diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 299e41853..000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,9 +0,0 @@ -Before opening this PR, ensure the following: -- `./format.sh` was run to apply standard formatting. -- `make` successfully builds a matching ROM. -- No new compiler warnings were introduced during the build process. - - Can be verified locally by running `tools/warnings_count/check_new_warnings.sh` -- New variables & functions should follow standard naming conventions. -- Comments and variables have correct spelling. ---- - diff --git a/.gitignore b/.gitignore index e2078e841..aa3f65077 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ tags # Project-specific ignores *.z64 +*.sra *.bin *.elf archive/ @@ -32,6 +33,10 @@ tools/qemu-mips tools/ido_recomp/* binary ctx.c graphs/ +*.c.m2c +tools/**/*dSYM/ +tools/decomp-permuter/ +tools/mips_to_c/ # Assets *.png @@ -39,5 +44,11 @@ graphs/ !*_custom* .extracted-assets.json +# Docs +!docs/**/*.png +docs/doxygen/ +!.vscode/extensions.json + # Per-user configuration .python-version +.make_options diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ae00f424..e0839bb2d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,5 @@ -Contributing to the Majora's Mask Decompilation Project -======================================================= +# Contributing to the Majora's Mask Decompilation Project + Thanks for helping us reverse engineer *The Legend of Zelda: Majora's Mask* for the N64! 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. @@ -10,21 +10,19 @@ For general information about the project, see [our readme](https://github.com/z 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. -Useful Links ------------- - -- [Discord](https://discord.zelda64.dev/) - Primary discussion platform. -- [Trello board](https://trello.com/b/ruxw9n6m/majoras-mask-decompilation) - We use this to track decompilation progress, not GitHub Issues. +## Useful Links - [Installation guide](https://github.com/zeldaret/mm/blob/master/README.md#installation) - Instructions for getting this repository set up and built on your machine. -- [Code Review Guidelines](REVIEWING.md) - These are the guidelines that reviewers will be using when reviewing your code. Good to be familiar with these before submitting your code. +- [Style Guide](docs/STYLE.md) - Description of the project style that we ask contributors to adhere to. +- [Code Review Guidelines](docs/REVIEWING.md) - These are the guidelines that reviewers will be using when reviewing your code. Good to be familiar with these before submitting your code. -- [Zelda 64 Reverse Engineering Website](https://zelda64.dev/) - Our homepage, with links to other resources. -- [Introduction to OOT decomp](https://github.com/zeldaret/oot/blob/master/docs/tutorial/contents.md) - A very detailed tutorial on how to get started with decomp. For OOT, but largely applicable to MM as well. -- The `#resources` channel on the Discord contains many more links +- [Zelda 64 Reverse Engineering Website](https://zelda64.dev/mm) - Our homepage, with FAQ and progress graph :chart_with_upwards_trend:. +- [MM decomp tutorial](docs/tutorial/contents.md) Detailed tutorial for learning in general how decomp works and how to decompile a small, simple file. +- [Introduction to OOT decomp](https://github.com/zeldaret/oot/blob/master/docs/tutorial/contents.md) - The tutorial the MM one was based on. For OOT, but largely applicable to MM as well. Covers slightly different topics, including how to get your data OK with `vbindiff`. +- The `#resources` channel on the Discord contains many more links on specific details of decompiling IDO MIPS code. -Getting Started ---------------- + +## Getting Started ### What should I know to take part? @@ -32,11 +30,14 @@ Basic knowledge of C, particularly arrays and pointers, is extremely useful. Kno You should be familiar with using git and GitHub. There are a number of tutorials available online, [such as this one](https://github.com/firstcontributions/first-contributions) which can help you get started. -The most useful knowledge to have is a general understanding of how the game works. An afternoon of constructive mucking about in the [OOT Practice Rom](http://practicerom.com/) (aka GZ) or the [MM Practice Rom](https://kz.zeldacodes.org/) (aka KZ) will be very beneficial if you have not looked at either of the N64 Zelda's internals before. -The [OOT Decompilation Project](https://github.com/zeldaret/oot) is farther along than this project, so it can also be a great resource. +The most useful knowledge to have is a general understanding of how the game works. An afternoon of constructive mucking about in the [MM Practice Rom](https://kz.zeldacodes.org/) (aka KZ) or the [OoT Practice Rom](http://practicerom.com/) (aka GZ) will be very beneficial if you have not looked at either of the N64 Zelda's internals before. + +The [OoT Decompilation Project](https://github.com/zeldaret/oot) is farther along than this project, so it can also be a great resource. This project only uses *publicly available code*. -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. + + +**N.B.** 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. ### Environment Setup @@ -46,53 +47,28 @@ You should be able to build a matching ROM before you start making any changes. ### First Contribution Usually, the best place to get started is to decompile an actor overlay. -An *actor* is any thing in the game that moves or performs actions or interactions. This includes things like Link, enemies, NPCs, doors, pots, etc. +An *actor* is any thing in the game that moves or performs actions or interactions. This includes things like Link, enemies, NPCs, doors, pots, etc. Actors are good for a first file because they are generally small, self-contained systems. -You should [join the Discord](https://discord.zelda64.dev/) to say hello and get suggestions on where to start on the `#mm-decomp` channel. +We recommend that you [join the Discord](https://discord.zelda64.dev/) to say hello and get suggestions on where to start on the `#mm-decomp` channel. -We track who is working on what on the [Trello board](https://trello.com/b/ruxw9n6m/majoras-mask-decompilation). -After joining the Discord, ask to be added to the Trello board so you can claim your code file and avoid duplicate work. You may need to add a card if a card for your file does not currently exist. +We track who is working on what on some Google Sheets available in the Discord. Once you've decided on or been recommended a good first file, mark it as Reserved. -The work flow is: Reserve a file, decompile it, submit a PR, and then repeat while addressing review comments. The expectation is that one reservation goes to one file which ends up in a one file PR. +The workflow is: +- Reserve a file, +- decompile it, +- submit a PR, +- repeat while addressing review comments. -Please note that unless it is communicated beforehand you will be expected to fully complete the file if you reserve it on Trello. Exceptions are always easy to approve if it's communicated to the team. Real life circumstances can prevent someone from finishing. In these cases they should link their repo/branch in the trello and unreserve immediately. Communicate any issues with your reservations as early as possible. +The expectation is that one reservation goes to one file which ends up in a one file PR, although naturally some files are more sensibly worked on as a group, for example two actors that work together. This also does not apply to large asset files like `gameplay_keep`: you can just reserve the parts that are used in your files. -Style Guide & Conventions -------------------------- +If possible, we expect reserved files to be completed. If you find you cannot complete a file, because it is intractable for one reason or another, or real-life circumstances get in the way, please talk to one of the leads in Discord; we may find someone else interested in helping you finish, or who is happy to take over the file from you completely. If you unreserve a file on which you have useful progress, please leave a link to your branch in the Notes column on the Google Sheet that the next person who works on the file can use. -Most of the C formatting style is enforced by the `format.sh` script which is based on `clang-format`. -Running `./format.sh` will apply our standard style to all `.c` files in the repository. -There are some conventions that cannot be automatically enforced. +## Style Guide & Conventions -### Naming Scheme +See the [Style Guide](docs/STYLE.md). -The following overlays are good examples of our naming conventions: - -- [`ovl_Dm_Ravine`](src/overlays/actors/ovl_Dm_Ravine/z_dm_ravine.c) -- [`ovl_En_Jc_Mato`](src/overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.c) - -These files demonstrate the following: - -- Word order in names are from least-to-most specific (`DM_RAVINE_STATE_ACTIVE`, not `DM_RAVINE_ACTIVE_STATE`) -- Functions, structs, unions, enums, and typedefs are `TitleCase` (`DmRavine`) - - "Methods" for objects separate the object from the verb with an underscore (`DmRavine_Init`) -- Variable names are `camelCase` (`actionFunc`) - - Global variables start with `g` (`gSaveContext`) - - Static global variables start with `s` (`sSphereInit`) -- Macros and enum constants are `SCREAMING_SNAKE_CASE` (`DM_RAVINE_STATE_ACTIVE`) -- Public structs, enums, and constants should be defined in the header file in the following cases: - - The primary `Actor` struct (`DmRavine`) - - The actor's `InitVars`, as an `extern` symbol (`Dm_Ravine_InitVars`) - - Types used in other public declarations, like `actionFunc` typedefs (`DmRavineActionFunc`) - - Macros and enums for accessing & setting actor `params` - - The struct/enum/define is needed by other files -- Trailing commas in array and struct definitions (see `EnJcMatoDamageTable`) -- Constants converted to whichever looks best in context: hexadecimal, decimal, or float - - Rotation angles should always be in hexadecimal -- Define macros for bitwise access to `actor->params` - -### `NON_MATCHING` & `NON_EQUIVALENT` +## `NON_MATCHING` and `NON_EQUIVALENT` If you make significant progress on decompiling a function, but can't get it to match perfectly, you can use a `NON_MATCHING` block to commit your code but have it excluded from the build, like so: @@ -102,20 +78,23 @@ void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) { // ... } #else +void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v); #pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_SpawnWaterDroplets.s") #endif ``` -Before using `NON_MATCHING`, first try to use the [decomp-permuter](tools/decomp-permuter) tool to find a closer match. +Before PRing with a `NON_MATCHING`, you can try +- using the [decomp-permuter](tools/decomp-permuter) to find a closer match, +- Asking in `#mm-decomp-help` in Discord; the easiest way to allow other people to play around with the function you are stuck on is to make a scratch on [decomp.me](http://decomp.me). `NON_EQUIVALENT` can be used with the same syntax as `NON_MATCHING`, but it is used to mark sections of code which do not match *and* do not have the same behavior as the original code. -### Matching vs. Documenting +## Matching and Documenting Usually, the first step of decompiling a section of code is to get it *matching*: to produce a C version of the code that can be compiled into an identical ROM. However, the goal of this project is to produce a codebase that can be understood and modified. -So, beyond producing matching C code, the next steps are *documenting* the code. +Therefore once C code produces matching assembly, the next step is to *document* the code. Documenting is more than just adding comments. Documenting also includes: @@ -123,22 +102,19 @@ Documenting is more than just adding comments. Documenting also includes: - Using (or adding) constants, enums, and macros when possible - Explaining sections of code that are not straightforward -Overlays are not required to be documented at this time, but `code/` and `boot/` should be documented. When documentation on a file has been started it should be as complete as possible. +Overlays are not required to be documented at this time, but files from `code/` and `boot/` should be documented. When documentation on a file has been started it should be as complete as reasonable. -For right now, object segment symbols should not be documented/renamed. -These will be given names when object reconstruction is ready. -However, it can be useful to add comments with name suggestions. +See the [Style Guide](docs/STYLE.md) for more details on documentation style. -Pull Requests (PRs) -------------------- +## Pull Requests (PRs) ### Checklist Before opening a PR, walk through the following steps to ensure that your code conforms to the style guide and conventions. -- `./format.sh` was run to apply standard formatting. - `make` successfully builds a matching ROM. +- `./format.sh` was run to apply standard formatting. - No new compiler warnings were introduced during the build process. - Can be verified locally by running `tools/warnings_count/check_new_warnings.sh` - New variables & functions should follow standard naming conventions. @@ -148,15 +124,28 @@ Feel free to reach out on the Discord if you have any questions about these step ### Pull Request Process -After opening a PR, the Jenkins server will verify your changes. -If there is an error, double-check that you can successfully `make clean && make` locally. If the build is OK, the next thing to check is that all added/modified files were `git add`-ed to your commit. The final check before posting on Discord for help is that there are no new warnings added to the code causing Jenkins to fail. You can check this by running: `tools/warnings_count/check_new_warnings.sh`. +After opening a PR, the Jenkins agent will test formatting, the contents of the spec, build the rom and check for warnings. +If there is an error, double-check that you can successfully +```bash +make disasm +./extract_assets.py -f +make clean +make +``` +locally. If the build is `OK`, the next thing to check is that all added/modified files were `git add`-ed to your commit. The final check before posting on Discord for help is that there are no new warnings added to the code causing Jenkins to fail. You can check this by running: `tools/warnings_count/check_new_warnings.sh`. -Each PR needs a review from one reviewer and the project lead. +Each PR needs a review from two reviewers, at least one a project lead, and final approval from Kenix. -The PR author marks the comments as resolved: the commenter may not have permissions to do so. -Once all comments are addressed, it is courteous to ping the reviewer on either Discord or GitHub via re-requesting a review. +If the PR author agrees with a reviewer's suggestion, they make the change and resolve the conversation. If they disagree, have a better idea, or want to comment on something, they should at least leave a comment, and discuss it in Discord if it's not going to be resolved quickly, since long conversations on GitHub are hard to read. -After all the comments are addressed and at least one contributor has approved the review, the project lead can then review and merge the code. -The project lead is also responsible for ensuring that all of these procedures are followed. +Once all comments is addressed and all reviewers have approved, the PR will be merged. -Throughout the PR process, you (the author) should update the card on [Trello board](https://trello.com/b/ruxw9n6m/majoras-mask-decompilation) with the appropriate column and labels. +Project leads are responsible for ensuring that these conventions are followed. + +### Some git notes + +- You should work on a branch on your fork separate from your copy of master: it is always useful to have a clean master branch around if you need to fix something. +- When a PR is merged into master, it may conflict with your work. While your branch is private (in particular, not used for a PR), you can rebase, but when your branch is public/used for a PR always merge master instead of rebasing: it makes it much easier for people to understand what you changed since the last review. +- We squash commits when merging, so your commit history does not have to be completely spotless. + +Throughout the PR process, you (the author) should update the rows on the appropriate Google Sheets with the appropriate information as the decompilation process progresses. diff --git a/Jenkinsfile b/Jenkinsfile index df06c6a09..fb60f0aca 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -3,6 +3,10 @@ pipeline { label 'mm' } + options { + ansiColor('xterm') + } + stages { stage('Check formatting') { steps { @@ -10,6 +14,12 @@ pipeline { sh 'bash -c "tools/check_format.sh 2>&1 >(tee tools/check_format.txt)"' } } + stage('Check relocs') { + steps { + echo 'Checking relocs on spec...' + sh 'bash -c "tools/reloc_spec_check.sh"' + } + } stage('Copy ROM') { steps { echo 'Setting up ROM...' @@ -26,6 +36,16 @@ pipeline { sh 'bash -c "./tools/warnings_count/compare_warnings.sh setup"' } } + stage('Assets') { + steps { + sh 'bash -c "make -j assets 2> >(tee tools/warnings_count/warnings_assets_new.txt)"' + } + } + stage('Check assets warnings') { + steps { + sh 'bash -c "./tools/warnings_count/compare_warnings.sh assets"' + } + } stage('Disasm') { steps { sh 'bash -c "make -j disasm 2> >(tee tools/warnings_count/warnings_disasm_new.txt)"' @@ -38,7 +58,7 @@ pipeline { } stage('Build') { steps { - sh 'bash -c "make -j all 2> >(tee tools/warnings_count/warnings_build_new.txt)"' + sh 'bash -c "make -j uncompressed 2> >(tee tools/warnings_count/warnings_build_new.txt)"' } } stage('Check build warnings') { @@ -46,15 +66,25 @@ pipeline { sh 'bash -c "./tools/warnings_count/compare_warnings.sh build"' } } + stage('Compress') { + steps { + sh 'bash -c "make -j compressed 2> >(tee tools/warnings_count/warnings_compress_new.txt)"' + } + } + stage('Check compress warnings') { + steps { + sh 'bash -c "./tools/warnings_count/compare_warnings.sh compress"' + } + } stage('Report Progress') { when { branch 'master' } 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 +97,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 349c50b67..f33f60848 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ +# Build options can be changed by modifying the makefile or by building with 'make SETTING=value'. +# It is also possible to override the settings in Defaults in a file called .make_options as 'SETTING=value'. + +-include .make_options + MAKEFLAGS += --no-builtin-rules -# Build options can either be changed by modifying the makefile, or by building with 'make SETTING=value' +#### Defaults #### # If COMPARE is 1, check the output md5sum after building COMPARE ?= 1 @@ -8,8 +13,20 @@ COMPARE ?= 1 NON_MATCHING ?= 0 # If ORIG_COMPILER is 1, compile with QEMU_IRIX and the original compiler ORIG_COMPILER ?= 0 +# if WERROR is 1, pass -Werror to CC_CHECK, so warnings would be treated as errors +WERROR ?= 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 +# Check code syntax with host compiler +RUN_CC_CHECK ?= 1 +# Dump build object files +OBJDUMP_BUILD ?= 0 +# Number of threads to disassmble, extract, and compress with +N_THREADS ?= $(shell nproc) + +#### Setup #### ifeq ($(NON_MATCHING),1) CFLAGS := -DNON_MATCHING @@ -17,6 +34,11 @@ ifeq ($(NON_MATCHING),1) COMPARE := 0 endif +DISASM_FLAGS := --reg-names=o32 +ifneq ($(FULL_DISASM), 0) + DISASM_FLAGS += --all +endif + PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) MAKE = make @@ -36,14 +58,8 @@ 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 - #### Tools #### + ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0) MIPS_BINUTILS_PREFIX := mips-linux-gnu- else @@ -69,8 +85,12 @@ AS := $(MIPS_BINUTILS_PREFIX)as LD := $(MIPS_BINUTILS_PREFIX)ld OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump +ASM_PROC := python3 tools/asm-processor/build.py + +ASM_PROC_FLAGS := --input-enc=utf-8 --output-enc=euc-jp IINC := -Iinclude -Isrc -Iassets -Ibuild -I. + ifeq ($(KEEP_MDEBUG),0) RM_MDEBUG = $(OBJCOPY) --remove-section .mdebug $@ else @@ -78,8 +98,15 @@ else endif # Check code syntax with host compiler -CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces -Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-label -CC_CHECK := gcc -fno-builtin -fsyntax-only -funsigned-char -fdiagnostics-color -std=gnu90 -D _LANGUAGE_C -D NON_MATCHING $(IINC) -include stdarg.h $(CHECK_WARNINGS) +ifneq ($(RUN_CC_CHECK),0) + CHECK_WARNINGS := -Wall -Wextra -Wno-format-security -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable -Wno-missing-braces -Wno-int-conversion -Wno-unused-but-set-variable -Wno-unused-label + CC_CHECK := gcc -fno-builtin -fsyntax-only -funsigned-char -fdiagnostics-color -std=gnu89 -D _LANGUAGE_C -D NON_MATCHING $(IINC) -nostdinc $(CHECK_WARNINGS) + ifneq ($(WERROR), 0) + CC_CHECK += -Werror + endif +else + CC_CHECK := @: +endif CPP := cpp ELF2ROM := tools/buildtools/elf2rom @@ -92,16 +119,33 @@ ASFLAGS := -march=vr4300 -32 -Iinclude MIPS_VERSION := -mips2 # we support Microsoft extensions such as anonymous structs, which the compiler does support but warns for their usage. Surpress the warnings with -woff. -CFLAGS += -G 0 -non_shared -Xfullwarn -Xcpluscomm $(IINC) -Wab,-r4300_mul -woff 624,649,838,712 +CFLAGS += -G 0 -non_shared -fullwarn -verbose -Xcpluscomm $(IINC) -nostdinc -Wab,-r4300_mul -woff 624,649,838,712,516 + +# Use relocations and abi fpr names in the dump +OBJDUMP_FLAGS := --disassemble --reloc --disassemble-zeroes -Mreg-names=32 + +ifneq ($(OBJDUMP_BUILD), 0) + OBJDUMP_CMD = $(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s) + OBJCOPY_BIN = $(OBJCOPY) -O binary $@ $@.bin +else + OBJDUMP_CMD = @: + OBJCOPY_BIN = @: +endif ifeq ($(shell getconf LONG_BIT), 32) # Work around memory allocation bug in QEMU export QEMU_GUEST_BASE := 1 -else +else ifneq ($(RUN_CC_CHECK),0) # Ensure that gcc treats the code as 32-bit CC_CHECK += -m32 endif +# rom compression flags +COMPFLAGS := --threads $(N_THREADS) +ifneq ($(NON_MATCHING),1) + COMPFLAGS += --matching +endif + #### Files #### # ROM image @@ -116,25 +160,29 @@ $(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*") +# Prevents building C files that will be #include'd +ASSET_BIN_DIRS_C_FILES := $(shell find assets/* -type d -not -path "assets/xml*" -not -path "assets/code*" -not -path "assets/overlays*") + +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_C_FILES),$(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) @@ -153,29 +201,42 @@ build/src/libultra/io/%.o: OPTFLAGS := -O2 build/src/libultra/libc/%.o: OPTFLAGS := -O2 build/src/libultra/gu/%.o: OPTFLAGS := -O2 build/src/libultra/rmon/%.o: OPTFLAGS := -O2 +build/src/libultra/flash/%.o: OPTFLAGS := -g +build/src/libultra/flash/%.o: MIPS_VERSION := -mips1 + +build/src/code/audio/%.o: OPTFLAGS := -O2 + +build/assets/%.o: OPTFLAGS := -O1 +build/assets/%.o: ASM_PROC_FLAGS := # file flags build/src/boot_O2_g3/fault.o: CFLAGS += -trapuv build/src/boot_O2_g3/fault_drawer.o: CFLAGS += -trapuv +build/src/code/jpegutils.o: OPTFLAGS := -O2 +build/src/code/jpegdecoder.o: OPTFLAGS := -O2 +build/src/code/jpegutils.o: CC := $(CC_OLD) +build/src/code/jpegdecoder.o: CC := $(CC_OLD) + build/src/libultra/libc/ll.o: OPTFLAGS := -O1 build/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 -32 build/src/libultra/libc/llcvt.o: OPTFLAGS := -O1 build/src/libultra/libc/llcvt.o: MIPS_VERSION := -mips3 -32 # cc & asm-processor -build/src/boot_O2/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -build/src/boot_O2_g3/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- +build/src/boot_O2/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- +build/src/boot_O2_g3/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- -build/src/libultra/%.o: CC := python3 tools/asm-processor/build.py $(CC_OLD) -- $(AS) $(ASFLAGS) -- +build/src/libultra/%.o: CC := $(CC_OLD) +# Needed at least until voice is decompiled +build/src/libultra/voice/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC_OLD) -- $(AS) $(ASFLAGS) -- -build/src/code/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- +build/src/code/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- +build/src/code/audio/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- -build/src/overlays/actors/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -build/src/overlays/effects/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -build/src/overlays/fbdemos/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -build/src/overlays/gamestates/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- -build/src/overlays/kaleido_scope/%.o: CC := python3 tools/asm-processor/build.py $(CC) -- $(AS) $(ASFLAGS) -- +build/src/overlays/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- + +build/assets/%.o: CC := $(ASM_PROC) $(ASM_PROC_FLAGS) $(CC) -- $(AS) $(ASFLAGS) -- #### Main Targets ### @@ -191,17 +252,17 @@ ifeq ($(COMPARE),1) @md5sum -c checksum.md5 endif -.PHONY: all uncompressed compressed clean assetclean distclean disasm init setup +.PHONY: all uncompressed compressed clean assetclean distclean assets disasm init setup .DEFAULT_GOAL := uncompressed -all: compressed +all: uncompressed compressed $(ROM): $(ELF) $(ELF2ROM) -cic 6105 $< $@ -$(ROMC): uncompressed - python3 tools/z64compress_wrapper.py --mb 32 --matching --threads $(N_THREADS) $(ROM) $@ $(ELF) build/$(SPEC) +$(ROMC): $(ROM) + 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 $@ @@ -225,14 +286,16 @@ setup: $(MAKE) -C tools python3 tools/fixbaserom.py python3 tools/extract_baserom.py - python3 extract_assets.py -t $(N_THREADS) + +assets: + python3 extract_assets.py -j $(N_THREADS) ## Assembly generation disasm: $(RM) -rf asm data - python3 tools/disasm/disasm.py + python3 tools/disasm/disasm.py -j $(N_THREADS) $(DISASM_FLAGS) -diff-init: all +diff-init: uncompressed $(RM) -rf expected/ mkdir -p expected/ cp -r build expected/build @@ -240,14 +303,11 @@ diff-init: all init: $(MAKE) distclean $(MAKE) setup + $(MAKE) assets $(MAKE) disasm $(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 @@ -257,19 +317,24 @@ 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_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 $@ $< $(CC_CHECK) $< - @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< + $(OBJDUMP_CMD) # TODO: `() || true` is currently necessary to suppress `Error 1 (ignored)` make warnings caused by `test`, but this will go away if # the following is moved to a separate rule that is only run once when all the required objects have been compiled. $(ZAPD) bovl -eh -i $@ -cfg $< --outputpath $(@D)/$(notdir $(@D))_reloc.s @@ -277,28 +342,29 @@ build/src/overlays/%.o: src/overlays/%.c $(RM_MDEBUG) build/src/%.o: src/%.c - $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< - @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< + $(OBJDUMP_CMD) $(RM_MDEBUG) build/src/libultra/libc/ll.o: src/libultra/libc/ll.c - $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< python3 tools/set_o32abi_bit.py $@ - @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(OBJDUMP_CMD) $(RM_MDEBUG) build/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c - $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC_CHECK) $< + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< python3 tools/set_o32abi_bit.py $@ - @$(OBJDUMP) -d $@ > $(@:.o=.s) + $(OBJDUMP_CMD) $(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..f48230b90 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 @@ -17,32 +17,41 @@ ```diff - WARNING! - -The ROM this repository builds while has a matching checksum cannot be 'shifted' due -to hardcoded pointers which have yet to be dumped. Thus this repository is currently -in an experimental and research phase and cannot currently be used traditionally as a -source code base for general changes. +This repository is a work in progress, and while it can be used to make certain changes, it's +still constantly evolving. If you wish to use it for modding purposes in its current state, +please be aware that the codebase could drastically change at any time. Also note that some +parts of the ROM may not be 'shiftable' yet, so modifying them could currently be difficult. ``` -**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, and will not, produce a PC port.** For frequently asked questions, you can visit [our website](https://zelda64.dev/mm), and 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 version currently supported is N64 US, but we intend to eventually support every retail version of the original game (i.e. not versions of MM3D, which is a totally different game). -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](docs/BUILDING_MACOS.md). + ### Linux (Native or under WSL / VM) @@ -65,13 +74,7 @@ sudo apt update sudo apt install make git build-essential binutils-mips-linux-gnu python3 python3-pip libpng-dev ``` -To install the Python dependencies simply run in a terminal: - -```bash -python3 -m pip install -r requirements.txt -``` - -#### 2. Fork the repository +#### 2. Clone the repository Create your own fork of the repository at `https://github.com/zeldaret/mm`. Then clone your fork where you wish to have the project, with the command: @@ -79,11 +82,27 @@ Create your own fork of the repository at `https://github.com/zeldaret/mm`. Then git clone https://github.com//mm.git ``` -#### 3. Prepare a base ROM +This will copy the GitHub repository contents into a new folder in the current directory called `mm`. Change into this directory before doing anything else: + +```bash +cd mm +``` + +#### 3. Install python dependencies + +The build process has a few python packages required that are located in `requirements.txt`. + +To install them simply run in a terminal: + +```bash +python3 -m pip install -r requirements.txt +``` + +#### 4. Prepare a base ROM Copy your ROM to inside the root of this new project directory, and rename the file of the baserom to reflect the version of ROM you are using. ex: `baserom.mm.us.rev1.z64` -#### 4. Make and Build the ROM +#### 5. Make and Build the ROM To start the extraction/build process, run the following command: @@ -110,31 +129,18 @@ 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. +Some work also doesn'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. +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 or ZeldaRET's 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? -A: It is the view of the MM project leads that transient asm is safer than storing the disassembly in the repo. We feel like the C code is more transformative than a straight disassembly. \ No newline at end of file +For more information on getting started, see our [Contributing Guide](CONTRIBUTING.md), [Style Guide](docs/STYLE.md) and our [Code Review Guidelines](docs/REVIEWING.md) to see what code quality guidelines we follow. diff --git a/REVIEWING.md b/REVIEWING.md deleted file mode 100644 index 8f1524a17..000000000 --- a/REVIEWING.md +++ /dev/null @@ -1,67 +0,0 @@ -Reviewing Pull Requests to the Majora's Mask Decompilation Project -======================================================= - -Thanks for helping us reverse engineer *The Legend of Zelda: Majora's Mask* for the N64! -We invite all contributors to participate in our code review program. Every review submitted helps us keep code quality high and code merged in more quickly. - -This document is meant to be a set of tips and guidelines for reviewers of pull requests to the project. -For general information about the project, see [our readme](https://github.com/zeldaret/mm/blob/master/README.md). - -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. - -Useful Links ------------- - -- [Discord](https://discord.zelda64.dev/) - Primary discussion platform. -- [Trello board](https://trello.com/b/ruxw9n6m/majoras-mask-decompilation) - We use this to track decompilation progress, not GitHub Issues. - -- [Contributing guide](https://github.com/zeldaret/mm/blob/master/CONTRIBUTING.md) - Instructions for contributors. -- [Installation guide](https://github.com/zeldaret/mm/blob/master/README.md#installation) - Instructions for getting this repository set up and built on your machine. - -- [Zelda 64 Reverse Engineering Website](https://zelda64.dev/) - Our homepage, with links to other resources. -- [Introduction to OOT decomp](https://github.com/zeldaret/oot/blob/master/docs/tutorial/contents.md) - A very detailed tutorial on how to get started with decomp. For OOT, but largely applicable to MM as well. -- The `#resources` channel on the Discord contains many more links - -Getting Started ---------------- - -### What should I know to take part in the review process? - -You should first get yourself familiar with our [Contributing guide](https://github.com/zeldaret/mm/blob/master/CONTRIBUTING.md). It is also recommended that you have already successfully submitted a merged pull request to understand how the process works before submitting a review. - -Pull Requests (PRs) ------------- - -### How to review a Pull Request - -- When reviewing a PR it is suggested that you follow the checklist outlined in this section. -- You are not required to check for all of the items in the checklist. It is meant as a guide. -- Once the PR author has addressed all of your comments, you should add a comment with approval to the PR to signify to the project leads that this PR has been through peer review. -- If someone does not address your comments and expresses that a different way is better than yours, look for feedback from other contributors. The project lead will have final say in these situations. All decisions will generally be guided by a consensus of contributors. - -### Reviewer Checklist -- [ ] Jenkins build is successful. - - [ ] `make` builds a matching ROM. - - [ ] Any new compiler warnings that were added are required for matching. Ensure there is good reason if the warnings files have changed. `./tools/warnings_count/warnings_build_current.txt` and `./tools/warnings_count/warnings_setup_current.txt` -- [ ] Files with NON_MATCHING functions have equivalent behaviour. (This will only be reviewed once we have shiftability since equivalence testing is easiest in game) -- [ ] `code` and `boot` segment files should be documented as much as possible. Overlays with documentation should be complete. - - [ ] Overlays with documentation should have macros to define access to parameters if the parameter uses bitwise access. The params should have an enum when it makes sense. -- [ ] `format.sh` was run. -- [ ] Comments and variables have correct spelling. -- [ ] The following should be declared in an Actor header file. There should be nothing else in the Actor header file. - - [ ] Main Actor struct - - [ ] Extern'd initVar data. - - [ ] Types used in the actor struct. Specific example would be actionFunc typedefs. - - [ ] Param field macros and/or enums. - - [ ] For any other additional `enum`/`struct`/`define`/`function`/`global`, there needs to be evidence it is needed in another file. -- [ ] New variables and functions should follow standard naming conventions. - - [ ] Constants are converted to whichever looks best in context: hexadecimal, decimal, or float - - [ ] Rotation angles should always be in hexadecimal - - [ ] Colour values should always be in decimal. - - [ ] Functions, structs, unions, enums, and typedefs are `TitleCase` (`DmRavine`) - - [ ] "Methods" for objects separate the system from the verb with an underscore (`DmRavine_Init`) - - [ ] Variable names are `camelCase` (`actionFunc`) - - [ ] Global variables start with `g` (`gSaveContext`) - - [ ] Static global variables start with `s` (`sSphereInit`) - - [ ] Macros and enum constants are `SCREAMING_SNAKE_CASE` (`DM_RAVINE_STATE_ACTIVE`) - - [ ] Trailing commas in array and struct definitions (see `EnJcMatoDamageTable`) diff --git a/assets/xml/code/debug_display.xml b/assets/xml/code/debug_display.xml new file mode 100644 index 000000000..c8ac659bc --- /dev/null +++ b/assets/xml/code/debug_display.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/code/sub_s.xml b/assets/xml/code/sub_s.xml new file mode 100644 index 000000000..03329f0c5 --- /dev/null +++ b/assets/xml/code/sub_s.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/interface/do_action_static.xml b/assets/xml/interface/do_action_static.xml new file mode 100644 index 000000000..3fdd1e404 --- /dev/null +++ b/assets/xml/interface/do_action_static.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/interface/nes_font_static.xml b/assets/xml/interface/nes_font_static.xml new file mode 100644 index 000000000..b021dbfdb --- /dev/null +++ b/assets/xml/interface/nes_font_static.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/interface/parameter_static.xml b/assets/xml/interface/parameter_static.xml new file mode 100644 index 000000000..33ab40de4 --- /dev/null +++ b/assets/xml/interface/parameter_static.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/interface/week_static.xml b/assets/xml/interface/week_static.xml new file mode 100644 index 000000000..12cc885fa --- /dev/null +++ b/assets/xml/interface/week_static.xml @@ -0,0 +1,7 @@ + + + + + + + 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/misc/locerrmsg.xml b/assets/xml/misc/locerrmsg.xml new file mode 100644 index 000000000..d6f8bfdaa --- /dev/null +++ b/assets/xml/misc/locerrmsg.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/misc/memerrmsg.xml b/assets/xml/misc/memerrmsg.xml new file mode 100644 index 000000000..92c15f474 --- /dev/null +++ b/assets/xml/misc/memerrmsg.xml @@ -0,0 +1,6 @@ + + + + + + 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/misc/scene_texture_01.xml b/assets/xml/misc/scene_texture_01.xml new file mode 100644 index 000000000..edbb2d1c4 --- /dev/null +++ b/assets/xml/misc/scene_texture_01.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/misc/scene_texture_02.xml b/assets/xml/misc/scene_texture_02.xml new file mode 100644 index 000000000..a7219c31e --- /dev/null +++ b/assets/xml/misc/scene_texture_02.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/misc/scene_texture_03.xml b/assets/xml/misc/scene_texture_03.xml new file mode 100644 index 000000000..fcd10b9a9 --- /dev/null +++ b/assets/xml/misc/scene_texture_03.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/misc/scene_texture_04.xml b/assets/xml/misc/scene_texture_04.xml new file mode 100644 index 000000000..6faf681ac --- /dev/null +++ b/assets/xml/misc/scene_texture_04.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/misc/scene_texture_05.xml b/assets/xml/misc/scene_texture_05.xml new file mode 100644 index 000000000..d9ae4f2c3 --- /dev/null +++ b/assets/xml/misc/scene_texture_05.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/misc/scene_texture_06.xml b/assets/xml/misc/scene_texture_06.xml new file mode 100644 index 000000000..1a2dfc2a0 --- /dev/null +++ b/assets/xml/misc/scene_texture_06.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/misc/scene_texture_07.xml b/assets/xml/misc/scene_texture_07.xml new file mode 100644 index 000000000..22f445990 --- /dev/null +++ b/assets/xml/misc/scene_texture_07.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/misc/scene_texture_08.xml b/assets/xml/misc/scene_texture_08.xml new file mode 100644 index 000000000..31e557347 --- /dev/null +++ b/assets/xml/misc/scene_texture_08.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/misc/story_static.xml b/assets/xml/misc/story_static.xml new file mode 100644 index 000000000..9a15d8c4f --- /dev/null +++ b/assets/xml/misc/story_static.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/gameplay_dangeon_keep.xml b/assets/xml/objects/gameplay_dangeon_keep.xml new file mode 100644 index 000000000..9d5a9901a --- /dev/null +++ b/assets/xml/objects/gameplay_dangeon_keep.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml new file mode 100644 index 000000000..45fa3eccd --- /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..f73e9252f --- /dev/null +++ b/assets/xml/objects/gameplay_keep.xml @@ -0,0 +1,1439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ah.xml b/assets/xml/objects/object_ah.xml new file mode 100644 index 000000000..3644f2a90 --- /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..7d4c2c741 --- /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..d0f6a6cbb --- /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..b0737cb50 --- /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..2c212923d --- /dev/null +++ b/assets/xml/objects/object_an1.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..17cff4597 --- /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..f039e0114 --- /dev/null +++ b/assets/xml/objects/object_ani.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_aob.xml b/assets/xml/objects/object_aob.xml new file mode 100644 index 000000000..3325e9b53 --- /dev/null +++ b/assets/xml/objects/object_aob.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..d4382673f --- /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..4225bec84 --- /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..a16e2fb1f --- /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..c9c6a0a90 --- /dev/null +++ b/assets/xml/objects/object_bb.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bba.xml b/assets/xml/objects/object_bba.xml new file mode 100644 index 000000000..144c685e4 --- /dev/null +++ b/assets/xml/objects/object_bba.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bdoor.xml b/assets/xml/objects/object_bdoor.xml new file mode 100644 index 000000000..a57339f3b --- /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..8f1d704cf --- /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..0602f987d --- /dev/null +++ b/assets/xml/objects/object_bg.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bh.xml b/assets/xml/objects/object_bh.xml new file mode 100644 index 000000000..84f3050c0 --- /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..21ead0501 --- /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..531a151c6 --- /dev/null +++ b/assets/xml/objects/object_bigpo.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigslime.xml b/assets/xml/objects/object_bigslime.xml new file mode 100644 index 000000000..5b7530add --- /dev/null +++ b/assets/xml/objects/object_bigslime.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bji.xml b/assets/xml/objects/object_bji.xml new file mode 100644 index 000000000..b41ac1546 --- /dev/null +++ b/assets/xml/objects/object_bji.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bjt.xml b/assets/xml/objects/object_bjt.xml new file mode 100644 index 000000000..6266711ab --- /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..f942c84db --- /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..ed42d9031 --- /dev/null +++ b/assets/xml/objects/object_boj.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..6a10080a3 --- /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..9a400554b --- /dev/null +++ b/assets/xml/objects/object_boss02.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss03.xml b/assets/xml/objects/object_boss03.xml new file mode 100644 index 000000000..75ce1d3c9 --- /dev/null +++ b/assets/xml/objects/object_boss03.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss04.xml b/assets/xml/objects/object_boss04.xml new file mode 100644 index 000000000..d5d0f728a --- /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..b401ae2be --- /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..15a2e162d --- /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..62d6fb91f --- /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..fb1fb3fd5 --- /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..7ccf12bce --- /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..fccbf539f --- /dev/null +++ b/assets/xml/objects/object_cne.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..535d5dd85 --- /dev/null +++ b/assets/xml/objects/object_cow.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..de51da580 --- /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..803d2b02c --- /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..3a04c474e --- /dev/null +++ b/assets/xml/objects/object_ctower_rot.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..f613a9ab8 --- /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..57124bd28 --- /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..7d3e1e596 --- /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..b82cfb94b --- /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..8a45dd04a --- /dev/null +++ b/assets/xml/objects/object_dekunuts.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..7b1ff8c20 --- /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..a7b3874ec --- /dev/null +++ b/assets/xml/objects/object_dmask.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnk.xml b/assets/xml/objects/object_dnk.xml new file mode 100644 index 000000000..ad69c7722 --- /dev/null +++ b/assets/xml/objects/object_dnk.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dno.xml b/assets/xml/objects/object_dno.xml new file mode 100644 index 000000000..a320be10f --- /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..376368578 --- /dev/null +++ b/assets/xml/objects/object_dnp.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnq.xml b/assets/xml/objects/object_dnq.xml new file mode 100644 index 000000000..830e6d8e4 --- /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..d42f68f54 --- /dev/null +++ b/assets/xml/objects/object_dns.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + " Format="rgba16" Width="8" Height="8" Offset="0x28E8" /> + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnt.xml b/assets/xml/objects/object_dnt.xml new file mode 100644 index 000000000..6a2b0058d --- /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..f63a27467 --- /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..89eba9c96 --- /dev/null +++ b/assets/xml/objects/object_dog.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..c60fa9ba9 --- /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..941fa6fcc --- /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..394f5a6fe --- /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..ab4b09cf7 --- /dev/null +++ b/assets/xml/objects/object_dora.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + 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..c5f4ee726 --- /dev/null +++ b/assets/xml/objects/object_drs.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ds2.xml b/assets/xml/objects/object_ds2.xml new file mode 100644 index 000000000..1f1fd9d20 --- /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..8cee6b22e --- /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..78ad8046e --- /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..8dd90375a --- /dev/null +++ b/assets/xml/objects/object_dy_obj.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..3cb6468b9 --- /dev/null +++ b/assets/xml/objects/object_efc_tw.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_eg.xml b/assets/xml/objects/object_eg.xml new file mode 100644 index 000000000..46d3e0089 --- /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..f80b67696 --- /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..47fa1da70 --- /dev/null +++ b/assets/xml/objects/object_fall.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + \ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fall2.xml b/assets/xml/objects/object_fall2.xml new file mode 100644 index 000000000..4e58e9fd3 --- /dev/null +++ b/assets/xml/objects/object_fall2.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_famos.xml b/assets/xml/objects/object_famos.xml new file mode 100644 index 000000000..cbbf0057c --- /dev/null +++ b/assets/xml/objects/object_famos.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fb.xml b/assets/xml/objects/object_fb.xml new file mode 100644 index 000000000..f0d3b8111 --- /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..84018ddd8 --- /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..9da78b6ab --- /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..cb02087ba --- /dev/null +++ b/assets/xml/objects/object_fr.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fsn.xml b/assets/xml/objects/object_fsn.xml new file mode 100644 index 000000000..f90bf4e4d --- /dev/null +++ b/assets/xml/objects/object_fsn.xml @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu.xml b/assets/xml/objects/object_fu.xml new file mode 100644 index 000000000..4094355ae --- /dev/null +++ b/assets/xml/objects/object_fu.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..2f6aac2dd --- /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..6338b48d6 --- /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..17c21c93a --- /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..8698d176b --- /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..3fde40f94 --- /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..ae80c7dfc --- /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..7490a661e --- /dev/null +++ b/assets/xml/objects/object_gmo.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + 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..35120e0c9 --- /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..4f595b6be --- /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..227fc4cf8 --- /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..62cf67540 --- /dev/null +++ b/assets/xml/objects/object_hanareyama_obj.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_harfgibud.xml b/assets/xml/objects/object_harfgibud.xml new file mode 100644 index 000000000..a97e42c00 --- /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..5cb2d8328 --- /dev/null +++ b/assets/xml/objects/object_hariko.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_hata.xml b/assets/xml/objects/object_hata.xml new file mode 100644 index 000000000..3f5e12a38 --- /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..a500981a7 --- /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..506135e0c --- /dev/null +++ b/assets/xml/objects/object_horse_link_child.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hs.xml b/assets/xml/objects/object_hs.xml new file mode 100644 index 000000000..ae025f327 --- /dev/null +++ b/assets/xml/objects/object_hs.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..ba755d100 --- /dev/null +++ b/assets/xml/objects/object_ice_block.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..0b68303da --- /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..56f8fd0e9 --- /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..3874e4834 --- /dev/null +++ b/assets/xml/objects/object_in.xml @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_in2.xml b/assets/xml/objects/object_in2.xml new file mode 100644 index 000000000..4457defae --- /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..17889995f --- /dev/null +++ b/assets/xml/objects/object_jg.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_js.xml b/assets/xml/objects/object_js.xml new file mode 100644 index 000000000..92f14da0b --- /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..33816a797 --- /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..36dceb0ca --- /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..8dd96770a --- /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..9b45ad478 --- /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..aad49e946 --- /dev/null +++ b/assets/xml/objects/object_kbt.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..0e2d3be2c --- /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..05d090d93 --- /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..0459cb062 --- /dev/null +++ b/assets/xml/objects/object_knight.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kujiya.xml b/assets/xml/objects/object_kujiya.xml new file mode 100644 index 000000000..f657e8bd8 --- /dev/null +++ b/assets/xml/objects/object_kujiya.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..36c61f364 --- /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..2b714be38 --- /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..0a374033b --- /dev/null +++ b/assets/xml/objects/object_lightswitch.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_boy.xml b/assets/xml/objects/object_link_boy.xml new file mode 100644 index 000000000..b0a85ece5 --- /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..51145033c --- /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..2fe3906fb --- /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..e3dab39da --- /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..d36aaa420 --- /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..0756c3300 --- /dev/null +++ b/assets/xml/objects/object_lodmoon.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + 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..3d0ea1fcc --- /dev/null +++ b/assets/xml/objects/object_ma1.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ma2.xml b/assets/xml/objects/object_ma2.xml new file mode 100644 index 000000000..a61eff4e0 --- /dev/null +++ b/assets/xml/objects/object_ma2.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mag.xml b/assets/xml/objects/object_mag.xml new file mode 100644 index 000000000..29d30daad --- /dev/null +++ b/assets/xml/objects/object_mag.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..b1a816f47 --- /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..1ee3741bb --- /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..baac5425d --- /dev/null +++ b/assets/xml/objects/object_mm.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mnk.xml b/assets/xml/objects/object_mnk.xml new file mode 100644 index 000000000..c6e23399d --- /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..58a920522 --- /dev/null +++ b/assets/xml/objects/object_moonston.xml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_ms.xml b/assets/xml/objects/object_ms.xml new file mode 100644 index 000000000..a4a36e149 --- /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..6bfd0e46d --- /dev/null +++ b/assets/xml/objects/object_msmo.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mtoride.xml b/assets/xml/objects/object_mtoride.xml new file mode 100644 index 000000000..a79547730 --- /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..925cb74e9 --- /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..e8a695b52 --- /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..0e533fb6e --- /dev/null +++ b/assets/xml/objects/object_niw.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..a450cf11a --- /dev/null +++ b/assets/xml/objects/object_numa_obj.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nwc.xml b/assets/xml/objects/object_nwc.xml new file mode 100644 index 000000000..8c67159ce --- /dev/null +++ b/assets/xml/objects/object_nwc.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..6c3af0778 --- /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..0f79703b5 --- /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..70daa6172 --- /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..09e070254 --- /dev/null +++ b/assets/xml/objects/object_obj_tokeidai.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..e10afa135 --- /dev/null +++ b/assets/xml/objects/object_okuta.xml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..74a4101bd --- /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..b31660e6a --- /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..49a8d89ce --- /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..6c9d79883 --- /dev/null +++ b/assets/xml/objects/object_owl.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_oyu.xml b/assets/xml/objects/object_oyu.xml new file mode 100644 index 000000000..78cc8b34d --- /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..6b457ab8b --- /dev/null +++ b/assets/xml/objects/object_pamera.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ph.xml b/assets/xml/objects/object_ph.xml new file mode 100644 index 000000000..2e8a8eb29 --- /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..2cc6e5cbd --- /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..ae8ef56e3 --- /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..5885b89a3 --- /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..f42fe1664 --- /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..1ac690935 --- /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..95fc4743c --- /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..f341e95a4 --- /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..3649877ea --- /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..e3b4d2d93 --- /dev/null +++ b/assets/xml/objects/object_raf.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..ce32e20cc --- /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..72b3e6cb6 --- /dev/null +++ b/assets/xml/objects/object_rb.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rd.xml b/assets/xml/objects/object_rd.xml new file mode 100644 index 000000000..854ded388 --- /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..01099db47 --- /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..f2d3fd2b0 --- /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..a75e033f0 --- /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..359cff20d --- /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..219436b02 --- /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..3529620aa --- /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..4a8e01867 --- /dev/null +++ b/assets/xml/objects/object_shn.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sichitai_obj.xml b/assets/xml/objects/object_sichitai_obj.xml new file mode 100644 index 000000000..d1179beab --- /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..3c23a73ce --- /dev/null +++ b/assets/xml/objects/object_sinkai_kabe.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_skb.xml b/assets/xml/objects/object_skb.xml new file mode 100644 index 000000000..c9935b64f --- /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..fde2d911f --- /dev/null +++ b/assets/xml/objects/object_snowman.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..57599fdce --- /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..2dabce2f8 --- /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..c7a0ffd25 --- /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..68e8ae26b --- /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..01ab0ef90 --- /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..2e546f471 --- /dev/null +++ b/assets/xml/objects/object_syoten.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tab.xml b/assets/xml/objects/object_tab.xml new file mode 100644 index 000000000..9a63c2ed3 --- /dev/null +++ b/assets/xml/objects/object_tab.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..2c988e74b --- /dev/null +++ b/assets/xml/objects/object_tanron4.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..6b0a5349c --- /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..e7cb3ac91 --- /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..681b732e8 --- /dev/null +++ b/assets/xml/objects/object_tite.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tk.xml b/assets/xml/objects/object_tk.xml new file mode 100644 index 000000000..0c0ea3831 --- /dev/null +++ b/assets/xml/objects/object_tk.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tl.xml b/assets/xml/objects/object_tl.xml new file mode 100644 index 000000000..6397283af --- /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..aac4b5ea9 --- /dev/null +++ b/assets/xml/objects/object_tokei_step.xml @@ -0,0 +1,9 @@ + + + + + + + + + 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..45d3da100 --- /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..a0d83076e --- /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..dd0e6d20c --- /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..761a6e0d7 --- /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..a58af5654 --- /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..5717124a7 --- /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..a1f499eb6 --- /dev/null +++ b/assets/xml/objects/object_utubo.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..b6c1cdfa2 --- /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..fba2bc246 --- /dev/null +++ b/assets/xml/objects/object_wallmaster.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_warp1.xml b/assets/xml/objects/object_warp1.xml new file mode 100644 index 000000000..814334792 --- /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..bcd5b0ce3 --- /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..07ad601dd --- /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..6eb0f4ed0 --- /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..3d9ce392d --- /dev/null +++ b/assets/xml/objects/object_wf.xml @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wiz.xml b/assets/xml/objects/object_wiz.xml new file mode 100644 index 000000000..947cab3c7 --- /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..1a8503a6e --- /dev/null +++ b/assets/xml/objects/object_yb.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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..04d4ae406 --- /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..dafdef8cd --- /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..f6f1b95e5 --- /dev/null +++ b/assets/xml/objects/object_zm.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zo.xml b/assets/xml/objects/object_zo.xml new file mode 100644 index 000000000..8fc22ae46 --- /dev/null +++ b/assets/xml/objects/object_zo.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zob.xml b/assets/xml/objects/object_zob.xml new file mode 100644 index 000000000..bc4d61c6a --- /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..3e0b6567a --- /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..627bb676a --- /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..367d2df76 --- /dev/null +++ b/assets/xml/objects/object_zoraegg.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zos.xml b/assets/xml/objects/object_zos.xml new file mode 100644 index 000000000..1f5a2a542 --- /dev/null +++ b/assets/xml/objects/object_zos.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zov.xml b/assets/xml/objects/object_zov.xml new file mode 100644 index 000000000..abbc52268 --- /dev/null +++ b/assets/xml/objects/object_zov.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_Arrow_Ice.xml b/assets/xml/overlays/ovl_Arrow_Ice.xml index 96c0f2522..bec512600 100644 --- a/assets/xml/overlays/ovl_Arrow_Ice.xml +++ b/assets/xml/overlays/ovl_Arrow_Ice.xml @@ -1,11 +1,12 @@ + - - - + + + - - + + diff --git a/assets/xml/overlays/ovl_Arrow_Light.xml b/assets/xml/overlays/ovl_Arrow_Light.xml new file mode 100644 index 000000000..3d5ae87b8 --- /dev/null +++ b/assets/xml/overlays/ovl_Arrow_Light.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_Arrow_fire.xml b/assets/xml/overlays/ovl_Arrow_fire.xml new file mode 100644 index 000000000..893f335d0 --- /dev/null +++ b/assets/xml/overlays/ovl_Arrow_fire.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_Dm_Char01.xml b/assets/xml/overlays/ovl_Dm_Char01.xml new file mode 100644 index 000000000..3f855c376 --- /dev/null +++ b/assets/xml/overlays/ovl_Dm_Char01.xml @@ -0,0 +1,7 @@ + + + + + + + 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_Bom.xml b/assets/xml/overlays/ovl_En_Bom.xml new file mode 100644 index 000000000..08902add6 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bom.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bom_Bowl_Man.xml b/assets/xml/overlays/ovl_En_Bom_Bowl_Man.xml new file mode 100644 index 000000000..7e0b6d08b --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bom_Bowl_Man.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bombers.xml b/assets/xml/overlays/ovl_En_Bombers.xml new file mode 100644 index 000000000..c6fc64246 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bombers.xml @@ -0,0 +1,6 @@ + + + + + + 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_Gakufu.xml b/assets/xml/overlays/ovl_En_Gakufu.xml new file mode 100644 index 000000000..92b2672d4 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Gakufu.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Horse_Game_Check.xml b/assets/xml/overlays/ovl_En_Horse_Game_Check.xml new file mode 100644 index 000000000..bcb8ea695 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Horse_Game_Check.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/overlays/ovl_En_Kanban.xml b/assets/xml/overlays/ovl_En_Kanban.xml new file mode 100644 index 000000000..386cfc663 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Kanban.xml @@ -0,0 +1,9 @@ + + + + + + + + + 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_Mm3.xml b/assets/xml/overlays/ovl_En_Mm3.xml new file mode 100644 index 000000000..207b5ec8f --- /dev/null +++ b/assets/xml/overlays/ovl_En_Mm3.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/overlays/ovl_En_Sda.xml b/assets/xml/overlays/ovl_En_Sda.xml new file mode 100644 index 000000000..7e257ee20 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Sda.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Sth.xml b/assets/xml/overlays/ovl_En_Sth.xml new file mode 100644 index 000000000..80393fc2d --- /dev/null +++ b/assets/xml/overlays/ovl_En_Sth.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Syateki_Okuta.xml b/assets/xml/overlays/ovl_En_Syateki_Okuta.xml new file mode 100644 index 000000000..0e5054c19 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Syateki_Okuta.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Tanron1.xml b/assets/xml/overlays/ovl_En_Tanron1.xml new file mode 100644 index 000000000..17cf5faf5 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Tanron1.xml @@ -0,0 +1,7 @@ + + + + + + + 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/assets/xml/overlays/ovl_Obj_Entotu.xml b/assets/xml/overlays/ovl_Obj_Entotu.xml new file mode 100644 index 000000000..e6e6c64cf --- /dev/null +++ b/assets/xml/overlays/ovl_Obj_Entotu.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/overlays/ovl_Obj_Grass.xml b/assets/xml/overlays/ovl_Obj_Grass.xml new file mode 100644 index 000000000..e1002b369 --- /dev/null +++ b/assets/xml/overlays/ovl_Obj_Grass.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/overlays/ovl_Obj_Smork.xml b/assets/xml/overlays/ovl_Obj_Smork.xml new file mode 100644 index 000000000..745c6b6af --- /dev/null +++ b/assets/xml/overlays/ovl_Obj_Smork.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/overlays/ovl_Oceff_Wipe6.xml b/assets/xml/overlays/ovl_Oceff_Wipe6.xml new file mode 100644 index 000000000..e64c8cc71 --- /dev/null +++ b/assets/xml/overlays/ovl_Oceff_Wipe6.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/scenes/Z2_00KEIKOKU/Z2_00KEIKOKU.xml b/assets/xml/scenes/Z2_00KEIKOKU/Z2_00KEIKOKU.xml index 58d50ee83..3cf73a255 100644 --- a/assets/xml/scenes/Z2_00KEIKOKU/Z2_00KEIKOKU.xml +++ b/assets/xml/scenes/Z2_00KEIKOKU/Z2_00KEIKOKU.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_10YUKIYAMANOMURA/Z2_10YUKIYAMANOMURA.xml b/assets/xml/scenes/Z2_10YUKIYAMANOMURA/Z2_10YUKIYAMANOMURA.xml index c48cb9646..9676cbc39 100644 --- a/assets/xml/scenes/Z2_10YUKIYAMANOMURA/Z2_10YUKIYAMANOMURA.xml +++ b/assets/xml/scenes/Z2_10YUKIYAMANOMURA/Z2_10YUKIYAMANOMURA.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_10YUKIYAMANOMURA2/Z2_10YUKIYAMANOMURA2.xml b/assets/xml/scenes/Z2_10YUKIYAMANOMURA2/Z2_10YUKIYAMANOMURA2.xml index 565dcc06c..943e58e58 100644 --- a/assets/xml/scenes/Z2_10YUKIYAMANOMURA2/Z2_10YUKIYAMANOMURA2.xml +++ b/assets/xml/scenes/Z2_10YUKIYAMANOMURA2/Z2_10YUKIYAMANOMURA2.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_11GORONNOSATO/Z2_11GORONNOSATO.xml b/assets/xml/scenes/Z2_11GORONNOSATO/Z2_11GORONNOSATO.xml index 2a948603b..986823c90 100644 --- a/assets/xml/scenes/Z2_11GORONNOSATO/Z2_11GORONNOSATO.xml +++ b/assets/xml/scenes/Z2_11GORONNOSATO/Z2_11GORONNOSATO.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_11GORONNOSATO2/Z2_11GORONNOSATO2.xml b/assets/xml/scenes/Z2_11GORONNOSATO2/Z2_11GORONNOSATO2.xml index 40e82522f..9e6925131 100644 --- a/assets/xml/scenes/Z2_11GORONNOSATO2/Z2_11GORONNOSATO2.xml +++ b/assets/xml/scenes/Z2_11GORONNOSATO2/Z2_11GORONNOSATO2.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_12HAKUGINMAE/Z2_12HAKUGINMAE.xml b/assets/xml/scenes/Z2_12HAKUGINMAE/Z2_12HAKUGINMAE.xml index ca23dfa17..740f6a15a 100644 --- a/assets/xml/scenes/Z2_12HAKUGINMAE/Z2_12HAKUGINMAE.xml +++ b/assets/xml/scenes/Z2_12HAKUGINMAE/Z2_12HAKUGINMAE.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_14YUKIDAMANOMITI/Z2_14YUKIDAMANOMITI.xml b/assets/xml/scenes/Z2_14YUKIDAMANOMITI/Z2_14YUKIDAMANOMITI.xml index 2165e80f5..6c368004f 100644 --- a/assets/xml/scenes/Z2_14YUKIDAMANOMITI/Z2_14YUKIDAMANOMITI.xml +++ b/assets/xml/scenes/Z2_14YUKIDAMANOMITI/Z2_14YUKIDAMANOMITI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_17SETUGEN/Z2_17SETUGEN.xml b/assets/xml/scenes/Z2_17SETUGEN/Z2_17SETUGEN.xml index b5b9f6d77..ed6beb36e 100644 --- a/assets/xml/scenes/Z2_17SETUGEN/Z2_17SETUGEN.xml +++ b/assets/xml/scenes/Z2_17SETUGEN/Z2_17SETUGEN.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_17SETUGEN2/Z2_17SETUGEN2.xml b/assets/xml/scenes/Z2_17SETUGEN2/Z2_17SETUGEN2.xml index 357c0b897..1ac9488d7 100644 --- a/assets/xml/scenes/Z2_17SETUGEN2/Z2_17SETUGEN2.xml +++ b/assets/xml/scenes/Z2_17SETUGEN2/Z2_17SETUGEN2.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_20SICHITAI/Z2_20SICHITAI.xml b/assets/xml/scenes/Z2_20SICHITAI/Z2_20SICHITAI.xml index 73c697f16..d144c9e8e 100644 --- a/assets/xml/scenes/Z2_20SICHITAI/Z2_20SICHITAI.xml +++ b/assets/xml/scenes/Z2_20SICHITAI/Z2_20SICHITAI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_20SICHITAI2/Z2_20SICHITAI2.xml b/assets/xml/scenes/Z2_20SICHITAI2/Z2_20SICHITAI2.xml index fca3e6846..144914621 100644 --- a/assets/xml/scenes/Z2_20SICHITAI2/Z2_20SICHITAI2.xml +++ b/assets/xml/scenes/Z2_20SICHITAI2/Z2_20SICHITAI2.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_22DEKUCITY/Z2_22DEKUCITY.xml b/assets/xml/scenes/Z2_22DEKUCITY/Z2_22DEKUCITY.xml index 1db584d58..77f382ecc 100644 --- a/assets/xml/scenes/Z2_22DEKUCITY/Z2_22DEKUCITY.xml +++ b/assets/xml/scenes/Z2_22DEKUCITY/Z2_22DEKUCITY.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_24KEMONOMITI/Z2_24KEMONOMITI.xml b/assets/xml/scenes/Z2_24KEMONOMITI/Z2_24KEMONOMITI.xml index eb4b353db..f6c852dc9 100644 --- a/assets/xml/scenes/Z2_24KEMONOMITI/Z2_24KEMONOMITI.xml +++ b/assets/xml/scenes/Z2_24KEMONOMITI/Z2_24KEMONOMITI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_26SARUNOMORI/Z2_26SARUNOMORI.xml b/assets/xml/scenes/Z2_26SARUNOMORI/Z2_26SARUNOMORI.xml index 5055f4ff3..83e362742 100644 --- a/assets/xml/scenes/Z2_26SARUNOMORI/Z2_26SARUNOMORI.xml +++ b/assets/xml/scenes/Z2_26SARUNOMORI/Z2_26SARUNOMORI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_30GYOSON/Z2_30GYOSON.xml b/assets/xml/scenes/Z2_30GYOSON/Z2_30GYOSON.xml index eca539742..f24a37254 100644 --- a/assets/xml/scenes/Z2_30GYOSON/Z2_30GYOSON.xml +++ b/assets/xml/scenes/Z2_30GYOSON/Z2_30GYOSON.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_31MISAKI/Z2_31MISAKI.xml b/assets/xml/scenes/Z2_31MISAKI/Z2_31MISAKI.xml index 918dc1ceb..afd35a817 100644 --- a/assets/xml/scenes/Z2_31MISAKI/Z2_31MISAKI.xml +++ b/assets/xml/scenes/Z2_31MISAKI/Z2_31MISAKI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_AYASHIISHOP/Z2_AYASHIISHOP.xml b/assets/xml/scenes/Z2_AYASHIISHOP/Z2_AYASHIISHOP.xml index c757263f3..3b03e8e5e 100644 --- a/assets/xml/scenes/Z2_AYASHIISHOP/Z2_AYASHIISHOP.xml +++ b/assets/xml/scenes/Z2_AYASHIISHOP/Z2_AYASHIISHOP.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_DOUJOU/Z2_DOUJOU.xml b/assets/xml/scenes/Z2_DOUJOU/Z2_DOUJOU.xml index 00e6702fa..a6b7a1a6a 100644 --- a/assets/xml/scenes/Z2_DOUJOU/Z2_DOUJOU.xml +++ b/assets/xml/scenes/Z2_DOUJOU/Z2_DOUJOU.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_KAJIYA/Z2_KAJIYA.xml b/assets/xml/scenes/Z2_KAJIYA/Z2_KAJIYA.xml index 6e73abc32..158669f8f 100644 --- a/assets/xml/scenes/Z2_KAJIYA/Z2_KAJIYA.xml +++ b/assets/xml/scenes/Z2_KAJIYA/Z2_KAJIYA.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_LOST_WOODS/Z2_LOST_WOODS.xml b/assets/xml/scenes/Z2_LOST_WOODS/Z2_LOST_WOODS.xml index 066cbe10e..0c41a1b29 100644 --- a/assets/xml/scenes/Z2_LOST_WOODS/Z2_LOST_WOODS.xml +++ b/assets/xml/scenes/Z2_LOST_WOODS/Z2_LOST_WOODS.xml @@ -1,5 +1,5 @@ - + diff --git a/assets/xml/scenes/Z2_ROMANYMAE/Z2_ROMANYMAE.xml b/assets/xml/scenes/Z2_ROMANYMAE/Z2_ROMANYMAE.xml index e49402a10..3ef612381 100644 --- a/assets/xml/scenes/Z2_ROMANYMAE/Z2_ROMANYMAE.xml +++ b/assets/xml/scenes/Z2_ROMANYMAE/Z2_ROMANYMAE.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_SINKAI/Z2_SINKAI.xml b/assets/xml/scenes/Z2_SINKAI/Z2_SINKAI.xml index d2f362453..6a3df8b2e 100644 --- a/assets/xml/scenes/Z2_SINKAI/Z2_SINKAI.xml +++ b/assets/xml/scenes/Z2_SINKAI/Z2_SINKAI.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_SONCHONOIE/Z2_SONCHONOIE.xml b/assets/xml/scenes/Z2_SONCHONOIE/Z2_SONCHONOIE.xml index 36168378b..72f476631 100644 --- a/assets/xml/scenes/Z2_SONCHONOIE/Z2_SONCHONOIE.xml +++ b/assets/xml/scenes/Z2_SONCHONOIE/Z2_SONCHONOIE.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_TORIDE/Z2_TORIDE.xml b/assets/xml/scenes/Z2_TORIDE/Z2_TORIDE.xml index c8e4a16c2..4003e785d 100644 --- a/assets/xml/scenes/Z2_TORIDE/Z2_TORIDE.xml +++ b/assets/xml/scenes/Z2_TORIDE/Z2_TORIDE.xml @@ -1,4 +1,5 @@ + diff --git a/assets/xml/scenes/Z2_YADOYA/Z2_YADOYA.xml b/assets/xml/scenes/Z2_YADOYA/Z2_YADOYA.xml index 9a2ad7080..03801385c 100644 --- a/assets/xml/scenes/Z2_YADOYA/Z2_YADOYA.xml +++ b/assets/xml/scenes/Z2_YADOYA/Z2_YADOYA.xml @@ -1,4 +1,5 @@ + diff --git a/diff_settings.py b/diff_settings.py index a6cee9dc8..4eeb4989c 100755 --- a/diff_settings.py +++ b/diff_settings.py @@ -5,4 +5,5 @@ def apply(config, args): config['myimg'] = 'mm.us.rev1.rom_uncompressed.z64' config['mapfile'] = 'build/mm.map' config['source_directories'] = ['./src','./include'] + config['objdump_flags'] = ['-M','reg-names=32'] config['makeflags'] = ['KEEP_MDEBUG=1'] diff --git a/docs/BUILDING_MACOS.md b/docs/BUILDING_MACOS.md new file mode 100644 index 000000000..77f1d839e --- /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/REVIEWING.md b/docs/REVIEWING.md new file mode 100644 index 000000000..11545fb27 --- /dev/null +++ b/docs/REVIEWING.md @@ -0,0 +1,59 @@ +# Reviewing Pull Requests to the Majora's Mask Decompilation Project + +Thanks for helping us reverse engineer *The Legend of Zelda: Majora's Mask*! +We encourage all contributors to participate in code review: this is your codebase too! +Every review submitted helps us keep code quality high and code merged in more quickly. + +This document is meant to be a set of tips and guidelines for reviewers of pull requests to the project. +For general information about the project, see [our readme](https://github.com/zeldaret/mm/blob/master/README.md). + +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. + +Other links are available in the [CONTRIBUTING.md](CONTRIBUTING.md) + + +## Getting Started + +### What should I know to take part in the review process? + +You should first famiiarise yourself with our [Contributing guide](CONTRIBUTING.md) and [Style guide](docs/STYLE.md). It is also recommended that you have already successfully submitted a merged pull request to understand how the process works before submitting a review. + + +## Pull Requests (PRs) + +### How to review a Pull Request + +- When reviewing a PR it is suggested that you follow the checklist outlined in this section. +- You are not required to go through *every* item in the checklist. It is meant as a guide; if you have only one thing you want to mention, that's fine too. +- Once the PR author has addressed all of your comments, you should add a review with approval to the PR to signify to the project leads that this PR has been through peer review. +- If someone does not address your comments and expresses that a different way is better than yours, look for feedback from other contributors (we encourage discussing this sort of thing in Discord, since long GitHub conversations get hard to read). The project leads will have final say in these situations. All decisions are generally guided by a consensus of contributors. + +### Reviewer Checklist +- [ ] Jenkins build is successful. + - [ ] `make` builds a matching ROM. + - [ ] `format.sh` was run. + - [ ] `spec` contains correct relocation files. + - [ ] Any new compiler warnings that were added are required for matching. Ensure there is good reason if the warnings files have changed. +- [ ] Files with `NON_MATCHING` functions have equivalent behaviour. +- [ ] `code` and `boot` segment files should be documented as much as possible. Overlays with documentation should be as complete as is reasonable. + - [ ] Overlays should have macros to define access to parameters if the parameter uses bitwise access. The params should have an enum when it makes sense. +- [ ] Comments and variables have correct spelling. +- [ ] The following should be declared in an Actor header file. There should be nothing else in the Actor header file. + - [ ] Main Actor struct + - [ ] Extern'd initVar data. + - [ ] Types used in the actor struct. Specific example would be actionFunc typedefs. + - [ ] Param field macros and/or enums. + - [ ] For any other additional `enum`/`struct`/`define`/`function`/`global`, there needs to be evidence it is needed in another file. +- [ ] New variables and functions should follow standard naming conventions. + - [ ] Constants are converted to whichever looks best in context: hexadecimal, decimal, or float + - [ ] Rotation angles should always be in hexadecimal + - [ ] Colour values should always be in decimal. + - [ ] Functions, structs, unions, enums, and typedefs are `TitleCase` (`DmRavine`) + - [ ] Functions within a system separate the system from the function's own subname with an underscore (`DmRavine_Init`) + - [ ] Variable names are `camelCase` (`actionFunc`) + - [ ] Global variables start with `g` (`gSaveContext`) + - [ ] Static global variables start with `s` (`sSphereInit`) + - [ ] Macros and enum constants are `SCREAMING_SNAKE_CASE` (`DM_RAVINE_STATE_ACTIVE`) + - [ ] Trailing commas in array and struct definitions chosen to make it look best (see e.g. `EnJcMatoDamageTable`) + +etc. diff --git a/docs/STYLE.md b/docs/STYLE.md new file mode 100644 index 000000000..6524e05d6 --- /dev/null +++ b/docs/STYLE.md @@ -0,0 +1,232 @@ +# Majora's Mask decompilation style guide + +In general, completed documented files are a good place to look to understand project style in general. + +## Types + +Use the types from `ultratypes.h`, not the standard C types: i.e. `u8`,`s8`,`s16`,`u16`,`s32`,`u32`,`f32` rather than `char`, `short`, `int`, `float` and their `signed`/`unsigned` varieties. + +We always write our enums and structs as `typedef`s. (Usually one can't use an enum typedef as a function argument since enum typedefs are implicitly `s32`.) + +## Naming + +Names are "big-endian": the most significant/largest part of the system goes first, e.g. `DM_RAVINE_STATE_ACTIVE` rather than `DM_RAVINE_ACTIVE_STATE`. + +| Type | Style | Example | +| -------------------- | ----------------------- | ----------------------- | +| Local variables | camelCase | `yawToPlayer` | +| Global variables | gCamelCase | `gSaveContext` | +| Static variables[^1] | sCamelCase | `sZeroVec` | +| Struct members | camelCase | `actionFunc` | +| Struct names | PascalCase | `EnFirefly` | +| Enum types | PascalCase | `EnFireflyMainType` | +| Enum values | SCREAMING_SNAKE_CASE | `AT_ON` | +| Defines/macros | SCREAMING_SNAKE_CASE | `SCREEN_WIDTH`,`ABS(x)` | +| Functions | SystemName_FunctionName | `Actor_SpawnAsChild` | +| Files | snake_case | `z_en_firefly.c` | + +[^1]: including in-function static + +Action functions are usually named with a simple present-tense verb or verb phrase: `{...}_Talk`, `{...}_Wait`, `{...}_FallToGround`, etc. Setup functions are `Setup{name of action}`. + +Ideally names should be both short and clear, although it's better to be clear than short. + +## Formatting + +A lot of formatting is done by clang-format, such as + +- indent is 4 spaces, tabs are not used +- case labels indented +- 120 column limit +- brackets go on the same line (`if (1) {`) +- pointer goes on type (`s32* var;` not `s32 *var;`) + +There are various other conventions that it does not catch, though: + +- Blank line between declarations and code: + ```c + s32 var; + + func(); + ``` +- combine declarations and definitions if possible: + ```c + s32 var = 0; + + func(); + ``` + instead of + ```c + s32 var; + + var = 0; + func(); + ``` +- blank lines between switch cases if they're long (use your judgement). + + +## Numbers + +### dec(imal) + +- timers +- colours and alpha +- Usually array accesses and sizes + +### hex(adecimal) + +- angles (for now; the code itself is very inconsistent with round hex, round dec, and degrees) +- Addresses +- Bitmasks (i.e. `& 0x80` etc.) +- Struct offset comments + +Numbers below `10`/`0xA` do not need the `0x` if by themselves in code. + +### Booleans + +If a function returns only `0` or `1`, and is used as a boolean (i.e. in conditionals), replace the returns by `false` and `true`. (We do not use `bool`, partly because is a C99 thing, and partly because the original has used almost every integer type as a boolean return at some point!) + +### Floats + +Floats usually need an `f` on the end to match, or IDO will use doubles. Our floats are always of the form `1.0f`, even when the decimal part is zero. + +## Conditionals/Loops + +- Spacing out conditional or loop blocks from surrounding code often makes them easier to read. +- Avoid assigning or mutating variables in conditionals if possible (including `++`/`--`), avoid side effects in the loop increment slot (i.e. incrementing/assigning to loop variables is fine, something like `*a = b++` is not). +- We *always* use `{}` on conditional/loop blocks, even if they're one line (clang-tidy will enforce this). +- When conditions are `&&`d or `||`d together, use brackets around each that includes an arithmetic comparison or bitwise operator (i.e. not `!var` or `func()`, but ones with `==` or `&` etc.) +- Flag checks or functions that return booleans do not need the `== 0`/`!= 0`. +- Prefer `if-else` over `if { return; }`, i.e. + ```c + if (cond) { + foo(); + } else { + bar(); + } + ``` + over + ```c + if (cond) { + foo(); + return; + } + bar(); + ``` +**Exception**: After `Actor_MarkForDeath` or sometimes setting the action function, if it makes sense to do so (this expresses the finality a bit better). + +## Macros and enums + +Become familiar with the various defines and enums we have available. There are too many to list all of them here, but the following are common: + +- Those in `macros.h` + - `ABS`, `ABS_ALT`, + - `CLAMP` and friends, + - `BINANG_*`, which are used for angles, especially when there's a lot of `s16` casts around +- `MTXMODE` for many of the `sys_matrix` functions +- CollisionCheck flags: `AT_ON` and so on. Pick the appropriate one for the collider type. +- Actor flags, `ACTOR_FLAG_N`. + +Damage flag enums are not being used at present: we want to wait until we have a better idea what the common groupings should be. + +Pre-C99, commas at the end of the last item in an enum will cause a compiler warning, so leave them off. + +All compound flag lists (e.g. `ACTOR_FLAG_4 | ACTOR_FLAG_8`) should be listed in *ascending* order + +## Arrays + +- It's better to not hardcode array sizes (easier to mod) +- Use `sizeof` or `ARRAY_COUNT`/`ARRAY_COUNTU` where it makes sense, e.g. in loops that are using an array. +- clang-format sometimes does weird things to array formatting. Experiment with and without a comma after the last element and see which looks better. + +## GlobalCtx2 + +In some particular instances, IDO requires the function argument `globalCtx` to be cast to a second variable of the same type to match. In these particular instances, the function argument should be renamed to `globalCtx2` and than this `globalCtx2` just assigned to a stack variable called `globalCtx`. This cast should occur before the actor `THIS` cast is made. For example in `z_en_firefly.c` +```c +void EnFirefly_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFirefly* this = THIS; +``` + +In other places the cast is actually not explictly needed, but a stack `pad` variable is still needed. For this there should just be a stack variable called `pad` of type `s32` before the actor `THIS` cast. For example in `z_bg_goron_oyu` +```c +void BgGoronOyu_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgGoronOyu* this = THIS; + CollisionHeader* colHeader = NULL; +``` + +In general, pads should be `s32`, or `s16`/`s8` if required. + + +## Documentation and Comments + +Documentation includes: +- Naming functions +- Naming struct variables +- Naming data +- Naming local variables +- Describing the general purpose of the file +- Describing any unusual, interesting or strange features of how the file or parts of its content work +- Labelling and explaining bugs +- Making enums or defines for significant numbers for the file, like actor params values. +- Naming the contents of the asset file(s) the file may use (for an actor, the object(s) it uses) + +If you are not sure what something does, it is better to leave it unnamed than name it wrongly. It is fine to make a note of something you are not sure about when PRing, it means the reviewers will pay special attention to it. + +We use comments for: +- Top of file: a short description of the system. For actors there is already a brief description of our current understanding, but feel free to add to it. +- For function descriptions, we use multiline comments, + ```c + /** + * Describe what the function does + */ + ``` + These are *optional*: if you think the code is clear enough, you do not need to put a comment. You can use Doxygen formatting if you think it adds something, but it is also not required. +- If something in a function is strange, or unintuitive, do leave a comment explaining what's going on. We use `//` for this. +- We also use `//` for temporary comments above a function. Feel free to use `TODO:` in these if appropriate. +- A bug should be commented with an `//! @bug Bug description` above the code that causes the bug. + +## What goes where + +This section mostly applies to actors. + +### Functions + +All functions should go in the main C file in the same order as the assembly (the latter is required to match anyway). (We may make exceptions for particularly large files with a particular organisational structure, but we ask that you check on Discord first before doing this) + +### Data + +- If in doubt, leave all the data at the top of the file. Reviewers will decide for you. +- Data must go in the same order as in the assembly files, but is only constrained by other data, not functions or rodata. +- Some data has to be inline static to match. Generally it's better to not use `static` on data outside funtions until the file is matching, since `static` data is left out of the mapfile and this makes debugging harder. +- *This is even more true of bss, where we have trouble with IDO unpredictably reordering it in certain files.* +- For small arrays or simple data that is used in only one function, we usually inline it, if it fits in the ordering. +- Generally data that is only used by the draw functions is put down near them: this is one of the few consistencies in ordering of actors' functions. + +### Enums and defines + +- Actors that bitpack params should have macros made for each access or write that is made. `z_en_dg.h` has an undocumented example, + ```c + #define ENDG_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + #define ENDG_GET_3E0(thisx) (((thisx)->params & 0x3E0) >> 5) + ``` + while `z_en_firefly.h` has a documented one, + ```c + #define KEESE_INVISIBLE (1 << 0xF) + #define KEESE_GET_MAIN_TYPE(thisx) ((thisx)->params & 0x7FFF) + ``` +- In a similar manner, actors that use `home.rot.(x|y|z)` like params should also macros made for accesses and writes. (See, e.g. `z_obj_bean.h`.) +- Stuff that only the actor itself will use goes in the C file unless needed in the header. +- Anything actor-specific that might be used by another file goes in the header, in particular params access macros. +- Anything that is expected to have widespread use should go in `macros.h` or an appropriate header in `include`. + +### Objects + +Are covered in the [ZAPD extraction xml spec](../tools/ZAPD/docs/zapd_extraction_xml_reference.md). Symbol names are `gPrefixDescriptionSuffix` for symbols accessed from the header (they will be global). Texture OutNames are in snake_case since they are filenames. + +## Above all else + +*All of the above is subservient to matching.* Sometimes IDO cares about newlines, for example. + +If you are not sure about any of the above, please ask in Discord. 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..4952f7586 --- /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, ActorShadow_DrawCircle, 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.save.inventory.items[10] == ITEM_NONE) { + this->actor.textId = 0x92E; + } else { + this->actor.textId = 0x932; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 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 { + Actor_PickUp(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void func_80952A1C(EnMs *this, GlobalContext *globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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_SetFocus(&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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (Message_ShouldAdvance(globalCtx) != 0)) { + this->actionFunc = func_80952734; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + if (Message_ShouldAdvance(globalCtx) != 0) { + func_801477B4(globalCtx); + Actor_PickUp((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 (Message_ShouldAdvance(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.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if ((s32) gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + func_8019F208(); + Actor_PickUp((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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (Message_ShouldAdvance(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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (Message_ShouldAdvance(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (Message_ShouldAdvance(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (Message_ShouldAdvance(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.save.playerData.rupees >= 0xA) { + goto block_13; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; +block_13: + if ((s32) gSaveContext.save.inventory.ammo[gItemSlots[0xA]] < 0x14) { + goto block_15; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; +block_15: + func_8019F208(); + Actor_PickUp((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.save.playerData.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.save.playerData.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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (Message_ShouldAdvance(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (Message_ShouldAdvance(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (Message_ShouldAdvance(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.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + Actor_PickUp((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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (Message_ShouldAdvance(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (Message_ShouldAdvance(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (Message_ShouldAdvance(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.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + Actor_PickUp((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.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + Actor_PickUp((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.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + Actor_PickUp((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 (Message_ShouldAdvance(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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (Message_ShouldAdvance(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (Message_ShouldAdvance(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (Message_ShouldAdvance(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + Actor_PickUp((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 = Message_GetState(&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 (Message_GetState(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (Message_ShouldAdvance(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + break; + + case 4: + if (Message_ShouldAdvance(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + Actor_PickUp((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 (Message_GetState(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (Message_ShouldAdvance(globalCtx) != 0) { + func_801477B4(globalCtx); + Actor_PickUp((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + } + break; + + case 4: + if (Message_ShouldAdvance(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.save.playerData.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.save.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + Actor_PickUp((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..13e5941fc --- /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. + +4. `if`'d-out section containing the `InitVars` and a few other common pieces of data. This can be ignored until we import the data. + +5. 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). These can simply be replaced by including the object file (see [Object Decompilation](object_decomp.md) for how this process works). + +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* animation, 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..0435becb4 --- /dev/null +++ b/docs/tutorial/contents.md @@ -0,0 +1,58 @@ +# 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 + +- [Documenting a decompiled file](documenting.md) + +## [Object Decompilation](object_decomp.md) +- 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..972451b07 --- /dev/null +++ b/docs/tutorial/data.md @@ -0,0 +1,165 @@ +# 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 and object symbols](#segmented-pointers-and-object-symbols) +- [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 and object symbols + +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.) + +For actors which have yet to be decompiled, this is mitigated by use of the file `undefined_syms.txt`, which feeds the linker the raw addresses to use as the symbol definitions. However, we want to replace these segmented addresses with proper object symbols whenever possible. In `En_Recepgirl_InitVars`, we can see that this actor uses the object `OBJECT_BG`: +```c +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, +}; +``` + +If we open up `assets/objects/object_bg.h`, we can see a bunch of different names corresponding to every asset in the object. You may notice that some of these names look a bit familiar; `object_bg_Tex_00F8F0` seems very close to the segmented address `(void*)0x600F8F0`. This is the proper object symbol for this segmented address, so we should `#include` this header in our actor and use these object symbols like so: +```c +static void* D_80C106B0[4] = { object_bg_Tex_00F8F0, object_bg_Tex_00FCF0, object_bg_Tex_0100F0, object_bg_Tex_00FCF0 }; +``` + +After replacing every segmented pointer with an object symbol, you should go ahead and delete every segmented pointer associated with this actor from `undefined_syms`. + +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..7e8435da9 --- /dev/null +++ b/docs/tutorial/documenting.md @@ -0,0 +1,583 @@ +# 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, +}; + +static void* D_80C106B0[4] = { object_bg_Tex_00F8F0, object_bg_Tex_00FCF0, object_bg_Tex_0100F0, object_bg_Tex_00FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +// #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, &object_bg_Skel_011B60, &object_bg_Anim_009890, 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 == &object_bg_Anim_001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 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 == &object_bg_Anim_00A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, -4.0f); + } + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + func_80C10290(this); + } else if (Actor_IsFacingPlayer(&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, &object_bg_Anim_00A280, -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 == &object_bg_Anim_00A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &object_bg_Anim_001384); + } else if (this->skelAnime.animation == &object_bg_Anim_00AD98) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00A280, -4.0f); + } + } + + temp_v0_2 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if ((temp_v0_2 == 5) && (Message_ShouldAdvance(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Flags_SetSwitch(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f); + if ((gSaveContext.save.weekEventReg[63] & 0x80)) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (this->actor.textId == 0x2ADC) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 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_RotateYS(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_MultVecX(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]); + + SkelAnime_DrawTransformFlexOpa(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_TransformLimbDraw`. 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 +static void* D_80C106B0[4] = { object_bg_Tex_00F8F0, object_bg_Tex_00FCF0, object_bg_Tex_0100F0, object_bg_Tex_00FCF0 }; +``` +actually are. We know they are set on segment 8, so we need to find where the skeleton uses them. We know from `object_bg_Skel_011B60` 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 `object_bg_Anim_000968`, 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 +static TexturePtr sEyeTextures[] = { object_bg_Tex_00F8F0, object_bg_Tex_00FCF0, object_bg_Tex_0100F0, object_bg_Tex_00FCF0 }; +``` + +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_RotateYS(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_MultVecX(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 == &object_bg_Anim_001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} + +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &object_bg_Anim_00A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, -4.0f); + } + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + func_80C10290(this); + } else if (Actor_IsFacingPlayer(&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, &object_bg_Anim_00A280, -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 == &object_bg_Anim_00A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &object_bg_Anim_001384); + } else if (this->skelAnime.animation == &object_bg_Anim_00AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_ChangeTransitionRepeat(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00A280, -4.0f); + } + } + + temp_v0_2 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + func_80C10148(this); + } else if ((temp_v0_2 == 5) && (Message_ShouldAdvance(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Flags_SetSwitch(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f); + if (gSaveContext.save.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, &object_bg_Anim_00AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 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 `Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0`. This is something to do with talking. The other function handles the rest of the conversation, and hands back to the first if `Message_GetState(&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(&object_tree_Colheader_001B2C, &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(&object_tree_Colheader_001B2C, &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..4eb22bf4f --- /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]; + SkelAnime_DrawTransformFlexOpa(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]); + + SkelAnime_DrawTransformFlexOpa(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 `SkelAnime_DrawTransformFlexOpa`. 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 SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor) +``` +The typedefs of the callbacks it uses are in `z64animation.h`: +```C +typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* thisx); + +typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* thisx); + +[...] + +typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx); +``` +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, TransformLimbDraw + +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 TransformLimbDraw, it has a much simpler prototype. mips2c gives +```C +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor) { + if (limbIndex == 5) { + Matrix_RotateYS((s16) (0x400 - actor->unk2AE), 1); + Matrix_MultVecX(500.0f, (Vec3f *) &actor->focus); + } +} +``` +There is only minor cleanup needed here: +- recasting the last argument, +- replacing the last argument of `Matrix_RotateYS` 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_RotateYS(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_MultVecX(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_RotateZYX(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_RotateZYX(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/broken_texture.png b/docs/tutorial/images/broken_texture.png new file mode 100644 index 000000000..6f79f1872 Binary files /dev/null and b/docs/tutorial/images/broken_texture.png differ diff --git a/docs/tutorial/images/custom_texture_in_game.png b/docs/tutorial/images/custom_texture_in_game.png new file mode 100644 index 000000000..92fa53811 Binary files /dev/null and b/docs/tutorial/images/custom_texture_in_game.png differ diff --git a/docs/tutorial/images/dns_custom_texture.png b/docs/tutorial/images/dns_custom_texture.png new file mode 100644 index 000000000..3b8cf4d57 Binary files /dev/null and b/docs/tutorial/images/dns_custom_texture.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_dns_deku_flower.png b/docs/tutorial/images/z64utils_dns_deku_flower.png new file mode 100644 index 000000000..66b40a3fd Binary files /dev/null and b/docs/tutorial/images/z64utils_dns_deku_flower.png differ diff --git a/docs/tutorial/images/z64utils_dns_display_list.png b/docs/tutorial/images/z64utils_dns_display_list.png new file mode 100644 index 000000000..31cbd5794 Binary files /dev/null and b/docs/tutorial/images/z64utils_dns_display_list.png differ diff --git a/docs/tutorial/images/z64utils_dns_head_limb.png b/docs/tutorial/images/z64utils_dns_head_limb.png new file mode 100644 index 000000000..dcb658fe8 Binary files /dev/null and b/docs/tutorial/images/z64utils_dns_head_limb.png differ diff --git a/docs/tutorial/images/z64utils_dns_limb_dlist.png b/docs/tutorial/images/z64utils_dns_limb_dlist.png new file mode 100644 index 000000000..0f24d0225 Binary files /dev/null and b/docs/tutorial/images/z64utils_dns_limb_dlist.png differ diff --git a/docs/tutorial/images/z64utils_dns_skeletonheader.png b/docs/tutorial/images/z64utils_dns_skeletonheader.png new file mode 100644 index 000000000..4f0222673 Binary files /dev/null and b/docs/tutorial/images/z64utils_dns_skeletonheader.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_open_dns.png b/docs/tutorial/images/z64utils_open_dns.png new file mode 100644 index 000000000..84533270e Binary files /dev/null and b/docs/tutorial/images/z64utils_open_dns.png differ diff --git a/docs/tutorial/images/z64utils_set_segment_8.png b/docs/tutorial/images/z64utils_set_segment_8.png new file mode 100644 index 000000000..46b2f1cff Binary files /dev/null and b/docs/tutorial/images/z64utils_set_segment_8.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..6178019c8 --- /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 Actor_PickUp +/* 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 { + Actor_PickUp(&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..79e1386cc --- /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..f210dd446 --- /dev/null +++ b/docs/tutorial/object_decomp.md @@ -0,0 +1,160 @@ +# Object Decompilation + +- Up: [Contents](contents.md) +- Previous: [Documenting](documenting.md) + +Object decompilation is the process of taking an object file and writing instructions to extract the various assets from it in the correct format, with appropriate labelling to distinguish their nature and/or use. + +## What is an object file? + +An object file is generally where most of the information used by overlays is stored. Its contents can include + +- Vertices (positional/normal/color data used by displaylists) +- Textures +- DisplayLists (instructions to the graphics processor on how to put together textures and vertices) +- Skeleton (The underlying structure of an actor's shape, that can be manipulated to change its "pose") +- Animations +- Texture Animations (instructions to scroll/cycle textures or change colors) + +## How we work with objects + +These objects are considered assets so they are not included in the repository directly. Instead we use the Zelda Asset Processor for Decompilation (ZAPD) to extract them from the ROM. As input, ZAPD takes an XML file that describes what and how to extract. Each object already has an autogenerated XML created in the `assets/xml/objects` directory, though they are incomplete with just autogenerated names. The goal of object decompilation is to complete these files by identifying any remaining blobs and giving everything proper names. + +## How to decomp an object + +Choose an object to decomp. As usual, some will be easier than others. For reasons explained shortly, it is much easier to decomp an object if all actors that use it are decompiled. + +### Files and folders + +Select the XML file of your selected object, which should be in `assets/xml/objects/object_name.xml`. + +The ZAPD output will go in the folder `assets/objects/object_name/`. You'll want this folder open later to check the output is correct. + +### Examining actor files + +All objects have had their XML generated in an automated way, so most constituent parts of each object are already identified, but will still need to be named and documented properly. Further, these objects usually have some blobs unreferenced by the object's own contents and hence not automatically extracted; most of the time these can be identified by looking at references in the actor which uses said object. + +### Extracting assets + +You can run `extract_assets.py` to extract the object's assets. Running it with no arguments extracts all files that have been updated since the last time it was run. You can also run it with `-s` (for single file), and give it the location of the object you want to extract relative to `assets`, i.e. + +```bash +./extract_assets.py -s objects/object_name +``` + +This should populate the folder you created earlier. ZAPD produces a C file containing the extracted object data, which will be `assets/objects/object_name/object_name.c`. Any data that you have not specified the type of, or is not referenced elsewhere in the object, is extracted as unknown blobs (usually named `unaccounted_XXXXXX`). Open the C file to see if there are any such blobs. (Some are just padding with 0s and can be ignored.) + +You now have to try and decipher these blobs using the [list of tools given below](#tools) to work out what they might be. In the case of unused parts of the object, this can be very difficult. + +### Naming + +You'll want to name everything that exists in the XML, but it helps to break it down into separate steps. After each step, extract the single asset again. + +1. First, name every piece of data that is directly accessed by another part of the repo (generally, but not always, actors). For most objects, this includes several of a skeleton, animations, some textures, and collision information. + +2. Then, name the limbs associated with each skeleton. This is usually straightforward, providing Z64Utils can show the skeleton properly. Note that when naming limbs, you should name them *from the object's perspective*, so the "left arm" is the one that is to the *object's* left. As part of this step, you should also replace the autogenerated enum values associated with each limb with an appropriate name. Another thing to note is that some limbs are considered "Root" limbs that are simply parents to other limbs and don't actually render anything themselves. In these cases, you can simply add `Root` to the limb name, e.g., `gGibdoRightLegRootLimb`. + +3. Next, name the display lists that are associated to limbs in the skeleton. Z64Utils can show you which display list is associated with a given limb. + +4. If any non-limb display lists still lack a name, try naming them now. + +5. Lastly, try to name every texture in the object. This can be a bit tricky just by looking at the textures, so it helps to see how they're used in the display lists. You can also try manipulating the textures, recompiling the game, and loading up the resulting ROM to see what your changes look like in-game. + +You'll notice that we didn't mention vertices in this list. This is because, for the most part, vertices are not used outside the object itself, and so are not required to have names. However, some actors have code that manipulates or otherwise interacts with vertices; in these cases, the vertices should be added to the XML and named. + +Current naming practice is to name each item in the xml using camelCase as usual, with the `g` prefix (for "global"), and the type of data last (`Skel`, `Anim`, `DL`, `Tex`, `TLUT`, `Vtx`, `TexAnim`, etc.), while output texture files are named in `snake_case`. TLUTs (texture look-up tables) should always have their output file end in `tlut`. For more info on which suffixes to use, check out the [ZAPD documentation on extraction XML](https://github.com/zeldaret/mm/blob/master/tools/ZAPD/docs/zapd_extraction_xml_reference.md). + +### Textures + +Since all objects have an autogenerated XML, most textures in the game already have an entry in an XML file. However, some did not get automatically detected, and textures can be especially troublesome due to the abundance of formats they can be in. Some are simple RGBA textures, while others use external palettes, and can look meaningless without. If the texture is used in a displaylist, it will tell you the format, but if not, you have to use your best judgement based on anything you know about its context. + +The order of operations is that palettes are loaded first, then the texture, and then the vertices to which it is applied. + +The first argument of `gsDPLoadTextureBlock` tells you the offset, the second the format, the third the bit depth, fourth the width and fifth the height + +The following is a list of the texture formats the Nintendo 64 supports, with their gfxdis names and ZAPD format names. + + +| Format name | Typing in `gsDPLoadTextureBlock` | "Format" in xml | +| ----------------------------------------------- | -------------------------------- | --------------- | +| 4-bit intensity (I) | `G_IM_FMT_I, G_IM_SIZ_4b` | i4 | +| 4-bit intensity with alpha (I/A) (3/1) | `G_IM_FMT_IA, G_IM_SIZ_4b` | ia4 | +| 4-bit color index (CI) | `G_IM_FMT_CI, G_IM_SIZ_4b` | ci4 | +| 8-bit I | `G_IM_FMT_I, G_IM_SIZ_8b` | i8 | +| 8-bit IA (4/4) | `G_IM_FMT_IA, G_IM_SIZ_8b` | ia8 | +| 8-bit CI | `G_IM_FMT_CI, G_IM_SIZ_8b` | ci8 | +| 16-bit red, green, blue, alpha (RGBA) (5/5/5/1) | `G_IM_FMT_RGBA, G_IM_SIZ_16b` | rgba16 | +| 16-bit IA (8/8) | `G_IM_FMT_IA, G_IM_SIZ_16b` | ia16 | +| 16-bit YUV (Luminance, Blue-Y, Red-Y) | `G_IM_FMT_YUV, G_IM_SIZ_16b` | (not used) | +| 32-bit RGBA (8/8/8/8) | `G_IM_FMT_RGBA, G_IM_SIZ_32b` | rgba32 | + +The 4-bit formats are loaded using `gDPLoadTextureBlock_4b`. The others use `gDPLoadTextureBlock`. + +For example, + +```c +gsDPLoadTextureBlock(D_06006110, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, 0, 0), +``` + +says that there is a texture at offset `0x6110`, its Format is `rgba16`, Width is `16` and Height is `16`, so we can declare + +```XML + +``` + +See [this web page](http://n64devkit.square7.ch/tutorial/graphics/3/3_3.htm) for more information about these formats, and [gSP functions](http://n64devkit.square7.ch/n64man/gsp/gSP_INDEX.htm) and [gDP functions](http://n64devkit.square7.ch/n64man/gdp/gDP_INDEX.htm) for more about the graphics functions used. + +The `ci` formats use palettes, which are declared separately. The shape you give the palette does not matter, but to avoid overlap errors it needs to fit into a rectangle; choose the one you think looks best, and if in doubt, just do height 1 and appropriate width. + +If in doubt, look at completed objects in the repo, and if still in doubt, ask. + +## 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) + +## Building and investigative modding + +Thankfully it is not necessary to do a full make from clean to check that a particular object file has been decompiled successfully. + +- With a valid xml file, run `extract_assets.py -s` on its object. +- `make` + +If you want to change a texture, for example to see precisely where it is used, the following steps ensure it will be used in the build + +- Change and save the texture. You can simply open the texture's PNG file in most image editors (e.g., Photoshop, GIMP, Paint, etc.) and edit it to your liking, though you'll need to keep the original palette in mind for palettized textures. +- Touch the object's main C file (in the same directory) +- make +- Ironically, ERROR 1 implies success (your new texture has changed the checksum). + +If you'd rather not have it tell you about the checksum, you can run `make COMPARE=0` instead. + +--- + +To revert to the original texture, you can just run `extract_assets.py -s` on the object again. + +N.B. doing this will overwrite every custom texture, as will running `make setup`. + +## Example + +An example of decompiling a particular object is given [here](object_decomp_example.md). + +## Tips and Tricks + +### Fixing improper-looking textures + +For CI4 and CI8 textures, you might see improper-looking textures like so: + +![An improper-looking CI8 texture](images/broken_texture.png) + +The reason this happens is because ZAPD couldn't determine the TLUT for the texture, so it couldn't use the proper palette. To fix this, you can supply a `TlutOffset` to the texture like so: +```xml + +``` + +### Understanding texture animations + +Texture animations are new to Majora's Mask, and they can be pretty tricky to understand. Luckily, there's some extensive documentation on how they're structured [here](https://github.com/zeldaret/mm/blob/master/tools/ZAPD/ZAPD/ZTextureAnimation.cpp). One useful thing to remember is that empty texture animations take the form of `00 00 00 06 00 00 00 00`. The process that automatically generated all the object XMLs sometimes failed to recognize this as an empty texture animation, so it puts it in various blobs or fails to account for it at all. + +Next: [The merging process](merging.md) \ No newline at end of file diff --git a/docs/tutorial/object_decomp_example.md b/docs/tutorial/object_decomp_example.md new file mode 100644 index 000000000..798167e68 --- /dev/null +++ b/docs/tutorial/object_decomp_example.md @@ -0,0 +1,258 @@ +# Object Decompilation Example + +- Previous: [Object Decompilation](object_decomp.md) + +Let's take a look at `object_dns`, which is a pretty typical NPC object. It's used by one actor: `ovl_En_Dns`. + +## Step 1: Naming the skeleton and limbs + +We already went through the steps of opening an object file in Z64Utils in the [documenting step](documenting.md#z64utils), but we'll do it in more detail here. First, search for the object file, then 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 OK. + +![Opening object_dns in Z64Utils](images/z64utils_open_dns.png) + +In the resulting window, go to "Analysis -> Find Dlists" and press OK (the defaults are usually fine). This will only find display lists, so to find everything else in the obect, do "Analysis -> Analyze Dlists". We're looking for the skeleton, so scroll down to the SkeletonHeader, right-click it, and select "Open in Skeleton Viewer": + +![Finding object_dns's SkeletonHeader in Z64Utils](images/z64utils_dns_skeletonheader.png) + +When you open the Skeleton Viewer, you'll see a list of animations off to the side. Selecting one of them will display an error that says something like `RENDER ERROR AT 0x06001A98! (Could not read 0x80 bytes at address 08000000)`. This is because one of the display lists in the skeleton is expecting something to be set at segment 8. From the actor, we know that it's expecting the eye textures to be loaded into segment 8 like so: +```c +static TexturePtr D_8092DE1C[] = { &D_060028E8, &D_06002968, &D_060029E8, &D_06002968 }; +[...] +gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); +``` + +Let's set segment 8 to be one of the eye textures listed here. Click on "Segments", then for segment 08, click "Edit" and select "Address" as the source. Input "060028E8" as the address, then hit OK. This should result in the window looking as follows: + +![Setting segment 8 to one of the eye textures in Z64Utils](images/z64utils_set_segment_8.png) + +Now that we've gotten around the error, we can see what each limb in the skeleton corresponds to by clicking on it in the Hierarchy. Clicking on any given limb will highlight what part of the model it represents in red. In the below example, this limb is clearly the head: + +![Showing the head limb in Z64Utils](images/z64utils_dns_head_limb.png) + +Note that some limbs don't actually render anything, so sometimes clicking on a limb will not turn anything red; this may indicate a "Root" limb that has no associated display list, or it may indicate something like an eye limb that doesn't have the right textures loaded to display anything in Z64Utils. It may be useful to skip ahead to [Step #5](#step-5-naming-limb-display-lists) to learn how to check if the limb has a display list. If it doesn't have a display list, then it's a "Root" limb that will never be highlighted. + +We can now start naming the skeleton and individual limbs. Since we know this particular skeleton is the King's Chamber Deku Guard, we can name the skeleton `gKingsChamberDekuGuardSkel`. For the LimbNone name, we can call it something like `KINGS_CHAMBER_DEKU_GUARD_LIMB_NONE`, and we can name the LimbMax similarly. For the EnumName, we can name it `KingsChamberDekuGuardLimbs`. For each individual limb, we can name them based on what we see in Z64Utils; just make sure to update both the Name and the EnumName. After naming everything, we have something that looks like this: +```xml + + + + + + + + + + + + + +``` + +Now we can run `./extract_assets.py -s objects/object_dns` to extract the object again, this time with our new names. What can we do with this? Quite a bit actually. In `z_en_dns.h`, we can add this to the top of the file to start using these new names in our code: +```c +#include "objects/object_dns/object_dns.h" +``` + +Now, we can redefine the `jointTable` and `morphTable` in terms of the limb enum we defined before, like so: +```c +/* 0x22A */ Vec3s jointTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX]; +/* 0x278 */ Vec3s morphTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX]; +``` + +We can also use our new skeleton name and limb enum when initialization the skeleton like so: +```c +SkelAnime_Init(globalCtx, &this->skelAnime, &gKingsChamberDekuGuardSkel, NULL, this->jointTable, this->morphTable, KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX); +``` + +Lastly, we can use our limb enum in `EnDns_PostLimbDraw`. Where the code originally had: +```c +if (limbIndex == 2) { + [...] +} +``` + +We can instead write: +```c +if (limbIndex == KINGS_CHAMBER_DEKU_GUARD_LIMB_HEAD) { + [...] +} +``` + +## Step 2: Naming the animations + +Now that we have the skeleton figured out, it's time to name all the animations. In the Skeleton Viewer, you can hit the "play" button on any animation to see what it looks like. Note that some objects have multiple skeletons, and selecting an animation that is associated with a different skeleton than the one you're looking at can cause odd behavior. Try to give each animation a descriptive name based on what it looks like. If you're struggling; +- Try viewing the animation in game. In what contexts does this animation play? +- Try analyzing the code for the actor to see when the animation is used. Is this animation ever referenced? +- If you're still really struggling, Majora's Mask 3D contains the original animation names for the majority of animations in the game. These original names can help you figure out what the developers were originally intending. Explaining how to find these animations in MM3D is outside of the scope of this document, so just ask in Discord if you want to try this. + +After naming the animations, the end result will look something like this: +```xml + + + + + + +[...] + + +``` + +Once again, we can run `./extract_assets.py -s objects/object_dns` to extract the object, and we can update the animation names in `z_en_dns.c` to use our new names like so: +```c +static AnimationInfoS sAnimations[] = { + { &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gKingsChamberDekuGuardSurpriseStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardSurpriseLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardRunStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardRunLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardDanceAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardFlipAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, +}; +``` + +## Step 3: Identifying the blob + +In the XML, you may notice undefined blobs like this: +```xml + +``` + +You might already have an idea as to what this is based on what you've seen before. Recall that the eye textures are referenced in the actor's code like this: +```c +static TexturePtr D_8092DE1C[] = { &D_060028E8, &D_06002968, &D_060029E8, &D_06002968 }; +``` + +Do you notice how the "28E8" in `D_060028E8` also appears as the Offset in that blob? That's because the blob is just the eye textures; the process for automatically creating the XML wasn't able to figure it out on its own, so we'll need to do it ourselves. But how should we define these textures in the XML? Recall that the eye textures were loaded into segment 8; let's take a look in `object_dns.c` and see if we can find something that uses this segment. This display list has the answer: +```c +Gfx object_dns_DL_001A50[] = { + [...] + gsDPLoadTextureBlock(0x08000000, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | + G_TX_CLAMP, 3, 3, G_TX_NOLOD, G_TX_NOLOD), + [...] +}; +``` + +Using `0x08000000` with `gsDPLoadTextureBlock` signals that this display list is expecting a texture in segment 8. What kind of texture is it expecting? We can look at the arguments after the `0x08000000`. It's looking for an RBGA16 texture with dimensions of 8x8, so we can define these textures in the XML like so: +```xml + + + +``` + +Now, we just have to name them. In [Step #1](#step-1-naming-the-skeleton-and-limbs), we set segment 8 to one of the eye textures; we can use that same technique with the other two eye textures to see what they are. Like most NPCs, these various eye textures are used for handling blinking, so we can name them based on how open the eye is: +```xml + + + +``` + +Like with previous steps, we can run `./extract_assets.py -s objects/object_dns` and then update `z_en_dns.c` with our new names: +```c +static TexturePtr sEyeTextures[] = { + gKingsChamberDekuGuardEyeOpenTex, + gKingsChamberDekuGuardEyeHalfTex, + gKingsChamberDekuGuardEyeClosedTex, + gKingsChamberDekuGuardEyeHalfTex, +}; +``` + +Note that this step might be tricky to do if multiple things in the actor use the same segment. It's okay to wait to do this until you've named all the display lists in the actor, since that will make it easier to find the display list associated with a given texture. + +## Step #4: Naming anything else in the actor + +For some actors, there may be a few other things left to name that are directly referenced in the actor's code. In our case, there is one display list that we still need to name: +```c +gSPDisplayList(POLY_OPA_DISP++, &D_06002C48); +``` + +In Z64Utils, scroll to find this display list, then right-click and select "Open in Dlist Viewer": + +![Opening dlist_00002C48 in Z64Utils](images/z64utils_dns_display_list.png) + +We can see this is the guard's Deku Flower: + +![Showing the guard's Deku Flower in Z64Utils](images/z64utils_dns_deku_flower.png) + +We can name the display list as such in the XML: +```xml + +``` + +Then, like all steps before, we can run `./extract_assets.py -s objects/object_dns` and then update `z_en_dns.c` with our new name: +```c +gSPDisplayList(POLY_OPA_DISP++, gKingsChamberDekuGuardDekuFlower); +``` + +## Step #5: Naming limb display lists + +Now that we've named everything that's used externally by the actor, we just need to clean up the rest of the unnamed stuff in the XML. Let's start by naming the display lists for each limb. There are two ways you can determine which display list is associated with a given limb. One way is to click on the limb in Z64Utils; it will tell you what display list is used for that limb: + +![Showing the head limb's display list in Z64Utils](images/z64utils_dns_limb_dlist.png) + +Another way is to simply check `object_dns.c`. Each limb lists its own display list like this: +```c +StandardLimb gKingsChamberDekuGuardHeadLimb = { + { 0, 1300, 0 }, KINGS_CHAMBER_DEKU_GUARD_LIMB_STALK - 1, KINGS_CHAMBER_DEKU_GUARD_LIMB_LEFT_FOOT - 1, + object_dns_DL_0018B8 +}; +``` + +Either way you go about it, you should be able to name all the limb display lists like so: +```xml + + + + + + + + + + + + +``` + +Run `./extract_assets.py -s objects/object_dns` once again, since it will help in the next step to have all of our display lists named. + +### Step #6: Naming remaining textures + +With every display list named, it's now a lot easier to name the remaining textures. In the `assets/objects/object_dns/` folder, you can see all the textures in the object as various PNG files. For some of the textures, just looking at them will give you a good idea as to what they should be named. For other textures, it may help to see how the texture is used in the object's display lists. Let's take a look at `object_dns_Tex_002868`, which is only used in one display list: +```c +Gfx gKingsChamberDekuGuardSnoutDL[] = { + [...] + gsDPLoadTextureBlock(object_dns_Tex_002868, G_IM_FMT_RGBA, G_IM_SIZ_16b, 8, 8, 0, G_TX_MIRROR | G_TX_CLAMP, + G_TX_MIRROR | G_TX_CLAMP, 3, 3, G_TX_NOLOD, G_TX_NOLOD), + [...] +}; +``` + +Since `tex_002868.rgba16.png` looks like the inside of the Deku Guard's mouth, and it's *only* used in the snout display list, you can probably name this something like `gKingsChamberDekuGuardMouthTex`. But rather than guessing, we can confirm it by editing the texture ourselves and then viewing it in-game. Using an image editor, let's change `tex_002868.rgba16.png` to this: + +![Our custom mouth texture](images/dns_custom_texture.png) + +Now, rebuild the game using [the steps described here](object_decomp.md#building-and-investigative-modding) and look at the guard in-game. You should see something like this: + +![Our custom mouth texture being shown in-game](images/custom_texture_in_game.png) + +This confirms our suspicion that this is indeed the mouth texture, so we can name it as such. We can use similar strategies to name all the other textures like so: +```xml + + + +``` + +### Step #7: Finishing up + +If you have any other unnamed assets, now's the time to identify them. Otherwise, finish up the file by putting a comment at the top above the `` node: +```xml + + + +``` + +And we're done! Hopefully, you found this example helpful when decompiling your own objects. \ 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..796939dd8 --- /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 (Actor_ProcessTalkRequest((Actor *) this, globalCtx) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsFacingPlayer((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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsFacingPlayer(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + func_80C10290(this); + } else if (Actor_IsFacingPlayer(&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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(globalCtx) != 0)) { + temp_v0_3 = this->actor.textId; + if (temp_v0_3 == 0x2AD9) { + Flags_SetSwitch(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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Flags_SetSwitch(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.save.weekEventReg[63] & 0x80`. Now it will compile. We also don't use `!= 0` for flag comparisons: just `if (gSaveContext.save.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 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(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/PR/abi.h b/include/PR/abi.h index 63d6b0f99..49d539762 100644 --- a/include/PR/abi.h +++ b/include/PR/abi.h @@ -1,7 +1,8 @@ -#ifndef _ABI_H_ -#define _ABI_H_ +#ifndef ULTRA64_ABI_H +#define ULTRA64_ABI_H /* Audio commands: */ +/* #define A_SPNOOP 0 #define A_ADPCM 1 #define A_CLEARBUFF 2 @@ -18,12 +19,37 @@ #define A_INTERLEAVE 13 #define A_POLEF 14 #define A_SETLOOP 15 +*/ +#define A_SPNOOP 0 +#define A_ADPCM 1 +#define A_CLEARBUFF 2 +#define A_UNK3 3 +#define A_ADDMIXER 4 +#define A_RESAMPLE 5 +#define A_RESAMPLE_ZOH 6 +#define A_FILTER 7 +#define A_SETBUFF 8 +#define A_DUPLICATE 9 +#define A_DMEMMOVE 10 +#define A_LOADADPCM 11 +#define A_MIXER 12 +#define A_INTERLEAVE 13 +#define A_HILOGAIN 14 +#define A_SETLOOP 15 +#define A_INTERL 17 +#define A_ENVSETUP1 18 +#define A_ENVMIXER 19 +#define A_LOADBUFF 20 +#define A_SAVEBUFF 21 +#define A_ENVSETUP2 22 +#define A_S8DEC 23 +#define A_UNK19 25 #define ACMD_SIZE 32 + /* * Audio flags */ - #define A_INIT 0x01 #define A_CONTINUE 0x00 #define A_LOOP 0x02 @@ -254,138 +280,252 @@ typedef short ENVMIX_STATE[40]; * Macros to assemble the audio command list */ -#define aADPCMdec(pkt, f, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_ADPCM, 24, 8) | _SHIFTL(f, 16, 8); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aADPCMdec(pkt, f, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_ADPCM, 24, 8) | _SHIFTL(f, 16, 8); \ + _a->words.w1 = (unsigned int)(s); \ +} -#define aPoleFilter(pkt, f, g, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_POLEF, 24, 8) | _SHIFTL(f, 16, 8) | \ - _SHIFTL(g, 0, 16)); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aPoleFilter(pkt, f, g, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_POLEF, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(g, 0, 16)); \ + _a->words.w1 = (unsigned int)(s); \ +} + +#define aHiLoGain(pkt, gain, count, dmem, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_HILOGAIN, 24, 8) | \ + _SHIFTL(gain, 16, 8) | _SHIFTL(count, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmem, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aUnkCmd3(pkt, a1, a2, a3) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_UNK3, 24, 8) | _SHIFTL(a3, 0, 16); \ + _a->words.w1 = _SHIFTL(a1, 16, 16) | _SHIFTL(a2, 0, 16); \ +} + +#define aUnkCmd19(pkt, a1, a2, a3, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_UNK19, 24, 8) | _SHIFTL(a1, 16, 8) | \ + _SHIFTL(a2, 0, 16)); \ + _a->words.w1 = _SHIFTL(a3, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aS8Dec(pkt, a1, a2) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_S8DEC, 24, 8) | _SHIFTL(a1, 16, 8); \ + _a->words.w1 = (unsigned int)(a2); \ +} #define aClearBuffer(pkt, d, c) \ - { \ +{ \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = _SHIFTL(A_CLEARBUFF, 24, 8) | _SHIFTL(d, 0, 24); \ _a->words.w1 = (unsigned int)(c); \ - } +} -#define aEnvMixer(pkt, f, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_ENVMIXER, 24, 8) | _SHIFTL(f, 16, 8); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aEnvMixer(pkt, dmemi, count, swapLR, x0, x1, x2, x3, m, bits) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (bits | _SHIFTL(dmemi >> 4, 16, 8) | \ + _SHIFTL(count, 8, 8) | _SHIFTL(swapLR, 4, 1) | \ + _SHIFTL(x0, 3, 1) | _SHIFTL(x1, 2, 1) | \ + _SHIFTL(x2, 1, 1) | _SHIFTL(x3, 0, 1)); \ + _a->words.w1 = (unsigned int)(m); \ +} -#define aInterleave(pkt, l, r) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_INTERLEAVE, 24, 8); \ - _a->words.w1 = _SHIFTL(l, 16, 16) | _SHIFTL(r, 0, 16); \ - } +#define aInterleave(pkt, o, l, r, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_INTERLEAVE, 24, 8) | \ + _SHIFTL(c >> 4, 16, 8) | _SHIFTL(o, 0, 16)); \ + _a->words.w1 = _SHIFTL(l, 16, 16) | _SHIFTL(r, 0, 16); \ +} -#define aLoadBuffer(pkt, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_LOADBUFF, 24, 8); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aInterl(pkt, dmemi, dmemo, count) \ +{ \ + Acmd *_a = (Acmd*)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_INTERL, 24, 8) | \ + _SHIFTL(count, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemi, 16, 16) | _SHIFTL(dmemo, 0, 16); \ +} -#define aMix(pkt, f, g, i, o) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_MIXER, 24, 8) | _SHIFTL(f, 16, 8) | \ - _SHIFTL(g, 0, 16)); \ - _a->words.w1 = _SHIFTL(i, 16, 16) | _SHIFTL(o, 0, 16); \ - } +#define aLoadBuffer(pkt, s, d, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_LOADBUFF, 24, 8) | \ + _SHIFTL((c) >> 4, 16, 8) | _SHIFTL(d, 0, 16); \ + _a->words.w1 = (unsigned int)(s); \ +} -#define aPan(pkt, f, d, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_PAN, 24, 8) | _SHIFTL(f, 16, 8) | \ - _SHIFTL(d, 0, 16)); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aMix(pkt, f, g, i, o) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_MIXER, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(g, 0, 16)); \ + _a->words.w1 = _SHIFTL(i, 16, 16) | _SHIFTL(o, 0, 16); \ +} -#define aResample(pkt, f, p, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_RESAMPLE, 24, 8) | _SHIFTL(f, 16, 8) | \ - _SHIFTL(p, 0, 16)); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aPan(pkt, f, d, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_PAN, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(d, 0, 16)); \ + _a->words.w1 = (unsigned int)(s); \ +} -#define aSaveBuffer(pkt, s) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_SAVEBUFF, 24, 8); \ - _a->words.w1 = (unsigned int)(s); \ - } +#define aResample(pkt, f, p, s) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_RESAMPLE, 24, 8) | \ + _SHIFTL(f, 16, 8) | _SHIFTL(p, 0, 16)); \ + _a->words.w1 = (unsigned int)(s); \ +} -#define aSegment(pkt, s, b) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_SEGMENT, 24, 8); \ - _a->words.w1 = _SHIFTL(s, 24, 8) | _SHIFTL(b, 0, 24); \ - } +#define aSaveBuffer(pkt, s, d, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_SAVEBUFF, 24, 8) | \ + _SHIFTL((c) >> 4, 16, 8) | _SHIFTL(s, 0, 16); \ + _a->words.w1 = (unsigned int)(d); \ +} + +#define aSegment(pkt, s, b) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_SEGMENT, 24, 8); \ + _a->words.w1 = _SHIFTL(s, 24, 8) | _SHIFTL(b, 0, 24); \ +} #define aSetBuffer(pkt, f, i, o, c) \ - { \ +{ \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = (_SHIFTL(A_SETBUFF, 24, 8) | _SHIFTL(f, 16, 8) | \ _SHIFTL(i, 0, 16)); \ - _a->words.w1 = _SHIFTL(c, 0, 16) | _SHIFTL(o, 16, 16); \ - } + _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ +} -#define aSetVolume(pkt, f, v, t, r) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ - _SHIFTL(v, 0, 16)); \ - /* had to change this otherwise it doesn't want to match */ \ - _a->words.w1 = (unsigned int)(r); /*_SHIFTL(r, 0, 16)|_SHIFTL(t, 16, 16) ;*/ \ - } +#define aSetVolume(pkt, f, v, t, r) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ + _SHIFTL(v, 0, 16)); \ + _a->words.w1 = _SHIFTL(r, 0, 16) | _SHIFTL(t, 16, 16); \ +} -#define aSetLoop(pkt, a) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - _a->words.w0 = _SHIFTL(A_SETLOOP, 24, 8); \ - _a->words.w1 = (unsigned int)(a); \ - } +#define aSetVolume32(pkt, f, v, tr) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_SETVOL, 24, 8) | _SHIFTL(f, 16, 16) | \ + _SHIFTL(v, 0, 16)); \ + _a->words.w1 = (unsigned int)(tr); \ +} -#define aDMEMMove(pkt, i, o, c) \ - { \ - Acmd *_a = (Acmd *)pkt; \ - \ - _a->words.w0 = _SHIFTL(A_DMEMMOVE, 24, 8) | _SHIFTL(i, 0, 24); \ - _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ - } +#define aSetLoop(pkt, a) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_SETLOOP, 24, 8); \ + _a->words.w1 = (unsigned int)(a); \ +} + +#define aDMEMMove(pkt, i, o, c) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_DMEMMOVE, 24, 8) | _SHIFTL(i, 0, 24); \ + _a->words.w1 = _SHIFTL(o, 16, 16) | _SHIFTL(c, 0, 16); \ +} #define aLoadADPCM(pkt, c, d) \ - { \ +{ \ Acmd *_a = (Acmd *)pkt; \ \ _a->words.w0 = _SHIFTL(A_LOADADPCM, 24, 8) | _SHIFTL(c, 0, 24); \ _a->words.w1 = (unsigned int)d; \ - } +} -#endif /* !_ABI_H_ */ + + +#define aEnvSetup1(pkt, a, b, c, d) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_ENVSETUP1, 24, 8) | \ + _SHIFTL(a, 16, 8) | _SHIFTL(b, 0, 16)); \ + _a->words.w1 = _SHIFTL(c, 16, 16) | _SHIFTL(d, 0, 16); \ +} + +#define aEnvSetup2(pkt, volLeft, volRight) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_ENVSETUP2, 24, 8); \ + _a->words.w1 = _SHIFTL(volLeft, 16, 16) | \ + _SHIFTL(volRight, 0, 16); \ +} + +#define aFilter(pkt, f, countOrBuf, addr) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = _SHIFTL(A_FILTER, 24, 8) | _SHIFTL(f, 16, 8) | \ + _SHIFTL(countOrBuf, 0, 16); \ + _a->words.w1 = (unsigned int)(addr); \ +} + +#define aDuplicate(pkt, count, dmemi, dmemo, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_DUPLICATE, 24, 8) | \ + _SHIFTL(count, 16, 8) | _SHIFTL(dmemi, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemo, 16, 16) | _SHIFTL(a4, 0, 16); \ +} + +#define aAddMixer(pkt, count, dmemi, dmemo, a4) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_ADDMIXER, 24, 8) | \ + _SHIFTL(count >> 4, 16, 8) | _SHIFTL(a4, 0, 16)); \ + _a->words.w1 = _SHIFTL(dmemi, 16, 16) | _SHIFTL(dmemo, 0, 16); \ +} + +#define aResampleZoh(pkt, pitch, pitchAccu) \ +{ \ + Acmd *_a = (Acmd *)pkt; \ + \ + _a->words.w0 = (_SHIFTL(A_RESAMPLE_ZOH, 24, 8) | \ + _SHIFTL(pitch, 0, 16)); \ + _a->words.w1 = _SHIFTL(pitchAccu, 0, 16); \ +} + +#endif /* ULTRA64_ABI_H */ diff --git a/include/PR/gbi.h b/include/PR/gbi.h index 2c04e570f..8e5aefe8e 100644 --- a/include/PR/gbi.h +++ b/include/PR/gbi.h @@ -1347,60 +1347,329 @@ typedef union { long int force_structure_alignment[4]; } Hilite; -#define gdSPDefLights0(ar,ag,ab) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ { 0, 0, 0},0,{ 0, 0, 0},0,{ 0, 0, 0},0}}} } -#define gdSPDefLights1(ar,ag,ab,r1,g1,b1,x1,y1,z1) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}} } -#define gdSPDefLights2(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}} } -#define gdSPDefLights3(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ - {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}} } -#define gdSPDefLights4(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ - {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ - {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}} } -#define gdSPDefLights5(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ - {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ - {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ - {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}} } +#define gdSPDefLights0(ar,ag,ab) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { 0, 0, 0 }, 0, \ + { 0, 0, 0 }, 0, \ + { 0, 0, 0 }, 0 \ + }} \ + } \ + } +#define gdSPDefLights1(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }} \ + } \ + } -#define gdSPDefLights6(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ - {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ - {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ - {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \ - {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}} } +#define gdSPDefLights2(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }} \ + } \ + } +#define gdSPDefLights3(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2, \ + r3,g3,b3, \ + x3,y3,z3) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }}, \ + {{ \ + { r3, g3, b3 }, 0, \ + { r3, g3, b3 }, 0, \ + { x3, y3, z3 }, 0 \ + }} \ + } \ + } -#define gdSPDefLights7(ar,ag,ab,r1,g1,b1,x1,y1,z1,r2,g2,b2,x2,y2,z2,r3,g3,b3,x3,y3,z3,r4,g4,b4,x4,y4,z4,r5,g5,b5,x5,y5,z5,r6,g6,b6,x6,y6,z6,r7,g7,b7,x7,y7,z7) \ - { {{ {ar,ag,ab},0,{ar,ag,ab},0}}, \ - {{{ {r1,g1,b1},0,{r1,g1,b1},0,{x1,y1,z1},0}}, \ - {{ {r2,g2,b2},0,{r2,g2,b2},0,{x2,y2,z2},0}}, \ - {{ {r3,g3,b3},0,{r3,g3,b3},0,{x3,y3,z3},0}}, \ - {{ {r4,g4,b4},0,{r4,g4,b4},0,{x4,y4,z4},0}}, \ - {{ {r5,g5,b5},0,{r5,g5,b5},0,{x5,y5,z5},0}}, \ - {{ {r6,g6,b6},0,{r6,g6,b6},0,{x6,y6,z6},0}}, \ - {{ {r7,g7,b7},0,{r7,g7,b7},0,{x7,y7,z7},0}}} } +#define gdSPDefLights4(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2, \ + r3,g3,b3, \ + x3,y3,z3, \ + r4,g4,b4, \ + x4,y4,z4) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }}, \ + {{ \ + { r3, g3, b3 }, 0, \ + { r3, g3, b3 }, 0, \ + { x3, y3, z3 }, 0 \ + }}, \ + {{ \ + { r4, g4, b4 }, 0, \ + { r4, g4, b4 }, 0, \ + { x4, y4, z4 }, 0 \ + }} \ + } \ + } +#define gdSPDefLights5(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2, \ + r3,g3,b3, \ + x3,y3,z3, \ + r4,g4,b4, \ + x4,y4,z4, \ + r5,g5,b5, \ + x5,y5,z5) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }}, \ + {{ \ + { r3, g3, b3 }, 0, \ + { r3, g3, b3 }, 0, \ + { x3, y3, z3 }, 0 \ + }}, \ + {{ \ + { r4, g4, b4 }, 0, \ + { r4, g4, b4 }, 0, \ + { x4, y4, z4 }, 0 \ + }}, \ + {{ \ + { r5, g5, b5 }, 0, \ + { r5, g5, b5 }, 0, \ + { x5, y5, z5 }, 0 \ + }} \ + } \ + } -#define gdSPDefLookAt(rightx,righty,rightz,upx,upy,upz) \ - { {{ {{0,0,0},0,{0,0,0},0,{rightx,righty,rightz},0}}, \ - { {{0,0x80,0},0,{0,0x80,0},0,{upx,upy,upz},0}}} } +#define gdSPDefLights6(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2, \ + r3,g3,b3, \ + x3,y3,z3, \ + r4,g4,b4, \ + x4,y4,z4, \ + r5,g5,b5, \ + x5,y5,z5, \ + r6,g6,b6, \ + x6,y6,z6) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }}, \ + {{ \ + { r3, g3, b3 }, 0, \ + { r3, g3, b3 }, 0, \ + { x3, y3, z3 }, 0 \ + }}, \ + {{ \ + { r4, g4, b4 }, 0, \ + { r4, g4, b4 }, 0, \ + { x4, y4, z4 }, 0 \ + }}, \ + {{ \ + { r5, g5, b5 }, 0, \ + { r5, g5, b5 }, 0, \ + { x5, y5, z5 }, 0 \ + }}, \ + {{ \ + { r6, g6, b6 }, 0, \ + { r6, g6, b6 }, 0, \ + { x6, y6, z6 }, 0 \ + }} \ + } \ + } + +#define gdSPDefLights7(ar,ag,ab, \ + r1,g1,b1, \ + x1,y1,z1, \ + r2,g2,b2, \ + x2,y2,z2, \ + r3,g3,b3, \ + x3,y3,z3, \ + r4,g4,b4, \ + x4,y4,z4, \ + r5,g5,b5, \ + x5,y5,z5, \ + r6,g6,b6, \ + x6,y6,z6, \ + r7,g7,b7, \ + x7,y7,z7) \ + { \ + {{ \ + { ar, ag, ab }, 0, \ + { ar, ag, ab }, 0 \ + }}, \ + { \ + {{ \ + { r1, g1, b1 }, 0, \ + { r1, g1, b1 }, 0, \ + { x1, y1, z1 }, 0 \ + }}, \ + {{ \ + { r2, g2, b2 }, 0, \ + { r2, g2, b2 }, 0, \ + { x2, y2, z2 }, 0 \ + }}, \ + {{ \ + { r3, g3, b3 }, 0, \ + { r3, g3, b3 }, 0, \ + { x3, y3, z3 }, 0 \ + }}, \ + {{ \ + { r4, g4, b4 }, 0, \ + { r4, g4, b4 }, 0, \ + { x4, y4, z4 }, 0 \ + }}, \ + {{ \ + { r5, g5, b5 }, 0, \ + { r5, g5, b5 }, 0, \ + { x5, y5, z5 }, 0 \ + }}, \ + {{ \ + { r6, g6, b6 }, 0, \ + { r6, g6, b6 }, 0, \ + { x6, y6, z6 }, 0 \ + }}, \ + {{ \ + { r7, g7, b7 }, 0, \ + { r7, g7, b7 }, 0, \ + { x7, y7, z7 }, 0 \ + }} \ + } \ + } + +#define gdSPDefLookAt(rightx,righty,rightz,upx,upy,upz) \ + {{ \ + {{ \ + { 0, 0, 0 }, 0, \ + { 0, 0, 0 }, 0, \ + { rightx, righty, rightz }, 0 \ + }}, \ + {{ \ + { 0, 0x80, 0 }, 0, \ + { 0, 0x80, 0 }, 0, \ + { upx, upy, upz }, 0 \ + }} \ + }} + +#define qs1616(e) ((s32)((e) * 0x00010000)) + +#define IPART(x) ((qs1616(x) >> 16) & 0xFFFF) +#define FPART(x) (qs1616(x) & 0xFFFF) + +#define gdSPDefMtx( \ + xx, yx, zx, wx, \ + xy, yy, zy, wy, \ + xz, yz, zz, wz, \ + xw, yw, zw, ww) \ + {{ \ + (IPART(xx) << 0x10) | IPART(xy), \ + (IPART(xz) << 0x10) | IPART(xw), \ + (IPART(yx) << 0x10) | IPART(yy), \ + (IPART(yz) << 0x10) | IPART(yw), \ + (IPART(zx) << 0x10) | IPART(zy), \ + (IPART(zz) << 0x10) | IPART(zw), \ + (IPART(wx) << 0x10) | IPART(wy), \ + (IPART(wz) << 0x10) | IPART(ww), \ + (FPART(xx) << 0x10) | FPART(xy), \ + (FPART(xz) << 0x10) | FPART(xw), \ + (FPART(yx) << 0x10) | FPART(yy), \ + (FPART(yz) << 0x10) | FPART(yw), \ + (FPART(zx) << 0x10) | FPART(zy), \ + (FPART(zz) << 0x10) | FPART(zw), \ + (FPART(wx) << 0x10) | FPART(wy), \ + (FPART(wz) << 0x10) | FPART(ww), \ + }} /* * Graphics DMA Packet @@ -2899,6 +3168,9 @@ _DW({ \ gsSPSetOtherMode(G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 2, mode) #endif + #define gDPSetDither(pkt, mode) \ + gSPSetOtherMode(pkt, G_SETOTHERMODE_H, G_MDSFT_ALPHADITHER, 4, mode) + /* 'blendmask' is not supported anymore. * The bits are reserved for future use. * Fri May 26 13:45:55 PDT 1995 diff --git a/include/PR/pfs.h b/include/PR/pfs.h index ff7f72bc5..596fafbfe 100644 --- a/include/PR/pfs.h +++ b/include/PR/pfs.h @@ -134,4 +134,8 @@ typedef struct { /* 0x101 */ u8 map[PFS_INODE_DIST_MAP]; } __OSInodeCache; // size = 0x202 +s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check); +s32 __osGetId(OSPfs* pfs); +s32 osPfsChecker(OSPfs* pfs); + #endif diff --git a/include/PR/sched.h b/include/PR/sched.h new file mode 100644 index 000000000..d0aac1d0e --- /dev/null +++ b/include/PR/sched.h @@ -0,0 +1,38 @@ +#ifndef SCHED_H +#define SCHED_H + +#include "PR/ultratypes.h" +#include "ultra64/vi.h" +#include "ultra64/sptask.h" + +#define OS_SC_NEEDS_RDP 0x0001 +#define OS_SC_NEEDS_RSP 0x0002 +#define OS_SC_DRAM_DLIST 0x0004 +#define OS_SC_PARALLEL_TASK 0x0010 +#define OS_SC_LAST_TASK 0x0020 +#define OS_SC_SWAPBUFFER 0x0040 + +#define OS_SC_RCP_MASK 0x0003 +#define OS_SC_TYPE_MASK 0x0007 + +#define OS_SC_DP 0x0001 +#define OS_SC_SP 0x0002 +#define OS_SC_YIELD 0x0010 +#define OS_SC_YIELDED 0x0020 + +typedef struct OSScTask { + /* 0x00 */ struct OSScTask* next; + /* 0x04 */ u32 state; + /* 0x08 */ u32 flags; + /* 0x0C */ void* framebuffer; + /* 0x10 */ OSTask list; + /* 0x50 */ OSMesgQueue* msgQ; + /* 0x54 */ OSMesg msg; +} OSScTask; // size = 0x58 + +typedef struct { + /* 0x0 */ s16 type; + /* 0x2 */ u8 misc[30]; +} OSScMsg; + +#endif diff --git a/include/PR/ultratypes.h b/include/PR/ultratypes.h index 0e6f4cf39..8b4e1a82c 100644 --- a/include/PR/ultratypes.h +++ b/include/PR/ultratypes.h @@ -27,6 +27,10 @@ typedef void* TexturePtr; typedef long int Mtx_t[4][4]; typedef union { Mtx_t m; + struct { + u16 intPart[4][4]; + u16 fracPart[4][4]; + }; long long int forc_structure_alignment; } Mtx; // size = 0x40 @@ -34,10 +38,10 @@ typedef float MtxF_t[4][4]; typedef union { MtxF_t mf; struct { - float xx, xy, xz, xw, - yx, yy, yz, yw, - zx, zy, zz, zw, - wx, wy, wz, ww; + float xx, yx, zx, wx, + xy, yy, zy, wy, + xz, yz, zz, wz, + xw, yw, zw, ww; }; } MtxF; // size = 0x40 diff --git a/include/assert.h b/include/assert.h deleted file mode 100644 index 04831e48f..000000000 --- a/include/assert.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef _ASSERT_H_ -#define _ASSERT_H_ - -#endif diff --git a/include/bgm.h b/include/bgm.h deleted file mode 100644 index 4cd19c957..000000000 --- a/include/bgm.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef BGM_H -#define BGM_H - -#define NA_BGM_STOP 0x100000FF - -#endif diff --git a/include/color.h b/include/color.h index 06cf63972..438d857ad 100644 --- a/include/color.h +++ b/include/color.h @@ -3,6 +3,9 @@ #include "PR/ultratypes.h" +// For checking the alpha bit in an RGBA16 pixel +#define RGBA16_PIXEL_OPAQUE 1 + typedef struct { /* 0x0 */ u8 r; /* 0x1 */ u8 g; diff --git a/include/command_macros_base.h b/include/command_macros_base.h index c0d2ac4e8..4a866c29e 100644 --- a/include/command_macros_base.h +++ b/include/command_macros_base.h @@ -3,7 +3,7 @@ /** * Command Base macros intended for use in designing of more specific command macros - * Each macro packs bytes (B), halfowrds (H) and words (W, for consistency) into a single word + * Each macro packs bytes (B), halfwords (H) and words (W, for consistency) into a single word */ #define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8)) @@ -16,6 +16,12 @@ #define CMD_W(a) (a) -#define CMD_PTR(a) (u32)(a) +#ifdef __GNUC__ +#define CMD_F(a) .f = (a) +#else +#define CMD_F(a) (a) +#endif + +#define CMD_PTR(a) (uintptr_t)(a) #endif diff --git a/include/functions.h b/include/functions.h index 6f977f711..0c7256309 100644 --- a/include/functions.h +++ b/include/functions.h @@ -3,28 +3,20 @@ #include "z64.h" -float fabsf(float f); -#pragma intrinsic(fabsf) -float sqrtf(float f); -#pragma intrinsic(sqrtf) -double sqrt(double d); -#pragma intrinsic(sqrt) - void bootproc(void); void Idle_ThreadEntry(void* arg); void ViConfig_UpdateVi(u32 arg0); void ViConfig_UpdateBlack(void); -s32 DmaMgr_DMARomToRam(u32 src, void* dst, size_t size); -void DmaMgr_DmaCallback0(OSPiHandle* piHandle, OSIoMesg* mb, s32 direction); +s32 DmaMgr_DmaRomToRam(u32 src, void* dst, size_t size); +s32 DmaMgr_DmaHandler(OSPiHandle* piHandle, OSIoMesg* mb, s32 direction); DmaEntry* DmaMgr_FindDmaEntry(u32 vromAddr); u32 DmaMgr_TranslateVromToRom(u32 vromAddr); s32 DmaMgr_FindDmaIndex(u32 vromAddr); const char* func_800809F4(u32 param_1); void DmaMgr_ProcessMsg(DmaRequest* req); void DmaMgr_ThreadEntry(void* arg); -s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, u32 vromStart, size_t size, UNK_TYPE4 unused, - OSMesgQueue* callback, void* callbackMesg); -s32 DmaMgr_SendRequest0(void* vramStart, u32 vromStart, size_t size); +s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, uintptr_t vromStart, size_t size, UNK_TYPE4 unused, OSMesgQueue* callback, void* callbackMesg); +s32 DmaMgr_SendRequest0(void* vramStart, uintptr_t vromStart, size_t size); void DmaMgr_Start(void); void DmaMgr_Stop(void); void* Yaz0_FirstDMA(void); @@ -53,9 +45,9 @@ void __osSyncVPrintf(const char* fmt, ...); void osSyncPrintf(const char* fmt, ...); void rmonPrintf(const char* fmt, ...); void Fault_SleepImpl(u32 duration); -void Fault_AddClient(FaultClient* client, fault_client_func callback, void* param0, void* param1); +void Fault_AddClient(FaultClient* client, void* callback, void* param0, void* param1); void Fault_RemoveClient(FaultClient* client); -void Fault_AddAddrConvClient(FaultAddrConvClient* client, FaultAddrConvFunc callback, void* param); +void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* param); void Fault_RemoveAddrConvClient(FaultAddrConvClient* client); void* Fault_ConvertAddress(void* addr); void Fault_Sleep(u32 duration); @@ -78,7 +70,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); @@ -103,12 +95,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); @@ -156,25 +148,21 @@ void GfxPrint_Open(GfxPrint* printer, Gfx* dList); Gfx* GfxPrint_Close(GfxPrint* printer); s32 GfxPrint_VPrintf(GfxPrint* printer, const char* fmt, va_list args); s32 GfxPrint_Printf(GfxPrint* printer, const char* fmt, ...); -void MtxConv_F2L(MatrixInternal* m1, MtxF* m2); -void MtxConv_L2F(MtxF* m1, MatrixInternal* m2); +void MtxConv_F2L(Mtx* m1, MtxF* m2); +void MtxConv_L2F(MtxF* m1, Mtx* m2); void __assert(const char* file, u32 lineNum); // void func_800862B4(void); void* SystemArena_MallocMin1(u32 size); -void SystemArena_FreeNull(void* pvParm1); -void func_8008633C(u32 param_1, s32 param_2, s32 param_3, UNK_PTR param_4); -void func_800863AC(u32 param_1, s32 param_2, s32 param_3, UNK_PTR param_4); -// void func_8008641C(void); -// void func_800864EC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80086588(void); -void SystemArena_Init(u32 base, u32 size); +void SystemArena_FreeNullCheck(void* ptr); +void SystemArena_RunInits(void); +void SystemArena_Init(void* start, size_t size); s32 func_80086620(OSMesgQueue* param_1, PadMgr* param_2, OSContStatus* param_3); // void func_80086760(void); // void func_80086794(void); // 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); @@ -202,16 +190,7 @@ s32 func_80086D40(f64 param_1); f64 func_80086D6C(f64 param_1); s32 func_80086D8C(f32 param_1); s32 func_80086DAC(f64 param_1); -void* SystemArena_Malloc(size_t size); -void* SystemArena_MallocR(size_t size); -void* SystemArena_Realloc(void* oldPtr, size_t newSize); -void SystemArena_Free(void* ptr); -void* SystemArena_Calloc(u32 elements, size_t size); -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 SystemArena_CheckArena(void); -void SystemArena_InitArena(void* start, size_t size); -void SystemArena_Cleanup(void); -u8 SystemArena_IsInitialized(void); + s32 Rand_Next(void); void Rand_Seed(u32 seed); f32 Rand_ZeroOne(void); @@ -220,20 +199,7 @@ void Rand_Seed_Variable(u32* rndNum, u32 seed); u32 Rand_Next_Variable(u32* param_1); f32 Rand_ZeroOne_Variable(u32* param_1); f32 Rand_Centered_Variable(u32* param_1); -void ArenaImpl_LockInit(Arena* heap); -void ArenaImpl_Lock(Arena* heap); -void ArenaImpl_Unlock(Arena* heap); -ArenaNode* ArenaImpl_GetLastBlock(Arena* param_1); -void __osMallocInit(Arena* heap, void* heapBase, size_t heapSize); -void __osMallocAddBlock(Arena* heap, void* start, s32 size); -void __osMallocCleanup(Arena* heap); -u8 __osMallocIsInitalized(Arena* heap); -void* __osMalloc(Arena* heap, size_t size); -void* __osMallocR(Arena* heap, size_t size); -void __osFree(Arena* heap, void* ptr); -void* __osRealloc(Arena* heap, void* oldPtr, size_t newSize); -void __osAnalyzeArena(Arena* heap, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -u32 __osCheckArena(Arena* heap); + void* proutSprintf(void* s, const char* buf, size_t n); s32 vsprintf(char* dst, char* fmt, va_list args); s32 sprintf(char* s, char* fmt, ...); @@ -246,7 +212,7 @@ void Sleep_Msec(u32 ms); void Sleep_Sec(u32 sec); // void __osSetCause(void); s32 osSendMesg(OSMesgQueue* mq, OSMesg msg, s32 flags); -// void osPfsFreeBlocks(void); +s32 osPfsFreeBlocks(OSPfs* pfs, s32* leftoverBytes); void osViExtendVStart(u32 param_1); void osStopThread(OSThread* t); s32 osRecvMesg(OSMesgQueue* mq, OSMesg* msg, s32 flags); @@ -254,7 +220,7 @@ OSIntMask osSetIntMask(OSIntMask im); // OSIntMask osGetIntMask(void); // void osVoiceSetWord(void); // void guScale(void); -f32 __sinf(f32 __x); +f32 sinf(f32 __x); s16 sins(u16 x); OSTask* _VirtualToPhysicalTask(OSTask* intp); void osSpTaskLoad(OSTask* intp); @@ -283,9 +249,7 @@ void __osDequeueThread(OSThread** param_1, OSThread* param_2); void osDestroyThread(OSThread* puParm1); // void __osVoiceCheckResult(void); void bzero(void* begin, s32 length); -s32 osSetRumble(OSPfs* pfs, u32 vibrate); -// void osSetUpMempakWrite(void); -// void osProbeRumblePak(void); + void __osSiCreateAccessQueue(void); void __osSiGetAccess(void); void __osSiRelAccess(void); @@ -314,9 +278,9 @@ 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); -// void __osPfsGetStatus(void); +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); void guMtxIdentF(float mf[4][4]); @@ -325,8 +289,8 @@ void osViSetMode(OSViMode* modep); // void __osSetConfig(void); void guLookAtF(float mf[4][4], f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp); void guLookAt(Mtx* m, f32 xEye, f32 yEye, f32 zEye, f32 xAt, f32 yAt, f32 zAt, f32 xUp, f32 yUp, f32 zUp); -// void osPfsAllocateFile(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 __osPfsDeclearPage(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); +s32 osPfsAllocateFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName, s32 fileSize, s32* fileNo); +s32 __osPfsDeclearPage(OSPfs* pfs, __OSInode* inode, s32 fileSizeInPages, s32* startPage, u8 bank, s32* decleared, s32* finalPage); s32 osStopTimer(OSTimer* t); u32 __osProbeTLB(void* param_1); void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQ, OSMesg* cmdBuf, s32 cmdMsgCnt); @@ -340,13 +304,12 @@ u16 __osSumcalc(u8* ptr, s32 length); s32 __osIdCheckSum(u16* ptr, u16* checkSum, u16* idSum); s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid); // void __osCheckPackId(void); -// void __osGetId(void); s32 __osCheckId(OSPfs* pfs); s32 __osPfsRWInode(OSPfs* pfs, __OSInode* inode, u8 flag, u8 bank); u32 osGetCount(void); void guMtxL2F(MtxF* m1, Mtx* m2); u32 osGetMemSize(void); -// void osPfsFindFile(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); +s32 osPfsFindFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName, s32* fileNo); void osSetEventMesg(OSEvent e, OSMesgQueue* mq, OSMesg m); f32 sqrtf(f32 __x); s32 osAfterPreNMI(void); @@ -360,13 +323,13 @@ void _Putfld(_Pft* px, va_list* pap, u8 code, u8* ac); void osUnmapTLBAll(void); s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction); // void __osVoiceContRead2(void); -// void __osVoiceContDataCrc(void); +u8 __osVoiceContDataCrc(u8* data, size_t numBytes); const char* strchr(const char* __s, s32 __c); size_t strlen(const char* __s); void* memcpy(void* __dest, const void* __src, size_t __n); void osCreateMesgQueue(OSMesgQueue* mq, OSMesg* msq, s32 count); -void osInvalICache(void* vaddr, s32 nbytes); -void osInvalDCache(void* vaddr, s32 nbytes); +void osInvalICache(void* vaddr, size_t nbytes); +void osInvalDCache(void* vaddr, size_t nbytes); void __osTimerServicesInit(void); void __osTimerInterrupt(void); void __osSetTimerIntr(OSTime tim); @@ -390,7 +353,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); // void osVoiceInit(void); -// void __osContChannelReset(void); +s32 __osContChannelReset(OSMesgQueue* mq, s32 channel); // void __osVoiceSetADConverter(void); s32 osAiSetFrequency(u32 frequency); s32 __osContRamRead(OSMesgQueue* mq, s32 channel, u16 address, u8* buffer); @@ -414,8 +377,8 @@ void __osRestoreInt(OSIntMask im); void __osViInit(void); void __osViSwapContext(void); OSMesgQueue* osPiGetCmdQueue(void); -f32 __cosf(f32 __x); -// void osEPiReadIo(void); +f32 cosf(f32 __x); +s32 osEPiReadIo(OSPiHandle* pihandle, u32 devAddr, u32* data); void osViSetSpecialFeatures(u32 func); s16 coss(u16 x); void osSetTime(OSTime ticks); @@ -435,10 +398,8 @@ u32 __osGetFpcCsr(void); // void osPfsInitPak(void); // void __osPfsCheckRamArea(void); // void osPfsChecker(void); -// void corrupted_init(void); -// void corrupted(void); u32 osAiGetLength(void); -// void osEPiWriteIo(void); +s32 osEPiWriteIo(OSPiHandle* pihandle, u32 devAddr, u32 data); void osMapTLBRdb(void); void osYieldThread(void); // void guTranslate(void); @@ -456,7 +417,7 @@ s32 __osSiRawWriteIo(u32 devAddr, u32 data); u32 __osSpGetStatus(void); void __osSpSetStatus(u32 value); void osCreateViManager(OSPri pri); -void viMgrMain(OSDevMgr* iParm1); +// void viMgrMain(OSDevMgr* iParm1); __OSViContext* __osViGetCurrentContext(void); void osWritebackDCacheAll(void); OSThread* __osGetCurrFaultedThread(void); @@ -476,8 +437,8 @@ float __ull_to_f(unsigned long long l); // void osVoiceCheckWord(void); // void osVoiceControlGain(void); // void osVoiceStartReadData(void); -void* osViGetCurrentFramebuffer(void); -s32 __osSpSetPc(void* data); +u32* osViGetCurrentFramebuffer(void); +s32 __osSpSetPc(void* pc); // void __osVoiceContWrite4(void); void __osGetHWIntrRoutine(s32 idx, OSMesgQueue** outQueue, OSMesg* outMsg); void __osSetHWIntrRoutine(s32 idx, OSMesgQueue* queue, OSMesg msg); @@ -504,58 +465,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(void); -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(void); -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(EffTireMarkParams* 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); @@ -577,177 +523,140 @@ s16 func_800B09D0(s16 a0, s16 a1, f32 a2); u8 func_800B0A24(u8 a0, u8 a1, f32 a2); void EffectSs_DrawGEffect(GlobalContext* globalCtx, EffectSs* this, void* texture); void EffectSsDust_Spawn(GlobalContext* globalCtx, u16 drawFlags, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life, u8 updateMode); -void func_800B0DE0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep); -void func_800B0E48(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep); -void func_800B0EB0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); -void func_800B0F18(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); -void func_800B0F80(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); -void func_800B0FE8(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep); -void func_800B1054(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor, s16 scale, s16 scaleStep); +void func_800B0DE0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep); +void func_800B0E48(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep); +void func_800B0EB0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); +void func_800B0F18(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); +void func_800B0F80(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep, s16 life); +void func_800B0FE8(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep); +void func_800B1054(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 scaleStep); void func_800B10C0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel); void func_800B1130(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel); void func_800B11A0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep); void func_800B1210(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep); -void func_800B1280(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, - s16 life); -void func_800B12F0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, - s16 life); -void func_800B1360(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor); -void func_800B139C(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, - Color_RGBA8* envColor); +void func_800B1280(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life); +void func_800B12F0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life); +void func_800B1360(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor); +void func_800B139C(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor); void func_800B13D8(Vec3f* srcPos, f32 randScale, Vec3f* newPos, Vec3f* velocity, Vec3f* accel); void func_800B14D4(GlobalContext* globalCtx, f32 randScale, Vec3f* srcPos); void func_800B1598(GlobalContext* globalCtx, f32 randScale, Vec3f* srcPos); -void EffectSsKiraKira_SpawnSmallYellow(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel); -void EffectSsKiraKira_SpawnSmall(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, - Color_RGBA8* primColor, Color_RGBA8* envColor); -void EffectSsGSpk_SpawnSmall(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel, - Color_RGBA8* primColor, Color_RGBA8* envColor); -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 EffectSsKirakira_SpawnSmallYellow(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel); +void EffectSsKirakira_SpawnSmall(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor); +void EffectSsGSpk_SpawnSmall(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor); +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); +void EffectSsGSpk_SpawnFuse(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel); // void EffectSsGSpk_SpawnRandColor(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); // void EffectSsGSpk_SpawnSmall(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 EffectSsDFire_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, - s16 alpha, s16 fadeDelay, s16 life, s32 arg9); -void EffectSsBubble_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 yPosOffset, f32 yPosRandScale, f32 xzPosRandScale, - f32 scale); +void EffectSsDFire_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 alpha, s16 fadeDelay, s16 life, s32 arg9); +void EffectSsBubble_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 yPosOffset, f32 yPosRandScale, f32 xzPosRandScale, f32 scale); void EffectSsGRipple_Spawn(GlobalContext* globalCtx, Vec3f* pos, s16 radius, s16 radiusMax, s16 life); -void EffectSsGSplash_Spawn(GlobalContext* globalCtx, Vec3f* pos, Color_RGBA8* primColor, Color_RGBA8* envColor, - s16 type, s16 scale); +void EffectSsGSplash_Spawn(GlobalContext* globalCtx, Vec3f* pos, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 type, s16 scale); // void EffectSsGFire_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2); // void EffectSsLightning_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Color_RGBA8* pzParm3, Color_RGBA8* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8); // void EffectSsDtBubble_SpawnColorProfile(UNK_TYPE4 param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8); -void EffectSsDtBubble_SpawnCustomColor(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, - Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 life, s16 randXZ); -void EffectSsHahen_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, s16 scale, - s16 objId, s16 life, Gfx* dList); -void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstScale, s16 unused, s16 scale, - s16 randScaleRange, s16 count, s16 objId, s16 life, Gfx* dList); +void EffectSsDtBubble_SpawnCustomColor(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s16 life, s16 randXZ); +void EffectSsHahen_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, s16 scale, s16 objId, s16 life, Gfx* dList); +void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstScale, s16 unused, s16 scale, s16 randScaleRange, s16 count, s16 objId, s16 life, Gfx* dList); // void func_800B2364(void); // void EffectSsStick_Spawn(UNK_TYPE4 uParm1, UNK_PTR puParm2, UNK_TYPE2 uParm3); // void EffectSsSibuki_Spawn(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 EffectSsSibuki_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos); -// void EffectSsStone1_Spawn(UNK_TYPE4 uParm1, UNK_PTR puParm2, UNK_TYPE4 uParm3); +void EffectSsStone1_Spawn(GlobalContext* globalCtx, Vec3f* pos, s32 reg0); // void EffectSsHitMark_Spawn(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, UNK_TYPE2 uParm3, Vec3f* pzParm4); void EffectSsHitMark_SpawnFixedScale(GlobalContext* globalCtx, s32 type, Vec3f* pos); -// void EffectSsHitMark_SpawnCustomScale(void); +void EffectSsHitMark_SpawnCustomScale(GlobalContext* globalCtx, s32 type, s16 scale, Vec3f* pos); // void EffectSsFhgFlash_SpawnShock(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, UNK_TYPE2 uParm4, UNK_TYPE1 param_5); -void EffectSsKFire_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scaleMax, u8 type); -void EffectSsSolderSrchBall_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, - s16* linkDetected, s16 drawFlag); -void EffectSsKakera_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* arg3, s16 gravity, s16 arg5, - s16 arg6, s16 arg7, s16 arg8, s16 scale, s16 arg10, s16 arg11, s32 life, s16 colorIdx, - s16 objId, Gfx* dList); +void EffectSsKFire_Spawn(GlobalContext* globalCtx, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, s32 param_5, s32 param_6); +void EffectSsSolderSrchBall_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 unused, s16* linkDetected, s16 drawFlag); +void EffectSsKakera_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* arg3, s16 gravity, s16 arg5, s16 arg6, s16 arg7, s16 arg8, s16 scale, s16 arg10, s16 arg11, s32 life, s16 colorIdx, s16 objId, Gfx* dList); // void EffectSsIcePiece_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, UNK_TYPE4 uParm3, Vec3f* pzParm4, Vec3f* param_5, UNK_TYPE4 param_6); // void EffectSsIcePiece_SpawnBurst(void); // void EffectSsEnIce_SpawnFlyingVec3f(UNK_TYPE4 uParm1, Actor* pzParm2, Vec3f* pzParm3, Color_RGBA8* pzParm4, Color_RGBA8* param_5, UNK_TYPE4 param_6); // void func_800B2B44(void); // void func_800B2B7C(void); -void EffectSsEnIce_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 scale, Vec3f* velocity, Vec3f* accel, - Color_RGBA8* primColor, Color_RGBA8* envColor, s32 life); +void EffectSsEnIce_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 scale, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s32 life); // void EffectSsFireTail_Spawn(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, UNK_TYPE4 uParm4, Vec3f* param_5, UNK_TYPE2 param_6, Color_RGBA8* param_7, Color_RGBA8* param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10, UNK_TYPE4 param_11); // void EffectSsFireTail_SpawnFlame(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 EffectSsFireTail_SpawnFlameOnPlayer(void); void EffectSsEnFire_SpawnVec3f(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, s16 scale, s16 arg4, s16 flags, s16 bodyPart); // void EffectSsEnFire_SpawnVec3s(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 EffectSsExtra_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); -void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env, - s16 scale, s16 scaleStep, s32 unk); -void func_800B3030(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, - s32 colorIndex); -// void EffectSsDeadDd_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE1* param_5, UNK_TYPE1* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE4 param_10); +void EffectSsExtra_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scoreIdx); +void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env, s16 scale, s16 scaleStep, s32 unk); +void func_800B3030(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s32 colorIndex); +void EffectSsDeadDd_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* prim, Color_RGBA8* env, s16 scale, s16 scaleStep, s16 alphaStep, s32 life); // 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 func_800B31BC(GlobalContext* globalCtx, Vec3f* pos, s16 scale, s16 scaleStep, s16 alpha, s32 life); 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); void Overlay_FreeGameState(GameStateOverlay* gameState); -void Actor_PrintLists(ActorContext* actorCtx); -void ActorShape_Init(ActorShape* actorShape, f32 yOffset, ActorShadowFunc func, f32 scale); -void ActorShadow_Draw(Actor* actor, Lights* mapper, GlobalContext* globalCtx, Gfx* displayList, Color_RGBA8* color); -void func_800B3FC0(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -void func_800B4024(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -void func_800B4088(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -void func_800B40B8(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -void func_800B40E0(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, f32 arg4, f32 arg5, f32 arg6); -void func_800B42F8(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -// void func_800B4A98(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_800B4AEC(GlobalContext* globalCtx, Actor* actor, f32 param_3); + +void ActorShape_Init(ActorShape* actorShape, f32 yOffset, ActorShadowFunc shadowDraw, f32 shadowScale); +void ActorShadow_DrawCircle(Actor* actor, Lights* lights, GlobalContext* globalCtx); +void ActorShadow_DrawSquare(Actor* actor, Lights* lights, GlobalContext* globalCtx); +void ActorShadow_DrawWhiteCircle(Actor* actor, Lights* lights, GlobalContext* globalCtx); +void ActorShadow_DrawHorse(Actor* actor, Lights* lights, GlobalContext* globalCtx); + +void ActorShadow_DrawFeet(Actor* actor, Lights* mapper, GlobalContext* globalCtx); +void Actor_SetFeetPos(Actor* actor, s32 limbIndex, s32 leftFootIndex, Vec3f* leftFootPos, s32 rightFootIndex, Vec3f* rightFootPos); +void func_800B4AEC(GlobalContext* globalCtx, Actor* actor, f32 y); void func_800B4B50(Actor* actor, Lights* mapper, GlobalContext* globalCtx); -void func_800B4EDC(GlobalContext* globalCtx, Vec3f* pzParm2, Vec3f* pzParm3, f32* pfParm4); -// void func_800B4F40(TargetContext* targetCtx, s32 param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4, UNK_TYPE4 param_5); -void func_800B4F78(TargetContext* targetCtx, u8 type, GlobalContext* globalCtx); -void func_800B5040(TargetContext* targetCtx, Actor* actor, u8 type, GlobalContext* globalCtx); -void Actor_TargetContextInit(TargetContext* targetCtx, Actor* actor, GlobalContext* globalCtx); -void func_800B5208(TargetContext* targetCtx, GlobalContext* globalCtx); -void func_800B5814(TargetContext* targetCtx, Player* player, Actor* actor, GlobalContext* globalCtx); -u32 Flags_GetSwitch(GlobalContext* globalCtx, s32 flag); -void Actor_SetSwitchFlag(GlobalContext* globalCtx, s32 flag); -void Actor_UnsetSwitchFlag(GlobalContext* globalCtx, s32 flag); -u32 Actor_GetChestFlag(GlobalContext* globalCtx, u32 flag); -void Actor_SetChestFlag(GlobalContext* globalCtx, u32 flag); -void Actor_SetAllChestFlag(GlobalContext* globalCtx, u32 flags); -u32 Actor_GetAllChestFlag(GlobalContext* globalCtx); -u32 Actor_GetRoomCleared(GlobalContext* globalCtx, u32 roomNumber); -void Actor_SetRoomCleared(GlobalContext* globalCtx, u32 roomNumber); -void Actor_UnsetRoomCleared(GlobalContext* globalCtx, u32 roomNumber); -u32 Actor_GetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber); -void Actor_SetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber); -void Actor_UnsetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber); -u32 Actor_GetCollectibleFlag(GlobalContext* globalCtx, s32 index); -void Actor_SetCollectibleFlag(GlobalContext* globalCtx, s32 index); -void Actor_TitleCardContextInit(GlobalContext* globalCtx, TitleCardContext* titleCardCtx); -void Actor_TitleCardCreate(GlobalContext* globalCtx, TitleCardContext* titleCardCtx, u32 texture, s16 param_4, s16 param_5, u8 param_6, u8 param_7); -// void Actor_Nop800B5E50(UNK_TYPE4 param_1, UNK_TYPE4 param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4); -void Actor_TitleCardUpdate(GlobalContext* globalCtx, TitleCardContext* titleCardCtx); -void Actor_TitleCardDraw(GlobalContext* globalCtx, TitleCardContext* titleCardCtx); -// UNK_TYPE4 func_800B6434(GlobalContext* globalCtx, TitleCardContext* titleCardCtx); -// UNK_TYPE4 func_800B645C(void); -void func_800B6468(GlobalContext* globalCtx); -void func_800B6474(GlobalContext* globalCtx); -// UNK_TYPE4 func_800B648C(GlobalContext* globalCtx, UNK_TYPE1 param_2, UNK_TYPE1 param_3, f32 param_4, Vec3f* param_5); -f32 func_800B64FC(GlobalContext* globalCtx, f32 fParm2, Vec3f* pzParm3, s32* puParm4); -void* func_800B6584(GlobalContext* globalCtx, s16 sParm2, void* pvParm3, u32 uParm4); -// UNK_TYPE4 func_800B6608(s32 iParm1, s16 sParm2); -// void func_800B6680(void); +void Actor_GetProjectedPos(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, f32* arg3); + +void Actor_DrawZTarget(TargetContext* targetCtx, GlobalContext* globalCtx); + +s32 Flags_GetSwitch(GlobalContext* globalCtx, s32 flag); +void Flags_SetSwitch(GlobalContext* globalCtx, s32 flag); +void Flags_UnsetSwitch(GlobalContext* globalCtx, s32 flag); +s32 Flags_GetTreasure(GlobalContext* globalCtx, s32 flag); +void Flags_SetTreasure(GlobalContext* globalCtx, s32 flag); +void Flags_SetAllTreasure(GlobalContext* globalCtx, s32 flag); +s32 Flags_GetAllTreasure(GlobalContext* globalCtx); +s32 Flags_GetClear(GlobalContext* globalCtx, s32 roomNumber); +void Flags_SetClear(GlobalContext* globalCtx, s32 roomNumber); +void Flags_UnsetClear(GlobalContext* globalCtx, s32 roomNumber); +s32 Flags_GetClearTemp(GlobalContext* globalCtx, s32 roomNumber); +void Flags_SetClearTemp(GlobalContext* globalCtx, s32 roomNumber); +void Flags_UnsetClearTemp(GlobalContext* globalCtx, s32 roomNumber); +s32 Flags_GetCollectible(GlobalContext* globalCtx, s32 flag); +void Flags_SetCollectible(GlobalContext* globalCtx, s32 flag); + +void TitleCard_InitBossName(GameState* gameState, TitleCardContext* titleCtx, TexturePtr texture, s16 x, s16 y, u8 width, u8 height); + +s32 func_800B648C(GlobalContext* globalCtx, s32 arg1, s32 arg2, f32 arg3, Vec3f* arg4); +f32 func_800B64FC(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2, s32* arg3); +void* func_800B6584(GlobalContext* globalCtx, s16 id, void* arg2, size_t size); +void* func_800B6608(GlobalContext* globalCtx, s16 id); +void* func_800B6680(GlobalContext* globalCtx, s16 id); void Actor_MarkForDeath(Actor* actor); -void Actor_InitCurrPosition(Actor* actor); -void Actor_SetHeight(Actor* actor, f32 height); -void Actor_SetRotationFromDrawRotation(Actor* actor); -void Actor_InitDrawRotation(Actor* actor); +void Actor_SetWorldToHome(Actor* actor); +void Actor_SetFocus(Actor* actor, f32 height); +void Actor_SetWorldRotToShape(Actor* actor); +void Actor_SetShapeRotToWorld(Actor* actor); void Actor_SetScale(Actor* actor, f32 scale); -void Actor_SetObjectSegment(GlobalContext* globalCtx, Actor* actor); -void Actor_InitToDefaultValues(Actor* actor, GlobalContext* globalCtx); -void Actor_FiniActor(Actor* actor, GlobalContext* globalCtx); +void Actor_SetObjectDependency(GlobalContext* globalCtx, Actor* actor); void Actor_SetMovementScale(s32 scale); -void Actor_ApplyMovement(Actor* actor); -void Actor_SetVelocityYRotationAndGravity(Actor* actor); -void Actor_SetVelocityAndMoveYRotationAndGravity(Actor* actor); -void Actor_SetVelocityXYRotation(Actor* actor); -void Actor_SetVelocityAndMoveXYRotation(Actor* actor); -void Actor_SetVelocityXYRotationReverse(Actor* actor); -void Actor_SetVelocityAndMoveXYRotationReverse(Actor* actor); -void func_800B6C04(Actor* actor, f32 fParm2); -// void func_800B6C58(Actor* actor, UNK_TYPE4 param_2); +void Actor_UpdatePos(Actor* actor); +void Actor_UpdateVelocityWithGravity(Actor* actor); +void Actor_MoveWithGravity(Actor* actor); +void Actor_UpdateVelocityWithoutGravity(Actor* actor); +void Actor_MoveWithoutGravity(Actor* actor); +void Actor_UpdateVelocityWithoutGravityReverse(Actor* actor); +void Actor_MoveWithoutGravityReverse(Actor* actor); +void Actor_SetSpeeds(Actor* actor, f32 speed); s16 Actor_YawBetweenActors(Actor* from, Actor* to); s16 Actor_YawBetweenActorsTop(Actor* from, Actor* to); s16 Actor_YawToPoint(Actor* actor, Vec3f* point); @@ -758,384 +667,315 @@ f32 Actor_DistanceBetweenActors(Actor* actor1, Actor* actor2); f32 Actor_DistanceToPoint(Actor* actor, Vec3f* point); f32 Actor_XZDistanceBetweenActors(Actor* actor1, Actor* actor2); f32 Actor_XZDistanceToPoint(Actor* actor, Vec3f* point); -void Actor_CalcOffsetOrientedToDrawRotation(Actor* actor, Vec3f* offset, Vec3f* point); -f32 Actor_YDistance(Actor* actor1, Actor* actor2); -void func_800B6F20(GlobalContext* globalCtx, s32 param_2, f32 param_3, s16 param_4); -float func_800B6FC8(Player* player); -// void func_800B7090(void); -// void func_800B7118(void); -// void func_800B7128(void); +void Actor_OffsetOfPointInActorCoords(Actor* actor, Vec3f* offset, Vec3f* point); +f32 Actor_HeightDiff(Actor* actor1, Actor* actor2); +void func_800B6F20(GlobalContext* globalCtx, Input* input, f32 arg2, s16 arg3); +f32 Player_GetHeight(Player* player); +f32 Player_GetRunSpeedLimit(Player* player); +s32 func_800B7118(Player* player); +s32 func_800B7128(Player* player); s32 func_800B715C(GlobalContext* globalCtx); -// void func_800B7170(void); -// void func_800B71DC(void); -u32 func_800B7200(s32 param_1); -// void func_800B722C(void); -void func_800B724C(GlobalContext* globalCtx, Actor* actor, u8 arg2); -u32 func_800B7298(GlobalContext* globalCtx, Actor* actor, u8 arg2); -void func_800B72E0(s32 param_1); -void func_800B72F8(DynaPolyActor* dpactor, f32 a1, s16 a2); -s32 Actor_IsLinkFacingActor(Actor* actor, s16 tolerance, GlobalContext* globalCtx); -s32 Actor_IsActorFacedByActor(Actor* actor, Actor* other, s16 tolerance); -s32 Actor_IsActorFacingLink(Actor* actor, s16 angle); -s32 Actor_IsActorFacingActor(Actor* actor, Actor* other, s16 tolerance); -s32 Actor_IsActorFacingLinkAndWithinRange(Actor* actor, f32 range, s16 tolerance); -s32 Actor_IsActorFacingActorAndWithinRange(Actor* actor, Actor* other, f32 range, s16 tolerance); -void func_800B75A0(CollisionPoly* param_1, Vec3f* param_2, s16* param_3); -// UNK_TYPE4 func_800B761C(Actor* param_1, UNK_TYPE4 param_2, u32 param_3); -// UNK_TYPE4 func_800B7678(GlobalContext* globalCtx, Actor* param_2, s32 param_3, u32 param_4); +void Actor_SetCameraHorseSetting(GlobalContext* globalCtx, Player* player); +void Actor_MountHorse(GlobalContext* globalCtx, Player* player, Actor* horse); +s32 func_800B724C(GlobalContext* globalCtx, Actor* actor, u8 csMode); +u32 func_800B7298(GlobalContext* globalCtx, Actor* actor, u8 csMode); +void func_800B72F8(DynaPolyActor* dyna, f32 extraPushForce, s16 yRotation); + +s32 Player_IsFacingActor(Actor* actor, s16 maxAngleDiff, GlobalContext* globalCtx); +s32 Actor_ActorBIsFacingActorA(Actor* actorA, Actor* actorB, s16 maxAngleDiff); +s32 Actor_IsFacingPlayer(Actor* actor, s16 angle); +s32 Actor_ActorAIsFacingActorB(Actor* actorA, Actor* actorB, s16 maxAngleDiff); +s32 Actor_IsFacingAndNearPlayer(Actor* actor, f32 range, s16 maxAngleDiff); +s32 Actor_ActorAIsFacingAndNearActorB(Actor* actorA, Actor* actorB, f32 range, s16 maxAngleDiff); + +void func_800B75A0(CollisionPoly* poly, Vec3f* normal, s16* azimuth); void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 wallCheckHeight, f32 wallCheckRadius, f32 ceilingCheckHeight, u32 flags); -// void func_800B7E04(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -Hilite* func_800B7FE0(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx); -// void func_800B8018(void); -void func_800B8050(Actor* actor, GlobalContext* globalCtx, s32 iParm3); -void func_800B8118(Actor* actor, GlobalContext* globalCtx, s32 iParm3); -// void func_800B81E0(void); -UNK_PTR func_800B8214(PosRot* param_1, Actor* param_2); -f32* func_800B8248(PosRot* param_1, Player* param_2); -// void func_800B82EC(void); -// void func_800B83BC(void); -// void func_800B83F8(void); -s32 func_800B84D0(Actor* actor, GlobalContext* globalCtx); // Actor_IsTalking -s32 func_800B8500(Actor* actor, GlobalContext* globalCtx, f32 fParm3, f32 fParm4, s32 param_5); -s32 func_800B85E0(Actor* actor, GlobalContext* globalCtx, f32 uParm3, s32 uParm4); -s32 func_800B8614(Actor* actor, GlobalContext* globalCtx, f32 uParm3); +Hilite* Hilite_DrawOpa(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx); +void func_800B8050(Actor* actor, GlobalContext* globalCtx, s32 flag); +void func_800B8118(Actor* actor, GlobalContext* globalCtx, s32 flag); +PosRot* Actor_GetFocus(PosRot* dest, Actor* actor); +PosRot* Actor_GetWorld(PosRot* dest, Actor* actor); +PosRot* Actor_GetWorldPosShapeRot(PosRot* dest, Actor* actor); + +s32 func_800B83F8(Actor* actor, Player* player, s32 flag); +s32 Actor_ProcessTalkRequest(Actor* actor, GameState* gameState); +s32 func_800B8500(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exchangeItemId); +s32 func_800B85E0(Actor* actor, GlobalContext* globalCtx, f32 radius, s32 exchangeItemId); +s32 func_800B8614(Actor* actor, GlobalContext* globalCtx, f32 radius); s32 func_800B863C(Actor* actor, GlobalContext* globalCtx); -u32 func_800B867C(Actor* actor, GlobalContext* globalCtx); -UNK_TYPE4 func_800B86C8(Actor* actor1, GlobalContext* globalCtx, Actor* actor2); -s32 func_800B8708(GlobalContext* globalCtx); -s32 func_800B8718(Actor* actor, GlobalContext* globalCtx); -void func_800B874C(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3); -// void func_800B8804(void); -// void func_800B882C(void); -// void func_800B886C(void); -void func_800B8898(GlobalContext* globalCtx, Actor* actor, s16* arg2, s16* arg3); +s32 Actor_TextboxIsClosing(Actor* actor, GlobalContext* globalCtx); +s32 Actor_ChangeFocus(Actor* actor1, GlobalContext* globalCtx, Actor* actor2); +s32 Player_GetExchangeItemId(GlobalContext* globalCtx); +s32 func_800B8718(Actor* actor, GameState* gameState); +s32 func_800B874C(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange); +s32 func_800B8804(Actor* actor, GlobalContext* globalCtx, f32 xzRange); +s32 func_800B886C(Actor* actor, GlobalContext* globalCtx); +void Actor_GetScreenPos(GlobalContext* globalCtx, Actor* actor, s16* x, s16* y); s32 func_800B8934(GlobalContext* globalCtx, Actor* actor); -u32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx); -UNK_TYPE4 func_800B8A1C(Actor* actor, GlobalContext* globalCtx, s32 iParm3, f32 fParm4, f32 param_5); -// void func_800B8B84(void); -void func_800B8BB0(Actor* actor, GlobalContext* globalCtx); -// void func_800B8BD0(void); +s32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx); +s32 Actor_PickUp(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRange, f32 yRange); +s32 Actor_PickUpNearby(Actor* actor, GlobalContext* globalCtx, s32 getItemId); +s32 Actor_LiftActor(Actor* actor, GlobalContext* globalCtx); +s32 Actor_PickUpFar(Actor* actor, GlobalContext* globalCtx, s32 getItemId); s32 Actor_HasNoParent(Actor* actor, GlobalContext* globalCtx); -// void func_800B8C20(void); +void func_800B8C20(Actor* actorA, Actor* actorB, GlobalContext* globalCtx); void func_800B8C50(Actor* actor, GlobalContext* globalCtx); -// void func_800B8C78(void); -// void func_800B8C9C(void); -// void func_800B8CEC(void); -// void func_800B8D10(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); +s32 Actor_HasRider(GlobalContext* globalCtx, Actor* horse); +s32 Actor_SetRideActor(GlobalContext* globalCtx, Actor* horse, s32 mountSide); +s32 Actor_HasNoRider(GlobalContext* globalCtx, Actor* horse); +void func_800B8D10(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4, u32 arg5, u32 arg6); void func_800B8D50(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 yaw, f32 arg4, u32 arg5); void func_800B8D98(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4); -// void func_800B8DD4(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_800B8E1C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -void func_800B8E58(Actor* actor, u16 sfxId); -void Audio_PlayActorSound2(Actor* actor, u16 sfxId); -// void func_800B8FC0(void); +void func_800B8DD4(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4, u32 arg5); +void func_800B8E1C(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4); +void func_800B8E58(Player* player, u16 sfxId); +void Actor_PlaySfxAtPos(Actor* actor, u16 sfxId); +void func_800B8EF4(GlobalContext* globalCtx, Actor* actor); void func_800B8F98(Actor* actor, u16 sfxId); +void func_800B8FC0(Actor* actor, u16 sfxId); void func_800B8FE8(Actor* actor, u16 sfxId); void func_800B9010(Actor* actor, u16 sfxId); -// void func_800B9038(void); -// void func_800B9084(void); +void func_800B9038(Actor* actor, s32 timer); +void func_800B9084(Actor* actor); void func_800B9098(Actor* actor); -s32 func_800B90AC(GlobalContext* globalCtx, Actor* actor, UNK_TYPE arg2, UNK_TYPE arg3, UNK_TYPE arg4); -// void func_800B90F4(void); +s32 func_800B90AC(GlobalContext* globalCtx, Actor* actor, CollisionPoly* polygon, s32 index, s32 arg4); +void func_800B90F4(GlobalContext* globalCtx); void func_800B9120(ActorContext* actorCtx); -// void Actor_Init(GlobalContext* globalCtx, ActorContext* actorCtx, UNK_TYPE4 uParm3); -void func_800B9334(GlobalContext* globalCtx, ActorContext* actorCtx); -Actor* Actor_UpdateActor(s800B948C* params); +void Actor_InitContext(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEntry* actorEntry); void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx); -void Actor_DrawActor(GlobalContext* globalCtx, Actor* actor); -void func_800B9D1C(Actor* actor); -void Actor_DrawAllSetup(GlobalContext* globalCtx); s32 Actor_RecordUndrawnActor(GlobalContext* globalCtx, Actor* actor); -// void func_800B9E84(void); -void func_800B9EF4(GlobalContext* globalCtx, s32 numActors, Actor** actors); -s32 func_800BA2D8(GlobalContext* globalCtx, Actor* actor); -s32 func_800BA2FC(GlobalContext* globalCtx, Actor* actor, Vec3f* param_3, f32 param_4); void Actor_DrawAll(GlobalContext* globalCtx, ActorContext* actorCtx); void func_800BA6FC(GlobalContext* globalCtx, ActorContext* actorCtx); void func_800BA798(GlobalContext* globalCtx, ActorContext* actorCtx); -void func_800BA8B8(GlobalContext* globalCtx, ActorContext* actorCtx); -// void func_800BA9B4(void); -void Actor_InsertIntoTypeList(ActorContext* actorCtx, Actor* actor, u8 type); -Actor* Actor_RemoveFromTypeList(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor); -void Actor_FreeOverlay(ActorOverlay* entry); -Actor* Actor_Spawn(ActorContext* actorCtx, GlobalContext* globalCtx, s16 index, f32 x, f32 y, f32 z, s16 rotX, s16 rotY, s16 rotZ, s16 sParm10); -ActorInit* Actor_LoadOverlay(ActorContext* actorCtx, s16 index); -Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, GlobalContext* globalCtx, s16 index, f32 x, f32 y, f32 z, s16 rotX, s16 rotY, s16 rotZ, s32 variable, u32 cutscene, s32 param_12, Actor* parent); -Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, GlobalContext* globalCtx, s16 index, f32 x, f32 y, f32 z, s16 rotX, s16 rotY, s16 rotZ, s32 variable); +void Actor_CleanupContext(ActorContext* actorCtx, GlobalContext* globalCtx); +Actor* Actor_Spawn(ActorContext* actorCtx, GlobalContext* globalCtx, s16 actorId, f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s32 params); +Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, GlobalContext* globalCtx, s16 index, f32 x, f32 y, f32 z, s16 rotX, s16 rotY, s16 rotZ, s32 params, u32 cutscene, s32 arg11, Actor* parent); +Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, GlobalContext* globalCtx, s16 actorId, f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s32 params); void Actor_SpawnTransitionActors(GlobalContext* globalCtx, ActorContext* actorCtx); -void func_800BB2D0(ActorContext* actorCtx, u16* param_2, GlobalContext* globalCtx); -Actor* func_800BB498(ActorContext* actorCtx, Actor* actor, GlobalContext* globalCtx); -// void func_800BB59C(void); -// void func_800BB604(void); -// void func_800BB8EC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); void Enemy_StartFinishingBlow(GlobalContext* globalCtx, Actor* actor); -// void func_800BBAC0(void); -void func_800BBB74(s16* arg1, UNK_TYPE1 arg2, UNK_TYPE1 arg3, UNK_TYPE4 arg4); -// void func_800BBC20(void); -void func_800BBCEC(Actor* actor, GlobalContext* globalCtx, s16 arg2, Gfx** dList); -void func_800BBDAC(GlobalContext* globalCtx, Actor* actor, Vec3f* arg2, f32 arg3, UNK_TYPE4 arg4, f32 arg5, s16 arg6, s16 arg7, u8 arg8); -void func_800BBFB0(GlobalContext* globalCtx, Vec3f* position, f32 param3, s32 param_4, s16 param_5, s16 param_6, u8 param_7); +s16 func_800BBAC0(s16 arg0[2], s16 arg1, s16 arg2, s16 arg3); +s16 func_800BBB74(s16 arg0[2], s16 arg1, s16 arg2, s16 arg3); +void Actor_SpawnBodyParts(Actor* actor, GlobalContext* globalCtx, s32 arg2, Gfx** dList); +void Actor_SpawnFloorDustRing(GlobalContext* globalCtx, Actor* actor, Vec3f* posXZ, f32 radius, s32 countMinusOne, f32 randAccelWeight, s16 scale, s16 scaleStep, u8 useLighting); +void func_800BBFB0(GlobalContext* globalCtx, Vec3f* position, f32 arg2, s32 arg3, s16 arg4, s16 scaleStep, u8 arg6); void func_800BC154(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor, u8 actorCategory); -// void func_800BC188(void); -// void func_800BC1B4(void); -Actor* func_800BC270(GlobalContext* globalCtx, Actor* actor, f32 arg2, UNK_TYPE4 arg3); +s32 func_800BC188(s32 index); +Actor* func_800BC270(GlobalContext* globalCtx, Actor* actor, f32 arg2, s32 arg3); Actor* func_800BC444(GlobalContext* globalCtx, Actor* actor, f32 arg2); -// void func_800BC4EC(void); -// void func_800BC5B8(void); -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_800BC8B8(void); -// void func_800BCB50(void); -void func_800BCB70(Actor* actor, u16 arg1, u16 arg2, s16 arg3, s16 arg4); -void func_800BCBF4(Vec3f* uParm1, GlobalContext* globalCtx); -void func_800BCC68(Vec3f* param_1, GlobalContext* globalCtx); -UNK_RET func_800BCCDC(Vec3s* points, u8 pathcount, Vec3f* pos1, Vec3f* pos2, UNK_TYPE parm5); -// void func_800BD2B4(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_800BD384(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, UNK_TYPE2 param_8, UNK_TYPE1 param_9); -// void func_800BD6E4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); -void func_800BD888(Actor*, struct_800BD888_arg1*, s16, s16); // This function is very similar to OoT's func_80034A14 -// void func_800BD9A0(void); -// void func_800BD9E0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE2 param_6); -// void func_800BDAA0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE2 param_6); -// void func_800BDB6C(void); -void func_800BDC5C(SkelAnime* skelAnime, ActorAnimationEntry animation[], s32 index); -// void func_800BDCF4(void); +s16 Actor_TestFloorInDirection(Actor* actor, GlobalContext* globalCtx, f32 distance, s16 angle); +s32 Actor_IsTargeted(GlobalContext* globalCtx, Actor* actor); +s32 Actor_OtherIsTargeted(GlobalContext* globalCtx, Actor* actor); +void func_800BC620(Vec3f* arg0, Vec3f* arg1, u8 alpha, GlobalContext* globalCtx); +void func_800BC770(GlobalContext* globalCtx, s16 y, s16 countdown); +void func_800BC7D8(GlobalContext* globalCtx, s16 y, s16 countdown, s16 speed); +void func_800BC848(Actor* actor, GlobalContext* globalCtx, s16 y, s16 countdown); +void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type); +void Actor_SetColorFilter(Actor* actor, u16 colorFlag, u16 colorIntensityMax, u16 xluFlag, u16 duration); +Hilite* func_800BCBF4(Vec3f* arg0, GlobalContext* globalCtx); +Hilite* func_800BCC68(Vec3f* arg0, GlobalContext* globalCtx); +void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3f* dstPos, s32 isPathLoop); +s32 func_800BD2B4(GlobalContext* globalCtx, Actor* actor, s16* arg2, f32 arg3, u16 (*textIdCallback)(GlobalContext*, Actor*), s16 (*arg5)(GlobalContext*, Actor*)); +void func_800BD888(Actor* actor, struct_800BD888_arg1* arg1, s16 arg2, s16 arg3); +void func_800BD9E0(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s16 alpha); +void func_800BDAA0(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, s16 alpha); +void Actor_ChangeAnimationByInfo(SkelAnime* skelAnime, AnimationInfo* animation, s32 index); void Actor_Noop(Actor* actor, GlobalContext* globalCtx); -void func_800BDFC0(GlobalContext* globalCtx, Gfx* dl); -void func_800BE03C(GlobalContext* globalCtx, Gfx* dl); -Actor* func_800BE0B8(GlobalContext* globalCtx, Actor* inActor, s16 arg2, u8 arg3, f32 arg4); -// void func_800BE184(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); -u8 Actor_ApplyDamage(Actor* actor); // returns current health -void func_800BE258(Actor* actor, UNK_PTR arg1); -void func_800BE2B8(Actor* actor, ColliderJntSph* jntSphere); + +void Gfx_DrawDListOpa(GlobalContext* globalCtx, Gfx* dlist); +void Gfx_DrawDListXlu(GlobalContext* globalCtx, Gfx* dlist); + +Actor* Actor_FindNearby(GlobalContext* globalCtx, Actor* inActor, s16 actorId, u8 actorCategory, f32 distance); +s32 func_800BE184(GlobalContext* globalCtx, Actor* actor, f32 xzDist, s16 arg3, s16 arg4, s16 arg5); +u8 Actor_ApplyDamage(Actor* actor); +void Actor_SetDropFlag(Actor* actor, ColliderInfo* colInfo); +void Actor_SetDropFlagJntSph(Actor* actor, ColliderJntSph* jntSphere); void func_800BE33C(Vec3f* arg0, Vec3f* arg1, Vec3s* arg2, s32 arg3); -// void func_800BE3D0(void); +void func_800BE3D0(Actor* actor, s16 angle, Vec3s* arg2); void func_800BE504(Actor* actor, ColliderCylinder* collider); -// void func_800BE568(void); -void func_800BE5CC(Actor* actor, ColliderJntSph* collider, s32 arg2); -// void func_800BE63C(void); -void func_800BE680(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s16 arg3, f32 arg4, f32 arg5, f32 arg6, u8 mode); -void func_800BF7CC(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s32 arg3, s32 arg4, f32 arg5, f32 arg6); -void ActorOverlayTable_FaultPrint(void* arg0, void* arg1); // ActorOverlayTable_FaultPrint -void* ActorOverlayTable_FaultAddrConv(void* arg0, void* arg1); // ActorOverlayTable_FaultAddrConv -void ActorOverlayTable_Init(void); // ActorOverlayTable_Init -void ActorOverlayTable_Cleanup(void); // ActorOverlayTable_Cleanup -void BgCheck_PolygonLinkedListNodeInit(SSNode* node, s16* polyIndex, u16 next); -void BgCheck_PolygonLinkedListResetHead(u16* head); -void BgCheck_ScenePolygonListsNodeInsert(SSNodeList* list, u16* head, s16* polyIndex); -void BgCheck_PolygonLinkedListNodeInsert(DynaSSNodeList* list, u16* head, s16* polyIndex); -void BgCheck_PolygonLinkedListInit(GlobalContext* globalCtx, DynaSSNodeList* list); -void BgCheck_PolygonLinkedListAlloc(GlobalContext* globalCtx, DynaSSNodeList* list, u32 numNodes); -void BgCheck_PolygonLinkedListReset(DynaSSNodeList* list); -u16 BgCheck_AllocPolygonLinkedListNode(DynaSSNodeList* list); -void BgCheck_CreateVec3fFromVertex(Vec3s* vertex, Vec3f* vector); -void BgCheck_CreateVertexFromVec3f(Vec3s* vertex, Vec3f* vector); -float func_800BFD84(CollisionPoly* polygon, f32 param_2, f32 param_3); -s32 func_800BFDEC(CollisionPoly* param_1, CollisionPoly* param_2, u32* param_3, u32* param_4); -s32 BgCheck_PolygonGetMinY(CollisionPoly* polygons, Vec3s* vertices); -void BgCheck_PolygonGetNormal(CollisionPoly* polygon, f32* normalX, f32* normalY, f32* normalZ); -void func_800C0094(struct CollisionPoly* param_1, f32 xOffset, f32 yOffset, f32 zOffset, MtxF* matrix); -f32 func_800C01B8(CollisionPoly* param_1, Vec3f* param_2); -void BgCheck_CreateColTriParamsFromPolygon(CollisionPoly* polygon, Vec3s* vertices, TriNorm* tri); -void func_800C02C0(CollisionPoly* poly, s32 index, CollisionContext* colCtx, TriNorm* tri); -// void func_800C0340(CollisionPoly* param_1, Vec3s* param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -// UNK_TYPE4 func_800C0474(CollisionPoly* param_1, Vec3s* param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); -// void func_800C0668(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C06A8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C074C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C07F0(void); -void BgCheck_PolygonCollidesWithSphere(CollisionPoly* polygon, Vec3s* verticies, Vec3f* pos, f32 readius); -void BgCheck_ScenePolygonListsInsertSorted(CollisionContext* colCtx, u16* head, CollisionPoly* polygons, Vec3s* vertices, s16 index); -void BgCheck_ScenePolygonListsInsert(StaticLookup* subdivision, CollisionContext* colCtx, CollisionPoly* polygons, Vec3s* vertices, s16 index); -// void func_800C0E74(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_800C10FC(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); -// void func_800C1238(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE1 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11); -// void func_800C12A4(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); -// void func_800C1B68(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_800C1D7C(void); -// void func_800C2008(void); -// void func_800C20F4(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_800C2310(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 func_800C2460(void); -// void func_800C2514(void); -// void func_800C25E0(void); -void BgCheck_GetPolyMinSubdivisions(CollisionContext* colCtx, Vec3f* min, s32* xSubdivision, s32* ySubdivision, s32* zSubdivision); -void BgCheck_GetPolyMaxSubdivisions(CollisionContext* colCtx, Vec3f* max, s32* xSubdivision, s32* ySubdivision, s32* zSubdivision); -void BgCheck_GetPolyMinMaxSubdivisions(CollisionContext* colCtx, Vec3s* vertices, CollisionPoly* polygons, s32* minX, s32* minY, s32* minZ, s32* maxX, s32* maxY, s32* maxZ, s16 index); -// UNK_TYPE4 func_800C2BE0(Vec3f* param_1, Vec3f* param_2, CollisionPoly* polygons, Vec3s* vertices, s16 index); -u32 BgCheck_SplitScenePolygonsIntoSubdivisions(CollisionContext* colCtx, GlobalContext* globalCtx, StaticLookup* subdivisions); -s32 BgCheck_GetIsDefaultSpecialScene(GlobalContext* globalCtx); -s32 BgCheck_GetSpecialSceneMaxMemory(s32 sceneId, u32* maxMemory); -void BgCheck_CalcSubdivisionSize(f32 min, s32 subdivisions, f32* max, f32* subdivisionSize, f32* inverseSubdivisionSize); -s32 BgCheck_GetSpecialSceneMaxObjects(GlobalContext* globalCtx, u32* maxNodes, u32* maxPolygons, u32* maxVertices); -void BgCheck_Init(CollisionContext* colCtx, GlobalContext* globalCtx, CollisionHeader* mesh); -void func_800C3C00(CollisionContext* colCtx, u32 param_2); -void func_800C3C14(CollisionContext* colCtx, u32 param_2); -CollisionHeader* BgCheck_GetActorMeshHeader(CollisionContext* colCtx, s32 index); -// void func_800C3C94(void); -f32 func_800C3D50(s32 arg0, CollisionContext* colCtx, s32 arg2, CollisionPoly** arg3, s32* arg4, Vec3f* pos, Actor* actor, s32 arg7, f32 arg8, s32 arg9); -// void func_800C3F40(void); -// void func_800C3FA0(void); -f32 func_800C4000(GlobalContext* globalCtx, CollisionContext* colCtx, s32* arg2, Vec3f* arg3); -// void func_800C4058(void); -// void func_800C40B4(void); -f32 func_800C411C(CollisionContext* colCtx, CollisionPoly** arg1, s32* arg2, Actor* actor, Vec3f* pos); -// void func_800C4188(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_800C41E4(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_800C4240(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_800C42A8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C4314(void); -// void func_800C43CC(void); -// void func_800C4488(void); -// void func_800C44F0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C455C(void); -s32 func_800C45C4(CollisionContext* colCtx, u32 arg1, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4, f32 arg5, s32* arg6, s32* arg7, DynaPolyActor* arg8, f32 arg9, u8 arg10); -// void func_800C4C74(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_800C4CD8(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_800C4D3C(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); -// void func_800C4DA4(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); -// void func_800C4E10(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_800C4F38(void); -// void func_800C4F84(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_800C4FD4(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, UNK_TYPE4 param_11); -// void func_800C5464(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_800C54AC(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_800C5538(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); -s32 func_800C55C4(CollisionContext* colCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, u32 arg5, u32 arg6, u32 arg7, u32 arg8, u32* arg9); -// void func_800C5650(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, UNK_TYPE4 param_11); -// void func_800C56E0(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, UNK_TYPE4 param_11, UNK_TYPE4 param_12); -s32 func_800C576C(CollisionContext* colCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, u32 arg5, u32 arg6, u32 arg7, u32 arg8, u32* arg9); -// void func_800C57F8(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_800C583C(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); -// void func_800C58C8(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_800C5954(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); -s32 func_800C5A20(CollisionContext* colCtx, Vec3f* arg1, f32 arg2); -// void func_800C5A64(void); -void BgCheck_ScenePolygonListsInit(SSNodeList* arg0); -void BgCheck_ScenePolygonListsAlloc(GlobalContext* globalCtx, SSNodeList* lists, s32 numNodes, u32 numPolygons); -s32 func_800C5B80(u16* arg0); -u16 BgCheck_ScenePolygonListsReserveNode(SSNodeList* lists); -void BgCheck_ActorMeshParamsInit(ScaleRotPos* params); -void BgCheck_SetActorMeshParams(ScaleRotPos* params, Vec3f* scale, Vec3s* rotation, Vec3f* position); -s32 BgCheck_AreActorMeshParamsEqual(ScaleRotPos* arg0, ScaleRotPos* arg1); -void BgCheck_ActorMeshPolyListsHeadsInit(DynaLookup* lists); -void BgCheck_ActorMeshPolyListsInit(DynaLookup* lists); -void BgCheck_ActorMeshVerticesIndexInit(s16* index); -void BgCheck_ActorMeshWaterboxesIndexInit(s16* index); -void BgCheck_ActorMeshInit(GlobalContext* globalCtx, BgActor* mesh); -void BgCheck_ActorMeshInitFromActor(BgActor* actorMesh, DynaPolyActor* actor, CollisionHeader* header); -s32 BgCheck_HasActorMeshChanged(BgActor* mesh); -void BgCheck_PolygonsInit(CollisionPoly** polygons); -void BgCheck_PolygonsAlloc(GlobalContext* globalCtx, CollisionPoly* polygons, u32 numPolygons); -void BgCheck_VerticesInit(Vec3s** vertices); -void BgCheck_VerticesListAlloc(GlobalContext* globalCtx, Vec3s** vertices, u32 numVertices); -void BgCheck_WaterboxListInit(DynaSSWaterboxList* waterboxList); -void BgCheck_WaterboxListAlloc(GlobalContext* globalCtx, DynaSSWaterboxList* waterboxList, u32 numWaterboxes); -void BgCheck_ActorMeshUpdateParams(GlobalContext* globalCtx, BgActor* mesh); -s32 BgCheck_IsActorMeshIndexValid(s32 index); -void BgCheck_DynaInit(GlobalContext* globalCtx, DynaCollisionContext* param_2); -void BgCheck_DynaAlloc(GlobalContext* globalCtx, DynaCollisionContext* dyna); -s32 BgCheck_AddActorMesh(GlobalContext* globalCtx, DynaCollisionContext* dyna, DynaPolyActor* actor, CollisionHeader* header); -DynaPolyActor* BgCheck_GetActorOfMesh(CollisionContext* colCtx, s32 index); -void func_800C62BC(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void func_800C6314(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void func_800C636C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void func_800C63C4(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void func_800C641C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void func_800C6474(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -void BgCheck_RemoveActorMesh(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index); -// void func_800C6554(void); +void func_800BE568(Actor* actor, ColliderSphere* collider); +void func_800BE5CC(Actor* actor, ColliderJntSph* collider, s32 colliderIndex); +s32 func_800BE63C(struct EnBox* chest); +void Actor_DrawDamageEffects(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s16 limbPosCount, f32 effectScale, f32 frozenSteamScale, f32 effectAlpha, u8 type); +void Actor_SpawnIceEffects(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s32 limbPosCount, s32 effectsPerLimb, f32 scale, f32 scaleRange); + +void ActorOverlayTable_FaultPrint(void* arg0, void* arg1); +void* ActorOverlayTable_FaultAddrConv(void* arg0, void* arg1); +void ActorOverlayTable_Init(void); +void ActorOverlayTable_Cleanup(void); + +void SSNode_SetValue(SSNode* node, s16* polyIndex, u16 next); +void SSList_SetNull(SSList* head); +void SSNodeList_SetSSListHead(SSNodeList* list, SSList* ssList, s16* polyIndex); +void DynaSSNodeList_SetSSListHead(DynaSSNodeList* list, SSList* ssList, s16* polyIndex); +void DynaSSNodeList_Init(GlobalContext* globalCtx, DynaSSNodeList* list); +void DynaSSNodeList_Alloc(GlobalContext* globalCtx, DynaSSNodeList* list, u32 numNodes); +void DynaSSNodeList_ResetCount(DynaSSNodeList* list); +u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList* list); +void BgCheck_Vec3sToVec3f(Vec3s* vertex, Vec3f* vector); +void BgCheck_Vec3fToVec3s(Vec3s* vertex, Vec3f* vector); +f32 func_800BFD84(CollisionPoly *poly, f32 arg1, f32 arg2); +s32 func_800BFDEC(CollisionPoly* polyA, CollisionPoly* polyB, u32* outVtxId0, u32* outVtxId1); +s16 CollisionPoly_GetMinY(CollisionPoly* poly, Vec3s* vertices); +void CollisionPoly_GetNormalF(CollisionPoly* poly, f32* nx, f32* ny, f32* nz); +void func_800C0094(CollisionPoly* poly, f32 tx, f32 ty, f32 tz, MtxF* dest); +f32 CollisionPoly_GetPointDistanceFromPlane(CollisionPoly* poly, Vec3f* point); +void CollisionPoly_GetVerticesByBgId(CollisionPoly* poly, s32 bgId, CollisionContext* colCtx, Vec3f* dest); +s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center, f32 radius); +void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, CollisionPoly* polyList, Vec3s* vtxList, s16 polyId); +void StaticLookup_AddPoly(StaticLookup* lookup, CollisionContext* colCtx, CollisionPoly* polyList, Vec3s* vtxList, s16 index); +void BgCheck_GetSubdivisionMinBounds(CollisionContext* colCtx, Vec3f* pos, s32* sx, s32* sy, s32* sz); +void BgCheck_GetSubdivisionMaxBounds(CollisionContext* colCtx, Vec3f* pos, s32* sx, s32* sy, s32* sz); +void BgCheck_GetPolySubdivisionBounds(CollisionContext* colCtx, Vec3s* vtxList, CollisionPoly* polyList, s32* subdivMinX, s32* subdivMinY, s32* subdivMinZ, s32* subdivMaxX, s32* subdivMaxY, s32* subdivMaxZ, s16 polyId); +s32 BgCheck_PolyIntersectsSubdivision(Vec3f* min, Vec3f* max, CollisionPoly* polyList, Vec3s* vtxList, s16 polyId); +u32 BgCheck_InitStaticLookup(CollisionContext* colCtx, GlobalContext* globalCtx, StaticLookup* lookupTbl); +s32 BgCheck_IsSmallMemScene(GlobalContext* globalCtx); +s32 BgCheck_TryGetCustomMemsize(s32 sceneId, u32* memSize); +void BgCheck_SetSubdivisionDimension(f32 min, s32 subdivAmount, f32* max, f32* subdivLength, f32* subdivLengthInv); +s32 BgCheck_GetSpecialSceneMaxObjects(GlobalContext* globalCtx, s32* maxNodes, s32* maxPolygons, s32* maxVertices); +void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, CollisionHeader* colHeader); +void BgCheck_SetContextFlags(CollisionContext* colCtx, u32 flags); +void BgCheck_UnsetContextFlags(CollisionContext* colCtx, u32 flags); +CollisionHeader* BgCheck_GetCollisionHeader(CollisionContext* colCtx, s32 bgId); +f32 BgCheck_RaycastFloorImpl(GlobalContext* globalCtx, CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, s32* outBgId, Vec3f* pos, Actor* actor, u32 arg7, f32 chkDist, s32 arg9); +f32 BgCheck_CameraRaycastFloor1(CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor1(CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor2(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor2_1(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor3(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor5(CollisionContext* colCtx, CollisionPoly** outPoly, s32* outBgId, Actor* actor, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor5_2(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor5_3(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor6(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos, f32 chkDist); +f32 BgCheck_EntityRaycastFloor7(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos); +f32 BgCheck_AnyRaycastFloor1(CollisionContext* colCtx, CollisionPoly* outPoly, Vec3f* pos); +f32 BgCheck_AnyRaycastFloor2(CollisionContext* colCtx, CollisionPoly* outPoly, s32* bgId, Vec3f* pos); +f32 BgCheck_CameraRaycastFloor2(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor8(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos); +f32 BgCheck_EntityRaycastFloor9(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos); +s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight, u8 argA); +s32 BgCheck_EntitySphVsWall1(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, CollisionPoly** outPoly, f32 checkHeight); +s32 BgCheck_EntitySphVsWall2(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, CollisionPoly** outPoly, s32* outBgId, f32 checkHeight); +s32 BgCheck_EntitySphVsWall3(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight); +s32 BgCheck_EntitySphVsWall4(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight); +s32 BgCheck_CheckCeilingImpl(CollisionContext* colCtx, u16 xpFlags, f32* outY, Vec3f* pos, f32 checkHeight, CollisionPoly** outPoly, s32* outBgId, Actor* actor); +s32 BgCheck_AnyCheckCeiling(CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight); +s32 BgCheck_EntityCheckCeiling(CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight, CollisionPoly** outPoly, s32* outBgId, Actor* actor); +s32 BgCheck_CameraLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId); +s32 BgCheck_CameraLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId); +s32 BgCheck_EntityLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId); +s32 BgCheck_EntityLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId, Actor* actor); +s32 BgCheck_EntityLineTest3(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId, Actor* actor, f32 chkDist); +s32 BgCheck_ProjectileLineTest(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId); +s32 BgCheck_AnyLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkOneFace); +s32 BgCheck_AnyLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace); +s32 BgCheck_AnyLineTest3(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, s32 chkWall, s32 chkFloor, s32 chkCeil, s32 chkOneFace, s32* bgId); +s32 BgCheck_SphVsFirstPolyImpl(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, s32* outBgId, Vec3f* center, f32 radius, Actor* actor, u16 bciFlags); +s32 BgCheck_SphVsFirstPoly(CollisionContext* colCtx, Vec3f* center, f32 radius); +s32 BgCheck_SphVsFirstWall(CollisionContext* colCtx, Vec3f* center, f32 radius); +void SSNodeList_Init(SSNodeList* this); +void SSNodeList_Alloc(GlobalContext* globalCtx, SSNodeList* this, s32 tblMax, s32 numPolys); +SSNode* SSNodeList_GetNextNode(SSNodeList* this); +u16 SSNodeList_GetNextNodeIdx(SSNodeList* this); +void ScaleRotPos_Init(ScaleRotPos* srp); +void ScaleRotPos_SetValue(ScaleRotPos* srp, Vec3f* scale, Vec3s* rot, Vec3f* pos); +s32 ScaleRotPos_IsEqual(ScaleRotPos* a, ScaleRotPos* b); +void DynaLookup_ResetLists(DynaLookup* dynaLookup); +void DynaLookup_Reset(DynaLookup* dynaLookup); +void DynaLookup_ResetVtxStartIndex(u16* vtxStartIndex); +void DynaLookup_ResetWaterBoxStartIndex(u16* waterBoxStartIndex); +void BgActor_Init(GlobalContext* globalCtx, BgActor* bgActor); +void BgActor_SetActor(BgActor* bgActor, Actor* actor, CollisionHeader* colHeader); +s32 BgActor_IsTransformUnchanged(BgActor* bgActor); +void DynaPoly_NullPolyList(CollisionPoly** polyList); +void DynaPoly_AllocPolyList(GlobalContext* globalCtx, CollisionPoly** polyList, s32 numPolys); +void DynaPoly_NullVtxList(Vec3s** vtxList); +void DynaPoly_AllocVtxList(GlobalContext* globalCtx, Vec3s** vtxList, s32 numVtx); +void DynaPoly_InitWaterBoxList(DynaWaterBoxList* waterBoxList); +void DynaPoly_AllocWaterBoxList(GlobalContext* globalCtx, DynaWaterBoxList* waterBoxList, s32 numWaterBoxes); +void DynaPoly_SetBgActorPrevTransform(GlobalContext* globalCtx, BgActor* bgActor); +s32 DynaPoly_IsBgIdBgActor(s32 bgId); +void DynaPoly_Init(GlobalContext* globalCtx, DynaCollisionContext* dyna); +void DynaPoly_Alloc(GlobalContext* globalCtx, DynaCollisionContext* dyna); +s32 DynaPoly_SetBgActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, Actor* actor, CollisionHeader* colHeader); +DynaPolyActor* DynaPoly_GetActor(CollisionContext* colCtx, s32 bgId); +void func_800C62BC(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void func_800C6314(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void func_800C636C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void func_800C63C4(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void func_800C641C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void func_800C6474(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); +void DynaPoly_DeleteBgActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId); void BgCheck_CalcWaterboxDimensions(Vec3f* minPos, Vec3f* maxXPos, Vec3f* maxZPos, Vec3s* minPosOut, s16* xLength, s16* zLength); -void BgCheck_AddActorMeshToLists(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 index, s32* currVertices, s32* currPolygons, s32* currWaterboxes); +void DynaPoly_ExpandSRT(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId, s32* vtxStartIndex, s32* polyStartIndex, s32* waterBoxStartIndex); void BgCheck_ResetFlagsIfLoadedActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, Actor* actor); -void BgCheck_Update(GlobalContext* globalCtx, DynaCollisionContext* dyna); -void func_800C756C(s32 param_1, s32* param_2, s32* param_3, s32* param_4); -void BgCheck_UpdateAllActorMeshes(GlobalContext* globalCtx, DynaCollisionContext* dyna); -// void func_800C76EC(void); -// void func_800C7974(void); -// void func_800C7E40(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, UNK_TYPE4 param_11, UNK_TYPE4 param_12); -// void func_800C8580(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); -// void func_800C87D0(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); -// void func_800C8A60(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_800C8BD0(void); -// void func_800C8DC0(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, UNK_TYPE4 param_11); -// void func_800C8EEC(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, UNK_TYPE4 param_11); -// void func_800C90AC(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_800C921C(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 func_800C9380(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); -void BgCheck_RelocateMeshHeaderPointers(CollisionHeader* header); -void BgCheck_RelocateMeshHeader(CollisionHeader* meshSegPtr, CollisionHeader** param_2); -void BgCheck_RelocateAllMeshHeaders(CollisionContext* colCtx, GlobalContext* globalCtx); -// void func_800C9640(void); -u32 BgCheck_GetPolygonAttributes(CollisionContext* colCtx, CollisionPoly* polygon, s32 index, s32 attributeIndex); -u32 func_800C9704(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// void func_800C9728(void); -// UNK_TYPE4 func_800C9770(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// void func_800C97F8(void); -// UNK_TYPE4 func_800C9844(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// void func_800C98CC(void); -// UNK_TYPE4 func_800C9924(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C99AC(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C99D4(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C99FC(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9A24(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9A4C(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9A7C(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9AB0(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9AE4(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9B18(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9B40(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9B68(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9B90(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9BB8(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9BDC(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// u32 func_800C9C24(CollisionContext* colCtx, CollisionPoly* polygon, s32 index, UNK_TYPE4 param_4); -u32 func_800C9C74(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9C9C(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9CC4(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9CEC(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -// void func_800C9D14(void); -// void func_800C9D50(void); -u32 func_800C9D8C(CollisionContext* param_1, CollisionPoly* param_2, s32 param_3); -// void func_800C9DDC(void); -u32 func_800C9E18(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9E40(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -u32 func_800C9E88(CollisionContext* colCtx, CollisionPoly* polygon, s32 index); -s32 func_800C9EBC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox, s32* bgId); -s32 func_800CA1AC(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); -s32 func_800CA1E8(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); -// void func_800CA22C(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_800CA568(void); -// void func_800CA634(void); -// void func_800CA648(void); -// void func_800CA6B8(void); -// void func_800CA6D8(void); -// void func_800CA6F0(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_800CA9D0(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_800CAA14(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); +void DynaPoly_Setup(GlobalContext* globalCtx, DynaCollisionContext* dyna); +void func_800C756C(DynaCollisionContext* dyna, s32* numPolygons, s32* numVertices, s32* numWaterBoxes); +void DynaPoly_UpdateBgActorTransforms(GlobalContext* globalCtx, DynaCollisionContext* dyna); +void CollisionHeader_SegmentedToVirtual(CollisionHeader* header); +void CollisionHeader_GetVirtual(CollisionHeader* meshSegPtr, CollisionHeader** param_2); +void BgCheck_InitCollisionHeaders(CollisionContext* colCtx, GlobalContext* globalCtx); +u32 SurfaceType_GetData(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId, s32 dataIdx); +u32 SurfaceType_GetCamDataIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u16 SurfaceType_GetCameraSType(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u16 SurfaceType_GetNumCameras(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +Vec3s* SurfaceType_GetCamPosData(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_GetSceneExitIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C99D4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C99FC(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C9A24(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9A4C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9A7C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9AB0(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9AE4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C9B18(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C9B40(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C9B68(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_IsHorseBlocked(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 func_800C9BB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u16 SurfaceType_GetSfx(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9C24(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId, s32 arg3); +u32 SurfaceType_GetSlope(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_GetLightSettingIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_GetEcho(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_IsHookshotSurface(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 SurfaceType_IsIgnoredByEntities(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 SurfaceType_IsIgnoredByProjectiles(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 SurfaceType_GetConveyorType(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 func_800C9DDC(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_GetConveyorSpeed(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_GetConveyorDirection(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +u32 SurfaceType_IsWallDamage(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId); +s32 WaterBox_GetSurfaceImpl(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox, s32* bgId); +s32 WaterBox_GetSurface1(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); +s32 WaterBox_GetSurface1_2(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); +s32 WaterBox_GetSurface2(GlobalContext* globalCtx, CollisionContext* colCtx, Vec3f* pos, f32 surfaceChkDist, WaterBox** outWaterBox, s32* bgId); +f32 func_800CA568(CollisionContext* colCtx, s32 waterBoxId, s32 bgId); +u16 WaterBox_GetCameraSType(CollisionContext* colCtx, WaterBox* waterBox, s32 bgId); +void func_800CA6B8(CollisionContext* colCtx, WaterBox* waterBox); +u32 WaterBox_GetLightSettingIndex(CollisionContext* colCtx, WaterBox* waterBox); +s32 func_800CA6F0(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox, s32* bgId); +s32 func_800CA9D0(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, WaterBox** outWaterBox); +s32 func_800CAA14(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* pointA, Vec3f* pointB, Vec3f* closestPoint); void BgCheck2_UpdateActorPosition(CollisionContext* colCtx, s32 index, Actor* actor); void BgCheck2_UpdateActorYRotation(CollisionContext* colCtx, s32 index, Actor* actor); void BgCheck2_AttachToMesh(CollisionContext* colCtx, Actor* actor, s32 index); u32 BgCheck2_UpdateActorAttachedToMesh(CollisionContext* colCtx, s32 index, Actor* actor); -void BcCheck3_BgActorInit(DynaPolyActor* actor, UNK_TYPE4 param_2); -void BgCheck3_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* actor, CollisionHeader* meshHeader); -void BgCheck3_ResetFlags(DynaPolyActor* actor); -void func_800CAE88(DynaPolyActor* actor); -void func_800CAE9C(DynaPolyActor* actor); -void func_800CAEB0(CollisionContext* colCtx, s32 index); -void func_800CAEE0(DynaPolyActor* actor); -void func_800CAEF4(CollisionContext* colCtx, s32 index); -void func_800CAF24(DynaPolyActor* actor); -void func_800CAF38(DynaPolyActor* actor); -s32 func_800CAF4C(DynaPolyActor* actor); -s32 func_800CAF70(DynaPolyActor* actor); -s32 func_800CAF94(DynaPolyActor* actor); -s32 func_800CAFB8(DynaPolyActor* actor); -s32 func_800CAFDC(DynaPolyActor* actor); -// void func_800CB000(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); +void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags); +void DynaPolyActor_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* dynaActor, CollisionHeader* meshHeader); +void DynaPolyActor_ResetState(DynaPolyActor* dynaActor); +void DynaPolyActor_SetRidingFallingState(DynaPolyActor* dynaActor); +void DynaPolyActor_SetRidingMovingState(DynaPolyActor* dynaActor); +void DynaPolyActor_SetRidingMovingStateByIndex(CollisionContext* colCtx, s32 index); +void DynaPolyActor_SetRidingRotatingState(DynaPolyActor* dynaActor); +void DynaPolyActor_SetRidingRotatingStateByIndex(CollisionContext* colCtx, s32 index); +void DynaPolyActor_SetSwitchPressedState(DynaPolyActor* dynaActor); +void DynaPolyActor_SetHeavySwitchPressedState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsInRidingFallingState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsInRidingMovingState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsInRidingRotatingState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsInSwitchPressedState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_IsInHeavySwitchPressedState(DynaPolyActor* dynaActor); +s32 DynaPolyActor_ValidateMove(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 startRadius, s16 endRadius, s16 startHeight); f32 Camera_fabsf(f32 f); f32 Camera_LengthVec3f(Vec3f* v); // void func_800CB270(void); @@ -1292,18 +1132,18 @@ void func_800DE0EC(Camera* camera, Actor* actor); Vec3s* Camera_Update(Vec3s* param_1, Camera* camera); // void func_800DF498(void); u32 Camera_SetMode(Camera* camera, s16 mode, s8 param_3); -// void func_800DF840(void); +s32 Camera_ChangeMode(Camera* camera, s16 mode); // void func_800DF86C(void); // void func_800DF8EC(void); s32 func_800DFAC8(Camera* camera, s16 param_2); -u32 func_800DFB14(Camera* camera, u32 param_2); +u32 Camera_ChangeDataIdx(Camera* camera, u32 camDataIdx); // void func_800DFC1C(void); // void func_800DFC40(void); -s32 func_800DFC68(Camera* camera); -// void func_800DFC90(void); -s16 func_800DFCB4(Camera* camera); -s16 func_800DFCDC(Camera* camera); -// void func_800DFD04(void); +s32 Camera_GetInputDirYaw(Camera* camera); +void func_800DFC90(Vec3s* arg0, Camera* camera); +s16 Camera_GetCamDirPitch(Camera* camera); +s16 Camera_GetCamDirYaw(Camera* camera); +void func_800DFD04(Camera* camera, s32 arg1, s32 arg2, s32 arg3); // void func_800DFD78(void); // UNK_TYPE4 func_800DFEF0(s32 param_1, u16 param_2); // UNK_TYPE4 func_800DFF18(Camera* iParm1, UNK_TYPE2 uParm2); @@ -1311,16 +1151,16 @@ s16 func_800DFCDC(Camera* camera); // UNK_TYPE4 func_800DFF44(void); s16 Camera_SetFlags(Camera* iParm1, s16 flags); s16 Camera_ClearFlags(Camera* camera, s16 flags); -// void func_800DFFAC(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); +s32 func_800DFFAC(Camera* camera, Actor* doorActor, s16 bgCamDataId, f32 arg3, s16 timer1, s16 timer2, s16 timer3); // UNK_TYPE4 func_800E007C(Camera* param_1, Camera* param_2); // UNK_TYPE4 func_800E01AC(void); -// void func_800E01B8(void); +Vec3f* Camera_GetQuakeOffset(Vec3f* dst, Camera* camera); // void func_800E01DC(s32 param_1, u32 param_2, UNK_TYPE4 param_3, UNK_TYPE4 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); // UNK_TYPE4 func_800E0228(void); // void func_800E0238(void); -void func_800E02AC(Camera* camera, Actor* actor); -// void func_800E0308(void); -// void func_800E031C(void); +void Camera_SetToTrackActor(Camera* camera, Actor* actor); +void Camera_SetTargetActor(Camera* camera, Actor* actor); +f32 Camera_GetWaterYPos(Camera* camera); void func_800E0348(Camera* camera); DamageTable* DamageTable_Get(s32 index); void DamageTable_Clear(DamageTable* damageTable); @@ -1542,70 +1382,34 @@ s32 func_800E8F08(Vec3s* param_1, Vec3s* param_2); s32 func_800E8FA4(Actor* actor, Vec3f* param_2, Vec3s* param_3, Vec3s* param_4); s32 func_800E9138(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* param_4, f32 param_5); s32 func_800E9250(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* param_4, Vec3f param_5); -u8 func_800E9360(void); +void SaveContext_Init(void); void GameInfo_Init(void); -// void func_800E9470(void); -void DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX, f32 scaleY, f32 scaleZ, u8 red, u8 green, u8 blue, u8 alpha, s16 type, GraphicsContext* gfxCtx); -void DebugDisplay_DrawObjects(GlobalContext* globalCtx); -// void func_800E95F4(void); -// void func_800E97D8(void); -// void func_800E992C(void); -// void func_800E99B0(void); +// void DebugDisplay_Init(void); +DebugDispObject* DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX, f32 scaleY, f32 scaleZ, u8 red, u8 green, u8 blue, u8 alpha, s16 type, GraphicsContext* gfxCtx); // void func_800E9C90(void); // void func_800E9CA0(s32 param_1, UNK_TYPE1 param_2, s8* param_3); // void func_800E9CFC(void); // void func_800E9DBC(void); // void func_800E9E94(void); void func_800E9F78(GraphicsContext* gfxCtx); + void Cutscene_Init(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EA0D4(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EA0EC(GlobalContext* globalCtx, CutsceneContext* csCtx); -void Cutscene_StepCutscene1(GlobalContext* globalCtx, CutsceneContext* csCtx); -void Cutscene_StepCutscene2(GlobalContext* globalCtx, CutsceneContext* csCtx); -void Cutscene_Nop800EA210(GlobalContext* globalCtx, CutsceneContext* csCtx); -s32 func_800EA220(GlobalContext* globalCtx, CutsceneContext* csCtx, f32 target); -void func_800EA258(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EA2B8(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EA324(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EABAC(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdEnvLighting* cmd); -void func_800EAC08(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdMusicChange* cmd); -void func_800EAC44(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdMusicChange* cmd); -void func_800EAC94(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdMusicFade* cmd); -void func_800EAD14(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EAD48(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EAD7C(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EADB0(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EAECC(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EAF20(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdUnk190* cmd); -void func_800EAFE0(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdUnk9B* cmd); -void func_800EB1DC(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdDayTime* cmd); -void func_800EB364(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EB4B4(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EB6F8(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EBB68(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EBCD0(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -void func_800EBD60(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd); -s32 func_800EC678(GlobalContext* globalCtx, CsCmdUnk5A* cmd); -// u32 func_800EC6D4(void); -void func_800EC924(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdTextbox* cmd); -void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index); -void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cutscenePtr, u16* commandReadHead); -void func_800ED980(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800ED9C4(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EDA04(GlobalContext* globalCtx, CutsceneContext* csCtx); -void func_800EDA84(GlobalContext* globalCtx, CutsceneContext* csCtx); +void Cutscene_Start(GlobalContext* globalCtx, CutsceneContext* csCtx); +void Cutscene_End(GlobalContext* globalCtx, CutsceneContext* csCtx); +void Cutscene_Update1(GlobalContext* globalCtx, CutsceneContext* csCtx); +void Cutscene_Update2(GlobalContext* globalCtx, CutsceneContext* csCtx); void func_800EDBE0(GlobalContext* globalCtx); -void nop_800EDDB0(GlobalContext* globalCtx); -// void func_800EDDBC(void); -void func_800EDDCC(GlobalContext* globalCtx, u32 uParm2); -void func_800EDE34(Actor* actor, GlobalContext* globalCtx, s32 param_3); -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_800EE2F4(GlobalContext* globalCtx); +void func_800EDDB0(GlobalContext* globalCtx); +void Cutscene_LoadCutsceneData(GlobalContext* globalCtx, u8 csIndex); +void Cutscene_ActorTranslate(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex); +void Cutscene_ActorTranslateAndYaw(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex); +void Cutscene_ActorTranslateAndYawSmooth(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex); +void Cutscene_ActorTranslateXZAndYawSmooth(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex); +s32 Cutscene_GetSceneSetupIndex(GlobalContext* globalCtx); +s32 Cutscene_GetActorActionIndex(GlobalContext* globalCtx, u16 actorActionCmd); +s32 Cutscene_CheckActorAction(GlobalContext* globalCtx, u16 actorActionCmd); +u8 Cutscene_IsPlaying(GlobalContext* globalCtx); + void GetItem_Draw(GlobalContext* globalCtx, s16 index); void func_800EE364(GlobalContext* globalCtx, s16 index); void func_800EE400(GlobalContext* globalCtx, s16 index); @@ -1634,32 +1438,17 @@ void EffFootmark_Init(GlobalContext* globalCtx); void EffFootmark_Add(GlobalContext* globalCtx, MtxF* displayMatrix, Actor* actor, u8 id, Vec3f* location, u16 size, u8 red, u8 green, u8 blue, u16 alpha, u16 alphaChange, u16 fadeoutDelay); void EffFootmark_Update(GlobalContext* globalCtx); void EffFootmark_Draw(GlobalContext* globalCtx); -void func_800F0390(GlobalContext* globalCtx); -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(void); -// 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); +void SoundSource_InitAll(GlobalContext* globalCtx); +void SoundSource_UpdateAll(GlobalContext* globalCtx); +void SoundSource_PlaySfxAtFixedWorldPos(GlobalContext* globalCtx, Vec3f* worldPos, u32 duration, u16 sfxId); +void SoundSource_PlaySfxEachFrameAtFixedWorldPos(GlobalContext* globalCtx, Vec3f* worldPos, u32 duration, u16 sfxId); +u16 ElfMessage_GetFirstCycleHint(GlobalContext* globalCtx); + u16 Text_GetFaceReaction(GlobalContext* globalCtx, u32 reactionSet); -void func_800F12D0(GlobalContext* globalCtx); -void func_800F1304(GlobalContext* globalCtx, s16 param_2); -void func_800F1374(s32 param_1, s16 param_2); -s16 func_800F13E8(GlobalContext* globalCtx, s16 param_2); +void EnvFlags_UnsetAll(GlobalContext* globalCtx); +void EnvFlags_Set(GlobalContext* globalCtx, s16 flag); +void EnvFlags_Unset(GlobalContext* globalCtx, s16 flag); +s32 EnvFlags_Get(GlobalContext* globalCtx, s16 flag); s16 func_800F1460(s16 param_1); ActorCutscene* ActorCutscene_GetCutsceneImpl(s16 index); void ActorCutscene_Init(GlobalContext* globalCtx, ActorCutscene* cutscenes, s32 num); @@ -1679,55 +1468,42 @@ s16 ActorCutscene_GetCurrentIndex(void); 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_800F2138(s8 arg0); +s32 func_800F2178(s16 arg0); s16 ActorCutscene_GetCurrentCamera(s16 index); -// void func_800F21CC(void); +s16 func_800F21CC(void); s32 func_800F22C4(s16 param_1, Actor* actor); void ActorCutscene_SetReturnCamera(s16 index); // void func_800F23E0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); f32 func_800F2478(f32 target, TransformData* transData, s32 refIdx); void SkelCurve_Clear(SkelAnimeCurve* skelCurve); -s32 SkelCurve_Init(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, SkelCurveLimbList* limbListSeg, - TransformUpdateIndex* transUpdIdx); +s32 SkelCurve_Init(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, SkelCurveLimbList* limbListSeg, TransformUpdateIndex* transUpdIdx); void SkelCurve_Destroy(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve); -void SkelCurve_SetAnim(SkelAnimeCurve* skelCurve, TransformUpdateIndex* transUpdIdx, f32 arg2, f32 animFinalFrame, - f32 animCurFrame, f32 animSpeed); +void SkelCurve_SetAnim(SkelAnimeCurve* skelCurve, TransformUpdateIndex* transUpdIdx, f32 arg2, f32 animFinalFrame, f32 animCurFrame, f32 animSpeed); s32 SkelCurve_Update(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve); -void SkelCurve_Draw(Actor* actor, GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, - OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, Actor* thisx); -void FireObj_InitWithParams(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init); -void FireObj_SetState(FireObj* fire, f32 dynamicSizeStep, u8 newState); +void SkelCurve_Draw(Actor* actor, GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, Actor* thisx); void FireObj_SetPosition(FireObj* fire, Vec3f* pos); -void FireObj_StepSize(FireObj* fire); -void FireObj_UpdateStateTransitions(GlobalContext* globalCtx, FireObj* fire); void FireObj_Draw(GlobalContext* globalCtx, FireObj* fire); -void FireObj_InitLight(GlobalContext* globalCtx, FireObjLight* light, u8* param_3, Vec3f* pos); -void FireObj_FiniLight(GlobalContext* globalCtx, FireObjLight* light); -void FireObj_UpdateLight(GlobalContext* globalCtx, FireObjLight* light, FireObj* fire); void FireObj_Init(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init, Actor* actor); -void FireObj_Fini(GlobalContext* globalCtx, FireObj* fire); +void FireObj_Destroy(GlobalContext* globalCtx, FireObj* fire); void FireObj_SetState2(FireObj* fire, f32 dynamicSizeStep, u8 newState); -void FireObj_Update(GlobalContext* globalCtx, FireObj* fire); -// void func_800F3940(void); +void FireObj_Update(GlobalContext* globalCtx, FireObj* fire, Actor* actor); +s32 func_800F3940(GlobalContext* globalCtx); // void func_800F39B4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_800F3A64(void); -// void func_800F3B2C(void); +void func_800F3B2C(GlobalContext* globalCtx); // void func_800F3B68(void); // void func_800F3C44(void); // void func_800F3ED4(void); -void func_800F40A0(GlobalContext* globalCtx, s32 param_2); -// void func_800F415C(void); +void func_800F40A0(GameState* gameState, Player* player); +void func_800F415C(Actor* actor, Vec3f* arg1, s16 arg2); UNK_TYPE func_800F41E4(GlobalContext* globalCtx, ActorContext* actorCtx); -// void func_800F42A0(void); -// void func_800F43BC(void); -// void func_800F44F4(void); -// void func_800F4540(void); -// s32 func_800F470C(UNK_TYPE4 param_1, UNK_TYPE4 param_2, s32 param_3, u32 param_4); + void func_800F4A10(GlobalContext* globalCtx); -void func_800F4C0C(GlobalContext* globalCtx); -void func_800F4E20(GlobalContext* globalCtx); -void func_800F4F28(GlobalContext* globalCtx); +void KaleidoSetup_Update(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); @@ -1736,10 +1512,10 @@ void Font_LoadOrderedFont(Font* font); // void func_800F50D4(void); void Kankyo_Init(GlobalContext* globalCtx, EnvironmentContext* envCtx); 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); +f32 Environment_LerpWeight(u16 max, u16 min, u16 val); // 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); @@ -1764,7 +1540,7 @@ void func_800FAAB4(GlobalContext* globalCtx, u8 arg1); // void func_800FAC20(void); // void func_800FAF74(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); // void func_800FB010(void); -void func_800FB320(GlobalContext* globalCtx, u8 param_2); +void Environment_AddLightningBolts(GlobalContext* globalCtx, u8 num); // void func_800FB388(void); void func_800FB758(GlobalContext* globalCtx); // void func_800FB9B4(void); @@ -1775,16 +1551,16 @@ 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); void func_800FD654(GlobalContext* globalCtx, Color_RGB8* pzParm2, f32 fParm3); -// void func_800FD698(void); +void func_800FD698(GlobalContext* globalCtx, s16 arg1, s16 arg2, f32 arg3); // u32 get_days_elapsed(void); // void reset_days_elapsed(void); // u32 get_current_day(void); -void func_800FD750(UNK_TYPE arg0); +void func_800FD750(u16 seqId); // void func_800FD768(void); void func_800FD78C(GlobalContext* globalCtx); void func_800FD858(GlobalContext* globalCtx); @@ -1801,15 +1577,15 @@ u32 func_800FE4B8(GlobalContext* globalCtx); // void func_800FE590(void); // void func_800FE5D0(void); // UNK_TYPE4 func_800FE610(void); -s32 func_800FE620(GlobalContext* globalCtx); +u32 func_800FE620(GlobalContext* globalCtx); void func_800FE658(f32 arg0); // UNK_TYPE4 func_800FE6F8(UNK_TYPE4 param_1, s16 param_2, s16 param_3); // void func_800FE778(void); // void func_800FE788(void); // void func_800FE798(void); -// void func_800FE7A8(void); -// void func_800FE9B4(void); -// void func_800FEA50(void); +void func_800FE7A8(Color_RGBA8* inColor, Color_RGBA8* outColor); +s32 func_800FE9B4(GlobalContext* globalCtx); +void func_800FEA50(GlobalContext* globalCtx); void func_800FEAB0(void); // void func_800FEAC0(void); void func_800FEAF4(EnvironmentContext* envCtx); @@ -1868,12 +1644,12 @@ void Actor_ProcessInitChain(Actor* actor, InitChainEntry* ichain); f32 Math_SmoothStepToF(f32* pValue, f32 target, f32 fraction, f32 step, f32 minStep); void Math_ApproachF(f32* pValue, f32 target, f32 scale, f32 maxStep); void Math_ApproachZeroF(f32* pValue, f32 scale, f32 maxStep); -s32 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep); +s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep); void Math_ApproachS(s16* pValue, s16 target, s16 scale, s16 maxStep); void Color_RGBA8_Copy(Color_RGBA8* dst, Color_RGBA8* src); void func_801000A4(u16 sfxId); void func_801000CC(u16 sfxId); -void func_801000F4(s32 a0, u16 a1); +void Lib_PlaySfxAtPos(Vec3f* pos, u16 sfxId); void Lib_Vec3f_TranslateAndRotateY(Vec3f* translation, s16 a, Vec3f* src, Vec3f* dst); void Lib_LerpRGB(Color_RGB8* a, Color_RGB8* b, f32 t, Color_RGB8* dst); f32 Math_Vec3f_StepTo(Vec3f* start, Vec3f* target, f32 speed); @@ -1923,7 +1699,7 @@ void* ZeldaArena_Realloc(void* oldPtr, size_t newSize); void ZeldaArena_Free(void* param_1); void* ZeldaArena_Calloc(u32 num, size_t size); void ZeldaArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); -void ZeldaArena_Check(); +s32 ZeldaArena_Check(); void ZeldaArena_Init(void* start, size_t size); void ZeldaArena_Cleanup(); u8 ZeldaArena_IsInitialized(); @@ -2021,8 +1797,8 @@ void func_80105818(GlobalContext* globalCtx, u32 uParm2, TransitionActorEntry* p // void func_80109EF8(void); // void func_80109F78(void); s32 func_8010A000(GlobalContext* globalCtx); -// void func_8010A074(void); -// void func_8010A0A4(void); +s32 func_8010A074(GlobalContext* globalCtx); +s32 func_8010A0A4(GlobalContext* globalCtx); // void func_8010A0F0(void); // void func_8010A164(void); // void func_8010A194(void); @@ -2090,7 +1866,7 @@ s32 func_8010BF58(Actor* actor, GlobalContext* globalCtx, s32* param_3, UNK_PTR void Nmi_Init(void); void Nmi_SetPrenmiStart(void); // s32 Nmi_GetPrenmiHasStarted(void); -// void func_8010C1B0(void); +void MsgEvent_SendNullTask(void); f32 OLib_Vec3fDist(Vec3f* a, Vec3f* b); f32 OLib_Vec3fDistOutDiff(Vec3f* a, Vec3f* b, Vec3f* dest); f32 OLib_Vec3fDistXZ(Vec3f* a, Vec3f* b); @@ -2121,7 +1897,7 @@ void OLib_DbCameraVec3fSum(PosRot* a, Vec3f* b, Vec3f* dest, s16 mode); // void func_8010E028(void); // void func_8010E968(void); void func_8010E9F0(s16 arg0, s16 arg1); -// void func_8010EA9C(void); +void func_8010EA9C(s32 arg0, s32 arg1); // void func_8010EB50(void); // void func_8010EBA0(void); // void func_8010EC54(void); @@ -2134,18 +1910,18 @@ void Interface_ChangeAlpha(u16 param_1); // void func_80111CB4(void); // void func_801129E4(void); void func_80112AFC(GlobalContext* globalCtx); -void func_80112B40(GlobalContext* globalCtx, s32 arg1); +void func_80112B40(GlobalContext* globalCtx, u8 arg1); // void func_80112BE4(void); // void func_80112C0C(void); u32 Item_Give(GlobalContext* globalCtx, u8 param_2); // void func_801143CC(void); UNK_TYPE func_80114978(UNK_TYPE arg0); -void func_801149A0(s32 arg0, s16 arg1); +void func_801149A0(s32 itemId, s16 slotId); // void func_80114A9C(void); // void func_80114B84(void); // void func_80114CA0(void); -UNK_TYPE func_80114E90(void); -UNK_TYPE func_80114F2C(UNK_TYPE arg0); +s32 Interface_HasEmptyBottle(void); +s32 Interface_HasItemInBottle(u8 itemId); // void func_80114FD0(void); // void func_80115130(void); // void func_801152B8(void); @@ -2155,10 +1931,10 @@ void func_8011552C(GlobalContext* globalCtx, s16 arg1); // void func_801155B4(void); // void func_80115764(void); void func_80115844(GlobalContext* globalCtx, s16 param_2); -void func_80115908(GlobalContext* globalCtx, u8 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); @@ -2193,12 +1969,12 @@ void func_8011C808(GlobalContext* globalCtx); // void func_801210E0(void); // void func_80121F94(void); void func_80121FC4(GlobalContext* globalCtx); -s32 func_801224E0(s32 param_1, s16 param_2, s16 param_3); -f32 func_80122524(Actor* actor, Path* path, s16 arg2, s16* arg3); -// void func_801225CC(void); -// void func_80122660(void); -// UNK_TYPE4 func_80122670(s32* param_1, Input* input); -// void func_801226E0(void); +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 FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx); +s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input); +void func_801226E0(GlobalContext* globalCtx, s8 arg1); void func_80122744(GlobalContext* globalCtx, UNK_PTR arg1, u32 arg2, Vec3s* arg3); s32 func_80122760(GlobalContext* globalCtx, UNK_PTR arg1, f32 arg2); void func_80122868(GlobalContext* globalCtx, Player* player); @@ -2210,14 +1986,14 @@ void func_801229A0(GlobalContext* globalCtx, Player* player); // void func_80122D44(void); // void func_80122ED8(void); // void func_80122EEC(void); -void func_80122F28(Player* player, GlobalContext* globalCtx, Actor* actor); -// void func_80122F9C(void); -// void func_80122FCC(void); -// void func_8012300C(void); +void func_80122F28(Player* player); +s32 func_80122F9C(GlobalContext* globalCtx); +s32 func_80122FCC(GlobalContext* globalCtx); +void func_8012300C(GlobalContext* globalCtx, s32 arg1); void func_8012301C(s32 iParm1, GlobalContext* globalCtx); -void func_80123140(GlobalContext* globalCtx, Player* param_2); +void func_80123140(GlobalContext* globalCtx, Player* player); u32 func_80123358(GlobalContext* globalCtx, Player* player); -u32 func_801233E4(GlobalContext* globalCtx); +s32 Player_InCsMode(GameState* gameState); // void func_80123420(void); // void func_80123434(void); // void func_80123448(void); @@ -2228,34 +2004,34 @@ 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); +void Player_SetEquipmentData(GlobalContext* globalCtx, Player* this); void func_80123D50(GlobalContext* globalCtx, Player* player, UNK_TYPE arg2, UNK_TYPE arg3); void func_80123DA4(Player* player); // void func_80123DC0(void); void func_80123E90(GlobalContext* globalCtx, Actor* actor); void func_80123F2C(GlobalContext* globalCtx, s32 arg1); -// void func_80123F48(void); -// void func_80124020(void); +s32 func_80123F48(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3); +s32 func_80124020(void); u8 Player_GetMask(GlobalContext* globalCtx); void Player_RemoveMask(GlobalContext* globalCtx); -s32 func_8012405C(GlobalContext* globalCtx); // Player_HoldsMirrorShield -// void func_80124088(void); +s32 func_8012405C(GlobalContext* globalCtx); +s32 func_80124088(GlobalContext* globalCtx); s32 func_801240C8(Player* player); // void func_801240DC(void); // void func_80124110(void); // void func_80124148(void); // void func_80124168(void); -// void func_80124190(void); +s32 func_80124190(Player* player); // void func_801241B4(void); // void func_801241E0(void); // void func_8012420C(void); // void func_8012422C(void); -// void func_80124258(void); +s32 Player_GetExplosiveHeld(Player* player); // void func_80124278(void); -// void func_801242B4(void); +s32 func_801242B4(Player* player); // void func_801242DC(void); // void func_80124420(void); // void func_80124618(void); @@ -2275,7 +2051,7 @@ s32 func_801240C8(Player* player); // void func_80125D4C(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_801262C8(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_801263FC(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_80126440(GlobalContext* globalCtx, Collider* param_2, s32* param_3, Vec3f* param_4, Vec3f* param_5); +s32 func_80126440(GlobalContext* globalCtx, ColliderQuad* collider, WeaponInfo* weaponInfo, Vec3f* arg3, Vec3f* arg4); // void func_801265C8(void); // void func_8012669C(void); // void func_80126808(void); @@ -2326,14 +2102,14 @@ void Quake_Init(void); s16 Quake_Add(Camera* camera, u32 callbackIdx); u32 Quake_RemoveFromIdx(s16 idx); s16 Quake_Calc(Camera* camera, QuakeCamCalc* camData); -void Quake2_Init(GlobalContext* globalCtx); -void Quake2_SetCountdown(s16 countdown); -s16 Quake2_GetCountdown(void); -s16 Quake2_GetType(void); -void Quake2_SetType(s32 type); -void Quake2_ClearType(s32 type); -s32 Quake2_GetFloorQuake(Player* player); -void Quake2_Update(void); +void Distortion_Init(GlobalContext* globalCtx); +void Distortion_SetCountdown(s16 countdown); +s16 Distortion_GetCountdown(void); +s16 Distortion_GetType(void); +void Distortion_SetType(s32 type); +void Distortion_ClearType(s32 type); +s32 Distortion_GetUnderwaterCurrentSpeed(Player* player); +void Distortion_Update(void); s32 Quake_NumActiveQuakes(void); Gfx* Gfx_SetFog(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 n, s32 f); Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 n, s32 f); @@ -2412,7 +2188,7 @@ Gfx* Gfx_TwoTexScroll(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 wi Gfx* Gfx_TwoTexScrollEnvColor(GraphicsContext* gfxCtx, s32 tile1, u32 x1, u32 y1, s32 width1, s32 height1, s32 tile2, u32 x2, u32 y2, s32 width2, s32 height2, s32 r, s32 g, s32 b, s32 a); Gfx* Gfx_EnvColor(GraphicsContext* gfxCtx, s32 r, s32 g, s32 b, s32 a); Gfx* Gfx_PrimColor(GraphicsContext* gfxCtx, s32 lodfrac, s32 r, s32 g, s32 b, s32 a); -void func_8012CF0C(GraphicsContext* gfxCtx, s32 iParm2, s32 iParm3, u8 r, u8 g, u8 b); +void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g, u8 b); void func_8012D374(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b); void func_8012D40C(f32* param_1, f32* param_2, s16* param_3); void Room_nop8012D510(GlobalContext* globalCtx, Room* room, UNK_PTR param_3, UNK_TYPE1 param_4); @@ -2429,16 +2205,16 @@ s32 Room_StartRoomTransition(GlobalContext* globalCtx, RoomContext* roomCtx, s32 s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx); void Room_Draw(GlobalContext* globalCtx, Room* room, u32 flags); void func_8012EBF8(GlobalContext* globalCtx, RoomContext* roomCtx); -s32 func_8012EC80(GlobalContext* globalCtx); -void func_8012ED34(s16 equipment); -u8 func_8012ED78(GlobalContext* globalCtx, s16 equipment); -void func_8012EDE8(s16 arg0, u32 arg1); -s32 func_8012EE34(s16 arg0); -void func_8012EF0C(s16 arg0); -void func_8012F0EC(s16 arg0); -void func_8012F1BC(s16 sceneIndex); -s16 func_8012F22C(s16 sceneIndex); -void func_8012F278(GlobalContext* globalCtx); +s32 Inventory_GetBtnBItem(GlobalContext* globalCtx); +void Inventory_ChangeEquipment(s16 value); +u8 Inventory_DeleteEquipment(GlobalContext* globalCtx, s16 equipment); +void Inventory_ChangeUpgrade(s16 upgrade, u32 value); +s32 Inventory_IsMapVisible(s16 sceneNum); +void Inventory_SetMapVisibility(s16 tingleIndex); +void Inventory_SaveDekuPlaygroundHighScore(s16 timerId); +void Inventory_IncrementSkullTokenCount(s16 sceneIndex); +s16 Inventory_GetSkullTokenCount(s16 sceneIndex); +void Inventory_SaveLotteryCodeGuess(GlobalContext* globalCtx); s32 Object_Spawn(ObjectContext* objectCtx, s16 id); void Object_InitBank(GameState* gameState, ObjectContext* objectCtx); void Object_UpdateBank(ObjectContext* objectCtx); @@ -2461,7 +2237,7 @@ void Scene_HeaderCmdPathList(GlobalContext* globalCtx, SceneCmd* cmd); void Scene_HeaderCmdTransiActorList(GlobalContext* globalCtx, SceneCmd* cmd); void Door_InitContext(GameState* gameState, DoorContext* doorCtx); void Scene_HeaderCmdEnvLightSettings(GlobalContext* globalCtx, SceneCmd* cmd); -s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex); +void Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex); void Scene_HeaderCmdSkyboxSettings(GlobalContext* globalCtx, SceneCmd* cmd); void Scene_HeaderCmdSkyboxDisables(GlobalContext* globalCtx, SceneCmd* cmd); void Scene_HeaderCmdTimeSettings(GlobalContext* globalCtx, SceneCmd* cmd); @@ -2523,59 +2299,25 @@ s32 Entrance_GetSceneNum(u16 entranceIndex); s32 Entrance_GetSceneNumAbsolute(u16 entranceIndex); s32 Entrance_GetSpawnNum(u16 entranceIndex); s32 Entrance_GetTransitionFlags(u16 entranceIndex); -// void func_801323D0(void); -// void func_80132428(void); -// void func_80132494(void); -// void func_801326B8(void); -// void func_801328F0(void); -// void func_80132920(void); -// void func_80132938(void); -// void func_80132954(void); -// void func_8013296C(void); -// void func_80132A18(void); -// void func_80132A3C(void); -// void func_80132A80(void); -// void func_80132AD8(void); -// void func_80132B24(void); -// void func_80132B84(void); -// void func_80132D70(void); -// void func_80132E9C(void); -// void func_80132FDC(void); -// void func_80133000(void); -UNK_TYPE func_80133038(GlobalContext* globalCtx, UNK_TYPE* arg1, struct_80133038_arg2* arg2); +s32 Schedule_RunScript(GlobalContext* globalCtx, u8* script, ScheduleResult* result); void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor, s32 lod); void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor, s32 lod); void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, Actor* actor, s32 lod, Mtx** mtx); -void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, Actor* actor, - s32 lod); -void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); -void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); -void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor, - Mtx** limbMatricies); -void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); -void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDraw unkDraw, Actor* actor, - Mtx** mtx); -void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDraw unkDraw, Actor* actor); -void SkelAnime_GetFrameData(AnimationHeader* animationSeg, s32 currentFrame, s32 limbCount, Vec3s* dst); +void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawFlex overrideLimbDraw, PostLimbDrawFlex postLimbDraw, Actor* actor, s32 lod); +void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); +void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); +void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor, Mtx** limbMatricies); +void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, Actor* actor); +void SkelAnime_DrawTransformFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor, Mtx** mtx); +void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor); +void SkelAnime_GetFrameData(AnimationHeader* animation, s32 currentFrame, s32 limbCount, Vec3s* dst); s16 Animation_GetLength(void* animation); s16 Animation_GetLastFrame(void* animation); -Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); -Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, - OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); -Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, - Mtx** mtx, Gfx* gfx); -Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); -s16 SkelAnime_GetFrameData2(LegacyAnimationHeader* animation, s32 frame, Vec3s* frameTable); +Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); +Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); +Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx); +Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, Actor* actor, Gfx* gfx); +s16 SkelAnime_GetFrameDataLegacy(LegacyAnimationHeader* animation, s32 frame, Vec3s* frameTable); s16 Animation_GetLimbCount2(LegacyAnimationHeader* animation); s16 Animation_GetLength2(LegacyAnimationHeader* animation); s16 Animation_GetLastFrame2(LegacyAnimationHeader* animation); @@ -2584,10 +2326,9 @@ void AnimationContext_Reset(AnimationContext* animationCtx); void AnimationContext_SetNextQueue(GlobalContext* globalCtx); void AnimationContext_DisableQueue(GlobalContext* globalCtx); AnimationEntry* AnimationContext_AddEntry(AnimationContext* animationCtx, AnimationType type); -void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader* animation, s32 frame, - s32 limbCount, Vec3s* frameTable); +void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader* animation, s32 frame, s32 limbCount, Vec3s* frameTable); void AnimationContext_SetCopyAll(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src); -void AnimationContext_SetInterp(GlobalContext* globalCtx, s32 limbCount, Vec3s* arg2, Vec3s* arg3, f32 arg4); +void AnimationContext_SetInterp(GlobalContext* globalCtx, s32 vecCount, Vec3s* base, Vec3s* mod, f32 weight); void AnimationContext_SetCopyTrue(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index); void AnimationContext_SetCopyFalse(GlobalContext* globalCtx, s32 vecCount, Vec3s* dst, Vec3s* src, u8* index); void AnimationContext_SetMoveActor(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3); @@ -2598,35 +2339,32 @@ void AnimationContext_CopyTrue(GlobalContext* globalCtx, AnimationEntryData* dat void AnimationContext_CopyFalse(GlobalContext* globalCtx, AnimationEntryData* data); void AnimationContext_MoveActor(GlobalContext* globalCtx, AnimationEntryData* data); void AnimationContext_Update(GlobalContext* globalCtx, AnimationContext* animationCtx); -void SkelAnime_InitLink(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, - LinkAnimationHeader* animation, s32 flags, Vec3s* jointTable, - Vec3s* morphTable, s32 limbBufCount); +void SkelAnime_InitLink(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, LinkAnimationHeader* animation, s32 flags, Vec3s* jointTable, Vec3s* morphTable, s32 limbBufCount); void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime); s32 LinkAnimation_Update(GlobalContext* globalCtx, SkelAnime* skelAnime); s32 LinkAnimation_Morph(GlobalContext* globalCtx, SkelAnime* skelAnime); void LinkAnimation_AnimateFrame(GlobalContext* globalCtx, SkelAnime* skelAnime); s32 LinkAnimation_Loop(GlobalContext* globalCtx, SkelAnime* skelAnime); s32 LinkAnimation_Once(GlobalContext* globalCtx, SkelAnime* skelAnime); -void Animation_SetMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 transitionRate); -void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate); -void LinkAnimation_PlayOnce(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg); -void LinkAnimation_PlayOnceSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 playbackSpeed); -void LinkAnimation_PlayLoop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg); -void LinkAnimation_PlayLoopSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 playbackSpeed); +void Animation_SetMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 morphFrames); +void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames); +void LinkAnimation_PlayOnce(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation); +void LinkAnimation_PlayOnceSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 playSpeed); +void LinkAnimation_PlayLoop(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation); +void LinkAnimation_PlayLoopSetSpeed(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 playSpeed); void LinkAnimation_CopyJointToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime); void LinkAnimation_CopyMorphToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime); -void LinkAnimation_LoadToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 frame); -void LinkAnimation_LoadToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 frame); +void LinkAnimation_LoadToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 frame); +void LinkAnimation_LoadToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 frame); void LinkAnimation_InterpJointMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, f32 frame); -void LinkAnimation_BlendToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 transitionFrame, LinkAnimationHeader* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, Vec3s* jointTable); -void LinkAnimation_BlendToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, f32 transitionFrame, LinkAnimationHeader* linkAnimetionEntrySeg2, f32 frame, f32 transitionRate, Vec3s* jointTable); +void LinkAnimation_BlendToJoint(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation1, f32 frame1, LinkAnimationHeader* animation2, f32 frame2, f32 blendWeight, Vec3s* blendTable); +void LinkAnimation_BlendToMorph(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation1, f32 frame1, LinkAnimationHeader* animation2, f32 frame2, f32 blendWeight, Vec3s* blendTable); void LinkAnimation_EndLoop(SkelAnime* skelAnime); -s32 Animation_OnFrameImpl(SkelAnime* skelAnime, f32 arg1, f32 updateRate); -s32 LinkAnimation_OnFrame(SkelAnime* skelAnime, f32 arg1); -void SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animationSeg, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); -void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, - AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); -void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animationSeg); +s32 Animation_OnFrameImpl(SkelAnime* skelAnime, f32 frame, f32 updateRate); +s32 LinkAnimation_OnFrame(SkelAnime* skelAnime, f32 frame); +void SkelAnime_Init(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); +void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); +void SkelAnime_InitSkin(GameState* gameState, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animationSeg); void SkelAnime_SetUpdate(SkelAnime* skelAnime); s32 SkelAnime_Update(SkelAnime* skelAnime); s32 SkelAnime_Morph(SkelAnime* skelAnime); @@ -2635,39 +2373,22 @@ void SkelAnime_AnimateFrame(SkelAnime* skelAnime); s32 SkelAnime_LoopFull(SkelAnime* skelAnime); s32 SkelAnime_LoopPartial(SkelAnime* skelAnime); s32 SkelAnime_Once(SkelAnime* skelAnime); -void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationType, f32 transitionRate, s8 unk2); -void Animation_Change(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed, f32 frame, f32 frameCount, u8 mode, f32 transitionRate); -void Animation_PlayOnce(SkelAnime* skelAnime, AnimationHeader* animationSeg); -void Animation_MorphToPlayOnce(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate); -void Animation_PlayOnceSetSpeed(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed); -void Animation_PlayLoop(SkelAnime* skelAnime, AnimationHeader* animationSeg); -void Animation_MorphToLoop(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 transitionRate); -void Animation_PlayLoopSetSpeed(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 playbackSpeed); +void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames, s8 taper); +void Animation_Change(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed, f32 startFrame, f32 endFrame, u8 mode, f32 morphFrames); +void Animation_PlayOnce(SkelAnime* skelAnime, AnimationHeader* animation); +void Animation_MorphToPlayOnce(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames); +void Animation_PlayOnceSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed); +void Animation_PlayLoop(SkelAnime* skelAnime, AnimationHeader* animation); +void Animation_MorphToLoop(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames); +void Animation_PlayLoopSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed); void Animation_EndLoop(SkelAnime* skelAnime); void Animation_Reverse(SkelAnime* skelAnime); -void SkelAnime_CopyFrameTableTrue(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* index); -void SkelAnime_CopyFrameTableFalse(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* arg3); +void SkelAnime_CopyFrameTableTrue(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* copyFlag); +void SkelAnime_CopyFrameTableFalse(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src, u8* copyFlag); void SkelAnime_UpdateTranslation(SkelAnime* skelAnime, Vec3f* pos, s16 angle); -s32 Animation_OnFrame(SkelAnime* skelAnime, f32 arg1); +s32 Animation_OnFrame(SkelAnime* skelAnime, f32 frame); void SkelAnime_Free(SkelAnime* skelAnime, GlobalContext* globalCtx); void SkelAnime_CopyFrameTable(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src); -// void func_80137970(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80137B34(void); -// void func_80137EBC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80137F58(void); -// void func_80138050(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_80138228(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80138258(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_8013828C(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_801382C4(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_80138300(void); -// void func_8013835C(void); -// void func_80138410(void); -// void func_80138424(void); -// void func_8013859C(void); -// void func_80138700(void); -// void func_801387D4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); -// void func_801388E4(void); void SkinMatrix_Vec3fMtxFMultXYZW(MtxF* mf, Vec3f* src, Vec3f* xyzDest, f32* wDest); void SkinMatrix_Vec3fMtxFMultXYZ(MtxF* mf, Vec3f* src, Vec3f* dest); void SkinMatrix_MtxFMtxFMult(MtxF* mfB, MtxF* mfA, MtxF* dest); @@ -2692,72 +2413,74 @@ void SkinMatrix_MulXRotation(MtxF* mf, s16 a); void SkinMatrix_SetYRotation(MtxF* mf, s16 a); void SkinMatrix_MulYRotation(MtxF* mf, s16 a); void SkinMatrix_SetZRotation(MtxF* mf, s16 a); + s32 func_8013A240(GlobalContext* globalCtx); void func_8013A41C(s32 flag); 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); -// void func_8013A7C0(void); -// void func_8013A860(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); -Gfx* func_8013AB00(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, void* func1, void* func2, void* func3, Actor* actor, Gfx* gfx); -s32 func_8013AD6C(GlobalContext* globalCtx); -// void func_8013AD9C(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_8013AED4(u16* param_1, u16 param_2, u16 param_3); -void func_8013AF00(UNK_PTR arg0, UNK_TYPE arg1, UNK_TYPE arg2); -// void func_8013B010(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_8013B0C8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8013B350(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); -s32 func_8013B6B0(Path* path, UNK_PTR arg1, s32* arg2, s32 arg3, s32 arg4, s32* arg5, UNK_PTR arg6, Vec3f* arg7, s16 arg8); +struct EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 switchFlag); +Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx); +Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx); +s32 SubS_InCsMode(GlobalContext* globalCtx); +s32 SubS_UpdateLimb(s16 newRotZ, s16 newRotY, Vec3f* pos, Vec3s* rot, s32 stepRot, s32 overrideRot); +void SubS_UpdateFlags(u16* flags, u16 setBits, u16 unsetBits); +void func_8013AF00(f32* arg0, s32 arg1, s32 arg2); +s32 func_8013B010(f32* arg0, s32 arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, f32* arg6); +void func_8013B0C8(s32 arg0, f32 arg1, s32 arg2, f32* arg3, f32* arg4); +void func_8013B350(Vec3f* arg0, f32* arg1, f32 arg2, s32 arg3, s32 arg4, Vec3s* arg5, f32* arg6); +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, s32 actorCategory, s32 actorId); -s32 func_8013BC6C(SkelAnime* skelAnime, ActorAnimationEntryS* arg1, s32 arg2); -// void func_8013BD40(void); -s32 func_8013BEDC(GlobalContext* globalCtx, s32 arg1, s32 arg2, s32* arg3); -// void func_8013C068(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8013C624(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_8013C8B8(void); -void func_8013C964(Actor* actor, GlobalContext* globalCtx, f32 param_3, f32 param_4, s32 param_5, s16 param_6); -// void func_8013CC2C(void); -// void func_8013CD64(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -// void func_8013CF04(void); -// void func_8013D0E0(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_8013D2E0(Vec3f* arg0, PosRot* arg1, ActorShape* arg2, s16* arg3, s16* arg4, s16* arg5, s16* arg6); -UNK_TYPE func_8013D5E8(s16 arg0, UNK_TYPE arg1, s16 arg2); -Path* func_8013D648(GlobalContext* globalCtx, s16 arg1, s32 arg2); -UNK_TYPE func_8013D68C(Path* path, s16 arg1, UNK_PTR arg2); -// void func_8013D720(void); -UNK_TYPE func_8013D768(Actor* actor, UNK_PTR arg1, s16 arg2); -// void func_8013D83C(void); -s32 func_8013D8DC(s8 arg0, GlobalContext* globalCtx); -s8 func_8013D924(s32 arg0, GlobalContext* globalCtx); -Actor* func_ActorCategoryIterateById(GlobalContext* globalCtx, Actor* actorListStart, s32 actorCategory, s32 actorId); -void func_8013D9C8(GlobalContext* globalCtx, s16* arg1, s16* arg2, UNK_TYPE arg3); -u8 func_8013DB90(GlobalContext* globalCtx, UNK_PTR arg1, f32 arg2); -// void func_8013DC40(void); -void func_8013DCE0(GlobalContext* globalCtx, Vec3f* param_2, Actor* actor, EnDno_ActorUnkStruct* param_4, Path* param_5, s32 param_6, s32 param_7, s32 param_8, s32 param_9, s32 param_10); -void func_8013DE04(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1, EnDno_ActorUnkFunc arg2, EnDno_ActorUnkFunc arg3, EnDno_ActorUnkFunc arg4, EnDno_ActorUnkFunc arg5); -s32 func_8013DF3C(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1); -// void func_8013E054(void); -// void func_8013E07C(void); -s32 func_8013E0A4(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1); -void func_8013E1C8(SkelAnime* skelAnime, struct_80B8E1A8 animations[], s32 animationIndex, s32* actorAnimationIndex); -s32 func_8013E2D4(Actor* actor, s16 arg1, s32 arg2, s32 arg3); -s32 func_8013E3B8(Actor* actor, s16 cutscenes[], s32 cutsceneArrayLen); -// void func_8013E4B0(void); -s32 func_8013E5CC(Vec3f* param_1, Vec3s* param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, Vec3f* param_6); -// void func_8013E640(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); -// void func_8013E748(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_8013E7C0(void); -// void func_8013E8F8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); -s32 func_8013E950(Vec3f* param_1, Vec3f* param_2, s16 param_3, Vec3f* param_4, Vec3f* param_5, s16* param_6, s16* param_7, s16* param_8, s16* param_9, u16 param_10, u16 param_11, u16 param_12, u16 param_13); +Path* SubS_GetAdditionalPath(GlobalContext* globalCtx, u8 pathIndex, s32 max); +Actor* SubS_FindNearestActor(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId); +s32 SubS_ChangeAnimationByInfoS(SkelAnime* skelAnime, AnimationInfoS* animations, s32 index); +s32 SubS_HasReachedPoint(Actor* actor, Path* path, s32 pointIndex); +Path* SubS_GetDayDependentPath(GlobalContext* globalCtx, u8 pathIndex, u8 max, s32* startPointIndex); +s32 func_8013C068(Path* path, s32 arg1, Vec3f* arg2, f32 arg3, s32 arg4); +s32 func_8013C624(Actor* actor, Path* path, s32* arg2, f32* arg3, s32 arg4, s32 arg5); +s32 SubS_CopyPointFromPathCheckBounds(Path* path, s32 pointIndex, Vec3f* dst); +s32 func_8013C964(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 itemId, s32 type); +void SubS_FillShadowTex(s32 startCol, s32 startRow, u8* tex, s32 size); +void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween, u8 bodyPartsNum, u8 sizes[], s8 parentBodyParts[]); +void SubS_DrawShadowTex(Actor* actor, GameState* gameState, u8* tex); +s16 SubS_ComputeTurnToPointRot(s16* rot, s16 rotMax, s16 target, f32 slowness, f32 stepMin, f32 stepMax); +s32 SubS_TurnToPoint(Vec3f* point, Vec3f* focusPos, Vec3s* shapeRot, Vec3s* turnTarget, Vec3s* headRot, Vec3s* torsoRot, TurnOptionsSet* options); +s32 SubS_AngleDiffLessEqual(s16 angleA, s16 threshold, s16 angleB); +Path* SubS_GetPathByIndex(GlobalContext* globalCtx, s16 pathIndex, s16 max); +s32 SubS_CopyPointFromPath(Path* path, s32 pointIndex, Vec3f* dst); +s16 SubS_GetDistSqAndOrientPoints(Vec3f* vecA, Vec3f* vecB, f32* distSq); +s32 SubS_MoveActorToPoint(Actor* actor, Vec3f* point, s16 rotStep); +s16 SubS_GetDistSqAndOrientPath(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq); +s8 SubS_IsObjectLoaded(s8 index, GlobalContext* globalCtx); +s8 SubS_GetObjectIndex(s16 id, GlobalContext* globalCtx); +Actor* SubS_FindActor(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId); +s32 SubS_FillLimbRotTables(GlobalContext* globalCtx, s16* limbRotTableY, s16* limbRotTableZ, s32 numLimbs); +s32 SubS_IsFloorAbove(GlobalContext* globalCtx, Vec3f* pos, f32 distAbove); +s32 SubS_CopyPointFromPathList(Path* paths, s32 pathIndex, s32 pointIndex, Vec3f* dst); +u8 SubS_GetPathCount(Path* paths, s32 index); +void SubS_ActorPathing_Init(GlobalContext* globalCtx, Vec3f* worldPos, Actor* actor, ActorPathing* actorPath, Path* paths, s32 pathIndex, s32 begPointIndex, s32 endPointIndex, s32 curPointIndex, u8 flags); +s32 SubS_ActorPathing_Update(GlobalContext* globalCtx, ActorPathing* actorPath, ActorPathingComputeFunc computePointInfoFunc, ActorPathingUpdateFunc updateActorInfoFunc, ActorPathingUpdateFunc moveFunc, ActorPathingUpdateFunc setNextPointFunc); +void SubS_ActorPathing_ComputePointInfo(GlobalContext* globalCtx, ActorPathing* actorPath); +s32 SubS_ActorPathing_MoveWithGravity(GlobalContext* globalCtx, ActorPathing* actorPath); +s32 SubS_ActorPathing_MoveWithoutGravityReverse(GlobalContext* globalCtx, ActorPathing* actorPath); +s32 SubS_ActorPathing_SetNextPoint(GlobalContext* globalCtx, ActorPathing* actorPath); +void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* animations, s32 nextIndex, s32* curIndex); +s32 SubS_StartActorCutscene(Actor* actor, s16 nextCutscene, s16 curCutscene, s32 type); +s32 SubS_FillCutscenesList(Actor* actor, s16 cutscenes[], s16 numCutscenes); +void SubS_ConstructPlane(Vec3f* point, Vec3f* unitVec, Vec3s* rot, Plane* plane); +s32 SubS_LineSegVsPlane(Vec3f* point, Vec3s* rot, Vec3f* unitVec, Vec3f* linePointA, Vec3f* linePointB, Vec3f* intersect); +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 xzRange, f32 yRange, s32 exchangeItemId, void* data, func_8013E748_VerifyFunc verifyFunc); +s32 SubS_ActorAndPlayerFaceEachOther(GlobalContext* globalCtx, Actor* actor, void* data); +s32 func_8013E8F8(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exhangeItemId, s16 playerYawTol, s16 actorYawTol); +s32 SubS_TurnToPointStep(Vec3f* worldPos, Vec3f* focusPos, s16 shapeYRot, Vec3f* yawTarget, Vec3f* pitchTarget, s16* headZRotStep, s16* headXRotStep, s16* torsoZRotStep, s16* torsoXRotStep, u16 headZRotStepMax, u16 headXRotStepMax, u16 torsoZRotStepMax, u16 torsoXRotStepMax); // void func_8013EC10(void); -// void func_8013EC44(void); +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); @@ -2776,13 +2499,13 @@ void View_GetViewport(View* view, Viewport* viewport); void View_WriteScissor(Gfx** gfx, s32 ulx, s32 uly, s32 lrx, s32 lry); void View_SyncAndWriteScissor(View* view, Gfx** gfx); void View_SetScissorForLetterbox(View* view); -s32 View_SetQuakeRotation(View* view, f32 x, f32 y, f32 z); -s32 View_SetQuakeScale(View* view, f32 x, f32 y, f32 z); -s32 View_SetQuakeSpeed(View* view, f32 speed); -s32 View_InitCameraQuake(View* view); -s32 View_ClearQuake(View* view); -s32 View_SetQuake(View* view, Vec3f rot, Vec3f scale, f32 speed); -s32 View_StepQuake(View* view, Mtx* matrix); +s32 View_SetDistortionDirRot(View* view, f32 dirRotX, f32 dirRotY, f32 dirRotZ); +s32 View_SetDistortionScale(View* view, f32 scaleX, f32 scaleY, f32 scaleZ); +s32 View_SetDistortionSpeed(View* view, f32 speed); +s32 View_InitDistortion(View* view); +s32 View_ClearDistortion(View* view); +s32 View_SetDistortion(View* view, Vec3f dirRot, Vec3f scale, f32 speed); +s32 View_StepDistortion(View* view, Mtx* projectionMtx); void View_RenderView(View* view, s32 uParm2); s32 View_RenderToPerspectiveMatrix(View* view); s32 View_RenderToOrthographicMatrix(View* view); @@ -2820,55 +2543,22 @@ void VisMono_Draw(void* arg0, Gfx** gfx, u32 arg2); 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 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); 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); -void func_80143A10(u8 owlId); -// void func_80143A54(void); -void func_80143AC4(void); -void func_80143B0C(GlobalContext* globalCtx); -void Sram_IncrementDay(void); -u32 Sram_CalcChecksum(u8* data, u32 length); -// void func_80144628(void); -// void Sram_GenerateRandomSaveFields(void); -void func_80144890(void); -void Sram_InitDebugSave(void); -// void func_80144A94(void); -// void func_80144E78(void); -// void func_8014546C(void); -// void func_80145698(void); -void func_801457CC(GameState* gameState, SramContext* param_2); -void func_80146580(s32 param_1, SramContext* param_2, s32 param_3); -// void func_80146628(void); -// void func_80146AA0(void); -// void func_80146DF8(void); -void func_80146E40(GameState* gameState, SramContext* sramCtx); -void Sram_Alloc(GameState* gameState, SramContext* sramCtx); -// void func_80146EBC(SramContext* param_1, UNK_TYPE4 param_2, UNK_TYPE4 param_3); -// void func_80146EE8(void); -// void func_80146F5C(void); -// void func_80147008(void); -void func_80147020(SramContext* param_1); -void func_80147068(SramContext* param_1); -// void func_80147138(SramContext* param_1, UNK_TYPE4 param_2, UNK_TYPE4 param_3); -void func_80147150(SramContext* param_1); -void func_80147198(SramContext* param_1); -// void func_80147314(void); -// void func_80147414(void); -// void Sram_nop8014750C(UNK_TYPE4 param_1); +void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); +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_80147520(void); void func_80147564(GlobalContext* globalCtx); -u32 func_80147624(GlobalContext* globalCtx); -u32 func_80147734(GlobalContext* globalCtx); +s32 Message_ShouldAdvance(GlobalContext* globalCtx); +s32 Message_ShouldAdvanceSilent(GlobalContext* globalCtx); void func_801477B4(GlobalContext* globalCtx); -// void func_80147818(GlobalContext* globalCtx, UNK_PTR puParm2, UNK_TYPE4 uParm3, UNK_TYPE4 uParm4); +void func_80147818(GlobalContext* globalCtx, UNK_PTR puParm2, UNK_TYPE4 uParm3, UNK_TYPE4 uParm4); // void func_80147F18(GlobalContext* globalCtx, UNK_PTR puParm2, UNK_TYPE4 uParm3, UNK_TYPE4 uParm4); // void func_80148558(GlobalContext* globalCtx, UNK_PTR puParm2, UNK_TYPE4 uParm3, UNK_TYPE4 uParm4); void func_80148B98(GlobalContext* globalCtx, u8 bParm2); @@ -2879,31 +2569,31 @@ void func_80148B98(GlobalContext* globalCtx, u8 bParm2); // void func_80149454(void); // void func_801496C8(void); // void func_8014995C(void); -// void func_80149C18(void); -// void func_80149EBC(void); +void func_80149C18(GlobalContext* globalCtx); +// void Message_FindMessage(void); void func_80149F74(GlobalContext* globalCtx, u32** ppuParm2); // void func_8014AAD0(void); void func_8014ADBC(GlobalContext* globalCtx, UNK_PTR puParm2); // void func_8014C70C(void); -// void func_8014CC14(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); +void Message_LoadChar(GlobalContext* globalCtx, u16 codePointIndex, s32* offset, f32* arg3, s16 arg4); // void func_8014CCB4(void); // void func_8014CDF0(void); // void func_8014CFDC(void); -// void func_8014D304(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); +void func_8014D304(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_8014D62C(void); // void func_8014D7B4(void); -// void func_80150A84(void); +void func_80150A84(GlobalContext* globalCtx); void func_80150D08(GlobalContext* globalCtx, u32 uParm2); // void func_801514B0(void); -void func_801518B0(GlobalContext* globalCtx, u16 textId, Actor* Actor); +void Message_StartTextbox(GlobalContext* globalCtx, u16 textId, Actor* Actor); void func_80151938(GlobalContext* globalCtx, u16 textId); void func_80151A68(GlobalContext* globalCtx, u16 textId); -void func_80151BB4(GlobalContext* globalCtx, u32 uParm2); +void func_80151BB4(GlobalContext* globalCtx, u8 uParm2); // void func_80151C9C(void); -// void func_80151DA4(void); +void func_80151DA4(GlobalContext* globalCtx, u16 arg2); void func_80152434(GlobalContext* globalCtx, u16 arg2); // void func_80152464(void); -u8 func_80152498(MessageContext* msgCtx); +u8 Message_GetState(MessageContext* msgCtx); // void func_8015268C(void); // void func_80152C64(void); // void func_80152CAC(void); @@ -2912,30 +2602,26 @@ u8 func_80152498(MessageContext* msgCtx); // void func_80153750(void); // void func_80153E7C(void); // void func_80153EF0(void); -// void func_801541D4(void); +void func_801541D4(GlobalContext* globalCtx, Gfx** gfxp); // void func_80156758(void); void func_8015680C(GlobalContext* globalCtx); void func_801586A4(GlobalContext* globalCtx); void Message_Init(GlobalContext* globalCtx); -void func_801588D0(GlobalContext* globalCtx, s16 param_2); -// void func_80158988(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); -// void func_80158A24(void); -// void func_80158C04(void); -// void func_80158D98(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); -// void func_80158FB0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8015926C(void); +void Message_FindMessageNES(GlobalContext* globalCtx, u16 textId); +// void Message_LoadCharNES(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); +// void Message_LoadPluralRupeesNES(void); +// void Message_LoadLocalizedRupeesNES(void); +// void Message_LoadRupeesNES(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); +// void Message_LoadTimeNES(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); +// void Message_LoadAreaTextNES(void); // void func_80159438(void); -// void func_8015966C(void); +void func_8015966C(GlobalContext* globalCtx, UNK_PTR puParm2, UNK_TYPE arg3); // void func_8015A144(void); -// void func_8015B198(void); -// void func_8015E750(void); +void func_8015B198(GlobalContext* globalCtx); +void Message_FindCreditsMessage(GlobalContext *globalCtx, u16 textId); void func_8015E7EC(GlobalContext* globalCtx, UNK_PTR puParm2); // void func_8015F8A8(UNK_TYPE4 ctxt); -// void func_80160A90(void); -// void func_80160AF8(void); -// void func_80160B40(void); -// void func_80160B80(void); -// void func_80160BC0(void); + void ShrinkWindow_SetLetterboxTarget(s32 target); s32 ShrinkWindow_GetLetterboxTarget(void); void ShrinkWindow_SetLetterboxMagnitude(s32 magnitude); @@ -2949,13 +2635,13 @@ void ShrinkWindow_Destroy(void); void ShrinkWindow_Update(s32 framerateDivisor); void ShrinkWindow_Draw(GraphicsContext* gfxCtx); // void func_80161180(void); -// void func_8016119C(void); +s32 func_8016119C(Camera* camera, DbCameraUnkStruct* arg1); // void func_8016122C(void); // void func_801612B8(void); -// void func_80161998(void); +s32 func_80161998(u8* cmd, DbCameraUnkStruct* arg1); // s32 func_80161BAC(void); -// void func_80161BE0(void); -// void func_80161C0C(void); +void func_80161BE0(s16 arg0); +void func_80161C0C(void); // void func_80161C20(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_80161E4C(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_801620CC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); @@ -2969,17 +2655,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); @@ -3005,7 +2691,7 @@ void* TransitionFade_Init(void* param_1); // void TransitionCircle_Update(void); // void TransitionCircle_SetColor(void); // void TransitionCircle_SetType(void); -// void func_80164C14(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_80164C14(Gfx** arg0, TexturePtr* arg1, s32 arg2, s32 arg3, s32 arg4, s32 arg5, f32 arg6); // void TransitionCircle_Draw(void); // void TransitionCircle_IsDone(void); // void func_801651B0(void); @@ -3017,8 +2703,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(s16); +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); @@ -3037,48 +2723,46 @@ 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); -// void func_80169100(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); +s32 Play_InCsMode(GlobalContext* globalCtx); +f32 func_80169100(GlobalContext* globalCtx, MtxF* mtx, CollisionPoly** arg2, s32* arg3, Vec3f* feetPosPtr); // void func_801691F0(void); void* Play_LoadScene(GlobalContext* globalCtx, RomFile* entry); void func_8016927C(GlobalContext* globalCtx, s16 sParm2); // void func_801692C4(GlobalContext* globalCtx, UNK_TYPE1 uParm2); // void Play_SceneInit(GlobalContext* globalCtx, s32 sceneIndex, UNK_TYPE1 param_3); UNK_RET func_80169474(GlobalContext* globalCtx, Vec3f* v1, Vec3f* v2); -s32 func_801694DC(GlobalContext* globalCtx); -s32 Play_GetActiveCameraIndex(GlobalContext* globalCtx); -void func_80169590(GlobalContext* globalCtx, s16 param_2, s16 param_3); -void func_80169600(GlobalContext* globalCtx, s16 param_2); -// void func_80169668(void); +s32 Play_CreateSubCamera(GlobalContext* globalCtx); +s32 Play_GetActiveCamId(GlobalContext* globalCtx); +void Play_CameraChangeStatus(GlobalContext* globalCtx, s16 camId, s16 status); +void Play_ClearCamera(GlobalContext* globalCtx, s16 camId); Camera* Play_GetCamera(GlobalContext* globalCtx, s16 index); s32 Play_CameraSetAtEye(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye); -// void func_8016981C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80169940(void); -// void func_80169988(void); -void func_801699D4(GlobalContext* globalCtx, s16 arg1, s16 arg2); +void Play_CameraSetAtEyeUp(GlobalContext* globalCtx, s16 camId, Vec3f* at, Vec3f* eye, Vec3f* up); +void Play_CameraSetFov(GlobalContext* globalCtx, s16 camId, f32 fov); +void Play_CameraSetRoll(GlobalContext* globalCtx, s16 camId, s16 roll); +void Play_CopyCamera(GlobalContext* globalCtx, s16 dstCamId, s16 srcCamId); // void func_80169A50(void); -// void func_80169AC0(void); +void Play_CameraChangeSetting(GlobalContext* globalCtx, s16 camId, s16 setting); void func_80169AFC(GlobalContext* globalCtx, s16 camId, s16 arg2); -// void func_80169C64(void); -// void func_80169C84(void); -// void convert_scene_number_among_shared_scenes(void); -void func_80169D40(GlobalContext* globalCtx); -void func_80169DCC(GlobalContext* globalCtx, s32 arg1, u16 arg2, s32 arg3, s32 arg4, Vec3f* arg5, s16 arg6); -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_80169FFC(void); -s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); -// UNK_TYPE4 func_8016A02C(s32 param_1, s32 param_2, s16* param_3); -// void func_8016A0AC(void); +s16 Play_GetCsCamDataSetting(GlobalContext* globalCtx, s32 camId); +Vec3s* Play_GetCsCamDataVec3s(GlobalContext* globalCtx, s32 camId); +s16 Play_GetOriginalSceneNumber(s16 sceneNum); +void Play_SaveCycleSceneFlags(GameState* gameState); +void Play_SetRespawnData(GameState* gameState, s32 respawnNumber, u16 sceneSetup, s32 roomIndex, s32 playerParams, Vec3f* pos, s16 yaw); +void Play_SetupRespawnPoint(GameState* gameState, s32 respawnNumber, s32 playerParams); +void func_80169EFC(GameState* gameState); +void func_80169F78(GameState* gameState); +void func_80169FDC(GameState* gameState); +s32 func_80169FFC(GameState* gameState); +s32 FrameAdvance_IsEnabled(GameState* gameState); +s32 func_8016A02C(GameState* gameState, Actor* actor, s16* yaw); +s32 Play_IsUnderwater(GlobalContext* globalCtx, Vec3f* pos); 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 Play_AssignPlayerActorCsIdsFromScene(GameState* gameState, s32 cutscene); +void func_8016A268(GameState* gameState, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5); 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); @@ -3119,8 +2803,7 @@ void PreRender_ApplyFiltersSlowlyInit(PreRender* this); void PreRender_ApplyFiltersSlowlyDestroy(PreRender* this); void func_801720C4(PreRender* this); void func_801720FC(PreRenderParams* params, Gfx** gfxp); -void func_80172758(Gfx** gfxp, void* timg, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tt, u16 arg8, f32 x, - f32 y, f32 xScale, f32 yScale, u32 flags); +void func_80172758(Gfx** gfxp, void* timg, void* tlut, u16 width, u16 height, u8 fmt, u8 siz, u16 tt, u16 arg8, f32 x, f32 y, f32 xScale, f32 yScale, u32 flags); void THGA_Ct(TwoHeadGfxArena* thga, Gfx* start, size_t size); void THGA_Dt(TwoHeadGfxArena* thga); u32 THGA_IsCrash(TwoHeadGfxArena* thga); @@ -3176,26 +2859,26 @@ void GameState_Realloc(GameState* gameState, size_t size); void GameState_Init(GameState* gameState, GameStateFunc gameStateInit, GraphicsContext* gfxCtx); void GameState_Destroy(GameState* gameState); GameStateFunc GameState_GetNextStateInit(GameState* gameState); -size_t Game_GetNextStateSize(GameState* gameState); +size_t GameState_GetNextStateSize(GameState* gameState); u32 GameState_IsRunning(GameState* gameState); s32 GameState_GetArenaSize(GameState* gameState); s32 func_80173B48(GameState* gameState); -void GameAlloc_Log(GameAlloc* heap); -void* GameAlloc_Malloc(GameAlloc* heap, size_t size); -void GameAlloc_Free(GameAlloc* heap, void* ptr); -void GameAlloc_Cleanup(GameAlloc* heap); -void GameAlloc_Init(GameAlloc* iParm1); -// void Graph_FaultClient(void); -void Graph_DlAlloc(TwoHeadGfxArena* dl, void* memoryBlock, size_t size); -void Graph_InitTHGA(GraphicsContext* gfxCtx); +void GameAlloc_Log(GameAlloc* this); +void* GameAlloc_Malloc(GameAlloc* this, size_t size); +void GameAlloc_Free(GameAlloc* this, void* data); +void GameAlloc_Cleanup(GameAlloc* this); +void GameAlloc_Init(GameAlloc* this); +void Graph_FaultClient(void); +void Graph_InitTHGA(TwoHeadGfxArena* arena, Gfx* buffer, s32 size); +void Graph_SetNextGfxPool(GraphicsContext* gfxCtx); GameStateOverlay* Graph_GetNextGameState(GameState* gameState); -void* Graph_FaultAddrConvFunc(void* addr); +void* Graph_FaultAddrConvFunc(void* address, void* param); void Graph_Init(GraphicsContext* gfxCtx); -// void Graph_Destroy(void); -void Graph_Render(GraphicsContext* gfxCtx, GameState* gameState); -void Graph_FrameSetup(GameState* gameState); -void Graph_RenderFrame(GraphicsContext* gfxCtx, GameState* gameState); -void Graph_DoFrame(GraphicsContext* gfxCtx, GameState* gameState); +void Graph_Destroy(GraphicsContext* gfxCtx); +void Graph_TaskSet00(GraphicsContext* gfxCtx, GameState* gameState); +void Graph_UpdateGame(GameState* gameState); +void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState); +void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState); void Graph_ThreadEntry(void* arg); Gfx* Graph_GfxPlusOne(Gfx* gfx); Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst); @@ -3259,7 +2942,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); @@ -3267,10 +2950,10 @@ void func_801780F0(Mtx* param_1, f32 param_2, f32 param_3, f32 param_4, f32 para // void func_8017842C(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, UNK_TYPE4 param_10, UNK_TYPE4 param_11); // void func_80178750(void); // void func_80178818(void); -// void func_80178978(void); +void func_80178978(void); // void func_801789D4(void); -u32* get_framebuffer(s32 index); -// u16* get_zbuffer(void); +u32 SysCfb_GetFbPtr(s32 index); +u32 SysCfb_GetZBuffer(void); // UNK_TYPE4 func_80178A24(void); // void func_80178A34(void); s32 func_80178A94(s32 param_1, s32 param_2); @@ -3280,10 +2963,10 @@ s32 func_80178A94(s32 param_1, s32 param_2); // void func_80178DAC(void); // void func_80178E3C(void); // void func_80178E7C(void); -void Check_WriteRGBA16Pixel(u16* buffer, u32 x, u32 y, u16 value); -void Check_WriteI4Pixel(u16* buffer, u32 x, u32 y, u32 value); -void Check_DrawI4Texture(u16* buffer, u32 x, u32 y, u32 width, u32 height, u8* texture); -void Check_ClearRGBA16(s16* buffer); +// void Check_WriteRGBA16Pixel(u16* buffer, u32 x, u32 y, u32 value); +// void Check_WriteI4Pixel(u16* buffer, u32 x, u32 y, u32 value); +// void Check_DrawI4Texture(u16* buffer, u32 x, u32 y, u32 width, u32 height, u8* texture); +// void Check_ClearRGBA16(u16* buffer); // void Check_DrawExpansionPakErrorMessage(void); // void Check_DrawRegionLockErrorMessage(void); void Check_ExpansionPak(void); @@ -3296,21 +2979,21 @@ f32 cos_rad(f32 rad); f32 Rand_ZeroFloat(f32 scale); f32 randPlusMinusPoint5Scaled(f32 scale); f32 Math3D_Normalize(Vec3f* vec); -// UNK_TYPE4 func_80179678(f32 fParm1, f32 fParm2, f32 fParm5, f32 param_4, f32 param_5, f32 param_6, f32 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10, UNK_TYPE4 param_11); -// UNK_TYPE4 func_80179798(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, Vec3f* param_6); +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); +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); // void func_80179D74(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 Math3D_ScaleAndAdd(Vec3f* a, Vec3f* b, f32 scale, Vec3f* dst); void Math3D_Lerp(Vec3f* a, Vec3f* b, f32 t, Vec3f* dst); -s32 Math3D_Parallel(Vec3f* a, Vec3f* b); +f32 Math3D_Parallel(Vec3f* a, Vec3f* b); s32 Math3D_AngleBetweenVectors(Vec3f* a, Vec3f* b, f32* angle); void func_80179F64(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); s32 Math3D_XZBoundCheck(f32 xMin, f32 xMax, f32 zMin, f32 zMax, f32 x, f32 z); // void func_8017A09C(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_8017A1D0(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_8017A304(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); +s32 func_8017A304(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 z, f32 x, f32 chkDist); // UNK_TYPE4 func_8017A438(Vec3f* pfParm1, Vec3f* pfParm2, Vec3f* pfParm3, Vec3f* pfParm4, f32 param_5); f32 Math3D_XZLengthSquared(f32 x, f32 z); f32 Math3D_XZLength(f32 x, f32 z); @@ -3318,65 +3001,65 @@ f32 Math3D_XZDistanceSquared(f32 x1, f32 x2, f32 z1, f32 z2); f32 Math3D_XZDistance(f32 x1, f32 x2, f32 z1, f32 z2); f32 Math3D_LengthSquared(Vec3f* vec); f32 Math3D_Vec3fMagnitude(Vec3f* vec); -f32 Math3D_DistanceSquared(Vec3f* a, Vec3f* b); +f32 Math3D_Vec3fDistSq(Vec3f* a, Vec3f* b); f32 Math3D_Distance(Vec3f* a, Vec3f* b); f32 Math3D_DistanceS(Vec3s* s, Vec3f* f); f32 func_8017A7B8(f32* param_1, f32* param_2, f32 param_3, f32 param_4); f32 func_8017A7F8(f32* param_1, f32* param_2, f32 param_3, f32 param_4); f32 func_8017A838(f32* param_1, f32* param_2, f32 param_3, f32 param_4); void Math3D_CrossProduct(Vec3f* a, Vec3f* b, Vec3f* res); -void Math3D_NormalVector(Vec3f* a, Vec3f* b, Vec3f* c, Vec3f* res); -u32 func_8017A954(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); -u32 func_8017AA0C(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); -u32 func_8017ABBC(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); -// void func_8017AD38(void); +void Math3D_SurfaceNorm(Vec3f* a, Vec3f* b, Vec3f* c, Vec3f* res); +u32 Math3D_PointRelativeToCubeFaces(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); +u32 Math3D_PointRelativeToCubeEdges(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); +u32 Math3D_PointRelativeToCubeVertices(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3); +s32 Math3D_LineVsCube(Vec3f* min, Vec3f* max, Vec3f* a, Vec3f* b); // void func_8017B68C(void); void func_8017B7F8(Vec3f* arg0, s16 arg1, f32* arg2, f32* arg3, f32* arg4); void Math3D_UnitNormalVector(Vec3f* a, Vec3f* b, Vec3f* c, f32* normX, f32* normY, f32* normZ, f32* param_7); f32 Math3D_SignedDistanceFromPlane(f32 normX, f32 normY, f32 normZ, f32 d, Vec3f* position); // void func_8017B9D8(void); -f32 Math3D_NormalizedDistanceFromPlane(f32 normX, f32 normY, f32 normZ, f32 d, Vec3f* position); -f32 Math3D_NormalizedSignedDistanceFromPlane(f32 normX, f32 normY, f32 normZ, f32 d, Vec3f* position); -// void func_8017BAD0(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); +f32 Math3D_UDistPlaneToPos(f32 normX, f32 normY, f32 normZ, f32 d, Vec3f* position); +f32 Math3D_DistPlaneToPos(f32 normX, f32 normY, f32 normZ, f32 d, Vec3f* position); +s32 Math3D_TriChkPointParaYDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 unk, f32 chkDist, f32 ny); // void func_8017BD98(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_8017BDE0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8017BE30(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, UNK_TYPE4 param_11); -// void func_8017BEE0(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, UNK_TYPE4 param_11); +s32 Math3D_TriChkPointParaYIntersectDist(Vec3f* a, Vec3f* b, Vec3f* c, f32 nx, f32 ny, f32 nz, f32 dist, f32 z, f32 x, f32* yIntersect, f32 chkDist); +s32 Math3D_TriChkPointParaYIntersectInsideTri(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 z, f32 x, f32* yIntersect, f32 chkDist); // void func_8017BF8C(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_8017C008(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, UNK_TYPE4 param_11, UNK_TYPE4 param_12); +s32 Math3D_TriChkLineSegParaYIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 z, f32 x, f32* yIntersect, f32 y0, f32 y1); // void func_8017C17C(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_8017C1F0(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_8017C494(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, UNK_TYPE4 param_11); -// void func_8017C540(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); +s32 Math3D_TriChkPointParaYIntersectInsideTri2(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 z, f32 x, f32* yIntersect, f32 chkDist); +s32 Math3D_TriChkPointParaXDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 unk, f32 chkDist, f32 nx); // void func_8017C808(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_8017C850(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); +s32 Math3D_TriChkPointParaXIntersect(Vec3f* a, Vec3f* b, Vec3f* c, f32 nx, f32 ny, f32 nz, f32 dist, f32 y, f32 z, f32* xIntersect); // void func_8017C904(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_8017C980(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, UNK_TYPE4 param_11, UNK_TYPE4 param_12); +s32 Math3D_TriChkLineSegParaXIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 y, f32 z, f32* xIntersect, f32 x0, f32 x1); // void func_8017CB08(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_8017CB7C(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); +s32 Math3D_TriChkLineSegParaZDist(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 y, f32 z, f32 unk, f32 chkDist, f32 nz); // void func_8017CEA8(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_8017CEF0(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); +s32 Math3D_TriChkPointParaZIntersect(Vec3f* a, Vec3f* b, Vec3f* c, f32 nx, f32 ny, f32 nz, f32 dist, f32 x, f32 y, f32* zIntersect); // void func_8017CFA4(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_8017D020(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, UNK_TYPE4 param_11, UNK_TYPE4 param_12); +s32 Math3D_TriChkLineSegParaZIntersect(Vec3f* v0, Vec3f* v1, Vec3f* v2, f32 nx, f32 ny, f32 nz, f32 originDist, f32 x, f32 y, f32* zIntersect, f32 z0, f32 z1); // void func_8017D1AC(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_8017D220(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8017D2FC(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); +s32 Math3D_LineSegVsPlane(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* linePointA, Vec3f* linePointB, Vec3f* intersect, s32 fromFront); // void func_8017D404(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, UNK_TYPE4 param_11); void Math3D_TriSetCoords(TriNorm* tri, Vec3f* pointA, Vec3f* pointB, Vec3f* pointC); u32 Math3D_IsPointInSphere(Sphere16* sphere, Vec3f* point); -// void func_8017D668(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); -// void func_8017D7C0(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); +s32 Math3D_PointDistToLine2D(f32 arg0, f32 arg1, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32* arg6, f32* arg7, f32* arg8); // returns boolean +s32 func_8017D7C0(f32 x0, f32 y0, f32 x1, f32 y1, f32 x2, f32 y2, f32* lineLenSq); // void func_8017D814(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_8017D91C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_8017DA24(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -s32 Math3D_ColSphereLineSeg(Sphere16* sphere, LineSegment* line); +s32 Math3D_LineVsSph(Sphere16* sphere, LineSegment* line); void func_8017DD34(Sphere16* sphere, TriNorm* tri, Vec3f* pfParm3); s32 Math3D_ColSphereTri(Sphere16* sphere, TriNorm* tri, Vec3f* uParm3); // void func_8017E294(void); UNK_TYPE func_8017E350(UNK_PTR, Vec3f*, Vec3f*, Vec3f*, Vec3f*); s32 Math3D_ColCylinderTri(Cylinder16* cylinder, TriNorm* tri, Vec3f* pzParm3); // void func_8017F1A0(void); -s32 Math3D_ColSphereSphere(Sphere16* sphere1, Sphere16* sphere2); +s32 Math3D_SphVsSph(Sphere16* sphere1, Sphere16* sphere2); s32 Math3D_ColSphereSphereIntersect(Sphere16* sphere1, Sphere16* sphere2, f32* intersectAmount); s32 Math3D_ColSphereSphereIntersectAndDistance(Sphere16* sphere1, Sphere16* sphere2, f32* intersectAmount, f32* dist); s32 Math3D_ColSphereCylinderDistance(Sphere16* sphere, Cylinder16* cylinder, f32* dist); @@ -3384,62 +3067,23 @@ s32 Math3D_ColSphereCylinderDistanceAndAmount(Sphere16* sphere, Cylinder16* cyli s32 Math3D_ColCylinderCylinderAmount(Cylinder16* cylinder1, Cylinder16* cylinder2, f32* intersectAmount); s32 Math3D_ColCylinderCylinderAmountAndDistance(Cylinder16* cylinder1, Cylinder16* cylinder2, f32* intersectAmount, f32* dist); s32 Math3d_ColTriTri(TriNorm* tri1, TriNorm* tri2, Vec3f* uParm3); -// void func_8017F9C0(void); -// void func_8017FA34(void); -// void func_8017FAA8(void); +s32 Math3D_XZInSphere(Sphere16* sphere, f32 x, f32 z); +s32 Math3D_XYInSphere(Sphere16* sphere, f32 x, f32 y); +s32 Math3D_YZInSphere(Sphere16* sphere, f32 y, f32 z); // void func_8017FB1C(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, UNK_TYPE4 param_11); // void func_8017FD44(void); + u16 Math_GetAtan2Tbl(f32 opposite, f32 adjacent); s16 Math_Atan2S(f32 opposite, f32 adjacent); f32 Math_Atan2F(f32 opposite, f32 adjacent); s16 Math_FAtan2F(f32 adjacent, f32 opposite); f32 Math_Acot2F(f32 adjacent, f32 opposite); -void Matrix_StateAlloc(GameState* gameState); -void Matrix_StatePush(void); -void Matrix_StatePop(void); -void Matrix_CopyCurrentState(MtxF* matrix); -void Matrix_SetCurrentState(MtxF* matrix); -MtxF* Matrix_GetCurrentState(void); -void Matrix_InsertMatrix(MtxF* matrix, s32 appendToState); -void Matrix_InsertTranslation(f32 x, f32 y, f32 z, s32 appendToState); -void Matrix_Scale(f32 xScale, f32 yScale, f32 zScale, s32 appendToState); -void Matrix_InsertXRotation_s(s16 rotation, s32 appendToState); -void Matrix_InsertXRotation_f(f32 rotation, s32 appendToState); -void Matrix_RotateStateAroundXAxis(f32 rotation); -void Matrix_SetStateXRotation(f32 rotation); -void Matrix_RotateY(s16 rotation, s32 appendToState); -void Matrix_InsertYRotation_f(f32 rotation, s32 appendToState); -void Matrix_InsertZRotation_s(s16 rotation, s32 appendToState); -void Matrix_InsertZRotation_f(f32 rotation, s32 appendToState); -void Matrix_InsertRotation(s16 xRotation, s16 yRotation, s16 zRotation, s32 appendToState); -void Matrix_JointPosition(Vec3f* position, Vec3s* rotation); -void Matrix_RotateAndTranslateState(Vec3f* translation, Vec3s* rotation); -void Matrix_SetStateRotationAndTranslation(f32 x, f32 y, f32 z, Vec3s* rotation); -RSPMatrix* Matrix_ToRSPMatrix(MtxF* src, RSPMatrix* dst); -Mtx* Matrix_ToMtx(Mtx* dest); -RSPMatrix* Matrix_GetStateAsRSPMatrix(RSPMatrix* matrix); -Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx); -RSPMatrix* Matrix_AppendStateToPolyOpaDisp(GraphicsContext* gfxCtx); -void Matrix_AppendToPolyOpaDisp(MtxF* mtx, GraphicsContext* gfxCtx); -void Matrix_MultiplyVector3fByState(Vec3f* src, Vec3f* dst); -void Matrix_GetStateTranslation(Vec3f* dst); -void Matrix_GetStateTranslationAndScaledX(f32 scale, Vec3f* dst); -void Matrix_GetStateTranslationAndScaledY(f32 scale, Vec3f* dst); -void Matrix_GetStateTranslationAndScaledZ(f32 scale, Vec3f* dst); -void Matrix_MultiplyVector3fXZByCurrentState(Vec3f* src, Vec3f* dst); -void Matrix_MtxFCopy(MtxF* dst, MtxF* src); -void Matrix_FromRSPMatrix(Mtx* src, MtxF* dst); -void Matrix_MultiplyVector3fByMatrix(Vec3f* src, Vec3f* dst, MtxF* matrix); -void Matrix_TransposeXYZ(MtxF* matrix); -void Matrix_NormalizeXYZ(MtxF* matrix); -void func_8018219C(MtxF* pfParm1, Vec3s* psParm2, s32 iParm3); -// void func_801822C4(void); -void Matrix_InsertRotationAroundUnitVector_f(f32 rotation, Vec3f* vector, s32 appendToState); -void Matrix_InsertRotationAroundUnitVector_s(s16 rotation, Vec3f* vector, s32 appendToState); -// void func_80182C90(void); -// void func_80182CA0(void); -// void func_80182CBC(void); -// void func_80182CCC(void); + +u64* SysUcode_GetUCodeBoot(void); +size_t SysUcode_GetUCodeBootSize(void); +u64* SysUcode_GetUCode(void); +u64* SysUcode_GetUCodeData(void); + // void func_80182CE0(void); // void func_80183020(void); // void func_80183058(void); @@ -3452,12 +3096,12 @@ void func_80183070(void); // void func_801832B0(void); // void func_8018332C(void); // void func_8018340C(void); -// void func_80183430(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_8018349C(void); -// void func_801834A8(void); +void func_80183430(SkeletonInfo* skeletonInfo, void* arg1, void* arg2, Vec3s* arg3, s16* arg4, UnkKeyframeCallback* callbacks); +void func_8018349C(UNK_PTR arg0); +void func_801834A8(SkeletonInfo* skeletonInfo, void* arg1); // void func_80183510(void); // void func_80183580(void); -// void func_801835EC(void); +void func_801835EC(UNK_PTR arg0, UNK_PTR arg1); // void func_80183658(void); // void func_801836CC(void); // void func_8018373C(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); @@ -3467,9 +3111,11 @@ void func_80183070(void); // void func_80183A3C(void); // void func_80183B08(void); // void func_80183B68(void); -// void func_80183DE0(void); +s32 func_80183DE0(SkeletonInfo* skeletonInfo); // void func_8018410C(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_8018450C(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_8018450C(GlobalContext* globalCtx, SkeletonInfo* skeleton, Mtx* mtx, + OverrideKeyframeDrawScaled overrideKeyframeDraw, PostKeyframeDrawScaled postKeyframeDraw, + Actor* actor); // void func_801845A4(void); // void func_801845C8(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); // void func_80184638(void); @@ -3493,31 +3139,33 @@ void Slowly_Stop(SlowlyTask* slowly); // char* func_801857D0(void); // void func_80185864(void); u32 func_80185908(void); -// void func_80185968(void); +UNK_TYPE func_80185968(void* arg0, UNK_TYPE arg1, UNK_TYPE arg2); // void func_801859F0(void); // void func_80185A2C(void); // void func_80185B1C(void); // void func_80185BE4(void); // void func_80185C24(void); void SysFlashrom_ThreadEntry(s80185D40* param_1); -// void func_80185DDC(void); -// void func_80185EC4(void); -// void func_80185F04(void); -// void func_80185F64(void); +void func_80185DDC(u8* arg0, u32 arg1, u32 arg2); +s32 func_80185EC4(void); +s32 func_80185F04(void); +void func_80185F64(void* arg0, UNK_TYPE arg1, UNK_TYPE arg2); s32 func_80185F90(u32 param_1); -// void func_80186A70(void); -// void func_80186B78(void); -// void func_80186CAC(void); -// void func_80186D60(void); -// void func_80186E64(void); -// void func_80186EC8(void); -// void func_80187018(void); -// void func_80187080(void); -// void func_80187124(void); -// void func_80187284(void); -// void func_801872FC(void); -// void func_801873BC(void); -// void func_8018752C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); +u32 osFlashGetAddr(u32 pageNum); +OSPiHandle* osFlashReInit(u8 latency, u8 pulse, u8 pageSize, u8 relDuration, u32 start); +void osFlashChange(u32 flashNum); +OSPiHandle* osFlashInit(void); +void osFlashReadStatus(u8* flashStatus); +void osFlashReadId(u32* flashType, u32* flashVendor); +void osFlashClearStatus(void); +s32 osFlashAllErase(void); +void osFlashAllEraseThrough(void); +s32 osFlashCheckEraseEnd(void); +s32 osFlashSectorErase(u32 pageNum); +void osFlashSectorEraseThrough(u32 pageNum); +s32 osFlashWriteBuffer(OSIoMesg* mb, s32 priority, void* dramAddr, OSMesgQueue* mq); +s32 osFlashWriteArray(u32 pageNum); +s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u32 pageCount, OSMesgQueue* mq); // void func_801877D0(void); // void func_80187B64(void); // void func_80187BEC(void); @@ -3560,130 +3208,53 @@ s32 func_80185F90(u32 param_1); // void func_8018A808(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_8018ACC4(void); // void func_8018AE34(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_8018B0F0(void); -// void func_8018B10C(void); -// void func_8018B250(void); -// void func_8018B318(void); -// void func_8018B474(void); -// void func_8018B4F8(void); -// void func_8018B520(void); -// void func_8018B578(void); -// void func_8018B5D0(void); -// void func_8018B608(void); -// void func_8018B640(void); -// void func_8018B69C(void); -// void func_8018B6E8(void); -// void func_8018B740(void); -// void func_8018B768(void); -// void func_8018B77C(void); -// void func_8018B7BC(void); -// void func_8018B8FC(void); -// void func_8018B95C(void); -// void func_8018B9E0(void); -// void func_8018BA64(void); -// void func_8018BB28(void); -// void func_8018BBEC(void); -// void func_8018C380(void); -// void func_8018C3D8(void); -// void func_8018C8E8(void); -// void func_8018C93C(void); -// void func_8018C994(void); -// void func_8018CB70(void); -// void func_8018CB78(void); -// void func_8018CC3C(void); -// void func_8018CCA8(void); -// void func_8018CFAC(void); -// void func_8018D57C(void); -// void func_8018D5D4(void); -// void func_8018D658(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8018D6C8(void); -// void func_8018D760(void); -// void func_8018DA50(void); -// void func_8018DBC4(void); -// void func_8018DCB4(void); -// void func_8018DCF8(void); -// void func_8018DD98(void); -// void func_8018DDD4(void); -// void func_8018DF24(void); -// void func_8018DFE0(void); -// void func_8018E00C(void); -// void func_8018E03C(void); -// void func_8018E2A8(void); -// void func_8018E344(void); -// void func_8018E8C8(void); -// void func_8018EB60(void); -// void func_8018EC4C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8018EF88(void); -// void func_8018F220(void); -// void func_8018F298(void); -// void func_8018F310(void); -// void func_8018F388(void); -// void func_8018F3B8(void); -// void func_8018F3E8(void); -// void func_8018F448(void); -// void func_8018F478(void); -// void func_8018F4D8(void); -// void func_8018F588(void); -// void func_8018F604(void); -// void func_8018F6F0(void); -// void func_8018F7C0(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_8018F7F8(void); -// void func_8018F83C(void); -// void func_8018F880(void); -// void func_8018F8C4(void); -// void func_8018F908(void); -// void func_8018F9B8(void); -// void func_8018FA60(void); -// void func_8018FAD0(void); -// void func_8018FB20(void); -// void func_8018FB78(void); -// void func_8018FCCC(void); -// void func_8018FD20(void); -// void func_8018FD40(void); -// void func_8018FE5C(void); -// void func_8018FF60(void); -// void func_80190204(void); -// void func_80190240(void); -// void func_80190294(void); -// void func_801902D8(void); -// void func_80190544(void); -// void func_80190668(void); -// void func_8019067C(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_8019075C(void); -// void func_8019077C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_80190B08(void); -void func_80190B38(void* callback); -// void func_80190B50(void); -// void func_80190BB0(void); -// void func_80190F50(void); -// void func_80190F64(void); -// void func_80191134(void); -// void func_801911CC(void); -// void func_80191240(void); -// void func_801913C8(void); -// void func_8019144C(void); -// void func_80191460(void); -// void func_80191568(void); -// void func_80191598(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_8019161C(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_80191740(void); -// void func_80191864(void); -// void func_80191870(void); -// void func_801919AC(void); -// void func_80191B40(void); -// void func_80191BD0(void); -// void func_80191C40(void); -// void func_80191C54(void); -// void func_80191D94(void); -// void func_8019218C(void); -// void func_80192340(void); -// void func_80192388(void); -// void func_801924BC(void); -// void func_80192514(void); -// void func_80192990(void); -// void func_80192AE8(void); -// void func_80192B54(void); -// void func_80192BAC(void); +void AudioHeap_DiscardFont(s32 fontId); +void* AudioHeap_WritebackDCache(void* addr, size_t size); +void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size); +void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size); +void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size); +void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size); +void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* addr, size_t size); +void AudioHeap_PopCache(s32 tableType); +void AudioHeap_InitMainPool(size_t initPoolSize); +void* AudioHeap_AllocCached(s32 tableType, size_t size, s32 cache, s32 id); +void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id); +void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff); +s32 AudioHeap_ResetStep(void); +void AudioHeap_Init(void); +void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id); +void* AudioHeap_AllocPermanent(s32 tableType, s32 id, size_t size); +void* AudioHeap_AllocSampleCache(size_t size, s32 sampleBankId, void* sampleAddr, s8 medium, s32 cache); +void AudioHeap_ApplySampleBankCache(s32 sampleBankId); +void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 flags); +void AudioLoad_DecreaseSampleDmaTtls(void); +void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaIndexRef, s32 medium); +void AudioLoad_InitSampleDmaBuffers(s32 numNotes); +s32 AudioLoad_IsFontLoadComplete(s32 fontId); +s32 AudioLoad_IsSeqLoadComplete(s32 seqId); +void AudioLoad_SetFontLoadStatus(s32 fontId, s32 status); +void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 status); +void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue* arg3); +s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId); +void AudioLoad_AsyncLoadSeq(s32 seqId, s32 arg1, s32 retData, OSMesgQueue* retQueue); +void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 arg1, s32 retData, OSMesgQueue* retQueue); +void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* retQueue); +u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts); +void AudioLoad_DiscardSeqFonts(s32 seqId); +void func_8018FA60(u32 tableType, u32 id, s32 arg2, s32 arg3); +s32 AudioLoad_SyncIniPlayer(s32 playerIdx, s32 seqId, s32 arg2); +s32 AudioLoad_SyncInitSetSeqqPlayerSkipTicks(s32 playerIdx, s32 seqId, s32 skipTicks); +void AudioLoad_ProcessLoads(s32 resetStatus); +void AudioLoad_SetDmaHandler(DmaHandler callback); +void AudioLoad_Init(void* heap, u32 heapSize); +void AudioLoad_InitSlowLoads(void); +s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone); +s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone); +void AudioLoad_InitAsyncLoads(void); +void AudioLoad_LoadPermanentSamples(void); +void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* isDone); +void AudioLoad_ProcessScriptLoads(void); +void AudioLoad_InitScriptLoads(void); AudioTask* func_80192BE0(void); // void func_80192C00(void); // void func_8019319C(void); @@ -3693,7 +3264,7 @@ AudioTask* func_80192BE0(void); // void func_8019380C(void); // void func_80193858(void); // void func_8019387C(void); -// void func_801938A0(void); +void Audio_QueueCmdS8(u32 opArgs, s8 data); // void func_801938D0(void); // void func_80193900(void); // void func_80193990(void); @@ -3717,68 +3288,50 @@ AudioTask* func_80192BE0(void); // void func_80194528(void); // void func_80194548(void); // void func_80194568(void); -// void func_80194668(void); -// void func_801946E4(void); -// void func_80194710(void); -// void func_80194750(void); +u32 Audio_NextRandom(void); +void Audio_InitMesgQueues(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); -// void func_80194930(void); -// void func_80194DB0(void); -// void func_80194E60(void); -// void func_80194F20(void); -// void func_80194F84(void); -// void func_801954CC(void); -// void func_80195508(void); -// void func_801955DC(void); -// void func_801956C0(void); -// void func_801957B4(void); -// void func_801958F8(void); -// void func_80195C40(void); -// void func_80195C60(void); -// void func_80195C80(void); -// void func_80195D84(void); -// void func_80195DDC(void); -// void func_80195DEC(void); -// void func_80195E3C(void); -// void func_80195EE0(void); -// void func_80196040(void); -// void func_8019617C(void); -// void func_801961BC(void); -// void func_801961E8(void); -// void func_80196268(void); -// void func_801963E8(void); -// void func_8019641C(void); -// void func_80196448(void); -// void func_80196494(void); -// void func_801964F8(void); -// void func_801965F0(void); -// void func_801968C4(void); -// void func_80196A00(void); -// void func_80196BC8(void); -// void func_80196D20(void); -// void func_80196D7C(void); -// void func_80196DB4(void); -// void func_80196FEC(void); -// void func_80197048(void); -// void func_80197138(void); -// void func_80197164(void); -// void func_80197188(void); +void AudioPlayback_NoteDisable(Note* note); +void AudioPlayback_ProcessNotes(void); +SoundFontSound* AudioPlayback_InstrumentGetSound(Instrument* instrument, s32 semitone); +Instrument* AudioPlayback_GetInstrumentInner(s32 fontId, s32 instId); +Drum* AudioPlayback_GetDrum(s32 fontId, s32 drumId); +SoundFontSound* AudioPlayback_GetSfx(s32 fontId, s32 sfxId); +s32 AudioPlayback_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* value); +void AudioPlayback_SeqLayerNoteDecay(SequenceLayer* layer); +void AudioPlayback_SeqLayerNoteRelease(SequenceLayer* layer); +void AudioPlayback_InitSyntheticWave(Note* note, SequenceLayer* layer); +void AudioPlayback_InitNoteLists(NotePool* pool); +void AudioPlayback_InitNoteFreeList(void); +void AudioPlayback_NotePoolClear(NotePool* pool); +void AudioPlayback_NotePoolFill(NotePool* pool, s32 count); +void AudioPlayback_AudioListRemove(AudioListItem* item); +Note* AudioPlayback_AllocNote(SequenceLayer* layer); +void AudioPlayback_NoteInitAll(void); +void AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer); +void AudioEffects_NoteVibratoUpdate(Note* note); +void AudioEffects_NoteVibratoInit(Note* note); +void AudioEffects_NotePortamentoInit(Note* note); +void AudioEffects_AdsrInit(AdsrState* adsr, AdsrEnvelope* envelope, s16* volOut); +f32 AudioEffects_AdsrUpdate(AdsrState* adsr); // void func_801974D0(void); // void func_80197538(void); // void func_80197714(void); // void func_80197880(void); // void func_801979D8(void); // void func_80197A54(void); -// void func_80197AA4(void); +void AudioSeq_SequenceChannelDisable(SequenceChannel* channel); // void func_80197B14(void); // void func_80197C0C(void); // void func_80197C8C(void); -// void func_80197D24(void); -// void func_80197D4C(void); -// void func_80197E08(void); -// void func_80197E48(void); +void AudioSeq_SequencePlayerDisableAsFinished(SequencePlayer* seqPlayer); +void AudioSeq_SequencePlayerDisable(SequencePlayer* seqPlayer); +void AudioSeq_AudioListPushBack(AudioListItem* list, AudioListItem* item); +void* AudioSeq_AudioListPopBack(AudioListItem* list); // void func_80197E88(void); // void func_80197F28(void); // void func_80197F3C(void); @@ -3797,23 +3350,23 @@ void func_80199268(s32* param_1); // void func_8019A0BC(void); // void func_8019AA3C(void); // void func_8019AAF0(void); -// void func_8019AB40(void); -// void func_8019AC10(void); +void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer); +void AudioSeq_InitSequencePlayerChannels(s32 playerIdx); // void func_8019ACEC(void); -// void func_8019ADBC(void); +void AudioSeq_InitSequencePlayers(void); void func_8019AE40(s32 param_1, s32 param_2, u32 param_3, s32 param_4); void func_8019AEC0(UNK_PTR param_1, UNK_PTR param_2); // void func_8019AF00(void); // void func_8019AF58(void); // void func_8019AFE8(void); // void func_8019B02C(void); -// void func_8019B074(void); +// void AudioOcarina_MapSongFromNotesToButtons(void); // void func_8019B144(void); // void func_8019B378(void); // void func_8019B38C(void); // void func_8019B3D0(void); // void func_8019B4B8(void); -void func_8019B544(u16 arg0); +void AudioOcarina_StartDefault(u32 arg0); // void func_8019B568(void); // void func_8019B5AC(void); // void func_8019B5EC(void); @@ -3825,7 +3378,7 @@ void func_8019B544(u16 arg0); // void func_8019C1D0(void); // void func_8019C268(void); // void func_8019C2E4(void); -void func_8019C300(s32 arg0); +u32 AudioOcarina_SetInstrumentId(u8 arg0); // void func_8019C398(void); // void func_8019C5A0(void); // void func_8019C8D8(void); @@ -3835,14 +3388,14 @@ void func_8019C300(s32 arg0); // void func_8019CEBC(void); // void func_8019CF6C(void); // void func_8019CF78(void); -// void func_8019CF9C(void); +OcarinaStaff* AudioOcarina_GetPlaybackStaff(void); // void func_8019CFA8(void); -// void func_8019D134(void); -// void func_8019D26C(void); -// void func_8019D488(void); -// void func_8019D4F8(void); +// void AudioOcarina_TerminaWallValidateNotes(void); +void AudioOcarina_TerminaWallGenerateNotes(void); +// void AudioOcarina_MemoryGameSetNumNotes(void); +// void AudioOcarina_MemoryGameGenerateNotes(void); // void func_8019D600(void); -// void func_8019D758(void); +void func_8019D758(void); // void func_8019D864(void); // void func_8019D8B4(void); // void func_8019D8E4(void); @@ -3861,16 +3414,16 @@ void func_8019E014(void); // void func_8019F05C(void); void play_sound(u16 sfxId); void func_8019F128(u16 sfxId); -// void func_8019F170(void); -void func_8019F1C0(Vec3f* pos, u16 sfxId); -void func_8019F208(void); -void func_8019F230(void); // Plays "No" sound +void func_8019F170(Vec3f* pos, u16 sfxId); +void Audio_PlaySfxAtPos(Vec3f* pos, u16 sfxId); +void func_8019F208(void); // decide sfx +void func_8019F230(void); // cancel sfx // void func_8019F258(void); // void func_8019F300(void); void func_8019F420(Vec3f* pos, u16 sfxId); -// void func_8019F4AC(void); -void func_8019F540(u8 arg0); -// void func_8019F570(void); +void func_8019F4AC(Vec3f* pos, u16 sfxId); +void func_8019F540(s8 arg0); +void func_8019F570(Vec3f* pos, s8 arg1); // void func_8019F5AC(void); // void func_8019F638(void); // void func_8019F780(void); @@ -3880,33 +3433,33 @@ 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 sfxId, f32 param_3); -// void func_8019FB0C(void); -// void func_8019FC20(void); +void func_8019FB0C(Vec3f* arg0, u16 sfxId, f32 arg2, s32 arg3); +void func_8019FC20(Vec3f* pos, u16 sfxId); // void func_8019FCB8(void); // void func_8019FD90(void); void func_8019FDC8(UNK_PTR arg0, u16 sfxId, UNK_TYPE arg2); -void func_8019FE1C(Vec3f* arg0, u16 sfxId, f32 arg2); -void func_8019FE74(f32* arg0, f32 arg1, UNK_TYPE arg2); +void func_8019FE1C(Vec3f*, u16 sfxId, f32); +void func_8019FE74(f32* arg0, f32 arg1, s32 arg2); // void func_8019FEDC(void); // void func_8019FF38(void); -// void func_8019FF9C(void); -// void func_801A0048(void); -// void func_801A00EC(void); +void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale); +// void Audio_PlaySfxForWaterfall(void); +// void Audio_StepFreqLerp(void); void func_801A0124(Vec3f* pos, u8 arg1); // void func_801A0184(void); // void func_801A01C4(void); -void func_801A0204(UNK_TYPE); -// void func_801A0238(void); -// void func_801A026C(void); -// void func_801A0318(void); -// void func_801A046C(void); +void func_801A0204(s8 seqId); +void func_801A0238(s32 arg0, s32 arg1); +// void Audio_SetGanonsTowerBgmVolumeLevel(void); +// void Audio_SetGanonsTowerBgmVolume(void); +// void Audio_UpdateRiverSoundVolumes(void); // void func_801A0554(void); // void func_801A05F0(void); -// void func_801A0654(void); -// void func_801A0810(void); -// void func_801A0868(void); +void func_801A0654(Vec3f* arg0, u16 sfxId, s32 arg2); +void func_801A0810(Vec3f* arg0, u16 sfxId, u8 arg2); +void func_801A0868(Vec3f* pos, u16 sfxId, u8 val); // void func_801A09D4(void); -// void func_801A0CB0(void); +// void Audio_SplitBgmChannels(void); // void func_801A0E44(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_801A1290(void); // void func_801A1348(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); @@ -3916,57 +3469,57 @@ void func_801A0204(UNK_TYPE); // void func_801A1904(void); // void func_801A1A10(void); // void func_801A1A8C(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_801A1D44(Vec3f* vec, UNK_TYPE arg1, f32 arg2); -void func_801A1DB8(Vec3f* vec, UNK_TYPE arg1, f32 arg2); +void func_801A1D44(Vec3f* vec, u8 seqId, f32 arg2); +void func_801A1DB8(Vec3f* vec, u8 seqId, f32 arg2); // void func_801A1E0C(void); -void func_801A1F00(s32 arg0, s32 arg1); +void func_801A1F00(u8 arg0, u16 seqId); void func_801A1F88(void); -// void func_801A1FB4(void); +void func_801A1FB4(u8 playerIdx, Vec3f* pos, u16 seqId, f32 maxDist); // void func_801A2090(void); void func_801A246C(u8 param_1, u8 param_2); // void func_801A2544(void); // void func_801A257C(void); -// void func_801A25E4(void); +void func_801A25E4(u16 seqId, u8 dayMinusOne); // void func_801A2670(void); // void func_801A2778(void); // void func_801A27E8(void); // void func_801A281C(void); void func_801A29D4(UNK_TYPE arg0, f32 arg1, UNK_TYPE arg2); -void func_801A2BB8(s32 arg0); +void func_801A2BB8(s32 seqId); void func_801A2C20(void); // void func_801A2C44(void); -// void func_801A2C88(void); -// void func_801A2D54(void); -s32 func_801A2DE0(UNK_TYPE4 arg1); -void func_801A2E54(s32 param_1); +void func_801A2C88(u16 seqId); +void func_801A2D54(u16 seqId); +s32 Audio_IsSequencePlaying(u8 seqId); +void func_801A2E54(s32 bgmId); void func_801A2ED8(void); // void func_801A2F88(void); // void func_801A3000(void); // void func_801A3038(void); -void func_801A3098(u16 arg0); +void func_801A3098(u16 seqId); // void func_801A312C(void); -void func_801A31EC(UNK_TYPE1 arg1, UNK_TYPE4 arg2, u8 arg3); +void func_801A31EC(u16 seqId, s8 arg1, u8 arg2); // void func_801A3238(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); // void func_801A32CC(void); // void func_801A3590(void); -// void func_801A3950(void); +u8 func_801A3950(s32 playerIndex, s32 isChannelIOSet); u8 func_801A39F8(void); -// void func_801A3A7C(void); +void func_801A3A7C(s32 arg0); // void func_801A3AC0(void); -// void func_801A3AEC(void); +void func_801A3AEC(s32 arg0); void func_801A3B48(UNK_TYPE arg0); // void func_801A3B90(void); void func_801A3CD8(s8 param_1); // void func_801A3CF4(void); -// void func_801A3D98(void); +void func_801A3D98(s8 audioSetting); // void func_801A3E38(void); // void func_801A3EC0(void); -// void func_801A3F54(void); +void Audio_SetCutsceneFlag(u8 flag); // 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); void audio_setBGM(u32 bgmID); -// void func_801A4058(void); +void func_801A4058(UNK_TYPE arg0); // void func_801A41C8(void); // void func_801A41F8(void); // void func_801A429C(void); @@ -3974,16 +3527,16 @@ void audio_setBGM(u32 bgmID); // void func_801A4324(void); // void func_801A4348(void); // void func_801A4380(void); -// void func_801A4428(void); +void func_801A4428(u8 reverbIndex); void Audio_PreNMI(void); // void func_801A44C4(void); // void func_801A44D4(void); s32 func_801A46F8(void); -// void func_801A4748(void); -void func_801A479C(Vec3f* arg0, u16 sfxId, UNK_TYPE arg2); -// void func_801A47DC(void); +void func_801A4748(Vec3f* pos, u16 sfxId); +void func_801A479C(Vec3f* arg0, u16 sfxId, s32 arg2); +void func_801A47DC(u8 channelIndexRange, u8 port, u8 val); // void func_801A48E0(void); -// void func_801A4A28(void); +void func_801A4A28(u8 natureSeqId); // void func_801A4B80(void); void func_801A4C30(void); // void func_801A4C54(void); @@ -3995,8 +3548,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); UNK_TYPE func_801A51F0(UNK_TYPE arg0); // void func_801A5228(void); @@ -4013,7 +3566,7 @@ UNK_TYPE func_801A51F0(UNK_TYPE arg0); void func_801A5BD0(s32 param_1); // void func_801A5C28(void); // void func_801A5C8C(void); -void func_801A5CFC(u16 sfxId, Vec3f* arg1, s32 arg2, f32* arg3, f32* arg4, s8* arg5); +void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* param_2, u8 param_3, f32* param_4, f32* param_5, s8* param_6); // void func_801A5DDC(void); // void func_801A5F7C(void); // void func_801A6430(void); @@ -4022,42 +3575,31 @@ void func_801A5CFC(u16 sfxId, Vec3f* arg1, s32 arg2, f32* arg3, f32* arg4, s8* a // void func_801A7084(void); // void func_801A7168(void); // void func_801A7284(void); -void func_801A72CC(Vec3f* uParm1); +void Audio_StopSfxByPos(Vec3f* pos); 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); // void func_801A787C(void); -// void func_801A78E4(void); +u8 Audio_IsSfxPlaying(u32 sfxId); // void func_801A794C(void); // void func_801A7B10(void); // void func_801A7D04(void); // void func_801A7D84(void); -void Audio_QueueSeqCmd(u32 arg0); +void Audio_QueueSeqCmd(u32 cmd); // void func_801A89D0(void); s32 func_801A8A50(s32 param1); // void func_801A8ABC(void); -// void func_801A8BD0(void); +void Audio_SetVolumeScale(u8 playerIdx, u8 scaleIdx, u8 targetVol, u8 volFadeTimer); // void func_801A8D5C(void); // void func_801A8E90(void); // void func_801A9768(void); // void func_801A982C(void); // void func_801A99B8(void); // void func_801A9A74(void); -// void func_801A9B10(void); -// void func_801A9B78(void); -// void func_801A9BFC(void); -// void func_801A9C68(void); -// void func_801A9D10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); -// void func_801A9DCC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5); -// void func_801A9EA4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE1 param_6); -// void func_801A9F4C(void); -// void func_801AA020(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); -// void func_801AA248(void); -// void func_801AA3E4(void); -// void func_801AA520(void); + void GameOver_Init(GlobalContext* globalCtx); void GameOver_FadeLights(GlobalContext* globalCtx); void GameOver_Update(GlobalContext* globalCtx); diff --git a/include/ichain.h b/include/ichain.h index 8b1112191..07bd07313 100644 --- a/include/ichain.h +++ b/include/ichain.h @@ -1,5 +1,7 @@ -#ifndef _ICHAIN_H_ -#define _ICHAIN_H_ +#ifndef ICHAIN_H +#define ICHAIN_H + +#include "libc/stddef.h" typedef struct { u32 cont: 1; @@ -8,8 +10,6 @@ typedef struct { s32 value: 16; } InitChainEntry; -#define OFFSETOF(structure, member) ((size_t)&(((structure*)0)->member)) - typedef enum { /* 0x0 */ ICHAINTYPE_U8, // sets byte /* 0x1 */ ICHAINTYPE_S8, @@ -38,7 +38,7 @@ typedef enum { * * cont ----- ICHAIN_CONTINUE (or ICHAIN_STOP) to continue (or stop) parsing */ #define ICHAIN(type, member, value, cont) \ - { cont, type, OFFSETOF(Actor, member), value } + { cont, type, offsetof(Actor, member), value } #define ICHAIN_U8(member, val, cont) ICHAIN(ICHAINTYPE_U8, member, val, cont) #define ICHAIN_S8(member, val, cont) ICHAIN(ICHAINTYPE_S8, member, val, cont) diff --git a/include/initvars.h b/include/initvars.h index a1dbe1fa1..11a6719e9 100644 --- a/include/initvars.h +++ b/include/initvars.h @@ -1,6 +1,40 @@ #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 Player_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 50add3561..4321df096 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 { @@ -114,16 +114,17 @@ typedef struct { } __OSContReadFormat; +// Original name: __OSContRequesFormat typedef struct { - /* 0x0 */ u8 dummy; - /* 0x1 */ u8 txsize; - /* 0x2 */ u8 rxsize; - /* 0x3 */ u8 cmd; - /* 0x4 */ u8 typeh; - /* 0x5 */ u8 typel; - /* 0x6 */ u8 status; - /* 0x7 */ u8 dummy1; -} __OSContRequesFormat; + /* 0x00 */ u8 align; + /* 0x01 */ u8 txsize; + /* 0x02 */ u8 rxsize; + /* 0x03 */ u8 poll; + /* 0x04 */ u8 typeh; + /* 0x05 */ u8 typel; + /* 0x06 */ u8 status; + /* 0x07 */ u8 align1; +} __OSContRequestHeader; // size = 0x8 typedef struct { /* 0x00 */ u8 txsize; @@ -145,5 +146,18 @@ typedef struct { /* 0x26 */ u8 datacrc; } __OSContRamReadFormat; +extern OSPifRam __osContPifRam; +// extern UNK_TYPE1 D_8009CF0C; +extern u8 __osContLastPoll; +extern u8 __osMaxControllers; +// extern OSMesgQueue D_8009CF38; +// extern OSMesg D_8009CF50; + +typedef struct { + /* 0x00 */ OSContPad cur; + /* 0x06 */ OSContPad prev; + /* 0x0C */ OSContPad press; // X/Y store delta from last frame + /* 0x12 */ OSContPad rel; // X/Y store adjusted +} Input; // size = 0x18 #endif diff --git a/include/irqmgr.h b/include/irqmgr.h new file mode 100644 index 000000000..40ed322d1 --- /dev/null +++ b/include/irqmgr.h @@ -0,0 +1,27 @@ +#ifndef IRQMGR_H +#define IRQMGR_H + +#include "PR/ultratypes.h" +#include "PR/sched.h" +#include "ultra64/message.h" + +typedef struct IrqMgrClient { + /* 0x0 */ struct IrqMgrClient* next; + /* 0x4 */ OSMesgQueue* queue; +} IrqMgrClient; // size = 0x8 + +typedef struct { + /* 0x000 */ OSScMsg verticalRetraceMesg; + /* 0x020 */ OSScMsg prenmiMsg; + /* 0x040 */ OSScMsg nmiMsg; + /* 0x060 */ OSMesgQueue irqQueue; + /* 0x078 */ OSMesg irqBuffer[8]; + /* 0x098 */ OSThread thread; + /* 0x248 */ IrqMgrClient* callbacks; + /* 0x24C */ u8 prenmiStage; + /* 0x250 */ OSTime lastPrenmiTime; + /* 0x258 */ OSTimer prenmiTimer; + /* 0x278 */ OSTime lastFrameTime; +} IrqMgr; // size = 0x280 + +#endif diff --git a/include/alloca.h b/include/libc/alloca.h similarity index 100% rename from include/alloca.h rename to include/libc/alloca.h diff --git a/include/libc/assert.h b/include/libc/assert.h new file mode 100644 index 000000000..1bc72e314 --- /dev/null +++ b/include/libc/assert.h @@ -0,0 +1,4 @@ +#ifndef ASSERT_H +#define ASSERT_H + +#endif diff --git a/include/math.h b/include/libc/math.h similarity index 74% rename from include/math.h rename to include/libc/math.h index 20fa352fa..c6756d959 100644 --- a/include/math.h +++ b/include/libc/math.h @@ -1,5 +1,5 @@ -#ifndef _MATH_H_ -#define _MATH_H_ +#ifndef MATH_H +#define MATH_H #include "PR/ultratypes.h" @@ -26,4 +26,11 @@ typedef union { extern f32 __libm_qnan_f; +float fabsf(float f); +#pragma intrinsic(fabsf) +float sqrtf(float f); +#pragma intrinsic(sqrtf) +double sqrt(double d); +#pragma intrinsic(sqrt) + #endif diff --git a/include/stdarg.h b/include/libc/stdarg.h similarity index 96% rename from include/stdarg.h rename to include/libc/stdarg.h index 26a67e580..77b8b8866 100644 --- a/include/stdarg.h +++ b/include/libc/stdarg.h @@ -1,5 +1,5 @@ -#ifndef _STDARG_H_ -#define _STDARG_H_ +#ifndef STDARG_H +#define STDARG_H #include "ultra64.h" @@ -41,5 +41,6 @@ typedef char *va_list; : __va_stack_arg(list, mode))))[-1] #define va_end(__list) -#endif -#endif +#endif /* __GNUC__ */ + +#endif /* STDARG_H */ diff --git a/include/stdbool.h b/include/libc/stdbool.h similarity index 72% rename from include/stdbool.h rename to include/libc/stdbool.h index 519806b31..d441054c1 100644 --- a/include/stdbool.h +++ b/include/libc/stdbool.h @@ -1,5 +1,5 @@ -#ifndef _STDBOOL -#define _STDBOOL +#ifndef STDBOOL +#define STDBOOL #define __bool_true_false_are_defined 1 @@ -11,4 +11,4 @@ #endif /* __cplusplus */ -#endif /* _STDBOOL */ +#endif /* STDBOOL */ diff --git a/include/libc/stddef.h b/include/libc/stddef.h new file mode 100644 index 000000000..4f55e5725 --- /dev/null +++ b/include/libc/stddef.h @@ -0,0 +1,20 @@ +#ifndef STDDEF_H +#define STDDEF_H + +#include "PR/ultratypes.h" + +typedef u32 size_t; + +typedef s32 ptrdiff_t; + +#ifndef NULL +#define NULL (void*)0 +#endif + +#ifdef __GNUC__ +#define offsetof(structure, member) __builtin_offsetof (structure, member) +#else +#define offsetof(structure, member) ((size_t)&(((structure*)0)->member)) +#endif + +#endif /* STDDEF_H */ diff --git a/include/stdint.h b/include/libc/stdint.h similarity index 86% rename from include/stdint.h rename to include/libc/stdint.h index 67e9e6862..1696615a7 100644 --- a/include/stdint.h +++ b/include/libc/stdint.h @@ -1,7 +1,7 @@ -#ifndef _STDINT_H_ -#define _STDINT_H_ +#ifndef STDINT_H +#define STDINT_H -#include "ultra64.h" +#include "PR/ultratypes.h" typedef s32 intptr_t; typedef u32 uintptr_t; @@ -26,4 +26,4 @@ typedef u32 uintptr_t; #define UINTPTR_MAX 0xffffffff -#endif /* _STDINT_H_ */ +#endif /* STDINT_H */ diff --git a/include/stdlib.h b/include/libc/stdlib.h similarity index 77% rename from include/stdlib.h rename to include/libc/stdlib.h index a7b44961a..57d352a13 100644 --- a/include/stdlib.h +++ b/include/libc/stdlib.h @@ -1,27 +1,25 @@ -#ifndef _STDLIB_H_ -#define _STDLIB_H_ +#ifndef STDLIB_H +#define STDLIB_H + +#include "libc/stddef.h" typedef struct { /* 0x0 */ int quot; /* 0x4 */ int rem; } div_t; - typedef struct { /* 0x0 */ long quot; /* 0x4 */ long rem; } ldiv_t; - typedef struct { /* 0x0 */ long long quot; /* 0x8 */ long long rem; } lldiv_t; -typedef unsigned long size_t; - typedef int ssize_t; typedef long wchar_t; -#endif +#endif /* STDLIB_H */ diff --git a/include/macro.inc b/include/macro.inc index 396a4cb68..d7a8da875 100644 --- a/include/macro.inc +++ b/include/macro.inc @@ -37,3 +37,39 @@ .set TagHi, $29 .set ErrorEPC, $30 .set Reserved31, $31 + + +# Float register aliases (o32 ABI, odd ones are rarely used) + +.set $fv0, $f0 +.set $fv0f, $f1 +.set $fv1, $f2 +.set $fv1f, $f3 +.set $ft0, $f4 +.set $ft0f, $f5 +.set $ft1, $f6 +.set $ft1f, $f7 +.set $ft2, $f8 +.set $ft2f, $f9 +.set $ft3, $f10 +.set $ft3f, $f11 +.set $fa0, $f12 +.set $fa0f, $f13 +.set $fa1, $f14 +.set $fa1f, $f15 +.set $ft4, $f16 +.set $ft4f, $f17 +.set $ft5, $f18 +.set $ft5f, $f19 +.set $fs0, $f20 +.set $fs0f, $f21 +.set $fs1, $f22 +.set $fs1f, $f23 +.set $fs2, $f24 +.set $fs2f, $f25 +.set $fs3, $f26 +.set $fs3f, $f27 +.set $fs4, $f28 +.set $fs4f, $f29 +.set $fs5, $f30 +.set $fs5f, $f31 diff --git a/include/macros.h b/include/macros.h index 607e5e9bc..bb7315b3d 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,25 +1,27 @@ -#ifndef _MACROS_H_ -#define _MACROS_H_ +#ifndef MACROS_H +#define MACROS_H -#include "stdint.h" -#include "convert.h" +#include "libc/stdint.h" +#include "ultra64/convert.h" #include "z64.h" +#define SCREEN_WIDTH 320 +#define SCREEN_HEIGHT 240 + +#define SCREEN_WIDTH_HIGH_RES 576 +#define SCREEN_HEIGHT_HIGH_RES 454 + #define ARRAY_COUNT(arr) (s32)(sizeof(arr) / sizeof(arr[0])) #define ARRAY_COUNTU(arr) (u32)(sizeof(arr) / sizeof(arr[0])) -#define HW_REG(reg, type) *(volatile type*)((reg) | 0xa0000000) - -// TODO: After uintptr_t cast change should have an AVOID_UB target that just toggles the KSEG0 bit in the address -// rather than add/sub 0x80000000 -#define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr) + 0x80000000) -#define PHYSICAL_TO_VIRTUAL2(addr) ((uintptr_t)(addr)-0x80000000) -#define VIRTUAL_TO_PHYSICAL(addr) (uintptr_t)((u8*)(addr)-0x80000000) +// TODO: After uintptr_t cast change should have an AVOID_UB target that just toggles the KSEG0 bit in the address rather than add/sub 0x80000000 +#define PHYSICAL_TO_VIRTUAL(addr) ((uintptr_t)(addr) + RDRAM_CACHED) +#define PHYSICAL_TO_VIRTUAL2(addr) ((uintptr_t)(addr) - RDRAM_CACHED) +#define VIRTUAL_TO_PHYSICAL(addr) (uintptr_t)((u8*)(addr) - RDRAM_CACHED) #define SEGMENTED_TO_VIRTUAL(addr) (void*)(PHYSICAL_TO_VIRTUAL(gSegments[SEGMENT_NUMBER(addr)]) + SEGMENT_OFFSET(addr)) #define GET_ACTIVE_CAM(globalCtx) ((globalCtx)->cameraPtrs[(globalCtx)->activeCamera]) -#define MAIN_CAM 0 -#define SUBCAM_FREE 0 +#define CAM_ID_MAIN 0 #define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \ (curState)->nextGameStateInit = (GameStateFunc)newInit; \ @@ -36,43 +38,78 @@ } \ (void)0 -#define GET_PLAYER(globalCtx) ((Player*)(globalCtx)->actorCtx.actorList[ACTORCAT_PLAYER].first) +#define GET_PLAYER(globalCtx) ((Player*)(globalCtx)->actorCtx.actorLists[ACTORCAT_PLAYER].first) -#define GET_FIRST_ENEMY(globalCtx) ((Actor*)(globalCtx)->actorCtx.actorList[ACTORCAT_ENEMY].first) +#define GET_FIRST_ENEMY(globalCtx) ((Actor*)(globalCtx)->actorCtx.actorLists[ACTORCAT_ENEMY].first) // linkAge still exists in MM, but is always set to 0 (always adult) // There are remnants of these macros from OOT, but they are essentially useless -//#define LINK_IS_CHILD (gSaveContext.linkAge != 0) -#define LINK_IS_ADULT (gSaveContext.linkAge == 0) +#define LINK_IS_CHILD (gSaveContext.save.linkAge == 1) +#define LINK_IS_ADULT (gSaveContext.save.linkAge == 0) -#define CURRENT_DAY (((void)0, gSaveContext.day) % 5) +#define CURRENT_DAY (((void)0, gSaveContext.save.day) % 5) -#define CLOCK_TIME(hr, min) ((s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60))) +#define CLOCK_TIME(hr, min) (s32)(((hr) * 60 + (min)) * 0x10000 / (24 * 60)) #define CLOCK_TIME_MINUTE (CLOCK_TIME(0, 1)) +#define DAY_LENGTH (CLOCK_TIME(24, 0)) + +#define TIME_TO_MINUTES_F(time) ((time) * ((24.0f * 60.0f) / 0x10000)) // 0.021972656f +#define CLOCK_TIME_F(hr, min) (((hr) * 60.0f + (min)) * (0x10000 / (24.0f * 60.0f))) + +#define TIME_TO_MINUTES_ALT_F(time) ((time) / (0x10000 / (24.0f * 60.0f))) +#define CLOCK_TIME_ALT_F(hr, min) (((hr) * 60.0f + (min)) / (24.0f * 60.0f / 0x10000)) #define SLOT(item) gItemSlots[item] -#define AMMO(item) gSaveContext.inventory.ammo[SLOT(item)] -#define INV_CONTENT(item) gSaveContext.inventory.items[SLOT(item)] +#define AMMO(item) gSaveContext.save.inventory.ammo[SLOT(item)] +#define INV_CONTENT(item) gSaveContext.save.inventory.items[SLOT(item)] +#define GET_INV_CONTENT(item) ((void)0, gSaveContext.save.inventory.items)[SLOT(item)] -#define ALL_EQUIP_VALUE_VOID(equip) \ - ((((void)0, gSaveContext.inventory.equipment) & gEquipMasks[equip]) >> gEquipShifts[equip]) -#define CUR_EQUIP_VALUE_VOID(equip) \ - ((((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 CUR_FORM ((gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.save.playerForm) -#define CUR_FORM ((gSaveContext.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.playerForm) +#define GET_SAVE_EQUIPS_EQUIPMENT ((void)0, gSaveContext.save.equips.equipment) +#define GET_SAVE_INVENTORY_UPGRADES ((void)0, gSaveContext.save.inventory.upgrades) +#define GET_SAVE_INVENTORY_QUEST_ITEMS ((void)0, gSaveContext.save.inventory.questItems) -#define ALL_EQUIP_VALUE(equip) ((gSaveContext.inventory.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) -#define CUR_EQUIP_VALUE(equip) ((gSaveContext.equips.equipment & gEquipMasks[equip]) >> gEquipShifts[equip]) -#define CUR_UPG_VALUE(upg) ((gSaveContext.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) -#define TAKE_EQUIPPED_ITEM(equip) (gSaveContext.equips.equipment = ((((void)0, gSaveContext.equips.equipment) & (gEquipNegMasks[equip])) | (u16)(0 << gEquipShifts[equip]))) -#define CUR_FORM_EQUIP(button) (gSaveContext.equips.buttonItems[CUR_FORM][button]) -#define CHECK_QUEST_ITEM(item) (((void)0, gSaveContext.inventory.questItems) & gBitFlags[item]) -#define REMOVE_QUEST_ITEM(item) (gSaveContext.inventory.questItems = (((void)0, gSaveContext.inventory.questItems) & (-1 - gBitFlags[item]))) +#define GET_CUR_EQUIP_VALUE(equip) ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipMasks[equip]) >> gEquipShifts[equip]) + +#define CUR_UPG_VALUE(upg) ((gSaveContext.save.inventory.upgrades & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) +#define GET_CUR_UPG_VALUE(upg) ((GET_SAVE_INVENTORY_UPGRADES & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) + +#define SET_EQUIP_VALUE(equip, value) (gSaveContext.save.equips.equipment = ((GET_SAVE_EQUIPS_EQUIPMENT & gEquipNegMasks[equip]) | (u16)((u16)(value) << gEquipShifts[equip]))) + +#define BUTTON_ITEM_EQUIP(form, button) (gSaveContext.save.equips.buttonItems[form][button]) +#define CUR_FORM_EQUIP(button) BUTTON_ITEM_EQUIP(CUR_FORM, button) + +#define C_SLOT_EQUIP(form, button) (gSaveContext.save.equips.cButtonSlots[form][button]) +#define CHECK_QUEST_ITEM(item) (GET_SAVE_INVENTORY_QUEST_ITEMS & gBitFlags[item]) +#define REMOVE_QUEST_ITEM(item) (gSaveContext.save.inventory.questItems = (GET_SAVE_INVENTORY_QUEST_ITEMS & (-1 - gBitFlags[item]))) + +#define CHECK_DUNGEON_ITEM(item, dungeonIndex) (gSaveContext.save.inventory.dungeonItems[(void)0, dungeonIndex] & gBitFlags[item]) +#define DUNGEON_KEY_COUNT(dungeonIndex) (gSaveContext.save.inventory.dungeonKeys[(void)0, dungeonIndex]) + +#define GET_CUR_FORM_BTN_ITEM(btn) ((u8)((btn) == EQUIP_SLOT_B ? BUTTON_ITEM_EQUIP(CUR_FORM, btn) : BUTTON_ITEM_EQUIP(0, btn))) + +#define SET_CUR_FORM_BTN_ITEM(btn, item) \ + do { \ + if ((btn) == EQUIP_SLOT_B) { \ + BUTTON_ITEM_EQUIP(CUR_FORM, (btn)) = (item); \ + } else { \ + BUTTON_ITEM_EQUIP(0, (btn)) = (item); \ + } \ + } while (0) + +#define STOLEN_ITEM_NONE (0) + +#define STOLEN_ITEM_1 ((gSaveContext.save.stolenItems & 0xFF000000) >> 0x18) +#define STOLEN_ITEM_2 ((gSaveContext.save.stolenItems & 0x00FF0000) >> 0x10) + +#define SET_STOLEN_ITEM_1(itemId) \ + (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0xFF000000) | ((itemId & 0xFF) << 0x18)) +#define SET_STOLEN_ITEM_2(itemId) \ + (gSaveContext.save.stolenItems = (gSaveContext.save.stolenItems & ~0x00FF0000) | ((itemId & 0xFF) << 0x10)) #define CAPACITY(upg, value) gUpgradeCapacities[upg][value] -#define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg) - 4) +#define CUR_CAPACITY(upg) CAPACITY(upg, CUR_UPG_VALUE(upg)) #define CONTROLLER1(globalCtx) (&(globalCtx)->state.input[0]) #define CONTROLLER2(globalCtx) (&(globalCtx)->state.input[1]) @@ -82,12 +119,15 @@ #define CHECK_BTN_ALL(state, combo) (~((state) | ~(combo)) == 0) #define CHECK_BTN_ANY(state, combo) (((state) & (combo)) != 0) +#define CHECK_FLAG_ALL(flags, mask) (((flags) & (mask)) == (mask)) + extern GraphicsContext* __gfxCtx; #define WORK_DISP __gfxCtx->work.p #define POLY_OPA_DISP __gfxCtx->polyOpa.p #define POLY_XLU_DISP __gfxCtx->polyXlu.p #define OVERLAY_DISP __gfxCtx->overlay.p +#define DEBUG_DISP __gfxCtx->debug.p // __gfxCtx shouldn't be used directly. // Use the DISP macros defined above when writing to display buffers. @@ -97,6 +137,7 @@ extern GraphicsContext* __gfxCtx; s32 __dispPad #define CLOSE_DISPS(gfxCtx) \ + (void)0; \ } \ (void)0 @@ -119,13 +160,30 @@ extern GraphicsContext* __gfxCtx; #define GRAPH_ALLOC(gfxCtx, size) ((void*)((gfxCtx)->polyOpa.d = (Gfx*)((u8*)(gfxCtx)->polyOpa.d - (size)))) +// Custom gbi macro +#define gDPSetTileCustom(pkt, fmt, siz, width, height, pal, cms, cmt, masks, maskt, shifts, shiftt) \ + { \ + gDPPipeSync(pkt); \ + gDPTileSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width)*siz##_TILE_BYTES) + 7) >> 3, 0, G_TX_LOADTILE, 0, cmt, maskt, shiftt, cms, \ + masks, shifts); \ + gDPTileSync(pkt); \ + gDPSetTile(pkt, fmt, siz, (((width)*siz##_TILE_BYTES) + 7) >> 3, 0, G_TX_RENDERTILE, pal, cmt, maskt, shiftt, \ + cms, masks, shifts); \ + gDPSetTileSize(pkt, G_TX_RENDERTILE, 0, 0, ((width)-1) << G_TEXTURE_IMAGE_FRAC, \ + ((height)-1) << G_TEXTURE_IMAGE_FRAC); \ + } \ + (void)0 + #define ALIGN8(val) (((val) + 7) & ~7) #define ALIGN16(val) (((val) + 0xF) & ~0xF) +#define ALIGN64(val) (((val) + 0x3F) & ~0x3F) +#define ALIGN256(val) (((val) + 0xFF) & ~0xFF) #define SQ(x) ((x) * (x)) #define ABS(x) ((x) >= 0 ? (x) : -(x)) #define ABS_ALT(x) ((x) < 0 ? -(x) : (x)) -#define DECR(x) ((x) == 0 ? 0 : ((x) -= 1)) +#define DECR(x) ((x) == 0 ? 0 : --(x)) #define CLAMP(x, min, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) #define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) @@ -140,4 +198,13 @@ extern GraphicsContext* __gfxCtx; (b) = _temp; \ } -#endif // _MACROS_H_ +#define OVERLAY_RELOCATION_OFFSET(overlayEntry) ((uintptr_t)((overlayEntry)->vramStart) - (uintptr_t)((overlayEntry)->loadedRamAddr)) +#define VRAM_PTR_SIZE(entry) ((uintptr_t)((entry)->vramEnd) - (uintptr_t)((entry)->vramStart)) + +#ifdef __GNUC__ +#define ALIGNED8 __attribute__ ((aligned (8))) +#else +#define ALIGNED8 +#endif + +#endif // MACROS_H diff --git a/include/message_data_static.h b/include/message_data_static.h new file mode 100644 index 000000000..f69e17232 --- /dev/null +++ b/include/message_data_static.h @@ -0,0 +1,12 @@ +#ifndef MESSAGE_DATA_STATIC_H +#define MESSAGE_DATA_STATIC_H + +#include "PR/ultratypes.h" + +typedef struct MessageTableEntry{ + /* 0x0 */ u16 textId; + /* 0x2 */ u8 typePos; + /* 0x4 */ const char* segment; +} MessageTableEntry; // size = 0x8; + +#endif diff --git a/include/os.h b/include/os.h index b182d4e47..838d8234a 100644 --- a/include/os.h +++ b/include/os.h @@ -1,13 +1,33 @@ #ifndef _OS_H_ #define _OS_H_ -#include "stdlib.h" +#include "libc/stdint.h" +#include "libc/stdlib.h" #include "ultra64/thread.h" #include "ultra64/message.h" #define OS_READ 0 #define OS_WRITE 1 +/* + * I/O message types + */ +#define OS_MESG_TYPE_BASE 10 +#define OS_MESG_TYPE_LOOPBACK (OS_MESG_TYPE_BASE+0) +#define OS_MESG_TYPE_DMAREAD (OS_MESG_TYPE_BASE+1) +#define OS_MESG_TYPE_DMAWRITE (OS_MESG_TYPE_BASE+2) +#define OS_MESG_TYPE_VRETRACE (OS_MESG_TYPE_BASE+3) +#define OS_MESG_TYPE_COUNTER (OS_MESG_TYPE_BASE+4) +#define OS_MESG_TYPE_EDMAREAD (OS_MESG_TYPE_BASE+5) +#define OS_MESG_TYPE_EDMAWRITE (OS_MESG_TYPE_BASE+6) + +/* + * I/O message priority + */ +#define OS_MESG_PRI_NORMAL 0 +#define OS_MESG_PRI_HIGH 1 + + typedef u32 OSIntMask; typedef u32 OSPageMask; @@ -34,8 +54,8 @@ typedef struct { } __OSTranxInfo; // size = 0x60 -typedef struct OSPiHandle_s { - /* 0x00 */ struct OSPiHandle_s* next; +typedef struct OSPiHandle { + /* 0x00 */ struct OSPiHandle* next; /* 0x04 */ u8 type; /* 0x05 */ u8 latency; /* 0x06 */ u8 pageSize; @@ -65,7 +85,7 @@ typedef struct { typedef struct { /* 0x00 */ OSIoMesgHdr hdr; /* 0x08 */ void* dramAddr; - /* 0x0C */ u32 devAddr; + /* 0x0C */ uintptr_t devAddr; /* 0x10 */ size_t size; /* 0x14 */ OSPiHandle* piHandle; } OSIoMesg; // size = 0x88 @@ -81,10 +101,8 @@ typedef struct { /* 0x18 */ s32 (*epiDmaCallback)(OSPiHandle*, s32, u32, void*, size_t); } OSDevMgr; // size = 0x1C - typedef u64 OSTime; - typedef struct OSTimer_s { /* 0x00 */ struct OSTimer_s* next; /* 0x04 */ struct OSTimer_s* prev; @@ -94,7 +112,6 @@ typedef struct OSTimer_s { /* 0x1C */ OSMesg msg; } OSTimer; // size = 0x20 - typedef struct { /* 0x0 */ u16 type; /* 0x2 */ u8 status; diff --git a/include/os_malloc.h b/include/os_malloc.h new file mode 100644 index 000000000..6b1cceab5 --- /dev/null +++ b/include/os_malloc.h @@ -0,0 +1,35 @@ +#ifndef OS_MALLOC +#define OS_MALLOC + +#include "PR/ultratypes.h" +#include "ultra64/message.h" +#include "libc/stddef.h" + +typedef struct ArenaNode { + /* 0x0 */ s16 magic; // Should always be 0x7373 + /* 0x2 */ s16 isFree; + /* 0x4 */ size_t size; + /* 0x8 */ struct ArenaNode* next; + /* 0xC */ struct ArenaNode* prev; +} ArenaNode; // size = 0x10 + +typedef struct { + /* 0x00 */ ArenaNode* head; + /* 0x04 */ void* start; + /* 0x08 */ OSMesgQueue lock; + /* 0x20 */ u8 unk20; + /* 0x21 */ u8 isInit; + /* 0x22 */ u8 flag; +} Arena; // size = 0x24 + +void __osMallocInit(Arena* arena, void* heap, size_t size); +void __osMallocCleanup(Arena* arena); +u8 __osMallocIsInitalized(Arena* arena); +void* __osMalloc(Arena* arena, size_t size); +void* __osMallocR(Arena* arena, size_t size); +void __osFree(Arena* arena, void* ptr); +void* __osRealloc(Arena* arena, void* ptr, size_t newSize); +void __osGetSizes(Arena* arena, size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +s32 __osCheckArena(Arena* arena); + +#endif diff --git a/include/osint.h b/include/osint.h index f4da044c6..fa74a82eb 100644 --- a/include/osint.h +++ b/include/osint.h @@ -3,7 +3,7 @@ // TODO should be in libultra/os -#include "stdarg.h" +#include "libc/stdarg.h" #include "os.h" #include "os_internal.h" #include "ultraerror.h" @@ -20,4 +20,7 @@ typedef struct { /* 0x4 */ OSPri priority; } __OSThreadTail; +extern __osHwInt __osHwIntTable[]; +extern __OSEventState __osEventStateTab[]; + #endif diff --git a/include/regs.h b/include/regs.h index e39e53d69..9942242a7 100644 --- a/include/regs.h +++ b/include/regs.h @@ -1,8 +1,8 @@ /* Header taken as placeholder from OoT sister project */ /* Confirm as needed */ -#ifndef _REGS_H_ -#define _REGS_H_ +#ifndef REGS_H +#define REGS_H #define REG_GROUPS 29 // number of REG groups, i.e. REG, SREG, OREG, etc. #define REG_PAGES 6 diff --git a/include/scheduler.h b/include/scheduler.h new file mode 100644 index 000000000..3cf588b1f --- /dev/null +++ b/include/scheduler.h @@ -0,0 +1,47 @@ +#ifndef SCHEDULER_H +#define SCHEDULER_H + +#include "PR/ultratypes.h" +#include "PR/sched.h" +#include "ultra64/vi.h" +#include "ultra64/sptask.h" +#include "irqmgr.h" + +#define TASK_FRAMEBUFFER(task) ((CfbInfo*)(task)->framebuffer) + +typedef struct { + /* 0x00 */ u16* fb1; + /* 0x04 */ u16* swapBuffer; + /* 0x08 */ OSViMode* viMode; + /* 0x0C */ u32 features; + /* 0x10 */ u8 unk_10; + /* 0x11 */ s8 updateRate; + /* 0x12 */ s8 updateRate2; + /* 0x13 */ u8 unk_13; + /* 0x14 */ f32 xScale; + /* 0x18 */ f32 yScale; +} CfbInfo; // size = 0x1C + +typedef struct { + /* 0x000 */ OSMesgQueue interruptQ; + /* 0x018 */ OSMesg intBuf[64]; + /* 0x118 */ OSMesgQueue cmdQ; + /* 0x130 */ OSMesg cmdMsgBuf[8]; + /* 0x150 */ OSThread thread; + /* 0x300 */ OSScTask* audioListHead; + /* 0x304 */ OSScTask* gfxListHead; + /* 0x308 */ OSScTask* audioListTail; + /* 0x30C */ OSScTask* gfxListTail; + /* 0x310 */ OSScTask* curRSPTask; + /* 0x314 */ OSScTask* curRDPTask; + /* 0x318 */ s32 retraceCount; + /* 0x318 */ s32 doAudio; + /* 0x320 */ CfbInfo* curBuf; + /* 0x324 */ CfbInfo* pendingSwapBuf1; + /* 0x328 */ CfbInfo* pendingSwapBuf2; + /* 0x32C */ char unk_32C[0x3]; + /* 0x32F */ u8 shouldUpdateVi; + /* 0x330 */ IrqMgrClient irqClient; +} SchedContext; // size = 0x338 + +#endif diff --git a/include/segment_symbols.h b/include/segment_symbols.h index a2dc30ff3..e133437cc 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -1,7 +1,8 @@ -#ifndef _SEGMENT_SYMBOLS_H_ -#define _SEGMENT_SYMBOLS_H_ +#ifndef SEGMENT_SYMBOLS_H +#define SEGMENT_SYMBOLS_H -#include "z64.h" +#include "libc/stddef.h" +#include "PR/ultratypes.h" #define DECLARE_SEGMENT(name) \ extern u8 _##name##SegmentStart[]; \ @@ -73,7 +74,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) @@ -1161,7 +1162,9 @@ DECLARE_ROM_SEGMENT(scene_texture_07) DECLARE_ROM_SEGMENT(scene_texture_08) DECLARE_ROM_SEGMENT(nintendo_rogo_static) DECLARE_ROM_SEGMENT(title_static) +DECLARE_SEGMENT(memerrmsg) DECLARE_ROM_SEGMENT(memerrmsg) +DECLARE_SEGMENT(locerrmsg) DECLARE_ROM_SEGMENT(locerrmsg) DECLARE_ROM_SEGMENT(parameter_static) DECLARE_ROM_SEGMENT(week_static) diff --git a/include/sequence.h b/include/sequence.h new file mode 100644 index 000000000..d46e96aea --- /dev/null +++ b/include/sequence.h @@ -0,0 +1,278 @@ +#ifndef SEQUENCE_H +#define SEQUENCE_H + +#define NA_BGM_STOP 0x100000FF + +#define NA_BGM_GENERAL_SFX 0x00 // General Sound Effects +#define NA_BGM_NATURE_AMBIENCE 0x01 // Ambient background noises +#define NA_BGM_TERMINA_FIELD 0x02 // Termina Field +#define NA_BGM_CHASE 0x03 // Forest Chase +#define NA_BGM_MAJORAS_THEME 0x04 // Majora's Theme "STALKID" +#define NA_BGM_CLOCK_TOWER 0x05 // The Clock Tower +#define NA_BGM_STONE_TOWER_TEMPLE 0x06 // Stone Tower Temple +#define NA_BGM_INV_STONE_TOWER_TEMPLE 0x07 // Stone Tower Temple Inverted +#define NA_BGM_FAILURE_0 0x08 // Missed Event 1 +#define NA_BGM_FAILURE_1 0x09 // Title +#define NA_BGM_HAPPY_MASK_SALESMAN 0x0A // Mask Salesman "OMENYA" +#define NA_BGM_SONG_OF_HEALING 0x0B // Song of Healing "DEMO_CURE" +#define NA_BGM_SWAMP_REGION 0x0C // Southern Swamp and Woodfall "DAMP_AREA" +#define NA_BGM_ALIEN_INVASION 0x0D // Ghost Attack "UFO" +#define NA_BGM_SWAMP_CRUISE 0x0E // Mini Game "JUNGLE_CREWS" +#define NA_BGM_SHARPS_CURSE 0x0F // Sharp's Curse +#define NA_BGM_GREAT_BAY_REGION 0x10 // Great Bay Coast "SEA_AREA" +#define NA_BGM_IKANA_REGION 0x11 // Ikana Valley +#define NA_BGM_DEKU_KING 0x12 // Court of the Deku King +#define NA_BGM_MOUNTAIN_REGION 0x13 // Mountain Village "SNOW_AREA" +#define NA_BGM_PIRATES_FORTRESS 0x14 // Pirates' Fortress "PIRATE_AREA" +#define NA_BGM_CLOCK_TOWN_DAY_1 0x15 // Clock Town Day 1 This song's filename is dummied out in MM3D "DUMMY_21" +#define NA_BGM_CLOCK_TOWN_DAY_2 0x16 // Clock Town Day 2 his song's filename is dummied out in MM3D "DUMMY_22" +#define NA_BGM_CLOCK_TOWN_DAY_3 0x17 // Clock Town Day 3 This song's filename is dummied out in MM3D "DUMMY_23" +#define NA_BGM_FILE_SELECT 0x18 // This song has no track name, as it's a duplicate of the Fairy's Fountain +#define NA_BGM_CLEAR_EVENT 0x19 // Event Clear +#define NA_BGM_ENEMY 0x1A // Battle +#define NA_BGM_BOSS 0x1B // Boss Battle +#define NA_BGM_WOODFALL_TEMPLE 0x1C // Woodfall Temple "JUNGLE_DUNGEON" +#define NA_BGM_MARKET 0x1D // Clock Town Day 1 Duplicate of #15. Interesting filename in MM3D. ✘ +#define NA_BGM_OPENING 0x1E // Forest Ambush +#define NA_BGM_INSIDE_A_HOUSE 0x1F // House "LINK_HOUSE" +#define NA_BGM_GAME_OVER 0x20 // Game Over +#define NA_BGM_CLEAR_BOSS 0x21 // Boss Clear +#define NA_BGM_GET_ITEM 0x22 // Item Catch +#define NA_BGM_GATE_OPEN 0x23 // Clock Town Day 2 Duplicate of #16. In MM3D, it shares its filename with the Door of Time song from OoT +#define NA_BGM_GET_HEART 0x24 // Complete a Heart Piece +#define NA_BGM_MINI_GAME_2 0x25 // Playing Minigame +#define NA_BGM_GORON_RACE 0x26 // Goron Race +#define NA_BGM_MUSIC_BOX_HOUSE 0x27 // Music Box House "ORGEL_HOUSE" +#define NA_BGM_FAIRY_FOUNTAIN 0x28 // Fairy's Fountain In MM3D, it shares its filename with the Door of Time song from OoT "GODESS" +#define NA_BGM_ZELDAS_LULLABY 0x29 // Zelda's Lullaby "HIME" +#define NA_BGM_ROSA_SISTERS 0x2A // Rosa Sisters' Dance "SISTER_DANCER" +#define NA_BGM_OPEN_CHEST 0x2B // Open Chest "OPEN_TRE_BOX" +#define NA_BGM_MARINE_RESEARCH_LAB 0x2C // Marine Research Laboratory "DRUGSTORE" +#define NA_BGM_GIANTS_THEME 0x2D // The Four Giants "KYOJIN_ROOM" +#define NA_BGM_SONG_OF_STORMS 0x2E // Guru-Guru's Song "FUSHA" +#define NA_BGM_ROMANI_RANCH 0x2F // Romani Ranch "RONRON" +#define NA_BGM_GORON_VILLAGE 0x30 // Goron Village +#define NA_BGM_MAYORS_OFFICE 0x31 // Mayor Dotour "MEETING" +#define NA_BGM_OCA_EPONA 0x32 // Ocarina Epona's Song +#define NA_BGM_OCA_SUNS 0x33 // Ocarina Sun's Song +#define NA_BGM_OCA_TIME 0x34 // Ocarina Song of Time "TIME_NORMAL" +#define NA_BGM_OCA_STORM 0x35 // Ocarina Song of Storms +#define NA_BGM_ZORA_HALL 0x36 // Zora Hall +#define NA_BGM_GET_NEW_MASK 0x37 // A New Mask +#define NA_BGM_MINI_BOSS 0x38 // Mini Boss "MIDDLE_BOSS" +#define NA_BGM_GET_SMALL_ITEM 0x39 // Small Item Catch "S_ITEM_GET" +#define NA_BGM_ASTRAL_OBSERVATORY 0x3A // Astral Observatory "TENMONDAI" +#define NA_BGM_CAVERN 0x3B // Clock Town Cavern "NORMAL_DUNGEON" +#define NA_BGM_MILK_BAR 0x3C // Milk Bar Latte +#define NA_BGM_ZELDA_APPEAR 0x3D // Meet Zelda (OoT) +#define NA_BGM_SARIAS_SONG 0x3E // Saria's Theme Song from OoT "MAYOIMORI" +#define NA_BGM_GORON_GOAL 0x3F // Goron Race Goal +#define NA_BGM_HORSE 0x40 // Gorman Race +#define NA_BGM_HORSE_GOAL 0x41 // Race Finish +#define NA_BGM_INGO 0x42 // Gorman Bros. "INGO" +#define NA_BGM_KOTAKE_POTION_SHOP 0x43 // Kotake's Potion Shop "KOTAKE_KOUME" +#define NA_BGM_SHOP 0x44 // Store +#define NA_BGM_OWL 0x45 // Gaebora's Theme +#define NA_BGM_MINI_GAME 0x46 // Target Practice +#define NA_BGM_OCA_SOARING 0x47 // Ocarina Song of Soaring "OCA_BIGWING" +#define NA_BGM_OCA_HEALING 0x48 // Ocarina Song of Healing "OCA_CURE" +#define NA_BGM_INVERTED_SONG_OF_TIME 0x49 // Inverted Song of Time "_SPEED" +#define NA_BGM_SONG_OF_DOUBLE_TIME 0x4A // Song of Double Time "TIME_JUMP" +#define NA_BGM_SONATA_OF_AWAKENING 0x4B // Sonata of Awakening "DEMO_AWAKING" +#define NA_BGM_GORON_LULLABY 0x4C // Goron Lullaby "DEMO_LULLABY" +#define NA_BGM_NEW_WAVE_BOSSA_NOVA 0x4D // New Wave Bossa Nova "DEMO_TIDE" +#define NA_BGM_ELEGY_OF_EMPTINESS 0x4E // Elegy of Emptiness "DEMO_SHELL" +#define NA_BGM_OATH_TO_ORDER 0x4F // Oath to Order "DEMO_PLEDGE" +#define NA_BGM_SWORD_TRAINING_HALL 0x50 // Sword Training "EXERCISE_HALL" +#define NA_BGM_GORON_LULLABY_INTRO 0x51 // Ocarina Goron Lullaby Intro "DEMO_LULLABY_HALF" +#define NA_BGM_OCA_FAIRY 0x52 // New Song "OCA_YOUSEI" +#define NA_BGM_BREMEN_MARCH 0x53 // Bremen March "FACEMASK" +#define NA_BGM_BALLAD_OF_THE_WIND_FISH 0x54 // Quartet performed in on the milk bar stage "QUARTET" +#define NA_BGM_SONG_OF_SOARING 0x55 // Song of Soaring "WING_WARP" +#define NA_BGM_MILK_BAR_DUPLICATE 0x56 // Milk Bar Latte Duplicate. "MILK_BAR_DUMMY" +#define NA_BGM_FINAL_HOURS 0x57 // Final Hours "TIME_LIMIT" +#define NA_BGM_MIKAU_RIFF 0x58 // Mikau's Tale "MIKAU_LIFF" +#define NA_BGM_MIKAU_FINALE 0x59 // A single guitar chord. "MIKAU_FIN" +#define NA_BGM_FROG_SONG 0x5A // Don Gero's Song +#define NA_BGM_OCA_SONATA 0x5B // Ocarina Sonata of Awakening "OCA_AWAKING" +#define NA_BGM_OCA_LULLABY 0x5C // Ocarina Goron Lullaby "OCA_LULLABY" +#define NA_BGM_OCA_NEW_WAVE 0x5D // Ocarina New Wave Bossa Nova "OCA_TIDE" +#define NA_BGM_OCA_ELEGY 0x5E // Ocarina Elegy of Emptiness "OCA_SHELL" +#define NA_BGM_OCA_OATH 0x5F // Ocarina Oath to Order "OCA_PLEDGE" +#define NA_BGM_MAJORAS_LAIR 0x60 // "LAST_DUNGEON" +#define NA_BGM_OCA_LULLABY_INTRO 0x61 // "OCA_LULLABY_HALF" +#define NA_BGM_OCA_GUITAR_BASS_SESSION 0x62 // Bass and Guitar Session "OCA_SESSION" +#define NA_BGM_PIANO_SESSION 0x63 // Piano Solo "DEMO_SESSION" +#define NA_BGM_INDIGO_GO_SESSION 0x64 // The Indigo-Go's Rehearsal "ALLPART_SESSION" +#define NA_BGM_SNOWHEAD_TEMPLE 0x65 // Snowhead Temple "SILVER_DUNGEON" +#define NA_BGM_GREAT_BAY_TEMPLE 0x66 // Great Bay Temple "DEEPBLUE_DUNGEON" +#define NA_BGM_NEW_WAVE_SAXOPHONE 0x67 // "DEMO_TIDE_SAX" +#define NA_BGM_NEW_WAVE_VOCAL 0x68 // "DEMO_TIDE_VOCAL" +#define NA_BGM_MAJORAS_WRATH 0x69 // Majora's Wrath "MUJURA_1" +#define NA_BGM_MAJORAS_INCARNATION 0x6A // Majora's Incarnation "MUJURA_2" +#define NA_BGM_MAJORAS_MASK 0x6B // Majora's Mask Battle "MUJURA_3" +#define NA_BGM_BASS_PLAY 0x6C // Bass Practice "BASS_PLAY" +#define NA_BGM_DRUMS_PLAY 0x6D // Drums Practice "DRUMS_PLAY" +#define NA_BGM_PIANO_PLAY 0x6E // Piano Practice "PIANO_PLAY" +#define NA_BGM_IKANA_CASTLE 0x6F // Ikana Castle +#define NA_BGM_GATHERING_GIANTS 0x70 // Calling the Four Giants +#define NA_BGM_KAMARO_DANCE 0x71 // Kamaro's Dance "CAMARO_DANCE" +#define NA_BGM_CREMIA_CARRIAGE 0x72 // Cremia's Carriage "DONKEY_CART" +#define NA_BGM_KEATON_QUIZ 0x73 // Keaton "QUIZ" +#define NA_BGM_END_CREDITS_1 0x74 // The End/Credits I "END_DEMO" +#define NA_BGM_OPENING_LOOP 0x75 // Forest Ambush (?) Duplicate. +#define NA_BGM_TITLE_THEME 0x76 // Title Screen +#define NA_BGM_DUNGEON_APPEAR 0x77 // Surfacing of Woodfall +#define NA_BGM_WOODFALL_CLEAR 0x78 // Woodfall Clear "PURIFICATION_0" +#define NA_BGM_SNOWHEAD_CLEAR 0x79 // Snowhead Clear "PURIFICATION_1" +#define NA_BGM_INTO_THE_MOON 0x7B // To the Moon +#define NA_BGM_GOODBYE_GIANT 0x7C // +#define NA_BGM_TATL_AND_TAEL 0x7D // Tatl and Tael "CHAT" +#define NA_BGM_MOONS_DESTRUCTION 0x7E // Moon's Destruction "MOON_VANISH" +#define NA_BGM_NO_MUSIC 0x7F // +#define NA_BGM_END_CREDITS_2 0x82 // The End/Credits II "STAFFROLL2" +#define NA_BGM_DISABLED 0xFFFF + +typedef enum { + /* 0 */ SEQ_PLAYER_BGM_MAIN, + /* 1 */ SEQ_PLAYER_FANFARE, + /* 2 */ SEQ_PLAYER_SFX, + /* 3 */ SEQ_PLAYER_BGM_SUB, + /* 4 */ SEQ_PLAYER_NATURE +} SequencePlayerId; + +typedef enum { + /* 0 */ SEQ_MODE_DEFAULT, + /* 1 */ SEQ_MODE_ENEMY, + /* 2 */ SEQ_MODE_STILL, // Not moving or first-person view + /* 3 */ SEQ_MODE_IGNORE +} SequenceMode; + +typedef enum { + /* 0x0 */ CHANNEL_IO_PORT_0, + /* 0x1 */ CHANNEL_IO_PORT_1, + /* 0x2 */ CHANNEL_IO_PORT_2, + /* 0x3 */ CHANNEL_IO_PORT_3, + /* 0x4 */ CHANNEL_IO_PORT_4, + /* 0x5 */ CHANNEL_IO_PORT_5, + /* 0x6 */ CHANNEL_IO_PORT_6, + /* 0x7 */ CHANNEL_IO_PORT_7 +} ChannelIOPort; + +typedef enum { + /* 0x0 */ NATURE_CHANNEL_STREAM_0, + /* 0x1 */ NATURE_CHANNEL_CRITTER_0, + /* 0x2 */ NATURE_CHANNEL_CRITTER_1, + /* 0x3 */ NATURE_CHANNEL_CRITTER_2, + /* 0x4 */ NATURE_CHANNEL_CRITTER_3, + /* 0x5 */ NATURE_CHANNEL_CRITTER_4, + /* 0x6 */ NATURE_CHANNEL_CRITTER_5, + /* 0x7 */ NATURE_CHANNEL_CRITTER_6, + /* 0x8 */ NATURE_CHANNEL_CRITTER_7, + /* 0xC */ NATURE_CHANNEL_STREAM_1 = 12, + /* 0xD */ NATURE_CHANNEL_UNK, + /* 0xE */ NATURE_CHANNEL_RAIN, + /* 0xF */ NATURE_CHANNEL_LIGHTNING +} NatureChannelIdx; // playerIdx = 4 + +typedef enum { + /* 0x00 */ NATURE_AMBIENCE_0, + /* 0x01 */ NATURE_AMBIENCE_1, + /* 0x02 */ NATURE_AMBIENCE_2, + /* 0x03 */ NATURE_AMBIENCE_3, + /* 0x04 */ NATURE_AMBIENCE_4, + /* 0x05 */ NATURE_AMBIENCE_5, + /* 0x06 */ NATURE_AMBIENCE_6, + /* 0x07 */ NATURE_AMBIENCE_7, + /* 0x08 */ NATURE_AMBIENCE_8, + /* 0x09 */ NATURE_AMBIENCE_9, + /* 0x0A */ NATURE_AMBIENCE_A, + /* 0x0B */ NATURE_AMBIENCE_B, + /* 0x0C */ NATURE_AMBIENCE_C, + /* 0x0D */ NATURE_AMBIENCE_D, + /* 0x0E */ NATURE_AMBIENCE_E, + /* 0x0F */ NATURE_AMBIENCE_F, + /* 0x10 */ NATURE_AMBIENCE_10, + /* 0x11 */ NATURE_AMBIENCE_11, + /* 0x12 */ NATURE_AMBIENCE_12, + /* 0x13 */ NATURE_AMBIENCE_13 +} NatureAmbienceId; // playerIdx = 4 + +typedef enum { + /* 0x00 */ NATURE_STREAM_0, + /* 0x01 */ NATURE_STREAM_1, + /* 0x02 */ NATURE_STREAM_2, + /* 0x03 */ NATURE_STREAM_3 +} NatureStreamId; + +typedef enum { + /* 0x00 */ NATURE_CRITTER_00, + /* 0x01 */ NATURE_CRITTER_01, + /* 0x02 */ NATURE_CRITTER_02, + /* 0x03 */ NATURE_CRITTER_03, + /* 0x04 */ NATURE_CRITTER_04, + /* 0x05 */ NATURE_CRITTER_05, + /* 0x06 */ NATURE_CRITTER_06, + /* 0x07 */ NATURE_CRITTER_07, + /* 0x08 */ NATURE_CRITTER_08, + /* 0x09 */ NATURE_CRITTER_09, + /* 0x0A */ NATURE_CRITTER_10, + /* 0x0B */ NATURE_CRITTER_11, + /* 0x0C */ NATURE_CRITTER_12, + /* 0x0D */ NATURE_CRITTER_13, + /* 0x0E */ NATURE_CRITTER_14, + /* 0x0F */ NATURE_CRITTER_15, + /* 0x10 */ NATURE_CRITTER_16, + /* 0x11 */ NATURE_CRITTER_17, + /* 0x12 */ NATURE_CRITTER_18, + /* 0x13 */ NATURE_CRITTER_19 +} NatureAmimalId; + +#define NATURE_IO_CRITTER_0_TYPE(type) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_0_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_0_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_0_PORT5(reverb) NATURE_CHANNEL_CRITTER_0, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_1_TYPE(type) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_1_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_1_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_1_PORT5(reverb) NATURE_CHANNEL_CRITTER_1, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_2_TYPE(type) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_2_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_2_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_2_PORT5(reverb) NATURE_CHANNEL_CRITTER_2, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_3_TYPE(type) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_3_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_3_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_3_PORT5(reverb) NATURE_CHANNEL_CRITTER_3, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_4_TYPE(type) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_4_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_4_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_4_PORT5(reverb) NATURE_CHANNEL_CRITTER_4, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_5_TYPE(type) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_5_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_5_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_5_PORT5(reverb) NATURE_CHANNEL_CRITTER_5, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_CRITTER_6_TYPE(type) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_2, type +#define NATURE_IO_CRITTER_6_BEND_PITCH(bend) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_3, bend +#define NATURE_IO_CRITTER_6_NUM_LAYERS(num) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_4, num +#define NATURE_IO_CRITTER_6_PORT5(reverb) NATURE_CHANNEL_CRITTER_6, CHANNEL_IO_PORT_5, reverb + +#define NATURE_IO_STREAM_0_TYPE(type) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_2, type +#define NATURE_IO_STREAM_0_PORT3(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_3, data +#define NATURE_IO_STREAM_0_PORT4(data) NATURE_CHANNEL_STREAM_0, CHANNEL_IO_PORT_4, data + +#define NATURE_IO_STREAM_1_TYPE(type) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_2, type +#define NATURE_IO_STREAM_1_PORT3(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_3, data +#define NATURE_IO_STREAM_1_PORT4(data) NATURE_CHANNEL_STREAM_1, CHANNEL_IO_PORT_4, data + +#define NATURE_IO_RAIN_PORT4(data) NATURE_CHANNEL_RAIN, CHANNEL_IO_PORT_4, data + +#define NATURE_IO_ENTRIES_END 0xFF + +#endif diff --git a/include/sys_matrix.h b/include/sys_matrix.h new file mode 100644 index 000000000..536322624 --- /dev/null +++ b/include/sys_matrix.h @@ -0,0 +1,81 @@ +#ifndef SYS_MATRIX_H +#define SYS_MATRIX_H + +#include "z64math.h" + + +struct GraphicsContext; +struct GameState; + + +typedef enum { + /* 0 */ MTXMODE_NEW, // generates a new matrix + /* 1 */ MTXMODE_APPLY // applies transformation to the current matrix +} MatrixMode; + + +extern Mtx gIdentityMtx; +extern MtxF gIdentityMtxF; + + +/* Stack operations */ + +void Matrix_Init(struct GameState* gameState); +void Matrix_Push(void); +void Matrix_Pop(void); +void Matrix_Get(MtxF* dest); +void Matrix_Put(MtxF* src); +MtxF* Matrix_GetCurrent(void); + +/* Basic operations */ + +void Matrix_Mult(MtxF* matrix, MatrixMode mode); +void Matrix_Translate(f32 x, f32 y, f32 z, MatrixMode mode); +void Matrix_Scale(f32 x, f32 y, f32 z, MatrixMode mode); +void Matrix_RotateXS(s16 x, MatrixMode mode); +void Matrix_RotateXF(f32 x, MatrixMode mode); +void Matrix_RotateXFApply(f32 x); +void Matrix_RotateXFNew(f32 x); +void Matrix_RotateYS(s16 y, MatrixMode mode); +void Matrix_RotateYF(f32 y, MatrixMode mode); +void Matrix_RotateZS(s16 z, MatrixMode mode); +void Matrix_RotateZF(f32 z, MatrixMode mode); + +/* Compound operations */ + +void Matrix_RotateZYX(s16 x, s16 y, s16 z, MatrixMode mode); +void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rot); +void Matrix_SetTranslateRotateYXZ(f32 x, f32 y, f32 z, Vec3s* rot); + +/* Conversion and allocation operations */ + +Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest); +Mtx* Matrix_ToMtx(Mtx* dest); +Mtx* Matrix_NewMtx(struct GraphicsContext* gfxCtx); +Mtx* Matrix_MtxFToNewMtx(MtxF* src, struct GraphicsContext* gfxCtx); + +/* Vector operations */ + +void Matrix_MultVec3f(Vec3f* src, Vec3f* dest); +void Matrix_MultZero(Vec3f* dest); +void Matrix_MultVecX(f32 x, Vec3f* dest); +void Matrix_MultVecY(f32 y, Vec3f* dest); +void Matrix_MultVecZ(f32 z, Vec3f* dest); +void Matrix_MultVec3fXZ(Vec3f* src, Vec3f* dest); + +/* Copy and another conversion */ + +void Matrix_MtxFCopy(MtxF* dest, MtxF* src); +void Matrix_MtxToMtxF(Mtx* src, MtxF* dest); + +/* Miscellaneous */ + +void Matrix_MultVec3fExt(Vec3f* src, Vec3f* dest, MtxF* mf); +void Matrix_Transpose(MtxF* mf); +void Matrix_ReplaceRotation(MtxF* mf); +void Matrix_MtxFToYXZRot(MtxF* src, Vec3s* dest, s32 nonUniformScale); +void Matrix_MtxFToZYXRot(MtxF* src, Vec3s* dest, s32 nonUniformScale); +void Matrix_RotateAxisF(f32 angle, Vec3f* axis, MatrixMode mode); +void Matrix_RotateAxisS(s16 angle, Vec3f* axis, MatrixMode mode); + +#endif diff --git a/include/system_malloc.h b/include/system_malloc.h new file mode 100644 index 000000000..e92eaf89f --- /dev/null +++ b/include/system_malloc.h @@ -0,0 +1,20 @@ +#ifndef SYSTEM_MALLOC +#define SYSTEM_MALLOC + +#include "PR/ultratypes.h" +#include "os_malloc.h" + +void* SystemArena_Malloc(size_t size); +void* SystemArena_MallocR(size_t size); +void* SystemArena_Realloc(void* oldPtr, size_t newSize); +void SystemArena_Free(void* ptr); +void* SystemArena_Calloc(u32 elements, size_t size); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated); +u32 SystemArena_CheckArena(void); +void SystemArena_InitArena(void* start, size_t size); +void SystemArena_Cleanup(void); +u8 SystemArena_IsInitialized(void); + +extern Arena gSystemArena; + +#endif diff --git a/include/ultra64.h b/include/ultra64.h index d309026b9..49323cc2b 100644 --- a/include/ultra64.h +++ b/include/ultra64.h @@ -11,6 +11,7 @@ #include "ultra64/sptask.h" #include "ultra64/thread.h" #include "ultra64/rcp.h" +#include "ultra64/rdp.h" #include "ultra64/rsp.h" #include "ultra64/vi.h" diff --git a/include/convert.h b/include/ultra64/convert.h similarity index 91% rename from include/convert.h rename to include/ultra64/convert.h index 456e4b198..59d8b801c 100644 --- a/include/convert.h +++ b/include/ultra64/convert.h @@ -1,7 +1,7 @@ -#ifndef _ULTRA64_CONVERT_H_ -#define _ULTRA64_CONVERT_H_ +#ifndef ULTRA64_CONVERT_H +#define ULTRA64_CONVERT_H -#include "stdint.h" +#include "libc/stdint.h" #define OS_CLOCK_RATE 62500000LL #define OS_CPU_COUNTER (OS_CLOCK_RATE*3/4) diff --git a/include/ultra64/gs2dex.h b/include/ultra64/gs2dex.h new file mode 100644 index 000000000..5c0bc7175 --- /dev/null +++ b/include/ultra64/gs2dex.h @@ -0,0 +1,379 @@ +#ifndef GS2DEX_H +#define GS2DEX_H + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +/*===========================================================================* + * Macro + *===========================================================================*/ +#define GS_CALC_DXT(line) (((1<< G_TX_DXT_FRAC)-1)/(line)+1) +#define GS_PIX2TMEM(pix, siz) ((pix)>>(4-(siz))) +#define GS_PIX2DXT(pix, siz) GS_CALC_DXT(GS_PIX2TMEM((pix), (siz))) + +/*===========================================================================* + * Data structures for S2DEX microcode + *===========================================================================*/ + +/*---------------------------------------------------------------------------* + * Background + *---------------------------------------------------------------------------*/ +#define G_BGLT_LOADBLOCK 0x0033 +#define G_BGLT_LOADTILE 0xfff4 + +#define G_BG_FLAG_FLIPS 0x01 +#define G_BG_FLAG_FLIPT 0x10 + +/* Non scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of the texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of the texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64 *imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* which to use, LoadBlock or LoadTile */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + /* The following is set in the initialization routine guS2DInitBg(). There is no need for the user to set it. */ + u16 tmemW; /* TMEM width and Word size of frame 1 line. + At LoadBlock, GS_PIX2TMEM(imageW/4,imageSiz) + At LoadTile GS_PIX2TMEM(frameW/4,imageSiz)+1 */ + u16 tmemH; /* height of TMEM loadable at a time (s13.2) 4 times value + When the normal texture, 512/tmemW*4 + When the CI texture, 256/tmemW*4 */ + u16 tmemLoadSH; /* SH value + At LoadBlock, tmemSize/2-1 + At LoadTile, tmemW*16-1 */ + u16 tmemLoadTH; /* TH value or Stride value + At LoadBlock, GS_CALC_DXT(tmemW) + At LoadTile, tmemH-1 */ + u16 tmemSizeW; /* skip value of imagePtr for image 1-line + At LoadBlock, tmemW*2 + At LoadTile, GS_PIX2TMEM(imageW/4,imageSiz)*2 */ + u16 tmemSize; /* skip value of imagePtr for 1-loading + = tmemSizeW*tmemH */ +} uObjBg_t; /* 40 bytes */ + +/* Scalable background plane */ +typedef struct { + u16 imageX; /* x-coordinate of upper-left position of texture (u10.5) */ + u16 imageW; /* width of texture (u10.2) */ + s16 frameX; /* upper-left position of transferred frame (s10.2) */ + u16 frameW; /* width of transferred frame (u10.2) */ + + u16 imageY; /* y-coordinate of upper-left position of texture (u10.5) */ + u16 imageH; /* height of texture (u10.2) */ + s16 frameY; /* upper-left position of transferred frame (s10.2) */ + u16 frameH; /* height of transferred frame (u10.2) */ + + u64 *imagePtr; /* texture source address on DRAM */ + u16 imageLoad; /* Which to use, LoadBlock or LoadTile? */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u16 imagePal; /* pallet number */ + u16 imageFlip; /* right & left image inversion (Inverted by G_BG_FLAG_FLIPS) */ + + u16 scaleW; /* scale value of X-direction (u5.10) */ + u16 scaleH; /* scale value of Y-direction (u5.10) */ + s32 imageYorig; /* start point of drawing on image (s20.5) */ + + u8 padding[4]; + +} uObjScaleBg_t; /* 40 bytes */ + +typedef union { + uObjBg_t b; + uObjScaleBg_t s; + long long int force_structure_alignment; +} uObjBg; + +/*---------------------------------------------------------------------------* + * 2D Objects + *---------------------------------------------------------------------------*/ +#define G_OBJ_FLAG_FLIPS 1<<0 /* inversion to S-direction */ +#define G_OBJ_FLAG_FLIPT 1<<4 /* nversion to T-direction */ + +typedef struct { + s16 objX; /* s10.2 OBJ x-coordinate of upper-left end */ + u16 scaleW; /* u5.10 Scaling of u5.10 width direction */ + u16 imageW; /* u10.5 width of u10.5 texture (length of S-direction) */ + u16 paddingX; /* Unused - Always 0 */ + s16 objY; /* s10.2 OBJ y-coordinate of s10.2 OBJ upper-left end */ + u16 scaleH; /* u5.10 Scaling of u5.10 height direction */ + u16 imageH; /* u10.5 height of u10.5 texture (length of T-direction) */ + u16 paddingY; /* Unused - Always 0 */ + u16 imageStride; /* folding width of texel (In units of 64bit word) */ + u16 imageAdrs; /* texture header position in TMEM (In units of 64bit word) */ + u8 imageFmt; /* format of texel - G_IM_FMT_* */ + u8 imageSiz; /* size of texel - G_IM_SIZ_* */ + u8 imagePal; /* pallet number (0-7) */ + u8 imageFlags; /* The display flag - G_OBJ_FLAG_FLIP* */ +} uObjSprite_t; /* 24 bytes */ + +typedef union { + uObjSprite_t s; + long long int force_structure_alignment; +} uObjSprite; + +/*---------------------------------------------------------------------------* + * 2D Matrix + *---------------------------------------------------------------------------*/ +typedef struct { + s32 A, B, C, D; /* s15.16 */ + s16 X, Y; /* s10.2 */ + u16 BaseScaleX; /* u5.10 */ + u16 BaseScaleY; /* u5.10 */ +} uObjMtx_t; /* 24 bytes */ + +typedef union { + uObjMtx_t m; + long long int force_structure_alignment; +} uObjMtx; + +typedef struct { + s16 X, Y; /* s10.2 */ + u16 BaseScaleX; /* u5.10 */ + u16 BaseScaleY; /* u5.10 */ +} uObjSubMtx_t; /* 8 bytes */ + +typedef union { + uObjSubMtx_t m; + long long int force_structure_alignment; +} uObjSubMtx; + +/*---------------------------------------------------------------------------* + * Loading into TMEM + *---------------------------------------------------------------------------*/ +#define G_OBJLT_TXTRBLOCK 0x00001033 +#define G_OBJLT_TXTRTILE 0x00fc1034 +#define G_OBJLT_TLUT 0x00000030 + +#define GS_TB_TSIZE(pix,siz) (GS_PIX2TMEM((pix),(siz))-1) +#define GS_TB_TLINE(pix,siz) (GS_CALC_DXT(GS_PIX2TMEM((pix),(siz)))) + +typedef struct { + u32 type; /* G_OBJLT_TXTRBLOCK divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 tmem; /* loaded TMEM word address (8byteWORD) */ + u16 tsize; /* Texture size, Specified by macro GS_TB_TSIZE() */ + u16 tline; /* width of Texture 1-line, Specified by macro GS_TB_TLINE() */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12) */ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrBlock_t; /* 24 bytes */ + +#define GS_TT_TWIDTH(pix,siz) ((GS_PIX2TMEM((pix), (siz))<<2)-1) +#define GS_TT_THEIGHT(pix,siz) (((pix)<<2)-1) + +typedef struct { + u32 type; /* G_OBJLT_TXTRTILE divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 tmem; /* loaded TMEM word address (8byteWORD)*/ + u16 twidth; /* width of Texture (Specified by macro GS_TT_TWIDTH()) */ + u16 theight; /* height of Texture (Specified by macro GS_TT_THEIGHT()) */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12) */ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrTile_t; /* 24 bytes */ + +#define GS_PAL_HEAD(head) ((head)+256) +#define GS_PAL_NUM(num) ((num)-1) + +typedef struct { + u32 type; /* G_OBJLT_TLUT divided into types */ + u64 *image; /* texture source address on DRAM */ + u16 phead; /* pallet number of load header (Between 256 and 511) */ + u16 pnum; /* loading pallet number -1 */ + u16 zero; /* Assign 0 all the time */ + u16 sid; /* STATE ID Multipled by 4 (Either one of 0, 4, 8 and 12)*/ + u32 flag; /* STATE flag */ + u32 mask; /* STATE mask */ +} uObjTxtrTLUT_t; /* 24 bytes */ + +typedef union { + uObjTxtrBlock_t block; + uObjTxtrTile_t tile; + uObjTxtrTLUT_t tlut; + long long int force_structure_alignment; +} uObjTxtr; + +/*---------------------------------------------------------------------------* + * Loading into TMEM & 2D Objects + *---------------------------------------------------------------------------*/ +typedef struct { + uObjTxtr txtr; + uObjSprite sprite; +} uObjTxSprite; /* 48 bytes */ + +/*===========================================================================* + * GBI Commands for S2DEX microcode + *===========================================================================*/ +/* GBI Header */ +#ifdef F3DEX_GBI_2 +#define G_OBJ_RECTANGLE_R 0xda +#define G_OBJ_MOVEMEM 0xdc +#define G_RDPHALF_0 0xe4 +#define G_OBJ_RECTANGLE 0x01 +#define G_OBJ_SPRITE 0x02 +#define G_SELECT_DL 0x04 +#define G_OBJ_LOADTXTR 0x05 +#define G_OBJ_LDTX_SPRITE 0x06 +#define G_OBJ_LDTX_RECT 0x07 +#define G_OBJ_LDTX_RECT_R 0x08 +#define G_BG_1CYC 0x09 +#define G_BG_COPY 0x0a +#define G_OBJ_RENDERMODE 0x0b +#else +#define G_BG_1CYC 0x01 +#define G_BG_COPY 0x02 +#define G_OBJ_RECTANGLE 0x03 +#define G_OBJ_SPRITE 0x04 +#define G_OBJ_MOVEMEM 0x05 +#define G_SELECT_DL 0xb0 +#define G_OBJ_RENDERMODE 0xb1 +#define G_OBJ_RECTANGLE_R 0xb2 +#define G_OBJ_LOADTXTR 0xc1 +#define G_OBJ_LDTX_SPRITE 0xc2 +#define G_OBJ_LDTX_RECT 0xc3 +#define G_OBJ_LDTX_RECT_R 0xc4 +#define G_RDPHALF_0 0xe4 +#endif + +/*---------------------------------------------------------------------------* + * Background wrapped screen + *---------------------------------------------------------------------------*/ +#define gSPBgRectangle(pkt, m, mptr) gDma0p((pkt),(m),(mptr),0) +#define gsSPBgRectangle(m, mptr) gsDma0p( (m),(mptr),0) +#define gSPBgRectCopy(pkt, mptr) gSPBgRectangle((pkt), G_BG_COPY, (mptr)) +#define gsSPBgRectCopy(mptr) gsSPBgRectangle( G_BG_COPY, (mptr)) +#define gSPBgRect1Cyc(pkt, mptr) gSPBgRectangle((pkt), G_BG_1CYC, (mptr)) +#define gsSPBgRect1Cyc(mptr) gsSPBgRectangle( G_BG_1CYC, (mptr)) + +/*---------------------------------------------------------------------------* + * 2D Objects + *---------------------------------------------------------------------------*/ +#define gSPObjSprite(pkt, mptr) gDma0p((pkt),G_OBJ_SPRITE, (mptr),0) +#define gsSPObjSprite(mptr) gsDma0p( G_OBJ_SPRITE, (mptr),0) +#define gSPObjRectangle(pkt, mptr) gDma0p((pkt),G_OBJ_RECTANGLE, (mptr),0) +#define gsSPObjRectangle(mptr) gsDma0p( G_OBJ_RECTANGLE, (mptr),0) +#define gSPObjRectangleR(pkt, mptr) gDma0p((pkt),G_OBJ_RECTANGLE_R,(mptr),0) +#define gsSPObjRectangleR(mptr) gsDma0p( G_OBJ_RECTANGLE_R,(mptr),0) + +/*---------------------------------------------------------------------------* + * 2D Matrix + *---------------------------------------------------------------------------*/ +#define gSPObjMatrix(pkt, mptr) gDma1p((pkt),G_OBJ_MOVEMEM,(mptr),0,23) +#define gsSPObjMatrix(mptr) gsDma1p( G_OBJ_MOVEMEM,(mptr),0,23) +#define gSPObjSubMatrix(pkt, mptr) gDma1p((pkt),G_OBJ_MOVEMEM,(mptr),2, 7) +#define gsSPObjSubMatrix(mptr) gsDma1p( G_OBJ_MOVEMEM,(mptr),2, 7) + +/*---------------------------------------------------------------------------* + * Loading into TMEM + *---------------------------------------------------------------------------*/ +#define gSPObjLoadTxtr(pkt, tptr) gDma0p((pkt),G_OBJ_LOADTXTR, (tptr),23) +#define gsSPObjLoadTxtr(tptr) gsDma0p( G_OBJ_LOADTXTR, (tptr),23) +#define gSPObjLoadTxSprite(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_SPRITE,(tptr),47) +#define gsSPObjLoadTxSprite(tptr) gsDma0p( G_OBJ_LDTX_SPRITE,(tptr),47) +#define gSPObjLoadTxRect(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_RECT, (tptr),47) +#define gsSPObjLoadTxRect(tptr) gsDma0p( G_OBJ_LDTX_RECT, (tptr),47) +#define gSPObjLoadTxRectR(pkt, tptr) gDma0p((pkt),G_OBJ_LDTX_RECT_R,(tptr),47) +#define gsSPObjLoadTxRectR(tptr) gsDma0p( G_OBJ_LDTX_RECT_R,(tptr),47) + +/*---------------------------------------------------------------------------* + * Select Display List + *---------------------------------------------------------------------------*/ +#define gSPSelectDL(pkt, mptr, sid, flag, mask) \ +{ gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); } +#define gsSPSelectDL(mptr, sid, flag, mask) \ +{ gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_PUSH); } +#define gSPSelectBranchDL(pkt, mptr, sid, flag, mask) \ +{ gDma1p((pkt), G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gDma1p((pkt), G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); } +#define gsSPSelectBranchDL(mptr, sid, flag, mask) \ +{ gsDma1p(G_RDPHALF_0, (flag), (u32)(mptr) & 0xffff, (sid)); \ + gsDma1p(G_SELECT_DL, (mask), (u32)(mptr) >> 16, G_DL_NOPUSH); } + +/*---------------------------------------------------------------------------* + * Set general status + *---------------------------------------------------------------------------*/ +#define G_MW_GENSTAT 0x08 /* Note that it is the same value of G_MW_FOG */ + +#define gSPSetStatus(pkt, sid, val) \ + gMoveWd((pkt), G_MW_GENSTAT, (sid), (val)) +#define gsSPSetStatus(sid, val) \ + gsMoveWd( G_MW_GENSTAT, (sid), (val)) + +/*---------------------------------------------------------------------------* + * Set Object Render Mode + *---------------------------------------------------------------------------*/ +#define G_OBJRM_NOTXCLAMP 0x01 +#define G_OBJRM_XLU 0x02 /* Ignored */ +#define G_OBJRM_ANTIALIAS 0x04 /* Ignored */ +#define G_OBJRM_BILERP 0x08 +#define G_OBJRM_SHRINKSIZE_1 0x10 +#define G_OBJRM_SHRINKSIZE_2 0x20 +#define G_OBJRM_WIDEN 0x40 + +#define gSPObjRenderMode(pkt, mode) gImmp1((pkt),G_OBJ_RENDERMODE,(mode)) +#define gsSPObjRenderMode(mode) gsImmp1( G_OBJ_RENDERMODE,(mode)) + +/*===========================================================================* + * Render Mode Macro + *===========================================================================*/ +#define RM_RA_SPRITE(clk) \ + AA_EN | CVG_DST_CLAMP | \ + CVG_X_ALPHA | ALPHA_CVG_SEL | ZMODE_OPA | TEX_EDGE | \ + GBL_c##clk(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA) + +#define G_RM_SPRITE G_RM_OPA_SURF +#define G_RM_SPRITE2 G_RM_OPA_SURF2 +#define G_RM_RA_SPRITE RM_RA_SPRITE(1) +#define G_RM_RA_SPRITE2 RM_RA_SPRITE(2) +#define G_RM_AA_SPRITE G_RM_AA_TEX_TERR +#define G_RM_AA_SPRITE2 G_RM_AA_TEX_TERR2 +#define G_RM_XLU_SPRITE G_RM_XLU_SURF +#define G_RM_XLU_SPRITE2 G_RM_XLU_SURF2 +#define G_RM_AA_XLU_SPRITE G_RM_AA_XLU_SURF +#define G_RM_AA_XLU_SPRITE2 G_RM_AA_XLU_SURF2 + +/*===========================================================================* + * External functions + *===========================================================================*/ +extern u64 gspS2DEX_fifoTextStart[], gspS2DEX_fifoTextEnd[]; +extern u64 gspS2DEX_fifoDataStart[], gspS2DEX_fifoDataEnd[]; +extern u64 gspS2DEX_fifo_dTextStart[], gspS2DEX_fifo_dTextEnd[]; +extern u64 gspS2DEX_fifo_dDataStart[], gspS2DEX_fifo_dDataEnd[]; +extern u64 gspS2DEX2_fifoTextStart[], gspS2DEX2_fifoTextEnd[]; +extern u64 gspS2DEX2_fifoDataStart[], gspS2DEX2_fifoDataEnd[]; +extern u64 gspS2DEX2_xbusTextStart[], gspS2DEX2_xbusTextEnd[]; +extern u64 gspS2DEX2_xbusDataStart[], gspS2DEX2_xbusDataEnd[]; +extern void guS2DInitBg(uObjBg *); + +#ifdef F3DEX_GBI_2 +# define guS2DEmuBgRect1Cyc guS2D2EmuBgRect1Cyc /*Wrapper*/ +# define guS2DEmuSetScissor guS2D2EmuSetScissor /*Wrapper*/ + extern void guS2D2EmuSetScissor(u32, u32, u32, u32, u8); + extern void guS2D2EmuBgRect1Cyc(Gfx **, uObjBg *); +#else + extern void guS2DEmuSetScissor(u32, u32, u32, u32, u8); + extern void guS2DEmuBgRect1Cyc(Gfx **, uObjBg *); +#endif + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif +#endif /* GS2DEX_H */ + +/*======== End of gs2dex.h ========*/ diff --git a/include/ultra64/hardware.h b/include/ultra64/hardware.h index 30e2b898b..57d560ab0 100644 --- a/include/ultra64/hardware.h +++ b/include/ultra64/hardware.h @@ -1,7 +1,17 @@ #ifndef _ULTRA64_HARDWARE_H_ #define _ULTRA64_HARDWARE_H_ -#define HW_REG(reg, type) *(volatile type*)((reg) | 0xa0000000) +// Segment Wrapper +// Uncached RDRAM +#define KSEG1 0xA0000000 // 0xA0000000 - 0xBFFFFFFF Physical memory, uncached, unmapped +#define RDRAM_UNCACHED KSEG1 + +// Cached RDRAM +#define KSEG0 0x80000000 // 0x80000000 - 0x9FFFFFFF Physical memory, cached, unmapped +#define RDRAM_CACHED KSEG0 + +// Volatile access wrapper, enforcing uncached memory +#define HW_REG(reg, type) *(volatile type*)((reg) | KSEG1) #define AI_DRAM_ADDR_REG 0x04500000 #define AI_LEN_REG 0x04500004 @@ -43,6 +53,8 @@ #define SP_DMEM_START 0x04000000 #define SP_DMEM_SIZE 0x1000 +#define TMEM_SIZE 0x1000 + #define SP_MEM_ADDR_REG 0x04040000 #define SP_DRAM_ADDR_REG 0x04040004 #define SP_RD_LEN_REG 0x04040008 @@ -70,7 +82,7 @@ #define PI_STATUS_BUSY (1 << 0) #define PI_STATUS_IOBUSY (1 << 1) -#define PI_STATUS_ERROR (PI_STATUS_BUSY | PI_STATUS_IOBUSY) +#define PI_STATUS_ERROR (1 << 2) #define PI_STATUS_RESET_CONTROLLER (1 << 0) #define PI_STATUS_CLEAR_INTR (1 << 1) @@ -86,6 +98,7 @@ #define SI_STATUS_INTERRUPT (1 << 12) #define PIF_RAM_START 0x1FC007C0 +#define PIF_RAM_SIZE 0x40 #define MI_INIT_MODE_REG 0x04300000 #define MI_MODE_REG MI_INIT_MODE_REG diff --git a/include/ultra64/motor.h b/include/ultra64/motor.h new file mode 100644 index 000000000..ad6828132 --- /dev/null +++ b/include/ultra64/motor.h @@ -0,0 +1,17 @@ +#ifndef ULTRA64_MOTOR_H +#define ULTRA64_MOTOR_H + +#include "PR/ultratypes.h" +#include "PR/pfs.h" +#include "ultra64/message.h" + +#define MOTOR_START 1 +#define MOTOR_STOP 0 + +#define osMotorStart(x) __osMotorAccess((x), MOTOR_START) +#define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP) + +s32 __osMotorAccess(OSPfs* pfs, u32 vibrate); +s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel); + +#endif diff --git a/include/ultra64/rdp.h b/include/ultra64/rdp.h new file mode 100644 index 000000000..b4b3bb532 --- /dev/null +++ b/include/ultra64/rdp.h @@ -0,0 +1,45 @@ +#ifndef ULTRA64_RDP_H +#define ULTRA64_RDP_H + +/* DP Command Registers */ +#define DPC_START_REG 0x04100000 +#define DPC_END_REG 0x04100004 +#define DPC_CURRENT_REG 0x04100008 +#define DPC_STATUS_REG 0x0410000C +#define DPC_CLOCK_REG 0x04100010 +#define DPC_BUFBUSY_REG 0x04100014 +#define DPC_PIPEBUSY_REG 0x04100018 +#define DPC_TMEM_REG 0x0410001C + +/* DP Span Registers */ +#define DPS_TBIST_REG 0x04200000 +#define DPS_TEST_MODE_REG 0x04200004 +#define DPS_BUFTEST_ADDR_REG 0x04200008 +#define DPS_BUFTEST_DATA_REG 0x0420000C + +/* DP Status Read Flags */ +#define DPC_STATUS_XBUS_DMEM_DMA (1 << 0) +#define DPC_STATUS_FREEZE (1 << 1) +#define DPC_STATUS_FLUSH (1 << 2) +#define DPC_STATUS_START_GCLK (1 << 3) +#define DPC_STATUS_TMEM_BUSY (1 << 4) +#define DPC_STATUS_PIPE_BUSY (1 << 5) +#define DPC_STATUS_CMD_BUSY (1 << 6) +#define DPC_STATUS_CBUF_READY (1 << 7) +#define DPC_STATUS_DMA_BUSY (1 << 8) +#define DPC_STATUS_END_VALID (1 << 9) +#define DPC_STATUS_START_VALID (1 << 10) + +/* DP Status Write Flags */ +#define DPC_CLR_XBUS_DMEM_DMA (1 << 0) +#define DPC_SET_XBUS_DMEM_DMA (1 << 1) +#define DPC_CLR_FREEZE (1 << 2) +#define DPC_SET_FREEZE (1 << 3) +#define DPC_CLR_FLUSH (1 << 4) +#define DPC_SET_FLUSH (1 << 5) +#define DPC_CLR_TMEM_CTR (1 << 6) +#define DPC_CLR_PIPE_CTR (1 << 7) +#define DPC_CLR_CMD_CTR (1 << 8) +#define DPC_CLR_CLOCK_CTR (1 << 9) + +#endif diff --git a/include/ultra64/sptask.h b/include/ultra64/sptask.h index c6e314f82..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 @@ -79,30 +80,29 @@ typedef struct { /* 0x00 */ u32 type; /* 0x04 */ u32 flags; - /* 0x08 */ u64* ucode_boot; - /* 0x0C */ u32 ucode_boot_size; + /* 0x08 */ u64* ucodeBoot; + /* 0x0C */ u32 ucodeBootSize; // ucode will load these sizes with lw, so need to be 32-bit /* 0x10 */ u64* ucode; - /* 0x14 */ u32 ucode_size; + /* 0x14 */ u32 ucodeSize; - /* 0x18 */ u64* ucode_data; - /* 0x1C */ u32 ucode_data_size; + /* 0x18 */ u64* ucodeData; + /* 0x1C */ u32 ucodeDataSize; - /* 0x20 */ u64* dram_stack; - /* 0x24 */ u32 dram_stack_size; + /* 0x20 */ u64* dramStack; + /* 0x24 */ u32 dramStackSize; - /* 0x28 */ u64* output_buff; - /* 0x2C */ u64* output_buff_size; + /* 0x28 */ u64* outputBuff; + /* 0x2C */ u64* outputBuffSize; - /* 0x30 */ u64* data_ptr; - /* 0x34 */ u32 data_size; + /* 0x30 */ u64* dataPtr; + /* 0x34 */ u32 dataSize; - /* 0x38 */ u64* yield_data_ptr; - /* 0x3C */ u32 yield_data_size; + /* 0x38 */ u64* yieldDataPtr; + /* 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/ultra64/vi.h b/include/ultra64/vi.h index 783087361..ca9b8e45e 100644 --- a/include/ultra64/vi.h +++ b/include/ultra64/vi.h @@ -1,15 +1,18 @@ #ifndef _ULTRA64_VI_H_ #define _ULTRA64_VI_H_ +#include "PR/ultratypes.h" +#include "ultra64/message.h" + /* Special Features */ -#define OS_VI_GAMMA_ON 0x0001 -#define OS_VI_GAMMA_OFF 0x0002 -#define OS_VI_GAMMA_DITHER_ON 0x0004 -#define OS_VI_GAMMA_DITHER_OFF 0x0008 -#define OS_VI_DIVOT_ON 0x0010 -#define OS_VI_DIVOT_OFF 0x0020 -#define OS_VI_DITHER_FILTER_ON 0x0040 -#define OS_VI_DITHER_FILTER_OFF 0x0080 +#define OS_VI_GAMMA_ON (1 << 0) +#define OS_VI_GAMMA_OFF (1 << 1) +#define OS_VI_GAMMA_DITHER_ON (1 << 2) +#define OS_VI_GAMMA_DITHER_OFF (1 << 3) +#define OS_VI_DIVOT_ON (1 << 4) +#define OS_VI_DIVOT_OFF (1 << 5) +#define OS_VI_DITHER_FILTER_ON (1 << 6) +#define OS_VI_DITHER_FILTER_OFF (1 << 7) #define OS_VI_GAMMA 0x08 #define OS_VI_GAMMA_DITHER 0x04 @@ -65,7 +68,7 @@ typedef struct { /* 0x14 */ OSMesg* msg; /* 0x18 */ __OSViScale x; /* 0x24 */ __OSViScale y; -} OSViContext; // size = 0x30 +} __OSViContext; // size = 0x30 #define OS_VI_NTSC_LPN1 0 /* NTSC */ #define OS_VI_NTSC_LPF1 1 @@ -97,6 +100,36 @@ typedef struct { #define OS_VI_PAL_HPN2 26 #define OS_VI_PAL_HPF2 27 +#define OS_VI_MPAL_LPN1 28 /* MPAL */ +#define OS_VI_MPAL_LPF1 29 +#define OS_VI_MPAL_LAN1 30 +#define OS_VI_MPAL_LAF1 31 +#define OS_VI_MPAL_LPN2 32 +#define OS_VI_MPAL_LPF2 33 +#define OS_VI_MPAL_LAN2 34 +#define OS_VI_MPAL_LAF2 35 +#define OS_VI_MPAL_HPN1 36 +#define OS_VI_MPAL_HPF1 37 +#define OS_VI_MPAL_HAN1 38 +#define OS_VI_MPAL_HAF1 39 +#define OS_VI_MPAL_HPN2 40 +#define OS_VI_MPAL_HPF2 41 + +#define OS_VI_FPAL_LPN1 42 /* FPAL */ +#define OS_VI_FPAL_LPF1 43 +#define OS_VI_FPAL_LAN1 44 +#define OS_VI_FPAL_LAF1 45 +#define OS_VI_FPAL_LPN2 46 +#define OS_VI_FPAL_LPF2 47 +#define OS_VI_FPAL_LAN2 48 +#define OS_VI_FPAL_LAF2 49 +#define OS_VI_FPAL_HPN1 50 +#define OS_VI_FPAL_HPF1 51 +#define OS_VI_FPAL_HAN1 52 +#define OS_VI_FPAL_HAF1 53 +#define OS_VI_FPAL_HPN2 54 +#define OS_VI_FPAL_HPF2 55 + #define OS_TV_PAL 0 #define OS_TV_NTSC 1 #define OS_TV_MPAL 2 diff --git a/include/unk.h b/include/unk.h index eb31a3874..0510fcd6a 100644 --- a/include/unk.h +++ b/include/unk.h @@ -1,5 +1,5 @@ -#ifndef _UNK_H_ -#define _UNK_H_ +#ifndef UNK_H +#define UNK_H #include "PR/ultratypes.h" diff --git a/include/variables.h b/include/variables.h index 2b223b9a7..c37938555 100644 --- a/include/variables.h +++ b/include/variables.h @@ -3,21 +3,22 @@ #include "z64.h" #include "segment_symbols.h" +#include "macros.h" // pre-boot variables extern u32 osTvType; extern u32 osRomType; -extern u32 osRomBase; +extern uintptr_t osRomBase; extern u32 osResetType; extern u32 osCicId; extern u32 osVersion; -extern u32 osMemSize; +extern size_t osMemSize; extern s32 osAppNmiBuffer[0x10]; 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; @@ -42,7 +43,6 @@ extern StackEntry* sStackInfoListEnd; // extern UNK_TYPE1 sGfxPrintUnkTLUT; // extern UNK_TYPE1 sGfxPrintUnkData; // extern UNK_TYPE1 sGfxPrintFontData; -// extern UNK_TYPE4 D_80097500; // extern UNK_TYPE4 D_80097524; // extern u32 sRandInt; extern OSViMode osViModeNtscHpf1; @@ -78,18 +78,18 @@ extern float D_80097F90; // extern UNK_TYPE1 D_80097FA0; // extern UNK_TYPE1 D_80097FA4; // extern UNK_TYPE1 D_80097FA5; -// extern UNK_TYPE4 D_80097FB0; +extern s32 __osPfsLastChannel; extern OSViMode osViModeNtscLan1; extern OSViMode osViModeMpalLan1; -extern __OSViContext D_80098060[2]; +// extern __OSViContext D_80098060[2]; extern __OSViContext* __osViCurr; extern __OSViContext* __osViNext; -// extern UNK_TYPE4 D_800980D0; +// extern UNK_TYPE4 sCartRomNeedsInit; extern OSViMode osViModeFpalLan1; -extern char ldigs[]; -extern char udigs[]; -extern OSDevMgr __osViDevMgr; -extern UNK_TYPE4 __additional_scanline; +// extern u8 ldigs[]; +// extern u8 udigs[]; +// extern OSDevMgr __osViDevMgr; +extern u32 __additional_scanline; // extern UNK_TYPE1 D_80098180; extern char bootThreadName[]; extern char idleThreadName[]; @@ -321,19 +321,13 @@ extern StackEntry sFaultThreadInfo; extern FaultThreadStruct gFaultStruct; extern FaultDrawer sFaultDrawerStruct; // extern UNK_TYPE4 D_8009CD10; -// extern Arena gSystemArena; extern u32 sRandFloat; // extern UNK_TYPE4 sArenaLockMsg; extern OSTask tmp_task; -extern OSPifRam osPifBuffers[4]; + extern OSMesg siAccessBuf[1]; extern OSMesgQueue __osSiAccessQueue; -extern OSPifRam __osContPifRam; -// extern UNK_TYPE1 D_8009CF0C; -extern u8 __osContLastCmd; -extern u8 __osMaxControllers; -// extern OSMesgQueue D_8009CF38; -// extern OSMesg D_8009CF50; + extern UNK_TYPE1 D_8009CF60; // extern UNK_TYPE4 D_8009CF70; extern OSThread __osThreadSave; @@ -357,14 +351,13 @@ extern OSPiHandle CartRomHandle; extern OSThread viThread; extern u8 viThreadStack[0x1000]; extern OSMesgQueue viEventQueue; -extern OSMesg viEventBuf[5]; -extern OSIoMesg viRetraceMsg; -extern OSIoMesg viCounterMsg; +// extern OSMesg viEventBuf[5]; +// extern OSIoMesg viRetraceMsg; +// extern OSIoMesg viCounterMsg; extern u16 viRetrace; extern DmaEntry dmadata[1568]; // extern UNK_TYPE1 D_80186028; -// extern UNK_TYPE1 D_801AAAB0; -// extern UNK_TYPE1 D_801AD370; +extern u64 aspMainTextStart[]; extern ActorInit En_A_Obj_InitVars; extern ColliderCylinderInit enAObjCylinderInit; extern InitChainEntry enAObjInitVar; @@ -378,7 +371,6 @@ extern u8 D_801AE214[32]; // extern UNK_TYPE4 D_801AE240; // extern UNK_TYPE4 D_801AE250; extern UNK_PTR D_801AE260[3]; -// extern UNK_TYPE4 D_801AE26C; // extern UNK_TYPE4 D_801AE27C; // extern UNK_TYPE4 D_801AE28C; // extern UNK_TYPE4 D_801AE29C; @@ -386,9 +378,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; @@ -416,16 +406,13 @@ 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; // extern s32 sTimer; -extern Color_RGBA8 D_801AEC80; -extern s801AEC84 D_801AEC84[13]; extern f32 actorMovementScale; -extern f32 D_801AECF0; -extern f32 D_801AECF4; +extern TargetRangeParams gTargetRanges[]; extern s16 D_801AED48[8]; // extern UNK_TYPE4 D_801AED58; extern Color_RGBA8 actorDefaultHitColor; @@ -440,20 +427,13 @@ extern Color_RGBA8 actorDefaultHitColor; // extern UNK_TYPE2 D_801AEE4C; extern Gfx D_801AEF88[]; extern Gfx D_801AEFA0[]; -// extern UNK_TYPE1 D_801AEFA8; // extern UNK_TYPE1 D_801AEFB8; // extern UNK_TYPE1 D_801AEFBC; // extern UNK_TYPE1 D_801AEFC0; extern ActorOverlay gActorOverlayTable[ACTOR_ID_MAX]; extern s32 gMaxActorId; -extern u32 D_801B4620[32]; -extern u16 D_801B46A0[16]; -extern u8 D_801B46C0[16]; -extern s16 bgSpecialSceneParamsDefault[1]; -// extern UNK_TYPE1 D_801B46D2; -extern BgSpecialSceneMaxMemory bgSpecialSceneMaxMemory[1]; -extern BgSpecialSceneMeshSubdivision bgSpecialSceneMeshSubdivisions[3]; -extern BgSpecialSceneMaxObjects bgSpecialSceneMaxObjects[1]; +extern BgCheckSceneSubdivisionEntry sSceneSubdivisionList[]; +extern BgSpecialSceneMaxObjects sCustomDynapolyMem[]; // extern UNK_TYPE1 D_801B4708; // extern UNK_TYPE1 D_801B4710; // extern UNK_TYPE1 D_801B4738; @@ -880,49 +860,20 @@ 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 UNK_TYPE1 D_801BA550; -// extern UNK_TYPE1 D_801BA750; -// extern UNK_TYPE1 D_801BA790; -// extern UNK_TYPE1 D_801BA7F0; -// extern UNK_TYPE1 D_801BA870; -// extern UNK_TYPE1 D_801BA8C0; -// extern UNK_TYPE1 D_801BAAC0; -// extern UNK_TYPE1 D_801BAB40; -// extern UNK_TYPE1 D_801BABB8; -// extern UNK_TYPE1 D_801BACB8; -// extern UNK_TYPE1 D_801BADB8; -// extern UNK_TYPE1 D_801BAEB8; -// extern UNK_TYPE1 D_801BAFB8; -// extern UNK_TYPE1 D_801BAFF8; -// extern UNK_TYPE1 D_801BB010; -// extern UNK_TYPE1 D_801BB018; -// extern UNK_TYPE1 D_801BB050; -// extern UNK_TYPE1 D_801BB058; -// extern UNK_TYPE2 D_801BB068; -// extern UNK_TYPE1 D_801BB08C; +extern EffectShieldParticleInit shieldParticleInitMetal; +extern EffectShieldParticleInit shieldParticleInitWood; // extern UNK_TYPE4 D_801BB090; // extern UNK_TYPE1 D_801BB094; // extern UNK_TYPE1 D_801BB0DC; // extern UNK_TYPE2 D_801BB0FC; // extern UNK_TYPE1 D_801BB100; -// extern UNK_TYPE2 D_801BB124; -// extern UNK_TYPE2 D_801BB128; + extern u8 D_801BB12C; -// extern UNK_TYPE1 D_801BB130; -extern cutscene_update_func sCsStateHandlers1[5]; -extern cutscene_update_func sCsStateHandlers2[5]; -// extern UNK_TYPE2 D_801BB15C; -// extern UNK_TYPE4 D_801BB160; + 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; // extern UNK_TYPE1 D_801BC41E; extern ActorCutscene actorCutscenesGlobalCutscenes[8]; extern s16 actorCutsceneCurrent; @@ -934,23 +885,15 @@ extern Actor* actorCutsceneCurrentCutsceneActor; extern GlobalContext* actorCutscenesGlobalCtxt; extern s16 actorCutsceneReturnCamera; extern s16 D_801BD8C6; -extern ColliderCylinderInit fireObjCollisionInit; -extern FireObjLightParams D_801BD8FC[2]; extern GameStateOverlay gGameStateOverlayTable[]; -// extern GameStateOverlay D_801BD940; -// extern GameStateOverlay titleGameStateInfo; -// extern GameStateOverlay mainGameStateInfo; -// extern GameStateOverlay openingGameStateInfo; -// extern GameStateOverlay fileChooseGameStateInfo; -// extern GameStateOverlay daytelopGameStateInfo; -// extern UNK_TYPE4 graphNumGameStates; +extern s32 graphNumGameStates; // extern UNK_TYPE2 D_801BDA70; // extern UNK_TYPE2 D_801BDA74; // extern UNK_TYPE2 D_801BDA78; // extern UNK_TYPE2 D_801BDA7C; extern s32 D_801BDA9C; extern UNK_TYPE4 D_801BDAA0; -// extern UNK_TYPE4 D_801BDAA4; +extern s32 D_801BDAA4; // extern UNK_TYPE2 D_801BDAA8; // extern UNK_TYPE2 D_801BDAAA; // extern UNK_TYPE2 D_801BDAAC; @@ -965,9 +908,7 @@ extern UNK_TYPE4 D_801BDAA0; // extern UNK_TYPE4 D_801BDACC; // extern UNK_TYPE4 D_801BDAF0; // extern UNK_TYPE4 D_801BDAF8; -// extern UNK_TYPE1 D_801BDB00; -// extern UNK_TYPE1 D_801BDB08; -// extern UNK_TYPE1 D_801BDB18; + extern u8 kanfontOrdering[92]; // extern UNK_TYPE4 D_801BDB90; // extern UNK_TYPE4 D_801BDB94; @@ -1301,7 +1242,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; @@ -1393,7 +1334,7 @@ extern u16 gEquipNegMasks[]; extern u32 gUpgradeMasks[8]; extern u32 gUpgradeNegMasks[]; extern u8 gEquipShifts[]; -extern u8 gUpgradeShifts[16]; +extern u8 gUpgradeShifts[8]; extern u16 gUpgradeCapacities[][4]; extern u32 gGsFlagsMask[]; extern u32 gGsFlagsShift[]; @@ -1408,12 +1349,6 @@ extern SceneTableEntry gSceneTable[]; extern UNK_PTR D_801C5C50; // extern UNK_TYPE1 D_801C5C9C; extern UNK_PTR D_801C5CB0; -extern MtxF sMtxFClear; -// extern UNK_TYPE1 D_801C5D10; -// extern UNK_TYPE1 D_801C5D20; -// extern UNK_TYPE1 D_801C5D60; -// extern UNK_TYPE1 D_801C5D80; -extern Vec3f D_801C5DB0; // extern UNK_TYPE1 D_801C5DD0; // extern UNK_TYPE1 D_801C5DE0; // extern UNK_TYPE1 D_801C5DF0; @@ -1425,36 +1360,7 @@ extern s32 D_801C5E9C[]; // D_801C5E9C extern s32 D_801C5EB0[]; // D_801C5EB0 extern s16 D_801C5EC4[]; // D_801C5EC4 extern struct_801C5F44 D_801C5F44[]; // D_801C5F44 -// extern UNK_TYPE4 D_801C5FC0; -// extern UNK_TYPE4 D_801C5FC4; -// extern UNK_TYPE4 D_801C5FC8; -// extern UNK_TYPE4 D_801C5FCC; -// extern UNK_TYPE4 D_801C5FD0; -// extern UNK_TYPE2 D_801C66D0; -// extern UNK_TYPE4 D_801C6798; -// extern UNK_TYPE1 D_801C67B0; -// extern UNK_TYPE4 D_801C67C8; -// extern UNK_TYPE4 D_801C67CC; -// extern UNK_TYPE4 D_801C67E8; -// extern UNK_TYPE4 D_801C67F0; -// extern UNK_TYPE4 D_801C67F4; -// extern UNK_TYPE1 D_801C6818; -// extern UNK_TYPE4 D_801C6838; -// extern UNK_TYPE1 D_801C6840; -// extern UNK_TYPE1 D_801C6850; -// extern UNK_TYPE1 D_801C6870; -// extern UNK_TYPE1 D_801C6890; -// extern UNK_TYPE1 D_801C6898; -// extern UNK_TYPE1 D_801C68C0; -extern Inventory gSaveDefaultInventory; -extern u16 gSaveDefaultChecksum; -// extern UNK_TYPE1 D_801C6970; -// extern UNK_TYPE1 D_801C6998; -extern Inventory D_801C69BC; -extern u16 D_801C6A44; -// extern UNK_TYPE1 D_801C6A48; -// extern UNK_TYPE1 D_801C6A50; -// extern UNK_TYPE1 D_801C6A58; + // extern UNK_TYPE1 D_801C6A70; // extern UNK_TYPE2 D_801C6A74; // extern UNK_TYPE2 D_801C6A78; @@ -1468,9 +1374,7 @@ extern u16 D_801C6A44; // extern UNK_TYPE1 D_801C6A98; // extern UNK_TYPE1 D_801C6AB8; // extern UNK_TYPE1 D_801C6B28; -// extern UNK_TYPE1 D_801C6B98; // extern UNK_TYPE1 D_801CED40; -// extern UNK_TYPE1 D_801CFB08; // extern UNK_TYPE2 D_801CFC78; // extern UNK_TYPE1 D_801CFC7A; // extern UNK_TYPE1 D_801CFC7C; @@ -1480,8 +1384,8 @@ extern u16 D_801C6A44; // extern UNK_TYPE1 D_801CFC8C; // extern UNK_TYPE1 D_801CFC8E; // extern UNK_TYPE1 D_801CFC92; -// extern UNK_TYPE1 D_801CFC98; -// extern UNK_TYPE2 D_801CFCA4; +extern u8 D_801CFC98; +extern s16 D_801CFCA4[9]; // extern UNK_TYPE2 D_801CFCAC; // extern UNK_TYPE1 D_801CFCB8; // extern UNK_TYPE2 D_801CFCD8; @@ -1573,11 +1477,11 @@ extern char D_801D039C[]; // extern UNK_TYPE1 D_801D0428; // extern UNK_TYPE1 D_801D045A; // extern UNK_TYPE1 D_801D0462; -// extern UNK_TYPE1 D_801D0468; +//extern UNK_TYPE1 D_801D0468; // extern UNK_TYPE1 D_801D0470; -extern char D_801D06F0[]; +// extern char D_801D06F0[]; // extern UNK_TYPE1 D_801D0710; -extern char D_801D0714[]; +// extern char D_801D0714[]; // extern UNK_TYPE1 D_801D07C4; // extern UNK_TYPE1 D_801D07DC; // extern UNK_TYPE1 D_801D080C; @@ -1590,11 +1494,9 @@ extern char D_801D0714[]; // extern UNK_TYPE1 D_801D08E4; // 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; @@ -1660,8 +1562,8 @@ extern s32 gFramerateDivisor; extern f32 gFramerateDivisorF; extern f32 gFramerateDivisorHalf; extern f32 gFramerateDivisorThird; -extern u32 D_801D1510; -extern u32 D_801D1514[3]; +extern u32 retryCount; +extern u32 cfbIdx[3]; extern s32 gScreenWidth; extern s32 gScreenHeight; extern u32 startHeapSize; @@ -1670,46 +1572,32 @@ 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 UNK_TYPE1 D_801D1E70; -// extern UNK_TYPE1 D_801D2E80; -// extern UNK_TYPE1 D_801D2F80; -// extern UNK_TYPE1 D_801D3070; -// extern UNK_TYPE1 D_801D3700; -// extern UNK_TYPE1 D_801D3D90; -// extern UNK_TYPE1 D_801D3F90; -// extern UNK_TYPE1 D_801D4190; -// extern UNK_TYPE1 D_801D4390; -// extern UNK_TYPE1 D_801D4590; -// extern UNK_TYPE1 D_801D4790; -// extern UNK_TYPE1 D_801D4990; -// extern UNK_TYPE1 D_801D4B90; -extern UNK_PTR D_801D4D90; +extern s16 gLowPassFilterData[]; +extern s16 gHighPassFilterData[]; +extern s16 gBandStopFilterData[]; +extern s16 gBandPassFilterData[]; +extern s16* gWaveSamples[9]; extern UNK_PTR D_801D4D98; extern UNK_PTR D_801D4DB0; -// extern UNK_TYPE1 D_801D4DB4; +extern f32 gBendPitchOneOctaveFrequencies[256]; // extern UNK_TYPE1 D_801D4FB4; -// extern UNK_TYPE4 D_801D51B4; +// extern UNK_TYPE4 gBendPitchTwoSemitonesFrequencies; // extern UNK_TYPE4 D_801D53B4; -// extern UNK_TYPE1 D_801D55B4; -// extern UNK_TYPE1 D_801D57B4; -// extern UNK_TYPE1 D_801D57C4; -// extern UNK_TYPE1 D_801D57D4; -// extern UNK_TYPE4 D_801D57E4; -// extern UNK_TYPE4 D_801D5804; -// extern UNK_TYPE2 D_801D5824; -// extern UNK_TYPE2 D_801D58A2; -// extern UNK_TYPE1 D_801D58AA; -// extern UNK_TYPE1 D_801D5928; -// extern UNK_TYPE1 D_801D5B24; -// extern UNK_TYPE1 D_801D5B28; -// extern UNK_TYPE1 D_801D5D24; -// extern UNK_TYPE1 D_801D5D28; +// extern UNK_TYPE1 gPitchFrequencies; +// extern UNK_TYPE1 gDefaultShortNoteVelocityTable; +// extern UNK_TYPE1 gDefaultShortNoteGateTimeTable; +// extern UNK_TYPE1 gDefaultEnvelope; +extern NoteSubEu gZeroNoteSub; +extern NoteSubEu gDefaultNoteSub; +extern u16 gHeadsetPanQuantization[]; +extern u16 gHeadsetPanQuantization[]; +extern s16 D_801D58A8[]; +extern f32 gHeadsetPanVolume[]; +extern f32 gStereoPanVolume[]; +extern f32 gDefaultPanVolume[]; // extern UNK_TYPE1 D_801D5F24; // extern UNK_TYPE4 D_801D5FB4; // extern UNK_TYPE4 D_801D5FB8; @@ -1718,7 +1606,7 @@ extern UNK_PTR D_801D4DB0; // extern UNK_TYPE1 D_801D5FD4; extern UNK_PTR D_801D5FE0; // extern UNK_TYPE1 D_801D5FE4; -// extern UNK_TYPE4 D_801D5FE8; +extern s32 gAudioContextInitalized; // extern UNK_TYPE4 D_801D5FEC; // extern UNK_TYPE4 D_801D5FF0; // extern UNK_TYPE4 D_801D5FF4; @@ -1742,7 +1630,7 @@ extern UNK_PTR D_801D618C; // extern UNK_TYPE1 D_801D6648; // extern UNK_TYPE1 D_801D664C; // extern UNK_TYPE1 D_801D6650; -extern f32 D_801D6654; +extern f32 gSfxVolume; // extern UNK_TYPE1 D_801D6658; // extern UNK_TYPE1 D_801D665C; // extern UNK_TYPE1 D_801D6660; @@ -1840,11 +1728,11 @@ extern UNK_PTR D_801D84F0; // extern UNK_TYPE2 D_801D853E; // extern UNK_TYPE1 D_801D8544; extern UNK_PTR D_801D889C; -extern UNK_PTR D_801D88A0; +extern u8* gScarecrowSpawnSongPtr; extern UNK_PTR D_801D88A4; // extern UNK_TYPE1 D_801D88A8; // extern UNK_TYPE1 D_801D88B8; -// extern UNK_TYPE1 D_801D8A48; +extern OcarinaSongButtons gOcarinaSongButtons[24]; // extern UNK_TYPE1 D_801D8B20; extern UNK_PTR D_801D8B24; // extern UNK_TYPE2 D_801D8B28; @@ -1860,21 +1748,21 @@ 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]; // extern UNK_TYPE1 D_801DB494; // extern UNK_TYPE1 D_801DB49C; // extern UNK_TYPE2 D_801DB4A0; -extern UNK_TYPE D_801DB4A4; +extern Vec3f D_801DB4A4; extern f32 D_801DB4B0; extern s8 D_801DB4B8; // extern UNK_TYPE1 D_801DB4C0; @@ -1899,7 +1787,7 @@ extern s8 D_801DB4B8; // extern UNK_TYPE1 D_801DB8B8; // extern UNK_TYPE1 D_801DB900; extern UNK_PTR D_801DB930; -extern s8018CFAC D_801DB958[21]; +extern AudioSpec gAudioSpecs[21]; // rodata extern f32 D_801DBDF0; @@ -2541,8 +2429,6 @@ extern f32 D_801DD774; extern f32 D_801DD780; extern f32 D_801DD7B0; extern f32 D_801DD7C0; -extern f32 D_801DD7D0; -extern f32 D_801DD7D4; extern f32 D_801DD7E0; extern f32 D_801DD7E4; extern f32 D_801DD7E8; @@ -2882,7 +2768,7 @@ extern f32 D_801DE860; extern f32 D_801DE864; extern f32 D_801DE868; extern f32 D_801DE884; -// extern UNK_TYPE1 D_801DE890; +extern TexturePtr D_801DE890[]; extern f32 D_801DF090; extern f32 D_801DF094; extern f32 D_801DF0A0; @@ -3080,7 +2966,7 @@ extern f32 D_801E05B4; extern f32 D_801E05B8; extern f32 D_801E05D0; extern f32 D_801E05D4; -// extern UNK_TYPE1 D_801E0BD0; +extern const u16 gAudioEnvironmentalSfx[]; // extern UNK_TYPE1 D_801E0BFC; extern f32 D_801E0CEC; extern f32 D_801E0CF0; @@ -3130,39 +3016,27 @@ 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; -// extern UNK_TYPE1 D_801E1420; -// 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 UNK_TYPE1 D_801E3F40; -// extern UNK_TYPE1 D_801E3FA0; +extern u8 gSoundFontTable[]; +extern u8 gSequenceFontTable[]; +extern u8 gSequenceTable[]; +extern u8 gSampleBankTable[]; +extern u64 aspMainDataStart[]; // 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; +extern CollisionPoly* D_801ED8B0; +extern s32 D_801ED8B4; // extern UNK_TYPE1 D_801ED8B8; // extern UNK_TYPE1 D_801ED8BC; // extern UNK_TYPE1 D_801ED8C0; // extern UNK_TYPE1 D_801ED8C4; extern f32 D_801ED8C8; -extern f32 D_801ED8CC; +extern f32 sBgmEnemyDistSq; extern f32 D_801ED8D0; // extern UNK_TYPE1 D_801ED8D4; // extern UNK_TYPE1 D_801ED8D8; @@ -3173,28 +3047,15 @@ extern FaultClient D_801ED930; extern FaultAddrConvClient D_801ED940; extern char D_801ED950[80]; extern char D_801ED9A0[80]; -extern Vec3f D_801ED9F0; -extern Vec3f D_801ED9FC; -extern Vec3f D_801EDA08; -extern Vec3f D_801EDA18; -extern Vec3f D_801EDA24; -extern Vec3f D_801EDA30; +extern Vec3f D_801ED9F0[3]; +extern Vec3f D_801EDA18[3]; extern MtxF D_801EDA40; -extern Vec3f D_801EDA80; -extern Vec3f D_801EDA8C; -extern Vec3f D_801EDA98; +extern Vec3f D_801EDA80[3]; extern char D_801EDAA8[80]; extern char D_801EDAF8[80]; -extern Vec3f D_801EDB48; -extern Vec3f D_01EDB54; -extern Vec3f D_01EDB60; -extern Vec3f D_01EDB70; -extern Vec3f D_801EDB7C; -extern Vec3f D_801EDB88; -extern f32 D_801EDB98; -extern f32 D_801EDB9C; -extern f32 D_801EDBA0; -// extern UNK_TYPE1 D_801EDBA4; +extern Vec3f D_801EDB48[3]; +extern Vec3f D_801EDB70[3]; +extern Plane D_801EDB98; extern Sphere16 D_801EDBA8; extern TriNorm D_801EDBB0; // extern UNK_TYPE1 D_801EDBD4; @@ -3251,12 +3112,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; @@ -3270,43 +3131,36 @@ extern SaveContext gSaveContext; // extern UNK_TYPE1 D_801F3F4A; // extern UNK_TYPE1 D_801F3F5A; extern GameInfo* gGameInfo; -// extern UNK_TYPE1 D_801F3F70; // extern UNK_TYPE1 D_801F3F80; // extern UNK_TYPE1 D_801F3F83; // extern UNK_TYPE1 D_801F48C8; -// extern UNK_TYPE1 D_801F4D40; -// extern UNK_TYPE2 D_801F4D42; -// extern UNK_TYPE1 D_801F4D48; -// extern UNK_TYPE1 D_801F4DC8; -// extern UNK_TYPE1 D_801F4DCA; -// extern UNK_TYPE2 D_801F4DCC[8]; -// extern UNK_TYPE1 D_801F4DDC; -// extern UNK_TYPE1 D_801F4DE0; -// extern UNK_TYPE2 D_801F4DE2; + +extern UNK_TYPE D_801F4DDC; +extern u8 D_801F4DE0; +extern s16 D_801F4DE2; + extern ActorCutscene* actorCutscenes; extern s16 actorCutsceneCount; extern u8 actorCutsceneWaiting[16]; // extern UNK_TYPE1 D_801F4E08; extern u8 actorCutsceneNextCutscenes[16]; // extern UNK_TYPE1 D_801F4E20; -// extern UNK_TYPE1 D_801F4E30; +extern u8 D_801F4E30; // extern UNK_TYPE1 D_801F4E31; extern s8 D_801F4E32; extern Vec3f D_801F4E38; extern f32 D_801F4E44; extern f32 D_801F4E48; extern s16 D_801F4E4C; -// extern UNK_TYPE1 D_801F4E4E; -// extern UNK_TYPE1 D_801F4E50; -// extern UNK_TYPE1 D_801F4E54; -// extern UNK_TYPE1 D_801F4E58; -// extern UNK_TYPE1 D_801F4E5C; -// extern UNK_TYPE1 D_801F4E60; -// extern UNK_TYPE1 D_801F4E64; -// extern UNK_TYPE1 D_801F4E68; +extern s8 D_801F4E4E; +extern Vec3f D_801F4E50; +extern f32 D_801F4E5C; +extern f32 D_801F4E60; +extern s16 D_801F4E64; +extern u8 D_801F4E68; extern f32 D_801F4E70; // extern UNK_TYPE1 D_801F4E74; -// extern UNK_TYPE1 D_801F4E78; +extern u16 D_801F4E78; extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F4E80; // extern UNK_TYPE1 D_801F4EE0; @@ -3338,8 +3192,7 @@ extern s16 D_801F4E7A; // extern UNK_TYPE1 D_801F4F66; // extern UNK_TYPE1 D_801F4F68; // extern UNK_TYPE1 D_801F4F6A; -extern LightsBuffer sLightsBuffer; -extern Arena sZeldaArena; +// extern LightsBuffer sLightsBuffer; // extern UNK_TYPE1 D_801F5130; // extern UNK_TYPE1 D_801F5270; // extern UNK_TYPE1 D_801F528E; @@ -3363,13 +3216,12 @@ extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F59F0; // extern UNK_TYPE1 D_801F59F4; // extern UNK_TYPE1 D_801F59F8; -// extern UNK_TYPE1 D_801F5AC0; // extern UNK_TYPE1 D_801F69D0; // extern UNK_TYPE1 D_801F6A10; // 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; @@ -3387,17 +3239,13 @@ extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F6B1E; // extern UNK_TYPE1 D_801F6B20; // extern UNK_TYPE1 D_801F6B22; -// extern UNK_TYPE1 D_801F6B30; -// extern UNK_TYPE1 D_801F6B34; -// extern UNK_TYPE1 D_801F6B38; -// extern UNK_TYPE1 D_801F6B3C; 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 void (*sKaleidoScopeUpdateFunc)(GlobalContext* globalCtx); +extern void (*sKaleidoScopeDrawFunc)(GlobalContext* globalCtx); +extern FaultAddrConvClient sKaleidoAreaFaultClient; // extern UNK_TYPE1 D_801F6C10; extern Input D_801F6C18; // extern UNK_TYPE1 D_801F6C30; @@ -3420,11 +3268,11 @@ extern struct_801F8010 D_801F8010; extern struct_801F8020 D_801F8020; extern VisMono sMonoColors; extern UNK_TYPE1 D_801F8048; -extern FaultAddrConvClient grapgFaultAddrConvClient; -extern FaultClient graphFaultClient; -extern Gfx* graphDlEntry; -// extern UNK_TYPE1 D_801F80F8; -extern u64 lastRenderFrameTimestamp; +extern FaultAddrConvClient sGraphFaultAddrConvClient; +extern FaultClient sGraphFaultClient; +extern GfxMasterList* gGfxMasterDL; +extern CfbInfo sGraphCfbInfos[3]; +extern OSTime sGraphTaskStartTime; extern OSMesgQueue sSiIntMsgQ; extern OSMesg sSiIntMsgBuf[1]; extern u32 gSegments[NUM_SEGMENTS]; @@ -3450,8 +3298,8 @@ extern OSTime sRSPOtherStartTime; extern OSTime sRDPStartTime; extern u64* gAudioSPDataPtr; extern u32 gAudioSPDataSize; -// extern UNK_TYPE1 D_801FBAE0; -// extern UNK_TYPE1 D_801FBAE8; +extern volatile OSTime D_801FBAE0; +extern volatile OSTime D_801FBAE8; extern volatile OSTime D_801FBAF0; extern volatile OSTime lastRenderFrameDuration; extern volatile OSTime gRSPAudioTotalTime; @@ -3464,21 +3312,21 @@ extern OSViMode D_801FBB30; extern u32* gFramebuffers[2]; extern OSViMode* D_801FBB88; extern u16* gZBufferPtr; -// extern UNK_TYPE4 D_801FBB90; -// extern UNK_TYPE1 D_801FBB94; -// extern UNK_TYPE1 D_801FBB98; +extern void* D_801FBB90; +extern u64* gGfxSPTaskOutputBufferPtr; +extern size_t gGfxSPTaskOutputBufferSize; // extern UNK_TYPE1 D_801FBB9C; // extern UNK_TYPE1 D_801FBBA0; -extern u16* sys_cfb_zbufl; -extern u16** sys_cfb_wbufl; -extern u16** sys_cfb_fifol; -// extern UNK_TYPE1 D_801FBBB0; +extern u16 (*gZBuffer)[SCREEN_WIDTH * SCREEN_HEIGHT]; +extern u16 (*gWorkBuffer)[SCREEN_WIDTH * SCREEN_HEIGHT]; +extern u64 (*gGfxSPTaskOutputBuffer)[0x3000]; +extern void* gGfxSPTaskOutputBufferEnd; // extern UNK_TYPE1 D_801FBBB4; // extern UNK_TYPE1 D_801FBBB8; // extern UNK_TYPE1 D_801FBBBC; // extern UNK_TYPE1 D_801FBBC0; -// extern UNK_TYPE1 D_801FBBC4; -// extern UNK_TYPE1 D_801FBBC8; +extern u64 (*gGfxSPTaskOutputBuffer2)[0x3000]; +extern void* gGfxSPTaskOutputBufferEnd2; extern UNK_TYPE2 D_801FBBCC; extern UNK_TYPE2 D_801FBBCE; // extern UNK_TYPE1 D_801FBBD0; @@ -3568,13 +3416,7 @@ extern StackEntry sys_flashromStackEntry; extern OSThread sys_flashromOSThread; extern s80185D40 D_801FD008; extern OSMesg D_801FD034; -// extern UNK_TYPE1 D_801FD040; -extern OSIoMesg D_801FD050; -extern OSMesgQueue D_801FD068; -extern OSPiHandle D_801FD080; -// extern UNK_TYPE1 D_801FD0F4; -// extern UNK_TYPE1 D_801FD0F8; -// extern UNK_TYPE1 D_801FD120; +extern s32 D_801FD120; // extern UNK_TYPE1 D_801FD140; // extern UNK_TYPE1 D_801FD158; // extern UNK_TYPE1 D_801FD198; @@ -3675,7 +3517,7 @@ extern OSPiHandle D_801FD080; // extern UNK_TYPE1 D_801FE4C0; // extern UNK_TYPE1 D_801FE640; // extern UNK_TYPE1 D_801FE6D0; -extern s801FE7C0 D_801FE7C0[1]; +extern SoundRequest D_801FE7C0[1]; // extern UNK_TYPE1 D_801FFBC0; // extern UNK_TYPE1 D_801FFBC8; // extern UNK_TYPE1 D_801FFBD0; @@ -3700,140 +3542,11 @@ extern s801FE7C0 D_801FE7C0[1]; // extern UNK_TYPE1 D_80200BCC; // extern UNK_TYPE1 D_80200BCE; // extern UNK_TYPE1 D_80200BD0; -// extern UNK_TYPE1 D_80200C70; -// extern UNK_TYPE1 D_80200C71; -// extern UNK_TYPE1 D_80200C76; -// extern UNK_TYPE1 D_80200C78; -// extern UNK_TYPE1 D_80200C7C; -// extern UNK_TYPE1 D_80200C80; -// extern UNK_TYPE1 D_80200C92; -// extern UNK_TYPE1 D_80200C94; -// extern UNK_TYPE1 D_80200C98; -// extern UNK_TYPE1 D_80200C9A; -// extern UNK_TYPE1 D_80200C9E; -// extern UNK_TYPE1 D_80200CA0; -// extern UNK_TYPE1 D_80200CF0; -// extern UNK_TYPE1 D_80200D38; -// extern UNK_TYPE1 D_80200D70; -// extern UNK_TYPE1 D_802011F0; -// extern UNK_TYPE1 D_8020178C; -// extern UNK_TYPE1 D_802017B0; -// extern UNK_TYPE1 D_80201D68; -// extern UNK_TYPE1 D_80201D6C; -// extern UNK_TYPE1 D_802023FC; -// extern UNK_TYPE1 D_80202878; -// extern UNK_TYPE1 D_80202880; -// extern UNK_TYPE1 D_802028BC; -extern OSMesgQueue D_80202980; -// extern UNK_TYPE1 D_802029D8; -extern OSMesgQueue D_80202AB0; -extern OSMesg D_80202AC8[0x10]; -extern OSMesgQueue D_80202B08; -extern OSMesg D_80202B20[0x10]; -extern OSMesgQueue D_80202B60; -extern OSMesg D_80202B78[0x40]; -extern OSMesgQueue D_80203278; -extern OSMesg D_80203290[1]; -// extern UNK_TYPE1 D_80203294; -// extern UNK_TYPE1 D_802034C0; -// extern UNK_TYPE1 D_802034C4; -// extern UNK_TYPE1 D_802034C8; -// extern UNK_TYPE4 D_802034D0; -// extern UNK_TYPE1 D_802034D4; -// extern UNK_TYPE1 D_802034D8; -// extern UNK_TYPE1 D_802034DC; -// extern UNK_TYPE1 D_802034E8; -// extern UNK_TYPE2 D_802034F0; -// extern UNK_TYPE1 D_802034F8; -// extern UNK_TYPE1 D_802034FC; -// extern UNK_TYPE1 D_80203500; -// extern UNK_TYPE4 D_80203528; -// extern UNK_TYPE1 D_8020352C; -// extern UNK_TYPE1 D_8020352E; -// extern UNK_TYPE1 D_80203530; -// extern UNK_TYPE4 D_8020360C; -// extern UNK_TYPE1 D_80203618; -// extern UNK_TYPE1 D_8020361C; -// extern UNK_TYPE1 D_80203620; -// extern UNK_TYPE1 D_80203624; -// extern UNK_TYPE1 D_80203628; -// extern UNK_TYPE1 D_80203630; -// extern UNK_TYPE1 D_80203640; -// extern UNK_TYPE1 D_80203650; -// extern UNK_TYPE1 D_80203660; -// extern UNK_TYPE1 D_80203690; -// extern UNK_TYPE1 D_802036A0; -// extern UNK_TYPE1 D_802036B0; -// extern UNK_TYPE1 D_802036C0; -// extern UNK_TYPE1 D_802036C4; -// extern UNK_TYPE1 D_80203794; -// extern UNK_TYPE1 D_80203798; -// extern UNK_TYPE1 D_802037D0; -// extern UNK_TYPE1 D_802037D4; -// extern UNK_TYPE1 D_802038A4; -// extern UNK_TYPE1 D_802038A8; -// extern UNK_TYPE1 D_802038C2; -// extern UNK_TYPE1 D_802038CE; -// extern UNK_TYPE1 D_802038E0; -// extern UNK_TYPE1 D_802038E4; -// extern UNK_TYPE1 D_80203970; -// extern UNK_TYPE1 D_802039B4; -// extern UNK_TYPE1 D_802039B8; -// extern UNK_TYPE1 D_802039D2; -// extern UNK_TYPE1 D_802039DE; -// extern UNK_TYPE1 D_802039F0; -// extern UNK_TYPE1 D_802039FC; -// extern UNK_TYPE1 D_80203B80; -// extern UNK_TYPE1 D_80203B88; -// extern UNK_TYPE1 D_80203B90; -// extern UNK_TYPE1 D_80204590; -// extern UNK_TYPE1 D_80204594; -// extern UNK_TYPE1 D_80204598; -// extern UNK_TYPE1 D_802045A4; -// extern UNK_TYPE1 D_80204FA4; -// extern UNK_TYPE1 D_80204FA8; -// extern UNK_TYPE1 D_80204FB4; -// extern UNK_TYPE1 D_80204FB8; -// extern UNK_TYPE1 D_80204FC0; -// extern UNK_TYPE1 D_80204FCC; -// extern UNK_TYPE1 D_80204FD8; -// extern UNK_TYPE1 D_80205008; -// extern UNK_TYPE1 D_80205038; -// extern UNK_TYPE1 D_802050B9; -// extern UNK_TYPE1 D_802050C0; -// extern UNK_TYPE1 D_802050C4; -// extern UNK_TYPE4 D_802050CC; -// extern UNK_TYPE4 D_802050D0; -// extern UNK_TYPE1 D_80205228; -// extern UNK_TYPE1 D_8020522B; -// extern UNK_TYPE1 D_80205390; -// extern UNK_TYPE1 D_802053C8; -// extern UNK_TYPE1 D_802057B0; -// extern UNK_TYPE1 D_80205830; -// extern UNK_TYPE1 D_802084B0; -// extern UNK_TYPE1 D_80208530; -// extern UNK_TYPE1 D_80208598; -// extern UNK_TYPE1 D_802085A8; -// extern UNK_TYPE1 D_802085B8; -// extern UNK_TYPE1 D_802085C8; -// extern UNK_TYPE1 D_802085D8; -// extern UNK_TYPE1 D_802085F8; -// extern UNK_TYPE1 D_802085FC; -// extern UNK_TYPE1 D_80208604; -// extern UNK_TYPE1 D_8020861C; -// extern UNK_TYPE1 D_80208634; -// extern UNK_TYPE1 D_8020864C; -// extern UNK_TYPE1 D_80208650; -// extern UNK_TYPE1 D_80208654; -// extern UNK_TYPE4 D_80208E68; -// extern UNK_TYPE4 D_80208E6C; -// extern UNK_TYPE4 D_80208E70; -// extern UNK_TYPE4 D_80208E74; -// extern UNK_TYPE1 D_80208E90; -// extern UNK_TYPE1 D_80208E94; -// extern UNK_TYPE1 D_80208E98; -// extern UNK_TYPE1 D_80208E99; -// extern UNK_TYPE1 D_80208E9C; +extern AudioContext gAudioContext; // at 0x80200C70 +extern void (*D_80208E68)(void); +extern u32 (*D_80208E6C)(s8 value, SequenceChannel* channel); +extern s32 (*D_80208E70)(SoundFontSample*, s32, s8, s32); +extern Acmd* (*D_80208E74)(Acmd*, s32, s32); // post-code buffers extern u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; @@ -3846,257 +3559,10 @@ extern u8 D_80780000[0x4600]; extern u8 D_80784600[0x56200]; extern u16 gFramebuffer0[SCREEN_HEIGHT][SCREEN_WIDTH]; -// keep objects - -extern Gfx D_040008D0[]; -extern UNK_TYPE D_040032B0; -extern UNK_TYPE D_0400CF58; -extern UNK_TYPE D_0400CF88; -extern UNK_TYPE D_0400CF98; -extern UNK_TYPE D_0400D0A8; -extern UNK_TYPE D_0400D0B0; -extern UNK_TYPE D_0400D0C8; -extern UNK_TYPE D_0400D100; -extern UNK_TYPE D_0400D218; -extern UNK_TYPE D_0400D220; -extern UNK_TYPE D_0400D228; -extern UNK_TYPE D_0400D2D0; -extern UNK_TYPE D_0400D3E8; -extern UNK_TYPE D_0400D3F8; -extern UNK_TYPE D_0400D488; -extern UNK_TYPE D_0400D490; -extern UNK_TYPE D_0400D500; -extern UNK_TYPE D_0400D520; -extern UNK_TYPE D_0400D568; -extern UNK_TYPE D_0400D638; -extern UNK_TYPE D_0400D660; -extern UNK_TYPE D_0400D698; -extern UNK_TYPE D_0400D728; -extern UNK_TYPE D_0400D9C8; -extern UNK_TYPE D_0400D9D0; -extern UNK_TYPE D_0400DA70; -extern UNK_TYPE D_0400DA88; -extern UNK_TYPE D_0400DAA8; -extern UNK_TYPE D_0400DAC0; -extern UNK_TYPE D_0400DAC8; -extern UNK_TYPE D_0400DAD8; -extern UNK_TYPE D_0400DAE0; -extern UNK_TYPE D_0400DAF0; -extern UNK_TYPE D_0400DB10; -extern UNK_TYPE D_0400DB18; -extern UNK_TYPE D_0400DB30; -extern UNK_TYPE D_0400DBB0; -extern UNK_TYPE D_0400DBE8; -extern UNK_TYPE D_0400DC48; -extern UNK_TYPE D_0400DC50; -extern UNK_TYPE D_0400DCA8; -extern UNK_TYPE D_0400DCD0; -extern UNK_TYPE D_0400DCD8; -extern UNK_TYPE D_0400DCF8; -extern UNK_TYPE D_0400DD30; -extern UNK_TYPE D_0400DD38; -extern UNK_TYPE D_0400DD40; -extern UNK_TYPE D_0400DD50; -extern UNK_TYPE D_0400DD58; -extern UNK_TYPE D_0400DD80; -extern UNK_TYPE D_0400DDB0; -extern UNK_TYPE D_0400DDF8; -extern UNK_TYPE D_0400DE00; -extern UNK_TYPE D_0400DE08; -extern UNK_TYPE D_0400DE10; -extern UNK_TYPE D_0400DE28; -extern UNK_TYPE D_0400DE30; -extern UNK_TYPE D_0400DE58; -extern UNK_TYPE D_0400DE60; -extern UNK_TYPE D_0400DEA0; -extern UNK_TYPE D_0400DEA8; -extern UNK_TYPE D_0400DF78; -extern UNK_TYPE D_0400DF90; -extern UNK_TYPE D_0400DFA0; -extern UNK_TYPE D_0400DFD0; -extern UNK_TYPE D_0400DFE0; -extern UNK_TYPE D_0400DFE8; -extern UNK_TYPE D_0400DFF8; -extern UNK_TYPE D_0400E000; -extern UNK_TYPE D_0400E070; -extern UNK_TYPE D_0400E088; -extern UNK_TYPE D_0400E120; -extern UNK_TYPE D_0400E150; -extern UNK_TYPE D_0400E1F0; -extern UNK_TYPE D_0400E200; -extern UNK_TYPE D_0400E208; -extern UNK_TYPE D_0400E270; -extern UNK_TYPE D_0400E290; -extern UNK_TYPE D_0400E2A8; -extern UNK_TYPE D_0400E2B8; -extern UNK_TYPE D_0400E2C0; -extern UNK_TYPE D_0400E2D0; -extern UNK_TYPE D_0400E2D8; -extern UNK_TYPE D_0400E2E8; -extern UNK_TYPE D_0400E318; -extern UNK_TYPE D_0400E398; -extern UNK_TYPE D_0400E3A0; -extern UNK_TYPE D_0400E3A8; -extern UNK_TYPE D_0400E3C0; -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 UNK_TYPE D_04015FA0; -extern UNK_TYPE D_04016360; -extern UNK_TYPE D_0401A4D0; -extern UNK_TYPE D_0401A538; -extern UNK_TYPE D_0401A620; -extern Gfx D_0401C430[]; -extern UNK_TYPE D_0401F740; -extern UNK_TYPE D_0401F7C0; -extern UNK_TYPE D_0401F8C0; -extern UNK_TYPE D_0401FA40; -extern UNK_TYPE D_04020BB8; -extern UNK_TYPE D_040221B8; -extern UNK_TYPE D_04023100; -extern UNK_TYPE D_04023130; -extern Gfx D_04023210[]; -extern UNK_TYPE D_04023288; -extern Gfx D_04023348[]; -extern Gfx D_040233B8[]; -extern Gfx D_04023428[]; -extern UNK_TYPE D_04025850; -extern UNK_TYPE D_04025DD0; -extern UNK_TYPE D_040281DC; -extern UNK_TYPE D_04028FEC; -extern UNK_TYPE D_04029140; -extern Gfx D_04029CB0[]; -extern Gfx D_04029CF0[]; -extern UNK_TYPE D_04029D20; -extern UNK_TYPE D_0402B494; -extern UNK_TYPE D_0402C908; -extern Gfx D_0402E510[]; -extern UNK_TYPE D_0402E65C; -extern UNK_TYPE D_0402F0EC; -extern Gfx D_04030100[]; // Floor shockwave ring -extern UNK_TYPE D_040301B0; -extern UNK_TYPE D_04032270; -extern UNK_TYPE D_04035710; -extern UNK_TYPE D_040367B0; -extern UNK_TYPE D_040377B0; -extern UNK_TYPE D_04037850; -extern Gfx D_040378F0[]; // gExplosionSplashTex1 -extern Gfx D_04037DF0[]; // gExplosionSplashTex2 -extern Gfx D_040382F0[]; // gExplosionSplashTex3 -extern Gfx D_040387F0[]; // gExplosionSplashTex4 -extern Gfx D_04038CF0[]; // gExplosionSplashTex5 -extern Gfx D_040391F0[]; // gExplosionSplashTex6 -extern Gfx D_040396F0[]; // gExplosionSplashTex7 -extern Gfx D_04039BF0[]; // gExplosionSplashTex8 -extern Gfx D_0403A0F0[]; // gExplosionSplashDL -extern UNK_TYPE D_0403C190; -extern UNK_TYPE D_0403F230; -extern UNK_TYPE D_04044300; -extern Gfx D_04048DF0[]; -extern UNK_TYPE D_04050D10; -extern UNK_TYPE D_04051180; -extern UNK_TYPE D_04051238; -extern UNK_TYPE D_0405140C; -extern UNK_TYPE D_040527F0; -extern UNK_TYPE D_040528B0; -extern Gfx D_04054A90[]; -extern UNK_TYPE D_04055628; -extern Gfx D_04057B10[]; -extern Gfx D_04058BA0[]; -extern Gfx D_04089070[]; -extern TexturePtr D_0408DBE0[]; // gDust1Tex -extern TexturePtr D_0408DFE0[]; // gDust2Tex -extern TexturePtr D_0408E3E0[]; // gDust3Tex -extern TexturePtr D_0408E7E0[]; // gDust4Tex -extern TexturePtr D_0408EBE0[]; // gDust5Tex -extern TexturePtr D_0408EFE0[]; // gDust6Tex -extern TexturePtr D_0408F3E0[]; // gDust7Tex -extern TexturePtr D_0408F7E0[]; // gDust8Tex -extern UNK_TYPE D_04050550; -extern UNK_TYPE D_04050648; -extern UNK_TYPE D_040510B0; -extern UNK_TYPE D_04054940; -extern Gfx D_0405AAB0[]; -extern UNK_TYPE D_0405B6F0; -extern UNK_TYPE D_0405BEF0; -extern UNK_TYPE D_0405C6F0; -extern UNK_TYPE D_0405CEF0; -extern UNK_TYPE D_0405E6F0; -extern Gfx D_0405F6F0[]; -extern UNK_TYPE D_0405F7C0; -extern UNK_TYPE D_0405FFC0; -extern UNK_TYPE D_040607C0; -extern UNK_TYPE D_04060FC0; -extern UNK_TYPE D_040617C0; -extern UNK_TYPE D_04061FC0; -extern UNK_TYPE D_04061FE0; -extern UNK_TYPE D_04062000; -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 UNK_TYPE D_0406B730; -extern UNK_TYPE D_0406BB0C; -extern UNK_TYPE D_0406F380; -extern UNK_TYPE D_04073F00; -extern UNK_TYPE D_04075400; -extern Gfx D_04075A40[]; -extern Gfx D_04075B30[]; -extern Gfx D_04076BC0[]; -extern Gfx D_04077480[]; -extern UNK_TYPE D_04079B10; -extern Gfx D_0407AB10[]; -extern Gfx D_0407AB58[]; -extern UNK_TYPE D_0407AFB0; -extern Gfx D_0407D590[]; -extern UNK_TYPE D_0407D650; -extern UNK_TYPE D_0407F218; -extern UNK_TYPE D_040815D0; -extern UNK_TYPE D_04081628; -extern UNK_TYPE D_04083534; -extern UNK_TYPE D_04091BE0; -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 UNK_TYPE D_05007498; -extern Gfx D_05007890[]; -extern UNK_TYPE D_050078A0; -extern UNK_TYPE D_05007938; -extern Gfx D_05007980[]; -extern UNK_TYPE D_05007E00; -extern UNK_TYPE D_05008018; -extern UNK_TYPE D_050085F0; -extern Gfx D_05017EA0[]; // pot displaylist -extern Gfx D_05018090[]; // pot break shard displaylist -extern UNK_TYPE D_050182A8; -extern UNK_TYPE D_0501B508; -extern UNK_TYPE D_0501C058; -extern Gfx D_0501D980[]; -extern Gfx D_050219E0[]; -extern UNK_TYPE D_05023008; -extern UNK_TYPE D_0502324C; - // other segments -extern UNK_TYPE D_0E000048; -extern UNK_TYPE D_0E000088; -extern UNK_TYPE D_0E000140; -extern UNK_TYPE D_0E0001C8; -extern UNK_TYPE D_0E0002C8; +extern GfxMasterList D_0E000000; +extern Mtx D_01000000; +extern UNK_TYPE D_0F000000; + #endif diff --git a/include/viint.h b/include/viint.h index e850c895a..fadd5d781 100644 --- a/include/viint.h +++ b/include/viint.h @@ -16,13 +16,13 @@ typedef struct { /* 0x0 */ u16 state; /* 0x2 */ u16 retraceCount; - /* 0x4 */ void* framep; + /* 0x4 */ void* buffer; /* 0x8 */ OSViMode* modep; /* 0xC */ u32 control; /* 0x10 */ OSMesgQueue* msgq; /* 0x14 */ OSMesg msg; /* 0x18 */ __OSViScale x; /* 0x24 */ __OSViScale y; -} __OSViContext; +} __OSViContext; // size = 0x30 #endif diff --git a/include/xstdio.h b/include/xstdio.h index 6ea17e1c7..102a25ee4 100644 --- a/include/xstdio.h +++ b/include/xstdio.h @@ -1,7 +1,7 @@ #ifndef _XSTDIO_H_ #define _XSTDIO_H_ -#include "stdarg.h" +#include "libc/stdarg.h" typedef struct { /* 0x0 */ union { @@ -22,4 +22,12 @@ typedef struct { /* 0x34 */ u8 qual; } _Pft; +typedef void* (*PrintCallback)(void*, const char*, size_t); + +#define FLAGS_SPACE 1 +#define FLAGS_PLUS 2 +#define FLAGS_MINUS 4 +#define FLAGS_HASH 8 +#define FLAGS_ZERO 16 + #endif diff --git a/include/z64.h b/include/z64.h index cd00fb86f..7f1dfd701 100644 --- a/include/z64.h +++ b/include/z64.h @@ -1,28 +1,32 @@ -#ifndef _Z64_H_ -#define _Z64_H_ +#ifndef Z64_H +#define Z64_H -#include "stdarg.h" -#include "stdbool.h" -#include "stdint.h" +#include "libc/math.h" +#include "libc/stdarg.h" +#include "libc/stdbool.h" +#include "libc/stddef.h" +#include "libc/stdint.h" +#include "libc/stdlib.h" -#include "PR/ultratypes.h" -#include "PR/gbi.h" +#include "ultra64.h" +#include "ultra64/gs2dex.h" #include "io/controller.h" #include "osint.h" -#include "viint.h" -#include "math.h" #include "os.h" -#include "stdlib.h" +#include "irqmgr.h" +#include "scheduler.h" #include "xstdio.h" -#include "unk.h" -#include "bgm.h" -#include "sfx.h" #include "color.h" #include "ichain.h" +#include "sequence.h" +#include "sfx.h" +#include "message_data_static.h" +#include "sys_matrix.h" #include "z64actor.h" #include "z64animation.h" +#include "z64audio.h" #include "z64bgcheck.h" #include "z64collision_check.h" #include "z64cutscene.h" @@ -32,18 +36,16 @@ #include "z64light.h" #include "z64math.h" #include "z64object.h" +#include "z64ocarina.h" #include "z64player.h" -#include "z64scene.h" #include "z64save.h" +#include "z64scene.h" +#include "z64schedule.h" +#include "z64skin.h" +#include "z64subs.h" #include "z64transition.h" #include "regs.h" -#define SCREEN_WIDTH 320 -#define SCREEN_HEIGHT 240 - -#define SCREEN_WIDTH_HIGH_RES 576 -#define SCREEN_HEIGHT_HIGH_RES 454 - #define Z_THREAD_ID_IDLE 1 #define Z_THREAD_ID_SLOWLY 2 #define Z_THREAD_ID_MAIN 3 @@ -70,7 +72,7 @@ typedef struct { /* 0x0 */ s16 priority; // Lower means higher priority. -1 means it ignores priority /* 0x2 */ s16 length; - /* 0x4 */ s16 unk4; + /* 0x4 */ s16 csCamSceneDataId; // Index of CsCameraEntry to use. Negative indices use sGlobalCamDataSettings. Indices 0 and above use CsCameraEntry from scene /* 0x6 */ s16 unk6; /* 0x8 */ s16 additionalCutscene; /* 0xA */ u8 sound; @@ -80,13 +82,6 @@ typedef struct { /* 0xF */ u8 letterboxSize; } ActorCutscene; // size = 0x10 -typedef struct { - /* 0x0 */ s16 polyStartIndex; - /* 0x2 */ s16 ceilingNodeHead; - /* 0x4 */ s16 wallNodeHead; - /* 0x6 */ s16 floorNodeHead; -} ActorMeshPolyLists; // size = 0x8 - typedef struct { /* 0x0 */ s8 segment; /* 0x2 */ s16 type; @@ -107,49 +102,6 @@ typedef struct { /* 0x08 */ void* end; } PolygonType2; // size = 0xC -typedef struct { - /* 0x0 */ u16 floorHead; - /* 0x2 */ u16 wallHead; - /* 0x4 */ u16 ceilingHead; -} BgMeshSubdivision; // size = 0x6 - -typedef struct { - /* 0x0 */ u32 attributes[2]; -} BgPolygonAttributes; // size = 0x8 - -typedef struct { - /* 0x0 */ s16 polyIndex; - /* 0x2 */ u16 next; -} BgPolygonLinkedListNode; // size = 0x4 - -typedef struct { - /* 0x0 */ u16 maxNodes; - /* 0x2 */ u16 reservedNodes; - /* 0x4 */ BgPolygonLinkedListNode* nodes; - /* 0x8 */ u8* unk8; -} BgScenePolygonLists; // size = 0xC - -typedef struct { - /* 0x0 */ s16 sceneNumber; - /* 0x2 */ UNK_TYPE1 pad2[0x2]; - /* 0x4 */ u32 maxMemory; -} BgSpecialSceneMaxMemory; // size = 0x8 - -typedef struct { - /* 0x0 */ s16 sceneId; - /* 0x2 */ s16 maxNodes; - /* 0x4 */ s16 maxPolygons; - /* 0x6 */ s16 maxVertices; -} BgSpecialSceneMaxObjects; // size = 0x8 - -typedef struct { - /* 0x0 */ s16 sceneNumber; - /* 0x2 */ s16 xSubdivisions; - /* 0x4 */ s16 ySubdivisions; - /* 0x6 */ s16 zSubdivisions; - /* 0x8 */ s32 unk8; -} BgSpecialSceneMeshSubdivision; // size = 0xC - typedef struct { /* 0x0 */ s16 func; /* 0x2 */ UNK_TYPE1 pad2[0x6]; @@ -161,24 +113,6 @@ typedef struct { /* 0x8 */ CameraModeParams* modes; } CameraStateParams; // size = 0xC -typedef struct { - /* 0x00 */ u8 sceneCsCount; - /* 0x04 */ void* segment; - /* 0x08 */ u8 state; - /* 0x0C */ f32 unk_0C; - /* 0x10 */ u16 frames; - /* 0x12 */ u16 unk_12; - /* 0x14 */ s32 unk_14; - /* 0x18 */ u16 unk_18; - /* 0x1A */ u8 unk_1A; - /* 0x1B */ u8 unk_1B; - /* 0x1C */ CutsceneCameraPoint* cameraFocus; - /* 0x20 */ CutsceneCameraPoint* cameraPosition; - /* 0x24 */ CsCmdActorAction* linkAction; - /* 0x28 */ CsCmdActorAction* npcActions[10]; // "npcdemopnt" - /* 0x50 */ CutsceneEntry* sceneCsList; -} CutsceneContext; // size = 0x54 - typedef struct { /* 0x0 */ s16 x; /* 0x2 */ s16 y; @@ -210,24 +144,27 @@ typedef struct { /* 0x4 */ f32 dynamicSizeStep; /* 0x8 */ u8 state; /* 0x9 */ u8 sizeGrowsCos2; - /* 0xA */ u8 unkA; + /* 0xA */ u8 colorsIndex; /* 0xB */ u8 flags; - /* 0xC */ u8 unkC; + /* 0xC */ u8 lightParamsIndex; } FireObjInitParams; // size = 0xD -typedef struct { - /* 0x0 */ u8 unk0; - /* 0x1 */ u8 unk1; - /* 0x2 */ u8 unk2; - /* 0x3 */ u8 unk3; - /* 0x4 */ u8 unk4; - /* 0x5 */ u8 unk5; - /* 0x6 */ u8 unk6; - /* 0x7 */ u8 unk7; +typedef struct FireObjColors { + /* 0x0 */ Color_RGBA8 primColor; + /* 0x4 */ u8 lod; + /* 0x5 */ Color_RGB8 envColor; +} FireObjColors; // size = 0x8 + +typedef struct FireObjLightParams { + /* 0x0 */ s16 radius; + /* 0x2 */ Color_RGB8 color; + /* 0x5 */ Color_RGB8 maxColorAdj; } FireObjLightParams; // size = 0x8 +#define FONT_CHAR_TEX_WIDTH 16 +#define FONT_CHAR_TEX_HEIGHT 16 //! @TODO: Make this use `sizeof(AnyFontTextureSymbol)` -#define FONT_CHAR_TEX_SIZE ((16 * 16) / 2) +#define FONT_CHAR_TEX_SIZE ((16 * 16) / 2) // 16x16 I4 texture // Font textures are loaded into here typedef struct { @@ -240,7 +177,7 @@ typedef struct { } msgBuf; /* 0x11D80 */ u8* messageStart; /* 0x11D84 */ u8* messageEnd; - /* 0x11D88 */ u8 unk_11D88; + /* 0x11D88 */ u8 unk_11D88; // current Char Buffer ? } Font; // size = 0x11D8C // Game Info aka. Static Context @@ -269,62 +206,72 @@ typedef struct { /* 0x000C */ Gfx* d; } TwoHeadGfxArena; // size = 0x10 +typedef struct { + /* 0x000 */ Gfx taskStart[9]; + /* 0x048 */ Gfx clearZBuffer[8]; // original name: clear_zb_dl + /* 0x088 */ Gfx clearFrameBuffer[5]; // original name: clear_fb_dl + /* 0x0B0 */ Gfx setupBuffers[6]; // setup framebuffer and zbuffer + /* 0x0E0 */ Gfx unk_E0[12]; // unused + /* 0x140 */ Gfx syncSegments[17]; + /* 0x1C8 */ Gfx setScissor[2]; + /* 0x1D8 */ Gfx unk_1D8[25]; // unused + /* 0x2A0 */ Gfx disps[5]; + /* 0x2C8 */ Gfx clearFillRect[3]; // fillrect for clearing buffers + /* 0x2E0 */ Gfx fillRect[3]; // fillrect for general purpose + /* 0x2F8 */ Gfx debugDisp[1]; +} GfxMasterList; // size = 0x300 + +#define GFXPOOL_HEAD_MAGIC 0x1234 +#define GFXPOOL_TAIL_MAGIC 0x5678 + typedef struct { /* 0x00000 */ u16 headMagic; // 1234 - /* 0x00008 */ Gfx unk8[96]; + /* 0x00008 */ GfxMasterList master; /* 0x00308 */ Gfx polyXluBuffer[2048]; /* 0x04308 */ Gfx overlayBuffer[1024]; - /* 0x06308 */ Gfx unk6308[64]; - /* 0x06508 */ Gfx unk6508[64]; + /* 0x06308 */ Gfx workBuffer[64]; + /* 0x06508 */ Gfx debugBuffer[64]; /* 0x06708 */ Gfx polyOpaBuffer[13184]; /* 0x20308 */ u16 tailMagic; // 5678 } GfxPool; // size = 0x20310 -typedef struct { - /* 0x00 */ u16* fb1; - /* 0x04 */ u16* swapBuffer; - /* 0x08 */ OSViMode* viMode; - /* 0x0C */ u32 features; - /* 0x10 */ u8 unk_10; - /* 0x11 */ s8 updateRate; - /* 0x12 */ s8 updateRate2; - /* 0x13 */ u8 unk_13; - /* 0x14 */ f32 xScale; - /* 0x18 */ f32 yScale; -} CfbInfo; // size = 0x1C - typedef struct GraphicsContext { - /* 0x000 */ Gfx* polyOpaBuffer; - /* 0x004 */ Gfx* polyXluBuffer; - /* 0x008 */ UNK_TYPE1 pad8[0x8]; - /* 0x010 */ Gfx* overlayBuffer; - /* 0x014 */ UNK_TYPE1 pad14[0x24]; - /* 0x038 */ UNK_TYPE4 unk38[8]; - /* 0x058 */ OSMesgQueue* unk58; - /* 0x05C */ OSMesgQueue unk5C; - /* 0x074 */ UNK_TYPE1 pad74[0x12C]; - /* 0x1A0 */ Gfx* unk1A0; - /* 0x1A4 */ TwoHeadGfxArena unk1A4; - /* 0x1B4 */ Gfx* unk1B4; - /* 0x1B8 */ TwoHeadGfxArena unk1B8; - /* 0x1C8 */ UNK_TYPE1 pad1C8[0xAC]; - /* 0x274 */ OSViMode* viMode; - /* 0x278 */ void* zbuffer; - /* 0x27C */ UNK_TYPE1 pad27C[0x1C]; - /* 0x298 */ TwoHeadGfxArena overlay; - /* 0x2A8 */ TwoHeadGfxArena polyOpa; - /* 0x2B8 */ TwoHeadGfxArena polyXlu; - /* 0x2C8 */ s32 displaylistCounter; - /* 0x2CC */ void* framebuffer; - /* 0x2D0 */ int pad2D0; - /* 0x2D4 */ u32 viConfigFeatures; - /* 0x2D8 */ UNK_TYPE1 gap2D8[0x3]; - /* 0x2DB */ u8 framebufferCounter; - /* 0x2DC */ UNK_TYPE1 pad2DC[0x8]; - /* 0x2E4 */ f32 viConfigXScale; - /* 0x2E8 */ f32 viConfigYScale; - /* 0x2EC */ UNK_TYPE1 pad2EC[0x4]; -} GraphicsContext; // size = 0x2F0 + /* 0x000 */ Gfx* polyOpaBuffer; // Pointer to "Zelda 0" + /* 0x004 */ Gfx* polyXluBuffer; // Pointer to "Zelda 1" + /* 0x008 */ char unk_8[0x8]; // Unused, could this be pointers to "Zelda 2" / "Zelda 3" + /* 0x010 */ Gfx* overlayBuffer; // Pointer to "Zelda 4" + /* 0x014 */ u32 unk_14; + /* 0x018 */ char unk_18[0x20]; + /* 0x038 */ OSMesg msgBuff[8]; + /* 0x058 */ OSMesgQueue* schedMsgQ; + /* 0x05C */ OSMesgQueue queue; + /* 0x074 */ char unk_74[0x04]; + /* 0x078 */ OSScTask task; + /* 0x0E0 */ char unk_E0[0xD0]; + /* 0x1B0 */ Gfx* workBuffer; + /* 0x1B4 */ TwoHeadGfxArena work; + /* 0x1C4 */ Gfx* debugBuffer; + /* 0x1C8 */ TwoHeadGfxArena debug; + /* 0x1D8 */ char unk_1D8[0xAC]; + /* 0x284 */ OSViMode* viMode; + /* 0x288 */ void* zbuffer; + /* 0x28C */ char unk_28C[0x1C]; + /* 0x2A8 */ TwoHeadGfxArena overlay; // "Zelda 4" + /* 0x2B8 */ TwoHeadGfxArena polyOpa; // "Zelda 0" + /* 0x2C8 */ TwoHeadGfxArena polyXlu; // "Zelda 1" + /* 0x2D8 */ u32 gfxPoolIdx; + /* 0x2DC */ u16* curFrameBuffer; + /* 0x2E0 */ char unk_2E0[0x4]; + /* 0x2E4 */ u32 viConfigFeatures; + /* 0x2E8 */ char unk_2E8[0x2]; + /* 0x2EA */ u8 updateViMode; + /* 0x2EB */ u8 framebufferIdx; + /* 0x2EC */ void (*callback)(struct GraphicsContext*, u32); + /* 0x2F0 */ u32 callbackParam; + /* 0x2F4 */ f32 xScale; + /* 0x2F8 */ f32 yScale; + /* 0x2FC */ GfxMasterList* masterList; +} GraphicsContext; // size = 0x300 typedef enum IRQ_MSG_TYPE { IRQ_VERTICAL_RETRACE_MSG = 0x1, @@ -358,11 +305,6 @@ typedef struct { /* 0x10 */ OSTime resetTime; } NmiBuff; // size >= 0x18 -typedef struct { - /* 0x00 */ s16 intPart[16]; - /* 0x20 */ u16 fracPart[16]; -} RSPMatrix; // size = 0x40 - typedef struct { /* 0x0 */ s8 letterboxTarget; /* 0x1 */ s8 letterboxMagnitude; @@ -370,39 +312,6 @@ typedef struct { /* 0x3 */ s8 pillarboxMagnitude; } ShrinkWindowContext; // size = 0x4 -typedef struct { - /* 0x00 */ u8* readBuff; - /* 0x04 */ u32* flashReadBuff; - /* 0x08 */ char unk_08[4]; - /* 0x0C */ s16 status; - /* 0x10 */ u32 curPage; - /* 0x14 */ u32 numPages; - /* 0x18 */ OSTime unk_18; - /* 0x20 */ s16 unk_20; - /* 0x22 */ s16 unk_22; - /* 0x24 */ s16 unk_24; -} SramContext; // size = 0x28 - -typedef struct { - /* 0x00 */ UNK_TYPE4 unk0; - /* 0x04 */ UNK_TYPE4 unk4; - /* 0x08 */ UNK_TYPE4 unk8; - /* 0x0C */ f32 unkC; - /* 0x10 */ Color_RGBA8 unk10; -} TargetContextEntry; // size = 0x14 - -typedef struct { - /* 0x0 */ u32 texture; - /* 0x4 */ s16 unk4; - /* 0x6 */ s16 unk6; - /* 0x8 */ u8 unk8; - /* 0x9 */ u8 unk9; - /* 0xA */ u8 fadeOutDelay; - /* 0xB */ u8 fadeInDelay; - /* 0xC */ s16 alpha; - /* 0xE */ s16 color; -} TitleCardContext; // size = 0x10 - typedef struct { /* 0x0 */ s32 topY; /* 0x4 */ s32 bottomY; @@ -410,14 +319,8 @@ typedef struct { /* 0xC */ s32 rightX; } Viewport; // size = 0x10 -typedef void*(*FaultAddrConvFunc)(void* addr, void* arg); - -typedef void(*fault_client_func)(void* arg1, void* arg2); - typedef void(*osCreateThread_func)(void*); -typedef void* (*PrintCallback)(void*, const char*, size_t); - typedef enum { SLOWLY_CALLBACK_NO_ARGS, SLOWLY_CALLBACK_ONE_ARG, @@ -469,21 +372,6 @@ typedef struct { /* 0x34 */ u32 unk34; } s8018CFAC; // size = 0x38 -typedef struct { - /* 0x0 */ u8 unk0; - /* 0x1 */ u8 unk1; - /* 0x2 */ u8 unk2; - /* 0x3 */ u8 unk3; - /* 0x4 */ u8 unk4; - /* 0x5 */ u8 unk5; - /* 0x6 */ u8 unk6; - /* 0x7 */ u8 unk7; -} s801AEC84; // size = 0x8 - -typedef struct { - /* 0x00 */ UNK_TYPE1 pad0[0x14]; -} s801FE7C0; // size = 0x14 - typedef struct { /* 0x00 */ Vec3f unk0; /* 0x0C */ Vec3f unkC; @@ -491,34 +379,20 @@ typedef struct { /* 0x1A */ s16 unk1A; } s80874650; // size = 0x1C -typedef struct { - /* 0x00 */ Vec3f scale; - /* 0x0C */ Vec3s rotation; - /* 0x14 */ Vec3f pos; -} ActorMeshParams; // size = 0x20 - -typedef struct { - /* 0x0 */ BgPolygonLinkedListNode* nodes; - /* 0x4 */ u32 nextFreeNode; - /* 0x8 */ s32 maxNodes; -} BgPolygonLinkedList; // size = 0xC - -typedef struct { - /* 0x00 */ f32 x[4]; - /* 0x10 */ f32 y[4]; - /* 0x20 */ f32 z[4]; - /* 0x30 */ f32 w[4]; -} z_Matrix; // size = 0x40 - -typedef struct { - /* 0x0 */ Vec3s pos; -} BgVertex; // size = 0x6 - typedef union { F3DVertexColor color; F3DVertexNormal normal; } F3DVertex; // size = 0x10 +// End of RDRAM without the Expansion Pak installed +#define NORMAL_RDRAM_END 0x80400000 +// End of RDRAM with the Expansion Pak installed +#define EXPANDED_RDRAM_END 0x80800000 +// 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; @@ -531,7 +405,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; @@ -539,7 +413,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 { @@ -563,38 +437,14 @@ typedef enum { GFXPRINT_OPEN = 0x80 } GfxPrintFlag; -typedef struct GameState GameState; - -typedef void (*GameStateFunc)(GameState* gameState); - typedef struct { - /* 0x00 */ void* loadedRamAddr; - /* 0x04 */ uintptr_t vromStart; // if applicable - /* 0x08 */ uintptr_t vromEnd; // if applicable - /* 0x0C */ void* vramStart; // if applicable - /* 0x10 */ void* vramEnd; // if applicable - /* 0x14 */ UNK_PTR unk_14; - /* 0x18 */ GameStateFunc init; // initializes and executes the given context - /* 0x1C */ GameStateFunc destroy; // deconstructs the context, and sets the next context to load - /* 0x20 */ UNK_PTR unk_20; - /* 0x24 */ UNK_PTR unk_24; - /* 0x28 */ UNK_TYPE unk_28; - /* 0x2C */ size_t instanceSize; -} GameStateOverlay; // size = 0x30 - -typedef struct { - /* 0x00 */ u16 countdown; - /* 0x04 */ Vec3f originPos; - /* 0x10 */ Vec3f relativePos; + /* 0x00 */ u8 countdown; + /* 0x01 */ u8 playSfxEachFrame; + /* 0x02 */ u16 sfxId; + /* 0x04 */ Vec3f worldPos; + /* 0x10 */ Vec3f projectedPos; } SoundSource; // size = 0x1C -typedef struct { - /* 0x00 */ OSContPad cur; - /* 0x06 */ OSContPad prev; - /* 0x0C */ OSContPad press; // X/Y store delta from last frame - /* 0x12 */ OSContPad rel; // X/Y store adjusted -} Input; // size = 0x18 - typedef struct { /* 0x000 */ u32 magic; /* 0x004 */ GraphicsContext* gfxCtx; @@ -613,25 +463,18 @@ typedef struct { /* 0x0E0 */ Mtx unkE0; /* 0x120 */ Mtx* projectionPtr; /* 0x124 */ Mtx* viewingPtr; - /* 0x128 */ Vec3f quakeRot; - /* 0x134 */ Vec3f quakeScale; - /* 0x140 */ f32 quakeSpeed; - /* 0x144 */ Vec3f currQuakeRot; - /* 0x150 */ Vec3f currQuakeScale; + /* 0x128 */ Vec3f distortionDirRot; + /* 0x134 */ Vec3f distortionScale; + /* 0x140 */ f32 distortionSpeed; + /* 0x144 */ Vec3f curDistortionDirRot; + /* 0x150 */ Vec3f curDistortionScale; /* 0x15C */ u16 normal; - /* 0x15E */ UNK_TYPE1 pad15E[0x2]; /* 0x160 */ u32 flags; // bit 3: Render to an orthographic perspective /* 0x164 */ UNK_TYPE4 unk164; } View; // size = 0x168 typedef void(*fault_update_input_func)(Input* input); -typedef struct { - /* 0x00 */ u8 noteIdx; - /* 0x01 */ u8 state; - /* 0x02 */ u8 pos; -} OcarinaStaff; // size = 0x3; - typedef struct { /* 0x000 */ View view; /* 0x168 */ u8* iconItemSegment; @@ -683,7 +526,7 @@ typedef struct { /* 0x258 */ s16 unk_258; /* 0x25A */ s16 unk_25A; /* 0x25C */ u16 unk_25C; - /* 0x25E */ u16 unk_25E[5]; + /* 0x25E */ u16 unk_25E[5]; // ItemId /* 0x268 */ u16 unk_268[5]; /* 0x272 */ u16 equipTargetItem; /* 0x274 */ u16 equipTargetSlot; @@ -816,9 +659,25 @@ 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; + /* 0x02 */ u16 timeIncrement; /* 0x04 */ f32 unk_4; /* 0x08 */ f32 unk_8; /* 0x0C */ f32 unk_C; @@ -827,8 +686,8 @@ typedef struct { /* 0x12 */ u8 unk_12; /* 0x13 */ u8 unk_13; /* 0x14 */ u8 unk_14; - /* 0x15 */ u8 unk_15; - /* 0x16 */ u8 unk_16; + /* 0x15 */ u8 skyboxDisabled; + /* 0x16 */ u8 sunMoonDisabled; /* 0x17 */ u8 unk_17; /* 0x18 */ u8 unk_18; /* 0x19 */ u8 unk_19; @@ -841,7 +700,7 @@ typedef struct { /* 0x22 */ u16 unk_22; /* 0x24 */ u16 unk_24; /* 0x26 */ u8 unk_26; - /* 0x28 */ LightInfo unk_28; // sun 1 + /* 0x28 */ LightInfo dirLight1; // sun 1 /* 0x36 */ LightInfo unk_36; // sun 2 /* 0x44 */ s8 unk_44; /* 0x48 */ DmaRequest unk_48; @@ -849,7 +708,7 @@ typedef struct { /* 0x80 */ OSMesg unk_80; /* 0x84 */ f32 unk_84; /* 0x88 */ f32 unk_88; - /* 0x8C */ LightSettings2 unk_8C; + /* 0x8C */ EnvLightSettings lightSettings; /* 0xA8 */ f32 unk_A8; /* 0xAC */ Vec3s windDir; /* 0xB4 */ f32 windSpeed; @@ -858,33 +717,32 @@ typedef struct { /* 0xC0 */ u8 unk_C0; /* 0xC1 */ u8 unk_C1; /* 0xC2 */ u8 unk_C2; - /* 0xC3 */ u8 unk_C3; + /* 0xC3 */ u8 lightSettingOverride; /* 0xC4 */ LightSettings unk_C4; /* 0xDA */ u16 unk_DA; - /* 0xDC */ f32 unk_DC; + /* 0xDC */ f32 lightBlend; /* 0xE0 */ u8 unk_E0; /* 0xE1 */ u8 unk_E1; /* 0xE2 */ s8 unk_E2; /* 0xE3 */ u8 unk_E3; // modified by unused func in EnWeatherTag /* 0xE4 */ u8 unk_E4; - /* 0xE5 */ u8 unk_E5; - /* 0xE6 */ u8 unk_E6[4]; - /* 0xEA */ u8 unk_EA; + /* 0xE5 */ u8 fillScreen; + /* 0xE6 */ u8 screenFillColor[4]; + /* 0xEA */ u8 sandstormState; /* 0xEB */ u8 unk_EB; /* 0xEC */ u8 unk_EC; /* 0xED */ u8 unk_ED; /* 0xEE */ u8 unk_EE[4]; - /* 0xF2 */ u8 unk_F2[8]; + /* 0xF2 */ u8 unk_F2[8]; // [3] is used by both DemoKankyo and ObjectKankyo particle count /* 0xFA */ u8 unk_FA[4]; } EnvironmentContext; // size = 0x100 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; @@ -905,6 +763,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; @@ -955,72 +817,106 @@ typedef struct { typedef struct { /* 0x00000 */ View view; /* 0x00168 */ Font font; - /* 0x11EF4 */ char unk_11EF4[0x10]; - /* 0x11F04 */ u16 unk11F04; + /* 0x11EF4 */ char unk_11EF4[0x4]; + /* 0x11EF8 */ UNK_PTR unk11EF8; + /* 0x11EFC */ UNK_TYPE1 unk11EFC[0x8]; + /* 0x11F04 */ u16 currentTextId; /* 0x11F06 */ UNK_TYPE1 pad11F06[0x4]; /* 0x11F0A */ u8 unk11F0A; /* 0x11F0B */ UNK_TYPE1 pad11F0B[0x5]; /* 0x11F10 */ s32 unk11F10; - /* 0x11F14 */ UNK_TYPE1 pad11F14[0xE]; - /* 0x11F22 */ u8 unk11F22; - /* 0x11F23 */ UNK_TYPE1 pad11F23[0xFD]; + /* 0x11F14 */ UNK_TYPE1 pad11F14[0x6]; + /* 0x11F1A */ s16 unk11F1A[3]; + /* 0x11F20 */ UNK_TYPE1 pad11F20[0x2]; + /* 0x11F22 */ u8 msgMode; + /* 0x11F23 */ UNK_TYPE1 pad11F23; + /* 0x11F24 */ union { + u8 schar[206]; + u16 wchar[103]; + } decodedBuffer; + /* 0x11FF2 */ u16 unk11FF2; + /* 0x11FF4 */ s16 unk11FF4; + /* 0x11FF6 */ s16 unk11FF6; + /* 0x11FF8 */ UNK_TYPE1 unk11FF8[0x6]; + /* 0x11FFE */ s16 unk11FFE[0x3]; + /* 0x12004 */ s16 unk12004; + /* 0x12006 */ s16 unk12006; + /* 0x12008 */ u8 unk12008[0x16]; + /* 0x1201E */ s16 unk1201E; /* 0x12020 */ u8 unk12020; /* 0x12021 */ u8 choiceIndex; - /* 0x12022 */ UNK_TYPE1 unk12022; + /* 0x12022 */ u8 unk12022; /* 0x12023 */ u8 unk12023; - /* 0x12024 */ UNK_TYPE1 unk12024[0x6]; - /* 0x1202A */ u16 unk1202A; - /* 0x1202C */ UNK_TYPE1 pad1202C[0x2]; + /* 0x12024 */ s16 unk12024; + /* 0x12026 */ u16 unk12026; + /* 0x12028 */ u16 songPlayed; + /* 0x1202A */ u16 ocarinaMode; + /* 0x1202C */ u16 ocarinaAction; /* 0x1202E */ u16 unk1202E; - /* 0x12030 */ UNK_TYPE1 pad12030[0x14]; + /* 0x12030 */ s16 unk_12030; + /* 0x12032 */ UNK_TYPE1 unk_12032[0x2]; + /* 0x12034 */ UNK_TYPE1 pad12034[0x6]; + /* 0x1203A */ s16 unk1203A; + /* 0x1203C */ s16 unk1203C; + /* 0x1203E */ s16 pad1203E; + /* 0x12040 */ Actor* unkActor; /* 0x12044 */ s16 unk12044; - /* 0x12046 */ UNK_TYPE1 pad12046[0x24]; + /* 0x12046 */ s16 unk12046; + /* 0x12048 */ u8 unk12048; // EnKakasi + /* 0x12049 */ UNK_TYPE1 pad12049[0x1]; + /* 0x1204A */ s16 unk1204A[0x5]; + /* 0x12054 */ s16 unk12054[3]; // First, second and third digits in lottery code guess + /* 0x1205A */ UNK_TYPE1 pad1205A[0xE]; + /* 0x12068 */ s16 unk12068; /* 0x1206A */ s16 unk1206A; /* 0x1206C */ s32 unk1206C; - /* 0x12070 */ UNK_TYPE1 pad12070[0x8]; + /* 0x12070 */ s32 unk12070; + /* 0x12074 */ UNK_TYPE1 pad12074[0x4]; /* 0x12078 */ s32 bankRupeesSelected; - /* 0x1207C */ s32 bankRupees; - /* 0x12080 */ UNK_TYPE1 pad12080[0x31]; + /* 0x1207C */ s32 bankRupees; + /* 0x12080 */ MessageTableEntry* messageEntryTable; + /* 0x12084 */ MessageTableEntry* messageEntryTableNes; + /* 0x12088 */ UNK_TYPE4 unk12088; + /* 0x1208C */ MessageTableEntry* messageTableStaff; + /* 0x12090 */ s16 unk12090; + /* 0x12092 */ s16 unk12092; + /* 0x12094 */ s8 unk12094; + /* 0x12095 */ UNK_TYPE1 unk12095[0x3]; + /* 0x12098 */ f32 unk12098; // Text_Scale? + /* 0x1209C */ s16 unk1209C; + /* 0x1209E */ UNK_TYPE1 unk1209E[0x2]; + /* 0x120A0 */ s32 unk120A0; + /* 0x120A4 */ UNK_TYPE1 unk120A4[0xC]; + /* 0x120B0 */ u8 unk120B0; /* 0x120B1 */ u8 unk120B1; - /* 0x120B2 */ UNK_TYPE1 pad120B2[0x22]; - /* 0x120D4 */ UNK_TYPE2 unk120D4; - /* 0x120D6 */ UNK_TYPE2 unk120D6; + /* 0x120B2 */ u8 unk120B2[0xC]; + /* 0x120BE */ s16 unk120BE; + /* 0x120C0 */ s16 unk120C0; + /* 0x120C2 */ s16 unk120C2; + /* 0x120C4 */ s32 unk120C4; + /* 0x120C8 */ s16 unk120C8; + /* 0x120CA */ s16 unk120CA; + /* 0x120CC */ s16 unk120CC; + /* 0x120CE */ s16 unk120CE; + /* 0x120D0 */ s16 unk120D0; + /* 0x120D2 */ s16 unk120D2; + /* 0x120D4 */ s16 unk120D4; + /* 0x120D6 */ s16 unk120D6; /* 0x120D8 */ UNK_TYPE1 pad120D8[0x8]; } MessageContext; // size = 0x120E0 -typedef struct ArenaNode_t { - /* 0x0 */ s16 magic; // Should always be 0x7373 - /* 0x2 */ s16 isFree; - /* 0x4 */ size_t size; - /* 0x8 */ struct ArenaNode_t* next; - /* 0xC */ struct ArenaNode_t* prev; -} ArenaNode; // size = 0x10 - -typedef struct { - /* 0x00 */ ArenaNode* head; - /* 0x04 */ void* start; - /* 0x08 */ OSMesgQueue lock; - /* 0x20 */ u8 unk20; - /* 0x21 */ u8 isInit; - /* 0x22 */ u8 flag; -} Arena; // size = 0x24 - -typedef struct FaultAddrConvClient FaultAddrConvClient; - -struct FaultAddrConvClient { - /* 0x0 */ FaultAddrConvClient* next; - /* 0x4 */ FaultAddrConvFunc callback; +typedef struct FaultAddrConvClient { + /* 0x0 */ struct FaultAddrConvClient* next; + /* 0x4 */ void* (*callback)(void*, void*); /* 0x8 */ void* param; -}; // size = 0xC +} FaultAddrConvClient; // size = 0xC -typedef struct FaultClient FaultClient; - -struct FaultClient { - /* 0x0 */ FaultClient* next; - /* 0x4 */ fault_client_func callback; +typedef struct FaultClient { + /* 0x0 */ struct FaultClient* next; + /* 0x4 */ void (*callback)(void*, void*); /* 0x8 */ void* param0; /* 0xC */ void* param1; -}; // size = 0x10 +} FaultClient; // size = 0x10 typedef struct { /* 0x000 */ OSThread thread; @@ -1044,9 +940,28 @@ typedef struct FireObj FireObj; typedef struct FireObjLight FireObjLight; -typedef struct GameAllocNode { - /* 0x0 */ struct GameAllocNode* next; - /* 0x4 */ struct GameAllocNode* prev; +struct GameState; + +typedef void (*GameStateFunc)(struct GameState* gameState); + +typedef struct { + /* 0x00 */ void* loadedRamAddr; + /* 0x04 */ uintptr_t vromStart; // if applicable + /* 0x08 */ uintptr_t vromEnd; // if applicable + /* 0x0C */ void* vramStart; // if applicable + /* 0x10 */ void* vramEnd; // if applicable + /* 0x14 */ UNK_PTR unk_14; + /* 0x18 */ GameStateFunc init; // initializes and executes the given context + /* 0x1C */ GameStateFunc destroy; // deconstructs the context, and sets the next context to load + /* 0x20 */ UNK_PTR unk_20; + /* 0x24 */ UNK_PTR unk_24; + /* 0x28 */ UNK_TYPE unk_28; + /* 0x2C */ size_t instanceSize; +} GameStateOverlay; // size = 0x30 + +typedef struct GameAllocEntry { + /* 0x0 */ struct GameAllocEntry* next; + /* 0x4 */ struct GameAllocEntry* prev; /* 0x8 */ size_t size; /* 0xC */ u32 unk_0C; } GameAllocEntry; // size = 0x10 @@ -1056,7 +971,7 @@ typedef struct GameAlloc { /* 0x10 */ GameAllocEntry* head; } GameAlloc; // size = 0x14 -struct GameState { +typedef struct GameState { /* 0x00 */ GraphicsContext* gfxCtx; /* 0x04 */ GameStateFunc main; /* 0x08 */ GameStateFunc destroy; @@ -1070,8 +985,8 @@ struct GameState { /* 0x9C */ u32 frames; /* 0xA0 */ u8 padA0[0x2]; /* 0xA2 */ u8 framerateDivisor; // game speed? - /* 0xA3 */ UNK_TYPE1 unkA3; -}; // size = 0xA4 + /* 0xA3 */ u8 unk_A3; +} GameState; // size = 0xA4 typedef struct PreNMIContext { /* 0x00 */ GameState state; @@ -1094,8 +1009,6 @@ typedef void (*ColChkApplyFunc)(GlobalContext*, CollisionCheckContext*, Collider typedef void (*ColChkVsFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Collider*); typedef s32 (*ColChkLineFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*); -typedef void(*cutscene_update_func)(GlobalContext* globalCtx, CutsceneContext* cCtxt); - typedef void(*draw_func)(GlobalContext* globalCtx, s16 index); typedef void(*room_draw_func)(GlobalContext* globalCtx, Room* room, u32 flags); @@ -1170,7 +1083,7 @@ typedef struct Camera { /* 0x15E */ s16 animState; /* 0x160 */ s16 unk160; /* 0x162 */ s16 timer; - /* 0x164 */ s16 thisIdx; + /* 0x164 */ s16 camId; /* 0x166 */ s16 prevCamDataIdx; /* 0x168 */ s16 unk168; /* 0x16A */ s16 unk16A; @@ -1199,7 +1112,7 @@ typedef struct { /* 0x1A */ s16 speed; /* 0x1C */ s16 isShakePerpendicular; /* 0x1E */ s16 countdown; - /* 0x20 */ s16 cameraPtrsIdx; + /* 0x20 */ s16 camId; } QuakeRequest; // size = 0x24 typedef struct { @@ -1228,37 +1141,13 @@ typedef struct { /* 0x4 */ s32 type; // bitfield, highest set bit determines type /* 0x8 */ s16 countdown; /* 0xA */ s16 state; -} Quake2Context; // size = 0xC +} DistortionContext; // size = 0xC typedef enum { - QUAKE2_INACTIVE, - QUAKE2_ACTIVE, - QUAKE2_SETUP, -} Quake2State; - -typedef struct IrqMgrClient_t { - /* 0x0 */ struct IrqMgrClient_t* next; - /* 0x4 */ OSMesgQueue* queue; -} IrqMgrClient; // size = 0x8 - -typedef struct { - /* 0x0 */ s16 type; - /* 0x2 */ u8 misc[30]; -} OSScMsg; - -typedef struct { - /* 0x000 */ OSScMsg verticalRetraceMesg; - /* 0x020 */ OSScMsg prenmiMsg; - /* 0x040 */ OSScMsg nmiMsg; - /* 0x060 */ OSMesgQueue irqQueue; - /* 0x078 */ OSMesg irqBuffer[8]; - /* 0x098 */ OSThread thread; - /* 0x248 */ IrqMgrClient* callbacks; - /* 0x24C */ u8 prenmiStage; - /* 0x250 */ OSTime lastPrenmiTime; - /* 0x258 */ OSTimer prenmiTimer; - /* 0x278 */ OSTime lastFrameTime; -} IrqMgr; // size = 0x280 + /* 0 */ DISTORTION_INACTIVE, + /* 1 */ DISTORTION_ACTIVE, + /* 2 */ DISTORTION_SETUP +} DistortionState; typedef struct { /* 0x000 */ u8 controllers; // bit 0 is set if controller 1 is plugged in, etc. @@ -1283,56 +1172,9 @@ typedef struct { /* 0x47F */ UNK_TYPE1 pad47F[0x1]; } PadMgr; // size = 0x480 -#define OS_SC_NEEDS_RDP 0x0001 -#define OS_SC_NEEDS_RSP 0x0002 -#define OS_SC_DRAM_DLIST 0x0004 -#define OS_SC_PARALLEL_TASK 0x0010 -#define OS_SC_LAST_TASK 0x0020 -#define OS_SC_SWAPBUFFER 0x0040 - -#define OS_SC_RCP_MASK 0x0003 -#define OS_SC_TYPE_MASK 0x0007 - -#define OS_SC_DP 0x0001 -#define OS_SC_SP 0x0002 -#define OS_SC_YIELD 0x0010 -#define OS_SC_YIELDED 0x0020 - -typedef struct OSScTask { - /* 0x00 */ struct OSScTask* next; - /* 0x04 */ u32 state; - /* 0x08 */ u32 flags; - /* 0x0C */ CfbInfo* framebuffer; - /* 0x10 */ OSTask list; - /* 0x50 */ OSMesgQueue* msgQ; - /* 0x54 */ OSMesg msg; -} OSScTask; // size = 0x58 - -typedef struct { - /* 0x0000 */ OSMesgQueue interruptQ; - /* 0x0018 */ OSMesg intBuf[64]; - /* 0x0118 */ OSMesgQueue cmdQ; - /* 0x0130 */ OSMesg cmdMsgBuf[8]; - /* 0x0150 */ OSThread thread; - /* 0x0300 */ OSScTask* audioListHead; - /* 0x0304 */ OSScTask* gfxListHead; - /* 0x0308 */ OSScTask* audioListTail; - /* 0x030C */ OSScTask* gfxListTail; - /* 0x0310 */ OSScTask* curRSPTask; - /* 0x0314 */ OSScTask* curRDPTask; - /* 0x0318 */ s32 retraceCount; - /* 0x0318 */ s32 doAudio; - /* 0x0320 */ CfbInfo* curBuf; - /* 0x0324 */ CfbInfo* pendingSwapBuf1; - /* 0x0328 */ CfbInfo* pendingSwapBuf2; - /* 0x032C */ char unk_32C[0x3]; - /* 0x032F */ u8 shouldUpdateVi; - /* 0x0330 */ IrqMgrClient irqClient; -} SchedContext; // size = 0x338 - -typedef struct StackEntry_t { - /* 0x00 */ struct StackEntry_t* next; - /* 0x04 */ struct StackEntry_t* prev; +typedef struct StackEntry { + /* 0x00 */ struct StackEntry* next; + /* 0x04 */ struct StackEntry* prev; /* 0x08 */ u32 head; /* 0x0C */ u32 tail; /* 0x10 */ u32 initValue; @@ -1346,35 +1188,17 @@ typedef enum { STACK_STATUS_OVERFLOW = 2 } StackStatus; -typedef struct TargetContext TargetContext; - -typedef struct ActorContext ActorContext; - -typedef struct s800B948C s800B948C; - struct FireObjLight { /* 0x00 */ LightNode* light; - /* 0x04 */ LightInfoPositional lightInfo; - /* 0x12 */ u8 unk12; + /* 0x04 */ LightInfo lightInfo; + /* 0x12 */ u8 lightParamsIndex; }; // size = 0x13 -typedef struct ActorListEntry { - /* 0x0 */ s32 length; // number of actors loaded of this type - /* 0x4 */ Actor* first; // pointer to first actor of this type - /* 0x8 */ UNK_TYPE1 pad8[0x4]; -} ActorListEntry; // size = 0xC - #define OS_SC_RETRACE_MSG 1 #define OS_SC_DONE_MSG 2 #define OS_SC_NMI_MSG 3 // name is made up, 3 is OS_SC_RDP_DONE_MSG in the original sched.c #define OS_SC_PRE_NMI_MSG 4 -typedef struct { - /* 0x0000 */ OSTask task; - /* 0x0040 */ OSMesgQueue* taskQueue; - /* 0x0044 */ char unk_44[0xC]; -} AudioTask; // size = 0x50 - typedef struct { /* 0x000 */ IrqMgr* irqMgr; /* 0x004 */ SchedContext* sched; @@ -1389,7 +1213,7 @@ typedef struct { /* 0x12C */ UNK_TYPE1 pad_12C[0x4]; /* 0x130 */ OSThread thread; } AudioMgr; // size = 0x2E0 - + typedef struct { /* 0x00 */ MtxF displayMatrix; /* 0x40 */ Actor* actor; @@ -1418,7 +1242,7 @@ struct FireObj { /* 0x24 */ u8 state; // 0 - growing, 1 - shrinking, 2 - fully lit, 3 - not lit /* 0x25 */ u8 sizeGrowsCos2; /* 0x26 */ u8 unk26; - /* 0x27 */ u8 unk27; + /* 0x27 */ u8 colorsIndex; /* 0x28 */ u8 flags; // bit 0 - ?, bit 1 - ? /* 0x29 */ UNK_TYPE1 pad29[0x1]; /* 0x2A */ s16 ignitionDelay; @@ -1426,78 +1250,6 @@ struct FireObj { /* 0x78 */ FireObjLight light; }; // size = 0x8B -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; - /* 0x38 */ Actor* unk38; - /* 0x3C */ Actor* unk3C; - /* 0x40 */ f32 unk40; - /* 0x44 */ f32 unk44; - /* 0x48 */ s16 unk48; - /* 0x4A */ u8 unk4A; - /* 0x4B */ u8 unk4B; - /* 0x4C */ s8 unk4C; - /* 0x4D */ UNK_TYPE1 pad4D[0x3]; - /* 0x50 */ TargetContextEntry unk50[3]; - /* 0x8C */ Actor* unk8C; - /* 0x90 */ Actor* unk90; - /* 0x94 */ UNK_TYPE1 pad94[0x4]; -}; // size = 0x98 - -struct s800B948C { - /* 0x00 */ GlobalContext* globalCtx; - /* 0x04 */ Actor* actor; - /* 0x08 */ u32 updateActorIfSet; - /* 0x0C */ u32 unkC; - /* 0x10 */ Actor* unk10; - /* 0x14 */ Player* player; - /* 0x18 */ u32 runMainIfSet; // Bitmask of actor flags. The actor will only have main called if it has at least 1 flag set that matches this bitmask -}; // size = 0x1C - -struct ActorContext { - /* 0x000 */ UNK_TYPE1 pad0[0x2]; - /* 0x002 */ u8 unk2; - /* 0x003 */ u8 unk3; - /* 0x004 */ s8 unk4; - /* 0x005 */ u8 unk5; - /* 0x006 */ UNK_TYPE1 pad6[0x5]; - /* 0x00B */ s8 unkB; - /* 0x00C */ s16 unkC; - /* 0x00E */ u8 totalLoadedActors; - /* 0x00F */ u8 undrawnActorCount; - /* 0x010 */ ActorListEntry actorList[12]; - /* 0x0A0 */ Actor* undrawnActors[32]; // Records the first 32 actors drawn each frame - /* 0x120 */ TargetContext targetContext; - /* 0x1B8 */ u32 switchFlags[4]; // First 0x40 are permanent, second 0x40 are temporary - /* 0x1C8 */ u32 chestFlags; - /* 0x1CC */ u32 clearedRooms; - /* 0x1D0 */ u32 clearedRoomsTemp; - /* 0x1D4 */ u32 collectibleFlags[4]; // bitfield of 128 bits - /* 0x1E4 */ TitleCardContext titleCtxt; - /* 0x1F4 */ u8 unk1F4; - /* 0x1F5 */ u8 unk1F5; - /* 0x1F6 */ UNK_TYPE1 pad1F6[0x2]; - /* 0x1F8 */ f32 unk1F8; - /* 0x1FC */ Vec3f unk1FC; - /* 0x208 */ UNK_TYPE1 pad208[0x48]; - /* 0x250 */ void* unk250; // allocation of 0x20f0 bytes? - /* 0x254 */ u32 unk254[5]; - /* 0x268 */ u8 unk268; - /* 0x269 */ UNK_TYPE1 pad269[0x3]; - /* 0x26C */ UNK_TYPE1 pad26C[0xC]; - /* 0x278 */ u16 unk278; - /* 0x27A */ UNK_TYPE1 pad27A[0x2]; - /* 0x27C */ UNK_TYPE1 pad27C[0x8]; -}; // size = 0x284 - typedef struct { /* 0x00 */ u8 seqIndex; /* 0x01 */ u8 nightSeqIndex; @@ -1560,7 +1312,7 @@ struct GlobalContext { /* 0x18760 */ DoorContext doorCtx; /* 0x18768 */ void (*playerInit)(Player* player, struct GlobalContext* globalCtx, FlexSkeletonHeader* skelHeader); /* 0x1876C */ void (*playerUpdate)(Player* player, struct GlobalContext* globalCtx, Input* input); - /* 0x18770 */ void* unk_18770; //! @TODO: Determine function prototype + /* 0x18770 */ void (*unk_18770)(struct GlobalContext* globalCtx, Player* player); /* 0x18774 */ s32 (*startPlayerFishing)(struct GlobalContext* globalCtx); /* 0x18778 */ s32 (*grabPlayer)(struct GlobalContext* globalCtx, Player* player); /* 0x1877C */ s32 (*startPlayerCutscene)(struct GlobalContext* globalCtx, Player* player, s32 mode); @@ -1571,11 +1323,11 @@ struct GlobalContext { /* 0x18790 */ void (*unk_18790)(struct GlobalContext* globalCtx, s16 arg1, Actor* actor); /* 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; + /* 0x1879C */ s16 playerActorCsIds[10]; + /* 0x187B0 */ MtxF viewProjectionMtxF; /* 0x187F0 */ Vec3f unk_187F0; - /* 0x187FC */ MtxF mf_187FC; - /* 0x1883C */ Mtx* unk_1883C; + /* 0x187FC */ MtxF billboardMtxF; + /* 0x1883C */ Mtx* billboardMtx; /* 0x18840 */ u32 gameplayFrames; /* 0x18844 */ u8 unk_18844; /* 0x18845 */ u8 unk_18845; @@ -1584,7 +1336,7 @@ struct GlobalContext { /* 0x1884C */ RomFile* roomList; /* 0x18850 */ ActorEntry* linkActorEntry; /* 0x18854 */ ActorEntry* setupActorList; - /* 0x18858 */ void* unk_18858; + /* 0x18858 */ CsCamData* csCamData; /* 0x1885C */ EntranceEntry* setupEntranceList; /* 0x18860 */ u16* setupExitList; /* 0x18864 */ Path* setupPathList; @@ -1599,7 +1351,7 @@ struct GlobalContext { /* 0x1887C */ s8 unk_1887C; /* 0x1887D */ s8 unk_1887D; /* 0x1887E */ s8 unk_1887E; - /* 0x1887F */ u8 unk_1887F; + /* 0x1887F */ u8 unk_1887F; // fadeTransition /* 0x18880 */ u8 unk_18880; /* 0x18884 */ CollisionCheckContext colChkCtx; /* 0x18B20 */ u16 envFlags[20]; @@ -1609,7 +1361,9 @@ struct GlobalContext { /* 0x18B4C */ PreRender pauseBgPreRender; /* 0x18B9C */ char unk_18B9C[0x2B8]; /* 0x18E54 */ SceneTableEntry* loadedScene; - /* 0x18E58 */ char unk_18E58[0x400]; + /* 0x18E58 */ char unk_18E58[0x10]; + /* 0x18E68 */ s32 unk_18E68; + /* 0x18E6C */ char unk_18E6C[0x3EC]; }; // size = 0x19258 typedef struct { @@ -1633,12 +1387,6 @@ typedef struct { /* 0x24 */ s16 unk_24; } struct_800BD888_arg1; // size = 0x28 -typedef struct { - /* 0x0 */ u8 unk0; - /* 0x4 */ s32 unk4; - /* 0x8 */ s32 unk8; -} struct_80133038_arg2; // size = 0xC - typedef struct { /* 0x00 */ u32 type; /* 0x04 */ u32 setScissor; @@ -1662,19 +1410,94 @@ typedef struct { /* 0x14 */ Gfx* monoDl; } VisMono; // size = 0x18 -typedef enum { - MTXMODE_NEW, // generates a new matrix - MTXMODE_APPLY // applies transformation to the current matrix -} MatrixMode; +typedef struct DebugDispObject { + /* 0x00 */ Vec3f pos; + /* 0x0C */ Vec3s rot; + /* 0x14 */ Vec3f scale; + /* 0x20 */ Color_RGBA8 color; + /* 0x24 */ s16 type; + /* 0x28 */ struct DebugDispObject* next; + /* 0x2C */ s32 pad; //Padding not in the OOT version +} DebugDispObject; // size = 0x30 typedef struct { - /* 0x00 */ u16 intPart[4][4]; - /* 0x20 */ u16 fracPart[4][4]; -} MatrixInternal; // size = 0x40 + /* 0x0 */ f32 rangeSq; + /* 0x4 */ f32 leashScale; +} TargetRangeParams; // size = 0x8 typedef struct { /* 0x00 */ u8* value; /* 0x04 */ const char* name; } FlagSetEntry; // size = 0x08 +// TODO: Dedicated Header? +#define FRAM_BASE_ADDRESS 0x08000000 // FRAM Base Address in Cart Memory +#define FRAM_STATUS_REGISTER FRAM_BASE_ADDRESS // FRAM Base Address in Cart Memory +#define FRAM_COMMAND_REGISTER 0x10000 // Located at 0x08010000 on the Cart + +enum fram_command { + /* Does nothing for FRAM_COMMAND_SET_MODE_READ_AND_STATUS, FRAM_MODE_NOP, FRAM_COMMAND_SET_MODE_STATUS_AND_STATUS + Initializes fram to 0xFF in FRAM_MODE_ERASE + Writes Contents in FLASHRAM_MODE_WRITE + After execution, sets FRAM_MODE to FRAM_MODE_NOP */ + FRAM_COMMAND_EXECUTE = 0xD2000000, + /* flashram->erase_offset = (command & 0xffff) * 128; */ + FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET = 0x4B000000, + /* flashram->mode = FLASHRAM_MODE_ERASE; + flashram->status = 0x1111800800c20000LL; */ + FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS = 0x78000000, + /* flashram->erase_offset = (command & 0xffff) * 128; + flashram->status = 0x1111800400c20000LL; */ + FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET_AND_STATUS = 0xA5000000, + /* flashram->mode = FLASHRAM_MODE_WRITE; */ + FRAM_COMMAND_SET_MODE_WRITE = 0xB4000000, + /* flashram->mode = FLASHRAM_MODE_STATUS; + flashram->status = 0x1111800100c20000LL; */ + FRAM_COMMAND_SET_MODE_STATUS_AND_STATUS = 0xE1000000, + /* flashram->mode = FLASHRAM_MODE_READ; + flashram->status = 0x11118004f0000000LL; */ + FRAM_COMMAND_SET_MODE_READ_AND_STATUS = 0xF0000000, + /* unk */ + FRAM_COMMAND_UNK_ERASE_OPERATION = 0x3C000000 +}; + +enum fram_mode { + FRAM_MODE_NOP = 0, + FRAM_MODE_ERASE, + FRAM_MODE_WRITE, + FRAM_MODE_READ, + FRAM_MODE_STATUS +}; + +typedef struct { + /* 0x00 */ UNK_TYPE1 unk_00[0x14]; + /* 0x14 */ s16 unk_14; + /* 0x16 */ s16 unk_16; + /* 0x18 */ s16 unk_18; + /* 0x1A */ UNK_TYPE1 unk_1A[0x3]; + /* 0x0C */ u8 unk_1D; + /* 0x1E */ UNK_TYPE1 unk_1E[0xC]; + /* 0x2A */ s16 unk_2A; + /* 0x1E */ UNK_TYPE1 unk_2C[0x1]; + /* 0x2D */ u8 unk_2D; + /* 0x2E */ UNK_TYPE1 unk_2E[2]; +} DbCameraUnkSubStruct; // size = 0x30 + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ s16 unk_04; + /* 0x06 */ s16 unk_06; + /* 0x08 */ s16 unk_08; + /* 0x0A */ s16 unk_0A; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ UNK_TYPE1 unk_0E[0x02]; + /* 0x10 */ DbCameraUnkSubStruct unk_10; + /* 0x40 */ DbCameraUnkSubStruct unk_40; + /* 0x70 */ UNK_PTR unk_70; + /* 0x74 */ UNK_PTR unk_74; + /* 0x78 */ UNK_PTR unk_78; + /* 0x7C */ Camera* camera; +} DbCameraUnkStruct; // size = 0x80 + #endif diff --git a/include/z64actor.h b/include/z64actor.h index 5876251fb..c7724bcd7 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -1,5 +1,5 @@ -#ifndef _Z64ACTOR_H_ -#define _Z64ACTOR_H_ +#ifndef Z64ACTOR_H +#define Z64ACTOR_H #include "PR/ultratypes.h" #include "z64math.h" @@ -7,6 +7,8 @@ #include "z64collision_check.h" #include "unk.h" +// This value is hardcoded to be the size of ovl_Arrow_Fire which currently is the biggest actor that uses the AM_FIELD. +#define AM_FIELD_SIZE SEGMENT_SIZE(ovl_Arrow_Fire) #define MASS_IMMOVABLE 0xFF // Cannot be pushed by OC collisions #define MASS_HEAVY 0xFE // Can only be pushed by OC collisions with IMMOVABLE and HEAVY objects. @@ -15,6 +17,8 @@ struct GlobalContext; struct Lights; struct CollisionPoly; +struct EnBox; + typedef void(*ActorFunc)(struct Actor* this, struct GlobalContext* globalCtx); typedef struct { @@ -76,31 +80,6 @@ typedef struct { /* 0x3A */ s16 unk3A; } ActorEnTest20C; // size = 0x3C -struct EnDno_ActorUnkStruct; -typedef s32 (*EnDno_ActorUnkFunc)(struct GlobalContext*, struct EnDno_ActorUnkStruct*); - -typedef struct EnDno_ActorUnkStruct { - /* 0x00 */ Vec3f unk_00; - /* 0x0C */ UNK_TYPE1 unk_0C[0x4]; - /* 0x10 */ s16 unk_10; - /* 0x12 */ UNK_TYPE1 unk_12[0xA]; - /* 0x1C */ u8 unk_1C; - /* 0x1D */ u8 unk_1D; - /* 0x20 */ Vec3f unk_20; - /* 0x2C */ Vec3f unk_2C; - /* 0x38 */ UNK_TYPE1 unk_38[0x10]; - /* 0x48 */ struct Actor* unk_48; - /* 0x4C */ f32 unk_4C; - /* 0x50 */ f32 unk_50; - /* 0x54 */ s16 unk_54; - /* 0x56 */ s16 unk_56; - /* 0x58 */ s32 unk_58; - /* 0x5C */ EnDno_ActorUnkFunc unk_5C; - /* 0x60 */ EnDno_ActorUnkFunc unk_60; - /* 0x64 */ EnDno_ActorUnkFunc unk_64; - /* 0x68 */ EnDno_ActorUnkFunc unk_68; -} EnDno_ActorUnkStruct; // size >= 0x6C - typedef struct { /* 0x00 */ s16 id; /* 0x02 */ u8 type; @@ -141,6 +120,8 @@ typedef struct { /* 0x10 */ f32 shadowScale; // Changes the size of the shadow /* 0x14 */ u8 shadowAlpha; // Default is 255 /* 0x15 */ u8 feetFloorFlags; // Set if the actor's foot is clipped under the floor. & 1 is right foot, & 2 is left + /* 0x16 */ u8 unk_16; + /* 0x17 */ u8 unk_17; /* 0x18 */ Vec3f feetPos[2]; // Update by using `Actor_SetFeetPos` in PostLimbDrawOpa } ActorShape; // size = 0x30 @@ -156,27 +137,27 @@ typedef struct Actor { /* 0x020 */ s16 unk20; /* 0x024 */ PosRot world; // Position/rotation in the world /* 0x038 */ s8 cutscene; - /* 0x039 */ s8 unk39; + /* 0x039 */ u8 audioFlags; // Another set of flags? Seems related to sfx or bgm /* 0x03C */ PosRot focus; // Target reticle focuses on this position. For player this represents head pos and rot - /* 0x050 */ u16 sfx; // SFX ID to play. Sound plays when value is set, then is cleared the following update cycle + /* 0x050 */ u16 sfxId; // Id of sound effect to play. Plays when value is set, then is cleared the following update cycle /* 0x054 */ f32 targetArrowOffset; // Height offset of the target arrow relative to `focus` position /* 0x058 */ Vec3f scale; // Scale of the actor in each axis /* 0x064 */ Vec3f velocity; // Velocity of the actor in each axis /* 0x070 */ f32 speedXZ; // How fast the actor is traveling along the XZ plane /* 0x074 */ f32 gravity; // Acceleration due to gravity. Value is added to Y velocity every frame - /* 0x078 */ f32 minVelocityY; // Sets the lower bounds cap on velocity along the Y axis + /* 0x078 */ f32 terminalVelocity; // Sets the lower bounds cap on velocity along the Y axis /* 0x07C */ struct CollisionPoly* wallPoly; // Wall polygon the actor is touching /* 0x080 */ struct CollisionPoly* floorPoly; // Floor polygon directly below the actor /* 0x084 */ u8 wallBgId; // Bg ID of the wall polygon the actor is touching /* 0x085 */ u8 floorBgId; // Bg ID of the floor polygon directly below the actor /* 0x086 */ s16 wallYaw; // Y rotation of the wall polygon the actor is touching /* 0x088 */ f32 floorHeight; // Y position of the floor polygon directly below the actor - /* 0x08C */ f32 yDistToWater; // Distance to the surface of active waterbox. Negative value means above water + /* 0x08C */ f32 depthInWater; // Directed distance to the surface of active waterbox. Negative value means water is below. /* 0x090 */ u16 bgCheckFlags; // See comments below actor struct for wip docs. TODO: macros for these flags /* 0x092 */ s16 yawTowardsPlayer; // Y rotation difference between the actor and the player /* 0x094 */ f32 xyzDistToPlayerSq; // Squared distance between the actor and the player in the x,y,z axis /* 0x098 */ f32 xzDistToPlayer; // Distance between the actor and the player in the XZ plane - /* 0x09C */ f32 yDistToPlayer; // Dist is negative if the actor is above the player + /* 0x09C */ f32 playerHeightRel; // Directed distance is negative if the player is below. /* 0x0A0 */ CollisionCheckInfo colChkInfo; // Variables related to the Collision Check system /* 0x0BC */ ActorShape shape; // Variables related to the physical shape of the actor /* 0x0EC */ Vec3f projectedPos; // Position of the actor in projected space @@ -193,12 +174,12 @@ typedef struct Actor { /* 0x11C */ u8 colorFilterTimer; // A non-zero value enables the color filter. Decrements automatically /* 0x11D */ u8 isDrawn; // Set to true if the actor is currently being drawn. Always stays false for lens actors /* 0x11E */ u8 dropFlag; // Configures what item is dropped by the actor from `Item_DropCollectibleRandom` - /* 0x11F */ u8 hintId; // Sets what 0600 dialog to display when talking to navi. Default 0xFF + /* 0x11F */ u8 hintId; // Sets what 0600 dialog to display when talking to Tatl. Default 0xFF /* 0x120 */ struct Actor* parent; // Usage is actor specific. Set if actor is spawned via `Actor_SpawnAsChild` /* 0x124 */ struct Actor* child; // Usage is actor specific. Set if actor is spawned via `Actor_SpawnAsChild` /* 0x128 */ struct Actor* prev; // Previous actor of this category /* 0x12C */ struct Actor* next; // Next actor of this category - /* 0x130 */ ActorFunc init; // Initialization Routine. Called by `Actor_Init` or `Actor_UpdateAll` + /* 0x130 */ ActorFunc init; // Initialization Routine. Called by `Actor_InitContext` or `Actor_UpdateAll` /* 0x134 */ ActorFunc destroy; // Destruction Routine. Called by `Actor_Destroy` /* 0x138 */ ActorFunc update; // Update Routine. Called by `Actor_UpdateAll` /* 0x13C */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw` @@ -227,12 +208,12 @@ typedef enum { typedef struct { /* 0x000 */ Actor actor; /* 0x144 */ s32 bgId; - /* 0x148 */ f32 unk148; + /* 0x148 */ f32 pushForce; /* 0x14C */ f32 unk14C; - /* 0x150 */ s16 unk150; + /* 0x150 */ s16 yRotation; /* 0x152 */ u16 unk152; - /* 0x154 */ u32 unk154; - /* 0x158 */ u8 unk_158; + /* 0x154 */ u32 flags; + /* 0x158 */ u8 stateFlags; /* 0x15A */ s16 pad15A; } DynaPolyActor; // size = 0x15C @@ -256,7 +237,7 @@ typedef enum { /* 0x10 */ ITEM00_MASK, /* 0x11 */ ITEM00_SMALL_KEY, /* 0x12 */ ITEM00_FLEXIBLE, - /* 0x13 */ ITEM00_RUPEE_ORANGE, + /* 0x13 */ ITEM00_RUPEE_HUGE, /* 0x14 */ ITEM00_RUPEE_PURPLE, /* 0x15 */ ITEM00_3_HEARTS, /* 0x16 */ ITEM00_SHIELD_HERO, @@ -275,6 +256,9 @@ struct EnItem00; typedef void (*EnItem00ActionFunc)(struct EnItem00*, struct GlobalContext*); +#define ENITEM00_GET_8000(thisx) ((thisx)->params & 0x8000) +#define ENITEM00_GET_7F00(thisx) (((thisx)->params & 0x7F00) >> 8) + typedef struct EnItem00 { /* 0x000 */ Actor actor; /* 0x144 */ EnItem00ActionFunc actionFunc; @@ -312,26 +296,111 @@ typedef enum { /* 0x08 */ ACTORCAT_MISC, /* 0x09 */ ACTORCAT_BOSS, /* 0x0A */ ACTORCAT_DOOR, - /* 0x0B */ ACTORCAT_CHEST + /* 0x0B */ ACTORCAT_CHEST, + /* 0x0C */ ACTORCAT_MAX } ActorType; typedef struct { - /* 0x00 */ AnimationHeader* animation; - /* 0x04 */ f32 playSpeed; - /* 0x08 */ f32 startFrame; - /* 0x0C */ f32 frameCount; - /* 0x10 */ u8 mode; - /* 0x14 */ f32 morphFrames; -} ActorAnimationEntry; // size = 0x18 + /* 0x00 */ Vec3f pos; + /* 0x0C */ f32 unkC; + /* 0x10 */ Color_RGBA8 color; +} TargetContextEntry; // size = 0x14 + +typedef struct TargetContext { + /* 0x00 */ Vec3f unk0; + /* 0x0C */ Vec3f targetCenterPos; + /* 0x18 */ Color_RGBAf fairyInner; + /* 0x28 */ Color_RGBAf fairyOuter; + /* 0x38 */ Actor* arrowPointedActor; + /* 0x3C */ Actor* targetedActor; + /* 0x40 */ f32 unk40; + /* 0x44 */ f32 unk44; + /* 0x48 */ s16 unk48; // alpha + /* 0x4A */ u8 unk4A; + /* 0x4B */ u8 unk4B; + /* 0x4C */ s8 unk4C; + /* 0x4D */ UNK_TYPE1 pad4D[0x3]; + /* 0x50 */ TargetContextEntry unk50[3]; + /* 0x8C */ Actor* unk8C; + /* 0x90 */ Actor* bgmEnemy; + /* 0x94 */ Actor* unk_94; +} TargetContext; // size = 0x98 typedef struct { - /* 0x00 */ AnimationHeader* animationSeg; - /* 0x04 */ f32 playbackSpeed; - /* 0x08 */ s16 frame; - /* 0x0A */ s16 frameCount; - /* 0x0C */ u8 mode; - /* 0x0E */ s16 transitionRate; -} ActorAnimationEntryS; // size = 0x10 + /* 0x0 */ TexturePtr texture; + /* 0x4 */ s16 x; + /* 0x6 */ s16 y; + /* 0x8 */ u8 width; + /* 0x9 */ u8 height; + /* 0xA */ u8 durationTimer; // how long the title card appears for before fading + /* 0xB */ u8 delayTimer; // how long the title card waits to appear + /* 0xC */ s16 alpha; + /* 0xE */ s16 intensity; +} TitleCardContext; // size = 0x10 + +typedef struct ActorContext_unk_20C { + /* 0x0 */ s16 id; + /* 0x2 */ s8 isDynamicallyInitialised; + /* 0x4 */ void* ptr; +} ActorContext_unk_20C; // size = 0x8 + +typedef struct ActorContextFlags { + /* 0x00 */ u32 switches[4]; // First 0x40 are permanent, second 0x40 are temporary + /* 0x10 */ u32 chest; + /* 0x14 */ u32 clearedRoom; + /* 0x18 */ u32 clearedRoomTemp; + /* 0x1C */ u32 collectible[4]; // bitfield of 128 bits +} ActorContextFlags; // size = 0x2C + +typedef struct ActorListEntry { + /* 0x0 */ s32 length; // number of actors loaded of this type + /* 0x4 */ Actor* first; // pointer to first actor of this type + /* 0x8 */ s32 unk_08; +} ActorListEntry; // size = 0xC + +typedef struct ActorContext { + /* 0x000 */ u8 freezeFlashTimer; + /* 0x001 */ UNK_TYPE1 pad1; + /* 0x002 */ u8 unk2; + /* 0x003 */ u8 unk3; + /* 0x004 */ s8 unk4; + /* 0x005 */ u8 unk5; + /* 0x006 */ UNK_TYPE1 pad6[0x5]; + /* 0x00B */ s8 unkB; + /* 0x00C */ s16 unkC; + /* 0x00E */ u8 totalLoadedActors; + /* 0x00F */ u8 undrawnActorCount; + /* 0x010 */ ActorListEntry actorLists[ACTORCAT_MAX]; + /* 0x0A0 */ Actor* undrawnActors[32]; // Records the first 32 actors drawn each frame + /* 0x120 */ TargetContext targetContext; + /* 0x1B8 */ ActorContextFlags flags; + /* 0x1E4 */ TitleCardContext titleCtxt; + /* 0x1F4 */ u8 unk1F4; + /* 0x1F5 */ u8 unk1F5; + /* 0x1F6 */ UNK_TYPE1 pad1F6[0x2]; + /* 0x1F8 */ f32 unk1F8; + /* 0x1FC */ Vec3f unk1FC; + /* 0x208 */ UNK_TYPE1 unk_208[0x4]; + /* 0x20C */ ActorContext_unk_20C unk_20C[8]; + /* 0x24C */ UNK_TYPE1 unk_24C[0x4]; + /* 0x250 */ void* absoluteSpace; // Space used to allocate actor overlays of alloc type ALLOCTYPE_ABSOLUTE + /* 0x254 */ u32 unk254[5]; + /* 0x268 */ u8 unk268; + /* 0x269 */ UNK_TYPE1 pad269[0x3]; + /* 0x26C */ Input unk_26C; +} ActorContext; // size = 0x284 + +typedef enum { + /* 00 */ ACTOR_DRAW_DMGEFF_FIRE, + /* 01 */ ACTOR_DRAW_DMGEFF_BLUE_FIRE, + /* 10 */ ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX = 10, + /* 11 */ ACTOR_DRAW_DMGEFF_FROZEN_SFX, + /* 20 */ ACTOR_DRAW_DMGEFF_LIGHT_ORBS = 20, + /* 21 */ ACTOR_DRAW_DMGEFF_BLUE_LIGHT_ORBS, + /* 30 */ ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL = 30, + /* 31 */ ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM, + /* 32 */ ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE +} ActorDrawDamageEffectType; typedef enum { /* 0x000 */ ACTOR_PLAYER, @@ -1027,6 +1096,78 @@ typedef enum { /* 0x2B2 */ ACTOR_ID_MAX // originally "ACTOR_DLF_MAX" } ActorID; +typedef enum { + /* 0 */ DOORLOCK_NORMAL, + /* 1 */ DOORLOCK_BOSS, + /* 2 */ DOORLOCK_2, // DOORLOCK_NORMAL_SPIRIT on OoT + /* 3 */ DOORLOCK_MAX +} DoorLockType; + +// Targetability / ACTOR_FLAG_TARGETABLE? +#define ACTOR_FLAG_1 (1 << 0) +// +#define ACTOR_FLAG_2 (1 << 1) +// +#define ACTOR_FLAG_4 (1 << 2) +// +#define ACTOR_FLAG_8 (1 << 3) +// +#define ACTOR_FLAG_10 (1 << 4) +// +#define ACTOR_FLAG_20 (1 << 5) +// +#define ACTOR_FLAG_40 (1 << 6) +// Invisible +#define ACTOR_FLAG_80 (1 << 7) +// Related to talk +#define ACTOR_FLAG_100 (1 << 8) +// +#define ACTOR_FLAG_200 (1 << 9) +// +#define ACTOR_FLAG_400 (1 << 10) +// +#define ACTOR_FLAG_800 (1 << 11) +// +#define ACTOR_FLAG_1000 (1 << 12) +// +#define ACTOR_FLAG_2000 (1 << 13) +// +#define ACTOR_FLAG_4000 (1 << 14) +// +#define ACTOR_FLAG_8000 (1 << 15) +// +#define ACTOR_FLAG_10000 (1 << 16) +// +#define ACTOR_FLAG_20000 (1 << 17) +// +#define ACTOR_FLAG_40000 (1 << 18) +// +#define ACTOR_FLAG_80000 (1 << 19) +// +#define ACTOR_FLAG_100000 (1 << 20) +// +#define ACTOR_FLAG_200000 (1 << 21) +// +#define ACTOR_FLAG_400000 (1 << 22) +// +#define ACTOR_FLAG_800000 (1 << 23) +// +#define ACTOR_FLAG_1000000 (1 << 24) +// +#define ACTOR_FLAG_2000000 (1 << 25) +// +#define ACTOR_FLAG_4000000 (1 << 26) +// +#define ACTOR_FLAG_8000000 (1 << 27) +// +#define ACTOR_FLAG_10000000 (1 << 28) +// +#define ACTOR_FLAG_20000000 (1 << 29) +// +#define ACTOR_FLAG_40000000 (1 << 30) +// +#define ACTOR_FLAG_80000000 (1 << 31) + typedef enum { /* 0x00 */ CLEAR_TAG_SMALL_EXPLOSION, /* 0x01 */ CLEAR_TAG_LARGE_EXPLOSION, @@ -1034,7 +1175,7 @@ typedef enum { /* 0x03 */ CLEAR_TAG_SMALL_LIGHT_RAYS, /* 0x04 */ CLEAR_TAG_LARGE_LIGHT_RAYS, /* 0x23 */ CLEAR_TAG_SPLASH = 35, - /* 0xC8 */ CLEAR_TAG_SMOKE = 200, + /* 0xC8 */ CLEAR_TAG_SMOKE = 200 } ClearTagType; #endif diff --git a/include/z64animation.h b/include/z64animation.h index 2eed33ffd..58ddb34df 100644 --- a/include/z64animation.h +++ b/include/z64animation.h @@ -1,5 +1,5 @@ -#ifndef _Z64_ANIMATION_H -#define _Z64_ANIMATION_H +#ifndef Z64_ANIMATION_H +#define Z64_ANIMATION_H #include "PR/ultratypes.h" #include "PR/gbi.h" @@ -28,7 +28,7 @@ typedef enum { } AnimationModes; typedef enum { - /* -1 */ ANIMTAPER_DECEL = -1, + /* -1 */ ANIMTAPER_DECEL = -1, /* 0 */ ANIMTAPER_NONE, /* 1 */ ANIMTAPER_ACCEL } AnimationTapers; @@ -187,7 +187,10 @@ typedef struct SkelAnime { /* 0x24 */ Vec3s* morphTable; // Table of values used to morph between animations /* 0x28 */ f32 morphWeight; // Weight of the current animation morph as a fraction in [0,1] /* 0x2C */ f32 morphRate; // Reciprocal of the number of frames in the morph - /* 0x30 */ s32 (*update)(); // Can be Loop, Partial loop, Play once, Morph, or Tapered morph. Link only has Loop, Play once, and Morph + /* 0x30 */ union { + s32 (*normal)(struct SkelAnime*);// Can be Loop, Partial loop, Play once, Morph, or Tapered morph + s32 (*link)(struct GlobalContext*, struct SkelAnime*); // Loop, Play once, and Morph + } update; /* 0x34 */ s8 initFlags; // Flags used when initializing Link's skeleton /* 0x35 */ u8 moveFlags; // Flags used for animations that move the actor in worldspace. /* 0x36 */ s16 prevRot; // Previous rotation in worldspace. @@ -196,24 +199,26 @@ typedef struct SkelAnime { } SkelAnime; // size = 0x44 typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor, Gfx** gfx); + struct Actor* thisx, Gfx** gfx); typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - struct Actor* actor, Gfx** gfx); + struct Actor* thisx, Gfx** gfx); typedef s32 (*OverrideLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); typedef void (*PostLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot, - struct Actor* actor); + struct Actor* thisx); -typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); +typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx); + +typedef void (*TransformLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx, Gfx** gfx); typedef void (*AnimationEntryCallback)(struct GlobalContext*, AnimationEntryData*); @@ -269,11 +274,98 @@ typedef s32 (*OverrideCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeC typedef void (*PostCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, struct Actor* actor); -typedef struct struct_80B8E1A8 { - /* 0x00 */ AnimationHeader* animationSeg; - /* 0x04 */ f32 playbackSpeed; +typedef struct { + /* 0x00 */ AnimationHeader* animation; + /* 0x04 */ f32 playSpeed; + /* 0x08 */ f32 startFrame; + /* 0x0C */ f32 frameCount; + /* 0x10 */ u8 mode; + /* 0x14 */ f32 morphFrames; +} AnimationInfo; // size = 0x18 + +typedef struct { + /* 0x00 */ AnimationHeader* animation; + /* 0x04 */ f32 playSpeed; + /* 0x08 */ s16 startFrame; + /* 0x0A */ s16 frameCount; + /* 0x0C */ u8 mode; + /* 0x0E */ s16 morphFrames; +} AnimationInfoS; // size = 0x10 + +typedef struct AnimationSpeedInfo { + /* 0x00 */ AnimationHeader* animation; + /* 0x04 */ f32 playSpeed; /* 0x08 */ u8 mode; - /* 0x0C */ f32 transitionRate; -} struct_80B8E1A8; // size = 0x10 + /* 0x0C */ f32 morphFrames; +} AnimationSpeedInfo; // size = 0x10 + +struct SkeletonInfo; + +typedef s32 (*UnkKeyframeCallback)(struct GlobalContext* globalCtx, struct SkeletonInfo* skeletonInfo, s32* arg2, Gfx** dList, + u8* arg4, void* arg5); + +// Keyframe limb? +typedef struct { + /* 0x00 */ Gfx* dList; + /* 0x04 */ u8 unk_4; + /* 0x05 */ u8 flags; + /* 0x06 */ Vec3s root; +} Struct_801BFA14_Arg1_Field4; // size = 0xC + +// Other limb type? +typedef struct { + /* 0x00 */ Gfx* dList; + /* 0x04 */ u8 unk_4; + /* 0x05 */ u8 flags; + /* 0x06 */ u8 unk_6; // transform limb draw index +} Struct_801BFA14_Arg1_Field4_2; // size = 0x8 + +typedef struct { + /* 0x00 */ u8 limbCount; + /* 0x01 */ u8 unk_1; // non-zero in object files, number of non-null-dlist limbs? + /* 0x04 */ union { + Struct_801BFA14_Arg1_Field4* unk_4; // arrays + Struct_801BFA14_Arg1_Field4_2* unk_4_2; + }; + /* 0x08 */ s16* unk_8; + /* 0x0C */ s16* unk_C; + /* 0x0C */ char unk_10[0x2]; + /* 0x12 */ s16 unk_12; +} Struct_801BFA14_Arg1; + +typedef struct { + /* 0x00 */ u16* unk_0; + /* 0x04 */ s16* unk_4; + /* 0x08 */ s16* unk_8; + /* 0x0C */ s16* unk_C; + /* 0x0C */ char unk_10[0x2]; + /* 0x12 */ s16 unk_12; +} SkeletonInfo_1C; + +typedef struct { + /* 0x00 */ f32 unk_0; + /* 0x04 */ f32 unk_4; + /* 0x08 */ f32 unk_8; + /* 0x0C */ f32 unk_C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ s32 unk_14; +} FrameControl; + +// FlexKeyframeSkeleton ? +typedef struct SkeletonInfo { + /* 0x00 */ FrameControl frameCtrl; + /* 0x18 */ Struct_801BFA14_Arg1* unk_18; // array + /* 0x1C */ SkeletonInfo_1C* unk_1C; + /* 0x20 */ UnkKeyframeCallback* unk_20; // pointer to array of functions + /* 0x24 */ f32 unk_24; // duration? current time? + /* 0x28 */ Vec3s* frameData; // array of 3 Vec3s + /* 0x2C */ s16* unk_2C; +} SkeletonInfo; + +typedef s32 (*OverrideKeyframeDrawScaled)(struct GlobalContext* globalCtx, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, + u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos); + +typedef void (*PostKeyframeDrawScaled)(struct GlobalContext* globalCtx, SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList, + u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos); #endif diff --git a/include/z64audio.h b/include/z64audio.h new file mode 100644 index 000000000..5dd78f73a --- /dev/null +++ b/include/z64audio.h @@ -0,0 +1,1143 @@ +#ifndef Z64_AUDIO_H +#define Z64_AUDIO_H + +#define MK_AUDIO_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0)) + +#define NO_LAYER ((SequenceLayer*)(-1)) + +#define TATUMS_PER_BEAT 48 + +#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((uintptr_t)(ptr) != (uintptr_t)&gAudioContext.sequenceChannelNone) + +#define MAX_CHANNELS_PER_BANK 3 + +#define AUDIO_LERPIMP(v0, v1, t) (v0 + ((v1 - v0) * t)) + +#define ADSR_DISABLE 0 +#define ADSR_HANG -1 +#define ADSR_GOTO -2 +#define ADSR_RESTART -3 + +#define AIBUF_LEN 0x580 + +typedef enum { + /* 0 */ AUDIO_FS_STEREO, + /* 1 */ AUDIO_FS_HEADSET, + /* 2 */ AUDIO_FS_SURROUND, + /* 3 */ AUDIO_FS_MONO +} AudioFileSelectOption; + +typedef enum { + /* 0 */ AUDIO_MODE_STEREO, + /* 1 */ AUDIO_MODE_HEADSET, + /* 2 */ AUDIO_MODE_UNK, + /* 3 */ AUDIO_MODE_MONO, + /* 4 */ AUDIO_MODE_SURROUND +} AudioSoundMode; + +typedef enum { + /* 0 */ ADSR_STATE_DISABLED, + /* 1 */ ADSR_STATE_INITIAL, + /* 2 */ ADSR_STATE_START_LOOP, + /* 3 */ ADSR_STATE_LOOP, + /* 4 */ ADSR_STATE_FADE, + /* 5 */ ADSR_STATE_HANG, + /* 6 */ ADSR_STATE_DECAY, + /* 7 */ ADSR_STATE_RELEASE, + /* 8 */ ADSR_STATE_SUSTAIN +} AdsrStatus; + +typedef enum { + /* 0 */ MEDIUM_RAM, + /* 1 */ MEDIUM_UNK, + /* 2 */ MEDIUM_CART, + /* 3 */ MEDIUM_DISK_DRIVE, + /* 5 */ MEDIUM_RAM_UNLOADED = 5 +} SampleMedium; + +typedef enum { + /* 0 */ CODEC_ADPCM, + /* 1 */ CODEC_S8, + /* 2 */ CODEC_S16_INMEMORY, + /* 3 */ CODEC_SMALL_ADPCM, + /* 4 */ CODEC_REVERB, + /* 5 */ CODEC_S16 +} SampleCodec; + +typedef enum { + /* 0 */ SEQUENCE_TABLE, + /* 1 */ FONT_TABLE, + /* 2 */ SAMPLE_TABLE +} SampleBankTableType; + +typedef enum { + /* 0 */ CACHE_LOAD_PERMANENT, + /* 1 */ CACHE_LOAD_PERSISTENT, + /* 2 */ CACHE_LOAD_TEMPORARY, + /* 3 */ CACHE_LOAD_EITHER, + /* 4 */ CACHE_LOAD_EITHER_NOSYNC +} AudioCacheLoadType; + +typedef enum { + /* 0 */ CACHE_TEMPORARY, + /* 1 */ CACHE_PERSISTENT, + /* 2 */ CACHE_EITHER, + /* 3 */ CACHE_PERMANENT +} AudioCacheType; + +typedef enum { + /* 0 */ LOAD_STATUS_0, + /* 1 */ LOAD_STATUS_1, + /* 2 */ LOAD_STATUS_2, // Samples/Seqplayer + /* 3 */ LOAD_STATUS_3, // Sequences + /* 4 */ LOAD_STATUS_4, // SoundFonts + /* 5 */ LOAD_STATUS_5 // Permanent +} AudioLoadStatus; + +typedef s32 (*DmaHandler)(OSPiHandle* handle, OSIoMesg* mb, s32 direction); + +struct Note; +struct NotePool; +struct SequenceChannel; +struct SequenceLayer; + +// A node in a circularly linked list. Each node is either a head or an item: +// - Items can be either detached (prev = NULL), or attached to a list. +// 'value' points to something of interest. +// - List heads are always attached; if a list is empty, its head points +// to itself. 'count' contains the size of the list. +// If the list holds notes, 'pool' points back to the pool where it lives. +// Otherwise, that member is NULL. +typedef struct AudioListItem { + /* 0x00 */ struct AudioListItem* prev; + /* 0x04 */ struct AudioListItem* next; + union { + /* 0x08 */ void* value; // either Note* or SequenceLayer* + /* 0x08 */ s32 count; + } u; + /* 0x0C */ struct NotePool* pool; +} AudioListItem; // size = 0x10 + +typedef struct NotePool { + /* 0x00 */ AudioListItem disabled; + /* 0x10 */ AudioListItem decaying; + /* 0x20 */ AudioListItem releasing; + /* 0x30 */ AudioListItem active; +} NotePool; // size = 0x40 + +// Pitch sliding by up to one octave in the positive direction. Negative +// direction is "supported" by setting extent to be negative. The code +// extrapolates exponentially in the wrong direction in that case, but that +// doesn't prevent seqplayer from doing it, AFAICT. +typedef struct { + /* 0x0 */ u8 mode; // bit 0x80 denotes something; the rest are an index 0-5 + /* 0x2 */ u16 cur; + /* 0x4 */ u16 speed; + /* 0x8 */ f32 extent; +} Portamento; // size = 0xC + +typedef struct { + /* 0x0 */ s16 delay; + /* 0x2 */ s16 arg; +} AdsrEnvelope; // size = 0x4 + +typedef struct { + /* 0x00 */ u32 start; + /* 0x04 */ u32 end; + /* 0x08 */ u32 count; + /* 0x0C */ u32 unk_0C; + /* 0x10 */ s16 state[16]; // only exists if count != 0. 8-byte aligned +} AdpcmLoop; // size = 0x30 (or 0x10) + +typedef struct { + /* 0x00 */ s32 order; + /* 0x04 */ s32 npredictors; + /* 0x08 */ s16 book[1]; // size 8 * order * npredictors. 8-byte aligned +} AdpcmBook; // size >= 0x8 + +typedef struct { + /* 0x00 */ u32 unk_0 : 1; + /* 0x00 */ u32 codec : 3; + /* 0x00 */ u32 medium : 2; + /* 0x00 */ u32 unk_bit26 : 1; + /* 0x00 */ u32 unk_bit25 : 1; + /* 0x01 */ u32 size : 24; + /* 0x04 */ u8* sampleAddr; + /* 0x08 */ AdpcmLoop* loop; + /* 0x0C */ AdpcmBook* book; +} SoundFontSample; // size = 0x10 + +typedef struct { + /* 0x00 */ SoundFontSample* sample; + /* 0x04 */ f32 tuning; // frequency scale factor +} SoundFontSound; // size = 0x8 + +typedef struct { + /* 0x00 */ s16 numSamplesAfterDownsampling; // never read + /* 0x02 */ s16 chunkLen; // never read + /* 0x04 */ s16* toDownsampleLeft; + /* 0x08 */ s16* toDownsampleRight; // data pointed to by left and right are adjacent in memory + /* 0x0C */ s32 startPos; // start pos in ring buffer + /* 0x10 */ s16 lengthA; // first length in ring buffer (from startPos, at most until end) + /* 0x12 */ s16 lengthB; // second length in ring buffer (from pos 0) + /* 0x14 */ u16 unk_14; + /* 0x16 */ u16 unk_16; + /* 0x18 */ u16 unk_18; +} ReverbRingBufferItem; // size = 0x1C + +typedef struct { + /* 0x000 */ u8 resampleFlags; + /* 0x001 */ u8 useReverb; + /* 0x002 */ u8 framesToIgnore; + /* 0x003 */ u8 curFrame; + /* 0x004 */ u8 downsampleRate; + /* 0x005 */ s8 unk_05; + /* 0x006 */ u16 windowSize; + /* 0x008 */ s16 unk_08; + /* 0x00A */ s16 unk_0A; + /* 0x00C */ u16 unk_0C; + /* 0x00E */ u16 unk_0E; + /* 0x010 */ s16 leakRtl; + /* 0x012 */ s16 leakLtr; + /* 0x014 */ u16 unk_14; + /* 0x016 */ s16 unk_16; + /* 0x018 */ u8 unk_18; + /* 0x019 */ s8 unk_19; + /* 0x01A */ u16 unk_1A; + /* 0x01C */ u16 unk_1C; + /* 0x01E */ u8 unk_1E; + /* 0x020 */ s32 nextRingBufPos; + /* 0x024 */ s32 unk_24; // May be bufSizePerChan + /* 0x028 */ s16* leftRingBuf; + /* 0x02C */ s16* rightRingBuf; + /* 0x030 */ void* unk_30; + /* 0x034 */ void* unk_34; + /* 0x038 */ void* unk_38; + /* 0x03C */ void* unk_3C; + /* 0x040 */ ReverbRingBufferItem items[2][5]; + /* 0x158 */ ReverbRingBufferItem items2[2][5]; + /* 0x270 */ s16* filterLeft; + /* 0x274 */ s16* filterRight; + /* 0x278 */ s16* unk_278; + /* 0x27C */ s16* unk_27C; + /* 0x280 */ s16* filterLeftState; + /* 0x284 */ s16* filterRightState; + /* 0x288 */ SoundFontSound sound; + /* 0x290 */ SoundFontSample sample; + /* 0x2A0 */ AdpcmLoop loop; +} SynthesisReverb; // size = 0x2D0 + +typedef struct { + /* 0x00 */ u8 loaded; + /* 0x01 */ u8 normalRangeLo; + /* 0x02 */ u8 normalRangeHi; + /* 0x03 */ u8 releaseRate; + /* 0x04 */ AdsrEnvelope* envelope; + /* 0x08 */ SoundFontSound lowNotesSound; + /* 0x10 */ SoundFontSound normalNotesSound; + /* 0x18 */ SoundFontSound highNotesSound; +} Instrument; // size = 0x20 + +typedef struct { + /* 0x00 */ u8 releaseRate; + /* 0x01 */ u8 pan; + /* 0x02 */ u8 loaded; + /* 0x04 */ SoundFontSound sound; + /* 0x14 */ AdsrEnvelope* envelope; +} Drum; // size = 0x18 + +typedef struct { + /* 0x00 */ u8 numInstruments; + /* 0x01 */ u8 numDrums; + /* 0x02 */ u8 sampleBankId1; + /* 0x03 */ u8 sampleBankId2; + /* 0x04 */ u16 numSfx; + /* 0x08 */ Instrument** instruments; + /* 0x0C */ Drum** drums; + /* 0x10 */ SoundFontSound* soundEffects; +} SoundFont; // size = 0x14 + +typedef struct { + /* 0x00 */ u8* pc; // program counter + /* 0x04 */ u8* stack[4]; + /* 0x14 */ u8 remLoopIters[4]; // remaining loop iterations + /* 0x18 */ u8 depth; + /* 0x19 */ s8 value; +} SeqScriptState; // size = 0x1C + +// Also known as a Group, according to debug strings. +typedef struct { + /* 0x000 */ u8 enabled : 1; + /* 0x000 */ u8 finished : 1; + /* 0x000 */ u8 muted : 1; + /* 0x000 */ u8 seqDmaInProgress : 1; + /* 0x000 */ u8 fontDmaInProgress : 1; + /* 0x000 */ u8 recalculateVolume : 1; + /* 0x000 */ u8 stopScript : 1; + /* 0x000 */ u8 applyBend : 1; + /* 0x001 */ u8 state; + /* 0x002 */ u8 noteAllocPolicy; + /* 0x003 */ u8 muteBehavior; + /* 0x004 */ u8 seqId; + /* 0x005 */ u8 defaultFont; + /* 0x006 */ u8 unk_06[1]; + /* 0x007 */ s8 playerIdx; + /* 0x008 */ u16 tempo; // tatums per minute + /* 0x00A */ u16 tempoAcc; + /* 0x00C */ s16 unk_0C; + /* 0x00E */ s16 transposition; + /* 0x010 */ u16 delay; + /* 0x012 */ u16 fadeTimer; + /* 0x014 */ u16 fadeTimerUnkEu; + /* 0x016 */ u16 unk_16; // New to MM + union { + /* 0x018 */ u8* seqData; + /* 0x018 */ u16* seqData16; + }; + /* 0x01C */ f32 fadeVolume; + /* 0x020 */ f32 fadeVelocity; + /* 0x024 */ f32 volume; + /* 0x028 */ f32 muteVolumeScale; + /* 0x02C */ f32 fadeVolumeScale; + /* 0x030 */ f32 appliedFadeVolume; + /* 0x034 */ f32 bend; + /* 0x038 */ struct SequenceChannel* channels[16]; + /* 0x078 */ SeqScriptState scriptState; + /* 0x094 */ u8* shortNoteVelocityTable; + /* 0x098 */ u8* shortNoteGateTimeTable; + /* 0x09C */ NotePool notePool; + /* 0x0DC */ s32 skipTicks; + /* 0x0E0 */ u32 scriptCounter; + /* 0x0E4 */ char unk_E4[0x74]; // unused struct members for sequence/sound font dma management, according to sm64 decomp + /* 0x158 */ s8 soundScriptIO[8]; +} SequencePlayer; // size = 0x160 + +typedef struct { + /* 0x0 */ u8 releaseRate; + /* 0x1 */ u8 sustain; + /* 0x4 */ AdsrEnvelope* envelope; +} AdsrSettings; // size = 0x8 + +typedef struct { + union { + struct { + /* 0x00 */ u8 unk_0b80 : 1; + /* 0x00 */ u8 hang : 1; + /* 0x00 */ u8 decay : 1; + /* 0x00 */ u8 release : 1; + /* 0x00 */ u8 state : 4; + } s; + /* 0x00 */ u8 asByte; + } action; + /* 0x01 */ u8 envIndex; + /* 0x02 */ s16 delay; + /* 0x04 */ f32 sustain; + /* 0x08 */ f32 velocity; + /* 0x0C */ f32 fadeOutVel; + /* 0x10 */ f32 current; + /* 0x14 */ f32 target; + /* 0x18 */ char unk_18[4]; + /* 0x1C */ AdsrEnvelope* envelope; +} AdsrState; // size = 0x20 + +typedef struct { + /* 0x0 */ u8 unused : 2; + /* 0x0 */ u8 bit2 : 2; + /* 0x0 */ u8 strongRight : 1; + /* 0x0 */ u8 strongLeft : 1; + /* 0x0 */ u8 stereoHeadsetEffects : 1; + /* 0x0 */ u8 usesHeadsetPanEffects : 1; +} StereoData; // size = 0x1 + +typedef union { + /* 0x0 */ StereoData s; + /* 0x0 */ u8 asByte; +} Stereo; // size = 0x1 + +typedef struct { + /* 0x00 */ u8 reverb; + /* 0x01 */ u8 unk_1; + /* 0x02 */ u8 pan; + /* 0x03 */ u8 unk_3; // Possibly part of stereo? + /* 0x04 */ Stereo stereo; + /* 0x05 */ u8 unk_4; + /* 0x06 */ u16 unk_6; + /* 0x08 */ f32 freqScale; + /* 0x0C */ f32 velocity; + /* 0x10 */ s16* filter; + /* 0x14 */ s16* filterBuf; +} NoteAttributes; // size = 0x18 + +typedef struct VibratoSubStruct { + /* 0x0 */ u16 vibratoRateStart; + /* 0x2 */ u16 vibratoExtentStart; + /* 0x4 */ u16 vibratoRateTarget; + /* 0x6 */ u16 vibratoExtentTarget; + /* 0x8 */ u16 vibratoRateChangeDelay; + /* 0xA */ u16 vibratoExtentChangeDelay; + /* 0xC */ u16 vibratoDelay; +} VibratoSubStruct; // size = 0xE + +// Also known as a SubTrack, according to sm64 debug strings. +typedef struct SequenceChannel { + /* 0x00 */ u8 enabled : 1; + /* 0x00 */ u8 finished : 1; + /* 0x00 */ u8 stopScript : 1; + /* 0x00 */ u8 stopSomething2 : 1; // sets SequenceLayer.stopSomething + /* 0x00 */ u8 hasInstrument : 1; + /* 0x00 */ u8 stereoHeadsetEffects : 1; + /* 0x00 */ u8 largeNotes : 1; // notes specify duration and velocity + /* 0x00 */ u8 unused : 1; + union { + struct { + /* 0x01 */ u8 freqScale : 1; + /* 0x01 */ u8 volume : 1; + /* 0x01 */ u8 pan : 1; + } s; + /* 0x01 */ u8 asByte; + } changes; + /* 0x02 */ u8 noteAllocPolicy; + /* 0x03 */ u8 muteBehavior; + /* 0x04 */ u8 reverb; // or dry/wet mix + /* 0x05 */ u8 notePriority; // 0-3 + /* 0x06 */ u8 someOtherPriority; + /* 0x07 */ u8 fontId; + /* 0x08 */ u8 reverbIndex; + /* 0x09 */ u8 bookOffset; + /* 0x0A */ u8 newPan; + /* 0x0B */ u8 panChannelWeight; // proportion of pan that comes from the channel (0..128) + /* 0x0C */ u8 unk_0C; + /* 0x0D */ u8 velocityRandomVariance; + /* 0x0E */ u8 gateTimeRandomVariance; + /* 0x0F */ u8 unk_0F; + /* 0x10 */ u8 unk_10; // New to MM + /* 0x11 */ u8 unk_11; // New to MM + /* 0x12 */ VibratoSubStruct vibrato; + /* 0x20 */ u16 delay; + /* 0x22 */ u16 unk_20; + /* 0x24 */ u16 unk_22; // Used for indexing data + /* 0x26 */ s16 instOrWave; // either 0 (none), instrument index + 1, or + // 0x80..0x83 for sawtooth/triangle/sine/square waves. + /* 0x28 */ s16 transposition; + /* 0x2C */ f32 volumeScale; + /* 0x30 */ f32 volume; + /* 0x34 */ s32 pan; + /* 0x38 */ f32 appliedVolume; + /* 0x3C */ f32 freqScale; + /* 0x40 */ u8 (*dynTable)[][2]; + /* 0x44 */ struct Note* noteUnused; + /* 0x48 */ struct SequenceLayer* layerUnused; + /* 0x4C */ Instrument* instrument; + /* 0x50 */ SequencePlayer* seqPlayer; + /* 0x54 */ struct SequenceLayer* layers[4]; + /* 0x64 */ SeqScriptState scriptState; + /* 0x80 */ AdsrSettings adsr; + /* 0x88 */ NotePool notePool; + /* 0xC8 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib, "io ports" + /* 0xD0 */ u8* unk_D0; // New to MM + /* 0xD4 */ s16* filter; + /* 0xD8 */ Stereo stereo; + /* 0xDC */ s32 unk_DC; // New to MM + /* 0xE0 */ s32 unk_E0; // New to MM +} SequenceChannel; // size = 0xE4 + +// Might also be known as a Track, according to sm64 debug strings (?). +typedef struct SequenceLayer { + /* 0x00 */ u8 enabled : 1; + /* 0x00 */ u8 finished : 1; + /* 0x00 */ u8 stopSomething : 1; + /* 0x00 */ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound + /* 0x00 */ u8 bit3 : 1; // "loaded"? + /* 0x00 */ u8 ignoreDrumPan : 1; + /* 0x00 */ u8 bit1 : 1; // "has initialized continuous notes"? + /* 0x00 */ u8 notePropertiesNeedInit : 1; + /* 0x01 */ Stereo stereo; + /* 0x02 */ u8 instOrWave; + /* 0x03 */ u8 gateTime; + /* 0x04 */ u8 semitone; + /* 0x05 */ u8 portamentoTargetNote; + /* 0x06 */ u8 pan; // 0..128 + /* 0x07 */ u8 notePan; + /* 0x08 */ u8 unk_08; + /* 0x09 */ u8 unk_09; + union { + struct { + /* 0x0A */ u16 bit_0 : 1; + /* 0x0A */ u16 bit_1 : 1; + /* 0x0A */ u16 bit_2 : 1; + /* 0x0A */ u16 bit_3 : 1; + /* 0x0A */ u16 bit_4 : 1; + /* 0x0A */ u16 bit_5 : 1; + /* 0x0A */ u16 bit_6 : 1; + /* 0x0A */ u16 bit_7 : 1; + /* 0x0A */ u16 bit_8 : 1; + /* 0x0A */ u16 bit_9 : 1; + /* 0x0A */ u16 bit_A : 1; + /* 0x0A */ u16 bit_B : 1; + /* 0x0A */ u16 bit_C : 1; + /* 0x0A */ u16 bit_D : 1; + /* 0x0A */ u16 bit_E : 1; + /* 0x0A */ u16 bit_F : 1; + } s; + /* 0x0A */ u16 asByte; + } unk_0A; + /* 0x0C */ VibratoSubStruct vibrato; + /* 0x1A */ s16 delay; + /* 0x1C */ s16 gateDelay; + /* 0x1E */ s16 delay2; + /* 0x20 */ u16 portamentoTime; + /* 0x22 */ s16 transposition; // #semitones added to play commands + // (seq instruction encoding only allows referring to the limited range + // 0..0x3F; this makes 0x40..0x7F accessible as well) + /* 0x24 */ s16 shortNoteDefaultDelay; + /* 0x26 */ s16 lastDelay; + /* 0x28 */ AdsrSettings adsr; + /* 0x30 */ Portamento portamento; + /* 0x3C */ struct Note* note; + /* 0x40 */ f32 freqScale; + /* 0x44 */ f32 bend; + /* 0x48 */ f32 velocitySquare2; + /* 0x4C */ f32 velocitySquare; // not sure which one of those corresponds to the sm64 original + /* 0x50 */ f32 noteVelocity; + /* 0x54 */ f32 noteFreqScale; + /* 0x58 */ Instrument* instrument; + /* 0x5C */ SoundFontSound* sound; + /* 0x60 */ SequenceChannel* channel; // Not SequenceChannel? + /* 0x64 */ SeqScriptState scriptState; + /* 0x80 */ AudioListItem listItem; +} SequenceLayer; // size = 0x90 + +typedef struct { + /* 0x00 */ s16 adpcmdecState[0x10]; + /* 0x20 */ s16 finalResampleState[0x10]; + /* 0x40 */ s16 mixEnvelopeState[0x28]; + /* 0x90 */ s16 panResampleState[0x10]; + /* 0xB0 */ s16 panSamplesBuffer[0x20]; + /* 0xF0 */ s16 dummyResampleState[0x10]; +} NoteSynthesisBuffers; // size = 0x110 + +typedef struct { + /* 0x00 */ u8 restart_bit0 : 1; + /* 0x00 */ u8 restart_bit1 : 1; + /* 0x00 */ u8 restart_bit2 : 1; + /* 0x00 */ u8 restart_bit3 : 1; + /* 0x00 */ u8 restart_bit4 : 1; + /* 0x00 */ u8 restart_bit5 : 1; + /* 0x00 */ u8 restart_bit6 : 1; + /* 0x00 */ u8 restart_bit7 : 1; + /* 0x01 */ u8 sampleDmaIndex; + /* 0x02 */ u8 prevHeadsetPanRight; + /* 0x03 */ u8 prevHeadsetPanLeft; + /* 0x04 */ u8 reverbVol; + /* 0x05 */ u8 numParts; + /* 0x06 */ u16 samplePosFrac; + /* 0x08 */ u16 unk_08; // New to MM + /* 0x0C */ s32 samplePosInt; + /* 0x10 */ NoteSynthesisBuffers* synthesisBuffers; + /* 0x14 */ s16 curVolLeft; + /* 0x16 */ s16 curVolRight; + /* 0x18 */ u16 unk_14; + /* 0x1A */ u16 unk_16; + /* 0x1C */ u16 unk_18; + /* 0x1E */ u8 unk_1A; + /* 0x1F */ u8 unk_1F; + /* 0x20 */ u16 unk_1C; + /* 0x22 */ u16 unk_1E; +} NoteSynthesisState; // size = 0x24 + +typedef struct { + /* 0x00 */ struct VibratoSubStruct* vibSubStruct; // MM Something else? + /* 0x04 */ u32 time; + /* 0x08 */ s16* curve; + /* 0x0C */ f32 extent; + /* 0x10 */ f32 rate; + /* 0x14 */ u8 active; + /* 0x16 */ u16 rateChangeTimer; + /* 0x18 */ u16 extentChangeTimer; + /* 0x1A */ u16 delay; +} VibratoState; // size = 0x1C + +typedef struct { + /* 0x00 */ u8 priority; + /* 0x01 */ u8 waveId; + /* 0x02 */ u8 sampleCountIndex; + /* 0x03 */ u8 fontId; + /* 0x04 */ u8 unk_04; + /* 0x05 */ u8 stereoHeadsetEffects; + /* 0x06 */ s16 adsrVolScaleUnused; + /* 0x08 */ f32 portamentoFreqScale; + /* 0x0C */ f32 vibratoFreqScale; + /* 0x18 */ SequenceLayer* wantedParentLayer; + /* 0x14 */ SequenceLayer* parentLayer; + /* 0x10 */ SequenceLayer* prevParentLayer; + /* 0x1C */ NoteAttributes attributes; + /* 0x34 */ AdsrState adsr; + /* 0x54 */ Portamento portamento; + /* 0x60 */ VibratoState vibratoState; + /* 0x7C */ char unk_7C[0x8]; + /* 0x84 */ u32 unk_84; +} NotePlaybackState; // size = 0x88 + +typedef struct { + struct { + /* 0x00 */ volatile u8 enabled : 1; + /* 0x00 */ u8 needsInit : 1; + /* 0x00 */ u8 finished : 1; // ? + /* 0x00 */ u8 unused : 1; + /* 0x00 */ u8 stereoStrongRight : 1; + /* 0x00 */ u8 stereoStrongLeft : 1; + /* 0x00 */ u8 stereoHeadsetEffects : 1; + /* 0x00 */ u8 usesHeadsetPanEffects : 1; // ? + } bitField0; + struct { + /* 0x01 */ u8 reverbIndex : 3; + /* 0x01 */ u8 bookOffset : 2; + /* 0x01 */ u8 isSyntheticWave : 1; + /* 0x01 */ u8 hasTwoParts : 1; + /* 0x01 */ u8 usesHeadsetPanEffects2 : 1; + } bitField1; + /* 0x02 */ u8 unk_2; + /* 0x03 */ u8 headsetPanRight; + /* 0x04 */ u8 headsetPanLeft; + /* 0x05 */ u8 reverbVol; + /* 0x06 */ u8 unk_06; + /* 0x07 */ u8 unk_07; + /* 0x08 */ u16 targetVolLeft; + /* 0x0A */ u16 targetVolRight; + /* 0x0C */ u16 resamplingRateFixedPoint; + /* 0x0E */ u16 unk_0E; + union { + /* 0x10 */ SoundFontSound* soundFontSound; + /* 0x10 */ s16* samples; // used for synthetic waves + } sound; + /* 0x14 */ s16* filter; + /* 0x18 */ u8 unk_18; // New to MM + /* 0x19 */ u8 unk_19; // New to MM + /* 0x1A */ UNK_TYPE1 pad_1A[0x6]; +} NoteSubEu; // size = 0x20 + +typedef struct Note { + /* 0x00 */ AudioListItem listItem; + /* 0x10 */ NoteSynthesisState synthesisState; + /* 0x34 */ NotePlaybackState playbackState; + /* 0xBC */ char unk_BC[0x1C]; + /* 0xD8 */ NoteSubEu noteSubEu; +} Note; // size = 0xF8 + +typedef struct { + /* 0x00 */ u8 downsampleRate; + /* 0x02 */ u16 windowSize; + /* 0x04 */ u16 unk_4; + /* 0x06 */ u16 unk_6; + /* 0x08 */ u16 unk_8; + /* 0x0A */ u16 unk_A; + /* 0x0C */ u16 leakRtl; + /* 0x0E */ u16 leakLtr; + /* 0x10 */ s8 unk_10; + /* 0x12 */ u16 unk_12; + /* 0x14 */ s16 lowPassFilterCutoffLeft; + /* 0x16 */ s16 lowPassFilterCutoffRight; +} ReverbSettings; // size = 0x18 + +/** + * The high-level audio specifications requested when initializing or resetting the audio heap. + * Most often resets during scene transitions, but will highly depend on game play. + */ +typedef struct { + /* 0x00 */ u32 samplingFreq; // Target sampling rate in Hz + /* 0x04 */ u8 unk_04; + /* 0x05 */ u8 numNotes; + /* 0x06 */ u8 numSequencePlayers; + /* 0x07 */ u8 unk_07[0x2]; // unused, set to zero + /* 0x09 */ u8 numReverbs; + /* 0x0C */ ReverbSettings* reverbSettings; + /* 0x10 */ u16 sampleDmaBufSize1; + /* 0x12 */ u16 sampleDmaBufSize2; + /* 0x14 */ u16 unk_14; + /* 0x18 */ size_t persistentSeqCacheSize; // size of cache on audio pool to store sequences persistently + /* 0x1C */ size_t persistentFontCacheSize; // size of cache on audio pool to store soundFonts persistently + /* 0x20 */ size_t persistentSampleBankCacheSize; // size of cache on audio pool to store entire sample banks persistently + /* 0x24 */ size_t temporarySeqCacheSize; // size of cache on audio pool to store sequences temporarily + /* 0x28 */ size_t temporaryFontCacheSize; // size of cache on audio pool to store soundFonts temporarily + /* 0x2C */ size_t temporarySampleBankCacheSize; // size of cache on audio pool to store entire sample banks temporarily + /* 0x30 */ size_t persistentSampleCacheSize; // size of cache on audio pool to store individual samples persistently + /* 0x34 */ size_t temporarySampleCacheSize; // size of cache on audio pool to store individual samples temporarily +} AudioSpec; // size = 0x38 + +/** + * The audio buffer stores the fully processed digital audio before it is sent to the audio interface (AI), then to the + * digital-analog converter (DAC), then to play on the speakers. The audio buffer is written to by the rsp after + * processing audio commands, and the audio buffer is read by AI which sends the data to the DAC. + * This struct parameterizes that buffer. + */ +typedef struct { + /* 0x00 */ s16 specUnk4; + /* 0x02 */ u16 samplingFreq; // Target sampling rate in Hz + /* 0x04 */ u16 aiSamplingFreq; // True sampling rate set to the audio interface (AI) for the audio digital-analog converter (DAC) + /* 0x06 */ s16 samplesPerFrameTarget; + /* 0x08 */ s16 maxAiBufferLength; + /* 0x0A */ s16 minAiBufferLength; + /* 0x0C */ s16 updatesPerFrame; + /* 0x0E */ s16 samplesPerUpdate; + /* 0x10 */ s16 samplesPerUpdateMax; + /* 0x12 */ s16 samplesPerUpdateMin; + /* 0x14 */ s16 numSequencePlayers; + /* 0x18 */ f32 resampleRate; + /* 0x1C */ f32 updatesPerFrameInv; + /* 0x20 */ f32 unkUpdatesPerFrameScaled; + /* 0x24 */ f32 unk_24; +} AudioBufferParameters; // size = 0x28 + +/** + * Meta-data associated with a pool (contain withing the Audio Heap) + */ +typedef struct { + /* 0x0 */ u8* startAddr; // start addr of the pool + /* 0x4 */ u8* curAddr; // address of the next available memory for allocation + /* 0x8 */ size_t size; // size of the pool + /* 0xC */ s32 count; // number of entries allocated to the pool +} AudioAllocPool; // size = 0x10 + +/** + * Audio cache entry data to store a single entry containing either a sequence, soundfont, or entire sample banks + */ +typedef struct { + /* 0x0 */ u8* addr; + /* 0x4 */ size_t size; + /* 0x8 */ s16 tableType; + /* 0xA */ s16 id; +} AudioCacheEntry; // size = 0xC + +/** + * Audio cache entry data to store a single entry containing an individual sample + */ +typedef struct { + /* 0x00 */ s8 inUse; + /* 0x01 */ s8 origMedium; + /* 0x02 */ u8 sampleBankId; + /* 0x03 */ char unk_03[0x5]; + /* 0x08 */ u8* allocatedAddr; + /* 0x0C */ void* sampleAddr; + /* 0x10 */ size_t size; +} SampleCacheEntry; // size = 0x14 + +/** + * Audio cache entry data to store individual samples + */ +typedef struct { + /* 0x000 */ AudioAllocPool pool; + /* 0x010 */ SampleCacheEntry entries[128]; + /* 0xA10 */ s32 numEntries; +} AudioSampleCache; // size = 0xA14 + +typedef struct { + /* 0x00 */ u32 numEntries; + /* 0x04 */ AudioAllocPool pool; + /* 0x14 */ AudioCacheEntry entries[16]; +} AudioPersistentCache; // size = 0xD4 + +typedef struct { + /* 0x00 */ u32 nextSide; + /* 0x04 */ AudioAllocPool pool; + /* 0x14 */ AudioCacheEntry entries[2]; +} AudioTemporaryCache; // size = 0x3C + +typedef struct { + /* 0x000 */ AudioPersistentCache persistent; + /* 0x0D4 */ AudioTemporaryCache temporary; + /* 0x100 */ u8 unk_100[0x10]; +} AudioCache; // size = 0x110 + +typedef struct { + /* 0x0 */ size_t persistentCommonPoolSize; + /* 0x4 */ size_t temporaryCommonPoolSize; +} AudioCachePoolSplit; // size = 0x8 + +typedef struct { + /* 0x0 */ size_t seqCacheSize; + /* 0x4 */ size_t fontCacheSize; + /* 0x8 */ size_t sampleBankCacheSize; +} AudioCommonPoolSplit; // size = 0xC + +typedef struct { + /* 0x0 */ size_t miscPoolSize; + /* 0x4 */ u32 unkSizes[2]; + /* 0xC */ size_t cachePoolSize; +} AudioSessionPoolSplit; // size = 0x10 + +typedef struct { + /* 0x00 */ u32 endAndMediumKey; + /* 0x04 */ SoundFontSample* sample; + /* 0x08 */ u8* ramAddr; + /* 0x0C */ u32 encodedInfo; + /* 0x10 */ s32 isFree; +} AudioPreloadReq; // size = 0x14 + +typedef struct { + union { + /* 0x0 */ u32 opArgs; + struct { + /* 0x0 */ u8 op; + /* 0x1 */ u8 arg0; + /* 0x2 */ u8 arg1; + /* 0x3 */ u8 arg2; + }; + }; + union { + /* 0x4 */ void* data; + /* 0x4 */ f32 asFloat; + /* 0x4 */ s32 asInt; + /* 0x4 */ u16 asUShort; + /* 0x4 */ s8 asSbyte; + /* 0x4 */ u8 asUbyte; + /* 0x4 */ u32 asUInt; + }; +} AudioCmd; // size = 0x8 + +typedef struct { + /* 0x00 */ s8 status; + /* 0x01 */ s8 delay; + /* 0x02 */ s8 medium; + /* 0x04 */ u8* ramAddr; + /* 0x08 */ uintptr_t curDevAddr; + /* 0x0C */ u8* curRamAddr; + /* 0x10 */ size_t bytesRemaining; + /* 0x14 */ size_t chunkSize; + /* 0x18 */ s32 unkMediumParam; + /* 0x1C */ u32 retMsg; + /* 0x20 */ OSMesgQueue* retQueue; + /* 0x24 */ OSMesgQueue msgQueue; + /* 0x3C */ OSMesg msg; + /* 0x40 */ OSIoMesg ioMesg; +} AudioAsyncLoad; // size = 0x58 + +typedef struct { + /* 0x00 */ u8 medium; + /* 0x01 */ u8 seqOrFontId; + /* 0x02 */ u16 instId; + /* 0x04 */ s32 unkMediumParam; + /* 0x08 */ uintptr_t curDevAddr; + /* 0x0C */ u8* curRamAddr; + /* 0x10 */ u8* ramAddr; + /* 0x14 */ s32 status; + /* 0x18 */ size_t bytesRemaining; + /* 0x1C */ s8* isDone; // TODO: rename in OoT and sync up here. This is an external status while (s32 status) is an internal status + /* 0x20 */ SoundFontSample sample; + /* 0x30 */ OSMesgQueue msgqueue; + /* 0x48 */ OSMesg msg; + /* 0x4C */ OSIoMesg ioMesg; +} AudioSlowLoad; // size = 0x64 + +typedef struct { + /* 0x00 */ uintptr_t romAddr; + /* 0x04 */ size_t size; + /* 0x08 */ s8 medium; + /* 0x09 */ s8 cachePolicy; + /* 0x0A */ s16 shortData1; + /* 0x0C */ s16 shortData2; + /* 0x0E */ s16 shortData3; +} AudioTableEntry; // size = 0x10 + +typedef struct { + /* 0x00 */ s16 numEntries; + /* 0x02 */ s16 unkMediumParam; + /* 0x04 */ uintptr_t romAddr; + /* 0x08 */ char pad[0x8]; + /* 0x10 */ AudioTableEntry entries[1]; // (dynamic size) +} AudioTable; // size >= 0x20 + +typedef struct { + /* 0x00 */ OSTask task; + /* 0x40 */ OSMesgQueue* taskQueue; + /* 0x44 */ void* unk_44; // probably a message that gets unused. + /* 0x48 */ char unk_48[0x8]; +} AudioTask; // size = 0x50 + +typedef struct { + /* 0x00 */ u8* ramAddr; + /* 0x04 */ uintptr_t devAddr; + /* 0x08 */ u16 sizeUnused; + /* 0x0A */ u16 size; + /* 0x0C */ u8 unused; + /* 0x0D */ u8 reuseIndex; // position in sSampleDmaReuseQueue1/2, if ttl == 0 + /* 0x0E */ u8 ttl; // Time To Live: duration after which the DMA can be discarded +} SampleDma; // size = 0x10 + +typedef struct { + /* 0x0000 */ char unk_0000; + /* 0x0001 */ s8 numSynthesisReverbs; + /* 0x0002 */ u16 unk_2; // reads from audio spec unk_14, never used, always set to 0x7FFF + /* 0x0004 */ u16 unk_4; + /* 0x0006 */ char unk_0006[0xA]; + /* 0x0010 */ s16* curLoadedBook; + /* 0x0014 */ NoteSubEu* noteSubsEu; + /* 0x0018 */ SynthesisReverb synthesisReverbs[4]; + /* 0x0B58 */ char unk_0B58[0x30]; + /* 0x0B88 */ SoundFontSample* usedSamples[128]; + /* 0x0D88 */ AudioPreloadReq preloadSampleStack[128]; + /* 0x1788 */ s32 numUsedSamples; + /* 0x178C */ s32 preloadSampleStackTop; + /* 0x1790 */ AudioAsyncLoad asyncLoads[0x10]; + /* 0x1D10 */ OSMesgQueue asyncLoadUnkMediumQueue; + /* 0x1D28 */ char unk_1D08[0x40]; + /* 0x1D68 */ AudioAsyncLoad* curUnkMediumLoad; + /* 0x1D6C */ u32 slowLoadPos; + /* 0x1D70 */ AudioSlowLoad slowLoads[2]; + /* 0x1E38 */ OSPiHandle* cartHandle; + /* 0x1E2C */ OSPiHandle* driveHandle; + /* 0x1E40 */ OSMesgQueue externalLoadQueue; + /* 0x1E58 */ OSMesg externalLoadMesgBuf[0x10]; + /* 0x1E98 */ OSMesgQueue preloadSampleQueue; + /* 0x1EB0 */ OSMesg preloadSampleMesgBuf[0x10]; + /* 0x1EF0 */ OSMesgQueue currAudioFrameDmaQueue; + /* 0x1F08 */ OSMesg currAudioFrameDmaMesgBuf[0x40]; + /* 0x2008 */ OSIoMesg currAudioFrameDmaIoMesgBuf[0x40]; + /* 0x2608 */ OSMesgQueue syncDmaQueue; + /* 0x2620 */ OSMesg syncDmaMesg; + /* 0x2624 */ OSIoMesg syncDmaIoMesg; + /* 0x263C */ SampleDma* sampleDmas; + /* 0x2640 */ u32 sampleDmaCount; + /* 0x2644 */ u32 sampleDmaListSize1; + /* 0x2648 */ s32 unused2648; + /* 0x264C */ u8 sampleDmaReuseQueue1[0x100]; // read pos <= write pos, wrapping mod 256 + /* 0x274C */ u8 sampleDmaReuseQueue2[0x100]; + /* 0x284C */ u8 sampleDmaReuseQueue1RdPos; // Read position for dma 1 + /* 0x284D */ u8 sampleDmaReuseQueue2RdPos; // Read position for dma 2 + /* 0x284E */ u8 sampleDmaReuseQueue1WrPos; // Write position for dma 1 + /* 0x284F */ u8 sampleDmaReuseQueue2WrPos; // Write position for dma 2 + /* 0x2850 */ AudioTable* sequenceTable; + /* 0x2854 */ AudioTable* soundFontTable; + /* 0x2858 */ AudioTable* sampleBankTable; + /* 0x285C */ char unk_285C[0x4]; + /* 0x2860 */ u8* sequenceFontTable; + /* 0x2864 */ u16 numSequences; + /* 0x2868 */ SoundFont* soundFonts; + /* 0x286C */ AudioBufferParameters audioBufferParameters; + /* 0x2994 */ f32 unk_2870; + /* 0x2898 */ s32 sampleDmaBufSize1; + /* 0x289C */ s32 sampleDmaBufSize2; + /* 0x28A0 */ char unk_287C[0x10]; + /* 0x28B0 */ s32 sampleDmaBufSize; + /* 0x28B4 */ s32 maxAudioCmds; + /* 0x28B8 */ s32 numNotes; + /* 0x2898 */ s16 tempoInternalToExternal; + /* 0x28BE */ s8 soundMode; + /* 0x28C0 */ s32 totalTaskCount; // The total number of times the top-level function on the audio thread is run since the last audio reset + /* 0x28C4 */ s32 curAudioFrameDmaCount; + /* 0x28C8 */ s32 rspTaskIndex; + /* 0x28CC */ s32 curAiBuffferIndex; + /* 0x28AC */ Acmd* abiCmdBufs[2]; // Pointer to audio heap where the audio binary interface command lists are stored. Two lists that alternative every frame + /* 0x28B4 */ Acmd* curAbiCmdBuf; + /* 0x28DC */ AudioTask* curTask; + /* 0x28C0 */ AudioTask rspTask[2]; + /* 0x2980 */ f32 unk_2960; + /* 0x2984*/ s32 refreshRate; + /* 0x2988 */ s16* aiBuffers[3]; // Pointers to the audio buffer allocated on the initPool contained in the audio heap. Stores fully processed digital audio before transferring to the audio interface (AI) + /* 0x2994 */ s16 aiBufLengths[3]; // Number of bytes to transfer to the audio interface buffer + /* 0x299C */ u32 audioRandom; + /* 0x29A0 */ s32 audioErrorFlags; + /* 0x29A4 */ volatile u32 resetTimer; + /* 0x29A8 */ u32 (*unk_29A8[4])(s8 value, SequenceChannel* channel); + /* 0x29B8 */ s8 unk_29B8; + /* 0x29BC */ s32 unk_29BC; // sMaxAbiCmdCnt + /* 0x29C0 */ AudioAllocPool audioSessionPool; // A sub-pool to main pool, contains all sub-pools and data that changes every audio reset + /* 0x29D0 */ AudioAllocPool externalPool; // pool allocated on an external device. Never used in game + /* 0x29E0 */ AudioAllocPool audioInitPool; // A sub-pool to the main pool, contains all sub-pools and data that persists every audio reset + /* 0x29F0 */ AudioAllocPool miscPool; // A sub-pool to the session pool, + /* 0x2A00 */ char unk_29D0[0x20]; // probably two unused pools + /* 0x2A20 */ AudioAllocPool cachePool; // The common pool for all cache entries + /* 0x2A30 */ AudioAllocPool persistentCommonPool; // A sub-pool to the cache pool, contains all caches for data stored persistently + /* 0x2A40 */ AudioAllocPool temporaryCommonPool; // A sub-pool to the cache pool, contains all caches for data stored temporarily + /* 0x2A50 */ AudioCache seqCache; // Cache to store sequences + /* 0x2B60 */ AudioCache fontCache; // Cache to store soundFonts + /* 0x2C70 */ AudioCache sampleBankCache; // Cache for loading entire sample banks + /* 0x2D80 */ AudioAllocPool permanentPool; // Pool to stores audio data that is always loaded in. Primarily used for sfxs + /* 0x2D90 */ AudioCacheEntry permanentEntries[32]; // indificual entries to the permanent pool + /* 0x3690 */ AudioSampleCache persistentSampleCache; // Stores individual samples persistently + /* 0x40A4 */ AudioSampleCache temporarySampleCache; // Stores individual samples temporarily + /* 0x4338 */ AudioSessionPoolSplit sessionPoolSplit; // splits session pool into the cache pool and misc pool + /* 0x4348 */ AudioCachePoolSplit cachePoolSplit; // splits cache pool into the persistent & temporary common pools + /* 0x4350 */ AudioCommonPoolSplit persistentCommonPoolSplit; // splits persistent common pool into caches for sequences, soundFonts, sample banks + /* 0x435C */ AudioCommonPoolSplit temporaryCommonPoolSplit; // splits temporary common pool into caches for sequences, soundFonts, sample banks + /* 0x4368 */ u8 sampleFontLoadStatus[0x30]; + /* 0x4398 */ u8 fontLoadStatus[0x30]; + /* 0x43C8 */ u8 seqLoadStatus[0x80]; + /* 0x4448 */ volatile u8 resetStatus; + /* 0x4449 */ u8 audioResetSpecIdToLoad; + /* 0x444C */ s32 audioResetFadeOutFramesLeft; + /* 0x4450 */ f32* unk_3520; // fadeOutVelocities for ADSR + /* 0x4454 */ u8* audioHeap; + /* 0x4458 */ size_t audioHeapSize; + /* 0x445C */ Note* notes; + /* 0x4460 */ SequencePlayer seqPlayers[5]; + /* 0x4B40 */ SequenceLayer sequenceLayers[80]; + /* 0x7840 */ SequenceChannel sequenceChannelNone; + /* 0x7924 */ s32 noteSubEuOffset; + /* 0x7928 */ AudioListItem layerFreeList; + /* 0x7938 */ NotePool noteFreeLists; + /* 0x7978 */ u8 cmdWritePos; + /* 0x7979 */ u8 cmdReadPos; + /* 0x797A */ u8 cmdQueueFinished; + /* 0x797C */ u16 activeChannelsFlags[5]; // bitwise flag for 16 channels. Only channels with bit turned on will be processed + /* 0x7988 */ OSMesgQueue* audioResetQueueP; + /* 0x798C */ OSMesgQueue* taskStartQueueP; + /* 0x7990 */ OSMesgQueue* cmdProcQueueP; + /* 0x7994 */ OSMesgQueue taskStartQueue; + /* 0x79AC */ OSMesgQueue cmdProcQueue; + /* 0x79C4 */ OSMesgQueue audioResetQueue; + /* 0x79DC */ OSMesg taskStartMsgs[1]; + /* 0x79E0 */ OSMesg audioResetMesgs[1]; + /* 0x79E4 */ OSMesg cmdProcMsgs[4]; + /* 0x79F4 */ AudioCmd cmdBuf[0x100]; // Audio commands used to transfer audio requests from the graph thread to the audio thread + /* 0x81F4 */ char unk_81F4[4]; +} AudioContext; // size = 0x81F8 + +typedef struct { + /* 0x00 */ u8 reverbVol; + /* 0x01 */ u8 unk_1; + /* 0x02 */ u8 pan; + /* 0x03 */ u8 unk_3; + /* 0x04 */ Stereo stereo; + /* 0x08 */ f32 frequency; + /* 0x0C */ f32 velocity; + /* 0x10 */ char unk_0C[0x4]; + /* 0x14 */ s16* filter; + /* 0x18 */ u8 unk_14; + /* 0x1A */ u16 unk_16; +} NoteSubAttributes; // size = 0x1A + +typedef struct { + /* 0x0 */ size_t heapSize; // total number of bytes allocated to the audio heap. Must be <= the size of `gAudioHeap` (ideally about the same size) + /* 0x4 */ size_t mainPoolSplitSize; // The entire audio heap is split into two pools. + /* 0x8 */ size_t permanentPoolSize; +} AudioContextInitSizes; // size = 0xC + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_10; + /* 0x10 */ f32 unk_14; + /* 0x14 */ f32 unk_18; + /* 0x18 */ u16 unk_0C; + /* 0x1A */ u16 unk_1C; +} unk_50_s; // size = 0x1C + +typedef struct { + /* 0x000 */ unk_50_s unk_50[0x10]; + /* 0x1C0 */ f32 volCur; + /* 0x1C4 */ f32 volTarget; + /* 0x1C8 */ f32 unk_08; + /* 0x1CC */ u32 unk_14; + /* 0x1D0 */ f32 unk_1C; + /* 0x1D4 */ f32 unk_20; + /* 0x1D8 */ f32 unk_24; + /* 0x1DC */ u32 unk_2C[8]; + /* 0x1FC */ u32 unk_25C; + /* 0x200 */ u16 unk_0C; + /* 0x202 */ u16 unk_18; + /* 0x204 */ u16 unk_28; + /* 0x206 */ u16 unk_250; + /* 0x208 */ u16 unk_252; + /* 0x20A */ u16 unk_254; + /* 0x20C */ u16 unk_256; + /* 0x20E */ u16 unk_258; + /* 0x210 */ u8 unk_260; + /* 0x211 */ u8 unk_261[0x1]; + /* 0x212 */ u8 volScales[0x4]; + /* 0x216 */ u8 volFadeTimer; + /* 0x217 */ u8 fadeVolUpdate; + /* 0x218 */ u8 unk_4C; + /* 0x219 */ u8 unk_4D; + /* 0x21A */ u8 unk_4E; + /* 0x21B */ u8 unk_21B; // New to MM +} unk_D_8016E750; // size = 0x21C + +typedef struct { + /* 0x0 */ u8 unk_0; + /* 0x1 */ u8 unk_1; // importance? +} Struct_8016E320; // size = 0x02 + +typedef enum { + /* 0 */ BANK_PLAYER, + /* 1 */ BANK_ITEM, + /* 2 */ BANK_ENV, + /* 3 */ BANK_ENEMY, + /* 4 */ BANK_SYSTEM, + /* 5 */ BANK_OCARINA, + /* 6 */ BANK_VOICE +} SoundBankTypes; + +typedef enum { + /* 0 */ SFX_STATE_EMPTY, + /* 1 */ SFX_STATE_QUEUED, + /* 2 */ SFX_STATE_READY, + /* 3 */ SFX_STATE_PLAYING_REFRESH, + /* 4 */ SFX_STATE_PLAYING_1, + /* 5 */ SFX_STATE_PLAYING_2 +} SfxState; + +typedef struct { + /* 0x00 */ f32* posX; + /* 0x04 */ f32* posY; + /* 0x08 */ f32* posZ; + /* 0x0C */ f32* freqScale; + /* 0x10 */ f32* vol; + /* 0x14 */ s8* reverbAdd; + /* 0x18 */ f32 dist; + /* 0x1C */ u32 priority; // lower is more prioritized + /* 0x20 */ u16 sfxParams; + /* 0x22 */ u16 sfxId; + /* 0x25 */ u8 sfxFlags; + /* 0x24 */ u8 sfxImportance; + /* 0x26 */ u8 state; // uses SfxState enum + /* 0x27 */ u8 freshness; + /* 0x28 */ u8 prev; + /* 0x29 */ u8 next; + /* 0x2A */ u8 channelIdx; + /* 0x2B */ u8 unk_2F; + /* 0x2C */ u8 token; +} SfxBankEntry; // size = 0x30 + +/* + * SFX IDs + * + * index 0000000111111111 observed in audio code + * & 200 0000001000000000 single bit + * & 400 0000010000000000 single bit + * & 800 0000100000000000 single bit, what we currently call SFX_FLAG + * & 600 0000011000000000 2 bits + * & A00 0000101000000000 2 bits + * & C00 0000110000000000 2 bits, observed in audio code + * & E00 0000111000000000 all 3 bits + * bank 1111000000000000 observed in audio code + */ + +#define SFX_BANK_SHIFT(sfxId) (((sfxId) >> 12) & 0xFF) + +#define SFX_BANK_MASK(sfxId) ((sfxId) & 0xF000) + +#define SFX_INDEX(sfxId) ((sfxId) & 0x03FF) +#define SFX_BANK(sfxId) SFX_BANK_SHIFT(SFX_BANK_MASK(sfxId)) + +typedef struct { + /* 0x0 */ u32 priority; // lower is more prioritized + /* 0x4 */ u8 entryIndex; +} ActiveSfx; // size = 0x08 + +typedef struct { + /* 0x0 */ u8 importance; + /* 0x1 */ u8 flags; + /* 0x2 */ u16 params; +} SfxParams; // size = 0x4 + +typedef struct { + /* 0x00 */ u16 sfxId; + /* 0x02 */ u8 token; + /* 0x04 */ s8* reverbAdd; + /* 0x08 */ Vec3f* pos; + /* 0x0C */ f32* freqScale; + /* 0x10 */ f32* vol; +} SoundRequest; // size = 0x14 + +#endif diff --git a/include/z64bgcheck.h b/include/z64bgcheck.h index 7dc380bf2..0a5afb3d9 100644 --- a/include/z64bgcheck.h +++ b/include/z64bgcheck.h @@ -1,10 +1,12 @@ -#ifndef _Z_BGCHECK_ -#define _Z_BGCHECK_ +#ifndef Z64_BGCHECK_H +#define Z64_BGCHECK_H struct GlobalContext; struct Actor; struct DynaPolyActor; +#define SS_NULL 0xFFFF + #define COLPOLY_NORMAL_FRAC (1.0f / SHT_MAX) #define COLPOLY_SNORMAL(x) ((s16)((x) * SHT_MAX)) #define COLPOLY_GET_NORMAL(n) ((n)*COLPOLY_NORMAL_FRAC) @@ -15,24 +17,59 @@ struct DynaPolyActor; #define BGACTOR_NEG_ONE -1 #define BG_ACTOR_MAX 50 +#define DYNA_WATERBOX_MAX 30 #define BGCHECK_SCENE BG_ACTOR_MAX +#define BGCHECK_Y_MAX 32000.0f #define BGCHECK_Y_MIN -32000.0f #define BGCHECK_XYZ_ABSMAX 32760.0f #define BGCHECK_SUBDIV_OVERLAP 50 #define BGCHECK_SUBDIV_MIN 150.0f -#define FUNC_80041EA4_RESPAWN 5 -#define FUNC_80041EA4_MOUNT_WALL 6 -#define FUNC_80041EA4_STOP 8 -#define FUNC_80041EA4_VOID_OUT 12 +#define WATERBOX_ROOM(p) ((((s32)p) >> 13) & 0x3F) -#define WATERBOX_ROOM(p) ((p >> 13) & 0x3F) +// bccFlags (bgcheck check flags) +#define BGCHECK_CHECK_WALL (1 << 0) +#define BGCHECK_CHECK_FLOOR (1 << 1) +#define BGCHECK_CHECK_CEILING (1 << 2) +#define BGCHECK_CHECK_ONE_FACE (1 << 3) +#define BGCHECK_CHECK_DYNA (1 << 4) +#define BGCHECK_CHECK_ALL \ + (BGCHECK_CHECK_WALL | BGCHECK_CHECK_FLOOR | BGCHECK_CHECK_CEILING | BGCHECK_CHECK_ONE_FACE | BGCHECK_CHECK_DYNA) + +// bciFlags (bgcheck ignore flags) +#define BGCHECK_IGNORE_NONE 0 +#define BGCHECK_IGNORE_CEILING (1 << 0) +#define BGCHECK_IGNORE_WALL (1 << 1) +#define BGCHECK_IGNORE_FLOOR (1 << 2) + +// xpFlags (poly exclusion flags) +#define COLPOLY_IGNORE_NONE 0 +#define COLPOLY_IGNORE_CAMERA (1 << 0) +#define COLPOLY_IGNORE_ENTITY (1 << 1) +#define COLPOLY_IGNORE_PROJECTILES (1 << 2) + +// Surface Types +#define COLPOLY_SURFACE_GROUND 0 +#define COLPOLY_SURFACE_SAND 1 +#define COLPOLY_SURFACE_SNOW 14 + +// CollisionContext flags +#define BGCHECK_FLAG_REVERSE_CONVEYOR_FLOW 1 + +typedef enum { + /* 0 */ CONVEYOR_WATER, + /* 1 */ CONVEYOR_FLOOR +} ConveyorType; typedef struct { - Vec3f scale; - Vec3s rot; - Vec3f pos; -} ScaleRotPos; + /* 0x0 */ Vec3s pos; +} BgVertex; // size = 0x6 + +typedef struct { + /* 0x00 */ Vec3f scale; + /* 0x0C */ Vec3s rot; + /* 0x14 */ Vec3f pos; +} ScaleRotPos; // size = 0x20 typedef struct CollisionPoly { /* 0x00 */ u16 type; @@ -52,31 +89,45 @@ typedef struct CollisionPoly { } CollisionPoly; // size = 0x10 typedef struct { - /* 0x00 */ u16 cameraSType; - /* 0x02 */ s16 numCameras; - /* 0x04 */ Vec3s* camPosData; -} CamData; + /* 0x0 */ u16 setting; + /* 0x2 */ s16 numData; + /* 0x4 */ Vec3s* data; +} CamData; // size = 0x8 (BgCamData) typedef struct { - /* 0x00 */ s16 xMin; - /* 0x02 */ s16 ySurface; - /* 0x04 */ s16 zMin; - /* 0x06 */ s16 xLength; - /* 0x08 */ s16 zLength; - /* 0x0C */ u32 properties; - + /* 0x0 */ Vec3s minPos; + /* 0x6 */ s16 xLength; + /* 0x8 */ s16 zLength; + /* 0xC */ u32 properties; // 0x0008_0000 = ? - // 0x0007_E000 = Room Index, 0x3F = all rooms - // 0x0000_1F00 = Lighting Settings Index + // 0x0007_E000 = room index, 0x3F = all rooms + // 0x0000_1F00 = lighting setting index // 0x0000_00FF = CamData index } WaterBox; // size = 0x10 typedef struct { - u32 data[2]; + /* 0x0 */ u32 data[2]; - // Type 1 + // Word 0 + // 0x8000_0000 = horse blocked + // 0x4000_0000 = floor surface recessed by 1 unit + // 0x3C00_0000 = ? (floor property?) + // 0x03E0_0000 = ? (wall property?) + // 0x001C_0000 = ? + // 0x0003_E000 = ? + // 0x0000_1F00 = scene exit index + // 0x0000_00FF = CamData index + // Word 1 // 0x0800_0000 = wall damage -} SurfaceType; + // 0x07E0_0000 = conveyor direction + // 0x001C_0000 = conveyor speed + // 0x0002_0000 = is hookable surface + // 0x0001_F800 = echo/reverb + // 0x0000_07C0 = lighting setting index + // 0x0000_0030 = surface slope + // 0x0000_000F = type + +} SurfaceType; // size = 0x8 typedef struct { /* 0x00 */ Vec3s minBounds; // minimum coordinates of poly bounding box @@ -89,49 +140,54 @@ typedef struct { /* 0x20 */ CamData* cameraDataList; /* 0x24 */ u16 numWaterBoxes; /* 0x28 */ WaterBox* waterBoxes; -} CollisionHeader; // original name: BGDataInfo +} CollisionHeader; // size = 0x2C typedef struct { - s16 polyId; - u16 next; // next SSNode index -} SSNode; + /* 0x0 */ s16 polyId; + /* 0x2 */ u16 next; // index of the next SSNode in the list, or SS_NULL if last element +} SSNode; // size = 0x4 typedef struct { - u16 head; // first SSNode index -} SSList; + u16 head; // index of the first SSNode in the list, or SS_NULL if the list is empty +} SSList; // represents a linked list of type SSNode typedef struct { - /* 0x00 */ u16 max; // original name: short_slist_node_size - /* 0x02 */ u16 count; // original name: short_slist_node_last_index - /* 0x04 */ SSNode* tbl; // original name: short_slist_node_tbl - /* 0x08 */ u8* polyCheckTbl; // points to an array of bytes, one per static poly. Zero initialized when starting a - // bg check, and set to 1 if that poly has already been tested. -} SSNodeList; + /* 0x0 */ u16 max; + /* 0x2 */ u16 count; + /* 0x4 */ SSNode* tbl; + /* 0x8 */ u8* polyCheckTbl; +} SSNodeList; // size = 0xC typedef struct { - SSNode* tbl; - s32 count; - s32 max; -} DynaSSNodeList; + /* 0x0 */ SSNode* tbl; + /* 0x4 */ u32 count; + /* 0x8 */ s32 maxNodes; +} DynaSSNodeList; // size = 0xC typedef struct { - SSList floor; - SSList wall; - SSList ceiling; -} StaticLookup; + /* 0x0 */ s32 unk0; + /* 0x4 */ WaterBox* boxes; +} DynaWaterBoxList; // size = 0x8 typedef struct { - u16 polyStartIndex; - SSList ceiling; - SSList wall; - SSList floor; -} DynaLookup; + /* 0x0 */ SSList floor; + /* 0x2 */ SSList wall; + /* 0x4 */ SSList ceiling; +} StaticLookup; // size = 0x6 typedef struct { - /* 0x00 */ struct Actor* actor; + /* 0x0 */ s16 polyStartIndex; + /* 0x2 */ SSList ceiling; + /* 0x4 */ SSList wall; + /* 0x6 */ SSList floor; +} DynaLookup; // size = 0x8 + +typedef struct { + /* 0x00 */ Actor* actor; /* 0x04 */ CollisionHeader* colHeader; /* 0x08 */ DynaLookup dynaLookup; /* 0x10 */ u16 vtxStartIndex; + /* 0x12 */ u16 waterboxesStartIndex; /* 0x14 */ ScaleRotPos prevTransform; /* 0x34 */ ScaleRotPos curTransform; /* 0x54 */ Sphere16 boundingSphere; @@ -139,25 +195,20 @@ typedef struct { /* 0x60 */ f32 maxY; } BgActor; // size = 0x64 -typedef struct { - /* 0x0 */ UNK_TYPE1 pad0[0x4]; - /* 0x4 */ WaterBox* boxes; -} DynaSSWaterboxList; // size = 0x8 - typedef struct { /* 0x0000 */ u8 bitFlag; /* 0x0004 */ BgActor bgActors[BG_ACTOR_MAX]; - /* 0x138C */ u16 bgActorFlags[BG_ACTOR_MAX]; // & 0x0008 = no dyna ceiling + /* 0x138C */ u16 bgActorFlags[BG_ACTOR_MAX]; // bit 0 - Is mesh active /* 0x13F0 */ CollisionPoly* polyList; /* 0x13F4 */ Vec3s* vtxList; - /* 0x13F8 */ DynaSSWaterboxList waterboxes; + /* 0x13F8 */ DynaWaterBoxList waterBoxList; /* 0x1400 */ DynaSSNodeList polyNodes; /* 0x140C */ s32 polyNodesMax; /* 0x1410 */ s32 polyListMax; /* 0x1414 */ s32 vtxListMax; } DynaCollisionContext; // size = 0x1418 -typedef struct CollisionContext { +typedef struct { /* 0x00 */ CollisionHeader* colHeader; // scene's static collision /* 0x04 */ Vec3f minBounds; // minimum coordinates of collision bounding box /* 0x10 */ Vec3f maxBounds; // maximum coordinates of collision bounding box @@ -166,28 +217,46 @@ typedef struct CollisionContext { /* 0x34 */ Vec3f subdivLengthInv; // inverse of subdivision length /* 0x40 */ StaticLookup* lookupTbl; // 3d array of length subdivAmount /* 0x44 */ SSNodeList polyNodes; - /* 0x50 */ DynaCollisionContext dyna; - /* 0x1460 */ u32 memSize; // Size of all allocated memory plus CollisionContext - /* 0x146C */ u32 unk146C; + /* 0x0050 */ DynaCollisionContext dyna; + /* 0x1468 */ u32 memSize; // Size of all allocated memory plus CollisionContext + /* 0x146C */ u32 flags; // bit 0 reverses conveyor direction (i.e. water flow in Great Bay Temple) } CollisionContext; // size = 0x1470 typedef struct { /* 0x00 */ struct GlobalContext* globalCtx; - /* 0x04 */ struct CollisionContext* colCtx; + /* 0x04 */ CollisionContext* colCtx; /* 0x08 */ u16 xpFlags; /* 0x0C */ CollisionPoly** resultPoly; /* 0x10 */ f32 yIntersect; /* 0x14 */ Vec3f* pos; /* 0x18 */ s32* bgId; - /* 0x1C */ struct Actor* actor; - /* 0x20 */ u32 unk_20; - /* 0x24 */ f32 chkDist; - /* 0x28 */ DynaCollisionContext* dyna; - /* 0x2C */ SSList* ssList; -} DynaRaycast; + /* 0x1C */ s32 unk1C; + /* 0x20 */ struct Actor* actor; + /* 0x24 */ u32 unk_24; + /* 0x28 */ f32 checkDist; + /* 0x2C */ DynaCollisionContext* dyna; + /* 0x30 */ SSList* ssList; +} DynaRaycast; // size = 0x34 + +typedef struct +{ + /* 0x00 */ StaticLookup* lookup; + /* 0x04 */ SSList* ssList; + /* 0x08 */ CollisionContext* colCtx; + /* 0x0C */ u16 xpFlags1; + /* 0x0E */ u16 xpFlags2; + /* 0x10 */ Vec3f* posA; + /* 0x14 */ Vec3f* posB; + /* 0x18 */ Vec3f* outPos; + /* 0x1C */ CollisionPoly** outPoly; + /* 0x20 */ f32 outDistSq; + /* 0x24 */ f32 checkDist; + /* 0x28 */ s32 bccFlags; + /* 0x2C */ Actor* actor; +} StaticLineTest; // size = 0x30 typedef struct { - /* 0x00 */ struct CollisionContext* colCtx; + /* 0x00 */ CollisionContext* colCtx; /* 0x04 */ u16 xpFlags; /* 0x08 */ DynaCollisionContext* dyna; /* 0x0C */ SSList* ssList; @@ -195,9 +264,46 @@ typedef struct { /* 0x14 */ Vec3f* posB; /* 0x18 */ Vec3f* posResult; /* 0x1C */ CollisionPoly** resultPoly; - /* 0x20 */ s32 chkOneFace; // bccFlags & 0x8 - /* 0x24 */ f32* distSq; // distance from posA to poly squared - /* 0x28 */ f32 chkDist; // distance from poly -} DynaLineTest; + /* 0x20 */ s32 checkOneFace; // bccFlags & 0x8 + /* 0x24 */ f32* distSq; // distance from posA to poly squared + /* 0x28 */ f32 checkDist; // distance from poly + /* 0x2C */ Actor* actor; + /* 0x30 */ s32 bgId; +} DynaLineTest; // size = 0x34 +typedef struct { + /* 0x00 */ CollisionPoly* poly; + /* 0x04 */ Vec3s* vtxList; + /* 0x08 */ Vec3f* posA; + /* 0x0C */ Vec3f* posB; + /* 0x10 */ Vec3f* planeIntersect; + /* 0x14 */ s32 checkOneFace; + /* 0x18 */ f32 checkDist; +} BgLineVsPolyTest; // size = 0x1C + +typedef struct { + /* 0x0 */ s16 sceneId; + /* 0x4 */ u32 memSize; +} BgSpecialSceneMaxMemory; // size = 0x8 + +typedef struct { + /* 0x0 */ s16 sceneId; + /* 0x2 */ s16 maxNodes; + /* 0x4 */ s16 maxPolygons; + /* 0x6 */ s16 maxVertices; +} BgSpecialSceneMaxObjects; // size = 0x8 + +typedef struct { + /* 0x0 */ s16 sceneId; + /* 0x2 */ s16 xSubdivisions; + /* 0x4 */ s16 ySubdivisions; + /* 0x6 */ s16 zSubdivisions; + /* 0x8 */ s32 unk8; +} BgSpecialSceneMeshSubdivision; // size = 0xC + +typedef struct { + s16 sceneId; + Vec3s subdivAmount; + s32 nodeListMax; // if -1, dynamically compute max nodes +} BgCheckSceneSubdivisionEntry; #endif diff --git a/include/z64cutscene.h b/include/z64cutscene.h index 51e60799e..84150a527 100644 --- a/include/z64cutscene.h +++ b/include/z64cutscene.h @@ -1,5 +1,5 @@ -#ifndef _Z64CUTSCENE_H_ -#define _Z64CUTSCENE_H_ +#ifndef Z64CUTSCENE_H +#define Z64CUTSCENE_H #include "ultra64.h" #include "unk.h" @@ -26,21 +26,24 @@ typedef struct { } CutsceneCameraMove; // size = 0xC typedef struct { - /* 0x00 */ u16 unk0; // action; // "dousa" + /* 0x00 */ u16 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]; + union { + /* 0x06 */ Vec3s rot; + /* 0x06 */ Vec3us urot; + }; + /* 0x0C */ Vec3i startPos; + /* 0x18 */ Vec3i endPos; + /* 0x24 */ Vec3f normal; } CsCmdActorAction; // size = 0x30 typedef struct { /* 0x0 */ u16 base; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; -} CsCmdBase; // size = 0x6 + /* 0x6 */ u16 unk_06; +} CsCmdBase; // size = 0x8 typedef struct { /* 0x0 */ u16 unk0; @@ -48,25 +51,30 @@ typedef struct { /* 0x4 */ u16 endFrame; /* 0x6 */ u8 hour; /* 0x7 */ u8 minute; -} CsCmdDayTime; // size = 0x8 + /* 0x8 */ UNK_TYPE1 unk_08[0x04]; +} CsCmdDayTime; // size = 0xC typedef struct { /* 0x0 */ u16 setting; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; -} CsCmdEnvLighting; // size = 0x6 + /* 0x6 */ u16 unk_06; +} CsCmdEnvLighting; // size = 0x8 typedef struct { /* 0x0 */ u16 sequence; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; -} CsCmdMusicChange; // size = 0x6 + /* 0x6 */ u16 unk_06; +} CsCmdSequenceChange; // size = 0x8 typedef struct { /* 0x0 */ u16 type; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; -} CsCmdMusicFade; // size = 0x6 + /* 0x6 */ u16 unk_06; + /* 0x8 */ u32 unk_08; +} CsCmdSequenceFade; // size = 0xC typedef struct { /* 0x0 */ u16 base; @@ -77,30 +85,77 @@ typedef struct { /* 0xA */ u16 textId2; } CsCmdTextbox; // size = 0xC +typedef enum { + /* 0 */ CS_TEXTBOX_TYPE_DEFAULT, + /* 1 */ CS_TEXTBOX_TYPE_1, + /* 2 */ CS_TEXTBOX_TYPE_LEARN_SONG, + /* 3 */ CS_TEXTBOX_TYPE_3, + /* 4 */ CS_TEXTBOX_TYPE_BOSSES_REMAINS, + /* 5 */ CS_TEXTBOX_TYPE_ALL_NORMAL_MASKS, + /* 0xFFFF */ CS_TEXTBOX_TYPE_NONE = 0xFFFF +} CutsceneTextboxType; + typedef struct { - /* 0x0 */ u16 unk0; + /* 0x0 */ u16 type; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; /* 0x6 */ u8 unk6; /* 0x7 */ u8 unk7; /* 0x8 */ u8 unk8; /* 0x9 */ UNK_TYPE1 pad9[0x3]; -} CsCmdUnk190; // size = 0xC - -typedef struct { - /* 0x0 */ UNK_TYPE4 unk0; - /* 0x4 */ UNK_TYPE4 unk4; -} CsCmdUnk5A; // size = 0x8 +} CsCmdRumble; // size = 0xC typedef struct { /* 0x0 */ u16 unk0; /* 0x2 */ u16 startFrame; /* 0x4 */ u16 endFrame; - /* 0x6 */ u8 unk6; - /* 0x7 */ u8 unk7; - /* 0x8 */ u8 unk8; + /* 0x6 */ Color_RGB8 color; /* 0x9 */ UNK_TYPE1 pad9[0x3]; -} CsCmdUnk9B; // size = 0xC +} CsCmdFadeScreen; // size = 0xC + +typedef enum { + /* 0 */ CS_STATE_0, + /* 1 */ CS_STATE_1, + /* 2 */ CS_STATE_2, + /* 3 */ CS_STATE_3, + /* 4 */ CS_STATE_4 +} CutsceneState; + +typedef enum { + /* 0x00A */ CS_CMD_TEXTBOX = 0xA, + /* 0x05A */ CS_CMD_CAMERA = 0x5A, + /* 0x096 */ CS_CMD_MISC = 0x96, + /* 0x097 */ CS_CMD_SET_LIGHTING, + /* 0x098 */ CS_CMD_SCENE_TRANS_FX, + /* 0x099 */ CS_CMD_MOTIONBLUR, + /* 0x09A */ CS_CMD_GIVETATL, + /* 0x09B */ CS_CMD_FADESCREEN, + /* 0x09C */ CS_CMD_FADESEQ, + /* 0x09D */ CS_CMD_SETTIME, + /* 0x0C8 */ CS_CMD_SET_PLAYER_ACTION = 0xC8, + /* 0x0FA */ CS_CMD_UNK_FA = 0xFA, + /* 0x0FE */ CS_CMD_UNK_FE = 0xFE, + /* 0x0FF */ CS_CMD_UNK_FF, + /* 0x100 */ CS_CMD_UNK_100, + /* 0x101 */ CS_CMD_UNK_101, + /* 0x102 */ CS_CMD_UNK_102, + /* 0x103 */ CS_CMD_UNK_103, + /* 0x104 */ CS_CMD_UNK_104, + /* 0x105 */ CS_CMD_UNK_105, + /* 0x108 */ CS_CMD_UNK_108 = 0x108, + /* 0x109 */ CS_CMD_UNK_109, + /* 0x12C */ CS_CMD_PLAYSEQ = 0x12C, + /* 0x12D */ CS_CMD_UNK_12D, + /* 0x130 */ CS_CMD_130 = 0x130, + /* 0x131 */ CS_CMD_131, + /* 0x132 */ CS_CMD_132, + /* 0x133 */ CS_CMD_STOPSEQ, + /* 0x134 */ CS_CMD_PLAYAMBIENCE, + /* 0x135 */ CS_CMD_FADEAMBIENCE, + /* 0x15E */ CS_CMD_TERMINATOR = 0x15E, + /* 0x15F */ CS_CMD_CHOOSE_CREDITS_SCENES, + /* 0x190 */ CS_CMD_RUMBLE = 0x190 +} CutsceneCmd; typedef union CutsceneData { s32 i; @@ -109,4 +164,29 @@ typedef union CutsceneData { s8 b[4]; } CutsceneData; +typedef struct { + /* 0x0 */ CutsceneData* segmentedData; + /* 0x4 */ s16 nextEntranceIndex; + /* 0x6 */ u8 unk6; + /* 0x7 */ u8 unk7; // a weekEventReg bitpack? +} CutsceneEntry; // size = 0x8 + +typedef struct { + /* 0x00 */ u8 sceneCsCount; + /* 0x04 */ CutsceneData* csData; + /* 0x08 */ u8 state; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ u16 frames; + /* 0x12 */ u16 currentCsIndex; + /* 0x14 */ s32 csCamId; + /* 0x18 */ u16 unk_18; + /* 0x1A */ u8 unk_1A; + /* 0x1B */ u8 unk_1B; + /* 0x1C */ CutsceneCameraPoint* atPoints; + /* 0x20 */ CutsceneCameraPoint* eyePoints; + /* 0x24 */ CsCmdActorAction* playerAction; + /* 0x28 */ CsCmdActorAction* actorActions[10]; // "npcdemopnt" + /* 0x50 */ CutsceneEntry* sceneCsList; +} CutsceneContext; // size = 0x54 + #endif diff --git a/include/z64cutscene_commands.h b/include/z64cutscene_commands.h index 99000eec2..b487b49b1 100644 --- a/include/z64cutscene_commands.h +++ b/include/z64cutscene_commands.h @@ -1,5 +1,5 @@ -#ifndef _Z64CUTSCENE_COMMANDS_H_ -#define _Z64CUTSCENE_COMMANDS_H_ +#ifndef Z64CUTSCENE_COMMANDS_H +#define Z64CUTSCENE_COMMANDS_H #include "command_macros_base.h" #include "z64cutscene.h" @@ -11,11 +11,571 @@ * eeeeeeee nnnnnnnn * size = 0x8 */ -#define CS_BEGIN_CUTSCENE(totalEntries, endFrame) CMD_W(totalEntries), CMD_W(endFrame) +#define CS_BEGIN_CUTSCENE(totalEntries, endFrame) { CMD_W(totalEntries) }, { CMD_W(endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000000A eeeeeeee + * size = 0x8 + */ +#define CS_TEXT_LIST(entries) { CS_CMD_TEXTBOX }, { CMD_W(entries) } + +/** + * ARGS + * s16 messageId (i), s16 startFrame (s), s16 endFrame (e), s16 type (o), + * s16 topOptionBranch (y), s16 bottomOptionBranch (n) + * FORMAT + * iiiissss eeeeoooo yyyynnnn + * size = 0xC + */ +#define CS_TEXT_DISPLAY_TEXTBOX(messageId, startFrame, endFrame, type, topOptionBranch, bottomOptionBranch) \ + { CMD_HH(messageId, startFrame) }, { CMD_HH(endFrame, type) }, { CMD_HH(topOptionBranch, bottomOptionBranch) } + +/** + * ARGS + * s16 messageId (i), s16 startFrame (s), s16 endFrame (e), + * s16 topOptionBranch (y), s16 bottomOptionBranch (n) + * FORMAT + * iiiissss eeee0000 yyyynnnn + * size = 0xC + */ +#define CS_TEXT_DEFAULT(messageId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \ + CS_TEXT_DISPLAY_TEXTBOX(messageId, startFrame, endFrame, CS_TEXTBOX_TYPE_DEFAULT, topOptionBranch, bottomOptionBranch) + +/** + * ARGS + * s16 messageId (i), s16 startFrame (s), s16 endFrame (e), + * s16 topOptionBranch (y), s16 bottomOptionBranch (n) + * FORMAT + * iiiissss eeee0001 yyyynnnn + * size = 0xC + */ +#define CS_TEXT_TYPE_1(messageId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \ + CS_TEXT_DISPLAY_TEXTBOX(messageId, startFrame, endFrame, CS_TEXTBOX_TYPE_1, topOptionBranch, bottomOptionBranch) + +/** + * ARGS + * s16 ocarinaSongAction (o), s16 startFrame (s), s16 endFrame (e), s16 messageId (i) + * FORMAT + * oooossss eeee0002 iiiiFFFF + * size = 0xC + */ +#define CS_TEXT_LEARN_SONG(ocarinaSongAction, startFrame, endFrame, messageId) \ + CS_TEXT_DISPLAY_TEXTBOX(ocarinaSongAction, startFrame, endFrame, CS_TEXTBOX_TYPE_LEARN_SONG, messageId, 0xFFFF) + +/** + * ARGS + * s16 messageId (i), s16 startFrame (s), s16 endFrame (e), + * s16 topOptionBranch (y), s16 bottomOptionBranch (n) + * FORMAT + * iiiissss eeee0003 yyyynnnn + * size = 0xC + */ +#define CS_TEXT_TYPE_3(messageId, startFrame, endFrame, topOptionBranch, bottomOptionBranch) \ + CS_TEXT_DISPLAY_TEXTBOX(messageId, startFrame, endFrame, CS_TEXTBOX_TYPE_3, topOptionBranch, bottomOptionBranch) + +/** + * If Player has all 4 bosses' remains then alternativeMessageId is used, otherwise defaultMessageId is used + * ARGS + * s16 defaultMessageId (d), s16 startFrame (s), s16 endFrame (e), s16 alternativeMessageId (a) + * FORMAT + * ddddssss eeee0004 aaaaFFFF + * size = 0xC + */ +#define CS_TEXT_BOSSES_REMAINS(defaultMessageId, startFrame, endFrame, alternativeMessageId) \ + CS_TEXT_DISPLAY_TEXTBOX(defaultMessageId, startFrame, endFrame, CS_TEXTBOX_TYPE_BOSSES_REMAINS, alternativeMessageId, 0xFFFF) + +/** + * If Player has every non-transformation mask then alternativeMessageId is used, otherwise defaultMessageId is used + * ARGS + * s16 defaultMessageId (d), s16 startFrame (s), s16 endFrame (e), s16 alternativeMessageId (a) + * FORMAT + * ddddssss eeee0005 aaaaFFFF + * size = 0xC + */ +#define CS_TEXT_ALL_NORMAL_MASKS(defaultMessageId, startFrame, endFrame, alternativeMessageId) \ + CS_TEXT_DISPLAY_TEXTBOX(defaultMessageId, startFrame, endFrame, CS_TEXTBOX_TYPE_ALL_NORMAL_MASKS, alternativeMessageId, 0xFFFF) + +/** + * ARGS + * s16 startFrame (s), s16 endFrame (e) + * FORMAT + * FFFFssss eeeeFFFF FFFFFFFF + * size = 0xC + */ +#define CS_TEXT_NONE(startFrame, endFrame) \ + CS_TEXT_DISPLAY_TEXTBOX(0xFFFF, startFrame, endFrame, CS_TEXTBOX_TYPE_NONE, 0xFFFF, 0xFFFF) + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000005A eeeeeeee + * size = 0x8 + */ +#define CS_CAMERA_LIST(entries) { CS_CMD_CAMERA }, { CMD_W(entries) } + +// TODO: Camera command macros. Requieres func_80161998 being decomped + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000096 eeeeeeee + * size = 0x8 + */ +#define CS_MISC_LIST(entries) { CS_CMD_MISC }, { CMD_W(entries) } + +/** + * ARGS + * s16 unk (u), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * uuuussss eeeeUUUU + * size = 0x08 + */ +#define CS_MISC(unk, startFrame, endFrame, unk_06) \ + { CMD_HH(unk, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000097 eeeeeeee + * size = 0x8 + */ +#define CS_LIGHTING_LIST(entries) { CS_CMD_SET_LIGHTING }, { CMD_W(entries) } + +/** + * ARGS + * s16 setting (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_LIGHTING(setting, startFrame, endFrame) \ + { CMD_HH(setting, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000098 eeeeeeee + * size = 0x8 + */ +#define CS_SCENE_TRANS_FX_LIST(entries) { CS_CMD_SCENE_TRANS_FX }, { CMD_W(entries) } + +/** + * ARGS + * s16 transitionType (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_SCENE_TRANS_FX(transitionType, startFrame, endFrame) \ + { CMD_HH(transitionType, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000099 eeeeeeee + * size = 0x08 + */ +#define CS_MOTIONBLUR_LIST(entries) { CS_CMD_MOTIONBLUR }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_MOTIONBLUR(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000009A eeeeeeee + * size = 0x8 + */ +#define CS_GIVETATL_LIST(entries) { CS_CMD_GIVETATL }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_GIVETATL(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000009B eeeeeeee + * size = 0x8 + */ +#define CS_FADESCREEN_LIST(entries) { CS_CMD_FADESCREEN }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e), + * u8 red (r), u8 green (g), blue (b) + * FORMAT + * Capital U is Unused + * mmmmssss eeeerrgg bbUUUUUU + * size = 0x0C + */ +#define CS_FADESCREEN(base, startFrame, endFrame, red, green, blue) \ + { CMD_HH(base, startFrame) }, { CMD_HBB(endFrame, red, green) }, { CMD_BBBB(blue, 0, 0, 0) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000009C eeeeeeee + * size = 0x8 + */ +#define CS_FADESEQ_LIST(entries) { CS_CMD_FADESEQ }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU UUUUUUUU + * size = 0x0C + */ +#define CS_FADESEQ(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, 0) }, { CMD_W(0) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000009D eeeeeeee + * size = 0x8 + */ +#define CS_TIME_LIST(entries) { CS_CMD_SETTIME }, { CMD_W(entries) } + +/** + * ARGS + * s16 unk (u), s16 startFrame (s), s16 endFrame (e), s8 hour (h), s8 min (m) + * FORMAT + * Capital U is Unused + * uuuussss eeeehhmm UUUUUUUU + * size = 0xC + */ +#define CS_TIME(unk, startFrame, endFrame, hour, min, unused) \ + { CMD_HH(unk, startFrame) }, { CMD_HBB(endFrame, hour, min) }, { CMD_W(unused) } + + +/** + * ARGS + * s32 cmdType (c), s32 entries (e) + * FORMAT + * cccccccc eeeeeeee + * size = 0x8 + */ +#define CS_ACTOR_ACTION_LIST(cmdType, entries) { CMD_W(cmdType) }, { CMD_W(entries) } + +/** + * ARGS + * s16 npcAction (a), s16 startFrame (s), s16 endFrame (e), + * s16 rotX (u), s16 rotY (v), s16 rotZ (w), + * s32 startX (i), s32 startY (j), s32 startZ (k), + * s32 endX (l), s32 endY (m), s32 endZ (n), + * f32 normX (x), f32 normY (y), f32 normZ (z), + * FORMAT + * aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz + * size = 0x30 + */ +#define CS_ACTOR_ACTION(npcAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \ + { CMD_HH(npcAction, startFrame) }, { CMD_HH(endFrame, rotX) }, { CMD_HH(rotY, rotZ) }, \ + { CMD_W(startX) }, { CMD_W(startY) }, { CMD_W(startZ) }, \ + { CMD_W(endX) }, { CMD_W(endY) }, { CMD_W(endZ) }, \ + { CMD_F(normX) }, { CMD_F(normY) }, { CMD_F(normZ) } + + +/** + * ARGS + * s32 cmdType (c), s32 entries (e) + * FORMAT + * 000000C8 eeeeeeee + * size = 0x8 + */ +#define CS_PLAYER_ACTION_LIST(entries) { CS_CMD_SET_PLAYER_ACTION }, { CMD_W(entries) } + +/** + * ARGS + * s16 playerAction (a), s16 startFrame (s), s16 endFrame (e), + * s16 rotX (u), s16 rotY (v), s16 rotZ (w), + * s32 startX (i), s32 startY (j), s32 startZ (k), + * s32 endX (l), s32 endY (m), s32 endZ (n), + * f32 normX (x), f32 normY (y), f32 normZ (z), + * FORMAT + * aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz + * size = 0x30 + */ +#define CS_PLAYER_ACTION(playerAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \ + CS_ACTOR_ACTION(playerAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000012C eeeeeeee + * size = 0x8 + */ +#define CS_PLAYSEQ_LIST(entries) { CS_CMD_PLAYSEQ }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_PLAYSEQ(sequence, startFrame, endFrame) \ + { CMD_HH(sequence, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000130 eeeeeeee + * size = 0x8 + */ +#define CS_SCENE_UNK_130_LIST(entries) { CS_CMD_130 }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x30 + */ +#define CS_SCENE_UNK_130(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000131 eeeeeeee + * size = 0x8 + */ +#define CS_SCENE_UNK_131_LIST(entries) { CS_CMD_131 }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_SCENE_UNK_131(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000132 eeeeeeee + * size = 0x8 + */ +#define CS_SCENE_UNK_132_LIST(entries) { CS_CMD_132 }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_SCENE_UNK_132(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000133 eeeeeeee + * size = 0x8 + */ +#define CS_STOPSEQ_LIST(entries) { CS_CMD_STOPSEQ }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_STOPSEQ(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000134 eeeeeeee + * size = 0x8 + */ +#define CS_PLAYAMBIENCE_LIST(entries) { CS_CMD_PLAYAMBIENCE }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_PLAYAMBIENCE(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000135 eeeeeeee + * size = 0x8 + */ +#define CS_FADEAMBIENCE_LIST(entries) { CS_CMD_FADEAMBIENCE }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_FADEAMBIENCE(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000015E eeeeeeee + * size = 0x8 + */ +#define CS_TERMINATOR_LIST(entries) { CS_CMD_TERMINATOR }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_TERMINATOR(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 0000015F eeeeeeee + * size = 0x8 + */ +#define CS_CHOOSE_CREDITS_SCENES_LIST(entries) { CS_CMD_CHOOSE_CREDITS_SCENES }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_CHOOSE_CREDITS_SCENES(base, startFrame, endFrame) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, endFrame) } + + +/** + * ARGS + * s32 entries (e) + * FORMAT + * 00000004 eeeeeeee + * size = 0x8 + */ +#define CS_RUMBLE_LIST(entries) { CS_CMD_RUMBLE }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_RUMBLE(base, startFrame, endFrame, unk6, unk7, unk8) \ + { CMD_HH(base, startFrame) }, { CMD_HBB(endFrame, unk6, unk7) }, { CMD_BBBB(unk8, 0, 0, 0) } + + +/** + * ARGS + * s32 cmd (c), s32 entries (e) + * FORMAT + * cccccccc eeeeeeee + * size = 0x8 + */ +#define CS_UNK_DATA_LIST(cmd, entries) { CMD_W(cmd) }, { CMD_W(entries) } + +/** + * ARGS + * s16 base (m), s16 startFrame (s), s16 endFrame (e) + * FORMAT + * Capital U is Unused + * mmmmssss eeeeUUUU + * size = 0x08 + */ +#define CS_UNK_DATA(base, startFrame, endFrame, unk_06) \ + { CMD_HH(base, startFrame) }, { CMD_HH(endFrame, unk_06) } + /** * Marks the end of a cutscene */ -#define CS_END() 0xFFFFFFFF +#define CS_END() { CMD_W(0xFFFFFFFF) } #endif diff --git a/include/z64effect.h b/include/z64effect.h index adb690732..0b848a478 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,9 +254,10 @@ typedef struct { /* 0x0C */ void* vramEnd; /* 0x10 */ void* loadedRamAddr; /* 0x14 */ EffectSsInit* initInfo; - /* 0x18 */ u32 unk18; // Always 0x01000000? + /* 0x18 */ u8 unk18; // Always 1? } EffectSsOverlay; // size = 0x1C +//! TODO: Review reuse of vec/gfx/actor fields across all effects typedef struct EffectSs { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; @@ -274,27 +280,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 434b565fb..785d56577 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -12,56 +12,233 @@ typedef enum { } EquipmentType; typedef enum { - /* 0x0 */ UPG_QUIVER, - /* 0x1 */ UPG_BOMB_BAG, - /* 0x4 */ UPG_WALLET = 0x4, - /* 0x6 */ UPG_STICK = 0x6, - /* 0x7 */ UPG_NUTS + /* 0x00 */ UPG_QUIVER, + /* 0x01 */ UPG_BOMB_BAG, + /* 0x02 */ UPG_STRENGTH, + /* 0x03 */ UPG_SCALE, + /* 0x04 */ UPG_WALLET, + /* 0x05 */ UPG_BULLET_BAG, + /* 0x06 */ UPG_STICKS, + /* 0x07 */ UPG_NUTS } UpgradeType; +typedef enum { + /* 0x00 */ QUEST_REMAINS_ODOWLA, + /* 0x01 */ QUEST_REMAINS_GOHT, + /* 0x02 */ QUEST_REMAINS_GYORG, + /* 0x03 */ QUEST_REMAINS_TWINMOLD, + /* 0x04 */ QUEST_SHIELD, + /* 0x05 */ QUEST_SWORD, + /* 0x06 */ QUEST_SONG_SONATA, + /* 0x07 */ QUEST_SONG_LULLABY, + /* 0x08 */ QUEST_SONG_BOSSA_NOVA, + /* 0x09 */ QUEST_SONG_ELEGY, + /* 0x0A */ QUEST_SONG_OATH, + /* 0x0B */ QUEST_SONG_SARIA, + /* 0x0C */ QUEST_SONG_TIME, + /* 0x0D */ QUEST_SONG_HEALING, + /* 0x0E */ QUEST_SONG_EPONA, + /* 0x0F */ QUEST_SONG_SOARING, + /* 0x10 */ QUEST_SONG_STORMS, + /* 0x11 */ QUEST_SONG_SUN, + /* 0x12 */ QUEST_BOMBERS_NOTEBOOK, + /* 0x18 */ QUEST_SONG_LULLABY_INTRO = 0x18, + /* 0x19 */ QUEST_UNK_19 // Related to PictoBox +} QuestItem; + +typedef enum { + /* 0x00 */ SLOT_OCARINA, + /* 0x01 */ SLOT_BOW, + /* 0x02 */ SLOT_ARROW_FIRE, + /* 0x03 */ SLOT_ARROW_ICE, + /* 0x04 */ SLOT_ARROW_LIGHT, + /* 0x05 */ SLOT_TRADE_DEED, + /* 0x06 */ SLOT_BOMB, + /* 0x07 */ SLOT_BOMBCHU, + /* 0x08 */ SLOT_STICK, + /* 0x09 */ SLOT_NUT, + /* 0x0A */ SLOT_MAGIC_BEANS, + /* 0x0B */ SLOT_TRADE_KEY_MAMA, + /* 0x0C */ SLOT_POWDER_KEG, + /* 0x0D */ SLOT_PICTO_BOX, + /* 0x0E */ SLOT_LENS, + /* 0x0F */ SLOT_HOOKSHOT, + /* 0x10 */ SLOT_SWORD_GREAT_FAIRY, + /* 0x11 */ SLOT_TRADE_COUPLE, + /* 0x12 */ SLOT_BOTTLE_1, + /* 0x13 */ SLOT_BOTTLE_2, + /* 0x14 */ SLOT_BOTTLE_3, + /* 0x15 */ SLOT_BOTTLE_4, + /* 0x16 */ SLOT_BOTTLE_5, + /* 0x17 */ SLOT_BOTTLE_6, + /* 0x18 */ SLOT_MASK_POSTMAN, + /* 0x19 */ SLOT_MASK_ALL_NIGHT, + /* 0x1A */ SLOT_MASK_BLAST, + /* 0x1B */ SLOT_MASK_STONE, + /* 0x1C */ SLOT_MASK_GREAT_FAIRY, + /* 0x1D */ SLOT_MASK_DEKU, + /* 0x1E */ SLOT_MASK_KEATON, + /* 0x1F */ SLOT_MASK_BREMEN, + /* 0x20 */ SLOT_MASK_BUNNY, + /* 0x21 */ SLOT_MASK_DON_GERO, + /* 0x22 */ SLOT_MASK_SCENTS, + /* 0x23 */ SLOT_MASK_GORON, + /* 0x24 */ SLOT_MASK_ROMANI, + /* 0x25 */ SLOT_MASK_CIRCUS_LEADER, + /* 0x26 */ SLOT_MASK_KAFEIS_MASK, + /* 0x27 */ SLOT_MASK_COUPLE, + /* 0x28 */ SLOT_MASK_TRUTH, + /* 0x29 */ SLOT_MASK_ZORA, + /* 0x2A */ SLOT_MASK_KAMARO, + /* 0x2B */ SLOT_MASK_GIBDO, + /* 0x2C */ SLOT_MASK_GARO, + /* 0x2D */ SLOT_MASK_CAPTAIN, + /* 0x2E */ SLOT_MASK_GIANT, + /* 0x2F */ SLOT_MASK_FIERCE_DEITY, + /* 0xFF */ SLOT_NONE = 0xFF +} InventorySlot; + typedef enum { /* 0x00 */ ITEM_OCARINA, /* 0x01 */ ITEM_BOW, - /* 0x06 */ ITEM_BOMB = 0x06, + /* 0x02 */ ITEM_ARROW_FIRE, + /* 0x03 */ ITEM_ARROW_ICE, + /* 0x04 */ ITEM_ARROW_LIGHT, + /* 0x05 */ ITEM_OCARINA_FAIRY, + /* 0x06 */ ITEM_BOMB, /* 0x07 */ ITEM_BOMBCHU, /* 0x08 */ ITEM_STICK, /* 0x09 */ ITEM_NUT, - /* 0x10 */ ITEM_SWORD_GREAT_FAIRY = 0x10, - /* 0x12 */ ITEM_BOTTLE = 0x12, + /* 0x0A */ ITEM_MAGIC_BEANS, + /* 0x0B */ ITEM_SLINGSHOT, + /* 0x0C */ ITEM_POWDER_KEG, + /* 0x0D */ ITEM_PICTO_BOX, + /* 0x0E */ ITEM_LENS, + /* 0x0F */ ITEM_HOOKSHOT, + /* 0x10 */ ITEM_SWORD_GREAT_FAIRY, + /* 0x11 */ ITEM_LONGSHOT, // OoT Leftover + /* 0x12 */ ITEM_BOTTLE, /* 0x13 */ ITEM_POTION_RED, /* 0x14 */ ITEM_POTION_GREEN, /* 0x15 */ ITEM_POTION_BLUE, /* 0x16 */ ITEM_FAIRY, /* 0x17 */ ITEM_DEKU_PRINCESS, - /* 0x1E */ ITEM_MUSHROOM = 0x1E, - /* 0x32 */ ITEM_MASK_DEKU = 0x32, - /* 0x38 */ ITEM_MASK_ALL_NIGHT = 0x38, - /* 0x3A */ ITEM_MASK_KEATON = 0x3A, + /* 0x18 */ ITEM_MILK_BOTTLE, + /* 0x19 */ ITEM_MILK_HALF, + /* 0x1A */ ITEM_FISH, + /* 0x1B */ ITEM_BUG, + /* 0x1C */ ITEM_BLUE_FIRE, + /* 0x1D */ ITEM_POE, + /* 0x1E */ ITEM_BIG_POE, + /* 0x1F */ ITEM_SPRING_WATER, + /* 0x20 */ ITEM_HOT_SPRING_WATER, + /* 0x21 */ ITEM_ZORA_EGG, + /* 0x22 */ ITEM_GOLD_DUST, + /* 0x23 */ ITEM_MUSHROOM, + /* 0x24 */ ITEM_SEA_HORSE, + /* 0x25 */ ITEM_CHATEAU, + /* 0x26 */ ITEM_HYLIAN_LOACH, + /* 0x27 */ ITEM_OBABA_DRINK, + /* 0x28 */ ITEM_MOON_TEAR, + /* 0x29 */ ITEM_DEED_LAND, + /* 0x2A */ ITEM_DEED_SWAMP, + /* 0x2B */ ITEM_DEED_MOUNTAIN, + /* 0x2C */ ITEM_DEED_OCEAN, + /* 0x2D */ ITEM_ROOM_KEY, + /* 0x2E */ ITEM_LETTER_MAMA, + /* 0x2F */ ITEM_LETTER_TO_KAFEI, + /* 0x30 */ ITEM_PENDANT_MEMORIES, + /* 0x31 */ ITEM_TINGLE_MAP, + /* 0x32 */ ITEM_MASK_DEKU, + /* 0x33 */ ITEM_MASK_GORON, + /* 0x34 */ ITEM_MASK_ZORA, + /* 0x35 */ ITEM_MASK_FIERCE_DEITY, + /* 0x36 */ ITEM_MASK_TRUTH, + /* 0x37 */ ITEM_MASK_KAFEIS_MASK, + /* 0x38 */ ITEM_MASK_ALL_NIGHT, + /* 0x39 */ ITEM_MASK_BUNNY, + /* 0x3A */ ITEM_MASK_KEATON, /* 0x3B */ ITEM_MASK_GARO, - /* 0x3C */ ITEM_MASK_ROMANIS, - /* 0x46 */ ITEM_MASK_BREMEN = 0x46, - /* 0x48 */ ITEM_MASK_SCENTS = 0x48, - /* 0x4D */ ITEM_SWORD_KOKIRI = 0x4D, + /* 0x3C */ ITEM_MASK_ROMANI, + /* 0x3D */ ITEM_MASK_CIRCUS_LEADER, + /* 0x3E */ ITEM_MASK_POSTMAN, + /* 0x3F */ ITEM_MASK_COUPLE, + /* 0x40 */ ITEM_MASK_GREAT_FAIRY, + /* 0x41 */ ITEM_MASK_GIBDO, + /* 0x42 */ ITEM_MASK_DON_GERO, + /* 0x43 */ ITEM_MASK_KAMARO, + /* 0x44 */ ITEM_MASK_CAPTAIN, + /* 0x45 */ ITEM_MASK_STONE, + /* 0x46 */ ITEM_MASK_BREMEN, + /* 0x47 */ ITEM_MASK_BLAST, + /* 0x48 */ ITEM_MASK_SCENTS, + /* 0x49 */ ITEM_MASK_GIANT, + /* 0x4A */ ITEM_BOW_ARROW_FIRE, + /* 0x4B */ ITEM_BOW_ARROW_ICE, + /* 0x4C */ ITEM_BOW_ARROW_LIGHT, + /* 0x4D */ ITEM_SWORD_KOKIRI, /* 0x4E */ ITEM_SWORD_RAZOR, /* 0x4F */ ITEM_SWORD_GILDED, /* 0x50 */ ITEM_SWORD_DEITY, /* 0x51 */ ITEM_SHIELD_HERO, /* 0x52 */ ITEM_SHIELD_MIRROR, - /* 0x56 */ ITEM_BOMB_BAG_20 = 0x56, + /* 0x53 */ ITEM_QUIVER_30, + /* 0x54 */ ITEM_QUIVER_40, + /* 0x55 */ ITEM_QUIVER_50, + /* 0x56 */ ITEM_BOMB_BAG_20, /* 0x57 */ ITEM_BOMB_BAG_30, /* 0x58 */ ITEM_BOMB_BAG_40, - /* 0x78 */ ITEM_KEY_SMALL = 0x78, + /* 0x59 */ ITEM_WALLET_DEFAULT, + /* 0x5A */ ITEM_WALLET_ADULT, + /* 0x5B */ ITEM_WALLET_GIANT, + /* 0x5C */ ITEM_FISHING_POLE, + /* 0x5D */ ITEM_REMAINS_ODOLWA, + /* 0x5E */ ITEM_REMAINS_GOHT, + /* 0x5F */ ITEM_REMAINS_GYORG, + /* 0x60 */ ITEM_REMAINS_TWINMOLD, + /* 0x61 */ ITEM_SONG_SONATA, + /* 0x62 */ ITEM_SONG_LULLABY, + /* 0x63 */ ITEM_SONG_NOVA, + /* 0x64 */ ITEM_SONG_ELEGY, + /* 0x65 */ ITEM_SONG_OATH, + /* 0x66 */ ITEM_SONG_SARIA, + /* 0x67 */ ITEM_SONG_TIME, + /* 0x68 */ ITEM_SONG_HEALING, + /* 0x69 */ ITEM_SONG_EPONA, + /* 0x6A */ ITEM_SONG_SOARING, + /* 0x6B */ ITEM_SONG_STORMS, + /* 0x6C */ ITEM_SONG_SUN, + /* 0x6D */ ITEM_BOMBERS_NOTEBOOK, + /* 0x6E */ ITEM_SKULL_TOKEN, + /* 0x6F */ ITEM_HEART_CONTAINER, + /* 0x70 */ ITEM_HEART_PIECE, + /* 0x73 */ ITEM_SONG_LULLABY_INTRO = 0x73, + /* 0x74 */ ITEM_KEY_BOSS, + /* 0x75 */ ITEM_COMPASS, + /* 0x76 */ ITEM_DUNGEON_MAP, + /* 0x77 */ ITEM_STRAY_FAIRIES, + /* 0x78 */ ITEM_KEY_SMALL, /* 0x79 */ ITEM_MAGIC_SMALL, /* 0x7A */ ITEM_MAGIC_LARGE, - /* 0x83 */ ITEM_HEART = 0x83, + /* 0x7B */ ITEM_HEART_PIECE_2, + /* 0x7C */ ITEM_INVALID_1, + /* 0x7D */ ITEM_INVALID_2, + /* 0x7E */ ITEM_INVALID_3, + /* 0x7F */ ITEM_INVALID_4, + /* 0x80 */ ITEM_INVALID_5, + /* 0x81 */ ITEM_INVALID_6, + /* 0x82 */ ITEM_INVALID_7, + /* 0x83 */ ITEM_HEART, /* 0x84 */ ITEM_RUPEE_GREEN, /* 0x85 */ ITEM_RUPEE_BLUE, /* 0x86 */ ITEM_RUPEE_10, /* 0x87 */ ITEM_RUPEE_RED, /* 0x88 */ ITEM_RUPEE_PURPLE, - /* 0x89 */ ITEM_RUPEE_100, - /* 0x8A */ ITEM_RUPEE_ORANGE, - /* 0x8D */ ITEM_NUTS_5 = 0x8D, + /* 0x89 */ ITEM_RUPEE_SILVER, + /* 0x8A */ ITEM_RUPEE_HUGE, + /* 0x8B */ ITEM_STICKS_5, + /* 0x8C */ ITEM_STICKS_10, + /* 0x8D */ ITEM_NUTS_5, /* 0x8E */ ITEM_NUTS_10, /* 0x8F */ ITEM_BOMBS_5, /* 0x90 */ ITEM_BOMBS_10, @@ -71,7 +248,20 @@ typedef enum { /* 0x94 */ ITEM_ARROWS_30, /* 0x95 */ ITEM_ARROWS_40, /* 0x96 */ ITEM_ARROWS_50, - /* 0x98 */ ITEM_BOMBCHUS_10 = 0x98, + /* 0x97 */ ITEM_BOMBCHUS_20, + /* 0x98 */ ITEM_BOMBCHUS_10, + /* 0x99 */ ITEM_BOMBCHUS_1, + /* 0x9A */ ITEM_BOMBCHUS_5, + /* 0x9B */ ITEM_STICK_UPGRADE_20, + /* 0x9C */ ITEM_STICK_UPGRADE_30, + /* 0x9D */ ITEM_NUT_UPGRADE_30, + /* 0x9E */ ITEM_NUT_UPGRADE_40, + /* 0x9F */ ITEM_CHATEAU_2, + /* 0xA0 */ ITEM_MILK, + /* 0xA1 */ ITEM_GOLD_DUST_2, + /* 0xA2 */ ITEM_HYLIAN_LOACH_2, + /* 0xA3 */ ITEM_SEA_HORSE_CAUGHT, + /* 0xFD */ ITEM_UNK_FD = 0xFD, /* 0xFF */ ITEM_NONE = 0xFF } ItemID; @@ -83,7 +273,10 @@ typedef enum { /* 0x04 */ GI_RUPEE_RED, /* 0x05 */ GI_RUPEE_PURPLE, /* 0x06 */ GI_RUPEE_SILVER, - /* 0x07 */ GI_RUPEE_GOLD, + /* 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, @@ -103,31 +296,67 @@ 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, + /* 0x50 */ GI_50 = 0x50, + /* 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, /* 0x5D */ GI_POTION_BLUE, /* 0x5E */ GI_FAIRY, /* 0x60 */ GI_MILK_BOTTLE = 0x60, - /* 0x7E */ GI_MASK_ALL_NIGHT = 0x7E, - /* 0x80 */ GI_MASK_KEATON = 0x80, - /* 0x82 */ GI_MASK_ROMANIS = 0x82, - /* 0x8C */ GI_MASK_BREMEN = 0x8C, + /* 0x78 */ GI_MASK_DEKU = 0x78, + /* 0x79 */ GI_MASK_GORON, + /* 0x7A */ GI_MASK_ZORA, + /* 0x7B */ GI_MASK_FIERCE_DEITY, + /* 0x7C */ GI_MASK_TRUTH, + /* 0x7D */ GI_MASK_KAFEIS_MASK, + /* 0x7E */ GI_MASK_ALL_NIGHT, + /* 0x7F */ GI_MASK_BUNNY, + /* 0x80 */ GI_MASK_KEATON, + /* 0x81 */ GI_MASK_GARO, + /* 0x82 */ GI_MASK_ROMANI, + /* 0x83 */ GI_MASK_CIRCUS_LEADER, + /* 0x84 */ GI_MASK_POSTMAN, + /* 0x85 */ GI_MASK_COUPLE, + /* 0x86 */ GI_MASK_GREAT_FAIRY, + /* 0x87 */ GI_MASK_GIBDO, + /* 0x88 */ GI_MASK_DON_GERO, + /* 0x89 */ GI_MASK_KAMARO, + /* 0x8A */ GI_MASK_CAPTAIN, + /* 0x8B */ GI_MASK_STONE, + /* 0x8C */ GI_MASK_BREMEN, + /* 0x8D */ GI_MASK_BLAST, + /* 0x8E */ GI_MASK_SCENTS, + /* 0x8F */ GI_MASK_GIANT, + /* 0x92 */ GI_MILK = 0x92, + /* 0x95 */ GI_95 = 0x95, + /* 0x96 */ GI_MOON_TEAR, + /* 0x97 */ GI_DEED_LAND, + /* 0x98 */ GI_DEED_SWAMP, + /* 0x99 */ GI_DEED_MOUNTAIN, + /* 0x9A */ GI_DEED_OCEAN, /* 0x9B */ GI_SWORD_GREAT_FAIRY = 0x9B, /* 0x9C */ GI_SWORD_KOKIRI, /* 0x9D */ GI_SWORD_RAZOR, /* 0x9E */ GI_SWORD_GILDED, /* 0x9F */ GI_SHIELD_HERO_2, // Code that treats this as hero's shield is unused, so take with a grain of salt /* 0xA1 */ GI_LETTER_TO_MAMA = 0xA1, - /* 0xA9 */ GI_BOTTLE = 0xA9 + /* 0xA9 */ GI_BOTTLE = 0xA9, + /* 0xAB */ GI_PENDANT_OF_MEMORIES = 0xAB, + /* 0xBA */ GI_MAX = 0xBA } GetItemID; typedef enum { /* 0x00 */ GID_BOTTLE, + /* 0x02 */ GID_02 = 0x02, + /* 0x03 */ GID_03, /* 0x0A */ GID_COMPASS = 0x0A, + /* 0x0E */ GID_0E = 0x0E, + /* 0x0F */ GID_0F, /* 0x10 */ GID_MASK_ALL_NIGHT = 0x10, /* 0x11 */ GID_NUTS, /* 0x17 */ GID_BOMB_BAG_20 = 0x17, @@ -145,11 +374,30 @@ typedef enum { /* 0x31 */ GID_POTION_RED, /* 0x32 */ GID_POTION_BLUE, /* 0x33 */ GID_SHIELD_MIRROR, - /* 0x3B */ GID_FAIRY = 0x3B, + /* 0x39 */ GID_39 = 0x39, + /* 0x3A */ GID_3A, + /* 0x3B */ GID_FAIRY, + /* 0x3E */ GID_3E = 0x3E, + /* 0x44 */ GID_44 = 0x44, + /* 0x45 */ GID_45, /* 0x55 */ GID_SWORD_KOKIRI = 0x55, /* 0x66 */ GID_SWORD_RAZOR = 0x66, /* 0x67 */ GID_SWORD_GILDED, - /* 0x68 */ GID_SWORD_GREAT_FAIRY + /* 0x68 */ GID_SWORD_GREAT_FAIRY, + /* 0x6A */ GID_6A = 0x6A, + /* 0x6B */ GID_6B, + /* 0x70 */ GID_70 = 0x70, + /* 0x71 */ GID_71 } GetItemDrawID; +// TODO: fill +typedef enum { + /* -1 */ EXCH_ITEM_MINUS1 = -1, // Unknown usage or function + /* 0x00 */ EXCH_ITEM_NONE, + /* 0x13 */ EXCH_ITEM_13 = 0x13, + /* 0x1E */ EXCH_ITEM_1E = 0x1E, // BOTTLE_MUSHROOM + /* 0x2A */ EXCH_ITEM_2A = 0x2A, // MOON_TEAR? + /* 0x2E */ EXCH_ITEM_2E = 0x2E +} ExchangeItemID; + #endif diff --git a/include/z64jpeg.h b/include/z64jpeg.h new file mode 100644 index 000000000..38183bfa9 --- /dev/null +++ b/include/z64jpeg.h @@ -0,0 +1,99 @@ +#ifndef Z64_JPEG_H +#define Z64_JPEG_H + +#include "PR/ultratypes.h" +#include "ultra64/message.h" +#include "PR/sched.h" + +typedef struct { + /* 0x00 */ u16 table[8*8]; +} JpegQuantizationTable; // size = 0x80 + +typedef struct { + /* 0x00 */ u8 codeOffs[16]; + /* 0x10 */ u16 codesA[16]; + /* 0x30 */ u16 codesB[16]; + /* 0x50 */ u8* symbols; +} JpegHuffmanTable; // size = 0x54 + +// this struct might be inaccurate but it's not used outside jpegutils.c +typedef struct { + /* 0x000 */ u8 codeOffs[16]; + /* 0x010 */ u16 dcCodes[120]; + /* 0x100 */ u16 acCodes[256]; +} JpegHuffmanTableOld; // size = 0x300 + +typedef struct { + /* 0x00 */ void* address; + /* 0x04 */ u32 mbCount; + /* 0x08 */ u32 mode; + /* 0x0C */ void* qTableYPtr; + /* 0x10 */ void* qTableUPtr; + /* 0x14 */ void* qTableVPtr; + /* 0x18 */ char unk_18[0x8]; +} JpegTaskData; // size = 0x20 + +typedef struct { + /* 0x000 */ JpegTaskData taskData; + /* 0x020 */ char yieldData[0x200]; + /* 0x220 */ JpegQuantizationTable qTableY; + /* 0x2A0 */ JpegQuantizationTable qTableU; + /* 0x320 */ JpegQuantizationTable qTableV; + /* 0x3A0 */ u8 codesLengths[0x110]; + /* 0x4B0 */ u16 codes[0x108]; + /* 0x6C0 */ u16 data[4][0x180]; +} JpegWork; // size = 0x12C0 + +typedef struct { + /* 0x00 */ void* imageData; + /* 0x04 */ u8 mode; + /* 0x05 */ u8 unk_05; + /* 0x08 */ JpegHuffmanTable* hTablePtrs[4]; + /* 0x18 */ u8 unk_18; +} JpegDecoder; // size = 0x1C + +typedef struct { + /* 0x00 */ u8 dqtCount; + /* 0x04 */ u8* dqtPtr[3]; + /* 0x10 */ u8 dhtCount; + /* 0x14 */ u8* dhtPtr[4]; + /* 0x24 */ void* imageData; + /* 0x28 */ u8 mode; // 0 if Y V0 is 1 and 2 if Y V0 is 2 + /* 0x30 */ OSScTask scTask; + /* 0x98 */ OSMesgQueue mq; + /* 0xB0 */ OSMesg msg; + /* 0xB4 */ JpegWork* workBuf; +} JpegContext; // size = 0xB8 + +typedef struct { + /* 0x00 */ u32 byteIdx; + /* 0x04 */ u8 bitIdx; + /* 0x05 */ u8 dontSkip; + /* 0x08 */ u32 curWord; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ s16 unk_0E; + /* 0x10 */ s16 unk_10; +} JpegDecoderState; // size = 0x14 + + +void Jpeg_ScheduleDecoderTask(JpegContext* jpegCtx); +void Jpeg_CopyToZbuffer(u16* src, u16* zbuffer, s32 x, s32 y); +u16 Jpeg_GetUnalignedU16(u8* ptr); +void Jpeg_ParseMarkers(u8* ptr, JpegContext* jpegCtx); +s32 Jpeg_Decode(void* data, void* zbuffer, void* work, u32 workSize); + +void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count); +s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths); +s32 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes); +s32 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes); +u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc); +u32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count); +void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc); +u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes); + +s32 JpegDecoder_Decode(JpegDecoder* decoder, u16* mcuBuff, s32 count, u8 isFollowing, JpegDecoderState* state); +s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, u16* mcu, s16* unk); +s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount); +u16 JpegDecoder_ReadBits(u8 len); + +#endif diff --git a/include/z64light.h b/include/z64light.h index 90ee01fb0..0c90be713 100644 --- a/include/z64light.h +++ b/include/z64light.h @@ -23,7 +23,7 @@ typedef struct { /* 0x12 */ s16 fogColor[3]; /* 0x18 */ s16 fogNear; /* 0x1A */ s16 fogFar; -} LightSettings2; // size = 0x1C +} EnvLightSettings; // size = 0x1C typedef struct { /* 0x0 */ s16 x; @@ -57,18 +57,12 @@ typedef struct Lights { /* 0x08 */ Lightsn l; } Lights; // size = 0x80 -typedef struct LightInfoPositional { - /* 0x0 */ u8 type; - /* 0x2 */ LightPoint params; -} LightInfoPositional; // size = 0xE - typedef struct LightNode { /* 0x0 */ LightInfo* info; /* 0x4 */ struct LightNode* prev; /* 0x8 */ struct LightNode* next; } LightNode; // size = 0xC -// TODO move LightsBuffer to .c file once .bss has been split #define LIGHTS_BUFFER_SIZE 32 typedef struct LightsBuffer { diff --git a/include/z64math.h b/include/z64math.h index 3caad9108..33f05bb0a 100644 --- a/include/z64math.h +++ b/include/z64math.h @@ -1,13 +1,18 @@ -#ifndef _Z64MATH_H_ -#define _Z64MATH_H_ +#ifndef Z64MATH_H +#define Z64MATH_H #include "ultra64.h" #define VEC_SET(V,X,Y,Z) V.x=X;V.y=Y;V.z=Z +typedef struct { + /* 0x00 */ s16 x; + /* 0x02 */ s16 z; +} Vec2s; // size = 0x04 + typedef struct { /* 0x00 */ f32 x; - /* 0x04 */ f32 y; + /* 0x04 */ f32 z; } Vec2f; // size = 0x08 typedef struct { @@ -44,6 +49,10 @@ typedef struct { /* 0x0C */ f32 radius; } Spheref; // size = 0x10 +/* +The plane paramaters are of form `ax + by + cz + d = 0` +where `(a,b,c)` is the plane's normal vector and d is the originDist + */ typedef struct { /* 0x00 */ Vec3f normal; /* 0x0C */ f32 originDist; @@ -85,9 +94,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)) @@ -101,7 +111,7 @@ typedef struct { // Trig macros #define DEGF_TO_BINANG(degreesf) (s16)(degreesf * 182.04167f + .5f) -#define RADF_TO_BINANG(radf) (s16)(radf * (32768.0f / M_PI)) +#define RADF_TO_BINANG(radf) (s16)(radf * (0x8000 / M_PI)) #define RADF_TO_DEGF(radf) (radf * (180.0f / M_PI)) #define DEGF_TO_RADF(degf) (degf * (M_PI / 180.0f)) #define BINANG_ROT180(angle) ((s16)(angle + 0x8000)) @@ -109,7 +119,7 @@ typedef struct { #define BINANG_ADD(a, b) ((s16)(a + b)) #define DEG_TO_RAD(degrees) ((degrees) * (M_PI / 180.0f)) #define BINANG_TO_DEGF(binang) ((f32)binang * (360.0001525f / 65535.0f)) -#define BINANG_TO_RAD(binang) (((f32)binang / 32768.0f) * M_PI) +#define BINANG_TO_RAD(binang) (((f32)binang / 0x8000) * M_PI) // Vector macros #define SQXZ(vec) ((vec.x) * (vec.x) + (vec.z) * (vec.z)) diff --git a/include/z64object.h b/include/z64object.h index 920a9e5dd..34035306b 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, @@ -405,7 +405,7 @@ typedef enum { /* 0x189 */ OBJECT_HANAREYAMA_OBJ, /* 0x18A */ OBJECT_CRACE_OBJECT, /* 0x18B */ OBJECT_DNQ, - /* 0x18C */ OBJECT_OBJECT_UNSET_TOKEIDAI, + /* 0x18C */ OBJECT_OBJ_TOKEIDAI, /* 0x18D */ OBJECT_EG, /* 0x18E */ OBJECT_TRU, /* 0x18F */ OBJECT_TRT, @@ -545,13 +545,13 @@ typedef enum { /* 0x215 */ OBJECT_GI_RESERVE_C_01, /* 0x216 */ OBJECT_ZOD, /* 0x217 */ OBJECT_KUMO30, - /* 0x218 */ OBJECT_OBJECT_UNSET_YASI, + /* 0x218 */ OBJECT_OBJ_YASI, /* 0x219 */ OBJECT_MASK_ROMERNY, /* 0x21A */ OBJECT_TANRON1, /* 0x21B */ OBJECT_TANRON2, /* 0x21C */ OBJECT_TANRON3, /* 0x21D */ OBJECT_GI_MAGICMUSHROOM, - /* 0x21E */ OBJECT_OBJECT_UNSET_CHAN, + /* 0x21E */ OBJECT_OBJ_CHAN, /* 0x21F */ OBJECT_GI_MASK10, /* 0x220 */ OBJECT_ZOS, /* 0x221 */ OBJECT_MASK_POSTHAT, @@ -589,7 +589,7 @@ typedef enum { /* 0x241 */ OBJECT_DT, /* 0x242 */ OBJECT_GI_MASK03, /* 0x243 */ OBJECT_CHA, - /* 0x244 */ OBJECT_OBJECT_UNSET_DINNER, + /* 0x244 */ OBJECT_OBJ_DINNER, /* 0x245 */ OBJECT_GI_RESERVE_B_01, /* 0x246 */ OBJECT_LASTDAY, /* 0x247 */ OBJECT_BAI, @@ -608,7 +608,7 @@ typedef enum { /* 0x254 */ OBJECT_GI_STONEMASK, /* 0x255 */ OBJECT_ZORABAND, /* 0x256 */ OBJECT_KEPN_KOYA, - /* 0x257 */ OBJECT_OBJECT_UNSET_USIYANE, + /* 0x257 */ OBJECT_OBJ_USIYANE, /* 0x258 */ OBJECT_GI_MASK05, /* 0x259 */ OBJECT_GI_MASK11, /* 0x25A */ OBJECT_GI_MASK20, @@ -618,7 +618,7 @@ typedef enum { /* 0x25E */ OBJECT_MASK_MEOTO, /* 0x25F */ OBJECT_MASK_DANCER, /* 0x260 */ OBJECT_KZSAKU, - /* 0x261 */ OBJECT_OBJECT_UNSET_MILK_BIN, + /* 0x261 */ OBJECT_OBJ_MILK_BIN, /* 0x262 */ OBJECT_RANDOM_OBJ, /* 0x263 */ OBJECT_KUJIYA, /* 0x264 */ OBJECT_KITAN, @@ -636,7 +636,7 @@ typedef enum { /* 0x270 */ OBJECT_MOONEND, /* 0x271 */ OBJECT_OB, /* 0x272 */ OBJECT_GI_BOTTLE_04, - /* 0x273 */ OBJECT_OBJECT_UNSET_DANPEILIFT, + /* 0x273 */ OBJECT_OBJ_DANPEILIFT, /* 0x274 */ OBJECT_WDOR01, /* 0x275 */ OBJECT_WDOR02, /* 0x276 */ OBJECT_WDOR03, diff --git a/include/z64ocarina.h b/include/z64ocarina.h new file mode 100644 index 000000000..56ab48312 --- /dev/null +++ b/include/z64ocarina.h @@ -0,0 +1,125 @@ +#ifndef Z64OCARINA_H +#define Z64OCARINA_H + +#include "ultra64.h" + +typedef enum { + /* 0 */ OCARINA_SONG_SONATA, + /* 1 */ OCARINA_SONG_GORON_LULLABY, + /* 2 */ OCARINA_SONG_NEW_WAVE, + /* 3 */ OCARINA_SONG_ELEGY, + /* 4 */ OCARINA_SONG_OATH, + /* 5 */ OCARINA_SONG_SARIAS, + /* 6 */ OCARINA_SONG_TIME, + /* 7 */ OCARINA_SONG_HEALING, + /* 8 */ OCARINA_SONG_EPONAS, + /* 9 */ OCARINA_SONG_SOARING, + /* 10 */ OCARINA_SONG_STORMS, + /* 11 */ OCARINA_SONG_SUNS, + /* 12 */ OCARINA_SONG_INVERTED_TIME, + /* 13 */ OCARINA_SONG_DOUBLE_TIME, + /* 14 */ OCARINA_SONG_GORON_LULLABY_INTRO, + /* 15 */ OCARINA_SONG_WIND_FISH_HUMAN, // "Ballad of the Wind Fish" + /* 16 */ OCARINA_SONG_WIND_FISH_GORON, + /* 17 */ OCARINA_SONG_WIND_FISH_ZORA, + /* 18 */ OCARINA_SONG_WIND_FISH_DEKU, + /* 19 */ OCARINA_SONG_EVAN_PART1, + /* 20 */ OCARINA_SONG_EVAN_PART2, + /* 21 */ OCARINA_SONG_ZELDAS_LULLABY, + /* 22 */ OCARINA_SONG_SCARECROW, + /* 23 */ OCARINA_SONG_TERMINA_WALL, + /* 24 */ OCARINA_SONG_MAX, + /* 24 */ OCARINA_SONG_SCARECROW_LONG = OCARINA_SONG_MAX +} OcarinaSongId; + +typedef enum { + /* 0 */ OCARINA_BTN_A, + /* 1 */ OCARINA_BTN_C_DOWN, + /* 2 */ OCARINA_BTN_C_RIGHT, + /* 3 */ OCARINA_BTN_C_LEFT, + /* 4 */ OCARINA_BTN_C_UP, + /* -1 */ OCARINA_BTN_INVALID = 0xFF +} OcarinaButtonIndex; + +// Uses scientific pitch notation relative to middle C +// https://en.wikipedia.org/wiki/Scientific_pitch_notation +typedef enum { + /* 0x0 */ OCARINA_PITCH_C4, + /* 0x1 */ OCARINA_PITCH_DFLAT4, + /* 0x2 */ OCARINA_PITCH_D4, + /* 0x3 */ OCARINA_PITCH_EFLAT4, + /* 0x4 */ OCARINA_PITCH_E4, + /* 0x5 */ OCARINA_PITCH_F4, + /* 0x6 */ OCARINA_PITCH_GFLAT4, + /* 0x7 */ OCARINA_PITCH_G4, + /* 0x8 */ OCARINA_PITCH_AFLAT4, + /* 0x9 */ OCARINA_PITCH_A4, + /* 0xA */ OCARINA_PITCH_BFLAT4, + /* 0xB */ OCARINA_PITCH_B4, + /* 0xC */ OCARINA_PITCH_C5, + /* 0xD */ OCARINA_PITCH_DFLAT5, + /* 0xE */ OCARINA_PITCH_D5, + /* 0xF */ OCARINA_PITCH_EFLAT5, + /* -1 */ OCARINA_PITCH_NONE = 0xFF +} OcarinaPitch; + +// Mainly set by func_80152CAC in z_message.c +typedef enum { + /* 0 */ OCARINA_INSTRUMENT_OFF, + /* 1 */ OCARINA_INSTRUMENT_DEFAULT, + /* 2 */ OCARINA_INSTRUMENT_FEMALE_VOICE, + /* 3 */ OCARINA_INSTRUMENT_WHISTLING_FLUTE, + /* 4 */ OCARINA_INSTRUMENT_HARP, + /* 5 */ OCARINA_INSTRUMENT_IKANA_KING, + /* 6 */ OCARINA_INSTRUMENT_TATL, + /* 7 */ OCARINA_INSTRUMENT_GORON_DRUMS, + /* 8 */ OCARINA_INSTRUMENT_ZORA_GUITAR, + /* 9 */ OCARINA_INSTRUMENT_DEKU_PIPES, + /* 10 */ OCARINA_INSTRUMENT_MONKEY, + /* 11 */ OCARINA_INSTRUMENT_DEKU_TRUMPET, // Pull out ocarina for captured monkey + /* 12 */ OCARINA_INSTRUMENT_ELDER_GORON_DRUMS, + /* 13 */ OCARINA_INSTRUMENT_PIANO, + /* 14 */ OCARINA_INSTRUMENT_BASS_GUITAR, + /* 15 */ OCARINA_INSTRUMENT_BABY_SINGING, + /* 16 */ OCARINA_INSTRUMENT_AMPLIFIED_GUITAR // Related to (gSaveContext.weekEventReg[41] & 0x20) +} OcarinaInstrumentId; + +typedef enum { + /* 0 */ OCARINA_RECORD_OFF, + /* 1 */ OCARINA_RECORD_SCARECROW_LONG, + /* 2 */ OCARINA_RECORD_SCARECROW_SPAWN, + /* -1 */ OCARINA_RECORD_REJECTED = 0xFF +} OcarinaRecordingState; + +/** + * BFlat4Flag Note: + * Flag for resolving whether (pitch = OCARINA_PITCH_BFLAT4) + * gets mapped to either C_RIGHT and C_LEFT + * + * This is required as C_RIGHT and C_LEFT are the only notes + * that map to two semitones apart (NOTE_A4 and NOTE_B4) + * 0x40 - BTN_Z is pressed to lower note by a semitone + * 0x80 - BTN_R is pressed to raise note by a semitone + */ + +typedef struct { + /* 0x0 */ u8 pitch; // number of semitones above middle C + /* 0x2 */ u16 length; // number of frames the note is sustained + /* 0x4 */ u8 volume; + /* 0x5 */ u8 vibrato; + /* 0x6 */ s8 bend; // frequency multiplicative offset from the pitch defined by pitch + /* 0x7 */ u8 BFlat4Flag; // See note above +} OcarinaNote; // size = 0x8 + +typedef struct { + /* 0x0 */ u8 numButtons; + /* 0x1 */ u8 buttonIndex[8]; +} OcarinaSongButtons; // size = 0x9 + +typedef struct { + /* 0x0 */ u8 buttonIndex; + /* 0x1 */ u8 state; // original name: "status" + /* 0x2 */ u8 pos; // original name: "locate" +} OcarinaStaff; // size = 0x3 + +#endif diff --git a/include/z64player.h b/include/z64player.h index 8bab2605f..4066e2baf 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -1,5 +1,5 @@ -#ifndef _Z64PLAYER_H_ -#define _Z64PLAYER_H_ +#ifndef Z64PLAYER_H +#define Z64PLAYER_H #include "z64actor.h" #include "os.h" @@ -7,50 +7,139 @@ struct Player; typedef enum { - /* 0x00 */ PLAYER_SHIELD_NONE, - /* 0x01 */ PLAYER_SHIELD_HEROS_SHIELD, - /* 0x02 */ PLAYER_SHIELD_MIRROR_SHIELD, - /* 0x03 */ PLAYER_SHIELD_MAX + /* 0x00 */ PLAYER_SHIELD_NONE, + /* 0x01 */ PLAYER_SHIELD_HEROS_SHIELD, + /* 0x02 */ PLAYER_SHIELD_MIRROR_SHIELD, + /* 0x03 */ PLAYER_SHIELD_MAX } PlayerShield; typedef enum { - /* 0x00 */ PLAYER_FORM_FIERCE_DEITY, - /* 0x01 */ PLAYER_FORM_GORON, - /* 0x02 */ PLAYER_FORM_ZORA, - /* 0x03 */ PLAYER_FORM_DEKU, - /* 0x04 */ PLAYER_FORM_HUMAN, - /* 0x05 */ PLAYER_FORM_MAX + /* 0x00 */ PLAYER_BOOTS_FIERCE_DEITY, + /* 0x01 */ PLAYER_BOOTS_HYLIAN, + /* 0x02 */ PLAYER_BOOTS_GIANT, + /* 0x03 */ PLAYER_BOOTS_DEKU, + /* 0x04 */ PLAYER_BOOTS_ZORA_LAND, + /* 0x05 */ PLAYER_BOOTS_ZORA_UNDERWATER, + /* 0x06 */ PLAYER_BOOTS_GORON, + /* 0x07 */ PLAYER_BOOTS_MAX +} PlayerBoots; + +typedef enum { + /* 0x00 */ PLAYER_FORM_FIERCE_DEITY, + /* 0x01 */ PLAYER_FORM_GORON, + /* 0x02 */ PLAYER_FORM_ZORA, + /* 0x03 */ PLAYER_FORM_DEKU, + /* 0x04 */ PLAYER_FORM_HUMAN, + /* 0x05 */ PLAYER_FORM_MAX } PlayerTransformation; typedef enum { - /* 0x00 */ PLAYER_MASK_NONE, - /* 0x01 */ PLAYER_MASK_MASK_OF_TRUTH, - /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, - /* 0x03 */ PLAYER_MASK_ALL_NIGHT_MASK, - /* 0x04 */ PLAYER_MASK_BUNNY_HOOD, - /* 0x05 */ PLAYER_MASK_KEATON_MASK, - /* 0x06 */ PLAYER_MASK_GAROS_MASK, - /* 0x07 */ PLAYER_MASK_ROMANIS_MASK, - /* 0x08 */ PLAYER_MASK_CIRCUS_LEADERS_MASK, - /* 0x09 */ PLAYER_MASK_POSTMANS_HAT, - /* 0x0A */ PLAYER_MASK_COUPLES_MASK, - /* 0x0B */ PLAYER_MASK_GREAT_FAIRYS_MASK, - /* 0x0C */ PLAYER_MASK_GIBDO_MASK, - /* 0x0D */ PLAYER_MASK_DON_GEROS_MASK, - /* 0x0E */ PLAYER_MASK_KAMAROS_MASK, - /* 0x0F */ PLAYER_MASK_CAPTAINS_HAT, - /* 0x10 */ PLAYER_MASK_STONE_MASK, - /* 0x11 */ PLAYER_MASK_BREMEN_MASK, - /* 0x12 */ PLAYER_MASK_BLAST_MASK, - /* 0x13 */ PLAYER_MASK_MASK_OF_SCENTS, - /* 0x14 */ PLAYER_MASK_GIANTS_MASK, - /* 0x15 */ PLAYER_MASK_FIERCE_DEITYS_MASK, - /* 0x16 */ PLAYER_MASK_GORON_MASK, - /* 0x17 */ PLAYER_MASK_ZORA_MASK, - /* 0x18 */ PLAYER_MASK_DEKU_MASK, - /* 0x19 */ PLAYER_MASK_MAX + /* 0x00 */ PLAYER_MASK_NONE, + /* 0x01 */ PLAYER_MASK_TRUTH, + /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, + /* 0x03 */ PLAYER_MASK_ALL_NIGHT, + /* 0x04 */ PLAYER_MASK_BUNNY, + /* 0x05 */ PLAYER_MASK_KEATON, + /* 0x06 */ PLAYER_MASK_GARO, + /* 0x07 */ PLAYER_MASK_ROMANI, + /* 0x08 */ PLAYER_MASK_CIRCUS_LEADER, + /* 0x09 */ PLAYER_MASK_POSTMAN, + /* 0x0A */ PLAYER_MASK_COUPLE, + /* 0x0B */ PLAYER_MASK_GREAT_FAIRY, + /* 0x0C */ PLAYER_MASK_GIBDO, + /* 0x0D */ PLAYER_MASK_DON_GERO, + /* 0x0E */ PLAYER_MASK_KAMARO, + /* 0x0F */ PLAYER_MASK_CAPTAIN, + /* 0x10 */ PLAYER_MASK_STONE, + /* 0x11 */ PLAYER_MASK_BREMEN, + /* 0x12 */ PLAYER_MASK_BLAST, + /* 0x13 */ PLAYER_MASK_SCENTS, + /* 0x14 */ PLAYER_MASK_GIANT, + /* 0x15 */ PLAYER_MASK_FIERCE_DEITY, + /* 0x16 */ PLAYER_MASK_GORON, + /* 0x17 */ PLAYER_MASK_ZORA, + /* 0x18 */ PLAYER_MASK_DEKU, + /* 0x19 */ PLAYER_MASK_MAX } PlayerMask; +typedef enum { + /* 0x00 */ PLAYER_AP_NONE, + /* 0x01 */ PLAYER_AP_UNK_1, + /* 0x02 */ PLAYER_AP_UNK_2, + /* 0x03 */ PLAYER_AP_SWORD_KOKIRI, + /* 0x04 */ PLAYER_AP_SWORD_RAZOR, + /* 0x05 */ PLAYER_AP_SWORD_GILDED, + /* 0x06 */ PLAYER_AP_SWORD_GREAT_FAIRY, + /* 0x07 */ PLAYER_AP_STICK, + /* 0x08 */ PLAYER_AP_UNK_8, + /* 0x09 */ PLAYER_AP_BOW, + /* 0x0A */ PLAYER_AP_BOW_FIRE, + /* 0x0B */ PLAYER_AP_BOW_ICE, + /* 0x0C */ PLAYER_AP_BOW_LIGHT, + /* 0x0D */ PLAYER_AP_HOOKSHOT, + /* 0x0E */ PLAYER_AP_BOMB, + /* 0x0F */ PLAYER_AP_POWDER_KEG, + /* 0x10 */ PLAYER_AP_BOMBCHU, + /* 0x12 */ PLAYER_AP_NUT = 0x12, + /* 0x13 */ PLAYER_AP_PICTO_BOX, + /* 0x14 */ PLAYER_AP_OCARINA, + /* 0x15 */ PLAYER_AP_BOTTLE, + /* 0x16 */ PLAYER_AP_BOTTLE_FISH, + /* 0x17 */ PLAYER_AP_BOTTLE_SPRING_WATER, + /* 0x18 */ PLAYER_AP_BOTTLE_HOT_SPRING_WATER, + /* 0x19 */ PLAYER_AP_BOTTLE_ZORA_EGG, + /* 0x1A */ PLAYER_AP_BOTTLE_DEKU_PRINCESS, + /* 0x1B */ PLAYER_AP_BOTTLE_GOLD_DUST, + /* 0x1D */ PLAYER_AP_BOTTLE_SEA_HORSE = 0x1D, + /* 0x1E */ PLAYER_AP_BOTTLE_MUSHROOM, + /* 0x1F */ PLAYER_AP_BOTTLE_HYLIAN_LOACH, + /* 0x20 */ PLAYER_AP_BOTTLE_BUG, + /* 0x21 */ PLAYER_AP_BOTTLE_POE, + /* 0x22 */ PLAYER_AP_BOTTLE_BIG_POE, + /* 0x23 */ PLAYER_AP_BOTTLE_POTION_RED, + /* 0x24 */ PLAYER_AP_BOTTLE_POTION_BLUE, + /* 0x25 */ PLAYER_AP_BOTTLE_POTION_GREEN, + /* 0x26 */ PLAYER_AP_BOTTLE_MILK, + /* 0x27 */ PLAYER_AP_BOTTLE_MILK_HALF, + /* 0x28 */ PLAYER_AP_BOTTLE_CHATEAU, + /* 0x29 */ PLAYER_AP_BOTTLE_FAIRY, + /* 0x2A */ PLAYER_AP_MOON_TEAR, + /* 0x2B */ PLAYER_AP_DEED_LAND, + /* 0x2C */ PLAYER_AP_ROOM_KEY, + /* 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_KAFEIS_MASK, + /* 0x3C */ PLAYER_AP_MASK_ALL_NIGHT, + /* 0x3D */ PLAYER_AP_MASK_BUNNY, + /* 0x3E */ PLAYER_AP_MASK_KEATON, + /* 0x3F */ PLAYER_AP_MASK_GARO, + /* 0x40 */ PLAYER_AP_MASK_ROMANI, + /* 0x41 */ PLAYER_AP_MASK_CIRCUS_LEADER, + /* 0x42 */ PLAYER_AP_MASK_POSTMAN, + /* 0x43 */ PLAYER_AP_MASK_COUPLE, + /* 0x44 */ PLAYER_AP_MASK_GREAT_FAIRY, + /* 0x45 */ PLAYER_AP_MASK_GIBDO, + /* 0x46 */ PLAYER_AP_MASK_DON_GERO, + /* 0x47 */ PLAYER_AP_MASK_KAMARO, + /* 0x48 */ PLAYER_AP_MASK_CAPTAIN, + /* 0x49 */ PLAYER_AP_MASK_STONE, + /* 0x4A */ PLAYER_AP_MASK_BREMEN, + /* 0x4B */ PLAYER_AP_MASK_BLAST, + /* 0x4C */ PLAYER_AP_MASK_SCENTS, + /* 0x4D */ PLAYER_AP_MASK_GIANT, + /* 0x4E */ PLAYER_AP_MASK_FIERCE_DEITY, + /* 0x4F */ PLAYER_AP_MASK_GORON, + /* 0x50 */ PLAYER_AP_MASK_ZORA, + /* 0x51 */ PLAYER_AP_MASK_DEKU, + /* 0x52 */ PLAYER_AP_LENS, + /* 0xFD */ PLAYER_AP_MAX = 0xFD +} PlayerActionParam; typedef struct { /* 0x00 */ f32 unk_00; @@ -163,7 +252,7 @@ typedef struct Player { /* 0x32A */ Vec3s morphTable[5]; /* 0x348 */ s16 eyeTexId; /* 0x34A */ s16 eyeAnimTimer; - /* 0x34C */ Actor* leftHandActor; + /* 0x34C */ Actor* heldActor; /* 0x350 */ PosRot leftHandWorld; /* 0x364 */ Actor* rightHandActor; /* 0x368 */ PosRot rightHandWorld; @@ -172,12 +261,12 @@ typedef struct Player { /* 0x37E */ s8 doorTimer; /* 0x37F */ s8 doorNext; // used with spiral staircase /* 0x380 */ Actor* doorActor; - /* 0x384 */ s16 unk_384; - /* 0x386 */ u16 unk_386; - /* 0x388 */ Actor* unk_388; - /* 0x38C */ s16 unk_38C; + /* 0x384 */ s16 getItemId; + /* 0x386 */ u16 getItemDirection; + /* 0x388 */ Actor* interactRangeActor; + /* 0x38C */ s8 mountSide; /* 0x390 */ Actor* rideActor; - /* 0x394 */ u8 unk_394; + /* 0x394 */ u8 csMode; /* 0x395 */ u8 unk_395; /* 0x396 */ u8 unk_396; /* 0x397 */ u8 unk_397; @@ -200,7 +289,8 @@ typedef struct Player { /* 0x664 */ ColliderQuad shieldQuad; /* 0x6E4 */ ColliderCylinder shieldCylinder; /* 0x730 */ Actor* unk_730; - /* 0x734 */ char unk_734[8]; + /* 0x734 */ char unk_734[4]; + /* 0x738 */ s32 unk_738; /* 0x73C */ s32 blureEffectIndex[3]; /* 0x748 */ char unk_748[0x320]; /* 0xA68 */ PlayerAgeProperties* ageProperties; // repurposed as "transformation properties"? @@ -212,7 +302,7 @@ typedef struct Player { /* 0xA80 */ Actor* tatlActor; /* 0xA84 */ s16 tatlTextId; /* 0xA86 */ s8 unk_A86; - /* 0xA87 */ s8 unk_A87; + /* 0xA87 */ s8 exchangeItemId; /* 0xA88 */ Actor* targetActor; /* 0xA8C */ f32 targetActorDistance; /* 0xA90 */ Actor* unk_A90; @@ -251,7 +341,7 @@ typedef struct Player { /* 0xAEC */ f32 unk_AEC; /* 0xAF0 */ Vec3f unk_AF0[2]; /* 0xB08 */ f32 unk_B08[8]; - /* 0xB28 */ s16 unk_B28; + /* 0xB28 */ s16 unk_B28; //Burning stick timer? /* 0xB2A */ s8 unk_B2A; /* 0xB2B */ s8 unk_B2B; /* 0xB2C */ f32 windSpeed; diff --git a/include/z64save.h b/include/z64save.h index a1ec72ab9..260701473 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -1,200 +1,312 @@ -#ifndef _Z64SAVE_H_ -#define _Z64SAVE_H_ +#ifndef Z64SAVE_H +#define Z64SAVE_H #include "ultra64.h" #include "z64math.h" #include "os.h" -typedef struct { - /* 0x00 */ u8 buttonItems[4][4]; - /* 0x10 */ u8 cButtonSlots[4][4]; - /* 0x20 */ u16 equipment; -} ItemEquips; // size = 0x0A +struct GameState; +struct GlobalContext; +struct FileChooseContext; -typedef struct { - /* 0x00 */ u8 items[24]; - /* 0x18 */ u8 masks[24]; - /* 0x30 */ s8 ammo[24]; - /* 0x48 */ u32 upgrades; // some bits are wallet upgrades - /* 0x4C */ u32 questItems; - /* 0x50 */ u8 dungeonItems[10]; - /* 0x5A */ s8 dungeonKeys[10]; - /* 0x64 */ s8 strayFairies[10]; // "orange_fairy" - /* 0x6E */ u8 unk_6E[8][3]; // "degnuts_memory_name" +// TODO: properly name DOWN, RETURN and TOP +typedef enum RespawnMode { + /* 0 */ RESTART_MODE_DOWN, // "RESTART_MODE_DOWN" + /* 1 */ RESTART_MODE_RETURN, // "RESTART_MODE_RETURN" + /* 2 */ RESTART_MODE_TOP, // "RESTART_MODE_TOP" + /* 3 */ RESPAWN_MODE_UNK_3, // Maybe related to grottos + /* 4 */ RESPAWN_MODE_GORON, // "RESTART_MODE_GORON" + /* 5 */ RESPAWN_MODE_ZORA, // "RESTART_MODE_ZORA" + /* 6 */ RESPAWN_MODE_DEKU, // "RESTART_MODE_NUTS" + /* 7 */ RESPAWN_MODE_HUMAN, // "RESTART_MODE_CHILD" + /* 8 */ RESPAWN_MODE_MAX +} RespawnMode; + +#define SAVE_BUFFER_SIZE 0x4000 + +typedef struct SramContext { + /* 0x00 */ u8* readBuff; + /* 0x04 */ u8 *saveBuf; + /* 0x08 */ char unk_08[4]; + /* 0x0C */ s16 status; + /* 0x10 */ u32 curPage; + /* 0x14 */ u32 numPages; + /* 0x18 */ OSTime unk_18; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; + /* 0x24 */ s16 unk_24; +} SramContext; // size = 0x28 + +typedef struct ItemEquips { + /* 0x00 */ u8 buttonItems[4][4]; // "register_item" + /* 0x10 */ u8 cButtonSlots[4][4]; // "register_item_pt" + /* 0x20 */ u16 equipment; +} ItemEquips; // size = 0x22 + +typedef struct Inventory { + /* 0x00 */ u8 items[48]; // "item_register", first 24 elements are normal items and the other 24 are masks + /* 0x30 */ s8 ammo[24]; // "item_count" + /* 0x48 */ u32 upgrades; // "non_equip_register" some bits are wallet upgrades + /* 0x4C */ u32 questItems; // "collect_register" + /* 0x50 */ u8 dungeonItems[10]; // "key_compass_map" + /* 0x5A */ s8 dungeonKeys[10]; // "key_register" + /* 0x64 */ s8 strayFairies[10]; // "orange_fairy" + /* 0x6E */ char dekuPlaygroundPlayerName[3][8]; // "degnuts_memory_name" Stores playerName (8 char) over (3 days) when getting a new high score } Inventory; // size = 0x88 -typedef struct { - /* 0x00 */ s16 scene; - /* 0x02 */ Vec3s pos; - /* 0x08 */ s16 angle; +typedef struct HorseData { + /* 0x00 */ s16 scene; // "spot_no" + /* 0x02 */ Vec3s pos; // "horse_x", "horse_y" and "horse_z" + /* 0x08 */ s16 yaw; // "horse_a" } HorseData; // size = 0x0A -typedef struct { - /* 0x0 */ Vec3f pos; - /* 0xC */ s16 yaw; - /* 0xE */ s16 playerParams; +typedef struct RespawnData { + /* 0x00 */ Vec3f pos; + /* 0x0C */ s16 yaw; + /* 0x0E */ s16 playerParams; /* 0x10 */ u16 entranceIndex; /* 0x12 */ u8 roomIndex; /* 0x13 */ s8 data; - /* 0x14 */ u32 tempSwchFlags; + /* 0x14 */ u32 tempSwitchFlags; /* 0x18 */ u32 unk_18; /* 0x1C */ u32 tempCollectFlags; } RespawnData; // size = 0x20 -typedef struct { - /* 0x0000 */ u32 entranceIndex; // "scene_no" - /* 0x0004 */ u8 equippedMask; // "player_mask" - /* 0x0005 */ u8 unk_05; // "opening_flag" +typedef struct PermanentSceneFlags { + /* 0x00 */ u32 chest; + /* 0x04 */ u32 switch0; + /* 0x08 */ u32 switch1; + /* 0x0C */ u32 clearedRoom; + /* 0x10 */ u32 collectible; + /* 0x14 */ u32 unk_14; + /* 0x18 */ u32 unk_18; +} PermanentSceneFlags; // size = 0x1C + +typedef struct CycleSceneFlags { + /* 0x00 */ u32 chest; + /* 0x04 */ u32 switch0; + /* 0x08 */ u32 switch1; + /* 0x0C */ u32 clearedRoom; + /* 0x10 */ u32 collectible; +} CycleSceneFlags; // size = 0x14 + +typedef struct SaveOptions { + /* 0x00 */ u16 optionId; // "option_id" + /* 0x02 */ u8 language; // "j_n" + /* 0x03 */ s8 audioSetting; // "s_sound" + /* 0x04 */ u8 languageSetting; // "language" + /* 0x05 */ u8 zTargetSetting; // "z_attention", 0: Switch; 1: Hold +} SaveOptions; // size = 0x06 + +typedef struct SavePlayerData { + /* 0x0000 */ char newf[6]; // "newf" Will always be "ZELDA3 for a valid save + /* 0x0006 */ u16 deaths; // "savect" + /* 0x0008 */ char playerName[8]; // "player_name" + /* 0x0010 */ s16 healthCapacity; // "max_life" + /* 0x0012 */ s16 health; // "now_life" + /* 0x0014 */ s8 magicLevel; // "magic_max" + /* 0x0015 */ s8 magic; // "magic_now" + /* 0x0016 */ s16 rupees; // "lupy_count" + /* 0x0018 */ u16 swordHealth; // "long_sword_hp" + /* 0x001A */ u16 tatlTimer; // "navi_timer" + /* 0x001C */ u8 magicAcquired; // "magic_mode" + /* 0x001D */ u8 doubleMagic; // "magic_ability" + /* 0x001E */ u8 doubleDefense; // "life_ability" + /* 0x001F */ u8 unk_1F; // "ocarina_round" + /* 0x0020 */ u8 unk_20; // "first_memory" + /* 0x0022 */ u16 owlActivationFlags; // "memory_warp_point" + /* 0x0024 */ u8 unk_24; // "last_warp_pt" + /* 0x0026 */ s16 savedSceneNum; // "scene_data_ID" +} SavePlayerData; // size = 0x28 + +typedef struct Save { + /* 0x0000 */ u32 entranceIndex; // "scene_no" + /* 0x0004 */ u8 equippedMask; // "player_mask" + /* 0x0005 */ u8 isFirstCycle; // "opening_flag" /* 0x0006 */ u8 unk_06; - /* 0x0007 */ u8 linkAge; // "link_age" - /* 0x0008 */ s32 cutscene; // "day_time" - /* 0x000C */ u16 time; // "zelda_time" + /* 0x0007 */ u8 linkAge; // "link_age" + /* 0x0008 */ s32 cutscene; // "day_time" + /* 0x000C */ u16 time; // "zelda_time" /* 0x000E */ u16 owlSaveLocation; - /* 0x0010 */ s32 isNight; // "asahiru_fg" - /* 0x0014 */ u32 unk_14; // "change_zelda_time" - /* 0x0018 */ s32 day; // "totalday" - /* 0x001C */ u32 daysElapsed; // "eventday" - /* 0x0020 */ u8 playerForm; // "player_character" - /* 0x0021 */ u8 snowheadCleared; // "spring_flag" - /* 0x0022 */ u8 hasTatl; // "bell_flag" + /* 0x0010 */ s32 isNight; // "asahiru_fg" + /* 0x0014 */ s32 daySpeed; // "change_zelda_time" + /* 0x0018 */ s32 day; // "totalday" + /* 0x001C */ s32 daysElapsed; // "eventday" + /* 0x0020 */ u8 playerForm; // "player_character" + /* 0x0021 */ u8 snowheadCleared; // "spring_flag" + /* 0x0022 */ u8 hasTatl; // "bell_flag" /* 0x0023 */ u8 isOwlSave; - /* 0x0024 */ char newf[6]; // Will always be "ZELDA3" for a valid save - /* 0x002B */ u16 deaths; // "savect" - /* 0x002C */ char playerName[8]; // "player_name" - /* 0x0034 */ s16 healthCapacity; // "max_life" - /* 0x0036 */ s16 health; // "now_life" - /* 0x0038 */ s8 magicLevel; // "magic_max" - /* 0x0039 */ s8 magic; // "magic_now" - /* 0x003A */ s16 rupees; // "lupy_count" - /* 0x003C */ u16 swordHealth; // "long_sword_hp" - /* 0x003E */ u16 naviTimer; // "navi_timer" - /* 0x0040 */ u8 magicAcquired; // "magic_mode" - /* 0x0041 */ u8 doubleMagic; // "magic_ability" - /* 0x0042 */ u8 doubleDefense; // "life_ability" - /* 0x0043 */ u8 unk_43; // "ocarina_round" - /* 0x0044 */ u8 unk_44; // "first_memory" - /* 0x0046 */ u16 owlActivationFlags; // "memory_warp_point" - /* 0x0048 */ u8 unk_48; // "last_warp_pt" - /* 0x004A */ s16 savedSceneNum; // "scene_data_ID" + /* 0x0024 */ SavePlayerData playerData; /* 0x004C */ ItemEquips equips; /* 0x0070 */ Inventory inventory; - /* 0x00F8 */ u32 roomInf[128][7]; - /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" - /* 0x0F5C */ u32 mapsVisited; // "area_arrival" - /* 0x0F60 */ u32 unk_F60; // "cloud_clear" - /* 0x0F64 */ u8 unk_F64; // "oca_rec_flag" - /* 0x0F65 */ u8 unk_F65; // "oca_rec_flag8" - /* 0x0F66 */ u8 unk_F66[128]; // "oca_rec_buff8" - /* 0x0FE6 */ s8 unk_FE6; // "aikotoba_index" - /* 0x0FE7 */ s8 unk_FE7[5]; // "aikotoba_table" - /* 0x0FEC */ s8 lotteryCodes[3][3]; // "numbers_table" - /* 0x0FF5 */ s8 spiderHouseMaskOrder[6]; // "kinsta_color_table" - /* 0x0FFB */ s8 bomberCode[5]; // "bombers_aikotoba_table" + /* 0x00F8 */ PermanentSceneFlags permanentSceneFlags[120]; + /* 0x0E18 */ u8 unk_E18[0x54]; + /* 0x0E6C */ u32 dekuPlaygroundHighScores[3]; + /* 0x0E78 */ u32 pictoFlags0; + /* 0x0E7C */ u32 pictoFlags1; + /* 0x0E80 */ u32 unk_E80; + /* 0x0E84 */ u32 unk_E84; + /* 0x0E88 */ u32 unk_E88[7]; // Invadepoh flags + /* 0x0EA4 */ u32 scenesVisible[7]; // tingle maps and clouded regions on pause map. Stores scenes bitwise for up to 224 scenes even though there are not that many scenes + /* 0x0EC0 */ u32 skullTokenCount; // upper 16 bits store Swamp skulls, lower 16 bits store Ocean skulls + /* 0x0EC4 */ u32 unk_EC4; // Gossic stone heart piece flags + /* 0x0EC8 */ u32 unk_EC8; + /* 0x0ECC */ u32 unk_ECC[2]; // Related to blue warps + /* 0x0ED4 */ u32 stolenItems; // Items stolen by Takkuri and given to Curiosity Shop Man + /* 0x0ED8 */ u32 unk_DD8; + /* 0x0EDC */ u32 bankRupees; + /* 0x0EE0 */ u32 unk_EE0; + /* 0x0EE4 */ u32 unk_EE4; // Fishing flags + /* 0x0EE8 */ u32 unk_EE8; + /* 0x0EEC */ u32 horseBackBalloonHighScore; + /* 0x0EF0 */ u32 lotteryCodeGuess; // Lottery code chosen by player (only uses lower three hex digits) + /* 0x0EF4 */ u32 unk_EF4; // Shooting Gallery Man Flags + /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" + /* 0x0F5C */ u32 mapsVisited; // "area_arrival" + /* 0x0F60 */ u32 mapsVisible; // "cloud_clear" + /* 0x0F64 */ u8 unk_F64; // "oca_rec_flag" has scarecrows song + /* 0x0F65 */ u8 unk_F65; // "oca_rec_flag8" scarecrows song set? + /* 0x0F66 */ u8 scarecrowsSong[128]; + /* 0x0FE6 */ s8 bombersCaughtNum; // "aikotoba_index" + /* 0x0FE7 */ s8 bombersCaughtOrder[5]; // "aikotoba_table" + /* 0x0FEC */ s8 lotteryCodes[3][3]; // "numbers_table", Preset lottery codes + /* 0x0FF5 */ s8 spiderHouseMaskOrder[6]; // "kinsta_color_table" + /* 0x0FFB */ s8 bomberCode[5]; // "bombers_aikotoba_table" /* 0x1000 */ HorseData horseData; - /* 0x100A */ u16 checksum; // "check_sum" - /* 0x100C */ u8 eventInf[8]; - /* 0x1014 */ u8 unk_1014; // "stone_set_flag" + /* 0x100A */ u16 checksum; // "check_sum" +} Save; // size = 0x100C + +typedef struct SaveContext { + /* 0x0000 */ Save save; + /* 0x100C */ u8 eventInf[8]; // "event_inf" + /* 0x1014 */ u8 unk_1014; // "stone_set_flag" /* 0x1015 */ u8 unk_1015; - /* 0x1016 */ u16 unk_1016; - /* 0x1018 */ s16 rupeeAccumulator; // "lupy_udct" - /* 0x101A */ u8 unk_101A[6]; // "bottle_status", one entry for each bottle - /* 0x1020 */ OSTime unk_1020[6]; // "bottle_ostime", one entry for each bottle - /* 0x1050 */ OSTime unk_1050[6]; // "bottle_sub", one entry for each bottle - /* 0x1080 */ OSTime unk_1080[6]; // "bottle_time", one entry for each bottle - /* 0x10B0 */ OSTime unk_10B0[6]; // "bottle_stop_time", one entry for each bottle - /* 0x10E0 */ u64 pictoPhoto[1400]; // buffer containing the pictograph photo - /* 0x3CA0 */ s32 fileNum; // "file_no" - /* 0x3CA4 */ s16 powderKegTimer; // "big_bom_timer" + /* 0x1016 */ u16 jinxTimer; + /* 0x1018 */ s16 rupeeAccumulator; // "lupy_udct" + /* 0x101A */ u8 unk_101A[6]; // "bottle_status", one entry for each bottle + /* 0x1020 */ OSTime unk_1020[6]; // "bottle_ostime", one entry for each bottle + /* 0x1050 */ OSTime unk_1050[6]; // "bottle_sub", one entry for each bottle + /* 0x1080 */ OSTime unk_1080[6]; // "bottle_time", one entry for each bottle + /* 0x10B0 */ OSTime unk_10B0[6]; // "bottle_stop_time", one entry for each bottle + /* 0x10E0 */ u64 pictoPhoto[1400]; // buffer containing the pictograph photo + /* 0x3CA0 */ s32 fileNum; // "file_no" + /* 0x3CA4 */ s16 powderKegTimer; // "big_bom_timer" /* 0x3CA6 */ u8 unk_3CA6; - /* 0x3CA7 */ u8 unk_3CA7; // "day_night_flag" - /* 0x3CA8 */ s32 gameMode; // "mode" - /* 0x3CAC */ s32 sceneSetupIndex; // "counter" - /* 0x3CB0 */ s32 respawnFlag; // "restart_flag" - /* 0x3CB4 */ RespawnData respawn[8]; // "restart_data" - /* 0x3DB4 */ f32 entranceSpeed; // "player_wipe_speedF" - /* 0x3DB8 */ u16 entranceSound; // "player_wipe_door_SE" - /* 0x3DBA */ u8 unk_3DBA; // "player_wipe_item" - /* 0x3DBB */ u8 unk_3DBB; // "next_walk" - /* 0x3DBC */ u16 dogParams; // "dog_flag" - /* 0x3DBE */ u8 textTriggerFlags; // "guide_status" - /* 0x3DBF */ u8 showTitleCard; // "name_display" - /* 0x3DC0 */ s16 unk_3DC0; // "shield_magic_timer" - /* 0x3DC2 */ u8 unk_3DC2; // "pad1" - /* 0x3DC8 */ OSTime unk_3DC8; // "get_time" - /* 0x3DD0 */ u8 unk_3DD0[7]; // "event_fg" - /* 0x3DD7 */ u8 unk_3DD7[7]; // "calc_flag" - /* 0x3DE0 */ OSTime unk_3DE0[7]; // "event_ostime" - /* 0x3E18 */ OSTime unk_3E18[7]; // "event_sub" - /* 0x3E50 */ OSTime unk_3E50[7]; // "func_time" - /* 0x3E88 */ OSTime unk_3E88[7]; // "func_end_time" - /* 0x3EC0 */ OSTime unk_3EC0[7]; // "func_stop_time" - /* 0x3EF8 */ s16 timerX[7]; // "event_xp" - /* 0x3F06 */ s16 timerY[7]; // "event_yp" - /* 0x3F14 */ s16 unk_3F14; // "character_change" - /* 0x3F16 */ u8 seqIndex; // "old_bgm" - /* 0x3F17 */ u8 nightSeqIndex; // "old_env" - /* 0x3F18 */ u8 buttonStatus[6]; // "button_item" - /* 0x3F1E */ u8 unk_3F1E; // "ck_fg" - /* 0x3F20 */ u16 unk_3F20; // "alpha_type" - /* 0x3F22 */ u16 unk_3F22; // "prev_alpha_type" - /* 0x3F24 */ u16 unk_3F24; // "alpha_count" - /* 0x3F26 */ u16 unk_3F26; // "last_time_type" - /* 0x3F28 */ s16 unk_3F28; // "magic_flag" - /* 0x3F2A */ s16 unk_3F2A; // "recovery_magic_flag" - /* 0x3F2C */ s16 unk_3F2C; // "keep_magic_flag" - /* 0x3F2E */ s16 unk_3F2E; // "magic_now_max" - /* 0x3F30 */ s16 unk_3F30; // "magic_now_now" - /* 0x3F32 */ s16 unk_3F32; // "magic_used" - /* 0x3F34 */ s16 unk_3F34; // "magic_recovery" - /* 0x3F36 */ u16 mapIndex; // "scene_ID" - /* 0x3F38 */ u16 minigameState; // "yabusame_mode" - /* 0x3F3A */ u16 minigameScore; // "yabusame_total" - /* 0x3F3C */ u16 unk_3F3C; // "yabusame_out_ct" - /* 0x3F3E */ u8 unk_3F3E; // "no_save" - /* 0x3F3F */ u8 unk_3F3F; // "flash_flag" - /* 0x3F40 */ u16 option_id; // "option_id" - /* 0x3F42 */ u8 language; // "j_n" - /* 0x3F43 */ u8 audioSetting; // "s_sound" - /* 0x3F44 */ u8 unk_3F44; // "language" - /* 0x3F45 */ u8 zTargetSetting; // 0: Switch; 1: Hold - /* 0x3F46 */ u16 unk_3F46; // "NottoriBgm" - /* 0x3F48 */ u8 unk_3F48; // "fade_go" - /* 0x3F4A */ u16 nextCutsceneIndex; // "next_daytime" - /* 0x3F4C */ u8 cutsceneTrigger; // "doukidemo" - /* 0x3F4D */ u8 unk_3F4D; // "Kenjya_no" - /* 0x3F4E */ u16 nextDayTime; // "next_zelda_time" - /* 0x3F50 */ u8 fadeDuration; // "fade_speed" - /* 0x3F51 */ u8 unk_3F51; // "wipe_speed" - /* 0x3F52 */ u16 environmentTime; // "kankyo_time" - /* 0x3F54 */ u8 dogIsLost; // "dog_event_flag" - /* 0x3F55 */ u8 nextTransition; // "next_wipe" - /* 0x3F56 */ s16 worldMapArea; // "area_type" - /* 0x3F58 */ s16 unk_3F58; // "sunmoon_flag" - /* 0x3F5A */ s16 healthAccumulator; // "life_mode" - /* 0x3F5C */ s32 unk_3F5C; // "bet_rupees" - /* 0x3F60 */ u8 unk_3F60; // "framescale_flag" - /* 0x3F64 */ f32 unk_3F64; // "framescale_scale" - /* 0x3F68 */ u32 unk_3F68[5][120]; - /* 0x48C8 */ u16 unk_48C8; // "scene_id_mix" - /* 0x48CA */ u8 maskMaskBit[3]; // masks given away on the Moon - /* 0x48CD */ char unk_48CD[24]; + /* 0x3CA7 */ u8 unk_3CA7; // "day_night_flag" + /* 0x3CA8 */ s32 gameMode; // "mode" + /* 0x3CAC */ s32 sceneSetupIndex; // "counter" + /* 0x3CB0 */ s32 respawnFlag; // "restart_flag" + /* 0x3CB4 */ RespawnData respawn[RESPAWN_MODE_MAX]; // "restart_data" + /* 0x3DB4 */ f32 entranceSpeed; // "player_wipe_speedF" + /* 0x3DB8 */ u16 entranceSound; // "player_wipe_door_SE" + /* 0x3DBA */ u8 unk_3DBA; // "player_wipe_item" + /* 0x3DBB */ u8 unk_3DBB; // "next_walk" + /* 0x3DBC */ u16 dogParams; // "dog_flag" + /* 0x3DBE */ u8 textTriggerFlags; // "guide_status" + /* 0x3DBF */ u8 showTitleCard; // "name_display" + /* 0x3DC0 */ s16 unk_3DC0; // "shield_magic_timer" + /* 0x3DC2 */ u8 unk_3DC2; // "pad1" + /* 0x3DC8 */ OSTime unk_3DC8; // "get_time" + /* 0x3DD0 */ u8 unk_3DD0[7]; // "event_fg" + /* 0x3DD7 */ u8 unk_3DD7[7]; // "calc_flag" + /* 0x3DE0 */ OSTime unk_3DE0[7]; // "event_ostime" + /* 0x3E18 */ OSTime unk_3E18[7]; // "event_sub" + /* 0x3E50 */ OSTime unk_3E50[7]; // "func_time" + /* 0x3E88 */ OSTime unk_3E88[7]; // "func_end_time" + /* 0x3EC0 */ OSTime unk_3EC0[7]; // "func_stop_time" + /* 0x3EF8 */ s16 timerX[7]; // "event_xp" + /* 0x3F06 */ s16 timerY[7]; // "event_yp" + /* 0x3F14 */ s16 unk_3F14; // "character_change" + /* 0x3F16 */ u8 seqIndex; // "old_bgm" + /* 0x3F17 */ u8 nightSeqIndex; // "old_env" + /* 0x3F18 */ u8 buttonStatus[6]; // "button_item" + /* 0x3F1E */ u8 unk_3F1E; // "ck_fg" + /* 0x3F20 */ u16 unk_3F20; // "alpha_type" + /* 0x3F22 */ u16 unk_3F22; // "prev_alpha_type" + /* 0x3F24 */ u16 unk_3F24; // "alpha_count" + /* 0x3F26 */ u16 unk_3F26; // "last_time_type" + /* 0x3F28 */ s16 unk_3F28; // "magic_flag" + /* 0x3F2A */ s16 unk_3F2A; // "recovery_magic_flag" + /* 0x3F2C */ s16 unk_3F2C; // "keep_magic_flag" + /* 0x3F2E */ s16 unk_3F2E; // "magic_now_max" + /* 0x3F30 */ s16 unk_3F30; // "magic_now_now" + /* 0x3F32 */ s16 unk_3F32; // "magic_used" + /* 0x3F34 */ s16 unk_3F34; // "magic_recovery" + /* 0x3F36 */ u16 mapIndex; // "scene_ID" + /* 0x3F38 */ u16 minigameState; // "yabusame_mode" + /* 0x3F3A */ u16 minigameScore; // "yabusame_total" + /* 0x3F3C */ u16 unk_3F3C; // "yabusame_out_ct" + /* 0x3F3E */ u8 unk_3F3E; // "no_save" + /* 0x3F3F */ u8 unk_3F3F; // "flash_flag" + /* 0x3F40 */ SaveOptions options; + /* 0x3F46 */ u16 unk_3F46; // "NottoriBgm" + /* 0x3F48 */ u8 unk_3F48; // "fade_go" + /* 0x3F4A */ u16 nextCutsceneIndex; // "next_daytime" + /* 0x3F4C */ u8 cutsceneTrigger; // "doukidemo" + /* 0x3F4D */ u8 unk_3F4D; // "Kenjya_no" + /* 0x3F4E */ u16 nextDayTime; // "next_zelda_time" + /* 0x3F50 */ u8 fadeDuration; // "fade_speed" + /* 0x3F51 */ u8 fadeSpeed; // "wipe_speed" transition related + /* 0x3F52 */ u16 environmentTime; // "kankyo_time" + /* 0x3F54 */ u8 dogIsLost; // "dog_event_flag" + /* 0x3F55 */ u8 nextTransition; // "next_wipe" + /* 0x3F56 */ s16 worldMapArea; // "area_type" + /* 0x3F58 */ s16 sunsSongState; // "sunmoon_flag" + /* 0x3F5A */ s16 healthAccumulator; // "life_mode" + /* 0x3F5C */ s32 unk_3F5C; // "bet_rupees" + /* 0x3F60 */ u8 screenScaleFlag; // "framescale_flag" + /* 0x3F64 */ f32 screenScale; // "framescale_scale" + /* 0x3F68 */ CycleSceneFlags cycleSceneFlags[120]; // Scene flags that are temporarily stored over the duration of a single 3-day cycle + /* 0x48C8 */ u16 unk_48C8; // "scene_id_mix" + /* 0x48CA */ u8 maskMaskBit[27]; // "mask_mask_bit", masks given away on the Moon } SaveContext; // size = 0x48C8 -typedef enum { - /* 0x00 */ RESPAWN_MODE_VOID_OUT, - /* 0x01 */ RESPAWN_MODE_GROTTO, // Exiting a grotto - /* 0x02 */ RESPAWN_MODE_FARORES_WIND, // Unused in MM - /* 0x03 */ RESPAWN_MODE_GORON, - /* 0x04 */ RESPAWN_MODE_ZORA, - /* 0x05 */ RESPAWN_MODE_DEKU, - /* 0x06 */ RESPAWN_MODE_CHILD_LINK, - /* 0x07 */ RESPAWN_MODE_UNK_7, - /* 0x07 */ RESPAWN_MODE_UNK_8 -} RespawnMode; - -typedef enum { +typedef enum ButtonStatus { /* 0x00 */ BTN_ENABLED, /* 0xFF */ BTN_DISABLED = 0xFF } ButtonStatus; +typedef enum SunsSongState { + /* 0 */ SUNSSONG_INACTIVE, + /* 1 */ SUNSSONG_START, // the suns ocarina effect signals that the song has finished playing + /* 2 */ SUNSSONG_SPEED_TIME, // suns was played where time passes, speed up the advancement of time + /* 3 */ SUNSSONG_SPECIAL // time does not advance, but signals the song was played. used for freezing redeads +} SunsSongState; + +void Sram_ActivateOwl(u8 owlId); +void Sram_ClearFlagsAtDawnOfTheFirstDay(void); +void Sram_SaveEndOfCycle(struct GlobalContext* globalCtx); +void Sram_IncrementDay(void); +u16 Sram_CalcChecksum(void* data, size_t count); +void Sram_InitNewSave(void); +void Sram_InitDebugSave(void); +void func_80144A94(SramContext* sramCtx); +void Sram_OpenSave(struct FileChooseContext* fileChooseCtx, SramContext* sramCtx); +void func_8014546C(SramContext* sramCtx); +void func_801457CC(struct FileChooseContext* fileChooseCtx, SramContext* sramCtx); +void func_80146580(struct FileChooseContext* fileChooseCtx, SramContext* sramCtx, s32 fileNum); +void func_80146628(struct FileChooseContext* fileChooseCtx, SramContext* sramCtx); +void Sram_InitSave(struct FileChooseContext* fileChooseCtx, SramContext* sramCtx); +void func_80146DF8(SramContext* sramCtx); +void Sram_InitSram(struct GameState* gameState, SramContext* sramCtx); +void Sram_Alloc(struct GameState* gamestate, SramContext* sramCtx); +void Sram_SaveSpecialEnterClockTown(struct GlobalContext* globalCtx); +void Sram_SaveSpecialNewDay(struct GlobalContext* globalCtx); +void func_80147008(SramContext* sramCtx, u32 curPage, u32 numPages); +void func_80147020(SramContext* sramCtx); +void func_80147068(SramContext* sramCtx); +void func_80147138(SramContext* sramCtx, s32 curPage, s32 numPages); +void func_80147150(SramContext* sramCtx); +void func_80147198(SramContext* sramCtx); + +extern s32 D_801C6798[]; +extern u8 D_801C67B0[24]; +extern s32 D_801C67C8[]; +extern s32 D_801C67E8[]; +extern s32 D_801C67F0[]; +extern s32 D_801C6818[]; +extern s32 D_801C6838[]; +extern s32 D_801C6840[]; +extern s32 D_801C6850[]; + #endif diff --git a/include/z64scene.h b/include/z64scene.h index 333569974..5a1c39e16 100644 --- a/include/z64scene.h +++ b/include/z64scene.h @@ -1,15 +1,16 @@ -#ifndef _Z64SCENE_H_ -#define _Z64SCENE_H_ +#ifndef Z64SCENE_H +#define Z64SCENE_H #include "ultra64.h" #include "z64dma.h" +#include "z64cutscene.h" #include "unk.h" #define SPAWN_ROT_FLAGS(rotation, flags) (((rotation) << 7) | (flags)) typedef struct { - /* 0x00 */ u32 vromStart; - /* 0x04 */ u32 vromEnd; + /* 0x00 */ uintptr_t vromStart; + /* 0x04 */ uintptr_t vromEnd; } RomFile; // size = 0x8 typedef struct { @@ -290,12 +291,12 @@ typedef struct { typedef struct { struct { s8 room; // Room to switch to - s8 effects; // How the camera reacts during the transition + s8 bgCamDataId; // How the camera reacts during the transition. -2 for spiral staircase. -1 for generic door. 0+ will index scene CamData } /* 0x00 */ sides[2]; // 0 = front, 1 = back /* 0x04 */ s16 id; /* 0x06 */ Vec3s pos; /* 0x0C */ s16 rotY; - /* 0x0E */ s16 params; + /* 0x0E */ u16 params; } TransitionActorEntry; // size = 0x10 typedef struct { @@ -310,13 +311,6 @@ typedef struct { /* 0xE */ s16 params; } ActorEntry; // size = 0x10 -typedef struct { - /* 0x0 */ u32 data; - /* 0x4 */ s16 unk4; - /* 0x6 */ u8 unk6; - /* 0x7 */ u8 unk7; -} CutsceneEntry; // size = 0x8 - typedef struct { /* 0x0 */ u8 spawn; /* 0x1 */ u8 room; @@ -496,10 +490,12 @@ typedef struct { } MinimapChest; // size = 0xA typedef struct { - /* 0x00 */ s16 type; - /* 0x00 */ s16 numPoints; - /* 0x00 */ Vec3s* points; -} CsCameraEntry; + /* 0x0 */ s16 setting; + /* 0x2 */ s16 numData; + /* 0x4 */ Vec3s* data; +} CsCamData; // size = 0x8 + +typedef CsCamData CsCameraEntry; // TODO: Remove once ZAPD updates its structs typedef union { /* Command: N/A */ SCmdBase base; @@ -649,7 +645,8 @@ typedef enum { /* 0x6D */ SCENE_ICHIBA, /* 0x6E */ SCENE_BACKTOWN, /* 0x6F */ SCENE_CLOCKTOWER, - /* 0x70 */ SCENE_ALLEY + /* 0x70 */ SCENE_ALLEY, + /* 0x71 */ SCENE_MAX } SceneID; // SceneTableEntry draw configs diff --git a/include/z64schedule.h b/include/z64schedule.h new file mode 100644 index 000000000..f5dfb2be8 --- /dev/null +++ b/include/z64schedule.h @@ -0,0 +1,248 @@ +#ifndef Z64SCHEDULE_H +#define Z64SCHEDULE_H + +#include "ultra64.h" + +/* + Schedule is a subsystem that acts as a way to make decisions based on the + time and scene (and a limited selection of items). It is utilized by writing + a script that is encoded into bytecode and ran, returning the result in a + struct. The returned result can be a value or a encoded time value. + + The scripts contain 2 kinds of instructions: + - Checks with branches (relative offsets, either 1-byte offsets (short, *_S), + or 2-byte offsets (long, *_L)) + - Returns + + Scripts are stored as u8[]. They are built using the macros are the bottom of + this file. The scheduledis.py script can be used to convert any scripts in + actor data into the macros. +*/ + +// Macro to convert the time format used in the save struct into the format used in Schedule +#define SCHEDULE_CONVERT_TIME(time) ((time) - 0x10000 / 360 * 90) +#define SCHEDULE_TIME_NOW SCHEDULE_CONVERT_TIME(gSaveContext.save.time) + +typedef enum { + /* 00 */ SCHEDULE_CMD_ID_CHECK_FLAG_S, // Checks if a weekEventReg flag is set and branches if so, short range branch + /* 01 */ SCHEDULE_CMD_ID_CHECK_FLAG_L, // Checks if a weekEventReg flag is set and branches if so, long range branch + /* 02 */ SCHEDULE_CMD_ID_CHECK_TIME_RANGE_S, // Checks if the current time is within the range of the two provided times and branches if so, short range branch + /* 03 */ SCHEDULE_CMD_ID_CHECK_TIME_RANGE_L, // Checks if the current time is within the range of the two provided times and branches if so, long range branch + /* 04 */ SCHEDULE_CMD_ID_RET_VAL_L, // Ends script and returns 2-byte value (Note: bugged as the return value size is only 1 byte in the struct) + /* 05 */ SCHEDULE_CMD_ID_RET_NONE, // Ends script without returning anything + /* 06 */ SCHEDULE_CMD_ID_RET_EMPTY, // Ends script and indicates return without changing existing value + /* 07 */ SCHEDULE_CMD_ID_NOP, // No-Op + /* 08 */ SCHEDULE_CMD_ID_CHECK_MISC_S, // Special check based on items or masks and branches if check passes, short range branch + /* 09 */ SCHEDULE_CMD_ID_RET_VAL_S, // Ends script and returns byte value + /* 10 */ SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_S, // Checks if the current scene is not SceneNum and branches if so, short range branch + /* 11 */ SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_L, // Checks if the current scene is not SceneNum and branches if so, long range branch + /* 12 */ SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_S, // Checks if the current day is not Day and branches if so, short range branch + /* 13 */ SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_L, // Checks if the current day is not Day and branches if so, long range branch + /* 14 */ SCHEDULE_CMD_ID_RET_TIME, // Returns 2 time values + /* 15 */ SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_S, // Branches if the current time is less than the command time, short range branch + /* 16 */ SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_L, // Branches if the current time is less than the command time, long range branch + /* 17 */ SCHEDULE_CMD_ID_BRANCH_S, // Always branch, short range branch + /* 18 */ SCHEDULE_CMD_ID_BRANCH_L, // Always branch, long range branch +} ScheduleCommandId; + +typedef enum { + /* 0 */ SCHEDULE_CHECK_MISC_ROOM_KEY, + /* 1 */ SCHEDULE_CHECK_MISC_LETTER_TO_KAFEI, + /* 2 */ SCHEDULE_CHECK_MISC_MASK_ROMANI, +} ScheduleCheckMisc; + +typedef struct { + /* 0x0 */ u8 result; + /* 0x4 */ s32 time0; + /* 0x8 */ s32 time1; + /* 0xC */ s32 hasResult; +} ScheduleResult; // size = 0x10 + +typedef struct { + /* 0x0 */ u8 cmd; +} ScheduleCmdBase; // size = 0x1 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 flagByte; + /* 0x2 */ u8 flagMask; + /* 0x3 */ s8 offset; +} ScheduleCmdCheckFlagS; // size = 0x4 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 flagByte; + /* 0x2 */ u8 flagMask; + /* 0x3 */ u8 offsetH; + /* 0x4 */ u8 offsetL; +} ScheduleCmdCheckFlagL; // size = 0x5 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 startHr; + /* 0x2 */ u8 startMin; + /* 0x3 */ u8 endHr; + /* 0x4 */ u8 endMin; + /* 0x5 */ s8 offset; +} ScheduleCmdCheckTimeRangeS; // size = 0x6 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 startHr; + /* 0x2 */ u8 startMin; + /* 0x3 */ u8 endHr; + /* 0x4 */ u8 endMin; + /* 0x5 */ u8 offsetH; + /* 0x6 */ u8 offsetL; +} ScheduleCmdCheckTimeRangeL; // size = 0x7 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 retH; + /* 0x2 */ u8 retL; +} ScheduleCmdReturnValueL; // size = 0x3 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 unk1; + /* 0x2 */ u8 unk2; + /* 0x3 */ u8 unk3; +} ScheduleCmdNop; // size = 0x4 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 which; + /* 0x2 */ s8 offset; +} ScheduleCmdCheckMiscS; // size = 0x3 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 result; +} ScheduleCmdReturnValueS; // size = 0x2 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 sceneH; + /* 0x2 */ u8 sceneL; + /* 0x3 */ s8 offset; +} ScheduleCmdCheckNotInSceneS; // size = 0x4 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 sceneH; + /* 0x2 */ u8 sceneL; + /* 0x3 */ u8 offsetH; + /* 0x4 */ u8 offsetL; +} ScheduleCmdCheckNotInSceneL; // size = 0x5 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 dayH; + /* 0x2 */ u8 dayL; + /* 0x3 */ s8 offset; +} ScheduleCmdCheckNotInDayS; // size = 0x4 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 dayH; + /* 0x2 */ u8 dayL; + /* 0x3 */ u8 offsetH; + /* 0x4 */ u8 offsetL; +} ScheduleCmdCheckNotInDayL; // size = 0x5 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 time0Hr; + /* 0x2 */ u8 time0Min; + /* 0x3 */ u8 time1Hr; + /* 0x4 */ u8 time1Min; + /* 0x5 */ u8 result; +} ScheduleCmdReturnTime; // size = 0x6 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 timeHr; + /* 0x2 */ u8 timeMin; + /* 0x3 */ s8 offset; +} ScheduleCmdCheckBeforeTimeS; // size = 0x4 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 timeHr; + /* 0x2 */ u8 timeMin; + /* 0x3 */ u8 offsetH; + /* 0x4 */ u8 offsetL; +} ScheduleCmdCheckBeforeTimeL; // size = 0x5 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ s8 offset; +} ScheduleCmdBranchS; // size = 0x2 + +typedef struct { + /* 0x0 */ ScheduleCmdBase base; + /* 0x1 */ u8 offsetH; + /* 0x2 */ u8 offsetL; +} ScheduleCmdBranchL; // size = 0x3 + +#define SCHEDULE_PACK_S16(val) \ + ((val) >> 8) & 0xFF, (val) & 0xFF + +#define SCHEDULE_CMD_CHECK_FLAG_S(index, mask, offset) \ + SCHEDULE_CMD_ID_CHECK_FLAG_S, (index), (mask), (offset) + +#define SCHEDULE_CMD_CHECK_FLAG_L(index, mask, offset) \ + SCHEDULE_CMD_ID_CHECK_FLAG_L, (index), (mask), SCHEDULE_PACK_S16(offset) + +#define SCHEDULE_CMD_CHECK_TIME_RANGE_S(startHr, startMin, endHr, endMin, offset) \ + SCHEDULE_CMD_ID_CHECK_TIME_RANGE_S, (startHr), (startMin), (endHr), (endMin), (offset) + +#define SCHEDULE_CMD_CHECK_TIME_RANGE_L(startHr, startMin, endHr, endMin, offset) \ + SCHEDULE_CMD_ID_CHECK_TIME_RANGE_L, (startHr), (startMin), (endHr), (endMin), SCHEDULE_PACK_S16(offset) + +#define SCHEDULE_CMD_RET_VAL_L(result) \ + SCHEDULE_CMD_ID_RET_VAL_L, SCHEDULE_PACK_S16(result) + +#define SCHEDULE_CMD_RET_NONE() \ + SCHEDULE_CMD_ID_RET_NONE + +#define SCHEDULE_CMD_RET_EMPTY() \ + SCHEDULE_CMD_ID_RET_EMPTY, + +#define SCHEDULE_CMD_NOP(unk0, unk1, unk2) \ + SCHEDULE_CMD_ID_NOP, (unk0), (unk1), (unk2) + +#define SCHEDULE_CMD_CHECK_MISC_S(which, offset) \ + SCHEDULE_CMD_ID_CHECK_MISC_S, (which), (offset) + +#define SCHEDULE_CMD_RET_VAL_S(result) \ + SCHEDULE_CMD_ID_RET_VAL_S, (result) + +#define SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(scene, offset) \ + SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_S, SCHEDULE_PACK_S16(scene), (offset) + +#define SCHEDULE_CMD_CHECK_NOT_IN_SCENE_L(scene, offset) \ + SCHEDULE_CMD_ID_CHECK_NOT_IN_SCENE_L, SCHEDULE_PACK_S16(scene), SCHEDULE_PACK_S16(offset) + +#define SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(day, offset) \ + SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_S, SCHEDULE_PACK_S16(day), (offset) + +#define SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(day, offset) \ + SCHEDULE_CMD_ID_CHECK_NOT_IN_DAY_L, SCHEDULE_PACK_S16(day), SCHEDULE_PACK_S16(offset) + +#define SCHEDULE_CMD_RET_TIME(time0Hr, time0Min, time1Hr, time1Min, result) \ + SCHEDULE_CMD_ID_RET_TIME, (time0Hr), (time0Min), (time1Hr), (time1Min), (result) + +#define SCHEDULE_CMD_CHECK_BEFORE_TIME_S(timeHr, timeMin, offset) \ + SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_S, (timeHr), (timeMin), (offset) + +#define SCHEDULE_CMD_CHECK_BEFORE_TIME_L(timeHr, timeMin, offset) \ + SCHEDULE_CMD_ID_CHECK_BEFORE_TIME_L, (timeHr), (timeMin), SCHEDULE_PACK_S16(offset) + +#define SCHEDULE_CMD_BRANCH_S(offset) \ + SCHEDULE_CMD_ID_BRANCH_S, (offset) + +#define SCHEDULE_CMD_BRANCH_L(offset) \ + SCHEDULE_CMD_ID_BRANCH_L, SCHEDULE_PACK_S16(offset) + +#endif diff --git a/include/z64skin.h b/include/z64skin.h new file mode 100644 index 000000000..adb2f9b0f --- /dev/null +++ b/include/z64skin.h @@ -0,0 +1,106 @@ +#ifndef Z64_SKIN_H +#define Z64_SKIN_H + +#include "z64animation.h" + +struct GraphicsContext; +struct GameState; +struct GlobalContext; + +/** + * Holds a compact version of a vertex used in the Skin system (doesn't has the x, y, z positions or the flag member) + * It is used to initialise the Vtx used by an animated limb + */ +typedef struct { + /* 0x0 */ u16 index; + /* 0x2 */ s16 s; // s and t are texture coordinates (also known as u and v) + /* 0x4 */ s16 t; + /* 0x6 */ s8 normX; + /* 0x7 */ s8 normY; + /* 0x8 */ s8 normZ; + /* 0x9 */ u8 alpha; +} SkinVertex; // size = 0xA + +/** + * Describes a position displacement and a scale to be applied to a limb at index `limbIndex` + */ +typedef struct { + /* 0x0 */ u8 limbIndex; + /* 0x2 */ s16 x; + /* 0x4 */ s16 y; + /* 0x6 */ s16 z; + /* 0x8 */ u8 scale; +} SkinTransformation; // size = 0xA + +typedef struct { + /* 0x00 */ u16 vtxCount; // number of vertices in this modif entry + /* 0x02 */ u16 transformCount; + /* 0x04 */ u16 unk_04; // index of limbTransformations + /* 0x08 */ SkinVertex* skinVertices; + /* 0x0C */ SkinTransformation* limbTransformations; +} SkinLimbModif; // size = 0x10 + +typedef struct { + /* 0x00 */ u16 totalVtxCount; // total vertex count for all modif entries + /* 0x02 */ u16 limbModifCount; // count of limbModifCount + /* 0x04 */ SkinLimbModif* limbModifications; + /* 0x08 */ Gfx* dlist; +} SkinAnimatedLimbData; // size = 0xC + +// ZAPD compatibility typedefs +// TODO: Remove when ZAPD adds support for them +typedef SkinVertex Struct_800A57C0; +typedef SkinTransformation Struct_800A598C_2; +typedef SkinAnimatedLimbData Struct_800A5E28; +typedef SkinLimbModif Struct_800A598C; + +#define SKIN_LIMB_TYPE_ANIMATED 4 +#define SKIN_LIMB_TYPE_NORMAL 11 + +typedef struct { + /* 0x00 */ Vec3s jointPos; // Root is position in model space, children are relative to parent + /* 0x06 */ u8 child; + /* 0x07 */ u8 sibling; + /* 0x08 */ s32 segmentType; // Type of data contained in segment + /* 0x0C */ void* segment; // Gfx* if segmentType is SKIN_LIMB_TYPE_NORMAL, SkinAnimatedLimbData if segmentType is SKIN_LIMB_TYPE_ANIMATED, NULL otherwise +} SkinLimb; // size = 0x10 + +typedef struct { + /* 0x0 */ u8 index; // alternates every draw cycle + /* 0x4 */ Vtx* buf[2]; // number of vertices in buffer determined by `totalVtxCount` +} SkinLimbVtx; // size = 0xC + +typedef struct { + /* 0x000 */ SkeletonHeader* skeletonHeader; + /* 0x004 */ MtxF mtx; + /* 0x044 */ s32 limbCount; + /* 0x048 */ SkinLimbVtx* vtxTable; // double buffered list of vertices for each limb + /* 0x04C */ SkelAnime skelAnime; +} Skin; // size = 0x90 + +typedef void (*SkinPostDraw)(struct Actor*, struct GlobalContext*, Skin*); +typedef s32 (*SkinOverrideLimbDraw)(struct Actor*, struct GlobalContext*, s32, Skin*); + +#define SKIN_DRAW_FLAG_CUSTOM_TRANSFORMS (1 << 0) +#define SKIN_DRAW_FLAG_CUSTOM_MATRIX (1 << 1) + + +void Skin_UpdateVertices(MtxF* mtx, SkinVertex* skinVertices, SkinLimbModif* modifEntry, Vtx* vtxBuf, Vec3f* pos); +void Skin_ApplyLimbModifications(struct GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3); +void Skin_DrawAnimatedLimb(struct GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3, s32 drawFlags); +void Skin_DrawLimb(struct GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, Gfx* dListOverride, s32 drawFlags); +void func_80138228(Actor* actor, struct GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, s32 setTranslation); +void func_80138258(Actor* actor, struct GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation); +void func_8013828C(Actor* actor, struct GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6); +void func_801382C4(Actor* actor, struct GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags); +void Skin_GetLimbPos(Skin* skin, s32 limbIndex, Vec3f* offset, Vec3f* dst); +void Skin_GetVertexPos(Skin* skin, s32 limbIndex, s32 vtxIndex, Vec3f* dst); + +void Skin_Setup(Skin* skin); +void Skin_InitAnimatedLimb(struct GameState* gameState, Skin* skin, s32 limbIndex); +void Skin_Init(struct GameState* gameState, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader); +void Skin_Free(struct GameState* gameState, Skin* skin); +s32 func_801387D4(Skin* skin, SkinLimb** skeleton, MtxF* limbMatrices, u8 parentIndex, u8 limbIndex); +s32 Skin_ApplyAnimTransformations(Skin* skin, MtxF* limbMatrices, Actor* actor, s32 setTranslation); + +#endif diff --git a/include/z64subs.h b/include/z64subs.h new file mode 100644 index 000000000..3b13d2add --- /dev/null +++ b/include/z64subs.h @@ -0,0 +1,83 @@ +#ifndef Z64SUBS_H +#define Z64SUBS_H + +#include "z64actor.h" +#include "z64scene.h" + +#include "code/sub_s/sub_s.h" + +extern Vec3f gOneVec3f; + +typedef enum { + /* 0 */ SUBS_CUTSCENE_SET_UNK_LINK_FIELDS, + /* 1 */ SUBS_CUTSCENE_NORMAL, + /* 2 */ SUBS_CUTSCENE_SET_FLAG +} SubSCutsceneType; + +//! @TODO: rename based on func_8013E748 and func_800B8500 +typedef s32 (*func_8013E748_VerifyFunc)(struct GlobalContext*, Actor*, void*); + +typedef s32 (*VerifyActor)(struct GlobalContext*, Actor*, Actor*, void*); + +#define SUBS_SHADOW_TEX_WIDTH 64 +#define SUBS_SHADOW_TEX_HEIGHT 64 +#define SUBS_SHADOW_TEX_SIZE ((s32)sizeof(u8[SUBS_SHADOW_TEX_HEIGHT][SUBS_SHADOW_TEX_WIDTH])) + +#define ACTOR_PATHING_RETURN_TO_START (1 << 0) +#define ACTOR_PATHING_SWITCH_DIRECTION (1 << 1) +#define ACTOR_PATHING_MOVE_BACKWARDS (1 << 3) +#define ACTOR_PATHING_REACHED_POINT_PERMANENT (1 << 4) +#define ACTOR_PATHING_REACHED_END_PERMANENT (1 << 5) +#define ACTOR_PATHING_REACHED_POINT_TEMPORARY (1 << 6) +#define ACTOR_PATHING_REACHED_END_TEMPORARY (1 << 7) + +#define ACTOR_PATHING_REACHED_TEMPORARY \ + (ACTOR_PATHING_REACHED_POINT_TEMPORARY | ACTOR_PATHING_REACHED_END_TEMPORARY) +#define ACTOR_PATHING_REACHED_POINT \ + (ACTOR_PATHING_REACHED_POINT_PERMANENT | ACTOR_PATHING_REACHED_POINT_TEMPORARY) +#define ACTOR_PATHING_REACHED_END \ + (ACTOR_PATHING_REACHED_END_PERMANENT | ACTOR_PATHING_REACHED_END_TEMPORARY) + +typedef struct TurnOptions { + /* 0x0 */ u16 rotMax; // binary angles + /* 0x2 */ u16 slowness; // larger for slower rotation, cannot be 0 + /* 0x4 */ u16 rotStepMin; // degrees + /* 0x6 */ u16 rotStepMax; // degrees +} TurnOptions; // size = 0x8 + +typedef struct TurnOptionsSet { + /* 0x00 */ TurnOptions headRotX; + /* 0x08 */ TurnOptions headRotY; + /* 0x10 */ TurnOptions torsoRotX; + /* 0x18 */ TurnOptions torsoRotY; +} TurnOptionsSet; // size = 0x20 + +struct ActorPathing; +typedef void (*ActorPathingComputeFunc)(struct GlobalContext*, struct ActorPathing*); +typedef s32 (*ActorPathingUpdateFunc)(struct GlobalContext*, struct ActorPathing*); + +typedef struct ActorPathing { + /* 0x00 */ Path* setupPathList; + /* 0x04 */ s32 pathIndex; + /* 0x08 */ Vec3s* points; + /* 0x0C */ s32 count; + /* 0x10 */ s32 curPointIndex; + /* 0x14 */ s32 begPointIndex; + /* 0x18 */ s32 endPointIndex; + /* 0x1C */ u8 flags; + /* 0x1D */ u8 prevFlags; + /* 0x20 */ Vec3f curPoint; + /* 0x2C */ Vec3f pointOffset; + /* 0x38 */ Vec3f prevPoint; + /* 0x44 */ Vec3f* worldPos; + /* 0x48 */ Actor* actor; + /* 0x4C */ f32 distSqToCurPointXZ; + /* 0x50 */ f32 distSqToCurPoint; + /* 0x54 */ Vec3s rotToCurPoint; + /* 0x5C */ ActorPathingComputeFunc computePointInfoFunc; + /* 0x60 */ ActorPathingUpdateFunc updateActorInfoFunc; // Return true if should setNextPoint, false if the actor should move forward + /* 0x64 */ ActorPathingUpdateFunc moveFunc; // Return true if should compute and update again + /* 0x68 */ ActorPathingUpdateFunc setNextPointFunc; // Return true if should compute and update again +} ActorPathing; // size = 0x6C + +#endif diff --git a/include/z_en_hy_code.h b/include/z_en_hy_code.h new file mode 100644 index 000000000..a0f9bcdd4 --- /dev/null +++ b/include/z_en_hy_code.h @@ -0,0 +1,94 @@ +#ifndef Z_EN_HY_CODE_H +#define Z_EN_HY_CODE_H + +#include "global.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" + +struct EnHy; + +#define ENHY_LIMB_MAX 16 + +//! TODO: Better animaion enum names when animations are documented +typedef enum { + /* 0 */ ENHY_ANIMATION_AOB_0, + /* 1 */ ENHY_ANIMATION_BOJ_1, + /* 2 */ ENHY_ANIMATION_BOJ_2, + /* 3 */ ENHY_ANIMATION_BOJ_3, + /* 4 */ ENHY_ANIMATION_BOJ_4, + /* 5 */ ENHY_ANIMATION_BOJ_5, + /* 6 */ ENHY_ANIMATION_BBA_6, + /* 7 */ ENHY_ANIMATION_BJI_7, + /* 8 */ ENHY_ANIMATION_BJI_8, + /* 9 */ ENHY_ANIMATION_BJI_9, + /* 10 */ ENHY_ANIMATION_BOJ_10, + /* 11 */ ENHY_ANIMATION_OS_ANIME_11, + /* 12 */ ENHY_ANIMATION_BOJ_12, + /* 13 */ ENHY_ANIMATION_BOJ_13, + /* 14 */ ENHY_ANIMATION_BOJ_14, + /* 15 */ ENHY_ANIMATION_BOJ_15, + /* 16 */ ENHY_ANIMATION_BOJ_16, + /* 17 */ ENHY_ANIMATION_BOJ_17, + /* 18 */ ENHY_ANIMATION_BOJ_18, + /* 19 */ ENHY_ANIMATION_BOJ_19, + /* 20 */ ENHY_ANIMATION_BOJ_20, + /* 21 */ ENHY_ANIMATION_MAX +} EnHyAnimation; + +typedef void (*EnHyActionFunc)(struct EnHy*, GlobalContext*); + +typedef struct EnHy { + /* 0x000 */ Actor actor; + /* 0x144 */ EnHyActionFunc actionFunc; + /* 0x148 */ EnHyActionFunc tmpActionFunc; + /* 0x14C */ SkelAnime skelAnime; + /* 0x190 */ s8 headObjIndex; // Limb 15 + /* 0x191 */ s8 skelUpperObjIndex; // Limbs 8-14 + /* 0x192 */ s8 skelLowerObjIndex; // Limbs 1-7 + /* 0x193 */ s8 animObjIndex; + /* 0x194 */ ColliderCylinder collider; + /* 0x1E0 */ u16 textId; + /* 0x1E2 */ u8 waitingOnInit; + /* 0x1E3 */ u8 inMsgState3; + /* 0x1E4 */ Path* path; + /* 0x1E8 */ s16 curPoint; + /* 0x1EC */ Vec3f leftFootPos; + /* 0x1F8 */ Vec3f rightFootPos; + /* 0x204 */ u8 isLeftFootOnGround; + /* 0x205 */ u8 isRightFootOnGround; + /* 0x206 */ Vec3s jointTable[ENHY_LIMB_MAX]; + /* 0x266 */ Vec3s morphTable[ENHY_LIMB_MAX]; + /* 0x2C6 */ Vec3s turnTarget; + /* 0x2CC */ Vec3s headRot; + /* 0x2D2 */ Vec3s torsoRot; + /* 0x2D8 */ Vec3s tmpTurnTarget; + /* 0x2DE */ Vec3s tmpHeadRot; + /* 0x2E4 */ Vec3s tmpTorsoRot; + /* 0x2EA */ s16 limbRotTableY[16]; + /* 0x30A */ s16 limbRotTableZ[16]; + /* 0x32C */ Vec3f bodyPartsPos[15]; + /* 0x3E0 */ UNK_TYPE1 unk_3E0[0x6]; + /* 0x3E6 */ s16 eyeTexIndex; + /* 0x3E8 */ s16 blinkTimer; +} EnHy; // size = 0x3EC + +extern s8 gEnHyBodyParts[]; +extern s8 gEnHyParentBodyParts[]; +extern u8 gEnHyShadowSizes[]; + +s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex); +EnDoor* 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, EnDoor* door, 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 speedTarget); +s32 EnHy_MoveBackwards(EnHy* enHy, f32 speedTarget); +void EnHy_UpdateCollider(EnHy* enHy, GlobalContext* globalCtx); +s32 EnHy_PlayWalkingSound(EnHy* enHy, GlobalContext* globalCtx, f32 distAboveThreshold); + +#endif // Z_EN_HY_CODE_H diff --git a/spec b/spec index bcdb24b47..b92703697 100644 --- a/spec +++ b/spec @@ -14,7 +14,7 @@ beginseg name "boot" address 0x80080060 include "build/src/boot_O2_g3/boot_main.o" - include "build/data/boot/rsp_boot.data.o" + include "build/data/boot/rspboot.data.o" include "build/src/boot_O2_g3/idle.o" include "build/src/boot_O2_g3/idle_extra_bss.o" include "build/src/boot_O2_g3/viconfig.o" @@ -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" @@ -39,7 +38,6 @@ beginseg include "build/src/boot_O2/mtxuty-cvt.o" include "build/src/boot_O2/assert.o" include "build/src/boot_O2/boot_800862E0.o" - include "build/data/boot/boot_800862E0.data.o" include "build/src/boot_O2/padsetup.o" include "build/src/boot_O2/boot_80086760.o" include "build/asm/boot/fp.text.o" @@ -47,7 +45,6 @@ beginseg include "build/src/boot_O2/system_malloc.o" include "build/src/boot_O2/rand.o" include "build/src/boot_O2/__osMalloc.o" - include "build/data/boot/__osMalloc.bss.o" include "build/src/libultra/rmon/sprintf.o" include "build/src/boot_O2/printutils.o" include "build/src/boot_O2/sleep.o" @@ -61,7 +58,8 @@ beginseg include "build/data/boot/setintmask.rodata.o" include "build/asm/boot/getintmask.text.o" include "build/src/libultra/voice/voicesetword.o" - include "build/data/boot/vimodeHpf.data.o" + include "build/src/libultra/io/osViModeNtscHpf1.o" + include "build/src/libultra/io/osViModePalLan1.o" include "build/asm/boot/guScale.text.o" include "build/src/libultra/gu/sinf.o" include "build/src/libultra/gu/sins.o" @@ -74,8 +72,7 @@ beginseg include "build/src/libultra/os/destroythread.o" include "build/src/libultra/voice/voicecheckresult.o" include "build/asm/boot/bzero.text.o" - include "build/src/libultra/io/rumblepak.o" - include "build/data/boot/rumblepak.bss.o" + include "build/src/libultra/io/motor.o" include "build/src/libultra/io/siacs.o" include "build/src/libultra/io/controller.o" include "build/src/libultra/os/createthread.o" @@ -121,8 +118,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" @@ -166,11 +161,10 @@ beginseg include "build/src/libultra/voice/voicesetadconverter.o" include "build/src/libultra/io/aisetfreq.o" include "build/src/libultra/io/contramread.o" - include "build/data/boot/contramread.data.o" include "build/src/libultra/voice/voicecontwrite20.o" include "build/src/libultra/io/crc.o" include "build/src/libultra/os/getactivequeue.o" - include "build/src/libultra/gu/normalize.o" + include "build/asm/boot/normalize.text.o" include "build/asm/boot/setcompare.text.o" include "build/asm/boot/getcompare.text.o" include "build/src/libultra/io/dpgetstat.o" @@ -180,8 +174,9 @@ beginseg include "build/src/libultra/io/pfsdeletefile.o" include "build/src/libultra/gu/ortho.o" include "build/asm/boot/interrupt.text.o" + include "build/src/libultra/io/osViModeNtscLan1.o" + include "build/src/libultra/io/osViModeMpalLan1.o" include "build/src/libultra/io/vi.o" - include "build/data/boot/vi.data.o" include "build/src/libultra/io/viswapcontext.o" include "build/src/libultra/io/pigetcmdq.o" include "build/src/libultra/gu/cosf.o" @@ -194,8 +189,6 @@ beginseg include "build/src/libultra/io/pfsisplug.o" include "build/src/libultra/voice/voicegetstatus.o" include "build/src/libultra/io/cartrominit.o" - include "build/data/boot/cartrominit.data.o" - include "build/data/boot/cartrominit.bss.o" include "build/src/libultra/gu/guS2DInitBg.o" include "build/data/boot/guS2DInitBg.data.o" include "build/src/libultra/io/pfsselectbank.o" @@ -217,7 +210,6 @@ beginseg include "build/src/libultra/os/settimer.o" include "build/data/boot/__libm_qnan_f.rodata.o" include "build/src/libultra/rmon/xldtob.o" - include "build/data/boot/xldtob.data.o" include "build/src/libultra/libc/ldiv.o" include "build/src/libultra/rmon/xlitob.o" include "build/src/libultra/io/sirawwrite.o" @@ -225,8 +217,6 @@ beginseg include "build/src/libultra/io/spsetstat.o" pad_text include "build/src/libultra/io/vimgr.o" - include "build/data/boot/vimgr.data.o" - include "build/data/boot/vimgr.bss.o" include "build/src/libultra/io/vigetcurrcontext.o" include "build/asm/boot/writebackdcacheall.text.o" include "build/src/libultra/os/getcurrfaultthread.o" @@ -317,7 +307,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 @@ -386,13 +376,15 @@ beginseg name "story_static" compress romalign 0x1000 - include "build/baserom/story_static.o" + include "build/assets/misc/story_static/story_static.o" + number 7 endseg beginseg name "do_action_static" romalign 0x1000 - include "build/baserom/do_action_static.o" + include "build/assets/interface/do_action_static/do_action_static.o" + number 9 endseg beginseg @@ -430,36 +422,31 @@ beginseg compress after "dmadata" include "build/src/code/z_en_a_keep.o" - include "build/data/code/z_en_a_keep.data.o" + include "build/data/code/aspMain.data.o" + include "build/data/code/gspS2DEX2.fifo.data.o" + include "build/data/code/njpgdspMain.data.o" include "build/data/code/code_801ADE60.data.o" 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" - include "build/data/code/z_actor.data.o" include "build/data/code/z_actor.bss.o" include "build/src/code/z_actor_dlftbls.o" include "build/src/code/z_bgcheck.o" - include "build/data/code/z_bgcheck.data.o" - include "build/data/code/z_bgcheck.bss.o" include "build/src/code/z_bg_collect.o" include "build/src/code/z_bg_item.o" - include "build/src/code/code_800CB000.o" include "build/src/code/z_camera.o" include "build/data/code/z_camera.data.o" include "build/data/code/z_camera.bss.o" @@ -468,38 +455,31 @@ beginseg include "build/src/code/z_collision_check.o" include "build/src/code/code_800E8EA0.o" include "build/src/code/z_common_data.o" - include "build/data/code/z_common_data.bss.o" include "build/src/code/z_debug.o" include "build/src/code/z_debug_display.o" - include "build/data/code/z_debug_display.data.o" - include "build/data/code/z_debug_display.bss.o" include "build/src/code/z_debug_mode.o" include "build/data/code/z_debug_mode.data.o" include "build/data/code/z_debug_mode.bss.o" include "build/src/code/z_demo.o" - include "build/data/code/z_demo.bss.o" include "build/src/code/z_draw.o" include "build/data/code/z_draw.data.o" include "build/src/code/z_eff_footmark.o" include "build/data/code/z_eff_footmark.data.o" - include "build/src/code/code_800F0390.o" + include "build/src/code/z_sound_source.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_code.o" include "build/src/code/z_face_reaction.o" - include "build/src/code/code_800F12D0.o" + include "build/src/code/z_env_flags.o" include "build/src/code/z_eventmgr.o" include "build/data/code/z_eventmgr.bss.o" include "build/src/code/z_fcurve_data.o" include "build/src/code/z_fcurve_data_skelanime.o" include "build/data/code/code_801BD830.data.o" include "build/src/code/z_fireobj.o" - include "build/data/code/z_fireobj.data.o" include "build/src/code/z_game_dlftbls.o" include "build/src/code/z_horse.o" include "build/data/code/z_horse.data.o" include "build/src/code/z_jpeg.o" - include "build/data/code/z_jpeg.data.o" include "build/src/code/z_kaleido_setup.o" include "build/src/code/z_kanfont.o" include "build/src/code/z_kankyo.o" @@ -508,9 +488,7 @@ beginseg include "build/src/code/z_lib.o" include "build/src/code/z_lifemeter.o" include "build/src/code/z_lights.o" - include "build/data/code/z_lights.bss.o" include "build/src/code/z_malloc.o" - include "build/data/code/z_malloc.bss.o" include "build/src/code/z_map_disp.o" include "build/data/code/z_map_disp.data.o" include "build/data/code/z_map_disp.bss.o" @@ -544,16 +522,13 @@ beginseg include "build/data/code/code_801C2730.data.o" include "build/src/code/z_scene_proc.o" include "build/src/code/z_scene_table.o" - include "build/src/code/code_801323D0.o" - include "build/data/code/code_801C5C50.data.o" + include "build/src/code/z_schedule.o" include "build/src/code/z_skelanime.o" include "build/src/code/z_skin.o" - include "build/data/code/z_skin.bss.o" include "build/src/code/z_skin_awb.o" include "build/src/code/z_skin_matrix.o" include "build/src/code/z_snap.o" include "build/src/code/z_sub_s.o" - include "build/data/code/z_sub_s.data.o" include "build/data/code/code_801DE890.rodata.o" include "build/src/code/code_8013EC10.o" include "build/data/code/code_8013EC10.bss.o" @@ -565,27 +540,19 @@ 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" include "build/src/code/z_message.o" + include "build/data/code/z_message.data.o" include "build/data/code/z_message.bss.o" include "build/src/code/z_message_nes.o" include "build/data/code/z_message_nes.data.o" include "build/src/code/z_message_staff.o" include "build/src/code/z_player_call.o" - include "build/data/code/z_player_call.bss.o" include "build/src/code/z_shrink_window.o" include "build/src/code/db_camera.o" 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" @@ -610,11 +577,10 @@ beginseg include "build/data/code/game.bss.o" include "build/src/code/gamealloc.o" include "build/src/code/graph.o" - include "build/data/code/graph.data.o" - include "build/data/code/graph.bss.o" - include "build/src/code/code_80174A40.o" + include "build/src/code/graphalloc.o" include "build/src/code/listalloc.o" include "build/src/code/main.o" + include "build/data/code/main.data.o" include "build/data/code/main.bss.o" include "build/src/code/padmgr.o" include "build/data/code/padmgr.data.o" @@ -632,9 +598,8 @@ beginseg include "build/data/code/code_801D15B0.data.o" include "build/src/code/sys_math_atan.o" include "build/src/code/sys_matrix.o" - include "build/data/code/sys_matrix.data.o" - include "build/data/code/sys_matrix.bss.o" include "build/src/code/sys_ucode.o" + include "build/src/code/code_80182CE0.o" include "build/data/code/code_801D1E70.data.o" include "build/src/code/code_80183070.o" include "build/src/code/c_keyframe.o" @@ -642,49 +607,61 @@ beginseg include "build/src/code/sys_flashrom.o" include "build/data/code/sys_flashrom.bss.o" include "build/asm/code/code_80185F90.text.o" // handwritten - include "build/src/code/osFlash.o" - include "build/data/code/osFlash.bss.o" + include "build/src/libultra/flash/osFlash.o" pad_text pad_text pad_text - include "build/src/code/audio_synthesis.o" - include "build/src/code/audio_heap.o" - include "build/data/code/code_801D2E80.data.o" + include "build/src/code/audio/audio_data.o" + include "build/src/code/audio/audio_synthesis.o" + include "build/data/code/audio_synthesis.data.o" + include "build/src/code/audio/audio_heap.o" include "build/data/code/audio_heap.bss.o" - include "build/data/code/code_801D3D90.data.o" - include "build/src/code/audio_load.o" - include "build/data/code/audio_load.bss.o" - include "build/src/code/code_80192BE0.o" - include "build/src/code/code_80194710.o" - include "build/src/code/audio_playback.o" - include "build/src/code/audio_effects.o" - include "build/src/code/audio_seqplayer.o" + include "build/src/code/audio/audio_load.o" + include "build/src/code/audio/code_80192BE0.o" + include "build/data/code/code_80192BE0.data.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" + include "build/src/code/audio/audio_effects.o" + include "build/src/code/audio/audio_seqplayer.o" + include "build/data/code/audio_seqplayer.data.o" + include "build/data/code/audio_dramStack.data.o" include "build/asm/code/code_8019AE40.text.o" // handwritten pad_text include "build/asm/code/code_8019AEC0.text.o" // handwritten - include "build/src/code/code_8019AF00.o" - include "build/data/code/code_8019AF00.bss.o" - include "build/data/code/code_801D55B0.data.o" - include "build/src/code/code_801A51F0.o" + include "build/src/code/audio/code_8019AF00.o" + include "build/src/code/audio/code_801A4EB0.o" + include "build/data/code/code_801A4EB0.data.o" + include "build/src/code/audio/code_801A51F0.o" include "build/data/code/code_801A51F0.data.o" include "build/data/code/code_801A51F0.bss.o" pad_text - include "build/src/code/code_801A5BD0.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/code_801A7B10.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/src/code/code_801AA020.o" - include "build/data/code/code_801AA020.bss.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/code_801D9090.data.o" - include "build/data/code/code_801E1180.rodata.o" + include "build/data/code/audio_tables.rodata.o" + include "build/data/code/aspMain.rodata.o" + include "build/data/code/gspF3DZEX2.NoN.PosLight.fifo.rodata.o" + include "build/data/code/gspS2DEX2.fifo.rodata.o" + include "build/data/code/njpgdspMain.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 @@ -743,20 +720,19 @@ 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 name "ovl_En_Test" compress include "build/src/overlays/actors/ovl_En_Test/z_en_test.o" - include "build/data/ovl_En_Test/ovl_En_Test.data.o" - include "build/data/ovl_En_Test/ovl_En_Test.reloc.o" + include "build/src/overlays/actors/ovl_En_Test/ovl_En_Test_reloc.o" endseg beginseg @@ -778,17 +754,14 @@ beginseg name "ovl_En_Light" compress include "build/src/overlays/actors/ovl_En_Light/z_en_light.o" - include "build/data/ovl_En_Light/ovl_En_Light.data.o" - include "build/data/ovl_En_Light/ovl_En_Light.reloc.o" + include "build/src/overlays/actors/ovl_En_Light/ovl_En_Light_reloc.o" endseg beginseg name "ovl_En_Door" compress include "build/src/overlays/actors/ovl_En_Door/z_en_door.o" - include "build/data/ovl_En_Door/ovl_En_Door.data.o" - include "build/data/ovl_En_Door/ovl_En_Door.bss.o" - include "build/data/ovl_En_Door/ovl_En_Door.reloc.o" + include "build/src/overlays/actors/ovl_En_Door/ovl_En_Door_reloc.o" endseg beginseg @@ -818,17 +791,14 @@ beginseg name "ovl_En_Bom" compress include "build/src/overlays/actors/ovl_En_Bom/z_en_bom.o" - include "build/data/ovl_En_Bom/ovl_En_Bom.data.o" - include "build/data/ovl_En_Bom/ovl_En_Bom.bss.o" - include "build/data/ovl_En_Bom/ovl_En_Bom.reloc.o" + include "build/src/overlays/actors/ovl_En_Bom/ovl_En_Bom_reloc.o" endseg beginseg name "ovl_En_Wallmas" compress include "build/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.o" - include "build/data/ovl_En_Wallmas/ovl_En_Wallmas.data.o" - include "build/data/ovl_En_Wallmas/ovl_En_Wallmas.reloc.o" + include "build/src/overlays/actors/ovl_En_Wallmas/ovl_En_Wallmas_reloc.o" endseg beginseg @@ -849,24 +819,25 @@ beginseg name "ovl_En_Horse" compress include "build/src/overlays/actors/ovl_En_Horse/z_en_horse.o" - include "build/data/ovl_En_Horse/ovl_En_Horse.data.o" - include "build/data/ovl_En_Horse/ovl_En_Horse.reloc.o" + include "build/src/overlays/actors/ovl_En_Horse/ovl_En_Horse_reloc.o" endseg beginseg name "ovl_En_Arrow" compress include "build/src/overlays/actors/ovl_En_Arrow/z_en_arrow.o" - include "build/data/ovl_En_Arrow/ovl_En_Arrow.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Arrow/ovl_En_Arrow_reloc.o" +#else include "build/data/ovl_En_Arrow/ovl_En_Arrow.reloc.o" +#endif endseg 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 @@ -880,16 +851,14 @@ beginseg name "ovl_En_Tite" compress include "build/src/overlays/actors/ovl_En_Tite/z_en_tite.o" - include "build/data/ovl_En_Tite/ovl_En_Tite.data.o" - include "build/data/ovl_En_Tite/ovl_En_Tite.reloc.o" + include "build/src/overlays/actors/ovl_En_Tite/ovl_En_Tite_reloc.o" endseg 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 @@ -942,16 +911,14 @@ beginseg name "ovl_Door_Shutter" compress include "build/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.o" - include "build/data/ovl_Door_Shutter/ovl_Door_Shutter.data.o" - include "build/data/ovl_Door_Shutter/ovl_Door_Shutter.reloc.o" + include "build/src/overlays/actors/ovl_Door_Shutter/ovl_Door_Shutter_reloc.o" endseg beginseg name "ovl_En_Boom" compress include "build/src/overlays/actors/ovl_En_Boom/z_en_boom.o" - include "build/data/ovl_En_Boom/ovl_En_Boom.data.o" - include "build/data/ovl_En_Boom/ovl_En_Boom.reloc.o" + include "build/src/overlays/actors/ovl_En_Boom/ovl_En_Boom_reloc.o" endseg beginseg @@ -972,24 +939,21 @@ 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 name "ovl_Obj_Wturn" compress include "build/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.o" - include "build/data/ovl_Obj_Wturn/ovl_Obj_Wturn.data.o" - include "build/data/ovl_Obj_Wturn/ovl_Obj_Wturn.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Wturn/ovl_Obj_Wturn_reloc.o" endseg beginseg name "ovl_En_River_Sound" compress include "build/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.o" - include "build/data/ovl_En_River_Sound/ovl_En_River_Sound.data.o" - include "build/data/ovl_En_River_Sound/ovl_En_River_Sound.reloc.o" + include "build/src/overlays/actors/ovl_En_River_Sound/ovl_En_River_Sound_reloc.o" endseg beginseg @@ -1003,24 +967,21 @@ beginseg name "ovl_En_Famos" compress include "build/src/overlays/actors/ovl_En_Famos/z_en_famos.o" - include "build/data/ovl_En_Famos/ovl_En_Famos.data.o" - include "build/data/ovl_En_Famos/ovl_En_Famos.reloc.o" + include "build/src/overlays/actors/ovl_En_Famos/ovl_En_Famos_reloc.o" endseg beginseg name "ovl_En_Bombf" compress include "build/src/overlays/actors/ovl_En_Bombf/z_en_bombf.o" - include "build/data/ovl_En_Bombf/ovl_En_Bombf.data.o" - include "build/data/ovl_En_Bombf/ovl_En_Bombf.reloc.o" + include "build/src/overlays/actors/ovl_En_Bombf/ovl_En_Bombf_reloc.o" endseg beginseg name "ovl_En_Am" compress include "build/src/overlays/actors/ovl_En_Am/z_en_am.o" - include "build/data/ovl_En_Am/ovl_En_Am.data.o" - include "build/data/ovl_En_Am/ovl_En_Am.reloc.o" + include "build/src/overlays/actors/ovl_En_Am/ovl_En_Am_reloc.o" endseg beginseg @@ -1050,17 +1011,14 @@ beginseg name "ovl_Bg_Breakwall" compress include "build/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.o" - include "build/data/ovl_Bg_Breakwall/ovl_Bg_Breakwall.data.o" - include "build/data/ovl_Bg_Breakwall/ovl_Bg_Breakwall.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Breakwall/ovl_Bg_Breakwall_reloc.o" endseg 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" - include "build/data/ovl_Door_Warp1/ovl_Door_Warp1.reloc.o" + include "build/src/overlays/actors/ovl_Door_Warp1/ovl_Door_Warp1_reloc.o" endseg beginseg @@ -1088,8 +1046,7 @@ beginseg name "ovl_En_Bbfall" compress include "build/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.o" - include "build/data/ovl_En_Bbfall/ovl_En_Bbfall.data.o" - include "build/data/ovl_En_Bbfall/ovl_En_Bbfall.reloc.o" + include "build/src/overlays/actors/ovl_En_Bbfall/ovl_En_Bbfall_reloc.o" endseg beginseg @@ -1103,8 +1060,7 @@ beginseg name "ovl_En_Bb" compress include "build/src/overlays/actors/ovl_En_Bb/z_en_bb.o" - include "build/data/ovl_En_Bb/ovl_En_Bb.data.o" - include "build/data/ovl_En_Bb/ovl_En_Bb.reloc.o" + include "build/src/overlays/actors/ovl_En_Bb/ovl_En_Bb_reloc.o" endseg beginseg @@ -1118,9 +1074,7 @@ beginseg name "ovl_En_Wood02" compress include "build/src/overlays/actors/ovl_En_Wood02/z_en_wood02.o" - include "build/data/ovl_En_Wood02/ovl_En_Wood02.data.o" - include "build/data/ovl_En_Wood02/ovl_En_Wood02.bss.o" - include "build/data/ovl_En_Wood02/ovl_En_Wood02.reloc.o" + include "build/src/overlays/actors/ovl_En_Wood02/ovl_En_Wood02_reloc.o" endseg beginseg @@ -1144,32 +1098,28 @@ beginseg name "ovl_En_Vm" compress include "build/src/overlays/actors/ovl_En_Vm/z_en_vm.o" - include "build/data/ovl_En_Vm/ovl_En_Vm.data.o" - include "build/data/ovl_En_Vm/ovl_En_Vm.reloc.o" + include "build/src/overlays/actors/ovl_En_Vm/ovl_En_Vm_reloc.o" endseg beginseg name "ovl_Demo_Effect" compress include "build/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.o" - include "build/data/ovl_Demo_Effect/ovl_Demo_Effect.data.o" - include "build/data/ovl_Demo_Effect/ovl_Demo_Effect.reloc.o" + include "build/src/overlays/actors/ovl_Demo_Effect/ovl_Demo_Effect_reloc.o" endseg beginseg name "ovl_Demo_Kankyo" compress include "build/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.o" - include "build/data/ovl_Demo_Kankyo/ovl_Demo_Kankyo.data.o" - include "build/data/ovl_Demo_Kankyo/ovl_Demo_Kankyo.reloc.o" + include "build/src/overlays/actors/ovl_Demo_Kankyo/ovl_Demo_Kankyo_reloc.o" endseg beginseg name "ovl_En_Floormas" compress include "build/src/overlays/actors/ovl_En_Floormas/z_en_floormas.o" - include "build/data/ovl_En_Floormas/ovl_En_Floormas.data.o" - include "build/data/ovl_En_Floormas/ovl_En_Floormas.reloc.o" + include "build/src/overlays/actors/ovl_En_Floormas/ovl_En_Floormas_reloc.o" endseg beginseg @@ -1191,8 +1141,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 @@ -1210,9 +1159,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 @@ -1271,8 +1222,11 @@ beginseg name "ovl_Mir_Ray" compress include "build/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.o" - include "build/data/ovl_Mir_Ray/ovl_Mir_Ray.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Mir_Ray/ovl_Mir_Ray_reloc.o" +#else include "build/data/ovl_Mir_Ray/ovl_Mir_Ray.reloc.o" +#endif endseg beginseg @@ -1286,16 +1240,14 @@ 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 name "ovl_En_Karebaba" compress include "build/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.o" - include "build/data/ovl_En_Karebaba/ovl_En_Karebaba.data.o" - include "build/data/ovl_En_Karebaba/ovl_En_Karebaba.reloc.o" + include "build/src/overlays/actors/ovl_En_Karebaba/ovl_En_Karebaba_reloc.o" endseg beginseg @@ -1309,49 +1261,42 @@ beginseg name "ovl_En_Bom_Chu" compress include "build/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.o" - include "build/data/ovl_En_Bom_Chu/ovl_En_Bom_Chu.data.o" - include "build/data/ovl_En_Bom_Chu/ovl_En_Bom_Chu.reloc.o" + include "build/src/overlays/actors/ovl_En_Bom_Chu/ovl_En_Bom_Chu_reloc.o" endseg beginseg name "ovl_En_Horse_Game_Check" compress include "build/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.o" - include "build/data/ovl_En_Horse_Game_Check/ovl_En_Horse_Game_Check.data.o" - include "build/data/ovl_En_Horse_Game_Check/ovl_En_Horse_Game_Check.reloc.o" + include "build/src/overlays/actors/ovl_En_Horse_Game_Check/ovl_En_Horse_Game_Check_reloc.o" endseg 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" - include "build/data/ovl_En_Fishing/ovl_En_Fishing.reloc.o" + include "build/src/overlays/actors/ovl_En_Fishing/ovl_En_Fishing_reloc.o" endseg beginseg name "ovl_Obj_Oshihiki" compress include "build/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.o" - include "build/data/ovl_Obj_Oshihiki/ovl_Obj_Oshihiki.data.o" - include "build/data/ovl_Obj_Oshihiki/ovl_Obj_Oshihiki.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Oshihiki/ovl_Obj_Oshihiki_reloc.o" endseg beginseg @@ -1373,24 +1318,21 @@ beginseg name "ovl_En_Insect" compress include "build/src/overlays/actors/ovl_En_Insect/z_en_insect.o" - include "build/data/ovl_En_Insect/ovl_En_Insect.data.o" - include "build/data/ovl_En_Insect/ovl_En_Insect.reloc.o" + include "build/src/overlays/actors/ovl_En_Insect/ovl_En_Insect_reloc.o" endseg beginseg name "ovl_En_Butte" compress include "build/src/overlays/actors/ovl_En_Butte/z_en_butte.o" - include "build/data/ovl_En_Butte/ovl_En_Butte.data.o" - include "build/data/ovl_En_Butte/ovl_En_Butte.reloc.o" + include "build/src/overlays/actors/ovl_En_Butte/ovl_En_Butte_reloc.o" endseg 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 @@ -1405,9 +1347,7 @@ beginseg name "ovl_Arrow_Fire" compress include "build/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.data.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.bss.o" - include "build/data/ovl_Arrow_Fire/ovl_Arrow_Fire.reloc.o" + include "build/src/overlays/actors/ovl_Arrow_Fire/ovl_Arrow_Fire_reloc.o" endseg beginseg @@ -1421,9 +1361,7 @@ beginseg name "ovl_Arrow_Light" compress include "build/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.data.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.bss.o" - include "build/data/ovl_Arrow_Light/ovl_Arrow_Light.reloc.o" + include "build/src/overlays/actors/ovl_Arrow_Light/ovl_Arrow_Light_reloc.o" endseg beginseg @@ -1490,50 +1428,42 @@ beginseg name "ovl_Obj_Ice_Poly" compress include "build/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.o" - include "build/data/ovl_Obj_Ice_Poly/ovl_Obj_Ice_Poly.data.o" - include "build/data/ovl_Obj_Ice_Poly/ovl_Obj_Ice_Poly.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Ice_Poly/ovl_Obj_Ice_Poly_reloc.o" endseg 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 name "ovl_En_Kusa" compress include "build/src/overlays/actors/ovl_En_Kusa/z_en_kusa.o" - include "build/data/ovl_En_Kusa/ovl_En_Kusa.data.o" - include "build/data/ovl_En_Kusa/ovl_En_Kusa.bss.o" - include "build/data/ovl_En_Kusa/ovl_En_Kusa.reloc.o" + include "build/src/overlays/actors/ovl_En_Kusa/ovl_En_Kusa_reloc.o" endseg beginseg name "ovl_Obj_Bean" compress include "build/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.o" - include "build/data/ovl_Obj_Bean/ovl_Obj_Bean.data.o" - include "build/data/ovl_Obj_Bean/ovl_Obj_Bean.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Bean/ovl_Obj_Bean_reloc.o" endseg beginseg name "ovl_Obj_Bombiwa" compress include "build/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.o" - include "build/data/ovl_Obj_Bombiwa/ovl_Obj_Bombiwa.data.o" - include "build/data/ovl_Obj_Bombiwa/ovl_Obj_Bombiwa.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Bombiwa/ovl_Obj_Bombiwa_reloc.o" endseg beginseg name "ovl_Obj_Switch" compress include "build/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.o" - include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.data.o" - include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.bss.o" - include "build/data/ovl_Obj_Switch/ovl_Obj_Switch.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Switch/ovl_Obj_Switch_reloc.o" endseg beginseg @@ -1564,8 +1494,7 @@ beginseg name "ovl_En_Goroiwa" compress include "build/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.o" - include "build/data/ovl_En_Goroiwa/ovl_En_Goroiwa.data.o" - include "build/data/ovl_En_Goroiwa/ovl_En_Goroiwa.reloc.o" + include "build/src/overlays/actors/ovl_En_Goroiwa/ovl_En_Goroiwa_reloc.o" endseg beginseg @@ -1579,8 +1508,7 @@ beginseg name "ovl_En_Nwc" compress include "build/src/overlays/actors/ovl_En_Nwc/z_en_nwc.o" - include "build/data/ovl_En_Nwc/ovl_En_Nwc.data.o" - include "build/data/ovl_En_Nwc/ovl_En_Nwc.reloc.o" + include "build/src/overlays/actors/ovl_En_Nwc/ovl_En_Nwc_reloc.o" endseg beginseg @@ -1602,17 +1530,14 @@ beginseg name "ovl_Obj_Blockstop" compress include "build/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.o" - include "build/data/ovl_Obj_Blockstop/ovl_Obj_Blockstop.data.o" - include "build/data/ovl_Obj_Blockstop/ovl_Obj_Blockstop.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Blockstop/ovl_Obj_Blockstop_reloc.o" endseg beginseg name "ovl_En_Sda" compress include "build/src/overlays/actors/ovl_En_Sda/z_en_sda.o" - include "build/data/ovl_En_Sda/ovl_En_Sda.data.o" - include "build/data/ovl_En_Sda/ovl_En_Sda.bss.o" - include "build/data/ovl_En_Sda/ovl_En_Sda.reloc.o" + include "build/src/overlays/actors/ovl_En_Sda/ovl_En_Sda_reloc.o" endseg beginseg @@ -1626,56 +1551,53 @@ 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 name "ovl_En_Hs" compress include "build/src/overlays/actors/ovl_En_Hs/z_en_hs.o" - include "build/data/ovl_En_Hs/ovl_En_Hs.data.o" - include "build/data/ovl_En_Hs/ovl_En_Hs.reloc.o" + include "build/src/overlays/actors/ovl_En_Hs/ovl_En_Hs_reloc.o" endseg beginseg name "ovl_Bg_Ingate" compress include "build/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.o" - include "build/data/ovl_Bg_Ingate/ovl_Bg_Ingate.data.o" - include "build/data/ovl_Bg_Ingate/ovl_Bg_Ingate.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Ingate/ovl_Bg_Ingate_reloc.o" endseg beginseg name "ovl_En_Kanban" compress include "build/src/overlays/actors/ovl_En_Kanban/z_en_kanban.o" - include "build/data/ovl_En_Kanban/ovl_En_Kanban.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Kanban/ovl_En_Kanban_reloc.o" +#else include "build/data/ovl_En_Kanban/ovl_En_Kanban.reloc.o" +#endif endseg beginseg name "ovl_En_Attack_Niw" compress include "build/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.o" - include "build/data/ovl_En_Attack_Niw/ovl_En_Attack_Niw.data.o" - include "build/data/ovl_En_Attack_Niw/ovl_En_Attack_Niw.reloc.o" + include "build/src/overlays/actors/ovl_En_Attack_Niw/ovl_En_Attack_Niw_reloc.o" endseg beginseg name "ovl_En_Mk" compress include "build/src/overlays/actors/ovl_En_Mk/z_en_mk.o" - include "build/data/ovl_En_Mk/ovl_En_Mk.data.o" - include "build/data/ovl_En_Mk/ovl_En_Mk.reloc.o" + include "build/src/overlays/actors/ovl_En_Mk/ovl_En_Mk_reloc.o" endseg beginseg @@ -1689,8 +1611,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 @@ -1726,16 +1647,14 @@ 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 name "ovl_En_Mm" compress include "build/src/overlays/actors/ovl_En_Mm/z_en_mm.o" - include "build/data/ovl_En_Mm/ovl_En_Mm.data.o" - include "build/data/ovl_En_Mm/ovl_En_Mm.reloc.o" + include "build/src/overlays/actors/ovl_En_Mm/ovl_En_Mm_reloc.o" endseg beginseg @@ -1749,8 +1668,7 @@ beginseg name "ovl_En_Ani" compress include "build/src/overlays/actors/ovl_En_Ani/z_en_ani.o" - include "build/data/ovl_En_Ani/ovl_En_Ani.data.o" - include "build/data/ovl_En_Ani/ovl_En_Ani.reloc.o" + include "build/src/overlays/actors/ovl_En_Ani/ovl_En_Ani_reloc.o" endseg beginseg @@ -1772,8 +1690,7 @@ beginseg name "ovl_En_Mag" compress include "build/src/overlays/actors/ovl_En_Mag/z_en_mag.o" - include "build/data/ovl_En_Mag/ovl_En_Mag.data.o" - include "build/data/ovl_En_Mag/ovl_En_Mag.reloc.o" + include "build/src/overlays/actors/ovl_En_Mag/ovl_En_Mag_reloc.o" endseg beginseg @@ -1797,8 +1714,7 @@ beginseg name "ovl_En_Kakasi" compress include "build/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.o" - include "build/data/ovl_En_Kakasi/ovl_En_Kakasi.data.o" - include "build/data/ovl_En_Kakasi/ovl_En_Kakasi.reloc.o" + include "build/src/overlays/actors/ovl_En_Kakasi/ovl_En_Kakasi_reloc.o" endseg beginseg @@ -1835,16 +1751,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 @@ -1868,8 +1782,7 @@ beginseg name "ovl_Effect_Ss_Kirakira" compress include "build/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.o" - include "build/data/ovl_Effect_Ss_Kirakira/ovl_Effect_Ss_Kirakira.data.o" - include "build/data/ovl_Effect_Ss_Kirakira/ovl_Effect_Ss_Kirakira.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Kirakira/ovl_Effect_Ss_Kirakira_reloc.o" endseg beginseg @@ -1908,8 +1821,7 @@ beginseg name "ovl_Effect_Ss_Bubble" compress include "build/src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.o" - include "build/data/ovl_Effect_Ss_Bubble/ovl_Effect_Ss_Bubble.data.o" - include "build/data/ovl_Effect_Ss_Bubble/ovl_Effect_Ss_Bubble.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Bubble/ovl_Effect_Ss_Bubble_reloc.o" endseg beginseg @@ -1940,8 +1852,7 @@ beginseg name "ovl_Effect_Ss_Lightning" compress include "build/src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.o" - include "build/data/ovl_Effect_Ss_Lightning/ovl_Effect_Ss_Lightning.data.o" - include "build/data/ovl_Effect_Ss_Lightning/ovl_Effect_Ss_Lightning.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Lightning/ovl_Effect_Ss_Lightning_reloc.o" endseg beginseg @@ -1964,24 +1875,21 @@ 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 name "ovl_Effect_Ss_Sibuki" compress include "build/src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.o" - include "build/data/ovl_Effect_Ss_Sibuki/ovl_Effect_Ss_Sibuki.data.o" - include "build/data/ovl_Effect_Ss_Sibuki/ovl_Effect_Ss_Sibuki.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Sibuki/ovl_Effect_Ss_Sibuki_reloc.o" endseg beginseg name "ovl_Effect_Ss_Stone1" compress include "build/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.o" - include "build/data/ovl_Effect_Ss_Stone1/ovl_Effect_Ss_Stone1.data.o" - include "build/data/ovl_Effect_Ss_Stone1/ovl_Effect_Ss_Stone1.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Stone1/ovl_Effect_Ss_Stone1_reloc.o" endseg beginseg @@ -2020,8 +1928,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 @@ -2155,8 +2062,7 @@ beginseg name "ovl_Obj_Comb" compress include "build/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.o" - include "build/data/ovl_Obj_Comb/ovl_Obj_Comb.data.o" - include "build/data/ovl_Obj_Comb/ovl_Obj_Comb.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Comb/ovl_Obj_Comb_reloc.o" endseg beginseg @@ -2193,8 +2099,7 @@ beginseg name "ovl_En_Wf" compress include "build/src/overlays/actors/ovl_En_Wf/z_en_wf.o" - include "build/data/ovl_En_Wf/ovl_En_Wf.data.o" - include "build/data/ovl_En_Wf/ovl_En_Wf.reloc.o" + include "build/src/overlays/actors/ovl_En_Wf/ovl_En_Wf_reloc.o" endseg beginseg @@ -2208,8 +2113,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 @@ -2224,16 +2128,14 @@ beginseg name "ovl_En_Crow" compress include "build/src/overlays/actors/ovl_En_Crow/z_en_crow.o" - include "build/data/ovl_En_Crow/ovl_En_Crow.data.o" - include "build/data/ovl_En_Crow/ovl_En_Crow.reloc.o" + include "build/src/overlays/actors/ovl_En_Crow/ovl_En_Crow_reloc.o" endseg 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 @@ -2249,8 +2151,7 @@ beginseg name "ovl_En_Zo" compress include "build/src/overlays/actors/ovl_En_Zo/z_en_zo.o" - include "build/data/ovl_En_Zo/ovl_En_Zo.data.o" - include "build/data/ovl_En_Zo/ovl_En_Zo.reloc.o" + include "build/src/overlays/actors/ovl_En_Zo/ovl_En_Zo_reloc.o" endseg beginseg @@ -2281,8 +2182,7 @@ beginseg name "ovl_Obj_Hamishi" compress include "build/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.o" - include "build/data/ovl_Obj_Hamishi/ovl_Obj_Hamishi.data.o" - include "build/data/ovl_Obj_Hamishi/ovl_Obj_Hamishi.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Hamishi/ovl_Obj_Hamishi_reloc.o" endseg beginseg @@ -2297,8 +2197,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 @@ -2312,8 +2211,7 @@ beginseg name "ovl_Obj_Pzlblock" compress include "build/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.o" - include "build/data/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock.data.o" - include "build/data/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Pzlblock/ovl_Obj_Pzlblock_reloc.o" endseg beginseg @@ -2328,8 +2226,7 @@ beginseg name "ovl_Obj_Armos" compress include "build/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.o" - include "build/data/ovl_Obj_Armos/ovl_Obj_Armos.data.o" - include "build/data/ovl_Obj_Armos/ovl_Obj_Armos.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Armos/ovl_Obj_Armos_reloc.o" endseg beginseg @@ -2351,17 +2248,14 @@ beginseg name "ovl_Obj_Grass" compress include "build/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.o" - include "build/data/ovl_Obj_Grass/ovl_Obj_Grass.data.o" - include "build/data/ovl_Obj_Grass/ovl_Obj_Grass.bss.o" - include "build/data/ovl_Obj_Grass/ovl_Obj_Grass.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Grass/ovl_Obj_Grass_reloc.o" endseg beginseg name "ovl_Obj_Grass_Carry" compress include "build/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.o" - include "build/data/ovl_Obj_Grass_Carry/ovl_Obj_Grass_Carry.data.o" - include "build/data/ovl_Obj_Grass_Carry/ovl_Obj_Grass_Carry.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Grass_Carry/ovl_Obj_Grass_Carry_reloc.o" endseg beginseg @@ -2424,16 +2318,14 @@ beginseg name "ovl_En_Warp_tag" compress include "build/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.o" - include "build/data/ovl_En_Warp_tag/ovl_En_Warp_tag.data.o" - include "build/data/ovl_En_Warp_tag/ovl_En_Warp_tag.reloc.o" + include "build/src/overlays/actors/ovl_En_Warp_tag/ovl_En_Warp_tag_reloc.o" endseg 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 @@ -2469,8 +2361,7 @@ beginseg name "ovl_En_Bom_Bowl_Man" compress include "build/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.o" - include "build/data/ovl_En_Bom_Bowl_Man/ovl_En_Bom_Bowl_Man.data.o" - include "build/data/ovl_En_Bom_Bowl_Man/ovl_En_Bom_Bowl_Man.reloc.o" + include "build/src/overlays/actors/ovl_En_Bom_Bowl_Man/ovl_En_Bom_Bowl_Man_reloc.o" endseg beginseg @@ -2491,8 +2382,7 @@ beginseg name "ovl_En_Syateki_Crow" compress include "build/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.o" - include "build/data/ovl_En_Syateki_Crow/ovl_En_Syateki_Crow.data.o" - include "build/data/ovl_En_Syateki_Crow/ovl_En_Syateki_Crow.reloc.o" + include "build/src/overlays/actors/ovl_En_Syateki_Crow/ovl_En_Syateki_Crow_reloc.o" endseg beginseg @@ -2506,16 +2396,14 @@ beginseg name "ovl_En_Cne_01" compress include "build/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.o" - include "build/data/ovl_En_Cne_01/ovl_En_Cne_01.data.o" - include "build/data/ovl_En_Cne_01/ovl_En_Cne_01.reloc.o" + include "build/src/overlays/actors/ovl_En_Cne_01/ovl_En_Cne_01_reloc.o" endseg beginseg name "ovl_En_Bba_01" compress include "build/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.o" - include "build/data/ovl_En_Bba_01/ovl_En_Bba_01.data.o" - include "build/data/ovl_En_Bba_01/ovl_En_Bba_01.reloc.o" + include "build/src/overlays/actors/ovl_En_Bba_01/ovl_En_Bba_01_reloc.o" endseg beginseg @@ -2529,16 +2417,18 @@ beginseg name "ovl_Bg_Spdweb" compress include "build/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.o" - include "build/data/ovl_Bg_Spdweb/ovl_Bg_Spdweb.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Bg_Spdweb/ovl_Bg_Spdweb_reloc.o" +#else include "build/data/ovl_Bg_Spdweb/ovl_Bg_Spdweb.reloc.o" +#endif endseg beginseg name "ovl_En_Mt_tag" compress include "build/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.o" - include "build/data/ovl_En_Mt_tag/ovl_En_Mt_tag.data.o" - include "build/data/ovl_En_Mt_tag/ovl_En_Mt_tag.reloc.o" + include "build/src/overlays/actors/ovl_En_Mt_tag/ovl_En_Mt_tag_reloc.o" endseg beginseg @@ -2554,27 +2444,21 @@ beginseg name "ovl_Boss_02" compress include "build/src/overlays/actors/ovl_Boss_02/z_boss_02.o" - include "build/data/ovl_Boss_02/ovl_Boss_02.data.o" - include "build/data/ovl_Boss_02/ovl_Boss_02.bss.o" - include "build/data/ovl_Boss_02/ovl_Boss_02.reloc.o" + include "build/src/overlays/actors/ovl_Boss_02/ovl_Boss_02_reloc.o" endseg beginseg name "ovl_Boss_03" compress include "build/src/overlays/actors/ovl_Boss_03/z_boss_03.o" - include "build/data/ovl_Boss_03/ovl_Boss_03.data.o" - include "build/data/ovl_Boss_03/ovl_Boss_03.bss.o" - include "build/data/ovl_Boss_03/ovl_Boss_03.reloc.o" + include "build/src/overlays/actors/ovl_Boss_03/ovl_Boss_03_reloc.o" endseg 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 @@ -2590,9 +2474,11 @@ beginseg name "ovl_Boss_06" compress include "build/src/overlays/actors/ovl_Boss_06/z_boss_06.o" - include "build/data/ovl_Boss_06/ovl_Boss_06.data.o" - include "build/data/ovl_Boss_06/ovl_Boss_06.bss.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Boss_06/ovl_Boss_06_reloc.o" +#else include "build/data/ovl_Boss_06/ovl_Boss_06.reloc.o" +#endif endseg beginseg @@ -2628,16 +2514,18 @@ 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 name "ovl_En_Raf" compress include "build/src/overlays/actors/ovl_En_Raf/z_en_raf.o" - include "build/data/ovl_En_Raf/ovl_En_Raf.data.o" - include "build/data/ovl_En_Raf/ovl_En_Raf.reloc.o" + include "build/src/overlays/actors/ovl_En_Raf/ovl_En_Raf_reloc.o" endseg beginseg @@ -2658,25 +2546,25 @@ beginseg name "ovl_Bg_Numa_Hana" compress include "build/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.o" - include "build/data/ovl_Bg_Numa_Hana/ovl_Bg_Numa_Hana.data.o" - include "build/data/ovl_Bg_Numa_Hana/ovl_Bg_Numa_Hana.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Numa_Hana/ovl_Bg_Numa_Hana_reloc.o" endseg 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 name "ovl_Obj_Spinyroll" compress include "build/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.o" - include "build/data/ovl_Obj_Spinyroll/ovl_Obj_Spinyroll.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Obj_Spinyroll/ovl_Obj_Spinyroll_reloc.o" +#else include "build/data/ovl_Obj_Spinyroll/ovl_Obj_Spinyroll.reloc.o" +#endif endseg beginseg @@ -2691,32 +2579,28 @@ beginseg name "ovl_En_Syateki_Wf" compress include "build/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.o" - include "build/data/ovl_En_Syateki_Wf/ovl_En_Syateki_Wf.data.o" - include "build/data/ovl_En_Syateki_Wf/ovl_En_Syateki_Wf.reloc.o" + include "build/src/overlays/actors/ovl_En_Syateki_Wf/ovl_En_Syateki_Wf_reloc.o" endseg beginseg name "ovl_Obj_Skateblock" compress include "build/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.o" - include "build/data/ovl_Obj_Skateblock/ovl_Obj_Skateblock.data.o" - include "build/data/ovl_Obj_Skateblock/ovl_Obj_Skateblock.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Skateblock/ovl_Obj_Skateblock_reloc.o" endseg beginseg name "ovl_Effect_En_Ice_Block" compress include "build/src/overlays/effects/ovl_Effect_En_Ice_Block/z_eff_en_ice_block.o" - include "build/data/ovl_Effect_En_Ice_Block/ovl_Effect_En_Ice_Block.data.o" - include "build/data/ovl_Effect_En_Ice_Block/ovl_Effect_En_Ice_Block.reloc.o" + include "build/src/overlays/effects/ovl_Effect_En_Ice_Block/ovl_Effect_En_Ice_Block_reloc.o" endseg 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" - include "build/data/ovl_Obj_Iceblock/ovl_Obj_Iceblock.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Iceblock/ovl_Obj_Iceblock_reloc.o" endseg beginseg @@ -2731,17 +2615,14 @@ beginseg name "ovl_Bg_Dblue_Movebg" compress include "build/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.o" - include "build/data/ovl_Bg_Dblue_Movebg/ovl_Bg_Dblue_Movebg.data.o" - include "build/data/ovl_Bg_Dblue_Movebg/ovl_Bg_Dblue_Movebg.bss.o" - include "build/data/ovl_Bg_Dblue_Movebg/ovl_Bg_Dblue_Movebg.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Dblue_Movebg/ovl_Bg_Dblue_Movebg_reloc.o" endseg beginseg name "ovl_En_Syateki_Dekunuts" compress include "build/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.o" - include "build/data/ovl_En_Syateki_Dekunuts/ovl_En_Syateki_Dekunuts.data.o" - include "build/data/ovl_En_Syateki_Dekunuts/ovl_En_Syateki_Dekunuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Syateki_Dekunuts/ovl_En_Syateki_Dekunuts_reloc.o" endseg beginseg @@ -2786,8 +2667,7 @@ beginseg name "ovl_En_Pr" compress include "build/src/overlays/actors/ovl_En_Pr/z_en_pr.o" - include "build/data/ovl_En_Pr/ovl_En_Pr.data.o" - include "build/data/ovl_En_Pr/ovl_En_Pr.reloc.o" + include "build/src/overlays/actors/ovl_En_Pr/ovl_En_Pr_reloc.o" endseg beginseg @@ -2802,8 +2682,7 @@ beginseg name "ovl_Obj_Entotu" compress include "build/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.o" - include "build/data/ovl_Obj_Entotu/ovl_Obj_Entotu.data.o" - include "build/data/ovl_Obj_Entotu/ovl_Obj_Entotu.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Entotu/ovl_Obj_Entotu_reloc.o" endseg beginseg @@ -2817,8 +2696,7 @@ beginseg name "ovl_En_Syateki_Okuta" compress include "build/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.o" - include "build/data/ovl_En_Syateki_Okuta/ovl_En_Syateki_Okuta.data.o" - include "build/data/ovl_En_Syateki_Okuta/ovl_En_Syateki_Okuta.reloc.o" + include "build/src/overlays/actors/ovl_En_Syateki_Okuta/ovl_En_Syateki_Okuta_reloc.o" endseg beginseg @@ -2849,8 +2727,7 @@ beginseg name "ovl_En_Elfgrp" compress include "build/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.o" - include "build/data/ovl_En_Elfgrp/ovl_En_Elfgrp.data.o" - include "build/data/ovl_En_Elfgrp/ovl_En_Elfgrp.reloc.o" + include "build/src/overlays/actors/ovl_En_Elfgrp/ovl_En_Elfgrp_reloc.o" endseg beginseg @@ -2865,24 +2742,21 @@ beginseg name "ovl_En_Baguo" compress include "build/src/overlays/actors/ovl_En_Baguo/z_en_baguo.o" - include "build/data/ovl_En_Baguo/ovl_En_Baguo.data.o" - include "build/data/ovl_En_Baguo/ovl_En_Baguo.reloc.o" + include "build/src/overlays/actors/ovl_En_Baguo/ovl_En_Baguo_reloc.o" endseg beginseg name "ovl_Obj_Vspinyroll" compress include "build/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.o" - include "build/data/ovl_Obj_Vspinyroll/ovl_Obj_Vspinyroll.data.o" - include "build/data/ovl_Obj_Vspinyroll/ovl_Obj_Vspinyroll.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Vspinyroll/ovl_Obj_Vspinyroll_reloc.o" endseg beginseg name "ovl_Obj_Smork" compress include "build/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.o" - include "build/data/ovl_Obj_Smork/ovl_Obj_Smork.data.o" - include "build/data/ovl_Obj_Smork/ovl_Obj_Smork.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Smork/ovl_Obj_Smork_reloc.o" endseg beginseg @@ -2906,11 +2780,7 @@ beginseg name "ovl_En_Test4" compress include "build/src/overlays/actors/ovl_En_Test4/z_en_test4.o" -#ifdef NON_MATCHING include "build/src/overlays/actors/ovl_En_Test4/ovl_En_Test4_reloc.o" -#else - include "build/data/ovl_En_Test4/ovl_En_Test4.reloc.o" -#endif endseg beginseg @@ -2942,16 +2812,14 @@ beginseg name "ovl_En_Wiz_Brock" compress include "build/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.o" - include "build/data/ovl_En_Wiz_Brock/ovl_En_Wiz_Brock.data.o" - include "build/data/ovl_En_Wiz_Brock/ovl_En_Wiz_Brock.reloc.o" + include "build/src/overlays/actors/ovl_En_Wiz_Brock/ovl_En_Wiz_Brock_reloc.o" endseg 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 @@ -2973,8 +2841,7 @@ beginseg name "ovl_Obj_Fireshield" compress include "build/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.o" - include "build/data/ovl_Obj_Fireshield/ovl_Obj_Fireshield.data.o" - include "build/data/ovl_Obj_Fireshield/ovl_Obj_Fireshield.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Fireshield/ovl_Obj_Fireshield_reloc.o" endseg beginseg @@ -3041,8 +2908,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 @@ -3064,17 +2930,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 @@ -3118,41 +2981,35 @@ beginseg name "ovl_Obj_Driftice" compress include "build/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.o" - include "build/data/ovl_Obj_Driftice/ovl_Obj_Driftice.data.o" - include "build/data/ovl_Obj_Driftice/ovl_Obj_Driftice.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Driftice/ovl_Obj_Driftice_reloc.o" endseg beginseg name "ovl_En_Look_Nuts" compress include "build/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.o" - include "build/data/ovl_En_Look_Nuts/ovl_En_Look_Nuts.data.o" - include "build/data/ovl_En_Look_Nuts/ovl_En_Look_Nuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Look_Nuts/ovl_En_Look_Nuts_reloc.o" endseg beginseg name "ovl_En_Mushi2" compress include "build/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.o" - include "build/data/ovl_En_Mushi2/ovl_En_Mushi2.data.o" - include "build/data/ovl_En_Mushi2/ovl_En_Mushi2.reloc.o" + include "build/src/overlays/actors/ovl_En_Mushi2/ovl_En_Mushi2_reloc.o" endseg 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 name "ovl_En_Mm3" compress include "build/src/overlays/actors/ovl_En_Mm3/z_en_mm3.o" - include "build/data/ovl_En_Mm3/ovl_En_Mm3.data.o" - include "build/data/ovl_En_Mm3/ovl_En_Mm3.reloc.o" + include "build/src/overlays/actors/ovl_En_Mm3/ovl_En_Mm3_reloc.o" endseg beginseg @@ -3175,16 +3032,14 @@ beginseg name "ovl_En_Pr2" compress include "build/src/overlays/actors/ovl_En_Pr2/z_en_pr2.o" - include "build/data/ovl_En_Pr2/ovl_En_Pr2.data.o" - include "build/data/ovl_En_Pr2/ovl_En_Pr2.reloc.o" + include "build/src/overlays/actors/ovl_En_Pr2/ovl_En_Pr2_reloc.o" endseg beginseg name "ovl_En_Prz" compress include "build/src/overlays/actors/ovl_En_Prz/z_en_prz.o" - include "build/data/ovl_En_Prz/ovl_En_Prz.data.o" - include "build/data/ovl_En_Prz/ovl_En_Prz.reloc.o" + include "build/src/overlays/actors/ovl_En_Prz/ovl_En_Prz_reloc.o" endseg beginseg @@ -3231,8 +3086,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 @@ -3246,17 +3104,14 @@ 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 name "ovl_En_Test6" compress include "build/src/overlays/actors/ovl_En_Test6/z_en_test6.o" - include "build/data/ovl_En_Test6/ovl_En_Test6.data.o" - include "build/data/ovl_En_Test6/ovl_En_Test6.bss.o" - include "build/data/ovl_En_Test6/ovl_En_Test6.reloc.o" + include "build/src/overlays/actors/ovl_En_Test6/ovl_En_Test6_reloc.o" endseg beginseg @@ -3295,25 +3150,21 @@ 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 name "ovl_Dm_Char00" compress include "build/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.o" - include "build/data/ovl_Dm_Char00/ovl_Dm_Char00.data.o" - include "build/data/ovl_Dm_Char00/ovl_Dm_Char00.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Char00/ovl_Dm_Char00_reloc.o" endseg beginseg name "ovl_Dm_Char01" compress include "build/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.o" - include "build/data/ovl_Dm_Char01/ovl_Dm_Char01.data.o" - include "build/data/ovl_Dm_Char01/ovl_Dm_Char01.bss.o" - include "build/data/ovl_Dm_Char01/ovl_Dm_Char01.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Char01/ovl_Dm_Char01_reloc.o" endseg beginseg @@ -3344,8 +3195,7 @@ beginseg name "ovl_Dm_Char05" compress include "build/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.o" - include "build/data/ovl_Dm_Char05/ovl_Dm_Char05.data.o" - include "build/data/ovl_Dm_Char05/ovl_Dm_Char05.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Char05/ovl_Dm_Char05_reloc.o" endseg beginseg @@ -3383,8 +3233,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 @@ -3407,16 +3256,14 @@ beginseg name "ovl_En_Guard_Nuts" compress include "build/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.o" - include "build/data/ovl_En_Guard_Nuts/ovl_En_Guard_Nuts.data.o" - include "build/data/ovl_En_Guard_Nuts/ovl_En_Guard_Nuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Guard_Nuts/ovl_En_Guard_Nuts_reloc.o" endseg beginseg name "ovl_Bg_Hakugin_Bombwall" compress include "build/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.o" - include "build/data/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall.data.o" - include "build/data/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/ovl_Bg_Hakugin_Bombwall_reloc.o" endseg beginseg @@ -3470,8 +3317,7 @@ beginseg name "ovl_En_Bigokuta" compress include "build/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.o" - include "build/data/ovl_En_Bigokuta/ovl_En_Bigokuta.data.o" - include "build/data/ovl_En_Bigokuta/ovl_En_Bigokuta.reloc.o" + include "build/src/overlays/actors/ovl_En_Bigokuta/ovl_En_Bigokuta_reloc.o" endseg beginseg @@ -3527,8 +3373,7 @@ beginseg name "ovl_Effect_Ss_Sbn" compress include "build/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.o" - include "build/data/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn.data.o" - include "build/data/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Sbn/ovl_Effect_Ss_Sbn_reloc.o" endseg beginseg @@ -3559,8 +3404,7 @@ beginseg name "ovl_Bg_Open_Spot" compress include "build/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.o" - include "build/data/ovl_Bg_Open_Spot/ovl_Bg_Open_Spot.data.o" - include "build/data/ovl_Bg_Open_Spot/ovl_Bg_Open_Spot.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Open_Spot/ovl_Bg_Open_Spot_reloc.o" endseg beginseg @@ -3581,8 +3425,7 @@ beginseg name "ovl_En_Elforg" compress include "build/src/overlays/actors/ovl_En_Elforg/z_en_elforg.o" - include "build/data/ovl_En_Elforg/ovl_En_Elforg.data.o" - include "build/data/ovl_En_Elforg/ovl_En_Elforg.reloc.o" + include "build/src/overlays/actors/ovl_En_Elforg/ovl_En_Elforg_reloc.o" endseg beginseg @@ -3596,24 +3439,21 @@ beginseg name "ovl_En_Fu_Mato" compress include "build/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.o" - include "build/data/ovl_En_Fu_Mato/ovl_En_Fu_Mato.data.o" - include "build/data/ovl_En_Fu_Mato/ovl_En_Fu_Mato.reloc.o" + include "build/src/overlays/actors/ovl_En_Fu_Mato/ovl_En_Fu_Mato_reloc.o" endseg beginseg name "ovl_En_Fu_Kago" compress include "build/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.o" - include "build/data/ovl_En_Fu_Kago/ovl_En_Fu_Kago.data.o" - include "build/data/ovl_En_Fu_Kago/ovl_En_Fu_Kago.reloc.o" + include "build/src/overlays/actors/ovl_En_Fu_Kago/ovl_En_Fu_Kago_reloc.o" endseg beginseg name "ovl_En_Osn" compress include "build/src/overlays/actors/ovl_En_Osn/z_en_osn.o" - include "build/data/ovl_En_Osn/ovl_En_Osn.data.o" - include "build/data/ovl_En_Osn/ovl_En_Osn.reloc.o" + include "build/src/overlays/actors/ovl_En_Osn/ovl_En_Osn_reloc.o" endseg beginseg @@ -3627,8 +3467,7 @@ beginseg name "ovl_En_Trt2" compress include "build/src/overlays/actors/ovl_En_Trt2/z_en_trt2.o" - include "build/data/ovl_En_Trt2/ovl_En_Trt2.data.o" - include "build/data/ovl_En_Trt2/ovl_En_Trt2.reloc.o" + include "build/src/overlays/actors/ovl_En_Trt2/ovl_En_Trt2_reloc.o" endseg beginseg @@ -3649,8 +3488,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 @@ -3704,8 +3542,7 @@ beginseg name "ovl_En_Tsn" compress include "build/src/overlays/actors/ovl_En_Tsn/z_en_tsn.o" - include "build/data/ovl_En_Tsn/ovl_En_Tsn.data.o" - include "build/data/ovl_En_Tsn/ovl_En_Tsn.reloc.o" + include "build/src/overlays/actors/ovl_En_Tsn/ovl_En_Tsn_reloc.o" endseg beginseg @@ -3727,8 +3564,7 @@ beginseg name "ovl_En_Shn" compress include "build/src/overlays/actors/ovl_En_Shn/z_en_shn.o" - include "build/data/ovl_En_Shn/ovl_En_Shn.data.o" - include "build/data/ovl_En_Shn/ovl_En_Shn.reloc.o" + include "build/src/overlays/actors/ovl_En_Shn/ovl_En_Shn_reloc.o" endseg beginseg @@ -3743,8 +3579,7 @@ beginseg name "ovl_Obj_Bigicicle" compress include "build/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.o" - include "build/data/ovl_Obj_Bigicicle/ovl_Obj_Bigicicle.data.o" - include "build/data/ovl_Obj_Bigicicle/ovl_Obj_Bigicicle.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Bigicicle/ovl_Obj_Bigicicle_reloc.o" endseg beginseg @@ -3759,9 +3594,7 @@ beginseg name "ovl_En_Tk" compress include "build/src/overlays/actors/ovl_En_Tk/z_en_tk.o" - include "build/data/ovl_En_Tk/ovl_En_Tk.data.o" - include "build/data/ovl_En_Tk/ovl_En_Tk.bss.o" - include "build/data/ovl_En_Tk/ovl_En_Tk.reloc.o" + include "build/src/overlays/actors/ovl_En_Tk/ovl_En_Tk_reloc.o" endseg beginseg @@ -3783,9 +3616,7 @@ beginseg name "ovl_En_Test7" compress include "build/src/overlays/actors/ovl_En_Test7/z_en_test7.o" - include "build/data/ovl_En_Test7/ovl_En_Test7.data.o" - include "build/data/ovl_En_Test7/ovl_En_Test7.bss.o" - include "build/data/ovl_En_Test7/ovl_En_Test7.reloc.o" + include "build/src/overlays/actors/ovl_En_Test7/ovl_En_Test7_reloc.o" endseg beginseg @@ -3839,16 +3670,14 @@ beginseg name "ovl_En_Pm" compress include "build/src/overlays/actors/ovl_En_Pm/z_en_pm.o" - include "build/data/ovl_En_Pm/ovl_En_Pm.data.o" - include "build/data/ovl_En_Pm/ovl_En_Pm.reloc.o" + include "build/src/overlays/actors/ovl_En_Pm/ovl_En_Pm_reloc.o" endseg beginseg name "ovl_En_Gakufu" compress include "build/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.o" - include "build/data/ovl_En_Gakufu/ovl_En_Gakufu.data.o" - include "build/data/ovl_En_Gakufu/ovl_En_Gakufu.reloc.o" + include "build/src/overlays/actors/ovl_En_Gakufu/ovl_En_Gakufu_reloc.o" endseg beginseg @@ -3871,16 +3700,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 @@ -3894,8 +3721,7 @@ 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" - include "build/data/ovl_Obj_Snowball/ovl_Obj_Snowball.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Snowball/ovl_Obj_Snowball_reloc.o" endseg beginseg @@ -3910,8 +3736,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 @@ -3940,33 +3765,28 @@ beginseg name "ovl_Obj_Dhouse" compress include "build/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.o" - include "build/data/ovl_Obj_Dhouse/ovl_Obj_Dhouse.data.o" - include "build/data/ovl_Obj_Dhouse/ovl_Obj_Dhouse.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Dhouse/ovl_Obj_Dhouse_reloc.o" endseg beginseg name "ovl_Obj_Hakaisi" compress include "build/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.o" - include "build/data/ovl_Obj_Hakaisi/ovl_Obj_Hakaisi.data.o" - include "build/data/ovl_Obj_Hakaisi/ovl_Obj_Hakaisi.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Hakaisi/ovl_Obj_Hakaisi_reloc.o" endseg beginseg name "ovl_Bg_Hakugin_Switch" compress include "build/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.o" - include "build/data/ovl_Bg_Hakugin_Switch/ovl_Bg_Hakugin_Switch.data.o" - include "build/data/ovl_Bg_Hakugin_Switch/ovl_Bg_Hakugin_Switch.bss.o" - include "build/data/ovl_Bg_Hakugin_Switch/ovl_Bg_Hakugin_Switch.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Hakugin_Switch/ovl_Bg_Hakugin_Switch_reloc.o" endseg beginseg name "ovl_En_Snowman" compress include "build/src/overlays/actors/ovl_En_Snowman/z_en_snowman.o" - include "build/data/ovl_En_Snowman/ovl_En_Snowman.data.o" - include "build/data/ovl_En_Snowman/ovl_En_Snowman.reloc.o" + include "build/src/overlays/actors/ovl_En_Snowman/ovl_En_Snowman_reloc.o" endseg beginseg @@ -3980,8 +3800,7 @@ beginseg name "ovl_En_Po_Sisters" compress include "build/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.o" - include "build/data/ovl_En_Po_Sisters/ovl_En_Po_Sisters.data.o" - include "build/data/ovl_En_Po_Sisters/ovl_En_Po_Sisters.reloc.o" + include "build/src/overlays/actors/ovl_En_Po_Sisters/ovl_En_Po_Sisters_reloc.o" endseg beginseg @@ -3996,24 +3815,21 @@ beginseg name "ovl_En_Hakurock" compress include "build/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.o" - include "build/data/ovl_En_Hakurock/ovl_En_Hakurock.data.o" - include "build/data/ovl_En_Hakurock/ovl_En_Hakurock.reloc.o" + include "build/src/overlays/actors/ovl_En_Hakurock/ovl_En_Hakurock_reloc.o" endseg beginseg name "ovl_En_Hanabi" compress include "build/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.o" - include "build/data/ovl_En_Hanabi/ovl_En_Hanabi.data.o" - include "build/data/ovl_En_Hanabi/ovl_En_Hanabi.reloc.o" + include "build/src/overlays/actors/ovl_En_Hanabi/ovl_En_Hanabi_reloc.o" endseg 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 @@ -4028,16 +3844,14 @@ beginseg name "ovl_En_Racedog" compress include "build/src/overlays/actors/ovl_En_Racedog/z_en_racedog.o" - include "build/data/ovl_En_Racedog/ovl_En_Racedog.data.o" - include "build/data/ovl_En_Racedog/ovl_En_Racedog.reloc.o" + include "build/src/overlays/actors/ovl_En_Racedog/ovl_En_Racedog_reloc.o" endseg beginseg name "ovl_En_Kendo_Js" compress include "build/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.o" - include "build/data/ovl_En_Kendo_Js/ovl_En_Kendo_Js.data.o" - include "build/data/ovl_En_Kendo_Js/ovl_En_Kendo_Js.reloc.o" + include "build/src/overlays/actors/ovl_En_Kendo_Js/ovl_En_Kendo_Js_reloc.o" endseg beginseg @@ -4052,8 +3866,7 @@ beginseg name "ovl_En_Fish2" compress include "build/src/overlays/actors/ovl_En_Fish2/z_en_fish2.o" - include "build/data/ovl_En_Fish2/ovl_En_Fish2.data.o" - include "build/data/ovl_En_Fish2/ovl_En_Fish2.reloc.o" + include "build/src/overlays/actors/ovl_En_Fish2/ovl_En_Fish2_reloc.o" endseg beginseg @@ -4075,56 +3888,53 @@ beginseg name "ovl_Obj_Spidertent" compress include "build/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.o" - include "build/data/ovl_Obj_Spidertent/ovl_Obj_Spidertent.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Obj_Spidertent/ovl_Obj_Spidertent_reloc.o" +#else include "build/data/ovl_Obj_Spidertent/ovl_Obj_Spidertent.reloc.o" +#endif endseg beginseg name "ovl_En_Zoraegg" compress include "build/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.o" - include "build/data/ovl_En_Zoraegg/ovl_En_Zoraegg.data.o" - include "build/data/ovl_En_Zoraegg/ovl_En_Zoraegg.reloc.o" + include "build/src/overlays/actors/ovl_En_Zoraegg/ovl_En_Zoraegg_reloc.o" endseg beginseg name "ovl_En_Kbt" compress include "build/src/overlays/actors/ovl_En_Kbt/z_en_kbt.o" - include "build/data/ovl_En_Kbt/ovl_En_Kbt.data.o" - include "build/data/ovl_En_Kbt/ovl_En_Kbt.reloc.o" + include "build/src/overlays/actors/ovl_En_Kbt/ovl_En_Kbt_reloc.o" endseg beginseg name "ovl_En_Gg" compress include "build/src/overlays/actors/ovl_En_Gg/z_en_gg.o" - include "build/data/ovl_En_Gg/ovl_En_Gg.data.o" - include "build/data/ovl_En_Gg/ovl_En_Gg.reloc.o" + include "build/src/overlays/actors/ovl_En_Gg/ovl_En_Gg_reloc.o" endseg beginseg name "ovl_En_Maruta" compress include "build/src/overlays/actors/ovl_En_Maruta/z_en_maruta.o" - include "build/data/ovl_En_Maruta/ovl_En_Maruta.data.o" - include "build/data/ovl_En_Maruta/ovl_En_Maruta.reloc.o" + include "build/src/overlays/actors/ovl_En_Maruta/ovl_En_Maruta_reloc.o" endseg beginseg name "ovl_Obj_Snowball2" compress include "build/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.o" - include "build/data/ovl_Obj_Snowball2/ovl_Obj_Snowball2.data.o" - include "build/data/ovl_Obj_Snowball2/ovl_Obj_Snowball2.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Snowball2/ovl_Obj_Snowball2_reloc.o" endseg beginseg name "ovl_En_Gg2" compress include "build/src/overlays/actors/ovl_En_Gg2/z_en_gg2.o" - include "build/data/ovl_En_Gg2/ovl_En_Gg2.data.o" - include "build/data/ovl_En_Gg2/ovl_En_Gg2.reloc.o" + include "build/src/overlays/actors/ovl_En_Gg2/ovl_En_Gg2_reloc.o" endseg beginseg @@ -4152,8 +3962,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 @@ -4174,8 +3983,7 @@ beginseg name "ovl_En_Gk" compress include "build/src/overlays/actors/ovl_En_Gk/z_en_gk.o" - include "build/data/ovl_En_Gk/ovl_En_Gk.data.o" - include "build/data/ovl_En_Gk/ovl_En_Gk.reloc.o" + include "build/src/overlays/actors/ovl_En_Gk/ovl_En_Gk_reloc.o" endseg beginseg @@ -4198,25 +4006,21 @@ beginseg name "ovl_En_Ot" compress include "build/src/overlays/actors/ovl_En_Ot/z_en_ot.o" - include "build/data/ovl_En_Ot/ovl_En_Ot.data.o" - include "build/data/ovl_En_Ot/ovl_En_Ot.bss.o" - include "build/data/ovl_En_Ot/ovl_En_Ot.reloc.o" + include "build/src/overlays/actors/ovl_En_Ot/ovl_En_Ot_reloc.o" endseg beginseg name "ovl_En_Dragon" compress include "build/src/overlays/actors/ovl_En_Dragon/z_en_dragon.o" - include "build/data/ovl_En_Dragon/ovl_En_Dragon.data.o" - include "build/data/ovl_En_Dragon/ovl_En_Dragon.reloc.o" + include "build/src/overlays/actors/ovl_En_Dragon/ovl_En_Dragon_reloc.o" endseg beginseg name "ovl_Obj_Dora" compress include "build/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.o" - include "build/data/ovl_Obj_Dora/ovl_Obj_Dora.data.o" - include "build/data/ovl_Obj_Dora/ovl_Obj_Dora.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Dora/ovl_Obj_Dora_reloc.o" endseg beginseg @@ -4230,32 +4034,32 @@ beginseg name "ovl_Obj_Kendo_Kanban" compress include "build/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.o" - include "build/data/ovl_Obj_Kendo_Kanban/ovl_Obj_Kendo_Kanban.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Obj_Kendo_Kanban/ovl_Obj_Kendo_Kanban_reloc.o" +#else include "build/data/ovl_Obj_Kendo_Kanban/ovl_Obj_Kendo_Kanban.reloc.o" +#endif endseg beginseg name "ovl_Obj_Hariko" compress include "build/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.o" - include "build/data/ovl_Obj_Hariko/ovl_Obj_Hariko.data.o" - include "build/data/ovl_Obj_Hariko/ovl_Obj_Hariko.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Hariko/ovl_Obj_Hariko_reloc.o" endseg beginseg name "ovl_En_Sth" compress include "build/src/overlays/actors/ovl_En_Sth/z_en_sth.o" - include "build/data/ovl_En_Sth/ovl_En_Sth.data.o" - include "build/data/ovl_En_Sth/ovl_En_Sth.reloc.o" + include "build/src/overlays/actors/ovl_En_Sth/ovl_En_Sth_reloc.o" endseg beginseg name "ovl_Bg_Sinkai_Kabe" compress include "build/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.o" - include "build/data/ovl_Bg_Sinkai_Kabe/ovl_Bg_Sinkai_Kabe.data.o" - include "build/data/ovl_Bg_Sinkai_Kabe/ovl_Bg_Sinkai_Kabe.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Sinkai_Kabe/ovl_Bg_Sinkai_Kabe_reloc.o" endseg beginseg @@ -4292,32 +4096,28 @@ beginseg name "ovl_Bg_Kin2_Shelf" compress include "build/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.o" - include "build/data/ovl_Bg_Kin2_Shelf/ovl_Bg_Kin2_Shelf.data.o" - include "build/data/ovl_Bg_Kin2_Shelf/ovl_Bg_Kin2_Shelf.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Kin2_Shelf/ovl_Bg_Kin2_Shelf_reloc.o" endseg 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 name "ovl_En_Jg" compress include "build/src/overlays/actors/ovl_En_Jg/z_en_jg.o" - include "build/data/ovl_En_Jg/ovl_En_Jg.data.o" - include "build/data/ovl_En_Jg/ovl_En_Jg.reloc.o" + include "build/src/overlays/actors/ovl_En_Jg/ovl_En_Jg_reloc.o" endseg beginseg name "ovl_En_Tru_Mt" compress include "build/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.o" - include "build/data/ovl_En_Tru_Mt/ovl_En_Tru_Mt.data.o" - include "build/data/ovl_En_Tru_Mt/ovl_En_Tru_Mt.reloc.o" + include "build/src/overlays/actors/ovl_En_Tru_Mt/ovl_En_Tru_Mt_reloc.o" endseg beginseg @@ -4332,8 +4132,7 @@ beginseg name "ovl_En_Neo_Reeba" compress include "build/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.o" - include "build/data/ovl_En_Neo_Reeba/ovl_En_Neo_Reeba.data.o" - include "build/data/ovl_En_Neo_Reeba/ovl_En_Neo_Reeba.reloc.o" + include "build/src/overlays/actors/ovl_En_Neo_Reeba/ovl_En_Neo_Reeba_reloc.o" endseg beginseg @@ -4347,8 +4146,7 @@ beginseg name "ovl_Bg_Ikana_Block" compress include "build/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.o" - include "build/data/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block.data.o" - include "build/data/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Ikana_Block/ovl_Bg_Ikana_Block_reloc.o" endseg beginseg @@ -4363,25 +4161,21 @@ beginseg name "ovl_Bg_Ikana_Rotaryroom" compress include "build/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.o" - include "build/data/ovl_Bg_Ikana_Rotaryroom/ovl_Bg_Ikana_Rotaryroom.data.o" - include "build/data/ovl_Bg_Ikana_Rotaryroom/ovl_Bg_Ikana_Rotaryroom.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/ovl_Bg_Ikana_Rotaryroom_reloc.o" endseg beginseg name "ovl_Bg_Dblue_Balance" compress include "build/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.o" - include "build/data/ovl_Bg_Dblue_Balance/ovl_Bg_Dblue_Balance.data.o" - include "build/data/ovl_Bg_Dblue_Balance/ovl_Bg_Dblue_Balance.bss.o" - include "build/data/ovl_Bg_Dblue_Balance/ovl_Bg_Dblue_Balance.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Dblue_Balance/ovl_Bg_Dblue_Balance_reloc.o" endseg beginseg name "ovl_Bg_Dblue_Waterfall" compress include "build/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.o" - include "build/data/ovl_Bg_Dblue_Waterfall/ovl_Bg_Dblue_Waterfall.data.o" - include "build/data/ovl_Bg_Dblue_Waterfall/ovl_Bg_Dblue_Waterfall.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Dblue_Waterfall/ovl_Bg_Dblue_Waterfall_reloc.o" endseg beginseg @@ -4441,9 +4235,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 @@ -4458,16 +4250,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 @@ -4481,8 +4271,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 @@ -4521,9 +4310,7 @@ beginseg name "ovl_Obj_Hunsui" compress include "build/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.o" - include "build/data/ovl_Obj_Hunsui/ovl_Obj_Hunsui.data.o" - include "build/data/ovl_Obj_Hunsui/ovl_Obj_Hunsui.bss.o" - include "build/data/ovl_Obj_Hunsui/ovl_Obj_Hunsui.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Hunsui/ovl_Obj_Hunsui_reloc.o" endseg beginseg @@ -4537,33 +4324,32 @@ beginseg name "ovl_Mir_Ray3" compress include "build/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.o" - include "build/data/ovl_Mir_Ray3/ovl_Mir_Ray3.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Mir_Ray3/ovl_Mir_Ray3_reloc.o" +#else include "build/data/ovl_Mir_Ray3/ovl_Mir_Ray3.reloc.o" +#endif endseg beginseg name "ovl_En_Zob" compress include "build/src/overlays/actors/ovl_En_Zob/z_en_zob.o" - include "build/data/ovl_En_Zob/ovl_En_Zob.data.o" - include "build/data/ovl_En_Zob/ovl_En_Zob.reloc.o" + include "build/src/overlays/actors/ovl_En_Zob/ovl_En_Zob_reloc.o" endseg beginseg name "ovl_Elf_Msg6" compress include "build/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.o" - include "build/data/ovl_Elf_Msg6/ovl_Elf_Msg6.data.o" - include "build/data/ovl_Elf_Msg6/ovl_Elf_Msg6.reloc.o" + include "build/src/overlays/actors/ovl_Elf_Msg6/ovl_Elf_Msg6_reloc.o" endseg beginseg name "ovl_Obj_Nozoki" compress include "build/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.o" - include "build/data/ovl_Obj_Nozoki/ovl_Obj_Nozoki.data.o" - include "build/data/ovl_Obj_Nozoki/ovl_Obj_Nozoki.bss.o" - include "build/data/ovl_Obj_Nozoki/ovl_Obj_Nozoki.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Nozoki/ovl_Obj_Nozoki_reloc.o" endseg beginseg @@ -4584,8 +4370,7 @@ beginseg name "ovl_En_Baba" compress include "build/src/overlays/actors/ovl_En_Baba/z_en_baba.o" - include "build/data/ovl_En_Baba/ovl_En_Baba.data.o" - include "build/data/ovl_En_Baba/ovl_En_Baba.reloc.o" + include "build/src/overlays/actors/ovl_En_Baba/ovl_En_Baba_reloc.o" endseg beginseg @@ -4607,74 +4392,63 @@ beginseg name "ovl_En_Kujiya" compress include "build/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.o" - include "build/data/ovl_En_Kujiya/ovl_En_Kujiya.data.o" - include "build/data/ovl_En_Kujiya/ovl_En_Kujiya.reloc.o" + include "build/src/overlays/actors/ovl_En_Kujiya/ovl_En_Kujiya_reloc.o" endseg 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 name "ovl_Obj_Kinoko" compress include "build/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.o" - include "build/data/ovl_Obj_Kinoko/ovl_Obj_Kinoko.data.o" - include "build/data/ovl_Obj_Kinoko/ovl_Obj_Kinoko.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Kinoko/ovl_Obj_Kinoko_reloc.o" endseg beginseg name "ovl_Obj_Yasi" compress include "build/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.o" - include "build/data/ovl_Obj_Yasi/ovl_Obj_Yasi.data.o" - include "build/data/ovl_Obj_Yasi/ovl_Obj_Yasi.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Yasi/ovl_Obj_Yasi_reloc.o" endseg beginseg name "ovl_En_Tanron1" compress include "build/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.o" - include "build/data/ovl_En_Tanron1/ovl_En_Tanron1.data.o" - include "build/data/ovl_En_Tanron1/ovl_En_Tanron1.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron1/ovl_En_Tanron1_reloc.o" endseg beginseg name "ovl_En_Tanron2" compress include "build/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.o" - include "build/data/ovl_En_Tanron2/ovl_En_Tanron2.data.o" - include "build/data/ovl_En_Tanron2/ovl_En_Tanron2.bss.o" - include "build/data/ovl_En_Tanron2/ovl_En_Tanron2.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron2/ovl_En_Tanron2_reloc.o" endseg 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 name "ovl_Obj_Chan" compress include "build/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.o" - include "build/data/ovl_Obj_Chan/ovl_Obj_Chan.data.o" - include "build/data/ovl_Obj_Chan/ovl_Obj_Chan.bss.o" - include "build/data/ovl_Obj_Chan/ovl_Obj_Chan.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Chan/ovl_Obj_Chan_reloc.o" endseg beginseg name "ovl_En_Zos" compress include "build/src/overlays/actors/ovl_En_Zos/z_en_zos.o" - include "build/data/ovl_En_Zos/ovl_En_Zos.data.o" - include "build/data/ovl_En_Zos/ovl_En_Zos.reloc.o" + include "build/src/overlays/actors/ovl_En_Zos/ovl_En_Zos_reloc.o" endseg beginseg @@ -4697,25 +4471,21 @@ beginseg name "ovl_En_Ja" compress include "build/src/overlays/actors/ovl_En_Ja/z_en_ja.o" - include "build/data/ovl_En_Ja/ovl_En_Ja.data.o" - include "build/data/ovl_En_Ja/ovl_En_Ja.reloc.o" + include "build/src/overlays/actors/ovl_En_Ja/ovl_En_Ja_reloc.o" endseg beginseg name "ovl_Bg_F40_Block" compress include "build/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.o" - include "build/data/ovl_Bg_F40_Block/ovl_Bg_F40_Block.data.o" - include "build/data/ovl_Bg_F40_Block/ovl_Bg_F40_Block.reloc.o" + include "build/src/overlays/actors/ovl_Bg_F40_Block/ovl_Bg_F40_Block_reloc.o" endseg beginseg name "ovl_Bg_F40_Switch" compress include "build/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.o" - include "build/data/ovl_Bg_F40_Switch/ovl_Bg_F40_Switch.data.o" - include "build/data/ovl_Bg_F40_Switch/ovl_Bg_F40_Switch.bss.o" - include "build/data/ovl_Bg_F40_Switch/ovl_Bg_F40_Switch.reloc.o" + include "build/src/overlays/actors/ovl_Bg_F40_Switch/ovl_Bg_F40_Switch_reloc.o" endseg beginseg @@ -4754,24 +4524,21 @@ beginseg name "ovl_Oceff_Wipe6" compress include "build/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.o" - include "build/data/ovl_Oceff_Wipe6/ovl_Oceff_Wipe6.data.o" - include "build/data/ovl_Oceff_Wipe6/ovl_Oceff_Wipe6.reloc.o" + include "build/src/overlays/actors/ovl_Oceff_Wipe6/ovl_Oceff_Wipe6_reloc.o" endseg beginseg name "ovl_En_Scopenuts" compress include "build/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.o" - include "build/data/ovl_En_Scopenuts/ovl_En_Scopenuts.data.o" - include "build/data/ovl_En_Scopenuts/ovl_En_Scopenuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Scopenuts/ovl_En_Scopenuts_reloc.o" endseg beginseg name "ovl_En_Scopecrow" compress include "build/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.o" - include "build/data/ovl_En_Scopecrow/ovl_En_Scopecrow.data.o" - include "build/data/ovl_En_Scopecrow/ovl_En_Scopecrow.reloc.o" + include "build/src/overlays/actors/ovl_En_Scopecrow/ovl_En_Scopecrow_reloc.o" endseg beginseg @@ -4803,24 +4570,21 @@ beginseg name "ovl_En_Hgo" compress include "build/src/overlays/actors/ovl_En_Hgo/z_en_hgo.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.data.o" - include "build/data/ovl_En_Hgo/ovl_En_Hgo.reloc.o" + include "build/src/overlays/actors/ovl_En_Hgo/ovl_En_Hgo_reloc.o" endseg beginseg name "ovl_En_Zov" compress include "build/src/overlays/actors/ovl_En_Zov/z_en_zov.o" - include "build/data/ovl_En_Zov/ovl_En_Zov.data.o" - include "build/data/ovl_En_Zov/ovl_En_Zov.reloc.o" + include "build/src/overlays/actors/ovl_En_Zov/ovl_En_Zov_reloc.o" endseg beginseg name "ovl_En_Ah" compress include "build/src/overlays/actors/ovl_En_Ah/z_en_ah.o" - include "build/data/ovl_En_Ah/ovl_En_Ah.data.o" - include "build/data/ovl_En_Ah/ovl_En_Ah.reloc.o" + include "build/src/overlays/actors/ovl_En_Ah/ovl_En_Ah_reloc.o" endseg beginseg @@ -4834,8 +4598,11 @@ beginseg name "ovl_Bg_Ikana_Bombwall" compress include "build/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.o" - include "build/data/ovl_Bg_Ikana_Bombwall/ovl_Bg_Ikana_Bombwall.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Bg_Ikana_Bombwall/ovl_Bg_Ikana_Bombwall_reloc.o" +#else include "build/data/ovl_Bg_Ikana_Bombwall/ovl_Bg_Ikana_Bombwall.reloc.o" +#endif endseg beginseg @@ -4908,40 +4675,35 @@ beginseg name "ovl_En_Hidden_Nuts" compress include "build/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.o" - include "build/data/ovl_En_Hidden_Nuts/ovl_En_Hidden_Nuts.data.o" - include "build/data/ovl_En_Hidden_Nuts/ovl_En_Hidden_Nuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Hidden_Nuts/ovl_En_Hidden_Nuts_reloc.o" endseg beginseg name "ovl_En_Zow" compress include "build/src/overlays/actors/ovl_En_Zow/z_en_zow.o" - include "build/data/ovl_En_Zow/ovl_En_Zow.data.o" - include "build/data/ovl_En_Zow/ovl_En_Zow.reloc.o" + include "build/src/overlays/actors/ovl_En_Zow/ovl_En_Zow_reloc.o" endseg 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 name "ovl_En_Al" compress include "build/src/overlays/actors/ovl_En_Al/z_en_al.o" - include "build/data/ovl_En_Al/ovl_En_Al.data.o" - include "build/data/ovl_En_Al/ovl_En_Al.reloc.o" + include "build/src/overlays/actors/ovl_En_Al/ovl_En_Al_reloc.o" endseg beginseg name "ovl_En_Tab" compress include "build/src/overlays/actors/ovl_En_Tab/z_en_tab.o" - include "build/data/ovl_En_Tab/ovl_En_Tab.data.o" - include "build/data/ovl_En_Tab/ovl_En_Tab.reloc.o" + include "build/src/overlays/actors/ovl_En_Tab/ovl_En_Tab_reloc.o" endseg beginseg @@ -4956,32 +4718,28 @@ 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 name "ovl_En_Tanron4" compress include "build/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.o" - include "build/data/ovl_En_Tanron4/ovl_En_Tanron4.data.o" - include "build/data/ovl_En_Tanron4/ovl_En_Tanron4.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron4/ovl_En_Tanron4_reloc.o" endseg beginseg name "ovl_En_Tanron5" compress include "build/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.o" - include "build/data/ovl_En_Tanron5/ovl_En_Tanron5.data.o" - include "build/data/ovl_En_Tanron5/ovl_En_Tanron5.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron5/ovl_En_Tanron5_reloc.o" endseg beginseg @@ -5016,16 +4774,14 @@ beginseg name "ovl_En_Heishi" compress include "build/src/overlays/actors/ovl_En_Heishi/z_en_heishi.o" - include "build/data/ovl_En_Heishi/ovl_En_Heishi.data.o" - include "build/data/ovl_En_Heishi/ovl_En_Heishi.reloc.o" + include "build/src/overlays/actors/ovl_En_Heishi/ovl_En_Heishi_reloc.o" endseg beginseg name "ovl_En_Demo_heishi" compress include "build/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.o" - include "build/data/ovl_En_Demo_heishi/ovl_En_Demo_heishi.data.o" - include "build/data/ovl_En_Demo_heishi/ovl_En_Demo_heishi.reloc.o" + include "build/src/overlays/actors/ovl_En_Demo_heishi/ovl_En_Demo_heishi_reloc.o" endseg beginseg @@ -5071,8 +4827,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 @@ -5087,25 +4842,21 @@ beginseg name "ovl_En_Ig" compress include "build/src/overlays/actors/ovl_En_Ig/z_en_ig.o" - include "build/data/ovl_En_Ig/ovl_En_Ig.data.o" - include "build/data/ovl_En_Ig/ovl_En_Ig.reloc.o" + include "build/src/overlays/actors/ovl_En_Ig/ovl_En_Ig_reloc.o" endseg beginseg name "ovl_En_Rg" compress include "build/src/overlays/actors/ovl_En_Rg/z_en_rg.o" - include "build/data/ovl_En_Rg/ovl_En_Rg.data.o" - include "build/data/ovl_En_Rg/ovl_En_Rg.bss.o" - include "build/data/ovl_En_Rg/ovl_En_Rg.reloc.o" + include "build/src/overlays/actors/ovl_En_Rg/ovl_En_Rg_reloc.o" endseg beginseg name "ovl_En_Osk" compress include "build/src/overlays/actors/ovl_En_Osk/z_en_osk.o" - include "build/data/ovl_En_Osk/ovl_En_Osk.data.o" - include "build/data/ovl_En_Osk/ovl_En_Osk.reloc.o" + include "build/src/overlays/actors/ovl_En_Osk/ovl_En_Osk_reloc.o" endseg beginseg @@ -5120,8 +4871,7 @@ beginseg name "ovl_En_Yb" compress include "build/src/overlays/actors/ovl_En_Yb/z_en_yb.o" - include "build/data/ovl_En_Yb/ovl_En_Yb.data.o" - include "build/data/ovl_En_Yb/ovl_En_Yb.reloc.o" + include "build/src/overlays/actors/ovl_En_Yb/ovl_En_Yb_reloc.o" endseg beginseg @@ -5151,32 +4901,28 @@ 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" + include "build/src/overlays/actors/ovl_En_Bomjima/ovl_En_Bomjima_reloc.o" endseg 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 name "ovl_En_Bombers" compress include "build/src/overlays/actors/ovl_En_Bombers/z_en_bombers.o" - include "build/data/ovl_En_Bombers/ovl_En_Bombers.data.o" - include "build/data/ovl_En_Bombers/ovl_En_Bombers.reloc.o" + include "build/src/overlays/actors/ovl_En_Bombers/ovl_En_Bombers_reloc.o" endseg beginseg name "ovl_En_Bombers2" compress include "build/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.o" - include "build/data/ovl_En_Bombers2/ovl_En_Bombers2.data.o" - include "build/data/ovl_En_Bombers2/ovl_En_Bombers2.reloc.o" + include "build/src/overlays/actors/ovl_En_Bombers2/ovl_En_Bombers2_reloc.o" endseg beginseg @@ -5243,8 +4989,7 @@ beginseg name "ovl_Obj_Kzsaku" compress include "build/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.o" - include "build/data/ovl_Obj_Kzsaku/ovl_Obj_Kzsaku.data.o" - include "build/data/ovl_Obj_Kzsaku/ovl_Obj_Kzsaku.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Kzsaku/ovl_Obj_Kzsaku_reloc.o" endseg beginseg @@ -5289,8 +5034,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,8 +5048,7 @@ beginseg name "ovl_En_Jgame_Tsn" compress include "build/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.o" - include "build/data/ovl_En_Jgame_Tsn/ovl_En_Jgame_Tsn.data.o" - include "build/data/ovl_En_Jgame_Tsn/ovl_En_Jgame_Tsn.reloc.o" + include "build/src/overlays/actors/ovl_En_Jgame_Tsn/ovl_En_Jgame_Tsn_reloc.o" endseg beginseg @@ -5320,17 +5063,14 @@ 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 name "ovl_Demo_Syoten" compress include "build/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.o" - include "build/data/ovl_Demo_Syoten/ovl_Demo_Syoten.data.o" - include "build/data/ovl_Demo_Syoten/ovl_Demo_Syoten.reloc.o" + include "build/src/overlays/actors/ovl_Demo_Syoten/ovl_Demo_Syoten_reloc.o" endseg beginseg @@ -5401,8 +5141,7 @@ beginseg name "ovl_Dm_An" compress include "build/src/overlays/actors/ovl_Dm_An/z_dm_an.o" - include "build/data/ovl_Dm_An/ovl_Dm_An.data.o" - include "build/data/ovl_Dm_An/ovl_Dm_An.reloc.o" + include "build/src/overlays/actors/ovl_Dm_An/ovl_Dm_An_reloc.o" endseg beginseg @@ -5424,8 +5163,7 @@ beginseg name "ovl_En_Drs" compress include "build/src/overlays/actors/ovl_En_Drs/z_en_drs.o" - include "build/data/ovl_En_Drs/ovl_En_Drs.data.o" - include "build/data/ovl_En_Drs/ovl_En_Drs.reloc.o" + include "build/src/overlays/actors/ovl_En_Drs/ovl_En_Drs_reloc.o" endseg beginseg @@ -5455,8 +5193,7 @@ beginseg name "ovl_En_Hint_Skb" compress include "build/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.o" - include "build/data/ovl_En_Hint_Skb/ovl_En_Hint_Skb.data.o" - include "build/data/ovl_En_Hint_Skb/ovl_En_Hint_Skb.reloc.o" + include "build/src/overlays/actors/ovl_En_Hint_Skb/ovl_En_Hint_Skb_reloc.o" endseg beginseg @@ -5514,8 +5251,7 @@ beginseg name "ovl_Dm_Gm" compress include "build/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.o" - include "build/data/ovl_Dm_Gm/ovl_Dm_Gm.data.o" - include "build/data/ovl_Dm_Gm/ovl_Dm_Gm.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Gm/ovl_Dm_Gm_reloc.o" endseg beginseg @@ -5530,8 +5266,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 @@ -5552,21 +5287,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 @@ -5580,3290 +5318,3759 @@ 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 name "scene_texture_01" compress romalign 0x1000 - include "build/baserom/scene_texture_01.o" + number 6 + include "build/assets/misc/scene_texture_01/scene_texture_01.o" endseg beginseg name "scene_texture_02" compress romalign 0x1000 - include "build/baserom/scene_texture_02.o" + number 6 + include "build/assets/misc/scene_texture_02/scene_texture_02.o" endseg beginseg name "scene_texture_03" compress romalign 0x1000 - include "build/baserom/scene_texture_03.o" + number 6 + include "build/assets/misc/scene_texture_03/scene_texture_03.o" endseg beginseg name "scene_texture_04" compress romalign 0x1000 - include "build/baserom/scene_texture_04.o" + number 6 + include "build/assets/misc/scene_texture_04/scene_texture_04.o" endseg beginseg name "scene_texture_05" compress romalign 0x1000 - include "build/baserom/scene_texture_05.o" + number 6 + include "build/assets/misc/scene_texture_05/scene_texture_05.o" endseg beginseg name "scene_texture_06" compress romalign 0x1000 - include "build/baserom/scene_texture_06.o" + number 6 + include "build/assets/misc/scene_texture_06/scene_texture_06.o" endseg beginseg name "scene_texture_07" compress romalign 0x1000 - include "build/baserom/scene_texture_07.o" + number 6 + include "build/assets/misc/scene_texture_07/scene_texture_07.o" endseg beginseg name "scene_texture_08" compress romalign 0x1000 - include "build/baserom/scene_texture_08.o" + number 6 + include "build/assets/misc/scene_texture_08/scene_texture_08.o" endseg 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 @@ -8878,34 +9085,38 @@ beginseg name "memerrmsg" compress romalign 0x1000 - include "build/baserom/memerrmsg.o" + include "build/assets/misc/memerrmsg/memerrmsg.o" + number 1 endseg beginseg name "locerrmsg" compress romalign 0x1000 - include "build/baserom/locerrmsg.o" + include "build/assets/misc/locerrmsg/locerrmsg.o" + number 1 endseg beginseg name "parameter_static" compress romalign 0x1000 - include "build/baserom/parameter_static.o" + include "build/assets/interface/parameter_static/parameter_static.o" + number 2 endseg beginseg name "week_static" romalign 0x1000 - include "build/baserom/week_static.o" + include "build/assets/interface/week_static/week_static.o" + number 9 endseg 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 @@ -8913,7 +9124,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 @@ -8921,7 +9132,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 @@ -8929,7 +9140,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_O1/viextendvstart.c b/src/boot_O1/viextendvstart.c deleted file mode 100644 index ce9f718d0..000000000 --- a/src/boot_O1/viextendvstart.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "global.h" - -void osViExtendVStart(u32 a0) { - __additional_scanline = a0; -} diff --git a/src/boot_O2/__osMalloc.c b/src/boot_O2/__osMalloc.c index 503c7c25a..24fa6d39e 100644 --- a/src/boot_O2/__osMalloc.c +++ b/src/boot_O2/__osMalloc.c @@ -1,4 +1,8 @@ -#include "global.h" +#include "os_malloc.h" +#include "libc/stdbool.h" +#include "libc/stdint.h" +#include "macros.h" +#include "functions.h" #define FILL_ALLOCBLOCK (1 << 0) #define FILL_FREEBLOCK (1 << 1) @@ -13,9 +17,9 @@ #define BLOCK_FREE_MAGIC (0xEF) #define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF) -extern OSMesg sArenaLockMsg[1]; +OSMesg sArenaLockMsg[1]; -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/D_80099110.s") +void __osMallocAddHeap(Arena* arena, void* heap, size_t size); void ArenaImpl_LockInit(Arena* arena) { osCreateMesgQueue(&arena->lock, sArenaLockMsg, ARRAY_COUNT(sArenaLockMsg)); @@ -45,111 +49,184 @@ ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) { return last; } -void __osMallocInit(Arena* arena, void* start, size_t size) { - bzero(arena, sizeof(*arena)); +/** + * Initializes \p arena to manage the memory region \p heap. + * + * @param arena The Arena to initialize. + * @param heap The memory region to use as heap space. + * @param size The size of the heap. + */ +void __osMallocInit(Arena* arena, void* heap, size_t size) { + bzero(arena, sizeof(Arena)); + ArenaImpl_LockInit(arena); - __osMallocAddBlock(arena, start, size); - arena->isInit = 1; + + __osMallocAddHeap(arena, heap, size); + arena->isInit = true; } -void __osMallocAddBlock(Arena* arena, void* start, s32 size) { - s32 diff; - s32 size2; +// Original name: __osMallocAddBlock +void __osMallocAddHeap(Arena* arena, void* heap, size_t size) { + ptrdiff_t diff; + s32 alignedSize; ArenaNode* firstNode; ArenaNode* lastNode; - if (start != NULL) { - firstNode = (ArenaNode*)ALIGN16((u32)start); - diff = (s32)firstNode - (s32)start; - size2 = (size - diff) & ~0xF; + if (heap == NULL) { + return; + } - if (size2 > (s32)sizeof(ArenaNode)) { - firstNode->next = NULL; - firstNode->prev = NULL; - firstNode->size = size2 - sizeof(ArenaNode); - firstNode->isFree = 1; - firstNode->magic = NODE_MAGIC; - ArenaImpl_Lock(arena); - lastNode = ArenaImpl_GetLastBlock(arena); - if (lastNode == NULL) { - arena->head = firstNode; - arena->start = start; - } else { - firstNode->prev = lastNode; - lastNode->next = firstNode; - } - ArenaImpl_Unlock(arena); + firstNode = (ArenaNode*)ALIGN16((uintptr_t)heap); + diff = (uintptr_t)firstNode - (uintptr_t)heap; + alignedSize = ((s32)size - diff) & ~0xF; + + // If the size of the heap is smaller than sizeof(ArenaNode), then the initialization will silently fail + if (alignedSize > (s32)sizeof(ArenaNode)) { + firstNode->next = NULL; + firstNode->prev = NULL; + firstNode->size = alignedSize - sizeof(ArenaNode); + firstNode->isFree = true; + firstNode->magic = NODE_MAGIC; + + ArenaImpl_Lock(arena); + + lastNode = ArenaImpl_GetLastBlock(arena); + + // Checks if there's already a block + if (lastNode == NULL) { + arena->head = firstNode; + arena->start = heap; + } else { + // Chain the existing block with the new one + firstNode->prev = lastNode; + lastNode->next = firstNode; } + + ArenaImpl_Unlock(arena); } } +/** + * Clears the whole \p arena, invalidating every allocated pointer to it. + * + * @param arena The Arena to clear. + */ void __osMallocCleanup(Arena* arena) { - bzero(arena, sizeof(*arena)); + bzero(arena, sizeof(Arena)); } +/** + * Returns whether or not the \p arena has been initialized. + * + * @param arena The Arena to check. + * @return u8 `true` if the \p arena has been initialized. `false` otherwise. + */ u8 __osMallocIsInitalized(Arena* arena) { return arena->isInit; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * The block of memory will be allocated at the start of the first sufficiently large free block. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using either `__osFree` or + * `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMalloc(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - void* alloc; - u32 blockSize; - alloc = NULL; + void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the head of the arena. iter = arena->head; + // Iterate over the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; - blockSize = ALIGN16(size) + sizeof(ArenaNode); + size_t blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + blockSize); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + blockSize); newNode->next = iter->next; newNode->prev = iter; newNode->size = iter->size - blockSize; - newNode->isFree = 1; + newNode->isFree = true; newNode->magic = NODE_MAGIC; iter->next = newNode; iter->size = size; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->next; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Allocates at least \p size bytes of memory using the given \p arena. + * Unlike __osMalloc, the block of memory will be allocated from the end of the \p arena. + * + * - If there's not enough space in the given \p arena, this function will fail, returning `NULL`. + * - If \p size is zero, then an empty region of memory is returned. + * + * To avoid memory leaks, the returned pointer should be eventually deallocated using `__osFree` or `__osRealloc`. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in] size The size in bytes that will be allocated. + * @return void* On success, the allocated area of the \p arena memory. Otherwise, `NULL`. + */ void* __osMallocR(Arena* arena, size_t size) { ArenaNode* iter; ArenaNode* newNode; - u32 blockSize; + size_t blockSize; void* alloc = NULL; size = ALIGN16(size); + ArenaImpl_Lock(arena); + + // Start iterating from the last block of the arena. iter = ArenaImpl_GetLastBlock(arena); + // Iterate in reverse the arena looking for a big enough space of memory. while (iter != NULL) { if (iter->isFree && iter->size >= size) { - ArenaNode* next; blockSize = ALIGN16(size) + sizeof(ArenaNode); + + // If the block is larger than the requested size, then split it and just use the required size of the + // current block. if (blockSize < iter->size) { - newNode = (ArenaNode*)((u32)iter + (iter->size - size)); + ArenaNode* next; + + newNode = (ArenaNode*)((uintptr_t)iter + (iter->size - size)); newNode->next = iter->next; newNode->prev = iter; newNode->size = size; @@ -157,69 +234,171 @@ void* __osMallocR(Arena* arena, size_t size) { iter->next = newNode; iter->size -= blockSize; + next = newNode->next; - if (next) { + if (next != NULL) { next->prev = newNode; } iter = newNode; } - iter->isFree = 0; - alloc = (void*)((u32)iter + sizeof(ArenaNode)); + iter->isFree = false; + alloc = (void*)((uintptr_t)iter + sizeof(ArenaNode)); break; } iter = iter->prev; } + ArenaImpl_Unlock(arena); return alloc; } +/** + * Deallocates the pointer \p ptr previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc`. + * If \p ptr is `NULL` or it has been already been freed, then this function does nothing. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - Any access to the freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + */ void __osFree(Arena* arena, void* ptr) { ArenaNode* node; ArenaNode* next; ArenaNode* prev; - ArenaNode* newNext; ArenaImpl_Lock(arena); - node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode)); - if (ptr == NULL || (node->magic != NODE_MAGIC) || node->isFree) { - goto end; - } + node = (ArenaNode*)((uintptr_t)ptr - sizeof(ArenaNode)); - next = node->next; - prev = node->prev; - node->isFree = 1; + if (ptr != NULL && node->magic == NODE_MAGIC && !node->isFree) { + next = node->next; + prev = node->prev; + node->isFree = true; - newNext = next; - if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree) { - newNext = next->next; - if (newNext != NULL) { - newNext->prev = node; + // Checks if the next node is contiguous to the current node and if it isn't currently allocated. Then merge the + // two nodes into one. + if ((uintptr_t)next == (uintptr_t)node + sizeof(ArenaNode) + node->size && next->isFree) { + ArenaNode* newNext = next->next; + + if (newNext != NULL) { + newNext->prev = node; + } + + node->size += next->size + sizeof(ArenaNode); + + node->next = newNext; + next = newNext; } - node->size += next->size + sizeof(ArenaNode); + // Checks if the previous node is contiguous to the current node and if it isn't currently allocated. Then merge + // the two nodes into one. + if (prev != NULL && prev->isFree && (uintptr_t)node == (uintptr_t)prev + sizeof(ArenaNode) + prev->size) { + if (next != NULL) { + next->prev = prev; + } - node->next = newNext; - next = newNext; - } - - if (prev != NULL && prev->isFree && (u32)node == (u32)prev + sizeof(ArenaNode) + prev->size) { - if (next) { - next->prev = prev; + prev->next = next; + prev->size += node->size + sizeof(ArenaNode); } - prev->next = next; - prev->size += node->size + sizeof(ArenaNode); } -end: ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osRealloc.s") +/** + * Reallocates the pointer \p ptr. + * \p ptr must be either a pointer previously allocated by `__osMalloc`, `__osMallocR` or `__osRealloc` and + * not freed yet, or a `NULL` pointer. + * + * - If \p ptr is `NULL` a new pointer is allocated. See `__osMalloc` for more details. + * - If \p newSize is 0, then the given pointer is freed and `NULL` is returned. See `__osFree` for more details. + * - If \p newSize is bigger than the currently allocated allocated pointer, then the area of memory is expanded to a + * size big enough to fit the requested size. + * + * - The behaviour is undefined if \p ptr is not a memory region returned by one of the cited allocating + * functions. + * - The behaviour is undefined if \p ptr doesn't correspond to the given \p arena. + * - If the pointer is freed, then any access to the original freed pointer is undefined behaviour. + * + * @param[in, out] arena The specific Arena to be used for the allocation. + * @param[in, out] ptr The allocated memory block to deallocate. + * @param[in] newSize The new requested size. + * @return void* On success, the pointer to the reallocated area of memory. On failure, `NULL` is returned, + * and the original parameter \p ptr remains valid. + */ +void* __osRealloc(Arena* arena, void* ptr, size_t newSize) { + ArenaImpl_Lock(arena); -void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { + (void)"__osRealloc(%08x, %d)\n"; + + if (ptr == NULL) { + // if the `ptr` is NULL, then allocate a new pointer with the specified size + // if newSize is 0, then __osMalloc would return a NULL pointer + ptr = __osMalloc(arena, newSize); + } else if (newSize == 0) { + // if the requested size is zero, then free the pointer + __osFree(arena, ptr); + ptr = NULL; + } else { + size_t diff; + void* newPtr; + // Gets the start of the ArenaNode pointer embedded + ArenaNode* node = (void*)((uintptr_t)ptr - sizeof(ArenaNode)); + + newSize = ALIGN16(newSize); + + // Only reallocate the memory if the new size isn't smaller than the actual node size + if ((newSize != node->size) && (node->size < newSize)) { + ArenaNode* next = node->next; + + diff = newSize - node->size; + // Checks if the next node is contiguous to the current allocated node and it has enough space to fit the + // new requested size + if (((uintptr_t)next == (uintptr_t)node + node->size + sizeof(ArenaNode)) && (next->isFree) && + (next->size >= diff)) { + ArenaNode* next2 = next->next; + + next->size = (next->size - diff); + if (next2 != NULL) { + // Update the previous element of the linked list + next2->prev = (void*)((uintptr_t)next + diff); + } + + next2 = (void*)((uintptr_t)next + diff); + node->next = next2; + node->size = newSize; + __osMemcpy(next2, next, sizeof(ArenaNode)); + } else { + // Create a new pointer and manually copy the data from the old pointer to the new one + newPtr = __osMalloc(arena, newSize); + if (newPtr != NULL) { + bcopy(newPtr, ptr, node->size); + __osFree(arena, ptr); + } + ptr = newPtr; + } + } + } + + ArenaImpl_Unlock(arena); + + return ptr; +} + +/** + * Gets the size of the largest free block, the total free space and the total allocated space. + * + * @param[in, out] arena The Arena which will be used to get the values from. + * @param[out] outMaxFree The size of the largest free block. + * @param[out] outFree The total free space. + * @param[out] outAlloc The total allocated space. + */ +void __osGetSizes(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { ArenaNode* iter; ArenaImpl_Lock(arena); @@ -245,4 +424,35 @@ void __osAnalyzeArena(Arena* arena, size_t* outMaxFree, size_t* outFree, size_t* ArenaImpl_Unlock(arena); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/__osMalloc/__osCheckArena.s") +/** + * Checks the validity of every node of the \p arena. + * + * @param arena The Arena to check. + * @return s32 0 if every pointer is valid. 1 otherwise. + */ +s32 __osCheckArena(Arena* arena) { + ArenaNode* iter; + s32 err = 0; + + ArenaImpl_Lock(arena); + + // "Checking the contents of the arena..." + (void)"アリーナの内容をチェックしています... (%08x)\n"; + + for (iter = arena->head; iter != NULL; iter = iter->next) { + if (iter->magic != NODE_MAGIC) { + // "Oops!!" + (void)"おおっと!! (%08x %08x)\n"; + + err = 1; + break; + } + } + + // "The arena still looks good" + (void)"アリーナはまだ、いけそうです\n"; + + ArenaImpl_Unlock(arena); + + return err; +} diff --git a/src/boot_O2/boot_800862E0.c b/src/boot_O2/boot_800862E0.c index ecba8c5f5..5774af9da 100644 --- a/src/boot_O2/boot_800862E0.c +++ b/src/boot_O2/boot_800862E0.c @@ -1,17 +1,116 @@ #include "global.h" +#include "system_malloc.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/SystemArena_MallocMin1.s") +typedef void (*BlockFunc)(void*); +typedef void (*BlockFunc1)(void*, u32); +typedef void (*BlockFunc8)(void*, u32, u32, u32, u32, u32, u32, u32, u32); -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/SystemArena_FreeNull.s") +typedef struct InitFunc { + uintptr_t nextOffset; + void (*func)(void); +} InitFunc; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/func_8008633C.s") +void* sInitFuncs = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/func_800863AC.s") +char sNew[] = { 0x00, 0x00, 0x00, 0x00 }; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/func_8008641C.s") +char D_80097508[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, + 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, +}; -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/func_800864EC.s") +void* SystemArena_MallocMin1(size_t size) { + if (size == 0) { + size = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/func_80086588.s") + return __osMalloc(&gSystemArena, size); +} -#pragma GLOBAL_ASM("asm/non_matchings/boot/boot_800862E0/SystemArena_Init.s") +void SystemArena_FreeNullCheck(void* ptr) { + if (ptr != NULL) { + __osFree(&gSystemArena, ptr); + } +} + +void SystemArena_RunBlockFunc(void* blk, size_t nBlk, size_t blkSize, BlockFunc blockFunc) { + uintptr_t pos = blk; + + for (; pos < (uintptr_t)blk + (nBlk * blkSize); pos += (blkSize & ~0)) { + blockFunc(pos); + } +} + +void SystemArena_RunBlockFunc1(void* blk, size_t nBlk, size_t blkSize, BlockFunc1 blockFunc) { + uintptr_t pos = blk; + + for (; pos < (uintptr_t)blk + (nBlk * blkSize); pos += (blkSize & ~0)) { + blockFunc(pos, 2); + } +} + +void* SystemArena_RunBlockFunc8(void* blk, size_t nBlk, size_t blkSize, BlockFunc8 blockFunc) { + if (blk == NULL) { + blk = SystemArena_MallocMin1(nBlk * blkSize); + } + + if (blk != NULL && blockFunc != NULL) { + uintptr_t pos = blk; + + for (; pos < (uintptr_t)blk + (nBlk * blkSize); pos += (blkSize & ~0)) { + blockFunc(pos, 0, 0, 0, 0, 0, 0, 0, 0); + } + } + + return blk; +} + +void SystemArena_RunBlockFunc1Reverse(void* blk, size_t nBlk, size_t blkSize, BlockFunc1 blockFunc, s32 shouldFree) { + uintptr_t pos; + uintptr_t start; + size_t maskedBlkSize; + + if (blk == NULL) { + return; + } + + if (blockFunc != NULL) { + start = blk; + maskedBlkSize = (blkSize & ~0); + pos = (uintptr_t)start + (nBlk * blkSize); + + while (pos > start) { + pos -= maskedBlkSize; + blockFunc(pos, 2); + } + } + + if (shouldFree) { + SystemArena_FreeNullCheck(blk); + } +} + +void SystemArena_RunInits(void) { + InitFunc* initFunc = (InitFunc*)&sInitFuncs; + u32 nextOffset = initFunc->nextOffset; + InitFunc* prev = NULL; + + while (nextOffset != 0) { + initFunc = (InitFunc*)((uintptr_t)initFunc + nextOffset); + + if (initFunc->func != NULL) { + (*initFunc->func)(); + } + + nextOffset = initFunc->nextOffset; + initFunc->nextOffset = (uintptr_t)prev; + prev = initFunc; + } + + sInitFuncs = prev; +} + +void SystemArena_Init(void* start, size_t size) { + SystemArena_InitArena(start, size); + SystemArena_RunInits(); +} diff --git a/src/boot_O2/boot_80086760.c b/src/boot_O2/boot_80086760.c index 1a9b37453..398a1e41a 100644 --- a/src/boot_O2/boot_80086760.c +++ b/src/boot_O2/boot_80086760.c @@ -14,40 +14,40 @@ extern f32 func_80086D18(f32 x); s32 gUseAtanContFrac; /** - * Tangent function computed using libultra __sinf and __cosf + * Tangent function computed using libultra sinf and cosf */ // Math_FTanF f32 func_80086760(f32 x) { - return __sinf(x) / __cosf(x); + return sinf(x) / cosf(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/loadfragment.c b/src/boot_O2/loadfragment.c index 4589cd359..968fb464a 100644 --- a/src/boot_O2/loadfragment.c +++ b/src/boot_O2/loadfragment.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/boot/loadfragment/Load_Relocate.s") diff --git a/src/boot_O2/loadfragment2.c b/src/boot_O2/loadfragment2.c index 5c884be96..c324b80d5 100644 --- a/src/boot_O2/loadfragment2.c +++ b/src/boot_O2/loadfragment2.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" UNK_TYPE4 D_80096C30 = 2; diff --git a/src/boot_O2/mtxuty-cvt.c b/src/boot_O2/mtxuty-cvt.c index 221dbf554..2c1634392 100644 --- a/src/boot_O2/mtxuty-cvt.c +++ b/src/boot_O2/mtxuty-cvt.c @@ -1,18 +1,19 @@ #include "global.h" -void MtxConv_F2L(MatrixInternal* m1, MtxF* m2) { +void MtxConv_F2L(Mtx* mtx, MtxF* mf) { s32 i; s32 j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { - s32 value = (m2->mf[i][j] * 0x10000); - m1->intPart[i][j] = value >> 16; - m1->fracPart[i][j] = value; + s32 value = (mf->mf[i][j] * 0x10000); + + mtx->intPart[i][j] = value >> 16; + mtx->fracPart[i][j] = value; } } } -void MtxConv_L2F(MtxF* m1, MatrixInternal* m2) { - guMtxL2F(m1, (Mtx*)m2); +void MtxConv_L2F(MtxF* mtx, Mtx* mf) { + guMtxL2F(mtx, mf); } diff --git a/src/boot_O2/padsetup.c b/src/boot_O2/padsetup.c index 5f83bd524..9cef6f196 100644 --- a/src/boot_O2/padsetup.c +++ b/src/boot_O2/padsetup.c @@ -1,3 +1,34 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/padsetup/func_80086620.s") +s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status) { + s32 ret; + s32 i; + + *outMask = 0xFF; + ret = osContInit(mq, outMask, status); + if (ret != 0) { + return ret; + } + if (*outMask == 0xFF) { + if (osContStartQuery(mq) != 0) { + return 1; + } + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + osContGetQuery(status); + + *outMask = 0; + + for (i = 0; i < MAXCONTROLLERS; i++) { + switch (status[i].errno) { + case 0: + if (status[i].type == CONT_TYPE_NORMAL) { + *outMask |= 1 << i; + } + break; + default: + break; + } + } + } + return 0; +} diff --git a/src/boot_O2/system_malloc.c b/src/boot_O2/system_malloc.c index ad2bb6345..56608166c 100644 --- a/src/boot_O2/system_malloc.c +++ b/src/boot_O2/system_malloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "os_malloc.h" Arena gSystemArena; @@ -29,8 +30,8 @@ void* SystemArena_Calloc(u32 elements, size_t size) { return ptr; } -void SystemArena_AnalyzeArena(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { - __osAnalyzeArena(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); +void SystemArena_GetSizes(size_t* maxFreeBlock, size_t* bytesFree, size_t* bytesAllocated) { + __osGetSizes(&gSystemArena, maxFreeBlock, bytesFree, bytesAllocated); } u32 SystemArena_CheckArena(void) { diff --git a/src/boot_O2_g3/CIC6105.c b/src/boot_O2_g3/CIC6105.c index 5a51b22c8..78eed1a77 100644 --- a/src/boot_O2_g3/CIC6105.c +++ b/src/boot_O2_g3/CIC6105.c @@ -17,7 +17,7 @@ void CIC6105_PrintRomInfo(void) { } void CIC6105_AddRomInfoFaultPage(void) { - Fault_AddClient(&romInfoFaultClient, (fault_client_func)CIC6105_PrintRomInfo, 0, 0); + Fault_AddClient(&romInfoFaultClient, CIC6105_PrintRomInfo, 0, 0); } void CIC6105_RemoveRomInfoFaultPage(void) { diff --git a/src/boot_O2_g3/boot_main.c b/src/boot_O2_g3/boot_main.c index ec6b446e7..04bb9a33a 100644 --- a/src/boot_O2_g3/boot_main.c +++ b/src/boot_O2_g3/boot_main.c @@ -1,5 +1,4 @@ #include "global.h" -#include "prevent_bss_reordering.h" StackEntry sBootThreadInfo; OSThread sIdleThread; diff --git a/src/boot_O2_g3/fault.c b/src/boot_O2_g3/fault.c index 1851d21cb..1f5503445 100644 --- a/src/boot_O2_g3/fault.c +++ b/src/boot_O2_g3/fault.c @@ -33,7 +33,7 @@ void Fault_SleepImpl(u32 duration) { Sleep_Cycles(value); } -void Fault_AddClient(FaultClient* client, fault_client_func callback, void* param0, void* param1) { +void Fault_AddClient(FaultClient* client, void* callback, void* param0, void* param1) { OSIntMask mask; u32 alreadyExists = 0; @@ -104,7 +104,7 @@ void Fault_RemoveClient(FaultClient* client) { } } -void Fault_AddAddrConvClient(FaultAddrConvClient* client, FaultAddrConvFunc callback, void* param) { +void Fault_AddAddrConvClient(FaultAddrConvClient* client, void* callback, void* param) { OSIntMask mask; u32 alreadyExists = 0; @@ -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); } } @@ -714,7 +707,7 @@ void Fault_CommitFB() { osViSetYScale(1.0f); osViSetMode(&osViModeNtscLan1); osViSetSpecialFeatures(0x42); // gama_disable|dither_fliter_enable_aa_mode3_disable - osViBlack(0); + osViBlack(false); if (sFaultContext->fb) { fb = sFaultContext->fb; @@ -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); @@ -802,7 +796,7 @@ void Fault_ThreadEntry(void* arg) { osSetEventMesg(12, &sFaultContext->queue, (OSMesg)2); while (1) { do { - osRecvMesg(&sFaultContext->queue, &msg, 1); + osRecvMesg(&sFaultContext->queue, &msg, OS_MESG_BLOCK); if (msg == (OSMesg)1) { sFaultContext->msgId = 1; @@ -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); @@ -910,8 +904,8 @@ void Fault_HangupFaultClient(const char* arg0, char* arg1) { void Fault_AddHungupAndCrashImpl(const char* arg0, char* arg1) { FaultClient client; - char padd[4]; - Fault_AddClient(&client, (fault_client_func)Fault_HangupFaultClient, (void*)arg0, arg1); + u32 pad; + Fault_AddClient(&client, Fault_HangupFaultClient, (void*)arg0, arg1); *(u32*)0x11111111 = 0; // trigger an exception } diff --git a/src/boot_O2_g3/fault_drawer.c b/src/boot_O2_g3/fault_drawer.c index 949faadf1..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*)0x803DA800, // fb - TODO map out buffers in this region and avoid hard-coded pointer + 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 4be8a1094..da93f13fd 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -1,3 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" u8 D_80096B20 = 1; @@ -18,11 +19,11 @@ OSMesgQueue gPiMgrCmdQ; void Idle_ClearMemory(void* begin, void* end) { if (begin < end) { - bzero(begin, (u32)end - (u32)begin); + bzero(begin, (uintptr_t)end - (uintptr_t)begin); } } -void Idle_InitFramebuffer(u32* ptr, u32 numBytes, u32 value) { +void Idle_InitFramebuffer(u32* ptr, size_t numBytes, u32 value) { s32 temp = sizeof(u32); while (numBytes) { @@ -35,7 +36,7 @@ void Idle_InitScreen(void) { Idle_InitFramebuffer((u32*)gFramebuffer1, 0x25800, 0x00010001); ViConfig_UpdateVi(0); osViSwapBuffer(gFramebuffer1); - osViBlack(0); + osViBlack(false); } void Idle_InitMemory(void) { @@ -51,7 +52,7 @@ void Idle_InitCodeAndMemory(void) { DmaRequest dmaReq; OSMesgQueue queue; OSMesg mesg; - u32 oldSize; + size_t oldSize; osCreateMesgQueue(&queue, &mesg, 1); @@ -62,7 +63,7 @@ void Idle_InitCodeAndMemory(void) { SEGMENT_ROM_END(code) - SEGMENT_ROM_START(code), 0, &queue, 0); Idle_InitScreen(); Idle_InitMemory(); - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); sDmaMgrDmaBuffSize = oldSize; @@ -70,7 +71,7 @@ void Idle_InitCodeAndMemory(void) { } void Main_ThreadEntry(void* arg) { - StackCheck_Init(&sIrqMgrStackInfo, sIrqMgrStack, sIrqMgrStack + sizeof(sIrqMgrStack), 0, 256, "irqmgr"); + StackCheck_Init(&sIrqMgrStackInfo, sIrqMgrStack, sIrqMgrStack + sizeof(sIrqMgrStack), 0, 0x100, "irqmgr"); IrqMgr_Init(&gIrqMgr, &sIrqMgrStackInfo, Z_PRIORITY_IRQMGR, 1); DmaMgr_Start(); Idle_InitCodeAndMemory(); @@ -86,15 +87,15 @@ void Idle_InitVideo(void) { gViConfigYScale = 1.0; switch (osTvType) { - case 1: + case OS_TV_NTSC: D_8009B290 = 2; gViConfigMode = osViModeNtscLan1; break; - case 2: + case OS_TV_MPAL: D_8009B290 = 30; gViConfigMode = osViModeMpalLan1; break; - case 0: + case OS_TV_PAL: D_8009B290 = 44; gViConfigMode = osViModeFpalLan1; gViConfigYScale = 0.833f; @@ -107,7 +108,7 @@ void Idle_InitVideo(void) { void Idle_ThreadEntry(void* arg) { Idle_InitVideo(); osCreatePiManager(150, &gPiMgrCmdQ, sPiMgrCmdBuff, ARRAY_COUNT(sPiMgrCmdBuff)); - StackCheck_Init(&sMainStackInfo, sMainStack, sMainStack + sizeof(sMainStack), 0, 1024, "main"); + StackCheck_Init(&sMainStackInfo, sMainStack, sMainStack + sizeof(sMainStack), 0, 0x400, "main"); osCreateThread(&gMainThread, Z_THREAD_ID_MAIN, Main_ThreadEntry, arg, sMainStack + sizeof(sMainStack), Z_PRIORITY_MAIN); osStartThread(&gMainThread); diff --git a/src/boot_O2_g3/idle_extra_bss.c b/src/boot_O2_g3/idle_extra_bss.c index 019b62640..24fc0083f 100644 --- a/src/boot_O2_g3/idle_extra_bss.c +++ b/src/boot_O2_g3/idle_extra_bss.c @@ -1,4 +1,5 @@ -#include "global.h" +#include "PR/ultratypes.h" +#include "ultra64/vi.h" // This file is currently required to fix bss reordering in idle.c. It is not resolved by prevent_bss_reordering.h . // Hopefully it will not be permanent. diff --git a/src/boot_O2_g3/irqmgr.c b/src/boot_O2_g3/irqmgr.c index 3f4ca04ae..f605dc327 100644 --- a/src/boot_O2_g3/irqmgr.c +++ b/src/boot_O2_g3/irqmgr.c @@ -17,10 +17,10 @@ void IrqMgr_AddClient(IrqMgr* irqmgr, IrqMgrClient* param_2, OSMesgQueue* param_ osSetIntMask(saveMask); if (irqmgr->prenmiStage > 0) { - osSendMesg(param_2->queue, &irqmgr->prenmiMsg.type, 0); + osSendMesg(param_2->queue, &irqmgr->prenmiMsg.type, OS_MESG_NOBLOCK); } if (irqmgr->prenmiStage > 1) { - osSendMesg(param_2->queue, &irqmgr->nmiMsg.type, 0); + osSendMesg(param_2->queue, &irqmgr->nmiMsg.type, OS_MESG_NOBLOCK); } } @@ -54,7 +54,7 @@ void IrqMgr_SendMesgForClient(IrqMgr* irqmgr, OSMesg msg) { IrqMgrClient* iter = irqmgr->callbacks; while (iter != NULL) { - osSendMesg(iter->queue, msg, 0); + osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK); iter = iter->next; } } @@ -64,7 +64,7 @@ void IrqMgr_JamMesgForClient(IrqMgr* irqmgr, OSMesg msg) { while (iter != NULL) { if (iter->queue->validCount < iter->queue->msgCount) { - osSendMesg(iter->queue, msg, 0); + osSendMesg(iter->queue, msg, OS_MESG_NOBLOCK); } iter = iter->next; } @@ -130,7 +130,7 @@ void IrqMgr_ThreadEntry(IrqMgr* irqmgr) { ; } - osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, 1); + osRecvMesg(&irqmgr->irqQueue, (OSMesg*)&interrupt, OS_MESG_BLOCK); switch (interrupt) { case 0x29A: IrqMgr_HandleRetrace(irqmgr); @@ -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/boot_O2_g3/viconfig.c b/src/boot_O2_g3/viconfig.c index d32fc9b91..6539421e6 100644 --- a/src/boot_O2_g3/viconfig.c +++ b/src/boot_O2_g3/viconfig.c @@ -3,13 +3,13 @@ void ViConfig_UpdateVi(u32 mode) { if (mode != 0) { switch (osTvType) { - case 2: + case OS_TV_MPAL: osViSetMode(&osViModeMpalLan1); break; - case 0: + case OS_TV_PAL: osViSetMode(&osViModePalLan1); break; - case 1: + case OS_TV_NTSC: default: osViSetMode(&osViModeNtscLan1); break; @@ -47,8 +47,8 @@ void ViConfig_UpdateVi(u32 mode) { void ViConfig_UpdateBlack(void) { if (gViConfigUseDefault != 0) { - osViBlack(1); + osViBlack(true); } else { - osViBlack(0); + osViBlack(false); } } diff --git a/src/boot_O2_g3/yaz0.c b/src/boot_O2_g3/yaz0.c index 094c0bb38..80d819acc 100644 --- a/src/boot_O2_g3/yaz0.c +++ b/src/boot_O2_g3/yaz0.c @@ -17,7 +17,7 @@ void* Yaz0_FirstDMA() { curSize = (u32)sYaz0CurDataEnd - (u32)sYaz0DataBuffer; dmaSize = (curSize > sYaz0CurSize) ? sYaz0CurSize : curSize; - DmaMgr_DMARomToRam(sYaz0CurRomStart, sYaz0DataBuffer, dmaSize); + DmaMgr_DmaRomToRam(sYaz0CurRomStart, sYaz0DataBuffer, dmaSize); sYaz0CurRomStart += dmaSize; sYaz0CurSize -= dmaSize; return sYaz0DataBuffer; @@ -40,7 +40,7 @@ void* Yaz0_NextDMA(void* curSrcPos) { } if (dmaSize != 0) { - DmaMgr_DMARomToRam(sYaz0CurRomStart, dst + restSize, dmaSize); + DmaMgr_DmaRomToRam(sYaz0CurRomStart, dst + restSize, dmaSize); sYaz0CurRomStart += dmaSize; sYaz0CurSize -= dmaSize; if (!sYaz0CurSize) { diff --git a/src/boot_O2_g3/z_std_dma.c b/src/boot_O2_g3/z_std_dma.c index 2903b488f..d9c7fb221 100644 --- a/src/boot_O2_g3/z_std_dma.c +++ b/src/boot_O2_g3/z_std_dma.c @@ -9,12 +9,12 @@ OSMesg sDmaMgrMsgs[32]; OSThread sDmaMgrThread; u8 sDmaMgrStack[0x500]; -s32 DmaMgr_DMARomToRam(u32 rom, void* ram, size_t size) { +s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) { OSIoMesg ioMsg; OSMesgQueue queue; OSMesg msg[1]; s32 ret; - u32 buffSize = sDmaMgrDmaBuffSize; + size_t buffSize = sDmaMgrDmaBuffSize; osInvalDCache(ram, size); osCreateMesgQueue(&queue, msg, ARRAY_COUNT(msg)); @@ -23,7 +23,7 @@ s32 DmaMgr_DMARomToRam(u32 rom, void* ram, size_t size) { while (buffSize < size) { ioMsg.hdr.pri = 0; ioMsg.hdr.retQueue = &queue; - ioMsg.devAddr = (u32)rom; + ioMsg.devAddr = rom; ioMsg.dramAddr = ram; ioMsg.size = buffSize; ret = osEPiStartDma(gCartHandle, &ioMsg, 0); @@ -31,7 +31,7 @@ s32 DmaMgr_DMARomToRam(u32 rom, void* ram, size_t size) { goto END; } - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); size -= buffSize; rom = rom + buffSize; ram = (u8*)ram + buffSize; @@ -39,15 +39,15 @@ s32 DmaMgr_DMARomToRam(u32 rom, void* ram, size_t size) { } ioMsg.hdr.pri = 0; ioMsg.hdr.retQueue = &queue; - ioMsg.devAddr = (u32)rom; + ioMsg.devAddr = rom; ioMsg.dramAddr = ram; - ioMsg.size = (u32)size; + ioMsg.size = size; ret = osEPiStartDma(gCartHandle, &ioMsg, 0); if (ret) { goto END; } - osRecvMesg(&queue, NULL, 1); + osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osInvalDCache(ram, size); @@ -55,8 +55,8 @@ END: return ret; } -void DmaMgr_DmaCallback0(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) { - osEPiStartDma(pihandle, mb, direction); +s32 DmaMgr_DmaHandler(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) { + return osEPiStartDma(pihandle, mb, direction); } DmaEntry* DmaMgr_FindDmaEntry(u32 vrom) { @@ -109,11 +109,11 @@ const char* func_800809F4(u32 a0) { } void DmaMgr_ProcessMsg(DmaRequest* req) { - u32 vrom; + uintptr_t vrom; void* ram; size_t size; - u32 romStart; - u32 romSize; + uintptr_t romStart; + size_t romSize; DmaEntry* dmaEntry; s32 index; @@ -129,7 +129,7 @@ void DmaMgr_ProcessMsg(DmaRequest* req) { if (dmaEntry->vromEnd < (vrom + size)) { Fault_AddHungupAndCrash("../z_std_dma.c", 499); } - DmaMgr_DMARomToRam((dmaEntry->romStart + vrom) - dmaEntry->vromStart, (u8*)ram, size); + DmaMgr_DmaRomToRam((dmaEntry->romStart + vrom) - dmaEntry->vromStart, (u8*)ram, size); return; } @@ -172,7 +172,7 @@ void DmaMgr_ThreadEntry(void* a0) { } } -s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, u32 vromStart, size_t size, UNK_TYPE4 unused, +s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, uintptr_t vromStart, size_t size, UNK_TYPE4 unused, OSMesgQueue* queue, OSMesg msg) { if (gIrqMgrResetStatus >= 2) { return -2; @@ -190,7 +190,7 @@ s32 DmaMgr_SendRequestImpl(DmaRequest* request, void* vramStart, u32 vromStart, return 0; } -s32 DmaMgr_SendRequest0(void* vramStart, u32 vromStart, size_t size) { +s32 DmaMgr_SendRequest0(void* vramStart, uintptr_t vromStart, size_t size) { DmaRequest req; OSMesgQueue queue; OSMesg msg[1]; @@ -210,24 +210,20 @@ s32 DmaMgr_SendRequest0(void* vramStart, u32 vromStart, size_t size) { } void DmaMgr_Start(void) { - DmaEntry* iter; - u32 idx; + DmaMgr_DmaRomToRam(SEGMENT_ROM_START(dmadata), dmadata, SEGMENT_ROM_SIZE(dmadata)); - DmaMgr_DMARomToRam(SEGMENT_ROM_START(dmadata), dmadata, SEGMENT_ROM_SIZE(dmadata)); + { + DmaEntry* iter = dmadata; + u32 idx = 0; -dummy_label:; + while (iter->vromEnd != 0) { + iter++; + idx++; + } - iter = dmadata; - idx = 0; - while (iter->vromEnd != 0) { - iter++; - idx++; + numDmaEntries = idx; } - numDmaEntries = idx; - -dummy_label_2:; - osCreateMesgQueue(&sDmaMgrMsgQueue, sDmaMgrMsgs, ARRAY_COUNT(sDmaMgrMsgs)); StackCheck_Init(&sDmaMgrStackInfo, sDmaMgrStack, sDmaMgrStack + sizeof(sDmaMgrStack), 0, 0x100, "dmamgr"); osCreateThread(&sDmaMgrThread, Z_THREAD_ID_DMAMGR, DmaMgr_ThreadEntry, NULL, sDmaMgrStack + sizeof(sDmaMgrStack), 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..94a5f55c9 100644 --- a/src/buffers/gfxbuffers.c +++ b/src/buffers/gfxyield.c @@ -1,7 +1,4 @@ +#include "prevent_bss_reordering.h" #include "global.h" u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; - -u8 gGfxSPTaskStack[0x400]; - -GfxPool gGfxPools[2]; diff --git a/src/code/audio/audio_data.c b/src/code/audio/audio_data.c new file mode 100644 index 000000000..c43018922 --- /dev/null +++ b/src/code/audio/audio_data.c @@ -0,0 +1,949 @@ +#include "global.h" + +s16 gLowPassFilterData[16 * 8] = { + /* 0x0 */ 0, 0, 0, 32767, 0, 0, 0, 0, // Identity filter (delta function) + /* 0x1 */ 3854, 4188, 4398, 4469, 4398, 4188, 3854, 3416, // low-freq cutoff (more filtering) + /* 0x2 */ 3415, 4314, 4915, 5126, 4915, 4314, 3415, 2351, + /* 0x3 */ 2636, 4433, 5762, 6252, 5762, 4433, 2636, 849, + /* 0x4 */ 1334, 4196, 6646, 7609, 6646, 4196, 1334, -802, + /* 0x5 */ -265, 3421, 7292, 8944, 7292, 3421, -265, -1863, + /* 0x6 */ -1558, 2065, 7146, 9546, 7146, 2065, -1558, -1682, + /* 0x7 */ -2353, 726, 7441, 11028, 7441, 726, -2353, -697, + /* 0x8 */ -2252, -693, 7121, 11962, 7121, -693, -2252, 668, + /* 0x9 */ -1373, -1819, 6299, 12298, 6299, -1819, -1373, 1484, + /* 0xA */ -213, -2740, 5843, 13680, 5843, -2740, -213, 1494, + /* 0xB */ 980, -3081, 4883, 14286, 4883, -3081, 980, 590, + /* 0xC */ 1769, -2973, 3866, 14981, 3866, -2973, 1769, -568, + /* 0xD */ 2023, -2554, 2911, 16397, 2911, -2554, 2023, -1391, + /* 0xE */ 1766, -1918, 2016, 19800, 2016, -1918, 1766, -1564, + /* 0xF */ 841, -853, 863, 26829, 863, -853, 841, -820, // high-freq cutoff (less filtering) +}; + +s16 gHighPassFilterData[15 * 8] = { + /* 0x0 */ -289, -291, -289, 30736, -289, -291, -289, -290, // low-freq cutoff (less filtering) + /* 0x1 */ -464, -467, -467, 29506, -467, -467, -464, -463, + /* 0x2 */ -662, -670, -672, 28101, -672, -670, -662, -656, + /* 0x3 */ -839, -855, -861, 26830, -861, -855, -839, -822, + /* 0x4 */ -996, -1024, -1038, 25685, -1038, -1024, -996, -963, + /* 0x5 */ -1184, -1236, -1266, 24272, -1266, -1236, -1184, -1118, + /* 0x6 */ -1357, -1450, -1506, 22900, -1506, -1450, -1357, -1238, + /* 0x7 */ -1514, -1680, -1784, 21498, -1784, -1680, -1514, -1307, + /* 0x8 */ -1613, -1877, -2048, 20390, -2048, -1877, -1613, -1298, + /* 0x9 */ -1657, -2185, -2559, 18869, -2559, -2185, -1657, -1093, + /* 0xA */ -1524, -2395, -3078, 18030, -3078, -2395, -1524, -739, + /* 0xB */ -1253, -2504, -3621, 17642, -3621, -2504, -1253, -367, + /* 0xC */ -525, -2367, -4732, 17517, -4732, -2367, -525, 0, + /* 0xD */ -34, -1762, -5706, 17503, -5706, -1762, -34, -258, + /* 0xE */ -772, -3, -6985, 17240, -6985, -3, -772, -3, // high-freq cutoff (more filtering) +}; + +// clang-format off +s16 gBandStopFilterData[105 * 8] = { + // Block 0 + /* 0x00 */ -43, -716, -1205, 28210, -1205, -716, -43, 629, + /* 0x01 */ 249, -919, -1819, 25489, -1819, -919, 249, 1301, + /* 0x02 */ 1267, -802, -2650, 20722, -2650, -802, 1267, 2603, + /* 0x03 */ 2497, -210, -3196, 17617, -3196, -210, 2497, 3339, + /* 0x04 */ 3413, 690, -3385, 14754, -3385, 690, 3413, 3035, + /* 0x05 */ 3859, 1734, -3416, 12704, -3416, 1734, 3859, 2042, + /* 0x06 */ 3858, 2907, -3414, 11516, -3414, 2907, 3858, 890, + /* 0x07 */ 3374, 4194, -3345, 10859, -3345, 4194, 3374, 80, + /* 0x08 */ 2446, 5521, -3130, 10483, -3130, 5521, 2446, 86, + /* 0x09 */ 1275, 6760, -2665, 10225, -2665, 6760, 1275, 1140, + /* 0x0A */ 252, 7778, -1836, 10022, -1836, 7778, 252, 3010, + /* 0x0B */ -98, 8427, -461, 9805, -461, 8427, -98, 4988, + /* 0x0C */ 719, 7392, 1528, 8201, 1528, 7392, 719, 5286, + /* 0x0D */ 2499, 5359, 3651, 5985, 3651, 5359, 2499, 3761, + + // Block 1 + /* 0x0E */ 711, -205, -1026, 27608, -1026, -205, 711, 1271, + /* 0x0F */ 1335, -108, -1520, 24836, -1520, -108, 1335, 2003, + /* 0x10 */ 2540, 455, -2104, 19853, -2104, 455, 2540, 2712, + /* 0x11 */ 3406, 1298, -2347, 16266, -2347, 1298, 3406, 2397, + /* 0x12 */ 3860, 2321, -2440, 14094, -2440, 2321, 3860, 1428, + /* 0x13 */ 3858, 3511, -2439, 12888, -2439, 3511, 3858, 259, + /* 0x14 */ 3248, 4679, -2238, 11859, -2238, 4679, 3248, -575, + /* 0x15 */ 2329, 6021, -1929, 11579, -1929, 6021, 2329, -626, + /* 0x16 */ 1225, 7613, -1395, 11967, -1395, 7613, 1225, 332, + /* 0x17 */ 172, 8785, -352, 12028, -352, 8785, 172, 2119, + /* 0x18 */ -172, 8198, 1139, 10360, 1139, 8198, -172, 3385, + /* 0x19 */ 511, 7006, 2830, 8649, 2830, 7006, 511, 3421, + /* 0x1A */ 1995, 5313, 4595, 6801, 4595, 5313, 1995, 2158, + + // Block 2 + /* 0x1B */ 1196, 313, -815, 26961, -815, 313, 1196, 1154, + /* 0x1C */ 1896, 666, -1159, 23821, -1159, 666, 1896, 1500, + /* 0x1D */ 2934, 1569, -1548, 19353, -1548, 1569, 2934, 1308, + /* 0x1E */ 3463, 2673, -1703, 16770, -1703, 2673, 3463, 316, + /* 0x1F */ 3269, 3757, -1608, 14587, -1608, 3757, 3269, -910, + /* 0x20 */ 2585, 4889, -1364, 13325, -1364, 4889, 2585, -1763, + /* 0x21 */ 1588, 6277, -970, 13171, -970, 6277, 1588, -1922, + /* 0x22 */ 337, 8121, -265, 14134, -265, 8121, 337, -1186, + /* 0x23 */ -795, 8193, 882, 12631, 882, 8193, -795, 391, + /* 0x24 */ -1058, 7224, 2132, 10492, 2132, 7224, -1058, 1444, + /* 0x25 */ -503, 6540, 3803, 9532, 3803, 6540, -503, 1541, + /* 0x26 */ 906, 5326, 5759, 8358, 5759, 5326, 906, 423, + + // Block 3 + /* 0x27 */ 1298, 781, -597, 27018, -597, 781, 1298, 392, + /* 0x28 */ 1914, 1364, -834, 24334, -834, 1364, 1914, 205, + /* 0x29 */ 2474, 2527, -1015, 19916, -1015, 2527, 2474, -817, + /* 0x2A */ 2277, 3649, -934, 16994, -934, 3649, 2277, -2050, + /* 0x2B */ 1545, 4865, -673, 15635, -673, 4865, 1545, -2964, + /* 0x2C */ 366, 6363, -181, 15693, -181, 6363, 366, -3252, + /* 0x2D */ -1017, 6734, 611, 13854, 611, 6734, -1017, -2187, + /* 0x2E */ -1937, 6500, 1558, 12000, 1558, 6500, -1937, -774, + /* 0x2F */ -2216, 6018, 2714, 10698, 2714, 6018, -2216, 171, + /* 0x30 */ -1795, 5344, 4221, 9864, 4221, 5344, -1795, 182, + /* 0x31 */ -659, 4411, 6228, 9260, 6228, 4411, -659, -908, + + // Block 4 + /* 0x32 */ 968, 1138, -358, 27228, -358, 1138, 968, -607, + /* 0x33 */ 1251, 1846, -453, 24418, -453, 1846, 1251, -1246, + /* 0x34 */ 1138, 3176, -412, 20709, -412, 3176, 1138, -2601, + /* 0x35 */ 313, 4550, -119, 19167, -119, 4550, 313, -3633, + /* 0x36 */ -972, 5170, 419, 16290, 419, 5170, -972, -3351, + /* 0x37 */ -2123, 5230, 1090, 13680, 1090, 5230, -2123, -2199, + /* 0x38 */ -2916, 5066, 1926, 12019, 1926, 5066, -2916, -929, + /* 0x39 */ -3202, 4669, 2995, 10953, 2995, 4669, -3202, -80, + /* 0x3A */ -2874, 3990, 4369, 10214, 4369, 3990, -2874, -84, + /* 0x3B */ -1937, 3001, 6108, 9601, 6108, 3001, -1937, -1071, + + // Block 5 + /* 0x3C */ 310, 1351, -102, 27950, -102, 1351, 310, -1287, + /* 0x3D */ 169, 2166, -55, 25895, -55, 2166, 169, -2088, + /* 0x3E */ -697, 3332, 252, 21292, 252, 3332, -697, -2909, + /* 0x3F */ -1846, 3873, 739, 17298, 739, 3873, -1846, -2549, + /* 0x40 */ -2904, 4036, 1371, 14658, 1371, 4036, -2904, -1485, + /* 0x41 */ -3657, 3912, 2183, 12999, 2183, 3912, -3657, -261, + /* 0x42 */ -3814, 3385, 3124, 11558, 3124, 3385, -3814, 561, + /* 0x43 */ -3535, 2679, 4428, 10890, 4428, 2679, -3535, 589, + /* 0x44 */ -2812, 1718, 6312, 10782, 6312, 1718, -2812, -299, + + // Block 6 + /* 0x45 */ -472, 1315, 164, 27677, 164, 1315, -472, -1185, + /* 0x46 */ -993, 1945, 353, 24630, 353, 1945, -993, -1551, + /* 0x47 */ -2181, 2706, 860, 19924, 860, 2706, -2181, -1347, + /* 0x48 */ -3275, 2979, 1521, 16895, 1521, 2979, -3275, -319, + /* 0x49 */ -3842, 2725, 2248, 14245, 2248, 2725, -3842, 889, + /* 0x4A */ -3933, 2186, 3141, 12579, 3141, 2186, -3933, 1665, + /* 0x4B */ -3664, 1431, 4428, 11971, 4428, 1431, -3664, 1747, + /* 0x4C */ -3021, 346, 6399, 12209, 6399, 346, -3021, 1024, + + // Block 7 + /* 0x4D */ -1075, 1074, 417, 27236, 417, 1074, -1075, -395, + /* 0x4E */ -1798, 1521, 741, 24438, 741, 1521, -1798, -206, + /* 0x4F */ -2921, 1848, 1426, 19572, 1426, 1848, -2921, 803, + /* 0x50 */ -3491, 1649, 2169, 16192, 2169, 1649, -3491, 1954, + /* 0x51 */ -3600, 1124, 3106, 14379, 3106, 1124, -3600, 2726, + /* 0x52 */ -3300, 278, 4453, 13834, 4453, 278, -3300, 2867, + /* 0x53 */ -2282, -916, 5804, 12748, 5804, -916, -2282, 2012, + + // Block 8 + /* 0x54 */ -1306, 682, 649, 26892, 649, 682, -1306, 599, + /* 0x55 */ -1951, 858, 1073, 23787, 1073, 858, -1951, 1214, + /* 0x56 */ -2705, 755, 1945, 19505, 1945, 755, -2705, 2450, + /* 0x57 */ -2857, 207, 2996, 17354, 2996, 207, -2857, 3289, + /* 0x58 */ -2261, -722, 4101, 15425, 4101, -722, -2261, 3173, + /* 0x59 */ -1164, -1891, 5287, 13853, 5287, -1891, -1164, 2227, + + // Block 9 + /* 0x5A */ -1119, 202, 869, 27136, 869, 202, -1119, 1249, + /* 0x5B */ -1545, 108, 1432, 24611, 1432, 108, -1545, 1984, + /* 0x5C */ -1675, -472, 2529, 20597, 2529, -472, -1675, 2814, + /* 0x5D */ -1040, -1426, 3661, 17877, 3661, -1426, -1040, 2634, + /* 0x5E */ 105, -2626, 4871, 15944, 4871, -2626, 105, 1615, + + // Block 10 + /* 0x5F */ -554, -321, 1071, 27687, 1071, -321, -554, 1185, + /* 0x60 */ -562, -704, 1738, 25171, 1738, -704, -562, 1585, + /* 0x61 */ 73, -1749, 3045, 21572, 3045, -1749, 73, 1458, + /* 0x62 */ 1152, -2704, 3884, 16963, 3884, -2704, 1152, 320, + + // Block 11 + /* 0x63 */ 222, -806, 1221, 27862, 1221, -806, 222, 404, + /* 0x64 */ 632, -1385, 1908, 24706, 1908, -1385, 632, 208, + /* 0x65 */ 1605, -2339, 2840, 18439, 2840, -2339, 1605, -756, + + // Block 12 + /* 0x66 */ 861, -1081, 1224, 25856, 1224, -1081, 861, -576, + /* 0x67 */ 1422, -1655, 1804, 21885, 1804, -1655, 1422, -1117, + + // Block 13 + /* 0x68 */ 434, -453, 467, 29652, 467, -453, 434, -405, +}; + +s16 gBandPassFilterData[105 * 8] = { + // Block 0 + /* 0x00 */ 687, 4058, 6599, 7544, 6599, 4058, 687, -2532, + /* 0x01 */ -1303, 2777, 6337, 7745, 6337, 2777, -1303, -4185, + /* 0x02 */ -2873, 1376, 5931, 7886, 5931, 1376, -2873, -4520, + /* 0x03 */ -4108, 0, 5913, 8723, 5913, 0, -4108, -3999, + /* 0x04 */ -4233, -1334, 5242, 8775, 5242, -1334, -4233, -2371, + /* 0x05 */ -3882, -2547, 4808, 9389, 4808, -2547, -3882, -900, + /* 0x06 */ -3072, -3668, 4423, 10438, 4423, -3668, -3072, 0, + /* 0x07 */ -1914, -4609, 3950, 11819, 3950, -4609, -1914, 0, + /* 0x08 */ -678, -5227, 3301, 13449, 3301, -5227, -678, -903, + /* 0x09 */ 246, -5250, 2363, 14858, 2363, -5250, 246, -2189, + /* 0x0A */ 509, -4812, 1262, 16454, 1262, -4812, 509, -3143, + /* 0x0B */ 0, -4404, 0, 20367, 0, -4404, 0, -3591, + /* 0x0C */ -1151, -2707, -1393, 19954, -1393, -2707, -1151, -2310, + /* 0x0D */ -1765, -1920, -2014, 19800, -2014, -1920, -1765, -1566, + + // Block 1 + /* 0x0E */ -3122, 1346, 5464, 7125, 5464, 1346, -3122, -5776, + /* 0x0F */ -4566, 0, 5211, 7489, 5211, 0, -4566, -5723, + /* 0x10 */ -4941, -1265, 4474, 7249, 4474, -1265, -4941, -4155, + /* 0x11 */ -4932, -2431, 4021, 7549, 4021, -2431, -4932, -2447, + /* 0x12 */ -4511, -3587, 3678, 8286, 3678, -3587, -4511, -927, + /* 0x13 */ -3660, -4711, 3314, 9396, 3314, -4711, -3660, 0, + /* 0x14 */ -2471, -5685, 2820, 10810, 2820, -5685, -2471, 0, + /* 0x15 */ -1213, -6349, 2123, 12463, 2123, -6349, -1213, -929, + /* 0x16 */ -272, -6581, 1189, 14354, 1189, -6581, -272, -2327, + /* 0x17 */ 0, -6351, 0, 16604, 0, -6351, 0, -3460, + /* 0x18 */ -509, -4812, -1262, 16454, -1262, -4812, -509, -3143, + /* 0x19 */ -1488, -3277, -2395, 16401, -2395, -3277, -1488, -2045, + /* 0x1A */ -2021, -2555, -2910, 16397, -2910, -2555, -2021, -1392, + + // Block 2 + /* 0x1B */ -5281, -1216, 4054, 6441, 4054, -1216, -5281, -5221, + /* 0x1C */ -5495, -2330, 3552, 6498, 3552, -2330, -5495, -3511, + /* 0x1D */ -5377, -3474, 3206, 6991, 3206, -3474, -5377, -1659, + /* 0x1E */ -4853, -4693, 2893, 7887, 2893, -4693, -4853, 0, + /* 0x1F */ -3646, -5586, 2357, 8623, 2357, -5586, -3646, 965, + /* 0x20 */ -2373, -6636, 1821, 10132, 1821, -6636, -2373, 971, + /* 0x21 */ -1086, -7852, 1115, 12658, 1115, -7852, -1086, 0, + /* 0x22 */ 0, -8182, 0, 14837, 0, -8182, 0, -1565, + /* 0x23 */ 272, -6581, -1189, 14354, -1189, -6581, 272, -2326, + /* 0x24 */ -246, -5250, -2363, 14858, -2363, -5250, -246, -2189, + /* 0x25 */ -1231, -3701, -3393, 14931, -3393, -3701, -1231, -1181, + /* 0x26 */ -1768, -2974, -3865, 14981, -3865, -2974, -1768, -569, + + // Block 3 + /* 0x27 */ -5832, -3391, 2948, 6305, 2948, -3391, -5832, -2116, + /* 0x28 */ -5587, -4647, 2641, 7014, 2641, -4647, -5587, 0, + /* 0x29 */ -4365, -5434, 2063, 7306, 2063, -5434, -4365, 1734, + /* 0x2A */ -3036, -6379, 1534, 8205, 1534, -6379, -3036, 2660, + /* 0x2B */ -1576, -7586, 916, 9927, 916, -7586, -1576, 2682, + /* 0x2C */ 0, -9097, 0, 12831, 0, -9097, 0, 1740, + /* 0x2D */ 1086, -7852, -1115, 12658, -1115, -7852, 1086, 0, + /* 0x2E */ 1213, -6349, -2123, 12463, -2123, -6349, 1213, -929, + /* 0x2F */ 678, -5227, -3301, 13449, -3301, -5227, 678, -903, + /* 0x30 */ -406, -3992, -4605, 14759, -4605, -3992, -406, 0, + /* 0x31 */ -979, -3083, -4882, 14287, -4882, -3083, -979, 589, + + // Block 4 + /* 0x32 */ -4748, -5319, 1902, 6607, 1902, -5319, -4748, 2218, + /* 0x33 */ -3402, -6148, 1363, 7101, 1363, -6148, -3402, 3837, + /* 0x34 */ -1853, -7246, 787, 8259, 787, -7246, -1853, 4733, + /* 0x35 */ 0, -8777, 0, 10430, 0, -8777, 0, 4782, + /* 0x36 */ 1576, -7586, -916, 9927, -916, -7586, 1576, 2682, + /* 0x37 */ 2373, -6636, -1821, 10132, -1821, -6636, 2373, 971, + /* 0x38 */ 2471, -5685, -2820, 10810, -2820, -5685, 2471, 0, + /* 0x39 */ 1914, -4609, -3950, 11819, -3950, -4609, 1914, 0, + /* 0x3A */ 846, -3385, -5195, 13035, -5195, -3385, 846, 875, + /* 0x3B */ 214, -2741, -5841, 13679, -5841, -2741, 214, 1492, + + // Block 5 + /* 0x3C */ -1989, -7002, 716, 7373, 716, -7002, -1989, 5976, + /* 0x3D */ 0, -8439, 0, 9006, 0, -8439, 0, 6882, + /* 0x3E */ 1853, -7246, -787, 8259, -787, -7246, 1853, 4733, + /* 0x3F */ 3036, -6379, -1534, 8205, -1534, -6379, 3036, 2660, + /* 0x40 */ 3646, -5586, -2357, 8623, -2357, -5586, 3646, 965, + /* 0x41 */ 3660, -4711, -3314, 9396, -3314, -4711, 3660, 0, + /* 0x42 */ 3072, -3668, -4423, 10438, -4423, -3668, 3072, 0, + /* 0x43 */ 2003, -2459, -5656, 11656, -5656, -2459, 2003, 869, + /* 0x44 */ 1374, -1820, -6298, 12297, -6298, -1820, 1374, 1483, + + // Block 6 + /* 0x45 */ 1989, -7002, -716, 7373, -716, -7002, 1989, 5976, + /* 0x46 */ 3402, -6148, -1363, 7101, -1363, -6148, 3402, 3837, + /* 0x47 */ 4365, -5434, -2063, 7306, -2063, -5434, 4365, 1734, + /* 0x48 */ 4853, -4693, -2893, 7887, -2893, -4693, 4853, 0, + /* 0x49 */ 4511, -3587, -3678, 8286, -3678, -3587, 4511, -927, + /* 0x4A */ 3882, -2547, -4808, 9389, -4808, -2547, 3882, -900, + /* 0x4B */ 2938, -1390, -6423, 11264, -6423, -1390, 2938, 0, + /* 0x4C */ 2253, -695, -7120, 11961, -7120, -695, 2253, 667, + + // Block 7 + /* 0x4D */ 4748, -5319, -1902, 6607, -1902, -5319, 4748, 2218, + /* 0x4E */ 5587, -4647, -2641, 7014, -2641, -4647, 5587, 0, + /* 0x4F */ 5377, -3474, -3206, 6991, -3206, -3474, 5377, -1659, + /* 0x50 */ 4932, -2431, -4021, 7549, -4021, -2431, 4932, -2447, + /* 0x51 */ 4233, -1334, -5242, 8775, -5242, -1334, 4233, -2371, + /* 0x52 */ 3218, 0, -7035, 10795, -7035, 0, 3218, -1464, + /* 0x53 */ 2355, 725, -7440, 11027, -7440, 725, 2355, -698, + + // Block 8 + /* 0x54 */ 5832, -3391, -2948, 6305, -2948, -3391, 5832, -2116, + /* 0x55 */ 5495, -2330, -3552, 6498, -3552, -2330, 5495, -3511, + /* 0x56 */ 4941, -1265, -4474, 7249, -4474, -1265, 4941, -4155, + /* 0x57 */ 4108, 0, -5913, 8723, -5913, 0, 4108, -3999, + /* 0x58 */ 2383, 1404, -6726, 9241, -6726, 1404, 2383, -2496, + /* 0x59 */ 1559, 2063, -7145, 9545, -7145, 2063, 1559, -1684, + + // Block 9 + /* 0x5A */ 5281, -1216, -4054, 6441, -4054, -1216, 5281, -5221, + /* 0x5B */ 4566, 0, -5211, 7489, -5211, 0, 4566, -5723, + /* 0x5C */ 2873, 1376, -5931, 7886, -5931, 1376, 2873, -4520, + /* 0x5D */ 1113, 2760, -6833, 8572, -6833, 2760, 1113, -2779, + /* 0x5E */ 267, 3420, -7291, 8943, -7291, 3420, 267, -1864, + + // Block 10 + /* 0x5F */ 3122, 1346, -5464, 7125, -5464, 1346, 3122, -5776, + /* 0x60 */ 1303, 2777, -6337, 7745, -6337, 2777, 1303, -4185, + /* 0x61 */ -605, 3972, -6859, 7994, -6859, 3972, -605, -1897, + /* 0x62 */ -1333, 4196, -6647, 7610, -6647, 4196, -1333, -803, + + // Block 11 + /* 0x63 */ -687, 4058, -6599, 7544, -6599, 4058, -687, -2532, + /* 0x64 */ -2251, 4520, -6201, 6821, -6201, 4520, -2251, 0, + /* 0x65 */ -2636, 4433, -5763, 6253, -5763, 4433, -2636, 847, + + // Block 12 + /* 0x66 */ -3207, 4379, -5163, 5439, -5163, 4379, -3207, 1826, + /* 0x67 */ -3414, 4314, -4915, 5127, -4915, 4314, -3414, 2350, + + // Block 13 + /* 0x68 */ -3854, 4188, -4398, 4469, -4398, 4188, -3854, 3415, +}; + +s16 gSawtoothWaveSample[] = { + // 1st Harmonic + 0, 1023, 2047, 3071, 4095, 5119, 6143, 7167, + 8191, 9215, 10239, 11263, 12287, 13311, 14335, 15359, + 16383, 17407, 18431, 19455, 20479, 21503, 22527, 23551, + 24575, 25599, 26623, 27647, 28671, 29695, 30719, 31743, + -32767, -31743, -30719, -29695, -28671, -27647, -26623, -25599, + -24575, -23551, -22527, -21503, -20479, -19455, -18431, -17407, + -16383, -15359, -14335, -13311, -12287, -11263, -10239, -9215, + -8191, -7167, -6143, -5119, -4095, -3071, -2047, -1023, + + // 2nd Harmonic + 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, + 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, + -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, + -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, + 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, + 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, + -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, + -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, + + // 4th Harmonic + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + + // 8th Harmonic + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, -32767, -24575, -16383, -8191, +}; + +s16 gTriangleWaveSample[] = { + // 1st Harmonic + 0, 2047, 4095, 6143, 8191, 10239, 12287, 14335, + 16383, 18431, 20479, 22527, 24575, 26623, 28671, 30719, + 32767, 30719, 28671, 26623, 24575, 22527, 20479, 18431, + 16383, 14335, 12287, 10239, 8191, 6143, 4095, 2047, + 0, -2047, -4095, -6143, -8191, -10239, -12287, -14335, + -16383, -18431, -20479, -22527, -24575, -26623, -28671, -30719, + -32767, -30719, -28671, -26623, -24575, -22527, -20479, -18431, + -16383, -14335, -12287, -10239, -8191, -6143, -4095, -2047, + + // 2nd Harmonic + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + 32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095, + 0, -4095, -8191, -12287, -16383, -20479, -24575, -28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + 0, 4095, 8191, 12287, 16383, 20479, 24575, 28671, + 32767, 28671, 24575, 20479, 16383, 12287, 8191, 4095, + 0, -4095, -8191, -12287, -16383, -20479, -24575, -28671, + -32767, -28671, -24575, -20479, -16383, -12287, -8191, -4095, + + // 4th Harmonic + 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, + 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, + 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, + 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, + 0, 8191, 16383, 24575, 32767, 24575, 16383, 8191, + 0, -8191, -16383, -24575, -32767, -24575, -16383, -8191, + + // 8th Harmonic + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, + 0, 16383, 32767, 16383, 0, -16383, -32767, -16383, +}; + +s16 gSineWaveSample[] = { + // 1st Harmonic + 0, 3211, 6392, 9511, 12539, 15446, 18204, 20787, + 23169, 25329, 27244, 28897, 30272, 31356, 32137, 32609, + 32767, 32609, 32137, 31356, 30272, 28897, 27244, 25329, + 23169, 20787, 18204, 15446, 12539, 9511, 6392, 3211, + 0, -3211, -6392, -9511, -12539, -15446, -18204, -20787, + -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, + -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, + -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, + + // 2nd Harmonic + 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, + 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, + 0, -6392, -12539, -18204, -23169, -27244, -30272, -32137, + -32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392, + 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, + 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, + 0, -6392, -12539, -18204, -23169, -27244, -30272, -32137, + -32767, -32137, -30272, -27244, -23169, -18204, -12539, -6392, + + // 4th Harmonic + 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, + 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, + 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, + 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, + 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, + 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, + 0, 12539, 23169, 30272, 32767, 30272, 23169, 12539, + 0, -12539, -23169, -30272, -32767, -30272, -23169, -12539, + + // 8th Harmonic + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, + 0, 23169, 32767, 23169, 0, -23169, -32767, -23169, +}; + +s16 gSquareWaveSample[] = { + // 1st Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, + -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, + + // 2nd Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 4th Harmonic + -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, -32767, -32767, -32767, -32767, + + // 8th Harmonic + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, + 0, 0, 32767, 32767, 0, 0, -32767, -32767, +}; + +s16 gWhiteNoiseSample[] = { + // 1st Harmonic + 0, -25689, -25791, 27803, -27568, -21030, 22174, 6298, + 27071, -18531, 28649, 2284, 3380, 6890, -12682, -21114, + 10000, -24520, 32296, 12248, 15096, 15354, -12021, -31545, + -12929, 6388, -11064, 30456, -30316, -21999, 29691, 27649, + 0, -27649, -29691, 21999, 30316, -30457, 11064, -6387, + 12929, 31544, 12021, -15353, -15096, -12249, -32296, 24521, + -10000, 21113, 12682, -6889, -3380, -2285, -28649, 18532, + -27071, -6299, -22174, 21031, 27568, -27804, 25791, 25690, + + // 2nd Harmonic + 0, -25791, -27568, 22174, 27071, 28649, 3380, -12682, + 10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691, + 0, -29691, 30316, 11064, 12929, 12021, -15096, -32296, + -10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791, + 0, -25791, -27568, 22174, 27071, 28649, 3380, -12682, + 10000, 32296, 15096, -12021, -12929, -11064, -30316, 29691, + 0, -29691, 30316, 11064, 12929, 12021, -15096, -32296, + -10000, 12682, -3380, -28649, -27071, -22174, 27568, 25791, + + // 4th Harmonic + 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, + 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, + 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, + 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, + 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, + 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, + 0, -27568, 27071, 3380, 10000, 15096, -12929, -30316, + 0, 30316, 12929, -15096, -10000, -3380, -27071, 27568, + + // 8th Harmonic + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, + 0, 27071, 10000, -12929, 0, 12929, -10000, -27071, +}; + +// Sine White Noise? +s16 D_801D4790[] = { + // 1st Harmonic + 0, 16316, 20148, 20257, 27209, -32657, 29264, 27259, + -29394, -21494, -26410, 30770, 30033, 29130, 20206, 14129, + 20000, 25677, 19024, 9146, 6921, 4506, -5868, -13122, + -7858, -1885, -7042, -14025, -11903, -8647, -12346, -12396, + 0, 12396, 12346, 8647, 11903, 14024, 7042, 1886, + 7858, 13121, 5868, -4505, -6921, -9147, -19024, -25676, + -20000, -14130, -20206, -29129, -30033, -30771, 26410, 21495, + 29394, -27260, -29264, 32658, -27209, -20258, -20148, -16315, + + // 2nd Harmonic + 0, 20148, 27209, 29264, -29394, -26410, 30033, 20206, + 20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346, + 0, 12346, 11903, 7042, 7858, 5868, -6921, -19024, + -20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148, + 0, 20148, 27209, 29264, -29394, -26410, 30033, 20206, + 20000, 19024, 6921, -5868, -7858, -7042, -11903, -12346, + 0, 12346, 11903, 7042, 7858, 5868, -6921, -19024, + -20000, -20206, -30033, 26410, 29394, -29264, -27209, -20148, + + // 4th Harmonic + 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, + 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, + 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, + 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, + 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, + 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, + 0, 27209, -29394, 30033, 20000, 6921, -7858, -11903, + 0, 11903, 7858, -6921, -20000, -30033, 29394, -27209, + + // 8th Harmonic + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, + 0, -29394, 20000, -7858, 0, 7858, -20000, 29394, +}; + +// Pulse Wave (duty cycle = 12.5%) +s16 gEighthPulseWaveSample[] = { + // 1st Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 2nd Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, 0, 0, 0, 0, 0, 0, + + // 4th Harmonic + 0, 0, 0, 0, 32767, 0, 0, 0, + 0, 0, 0, 0, -32767, 0, 0, 0, + 0, 0, 0, 0, 32767, 0, 0, 0, + 0, 0, 0, 0, -32767, 0, 0, 0, + 0, 0, 0, 0, 32767, 0, 0, 0, + 0, 0, 0, 0, -32767, 0, 0, 0, + 0, 0, 0, 0, 32767, 0, 0, 0, + 0, 0, 0, 0, -32767, 0, 0, 0, + + // 8th Harmonic + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, +}; + +// Pulse Wave (duty cycle = 25%) +s16 gQuarterPulseWaveSample[] = { + // 1st Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 32767, 32767, 32767, 32767, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, -32767, -32767, -32767, -32767, + 0, 0, 0, 0, 0, 0, 0, 0, + + // 2nd Harmonic + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 32767, 32767, 32767, 32767, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + -32767, -32767, -32767, -32767, 0, 0, 0, 0, + + // 4th Harmonic + 0, 0, 0, 0, 32767, 32767, 0, 0, + 0, 0, 0, 0, -32767, -32767, 0, 0, + 0, 0, 0, 0, 32767, 32767, 0, 0, + 0, 0, 0, 0, -32767, -32767, 0, 0, + 0, 0, 0, 0, 32767, 32767, 0, 0, + 0, 0, 0, 0, -32767, -32767, 0, 0, + 0, 0, 0, 0, 32767, 32767, 0, 0, + 0, 0, 0, 0, -32767, -32767, 0, 0, + + // 8th Harmonic + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, + 0, 0, 32767, 0, 0, 0, -32767, 0, +}; +// clang-format on + +s16* gWaveSamples[] = { + gSawtoothWaveSample, gTriangleWaveSample, gSineWaveSample, gSquareWaveSample, gWhiteNoiseSample, + D_801D4790, gEighthPulseWaveSample, gQuarterPulseWaveSample, gQuarterPulseWaveSample, +}; + +f32 gBendPitchOneOctaveFrequencies[] = { + 0.5f, 0.5f, 0.502736f, 0.505488f, 0.508254f, 0.511036f, 0.513833f, 0.516645f, 0.519472f, 0.522315f, + 0.525174f, 0.528048f, 0.530938f, 0.533843f, 0.536765f, 0.539702f, 0.542656f, 0.545626f, 0.548612f, 0.551614f, + 0.554633f, 0.557669f, 0.560721f, 0.563789f, 0.566875f, 0.569977f, 0.573097f, 0.576233f, 0.579387f, 0.582558f, + 0.585746f, 0.588951f, 0.592175f, 0.595415f, 0.598674f, 0.60195f, 0.605245f, 0.608557f, 0.611888f, 0.615236f, + 0.618603f, 0.621989f, 0.625393f, 0.628815f, 0.632257f, 0.635717f, 0.639196f, 0.642694f, 0.646212f, 0.649748f, + 0.653304f, 0.65688f, 0.660475f, 0.664089f, 0.667724f, 0.671378f, 0.675052f, 0.678747f, 0.682461f, 0.686196f, + 0.689952f, 0.693727f, 0.697524f, 0.701341f, 0.70518f, 0.709039f, 0.712919f, 0.716821f, 0.720744f, 0.724689f, + 0.728655f, 0.732642f, 0.736652f, 0.740684f, 0.744737f, 0.748813f, 0.752911f, 0.757031f, 0.761175f, 0.76534f, + 0.769529f, 0.77374f, 0.777975f, 0.782232f, 0.786513f, 0.790818f, 0.795146f, 0.799497f, 0.803873f, 0.808272f, + 0.812696f, 0.817144f, 0.821616f, 0.826112f, 0.830633f, 0.835179f, 0.83975f, 0.844346f, 0.848966f, 0.853613f, + 0.858284f, 0.862982f, 0.867704f, 0.872453f, 0.877228f, 0.882029f, 0.886856f, 0.891709f, 0.89659f, 0.901496f, + 0.90643f, 0.911391f, 0.916379f, 0.921394f, 0.926436f, 0.931507f, 0.936604f, 0.94173f, 0.946884f, 0.952066f, + 0.957277f, 0.962516f, 0.967783f, 0.97308f, 0.978405f, 0.98376f, 0.989144f, 0.994557f, 1.0f, 1.005473f, + 1.010975f, 1.016508f, 1.022071f, 1.027665f, 1.033289f, 1.038944f, 1.04463f, 1.050347f, 1.056095f, 1.061875f, + 1.067687f, 1.07353f, 1.079405f, 1.085312f, 1.091252f, 1.097224f, 1.103229f, 1.109267f, 1.115337f, 1.121441f, + 1.127579f, 1.13375f, 1.139955f, 1.146193f, 1.152466f, 1.158773f, 1.165115f, 1.171491f, 1.177903f, 1.184349f, + 1.190831f, 1.197348f, 1.203901f, 1.210489f, 1.217114f, 1.223775f, 1.230473f, 1.237207f, 1.243978f, 1.250786f, + 1.257631f, 1.264514f, 1.271434f, 1.278392f, 1.285389f, 1.292423f, 1.299497f, 1.306608f, 1.313759f, 1.320949f, + 1.328178f, 1.335447f, 1.342756f, 1.350104f, 1.357493f, 1.364922f, 1.372392f, 1.379903f, 1.387455f, 1.395048f, + 1.402683f, 1.41036f, 1.418078f, 1.425839f, 1.433642f, 1.441488f, 1.449377f, 1.457309f, 1.465285f, 1.473304f, + 1.481367f, 1.489474f, 1.497626f, 1.505822f, 1.514063f, 1.522349f, 1.530681f, 1.539058f, 1.547481f, 1.55595f, + 1.564465f, 1.573027f, 1.581636f, 1.590292f, 1.598995f, 1.607746f, 1.616545f, 1.625392f, 1.634287f, 1.643231f, + 1.652224f, 1.661266f, 1.670358f, 1.6795f, 1.688691f, 1.697933f, 1.707225f, 1.716569f, 1.725963f, 1.735409f, + 1.744906f, 1.754456f, 1.764058f, 1.773712f, 1.783419f, 1.793179f, 1.802993f, 1.81286f, 1.822782f, 1.832757f, + 1.842788f, 1.852873f, 1.863013f, 1.873209f, 1.883461f, 1.893768f, 1.904132f, 1.914553f, 1.925031f, 1.935567f, + 1.946159f, 1.95681f, 1.96752f, 1.978287f, 1.989114f, 2.0f, +}; + +f32 gBendPitchTwoSemitonesFrequencies[] = { + 0.890899f, 0.890899f, 0.89171f, 0.892521f, 0.893333f, 0.894146f, 0.89496f, 0.895774f, 0.89659f, 0.897406f, + 0.898222f, 0.89904f, 0.899858f, 0.900677f, 0.901496f, 0.902317f, 0.903138f, 0.90396f, 0.904783f, 0.905606f, + 0.90643f, 0.907255f, 0.908081f, 0.908907f, 0.909734f, 0.910562f, 0.911391f, 0.91222f, 0.91305f, 0.913881f, + 0.914713f, 0.915545f, 0.916379f, 0.917213f, 0.918047f, 0.918883f, 0.919719f, 0.920556f, 0.921394f, 0.922232f, + 0.923072f, 0.923912f, 0.924752f, 0.925594f, 0.926436f, 0.927279f, 0.928123f, 0.928968f, 0.929813f, 0.93066f, + 0.931507f, 0.932354f, 0.933203f, 0.934052f, 0.934902f, 0.935753f, 0.936604f, 0.937457f, 0.93831f, 0.939164f, + 0.940019f, 0.940874f, 0.94173f, 0.942587f, 0.943445f, 0.944304f, 0.945163f, 0.946023f, 0.946884f, 0.947746f, + 0.948608f, 0.949472f, 0.950336f, 0.951201f, 0.952066f, 0.952933f, 0.9538f, 0.954668f, 0.955537f, 0.956406f, + 0.957277f, 0.958148f, 0.95902f, 0.959893f, 0.960766f, 0.961641f, 0.962516f, 0.963392f, 0.964268f, 0.965146f, + 0.966024f, 0.966903f, 0.967783f, 0.968664f, 0.969546f, 0.970428f, 0.971311f, 0.972195f, 0.97308f, 0.973965f, + 0.974852f, 0.975739f, 0.976627f, 0.977516f, 0.978405f, 0.979296f, 0.980187f, 0.981079f, 0.981972f, 0.982865f, + 0.98376f, 0.984655f, 0.985551f, 0.986448f, 0.987346f, 0.988244f, 0.989144f, 0.990044f, 0.990945f, 0.991847f, + 0.992749f, 0.993653f, 0.994557f, 0.995462f, 0.996368f, 0.997275f, 0.998182f, 0.999091f, 1.0f, 1.00091f, + 1.001821f, 1.002733f, 1.003645f, 1.004559f, 1.005473f, 1.006388f, 1.007304f, 1.00822f, 1.009138f, 1.010056f, + 1.010975f, 1.011896f, 1.012816f, 1.013738f, 1.014661f, 1.015584f, 1.016508f, 1.017433f, 1.018359f, 1.019286f, + 1.020214f, 1.021142f, 1.022071f, 1.023002f, 1.023933f, 1.024864f, 1.025797f, 1.026731f, 1.027665f, 1.0286f, + 1.029536f, 1.030473f, 1.031411f, 1.03235f, 1.033289f, 1.03423f, 1.035171f, 1.036113f, 1.037056f, 1.038f, + 1.038944f, 1.03989f, 1.040836f, 1.041783f, 1.042731f, 1.04368f, 1.04463f, 1.045581f, 1.046532f, 1.047485f, + 1.048438f, 1.049392f, 1.050347f, 1.051303f, 1.05226f, 1.053217f, 1.054176f, 1.055135f, 1.056095f, 1.057056f, + 1.058018f, 1.058981f, 1.059945f, 1.06091f, 1.061875f, 1.062842f, 1.063809f, 1.064777f, 1.065746f, 1.066716f, + 1.067687f, 1.068658f, 1.069631f, 1.070604f, 1.071578f, 1.072554f, 1.07353f, 1.074507f, 1.075485f, 1.076463f, + 1.077443f, 1.078424f, 1.079405f, 1.080387f, 1.08137f, 1.082355f, 1.08334f, 1.084325f, 1.085312f, 1.0863f, + 1.087289f, 1.088278f, 1.089268f, 1.09026f, 1.091252f, 1.092245f, 1.093239f, 1.094234f, 1.09523f, 1.096226f, + 1.097224f, 1.098223f, 1.099222f, 1.100222f, 1.101224f, 1.102226f, 1.103229f, 1.104233f, 1.105238f, 1.106244f, + 1.10725f, 1.108258f, 1.109267f, 1.110276f, 1.111287f, 1.112298f, 1.11331f, 1.114323f, 1.115337f, 1.116352f, + 1.117368f, 1.118385f, 1.119403f, 1.120422f, 1.121441f, 1.122462f, +}; + +f32 gPitchFrequencies[] = { + /* 0x00 */ 0.105112f, // PITCH_A0 + /* 0x01 */ 0.111362f, // PITCH_BFLAT0 + /* 0x02 */ 0.117984f, // PITCH_B0 + /* 0x03 */ 0.125f, // PITCH_C1 + /* 0x04 */ 0.132433f, // PITCH_DFLAT1 + /* 0x05 */ 0.140308f, // PITCH_D1 + /* 0x06 */ 0.148651f, // PITCH_EFLAT1 + /* 0x07 */ 0.15749f, // PITCH_E1 + /* 0x08 */ 0.166855f, // PITCH_F1 + /* 0x09 */ 0.176777f, // PITCH_GFLAT1 + /* 0x0A */ 0.187288f, // PITCH_G1 + /* 0x0B */ 0.198425f, // PITCH_AFLAT1 + /* 0x0C */ 0.210224f, // PITCH_A1 + /* 0x0D */ 0.222725f, // PITCH_BFLAT1 + /* 0x0E */ 0.235969f, // PITCH_B1 + /* 0x0F */ 0.25f, // PITCH_C2 + /* 0x10 */ 0.264866f, // PITCH_DFLAT2 + /* 0x11 */ 0.280616f, // PITCH_D2 + /* 0x12 */ 0.297302f, // PITCH_EFLAT2 + /* 0x13 */ 0.31498f, // PITCH_E2 + /* 0x14 */ 0.33371f, // PITCH_F2 + /* 0x15 */ 0.353553f, // PITCH_GFLAT2 + /* 0x16 */ 0.374577f, // PITCH_G2 + /* 0x17 */ 0.39685f, // PITCH_AFLAT2 + /* 0x18 */ 0.420448f, // PITCH_A2 + /* 0x19 */ 0.445449f, // PITCH_BFLAT2 + /* 0x1A */ 0.471937f, // PITCH_B2 + /* 0x1B */ 0.5f, // PITCH_C3 + /* 0x1C */ 0.529732f, // PITCH_DFLAT3 + /* 0x1D */ 0.561231f, // PITCH_D3 + /* 0x1E */ 0.594604f, // PITCH_EFLAT3 + /* 0x1F */ 0.629961f, // PITCH_E3 + /* 0x20 */ 0.66742f, // PITCH_F3 + /* 0x21 */ 0.707107f, // PITCH_GFLAT3 + /* 0x22 */ 0.749154f, // PITCH_G3 + /* 0x23 */ 0.793701f, // PITCH_AFLAT3 + /* 0x24 */ 0.840897f, // PITCH_A3 + /* 0x25 */ 0.890899f, // PITCH_BFLAT3 + /* 0x26 */ 0.943875f, // PITCH_B3 + /* 0x27 */ 1.0f, // PITCH_C4 (Middle C) + /* 0x28 */ 1.059463f, // PITCH_DFLAT4 + /* 0x29 */ 1.122462f, // PITCH_D4 + /* 0x2A */ 1.189207f, // PITCH_EFLAT4 + /* 0x2B */ 1.259921f, // PITCH_E4 + /* 0x2C */ 1.33484f, // PITCH_F4 + /* 0x2D */ 1.414214f, // PITCH_GFLAT4 + /* 0x2E */ 1.498307f, // PITCH_G4 + /* 0x2F */ 1.587401f, // PITCH_AFLAT4 + /* 0x30 */ 1.681793f, // PITCH_A4 + /* 0x31 */ 1.781798f, // PITCH_BFLAT4 + /* 0x32 */ 1.887749f, // PITCH_B4 + /* 0x33 */ 2.0f, // PITCH_C5 + /* 0x34 */ 2.118926f, // PITCH_DFLAT5 + /* 0x35 */ 2.244924f, // PITCH_D5 + /* 0x36 */ 2.378414f, // PITCH_EFLAT5 + /* 0x37 */ 2.519842f, // PITCH_E5 + /* 0x38 */ 2.66968f, // PITCH_F5 + /* 0x39 */ 2.828428f, // PITCH_GFLAT5 + /* 0x3A */ 2.996615f, // PITCH_G5 + /* 0x3B */ 3.174803f, // PITCH_AFLAT5 + /* 0x3C */ 3.363586f, // PITCH_A5 + /* 0x3D */ 3.563596f, // PITCH_BFLAT5 + /* 0x3E */ 3.775498f, // PITCH_B5 + /* 0x3F */ 4.0f, // PITCH_C6 + /* 0x40 */ 4.237853f, // PITCH_DFLAT6 + /* 0x41 */ 4.489849f, // PITCH_D6 + /* 0x42 */ 4.756829f, // PITCH_EFLAT6 + /* 0x43 */ 5.039685f, // PITCH_E6 + /* 0x44 */ 5.33936f, // PITCH_F6 + /* 0x45 */ 5.656855f, // PITCH_GFLAT6 + /* 0x46 */ 5.993229f, // PITCH_G6 + /* 0x47 */ 6.349606f, // PITCH_AFLAT6 + /* 0x48 */ 6.727173f, // PITCH_A6 + /* 0x49 */ 7.127192f, // PITCH_BFLAT6 + /* 0x4A */ 7.550996f, // PITCH_B6 + /* 0x4B */ 8.0f, // PITCH_C7 + /* 0x4C */ 8.475705f, // PITCH_DFLAT7 + /* 0x4D */ 8.979697f, // PITCH_D7 + /* 0x4E */ 9.513658f, // PITCH_EFLAT7 + /* 0x4F */ 10.07937f, // PITCH_E7 + /* 0x50 */ 10.6787205f, // PITCH_F7 + /* 0x51 */ 11.31371f, // PITCH_GFLAT7 + /* 0x52 */ 11.986459f, // PITCH_G7 + /* 0x53 */ 12.699211f, // PITCH_AFLAT7 + /* 0x54 */ 13.454346f, // PITCH_A7 + /* 0x55 */ 14.254383f, // PITCH_BFLAT7 + /* 0x56 */ 15.101993f, // PITCH_B7 + /* 0x57 */ 16.0f, // PITCH_C8 + /* 0x58 */ 16.95141f, // PITCH_DFLAT8 + /* 0x59 */ 17.959395f, // PITCH_D8 + /* 0x5A */ 19.027315f, // PITCH_EFLAT8 + /* 0x5B */ 20.15874f, // PITCH_E8 + /* 0x5C */ 21.35744f, // PITCH_F8 + /* 0x5D */ 22.62742f, // PITCH_GFLAT8 + /* 0x5E */ 23.972918f, // PITCH_G8 + /* 0x5F */ 25.398422f, // PITCH_AFLAT8 + /* 0x60 */ 26.908691f, // PITCH_A8 + /* 0x61 */ 28.508766f, // PITCH_BFLAT8 + /* 0x62 */ 30.203985f, // PITCH_B8 + /* 0x63 */ 32.0f, // PITCH_C9 + /* 0x64 */ 33.90282f, // PITCH_DFLAT9 + /* 0x65 */ 35.91879f, // PITCH_D9 + /* 0x66 */ 38.05463f, // PITCH_EFLAT9 + /* 0x67 */ 40.31748f, // PITCH_E9 + /* 0x68 */ 42.71488f, // PITCH_F9 + /* 0x69 */ 45.25484f, // PITCH_GFLAT9 + /* 0x6A */ 47.945835f, // PITCH_G9 + /* 0x6B */ 50.796845f, // PITCH_AFLAT9 + /* 0x6C */ 53.817383f, // PITCH_A9 + /* 0x6D */ 57.017532f, // PITCH_BFLAT9 + /* 0x6E */ 60.40797f, // PITCH_B9 + /* 0x6F */ 64.0f, // PITCH_C10 + /* 0x70 */ 67.80564f, // PITCH_DFLAT10 + /* 0x71 */ 71.83758f, // PITCH_D10 + /* 0x72 */ 76.10926f, // PITCH_EFLAT10 + /* 0x73 */ 80.63496f, // PITCH_E10 + /* 0x74 */ 85.42976f, // PITCH_F10 + /* 0x75 */ 0.055681f, // PITCH_BFLATNEG1 + /* 0x76 */ 0.058992f, // PITCH_BNEG1 + /* 0x77 */ 0.0625f, // PITCH_C0 + /* 0x78 */ 0.066216f, // PITCH_DFLAT0 + /* 0x79 */ 0.070154f, // PITCH_D0 + /* 0x7A */ 0.074325f, // PITCH_EFLAT0 + /* 0x7B */ 0.078745f, // PITCH_E0 + /* 0x7C */ 0.083427f, // PITCH_F0 + /* 0x7D */ 0.088388f, // PITCH_GFLAT0 + /* 0x7E */ 0.093644f, // PITCH_G0 + /* 0x7F */ 0.099213f, // PITCH_AFLAT0 +}; + +u8 gDefaultShortNoteVelocityTable[] = { + 12, 25, 38, 51, 57, 64, 71, 76, 83, 89, 96, 102, 109, 115, 121, 127, +}; + +u8 gDefaultShortNoteGateTimeTable[] = { + 229, 203, 177, 151, 139, 126, 113, 100, 87, 74, 61, 48, 36, 23, 10, 0, +}; + +AdsrEnvelope gDefaultEnvelope[] = { + { 1, 32000 }, + { 1000, 32000 }, + { -1, 0 }, + { 0, 0 }, +}; + +NoteSubEu gZeroNoteSub = { 0 }; + +NoteSubEu gDefaultNoteSub = { + { 1, 1, 0, 0, 0, 0, 0, 0 }, { 0 }, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +u16 gHeadsetPanQuantization[64] = { + 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, + 16, 14, 12, 10, 8, 6, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +s32 D_801D58A4 = 0; + +// clang-format off +s16 D_801D58A8[] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 500, 0, 0, 0, 0, + 0, 0, 0, 500, 0, 0, 0, 0, + 0, 0, 0, 500, 0, 0, 0, 0, + 0, 0, 0, 500, 0, 0, 0, 0, +}; +// clang-format on + +f32 gHeadsetPanVolume[] = { + 1.0f, 0.995386f, 0.990772f, 0.986157f, 0.981543f, 0.976929f, 0.972315f, 0.967701f, 0.963087f, 0.958472f, + 0.953858f, 0.949244f, 0.94463f, 0.940016f, 0.935402f, 0.930787f, 0.926173f, 0.921559f, 0.916945f, 0.912331f, + 0.907717f, 0.903102f, 0.898488f, 0.893874f, 0.88926f, 0.884646f, 0.880031f, 0.875417f, 0.870803f, 0.866189f, + 0.861575f, 0.856961f, 0.852346f, 0.847732f, 0.843118f, 0.838504f, 0.83389f, 0.829276f, 0.824661f, 0.820047f, + 0.815433f, 0.810819f, 0.806205f, 0.801591f, 0.796976f, 0.792362f, 0.787748f, 0.783134f, 0.77852f, 0.773906f, + 0.769291f, 0.764677f, 0.760063f, 0.755449f, 0.750835f, 0.74622f, 0.741606f, 0.736992f, 0.732378f, 0.727764f, + 0.72315f, 0.718535f, 0.713921f, 0.709307f, 0.70537f, 0.70211f, 0.69885f, 0.695591f, 0.692331f, 0.689071f, + 0.685811f, 0.682551f, 0.679291f, 0.676031f, 0.672772f, 0.669512f, 0.666252f, 0.662992f, 0.659732f, 0.656472f, + 0.653213f, 0.649953f, 0.646693f, 0.643433f, 0.640173f, 0.636913f, 0.633654f, 0.630394f, 0.627134f, 0.623874f, + 0.620614f, 0.617354f, 0.614094f, 0.610835f, 0.607575f, 0.604315f, 0.601055f, 0.597795f, 0.594535f, 0.591276f, + 0.588016f, 0.584756f, 0.581496f, 0.578236f, 0.574976f, 0.571717f, 0.568457f, 0.565197f, 0.561937f, 0.558677f, + 0.555417f, 0.552157f, 0.548898f, 0.545638f, 0.542378f, 0.539118f, 0.535858f, 0.532598f, 0.529339f, 0.526079f, + 0.522819f, 0.519559f, 0.516299f, 0.513039f, 0.50978f, 0.50652f, 0.50326f, 0.5f, +}; + +f32 gStereoPanVolume[] = { + 0.707f, 0.716228f, 0.725457f, 0.734685f, 0.743913f, 0.753142f, 0.76237f, 0.771598f, 0.780827f, 0.790055f, + 0.799283f, 0.808512f, 0.81774f, 0.826968f, 0.836197f, 0.845425f, 0.854654f, 0.863882f, 0.87311f, 0.882339f, + 0.891567f, 0.900795f, 0.910024f, 0.919252f, 0.92848f, 0.937709f, 0.946937f, 0.956165f, 0.965394f, 0.974622f, + 0.98385f, 0.993079f, 0.997693f, 0.988465f, 0.979236f, 0.970008f, 0.960779f, 0.951551f, 0.942323f, 0.933095f, + 0.923866f, 0.914638f, 0.905409f, 0.896181f, 0.886953f, 0.877724f, 0.868496f, 0.859268f, 0.850039f, 0.840811f, + 0.831583f, 0.822354f, 0.813126f, 0.803898f, 0.794669f, 0.785441f, 0.776213f, 0.766984f, 0.757756f, 0.748528f, + 0.739299f, 0.730071f, 0.720843f, 0.711614f, 0.695866f, 0.673598f, 0.651331f, 0.629063f, 0.606795f, 0.584528f, + 0.56226f, 0.539992f, 0.517724f, 0.495457f, 0.473189f, 0.450921f, 0.428654f, 0.406386f, 0.384118f, 0.36185f, + 0.339583f, 0.317315f, 0.295047f, 0.27278f, 0.250512f, 0.228244f, 0.205976f, 0.183709f, 0.161441f, 0.139173f, + 0.116905f, 0.094638f, 0.07237f, 0.050102f, 0.027835f, 0.005567f, 0.00835f, 0.019484f, 0.030618f, 0.041752f, + 0.052886f, 0.06402f, 0.075154f, 0.086287f, 0.097421f, 0.108555f, 0.119689f, 0.130823f, 0.141957f, 0.153091f, + 0.164224f, 0.175358f, 0.186492f, 0.197626f, 0.20876f, 0.219894f, 0.231028f, 0.242161f, 0.253295f, 0.264429f, + 0.275563f, 0.286697f, 0.297831f, 0.308965f, 0.320098f, 0.331232f, 0.342366f, 0.3535f, +}; + +f32 gDefaultPanVolume[] = { + 1.0f, 0.999924f, 0.999694f, 0.999312f, 0.998776f, 0.998088f, 0.997248f, 0.996254f, 0.995109f, 0.993811f, + 0.992361f, 0.990759f, 0.989006f, 0.987101f, 0.985045f, 0.982839f, 0.980482f, 0.977976f, 0.97532f, 0.972514f, + 0.96956f, 0.966457f, 0.963207f, 0.959809f, 0.956265f, 0.952574f, 0.948737f, 0.944755f, 0.940629f, 0.936359f, + 0.931946f, 0.92739f, 0.922692f, 0.917853f, 0.912873f, 0.907754f, 0.902497f, 0.897101f, 0.891567f, 0.885898f, + 0.880093f, 0.874153f, 0.868079f, 0.861873f, 0.855535f, 0.849066f, 0.842467f, 0.835739f, 0.828884f, 0.821901f, + 0.814793f, 0.807561f, 0.800204f, 0.792725f, 0.785125f, 0.777405f, 0.769566f, 0.76161f, 0.753536f, 0.745348f, + 0.737045f, 0.72863f, 0.720103f, 0.711466f, 0.70272f, 0.693867f, 0.684908f, 0.675843f, 0.666676f, 0.657406f, + 0.648036f, 0.638567f, 0.629f, 0.619337f, 0.609579f, 0.599728f, 0.589785f, 0.579752f, 0.56963f, 0.559421f, + 0.549126f, 0.538748f, 0.528287f, 0.517745f, 0.507124f, 0.496425f, 0.485651f, 0.474802f, 0.46388f, 0.452888f, + 0.441826f, 0.430697f, 0.419502f, 0.408243f, 0.396921f, 0.385538f, 0.374097f, 0.362598f, 0.351044f, 0.339436f, + 0.327776f, 0.316066f, 0.304308f, 0.292503f, 0.280653f, 0.268761f, 0.256827f, 0.244854f, 0.232844f, 0.220798f, + 0.208718f, 0.196606f, 0.184465f, 0.172295f, 0.160098f, 0.147877f, 0.135634f, 0.12337f, 0.111087f, 0.098786f, + 0.086471f, 0.074143f, 0.061803f, 0.049454f, 0.037097f, 0.024734f, 0.012368f, 0.0f, +}; + +// clang-format off +s16 D_801D5F24[8 * (2 + 3 + 3)] = { + // floor(sin(i * M_PI / 16) * (2^15 - 1)) + 0, 6392, 12539, 18204, 23169, 27244, 30272, 32137, + 32767, 32137, 30272, 27244, 23169, 18204, 12539, 6392, + // -floor(sin(i * M_PI / 32) * (2^15 - 1)) + 0, -3211, -6392, -9511, -12539, -15446, -18204, -20787, + -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, + -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, + // -floor(sin(i * M_PI / 32) * (2^15 - 1)) + -23169, -25329, -27244, -28897, -30272, -31356, -32137, -32609, + -32767, -32609, -32137, -31356, -30272, -28897, -27244, -25329, + -23169, -20787, -18204, -15446, -12539, -9511, -6392, -3211, +}; +// clang-format on 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_effects.c b/src/code/audio/audio_effects.c new file mode 100644 index 000000000..2dcef2237 --- /dev/null +++ b/src/code/audio/audio_effects.c @@ -0,0 +1,341 @@ +#include "global.h" + +void AudioEffects_SequenceChannelProcessSound(SequenceChannel* channel, s32 recalculateVolume, s32 applyBend) { + f32 channelVolume; + f32 chanFreqScale; + s32 i; + + if (channel->changes.s.volume || recalculateVolume) { + channelVolume = channel->volume * channel->volumeScale * channel->seqPlayer->appliedFadeVolume; + if (channel->seqPlayer->muted && (channel->muteBehavior & 0x20)) { + channelVolume = channel->seqPlayer->muteVolumeScale * channelVolume; + } + channel->appliedVolume = channelVolume * channelVolume; + } + + if (channel->changes.s.pan) { + channel->pan = channel->newPan * channel->panChannelWeight; + } + + chanFreqScale = channel->freqScale; + if (applyBend) { + chanFreqScale *= channel->seqPlayer->bend; + channel->changes.s.freqScale = true; + } + + for (i = 0; i < ARRAY_COUNT(channel->layers); i++) { + SequenceLayer* layer = channel->layers[i]; + + if (layer != NULL && layer->enabled && layer->note != NULL) { + if (layer->notePropertiesNeedInit) { + layer->noteFreqScale = layer->freqScale * chanFreqScale; + layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; + layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; + layer->notePropertiesNeedInit = false; + } else { + if (channel->changes.s.freqScale) { + layer->noteFreqScale = layer->freqScale * chanFreqScale; + } + if (channel->changes.s.volume || recalculateVolume) { + layer->noteVelocity = layer->velocitySquare2 * channel->appliedVolume; + } + if (channel->changes.s.pan) { + layer->notePan = (channel->pan + layer->pan * (0x80 - channel->panChannelWeight)) >> 7; + } + } + } + } + channel->changes.asByte = 0; +} + +void AudioEffects_SequencePlayerProcessSound(SequencePlayer* seqPlayer) { + s32 i; + + if ((seqPlayer->fadeTimer != 0) && (seqPlayer->skipTicks == 0)) { + seqPlayer->fadeVolume += seqPlayer->fadeVelocity; + seqPlayer->recalculateVolume = true; + + if (seqPlayer->fadeVolume > 1.0f) { + seqPlayer->fadeVolume = 1.0f; + } + if (seqPlayer->fadeVolume < 0.0f) { + seqPlayer->fadeVolume = 0.0f; + } + + seqPlayer->fadeTimer--; + if (seqPlayer->fadeTimer == 0 && seqPlayer->state == 2) { + AudioSeq_SequencePlayerDisable(seqPlayer); + return; + } + } + + if (seqPlayer->recalculateVolume) { + seqPlayer->appliedFadeVolume = seqPlayer->fadeVolume * seqPlayer->fadeVolumeScale; + } + + for (i = 0; i < ARRAY_COUNT(seqPlayer->channels); i++) { + if (seqPlayer->channels[i]->enabled == true) { + AudioEffects_SequenceChannelProcessSound(seqPlayer->channels[i], seqPlayer->recalculateVolume, + seqPlayer->applyBend); + } + } + + seqPlayer->recalculateVolume = false; +} + +f32 AudioEffects_GetPortamentoFreqScale(Portamento* portamento) { + u32 loResCur; + f32 portamentoFreq; + + portamento->cur += portamento->speed; + loResCur = (portamento->cur >> 8) & 0xFF; + + if (loResCur >= 127) { + loResCur = 127; + portamento->mode = 0; + } + + portamentoFreq = AUDIO_LERPIMP(1.0f, gBendPitchOneOctaveFrequencies[loResCur + 128], portamento->extent); + + return portamentoFreq; +} + +s16 AudioEffects_GetVibratoPitchChange(VibratoState* vib) { + s32 index; + + vib->time += (s32)vib->rate; + index = (vib->time >> 10) & 0x3F; + return vib->curve[index]; +} + +f32 AudioEffects_GetVibratoFreqScale(VibratoState* vib) { + static f32 activeVibratoFreqScaleSum = 0.0f; + static s32 activeVibratoCount = 0; + f32 pitchChange; + f32 extent; + f32 invExtent; + f32 result; + f32 scaledExtent; + VibratoSubStruct* subVib = vib->vibSubStruct; + + if (vib->delay != 0) { + vib->delay--; + return 1.0f; + } + + if (subVib != NULL) { + if (vib->extentChangeTimer) { + if (vib->extentChangeTimer == 1) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } else { + vib->extent += ((s32)subVib->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer; + } + + vib->extentChangeTimer--; + } else if (subVib->vibratoExtentTarget != (s32)vib->extent) { + if ((vib->extentChangeTimer = subVib->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } + } + + if (vib->rateChangeTimer) { + if (vib->rateChangeTimer == 1) { + vib->rate = (s32)subVib->vibratoRateTarget; + } else { + vib->rate += ((s32)subVib->vibratoRateTarget - vib->rate) / (s32)vib->rateChangeTimer; + } + + vib->rateChangeTimer--; + } else if (subVib->vibratoRateTarget != (s32)vib->rate) { + if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { + vib->rate = (s32)subVib->vibratoRateTarget; + } + } + } + + if (vib->extent == 0.0f) { + return 1.0f; + } + + pitchChange = AudioEffects_GetVibratoPitchChange(vib) + 32768.0f; + scaledExtent = vib->extent / 4096.0f; + extent = scaledExtent + 1.0f; + invExtent = 1.0f / extent; + + // inverse linear interpolation + result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent); + + activeVibratoFreqScaleSum += result; + activeVibratoCount++; + + return result; +} + +void AudioEffects_NoteVibratoUpdate(Note* note) { + if (note->playbackState.portamento.mode != 0) { + note->playbackState.portamentoFreqScale = AudioEffects_GetPortamentoFreqScale(¬e->playbackState.portamento); + } + if (note->playbackState.vibratoState.active) { + note->playbackState.vibratoFreqScale = AudioEffects_GetVibratoFreqScale(¬e->playbackState.vibratoState); + } +} + +void AudioEffects_NoteVibratoInit(Note* note) { + NotePlaybackState* playbackState = ¬e->playbackState; + VibratoState* vib = &playbackState->vibratoState; + VibratoSubStruct* subVib; + + vib->active = true; + vib->curve = gWaveSamples[2]; + + if (playbackState->parentLayer->unk_0A.s.bit_3 == 1) { + vib->vibSubStruct = &playbackState->parentLayer->channel->vibrato; + } else { + vib->vibSubStruct = &playbackState->parentLayer->vibrato; + } + + subVib = vib->vibSubStruct; + + if ((vib->extentChangeTimer = subVib->vibratoExtentChangeDelay) == 0) { + vib->extent = (s32)subVib->vibratoExtentTarget; + } else { + vib->extent = (s32)subVib->vibratoExtentStart; + } + + if ((vib->rateChangeTimer = subVib->vibratoRateChangeDelay) == 0) { + vib->rate = (s32)subVib->vibratoRateTarget; + } else { + vib->rate = (s32)subVib->vibratoRateStart; + } + + playbackState->vibratoFreqScale = 1.0f; + vib->time = 0; + vib->delay = subVib->vibratoDelay; +} + +void AudioEffects_NotePortamentoInit(Note* note) { + note->playbackState.portamentoFreqScale = 1.0f; + note->playbackState.portamento = note->playbackState.parentLayer->portamento; +} + +void AudioEffects_AdsrInit(AdsrState* adsr, AdsrEnvelope* envelope, s16* volOut) { + adsr->action.asByte = 0; + adsr->delay = 0; + adsr->envelope = envelope; + adsr->sustain = 0.0f; + adsr->current = 0.0f; + adsr->velocity = 0.0f; + // (An older versions of the audio engine used in Super Mario 64 did + // adsr->volOut = volOut. That line and associated struct member were + // removed, but the function parameter was forgotten and remains.) +} + +f32 AudioEffects_AdsrUpdate(AdsrState* adsr) { + u8 state = adsr->action.s.state; + + switch (state) { + case ADSR_STATE_DISABLED: + return 0.0f; + + case ADSR_STATE_INITIAL: + if (adsr->action.s.hang) { + adsr->action.s.state = ADSR_STATE_HANG; + break; + } + // fallthrough + + case ADSR_STATE_START_LOOP: + adsr->envIndex = 0; + adsr->action.s.state = ADSR_STATE_LOOP; + // fallthrough + + retry: + case ADSR_STATE_LOOP: + adsr->delay = adsr->envelope[adsr->envIndex].delay; + switch (adsr->delay) { + case ADSR_DISABLE: + adsr->action.s.state = ADSR_STATE_DISABLED; + break; + case ADSR_HANG: + adsr->action.s.state = ADSR_STATE_HANG; + break; + case ADSR_GOTO: + adsr->envIndex = adsr->envelope[adsr->envIndex].arg; + goto retry; + case ADSR_RESTART: + adsr->action.s.state = ADSR_STATE_INITIAL; + break; + + default: + adsr->delay *= gAudioContext.audioBufferParameters.unk_24; + if (adsr->delay == 0) { + adsr->delay = 1; + } + adsr->target = adsr->envelope[adsr->envIndex].arg / 32767.0f; + adsr->target = adsr->target * adsr->target; + adsr->velocity = (adsr->target - adsr->current) / adsr->delay; + adsr->action.s.state = ADSR_STATE_FADE; + adsr->envIndex++; + break; + } + if (adsr->action.s.state != ADSR_STATE_FADE) { + break; + } + // fallthrough + + case ADSR_STATE_FADE: + adsr->current += adsr->velocity; + if (--adsr->delay <= 0) { + adsr->action.s.state = ADSR_STATE_LOOP; + } + // fallthrough + + case ADSR_STATE_HANG: + break; + + case ADSR_STATE_DECAY: + case ADSR_STATE_RELEASE: + adsr->current -= adsr->fadeOutVel; + if (adsr->sustain != 0.0f && state == ADSR_STATE_DECAY) { + if (adsr->current < adsr->sustain) { + adsr->current = adsr->sustain; + adsr->delay = 128; + adsr->action.s.state = ADSR_STATE_SUSTAIN; + } + break; + } + + if (adsr->current < 0.00001f) { + adsr->current = 0.0f; + adsr->action.s.state = ADSR_STATE_DISABLED; + } + break; + + case ADSR_STATE_SUSTAIN: + adsr->delay--; + if (adsr->delay == 0) { + adsr->action.s.state = ADSR_STATE_RELEASE; + } + break; + } + + if (adsr->action.s.decay) { + adsr->action.s.state = ADSR_STATE_DECAY; + adsr->action.s.decay = false; + } + + if (adsr->action.s.release) { + adsr->action.s.state = ADSR_STATE_RELEASE; + adsr->action.s.release = false; + } + + if (adsr->current < 0.0f) { + return 0.0f; + } + + if (adsr->current > 1.0f) { + return 1.0f; + } + + return adsr->current; +} diff --git a/src/code/audio/audio_heap.c b/src/code/audio/audio_heap.c new file mode 100644 index 000000000..b06f6a577 --- /dev/null +++ b/src/code/audio/audio_heap.c @@ -0,0 +1,1687 @@ +#include "global.h" + +void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id); +void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize); +SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size); +void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry); +void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample); +SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size); +void AudioHeap_DiscardSampleCaches(void); +void AudioHeap_DiscardSampleBank(s32 sampleBankId); +void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId); +void AudioHeap_DiscardSampleBanks(void); +void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags); + +#define gTatumsPerBeat (gAudioTatumInit[1]) + +f32 func_8018B0F0(f32 arg0) { + return 256.0f * gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled / arg0; +} + +void func_8018B10C(void) { + s32 i; + + gAudioContext.unk_3520[255] = func_8018B0F0(0.25f); + gAudioContext.unk_3520[254] = func_8018B0F0(0.33f); + gAudioContext.unk_3520[253] = func_8018B0F0(0.5f); + gAudioContext.unk_3520[252] = func_8018B0F0(0.66f); + gAudioContext.unk_3520[251] = func_8018B0F0(0.75f); + + for (i = 128; i < 251; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(251 - i); + } + + for (i = 16; i < 128; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(4 * (143 - i)); + } + + for (i = 1; i < 16; i++) { + gAudioContext.unk_3520[i] = func_8018B0F0(60 * (23 - i)); + } + + gAudioContext.unk_3520[0] = 0.0f; +} + +void AudioHeap_ResetLoadStatus(void) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(gAudioContext.fontLoadStatus); i++) { + if (gAudioContext.fontLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.fontLoadStatus[i] = LOAD_STATUS_0; + } + } + + for (i = 0; i < ARRAY_COUNT(gAudioContext.sampleFontLoadStatus); i++) { + if (gAudioContext.sampleFontLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.sampleFontLoadStatus[i] = LOAD_STATUS_0; + } + } + + for (i = 0; i < ARRAY_COUNT(gAudioContext.seqLoadStatus); i++) { + if (gAudioContext.seqLoadStatus[i] != LOAD_STATUS_5) { + gAudioContext.seqLoadStatus[i] = LOAD_STATUS_0; + } + } +} + +void AudioHeap_DiscardFont(s32 fontId) { + s32 i; + + for (i = 0; i < gAudioContext.numNotes; i++) { + Note* note = &gAudioContext.notes[i]; + + if (note->playbackState.fontId == fontId) { + if ((note->playbackState.unk_04 == 0) && (note->playbackState.priority != 0)) { + note->playbackState.parentLayer->enabled = false; + note->playbackState.parentLayer->finished = true; + } + + AudioPlayback_NoteDisable(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(&gAudioContext.noteFreeLists.disabled, ¬e->listItem); + } + } +} + +void AudioHeap_ReleaseNotesForFont(s32 fontId) { + s32 i; + + for (i = 0; i < gAudioContext.numNotes; i++) { + Note* note = &gAudioContext.notes[i]; + NotePlaybackState* playbackState = ¬e->playbackState; + + if (playbackState->fontId == fontId) { + if (playbackState->priority != 0) { + playbackState->priority = 1; + playbackState->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + playbackState->adsr.action.s.release = true; + } + } + } +} + +void AudioHeap_DiscardSequence(s32 seqId) { + s32 i; + + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && gAudioContext.seqPlayers[i].seqId == seqId) { + AudioSeq_SequencePlayerDisable(&gAudioContext.seqPlayers[i]); + } + } +} + +/** + * Perform a writeback from the L1 data cache to the ram. + */ +void* AudioHeap_WritebackDCache(void* addr, size_t size) { + Audio_WritebackDCache(addr, size); + if (addr) {} + + // KSEG0 to KSEG1 (ensures data is written straight to ram instead of the data cache) + return OS_PHYSICAL_TO_K1(OS_K0_TO_PHYSICAL(addr)); +} + +/** + * Attempt to allocated space on an external device. If no external device is available, + * then allocate space on the pool provided in the argument. + * Afterwards, zero all data pool the new allocated space + */ +void* AudioHeap_AllocZeroedAttemptExternal(AudioAllocPool* pool, size_t size) { + void* addr = NULL; + + if (gAudioContext.externalPool.startAddr != NULL) { + addr = AudioHeap_AllocZeroed(&gAudioContext.externalPool, size); + } + + if (addr == NULL) { + addr = AudioHeap_AllocZeroed(pool, size); + } + + return addr; +} + +/** + * Attempt to allocated space on an external device. If no external device is available, + * then allocate space on the pool provided in the argument + */ +void* AudioHeap_AllocAttemptExternal(AudioAllocPool* pool, size_t size) { + void* addr = NULL; + + if (gAudioContext.externalPool.startAddr != NULL) { + addr = AudioHeap_Alloc(&gAudioContext.externalPool, size); + } + + if (addr == NULL) { + addr = AudioHeap_Alloc(pool, size); + } + + return addr; +} + +void* AudioHeap_AllocDmaMemory(AudioAllocPool* pool, size_t size) { + void* addr = AudioHeap_Alloc(pool, size); + + if (addr != NULL) { + addr = AudioHeap_WritebackDCache(addr, size); + } + + return addr; +} + +void* AudioHeap_AllocDmaMemoryZeroed(AudioAllocPool* pool, size_t size) { + void* addr = AudioHeap_AllocZeroed(pool, size); + + if (addr != NULL) { + addr = AudioHeap_WritebackDCache(addr, size); + } + + return addr; +} + +/** + * Allocates space on a pool contained withing the heap and sets all the allocated space to 0 + */ +void* AudioHeap_AllocZeroed(AudioAllocPool* pool, size_t size) { + u8* addr = AudioHeap_Alloc(pool, size); + u8* ptr; + + if (addr != NULL) { + for (ptr = addr; ptr < pool->curAddr; ptr++) { + *ptr = 0; + } + } + + return addr; +} + +/** + * Tests the pool to see if the requested allocation would fit without actually allocating space. + * Returns NULL if there is not enough space on the pool. + * Else, return the address that would have been allocated + */ +void* AudioHeap_TestAlloc(AudioAllocPool* pool, size_t size) { + u8* oldAddr = pool->curAddr; + void* addr = AudioHeap_Alloc(pool, size); + + // remove allocation from pool + if (addr != NULL) { + pool->curAddr = oldAddr; + pool->count--; + } + + return addr; +} + +/** + * Allocates space on the pool contained withing the heap. If there is not enough space on the pool, return NULL + */ +void* AudioHeap_Alloc(AudioAllocPool* pool, size_t size) { + size_t alignedSize = ALIGN16(size); + u8* curAddr = pool->curAddr; + + if ((pool->startAddr + pool->size) >= (pool->curAddr + alignedSize)) { + pool->curAddr += alignedSize; + } else { + return NULL; + } + + pool->count++; + return curAddr; +} + +/** + * Initialize a pool at the requested address with the requested size. + * Store the metadata of this pool in AudioAllocPool* pool + */ +void AudioHeap_AllocPoolInit(AudioAllocPool* pool, void* addr, size_t size) { + pool->curAddr = pool->startAddr = (u8*)ALIGN16((uintptr_t)addr); + pool->size = size - ((uintptr_t)addr & 0xF); + pool->count = 0; +} + +void AudioHeap_ClearPersistentCache(AudioPersistentCache* persistent) { + persistent->pool.count = 0; + persistent->numEntries = 0; + persistent->pool.curAddr = persistent->pool.startAddr; +} + +void AudioHeap_ClearTemporaryCache(AudioTemporaryCache* temporary) { + temporary->pool.count = 0; + temporary->pool.curAddr = temporary->pool.startAddr; + temporary->nextSide = 0; + temporary->entries[0].addr = temporary->pool.startAddr; + temporary->entries[1].addr = temporary->pool.startAddr + temporary->pool.size; + temporary->entries[0].id = -1; + temporary->entries[1].id = -1; +} + +void AudioHeap_ResetPool(AudioAllocPool* pool) { + pool->count = 0; + pool->curAddr = pool->startAddr; +} + +void AudioHeap_PopCache(s32 tableType) { + AudioCache* loadedCache; + AudioAllocPool* persistentHeap; + AudioPersistentCache* persistent; + void* entryAddr; + u8* loadStatus; + + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + loadStatus = gAudioContext.seqLoadStatus; + break; + + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + loadStatus = gAudioContext.fontLoadStatus; + break; + + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + loadStatus = gAudioContext.sampleFontLoadStatus; + break; + } + + persistent = &loadedCache->persistent; + persistentHeap = &persistent->pool; + + if (persistent->numEntries == 0) { + return; + } + + entryAddr = persistent->entries[persistent->numEntries - 1].addr; + persistentHeap->curAddr = entryAddr; + persistentHeap->count--; + + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(persistent->entries[persistent->numEntries - 1].id); + } + if (tableType == FONT_TABLE) { + AudioHeap_DiscardFont(persistent->entries[persistent->numEntries - 1].id); + } + + loadStatus[persistent->entries[persistent->numEntries - 1].id] = LOAD_STATUS_0; + persistent->numEntries--; +} + +void AudioHeap_InitMainPool(size_t mainPoolSplitSize) { + AudioHeap_AllocPoolInit(&gAudioContext.audioInitPool, gAudioContext.audioHeap, mainPoolSplitSize); + AudioHeap_AllocPoolInit(&gAudioContext.audioSessionPool, gAudioContext.audioHeap + mainPoolSplitSize, + gAudioContext.audioHeapSize - mainPoolSplitSize); + + gAudioContext.externalPool.startAddr = NULL; +} + +void AudioHeap_InitSessionPool(AudioSessionPoolSplit* split) { + gAudioContext.audioSessionPool.curAddr = gAudioContext.audioSessionPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.miscPool, + AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->miscPoolSize), split->miscPoolSize); + AudioHeap_AllocPoolInit(&gAudioContext.cachePool, + AudioHeap_Alloc(&gAudioContext.audioSessionPool, split->cachePoolSize), + split->cachePoolSize); +} + +void AudioHeap_InitCachePool(AudioCachePoolSplit* split) { + gAudioContext.cachePool.curAddr = gAudioContext.cachePool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.persistentCommonPool, + AudioHeap_Alloc(&gAudioContext.cachePool, split->persistentCommonPoolSize), + split->persistentCommonPoolSize); + AudioHeap_AllocPoolInit(&gAudioContext.temporaryCommonPool, + AudioHeap_Alloc(&gAudioContext.cachePool, split->temporaryCommonPoolSize), + split->temporaryCommonPoolSize); +} + +void AudioHeap_InitPersistentCache(AudioCommonPoolSplit* split) { + gAudioContext.persistentCommonPool.curAddr = gAudioContext.persistentCommonPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.seqCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->seqCacheSize), + split->seqCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.fontCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->fontCacheSize), + split->fontCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.persistent.pool, + AudioHeap_Alloc(&gAudioContext.persistentCommonPool, split->sampleBankCacheSize), + split->sampleBankCacheSize); + + AudioHeap_ClearPersistentCache(&gAudioContext.seqCache.persistent); + AudioHeap_ClearPersistentCache(&gAudioContext.fontCache.persistent); + AudioHeap_ClearPersistentCache(&gAudioContext.sampleBankCache.persistent); +} + +void AudioHeap_InitTemporaryCache(AudioCommonPoolSplit* split) { + gAudioContext.temporaryCommonPool.curAddr = gAudioContext.temporaryCommonPool.startAddr; + + AudioHeap_AllocPoolInit(&gAudioContext.seqCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->seqCacheSize), + split->seqCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.fontCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->fontCacheSize), + split->fontCacheSize); + AudioHeap_AllocPoolInit(&gAudioContext.sampleBankCache.temporary.pool, + AudioHeap_Alloc(&gAudioContext.temporaryCommonPool, split->sampleBankCacheSize), + split->sampleBankCacheSize); + + AudioHeap_ClearTemporaryCache(&gAudioContext.seqCache.temporary); + AudioHeap_ClearTemporaryCache(&gAudioContext.fontCache.temporary); + AudioHeap_ClearTemporaryCache(&gAudioContext.sampleBankCache.temporary); +} + +void* AudioHeap_AllocCached(s32 tableType, size_t size, s32 cache, s32 id) { + AudioCache* loadedCache; + AudioTemporaryCache* temporaryCache; + AudioAllocPool* temporaryPool; + void* persistentAddr; + void* temporaryAddr; + u8 loadStatusEntry0; + u8 loadStatusEntry1; + s32 i; + u8* loadStatus; + s32 side; + + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + loadStatus = gAudioContext.seqLoadStatus; + break; + + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + loadStatus = gAudioContext.fontLoadStatus; + break; + + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + loadStatus = gAudioContext.sampleFontLoadStatus; + break; + } + + if (cache == CACHE_TEMPORARY) { + temporaryCache = &loadedCache->temporary; + temporaryPool = &temporaryCache->pool; + + if ((s32)temporaryPool->size < (s32)size) { + return NULL; + } + + loadStatusEntry0 = + (temporaryCache->entries[0].id == -1) ? LOAD_STATUS_0 : loadStatus[temporaryCache->entries[0].id]; + loadStatusEntry1 = + (temporaryCache->entries[1].id == -1) ? LOAD_STATUS_0 : loadStatus[temporaryCache->entries[1].id]; + + if (tableType == FONT_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_4) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[0].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + + if (i == gAudioContext.numNotes) { + AudioLoad_SetFontLoadStatus(temporaryCache->entries[0].id, LOAD_STATUS_3); + loadStatusEntry0 = LOAD_STATUS_3; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_4) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[1].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + + if (i == gAudioContext.numNotes) { + AudioLoad_SetFontLoadStatus(temporaryCache->entries[1].id, LOAD_STATUS_3); + loadStatusEntry1 = LOAD_STATUS_3; + } + } + } + + if (loadStatusEntry0 == LOAD_STATUS_0) { + temporaryCache->nextSide = 0; + } else if (loadStatusEntry1 == LOAD_STATUS_0) { + temporaryCache->nextSide = 1; + } else if ((loadStatusEntry0 == LOAD_STATUS_3) && (loadStatusEntry1 == LOAD_STATUS_3)) { + // Use the opposite side from last time. + } else if (loadStatusEntry0 == LOAD_STATUS_3) { + temporaryCache->nextSide = 0; + } else if (loadStatusEntry1 == LOAD_STATUS_3) { + temporaryCache->nextSide = 1; + } else { + // Check if there is a side which isn't in active use, if so, evict that one. + if (tableType == SEQUENCE_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && + gAudioContext.seqPlayers[i].seqId == temporaryCache->entries[0].id) { + break; + } + } + + if (i == gAudioContext.audioBufferParameters.numSequencePlayers) { + temporaryCache->nextSide = 0; + goto done; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + if (gAudioContext.seqPlayers[i].enabled && + gAudioContext.seqPlayers[i].seqId == temporaryCache->entries[1].id) { + break; + } + } + + if (i == gAudioContext.audioBufferParameters.numSequencePlayers) { + temporaryCache->nextSide = 1; + goto done; + } + } + } else if (tableType == FONT_TABLE) { + if (loadStatusEntry0 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[0].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + if (i == gAudioContext.numNotes) { + temporaryCache->nextSide = 0; + goto done; + } + } + + if (loadStatusEntry1 == LOAD_STATUS_2) { + for (i = 0; i < gAudioContext.numNotes; i++) { + if ((gAudioContext.notes[i].playbackState.fontId == temporaryCache->entries[1].id) && + gAudioContext.notes[i].noteSubEu.bitField0.enabled) { + break; + } + } + if (i == gAudioContext.numNotes) { + temporaryCache->nextSide = 1; + goto done; + } + } + } + + // No such luck. Evict the side that wasn't chosen last time, except + // if it is being loaded into. + if (temporaryCache->nextSide == 0) { + if (loadStatusEntry0 == LOAD_STATUS_1) { + if (loadStatusEntry1 == LOAD_STATUS_1) { + goto fail; + } + temporaryCache->nextSide = 1; + } + } else { + if (loadStatusEntry1 == LOAD_STATUS_1) { + if (loadStatusEntry0 == LOAD_STATUS_1) { + goto fail; + } + temporaryCache->nextSide = 0; + } + } + + if (0) { + fail: + // Both sides are being loaded into. + return NULL; + } + } + done: + + side = temporaryCache->nextSide; + + if (temporaryCache->entries[side].id != -1) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[side].id); + } + + loadStatus[temporaryCache->entries[side].id] = LOAD_STATUS_0; + + if (tableType == FONT_TABLE) { + AudioHeap_DiscardFont(temporaryCache->entries[side].id); + } + } + + switch (side) { + case 0: + temporaryCache->entries[0].addr = temporaryPool->startAddr; + temporaryCache->entries[0].id = id; + temporaryCache->entries[0].size = size; + temporaryPool->curAddr = temporaryPool->startAddr + size; + + if ((temporaryCache->entries[1].id != -1) && + (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[1].id); + } + + loadStatus[temporaryCache->entries[1].id] = LOAD_STATUS_0; + + switch (tableType) { + case SEQUENCE_TABLE: + AudioHeap_DiscardSequence((s32)temporaryCache->entries[1].id); + break; + + case FONT_TABLE: + AudioHeap_DiscardFont((s32)temporaryCache->entries[1].id); + break; + } + + temporaryCache->entries[1].id = -1; + temporaryCache->entries[1].addr = temporaryPool->startAddr + temporaryPool->size; + } + + temporaryAddr = temporaryCache->entries[0].addr; + break; + + case 1: + temporaryCache->entries[1].addr = + (u8*)((uintptr_t)(temporaryPool->startAddr + temporaryPool->size - size) & ~0xF); + temporaryCache->entries[1].id = id; + temporaryCache->entries[1].size = size; + if ((temporaryCache->entries[0].id != -1) && + (temporaryCache->entries[1].addr < temporaryPool->curAddr)) { + if (tableType == SAMPLE_TABLE) { + AudioHeap_DiscardSampleBank(temporaryCache->entries[0].id); + } + + loadStatus[temporaryCache->entries[0].id] = LOAD_STATUS_0; + + switch (tableType) { + case SEQUENCE_TABLE: + AudioHeap_DiscardSequence(temporaryCache->entries[0].id); + break; + + case FONT_TABLE: + AudioHeap_DiscardFont(temporaryCache->entries[0].id); + break; + } + + temporaryCache->entries[0].id = -1; + temporaryPool->curAddr = temporaryPool->startAddr; + } + + temporaryAddr = temporaryCache->entries[1].addr; + break; + + default: + return NULL; + } + + temporaryCache->nextSide ^= 1; + return temporaryAddr; + } + + persistentAddr = AudioHeap_Alloc(&loadedCache->persistent.pool, size); + loadedCache->persistent.entries[loadedCache->persistent.numEntries].addr = persistentAddr; + + if (persistentAddr == NULL) { + switch (cache) { + case CACHE_EITHER: + return AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, id); + + case CACHE_TEMPORARY: + case CACHE_PERSISTENT: + return NULL; + } + } + + loadedCache->persistent.entries[loadedCache->persistent.numEntries].id = id; + loadedCache->persistent.entries[loadedCache->persistent.numEntries].size = size; + + return loadedCache->persistent.entries[loadedCache->persistent.numEntries++].addr; +} + +void* AudioHeap_SearchCaches(s32 tableType, s32 cache, s32 id) { + void* addr; + + // Always search the permanent cache in addition to the regular ones. + addr = AudioHeap_SearchPermanentCache(tableType, id); + if (addr != NULL) { + return addr; + } + if (cache == CACHE_PERMANENT) { + return NULL; + } + return AudioHeap_SearchRegularCaches(tableType, cache, id); +} + +void* AudioHeap_SearchRegularCaches(s32 tableType, s32 cache, s32 id) { + u32 i; + AudioCache* loadedCache; + AudioTemporaryCache* temporary; + AudioPersistentCache* persistent; + + switch (tableType) { + case SEQUENCE_TABLE: + loadedCache = &gAudioContext.seqCache; + break; + + case FONT_TABLE: + loadedCache = &gAudioContext.fontCache; + break; + + case SAMPLE_TABLE: + loadedCache = &gAudioContext.sampleBankCache; + break; + } + + temporary = &loadedCache->temporary; + + if (cache == CACHE_TEMPORARY) { + if (temporary->entries[0].id == id) { + temporary->nextSide = 1; + return temporary->entries[0].addr; + } else if (temporary->entries[1].id == id) { + temporary->nextSide = 0; + return temporary->entries[1].addr; + } else { + return NULL; + } + } + + persistent = &loadedCache->persistent; + + for (i = 0; i < persistent->numEntries; i++) { + if (persistent->entries[i].id == id) { + return persistent->entries[i].addr; + } + } + + if (cache == CACHE_EITHER) { + return AudioHeap_SearchCaches(tableType, CACHE_TEMPORARY, id); + } + return NULL; +} + +void func_8018C4E4(f32 p, f32 q, u16* out) { + // With the bug below fixed, this mysterious unused function computes two recurrences + // out[0..7] = a_i, out[8..15] = b_i, where + // a_{-2} = b_{-1} = 262159 = 2^18 + 15 + // a_{-1} = b_{-2} = 0 + // a_i = q * a_{i-1} + p * a_{i-2} + // b_i = q * b_{i-1} + p * b_{i-2} + // These grow exponentially if p < -1 or p + |q| > 1. + s32 i; + f32 tmp[16]; + + tmp[0] = (f32)(q * 262159.0f); + tmp[8] = (f32)(p * 262159.0f); + tmp[1] = (f32)((q * p) * 262159.0f); + tmp[9] = (f32)(((p * p) + q) * 262159.0f); + + for (i = 2; i < 8; i++) { + //! @bug value should be stored to tmp[i] and tmp[8 + i], otherwise we read + //! garbage in later loop iterations. + out[i] = q * tmp[i - 2] + p * tmp[i - 1]; + out[8 + i] = q * tmp[6 + i] + p * tmp[7 + i]; + } + + for (i = 0; i < 16; i++) { + out[i] = tmp[i]; + } +} + +void AudioHeap_ClearFilter(s16* filter) { + s32 i; + + for (i = 0; i < 8; i++) { + filter[i] = 0; + } +} + +void AudioHeap_LoadLowPassFilter(s16* filter, s32 cutoff) { + s32 i; + s16* ptr = &gLowPassFilterData[8 * cutoff]; + + for (i = 0; i < 8; i++) { + filter[i] = ptr[i]; + } +} + +void AudioHeap_LoadHighPassFilter(s16* filter, s32 cutoff) { + s32 i; + s16* ptr = &gHighPassFilterData[8 * (cutoff - 1)]; + + for (i = 0; i < 8; i++) { + filter[i] = ptr[i]; + } +} + +void AudioHeap_LoadFilter(s16* filter, s32 lowPassCutoff, s32 highPassCutoff) { + s32 i; + s32 j; + s32 k; + s32 cutOff; + + //! @bug filter is never set if (lowPassCutoff == highPassCutoff) and does not equal 0 + if (lowPassCutoff == 0 && highPassCutoff == 0) { + // Identity filter + AudioHeap_LoadLowPassFilter(filter, 0); + } else if (highPassCutoff == 0) { + AudioHeap_LoadLowPassFilter(filter, lowPassCutoff); + } else if (lowPassCutoff == 0) { + AudioHeap_LoadHighPassFilter(filter, highPassCutoff); + } else { + k = 0; + j = 14; + + cutOff = lowPassCutoff; + if (lowPassCutoff < highPassCutoff) { + + for (i = 1; i < cutOff; i++) { + k += j; + j--; + } + + k += highPassCutoff - lowPassCutoff - 1; + for (i = 0; i < 8; i++) { + //! @bug should be gBandStopFilterData[8 * k + i]; + filter[i] = gBandStopFilterData[k + i]; + } + } else if (highPassCutoff < lowPassCutoff) { + + cutOff = highPassCutoff; + for (i = 1; i < cutOff; i++) { + k += j; + j--; + } + + k += lowPassCutoff - highPassCutoff - 1; + for (i = 0; i < 8; i++) { + //! @bug should be gBandPassFilterData[8 * k + i]; + filter[i] = gBandPassFilterData[k + i]; + } + } + } +} + +void AudioHeap_UpdateReverb(SynthesisReverb* reverb) { +} + +void AudioHeap_UpdateReverbs(void) { + s32 count; + s32 i; + s32 j; + + if (gAudioContext.audioBufferParameters.specUnk4 == 2) { + count = 2; + } else { + count = 1; + } + + for (i = 0; i < gAudioContext.numSynthesisReverbs; i++) { + for (j = 0; j < count; j++) { + AudioHeap_UpdateReverb(&gAudioContext.synthesisReverbs[i]); + } + } +} + +/** + * Clear the Audio Interface Buffers + */ +void AudioHeap_ClearAiBuffers(void) { + s32 curAiBuffferIndex = gAudioContext.curAiBuffferIndex; + s32 i; + + gAudioContext.aiBufLengths[curAiBuffferIndex] = gAudioContext.audioBufferParameters.minAiBufferLength; + + for (i = 0; i < AIBUF_LEN; i++) { + gAudioContext.aiBuffers[curAiBuffferIndex][i] = 0; + } +} + +s32 AudioHeap_ResetStep(void) { + s32 i; + s32 j; + s32 count; + + if (gAudioContext.audioBufferParameters.specUnk4 == 2) { + count = 2; + } else { + count = 1; + } + + switch (gAudioContext.resetStatus) { + case 5: + for (i = 0; i < gAudioContext.audioBufferParameters.numSequencePlayers; i++) { + AudioSeq_SequencePlayerDisableAsFinished(&gAudioContext.seqPlayers[i]); + } + gAudioContext.audioResetFadeOutFramesLeft = 2 / count; + gAudioContext.resetStatus--; + break; + + case 4: + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + AudioHeap_UpdateReverbs(); + } else { + for (i = 0; i < gAudioContext.numNotes; i++) { + if (gAudioContext.notes[i].noteSubEu.bitField0.enabled && + gAudioContext.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) { + gAudioContext.notes[i].playbackState.adsr.fadeOutVel = + gAudioContext.audioBufferParameters.updatesPerFrameInv; + gAudioContext.notes[i].playbackState.adsr.action.s.release = true; + } + } + gAudioContext.audioResetFadeOutFramesLeft = 8 / count; + gAudioContext.resetStatus--; + } + break; + + case 3: + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + AudioHeap_UpdateReverbs(); + } else { + gAudioContext.audioResetFadeOutFramesLeft = 2 / count; + gAudioContext.resetStatus--; + } + break; + + case 2: + AudioHeap_ClearAiBuffers(); + if (gAudioContext.audioResetFadeOutFramesLeft != 0) { + gAudioContext.audioResetFadeOutFramesLeft--; + } else { + gAudioContext.resetStatus--; + AudioHeap_DiscardSampleCaches(); + AudioHeap_DiscardSampleBanks(); + } + break; + + case 1: + AudioHeap_Init(); + gAudioContext.resetStatus = 0; + for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) { + gAudioContext.aiBufLengths[i] = gAudioContext.audioBufferParameters.maxAiBufferLength; + for (j = 0; j < AIBUF_LEN; j++) { + gAudioContext.aiBuffers[i][j] = 0; + } + } + break; + } + + if (gAudioContext.resetStatus < 3) { + return false; + } + + return true; +} + +void AudioHeap_Init(void) { + s32 pad1[4]; + s16* addr; + size_t persistentSize; + size_t temporarySize; + size_t cachePoolSize; + size_t miscPoolSize; + u32 intMask; + s32 i; + s32 j; + s32 pad2; + AudioSpec* spec = &gAudioSpecs[gAudioContext.audioResetSpecIdToLoad]; // Audio Specifications + + gAudioContext.sampleDmaCount = 0; + + // audio buffer parameters + gAudioContext.audioBufferParameters.samplingFreq = spec->samplingFreq; + gAudioContext.audioBufferParameters.aiSamplingFreq = + osAiSetFrequency(gAudioContext.audioBufferParameters.samplingFreq); + + gAudioContext.audioBufferParameters.samplesPerFrameTarget = + ALIGN16(gAudioContext.audioBufferParameters.samplingFreq / gAudioContext.refreshRate); + gAudioContext.audioBufferParameters.minAiBufferLength = + gAudioContext.audioBufferParameters.samplesPerFrameTarget - 0x10; + gAudioContext.audioBufferParameters.maxAiBufferLength = + gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10; + gAudioContext.audioBufferParameters.updatesPerFrame = + ((gAudioContext.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1; + gAudioContext.audioBufferParameters.samplesPerUpdate = (gAudioContext.audioBufferParameters.samplesPerFrameTarget / + gAudioContext.audioBufferParameters.updatesPerFrame) & + ~7; + gAudioContext.audioBufferParameters.samplesPerUpdateMax = gAudioContext.audioBufferParameters.samplesPerUpdate + 8; + gAudioContext.audioBufferParameters.samplesPerUpdateMin = gAudioContext.audioBufferParameters.samplesPerUpdate - 8; + gAudioContext.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioContext.audioBufferParameters.samplingFreq; + gAudioContext.audioBufferParameters.unkUpdatesPerFrameScaled = + (1.0f / 256.0f) / gAudioContext.audioBufferParameters.updatesPerFrame; + gAudioContext.audioBufferParameters.unk_24 = gAudioContext.audioBufferParameters.updatesPerFrame * 0.25f; + gAudioContext.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioContext.audioBufferParameters.updatesPerFrame; + + // sample dma size + gAudioContext.sampleDmaBufSize1 = spec->sampleDmaBufSize1; + gAudioContext.sampleDmaBufSize2 = spec->sampleDmaBufSize2; + + gAudioContext.numNotes = spec->numNotes; + gAudioContext.audioBufferParameters.numSequencePlayers = spec->numSequencePlayers; + + if (gAudioContext.audioBufferParameters.numSequencePlayers > 5) { + gAudioContext.audioBufferParameters.numSequencePlayers = 5; + } + + gAudioContext.unk_29BC = 8; + gAudioContext.unk_2 = spec->unk_14; + gAudioContext.tempoInternalToExternal = (u32)(gAudioContext.audioBufferParameters.updatesPerFrame * 2880000.0f / + gTatumsPerBeat / gAudioContext.unk_2960); + + gAudioContext.unk_2870 = gAudioContext.refreshRate; + gAudioContext.unk_2870 *= gAudioContext.audioBufferParameters.updatesPerFrame; + gAudioContext.unk_2870 /= gAudioContext.audioBufferParameters.aiSamplingFreq; + gAudioContext.unk_2870 /= gAudioContext.tempoInternalToExternal; + + gAudioContext.audioBufferParameters.specUnk4 = spec->unk_04; + gAudioContext.audioBufferParameters.samplesPerFrameTarget *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.maxAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.minAiBufferLength *= gAudioContext.audioBufferParameters.specUnk4; + gAudioContext.audioBufferParameters.updatesPerFrame *= gAudioContext.audioBufferParameters.specUnk4; + + if (gAudioContext.audioBufferParameters.specUnk4 >= 2) { + gAudioContext.audioBufferParameters.maxAiBufferLength -= 0x10; + } + + // Determine the maximum allowable number of audio command list entries for the rsp microcode + gAudioContext.maxAudioCmds = + gAudioContext.numNotes * 20 * gAudioContext.audioBufferParameters.updatesPerFrame + spec->numReverbs * 30 + 800; + + // Calculate sizes for various caches on the audio heap + persistentSize = + spec->persistentSeqCacheSize + spec->persistentFontCacheSize + spec->persistentSampleBankCacheSize + 0x10; + temporarySize = + spec->temporarySeqCacheSize + spec->temporaryFontCacheSize + spec->temporarySampleBankCacheSize + 0x10; + cachePoolSize = persistentSize + temporarySize; + miscPoolSize = gAudioContext.audioSessionPool.size - cachePoolSize - 0x100; + + if (gAudioContext.externalPool.startAddr != NULL) { + gAudioContext.externalPool.curAddr = gAudioContext.externalPool.startAddr; + } + + // Session Pool Split (split into Cache and Misc heaps) + gAudioContext.sessionPoolSplit.miscPoolSize = miscPoolSize; + gAudioContext.sessionPoolSplit.cachePoolSize = cachePoolSize; + AudioHeap_InitSessionPool(&gAudioContext.sessionPoolSplit); + + // Cache Pool Split (Split into Persistent and Temporary heaps) + gAudioContext.cachePoolSplit.persistentCommonPoolSize = persistentSize; + gAudioContext.cachePoolSplit.temporaryCommonPoolSize = temporarySize; + AudioHeap_InitCachePool(&gAudioContext.cachePoolSplit); + + // Persistent Pool Split (Split into Sequences, SoundFonts, Samples) + gAudioContext.persistentCommonPoolSplit.seqCacheSize = spec->persistentSeqCacheSize; + gAudioContext.persistentCommonPoolSplit.fontCacheSize = spec->persistentFontCacheSize; + gAudioContext.persistentCommonPoolSplit.sampleBankCacheSize = spec->persistentSampleBankCacheSize; + AudioHeap_InitPersistentCache(&gAudioContext.persistentCommonPoolSplit); + + // Temporary Pool Split (Split into Sequences, SoundFonts, Samples) + gAudioContext.temporaryCommonPoolSplit.seqCacheSize = spec->temporarySeqCacheSize; + gAudioContext.temporaryCommonPoolSplit.fontCacheSize = spec->temporaryFontCacheSize; + gAudioContext.temporaryCommonPoolSplit.sampleBankCacheSize = spec->temporarySampleBankCacheSize; + AudioHeap_InitTemporaryCache(&gAudioContext.temporaryCommonPoolSplit); + + AudioHeap_ResetLoadStatus(); + + // Initialize notes + gAudioContext.notes = AudioHeap_AllocZeroed(&gAudioContext.miscPool, gAudioContext.numNotes * sizeof(Note)); + AudioPlayback_NoteInitAll(); + AudioPlayback_InitNoteFreeList(); + gAudioContext.noteSubsEu = + AudioHeap_AllocZeroed(&gAudioContext.miscPool, gAudioContext.audioBufferParameters.updatesPerFrame * + gAudioContext.numNotes * sizeof(NoteSubEu)); + + // Initialize audio binary interface command list buffer + for (j = 0; j < ARRAY_COUNT(gAudioContext.abiCmdBufs); j++) { + gAudioContext.abiCmdBufs[j] = + AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, gAudioContext.maxAudioCmds * sizeof(u64)); + } + + // Initialize unk_3520 (fadeOutVelocities for ADSR) + gAudioContext.unk_3520 = AudioHeap_Alloc(&gAudioContext.miscPool, 0x100 * sizeof(f32)); + func_8018B10C(); + + // Initialize reverbs + for (i = 0; i < ARRAY_COUNT(gAudioContext.synthesisReverbs); i++) { + gAudioContext.synthesisReverbs[i].useReverb = 0; + } + + gAudioContext.numSynthesisReverbs = spec->numReverbs; + for (i = 0; i < gAudioContext.numSynthesisReverbs; i++) { + AudioHeap_InitReverb(i, &spec->reverbSettings[i], 1); + } + + // Initialize sequence players + AudioSeq_InitSequencePlayers(); + for (j = 0; j < gAudioContext.audioBufferParameters.numSequencePlayers; j++) { + AudioSeq_InitSequencePlayerChannels(j); + AudioSeq_ResetSequencePlayer(&gAudioContext.seqPlayers[j]); + } + + // Initialize two additional caches on the audio heap to store individual audio samples + AudioHeap_InitSampleCaches(spec->persistentSampleCacheSize, spec->temporarySampleCacheSize); + AudioLoad_InitSampleDmaBuffers(gAudioContext.numNotes); + + // Initalize Loads + gAudioContext.preloadSampleStackTop = 0; + AudioLoad_InitSlowLoads(); + AudioLoad_InitScriptLoads(); + AudioLoad_InitAsyncLoads(); + gAudioContext.unk_4 = 0x1000; + AudioLoad_LoadPermanentSamples(); + + intMask = osSetIntMask(1); + osWritebackDCacheAll(); + osSetIntMask(intMask); +} + +void* AudioHeap_SearchPermanentCache(s32 tableType, s32 id) { + s32 i; + + for (i = 0; i < gAudioContext.permanentPool.count; i++) { + if (gAudioContext.permanentEntries[i].tableType == tableType && gAudioContext.permanentEntries[i].id == id) { + return gAudioContext.permanentEntries[i].addr; + } + } + return NULL; +} + +void* AudioHeap_AllocPermanent(s32 tableType, s32 id, size_t size) { + void* addr; + s32 index = gAudioContext.permanentPool.count; + + addr = AudioHeap_Alloc(&gAudioContext.permanentPool, size); + gAudioContext.permanentEntries[index].addr = addr; + + if (addr == NULL) { + return NULL; + } + + gAudioContext.permanentEntries[index].tableType = tableType; + gAudioContext.permanentEntries[index].id = id; + gAudioContext.permanentEntries[index].size = size; + //! @bug UB: missing return. "addr" is in v0 at this point, but doing an + // explicit return uses an additional register. + // return addr; +} + +void* AudioHeap_AllocSampleCache(size_t size, s32 sampleBankId, void* sampleAddr, s8 medium, s32 cache) { + SampleCacheEntry* entry; + + if (cache == CACHE_TEMPORARY) { + entry = AudioHeap_AllocTemporarySampleCacheEntry(size); + } else { + entry = AudioHeap_AllocPersistentSampleCacheEntry(size); + } + + if (entry != NULL) { + entry->sampleBankId = sampleBankId; + entry->sampleAddr = sampleAddr; + entry->origMedium = medium; + return entry->allocatedAddr; + } + return NULL; +} + +/** + * Initializes the persistent and temporary caches used for individual samples. Will attempt to use heap space available + * on the external pool. If no external pool is provided, then default to using space on the misc heap. + */ +void AudioHeap_InitSampleCaches(size_t persistentSampleCacheSize, size_t temporarySampleCacheSize) { + void* addr; + + addr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, persistentSampleCacheSize); + if (addr == NULL) { + gAudioContext.persistentSampleCache.pool.size = 0; + } else { + AudioHeap_AllocPoolInit(&gAudioContext.persistentSampleCache.pool, addr, persistentSampleCacheSize); + } + + addr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, temporarySampleCacheSize); + if (addr == NULL) { + gAudioContext.temporarySampleCache.pool.size = 0; + } else { + AudioHeap_AllocPoolInit(&gAudioContext.temporarySampleCache.pool, addr, temporarySampleCacheSize); + } + + gAudioContext.persistentSampleCache.numEntries = 0; + gAudioContext.temporarySampleCache.numEntries = 0; +} + +SampleCacheEntry* AudioHeap_AllocTemporarySampleCacheEntry(size_t size) { + s32 pad2[2]; + void* addr; + s32 pad3[2]; + u8* allocAfter; + u8* allocBefore; + s32 pad1; + s32 index; + s32 i; + SampleCacheEntry* entry; + AudioPreloadReq* preload; + AudioSampleCache* cache; + u8* startAddr; + u8* endAddr; + + cache = &gAudioContext.temporarySampleCache; + allocBefore = cache->pool.curAddr; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + // Reset the heap and try again. We still keep pointers to within the + // heap, so we have to be careful to discard existing overlapping + // allocations further down. + u8* oldAddr = cache->pool.curAddr; + + cache->pool.curAddr = cache->pool.startAddr; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + cache->pool.curAddr = oldAddr; + return NULL; + } + allocBefore = cache->pool.startAddr; + } + + allocAfter = cache->pool.curAddr; + + index = -1; + for (i = 0; i < gAudioContext.preloadSampleStackTop; i++) { + preload = &gAudioContext.preloadSampleStack[i]; + if (preload->isFree == false) { + startAddr = preload->ramAddr; + endAddr = preload->ramAddr + preload->sample->size - 1; + + if ((endAddr < allocBefore) && (startAddr < allocBefore)) { + continue; + } + if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { + continue; + } + + // Overlap, skip this preload. + preload->isFree = true; + } + } + + for (i = 0; i < cache->numEntries; i++) { + if (!cache->entries[i].inUse) { + continue; + } + + startAddr = cache->entries[i].allocatedAddr; + endAddr = startAddr + cache->entries[i].size - 1; + + if ((endAddr < allocBefore) && (startAddr < allocBefore)) { + continue; + } + if ((endAddr >= allocAfter) && (startAddr >= allocAfter)) { + continue; + } + + // Overlap, discard existing entry. + AudioHeap_DiscardSampleCacheEntry(&cache->entries[i]); + cache->entries[i].inUse = false; + if (index == -1) { + index = i; + } + } + + if (index == -1) { + for (i = 0; i < cache->numEntries; i++) { + if (!cache->entries[i].inUse) { + break; + } + } + + index = i; + if (index == cache->numEntries) { + if (cache->numEntries == 128) { + return NULL; + } + cache->numEntries++; + } + } + + entry = &cache->entries[index]; + entry->inUse = 1; + entry->allocatedAddr = addr; + entry->size = size; + + return entry; +} + +void AudioHeap_UnapplySampleCacheForFont(SampleCacheEntry* entry, s32 fontId) { + Drum* drum; + Instrument* inst; + SoundFontSound* sfx; + s32 instId; + s32 drumId; + s32 sfxId; + + for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) { + inst = AudioPlayback_GetInstrumentInner(fontId, instId); + if (inst != NULL) { + if (inst->normalRangeLo != 0) { + AudioHeap_UnapplySampleCache(entry, inst->lowNotesSound.sample); + } + if (inst->normalRangeHi != 0x7F) { + AudioHeap_UnapplySampleCache(entry, inst->highNotesSound.sample); + } + AudioHeap_UnapplySampleCache(entry, inst->normalNotesSound.sample); + } + } + + for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) { + drum = AudioPlayback_GetDrum(fontId, drumId); + if (drum != NULL) { + AudioHeap_UnapplySampleCache(entry, drum->sound.sample); + } + } + + for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) { + sfx = AudioPlayback_GetSfx(fontId, sfxId); + if (sfx != NULL) { + AudioHeap_UnapplySampleCache(entry, sfx->sample); + } + } +} + +void AudioHeap_DiscardSampleCacheEntry(SampleCacheEntry* entry) { + s32 numFonts; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + + numFonts = gAudioContext.soundFontTable->numEntries; + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if (((sampleBankId1 != 0xFF) && (entry->sampleBankId == sampleBankId1)) || + ((sampleBankId2 != 0xFF) && (entry->sampleBankId == sampleBankId2)) || entry->sampleBankId == 0 || + entry->sampleBankId == 0xFE) { + if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) != NULL) { + if (1) {} + if (AudioLoad_IsFontLoadComplete(fontId) != 0) { + AudioHeap_UnapplySampleCacheForFont(entry, fontId); + } + } + } + } +} + +void AudioHeap_UnapplySampleCache(SampleCacheEntry* entry, SoundFontSample* sample) { + if (sample != NULL) { + if (sample->sampleAddr == entry->allocatedAddr) { + sample->sampleAddr = entry->sampleAddr; + sample->medium = entry->origMedium; + } + } +} + +SampleCacheEntry* AudioHeap_AllocPersistentSampleCacheEntry(size_t size) { + AudioSampleCache* cache; + SampleCacheEntry* entry; + void* addr; + + cache = &gAudioContext.persistentSampleCache; + addr = AudioHeap_Alloc(&cache->pool, size); + if (addr == NULL) { + return NULL; + } + + if (cache->numEntries == 128) { + return NULL; + } + + entry = &cache->entries[cache->numEntries]; + entry->inUse = true; + entry->allocatedAddr = addr; + entry->size = size; + cache->numEntries++; + + return entry; +} + +void AudioHeap_DiscardSampleCacheForFont(SampleCacheEntry* entry, s32 sampleBankId1, s32 sampleBankId2, s32 fontId) { + if ((entry->sampleBankId == sampleBankId1) || (entry->sampleBankId == sampleBankId2) || + (entry->sampleBankId == 0)) { + AudioHeap_UnapplySampleCacheForFont(entry, fontId); + } +} + +void AudioHeap_DiscardSampleCaches(void) { + s32 numFonts; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + s32 j; + + numFonts = gAudioContext.soundFontTable->numEntries; + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if ((sampleBankId1 == 0xFF) && (sampleBankId2 == 0xFF)) { + continue; + } + if (AudioHeap_SearchCaches(FONT_TABLE, CACHE_PERMANENT, fontId) == NULL || + !AudioLoad_IsFontLoadComplete(fontId)) { + continue; + } + + for (j = 0; j < gAudioContext.persistentSampleCache.numEntries; j++) { + AudioHeap_DiscardSampleCacheForFont(&gAudioContext.persistentSampleCache.entries[j], sampleBankId1, + sampleBankId2, fontId); + } + for (j = 0; j < gAudioContext.temporarySampleCache.numEntries; j++) { + AudioHeap_DiscardSampleCacheForFont(&gAudioContext.temporarySampleCache.entries[j], sampleBankId1, + sampleBankId2, fontId); + } + } +} + +typedef struct { + uintptr_t oldAddr; + uintptr_t newAddr; + size_t size; + u8 newMedium; +} StorageChange; + +void AudioHeap_ChangeStorage(StorageChange* change, SoundFontSample* sample) { + if (sample != NULL && ((sample->medium == change->newMedium) || (D_801FD120 != 1)) && + ((sample->medium == MEDIUM_RAM) || (D_801FD120 != 0))) { + uintptr_t startAddr = change->oldAddr; + uintptr_t endAddr = change->oldAddr + change->size; + + if (startAddr <= (uintptr_t)sample->sampleAddr && (uintptr_t)sample->sampleAddr < endAddr) { + sample->sampleAddr = sample->sampleAddr - startAddr + change->newAddr; + if (D_801FD120 == 0) { + sample->medium = change->newMedium; + } else { + sample->medium = MEDIUM_RAM; + } + } + } +} + +void AudioHeap_DiscardSampleBank(s32 sampleBankId) { + D_801FD120 = 0; + AudioHeap_ApplySampleBankCacheInternal(false, sampleBankId); +} + +void AudioHeap_ApplySampleBankCache(s32 sampleBankId) { + D_801FD120 = 1; + AudioHeap_ApplySampleBankCacheInternal(true, sampleBankId); +} + +void AudioHeap_ApplySampleBankCacheInternal(s32 apply, s32 sampleBankId) { + AudioTable* sampleBankTable; + AudioTableEntry* entry; + s32 numFonts; + s32 instId; + s32 drumId; + s32 sfxId; + StorageChange change; + s32 sampleBankId1; + s32 sampleBankId2; + s32 fontId; + Drum* drum; + Instrument* inst; + SoundFontSound* sfx; + uintptr_t* newAddr; + s32 pad[4]; + + sampleBankTable = gAudioContext.sampleBankTable; + numFonts = gAudioContext.soundFontTable->numEntries; + change.oldAddr = AudioHeap_SearchCaches(SAMPLE_TABLE, CACHE_EITHER, sampleBankId); + if (change.oldAddr == 0) { + return; + } + + entry = &sampleBankTable->entries[sampleBankId]; + change.size = entry->size; + change.newMedium = entry->medium; + change.newAddr = entry->romAddr; + + newAddr = &change.oldAddr; + if (apply && (apply == true)) { + uintptr_t oldAddr; + + oldAddr = change.newAddr; + + change.newAddr = *newAddr; + change.oldAddr = oldAddr; + } + + for (fontId = 0; fontId < numFonts; fontId++) { + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + if ((sampleBankId1 != 0xFF) || (sampleBankId2 != 0xFF)) { + if (!AudioLoad_IsFontLoadComplete(fontId) || + AudioHeap_SearchCaches(FONT_TABLE, CACHE_EITHER, fontId) == NULL) { + continue; + } + + if (sampleBankId1 == sampleBankId) { + } else if (sampleBankId2 == sampleBankId) { + } else { + continue; + } + + for (instId = 0; instId < gAudioContext.soundFonts[fontId].numInstruments; instId++) { + inst = AudioPlayback_GetInstrumentInner(fontId, instId); + if (inst != NULL) { + if (inst->normalRangeLo != 0) { + AudioHeap_ChangeStorage(&change, inst->lowNotesSound.sample); + } + if (inst->normalRangeHi != 0x7F) { + AudioHeap_ChangeStorage(&change, inst->highNotesSound.sample); + } + AudioHeap_ChangeStorage(&change, inst->normalNotesSound.sample); + } + } + + for (drumId = 0; drumId < gAudioContext.soundFonts[fontId].numDrums; drumId++) { + drum = AudioPlayback_GetDrum(fontId, drumId); + if (drum != NULL) { + AudioHeap_ChangeStorage(&change, drum->sound.sample); + } + } + + for (sfxId = 0; sfxId < gAudioContext.soundFonts[fontId].numSfx; sfxId++) { + sfx = AudioPlayback_GetSfx(fontId, sfxId); + if (sfx != NULL) { + AudioHeap_ChangeStorage(&change, sfx->sample); + } + } + } + } +} + +void AudioHeap_DiscardSampleBanks(void) { + AudioCache* cache; + AudioPersistentCache* persistent; + AudioTemporaryCache* temporary; + u32 i; + + cache = &gAudioContext.sampleBankCache; + temporary = &cache->temporary; + + if (temporary->entries[0].id != -1) { + AudioHeap_DiscardSampleBank(temporary->entries[0].id); + } + + if (temporary->entries[1].id != -1) { + AudioHeap_DiscardSampleBank(temporary->entries[1].id); + } + + persistent = &cache->persistent; + for (i = 0; i < persistent->numEntries; i++) { + AudioHeap_DiscardSampleBank(persistent->entries[i].id); + } +} + +void AudioHeap_SetReverbData(s32 reverbIndex, u32 dataType, s32 data, s32 flags) { + s32 windowSize; + SynthesisReverb* reverb = &gAudioContext.synthesisReverbs[reverbIndex]; + + switch (dataType) { + case 0: + AudioHeap_InitReverb(reverbIndex, (ReverbSettings*)data, 0); + break; + case 1: + if (data < 4) { + data = 4; + } + + windowSize = data * 64; + if (windowSize < 0x100) { + windowSize = 0x100; + } + + windowSize /= reverb->downsampleRate; + + if (flags == 0) { + if (reverb->unk_1E >= (data / reverb->downsampleRate)) { + if ((reverb->nextRingBufPos >= windowSize) || (reverb->unk_24 >= windowSize)) { + reverb->nextRingBufPos = 0; + reverb->unk_24 = 0; + } + } else { + break; + } + } + + reverb->windowSize = windowSize; + + if ((reverb->downsampleRate != 1) || reverb->unk_18) { + reverb->unk_0E = 0x8000 / reverb->downsampleRate; + if (reverb->unk_30 == NULL) { + reverb->unk_30 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioContext.miscPool, 0x20); + if (reverb->unk_3C == NULL) { + reverb->downsampleRate = 1; + } + } + } + break; + case 2: + gAudioContext.synthesisReverbs[reverbIndex].unk_0C = data; + break; + case 3: + gAudioContext.synthesisReverbs[reverbIndex].unk_16 = data; + break; + case 4: + gAudioContext.synthesisReverbs[reverbIndex].unk_0A = data; + break; + case 5: + gAudioContext.synthesisReverbs[reverbIndex].leakRtl = data; + break; + case 6: + gAudioContext.synthesisReverbs[reverbIndex].leakLtr = data; + break; + case 7: + if (data != 0) { + if ((flags != 0) || (reverb->unk_278 == 0)) { + reverb->filterLeftState = AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, 0x40); + reverb->unk_278 = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10); + } + + reverb->filterLeft = reverb->unk_278; + if (reverb->filterLeft != 0) { + AudioHeap_LoadLowPassFilter(reverb->filterLeft, data); + } + } else { + reverb->filterLeft = 0; + + if (flags != 0) { + reverb->unk_278 = 0; + } + } + + break; + case 8: + if (data != 0) { + if ((flags != 0) || (reverb->unk_27C == 0)) { + reverb->filterRightState = AudioHeap_AllocDmaMemoryZeroed(&gAudioContext.miscPool, 0x40); + reverb->unk_27C = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10); + } + reverb->filterRight = reverb->unk_27C; + if (reverb->unk_27C != 0) { + AudioHeap_LoadLowPassFilter(reverb->unk_27C, data); + } + } else { + reverb->filterRight = 0; + if (flags != 0) { + reverb->unk_27C = 0; + } + } + break; + case 9: + reverb->unk_19 = data; + if (data == 0) { + reverb->unk_18 = false; + } else { + reverb->unk_18 = true; + } + break; + default: + break; + } +} + +void AudioHeap_InitReverb(s32 reverbIndex, ReverbSettings* settings, s32 flags) { + SynthesisReverb* reverb = &gAudioContext.synthesisReverbs[reverbIndex]; + + if (flags != 0) { + reverb->unk_1E = settings->windowSize / settings->downsampleRate; + reverb->unk_30 = 0; + } else if (reverb->unk_1E < (settings->windowSize / settings->downsampleRate)) { + return; + } + + reverb->downsampleRate = settings->downsampleRate; + reverb->unk_18 = false; + reverb->unk_19 = 0; + reverb->unk_1A = 0; + reverb->unk_1C = 0; + AudioHeap_SetReverbData(reverbIndex, 1, settings->windowSize, flags); + reverb->unk_0C = settings->unk_4; + reverb->unk_0A = settings->unk_A; + reverb->unk_14 = settings->unk_6 << 6; + reverb->unk_16 = settings->unk_8; + reverb->leakRtl = settings->leakRtl; + reverb->leakLtr = settings->leakLtr; + reverb->unk_05 = settings->unk_10; + reverb->unk_08 = settings->unk_12; + reverb->useReverb = 8; + + if (flags != 0) { + reverb->leftRingBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioContext.miscPool, reverb->windowSize * 2); + reverb->rightRingBuf = AudioHeap_AllocZeroedAttemptExternal(&gAudioContext.miscPool, reverb->windowSize * 2); + reverb->resampleFlags = 1; + reverb->nextRingBufPos = 0; + reverb->unk_24 = 0; + reverb->curFrame = 0; + reverb->framesToIgnore = 2; + } + + reverb->sound.sample = &reverb->sample; + reverb->sample.loop = &reverb->loop; + reverb->sound.tuning = 1.0f; + reverb->sample.codec = CODEC_REVERB; + reverb->sample.medium = MEDIUM_RAM; + reverb->sample.size = reverb->windowSize * 2; + reverb->sample.sampleAddr = (u8*)reverb->leftRingBuf; + reverb->loop.start = 0; + reverb->loop.count = 1; + reverb->loop.end = reverb->windowSize; + + AudioHeap_SetReverbData(reverbIndex, 7, settings->lowPassFilterCutoffLeft, flags); + AudioHeap_SetReverbData(reverbIndex, 8, settings->lowPassFilterCutoffRight, flags); +} diff --git a/src/code/audio/audio_init_params.c b/src/code/audio/audio_init_params.c new file mode 100644 index 000000000..b407ef7c9 --- /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, // mainPoolSplitSize + 0x1A000, // permanentPoolSize +}; diff --git a/src/code/audio/audio_load.c b/src/code/audio/audio_load.c new file mode 100644 index 000000000..8faf565ea --- /dev/null +++ b/src/code/audio/audio_load.c @@ -0,0 +1,2163 @@ +/** + * @file audio_load.c + * + * Implements the transfer of audio data from the cartridge to the audio heap. + * + * The audio data in ROM consists of: + * 1) Sequences stored as a midi-based script called the music-macro language (.mus files) + * 2) SoundFonts stored as various sound-font structs bundled togther in a custom way + * that is extracted through relocs (See SoundFontData, generic .o files) + * 3) Samples consisting of raw soundbytes stored using a compressed ADPCM algorithm (.aifc files) + */ + +#include "global.h" + +/** + * SoundFont Notes: + * + */ +// opaque type for unpatched sound font data (should maybe get rid of this?) +typedef void SoundFontData; + +typedef struct { + /* 0x00 */ s32 sampleBankId1; + /* 0x04 */ s32 sampleBankId2; + /* 0x08 */ uintptr_t baseAddr1; + /* 0x0C */ uintptr_t baseAddr2; + /* 0x10 */ u32 medium1; + /* 0x14 */ u32 medium2; +} AudioRelocInfo; // size = 0x18 + +void AudioLoad_DiscardFont(s32 fontId); +s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2); +u8* AudioLoad_SyncLoadSeq(s32 seqId); +u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad); +SoundFontData* AudioLoad_SyncLoadFont(u32 fontId); +void* AudioLoad_SyncLoad(s32 tableType, u32 id, s32* didAllocate); +u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id); +void* AudioLoad_SearchCaches(s32 tableType, s32 id); +AudioTable* AudioLoad_GetLoadTable(s32 tableType); +void AudioLoad_SyncDma(uintptr_t devAddr, u8* addr, size_t size, s32 medium); +void AudioLoad_SyncDmaUnkMedium(uintptr_t devAddr, u8* addr, size_t size, s32 unkMediumParam); +s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr, void* ramAddr, size_t size, + OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType); +void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue); +SoundFontSample* AudioLoad_GetFontSample(s32 fontId, s32 instId); +void AudioLoad_ProcessSlowLoads(s32 resetStatus); +void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, size_t size); +void AudioLoad_DmaSlowCopyUnkMedium(intptr_t devAddr, intptr_t ramAddr, size_t size, s32 arg3); +AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, uintptr_t devAddr, void* ramAddr, size_t size, + s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg); +AudioAsyncLoad* AudioLoad_StartAsyncLoad(uintptr_t devAddr, void* ramAddr, size_t size, s32 medium, s32 nChunks, + OSMesgQueue* retQueue, s32 retMsg); +void AudioLoad_ProcessAsyncLoads(s32 resetStatus); +void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus); +void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus); +void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size); +void AudioLoad_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size); +void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t size, s16 arg3); +void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* fontData, AudioRelocInfo* relocInfo); +void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* fontData, AudioRelocInfo* relocInfo, s32 async); +s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus); + +#define MK_ASYNC_MSG(retData, tableType, id, loadStatus) \ + (((retData) << 24) | ((tableType) << 16) | ((id) << 8) | (loadStatus)) + +#define ASYNC_TBLTYPE(v) ((u8)(v >> 16)) +#define ASYNC_ID(v) ((u8)(v >> 8)) +#define ASYNC_STATUS(v) ((u8)(v >> 0)) + +typedef enum { + /* 0 */ LOAD_STATUS_WAITING, + /* 1 */ LOAD_STATUS_START, + /* 2 */ LOAD_STATUS_LOADING, + /* 3 */ LOAD_STATUS_DONE +} SlowLoadStatus; + +#define OS_MESG_PRI_NORMAL 0 +#define OS_MESG_PRI_HIGH 1 + +typedef struct { + u16 numInstruments; + u16 numDrums; + u16 numSfx; +} UnloadedFonts; + +OSMesgQueue sScriptLoadQueue; +OSMesg sScriptLoadMesgBuf[0x10]; +s8* sScriptLoadDonePointers[0x10]; +s32 sAudioLoadPad1[2]; // file padding +s32 D_801FD1E0; + +DmaHandler sDmaHandler = osEPiStartDma; +void* sUnusedHandler = NULL; +s32 gAudioContextInitalized = false; + +void AudioLoad_DecreaseSampleDmaTtls(void) { + u32 i; + + for (i = 0; i < gAudioContext.sampleDmaListSize1; i++) { + SampleDma* dma = &gAudioContext.sampleDmas[i]; + + if (dma->ttl != 0) { + dma->ttl--; + if (dma->ttl == 0) { + dma->reuseIndex = gAudioContext.sampleDmaReuseQueue1WrPos; + gAudioContext.sampleDmaReuseQueue1[gAudioContext.sampleDmaReuseQueue1WrPos] = i; + gAudioContext.sampleDmaReuseQueue1WrPos++; + } + } + } + + for (i = gAudioContext.sampleDmaListSize1; i < gAudioContext.sampleDmaCount; i++) { + SampleDma* dma = &gAudioContext.sampleDmas[i]; + + if (dma->ttl != 0) { + dma->ttl--; + if (dma->ttl == 0) { + dma->reuseIndex = gAudioContext.sampleDmaReuseQueue2WrPos; + gAudioContext.sampleDmaReuseQueue2[gAudioContext.sampleDmaReuseQueue2WrPos] = i; + gAudioContext.sampleDmaReuseQueue2WrPos++; + } + } + } + + gAudioContext.unused2648 = 0; +} + +void* AudioLoad_DmaSampleData(uintptr_t devAddr, size_t size, s32 arg2, u8* dmaIndexRef, s32 medium) { + s32 pad1; + SampleDma* dma; + s32 hasDma = false; + uintptr_t dmaDevAddr; + u32 pad2; + u32 dmaIndex; + u32 transfer; + s32 bufferPos; + u32 i; + + if (arg2 != 0 || *dmaIndexRef >= gAudioContext.sampleDmaListSize1) { + for (i = gAudioContext.sampleDmaListSize1; i < gAudioContext.sampleDmaCount; i++) { + dma = &gAudioContext.sampleDmas[i]; + bufferPos = devAddr - dma->devAddr; + if (0 <= bufferPos && ((u32)bufferPos <= dma->size - size)) { + // We already have a DMA request for this memory range. + if (dma->ttl == 0 && + gAudioContext.sampleDmaReuseQueue2RdPos != gAudioContext.sampleDmaReuseQueue2WrPos) { + // Move the DMA out of the reuse queue, by swapping it with the + // read pos, and then incrementing the read pos. + if (dma->reuseIndex != gAudioContext.sampleDmaReuseQueue2RdPos) { + gAudioContext.sampleDmaReuseQueue2[dma->reuseIndex] = + gAudioContext.sampleDmaReuseQueue2[gAudioContext.sampleDmaReuseQueue2RdPos]; + gAudioContext + .sampleDmas[gAudioContext.sampleDmaReuseQueue2[gAudioContext.sampleDmaReuseQueue2RdPos]] + .reuseIndex = dma->reuseIndex; + } + gAudioContext.sampleDmaReuseQueue2RdPos++; + } + dma->ttl = 32; + *dmaIndexRef = (u8)i; + return dma->ramAddr + (devAddr - dma->devAddr); + } + } + + if (arg2 == 0) { + goto search_short_lived; + } + + if (gAudioContext.sampleDmaReuseQueue2RdPos != gAudioContext.sampleDmaReuseQueue2WrPos && arg2 != 0) { + // Allocate a DMA from reuse queue 2, unless full. + dmaIndex = gAudioContext.sampleDmaReuseQueue2[gAudioContext.sampleDmaReuseQueue2RdPos]; + gAudioContext.sampleDmaReuseQueue2RdPos++; + dma = gAudioContext.sampleDmas + dmaIndex; + hasDma = true; + } + } else { + search_short_lived: + dma = gAudioContext.sampleDmas + *dmaIndexRef; + i = 0; + again: + bufferPos = devAddr - dma->devAddr; + if (0 <= bufferPos && (u32)bufferPos <= dma->size - size) { + // We already have DMA for this memory range. + if (dma->ttl == 0) { + // Move the DMA out of the reuse queue, by swapping it with the + // read pos, and then incrementing the read pos. + if (dma->reuseIndex != gAudioContext.sampleDmaReuseQueue1RdPos) { + gAudioContext.sampleDmaReuseQueue1[dma->reuseIndex] = + gAudioContext.sampleDmaReuseQueue1[gAudioContext.sampleDmaReuseQueue1RdPos]; + gAudioContext + .sampleDmas[gAudioContext.sampleDmaReuseQueue1[gAudioContext.sampleDmaReuseQueue1RdPos]] + .reuseIndex = dma->reuseIndex; + } + gAudioContext.sampleDmaReuseQueue1RdPos++; + } + dma->ttl = 2; + return dma->ramAddr + (devAddr - dma->devAddr); + } + dma = gAudioContext.sampleDmas + i++; + if (i <= gAudioContext.sampleDmaListSize1) { + goto again; + } + } + + if (!hasDma) { + if (gAudioContext.sampleDmaReuseQueue1RdPos == gAudioContext.sampleDmaReuseQueue1WrPos) { + return NULL; + } + // Allocate a DMA from reuse queue 1. + dmaIndex = gAudioContext.sampleDmaReuseQueue1[gAudioContext.sampleDmaReuseQueue1RdPos++]; + dma = gAudioContext.sampleDmas + dmaIndex; + hasDma = true; + } + + transfer = dma->size; + dmaDevAddr = devAddr & ~0xF; + dma->ttl = 3; + dma->devAddr = dmaDevAddr; + dma->sizeUnused = transfer; + AudioLoad_Dma(&gAudioContext.currAudioFrameDmaIoMesgBuf[gAudioContext.curAudioFrameDmaCount++], OS_MESG_PRI_NORMAL, + OS_READ, dmaDevAddr, dma->ramAddr, transfer, &gAudioContext.currAudioFrameDmaQueue, medium, + "SUPERDMA"); + *dmaIndexRef = dmaIndex; + return (devAddr - dmaDevAddr) + dma->ramAddr; +} + +// This string does not appear to belong in context to any function between the previous string and the next string +const char D_801E030C[] = "TYPE %d:ID %d is not External Map.\n"; + +void AudioLoad_InitSampleDmaBuffers(s32 numNotes) { + SampleDma* dma; + s32 i; + s32 t2; + s32 j; + + gAudioContext.sampleDmaBufSize = gAudioContext.sampleDmaBufSize1; + gAudioContext.sampleDmas = + AudioHeap_Alloc(&gAudioContext.miscPool, + 4 * gAudioContext.numNotes * sizeof(SampleDma) * gAudioContext.audioBufferParameters.specUnk4); + t2 = 3 * gAudioContext.numNotes * gAudioContext.audioBufferParameters.specUnk4; + + // First 3/4 sampleDmas + for (i = 0; i < t2; i++) { + dma = &gAudioContext.sampleDmas[gAudioContext.sampleDmaCount]; + dma->ramAddr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, gAudioContext.sampleDmaBufSize); + if (dma->ramAddr == NULL) { + break; + } else { + AudioHeap_WritebackDCache(dma->ramAddr, gAudioContext.sampleDmaBufSize); + dma->size = gAudioContext.sampleDmaBufSize; + dma->devAddr = 0; + dma->sizeUnused = 0; + dma->unused = 0; + dma->ttl = 0; + gAudioContext.sampleDmaCount++; + } + } + + for (i = 0; (u32)i < gAudioContext.sampleDmaCount; i++) { + gAudioContext.sampleDmaReuseQueue1[i] = i; + gAudioContext.sampleDmas[i].reuseIndex = i; + } + + for (i = gAudioContext.sampleDmaCount; i < 0x100; i++) { + gAudioContext.sampleDmaReuseQueue1[i] = 0; + } + + gAudioContext.sampleDmaReuseQueue1RdPos = 0; + gAudioContext.sampleDmaReuseQueue1WrPos = gAudioContext.sampleDmaCount; + gAudioContext.sampleDmaListSize1 = gAudioContext.sampleDmaCount; + gAudioContext.sampleDmaBufSize = gAudioContext.sampleDmaBufSize2; + + for (j = 0; j < gAudioContext.numNotes; j++) { + dma = &gAudioContext.sampleDmas[gAudioContext.sampleDmaCount]; + dma->ramAddr = AudioHeap_AllocAttemptExternal(&gAudioContext.miscPool, gAudioContext.sampleDmaBufSize); + if (dma->ramAddr == NULL) { + break; + } else { + AudioHeap_WritebackDCache(dma->ramAddr, gAudioContext.sampleDmaBufSize); + dma->size = gAudioContext.sampleDmaBufSize; + dma->devAddr = 0U; + dma->sizeUnused = 0; + dma->unused = 0; + dma->ttl = 0; + gAudioContext.sampleDmaCount++; + } + } + + for (i = gAudioContext.sampleDmaListSize1; (u32)i < gAudioContext.sampleDmaCount; i++) { + gAudioContext.sampleDmaReuseQueue2[i - gAudioContext.sampleDmaListSize1] = i; + gAudioContext.sampleDmas[i].reuseIndex = i - gAudioContext.sampleDmaListSize1; + } + + for (i = gAudioContext.sampleDmaCount; i < 0x100; i++) { + gAudioContext.sampleDmaReuseQueue2[i] = gAudioContext.sampleDmaListSize1; + } + + gAudioContext.sampleDmaReuseQueue2RdPos = 0; + gAudioContext.sampleDmaReuseQueue2WrPos = gAudioContext.sampleDmaCount - gAudioContext.sampleDmaListSize1; +} + +s32 AudioLoad_IsFontLoadComplete(s32 fontId) { + if (fontId == 0xFF) { + return true; + } else if (gAudioContext.fontLoadStatus[fontId] >= LOAD_STATUS_2) { + return true; + } else if (gAudioContext.fontLoadStatus[AudioLoad_GetRealTableIndex(FONT_TABLE, fontId)] >= LOAD_STATUS_2) { + return true; + } else { + return false; + } +} + +s32 AudioLoad_IsSeqLoadComplete(s32 seqId) { + if (seqId == 0xFF) { + return true; + } else if (gAudioContext.seqLoadStatus[seqId] >= LOAD_STATUS_2) { + return true; + } else if (gAudioContext.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] >= LOAD_STATUS_2) { + return true; + } else { + return false; + } +} + +s32 AudioLoad_IsSampleLoadComplete(s32 sampleBankId) { + if (sampleBankId == 0xFF) { + return true; + } else if (gAudioContext.sampleFontLoadStatus[sampleBankId] >= LOAD_STATUS_2) { + return true; + } else if (gAudioContext.sampleFontLoadStatus[AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankId)] >= + LOAD_STATUS_2) { + return true; + } else { + return false; + } +} + +void AudioLoad_SetFontLoadStatus(s32 fontId, s32 loadStatus) { + if ((fontId != 0xFF) && (gAudioContext.fontLoadStatus[fontId] != LOAD_STATUS_5)) { + gAudioContext.fontLoadStatus[fontId] = loadStatus; + } +} + +void AudioLoad_SetSeqLoadStatus(s32 seqId, s32 loadStatus) { + if ((seqId != 0xFF) && (gAudioContext.seqLoadStatus[seqId] != LOAD_STATUS_5)) { + gAudioContext.seqLoadStatus[seqId] = loadStatus; + } +} + +void AudioLoad_SetSampleFontLoadStatusAndApplyCaches(s32 sampleBankId, s32 loadStatus) { + if (sampleBankId != 0xFF) { + if (gAudioContext.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_5) { + gAudioContext.sampleFontLoadStatus[sampleBankId] = loadStatus; + } + + if ((gAudioContext.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_5) || + (gAudioContext.sampleFontLoadStatus[sampleBankId] == LOAD_STATUS_2)) { + AudioHeap_ApplySampleBankCache(sampleBankId); + } + } +} + +void AudioLoad_SetSampleFontLoadStatus(s32 sampleBankId, s32 loadStatus) { + if ((sampleBankId != 0xFF) && (gAudioContext.sampleFontLoadStatus[sampleBankId] != LOAD_STATUS_5)) { + gAudioContext.sampleFontLoadStatus[sampleBankId] = loadStatus; + } +} + +void AudioLoad_InitTable(AudioTable* table, uintptr_t romAddr, u16 unkMediumParam) { + s32 i; + + table->unkMediumParam = unkMediumParam; + table->romAddr = romAddr; + + for (i = 0; i < table->numEntries; i++) { + if ((table->entries[i].size != 0) && (table->entries[i].medium == MEDIUM_CART)) { + table->entries[i].romAddr += romAddr; + } + } +} + +SoundFontData* AudioLoad_SyncLoadSeqFonts(s32 seqId, u32* outDefaultFontId) { + s32 pad[2]; + s32 index; + SoundFontData* fontData; + s32 numFonts; + s32 fontId; + s32 i; + + if (seqId >= gAudioContext.numSequences) { + return NULL; + } + + fontId = 0xFF; + index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + numFonts = gAudioContext.sequenceFontTable[index++]; + + while (numFonts > 0) { + fontId = gAudioContext.sequenceFontTable[index++]; + fontData = AudioLoad_SyncLoadFont(fontId); + numFonts--; + } + + *outDefaultFontId = fontId; + return fontData; +} + +void AudioLoad_SyncLoadSeqParts(s32 seqId, s32 arg1, s32 arg2, OSMesgQueue* arg3) { + s32 pad; + u32 defaultFontId; + + if (seqId < gAudioContext.numSequences) { + if (arg1 & 2) { + AudioLoad_SyncLoadSeqFonts(seqId, &defaultFontId); + } + if (arg1 & 1) { + AudioLoad_SyncLoadSeq(seqId); + } + if (arg2 != 0) { + osSendMesg(arg3, arg2 << 0x18, OS_MESG_NOBLOCK); + } + } +} + +s32 AudioLoad_SyncLoadSample(SoundFontSample* sample, s32 fontId) { + void* sampleAddr; + + if (sample->unk_bit25 == true) { + if (sample->medium != MEDIUM_RAM) { + sampleAddr = AudioHeap_AllocSampleCache(sample->size, fontId, (void*)sample->sampleAddr, sample->medium, + CACHE_PERSISTENT); + if (sampleAddr == NULL) { + return -1; + } + + if (sample->medium == MEDIUM_UNK) { + AudioLoad_SyncDmaUnkMedium(sample->sampleAddr, sampleAddr, sample->size, + gAudioContext.sampleBankTable->unkMediumParam); + } else { + AudioLoad_SyncDma(sample->sampleAddr, sampleAddr, sample->size, sample->medium); + } + sample->medium = MEDIUM_RAM; + sample->sampleAddr = sampleAddr; + } + } +} + +s32 AudioLoad_SyncLoadInstrument(s32 fontId, s32 instId, s32 drumId) { + if (instId < 0x7F) { + Instrument* instrument = AudioPlayback_GetInstrumentInner(fontId, instId); + + if (instrument == NULL) { + return -1; + } + if (instrument->normalRangeLo != 0) { + AudioLoad_SyncLoadSample(instrument->lowNotesSound.sample, fontId); + } + AudioLoad_SyncLoadSample(instrument->normalNotesSound.sample, fontId); + if (instrument->normalRangeHi != 0x7F) { + return AudioLoad_SyncLoadSample(instrument->highNotesSound.sample, fontId); + } + // TODO: is this missing return UB? + } else if (instId == 0x7F) { + Drum* drum = AudioPlayback_GetDrum(fontId, drumId); + + if (drum == NULL) { + return -1; + } + AudioLoad_SyncLoadSample(drum->sound.sample, fontId); + return 0; + } + // TODO: is this missing return UB? +} + +void AudioLoad_AsyncLoad(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { + if (AudioLoad_AsyncLoadInner(tableType, id, nChunks, retData, retQueue) == NULL) { + osSendMesg(retQueue, 0xFFFFFFFF, OS_MESG_NOBLOCK); + } +} + +void AudioLoad_AsyncLoadSeq(s32 seqId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { + AudioLoad_AsyncLoad(SEQUENCE_TABLE, seqId, 0, retData, retQueue); +} + +void AudioLoad_AsyncLoadSampleBank(s32 sampleBankId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { + AudioLoad_AsyncLoad(SAMPLE_TABLE, sampleBankId, 0, retData, retQueue); +} + +void AudioLoad_AsyncLoadFont(s32 fontId, s32 arg1, s32 retData, OSMesgQueue* retQueue) { + AudioLoad_AsyncLoad(FONT_TABLE, fontId, 0, retData, retQueue); +} + +u8* AudioLoad_GetFontsForSequence(s32 seqId, u32* outNumFonts) { + s32 index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + + *outNumFonts = gAudioContext.sequenceFontTable[index++]; + if (*outNumFonts == 0) { + return NULL; + } + return &gAudioContext.sequenceFontTable[index]; +} + +void AudioLoad_DiscardSeqFonts(s32 seqId) { + s32 fontId; + s32 index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + s32 numFonts = gAudioContext.sequenceFontTable[index++]; + + while (numFonts > 0) { + numFonts--; + fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioContext.sequenceFontTable[index++]); + if (AudioHeap_SearchPermanentCache(FONT_TABLE, fontId) == NULL) { + AudioLoad_DiscardFont(fontId); + AudioLoad_SetFontLoadStatus(fontId, LOAD_STATUS_0); + } + } +} + +void AudioLoad_DiscardFont(s32 fontId) { + u32 i; + AudioCache* pool = &gAudioContext.fontCache; + AudioPersistentCache* persistent; + + if (fontId == pool->temporary.entries[0].id) { + pool->temporary.entries[0].id = -1; + } else if (fontId == pool->temporary.entries[1].id) { + pool->temporary.entries[1].id = -1; + } + + persistent = &pool->persistent; + for (i = 0; i < persistent->numEntries; i++) { + if (fontId == persistent->entries[i].id) { + persistent->entries[i].id = -1; + } + } + + AudioHeap_DiscardFont(fontId); +} + +void func_8018FA60(u32 tableType, u32 id, s32 type, s32 data) { + AudioTable* table = AudioLoad_GetLoadTable(tableType); + + if (table->entries[id].medium == MEDIUM_RAM_UNLOADED) { + switch (type) { + case 0: + table->entries[id].romAddr = data; + break; + case 1: + table->entries[id].size = data; + break; + default: + break; + } + } +} + +s32 AudioLoad_SyncInitSeqPlayer(s32 playerIdx, s32 seqId, s32 arg2) { + if (gAudioContext.resetTimer != 0) { + return 0; + } + + gAudioContext.seqPlayers[playerIdx].skipTicks = 0; + AudioLoad_SyncInitSeqPlayerInternal(playerIdx, seqId, arg2); + // Intentionally missing return. Returning the result of the above function + // call matches but is UB because it too is missing a return, and using the + // result of a non-void function that has failed to return a value is UB. + // The callers of this function do not use the return value, so it's fine. +} + +s32 AudioLoad_SyncInitSeqPlayerSkipTicks(s32 playerIdx, s32 seqId, s32 skipTicks) { + if (gAudioContext.resetTimer != 0) { + return 0; + } + + gAudioContext.seqPlayers[playerIdx].skipTicks = skipTicks; + AudioLoad_SyncInitSeqPlayerInternal(playerIdx, seqId, 0); + // Missing return, see above. +} + +s32 AudioLoad_SyncInitSeqPlayerInternal(s32 playerIdx, s32 seqId, s32 arg2) { + SequencePlayer* seqPlayer = &gAudioContext.seqPlayers[playerIdx]; + u8* seqData; + s32 index; + s32 numFonts; + s32 fontId; + + if (seqId >= gAudioContext.numSequences) { + return 0; + } + + AudioSeq_SequencePlayerDisable(seqPlayer); + + if (1) {} + fontId = 0xFF; + index = ((u16*)gAudioContext.sequenceFontTable)[seqId]; + numFonts = gAudioContext.sequenceFontTable[index++]; + + while (numFonts > 0) { + fontId = gAudioContext.sequenceFontTable[index++]; + AudioLoad_SyncLoadFont(fontId); + numFonts--; + } + + seqData = AudioLoad_SyncLoadSeq(seqId); + if (seqData == NULL) { + return 0; + } + + AudioSeq_ResetSequencePlayer(seqPlayer); + seqPlayer->seqId = seqId; + + if (fontId != 0xFF) { + seqPlayer->defaultFont = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); + } else { + seqPlayer->defaultFont = 0xFF; + } + + seqPlayer->seqData = seqData; + seqPlayer->enabled = true; + seqPlayer->scriptState.pc = seqData; + seqPlayer->scriptState.depth = 0; + seqPlayer->delay = 0; + seqPlayer->finished = false; + seqPlayer->playerIdx = playerIdx; + //! @bug missing return (but the return value is not used so it's not UB) +} + +u8* AudioLoad_SyncLoadSeq(s32 seqId) { + s32 pad; + s32 didAllocate; + + if (gAudioContext.seqLoadStatus[AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId)] == LOAD_STATUS_1) { + return NULL; + } + + return AudioLoad_SyncLoad(SEQUENCE_TABLE, seqId, &didAllocate); +} + +u32 AudioLoad_GetSampleBank(u32 sampleBankId, u32* outMedium) { + return AudioLoad_TrySyncLoadSampleBank(sampleBankId, outMedium, true); +} + +u32 AudioLoad_TrySyncLoadSampleBank(u32 sampleBankId, u32* outMedium, s32 noLoad) { + void* addr; + AudioTable* sampleBankTable; + u32 realTableId = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, sampleBankId); + s8 cachePolicy; + + sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE); + + addr = AudioLoad_SearchCaches(SAMPLE_TABLE, realTableId); + if (addr != NULL) { + if (gAudioContext.sampleFontLoadStatus[realTableId] != LOAD_STATUS_1) { + AudioLoad_SetSampleFontLoadStatus(realTableId, LOAD_STATUS_2); + } + + *outMedium = MEDIUM_RAM; + return addr; + } + + cachePolicy = sampleBankTable->entries[sampleBankId].cachePolicy; + + if ((cachePolicy == CACHE_LOAD_EITHER_NOSYNC) || (noLoad == true)) { + *outMedium = sampleBankTable->entries[sampleBankId].medium; + return sampleBankTable->entries[realTableId].romAddr; + } + + addr = AudioLoad_SyncLoad(SAMPLE_TABLE, sampleBankId, &noLoad); + if (addr != NULL) { + *outMedium = MEDIUM_RAM; + return addr; + } + + *outMedium = sampleBankTable->entries[sampleBankId].medium; + return sampleBankTable->entries[realTableId].romAddr; +} + +SoundFontData* AudioLoad_SyncLoadFont(u32 fontId) { + SoundFontData* fontData; + s32 sampleBankId1; + s32 sampleBankId2; + s32 didAllocate; + AudioRelocInfo relocInfo; + s32 realFontId = AudioLoad_GetRealTableIndex(FONT_TABLE, fontId); + + if (gAudioContext.fontLoadStatus[realFontId] == LOAD_STATUS_1) { + return NULL; + } + + sampleBankId1 = gAudioContext.soundFonts[realFontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[realFontId].sampleBankId2; + + relocInfo.sampleBankId1 = sampleBankId1; + relocInfo.sampleBankId2 = sampleBankId2; + if (relocInfo.sampleBankId1 != 0xFF) { + relocInfo.baseAddr1 = AudioLoad_TrySyncLoadSampleBank(relocInfo.sampleBankId1, &relocInfo.medium1, false); + } else { + relocInfo.baseAddr1 = 0; + } + + if (sampleBankId2 != 0xFF) { + relocInfo.baseAddr2 = AudioLoad_TrySyncLoadSampleBank(sampleBankId2, &relocInfo.medium2, false); + } else { + relocInfo.baseAddr2 = 0; + } + + fontData = AudioLoad_SyncLoad(FONT_TABLE, fontId, &didAllocate); + if (fontData == NULL) { + return NULL; + } + if (didAllocate == true) { + AudioLoad_RelocateFontAndPreloadSamples(realFontId, fontData, &relocInfo, false); + } + + return fontData; +} + +void* AudioLoad_SyncLoad(s32 tableType, u32 id, s32* didAllocate) { + size_t size; + AudioTable* table; + s32 medium2; + u32 medium; + s32 loadStatus; + uintptr_t romAddr; + s32 cachePolicy; + void* ramAddr; + u32 realId; + s32 mediumUnk = MEDIUM_UNK; + + realId = AudioLoad_GetRealTableIndex(tableType, id); + ramAddr = AudioLoad_SearchCaches(tableType, realId); + if (ramAddr != NULL) { + *didAllocate = false; + loadStatus = LOAD_STATUS_2; + } else { + table = AudioLoad_GetLoadTable(tableType); + size = table->entries[realId].size; + size = ALIGN16(size); + medium = table->entries[id].medium; + cachePolicy = table->entries[id].cachePolicy; + romAddr = table->entries[realId].romAddr; + switch (cachePolicy) { + case CACHE_LOAD_PERMANENT: + ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHE_LOAD_PERSISTENT: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + case CACHE_LOAD_TEMPORARY: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHE_LOAD_EITHER: + case CACHE_LOAD_EITHER_NOSYNC: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + } + + *didAllocate = true; + + medium2 = medium; + if (medium == MEDIUM_RAM_UNLOADED) { + if (romAddr == 0) { + return NULL; + } + + if (tableType == FONT_TABLE) { + SoundFont* soundFont = &gAudioContext.soundFonts[realId]; + + soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments; + soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums; + soundFont->numSfx = ((UnloadedFonts*)romAddr)->numSfx; + romAddr += 0x10; + size -= 0x10; + } + + bcopy(romAddr, ramAddr, size); + } else if (medium2 == mediumUnk) { + AudioLoad_SyncDmaUnkMedium(romAddr, ramAddr, size, (s16)table->unkMediumParam); + } else { + AudioLoad_SyncDma(romAddr, ramAddr, size, medium); + } + + loadStatus = (cachePolicy == CACHE_LOAD_PERMANENT) ? LOAD_STATUS_5 : LOAD_STATUS_2; + } + + switch (tableType) { + case SEQUENCE_TABLE: + AudioLoad_SetSeqLoadStatus(realId, loadStatus); + break; + case FONT_TABLE: + AudioLoad_SetFontLoadStatus(realId, loadStatus); + break; + case SAMPLE_TABLE: + AudioLoad_SetSampleFontLoadStatusAndApplyCaches(realId, loadStatus); + break; + default: + break; + } + + return ramAddr; +} + +u32 AudioLoad_GetRealTableIndex(s32 tableType, u32 id) { + AudioTable* table = AudioLoad_GetLoadTable(tableType); + + if (table->entries[id].size == 0) { + id = table->entries[id].romAddr; + } + + return id; +} + +void* AudioLoad_SearchCaches(s32 tableType, s32 id) { + void* addr; + + addr = AudioHeap_SearchPermanentCache(tableType, id); + if (addr != NULL) { + return addr; + } + + addr = AudioHeap_SearchCaches(tableType, CACHE_EITHER, id); + if (addr != NULL) { + return addr; + } + + return NULL; +} + +AudioTable* AudioLoad_GetLoadTable(s32 tableType) { + AudioTable* table; + + switch (tableType) { + case SEQUENCE_TABLE: + table = gAudioContext.sequenceTable; + break; + case FONT_TABLE: + table = gAudioContext.soundFontTable; + break; + default: + table = NULL; + break; + case SAMPLE_TABLE: + table = gAudioContext.sampleBankTable; + break; + } + return table; +} + +/** + * + * SoundFontData* mem -> the address of the soundFont as stored in memory + */ +void AudioLoad_RelocateFont(s32 fontId, SoundFontData* fontData, AudioRelocInfo* relocInfo) { + uintptr_t reloc; + uintptr_t reloc2; + Instrument* inst; + Drum* drum; + SoundFontSound* sfx; + s32 i; + s32 numDrums = gAudioContext.soundFonts[fontId].numDrums; + s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments; + s32 numSfx = gAudioContext.soundFonts[fontId].numSfx; + void** ptrs = (void**)fontData; + +#define BASE_OFFSET(x) (void*)((uintptr_t)(x) + (uintptr_t)(fontData)) + + // relocate drums + reloc2 = ptrs[0]; + if (1) {} + if ((reloc2 != 0) && (numDrums != 0)) { + ptrs[0] = BASE_OFFSET(reloc2); + for (i = 0; i < numDrums; i++) { + reloc = ((Drum**)ptrs[0])[i]; + if (reloc != 0) { + reloc = BASE_OFFSET(reloc); + ((Drum**)ptrs[0])[i] = drum = reloc; + if (!drum->loaded) { + AudioLoad_RelocateSample(&drum->sound, fontData, relocInfo); + reloc = drum->envelope; + drum->envelope = BASE_OFFSET(reloc); + drum->loaded = true; + } + } + } + } + + // relocate sfxs + reloc2 = ptrs[1]; + if (1) {} + if ((reloc2 != 0) && (numSfx != 0)) { + ptrs[1] = BASE_OFFSET(reloc2); + for (i = 0; i < numSfx; i++) { + reloc = (SoundFontSound*)ptrs[1] + i; + if (reloc != 0) { + sfx = reloc; + if (sfx->sample != NULL) { + AudioLoad_RelocateSample(sfx, fontData, relocInfo); + } + } + } + } + + if (numInstruments > 0x7E) { + numInstruments = 0x7E; + } + + // relocate instruments + for (i = 2; i <= 2 + numInstruments - 1; i++) { + if (ptrs[i] != NULL) { + ptrs[i] = BASE_OFFSET(ptrs[i]); + inst = ptrs[i]; + if (!inst->loaded) { + if (inst->normalRangeLo != 0) { + AudioLoad_RelocateSample(&inst->lowNotesSound, fontData, relocInfo); + } + AudioLoad_RelocateSample(&inst->normalNotesSound, fontData, relocInfo); + if (inst->normalRangeHi != 0x7F) { + AudioLoad_RelocateSample(&inst->highNotesSound, fontData, relocInfo); + } + + reloc = inst->envelope; + inst->envelope = BASE_OFFSET(reloc); + inst->loaded = true; + } + } + } + +#undef BASE_OFFSET + + gAudioContext.soundFonts[fontId].drums = ptrs[0]; + gAudioContext.soundFonts[fontId].soundEffects = ptrs[1]; + gAudioContext.soundFonts[fontId].instruments = (Instrument**)(&ptrs[2]); +} + +void AudioLoad_SyncDma(uintptr_t devAddr, u8* ramAddr, size_t size, s32 medium) { + OSMesgQueue* msgQueue = &gAudioContext.syncDmaQueue; + OSIoMesg* ioMesg = &gAudioContext.syncDmaIoMesg; + size = ALIGN16(size); + + Audio_InvalDCache(ramAddr, size); + + while (true) { + if (size < 0x400) { + break; + } + AudioLoad_Dma(ioMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, ramAddr, 0x400, msgQueue, medium, "FastCopy"); + osRecvMesg(msgQueue, NULL, OS_MESG_BLOCK); + size -= 0x400; + devAddr += 0x400; + ramAddr += 0x400; + } + + if (size != 0) { + AudioLoad_Dma(ioMesg, OS_MESG_PRI_HIGH, OS_READ, devAddr, ramAddr, size, msgQueue, medium, "FastCopy"); + osRecvMesg(msgQueue, NULL, OS_MESG_BLOCK); + } +} + +void AudioLoad_SyncDmaUnkMedium(uintptr_t devAddr, u8* ramAddr, size_t size, s32 unkMediumParam) { +} + +s32 AudioLoad_Dma(OSIoMesg* mesg, u32 priority, s32 direction, uintptr_t devAddr, void* ramAddr, size_t size, + OSMesgQueue* reqQueue, s32 medium, const char* dmaFuncType) { + OSPiHandle* handle; + + if (gAudioContext.resetTimer > 16) { + return -1; + } + + switch (medium) { + case MEDIUM_CART: + handle = gAudioContext.cartHandle; + break; + + case MEDIUM_DISK_DRIVE: + // driveHandle is uninitialized and corresponds to stubbed-out disk drive support. + // SM64 Shindou called osDriveRomInit here. + handle = gAudioContext.driveHandle; + break; + + default: + return 0; + } + + if ((size % 0x10) != 0) { + size = ALIGN16(size); + } + + mesg->hdr.pri = priority; + mesg->hdr.retQueue = reqQueue; + mesg->dramAddr = ramAddr; + mesg->devAddr = devAddr; + mesg->size = size; + handle->transferInfo.cmdType = 2; + sDmaHandler(handle, mesg, direction); + return 0; +} + +void AudioLoad_Unused1(void) { +} + +void AudioLoad_SyncLoadSimple(u32 tableType, u32 fontId) { + s32 didAllocate; + + AudioLoad_SyncLoad(tableType, fontId, &didAllocate); +} + +void* AudioLoad_AsyncLoadInner(s32 tableType, s32 id, s32 nChunks, s32 retData, OSMesgQueue* retQueue) { + size_t size; + AudioTable* table; + void* ramAddr; + s32 medium; + s8 cachePolicy; + uintptr_t romAddr; + s32 loadStatus; + SoundFont* soundFont; + u32 realId = AudioLoad_GetRealTableIndex(tableType, id); + u32 pad; + + switch (tableType) { + case SEQUENCE_TABLE: + if (gAudioContext.seqLoadStatus[realId] == LOAD_STATUS_1) { + return NULL; + } + break; + + case FONT_TABLE: + if (gAudioContext.fontLoadStatus[realId] == LOAD_STATUS_1) { + return NULL; + } + break; + + case SAMPLE_TABLE: + if (gAudioContext.sampleFontLoadStatus[realId] == LOAD_STATUS_1) { + return NULL; + } + break; + } + + ramAddr = AudioLoad_SearchCaches(tableType, realId); + if (ramAddr != NULL) { + loadStatus = LOAD_STATUS_2; + osSendMesg(retQueue, MK_ASYNC_MSG(retData, 0, 0, LOAD_STATUS_0), OS_MESG_NOBLOCK); + } else { + table = AudioLoad_GetLoadTable(tableType); + size = table->entries[realId].size; + size = ALIGN16(size); + medium = table->entries[id].medium; + cachePolicy = table->entries[id].cachePolicy; + romAddr = table->entries[realId].romAddr; + loadStatus = LOAD_STATUS_2; + + switch (cachePolicy) { + case CACHE_LOAD_PERMANENT: + ramAddr = AudioHeap_AllocPermanent(tableType, realId, size); + if (ramAddr == NULL) { + return ramAddr; + } + loadStatus = LOAD_STATUS_5; + break; + + case CACHE_LOAD_PERSISTENT: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_PERSISTENT, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHE_LOAD_TEMPORARY: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_TEMPORARY, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + + case CACHE_LOAD_EITHER: + case CACHE_LOAD_EITHER_NOSYNC: + ramAddr = AudioHeap_AllocCached(tableType, size, CACHE_EITHER, realId); + if (ramAddr == NULL) { + return ramAddr; + } + break; + } + + if (medium == MEDIUM_RAM_UNLOADED) { + if (romAddr == 0) { + return NULL; + } + + if (tableType == FONT_TABLE) { + soundFont = &gAudioContext.soundFonts[realId]; + + soundFont->numInstruments = ((UnloadedFonts*)romAddr)->numInstruments; + soundFont->numDrums = ((UnloadedFonts*)romAddr)->numDrums; + soundFont->numSfx = ((UnloadedFonts*)romAddr)->numSfx; + romAddr += 0x10; + size += -0x10; + } + } + + if (medium == MEDIUM_UNK) { + AudioLoad_StartAsyncLoadUnkMedium((s16)table->unkMediumParam, romAddr, ramAddr, size, medium, nChunks, + retQueue, MK_ASYNC_MSG(retData, tableType, realId, loadStatus)); + } else { + AudioLoad_StartAsyncLoad(romAddr, ramAddr, size, medium, nChunks, retQueue, + MK_ASYNC_MSG(retData, tableType, realId, loadStatus)); + } + + loadStatus = LOAD_STATUS_1; + } + + switch (tableType) { + case SEQUENCE_TABLE: + AudioLoad_SetSeqLoadStatus(realId, loadStatus); + break; + case FONT_TABLE: + AudioLoad_SetFontLoadStatus(realId, loadStatus); + break; + case SAMPLE_TABLE: + AudioLoad_SetSampleFontLoadStatusAndApplyCaches(realId, loadStatus); + break; + default: + break; + } + + return ramAddr; +} + +void AudioLoad_ProcessLoads(s32 resetStatus) { + AudioLoad_ProcessSlowLoads(resetStatus); + AudioLoad_ProcessSamplePreloads(resetStatus); + AudioLoad_ProcessAsyncLoads(resetStatus); +} + +void AudioLoad_SetDmaHandler(DmaHandler callback) { + sDmaHandler = callback; +} + +void AudioLoad_SetUnusedHandler(void* callback) { + sUnusedHandler = callback; +} + +void AudioLoad_InitSoundFontMeta(s32 fontId) { + SoundFont* font = &gAudioContext.soundFonts[fontId]; + AudioTableEntry* entry = &gAudioContext.soundFontTable->entries[fontId]; + + font->sampleBankId1 = (entry->shortData1 >> 8) & 0xFF; + font->sampleBankId2 = (entry->shortData1) & 0xFF; + font->numInstruments = (entry->shortData2 >> 8) & 0xFF; + font->numDrums = entry->shortData2 & 0xFF; + font->numSfx = entry->shortData3; +} + +void AudioLoad_Init(void* heap, size_t heapSize) { + s32 pad1[9]; + s32 numFonts; + s32 pad2[2]; + u8* audioContextPtr; + void* addr; + s32 i; + s32 j; + + D_80208E68 = NULL; + D_80208E70 = NULL; + D_80208E74 = NULL; + + for (i = 0; i < ARRAY_COUNT(gAudioContext.unk_29A8); i++) { + gAudioContext.unk_29A8[i] = NULL; + } + + gAudioContext.resetTimer = 0; + gAudioContext.unk_29B8 = false; + + // Set all of gAudioContext to 0 + audioContextPtr = (u8*)&gAudioContext; + for (j = sizeof(gAudioContext); j >= 0; j--) { + *audioContextPtr++ = 0; + } + + switch (osTvType) { + case OS_TV_PAL: + gAudioContext.unk_2960 = 20.03042f; + gAudioContext.refreshRate = 50; + break; + + case OS_TV_MPAL: + gAudioContext.unk_2960 = 16.546f; + gAudioContext.refreshRate = 60; + break; + + case OS_TV_NTSC: + default: + gAudioContext.unk_2960 = 16.713f; + gAudioContext.refreshRate = 60; + } + + Audio_InitMesgQueues(); + + for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBufLengths); i++) { + gAudioContext.aiBufLengths[i] = 0xA0; + } + + gAudioContext.totalTaskCount = 0; + gAudioContext.rspTaskIndex = 0; + gAudioContext.curAiBuffferIndex = 0; + gAudioContext.soundMode = AUDIO_MODE_STEREO; + gAudioContext.curTask = NULL; + gAudioContext.rspTask[0].task.t.dataSize = 0; + gAudioContext.rspTask[1].task.t.dataSize = 0; + + osCreateMesgQueue(&gAudioContext.syncDmaQueue, &gAudioContext.syncDmaMesg, 1); + osCreateMesgQueue(&gAudioContext.currAudioFrameDmaQueue, gAudioContext.currAudioFrameDmaMesgBuf, + ARRAY_COUNT(gAudioContext.currAudioFrameDmaMesgBuf)); + osCreateMesgQueue(&gAudioContext.externalLoadQueue, gAudioContext.externalLoadMesgBuf, + ARRAY_COUNT(gAudioContext.externalLoadMesgBuf)); + osCreateMesgQueue(&gAudioContext.preloadSampleQueue, gAudioContext.preloadSampleMesgBuf, + ARRAY_COUNT(gAudioContext.preloadSampleMesgBuf)); + gAudioContext.curAudioFrameDmaCount = 0; + gAudioContext.sampleDmaCount = 0; + gAudioContext.cartHandle = osCartRomInit(); + + if (heap == NULL) { + gAudioContext.audioHeap = gAudioHeap; + gAudioContext.audioHeapSize = gAudioContextInitSizes.heapSize; + } else { + void** hp = &heap; + gAudioContext.audioHeap = *hp; + gAudioContext.audioHeapSize = heapSize; + } + + for (i = 0; i < (s32)gAudioContext.audioHeapSize / 8; i++) { + ((u64*)gAudioContext.audioHeap)[i] = 0; + } + + // Main Pool Split (split entirety of audio heap into initPool and sessionPool) + AudioHeap_InitMainPool(gAudioContextInitSizes.mainPoolSplitSize); + + // Initialize the audio interface buffer + for (i = 0; i < ARRAY_COUNT(gAudioContext.aiBuffers); i++) { + gAudioContext.aiBuffers[i] = AudioHeap_AllocZeroed(&gAudioContext.audioInitPool, AIBUF_LEN * sizeof(s16)); + } + + // Connect audio tables to their tables in memory + gAudioContext.sequenceTable = (AudioTable*)gSequenceTable; + gAudioContext.soundFontTable = (AudioTable*)gSoundFontTable; + gAudioContext.sampleBankTable = (AudioTable*)gSampleBankTable; + gAudioContext.sequenceFontTable = gSequenceFontTable; + + gAudioContext.numSequences = gAudioContext.sequenceTable->numEntries; + + gAudioContext.audioResetSpecIdToLoad = 0; + gAudioContext.resetStatus = 1; // Set reset to immediately initialize the audio heap + AudioHeap_ResetStep(); + + // Initialize audio tables + AudioLoad_InitTable(gAudioContext.sequenceTable, SEGMENT_ROM_START(Audioseq), 0); + AudioLoad_InitTable(gAudioContext.soundFontTable, SEGMENT_ROM_START(Audiobank), 0); + AudioLoad_InitTable(gAudioContext.sampleBankTable, SEGMENT_ROM_START(Audiotable), 0); + + numFonts = gAudioContext.soundFontTable->numEntries; + gAudioContext.soundFonts = AudioHeap_Alloc(&gAudioContext.audioInitPool, numFonts * sizeof(SoundFont)); + + for (i = 0; i < numFonts; i++) { + AudioLoad_InitSoundFontMeta(i); + } + + if (addr = AudioHeap_Alloc(&gAudioContext.audioInitPool, gAudioContextInitSizes.permanentPoolSize), addr == NULL) { + // cast away const from D_8014A6C4 + *((u32*)&gAudioContextInitSizes.permanentPoolSize) = 0; + } + + AudioHeap_AllocPoolInit(&gAudioContext.permanentPool, addr, gAudioContextInitSizes.permanentPoolSize); + gAudioContextInitalized = true; + osSendMesg(gAudioContext.taskStartQueueP, (void*)gAudioContext.totalTaskCount, OS_MESG_NOBLOCK); +} + +void AudioLoad_InitSlowLoads(void) { + gAudioContext.slowLoads[0].status = 0; + gAudioContext.slowLoads[1].status = 0; +} + +s32 AudioLoad_SlowLoadSample(s32 fontId, s32 instId, s8* isDone) { + SoundFontSample* sample; + AudioSlowLoad* slowLoad; + + sample = AudioLoad_GetFontSample(fontId, instId); + if (sample == NULL) { + *isDone = 0; + return -1; + } + + if (sample->medium == MEDIUM_RAM) { + *isDone = 2; + return 0; + } + + slowLoad = &gAudioContext.slowLoads[gAudioContext.slowLoadPos]; + if (slowLoad->status == LOAD_STATUS_DONE) { + slowLoad->status = LOAD_STATUS_WAITING; + } + + slowLoad->sample = *sample; + slowLoad->isDone = isDone; + slowLoad->curRamAddr = + AudioHeap_AllocSampleCache(sample->size, fontId, sample->sampleAddr, (s32)sample->medium, CACHE_TEMPORARY); + + if (slowLoad->curRamAddr == NULL) { + if (sample->medium == MEDIUM_UNK || sample->codec == CODEC_S16_INMEMORY) { + *isDone = 0; + return -1; + } else { + *isDone = 3; + return -1; + } + } + + slowLoad->status = LOAD_STATUS_START; + slowLoad->bytesRemaining = ALIGN16(sample->size); + slowLoad->ramAddr = slowLoad->curRamAddr; + slowLoad->curDevAddr = sample->sampleAddr; + slowLoad->medium = sample->medium; + slowLoad->seqOrFontId = fontId; + slowLoad->instId = instId; + + if (slowLoad->medium == MEDIUM_UNK) { + slowLoad->unkMediumParam = gAudioContext.sampleBankTable->unkMediumParam; + } + + gAudioContext.slowLoadPos ^= 1; + return 0; +} + +SoundFontSample* AudioLoad_GetFontSample(s32 fontId, s32 instId) { + SoundFontSample* sample; + + if (instId < 0x80) { + Instrument* instrument = AudioPlayback_GetInstrumentInner(fontId, instId); + + if (instrument == NULL) { + return NULL; + } + sample = instrument->normalNotesSound.sample; + } else if (instId < 0x100) { + Drum* drum = AudioPlayback_GetDrum(fontId, instId - 0x80); + + if (drum == NULL) { + return NULL; + } + sample = drum->sound.sample; + } else { + SoundFontSound* sound = AudioPlayback_GetSfx(fontId, instId - 0x100); + + if (sound == NULL) { + return NULL; + } + sample = sound->sample; + } + + return sample; +} + +void AudioLoad_Unused2(void) { +} + +void AudioLoad_FinishSlowLoad(AudioSlowLoad* slowLoad) { + SoundFontSample* sample; + + if (slowLoad->sample.sampleAddr == NULL) { + return; + } + + sample = AudioLoad_GetFontSample(slowLoad->seqOrFontId, slowLoad->instId); + if (sample == NULL) { + return; + } + + slowLoad->sample = *sample; + sample->sampleAddr = slowLoad->ramAddr; + sample->medium = MEDIUM_RAM; +} + +void AudioLoad_ProcessSlowLoads(s32 resetStatus) { + AudioSlowLoad* slowLoad; + s32 i; + + for (i = 0; i < ARRAY_COUNT(gAudioContext.slowLoads); i++) { + slowLoad = &gAudioContext.slowLoads[i]; + switch (gAudioContext.slowLoads[i].status) { + case LOAD_STATUS_LOADING: + if (slowLoad->medium != MEDIUM_UNK) { + osRecvMesg(&slowLoad->msgqueue, NULL, OS_MESG_BLOCK); + } + + if (resetStatus != 0) { + slowLoad->status = LOAD_STATUS_DONE; + continue; + } + case LOAD_STATUS_START: + slowLoad->status = LOAD_STATUS_LOADING; + if (slowLoad->bytesRemaining == 0) { + AudioLoad_FinishSlowLoad(slowLoad); + slowLoad->status = LOAD_STATUS_DONE; + *slowLoad->isDone = 1; + } else if ((s32)slowLoad->bytesRemaining < 0x400) { + if (slowLoad->medium == MEDIUM_UNK) { + size_t size = slowLoad->bytesRemaining; + + AudioLoad_DmaSlowCopyUnkMedium(slowLoad->curDevAddr, slowLoad->curRamAddr, size, + slowLoad->unkMediumParam); + } else { + AudioLoad_DmaSlowCopy(slowLoad, slowLoad->bytesRemaining); + } + slowLoad->bytesRemaining = 0; + } else { + if (slowLoad->medium == MEDIUM_UNK) { + AudioLoad_DmaSlowCopyUnkMedium(slowLoad->curDevAddr, slowLoad->curRamAddr, 0x400, + slowLoad->unkMediumParam); + } else { + AudioLoad_DmaSlowCopy(slowLoad, 0x400); + } + slowLoad->bytesRemaining -= 0x400; + slowLoad->curRamAddr += 0x400; + slowLoad->curDevAddr += 0x400; + } + break; + } + } +} + +void AudioLoad_DmaSlowCopy(AudioSlowLoad* slowLoad, size_t size) { + Audio_InvalDCache(slowLoad->curRamAddr, size); + osCreateMesgQueue(&slowLoad->msgqueue, &slowLoad->msg, 1); + AudioLoad_Dma(&slowLoad->ioMesg, OS_MESG_PRI_NORMAL, OS_READ, slowLoad->curDevAddr, slowLoad->curRamAddr, size, + &slowLoad->msgqueue, slowLoad->medium, "SLOWCOPY"); +} + +void AudioLoad_DmaSlowCopyUnkMedium(intptr_t devAddr, intptr_t ramAddr, size_t size, s32 arg3) { +} + +s32 AudioLoad_SlowLoadSeq(s32 seqId, u8* ramAddr, s8* isDone) { + AudioSlowLoad* slowLoad; + AudioTable* seqTable; + size_t size; + + if (seqId >= gAudioContext.numSequences) { + *isDone = 0; + return -1; + } + + seqId = AudioLoad_GetRealTableIndex(SEQUENCE_TABLE, seqId); + seqTable = AudioLoad_GetLoadTable(SEQUENCE_TABLE); + slowLoad = &gAudioContext.slowLoads[gAudioContext.slowLoadPos]; + if (slowLoad->status == LOAD_STATUS_DONE) { + slowLoad->status = LOAD_STATUS_WAITING; + } + + slowLoad->sample.sampleAddr = NULL; + slowLoad->isDone = isDone; + size = seqTable->entries[seqId].size; + size = ALIGN16(size); + slowLoad->curRamAddr = ramAddr; + slowLoad->status = LOAD_STATUS_START; + slowLoad->bytesRemaining = size; + slowLoad->ramAddr = ramAddr; + slowLoad->curDevAddr = seqTable->entries[seqId].romAddr; + slowLoad->medium = seqTable->entries[seqId].medium; + slowLoad->seqOrFontId = seqId; + + if (slowLoad->medium == MEDIUM_UNK) { + slowLoad->unkMediumParam = seqTable->unkMediumParam; + } + + gAudioContext.slowLoadPos ^= 1; + return 0; +} + +void AudioLoad_InitAsyncLoads(void) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(gAudioContext.asyncLoads); i++) { + gAudioContext.asyncLoads[i].status = 0; + } +} + +AudioAsyncLoad* AudioLoad_StartAsyncLoadUnkMedium(s32 unkMediumParam, uintptr_t devAddr, void* ramAddr, size_t size, + s32 medium, s32 nChunks, OSMesgQueue* retQueue, s32 retMsg) { + AudioAsyncLoad* asyncLoad; + + asyncLoad = AudioLoad_StartAsyncLoad(devAddr, ramAddr, size, medium, nChunks, retQueue, retMsg); + if (asyncLoad == NULL) { + return NULL; + } + + osSendMesg(&gAudioContext.asyncLoadUnkMediumQueue, asyncLoad, OS_MESG_NOBLOCK); + asyncLoad->unkMediumParam = unkMediumParam; + return asyncLoad; +} + +AudioAsyncLoad* AudioLoad_StartAsyncLoad(uintptr_t devAddr, void* ramAddr, size_t size, s32 medium, s32 nChunks, + OSMesgQueue* retQueue, s32 retMsg) { + AudioAsyncLoad* asyncLoad; + s32 i; + + for (i = 0; i < ARRAY_COUNT(gAudioContext.asyncLoads); i++) { + if (gAudioContext.asyncLoads[i].status == 0) { + asyncLoad = &gAudioContext.asyncLoads[i]; + break; + } + } + + // no more available async loads + if (i == ARRAY_COUNT(gAudioContext.asyncLoads)) { + return NULL; + } + + asyncLoad->status = LOAD_STATUS_START; + asyncLoad->curDevAddr = devAddr; + asyncLoad->ramAddr = ramAddr; + asyncLoad->curRamAddr = ramAddr; + asyncLoad->bytesRemaining = size; + + if (nChunks == 0) { + asyncLoad->chunkSize = 0x1000; + } else if (nChunks == 1) { + asyncLoad->chunkSize = size; + } else { + asyncLoad->chunkSize = ALIGN256((s32)size / nChunks); + if (asyncLoad->chunkSize < 0x100) { + asyncLoad->chunkSize = 0x100; + } + } + + asyncLoad->retQueue = retQueue; + asyncLoad->delay = 3; + asyncLoad->medium = medium; + asyncLoad->retMsg = retMsg; + osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); + return asyncLoad; +} + +void AudioLoad_ProcessAsyncLoads(s32 resetStatus) { + AudioAsyncLoad* asyncLoad; + s32 i; + + if (gAudioContext.resetTimer == 1) { + return; + } + + if (gAudioContext.curUnkMediumLoad == NULL) { + if (resetStatus != 0) { + // Clear and ignore queue if resetting. + do { + } while (osRecvMesg(&gAudioContext.asyncLoadUnkMediumQueue, (OSMesg*)&asyncLoad, OS_MESG_NOBLOCK) != -1); + } else if (osRecvMesg(&gAudioContext.asyncLoadUnkMediumQueue, (OSMesg*)&asyncLoad, OS_MESG_NOBLOCK) == -1) { + gAudioContext.curUnkMediumLoad = NULL; + } else { + gAudioContext.curUnkMediumLoad = asyncLoad; + } + } + + if (gAudioContext.curUnkMediumLoad != NULL) { + AudioLoad_ProcessAsyncLoadUnkMedium(gAudioContext.curUnkMediumLoad, resetStatus); + } + + for (i = 0; i < ARRAY_COUNT(gAudioContext.asyncLoads); i++) { + if (gAudioContext.asyncLoads[i].status == 1) { + asyncLoad = &gAudioContext.asyncLoads[i]; + if (asyncLoad->medium != MEDIUM_UNK) { + AudioLoad_ProcessAsyncLoad(asyncLoad, resetStatus); + } + } + } +} + +void AudioLoad_ProcessAsyncLoadUnkMedium(AudioAsyncLoad* asyncLoad, s32 resetStatus) { +} + +void AudioLoad_FinishAsyncLoad(AudioAsyncLoad* asyncLoad) { + u32 retMsg = asyncLoad->retMsg; + u32 fontId; + u32 pad; + OSMesg doneMsg; + u32 sampleBankId1; + u32 sampleBankId2; + AudioRelocInfo relocInfo; + + if (1) {} + switch (ASYNC_TBLTYPE(retMsg)) { + case SEQUENCE_TABLE: + AudioLoad_SetSeqLoadStatus(ASYNC_ID(retMsg), ASYNC_STATUS(retMsg)); + break; + case SAMPLE_TABLE: + AudioLoad_SetSampleFontLoadStatusAndApplyCaches(ASYNC_ID(retMsg), ASYNC_STATUS(retMsg)); + break; + case FONT_TABLE: + fontId = ASYNC_ID(retMsg); + sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + relocInfo.sampleBankId1 = sampleBankId1; + relocInfo.sampleBankId2 = sampleBankId2; + relocInfo.baseAddr1 = + sampleBankId1 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId1, &relocInfo.medium1) : 0; + relocInfo.baseAddr2 = + sampleBankId2 != 0xFF ? AudioLoad_GetSampleBank(sampleBankId2, &relocInfo.medium2) : 0; + AudioLoad_SetFontLoadStatus(fontId, ASYNC_STATUS(retMsg)); + AudioLoad_RelocateFontAndPreloadSamples(fontId, asyncLoad->ramAddr, &relocInfo, true); + break; + } + + doneMsg = asyncLoad->retMsg; + if (1) {} + asyncLoad->status = LOAD_STATUS_WAITING; + osSendMesg(asyncLoad->retQueue, doneMsg, OS_MESG_NOBLOCK); +} + +void AudioLoad_ProcessAsyncLoad(AudioAsyncLoad* asyncLoad, s32 resetStatus) { + AudioTable* sampleBankTable = gAudioContext.sampleBankTable; + + if (asyncLoad->delay >= 2) { + asyncLoad->delay--; + return; + } + + if (asyncLoad->delay == 1) { + asyncLoad->delay = 0; + } else if (resetStatus != 0) { + // Await the previous DMA response synchronously, then return. + osRecvMesg(&asyncLoad->msgQueue, NULL, OS_MESG_BLOCK); + asyncLoad->status = LOAD_STATUS_WAITING; + return; + } else if (osRecvMesg(&asyncLoad->msgQueue, NULL, OS_MESG_NOBLOCK) == -1) { + // If the previous DMA step isn't done, return. + return; + } + + if (asyncLoad->bytesRemaining == 0) { + AudioLoad_FinishAsyncLoad(asyncLoad); + return; + } + + if (asyncLoad->bytesRemaining < asyncLoad->chunkSize) { + if (asyncLoad->medium == MEDIUM_UNK) { + AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->bytesRemaining, + sampleBankTable->unkMediumParam); + } else if (asyncLoad->medium == MEDIUM_RAM_UNLOADED) { + AudioLoad_AsyncDmaRamUnloaded(asyncLoad, asyncLoad->bytesRemaining); + } else { + AudioLoad_AsyncDma(asyncLoad, asyncLoad->bytesRemaining); + } + asyncLoad->bytesRemaining = 0; + return; + } + + if (asyncLoad->medium == MEDIUM_UNK) { + AudioLoad_AsyncDmaUnkMedium(asyncLoad->curDevAddr, asyncLoad->curRamAddr, asyncLoad->chunkSize, + sampleBankTable->unkMediumParam); + } else if (asyncLoad->medium == MEDIUM_RAM_UNLOADED) { + AudioLoad_AsyncDmaRamUnloaded(asyncLoad, asyncLoad->chunkSize); + } else { + AudioLoad_AsyncDma(asyncLoad, asyncLoad->chunkSize); + } + + asyncLoad->bytesRemaining -= asyncLoad->chunkSize; + asyncLoad->curDevAddr += asyncLoad->chunkSize; + asyncLoad->curRamAddr = asyncLoad->curRamAddr + asyncLoad->chunkSize; +} + +void AudioLoad_AsyncDma(AudioAsyncLoad* asyncLoad, size_t size) { + if (size) {} + size = ALIGN16(size); + Audio_InvalDCache(asyncLoad->curRamAddr, size); + osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); + AudioLoad_Dma(&asyncLoad->ioMesg, OS_MESG_PRI_NORMAL, OS_READ, asyncLoad->curDevAddr, asyncLoad->curRamAddr, size, + &asyncLoad->msgQueue, asyncLoad->medium, "BGCOPY"); +} + +void AudioLoad_AsyncDmaRamUnloaded(AudioAsyncLoad* asyncLoad, size_t size) { + if (size) {} + size = ALIGN16(size); + Audio_InvalDCache(asyncLoad->curRamAddr, size); + osCreateMesgQueue(&asyncLoad->msgQueue, &asyncLoad->msg, 1); + bcopy(asyncLoad->curDevAddr, asyncLoad->curRamAddr, size); + osSendMesg(&asyncLoad->msgQueue, NULL, OS_MESG_NOBLOCK); +} + +void AudioLoad_AsyncDmaUnkMedium(uintptr_t devAddr, void* ramAddr, size_t size, s16 arg3) { +} + +#define RELOC(v, base) (reloc = (void*)((uintptr_t)(v) + (uintptr_t)(base))) + +void AudioLoad_RelocateSample(SoundFontSound* sound, SoundFontData* mem, AudioRelocInfo* relocInfo) { + SoundFontSample* sample; + void* reloc; + + if ((uintptr_t)sound->sample <= 0x80000000) { + sample = sound->sample = RELOC(sound->sample, mem); + if (sample->size != 0 && sample->unk_bit25 != true) { + sample->loop = RELOC(sample->loop, mem); + sample->book = RELOC(sample->book, mem); + + // Resolve the sample medium 2-bit bitfield into a real value based on relocInfo. + switch (sample->medium) { + case 0: + sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr1); + sample->medium = relocInfo->medium1; + break; + case 1: + sample->sampleAddr = RELOC(sample->sampleAddr, relocInfo->baseAddr2); + sample->medium = relocInfo->medium2; + break; + case 2: + case 3: + // Invalid? This leaves sample->medium as MEDIUM_CART and MEDIUM_DISK_DRIVE + // respectively, and the sampleAddr unrelocated. + break; + } + + sample->unk_bit25 = true; + if (sample->unk_bit26 && (sample->medium != MEDIUM_RAM)) { + gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + } + } + } +} + +#undef RELOC + +void AudioLoad_RelocateFontAndPreloadSamples(s32 fontId, SoundFontData* mem, AudioRelocInfo* relocInfo, s32 async) { + AudioPreloadReq* preload; + AudioPreloadReq* topPreload; + SoundFontSample* sample; + size_t size; + s32 nChunks; + u8* sampleRamAddr; + s32 preloadInProgress; + s32 i; + + preloadInProgress = false; + if (gAudioContext.preloadSampleStackTop != 0) { + preloadInProgress = true; + } else { + D_801FD1E0 = 0; + } + + gAudioContext.numUsedSamples = 0; + AudioLoad_RelocateFont(fontId, mem, relocInfo); + + size = 0; + for (i = 0; i < gAudioContext.numUsedSamples; i++) { + size += ALIGN16(gAudioContext.usedSamples[i]->size); + } + if (size && size) {} + + for (i = 0; i < gAudioContext.numUsedSamples; i++) { + if (gAudioContext.preloadSampleStackTop == 120) { + break; + } + + sample = gAudioContext.usedSamples[i]; + sampleRamAddr = NULL; + switch (async) { + case false: + if (sample->medium == relocInfo->medium1) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, + sample->sampleAddr, sample->medium, CACHE_PERSISTENT); + } else if (sample->medium == relocInfo->medium2) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, + sample->sampleAddr, sample->medium, CACHE_PERSISTENT); + } else if (sample->medium == MEDIUM_DISK_DRIVE) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium, + CACHE_PERSISTENT); + } + break; + + case true: + if (sample->medium == relocInfo->medium1) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, + sample->sampleAddr, sample->medium, CACHE_TEMPORARY); + } else if (sample->medium == relocInfo->medium2) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, + sample->sampleAddr, sample->medium, CACHE_TEMPORARY); + } else if (sample->medium == MEDIUM_DISK_DRIVE) { + sampleRamAddr = AudioHeap_AllocSampleCache(sample->size, 0xFE, sample->sampleAddr, sample->medium, + CACHE_TEMPORARY); + } + break; + } + if (sampleRamAddr == NULL) { + continue; + } + + switch (async) { + case false: + if (sample->medium == MEDIUM_UNK) { + AudioLoad_SyncDmaUnkMedium((uintptr_t)sample->sampleAddr, sampleRamAddr, sample->size, + gAudioContext.sampleBankTable->unkMediumParam); + sample->sampleAddr = sampleRamAddr; + sample->medium = MEDIUM_RAM; + } else { + AudioLoad_SyncDma((uintptr_t)sample->sampleAddr, sampleRamAddr, sample->size, sample->medium); + sample->sampleAddr = sampleRamAddr; + sample->medium = MEDIUM_RAM; + } + if (sample->medium == MEDIUM_DISK_DRIVE) {} + break; + + case true: + preload = &gAudioContext.preloadSampleStack[gAudioContext.preloadSampleStackTop]; + preload->sample = sample; + preload->ramAddr = sampleRamAddr; + preload->encodedInfo = (gAudioContext.preloadSampleStackTop << 24) | 0xFFFFFF; + preload->isFree = false; + preload->endAndMediumKey = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; + gAudioContext.preloadSampleStackTop++; + break; + } + } + gAudioContext.numUsedSamples = 0; + + if (gAudioContext.preloadSampleStackTop != 0 && !preloadInProgress) { + topPreload = &gAudioContext.preloadSampleStack[gAudioContext.preloadSampleStackTop - 1]; + sample = topPreload->sample; + nChunks = (sample->size >> 12) + 1; + AudioLoad_StartAsyncLoad((uintptr_t)sample->sampleAddr, topPreload->ramAddr, sample->size, sample->medium, + nChunks, &gAudioContext.preloadSampleQueue, topPreload->encodedInfo); + } +} + +s32 AudioLoad_ProcessSamplePreloads(s32 resetStatus) { + SoundFontSample* sample; + AudioPreloadReq* preload; + u32 preloadIndex; + u32 key; + u32 nChunks; + s32 pad; + + if (gAudioContext.preloadSampleStackTop > 0) { + if (resetStatus != 0) { + // Clear result queue and preload stack and return. + osRecvMesg(&gAudioContext.preloadSampleQueue, (OSMesg*)&preloadIndex, OS_MESG_NOBLOCK); + gAudioContext.preloadSampleStackTop = 0; + return false; + } + if (osRecvMesg(&gAudioContext.preloadSampleQueue, (OSMesg*)&preloadIndex, OS_MESG_NOBLOCK) == -1) { + // Previous preload is not done yet. + return false; + } + + preloadIndex >>= 24; + preload = &gAudioContext.preloadSampleStack[preloadIndex]; + + if (preload->isFree == false) { + sample = preload->sample; + key = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; + if (key == preload->endAndMediumKey) { + // Change storage for sample to the preloaded version. + sample->sampleAddr = preload->ramAddr; + sample->medium = MEDIUM_RAM; + } + preload->isFree = true; + } + + // Pop requests with isFree = true off the stack, as far as possible, + // and dispatch the next DMA. + for (;;) { + if (gAudioContext.preloadSampleStackTop <= 0) { + break; + } + preload = &gAudioContext.preloadSampleStack[gAudioContext.preloadSampleStackTop - 1]; + if (preload->isFree == true) { + gAudioContext.preloadSampleStackTop--; + continue; + } + + sample = preload->sample; + nChunks = (sample->size >> 12) + 1; + key = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; + if (key != preload->endAndMediumKey) { + preload->isFree = true; + gAudioContext.preloadSampleStackTop--; + } else { + AudioLoad_StartAsyncLoad((uintptr_t)sample->sampleAddr, preload->ramAddr, sample->size, sample->medium, + nChunks, &gAudioContext.preloadSampleQueue, preload->encodedInfo); + break; + } + } + } + return true; +} + +s32 AudioLoad_AddToSampleSet(SoundFontSample* sample, s32 numSamples, SoundFontSample** sampleSet) { + s32 i; + + for (i = 0; i < numSamples; i++) { + if (sample->sampleAddr == sampleSet[i]->sampleAddr) { + break; + } + } + + if (i == numSamples) { + sampleSet[numSamples] = sample; + numSamples++; + } + + return numSamples; +} + +s32 AudioLoad_GetSamplesForFont(s32 fontId, SoundFontSample** sampleSet) { + s32 i; + s32 numSamples = 0; + s32 numDrums = gAudioContext.soundFonts[fontId].numDrums; + s32 numInstruments = gAudioContext.soundFonts[fontId].numInstruments; + + for (i = 0; i < numDrums; i++) { + Drum* drum = AudioPlayback_GetDrum(fontId, i); + + if (1) {} + if (drum != NULL) { + numSamples = AudioLoad_AddToSampleSet(drum->sound.sample, numSamples, sampleSet); + } + } + + for (i = 0; i < numInstruments; i++) { + Instrument* instrument = AudioPlayback_GetInstrumentInner(fontId, i); + + if (instrument != NULL) { + if (instrument->normalRangeLo != 0) { + numSamples = AudioLoad_AddToSampleSet(instrument->lowNotesSound.sample, numSamples, sampleSet); + } + if (instrument->normalRangeHi != 0x7F) { + numSamples = AudioLoad_AddToSampleSet(instrument->highNotesSound.sample, numSamples, sampleSet); + } + numSamples = AudioLoad_AddToSampleSet(instrument->normalNotesSound.sample, numSamples, sampleSet); + } + } + + // Should really also process sfx, but this method is never called + return numSamples; +} + +void AudioLoad_AddUsedSample(SoundFontSound* sound) { + SoundFontSample* sample = sound->sample; + + if ((sample->size != 0) && (sample->unk_bit26) && (sample->medium != MEDIUM_RAM)) { + gAudioContext.usedSamples[gAudioContext.numUsedSamples++] = sample; + } +} + +void AudioLoad_PreloadSamplesForFont(s32 fontId, s32 async, AudioRelocInfo* relocInfo) { + s32 numDrums; + s32 numInstruments; + s32 numSfx; + Drum* drum; + Instrument* instrument; + SoundFontSound* sound; + AudioPreloadReq* preload; + AudioPreloadReq* topPreload; + u8* addr; + size_t size; + s32 i; + SoundFontSample* sample; + s32 preloadInProgress; + s32 nChunks; + + preloadInProgress = false; + if (gAudioContext.preloadSampleStackTop != 0) { + preloadInProgress = true; + } + + gAudioContext.numUsedSamples = 0; + + numDrums = gAudioContext.soundFonts[fontId].numDrums; + numInstruments = gAudioContext.soundFonts[fontId].numInstruments; + numSfx = gAudioContext.soundFonts[fontId].numSfx; + + for (i = 0; i < numInstruments; i++) { + instrument = AudioPlayback_GetInstrumentInner(fontId, i); + if (instrument != NULL) { + if (instrument->normalRangeLo != 0) { + AudioLoad_AddUsedSample(&instrument->lowNotesSound); + } + if (instrument->normalRangeHi != 0x7F) { + AudioLoad_AddUsedSample(&instrument->highNotesSound); + } + AudioLoad_AddUsedSample(&instrument->normalNotesSound); + } + } + + for (i = 0; i < numDrums; i++) { + drum = AudioPlayback_GetDrum(fontId, i); + if (drum != NULL) { + AudioLoad_AddUsedSample(&drum->sound); + } + } + + for (i = 0; i < numSfx; i++) { + sound = AudioPlayback_GetSfx(fontId, i); + if (sound != NULL) { + AudioLoad_AddUsedSample(sound); + } + } + + if (gAudioContext.numUsedSamples == 0) { + return; + } + + size = 0; + for (i = 0; i < gAudioContext.numUsedSamples; i++) { + size += ALIGN16(gAudioContext.usedSamples[i]->size); + } + if (size) {} + + for (i = 0; i < gAudioContext.numUsedSamples; i++) { + if (gAudioContext.preloadSampleStackTop == 120) { + break; + } + + sample = gAudioContext.usedSamples[i]; + if (sample->medium == MEDIUM_RAM) { + continue; + } + + switch (async) { + case false: + if (sample->medium == relocInfo->medium1) { + addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, sample->sampleAddr, + sample->medium, CACHE_PERSISTENT); + } else if (sample->medium == relocInfo->medium2) { + addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, sample->sampleAddr, + sample->medium, CACHE_PERSISTENT); + } + break; + + case true: + if (sample->medium == relocInfo->medium1) { + addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId1, sample->sampleAddr, + sample->medium, CACHE_TEMPORARY); + } else if (sample->medium == relocInfo->medium2) { + addr = AudioHeap_AllocSampleCache(sample->size, relocInfo->sampleBankId2, sample->sampleAddr, + sample->medium, CACHE_TEMPORARY); + } + break; + } + if (addr == NULL) { + continue; + } + + switch (async) { + case false: + if (sample->medium == MEDIUM_UNK) { + AudioLoad_SyncDmaUnkMedium((uintptr_t)sample->sampleAddr, addr, sample->size, + gAudioContext.sampleBankTable->unkMediumParam); + sample->sampleAddr = addr; + sample->medium = MEDIUM_RAM; + } else { + AudioLoad_SyncDma((uintptr_t)sample->sampleAddr, addr, sample->size, sample->medium); + sample->sampleAddr = addr; + sample->medium = MEDIUM_RAM; + } + break; + + case true: + preload = &gAudioContext.preloadSampleStack[gAudioContext.preloadSampleStackTop]; + preload->sample = sample; + preload->ramAddr = addr; + preload->encodedInfo = (gAudioContext.preloadSampleStackTop << 24) | 0xFFFFFF; + preload->isFree = false; + preload->endAndMediumKey = (uintptr_t)sample->sampleAddr + sample->size + sample->medium; + gAudioContext.preloadSampleStackTop++; + break; + } + } + gAudioContext.numUsedSamples = 0; + + if (gAudioContext.preloadSampleStackTop != 0 && !preloadInProgress) { + topPreload = &gAudioContext.preloadSampleStack[gAudioContext.preloadSampleStackTop - 1]; + sample = topPreload->sample; + nChunks = (sample->size >> 12) + 1; + AudioLoad_StartAsyncLoad((uintptr_t)sample->sampleAddr, topPreload->ramAddr, sample->size, sample->medium, + nChunks, &gAudioContext.preloadSampleQueue, topPreload->encodedInfo); + } +} + +void AudioLoad_LoadPermanentSamples(void) { + s32 pad; + u32 fontId; + AudioTable* sampleBankTable; + s32 pad2; + s32 i; + + sampleBankTable = AudioLoad_GetLoadTable(SAMPLE_TABLE); + for (i = 0; i < gAudioContext.permanentPool.count; i++) { + AudioRelocInfo relocInfo; + + if (gAudioContext.permanentEntries[i].tableType == FONT_TABLE) { + fontId = AudioLoad_GetRealTableIndex(FONT_TABLE, gAudioContext.permanentEntries[i].id); + relocInfo.sampleBankId1 = gAudioContext.soundFonts[fontId].sampleBankId1; + relocInfo.sampleBankId2 = gAudioContext.soundFonts[fontId].sampleBankId2; + + if (relocInfo.sampleBankId1 != 0xFF) { + relocInfo.sampleBankId1 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId1); + relocInfo.medium1 = sampleBankTable->entries[relocInfo.sampleBankId1].medium; + } + + if (relocInfo.sampleBankId2 != 0xFF) { + relocInfo.sampleBankId2 = AudioLoad_GetRealTableIndex(SAMPLE_TABLE, relocInfo.sampleBankId2); + relocInfo.medium2 = sampleBankTable->entries[relocInfo.sampleBankId2].medium; + } + AudioLoad_PreloadSamplesForFont(fontId, false, &relocInfo); + } + } +} + +void AudioLoad_Unused3(void) { +} + +void AudioLoad_Unused4(void) { +} + +void AudioLoad_Unused5(void) { +} + +void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* isDone) { + static u32 sLoadIndex = 0; + + sScriptLoadDonePointers[sLoadIndex] = isDone; + AudioLoad_AsyncLoad(tableType, id, 0, sLoadIndex, &sScriptLoadQueue); + sLoadIndex++; + if (sLoadIndex == 0x10) { + sLoadIndex = 0; + } +} + +void AudioLoad_ProcessScriptLoads(void) { + u32 temp; + u32 sp20; + s8* isDone; + + if (osRecvMesg(&sScriptLoadQueue, (OSMesg*)&sp20, OS_MESG_NOBLOCK) != -1) { + temp = sp20 >> 24; + isDone = sScriptLoadDonePointers[temp]; + if (isDone != NULL) { + *isDone = false; + } + } +} + +void AudioLoad_InitScriptLoads(void) { + osCreateMesgQueue(&sScriptLoadQueue, sScriptLoadMesgBuf, ARRAY_COUNT(sScriptLoadMesgBuf)); +} diff --git a/src/code/audio/audio_playback.c b/src/code/audio/audio_playback.c new file mode 100644 index 000000000..6ae5696f1 --- /dev/null +++ b/src/code/audio/audio_playback.c @@ -0,0 +1,988 @@ +#include "global.h" + +void AudioPlayback_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput); +void AudioPlayback_AudioListPushFront(AudioListItem* list, AudioListItem* item); +void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer); + +void AudioPlayback_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) { + f32 volRight, volLeft; + s32 smallPanIndex; + u64 pad; + u8 strongLeft; + u8 strongRight; + f32 vel; + u8 pan; + u8 reverbVol; + StereoData stereoData; + s32 stereoHeadsetEffects = note->playbackState.stereoHeadsetEffects; + + vel = attrs->velocity; + pan = attrs->pan; + reverbVol = attrs->reverbVol; + stereoData = attrs->stereo.s; + + sub->bitField0 = note->noteSubEu.bitField0; + sub->bitField1 = note->noteSubEu.bitField1; + sub->sound.samples = note->noteSubEu.sound.samples; + sub->unk_06 = note->noteSubEu.unk_06; + + AudioPlayback_NoteSetResamplingRate(sub, attrs->frequency); + + pan &= 0x7F; + + sub->bitField0.stereoStrongRight = false; + sub->bitField0.stereoStrongLeft = false; + sub->bitField0.stereoHeadsetEffects = stereoData.stereoHeadsetEffects; + sub->bitField0.usesHeadsetPanEffects = stereoData.usesHeadsetPanEffects; + if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_HEADSET) { + smallPanIndex = pan >> 1; + if (smallPanIndex > 0x3F) { + smallPanIndex = 0x3F; + } + + sub->headsetPanLeft = gHeadsetPanQuantization[smallPanIndex]; + sub->headsetPanRight = gHeadsetPanQuantization[0x3F - smallPanIndex]; + sub->bitField1.usesHeadsetPanEffects2 = true; + + volLeft = gHeadsetPanVolume[pan]; + volRight = gHeadsetPanVolume[0x7F - pan]; + } else if (stereoHeadsetEffects && gAudioContext.soundMode == AUDIO_MODE_STEREO) { + strongLeft = strongRight = false; + sub->headsetPanRight = 0; + sub->headsetPanLeft = 0; + sub->bitField1.usesHeadsetPanEffects2 = false; + + volLeft = gStereoPanVolume[pan]; + volRight = gStereoPanVolume[0x7F - pan]; + if (pan < 0x20) { + strongLeft = true; + } else if (pan > 0x60) { + strongRight = true; + } + + sub->bitField0.stereoStrongRight = strongRight; + sub->bitField0.stereoStrongLeft = strongLeft; + + switch (stereoData.bit2) { + case 0: + break; + case 1: + sub->bitField0.stereoStrongRight = stereoData.strongRight; + sub->bitField0.stereoStrongLeft = stereoData.strongLeft; + break; + case 2: + sub->bitField0.stereoStrongRight = stereoData.strongRight | strongRight; + sub->bitField0.stereoStrongLeft = stereoData.strongLeft | strongLeft; + break; + case 3: + sub->bitField0.stereoStrongRight = stereoData.strongRight ^ strongRight; + sub->bitField0.stereoStrongLeft = stereoData.strongLeft ^ strongLeft; + break; + } + + } else if (gAudioContext.soundMode == AUDIO_MODE_MONO) { + sub->bitField0.stereoHeadsetEffects = false; + sub->bitField0.usesHeadsetPanEffects = false; + volLeft = 0.707f; // approx 1/sqrt(2) + volRight = 0.707f; + } else { + sub->bitField0.stereoStrongRight = stereoData.strongRight; + sub->bitField0.stereoStrongLeft = stereoData.strongLeft; + volLeft = gDefaultPanVolume[pan]; + volRight = gDefaultPanVolume[0x7F - pan]; + } + + vel = 0.0f > vel ? 0.0f : vel; + vel = 1.0f < vel ? 1.0f : vel; + + sub->targetVolLeft = (s32)((vel * volLeft) * (0x1000 - 0.001f)); + sub->targetVolRight = (s32)((vel * volRight) * (0x1000 - 0.001f)); + + sub->unk_2 = attrs->unk_1; + sub->filter = attrs->filter; + sub->unk_07 = attrs->unk_14; + sub->unk_0E = attrs->unk_16; + sub->reverbVol = reverbVol; + sub->unk_19 = attrs->unk_3; +} + +void AudioPlayback_NoteSetResamplingRate(NoteSubEu* noteSubEu, f32 resamplingRateInput) { + f32 resamplingRate = 0.0f; + + if (resamplingRateInput < 2.0f) { + noteSubEu->bitField1.hasTwoParts = false; + resamplingRate = CLAMP_MAX(resamplingRateInput, 1.99998f); + + } else { + noteSubEu->bitField1.hasTwoParts = true; + if (resamplingRateInput > 3.99996f) { + resamplingRate = 1.99998f; + } else { + resamplingRate = resamplingRateInput * 0.5f; + } + } + noteSubEu->resamplingRateFixedPoint = (s32)(resamplingRate * 32768.0f); +} + +void AudioPlayback_NoteInit(Note* note) { + if (note->playbackState.parentLayer->adsr.releaseRate == 0) { + AudioEffects_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->channel->adsr.envelope, + ¬e->playbackState.adsrVolScaleUnused); + } else { + AudioEffects_AdsrInit(¬e->playbackState.adsr, note->playbackState.parentLayer->adsr.envelope, + ¬e->playbackState.adsrVolScaleUnused); + } + + note->playbackState.unk_04 = 0; + note->playbackState.adsr.action.s.state = ADSR_STATE_INITIAL; + note->noteSubEu = gDefaultNoteSub; +} + +void AudioPlayback_NoteDisable(Note* note) { + if (note->noteSubEu.bitField0.needsInit == true) { + note->noteSubEu.bitField0.needsInit = false; + } + note->playbackState.priority = 0; + note->noteSubEu.bitField0.enabled = false; + note->playbackState.unk_04 = 0; + note->noteSubEu.bitField0.finished = false; + note->playbackState.parentLayer = NO_LAYER; + note->playbackState.prevParentLayer = NO_LAYER; + note->playbackState.adsr.action.s.state = ADSR_STATE_DISABLED; + note->playbackState.adsr.current = 0; +} + +void AudioPlayback_ProcessNotes(void) { + s32 pad; + s32 unk_04; + NoteAttributes* attrs; + NoteSubEu* noteSubEu2; + NoteSubEu* noteSubEu; + Note* note; + NotePlaybackState* playbackState; + NoteSubAttributes subAttrs; + u8 bookOffset; + f32 scale; + s32 i; + + for (i = 0; i < gAudioContext.numNotes; i++) { + note = &gAudioContext.notes[i]; + noteSubEu2 = &gAudioContext.noteSubsEu[gAudioContext.noteSubEuOffset + i]; + playbackState = ¬e->playbackState; + if (playbackState->parentLayer != NO_LAYER) { + if ((u32)playbackState->parentLayer < 0x7FFFFFFF) { + continue; + } + + if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) { + playbackState->adsr.action.s.release = true; + playbackState->adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + playbackState->priority = 1; + playbackState->unk_04 = 2; + goto out; + } else if (!playbackState->parentLayer->enabled && playbackState->unk_04 == 0 && + playbackState->priority >= 1) { + // do nothing + } else if (playbackState->parentLayer->channel->seqPlayer == NULL) { + AudioSeq_SequenceChannelDisable(playbackState->parentLayer->channel); + playbackState->priority = 1; + playbackState->unk_04 = 1; + continue; + } else if (playbackState->parentLayer->channel->seqPlayer->muted && + (playbackState->parentLayer->channel->muteBehavior & 0x40)) { + // do nothing + } else { + goto out; + } + + AudioPlayback_SeqLayerNoteRelease(playbackState->parentLayer); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioPlayback_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); + playbackState->priority = 1; + playbackState->unk_04 = 2; + } else if (playbackState->unk_04 == 0 && playbackState->priority >= 1) { + continue; + } + + out: + if (playbackState->priority != 0) { + if (1) {} + noteSubEu = ¬e->noteSubEu; + if (playbackState->unk_04 >= 1 || noteSubEu->bitField0.finished) { + if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED || noteSubEu->bitField0.finished) { + if (playbackState->wantedParentLayer != NO_LAYER) { + AudioPlayback_NoteDisable(note); + if (playbackState->wantedParentLayer->channel != NULL) { + AudioPlayback_NoteInitForLayer(note, playbackState->wantedParentLayer); + AudioEffects_NoteVibratoInit(note); + AudioEffects_NotePortamentoInit(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(¬e->listItem.pool->active, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + // don't skip + } else { + AudioPlayback_NoteDisable(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); + playbackState->wantedParentLayer = NO_LAYER; + goto skip; + } + } else { + if (playbackState->parentLayer != NO_LAYER) { + playbackState->parentLayer->bit1 = true; + } + AudioPlayback_NoteDisable(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); + continue; + } + } + } else if (playbackState->adsr.action.s.state == ADSR_STATE_DISABLED) { + if (playbackState->parentLayer != NO_LAYER) { + playbackState->parentLayer->bit1 = true; + } + AudioPlayback_NoteDisable(note); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(¬e->listItem.pool->disabled, ¬e->listItem); + continue; + } + + scale = AudioEffects_AdsrUpdate(&playbackState->adsr); + AudioEffects_NoteVibratoUpdate(note); + unk_04 = playbackState->unk_04; + attrs = &playbackState->attributes; + if (unk_04 == 1 || unk_04 == 2) { + subAttrs.frequency = attrs->freqScale; + subAttrs.velocity = attrs->velocity; + subAttrs.pan = attrs->pan; + subAttrs.reverbVol = attrs->reverb; + subAttrs.stereo = attrs->stereo; + subAttrs.unk_1 = attrs->unk_1; + subAttrs.filter = attrs->filter; + subAttrs.unk_14 = attrs->unk_4; + subAttrs.unk_16 = attrs->unk_6; + subAttrs.unk_3 = attrs->unk_3; + bookOffset = noteSubEu->bitField1.bookOffset; + } else { + SequenceLayer* layer = playbackState->parentLayer; + SequenceChannel* channel = playbackState->parentLayer->channel; + + subAttrs.frequency = layer->noteFreqScale; + subAttrs.velocity = layer->noteVelocity; + subAttrs.pan = layer->notePan; + + if (layer->unk_08 == 0x80) { + subAttrs.unk_3 = channel->unk_10; + } else { + subAttrs.unk_3 = layer->unk_08; + } + + if (layer->stereo.s.bit2 == 0) { + subAttrs.stereo = channel->stereo; + } else { + subAttrs.stereo = layer->stereo; + } + + if (layer->unk_0A.s.bit_2 == 1) { + subAttrs.reverbVol = channel->reverb; + } else { + subAttrs.reverbVol = layer->unk_09; + } + + if (layer->unk_0A.s.bit_9 == 1) { + subAttrs.unk_1 = channel->unk_0C; + } else { + subAttrs.unk_1 = 0; + if (1) {} + } + + subAttrs.filter = channel->filter; + subAttrs.unk_14 = channel->unk_0F; + subAttrs.unk_16 = channel->unk_20; + bookOffset = channel->bookOffset & 0x7; + + if (channel->seqPlayer->muted && (channel->muteBehavior & 8)) { + subAttrs.frequency = 0.0f; + subAttrs.velocity = 0.0f; + } + } + + subAttrs.frequency *= playbackState->vibratoFreqScale * playbackState->portamentoFreqScale; + subAttrs.frequency *= gAudioContext.audioBufferParameters.resampleRate; + subAttrs.velocity *= scale; + AudioPlayback_InitNoteSub(note, noteSubEu2, &subAttrs); + noteSubEu->bitField1.bookOffset = bookOffset; + skip:; + } + } +} + +SoundFontSound* AudioPlayback_InstrumentGetSound(Instrument* instrument, s32 semitone) { + SoundFontSound* sound; + + if (semitone < instrument->normalRangeLo) { + sound = &instrument->lowNotesSound; + } else if (semitone <= instrument->normalRangeHi) { + sound = &instrument->normalNotesSound; + } else { + sound = &instrument->highNotesSound; + } + return sound; +} + +Instrument* AudioPlayback_GetInstrumentInner(s32 fontId, s32 instId) { + Instrument* inst; + + if (fontId == 0xFF) { + return NULL; + } + + if (!AudioLoad_IsFontLoadComplete(fontId)) { + gAudioContext.audioErrorFlags = fontId + 0x10000000; + return NULL; + } + + if (instId >= gAudioContext.soundFonts[fontId].numInstruments) { + gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x3000000; + return NULL; + } + + inst = gAudioContext.soundFonts[fontId].instruments[instId]; + if (inst == NULL) { + gAudioContext.audioErrorFlags = ((fontId << 8) + instId) + 0x1000000; + return inst; + } + + return inst; +} + +Drum* AudioPlayback_GetDrum(s32 fontId, s32 drumId) { + Drum* drum; + + if (fontId == 0xFF) { + return NULL; + } + + if (!AudioLoad_IsFontLoadComplete(fontId)) { + gAudioContext.audioErrorFlags = fontId + 0x10000000; + return NULL; + } + + if (drumId >= gAudioContext.soundFonts[fontId].numDrums) { + gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x4000000; + return NULL; + } + if ((u32)gAudioContext.soundFonts[fontId].drums < 0x80000000) { + return NULL; + } + drum = gAudioContext.soundFonts[fontId].drums[drumId]; + + if (drum == NULL) { + gAudioContext.audioErrorFlags = ((fontId << 8) + drumId) + 0x5000000; + } + + return drum; +} + +SoundFontSound* AudioPlayback_GetSfx(s32 fontId, s32 sfxId) { + SoundFontSound* sfx; + + if (fontId == 0xFF) { + return NULL; + } + + if (!AudioLoad_IsFontLoadComplete(fontId)) { + gAudioContext.audioErrorFlags = fontId + 0x10000000; + return NULL; + } + + if (sfxId >= gAudioContext.soundFonts[fontId].numSfx) { + gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x4000000; + return NULL; + } + + if ((u32)gAudioContext.soundFonts[fontId].soundEffects < 0x80000000) { + return NULL; + } + + sfx = &gAudioContext.soundFonts[fontId].soundEffects[sfxId]; + + if (sfx == NULL) { + gAudioContext.audioErrorFlags = ((fontId << 8) + sfxId) + 0x5000000; + } + + if (sfx->sample == NULL) { + return NULL; + } + + return sfx; +} + +s32 AudioPlayback_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* value) { + if (fontId == 0xFF) { + return -1; + } + + if (!AudioLoad_IsFontLoadComplete(fontId)) { + return -2; + } + + switch (instrumentType) { + case 0: + if (index >= gAudioContext.soundFonts[fontId].numDrums) { + return -3; + } + gAudioContext.soundFonts[fontId].drums[index] = value; + break; + + case 1: + if (index >= gAudioContext.soundFonts[fontId].numSfx) { + return -3; + } + gAudioContext.soundFonts[fontId].soundEffects[index] = *(SoundFontSound*)value; + break; + + default: + if (index >= gAudioContext.soundFonts[fontId].numInstruments) { + return -3; + } + gAudioContext.soundFonts[fontId].instruments[index] = value; + break; + } + + return 0; +} + +void AudioPlayback_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { + Note* note; + NoteAttributes* attrs; + SequenceChannel* chan; + s32 i; + + if (layer == NO_LAYER) { + return; + } + + layer->bit3 = false; + + if (layer->note == NULL) { + return; + } + + note = layer->note; + attrs = ¬e->playbackState.attributes; + + if (note->playbackState.wantedParentLayer == layer) { + note->playbackState.wantedParentLayer = NO_LAYER; + } + + if (note->playbackState.parentLayer != layer) { + if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER && + note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) { + note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.action.s.release = true; + } + return; + } + + if (note->playbackState.adsr.action.s.state != ADSR_STATE_DECAY) { + attrs->freqScale = layer->noteFreqScale; + attrs->velocity = layer->noteVelocity; + attrs->pan = layer->notePan; + + if (layer->channel != NULL) { + chan = layer->channel; + + if (layer->unk_0A.s.bit_2 == 1) { + attrs->reverb = chan->reverb; + } else { + attrs->reverb = layer->unk_09; + } + + if (layer->unk_08 == 0x80) { + attrs->unk_3 = chan->unk_10; + } else { + attrs->unk_3 = layer->unk_08; + } + + if (layer->unk_0A.s.bit_9 == 1) { + attrs->unk_1 = chan->unk_0C; + } else { + attrs->unk_1 = 0; + } + + attrs->filter = chan->filter; + + if (attrs->filter != NULL) { + for (i = 0; i < 8; i++) { + attrs->filterBuf[i] = attrs->filter[i]; + } + attrs->filter = attrs->filterBuf; + } + + attrs->unk_6 = chan->unk_20; + attrs->unk_4 = chan->unk_0F; + if (chan->seqPlayer->muted && (chan->muteBehavior & 8)) { + note->noteSubEu.bitField0.finished = true; + } + + if (layer->stereo.asByte == 0) { + attrs->stereo = chan->stereo; + } else { + attrs->stereo = layer->stereo; + } + note->playbackState.priority = chan->someOtherPriority; + } else { + attrs->stereo = layer->stereo; + note->playbackState.priority = 1; + } + + note->playbackState.prevParentLayer = note->playbackState.parentLayer; + note->playbackState.parentLayer = NO_LAYER; + if (target == ADSR_STATE_RELEASE) { + note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.action.s.release = true; + note->playbackState.unk_04 = 2; + } else { + note->playbackState.unk_04 = 1; + note->playbackState.adsr.action.s.decay = true; + if (layer->adsr.releaseRate == 0) { + note->playbackState.adsr.fadeOutVel = gAudioContext.unk_3520[layer->channel->adsr.releaseRate]; + } else { + note->playbackState.adsr.fadeOutVel = gAudioContext.unk_3520[layer->adsr.releaseRate]; + } + note->playbackState.adsr.sustain = + ((f32)(s32)(layer->channel->adsr.sustain) * note->playbackState.adsr.current) / 256.0f; + } + } + + if (target == ADSR_STATE_DECAY) { + AudioPlayback_AudioListRemove(¬e->listItem); + AudioPlayback_AudioListPushFront(¬e->listItem.pool->decaying, ¬e->listItem); + } +} + +void AudioPlayback_SeqLayerNoteDecay(SequenceLayer* layer) { + AudioPlayback_SeqLayerDecayRelease(layer, ADSR_STATE_DECAY); +} + +void AudioPlayback_SeqLayerNoteRelease(SequenceLayer* layer) { + AudioPlayback_SeqLayerDecayRelease(layer, ADSR_STATE_RELEASE); +} + +s32 AudioPlayback_BuildSyntheticWave(Note* note, SequenceLayer* layer, s32 waveId) { + f32 freqScale; + f32 ratio; + u8 sampleCountIndex; + + if (waveId < 128) { + waveId = 128; + } + + freqScale = layer->freqScale; + if (layer->portamento.mode != 0 && 0.0f < layer->portamento.extent) { + freqScale *= (layer->portamento.extent + 1.0f); + } + if (freqScale < 0.99999f) { + sampleCountIndex = 0; + ratio = 1.0465f; + } else if (freqScale < 1.99999f) { + sampleCountIndex = 1; + ratio = 0.52325f; + } else if (freqScale < 3.99999f) { + sampleCountIndex = 2; + ratio = 0.26263f; + } else { + sampleCountIndex = 3; + ratio = 0.13081f; + } + layer->freqScale *= ratio; + note->playbackState.waveId = waveId; + note->playbackState.sampleCountIndex = sampleCountIndex; + + note->noteSubEu.sound.samples = &gWaveSamples[waveId - 128][sampleCountIndex * 64]; + + return sampleCountIndex; +} + +void AudioPlayback_InitSyntheticWave(Note* note, SequenceLayer* layer) { + s32 sampleCountIndex; + s32 waveSampleCountIndex; + s32 waveId = layer->instOrWave; + + if (waveId == 0xFF) { + waveId = layer->channel->instOrWave; + } + + sampleCountIndex = note->playbackState.sampleCountIndex; + waveSampleCountIndex = AudioPlayback_BuildSyntheticWave(note, layer, waveId); + + if (waveSampleCountIndex != sampleCountIndex) { + note->noteSubEu.unk_06 = waveSampleCountIndex * 4 + sampleCountIndex; + } +} + +void AudioPlayback_InitNoteList(AudioListItem* list) { + list->prev = list; + list->next = list; + list->u.count = 0; +} + +void AudioPlayback_InitNoteLists(NotePool* pool) { + AudioPlayback_InitNoteList(&pool->disabled); + AudioPlayback_InitNoteList(&pool->decaying); + AudioPlayback_InitNoteList(&pool->releasing); + AudioPlayback_InitNoteList(&pool->active); + pool->disabled.pool = pool; + pool->decaying.pool = pool; + pool->releasing.pool = pool; + pool->active.pool = pool; +} + +void AudioPlayback_InitNoteFreeList(void) { + s32 i; + + AudioPlayback_InitNoteLists(&gAudioContext.noteFreeLists); + for (i = 0; i < gAudioContext.numNotes; i++) { + gAudioContext.notes[i].listItem.u.value = &gAudioContext.notes[i]; + gAudioContext.notes[i].listItem.prev = NULL; + AudioSeq_AudioListPushBack(&gAudioContext.noteFreeLists.disabled, &gAudioContext.notes[i].listItem); + } +} + +void AudioPlayback_NotePoolClear(NotePool* pool) { + s32 i; + AudioListItem* source; + AudioListItem* cur; + AudioListItem* dest; + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: + source = &pool->disabled; + dest = &gAudioContext.noteFreeLists.disabled; + break; + + case 1: + source = &pool->decaying; + dest = &gAudioContext.noteFreeLists.decaying; + break; + + case 2: + source = &pool->releasing; + dest = &gAudioContext.noteFreeLists.releasing; + break; + + case 3: + source = &pool->active; + dest = &gAudioContext.noteFreeLists.active; + break; + } + + for (;;) { + cur = source->next; + if (cur == source || cur == NULL) { + break; + } + AudioPlayback_AudioListRemove(cur); + AudioSeq_AudioListPushBack(dest, cur); + } + } +} + +void AudioPlayback_NotePoolFill(NotePool* pool, s32 count) { + s32 i; + s32 j; + Note* note; + AudioListItem* source; + AudioListItem* dest; + + AudioPlayback_NotePoolClear(pool); + + for (i = 0, j = 0; j < count; i++) { + if (i == 4) { + return; + } + + switch (i) { + case 0: + source = &gAudioContext.noteFreeLists.disabled; + dest = &pool->disabled; + break; + + case 1: + source = &gAudioContext.noteFreeLists.decaying; + dest = &pool->decaying; + break; + + case 2: + source = &gAudioContext.noteFreeLists.releasing; + dest = &pool->releasing; + break; + + case 3: + source = &gAudioContext.noteFreeLists.active; + dest = &pool->active; + break; + } + + while (j < count) { + note = AudioSeq_AudioListPopBack(source); + if (note == NULL) { + break; + } + AudioSeq_AudioListPushBack(dest, ¬e->listItem); + j++; + } + } +} + +void AudioPlayback_AudioListPushFront(AudioListItem* list, AudioListItem* item) { + // add 'item' to the front of the list given by 'list', if it's not in any list + if (item->prev == NULL) { + item->prev = list; + item->next = list->next; + list->next->prev = item; + list->next = item; + list->u.count++; + item->pool = list->pool; + } +} + +void AudioPlayback_AudioListRemove(AudioListItem* item) { + // remove 'item' from the list it's in, if any + if (item->prev != NULL) { + item->prev->next = item->next; + item->next->prev = item->prev; + item->prev = NULL; + } +} + +Note* AudioPlayback_FindNodeWithPrioLessThan(AudioListItem* list, s32 limit) { + AudioListItem* cur = list->next; + AudioListItem* best; + + if (cur == list) { + return NULL; + } + + for (best = cur; cur != list; cur = cur->next) { + if (((Note*)best->u.value)->playbackState.priority >= ((Note*)cur->u.value)->playbackState.priority) { + best = cur; + } + } + + if (best == NULL) { + return NULL; + } + + if (limit <= ((Note*)best->u.value)->playbackState.priority) { + return NULL; + } + + return best->u.value; +} + +void AudioPlayback_NoteInitForLayer(Note* note, SequenceLayer* layer) { + s32 pad[3]; + s16 instId; + SequenceChannel* channel = layer->channel; + NotePlaybackState* playbackState = ¬e->playbackState; + NoteSubEu* noteSubEu = ¬e->noteSubEu; + + playbackState->prevParentLayer = NO_LAYER; + playbackState->parentLayer = layer; + playbackState->priority = channel->notePriority; + layer->notePropertiesNeedInit = true; + layer->bit3 = true; + layer->note = note; + channel->noteUnused = note; + channel->layerUnused = layer; + layer->noteVelocity = 0.0f; + AudioPlayback_NoteInit(note); + instId = layer->instOrWave; + + if (instId == 0xFF) { + instId = channel->instOrWave; + } + noteSubEu->sound.soundFontSound = layer->sound; + + if (instId >= 0x80 && instId < 0xC0) { + noteSubEu->bitField1.isSyntheticWave = true; + } else { + noteSubEu->bitField1.isSyntheticWave = false; + } + + if (noteSubEu->bitField1.isSyntheticWave) { + AudioPlayback_BuildSyntheticWave(note, layer, instId); + } else if (channel->unk_DC == 1) { + playbackState->unk_84 = noteSubEu->sound.soundFontSound->sample->loop->start; + } else { + playbackState->unk_84 = channel->unk_DC; + if (playbackState->unk_84 >= noteSubEu->sound.soundFontSound->sample->loop->end) { + playbackState->unk_84 = 0; + } + } + + playbackState->fontId = channel->fontId; + playbackState->stereoHeadsetEffects = channel->stereoHeadsetEffects; + noteSubEu->bitField1.reverbIndex = channel->reverbIndex & 3; +} + +void func_801963E8(Note* note, SequenceLayer* layer) { + // similar to Audio_NoteReleaseAndTakeOwnership, hard to say what the difference is + AudioPlayback_SeqLayerNoteRelease(note->playbackState.parentLayer); + note->playbackState.wantedParentLayer = layer; +} + +void AudioPlayback_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) { + note->playbackState.wantedParentLayer = layer; + note->playbackState.priority = layer->channel->notePriority; + + note->playbackState.adsr.fadeOutVel = gAudioContext.audioBufferParameters.updatesPerFrameInv; + note->playbackState.adsr.action.s.release = true; +} + +Note* AudioPlayback_AllocNoteFromDisabled(NotePool* pool, SequenceLayer* layer) { + Note* note = AudioSeq_AudioListPopBack(&pool->disabled); + if (note != NULL) { + AudioPlayback_NoteInitForLayer(note, layer); + AudioPlayback_AudioListPushFront(&pool->active, ¬e->listItem); + } + return note; +} + +Note* AudioPlayback_AllocNoteFromDecaying(NotePool* pool, SequenceLayer* layer) { + Note* note = AudioPlayback_FindNodeWithPrioLessThan(&pool->decaying, layer->channel->notePriority); + + if (note != NULL) { + AudioPlayback_NoteReleaseAndTakeOwnership(note, layer); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(&pool->releasing, ¬e->listItem); + } + return note; +} + +Note* AudioPlayback_AllocNoteFromActive(NotePool* pool, SequenceLayer* layer) { + Note* rNote; + Note* aNote; + s32 rPriority; + s32 aPriority; + + rPriority = aPriority = 0x10; + rNote = AudioPlayback_FindNodeWithPrioLessThan(&pool->releasing, layer->channel->notePriority); + + if (rNote != NULL) { + rPriority = rNote->playbackState.priority; + } + + aNote = AudioPlayback_FindNodeWithPrioLessThan(&pool->active, layer->channel->notePriority); + + if (aNote != NULL) { + aPriority = aNote->playbackState.priority; + } + + if (rNote == NULL && aNote == NULL) { + return NULL; + } + + if (aPriority < rPriority) { + AudioPlayback_AudioListRemove(&aNote->listItem); + func_801963E8(aNote, layer); + AudioSeq_AudioListPushBack(&pool->releasing, &aNote->listItem); + aNote->playbackState.priority = layer->channel->notePriority; + return aNote; + } + rNote->playbackState.wantedParentLayer = layer; + rNote->playbackState.priority = layer->channel->notePriority; + return rNote; +} + +Note* AudioPlayback_AllocNote(SequenceLayer* layer) { + Note* note; + u32 policy = layer->channel->noteAllocPolicy; + + if (policy & 1) { + note = layer->note; + if (note != NULL && note->playbackState.prevParentLayer == layer && + note->playbackState.wantedParentLayer == NO_LAYER) { + AudioPlayback_NoteReleaseAndTakeOwnership(note, layer); + AudioPlayback_AudioListRemove(¬e->listItem); + AudioSeq_AudioListPushBack(¬e->listItem.pool->releasing, ¬e->listItem); + return note; + } + } + + if (policy & 2) { + if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer))) { + goto null_return; + } + return note; + } + + if (policy & 4) { + if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer))) { + goto null_return; + } + return note; + } + + if (policy & 8) { + if (!(note = AudioPlayback_AllocNoteFromDisabled(&gAudioContext.noteFreeLists, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&gAudioContext.noteFreeLists, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&gAudioContext.noteFreeLists, layer))) { + goto null_return; + } + return note; + } + + if (!(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDisabled(&layer->channel->seqPlayer->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDisabled(&gAudioContext.noteFreeLists, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&layer->channel->seqPlayer->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromDecaying(&gAudioContext.noteFreeLists, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&layer->channel->seqPlayer->notePool, layer)) && + !(note = AudioPlayback_AllocNoteFromActive(&gAudioContext.noteFreeLists, layer))) { + goto null_return; + } + return note; + +null_return: + layer->bit3 = true; + return NULL; +} + +void AudioPlayback_NoteInitAll(void) { + Note* note; + s32 i; + + for (i = 0; i < gAudioContext.numNotes; i++) { + note = &gAudioContext.notes[i]; + note->noteSubEu = gZeroNoteSub; + note->playbackState.priority = 0; + note->playbackState.unk_04 = 0; + note->playbackState.parentLayer = NO_LAYER; + note->playbackState.wantedParentLayer = NO_LAYER; + note->playbackState.prevParentLayer = NO_LAYER; + note->playbackState.waveId = 0; + note->playbackState.attributes.velocity = 0.0f; + note->playbackState.adsrVolScaleUnused = 0; + note->playbackState.adsr.action.asByte = 0; + note->playbackState.vibratoState.active = false; + note->playbackState.portamento.cur = 0; + note->playbackState.portamento.speed = 0; + note->playbackState.stereoHeadsetEffects = false; + note->playbackState.unk_84 = 0; + note->synthesisState.synthesisBuffers = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x2E0); + note->playbackState.attributes.filterBuf = AudioHeap_AllocDmaMemory(&gAudioContext.miscPool, 0x10); + } +} diff --git a/src/code/audio_seqplayer.c b/src/code/audio/audio_seqplayer.c similarity index 74% rename from src/code/audio_seqplayer.c rename to src/code/audio/audio_seqplayer.c index e3841a50a..e57ad19b5 100644 --- a/src/code/audio_seqplayer.c +++ b/src/code/audio/audio_seqplayer.c @@ -12,7 +12,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197A54.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197AA4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequenceChannelDisable.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197B14.s") @@ -20,13 +20,13 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197C8C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197D24.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisableAsFinished.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197D4C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197E08.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPushBack.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197E48.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPopBack.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_80197E88.s") @@ -64,10 +64,10 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019AAF0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019AB40.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_ResetSequencePlayer.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019AC10.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayerChannels.s") #pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019ACEC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/func_8019ADBC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayers.s") 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_synthesis.c b/src/code/audio/audio_synthesis.c similarity index 100% rename from src/code/audio_synthesis.c rename to src/code/audio/audio_synthesis.c diff --git a/src/code/code_80192BE0.c b/src/code/audio/code_80192BE0.c similarity index 92% rename from src/code/code_80192BE0.c rename to src/code/audio/code_80192BE0.c index d408361c7..20b4239da 100644 --- a/src/code/code_80192BE0.c +++ b/src/code/audio/code_80192BE0.c @@ -18,7 +18,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_8019387C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_801938A0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_QueueCmdS8.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_801938D0.s") @@ -76,6 +76,6 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80194568.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_80194668.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_NextRandom.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/func_801946E4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80192BE0/Audio_InitMesgQueues.s") diff --git a/src/code/audio/code_80194790.c b/src/code/audio/code_80194790.c new file mode 100644 index 000000000..9ba2436de --- /dev/null +++ b/src/code/audio/code_80194790.c @@ -0,0 +1,9 @@ +#include "global.h" + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194790/func_80194790.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194790/func_80194804.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194790/func_80194840.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194790/func_801948B0.s") diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c new file mode 100644 index 000000000..2e7cc91e1 --- /dev/null +++ b/src/code/audio/code_8019AF00.c @@ -0,0 +1,2703 @@ +#include "global.h" + +typedef struct { + /* 0x0 */ s8 x; + /* 0x1 */ s8 y; +} OcarinaControlStick; // size = 0x2 + +typedef struct { + /* 0x0 */ u16 playerIO; + /* 0x2 */ u16 channelMask; + /* 0x4 */ u8 channelIO[3 * 33 + 1]; +} NatureAmbienceDataIO; // size = 0x68 + +typedef struct { + /* 0x0 */ Vec3f* pos; + /* 0x4 */ f32 freqScale; + /* 0x8 */ s8 reverbAdd; +} SfxSettings; // size = 0x9 + +typedef struct { + /* 0x0 */ f32 vol; + /* 0x4 */ f32 freqScale; + /* 0x8 */ s8 reverb; + /* 0x9 */ s8 panSigned; + /* 0xA */ s8 stereoBits; + /* 0xB */ u8 filter; + /* 0xC */ u8 unk_0C; + /* 0xD */ u8 unk_0D; +} SfxPlayerState; // size = 0xE + +typedef enum { + /* 0x0 */ SFX_CHANNEL_PLAYER0, // SfxPlayerBank + /* 0x1 */ SFX_CHANNEL_PLAYER1, + /* 0x2 */ SFX_CHANNEL_PLAYER2, + /* 0x3 */ SFX_CHANNEL_ITEM0, // SfxItemBank + /* 0x4 */ SFX_CHANNEL_ITEM1, + /* 0x5 */ SFX_CHANNEL_ENV0, // SfxEnvironmentBank + /* 0x6 */ SFX_CHANNEL_ENV1, + /* 0x7 */ SFX_CHANNEL_ENV2, + /* 0x8 */ SFX_CHANNEL_ENEMY0, // SfxEnemyBank + /* 0x9 */ SFX_CHANNEL_ENEMY1, + /* 0xA */ SFX_CHANNEL_ENEMY2, + /* 0xB */ SFX_CHANNEL_SYSTEM0, // SfxSystemBank + /* 0xC */ SFX_CHANNEL_SYSTEM1, + /* 0xD */ SFX_CHANNEL_OCARINA, // SfxOcarinaBank + /* 0xE */ SFX_CHANNEL_VOICE0, // SfxVoiceBank + /* 0xF */ SFX_CHANNEL_VOICE1 +} SfxChannelIndex; // playerIndex = 2 + +// Global IO ports for sequences, 8 global ports per seqPlayer +typedef enum { + /* 0x0 */ SEQ_PLAYER_IO_PORT_0, + /* 0x1 */ SEQ_PLAYER_IO_PORT_1, + /* 0x2 */ SEQ_PLAYER_IO_PORT_2, + /* 0x3 */ SEQ_PLAYER_IO_PORT_3, + /* 0x4 */ SEQ_PLAYER_IO_PORT_4, + /* 0x5 */ SEQ_PLAYER_IO_PORT_5, + /* 0x6 */ SEQ_PLAYER_IO_PORT_6, + /* 0x7 */ SEQ_PLAYER_IO_PORT_7, +} SeqPlayerIOPort; + +typedef struct { + /* 0x0 */ f32 value; + /* 0x4 */ f32 target; + /* 0x8 */ f32 step; + /* 0xC */ s32 remainingFrames; +} FreqLerp; // size = 0x10 + +s32 AudioOcarina_MemoryGameGenerateNotes(void); +s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume); +void func_801A3238(s8 playerIndex, u16 seqId, u8 fadeTimer, s8 arg3, u8 arg4); + +// Sfx bss +SfxSettings sSfxSettings[8]; +u8 sSfxSettingsFlags; +f32 sTwoSemitonesLoweredFreq; +s8 sSfxIncreasedReverb; +f32 sSfxSyncedVolume; +f32 sSfxSyncedVolumeForMetalEffects; +f32 sSfxSyncedFreq; +FreqLerp sRiverFreqScaleLerp; +FreqLerp sWaterfallFreqScaleLerp; +f32 sSfxAdjustedFreq; +s8 sSfxCustomReverb; +u8 sRiverSoundMainBgmVol; +u8 sRiverSoundMainBgmCurrentVol; +u8 sRiverSoundMainBgmLower; +u8 sRiverSoundMainBgmRestore; +u8 sGanonsTowerVol; +f32* sSfxVolumeCur; +f32 sSfxVolumeTarget; +f32 sSfxVolumeRate; +u16 sSceneSeqId1; +SfxPlayerState sSfxChannelState[16]; + +// Sequence bss +u8 D_801FD3A8; +u8 D_801FD3A9; +u8 sRiverSoundBgmTimer; +u8 sFanfareState; +u16 sFanfareSeqId; +u8 sMuteOnlySfxAndNatureSeq; +u8 sAllPlayersMutedExceptOcaAndSys; +u8 sAudioPauseState; +u8 sSpatialSeqIsActive[4]; +u8 sSequenceFilter[8 * 4]; +u8 sIsFinalHoursOrSoaring; +u8 sObjSoundFanfareSeqId; +u8 sObjSoundFanfareRequested; +Vec3f sObjSoundFanfarePos; +u8 sObjSoundPlayerIndex; +Vec3f sObjSoundPos; +s16 sObjSoundFlags; +f32 sObjSoundMinDist; +f32 sObjSoundMaxDist; +f32 sObjSoundMaxVol; +f32 sObjSoundMinVol; +Vec3f sSpatialSeqNoFilterPos; +Vec3f sSpatialSeqFilterPos; +f32 sSpatialSeqMaxDist; +u8 sSpatialSeqSeqId; +u8 sSpatialSeqFlags; +u8 D_801FD432; +u8 sSpatialSubBgmFadeTimer; +u8 D_801FD434; +u8 sSpatialSeqPlayerIndex; +u8 sSpatialSeqFadeTimer; +u16 D_801FD438; + +// AudioOcarina bss +OcarinaStaff sPlayingStaff; +OcarinaStaff sPlaybackStaff; +OcarinaStaff sRecordingStaff; +u32 sOcarinaUpdateTaskCurrent; +OcarinaControlStick sOcarinaInputStickRel; +u32 sOcarinaInputButtonCur; +u32 sOcarinaInputButtonStart; +u32 sOcarinaInputButtonPrev; +s32 sOcaInputBtnPress; +u8 sOcarinaResetDelay; +u8 sOcarinaResetUnused; +u8 sOcarinaHasStartedSong; +u8 sFirstOcarinaSongIndex; +u8 sLastOcarinaSongIndex; +u32 sOcarinaAvailSongs; +u8 sOcarinaStaffPlayingPos; +u16 sMusicStaffPos[OCARINA_SONG_MAX]; +u16 sMusicStaffCurHeldLength[OCARINA_SONG_MAX]; +u16 sMusicStaffExpectedLength[OCARINA_SONG_MAX]; +u8 sMusicStaffExpectedPitch[OCARINA_SONG_MAX]; // Next required pitch in song playback +u8 D_801FD518[OCARINA_SONG_MAX]; +u32 D_801FD530[OCARINA_SONG_MAX]; +OcarinaNote sRecordingSongNote; +u16 sCustomSequencePc; + +// Sfx Data +u8 D_801D6600[] = { + true, false, true, true, false, false, true, +}; +u8 D_801D6608[] = { + true, true, true, true, true, false, true, +}; +u8 gChannelsPerBank[4][7] = { + { 3, 2, 3, 3, 2, 1, 2 }, + { 3, 2, 2, 2, 2, 2, 2 }, + { 3, 2, 2, 2, 2, 2, 2 }, + { 4, 1, 0, 0, 2, 2, 2 }, +}; +u8 gUsedChannelsPerBank[4][7] = { + { 3, 2, 3, 2, 2, 1, 1 }, + { 3, 1, 1, 1, 2, 1, 1 }, + { 3, 1, 1, 1, 2, 1, 1 }, + { 2, 1, 0, 0, 1, 1, 1 }, +}; +f32 sGiantsMaskFreq = 0.89167805f; // Around 2 semitones down in pitch +s8 sGiantsMaskReverbAdd = 0x40; +f32 sWaterWheelVolume = 0.65f; +f32 gSfxVolume = 1.0f; +s8 sSfxTimer = 20; +s8 sSfxTimerLerpRange2 = 30; +s8 sSfxTimerLerpRange1 = 20; +f32 sBehindScreenZ[2] = { -15.0f, -65.0f }; // Unused Remnant of OoT +u8 sAudioIncreasingTranspose = 0; // Remnant of OoT, only unsed in unused functions +u8 gMorphaTransposeTable[16] = { 0, 0, 0, 1, 1, 2, 4, 6, 8, 8, 8, 8, 8, 8, 8, 8 }; // Unused Remnant of OoT +u8 sPrevChargeLevel = 0; +f32 sChargeLevelsSfxFreq[] = { 1.0f, 1.12246f, 1.33484f, 1.33484f }; +f32 sCurChargeLevelSfxFreq = 1.0f; +u8 sGanonsTowerLevelsVol[] = { + 127, 80, 75, 73, 70, 68, 65, 60 // volumes +}; +u8 sEnterGanonsTowerTimer = 0; +u16 sSfxVolumeDuration = 0; + +// System Data +s8 sAudioFileSelectSetting = AUDIO_FS_STEREO; +s8 sAudioIsWindowOpen = false; +s8 sAudioCutsceneFlag = false; +s8 sSpecReverb = 0; +s8 sAudioEnvReverb = 0; +s8 sAudioCodeReverb = 0; + +// Sequence Data +u8 sPrevSeqMode = 0; +f32 sAudioEnemyDist = 0.0f; +s8 sAudioEnemyVol = 127; +u16 sPrevMainBgmSeqId = NA_BGM_DISABLED; +u8 sBgmPlayerIOPort7 = 0; +u8 sSceneSeqId2 = NA_BGM_GENERAL_SFX; +u32 sNumFramesStill = 0; +u32 sNumFramesMoving = 0; +u8 sAudioBaseFilter = 0; +u8 sAudioExtraFilter = 0; +u8 sAudioBaseFilter2 = 0; +u8 sAudioExtraFilter2 = 0; +s8 gUnderwaterSfxReverbAdd = 0; +Vec3f* sRiverSoundBgmPos = NULL; +f32 sRiverSoundXZDistToPlayer = 2000.0f; +u8 sObjSoundMainBgmSeqId = NA_BGM_GENERAL_SFX; +u8 sSeqFlags[] = { + 0x3, // NA_BGM_GENERAL_SFX + 0x1, // NA_BGM_NATURE_AMBIENCE + 0x1, // NA_BGM_TERMINA_FIELD + 0x8, // NA_BGM_CHASE + 0, // NA_BGM_MAJORAS_THEME + 0, // NA_BGM_CLOCK_TOWER + 0x1, // NA_BGM_STONE_TOWER_TEMPLE + 0x1, // NA_BGM_INV_STONE_TOWER_TEMPLE + 0x2, // NA_BGM_FAILURE_0 + 0x2, // NA_BGM_FAILURE_1 + 0, // NA_BGM_HAPPY_MASK_SALESMAN + 0, // NA_BGM_SONG_OF_HEALING + 0x1, // NA_BGM_SWAMP_REGION + 0, // NA_BGM_ALIEN_INVASION + 0x2, // NA_BGM_SWAMP_CRUISE + 0, // NA_BGM_SHARPS_CURSE + 0x1, // NA_BGM_GREAT_BAY_REGION + 0x1, // NA_BGM_IKANA_REGION + 0, // NA_BGM_DEKU_KING + 0x1, // NA_BGM_MOUNTAIN_REGION + 0, // NA_BGM_PIRATES_FORTRESS + 0, // NA_BGM_CLOCK_TOWN_DAY_1 + 0, // NA_BGM_CLOCK_TOWN_DAY_2 + 0, // NA_BGM_CLOCK_TOWN_DAY_3 + 0x40, // NA_BGM_FILE_SELECT + 0x10, // NA_BGM_CLEAR_EVENT + 0, // NA_BGM_ENEMY + 0x8, // NA_BGM_BOSS + 0x1, // NA_BGM_WOODFALL_TEMPLE + 0, // NA_BGM_MARKET + 0, // NA_BGM_OPENING + 0x20, // NA_BGM_INSIDE_A_HOUSE + 0x2, // NA_BGM_GAME_OVER + 0, // NA_BGM_CLEAR_BOSS + 0x2, // NA_BGM_GET_ITEM + 0x2, // NA_BGM_GATE_OPEN + 0x2, // NA_BGM_GET_HEART + 0x8, // NA_BGM_TIMED_MINI_GAME + 0, // NA_BGM_GORON_RACE + 0, // NA_BGM_MUSIC_BOX_HOUSE + 0, // NA_BGM_FAIRY_FOUNTAIN + 0, // NA_BGM_ZELDAS_LULLABY + 0, // NA_BGM_ROSA_SISTERS + 0x2, // NA_BGM_OPEN_CHEST + 0, // NA_BGM_MARINE_RESEARCH_LAB + 0x40, // NA_BGM_GIANTS_THEME + 0, // NA_BGM_SONG_OF_STORMS + 0, // NA_BGM_ROMANI_RANCH + 0, // NA_BGM_GORON_VILLAGE + 0, // NA_BGM_MAYORS_OFFICE + 0x2, // NA_BGM_OCA_EPONA + 0x2, // NA_BGM_OCA_SUNS + 0x2, // NA_BGM_OCA_TIME + 0x2, // NA_BGM_OCA_STORM + 0x10, // NA_BGM_ZORA_HALL + 0x2, // NA_BGM_GET_NEW_MASK + 0x8, // NA_BGM_MINI_BOSS + 0x2, // NA_BGM_GET_SMALL_ITEM + 0, // NA_BGM_ASTRAL_OBSERVATORY + 0x1, // NA_BGM_CAVERN + 0x11, // NA_BGM_MILK_BAR + 0x2, // NA_BGM_ZELDA_APPEAR + 0, // NA_BGM_SARIAS_SONG + 0, // NA_BGM_GORON_GOAL + 0, // NA_BGM_HORSE + 0, // NA_BGM_HORSE_GOAL + 0, // NA_BGM_INGO + 0, // NA_BGM_KOTAKE_POTION_SHOP + 0x20, // NA_BGM_SHOP + 0x2, // NA_BGM_OWL + 0x20, // NA_BGM_MINI_GAME + 0x2, // NA_BGM_OCA_SOARING + 0x2, // NA_BGM_OCA_HEALING + 0x2, // NA_BGM_INVERTED_SONG_OF_TIME + 0x2, // NA_BGM_SONG_OF_DOUBLE_TIME + 0x2, // NA_BGM_SONATA_OF_AWAKENING + 0x2, // NA_BGM_GORON_LULLABY + 0x2, // NA_BGM_NEW_WAVE_BOSSA_NOVA + 0x2, // NA_BGM_ELEGY_OF_EMPTINESS + 0x2, // NA_BGM_OATH_TO_ORDER + 0, // NA_BGM_SWORD_TRAINING_HALL + 0x2, // NA_BGM_GORON_LULLABY_INTRO + 0x2, // NA_BGM_OCA_FAIRY + 0x2, // NA_BGM_BREMEN_MARCH + 0x2, // NA_BGM_BALLAD_OF_THE_WIND_FISH + 0x8, // NA_BGM_SONG_OF_SOARING + 0, // NA_BGM_MILK_BAR_DUPLICATE + 0, // NA_BGM_FINAL_HOURS + 0x2, // NA_BGM_MIKAU_RIFF + 0x2, // NA_BGM_MIKAU_FINALE + 0, // NA_BGM_FROG_SONG + 0x2, // NA_BGM_OCA_SONATA + 0x2, // NA_BGM_OCA_LULLABY + 0x2, // NA_BGM_OCA_NEW_WAVE + 0x2, // NA_BGM_OCA_ELEGY + 0x2, // NA_BGM_OCA_OATH + 0, // NA_BGM_MAJORAS_LAIR + 0x2, // NA_BGM_OCA_LULLABY_INTRO + 0x2, // NA_BGM_OCA_GUITAR_BASS_SESSION + 0x2, // NA_BGM_PIANO_SESSION + 0x2, // NA_BGM_INDIGO_GO_SESSION + 0x1, // NA_BGM_SNOWHEAD_TEMPLE + 0x1, // NA_BGM_GREAT_BAY_TEMPLE + 0x2, // NA_BGM_NEW_WAVE_SAXOPHONE + 0x2, // NA_BGM_NEW_WAVE_VOCAL + 0, // NA_BGM_MAJORAS_WRATH + 0, // NA_BGM_MAJORAS_INCARNATION + 0, // NA_BGM_MAJORAS_MASK + 0x2, // NA_BGM_BASS_PLAY + 0x2, // NA_BGM_DRUMS_PLAY + 0x2, // NA_BGM_PIANO_PLAY + 0x1, // NA_BGM_IKANA_CASTLE + 0, // NA_BGM_GATHERING_GIANTS + 0x4, // NA_BGM_KAMARO_DANCE + 0, // NA_BGM_CREMIA_CARRIAGE + 0x2, // NA_BGM_KEATON_QUIZ + 0, // NA_BGM_END_CREDITS_1 + 0, // NA_BGM_OPENING_LOOP + 0, // NA_BGM_TITLE_THEME + 0x2, // NA_BGM_DUNGEON_APPEAR + 0x2, // NA_BGM_WOODFALL_CLEAR + 0x2, // NA_BGM_SNOWHEAD_CLEAR + 0, // + 0, // NA_BGM_INTO_THE_MOON + 0, // NA_BGM_GOODBYE_GIANT + 0, // NA_BGM_TATL_AND_TAEL + 0, // NA_BGM_MOONS_DESTRUCTION + 0, // NA_BGM_END_CREDITS_2 +}; + +s8 sSpecReverbs[20] = { + 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +NatureAmbienceDataIO sNatureAmbienceData[20] = { + // natureSeqId: 0 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_09), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(32), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_1_BEND_PITCH(0), + NATURE_IO_CRITTER_1_NUM_LAYERS(1), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_10), + NATURE_IO_CRITTER_2_BEND_PITCH(112), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(48), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_03), + NATURE_IO_CRITTER_3_BEND_PITCH(127), + NATURE_IO_CRITTER_3_NUM_LAYERS(0), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_00), + NATURE_IO_CRITTER_4_BEND_PITCH(127), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(16), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(3), + NATURE_IO_CRITTER_5_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 1 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(32), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_16), + NATURE_IO_CRITTER_1_BEND_PITCH(0), + NATURE_IO_CRITTER_1_NUM_LAYERS(1), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_12), + NATURE_IO_CRITTER_2_BEND_PITCH(112), + NATURE_IO_CRITTER_2_NUM_LAYERS(0), + NATURE_IO_CRITTER_2_PORT5(48), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_15), + NATURE_IO_CRITTER_3_BEND_PITCH(127), + NATURE_IO_CRITTER_3_NUM_LAYERS(1), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_06), + NATURE_IO_CRITTER_4_BEND_PITCH(127), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(16), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(3), + NATURE_IO_CRITTER_5_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 2 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(48), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_10), + NATURE_IO_CRITTER_1_BEND_PITCH(0), + NATURE_IO_CRITTER_1_NUM_LAYERS(1), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_2_BEND_PITCH(48), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(32), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_03), + NATURE_IO_CRITTER_3_BEND_PITCH(127), + NATURE_IO_CRITTER_3_NUM_LAYERS(0), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_4_BEND_PITCH(64), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(0), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(0), + NATURE_IO_CRITTER_5_PORT5(63), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 3 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_09), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(32), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_1_BEND_PITCH(64), + NATURE_IO_CRITTER_1_NUM_LAYERS(0), + NATURE_IO_CRITTER_1_PORT5(48), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_10), + NATURE_IO_CRITTER_2_BEND_PITCH(32), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(32), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_14), + NATURE_IO_CRITTER_3_BEND_PITCH(64), + NATURE_IO_CRITTER_3_NUM_LAYERS(1), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_00), + NATURE_IO_CRITTER_4_BEND_PITCH(127), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(16), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(3), + NATURE_IO_CRITTER_5_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 4 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(32), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_02), + NATURE_IO_CRITTER_1_BEND_PITCH(64), + NATURE_IO_CRITTER_1_NUM_LAYERS(1), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_12), + NATURE_IO_CRITTER_2_BEND_PITCH(112), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(48), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_13), + NATURE_IO_CRITTER_3_BEND_PITCH(64), + NATURE_IO_CRITTER_3_NUM_LAYERS(1), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_4_BEND_PITCH(64), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(16), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_02), + NATURE_IO_CRITTER_5_BEND_PITCH(112), + NATURE_IO_CRITTER_5_NUM_LAYERS(0), + NATURE_IO_CRITTER_5_PORT5(48), + + // Channel 14 + NATURE_IO_RAIN_PORT4(63), + + // End + NATURE_IO_ENTRIES_END, + + }, + }, + + // natureSeqId: 5 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_09), + NATURE_IO_CRITTER_0_BEND_PITCH(64), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(32), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_1_BEND_PITCH(0), + NATURE_IO_CRITTER_1_NUM_LAYERS(1), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_10), + NATURE_IO_CRITTER_2_BEND_PITCH(112), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(48), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_13), + NATURE_IO_CRITTER_3_BEND_PITCH(127), + NATURE_IO_CRITTER_3_NUM_LAYERS(0), + NATURE_IO_CRITTER_3_PORT5(63), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_00), + NATURE_IO_CRITTER_4_BEND_PITCH(127), + NATURE_IO_CRITTER_4_NUM_LAYERS(1), + NATURE_IO_CRITTER_4_PORT5(16), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(3), + NATURE_IO_CRITTER_5_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 6 + { + 0xC0FF, // PlayerIO Data + 0xC0FE, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_11), + NATURE_IO_CRITTER_0_BEND_PITCH(112), + NATURE_IO_CRITTER_0_NUM_LAYERS(0), + NATURE_IO_CRITTER_0_PORT5(48), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_15), + NATURE_IO_CRITTER_1_BEND_PITCH(112), + NATURE_IO_CRITTER_1_NUM_LAYERS(0), + NATURE_IO_CRITTER_1_PORT5(63), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_11), + NATURE_IO_CRITTER_2_BEND_PITCH(48), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(16), + + // Channel 4 + NATURE_IO_CRITTER_3_TYPE(NATURE_CRITTER_14), + NATURE_IO_CRITTER_3_BEND_PITCH(48), + NATURE_IO_CRITTER_3_NUM_LAYERS(1), + NATURE_IO_CRITTER_3_PORT5(16), + + // Channel 5 + NATURE_IO_CRITTER_4_TYPE(NATURE_CRITTER_11), + NATURE_IO_CRITTER_4_BEND_PITCH(127), + NATURE_IO_CRITTER_4_NUM_LAYERS(0), + NATURE_IO_CRITTER_4_PORT5(32), + + // Channel 6 + NATURE_IO_CRITTER_5_TYPE(NATURE_CRITTER_02), + NATURE_IO_CRITTER_5_BEND_PITCH(127), + NATURE_IO_CRITTER_5_NUM_LAYERS(0), + NATURE_IO_CRITTER_5_PORT5(48), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 7 + { + 0xC001, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 8 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_0_BEND_PITCH(127), + NATURE_IO_CRITTER_0_NUM_LAYERS(3), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 9 + { + 0xC00F, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_16), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(2), + NATURE_IO_CRITTER_0_PORT5(16), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_12), + NATURE_IO_CRITTER_1_BEND_PITCH(112), + NATURE_IO_CRITTER_1_NUM_LAYERS(0), + NATURE_IO_CRITTER_1_PORT5(48), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_15), + NATURE_IO_CRITTER_2_BEND_PITCH(127), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 10 + { + 0xC081, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_1), + NATURE_IO_STREAM_0_PORT3(8), + + // Channel 7 + NATURE_IO_CRITTER_6_TYPE(NATURE_CRITTER_11), + NATURE_IO_CRITTER_6_BEND_PITCH(112), + NATURE_IO_CRITTER_6_NUM_LAYERS(2), + NATURE_IO_CRITTER_6_PORT5(32), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 11 + { + 0xC00F, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_3), + NATURE_IO_STREAM_0_PORT3(8), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_0_BEND_PITCH(127), + NATURE_IO_CRITTER_0_NUM_LAYERS(3), + NATURE_IO_CRITTER_0_PORT5(16), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_00), + NATURE_IO_CRITTER_1_BEND_PITCH(127), + NATURE_IO_CRITTER_1_NUM_LAYERS(2), + NATURE_IO_CRITTER_1_PORT5(16), + + // Channel 3 + NATURE_IO_CRITTER_2_TYPE(NATURE_CRITTER_06), + NATURE_IO_CRITTER_2_BEND_PITCH(127), + NATURE_IO_CRITTER_2_NUM_LAYERS(1), + NATURE_IO_CRITTER_2_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 12 + { + 0xC007, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_00), + NATURE_IO_CRITTER_0_BEND_PITCH(127), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // Channel 2 + NATURE_IO_CRITTER_1_TYPE(NATURE_CRITTER_01), + NATURE_IO_CRITTER_1_BEND_PITCH(127), + NATURE_IO_CRITTER_1_NUM_LAYERS(3), + NATURE_IO_CRITTER_1_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 13 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 14 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 15 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 16 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 17 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 18 + { + 0xC000, // PlayerIO Data + 0xC000, // Channel Mask + { + // Channel 0 + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + + // End + NATURE_IO_ENTRIES_END, + }, + }, + + // natureSeqId: 19 + { + 0xC003, // PlayerIO Data + 0xC000, // Channel Mask + { + NATURE_IO_STREAM_0_TYPE(NATURE_STREAM_0), + NATURE_IO_STREAM_0_PORT3(0), + + // Channel 1 + NATURE_IO_CRITTER_0_TYPE(NATURE_CRITTER_04), + NATURE_IO_CRITTER_0_BEND_PITCH(0), + NATURE_IO_CRITTER_0_NUM_LAYERS(1), + NATURE_IO_CRITTER_0_PORT5(16), + + // End + NATURE_IO_ENTRIES_END, + + }, + }, +}; + +// AudioOcarina Data +u8 sIsOcarinaInputEnabled = false; +s8 sOcarinaInstrumentId = OCARINA_INSTRUMENT_OFF; +u8 sCurOcarinaPitch = OCARINA_PITCH_NONE; +u8 sPrevOcarinaPitch = 0; +u8 sCurOcarinaButtonIndex = 0; +u8 sMusicStaffPrevPitch = 0; +f32 sCurOcarinaBendFreq = 1.0f; +f32 sDefaultOcarinaVolume = 0.68503935f; +s8 sCurOcarinaBendIndex = 0; +s8 sCurOcarinaVolume = 0x57; +s8 sCurOcarinaVibrato = 0; +u8 sPlaybackState = 0; +u8 D_801D6FE4 = 0xFF; +u8 D_801D6FE8 = 0xFF; +u32 sOcarinaFlags = 0; +s32 sPlaybackNoteTimer = 0; +u16 sPlaybackNotePos = 0; +u16 sPlaybackStaffPos = 0; +u32 sPrevOcarinaSongFlags = 0; // Stores sOcarinaFlags but never used +u8 sPlaybackNoteValue = OCARINA_PITCH_NONE; +u8 sNotePlaybackVolume = 0; +u8 sNotePlaybackVibrato = 0; +s8 sNotePlaybackBend = 0; +f32 sNormalizedNotePlaybackTone = 1.0f; +f32 sNormalizedNotePlaybackVolume = 1.0f; +u32 sOcarinaPlaybackTaskStart = 0; +u32 sOcarinaWallCounter = 0; +u8 sCurOcarinaSong[8] = { + OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, + OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, OCARINA_PITCH_C4, +}; +u8 sOcarinaSongAppendPos = 0; +u8 sOcarinaSongStartingPos = 0; + +u8 sButtonToPitchMap[5] = { + OCARINA_PITCH_D4, // OCARINA_BTN_A + OCARINA_PITCH_F4, // OCARINA_BTN_C_DOWN + OCARINA_PITCH_A4, // OCARINA_BTN_C_RIGHT + OCARINA_PITCH_B4, // OCARINA_BTN_C_LEFT + OCARINA_PITCH_D5, // OCARINA_BTN_C_UP +}; + +u8 sOcarinaMemoryGameAppendPos = 0; +u8 sOcaMemoryGameEndPos = 0; +u8 sOcaMemoryGameNumNotes[] = { 5, 6, 8 }; +OcarinaNote sOcarinaSongNotes[OCARINA_SONG_MAX][20] = { + // 0: Sonata of Awakening + { + { OCARINA_PITCH_D5, 19, 92, 0, 0, 0 }, + { OCARINA_PITCH_B4, 19, 90, 0, 0, 0 }, + { OCARINA_PITCH_D5, 19, 90, 0, 0, 0 }, + { OCARINA_PITCH_B4, 38, 90, 0, 0, 0 }, + { OCARINA_PITCH_D4, 39, 92, 0, 0, 0 }, + { OCARINA_PITCH_A4, 76, 89, 0, 0, 0 }, + { OCARINA_PITCH_D4, 77, 82, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 }, + }, + + // 1: Goron Lullaby + { + { OCARINA_PITCH_D4, 41, 80, 0, 0, 0 }, + { OCARINA_PITCH_A4, 40, 72, 0, 0, 0 }, + { OCARINA_PITCH_B4, 39, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 42, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 40, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 39, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 41, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 80, 76, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 40, 76, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 2: New Wave Bossa Nova + { + { OCARINA_PITCH_B4, 64, 74, 0, 0, 0 }, + { OCARINA_PITCH_D5, 13, 88, 0, 0, 0 }, + { OCARINA_PITCH_B4, 12, 90, 0, 0, 0 }, + { OCARINA_PITCH_A4, 78, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 12, 76, 0, 0, 0 }, + { OCARINA_PITCH_B4, 13, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 114, 76, 6, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 3: Elegy of Emptyness + { + { OCARINA_PITCH_A4, 85, 93, 0, 0, 0 }, + { OCARINA_PITCH_B4, 43, 91, 0, 0, 0 }, + { OCARINA_PITCH_A4, 43, 93, 0, 0, 0 }, + { OCARINA_PITCH_F4, 21, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 21, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 43, 101, 0, 0, 0 }, + { OCARINA_PITCH_B4, 85, 95, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 }, + }, + + // 4: Oath to Order + { + { OCARINA_PITCH_A4, 97, 104, 0, 0, 0 }, + { OCARINA_PITCH_F4, 48, 88, 0, 0, 0 }, + { OCARINA_PITCH_D4, 49, 78, 0, 0, 0 }, + { OCARINA_PITCH_F4, 49, 78, 0, 0, 0 }, + { OCARINA_PITCH_A4, 48, 94, 0, 0, 0 }, + { OCARINA_PITCH_D5, 97, 100, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 96, 0, 0, 0 }, + + }, + + // 5: Sarias Song + { + { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, + { OCARINA_PITCH_B4, 34, 80, 0, 0, 0 }, + { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, + { OCARINA_PITCH_B4, 136, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 6: Song of Time + { + { OCARINA_PITCH_A4, 32, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 33, 80, 0, 0, 0 }, + { OCARINA_PITCH_A4, 32, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 99, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 7: Song of Healing + { + { OCARINA_PITCH_B4, 32, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 33, 69, 0, 0, 0 }, + { OCARINA_PITCH_B4, 32, 94, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 121, 86, 2, 0, 0 }, + { OCARINA_PITCH_NONE, 10, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 8: Eponas Song + { + { OCARINA_PITCH_D5, 18, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 72, 80, 0, 0, 0 }, + { OCARINA_PITCH_D5, 18, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 144, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 9: Song of Soaring + { + { OCARINA_PITCH_F4, 18, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 80, 0, 0, 0 }, + { OCARINA_PITCH_D5, 36, 94, 0, 0, 0 }, + { OCARINA_PITCH_F4, 18, 73, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 76, 0, 0, 0 }, + { OCARINA_PITCH_D5, 108, 96, 2, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 10: Song of Storms + { + { OCARINA_PITCH_D4, 11, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 11, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 45, 80, 0, 0, 0 }, + { OCARINA_PITCH_D4, 11, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 11, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 90, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 11: Suns Song + { + { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 29, 80, 2, 0, 0 }, + { OCARINA_PITCH_NONE, 9, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 120, 80, 3, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 12: Inverted Song of Time + { + { OCARINA_PITCH_F4, 32, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 80, 0, 0, 0 }, + { OCARINA_PITCH_F4, 32, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 65, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 99, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 13: Song of Double Time + { + { OCARINA_PITCH_A4, 29, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 30, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 29, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 29, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 99, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, + }, + + // 14: Goron Lullaby Intro + { + { OCARINA_PITCH_D4, 32, 78, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 90, 0, 0, 0 }, + { OCARINA_PITCH_B4, 33, 87, 0, 0, 0 }, + { OCARINA_PITCH_D4, 32, 92, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 86, 0, 0, 0 }, + { OCARINA_PITCH_B4, 130, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 15: Milk Bar Jam "Ballad of the Wind Fish" Human + { + { OCARINA_PITCH_D5, 89, 80, 0, 0, 0 }, + { OCARINA_PITCH_A4, 41, 72, 0, 0, 0 }, + { OCARINA_PITCH_B4, 22, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 91, 76, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 30, 66, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 16: Milk Bar Jam "Ballad of the Wind Fish" Goron + { + { OCARINA_PITCH_D4, 52, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_D4, 8, 72, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_F4, 34, 76, 0, 0, 0 }, + { OCARINA_PITCH_D4, 52, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_D4, 8, 72, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_D4, 30, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 66, 0, 0, 0 }, + { OCARINA_PITCH_A4, 34, 76, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 17: Milk Bar Jam "Ballad of the Wind Fish" Zora + { + { OCARINA_PITCH_D5, 11, 80, 0, 0, 0 }, + { OCARINA_PITCH_A4, 11, 72, 0, 0, 0 }, + { OCARINA_PITCH_F4, 11, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 100, 76, 0, 0, 0 }, + { OCARINA_PITCH_D5, 11, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 11, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 11, 72, 0, 0, 0 }, + { OCARINA_PITCH_F4, 100, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 18: Milk Bar Jam "Ballad of the Wind Fish" Deku + { + { OCARINA_PITCH_A4, 54, 80, 0, 0, 0 }, + { OCARINA_PITCH_D4, 77, 72, 0, 0, 0 }, + { OCARINA_PITCH_F4, 19, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 20, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 78, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 19: Evan HP (Zora Band Leader) Song Part 1 + { + { OCARINA_PITCH_A4, 33, 100, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 92, 0, 0, 0 }, + { OCARINA_PITCH_A4, 37, 104, 0, 0, 0 }, + { OCARINA_PITCH_F4, 24, 100, 0, 0, 0 }, + { OCARINA_PITCH_D4, 70, 97, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 96, 0, 0, 0 }, + { OCARINA_PITCH_D4, 12, 93, 0, 0, 0 }, + { OCARINA_PITCH_F4, 12, 100, 0, 0, 0 }, + { OCARINA_PITCH_A4, 12, 62, 0, 0, 0 }, + { OCARINA_PITCH_D4, 170, 91, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 20: Evan HP (Zora Band Leader) Song Part 2 + { + { OCARINA_PITCH_B4, 33, 107, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 100, 0, 0, 0 }, + { OCARINA_PITCH_B4, 37, 104, 0, 0, 0 }, + { OCARINA_PITCH_A4, 24, 97, 0, 0, 0 }, + { OCARINA_PITCH_F4, 70, 104, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 104, 0, 0, 0 }, + { OCARINA_PITCH_F4, 12, 90, 0, 0, 0 }, + { OCARINA_PITCH_A4, 12, 96, 0, 0, 0 }, + { OCARINA_PITCH_B4, 12, 81, 0, 0, 0 }, + { OCARINA_PITCH_F4, 170, 66, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // 21: Zeldas Lullaby + { + { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, + { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 78, 80, 0, 0, 0 }, + { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, + { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 100, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // 22: Scarecrow + { + { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, + }, + + // 23: Termina Field 2D Song Buttons Appearing on Wall (In OoT, this is Ocarina Memory Game) + { + { OCARINA_PITCH_D4, 3, 0, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 255, 0, 0, 0 }, + }, +}; + +OcarinaNote sOoTOcarinaSongNotes[9][20] = { + // Minuet + { + { OCARINA_PITCH_D4, 18, 86, 0, 0, 0 }, + { OCARINA_PITCH_D5, 18, 92, 0, 0, 0 }, + { OCARINA_PITCH_B4, 72, 86, 0, 0, 0 }, + { OCARINA_PITCH_A4, 18, 80, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 144, 86, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 86, 0, 0, 0 }, + }, + + // Bolero + { + { OCARINA_PITCH_F4, 15, 80, 0, 0, 0 }, + { OCARINA_PITCH_D4, 15, 72, 0, 0, 0 }, + { OCARINA_PITCH_F4, 15, 84, 0, 0, 0 }, + { OCARINA_PITCH_D4, 15, 76, 0, 0, 0 }, + { OCARINA_PITCH_A4, 15, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 15, 74, 0, 0, 0 }, + { OCARINA_PITCH_A4, 15, 78, 0, 0, 0 }, + { OCARINA_PITCH_F4, 135, 66, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 66, 0, 0, 0 }, + }, + + // Serenade + { + { OCARINA_PITCH_D4, 36, 60, 0, 0, 0 }, + { OCARINA_PITCH_F4, 36, 78, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 82, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 82, 0, 0, 0 }, + { OCARINA_PITCH_A4, 36, 84, 0, 0, 0 }, + { OCARINA_PITCH_B4, 144, 90, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // Requiem + { + { OCARINA_PITCH_D4, 45, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 23, 86, 0, 0, 0 }, + { OCARINA_PITCH_D4, 22, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 45, 86, 0, 0, 0 }, + { OCARINA_PITCH_F4, 45, 94, 0, 0, 0 }, + { OCARINA_PITCH_D4, 180, 94, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 94, 0, 0, 0 }, + }, + + // Nocturne + { + { OCARINA_PITCH_B4, 36, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 33, 84, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 3, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 18, 82, 0, 0, 0 }, + { OCARINA_PITCH_D4, 18, 60, 0, 0, 0 }, + { OCARINA_PITCH_B4, 18, 90, 0, 0, 0 }, + { OCARINA_PITCH_A4, 18, 88, 0, 0, 0 }, + { OCARINA_PITCH_F4, 144, 96, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 96, 0, 0, 0 }, + }, + + // Prelude + { + { OCARINA_PITCH_D5, 15, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 45, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 15, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 15, 82, 0, 0, 0 }, + { OCARINA_PITCH_B4, 15, 86, 0, 0, 0 }, + { OCARINA_PITCH_D5, 60, 90, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 75, 90, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // Sarias + { + { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, + { OCARINA_PITCH_B4, 34, 80, 0, 0, 0 }, + { OCARINA_PITCH_F4, 17, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 17, 88, 0, 0, 0 }, + { OCARINA_PITCH_B4, 136, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // Zeldas Lullaby + { + { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, + { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 78, 80, 0, 0, 0 }, + { OCARINA_PITCH_B4, 51, 84, 0, 0, 0 }, + { OCARINA_PITCH_D5, 25, 88, 0, 0, 0 }, + { OCARINA_PITCH_A4, 100, 80, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, + + // Suns Song + { + { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 29, 80, 2, 0, 0 }, + { OCARINA_PITCH_NONE, 9, 84, 0, 0, 0 }, + { OCARINA_PITCH_A4, 12, 84, 0, 0, 0 }, + { OCARINA_PITCH_F4, 13, 88, 0, 0, 0 }, + { OCARINA_PITCH_D5, 120, 80, 3, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 90, 0, 0, 0 }, + }, +}; + +u8 sOoTOcarinaSongsNumNotes[] = { + 6, // Minuet + 8, // Bolero + 5, // Serenade + 6, // Requiem + 7, // Nocturne + 6, // Prelude + 6, // Sarias + 6, // Zeldas Lullaby + 6, // Suns Song +}; + +OcarinaNote* sPlaybackSong = sOcarinaSongNotes[OCARINA_SONG_SONATA]; +u8 sFrogsSongNotes[14] = { + OCARINA_BTN_A, OCARINA_BTN_C_LEFT, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, OCARINA_BTN_C_DOWN, OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, OCARINA_BTN_C_RIGHT, OCARINA_BTN_C_LEFT, OCARINA_BTN_A, +}; +u8* gFrogsSongPtr = sFrogsSongNotes; +u8 sRecordingState = OCARINA_RECORD_OFF; +u8 sRecordSongPos = 0; +u32 sOcarinaRecordTaskStart = 0; +u8 sRecordOcarinaPitch = 0; +u8 sRecordOcarinaVolume = 0; +u8 sRecordOcarinaVibrato = 0; +s8 sRecordOcarinaBendIndex = 0; +u8 sRecordOcarinaButtonIndex = 0; +u8 sPlayedOcarinaSongIndexPlusOne = 0; +u8 sMusicStaffNumNotesPerTest = 0; +u8 D_801D8530 = false; +u32 D_801D8534 = 0; +u8 sIsOcarinaNoteChanged = false; + +OcarinaNote sScarecrowsLongSongNotes[108] = { + { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, + { OCARINA_PITCH_NONE, 0, 0, 0, 0, 0 }, +}; + +OcarinaNote* gScarecrowLongSongPtr = sScarecrowsLongSongNotes; +u8* gScarecrowSpawnSongPtr = (u8*)&sOcarinaSongNotes[OCARINA_SONG_SCARECROW]; +OcarinaNote* sTerminaWallSongPtr = sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL]; + +u8 sPitchToButtonMap[16] = { + OCARINA_BTN_A, // OCARINA_PITCH_C4 + OCARINA_BTN_A, // OCARINA_PITCH_DFLAT4 + OCARINA_BTN_A, // OCARINA_PITCH_D4 + OCARINA_BTN_A, // OCARINA_PITCH_EFLAT4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_E4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_F4 + OCARINA_BTN_C_DOWN, // OCARINA_PITCH_GFLAT4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_G4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_AFLAT4 + OCARINA_BTN_C_RIGHT, // OCARINA_PITCH_A4 + OCARINA_BTN_C_RIGHT + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_BFLAT4: Interface/Overlap between C_RIGHT and C_LEFT + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_B4 + OCARINA_BTN_C_LEFT, // OCARINA_PITCH_C5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_DFLAT5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_D5 + OCARINA_BTN_C_UP, // OCARINA_PITCH_EFLAT5 +}; + +// seqData written in the music macro language +// Only used in unused functions +u8 sCustomSequenceScript[400] = { + 0xFE, 0xFE, 0xD3, 0x20, 0xD7, 0x00, 0x01, 0xCC, 0x00, 0x70, 0x90, 0x00, 0x16, 0xDB, 0x64, 0xDD, 0x78, + 0xFE, 0x00, 0xF3, 0xFC, 0xFF, 0xC3, 0x88, 0x00, 0x29, 0x89, 0x00, 0x2B, 0xDF, 0x7F, 0xE9, 0x0F, 0xDD, + 0x37, 0xD4, 0x40, 0xC1, 0x52, 0xFE, 0x80, 0xF3, 0xFC, 0xFF, 0xC2, 0xFB, 0xC0, 0x00, 0xC1, 0x57, 0xC9, +}; + +OcarinaSongButtons gOcarinaSongButtons[OCARINA_SONG_MAX] = { + // 0: Sonata of Awakening + { + 7, + { + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + }, + }, + + // 1: Goron Lullaby + { + 8, + { + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + }, + }, + + // 2: New Wave Bossa Nova + { + 7, + { + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 3: Elegy of Emptyness + { + 7, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + }, + }, + + // 4: Oath to Order + { + 6, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_UP, + }, + }, + + // 5; Sarias Song + { + 6, + { + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + }, + }, + + // 6: Song of Time + { + 6, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + }, + }, + + // 7: Song of Healing + { + 6, + { + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + }, + }, + + // 8: Eponas Song + { + 6, + { + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 9: Song of Soaring + { + 6, + { + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + }, + }, + + // 10: Song of Storms + { + 6, + { + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_UP, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_UP, + }, + }, + + // 11: Suns Song + { + 6, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_UP, + }, + }, + + // 12: Inverted Song of Time + { + 6, + { + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 13; Song of Double Time + { + 6, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_DOWN, + }, + }, + + // 14: Goron Lullaby Intro + { + 6, + { + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + }, + }, + + // 15: Milk Bar Jam "Ballad of the Wind Fish" Human + { + 4, + { + OCARINA_BTN_C_UP, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 16: Milk Bar Jam "Ballad of the Wind Fish" Goron + { + 8, + { + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 17: Milk Bar Jam "Ballad of the Wind Fish" Zora + { + 8, + { + OCARINA_BTN_C_UP, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + }, + }, + + // 18: Milk Bar Jam "Ballad of the Wind Fish" Deku + { + 5, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 19: Evan HP (Zora Band Leader) Song Part 1 + { + 8, + { + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_A, + }, + }, + + // 20: Evan HP (Zora Band Leader) Song Part 2 + { + 8, + { + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_DOWN, + }, + }, + + // 21: Zeldas Lullaby + { + 6, + { + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_RIGHT, + }, + }, + + // 22: Scarecrow + { + 8, + { + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + OCARINA_BTN_A, + }, + }, + + // 23: Termina Field 2D Song Buttons Appearing on Wall (In OoT, this is Ocarina Memory Game) + { + 8, + { + OCARINA_BTN_A, + OCARINA_BTN_C_DOWN, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_UP, + OCARINA_BTN_C_LEFT, + OCARINA_BTN_C_RIGHT, + OCARINA_BTN_C_DOWN, + }, + }, +}; + +// Static In-Function Data +u8 sScarecrowAfterCreditsState = 0; +u8 sScarecrowAfterCreditsIntrumentId = OCARINA_INSTRUMENT_DEFAULT; +u16 sScarecrowAfterCreditsTimer = 1200; +u8 sRequestCustomSequence = false; +s8 D_801D8B30[] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, + 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, 105, 107, 109, 111, 113, 115, 117, 119, 121, 123, 125, 127, +}; +f32 sBigBellsVolume[8] = { + 1.0f, 0.9f, 0.8f, 0.7f, 0.6f, 0.5f, 0.4f, 0.3f, +}; +u8 sBgmPlayers[2] = { SEQ_PLAYER_BGM_MAIN, SEQ_PLAYER_BGM_SUB }; +f32 sSfxOriginalPos[] = { 0.0f, 0.0f, 0.0f }; + +// OoT's soundEffects from EnRiverSound +const u16 gAudioEnvironmentalSfx[] = { + NA_SE_EV_RIVER_STREAM - SFX_FLAG, NA_SE_EV_WAVE - SFX_FLAG, + NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, NA_SE_EV_WATER_WALL - SFX_FLAG, + NA_SE_EV_MAGMA_LEVEL - SFX_FLAG, NA_SE_EV_MAGMA_LEVEL_M - SFX_FLAG, + NA_SE_EV_MAGMA_LEVEL_L - SFX_FLAG, NA_SE_EV_TORCH - SFX_FLAG, + NA_SE_EV_FOUNTAIN - SFX_FLAG, NA_SE_EV_DRAIN - SFX_FLAG, + NA_SE_EV_CROWD - SFX_FLAG, NA_SE_EV_WATER_CONVECTION - SFX_FLAG, + NA_SE_EV_GORON_CHEER - SFX_FLAG, NA_SE_EV_WATER_WALL_BIG_SILENT - SFX_FLAG, + NA_SE_EV_WATER_BUBBLE - SFX_FLAG, NA_SE_EV_COW_CRY_LV - SFX_FLAG, + NA_SE_EV_MAKE_TURRET - SFX_FLAG, NA_SE_EV_BOILED_WATER_S - SFX_FLAG, + NA_SE_EV_BOILED_WATER_L - SFX_FLAG, NA_SE_EV_WAVE_S - SFX_FLAG, + NA_SE_EV_WAVE_S - SFX_FLAG, NA_SE_EV_WAVE_S - SFX_FLAG, +}; + +extern const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX]; +/** +const u8 sIsOcarinaSongReserved[OCARINA_SONG_MAX] = { + true, // OCARINA_SONG_SONATA + true, // OCARINA_SONG_GORON_LULLABY + true, // OCARINA_SONG_NEW_WAVE + true, // OCARINA_SONG_ELEGY + true, // OCARINA_SONG_OATH + false, // OCARINA_SONG_SARIAS + true, // OCARINA_SONG_TIME + true, // OCARINA_SONG_HEALING + true, // OCARINA_SONG_EPONAS + true, // OCARINA_SONG_SOARING + true, // OCARINA_SONG_STORMS + false, // OCARINA_SONG_SUNS + true, // OCARINA_SONG_INVERTED_TIME + true, // OCARINA_SONG_DOUBLE_TIME + true, // OCARINA_SONG_GORON_LULLABY_INTRO + false, // OCARINA_SONG_WIND_FISH_HUMAN + false, // OCARINA_SONG_WIND_FISH_GORON + false, // OCARINA_SONG_WIND_FISH_ZORA + false, // OCARINA_SONG_WIND_FISH_DEKU + true, // OCARINA_SONG_EVAN_PART1 + true, // OCARINA_SONG_EVAN_PART2 + false, // OCARINA_SONG_ZELDAS_LULLABY + true, // OCARINA_SONG_SCARECROW + false, // OCARINA_SONG_TERMINA_WALL +}; +*/ + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF00.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AFE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B02C.s") + +void AudioOcarina_MapSongFromNotesToButtons(u8 noteSongIndex, u8 buttonSongIndex, u8 numButtons); +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_MapSongFromNotesToButtons.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B144.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B378.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B38C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B3D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B4B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_StartDefault.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B568.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B618.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B654.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B6B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BC44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BE98.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C268.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C2E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_SetInstrumentId.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C398.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C5A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C8D8.s") + +const char sAudioOcarinaUnusedText0[] = "key step is too long !!! %d:%d>%d\n"; +const char sAudioOcarinaUnusedText1[] = "You played %d Melody !!! (last step:%d)\n"; +const char sAudioOcarinaUnusedText2[] = "pass 0\n"; +const char sAudioOcarinaUnusedText3[] = "pass 1\n"; +const char sAudioOcarinaUnusedText4[] = "pass 2\n"; +const char sAudioOcarinaUnusedText5[] = "last key is bad !!! %d %d %02X %02X\n"; +const char sAudioOcarinaUnusedText6[] = "last key step is too short !!! %d:%d %d<%d\n"; +const char sAudioOcarinaUnusedText7[] = "check is over!!! %d %d %d\n"; + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CD08.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE34.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE6C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CEBC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF6C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF78.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/AudioOcarina_GetPlaybackStaff.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CFA8.s") + +/** + * Tests to see if the notes from songIndex contain identical notes + * within its song to any of the reserved songIndex from 0 up to maxSongIndex + */ +s32 AudioOcarina_TerminaWallValidateNotes(u8 songIndex, u8 maxSongIndex) { + u8 curSongIndex; + u8 j; + u8 k; + + // loop through all possible songs up to maxSongIndex + for (curSongIndex = 0; curSongIndex < maxSongIndex; curSongIndex++) { + // check to see if the song is reserved or not + if (sIsOcarinaSongReserved[curSongIndex]) { + // starting index to test the song + for (j = 0; j < (9 - gOcarinaSongButtons[curSongIndex].numButtons); j++) { + // loop through each note in the song + for (k = 0; (k < gOcarinaSongButtons[curSongIndex].numButtons) && ((k + j) < 8) && + (gOcarinaSongButtons[curSongIndex].buttonIndex[k] == + gOcarinaSongButtons[songIndex].buttonIndex[(k + j)]); + k++) { + continue; + } + + if (k == gOcarinaSongButtons[curSongIndex].numButtons) { + // failure: songIndex is identical to curSongIndex. + return -1; + } + } + } + } + + // success: notes are accepted and used + return 0; +} + +/** + * Generates the notes displayed on the Termina Field wall of musical notes + * Song generation loop alternates between 8 random notes and a random song from Ocarina of Time (OoT). + * Will check to see that the notes are valid by ensuring no playable song is within the selected notes + * All OoT songs are valid, so the outer loop will run a maxiumum of two times. + * i.e. if random notes fails, then the next set of notes will be from a valid OoT song + */ +void AudioOcarina_TerminaWallGenerateNotes(void) { + OcarinaNote* ocarinaNote; + u8 randButtonIndex; + u8 i; + u8 j; + + do { + i = 0; + if (sOcarinaWallCounter++ % 2) { + j = 0; + + for (; i < 8; i++) { + randButtonIndex = Audio_NextRandom() % ARRAY_COUNT(sButtonToPitchMap); + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = sButtonToPitchMap[randButtonIndex]; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 19; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 80; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; + j++; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].length = 3; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].volume = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j].bend = 0; + j++; + } + + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 2].length = 90; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j - 1].length = 22; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][j + 1].length = 0; + AudioOcarina_MapSongFromNotesToButtons(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, 8); + } else { + j = Audio_NextRandom() % ARRAY_COUNT(sOoTOcarinaSongNotes); + ocarinaNote = sOoTOcarinaSongNotes[j]; + + for (; ocarinaNote[i].length != 0; i++) { + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i] = ocarinaNote[i]; + } + + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_TERMINA_WALL][i].length = 0; + AudioOcarina_MapSongFromNotesToButtons(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL, + sOoTOcarinaSongsNumNotes[j]); + } + } while (AudioOcarina_TerminaWallValidateNotes(OCARINA_SONG_TERMINA_WALL, OCARINA_SONG_TERMINA_WALL) != 0); +} + +/** + * Unused remnant of OoT + */ +void AudioOcarina_MemoryGameSetNumNotes(u8 minigameRound) { + u8 i; + + if (minigameRound > 2) { + minigameRound = 2; + } + + sOcarinaMemoryGameAppendPos = 0; + sOcaMemoryGameEndPos = sOcaMemoryGameNumNotes[minigameRound]; + + for (i = 0; i < 3; i++) { + AudioOcarina_MemoryGameGenerateNotes(); + } +} + +/** + * Unused remnant of OoT, Id 14 now represent Goron Lullaby Intro instead of the OoT ocarina memory game + * //! @bug calling this function in MM will overwrite Goron Lullaby Intro + */ +#define OCARINA_SONG_MEMORYGAME 14 +s32 AudioOcarina_MemoryGameGenerateNotes(void) { + u32 randButtonIndex; + u8 randPitch; + + if (sOcarinaMemoryGameAppendPos == sOcaMemoryGameEndPos) { + return true; + } + + randButtonIndex = Audio_NextRandom(); + randPitch = sButtonToPitchMap[randButtonIndex % ARRAY_COUNT(sButtonToPitchMap)]; + + if (sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos - 1].pitch == randPitch) { + randPitch = sButtonToPitchMap[(randButtonIndex + 1) % ARRAY_COUNT(sButtonToPitchMap)]; + } + + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].pitch = randPitch; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].length = 45; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].volume = 0x50; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].vibrato = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].bend = 0; + + sOcarinaMemoryGameAppendPos++; + + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos].length = 0; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos + 1].pitch = OCARINA_PITCH_NONE; + sOcarinaSongNotes[OCARINA_SONG_MEMORYGAME][sOcarinaMemoryGameAppendPos + 1].length = 0; + if (1) {} + return false; +} +#undef OCARINA_SONG_MEMORYGAME + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D600.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D758.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D864.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF64.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DFF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E000.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E00C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E014.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E0FC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E104.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E110.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E14C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E324.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E4B0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E634.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E864.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EA40.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EB2C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F024.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F05C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/play_sound.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F128.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F170.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PlaySfxAtPos.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F208.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F230.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F258.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F300.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F420.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F4AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F540.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F570.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F5AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F638.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F780.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F7D8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F830.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F88C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F900.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FA18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FAD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FB0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FC20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FCB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FD90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FDC8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE1C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE74.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FEDC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FF38.s") + +/** + * Used for EnRiverSound + */ +void Audio_PlaySfxForRiver(Vec3f* pos, f32 freqScale) { + if (!Audio_IsSfxPlaying(NA_SE_EV_RIVER_STREAM - SFX_FLAG)) { + sRiverFreqScaleLerp.value = freqScale; + } else if (freqScale != sRiverFreqScaleLerp.value) { + sRiverFreqScaleLerp.target = freqScale; + sRiverFreqScaleLerp.remainingFrames = 40; + sRiverFreqScaleLerp.step = (sRiverFreqScaleLerp.target - sRiverFreqScaleLerp.value) / 40; + } + Audio_PlaySfxGeneral(NA_SE_EV_RIVER_STREAM - SFX_FLAG, pos, 4, &sRiverFreqScaleLerp.value, &D_801DB4B0, + &D_801DB4B8); +} + +/** + * Unused remnant of OoT's EnRiverSound + * Used for Zora's River Waterfall + */ +void Audio_PlaySfxForWaterfall(Vec3f* pos, f32 freqScale) { + if (!Audio_IsSfxPlaying(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG)) { + sWaterfallFreqScaleLerp.value = freqScale; + } else if (freqScale != sWaterfallFreqScaleLerp.value) { + sWaterfallFreqScaleLerp.target = freqScale; + sWaterfallFreqScaleLerp.remainingFrames = 40; + sWaterfallFreqScaleLerp.step = (sWaterfallFreqScaleLerp.target - sWaterfallFreqScaleLerp.value) / 40; + } + Audio_PlaySfxGeneral(NA_SE_EV_WATER_WALL_BIG - SFX_FLAG, pos, 4, &sWaterfallFreqScaleLerp.value, + &sWaterfallFreqScaleLerp.value, &D_801DB4B8); +} + +/** + * Used for EnRiverSound variables + */ +void Audio_StepFreqLerp(FreqLerp* lerp) { + if (lerp->remainingFrames != 0) { + lerp->remainingFrames--; + if (lerp->remainingFrames != 0) { + lerp->value += lerp->step; + } else { + lerp->value = lerp->target; + } + } +} + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0124.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0184.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A01C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0204.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0238.s") + +/** + * Unused remnant from OoT's EnRiverSound + * Was designed to incrementally increase volume of NA_BGM_GANON_TOWER for each new room during the climb of Ganon's + * Tower + */ +void Audio_SetGanonsTowerBgmVolumeLevel(u8 ganonsTowerLevel) { + u8 channelIndex; + s8 pan = 0; + + // Ganondorfs's Lair + if (ganonsTowerLevel == 0) { + pan = 0x7F; + } + + for (channelIndex = 0; channelIndex < 16; channelIndex++) { + // CHAN_UPD_PAN_UNSIGNED + Audio_QueueCmdS8(((u8)(u32)channelIndex << 8) | 0x7000000, pan); + } + + // Lowest room in Ganon's Tower (Entrance Room) + if (ganonsTowerLevel == 7) { + // Adds a delay to setting the volume in the first room + sEnterGanonsTowerTimer = 2; + } else { + Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[ganonsTowerLevel % ARRAY_COUNTU(sGanonsTowerLevelsVol)]); + } +} + +/** + * Unused remnant from OoT's EnRiverSound + * If a new volume is requested for ganon's tower, update the volume and + * calculate a new low-pass filter cutoff and reverb based on the new volume + */ +s32 Audio_SetGanonsTowerBgmVolume(u8 targetVolume) { + u8 lowPassFilterCutoff; + u8 channelIndex; + u16 reverb; + + if (sGanonsTowerVol != targetVolume) { + // Sets the volume + Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, targetVolume, 2); + + // Sets the filter cutoff of the form (lowPassFilterCutoff << 4) | (highPassFilter & 0xF). highPassFilter is + // always set to 0 + if (targetVolume < 0x40) { + // Only the first room + lowPassFilterCutoff = 0x10; + } else { + // Higher volume leads to a higher cut-off frequency in the low-pass filtering + lowPassFilterCutoff = (((targetVolume - 0x40) >> 2) + 1) << 4; + } + + Audio_QueueSeqCmd((8 << 28) | ((u8)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u8)(4) << 16) | ((u8)(15) << 8) | + (u8)(lowPassFilterCutoff)); + + // Sets the reverb + for (channelIndex = 0; channelIndex < ARRAY_COUNT(gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels); + channelIndex++) { + if (&gAudioContext.sequenceChannelNone != + gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]) { + // soundScriptIO[5] was set to 0x40 in channels 0, 1, and 4 (BGM no longer in OoT) + if ((u8)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]->soundScriptIO[5] != + 0xFF) { + // Higher volume leads to lower reverb + reverb = + (((u16)gAudioContext.seqPlayers[SEQ_PLAYER_BGM_MAIN].channels[channelIndex]->soundScriptIO[5] - + targetVolume) + + 0x7F); + + if (reverb > 0x7F) { + reverb = 0x7F; + } + + // CHAN_UPD_REVERB + Audio_QueueCmdS8(_SHIFTL(5, 24, 8) | _SHIFTL(SEQ_PLAYER_BGM_MAIN, 16, 8) | + _SHIFTL(channelIndex, 8, 8), + (u8)reverb); + } + } + } + + sGanonsTowerVol = targetVolume; + } + return -1; +} + +/** + * Unused remnant from OoT's EnRiverSound + * Responsible for lowering market bgm in Child Market Entrance and Child Market Back Alley + * Only lowers volume for 1 frame, so must be called every frame to maintain lower volume + */ +void Audio_LowerMainBgmVolume(u8 volume) { + sRiverSoundMainBgmVol = volume; + sRiverSoundMainBgmLower = true; +} + +/** + * Unused remnant from OoT's EnRiverSound + * Still called by Audio_Update every frame, but none of these processes get initialized + */ +void Audio_UpdateRiverSoundVolumes(void) { + // Updates Main Bgm Volume (RiverSound of type RS_LOWER_MAIN_BGM_VOLUME) + if (sRiverSoundMainBgmLower == true) { + if (sRiverSoundMainBgmCurrentVol != sRiverSoundMainBgmVol) { + // lowers the volume for 1 frame + Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, sRiverSoundMainBgmVol, 10); + sRiverSoundMainBgmCurrentVol = sRiverSoundMainBgmVol; + sRiverSoundMainBgmRestore = true; + } + sRiverSoundMainBgmLower = false; + } else if ((sRiverSoundMainBgmRestore == true) && !sAudioIsWindowOpen) { + // restores the volume every frame + Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 0, 0x7F, 10); + sRiverSoundMainBgmCurrentVol = 0x7F; + sRiverSoundMainBgmRestore = false; + } + + // Update Ganon's Tower Volume (RiverSound of type RS_GANON_TOWER_7) + if (sEnterGanonsTowerTimer != 0) { + sEnterGanonsTowerTimer--; + if (sEnterGanonsTowerTimer == 0) { + Audio_SetGanonsTowerBgmVolume(sGanonsTowerLevelsVol[7]); + } + } +} + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0554.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0654.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0810.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0868.s") + +/** + * Unused remnant of OoT's EnRiverSound (func_800F4E30) + */ +void func_801A09D4(Vec3f* pos, f32 xzDistToPlayer) { + f32 volumeRel; + s8 pan; + u8 channelIndex; + + if (sRiverSoundBgmPos == NULL) { + sRiverSoundBgmPos = pos; + sRiverSoundXZDistToPlayer = xzDistToPlayer; + } else if (sRiverSoundBgmPos != pos) { + if (sRiverSoundXZDistToPlayer > xzDistToPlayer) { + sRiverSoundBgmPos = pos; + sRiverSoundXZDistToPlayer = xzDistToPlayer; + } + } else { + sRiverSoundXZDistToPlayer = xzDistToPlayer; + } + + if (sRiverSoundBgmPos->x > 100.0f) { + pan = 0x7F; + } else if (sRiverSoundBgmPos->x < -100.0f) { + pan = 0; + } else { + pan = ((sRiverSoundBgmPos->x / 100.0f) * 64.0f) + 64.0f; + } + + if (sRiverSoundXZDistToPlayer > 400.0f) { + volumeRel = 0.1f; + } else if (sRiverSoundXZDistToPlayer < 120.0f) { + volumeRel = 1.0f; + } else { + volumeRel = ((1.0f - ((sRiverSoundXZDistToPlayer - 120.0f) / 280.0f)) * 0.9f) + 0.1f; + } + + for (channelIndex = 0; channelIndex < 16; channelIndex++) { + if (channelIndex != 9) { + Audio_QueueSeqCmd(((u32)(6) << 28) | ((u32)(SEQ_PLAYER_BGM_MAIN) << 24) | ((u32)(2) << 16) | + ((u32)(channelIndex) << 8) | ((u8)(127.0f * volumeRel))); + Audio_QueueCmdS8(0x03000000 | ((u8)((u32)channelIndex) << 8), pan); + } + } +} + +/** + * Unused remnant of OoT's EnRiverSound + */ +void Audio_ClearSariaBgm(void) { + if (sRiverSoundBgmPos != NULL) { + sRiverSoundBgmPos = NULL; + } +} + +/** + * Unused remnant of OoT's EnRiverSound + */ +void Audio_ClearSariaBgmAtPos(Vec3f* pos) { + if (sRiverSoundBgmPos == pos) { + sRiverSoundBgmPos = NULL; + } +} + +void Audio_SplitBgmChannels(s8 volumeSplit); +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0E44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1290.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1348.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A13BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A153C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A17F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1904.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A8C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1D44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1DB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1E0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F00.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F88.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1FB4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2090.s") + +/** + * Unused remnant of OoT's EnRiverSound + */ +void Audio_PlaySariaBgm(Vec3f* pos, u16 seqId, u16 distMax) { + f32 absY; + f32 dist; + u8 targetVolume; + f32 prevDist; + + if (sRiverSoundBgmTimer != 0) { + sRiverSoundBgmTimer--; + return; + } + + dist = sqrtf(SQ(pos->z) + (SQ(pos->x) + SQ(pos->y))); + + if (sRiverSoundBgmPos == NULL) { + sRiverSoundBgmPos = pos; + func_801A3238(SEQ_PLAYER_BGM_SUB, seqId, 0, 7, 2); + } else { + prevDist = sqrtf(SQ(sRiverSoundBgmPos->z) + SQ(sRiverSoundBgmPos->x)); + if (dist < prevDist) { + sRiverSoundBgmPos = pos; + } else { + dist = prevDist; + } + } + + absY = ABS_ALT(pos->y); + + if ((distMax / 15.0f) < absY) { + targetVolume = 0; + } else if (dist < distMax) { + targetVolume = (1.0f - (dist / distMax)) * 127.0f; + } else { + targetVolume = 0; + } + + if (seqId != NA_BGM_FAIRY_FOUNTAIN) { + Audio_SplitBgmChannels(targetVolume); + } + + Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, 3, targetVolume, 0); + Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, 3, 0x7F - targetVolume, 0); +} + +/** + * Unused remnant of OoT's EnRiverSound + */ +void Audio_ClearSariaBgm2(void) { + sRiverSoundBgmPos = NULL; +} + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A246C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2544.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A257C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A25E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2670.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2778.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A27E8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A281C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A29D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2BB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C88.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2D54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_IsSequencePlaying.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2E54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2ED8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2F88.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2FC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3000.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3038.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3098.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A312C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A31EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3238.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A32CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3590.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A36F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3950.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A39F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3A7C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B48.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D98.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3E38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3EC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_SetCutsceneFlag.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F6C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FB4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/audio_setBGM.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4058.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41C8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A429C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A42C8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4324.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4348.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4380.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4428.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PreNMI.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A44C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A44D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A46F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4748.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A479C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A47DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A48E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4A28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4B80.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D00.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DA4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4E64.s") diff --git a/src/code/audio/code_801A4EB0.c b/src/code/audio/code_801A4EB0.c new file mode 100644 index 000000000..d3461c8f5 --- /dev/null +++ b/src/code/audio/code_801A4EB0.c @@ -0,0 +1,17 @@ +#include "global.h" + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4EB0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4EB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A4FD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5080.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A50C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5100.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A510C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A4EB0/func_801A5118.s") diff --git a/src/code/code_801A51F0.c b/src/code/audio/code_801A51F0.c similarity index 100% rename from src/code/code_801A51F0.c rename to src/code/audio/code_801A51F0.c diff --git a/src/code/code_801A5BD0.c b/src/code/audio/code_801A5BD0.c similarity index 85% rename from src/code/code_801A5BD0.c rename to src/code/audio/code_801A5BD0.c index 32889dcb8..8397fd52e 100644 --- a/src/code/code_801A5BD0.c +++ b/src/code/audio/code_801A5BD0.c @@ -6,7 +6,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5C8C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5CFC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_PlaySfxGeneral.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A5DDC.s") @@ -24,7 +24,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7284.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A72CC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_StopSfxByPos.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A7328.s") @@ -40,6 +40,6 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A787C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A78E4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/Audio_IsSfxPlaying.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A5BD0/func_801A794C.s") diff --git a/src/code/code_801A7B10.c b/src/code/audio/code_801A7B10.c similarity index 61% rename from src/code/code_801A7B10.c rename to src/code/audio/code_801A7B10.c index 707996820..6d3faaeab 100644 --- a/src/code/code_801A7B10.c +++ b/src/code/audio/code_801A7B10.c @@ -18,7 +18,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8B2C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8BD0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/Audio_SetVolumeScale.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A8D5C.s") @@ -29,19 +29,3 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A99B8.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9A74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9B10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9B78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9BFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9C68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9D10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9DCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9EA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801A7B10/func_801A9F4C.s") diff --git a/src/code/audioMgr.c b/src/code/audioMgr.c index dcf540483..ee6014137 100644 --- a/src/code/audioMgr.c +++ b/src/code/audioMgr.c @@ -79,7 +79,7 @@ void AudioMgr_ThreadEntry(void* arg) { s32 exit; func_801A4C30(); - func_80190B38(DmaMgr_DmaCallback0); + AudioLoad_SetDmaHandler(DmaMgr_DmaHandler); func_801A4D00(); osSendMesg(&audioMgr->lockMsgQ, NULL, OS_MESG_BLOCK); IrqMgr_AddClient(audioMgr->irqMgr, &irqClient, &audioMgr->interruptMsgQ); diff --git a/src/code/audio_effects.c b/src/code/audio_effects.c deleted file mode 100644 index e795d5e9f..000000000 --- a/src/code/audio_effects.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196A00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196BC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196D20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196D7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196DB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80196FEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197048.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197138.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197164.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_effects/func_80197188.s") diff --git a/src/code/audio_heap.c b/src/code/audio_heap.c deleted file mode 100644 index 7c43ef0f1..000000000 --- a/src/code/audio_heap.c +++ /dev/null @@ -1,111 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B0F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B10C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B250.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B318.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B3FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B474.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B4F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B520.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B578.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B5D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B608.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B640.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B69C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B6E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B740.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B768.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B77C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B7AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B7BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B8FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B95C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018B9E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018BA64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018BB28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018BBEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C380.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C3D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C4E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C8B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C8E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C93C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018C994.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CB70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CB78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CC3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CCA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018CFAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D57C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D5D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D658.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D6C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018D760.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DA50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DBC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DCB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DCF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DD98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DDD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DF24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018DFE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E00C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E03C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E2A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E344.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_heap/func_8018E8C8.s") diff --git a/src/code/audio_load.c b/src/code/audio_load.c deleted file mode 100644 index 15e54b3c5..000000000 --- a/src/code/audio_load.c +++ /dev/null @@ -1,161 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018EB60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018EC4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/D_801E030C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018EF88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F220.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F298.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F310.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F388.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F3B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F3E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F448.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F478.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F4D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F588.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F604.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F6F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F7C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F7F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F83C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F880.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F8C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F908.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018F9B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FA60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FAD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FB20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FB78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FCCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FD20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FD40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FE5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8018FF60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190204.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190240.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190294.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801902D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190544.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190668.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019067C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190754.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019075C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019077C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190B38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190B44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190B50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190BB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190F50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80190F64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191134.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801911C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801911CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191240.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801913C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019144C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191568.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191598.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019161C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191740.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191864.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191870.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801919AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191B40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191BD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191C40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191C54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80191D94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_8019218C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192340.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192388.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_801924BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192514.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192990.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192AD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192AD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192AE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192AE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192B54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_load/func_80192BAC.s") diff --git a/src/code/audio_playback.c b/src/code/audio_playback.c deleted file mode 100644 index ec8dd86b8..000000000 --- a/src/code/audio_playback.c +++ /dev/null @@ -1,63 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80194930.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80194DB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80194E60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80194F20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80194F84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801954CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195508.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801955DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801956C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801957B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801958F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195C40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195C60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195C80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195D84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195DDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195DEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195E3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80195EE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80196040.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_8019617C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801961BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801961E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80196268.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801963E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_8019641C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80196448.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_80196494.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801964F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801965F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/audio_playback/func_801968C4.s") diff --git a/src/code/code_800CB000.c b/src/code/code_800CB000.c deleted file mode 100644 index 7642d35c4..000000000 --- a/src/code/code_800CB000.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800CB000/func_800CB000.s") diff --git a/src/code/code_800E8EA0.c b/src/code/code_800E8EA0.c index 754b8759d..d95f53269 100644 --- a/src/code/code_800E8EA0.c +++ b/src/code/code_800E8EA0.c @@ -57,15 +57,13 @@ s32 func_800E9138(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* Player* player = GET_PLAYER(globalCtx); s16 sVar3; Vec3f local_14; - s16 sVar3A; actor->focus.pos = actor->world.pos; actor->focus.pos.y += param_5; if (((globalCtx->csCtx).state == 0) && (D_801D0D50 == 0)) { - sVar3 = actor->yawTowardsPlayer - actor->shape.rot.y; - sVar3A = ABS_ALT(sVar3); - if (sVar3A >= 0x4300) { + sVar3 = ABS_ALT(BINANG_SUB(actor->yawTowardsPlayer, actor->shape.rot.y)); + if (sVar3 >= 0x4300) { func_800E8F08(param_3, param_4); return 0; } @@ -86,14 +84,12 @@ s32 func_800E9250(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* Player* player = GET_PLAYER(globalCtx); s16 sVar3; Vec3f local_14; - s16 sVar3A; actor->focus.pos = param_5; if (((globalCtx->csCtx).state == 0) && (D_801D0D50 == 0)) { - sVar3 = actor->yawTowardsPlayer - actor->shape.rot.y; - sVar3A = ABS_ALT(sVar3); - if (sVar3A >= 0x4300) { + sVar3 = ABS_ALT(BINANG_SUB(actor->yawTowardsPlayer, actor->shape.rot.y)); + if (sVar3 >= 0x4300) { func_800E8F08(param_3, param_4); return 0; } diff --git a/src/code/code_800F0390.c b/src/code/code_800F0390.c deleted file mode 100644 index f495cfe5e..000000000 --- a/src/code/code_800F0390.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F0390.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F03C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F048C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/Audio_PlaySoundAtPosition.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F0390/func_800F0590.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_800F12D0.c b/src/code/code_800F12D0.c deleted file mode 100644 index d34f11e81..000000000 --- a/src/code/code_800F12D0.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F12D0/func_800F12D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F12D0/func_800F1304.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F12D0/func_800F1374.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F12D0/func_800F13E8.s") diff --git a/src/code/code_8010C1B0.c b/src/code/code_8010C1B0.c index 12e0eadb4..2c1fd410f 100644 --- a/src/code/code_8010C1B0.c +++ b/src/code/code_8010C1B0.c @@ -1,7 +1,7 @@ #include "global.h" // Blocks the current thread until all currently queued scheduler tasks have been completed -void func_8010C1B0(void) { +void MsgEvent_SendNullTask(void) { OSScTask task; OSMesgQueue queue; OSMesg msg; diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index 084e91872..5dee17fb5 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -1,6 +1,7 @@ #include "global.h" +#include "interface/parameter_static/parameter_static.h" -// Bit Flag array in which gBitFlags[n] is literally (1 << n) +// Bit Flag array in which gBitFlags[n] is (1 << n) u32 gBitFlags[] = { (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), @@ -8,61 +9,359 @@ u32 gBitFlags[] = { (1 << 24), (1 << 25), (1 << 26), (1 << 27), (1 << 28), (1 << 29), (1 << 30), (1 << 31), }; -u16 gEquipMasks[] = { 0x000F, 0x00F0, 0x0F00, 0xF000 }; -u16 gEquipNegMasks[] = { 0xFFF0, 0xFF0F, 0xF0FF, 0x0FFF }; +// four-bit masks +u16 gEquipMasks[] = { + 0xF << 0, // Sword + 0xF << 4, // Shield + 0xF << 8, // Unused (Tunic) + 0xF << 12, // Unused (Boots) +}; + +// four-bit masks +u16 gEquipNegMasks[] = { + ~(0xF << 0), // Sword + ~(0xF << 4), // Shield + ~(0xF << 8), // Unused (Tunic) + (u16) ~(0xF << 12), // Unused (Boots) +}; + +// 3 = two bit masks +// 7 = three bit masks u32 gUpgradeMasks[] = { - 0x00000007, 0x00000038, 0x000001C0, 0x00000E00, 0x00003000, 0x0001C000, 0x000E0000, 0x00700000, + 7 << 0, // Quivers + 7 << 3, // Bomb Bags + 7 << 6, // Unused (Strength) + 7 << 9, // Unused (Scale) + 3 << 12, // Wallets + 7 << 14, // Unused (Deku Seed Bullet Bags) + 7 << 17, // Unused (Deku Stick) + 7 << 20, // Unused (Deku Nut) }; + +// 3 = two-bit masks +// 7 = three-bit masks u32 gUpgradeNegMasks[] = { - 0xFFFFFFF8, 0xFFFFFFC7, 0xFFFFFE3F, 0xFFFFF1FF, 0xFFFFCFFF, 0xFFFE3FFF, 0xFFF1FFFF, 0xFF8FFFFF, + ~(7 << 0), // Quivers + ~(7 << 3), // Bomb Bags + ~(7 << 6), // Unused (Strength) + ~(7 << 9), // Unused (Scale) + ~(3 << 12), // Wallets + ~(7 << 14), // Unused (Deku Seed Bullet Bags) + ~(7 << 17), // Unused (Deku Stick) + ~(7 << 20), // Unused (Deku Nut) +}; + +u8 gEquipShifts[] = { + 0, // Sword + 4, // Shield + 8, // Unused (Tunic) + 12, // Unused (Boots) +}; + +u8 gUpgradeShifts[] = { + 0, // Quivers + 3, // Bomb Bags + 6, // Unused (Strength) + 9, // Unused (Scale) + 12, // Wallets + 14, // Unused (Deku Seed Bullet Bags) + 17, // Unused (Deku Stick) + 20, // Unused (Deku Nut) }; -u8 gEquipShifts[] = { 0, 4, 8, 12 }; -u8 gUpgradeShifts[] = { 0, 3, 6, 9, 12, 14, 17, 20, 0, 0, 0, 30, 0, 40, 0, 50 }; u16 gUpgradeCapacities[][4] = { - { 0, 20, 30, 40 }, // Bomb Bags - { 0, 0, 0, 0 }, // Unused (Scale) - { 0, 0, 0, 0 }, // Unused (Strength) - { 99, 200, 500, 500 }, // Wallets { 0, 30, 40, 50 }, // Quivers + { 0, 20, 30, 40 }, // Bomb Bags + { 0, 0, 0, 0 }, // Unused (Strength) + { 0, 0, 0, 0 }, // Unused (Scale) + { 99, 200, 500, 500 }, // Wallets + { 0, 30, 40, 50 }, // Unused (Deku Seed Bullet Bags) { 0, 10, 20, 30 }, // Unused (Deku Stick) { 0, 20, 30, 40 }, // Unused (Deku Nut) }; -u32 gGsFlagsMask[] = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }; -u32 gGsFlagsShift[] = { 0, 8, 16, 24 }; +// eight-bit masks +u32 gGsFlagsMask[] = { + 0xFF << 0, + 0xFF << 8, + 0xFF << 16, + 0xFF << 24, +}; + +u32 gGsFlagsShift[] = { + 0, + 8, + 16, + 24, +}; // TODO: use symbols for these icon textures once textures are properly in C void* gItemIcons[] = { - 0x08000000, 0x08001000, 0x08002000, 0x08003000, 0x08004000, 0x08005000, 0x08006000, 0x08007000, 0x08008000, - 0x08009000, 0x0800A000, 0x0800B000, 0x0800C000, 0x0800D000, 0x0800E000, 0x0800F000, 0x08010000, 0x08011000, - 0x08012000, 0x08013000, 0x08014000, 0x08015000, 0x08016000, 0x08017000, 0x08018000, 0x08019000, 0x0801A000, - 0x0801B000, 0x0801C000, 0x0801D000, 0x0801E000, 0x0801F000, 0x08020000, 0x08021000, 0x08022000, 0x08023000, - 0x08024000, 0x08025000, 0x08026000, 0x08027000, 0x08028000, 0x08029000, 0x0802A000, 0x0802B000, 0x0802C000, - 0x0802D000, 0x0802E000, 0x0802F000, 0x08030000, 0x08031000, 0x08032000, 0x08033000, 0x08034000, 0x08035000, - 0x08036000, 0x08037000, 0x08038000, 0x08039000, 0x0803A000, 0x0803B000, 0x0803C000, 0x0803D000, 0x0803E000, - 0x0803F000, 0x08040000, 0x08041000, 0x08042000, 0x08043000, 0x08044000, 0x08045000, 0x08046000, 0x08047000, - 0x08048000, 0x08049000, 0x0804A000, 0x0804B000, 0x0804C000, 0x0804D000, 0x0804E000, 0x0804F000, 0x08050000, - 0x08051000, 0x08052000, 0x08053000, 0x08054000, 0x08055000, 0x08056000, 0x08057000, 0x08058000, 0x08059000, - 0x0805A000, 0x0805B000, 0x0805C000, 0x0805D000, 0x0805E000, 0x0805F000, 0x08060000, 0x08062000, 0x08062000, - 0x08062000, 0x08062000, 0x08062000, 0x08062000, 0x08062000, 0x08062000, 0x08062000, 0x08062000, 0x08062000, - 0x08062000, 0x08061000, 0x09000000, 0x09000900, 0x09001200, 0x08062000, 0x08062000, 0x08062000, 0x09003600, - 0x09004800, 0x09003F00, 0x09005100, 0x09005A00, 0x09006300, 0x09006C00, 0x08062180, 0x08062A80, 0x08063380, - 0x020028A0, 0x020025A0, 0x020027A0, 0x020026A0, 0x020024A0, + 0x08000000, // ITEM_OCARINA + 0x08001000, // ITEM_BOW + 0x08002000, // ITEM_ARROW_FIRE + 0x08003000, // ITEM_ARROW_ICE + 0x08004000, // ITEM_ARROW_LIGHT + 0x08005000, // ITEM_OCARINA_FAIRY + 0x08006000, // ITEM_BOMB + 0x08007000, // ITEM_BOMBCHU + 0x08008000, // ITEM_STICK + 0x08009000, // ITEM_NUT + 0x0800A000, // ITEM_MAGIC_BEANS + 0x0800B000, // ITEM_SLINGSHOT + 0x0800C000, // ITEM_POWDER_KEG + 0x0800D000, // ITEM_PICTO_BOX + 0x0800E000, // ITEM_LENS + 0x0800F000, // ITEM_HOOKSHOT + 0x08010000, // ITEM_SWORD_GREAT_FAIRY + 0x08011000, // ITEM_LONGSHOT + 0x08012000, // ITEM_BOTTLE + 0x08013000, // ITEM_POTION_RED + 0x08014000, // ITEM_POTION_GREEN + 0x08015000, // ITEM_POTION_BLUE + 0x08016000, // ITEM_FAIRY + 0x08017000, // ITEM_DEKU_PRINCESS + 0x08018000, // ITEM_MILK_BOTTLE + 0x08019000, // ITEM_MILK_HALF + 0x0801A000, // ITEM_FISH + 0x0801B000, // ITEM_BUG + 0x0801C000, // ITEM_BLUE_FIRE + 0x0801D000, // ITEM_POE + 0x0801E000, // ITEM_BIG_POE + 0x0801F000, // ITEM_SPRING_WATER + 0x08020000, // ITEM_HOT_SPRING_WATER + 0x08021000, // ITEM_ZORA_EGG + 0x08022000, // ITEM_GOLD_DUST + 0x08023000, // ITEM_MUSHROOM + 0x08024000, // ITEM_SEA_HORSE + 0x08025000, // ITEM_CHATEAU + 0x08026000, // ITEM_HYLIAN_LOACH + 0x08027000, // ITEM_OBABA_DRINK + 0x08028000, // ITEM_MOON_TEAR + 0x08029000, // ITEM_DEED_LAND + 0x0802A000, // ITEM_DEED_SWAMP + 0x0802B000, // ITEM_DEED_MOUNTAIN + 0x0802C000, // ITEM_DEED_OCEAN + 0x0802D000, // ITEM_ROOM_KEY + 0x0802E000, // ITEM_LETTER_MAMA + 0x0802F000, // ITEM_LETTER_TO_KAFEI + 0x08030000, // ITEM_PENDANT_MEMORIES + 0x08031000, // ITEM_TINGLE_MAP + 0x08032000, // ITEM_MASK_DEKU + 0x08033000, // ITEM_MASK_GORON + 0x08034000, // ITEM_MASK_ZORA + 0x08035000, // ITEM_MASK_FIERCE_DEITY + 0x08036000, // ITEM_MASK_TRUTH + 0x08037000, // ITEM_MASK_KAFEIS_MASK + 0x08038000, // ITEM_MASK_ALL_NIGHT + 0x08039000, // ITEM_MASK_BUNNY + 0x0803A000, // ITEM_MASK_KEATON + 0x0803B000, // ITEM_MASK_GARO + 0x0803C000, // ITEM_MASK_ROMANI + 0x0803D000, // ITEM_MASK_CIRCUS_LEADER + 0x0803E000, // ITEM_MASK_POSTMAN + 0x0803F000, // ITEM_MASK_COUPLE + 0x08040000, // ITEM_MASK_GREAT_FAIRY + 0x08041000, // ITEM_MASK_GIBDO + 0x08042000, // ITEM_MASK_DON_GERO + 0x08043000, // ITEM_MASK_KAMARO + 0x08044000, // ITEM_MASK_CAPTAIN + 0x08045000, // ITEM_MASK_STONE + 0x08046000, // ITEM_MASK_BREMEN + 0x08047000, // ITEM_MASK_BLAST + 0x08048000, // ITEM_MASK_SCENTS + 0x08049000, // ITEM_MASK_GIANT + 0x0804A000, // ITEM_BOW_ARROW_FIRE + 0x0804B000, // ITEM_BOW_ARROW_ICE + 0x0804C000, // ITEM_BOW_ARROW_LIGHT + 0x0804D000, // ITEM_SWORD_KOKIRI + 0x0804E000, // ITEM_SWORD_RAZOR + 0x0804F000, // ITEM_SWORD_GILDED + 0x08050000, // ITEM_SWORD_DEITY + 0x08051000, // ITEM_SHIELD_HERO + 0x08052000, // ITEM_SHIELD_MIRROR + 0x08053000, // ITEM_QUIVER_30 + 0x08054000, // ITEM_QUIVER_40 + 0x08055000, // ITEM_QUIVER_50 + 0x08056000, // ITEM_BOMB_BAG_20 + 0x08057000, // ITEM_BOMB_BAG_30 + 0x08058000, // ITEM_BOMB_BAG_40 + 0x08059000, // ITEM_WALLET_DEFAULT + 0x0805A000, // ITEM_WALLET_ADULT + 0x0805B000, // ITEM_WALLET_GIANT + 0x0805C000, // ITEM_FISHING_POLE + 0x0805D000, // ITEM_REMAINS_ODOLWA + 0x0805E000, // ITEM_REMAINS_GOHT + 0x0805F000, // ITEM_REMAINS_GYORG + 0x08060000, // ITEM_REMAINS_TWINMOLD + 0x08062000, // ITEM_SONG_SONATA + 0x08062000, // ITEM_SONG_LULLABY + 0x08062000, // ITEM_SONG_NOVA + 0x08062000, // ITEM_SONG_ELEGY + 0x08062000, // ITEM_SONG_OATH + 0x08062000, // ITEM_SONG_SARIA + 0x08062000, // ITEM_SONG_TIME + 0x08062000, // ITEM_SONG_HEALING + 0x08062000, // ITEM_SONG_EPONA + 0x08062000, // ITEM_SONG_SOARING + 0x08062000, // ITEM_SONG_STORMS + 0x08062000, // ITEM_SONG_SUN + 0x08061000, // ITEM_BOMBERS_NOTEBOOK + 0x09000000, // ITEM_SKULL_TOKEN + 0x09000900, // ITEM_HEART_CONTAINER + 0x09001200, // ITEM_HEART_PIECE + 0x08062000, // + 0x08062000, // + 0x08062000, // ITEM_SONG_LULLABY_INTRO + 0x09003600, // ITEM_KEY_BOSS + 0x09004800, // ITEM_COMPASS + 0x09003F00, // ITEM_DUNGEON_MAP + 0x09005100, // ITEM_STRAY_FAIRIES + 0x09005A00, // ITEM_KEY_SMALL + 0x09006300, // ITEM_MAGIC_SMALL + 0x09006C00, // ITEM_MAGIC_LARGE + 0x08062180, // ITEM_HEART_PIECE_2 + 0x08062A80, // ITEM_INVALID_1 + 0x08063380, // ITEM_INVALID_2 + gOcarinaCUpTex, // ITEM_INVALID_3 + gOcarinaCDownTex, // ITEM_INVALID_4 + gOcarinaCLeftTex, // ITEM_INVALID_5 + gOcarinaCRightTex, // ITEM_INVALID_6 + gOcarinaATex, // ITEM_INVALID_7 }; // Used to map item IDs to inventory slots u8 gItemSlots[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x05, 0x05, 0x05, 0x05, 0x05, 0x0B, 0x0B, 0x11, - 0x11, 0x11, 0x1D, 0x23, 0x29, 0x2F, 0x28, 0x26, 0x19, 0x20, 0x1E, 0x2C, 0x24, 0x25, 0x18, 0x27, - 0x1C, 0x2B, 0x21, 0x2A, 0x2D, 0x1B, 0x1F, 0x1A, 0x22, 0x2E, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, + SLOT_OCARINA, // ITEM_OCARINA + SLOT_BOW, // ITEM_BOW + SLOT_ARROW_FIRE, // ITEM_ARROW_FIRE + SLOT_ARROW_ICE, // ITEM_ARROW_ICE + SLOT_ARROW_LIGHT, // ITEM_ARROW_LIGHT + SLOT_TRADE_DEED, // ITEM_OCARINA_FAIRY + SLOT_BOMB, // ITEM_BOMB + SLOT_BOMBCHU, // ITEM_BOMBCHU + SLOT_STICK, // ITEM_STICK + SLOT_NUT, // ITEM_NUT + SLOT_MAGIC_BEANS, // ITEM_MAGIC_BEANS + SLOT_TRADE_KEY_MAMA, // ITEM_SLINGSHOT + SLOT_POWDER_KEG, // ITEM_POWDER_KEG + SLOT_PICTO_BOX, // ITEM_PICTO_BOX + SLOT_LENS, // ITEM_LENS + SLOT_HOOKSHOT, // ITEM_HOOKSHOT + SLOT_SWORD_GREAT_FAIRY, // ITEM_SWORD_GREAT_FAIRY + SLOT_BOTTLE_1, // + SLOT_BOTTLE_1, // ITEM_BOTTLE + SLOT_BOTTLE_1, // ITEM_POTION_RED + SLOT_BOTTLE_1, // ITEM_POTION_GREEN + SLOT_BOTTLE_1, // ITEM_POTION_BLUE + SLOT_BOTTLE_1, // ITEM_FAIRY + SLOT_BOTTLE_1, // ITEM_DEKU_PRINCESS + SLOT_BOTTLE_1, // ITEM_MILK_BOTTLE + SLOT_BOTTLE_1, // ITEM_MILK_HALF + SLOT_BOTTLE_1, // ITEM_FISH + SLOT_BOTTLE_1, // ITEM_BUG + SLOT_BOTTLE_1, // ITEM_BLUE_FIRE + SLOT_BOTTLE_1, // ITEM_POE + SLOT_BOTTLE_1, // ITEM_BIG_POE + SLOT_BOTTLE_1, // ITEM_SPRING_WATER + SLOT_BOTTLE_1, // ITEM_HOT_SPRING_WATER + SLOT_BOTTLE_1, // ITEM_ZORA_EGG + SLOT_BOTTLE_1, // ITEM_GOLD_DUST + SLOT_BOTTLE_1, // ITEM_MUSHROOM + SLOT_BOTTLE_1, // ITEM_SEA_HORSE + SLOT_BOTTLE_1, // ITEM_CHATEAU + SLOT_BOTTLE_1, // ITEM_HYLIAN_LOACH + SLOT_BOTTLE_1, // ITEM_OBABA_DRINK + SLOT_TRADE_DEED, // ITEM_MOON_TEAR + SLOT_TRADE_DEED, // ITEM_DEED_LAND + SLOT_TRADE_DEED, // ITEM_DEED_SWAMP + SLOT_TRADE_DEED, // ITEM_DEED_MOUNTAIN + 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_TO_KAFEI + SLOT_TRADE_COUPLE, // ITEM_PENDANT_MEMORIES + SLOT_TRADE_COUPLE, // ITEM_TINGLE_MAP + SLOT_MASK_DEKU, // ITEM_MASK_DEKU + SLOT_MASK_GORON, // ITEM_MASK_GORON + SLOT_MASK_ZORA, // ITEM_MASK_ZORA + SLOT_MASK_FIERCE_DEITY, // ITEM_MASK_FIERCE_DEITY + SLOT_MASK_TRUTH, // ITEM_MASK_TRUTH + 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 + SLOT_MASK_GARO, // ITEM_MASK_GARO + SLOT_MASK_ROMANI, // ITEM_MASK_ROMANI + SLOT_MASK_CIRCUS_LEADER, // ITEM_MASK_CIRCUS_LEADER + SLOT_MASK_POSTMAN, // ITEM_MASK_POSTMAN + SLOT_MASK_COUPLE, // ITEM_MASK_COUPLE + SLOT_MASK_GREAT_FAIRY, // ITEM_MASK_GREAT_FAIRY + SLOT_MASK_GIBDO, // ITEM_MASK_GIBDO + SLOT_MASK_DON_GERO, // ITEM_MASK_DON_GERO + SLOT_MASK_KAMARO, // ITEM_MASK_KAMARO + SLOT_MASK_CAPTAIN, // ITEM_MASK_CAPTAIN + SLOT_MASK_STONE, // ITEM_MASK_STONE + SLOT_MASK_BREMEN, // ITEM_MASK_BREMEN + SLOT_MASK_BLAST, // ITEM_MASK_BLAST + SLOT_MASK_SCENTS, // ITEM_MASK_SCENTS + SLOT_MASK_GIANT, // ITEM_MASK_GIANT + SLOT_BOW, // ITEM_BOW_ARROW_FIRE + SLOT_BOW, // ITEM_BOW_ARROW_ICE + SLOT_BOW, // ITEM_BOW_ARROW_LIGHT }; s16 gItemPrices[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 20, 20, 20, 0, 20, - 5, 20, 20, 50, 50, 200, 20, 20, 20, 200, 5, 0, 200, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, // ITEM_OCARINA + 0, // ITEM_BOW + 0, // ITEM_ARROW_FIRE + 0, // ITEM_ARROW_ICE + 0, // ITEM_ARROW_LIGHT + 0, // ITEM_OCARINA_FAIRY + 0, // ITEM_BOMB + 0, // ITEM_BOMBCHU + 0, // ITEM_STICK + 0, // ITEM_NUT + 0, // ITEM_MAGIC_BEANS + 0, // ITEM_SLINGSHOT + 0, // ITEM_POWDER_KEG + 0, // ITEM_PICTO_BOX + 0, // ITEM_LENS + 0, // ITEM_HOOKSHOT + 0, // ITEM_SWORD_GREAT_FAIRY + 0, // ITEM_LONGSHOT + 0, // ITEM_BOTTLE + 20, // ITEM_POTION_RED + 20, // ITEM_POTION_GREEN + 20, // ITEM_POTION_BLUE + 20, // ITEM_FAIRY + 0, // ITEM_DEKU_PRINCESS + 20, // ITEM_MILK_BOTTLE + 5, // ITEM_MILK_HALF + 20, // ITEM_FISH + 20, // ITEM_BUG + 50, // ITEM_BLUE_FIRE + 50, // ITEM_POE + 200, // ITEM_BIG_POE + 20, // ITEM_SPRING_WATER + 20, // ITEM_HOT_SPRING_WATER + 20, // ITEM_ZORA_EGG + 200, // ITEM_GOLD_DUST + 5, // ITEM_MUSHROOM + 0, // ITEM_SEA_HORSE + 200, // ITEM_CHATEAU + 20, // ITEM_HYLIAN_LOACH + 0, // ITEM_OBABA_DRINK + 0, // ITEM_MOON_TEAR + 0, // ITEM_DEED_LAND + 0, // ITEM_DEED_SWAMP + 0, // ITEM_DEED_MOUNTAIN + 0, // ITEM_DEED_OCEAN + 0, // ITEM_ROOM_KEY + 0, // ITEM_LETTER_MAMA + 0, // ITEM_LETTER_KAFEI + 0, // ITEM_PENDANT_MEMORIES + 0, // ITEM_TINGLE_MAP }; // Used to map scene indexes to their region in Termina @@ -175,7 +474,7 @@ u16 gScenesPerRegion[11][27] = { }, }; -s32 func_8012EC80(GlobalContext* globalCtx) { +s32 Inventory_GetBtnBItem(GlobalContext* globalCtx) { if (gSaveContext.buttonStatus[0] == BTN_DISABLED) { return ITEM_NONE; } else if (gSaveContext.unk_1015 == ITEM_NONE) { @@ -192,129 +491,240 @@ s32 func_8012EC80(GlobalContext* globalCtx) { } } -void func_8012ED34(s16 equipment); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012ED34.s") +/** + * Only changes shield + */ +void Inventory_ChangeEquipment(s16 value) { + SET_EQUIP_VALUE(EQUIP_SHIELD, value); +} -u8 func_8012ED78(GlobalContext* globalCtx, s16 equipment); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012ED78.s") +/** + * Only deletes shield, equipment argument unused and is a remnant of OoT + */ +u8 Inventory_DeleteEquipment(GlobalContext* globalCtx, s16 equipment) { + Player* player = GET_PLAYER(globalCtx); -void func_8012EDE8(s16 arg0, u32 arg1); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012EDE8.s") + if (GET_CUR_EQUIP_VALUE(EQUIP_SHIELD) != 0) { + SET_EQUIP_VALUE(EQUIP_SHIELD, 0); + Player_SetEquipmentData(globalCtx, player); + return true; + } -s32 func_8012EE34(s16 arg0) { - s16 num = 0; + return false; +} - if (arg0 >= 0x20) { - if (arg0 < 0x40) { - num = 1; - } else if (arg0 < 0x60) { - num = 2; - } else if (arg0 < 0x80) { - num = 3; - } else if (arg0 < 0xA0) { - num = 4; - } else if (arg0 < 0xC0) { - num = 5; - } else if (arg0 < 0xE0) { - num = 6; +void Inventory_ChangeUpgrade(s16 upgrade, u32 value) { + u32 upgrades = gSaveContext.save.inventory.upgrades; + + upgrades &= gUpgradeNegMasks[upgrade]; + upgrades |= value << gUpgradeShifts[upgrade]; + + gSaveContext.save.inventory.upgrades = upgrades; +} + +s32 Inventory_IsMapVisible(s16 sceneNum) { + s16 index = 0; + + /** + * a single index of scenesVisible can only hold 32 bits. So for every 32 scenes in the scene enum, + * increment to the next index of scenesVisible so that every scene gets a unique flag in scenesVisible, + * 224 bits were allocated to this although there are only 112 scenes + */ + if (sceneNum >= 0x20) { + if (sceneNum < 0x40) { + index = 1; + } else if (sceneNum < 0x60) { + index = 2; + } else if (sceneNum < 0x80) { + index = 3; + } else if (sceneNum < 0xA0) { + index = 4; + } else if (sceneNum < 0xC0) { + index = 5; + } else if (sceneNum < 0xE0) { + index = 6; } } - if (gSaveContext.roomInf[125][num] & gBitFlags[arg0 - (num << 5)]) { - return 1; + if (gSaveContext.save.scenesVisible[index] & gBitFlags[sceneNum - (index << 5)]) { + return true; } - return 0; + return false; } -static u16 D_801C2380[6][12] = { - { SCENE_00KEIKOKU, SCENE_BOTI, SCENE_13HUBUKINOMITI, SCENE_24KEMONOMITI, SCENE_IKANAMAE, SCENE_TOWN, SCENE_ICHIBA, - SCENE_BACKTOWN, SCENE_CLOCKTOWER, SCENE_ALLEY, -1 }, - { SCENE_20SICHITAI, SCENE_20SICHITAI2, SCENE_21MITURINMAE, SCENE_22DEKUCITY, SCENE_DEKU_KING, SCENE_KINSTA1, -1 }, - { SCENE_10YUKIYAMANOMURA, SCENE_10YUKIYAMANOMURA2, SCENE_11GORONNOSATO, SCENE_11GORONNOSATO2, SCENE_16GORON_HOUSE, - SCENE_12HAKUGINMAE, SCENE_14YUKIDAMANOMITI, SCENE_GORONRACE, SCENE_17SETUGEN, SCENE_17SETUGEN2, -1 }, - { SCENE_F01, SCENE_ROMANYMAE, SCENE_OMOYA, SCENE_F01C, SCENE_F01_B, SCENE_KOEPONARACE, -1 }, - { SCENE_30GYOSON, SCENE_SINKAI, SCENE_31MISAKI, SCENE_TORIDE, SCENE_KAIZOKU, SCENE_33ZORACITY, SCENE_35TAKI, -1 }, - { SCENE_F40, SCENE_F41, SCENE_CASTLE, SCENE_IKANA, SCENE_REDEAD, -1 }, +static u16 sScenesPerTingleMap[6][12] = { + { + // Clock Town Tingle Map + SCENE_00KEIKOKU, + SCENE_BOTI, + SCENE_13HUBUKINOMITI, + SCENE_24KEMONOMITI, + SCENE_IKANAMAE, + SCENE_TOWN, + SCENE_ICHIBA, + SCENE_BACKTOWN, + SCENE_CLOCKTOWER, + SCENE_ALLEY, + -1, + }, + { + // Woodfall Tingle Map + SCENE_20SICHITAI, + SCENE_20SICHITAI2, + SCENE_21MITURINMAE, + SCENE_22DEKUCITY, + SCENE_DEKU_KING, + SCENE_KINSTA1, + -1, + }, + { + // Snowhead Tingle Map + SCENE_10YUKIYAMANOMURA, + SCENE_10YUKIYAMANOMURA2, + SCENE_11GORONNOSATO, + SCENE_11GORONNOSATO2, + SCENE_16GORON_HOUSE, + SCENE_12HAKUGINMAE, + SCENE_14YUKIDAMANOMITI, + SCENE_GORONRACE, + SCENE_17SETUGEN, + SCENE_17SETUGEN2, + -1, + }, + { + // Romani Ranch Tingle Map + SCENE_F01, + SCENE_ROMANYMAE, + SCENE_OMOYA, + SCENE_F01C, + SCENE_F01_B, + SCENE_KOEPONARACE, + -1, + }, + { + // Great Bay Tingle Map + SCENE_30GYOSON, + SCENE_SINKAI, + SCENE_31MISAKI, + SCENE_TORIDE, + SCENE_KAIZOKU, + SCENE_33ZORACITY, + SCENE_35TAKI, + -1, + }, + { + // Stone Tower Tingle Map + SCENE_F40, + SCENE_F41, + SCENE_CASTLE, + SCENE_IKANA, + SCENE_REDEAD, + -1, + }, }; -void func_8012EF0C(s16 arg0) { - s16 phi_v0 = 0; - s16 phi_v1 = 0; - u16(*new_var)[] = &D_801C2380[arg0]; +/** + * Map visibility is achieved by purchasing a tingle map + */ +void Inventory_SetMapVisibility(s16 tingleIndex) { + s16 i = 0; + s16 index = 0; + u16(*tingleMapSceneIndices)[] = &sScenesPerTingleMap[tingleIndex]; - if ((arg0 >= 0) && (arg0 < 6)) { + if ((tingleIndex >= 0) && (tingleIndex < 6)) { while (true) { - if ((*new_var)[phi_v0] == 0xFFFF) { + if ((*tingleMapSceneIndices)[i] == 0xFFFF) { break; } - if (((s16)(*new_var)[phi_v0]) < 0x20) { - phi_v1 = 0; - } else if (((s16)(*new_var)[phi_v0]) < 0x40) { - phi_v1 = 1; - } else if (((s16)(*new_var)[phi_v0]) < 0x60) { - phi_v1 = 2; - } else if (((s16)(*new_var)[phi_v0]) < 0x80) { - phi_v1 = 3; - } else if (((s16)(*new_var)[phi_v0]) < 0xA0) { - phi_v1 = 4; - } else if (((s16)(*new_var)[phi_v0]) < 0xC0) { - phi_v1 = 5; - } else if (((s16)(*new_var)[phi_v0]) < 0xE0) { - phi_v1 = 6; + /** + * a single index of scenesVisible can only hold 32 bits. So for every 32 scenes in the scene enum, + * increment to the next index of scenesVisible so that every scene gets a unique flag in scenesVisible, + * 224 bits were allocated to this although there are only 112 scenes + */ + if (((s16)(*tingleMapSceneIndices)[i]) < 0x20) { + index = 0; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0x40) { + index = 1; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0x60) { + index = 2; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0x80) { + index = 3; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0xA0) { + index = 4; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0xC0) { + index = 5; + } else if (((s16)(*tingleMapSceneIndices)[i]) < 0xE0) { + index = 6; } - // Required to match - gSaveContext.roomInf[125][phi_v1] = - gSaveContext.roomInf[125][phi_v1] | gBitFlags[(s16)(*new_var)[phi_v0] - (phi_v1 << 5)]; - phi_v0++; + gSaveContext.save.scenesVisible[index] = + gSaveContext.save.scenesVisible[index] | gBitFlags[(s16)(*tingleMapSceneIndices)[i] - (index << 5)]; + i++; } - if ((*new_var) == D_801C2380[0]) { - gSaveContext.unk_F60 |= 3; - } else if ((*new_var) == D_801C2380[1]) { - gSaveContext.unk_F60 |= 0x1C; - } else if ((*new_var) == D_801C2380[2]) { - gSaveContext.unk_F60 |= 0xE0; - } else if ((*new_var) == D_801C2380[3]) { - gSaveContext.unk_F60 |= 0x100; - } else if ((*new_var) == D_801C2380[4]) { - gSaveContext.unk_F60 |= 0x1E00; - } else if ((*new_var) == D_801C2380[5]) { - gSaveContext.unk_F60 |= 0x6000; + if ((*tingleMapSceneIndices) == sScenesPerTingleMap[0]) { + gSaveContext.save.mapsVisible |= 3; + } else if ((*tingleMapSceneIndices) == sScenesPerTingleMap[1]) { + gSaveContext.save.mapsVisible |= 0x1C; + } else if ((*tingleMapSceneIndices) == sScenesPerTingleMap[2]) { + gSaveContext.save.mapsVisible |= 0xE0; + } else if ((*tingleMapSceneIndices) == sScenesPerTingleMap[3]) { + gSaveContext.save.mapsVisible |= 0x100; + } else if ((*tingleMapSceneIndices) == sScenesPerTingleMap[4]) { + gSaveContext.save.mapsVisible |= 0x1E00; + } else if ((*tingleMapSceneIndices) == sScenesPerTingleMap[5]) { + gSaveContext.save.mapsVisible |= 0x6000; } } XREG(95) = 0; } -void func_8012F0EC(s16 arg0); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012F0EC.s") +/** + * Also stores the players filename into dekuPlaygroundPlayerName + */ +void Inventory_SaveDekuPlaygroundHighScore(s16 timerId) { + s16 i; -#ifdef NON_MATCHING -// regalloc -void func_8012F1BC(s16 sceneIndex) { - if (sceneIndex == SCENE_KINSTA1) { - gSaveContext.roomInf[126][0] = ((((gSaveContext.roomInf[126][0] & 0xFFFF0000) >> 0x10) + 1) << 0x10) | - (gSaveContext.roomInf[126][0] & 0xFFFF); - } else { - gSaveContext.roomInf[126][0] = - ((gSaveContext.roomInf[126][0] + 1) & 0xFFFF) | (gSaveContext.roomInf[126][0] & 0xFFFF0000); - } -} -#else -void func_8012F1BC(s16 arg0); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012F1BC.s") -#endif + gSaveContext.save.dekuPlaygroundHighScores[CURRENT_DAY - 1] = gSaveContext.unk_3DE0[timerId]; -s16 func_8012F22C(s16 sceneIndex) { - if (sceneIndex == SCENE_KINSTA1) { - return (gSaveContext.roomInf[126][0] & 0xFFFF0000) >> 0x10; - } else { - return gSaveContext.roomInf[126][0] & 0xFFFF; + for (i = 0; i < 8; i++) { + gSaveContext.save.inventory.dekuPlaygroundPlayerName[CURRENT_DAY - 1][i] = + gSaveContext.save.playerData.playerName[i]; } } -void func_8012F278(GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8012EC80/func_8012F278.s") +void Inventory_IncrementSkullTokenCount(s16 sceneIndex) { + if (sceneIndex == SCENE_KINSTA1) { + // Swamp Spider House (increment high bits of skullTokenCount) + gSaveContext.save.skullTokenCount = + ((u16)(((gSaveContext.save.skullTokenCount & 0xFFFF0000) >> 0x10) + 1) << 0x10) | + (gSaveContext.save.skullTokenCount & 0xFFFF); + } else { + // Ocean Spider House (increment low bits of skullTokenCount) + gSaveContext.save.skullTokenCount = + (((u16)gSaveContext.save.skullTokenCount + 1) & 0xFFFF) | (gSaveContext.save.skullTokenCount & 0xFFFF0000); + } +} + +s16 Inventory_GetSkullTokenCount(s16 sceneIndex) { + if (sceneIndex == SCENE_KINSTA1) { + // Swamp Spider House + return (gSaveContext.save.skullTokenCount & 0xFFFF0000) >> 0x10; + } else { + // Ocean Spider House + return gSaveContext.save.skullTokenCount & 0xFFFF; + } +} + +void Inventory_SaveLotteryCodeGuess(GlobalContext* globalCtx) { + u16 lotteryCodeGuess; + + lotteryCodeGuess = ((globalCtx->msgCtx.unk12054[0] & 0xF) << 8); // First Digit + lotteryCodeGuess |= ((globalCtx->msgCtx.unk12054[1] & 0xF) << 4); // Second Digit + lotteryCodeGuess |= (globalCtx->msgCtx.unk12054[2] & 0xF); // Third Digit + gSaveContext.save.lotteryCodeGuess = + (gSaveContext.save.lotteryCodeGuess & 0xFFFF0000) | (lotteryCodeGuess & 0xFFFF); +} diff --git a/src/code/code_801323D0.c b/src/code/code_801323D0.c deleted file mode 100644 index 1457f537d..000000000 --- a/src/code/code_801323D0.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_801323D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132428.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132494.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_801326B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_801328F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132920.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132938.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132954.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_8013296C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132A18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132A3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132A80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132AD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132B24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132B84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132D70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132E9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80132FDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80133000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801323D0/func_80133038.s") diff --git a/src/code/code_80174A40.c b/src/code/code_80174A40.c deleted file mode 100644 index a4daff018..000000000 --- a/src/code/code_80174A40.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80174A40/Graph_GfxPlusOne.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80174A40/Graph_BranchDlist.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80174A40/Graph_DlistAlloc.s") diff --git a/src/code/code_80182CE0.c b/src/code/code_80182CE0.c new file mode 100644 index 000000000..6ff8736e5 --- /dev/null +++ b/src/code/code_80182CE0.c @@ -0,0 +1,7 @@ +#include "global.h" + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80182CE0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80183020.s") + +#pragma GLOBAL_ASM("asm/non_matchings/code/code_80182CE0/func_80183058.s") diff --git a/src/code/code_80194710.c b/src/code/code_80194710.c deleted file mode 100644 index aa4f784c4..000000000 --- a/src/code/code_80194710.c +++ /dev/null @@ -1,13 +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") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_80194790.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_80194804.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_80194840.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_801948B0.s") diff --git a/src/code/code_8019AF00.c b/src/code/code_8019AF00.c deleted file mode 100644 index 8f0d129ad..000000000 --- a/src/code/code_8019AF00.c +++ /dev/null @@ -1,429 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/D_801E0BD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AF58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019AFE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B02C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B074.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B144.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B378.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B38C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B3D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B4B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B544.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B568.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B5EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B618.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B654.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019B6B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BC44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019BE98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C1D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C268.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C2E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C300.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C398.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C5A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019C8D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/D_801E0C14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CD08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE34.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CE6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CEBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CF9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019CFA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D134.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D26C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D488.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D4F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D600.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D758.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D864.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019D8E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DF64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019DFF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E00C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E014.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E0FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E104.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E110.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E14C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E324.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E4B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E634.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019E864.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EA40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019EB2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F024.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F05C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/play_sound.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F128.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F170.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F1C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F208.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F230.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F258.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F300.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F420.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F4AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F540.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F5AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F638.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F780.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F7D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F830.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F88C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019F900.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FA18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FAD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FB0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FC20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FCB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FD90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FDC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FE74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FEDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FF38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_8019FF9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0048.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A00EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0184.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A01C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0204.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A026C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0318.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0450.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A046C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0554.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A05F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0654.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0810.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0868.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A09D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0C90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0CB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A0E44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1290.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1348.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A13BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A153C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A17F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1904.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1A8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1D44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1DB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1E0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1F88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A1FB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2090.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A21FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A246C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2544.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A257C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A25E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2670.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2778.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A27E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A281C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A29D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2BB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2C88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2D54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2DE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2E54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2ED8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2F88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2FC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3038.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3098.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A312C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A31EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A32CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3590.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A36F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3950.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A39F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3A7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3AEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3B90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3CF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3D98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3E38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3EC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3F6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A3FFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/audio_setBGM.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A41F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A429C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A42C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4324.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4348.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4380.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4428.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_PreNMI.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A44C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A44D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A46F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4748.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A479C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A47DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A48E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4A28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4B80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4C54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4DF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4E64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4EB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4EB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A4FD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A5080.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A50C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A5100.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A510C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A5118.s") diff --git a/src/code/code_801AA020.c b/src/code/code_801AA020.c deleted file mode 100644 index 2144c6bcb..000000000 --- a/src/code/code_801AA020.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/D_801E1100.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA020.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA248.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA3E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA520.s") diff --git a/src/code/flg_set.c b/src/code/flg_set.c index 780884c85..53be7b68d 100644 --- a/src/code/flg_set.c +++ b/src/code/flg_set.c @@ -12,106 +12,106 @@ #include "global.h" static FlagSetEntry sFlagEntries[] = { - { &gSaveContext.weekEventReg[0], "week_event_reg[0]" }, - { &gSaveContext.weekEventReg[1], "week_event_reg[1]" }, - { &gSaveContext.weekEventReg[2], "week_event_reg[2]" }, - { &gSaveContext.weekEventReg[3], "week_event_reg[3]" }, - { &gSaveContext.weekEventReg[4], "week_event_reg[4]" }, - { &gSaveContext.weekEventReg[5], "week_event_reg[5]" }, - { &gSaveContext.weekEventReg[6], "week_event_reg[6]" }, - { &gSaveContext.weekEventReg[7], "week_event_reg[7]" }, - { &gSaveContext.weekEventReg[8], "week_event_reg[8]" }, - { &gSaveContext.weekEventReg[9], "week_event_reg[9]" }, - { &gSaveContext.weekEventReg[10], "week_event_reg[10]" }, - { &gSaveContext.weekEventReg[11], "week_event_reg[11]" }, - { &gSaveContext.weekEventReg[12], "week_event_reg[12]" }, - { &gSaveContext.weekEventReg[13], "week_event_reg[13]" }, - { &gSaveContext.weekEventReg[14], "week_event_reg[14]" }, - { &gSaveContext.weekEventReg[15], "week_event_reg[15]" }, - { &gSaveContext.weekEventReg[16], "week_event_reg[16]" }, - { &gSaveContext.weekEventReg[17], "week_event_reg[17]" }, - { &gSaveContext.weekEventReg[18], "week_event_reg[18]" }, - { &gSaveContext.weekEventReg[19], "week_event_reg[19]" }, - { &gSaveContext.weekEventReg[20], "week_event_reg[20]" }, - { &gSaveContext.weekEventReg[21], "week_event_reg[21]" }, - { &gSaveContext.weekEventReg[22], "week_event_reg[22]" }, - { &gSaveContext.weekEventReg[23], "week_event_reg[23]" }, - { &gSaveContext.weekEventReg[24], "week_event_reg[24]" }, - { &gSaveContext.weekEventReg[25], "week_event_reg[25]" }, - { &gSaveContext.weekEventReg[26], "week_event_reg[26]" }, - { &gSaveContext.weekEventReg[27], "week_event_reg[27]" }, - { &gSaveContext.weekEventReg[28], "week_event_reg[28]" }, - { &gSaveContext.weekEventReg[29], "week_event_reg[29]" }, - { &gSaveContext.weekEventReg[30], "week_event_reg[30]" }, - { &gSaveContext.weekEventReg[31], "week_event_reg[31]" }, - { &gSaveContext.weekEventReg[32], "week_event_reg[32]" }, - { &gSaveContext.weekEventReg[33], "week_event_reg[33]" }, - { &gSaveContext.weekEventReg[34], "week_event_reg[34]" }, - { &gSaveContext.weekEventReg[35], "week_event_reg[35]" }, - { &gSaveContext.weekEventReg[36], "week_event_reg[36]" }, - { &gSaveContext.weekEventReg[37], "week_event_reg[37]" }, - { &gSaveContext.weekEventReg[38], "week_event_reg[38]" }, - { &gSaveContext.weekEventReg[39], "week_event_reg[39]" }, - { &gSaveContext.weekEventReg[40], "week_event_reg[40]" }, - { &gSaveContext.weekEventReg[41], "week_event_reg[41]" }, - { &gSaveContext.weekEventReg[42], "week_event_reg[42]" }, - { &gSaveContext.weekEventReg[43], "week_event_reg[43]" }, - { &gSaveContext.weekEventReg[44], "week_event_reg[44]" }, - { &gSaveContext.weekEventReg[45], "week_event_reg[45]" }, - { &gSaveContext.weekEventReg[46], "week_event_reg[46]" }, - { &gSaveContext.weekEventReg[47], "week_event_reg[47]" }, - { &gSaveContext.weekEventReg[48], "week_event_reg[48]" }, - { &gSaveContext.weekEventReg[49], "week_event_reg[49]" }, - { &gSaveContext.weekEventReg[50], "week_event_reg[50]" }, - { &gSaveContext.weekEventReg[51], "week_event_reg[51]" }, - { &gSaveContext.weekEventReg[52], "week_event_reg[52]" }, - { &gSaveContext.weekEventReg[53], "week_event_reg[53]" }, - { &gSaveContext.weekEventReg[54], "week_event_reg[54]" }, - { &gSaveContext.weekEventReg[55], "week_event_reg[55]" }, - { &gSaveContext.weekEventReg[56], "week_event_reg[56]" }, - { &gSaveContext.weekEventReg[57], "week_event_reg[57]" }, - { &gSaveContext.weekEventReg[58], "week_event_reg[58]" }, - { &gSaveContext.weekEventReg[59], "week_event_reg[59]" }, - { &gSaveContext.weekEventReg[60], "week_event_reg[60]" }, - { &gSaveContext.weekEventReg[61], "week_event_reg[61]" }, - { &gSaveContext.weekEventReg[62], "week_event_reg[62]" }, - { &gSaveContext.weekEventReg[63], "week_event_reg[63]" }, - { &gSaveContext.weekEventReg[64], "week_event_reg[64]" }, - { &gSaveContext.weekEventReg[65], "week_event_reg[65]" }, - { &gSaveContext.weekEventReg[66], "week_event_reg[66]" }, - { &gSaveContext.weekEventReg[67], "week_event_reg[67]" }, - { &gSaveContext.weekEventReg[68], "week_event_reg[68]" }, - { &gSaveContext.weekEventReg[69], "week_event_reg[69]" }, - { &gSaveContext.weekEventReg[70], "week_event_reg[70]" }, - { &gSaveContext.weekEventReg[71], "week_event_reg[71]" }, - { &gSaveContext.weekEventReg[72], "week_event_reg[72]" }, - { &gSaveContext.weekEventReg[73], "week_event_reg[73]" }, - { &gSaveContext.weekEventReg[74], "week_event_reg[74]" }, - { &gSaveContext.weekEventReg[75], "week_event_reg[75]" }, - { &gSaveContext.weekEventReg[76], "week_event_reg[76]" }, - { &gSaveContext.weekEventReg[77], "week_event_reg[77]" }, - { &gSaveContext.weekEventReg[78], "week_event_reg[78]" }, - { &gSaveContext.weekEventReg[79], "week_event_reg[79]" }, - { &gSaveContext.weekEventReg[80], "week_event_reg[80]" }, - { &gSaveContext.weekEventReg[81], "week_event_reg[81]" }, - { &gSaveContext.weekEventReg[82], "week_event_reg[82]" }, - { &gSaveContext.weekEventReg[83], "week_event_reg[83]" }, - { &gSaveContext.weekEventReg[84], "week_event_reg[84]" }, - { &gSaveContext.weekEventReg[85], "week_event_reg[85]" }, - { &gSaveContext.weekEventReg[86], "week_event_reg[86]" }, - { &gSaveContext.weekEventReg[87], "week_event_reg[87]" }, - { &gSaveContext.weekEventReg[88], "week_event_reg[88]" }, - { &gSaveContext.weekEventReg[89], "week_event_reg[89]" }, - { &gSaveContext.weekEventReg[90], "week_event_reg[90]" }, - { &gSaveContext.weekEventReg[91], "week_event_reg[91]" }, - { &gSaveContext.weekEventReg[92], "week_event_reg[92]" }, - { &gSaveContext.weekEventReg[93], "week_event_reg[93]" }, - { &gSaveContext.weekEventReg[94], "week_event_reg[94]" }, - { &gSaveContext.weekEventReg[95], "week_event_reg[95]" }, - { &gSaveContext.weekEventReg[96], "week_event_reg[96]" }, - { &gSaveContext.weekEventReg[97], "week_event_reg[97]" }, - { &gSaveContext.weekEventReg[98], "week_event_reg[98]" }, - { &gSaveContext.weekEventReg[99], "week_event_reg[99]" }, + { &gSaveContext.save.weekEventReg[0], "week_event_reg[0]" }, + { &gSaveContext.save.weekEventReg[1], "week_event_reg[1]" }, + { &gSaveContext.save.weekEventReg[2], "week_event_reg[2]" }, + { &gSaveContext.save.weekEventReg[3], "week_event_reg[3]" }, + { &gSaveContext.save.weekEventReg[4], "week_event_reg[4]" }, + { &gSaveContext.save.weekEventReg[5], "week_event_reg[5]" }, + { &gSaveContext.save.weekEventReg[6], "week_event_reg[6]" }, + { &gSaveContext.save.weekEventReg[7], "week_event_reg[7]" }, + { &gSaveContext.save.weekEventReg[8], "week_event_reg[8]" }, + { &gSaveContext.save.weekEventReg[9], "week_event_reg[9]" }, + { &gSaveContext.save.weekEventReg[10], "week_event_reg[10]" }, + { &gSaveContext.save.weekEventReg[11], "week_event_reg[11]" }, + { &gSaveContext.save.weekEventReg[12], "week_event_reg[12]" }, + { &gSaveContext.save.weekEventReg[13], "week_event_reg[13]" }, + { &gSaveContext.save.weekEventReg[14], "week_event_reg[14]" }, + { &gSaveContext.save.weekEventReg[15], "week_event_reg[15]" }, + { &gSaveContext.save.weekEventReg[16], "week_event_reg[16]" }, + { &gSaveContext.save.weekEventReg[17], "week_event_reg[17]" }, + { &gSaveContext.save.weekEventReg[18], "week_event_reg[18]" }, + { &gSaveContext.save.weekEventReg[19], "week_event_reg[19]" }, + { &gSaveContext.save.weekEventReg[20], "week_event_reg[20]" }, + { &gSaveContext.save.weekEventReg[21], "week_event_reg[21]" }, + { &gSaveContext.save.weekEventReg[22], "week_event_reg[22]" }, + { &gSaveContext.save.weekEventReg[23], "week_event_reg[23]" }, + { &gSaveContext.save.weekEventReg[24], "week_event_reg[24]" }, + { &gSaveContext.save.weekEventReg[25], "week_event_reg[25]" }, + { &gSaveContext.save.weekEventReg[26], "week_event_reg[26]" }, + { &gSaveContext.save.weekEventReg[27], "week_event_reg[27]" }, + { &gSaveContext.save.weekEventReg[28], "week_event_reg[28]" }, + { &gSaveContext.save.weekEventReg[29], "week_event_reg[29]" }, + { &gSaveContext.save.weekEventReg[30], "week_event_reg[30]" }, + { &gSaveContext.save.weekEventReg[31], "week_event_reg[31]" }, + { &gSaveContext.save.weekEventReg[32], "week_event_reg[32]" }, + { &gSaveContext.save.weekEventReg[33], "week_event_reg[33]" }, + { &gSaveContext.save.weekEventReg[34], "week_event_reg[34]" }, + { &gSaveContext.save.weekEventReg[35], "week_event_reg[35]" }, + { &gSaveContext.save.weekEventReg[36], "week_event_reg[36]" }, + { &gSaveContext.save.weekEventReg[37], "week_event_reg[37]" }, + { &gSaveContext.save.weekEventReg[38], "week_event_reg[38]" }, + { &gSaveContext.save.weekEventReg[39], "week_event_reg[39]" }, + { &gSaveContext.save.weekEventReg[40], "week_event_reg[40]" }, + { &gSaveContext.save.weekEventReg[41], "week_event_reg[41]" }, + { &gSaveContext.save.weekEventReg[42], "week_event_reg[42]" }, + { &gSaveContext.save.weekEventReg[43], "week_event_reg[43]" }, + { &gSaveContext.save.weekEventReg[44], "week_event_reg[44]" }, + { &gSaveContext.save.weekEventReg[45], "week_event_reg[45]" }, + { &gSaveContext.save.weekEventReg[46], "week_event_reg[46]" }, + { &gSaveContext.save.weekEventReg[47], "week_event_reg[47]" }, + { &gSaveContext.save.weekEventReg[48], "week_event_reg[48]" }, + { &gSaveContext.save.weekEventReg[49], "week_event_reg[49]" }, + { &gSaveContext.save.weekEventReg[50], "week_event_reg[50]" }, + { &gSaveContext.save.weekEventReg[51], "week_event_reg[51]" }, + { &gSaveContext.save.weekEventReg[52], "week_event_reg[52]" }, + { &gSaveContext.save.weekEventReg[53], "week_event_reg[53]" }, + { &gSaveContext.save.weekEventReg[54], "week_event_reg[54]" }, + { &gSaveContext.save.weekEventReg[55], "week_event_reg[55]" }, + { &gSaveContext.save.weekEventReg[56], "week_event_reg[56]" }, + { &gSaveContext.save.weekEventReg[57], "week_event_reg[57]" }, + { &gSaveContext.save.weekEventReg[58], "week_event_reg[58]" }, + { &gSaveContext.save.weekEventReg[59], "week_event_reg[59]" }, + { &gSaveContext.save.weekEventReg[60], "week_event_reg[60]" }, + { &gSaveContext.save.weekEventReg[61], "week_event_reg[61]" }, + { &gSaveContext.save.weekEventReg[62], "week_event_reg[62]" }, + { &gSaveContext.save.weekEventReg[63], "week_event_reg[63]" }, + { &gSaveContext.save.weekEventReg[64], "week_event_reg[64]" }, + { &gSaveContext.save.weekEventReg[65], "week_event_reg[65]" }, + { &gSaveContext.save.weekEventReg[66], "week_event_reg[66]" }, + { &gSaveContext.save.weekEventReg[67], "week_event_reg[67]" }, + { &gSaveContext.save.weekEventReg[68], "week_event_reg[68]" }, + { &gSaveContext.save.weekEventReg[69], "week_event_reg[69]" }, + { &gSaveContext.save.weekEventReg[70], "week_event_reg[70]" }, + { &gSaveContext.save.weekEventReg[71], "week_event_reg[71]" }, + { &gSaveContext.save.weekEventReg[72], "week_event_reg[72]" }, + { &gSaveContext.save.weekEventReg[73], "week_event_reg[73]" }, + { &gSaveContext.save.weekEventReg[74], "week_event_reg[74]" }, + { &gSaveContext.save.weekEventReg[75], "week_event_reg[75]" }, + { &gSaveContext.save.weekEventReg[76], "week_event_reg[76]" }, + { &gSaveContext.save.weekEventReg[77], "week_event_reg[77]" }, + { &gSaveContext.save.weekEventReg[78], "week_event_reg[78]" }, + { &gSaveContext.save.weekEventReg[79], "week_event_reg[79]" }, + { &gSaveContext.save.weekEventReg[80], "week_event_reg[80]" }, + { &gSaveContext.save.weekEventReg[81], "week_event_reg[81]" }, + { &gSaveContext.save.weekEventReg[82], "week_event_reg[82]" }, + { &gSaveContext.save.weekEventReg[83], "week_event_reg[83]" }, + { &gSaveContext.save.weekEventReg[84], "week_event_reg[84]" }, + { &gSaveContext.save.weekEventReg[85], "week_event_reg[85]" }, + { &gSaveContext.save.weekEventReg[86], "week_event_reg[86]" }, + { &gSaveContext.save.weekEventReg[87], "week_event_reg[87]" }, + { &gSaveContext.save.weekEventReg[88], "week_event_reg[88]" }, + { &gSaveContext.save.weekEventReg[89], "week_event_reg[89]" }, + { &gSaveContext.save.weekEventReg[90], "week_event_reg[90]" }, + { &gSaveContext.save.weekEventReg[91], "week_event_reg[91]" }, + { &gSaveContext.save.weekEventReg[92], "week_event_reg[92]" }, + { &gSaveContext.save.weekEventReg[93], "week_event_reg[93]" }, + { &gSaveContext.save.weekEventReg[94], "week_event_reg[94]" }, + { &gSaveContext.save.weekEventReg[95], "week_event_reg[95]" }, + { &gSaveContext.save.weekEventReg[96], "week_event_reg[96]" }, + { &gSaveContext.save.weekEventReg[97], "week_event_reg[97]" }, + { &gSaveContext.save.weekEventReg[98], "week_event_reg[98]" }, + { &gSaveContext.save.weekEventReg[99], "week_event_reg[99]" }, { &gSaveContext.eventInf[0], "event_inf[0]" }, { &gSaveContext.eventInf[1], "event_inf[1]" }, @@ -245,8 +245,8 @@ void FlagSet_Update(GameState* gameState) { if (CHECK_BTN_ALL(input->cur.button, BTN_START)) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { s16 i; - for (i = 0; i < ARRAY_COUNT(gSaveContext.weekEventReg); i++) { - gSaveContext.weekEventReg[i] = 0; + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.weekEventReg); i++) { + gSaveContext.save.weekEventReg[i] = 0; } for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { gSaveContext.eventInf[i] = 0; diff --git a/src/code/game.c b/src/code/game.c index a90fc7ac2..2713be299 100644 --- a/src/code/game.c +++ b/src/code/game.c @@ -1,13 +1,11 @@ #include "global.h" +#include "system_malloc.h" s32 gFramerateDivisor = 1; f32 gFramerateDivisorF = 1.0f; f32 gFramerateDivisorHalf = 1.0f / 2.0f; f32 gFramerateDivisorThird = 1.0f / 3.0f; -u32 D_801D1510 = 0x0000000A; -u32 D_801D1514[3] = { 0 }; - void Game_UpdateFramerateVariables(s32 divisor) { gFramerateDivisor = divisor; gFramerateDivisorF = (f32)divisor; @@ -104,12 +102,12 @@ void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) { void GameState_SetFrameBuffer(GraphicsContext* gfxCtx) { OPEN_DISPS(gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0, NULL); - gSPSegment(POLY_OPA_DISP++, 0xF, gfxCtx->framebuffer); - gSPSegment(POLY_XLU_DISP++, 0, NULL); - gSPSegment(POLY_XLU_DISP++, 0xF, gfxCtx->framebuffer); - gSPSegment(OVERLAY_DISP++, 0, NULL); - gSPSegment(OVERLAY_DISP++, 0xF, gfxCtx->framebuffer); + gSPSegment(POLY_OPA_DISP++, 0x00, NULL); + gSPSegment(POLY_OPA_DISP++, 0x0F, gfxCtx->curFrameBuffer); + gSPSegment(POLY_XLU_DISP++, 0x00, NULL); + gSPSegment(POLY_XLU_DISP++, 0x0F, gfxCtx->curFrameBuffer); + gSPSegment(OVERLAY_DISP++, 0x00, NULL); + gSPSegment(OVERLAY_DISP++, 0x0F, gfxCtx->curFrameBuffer); CLOSE_DISPS(gfxCtx); } @@ -177,7 +175,7 @@ void GameState_Realloc(GameState* gameState, size_t size) { alloc = &gameState->alloc; THA_Dt(&gameState->heap); GameAlloc_Free(alloc, heapStart); - SystemArena_AnalyzeArena(&systemMaxFree, &bytesFree, &bytesAllocated); + SystemArena_GetSizes(&systemMaxFree, &bytesFree, &bytesAllocated); size = ((systemMaxFree - (sizeof(ArenaNode))) < size) ? (0) : (size); if (size == 0) { size = systemMaxFree - (sizeof(ArenaNode)); @@ -199,8 +197,8 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g gameState->running = 1; gfxCtx->viMode = D_801FBB88; gfxCtx->viConfigFeatures = gViConfigFeatures; - gfxCtx->viConfigXScale = gViConfigXScale; - gfxCtx->viConfigYScale = gViConfigYScale; + gfxCtx->xScale = gViConfigXScale; + gfxCtx->yScale = gViConfigYScale; gameState->nextGameStateInit = NULL; gameState->nextGameStateSize = 0U; @@ -220,14 +218,14 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g func_801773A0(&D_801F7FF0); func_8013ED9C(); - osSendMesg(&gameState->gfxCtx->unk5C, NULL, 1); + osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); } } void GameState_Destroy(GameState* gameState) { func_80172BC0(); func_8019E014(); - osRecvMesg(&gameState->gfxCtx->unk5C, NULL, OS_MESG_BLOCK); + osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); if (gameState->destroy != NULL) { gameState->destroy(gameState); @@ -247,7 +245,7 @@ GameStateFunc GameState_GetNextStateInit(GameState* gameState) { return gameState->nextGameStateInit; } -size_t Game_GetNextStateSize(GameState* gameState) { +size_t GameState_GetNextStateSize(GameState* gameState) { return gameState->nextGameStateSize; } diff --git a/src/code/gamealloc.c b/src/code/gamealloc.c index 541f9125b..6067ad91c 100644 --- a/src/code/gamealloc.c +++ b/src/code/gamealloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" void GameAlloc_Log(GameAlloc* this) { GameAllocEntry* iter; diff --git a/src/code/graph.c b/src/code/graph.c index 428bd8621..28327c35f 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -1,25 +1,382 @@ #include "global.h" +#include "system_malloc.h" +#include "overlays/gamestates/ovl_daytelop/z_daytelop.h" +#include "overlays/gamestates/ovl_file_choose/z_file_choose.h" +#include "overlays/gamestates/ovl_opening/z_opening.h" +#include "overlays/gamestates/ovl_select/z_select.h" +#include "overlays/gamestates/ovl_title/z_title.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_FaultClient.s") +FaultAddrConvClient sGraphFaultAddrConvClient; +FaultClient sGraphFaultClient; +GfxMasterList* gGfxMasterDL; +CfbInfo sGraphCfbInfos[3]; +OSTime sGraphTaskStartTime; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_DlAlloc.s") +void Graph_FaultClient(void) { + FaultDrawer_DrawText(30, 100, "ShowFrameBuffer PAGE 0/1"); + osViSwapBuffer(SysCfb_GetFbPtr(0)); + osViSetMode(D_801FBB88); + osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_GAMMA_OFF); + Fault_WaitForInput(); + osViSwapBuffer(SysCfb_GetFbPtr(1)); + osViSetMode(D_801FBB88); + osViSetSpecialFeatures(OS_VI_DITHER_FILTER_ON | OS_VI_GAMMA_OFF); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_InitTHGA.s") +void Graph_InitTHGA(TwoHeadGfxArena* arena, Gfx* buffer, s32 size) { + THGA_Ct(arena, buffer, size); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_GetNextGameState.s") +void Graph_SetNextGfxPool(GraphicsContext* gfxCtx) { + GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx % 2]; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_FaultAddrConvFunc.s") + gGfxMasterDL = &pool->master; + gSegments[0x0E] = gGfxMasterDL; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_Init.s") + pool->headMagic = GFXPOOL_HEAD_MAGIC; + pool->tailMagic = GFXPOOL_TAIL_MAGIC; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_Destroy.s") + Graph_InitTHGA(&gfxCtx->polyOpa, pool->polyOpaBuffer, sizeof(pool->polyOpaBuffer)); + Graph_InitTHGA(&gfxCtx->polyXlu, pool->polyXluBuffer, sizeof(pool->polyXluBuffer)); + Graph_InitTHGA(&gfxCtx->overlay, pool->overlayBuffer, sizeof(pool->overlayBuffer)); + Graph_InitTHGA(&gfxCtx->work, pool->workBuffer, sizeof(pool->workBuffer)); + Graph_InitTHGA(&gfxCtx->debug, pool->debugBuffer, sizeof(pool->debugBuffer)); -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_Render.s") + gfxCtx->polyOpaBuffer = pool->polyOpaBuffer; + gfxCtx->polyXluBuffer = pool->polyXluBuffer; + gfxCtx->overlayBuffer = pool->overlayBuffer; + gfxCtx->workBuffer = pool->workBuffer; + gfxCtx->debugBuffer = pool->debugBuffer; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_FrameSetup.s") + gfxCtx->curFrameBuffer = (u16*)SysCfb_GetFbPtr(gfxCtx->framebufferIdx % 2); + gSegments[0x0F] = gfxCtx->curFrameBuffer; -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_RenderFrame.s") + gfxCtx->zbuffer = SysCfb_GetZBuffer(); -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_DoFrame.s") + gSPBranchList(&gGfxMasterDL->disps[0], pool->polyOpaBuffer); + gSPBranchList(&gGfxMasterDL->disps[1], pool->polyXluBuffer); + gSPBranchList(&gGfxMasterDL->disps[2], pool->overlayBuffer); + gSPBranchList(&gGfxMasterDL->disps[3], pool->workBuffer); + gSPEndDisplayList(&gGfxMasterDL->disps[4]); + gSPBranchList(&gGfxMasterDL->debugDisp[0], pool->debugBuffer); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_ThreadEntry.s") +GameStateOverlay* Graph_GetNextGameState(GameState* gameState) { + GameStateFunc gameStateInit = GameState_GetNextStateInit(gameState); + + if (gameStateInit == (GameStateFunc)TitleSetup_Init) { + return &gGameStateOverlayTable[0]; + } + if (gameStateInit == (GameStateFunc)Select_Init) { + return &gGameStateOverlayTable[1]; + } + if (gameStateInit == (GameStateFunc)Title_Init) { + return &gGameStateOverlayTable[2]; + } + if (gameStateInit == (GameStateFunc)Play_Init) { + return &gGameStateOverlayTable[3]; + } + if (gameStateInit == (GameStateFunc)Opening_Init) { + return &gGameStateOverlayTable[4]; + } + if (gameStateInit == (GameStateFunc)FileChoose_Init) { + return &gGameStateOverlayTable[5]; + } + if (gameStateInit == (GameStateFunc)Daytelop_Init) { + return &gGameStateOverlayTable[6]; + } + return NULL; +} + +void* Graph_FaultAddrConvFunc(void* address, void* param) { + 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++) { + diff = VRAM_PTR_SIZE(gamestateOvl); + ramStart = gamestateOvl->loadedRamAddr; + ramConv = (uintptr_t)gamestateOvl->vramStart - (uintptr_t)ramStart; + + if (ramStart != NULL) { + if (addr >= (uintptr_t)ramStart && addr < (uintptr_t)ramStart + diff) { + return addr + ramConv; + } + } + } + return NULL; +} + +void Graph_Init(GraphicsContext* gfxCtx) { + bzero(gfxCtx, sizeof(GraphicsContext)); + gfxCtx->gfxPoolIdx = 0; + gfxCtx->framebufferIdx = 0; + gfxCtx->viMode = NULL; + gfxCtx->viConfigFeatures = gViConfigFeatures; + gfxCtx->xScale = gViConfigXScale; + gfxCtx->yScale = gViConfigYScale; + osCreateMesgQueue(&gfxCtx->queue, gfxCtx->msgBuff, ARRAY_COUNT(gfxCtx->msgBuff)); + Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, NULL, NULL); + Fault_AddAddrConvClient(&sGraphFaultAddrConvClient, Graph_FaultAddrConvFunc, NULL); +} + +void Graph_Destroy(GraphicsContext* gfxCtx) { + Fault_RemoveClient(&sGraphFaultClient); + Fault_RemoveAddrConvClient(&sGraphFaultAddrConvClient); +} + +/** + * Constructs the graphics OSTask and forwards it to the scheduler. + * Waits for up to 3 additional seconds for any current graphics task to complete. + * If it does not signal completion in that time, retry or trigger a crash. + */ +void Graph_TaskSet00(GraphicsContext* gfxCtx, GameState* gameState) { + static s32 retryCount = 10; + static s32 cfbIdx = 0; + OSTask_t* task = &gfxCtx->task.list.t; + OSScTask* scTask = &gfxCtx->task; + OSTimer timer; + OSMesg msg; + CfbInfo* cfb; + +retry: + osSetTimer(&timer, OS_USEC_TO_CYCLES(3 * 1000 * 1000), 0, &gfxCtx->queue, (OSMesg)666); + osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK); + osStopTimer(&timer); + + if (msg == (OSMesg)666) { + osSyncPrintf("GRAPH SP TIMEOUT\n"); + if (retryCount >= 0) { + retryCount--; + Sched_SendGfxCancelMsg(&gSchedContext); + goto retry; + } else { + // graph.c: No more! die! + osSyncPrintf("graph.c:もうダメ!死ぬ!\n"); + Fault_AddHungupAndCrashImpl("RCP is HUNG UP!!", "Oh! MY GOD!!"); + } + } + + gfxCtx->masterList = gGfxMasterDL; + if (gfxCtx->callback != NULL) { + gfxCtx->callback(gfxCtx, gfxCtx->callbackParam); + } + + task->type = M_GFXTASK; + task->flags = OS_SC_DRAM_DLIST; + task->ucodeBoot = SysUcode_GetUCodeBoot(); + task->ucodeBootSize = SysUcode_GetUCodeBootSize(); + task->ucode = SysUcode_GetUCode(); + task->ucodeData = SysUcode_GetUCodeData(); + task->ucodeSize = 0x1000; + task->ucodeDataSize = 0x800; + task->dramStack = (u64*)gGfxSPTaskStack; + task->dramStackSize = sizeof(gGfxSPTaskStack); + task->outputBuff = gGfxSPTaskOutputBufferPtr; + task->outputBuffSize = gGfxSPTaskOutputBufferSize; + task->dataPtr = (u64*)gGfxMasterDL; + task->dataSize = 0; + task->yieldDataPtr = (u64*)gGfxSPTaskYieldBuffer; + task->yieldDataSize = sizeof(gGfxSPTaskYieldBuffer); + + scTask->next = NULL; + scTask->flags = OS_SC_RCP_MASK | OS_SC_SWAPBUFFER | OS_SC_LAST_TASK; + + if (SREG(33) & 1) { + SREG(33) &= ~1; + scTask->flags &= ~OS_SC_SWAPBUFFER; + gfxCtx->framebufferIdx--; + } + + scTask->msgQ = &gfxCtx->queue; + scTask->msg = NULL; + + { s32 pad; } + + cfb = &sGraphCfbInfos[cfbIdx]; + cfbIdx = (cfbIdx + 1) % ARRAY_COUNT(sGraphCfbInfos); + + cfb->fb1 = gfxCtx->curFrameBuffer; + cfb->swapBuffer = gfxCtx->curFrameBuffer; + + if (gfxCtx->updateViMode) { + gfxCtx->updateViMode = false; + cfb->viMode = gfxCtx->viMode; + cfb->features = gfxCtx->viConfigFeatures; + cfb->xScale = gfxCtx->xScale; + cfb->yScale = gfxCtx->yScale; + } else { + cfb->viMode = NULL; + } + cfb->unk_10 = 0; + cfb->updateRate = gameState->framerateDivisor; + + scTask->framebuffer = cfb; + + while (gfxCtx->queue.validCount != 0) { + osRecvMesg(&gfxCtx->queue, NULL, OS_MESG_NOBLOCK); + } + + gfxCtx->schedMsgQ = &gSchedContext.cmdQ; + osSendMesg(&gSchedContext.cmdQ, scTask, OS_MESG_BLOCK); + Sched_SendEntryMsg(&gSchedContext); +} + +void Graph_UpdateGame(GameState* gameState) { + Game_UpdateInput(gameState); + Game_IncrementFrameCount(gameState); + if (SREG(20) < 3) { + func_8019E014(); + } +} + +/** + * Run the gamestate logic, then finalize the gfx buffer + * and run the graphics task for this frame. + */ +void Graph_ExecuteAndDraw(GraphicsContext* gfxCtx, GameState* gameState) { + u32 problem; + + gameState->unk_A3 = 0; + Graph_SetNextGfxPool(gfxCtx); + + Game_Update(gameState); + + OPEN_DISPS(gfxCtx); + + gSPEndDisplayList(WORK_DISP++); + gSPEndDisplayList(POLY_OPA_DISP++); + gSPEndDisplayList(POLY_XLU_DISP++); + gSPEndDisplayList(OVERLAY_DISP++); + gSPEndDisplayList(DEBUG_DISP++); + + CLOSE_DISPS(gfxCtx); + + { + Gfx* gfx = gGfxMasterDL->taskStart; + + gSPSegment(gfx++, 0x0E, gGfxMasterDL); + gSPDisplayList(gfx++, &D_0E000000.disps[3]); + gSPDisplayList(gfx++, &D_0E000000.disps[0]); + gSPDisplayList(gfx++, &D_0E000000.disps[1]); + gSPDisplayList(gfx++, &D_0E000000.disps[2]); + gSPDisplayList(gfx++, &D_0E000000.debugDisp[0]); + + gDPPipeSync(gfx++); + gDPFullSync(gfx++); + gSPEndDisplayList(gfx++); + } + + problem = false; + + { + GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx % 2]; + + if (pool->headMagic != GFXPOOL_HEAD_MAGIC) { + Fault_AddHungupAndCrash("../graph.c", 1054); + } + if (pool->tailMagic != GFXPOOL_TAIL_MAGIC) { + Fault_AddHungupAndCrash("../graph.c", 1066); + } + } + + if (THGA_IsCrash(&gfxCtx->polyOpa)) { + problem = true; + } + if (THGA_IsCrash(&gfxCtx->polyXlu)) { + problem = true; + } + if (THGA_IsCrash(&gfxCtx->overlay)) { + problem = true; + } + if (THGA_IsCrash(&gfxCtx->work)) { + problem = true; + } + if (THGA_IsCrash(&gfxCtx->debug)) { + problem = true; + } + + if (!problem) { + Graph_TaskSet00(gfxCtx, gameState); + gfxCtx->gfxPoolIdx++; + gfxCtx->framebufferIdx++; + } + + { + OSTime time = osGetTime(); + + D_801FBAE8 = sRSPGFXTotalTime; + D_801FBAE0 = gRSPAudioTotalTime; + D_801FBAF0 = gRDPTotalTime; + sRSPGFXTotalTime = 0; + gRSPAudioTotalTime = 0; + gRDPTotalTime = 0; + + if (sGraphTaskStartTime != 0) { + lastRenderFrameDuration = time - sGraphTaskStartTime; + } + sGraphTaskStartTime = time; + } +} + +void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { + gameState->unk_A3 = 0; + + Graph_UpdateGame(gameState); + Graph_ExecuteAndDraw(gfxCtx, gameState); +} + +void Graph_ThreadEntry(void* arg) { + GraphicsContext gfxCtx; + GameStateOverlay* nextOvl = &gGameStateOverlayTable[0]; + GameStateOverlay* ovl; + GameState* gameState; + u32 size; + s32 pad[2]; + + gZBuffer = SystemArena_Malloc(sizeof(*gZBuffer) + sizeof(*gWorkBuffer) + 64 - 1); + gZBuffer = (void*)ALIGN64((u32)gZBuffer); + + gWorkBuffer = (void*)((u8*)gZBuffer + sizeof(*gZBuffer)); + + gGfxSPTaskOutputBuffer2 = gGfxSPTaskOutputBuffer = SystemArena_Malloc(sizeof(*gGfxSPTaskOutputBuffer)); + + gGfxSPTaskOutputBufferEnd = (u8*)gGfxSPTaskOutputBuffer + sizeof(*gGfxSPTaskOutputBuffer); + gGfxSPTaskOutputBufferEnd2 = (u8*)gGfxSPTaskOutputBuffer2 + sizeof(*gGfxSPTaskOutputBuffer2); + + func_80178978(); + Fault_SetFB(D_801FBB90, SCREEN_WIDTH, SCREEN_HEIGHT); + Graph_Init(&gfxCtx); + + while (nextOvl) { + ovl = nextOvl; + + Overlay_LoadGameState(ovl); + + size = ovl->instanceSize; + + func_800809F4(ovl->vromStart); + + gameState = SystemArena_Malloc(size); + + bzero(gameState, size); + GameState_Init(gameState, ovl->init, &gfxCtx); + + while (GameState_IsRunning(gameState)) { + Graph_Update(&gfxCtx, gameState); + } + + nextOvl = Graph_GetNextGameState(gameState); + + if (size) {} + + GameState_Destroy(gameState); + SystemArena_Free(gameState); + + Overlay_FreeGameState(ovl); + } + Graph_Destroy(&gfxCtx); +} diff --git a/src/code/graphalloc.c b/src/code/graphalloc.c new file mode 100644 index 000000000..cbae8ebe4 --- /dev/null +++ b/src/code/graphalloc.c @@ -0,0 +1,29 @@ +#include "global.h" + +Gfx* Graph_GfxPlusOne(Gfx* gfx) { + return &gfx[1]; +} + +Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst) { + gSPBranchList(gfx, dst); + return dst; +} + +/** + * Allocates a structure of `size` into the display list buffer`gfx`, + * returning a pointer to the start of the buffer. + * Since the alloc may not itself be display list commands, a BranchList + * command is used to step over this region. + */ +void* Graph_DlistAlloc(Gfx** gfx, size_t size) { + u8* start; + Gfx* end; + + size = ALIGN8(size); + start = (u8*)&(*gfx)[1]; + end = (Gfx*)(start + size); + gSPBranchList(*gfx, end); + + *gfx = end; + return start; +} diff --git a/src/code/jpegdecoder.c b/src/code/jpegdecoder.c new file mode 100644 index 000000000..336e381f9 --- /dev/null +++ b/src/code/jpegdecoder.c @@ -0,0 +1,193 @@ +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "macros.h" + +u8* sJpegBitStreamPtr; +u32 sJpegBitStreamByteIdx; +u8 sJpegBitStreamBitIdx; +u8 sJpegBitStreamDontSkip; +u32 sJpegBitStreamCurWord; + +s32 JpegDecoder_Decode(JpegDecoder* decoder, u16* mcuBuff, s32 count, u8 isFollowing, JpegDecoderState* state) { + s16 pad; + s16 unk0; + s16 unk1; + s16 unk2; + u32 idx; + s32 inc; + u16 unkCount; + + JpegHuffmanTable* hTable0; + JpegHuffmanTable* hTable1; + JpegHuffmanTable* hTable2; + JpegHuffmanTable* hTable3; + + inc = 0; + sJpegBitStreamPtr = decoder->imageData; + if (decoder->mode == 0) { + unkCount = 2; + } else { + unkCount = 4; + if (decoder->unk_05 == 1) { + inc = 8 * 8 * 2; + } + } + + hTable0 = decoder->hTablePtrs[0]; + hTable1 = decoder->hTablePtrs[1]; + hTable2 = decoder->hTablePtrs[2]; + hTable3 = decoder->hTablePtrs[3]; + + if (!isFollowing) { + sJpegBitStreamByteIdx = 0; + sJpegBitStreamBitIdx = 32; + sJpegBitStreamCurWord = 0; + sJpegBitStreamDontSkip = 0; + unk0 = 0; + unk1 = 0; + unk2 = 0; + } else { + sJpegBitStreamByteIdx = state->byteIdx; + sJpegBitStreamBitIdx = state->bitIdx; + sJpegBitStreamCurWord = state->curWord; + sJpegBitStreamDontSkip = state->dontSkip; + unk0 = state->unk_0C; + unk1 = state->unk_0E; + unk2 = state->unk_10; + } + + while (count != 0) { + for (idx = 0; idx < unkCount; idx++) { + if (JpegDecoder_ProcessMcu(hTable0, hTable1, mcuBuff, &unk0)) { + return 2; + } + mcuBuff += 8 * 8; + } + + if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk1)) { + return 2; + } + mcuBuff += 8 * 8; + + if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk2)) { + return 2; + } + + count--; + mcuBuff += 8 * 8; + mcuBuff += inc; + } + + state->byteIdx = sJpegBitStreamByteIdx; + state->bitIdx = sJpegBitStreamBitIdx; + state->curWord = sJpegBitStreamCurWord; + state->dontSkip = sJpegBitStreamDontSkip; + state->unk_0C = unk0; + state->unk_0E = unk1; + state->unk_10 = unk2; + return 0; +} + +s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, u16* mcu, s16* unk) { + s8 i = 0; + s8 zeroCount; + s16 coeff; + + if (JpegDecoder_ParseNextSymbol(hTable0, &coeff, &zeroCount)) { + return true; + } + + *unk += coeff; + mcu[i++] = *unk; + while (i < 8 * 8) { + if (JpegDecoder_ParseNextSymbol(hTable1, &coeff, &zeroCount)) { + return true; + } + + if (coeff == 0) { + if (zeroCount == 0xF) { + while (zeroCount-- >= 0) { + mcu[i++] = 0; + } + } else { + while (i < 8 * 8) { + mcu[i++] = 0; + } + break; + } + } else { + while (0 < zeroCount--) { + mcu[i++] = 0; + } + mcu[i++] = coeff; + } + } + + return false; +} + +s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount) { + u8 codeIdx; + u8 sym; + u16 codeOff = 0; + u16 buff = JpegDecoder_ReadBits(16); + + for (codeIdx = 0; codeIdx < ARRAY_COUNT(hTable->codesB); codeIdx++) { + if (hTable->codesB[codeIdx] == 0xFFFF) { + continue; + } + + codeOff = buff >> (15 - codeIdx); + if (codeOff <= hTable->codesB[codeIdx]) { + break; + } + } + + if (codeIdx >= ARRAY_COUNT(hTable->codesB)) { + return true; + } + + sym = hTable->symbols[hTable->codeOffs[codeIdx] + codeOff - hTable->codesA[codeIdx]]; + *outZeroCount = sym >> 4; + sym &= 0xF; + + sJpegBitStreamBitIdx += codeIdx - 15; + *outCoeff = 0; + if (sym) { + *outCoeff = JpegDecoder_ReadBits(sym); + if (*outCoeff < (1 << (sym - 1))) { + *outCoeff += (-1 << sym) + 1; + } + } + + return false; +} + +u16 JpegDecoder_ReadBits(u8 len) { + u8 byteCount; + u8 data; + s32 ret; + u32 temp; + ret = 0; // this is required for some reason + + for (byteCount = sJpegBitStreamBitIdx >> 3; byteCount > 0; byteCount--) { + data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++]; + if (sJpegBitStreamDontSkip) { + if (data == 0) { + data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++]; + } + } + + sJpegBitStreamDontSkip = (data == 0xFF) ? true : false; + + sJpegBitStreamCurWord <<= 8; + sJpegBitStreamCurWord |= data; + sJpegBitStreamBitIdx -= 8; + } + + ret = (sJpegBitStreamCurWord << (sJpegBitStreamBitIdx)); + temp = ret; + ret = temp >> -len; + sJpegBitStreamBitIdx += len; + return ret; +} diff --git a/src/code/jpegutils.c b/src/code/jpegutils.c new file mode 100644 index 000000000..904643f46 --- /dev/null +++ b/src/code/jpegutils.c @@ -0,0 +1,155 @@ +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "macros.h" + +void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count) { + u8 i; + + for (i = 0; i < count; i++) { + u8 j; + + dqt++; + for (j = 0; j < ARRAY_COUNT(qt[i].table); j++) { + qt[i].table[j] = *dqt++; + } + } +} + +s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) { + u8 off = 1; + s16 count = 0; + s16 idx = 1; + + while (off <= 16) { + while (idx <= ptr[off - 1]) { + codesLengths[count++] = off; + idx++; + } + idx = 1; + off++; + } + + codesLengths[count] = 0; + return count; +} + +s32 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes) { + s16 idx = 0; + u16 code = 0; + u8 lastLen = codesLengths[0]; + + while (true) { + while (true) { + codes[idx++] = code++; + + if (codesLengths[idx] != lastLen) { + break; + } + } + + if (codesLengths[idx] == 0) { + break; + } + + while (true) { + if (code <<= 1, codesLengths[idx] == ++lastLen) { + break; + } + } + } + + return idx; +} + +s32 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { + u8 idx; + u16 codeOff = 0; + + for (idx = 0; idx < 16; idx++) { + if (data[idx]) { + ht->codeOffs[idx] = codeOff; + ht->codesA[idx] = codes[codeOff]; + codeOff += data[idx] - 1; + ht->codesB[idx] = codes[codeOff]; + codeOff++; + } else { + ht->codesB[idx] = 0xFFFF; + } + } + + return codeOff; +} + +u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc) { + s16 ret; + s32 count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths); + s32 temp; + + ret = count; + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { + return 0; + } + if (ret != JpegUtils_GetHuffmanCodes(codesLengths, codes)) { + return 0; + } + if (temp = JpegUtils_SetHuffmanTable(data, ht, codes), temp != ret) { + return 0; + } + + return ret; +} + +u32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) { + u8 idx; + u32 codeCount; + + for (idx = 0; idx < count; idx++) { + u32 ac = (*dht++ >> 4); + + codeCount = JpegUtils_ProcessHuffmanTableImpl(dht, &ht[idx], codesLengths, codes, ac); + if (codeCount == 0) { + return true; + } + + dht += 16; + ht[idx].symbols = dht; + dht += codeCount; + } + return false; +} + +void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc) { + s16 idx; + u8 a; + + for (idx = 0; idx < count; idx++) { + a = data[idx]; + if (isAc) { + ht->acCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; + } else { + ht->dcCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; + } + } +} + +u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes) { + u8 isAc = *dht++ >> 4; + s16 count2; + s32 count; + + count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths); + + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { + return true; + } + + if (JpegUtils_GetHuffmanCodes(codesLengths, codes) != count2) { + return true; + } + + JpegUtils_SetHuffmanTableOld(dht + 0x10, ht, codesLengths, codes, count2, isAc); + + return false; +} diff --git a/src/code/listalloc.c b/src/code/listalloc.c index da294a109..33f9989ba 100644 --- a/src/code/listalloc.c +++ b/src/code/listalloc.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" ListAlloc* ListAlloc_Init(ListAlloc* this) { this->prev = NULL; diff --git a/src/code/osFlash.c b/src/code/osFlash.c deleted file mode 100644 index e661bc9c7..000000000 --- a/src/code/osFlash.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186A70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186AB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186B78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186CAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186D60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186E64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80186EC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187018.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187080.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_80187284.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_801872FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_801873BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/osFlash/func_8018752C.s") diff --git a/src/code/padmgr.c b/src/code/padmgr.c index a8ef1db15..0d539126a 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -1,4 +1,5 @@ #include "global.h" +#include "ultra64/motor.h" #pragma GLOBAL_ASM("asm/non_matchings/code/padmgr/Padmgr_GetControllerBitmask.s") diff --git a/src/code/sched.c b/src/code/sched.c index a5a3a8558..927a48f66 100644 --- a/src/code/sched.c +++ b/src/code/sched.c @@ -179,7 +179,7 @@ halt_rdp: if (dpTask->type == M_GFXTASK) { // Try to stop DP osSyncPrintf("DP止めようとします\n"); - bzero(dpTask->output_buff, (u32)dpTask->output_buff_size - (u32)dpTask->output_buff); + bzero(dpTask->outputBuff, (u32)dpTask->outputBuffSize - (u32)dpTask->outputBuff); osSendMesg(&sched->interruptQ, RDP_DONE_MSG, OS_MESG_NOBLOCK); } } @@ -225,7 +225,7 @@ s32 Sched_TaskCheckFramebuffers(SchedContext* sched, OSScTask* task) { void* nextFB = osViGetNextFramebuffer(); void* curFB = osViGetCurrentFramebuffer(); - if (task == NULL || sched->pendingSwapBuf1 != NULL || (curFB == task->framebuffer->fb1 && curFB != nextFB)) { + if (task == NULL || sched->pendingSwapBuf1 != NULL || (curFB == TASK_FRAMEBUFFER(task)->fb1 && curFB != nextFB)) { return 0; } return 1; @@ -257,7 +257,7 @@ s32 Sched_Schedule(SchedContext* sched, OSScTask** spTask, OSScTask** dpTask, s3 } } } else if (ret == (OS_SC_SP | OS_SC_DP)) { - if (gfxTask->framebuffer == NULL || Sched_TaskCheckFramebuffers(sched, gfxTask)) { + if (TASK_FRAMEBUFFER(gfxTask) == NULL || Sched_TaskCheckFramebuffers(sched, gfxTask)) { *spTask = *dpTask = gfxTask; ret &= ~(OS_SC_SP | OS_SC_DP); sched->gfxListHead = sched->gfxListHead->next; @@ -271,7 +271,7 @@ s32 Sched_Schedule(SchedContext* sched, OSScTask** spTask, OSScTask** dpTask, s3 } void Sched_TaskUpdateFramebuffer(SchedContext* sched, OSScTask* task) { - sched->pendingSwapBuf1 = task->framebuffer; + sched->pendingSwapBuf1 = TASK_FRAMEBUFFER(task); if (sched->curBuf != NULL && sched->curBuf->updateRate2 > 0) { return; @@ -336,8 +336,8 @@ void Sched_RunTask(SchedContext* sched, OSScTask* spTask, OSScTask* dpTask) { if (spTask->list.t.type == M_AUDTASK) { // Set global pointers to audio task data for use in audio processing - gAudioSPDataPtr = spTask->list.t.data_ptr; - gAudioSPDataSize = spTask->list.t.data_size; + gAudioSPDataPtr = spTask->list.t.dataPtr; + gAudioSPDataSize = spTask->list.t.dataSize; } // Begin task execution @@ -527,7 +527,7 @@ void Sched_FaultClient(void* param1, void* param2) { spTask = sched->curRSPTask; if (spTask != NULL) { FaultDrawer_Printf("RSPTask %08x %08x %02x %02x\n%01x %08x %08x\n", spTask, spTask->next, spTask->state, - spTask->flags, spTask->list.t.type, spTask->list.t.data_ptr, spTask->list.t.data_size); + spTask->flags, spTask->list.t.type, spTask->list.t.dataPtr, spTask->list.t.dataSize); } dpTask = sched->curRDPTask; diff --git a/src/code/speed_meter.c b/src/code/speed_meter.c index b8b0299eb..9f04de110 100644 --- a/src/code/speed_meter.c +++ b/src/code/speed_meter.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/speed_meter/func_80177390.s") diff --git a/src/code/sys_cmpdma.c b/src/code/sys_cmpdma.c index c7317a7b7..2533c44f5 100644 --- a/src/code/sys_cmpdma.c +++ b/src/code/sys_cmpdma.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/func_80178750.s") @@ -8,9 +9,9 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/func_801789D4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/get_framebuffer.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/SysCfb_GetFbPtr.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/get_zbuffer.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/SysCfb_GetZBuffer.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_cmpdma/func_80178A24.s") diff --git a/src/code/sys_flashrom.c b/src/code/sys_flashrom.c index 1431e7a66..8b6c2fa5c 100644 --- a/src/code/sys_flashrom.c +++ b/src/code/sys_flashrom.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/sys_flashrom/func_801857C0.s") diff --git a/src/code/sys_initial_check.c b/src/code/sys_initial_check.c index 7b0a26cc8..ec61d07b5 100644 --- a/src/code/sys_initial_check.c +++ b/src/code/sys_initial_check.c @@ -1,17 +1,125 @@ +/** + * File: sys_initial_check.c + * Description: Functions for checking for the presence of the Expansion Pak and the correct TV type (PAL/NTSC/MPAL), + * and functions for printing error messages directly to screen if not found or incorrect. + * + * These checks are some of the first functions run in Main, before even setting up the system heap, and any image files + * are DMA'd directly to fixed RAM addresses. + */ #include "global.h" +#include "misc/locerrmsg/locerrmsg.h" +#include "misc/memerrmsg/memerrmsg.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_WriteRGBA16Pixel.s") +#define LOCERRMSG_WIDTH 208 +#define LOCERRMSG_HEIGHT 16 +#define NUMBEROF_LOCERRMSGS 1 -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_WriteI4Pixel.s") +#define MEMERRMSG_WIDTH 128 +#define MEMERRMSG_HEIGHT 37 +#define NUMBEROF_MEMERRMSGS 2 -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawI4Texture.s") +#define SIZEOF_LOCERRMSG (LOCERRMSG_WIDTH * LOCERRMSG_HEIGHT / 2 * NUMBEROF_LOCERRMSGS) +#define SIZEOF_MEMERRMSG (MEMERRMSG_WIDTH * MEMERRMSG_HEIGHT / 2 * NUMBEROF_MEMERRMSGS) -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_ClearRGBA16.s") +// Address with enough room after to load either of the error message image files before the fault screen buffer at the +// end of RDRAM +#define CHECK_ERRMSG_STATIC_SEGMENT (u8*)(FAULT_FB_ADDRESS - MAX(SIZEOF_LOCERRMSG, SIZEOF_MEMERRMSG)) -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawExpansionPakErrorMessage.s") +void Check_WriteRGBA16Pixel(u16* buffer, u32 x, u32 y, u32 value) { + if (value & RGBA16_PIXEL_OPAQUE) { + (&buffer[x])[y * SCREEN_WIDTH] = value; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_DrawRegionLockErrorMessage.s") +void Check_WriteI4Pixel(u16* buffer, u32 x, u32 y, u32 value) { + Check_WriteRGBA16Pixel(buffer, x, y, value * GPACK_RGBA5551(16, 16, 16, 0) + GPACK_RGBA5551(12, 12, 12, 1)); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_ExpansionPak.s") +/** + * x and y are the coordinates of the bottom-left corner. + */ +void Check_DrawI4Texture(u16* buffer, s32 x, s32 y, s32 width, s32 height, u8* texture) { + s32 v; + s32 u; + u8 pixelPair; + u8* pixelPairPtr = texture; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_initial_check/Check_RegionIsSupported.s") + // I4 textures are bitpacked 2 pixels per byte, so this writes a pair of pixels in each iteration using bitmasking. + for (v = 0; v < height; v++) { + for (u = 0; u < width; u += 2, pixelPairPtr++) { + pixelPair = *pixelPairPtr; + Check_WriteI4Pixel(buffer, x + u, y + v, pixelPair >> 4); + pixelPair = *pixelPairPtr; + Check_WriteI4Pixel(buffer, x + u + 1, y + v, pixelPair & 0xF); + } + } +} + +void Check_ClearRGBA16(u16* buffer) { + u32 x; + u32 y; + + for (y = 0; y < SCREEN_HEIGHT; y++) { + for (x = 0; x < SCREEN_WIDTH; x++) { + Check_WriteRGBA16Pixel(buffer, x, y, 1); + } + } +} + +/** + * Draw error message textures directly to a screen buffer at the end of normal RDRAM + */ +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, 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); +} + +/** + * Draw error message texture directly to a screen buffer at the end of normal RDRAM + */ +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, LOCERRMSG_WIDTH, LOCERRMSG_HEIGHT, + CHECK_ERRMSG_STATIC_SEGMENT); + osWritebackDCacheAll(); + osViSwapBuffer((u16*)FAULT_FB_ADDRESS); + osViBlack(false); +} + +/** + * If Expansion pak is not installed, display error message until console is turned off + */ +void Check_ExpansionPak(void) { + // Expansion pak installed + if (osMemSize >= 0x800000) { + return; + } + + Check_DrawExpansionPakErrorMessage(); + osDestroyThread(NULL); + while (true) {} +} + +/** + * If region is not NTSC or MPAL, display error message until console is turned off + */ +void Check_RegionIsSupported(void) { + s32 regionSupported = false; + + if ((osTvType == OS_TV_NTSC) || (osTvType == OS_TV_MPAL)) { + regionSupported = true; + } + + if (!regionSupported) { + Check_DrawRegionLockErrorMessage(); + osDestroyThread(NULL); + while (true) {} + } +} diff --git a/src/code/sys_math.c b/src/code/sys_math.c index 9b274c7e2..da4ccc9d2 100644 --- a/src/code/sys_math.c +++ b/src/code/sys_math.c @@ -34,7 +34,7 @@ f32 func_80179400(s32 n) { //! @bug No check for negative argument. Will read the array out-of-bounds if the argument is negative. //! (The OoT version does an unsigned check instead, which will return sFactorialTbl[12] for a negative argument.) - if (n > 12) { + if (n >= ARRAY_COUNT(sFactorialTbl)) { ret = sFactorialTbl[12]; for (i = 13; i <= n; i++) { ret *= i; diff --git a/src/code/sys_math3d.c b/src/code/sys_math3d.c index f607295c1..45b94d569 100644 --- a/src/code/sys_math3d.c +++ b/src/code/sys_math3d.c @@ -2,7 +2,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Normalize.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179678.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PlaneVsLineSegClosestPoint.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_80179798.s") @@ -46,7 +46,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Vec3fMagnitude.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_DistanceSquared.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Vec3fDistSq.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_Distance.s") @@ -60,15 +60,15 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_CrossProduct.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_NormalVector.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_SurfaceNorm.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017A954.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeFaces.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017AA0C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeEdges.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017ABBC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeVertices.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017AD38.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineVsCube.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017B68C.s") @@ -80,57 +80,57 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017B9D8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_NormalizedDistanceFromPlane.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_UDistPlaneToPos.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_NormalizedSignedDistanceFromPlane.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_DistPlaneToPos.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BAD0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYDist.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BD98.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BDE0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BE30.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectDist.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BEE0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017BF8C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C008.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaYIntersect.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C17C.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C1F0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C494.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri2.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C540.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXDist.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C808.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C850.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXIntersect.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C904.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017C980.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaXIntersect.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CB08.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CB7C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZDist.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CEA8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CEF0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaZIntersect.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017CFA4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D020.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZIntersect.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D1AC.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D220.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D2FC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineSegVsPlane.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D404.s") @@ -138,7 +138,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_IsPointInSphere.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D668.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_PointDistToLine2D.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017D7C0.s") @@ -148,7 +148,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017DA24.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereLineSeg.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_LineVsSph.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017DD34.s") @@ -162,7 +162,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017F1A0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereSphere.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_SphVsSph.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_ColSphereSphereIntersect.s") @@ -178,11 +178,11 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3d_ColTriTri.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017F9C0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XZInSphere.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017FA34.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_XYInSphere.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017FAA8.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/Math3D_YZInSphere.s") #pragma GLOBAL_ASM("asm/non_matchings/code/sys_math3d/func_8017FB1C.s") diff --git a/src/code/sys_matrix.c b/src/code/sys_matrix.c index a4d5b9379..f2ed19c38 100644 --- a/src/code/sys_matrix.c +++ b/src/code/sys_matrix.c @@ -1,97 +1,1944 @@ +/** + * @file sys_matrix.c + * @brief: Matrix system that mostly uses a matrix stack, and concerns affine transformations. + * + * @note The RSP matrix format (and hence the `MtxF` format) is column-major: vectors are presumed to be row vectors, + * and matrices as a column of row vectors. This means that, for example, a translation matrix + * \f[ + * \begin{pmatrix} + * 1 & 0 & 0 & x \\ + * 0 & 1 & 0 & y \\ + * 0 & 0 & 1 & z \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * will be stored as + * + * { { 1, 0, 0, 0 }, + * { 0, 1, 0, 0 }, + * { 0, 0, 1, 0 }, + * { x, y, z, 1 }, } + * + * @note As such, we label the elements in column-major order so we can follow the same conventions for multiplying + * matrices as the rest of the world, i.e. that \f$ [AB]_{ij} = \sum_k A_{ik} B_{kj} \f$. + * + * This file is primarily concerned with matrices representing affine transformations, implemented using an augmented + * matrix formalism, + * + * \f[ + * \begin{pmatrix} + * A & b \\ + * 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ A \f$ is a \f$ 3 \times 3 \f$ matrix (the *linear part*) and \f$ b \f$ a \f$ 3 \times 1 \f$ matrix, i.e. a + * 3D vector (the *translation part*), and most of the functions assume that the matrices have this form. + * + * Throughout this file, `mode` indicates whether to multiply the matrix on top of the stack by the new construction + * (APPLY), or to just overwrite it (NEW). + */ + #include "global.h" -void Matrix_StateAlloc(GameState* gameState) { - sMatrixStack = (MtxF*)THA_AllocEndAlign16(&gameState->heap, 0x500); +/* data */ + +// clang-format off +Mtx gIdentityMtx = gdSPDefMtx( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f +); +// clang-format on + +MtxF gIdentityMtxF = { { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, +} }; + +/* bss */ + +MtxF* sMatrixStack; //!< original name: "Matrix_stack" +MtxF* sCurrentMatrix; //!< original name: "Matrix_now" + +#define MATRIX_STACK_SIZE 20 + +/* Stack operations */ + +/** + * @brief Create the matrix stack and set the pointer to the top of it. + * + * @remark original name: "new_Matrix" + */ +void Matrix_Init(GameState* gameState) { + sMatrixStack = THA_AllocEndAlign16(&gameState->heap, MATRIX_STACK_SIZE * sizeof(MtxF)); sCurrentMatrix = sMatrixStack; } -void Matrix_StatePush(void) { +/** + * @brief Place a new matrix on the top of the stack and move the stack pointer up. + * + * @remark original name: "Matrix_push" + */ +void Matrix_Push(void) { MtxF* prev = sCurrentMatrix; sCurrentMatrix++; Matrix_MtxFCopy(sCurrentMatrix, prev); } -void Matrix_StatePop(void) { +/** + * @brief Discard the top matrix on the stack and move stack pointer to the next one down. + * + * @remark original name: "Matrix_pull" + */ +void Matrix_Pop(void) { sCurrentMatrix--; } -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_CopyCurrentState.s") +/** + * @brief Copy the top matrix from the stack. + * + * @param[out] dest Matrix into which to copy. + * + * @remark original name: "Matrix_get" + */ +void Matrix_Get(MtxF* dest) { + Matrix_MtxFCopy(dest, sCurrentMatrix); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_SetCurrentState.s") +/** + * @brief Overwrite the top matrix on the stack. + * + * @param[in] src Matrix from which to copy. + * + * @remark original name: "Matrix_put" + */ +void Matrix_Put(MtxF* src) { + Matrix_MtxFCopy(sCurrentMatrix, src); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_GetCurrentState.s") +/** + * @brief Return pointer to the top of the matrix stack. + * + * @return pointer to top matrix on the stack. + * + * @remark original name: get_Matrix_now + */ +MtxF* Matrix_GetCurrent(void) { + return sCurrentMatrix; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertMatrix.s") +/* General transformation matrix functions */ -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertTranslation.s") +/** + * @brief General multiplication of current by a matrix. + * - APPLY: current * mf -> current + * - NEW: mf -> current + * + * @param mf Matrix to multiply by. + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_mult" + */ +void Matrix_Mult(MtxF* mf, MatrixMode mode) { + MtxF* cmf = Matrix_GetCurrent(); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_Scale.s") + if (mode == MTXMODE_APPLY) { + SkinMatrix_MtxFMtxFMult(cmf, mf, cmf); + } else { + Matrix_MtxFCopy(sCurrentMatrix, mf); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertXRotation_s.s") +/** + * @brief Right-multiply current by a translation matrix T. + * - APPLY: current * T -> current + * - NEW: T -> current + * + * T is given by + * + * \f[ + * \begin{pmatrix} + * 1 & 0 & 0 & x \\ + * 0 & 1 & 0 & y \\ + * 0 & 0 & 1 & z \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} . + * \f] + * + * @param x translation distance in the x direction. + * @param y translation distance in the y direction. + * @param z translation distance in the z direction. + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_translate" + */ +void Matrix_Translate(f32 x, f32 y, f32 z, MatrixMode mode) { + MtxF* cmf = sCurrentMatrix; + f32 tempX; + f32 tempY; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertXRotation_f.s") + if (mode == MTXMODE_APPLY) { + tempX = cmf->xx; + tempY = cmf->xy; + cmf->xw += tempX * x + tempY * y + cmf->xz * z; + tempX = cmf->yx; + tempY = cmf->yy; + cmf->yw += tempX * x + tempY * y + cmf->yz * z; + tempX = cmf->zx; + tempY = cmf->zy; + cmf->zw += tempX * x + tempY * y + cmf->zz * z; + tempX = cmf->wx; + tempY = cmf->wy; + cmf->ww += tempX * x + tempY * y + cmf->wz * z; + } else { + SkinMatrix_SetTranslate(cmf, x, y, z); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_RotateStateAroundXAxis.s") +/** + * @brief Right-multiply by the diagonal scale matrix S = diag(x,y,z,1). + * - APPLY: current * S -> current + * - NEW: S -> current + * + * S is given by + * + * \f[ + * \begin{pmatrix} + * x & 0 & 0 & 0 \\ + * 0 & y & 0 & 0 \\ + * 0 & 0 & z & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} . + * \f] + * + * @param x scale in x direction. + * @param y scale in y direction. + * @param z scale in z direction. + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_scale" + */ +void Matrix_Scale(f32 x, f32 y, f32 z, MatrixMode mode) { + MtxF* cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_SetStateXRotation.s") + if (mode == MTXMODE_APPLY) { + cmf->xx *= x; + cmf->yx *= x; + cmf->zx *= x; + cmf->xy *= y; + cmf->yy *= y; + cmf->zy *= y; + cmf->xz *= z; + cmf->yz *= z; + cmf->zz *= z; + cmf->wx *= x; + cmf->wy *= y; + cmf->wz *= z; + } else { + SkinMatrix_SetScale(cmf, x, y, z); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_RotateY.s") +/** + * @brief Right-multiply by a rotation about the x axis + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * 1 & 0 & 0 & 0 \\ + * 0 & c & -s & 0 \\ + * 0 & s & c & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos x, s = \sin x \f$. + * + * @note The same as Matrix_RotateXF(), but uses a binary angle. + * + * @param x rotation angle (binary). + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_RotateX" + */ +void Matrix_RotateXS(s16 x, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempY; + f32 tempZ; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertYRotation_f.s") + if (mode == MTXMODE_APPLY) { + if (x != 0) { + cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertZRotation_s.s") + sin = Math_SinS(x); + cos = Math_CosS(x); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertZRotation_f.s") + tempY = cmf->xy; + tempZ = cmf->xz; + cmf->xy = tempY * cos + tempZ * sin; + cmf->xz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertRotation.s") + tempY = cmf->yy; + tempZ = cmf->yz; + cmf->yy = tempY * cos + tempZ * sin; + cmf->yz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_JointPosition.s") + tempY = cmf->zy; + tempZ = cmf->zz; + cmf->zy = tempY * cos + tempZ * sin; + cmf->zz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_SetStateRotationAndTranslation.s") + tempY = cmf->wy; + tempZ = cmf->wz; + cmf->wy = tempY * cos + tempZ * sin; + cmf->wz = tempZ * cos - tempY * sin; + } + } else { + cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_ToRSPMatrix.s") + if (x != 0) { + sin = Math_SinS(x); + cos = Math_CosS(x); + } else { + sin = 0.0f; + cos = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_ToMtx.s") + cmf->yx = 0.0f; + cmf->zx = 0.0f; + cmf->wx = 0.0f; + cmf->xy = 0.0f; + cmf->wy = 0.0f; + cmf->xz = 0.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->xx = 1.0f; + cmf->ww = 1.0f; + cmf->yy = cos; + cmf->zz = cos; + cmf->zy = sin; + cmf->yz = -sin; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_NewMtx.s") +// Unused +/** + * @brief Right-multiply by a rotation about the x axis. + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * 1 & 0 & 0 & 0 \\ + * 0 & c & -s & 0 \\ + * 0 & s & c & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos x, s = \sin x \f$. + * + * @note The same as Matrix_RotateXS(), but uses a float angle in radians. + * + * @param x rotation angle (radians). + * @param mode APPLY or NEW. + * + * @remark original name may have been "Matrix_RotateX", but clashed with the previous function. + */ +void Matrix_RotateXF(f32 x, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempY; + f32 tempZ; + f32 zero = 0.0; + f32 one = 1.0; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_AppendToPolyOpaDisp.s") + if (mode == MTXMODE_APPLY) { + if (x != 0) { + cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fByState.s") + sin = sinf(x); + cos = cosf(x); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslation.s") + tempY = cmf->xy; + tempZ = cmf->xz; + cmf->xy = tempY * cos + tempZ * sin; + cmf->xz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledX.s") + tempY = cmf->yy; + tempZ = cmf->yz; + cmf->yy = tempY * cos + tempZ * sin; + cmf->yz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledY.s") + tempY = cmf->zy; + tempZ = cmf->zz; + cmf->zy = tempY * cos + tempZ * sin; + cmf->zz = tempZ * cos - tempY * sin; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledZ.s") + tempY = cmf->wy; + tempZ = cmf->wz; + cmf->wy = tempY * cos + tempZ * sin; + cmf->wz = tempZ * cos - tempY * sin; + } + } else { + cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fXZByCurrentState.s") + if (x != 0) { + sin = sinf(x); + cos = cosf(x); + } else { + sin = zero; + cos = one; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_MtxFCopy.s") + cmf->xx = one; + cmf->yx = zero; + cmf->zx = zero; + cmf->wx = zero; + cmf->xy = zero; + cmf->yy = cos; + cmf->zy = sin; + cmf->wy = zero; + cmf->xz = zero; + cmf->yz = -sin; + cmf->zz = cos; + cmf->wz = zero; + cmf->xw = zero; + cmf->yw = zero; + cmf->zw = zero; + cmf->ww = one; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_FromRSPMatrix.s") +/** + * @brief Right-multiply by a rotation about the x axis. + * current * R -> current + * + * @note Matrix_RotateXF() with mode APPLY. + * + * @param x rotation angle (radians). + */ +void Matrix_RotateXFApply(f32 x) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempY; + f32 tempZ; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fByMatrix.s") + if (x != 0.0f) { + cmf = sCurrentMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_TransposeXYZ.s") + sin = sins(RADF_TO_BINANG(x)) * SHT_MINV; + cos = coss(RADF_TO_BINANG(x)) * SHT_MINV; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_NormalizeXYZ.s") + tempY = cmf->xy; + tempZ = cmf->xz; + cmf->xy = (tempY * cos) + (tempZ * sin); + cmf->xz = (tempZ * cos) - (tempY * sin); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_8018219C.s") + tempY = cmf->yy; + tempZ = cmf->yz; + cmf->yy = (tempY * cos) + (tempZ * sin); + cmf->yz = (tempZ * cos) - (tempY * sin); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_801822C4.s") + tempY = cmf->zy; + tempZ = cmf->zz; + cmf->zy = (tempY * cos) + (tempZ * sin); + cmf->zz = (tempZ * cos) - (tempY * sin); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertRotationAroundUnitVector_f.s") + tempY = cmf->wy; + tempZ = cmf->wz; + cmf->wy = (tempY * cos) + (tempZ * sin); + cmf->wz = (tempZ * cos) - (tempY * sin); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/Matrix_InsertRotationAroundUnitVector_s.s") +/** + * @brief Replace current by a rotation about the x axis. + * R -> current + * + * @note Matrix_RotateXF() with mode NEW. + * + * @param x rotation angle (radians). + */ +void Matrix_RotateXFNew(f32 x) { + MtxF* cmf = sCurrentMatrix; + s32 pad[2]; + f32 sin; + f32 cos; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_80182C90.s") + cmf->xx = 1.0f; + cmf->yx = 0.0f; + cmf->zx = 0.0f; + cmf->wx = 0.0f; + cmf->xy = 0.0f; + cmf->wy = 0.0f; + cmf->xz = 0.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->ww = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_80182CA0.s") + if (x != 0.0f) { + sin = sinf(x); + cos = cosf(x); -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_80182CBC.s") + cmf->yy = cos; + cmf->zz = cos; + cmf->yz = -sin; + cmf->zy = sin; + } else { + cmf->yy = 1.0f; + cmf->zy = 0.0f; + cmf->yz = 0.0f; + cmf->zz = 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_matrix/func_80182CCC.s") +/** + * @brief Right-multiply by a rotation about the y axis + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * c & 0 & s & 0 \\ + * 0 & 1 & 0 & 0 \\ + * -s & 0 & c & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos y, s = \sin y \f$. + * + * @note The same as Matrix_RotateYF(), but uses a binary angle. + * + * @param y rotation angle (binary). + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_RotateY" + */ +void Matrix_RotateYS(s16 y, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempX; + f32 tempZ; + + if (mode == MTXMODE_APPLY) { + if (y != 0) { + cmf = sCurrentMatrix; + + sin = Math_SinS(y); + cos = Math_CosS(y); + + tempX = cmf->xx; + tempZ = cmf->xz; + cmf->xx = tempX * cos - tempZ * sin; + cmf->xz = tempX * sin + tempZ * cos; + + tempX = cmf->yx; + tempZ = cmf->yz; + cmf->yx = tempX * cos - tempZ * sin; + cmf->yz = tempX * sin + tempZ * cos; + + tempX = cmf->zx; + tempZ = cmf->zz; + cmf->zx = tempX * cos - tempZ * sin; + cmf->zz = tempX * sin + tempZ * cos; + + tempX = cmf->wx; + tempZ = cmf->wz; + cmf->wx = tempX * cos - tempZ * sin; + cmf->wz = tempX * sin + tempZ * cos; + } + } else { + cmf = sCurrentMatrix; + + if (y != 0) { + sin = Math_SinS(y); + cos = Math_CosS(y); + } else { + sin = 0.0f; + cos = 1.0f; + } + + cmf->yx = 0.0f; + cmf->wx = 0.0f; + cmf->xy = 0.0f; + cmf->zy = 0.0f; + cmf->wy = 0.0f; + cmf->yz = 0.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->yy = 1.0f; + cmf->ww = 1.0f; + cmf->xx = cos; + cmf->zz = cos; + cmf->zx = -sin; + cmf->xz = sin; + } +} + +/** + * @brief Right-multiply by a rotation about the y axis. + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * c & 0 & s & 0 \\ + * 0 & 1 & 0 & 0 \\ + * -s & 0 & c & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos y, s = \sin y \f$. + * + * @note The same as Matrix_RotateYS(), but uses a float angle in radians. + * + * @param y rotation angle (radians). + * @param mode APPLY or NEW. + * + * @remark original name may have been "Matrix_RotateY", but clashed with the previous function. + */ +void Matrix_RotateYF(f32 y, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempX; + f32 tempZ; + f32 zero = 0.0; + f32 one = 1.0; + + if (mode == MTXMODE_APPLY) { + if (y != 0.0f) { + cmf = sCurrentMatrix; + + sin = sinf(y); + cos = cosf(y); + + tempX = cmf->xx; + tempZ = cmf->xz; + cmf->xx = tempX * cos - tempZ * sin; + cmf->xz = tempX * sin + tempZ * cos; + + tempX = cmf->yx; + tempZ = cmf->yz; + cmf->yx = tempX * cos - tempZ * sin; + cmf->yz = tempX * sin + tempZ * cos; + + tempX = cmf->zx; + tempZ = cmf->zz; + cmf->zx = tempX * cos - tempZ * sin; + cmf->zz = tempX * sin + tempZ * cos; + + tempX = cmf->wx; + tempZ = cmf->wz; + cmf->wx = tempX * cos - tempZ * sin; + cmf->wz = tempX * sin + tempZ * cos; + } + } else { + cmf = sCurrentMatrix; + + if (y != 0.0f) { + sin = sinf(y); + cos = cosf(y); + } else { + cos = one; + sin = zero; + } + + cmf->yx = zero; + cmf->wx = zero; + cmf->xy = zero; + cmf->zy = zero; + cmf->wy = zero; + cmf->yz = zero; + cmf->wz = zero; + cmf->xw = zero; + cmf->yw = zero; + cmf->zw = zero; + cmf->yy = one; + cmf->ww = one; + cmf->xx = cos; + cmf->zz = cos; + cmf->zx = -sin; + cmf->xz = sin; + } +} + +/** + * @brief Right-multiply by a rotation about the z axis. + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * c & -s & 0 & 0 \\ + * s & c & 0 & 0 \\ + * 0 & 0 & 1 & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos z, s = \sin z \f$. + * + * @note The same as Matrix_RotateZF, but uses a binary angle. + * + * @param z rotation angle (binary). + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_RotateZ" + */ +void Matrix_RotateZS(s16 z, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempX; + f32 tempY; + f32 zero = 0.0; + f32 one = 1.0; + + if (mode == MTXMODE_APPLY) { + if (z != 0) { + cmf = sCurrentMatrix; + + sin = Math_SinS(z); + cos = Math_CosS(z); + + tempX = cmf->xx; + tempY = cmf->xy; + cmf->xx = tempX * cos + tempY * sin; + cmf->xy = tempY * cos - tempX * sin; + + tempX = cmf->yx; + tempY = cmf->yy; + cmf->yx = tempX * cos + tempY * sin; + cmf->yy = tempY * cos - tempX * sin; + + tempX = cmf->zx; + tempY = cmf->zy; + cmf->zx = tempX * cos + tempY * sin; + cmf->zy = tempY * cos - tempX * sin; + + tempX = cmf->wx; + tempY = cmf->wy; + cmf->wx = tempX * cos + tempY * sin; + cmf->wy = tempY * cos - tempX * sin; + } + } else { + cmf = sCurrentMatrix; + + if (z != 0) { + sin = Math_SinS(z); + cos = Math_CosS(z); + } else { + sin = zero; + cos = one; + } + + cmf->zx = zero; + cmf->wx = zero; + cmf->zy = zero; + cmf->wy = zero; + cmf->xz = zero; + cmf->yz = zero; + cmf->wz = zero; + cmf->xw = zero; + cmf->yw = zero; + cmf->zw = zero; + cmf->zz = one; + cmf->ww = one; + cmf->xx = cos; + cmf->yy = cos; + cmf->yx = sin; + cmf->xy = -sin; + } +} + +/** + * @brief Right-multiply by a rotation about the z axis. + * - APPLY: current * R -> current + * - NEW: R -> current + * + * R is given by + * + * \f[ + * \begin{pmatrix} + * c & -s & 0 & 0 \\ + * s & c & 0 & 0 \\ + * 0 & 0 & 1 & 0 \\ + * 0 & 0 & 0 & 1 + * \end{pmatrix} + * \f] + * + * where \f$ c = \cos z, s = \sin z \f$. + * + * @note The same as Matrix_RotateYS(), but uses a float angle in radians. + * + * @param z rotation angle (radians). + * @param mode APPLY or NEW. + * + * @remark original name may have been "Matrix_RotateZ", but clashed with the previous function. + */ +void Matrix_RotateZF(f32 z, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 tempX; + f32 tempY; + + if (mode == MTXMODE_APPLY) { + if (z != 0) { + cmf = sCurrentMatrix; + + sin = sinf(z); + cos = cosf(z); + + tempX = cmf->xx; + tempY = cmf->xy; + cmf->xx = tempX * cos + tempY * sin; + cmf->xy = tempY * cos - tempX * sin; + + tempX = cmf->yx; + tempY = cmf->yy; + cmf->yx = tempX * cos + tempY * sin; + cmf->yy = tempY * cos - tempX * sin; + + tempX = cmf->zx; + tempY = cmf->zy; + cmf->zx = tempX * cos + tempY * sin; + cmf->zy = tempY * cos - tempX * sin; + + tempX = cmf->wx; + tempY = cmf->wy; + cmf->wx = tempX * cos + tempY * sin; + cmf->wy = tempY * cos - tempX * sin; + } + } else { + cmf = sCurrentMatrix; + + if (z != 0) { + sin = sinf(z); + cos = cosf(z); + } else { + sin = 0.0f; + cos = 1.0f; + } + + cmf->zx = 0.0f; + cmf->wx = 0.0f; + cmf->zy = 0.0f; + cmf->wy = 0.0f; + cmf->xz = 0.0f; + cmf->yz = 0.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->zz = 1.0f; + cmf->ww = 1.0f; + cmf->xx = cos; + cmf->yy = cos; + cmf->yx = sin; + cmf->xy = -sin; + } +} + +/** + * @brief Rotate using ZYX Tait-Bryan angles. + * - APPLY: current Rz Ry Rx -> current + * - NEW: Rz Ry Rx -> current + * + * This means a (column) vector is first rotated around X, then around Y, then around Z, then (if `mode` is APPLY) gets + * transformed by what the matrix was before adding the ZYX rotation. + * + * See previous functions for the forms of Rz, Ry, Rx + * + * @param x binary angle to rotate about x axis + * @param y binary angle to rotate about y axis + * @param z binary angle to rotate about z axis + * @param mode APPLY or NEW + * + * @remark original name: "Matrix_RotateXYZ", changed to reflect rotation order. + */ +void Matrix_RotateZYX(s16 x, s16 y, s16 z, MatrixMode mode) { + MtxF* cmf = sCurrentMatrix; + f32 temp1; + f32 temp2; + f32 sin; + f32 cos; + + if (mode == MTXMODE_APPLY) { + if (z != 0) { // Added in MM, OoT always follows the nonzero path + sin = Math_SinS(z); + cos = Math_CosS(z); + + temp1 = cmf->xx; + temp2 = cmf->xy; + cmf->xx = temp1 * cos + temp2 * sin; + cmf->xy = temp2 * cos - temp1 * sin; + + temp1 = cmf->yx; + temp2 = cmf->yy; + cmf->yx = temp1 * cos + temp2 * sin; + cmf->yy = temp2 * cos - temp1 * sin; + + temp1 = cmf->zx; + temp2 = cmf->zy; + cmf->zx = temp1 * cos + temp2 * sin; + cmf->zy = temp2 * cos - temp1 * sin; + + temp1 = cmf->wx; + temp2 = cmf->wy; + cmf->wx = temp1 * cos + temp2 * sin; + cmf->wy = temp2 * cos - temp1 * sin; + } + + if (y != 0) { + sin = Math_SinS(y); + cos = Math_CosS(y); + + temp1 = cmf->xx; + temp2 = cmf->xz; + cmf->xx = temp1 * cos - temp2 * sin; + cmf->xz = temp1 * sin + temp2 * cos; + + temp1 = cmf->yx; + temp2 = cmf->yz; + cmf->yx = temp1 * cos - temp2 * sin; + cmf->yz = temp1 * sin + temp2 * cos; + + temp1 = cmf->zx; + temp2 = cmf->zz; + cmf->zx = temp1 * cos - temp2 * sin; + cmf->zz = temp1 * sin + temp2 * cos; + + temp1 = cmf->wx; + temp2 = cmf->wz; + cmf->wx = temp1 * cos - temp2 * sin; + cmf->wz = temp1 * sin + temp2 * cos; + } + + if (x != 0) { + sin = Math_SinS(x); + cos = Math_CosS(x); + + temp1 = cmf->xy; + temp2 = cmf->xz; + cmf->xy = temp1 * cos + temp2 * sin; + cmf->xz = temp2 * cos - temp1 * sin; + + temp1 = cmf->yy; + temp2 = cmf->yz; + cmf->yy = temp1 * cos + temp2 * sin; + cmf->yz = temp2 * cos - temp1 * sin; + + temp1 = cmf->zy; + temp2 = cmf->zz; + cmf->zy = temp1 * cos + temp2 * sin; + cmf->zz = temp2 * cos - temp1 * sin; + + temp1 = cmf->wy; + temp2 = cmf->wz; + cmf->wy = temp1 * cos + temp2 * sin; + cmf->wz = temp2 * cos - temp1 * sin; + } + } else { + SkinMatrix_SetRotateRPY(cmf, x, y, z); + } +} + +/** + * @brief Translate and rotate using ZYX Tait-Bryan angles. + * current T Rz Ry Rx -> current + * + * This means a (column) vector is first rotated around X, then around Y, then around Z, then translated, then gets + * transformed by whatever the matrix was previously. + * + * @param translation vector by which to translate. + * @param rot vector of rotation angles. + * + * @remark original name appears to be "Matrix_softcv3_mult" + */ +void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rot) { + MtxF* cmf = sCurrentMatrix; + f32 sin = Math_SinS(rot->z); + f32 cos = Math_CosS(rot->z); + f32 temp1; + f32 temp2; + + // No check for z != 0, presumably since translation is interleaved. + temp1 = cmf->xx; + temp2 = cmf->xy; + cmf->xw += temp1 * translation->x + temp2 * translation->y + cmf->xz * translation->z; + cmf->xx = temp1 * cos + temp2 * sin; + cmf->xy = temp2 * cos - temp1 * sin; + + temp1 = cmf->yx; + temp2 = cmf->yy; + cmf->yw += temp1 * translation->x + temp2 * translation->y + cmf->yz * translation->z; + cmf->yx = temp1 * cos + temp2 * sin; + cmf->yy = temp2 * cos - temp1 * sin; + + temp1 = cmf->zx; + temp2 = cmf->zy; + cmf->zw += temp1 * translation->x + temp2 * translation->y + cmf->zz * translation->z; + cmf->zx = temp1 * cos + temp2 * sin; + cmf->zy = temp2 * cos - temp1 * sin; + + temp1 = cmf->wx; + temp2 = cmf->wy; + cmf->ww += temp1 * translation->x + temp2 * translation->y + cmf->wz * translation->z; + cmf->wx = temp1 * cos + temp2 * sin; + cmf->wy = temp2 * cos - temp1 * sin; + + if (rot->y != 0) { + sin = Math_SinS(rot->y); + cos = Math_CosS(rot->y); + + temp1 = cmf->xx; + temp2 = cmf->xz; + cmf->xx = temp1 * cos - temp2 * sin; + cmf->xz = temp1 * sin + temp2 * cos; + + temp1 = cmf->yx; + temp2 = cmf->yz; + cmf->yx = temp1 * cos - temp2 * sin; + cmf->yz = temp1 * sin + temp2 * cos; + + temp1 = cmf->zx; + temp2 = cmf->zz; + cmf->zx = temp1 * cos - temp2 * sin; + cmf->zz = temp1 * sin + temp2 * cos; + + temp1 = cmf->wx; + temp2 = cmf->wz; + cmf->wx = temp1 * cos - temp2 * sin; + cmf->wz = temp1 * sin + temp2 * cos; + } + + if (rot->x != 0) { + sin = Math_SinS(rot->x); + cos = Math_CosS(rot->x); + + temp1 = cmf->xy; + temp2 = cmf->xz; + cmf->xy = temp1 * cos + temp2 * sin; + cmf->xz = temp2 * cos - temp1 * sin; + + temp1 = cmf->yy; + temp2 = cmf->yz; + cmf->yy = temp1 * cos + temp2 * sin; + cmf->yz = temp2 * cos - temp1 * sin; + + temp1 = cmf->zy; + temp2 = cmf->zz; + cmf->zy = temp1 * cos + temp2 * sin; + cmf->zz = temp2 * cos - temp1 * sin; + + temp1 = cmf->wy; + temp2 = cmf->wz; + cmf->wy = temp1 * cos + temp2 * sin; + cmf->wz = temp2 * cos - temp1 * sin; + } +} + +/** + * @brief Set current to a general translation and rotation using YXZ Tait-Bryan angles: T Ry Rx Rz -> current + * + * This means a (column) vector is first rotated around Y, then around X, then around Z, then translated, then gets + * transformed by whatever the matrix was previously. + * + * @param x amount to translate in X direction. + * @param y amount to translate in Y direction. + * @param z amount to translate in Z direction. + * @param rot vector of rotation angles. + * + * @remark original name appears to be "Matrix_softcv3_load" + */ +void Matrix_SetTranslateRotateYXZ(f32 x, f32 y, f32 z, Vec3s* rot) { + MtxF* cmf = sCurrentMatrix; + f32 sinY = Math_SinS(rot->y); + f32 cosY = Math_CosS(rot->y); + f32 cosTemp; + f32 sinTemp; + + cmf->xx = cosY; + cmf->zx = -sinY; + cmf->xw = x; + cmf->yw = y; + cmf->zw = z; + cmf->wx = 0.0f; + cmf->wy = 0.0f; + cmf->wz = 0.0f; + cmf->ww = 1.0f; + + if (rot->x != 0) { + sinTemp = Math_SinS(rot->x); + cosTemp = Math_CosS(rot->x); + + cmf->zz = cosY * cosTemp; + cmf->zy = cosY * sinTemp; + cmf->xz = sinY * cosTemp; + cmf->xy = sinY * sinTemp; + cmf->yz = -sinTemp; + cmf->yy = cosTemp; + } else { + cmf->zz = cosY; + cmf->xz = sinY; + cmf->yz = 0.0f; + cmf->zy = 0.0f; + cmf->xy = 0.0f; + cmf->yy = 1.0f; + } + + if (rot->z != 0) { + sinTemp = Math_SinS(rot->z); + cosTemp = Math_CosS(rot->z); + + sinY = cmf->xx; + cosY = cmf->xy; + cmf->xx = sinY * cosTemp + cosY * sinTemp; + cmf->xy = cosY * cosTemp - sinY * sinTemp; + + sinY = cmf->zx; + cosY = cmf->zy; + cmf->zx = sinY * cosTemp + cosY * sinTemp; + cmf->zy = cosY * cosTemp - sinY * sinTemp; + + cosY = cmf->yy; + cmf->yx = cosY * sinTemp; + cmf->yy = cosY * cosTemp; + } else { + cmf->yx = 0.0f; + } +} + +/** + * @brief Converts a floating-point MtxF to a fixed-point RSP-compatible matrix. + * + * @param[in] src MtxF to convert. + * @param[out] dest mtx to output to. + * + * @return dest + * + * @remark original name: "_MtxF_to_Mtx" + */ +Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest) { + s32 temp; + u16* intPart = (u16*)&dest->m[0][0]; + u16* fracPart = (u16*)&dest->m[2][0]; + + // For some reason the first 9 elements use the intPart temp for the fractional part. + temp = src->xx * 0x10000; + intPart[0] = (temp >> 0x10); + intPart[16 + 0] = temp; + + temp = src->yx * 0x10000; + intPart[1] = (temp >> 0x10); + intPart[16 + 1] = temp; + + temp = src->zx * 0x10000; + intPart[2] = (temp >> 0x10); + intPart[16 + 2] = temp; + + temp = src->wx * 0x10000; + intPart[3] = (temp >> 0x10); + intPart[16 + 3] = temp; + + temp = src->xy * 0x10000; + intPart[4] = (temp >> 0x10); + intPart[16 + 4] = temp; + + temp = src->yy * 0x10000; + intPart[5] = (temp >> 0x10); + intPart[16 + 5] = temp; + + temp = src->zy * 0x10000; + intPart[6] = (temp >> 0x10); + intPart[16 + 6] = temp; + + temp = src->wy * 0x10000; + intPart[7] = (temp >> 0x10); + intPart[16 + 7] = temp; + + temp = src->xz * 0x10000; + intPart[8] = (temp >> 0x10); + intPart[16 + 8] = temp; + + temp = src->yz * 0x10000; + intPart[9] = (temp >> 0x10); + fracPart[9] = temp; + + temp = src->zz * 0x10000; + intPart[10] = (temp >> 0x10); + fracPart[10] = temp; + + temp = src->wz * 0x10000; + intPart[11] = (temp >> 0x10); + fracPart[11] = temp; + + temp = src->xw * 0x10000; + intPart[12] = (temp >> 0x10); + fracPart[12] = temp; + + temp = src->yw * 0x10000; + intPart[13] = (temp >> 0x10); + fracPart[13] = temp; + + temp = src->zw * 0x10000; + intPart[14] = (temp >> 0x10); + fracPart[14] = temp; + + temp = src->ww * 0x10000; + intPart[15] = (temp >> 0x10); + fracPart[15] = temp; + + return dest; +} + +/** + * @brief Converts current to a fixed-point RSP-compatible matrix. + * + * @note Debug uses Matrix_CheckFloats to test current first. + * + * @param[out] dest mtx to output to. + * + * @return dest + * + * @remark original name: "_Matrix_to_Mtx" + */ +Mtx* Matrix_ToMtx(Mtx* dest) { + return Matrix_MtxFToMtx(sCurrentMatrix, dest); +} + +/** + * @brief Converts current to a RSP-compatible matrix and saves it to allocated space in the OPA buffer. + * + * @param[in,out] gfxCtx Graphics context. + * + * @return allocated mtx. + * + * @remark original name: "_Matrix_to_Mtx_new" + */ +Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx) { + return Matrix_ToMtx(GRAPH_ALLOC(gfxCtx, sizeof(Mtx))); +} + +// Unused +/** + * @brief Converts src to a RSP-compatible matrix and saves it to allocated space in the OPA buffer. + * + * @param[in] src MtxF to convert. + * @param[in,out] gfxCtx Graphics context. + * + * @return allocated mtx. + * + * @remark original name unknown, likely close to "_Matrix_MtxF_to_Mtx_new" + */ +Mtx* Matrix_MtxFToNewMtx(MtxF* src, GraphicsContext* gfxCtx) { + return Matrix_MtxFToMtx(src, GRAPH_ALLOC(gfxCtx, sizeof(Mtx))); +} + +/** + * @brief Calculates current * (src,1) and writes its components to dest. + * + * This assumes that current has the form + * + * \f[ + * M = + * \begin{pmatrix} + * A & b \\ + * 0 & 1 + * \end{pmatrix} + * \f] + * + * where A is \f$ 3 \times 3 \f$ and b \f$ 3 \times 1 \f$, and so calculates + * + * \f[ + * MX = + * \begin{pmatrix} + * A & b \\ + * 0 & 1 + * \end{pmatrix} + * \begin{pmatrix} + * x \\ + * 1 + * \end{pmatrix} + * = + * \begin{pmatrix} + * Ax + b \\ + * 1 + * \end{pmatrix} + * \f] + * + * and discards the extra w component (1). + * + * @param[in] src input vector + * @param[out] dest output vector + * + * @remark original name: "Matrix_Position" + */ +void Matrix_MultVec3f(Vec3f* src, Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw + (cmf->xx * src->x + cmf->xy * src->y + cmf->xz * src->z); + dest->y = cmf->yw + (cmf->yx * src->x + cmf->yy * src->y + cmf->yz * src->z); + dest->z = cmf->zw + (cmf->zx * src->x + cmf->zy * src->y + cmf->zz * src->z); +} + +/** + * @brief Multiply the vector `(0, 0, 0, 1)` by current. + * + * Can also see it as obtaining the translation vector part of current, but the former interpretation is consistent with + * the other functions nearby. + * + * @note Special case of Matrix_MultVec3f() with `src = { 0, 0, 0 }`; the same assumptions apply. + * + * @param[out] dest output vector. + * + * @remark original name: "Matrix_Position_Zero" + */ +void Matrix_MultZero(Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw; + dest->y = cmf->yw; + dest->z = cmf->zw; +} + +/** + * @brief Multiply the vector `(x, 0, 0, 1)` by current. + * + * I.e. calculate \f$ A(x, 0, 0) + b \f$. + * + * @note Special case of Matrix_MultVec3f() with `src = { x, 0, 0 }`; the same assumptions apply. + * + * @param[in] x multiplier of unit vector in x direction. + * @param[out] dest output vector. + * + * @remark original name: "Matrix_Position_VecX" + */ +void Matrix_MultVecX(f32 x, Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw + cmf->xx * x; + dest->y = cmf->yw + cmf->yx * x; + dest->z = cmf->zw + cmf->zx * x; +} + +/** + * @brief Multiply the vector `(0, y, 0, 1)` by current. + * + * I.e. calculate \f$ A(0, y, 0) + b \f$. + * + * @note Special case of Matrix_MultVec3f() with `src = { 0, y, 0 }`; the same assumptions apply. + * + * @param[in] y multiplier of unit vector in y direction. + * @param[out] dest output vector. + * + * @remark original name is most likely "Matrix_Position_VecY" by analogy with the other two. + */ +void Matrix_MultVecY(f32 y, Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw + cmf->xy * y; + dest->y = cmf->yw + cmf->yy * y; + dest->z = cmf->zw + cmf->zy * y; +} + +/** + * @brief Multiply the vector `(0, 0, z, 1)` by current. + * + * I.e. calculate \f$ A(0, 0, z) + b \f$. + * + * @note Special case of Matrix_MultVec3f() with `src = { 0, 0, z }`; the same assumptions apply. + * + * @param[in] z multiplier of unit vector in z direction. + * @param[out] dest output vector. + * + * @remark original name: "Matrix_Position_VecZ" + */ +void Matrix_MultVecZ(f32 z, Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw + cmf->xz * z; + dest->y = cmf->yw + cmf->yz * z; + dest->z = cmf->zw + cmf->zz * z; +} + +/** + * @brief Calculates current * (src,1) and writes its x and z components to dest. + * + * The same as Matrix_MultVec3f(), but only applies to the x and z components; the same assumptions apply. + * + * @note Unlike the previous functions, does *not* just multiply (x, 0, z, 1) and save the x,y,z components. + * + * @param[in] src input vector. + * @param[out] dest output vector. + */ +void Matrix_MultVec3fXZ(Vec3f* src, Vec3f* dest) { + MtxF* cmf = sCurrentMatrix; + + dest->x = cmf->xw + (cmf->xx * src->x + cmf->xy * src->y + cmf->xz * src->z); + dest->z = cmf->zw + (cmf->zx * src->x + cmf->zy * src->y + cmf->zz * src->z); +} + +/** + * @brief Copies the matrix src into dest. + * + * @param[out] dest matrix to copy to. + * @param[in] src matrix to copy from. + * + * @remark original name: "Matrix_copy_MtxF" + */ +void Matrix_MtxFCopy(MtxF* dest, MtxF* src) { + f32 fv0; + f32 fv1; + + // This ought to be a loop, but all attempts to match it as one have so far failed. + if (1) { + fv0 = src->mf[0][0]; + fv1 = src->mf[0][1]; + dest->mf[0][0] = fv0; + dest->mf[0][1] = fv1; + fv0 = src->mf[0][2]; + fv1 = src->mf[0][3]; + dest->mf[0][2] = fv0; + dest->mf[0][3] = fv1; + } + if (1) { + fv0 = src->mf[1][0]; + fv1 = src->mf[1][1]; + dest->mf[1][0] = fv0; + dest->mf[1][1] = fv1; + fv0 = src->mf[1][2]; + fv1 = src->mf[1][3]; + dest->mf[1][2] = fv0; + dest->mf[1][3] = fv1; + } + if (1) { + fv0 = src->mf[2][0]; + fv1 = src->mf[2][1]; + dest->mf[2][0] = fv0; + dest->mf[2][1] = fv1; + fv0 = src->mf[2][2]; + fv1 = src->mf[2][3]; + dest->mf[2][2] = fv0; + dest->mf[2][3] = fv1; + } + if (1) { + fv0 = src->mf[3][0]; + fv1 = src->mf[3][1]; + dest->mf[3][0] = fv0; + dest->mf[3][1] = fv1; + fv0 = src->mf[3][2]; + fv1 = src->mf[3][3]; + dest->mf[3][2] = fv0; + dest->mf[3][3] = fv1; + } +} + +/** + * @brief Converts fixed-point RSP-compatible matrix to an MtxF. + * + * @param[in] src mtx to convert + * @param[out] dest MtxF to output to + * + * @remark original name: "Matrix_MtxtoMtxF" + */ +void Matrix_MtxToMtxF(Mtx* src, MtxF* dest) { + u16* intPart = (u16*)&src->m[0][0]; + u16* fracPart = (u16*)&src->m[2][0]; + + dest->xx = ((intPart[0] << 0x10) | fracPart[0]) * (1 / (f32)0x10000); + dest->yx = ((intPart[1] << 0x10) | fracPart[1]) * (1 / (f32)0x10000); + dest->zx = ((intPart[2] << 0x10) | fracPart[2]) * (1 / (f32)0x10000); + dest->wx = ((intPart[3] << 0x10) | fracPart[3]) * (1 / (f32)0x10000); + dest->xy = ((intPart[4] << 0x10) | fracPart[4]) * (1 / (f32)0x10000); + dest->yy = ((intPart[5] << 0x10) | fracPart[5]) * (1 / (f32)0x10000); + dest->zy = ((intPart[6] << 0x10) | fracPart[6]) * (1 / (f32)0x10000); + dest->wy = ((intPart[7] << 0x10) | fracPart[7]) * (1 / (f32)0x10000); + dest->xz = ((intPart[8] << 0x10) | fracPart[8]) * (1 / (f32)0x10000); + dest->yz = ((intPart[9] << 0x10) | fracPart[9]) * (1 / (f32)0x10000); + dest->zz = ((intPart[10] << 0x10) | fracPart[10]) * (1 / (f32)0x10000); + dest->wz = ((intPart[11] << 0x10) | fracPart[11]) * (1 / (f32)0x10000); + dest->xw = ((intPart[12] << 0x10) | fracPart[12]) * (1 / (f32)0x10000); + dest->yw = ((intPart[13] << 0x10) | fracPart[13]) * (1 / (f32)0x10000); + dest->zw = ((intPart[14] << 0x10) | fracPart[14]) * (1 / (f32)0x10000); + dest->ww = ((intPart[15] << 0x10) | fracPart[15]) * (1 / (f32)0x10000); +} + +// Unused +/** + * @brief Calculates mf * (src,1) and writes its components to dest. + * + * This is the same as Matrix_MultVec3f() but using a specified matrix rather than the current one; the same + * assumptions apply. + * + * @param[in] src input vector + * @param[out] dest output vector + * @param[in] mf matrix to multiply by + */ +void Matrix_MultVec3fExt(Vec3f* src, Vec3f* dest, MtxF* mf) { + dest->x = mf->xw + (mf->xx * src->x + mf->xy * src->y + mf->xz * src->z); + dest->y = mf->yw + (mf->yx * src->x + mf->yy * src->y + mf->yz * src->z); + dest->z = mf->zw + (mf->zx * src->x + mf->zy * src->y + mf->zz * src->z); +} + +/** + * @brief Overwrite the linear part of mf with its transpose (ignores the translational part). + * + * Viz., + * + * \f[ + * \begin{pmatrix} + * A & b \\ + * 0 & 1 + * \end{pmatrix} + * \longrightarrow + * \begin{pmatrix} + * A^T & b \\ + * 0 & 1 + * \end{pmatrix} + * \f] + * + * @param[in,out] mf matrix to transpose + * + * @remark original name: "Matrix_reverse" + */ +void Matrix_Transpose(MtxF* mf) { + f32 temp; + + temp = mf->yx; + mf->yx = mf->xy; + mf->xy = temp; + + temp = mf->zx; + mf->zx = mf->xz; + mf->xz = temp; + + temp = mf->zy; + mf->zy = mf->yz; + mf->yz = temp; +} + +/** + * @brief Decompose the linear part A of current into B * S, where B has normalised columns and S is diagonal, and + * replace B by `mf`. + * + * Since B is typically a rotation matrix, and the linear part R * S to `mf` * S, this operation can be + * seen as replacing the B rotation with `mf`, hence the function name. + * + * @param[in] mf matrix whose linear part will replace the normalised part of A. + */ +void Matrix_ReplaceRotation(MtxF* mf) { + MtxF* cmf = sCurrentMatrix; + f32 acc; + f32 component; + f32 curColNorm; + + // compute the Euclidean norm of the first column of the current matrix + acc = cmf->xx; + acc *= acc; + component = cmf->yx; + acc += SQ(component); + component = cmf->zx; + acc += SQ(component); + curColNorm = sqrtf(acc); + + cmf->xx = mf->xx * curColNorm; + cmf->yx = mf->yx * curColNorm; + cmf->zx = mf->zx * curColNorm; + + // second column + acc = cmf->xy; + acc *= acc; + component = cmf->yy; + acc += SQ(component); + component = cmf->zy; + acc += SQ(component); + curColNorm = sqrtf(acc); + + cmf->xy = mf->xy * curColNorm; + cmf->yy = mf->yy * curColNorm; + cmf->zy = mf->zy * curColNorm; + + // third column + acc = cmf->xz; + acc *= acc; + component = cmf->yz; + acc += SQ(component); + component = cmf->zz; + acc += SQ(component); + curColNorm = sqrtf(acc); + + cmf->xz = mf->xz * curColNorm; + cmf->yz = mf->yz * curColNorm; + cmf->zz = mf->zz * curColNorm; +} + +/** + * @brief Extract the YXZ Tait-Bryan rotation angles from the linear part \f$ A \f$ of a matrix. + * + * \f$ A \f$ should have orthogonal columns; the most general matrix of this form can be written as \f$ RS \f$ + * with \f$ S \f$ a scale matrix. + * + * If A has columns with the same norm (such as if it is just a rotation matrix), it is sufficient (and faster) to use + * `nonUniformScale` off: `nonUniformScale` being set enables extraction of the angles from a matrix with columns that + * are orthogonal but have different scales, at the cost of requiring extra calculation. + * + * @param[in] src Matrix to extract angles from. + * @param[out] dest vector to write angles to. + * @param[in] nonUniformScale boolean: true enables handling matrices with differently-scaled columns. + * + * @remark original name: "Matrix_to_rotate_new"? + */ +void Matrix_MtxFToYXZRot(MtxF* src, Vec3s* dest, s32 nonUniformScale) { + f32 temp; + f32 temp2; + f32 temp3; + f32 temp4; + + temp = src->xz; + temp *= temp; + temp += SQ(src->zz); + dest->x = Math_Atan2S(-src->yz, sqrtf(temp)); + + if ((dest->x == 0x4000) || (dest->x == -0x4000)) { + // cos(x) = 0 if either of these is true, and we get gimbal locking + // (https://en.wikipedia.org/wiki/Gimbal_lock#Loss_of_a_degree_of_freedom_with_Euler_angles); fix z to make y + // well-defined. + dest->z = 0; + + dest->y = Math_Atan2S(-src->zx, src->xx); + } else { + dest->y = Math_Atan2S(src->xz, src->zz); + + if (!nonUniformScale) { + // assume the columns have the same normalisation + dest->z = Math_Atan2S(src->yx, src->yy); + } else { + temp = src->xx; + temp2 = src->zx; + temp3 = src->zy; + + // find norm of the first column + temp *= temp; + temp += SQ(temp2); + temp2 = src->yx; + temp += SQ(temp2); + // temp = xx^2+zx^2+yx^2 == 1 for a rotation matrix + temp = sqrtf(temp); + temp = temp2 / temp; // yx in normalised column + + // find norm of the second column + temp2 = src->xy; + temp2 *= temp2; + temp2 += SQ(temp3); + temp3 = src->yy; + temp2 += SQ(temp3); + // temp2 = xy^2+zy^2+yy^2 == 1 for a rotation matrix + temp2 = sqrtf(temp2); + temp2 = temp3 / temp2; // yy in normalised column + + // for a rotation matrix, temp == yx and temp2 == yy which is the same as in the !nonUniformScale branch + dest->z = Math_Atan2S(temp, temp2); + } + } +} + +/** + * @brief Extract the ZYX Tait-Bryan rotation angles from the linear part \f$ A \f$ of a matrix. + * + * \f$ A \f$ should have orthogonal columns; the most general matrix of this form can be written as \f$ RS \f$ + * with \f$ S \f$ a scale matrix. + * + * If A has columns with the same norm (such as if it is just a rotation matrix), it is sufficient (and faster) to use + * `nonUniformScale` off: `nonUniformScale` being set enables extraction of the angles from a matrix with columns that + * are orthogonal but have different scales, at the cost of requiring extra calculation. + * + * @param[in] src Matrix to extract angles from. + * @param[out] dest vector to write angles to. + * @param[in] nonUniformScale boolean: true enables handling matrices with unnormalised columns. + * + * @remark original name: "Matrix_to_rotate2_new"? + * + * See Matrix_MtxFToYXZRot() for full inline documentation. + */ +void Matrix_MtxFToZYXRot(MtxF* src, Vec3s* dest, s32 nonUniformScale) { + f32 temp; + f32 temp2; + f32 temp3; + f32 temp4; + + temp = src->xx; + temp *= temp; + temp += SQ(src->yx); + dest->y = Math_Atan2S(-src->zx, sqrtf(temp)); + + if ((dest->y == 0x4000) || (dest->y == -0x4000)) { + dest->x = 0; + dest->z = Math_Atan2S(-src->xy, src->yy); + } else { + dest->z = Math_Atan2S(src->yx, src->xx); + + if (!nonUniformScale) { + dest->x = Math_Atan2S(src->zy, src->zz); + } else { + temp = src->xy; + temp2 = src->yy; + temp3 = src->yz; + + temp *= temp; + temp += SQ(temp2); + temp2 = src->zy; + temp += SQ(temp2); + temp = sqrtf(temp); + temp = temp2 / temp; + + temp2 = src->xz; + temp2 *= temp2; + temp2 += SQ(temp3); + temp3 = src->zz; + temp2 += SQ(temp3); + temp2 = sqrtf(temp2); + temp2 = temp3 / temp2; + + dest->x = Math_Atan2S(temp, temp2); + } + } +} + +/** + * @brief Rotate by `angle` radians about `axis`, which is assumed to be a unit vector. + * + * @param angle rotation angle (radians). + * @param axis axis about which to rotate, must be a unit vector. + * @param mode APPLY or NEW. + * + * @remark original name may have been "Matrix_RotateVector", but clashed with the next function. + */ +void Matrix_RotateAxisF(f32 angle, Vec3f* axis, MatrixMode mode) { + MtxF* cmf; + f32 sin; + f32 cos; + f32 versin; + f32 temp1; + f32 temp2; + f32 temp3; + f32 temp4; + f32 temp5; + + if (mode == MTXMODE_APPLY) { + if (angle != 0) { + cmf = sCurrentMatrix; + + sin = sinf(angle); + cos = cosf(angle); + + temp1 = cmf->xx; + temp2 = cmf->xy; + temp3 = cmf->xz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->xx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->xy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->xz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + + temp1 = cmf->yx; + temp2 = cmf->yy; + temp3 = cmf->yz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->yx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->yy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->yz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + + temp1 = cmf->zx; + temp2 = cmf->zy; + temp3 = cmf->zz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->zx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->zy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->zz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + } + } else { + cmf = sCurrentMatrix; + + if (angle != 0) { + sin = sinf(angle); + cos = cosf(angle); + versin = 1.0f - cos; + + cmf->xx = axis->x * axis->x * versin + cos; + cmf->yy = axis->y * axis->y * versin + cos; + cmf->zz = axis->z * axis->z * versin + cos; + + if (0) {} + + temp2 = axis->x * versin * axis->y; + temp3 = axis->z * sin; + cmf->yx = temp2 + temp3; + cmf->xy = temp2 - temp3; + + temp2 = axis->x * versin * axis->z; + temp3 = axis->y * sin; + cmf->zx = temp2 - temp3; + cmf->xz = temp2 + temp3; + + temp2 = axis->y * versin * axis->z; + temp3 = axis->x * sin; + cmf->zy = temp2 + temp3; + cmf->yz = temp2 - temp3; + + cmf->wx = cmf->wy = cmf->wz = cmf->xw = cmf->yw = cmf->zw = 0.0f; + cmf->ww = 1.0f; + } else { + cmf->xx = 1.0f; + cmf->yx = 0.0f; + cmf->zx = 0.0f; + cmf->wx = 0.0f; + cmf->xy = 0.0f; + cmf->yy = 1.0f; + cmf->zy = 0.0f; + cmf->wy = 0.0f; + cmf->xz = 0.0f; + cmf->yz = 0.0f; + cmf->zz = 1.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->ww = 1.0f; + } + } +} + +/** + * @brief Rotate by binary angle `angle` about `axis`, which is assumed to be a unit vector. + * + * @param angle rotation angle (binary). + * @param axis axis about which to rotate, must be a unit vector. + * @param mode APPLY or NEW. + * + * @remark original name: "Matrix_RotateVector" + */ +void Matrix_RotateAxisS(s16 angle, Vec3f* axis, MatrixMode mode) { + MtxF* cmf; + f32 cos; + f32 sin; + f32 versin; + f32 temp1; + f32 temp2; + f32 temp3; + f32 temp4; + + if (mode == MTXMODE_APPLY) { + if (angle != 0) { + cmf = sCurrentMatrix; + + sin = Math_SinS(angle); + cos = Math_CosS(angle); + + temp1 = cmf->xx; + temp2 = cmf->xy; + temp3 = cmf->xz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->xx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->xy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->xz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + + temp1 = cmf->yx; + temp2 = cmf->yy; + temp3 = cmf->yz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->yx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->yy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->yz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + + temp1 = cmf->zx; + temp2 = cmf->zy; + temp3 = cmf->zz; + temp4 = (axis->x * temp1 + axis->y * temp2 + axis->z * temp3) * (1.0f - cos); + cmf->zx = temp1 * cos + axis->x * temp4 + sin * (temp2 * axis->z - temp3 * axis->y); + cmf->zy = temp2 * cos + axis->y * temp4 + sin * (temp3 * axis->x - temp1 * axis->z); + cmf->zz = temp3 * cos + axis->z * temp4 + sin * (temp1 * axis->y - temp2 * axis->x); + } + } else { + cmf = sCurrentMatrix; + + if (angle != 0) { + sin = Math_SinS(angle); + cos = Math_CosS(angle); + versin = 1.0f - cos; + + cmf->xx = axis->x * axis->x * versin + cos; + cmf->yy = axis->y * axis->y * versin + cos; + cmf->zz = axis->z * axis->z * versin + cos; + + if (0) {} + + temp2 = axis->x * versin * axis->y; + temp3 = axis->z * sin; + cmf->yx = temp2 + temp3; + cmf->xy = temp2 - temp3; + + temp2 = axis->x * versin * axis->z; + temp3 = axis->y * sin; + cmf->zx = temp2 - temp3; + cmf->xz = temp2 + temp3; + + temp2 = axis->y * versin * axis->z; + temp3 = axis->x * sin; + cmf->zy = temp2 + temp3; + cmf->yz = temp2 - temp3; + + cmf->wx = cmf->wy = cmf->wz = cmf->xw = cmf->yw = cmf->zw = 0.0f; + cmf->ww = 1.0f; + } else { + cmf->xx = 1.0f; + cmf->yx = 0.0f; + cmf->zx = 0.0f; + cmf->wx = 0.0f; + cmf->xy = 0.0f; + cmf->yy = 1.0f; + cmf->zy = 0.0f; + cmf->wy = 0.0f; + cmf->xz = 0.0f; + cmf->yz = 0.0f; + cmf->zz = 1.0f; + cmf->wz = 0.0f; + cmf->xw = 0.0f; + cmf->yw = 0.0f; + cmf->zw = 0.0f; + cmf->ww = 1.0f; + } + } +} diff --git a/src/code/sys_ucode.c b/src/code/sys_ucode.c index 973606702..f9433eab2 100644 --- a/src/code/sys_ucode.c +++ b/src/code/sys_ucode.c @@ -1,7 +1,30 @@ +/* + * 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/func_80182CE0.s") +extern u64 rspbootTextStart[]; +extern u64 rspbootTextEnd[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/func_80183020.s") +extern u64 gspF3DZEX2_NoN_PosLight_fifoTextStart[]; +extern u64 gspF3DZEX2_NoN_PosLight_fifoDataStart[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/func_80183058.s") +u64* initialgspUcodeText = gspF3DZEX2_NoN_PosLight_fifoTextStart; +u64* initialgspUcodeData = gspF3DZEX2_NoN_PosLight_fifoDataStart; + +u64* SysUcode_GetUCodeBoot(void) { + return rspbootTextStart; +} + +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/title_setup.c b/src/code/title_setup.c index 324f8df3e..69790b60c 100644 --- a/src/code/title_setup.c +++ b/src/code/title_setup.c @@ -47,7 +47,7 @@ void TitleSetup_GameStateResetContext(void) { void TitleSetup_InitImpl(GameState* gameState) { func_80185908(); - func_800E9360(); + SaveContext_Init(); TitleSetup_GameStateResetContext(); gameState->running = 0; @@ -62,6 +62,6 @@ void TitleSetup_Destroy(GameState* gameState) { } void TitleSetup_Init(GameState* gameState) { - gameState->destroy = &TitleSetup_Destroy; + gameState->destroy = TitleSetup_Destroy; TitleSetup_InitImpl(gameState); } diff --git a/src/code/z_DLF.c b/src/code/z_DLF.c index 688a5af15..4c57aca01 100644 --- a/src/code/z_DLF.c +++ b/src/code/z_DLF.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_DLF/Overlay_LoadGameState.s") diff --git a/src/code/z_actor.c b/src/code/z_actor.c index 8d87e539b..a7ab81f77 100644 --- a/src/code/z_actor.c +++ b/src/code/z_actor.c @@ -1,7 +1,44 @@ +/* + * File: z_actor.c + * Description: + */ + #include "global.h" +#include "overlays/actors/ovl_En_Horse/z_en_horse.h" +#include "overlays/actors/ovl_En_Part/z_en_part.h" +#include "overlays/actors/ovl_En_Box/z_en_box.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_bdoor/object_bdoor.h" + +// bss +extern FaultClient sActorFaultClient; // 2 funcs +extern CollisionPoly* D_801ED8B0; // 1 func +extern s32 D_801ED8B4; // 2 funcs +extern Actor* D_801ED8B8; // 2 funcs +extern Actor* D_801ED8BC; // 2 funcs +extern Actor* D_801ED8C0; // 2 funcs +extern Actor* D_801ED8C4; // 2 funcs +extern f32 D_801ED8C8; // 2 funcs +extern f32 sBgmEnemyDistSq; // 2 funcs +extern f32 D_801ED8D0; // 2 funcs +extern s32 D_801ED8D4; // 2 funcs +extern s32 D_801ED8D8; // 2 funcs +extern s16 D_801ED8DC; // 2 funcs +extern Mtx D_801ED8E0; // 1 func +extern Actor* D_801ED920; // 2 funcs. 1 out of z_actor + +// Internal forward declarations +void func_800BA8B8(GlobalContext* globalCtx, ActorContext* actorCtx); +Actor* Actor_SpawnEntry(ActorContext* actorCtx, ActorEntry* actorEntry, GlobalContext* globalCtx); +Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, GlobalContext* globalCtx); +void func_800BB8EC(GameState* gameState, ActorContext* actorCtx, Actor** arg2, Actor** arg3, Player* player); +s32 func_800BA2FC(GlobalContext* globalCtx, Actor* actor, Vec3f* projectedPos, f32 projectedW); +void Actor_AddToCategory(ActorContext* actorCtx, Actor* actor, u8 actorCategory); +Actor* Actor_RemoveFromCategory(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actorToRemove); void Actor_PrintLists(ActorContext* actorCtx) { - ActorListEntry* actorList = &actorCtx->actorList[0]; + ActorListEntry* actorList = &actorCtx->actorLists[0]; Actor* actor; s32 i; @@ -9,7 +46,7 @@ void Actor_PrintLists(ActorContext* actorCtx) { FaultDrawer_Printf("actor\n", gMaxActorId); FaultDrawer_Printf("No. Actor Name Part SegName\n"); - for (i = 0; i < ARRAY_COUNT(actorCtx->actorList); i++) { + for (i = 0; i < ARRAY_COUNT(actorCtx->actorLists); i++) { actor = actorList[i].first; while (actor != NULL) { @@ -26,7 +63,6 @@ void ActorShape_Init(ActorShape* actorShape, f32 yOffset, ActorShadowFunc shadow actorShape->shadowAlpha = 255; } -#ifdef NON_MATCHING void ActorShadow_Draw(Actor* actor, Lights* lights, GlobalContext* globalCtx, Gfx* dlist, Color_RGBA8* color) { if (actor->floorPoly != NULL) { f32 dy = actor->world.pos.y - actor->floorHeight; @@ -43,7 +79,10 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, GlobalContext* globalCtx, Gf COMBINED); dy = CLAMP(dy, 0.0f, 150.0f); - shadowScale = 1.0f - (dy * 0.0028571428f); + shadowScale = 1.0f - (dy * (1.0f / 350.0f)); + if ((dy * (1.0f / 350.0f)) > 1.0f) { + shadowScale = 0.0f; + } if (color != NULL) { gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, color->r, color->g, color->b, @@ -53,15 +92,14 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, GlobalContext* globalCtx, Gf } func_800C0094(actor->floorPoly, actor->world.pos.x, actor->floorHeight, actor->world.pos.z, &mtx); - Matrix_SetCurrentState(&mtx); + Matrix_Put(&mtx); - if (dlist != D_04076BC0) { - Matrix_RotateY((f32)actor->shape.rot.y * (M_PI / 32768), MTXMODE_APPLY); + if ((dlist != gCircleShadowDL) || (actor->scale.x != actor->scale.z)) { + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); } - shadowScale = 1.0f - (dy * 0.0028571428f); shadowScale *= actor->shape.shadowScale; - Matrix_Scale(shadowScale * actor->scale.x, 1.0f, shadowScale * actor->scale.z, MTXMODE_APPLY); + Matrix_Scale(actor->scale.x * shadowScale, 1.0f, actor->scale.z * shadowScale, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, dlist); @@ -70,244 +108,949 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, GlobalContext* globalCtx, Gf } } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/ActorShadow_Draw.s") -#endif -/* ActorShadow_DrawCircle */ -void func_800B3FC0(Actor* actor, Lights* lights, GlobalContext* globalCtx) { +void ActorShadow_DrawCircle(Actor* actor, Lights* lights, GlobalContext* globalCtx) { if (actor->bgCheckFlags & 0x400) { func_800B4AEC(globalCtx, actor, 50.0f); } - ActorShadow_Draw(actor, lights, globalCtx, D_04076BC0, NULL); + ActorShadow_Draw(actor, lights, globalCtx, gCircleShadowDL, NULL); } -/* ActorShadow_DrawSquare */ -void func_800B4024(Actor* actor, Lights* lights, GlobalContext* globalCtx) { +void ActorShadow_DrawSquare(Actor* actor, Lights* lights, GlobalContext* globalCtx) { if (actor->bgCheckFlags & 0x400) { func_800B4AEC(globalCtx, actor, 50.0f); } - ActorShadow_Draw(actor, lights, globalCtx, D_04075A40, NULL); + ActorShadow_Draw(actor, lights, globalCtx, gSquareShadowDL, NULL); } -/* ActorShadow_DrawWhiteCircle */ -void func_800B4088(Actor* actor, Lights* lights, GlobalContext* globalCtx) { - ActorShadow_Draw(actor, lights, globalCtx, D_04076BC0, &D_801AEC80); +void ActorShadow_DrawWhiteCircle(Actor* actor, Lights* lights, GlobalContext* globalCtx) { + static Color_RGBA8 color = { 255, 255, 255, 255 }; + + ActorShadow_Draw(actor, lights, globalCtx, gCircleShadowDL, &color); } -/* ActorShadow_DrawHorse */ -void func_800B40B8(Actor* actor, Lights* lights, GlobalContext* globalCtx) { - ActorShadow_Draw(actor, lights, globalCtx, D_04077480, NULL); +void ActorShadow_DrawHorse(Actor* actor, Lights* lights, GlobalContext* globalCtx) { + ActorShadow_Draw(actor, lights, globalCtx, gHorseShadowDL, NULL); } -/* ActorShadow_DrawFoot */ -#ifdef NON_MATCHING -void func_800B40E0(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 arg3, f32 arg4, f32 arg5, f32 arg6) { - s32 pad1; +void ActorShadow_DrawFoot(GlobalContext* globalCtx, Light* light, MtxF* arg2, s32 lightNum, f32 shadowAlpha, + f32 shadowScaleX, f32 shadowScaleZ) { + s32 pad; s16 sp58; - s32 pad2[2]; + f32 dir2; + f32 dir0; OPEN_DISPS(globalCtx->state.gfxCtx); - gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, - (u32)(((arg3 * 1.3e-05f) > 1.0f ? 1.0f : (arg3 * 1.3e-05f)) * arg4) & 0xFF); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(CLAMP_MAX(lightNum * 1.3e-05f, 1.0f) * shadowAlpha)); - sp58 = Math_FAtan2F(light->l.dir[0], light->l.dir[2]); - arg6 *= (4.5f - (light->l.dir[1] * 0.035f)); - arg6 = (arg6 < 1.0f) ? 1.0f : arg6; - Matrix_SetCurrentState(arg2); - Matrix_RotateY(sp58, MTXMODE_APPLY); - Matrix_Scale(arg5, 1.0f, arg5 * arg6, MTXMODE_APPLY); + dir0 = light->l.dir[0]; + dir2 = light->l.dir[2]; + sp58 = Math_FAtan2F(dir2, dir0); + shadowScaleZ *= (4.5f - (light->l.dir[1] * 0.035f)); + shadowScaleZ = CLAMP_MIN(shadowScaleZ, 1.0f); + Matrix_Put(arg2); + Matrix_RotateYS(sp58, MTXMODE_APPLY); + Matrix_Scale(shadowScaleX, 1.0f, shadowScaleX * shadowScaleZ, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, D_04075B30); + gSPDisplayList(POLY_OPA_DISP++, gFootShadowDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B40E0.s") -#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B42F8.s") +void ActorShadow_DrawFeet(Actor* actor, Lights* mapper, GlobalContext* globalCtx) { + f32 distToFloor = actor->world.pos.y - actor->floorHeight; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4A98.s") + if (distToFloor > 0.0f) { + f32 shadowScale = actor->shape.shadowScale; + u8 shadowAlpha = actor->shape.shadowAlpha; + f32 alphaRatio; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4AEC.s") + if ((actor->id == ACTOR_PLAYER) && (((Player*)actor)->stateFlags3 & 0x8000)) { + f32 tmpScaleZ = actor->scale.z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4B50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4EDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4F40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B4F78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B5040.s") - -void Actor_TargetContextInit(TargetContext* targetCtx, Actor* actor, GlobalContext* globalCtx) { - targetCtx->unk90 = NULL; - targetCtx->unk8C = NULL; - targetCtx->unk3C = NULL; - targetCtx->unk38 = NULL; - targetCtx->unk4B = 0; - targetCtx->unk4C = 0; - targetCtx->unk40 = 0; - func_800B5040(targetCtx, actor, actor->category, globalCtx); - func_800B4F78(targetCtx, actor->category, globalCtx); -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B5208.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B5814.s") - -u32 Flags_GetSwitch(GlobalContext* globalCtx, s32 flag) { - if (flag >= 0 && flag < 0x80) { - return globalCtx->actorCtx.switchFlags[(flag & -0x20) >> 5] & (1 << (flag & 0x1F)); - } - return 0; -} - -void Actor_SetSwitchFlag(GlobalContext* globalCtx, s32 flag) { - if (flag >= 0 && flag < 0x80) { - globalCtx->actorCtx.switchFlags[(flag & -0x20) >> 5] |= 1 << (flag & 0x1F); - } -} - -void Actor_UnsetSwitchFlag(GlobalContext* globalCtx, s32 flag) { - if (flag >= 0 && flag < 0x80) { - globalCtx->actorCtx.switchFlags[(flag & -0x20) >> 5] &= ~(1 << (flag & 0x1F)); - } -} - -u32 Actor_GetChestFlag(GlobalContext* globalCtx, u32 flag) { - return globalCtx->actorCtx.chestFlags & (1 << flag); -} - -void Actor_SetChestFlag(GlobalContext* globalCtx, u32 flag) { - globalCtx->actorCtx.chestFlags |= (1 << flag); -} - -void Actor_SetAllChestFlag(GlobalContext* globalCtx, u32 flag) { - globalCtx->actorCtx.chestFlags = flag; -} - -u32 Actor_GetAllChestFlag(GlobalContext* globalCtx) { - return globalCtx->actorCtx.chestFlags; -} - -u32 Actor_GetRoomCleared(GlobalContext* globalCtx, u32 roomNumber) { - return globalCtx->actorCtx.clearedRooms & (1 << roomNumber); -} - -void Actor_SetRoomCleared(GlobalContext* globalCtx, u32 roomNumber) { - globalCtx->actorCtx.clearedRooms |= (1 << roomNumber); -} - -void Actor_UnsetRoomCleared(GlobalContext* globalCtx, u32 roomNumber) { - globalCtx->actorCtx.clearedRooms &= ~(1 << roomNumber); -} - -u32 Actor_GetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber) { - return globalCtx->actorCtx.clearedRoomsTemp & (1 << roomNumber); -} - -void Actor_SetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber) { - globalCtx->actorCtx.clearedRoomsTemp |= (1 << roomNumber); -} - -void Actor_UnsetRoomClearedTemp(GlobalContext* globalCtx, u32 roomNumber) { - globalCtx->actorCtx.clearedRoomsTemp &= ~(1 << roomNumber); -} - -u32 Actor_GetCollectibleFlag(GlobalContext* globalCtx, s32 index) { - if (index > 0 && index < 0x80) { - return globalCtx->actorCtx.collectibleFlags[(index & -0x20) >> 5] & (1 << (index & 0x1F)); - } - return 0; -} - -void Actor_SetCollectibleFlag(GlobalContext* globalCtx, s32 index) { - if (index > 0 && index < 0x80) { - globalCtx->actorCtx.collectibleFlags[(index & -0x20) >> 5] |= 1 << (index & 0x1F); - } -} - -void Actor_TitleCardContextInit(GlobalContext* globalCtx, TitleCardContext* titleCardCtx) { - titleCardCtx->fadeOutDelay = 0; - titleCardCtx->fadeInDelay = 0; - titleCardCtx->color = 0; - titleCardCtx->alpha = 0; -} - -void Actor_TitleCardCreate(GlobalContext* globalCtx, TitleCardContext* titleCardCtx, u32 texture, s16 param_4, - s16 param_5, u8 param_6, u8 param_7) { - titleCardCtx->texture = texture; - titleCardCtx->unk4 = param_4; - titleCardCtx->unk6 = param_5; - titleCardCtx->unk8 = param_6; - titleCardCtx->unk9 = param_7; - titleCardCtx->fadeOutDelay = 80; - titleCardCtx->fadeInDelay = 0; -} - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_Nop800B5E50.s") - -void Actor_TitleCardUpdate(GlobalContext* globalCtx, TitleCardContext* titleCardCtx) { - if (DECR(titleCardCtx->fadeInDelay) == 0) { - if (DECR(titleCardCtx->fadeOutDelay) == 0) { - Math_StepToS(&titleCardCtx->alpha, 0, 30); - Math_StepToS(&titleCardCtx->color, 0, 70); + actor->scale.z += 0.03f * fabsf(Math_CosS(((Player*)actor)->unk_AAA)); + actor->shape.shadowScale *= 0.2f; + alphaRatio = distToFloor * 0.03f; + actor->shape.shadowAlpha = actor->shape.shadowAlpha * CLAMP_MAX(alphaRatio, 1.0f); + ActorShadow_Draw(actor, mapper, globalCtx, gCircleShadowDL, NULL); + actor->scale.z = tmpScaleZ; } else { - Math_StepToS(&titleCardCtx->alpha, 255, 10); - Math_StepToS(&titleCardCtx->color, 255, 20); + actor->shape.shadowScale *= 0.3f; + alphaRatio = (distToFloor - 20.0f) * 0.02f; + actor->shape.shadowAlpha = actor->shape.shadowAlpha * CLAMP_MAX(alphaRatio, 1.0f); + ActorShadow_DrawCircle(actor, mapper, globalCtx); + } + + actor->shape.shadowScale = shadowScale; + actor->shape.shadowAlpha = shadowAlpha; + } + + if (distToFloor < 200.0f) { + MtxF sp13C; + MtxF spFC; + CollisionPoly* spF8; + s32 bgId; + f32 floorHeight[2]; + Light* firstLight = &mapper->l.l[0]; + f32 shadowAlpha; + f32 shadowScaleX; + f32 shadowScaleZ; + Light* lightPtr; + s32 lightNumMax; + s32 i; + s32 j; + s32 lightNum; + Vec3f* feetPosPtr; + s32 numLights; + f32* floorHeightPtr; + s32 spB8; + + numLights = mapper->numLights - 2; + feetPosPtr = actor->shape.feetPos; + floorHeightPtr = floorHeight; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + actor->shape.feetFloorFlags = 0; + spB8 = 2; + + for (i = 0; i < ARRAY_COUNT(floorHeight); i++, spB8 >>= 1) { + feetPosPtr->y += 50.0f; + *floorHeightPtr = func_80169100(globalCtx, &sp13C, &spF8, &bgId, feetPosPtr); + feetPosPtr->y -= 50.0f; + + distToFloor = feetPosPtr->y - *floorHeightPtr; + if ((distToFloor >= -1.0f) && (distToFloor < 500.0f)) { + lightNumMax = 0; + + if (distToFloor <= 10.0f) { + actor->shape.feetFloorFlags |= spB8; + + if ((actor->depthInWater < 0.0f) && (bgId == 0x32) && ((actor->shape.unk_17 & spB8) != 0)) { + if (func_800C9C24(&globalCtx->colCtx, spF8, bgId, 1) != 0) { + SkinMatrix_MtxFCopy(&sp13C, &spFC); + SkinMatrix_MulYRotation(&spFC, actor->shape.rot.y); + EffFootmark_Add(globalCtx, &spFC, actor, i, feetPosPtr, (actor->shape.shadowScale * 0.3f), + IREG(88) + 80, IREG(89) + 60, IREG(90) + 40, 30000, 200, 60); + } + actor->shape.unk_17 &= ~spB8; + } + } + + if (distToFloor > 30.0f) { + distToFloor = 30.0f; + } + + shadowAlpha = actor->shape.shadowAlpha * (1.0f - (distToFloor * (1 / 30.0f))); + shadowScaleZ = 1.0f - (distToFloor * (1.0f / 70.0f)); + shadowScaleX = actor->shape.shadowScale * shadowScaleZ * actor->scale.x; + + lightPtr = firstLight; + for (j = 0; j < numLights; j++) { + if (lightPtr->l.dir[1] > 0) { + lightNum = (lightPtr->l.col[0] + lightPtr->l.col[1] + lightPtr->l.col[2]) * + ABS_ALT(lightPtr->l.dir[1]); + + if (lightNum > 0) { + lightNumMax += lightNum; + ActorShadow_DrawFoot(globalCtx, lightPtr, &sp13C, lightNum, shadowAlpha, shadowScaleX, + shadowScaleZ); + } + } + lightPtr++; + } + + for (j = 0; j < 2; j++) { + if (lightPtr->l.dir[1] > 0) { + lightNum = ((lightPtr->l.col[0] + lightPtr->l.col[1] + lightPtr->l.col[2]) * + ABS_ALT(lightPtr->l.dir[1])) - + (lightNumMax * 8); + if (lightNum > 0) { + ActorShadow_DrawFoot(globalCtx, lightPtr, &sp13C, lightNum, shadowAlpha, shadowScaleX, + shadowScaleZ); + } + } + lightPtr++; + } + } + feetPosPtr++; + floorHeightPtr++; + } + + if (!(actor->bgCheckFlags & 1)) { + actor->shape.feetFloorFlags = 0; + } else if (actor->shape.feetFloorFlags == 3) { + f32 footDistY = actor->shape.feetPos[FOOT_LEFT].y - actor->shape.feetPos[FOOT_RIGHT].y; + + if ((floorHeight[0] + footDistY) < (floorHeight[1] - footDistY)) { + actor->shape.feetFloorFlags = 2; + } else { + actor->shape.feetFloorFlags = 1; + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void Actor_SetFeetPos(Actor* actor, s32 limbIndex, s32 leftFootIndex, Vec3f* leftFootPos, s32 rightFootIndex, + Vec3f* rightFootPos) { + if (limbIndex == leftFootIndex) { + Matrix_MultVec3f(leftFootPos, &actor->shape.feetPos[FOOT_LEFT]); + } else if (limbIndex == rightFootIndex) { + Matrix_MultVec3f(rightFootPos, &actor->shape.feetPos[FOOT_RIGHT]); + } +} + +void func_800B4AEC(GlobalContext* globalCtx, Actor* actor, f32 y) { + s32 floorBgId; + f32 yPos = actor->world.pos.y; + + actor->world.pos.y += y; + actor->floorHeight = BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &actor->floorPoly, &floorBgId, + actor, &actor->world.pos); + actor->floorBgId = floorBgId; + actor->world.pos.y = yPos; +} + +void func_800B4B50(Actor* actor, Lights* mapper, GlobalContext* globalCtx) { + f32 spEC; + f32 temp_f12; + f32 shadowScaleZ; + f32 temp_f22; + f32 temp_f24; + f32 temp_f8; + s32 lightNum; + MtxF sp94; + s32 numLights; + s8 phi_v1; + u8 temp_v0; + Light* phi_s0; + s32 lightNumMax; + + if (actor->bgCheckFlags & 0x400) { + func_800B4AEC(globalCtx, actor, 50.0f); + } + + if (actor->floorPoly != NULL) { + s32 j; + + spEC = actor->world.pos.y - actor->floorHeight; + if (spEC > 20.0f) { + f32 temp_f20 = actor->shape.shadowScale; + + temp_v0 = actor->shape.shadowAlpha; + actor->shape.shadowScale *= 0.3f; + temp_f12 = (spEC - 20.0f) * 0.02f; + actor->shape.shadowAlpha = CLAMP_MAX(temp_f12, 1.0f) * actor->shape.shadowAlpha; + ActorShadow_DrawCircle(actor, mapper, globalCtx); + actor->shape.shadowScale = temp_f20; + actor->shape.shadowAlpha = temp_v0; + } else if (spEC >= -1.0f) { + numLights = mapper->numLights - 2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + + func_800C0094(actor->floorPoly, actor->world.pos.x, actor->floorHeight, actor->world.pos.z, &sp94); + temp_f22 = (f32)actor->shape.shadowAlpha * (1.0f - (spEC * (1.0f / 30.0f))); + phi_s0 = mapper->l.l; + shadowScaleZ = 1.0f - (spEC * (1.0f / 70.0f)); + temp_f24 = actor->shape.shadowScale * shadowScaleZ * actor->scale.x; + + lightNumMax = 0; + for (j = 0; j < numLights; j++, phi_s0++) { + if (phi_s0->l.dir[1] > 0) { + lightNum = (phi_s0->l.col[0] + phi_s0->l.col[1] + phi_s0->l.col[2]) * ABS_ALT(phi_s0->l.dir[1]); + if (lightNum > 0) { + lightNumMax += lightNum; + ActorShadow_DrawFoot(globalCtx, phi_s0, &sp94, lightNum, temp_f22, temp_f24, shadowScaleZ); + } + } + } + + for (j = 0; j < 2; j++, phi_s0++) { + if (phi_s0->l.dir[1] > 0) { + lightNum = ((phi_s0->l.col[0] + phi_s0->l.col[1] + phi_s0->l.col[2]) * ABS_ALT(phi_s0->l.dir[1])) - + (8 * lightNumMax); + if (lightNum > 0) { + ActorShadow_DrawFoot(globalCtx, phi_s0, &sp94, lightNum, temp_f22, temp_f24, shadowScaleZ); + } + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); } } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_TitleCardDraw.s") +void Actor_GetProjectedPos(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, f32* arg3) { + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, arg1, arg2, arg3); + if (*arg3 < 1.0f) { + *arg3 = 1.0f; + } else { + *arg3 = 1.0f / *arg3; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6434.s") +void Target_SetPos(TargetContext* targetCtx, s32 index, f32 x, f32 y, f32 z) { + targetCtx->unk50[index].pos.x = x; + targetCtx->unk50[index].pos.y = y; + targetCtx->unk50[index].pos.z = z; + targetCtx->unk50[index].unkC = targetCtx->unk44; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6468.s") +typedef struct { + /* 0x0 */ Color_RGBA8 inner; + /* 0x4 */ Color_RGBA8 outer; +} TatlColor; // size = 0x8 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6474.s") +TatlColor sTatlColorList[] = { + { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, + { { 255, 255, 230, 255 }, { 220, 160, 80, 0 } }, { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, + { { 150, 150, 255, 255 }, { 150, 150, 255, 0 } }, { { 255, 255, 0, 255 }, { 200, 155, 0, 0 } }, + { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, + { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, { { 255, 255, 0, 255 }, { 200, 155, 0, 0 } }, + { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } }, + { { 0, 255, 0, 255 }, { 0, 255, 0, 0 } } +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B648C.s") +void func_800B4F78(TargetContext* targetCtx, s32 type, GlobalContext* globalCtx) { + TatlColor* tatlColorEntry; + s32 i; + TargetContextEntry* targetEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B64FC.s") + Math_Vec3f_Copy(&targetCtx->targetCenterPos, &globalCtx->view.eye); + targetCtx->unk48 = 0x100; + tatlColorEntry = &sTatlColorList[type]; + targetCtx->unk44 = 500.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6584.s") + targetEntry = targetCtx->unk50; + for (i = 0; i < ARRAY_COUNT(targetCtx->unk50); i++, targetEntry++) { + Target_SetPos(targetCtx, i, 0.0f, 0.0f, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6608.s") + targetEntry->color.r = tatlColorEntry->inner.r; + targetEntry->color.g = tatlColorEntry->inner.g; + targetEntry->color.b = tatlColorEntry->inner.b; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6680.s") +void Target_SetColors(TargetContext* targetCtx, Actor* actor, s32 type, GlobalContext* globalCtx) { + targetCtx->unk0.x = actor->focus.pos.x; + targetCtx->unk0.y = actor->focus.pos.y + (actor->targetArrowOffset * actor->scale.y); + targetCtx->unk0.z = actor->focus.pos.z; + + targetCtx->fairyInner.r = sTatlColorList[type].inner.r; + targetCtx->fairyInner.g = sTatlColorList[type].inner.g; + targetCtx->fairyInner.b = sTatlColorList[type].inner.b; + targetCtx->fairyInner.a = sTatlColorList[type].inner.a; + targetCtx->fairyOuter.r = sTatlColorList[type].outer.r; + targetCtx->fairyOuter.g = sTatlColorList[type].outer.g; + targetCtx->fairyOuter.b = sTatlColorList[type].outer.b; + targetCtx->fairyOuter.a = sTatlColorList[type].outer.a; +} + +void Actor_TargetContextInit(TargetContext* targetCtx, Actor* actor, GlobalContext* globalCtx) { + targetCtx->bgmEnemy = NULL; + targetCtx->unk8C = NULL; + targetCtx->targetedActor = NULL; + targetCtx->arrowPointedActor = NULL; + targetCtx->unk4B = 0; + targetCtx->unk4C = 0; + targetCtx->unk40 = 0.0f; + Target_SetColors(targetCtx, actor, actor->category, globalCtx); + func_800B4F78(targetCtx, actor->category, globalCtx); +} + +void Actor_DrawZTarget(TargetContext* targetCtx, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags1 & 0x300006C2)) { + Actor* actor = targetCtx->targetedActor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + if (targetCtx->unk48 != 0) { + TargetContextEntry* entry; + s16 alpha = 255; + f32 var1 = 1.0f; + Vec3f spBC; + s32 spB8; + f32 spB4; + s32 spB0; + s32 spAC; + f32 var2; + s32 i; + + if (targetCtx->unk4B != 0) { + spB8 = 1; + } else { + spB8 = 3; + } + + if (actor != NULL) { + Math_Vec3f_Copy(&targetCtx->targetCenterPos, &actor->focus.pos); + var1 = (500.0f - targetCtx->unk44) / 420.0f; + } else { + targetCtx->unk48 -= 120; + if (targetCtx->unk48 < 0) { + targetCtx->unk48 = 0; + } + alpha = targetCtx->unk48; + } + + Actor_GetProjectedPos(globalCtx, &targetCtx->targetCenterPos, &spBC, &spB4); + + spBC.x = (160 * (spBC.x * spB4)) * var1; + spBC.x = CLAMP(spBC.x, -320.0f, 320.0f); + + spBC.y = (120 * (spBC.y * spB4)) * var1; + spBC.y = CLAMP(spBC.y, -240.0f, 240.0f); + + spBC.z = spBC.z * var1; + + targetCtx->unk4C--; + if (targetCtx->unk4C < 0) { + targetCtx->unk4C = 2; + } + + Target_SetPos(targetCtx, targetCtx->unk4C, spBC.x, spBC.y, spBC.z); + + if ((!(player->stateFlags1 & 0x40)) || (actor != player->unk_730)) { + OVERLAY_DISP = Gfx_CallSetupDL(OVERLAY_DISP, 0x39); + + for (spB0 = 0, spAC = targetCtx->unk4C; spB0 < spB8; spB0++, spAC = (spAC + 1) % 3) { + entry = &targetCtx->unk50[spAC]; + + if (entry->unkC < 500.0f) { + if (entry->unkC <= 120.0f) { + var2 = 0.15f; + } else { + var2 = ((entry->unkC - 120.0f) * 0.001f) + 0.15f; + } + + Matrix_Translate(entry->pos.x, entry->pos.y, 0.0f, MTXMODE_NEW); + Matrix_Scale(var2, 0.15f, 1.0f, MTXMODE_APPLY); + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, entry->color.r, entry->color.g, entry->color.b, + (u8)alpha); + + Matrix_RotateZS((targetCtx->unk4B * 512), MTXMODE_APPLY); + + for (i = 0; i < 4; i++) { + Matrix_RotateZS(0x4000, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Translate(entry->unkC, entry->unkC, 0.0f, MTXMODE_APPLY); + gSPMatrix(OVERLAY_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(OVERLAY_DISP++, gZTargetLockOnTriangleDL); + Matrix_Pop(); + } + } + + alpha -= 255 / 3; + if (alpha < 0) { + alpha = 0; + } + } + } + } + + actor = targetCtx->unk_94; + if ((actor != NULL) && !(actor->flags & ACTOR_FLAG_8000000)) { + TatlColor* color = &sTatlColorList[actor->category]; + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x07); + + Matrix_Translate(actor->focus.pos.x, + actor->focus.pos.y + (actor->targetArrowOffset * actor->scale.y) + 17.0f, + actor->focus.pos.z, MTXMODE_NEW); + Matrix_RotateYS((globalCtx->gameplayFrames * 3000), MTXMODE_APPLY); + Matrix_Scale((iREG(27) + 35) / 1000.0f, (iREG(28) + 60) / 1000.0f, (iREG(29) + 50) / 1000.0f, + MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, color->inner.r, color->inner.g, color->inner.b, 255); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gSPDisplayList(POLY_XLU_DISP++, gZTargetArrowDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +// OoT: func_8002C7BC +void func_800B5814(TargetContext* targetCtx, Player* player, Actor* actor, GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + Actor* sp68 = NULL; + s32 category; + Vec3f sp58; + f32 sp54; + + if ((player->unk_730 != 0) && (player->unk_AE3[player->unk_ADE] == 2)) { + targetCtx->unk_94 = NULL; + } else { + func_800BB8EC(gameState, &globalCtx->actorCtx, &sp68, &D_801ED920, player); + targetCtx->unk_94 = sp68; + } + + if (targetCtx->unk8C != 0) { + sp68 = targetCtx->unk8C; + targetCtx->unk8C = NULL; + } else if (actor != 0) { + sp68 = actor; + } + + if (sp68 != NULL) { + category = sp68->category; + } else { + category = player->actor.category; + } + + if ((sp68 != targetCtx->arrowPointedActor) || (category != targetCtx->unk4A)) { + targetCtx->arrowPointedActor = sp68; + targetCtx->unk4A = category; + targetCtx->unk40 = 1.0f; + } + + if (sp68 == NULL) { + sp68 = &player->actor; + } + + if (!Math_StepToF(&targetCtx->unk40, 0.0f, 0.25f)) { + f32 temp_f0; + f32 x; + f32 y; + f32 z; + + temp_f0 = 0.25f / targetCtx->unk40; + + x = sp68->focus.pos.x - targetCtx->unk0.x; + y = (sp68->focus.pos.y + (sp68->targetArrowOffset * sp68->scale.y)) - targetCtx->unk0.y; + z = sp68->focus.pos.z - targetCtx->unk0.z; + + targetCtx->unk0.x += x * temp_f0; + targetCtx->unk0.y += y * temp_f0; + targetCtx->unk0.z += z * temp_f0; + } else { + Target_SetColors(targetCtx, sp68, category, globalCtx); + } + + if (actor != NULL && targetCtx->unk4B == 0) { + Actor_GetProjectedPos(globalCtx, &actor->focus.pos, &sp58, &sp54); + if ((sp58.z <= 0.0f) || (fabsf(sp58.x * sp54) >= 1.0f) || (fabsf(sp58.y * sp54) >= 1.0f)) { + actor = NULL; + } + } + + if (actor != NULL) { + if (actor != targetCtx->targetedActor) { + s32 sfxId; + + func_800B4F78(targetCtx, actor->category, globalCtx); + + targetCtx->targetedActor = actor; + + if (actor->id == ACTOR_EN_BOOM) { + targetCtx->unk48 = 0; + } + + sfxId = + CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_4 | ACTOR_FLAG_1) ? NA_SE_SY_LOCK_ON : NA_SE_SY_LOCK_ON_HUMAN; + play_sound(sfxId); + } + + targetCtx->targetCenterPos.x = actor->world.pos.x; + targetCtx->targetCenterPos.y = actor->world.pos.y - (actor->shape.yOffset * actor->scale.y); + targetCtx->targetCenterPos.z = actor->world.pos.z; + + if (targetCtx->unk4B == 0) { + f32 temp_f0_2; + f32 clampedFloat; + + temp_f0_2 = (500.0f - targetCtx->unk44) * 3.0f; + clampedFloat = CLAMP(temp_f0_2, 30.0f, 100.0f); + + if (Math_StepToF(&targetCtx->unk44, 80.0f, clampedFloat)) { + targetCtx->unk4B++; + } + } else { + targetCtx->unk4B = (targetCtx->unk4B + 3) | 0x80; + targetCtx->unk44 = 120.0f; + } + } else { + targetCtx->targetedActor = NULL; + Math_StepToF(&targetCtx->unk44, 500.0f, 80.0f); + } +} + +/* Start of Flags section */ + +/** + * Tests if current scene switch flag is set. + */ +s32 Flags_GetSwitch(GlobalContext* globalCtx, s32 flag) { + if (flag >= 0 && flag < 0x80) { + return globalCtx->actorCtx.flags.switches[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F)); + } + return 0; +} + +/** + * Sets current scene switch flag. + */ +void Flags_SetSwitch(GlobalContext* globalCtx, s32 flag) { + if (flag >= 0 && flag < 0x80) { + globalCtx->actorCtx.flags.switches[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F); + } +} + +/** + * Unsets current scene switch flag. + */ +void Flags_UnsetSwitch(GlobalContext* globalCtx, s32 flag) { + if (flag >= 0 && flag < 0x80) { + globalCtx->actorCtx.flags.switches[(flag & ~0x1F) >> 5] &= ~(1 << (flag & 0x1F)); + } +} + +/** + * Tests if current scene chest flag is set. + */ +s32 Flags_GetTreasure(GlobalContext* globalCtx, s32 flag) { + return globalCtx->actorCtx.flags.chest & (1 << flag); +} + +/** + * Sets current scene chest flag. + */ +void Flags_SetTreasure(GlobalContext* globalCtx, s32 flag) { + globalCtx->actorCtx.flags.chest |= (1 << flag); +} + +/** + * Overrides the all the chest flags. + */ +void Flags_SetAllTreasure(GlobalContext* globalCtx, s32 flag) { + globalCtx->actorCtx.flags.chest = flag; +} + +/** + * Returns all the chest flags. + */ +s32 Flags_GetAllTreasure(GlobalContext* globalCtx) { + return globalCtx->actorCtx.flags.chest; +} + +/** + * Tests if current scene clear flag is set. + */ +s32 Flags_GetClear(GlobalContext* globalCtx, s32 roomNumber) { + return globalCtx->actorCtx.flags.clearedRoom & (1 << roomNumber); +} + +/** + * Sets current scene clear flag. + */ +void Flags_SetClear(GlobalContext* globalCtx, s32 roomNumber) { + globalCtx->actorCtx.flags.clearedRoom |= (1 << roomNumber); +} + +/** + * Unsets current scene clear flag. + */ +void Flags_UnsetClear(GlobalContext* globalCtx, s32 roomNumber) { + globalCtx->actorCtx.flags.clearedRoom &= ~(1 << roomNumber); +} + +/** + * Tests if current scene temp clear flag is set. + */ +s32 Flags_GetClearTemp(GlobalContext* globalCtx, s32 roomNumber) { + return globalCtx->actorCtx.flags.clearedRoomTemp & (1 << roomNumber); +} + +/** + * Sets current scene temp clear flag. + */ +void Flags_SetClearTemp(GlobalContext* globalCtx, s32 roomNumber) { + globalCtx->actorCtx.flags.clearedRoomTemp |= (1 << roomNumber); +} + +/** + * Unsets current scene temp clear flag. + */ +void Flags_UnsetClearTemp(GlobalContext* globalCtx, s32 roomNumber) { + globalCtx->actorCtx.flags.clearedRoomTemp &= ~(1 << roomNumber); +} + +/** + * Tests if current scene collectible flag is set. + */ +s32 Flags_GetCollectible(GlobalContext* globalCtx, s32 flag) { + if (flag > 0 && flag < 0x80) { + return globalCtx->actorCtx.flags.collectible[(flag & ~0x1F) >> 5] & (1 << (flag & 0x1F)); + } + return 0; +} + +/** + * Sets current scene collectible flag. + */ +void Flags_SetCollectible(GlobalContext* globalCtx, s32 flag) { + if (flag > 0 && flag < 0x80) { + globalCtx->actorCtx.flags.collectible[(flag & ~0x1F) >> 5] |= 1 << (flag & 0x1F); + } +} + +/* End of Flags section */ + +/* Start of TitleCard section */ + +void TitleCard_ContextInit(GameState* gameState, TitleCardContext* titleCtx) { + titleCtx->durationTimer = 0; + titleCtx->delayTimer = 0; + titleCtx->intensity = 0; + titleCtx->alpha = 0; +} + +void TitleCard_InitBossName(GameState* gameState, TitleCardContext* titleCtx, TexturePtr texture, s16 x, s16 y, + u8 width, u8 height) { + titleCtx->texture = texture; + titleCtx->x = x; + titleCtx->y = y; + titleCtx->width = width; + titleCtx->height = height; + titleCtx->durationTimer = 80; + titleCtx->delayTimer = 0; +} + +void TitleCard_InitPlaceName(GameState* gameState, TitleCardContext* titleCtx, TexturePtr texture, s32 x, s32 y, + s32 width, s32 height, s32 delay) { +} + +void TitleCard_Update(GameState* gameState, TitleCardContext* titleCtx) { + if (DECR(titleCtx->delayTimer) == 0) { + if (DECR(titleCtx->durationTimer) == 0) { + Math_StepToS(&titleCtx->alpha, 0, 30); + Math_StepToS(&titleCtx->intensity, 0, 70); + } else { + Math_StepToS(&titleCtx->alpha, 255, 10); + Math_StepToS(&titleCtx->intensity, 255, 20); + } + } +} + +void TitleCard_Draw(GameState* gameState, TitleCardContext* titleCtx) { + if (titleCtx->alpha != 0) { + s32 width = titleCtx->width; + s32 height = titleCtx->height; + s32 unk1; + s32 spC0; + s32 sp38; + s32 spB8; + s32 spB4; + s32 temp; + + temp = width * 2; + spC0 = (titleCtx->x * 4) - temp; + spB8 = (titleCtx->y * 4) - (height * 2); + sp38 = width * 2; + + OPEN_DISPS(gameState->gfxCtx); + + height = (width * height > TMEM_SIZE) ? TMEM_SIZE / width : height; + spB4 = spB8 + (height * 4); + + if (1) {} + + OVERLAY_DISP = func_8012C014(OVERLAY_DISP); + + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, (u8)titleCtx->intensity, (u8)titleCtx->intensity, (u8)titleCtx->intensity, + (u8)titleCtx->alpha); + + gDPLoadTextureBlock(OVERLAY_DISP++, (s32*)titleCtx->texture, G_IM_FMT_IA, G_IM_SIZ_8b, width, height, 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); + + gSPTextureRectangle(OVERLAY_DISP++, spC0, spB8, ((sp38 * 2) + spC0) - 4, spB8 + (height * 4) - 1, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + height = titleCtx->height - height; + + if (height > 0) { + gDPLoadTextureBlock(OVERLAY_DISP++, (s32)titleCtx->texture + 0x1000, G_IM_FMT_IA, G_IM_SIZ_8b, width, + height, 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); + + gSPTextureRectangle(OVERLAY_DISP++, spC0, spB4, ((sp38 * 2) + spC0) - 4, spB4 + (height * 4) - 1, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + } + + CLOSE_DISPS(gameState->gfxCtx); + } +} + +/* End of TitleCard section */ + +// unused +s32 func_800B6434(GlobalContext* globalCtx, TitleCardContext* titleCtx) { + if ((globalCtx->actorCtx.titleCtxt.delayTimer != 0) || (globalCtx->actorCtx.titleCtxt.alpha != 0)) { + titleCtx->durationTimer = 0; + titleCtx->delayTimer = 0; + return false; + } + return true; +} + +void func_800B6468(GlobalContext* globalCtx) { + globalCtx->actorCtx.unk1F5 = 0; +} + +void func_800B6474(GlobalContext* globalCtx) { + if (globalCtx->actorCtx.unk1F5 != 0) { + globalCtx->actorCtx.unk1F5--; + } +} + +s32 func_800B648C(GlobalContext* globalCtx, s32 arg1, s32 arg2, f32 arg3, Vec3f* arg4) { + if ((globalCtx->actorCtx.unk1F5 != 0) && (arg3 < globalCtx->actorCtx.unk1F8)) { + return false; + } + + globalCtx->actorCtx.unk1F4 = arg1; + globalCtx->actorCtx.unk1F5 = arg2; + globalCtx->actorCtx.unk1F8 = arg3; + Math_Vec3f_Copy(&globalCtx->actorCtx.unk1FC, arg4); + + return true; +} + +f32 func_800B64FC(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2, s32* arg3) { + f32 temp_f8; + + if ((globalCtx->actorCtx.unk1F5 == 0) || (arg1 == 0.0f)) { + return -1.0f; + } + + temp_f8 = Math_Vec3f_DistXYZ(&globalCtx->actorCtx.unk1FC, arg2) / arg1; + *arg3 = globalCtx->actorCtx.unk1F4; + return globalCtx->actorCtx.unk1F8 - temp_f8; +} + +/** + * Initializes an element of the `globalCtx->actorCtx.unk_20C` array to the `arg2` pointer, or allocates one using the + * `size` argument in case `arg2` is NULL. This element is associated to an `id` + * + * In success returns the allocated pointer if `arg2` was NULL or the `arg2` pointer otherwise + * In failure (There's no space left in `globalCtx->actorCtx.unk_20C` or an allocation error happened) returns NULL + * + * Note there are no duplicated id checks. + * + * Used only by EnLiftNuts. + */ +void* func_800B6584(GlobalContext* globalCtx, s16 id, void* arg2, size_t size) { + ActorContext_unk_20C* entry = globalCtx->actorCtx.unk_20C; + s32 i; + + for (i = 0; i < ARRAY_COUNT(globalCtx->actorCtx.unk_20C); i++) { + if (entry->id == 0) { + if (arg2 == NULL) { + arg2 = ZeldaArena_Malloc(size); + if (arg2 == NULL) { + return NULL; + } + entry->isDynamicallyInitialised = true; + } + + entry->id = id; + entry->ptr = arg2; + return arg2; + } + + entry++; + } + + return NULL; +} + +/** + * Frees the first element of `globalCtx->actorCtx.unk_20C` with id `id`. + * + * If success, the free'd pointer is returned. + * If failure, NULL is returned. + * + * Used only by EnLiftNuts. + */ +void* func_800B6608(GlobalContext* globalCtx, s16 id) { + ActorContext_unk_20C* entry = globalCtx->actorCtx.unk_20C; + s32 i; + + for (i = 0; i < ARRAY_COUNT(globalCtx->actorCtx.unk_20C); i++) { + if (id == entry->id) { + entry->id = 0; + if (entry->isDynamicallyInitialised) { + ZeldaArena_Free(entry->ptr); + entry->isDynamicallyInitialised = false; + } + return entry->ptr; + } + + entry++; + } + + return NULL; +} + +/** + * Retrieves the first pointer stored with the id `id`. + * If there's no pointer stored with that id, NULL is returned. + * + * Used only by EnLiftNuts. + */ +void* func_800B6680(GlobalContext* globalCtx, s16 id) { + ActorContext_unk_20C* entry = globalCtx->actorCtx.unk_20C; + s32 i; + + for (i = 0; i < ARRAY_COUNT(globalCtx->actorCtx.unk_20C); i++) { + if (id == entry->id) { + return entry->ptr; + } + + entry++; + } + + return NULL; +} void Actor_MarkForDeath(Actor* actor) { actor->draw = NULL; actor->update = NULL; - actor->flags &= ~0x1; + actor->flags &= ~ACTOR_FLAG_1; } -void Actor_InitCurrPosition(Actor* actor) { +void Actor_SetWorldToHome(Actor* actor) { actor->world = actor->home; } -void Actor_SetHeight(Actor* actor, f32 height) { +void Actor_SetFocus(Actor* actor, f32 height) { actor->focus.pos.x = actor->world.pos.x; actor->focus.pos.y = actor->world.pos.y + height; actor->focus.pos.z = actor->world.pos.z; + actor->focus.rot.x = actor->world.rot.x; actor->focus.rot.y = actor->world.rot.y; actor->focus.rot.z = actor->world.rot.z; } -void Actor_SetRotationFromDrawRotation(Actor* actor) { +void Actor_SetWorldRotToShape(Actor* actor) { actor->world.rot = actor->shape.rot; } -void Actor_InitDrawRotation(Actor* actor) { +void Actor_SetShapeRotToWorld(Actor* actor) { actor->shape.rot = actor->world.rot; } @@ -317,43 +1060,38 @@ void Actor_SetScale(Actor* actor, f32 scale) { actor->scale.x = scale; } -void Actor_SetObjectSegment(GlobalContext* globalCtx, Actor* actor) { - // TODO: Segment number enum - gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[actor->objBankIndex].segment); +void Actor_SetObjectDependency(GlobalContext* globalCtx, Actor* actor) { + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[actor->objBankIndex].segment); } -#if 0 -void Actor_InitToDefaultValues(Actor* actor, GlobalContext* globalCtx) { - Actor_InitCurrPosition(actor); - Actor_InitDrawRotation(actor); - Actor_SetHeight(actor, 0); +void Actor_Init(Actor* actor, GlobalContext* globalCtx) { + Actor_SetWorldToHome(actor); + Actor_SetShapeRotToWorld(actor); + Actor_SetFocus(actor, 0.0f); Math_Vec3f_Copy(&actor->prevPos, &actor->world.pos); - Actor_SetScale(actor, 0.01); + Actor_SetScale(actor, 0.01f); actor->targetMode = 3; - actor->minYVelocity = -20.0f; + actor->terminalVelocity = -20.0f; - actor->meshAttachedTo = 0x32; - - actor->sqrdDistToLink = D_801DCA54; - CollisionCheck_InitInfo(&actor->colChkInfo); + actor->xyzDistToPlayerSq = FLT_MAX; actor->uncullZoneForward = 1000.0f; actor->uncullZoneScale = 350.0f; actor->uncullZoneDownward = 700.0f; - actor->naviMsgId = 255; + actor->hintId = 255; - Actor_Setshape(&actor->shape, 0, 0, 0); - if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex) != 0) { - Actor_SetObjectSegment(globalCtx, actor); + CollisionCheck_InitInfo(&actor->colChkInfo); + actor->floorBgId = BGCHECK_SCENE; + + ActorShape_Init(&actor->shape, 0.0f, NULL, 0.0f); + if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { + Actor_SetObjectDependency(globalCtx, actor); actor->init(actor, globalCtx); actor->init = NULL; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_InitToDefaultValues.s") -#endif -void Actor_FiniActor(Actor* actor, GlobalContext* globalCtx) { +void Actor_Destroy(Actor* actor, GlobalContext* globalCtx) { if (actor->init == NULL) { if (actor->destroy != NULL) { actor->destroy(actor, globalCtx); @@ -362,60 +1100,111 @@ void Actor_FiniActor(Actor* actor, GlobalContext* globalCtx) { } } +f32 actorMovementScale = 1.0f; + void Actor_SetMovementScale(s32 scale) { actorMovementScale = scale * 0.5f; } -void Actor_ApplyMovement(Actor* actor) { +/** + * Update actor position using velocity and any push from z_collision_check. + */ +void Actor_UpdatePos(Actor* actor) { f32 speedRate = actorMovementScale; - actor->world.pos.x += ((actor->velocity.x * speedRate) + actor->colChkInfo.displacement.x); - actor->world.pos.y += ((actor->velocity.y * speedRate) + actor->colChkInfo.displacement.y); - actor->world.pos.z += ((actor->velocity.z * speedRate) + actor->colChkInfo.displacement.z); + actor->world.pos.x += (actor->velocity.x * speedRate) + actor->colChkInfo.displacement.x; + actor->world.pos.y += (actor->velocity.y * speedRate) + actor->colChkInfo.displacement.y; + actor->world.pos.z += (actor->velocity.z * speedRate) + actor->colChkInfo.displacement.z; } -void Actor_SetVelocityYRotationAndGravity(Actor* actor) { +/** + * Updates actor's velocity accounting for gravity (without exceeding terminal velocity) + * The operation is performed in cylindrical coordinates + * + * It is recommended to not call this function directly and use `Actor_MoveWithGravity` instead + */ +void Actor_UpdateVelocityWithGravity(Actor* actor) { actor->velocity.x = actor->speedXZ * Math_SinS(actor->world.rot.y); actor->velocity.z = actor->speedXZ * Math_CosS(actor->world.rot.y); - actor->velocity.y += actor->gravity; - if (actor->velocity.y < actor->minVelocityY) { - actor->velocity.y = actor->minVelocityY; + actor->velocity.y += actor->gravity; + if (actor->velocity.y < actor->terminalVelocity) { + actor->velocity.y = actor->terminalVelocity; } } -void Actor_SetVelocityAndMoveYRotationAndGravity(Actor* actor) { - Actor_SetVelocityYRotationAndGravity(actor); - Actor_ApplyMovement(actor); +/** + * Moves actor accounting for its current velocity and applying gravity + * The operation is performed in cylindrical coordinates + */ +void Actor_MoveWithGravity(Actor* actor) { + Actor_UpdateVelocityWithGravity(actor); + Actor_UpdatePos(actor); } -void Actor_SetVelocityXYRotation(Actor* actor) { - f32 velX = Math_CosS(actor->world.rot.x) * actor->speedXZ; - actor->velocity.x = Math_SinS(actor->world.rot.y) * velX; +/** + * Updates actor's velocity, ignoring gravity + * The operation is performed in spherical coordinates + * + * It is recommended to not call this function directly and use `Actor_MoveWithoutGravity` instead + */ +void Actor_UpdateVelocityWithoutGravity(Actor* actor) { + f32 horizontalSpeed = Math_CosS(actor->world.rot.x) * actor->speedXZ; + + actor->velocity.x = Math_SinS(actor->world.rot.y) * horizontalSpeed; actor->velocity.y = Math_SinS(actor->world.rot.x) * actor->speedXZ; - actor->velocity.z = Math_CosS(actor->world.rot.y) * velX; + actor->velocity.z = Math_CosS(actor->world.rot.y) * horizontalSpeed; } -void Actor_SetVelocityAndMoveXYRotation(Actor* actor) { - Actor_SetVelocityXYRotation(actor); - Actor_ApplyMovement(actor); +/** + * Moves actor accounting for its current velocity, without applying gravity + * The operation is performed in spherical coordinates + * + * Useful for flying or swimming actors + */ +void Actor_MoveWithoutGravity(Actor* actor) { + Actor_UpdateVelocityWithoutGravity(actor); + Actor_UpdatePos(actor); } -void Actor_SetVelocityXYRotationReverse(Actor* actor) { - f32 velX = Math_CosS(-actor->world.rot.x) * actor->speedXZ; - actor->velocity.x = Math_SinS(actor->world.rot.y) * velX; +/** + * Like `Actor_UpdateVelocityWithoutGravity`, but the actor is moved backwards instead of forwards + * + * It is recommended to not call this function directly and use `Actor_MoveWithoutGravityReverse` instead + */ +void Actor_UpdateVelocityWithoutGravityReverse(Actor* actor) { + f32 horizontalSpeed = Math_CosS(-actor->world.rot.x) * actor->speedXZ; + + actor->velocity.x = Math_SinS(actor->world.rot.y) * horizontalSpeed; actor->velocity.y = Math_SinS(-actor->world.rot.x) * actor->speedXZ; - actor->velocity.z = Math_CosS(actor->world.rot.y) * velX; + actor->velocity.z = Math_CosS(actor->world.rot.y) * horizontalSpeed; } -void Actor_SetVelocityAndMoveXYRotationReverse(Actor* actor) { - Actor_SetVelocityXYRotationReverse(actor); - Actor_ApplyMovement(actor); +/** + * Like `Actor_MoveWithoutGravity`, but the actor is moved backwards instead of forwards + */ +void Actor_MoveWithoutGravityReverse(Actor* actor) { + Actor_UpdateVelocityWithoutGravityReverse(actor); + Actor_UpdatePos(actor); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6C04.s") +/** + * Sets horizontal speed and Y velocity using the `speed` argument and current pitch + */ +void Actor_SetSpeeds(Actor* actor, f32 speed) { + actor->speedXZ = Math_CosS(actor->world.rot.x) * speed; + actor->velocity.y = -Math_SinS(actor->world.rot.x) * speed; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6C58.s") +// unused +void Actor_UpdatePosFromSkelAnime(Actor* actor, SkelAnime* skelAnime) { + Vec3f pos; + + SkelAnime_UpdateTranslation(skelAnime, &pos, actor->shape.rot.y); + actor->world.pos.x += pos.x * actor->scale.x; + actor->world.pos.y += pos.y * actor->scale.y; + actor->world.pos.z += pos.z * actor->scale.z; +} s16 Actor_YawBetweenActors(Actor* from, Actor* to) { return Math_Vec3f_Yaw(&from->world.pos, &to->world.pos); @@ -457,171 +1246,744 @@ f32 Actor_XZDistanceToPoint(Actor* actor, Vec3f* point) { return Math_Vec3f_DistXZ(&actor->world.pos, point); } -/** Performs the affine (linear) transformation from world coordinates to actor coordinates +/** + * Find the offset of a point from an actor in that actor's own coordinates (origin at the actor's + * world.pos, z-axis is facing angle, i.e. shape.rot.y) * * @param[in] actor The actor whose coordinate system to transform to. * @param[out] offset The transformed coordinates. * @param[in] point The point to transform to actor coordinates. */ -void Actor_CalcOffsetOrientedToDrawRotation(Actor* actor, Vec3f* offset, Vec3f* point) { - f32 cos_rot_y; - f32 sin_rot_y; - f32 imm_x; - f32 imm_z; +void Actor_OffsetOfPointInActorCoords(Actor* actor, Vec3f* offset, Vec3f* point) { + f32 cos = Math_CosS(actor->shape.rot.y); + f32 sin = Math_SinS(actor->shape.rot.y); + f32 diffX; + f32 diffZ; - cos_rot_y = Math_CosS(actor->shape.rot.y); - sin_rot_y = Math_SinS(actor->shape.rot.y); - imm_x = point->x - actor->world.pos.x; - imm_z = point->z - actor->world.pos.z; - offset->x = ((imm_x * cos_rot_y) - (imm_z * sin_rot_y)); - offset->z = ((imm_z * cos_rot_y) + (imm_x * sin_rot_y)); + // Shift X,Z to actor coordinates origin + diffX = point->x - actor->world.pos.x; + diffZ = point->z - actor->world.pos.z; + + // Rotate X and Z offsets to align Z to actor's shape.rot.y + offset->x = ((diffX * cos) - (diffZ * sin)); + offset->z = ((diffZ * cos) + (diffX * sin)); + + // Shift Y to origin offset->y = point->y - actor->world.pos.y; } -f32 Actor_YDistance(Actor* actor1, Actor* actor2) { +f32 Actor_HeightDiff(Actor* actor1, Actor* actor2) { return actor2->world.pos.y - actor1->world.pos.y; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6F20.s") +/** + * Sets the current and new inputs. + */ +void func_800B6F20(GlobalContext* globalCtx, Input* input, f32 magnitude, s16 baseYaw) { + s16 relativeYaw = baseYaw - Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx)); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B6FC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7090.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7118.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7128.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B715C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7170.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B71DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7200.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B722C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B724C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7298.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B72E0.s") - -void func_800B72F8(DynaPolyActor* dpactor, f32 a1, s16 a2) { - dpactor->unk150 = a2; - dpactor->unk148 += a1; + input->cur.stick_x = -Math_SinS(relativeYaw) * magnitude; + input->rel.stick_x = input->cur.stick_x; + input->cur.stick_y = Math_CosS(relativeYaw) * magnitude; + input->rel.stick_y = input->cur.stick_y; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_IsLinkFacingActor.s") +f32 Player_GetHeight(Player* player) { + f32 extraHeight; -s32 Actor_IsActorFacedByActor(Actor* actor, Actor* other, s16 tolerance) { - s16 angle; - s16 dist; - - angle = BINANG_ROT180(Actor_YawBetweenActors(actor, other)); - dist = angle - other->shape.rot.y; - if (ABS_ALT(dist) < tolerance) { - return 1; + if (player->stateFlags1 & 0x800000) { + extraHeight = 32.0f; + } else { + extraHeight = 0.0f; } - return 0; -} -s32 Actor_IsActorFacingLink(Actor* actor, s16 angle) { - s16 dist; - - dist = actor->yawTowardsPlayer - actor->shape.rot.y; - if (ABS_ALT(dist) < angle) { - return 1; + switch (player->transformation) { + default: + case PLAYER_FORM_FIERCE_DEITY: + return extraHeight + 124.0f; + case PLAYER_FORM_GORON: + // (player->stateFlags3 & 0x1000): being curled? + return extraHeight + ((player->stateFlags3 & 0x1000) ? 34.0f : 80.0f); + case PLAYER_FORM_ZORA: + return extraHeight + 68.0f; + case PLAYER_FORM_DEKU: + return extraHeight + 36.0f; + case PLAYER_FORM_HUMAN: + return extraHeight + 44.0f; } - return 0; } -s32 Actor_IsActorFacingActor(Actor* actor, Actor* other, s16 tolerance) { - s16 dist; - - dist = Actor_YawBetweenActors(actor, other) - actor->shape.rot.y; - if (ABS_ALT(dist) < tolerance) { - return 1; +f32 Player_GetRunSpeedLimit(Player* player) { + if (player->stateFlags1 & 0x800000) { + return 15.0f; + } else if (player->stateFlags1 & 0x8000000) { + return (R_RUN_SPEED_LIMIT / 100.0f) * 0.6f; + } else { + return R_RUN_SPEED_LIMIT / 100.0f; } - return 0; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_IsActorFacingLinkAndWithinRange.s") +s32 func_800B7118(Player* player) { + return player->stateFlags1 & 0x8; +} -s32 Actor_IsActorFacingActorAndWithinRange(Actor* actor, Actor* other, f32 range, s16 tolerance) { - s16 dist; +s32 func_800B7128(Player* player) { + return func_800B7118(player) && player->unk_ACC; +} - if (Actor_DistanceBetweenActors(actor, other) < range) { - dist = Actor_YawBetweenActors(actor, other) - actor->shape.rot.y; - if (ABS_ALT(dist) < tolerance) { - return 1; +s32 func_800B715C(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + return player->stateFlags2 & 0x8; +} + +void Actor_SetCameraHorseSetting(GlobalContext* globalCtx, Player* player) { + if ((globalCtx->roomCtx.currRoom.unk3 != 4) && (player->actor.id == ACTOR_PLAYER)) { + EnHorse* rideActor = (EnHorse*)player->rideActor; + + if ((rideActor != NULL) && !(rideActor->unk_1EC & 0x10)) { + func_800DFAC8(Play_GetCamera(globalCtx, CAM_ID_MAIN), 4); } } - return 0; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B75A0.s") +void Actor_MountHorse(GlobalContext* globalCtx, Player* player, Actor* horse) { + player->rideActor = horse; + player->stateFlags1 |= 0x800000; + horse->child = &player->actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B761C.s") +s32 func_800B7200(Player* player) { + return (player->stateFlags1 & 0x20000080) || (player->csMode != 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7678.s") +void func_800B722C(GameState* gameState, Player* player) { + func_800F40A0(gameState, player); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_UpdateBgCheckInfo.s") +s32 func_800B724C(GlobalContext* globalCtx, Actor* actor, u8 csMode) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7E04.s") + if ((player->csMode == 5) || ((csMode == 6) && (player->csMode == 0))) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B7FE0.s") + player->csMode = csMode; + player->unk_398 = actor; + player->unk_3BA = 0; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8018.s") +u32 func_800B7298(GlobalContext* globalCtx, Actor* actor, u8 csMode) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8050.s") + if (func_800B724C(globalCtx, actor, csMode)) { + player->unk_3BA = 1; + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8118.s") +// Unused +void func_800B72E0(DynaPolyActor* dyna) { + dyna->unk14C = 0.0f; + dyna->pushForce = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B81E0.s") +void func_800B72F8(DynaPolyActor* dyna, f32 extraPushForce, s16 yRotation) { + dyna->yRotation = yRotation; + dyna->pushForce += extraPushForce; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8214.s") +/** + * Check if the player is facing the specified actor. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngleDiff`. + */ +s32 Player_IsFacingActor(Actor* actor, s16 maxAngleDiff, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 yawDiff = BINANG_ADD(actor->yawTowardsPlayer, 0x8000) - player->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8248.s") + if (ABS_ALT(yawDiff) < maxAngleDiff) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B82EC.s") +/** + * Check if `actorB` is facing `actorA`. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngle`. + * + * This function is unused in the original game. + */ +s32 Actor_ActorBIsFacingActorA(Actor* actorA, Actor* actorB, s16 maxAngleDiff) { + s16 angle = BINANG_ROT180(Actor_YawBetweenActors(actorA, actorB)); + s16 dist = angle - actorB->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B83BC.s") + if (ABS_ALT(dist) < maxAngleDiff) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B83F8.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B84D0.s") +/** + * Check if the specified actor is facing the player. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngleDiff`. + */ +s32 Actor_IsFacingPlayer(Actor* actor, s16 angle) { + s16 dist = actor->yawTowardsPlayer - actor->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8500.s") + if (ABS_ALT(dist) < angle) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B85E0.s") +/** + * Check if `actorA` is facing `actorB`. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngleDiff`. + */ +s32 Actor_ActorAIsFacingActorB(Actor* actorA, Actor* actorB, s16 maxAngleDiff) { + s16 dist = Actor_YawBetweenActors(actorA, actorB) - actorA->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8614.s") + if (ABS_ALT(dist) < maxAngleDiff) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B863C.s") +/** + * Check if the specified actor is facing the player and is nearby. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngleDiff`. + * The maximum distance that qualifies as "nearby" is specified by `range`. + */ +s32 Actor_IsFacingAndNearPlayer(Actor* actor, f32 range, s16 maxAngleDiff) { + s16 yaw = actor->yawTowardsPlayer - actor->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B867C.s") + if (ABS_ALT(yaw) < maxAngleDiff) { + s16 pad; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B86C8.s") + if (sqrtf(SQ(actor->xzDistToPlayer) + SQ(actor->playerHeightRel)) < range) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8708.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8718.s") +/** + * Check if `actorA` is facing `actorB` and is nearby. + * The maximum angle difference that qualifies as "facing" is specified by `maxAngleDiff`. + * The maximum distance that qualifies as "nearby" is specified by `range`. + */ +s32 Actor_ActorAIsFacingAndNearActorB(Actor* actorA, Actor* actorB, f32 range, s16 maxAngleDiff) { + if (Actor_DistanceBetweenActors(actorA, actorB) < range) { + s16 dist = Actor_YawBetweenActors(actorA, actorB) - actorA->shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B874C.s") + if (ABS_ALT(dist) < maxAngleDiff) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8804.s") +/* Start of BgCheck related section */ -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B882C.s") +void func_800B75A0(CollisionPoly* poly, Vec3f* normal, s16* azimuth) { + normal->x = COLPOLY_GET_NORMAL(poly->normal.x); + normal->y = COLPOLY_GET_NORMAL(poly->normal.y); + normal->z = COLPOLY_GET_NORMAL(poly->normal.z); + *azimuth = Math_FAtan2F(normal->z, normal->x); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B886C.s") +s32 func_800B761C(Actor* actor, f32 arg1, s32 arg2) { + if (actor->bgCheckFlags & 1) { + actor->bgCheckFlags &= ~1; + actor->bgCheckFlags |= 4; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8898.s") + if ((actor->velocity.y < 0.0f) && (arg2 & 0x10)) { + actor->velocity.y = 0.0f; + } + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8934.s") + return true; +} -u32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx) { +s32 func_800B7678(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, s32 flags) { + f32 distToFloor; + s32 bgId; + + pos->y += (flags & 0x800) ? 10.0f : 50.0f; + + actor->floorHeight = + BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &actor->floorPoly, &bgId, actor, pos); + actor->bgCheckFlags &= ~(0x80 | 0x04 | 0x02); + if (actor->floorHeight <= BGCHECK_Y_MIN) { + return func_800B761C(actor, BGCHECK_Y_MIN, flags); + } + + distToFloor = actor->floorHeight - actor->world.pos.y; + actor->floorBgId = bgId; + if ((distToFloor >= 0.0f) || (((actor->bgCheckFlags & 1)) && !(actor->bgCheckFlags & 0x800) && + (distToFloor >= -11.0f) && (actor->velocity.y < 0.0f))) { + actor->bgCheckFlags |= 0x80; + + if (actor->bgCheckFlags & 0x10) { + if (bgId != D_801ED8B4) { + if (distToFloor > 15.0f) { + actor->bgCheckFlags |= 0x100; + } + } else { + actor->world.pos.x = actor->prevPos.x; + actor->world.pos.z = actor->prevPos.z; + } + } + + actor->world.pos.y = actor->floorHeight; + + if (actor->velocity.y <= 0.0f) { + if (!(actor->bgCheckFlags & 1)) { + actor->bgCheckFlags |= 2; + } else if ((flags & 8) && (actor->gravity < 0.0f)) { + actor->velocity.y = -4.0f; + } else if (!(flags & 0x100)) { + actor->velocity.y = 0.0f; + } + + actor->bgCheckFlags |= 1; + BgCheck2_AttachToMesh(&globalCtx->colCtx, actor, (s32)actor->floorBgId); + } + } else { + return func_800B761C(actor, distToFloor, flags); + } + + return true; +} + +void Actor_UpdateBgCheckInfo(GlobalContext* globalCtx, Actor* actor, f32 wallCheckHeight, f32 wallCheckRadius, + f32 ceilingCheckHeight, u32 flags) { + f32 sp94 = actor->world.pos.y - actor->prevPos.y; + s32 pad; + Vec3f pos; + + if ((actor->floorBgId != BGCHECK_SCENE) && (actor->bgCheckFlags & 1)) { + BgCheck2_UpdateActorAttachedToMesh(&globalCtx->colCtx, actor->floorBgId, actor); + } + + if (flags & 1) { + s32 bgId; + + actor->bgCheckFlags &= ~0x1000; + if ((!(flags & 0x80) && + (BgCheck_EntitySphVsWall3(&globalCtx->colCtx, &pos, &actor->world.pos, &actor->prevPos, wallCheckRadius, + &actor->wallPoly, &bgId, actor, wallCheckHeight))) || + ((flags & 0x80) && + (BgCheck_EntitySphVsWall4(&globalCtx->colCtx, &pos, &actor->world.pos, &actor->prevPos, wallCheckRadius, + &actor->wallPoly, &bgId, actor, wallCheckHeight)))) { + CollisionPoly* sp7C = actor->wallPoly; + + actor->bgCheckFlags |= 8; + if ((flags & 0x200) && (actor->bgCheckFlags & 0x1000) && ((s32)sp7C->normal.y > 0) && + (sqrtf(SQXYZ(actor->colChkInfo.displacement)) < 10.0f)) { + actor->bgCheckFlags &= ~8; + } else if (actor->bgCheckFlags & 8) { + Math_Vec3f_Copy(&actor->world.pos, &pos); + } + + actor->wallYaw = Math_FAtan2F(sp7C->normal.z, sp7C->normal.x); + actor->wallBgId = bgId; + } else { + actor->bgCheckFlags &= ~8; + } + } + + pos.x = actor->world.pos.x; + pos.z = actor->world.pos.z; + if (flags & 2) { + f32 y; + + pos.y = actor->prevPos.y + 4.0f; + if (BgCheck_EntityCheckCeiling(&globalCtx->colCtx, &y, &pos, (ceilingCheckHeight + sp94) - 4.0f, &D_801ED8B0, + &D_801ED8B4, actor)) { + actor->bgCheckFlags |= 0x10; + actor->world.pos.y = (y + sp94) - 4.0f; + } else { + actor->bgCheckFlags &= ~0x10; + } + } + if (flags & 4) { + WaterBox* waterbox; + f32 y; + + pos.y = actor->prevPos.y; + func_800B7678(globalCtx, actor, &pos, flags); + y = actor->world.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, actor->world.pos.x, actor->world.pos.z, &y, + &waterbox)) { + actor->depthInWater = y - actor->world.pos.y; + if (actor->depthInWater <= 0.0f) { + actor->bgCheckFlags &= ~(0x40 | 0x20); + } else if (!(actor->bgCheckFlags & 0x20)) { + actor->bgCheckFlags |= (0x40 | 0x20); + if (!(flags & 0x40)) { + Vec3f sp64; + + sp64.x = actor->world.pos.x; + sp64.y = y; + sp64.z = actor->world.pos.z; + + EffectSsGRipple_Spawn(globalCtx, &sp64, 100, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &sp64, 100, 500, 4); + EffectSsGRipple_Spawn(globalCtx, &sp64, 100, 500, 8); + } + } else { + actor->bgCheckFlags &= ~0x40; + } + } else { + actor->bgCheckFlags &= ~(0x40 | 0x20); + actor->depthInWater = BGCHECK_Y_MIN; + } + } + + if (flags & 0x400) { + WaterBox* waterbox; + f32 y = actor->world.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, actor->world.pos.x, actor->world.pos.z, &y, + &waterbox)) { + actor->depthInWater = y - actor->world.pos.y; + + if (actor->depthInWater < 0.0f) { + actor->bgCheckFlags &= ~(0x40 | 0x20); + } else if (!(actor->bgCheckFlags & 0x20)) { + actor->bgCheckFlags |= (0x40 | 0x20); + if (!(flags & 0x40)) { + Vec3f sp50; + + sp50.x = actor->world.pos.x; + sp50.y = y; + sp50.z = actor->world.pos.z; + + EffectSsGRipple_Spawn(globalCtx, &sp50, 100, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &sp50, 100, 500, 4); + EffectSsGRipple_Spawn(globalCtx, &sp50, 100, 500, 8); + } + } else { + actor->bgCheckFlags &= ~0x40; + } + } else { + actor->bgCheckFlags &= ~(0x40 | 0x20); + actor->depthInWater = BGCHECK_Y_MIN; + } + } +} + +Gfx* Hilite_Draw(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx, Gfx* dl, Hilite** hilite) { + LookAt* lookAt = GRAPH_ALLOC(gfxCtx, sizeof(LookAt)); + f32 correctedEyeX = (eye->x == object->x) && (eye->z == object->z) ? eye->x + 0.001f : eye->x; + + *hilite = GRAPH_ALLOC(gfxCtx, sizeof(Hilite)); + + guLookAtHilite(&D_801ED8E0, lookAt, *hilite, correctedEyeX, eye->y, eye->z, object->x, object->y, object->z, 0.0f, + 1.0f, 0.0f, lightDir->x, lightDir->y, lightDir->z, lightDir->x, lightDir->y, lightDir->z, 0x10, + 0x10); + + gSPLookAt(dl++, lookAt); + gDPSetHilite1Tile(dl++, 1, *hilite, 0x10, 0x10); + + return dl; +} + +Hilite* Hilite_DrawOpa(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx) { + Hilite* hilite; + + OPEN_DISPS(gfxCtx); + + POLY_OPA_DISP = Hilite_Draw(object, eye, lightDir, gfxCtx, POLY_OPA_DISP, &hilite); + + CLOSE_DISPS(gfxCtx); + + return hilite; +} + +Hilite* Hilite_DrawXlu(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext* gfxCtx) { + Hilite* hilite; + + OPEN_DISPS(gfxCtx); + + POLY_XLU_DISP = Hilite_Draw(object, eye, lightDir, gfxCtx, POLY_XLU_DISP, &hilite); + + CLOSE_DISPS(gfxCtx); + + return hilite; +} + +void func_800B8050(Actor* actor, GlobalContext* globalCtx, s32 flag) { + Hilite* hilite = func_800BCBF4(&actor->world.pos, globalCtx); + + if (flag != 0) { + Gfx* displayListHead; + Gfx* displayList = GRAPH_ALLOC(globalCtx->state.gfxCtx, 2 * sizeof(Gfx)); + + displayListHead = displayList; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPSetHilite1Tile(displayListHead++, 1, hilite, 0x10, 0x10); + gSPEndDisplayList(displayListHead); + gSPSegment(POLY_OPA_DISP++, 0x07, displayList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_800B8118(Actor* actor, GlobalContext* globalCtx, s32 flag) { + Hilite* hilite = func_800BCC68(&actor->world.pos, globalCtx); + + if (flag != 0) { + Gfx* displayListHead; + Gfx* displayList = GRAPH_ALLOC(globalCtx->state.gfxCtx, 2 * sizeof(Gfx)); + + displayListHead = displayList; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPSetHilite1Tile(displayListHead++, 1, hilite, 0x10, 0x10); + gSPEndDisplayList(displayListHead); + gSPSegment(POLY_XLU_DISP++, 0x07, displayList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +PosRot* Actor_GetFocus(PosRot* dest, Actor* actor) { + *dest = actor->focus; + + return dest; +} + +PosRot* Actor_GetWorld(PosRot* dest, Actor* actor) { + *dest = actor->world; + + return dest; +} + +PosRot* Actor_GetWorldPosShapeRot(PosRot* dest, Actor* actor) { + PosRot sp1C; + + Math_Vec3f_Copy(&sp1C.pos, &actor->world.pos); + if (actor->id == ACTOR_PLAYER) { + Player* player = (Player*)actor; + + sp1C.pos.y += player->unk_AC0 * actor->scale.y; + } + sp1C.rot = actor->shape.rot; + *dest = sp1C; + + return dest; +} + +f32 func_800B82EC(Actor* actor, Player* player, s16 angle) { + f32 temp_f12; + s16 temp_v0 = BINANG_SUB(BINANG_SUB(actor->yawTowardsPlayer, 0x8000), angle); + s16 yaw = ABS_ALT(temp_v0); + + if (player->unk_730 != NULL) { + if ((yaw > 0x4000) || ((actor->flags & ACTOR_FLAG_8000000))) { + return FLT_MAX; + } + + temp_f12 = actor->xyzDistToPlayerSq - ((actor->xyzDistToPlayerSq * 0.8f) * ((0x4000 - yaw) * (1.0f / 0x8000))); + return temp_f12; + } + + if (yaw >= 0x2AAB) { + return FLT_MAX; + } + return actor->xyzDistToPlayerSq; +} + +#define TARGET_RANGE(range, leash) \ + { SQ(range), (f32)range / leash } + +TargetRangeParams gTargetRanges[] = { + TARGET_RANGE(70, 140), TARGET_RANGE(170, 255), TARGET_RANGE(280, 5600), TARGET_RANGE(350, 525), + TARGET_RANGE(700, 1050), TARGET_RANGE(1000, 1500), TARGET_RANGE(100, 105.36842), TARGET_RANGE(140, 163.33333), + TARGET_RANGE(240, 576), TARGET_RANGE(280, 280000), TARGET_RANGE(2500, 3750), +}; + +s32 func_800B83BC(Actor* actor, f32 arg1) { + return arg1 < gTargetRanges[actor->targetMode].rangeSq; +} + +s32 func_800B83F8(Actor* actor, Player* player, s32 flag) { + if ((actor->update == NULL) || !(actor->flags & ACTOR_FLAG_1) || (actor->flags & ACTOR_FLAG_8000000)) { + return true; + } + + if (!flag) { + s16 yaw = BINANG_SUB(actor->yawTowardsPlayer, 0x8000) - player->actor.shape.rot.y; + s16 phi_v1 = ABS_ALT(yaw); + f32 dist; + + if ((player->unk_730 == NULL) && (phi_v1 >= 0x2AAB)) { + dist = FLT_MAX; + } else { + dist = actor->xyzDistToPlayerSq; + } + + return !func_800B83BC(actor, gTargetRanges[actor->targetMode].leashScale * dist); + } + + return false; +} + +s16 D_801AED48[] = { + 0x101, 0x141, 0x111, 0x151, 0x105, 0x145, 0x115, 0x155, +}; + +s32 Actor_ProcessTalkRequest(Actor* actor, GameState* gameState) { + if (actor->flags & ACTOR_FLAG_100) { + actor->flags &= ~ACTOR_FLAG_100; + return true; + } + + return false; +} + +// Actor_PickUpExchange? Seems to be called with exchangeItemId -1 if the same actor used Actor_PickUp +// This function is also used to toggle the "Speak" action on the A button +s32 func_800B8500(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exchangeItemId) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->actor.flags & ACTOR_FLAG_100) || + ((exchangeItemId > EXCH_ITEM_NONE) && Player_InCsMode(&globalCtx->state)) || + (!actor->isTargeted && + ((fabsf(actor->playerHeightRel) > fabsf(yRange)) || ((actor->xzDistToPlayer > player->targetActorDistance)) || + (xzRange < actor->xzDistToPlayer)))) { + return false; + } + + player->targetActor = actor; + player->targetActorDistance = actor->xzDistToPlayer; + player->exchangeItemId = exchangeItemId; + + ActorCutscene_SetIntentToPlay(0x7C); + return true; +} + +s32 func_800B85E0(Actor* actor, GlobalContext* globalCtx, f32 radius, s32 exchangeItemId) { + return func_800B8500(actor, globalCtx, radius, radius, exchangeItemId); +} + +s32 func_800B8614(Actor* actor, GlobalContext* globalCtx, f32 radius) { + return func_800B85E0(actor, globalCtx, radius, EXCH_ITEM_NONE); +} + +s32 func_800B863C(Actor* actor, GlobalContext* globalCtx) { + f32 cylRadius = actor->colChkInfo.cylRadius + 50.0f; + + return func_800B8614(actor, globalCtx, cylRadius); +} + +s32 Actor_TextboxIsClosing(Actor* actor, GlobalContext* globalCtx) { + if (Message_GetState(&globalCtx->msgCtx) == 2) { + actor->flags &= ~ACTOR_FLAG_100; + return true; + } + + return false; +} + +/** + * Changes the actor the Player is focussing on + * Fails if Player is not already focussing on an actor or in a talking state + */ +s32 Actor_ChangeFocus(Actor* actor1, GlobalContext* globalCtx, Actor* actor2) { + Actor* targetActor; + Player* player = GET_PLAYER(globalCtx); + + targetActor = player->targetActor; + + if ((player->actor.flags & ACTOR_FLAG_100) && (targetActor != NULL)) { + player->targetActor = actor2; + player->unk_730 = actor2; + return true; + } + + return false; +} + +s32 Player_GetExchangeItemId(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + return player->exchangeItemId; +} + +s32 func_800B8718(Actor* actor, GameState* gameState) { + if (actor->flags & ACTOR_FLAG_20000000) { + actor->flags &= ~ACTOR_FLAG_20000000; + return true; + } + + return false; +} + +// Similar to func_800B8500 +s32 func_800B874C(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->actor.flags & ACTOR_FLAG_20000000) || Player_InCsMode(&globalCtx->state) || + (yRange < fabsf(actor->playerHeightRel)) || ((player->unk_A94 < actor->xzDistToPlayer)) || + (xzRange < actor->xzDistToPlayer)) { + return false; + } + + player->unk_A90 = actor; + player->unk_A94 = actor->xzDistToPlayer; + return true; +} + +s32 func_800B8804(Actor* actor, GlobalContext* globalCtx, f32 xzRange) { + return func_800B874C(actor, globalCtx, xzRange, 20.0f); +} + +s32 func_800B882C(Actor* actor, GlobalContext* globalCtx) { + f32 cylRadius = actor->colChkInfo.cylRadius + 50.0f; + + return func_800B8804(actor, globalCtx, cylRadius); +} + +s32 func_800B886C(Actor* actor, GlobalContext* globalCtx) { + if (!(GET_PLAYER(globalCtx)->actor.flags & ACTOR_FLAG_20000000)) { + return true; + } + + return false; +} + +void Actor_GetScreenPos(GlobalContext* globalCtx, Actor* actor, s16* x, s16* y) { + Vec3f projectedPos; + f32 w; + + Actor_GetProjectedPos(globalCtx, &actor->focus.pos, &projectedPos, &w); + *x = (projectedPos.x * w * (SCREEN_WIDTH / 2)) + (SCREEN_WIDTH / 2); + *y = (projectedPos.y * w * -(SCREEN_HEIGHT / 2)) + (SCREEN_HEIGHT / 2); +} + +s32 func_800B8934(GlobalContext* globalCtx, Actor* actor) { + Vec3f sp2C; + f32 sp28; + s32 pad[2]; + + Actor_GetProjectedPos(globalCtx, &actor->focus.pos, &sp2C, &sp28); + + return (sp2C.x * sp28 >= -1.0f) && (sp2C.x * sp28 <= 1.0f) && (sp2C.y * sp28 >= -1.0f) && (sp2C.y * sp28 <= 1.0f); +} + +s32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx) { if (actor->parent != NULL) { return true; } else { @@ -629,119 +1991,1125 @@ u32 Actor_HasParent(Actor* actor, GlobalContext* globalCtx) { } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8A1C.s") +/** + * Allows to pick up an item (GetItem or GI), lift an actor or catch various actors in bottles + * within the specified range. + * + * GI_NONE is usually used as a special case to lift an actor + * GI_MAX is usually used to catch an actor in a bottle + */ +s32 Actor_PickUp(Actor* actor, GlobalContext* globalCtx, s32 getItemId, f32 xzRange, f32 yRange) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8B84.s") + if (!(player->stateFlags1 & 0x3C7080) && Player_GetExplosiveHeld(player) < 0) { + if ((actor->xzDistToPlayer <= xzRange) && (fabsf(actor->playerHeightRel) <= fabsf(yRange))) { + if (((getItemId == GI_MASK_CIRCUS_LEADER) || (getItemId == GI_PENDANT_OF_MEMORIES) || + (getItemId == GI_DEED_LAND) || + (((player->heldActor != NULL) || (actor == player->targetActor)) && + (getItemId > GI_NONE && getItemId < GI_MAX))) || + (!(player->stateFlags1 & 0x20000800))) { + s16 yawDiff = actor->yawTowardsPlayer - player->actor.shape.rot.y; + s32 absYawDiff = ABS_ALT(yawDiff); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8BB0.s") + if ((getItemId != GI_NONE) || (player->getItemDirection < absYawDiff)) { + player->getItemId = getItemId; + player->interactRangeActor = actor; + player->getItemDirection = absYawDiff; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8BD0.s") + if ((getItemId > GI_NONE) && (getItemId < GI_MAX)) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[1]); + } + + return true; + } + } + } + } + + return false; +} + +s32 Actor_PickUpNearby(Actor* actor, GlobalContext* globalCtx, s32 getItemId) { + return Actor_PickUp(actor, globalCtx, getItemId, 50.0f, 10.0f); +} + +s32 Actor_LiftActor(Actor* actor, GlobalContext* globalCtx) { + return Actor_PickUpNearby(actor, globalCtx, GI_NONE); +} + +s32 Actor_PickUpFar(Actor* actor, GlobalContext* globalCtx, s32 getItemId) { + return Actor_PickUp(actor, globalCtx, getItemId, 9999.9f, 9999.9f); +} s32 Actor_HasNoParent(Actor* actor, GlobalContext* globalCtx) { - if (!actor->parent) { + if (actor->parent == NULL) { return true; - } else { - return false; + } + + return false; +} + +void func_800B8C20(Actor* actorA, Actor* actorB, GlobalContext* globalCtx) { + Actor* parent = actorA->parent; + + if (parent->id == ACTOR_PLAYER) { + Player* player = (Player*)parent; + + player->heldActor = actorB; + player->interactRangeActor = actorB; + } + + parent->child = actorB; + actorB->parent = parent; + actorA->parent = NULL; +} + +void func_800B8C50(Actor* actor, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (actor->xyzDistToPlayerSq < player->unk_AA0) { + player->unk_AA0 = actor->xyzDistToPlayerSq; } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8C20.s") +s32 Actor_HasRider(GlobalContext* globalCtx, Actor* horse) { + if (horse->child != NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8C50.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8C78.s") +s32 Actor_SetRideActor(GlobalContext* globalCtx, Actor* horse, s32 mountSide) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8C9C.s") + if (!(player->stateFlags1 & 0x003C7880)) { + player->rideActor = horse; + player->mountSide = mountSide; + ActorCutscene_SetIntentToPlay(0x7C); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8CEC.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8D10.s") +s32 Actor_HasNoRider(GlobalContext* globalCtx, Actor* horse) { + if (horse->child == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8D50.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8D98.s") +void func_800B8D10(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4, u32 arg5, u32 arg6) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8DD4.s") + player->unk_B74 = arg6; + player->unk_B75 = arg5; + player->unk_B78 = arg2; + player->unk_B76 = arg3; + player->unk_B7C = arg4; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8E1C.s") +void func_800B8D50(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 yaw, f32 arg4, u32 arg5) { + func_800B8D10(globalCtx, actor, arg2, yaw, arg4, 3, arg5); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8E58.s") +void func_800B8D98(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4) { + func_800B8D50(globalCtx, actor, arg2, arg3, arg4, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Audio_PlayActorSound2.s") +void func_800B8DD4(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4, u32 arg5) { + func_800B8D10(globalCtx, actor, arg2, arg3, arg4, 2, arg5); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8EF4.s") +void func_800B8E1C(GlobalContext* globalCtx, Actor* actor, f32 arg2, s16 arg3, f32 arg4) { + func_800B8DD4(globalCtx, actor, arg2, arg3, arg4, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8F98.s") +void func_800B8E58(Player* player, u16 sfxId) { + if (player->currentMask == PLAYER_MASK_GIANT) { + func_8019F170(&player->actor.projectedPos, sfxId); + } else { + Audio_PlaySfxGeneral(sfxId, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8FC0.s") +/** + * Plays the sound effect at the actor's position + */ +void Actor_PlaySfxAtPos(Actor* actor, u16 sfxId) { + Audio_PlaySfxAtPos(&actor->projectedPos, sfxId); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B8FE8.s") +void func_800B8EF4(GlobalContext* globalCtx, Actor* actor) { + u32 sfxId; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9010.s") + if (actor->bgCheckFlags & 0x20) { + if (actor->depthInWater < 20.0f) { + sfxId = NA_SE_PL_WALK_WATER0 - SFX_FLAG; + } else { + sfxId = NA_SE_PL_WALK_WATER1 - SFX_FLAG; + } + } else { + sfxId = SurfaceType_GetSfx(&globalCtx->colCtx, actor->floorPoly, actor->floorBgId); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9038.s") + Audio_PlaySfxAtPos(&actor->projectedPos, NA_SE_EV_BOMB_BOUND); + Audio_PlaySfxAtPos(&actor->projectedPos, sfxId + SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9084.s") +void func_800B8F98(Actor* actor, u16 sfxId) { + actor->sfxId = sfxId; + actor->audioFlags &= ~(0x10 | 0x08 | 0x04 | 0x02 | 0x01); + actor->audioFlags |= 0x02; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9098.s") +void func_800B8FC0(Actor* actor, u16 sfxId) { + actor->sfxId = sfxId; + actor->audioFlags &= ~(0x10 | 0x08 | 0x04 | 0x02 | 0x01); + actor->audioFlags |= 4; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B90AC.s") +void func_800B8FE8(Actor* actor, u16 sfxId) { + actor->sfxId = sfxId; + actor->audioFlags &= ~(0x10 | 0x08 | 0x04 | 0x02 | 0x01); + actor->audioFlags |= 0x08; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B90F4.s") +void func_800B9010(Actor* actor, u16 sfxId) { + actor->sfxId = sfxId; + actor->audioFlags &= ~(0x10 | 0x08 | 0x04 | 0x02 | 0x01); + actor->audioFlags |= 0x01; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9120.s") +void func_800B9038(Actor* actor, s32 timer) { + actor->audioFlags &= ~(0x10 | 0x08 | 0x04 | 0x02 | 0x01); + actor->audioFlags |= 0x10; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_Init.s") + // The sfxId here are not actually sound effects, but instead this is data that gets sent into + // the io ports of the music macro language (func_801A0810 / Audio_PlaySfxAtPosWithSoundScriptIO is + // the function that it's used for) + if (timer < 40) { + actor->sfxId = 3; + } else if (timer < 100) { + actor->sfxId = 2; + } else { + actor->sfxId = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9334.s") +void func_800B9084(Actor* actor) { + actor->audioFlags |= 0x20; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_UpdateActor.s") +void func_800B9098(Actor* actor) { + actor->audioFlags |= 0x40; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_UpdateAll.s") +s32 func_800B90AC(GlobalContext* globalCtx, Actor* actor, CollisionPoly* polygon, s32 index, s32 arg4) { + if (func_800C99D4(&globalCtx->colCtx, polygon, index) == 8) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_DrawActor.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9D1C.s") +void func_800B90F4(GlobalContext* globalCtx) { + if (globalCtx->actorCtx.unk3 != 0) { + globalCtx->actorCtx.unk3 = 0; + func_80115D5C(&globalCtx->state); + } +} + +void func_800B9120(ActorContext* actorCtx) { + s32 phi_v0 = CURRENT_DAY * 2; + + if (gSaveContext.save.time < CLOCK_TIME(6, 0) || gSaveContext.save.time > CLOCK_TIME(18, 0)) { + phi_v0++; + } + + actorCtx->unkC = 0x200 >> phi_v0; +} + +void Actor_InitContext(GlobalContext* globalCtx, ActorContext* actorCtx, ActorEntry* actorEntry) { + ActorOverlay* overlayEntry; + CycleSceneFlags* cycleFlags; + s32 i; + + gSaveContext.save.weekEventReg[92] |= 0x80; + cycleFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(globalCtx->sceneNum)]; + + bzero(actorCtx, sizeof(ActorContext)); + ActorOverlayTable_Init(); + Matrix_MtxFCopy(&globalCtx->billboardMtxF, &gIdentityMtxF); + Matrix_MtxFCopy(&globalCtx->viewProjectionMtxF, &gIdentityMtxF); + + overlayEntry = gActorOverlayTable; + for (i = 0; i < ARRAY_COUNT(gActorOverlayTable); i++) { + overlayEntry->loadedRamAddr = NULL; + overlayEntry->numLoaded = 0; + overlayEntry++; + } + + actorCtx->flags.chest = cycleFlags->chest; + actorCtx->flags.switches[0] = cycleFlags->switch0; + actorCtx->flags.switches[1] = cycleFlags->switch1; + if (globalCtx->sceneNum == SCENE_INISIE_R) { + cycleFlags = &gSaveContext.cycleSceneFlags[globalCtx->sceneNum]; + } + actorCtx->flags.collectible[0] = cycleFlags->collectible; + actorCtx->flags.clearedRoom = cycleFlags->clearedRoom; + + TitleCard_ContextInit(&globalCtx->state, &actorCtx->titleCtxt); + func_800B6468(globalCtx); + + actorCtx->absoluteSpace = NULL; + + Actor_SpawnEntry(actorCtx, actorEntry, globalCtx); + Actor_TargetContextInit(&actorCtx->targetContext, actorCtx->actorLists[ACTORCAT_PLAYER].first, globalCtx); + func_800B9120(actorCtx); + Fault_AddClient(&sActorFaultClient, (void*)Actor_PrintLists, actorCtx, NULL); + func_800B722C(&globalCtx->state, (Player*)actorCtx->actorLists[ACTORCAT_PLAYER].first); +} + +/** + * Spawns the actors in the current setup (of the current scene/setup/room triple) + * Only spawns actors based on the time flags embedded in their rotation parameters + */ +void Actor_SpawnSetupActors(GlobalContext* globalCtx, ActorContext* actorCtx) { + if (globalCtx->numSetupActors > 0) { + ActorEntry* actorEntry = globalCtx->setupActorList; + s32 temp_fp = actorCtx->unkC; + s32 temp_s1; + s32 phi_v0; + s32 i; + + func_800B9120(actorCtx); + func_800BA8B8(globalCtx, &globalCtx->actorCtx); + + temp_s1 = (actorCtx->unkC * 2) & 0x2FF; + + for (i = 0; i < globalCtx->numSetupActors; i++) { + phi_v0 = ((actorEntry->rot.x & 7) << 7) | (actorEntry->rot.z & 0x7F); + if (phi_v0 == 0) { + phi_v0 = 0x3FF; + } + + if (!(phi_v0 & temp_fp) && (phi_v0 & actorCtx->unkC) && + (!(gSaveContext.eventInf[1] & 0x80) || !(phi_v0 & temp_s1) || !(actorEntry->id & 0x800))) { + Actor_SpawnEntry(&globalCtx->actorCtx, actorEntry, globalCtx); + } + actorEntry++; + } + + // Prevents re-spawning the setup actors + globalCtx->numSetupActors = -globalCtx->numSetupActors; + } +} + +typedef struct { + /* 0x00 */ GlobalContext* globalCtx; + /* 0x04 */ Actor* actor; + /* 0x08 */ u32 unk_08; + /* 0x0C */ u32 unkC; + /* 0x10 */ Actor* unk10; + /* 0x14 */ Player* player; + /* 0x18 */ u32 unk_18; // Bitmask of actor flags. The actor will only have main called if it has at least 1 + // flag set that matches this bitmask +} UpdateActor_Params; // size = 0x1C + +Actor* Actor_UpdateActor(UpdateActor_Params* params) { + GlobalContext* globalCtx = params->globalCtx; + Actor* actor = params->actor; + Actor* nextActor; + + if (actor->world.pos.y < -25000.0f) { + actor->world.pos.y = -25000.0f; + } + + actor->sfxId = 0; + actor->audioFlags &= ~0x7F; + + if (actor->init != NULL) { + if (Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { + Actor_SetObjectDependency(globalCtx, actor); + actor->init(actor, globalCtx); + actor->init = NULL; + } + nextActor = actor->next; + } else if (actor->update == NULL) { + if (!actor->isDrawn) { + nextActor = Actor_Delete(&globalCtx->actorCtx, actor, globalCtx); + } else { + Actor_Destroy(actor, globalCtx); + nextActor = actor->next; + } + } else { + if (!Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { + Actor_MarkForDeath(actor); + } else { + s32 tmp = (params->unk_08 == 0); + + if (((params->unk_08) && !(actor->flags & params->unk_08)) || + ((tmp = (params->unk_08 == 0)) && + (!(actor->flags & ACTOR_FLAG_100000) || + ((actor->category == ACTORCAT_EXPLOSIVES) && (params->player->stateFlags1 & 0x200))) && + (params->unkC != 0) && (actor != params->unk10) && ((actor != params->player->heldActor)) && + (actor->parent != ¶ms->player->actor))) { + CollisionCheck_ResetDamage(&actor->colChkInfo); + } else { + Math_Vec3f_Copy(&actor->prevPos, &actor->world.pos); + actor->xzDistToPlayer = Actor_XZDistanceBetweenActors(actor, ¶ms->player->actor); + actor->playerHeightRel = Actor_HeightDiff(actor, ¶ms->player->actor); + actor->xyzDistToPlayerSq = SQ(actor->xzDistToPlayer) + SQ(actor->playerHeightRel); + + actor->yawTowardsPlayer = Actor_YawBetweenActors(actor, ¶ms->player->actor); + actor->flags &= ~ACTOR_FLAG_1000000; + + if ((DECR(actor->freezeTimer) == 0) && (actor->flags & params->unk_18)) { + if (actor == params->player->unk_730) { + actor->isTargeted = true; + } else { + actor->isTargeted = false; + } + + if ((actor->targetPriority != 0) && (params->player->unk_730 == 0)) { + actor->targetPriority = 0; + } + + Actor_SetObjectDependency(globalCtx, actor); + + if (actor->colorFilterTimer != 0) { + actor->colorFilterTimer--; + } + + actor->update(actor, globalCtx); + BgCheck_ResetFlagsIfLoadedActor(globalCtx, &globalCtx->colCtx.dyna, actor); + } + + CollisionCheck_ResetDamage(&actor->colChkInfo); + } + } + nextActor = actor->next; + } + return nextActor; +} + +u32 D_801AED58[] = { + 0x100002C2, 0x100002C2, 0x00000200, 0x100006C2, 0x00000282, 0x300002C2, + 0x10000282, 0x00000002, 0x300002C2, 0x100006C2, 0x00000002, 0x100002C2, +}; + +void Actor_UpdateAll(GlobalContext* globalCtx, ActorContext* actorCtx) { + s32 i; + Actor* actor; + Player* player = GET_PLAYER(globalCtx); + u32* tmp; + s32 cat; + Actor* next; + ActorListEntry* entry; + UpdateActor_Params params; + + params.player = player; + params.globalCtx = globalCtx; + + if (globalCtx->unk_18844 != 0) { + params.unk_18 = ACTOR_FLAG_200000; + } else { + params.unk_18 = ACTOR_FLAG_200000 | ACTOR_FLAG_40 | ACTOR_FLAG_10; + } + + Actor_SpawnSetupActors(globalCtx, actorCtx); + + if (actorCtx->unk2 != 0) { + actorCtx->unk2--; + } + + tmp = D_801AED58; + + if (player->stateFlags2 & 0x8000000) { + params.unk_08 = 0x2000000; + } else { + params.unk_08 = 0; + } + + if ((player->stateFlags1 & 0x40) && ((player->actor.textId & 0xFF00) != 0x1900)) { + params.unk10 = player->targetActor; + } else { + params.unk10 = NULL; + } + + for (i = 0, entry = actorCtx->actorLists; i < ARRAY_COUNT(actorCtx->actorLists); entry++, tmp++, i++) { + params.unkC = *tmp & player->stateFlags1; + params.actor = entry->first; + + while (params.actor != NULL) { + params.actor = Actor_UpdateActor(¶ms); + } + + if (i == ACTORCAT_BG) { + DynaPoly_Setup(globalCtx, &globalCtx->colCtx.dyna); + } + } + + for (i = 0, entry = actorCtx->actorLists; i < ARRAY_COUNT(actorCtx->actorLists); entry++, i++) { + if (entry->unk_08 != 0) { + actor = entry->first; + + while (actor != NULL) { + if (i == actor->category) { + actor = actor->next; + } else { + next = actor->next; + cat = actor->category; + actor->category = i; + Actor_RemoveFromCategory(globalCtx, actorCtx, actor); + Actor_AddToCategory(actorCtx, actor, cat); + actor = next; + } + } + entry->unk_08 = 0; + } + } + + actor = player->unk_730; + if ((actor != NULL) && (actor->update == NULL)) { + actor = NULL; + func_80123DA4(player); + } + + if ((actor == NULL) || (player->unk_738 < 5)) { + actor = NULL; + if (actorCtx->targetContext.unk4B != 0) { + actorCtx->targetContext.unk4B = 0; + play_sound(NA_SE_SY_LOCK_OFF); + } + } + + if (!(player->stateFlags1 & 2)) { + func_800B5814(&actorCtx->targetContext, player, actor, &globalCtx->state); + } + + TitleCard_Update(&globalCtx->state, &actorCtx->titleCtxt); + func_800B6474(globalCtx); + DynaPoly_UpdateBgActorTransforms(globalCtx, &globalCtx->colCtx.dyna); +} + +void Actor_Draw(GlobalContext* globalCtx, Actor* actor) { + Lights* light; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + light = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx); + if ((actor->flags & ACTOR_FLAG_10000000) && (globalCtx->roomCtx.currRoom.enablePosLights || (MREG(93) != 0))) { + light->enablePosLights = true; + } + + Lights_BindAll(light, globalCtx->lightCtx.listHead, + (actor->flags & (ACTOR_FLAG_10000000 | ACTOR_FLAG_400000)) ? NULL : &actor->world.pos, globalCtx); + Lights_Draw(light, globalCtx->state.gfxCtx); + + if (actor->flags & ACTOR_FLAG_1000) { + Matrix_SetTranslateRotateYXZ( + actor->world.pos.x + globalCtx->mainCamera.skyboxOffset.x, + actor->world.pos.y + ((actor->shape.yOffset * actor->scale.y) + globalCtx->mainCamera.skyboxOffset.y), + actor->world.pos.z + globalCtx->mainCamera.skyboxOffset.z, &actor->shape.rot); + } else { + Matrix_SetTranslateRotateYXZ(actor->world.pos.x, actor->world.pos.y + (actor->shape.yOffset * actor->scale.y), + actor->world.pos.z, &actor->shape.rot); + } + + Matrix_Scale(actor->scale.x, actor->scale.y, actor->scale.z, MTXMODE_APPLY); + Actor_SetObjectDependency(globalCtx, actor); + + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[actor->objBankIndex].segment); + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[actor->objBankIndex].segment); + + if (actor->colorFilterTimer != 0) { + s32 temp_v0_2 = actor->colorFilterParams & 0xC000; + Color_RGBA8 actorDefaultHitColor = { 0, 0, 0, 255 }; + + if (temp_v0_2 == 0x8000) { + actorDefaultHitColor.r = actorDefaultHitColor.g = actorDefaultHitColor.b = + ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + } else if (temp_v0_2 == 0x4000) { + actorDefaultHitColor.r = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + } else if (temp_v0_2 == 0xC000) { + actorDefaultHitColor.b = actorDefaultHitColor.g = actorDefaultHitColor.r = 0; + } else { + actorDefaultHitColor.b = ((actor->colorFilterParams & 0x1F00) >> 5) | 7; + } + + if (actor->colorFilterParams & 0x2000) { + func_800AE778(globalCtx, &actorDefaultHitColor, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); + } else { + func_800AE434(globalCtx, &actorDefaultHitColor, actor->colorFilterTimer, actor->colorFilterParams & 0xFF); + } + } + + actor->draw(actor, globalCtx); + + if (actor->colorFilterTimer != 0) { + if (actor->colorFilterParams & 0x2000) { + func_800AE8EC(globalCtx); + } else { + func_800AE5A0(globalCtx); + } + } + + if (actor->shape.shadowDraw != NULL) { + actor->shape.shadowDraw(actor, light, globalCtx); + } + actor->isDrawn = true; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800B9D1C(Actor* actor) { + s32 sfxId = actor->sfxId; + + if (sfxId != 0) { + if (actor->audioFlags & 2) { + Audio_PlaySfxGeneral(sfxId, &actor->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + } else if (actor->audioFlags & 4) { + play_sound(sfxId); + } else if (actor->audioFlags & 8) { + func_8019F128(sfxId); + } else if (actor->audioFlags & 0x10) { + func_801A0810(&D_801DB4A4, NA_SE_SY_TIMER - SFX_FLAG, (sfxId - 1)); + } else if (actor->audioFlags & 1) { + Audio_PlaySfxAtPos(&actor->projectedPos, sfxId); + } + } + + if (sfxId) {} + + if (actor->audioFlags & 0x40) { + func_801A1FB4(3, &actor->projectedPos, NA_BGM_MUSIC_BOX_HOUSE, 1500.0f); + } + + if (actor->audioFlags & 0x20) { + func_801A1FB4(0, &actor->projectedPos, NA_BGM_KAMARO_DANCE, 900.0f); + } +} void Actor_DrawAllSetup(GlobalContext* globalCtx) { globalCtx->actorCtx.undrawnActorCount = 0; globalCtx->actorCtx.unkB = 0; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_RecordUndrawnActor.s") +s32 Actor_RecordUndrawnActor(GlobalContext* globalCtx, Actor* actor) { + if (globalCtx->actorCtx.undrawnActorCount >= 32) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9E84.s") + globalCtx->actorCtx.undrawnActors[globalCtx->actorCtx.undrawnActorCount] = actor; + globalCtx->actorCtx.undrawnActorCount++; + return true; +} +void func_800B9E84(Gfx** arg0, s32 arg1) { + func_80164C14(arg0, D_801DE890, 4, 0, 6, 6, ((100 - arg1) * 0.003f) + 1.0f); +} + +#ifdef NON_EQUIVALENT +// Related to draw actors with lens +void func_800B9EF4(GlobalContext* globalCtx, s32 numActors, Actor** actors) { + s32 spB4; + Gfx* spAC; + void* spA8; // pad + s32 spA4; + // void* sp34; + // Gfx* temp_s1_11; + // Gfx** temp_a0_2; + // Gfx** temp_a1; + // GraphicsContext* temp_s2; + // void* temp_s1_10; + // void* temp_s1_7; + // void* temp_s1_8; + // void* temp_s1_9; + // Gfx* phi_s1; + Gfx* phi_s1_2; + // void* phi_s1_4; + + OPEN_DISPS(globalCtx->state.gfxCtx); + // temp_s2 = globalCtx->state.gfxCtx; + + if (numActors > 0) { + spAC = POLY_XLU_DISP; + // sp34 = globalCtx + 0x18000; + spA4 = globalCtx->unk_18E68; + + PreRender_SetValues(&globalCtx->pauseBgPreRender, D_801FBBCC, D_801FBBCE, __gfxCtx->curFrameBuffer, + __gfxCtx->zbuffer); + + func_80170200(&globalCtx->pauseBgPreRender, &spAC, __gfxCtx->zbuffer, (void*)spA4); + + // spAC->words.w0 = 0xE7000000; + // spAC->words.w1 = 0; + // temp_s1_2 = spAC + 8; + gDPPipeSync(spAC++); + + // temp_s1_2->words.w0 = 0xEE000000; + // temp_s1_2->words.w1 = 0; + // temp_s1_3 = temp_s1_2 + 8; + gDPSetPrimDepth(spAC++, 0, 0); + + // temp_s1_3->words.w0 = 0xEF002C30; + // temp_s1_3->words.w1 = 0xAF504365; + // temp_s1_4 = temp_s1_3 + 8; + gDPSetOtherMode(spAC++, + G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_THRESHOLD | G_ZS_PRIM | Z_UPD | IM_RD | CVG_DST_SAVE | ZMODE_OPA | FORCE_BL | + GBL_c1(G_BL_CLR_BL, G_BL_0, G_BL_CLR_MEM, G_BL_1MA) | + GBL_c2(G_BL_CLR_BL, G_BL_0, G_BL_CLR_MEM, G_BL_1MA)); + + // temp_s1_4->words.w1 = 0xFF; + // temp_s1_4->words.w0 = 0xFA000000; + // temp_s1_5 = temp_s1_4 + 8; + gDPSetPrimColor(spAC++, 0, 0, 0, 0, 0, 255); + // temp_s1_5 = spAC; + + if (globalCtx->roomCtx.currRoom.unk5 == 0) { + // temp_s1_5->words.w0 = 0xFC61E6C3; + // temp_s1_5->words.w1 = 0x11CF9FCF; + // phi_s1 = temp_s1_5 + 8; + gDPSetCombineLERP(spAC++, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, + TEXEL0, PRIMITIVE, 0); + } else { + // temp_s1_5->words.w0 = 0xFC119623; + // temp_s1_5->words.w1 = 0xFF2FFFFF; + // phi_s1 = temp_s1_5 + 8; + gDPSetCombineMode(spAC++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + } + + // spAC = phi_s1; + func_800B9E84(&spAC, globalCtx->actorCtx.unk4); + phi_s1_2 = func_801660B8(globalCtx, spAC); + + for (spB4 = 0; spB4 < numActors; spB4++, actors++) { + Actor_Draw(globalCtx, *actors); + } + + // temp_s0_2 = &globalCtx->pauseBgPreRender; + + // phi_s1_2->words.w0 = 0xE7000000; + // phi_s1_2->words.w1 = 0; + // temp_s1_7 = phi_s1_2 + 8; + gDPPipeSync(phi_s1_2++); + + // temp_s1_7->unk_0 = 0xEF002CF0; + // temp_s1_7->unk_4 = 0xF5A714D; + // temp_s1_8 = temp_s1_7 + 8; + gDPSetOtherMode(phi_s1_2++, + G_AD_DISABLE | G_CD_DISABLE | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_THRESHOLD | G_ZS_PRIM | AA_EN | IM_RD | CVG_DST_WRAP | ZMODE_OPA | CVG_X_ALPHA | + ALPHA_CVG_SEL | FORCE_BL | GBL_c1(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_1) | + GBL_c2(G_BL_CLR_IN, G_BL_0, G_BL_CLR_MEM, G_BL_1)); + + // temp_s1_8->unk_4 = -0x100; + // temp_s1_8->unk_0 = 0xF9000000; + // temp_s1_9 = temp_s1_8 + 8; + gDPSetBlendColor(phi_s1_2++, 255, 255, 255, 0); + + // temp_s1_9->unk_4 = 0x20; + // temp_s1_9->unk_0 = 0xFA0000FF; + // temp_s1_10 = temp_s1_9 + 8; + gDPSetPrimColor(phi_s1_2++, 0, 0xFF, 0, 0, 0, 32); + + // temp_a0_2 = &spAC; + // if (sp34->unk_6E5 == 0) { + if (globalCtx->roomCtx.currRoom.unk5 == 0) { + // temp_s1_10->unk_0 = 0xFC119623; + // temp_s1_10->unk_4 = 0xFF2FFFFF; + // phi_s1_4 = temp_s1_10 + 8; + gDPSetCombineMode(phi_s1_2++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + //} else { + } else { + // temp_s1_10->unk_4 = 0x11CF9FCF; + // temp_s1_10->unk_0 = 0xFC61E6C3; + // phi_s1_4 = temp_s1_10 + 8; + gDPSetCombineLERP(phi_s1_2++, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, + TEXEL0, PRIMITIVE, 0); + + //} + } + // phi_s1_4->unk_0 = (s32) (((sp34->unk_B4C - 1) & 0xFFF) | 0xFF100000); + // temp_s1_11 = phi_s1_4 + 8; + // phi_s1_4->unk_4 = spA4; + gDPSetColorImage(phi_s1_2++, G_IM_FMT_RGBA, G_IM_SIZ_16b, ((globalCtx->pauseBgPreRender.width - 1) & 0xFFF), + spA4); + // temp_s1_11 = phi_s1_2; + + spAC = phi_s1_2; + + // spAC = temp_s1_11; + func_800B9E84(&spAC, (s32)globalCtx->actorCtx.unk4); + // temp_s1_11->words.w0 = 0xE7000000; + // temp_s1_11->words.w1 = 0; + // temp_s1_12 = temp_s1_11 + 8; + gDPPipeSync(spAC++); + + // temp_s1_12->words.w1 = -0xF8; + // temp_s1_12->words.w0 = 0xF9000000; + // temp_s1_13 = temp_s1_12 + 8; + gDPSetBlendColor(spAC++, 255, 255, 255, 8); + + // temp_s1_14 = temp_s1_13 + 8; + // temp_s1_13->words.w0 = ((sp34->unk_B4C - 1) & 0xFFF) | 0xFF100000; + // temp_s1_13->words.w1 = sp34->unk_B5C; + gDPSetColorImage(spAC++, G_IM_FMT_RGBA, G_IM_SIZ_16b, ((globalCtx->pauseBgPreRender.width - 1) & 0xFFF), + globalCtx->pauseBgPreRender.fbuf); + + // temp_a1 = &spAC; + // spAC = temp_s1_14; + // func_8016FDB8(&globalCtx->pauseBgPreRender, temp_a1, (void* ) spA4, spA8, 1U); + func_8016FDB8(&globalCtx->pauseBgPreRender, &spAC, (void*)spA4, __gfxCtx->zbuffer, 1U); + // + // POLY_OPA_DISP = temp_s1_14; + POLY_OPA_DISP = spAC; + } + + // temp_s1_15 = OVERLAY_DISP; + // temp_s1_15->words.w0 = 0xE7000000; + // temp_s1_15->words.w1 = 0; + // temp_s1_16 = temp_s1_15 + 8; + spAC = OVERLAY_DISP; + gDPPipeSync(spAC++); + + // temp_s1_16->words.w0 = 0xEF002C30; + // temp_s1_16->words.w1 = 0x00504345; + // temp_s1_17 = temp_s1_16 + 8; + gDPSetOtherMode(spAC++, + G_AD_DISABLE | G_CD_MAGICSQ | G_CK_NONE | G_TC_FILT | G_TF_BILERP | G_TT_NONE | G_TL_TILE | + G_TD_CLAMP | G_TP_NONE | G_CYC_1CYCLE | G_PM_NPRIMITIVE, + G_AC_THRESHOLD | G_ZS_PRIM | G_RM_CLD_SURF | G_RM_CLD_SURF2); + + // temp_s1_17->words.w0 = 0xFC61E6C3; + // temp_s1_17->words.w1 = 0x11CF9FCF; + // temp_s1_18 = temp_s1_17 + 8; + gDPSetCombineLERP(spAC++, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, PRIMITIVE, 0, 1, TEXEL0, + PRIMITIVE, 0); + + // temp_s1_18->words.w0 = 0xFA000000; + // temp_s1_18->words.w1 = 0x4A00004A; + // spAC = temp_s1_18 + 8; + gDPSetPrimColor(spAC++, 0, 0, 74, 0, 0, 74); + + func_800B9E84(&spAC, (s32)globalCtx->actorCtx.unk4); + + OVERLAY_DISP = spAC; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +void func_800B9EF4(GlobalContext* globalCtx, s32 numActors, Actor** actors); #pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800B9EF4.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA2D8.s") +s32 func_800BA2D8(GlobalContext* globalCtx, Actor* actor) { + return func_800BA2FC(globalCtx, actor, &actor->projectedPos, actor->projectedW); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA2FC.s") +s32 func_800BA2FC(GlobalContext* globalCtx, Actor* actor, Vec3f* projectedPos, f32 projectedW) { + if ((-actor->uncullZoneScale < projectedPos->z) && + (projectedPos->z < (actor->uncullZoneForward + actor->uncullZoneScale))) { + f32 phi_f12; + f32 phi_f2 = CLAMP_MIN(projectedW, 1.0f); + f32 phi_f14; + f32 phi_f16; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_DrawAll.s") + if (globalCtx->view.fovy != 60.0f) { + phi_f12 = actor->uncullZoneScale * globalCtx->unk_187F0.x * 0.76980036f; // sqrt(16/27) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA6FC.s") + phi_f14 = globalCtx->unk_187F0.y * 0.57735026f; // 1 / sqrt(3) + phi_f16 = actor->uncullZoneScale * phi_f14; + phi_f14 *= actor->uncullZoneDownward; + } else { + phi_f16 = phi_f12 = actor->uncullZoneScale; + phi_f14 = actor->uncullZoneDownward; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA798.s") + if (((fabsf(projectedPos->x) - phi_f12) < phi_f2) && ((-phi_f2 < (projectedPos->y + phi_f14))) && + ((projectedPos->y - phi_f16) < phi_f2)) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA8B8.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BA9B4.s") +void Actor_DrawAll(GlobalContext* globalCtx, ActorContext* actorCtx) { + s32 pad[2]; + Gfx* ref2; + Gfx* tmp2; + s32 pad2; + Gfx* sp58; + ActorListEntry* actorEntry; + Actor* actor; + s32 actorFlags; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_InsertIntoTypeList.s") + if (globalCtx->unk_18844 != 0) { + actorFlags = ACTOR_FLAG_200000; + } else { + actorFlags = ACTOR_FLAG_200000 | ACTOR_FLAG_40 | ACTOR_FLAG_20; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_RemoveFromTypeList.s") + OPEN_DISPS(globalCtx->state.gfxCtx); + + Actor_DrawAllSetup(globalCtx); + + sp58 = POLY_XLU_DISP; + POLY_XLU_DISP = &sp58[1]; + + for (i = 0, actorEntry = actorCtx->actorLists; i < ARRAY_COUNT(actorCtx->actorLists); i++, actorEntry++) { + actor = actorEntry->first; + + while (actor != NULL) { + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos, + &actor->projectedW); + + if (actor->audioFlags & 0x7F) { + func_800B9D1C(actor); + } + + if (func_800BA2D8(globalCtx, actor)) { + actor->flags |= ACTOR_FLAG_40; + } else { + actor->flags &= ~ACTOR_FLAG_40; + } + + actor->isDrawn = false; + if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & actorFlags)) { + if ((actor->flags & ACTOR_FLAG_80) && + ((globalCtx->roomCtx.currRoom.unk5 == 0) || (globalCtx->actorCtx.unk4 == 0x64) || + (actor->room != globalCtx->roomCtx.currRoom.num))) { + if (Actor_RecordUndrawnActor(globalCtx, actor)) {} + } else { + Actor_Draw(globalCtx, actor); + } + } + + actor = actor->next; + } + } + + Effect_DrawAll(globalCtx->state.gfxCtx); + EffectSS_DrawAllParticles(globalCtx); + EffFootmark_Draw(globalCtx); + + ref2 = POLY_XLU_DISP; + gSPDisplayList(sp58, &ref2[1]); + POLY_XLU_DISP = &ref2[1]; + + if (globalCtx->actorCtx.unk3 != 0) { + Math_StepToC(&globalCtx->actorCtx.unk4, 100, 20); + if (GET_PLAYER(globalCtx)->stateFlags2 & 0x8000000) { + func_800B90F4(globalCtx); + } + } else { + Math_StepToC(&globalCtx->actorCtx.unk4, 0, 10); + } + if (globalCtx->actorCtx.unk4 != 0) { + globalCtx->actorCtx.unkB = 1; + func_800B9EF4(globalCtx, globalCtx->actorCtx.undrawnActorCount, globalCtx->actorCtx.undrawnActors); + } + + tmp2 = POLY_XLU_DISP; + gSPEndDisplayList(&tmp2[0]); + gSPBranchList(ref2, &tmp2[1]); + POLY_XLU_DISP = &tmp2[1]; + + if (globalCtx->unk_18844 == 0) { + Lights_DrawGlow(globalCtx); + } + + TitleCard_Draw(&globalCtx->state, &actorCtx->titleCtxt); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +/** + * Kills every actor which its object is not loaded + */ +void func_800BA6FC(GlobalContext* globalCtx, ActorContext* actorCtx) { + Actor* actor; + s32 i; + + for (i = 0; i != ARRAY_COUNT(actorCtx->actorLists); i++) { + actor = actorCtx->actorLists[i].first; + + while (actor != NULL) { + if (!Object_IsLoaded(&globalCtx->objectCtx, actor->objBankIndex)) { + Actor_MarkForDeath(actor); + } + + actor = actor->next; + } + } +} + +/** + * Kill actors on room change and update flags accordingly + */ +void func_800BA798(GlobalContext* globalCtx, ActorContext* actorCtx) { + Actor* actor; + s32 i; + + for (i = 0; i < ARRAY_COUNT(actorCtx->actorLists); i++) { + actor = actorCtx->actorLists[i].first; + + while (actor != NULL) { + if ((actor->room >= 0) && (actor->room != globalCtx->roomCtx.currRoom.num) && + (actor->room != globalCtx->roomCtx.prevRoom.num)) { + if (!actor->isDrawn) { + actor = Actor_Delete(actorCtx, actor, globalCtx); + } else { + Actor_MarkForDeath(actor); + Actor_Destroy(actor, globalCtx); + actor = actor->next; + } + } else { + actor = actor->next; + } + } + } + + CollisionCheck_ClearContext(globalCtx, &globalCtx->colChkCtx); + actorCtx->flags.clearedRoomTemp = 0; + actorCtx->flags.switches[3] = 0; + actorCtx->flags.collectible[3] = 0; + globalCtx->msgCtx.unk_12030 = 0; +} + +void func_800BA8B8(GlobalContext* globalCtx, ActorContext* actorCtx) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(actorCtx->actorLists); i++) { + Actor* actor = actorCtx->actorLists[i].first; + + while (actor != NULL) { + if (!(actor->unk20 & actorCtx->unkC)) { + func_80123590(globalCtx, actor); + if (!actor->isDrawn) { + actor = Actor_Delete(actorCtx, actor, globalCtx); + } else { + Actor_MarkForDeath(actor); + Actor_Destroy(actor, globalCtx); + actor = actor->next; + } + } else { + actor = actor->next; + } + } + } + + CollisionCheck_ClearContext(globalCtx, &globalCtx->colChkCtx); + globalCtx->msgCtx.unk_12030 = 0; +} + +void Actor_CleanupContext(ActorContext* actorCtx, GlobalContext* globalCtx) { + s32 i; + + Fault_RemoveClient(&sActorFaultClient); + + for (i = 0; i < ARRAY_COUNT(actorCtx->actorLists); i++) { + if (i != ACTORCAT_PLAYER) { + Actor* actor = actorCtx->actorLists[i].first; + + while (actor != NULL) { + Actor_Delete(actorCtx, actor, globalCtx); + actor = actorCtx->actorLists[i].first; + } + } + } + + while (actorCtx->actorLists[ACTORCAT_PLAYER].first != NULL) { + Actor_Delete(actorCtx, actorCtx->actorLists[ACTORCAT_PLAYER].first, globalCtx); + } + + if (actorCtx->absoluteSpace != NULL) { + ZeldaArena_Free(actorCtx->absoluteSpace); + actorCtx->absoluteSpace = NULL; + } + + Play_SaveCycleSceneFlags(&globalCtx->state); + ActorOverlayTable_Cleanup(); +} + +/** + * Adds a given actor instance at the front of the actor list of the specified category. + * Also sets the actor instance as being of that category. + */ +void Actor_AddToCategory(ActorContext* actorCtx, Actor* actor, u8 actorCategory) { + Actor* actorAux; + Actor* lastActor; + + actor->category = actorCategory; + + actorCtx->totalLoadedActors++; + actorCtx->actorLists[actorCategory].length++; + lastActor = actorCtx->actorLists[actorCategory].first; + + if (lastActor == NULL) { + actorCtx->actorLists[actorCategory].first = actor; + return; + } + + actorAux = lastActor->next; + while (actorAux != NULL) { + lastActor = actorAux; + actorAux = actorAux->next; + } + + lastActor->next = actor; + actor->prev = lastActor; +} + +/** + * Removes a given actor instance from its actor list. + * Also sets the temp clear flag of the current room if the actor removed was the last enemy loaded. + */ +Actor* Actor_RemoveFromCategory(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actorToRemove) { + Actor* newHead; + + actorCtx->totalLoadedActors--; + actorCtx->actorLists[actorToRemove->category].length--; + + if (actorToRemove->prev != NULL) { + actorToRemove->prev->next = actorToRemove->next; + } else { + actorCtx->actorLists[actorToRemove->category].first = actorToRemove->next; + } + + newHead = actorToRemove->next; + + if (newHead != NULL) { + newHead->prev = actorToRemove->prev; + } + + actorToRemove->next = NULL; + actorToRemove->prev = NULL; + + if ((actorToRemove->room == globalCtx->roomCtx.currRoom.num) && (actorToRemove->category == ACTORCAT_ENEMY) && + (actorCtx->actorLists[ACTORCAT_ENEMY].length == 0)) { + Flags_SetClearTemp(globalCtx, globalCtx->roomCtx.currRoom.num); + } + + return newHead; +} void Actor_FreeOverlay(ActorOverlay* entry) { - void* ramAddr; - if (entry->numLoaded == 0) { - ramAddr = entry->loadedRamAddr; + void* ramAddr = entry->loadedRamAddr; + if (ramAddr != NULL) { - // Bit 1 - always loaded - if ((entry->allocType & 2) == 0) { - // Bit 0 - don't alloc memory - if ((entry->allocType & 1) != 0) { + if (!(entry->allocType & ALLOCTYPE_PERMANENT)) { + if (entry->allocType & ALLOCTYPE_ABSOLUTE) { entry->loadedRamAddr = NULL; } else { ZeldaArena_Free(ramAddr); @@ -752,115 +3120,1228 @@ void Actor_FreeOverlay(ActorOverlay* entry) { } } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_Spawn.s") +Actor* Actor_Spawn(ActorContext* actorCtx, GlobalContext* globalCtx, s16 actorId, f32 posX, f32 posY, f32 posZ, + s16 rotX, s16 rotY, s16 rotZ, s32 params) { + return Actor_SpawnAsChildAndCutscene(actorCtx, globalCtx, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, -1, + 0x3FF, NULL); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_LoadOverlay.s") +ActorInit* Actor_LoadOverlay(ActorContext* actorCtx, s16 index) { + size_t overlaySize; + ActorOverlay* overlayEntry = &gActorOverlayTable[index]; + ActorInit* actorInit; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_SpawnAsChildAndCutscene.s") + overlaySize = VRAM_PTR_SIZE(overlayEntry); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_SpawnAsChild.s") + if (overlayEntry->vramStart == NULL) { + actorInit = overlayEntry->initInfo; + } else { + if (overlayEntry->loadedRamAddr == NULL) { + if (overlayEntry->allocType & ALLOCTYPE_ABSOLUTE) { + if (actorCtx->absoluteSpace == NULL) { + actorCtx->absoluteSpace = ZeldaArena_MallocR(AM_FIELD_SIZE); + } + gActorOverlayTable[index].loadedRamAddr = actorCtx->absoluteSpace; + } else if (overlayEntry->allocType & ALLOCTYPE_PERMANENT) { + gActorOverlayTable[index].loadedRamAddr = ZeldaArena_MallocR(overlaySize); + } else { + gActorOverlayTable[index].loadedRamAddr = ZeldaArena_Malloc(overlaySize); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_SpawnTransitionActors.s") + if (overlayEntry->loadedRamAddr == NULL) { + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB2D0.s") + Load2_LoadOverlay(overlayEntry->vromStart, overlayEntry->vromEnd, overlayEntry->vramStart, + overlayEntry->vramEnd, overlayEntry->loadedRamAddr); + overlayEntry->numLoaded = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB498.s") + actorInit = + (uintptr_t)((overlayEntry->initInfo != NULL) + ? (void*)(-OVERLAY_RELOCATION_OFFSET(overlayEntry) + (uintptr_t)overlayEntry->initInfo) + : NULL); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB59C.s") + return actorInit; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB604.s") +Actor* Actor_SpawnAsChildAndCutscene(ActorContext* actorCtx, GlobalContext* globalCtx, s16 index, f32 x, f32 y, f32 z, + s16 rotX, s16 rotY, s16 rotZ, s32 params, u32 cutscene, s32 arg11, Actor* parent) { + s32 pad; + Actor* actor; + ActorInit* actorInit; + s32 objBankIndex; + ActorOverlay* overlayEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BB8EC.s") + if (actorCtx->totalLoadedActors >= 0xFF) { + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Enemy_StartFinishingBlow.s") + actorInit = Actor_LoadOverlay(actorCtx, index); + if (actorInit == NULL) { + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBAC0.s") + objBankIndex = Object_GetIndex(&globalCtx->objectCtx, actorInit->objectId); + if ((objBankIndex < 0) || + ((actorInit->type == ACTORCAT_ENEMY) && Flags_GetClear(globalCtx, globalCtx->roomCtx.currRoom.num) && + (actorInit->id != ACTOR_BOSS_05))) { + Actor_FreeOverlay(&gActorOverlayTable[index]); + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBB74.s") + actor = ZeldaArena_Malloc(actorInit->instanceSize); + if (actor == NULL) { + Actor_FreeOverlay(&gActorOverlayTable[index]); + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBC20.s") + overlayEntry = &gActorOverlayTable[index]; + if (overlayEntry->vramStart != 0) { + overlayEntry->numLoaded++; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBCEC.s") + bzero(actor, actorInit->instanceSize); + actor->overlayEntry = overlayEntry; + actor->id = actorInit->id; + actor->flags = actorInit->flags; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBDAC.s") + if (actorInit->id == ACTOR_EN_PART) { + actor->objBankIndex = rotZ; + rotZ = 0; + } else { + actor->objBankIndex = objBankIndex; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BBFB0.s") + actor->init = actorInit->init; + actor->destroy = actorInit->destroy; + actor->update = actorInit->update; + actor->draw = actorInit->draw; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC154.s") + if (parent != NULL) { + actor->room = parent->room; + actor->parent = parent; + parent->child = actor; + } else { + actor->room = globalCtx->roomCtx.currRoom.num; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC188.s") + actor->home.pos.x = x; + actor->home.pos.y = y; + actor->home.pos.z = z; + actor->home.rot.x = rotX; + actor->home.rot.y = rotY; + actor->home.rot.z = rotZ; + actor->params = params & 0xFFFF; + actor->cutscene = (cutscene & 0x7F); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC1B4.s") + if (actor->cutscene == 0x7F) { + actor->cutscene = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC270.s") + if (arg11 != 0) { + actor->unk20 = arg11; + } else { + actor->unk20 = 0x3FF; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC444.s") + Actor_AddToCategory(actorCtx, actor, actorInit->type); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC4EC.s") + { + u32 sp20 = gSegments[6]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC5B8.s") + Actor_Init(actor, globalCtx); + gSegments[6] = sp20; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC5EC.s") + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC620.s") +Actor* Actor_SpawnAsChild(ActorContext* actorCtx, Actor* parent, GlobalContext* globalCtx, s16 actorId, f32 posX, + f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, s32 params) { + return Actor_SpawnAsChildAndCutscene(actorCtx, globalCtx, actorId, posX, posY, posZ, rotX, rotY, rotZ, params, -1, + parent->unk20, parent); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC770.s") +void Actor_SpawnTransitionActors(GlobalContext* globalCtx, ActorContext* actorCtx) { + TransitionActorEntry* transitionActorList = globalCtx->doorCtx.transitionActorList; + s32 i; + s16 numTransitionActors = globalCtx->doorCtx.numTransitionActors; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC7D8.s") + for (i = 0; i < numTransitionActors; transitionActorList++, i++) { + if (transitionActorList->id >= 0) { + if ((transitionActorList->sides[0].room >= 0 && + (globalCtx->roomCtx.currRoom.num == transitionActorList->sides[0].room || + globalCtx->roomCtx.prevRoom.num == transitionActorList->sides[0].room)) || + (transitionActorList->sides[1].room >= 0 && + (globalCtx->roomCtx.currRoom.num == transitionActorList->sides[1].room || + globalCtx->roomCtx.prevRoom.num == transitionActorList->sides[1].room))) { + s16 rotY = ((transitionActorList->rotY >> 7) & 0x1FF) * (0x10000 / 360.0f); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC848.s") + if (Actor_SpawnAsChildAndCutscene(actorCtx, globalCtx, transitionActorList->id & 0x1FFF, + transitionActorList->pos.x, transitionActorList->pos.y, + transitionActorList->pos.z, 0, rotY, 0, + (i << 0xA) + (transitionActorList->params & 0x3FF), + transitionActorList->rotY & 0x7F, 0x3FF, 0) != NULL) { + transitionActorList->id = -transitionActorList->id; + } + numTransitionActors = globalCtx->doorCtx.numTransitionActors; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BC8B8.s") +Actor* Actor_SpawnEntry(ActorContext* actorCtx, ActorEntry* actorEntry, GlobalContext* globalCtx) { + s16 rotX = (actorEntry->rot.x >> 7) & 0x1FF; + s16 rotY = (actorEntry->rot.y >> 7) & 0x1FF; + s16 rotZ = (actorEntry->rot.z >> 7) & 0x1FF; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BCB50.s") + if (!(actorEntry->id & 0x8000)) { + rotY *= 0x10000 / 360.0f; + } else if (rotY > 180) { + rotY -= 360; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BCB70.s") + if (!(actorEntry->id & 0x4000)) { + rotX *= 0x10000 / 360.0f; + } else if (rotX > 180) { + rotX -= 360; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BCBF4.s") + if (!(actorEntry->id & 0x2000)) { + rotZ *= 0x10000 / 360.0f; + } else if (rotZ > 180) { + rotZ -= 360; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BCC68.s") + return Actor_SpawnAsChildAndCutscene(actorCtx, globalCtx, actorEntry->id & 0x1FFF, actorEntry->pos.x, + actorEntry->pos.y, actorEntry->pos.z, rotX, rotY, rotZ, + actorEntry->params & 0xFFFF, actorEntry->rot.y & 0x7F, + ((actorEntry->rot.x & 7) << 7) | (actorEntry->rot.z & 0x7F), NULL); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BCCDC.s") +Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Actor* newHead; + ActorOverlay* overlayEntry = actor->overlayEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD2B4.s") + if ((player != NULL) && (actor == player->unk_730)) { + func_80123DA4(player); + Camera_ChangeMode(Play_GetCamera(globalCtx, Play_GetActiveCamId(globalCtx)), 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD384.s") + if (actor == actorCtx->targetContext.arrowPointedActor) { + actorCtx->targetContext.arrowPointedActor = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD6B8.s") + if (actor == actorCtx->targetContext.unk8C) { + actorCtx->targetContext.unk8C = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD6E4.s") + if (actor == actorCtx->targetContext.bgmEnemy) { + actorCtx->targetContext.bgmEnemy = NULL; + } + + Audio_StopSfxByPos(&actor->projectedPos); + Actor_Destroy(actor, globalCtx); + + newHead = Actor_RemoveFromCategory(globalCtx, actorCtx, actor); + ZeldaArena_Free(actor); + + if (overlayEntry->vramStart != NULL) { + overlayEntry->numLoaded--; + Actor_FreeOverlay(overlayEntry); + } + + return newHead; +} + +s32 func_800BB59C(GlobalContext* globalCtx, Actor* actor) { + s16 x; + s16 y; + + Actor_GetScreenPos(globalCtx, actor, &x, &y); + + return (x > -20) && (x < gScreenWidth + 20) && (y > -160) && (y < gScreenHeight + 160); +} + +void func_800BB604(GameState* gameState, ActorContext* actorCtx, Player* player, s32 actorCategory) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + f32 temp_f0_2; + Actor* sp8C; + Actor* actor; + s32 phi_s2; + CollisionPoly* sp80; + s32 sp7C; + Vec3f sp70; + s32 phi_s2_2; + + actor = actorCtx->actorLists[actorCategory].first; + sp8C = player->unk_730; + while (actor != NULL) { + if ((actor->update != NULL) && ((Player*)actor != player)) { + if (actor->flags & (ACTOR_FLAG_40000000 | ACTOR_FLAG_1)) { + if ((actorCategory == ACTORCAT_ENEMY) && CHECK_FLAG_ALL(actor->flags, ACTOR_FLAG_4 | ACTOR_FLAG_1)) { + if ((actor->xyzDistToPlayerSq < SQ(500.0f)) && (actor->xyzDistToPlayerSq < sBgmEnemyDistSq)) { + actorCtx->targetContext.bgmEnemy = actor; + sBgmEnemyDistSq = actor->xyzDistToPlayerSq; + } + } + + if ((actor != sp8C) || (actor->flags & ACTOR_FLAG_80000)) { + temp_f0_2 = func_800B82EC(actor, player, D_801ED8DC); + phi_s2_2 = (actor->flags & 1) != 0; + if (phi_s2_2) { + phi_s2_2 = temp_f0_2 < D_801ED8C8; + } + phi_s2 = phi_s2_2; + phi_s2_2 = (actor->flags & ACTOR_FLAG_40000000) != 0; + if (phi_s2_2) { + phi_s2_2 = temp_f0_2 < D_801ED8D0; + } + + if (((phi_s2) || (phi_s2_2)) && (func_800B83BC(actor, temp_f0_2))) { + if (func_800BB59C(globalCtx, actor)) { + if (((!BgCheck_CameraLineTest1(&globalCtx->colCtx, &player->actor.focus.pos, + &actor->focus.pos, &sp70, &sp80, true, true, true, true, + &sp7C)) || + (SurfaceType_IsIgnoredByProjectiles(&globalCtx->colCtx, sp80, sp7C)))) { + if (actor->targetPriority != 0) { + if ((phi_s2 != 0) && (actor->targetPriority < D_801ED8D4)) { + D_801ED8BC = actor; + D_801ED8D4 = actor->targetPriority; + } + if ((phi_s2_2 != 0) && (actor->targetPriority < D_801ED8D8)) { + D_801ED8C4 = actor; + D_801ED8D8 = actor->targetPriority; + } + } else { + if (phi_s2 != 0) { + D_801ED8B8 = actor; + D_801ED8C8 = temp_f0_2; + } + if (phi_s2_2 != 0) { + D_801ED8C0 = actor; + D_801ED8D0 = temp_f0_2; + } + } + } + } + } + } + } + } + + actor = actor->next; + } +} + +u8 D_801AED8C[] = { + ACTORCAT_BOSS, ACTORCAT_ENEMY, ACTORCAT_BG, ACTORCAT_EXPLOSIVES, ACTORCAT_NPC, ACTORCAT_ITEMACTION, + ACTORCAT_CHEST, ACTORCAT_SWITCH, ACTORCAT_PROP, ACTORCAT_MISC, ACTORCAT_DOOR, ACTORCAT_SWITCH, +}; + +void func_800BB8EC(GameState* gameState, ActorContext* actorCtx, Actor** arg2, Actor** arg3, Player* player) { + u8* actorCategories; + s32 i; + + D_801ED8B8 = D_801ED8BC = D_801ED8C0 = D_801ED8C4 = NULL; + D_801ED8C8 = D_801ED8D0 = sBgmEnemyDistSq = FLT_MAX; + D_801ED8D4 = D_801ED8D8 = INT32_MAX; + + actorCtx->targetContext.bgmEnemy = NULL; + D_801ED8DC = player->actor.shape.rot.y; + + actorCategories = D_801AED8C; + + for (i = 0; i < 3; i++) { + func_800BB604(gameState, actorCtx, player, *actorCategories); + actorCategories++; + } + + if (D_801ED8B8 == NULL) { + for (; i < ARRAY_COUNT(D_801AED8C); i++) { + func_800BB604(gameState, actorCtx, player, *actorCategories); + actorCategories++; + } + } + + if (D_801ED8B8 == NULL) { + *arg2 = D_801ED8BC; + } else { + *arg2 = D_801ED8B8; + } + + if (D_801ED8C0 == NULL) { + *arg3 = D_801ED8C4; + } else { + *arg3 = D_801ED8C0; + } +} + +/** + * Play the death sound effect and flash the screen white for 4 frames. + * While the screen flashes, the game freezes. + */ +void Enemy_StartFinishingBlow(GlobalContext* globalCtx, Actor* actor) { + globalCtx->actorCtx.freezeFlashTimer = 5; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &actor->world.pos, 20, NA_SE_EN_LAST_DAMAGE); +} + +// blinking routine +s16 func_800BBAC0(s16 arg0[2], s16 arg1, s16 arg2, s16 arg3) { + if (DECR(arg0[1]) == 0) { + arg0[1] = Rand_S16Offset(arg1, arg2); + } + + if (arg0[1] - arg3 > 0) { + arg0[0] = 0; + } else if ((arg0[1] - arg3 >= -1) || (arg0[1] < 2)) { + arg0[0] = 1; + } else { + arg0[0] = 2; + } + + return arg0[0]; +} + +// blinking routine +s16 func_800BBB74(s16 arg0[2], s16 arg1, s16 arg2, s16 arg3) { + if (DECR(arg0[1]) == 0) { + arg0[1] = Rand_S16Offset(arg1, arg2); + } + + if (arg0[1] - arg3 > 0) { + arg0[0] = 0; + } else if (arg0[1] - arg3 == 0) { + arg0[0] = 1; + } else { + arg0[0] = 2; + } + + return arg0[0]; +} + +// unused blinking routine +s16 func_800BBC20(s16 arg0[2], s16 arg1, s16 arg2, s16 arg3) { + if (DECR(arg0[1]) == 0) { + arg0[1] = Rand_S16Offset(arg1, arg2); + arg0[0]++; + if ((arg0[0] % 3) == 0) { + arg0[0] = (s32)(Rand_ZeroOne() * arg3) * 3; + } + } + return arg0[0]; +} + +void Actor_SpawnBodyParts(Actor* actor, GlobalContext* globalCtx, s32 arg2, Gfx** dList) { + EnPart* part; + Actor* spawnedPart; + MtxF* currentMatrix; + + if (*dList != NULL) { + currentMatrix = Matrix_GetCurrent(); + spawnedPart = + Actor_SpawnAsChild(&globalCtx->actorCtx, actor, globalCtx, ACTOR_EN_PART, currentMatrix->mf[3][0], + currentMatrix->mf[3][1], currentMatrix->mf[3][2], 0, 0, actor->objBankIndex, arg2); + if (spawnedPart != NULL) { + part = (EnPart*)spawnedPart; + + Matrix_MtxFToYXZRot(currentMatrix, &part->actor.shape.rot, false); + part->unk_150 = *dList; + Math_Vec3f_Copy(&part->actor.scale, &actor->scale); + } + } +} + +void Actor_SpawnFloorDustRing(GlobalContext* globalCtx, Actor* actor, Vec3f* posXZ, f32 radius, s32 countMinusOne, + f32 randAccelWeight, s16 scale, s16 scaleStep, u8 useLighting) { + Vec3f pos; + Vec3f accel = { 0.0f, 0.3f, 0.0f }; + s32 pad[2]; + f32 angle; + s32 i; + + angle = (Rand_ZeroOne() - 0.5f) * (2.0f * 3.14f); + pos.y = actor->floorHeight; + accel.y += (Rand_ZeroOne() - 0.5f) * 0.2f; + + for (i = countMinusOne; i >= 0; i--) { + pos.x = (sin_rad(angle) * radius) + posXZ->x; + pos.z = (cos_rad(angle) * radius) + posXZ->z; + accel.x = (Rand_ZeroOne() - 0.5f) * randAccelWeight; + accel.z = (Rand_ZeroOne() - 0.5f) * randAccelWeight; + + if (scale == 0) { + func_800B10C0(globalCtx, &pos, &gZeroVec3f, &accel); + } else if (useLighting) { + func_800B1210(globalCtx, &pos, &gZeroVec3f, &accel, scale, scaleStep); + } else { + func_800B11A0(globalCtx, &pos, &gZeroVec3f, &accel, scale, scaleStep); + } + angle += (2.0f * 3.14f) / (countMinusOne + 1.0f); + } +} + +void func_800BBFB0(GlobalContext* globalCtx, Vec3f* position, f32 arg2, s32 arg3, s16 arg4, s16 scaleStep, u8 arg6) { + Vec3f pos; + Vec3f accel = { 0.0f, 0.3f, 0.0f }; + s32 i; + + for (i = arg3; i >= 0; i--) { + s16 scale; + + pos.x = ((Rand_ZeroOne() - 0.5f) * arg2) + position->x; + pos.y = ((Rand_ZeroOne() - 0.5f) * arg2) + position->y; + pos.z = ((Rand_ZeroOne() - 0.5f) * arg2) + position->z; + + scale = (s32)(Rand_ZeroOne() * arg4 * 0.2f); + scale += arg4; + + if (arg6) { + func_800B1210(globalCtx, &pos, &gZeroVec3f, &accel, scale, scaleStep); + } else { + func_800B11A0(globalCtx, &pos, &gZeroVec3f, &accel, scale, scaleStep); + } + } +} + +void func_800BC154(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* actor, u8 actorCategory) { + actorCtx->actorLists[actor->category].unk_08 = 1; + actor->category = actorCategory; +} + +// Damage flags for EnArrow +s32 D_801AEDB0[] = { + 0x800, 0x20, 0x20, 0x800, 0x1000, 0x2000, 0x1, 0x10000, 0x1, +}; + +s32 func_800BC188(s32 index) { + if ((index < 0) || (index >= ARRAY_COUNT(D_801AEDB0))) { + return 0; + } + + return D_801AEDB0[index]; +} + +s32 func_800BC1B4(Actor* actor, Actor* arg1, f32 arg2, f32 arg3) { + if ((arg3 > 0.0f) && (Actor_DistanceBetweenActors(arg1, actor) < ((arg3 * 2.5f) + arg2))) { + s16 temp_v1 = BINANG_SUB(Actor_YawBetweenActors(arg1, actor), arg1->world.rot.y); + + if (ABS_ALT(temp_v1) < 0x1400) { + return true; + } + } + + return false; +} + +Actor* func_800BC270(GlobalContext* globalCtx, Actor* actor, f32 arg2, s32 arg3) { + Actor* itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + + while (itemAction != NULL) { + if (((itemAction->id == ACTOR_ARMS_HOOK) && (arg3 & 0x80)) || + ((itemAction->id == ACTOR_EN_BOOM) && (arg3 & 0x10)) || + ((itemAction->id == ACTOR_EN_ARROW) && (func_800BC188(itemAction->params) & arg3))) { + f32 speedXZ; + + if ((itemAction->speedXZ <= 0.0f) && (GET_PLAYER(globalCtx)->unk_D57 != 0)) { + if (itemAction->id == ACTOR_ARMS_HOOK) { + speedXZ = 20.0f; + } else if (itemAction->id == ACTOR_EN_BOOM) { + speedXZ = 12.0f; + } else { + s32 temp_v0_3 = func_800BC188(itemAction->params); + + if (temp_v0_3 == 1) { + speedXZ = 80.0f; + } else if (temp_v0_3 == 0x10000) { + speedXZ = 60.0f; + } else { + speedXZ = 150.0f; + } + } + } else { + speedXZ = itemAction->speedXZ; + } + + if (func_800BC1B4(actor, itemAction, arg2, speedXZ)) { + break; + } + } + + itemAction = itemAction->next; + } + + return itemAction; +} + +Actor* func_800BC444(GlobalContext* globalCtx, Actor* actor, f32 arg2) { + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + + while (explosive != NULL) { + if (((explosive->id == ACTOR_EN_BOM) || (explosive->id == ACTOR_EN_BOM_CHU) || + (explosive->id == ACTOR_EN_BOMBF))) { + if (func_800BC1B4(actor, explosive, arg2, explosive->speedXZ)) { + break; + } + } + explosive = explosive->next; + } + + return explosive; +} + +/** + * Checks if a given actor will be standing on the ground after being translated + * by the provided distance and angle. + * + * Returns true if the actor will be standing on ground. + */ +s16 Actor_TestFloorInDirection(Actor* actor, GlobalContext* globalCtx, f32 distance, s16 angle) { + s16 ret; + u16 bgCheckFlags; + f32 dx; + f32 dz; + Vec3f actorPos; + + Math_Vec3f_Copy(&actorPos, &actor->world.pos); + + bgCheckFlags = actor->bgCheckFlags; + + dx = Math_SinS(angle) * distance; + dz = Math_CosS(angle) * distance; + + actor->world.pos.x += dx; + actor->world.pos.z += dz; + + Actor_UpdateBgCheckInfo(globalCtx, actor, 0.0f, 0.0f, 0.0f, 4); + Math_Vec3f_Copy(&actor->world.pos, &actorPos); + + ret = actor->bgCheckFlags & 1; + + actor->bgCheckFlags = bgCheckFlags; + + return ret; +} + +/** + * Returns true if the player is targeting the provided actor + */ +s32 Actor_IsTargeted(GlobalContext* globalCtx, Actor* actor) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->stateFlags3 & 0x80000000) && actor->isTargeted) { + return true; + } + + return false; +} + +/** + * Returns true if the player is targeting an actor other than the provided actor + */ +s32 Actor_OtherIsTargeted(GlobalContext* globalCtx, Actor* actor) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->stateFlags3 & 0x80000000) && !actor->isTargeted) { + return true; + } + + return false; +} + +void func_800BC620(Vec3f* arg0, Vec3f* arg1, u8 alpha, GlobalContext* globalCtx) { + MtxF sp58; + f32 sp54; + Vec3f sp48; + CollisionPoly* sp44; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, alpha); + + sp48.x = arg0->x; + sp48.y = arg0->y + 1.0f; + sp48.z = arg0->z; + + sp54 = BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &sp44, &sp48); + if (sp44 != NULL) { + func_800C0094(sp44, arg0->x, sp54, arg0->z, &sp58); + Matrix_Put(&sp58); + } else { + Matrix_Translate(arg0->x, arg0->y, arg0->z, MTXMODE_NEW); + } + Matrix_Scale(arg1->x, 1.0f, arg1->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++, gCircleShadowDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800BC770(GlobalContext* globalCtx, s16 y, s16 countdown) { + s16 idx = Quake_Add(&globalCtx->mainCamera, 3); + + Quake_SetSpeed(idx, 20000); + Quake_SetQuakeValues(idx, y, 0, 0, 0); + Quake_SetCountdown(idx, countdown); +} + +void func_800BC7D8(GlobalContext* globalCtx, s16 y, s16 countdown, s16 speed) { + s16 idx = Quake_Add(&globalCtx->mainCamera, 3); + + Quake_SetSpeed(idx, speed); + Quake_SetQuakeValues(idx, y, 0, 0, 0); + Quake_SetCountdown(idx, countdown); +} + +void func_800BC848(Actor* actor, GlobalContext* globalCtx, s16 y, s16 countdown) { + if (y >= 5) { + func_8013ECE0(actor->xyzDistToPlayerSq, 255, 20, 150); + } else { + func_8013ECE0(actor->xyzDistToPlayerSq, 180, 20, 100); + } + func_800BC770(globalCtx, y, countdown); +} + +typedef struct { + /* 0x00 */ f32 chainAngle; + /* 0x04 */ f32 chainLength; + /* 0x08 */ f32 yShift; + /* 0x0C */ f32 chainsScale; + /* 0x10 */ f32 chainsRotZInit; + /* 0x14 */ Gfx* chainDL; + /* 0x18 */ Gfx* lockDL; +} DoorLockInfo; // size = 0x1C + +DoorLockInfo sDoorLocksInfo[DOORLOCK_MAX] = { + /* DOORLOCK_NORMAL */ { 0.54f, 6000.0f, 5000.0, 1.0f, 0.0f, gDoorChainsDL, gDoorLockDL }, + /* DOORLOCK_BOSS */ { 0.644f, 12000.0f, 8000.0f, 1.0f, 0.0f, object_bdoor_DL_000530, object_bdoor_DL_000400 }, + /* DOORLOCK_2 */ { 0.6400000453f, 8500.0f, 8000.0f, 1.75f, 0.1f, gDoorChainsDL, gDoorLockDL }, +}; + +/** + * Draws chains and lock of a locked door, of the specified `type` (see `DoorLockType`). + * `frame` can be 0 to 10, where 0 is "open" and 10 is "closed", the chains slide accordingly. + */ +void Actor_DrawDoorLock(GlobalContext* globalCtx, s32 frame, s32 type) { + s32 pad[2]; + MtxF baseMtxF; + s32 i; + f32 chainsTranslateX; + f32 chainsTranslateY; + DoorLockInfo* entry = &sDoorLocksInfo[type]; + f32 chainRotZ = entry->chainsRotZInit; + f32 rotZStep; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(0.0f, entry->yShift, 500.0f, MTXMODE_APPLY); + Matrix_Get(&baseMtxF); + + chainsTranslateX = sinf(entry->chainAngle - chainRotZ) * -(10 - frame) * 0.1f * entry->chainLength; + chainsTranslateY = cosf(entry->chainAngle - chainRotZ) * (10 - frame) * 0.1f * entry->chainLength; + + for (i = 0; i < 4; i++) { + Matrix_Put(&baseMtxF); + Matrix_RotateZF(chainRotZ, MTXMODE_APPLY); + Matrix_Translate(chainsTranslateX, chainsTranslateY, 0.0f, MTXMODE_APPLY); + if (entry->chainsScale != 1.0f) { + Matrix_Scale(entry->chainsScale, entry->chainsScale, entry->chainsScale, MTXMODE_APPLY); + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, entry->chainDL); + + if ((i % 2) != 0) { + rotZStep = 2.0f * entry->chainAngle; + } else { + rotZStep = M_PI - (2.0f * entry->chainAngle); + } + + chainRotZ += rotZStep; + } + + Matrix_Put(&baseMtxF); + Matrix_Scale(frame * 0.1f, frame * 0.1f, frame * 0.1f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, entry->lockDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void Actor_SpawnShieldParticlesMetal(GlobalContext* globalCtx, Vec3f* pos) { + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, pos); +} + +void Actor_SetColorFilter(Actor* actor, u16 colorFlag, u16 colorIntensityMax, u16 xluFlag, u16 duration) { + if ((colorFlag == 0x8000) && !(colorIntensityMax & 0x8000)) { + Actor_PlaySfxAtPos(actor, NA_SE_EN_LIGHT_ARROW_HIT); + } + + actor->colorFilterParams = colorFlag | xluFlag | ((colorIntensityMax & 0xF8) << 5) | duration; + actor->colorFilterTimer = duration; +} + +Hilite* func_800BCBF4(Vec3f* arg0, GlobalContext* globalCtx) { + Vec3f lightDir; + + lightDir.x = globalCtx->envCtx.dirLight1.params.dir.x; + lightDir.y = globalCtx->envCtx.dirLight1.params.dir.y; + lightDir.z = globalCtx->envCtx.dirLight1.params.dir.z; + + return Hilite_DrawOpa(arg0, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx); +} + +Hilite* func_800BCC68(Vec3f* arg0, GlobalContext* globalCtx) { + Vec3f lightDir; + + lightDir.x = globalCtx->envCtx.dirLight1.params.dir.x; + lightDir.y = globalCtx->envCtx.dirLight1.params.dir.y; + lightDir.z = globalCtx->envCtx.dirLight1.params.dir.z; + + return Hilite_DrawXlu(arg0, &globalCtx->view.eye, &lightDir, globalCtx->state.gfxCtx); +} + +/** + * Calculates the closest position `dstPos` to the input position `srcPos` along the path given by `points`/`numPoints` + * Whether the points provided forms a closed-loop path is indicated by `isPathLoop` + */ +void Actor_GetClosestPosOnPath(Vec3s* points, s32 numPoints, Vec3f* srcPos, Vec3f* dstPos, s32 isPathLoop) { + s32 pointIndex; + s32 closestPointIndex; + s32 useAdjacentLines[2] = { + false, // determines whether to use line connecting to previous point in calculations + false, // determines whether to use line connecting to next point in calculations + }; + s32 isRightSideOfAdjacentLines[2] = { + false, // determines whether srcPos is on the right side of the line from prev to curr point + false, // determines whether srcPos is on the right side of the line from curr to next point + }; + Vec3f closestPoint; + Vec3f closestPos[2]; + Vec3f closestPointNext; + Vec3f closestPointPrev; + f32 distSq; // First used as distSq to closest point, then used as distSq to closest position + f32 closestPointDistSq; + f32 loopDistSq[2]; + s32 i; + + closestPointIndex = 0; + closestPointDistSq = SQ(40000.0f); + + // Find the point closest to srcPos + for (pointIndex = 0; pointIndex < numPoints; pointIndex++) { + distSq = Math3D_XZDistanceSquared(srcPos->x, srcPos->z, points[pointIndex].x, points[pointIndex].z); + if (distSq < closestPointDistSq) { + closestPointDistSq = distSq; + closestPointIndex = pointIndex; + } + } + + closestPoint.x = (points + closestPointIndex)->x; + closestPoint.z = (points + closestPointIndex)->z; + dstPos->y = (points + closestPointIndex)->y; + + // Analyze point on path immediately previous to the closest point + if (closestPointIndex != 0) { + // The point previous to the closest point + closestPointPrev.x = (points + closestPointIndex - 1)->x; + closestPointPrev.z = (points + closestPointIndex - 1)->z; + } else if (isPathLoop) { + // Closest point is the first point in the path list + // Set the previous point to loop around to the the final point on the path + closestPointPrev.x = (points + numPoints - 1)->x; + closestPointPrev.z = (points + numPoints - 1)->z; + } + if ((closestPointIndex != 0) || isPathLoop) { + // Use the adjacent line + useAdjacentLines[0] = + Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPointPrev.x, closestPointPrev.z, closestPoint.x, + closestPoint.z, &closestPos[0].x, &closestPos[0].z, &distSq); + } + + // Analyze point on path immediately next to the closest point + if (closestPointIndex + 1 != numPoints) { + // The point next to the closest point + closestPointNext.x = (points + closestPointIndex + 1)->x; + closestPointNext.z = (points + closestPointIndex + 1)->z; + } else if (isPathLoop) { + // Closest point is the final point in the path list + // Set the next point to loop around to the the first point on the path + closestPointNext.x = (points + 0)->x; + closestPointNext.z = (points + 0)->z; + } + if ((closestPointIndex + 1 != numPoints) || isPathLoop) { + useAdjacentLines[1] = + Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPoint.x, closestPoint.z, closestPointNext.x, + closestPointNext.z, &closestPos[1].x, &closestPos[1].z, &distSq); + } + + /** + * For close-looped paths, they must be defined in a clockwise orientation looking from the top down. + * Therefore, `srcPos` being interior of the loop will lead to both lines of `isRightSideOfAdjacentLines` + * returning true. + */ + if (isPathLoop) { + isRightSideOfAdjacentLines[0] = ((closestPointPrev.x - srcPos->x) * (closestPoint.z - srcPos->z)) < + ((closestPointPrev.z - srcPos->z) * (closestPoint.x - srcPos->x)); + + isRightSideOfAdjacentLines[1] = ((closestPointNext.z - srcPos->z) * (closestPoint.x - srcPos->x)) < + ((closestPoint.z - srcPos->z) * (closestPointNext.x - srcPos->x)); + + for (i = 0; i < ARRAY_COUNT(loopDistSq); i++) { + if (useAdjacentLines[i]) { + // Get distSq from srcPos to closestPos + loopDistSq[i] = Math3D_XZDistanceSquared(srcPos->x, srcPos->z, closestPos[i].x, closestPos[i].z); + } else { + // The closest Pos is not contained within the line-segment + loopDistSq[i] = SQ(40000.0f); + } + } + } + + // Calculate closest position along path + if (isPathLoop && ((isRightSideOfAdjacentLines[0] && isRightSideOfAdjacentLines[1]) || + (isRightSideOfAdjacentLines[0] && useAdjacentLines[0] && (loopDistSq[0] < loopDistSq[1])) || + (isRightSideOfAdjacentLines[1] && useAdjacentLines[1] && (loopDistSq[1] < loopDistSq[0])))) { + // srcPos is contained within the closed loop + dstPos->x = srcPos->x; + dstPos->z = srcPos->z; + } else if (useAdjacentLines[0] && useAdjacentLines[1]) { + // srcPos is somewhere withing the bend of the path + if (!isRightSideOfAdjacentLines[0] && !isRightSideOfAdjacentLines[1]) { + // srcPos is not inside a loop + if (!Math3D_PointDistToLine2D(srcPos->x, srcPos->z, closestPos[0].x, closestPos[0].z, closestPos[1].x, + closestPos[1].z, &dstPos->x, &dstPos->z, &distSq)) { + // The dstPos calculated in Math3D_PointDistToLine2D was not valid. + // Take the midpoint of the two closest ponits instead + dstPos->x = (closestPos[1].x + closestPos[0].x) * 0.5f; + dstPos->z = (closestPos[1].z + closestPos[0].z) * 0.5f; + } + } else if (loopDistSq[1] < loopDistSq[0]) { + // Use closest position along the line in the loop connecting the closest point and the next point + dstPos->x = closestPos[1].x; + dstPos->z = closestPos[1].z; + } else { + // Use closest position along the ling in the loop connecting the closest point and the prev point + dstPos->x = closestPos[0].x; + dstPos->z = closestPos[0].z; + } + } else if (useAdjacentLines[0]) { + // Use closest position along line segment connecting the closest point and the prev point + dstPos->x = closestPos[0].x; + dstPos->z = closestPos[0].z; + } else if (useAdjacentLines[1]) { + // Use closest position along line segment connecting the closest point and the next point + dstPos->x = closestPos[1].x; + dstPos->z = closestPos[1].z; + } else if (isPathLoop && ((((closestPointPrev.x - srcPos->x) * (closestPointNext.z - srcPos->z)) < + ((closestPointPrev.z - srcPos->z) * (closestPointNext.x - srcPos->x))))) { + // Inside the line that directly connects the previous point to the next point (inside the bend of a corner) + dstPos->x = srcPos->x; + dstPos->z = srcPos->z; + } else { + // The closest point and the closest position are the same (srcPos is near the outer region of a corner) + dstPos->x = closestPoint.x; + dstPos->z = closestPoint.z; + } +} + +// unused +s32 func_800BD2B4(GlobalContext* globalCtx, Actor* actor, s16* arg2, f32 arg3, + u16 (*textIdCallback)(GlobalContext*, Actor*), s16 (*arg5)(GlobalContext*, Actor*)) { + if (Actor_ProcessTalkRequest(actor, &globalCtx->state)) { + *arg2 = true; + return true; + } else if (*arg2) { + *arg2 = arg5(globalCtx, actor); + return false; + } else if (!func_800B8934(globalCtx, actor)) { + return false; + } else if (!func_800B8614(actor, globalCtx, arg3)) { + return false; + } else { + actor->textId = textIdCallback(globalCtx, actor); + return false; + } +} + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ s16 unk_04; + /* 0x06 */ s16 unk_06; + /* 0x08 */ s16 unk_08; + /* 0x0A */ s16 unk_0A; + /* 0x0C */ u8 unk_0C; +} struct_801AEE38_0; // size = 0x10 + +typedef struct { + /* 0x00 */ struct_801AEE38_0 sub_00; + /* 0x10 */ f32 unk_10; + /* 0x14 */ s16 unk_14; +} struct_801AEE38; // size = 0x18 + +struct_801AEE38 D_801AEE38[] = { + { { 0x1C20, 0xE390, 0x1C70, 0x1554, 0x0000, 0x0000, 0x0000 }, 170.0f, 0x3FFC }, + { { 0x2AA8, 0xEAAC, 0x1554, 0x1554, 0xF8E4, 0x0E38, 0x0001 }, 170.0f, 0x3FFC }, + { { 0x31C4, 0xE390, 0x0E38, 0x0E38, 0xF1C8, 0x071C, 0x0001 }, 170.0f, 0x3FFC }, + { { 0x1554, 0xF1C8, 0x0000, 0x071C, 0xF8E4, 0x0000, 0x0001 }, 170.0f, 0x3FFC }, + { { 0x2AA8, 0xF8E4, 0x071C, 0x0E38, 0xD558, 0x2AA8, 0x0001 }, 170.0f, 0x3FFC }, + { { 0x0000, 0xE390, 0x2AA8, 0x3FFC, 0xF1C8, 0x0E38, 0x0001 }, 170.0f, 0x3FFC }, + { { 0x2AA8, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 0x0001 }, 0.0f, 0x0000 }, + { { 0x2AA8, 0xF1C8, 0x0000, 0x0E38, 0x0000, 0x1C70, 0x0001 }, 0.0f, 0x0000 }, + { { 0x2AA8, 0xF1C8, 0xF1C8, 0x0000, 0x0000, 0x0000, 0x0001 }, 0.0f, 0x0000 }, + { { 0x071C, 0xF1C8, 0x0E38, 0x1C70, 0x0000, 0x0000, 0x0001 }, 0.0f, 0x0000 }, + { { 0x0E38, 0xF1C8, 0x0000, 0x1C70, 0x0000, 0x0E38, 0x0001 }, 0.0f, 0x0000 }, + { { 0x2AA8, 0xE390, 0x1C70, 0x0E38, 0xF1C8, 0x0E38, 0x0001 }, 0.0f, 0x0000 }, + { { 0x18E2, 0xF1C8, 0x0E38, 0x0E38, 0x0000, 0x0000, 0x0001 }, 0.0f, 0x0000 }, + { { 0x2A6C, 0xE390, 0x1C70, 0x1554, 0x0000, 0x0000, 0x0000 }, 170.0f, 0x3FFC }, +}; + +void func_800BD384(Actor* actor, struct_800BD888_arg1* arg1, s16 arg2, s16 arg3, s16 arg4, s16 arg5, s16 arg6, s16 arg7, + u8 arg8) { + s16 sp46; + s16 sp44; + s16 temp2; + s16 sp40; + s16 temp1; + Vec3f sp30; + + sp30.x = actor->world.pos.x; + sp30.y = actor->world.pos.y + arg1->unk_14; + sp30.z = actor->world.pos.z; + + sp46 = Math_Vec3f_Pitch(&sp30, &arg1->unk_18); + sp44 = Math_Vec3f_Yaw(&sp30, &arg1->unk_18); + sp40 = Math_Vec3f_Yaw(&actor->world.pos, &arg1->unk_18) - actor->shape.rot.y; + + temp1 = CLAMP(sp40, -arg2, arg2); + Math_SmoothStepToS(&arg1->unk_08.y, temp1, 6, 2000, 1); + + temp1 = (ABS_ALT(sp40) >= 0x8000) ? 0 : ABS_ALT(sp40); + arg1->unk_08.y = CLAMP(arg1->unk_08.y, -temp1, temp1); + + sp40 -= arg1->unk_08.y; + + temp1 = CLAMP(sp40, -arg5, arg5); + Math_SmoothStepToS(&arg1->unk_0E.y, temp1, 6, 2000, 1); + + temp1 = (ABS_ALT(sp40) >= 0x8000) ? 0 : ABS_ALT(sp40); + arg1->unk_0E.y = CLAMP(arg1->unk_0E.y, -temp1, temp1); + + if (arg8) { + Math_SmoothStepToS(&actor->shape.rot.y, sp44, 6, 2000, 1); + } + + temp1 = CLAMP(sp46, arg4, (s16)(u16)arg3); + Math_SmoothStepToS(&arg1->unk_08.x, temp1, 6, 2000, 1); + + temp2 = sp46 - arg1->unk_08.x; + + temp1 = CLAMP(temp2, arg7, arg6); + Math_SmoothStepToS(&arg1->unk_0E.x, temp1, 6, 2000, 1); +} + +// unused +s16 func_800BD6B8(s16 arg0) { + return D_801AEE38[arg0].unk_14; +} + +s16 func_800BD6E4(Actor* actor, struct_800BD888_arg1* arg1, f32 arg2, s16 arg3, s16 flag) { + s32 pad; + + if (flag) { + return flag; + } else if (arg1->unk_00 != 0) { + return 4; + } else if (arg2 < Math_Vec3f_DistXYZ(&actor->world.pos, &arg1->unk_18)) { + arg1->unk_04 = 0; + arg1->unk_06 = 0; + return 1; + } else { + s16 yaw = Math_Vec3f_Yaw(&actor->world.pos, &arg1->unk_18); + s16 phi_a0 = ABS_ALT(BINANG_SUB(yaw, actor->shape.rot.y)); + + if (arg3 >= phi_a0) { + arg1->unk_04 = 0; + arg1->unk_06 = 0; + return 2; + } else if (DECR(arg1->unk_04) != 0) { + return arg1->unk_02; + } else { + switch (arg1->unk_06) { + case 0: + case 2: + arg1->unk_04 = Rand_S16Offset(30, 30); + arg1->unk_06++; + return 1; + + case 1: + arg1->unk_04 = Rand_S16Offset(10, 10); + arg1->unk_06++; + return 3; + + default: + return 4; + } + } + } +} // This function is very similar to OoT's func_80034A14 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD888.s") +void func_800BD888(Actor* actor, struct_800BD888_arg1* arg1, s16 arg2, s16 arg3) { + struct_801AEE38_0 sp38; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD9A0.s") + arg1->unk_02 = func_800BD6E4(actor, arg1, D_801AEE38[arg2].unk_10, D_801AEE38[arg2].unk_14, arg3); + sp38 = D_801AEE38[arg2].sub_00; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BD9E0.s") + switch (arg1->unk_02) { + case 1: + sp38.unk_00 = 0; + sp38.unk_04 = 0; + sp38.unk_02 = 0; + case 3: + sp38.unk_06 = 0; + sp38.unk_0A = 0; + sp38.unk_08 = 0; + case 2: + sp38.unk_0C = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BDAA0.s") + func_800BD384(actor, arg1, sp38.unk_00, sp38.unk_04, sp38.unk_02, sp38.unk_06, sp38.unk_0A, sp38.unk_08, + sp38.unk_0C); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BDB6C.s") +Gfx D_801AEF88[] = { + gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + G_RM_FOG_SHADE_A, + AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)), + gsDPSetAlphaCompare(G_AC_THRESHOLD), + gsSPEndDisplayList(), +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BDC5C.s") +Gfx D_801AEFA0[] = { + gsSPEndDisplayList(), +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BDCF4.s") +Gfx* func_800BD9A0(GraphicsContext* gfxCtx) { + Gfx* displayListHead; + Gfx* displayList; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_Noop.s") + displayListHead = displayList = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 2); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BDFC0.s") + gDPSetRenderMode(displayListHead++, + AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + G_RM_FOG_SHADE_A, + AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)); + gSPEndDisplayList(displayListHead++); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE03C.s") + return displayList; +} -Actor* func_800BE0B8(GlobalContext* globalCtx, Actor* inActor, s16 arg2, u8 arg3, f32 arg4) { - Actor* actor = globalCtx->actorCtx.actorList[arg3].first; +// unused +void func_800BD9E0(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, + PostLimbDraw postLimbDraw, Actor* actor, s16 alpha) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, alpha); + gSPSegment(POLY_OPA_DISP++, 0x0C, gEmptyDL); + + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->jointTable, skelAnime->dListCount, + overrideLimbDraw, postLimbDraw, actor, POLY_OPA_DISP); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800BDAA0(GlobalContext* globalCtx, SkelAnime* skelAnime, OverrideLimbDraw overrideLimbDraw, + PostLimbDraw postLimbDraw, Actor* actor, s16 alpha) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, alpha); + gSPSegment(POLY_XLU_DISP++, 0x0C, func_800BD9A0(globalCtx->state.gfxCtx)); + + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, skelAnime->skeleton, skelAnime->jointTable, skelAnime->dListCount, + overrideLimbDraw, postLimbDraw, actor, POLY_XLU_DISP); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +// Unused +s16 func_800BDB6C(Actor* actor, GlobalContext* globalCtx, s16 arg2, f32 arg3) { + Player* player = GET_PLAYER(globalCtx); + f32 phi_f2; + + if ((globalCtx->csCtx.state != 0) || (D_801D0D50 != 0)) { + phi_f2 = Math_Vec3f_DistXYZ(&actor->world.pos, &globalCtx->view.eye) * 0.25f; + } else { + phi_f2 = Math_Vec3f_DistXYZ(&actor->world.pos, &player->actor.world.pos); + } + + if (arg3 < phi_f2) { + actor->flags &= ~ACTOR_FLAG_1; + Math_SmoothStepToS(&arg2, 0, 6, 0x14, 1); + } else { + actor->flags |= ACTOR_FLAG_1; + Math_SmoothStepToS(&arg2, 0xFF, 6, 0x14, 1); + } + + return arg2; +} + +void Actor_ChangeAnimationByInfo(SkelAnime* skelAnime, AnimationInfo* animation, s32 index) { + f32 frameCount; + + animation += index; + if (animation->frameCount > 0.0f) { + frameCount = animation->frameCount; + } else { + frameCount = Animation_GetLastFrame(&animation->animation->common); + } + + Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, frameCount, + animation->mode, animation->morphFrames); +} + +// Unused +void func_800BDCF4(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 size) { + s32 frames = globalCtx->gameplayFrames; + s32 i; + + for (i = 0; i < size; i++) { + arg1[i] = (0x814 + 50 * i) * frames; + arg2[i] = (0x940 + 50 * i) * frames; + } +} + +void Actor_Noop(Actor* actor, GlobalContext* globalCtx) { +} + +#include "z_cheap_proc.c" + +/** + * Finds the first actor instance of a specified Id and category within a given range from + * an actor if there is one. If the Id provided is -1, this will look for any actor of the + * specified category rather than a specific Id. + */ +Actor* Actor_FindNearby(GlobalContext* globalCtx, Actor* inActor, s16 actorId, u8 actorCategory, f32 distance) { + Actor* actor = globalCtx->actorCtx.actorLists[actorCategory].first; while (actor != NULL) { - if (actor == inActor || ((arg2 != -1) && (arg2 != actor->id))) { + if (actor == inActor || ((actorId != -1) && (actorId != actor->id))) { actor = actor->next; continue; } - if (Actor_DistanceBetweenActors(inActor, actor) <= arg4) { + if (Actor_DistanceBetweenActors(inActor, actor) <= distance) { return actor; } @@ -870,26 +4351,447 @@ Actor* func_800BE0B8(GlobalContext* globalCtx, Actor* inActor, s16 arg2, u8 arg3 return NULL; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE184.s") +s32 func_800BE184(GlobalContext* globalCtx, Actor* actor, f32 xzDist, s16 arg3, s16 arg4, s16 arg5) { + Player* player = GET_PLAYER(globalCtx); + s16 phi_v0 = BINANG_SUB(BINANG_ROT180(actor->yawTowardsPlayer), player->actor.shape.rot.y); + s16 temp_t0 = actor->yawTowardsPlayer - arg5; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/Actor_ApplyDamage.s") + if ((actor->xzDistToPlayer <= xzDist) && (player->swordState != 0)) { + if ((arg4 >= ABS_ALT(phi_v0)) && (arg3 >= ABS_ALT(temp_t0))) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE258.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE2B8.s") +u8 Actor_ApplyDamage(Actor* actor) { + if (actor->colChkInfo.damage >= actor->colChkInfo.health) { + actor->colChkInfo.health = 0; + } else { + actor->colChkInfo.health -= actor->colChkInfo.damage; + } + return actor->colChkInfo.health; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE33C.s") +void Actor_SetDropFlag(Actor* actor, ColliderInfo* colInfo) { + ColliderInfo* acHitInfo = colInfo->acHitInfo; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE3D0.s") + if (acHitInfo == NULL) { + actor->dropFlag = 0; + } else if (acHitInfo->toucher.dmgFlags & 0x800) { // DMG_FIRE_ARROW + actor->dropFlag = 1; + } else if (acHitInfo->toucher.dmgFlags & 0x1000) { // DMG_ICE_ARROW + actor->dropFlag = 2; + } else if (acHitInfo->toucher.dmgFlags & 0x2000) { // DMG_LIGHT_ARROW + actor->dropFlag = 0x20; + } else { + actor->dropFlag = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE504.s") +void Actor_SetDropFlagJntSph(Actor* actor, ColliderJntSph* jntSphere) { + s32 i; + ColliderJntSphElement* jntElement; + ColliderInfo* acHitInfo; + s32 flag; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE568.s") + actor->dropFlag = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE5CC.s") + for (i = jntSphere->count - 1; i >= 0; i--) { + jntElement = &jntSphere->elements[i]; + acHitInfo = jntElement->info.acHitInfo; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE63C.s") + if (acHitInfo == NULL) { + flag = 0; + } else { + s32 dmgFlags = acHitInfo->toucher.dmgFlags; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BE680.s") + if (dmgFlags & 0x800) { + flag = 1; + } else if (dmgFlags & 0x1000) { + flag = 2; + } else { + flag = (dmgFlags & 0x2000) ? 0x20 : 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_actor/func_800BF7CC.s") + actor->dropFlag |= flag; + } +} + +void func_800BE33C(Vec3f* arg0, Vec3f* arg1, Vec3s* arg2, s32 arg3) { + f32 xDiff = arg1->x - arg0->x; + f32 zDiff = arg1->z - arg0->z; + f32 yDiff = arg3 ? (arg1->y - arg0->y) : (arg0->y - arg1->y); + + arg2->y = Math_FAtan2F(zDiff, xDiff); + arg2->x = Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), yDiff); +} + +void func_800BE3D0(Actor* actor, s16 angle, Vec3s* arg2) { + f32 sp44; + f32 sp40; + f32 sp3C; + f32 sp38; + f32 sp34; + f32 sp30; + f32 sp2C; + s32 pad[3]; + + if (actor->floorPoly != NULL) { + CollisionPoly* floorPoly = actor->floorPoly; + + sp44 = COLPOLY_GET_NORMAL(floorPoly->normal.x); + sp40 = COLPOLY_GET_NORMAL(floorPoly->normal.y); + sp3C = COLPOLY_GET_NORMAL(floorPoly->normal.z); + + sp38 = Math_SinS(angle); + sp34 = Math_CosS(angle); + arg2->x = (s16)-Math_Atan2S((-(sp44 * sp38) - (sp3C * sp34)) * sp40, 1.0f); + + sp2C = Math_SinS(angle - 0x3FF7); + sp30 = Math_CosS(angle - 0x3FF7); + arg2->z = (s16)-Math_Atan2S((-(sp44 * sp2C) - (sp3C * sp30)) * sp40, 1.0f); + } +} + +void func_800BE504(Actor* actor, ColliderCylinder* collider) { + // Checks if was hit by either DMG_NORMAL_ARROW, DMG_FIRE_ARROW, DMG_ICE_ARROW, DMG_LIGHT_ARROW or DMG_DEKU_BUBBLE + if ((collider->info.acHitInfo->toucher.dmgFlags & (0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20))) { + actor->world.rot.y = collider->base.ac->shape.rot.y; + } else { + actor->world.rot.y = Actor_YawBetweenActors(collider->base.ac, actor); + } +} + +void func_800BE568(Actor* actor, ColliderSphere* collider) { + if (collider->info.acHitInfo->toucher.dmgFlags & (0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20)) { + actor->world.rot.y = collider->base.ac->shape.rot.y; + } else { + actor->world.rot.y = Actor_YawBetweenActors(collider->base.ac, actor); + } +} + +void func_800BE5CC(Actor* actor, ColliderJntSph* collider, s32 colliderIndex) { + if (collider->elements[colliderIndex].info.acHitInfo->toucher.dmgFlags & + (0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20)) { + actor->world.rot.y = collider->base.ac->shape.rot.y; + } else { + actor->world.rot.y = Actor_YawBetweenActors(collider->base.ac, actor); + } +} + +s32 func_800BE63C(struct EnBox* chest) { + if ((chest->unk_1F1 == 5) || (chest->unk_1F1 == 6) || (chest->unk_1F1 == 7) || (chest->unk_1F1 == 8) || + (chest->unk_1F1 == 0xC)) { + return true; + } + return false; +} + +TexturePtr sElectricSparkTextures[] = { + gElectricSpark1Tex, + gElectricSpark2Tex, + gElectricSpark3Tex, + gElectricSpark4Tex, +}; + +/** + * Draw common damage effects applied to each limb provided in limbPos + */ +void Actor_DrawDamageEffects(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s16 limbPosCount, f32 effectScale, + f32 frozenSteamScale, f32 effectAlpha, u8 type) { + if (effectAlpha > 0.001f) { + s32 twoTexScrollParam; + s16 limbIndex; + MtxF* currentMatrix; + f32 alpha; + f32 frozenScale; + f32 lightOrbsScale; + f32 electricSparksScale; + f32 steamScale; + Vec3f* limbPosStart = limbPos; + u32 gameplayFrames = globalCtx->gameplayFrames; + f32 effectAlphaScaled; + + currentMatrix = Matrix_GetCurrent(); + + // Apply sfx along with damage effect + if ((actor != NULL) && (effectAlpha > 0.05f) && (globalCtx->gameOverCtx.state == 0)) { + if (type == ACTOR_DRAW_DMGEFF_FIRE) { + Actor_PlaySfxAtPos(actor, NA_SE_EV_BURN_OUT - SFX_FLAG); + } else if (type == ACTOR_DRAW_DMGEFF_BLUE_FIRE) { + Actor_PlaySfxAtPos(actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } else if (type == ACTOR_DRAW_DMGEFF_FROZEN_SFX) { + Actor_PlaySfxAtPos(actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } else if ((type == ACTOR_DRAW_DMGEFF_LIGHT_ORBS) || (type == ACTOR_DRAW_DMGEFF_BLUE_LIGHT_ORBS)) { + Actor_PlaySfxAtPos(actor, NA_SE_EN_COMMON_DEADLIGHT - SFX_FLAG); + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + switch (type) { + case ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX: + case ACTOR_DRAW_DMGEFF_FROZEN_SFX: + frozenScale = ((KREG(19) * 0.01f) + 2.3f) * effectScale; + steamScale = ((KREG(28) * 0.0001f) + 0.035f) * frozenSteamScale; + func_800BCC68(limbPos, globalCtx); + + // Setup to draw ice over frozen actor + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, gameplayFrames & 0xFF, 32, 16, 1, 0, + (gameplayFrames * 2) & 0xFF, 64, 32)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, 255); + gSPDisplayList(POLY_XLU_DISP++, gFrozenIceDL); + + effectAlphaScaled = effectAlpha * 255.0f; + + // Apply and draw ice over each limb of frozen actor + for (limbIndex = 0; limbIndex < limbPosCount; limbIndex++, limbPos++) { + alpha = limbIndex & 3; + alpha = effectAlphaScaled - (30.0f * alpha); + if (effectAlphaScaled < (30.0f * (limbIndex & 3))) { + alpha = 0.0f; + } + if (alpha > 255.0f) { + alpha = 255.0f; + } + + gDPSetEnvColor(POLY_XLU_DISP++, KREG(20) + 200, KREG(21) + 200, KREG(22) + 255, (u8)alpha); + + Matrix_Translate(limbPos->x, limbPos->y, limbPos->z, MTXMODE_NEW); + Matrix_Scale(frozenScale, frozenScale, frozenScale, MTXMODE_APPLY); + + if (limbIndex & 1) { + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + } + + if (limbIndex & 2) { + Matrix_RotateZF(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++, gFrozenIceVtxDL); + } + + limbPos = limbPosStart; // reset limbPos + + // Setup to draw steam over frozen actor + + gDPSetColorDither(POLY_XLU_DISP++, G_CD_BAYER); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_PATTERN); + gSPDisplayList(POLY_XLU_DISP++, gFrozenSteamDL); + + alpha = effectAlpha * 100.0f; + if (alpha > 100.0f) { + alpha = 100.0f; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (u8)alpha); + + // Apply and draw steam over each limb of frozen actor + for (limbIndex = 0; limbIndex < limbPosCount; limbIndex++, limbPos++) { + twoTexScrollParam = ((limbIndex * 3) + gameplayFrames); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, twoTexScrollParam * 3, + twoTexScrollParam * -12, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_Translate(limbPos->x, limbPos->y, limbPos->z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(steamScale, steamScale, 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++, gFrozenSteamVtxDL); + } + break; + + case ACTOR_DRAW_DMGEFF_FIRE: + case ACTOR_DRAW_DMGEFF_BLUE_FIRE: + if (type == ACTOR_DRAW_DMGEFF_FIRE) { + gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0); + } else { + gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 255, 0); + // Reuse type for blue primitive color + type = 255; + } + + Matrix_Put(&globalCtx->billboardMtxF); + Matrix_Scale((effectScale * 0.005f) * 1.35f, (effectScale * 0.005f), (effectScale * 0.005f) * 1.35f, + MTXMODE_APPLY); + + effectAlphaScaled = effectAlpha * 255.0f; + + // Apply and draw fire on every limb + for (limbIndex = 0; limbIndex < limbPosCount; limbIndex++, limbPos++) { + alpha = limbIndex & 3; + alpha = effectAlphaScaled - 30.0f * alpha; + if (effectAlphaScaled < 30.0f * (limbIndex & 3)) { + alpha = 0.0f; + } + if (alpha > 255.0f) { + alpha = 255.0f; + } + + // Use type for blue primitive color + // = 0 for ACTOR_DRAW_DMGEFF_FIRE + // = 255 for ACTOR_DRAW_DMGEFF_BLUE_FIRE + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, type, (u8)alpha); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((limbIndex * 10 + gameplayFrames) * -20) & 0x1FF, 32, 128)); + + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + currentMatrix->mf[3][0] = limbPos->x; + currentMatrix->mf[3][1] = limbPos->y; + currentMatrix->mf[3][2] = limbPos->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + break; + + case ACTOR_DRAW_DMGEFF_LIGHT_ORBS: + case ACTOR_DRAW_DMGEFF_BLUE_LIGHT_ORBS: + + // Setup to draw light orbs on actor + + lightOrbsScale = ((KREG(19) * 0.01f) + 4.0f) * effectScale; + + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + + alpha = effectAlpha * 255.0f; + if (alpha > 255.0f) { + alpha = 255.0f; + } + + if (type == ACTOR_DRAW_DMGEFF_BLUE_LIGHT_ORBS) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)(sREG(16) + 255), (u8)(sREG(17) + 255), + (u8)(sREG(18) + 255), (u8)alpha); + + gDPSetEnvColor(POLY_XLU_DISP++, (u8)sREG(19), (u8)(sREG(20) + 255), (u8)(sREG(21) + 255), 128); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)alpha); + + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 100, 128); + } + + Matrix_Put(&globalCtx->billboardMtxF); + Matrix_Scale(lightOrbsScale, lightOrbsScale, 1.0f, MTXMODE_APPLY); + + // Apply and draw a light orb over each limb of frozen actor + for (limbIndex = 0; limbIndex < limbPosCount; limbIndex++, limbPos++) { + Matrix_RotateZF(randPlusMinusPoint5Scaled(2 * M_PI), MTXMODE_APPLY); + currentMatrix->mf[3][0] = limbPos->x; + currentMatrix->mf[3][1] = limbPos->y; + currentMatrix->mf[3][2] = limbPos->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); + } + break; + + case ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL: + case ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM: + case ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE: + if (type == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL) { + electricSparksScale = (KREG(19) * 0.01f + 1.0f) * effectScale; + } else if (type == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM) { + electricSparksScale = (KREG(19) * 0.01f + 1.5f) * effectScale; + } else { + electricSparksScale = (KREG(19) * 0.01f + 2.0f) * effectScale; + } + + gSPSegment(POLY_XLU_DISP++, 0x08, + Lib_SegmentedToVirtual(sElectricSparkTextures[globalCtx->gameplayFrames % 4])); + + gSPDisplayList(POLY_XLU_DISP++, gElectricSparkDL); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)(sREG(16) + 255), (u8)(sREG(17) + 255), (u8)(sREG(18) + 150), + (u8)(sREG(19) + 255)); + + gDPSetEnvColor(POLY_XLU_DISP++, (u8)(sREG(20) + 255), (u8)(sREG(21) + 255), (u8)sREG(22), (u8)sREG(23)); + + Matrix_Put(&globalCtx->billboardMtxF); + Matrix_Scale(electricSparksScale, electricSparksScale, electricSparksScale, MTXMODE_APPLY); + + // Every limb draws two electric sparks at random orientations + for (limbIndex = 0; limbIndex < limbPosCount; limbIndex++, limbPos++) { + // first electric spark + Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI)); + Matrix_RotateZF(Rand_ZeroFloat(2 * M_PI), MTXMODE_APPLY); + currentMatrix->mf[3][0] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->x; + currentMatrix->mf[3][1] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->y; + currentMatrix->mf[3][2] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gElectricSparkVtxDL); + + // second electric spark + Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI)); + Matrix_RotateZF(Rand_ZeroFloat(2 * M_PI), MTXMODE_APPLY); + currentMatrix->mf[3][0] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->x; + currentMatrix->mf[3][1] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->y; + currentMatrix->mf[3][2] = randPlusMinusPoint5Scaled((f32)sREG(24) + 30.0f) + limbPos->z; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gElectricSparkVtxDL); + } + + break; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void Actor_SpawnIceEffects(GlobalContext* globalCtx, Actor* actor, Vec3f limbPos[], s32 limbPosCount, + s32 effectsPerLimb, f32 scale, f32 scaleRange) { + static Color_RGBA8 primColor = { 170, 255, 255, 255 }; + static Color_RGBA8 envColor = { 200, 200, 255, 255 }; + static Vec3f accel = { 0.0f, -1.0f, 0.0f }; + s32 i; + s32 pad; + Vec3f velocity; + s16 randomYaw; + s16 yaw; + s32 j; + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &actor->world.pos, 30, NA_SE_EV_ICE_BROKEN); + + for (i = 0; i < limbPosCount; i++) { + yaw = Actor_YawToPoint(actor, limbPos); + + for (j = 0; j < effectsPerLimb; j++) { + randomYaw = (Rand_Next() >> 0x13) + yaw; + + velocity.z = Rand_ZeroFloat(5.0f); + + velocity.x = Math_SinS(randomYaw) * velocity.z; + velocity.y = Rand_ZeroFloat(4.0f) + 8.0f; + velocity.z *= Math_CosS(randomYaw); + + EffectSsEnIce_Spawn(globalCtx, limbPos, Rand_ZeroFloat(scaleRange) + scale, &velocity, &accel, &primColor, + &envColor, 30); + } + + limbPos++; + } +} diff --git a/src/code/z_actor_dlftbls.c b/src/code/z_actor_dlftbls.c index f33fcd538..77b6546ff 100644 --- a/src/code/z_actor_dlftbls.c +++ b/src/code/z_actor_dlftbls.c @@ -722,7 +722,7 @@ void ActorOverlayTable_FaultPrint(void* arg0, void* arg1) { FaultDrawer_Printf("No. RamStart- RamEnd cn Name\n"); for (i = 0, overlayEntry = &gActorOverlayTable[0]; i < gMaxActorId; i++, overlayEntry++) { - overlaySize = (u32)overlayEntry->vramEnd - (u32)overlayEntry->vramStart; + overlaySize = VRAM_PTR_SIZE(overlayEntry); if (overlayEntry->loadedRamAddr != NULL) { FaultDrawer_Printf("%3d %08x-%08x %3d %s\n", i, overlayEntry->loadedRamAddr, (u32)overlayEntry->loadedRamAddr + overlaySize, overlayEntry->numLoaded, ""); @@ -740,7 +740,7 @@ void* ActorOverlayTable_FaultAddrConv(void* arg0, void* arg1) { u32 offset; for (i = 0; i < gMaxActorId; i++, overlayEntry++) { - size = (u8*)overlayEntry->vramEnd - (u8*)overlayEntry->vramStart; + size = VRAM_PTR_SIZE(overlayEntry); ramStart = overlayEntry->loadedRamAddr; ramEnd = ramStart + size; offset = (u8*)overlayEntry->vramStart - ramStart; diff --git a/src/code/z_bg_collect.c b/src/code/z_bg_collect.c index 29c4cf7da..0d4f4a21f 100644 --- a/src/code/z_bg_collect.c +++ b/src/code/z_bg_collect.c @@ -1,33 +1,33 @@ #include "global.h" -void BgCheck2_UpdateActorPosition(CollisionContext* colCtx, s32 index, Actor* actor) { +void BgCheck2_UpdateActorPosition(CollisionContext* colCtx, s32 bgId, Actor* actor) { MtxF prevMatrix; MtxF prevMatrixInv; MtxF currMatrix; Vec3f newPos; Vec3f posWithInv; - if (BgCheck_IsActorMeshIndexValid(index) == 0) { + if (!DynaPoly_IsBgIdBgActor(bgId)) { return; } SkinMatrix_SetScaleRotateYRPTranslate( - &prevMatrix, colCtx->dyna.bgActors[index].prevTransform.scale.x, - colCtx->dyna.bgActors[index].prevTransform.scale.y, colCtx->dyna.bgActors[index].prevTransform.scale.z, - colCtx->dyna.bgActors[index].prevTransform.rot.x, colCtx->dyna.bgActors[index].prevTransform.rot.y, - colCtx->dyna.bgActors[index].prevTransform.rot.z, colCtx->dyna.bgActors[index].prevTransform.pos.x, - colCtx->dyna.bgActors[index].prevTransform.pos.y, colCtx->dyna.bgActors[index].prevTransform.pos.z); + &prevMatrix, colCtx->dyna.bgActors[bgId].prevTransform.scale.x, + colCtx->dyna.bgActors[bgId].prevTransform.scale.y, colCtx->dyna.bgActors[bgId].prevTransform.scale.z, + colCtx->dyna.bgActors[bgId].prevTransform.rot.x, colCtx->dyna.bgActors[bgId].prevTransform.rot.y, + colCtx->dyna.bgActors[bgId].prevTransform.rot.z, colCtx->dyna.bgActors[bgId].prevTransform.pos.x, + colCtx->dyna.bgActors[bgId].prevTransform.pos.y, colCtx->dyna.bgActors[bgId].prevTransform.pos.z); if (SkinMatrix_Invert(&prevMatrix, &prevMatrixInv) == 2) { return; } SkinMatrix_SetScaleRotateYRPTranslate( - &currMatrix, colCtx->dyna.bgActors[index].curTransform.scale.x, - colCtx->dyna.bgActors[index].curTransform.scale.y, colCtx->dyna.bgActors[index].curTransform.scale.z, - colCtx->dyna.bgActors[index].curTransform.rot.x, colCtx->dyna.bgActors[index].curTransform.rot.y, - colCtx->dyna.bgActors[index].curTransform.rot.z, colCtx->dyna.bgActors[index].curTransform.pos.x, - colCtx->dyna.bgActors[index].curTransform.pos.y, colCtx->dyna.bgActors[index].curTransform.pos.z); + &currMatrix, colCtx->dyna.bgActors[bgId].curTransform.scale.x, colCtx->dyna.bgActors[bgId].curTransform.scale.y, + colCtx->dyna.bgActors[bgId].curTransform.scale.z, colCtx->dyna.bgActors[bgId].curTransform.rot.x, + colCtx->dyna.bgActors[bgId].curTransform.rot.y, colCtx->dyna.bgActors[bgId].curTransform.rot.z, + colCtx->dyna.bgActors[bgId].curTransform.pos.x, colCtx->dyna.bgActors[bgId].curTransform.pos.y, + colCtx->dyna.bgActors[bgId].curTransform.pos.z); SkinMatrix_Vec3fMtxFMultXYZ(&prevMatrixInv, &actor->world.pos, &posWithInv); SkinMatrix_Vec3fMtxFMultXYZ(&currMatrix, &posWithInv, &newPos); @@ -35,14 +35,14 @@ void BgCheck2_UpdateActorPosition(CollisionContext* colCtx, s32 index, Actor* ac actor->world.pos = newPos; } -void BgCheck2_UpdateActorYRotation(CollisionContext* colCtx, s32 index, Actor* actor) { +void BgCheck2_UpdateActorYRotation(CollisionContext* colCtx, s32 bgId, Actor* actor) { s16 angleChange; - if (BgCheck_IsActorMeshIndexValid(index) == 0) { + if (!DynaPoly_IsBgIdBgActor(bgId)) { return; } - angleChange = colCtx->dyna.bgActors[index].curTransform.rot.y - colCtx->dyna.bgActors[index].prevTransform.rot.y; + angleChange = colCtx->dyna.bgActors[bgId].curTransform.rot.y - colCtx->dyna.bgActors[bgId].prevTransform.rot.y; if (actor->id == 0) { ((Player*)actor)->currentYaw += angleChange; @@ -52,51 +52,51 @@ void BgCheck2_UpdateActorYRotation(CollisionContext* colCtx, s32 index, Actor* a actor->world.rot.y += angleChange; } -void BgCheck2_AttachToMesh(CollisionContext* colCtx, Actor* actor, s32 index) { +void BgCheck2_AttachToMesh(CollisionContext* colCtx, Actor* actor, s32 bgId) { DynaPolyActor* meshActor; - if (BgCheck_IsActorMeshIndexValid(index) == 0) { + if (!DynaPoly_IsBgIdBgActor(bgId)) { return; } - meshActor = BgCheck_GetActorOfMesh(colCtx, index); + meshActor = DynaPoly_GetActor(colCtx, bgId); if (meshActor != NULL) { - func_800CAE88(meshActor); + DynaPolyActor_SetRidingFallingState(meshActor); if ((actor->flags & 0x4000000) == 0x4000000) { - func_800CAF24(meshActor); + DynaPolyActor_SetSwitchPressedState(meshActor); } if ((actor->flags & 0x20000) == 0x20000) { - func_800CAF38(meshActor); + DynaPolyActor_SetHeavySwitchPressedState(meshActor); } } } -u32 BgCheck2_UpdateActorAttachedToMesh(CollisionContext* colCtx, s32 index, Actor* actor) { +u32 BgCheck2_UpdateActorAttachedToMesh(CollisionContext* colCtx, s32 bgId, Actor* actor) { u32 wasUpdated = 0; DynaPolyActor* meshActor; - if (BgCheck_IsActorMeshIndexValid(index) == 0) { + if (!DynaPoly_IsBgIdBgActor(bgId)) { return 0; } - if (((colCtx->dyna.bgActorFlags[index] & 2) != 0) || ((colCtx->dyna.bgActorFlags[index] & 1) == 0)) { + if (colCtx->dyna.bgActorFlags[bgId] & 2 || !(colCtx->dyna.bgActorFlags[bgId] & 1)) { return 0; } - meshActor = BgCheck_GetActorOfMesh(colCtx, index); + meshActor = DynaPoly_GetActor(colCtx, bgId); if (meshActor == NULL) { return 0; } - if ((meshActor->unk154 & 1) != 0) { - BgCheck2_UpdateActorPosition(colCtx, index, actor); + if (meshActor->flags & 1) { + BgCheck2_UpdateActorPosition(colCtx, bgId, actor); wasUpdated = 1; } - if ((meshActor->unk154 & 2) != 0) { - BgCheck2_UpdateActorYRotation(colCtx, index, actor); + if (meshActor->flags & 2) { + BgCheck2_UpdateActorYRotation(colCtx, bgId, actor); wasUpdated = 1; } diff --git a/src/code/z_bg_item.c b/src/code/z_bg_item.c index 77cc014b4..74adbe695 100644 --- a/src/code/z_bg_item.c +++ b/src/code/z_bg_item.c @@ -1,99 +1,141 @@ #include "global.h" -void BcCheck3_BgActorInit(DynaPolyActor* actor, UNK_TYPE4 param_2) { - actor->bgId = -1; - actor->unk148 = 0; - actor->unk14C = 0; - actor->unk154 = param_2; - actor->unk_158 = 0; +#define DYNAPOLY_STATE_NONE 0 +#define DYNAPOLY_STATE_RIDING_FALLING (1 << 0) +#define DYNAPOLY_STATE_RIDING_MOVING (1 << 1) +#define DYNAPOLY_STATE_RIDING_ROTATING (1 << 2) +#define DYNAPOLY_STATE_SWITCH_PRESSED (1 << 3) +#define DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED (1 << 4) + +void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 flags) { + dynaActor->bgId = -1; + dynaActor->pushForce = 0.0f; + dynaActor->unk14C = 0.0f; + dynaActor->flags = flags; + dynaActor->stateFlags = DYNAPOLY_STATE_NONE; } -void BgCheck3_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* actor, CollisionHeader* meshHeader) { - CollisionHeader* header; +void DynaPolyActor_LoadMesh(GlobalContext* globalCtx, DynaPolyActor* dynaActor, CollisionHeader* meshHeader) { + CollisionHeader* header = NULL; - header = NULL; - BgCheck_RelocateMeshHeader(meshHeader, &header); - actor->bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, actor, header); + CollisionHeader_GetVirtual(meshHeader, &header); + dynaActor->bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &dynaActor->actor, header); } -void BgCheck3_ResetFlags(DynaPolyActor* actor) { - actor->unk_158 = 0; +void DynaPolyActor_ResetState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags = DYNAPOLY_STATE_NONE; } -void func_800CAE88(DynaPolyActor* actor) { - actor->unk_158 |= 1; +void DynaPolyActor_SetRidingFallingState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_FALLING; } -void func_800CAE9C(DynaPolyActor* actor) { - actor->unk_158 |= 2; +void DynaPolyActor_SetRidingMovingState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_MOVING; } -void func_800CAEB0(CollisionContext* colCtx, s32 index) { - DynaPolyActor* actor; +void DynaPolyActor_SetRidingMovingStateByIndex(CollisionContext* colCtx, s32 bgId) { + DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, bgId); - actor = BgCheck_GetActorOfMesh(colCtx, index); - if (actor != (DynaPolyActor*)0x0) { - func_800CAE9C(actor); + if (dynaActor != NULL) { + DynaPolyActor_SetRidingMovingState(dynaActor); } } -void func_800CAEE0(DynaPolyActor* actor) { - actor->unk_158 |= 4; +void DynaPolyActor_SetRidingRotatingState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags |= DYNAPOLY_STATE_RIDING_ROTATING; } -void func_800CAEF4(CollisionContext* colCtx, s32 index) { - DynaPolyActor* actor; +void DynaPolyActor_SetRidingRotatingStateByIndex(CollisionContext* colCtx, s32 bgId) { + DynaPolyActor* dynaActor = DynaPoly_GetActor(colCtx, bgId); - actor = BgCheck_GetActorOfMesh(colCtx, index); - if (actor != (DynaPolyActor*)0x0) { - func_800CAEE0(actor); + if (dynaActor != NULL) { + DynaPolyActor_SetRidingRotatingState(dynaActor); } } -void func_800CAF24(DynaPolyActor* actor) { - actor->unk_158 |= 8; +void DynaPolyActor_SetSwitchPressedState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags |= DYNAPOLY_STATE_SWITCH_PRESSED; } -void func_800CAF38(DynaPolyActor* actor) { - actor->unk_158 |= 0x10; +void DynaPolyActor_SetHeavySwitchPressedState(DynaPolyActor* dynaActor) { + dynaActor->stateFlags |= DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED; } -s32 func_800CAF4C(DynaPolyActor* actor) { - if (actor->unk_158 & 1) { - return 1; +s32 DynaPolyActor_IsInRidingFallingState(DynaPolyActor* dynaActor) { + if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_FALLING) { + return true; } else { - return 0; + return false; } } -s32 func_800CAF70(DynaPolyActor* actor) { - if (actor->unk_158 & 2) { - return 1; +s32 DynaPolyActor_IsInRidingMovingState(DynaPolyActor* dynaActor) { + if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_MOVING) { + return true; } else { - return 0; + return false; } } -s32 func_800CAF94(DynaPolyActor* actor) { - if (actor->unk_158 & 4) { - return 1; +s32 DynaPolyActor_IsInRidingRotatingState(DynaPolyActor* dynaActor) { + if (dynaActor->stateFlags & DYNAPOLY_STATE_RIDING_ROTATING) { + return true; } else { - return 0; + return false; } } -s32 func_800CAFB8(DynaPolyActor* actor) { - if (actor->unk_158 & 8) { - return 1; +s32 DynaPolyActor_IsInSwitchPressedState(DynaPolyActor* dynaActor) { + if (dynaActor->stateFlags & DYNAPOLY_STATE_SWITCH_PRESSED) { + return true; } else { - return 0; + return false; } } -s32 func_800CAFDC(DynaPolyActor* actor) { - if (actor->unk_158 & 0x10) { - return 1; +s32 DynaPolyActor_IsInHeavySwitchPressedState(DynaPolyActor* dynaActor) { + if (dynaActor->stateFlags & DYNAPOLY_STATE_HEAVY_SWITCH_PRESSED) { + return true; } else { - return 0; + return false; } } + +s32 DynaPolyActor_ValidateMove(GlobalContext* globalCtx, DynaPolyActor* dynaActor, s16 startRadius, s16 endRadius, + s16 startHeight) { + Vec3f startPos; + Vec3f endPos; + Vec3f intersectionPos; + f32 sin = Math_SinS(dynaActor->yRotation); + f32 cos = Math_CosS(dynaActor->yRotation); + s32 bgId; + CollisionPoly* poly; + f32 adjustedStartRadius; + f32 adjustedEndRadius; + f32 sign = (0.0f <= dynaActor->pushForce) ? 1.0f : -1.0f; + + adjustedStartRadius = (f32)startRadius - 0.1f; + startPos.x = dynaActor->actor.world.pos.x + (adjustedStartRadius * cos); + startPos.y = dynaActor->actor.world.pos.y + startHeight; + startPos.z = dynaActor->actor.world.pos.z - (adjustedStartRadius * sin); + + adjustedEndRadius = (f32)endRadius - 0.1f; + endPos.x = sign * adjustedEndRadius * sin + startPos.x; + endPos.y = startPos.y; + endPos.z = sign * adjustedEndRadius * cos + startPos.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &startPos, &endPos, &intersectionPos, &poly, true, false, false, + true, &bgId, &dynaActor->actor, 0.0f)) { + return false; + } + startPos.x = (dynaActor->actor.world.pos.x * 2.0f) - startPos.x; + startPos.z = (dynaActor->actor.world.pos.z * 2.0f) - startPos.z; + endPos.x = sign * adjustedEndRadius * sin + startPos.x; + endPos.z = sign * adjustedEndRadius * cos + startPos.z; + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &startPos, &endPos, &intersectionPos, &poly, true, false, false, + true, &bgId, &dynaActor->actor, 0.0f)) { + return false; + } + return true; +} diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index e607b978a..0667bd84b 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -1,432 +1,4684 @@ #include "global.h" +#include "vt.h" -void BgCheck_PolygonLinkedListNodeInit(SSNode* node, s16* polyIndex, u16 next) { +#define DYNA_RAYCAST_FLOORS 1 +#define DYNA_RAYCAST_WALLS 2 +#define DYNA_RAYCAST_CEILINGS 4 + +u32 sWallFlags[32] = { + 0, 1, 3, 5, 8, 16, 32, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +u16 sSurfaceTypeSfx[] = { + /* 0x00 */ NA_SE_PL_WALK_GROUND - SFX_FLAG, + /* 0x01 */ NA_SE_PL_WALK_SAND - SFX_FLAG, + /* 0x02 */ NA_SE_PL_WALK_CONCRETE - SFX_FLAG, + /* 0x03 */ NA_SE_PL_WALK_DIRT - SFX_FLAG, + /* 0x04 */ NA_SE_PL_WALK_WATER0 - SFX_FLAG, + /* 0x05 */ NA_SE_PL_WALK_WATER1 - SFX_FLAG, + /* 0x06 */ NA_SE_PL_WALK_WATER2 - SFX_FLAG, + /* 0x07 */ NA_SE_PL_WALK_MAGMA - SFX_FLAG, + /* 0x08 */ NA_SE_PL_WALK_GRASS - SFX_FLAG, + /* 0x09 */ NA_SE_PL_WALK_GLASS - SFX_FLAG, + /* 0x0A */ NA_SE_PL_WALK_LADDER - SFX_FLAG, + /* 0x0B */ NA_SE_PL_WALK_GROUND - SFX_FLAG, + /* 0x0C */ NA_SE_PL_WALK_ICE - SFX_FLAG, + /* 0x0D */ NA_SE_PL_WALK_IRON - SFX_FLAG, + /* 0x0E */ NA_SE_PL_WALK_SNOW - SFX_FLAG +}; + +u8 D_801B46C0[] = { + /* 0x00 */ 1, + /* 0x01 */ 1, + /* 0x02 */ 0, + /* 0x03 */ 1, + /* 0x04 */ 0, + /* 0x05 */ 0, + /* 0x06 */ 0, + /* 0x07 */ 0, + /* 0x08 */ 0, + /* 0x09 */ 0, + /* 0x0A */ 0, + /* 0x0B */ 0, + /* 0x0C */ 0, + /* 0x0D */ 0, + /* 0x0E */ 1 +}; + +s16 sSmallMemScenes[] = { + SCENE_F01, +}; + +typedef struct { + s16 sceneId; + u32 memSize; +} BgCheckSceneMemEntry; + +BgCheckSceneMemEntry sSceneMemList[] = { + { SCENE_00KEIKOKU, 0xC800 }, +}; + +BgCheckSceneSubdivisionEntry sSceneSubdivisionList[] = { + { SCENE_00KEIKOKU, { 36, 1, 36 }, -1 }, + { SCENE_30GYOSON, { 40, 1, 40 }, -1 }, + { SCENE_31MISAKI, { 40, 1, 40 }, -1 }, +}; + +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 +MtxF D_801EDA40; +Vec3f D_801EDA80[3]; // polyVerts +char D_801EDAA8[80]; +char D_801EDAF8[80]; +Vec3f D_801EDB48[3]; // polyVerts +Vec3f D_801EDB70[3]; +Plane D_801EDB98; + +void BgCheck_GetStaticLookupIndicesFromPos(CollisionContext* colCtx, Vec3f* pos, Vec3i* sector); +f32 BgCheck_RaycastFloorDyna(DynaRaycast* dynaRaycast); +s32 BgCheck_SphVsDynaWall(CollisionContext* colCtx, u16 xpFlags, f32* outX, f32* outZ, Vec3f* pos, f32 radius, + CollisionPoly** outPoly, s32* outBgId, Actor* actor); +s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2, Vec3f* posA, Vec3f* posB, + Vec3f* posResult, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkDist, + u32 bccFlags); +s32 BgCheck_CheckDynaCeiling(CollisionContext* colCtx, u16 xpFlags, f32* outY, Vec3f* pos, f32 checkDist, + CollisionPoly** outPoly, s32* outBgId, Actor* actor); +s32 BgCheck_CheckLineAgainstDyna(CollisionContext* colCtx, u16 xpFlags, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, f32* distSq, s32* outBgId, Actor* actor, f32 checkDist, + s32 bccFlags); +s32 BgCheck_SphVsFirstDynaPoly(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, s32* outBgId, + Vec3f* center, f32 radius, Actor* actor, u16 bciFlags); +void BgCheck_ResetPolyCheckTbl(SSNodeList* nodeList, s32 numPolys); +s32 BgCheck_PosInStaticBoundingBox(CollisionContext* colCtx, Vec3f* pos); + +void SSNode_SetValue(SSNode* node, s16* polyIndex, u16 next) { node->polyId = *polyIndex; node->next = next; } -void BgCheck_PolygonLinkedListResetHead(u16* head) { - *head = 0xFFFF; +void SSList_SetNull(SSList* ssList) { + ssList->head = SS_NULL; } -void BgCheck_ScenePolygonListsNodeInsert(SSNodeList* list, u16* head, s16* polyIndex) { +void SSNodeList_SetSSListHead(SSNodeList* list, SSList* ssList, s16* polyIndex) { u16 index; - index = BgCheck_ScenePolygonListsReserveNode(list); - BgCheck_PolygonLinkedListNodeInit(&list->tbl[index], polyIndex, *head); - *head = index; + index = SSNodeList_GetNextNodeIdx(list); + SSNode_SetValue(&list->tbl[index], polyIndex, ssList->head); + ssList->head = index; } -void BgCheck_PolygonLinkedListNodeInsert(DynaSSNodeList* list, u16* head, s16* polyIndex) { +void DynaSSNodeList_SetSSListHead(DynaSSNodeList* list, SSList* ssList, s16* polyIndex) { u16 index; - index = BgCheck_AllocPolygonLinkedListNode(list); - BgCheck_PolygonLinkedListNodeInit(&list->tbl[index], polyIndex, *head); - *head = index; + index = DynaSSNodeList_GetNextNodeIdx(list); + SSNode_SetValue(&list->tbl[index], polyIndex, ssList->head); + ssList->head = index; } -void BgCheck_PolygonLinkedListInit(GlobalContext* globalCtx, DynaSSNodeList* list) { +void DynaSSNodeList_Init(GlobalContext* globalCtx, DynaSSNodeList* list) { list->tbl = NULL; list->count = 0; } -void BgCheck_PolygonLinkedListAlloc(GlobalContext* globalCtx, DynaSSNodeList* list, u32 numNodes) { - list->tbl = (SSNode*)THA_AllocEndAlign(&globalCtx->state.heap, numNodes << 2, 0xfffffffe); - list->max = numNodes; +void DynaSSNodeList_Alloc(GlobalContext* globalCtx, DynaSSNodeList* list, u32 numNodes) { + list->tbl = (SSNode*)THA_AllocEndAlign(&globalCtx->state.heap, numNodes * sizeof(SSNode), -2); + list->maxNodes = numNodes; list->count = 0; } -void BgCheck_PolygonLinkedListReset(DynaSSNodeList* list) { +void DynaSSNodeList_ResetCount(DynaSSNodeList* list) { list->count = 0; } -u16 BgCheck_AllocPolygonLinkedListNode(DynaSSNodeList* list) { - u16 index; +u16 DynaSSNodeList_GetNextNodeIdx(DynaSSNodeList* list) { + u16 index = list->count++; - index = list->count++; - if (list->max <= index) { - return 0xffff; + if (list->maxNodes <= index) { + return SS_NULL; } return index; } -void BgCheck_CreateVec3fFromVertex(Vec3s* vertex, Vec3f* vector) { - vector->x = vertex->x; - vector->y = vertex->y; - vector->z = vertex->z; +void BgCheck_Vec3sToVec3f(Vec3s* src, Vec3f* dest) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; } -void BgCheck_CreateVertexFromVec3f(Vec3s* vertex, Vec3f* vector) { - vertex->x = vector->x; - vertex->y = vector->y; - vertex->z = vector->z; +void BgCheck_Vec3fToVec3s(Vec3s* dest, Vec3f* src) { + dest->x = src->x; + dest->y = src->y; + dest->z = src->z; } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800BFD84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800BFDEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetMinY.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetNormal.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C0094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C01B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CreateTriNormFromPolygon.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C02C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C0340.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C0474.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C0668.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C06A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C074C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C07F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_PolygonCollidesWithSphere.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsertSorted.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsert.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C0E74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C10FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C1238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C12A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C1B68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C1D7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C2008.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C20F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C2310.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C2460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C2514.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C25E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinSubdivisions.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMaxSubdivisions.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinMaxSubdivisions.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C2BE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_SplitScenePolygonsIntoSubdivisions.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetIsDefaultSpecialScene.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxMemory.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CalcSubdivisionSize.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxObjects.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3C00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3C14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetActorMeshHeader.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3C94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3F40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C3FA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C40B4.s") - -f32 func_800C411C(CollisionContext* colCtx, CollisionPoly** arg1, s32* arg2, Actor* actor, Vec3f* pos) { - return func_800C3D50(0, colCtx, 2, arg1, arg2, pos, actor, 28, 1.0f, 0); +f32 func_800BFD84(CollisionPoly* poly, f32 arg1, f32 arg2) { + return (COLPOLY_GET_NORMAL(poly->normal.x * arg1 + poly->normal.z * arg2) + poly->dist) / + COLPOLY_GET_NORMAL(-poly->normal.y); } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4188.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C41E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4240.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C42A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4314.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C43CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4488.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C44F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C455C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C45C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4C74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4CD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4D3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4E10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4F38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4F84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C4FD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5464.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C54AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5538.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C55C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5650.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C56E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C576C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C57F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C583C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C58C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5954.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5A20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5A64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsAlloc.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C5B80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsReserveNode.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshParamsInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_SetActorMeshParams.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_AreActorMeshParamsEqual.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsHeadsInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshVerticesIndexInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshWaterboxesIndexInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInitFromActor.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_HasActorMeshChanged.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsAlloc.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_VerticesInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_VerticesListAlloc.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListAlloc.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshUpdateParams.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_IsActorMeshIndexValid.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_DynaInit.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_DynaAlloc.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMesh.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetActorOfMesh.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C62BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C6314.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C636C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C63C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C641C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C6474.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RemoveActorMesh.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C6554.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CalcWaterboxDimensions.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMeshToLists.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_ResetFlagsIfLoadedActor.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C756C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_UpdateAllActorMeshes.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C76EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C7974.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C7E40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C8580.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C87D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C8A60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C8BD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C8DC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C8EEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C90AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C921C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9380.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeaderPointers.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeader.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RelocateAllMeshHeaders.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9640.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_GetPolygonAttributes.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9704.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9728.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C97F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9844.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C98CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9924.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C99AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C99D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C99FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9A24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9A4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9A7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9AB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9AE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9B18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9B40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9B68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9B90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9BB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9BDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9C24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9C74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9C9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9CC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9CEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9D14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9D8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9DDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9E18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9E40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9E88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800C9EBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA1AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA1E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA22C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA568.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA634.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA648.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA6B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA6D8.s") - +/** + * Unused + */ +s32 func_800BFDEC(CollisionPoly* polyA, CollisionPoly* polyB, u32* outVtxId0, u32* outVtxId1) { + s32 vtxIdA[3]; + s32 vtxIdB[3]; + s32 i; + s32 j; + s32 count; + + *outVtxId0 = *outVtxId1 = 0; + for (i = 0; i < ARRAY_COUNT(vtxIdA); i++) { + vtxIdA[i] = COLPOLY_VTX_INDEX(polyA->vtxData[i]); + vtxIdB[i] = COLPOLY_VTX_INDEX(polyB->vtxData[i]); + } + + count = 0; + for (i = 0; i < 2; i++) { + for (j = i + 1; j < 3; j++) { + if (vtxIdA[i] == vtxIdB[j]) { + if (count == 0) { + *outVtxId0 = vtxIdA[i]; + } else if (count == 1) { + *outVtxId1 = vtxIdA[i]; + } + count++; + } + } + } + return count; +} + +s16 CollisionPoly_GetMinY(CollisionPoly* poly, Vec3s* vertices) { + s16 minY; + s32 a = COLPOLY_VTX_INDEX(poly->flags_vIA); + s32 b = COLPOLY_VTX_INDEX(poly->flags_vIB); + s32 c = poly->vIC; + + minY = vertices[a].y; + if (vertices[b].y < minY) { + minY = vertices[b].y; + } + if (minY < vertices[c].y) { + return minY; + } + return vertices[c].y; +} + +void CollisionPoly_GetNormalF(CollisionPoly* poly, f32* nx, f32* ny, f32* nz) { + *nx = COLPOLY_GET_NORMAL(poly->normal.x); + *ny = COLPOLY_GET_NORMAL(poly->normal.y); + *nz = COLPOLY_GET_NORMAL(poly->normal.z); +} + +/** + * Compute transform matrix mapping +y (up) to the collision poly's normal + */ +void func_800C0094(CollisionPoly* poly, f32 tx, f32 ty, f32 tz, MtxF* dest) { + f32 nx; + f32 ny; + f32 nz; + s32 pad; + f32 z_f14; + f32 phi_f14; + f32 phi_f12; + f32 inv_z_f14; + + if (poly == NULL) { + return; + } + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + + z_f14 = sqrtf(SQ(ny) + SQ(nz)); + if (!IS_ZERO(z_f14)) { + inv_z_f14 = 1.0f / z_f14; + phi_f14 = ny * inv_z_f14; + phi_f12 = nz * inv_z_f14; + } else { + phi_f14 = 1.0f; + phi_f12 = 0.0f; + } + dest->xx = z_f14; + dest->yx = (-nx) * phi_f14; + dest->zx = (-nx) * phi_f12; + dest->xy = nx; + dest->yy = ny; + dest->zy = nz; + dest->xz = 0.0f; + dest->yz = -phi_f12; + dest->zz = phi_f14; + dest->xw = tx; + dest->yw = ty; + dest->zw = tz; + dest->wx = 0.0f; + dest->wy = 0.0f; + dest->wz = 0.0f; + dest->ww = 1.0f; +} + +f32 CollisionPoly_GetPointDistanceFromPlane(CollisionPoly* poly, Vec3f* point) { + return COLPOLY_GET_NORMAL(poly->normal.x * point->x + poly->normal.y * point->y + poly->normal.z * point->z) + + poly->dist; +} + +void CollisionPoly_GetVertices(CollisionPoly* poly, Vec3s* vtxList, Vec3f* dest) { + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)], &dest[0]); + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)], &dest[1]); + BgCheck_Vec3sToVec3f(&vtxList[poly->vIC], &dest[2]); +} + +void CollisionPoly_GetVerticesByBgId(CollisionPoly* poly, s32 bgId, CollisionContext* colCtx, Vec3f* dest) { + Vec3s* vtxList; + + if (poly == NULL || bgId > BG_ACTOR_MAX || dest == NULL) { + if (dest != NULL) { + // @bug: dest[2] x and y are not set to 0 + dest[0].x = dest[0].y = dest[0].z = dest[1].x = dest[1].y = dest[1].z = dest[2].z = 0.0f; + } + } else { + if (bgId == BGCHECK_SCENE) { + vtxList = colCtx->colHeader->vtxList; + } else { + vtxList = colCtx->dyna.vtxList; + } + CollisionPoly_GetVertices(poly, vtxList, dest); + } +} + +s32 CollisionPoly_CheckYIntersectApprox1(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect, + f32 checkDist) { + f32 nx; + f32 ny; + f32 nz; + Vec3s* vA; + Vec3s* vB; + Vec3s* vC; + + vA = &vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)]; + Math_Vec3s_ToVec3f(&D_801ED9F0[0], vA); + vB = &vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)]; + Math_Vec3s_ToVec3f(&D_801ED9F0[1], vB); + vC = &vtxList[poly->vIC]; + Math_Vec3s_ToVec3f(&D_801ED9F0[2], vC); + + nx = COLPOLY_GET_NORMAL(poly->normal.x); + ny = COLPOLY_GET_NORMAL(poly->normal.y); + nz = COLPOLY_GET_NORMAL(poly->normal.z); + + return Math3D_TriChkPointParaYIntersectDist(&D_801ED9F0[0], &D_801ED9F0[1], &D_801ED9F0[2], nx, ny, nz, poly->dist, + z, x, yIntersect, checkDist); +} + +/** + * Checks if point (`x`,`z`) is within `checkDist` of `poly`, computing `yIntersect` if true + * Determinant max 0.0f (checks if on or within poly) + */ +s32 CollisionPoly_CheckYIntersect(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect, f32 checkDist) { + Vec3s* sVerts; + f32 nx; + f32 ny; + f32 nz; + + sVerts = &vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)]; + 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)]; + 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(&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(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], nx, ny, nz, + poly->dist, z, x, yIntersect, checkDist); +} + +s32 CollisionPoly_CheckYIntersectApprox2(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect) { + return CollisionPoly_CheckYIntersectApprox1(poly, vtxList, x, z, yIntersect, 1.0f); +} + +s32 CollisionPoly_CheckXIntersectApprox(CollisionPoly* poly, Vec3s* vtxList, f32 y, f32 z, f32* xIntersect) { + f32 nx; + f32 ny; + f32 nz; + + CollisionPoly_GetVertices(poly, vtxList, D_801EDA80); + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + return Math3D_TriChkPointParaXIntersect(&D_801EDA80[0], &D_801EDA80[1], &D_801EDA80[2], nx, ny, nz, poly->dist, y, + z, xIntersect); +} + +s32 CollisionPoly_CheckZIntersectApprox(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 y, f32* zIntersect) { + f32 nx; + f32 ny; + f32 nz; + + CollisionPoly_GetVertices(poly, vtxList, D_801EDB48); + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + return Math3D_TriChkPointParaZIntersect(&D_801EDB48[0], &D_801EDB48[1], &D_801EDB48[2], nx, ny, nz, poly->dist, x, + y, zIntersect); +} + +#ifdef NON_MATCHING +s32 CollisionPoly_LineVsPoly(BgLineVsPolyTest* a0) { + static Vec3f polyVerts[3]; // D_801EDB70 + static Plane plane; // D_801EDB98 + f32 planeDistA; + f32 planeDistB; + f32 planeDistDelta; + + plane.originDist = a0->poly->dist; + planeDistA = COLPOLY_GET_NORMAL(a0->poly->normal.x * a0->posA->x + a0->poly->normal.y * a0->posA->y + + a0->poly->normal.z * a0->posA->z) + + plane.originDist; + planeDistB = COLPOLY_GET_NORMAL(a0->poly->normal.x * a0->posB->x + a0->poly->normal.y * a0->posB->y + + a0->poly->normal.z * a0->posB->z) + + plane.originDist; + + planeDistDelta = planeDistA - planeDistB; + if ((planeDistA >= 0.0f && planeDistB >= 0.0f) || (planeDistA < 0.0f && planeDistB < 0.0f) || + ((a0->checkOneFace != 0) && (planeDistA < 0.0f && planeDistB > 0.0f)) || IS_ZERO(planeDistDelta)) { + return false; + } + + CollisionPoly_GetNormalF(a0->poly, &plane.normal.x, &plane.normal.y, &plane.normal.z); + CollisionPoly_GetVertices(a0->poly, a0->vtxList, polyVerts); + Math3D_Lerp(a0->posA, a0->posB, planeDistA / planeDistDelta, a0->planeIntersect); + + if ((fabsf(plane.normal.x) > 0.5f && + Math3D_TriChkPointParaXDist(&polyVerts[0], &polyVerts[1], &polyVerts[2], a0->planeIntersect->y, + a0->planeIntersect->z, 0.0f, a0->checkDist, plane.normal.x)) || + (fabsf(plane.normal.y) > 0.5f && + Math3D_TriChkPointParaYDist(&polyVerts[0], &polyVerts[1], &polyVerts[2], a0->planeIntersect->z, + a0->planeIntersect->x, 0.0f, a0->checkDist, plane.normal.y)) || + (fabsf(plane.normal.z) > 0.5f && + Math3D_TriChkLineSegParaZDist(&polyVerts[0], &polyVerts[1], &polyVerts[2], a0->planeIntersect->x, + a0->planeIntersect->y, 0.0f, a0->checkDist, plane.normal.z))) { + return true; + } + return false; +} +#else +s32 CollisionPoly_LineVsPoly(BgLineVsPolyTest* a0); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/CollisionPoly_LineVsPoly.s") +#endif + +s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center, f32 radius) { + static Sphere16 sphere; // D_801EDBA8 + static TriNorm tri; // D_801EDBB0 + Vec3f intersect; + + CollisionPoly_GetVertices(poly, vtxList, tri.vtx); + CollisionPoly_GetNormalF(poly, &tri.plane.normal.x, &tri.plane.normal.y, &tri.plane.normal.z); + tri.plane.originDist = poly->dist; + sphere.center.x = center->x; + sphere.center.y = center->y; + sphere.center.z = center->z; + sphere.radius = radius; + return Math3D_ColSphereTri(&sphere, &tri, &intersect); +} + +/** + * Add poly to StaticLookup table + * Table is sorted by poly's smallest y vertex component + * `ssList` is the list to append a new poly to + * `polyList` is the CollisionPoly lookup list + * `vtxList` is the vertex lookup list + * `polyId` is the index of the poly in polyList to insert into the lookup table + */ +void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, CollisionPoly* polyList, Vec3s* vtxList, + s16 polyId) { + SSNode* curNode; + SSNode* nextNode; + s32 polyYMin; + u16 newNodeId; + s16 curPolyId; + + // if list is null + if (ssList->head == SS_NULL) { + SSNodeList_SetSSListHead(&colCtx->polyNodes, ssList, &polyId); + return; + } + + polyYMin = CollisionPoly_GetMinY(&polyList[polyId], vtxList); + + curNode = &colCtx->polyNodes.tbl[ssList->head]; + curPolyId = curNode->polyId; + + // if the poly being inserted has a lower y than the first poly + if (polyYMin < vtxList[COLPOLY_VTX_INDEX(polyList[curPolyId].flags_vIA)].y && + polyYMin < vtxList[COLPOLY_VTX_INDEX(polyList[curPolyId].flags_vIB)].y && + polyYMin < vtxList[polyList[curPolyId].vIC].y) { + SSNodeList_SetSSListHead(&colCtx->polyNodes, ssList, &polyId); + return; + } + 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; + break; + } + + nextNode = &colCtx->polyNodes.tbl[curNode->next]; + curPolyId = nextNode->polyId; + + // if the poly being inserted is lower than the next poly + if (polyYMin < vtxList[COLPOLY_VTX_INDEX(polyList[curPolyId].flags_vIA)].y && + polyYMin < vtxList[COLPOLY_VTX_INDEX(polyList[curPolyId].flags_vIB)].y && + polyYMin < vtxList[polyList[curPolyId].vIC].y) { + newNodeId = SSNodeList_GetNextNodeIdx(&colCtx->polyNodes); + SSNode_SetValue(&colCtx->polyNodes.tbl[newNodeId], &polyId, curNode->next); + curNode->next = newNodeId; + break; + } + curNode = nextNode; + } +} + +/** + * Add CollisionPoly to StaticLookup list + */ +void StaticLookup_AddPoly(StaticLookup* lookup, CollisionContext* colCtx, CollisionPoly* polyList, Vec3s* vtxList, + s16 index) { + if (polyList[index].normal.y > COLPOLY_SNORMAL(0.5f)) { + StaticLookup_AddPolyToSSList(colCtx, &lookup->floor, polyList, vtxList, index); + } else if (polyList[index].normal.y < COLPOLY_SNORMAL(-0.8f)) { + StaticLookup_AddPolyToSSList(colCtx, &lookup->ceiling, polyList, vtxList, index); + } else { + StaticLookup_AddPolyToSSList(colCtx, &lookup->wall, polyList, vtxList, index); + } +} + +/** + * Locates the closest static poly directly underneath `pos`, starting at list `ssList` + * returns yIntersect of the closest poly, or `yIntersectMin` + * stores the pointer of the closest poly to `outPoly` + * if (flags & 1), ignore polys with a normal.y < 0 (from vertical walls to ceilings) + */ +f32 BgCheck_RaycastFloorStaticList(CollisionContext* colCtx, u16 xpFlags, SSList* ssList, CollisionPoly** outPoly, + Vec3f* pos, f32 yIntersectMin, f32 checkDist, s32 flags, Actor* actor, s32 arg9) { + SSNode* curNode; + s32 polyId; + f32 result; + f32 yIntersect; + CollisionPoly* colPoly; + s32 pad; + + result = yIntersectMin; + if (ssList->head == SS_NULL) { + return result; + } + + curNode = &colCtx->polyNodes.tbl[ssList->head]; + + while (true) { + polyId = curNode->polyId; + colPoly = &colCtx->colHeader->polyList[polyId]; + + if (((flags & 1) && (colPoly->normal.y < 0)) || + ((arg9 & 0x20) && ((colCtx->colHeader->surfaceTypeList[colPoly->type].data[0] >> 0x1E) & 1)) || + COLPOLY_VIA_FLAG_TEST(colPoly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(colPoly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + + if (pos->y < colCtx->colHeader->vtxList[COLPOLY_VTX_INDEX(colPoly->flags_vIA)].y && + pos->y < colCtx->colHeader->vtxList[COLPOLY_VTX_INDEX(colPoly->flags_vIB)].y && + pos->y < colCtx->colHeader->vtxList[colPoly->vIC].y) { + break; + } + + if (CollisionPoly_CheckYIntersect(colPoly, colCtx->colHeader->vtxList, pos->x, pos->z, &yIntersect, + checkDist)) { + // if poly is closer to pos without going over + if (yIntersect < pos->y && result < yIntersect) { + result = yIntersect; + *outPoly = colPoly; + } + } + + if (curNode->next == SS_NULL) { + break; + } + curNode = &colCtx->polyNodes.tbl[curNode->next]; + } + return result; +} + +/** + * Locates the closest static poly directly underneath `pos` within `lookup`. + * returns yIntersect of the closest poly, or `yIntersectMin` + * stores the pointer of the closest poly to `outPoly` + */ +f32 BgCheck_RaycastFloorStatic(StaticLookup* lookup, CollisionContext* colCtx, u16 xpFlags, CollisionPoly** poly, + Vec3f* pos, u32 arg5, f32 checkDist, f32 yIntersectMin, Actor* actor) { + s32 flag; // skip polys with normal.y < 0 + f32 yIntersect = yIntersectMin; + + if (arg5 & 4) { + yIntersect = BgCheck_RaycastFloorStaticList(colCtx, xpFlags, &lookup->floor, poly, pos, yIntersect, checkDist, + 0, actor, arg5); + } + + if ((arg5 & 2) || (arg5 & 8)) { + flag = 0; + if (arg5 & 0x10) { + flag = 1; + } + yIntersect = BgCheck_RaycastFloorStaticList(colCtx, xpFlags, &lookup->wall, poly, pos, yIntersect, checkDist, + flag, actor, arg5); + } + + if (arg5 & 1) { + flag = 0; + if (arg5 & 0x10) { + flag = 1; + } + yIntersect = BgCheck_RaycastFloorStaticList(colCtx, xpFlags, &lookup->ceiling, poly, pos, yIntersect, checkDist, + flag, actor, arg5); + } + + return yIntersect; +} + +/** + * Compute wall displacement on `posX` and `posZ` + * sets `wallPolyPtr` to `poly` if `wallPolyPtr` is NULL + * returns true if `wallPolyPtr` was changed + * `invXZlength` is 1 / sqrt( sq(poly.normal.x) + sq(poly.normal.z) ) + */ +s32 BgCheck_ComputeWallDisplacement(CollisionContext* colCtx, CollisionPoly* poly, f32* posX, f32* posZ, f32 nx, f32 ny, + f32 nz, f32 invXZlength, f32 planeDist, f32 radius, CollisionPoly** wallPolyPtr) { + f32 displacement = (radius - planeDist) * invXZlength; + + *posX += displacement * nx; + *posZ += displacement * nz; + + if (*wallPolyPtr == NULL) { + *wallPolyPtr = poly; + return true; + } else { + return false; + } +} + +/** + * Performs collision detection on static poly walls within `lookup` on sphere `pos`, `radius` + * returns true if a collision was detected + * `outX` `outZ` return the displaced x,z coordinates, + * `outPoly` returns the pointer to the nearest poly collided with, or NULL + */ +s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16 xpFlags, f32* outX, f32* outZ, + Vec3f* pos, f32 radius, CollisionPoly** outPoly, Actor* actor) { + Vec3f resultPos; + f32 zTemp; + f32 xTemp; + f32 planeDist; + f32 intersect; + s32 result; + CollisionPoly* curPoly; + CollisionPoly* polyList; + SSNode* curNode; + f32 invNormalXZ; + Vec3s* vtxA; + Vec3s* vtxB; + Vec3s* vtxC; + s32 polyId; + f32 normalXZ; + f32 nx; + f32 ny; + f32 nz; + Vec3s* vtxList; + u16 pad; + f32 temp_f16; + f32 zMin; + f32 zMax; + f32 xMin; + f32 xMax; + + result = false; + if (lookup->wall.head == SS_NULL) { + return result; + } + resultPos = *pos; + + polyList = colCtx->colHeader->polyList; + vtxList = colCtx->colHeader->vtxList; + curNode = &colCtx->polyNodes.tbl[lookup->wall.head]; + + while (true) { + polyId = curNode->polyId; + curPoly = &polyList[polyId]; + vtxA = &vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIA)]; + vtxB = &vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIB)]; + vtxC = &vtxList[curPoly->vIC]; + + if (pos->y < vtxA->y && pos->y < vtxB->y && pos->y < vtxC->y) { + break; + } + + nx = COLPOLY_GET_NORMAL(curPoly->normal.x); + ny = COLPOLY_GET_NORMAL(curPoly->normal.y); + nz = COLPOLY_GET_NORMAL(curPoly->normal.z); + normalXZ = sqrtf(SQ(nx) + SQ(nz)); + planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos); + if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + invNormalXZ = 1.0f / normalXZ; + temp_f16 = fabsf(nz) * invNormalXZ; + if (temp_f16 < 0.4f) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + // compute curPoly zMin/zMax + zTemp = vtxA->z; + zMax = zMin = zTemp; + zTemp = vtxB->z; + + if (zTemp < zMin) { + zMin = zTemp; + } else if (zMax < zTemp) { + zMax = zTemp; + } + zTemp = vtxC->z; + if (zTemp < zMin) { + zMin = zTemp; + } else if (zTemp > zMax) { + zMax = zTemp; + } + + zMin -= radius; + zMax += radius; + + if (resultPos.z < zMin || resultPos.z > zMax) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + if (CollisionPoly_CheckZIntersectApprox(curPoly, vtxList, resultPos.x, pos->y, &intersect)) { + f32 test = intersect - resultPos.z; + + if (fabsf(test) <= radius / temp_f16) { + if (test * nz <= 4.0f) { + if (BgCheck_ComputeWallDisplacement(colCtx, curPoly, &resultPos.x, &resultPos.z, nx, ny, nz, + invNormalXZ, planeDist, radius, outPoly)) { + result = true; + } + } + } + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + } + } + + curNode = &colCtx->polyNodes.tbl[lookup->wall.head]; + + while (true) { + polyId = curNode->polyId; + curPoly = &polyList[polyId]; + vtxA = &vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIA)]; + vtxB = &vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIB)]; + vtxC = &vtxList[curPoly->vIC]; + + if (pos->y < vtxA->y && pos->y < vtxB->y && pos->y < vtxC->y) { + break; + } + + nx = COLPOLY_GET_NORMAL(curPoly->normal.x); + ny = COLPOLY_GET_NORMAL(curPoly->normal.y); + nz = COLPOLY_GET_NORMAL(curPoly->normal.z); + normalXZ = sqrtf(SQ(nx) + SQ(nz)); + planeDist = Math3D_DistPlaneToPos(nx, ny, nz, curPoly->dist, &resultPos); + if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + invNormalXZ = 1.0f / normalXZ; + temp_f16 = fabsf(nx) * invNormalXZ; + if (temp_f16 < 0.4f) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + // compute curPoly xMin/xMax + xTemp = vtxA->x; + xMax = xMin = xTemp; + xTemp = vtxB->x; + + if (xTemp < xMin) { + xMin = xTemp; + } else if (xMax < xTemp) { + xMax = xTemp; + } + xTemp = vtxC->x; + if (xTemp < xMin) { + xMin = xTemp; + } else if (xMax < xTemp) { + xMax = xTemp; + } + + xMin -= radius; + xMax += radius; + + if (resultPos.x < xMin || xMax < resultPos.x) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + if (CollisionPoly_CheckXIntersectApprox(curPoly, vtxList, pos->y, resultPos.z, &intersect)) { + f32 test = intersect - resultPos.x; + + if (fabsf(test) <= radius / temp_f16) { + if (test * nx <= 4.0f) { + if (BgCheck_ComputeWallDisplacement(colCtx, curPoly, &resultPos.x, &resultPos.z, nx, ny, nz, + invNormalXZ, planeDist, radius, outPoly)) { + result = true; + } + } + } + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + *outX = resultPos.x; + *outZ = resultPos.z; + return result; +} + +/** + * Tests for collision with a static poly ceiling + * returns true if a collision occurs, else false + * `outPoly` returns the poly collided with + * `outY` returns the y coordinate needed to not collide with `outPoly` + */ +s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos, + f32 checkHeight, CollisionPoly** outPoly, Actor* actor) { + s32 result = false; + CollisionPoly* curPoly; + CollisionPoly* polyList; + s32 curPolyId; + f32 ceilingY; + SSNode* curNode; + Vec3s* vtxList; + + if (lookup->ceiling.head == SS_NULL) { + return result; + } + 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) || + (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIB, 4) && + ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + + if (CollisionPoly_CheckYIntersectApprox2(curPoly, vtxList, pos->x, pos->z, &ceilingY)) { + intersectDist = ceilingY - *outY; + ny = COLPOLY_GET_NORMAL(curPoly->normal.y); + + if (intersectDist > 0 && intersectDist < checkHeight && intersectDist * ny <= 0) { + *outY = ceilingY - checkHeight; + *outPoly = curPoly; + result = true; + } + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + return result; +} + +/** + * Tests if line `posA` to `posB` intersects with a static poly in list `ssList`. Uses polyCheckTbl + * returns true if such a poly exists, else false + * `outPoly` returns the pointer of the poly intersected + * `posB` and `outPos` returns the point of intersection with `outPoly` + * `outDistSq` returns the squared distance from `posA` to the point of intersect + */ +#ifdef NON_MATCHING +s32 BgCheck_CheckLineAgainstSSList(StaticLineTest* arg0) { + CollisionContext* colCtx; + s32 result; + Vec3f polyIntersect; // sp7C + SSNode* curNode; + u8* checkedPoly; + f32 minY; + f32 distSq; + BgLineVsPolyTest test; // sp50 + s16 polyId; + CollisionPoly* polyList; + + result = false; + if (arg0->ssList->head == SS_NULL) { + return result; + } + colCtx = arg0->colCtx; + curNode = &colCtx->polyNodes.tbl[arg0->ssList->head]; + polyList = colCtx->colHeader->polyList; + test.vtxList = colCtx->colHeader->vtxList; + test.posA = arg0->posA; + test.posB = arg0->posB; + test.planeIntersect = &polyIntersect; // reorder maybe + test.checkOneFace = (arg0->bccFlags & BGCHECK_CHECK_ONE_FACE) != 0; + test.checkDist = arg0->checkDist; + + while (true) { + polyId = curNode->polyId; + test.poly = &polyList[polyId]; + checkedPoly = &arg0->colCtx->polyNodes.polyCheckTbl[polyId]; + + if (*checkedPoly == true || + (arg0->xpFlags2 != 0 && !COLPOLY_VIA_FLAG_TEST(test.poly->flags_vIA, arg0->xpFlags2)) || + COLPOLY_VIA_FLAG_TEST(test.poly->flags_vIA, arg0->xpFlags1) || + (COLPOLY_VIA_FLAG_TEST(test.poly->flags_vIB, 4) && + ((arg0->actor != NULL && arg0->actor->category != ACTORCAT_PLAYER) || + (arg0->actor == NULL && arg0->xpFlags1 != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &colCtx->polyNodes.tbl[curNode->next]; + continue; + } + } + *checkedPoly = true; + minY = CollisionPoly_GetMinY(test.poly, test.vtxList); + if (test.posA->y < minY && test.posB->y < minY) { + break; + } + if (CollisionPoly_LineVsPoly(&test)) { + distSq = Math3D_Vec3fDistSq(test.posA, test.planeIntersect); + if (distSq < arg0->outDistSq) { + arg0->outDistSq = distSq; + *arg0->outPos = *test.planeIntersect; + *arg0->posB = *test.planeIntersect; + *arg0->outPoly = test.poly; + result = true; + } + } + if (curNode->next == SS_NULL) { + break; + } + curNode = &arg0->colCtx->polyNodes.tbl[curNode->next]; + } + return result; +} +#else +s32 BgCheck_CheckLineAgainstSSList(StaticLineTest* arg0); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CheckLineAgainstSSList.s") +#endif + +/** + * Tests if line `posA` to `posB` intersects with a static poly in `lookup`. Uses polyCheckTbl + * returns true if such a poly exists, else false + * `outPoly` returns the pointer of the poly intersected + * `posB` and `outPos` returns the point of intersection with `outPoly` + * `outDistSq` returns the squared distance from `posA` to the point of intersect + */ +s32 BgCheck_CheckLineInSubdivision(StaticLineTest* arg0) { + s32 result = false; + + if ((arg0->bccFlags & BGCHECK_CHECK_FLOOR) && arg0->lookup->floor.head != SS_NULL) { + arg0->ssList = &arg0->lookup->floor; + if (BgCheck_CheckLineAgainstSSList(arg0)) { + result = true; + } + } + + if ((arg0->bccFlags & BGCHECK_CHECK_WALL) && arg0->lookup->wall.head != SS_NULL) { + arg0->ssList = &arg0->lookup->wall; + if (BgCheck_CheckLineAgainstSSList(arg0)) { + result = true; + } + } + + if ((arg0->bccFlags & BGCHECK_CHECK_CEILING) && arg0->lookup->ceiling.head != SS_NULL) { + arg0->ssList = &arg0->lookup->ceiling; + if (BgCheck_CheckLineAgainstSSList(arg0)) { + result = true; + } + } + return result; +} + +/** + * Get first static poly intersecting sphere `center` `radius` from list `node` + * returns true if any poly intersects the sphere, else returns false + * `outPoly` returns the pointer of the first poly found that intersects + */ +s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext* colCtx, Vec3f* center, f32 radius, + CollisionPoly** outPoly, Actor* actor) { + Vec3s* vtxList; + CollisionPoly* polyList; + CollisionPoly* curPoly; + u16 nextId; + s16 curPolyId; + + polyList = colCtx->colHeader->polyList; + vtxList = colCtx->colHeader->vtxList; + + while (true) { + curPolyId = node->polyId; + curPoly = &polyList[curPolyId]; + if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIB, 4) && + ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (node->next != SS_NULL) { + node = &colCtx->polyNodes.tbl[node->next]; + continue; + } + break; + } + + if (center->y + radius < vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIA)].y && + center->y + radius < vtxList[COLPOLY_VTX_INDEX(curPoly->flags_vIB)].y && + center->y + radius < vtxList[curPoly->vIC].y) { + break; + } + + if (CollisionPoly_SphVsPoly(curPoly, vtxList, center, radius)) { + *outPoly = curPoly; + return true; + } + if (node->next != SS_NULL) { + node = &colCtx->polyNodes.tbl[node->next]; + { s32 pad; } + + continue; + } + break; + } + return false; +} + +/** + * Get first static poly intersecting sphere `center` `radius` within `lookup` + * returns true if any poly intersects the sphere, else false + * `outPoly` returns the first poly found that intersects + */ +s32 BgCheck_SphVsFirstStaticPoly(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, Vec3f* center, f32 radius, + CollisionPoly** outPoly, u16 bciFlags, Actor* actor) { + if (lookup->floor.head != SS_NULL && !(bciFlags & BGCHECK_IGNORE_FLOOR) && + BgCheck_SphVsFirstStaticPolyList(&colCtx->polyNodes.tbl[lookup->floor.head], xpFlags, colCtx, center, radius, + outPoly, actor)) { + return true; + } + + if (lookup->wall.head != SS_NULL && !(bciFlags & BGCHECK_IGNORE_WALL) && + BgCheck_SphVsFirstStaticPolyList(&colCtx->polyNodes.tbl[lookup->wall.head], xpFlags, colCtx, center, radius, + outPoly, actor)) { + return true; + } + + if (lookup->ceiling.head != SS_NULL && !(bciFlags & BGCHECK_IGNORE_CEILING) && + BgCheck_SphVsFirstStaticPolyList(&colCtx->polyNodes.tbl[lookup->ceiling.head], xpFlags, colCtx, center, radius, + outPoly, actor)) { + return true; + } + + return false; +} + +/** + * Get StaticLookup from `pos` + * Does not return NULL + */ +StaticLookup* BgCheck_GetNearestStaticLookup(CollisionContext* colCtx, StaticLookup* lookupTbl, Vec3f* pos) { + Vec3i sector; + s32 subdivAmountX; + + BgCheck_GetStaticLookupIndicesFromPos(colCtx, pos, §or); + subdivAmountX = colCtx->subdivAmount.x; + return (sector.z * subdivAmountX) * colCtx->subdivAmount.y + lookupTbl + sector.x + sector.y * subdivAmountX; +} + +/** + * Get StaticLookup from `pos` + * Returns NULL if just outside the mesh bounding box + */ +StaticLookup* BgCheck_GetStaticLookup(CollisionContext* colCtx, StaticLookup* lookupTbl, Vec3f* pos) { + Vec3i sector; + s32 subdivAmountX; + + if (!BgCheck_PosInStaticBoundingBox(colCtx, pos)) { + return NULL; + } + BgCheck_GetStaticLookupIndicesFromPos(colCtx, pos, §or); + subdivAmountX = colCtx->subdivAmount.x; + return (sector.z * subdivAmountX) * colCtx->subdivAmount.y + lookupTbl + sector.x + sector.y * subdivAmountX; +} + +/** + * Get StaticLookup subdivision indices from `pos` + * `sector` returns the subdivision x,y,z indices containing or is nearest to `pos` + */ +void BgCheck_GetStaticLookupIndicesFromPos(CollisionContext* colCtx, Vec3f* pos, Vec3i* sector) { + sector->x = (pos->x - colCtx->minBounds.x) * colCtx->subdivLengthInv.x; + sector->y = (pos->y - colCtx->minBounds.y) * colCtx->subdivLengthInv.y; + sector->z = (pos->z - colCtx->minBounds.z) * colCtx->subdivLengthInv.z; + + if (sector->x < 0) { + sector->x = 0; + } else if (sector->x >= colCtx->subdivAmount.x) { + sector->x = colCtx->subdivAmount.x - 1; + } + + if (sector->y < 0) { + sector->y = 0; + } else if (sector->y >= colCtx->subdivAmount.y) { + sector->y = colCtx->subdivAmount.y - 1; + } + + if (sector->z < 0) { + sector->z = 0; + } else if (sector->z >= colCtx->subdivAmount.z) { + sector->z = colCtx->subdivAmount.z - 1; + } +} + +/** + * Get negative bias subdivision indices + * decrements indices if `pos` is within BGCHECK_SUBDIV_OVERLAP units of the negative subdivision boundary + * `sx`, `sy`, `sz` returns the subdivision x, y, z indices + */ +void BgCheck_GetSubdivisionMinBounds(CollisionContext* colCtx, Vec3f* pos, s32* sx, s32* sy, s32* sz) { + f32 dx = pos->x - colCtx->minBounds.x; + f32 dy = pos->y - colCtx->minBounds.y; + f32 dz = pos->z - colCtx->minBounds.z; + + *sx = dx * colCtx->subdivLengthInv.x; + *sy = dy * colCtx->subdivLengthInv.y; + *sz = dz * colCtx->subdivLengthInv.z; + + if (((s32)dx % (s32)colCtx->subdivLength.x < BGCHECK_SUBDIV_OVERLAP) && (*sx > 0)) { + *sx -= 1; + } + + if (((s32)dy % (s32)colCtx->subdivLength.y < BGCHECK_SUBDIV_OVERLAP) && (*sy > 0)) { + *sy -= 1; + } + + if (((s32)dz % (s32)colCtx->subdivLength.z < BGCHECK_SUBDIV_OVERLAP) && (*sz > 0)) { + *sz -= 1; + } +} + +/** + * Get positive bias subdivision indices + * increments indicies if `pos` is within BGCHECK_SUBDIV_OVERLAP units of the postive subdivision boundary + * `sx`, `sy`, `sz` returns the subdivision x, y, z indices + */ +void BgCheck_GetSubdivisionMaxBounds(CollisionContext* colCtx, Vec3f* pos, s32* sx, s32* sy, s32* sz) { + f32 dx = pos->x - colCtx->minBounds.x; + f32 dy = pos->y - colCtx->minBounds.y; + f32 dz = pos->z - colCtx->minBounds.z; + + *sx = dx * colCtx->subdivLengthInv.x; + *sy = dy * colCtx->subdivLengthInv.y; + *sz = dz * colCtx->subdivLengthInv.z; + + if (((s32)colCtx->subdivLength.x - BGCHECK_SUBDIV_OVERLAP < (s32)dx % (s32)colCtx->subdivLength.x) && + (*sx < colCtx->subdivAmount.x - 1)) { + *sx += 1; + } + + if (((s32)colCtx->subdivLength.y - BGCHECK_SUBDIV_OVERLAP < (s32)dy % (s32)colCtx->subdivLength.y) && + (*sy < colCtx->subdivAmount.y - 1)) { + *sy += 1; + } + + if (((s32)colCtx->subdivLength.z - BGCHECK_SUBDIV_OVERLAP < (s32)dz % (s32)colCtx->subdivLength.z) && + (*sz < colCtx->subdivAmount.z - 1)) { + *sz += 1; + } +} + +/** + * Calculate the subdivision index bounding box for CollisionPoly `polyId` + * `subdivMinX`, `subdivMinY`, `subdivMinZ` returns the minimum subdivision x, y, z indices + * `subdivMaxX`, `subdivMaxY`, `subdivMaxZ` returns the maximum subdivision x, y, z indices + */ +void BgCheck_GetPolySubdivisionBounds(CollisionContext* colCtx, Vec3s* vtxList, CollisionPoly* polyList, + s32* subdivMinX, s32* subdivMinY, s32* subdivMinZ, s32* subdivMaxX, + s32* subdivMaxY, s32* subdivMaxZ, s16 polyId) { + u16* vtxDataTemp; + Vec3f minVtx; + Vec3f maxVtx; + + f32 x; + f32 y; + f32 z; + + Vec3s* vtx; + s16 vtxId = COLPOLY_VTX_INDEX(polyList[polyId].vtxData[0]); + + Math_Vec3s_ToVec3f(&maxVtx, &vtxList[vtxId]); + Math_Vec3f_Copy(&minVtx, &maxVtx); + + for (vtxDataTemp = polyList[polyId].vtxData + 1; vtxDataTemp < polyList[polyId].vtxData + 3; vtxDataTemp++) { + vtxId = COLPOLY_VTX_INDEX(*vtxDataTemp); + vtx = &vtxList[vtxId]; + x = vtx->x; + y = vtx->y; + z = vtx->z; + + if (minVtx.x > x) { + minVtx.x = x; + } else if (maxVtx.x < x) { + maxVtx.x = x; + } + + if (minVtx.y > y) { + minVtx.y = y; + } else if (maxVtx.y < y) { + maxVtx.y = y; + } + + if (minVtx.z > z) { + minVtx.z = z; + } else if (maxVtx.z < z) { + maxVtx.z = z; + } + } + BgCheck_GetSubdivisionMinBounds(colCtx, &minVtx, subdivMinX, subdivMinY, subdivMinZ); + BgCheck_GetSubdivisionMaxBounds(colCtx, &maxVtx, subdivMaxX, subdivMaxY, subdivMaxZ); +} + +/** + * Test if poly `polyList`[`polyId`] intersects cube `min` `max` + * returns true if the poly intersects the cube, else false + */ +s32 BgCheck_PolyIntersectsSubdivision(Vec3f* min, Vec3f* max, CollisionPoly* polyList, Vec3s* vtxList, s16 polyId) { + f32 intersect; + Vec3f va2; + Vec3f vb2; + Vec3f vc2; + CollisionPoly* poly; + f32 nx; + f32 ny; + f32 nz; + f32 dist; + Vec3f va; + Vec3f vb; + Vec3f vc; + s32 flags[3]; + + flags[0] = flags[1] = 0; + poly = &polyList[polyId]; + + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)], &va); + flags[0] = Math3D_PointRelativeToCubeFaces(&va, min, max); + if (flags[0] == 0) { + return true; + } + + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)], &vb); + flags[1] = Math3D_PointRelativeToCubeFaces(&vb, min, max); + if (flags[1] == 0) { + return true; + } + + BgCheck_Vec3sToVec3f(&vtxList[poly->vIC], &vc); + flags[2] = Math3D_PointRelativeToCubeFaces(&vc, min, max); + if (flags[2] == 0) { + return true; + } + + if (flags[0] & flags[1] & flags[2]) { + return false; + } + + flags[0] |= Math3D_PointRelativeToCubeEdges(&va, min, max) << 8; + flags[1] |= Math3D_PointRelativeToCubeEdges(&vb, min, max) << 8; + flags[2] |= Math3D_PointRelativeToCubeEdges(&vc, min, max) << 8; + if (flags[0] & flags[1] & flags[2]) { + return false; + } + + flags[0] |= Math3D_PointRelativeToCubeVertices(&va, min, max) << 0x18; + flags[1] |= Math3D_PointRelativeToCubeVertices(&vb, min, max) << 0x18; + flags[2] |= Math3D_PointRelativeToCubeVertices(&vc, min, max) << 0x18; + if (flags[0] & flags[1] & flags[2]) { + return false; + } + + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + dist = poly->dist; + + if (Math3D_TriChkLineSegParaYIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->z, min->x, &intersect, min->y, + max->y) || + Math3D_TriChkLineSegParaYIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->z, min->x, &intersect, min->y, + max->y) || + Math3D_TriChkLineSegParaYIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->z, max->x, &intersect, min->y, + max->y) || + Math3D_TriChkLineSegParaYIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->z, max->x, &intersect, min->y, + max->y)) { + return true; + } + if (Math3D_TriChkLineSegParaZIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->x, min->y, &intersect, min->z, + max->z) || + Math3D_TriChkLineSegParaZIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->x, max->y, &intersect, min->z, + max->z) || + Math3D_TriChkLineSegParaZIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->x, min->y, &intersect, min->z, + max->z) || + Math3D_TriChkLineSegParaZIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->x, max->y, &intersect, min->z, + max->z)) { + return true; + } + if (Math3D_TriChkLineSegParaXIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->y, min->z, &intersect, min->x, + max->x) || + Math3D_TriChkLineSegParaXIntersect(&va, &vb, &vc, nx, ny, nz, dist, min->y, max->z, &intersect, min->x, + max->x) || + Math3D_TriChkLineSegParaXIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->y, min->z, &intersect, min->x, + max->x) || + Math3D_TriChkLineSegParaXIntersect(&va, &vb, &vc, nx, ny, nz, dist, max->y, max->z, &intersect, min->x, + max->x)) { + return true; + } + + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)], &va2); + BgCheck_Vec3sToVec3f(&vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)], &vb2); + BgCheck_Vec3sToVec3f(&vtxList[poly->vIC], &vc2); + if (Math3D_LineVsCube(min, max, &va2, &vb2) || Math3D_LineVsCube(min, max, &vb2, &vc2) || + Math3D_LineVsCube(min, max, &vc2, &va2)) { + return true; + } + return false; +} + +/** + * Initialize StaticLookup Table + * returns size of table, in bytes + */ +u32 BgCheck_InitStaticLookup(CollisionContext* colCtx, GlobalContext* globalCtx, StaticLookup* lookupTbl) { + Vec3s* vtxList; + CollisionPoly* polyList; + s32 polyMax; + s32 polyIdx; + s32 sx; + s32 sy; + s32 sz; + // subdivMin indices + s32 sxMin; + s32 syMin; + s32 szMin; + // subdivMax indices + s32 sxMax; + s32 syMax; + s32 szMax; + // subdiv min/max bounds for adding a poly + Vec3f curSubdivMin; + Vec3f curSubdivMax; + CollisionHeader* colHeader = colCtx->colHeader; + s32 pad[2]; + StaticLookup* iLookup; + StaticLookup* jLookup; + StaticLookup* lookup; + s32 sp98; + f32 subdivLengthX; + f32 subdivLengthY; + f32 subdivLengthZ; + + for (iLookup = lookupTbl; + iLookup < (colCtx->subdivAmount.x * colCtx->subdivAmount.y * colCtx->subdivAmount.z + lookupTbl); iLookup++) { + iLookup->floor.head = SS_NULL; + iLookup->wall.head = SS_NULL; + iLookup->ceiling.head = SS_NULL; + } + + polyMax = colHeader->numPolygons; + vtxList = colHeader->vtxList; + polyList = colHeader->polyList; + sp98 = colCtx->subdivAmount.x * colCtx->subdivAmount.y; + subdivLengthX = colCtx->subdivLength.x + (2 * BGCHECK_SUBDIV_OVERLAP); + subdivLengthY = colCtx->subdivLength.y + (2 * BGCHECK_SUBDIV_OVERLAP); + subdivLengthZ = colCtx->subdivLength.z + (2 * BGCHECK_SUBDIV_OVERLAP); + + for (polyIdx = 0; polyIdx < polyMax; polyIdx++) { + BgCheck_GetPolySubdivisionBounds(colCtx, vtxList, polyList, &sxMin, &syMin, &szMin, &sxMax, &syMax, &szMax, + polyIdx); + iLookup = szMin * sp98 + lookupTbl; + curSubdivMin.z = (colCtx->subdivLength.z * szMin + colCtx->minBounds.z) - BGCHECK_SUBDIV_OVERLAP; + curSubdivMax.z = curSubdivMin.z + subdivLengthZ; + + for (sz = szMin; sz < szMax + 1; sz++) { + jLookup = (colCtx->subdivAmount.x * syMin) + iLookup; + curSubdivMin.y = (colCtx->subdivLength.y * syMin + colCtx->minBounds.y) - BGCHECK_SUBDIV_OVERLAP; + curSubdivMax.y = curSubdivMin.y + subdivLengthY; + + for (sy = syMin; sy < syMax + 1; sy++) { + lookup = sxMin + jLookup; + curSubdivMin.x = (colCtx->subdivLength.x * sxMin + colCtx->minBounds.x) - BGCHECK_SUBDIV_OVERLAP; + curSubdivMax.x = curSubdivMin.x + subdivLengthX; + + for (sx = sxMin; sx < sxMax + 1; sx++) { + if (BgCheck_PolyIntersectsSubdivision(&curSubdivMin, &curSubdivMax, polyList, vtxList, polyIdx)) { + StaticLookup_AddPoly(lookup, colCtx, polyList, vtxList, polyIdx); + } + curSubdivMin.x += colCtx->subdivLength.x; + curSubdivMax.x += colCtx->subdivLength.x; + lookup++; + } + curSubdivMin.y += colCtx->subdivLength.y; + curSubdivMax.y += colCtx->subdivLength.y; + jLookup += colCtx->subdivAmount.x; + } + curSubdivMin.z += colCtx->subdivLength.z; + curSubdivMax.z += colCtx->subdivLength.z; + iLookup += sp98; + } + } + return colCtx->polyNodes.count * sizeof(SSNode); +} + +/** + * Returns whether the current scene should reserve less memory for it's collision lookup + */ +s32 BgCheck_IsSmallMemScene(GlobalContext* globalCtx) { + s16* i; + + for (i = sSmallMemScenes; i < sSmallMemScenes + ARRAY_COUNT(sSmallMemScenes); i++) { + if (globalCtx->sceneNum == *i) { + return true; + } + } + return false; +} + +/** + * Get custom scene memSize + */ +s32 BgCheck_TryGetCustomMemsize(s32 sceneId, u32* memSize) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(sSceneMemList); i++) { + if (sceneId == sSceneMemList[i].sceneId) { + *memSize = sSceneMemList[i].memSize; + return true; + } + } + return false; +} + +/** + * Compute subdivLength for scene mesh lookup, for a single dimension + */ +void BgCheck_SetSubdivisionDimension(f32 min, s32 subdivAmount, f32* max, f32* subdivLength, f32* subdivLengthInv) { + f32 length = (*max - min); + + *subdivLength = (s32)(length / subdivAmount) + 1; + *subdivLength = CLAMP_MIN(*subdivLength, BGCHECK_SUBDIV_MIN); + *subdivLengthInv = 1.0f / *subdivLength; + + *max = *subdivLength * subdivAmount + min; +} + +s32 BgCheck_GetSpecialSceneMaxObjects(GlobalContext* globalCtx, s32* maxNodes, s32* maxPolygons, s32* maxVertices) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(sCustomDynapolyMem); i++) { + if (globalCtx->sceneNum == sCustomDynapolyMem[i].sceneId) { + *maxNodes = sCustomDynapolyMem[i].maxNodes; + *maxPolygons = sCustomDynapolyMem[i].maxPolygons; + *maxVertices = sCustomDynapolyMem[i].maxVertices; + return true; + } + } + return false; +} + +/** + * Allocate CollisionContext + */ +void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, CollisionHeader* colHeader) { + u32 tblMax; + u32 memSize; + u32 lookupTblMemSize; + SSNodeList* nodeList; + s32 customNodeListMax; + + customNodeListMax = -1; + colCtx->colHeader = colHeader; + colCtx->flags = 0; + + if (BgCheck_IsSmallMemScene(globalCtx)) { + colCtx->memSize = 0xF000; + colCtx->dyna.polyNodesMax = 1000; + colCtx->dyna.polyListMax = 512; + colCtx->dyna.vtxListMax = 512; + colCtx->subdivAmount.x = 16; + 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 { + colCtx->memSize = 0x23000; + } + colCtx->dyna.polyNodesMax = 1000; + colCtx->dyna.polyListMax = 544; + colCtx->dyna.vtxListMax = 512; + BgCheck_GetSpecialSceneMaxObjects(globalCtx, &colCtx->dyna.polyNodesMax, &colCtx->dyna.polyListMax, + &colCtx->dyna.vtxListMax); + useCustomSubdivisions = false; + + for (i = 0; i < ARRAY_COUNT(sSceneSubdivisionList); i++) { + if (globalCtx->sceneNum == sSceneSubdivisionList[i].sceneId) { + colCtx->subdivAmount.x = sSceneSubdivisionList[i].subdivAmount.x; + colCtx->subdivAmount.y = sSceneSubdivisionList[i].subdivAmount.y; + colCtx->subdivAmount.z = sSceneSubdivisionList[i].subdivAmount.z; + useCustomSubdivisions = true; + customNodeListMax = sSceneSubdivisionList[i].nodeListMax; + } + } + if (useCustomSubdivisions == false) { + colCtx->subdivAmount.x = 16; + colCtx->subdivAmount.y = 4; + colCtx->subdivAmount.z = 16; + } + } + colCtx->lookupTbl = THA_AllocEndAlign( + &globalCtx->state.heap, + colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y * colCtx->subdivAmount.z, ~1); + if (colCtx->lookupTbl == NULL) { + Fault_AddHungupAndCrash("../z_bgcheck.c", 3955); + } + colCtx->minBounds.x = colCtx->colHeader->minBounds.x; + colCtx->minBounds.y = colCtx->colHeader->minBounds.y; + colCtx->minBounds.z = colCtx->colHeader->minBounds.z; + colCtx->maxBounds.x = colCtx->colHeader->maxBounds.x; + colCtx->maxBounds.y = colCtx->colHeader->maxBounds.y; + colCtx->maxBounds.z = colCtx->colHeader->maxBounds.z; + BgCheck_SetSubdivisionDimension(colCtx->minBounds.x, colCtx->subdivAmount.x, &colCtx->maxBounds.x, + &colCtx->subdivLength.x, &colCtx->subdivLengthInv.x); + BgCheck_SetSubdivisionDimension(colCtx->minBounds.y, colCtx->subdivAmount.y, &colCtx->maxBounds.y, + &colCtx->subdivLength.y, &colCtx->subdivLengthInv.y); + BgCheck_SetSubdivisionDimension(colCtx->minBounds.z, colCtx->subdivAmount.z, &colCtx->maxBounds.z, + &colCtx->subdivLength.z, &colCtx->subdivLengthInv.z); + memSize = colCtx->subdivAmount.x * sizeof(StaticLookup) * colCtx->subdivAmount.y * colCtx->subdivAmount.z + + colCtx->colHeader->numPolygons * sizeof(u8) + colCtx->dyna.polyNodesMax * sizeof(SSNode) + + colCtx->dyna.polyListMax * sizeof(CollisionPoly) + colCtx->dyna.vtxListMax * sizeof(Vec3s) + + sizeof(CollisionContext); + if (customNodeListMax > 0) { + // tblMax is set without checking if customNodeListMax will result in a memory overflow + // this is a non-issue as long as sSceneSubdivisionList.nodeListMax is -1 + tblMax = customNodeListMax; + } else { + if (colCtx->memSize < memSize) { + Fault_AddHungupAndCrash("../z_bgcheck.c", 4011); + } + tblMax = (colCtx->memSize - memSize) / sizeof(SSNode); + } + + SSNodeList_Init(&colCtx->polyNodes); + SSNodeList_Alloc(globalCtx, &colCtx->polyNodes, tblMax, colCtx->colHeader->numPolygons); + + lookupTblMemSize = BgCheck_InitStaticLookup(colCtx, globalCtx, colCtx->lookupTbl); + + DynaPoly_Init(globalCtx, &colCtx->dyna); + DynaPoly_Alloc(globalCtx, &colCtx->dyna); +} + +/** + * Enables CollisionContext wide flags + * Only used to reverse water flow in Great Bay Temple + */ +void BgCheck_SetContextFlags(CollisionContext* colCtx, u32 flags) { + colCtx->flags |= flags; +} + +/** + * Disables CollisionContext wide flags + * Only used to revert the reverse water flow in Great Bay Temple + */ +void BgCheck_UnsetContextFlags(CollisionContext* colCtx, u32 flags) { + colCtx->flags &= ~flags; +} + +/** + * original name: T_BGCheck_getBGDataInfo + */ +CollisionHeader* BgCheck_GetCollisionHeader(CollisionContext* colCtx, s32 bgId) { + if (bgId == BGCHECK_SCENE) { + return colCtx->colHeader; + } + if (bgId < 0 || bgId > BG_ACTOR_MAX) { + return NULL; + } + if (!(colCtx->dyna.bgActorFlags[bgId] & 1)) { + return NULL; + } + return colCtx->dyna.bgActors[bgId].colHeader; +} + +/** + * Test if pos is near collision boundaries + */ +s32 BgCheck_PosInStaticBoundingBox(CollisionContext* colCtx, Vec3f* pos) { + if (pos->x < (colCtx->minBounds.x - BGCHECK_SUBDIV_OVERLAP) || + (colCtx->maxBounds.x + BGCHECK_SUBDIV_OVERLAP) < pos->x || + pos->y < (colCtx->minBounds.y - BGCHECK_SUBDIV_OVERLAP) || + (colCtx->maxBounds.y + BGCHECK_SUBDIV_OVERLAP) < pos->y || + pos->z < (colCtx->minBounds.z - BGCHECK_SUBDIV_OVERLAP) || + (colCtx->maxBounds.z + BGCHECK_SUBDIV_OVERLAP) < pos->z) { + return false; + } + return true; +} + +/** + * Raycast Toward Floor + * returns the yIntersect of the nearest poly found directly below `pos`, or BGCHECK_Y_MIN if no floor detected + * returns the poly found in `outPoly`, and the bgId of the entity in `outBgId` + */ +f32 BgCheck_RaycastFloorImpl(GlobalContext* globalCtx, CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, + s32* outBgId, Vec3f* pos, Actor* actor, u32 arg7, f32 checkDist, s32 arg9) { + f32 yIntersectDyna; + f32 yIntersect; + StaticLookup* lookupTbl; + Vec3f checkPos; + StaticLookup* lookup; + DynaRaycast dynaRaycast; + + *outBgId = BGCHECK_SCENE; + *outPoly = NULL; + lookupTbl = colCtx->lookupTbl; + yIntersect = BGCHECK_Y_MIN; + checkPos = *pos; + + while (true) { + if (checkPos.y < colCtx->minBounds.y) { + break; + } + lookup = BgCheck_GetStaticLookup(colCtx, lookupTbl, &checkPos); + if (lookup == NULL) { + checkPos.y -= colCtx->subdivLength.y; + continue; + } + yIntersect = + BgCheck_RaycastFloorStatic(lookup, colCtx, xpFlags, outPoly, pos, arg7, checkDist, BGCHECK_Y_MIN, actor); + if (yIntersect > BGCHECK_Y_MIN) { + break; + } + checkPos.y -= colCtx->subdivLength.y; + } + if (!(arg9 & 1)) { + dynaRaycast.globalCtx = globalCtx; + dynaRaycast.colCtx = colCtx; + dynaRaycast.xpFlags = xpFlags; + dynaRaycast.resultPoly = outPoly; + dynaRaycast.yIntersect = yIntersect; + dynaRaycast.pos = pos; + dynaRaycast.bgId = outBgId; + dynaRaycast.unk1C = 50; + dynaRaycast.actor = actor; + dynaRaycast.unk_24 = arg7; + dynaRaycast.checkDist = checkDist; + + yIntersectDyna = BgCheck_RaycastFloorDyna(&dynaRaycast); + if (yIntersect < yIntersectDyna) { + yIntersect = yIntersectDyna; + } + } + + if (yIntersect != BGCHECK_Y_MIN && func_800C9B68(colCtx, *outPoly, *outBgId)) { + yIntersect -= 1.0f; + } + return yIntersect; +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_CameraRaycastFloor1(CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos) { + s32 bgId; + + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_CAMERA, outPoly, &bgId, pos, NULL, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor1(CollisionContext* colCtx, CollisionPoly** outPoly, Vec3f* pos) { + s32 bgId; + + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, &bgId, pos, NULL, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor2(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, + Vec3f* pos) { + s32 bgId; + + return BgCheck_RaycastFloorImpl(globalCtx, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, &bgId, pos, NULL, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor2_1(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, + Vec3f* pos) { + s32 bgId; + + return BgCheck_RaycastFloorImpl(globalCtx, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, &bgId, pos, NULL, 0x1C, 1.0f, 1); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor3(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, NULL, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor5(CollisionContext* colCtx, CollisionPoly** outPoly, s32* outBgId, Actor* actor, + Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, outBgId, pos, actor, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor5_2(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, + s32* bgId, Actor* actor, Vec3f* pos) { + return BgCheck_RaycastFloorImpl(globalCtx, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, actor, 0x1C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor5_3(GlobalContext* globalCtx, CollisionContext* colCtx, CollisionPoly** outPoly, + s32* bgId, Actor* actor, Vec3f* pos) { + return BgCheck_RaycastFloorImpl(globalCtx, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, actor, 0x3C, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor6(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, Vec3f* pos, + f32 checkDist) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, actor, 0x1C, checkDist, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor7(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, + Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, actor, 0x06, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_AnyRaycastFloor1(CollisionContext* colCtx, CollisionPoly* outPoly, Vec3f* pos) { + CollisionPoly* tempPoly; + f32 result; + s32 bgId; + + result = BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_NONE, &tempPoly, &bgId, pos, NULL, 0x1C, 1.0f, 0); + + if (tempPoly != NULL) { + *outPoly = *tempPoly; + } + return result; +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_AnyRaycastFloor2(CollisionContext* colCtx, CollisionPoly* outPoly, s32* bgId, Vec3f* pos) { + CollisionPoly* tempPoly; + f32 result = BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_NONE, &tempPoly, bgId, pos, NULL, 0x1C, 1.0f, 0); + + if (tempPoly != NULL) { + *outPoly = *tempPoly; + } + return result; +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_CameraRaycastFloor2(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_CAMERA, outPoly, bgId, pos, NULL, 0x06, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor8(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Actor* actor, + Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, actor, 0x02, 1.0f, 0); +} + +/** + * Public raycast toward floor + * returns yIntersect of the poly found, or BGCHECK_Y_MIN if no poly detected + */ +f32 BgCheck_EntityRaycastFloor9(CollisionContext* colCtx, CollisionPoly** outPoly, s32* bgId, Vec3f* pos) { + return BgCheck_RaycastFloorImpl(NULL, colCtx, COLPOLY_IGNORE_ENTITY, outPoly, bgId, pos, NULL, 0x06, 1.0f, 0); +} + +#ifdef NON_MATCHING +/** + * Tests if moving from `posPrev` to `posNext` will collide with a "wall" + * `radius` is used to form a sphere for collision detection purposes + * `checkHeight` is the positive height above posNext to perform certain checks + * returns true if a collision is detected, else false + * `outPoly` returns the closest poly detected, while `outBgId` returns the poly owner + */ +s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, + f32 radius, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight, u8 argA) { + StaticLookup* lookupTbl; + f32 temp_f0; + s32 result; + CollisionPoly* poly; + // change between posPrev to posNext + f32 dx; + f32 dy; + f32 dz; + Vec3f sphCenter; + s32 dynaPolyCollision; + Vec3f posIntersect; + s32 bgId; + f32 temp_f0_2; + f32 f32temp; + f32 nx2, nz2; + Vec3f checkLineNext; + Vec3f checkLinePrev; + f32 n2XZDist; + f32 n3XZDist; + f32 nx3, nz3; + s32 bccFlags; + Vec3f posIntersect2; + s32 bgId2; + // unit normal of polygon + f32 nx; + f32 ny; + f32 nz; + + result = false; + *outBgId = BGCHECK_SCENE; + *outPoly = NULL; + lookupTbl = colCtx->lookupTbl; + *posResult = *posNext; + dx = posNext->x - posPrev->x; + dy = posNext->y - posPrev->y; + dz = posNext->z - posPrev->z; + + // if there's movement on the xz plane, and argA flag is 0, + if ((dx != 0.0f || dz != 0.0f) && (argA & 1) == 0) { + if ((checkHeight + dy) < 5.0f) { + //! @bug checkHeight is not applied to posPrev/posNext + result = BgCheck_CheckLineImpl(colCtx, xpFlags, COLPOLY_IGNORE_NONE, posPrev, posNext, &posIntersect, &poly, + &bgId, actor, 1.0f, BGCHECK_CHECK_ALL & ~BGCHECK_CHECK_CEILING); + if (result) { + ny = COLPOLY_GET_NORMAL(poly->normal.y); + // if poly is floor, push result underneath the floor + if (ny > 0.5f) { + posResult->x = posIntersect.x; + if (checkHeight > 1.0f) { + posResult->y = posIntersect.y - 1.0f; + } else { + posResult->y = posIntersect.y - checkHeight; + } + posResult->z = posIntersect.z; + if (actor != NULL) { + actor->bgCheckFlags |= 0x1000; + } + } + // poly is wall + else { + nx = COLPOLY_GET_NORMAL(poly->normal.x); + nz = COLPOLY_GET_NORMAL(poly->normal.z); + posResult->x = radius * nx + posIntersect.x; + posResult->y = radius * ny + posIntersect.y; + posResult->z = radius * nz + posIntersect.z; + } + *outPoly = poly; + *outBgId = bgId; + } + } else { + // if the radius is less than the distance travelled on the xz plane, also test for floor collisions + bccFlags = SQ(radius) < (SQ(dx) + SQ(dz)) + ? (BGCHECK_CHECK_ALL & ~BGCHECK_CHECK_CEILING) + : (BGCHECK_CHECK_ALL & ~BGCHECK_CHECK_FLOOR & ~BGCHECK_CHECK_CEILING); + + // perform a straight line test to see if a line at posNext.y + checkHeight from posPrev.xz to posNext.xz + // passes through any wall and possibly floor polys + checkLineNext = *posNext; + checkLineNext.y += checkHeight; + checkLinePrev = *posPrev; + checkLinePrev.y = checkLineNext.y; + result = BgCheck_CheckLineImpl(colCtx, xpFlags, COLPOLY_IGNORE_NONE, &checkLinePrev, &checkLineNext, + &posIntersect, &poly, &bgId, actor, 1.0f, bccFlags); + + if (result) { + nx2 = COLPOLY_GET_NORMAL(poly->normal.x); + nz2 = COLPOLY_GET_NORMAL(poly->normal.z); + n2XZDist = sqrtf(SQ(nx2) + SQ(nz2)); + + // if poly is not a "flat" floor or "flat" ceiling + if (!IS_ZERO(n2XZDist)) { + // normalize nx,nz and multiply each by the radius to go back to the other side of the wall + f32temp = 1.0f / n2XZDist; + temp_f0 = radius * f32temp; + posResult->x = temp_f0 * nx2 + posIntersect.x; + posResult->z = temp_f0 * nz2 + posIntersect.z; + *outPoly = poly; + *outBgId = bgId; + result = true; + if (COLPOLY_GET_NORMAL(poly->normal.y) > 0.5f) { + if (actor != NULL) { + actor->bgCheckFlags |= 0x1000; + } + } + } else { + result = false; + } + } + } + } + + sphCenter = *posResult; + dynaPolyCollision = false; + sphCenter.y += checkHeight; + // test if sphere (sphCenter, radius) collides with a dynamic wall, displacing the x/z coordinates + if (BgCheck_SphVsDynaWall(colCtx, xpFlags, &posResult->x, &posResult->z, &sphCenter, radius, outPoly, outBgId, + actor)) { + result = true; + dynaPolyCollision = true; + sphCenter = *posResult; + sphCenter.y += checkHeight; + } + // test if sphere (sphCenter, radius) collides with a static wall, displacing the x/z coordinates + if (BgCheck_PosInStaticBoundingBox(colCtx, posNext) && + // possible bug? if the sphere's radius is smaller than the distance to a subdivision boundary, some static + // polys will be missed + BgCheck_SphVsStaticWall(BgCheck_GetNearestStaticLookup(colCtx, lookupTbl, posResult), colCtx, xpFlags, + &posResult->x, &posResult->z, &sphCenter, radius, outPoly, actor)) { + *outBgId = BGCHECK_SCENE; + result = true; + } + // if a collision with a dyna poly was detected + if (dynaPolyCollision || *outBgId != BGCHECK_SCENE) { + if (BgCheck_CheckLineImpl(colCtx, xpFlags, COLPOLY_IGNORE_NONE, posPrev, posResult, &posIntersect2, &poly, + &bgId2, actor, 1.0f, BGCHECK_CHECK_ONE_FACE | BGCHECK_CHECK_WALL)) { + nx3 = COLPOLY_GET_NORMAL(poly->normal.x); + nz3 = COLPOLY_GET_NORMAL(poly->normal.z); + n3XZDist = sqrtf(SQ(nx3) + SQ(nz3)); + + // if poly is not a "flat" floor or "flat" ceiling + if (!IS_ZERO(n3XZDist)) { + // normalize nx,nz and multiply each by the radius to go back to the other side of the wall + f32temp = 1.0f / n3XZDist; + temp_f0_2 = radius * f32temp; + posResult->x = temp_f0_2 * nx3 + posIntersect2.x; + posResult->z = temp_f0_2 * nz3 + posIntersect2.z; + *outPoly = poly; + *outBgId = bgId2; + result = true; + } + } + } + return result; +} +#else +s32 BgCheck_CheckWallImpl(CollisionContext* colCtx, u16 xpFlags, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, + f32 radius, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight, u8 argA); +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CheckWallImpl.s") +#endif + +/** + * Public. Tests if moving from `posPrev` to `posNext` will collide with a "wall" + * `radius` is used to form a sphere for collision detection purposes + * `checkHeight` is the positive height above posNext to perform certain checks + * returns true if a collision is detected, else false + * `outPoly` returns the closest poly detected + */ +s32 BgCheck_EntitySphVsWall1(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, + CollisionPoly** outPoly, f32 checkHeight) { + s32 bgId; + + return BgCheck_CheckWallImpl(colCtx, COLPOLY_IGNORE_ENTITY, posResult, posNext, posPrev, radius, outPoly, &bgId, + NULL, checkHeight, 0); +} + +/** + * Public. Tests if moving from `posPrev` to `posNext` will collide with a "wall" + * `radius` is used to form a sphere for collision detection purposes + * `checkHeight` is the positive height above posNext to perform certain checks + * returns true if a collision is detected, else false + * `outPoly` returns the closest poly detected, while `outBgId` returns the poly owner + */ +s32 BgCheck_EntitySphVsWall2(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, + CollisionPoly** outPoly, s32* outBgId, f32 checkHeight) { + return BgCheck_CheckWallImpl(colCtx, COLPOLY_IGNORE_ENTITY, posResult, posNext, posPrev, radius, outPoly, outBgId, + NULL, checkHeight, 0); +} + +/** + * Public. Tests if *moving from `posPrev` to `posNext` will collide with a "wall" + * `radius` is used to form a sphere for collision detection purposes + * `checkHeight` is the positive height above posNext to perform certain checks + * `actor` is the actor performing the check, allowing it to be skipped + * returns true if a collision is detected, else false + * `outPoly` returns the closest poly detected, while `outBgId` returns the poly owner + */ +s32 BgCheck_EntitySphVsWall3(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, + CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight) { + return BgCheck_CheckWallImpl(colCtx, COLPOLY_IGNORE_ENTITY, posResult, posNext, posPrev, radius, outPoly, outBgId, + actor, checkHeight, 0); +} + +/** + * Public. Tests if moving from `posPrev` to `posNext` will collide with a "wall" + * Skips a check that occurs only when moving on the xz plane + * `radius` is used to form a sphere for collision detection purposes + * `checkHeight` is the positive height above posNext to perform certain checks + * `actor` is the actor performing the check, allowing it to be skipped + * returns true if a collision is detected, else false + * `outPoly` returns the closest poly detected, while `outBgId` returns the poly owner + */ +s32 BgCheck_EntitySphVsWall4(CollisionContext* colCtx, Vec3f* posResult, Vec3f* posNext, Vec3f* posPrev, f32 radius, + CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkHeight) { + return BgCheck_CheckWallImpl(colCtx, COLPOLY_IGNORE_ENTITY, posResult, posNext, posPrev, radius, outPoly, outBgId, + actor, checkHeight, 1); +} + +/** + * Tests for collision with a ceiling poly + * `checkHeight` should be a positive value + * returns true if a collision occurs, else false + * `outPoly` returns the poly collided with, while `outBgId` returns the owner of the poly + * `outY` returns the y coordinate of pos needed to not collide with `outPoly` + */ +s32 BgCheck_CheckCeilingImpl(CollisionContext* colCtx, u16 xpFlags, f32* outY, Vec3f* pos, f32 checkHeight, + CollisionPoly** outPoly, s32* outBgId, Actor* actor) { + StaticLookup* lookupTbl; + StaticLookup* lookup; + s32 result; + Vec3f posTemp; + f32 tempY; + + *outBgId = BGCHECK_SCENE; + *outY = pos->y; + lookupTbl = colCtx->lookupTbl; + if (!BgCheck_PosInStaticBoundingBox(colCtx, pos)) { + return false; + } + + lookup = BgCheck_GetNearestStaticLookup(colCtx, lookupTbl, pos); + result = BgCheck_CheckStaticCeiling(lookup, xpFlags, colCtx, outY, pos, checkHeight, outPoly, actor); + + posTemp = *pos; + posTemp.y = *outY; + tempY = *outY; + + if (BgCheck_CheckDynaCeiling(colCtx, xpFlags, &tempY, &posTemp, checkHeight, outPoly, outBgId, actor)) { + *outY = tempY; + result = true; + } + return result; +} + +/** + * Tests for collision with any ceiling poly + * `checkHeight` must be a positive value + * returns true if a collision occurs, else false + * `outY` returns the displaced y coordinate needed to not collide with the poly + */ +s32 BgCheck_AnyCheckCeiling(CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight) { + CollisionPoly* poly; + s32 bgId; + + return BgCheck_CheckCeilingImpl(colCtx, COLPOLY_IGNORE_NONE, outY, pos, checkHeight, &poly, &bgId, NULL); +} + +/** + * Tests for collision with any entity solid ceiling poly + * `checkHeight` must be a positive value + * returns true if a collision occurs, else false + * `outY` returns the displaced y coordinate needed to not collide with the poly + */ +s32 BgCheck_EntityCheckCeiling(CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight, + CollisionPoly** outPoly, s32* outBgId, Actor* actor) { + return BgCheck_CheckCeilingImpl(colCtx, COLPOLY_IGNORE_ENTITY, outY, pos, checkHeight, outPoly, outBgId, actor); +} + +/** + * Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + * `posB`? `posResult` returns the point of intersection + * `outPoly` returns the pointer to the intersected poly, while `outBgId` returns the entity the poly belongs to + */ +s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2, Vec3f* posA, Vec3f* posB, + Vec3f* posResult, CollisionPoly** outPoly, s32* outBgId, Actor* actor, f32 checkDist, + u32 bccFlags) { + StaticLookup* lookupTbl; + StaticLookup* iLookup; + s32 subdivMin[3]; + s32 subdivMax[3]; + s32 i; + s32 result; + Vec3f posBTemp; + StaticLineTest checkLine; + Vec3f sectorMin; + Vec3f sectorMax; + s32 temp_lo; + StaticLookup* lookup; + s32 j; + + lookupTbl = colCtx->lookupTbl; + posBTemp = *posB; + + *outBgId = BGCHECK_SCENE; + + BgCheck_ResetPolyCheckTbl(&colCtx->polyNodes, colCtx->colHeader->numPolygons); + BgCheck_GetStaticLookupIndicesFromPos(colCtx, posA, (Vec3i*)&subdivMin); + BgCheck_GetStaticLookupIndicesFromPos(colCtx, &posBTemp, (Vec3i*)&subdivMax); + *posResult = *posB; + checkLine.outDistSq = 1.0e38f; + *outPoly = NULL; + + checkLine.colCtx = colCtx; + checkLine.xpFlags2 = xpFlags2; + checkLine.posA = posA; + checkLine.posB = &posBTemp; + checkLine.outPoly = outPoly; + checkLine.xpFlags1 = xpFlags1; + checkLine.outPos = posResult; + checkLine.checkDist = checkDist; + checkLine.bccFlags = bccFlags; + checkLine.actor = actor; + result = false; + + if (subdivMin[0] != subdivMax[0] || subdivMin[1] != subdivMax[1] || subdivMin[2] != subdivMax[2]) { + for (i = 0; i < 3; i++) { + if (subdivMax[i] < subdivMin[i]) { + j = subdivMax[i]; + subdivMax[i] = subdivMin[i]; + subdivMin[i] = j; + } + } + temp_lo = colCtx->subdivAmount.x * colCtx->subdivAmount.y; + iLookup = lookupTbl + subdivMin[2] * temp_lo; + sectorMin.z = subdivMin[2] * colCtx->subdivLength.z + colCtx->minBounds.z; + sectorMax.z = colCtx->subdivLength.z + sectorMin.z; + + for (i = subdivMin[2]; i < subdivMax[2] + 1; i++) { + 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; + + for (k = subdivMin[0]; k < subdivMax[0] + 1; k++) { + if (Math3D_LineVsCube(§orMin, §orMax, posA, &posBTemp)) { + checkLine.lookup = lookup; + + if (BgCheck_CheckLineInSubdivision(&checkLine)) { + result = true; + } + } + lookup++; + sectorMin.x += colCtx->subdivLength.x; + sectorMax.x += colCtx->subdivLength.x; + } + jLookup += colCtx->subdivAmount.x; + sectorMin.y += colCtx->subdivLength.y; + sectorMax.y += colCtx->subdivLength.y; + } + iLookup += temp_lo; + sectorMin.z += colCtx->subdivLength.z; + sectorMax.z += colCtx->subdivLength.z; + } + } else if (BgCheck_PosInStaticBoundingBox(colCtx, posA) == false) { + return false; + } else { + checkLine.lookup = BgCheck_GetNearestStaticLookup(colCtx, lookupTbl, posA); + result = BgCheck_CheckLineInSubdivision(&checkLine); + if (result) { + checkLine.outDistSq = Math3D_Vec3fDistSq(posResult, posA); + } + } + if ((bccFlags & BGCHECK_CHECK_DYNA) && + BgCheck_CheckLineAgainstDyna(colCtx, xpFlags1, posA, &posBTemp, posResult, outPoly, &checkLine.outDistSq, + outBgId, actor, checkDist, bccFlags)) { + result = true; + } + return result; +} + +/** + * Get bccFlags + */ +u32 BgCheck_GetBccFlags(s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, s32 checkDyna) { + u32 result = 0; + + if (checkWall) { + result = BGCHECK_CHECK_WALL; + } + if (checkFloor) { + result |= BGCHECK_CHECK_FLOOR; + } + if (checkCeil) { + result |= BGCHECK_CHECK_CEILING; + } + if (checkOneFace) { + result |= BGCHECK_CHECK_ONE_FACE; + } + if (checkDyna) { + result |= BGCHECK_CHECK_DYNA; + } + return result; +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_CameraLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_CAMERA, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, + bgId, NULL, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_CameraLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_NONE, COLPOLY_IGNORE_CAMERA, posA, posB, posResult, outPoly, + bgId, NULL, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_EntityLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_ENTITY, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, + bgId, NULL, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_EntityLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId, Actor* actor) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_ENTITY, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, + bgId, actor, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_EntityLineTest3(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId, Actor* actor, f32 checkDist) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_ENTITY, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, + bgId, actor, checkDist, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_ProjectileLineTest(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, + s32* bgId) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_PROJECTILES, COLPOLY_IGNORE_NONE, posA, posB, posResult, + outPoly, bgId, NULL, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_AnyLineTest1(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, + s32 checkOneFace) { + return BgCheck_AnyLineTest2(colCtx, posA, posB, posResult, outPoly, true, true, true, checkOneFace); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_AnyLineTest2(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, + s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace) { + s32 bgId; + + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_NONE, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, + &bgId, NULL, 1.0f, + BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Public. Tests if a line from `posA` to `posB` intersects with a poly + * returns true if it does, else false + */ +s32 BgCheck_AnyLineTest3(CollisionContext* colCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, + s32 checkWall, s32 checkFloor, s32 checkCeil, s32 checkOneFace, s32* bgId) { + return BgCheck_CheckLineImpl(colCtx, COLPOLY_IGNORE_NONE, COLPOLY_IGNORE_NONE, posA, posB, posResult, outPoly, bgId, + NULL, 1.0f, BgCheck_GetBccFlags(checkWall, checkFloor, checkCeil, checkOneFace, true)); +} + +/** + * Get first poly intersecting sphere `center` `radius` + * ignores `actor` dyna poly + * returns true if any poly intersects the sphere, else false + * `outPoly` returns the pointer of the first poly found that intersects + * `outBgId` returns the bgId of the entity that owns `outPoly` + */ +s32 BgCheck_SphVsFirstPolyImpl(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, s32* outBgId, + Vec3f* center, f32 radius, Actor* actor, u16 bciFlags) { + StaticLookup* lookup; + + *outBgId = BGCHECK_SCENE; + lookup = BgCheck_GetStaticLookup(colCtx, colCtx->lookupTbl, center); + if (lookup == NULL) { + return false; + } else if (BgCheck_SphVsFirstStaticPoly(lookup, xpFlags, colCtx, center, radius, outPoly, bciFlags, actor) || + BgCheck_SphVsFirstDynaPoly(colCtx, xpFlags, outPoly, outBgId, center, radius, actor, bciFlags)) { + return true; + } + return false; +} + +/** + * Public get first poly intersecting sphere `center` `radius` + */ +s32 BgCheck_SphVsFirstPoly(CollisionContext* colCtx, Vec3f* center, f32 radius) { + CollisionPoly* poly; + s32 bgId; + + return BgCheck_SphVsFirstPolyImpl(colCtx, COLPOLY_IGNORE_NONE, &poly, &bgId, center, radius, NULL, + BGCHECK_IGNORE_NONE); +} + +/** + * Public get first wall poly intersecting sphere `center` `radius` + */ +s32 BgCheck_SphVsFirstWall(CollisionContext* colCtx, Vec3f* center, f32 radius) { + CollisionPoly* poly; + s32 bgId; + + return BgCheck_SphVsFirstPolyImpl(colCtx, COLPOLY_IGNORE_NONE, &poly, &bgId, center, radius, NULL, + BGCHECK_IGNORE_FLOOR | BGCHECK_IGNORE_CEILING); +} + +/** + * Init SSNodeList + */ +void SSNodeList_Init(SSNodeList* this) { + this->max = 0; + this->count = 0; + this->tbl = NULL; + this->polyCheckTbl = NULL; +} + +/** + * Allocate SSNodeList + * tblMax is the number of SSNode records to allocate + * numPolys is the number of polygons defined within the CollisionHeader + */ +void SSNodeList_Alloc(GlobalContext* globalCtx, SSNodeList* this, s32 tblMax, s32 numPolys) { + this->max = tblMax; + this->count = 0; + this->tbl = THA_AllocEndAlign(&globalCtx->state.heap, tblMax * sizeof(SSNode), -2); + this->polyCheckTbl = THA_AllocEndAlign16(&globalCtx->state.heap, numPolys * sizeof(u8)); + + if (this->polyCheckTbl == NULL) { + sprintf(D_801ED950, "this->polygon_check == NULL(game_alloc() MemoryAllocationError.)\n"); + sprintf(D_801ED9A0, "short_slist_node_size = %d/polygon_num = %d\n", tblMax, numPolys); + Fault_AddHungupAndCrashImpl(D_801ED950, D_801ED9A0); + } +} + +/** + * Get next SSNodeList SSNode + */ +SSNode* SSNodeList_GetNextNode(SSNodeList* this) { + SSNode* result = &this->tbl[this->count]; + + this->count++; + if (!(this->count < this->max)) { + return NULL; + } + return result; +} + +/** + * Get next SSNodeList SSNode index + */ +u16 SSNodeList_GetNextNodeIdx(SSNodeList* this) { + u16 new_index = this->count++; + + return new_index; +} + +/** + * Initialize ScaleRotPos + */ +void ScaleRotPos_Init(ScaleRotPos* srp) { + srp->scale.x = srp->scale.y = srp->scale.z = 1; + srp->rot.x = 0; + srp->rot.y = 0; + srp->rot.z = 0; + srp->pos.x = srp->pos.y = srp->pos.z = 0; +} + +/** + * Set ScaleRotPos + */ +void ScaleRotPos_SetValue(ScaleRotPos* srp, Vec3f* scale, Vec3s* rot, Vec3f* pos) { + srp->scale = *scale; + srp->rot = *rot; + srp->pos = *pos; +} + +/** + * ScaleRotPos equality test + */ +s32 ScaleRotPos_IsEqual(ScaleRotPos* a, ScaleRotPos* b) { + if (a->scale.x != b->scale.x || a->scale.y != b->scale.y || a->scale.z != b->scale.z || a->rot.x != b->rot.x || + a->rot.y != b->rot.y || a->rot.z != b->rot.z || a->pos.x != b->pos.x || a->pos.y != b->pos.y || + a->pos.z != b->pos.z) { + return false; + } + return true; +} + +/** + * Reset DynaLookup lists + */ +void DynaLookup_ResetLists(DynaLookup* dynaLookup) { + SSList_SetNull(&dynaLookup->ceiling); + SSList_SetNull(&dynaLookup->wall); + SSList_SetNull(&dynaLookup->floor); +} + +/** + * Reset DynaLookup + */ +void DynaLookup_Reset(DynaLookup* dynaLookup) { + dynaLookup->polyStartIndex = 0; + DynaLookup_ResetLists(dynaLookup); +} + +/** + * Reset vtxStartIndex + */ +void DynaLookup_ResetVtxStartIndex(u16* vtxStartIndex) { + *vtxStartIndex = 0; +} + +/** + * Reset waterBoxStartIndex + */ +void DynaLookup_ResetWaterBoxStartIndex(u16* waterBoxStartIndex) { + *waterBoxStartIndex = 0; +} + +/** + * Initialize BgActor + */ +void BgActor_Init(GlobalContext* globalCtx, BgActor* bgActor) { + bgActor->actor = NULL; + bgActor->colHeader = NULL; + ScaleRotPos_Init(&bgActor->prevTransform); + ScaleRotPos_Init(&bgActor->curTransform); + DynaLookup_Reset(&bgActor->dynaLookup); + DynaLookup_ResetVtxStartIndex(&bgActor->vtxStartIndex); + DynaLookup_ResetWaterBoxStartIndex(&bgActor->waterboxesStartIndex); + bgActor->boundingSphere.center.x = bgActor->boundingSphere.center.y = bgActor->boundingSphere.center.z = 0; + bgActor->boundingSphere.radius = 0; +} + +/** + * setActor internal + */ +void BgActor_SetActor(BgActor* bgActor, Actor* actor, CollisionHeader* colHeader) { + bgActor->actor = actor; + bgActor->colHeader = colHeader; + bgActor->prevTransform.scale = actor->scale; + bgActor->prevTransform.rot = actor->shape.rot; + bgActor->prevTransform.rot.x--; + bgActor->prevTransform.pos = actor->world.pos; + bgActor->curTransform.scale = actor->scale; + bgActor->curTransform.rot = actor->shape.rot; + bgActor->curTransform.pos = actor->world.pos; +} + +/** + * Test if the BgActor transform is the same + */ +s32 BgActor_IsTransformUnchanged(BgActor* bgActor) { + return ScaleRotPos_IsEqual(&bgActor->prevTransform, &bgActor->curTransform); +} + +/** + * NULL polyList + */ +void DynaPoly_NullPolyList(CollisionPoly** polyList) { + *polyList = NULL; +} + +/** + * Allocate dyna.polyList + */ +void DynaPoly_AllocPolyList(GlobalContext* globalCtx, CollisionPoly** polyList, s32 numPolys) { + *polyList = THA_AllocEndAlign(&globalCtx->state.heap, numPolys * sizeof(CollisionPoly), -2); +} + +/** + * NULL vtxList + */ +void DynaPoly_NullVtxList(Vec3s** vtxList) { + *vtxList = NULL; +} + +/** + * Allocate dyna.vtxList + */ +void DynaPoly_AllocVtxList(GlobalContext* globalCtx, Vec3s** vtxList, s32 numVtx) { + *vtxList = THA_AllocEndAlign(&globalCtx->state.heap, numVtx * sizeof(Vec3s), -2); +} + +/** + * Init dyna.waterBoxList + */ +void DynaPoly_InitWaterBoxList(DynaWaterBoxList* waterBoxList) { + waterBoxList->unk0 = 0; + waterBoxList->boxes = NULL; +} + +/** + * Allocate dyna.waterBoxList + */ +void DynaPoly_AllocWaterBoxList(GlobalContext* globalCtx, DynaWaterBoxList* waterBoxList, s32 numWaterBoxes) { + waterBoxList->boxes = THA_AllocEndAlign(&globalCtx->state.heap, numWaterBoxes * sizeof(WaterBox), -2); +} + +/** + * Update BgActor's prevTransform + */ +void DynaPoly_SetBgActorPrevTransform(GlobalContext* globalCtx, BgActor* bgActor) { + bgActor->prevTransform = bgActor->curTransform; +} + +/** + * Is BgActor Id + */ +s32 DynaPoly_IsBgIdBgActor(s32 bgId) { + if (bgId < 0 || bgId >= BG_ACTOR_MAX) { + return false; + } + return true; +} + +/** + * Init DynaCollisionContext + */ +void DynaPoly_Init(GlobalContext* globalCtx, DynaCollisionContext* dyna) { + dyna->bitFlag = DYNAPOLY_INVALIDATE_LOOKUP; + DynaPoly_NullPolyList(&dyna->polyList); + DynaPoly_NullVtxList(&dyna->vtxList); + DynaPoly_InitWaterBoxList(&dyna->waterBoxList); + DynaSSNodeList_Init(globalCtx, &dyna->polyNodes); +} + +/** + * Set DynaCollisionContext + */ +void DynaPoly_Alloc(GlobalContext* globalCtx, DynaCollisionContext* dyna) { + s32 i; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + BgActor_Init(globalCtx, &dyna->bgActors[i]); + dyna->bgActorFlags[i] = 0; + } + DynaPoly_NullPolyList(&dyna->polyList); + DynaPoly_AllocPolyList(globalCtx, &dyna->polyList, dyna->polyListMax); + + DynaPoly_NullVtxList(&dyna->vtxList); + DynaPoly_AllocVtxList(globalCtx, &dyna->vtxList, dyna->vtxListMax); + + DynaPoly_InitWaterBoxList(&dyna->waterBoxList); + DynaPoly_AllocWaterBoxList(globalCtx, &dyna->waterBoxList, DYNA_WATERBOX_MAX); + + DynaSSNodeList_Init(globalCtx, &dyna->polyNodes); + DynaSSNodeList_Alloc(globalCtx, &dyna->polyNodes, dyna->polyNodesMax); +} + +/** + * Set BgActor + * original name: DynaPolyInfo_setActor + */ +s32 DynaPoly_SetBgActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, Actor* actor, + CollisionHeader* colHeader) { + s32 bgId; + s32 foundSlot = false; + + for (bgId = 0; bgId < BG_ACTOR_MAX; bgId++) { + if (!(dyna->bgActorFlags[bgId] & 1)) { + dyna->bgActorFlags[bgId] |= 1; + foundSlot = true; + break; + } + } + + if (foundSlot == false) { + return BG_ACTOR_MAX; + } + + BgActor_SetActor(&dyna->bgActors[bgId], actor, colHeader); + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + + dyna->bgActorFlags[bgId] &= ~2; + return bgId; +} + +/** + * Gets the actor assigned to `bgId` + */ +DynaPolyActor* DynaPoly_GetActor(CollisionContext* colCtx, s32 bgId) { + if (!DynaPoly_IsBgIdBgActor(bgId) || !(colCtx->dyna.bgActorFlags[bgId] & 1) || + colCtx->dyna.bgActorFlags[bgId] & 2) { + return NULL; + } + return (DynaPolyActor*)colCtx->dyna.bgActors[bgId].actor; +} + +void func_800C62BC(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] |= 4; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +void func_800C6314(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] &= ~4; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +void func_800C636C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] |= 8; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +void func_800C63C4(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] &= ~8; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +void func_800C641C(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] |= 0x20; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +void func_800C6474(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + if (DynaPoly_IsBgIdBgActor(bgId)) { + dyna->bgActorFlags[bgId] &= ~0x20; + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } +} + +/** + * original name: DynaPolyInfo_delReserve + */ +void DynaPoly_DeleteBgActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId) { + DynaPolyActor* actor; + + if (DynaPoly_IsBgIdBgActor(bgId) == false) { + return; + } + actor = DynaPoly_GetActor(&globalCtx->colCtx, bgId); + if (actor != NULL) { + + actor->bgId = BGACTOR_NEG_ONE; + dyna->bgActors[bgId].actor = NULL; + dyna->bgActorFlags[bgId] |= 2; + } +} + +void func_800C6554(GlobalContext* globalCtx, DynaCollisionContext* dyna) { + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; +} + +void BgCheck_CalcWaterboxDimensions(Vec3f* minPos, Vec3f* maxXPos, Vec3f* maxZPos, Vec3s* minPosOut, s16* xLength, + s16* zLength) { + f32 temp; + + minPosOut->x = minPos->x; + minPosOut->y = minPos->y; + minPosOut->z = minPos->z; + + if (maxXPos->x < minPosOut->x) { + minPosOut->x = maxXPos->x; + } + if (maxXPos->y < minPosOut->y) { + minPosOut->y = maxXPos->y; + } + if (maxXPos->z < minPosOut->z) { + minPosOut->z = maxXPos->z; + } + + if (maxZPos->x < minPosOut->x) { + minPosOut->x = maxZPos->x; + } + if (maxZPos->y < minPosOut->y) { + minPosOut->y = maxZPos->y; + } + if (maxZPos->z < minPosOut->z) { + minPosOut->z = maxZPos->z; + } + + *xLength = minPos->x - minPosOut->x; + temp = maxXPos->x - minPosOut->x; + + if (*xLength < temp) { + *xLength = temp; + } + temp = maxZPos->x - minPosOut->x; + if (*xLength < temp) { + *xLength = temp; + } + *zLength = minPos->z - minPosOut->z; + + temp = maxXPos->z - minPosOut->z; + if (*zLength < temp) { + *zLength = temp; + } + temp = maxZPos->z - minPosOut->z; + if (*zLength < temp) { + *zLength = temp; + } +} + +#ifdef NON_MATCHING +/** + * original name: DynaPolyInfo_expandSRT + */ +void DynaPoly_ExpandSRT(GlobalContext* globalCtx, DynaCollisionContext* dyna, s32 bgId, s32* vtxStartIndex, + s32* polyStartIndex, s32* waterBoxStartIndex) { + Actor* actor; + s32 pad; + s32 pad2; + f32 numVtxInverse; + s32 i; + Vec3f pos; // sp170 + Sphere16* sphere; + Vec3s* dVtxList; + Vec3s* point; + Vec3f newCenterPoint; // sp158 + + f32 newRadiusSq; + CollisionHeader* pbgdata; + Vec3f newVtx; // sp144 + Vec3f vtxA; // sp138 + Vec3f vtxB; // sp12C + Vec3f vtxC; // sp120 + Vec3f newNormal; + s32 wi; + Vec3f spB8; // waterbox ? + Vec3f spAC; + Vec3f spA0; // waterbox ? + Vec3f sp94; + Vec3f sp88; // waterbox ? + Vec3f sp7C; + WaterBox* waterBox; + + pbgdata = dyna->bgActors[bgId].colHeader; + sphere = &dyna->bgActors[bgId].boundingSphere; + actor = dyna->bgActors[bgId].actor; + dyna->bgActors[bgId].dynaLookup.polyStartIndex = *polyStartIndex; + dyna->bgActors[bgId].vtxStartIndex = *vtxStartIndex; + dyna->bgActors[bgId].waterboxesStartIndex = *waterBoxStartIndex; + pos = actor->world.pos; + pos.y += actor->shape.yOffset * actor->scale.y; + + ScaleRotPos_SetValue(&dyna->bgActors[bgId].curTransform, &actor->scale, &actor->shape.rot, &pos); + + if (dyna->bgActorFlags[bgId] & 4) { + return; + } + + if (!(DYNA_WATERBOX_MAX >= *waterBoxStartIndex + pbgdata->numWaterBoxes)) { + sprintf(D_801EDAA8, "water_poly Error:[MoveBG OSUGI!!!]"); + sprintf(D_801EDAF8, "num = %d > %d\n", *waterBoxStartIndex + pbgdata->numWaterBoxes, DYNA_WATERBOX_MAX); + Fault_AddHungupAndCrashImpl(D_801EDAA8, D_801EDAF8); + } + + if (!(dyna->polyListMax >= *polyStartIndex + pbgdata->numPolygons)) { + sprintf(D_801EDAA8, "bg_poly Error:[MoveBG OSUGI!!!]"); + sprintf(D_801EDAF8, "num = %d > %d\n", *polyStartIndex + pbgdata->numPolygons, dyna->polyListMax); + Fault_AddHungupAndCrashImpl(D_801EDAA8, D_801EDAF8); + } + + if (!(dyna->vtxListMax >= *vtxStartIndex + pbgdata->numVertices)) { + sprintf(D_801EDAA8, "bg_vert Error:[MoveBG OSUGI!!!]"); + sprintf(D_801EDAF8, "num = %d > %d\n", *vtxStartIndex + pbgdata->numVertices, dyna->vtxListMax); + Fault_AddHungupAndCrashImpl(D_801EDAA8, D_801EDAF8); + } + + if (!(dyna->bitFlag & DYNAPOLY_INVALIDATE_LOOKUP) && BgActor_IsTransformUnchanged(&dyna->bgActors[bgId])) { + s32 pi; + + for (pi = *polyStartIndex; pi < *polyStartIndex + pbgdata->numPolygons; pi++) { + CollisionPoly* poly = &dyna->polyList[pi]; + s16 normalY = poly->normal.y; + + if (normalY > COLPOLY_SNORMAL(0.5f)) { + if (!(dyna->bgActorFlags[bgId] & 0x20)) { + s16 polyIndex = pi; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.floor, &polyIndex); + } + } else if (normalY < COLPOLY_SNORMAL(-0.8f)) { + if (!(dyna->bgActorFlags[bgId] & 8)) { + s16 polyIndex = pi; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.ceiling, + &polyIndex); + } + } else { + s16 polyIndex = pi; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.wall, &polyIndex); + } + } + + *polyStartIndex += pbgdata->numPolygons; + *vtxStartIndex += pbgdata->numVertices; + *waterBoxStartIndex += pbgdata->numWaterBoxes; + } else { + SkinMatrix_SetScaleRotateYRPTranslate( + &D_801EDA40, dyna->bgActors[bgId].curTransform.scale.x, dyna->bgActors[bgId].curTransform.scale.y, + dyna->bgActors[bgId].curTransform.scale.z, dyna->bgActors[bgId].curTransform.rot.x, + dyna->bgActors[bgId].curTransform.rot.y, dyna->bgActors[bgId].curTransform.rot.z, + dyna->bgActors[bgId].curTransform.pos.x, dyna->bgActors[bgId].curTransform.pos.y, + dyna->bgActors[bgId].curTransform.pos.z); + + if (pbgdata->numVertices != 0 && pbgdata->numPolygons != 0) { + numVtxInverse = 1.0f / pbgdata->numVertices; + newCenterPoint.x = newCenterPoint.y = newCenterPoint.z = 0.0f; + for (i = 0; i < pbgdata->numVertices; i++) { + Vec3f vtx; // spF4 + Vec3f vtxT; // spE8 Vtx after mtx transform + + Math_Vec3s_ToVec3f(&vtx, &pbgdata->vtxList[i]); + SkinMatrix_Vec3fMtxFMultXYZ(&D_801EDA40, &vtx, &vtxT); + BgCheck_Vec3fToVec3s(&dyna->vtxList[*vtxStartIndex + i], &vtxT); + + if (i == 0) { + dyna->bgActors[bgId].minY = dyna->bgActors[bgId].maxY = vtxT.y; + } else if (vtxT.y < dyna->bgActors[bgId].minY) { + dyna->bgActors[bgId].minY = vtxT.y; + } else if (dyna->bgActors[bgId].maxY < vtxT.y) { + dyna->bgActors[bgId].maxY = vtxT.y; + } + newCenterPoint.x += vtxT.x; + newCenterPoint.y += vtxT.y; + newCenterPoint.z += vtxT.z; + } + + newCenterPoint.x *= numVtxInverse; + newCenterPoint.y *= numVtxInverse; + newCenterPoint.z *= numVtxInverse; + sphere->center.x = newCenterPoint.x; + sphere->center.y = newCenterPoint.y; + sphere->center.z = newCenterPoint.z; + newRadiusSq = -100.0f; + + for (i = 0; i < pbgdata->numVertices; i++) { + f32 radiusSq; + s32 idx = *vtxStartIndex + i; + + newVtx.x = dyna->vtxList[idx].x; + newVtx.y = dyna->vtxList[idx].y; + newVtx.z = dyna->vtxList[idx].z; + radiusSq = Math3D_Vec3fDistSq(&newVtx, &newCenterPoint); + if (newRadiusSq < radiusSq) { + newRadiusSq = radiusSq; + } + } + + sphere->radius = sqrtf(newRadiusSq) * 1.1f; + + for (i = 0; i < pbgdata->numPolygons; i++) { + CollisionPoly* newPoly = &dyna->polyList[*polyStartIndex + i]; + f32 newNormMagnitude; + u32 vIA; + u32 vIB; + u32 vIC; + + *newPoly = pbgdata->polyList[i]; + + vIA = (COLPOLY_VTX_INDEX(newPoly->flags_vIA) + *vtxStartIndex); + vIB = (COLPOLY_VTX_INDEX(newPoly->flags_vIB) + *vtxStartIndex); + vIC = newPoly->vIC + *vtxStartIndex; + + newPoly->flags_vIA = vIA | ((*newPoly).flags_vIA & 0xE000); + newPoly->flags_vIB = vIB | ((*newPoly).flags_vIB & 0xE000); + newPoly->vIC = vIC; + dVtxList = dyna->vtxList; + vtxA.x = dVtxList[vIA].x; + vtxA.y = dVtxList[vIA].y; + vtxA.z = dVtxList[vIA].z; + vtxB.x = dVtxList[vIB].x; + vtxB.y = dVtxList[vIB].y; + vtxB.z = dVtxList[vIB].z; + vtxC.x = dVtxList[vIC].x; + vtxC.y = dVtxList[vIC].y; + vtxC.z = dVtxList[vIC].z; + Math3D_SurfaceNorm(&vtxA, &vtxB, &vtxC, &newNormal); + newNormMagnitude = Math3D_Vec3fMagnitude(&newNormal); + + if (!IS_ZERO(newNormMagnitude)) { + newNormal.x *= (1.0f / newNormMagnitude); + newNormal.y *= (1.0f / newNormMagnitude); + newNormal.z *= (1.0f / newNormMagnitude); + newPoly->normal.x = COLPOLY_SNORMAL(newNormal.x); + newPoly->normal.y = COLPOLY_SNORMAL(newNormal.y); + newPoly->normal.z = COLPOLY_SNORMAL(newNormal.z); + } + + newPoly->dist = -DOTXYZ(newNormal, dVtxList[vIA]); + if (newNormal.y > 0.5f) { + s16 polyId = *polyStartIndex + i; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.floor, &polyId); + } else if (newNormal.y < -0.8f) { + s16 polyId = *polyStartIndex + i; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.ceiling, &polyId); + } else { + s16 polyId = *polyStartIndex + i; + + DynaSSNodeList_SetSSListHead(&dyna->polyNodes, &dyna->bgActors[bgId].dynaLookup.wall, &polyId); + } + } + } + + for (wi = 0; wi < pbgdata->numWaterBoxes; wi++) { + Math_Vec3s_ToVec3f(&spB8, &pbgdata->waterBoxes[wi].minPos); + Math_Vec3f_Copy(&spA0, &spB8); + spA0.x += pbgdata->waterBoxes[wi].xLength; + Math_Vec3f_Copy(&sp88, &spB8); + sp88.z += pbgdata->waterBoxes[wi].zLength; + SkinMatrix_Vec3fMtxFMultXYZ(&D_801EDA40, &spB8, &spAC); + SkinMatrix_Vec3fMtxFMultXYZ(&D_801EDA40, &spA0, &sp94); + SkinMatrix_Vec3fMtxFMultXYZ(&D_801EDA40, &sp88, &sp7C); + waterBox = &dyna->waterBoxList.boxes[*waterBoxStartIndex + wi]; + BgCheck_CalcWaterboxDimensions(&spAC, &sp94, &sp7C, &waterBox->minPos, &waterBox->xLength, + &waterBox->zLength); + waterBox->properties = pbgdata->waterBoxes[wi].properties; + } + + *polyStartIndex += pbgdata->numPolygons; + *vtxStartIndex += pbgdata->numVertices; + *waterBoxStartIndex += pbgdata->numWaterBoxes; + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/DynaPoly_ExpandSRT.s") +#endif + +void BgCheck_ResetFlagsIfLoadedActor(GlobalContext* globalCtx, DynaCollisionContext* dyna, Actor* actor) { + DynaPolyActor* dynaActor; + s32 i; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if ((dyna->bgActorFlags[i] & 1)) { + dynaActor = DynaPoly_GetActor(&globalCtx->colCtx, i); + if (dynaActor != NULL && &dynaActor->actor == actor) { + DynaPolyActor_ResetState((DynaPolyActor*)actor); + return; + } + } + } +} + +/** + * original name: DynaPolyInfo_setup + */ +void DynaPoly_Setup(GlobalContext* globalCtx, DynaCollisionContext* dyna) { + DynaPolyActor* actor; + s32 vtxStartIndex; + s32 polyStartIndex; + s32 waterBoxStartIndex; + s32 i; + + DynaSSNodeList_ResetCount(&dyna->polyNodes); + + for (i = 0; i < BG_ACTOR_MAX; i++) { + DynaLookup_ResetLists(&dyna->bgActors[i].dynaLookup); + } + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (dyna->bgActorFlags[i] & 2) { + // Initialize BgActor + dyna->bgActorFlags[i] = 0; + BgActor_Init(globalCtx, &dyna->bgActors[i]); + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } + if (dyna->bgActors[i].actor != NULL && dyna->bgActors[i].actor->update == NULL) { + // Delete BgActor + actor = DynaPoly_GetActor(&globalCtx->colCtx, i); + if (actor == NULL) { + return; + } + actor->bgId = BGACTOR_NEG_ONE; + dyna->bgActorFlags[i] = 0; + + BgActor_Init(globalCtx, &dyna->bgActors[i]); + dyna->bitFlag |= DYNAPOLY_INVALIDATE_LOOKUP; + } + } + vtxStartIndex = 0; + polyStartIndex = 0; + waterBoxStartIndex = 0; + for (i = 0; i < BG_ACTOR_MAX; i++) { + if ((dyna->bgActorFlags[i] & 1) && !(dyna->bgActorFlags[i] & 2)) { + DynaPoly_ExpandSRT(globalCtx, dyna, i, &vtxStartIndex, &polyStartIndex, &waterBoxStartIndex); + } + } + dyna->bitFlag &= ~DYNAPOLY_INVALIDATE_LOOKUP; +} + +/** + * Compute the number of dynamic resources in use? + */ +void func_800C756C(DynaCollisionContext* dyna, s32* numPolygons, s32* numVertices, s32* numWaterBoxes) { + s32 i; + CollisionHeader* colHeader; + + *numPolygons = 0; + *numVertices = 0; + *numWaterBoxes = 0; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if ((dyna->bgActorFlags[i] & 1) && !(dyna->bgActorFlags[i] & 2) && !(dyna->bgActorFlags[i] & 4)) { + colHeader = dyna->bgActors[i].colHeader; + *numPolygons += colHeader->numPolygons; + *numVertices += colHeader->numVertices; + *numWaterBoxes += colHeader->numWaterBoxes; + } + } +} + +/** + * Update all BgActor's previous ScaleRotPos + */ +void DynaPoly_UpdateBgActorTransforms(GlobalContext* globalCtx, DynaCollisionContext* dyna) { + s32 i; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (dyna->bgActorFlags[i] & 1) { + DynaPoly_SetBgActorPrevTransform(globalCtx, &dyna->bgActors[i]); + } + } +} + +/** + * Perform dyna poly raycast toward floor on a list of floor, wall, or ceiling polys + * `listType` specifies the poly list type (e.g. DYNA_RAYCAST_FLOORS) + */ +f32 BgCheck_RaycastFloorDynaList(DynaRaycast* dynaRaycast, u32 listType) { + CollisionPoly* polyList; + SSNode* curNode; + f32 result; + f32 yIntersect; + s16 id; + + result = dynaRaycast->yIntersect; + if (dynaRaycast->ssList->head == SS_NULL) { + return result; + } + polyList = dynaRaycast->dyna->polyList; + curNode = &dynaRaycast->dyna->polyNodes.tbl[dynaRaycast->ssList->head]; + + while (true) { + id = curNode->polyId; + if (COLPOLY_VIA_FLAG_TEST(polyList[id].flags_vIA, dynaRaycast->xpFlags) || + (COLPOLY_VIA_FLAG_TEST(polyList[id].flags_vIB, 4) && + ((dynaRaycast->actor != NULL && dynaRaycast->actor->category != ACTORCAT_PLAYER) || + (dynaRaycast->actor == NULL && dynaRaycast->xpFlags != COLPOLY_IGNORE_CAMERA))) || + ((dynaRaycast->unk_24 & 0x20) && func_800C9B68(dynaRaycast->colCtx, &polyList[id], dynaRaycast->unk1C))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dynaRaycast->dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + if ((listType & (DYNA_RAYCAST_WALLS | DYNA_RAYCAST_CEILINGS)) && (dynaRaycast->unk_24 & 0x10) && + COLPOLY_GET_NORMAL(polyList[id].normal.y) < 0.0f) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dynaRaycast->dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + if (CollisionPoly_CheckYIntersectApprox1(&polyList[id], dynaRaycast->dyna->vtxList, dynaRaycast->pos->x, + dynaRaycast->pos->z, &yIntersect, dynaRaycast->checkDist) && + yIntersect < dynaRaycast->pos->y && result < yIntersect) { + result = yIntersect; + *dynaRaycast->resultPoly = &dynaRaycast->dyna->polyList[id]; + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dynaRaycast->dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + return result; +} + +#ifdef NON_MATCHING +/** + * Perform dyna poly raycast toward floor + * returns the yIntersect of the poly found, or BGCHECK_Y_MIN if no poly is found + */ +f32 BgCheck_RaycastFloorDyna(DynaRaycast* dynaRaycast) { + s32 i; + f32 result; + f32 intersect2; + s32 i2; + s32 pauseState; + DynaPolyActor* dynaActor; + s32 pad; + Vec3f polyVtx[3]; + Vec3f polyNorm; + u32 polyIndex; + CollisionPoly* polyMin; + MtxF srpMtx; + f32 magnitude; + Vec3s* vtxList; + f32 polyDist; + Vec3f vtx; + f32 intersect; + ScaleRotPos* curTransform; + CollisionPoly* poly; + + result = BGCHECK_Y_MIN; + *dynaRaycast->bgId = BGCHECK_SCENE; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (!(dynaRaycast->colCtx->dyna.bgActorFlags[i] & 1) || (dynaRaycast->colCtx->dyna.bgActorFlags[i] & 2)) { + continue; + } + + if (dynaRaycast->actor == dynaRaycast->colCtx->dyna.bgActors[i].actor || + dynaRaycast->pos->y < dynaRaycast->colCtx->dyna.bgActors[i].minY || + !Math3D_XZInSphere(&dynaRaycast->colCtx->dyna.bgActors[i].boundingSphere, dynaRaycast->pos->x, + dynaRaycast->pos->z)) { + continue; + } + + dynaRaycast->unk1C = i; + dynaRaycast->dyna = &dynaRaycast->colCtx->dyna; + if (dynaRaycast->unk_24 & BGCHECK_IGNORE_FLOOR) { + dynaRaycast->ssList = &dynaRaycast->colCtx->dyna.bgActors[i].dynaLookup.floor; + intersect2 = BgCheck_RaycastFloorDynaList(dynaRaycast, DYNA_RAYCAST_FLOORS); + + if (dynaRaycast->yIntersect < intersect2) { + dynaRaycast->yIntersect = intersect2; + *dynaRaycast->bgId = i; + result = intersect2; + } + } + if ((dynaRaycast->unk_24 & BGCHECK_IGNORE_WALL) || + (*dynaRaycast->resultPoly == NULL && (dynaRaycast->unk_24 & 8))) { + dynaRaycast->ssList = &dynaRaycast->colCtx->dyna.bgActors[i].dynaLookup.wall; + intersect2 = BgCheck_RaycastFloorDynaList(dynaRaycast, DYNA_RAYCAST_WALLS); + if (dynaRaycast->yIntersect < intersect2) { + + dynaRaycast->yIntersect = intersect2; + *dynaRaycast->bgId = i; + result = intersect2; + } + } + + if (dynaRaycast->unk_24 & BGCHECK_IGNORE_CEILING) { + dynaRaycast->ssList = &dynaRaycast->colCtx->dyna.bgActors[i].dynaLookup.ceiling; + intersect2 = BgCheck_RaycastFloorDynaList(dynaRaycast, DYNA_RAYCAST_CEILINGS); + if (dynaRaycast->yIntersect < intersect2) { + + dynaRaycast->yIntersect = intersect2; + *dynaRaycast->bgId = i; + result = intersect2; + } + } + } + + dynaActor = DynaPoly_GetActor(dynaRaycast->colCtx, *dynaRaycast->bgId); + if ((result != BGCHECK_Y_MIN) && (dynaActor != NULL) && (dynaRaycast->globalCtx != NULL)) { + pauseState = dynaRaycast->globalCtx->pauseCtx.state != 0; + if (!pauseState) { + pauseState = dynaRaycast->globalCtx->pauseCtx.debugState != 0; + } + if (!pauseState && (dynaRaycast->colCtx->dyna.bgActorFlags[*dynaRaycast->bgId] & 2)) { + curTransform = &dynaRaycast->dyna->bgActors[*dynaRaycast->bgId].curTransform; + polyMin = &dynaRaycast->dyna + ->polyList[(u16)dynaRaycast->dyna->bgActors[*dynaRaycast->bgId].dynaLookup.polyStartIndex]; + polyIndex = *dynaRaycast->resultPoly - polyMin; + poly = &dynaRaycast->dyna->bgActors[*dynaRaycast->bgId].colHeader->polyList[polyIndex]; + + SkinMatrix_SetScaleRotateYRPTranslate(&srpMtx, curTransform->scale.x, curTransform->scale.y, + curTransform->scale.z, curTransform->rot.x, curTransform->rot.y, + curTransform->rot.z, curTransform->pos.x, curTransform->pos.y, + curTransform->pos.z); + + vtxList = dynaRaycast->dyna->bgActors[*dynaRaycast->bgId].colHeader->vtxList; + + for (i2 = 0; i2 < 3; i2++) { + Math_Vec3s_ToVec3f(&vtx, &vtxList[COLPOLY_VTX_INDEX(poly->vtxData[i2])]); + SkinMatrix_Vec3fMtxFMultXYZ(&srpMtx, &vtx, &polyVtx[i2]); + } + Math3D_SurfaceNorm(&polyVtx[0], &polyVtx[1], &polyVtx[2], &polyNorm); + magnitude = Math3D_Vec3fMagnitude(&polyNorm); + + if (!IS_ZERO(magnitude)) { + polyNorm.x *= 1.0f / magnitude; + polyNorm.y *= 1.0f / magnitude; + polyNorm.z *= 1.0f / magnitude; + polyDist = -DOTXYZ(polyNorm, polyVtx[0]); + if (Math3D_TriChkPointParaYIntersectInsideTri( + &polyVtx[0], &polyVtx[1], &polyVtx[2], polyNorm.x, polyNorm.y, polyNorm.z, polyDist, + dynaRaycast->pos->z, dynaRaycast->pos->x, &intersect, dynaRaycast->checkDist)) { + if (fabsf(intersect - result) < 1.0f) { + + result = intersect; + } + } + } + } + } + return result; +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RaycastFloorDyna.s") +#endif + +/** + * Performs collision detection on a BgActor's wall polys on sphere `pos`, `radius` + * returns true if a collision was detected + * `outX` `outZ` return the displaced x,z coordinates + * `outPoly` returns the pointer to the nearest poly collided with, or NULL + * `outBgId` returns `bgId` if the poly SurfaceType's wall damage flag is not set, 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) { + f32 temp; + f32 intersect; + s32 result = false; + CollisionPoly* poly; + SSNode* curNode; + f32 nx; + f32 ny; + f32 nz; + Vec3f resultPos; + s16 polyId; + f32 zTemp; + f32 xTemp; + f32 normalXZ; + f32 invNormalXZ; + f32 planeDist; + f32 temp_f18; + f32 zMin; + f32 zMax; + f32 xMin; + f32 xMax; + + if (ssList->head == SS_NULL) { + return result; + } + + resultPos = *pos; + curNode = &dyna->polyNodes.tbl[ssList->head]; + + while (true) { + polyId = curNode->polyId; + poly = &dyna->polyList[polyId]; + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + normalXZ = sqrtf(SQ(nx) + SQ(nz)); + + planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos); + if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags) || + ((COLPOLY_VIA_FLAG_TEST(poly->flags_vIB, 4)) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + invNormalXZ = 1.0f / normalXZ; + temp_f18 = fabsf(nz) * invNormalXZ; + if (temp_f18 < 0.4f) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + + // compute poly zMin/zMax + zTemp = dyna->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)].z; + zMax = zMin = zTemp; + + zTemp = dyna->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)].z; + if (zTemp < zMin) { + zMin = zTemp; + } else if (zTemp > zMax) { + zMax = zTemp; + } + + zTemp = dyna->vtxList[poly->vIC].z; + if (zTemp < zMin) { + zMin = zTemp; + } else if (zMax < zTemp) { + zMax = zTemp; + } + + zMin -= radius; + zMax += radius; + if (resultPos.z < zMin || zMax < resultPos.z) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + 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, + invNormalXZ, planeDist, radius, outPoly)) { + *outBgId = bgId; + } + result = true; + } + } + } + if (curNode->next == SS_NULL) { + break; + } + curNode = &dyna->polyNodes.tbl[curNode->next]; + } + + curNode = &dyna->polyNodes.tbl[ssList->head]; + while (true) { + polyId = curNode->polyId; + poly = &dyna->polyList[polyId]; + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + normalXZ = sqrtf(SQ(nx) + SQ(nz)); + + planeDist = Math3D_DistPlaneToPos(nx, ny, nz, poly->dist, &resultPos); + if (radius < fabsf(planeDist) || COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(poly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + + invNormalXZ = 1.0f / normalXZ; + temp_f18 = fabsf(nx) * invNormalXZ; + if (temp_f18 < 0.4f) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + + // compute poly xMin/xMax + xTemp = dyna->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)].x; + xMax = xMin = xTemp; + xTemp = dyna->vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)].x; + + if (xTemp < xMin) { + xMin = xTemp; + } else if (xMax < xTemp) { + xMax = xTemp; + } + xTemp = dyna->vtxList[poly->vIC].x; + if (xTemp < xMin) { + xMin = xTemp; + } else if (xMax < xTemp) { + xMax = xTemp; + } + + xMin -= radius; + xMax += radius; + if (resultPos.x < xMin || xMax < resultPos.x) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + + if (CollisionPoly_CheckXIntersectApprox(poly, dyna->vtxList, pos->y, resultPos.z, &intersect)) { + 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, + invNormalXZ, planeDist, radius, outPoly)) { + *outBgId = bgId; + } + result = true; + } + } + } + if (curNode->next == SS_NULL) { + break; + } + curNode = &dyna->polyNodes.tbl[curNode->next]; + } + *outX = resultPos.x; + *outZ = resultPos.z; + return result; +} + +/** + * Performs collision detection on all dyna poly walls using sphere `pos`, `radius` + * returns true if a collision was detected + * `outX` `outZ` return the displaced x,z coordinates + * `outPoly` returns the pointer to the nearest poly collided with, or NULL + * `outBgId` returns the index of the BgActor that owns `outPoly` + * If `actor` is not NULL, an BgActor bound to that actor will be ignored + */ +s32 BgCheck_SphVsDynaWall(CollisionContext* colCtx, u16 xpFlags, f32* outX, f32* outZ, Vec3f* pos, f32 radius, + CollisionPoly** outPoly, s32* outBgId, Actor* actor) { + Vec3f resultPos; + s32 result; + f32 r; + f32 dz; + f32 dx; + BgActor* bgActor; + s32 i; + + result = false; + resultPos = *pos; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (!(colCtx->dyna.bgActorFlags[i] & 1) || (colCtx->dyna.bgActorFlags[i] & 2)) { + continue; + } + if ((colCtx->dyna.bgActors + i)->actor == actor) { + continue; + } + bgActor = &colCtx->dyna.bgActors[i]; + + if (bgActor->minY > resultPos.y || bgActor->maxY < resultPos.y) { + continue; + } + + bgActor->boundingSphere.radius += (s16)radius; + + r = bgActor->boundingSphere.radius; + dx = bgActor->boundingSphere.center.x - resultPos.x; + dz = bgActor->boundingSphere.center.z - resultPos.z; + if (SQ(r) < (SQ(dx) + SQ(dz)) || (!Math3D_XYInSphere(&bgActor->boundingSphere, resultPos.x, resultPos.y) && + !Math3D_YZInSphere(&bgActor->boundingSphere, resultPos.y, resultPos.z))) { + bgActor->boundingSphere.radius -= (s16)radius; + continue; + } + bgActor->boundingSphere.radius -= (s16)radius; + if (BgCheck_SphVsDynaWallInBgActor(colCtx, xpFlags, &colCtx->dyna, + &(colCtx->dyna.bgActors + i)->dynaLookup.wall, outX, outZ, outPoly, outBgId, + &resultPos, radius, i, actor)) { + resultPos.x = *outX; + resultPos.z = *outZ; + result = true; + } + } + return result; +} + +/** + * Tests for collision with a dyna poly ceiling, starting at `ssList` + * returns true if a collision occurs, else false + * `outPoly` returns the poly collided with + * `outY` returns the y coordinate needed to not collide with `outPoly` + */ +s32 BgCheck_CheckDynaCeilingList(CollisionContext* colCtx, u16 xpFlags, DynaCollisionContext* dyna, SSList* ssList, + f32* outY, Vec3f* pos, f32 checkHeight, CollisionPoly** outPoly, Actor* actor, + s32 bgId) { + s16 polyId; + SSNode* curNode; + CollisionPoly* poly; + Vec3f testPos; + f32 ceilingY; + f32 sign; + f32 nx; + f32 ny; + f32 nz; + s32 result = false; + f32 intersectDist; + u16 padding; + + if (ssList->head == SS_NULL) { + return false; + } + curNode = &dyna->polyNodes.tbl[ssList->head]; + testPos = *pos; + + while (true) { + polyId = curNode->polyId; + poly = &dyna->polyList[polyId]; + if (COLPOLY_VIA_FLAG_TEST(poly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(poly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + CollisionPoly_GetNormalF(poly, &nx, &ny, &nz); + if (checkHeight < Math3D_UDistPlaneToPos(nx, ny, nz, poly->dist, &testPos)) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + if (CollisionPoly_CheckYIntersectApprox2(poly, dyna->vtxList, testPos.x, testPos.z, &ceilingY)) { + intersectDist = ceilingY - testPos.y; + if (testPos.y < ceilingY && intersectDist < checkHeight && intersectDist * ny <= 0.0f) { + sign = (0.0f <= ny) ? 1.0f : -1.0f; + testPos.y = (sign * checkHeight) + ceilingY; + result = true; + *outPoly = poly; + } + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + *outY = testPos.y; + return result; +} + +/** + * Tests collision with a dyna poly ceiling + * returns true if a collision occurs, else false + * `outPoly` returns the poly collided with, while `outBgId` returns the id of the BgActor that owns the poly + * `outY` returns the y coordinate needed to not collide with `outPoly`, or `pos`.y + `checkDist` if no collision occurs + */ +s32 BgCheck_CheckDynaCeiling(CollisionContext* colCtx, u16 xpFlags, f32* outY, Vec3f* pos, f32 checkDist, + CollisionPoly** outPoly, s32* outBgId, Actor* actor) { + s32 i; + s32 result = false; + f32 resultY; + f32 tempY = checkDist + pos->y; + BgActor* bgActor; + CollisionPoly* poly; + + resultY = tempY; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (!(colCtx->dyna.bgActorFlags[i] & 1) || (colCtx->dyna.bgActorFlags[i] & 2)) { + continue; + } + if (actor == colCtx->dyna.bgActors[i].actor) { + continue; + } + if (!Math3D_XZInSphere(&colCtx->dyna.bgActors[i].boundingSphere, pos->x, pos->z)) { + continue; + } + if (BgCheck_CheckDynaCeilingList(colCtx, xpFlags, &colCtx->dyna, &colCtx->dyna.bgActors[i].dynaLookup.ceiling, + &tempY, pos, checkDist, &poly, actor, i) && + tempY < resultY) { + + resultY = tempY; + *outPoly = poly; + *outBgId = i; + result = true; + } + } + *outY = resultY; + return result; +} + +/** + * Tests if DynaLineTest intersects with a poly + * returns true if a poly was intersected, else false + */ +s32 BgCheck_CheckLineAgainstBgActorSSList(DynaLineTest* dynaLineTest) { + f32 distSq; + s32 result; + SSNode* curNode; + Vec3f polyIntersect; + s16 polyId; + BgLineVsPolyTest test; + + result = false; + if (dynaLineTest->ssList->head == SS_NULL) { + return result; + } + curNode = &dynaLineTest->dyna->polyNodes.tbl[dynaLineTest->ssList->head]; + + test.vtxList = dynaLineTest->dyna->vtxList; + test.posA = dynaLineTest->posA; + test.posB = dynaLineTest->posB; + test.planeIntersect = &polyIntersect; + test.checkOneFace = dynaLineTest->checkOneFace; + test.checkDist = dynaLineTest->checkDist; + + while (true) { + polyId = curNode->polyId; + test.poly = &dynaLineTest->dyna->polyList[polyId]; + if (COLPOLY_VIA_FLAG_TEST(test.poly->flags_vIA, dynaLineTest->xpFlags) || + (COLPOLY_VIA_FLAG_TEST(test.poly->flags_vIB, 4) && + ((dynaLineTest->actor != NULL && dynaLineTest->actor->category != ACTORCAT_PLAYER) || + (dynaLineTest->actor == NULL && dynaLineTest->xpFlags != COLPOLY_IGNORE_CAMERA)))) { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dynaLineTest->dyna->polyNodes.tbl[curNode->next]; + } + } else { + if (CollisionPoly_LineVsPoly(&test)) { + distSq = Math3D_Vec3fDistSq(dynaLineTest->posA, test.planeIntersect); + if (distSq < *dynaLineTest->distSq) { + *dynaLineTest->distSq = distSq; + *dynaLineTest->posResult = *test.planeIntersect; + *dynaLineTest->posB = *test.planeIntersect; + *dynaLineTest->resultPoly = test.poly; + result = true; + } + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dynaLineTest->dyna->polyNodes.tbl[curNode->next]; + } + } + } + return result; +} + +/** + * Tests if line `posA` `posB` intersects with a dyna poly within BgActor `bgId` + * `distSq` is the maximum squared distance to check for a collision + * returns true if an intersection occurred, else false + * `posB`? and `posResult` return the point of intersection + * `outPoly` returns the poly intersected + * `distSq` returns the squared distance of the intersection + */ +s32 BgCheck_CheckLineAgainstBgActor(CollisionContext* colCtx, u16 xpFlags, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, f32* distSq, s32 bgId, f32 checkDist, s32 bccFlags, + Actor* actor) { + s32 result = false; + DynaLineTest dynaLineTest; + + dynaLineTest.colCtx = colCtx; + dynaLineTest.xpFlags = xpFlags; + dynaLineTest.dyna = &colCtx->dyna; + dynaLineTest.posA = posA; + dynaLineTest.posB = posB; + dynaLineTest.posResult = posResult; + dynaLineTest.resultPoly = outPoly; + dynaLineTest.checkOneFace = (bccFlags & BGCHECK_CHECK_ONE_FACE) != 0; + dynaLineTest.distSq = distSq; + dynaLineTest.checkDist = checkDist; + dynaLineTest.actor = actor; + dynaLineTest.bgId = bgId; + + dynaLineTest.ssList = &colCtx->dyna.bgActors[bgId].dynaLookup.wall; + if (bccFlags & BGCHECK_CHECK_WALL) { + if (BgCheck_CheckLineAgainstBgActorSSList(&dynaLineTest)) { + result = true; + } + } + dynaLineTest.ssList = &colCtx->dyna.bgActors[bgId].dynaLookup.floor; + if (bccFlags & BGCHECK_CHECK_FLOOR) { + if (BgCheck_CheckLineAgainstBgActorSSList(&dynaLineTest)) { + result = true; + } + } + dynaLineTest.ssList = &colCtx->dyna.bgActors[bgId].dynaLookup.ceiling; + if (bccFlags & BGCHECK_CHECK_CEILING) { + if (BgCheck_CheckLineAgainstBgActorSSList(&dynaLineTest)) { + result = true; + } + } + return result; +} + +/** + * Tests if line from `posA` to `posB` passes through a dyna poly. + * returns true if so, otherwise false + * `outPoly` returns the pointer of the poly intersected. + * `outBgId` returns the BgActor index of the poly + */ +s32 BgCheck_CheckLineAgainstDyna(CollisionContext* colCtx, u16 xpFlags, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** outPoly, f32* distSq, s32* outBgId, Actor* actor, f32 checkDist, + s32 bccFlags) { + s32 pad; + s32 i; + s32 result = false; + LineSegment line; + f32 ay; + f32 by; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if ((colCtx->dyna.bgActorFlags[i] & 1) && !(colCtx->dyna.bgActorFlags[i] & 2)) { + if (actor != colCtx->dyna.bgActors[i].actor) { + ay = posA->y; + by = posB->y; + if (!(ay < colCtx->dyna.bgActors[i].minY) || !(by < colCtx->dyna.bgActors[i].minY)) { + if (!(colCtx->dyna.bgActors[i].maxY < ay) || !(colCtx->dyna.bgActors[i].maxY < by)) { + line.a = *posA; + line.b = *posB; + if (Math3D_LineVsSph(&colCtx->dyna.bgActors[i].boundingSphere, &line) != 0) { + if (BgCheck_CheckLineAgainstBgActor(colCtx, xpFlags, posA, posB, posResult, outPoly, distSq, + i, checkDist, bccFlags, actor)) { + *outBgId = i; + result = true; + } + } + } + } + } + } + } + return result; +} + +/** + * Get first dyna poly intersecting sphere `center` `radius` from list `ssList` + * returns true if any poly intersects the sphere, else returns false + * `outPoly` returns the pointer of the first poly found that intersects + */ +s32 BgCheck_SphVsFirstDynaPolyList(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, Vec3f* center, + f32 radius, SSList* ssList, Actor* actor, s32 bgId) { + CollisionPoly* curPoly; + DynaCollisionContext* dyna; + SSNode* curNode; + s32 curPolyId; + + if (ssList->head == SS_NULL) { + return false; + } + dyna = &colCtx->dyna; + curNode = &dyna->polyNodes.tbl[ssList->head]; + while (true) { + curPolyId = curNode->polyId; + curPoly = &dyna->polyList[curPolyId]; + if (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIA, xpFlags) || + (COLPOLY_VIA_FLAG_TEST(curPoly->flags_vIB, 4) && ((actor != NULL && actor->category != ACTORCAT_PLAYER) || + (actor == NULL && xpFlags != COLPOLY_IGNORE_CAMERA)))) + + { + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + if (CollisionPoly_SphVsPoly(curPoly, dyna->vtxList, center, radius)) { + *outPoly = curPoly; + return true; + } + if (curNode->next == SS_NULL) { + break; + } else { + curNode = &dyna->polyNodes.tbl[curNode->next]; + continue; + } + } + return false; +} + +/** + * Get first dyna poly intersecting sphere `center` `radius` from BgActor `bgId` + * returns true if any poly intersects the sphere, else false + * `outPoly` returns the pointer of the first poly found that intersects + */ +s32 BgCheck_SphVsFirstDynaPolyInBgActor(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, Vec3f* center, + f32 radius, s32 bgId, u16 bciFlags, Actor* actor) { + if (!(bciFlags & BGCHECK_IGNORE_CEILING)) { + if (BgCheck_SphVsFirstDynaPolyList(colCtx, xpFlags, outPoly, center, radius, + &colCtx->dyna.bgActors[bgId].dynaLookup.ceiling, actor, bgId)) { + return true; + } + } + if (!(bciFlags & BGCHECK_IGNORE_WALL)) { + if (BgCheck_SphVsFirstDynaPolyList(colCtx, xpFlags, outPoly, center, radius, + &colCtx->dyna.bgActors[bgId].dynaLookup.wall, actor, bgId)) { + return true; + } + } + if (!(bciFlags & BGCHECK_IGNORE_FLOOR)) { + if (BgCheck_SphVsFirstDynaPolyList(colCtx, xpFlags, outPoly, center, radius, + &colCtx->dyna.bgActors[bgId].dynaLookup.floor, actor, bgId)) { + return true; + } + } + return false; +} + +/** + * Gets first dyna poly intersecting sphere `center` `radius` + * returns true if poly detected, else false + * `outPoly` returns the first intersecting poly, while `outBgId` returns the BgActor index of that poly + */ +s32 BgCheck_SphVsFirstDynaPoly(CollisionContext* colCtx, u16 xpFlags, CollisionPoly** outPoly, s32* outBgId, + Vec3f* center, f32 radius, Actor* actor, u16 bciFlags) { + s32 i = 0; + Sphere16 testSphere; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (!(colCtx->dyna.bgActorFlags[i] & 1) || (colCtx->dyna.bgActorFlags[i] & 2)) { + continue; + } + if (colCtx->dyna.bgActors[i].actor == actor) { + continue; + } + testSphere.center.x = center->x; + testSphere.center.y = center->y; + testSphere.center.z = center->z; + testSphere.radius = radius; + if (!Math3D_SphVsSph(&testSphere, &colCtx->dyna.bgActors[i].boundingSphere)) { + continue; + } + if (BgCheck_SphVsFirstDynaPolyInBgActor(colCtx, xpFlags, outPoly, center, radius, i, bciFlags, actor)) { + return true; + } + } + return false; +} + +/** + * SEGMENTED_TO_VIRTUAL CollisionHeader members + */ +void CollisionHeader_SegmentedToVirtual(CollisionHeader* colHeader) { + colHeader->vtxList = Lib_SegmentedToVirtual(colHeader->vtxList); + colHeader->polyList = Lib_SegmentedToVirtual(colHeader->polyList); + if (colHeader->surfaceTypeList) { + colHeader->surfaceTypeList = Lib_SegmentedToVirtual(colHeader->surfaceTypeList); + } + if (colHeader->cameraDataList) { + colHeader->cameraDataList = Lib_SegmentedToVirtual(colHeader->cameraDataList); + } + if (colHeader->waterBoxes) { + colHeader->waterBoxes = Lib_SegmentedToVirtual(colHeader->waterBoxes); + } +} + +/** + * Convert CollisionHeader Segmented to Virtual addressing + */ +void CollisionHeader_GetVirtual(CollisionHeader* colHeader, CollisionHeader** dest) { + *dest = Lib_SegmentedToVirtual(colHeader); + CollisionHeader_SegmentedToVirtual(*dest); +} + +/** + * SEGMENT_TO_VIRTUAL all active BgActor CollisionHeaders + */ +void BgCheck_InitCollisionHeaders(CollisionContext* colCtx, GlobalContext* globalCtx) { + DynaCollisionContext* dyna = &colCtx->dyna; + s32 i; + u16 flag; + + for (i = 0; i < BG_ACTOR_MAX; i++) { + flag = dyna->bgActorFlags[i]; + if ((flag & 1) && !(flag & 2)) { + Actor_SetObjectDependency(globalCtx, dyna->bgActors[i].actor); + CollisionHeader_SegmentedToVirtual(dyna->bgActors[i].colHeader); + } + } +} + +/** + * Reset SSNodeList polyCheckTbl + */ +void BgCheck_ResetPolyCheckTbl(SSNodeList* nodeList, s32 numPolys) { + u8* end = nodeList->polyCheckTbl + numPolys; + u8* t; + + for (t = nodeList->polyCheckTbl; t < end; t++) { + *t = 0; + } +} + +/** + * Get SurfaceType property set + */ +u32 SurfaceType_GetData(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId, s32 dataIdx) { + CollisionHeader* colHeader; + SurfaceType* surfaceTypes; + + colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + if (colHeader == NULL || poly == NULL) { + return 0; + } + surfaceTypes = colHeader->surfaceTypeList; + if (surfaceTypes == NULL) { + return 0; + } + return surfaceTypes[poly->type].data[dataIdx]; +} + +/** + * SurfaceType return CamData Index + */ +u32 SurfaceType_GetCamDataIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) & 0xFF; +} + +/** + * CamData return camera setting + */ +u16 func_800C9728(CollisionContext* colCtx, u32 camId, s32 bgId) { + u16 result; + CollisionHeader* colHeader; + CamData* camData; + + colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + if (colHeader == NULL) { + return 0; + } + camData = colHeader->cameraDataList; + result = camData[camId].setting; + return result; +} + +/** + * SurfaceType return camera setting + */ +u16 SurfaceType_GetCameraSetting(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + CollisionHeader* colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + CamData* camData; + SurfaceType* surfaceTypes; + + if (colHeader == NULL) { + return 0; + } + camData = colHeader->cameraDataList; + if (camData == NULL) { + return 0; + } + surfaceTypes = colHeader->surfaceTypeList; + if (surfaceTypes == NULL) { + return 0; + } + return func_800C9728(colCtx, SurfaceType_GetCamDataIndex(colCtx, poly, bgId), bgId); +} + +/** + * CamData get number of camera data blocks + */ +u16 func_800C97F8(CollisionContext* colCtx, u32 camId, s32 bgId) { + CollisionHeader* colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + CamData* camData; + + if (colHeader == NULL) { + return 0; + } + + camData = colHeader->cameraDataList; + if (camData == NULL) { + return 0; + } + return camData[camId].numData; +} + +/** + * SurfaceType get number of camera data blocks + */ +u16 func_800C9844(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + CollisionHeader* colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + CamData* camData; + SurfaceType* surfaceTypes; + + if (colHeader == NULL) { + return 0; + } + camData = colHeader->cameraDataList; + if (camData == NULL) { + return 0; + } + surfaceTypes = colHeader->surfaceTypeList; + if (surfaceTypes == NULL) { + return 0; + } + return func_800C97F8(colCtx, SurfaceType_GetCamDataIndex(colCtx, poly, bgId), bgId); +} + +/** + * CamData get data + */ +Vec3s* func_800C98CC(CollisionContext* colCtx, s32 camId, s32 bgId) { + CollisionHeader* colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + CamData* cameraDataList; + + if (colHeader == NULL) { + return NULL; + } + cameraDataList = colHeader->cameraDataList; + if (cameraDataList == NULL) { + return NULL; + } + return Lib_SegmentedToVirtual(cameraDataList[camId].data); +} + +/** + * SurfaceType Get data + */ +Vec3s* SurfaceType_GetCamPosData(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + CollisionHeader* colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + CamData* camData; + SurfaceType* surfaceTypes; + + if (colHeader == NULL) { + return NULL; + } + camData = colHeader->cameraDataList; + if (camData == NULL) { + return NULL; + } + surfaceTypes = colHeader->surfaceTypeList; + if (surfaceTypes == NULL) { + return NULL; + } + return func_800C98CC(colCtx, SurfaceType_GetCamDataIndex(colCtx, poly, bgId), bgId); +} + +/** + * SurfaceType Get Scene Exit Index + */ +u32 SurfaceType_GetSceneExitIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 8 & 0x1F; +} + +/** + * SurfaceType Get ? Property (& 0x0003_E000) + */ +u32 func_800C99D4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 13 & 0x1F; +} + +/** + * SurfaceType Get ? Property (& 0x001C_0000) + */ +u32 func_800C99FC(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 18 & 7; +} + +/** + * SurfaceType Get Wall Property (Internal) + */ +u32 func_800C9A24(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 21 & 0x1F; +} + +/** + * SurfaceType Get Wall Flags + */ +s32 func_800C9A4C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return sWallFlags[func_800C9A24(colCtx, poly, bgId)]; +} + +/** + * SurfaceType Is Wall Flag (1 << 0) Set + */ +s32 func_800C9A7C(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return (func_800C9A4C(colCtx, poly, bgId) & 1) ? true : false; +} + +/** + * SurfaceType Is Wall Flag (1 << 1) Set + */ +s32 func_800C9AB0(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return (func_800C9A4C(colCtx, poly, bgId) & 2) ? true : false; +} + +/** + * SurfaceType Is Wall Flag (1 << 2) Set + */ +s32 func_800C9AE4(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return (func_800C9A4C(colCtx, poly, bgId) & 4) ? true : false; +} + +u32 func_800C9B18(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 26 & 0xF; +} + +/** + * SurfaceType Get Floor Property + */ +u32 func_800C9B40(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 26 & 0xF; +} + +/** + * SurfaceType Is Floor Minus 1 + */ +u32 func_800C9B68(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 30 & 1; +} + +/** + * SurfaceType Is Horse Blocked + */ +u32 SurfaceType_IsHorseBlocked(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 0) >> 31 & 1; +} + +u32 func_800C9BB8(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) & 0xF; +} + +/** + * SurfaceType Get Poly Sfx + */ +u16 SurfaceType_GetSfx(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + s32 id = func_800C9BB8(colCtx, poly, bgId); + + if (id < 0 || id > 14) { + return NA_SE_PL_WALK_GROUND - SFX_FLAG; + } + return sSurfaceTypeSfx[id]; +} + +/** + * SurfaceType Get ? (same indexer as Get Poly Sfx) + */ +s32 func_800C9C24(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId, s32 arg3) { + s32 id = func_800C9BB8(colCtx, poly, bgId); + + if (id < 0 || id > 14) { + return 0; + } + return D_801B46C0[id] & arg3; +} + +/** + * SurfaceType get terrain slope surface + */ +u32 SurfaceType_GetSlope(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) >> 4 & 3; +} + +/** + * SurfaceType get surface lighting setting + */ +u32 SurfaceType_GetLightSettingIndex(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) >> 6 & 0x1F; +} + +/** + * SurfaceType get echo + */ +u32 SurfaceType_GetEcho(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) >> 11 & 0x3F; +} + +/** + * SurfaceType Is Hookshot Surface + */ +u32 SurfaceType_IsHookshotSurface(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) >> 17 & 1; +} + +/** + * CollisionPoly is ignored by entities + * Returns true if poly is ignored by entities, else false + */ +s32 SurfaceType_IsIgnoredByEntities(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + u32 flags; + + if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { + return true; + } + flags = poly->flags_vIA & 0x4000; + return !!flags; +} + +/** + * CollisionPoly is ignored by projectiles + * Returns true if poly is ignored by projectiles, else false + */ +s32 SurfaceType_IsIgnoredByProjectiles(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + u32 flags; + + if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { + return true; + } + flags = poly->flags_vIA & 0x8000; + return !!flags; +} + +/** + * SurfaceType Get Conveyor Surface Type + * Return type 0 (CONVEYOR_WATER) if 'poly' is a surface that will only move player underwater + * Return type 1 (CONVEYOR_FLOOR) if `poly` is a surface that must be stood on to move player + */ +s32 SurfaceType_GetConveyorType(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + u32 flags; + + if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { + return CONVEYOR_FLOOR; + } + if (poly == NULL) { + return CONVEYOR_WATER; + } + flags = poly->flags_vIB & 0x2000; + return !!flags; +} + +s32 func_800C9DDC(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + u32 flags; + + if (BgCheck_GetCollisionHeader(colCtx, bgId) == NULL) { + return true; + } + flags = poly->flags_vIB & 0x4000; + return !!flags; +} + +/** + * SurfaceType Get Conveyor Surface Speed + */ +u32 SurfaceType_GetConveyorSpeed(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return SurfaceType_GetData(colCtx, poly, bgId, 1) >> 18 & 7; +} + +/** + * SurfaceType Get Conveyor Direction + * returns a value between 0-63, representing 360 / 64 degrees of rotation + */ +u32 SurfaceType_GetConveyorDirection(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + u32 data; + + data = SurfaceType_GetData(colCtx, poly, bgId, 1) >> 21; + if (colCtx->flags & 1) { + data += 0x20; + } + return data & 0x3F; +} + +/** + * SurfaceType is Wall Damage + */ +u32 SurfaceType_IsWallDamage(CollisionContext* colCtx, CollisionPoly* poly, s32 bgId) { + return (SurfaceType_GetData(colCtx, poly, bgId, 1) & 0x8000000) ? true : false; +} + +/** + * Internal. Get the water surface at point (`x`, `ySurface`, `z`). `ySurface` doubles as position y input + * returns true if point is within the xz boundaries of an active water box, else false + * `ySurface` returns the water box's surface, while `outWaterBox` returns a pointer to the WaterBox + */ +s32 WaterBox_GetSurfaceImpl(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, + WaterBox** outWaterBox, s32* bgId) { + CollisionHeader* colHeader; + u32 room; + WaterBox* curWaterBox; + s32 i; + + *bgId = BGCHECK_SCENE; + colHeader = colCtx->colHeader; + + if (colHeader->numWaterBoxes != 0 && colHeader->waterBoxes != NULL) { + for (curWaterBox = colHeader->waterBoxes; curWaterBox < colHeader->waterBoxes + colHeader->numWaterBoxes; + curWaterBox++) { + room = 0x3F & (curWaterBox->properties >> 13); + if (room == (u32)globalCtx->roomCtx.currRoom.num || room == 0x3F) { + if (curWaterBox->properties & 0x80000) { + continue; + } + if (curWaterBox->minPos.x < x && x < curWaterBox->minPos.x + curWaterBox->xLength) { + if (curWaterBox->minPos.z < z && z < curWaterBox->minPos.z + curWaterBox->zLength) { + *outWaterBox = curWaterBox; + *ySurface = curWaterBox->minPos.y; + return true; + } + } + } + } + } + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if (colCtx->dyna.bgActorFlags[i] & 1) { + BgActor* bgActor; + if (colCtx->dyna.bgActorFlags[i] & 4) { + continue; + } + bgActor = &colCtx->dyna.bgActors[i]; + if (bgActor->colHeader->numWaterBoxes != 0 && bgActor->colHeader->waterBoxes != NULL) { + for (curWaterBox = colCtx->dyna.waterBoxList.boxes + bgActor->waterboxesStartIndex; + curWaterBox < colCtx->dyna.waterBoxList.boxes + bgActor->waterboxesStartIndex + + bgActor->colHeader->numWaterBoxes; + curWaterBox++) { + if (curWaterBox->properties & 0x80000) { + continue; + } + if (curWaterBox->minPos.x < x && x < curWaterBox->minPos.x + curWaterBox->xLength) { + if (curWaterBox->minPos.z < z && z < curWaterBox->minPos.z + curWaterBox->zLength) { + *outWaterBox = curWaterBox; + *ySurface = curWaterBox->minPos.y; + *bgId = i; + return true; + } + } + } + } + } + } + return false; +} + +// boolean +s32 WaterBox_GetSurface1(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, + WaterBox** outWaterBox) { + return WaterBox_GetSurface1_2(globalCtx, colCtx, x, z, ySurface, outWaterBox); +} + +// boolean +s32 WaterBox_GetSurface1_2(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, + WaterBox** outWaterBox) { + s32 bgId; + return WaterBox_GetSurfaceImpl(globalCtx, colCtx, x, z, ySurface, outWaterBox, &bgId); +} + +#ifdef NON_MATCHING +/** + * Gets the first active WaterBox at `pos` where WaterBox.properties & 0x80000 == 0 + * `surfaceCheckDist` is the absolute y distance from the water surface to check + * returns the index of the waterbox found, or -1 if no waterbox is found + * `outWaterBox` returns the pointer to the waterbox found, or NULL if none is found + */ +s32 WaterBox_GetSurface2(GlobalContext* globalCtx, CollisionContext* colCtx, Vec3f* pos, f32 surfaceCheckDist, + WaterBox** outWaterBox, s32* bgId) { + CollisionHeader* colHeader; + s32 room; + s32 i; + WaterBox* waterBox; + + *bgId = BGCHECK_SCENE; + colHeader = colCtx->colHeader; + + //! @bug: check skips testing BgActor waterboxes + if (colHeader->numWaterBoxes == 0 || colHeader->waterBoxes == NULL) { + *outWaterBox = NULL; + return -1; + } + + for (i = 0; i < colHeader->numWaterBoxes; i++) { + waterBox = &colHeader->waterBoxes[i]; + + room = WATERBOX_ROOM(waterBox->properties); + if (!(room == globalCtx->roomCtx.currRoom.num || room == 0x3F)) { + continue; + } + if ((waterBox->properties & 0x80000)) { + continue; + } + if ((waterBox->minPos.x < pos->x && pos->x < waterBox->minPos.x + waterBox->xLength)) { + if ((waterBox->minPos.z < pos->z && pos->z < waterBox->minPos.z + waterBox->zLength)) { + if (pos->y - surfaceCheckDist < waterBox->minPos.y && waterBox->minPos.y < pos->y + surfaceCheckDist) { + *outWaterBox = waterBox; + return i; + } + } + } + } + + for (i = 0; i < BG_ACTOR_MAX; i++) { + WaterBox* iterator; + WaterBox* start; + BgActor* bgActor; + if (!(colCtx->dyna.bgActorFlags[i] & 1) || (colCtx->dyna.bgActorFlags[i] & 4) || + (colCtx->dyna.bgActorFlags[i] & 2)) { + continue; + } + bgActor = &colCtx->dyna.bgActors[i]; + for (iterator = colCtx->dyna.waterBoxList.boxes + bgActor->waterboxesStartIndex; + iterator < + colCtx->dyna.waterBoxList.boxes + bgActor->waterboxesStartIndex + bgActor->colHeader->numWaterBoxes; + iterator++) { + if (iterator->properties & 0x80000) { + continue; + } + if ((iterator->minPos.x < pos->x) && pos->x < iterator->minPos.x + iterator->xLength) { + if ((iterator->minPos.z < pos->z) && pos->z < iterator->minPos.z + iterator->zLength) { + if (pos->y - surfaceCheckDist < iterator->minPos.y && + iterator->minPos.y < pos->y + surfaceCheckDist) { + *bgId = i; + *outWaterBox = iterator; + return i; + } + } + } + } + } + + *outWaterBox = NULL; + return -1; +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface2.s") +#endif + +f32 func_800CA568(CollisionContext* colCtx, s32 waterBoxId, s32 bgId) { + CollisionHeader* colHeader; + + colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + if ((colHeader == NULL) || (waterBoxId < 0) || (waterBoxId >= (s32)colHeader->numWaterBoxes)) { + return 0.0f; + } + if (bgId == BGCHECK_SCENE) { + return colCtx->colHeader->waterBoxes[waterBoxId].minPos.y; + } + return (&colCtx->dyna.waterBoxList.boxes[colCtx->dyna.bgActors[bgId].waterboxesStartIndex])[waterBoxId].minPos.y; +} + +/** + * WaterBox get CamData index + */ +u32 WaterBox_GetCamDataIndex(CollisionContext* colCtx, WaterBox* waterBox) { + u32 prop = waterBox->properties >> 0; + + return prop & 0xFF; +} + +/** + * WaterBox get CamData camera setting + */ +u16 WaterBox_GetCameraSetting(CollisionContext* colCtx, WaterBox* waterBox, s32 bgId) { + s32 pad[2]; + u16 result = 0; + CollisionHeader* colHeader; + CamData* camData; + s32 camId; + + colHeader = BgCheck_GetCollisionHeader(colCtx, bgId); + if (colHeader == NULL) { + return result; + } + camId = WaterBox_GetCamDataIndex(colCtx, waterBox); + camData = colHeader->cameraDataList; + + if (camData == NULL) { + return result; + } + + result = camData[camId].setting; + return result; +} + +void func_800CA6B8(CollisionContext* colCtx, WaterBox* waterBox) { + WaterBox_GetCameraSetting(colCtx, waterBox, BGCHECK_SCENE); +} + +/** + * WaterBox get lighting settings + */ +u32 WaterBox_GetLightSettingIndex(CollisionContext* colCtx, WaterBox* waterBox) { + u32 prop = waterBox->properties >> 8; + + return prop & 0x1F; +} + +#ifdef NON_MATCHING +/** + * Get the water surface at point (`x`, `ySurface`, `z`). `ySurface` doubles as position y input + * same as WaterBox_GetSurfaceImpl, but tests if WaterBox properties & 0x80000 != 0 + * returns true if point is within the xz boundaries of an active water box, else false + * `ySurface` returns the water box's surface, while `outWaterBox` returns a pointer to the WaterBox + */ +s32 func_800CA6F0(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, + WaterBox** outWaterBox, s32* bgId) { + CollisionHeader* colHeader; + u32 room; + WaterBox* curWaterBox; + s32 i; + BgActor* bgActor; + + colHeader = colCtx->colHeader; + *outWaterBox = NULL; + *bgId = BGCHECK_SCENE; + + if (colHeader->numWaterBoxes == 0 || colHeader->waterBoxes == NULL) { + return false; + } + for (curWaterBox = colHeader->waterBoxes; curWaterBox < colHeader->waterBoxes + colHeader->numWaterBoxes; + curWaterBox++) { + room = WATERBOX_ROOM(curWaterBox->properties); + if (room == (u32)globalCtx->roomCtx.currRoom.num || room == 0x3F) { + if ((curWaterBox->properties & 0x80000) != 0) { + if (curWaterBox->minPos.x < x && x < curWaterBox->minPos.x + curWaterBox->xLength) { + if (curWaterBox->minPos.z < z && z < curWaterBox->minPos.z + curWaterBox->zLength) { + *outWaterBox = curWaterBox; + *ySurface = curWaterBox->minPos.y; + return true; + } + } + } + } + } + + for (i = 0; i < BG_ACTOR_MAX; i++) { + if ((colCtx->dyna.bgActorFlags[i] & 1) && !(colCtx->dyna.bgActorFlags[i] & 2)) { + WaterBox* boxes; + boxes = colCtx->dyna.waterBoxList.boxes; + bgActor = &colCtx->dyna.bgActors[i]; + if (bgActor->colHeader->numWaterBoxes != 0 && bgActor->colHeader->waterBoxes != NULL) { + for (curWaterBox = boxes + bgActor->waterboxesStartIndex; + curWaterBox < boxes + bgActor->waterboxesStartIndex + bgActor->colHeader->numWaterBoxes; + curWaterBox++) { + if ((curWaterBox->properties & 0x80000) != 0) { + if (curWaterBox->minPos.x < x && x < curWaterBox->minPos.x + curWaterBox->xLength) { + if (curWaterBox->minPos.z < z && z < curWaterBox->minPos.z + curWaterBox->zLength) { + *outWaterBox = curWaterBox; + *ySurface = curWaterBox->minPos.y; + *bgId = i; + return true; + } + } + } + } + } + } + } + return false; +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA6F0.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CA9D0.s") +s32 func_800CA9D0(GlobalContext* globalCtx, CollisionContext* colCtx, f32 x, f32 z, f32* ySurface, + WaterBox** outWaterBox) { + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/func_800CAA14.s") + return func_800CA6F0(globalCtx, colCtx, x, z, ySurface, outWaterBox, &bgId); +} + +/** + * Get the `closestPoint` to line (`pointA`, `pointB`) formed from the intersection of planes `polyA` and `polyB` + * returns true if the `closestPoint` exists, else returns false + */ +s32 func_800CAA14(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* pointA, Vec3f* pointB, Vec3f* closestPoint) { + f32 n1X; + f32 n1Y; + f32 n1Z; + f32 n2X; + f32 n2Y; + f32 n2Z; + s32 result; + + CollisionPoly_GetNormalF(polyA, &n1X, &n1Y, &n1Z); + CollisionPoly_GetNormalF(polyB, &n2X, &n2Y, &n2Z); + result = Math3D_PlaneVsLineSegClosestPoint(n1X, n1Y, n1Z, polyA->dist, n2X, n2Y, n2Z, polyB->dist, pointA, pointB, + closestPoint); + return result; +} diff --git a/src/code/z_camera.c b/src/code/z_camera.c index 4c2502470..d3f1f9203 100644 --- a/src/code/z_camera.c +++ b/src/code/z_camera.c @@ -312,7 +312,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_SetMode.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DF840.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeMode.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DF86C.s") @@ -320,19 +320,19 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFAC8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFB14.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_ChangeDataIdx.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFC1C.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFC40.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFC68.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_GetInputDirYaw.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFC90.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFCB4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_GetCamDirPitch.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFCDC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_GetCamDirYaw.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800DFD04.s") @@ -356,7 +356,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E01AC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E01B8.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_GetQuakeOffset.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E01DC.s") @@ -364,10 +364,10 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E0238.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E02AC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_SetToTrackActor.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E0308.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_SetTargetActor.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E031C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/Camera_GetWaterYPos.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_camera/func_800E0348.s") diff --git a/src/code/z_cheap_proc.c b/src/code/z_cheap_proc.c new file mode 100644 index 000000000..d0709fde9 --- /dev/null +++ b/src/code/z_cheap_proc.c @@ -0,0 +1,39 @@ +#include "global.h" + +/** + * Draws a display list to the opaque display buffer + */ +void Gfx_DrawDListOpa(GlobalContext* globalCtx, Gfx* dlist) { + Gfx* dl; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + dl = POLY_OPA_DISP; + + gSPDisplayList(&dl[0], &sSetupDL[6 * 0x19]); + gSPMatrix(&dl[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[2], dlist); + + POLY_OPA_DISP = &dl[3]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +/** + * Draws a display list to the translucent display buffer + */ +void Gfx_DrawDListXlu(GlobalContext* globalCtx, Gfx* dlist) { + Gfx* dl; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + dl = POLY_XLU_DISP; + + gSPDisplayList(&dl[0], &sSetupDL[6 * 0x19]); + gSPMatrix(&dl[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&dl[2], dlist); + + POLY_XLU_DISP = &dl[3]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index 059fbce09..7ac956e5d 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; @@ -941,7 +941,7 @@ s32 Collider_QuadSetNearestAC(GlobalContext* globalCtx, ColliderQuad* quad, Vec3 return 1; } Math_Vec3s_ToVec3f(&dcMid, &quad->dim.dcMid); - acDist = Math3D_DistanceSquared(&dcMid, hitPos); + acDist = Math3D_Vec3fDistSq(&dcMid, hitPos); if (acDist < quad->dim.acDist) { quad->dim.acDist = acDist; @@ -1145,7 +1145,7 @@ ColChkResetFunc sATResetFuncs[] = { s32 CollisionCheck_SetAT(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) { s32 index; - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sATResetFuncs[collider->shape](globalCtx, collider); @@ -1171,7 +1171,7 @@ s32 CollisionCheck_SetAT(GlobalContext* globalCtx, CollisionCheckContext* colCtx * will be inserted into the next slot. */ s32 CollisionCheck_SetAT_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) { - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sATResetFuncs[collider->shape](globalCtx, collider); @@ -1205,7 +1205,7 @@ ColChkResetFunc sACResetFuncs[] = { s32 CollisionCheck_SetAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) { s32 index; - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sACResetFuncs[collider->shape](globalCtx, collider); @@ -1231,7 +1231,7 @@ s32 CollisionCheck_SetAC(GlobalContext* globalCtx, CollisionCheckContext* colCtx * will be inserted into the next slot */ s32 CollisionCheck_SetAC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) { - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sACResetFuncs[collider->shape](globalCtx, collider); @@ -1265,7 +1265,7 @@ ColChkResetFunc sOCResetFuncs[] = { s32 CollisionCheck_SetOC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider) { s32 index; - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sOCResetFuncs[collider->shape](globalCtx, collider); @@ -1291,7 +1291,7 @@ s32 CollisionCheck_SetOC(GlobalContext* globalCtx, CollisionCheckContext* colCtx * will be inserted into the next slot. */ s32 CollisionCheck_SetOC_SAC(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, Collider* collider, s32 index) { - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } sOCResetFuncs[collider->shape](globalCtx, collider); @@ -1323,7 +1323,7 @@ s32 CollisionCheck_SetOC_SAC(GlobalContext* globalCtx, CollisionCheckContext* co s32 CollisionCheck_SetOCLine(GlobalContext* globalCtx, CollisionCheckContext* colCtxt, OcLine* line) { s32 index; - if (FrameAdvance_IsEnabled(globalCtx)) { + if (FrameAdvance_IsEnabled(&globalCtx->state)) { return -1; } @@ -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") @@ -1525,7 +1525,7 @@ void CollisionCheck_HitSolid(GlobalContext* globalCtx, ColliderInfo* info, Colli if (collider->actor == NULL) { play_sound(NA_SE_IT_SHIELD_BOUND); } else { - func_8019F1C0(&collider->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); + Audio_PlaySfxAtPos(&collider->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); } } else if (flags == TOUCH_SFX_NORMAL) { EffectSsHitMark_SpawnFixedScale(globalCtx, 3, hitPos); @@ -1539,14 +1539,14 @@ void CollisionCheck_HitSolid(GlobalContext* globalCtx, ColliderInfo* info, Colli if (collider->actor == NULL) { play_sound(NA_SE_IT_SHIELD_BOUND); } else { - func_8019F1C0(&collider->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); + Audio_PlaySfxAtPos(&collider->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); } } else if (flags == TOUCH_SFX_WOOD) { EffectSsHitMark_SpawnFixedScale(globalCtx, 1, hitPos); if (collider->actor == NULL) { play_sound(NA_SE_IT_REFLECTION_WOOD); } else { - func_8019F1C0(&collider->actor->projectedPos, NA_SE_IT_REFLECTION_WOOD); + Audio_PlaySfxAtPos(&collider->actor->projectedPos, NA_SE_IT_REFLECTION_WOOD); } } } @@ -1557,13 +1557,13 @@ void CollisionCheck_HitSolid(GlobalContext* globalCtx, ColliderInfo* info, Colli s32 CollisionCheck_SwordHitAudio(Collider* at, ColliderInfo* acInfo) { if (at->actor != NULL && at->actor->category == ACTORCAT_PLAYER) { if (acInfo->elemType == ELEMTYPE_UNK0) { - func_8019F1C0(&at->actor->projectedPos, NA_SE_IT_SWORD_STRIKE); + Audio_PlaySfxAtPos(&at->actor->projectedPos, NA_SE_IT_SWORD_STRIKE); } else if (acInfo->elemType == ELEMTYPE_UNK1) { - func_8019F1C0(&at->actor->projectedPos, NA_SE_IT_SWORD_STRIKE_HARD); + Audio_PlaySfxAtPos(&at->actor->projectedPos, NA_SE_IT_SWORD_STRIKE_HARD); } else if (acInfo->elemType == ELEMTYPE_UNK2) { - func_8019F1C0(&at->actor->projectedPos, 0); + Audio_PlaySfxAtPos(&at->actor->projectedPos, 0); } else if (acInfo->elemType == ELEMTYPE_UNK3) { - func_8019F1C0(&at->actor->projectedPos, 0); + Audio_PlaySfxAtPos(&at->actor->projectedPos, 0); } } return 1; @@ -1618,7 +1618,7 @@ void CollisionCheck_HitEffects(GlobalContext* globalCtx, Collider* at, ColliderI if (ac->actor == NULL) { play_sound(NA_SE_IT_SHIELD_BOUND); } else { - func_8019F1C0(&ac->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); + Audio_PlaySfxAtPos(&ac->actor->projectedPos, NA_SE_IT_SHIELD_BOUND); } } } @@ -3510,7 +3510,7 @@ s32 CollisionCheck_LineOC_JntSph(GlobalContext* globalCtx, CollisionCheckContext D_801EDEB0.a = *a; D_801EDEB0.b = *b; - if (Math3D_ColSphereLineSeg(&element->dim.worldSphere, &D_801EDEB0) != 0) { + if (Math3D_LineVsSph(&element->dim.worldSphere, &D_801EDEB0) != 0) { return 1; } } @@ -3548,7 +3548,7 @@ s32 CollisionCheck_LineOC_Sphere(GlobalContext* globalCtx, CollisionCheckContext D_801EDFC8.a = *a; D_801EDFC8.b = *b; - if (Math3D_ColSphereLineSeg(&sphere->dim.worldSphere, &D_801EDFC8) != 0) { + if (Math3D_LineVsSph(&sphere->dim.worldSphere, &D_801EDFC8) != 0) { return 1; } @@ -3691,7 +3691,7 @@ void Collider_UpdateSpheres(s32 limb, ColliderJntSph* collider) { D_801EE1C0.x = collider->elements[i].dim.modelSphere.center.x; D_801EE1C0.y = collider->elements[i].dim.modelSphere.center.y; D_801EE1C0.z = collider->elements[i].dim.modelSphere.center.z; - Matrix_MultiplyVector3fByState(&D_801EE1C0, &D_801EE1D0); + Matrix_MultVec3f(&D_801EE1C0, &D_801EE1D0); collider->elements[i].dim.worldSphere.center.x = D_801EE1D0.x; collider->elements[i].dim.worldSphere.center.y = D_801EE1D0.y; collider->elements[i].dim.worldSphere.center.z = D_801EE1D0.z; @@ -3733,7 +3733,7 @@ void Collider_UpdateSphere(s32 limb, ColliderSphere* collider) { D_801EE1E0.x = collider->dim.modelSphere.center.x; D_801EE1E0.y = collider->dim.modelSphere.center.y; D_801EE1E0.z = collider->dim.modelSphere.center.z; - Matrix_MultiplyVector3fByState(&D_801EE1E0, &D_801EE1F0); + Matrix_MultVec3f(&D_801EE1E0, &D_801EE1F0); collider->dim.worldSphere.center.x = D_801EE1F0.x; collider->dim.worldSphere.center.y = D_801EE1F0.y; collider->dim.worldSphere.center.z = D_801EE1F0.z; @@ -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); } /** @@ -3905,7 +3905,7 @@ void CollisionCheck_SpawnShieldParticlesMetal(GlobalContext* globalCtx, Vec3f* v */ void CollisionCheck_SpawnShieldParticlesMetalSound(GlobalContext* globalCtx, Vec3f* v, Vec3f* pos) { CollisionCheck_SpawnShieldParticles(globalCtx, v); - func_8019F1C0(pos, NA_SE_IT_SHIELD_REFLECT_SW); + Audio_PlaySfxAtPos(pos, NA_SE_IT_SHIELD_REFLECT_SW); } /** @@ -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,8 +3944,8 @@ 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); - func_8019F1C0(pos, NA_SE_IT_REFLECTION_WOOD); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &shieldParticleInitWood); + Audio_PlaySfxAtPos(pos, NA_SE_IT_REFLECTION_WOOD); } /** diff --git a/src/code/z_common_data.c b/src/code/z_common_data.c index d391ce153..3860cf153 100644 --- a/src/code/z_common_data.c +++ b/src/code/z_common_data.c @@ -1,3 +1,24 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_common_data/func_800E9360.s") +SaveContext gSaveContext; + +void SaveContext_Init(void) { + bzero(&gSaveContext, sizeof(SaveContext)); + + gSaveContext.save.playerForm = 0; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; + gSaveContext.nightSeqIndex = 0xFF; + gSaveContext.unk_3F46 = NA_BGM_GENERAL_SFX; + gSaveContext.nextCutsceneIndex = 0xFFEF; + gSaveContext.cutsceneTrigger = 0; + gSaveContext.unk_3F4D = 0; + gSaveContext.nextDayTime = 0xFFFF; + gSaveContext.environmentTime = 0; + gSaveContext.dogIsLost = true; + gSaveContext.nextTransition = 0xFF; + gSaveContext.unk_3F26 = 50; + + gSaveContext.options.language = 1; + gSaveContext.options.audioSetting = 0; + gSaveContext.options.zTargetSetting = 0; +} diff --git a/src/code/z_debug.c b/src/code/z_debug.c index 924a2ad30..46649a4ce 100644 --- a/src/code/z_debug.c +++ b/src/code/z_debug.c @@ -1,11 +1,12 @@ #include "global.h" +#include "system_malloc.h" GameInfo* gGameInfo; void GameInfo_Init(void) { s32 i; - gGameInfo = (GameInfo*)SystemArena_Malloc(sizeof(GameInfo)); + gGameInfo = SystemArena_Malloc(sizeof(GameInfo)); if (1) {} gGameInfo->unk_00 = 0; gGameInfo->unk_01 = 0; diff --git a/src/code/z_debug_display.c b/src/code/z_debug_display.c index f61a90fad..fb7378751 100644 --- a/src/code/z_debug_display.c +++ b/src/code/z_debug_display.c @@ -1,15 +1,125 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/func_800E9470.s") +DebugDispObject* sDebugObjectListHead; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/DebugDisplay_AddObject.s") +typedef struct { + /* 0x00 */ s16 drawType; // indicates which draw function to use when displaying the object + /* 0x04 */ void* drawArg; // segment address (display list or texture) passed to the draw funciton when called +} DebugDispObjectInfo; // size = 0x8 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/DebugDisplay_DrawObjects.s") +typedef void (*DebugDispObject_DrawFunc)(DebugDispObject*, void*, GlobalContext*); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/func_800E95F4.s") +void DebugDisplay_DrawSpriteI8(DebugDispObject*, void*, GlobalContext*); +void DebugDisplay_DrawPolygon(DebugDispObject*, void*, GlobalContext*); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/func_800E97D8.s") +DebugDispObject* DebugDisplay_Init(void) { + sDebugObjectListHead = NULL; + return sDebugObjectListHead; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/func_800E992C.s") +DebugDispObject* DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX, + f32 scaleY, f32 scaleZ, u8 red, u8 green, u8 blue, u8 alpha, s16 type, + GraphicsContext* gfxCtx) { + DebugDispObject* oldHead = sDebugObjectListHead; + + sDebugObjectListHead = GRAPH_ALLOC(gfxCtx, sizeof(DebugDispObject)); + sDebugObjectListHead->pos.x = posX; + sDebugObjectListHead->pos.y = posY; + sDebugObjectListHead->pos.z = posZ; + sDebugObjectListHead->rot.x = rotX; + sDebugObjectListHead->rot.y = rotY; + sDebugObjectListHead->rot.z = rotZ; + sDebugObjectListHead->scale.x = scaleX; + sDebugObjectListHead->scale.y = scaleY; + sDebugObjectListHead->scale.z = scaleZ; + sDebugObjectListHead->color.r = red; + sDebugObjectListHead->color.g = green; + sDebugObjectListHead->color.b = blue; + sDebugObjectListHead->color.a = alpha; + sDebugObjectListHead->type = type; + sDebugObjectListHead->next = oldHead; + return sDebugObjectListHead; +} + +#include "code/debug_display/debug_display.c" + +DebugDispObject_DrawFunc sDebugObjectDrawFuncTable[] = { DebugDisplay_DrawSpriteI8, DebugDisplay_DrawPolygon }; + +DebugDispObjectInfo sDebugObjectInfoTable[] = { + { 0, sDebugDisplayCircleTex }, { 0, sDebugDisplayCrossTex }, { 0, sDebugDisplayBallTex }, + { 0, sDebugDisplayCursorTex }, { 1, &sDebugDisplay1DL }, { 1, &sDebugDisplay3DL }, + { 1, &sDebugDisplay2DL }, +}; + +void DebugDisplay_DrawObjects(GlobalContext* globalCtx) { + DebugDispObject* dispObj = sDebugObjectListHead; + DebugDispObjectInfo* objInfo; + + while (dispObj != NULL) { + objInfo = &sDebugObjectInfoTable[dispObj->type]; + sDebugObjectDrawFuncTable[objInfo->drawType](dispObj, objInfo->drawArg, globalCtx); + dispObj = dispObj->next; + } +} + +void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C6FC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a); + Matrix_Translate(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_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZYX(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); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, sDebugDisplaySpriteDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +Lights1 sDebugDisplayLight1 = gdSPDefLights1(128, 128, 128, 255, 255, 255, 73, 73, 73); + +void DebugDisplay_DrawPolygon(DebugDispObject* dispObj, void* arg1, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C588(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a); + + gSPSetLights1(POLY_XLU_DISP++, sDebugDisplayLight1); + + Matrix_SetTranslateRotateYXZ(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, &dispObj->rot); + 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); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 D_801BB068[] = { + 0x00140000, 0x0000FFEC, 0x00000000, 0x00000014, 0x00000000, 0xFFEC0000, 0x00000000, 0x00140000, 0x0000FFEC, +}; + +s32 D_801BB08C = 0; + +Gfx* func_800E99B0(GraphicsContext* gfxCtx, s32 arg1); + +void func_800E992C(GlobalContext* globalCtx, s32 arg1) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C560(globalCtx->state.gfxCtx); + 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); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_debug_display/func_800E99B0.s") diff --git a/src/code/z_demo.c b/src/code/z_demo.c index 72eeb742e..01ed87e70 100644 --- a/src/code/z_demo.c +++ b/src/code/z_demo.c @@ -1,99 +1,1682 @@ #include "global.h" +#include "overlays/gamestates/ovl_daytelop/z_daytelop.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_Init.s") +void Cutscene_DoNothing(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800EA258(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800ED9C4(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800EA2B8(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800ED980(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800EDA04(GlobalContext* globalCtx, CutsceneContext* csCtx); +void func_800EDA84(GlobalContext* globalCtx, CutsceneContext* csCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA0D4.s") +// Unused +UNK_TYPE4 D_801BB120 = 0; +u16 D_801BB124 = 0; +u16 D_801BB128 = 0; +u8 D_801BB12C = 0; +u8 sCutsceneStoredPlayerForm = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA0EC.s") +// bss +#ifndef NON_MATCHING +static u16 seqId; +#endif +s16 sCutsceneQuakeIndex; +DbCameraUnkStruct sCutsceneCameraInfo; +u16 D_801F4DC8[10]; +UNK_TYPE D_801F4DDC; +u8 D_801F4DE0; +s16 D_801F4DE2; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_StepCutscene1.s") +void Cutscene_Init(GlobalContext* globalCtx, CutsceneContext* csCtx) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_StepCutscene2.s") + csCtx->state = CS_STATE_0; + csCtx->frames = 0; + csCtx->unk_0C = 0.0f; + globalCtx->csCtx.sceneCsCount = 0; + globalCtx->csCtx.currentCsIndex = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_Nop800EA210.s") + for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) { + D_801F4DC8[i] = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA220.s") + D_801F4DE0 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA258.s") + Audio_SetCutsceneFlag(false); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA2B8.s") +void Cutscene_Start(GlobalContext* globalCtx, CutsceneContext* csCtx) { + csCtx->state = CS_STATE_1; + csCtx->playerAction = NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EA324.s") +void Cutscene_End(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if (csCtx->state != CS_STATE_4) { + csCtx->state = CS_STATE_3; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EABAC.s") +typedef void (*CutsceneStateHandler)(GlobalContext* globalCtx, CutsceneContext* csCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC08.s") +CutsceneStateHandler sCsStateHandlers1[] = { + Cutscene_DoNothing, // CS_STATE_0 + func_800EA258, // CS_STATE_1 + Cutscene_DoNothing, // CS_STATE_2 + func_800ED9C4, // CS_STATE_3 + Cutscene_DoNothing, // CS_STATE_4 +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC44.s") +void Cutscene_Update1(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if (gSaveContext.save.cutscene < 0xFFF0) { + sCsStateHandlers1[csCtx->state](globalCtx, csCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAC94.s") +CutsceneStateHandler sCsStateHandlers2[] = { + Cutscene_DoNothing, // CS_STATE_0 + func_800EA2B8, // CS_STATE_1 + func_800ED980, // CS_STATE_2 + func_800EDA04, // CS_STATE_3 + func_800ED980, // CS_STATE_4 +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD14.s") +void Cutscene_Update2(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if ((gSaveContext.cutsceneTrigger != 0) && (globalCtx->sceneLoadFlag == 0x14)) { + gSaveContext.cutsceneTrigger = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD48.s") + if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0)) { + gSaveContext.save.cutscene = 0xFFFD; + gSaveContext.cutsceneTrigger = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAD7C.s") + if (gSaveContext.save.cutscene >= 0xFFF0) { + func_800EDA84(globalCtx, csCtx); + sCsStateHandlers2[csCtx->state](globalCtx, csCtx); + } +} +void Cutscene_DoNothing(GlobalContext* globalCtx, CutsceneContext* csCtx) { +} + +s32 func_800EA220(GlobalContext* globalCtx, CutsceneContext* csCtx, f32 target) { + return Math_StepToF(&csCtx->unk_0C, target, 0.1f); +} + +void func_800EA258(GlobalContext* globalCtx, CutsceneContext* csCtx) { + Interface_ChangeAlpha(1); + ShrinkWindow_SetLetterboxTarget(32); + if (func_800EA220(globalCtx, csCtx, 1.0f)) { + Audio_SetCutsceneFlag(true); + csCtx->state++; + } +} + +void func_800EA2B8(GlobalContext* globalCtx, CutsceneContext* csCtx) { + func_800ED980(globalCtx, csCtx); + Interface_ChangeAlpha(1); + ShrinkWindow_SetLetterboxTarget(32); + if (func_800EA220(globalCtx, csCtx, 1.0f)) { + Audio_SetCutsceneFlag(true); + csCtx->state++; + } +} + +/* Start of command handling section */ + +// Command 0x96: Miscellaneous commands. +void Cutscene_Command_Misc(GlobalContext* globalCtx2, CutsceneContext* csCtx, CsCmdBase* cmd) { + static u16 D_801BB15C = 0xFFFF; + Player* player = GET_PLAYER(globalCtx2); + GlobalContext* globalCtx = globalCtx2; + u8 isStartFrame = false; + f32 progress; + SceneTableEntry* loadedScene; + + if ((csCtx->frames < cmd->startFrame) || ((csCtx->frames >= cmd->endFrame) && (cmd->endFrame != cmd->startFrame))) { + return; + } + + progress = Environment_LerpWeight(cmd->endFrame - 1, cmd->startFrame, csCtx->frames); + if (csCtx->frames == cmd->startFrame) { + isStartFrame = true; + } + + // TODO: consider creating an enum for this when we understand what each value does + switch (cmd->base) { + case 0x1: + if (isStartFrame) { + func_800FD78C(globalCtx); + globalCtx->envCtx.unk_F2[0] = 0x3C; + } + break; + case 0x2: + if (isStartFrame) { + func_801A47DC(NATURE_CHANNEL_LIGHTNING, CHANNEL_IO_PORT_0, 0); + Environment_AddLightningBolts(globalCtx, 3); + D_801F4E68 = 1; + } + break; + case 0x3: + if (globalCtx->envCtx.lightSettings.fogFar < 12800) { + globalCtx->envCtx.lightSettings.fogFar += 35; + } + break; + case 0x4: + if (isStartFrame) { + globalCtx->envCtx.unk_19 = 1; + globalCtx->envCtx.unk_17 = 1; + globalCtx->envCtx.unk_18 = 0; + globalCtx->envCtx.unk_1A = 0x3C; + globalCtx->envCtx.unk_21 = 1; + globalCtx->envCtx.unk_1F = 0; + globalCtx->envCtx.unk_20 = 1; + globalCtx->envCtx.unk_24 = 0x3C; + globalCtx->envCtx.unk_22 = globalCtx->envCtx.unk_24; + } + break; + case 0x5: + if (isStartFrame && (csCtx->state != CS_STATE_4)) { + csCtx->state = CS_STATE_3; + } + break; + case 0x7: + if (isStartFrame) { + loadedScene = globalCtx->loadedScene; + if (loadedScene->titleTextId != 0) { + func_80151A68(globalCtx, loadedScene->titleTextId); + } + } + break; + case 0x8: + func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); + if (isStartFrame) { + sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6); + Quake_SetSpeed(sCutsceneQuakeIndex, 22000); + Quake_SetQuakeValues(sCutsceneQuakeIndex, 6, 4, 0, 0); + Quake_SetCountdown(sCutsceneQuakeIndex, 800); + } + break; + case 0x9: + if (isStartFrame) { + Quake_Init(); + } + break; + case 0xA: + D_801F6D30.r = 255; + D_801F6D30.g = 255; + D_801F6D30.b = 255; + D_801F6D30.a = 255 * progress; + break; + case 0xB: + D_801F6D30.r = 255; + D_801F6D30.g = 180; + D_801F6D30.b = 100; + D_801F6D30.a = 255 * progress; + break; + case 0xC: + globalCtx->roomCtx.currRoom.segment = NULL; + break; + case 0xD: + if (globalCtx->state.frames & 8) { + if (globalCtx->envCtx.lightSettings.ambientColor[0] < 40) { + globalCtx->envCtx.lightSettings.ambientColor[0] += 2; + globalCtx->envCtx.lightSettings.diffuseColor1[1] -= 3; + globalCtx->envCtx.lightSettings.diffuseColor1[2] -= 3; + } + } else { + if (globalCtx->envCtx.lightSettings.ambientColor[0] > 2) { + globalCtx->envCtx.lightSettings.ambientColor[0] -= 2; + globalCtx->envCtx.lightSettings.diffuseColor1[1] += 3; + globalCtx->envCtx.lightSettings.diffuseColor1[2] += 3; + } + } + break; + case 0xE: + globalCtx->unk_18845 = 1; + break; + case 0xF: + globalCtx->unk_18845 = 0; + break; + case 0x10: + if (isStartFrame) { + globalCtx->envCtx.sandstormState = 1; + } + func_8019F128(NA_SE_EV_SAND_STORM - SFX_FLAG); + break; + case 0x11: + gSaveContext.sunsSongState = SUNSSONG_START; + break; + case 0x12: + if (!gSaveContext.save.isNight) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) - (u16)REG(15); + } else { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) - (u16)(2 * REG(15)); + } + break; + case 0x13: + // AudioOcarina_PlayLongScarecrowAfterCredits + func_8019D758(); + csCtx->frames = cmd->startFrame - 1; + break; + case 0x14: + EnvFlags_Set(globalCtx, 3); + break; + case 0x15: + EnvFlags_Set(globalCtx, 4); + break; + case 0x16: + gSaveContext.save.playerForm = PLAYER_FORM_DEKU; + break; + case 0x17: + player->stateFlags2 |= 0x4000000; + break; + case 0x18: + player->stateFlags2 &= ~0x4000000; + break; + case 0x19: + sCutsceneStoredPlayerForm = gSaveContext.save.playerForm; + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.equippedMask = PLAYER_MASK_NONE; + break; + case 0x1A: + func_8019F128(NA_SE_EV_EARTHQUAKE_LAST2 - SFX_FLAG); + if (isStartFrame) { + sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6); + Quake_SetSpeed(sCutsceneQuakeIndex, 30000); + Quake_SetQuakeValues(sCutsceneQuakeIndex, 20, 10, 0, 0); + Quake_SetCountdown(sCutsceneQuakeIndex, 800); + } + break; + case 0x1B: + if (isStartFrame) { + globalCtx->nextEntranceIndex = 0x1C00; + gSaveContext.nextCutsceneIndex = 0xFFF8; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + } + break; + case 0x1C: + if (isStartFrame) { + globalCtx->envCtx.unk_17 = 0xD; + } + break; + case 0x1D: + gSaveContext.save.playerForm = sCutsceneStoredPlayerForm; + break; + case 0x1E: + D_801F4DE0 = true; + break; + case 0x1F: + D_801F4DE0 = false; + break; + case 0x21: + if (isStartFrame) { + Sram_SaveSpecialEnterClockTown(globalCtx); + } + break; + case 0x22: + if (isStartFrame) { + func_80144A94(&globalCtx->sramCtx); + } + break; + case 0x23: + if (csCtx->frames != D_801BB15C) { + D_801BB15C = csCtx->frames; + + if (REG(15) != 0) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)REG(15); + gSaveContext.save.time = + ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.daySpeed); + } + } + break; + case 0x24: + func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); + if (isStartFrame) { + sCutsceneQuakeIndex = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6); + Quake_SetSpeed(sCutsceneQuakeIndex, 22000); + Quake_SetQuakeValues(sCutsceneQuakeIndex, 2, 1, 0, 0); + Quake_SetCountdown(sCutsceneQuakeIndex, 800); + } + break; + + case 0x26: + // Seems to be used to trigger "Dawn of A New Day" + + gSaveContext.save.day = 9; + + { + GameState* gameState = &globalCtx->state; + gameState->running = false; + } + SET_NEXT_GAMESTATE(&globalCtx->state, Daytelop_Init, DaytelopContext); + + Sram_SaveSpecialNewDay(globalCtx); + break; + + case 0x27: + gSaveContext.save.playerForm = PLAYER_FORM_ZORA; + break; + + case 0x28: + csCtx->frames = cmd->startFrame - 1; + break; + } +} + +// Command 0x97: Set Environment Lighting +void Cutscene_Command_SetLighting(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdEnvLighting* cmd) { + if (csCtx->frames == cmd->startFrame) { + if (cmd->setting != 0x20) { + globalCtx->envCtx.lightSettingOverride = cmd->setting - 1; + globalCtx->envCtx.lightBlend = 1.0f; + } else { + globalCtx->envCtx.lightSettingOverride = 0xFF; + } + } +} + +// Command 0x12C: Plays a sequence (Background music or Fanfare) +void Cutscene_Command_PlaySequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) { + if (csCtx->frames == cmd->startFrame) { + func_801A2C88(cmd->sequence - 1); + } +} + +// Command 0x12D: Stops a sequence (Background music or Fanfare) +void Cutscene_Command_StopSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceChange* cmd) { + if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { + func_801A2D54(cmd->sequence - 1); + } +} + +// Command 0x9C: Fade a sequence (Background music or Fanfare) over duration +void Cutscene_Command_FadeSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdSequenceFade* cmd) { + if ((csCtx->frames == cmd->startFrame) && (csCtx->frames < cmd->endFrame)) { + u8 fadeTimer = cmd->endFrame - cmd->startFrame; + + if (cmd->type == 2) { + Audio_QueueSeqCmd((fadeTimer << 0x10) | 0x110000FF); + } else { + Audio_QueueSeqCmd((fadeTimer << 0x10) | NA_BGM_STOP); + } + } +} + +// Command 0x12E: Play Ambience sequence +void Cutscene_Command_PlayAmbienceSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if (csCtx->frames == cmd->startFrame) { + // Audio_PlayNatureAmbienceSequence + // nightSeqIndex is natureAmbienceId + func_801A4A28(globalCtx->soundCtx.nightSeqIndex); + } +} + +// Command 0x130: +void func_800EAD48(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if (csCtx->frames == cmd->startFrame) { + // Audio_SetSfxReverbIndexExceptOcarinaBank + func_801A4428(2); + } +} + +// Command 0x131: +void func_800EAD7C(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if (csCtx->frames == cmd->startFrame) { + // Audio_SetSfxReverbIndexExceptOcarinaBank + func_801A4428(1); + } +} + +#ifdef NON_MATCHING +// needs in-function static bss +// audio related +void func_800EADB0(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + static u16 seqId; + u8 dayMinusOne; + + if (csCtx->frames == cmd->startFrame) { + dayMinusOne = (gSaveContext.save.day - 1); + if (dayMinusOne >= 3) { + dayMinusOne = 0; + } + + switch (cmd->base) { + case 1: + // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_1); + func_801A246C(SEQ_PLAYER_BGM_MAIN, 1); + break; + + case 2: + // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_0); + func_801A246C(SEQ_PLAYER_BGM_MAIN, 0); + break; + + case 3: + // func_801A246C(SEQ_PLAYER_BGM_MAIN, TYPE_2); + func_801A246C(SEQ_PLAYER_BGM_MAIN, 2); + break; + + case 4: + // func_801A246C(SEQ_PLAYER_NATURE, TYPE_1); + func_801A246C(SEQ_PLAYER_NATURE, 1); + break; + + case 5: + // func_801A246C(SEQ_PLAYER_NATURE, TYPE_0); + func_801A246C(SEQ_PLAYER_NATURE, 0); + break; + + case 6: + // func_801A246C(SEQ_PLAYER_NATURE, TYPE_2); + func_801A246C(SEQ_PLAYER_NATURE, 2); + break; + + case 7: + // Audio_GetActiveSequence + seqId = func_801A8A50(0); + break; + + case 8: + if (seqId != NA_BGM_DISABLED) { + // Audio_PlayBgmForDayScene + func_801A25E4(seqId, dayMinusOne); + } + break; + } + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EADB0.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAECC.s") +// Command 0x12F: Fade Ambience sequence +void Cutscene_Command_FadeAmbienceSequence(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if (csCtx->frames == cmd->startFrame && csCtx->frames < cmd->endFrame) { + u8 fadeTimer = cmd->endFrame - cmd->startFrame; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAF20.s") + Audio_QueueSeqCmd((fadeTimer << 0x10) | 0x140000FF); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EAFE0.s") +// Command 0x190: Rumble +void Cutscene_Command_Rumble(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdRumble* cmd) { + switch (cmd->type) { + case 1: + if (csCtx->frames == cmd->startFrame) { + func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB1DC.s") + case 2: + if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { + if ((csCtx->frames == cmd->startFrame) || (globalCtx->state.frames % 64 == 0)) { + func_8013ECE0(0.0f, cmd->unk6, cmd->unk7, cmd->unk8); + } + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB364.s") +// Command 0x9B: +void Cutscene_Command_FadeColorScreen(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdFadeScreen* cmd) { + if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { + f32 alpha; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB4B4.s") + globalCtx->envCtx.fillScreen = true; + alpha = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EB6F8.s") + if (((cmd->unk0 == 1)) || (cmd->unk0 == 2)) { + globalCtx->envCtx.screenFillColor[0] = cmd->color.r; + globalCtx->envCtx.screenFillColor[1] = cmd->color.g; + globalCtx->envCtx.screenFillColor[2] = cmd->color.b; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBB68.s") + if (cmd->unk0 == 2) { + globalCtx->envCtx.screenFillColor[3] = (1.0f - alpha) * 255.0f; + } else { + globalCtx->envCtx.screenFillColor[3] = 255.0f * alpha; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBCD0.s") +// Command 0x9D: Set Time of Day & Environment Time +void Cutscene_Command_SetTime(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdDayTime* cmd) { + u16 nextTime; + u16 hourAsMinutes; + u16 minutes; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EBD60.s") + if (csCtx->frames == cmd->startFrame) { + hourAsMinutes = CLOCK_TIME_ALT_F(cmd->hour, 0); + minutes = CLOCK_TIME_ALT_F(0, cmd->minute + 1); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC678.s") + nextTime = hourAsMinutes + minutes; + gSaveContext.save.time = nextTime; + gSaveContext.environmentTime = nextTime; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC6D4.s") +void Cutscene_TerminatorImpl(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + csCtx->state = CS_STATE_4; + func_80165690(); + Audio_SetCutsceneFlag(false); + gSaveContext.unk_3F48 = 1; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EC924.s") + if ((gSaveContext.gameMode != 0) && (csCtx->frames != cmd->startFrame)) { + gSaveContext.unk_3F1E = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ECD7C.s") + gSaveContext.save.cutscene = 0; + if (cmd->base == 1) { + globalCtx->nextEntranceIndex = globalCtx->csCtx.sceneCsList[globalCtx->csCtx.currentCsIndex].nextEntranceIndex; + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 0x14; + if (gSaveContext.gameMode != 1) { + Scene_SetExitFade(globalCtx); + } else { + D_801BB12C++; + if (D_801BB12C >= 2) { + D_801BB12C = 0; + } + globalCtx->unk_1887F = 4; + } + if ((globalCtx->nextEntranceIndex & 0xF) > 0) { + gSaveContext.nextCutsceneIndex = (globalCtx->nextEntranceIndex & 0xF) + 0xFFEF; + } + + globalCtx->nextEntranceIndex &= ~0xF; + } +} + +// Command 0x15E +void Cutscene_Command_Terminator(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if (cmd->base == 1) { + if (csCtx->frames == cmd->startFrame) { + Cutscene_TerminatorImpl(globalCtx, csCtx, cmd); + } + } else if (cmd->base == 2) { + if (csCtx->frames == cmd->startFrame) { + func_80165690(); + + switch (D_801F4DE2) { + case 0x1F: + if (gSaveContext.save.weekEventReg[20] & 2) { + globalCtx->nextEntranceIndex = 0x3010; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + } else { + globalCtx->nextEntranceIndex = 0x8600; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + } + break; + + case 0x44: + if (gSaveContext.save.weekEventReg[33] & 0x80) { + globalCtx->nextEntranceIndex = 0xAE70; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + } else { + globalCtx->nextEntranceIndex = 0xAE00; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + } + break; + + case 0x5F: + gSaveContext.save.weekEventReg[55] |= 0x80; + globalCtx->nextEntranceIndex = 0x6A80; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + break; + + case 0x36: + gSaveContext.save.weekEventReg[52] |= 0x20; + globalCtx->nextEntranceIndex = 0x2000; + gSaveContext.nextCutsceneIndex = 0xFFF1; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + break; + } + } + } +} + +// Command 0x15F: Chooses between a cutscene or a rotating mask depending on whether the player has the corresponding +// mask +void Cutscene_Command_ChooseCreditsScenes(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if ((csCtx->frames >= cmd->startFrame) && (func_801A3950(0, true) != 0xFF)) { + switch (cmd->base) { + case 1: + Cutscene_TerminatorImpl(globalCtx, csCtx, cmd); + break; + + case 2: + if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { + // Milk bar + globalCtx->nextEntranceIndex = 0x2400; + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C00; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 3: + if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { + // Fairy's fountain + globalCtx->nextEntranceIndex = 0x4600; + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C10; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 4: + if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) { + // Romani ranch + globalCtx->nextEntranceIndex = 0x6400; + gSaveContext.nextCutsceneIndex = 0xFFF1; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C20; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 5: + if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) { + // West clock town + globalCtx->nextEntranceIndex = 0xD400; + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C30; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 6: + if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) { + // Milk bar + globalCtx->nextEntranceIndex = 0x2400; + gSaveContext.nextCutsceneIndex = 0xFFF1; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C50; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 7: + if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) { + // Milk bar + globalCtx->nextEntranceIndex = 0x2400; + gSaveContext.nextCutsceneIndex = 0xFFF3; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C60; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 8: + // Ikana canyon + globalCtx->nextEntranceIndex = 0x2000; + gSaveContext.nextCutsceneIndex = 0xFFF3; + globalCtx->sceneLoadFlag = 0x14; + break; + + case 9: + if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) { + // Termina field + globalCtx->nextEntranceIndex = 0x5400; + gSaveContext.nextCutsceneIndex = 0xFFF8; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C70; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 10: + if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { + // Cucco shack + globalCtx->nextEntranceIndex = 0x7E00; + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C40; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + + case 11: + if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) { + // Termina field + globalCtx->nextEntranceIndex = 0x5410; + gSaveContext.nextCutsceneIndex = 0xFFF8; + } else { + // SPOT00 + globalCtx->nextEntranceIndex = 0x1C80; + gSaveContext.nextCutsceneIndex = 0xFFF9; + } + globalCtx->sceneLoadFlag = 0x14; + break; + } + } +} + +// Command 0x99: Motion blur +void Cutscene_Command_MotionBlur(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { + if ((csCtx->frames == cmd->startFrame) && (cmd->base == 1)) { + func_8016566C(180); + } + + if (cmd->base == 2) { + f32 progress = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); + + if (progress >= 0.9f) { + func_80165690(); + } else { + func_80165658((1.0f - progress) * 180.0f); + } + } + } +} + +// Command 0x9A: Gives Tatl to the player +void Cutscene_Command_GiveTatlToPlayer(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + Player* player = GET_PLAYER(globalCtx); + + if (csCtx->frames == cmd->startFrame) { + if (cmd->base == 1) { + gSaveContext.save.hasTatl = true; + if (player->tatlActor != NULL) { + return; + } + player->tatlActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, player->actor.world.pos.x, + player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, 0); + } + } +} + +// Command 0x98 +void Cutscene_Command_TransitionFX(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdBase* cmd) { + if ((csCtx->frames >= cmd->startFrame) && (cmd->endFrame >= csCtx->frames)) { + f32 temp_f0; + + globalCtx->envCtx.fillScreen = true; + temp_f0 = Environment_LerpWeight(cmd->endFrame, cmd->startFrame, csCtx->frames); + + switch (cmd->base) { + case 1: + case 5: + globalCtx->envCtx.screenFillColor[0] = 160; + globalCtx->envCtx.screenFillColor[1] = 160; + globalCtx->envCtx.screenFillColor[2] = 160; + if (cmd->base == 1) { + globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0; + if (temp_f0 == 0.0f) { + func_8019F128(NA_SE_EV_S_STONE_FLASH); + } + } else { + globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + } + break; + + case 2: + case 6: + globalCtx->envCtx.screenFillColor[0] = 0; + globalCtx->envCtx.screenFillColor[1] = 0; + globalCtx->envCtx.screenFillColor[2] = 255; + if (cmd->base == 2) { + globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0; + } else { + globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + } + break; + + case 3: + case 7: + globalCtx->envCtx.screenFillColor[0] = 255; + globalCtx->envCtx.screenFillColor[1] = 0; + globalCtx->envCtx.screenFillColor[2] = 0; + if (cmd->base == 3) { + globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + } else { + globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0; + } + break; + + case 4: + case 8: + globalCtx->envCtx.screenFillColor[0] = 0; + globalCtx->envCtx.screenFillColor[1] = 255; + globalCtx->envCtx.screenFillColor[2] = 0; + if (cmd->base == 4) { + globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + } else { + globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0; + } + break; + + case 9: + gSaveContext.unk_3F48 = 1; + break; + + case 10: + case 11: + globalCtx->envCtx.screenFillColor[0] = 0; + globalCtx->envCtx.screenFillColor[1] = 0; + globalCtx->envCtx.screenFillColor[2] = 0; + if (cmd->base == 10) { + globalCtx->envCtx.screenFillColor[3] = (1.0f - temp_f0) * 255.0f; + } else { + globalCtx->envCtx.screenFillColor[3] = 255.0f * temp_f0; + } + break; + + case 12: + globalCtx->envCtx.screenFillColor[0] = (160.0f * (1.0f - temp_f0)); + globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[0]; + globalCtx->envCtx.screenFillColor[2] = globalCtx->envCtx.screenFillColor[0]; + globalCtx->envCtx.screenFillColor[3] = 255; + break; + + case 13: + globalCtx->envCtx.screenFillColor[0] = (160.0f * temp_f0); + globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[0]; + globalCtx->envCtx.screenFillColor[2] = globalCtx->envCtx.screenFillColor[0]; + globalCtx->envCtx.screenFillColor[3] = 255; + break; + } + } +} + +// Command 0x5A: Camera +s32 Cutscene_Command_Camera(GlobalContext* globalCtx, u8* cmd) { + s32 sp1C = 0; + + bcopy(cmd, &sp1C, sizeof(s32)); + cmd += sizeof(s32); + if (func_8016A168() == 0) { + func_80161998(cmd, &sCutsceneCameraInfo); + } + return sp1C + sizeof(s32); +} + +/** + * Counts how many masks the player has + * The count doesn't include transformation masks + */ +s32 Cutscene_CountNormalMasks(void) { + s32 count = 0; + + if (INV_CONTENT(ITEM_MASK_TRUTH) == ITEM_MASK_TRUTH) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KAFEIS_MASK) == ITEM_MASK_KAFEIS_MASK) { + count++; + } + if (INV_CONTENT(ITEM_MASK_ALL_NIGHT) == ITEM_MASK_ALL_NIGHT) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KEATON) == ITEM_MASK_KEATON) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GARO) == ITEM_MASK_GARO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) { + count++; + } + if (INV_CONTENT(ITEM_MASK_CIRCUS_LEADER) == ITEM_MASK_CIRCUS_LEADER) { + count++; + } + if (INV_CONTENT(ITEM_MASK_POSTMAN) == ITEM_MASK_POSTMAN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_COUPLE) == ITEM_MASK_COUPLE) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GIBDO) == ITEM_MASK_GIBDO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_DON_GERO) == ITEM_MASK_DON_GERO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { + count++; + } + if (INV_CONTENT(ITEM_MASK_CAPTAIN) == ITEM_MASK_CAPTAIN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_STONE) == ITEM_MASK_STONE) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BREMEN) == ITEM_MASK_BREMEN) { + count++; + } + if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) { + count++; + } + if (INV_CONTENT(ITEM_MASK_SCENTS) == ITEM_MASK_SCENTS) { + count++; + } + if (INV_CONTENT(ITEM_MASK_GIANT) == ITEM_MASK_GIANT) { + count++; + } + + return count; +} + +// Command 0xA: Textbox +void Cutscene_Command_Textbox(GlobalContext* globalCtx, CutsceneContext* csCtx, CsCmdTextbox* cmd) { + static s32 D_801BB160 = CS_TEXTBOX_TYPE_DEFAULT; + u8 dialogState; + s32 pad; + u16 originalCsFrames; + s32 pad2; + + if ((cmd->startFrame >= csCtx->frames) || ((cmd->endFrame < csCtx->frames))) { + return; + } + + if (cmd->type != CS_TEXTBOX_TYPE_LEARN_SONG) { + if (D_801BB124 != cmd->base) { + if (D_801BB160 == CS_TEXTBOX_TYPE_3) { + csCtx->frames--; + } + D_801BB160 = CS_TEXTBOX_TYPE_1; + D_801BB124 = cmd->base; + if (cmd->type == CS_TEXTBOX_TYPE_BOSSES_REMAINS) { + 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 (cmd->textId1 != 0xFFFF) { + Message_StartTextbox(globalCtx, cmd->textId1, NULL); + } + } else { + Message_StartTextbox(globalCtx, cmd->base, NULL); + } + } else if (cmd->type == CS_TEXTBOX_TYPE_ALL_NORMAL_MASKS) { + if (Cutscene_CountNormalMasks() == 20) { + if (cmd->textId1 != 0xFFFF) { + Message_StartTextbox(globalCtx, cmd->textId1, NULL); + } + } else { + Message_StartTextbox(globalCtx, cmd->base, NULL); + } + } else { + Message_StartTextbox(globalCtx, cmd->base, NULL); + } + } else { + goto else_label; + } + } else if (D_801BB128 != cmd->base) { + D_801BB160 = CS_TEXTBOX_TYPE_LEARN_SONG; + D_801BB128 = cmd->base; + func_80152434(globalCtx, cmd->base); + } else { + else_label: + if (csCtx->frames >= cmd->endFrame) { + // The Textbox command can change the current cutscene frame, mainly to prevent advancing the cutscene when + // a textbox that is expected to be closed by the user is still open. + + originalCsFrames = csCtx->frames; + dialogState = Message_GetState(&globalCtx->msgCtx); + if ((dialogState != 2) && (dialogState != 0) && (dialogState != 7) && (dialogState != 8)) { + csCtx->frames--; + if ((dialogState == 4) && Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + if (cmd->base == 0x33BD) { + func_8019F230(); + } + + if (cmd->textId1 != 0xFFFF) { + func_80151938(globalCtx, cmd->textId1); + if (cmd->type == CS_TEXTBOX_TYPE_3) { + D_801BB160 = CS_TEXTBOX_TYPE_3; + if (cmd->textId2 != 0xFFFF) { + csCtx->frames++; + } + } + } else { + func_801477B4(globalCtx); + csCtx->frames++; + } + } else { + if (cmd->base == 0x33BD) { + func_8019F208(); + } + + if (cmd->textId2 != 0xFFFF) { + func_80151938(globalCtx, cmd->textId2); + if (cmd->type == CS_TEXTBOX_TYPE_3) { + D_801BB160 = CS_TEXTBOX_TYPE_3; + if (cmd->textId1 != 0xFFFF) { + csCtx->frames++; + } + } + } else { + func_801477B4(globalCtx); + csCtx->frames++; + } + } + } + + if (dialogState == 5 && Message_ShouldAdvance(globalCtx)) { + func_80152434(globalCtx, cmd->base); + } + } + + if ((dialogState == 2) && (D_801BB160 == CS_TEXTBOX_TYPE_3)) { + csCtx->frames--; + D_801BB124++; + } + + if (originalCsFrames == csCtx->frames) { + Interface_ChangeAlpha(1); + D_801BB124 = 0; + D_801BB128 = 0; + func_80161C0C(); + } else { + func_80161BE0(1); + } + } + } +} + +// Related to actorActions. Maybe a generic actorAction setter? +void func_800ECD7C(CutsceneContext* csCtx, u8** cutscenePtr, s16 index) { + s32 i; + s32 count; + + bcopy(*cutscenePtr, &count, sizeof(s32)); + *cutscenePtr += sizeof(s32); + + for (i = 0; i < count; i++) { + CsCmdActorAction* actorAction = *(CsCmdActorAction**)cutscenePtr; + + if ((csCtx->frames >= actorAction->startFrame) && (csCtx->frames < actorAction->endFrame)) { + csCtx->actorActions[index] = actorAction; + } + + *cutscenePtr += sizeof(CsCmdActorAction); + } +} + +#ifdef NON_MATCHING +// Some stack issues, and a few instructions in the "wrong" places +/** + * Loops over the cutscene data itself (`cutscenePtr`), applying the effects of each command instantaneously (for most + * commands). + * + * The cutscene data is an irregularly-structured array of words, which is made up of + * - A beginning, which contains the number of command lists of this cutscene and the ending frame (see + * `CS_BEGIN_CUTSCENE`). + * - Any number of cutscene command lists (which should be the number specified in the beginning), each one of which + * contains commands of the corresponding category. + * - A end marker (see `CS_END`). + * + * This function iterates over each command list until either it has processed the number of command lists stated on + * `CS_BEGIN_CUTSCENE` or until it finds a end marker. + * + * A command list starts with a pair of words containing the command category and a count of how many commands this list + * has (N). This is followed by N commands of the said category. (The exception is Camera, which has the length of the + * list in bytes instead of the number of commands). + * + * For most command lists categories (all but the actorActions and Camera commands): + * - For each command list found, read the number of commands and loop over them, passing each one to the corresponding + * function which handles the command, applying its effects and checking the frame range stored in the command. + * + * This function is invoked once per frame that a cutscene is active. + * + * TODO: consider changing the type of `cutscenePtr` to `uintptr_t` when this function matches. + */ +void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cutscenePtr) { + s32 i; + s16 phi_s0; + s32 totalEntries; + s32 j; + u32 cmdType; // sp5C + s32 pad; + s32 cmdEntries; // sp58 + s32 cutsceneEndFrame; // sp50 + s16 phi_s0_23; + CsCmdBase* cmd; + + // Read the command list count and the ending frame for this cutscene + bcopy(cutscenePtr, &totalEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + bcopy(cutscenePtr, &cutsceneEndFrame, sizeof(s32)); + cutscenePtr += sizeof(s32); + + if (((u16)cutsceneEndFrame < csCtx->frames) && (globalCtx->sceneLoadFlag != 0x14) && (csCtx->state != CS_STATE_4)) { + csCtx->state = CS_STATE_3; + return; + } + + // Loop over every command list + for (i = 0; i < totalEntries; i++) { + // Read the command type of the current command list. + bcopy(cutscenePtr, &cmdType, sizeof(u32)); + cutscenePtr += sizeof(u32); + + // TODO: This should probably be added to the CutsceneCmd enum. Consider doing it when this function matches. + if (cmdType == 0xFFFFFFFF) { + break; + } + + // Check special cases of command types. This are generic ActorActions + // Ranges: [0x64, 0x96), 0xC9, [0x1C2, 0x258) + if (((cmdType >= 100) && (cmdType < 150)) || (cmdType == 201) || ((cmdType >= 450) && (cmdType < 600))) { + for (phi_s0 = 0; phi_s0 < ARRAY_COUNT(D_801F4DC8); phi_s0++) { + if ((u16)cmdType == D_801F4DC8[phi_s0]) { + func_800ECD7C(csCtx, &cutscenePtr, phi_s0); + cmdType = -2; + break; + } else if (D_801F4DC8[phi_s0] == 0) { + D_801F4DC8[phi_s0] = cmdType; + func_800ECD7C(csCtx, &cutscenePtr, phi_s0); + cmdType = -2; + break; + } + } + } + + switch (cmdType) { + case CS_CMD_MISC: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_Misc(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_SET_LIGHTING: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_SetLighting(globalCtx, csCtx, (CsCmdEnvLighting*)cutscenePtr); + cutscenePtr += sizeof(CsCmdEnvLighting); + } + break; + + case CS_CMD_PLAYSEQ: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_PlaySequence(globalCtx, csCtx, (CsCmdSequenceChange*)cutscenePtr); + cutscenePtr += sizeof(CsCmdSequenceChange); + } + break; + + case CS_CMD_STOPSEQ: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_StopSequence(globalCtx, csCtx, (CsCmdSequenceChange*)cutscenePtr); + cutscenePtr += sizeof(CsCmdSequenceChange); + } + break; + + case CS_CMD_FADESEQ: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_FadeSequence(globalCtx, csCtx, (CsCmdSequenceFade*)cutscenePtr); + cutscenePtr += sizeof(CsCmdSequenceFade); + } + break; + + case CS_CMD_PLAYAMBIENCE: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_PlayAmbienceSequence(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_FADEAMBIENCE: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_FadeAmbienceSequence(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_130: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + func_800EAD48(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_131: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + func_800EAD7C(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_132: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + func_800EADB0(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_RUMBLE: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_Rumble(globalCtx, csCtx, (CsCmdRumble*)cutscenePtr); + cutscenePtr += sizeof(CsCmdRumble); + } + break; + + case CS_CMD_FADESCREEN: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_FadeColorScreen(globalCtx, csCtx, (CsCmdFadeScreen*)cutscenePtr); + cutscenePtr += sizeof(CsCmdFadeScreen); + } + break; + + case CS_CMD_SETTIME: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_SetTime(globalCtx, csCtx, (CsCmdDayTime*)cutscenePtr); + cutscenePtr += sizeof(CsCmdDayTime); + } + break; + + case CS_CMD_SET_PLAYER_ACTION: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + cmd = (CsCmdBase*)cutscenePtr; + if ((csCtx->frames >= cmd->startFrame) && (csCtx->frames < cmd->endFrame)) { + csCtx->playerAction = (CsCmdActorAction*)cutscenePtr; + } + cutscenePtr += sizeof(CsCmdActorAction); + } + break; + + case CS_CMD_CAMERA: + cutscenePtr = &cutscenePtr[Cutscene_Command_Camera(globalCtx, cutscenePtr)]; + break; + + case CS_CMD_TERMINATOR: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_Terminator(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_CHOOSE_CREDITS_SCENES: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_ChooseCreditsScenes(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_TEXTBOX: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + cmd = (CsCmdBase*)cutscenePtr; + if (cmd->base != 0xFFFF) { + Cutscene_Command_Textbox(globalCtx, csCtx, (CsCmdTextbox*)cutscenePtr); + } + cutscenePtr += sizeof(CsCmdTextbox); + } + break; + + case CS_CMD_SCENE_TRANS_FX: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_TransitionFX(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_MOTIONBLUR: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_MotionBlur(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case CS_CMD_GIVETATL: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + Cutscene_Command_GiveTatlToPlayer(globalCtx, csCtx, (CsCmdBase*)cutscenePtr); + cutscenePtr += sizeof(CsCmdBase); + } + break; + + case -2: + break; + + default: + bcopy(cutscenePtr, &cmdEntries, sizeof(s32)); + cutscenePtr += sizeof(s32); + for (j = 0; j < cmdEntries; j++) { + cutscenePtr += sizeof(CsCmdBase); + } + break; + } + } +} +#else +void Cutscene_ProcessCommands(GlobalContext* globalCtx, CutsceneContext* csCtx, u8* cutscenePtr); #pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/Cutscene_ProcessCommands.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ED980.s") +/* End of command handling section */ -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800ED9C4.s") +void func_800ED980(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if (gSaveContext.save.cutscene >= 0xFFF0) { + csCtx->frames++; + Cutscene_ProcessCommands(globalCtx, csCtx, (u8*)globalCtx->csCtx.csData); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDA04.s") +void func_800ED9C4(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if (func_800EA220(globalCtx, csCtx, 0.0f)) { + Audio_SetCutsceneFlag(false); + csCtx->state = CS_STATE_0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDA84.s") +// unused +void func_800EDA04(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if (func_800EA220(globalCtx, csCtx, 0.0f)) { + s16 i; + csCtx->playerAction = NULL; + + for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) { + csCtx->actorActions[i] = NULL; + } + + gSaveContext.save.cutscene = 0; + gSaveContext.gameMode = 0; + ActorCutscene_Stop(0x7F); + Audio_SetCutsceneFlag(false); + csCtx->state = CS_STATE_0; + } +} + +void func_800EDA84(GlobalContext* globalCtx, CutsceneContext* csCtx) { + if ((gSaveContext.cutsceneTrigger != 0) && (csCtx->state == CS_STATE_0) && !Player_InCsMode(&globalCtx->state)) { + gSaveContext.save.cutscene = 0xFFFD; + } + + if ((gSaveContext.save.cutscene >= 0xFFF0) && (csCtx->state == CS_STATE_0)) { + s16 i; + + D_801BB124 = 0; + D_801BB128 = 0; + csCtx->playerAction = NULL; + + for (i = 0; i < ARRAY_COUNT(csCtx->actorActions); i++) { + csCtx->actorActions[i] = NULL; + } + + csCtx->state++; + if (csCtx->state == CS_STATE_1) { + Audio_SetCutsceneFlag(true); + + csCtx->frames = 0xFFFF; + csCtx->csCamId = ActorCutscene_GetCurrentCamera(0x7F); + func_8016119C(Play_GetCamera(globalCtx, csCtx->csCamId), &sCutsceneCameraInfo); + csCtx->unk_18 = 0xFFFF; + + if (gSaveContext.cutsceneTrigger == 0) { + Interface_ChangeAlpha(1); + ShrinkWindow_SetLetterboxTarget(32); + ShrinkWindow_SetLetterboxMagnitude(0x20); + csCtx->state++; + } + + func_800ED980(globalCtx, csCtx); + } + + gSaveContext.cutsceneTrigger = 0; + } +} + +#ifdef NON_MATCHING +// HandleFlags? +// regalloc +void func_800EDBE0(GlobalContext* globalCtx) { + CutsceneEntry* temp_a3; + s16 sp2A; + SceneTableEntry* sp24; + s32 temp_v0_3; + + if (((gSaveContext.gameMode == 0) || (gSaveContext.gameMode == 1)) && (gSaveContext.respawnFlag <= 0)) { + sp2A = func_800F21CC(); + if (sp2A != -1) { + temp_v0_3 = func_800F2138(sp2A); + if (temp_v0_3 != -1) { + temp_a3 = ((void)0, globalCtx->csCtx.sceneCsList); + if ((temp_a3[temp_v0_3].unk7 != 0xFF) && (gSaveContext.respawnFlag == 0)) { + if (temp_a3[temp_v0_3].unk7 == 0xFE) { + ActorCutscene_Start(sp2A, NULL); + gSaveContext.showTitleCard = false; + } else if (!((1 << (temp_a3[temp_v0_3].unk7 % 8)) & + gSaveContext.save.weekEventReg[temp_a3[temp_v0_3].unk7 / 8])) { + gSaveContext.save.weekEventReg[(temp_a3[temp_v0_3].unk7 / 8)] |= + 1 << (temp_a3[temp_v0_3].unk7 % 8); + ActorCutscene_Start(sp2A, NULL); + gSaveContext.showTitleCard = false; + } + } + } else { + ActorCutscene_StartAndSetUnkLinkFields(sp2A, NULL); + } + } + } + + if ((gSaveContext.respawnFlag == 0) || (gSaveContext.respawnFlag == -2)) { + sp24 = globalCtx->loadedScene; + if ((sp24->titleTextId != 0) && gSaveContext.showTitleCard) { + if ((Entrance_GetTransitionFlags(gSaveContext.sceneSetupIndex + gSaveContext.save.entranceIndex) & + 0x4000) != 0) { + func_80151A68(globalCtx, sp24->titleTextId); + } + } + + gSaveContext.showTitleCard = true; + } +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDBE0.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/nop_800EDDB0.s") +void func_800EDDB0(GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDDBC.s") +void func_800EDDBC(UNK_TYPE arg0, UNK_TYPE arg1) { +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDDCC.s") +void Cutscene_LoadCutsceneData(GlobalContext* globalCtx, u8 csIndex) { + if (dREG(95) == 0) { + globalCtx->csCtx.currentCsIndex = csIndex; + globalCtx->csCtx.csData = Lib_SegmentedToVirtual(globalCtx->csCtx.sceneCsList[csIndex].segmentedData); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDE34.s") + gSaveContext.cutsceneTrigger = 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDF24.s") +/* Start of actor utilities section */ -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EDF78.s") +/** + * Interpolates the actor's position based on the corresponding actor action's position + * and the current cutscene frame + */ +void Cutscene_ActorTranslate(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex) { + Vec3f start; + Vec3f end; + CsCmdActorAction* entry = globalCtx->csCtx.actorActions[actorActionIndex]; + f32 progress; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE0CC.s") + start.x = entry->startPos.x; + start.y = entry->startPos.y; + start.z = entry->startPos.z; + end.x = entry->endPos.x; + end.y = entry->endPos.y; + end.z = entry->endPos.z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE1D8.s") + progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, globalCtx->csCtx.frames); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE200.s") + VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE29C.s") +/** + * Interpolates the actor's position based on the corresponding actor action's position + * and the current cutscene frame, and sets the actor's yaw using the actor action yaw + */ +void Cutscene_ActorTranslateAndYaw(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex) { + Cutscene_ActorTranslate(actor, globalCtx, actorActionIndex); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_demo/func_800EE2F4.s") + actor->world.rot.y = globalCtx->csCtx.actorActions[actorActionIndex]->urot.y; + actor->shape.rot.y = actor->world.rot.y; +} + +/** + * Interpolates the actor's position and yaw based on the corresponding actor action's + * position and the current cutscene frame + */ +void Cutscene_ActorTranslateAndYawSmooth(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex) { + Vec3f start; + Vec3f end; + CsCmdActorAction* entry; + f32 progress; + + start.x = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.x; + start.y = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.y; + start.z = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.z; + end.x = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.x; + end.y = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.y; + end.z = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.z; + + entry = globalCtx->csCtx.actorActions[actorActionIndex]; + progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, globalCtx->csCtx.frames); + + VEC3F_LERPIMPDST(&actor->world.pos, &start, &end, progress); + + Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1); + actor->shape.rot.y = actor->world.rot.y; +} + +/** + * Interpolates the actor's XZ position and yaw based on the corresponding actor action's + * position and the current cutscene frame + */ +void Cutscene_ActorTranslateXZAndYawSmooth(Actor* actor, GlobalContext* globalCtx, s32 actorActionIndex) { + Vec3f start; + Vec3f end; + CsCmdActorAction* entry; + f32 progress; + + start.x = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.x; + start.z = globalCtx->csCtx.actorActions[actorActionIndex]->startPos.z; + end.x = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.x; + end.z = globalCtx->csCtx.actorActions[actorActionIndex]->endPos.z; + + entry = globalCtx->csCtx.actorActions[actorActionIndex]; + progress = Environment_LerpWeight(entry->endFrame, entry->startFrame, globalCtx->csCtx.frames); + + actor->world.pos.x = start.x + (end.x - start.x) * progress; + actor->world.pos.z = start.z + (end.z - start.z) * progress; + + Math_SmoothStepToS(&actor->world.rot.y, Math_Vec3f_Yaw(&start, &end), 10, 1000, 1); + actor->shape.rot.y = actor->world.rot.y; +} + +s32 Cutscene_GetSceneSetupIndex(GlobalContext* globalCtx) { + s32 sceneSetupIndex = 0; + + if (gSaveContext.sceneSetupIndex > 0) { + sceneSetupIndex = gSaveContext.sceneSetupIndex; + } + return sceneSetupIndex; +} + +s32 Cutscene_GetActorActionIndex(GlobalContext* globalCtx, u16 actorActionCmd) { + s32 i; + s32 index = -1; + + for (i = 0; i < ARRAY_COUNT(D_801F4DC8); i++) { + if (actorActionCmd == D_801F4DC8[i]) { + index = i; + } + } + + return index; +} + +s32 Cutscene_CheckActorAction(GlobalContext* globalCtx, u16 actorActionCmd) { + if (globalCtx->csCtx.state != CS_STATE_0) { + s32 index = Cutscene_GetActorActionIndex(globalCtx, actorActionCmd); + + if (index != -1) { + return globalCtx->csCtx.actorActions[index] != NULL; + } + } + + return false; +} + +u8 Cutscene_IsPlaying(GlobalContext* globalCtx) { + return (gSaveContext.cutsceneTrigger != 0) || (globalCtx->csCtx.state != CS_STATE_0); +} + +/* End of actor utilities section */ diff --git a/src/code/z_eff_blure.c b/src/code/z_eff_blure.c index 17685de15..6ab70f1ef 100644 --- a/src/code/z_eff_blure.c +++ b/src/code/z_eff_blure.c @@ -1,27 +1,19 @@ #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.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 +24,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 +44,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 +69,976 @@ 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]; + Vec3s* unusedPtr = &sp30; // Optimized out but seems necessary to match stack usage + + 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; + } + + 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++, gameplay_keep_Tex_014570, 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_footmark.c b/src/code/z_eff_footmark.c index d246aaffa..f959867fe 100644 --- a/src/code/z_eff_footmark.c +++ b/src/code/z_eff_footmark.c @@ -106,7 +106,7 @@ void EffFootmark_Draw(GlobalContext* globalCtx) { for (footmark = globalCtx->footprintInfo, i = 0; i < 100; i++, footmark++) { if (footmark->actor != NULL) { - Matrix_SetCurrentState(&footmark->displayMatrix); + Matrix_Put(&footmark->displayMatrix); Matrix_Scale(footmark->size * (1.0f / 0x100) * 0.7f, 1, footmark->size * (1.0f / 0x100), MTXMODE_APPLY); gSPMatrix(gfxCtx->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD); diff --git a/src/code/z_eff_shield_particle.c b/src/code/z_eff_shield_particle.c index 29d93a715..e3a051fb4 100644 --- a/src/code/z_eff_shield_particle.c +++ b/src/code/z_eff_shield_particle.c @@ -1,11 +1,208 @@ #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" +#include "objects/gameplay_keep/gameplay_keep.h" -#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++, gameplay_keep_Tex_054F20, 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, MTXMODE_NEW); + 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..697c55398 100644 --- a/src/code/z_eff_spark.c +++ b/src/code/z_eff_spark.c @@ -1,9 +1,266 @@ #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.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++, gameplay_keep_Tex_054F20, 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..532e8e2fb 100644 --- a/src/code/z_eff_tire_mark.c +++ b/src/code/z_eff_tire_mark.c @@ -1,17 +1,289 @@ #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.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++, gameplay_keep_Tex_014570, 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)) { + s32 requiredScopeTemp; + + 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; + } 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..4c446b650 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; + if (FrameAdvance_IsEnabled(&globalCtx->state) != true) { + 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..fd1d0212c 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,39 +29,40 @@ 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) { if (effectSs->flags & 2) { - func_801A72CC(&effectSs->pos); + Audio_StopSfxByPos(&effectSs->pos); } if (effectSs->flags & 4) { - func_801A72CC(&effectSs->vec); + Audio_StopSfxByPos(&effectSs->vec); } EffectSS_ResetEntry(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; } } @@ -149,10 +152,10 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) { void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) { s32 index; - if (FrameAdvance_IsEnabled(globalCtx) != true) { + if (FrameAdvance_IsEnabled(&globalCtx->state) != 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 = VRAM_PTR_SIZE(entry); if (entry->vramStart == NULL) { initInfo = entry->initInfo; @@ -184,27 +187,25 @@ 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 = (uintptr_t)( + (entry->initInfo != NULL) ? (void*)(-OVERLAY_RELOCATION_OFFSET(entry) + (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 +223,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 +253,15 @@ 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 > BGCHECK_Y_MAX) || + (sEffectSsInfo.data_table[i].pos.x < BGCHECK_Y_MIN) || + (sEffectSsInfo.data_table[i].pos.y > BGCHECK_Y_MAX) || + (sEffectSsInfo.data_table[i].pos.y < BGCHECK_Y_MIN) || + (sEffectSsInfo.data_table[i].pos.z > BGCHECK_Y_MAX) || + (sEffectSsInfo.data_table[i].pos.z < BGCHECK_Y_MIN)) { + 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 cf27d2251..1e9b25573 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -48,9 +48,9 @@ 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[6] = PHYSICAL_TO_VIRTUAL(object); + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(object); gSPSegment(POLY_XLU_DISP++, 0x06, object); mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult); @@ -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,24 +206,21 @@ 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 = { 255, 255, 200, 255 }; + Color_RGBA8 envColor = { 255, 200, 0, 0 }; -void EffectSsKiraKira_SpawnSmallYellow(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - Color_RGBA8 primColor = D_801AE3B8; - Color_RGBA8 envColor = D_801AE3BC; - - EffectSsKiraKira_SpawnDispersed(globalCtx, pos, velocity, accel, &primColor, &envColor, 1000, 16); + EffectSsKirakira_SpawnDispersed(globalCtx, pos, velocity, accel, &primColor, &envColor, 1000, 16); } -void EffectSsKiraKira_SpawnSmall(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, +void EffectSsKirakira_SpawnSmall(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor) { - EffectSsKiraKira_SpawnDispersed(globalCtx, pos, velocity, accel, primColor, envColor, 1000, 16); + EffectSsKirakira_SpawnDispersed(globalCtx, pos, velocity, accel, primColor, envColor, 1000, 16); } -void EffectSsKiraKira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, +void EffectSsKirakira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s32 life) { - EffectSsKiraKiraInitParams initParams; + EffectSsKirakiraInitParams initParams; Math_Vec3f_Copy(&initParams.pos, pos); Math_Vec3f_Copy(&initParams.velocity, velocity); @@ -242,9 +239,9 @@ void EffectSsKiraKira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f EffectSs_Spawn(globalCtx, EFFECT_SS_KIRAKIRA, 128, &initParams); } -void EffectSsKiraKira_SpawnFocused(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, +void EffectSsKirakira_SpawnFocused(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s32 life) { - EffectSsKiraKiraInitParams initParams; + EffectSsKirakiraInitParams initParams; Math_Vec3f_Copy(&initParams.pos, pos); Math_Vec3f_Copy(&initParams.velocity, velocity); @@ -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++) { @@ -639,11 +625,11 @@ void EffectSsSibuki_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos) { // EffectSsStone1 Spawn Functions -void EffectSsStone1_Spawn(GlobalContext* globalCtx, Vec3f* pos, s32 arg2) { +void EffectSsStone1_Spawn(GlobalContext* globalCtx, Vec3f* pos, s32 reg0) { EffectSsStone1InitParams initParams; initParams.pos = *pos; - initParams.unk_C = arg2; + initParams.reg0 = reg0; EffectSs_Spawn(globalCtx, EFFECT_SS_STONE1, 128, &initParams); } @@ -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; @@ -818,17 +795,17 @@ void EffectSsEnIce_SpawnFlyingVec3f(GlobalContext* globalCtx, Actor* actor, Vec3 initParams.scale = scale; if (actor != NULL) { - Audio_PlayActorSound2(actor, NA_SE_PL_FREEZE_S); + Actor_PlaySfxAtPos(actor, NA_SE_PL_FREEZE_S); } 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); @@ -919,7 +888,7 @@ void EffectSsEnFire_SpawnVec3f(GlobalContext* globalCtx, Actor* actor, Vec3f* po initParams.bodyPart = bodyPart; if (actor != NULL) { - Audio_PlayActorSound2(actor, NA_SE_EV_FLAME_IGNITION); + Actor_PlaySfxAtPos(actor, NA_SE_EV_FLAME_IGNITION); } EffectSs_Spawn(globalCtx, EFFECT_SS_EN_FIRE, 128, &initParams); @@ -939,7 +908,7 @@ void EffectSsEnFire_SpawnVec3s(GlobalContext* globalCtx, Actor* actor, Vec3s* po initParams.bodyPart = bodyPart; if (actor != NULL) { - Audio_PlayActorSound2(actor, NA_SE_EV_FLAME_IGNITION); + Actor_PlaySfxAtPos(actor, NA_SE_EV_FLAME_IGNITION); } EffectSs_Spawn(globalCtx, EFFECT_SS_EN_FIRE, 128, &initParams); @@ -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..cd2fa96b6 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.save.weekEventReg[88] & 0x20) { + return 0; + } + if (gSaveContext.save.weekEventReg[79] & 0x10) { + if (gSaveContext.save.weekEventReg[8] & 0x40) { + return 0; + } + return 0x224; + } + if (!(gSaveContext.save.weekEventReg[8] & 0x80)) { + if (gSaveContext.save.weekEventReg[9] & 1) { + return 0x21E; + } + if (globalCtx->sceneNum == SCENE_YOUSEI_IZUMI) { + return 0; + } + return 0x21D; + } + if (gSaveContext.save.playerData.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.save.weekEventReg[86] & 4) { + return 0x242; + } + return 0x243; + } + if (gSaveContext.save.weekEventReg[74] & 0x20) { + return 0x223; + } + if (gSaveContext.save.weekEventReg[73] & 0x80) { + return 0x222; + } + if (gSaveContext.save.weekEventReg[73] & 0x20) { + return 0x221; + } + if (gSaveContext.save.weekEventReg[77] & 2) { + if (gSaveContext.save.weekEventReg[73] & 0x10) { + return 0x240; + } + return 0x241; + } + if ((gSaveContext.save.weekEventReg[86] & 2) || (gSaveContext.save.weekEventReg[73] & 0x40)) { + return 0x23F; + } + return 0x220; +} diff --git a/src/code/z_en_a_keep.c b/src/code/z_en_a_keep.c index d5125d249..1d083b2c7 100644 --- a/src/code/z_en_a_keep.c +++ b/src/code/z_en_a_keep.c @@ -11,10 +11,10 @@ void EnAObj_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.textId = ((this->actor.params >> 8) & 0xFF) | 0x300; this->actor.params = (this->actor.params & 0xFF) - 9; Actor_ProcessInitChain(&this->actor, &enAObjInitVar); - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 12); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 12); Collider_InitAndSetCylinder(globalCtx, &this->collision, &this->actor, &enAObjCylinderInit); Collider_UpdateCylinder(&this->actor, &this->collision); - this->actor.colChkInfo.mass = 255; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->actionFunc = EnAObj_Update1; } @@ -27,7 +27,7 @@ void EnAObj_Destroy(Actor* thisx, GlobalContext* globalCtx) { void EnAObj_Update1(EnAObj* this, GlobalContext* globalCtx) { s32 yawDiff; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = EnAObj_Update2; } else { yawDiff = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)); @@ -39,7 +39,7 @@ void EnAObj_Update1(EnAObj* this, GlobalContext* globalCtx) { } void EnAObj_Update2(EnAObj* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = EnAObj_Update1; } } @@ -48,10 +48,10 @@ void EnAObj_Update(Actor* thisx, GlobalContext* globalCtx) { EnAObj* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, 45.0f); + Actor_SetFocus(&this->actor, 45.0f); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collision.base); } void EnAObj_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, enAObjDisplayLists[thisx->params]); + Gfx_DrawDListOpa(globalCtx, enAObjDisplayLists[thisx->params]); } diff --git a/src/code/z_en_hy_code.c b/src/code/z_en_hy_code.c new file mode 100644 index 000000000..28c177068 --- /dev/null +++ b/src/code/z_en_hy_code.c @@ -0,0 +1,279 @@ +/* + * File: z_en_hy.c + * Description: Unused System for NPCs (includes animation, door interaction, blinking, pathing, and collider helpers) + */ + +#include "z_en_hy_code.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_aob/object_aob.h" +#include "objects/object_bba/object_bba.h" +#include "objects/object_bji/object_bji.h" +#include "objects/object_boj/object_boj.h" +#include "objects/object_os_anime/object_os_anime.h" + +static AnimationInfoS sAnimations[] = { + { &gMamamuYanUnusedIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_001494, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_001494, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_boj_Anim_001908, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_001908, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_boj_Anim_0008C0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gBbaIdleHoldingBagAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_bji_Anim_000FDC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_bji_Anim_000AB0, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_bji_Anim_00066C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_00071C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_os_anime_Anim_001EE0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_00DED8, 1.5f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_boj_Anim_00F920, 1.5f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_boj_Anim_00FC1C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_00FEE4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_010330, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_boj_Anim_00FC1C, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_boj_Anim_00FEE4, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_boj_Anim_010330, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, + { &object_boj_Anim_005D9C, 1.0f, 0, -1, ANIMMODE_LOOP, -8 }, +}; + +s8 gEnHyBodyParts[] = { -1, 1, 12, 13, 14, 9, 10, 11, 0, 6, 7, 8, 3, 4, 5, 2 }; + +s8 gEnHyParentBodyParts[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13 }; + +u8 gEnHyShadowSizes[] = { 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 >= ENHY_ANIMATION_AOB_0 && animIndex < ENHY_ANIMATION_MAX) { + isChanged = true; + frameCount = sAnimations[animIndex].frameCount; + if (frameCount < 0) { + frameCount = Animation_GetLastFrame(&sAnimations[animIndex].animation->common); + } + Animation_Change(skelAnime, sAnimations[animIndex].animation, sAnimations[animIndex].playSpeed, + sAnimations[animIndex].startFrame, frameCount, sAnimations[animIndex].mode, + sAnimations[animIndex].morphFrames); + } + return isChanged; +} + +EnDoor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx) { + EnDoor* nearestDoor = NULL; + Actor* doorIter = NULL; + f32 dist; + EnDoor* door; + s32 isSetup = false; + f32 minDist = 0.0f; + + do { + doorIter = SubS_FindActor(globalCtx, doorIter, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door = (EnDoor*)doorIter; + dist = Actor_DistanceBetweenActors(actor, &door->dyna.actor); + if (!isSetup || (dist < minDist)) { + nearestDoor = door; + minDist = dist; + isSetup = true; + } + doorIter = door->dyna.actor.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 ((SubS_IsObjectLoaded(enHy->animObjIndex, globalCtx) == true) && + (SubS_IsObjectLoaded(enHy->headObjIndex, globalCtx) == true) && + (SubS_IsObjectLoaded(enHy->skelUpperObjIndex, globalCtx) == true) && + (SubS_IsObjectLoaded(enHy->skelLowerObjIndex, globalCtx) == true)) { + enHy->actor.objBankIndex = enHy->skelLowerObjIndex; + 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, + ENHY_LIMB_MAX); + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + } + + return isInitialized; +} + +void func_800F0BB4(EnHy* enHy, GlobalContext* globalCtx, EnDoor* door, s16 arg3, s16 arg4) { + s32 pad; + s8 animIndex; + Vec3f offset; + f32 phi_f0; + + Actor_OffsetOfPointInActorCoords(&door->dyna.actor, &offset, &enHy->actor.world.pos); + phi_f0 = (offset.z >= 0.0f) ? 1.0f : -1.0f; + animIndex = ((s8)phi_f0 < 0) ? 0 : 2; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, (animIndex == 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); + door->unk_1A1 = 1; + door->animIndex = animIndex; +} + +s32 func_800F0CE4(EnHy* enHy, GlobalContext* globalCtx, ActorFunc draw, s16 arg3, s16 arg4, f32 arg5) { + s32 ret = false; + s16 yaw; + EnDoor* door; + s32 pad; + + if (SubS_CopyPointFromPath(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->dyna.actor.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; + EnDoor* door; + + enHy->curPoint = 0; + if (SubS_CopyPointFromPath(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->dyna.actor.world.pos); + enHy->actor.world.rot.y = enHy->actor.shape.rot.y; + enHy->actor.gravity = 0.0f; + enHy->actor.flags &= ~ACTOR_FLAG_1; + } + } + return ret; +} + +s32 EnHy_SetPointFowards(EnHy* enHy, GlobalContext* globalCtx, f32 gravity, s16 animIndex) { + enHy->actor.gravity = gravity; + enHy->actor.flags |= ACTOR_FLAG_1; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint++; + return false; +} + +s32 EnHy_SetPointBackwards(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex) { + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint--; + return false; +} + +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 (SubS_CopyPointFromPath(enHy->path, enHy->curPoint, &curPointPos) && + SubS_MoveActorToPoint(&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 (SubS_CopyPointFromPath(enHy->path, enHy->curPoint, &curPointPos) && + SubS_MoveActorToPoint(&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 = SubS_IsFloorAbove(globalCtx, &enHy->leftFootPos, distAboveThreshold); + if (enHy->isLeftFootOnGround && !wasLeftFootOnGround && isFootOnGround) { + Actor_PlaySfxAtPos(&enHy->actor, sfxId); + } + + enHy->isRightFootOnGround = isFootOnGround = SubS_IsFloorAbove(globalCtx, &enHy->rightFootPos, distAboveThreshold); + if (enHy->isRightFootOnGround && !wasRightFootOnGround && isFootOnGround) { + Actor_PlaySfxAtPos(&enHy->actor, sfxId); + } + + return false; +} diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index acae2e0ce..6b01753cc 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -1,4 +1,6 @@ #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_gi_hearts/object_gi_hearts.h" #define FLAGS 0x00000000 @@ -28,13 +30,22 @@ const ActorInit En_Item00_InitVars = { }; static ColliderCylinderInit sCylinderInit = { - { COLTYPE_NONE, AT_NONE, AC_ON | AT_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER }, - { ELEMTYPE_UNK0, - { 0x00000000, 0x00, 0x00 }, - { 0x00000010, 0x00, 0x00 }, - TOUCH_NONE | TOUCH_SFX_NORMAL, - BUMP_ON, - OCELEM_NONE }, + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AT_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000010, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 10, 30, 0, { 0, 0, 0 } }, }; @@ -43,7 +54,7 @@ static InitChainEntry sInitChain[] = { }; void EnItem00_SetObject(EnItem00* this, GlobalContext* globalCtx, f32* shadowOffset, f32* shadowScale) { - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); Actor_SetScale(&this->actor, 0.5f); this->unk154 = 0.5f; *shadowOffset = 0.0f; @@ -57,13 +68,13 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { f32 shadowOffset = 980.0f; f32 shadowScale = 6.0f; s32 getItemId = GI_NONE; - s32 sp30 = (this->actor.params & 0x8000) ? 1 : 0; + s32 sp30 = ENITEM00_GET_8000(&this->actor) ? 1 : 0; - this->collectibleFlag = (this->actor.params & 0x7F00) >> 8; + this->collectibleFlag = ENITEM00_GET_7F00(&this->actor); thisx->params &= 0xFF; // Has to be thisx to match - if (Actor_GetCollectibleFlag(globalCtx, this->collectibleFlag)) { + if (Flags_GetCollectible(globalCtx, this->collectibleFlag)) { if (this->actor.params == ITEM00_HEART_PIECE) { sp30 = 0; this->collectibleFlag = 0; @@ -136,7 +147,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk154 = 0.044999998f; shadowOffset = 320.0f; break; - case ITEM00_RUPEE_ORANGE: + case ITEM00_RUPEE_HUGE: Actor_SetScale(&this->actor, 0.044999998f); this->unk154 = 0.044999998f; shadowOffset = 750.0f; @@ -169,10 +180,10 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { } this->unk14E = 0; - ActorShape_Init(&this->actor.shape, shadowOffset, func_800B3FC0, shadowScale); + ActorShape_Init(&this->actor.shape, shadowOffset, ActorShadow_DrawCircle, shadowScale); this->actor.shape.shadowAlpha = 180; this->actor.focus.pos = this->actor.world.pos; - this->unk14A = 0; + this->unk14A = GI_NONE; if (sp30 < 0) { this->actionFunc = EnItem00_WaitForHeartObject; @@ -205,8 +216,8 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { case ITEM00_RUPEE_PURPLE: Item_Give(globalCtx, ITEM_RUPEE_PURPLE); break; - case ITEM00_RUPEE_ORANGE: - Item_Give(globalCtx, ITEM_RUPEE_ORANGE); + case ITEM00_RUPEE_HUGE: + Item_Give(globalCtx, ITEM_RUPEE_HUGE); break; case ITEM00_HEART: Item_Give(globalCtx, ITEM_HEART); @@ -251,7 +262,7 @@ void EnItem00_Init(Actor* thisx, GlobalContext* globalCtx) { } if ((getItemId != GI_NONE) && (Actor_HasParent(&this->actor, globalCtx) == 0)) { - func_800B8A1C(&this->actor, globalCtx, getItemId, 50.0f, 20.0f); + Actor_PickUp(&this->actor, globalCtx, getItemId, 50.0f, 20.0f); } this->actionFunc = func_800A6A40; @@ -335,7 +346,7 @@ void func_800A6650(EnItem00* this, GlobalContext* globalCtx) { pos.x = this->actor.world.pos.x + randPlusMinusPoint5Scaled(10.0f); pos.y = this->actor.world.pos.y + randPlusMinusPoint5Scaled(10.0f); pos.z = this->actor.world.pos.z + randPlusMinusPoint5Scaled(10.0f); - EffectSsKiraKira_SpawnSmall(globalCtx, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14); + EffectSsKirakira_SpawnSmall(globalCtx, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14); } if ((this->actor.bgCheckFlags & 3) != 0) { if (this->actor.velocity.y > -2.0f) { @@ -392,7 +403,7 @@ void func_800A6780(EnItem00* this, GlobalContext* globalCtx) { pos.x = this->actor.world.pos.x + ((Rand_ZeroOne() - 0.5f) * 10.0f); pos.y = this->actor.world.pos.y + ((Rand_ZeroOne() - 0.5f) * 10.0f); pos.z = this->actor.world.pos.z + ((Rand_ZeroOne() - 0.5f) * 10.0f); - EffectSsKiraKira_SpawnSmall(globalCtx, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14); + EffectSsKirakira_SpawnSmall(globalCtx, &pos, &D_801ADF18, &D_801ADF24, &D_801ADF10, &D_801ADF14); } if (this->actor.bgCheckFlags & 0x0003) { @@ -405,12 +416,12 @@ void func_800A6780(EnItem00* this, GlobalContext* globalCtx) { void func_800A6A40(EnItem00* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (this->unk14A != 0) { + if (this->unk14A != GI_NONE) { if (Actor_HasParent(&this->actor, globalCtx) == 0) { - func_800B8A1C(&this->actor, globalCtx, this->unk14A, 50.0f, 80.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk14A, 50.0f, 80.0f); this->unk152++; } else { - this->unk14A = 0; + this->unk14A = GI_NONE; } } @@ -434,15 +445,13 @@ void func_800A6A40(EnItem00* this, GlobalContext* globalCtx) { } } -#ifdef NON_MATCHING -// Minor regalloc issue where it uses v1 instead of v0 void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { EnItem00* this = THIS; s32 pad; Player* player = GET_PLAYER(globalCtx); s32 sp38 = player->stateFlags3 & 0x1000; s32 getItemId = GI_NONE; - s32 pad2; + s32 params; if (this->unk152 > 0) { this->unk152--; @@ -459,10 +468,10 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { this->actor.scale.y = this->actor.scale.x; if (this->actor.gravity != 0.0f) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 15.0f, 15.0f, 0x1D); - if (this->actor.floorHeight <= -32000.0f) { + if (this->actor.floorHeight <= BGCHECK_Y_MIN) { Actor_MarkForDeath(&this->actor); return; } @@ -471,8 +480,8 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if ((this->actor.params == ITEM00_SHIELD_HERO) || (this->actor.params == ITEM00_MAP) || - (this->actor.params == ITEM00_COMPASS)) { + params = this->actor.params; + if ((params == ITEM00_SHIELD_HERO) || (params == ITEM00_MAP) || (params == ITEM00_COMPASS)) { this->actor.shape.yOffset = fabsf(Math_CosS(this->actor.shape.rot.x) * 37.0f); } @@ -480,10 +489,10 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { return; } - if (!((sp38 != 0) && (this->actor.xzDistToPlayer <= 60.0f) && (this->actor.yDistToPlayer >= -100.0f) && - (this->actor.yDistToPlayer <= 100.0f)) && - !((sp38 == 0) && (this->actor.xzDistToPlayer <= 30.0f) && (this->actor.yDistToPlayer >= -50.0f) && - (this->actor.yDistToPlayer <= 50.0f))) { + if (!((sp38 != 0) && (this->actor.xzDistToPlayer <= 60.0f) && (this->actor.playerHeightRel >= -100.0f) && + (this->actor.playerHeightRel <= 100.0f)) && + !((sp38 == 0) && (this->actor.xzDistToPlayer <= 30.0f) && (this->actor.playerHeightRel >= -50.0f) && + (this->actor.playerHeightRel <= 50.0f))) { if (!Actor_HasParent(&this->actor, globalCtx)) { return; } @@ -510,9 +519,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk1A4 = 1; Item_Give(globalCtx, ITEM_RUPEE_PURPLE); break; - case ITEM00_RUPEE_ORANGE: + case ITEM00_RUPEE_HUGE: this->unk1A4 = 1; - Item_Give(globalCtx, ITEM_RUPEE_ORANGE); + Item_Give(globalCtx, ITEM_RUPEE_HUGE); break; case ITEM00_STICK: getItemId = GI_STICKS_1; @@ -576,7 +585,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { if (getItemId != GI_NONE) { if (!Actor_HasParent(&this->actor, globalCtx)) { - func_800B8A1C(&this->actor, globalCtx, getItemId, 50.0f, 20.0f); + Actor_PickUp(&this->actor, globalCtx, getItemId, 50.0f, 20.0f); } } @@ -588,7 +597,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { case ITEM00_MAP: case ITEM00_COMPASS: if (Actor_HasParent(&this->actor, globalCtx)) { - Actor_SetCollectibleFlag(globalCtx, this->collectibleFlag); + Flags_SetCollectible(globalCtx, this->collectibleFlag); Actor_MarkForDeath(&this->actor); } return; @@ -596,11 +605,11 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { break; } - if ((this->actor.params <= ITEM00_RUPEE_RED) || (this->actor.params == ITEM00_RUPEE_ORANGE)) { + if ((this->actor.params <= ITEM00_RUPEE_RED) || (this->actor.params == ITEM00_RUPEE_HUGE)) { play_sound(NA_SE_SY_GET_RUPY); } else if (getItemId != GI_NONE) { if (Actor_HasParent(&this->actor, globalCtx)) { - Actor_SetCollectibleFlag(globalCtx, this->collectibleFlag); + Flags_SetCollectible(globalCtx, this->collectibleFlag); Actor_MarkForDeath(&this->actor); } return; @@ -608,7 +617,7 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { play_sound(NA_SE_SY_GET_ITEM); } - Actor_SetCollectibleFlag(globalCtx, this->collectibleFlag); + Flags_SetCollectible(globalCtx, this->collectibleFlag); this->unk152 = 15; this->unk14C = 35; @@ -619,12 +628,9 @@ void EnItem00_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_SetScale(&this->actor, this->unk154); - this->unk14A = 0; + this->unk14A = GI_NONE; this->actionFunc = func_800A6A40; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/EnItem00_Update.s") -#endif void EnItem00_DrawRupee(EnItem00* this, GlobalContext* globalCtx); void EnItem00_DrawSprite(EnItem00* this, GlobalContext* globalCtx); @@ -640,7 +646,7 @@ void EnItem00_Draw(Actor* thisx, GlobalContext* globalCtx) { case ITEM00_RUPEE_GREEN: case ITEM00_RUPEE_BLUE: case ITEM00_RUPEE_RED: - case ITEM00_RUPEE_ORANGE: + case ITEM00_RUPEE_HUGE: case ITEM00_RUPEE_PURPLE: EnItem00_DrawRupee(this, globalCtx); break; @@ -656,7 +662,7 @@ void EnItem00_Draw(Actor* thisx, GlobalContext* globalCtx) { s8 bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GI_HEART); if (Object_IsLoaded(&globalCtx->objectCtx, bankIndex)) { this->actor.objBankIndex = bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); this->unk152 = -2; } } else { @@ -698,12 +704,12 @@ void EnItem00_Draw(Actor* thisx, GlobalContext* globalCtx) { } } -UNK_PTR D_801ADF30[5] = { - &D_04061FC0, // Green rupee - &D_04061FE0, // Blue rupee - &D_04062000, // Red rupee - &D_04062040, // Orange rupee - &D_04062020 // Purple rupee +TexturePtr D_801ADF30[] = { + gameplay_keep_Tex_061FC0, // Green rupee + gameplay_keep_Tex_061FE0, // Blue rupee + gameplay_keep_Tex_062000, // Red rupee + gameplay_keep_Tex_062040, // Orange rupee + gameplay_keep_Tex_062020 // Purple rupee }; void EnItem00_DrawRupee(EnItem00* this, GlobalContext* globalCtx) { @@ -725,24 +731,24 @@ void EnItem00_DrawRupee(EnItem00* this, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_801ADF30[iconNb])); - gSPDisplayList(POLY_OPA_DISP++, &D_040622C0); // TODO symbol + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0622C0); // TODO symbol CLOSE_DISPS(globalCtx->state.gfxCtx); } -UNK_PTR D_801ADF44[12] = { - &D_0405E6F0, // Heart (Not used) - &D_0405CEF0, // Bombs (A), Bombs (0) - &D_0405BEF0, // Arrows (10) - &D_0405B6F0, // Arrows (30) - &D_0405C6F0, // Arrows (40), Arrows (50) - &D_0405CEF0, // Bombs (B) - &D_040607C0, // Nuts (1), Nuts (10) - &D_04060FC0, // Sticks (1) - &D_040617C0, // Magic (Large) - &D_0405FFC0, // Magic (Small) +TexturePtr D_801ADF44[12] = { + gameplay_keep_Tex_05E6F0, // Heart (Not used) + gameplay_keep_Tex_05CEF0, // Bombs (A), Bombs (0) + gameplay_keep_Tex_05BEF0, // Arrows (10) + gameplay_keep_Tex_05B6F0, // Arrows (30) + gameplay_keep_Tex_05C6F0, // Arrows (40), Arrows (50) + gameplay_keep_Tex_05CEF0, // Bombs (B) + gameplay_keep_Tex_0607C0, // Nuts (1), Nuts (10) + gameplay_keep_Tex_060FC0, // Sticks (1) + gameplay_keep_Tex_0617C0, // Magic (Large) + gameplay_keep_Tex_05FFC0, // Magic (Small) NULL, - &D_0405F7C0 // Small Key + gameplay_keep_Tex_05F7C0 // Small Key }; void EnItem00_DrawSprite(EnItem00* this, GlobalContext* globalCtx) { @@ -769,14 +775,11 @@ void EnItem00_DrawSprite(EnItem00* this, GlobalContext* globalCtx) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_OPA_DISP++, D_0405F6F0); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0); CLOSE_DISPS(globalCtx->state.gfxCtx); } -extern Gfx D_06001290[]; -extern Gfx D_06001470[]; - void EnItem00_DrawHeartContainer(EnItem00* actor, GlobalContext* globalCtx) { s32 pad; s32 pad2; @@ -789,8 +792,8 @@ void EnItem00_DrawHeartContainer(EnItem00* actor, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_XLU_DISP++, D_06001290); - gSPDisplayList(POLY_XLU_DISP++, D_06001470); + gSPDisplayList(POLY_XLU_DISP++, object_gi_hearts_DL_001290); + gSPDisplayList(POLY_XLU_DISP++, object_gi_hearts_DL_001470); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -806,26 +809,24 @@ void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); - gSPDisplayList(POLY_XLU_DISP++, D_0405AAB0); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_05AAB0); CLOSE_DISPS(globalCtx->state.gfxCtx); } s16 func_800A7650(s16 dropId) { - s16 healthCapacity; - if ((((dropId == ITEM00_BOMBS_A) || (dropId == ITEM00_BOMBS_0) || (dropId == ITEM00_BOMBS_B)) && (INV_CONTENT(ITEM_BOMB) == ITEM_NONE)) || (((dropId == ITEM00_ARROWS_10) || (dropId == ITEM00_ARROWS_30) || (dropId == ITEM00_ARROWS_40) || (dropId == ITEM00_ARROWS_50)) && (INV_CONTENT(ITEM_BOW) == ITEM_NONE)) || - (((dropId == ITEM00_MAGIC_LARGE) || (dropId == ITEM00_MAGIC_SMALL)) && (gSaveContext.magicLevel == 0))) { + (((dropId == ITEM00_MAGIC_LARGE) || (dropId == ITEM00_MAGIC_SMALL)) && + (gSaveContext.save.playerData.magicLevel == 0))) { return ITEM00_NO_DROP; } if (dropId == ITEM00_HEART) { - healthCapacity = gSaveContext.healthCapacity; - if (healthCapacity == gSaveContext.health) { + if (((void)0, gSaveContext.save.playerData.healthCapacity) == ((void)0, gSaveContext.save.playerData.health)) { return ITEM00_RUPEE_GREEN; } } @@ -833,112 +834,94 @@ 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) { param7F00 >>= 8; - if (!Actor_GetCollectibleFlag(globalCtx, param7F00)) { + if (!Flags_GetCollectible(globalCtx, param7F00)) { 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); + if (!Flags_GetCollectible(globalCtx, (param7F00 >> 8) & 0x7F)) { + SoundSource_PlaySfxAtFixedWorldPos(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); + if (!Flags_GetCollectible(globalCtx, (param7F00 >> 8) & 0x7F)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } } } 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 { @@ -946,14 +929,14 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para 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 (Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F) == 0) { - Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); + if (Flags_GetCollectible(globalCtx, (param7F00 >> 8) & 0x7F) == 0) { + SoundSource_PlaySfxAtFixedWorldPos(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; @@ -972,9 +955,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, @@ -1052,17 +1032,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) { @@ -1070,58 +1047,63 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 dropQuantity = sDropTableAmounts[params + dropTableIndex]; if (dropId == ITEM00_MASK) { - dropQuantity = 1; - if (gSaveContext.playerForm != 1) { - if (gSaveContext.playerForm != 2) { - if (gSaveContext.playerForm != 4) { - dropId = ITEM00_RUPEE_GREEN; - } else { - dropId = ITEM00_ARROWS_10; - } - } else { + switch (gSaveContext.save.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.save.playerData.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); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); return; } - if (gSaveContext.health < 0x31) { + if (gSaveContext.save.playerData.health <= 0x30) { params = 0x10; dropId = ITEM00_HEART; dropQuantity = 3; - } else if (gSaveContext.health < 0x51) { + } else if (gSaveContext.save.playerData.health <= 0x50) { params = 0x10; dropId = ITEM00_HEART; dropQuantity = 1; - } else if ((gSaveContext.magicLevel != 0) && (gSaveContext.magic == 0)) { + } else if ((gSaveContext.save.playerData.magicLevel != 0) && (gSaveContext.save.playerData.magic == 0)) { params = 0xD0; dropId = ITEM00_MAGIC_LARGE; dropQuantity = 1; - } else if ((gSaveContext.magicLevel != 0) && ((gSaveContext.magicLevel >> 1) >= gSaveContext.magic)) { + } else if ((gSaveContext.save.playerData.magicLevel != 0) && + ((gSaveContext.save.playerData.magicLevel >> 1) >= gSaveContext.save.playerData.magic)) { params = 0xD0; dropId = ITEM00_MAGIC_LARGE; dropQuantity = 1; @@ -1133,10 +1115,12 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 params = 0xB0; dropId = ITEM00_BOMBS_A; dropQuantity = 1; - } else if (gSaveContext.rupees < 11) { + } else if (gSaveContext.save.playerData.rupees < 11) { params = 0xA0; dropId = ITEM00_RUPEE_RED; dropQuantity = 1; + } else { + return; } } @@ -1154,7 +1138,7 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 spawnedActor->actor.world.rot.y = Rand_ZeroOne() * 40000.0f; Actor_SetScale(&spawnedActor->actor, 0.0f); spawnedActor->actionFunc = func_800A6780; - spawnedActor->actor.flags = spawnedActor->actor.flags | 0x10; + spawnedActor->actor.flags = spawnedActor->actor.flags | ACTOR_FLAG_10; if ((spawnedActor->actor.params != ITEM00_SMALL_KEY) && (spawnedActor->actor.params != ITEM00_HEART_PIECE) && (spawnedActor->actor.params != ITEM00_HEART_CONTAINER)) { @@ -1172,18 +1156,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_ORANGE, - 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))) { @@ -1193,9 +1175,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))) { @@ -1206,5 +1186,5 @@ s32 func_800A817C(s32 index) { } s32 func_800A81A4(GlobalContext* globalCtx, s32 a1, s32 a2) { - return (func_800A8150(a1) == ITEM00_BIG_FAIRY) && (!Actor_GetCollectibleFlag(globalCtx, a2)); + return (func_800A8150(a1) == ITEM00_BIG_FAIRY) && (!Flags_GetCollectible(globalCtx, a2)); } diff --git a/src/code/z_env_flags.c b/src/code/z_env_flags.c new file mode 100644 index 000000000..d76681512 --- /dev/null +++ b/src/code/z_env_flags.c @@ -0,0 +1,33 @@ +#include "global.h" + +void EnvFlags_UnsetAll(GlobalContext* globalCtx) { + u8 i; + + for (i = 0; i < ARRAY_COUNT(globalCtx->envFlags); i++) { + globalCtx->envFlags[i] = 0; + } +} + +void EnvFlags_Set(GlobalContext* globalCtx, s16 flag) { + s16 index = flag / 16; + s16 bit = flag % 16; + s16 mask = 1 << bit; + + globalCtx->envFlags[index] |= mask; +} + +void EnvFlags_Unset(GlobalContext* globalCtx, s16 flag) { + s16 index = flag / 16; + s16 bit = flag % 16; + s16 mask = (1 << bit) ^ 0xFFFF; + + globalCtx->envFlags[index] &= mask; +} + +s32 EnvFlags_Get(GlobalContext* globalCtx, s16 flag) { + s16 index = flag / 16; + s16 bit = flag % 16; + s16 mask = 1 << bit; + + return globalCtx->envFlags[index] & mask; +} diff --git a/src/code/z_face_reaction.c b/src/code/z_face_reaction.c index b8955e1a9..d54561fdd 100644 --- a/src/code/z_face_reaction.c +++ b/src/code/z_face_reaction.c @@ -2,28 +2,28 @@ /** * Indices of the columns of this array: - * - index 0x00: PLAYER_MASK_MASK_OF_TRUTH + * - index 0x00: PLAYER_MASK_TRUTH * - index 0x01: PLAYER_MASK_KAFEIS_MASK - * - index 0x02: PLAYER_MASK_ALL_NIGHT_MASK - * - index 0x03: PLAYER_MASK_BUNNY_HOOD - * - index 0x04: PLAYER_MASK_KEATON_MASK - * - index 0x05: PLAYER_MASK_GAROS_MASK - * - index 0x06: PLAYER_MASK_ROMANIS_MASK - * - index 0x07: PLAYER_MASK_CIRCUS_LEADERS_MASK - * - index 0x08: PLAYER_MASK_POSTMANS_HAT - * - index 0x09: PLAYER_MASK_COUPLES_MASK - * - index 0x0A: PLAYER_MASK_GREAT_FAIRYS_MASK - * - index 0x0B: PLAYER_MASK_GIBDO_MASK - * - index 0x0C: PLAYER_MASK_DON_GEROS_MASK - * - index 0x0D: PLAYER_MASK_KAMAROS_MASK - * - index 0x0E: PLAYER_MASK_CAPTAINS_HAT - * - index 0x0F: PLAYER_MASK_STONE_MASK - * - index 0x10: PLAYER_MASK_BREMEN_MASK - * - index 0x11: PLAYER_MASK_BLAST_MASK - * - index 0x12: PLAYER_MASK_MASK_OF_SCENTS + * - index 0x02: PLAYER_MASK_ALL_NIGHT + * - index 0x03: PLAYER_MASK_BUNNY + * - index 0x04: PLAYER_MASK_KEATON + * - index 0x05: PLAYER_MASK_GARO + * - index 0x06: PLAYER_MASK_ROMANI + * - index 0x07: PLAYER_MASK_CIRCUS_LEADER + * - index 0x08: PLAYER_MASK_POSTMAN + * - index 0x09: PLAYER_MASK_COUPLE + * - index 0x0A: PLAYER_MASK_GREAT_FAIRY + * - index 0x0B: PLAYER_MASK_GIBDO + * - index 0x0C: PLAYER_MASK_DON_GERO + * - index 0x0D: PLAYER_MASK_KAMARO + * - index 0x0E: PLAYER_MASK_CAPTAIN + * - index 0x0F: PLAYER_MASK_STONE + * - index 0x10: PLAYER_MASK_BREMEN + * - index 0x11: PLAYER_MASK_BLAST + * - index 0x12: PLAYER_MASK_SCENTS */ // clang-format off -static u16 sReactionTextIds[][PLAYER_MASK_GIANTS_MASK - 1] = { +static u16 sReactionTextIds[][PLAYER_MASK_GIANT - 1] = { /* 0x00 */ { 0 }, /* 0x01 */ { 0 }, /* 0x02 */ { 0 }, @@ -179,7 +179,7 @@ static u16 sReactionTextIds[][PLAYER_MASK_GIANTS_MASK - 1] = { // clang-format on u16 Text_GetFaceReaction(GlobalContext* globalCtx, u32 reactionSet) { - if ((Player_GetMask(globalCtx) > PLAYER_MASK_NONE) && (Player_GetMask(globalCtx) < PLAYER_MASK_GIANTS_MASK)) { + if ((Player_GetMask(globalCtx) > PLAYER_MASK_NONE) && (Player_GetMask(globalCtx) < PLAYER_MASK_GIANT)) { return sReactionTextIds[reactionSet][Player_GetMask(globalCtx) - 1]; } return 0; diff --git a/src/code/z_fbdemo.c b/src/code/z_fbdemo.c index c2da6f9ce..3d33399e5 100644 --- a/src/code/z_fbdemo.c +++ b/src/code/z_fbdemo.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_fbdemo/func_80163DC0.s") diff --git a/src/code/z_fcurve_data_skelanime.c b/src/code/z_fcurve_data_skelanime.c index c6ee50d87..c8eb927fa 100644 --- a/src/code/z_fcurve_data_skelanime.c +++ b/src/code/z_fcurve_data_skelanime.c @@ -14,10 +14,10 @@ void SkelCurve_Clear(SkelAnimeCurve* skelCurve) { s32 SkelCurve_Init(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve, SkelCurveLimbList* limbListSeg, TransformUpdateIndex* transUpdIdx) { SkelCurveLimb** limbs; - SkelCurveLimbList* limbList = (SkelCurveLimbList*)Lib_SegmentedToVirtual(limbListSeg); + SkelCurveLimbList* limbList = Lib_SegmentedToVirtual(limbListSeg); skelCurve->limbCount = limbList->limbCount; - skelCurve->limbList = (SkelCurveLimb**)Lib_SegmentedToVirtual(limbList->limbs); + skelCurve->limbList = Lib_SegmentedToVirtual(limbList->limbs); skelCurve->transforms = ZeldaArena_Malloc(sizeof(*skelCurve->transforms) * skelCurve->limbCount); @@ -100,11 +100,11 @@ s32 SkelCurve_Update(GlobalContext* globalCtx, SkelAnimeCurve* skelCurve) { void SkelCurve_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, SkelAnimeCurve* skelCurve, OverrideCurveLimbDraw overrideLimbDraw, PostCurveLimbDraw postLimbDraw, s32 lod, Actor* thisx) { - SkelCurveLimb* limb = (SkelCurveLimb*)Lib_SegmentedToVirtual(skelCurve->limbList[limbIndex]); + SkelCurveLimb* limb = Lib_SegmentedToVirtual(skelCurve->limbList[limbIndex]); OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); if (overrideLimbDraw == NULL || (overrideLimbDraw != NULL && overrideLimbDraw(globalCtx, skelCurve, limbIndex, thisx))) { @@ -126,7 +126,7 @@ void SkelCurve_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, SkelAnimeCurve* pos.y = transform->y; pos.z = transform->z; - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); Matrix_Scale(scale.x, scale.y, scale.z, MTXMODE_APPLY); if (lod == 0) { @@ -164,7 +164,7 @@ void SkelCurve_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, SkelAnimeCurve* SkelCurve_DrawLimb(globalCtx, limb->firstChildIdx, skelCurve, overrideLimbDraw, postLimbDraw, lod, thisx); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->nextLimbIdx != LIMB_DONE) { SkelCurve_DrawLimb(globalCtx, limb->nextLimbIdx, skelCurve, overrideLimbDraw, postLimbDraw, lod, thisx); diff --git a/src/code/z_fireobj.c b/src/code/z_fireobj.c index abc78fc4d..f627c6394 100644 --- a/src/code/z_fireobj.c +++ b/src/code/z_fireobj.c @@ -1,27 +1,242 @@ #include "global.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_InitWithParams.s") +typedef enum { + FIRE_STATE_0, + FIRE_STATE_1, + FIRE_STATE_2, + FIRE_STATE_3, +} FireState; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetState.s") +ColliderCylinderInit sFireObjCollisionInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { 18, 67, 0, { 0, 0, 0 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetPosition.s") +FireObjColors sFireObjColors[] = { + { { 255, 255, 0, 255 }, 128, { 255, 0, 0 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_StepSize.s") +FireObjLightParams sFireObjLightParams[] = { + { 200, { 128, 128, 0 }, { 127, 127, 0 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_UpdateStateTransitions.s") +void FireObj_InitWithParams(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init) { + fire->size = init->size; + fire->sizeInv = 1.0f / init->size; + fire->dynamicSizeStep = init->dynamicSizeStep; + fire->state = init->state; + fire->sizeGrowsCos2 = init->sizeGrowsCos2; + fire->colorsIndex = init->colorsIndex; + fire->flags = init->flags; + fire->xScale = 0.0f; + fire->yScale = 0.0f; + fire->dynamicSize = 0.0f; + fire->unk26 = Rand_ZeroOne() * 20.0f; + fire->ignitionDelay = -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Draw.s") +void FireObj_SetState(FireObj* fire, f32 dynamicSizeStep, u8 newState) { + fire->state = newState; + if (fire->state == FIRE_STATE_3) { + fire->yScale = 0.0f; + fire->xScale = 0.0f; + fire->dynamicSize = 0.0f; + } else if (fire->state == FIRE_STATE_2) { + fire->xScale = fire->yScale = fire->size; + fire->dynamicSize = 1.0f; + } + fire->dynamicSizeStep = dynamicSizeStep; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_InitLight.s") +void FireObj_SetPosition(FireObj* fire, Vec3f* pos) { + Math_Vec3f_Copy(&fire->position, pos); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_FiniLight.s") +void FireObj_StepSize(FireObj* fire) { + if (fire->state == FIRE_STATE_0) { + if (Math_StepToF(&fire->dynamicSize, 1.0f, fire->dynamicSizeStep) != 0) { + FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_2); + } + } else if ((fire->state == FIRE_STATE_1) && (Math_StepToF(&fire->dynamicSize, 0.0f, fire->dynamicSizeStep) != 0)) { + FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_3); + } + if (fire->sizeGrowsCos2 == 1) { + if ((fire->state == FIRE_STATE_0) || (fire->state == FIRE_STATE_1)) { + fire->xScale = (1.0f - Math_CosS(SQ(fire->dynamicSize) * 0x4000)) * fire->size; + fire->yScale = fire->dynamicSize * fire->size; + } else { + fire->yScale = fire->dynamicSize * fire->size; + fire->xScale = fire->dynamicSize * fire->size; + } + return; + } else { + fire->yScale = fire->dynamicSize * fire->size; + } + fire->xScale = fire->dynamicSize * fire->size; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_UpdateLight.s") +void FireObj_UpdateStateTransitions(GlobalContext* globalCtx, FireObj* fire) { + Player* player = GET_PLAYER(globalCtx); + WaterBox* waterBox; + f32 waterY; + s32 sp40 = false; + u8 nextState; + Vec3f dist; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Init.s") + FireObj_StepSize(fire); + fire->unk26++; + if (fire->ignitionDelay > 0) { + fire->ignitionDelay--; + } else if (fire->ignitionDelay == 0) { + fire->ignitionDelay = -1; + if ((fire->state == FIRE_STATE_3) || (fire->state == FIRE_STATE_1)) { + nextState = FIRE_STATE_0; + } else { + nextState = FIRE_STATE_1; + } + FireObj_SetState(fire, fire->dynamicSizeStep, nextState); + } + if ((fire->flags & 1) && (fire->state != FIRE_STATE_3) && + WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, fire->position.x, fire->position.z, &waterY, &waterBox) && + (waterY - fire->position.y > 6500.0f * fire->yScale)) { + FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_3); + } + if ((fire->flags & 2) && (player->itemActionParam == PLAYER_AP_STICK)) { + Math_Vec3f_Diff(&player->swordInfo[0].tip, &fire->position, &dist); + if (Math3D_LengthSquared(&dist) < 400.0f) { + sp40 = true; + } + } + if (sp40) { + if (fire->state == FIRE_STATE_3) { + if (player->unk_B28 > 0) { + FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_0); + } + } else if (player->unk_B28 == 0) { + player->unk_B28 = 0xD2; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &fire->position, 20, NA_SE_EV_FLAME_IGNITION); + } else if (player->unk_B28 < 0xC8) { + player->unk_B28 = 0xC8; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Fini.s") +void FireObj_Draw(GlobalContext* globalCtx, FireObj* fire) { + s32 pad; + FireObjColors* fireColors = &sFireObjColors[fire->colorsIndex]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_SetState2.s") + if (fire->state != FIRE_STATE_3) { + Vec3s vec; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_fireobj/FireObj_Update.s") + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + gSPSegment( + POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (fire->unk26 * -20) & 511, 32, 128)); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, fireColors->lod, fireColors->primColor.r, fireColors->primColor.g, + fireColors->primColor.b, fireColors->primColor.a); + + gDPSetEnvColor(POLY_XLU_DISP++, fireColors->envColor.r, fireColors->envColor.g, fireColors->envColor.b, 0); + + vec.x = 0; + vec.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000; + vec.z = 0; + Matrix_SetTranslateRotateYXZ(fire->position.x, fire->position.y, fire->position.z, &vec); + 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++, gGameplayKeepDrawFlameDL); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void FireObj_InitLight(GlobalContext* globalCtx, FireObjLight* light, u8* paramsIndex, Vec3f* pos) { + FireObjLightParams* objectParams = &sFireObjLightParams[*paramsIndex]; + + Lights_PointGlowSetInfo(&light->lightInfo, pos->x, pos->y, pos->z, objectParams->color.r, objectParams->color.g, + objectParams->color.b, objectParams->radius); + light->light = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &light->lightInfo); + light->lightParamsIndex = *paramsIndex; +} + +void FireObj_DestroyLight(GlobalContext* globalCtx, FireObjLight* light) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, light->light); +} + +void FireObj_UpdateLight(GlobalContext* globalCtx, FireObjLight* light, FireObj* fire) { + FireObjLightParams* lightParams = &sFireObjLightParams[light->lightParamsIndex]; + s16 radius; + + if (fire->state == FIRE_STATE_3) { + Lights_PointSetColorAndRadius(&light->lightInfo, 0, 0, 0, -1); + } else { + radius = ((fire->yScale * 140.0f * fire->sizeInv) + 60.0f); + + Lights_PointGlowSetInfo(&light->lightInfo, fire->position.x, (fire->position.y + (fire->yScale * 6500.0f)), + fire->position.z, + ((s32)(Rand_ZeroOne() * lightParams->maxColorAdj.r) + lightParams->color.r), + ((s32)(Rand_ZeroOne() * lightParams->maxColorAdj.g) + lightParams->color.g), + ((s32)(Rand_ZeroOne() * lightParams->maxColorAdj.b) + lightParams->color.b), radius); + } +} + +void FireObj_Init(GlobalContext* globalCtx, FireObj* fire, FireObjInitParams* init, Actor* actor) { + FireObj* fire2 = fire; + + FireObj_InitWithParams(globalCtx, fire, init); + Collider_InitCylinder(globalCtx, &fire->collision); + Collider_SetCylinder(globalCtx, &fire->collision, actor, &sFireObjCollisionInit); + + fire2->collision.dim.radius = (fire->size * 4000.0f) + 2.5f; + fire2->collision.dim.height = fire->size * 16000.0f; + fire->collision.dim.yShift = fire->size * -1728.0f; + FireObj_InitLight(globalCtx, &fire->light, &init->lightParamsIndex, &fire->position); +} + +void FireObj_Destroy(GlobalContext* globalCtx, FireObj* fire) { + Collider_DestroyCylinder(globalCtx, &fire->collision); + FireObj_DestroyLight(globalCtx, &fire->light); +} + +void FireObj_SetState2(FireObj* fire, f32 dynamicSizeStep, u8 newState) { + FireObj_SetState(fire, dynamicSizeStep, newState); +} + +void FireObj_Update(GlobalContext* globalCtx, FireObj* fire, Actor* actor) { + s32 pad; // Gamestate cast? + EnArrow* arrow = (EnArrow*)fire->collision.base.ac; + + FireObj_UpdateStateTransitions(globalCtx, fire); + if (fire->state == FIRE_STATE_3) { + if ((fire->collision.base.acFlags & AC_HIT) && (fire->collision.info.acHitInfo->toucher.dmgFlags & 0x800)) { + FireObj_SetState(fire, fire->dynamicSizeStep, FIRE_STATE_0); + } + } else if ((fire->collision.base.acFlags & AC_HIT) && (arrow->actor.update != NULL) && + (arrow->actor.id == ACTOR_EN_ARROW)) { + arrow->actor.params = 0; + arrow->collider.info.toucher.dmgFlags = 0x800; + } + fire->collision.dim.pos.x = fire->position.x; + fire->collision.dim.pos.y = fire->position.y; + fire->collision.dim.pos.z = fire->position.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &fire->collision.base); + FireObj_UpdateLight(globalCtx, &fire->light, fire); +} diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index c510c1974..62d55bc00 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -44,8 +44,8 @@ void GameOver_Update(GlobalContext* globalCtx) { } gSaveContext.unk_3DC0 = 2000; - gSaveContext.naviTimer = 0; - gSaveContext.seqIndex = 0xFF; + gSaveContext.save.playerData.tatlTimer = 0; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; gSaveContext.eventInf[0] = 0; gSaveContext.eventInf[1] = 0; @@ -66,17 +66,17 @@ void GameOver_Update(GlobalContext* globalCtx) { gameOverCtx->state = GAMEOVER_DEATH_WAIT_GROUND; break; case GAMEOVER_DEATH_FADE_OUT: - if (func_801A8A50(1) != 32) { - func_80169F78(globalCtx); + if (func_801A8A50(1) != NA_BGM_GAME_OVER) { + func_80169F78(&globalCtx->state); if (gSaveContext.respawnFlag != -7) { gSaveContext.respawnFlag = -6; } gSaveContext.nextTransition = 2; - gSaveContext.health = 48; + gSaveContext.save.playerData.health = 48; gameOverCtx->state++; - if (gSaveContext.inventory.items[SLOT(ITEM_MASK_DEKU)] == ITEM_MASK_DEKU) { - gSaveContext.playerForm = PLAYER_FORM_HUMAN; - gSaveContext.equippedMask = PLAYER_MASK_NONE; + if (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU) { + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.equippedMask = PLAYER_MASK_NONE; } func_8013EE24(); } diff --git a/src/code/z_jpeg.c b/src/code/z_jpeg.c index 395a45835..7b9254ccd 100644 --- a/src/code/z_jpeg.c +++ b/src/code/z_jpeg.c @@ -1,11 +1,307 @@ -#include "global.h" +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "variables.h" +#include "functions.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F42A0.s") +#define MARKER_ESCAPE 0x00 +#define MARKER_SOI 0xD8 +#define MARKER_SOF 0xC0 +#define MARKER_DHT 0xC4 +#define MARKER_DQT 0xDB +#define MARKER_DRI 0xDD +#define MARKER_SOS 0xDA +#define MARKER_APP0 0xE0 +#define MARKER_APP1 0xE1 +#define MARKER_APP2 0xE2 +#define MARKER_COM 0xFE +#define MARKER_EOI 0xD9 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F43BC.s") +extern u64 njpgdspMainTextStart[]; +extern u64 njpgdspMainDataStart[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F44F4.s") +/** + * Configures and schedules a JPEG decoder task and waits for it to finish. + */ +void Jpeg_ScheduleDecoderTask(JpegContext* jpegCtx) { + static OSTask_t sJpegTask = { + M_NJPEGTASK, // type + 0, // flags + NULL, // ucode_boot + 0, // ucode_boot_size + njpgdspMainTextStart, // ucode + 0x1000, // ucode_size + njpgdspMainDataStart, // ucode_data + 0x800, // ucode_data_size + NULL, // dram_stack + 0, // dram_stack_size + NULL, // output_buff + NULL, // output_buff_size + NULL, // data_ptr + sizeof(JpegTaskData), // data_size + NULL, // yield_data_ptr + 0x200, // yield_data_size + }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F4540.s") + JpegWork* workBuf = jpegCtx->workBuf; + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F470C.s") + workBuf->taskData.address = &workBuf->data; + workBuf->taskData.mode = jpegCtx->mode; + workBuf->taskData.mbCount = 4; + workBuf->taskData.qTableYPtr = &workBuf->qTableY; + workBuf->taskData.qTableUPtr = &workBuf->qTableU; + workBuf->taskData.qTableVPtr = &workBuf->qTableV; + + sJpegTask.flags = 0; + sJpegTask.ucodeBoot = SysUcode_GetUCodeBoot(); + sJpegTask.ucodeBootSize = SysUcode_GetUCodeBootSize(); + sJpegTask.yieldDataPtr = (u64*)&workBuf->yieldData; + sJpegTask.dataPtr = (u64*)&workBuf->taskData; + + jpegCtx->scTask.next = NULL; + jpegCtx->scTask.flags = OS_SC_NEEDS_RSP; + jpegCtx->scTask.msgQ = &jpegCtx->mq; + jpegCtx->scTask.msg = NULL; + jpegCtx->scTask.framebuffer = NULL; + jpegCtx->scTask.list.t = sJpegTask; + + osSendMesg(&gSchedContext.cmdQ, (OSMesg)&jpegCtx->scTask, OS_MESG_BLOCK); + Sched_SendEntryMsg(&gSchedContext); // osScKickEntryMsg + osRecvMesg(&jpegCtx->mq, NULL, OS_MESG_BLOCK); +} + +/** + * Copies a 16x16 block of decoded image data to the Z-buffer. + */ +void Jpeg_CopyToZbuffer(u16* src, u16* zbuffer, s32 x, s32 y) { + u16* dst = zbuffer + (((y * SCREEN_WIDTH) + x) * 16); + s32 i; + + for (i = 0; i < 16; i++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + dst[4] = src[4]; + dst[5] = src[5]; + dst[6] = src[6]; + dst[7] = src[7]; + dst[8] = src[8]; + dst[9] = src[9]; + dst[10] = src[10]; + dst[11] = src[11]; + dst[12] = src[12]; + dst[13] = src[13]; + dst[14] = src[14]; + dst[15] = src[15]; + + src += 16; + dst += SCREEN_WIDTH; + } +} + +/** + * Reads an u16 from a possibly unaligned address in memory. + * + * Replaces unaligned 16-bit reads with a pair of aligned reads, allowing for reading the possibly + * unaligned values in JPEG header files. + */ +u16 Jpeg_GetUnalignedU16(u8* ptr) { + if (((u32)ptr & 1) == 0) { + // Read the value normally if it's aligned to a 16-bit address. + return *(u16*)ptr; + } else { + // Read unaligned values using two separate aligned memory accesses when it's not. + return *(u16*)(ptr - 1) << 8 | (*(u16*)(ptr + 1) >> 8); + } +} + +/** + * Parses the markers in the JPEG file, storing information such as the pointer to the image data + * in `jpegCtx` for later processing. + */ +void Jpeg_ParseMarkers(u8* ptr, JpegContext* jpegCtx) { + u32 exit = false; + + jpegCtx->dqtCount = 0; + jpegCtx->dhtCount = 0; + + while (true) { + if (exit) { + break; + } + + // 0xFF indicates the start of a JPEG marker, so look for the next. + if (*ptr++ == 0xFF) { + switch (*ptr++) { + case MARKER_ESCAPE: { + // Compressed value 0xFF is stored as 0xFF00 to escape it, so ignore it. + break; + } + case MARKER_SOI: { + // Start of Image + break; + } + case MARKER_APP0: { + // Application marker for JFIF + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_APP1: { + // Application marker for EXIF + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_APP2: { + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DQT: { + // Define Quantization Table, stored for later processing + jpegCtx->dqtPtr[jpegCtx->dqtCount++] = ptr + 2; + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DHT: { + // Define Huffman Table, stored for later processing + jpegCtx->dhtPtr[jpegCtx->dhtCount++] = ptr + 2; + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DRI: { + // Define Restart Interval + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_SOF: { + // Start of Frame, stores important metadata of the image. + // Only used for extracting the sampling factors (jpegCtx->mode). + + if (ptr[9] == 0x21) { + // component Y : V0 == 1 + jpegCtx->mode = 0; + } else if (ptr[9] == 0x22) { + // component Y : V0 == 2 + jpegCtx->mode = 2; + } + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_SOS: { + // Start of Scan marker, indicates the start of the image data. + ptr += Jpeg_GetUnalignedU16(ptr); + jpegCtx->imageData = ptr; + break; + } + case MARKER_EOI: { + // End of Image + exit = true; + break; + } + default: { + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + } + } + } +} + +s32 Jpeg_Decode(void* data, void* zbuffer, void* work, u32 workSize) { + s32 y; + s32 x; + s32 j; + s32 i; + JpegContext jpegCtx; + JpegHuffmanTable hTables[4]; + JpegDecoder decoder; + JpegDecoderState state; + JpegWork* workBuff = work; + + if (workSize < sizeof(JpegWork)) { + return -1; + } + + osCreateMesgQueue(&jpegCtx.mq, &jpegCtx.msg, 1); + MsgEvent_SendNullTask(); + + jpegCtx.workBuf = workBuff; + + Jpeg_ParseMarkers(data, &jpegCtx); + + switch (jpegCtx.dqtCount) { + case 1: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 3); + break; + + case 2: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableV, 1); + break; + + case 3: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[2], &workBuff->qTableV, 1); + break; + + default: + return -1; + } + + switch (jpegCtx.dhtCount) { + case 1: + if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[0], &hTables[0], workBuff->codesLengths, workBuff->codes, + 4)) { + return -1; + } + break; + + case 4: + // This chained if-else has printfs inside it on debug + if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[0], &hTables[0], workBuff->codesLengths, workBuff->codes, + 1)) { + } else if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[1], &hTables[1], workBuff->codesLengths, + workBuff->codes, 1)) { + } else if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[2], &hTables[2], workBuff->codesLengths, + workBuff->codes, 1)) { + } else if (!JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[3], &hTables[3], workBuff->codesLengths, + workBuff->codes, 1)) { + break; + } + return -1; + + default: + return -1; + } + + decoder.imageData = jpegCtx.imageData; + decoder.mode = jpegCtx.mode; + decoder.unk_05 = 2; + + decoder.hTablePtrs[0] = &hTables[0]; + decoder.hTablePtrs[1] = &hTables[1]; + decoder.hTablePtrs[2] = &hTables[2]; + decoder.hTablePtrs[3] = &hTables[3]; + decoder.unk_18 = 0; + + x = y = 0; + for (i = 0; i < 300; i += 4) { + if (!JpegDecoder_Decode(&decoder, (u16*)workBuff->data, 4, (i != 0), &state)) { + Jpeg_ScheduleDecoderTask(&jpegCtx); + + for (j = 0; j < 4; j++) { + Jpeg_CopyToZbuffer(workBuff->data[j], zbuffer, x, y); + x++; + + if (x >= 20) { + x = 0; + y++; + } + } + } + } + + return 0; +} diff --git a/src/code/z_kaleido_manager.c b/src/code/z_kaleido_manager.c index c79b0067f..5e89f49e9 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 = VRAM_PTR_SIZE(ovl); + 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, VRAM_PTR_SIZE(ovl)); + 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 = VRAM_PTR_SIZE(&gKaleidoMgrOverlayTable[i]); + 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..c3c616669 100644 --- a/src/code/z_kaleido_scope_call.c +++ b/src/code/z_kaleido_scope_call.c @@ -1,11 +1,85 @@ +#include "prevent_bss_reordering.h" #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..5a234ea44 100644 --- a/src/code/z_kaleido_setup.c +++ b/src/code/z_kaleido_setup.c @@ -1,9 +1,145 @@ #include "global.h" +#include "overlays/gamestates/ovl_file_choose/z_file_choose.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4A10.s") +s16 D_801BDB00[] = { PAUSE_1, PAUSE_2, PAUSE_3, PAUSE_0 }; +f32 sKaleidoSetupEyeX[] = { -64.0f, 0.0f, 64.0f, 0.0f }; +f32 sKaleidoSetupEyeZ[] = { 0.0f, -64.0f, 0.0f, 64.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4C0C.s") +void func_800F4A10(GlobalContext* globalCtx) { + PauseContext* pauseCtx = &globalCtx->pauseCtx; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4E20.s") + func_8013EE24(); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4F28.s") + pauseCtx->unk_206 = 0; + pauseCtx->unk_200 = 1; + pauseCtx->eye.x = sKaleidoSetupEyeX[pauseCtx->pageIndex]; + pauseCtx->eye.z = sKaleidoSetupEyeZ[pauseCtx->pageIndex]; + pauseCtx->pageIndex = D_801BDB00[pauseCtx->pageIndex]; + pauseCtx->unk_27E = -40; + + for (i = 0; i < ARRAY_COUNT(pauseCtx->worldMapPoints); i++) { + pauseCtx->worldMapPoints[i] = 0; + } + + if (pauseCtx->state == 1) { + for (i = 0; i < 11; i++) { + if ((gSaveContext.save.mapsVisited >> i) & 1) { + pauseCtx->worldMapPoints[i] = 1; + } + } + } else { + for (i = 9; i >= 0; i--) { + if ((gSaveContext.save.playerData.owlActivationFlags >> i) & 1) { + pauseCtx->worldMapPoints[i] = 1; + pauseCtx->unk_238[4] = i; + } + } + + if ((gSaveContext.save.playerData.owlActivationFlags >> 4) & 1) { + pauseCtx->unk_238[4] = 4; + } + } + + YREG(11) = -0x00C8; + YREG(12) = -0x3840; + YREG(13) = 0x2710; + YREG(14) = 0x2710; + YREG(15) = 0x2710; + YREG(16) = -0x00BE; + YREG(17) = -0x06D6; + YREG(18) = -0x0B90; + YREG(19) = 0x06E0; + YREG(20) = 0; + YREG(21) = -0x0622; + YREG(22) = -0x0C44; + YREG(23) = 0x0622; + YREG(24) = -0x0622; + YREG(25) = -0x005A; + YREG(26) = -0x3840; +} + +void KaleidoSetup_Update(GlobalContext* globalCtx) { + Input* input = CONTROLLER1(globalCtx); + MessageContext* msgCtx = &globalCtx->msgCtx; + Player* player = GET_PLAYER(globalCtx); + PauseContext* pauseCtx = &globalCtx->pauseCtx; + + if (CHECK_BTN_ALL(input->cur.button, BTN_R)) { + if (msgCtx && msgCtx) {} + } + + if ((pauseCtx->state == 0) && (pauseCtx->debugState == 0) && (globalCtx->gameOverCtx.state == GAMEOVER_INACTIVE)) { + if ((globalCtx->sceneLoadFlag == 0) && (globalCtx->unk_18B4A == 0)) { + if ((gSaveContext.save.cutscene < 0xFFF0) && (gSaveContext.nextCutsceneIndex < 0xFFF0)) { + if (!Play_InCsMode(globalCtx) || ((msgCtx->msgMode != 0) && (msgCtx->currentTextId == 0xFF))) { + if ((globalCtx->unk_1887C < 2) && (gSaveContext.unk_3F28 != 8) && (gSaveContext.unk_3F28 != 9)) { + if (!(gSaveContext.eventInf[1] & 0x80) && !(player->stateFlags1 & 0x20)) { + if (!(globalCtx->actorCtx.unk5 & 2) && !(globalCtx->actorCtx.unk5 & 4)) { + if ((globalCtx->actorCtx.unk268 == 0) && + CHECK_BTN_ALL(input->press.button, BTN_START)) { + gSaveContext.unk_3F26 = gSaveContext.unk_3F22; + pauseCtx->unk_2B9 = 0; + pauseCtx->state = 1; + func_800F4A10(globalCtx); + pauseCtx->mode = pauseCtx->pageIndex * 2 + 1; + func_801A3A7C(1); + } + + if (pauseCtx->state == 1) { + Game_SetFramerateDivisor(&globalCtx->state, 2); + if (ShrinkWindow_GetLetterboxTarget() != 0) { + ShrinkWindow_SetLetterboxTarget(0); + } + func_801A3AEC(1); + } + } + } + } + } + } + } + } +} + +void KaleidoSetup_Init(GlobalContext* globalCtx) { + PauseContext* pauseCtx = &globalCtx->pauseCtx; + s32 pad[2]; + + bzero(pauseCtx, sizeof(PauseContext)); + + pauseCtx->pageIndex = PAUSE_0; + + pauseCtx->unk_21C = 160.0f; + pauseCtx->unk_218 = 160.0f; + pauseCtx->unk_214 = 160.0f; + pauseCtx->unk_210 = 160.0f; + + pauseCtx->eye.x = -64.0f; + pauseCtx->unk_20C = 936.0f; + pauseCtx->unk_220 = -314.0f; + + pauseCtx->unk_238[PAUSE_1] = XREG(94) + 3; + + pauseCtx->unk_258 = 11; + pauseCtx->unk_25A = 0; + + pauseCtx->unk_25E[PAUSE_0] = 999; + pauseCtx->unk_25E[PAUSE_1] = XREG(94) + 3; + pauseCtx->unk_25E[PAUSE_2] = 999; + pauseCtx->unk_25E[PAUSE_3] = 999; + + pauseCtx->unk_268[PAUSE_0] = 0; + pauseCtx->unk_268[PAUSE_1] = XREG(94) + 3; + + pauseCtx->unk_284 = 2; + pauseCtx->unk_2A0 = -1; + pauseCtx->unk_2BA = 320; + pauseCtx->unk_2BC = 40; + pauseCtx->unk_29E = 100; + + View_Init(&pauseCtx->view, globalCtx->state.gfxCtx); +} + +void KaleidoSetup_Destroy(GlobalContext* globalCtx) { +} diff --git a/src/code/z_kanfont.c b/src/code/z_kanfont.c index b678642b1..2a4849ccb 100644 --- a/src/code/z_kanfont.c +++ b/src/code/z_kanfont.c @@ -19,11 +19,13 @@ void Font_LoadMessageBoxEndIcon(Font* font, u16 icon) { FONT_CHAR_TEX_SIZE); } -static u8 sFontOrdering[] = "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19" - "!\"#$%&\'()*+,-./0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "\x00\x0D\x0E\x1A" - "afjmosvwxyz{|}~" - "\x7F\x80\x81\x84\x86\x87\x88\x89\x8A\x8B\x8C"; +static u8 sFontOrdering[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5A, 0x00, 0x0D, 0x0E, 0x1A, 0x61, 0x66, 0x6A, 0x6D, 0x6F, 0x73, 0x76, 0x77, 0x78, 0x79, + 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x84, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, +}; void Font_LoadOrderedFont(Font* font) { u32 loadOffset; @@ -36,7 +38,7 @@ void Font_LoadOrderedFont(Font* font) { if (sFontOrdering[codePointIndex] == 0) { loadOffset = 0; } - // UB to convert pointer to u32 + DmaMgr_SendRequest0(writeLocation, (uintptr_t)SEGMENT_ROM_START(nes_font_static) + loadOffset, FONT_CHAR_TEX_SIZE); if (sFontOrdering[codePointIndex] == 0x8C) { diff --git a/src/code/z_kankyo.c b/src/code/z_kankyo.c index 6221e0910..ad66fe4a1 100644 --- a/src/code/z_kankyo.c +++ b/src/code/z_kankyo.c @@ -8,7 +8,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5954.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5A8C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_LerpWeight.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800F5B10.s") @@ -64,7 +64,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB010.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB320.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/Environment_AddLightningBolts.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_kankyo/func_800FB388.s") diff --git a/src/code/z_lib.c b/src/code/z_lib.c index 5bc49c8ac..aaf4bc7d9 100644 --- a/src/code/z_lib.c +++ b/src/code/z_lib.c @@ -371,7 +371,7 @@ void Math_Vec3f_DistXYZAndStoreNormDiff(Vec3f* a, Vec3f* b, f32 scale, Vec3f* de f32 Math_Vec3f_DistXYZ(Vec3f* a, Vec3f* b) { Vec3f diff; Math_Vec3f_Diff(b, a, &diff); - return sqrtf(SQ(diff.x) + SQ(diff.y) + SQ(diff.z)); + return sqrtf(SQXYZ(diff)); } f32 Math_Vec3f_DistXYZAndStoreDiff(Vec3f* a, Vec3f* b, Vec3f* dest) { @@ -578,7 +578,7 @@ void Math_ApproachZeroF(f32* pValue, f32 scale, f32 maxStep) { *pValue = *pValue - f0; } -s32 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep) { +s16 Math_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step, s16 minStep) { s16 stepSize = 0; s16 diff = target - *pValue; @@ -647,8 +647,8 @@ void func_801000CC(u16 sfxId) { func_8019F128(sfxId); } -void func_801000F4(s32 a0, u16 sfxId) { - func_8019F1C0(a0, sfxId); +void Lib_PlaySfxAtPos(Vec3f* pos, u16 sfxId) { + Audio_PlaySfxAtPos(pos, sfxId); } void Lib_Vec3f_TranslateAndRotateY(Vec3f* translation, s16 a, Vec3f* src, Vec3f* dst) { diff --git a/src/code/z_lifemeter.c b/src/code/z_lifemeter.c index 73a59f477..73ba326b5 100644 --- a/src/code/z_lifemeter.c +++ b/src/code/z_lifemeter.c @@ -1,45 +1,44 @@ +#include "prevent_bss_reordering.h" #include "global.h" +#include "interface/parameter_static/parameter_static.h" #include "prevent_bss_reordering.h" -static s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } }; -static s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } }; -static s16 sHeartsPrimFactors[3][3] = { { 0, 0, 0 }, { 0, 120, -50 }, { -155, 30, 205 } }; -static s16 sHeartsEnvFactors[3][3] = { { 0, 0, 0 }, { 205, -40, -60 }, { -50, -40, 195 } }; -static s16 sHeartsDDPrimColors[3][3] = { { 255, 255, 255 }, { 255, 190, 0 }, { 100, 100, 255 } }; -static s16 sHeartsDDEnvColors[3][3] = { { 200, 0, 0 }, { 255, 0, 0 }, { 0, 0, 255 } }; -static s16 sHeartsDDPrimFactors[3][3] = { { 0, 0, 0 }, { 0, -65, -255 }, { -155, -155, 0 } }; -static s16 sHeartsDDEnvFactors[3][3] = { { 0, 0, 0 }, { 55, 0, 0 }, { -200, 0, 255 } }; +s16 sHeartsPrimColors[3][3] = { { 255, 70, 50 }, { 255, 190, 0 }, { 100, 100, 255 } }; +s16 sHeartsEnvColors[3][3] = { { 50, 40, 60 }, { 255, 0, 0 }, { 0, 0, 255 } }; +s16 sHeartsPrimFactors[3][3] = { { 0, 0, 0 }, { 0, 120, -50 }, { -155, 30, 205 } }; +s16 sHeartsEnvFactors[3][3] = { { 0, 0, 0 }, { 205, -40, -60 }, { -50, -40, 195 } }; +s16 sHeartsDDPrimColors[3][3] = { { 255, 255, 255 }, { 255, 190, 0 }, { 100, 100, 255 } }; +s16 sHeartsDDEnvColors[3][3] = { { 200, 0, 0 }, { 255, 0, 0 }, { 0, 0, 255 } }; +s16 sHeartsDDPrimFactors[3][3] = { { 0, 0, 0 }, { 0, -65, -255 }, { -155, -155, 0 } }; +s16 sHeartsDDEnvFactors[3][3] = { { 0, 0, 0 }, { 55, 0, 0 }, { -200, 0, 255 } }; s16 sBeatingHeartsDDPrim[3]; s16 sBeatingHeartsDDEnv[3]; s16 sHeartsDDPrim[2][3]; s16 sHeartsDDEnv[2][3]; -extern TexturePtr D_02000000; // Empty heart texture -extern TexturePtr D_02000100; // Quarter Heart Texture -extern TexturePtr D_02000200; // Half Heart Texture -extern TexturePtr D_02000300; // Three Quarter Heart Texture -extern TexturePtr D_02000400; // Full heart texture -extern TexturePtr D_02000500; // Empty Double Defense Heart texture -extern TexturePtr D_02000600; // Quarter Double Defense Heart Texture -extern TexturePtr D_02000700; // Half Double Defense Heart Texture -extern TexturePtr D_02000800; // Three Quarter Double Defense Heart Texture -extern TexturePtr D_02000900; // Full Double Defense Heart texture +TexturePtr HeartTextures[] = { + gHeartFullTex, gHeartQuarterTex, gHeartQuarterTex, gHeartQuarterTex, + gHeartQuarterTex, gHeartQuarterTex, gHeartHalfTex, gHeartHalfTex, + gHeartHalfTex, gHeartHalfTex, gHeartHalfTex, gHeartThreeQuarterTex, + gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex, gHeartThreeQuarterTex, +}; -TexturePtr HeartTextures[] = { &D_02000400, &D_02000100, &D_02000100, &D_02000100, &D_02000100, &D_02000100, - &D_02000200, &D_02000200, &D_02000200, &D_02000200, &D_02000200, &D_02000300, - &D_02000300, &D_02000300, &D_02000300, &D_02000300 }; - -TexturePtr HeartDDTextures[] = { &D_02000900, &D_02000600, &D_02000600, &D_02000600, &D_02000600, &D_02000600, - &D_02000700, &D_02000700, &D_02000700, &D_02000700, &D_02000700, &D_02000800, - &D_02000800, &D_02000800, &D_02000800, &D_02000800 }; +TexturePtr HeartDDTextures[] = { + gDefenseHeartFullTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex, + gDefenseHeartQuarterTex, gDefenseHeartQuarterTex, gDefenseHeartQuarterTex, + gDefenseHeartHalfTex, gDefenseHeartHalfTex, gDefenseHeartHalfTex, + gDefenseHeartHalfTex, gDefenseHeartHalfTex, gDefenseHeartThreeQuarterTex, + gDefenseHeartThreeQuarterTex, gDefenseHeartThreeQuarterTex, gDefenseHeartThreeQuarterTex, + gDefenseHeartThreeQuarterTex, +}; void LifeMeter_Init(GlobalContext* globalCtx) { InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx; interfaceCtx->unkTimer = 320; - interfaceCtx->health = gSaveContext.health; + interfaceCtx->health = gSaveContext.save.playerData.health; interfaceCtx->lifeColorChange = 0; interfaceCtx->lifeColorChangeDirection = 0; @@ -169,7 +168,7 @@ void LifeMeter_UpdateColors(GlobalContext* globalCtx) { } s32 LifeMeter_SaveInterfaceHealth(GlobalContext* globalCtx) { - gSaveContext.health = globalCtx->interfaceCtx.health; + gSaveContext.save.playerData.health = globalCtx->interfaceCtx.health; return 1; } @@ -179,8 +178,8 @@ s32 LifeMeter_IncreaseInterfaceHealth(GlobalContext* globalCtx) { interfaceCtx->unkTimer = 320; interfaceCtx->health += 0x10; - if (globalCtx->interfaceCtx.health >= gSaveContext.health) { - globalCtx->interfaceCtx.health = gSaveContext.health; + if (globalCtx->interfaceCtx.health >= gSaveContext.save.playerData.health) { + globalCtx->interfaceCtx.health = gSaveContext.save.playerData.health; return 1; } return 0; @@ -196,7 +195,7 @@ s32 LifeMeter_DecreaseInterfaceHealth(GlobalContext* globalCtx) { interfaceCtx->health -= 0x10; if (interfaceCtx->health <= 0) { interfaceCtx->health = 0; - globalCtx->damagePlayer(globalCtx, -(((void)0, gSaveContext.health) + 1)); + globalCtx->damagePlayer(globalCtx, -(((void)0, gSaveContext.save.playerData.health) + 1)); return 1; } } @@ -217,18 +216,18 @@ void LifeMeter_Draw(GlobalContext* globalCtx) { GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx; Vtx* beatingHeartVtx = interfaceCtx->beatingHeartVtx; - s32 fractionHeartCount = gSaveContext.health % 0x10; - s16 healthCapacity = gSaveContext.healthCapacity / 0x10; - s16 fullHeartCount = gSaveContext.health / 0x10; + s32 fractionHeartCount = gSaveContext.save.playerData.health % 0x10; + s16 healthCapacity = gSaveContext.save.playerData.healthCapacity / 0x10; + s16 fullHeartCount = gSaveContext.save.playerData.health / 0x10; s32 pad2; f32 lifesize = interfaceCtx->lifeSizeChange * 0.1f; u32 curCombineModeSet = 0; TexturePtr temp = NULL; - s32 ddCount = gSaveContext.inventory.dungeonKeys[9] - 1; + s32 ddCount = gSaveContext.save.inventory.dungeonKeys[9] - 1; OPEN_DISPS(gfxCtx); - if ((gSaveContext.health % 0x10) == 0) { + if ((gSaveContext.save.playerData.health % 0x10) == 0) { fullHeartCount--; } offsetY = 0.0f; @@ -277,11 +276,11 @@ void LifeMeter_Draw(GlobalContext* globalCtx) { } if (i < fullHeartCount) { - heartTex = &D_02000400; + heartTex = gHeartFullTex; } else if (i == fullHeartCount) { heartTex = HeartTextures[fractionHeartCount]; } else { - heartTex = &D_02000000; + heartTex = gHeartEmptyTex; } } else { if (i < fullHeartCount) { @@ -317,11 +316,11 @@ void LifeMeter_Draw(GlobalContext* globalCtx) { gDPSetEnvColor(OVERLAY_DISP++, sHeartsDDEnv[1][0], sHeartsDDEnv[1][1], sHeartsDDEnv[1][2], 255); } if (i < fullHeartCount) { - heartTex = &D_02000900; + heartTex = gDefenseHeartFullTex; } else if (i == fullHeartCount) { heartTex = HeartDDTextures[fractionHeartCount]; } else { - heartTex = &D_02000500; + heartTex = gDefenseHeartEmptyTex; } } @@ -400,9 +399,8 @@ void LifeMeter_UpdateSizeAndBeep(GlobalContext* globalCtx) { if (interfaceCtx->lifeSizeChange <= 0) { interfaceCtx->lifeSizeChange = 0; interfaceCtx->lifeSizeChangeDirection = 0; - if (func_801233E4(globalCtx) == 0 && (globalCtx->pauseCtx.state == 0) && - (globalCtx->pauseCtx.debugState == 0) && LifeMeter_IsCritical() && func_801690CC(globalCtx) == 0) { - // func_801233E4 and func_801690CC : Check if in Cutscene + if (!Player_InCsMode(&globalCtx->state) && (globalCtx->pauseCtx.state == 0) && + (globalCtx->pauseCtx.debugState == 0) && LifeMeter_IsCritical() && !Play_InCsMode(globalCtx)) { play_sound(NA_SE_SY_HITPOINT_ALARM); } } @@ -418,19 +416,19 @@ void LifeMeter_UpdateSizeAndBeep(GlobalContext* globalCtx) { u32 LifeMeter_IsCritical(void) { s16 criticalThreshold; - if (gSaveContext.healthCapacity <= 80) { // healthCapacity <= 5 hearts? + if (gSaveContext.save.playerData.healthCapacity <= 80) { // healthCapacity <= 5 hearts? criticalThreshold = 16; - } else if (gSaveContext.healthCapacity <= 160) { // healthCapacity <= 10 hearts? + } else if (gSaveContext.save.playerData.healthCapacity <= 160) { // healthCapacity <= 10 hearts? criticalThreshold = 24; - } else if (gSaveContext.healthCapacity <= 240) { // healthCapacity <= 15 hearts? + } else if (gSaveContext.save.playerData.healthCapacity <= 240) { // healthCapacity <= 15 hearts? criticalThreshold = 32; } else { criticalThreshold = 44; } - if ((criticalThreshold >= gSaveContext.health) && (gSaveContext.health > 0)) { + if ((criticalThreshold >= gSaveContext.save.playerData.health) && (gSaveContext.save.playerData.health > 0)) { return true; } return false; diff --git a/src/code/z_lights.c b/src/code/z_lights.c index 80d3f7131..e9fae530a 100644 --- a/src/code/z_lights.c +++ b/src/code/z_lights.c @@ -1,4 +1,7 @@ #include "global.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +LightsBuffer sLightsBuffer; void Lights_PointSetInfo(LightInfo* info, s16 x, s16 y, s16 z, u8 r, u8 g, u8 b, s16 radius, s32 type) { info->type = type; @@ -127,11 +130,12 @@ void Lights_BindPoint(Lights* lights, LightParams* params, GlobalContext* global Vec3f posF; Vec3f adjustedPos; u32 pad; + if (radiusF > 0) { 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); @@ -212,7 +216,7 @@ void Lights_BindAll(Lights* lights, LightNode* listHead, Vec3f* refPos, GlobalCo } } -LightNode* Lights_FindBufSlot() { +LightNode* Lights_FindBufSlot(void) { LightNode* ret; if (sLightsBuffer.numOccupied >= LIGHTS_BUFFER_SIZE) { @@ -329,9 +333,7 @@ Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 Lights* lights; s32 i; - // TODO allocation should be a macro - lights = (Lights*)((int)gfxCtx->polyOpa.d - sizeof(Lights)); - gfxCtx->polyOpa.d = (void*)lights; + lights = GRAPH_ALLOC(gfxCtx, sizeof(Lights)); lights->l.a.l.col[0] = lights->l.a.l.colc[0] = ambientR; lights->l.a.l.col[1] = lights->l.a.l.colc[1] = ambientG; @@ -356,9 +358,7 @@ Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB) { Lights* lights; - // TODO allocation should be a macro - lights = (Lights*)((int)gfxCtx->polyOpa.d - sizeof(Lights)); - gfxCtx->polyOpa.d = (void*)lights; + lights = GRAPH_ALLOC(gfxCtx, sizeof(Lights)); lights->l.a.l.col[0] = ambientR; lights->l.a.l.colc[0] = ambientR; @@ -376,7 +376,7 @@ void Lights_GlowCheck(GlobalContext* globalCtx) { LightNode* light = globalCtx->lightCtx.listHead; while (light != NULL) { - LightPoint* params = (LightPoint*)&light->info->params; + LightPoint* params = &light->info->params.point; if (light->info->type == LIGHT_POINT_GLOW) { Vec3f pos; @@ -386,7 +386,7 @@ void Lights_GlowCheck(GlobalContext* globalCtx) { pos.x = params->x; pos.y = params->y; pos.z = params->z; - func_800B4EDC(globalCtx, &pos, &multDest, &wDest); + Actor_GetProjectedPos(globalCtx, &pos, &multDest, &wDest); params->drawGlow = 0; @@ -416,29 +416,28 @@ void Lights_DrawGlow(GlobalContext* globalCtx) { dl = func_8012C7FC(POLY_XLU_DISP); - gSPSetOtherMode(dl++, G_SETOTHERMODE_H, 4, 4, - 0x00000080); //! This doesn't resolve to any of the macros in gdi.h + gDPSetDither(dl++, G_CD_NOISE); gDPSetCombineLERP(dl++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); - gSPDisplayList(dl++, D_04029CB0); + gSPDisplayList(dl++, gameplay_keep_DL_029CB0); do { if (light->info->type == LIGHT_POINT_GLOW) { - params = (LightPoint*)&light->info->params; + params = &light->info->params.point; if (params->drawGlow) { f32 scale = SQ((f32)params->radius) * 2e-6f; gDPSetPrimColor(dl++, 0, 0, params->color[0], params->color[1], params->color[2], 50); - Matrix_InsertTranslation(params->x, params->y, params->z, MTXMODE_NEW); + Matrix_Translate(params->x, params->y, params->z, MTXMODE_NEW); Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(dl++, D_04029CF0); + gSPDisplayList(dl++, gameplay_keep_DL_029CF0); } } diff --git a/src/code/z_malloc.c b/src/code/z_malloc.c index 8d0bba44a..781f4310e 100644 --- a/src/code/z_malloc.c +++ b/src/code/z_malloc.c @@ -1,4 +1,7 @@ #include "global.h" +#include "os_malloc.h" + +Arena sZeldaArena; void* ZeldaArena_Malloc(size_t size) { void* ptr = __osMalloc(&sZeldaArena, size); @@ -34,11 +37,11 @@ void* ZeldaArena_Calloc(u32 num, size_t size) { } void ZeldaArena_GetSizes(size_t* outMaxFree, size_t* outFree, size_t* outAlloc) { - __osAnalyzeArena(&sZeldaArena, outMaxFree, outFree, outAlloc); + __osGetSizes(&sZeldaArena, outMaxFree, outFree, outAlloc); } -void ZeldaArena_Check() { - __osCheckArena(&sZeldaArena); +s32 ZeldaArena_Check() { + return __osCheckArena(&sZeldaArena); } void ZeldaArena_Init(void* start, size_t size) { diff --git a/src/code/z_message.c b/src/code/z_message.c index 0bfbdc53d..2a90f38ca 100644 --- a/src/code/z_message.c +++ b/src/code/z_message.c @@ -1,14 +1,111 @@ #include "global.h" +#include "message_data_static.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80147520.s") +#if 0 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80147564.s") +s16 D_801D02D8[15] = { + ACTOR_OCEFF_WIPE5, ACTOR_OCEFF_WIPE5, // Sonata of Awakening Effect, Sonata of Awakening Effect + ACTOR_OCEFF_WIPE5, ACTOR_OCEFF_WIPE5, // Sonata of Awakening Effect, Sonata of Awakening Effect + ACTOR_OCEFF_WIPE5, ACTOR_OCEFF_WIPE5, // Sonata of Awakening Effect, Sonata of Awakening Effect + ACTOR_OCEFF_WIPE, ACTOR_OCEFF_WIPE7, // Song of Time Effect, Song of Healing Effect + ACTOR_OCEFF_WIPE2, ACTOR_OCEFF_WIPE6, // Epona's Song Effect, Song of Soaring Effect + ACTOR_OCEFF_STORM, ACTOR_OCEFF_SPOT, // Song of Storms Effect II [?], Sun's Song Effect + ACTOR_OCEFF_WIPE, ACTOR_OCEFF_WIPE, // Song of Time Effect, Song of Time Effect + ACTOR_OCEFF_WIPE4 // Scarecrow's Song Effect +}; +s32 D_801D02F8[15] = { 0,1,2,3,4,0,1,0,0,0,0,0,1,1,0 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80147624.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80147734.s") +extern u16 D_801C6AB8[]; +extern u16 D_801C6B28[]; +extern s16 D_801D02D8[]; +extern s32 D_801D02F8[]; +extern s16 D_801F6B0C; +extern s16 D_801F6B0E; +extern s16 D_801F6B10; +extern s16 D_801F6B12; +extern s16 D_801F6B14; +extern s16 D_801F6B16; +extern s16 D_801F6B18; +extern s16 D_801F6B1A; +extern s16 D_801F6B1C; +extern s16 D_801F6B1E; +extern s16 D_801F6B20; +extern s16 D_801F6B22; +extern MessageTableEntry D_801C6B98[]; +extern MessageTableEntry D_801CFB08[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801477B4.s") +void func_80147520(void) { + D_801CFC98 = 0xFF; + D_801CFCA4[0] = D_801CFCA4[1] = D_801CFCA4[2] = D_801CFCA4[3] = D_801CFCA4[4] = D_801CFCA4[5] = D_801CFCA4[6] = + D_801CFCA4[7] = D_801CFCA4[8] = 0; +} + +void func_80147564(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + + msgCtx->unk1204A[0] = 0xBD; + msgCtx->unk1204A[1] = 0xB8; + msgCtx->unk1204A[2] = 0xB3; + msgCtx->unk1204A[3] = 0xAE; + msgCtx->unk1204A[4] = 0xA9; + func_80147520(); + D_801F6B0C = 0x50; + D_801F6B10 = 0x96; + D_801F6B0E = 0xFF; + D_801F6B12 = 0xA; + D_801F6B16 = 0xA; + D_801F6B14 = 0xA; + D_801F6B18 = 0xFF; + D_801F6B1C = 0xFF; + D_801F6B1A = 0x32; + D_801F6B1E = 0xA; + D_801F6B22 = 0xA; + D_801F6B20 = 0xA; +} + +s32 Message_ShouldAdvance(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Input* controller = CONTROLLER1(globalCtx); + + if ((msgCtx->unk12020 == 0x10) || (msgCtx->unk12020 == 0x11)) { + if (CHECK_BTN_ALL(controller->press.button, BTN_A)) { + play_sound(NA_SE_SY_MESSAGE_PASS); + } + return CHECK_BTN_ALL(controller->press.button, BTN_A); + } else { + if (CHECK_BTN_ALL(controller->press.button, BTN_A) || CHECK_BTN_ALL(controller->press.button, BTN_B) || + CHECK_BTN_ALL(controller->press.button, BTN_CUP)) { + play_sound(NA_SE_SY_MESSAGE_PASS); + } + return CHECK_BTN_ALL(controller->press.button, BTN_A) || CHECK_BTN_ALL(controller->press.button, BTN_B) || + CHECK_BTN_ALL(controller->press.button, BTN_CUP); + } +} + +s32 Message_ShouldAdvanceSilent(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Input* controller = CONTROLLER1(globalCtx); + + if (msgCtx->unk12020 == 0x10 || msgCtx->unk12020 == 0x11) { + return CHECK_BTN_ALL(controller->press.button, BTN_A); + } else { + return CHECK_BTN_ALL(controller->press.button, BTN_A) || CHECK_BTN_ALL(controller->press.button, BTN_B) || + CHECK_BTN_ALL(controller->press.button, BTN_CUP); + } +} + +void func_801477B4(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + + if (globalCtx->msgCtx.unk11F10 != 0) { + msgCtx->unk12023 = 2; + msgCtx->msgMode = 0x43; + msgCtx->unk12020 = 0; + play_sound(NA_SE_PL_WALK_GROUND - SFX_FLAG); + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80147818.s") @@ -16,9 +113,51 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80148558.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80148B98.s") +#ifdef NON_MATCHING +void func_80148B98(GlobalContext* globalCtx, u8 arg1) { + static s16 held = 0; + MessageContext* msgCtx = &globalCtx->msgCtx; + Input* curInput = CONTROLLER1(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80148CBC.s") + if ((curInput->rel.stick_y > 29) && held == 0) { + held = 1; + msgCtx->choiceIndex--; + if (msgCtx->choiceIndex > 128) { + msgCtx->choiceIndex = 0; + } else { + play_sound(NA_SE_SY_CURSOR); + } + return; + } else if ((curInput->rel.stick_y < -29) && held == 0) { + held = 1; + msgCtx->choiceIndex++; + if (msgCtx->choiceIndex > arg1) { + msgCtx->choiceIndex = arg1; + } else { + play_sound(NA_SE_SY_CURSOR); + } + return; + } else { + if (ABS_ALT(curInput->rel.stick_y) < 30) { + held = 0; + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80148B98.s") +#endif + +void func_80148CBC(GlobalContext* globalCtx, UNK_PTR puParm2, u8 arg2) { + MessageContext* msgCtx = &globalCtx->msgCtx; + + msgCtx->unk11FF4 = 0x30; + if (arg2 == 1) { + msgCtx->unk11FF6 = msgCtx->unk11FFE[1 + msgCtx->choiceIndex]; + } else { + msgCtx->unk11FF6 = msgCtx->unk11FFE[msgCtx->choiceIndex]; + } + func_80147818(globalCtx, puParm2, msgCtx->unk11FF4, msgCtx->unk11FF6); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80148D64.s") @@ -34,7 +173,33 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80149C18.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80149EBC.s") +void Message_FindMessage(GlobalContext* globalCtx, u16 textId) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Font* font = &msgCtx->font; + MessageTableEntry* msgEntry = msgCtx->messageEntryTable; + const char* segment = msgEntry->segment; + const char* foundSegment; + const char* nextSegment; + + while (msgEntry->textId != 0xFFFF) { + if (msgEntry->textId == textId) { + foundSegment = msgEntry->segment; + msgEntry++; + nextSegment = msgEntry->segment; + font->messageStart = foundSegment - segment; + font->messageEnd = nextSegment - foundSegment; + return; + } + msgEntry++; + } + + msgEntry = msgCtx->messageEntryTable; + foundSegment = msgEntry->segment; + msgEntry++; + nextSegment = msgEntry->segment; + font->messageStart = foundSegment - segment; + font->messageEnd = nextSegment - foundSegment; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80149F74.s") @@ -44,9 +209,43 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014C70C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014CC14.s") +void Message_LoadChar(GlobalContext* globalCtx, u16 codePointIndex, s32* offset, f32* arg3, s16 decodedBufPos) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s32 temp1 = *offset; + f32 temp2 = *arg3; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014CCB4.s") + Font_LoadChar(globalCtx, codePointIndex, temp1); + msgCtx->decodedBuffer.wchar[decodedBufPos] = codePointIndex; + temp1 += FONT_CHAR_TEX_SIZE; + temp2 += (16.0f * msgCtx->unk12098); + *offset = temp1; + *arg3 = temp2; +} + +// Message_LoadRupees JPN ? +void func_8014CCB4(GlobalContext* globalCtx, s16* decodedBufPos, s32* offset, f32* arg3) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 t = *decodedBufPos; + s32 k = *offset; + f32 f = *arg3; + + Font_LoadChar(globalCtx, 0x838B, k); // 0x838b = ル in JISX0213 + k += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.wchar[t] = 0x838B; + t += 1; + Font_LoadChar(globalCtx, 0x8373, k); // 0x8373 = ピ in JISX0213 + k += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.wchar[t] = 0x8373; + t += 1; + Font_LoadChar(globalCtx, 0x815C, k); // Ox815C = ― in JISX0213 + k += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.wchar[t] = 0x815C; + + f += 16.0f * msgCtx->unk12098 * 3.0f; + *decodedBufPos = t; + *offset = k; + *arg3 = f; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014CDF0.s") @@ -54,7 +253,62 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D304.s") +#ifdef NON_EQUIVALENT +extern u16* D_801D0188; +extern s16* D_801D0250; + +void func_8014D62C(GlobalContext* arg0, s32* arg1, f32* arg2, s16* arg3) { + f32 sp3C; + s16 temp_s0; + s16 temp_s1; + s16 temp_s1_2; + s16 temp_s6; + s32 temp_s2; + s32 temp_s2_2; + u16* temp_v0; + s16 phi_v0; + s16 phi_s0; + s16 phi_s1; + s32 phi_s2; + s16 phi_s1_2; + s32 phi_s2_2; + + temp_s1 = *arg3; + temp_s2 = *arg1; + sp3C = *arg2; + if ((func_8010A0A4(arg0) != 0) || (arg0->sceneNum == 0x4F)) { + phi_v0 = 0xA; + } else { + phi_v0 = arg0->pauseCtx.unk_238[4]; + } + temp_s6 = *(&D_801D0250 + (phi_v0 * 2)); + phi_s0 = 0; + phi_s1_2 = temp_s1; + phi_s2_2 = temp_s2; + if ((s32)temp_s6 > 0) { + phi_s1 = temp_s1; + phi_s2 = temp_s2; + do { + temp_v0 = (phi_v0 * 0x12) + &D_801D0188 + (phi_s0 * 2); + (arg0 + 0x4908 + (phi_s1 * 2))->decodedBuffer = (u16)*temp_v0; + Font_LoadChar(arg0, *temp_v0, phi_s2); + temp_s0 = phi_s0 + 1; + temp_s1_2 = phi_s1 + 1; + temp_s2_2 = phi_s2 + 0x80; + phi_s0 = temp_s0; + phi_s1 = temp_s1_2; + phi_s2 = temp_s2_2; + phi_s1_2 = temp_s1_2; + phi_s2_2 = temp_s2_2; + } while ((s32)temp_s0 < (s32)temp_s6); + } + *arg3 = phi_s1_2 - 1; + *arg1 = phi_s2_2; + *arg2 = sp3C + ((f32)(temp_s6 - 1) * (16.0f * arg0->msgCtx.unk12098)); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D62C.s") +#endif #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8014D7B4.s") @@ -64,46 +318,239 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801514B0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801518B0.s") +void Message_StartTextbox(GlobalContext* globalCtx, u16 textId, Actor* Actor) { + MessageContext* msgCtx = &globalCtx->msgCtx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151938.s") + msgCtx->ocarinaAction = 0xFFFF; + func_80150D08(globalCtx, textId); + msgCtx->unkActor = Actor; + msgCtx->msgMode = 1; + msgCtx->unk12023 = 0; + msgCtx->unk12024 = 0; + globalCtx->msgCtx.ocarinaMode = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151A68.s") +void func_80151938(GlobalContext* globalCtx, u16 textId) { + MessageContext* msgCtx = &globalCtx->msgCtx; + InterfaceContext* interfaceCtx = &globalCtx->interfaceCtx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151BB4.s") + msgCtx->unk11F10 = 0; + func_80150D08(globalCtx, textId); + func_80150A84(globalCtx); + msgCtx->msgMode = 5; + msgCtx->unk12023 = 8; + msgCtx->unk12024 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151C9C.s") + if (interfaceCtx->unk_222 == 0) { + if (textId != 0x1B93) { + func_8011552C(globalCtx, 0x10); + } else if (textId != 0xF8) { + func_8011552C(globalCtx, 6); + } + } + msgCtx->unk1203C = msgCtx->unk1203A; + + if (globalCtx->pauseCtx.unk_1F0 != 0) { + msgCtx->unk12004 = 0x22; + msgCtx->unk12006 = 0x15E; + func_80149C18(globalCtx); + msgCtx->unk12023 = 1; + } +} + +void func_80151A68(GlobalContext* globalCtx, u16 textId) { + MessageContext* msgCtx = &globalCtx->msgCtx; + + msgCtx->unk11F10 = 0; + func_80150D08(globalCtx, textId); + func_80150A84(globalCtx); + func_8015B198(globalCtx); + msgCtx->msgMode = 0x45; + msgCtx->unk12024 = 0; + msgCtx->unk1203C = msgCtx->unk1203A = msgCtx->unk1201E = 0; + msgCtx->unk12023 = 0x1E; + + // Day/Dawn/Night.. Messages + if ((msgCtx->currentTextId >= 0x1BB2) && (msgCtx->currentTextId < 0x1BB7)) { + XREG(74) = 0x6A; + XREG(75) = 0; + XREG(77) = 0x58; + XREG(76) = 0x44; + } else { + XREG(74) = 0x42; + XREG(75) = 0x1E; + XREG(77) = 0x3C; + XREG(76) = 0x1C; + msgCtx->unk11F1A[0] = msgCtx->unk11F1A[1] = msgCtx->unk11F1A[2] = 0; + Interface_ChangeAlpha(1); + } +} + +void func_80151BB4(GlobalContext* globalCtx, u8 arg1) { + MessageContext* msgCtx = &globalCtx->msgCtx; + u8 temp = arg1; + + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { + if ((gSaveContext.save.weekEventReg[D_801C6B28[arg1] >> 8] & (u8)D_801C6B28[arg1]) == 0) { + msgCtx->unk120B2[msgCtx->unk120B1] = temp; + msgCtx->unk120B1++; + } + } else if (arg1 >= 20) { + if ((gSaveContext.save.weekEventReg[D_801C6B28[arg1] >> 8] & (u8)D_801C6B28[arg1]) == 0) { + msgCtx->unk120B2[msgCtx->unk120B1] = temp; + msgCtx->unk120B1++; + } + } +} + +u32 func_80151C9C(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + + while (true) { + if (msgCtx->unk120B1 == 0) { + return false; + } + msgCtx->unk120B1--; + + if ((gSaveContext.save.weekEventReg[D_801C6B28[msgCtx->unk120B2[msgCtx->unk120B1]] >> 8] & + (u8)D_801C6B28[msgCtx->unk120B2[msgCtx->unk120B1]]) == 0) { + gSaveContext.save.weekEventReg[D_801C6B28[msgCtx->unk120B2[msgCtx->unk120B1]] >> 8] = + ((void)0, gSaveContext.save.weekEventReg[D_801C6B28[msgCtx->unk120B2[msgCtx->unk120B1]] >> 8]) | + (u8)D_801C6B28[msgCtx->unk120B2[msgCtx->unk120B1]]; + + if ((D_801C6AB8[msgCtx->unk120B2[msgCtx->unk120B1]] != 0) && CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { + func_80151938(globalCtx, D_801C6AB8[msgCtx->unk120B2[msgCtx->unk120B1]]); + play_sound(NA_SE_SY_SCHEDULE_WRITE); + return true; + } + } + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80151DA4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152434.s") +void func_80152434(GlobalContext* globalCtx, u16 arg2) { + globalCtx->msgCtx.unk12046 = 0; + func_80151DA4(globalCtx, arg2); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152464.s") +void func_80152464(GlobalContext* globalCtx, u16 arg1) { + globalCtx->msgCtx.unk12046 = 1; + func_80151DA4(globalCtx, arg1); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152498.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/Message_GetState.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8015268C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152C64.s") +void func_80152C64(View* view) { + SET_FULLSCREEN_VIEWPORT(view); + func_8013FBC8(view); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152CAC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152EC0.s") +// Spawn song effect? +void func_80152EC0(GlobalContext* globalCtx) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Player* player = GET_PLAYER(globalCtx); + + if (1) {} + if ((msgCtx->songPlayed < 0x17) && (msgCtx->songPlayed != 0xE) && + ((msgCtx->ocarinaAction < 0x43) || (msgCtx->ocarinaAction >= 0x47))) { + msgCtx->unk120B0 = 1; + if (msgCtx->songPlayed != 0x16) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, D_801D02D8[msgCtx->songPlayed], player->actor.world.pos.x, + player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, D_801D02F8[msgCtx->songPlayed]); + return; + } + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OCEFF_WIPE4, player->actor.world.pos.x, + player->actor.world.pos.y, player->actor.world.pos.z, 0, 0, 0, 0); + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80152FB8.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80153750.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80153E7C.s") +void func_80153E7C(GlobalContext* globalCtx, void* arg1) { + if ((gSaveContext.options.language == 0) && (globalCtx->msgCtx.unk12090 == 0)) { + func_8014ADBC(globalCtx, arg1); + return; + } + if (globalCtx->msgCtx.unk12090 != 0) { + func_8015E7EC(globalCtx, arg1); + return; + } + func_8015966C(globalCtx, arg1, 0); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80153EF0.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801541D4.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_80156758.s") +void func_80156758(GlobalContext* globalCtx) { + Gfx* nextDisplayList; + Gfx* polyOpa; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + polyOpa = POLY_OPA_DISP; + nextDisplayList = Graph_GfxPlusOne(polyOpa); + gSPDisplayList(OVERLAY_DISP++, nextDisplayList); + + if ((globalCtx->msgCtx.currentTextId != 0x5E6) || !Play_InCsMode(globalCtx)) { + func_801541D4(globalCtx, &nextDisplayList); + } + + gSPEndDisplayList(nextDisplayList++); + Graph_BranchDlist(polyOpa, nextDisplayList); + POLY_OPA_DISP = nextDisplayList; + CLOSE_DISPS(gfxCtx); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_8015680C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/func_801586A4.s") +void func_801586A4(GlobalContext* globalCtx) { + globalCtx->msgCtx.messageEntryTableNes = D_801C6B98; + globalCtx->msgCtx.messageTableStaff = D_801CFB08; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message/Message_Init.s") +void Message_Init(GlobalContext* globalCtx) { + Font* font; + MessageContext* messageCtx = &globalCtx->msgCtx; + + func_801586A4(globalCtx); + globalCtx->msgCtx.ocarinaMode = 0; + messageCtx->msgMode = 0; + messageCtx->unk11F10 = 0; + messageCtx->currentTextId = 0; + messageCtx->unk12020 = 0; + messageCtx->choiceIndex = 0; + messageCtx->ocarinaAction = messageCtx->unk11FF2 = 0; + messageCtx->unk1201E = 0xFF; + View_Init(&messageCtx->view, globalCtx->state.gfxCtx); + messageCtx->unk11EF8 = THA_AllocEndAlign16(&globalCtx->state.heap, 0x13C00); + font = &globalCtx->msgCtx.font; + Font_LoadOrderedFont(&globalCtx->msgCtx.font); + font->unk_11D88 = 0; + messageCtx->unk12090 = messageCtx->unk12092 = 0; + messageCtx->unk12094 = 0; + messageCtx->unk1209C = 0; + messageCtx->unk120A0 = 0; + messageCtx->unk12068 = 0x34; + messageCtx->unk1206A = 0x24; + messageCtx->unk120B0 = 0; + messageCtx->unk120BE = 0; + messageCtx->unk120C0 = 0; + messageCtx->unk120C2 = 0; + messageCtx->unk120C4 = 0; + messageCtx->unk120C8 = 0; + messageCtx->unk120CA = 0; + messageCtx->unk120CC = 0; + messageCtx->unk120CE = 0; + messageCtx->unk120D0 = 0; + messageCtx->unk120D2 = 0; + messageCtx->unk120D4 = 0; + messageCtx->unk120D6 = 0; +} diff --git a/src/code/z_message_nes.c b/src/code/z_message_nes.c index 4767810fb..485f016ff 100644 --- a/src/code/z_message_nes.c +++ b/src/code/z_message_nes.c @@ -1,18 +1,283 @@ #include "global.h" +#include "message_data_static.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_801588D0.s") +#if 0 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80158988.s") +//fontWidth +extern f32 D_801D0470[159]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80158A24.s") +//rupeesTextLocalization +u8 D_801D06F0[4][8] = { { "rupee(s)" }, //EN + { "rubin(e)" }, //DE + { "rubis" }, //FR + { "rupia(s)" } //SPA + }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80158C04.s") +// rupeesTextLength +u8 D_801D0710[4] = {8,8,5,8}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80158D98.s") +//TextArea +char D_801D0714[11][16] = { + "Great Bay Coast", + "Zora Cape", + "Snowhead", + "Mountain Village", + "Clock Town", + "Milk Road", + "Woodfall", + "Southern Swamp", + "Ikana Canyon", + "Stone Tower", + "Entrance" + }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80158FB0.s") +//TextAreaLength +s16 D_801D07C4[11] = {15,9,8,16,10,9,8,14,12,11,8}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_8015926C.s") +#endif + +extern f32 D_801D0470[159]; +extern u8 D_801D06F0[4][8]; +extern u8 D_801D0710[4]; +extern u8 D_801D0714[11][16]; +extern s16 D_801D07C4[11]; + +void Message_FindMessageNES(GlobalContext* globalCtx, u16 textId) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Font* font = &msgCtx->font; + MessageTableEntry* msgEntry = msgCtx->messageEntryTableNes; + const char* segment = msgEntry->segment; + const char* foundSegment; + const char* nextSegment; + + while (msgEntry->textId != 0xFFFF) { + if (msgEntry->textId == textId) { + foundSegment = msgEntry->segment; + msgEntry++; + nextSegment = msgEntry->segment; + font->messageStart = foundSegment - segment; + font->messageEnd = nextSegment - foundSegment; + return; + } + msgEntry++; + } + + msgEntry = msgCtx->messageEntryTableNes; + foundSegment = msgEntry->segment; + msgEntry++; + nextSegment = msgEntry->segment; + font->messageStart = foundSegment - segment; + font->messageEnd = nextSegment - foundSegment; +} + +void Message_LoadCharNES(GlobalContext* globalCtx, u8 codePointIndex, s32* offset, f32* arg3, s16 decodedBufPos) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s32 temp1 = *offset; + f32 temp2 = *arg3; + + Font_LoadCharNES(globalCtx, codePointIndex, temp1); + msgCtx->decodedBuffer.schar[decodedBufPos] = codePointIndex; + temp1 += FONT_CHAR_TEX_SIZE; + temp2 += (16.0f * msgCtx->unk12098); + *offset = temp1; + *arg3 = temp2; +} + +void Message_LoadPluralRupeesNES(GlobalContext* globalCtx, s16* decodedBufPos, s32* offset, f32* arg3) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 p = *decodedBufPos; + s32 o = *offset; + f32 f = *arg3; + + msgCtx->decodedBuffer.schar[p] = 0x20; + p++; + Font_LoadCharNES(globalCtx, 'R', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'R'; + p++; + Font_LoadCharNES(globalCtx, 'u', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'u'; + p++; + Font_LoadCharNES(globalCtx, 'p', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'p'; + p++; + Font_LoadCharNES(globalCtx, 'e', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'e'; + p++; + Font_LoadCharNES(globalCtx, 'e', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'e'; + p++; + Font_LoadCharNES(globalCtx, 's', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 's'; + + f += 16.0f * msgCtx->unk12098 * 6.0f; + *decodedBufPos = p; + *offset = o; + *arg3 = f; +} + +void Message_LoadLocalizedRupeesNES(GlobalContext* globalCtx, s16* decodedBufPos, s32* offset, f32* arg3) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 p = *decodedBufPos; + s32 o = *offset; + f32 f = *arg3; + u8 j; + + msgCtx->decodedBuffer.schar[p] = ' '; + p++; + + for (j = 0; j < D_801D0710[gSaveContext.options.language - 1]; j++) { + Font_LoadCharNES(globalCtx, D_801D06F0[gSaveContext.options.language - 1][j], o); + msgCtx->decodedBuffer.schar[p] = D_801D06F0[gSaveContext.options.language - 1][j]; + o += FONT_CHAR_TEX_SIZE; + p++; + } + + p--; + f += 16.0f * msgCtx->unk12098 * (D_801D0710[gSaveContext.options.language - 1] + 1); + *decodedBufPos = p; + *offset = o; + *arg3 = f; +} + +void Message_LoadRupeesNES(GlobalContext* globalCtx, s16* decodedBufPos, s32* offset, f32* arg3, s16 singular) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 p = *decodedBufPos; + s32 o = *offset; + f32 f = *arg3; + + msgCtx->decodedBuffer.schar[p] = ' '; + p++; + Font_LoadCharNES(globalCtx, 'R', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'R'; + p++; + Font_LoadCharNES(globalCtx, 'u', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'u'; + p++; + Font_LoadCharNES(globalCtx, 'p', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'p'; + p++; + Font_LoadCharNES(globalCtx, 'e', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'e'; + p++; + Font_LoadCharNES(globalCtx, 'e', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 'e'; + + if (singular != 1) { + p++; + Font_LoadCharNES(globalCtx, 's', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = 's'; + f += 16.0f * msgCtx->unk12098 * 6.0f; + } else { + f += 16.0f * msgCtx->unk12098 * 5.0f; + } + + *decodedBufPos = p; + *offset = o; + *arg3 = f; +} + +void Message_LoadTimeNES(GlobalContext* globalCtx, u8 arg1, s32* offset, f32* arg3, s16* decodedBufPos) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 p = *decodedBufPos; + s32 o = *offset; + f32 f = *arg3; + u32 timeLeft; + s16 digits[4]; + f32 timeLeftInMinutes; + s16 i; + + if (arg1 == 0xCF) { + // Calculates the time left before the moon crashes. + // The day begins at CLOCK_TIME(6, 0) so it must be offset. + timeLeft = (4 - CURRENT_DAY) * DAY_LENGTH - (u16)(((void)0, gSaveContext.save.time) - CLOCK_TIME(6, 0)); + } else { + // Calculates the time left before a new day. + // The day begins at CLOCK_TIME(6, 0) so it must be offset. + timeLeft = DAY_LENGTH - (u16)(((void)0, gSaveContext.save.time) - CLOCK_TIME(6, 0)); + } + + timeLeftInMinutes = TIME_TO_MINUTES_F(timeLeft); + + digits[0] = 0; + digits[1] = (timeLeftInMinutes / 60.0f); + while (digits[1] >= 10) { + digits[0]++; + digits[1] -= 10; + } + + digits[2] = 0; + digits[3] = (s32)timeLeftInMinutes % 60; + while (digits[3] >= 10) { + digits[2]++; + digits[3] -= 10; + } + + for (i = 0; i < 4; i++) { + Font_LoadCharNES(globalCtx, digits[i] + '0', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = digits[i] + '0'; + p++; + if (i == 1) { + Font_LoadCharNES(globalCtx, ':', o); + o += FONT_CHAR_TEX_SIZE; + msgCtx->decodedBuffer.schar[p] = ':'; + p++; + } + } + + f += 5.0f * (16.0f * msgCtx->unk12098); + *decodedBufPos = p - 1; + *offset = o; + *arg3 = f; +} + +void Message_LoadAreaTextNES(GlobalContext* globalCtx, s32* offset, f32* arg2, s16* decodedBufPos) { + MessageContext* msgCtx = &globalCtx->msgCtx; + s16 p = *decodedBufPos; + s32 o = *offset; + f32 f = *arg2; + s16 i; + u8 currentChar; + s16 currentArea; + s16 stringLimit; + + if ((func_8010A0A4(globalCtx) != 0) || (globalCtx->sceneNum == SCENE_SECOM)) { + currentArea = 10; + } else { + currentArea = globalCtx->pauseCtx.unk_238[4]; + } + stringLimit = D_801D07C4[currentArea]; + + for (i = 0; i < stringLimit; i++) { + msgCtx->decodedBuffer.schar[p] = D_801D0714[currentArea][i]; + currentChar = msgCtx->decodedBuffer.schar[p]; + if (currentChar != ' ') { + Font_LoadCharNES(globalCtx, D_801D0714[currentArea][i], o); + o += FONT_CHAR_TEX_SIZE; + } + currentChar = msgCtx->decodedBuffer.schar[p]; + p++; + f += (D_801D0470[currentChar - ' '] * msgCtx->unk12098); + } + + p--; + f += (stringLimit - 1) * (16.0f * msgCtx->unk12098); + *decodedBufPos = p; + *offset = o; + *arg2 = f; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message_nes/func_80159438.s") diff --git a/src/code/z_message_staff.c b/src/code/z_message_staff.c index 2dd698690..6620f88d5 100644 --- a/src/code/z_message_staff.c +++ b/src/code/z_message_staff.c @@ -1,6 +1,27 @@ #include "global.h" +#include "message_data_static.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_message_staff/func_8015E750.s") +void Message_FindCreditsMessage(GlobalContext* globalCtx, u16 textId) { + MessageContext* msgCtx = &globalCtx->msgCtx; + Font* font = &msgCtx->font; + MessageTableEntry* msgEntry = msgCtx->messageTableStaff; + const char* segment = msgEntry->segment; + const char* foundSegment; + const char* nextSegment; + + while (msgEntry->textId != 0xFFFF) { + if (msgEntry->textId == textId) { + foundSegment = msgEntry->segment; + font->charBuf[font->unk_11D88][0] = msgEntry->typePos; + msgEntry++; + nextSegment = msgEntry->segment; + font->messageStart = foundSegment - segment; + font->messageEnd = nextSegment - foundSegment; + return; + } + msgEntry++; + } +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_message_staff/func_8015E7EC.s") diff --git a/src/code/z_olib.c b/src/code/z_olib.c index c44fac276..6f1cdbc55 100644 --- a/src/code/z_olib.c +++ b/src/code/z_olib.c @@ -66,7 +66,7 @@ Vec3f* OLib_Vec3fDistNormalize(Vec3f* dest, Vec3f* a, Vec3f* b) { v1.y = b->y - a->y; v1.z = b->z - a->z; - dist = OLib_ClampMinDist(sqrtf(SQ(v1.x) + SQ(v1.y) + SQ(v1.z)), 0.01f); + dist = OLib_ClampMinDist(sqrtf(SQXYZ(v1)), 0.01f); v2.x = v1.x / dist; v2.y = v1.y / dist; diff --git a/src/code/z_parameter.c b/src/code/z_parameter.c index ec227aaa9..44b1de152 100644 --- a/src/code/z_parameter.c +++ b/src/code/z_parameter.c @@ -72,9 +72,9 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80114CA0.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80114E90.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_HasEmptyBottle.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80114F2C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/Interface_HasItemInBottle.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_parameter/func_80114FD0.s") diff --git a/src/code/z_path.c b/src/code/z_path.c index 15d940923..0462a40cd 100644 --- a/src/code/z_path.c +++ b/src/code/z_path.c @@ -1,7 +1,45 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_path/func_801224E0.s") +Path* Path_GetByIndex(GlobalContext* globalCtx, s16 index, s16 max) { + Path* path; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_path/func_80122524.s") + if (index != max) { + path = &globalCtx->setupPathList[index]; + } else { + path = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_path/func_801225CC.s") + return path; +} + +f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw) { + f32 dx; + f32 dz; + Vec3s* pointPos; + + if (path == NULL) { + return -1.0; + } + + pointPos = Lib_SegmentedToVirtual(path->points); + pointPos = &pointPos[waypoint]; + + dx = pointPos->x - actor->world.pos.x; + dz = pointPos->z - actor->world.pos.z; + + *yaw = Math_Atan2S(dx, dz); + + return SQ(dx) + SQ(dz); +} + +void Path_CopyLastPoint(Path* path, Vec3f* dest) { + Vec3s* pointPos; + + if (path != NULL) { + pointPos = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[path->count - 1]; + + dest->x = pointPos->x; + dest->y = pointPos->y; + dest->z = pointPos->z; + } +} 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..aa360934e 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -52,13 +52,15 @@ #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") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Update.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801690CC.s") +s32 Play_InCsMode(GlobalContext* globalCtx) { + return (globalCtx->csCtx.state != 0) || Player_InCsMode(&globalCtx->state); +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169100.s") @@ -74,70 +76,290 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169474.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801694DC.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CreateSubCamera.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetActiveCameraIndex.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetActiveCamId.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169590.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraChangeStatus.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169600.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_ClearCamera.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169668.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_ClearAllSubCameras.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCamera.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetAtEye.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016981C.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetAtEyeUp.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169940.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetFov.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169988.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraSetRoll.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_801699D4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CopyCamera.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169A50.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169AC0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraChangeSetting.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169AFC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169BC4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_CameraGetUID.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169BF8.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169C64.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCsCamDataSetting.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169C84.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_GetCsCamDataVec3s.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/convert_scene_number_among_shared_scenes.s") +/** + * Converts the number of a scene to its "original" equivalent, the default version of the area which the player first + * enters. + */ +s16 Play_GetOriginalSceneNumber(s16 sceneNum) { + // Inverted Stone Tower Temple -> Stone Tower Temple + if (sceneNum == SCENE_INISIE_R) { + return SCENE_INISIE_N; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169D40.s") + // Purified Southern Swamp -> Poisoned Sothern Swamp + if (sceneNum == SCENE_20SICHITAI2) { + return SCENE_20SICHITAI; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169DCC.s") + // Spring Mountain Village -> Winter Mountain Village + if (sceneNum == SCENE_10YUKIYAMANOMURA2) { + return SCENE_10YUKIYAMANOMURA; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169E6C.s") + // Spring Goron Village -> Winter Goron Village + if (sceneNum == SCENE_11GORONNOSATO2) { + return SCENE_11GORONNOSATO; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169ECC.s") + // Spring Path to Goron Village -> Winter Path to Goron Village + if (sceneNum == SCENE_17SETUGEN2) { + return SCENE_17SETUGEN; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169EFC.s") + // Inverted Stone Tower -> Stone Tower + if (sceneNum == SCENE_F41) { + return SCENE_F40; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169F78.s") + return sceneNum; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FDC.s") +/** + * Copies the flags set in ActorContext over to the current scene's CycleSceneFlags, usually using the original scene + * number. Exception for Inverted Stone Tower Temple, which uses its own. + */ +void Play_SaveCycleSceneFlags(GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + CycleSceneFlags* cycleSceneFlags; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80169FFC.s") + cycleSceneFlags = &gSaveContext.cycleSceneFlags[Play_GetOriginalSceneNumber(globalCtx->sceneNum)]; + cycleSceneFlags->chest = globalCtx->actorCtx.flags.chest; + cycleSceneFlags->switch0 = globalCtx->actorCtx.flags.switches[0]; + cycleSceneFlags->switch1 = globalCtx->actorCtx.flags.switches[1]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/FrameAdvance_IsEnabled.s") + if (globalCtx->sceneNum == SCENE_INISIE_R) { // Inverted Stone Tower Temple + cycleSceneFlags = &gSaveContext.cycleSceneFlags[globalCtx->sceneNum]; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A02C.s") + cycleSceneFlags->collectible = globalCtx->actorCtx.flags.collectible[0]; + cycleSceneFlags->clearedRoom = globalCtx->actorCtx.flags.clearedRoom; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A0AC.s") +void Play_SetRespawnData(GameState* gameState, s32 respawnMode, u16 entranceIndex, s32 roomIndex, s32 playerParams, + Vec3f* pos, s16 yaw) { + GlobalContext* globalCtx = (GlobalContext*)gameState; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A168.s") + gSaveContext.respawn[respawnMode].entranceIndex = Entrance_CreateIndex(entranceIndex >> 9, 0, entranceIndex & 0xF); + gSaveContext.respawn[respawnMode].roomIndex = roomIndex; + gSaveContext.respawn[respawnMode].pos = *pos; + gSaveContext.respawn[respawnMode].yaw = yaw; + gSaveContext.respawn[respawnMode].playerParams = playerParams; + gSaveContext.respawn[respawnMode].tempSwitchFlags = globalCtx->actorCtx.flags.switches[2]; + gSaveContext.respawn[respawnMode].unk_18 = globalCtx->actorCtx.flags.collectible[1]; + gSaveContext.respawn[respawnMode].tempCollectFlags = globalCtx->actorCtx.flags.collectible[2]; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A178.s") +void Play_SetupRespawnPoint(GameState* gameState, s32 respawnMode, s32 playerParams) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_8016A268.s") + if (globalCtx->sceneNum != SCENE_KAKUSIANA) { // Grottos + Play_SetRespawnData(&globalCtx->state, respawnMode, (u16)((void)0, gSaveContext.save.entranceIndex), + globalCtx->roomCtx.currRoom.num, playerParams, &player->actor.world.pos, + player->actor.shape.rot.y); + } +} + +// Override respawn data in Sakon's Hideout +void func_80169ECC(GlobalContext* globalCtx) { + if (globalCtx->sceneNum == SCENE_SECOM) { + globalCtx->nextEntranceIndex = 0x2060; + gSaveContext.respawnFlag = -7; + } +} + +// Gameplay_TriggerVoidOut ? +// Used by Player, Ikana_Rotaryroom, Bji01, Kakasi, LiftNuts, Test4, Warptag, WarpUzu, Roomtimer +void func_80169EFC(GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + + gSaveContext.respawn[RESTART_MODE_DOWN].tempSwitchFlags = globalCtx->actorCtx.flags.switches[2]; + gSaveContext.respawn[RESTART_MODE_DOWN].unk_18 = globalCtx->actorCtx.flags.collectible[1]; + gSaveContext.respawn[RESTART_MODE_DOWN].tempCollectFlags = globalCtx->actorCtx.flags.collectible[2]; + globalCtx->nextEntranceIndex = gSaveContext.respawn[RESTART_MODE_DOWN].entranceIndex; + gSaveContext.respawnFlag = 1; + func_80169ECC(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; +} + +// Gameplay_LoadToLastEntrance ? +// Used by game_over and Test7 +void func_80169F78(GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + + globalCtx->nextEntranceIndex = gSaveContext.respawn[RESTART_MODE_TOP].entranceIndex; + gSaveContext.respawnFlag = -1; + func_80169ECC(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; +} + +// Gameplay_TriggerRespawn ? +// Used for void by Wallmaster, Deku Shrine doors. Also used by Player, Kaleido, DoorWarp1 +void func_80169FDC(GameState* gameState) { + func_80169F78(gameState); +} + +// Used by Kankyo to determine how to change the lighting, e.g. for game over. +s32 func_80169FFC(GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + + return globalCtx->roomCtx.currRoom.mesh->type0.type != 1; +} + +s32 FrameAdvance_IsEnabled(GameState* gameState) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + + return globalCtx->frameAdvCtx.enabled != 0; +} + +// Unused, unchanged from OoT, which uses it only in one Camera function. +/** + * @brief Tests if \p actor is a door and the sides are different rooms. + * + * @param[in] gameState GameState, promoted to globalCtx inside. + * @param[in] actor Actor to test. + * @param[out] yaw Facing angle of the actor, or reverse if in the back room. + * @return true if \p actor is a door and the sides are in different rooms, false otherwise + */ +s32 func_8016A02C(GameState* gameState, Actor* actor, s16* yaw) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + TransitionActorEntry* transitionActor; + s8 frontRoom; + + if (actor->category != ACTORCAT_DOOR) { + return false; + } + + transitionActor = &globalCtx->doorCtx.transitionActorList[(u16)actor->params >> 10]; + frontRoom = transitionActor->sides[0].room; + if (frontRoom == transitionActor->sides[1].room) { + return false; + } + + if (frontRoom == actor->room) { + *yaw = actor->shape.rot.y; + } else { + *yaw = actor->shape.rot.y + 0x8000; + } + + return true; +} + +// Unused +/** + * @brief Tests if \p pos is underwater. + * + * @param[in] globalCtx GlobalContext + * @param[in] pos position to test + * @return true if inside a waterbox and not above a void. + */ +s32 Play_IsUnderwater(GlobalContext* globalCtx, Vec3f* pos) { + WaterBox* waterBox; + CollisionPoly* poly; + Vec3f waterSurfacePos; + s32 bgId; + + waterSurfacePos = *pos; + + if ((WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, waterSurfacePos.x, waterSurfacePos.z, &waterSurfacePos.y, + &waterBox) == true) && + (pos->y < waterSurfacePos.y) && + (BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &poly, &bgId, &waterSurfacePos) != BGCHECK_Y_MIN)) { + return true; + } else { + return false; + } +} + +// z_demo and EnTest4 +// This data appears to be a boolean. It is only set by Play_Init. +s32 func_8016A168(void) { + return D_801D0D50; +} + +// A mapping from playerActorCsIds to sGlobalCamDataSettings indices. +extern s16 D_801D0D64[]; +// s16 D_801D0D64[] = { -3, -2, -4, -5, -7, -11, -8, -9, -6, -16 }; + +// Used by Player +/** + * Extract the common actor cutscene ids used by Player from the scene and set the actor cutscene ids in + * globalCtx->playerActorCsIds. If a playerActorCsId is not present in the scene, then that particular id is set + * to -1. Otherwise, if there is an ActorCutscene where csCamSceneDataId matches the appropriate element of D_801D0D64, + * set the corresponding playerActorCsId (and possibly change its priority for the zeroth one) + */ +void Play_AssignPlayerActorCsIdsFromScene(GameState* gameState, s32 startActorCsId) { + GlobalContext* globalCtx = (GlobalContext*)gameState; + s32 i; + s16* curPlayerActorCsId = globalCtx->playerActorCsIds; + s16* phi_s1 = D_801D0D64; + + for (i = 0; i < ARRAY_COUNT(globalCtx->playerActorCsIds); i++, curPlayerActorCsId++, phi_s1++) { + ActorCutscene* actorCutscene; + s32 curActorCsId; + + *curPlayerActorCsId = -1; + + for (curActorCsId = startActorCsId; curActorCsId != -1; curActorCsId = actorCutscene->additionalCutscene) { + actorCutscene = ActorCutscene_GetCutscene(curActorCsId); + + if (actorCutscene->csCamSceneDataId == *phi_s1) { + if ((actorCutscene->csCamSceneDataId == -3) && + (actorCutscene->priority == 700)) { // override ocarina cs priority + actorCutscene->priority = 550; + } + *curPlayerActorCsId = curActorCsId; + break; + } + } + } +} + +// These regs are used by Gameplay_Draw, and several actors, purpose as yet unclear. +void func_8016A268(GameState* gameState, s16 arg1, u8 arg2, u8 arg3, u8 arg4, u8 arg5) { + MREG(64) = arg1; + MREG(65) = arg2; + MREG(66) = arg3; + MREG(67) = arg4; + MREG(68) = arg5; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Init.s") diff --git a/src/code/z_player_call.c b/src/code/z_player_call.c index 69e2f4dae..7ed1ce5ce 100644 --- a/src/code/z_player_call.c +++ b/src/code/z_player_call.c @@ -1,11 +1,60 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_call/func_80160A90.s") +#define FLAGS \ + (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_200000 | ACTOR_FLAG_2000000 | \ + ACTOR_FLAG_4000000 | ACTOR_FLAG_80000000) -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_call/func_80160AF8.s") +ActorFunc sPlayerCallInitFunc; +ActorFunc sPlayerCallDestroyFunc; +ActorFunc sPlayerCallUpdateFunc; +ActorFunc sPlayerCallDrawFunc; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_call/func_80160B40.s") +void PlayerCall_Init(Actor* thisx, GlobalContext* globalCtx); +void PlayerCall_Destroy(Actor* thisx, GlobalContext* globalCtx); +void PlayerCall_Update(Actor* thisx, GlobalContext* globalCtx); +void PlayerCall_Draw(Actor* thisx, GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_call/func_80160B80.s") +const ActorInit Player_InitVars = { + ACTOR_PLAYER, + ACTORCAT_PLAYER, + FLAGS, + GAMEPLAY_KEEP, + sizeof(Player), + (ActorFunc)PlayerCall_Init, + (ActorFunc)PlayerCall_Destroy, + (ActorFunc)PlayerCall_Update, + (ActorFunc)PlayerCall_Draw, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_call/func_80160BC0.s") +void Player_Init(Actor* thisx, GlobalContext* globalCtx); +void Player_Destroy(Actor* thisx, GlobalContext* globalCtx); +void Player_Update(Actor* thisx, GlobalContext* globalCtx); +void Player_Draw(Actor* thisx, GlobalContext* globalCtx); + +void PlayerCall_InitFuncPtrs(void) { + sPlayerCallInitFunc = KaleidoManager_GetRamAddr(Player_Init); + sPlayerCallDestroyFunc = KaleidoManager_GetRamAddr(Player_Destroy); + sPlayerCallUpdateFunc = KaleidoManager_GetRamAddr(Player_Update); + sPlayerCallDrawFunc = KaleidoManager_GetRamAddr(Player_Draw); +} + +void PlayerCall_Init(Actor* thisx, GlobalContext* globalCtx) { + KaleidoScopeCall_LoadPlayer(); + PlayerCall_InitFuncPtrs(); + sPlayerCallInitFunc(thisx, globalCtx); +} + +void PlayerCall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + KaleidoScopeCall_LoadPlayer(); + sPlayerCallDestroyFunc(thisx, globalCtx); +} + +void PlayerCall_Update(Actor* thisx, GlobalContext* globalCtx) { + KaleidoScopeCall_LoadPlayer(); + sPlayerCallUpdateFunc(thisx, globalCtx); +} + +void PlayerCall_Draw(Actor* thisx, GlobalContext* globalCtx) { + KaleidoScopeCall_LoadPlayer(); + sPlayerCallDrawFunc(thisx, globalCtx); +} diff --git a/src/code/z_player_lib.c b/src/code/z_player_lib.c index c03c0dfc7..cb3d14e8b 100644 --- a/src/code/z_player_lib.c +++ b/src/code/z_player_lib.c @@ -38,7 +38,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80123358.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_801233E4.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/Player_InCsMode.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80123420.s") @@ -68,7 +68,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80123C58.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80123C90.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/Player_SetEquipmentData.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80123D50.s") @@ -114,7 +114,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_8012422C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80124258.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/Player_GetExplosiveHeld.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_player_lib/func_80124278.s") diff --git a/src/code/z_prenmi.c b/src/code/z_prenmi.c index df55d2488..0e9c435c6 100644 --- a/src/code/z_prenmi.c +++ b/src/code/z_prenmi.c @@ -19,7 +19,7 @@ void PreNMI_Update(PreNMIContext* prenmiCtx) { void PreNMI_Draw(PreNMIContext* prenmiCtx) { GraphicsContext* gfxCtx = prenmiCtx->state.gfxCtx; - func_8012CF0C(gfxCtx, 1, 1, 0, 0, 0); + func_8012CF0C(gfxCtx, true, true, 0, 0, 0); OPEN_DISPS(gfxCtx); @@ -35,7 +35,7 @@ void PreNMI_Main(PreNMIContext* prenmiCtx) { PreNMI_Update(prenmiCtx); PreNMI_Draw(prenmiCtx); - prenmiCtx->state.unkA3 = 1; + prenmiCtx->state.unk_A3 = 1; } void PreNMI_Destroy(PreNMIContext* prenmiCtx) { diff --git a/src/code/z_quake.c b/src/code/z_quake.c index aeb8370ab..d57dc8e54 100644 --- a/src/code/z_quake.c +++ b/src/code/z_quake.c @@ -1,8 +1,7 @@ -#include "prevent_bss_reordering.h" #include "global.h" QuakeRequest sQuakeRequest[4]; -Quake2Context sQuake2Context; +DistortionContext sDistortionContext; static s16 sIsQuakeInitialized = true; static s16 sQuakeRequestCount = 0; @@ -138,7 +137,7 @@ QuakeRequest* Quake_AddImpl(Camera* camera, u32 callbackIdx) { __osMemset(req, 0, sizeof(QuakeRequest)); req->camera = camera; - req->cameraPtrsIdx = camera->thisIdx; + req->camId = camera->camId; req->callbackIdx = callbackIdx; req->isShakePerpendicular = true; req->randIdx = ((s16)(Rand_ZeroOne() * (f32)0x10000) & ~3) + idx; @@ -327,10 +326,10 @@ s16 Quake_Calc(Camera* camera, QuakeCamCalc* camData) { for (idx = 0; idx < ARRAY_COUNT(sQuakeRequest); idx++) { req = &sQuakeRequest[idx]; if (req->callbackIdx != 0) { - if (globalCtx->cameraPtrs[req->cameraPtrsIdx] == NULL) { + if (globalCtx->cameraPtrs[req->camId] == NULL) { Quake_Remove(req); } else { - eq = (camera->thisIdx != req->camera->thisIdx); + eq = (camera->camId != req->camera->camId); absSpeedDiv = ABS(req->speed) / (f32)0x8000; if (sQuakeCallbacks[req->callbackIdx](req, &shake) == 0) { Quake_Remove(req); @@ -383,57 +382,62 @@ s16 Quake_Calc(Camera* camera, QuakeCamCalc* camData) { return ret; } -void Quake2_Init(GlobalContext* globalCtx) { - sQuake2Context.globalCtx = globalCtx; - View_ClearQuake(&globalCtx->view); - sQuake2Context.type = 0; - sQuake2Context.countdown = 0; - sQuake2Context.state = QUAKE2_INACTIVE; +void Distortion_Init(GlobalContext* globalCtx) { + sDistortionContext.globalCtx = globalCtx; + View_ClearDistortion(&globalCtx->view); + sDistortionContext.type = 0; + sDistortionContext.countdown = 0; + sDistortionContext.state = DISTORTION_INACTIVE; } -void Quake2_SetCountdown(s16 countdown) { - sQuake2Context.countdown = countdown; - sQuake2Context.state = QUAKE2_SETUP; +void Distortion_SetCountdown(s16 countdown) { + sDistortionContext.countdown = countdown; + sDistortionContext.state = DISTORTION_SETUP; } -s16 Quake2_GetCountdown(void) { - return sQuake2Context.countdown; +s16 Distortion_GetCountdown(void) { + return sDistortionContext.countdown; } -s16 Quake2_GetType(void) { - return sQuake2Context.type; +s16 Distortion_GetType(void) { + return sDistortionContext.type; } -void Quake2_SetType(s32 type) { - if (sQuake2Context.type < type) { - sQuake2Context.type = type; +void Distortion_SetType(s32 type) { + if (sDistortionContext.type < type) { + sDistortionContext.type = type; } } -void Quake2_ClearType(s32 type) { - if (sQuake2Context.type == type) { - sQuake2Context.type = 0; +void Distortion_ClearType(s32 type) { + if (sDistortionContext.type == type) { + sDistortionContext.type = 0; } } -s32 Quake2_GetFloorQuake(Player* player) { - if (func_800C9D8C(&sQuake2Context.globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId) == 0) { - return func_800C9E18(&sQuake2Context.globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId); +/** + * Checks that the bg surface is an underwater conveyor type and if so, returns the conveyor speed + */ +s32 Distortion_GetUnderwaterCurrentSpeed(Player* player) { + if (SurfaceType_GetConveyorType(&sDistortionContext.globalCtx->colCtx, player->actor.floorPoly, + player->actor.floorBgId) == CONVEYOR_WATER) { + return SurfaceType_GetConveyorSpeed(&sDistortionContext.globalCtx->colCtx, player->actor.floorPoly, + player->actor.floorBgId); } return 0; } -void Quake2_Update(void) { - static s16 angle1 = 0x3F0; - static s16 angle2 = 0x156; +void Distortion_Update(void) { + static s16 depthPhase = 0x3F0; + static s16 screenPlanePhase = 0x156; static s16 countdownMax = 1; f32 xyScaleFactor; f32 zScaleFactor; f32 speedScaleFactor; f32 countdownRatio; f32 waterYScaleFactor; - f32 angle1Speed; - f32 angle2Speed; + f32 depthPhaseStep; + f32 screenPlanePhaseStep; f32 rotX; f32 rotY; f32 rotZ; @@ -442,181 +446,210 @@ void Quake2_Update(void) { f32 zScale; f32 speed; Player* player; - GlobalContext* globalCtx = sQuake2Context.globalCtx; + GlobalContext* globalCtx = sDistortionContext.globalCtx; PosRot playerPosRot; Camera* camera = GET_ACTIVE_CAM(globalCtx); f32 speedRatio = CLAMP_MAX(camera->speedRatio, 1.0f); - if (sQuake2Context.type != 0) { - if (sQuake2Context.type & 0x800) { - sQuake2Context.countdown = 2; - angle1 = 0x3F0; - angle2 = 0x156; - angle1Speed = 0.0f; - angle2Speed = 170.0f; + if (sDistortionContext.type != 0) { + if (sDistortionContext.type & 0x800) { + sDistortionContext.countdown = 2; + depthPhase = 0x3F0; + screenPlanePhase = 0x156; + + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 170.0f; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.0f; + xScale = -0.01f; yScale = 0.01f; zScale = 0.0f; + speed = 0.6f; - xyScaleFactor = zScaleFactor = sQuake2Context.countdown / 60.0f; + xyScaleFactor = zScaleFactor = sDistortionContext.countdown / 60.0f; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x400) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x3F0; - angle2 = 0x156; + } else if (sDistortionContext.type & 0x400) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x3F0; + screenPlanePhase = 0x156; } - angle1Speed = 0.0f; - angle2Speed = 50.0f / countdownMax; + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 50.0f / countdownMax; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.0f; + xScale = 0.01f; yScale = 100.0f; zScale = 0.0f; + speed = 0.4f; - xyScaleFactor = zScaleFactor = ((f32)countdownMax - sQuake2Context.countdown) / (f32)countdownMax; + xyScaleFactor = zScaleFactor = ((f32)countdownMax - sDistortionContext.countdown) / (f32)countdownMax; speedScaleFactor = 0.5f; - } else if (sQuake2Context.type & 0x200) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x1FC; - angle2 = 0x156; + } else if (sDistortionContext.type & 0x200) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x1FC; + screenPlanePhase = 0x156; } - angle1Speed = -5.0f; - angle2Speed = 5.0f; + depthPhaseStep = -5.0f; + screenPlanePhaseStep = 5.0f; + rotX = 0.0f; rotY = 0.0f; rotZ = 2.0f; + xScale = 0.3f; yScale = 0.3f; zScale = 0.0f; + speed = 0.1f; - xyScaleFactor = zScaleFactor = ((f32)countdownMax - sQuake2Context.countdown) / (f32)countdownMax; + xyScaleFactor = zScaleFactor = ((f32)countdownMax - sDistortionContext.countdown) / (f32)countdownMax; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x100) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x2710; - angle2 = 0x3E8; + } else if (sDistortionContext.type & 0x100) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x2710; + screenPlanePhase = 0x3E8; } - angle1Speed = 0.0f; - angle2Speed = 150.0f; + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 150.0f; + rotX = 0; rotY = 0; rotZ = 0.2f; + xScale = 0.025f; yScale = 0.02f; zScale = 0.01f; + speed = 1.5f; - if (sQuake2Context.countdown < 5) { - xyScaleFactor = zScaleFactor = ((f32)countdownMax - sQuake2Context.countdown) / (f32)countdownMax; + if (sDistortionContext.countdown < 5) { + xyScaleFactor = zScaleFactor = ((f32)countdownMax - sDistortionContext.countdown) / (f32)countdownMax; } else { xyScaleFactor = zScaleFactor = 0.0f; } speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x80) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x4B0; - angle2 = 0x7D0; + } else if (sDistortionContext.type & 0x80) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x4B0; + screenPlanePhase = 0x7D0; } - angle1Speed = 0.0f; - angle2Speed = 150.0f; + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 150.0f; + rotX = 0; rotY = 0; rotZ = 0; + xScale = 0.03f; yScale = 0.02f; zScale = 0.01f; + speed = 1.5f; - xyScaleFactor = zScaleFactor = sQuake2Context.countdown / (f32)countdownMax; + xyScaleFactor = zScaleFactor = sDistortionContext.countdown / (f32)countdownMax; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x40) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x9C4; - angle2 = 0xBB8; + } else if (sDistortionContext.type & 0x40) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x9C4; + screenPlanePhase = 0xBB8; } - angle1Speed = 0.0f; - angle2Speed = 150.0f; + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 150.0f; + rotX = 0; rotY = 0; rotZ = 0; + xScale = 0.03f; yScale = 0.03f; zScale = 0.01f; + speed = 1.3f; - if (sQuake2Context.countdown < 4) { - xyScaleFactor = zScaleFactor = sQuake2Context.countdown / (f32)countdownMax; + if (sDistortionContext.countdown < 4) { + xyScaleFactor = zScaleFactor = sDistortionContext.countdown / (f32)countdownMax; } else { xyScaleFactor = zScaleFactor = 0.0f; } speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x20) { - sQuake2Context.countdown = 2; - if (sQuake2Context.state == QUAKE2_SETUP) { - angle1 = 0x9C4; - angle2 = 0xBB8; + } else if (sDistortionContext.type & 0x20) { + sDistortionContext.countdown = 2; + if (sDistortionContext.state == DISTORTION_SETUP) { + depthPhase = 0x9C4; + screenPlanePhase = 0xBB8; } - angle1 += 0xB1; - angle2 -= 0x2B; - angle1Speed = -107.0f; - angle2Speed = 158.0f; + depthPhase += 0xB1; + screenPlanePhase -= 0x2B; + + depthPhaseStep = -107.0f; + screenPlanePhaseStep = 158.0f; + rotX = 0.2f; rotY = 1.7f; rotZ = -2.9f; + xScale = -0.6f; yScale = -0.7f; zScale = 0.6f; + speed = 0.2f; zScaleFactor = 1.0f; xyScaleFactor = 1.0f; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 0x10) { - if (sQuake2Context.state == QUAKE2_SETUP) { - countdownMax = sQuake2Context.countdown; - angle1 = 0x760; - angle2 = 0x1BC; + } else if (sDistortionContext.type & 0x10) { + if (sDistortionContext.state == DISTORTION_SETUP) { + countdownMax = sDistortionContext.countdown; + depthPhase = 0x760; + screenPlanePhase = 0x1BC; } - angle1Speed = 248.0f; - angle2Speed = -90.0f; + depthPhaseStep = 248.0f; + screenPlanePhaseStep = -90.0f; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.0f; + xScale = -0.4f; yScale = 0.4f; zScale = 0.2f; + speed = 0.25f; - countdownRatio = sQuake2Context.countdown / (f32)countdownMax; + countdownRatio = sDistortionContext.countdown / (f32)countdownMax; zScaleFactor = xyScaleFactor = countdownRatio; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 8) { - angle1 = 0x3F0; - angle2 = 0x156; - sQuake2Context.countdown = 2; + } else if (sDistortionContext.type & 8) { + depthPhase = 0x3F0; + screenPlanePhase = 0x156; + + sDistortionContext.countdown = 2; player = GET_PLAYER(globalCtx); - if (&player->actor != NULL) { - func_800B8248(&playerPosRot, player); + if (player != NULL) { + Actor_GetWorldPosShapeRot(&playerPosRot, &player->actor); } - angle1Speed = 359.2f; - angle2Speed = -18.5f; + depthPhaseStep = 359.2f; + screenPlanePhaseStep = -18.5f; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.3f; - switch (Quake2_GetFloorQuake(player)) { + + switch (Distortion_GetUnderwaterCurrentSpeed(player)) { case 3: xScale = -0.06f; yScale = 0.1f; @@ -650,17 +683,20 @@ void Quake2_Update(void) { } zScaleFactor = -xyScaleFactor; speedScaleFactor = 1.0f; - } else if (sQuake2Context.type & 4) { - angle1 = 0x3F0; - angle2 = 0x156; - sQuake2Context.countdown = 2; + } else if (sDistortionContext.type & 4) { + depthPhase = 0x3F0; + screenPlanePhase = 0x156; + + sDistortionContext.countdown = 2; player = GET_PLAYER(globalCtx); - angle1Speed = 359.2f; - angle2Speed = -18.5f; + + depthPhaseStep = 359.2f; + screenPlanePhaseStep = -18.5f; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.0f; - switch (Quake2_GetFloorQuake(player)) { + switch (Distortion_GetUnderwaterCurrentSpeed(player)) { case 3: xScale = 0.12f; yScale = 0.12f; @@ -695,18 +731,23 @@ void Quake2_Update(void) { xyScaleFactor = speedScaleFactor = (waterYScaleFactor * 0.15f) + 0.35f + (speedRatio * 0.4f); zScaleFactor = 0.9f - xyScaleFactor; - } else if (sQuake2Context.type & 1) { - angle1 = 0x3F0; - angle2 = 0x156; - sQuake2Context.countdown = 2; - angle1Speed = 0.0f; - angle2Speed = 150.0f; + } else if (sDistortionContext.type & 1) { + // Gives a small mirage-like appearance + depthPhase = 0x3F0; + screenPlanePhase = 0x156; + + sDistortionContext.countdown = 2; + depthPhaseStep = 0.0f; + screenPlanePhaseStep = 150.0f; + rotX = 0.0f; rotY = 0.0f; rotZ = 0.0f; + xScale = -0.01f; yScale = 0.01f; zScale = 0.01f; + speed = 0.6f; speedScaleFactor = 1.0f; zScaleFactor = 1.0f; @@ -715,26 +756,32 @@ void Quake2_Update(void) { return; } - angle1 += DEGF_TO_BINANG(angle1Speed); - angle2 += DEGF_TO_BINANG(angle2Speed); - View_SetQuakeRotation(&sQuake2Context.globalCtx->view, Math_CosS(angle1) * (DEGF_TO_RADF(rotX) * xyScaleFactor), - Math_SinS(angle1) * (DEGF_TO_RADF(rotY) * xyScaleFactor), - Math_SinS(angle2) * (DEGF_TO_RADF(rotZ) * zScaleFactor)); - View_SetQuakeScale(&sQuake2Context.globalCtx->view, (Math_SinS(angle2) * (xScale * xyScaleFactor)) + 1.0f, - (Math_CosS(angle2) * (yScale * xyScaleFactor)) + 1.0f, - (Math_CosS(angle1) * (zScale * zScaleFactor)) + 1.0f); - View_SetQuakeSpeed(&sQuake2Context.globalCtx->view, speed * speedScaleFactor); - sQuake2Context.state = QUAKE2_ACTIVE; - } else if (sQuake2Context.state != QUAKE2_INACTIVE) { - View_ClearQuake(&globalCtx->view); - sQuake2Context.state = QUAKE2_INACTIVE; - sQuake2Context.countdown = 0; + depthPhase += DEGF_TO_BINANG(depthPhaseStep); + screenPlanePhase += DEGF_TO_BINANG(screenPlanePhaseStep); + + View_SetDistortionDirRot(&sDistortionContext.globalCtx->view, + Math_CosS(depthPhase) * (DEGF_TO_RADF(rotX) * xyScaleFactor), + Math_SinS(depthPhase) * (DEGF_TO_RADF(rotY) * xyScaleFactor), + Math_SinS(screenPlanePhase) * (DEGF_TO_RADF(rotZ) * zScaleFactor)); + View_SetDistortionScale(&sDistortionContext.globalCtx->view, + (Math_SinS(screenPlanePhase) * (xScale * xyScaleFactor)) + 1.0f, + (Math_CosS(screenPlanePhase) * (yScale * xyScaleFactor)) + 1.0f, + (Math_CosS(depthPhase) * (zScale * zScaleFactor)) + 1.0f); + View_SetDistortionSpeed(&sDistortionContext.globalCtx->view, speed * speedScaleFactor); + + sDistortionContext.state = DISTORTION_ACTIVE; + + } else if (sDistortionContext.state != DISTORTION_INACTIVE) { + View_ClearDistortion(&globalCtx->view); + + sDistortionContext.state = DISTORTION_INACTIVE; + sDistortionContext.countdown = 0; } - if (sQuake2Context.countdown != 0) { - sQuake2Context.countdown--; - if (sQuake2Context.countdown == 0) { - sQuake2Context.type = 0; + if (sDistortionContext.countdown != 0) { + sDistortionContext.countdown--; + if (sDistortionContext.countdown == 0) { + sDistortionContext.type = 0; } } } diff --git a/src/code/z_rcp.c b/src/code/z_rcp.c index 0498885a0..f4ffd43c1 100644 --- a/src/code/z_rcp.c +++ b/src/code/z_rcp.c @@ -762,7 +762,7 @@ Gfx sFillSetupDL[] = { G_TD_CLAMP | G_TP_PERSP | G_CYC_FILL | G_PM_NPRIMITIVE, G_AC_NONE | G_ZS_PIXEL | G_RM_NOOP | G_RM_NOOP2), gsSPLoadGeometryMode(G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH), - gsSPDisplayList(&D_0E0001C8), + gsSPDisplayList(D_0E000000.setScissor), gsDPSetBlendColor(0x00, 0x00, 0x00, 0x08), gsSPClipRatio(FRUSTRATIO_2), gsSPEndDisplayList(), @@ -1222,93 +1222,116 @@ Gfx* Gfx_PrimColor(GraphicsContext* gfxCtx, s32 lodfrac, s32 r, s32 g, s32 b, s3 return displayList; } -#ifdef NON_MATCHING -// regalloc, some reorderings -void func_8012CF0C(GraphicsContext* gfxCtx, s32 iParm2, s32 iParm3, u8 r, u8 g, u8 b) { +void func_8012CF0C(GraphicsContext* gfxCtx, s32 clearFb, s32 clearZb, u8 r, u8 g, u8 b) { + Gfx* masterGfx; + void* zbuffer; s32 i; - Gfx* gfx; - gSegments[0] = 0; - gSegments[14] = (u32)graphDlEntry; - gSegments[15] = (u32)gfxCtx->framebuffer; + gSegments[0x00] = 0; + gSegments[0x0F] = gfxCtx->curFrameBuffer; + gSegments[0x0E] = gGfxMasterDL; - gfx = graphDlEntry + 0x16; - gSPDisplayList(gfx + 0, &D_0E000140); - gSPDisplayList(gfx + 1, &sFillSetupDL); - gDPSetColorImage(gfx + 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, 0x0F000000); - if (gfxCtx->zbuffer != NULL) { - gDPSetDepthImage(gfx + 3, gfxCtx->zbuffer); + zbuffer = gfxCtx->zbuffer; + + // Set up Framebuffer and Z-Buffer + + masterGfx = gGfxMasterDL->setupBuffers; + + gSPDisplayList(&masterGfx[0], D_0E000000.syncSegments); + gSPDisplayList(&masterGfx[1], sFillSetupDL); + gDPSetColorImage(&masterGfx[2], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000); + if (zbuffer != NULL) { + gDPSetDepthImage(&masterGfx[3], zbuffer); } else { - gDPSetDepthImage(gfx + 3, 0x0F000000); + gDPSetDepthImage(&masterGfx[3], &D_0F000000); } - gSPEndDisplayList(gfx + 4); + gSPEndDisplayList(&masterGfx[4]); - gfx = graphDlEntry + 0x39; - gDPSetScissor(gfx + 0, G_SC_NON_INTERLACE, 0, 0, D_801FBBCC, D_801FBBCE); - gSPEndDisplayList(gfx + 1); + // Set Scissor - gfx = graphDlEntry + 0x9; - if (gfxCtx->zbuffer == NULL) { - gSPEndDisplayList(gfx + 0); + masterGfx = gGfxMasterDL->setScissor; + + gDPSetScissor(&masterGfx[0], G_SC_NON_INTERLACE, 0, 0, D_801FBBCC, D_801FBBCE); + gSPEndDisplayList(&masterGfx[1]); + + // Clear Z-Buffer + + masterGfx = gGfxMasterDL->clearZBuffer; + + if (zbuffer == NULL) { + gSPEndDisplayList(&masterGfx[0]); } else { - gDPSetColorImage(gfx + 0, G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, gfxCtx->zbuffer); - gDPPipeSync(gfx + 1); - gDPSetCycleType(gfx + 2, G_CYC_FILL); - gDPSetRenderMode(gfx + 3, G_RM_NOOP, G_RM_NOOP2); - gDPSetFillColor(gfx + 4, (GPACK_RGBA5551(0xFF, 0xFF, 0xF0, 0) << 16) | GPACK_RGBA5551(0xFF, 0xFF, 0xF0, 0)); - gSPDisplayList(gfx + 5, &D_0E0002C8); - gDPSetColorImage(gfx + 6, G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, gfxCtx->zbuffer); - gSPEndDisplayList(gfx + 7); + gDPSetColorImage(&masterGfx[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, zbuffer); + gDPPipeSync(&masterGfx[1]); + gDPSetCycleType(&masterGfx[2], G_CYC_FILL); + gDPSetRenderMode(&masterGfx[3], G_RM_NOOP, G_RM_NOOP2); + gDPSetFillColor(&masterGfx[4], (GPACK_RGBA5551(255, 255, 240, 0) << 16) | GPACK_RGBA5551(255, 255, 240, 0)); + gSPDisplayList(&masterGfx[5], D_0E000000.clearFillRect); + gDPSetColorImage(&masterGfx[6], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000); + gSPEndDisplayList(&masterGfx[7]); } - gfx = graphDlEntry + 0x11; - gDPSetColorImage(gfx + 0, G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, 0x0F000000); - gDPSetCycleType(gfx + 1, G_CYC_FILL); - gDPSetRenderMode(gfx + 2, G_RM_NOOP, G_RM_NOOP2); - gDPSetFillColor(gfx + 3, GPACK_RGBA5551(r, g, b, 0)); - gSPBranchList(gfx + 4, &D_0E0002C8); + // Clear Framebuffer - gfx = graphDlEntry + 0x59; - gDPFillRectangle(gfx + 0, 0, 0, D_801FBBCC - 1, D_801FBBCE - 1); - gDPPipeSync(gfx + 1); - gSPEndDisplayList(gfx + 2); + masterGfx = gGfxMasterDL->clearFrameBuffer; - gfx = graphDlEntry + 0x5C; - gDPFillRectangle(gfx + 0, 0, 0, D_801FBBCC, D_801FBBCE); - gDPPipeSync(gfx + 1); - gSPEndDisplayList(gfx + 2); + gDPSetColorImage(&masterGfx[0], G_IM_FMT_RGBA, G_IM_SIZ_16b, D_801FBBCC, &D_0F000000); + gDPSetCycleType(&masterGfx[1], G_CYC_FILL); + gDPSetRenderMode(&masterGfx[2], G_RM_NOOP, G_RM_NOOP2); + gDPSetFillColor(&masterGfx[3], (GPACK_RGBA5551(r, g, b, 1) << 16) | GPACK_RGBA5551(r, g, b, 1)); + gSPBranchList(&masterGfx[4], D_0E000000.clearFillRect); - gfx = graphDlEntry + 0x28; - for (i = 0; i < 0x10; i++) { - if (i == 0xE) { - gSPNoOp(gfx + i); + // Fillrect used by the above buffer clearing routines + + masterGfx = gGfxMasterDL->clearFillRect; + + gDPFillRectangle(&masterGfx[0], 0, 0, D_801FBBCC - 1, D_801FBBCE - 1); + gDPPipeSync(&masterGfx[1]); + gSPEndDisplayList(&masterGfx[2]); + + // General Fillrect? + + masterGfx = gGfxMasterDL->fillRect; + + gDPFillRectangle(&masterGfx[0], 0, 0, D_801FBBCC, D_801FBBCE); + gDPPipeSync(&masterGfx[1]); + gSPEndDisplayList(&masterGfx[2]); + + // Sync SP Segments with current CPU Segments + + masterGfx = gGfxMasterDL->syncSegments; + + for (i = 0; i < ARRAY_COUNT(gSegments); i++) { + if (i == 0x0E) { + gSPNoOp(&masterGfx[i]); } else { - gSPSegment(gfx + i, i, gSegments[i]); + gSPSegment(&masterGfx[i], i, gSegments[i]); } } - gSPEndDisplayList(gfx + i); + gSPEndDisplayList(&masterGfx[i]); - gSPDisplayList(gfxCtx->polyOpa.p++, graphDlEntry + 0x16); - gSPDisplayList(gfxCtx->polyXlu.p++, graphDlEntry + 0x16); - gSPDisplayList(gfxCtx->overlay.p++, graphDlEntry + 0x16); - gSPDisplayList(gfxCtx->unk1B8.p++, graphDlEntry + 0x16); + OPEN_DISPS(gfxCtx); - if (iParm3) { - gSPDisplayList(gfxCtx->polyOpa.p++, &D_0E000048); + gSPDisplayList(POLY_OPA_DISP++, gGfxMasterDL->setupBuffers); + gSPDisplayList(POLY_XLU_DISP++, gGfxMasterDL->setupBuffers); + gSPDisplayList(OVERLAY_DISP++, gGfxMasterDL->setupBuffers); + gSPDisplayList(DEBUG_DISP++, gGfxMasterDL->setupBuffers); + + if (clearZb) { + gSPDisplayList(gfxCtx->polyOpa.p++, D_0E000000.clearZBuffer); } - if (iParm2) { - gSPDisplayList(gfxCtx->polyOpa.p++, &D_0E000088); + if (clearFb) { + gSPDisplayList(gfxCtx->polyOpa.p++, D_0E000000.clearFrameBuffer); } + + CLOSE_DISPS(gfxCtx); } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_rcp/func_8012CF0C.s") -#endif void func_8012D374(GraphicsContext* gfxCtx, u8 r, u8 g, u8 b) { if ((R_PAUSE_MENU_MODE < 2) && (D_801F6D10 < 2)) { - func_8012CF0C(gfxCtx, 1, 1, r, g, b); + func_8012CF0C(gfxCtx, true, true, r, g, b); } else { - func_8012CF0C(gfxCtx, 0, 0, r, g, b); + func_8012CF0C(gfxCtx, false, false, r, g, b); } } diff --git a/src/code/z_room.c b/src/code/z_room.c index 5163f1f29..7579c6200 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -18,18 +18,18 @@ 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; - meshParams = (RoomMeshType0Params*)Lib_SegmentedToVirtual(mesh->paramsStart); + meshParams = Lib_SegmentedToVirtual(mesh->paramsStart); for (i = 0; i < mesh->count; i++) { if ((flags & 1) && (meshParams->opaqueDl != NULL)) { gSPDisplayList(gfxCtx->polyOpa.p++, meshParams->opaqueDl); @@ -75,12 +75,10 @@ void Room_Init(GlobalContext* globalCtx, RoomContext* roomCtx) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_room/Room_AllocateAndLoad.s") -#ifdef NON_MATCHING s32 Room_StartRoomTransition(GlobalContext* globalCtx, RoomContext* roomCtx, s32 index) { - size_t size; - - // XXX: this should use a branch-likely if (roomCtx->unk31 == 0) { + s32 size; + roomCtx->prevRoom = roomCtx->currRoom; roomCtx->currRoom.num = index; roomCtx->currRoom.segment = NULL; @@ -101,9 +99,6 @@ s32 Room_StartRoomTransition(GlobalContext* globalCtx, RoomContext* roomCtx, s32 return 0; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_room/Room_StartRoomTransition.s") -#endif s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx) { if (roomCtx->unk31 == 1) { @@ -111,7 +106,7 @@ s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx) { roomCtx->unk31 = 0; roomCtx->currRoom.segment = roomCtx->activeRoomVram; // TODO: Segment number enum - gSegments[3] = PHYSICAL_TO_VIRTUAL(roomCtx->activeRoomVram); + gSegments[0x03] = PHYSICAL_TO_VIRTUAL(roomCtx->activeRoomVram); Scene_ProcessHeader(globalCtx, (SceneCmd*)roomCtx->currRoom.segment); func_80123140(globalCtx, GET_PLAYER(globalCtx)); @@ -119,7 +114,7 @@ s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx) { if (((globalCtx->sceneNum != SCENE_IKANA) || (roomCtx->currRoom.num != 1)) && (globalCtx->sceneNum != SCENE_IKNINSIDE)) { - globalCtx->envCtx.unk_C3 = 0xff; + globalCtx->envCtx.lightSettingOverride = 0xff; globalCtx->envCtx.unk_E0 = 0; } func_800FEAB0(); @@ -137,7 +132,7 @@ s32 Room_HandleLoadCallbacks(GlobalContext* globalCtx, RoomContext* roomCtx) { void Room_Draw(GlobalContext* globalCtx, Room* room, u32 flags) { if (room->segment != NULL) { // TODO: Segment number enum - gSegments[3] = PHYSICAL_TO_VIRTUAL(room->segment); + gSegments[0x03] = PHYSICAL_TO_VIRTUAL(room->segment); roomDrawFuncs[room->mesh->type0.type](globalCtx, room, flags); } return; diff --git a/src/code/z_scene.c b/src/code/z_scene.c index b744af5d0..b9dbb35dd 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -13,8 +13,7 @@ s32 Object_Spawn(ObjectContext* objectCtx, s16 id) { } if (objectCtx->num < OBJECT_EXCHANGE_BANK_MAX - 1) { - objectCtx->status[objectCtx->num + 1].segment = - (void*)ALIGN16((u32)objectCtx->status[objectCtx->num].segment + size); + objectCtx->status[objectCtx->num + 1].segment = ALIGN16((u32)objectCtx->status[objectCtx->num].segment + size); } objectCtx->num++; @@ -53,7 +52,7 @@ void Object_InitBank(GameState* gameState, ObjectContext* objectCtx) { objectCtx->spaceEnd = (void*)((u32)objectCtx->spaceStart + spaceSize); objectCtx->mainKeepIndex = Object_Spawn(objectCtx, GAMEPLAY_KEEP); - gSegments[4] = PHYSICAL_TO_VIRTUAL(objectCtx->status[objectCtx->mainKeepIndex].segment); + gSegments[0x04] = PHYSICAL_TO_VIRTUAL(objectCtx->status[objectCtx->mainKeepIndex].segment); } void Object_UpdateBank(ObjectContext* objectCtx) { @@ -143,27 +142,24 @@ void* func_8012F73C(ObjectContext* objectCtx, s32 iParm2, s16 id) { // SceneTableEntry Header Command 0x00: Spawn List void Scene_HeaderCmdSpawnList(GlobalContext* globalCtx, SceneCmd* cmd) { - GlobalContext* globalCtx2 = globalCtx; s32 loadedCount; - void* nextObject; s16 playerObjectId; - u8 playerForm; + void* nextObject; globalCtx->linkActorEntry = (ActorEntry*)Lib_SegmentedToVirtual(cmd->spawnList.segment) + globalCtx->setupEntranceList[globalCtx->curSpawn].spawn; if ((globalCtx->linkActorEntry->params & 0x0F00) >> 8 == 0x0C || - (gSaveContext.respawnFlag == 0x02 && gSaveContext.respawn[1].playerParams == 0x0CFF)) { + (gSaveContext.respawnFlag == 0x02 && gSaveContext.respawn[RESTART_MODE_RETURN].playerParams == 0x0CFF)) { // Skull Kid Object Object_Spawn(&globalCtx->objectCtx, OBJECT_STK); return; } loadedCount = Object_Spawn(&globalCtx->objectCtx, OBJECT_LINK_CHILD); - nextObject = globalCtx2->objectCtx.status[globalCtx2->objectCtx.num].segment; + nextObject = globalCtx->objectCtx.status[globalCtx->objectCtx.num].segment; globalCtx->objectCtx.num = loadedCount; globalCtx->objectCtx.spawnedObjectCount = loadedCount; - playerForm = gSaveContext.playerForm; - playerObjectId = gLinkFormObjectIndexes[playerForm]; + playerObjectId = gLinkFormObjectIndexes[(void)0, gSaveContext.save.playerForm]; gActorOverlayTable[0].initInfo->objectId = playerObjectId; Object_Spawn(&globalCtx->objectCtx, playerObjectId); @@ -172,14 +168,14 @@ void Scene_HeaderCmdSpawnList(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x01: Actor List void Scene_HeaderCmdActorList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->numSetupActors = (u16)cmd->actorList.num; - globalCtx->setupActorList = (ActorEntry*)Lib_SegmentedToVirtual(cmd->actorList.segment); - globalCtx->actorCtx.unkC = (u16)0; + globalCtx->numSetupActors = cmd->actorList.num; + globalCtx->setupActorList = Lib_SegmentedToVirtual(cmd->actorList.segment); + globalCtx->actorCtx.unkC = 0; } // SceneTableEntry Header Command 0x02: List of cameras for actor cutscenes void Scene_HeaderCmdActorCutsceneCamList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->unk_18858 = (UNK_PTR)Lib_SegmentedToVirtual(cmd->csCameraList.segment); + globalCtx->csCamData = Lib_SegmentedToVirtual(cmd->csCameraList.segment); } // SceneTableEntry Header Command 0x03: Collision Header @@ -187,35 +183,35 @@ void Scene_HeaderCmdColHeader(GlobalContext* globalCtx, SceneCmd* cmd) { CollisionHeader* colHeaderTemp; CollisionHeader* colHeader; - colHeaderTemp = (CollisionHeader*)Lib_SegmentedToVirtual(cmd->colHeader.segment); + colHeaderTemp = Lib_SegmentedToVirtual(cmd->colHeader.segment); colHeader = colHeaderTemp; - colHeader->vtxList = (Vec3s*)Lib_SegmentedToVirtual(colHeaderTemp->vtxList); - colHeader->polyList = (CollisionPoly*)Lib_SegmentedToVirtual(colHeader->polyList); + colHeader->vtxList = Lib_SegmentedToVirtual(colHeaderTemp->vtxList); + colHeader->polyList = Lib_SegmentedToVirtual(colHeader->polyList); if (colHeader->surfaceTypeList != NULL) { - colHeader->surfaceTypeList = (SurfaceType*)Lib_SegmentedToVirtual(colHeader->surfaceTypeList); + colHeader->surfaceTypeList = Lib_SegmentedToVirtual(colHeader->surfaceTypeList); } if (colHeader->cameraDataList != NULL) { - colHeader->cameraDataList = (void*)Lib_SegmentedToVirtual(colHeader->cameraDataList); + colHeader->cameraDataList = Lib_SegmentedToVirtual(colHeader->cameraDataList); } if (colHeader->waterBoxes != NULL) { - colHeader->waterBoxes = (WaterBox*)Lib_SegmentedToVirtual(colHeader->waterBoxes); + colHeader->waterBoxes = Lib_SegmentedToVirtual(colHeader->waterBoxes); } - BgCheck_Init(&globalCtx->colCtx, globalCtx, colHeader); + BgCheck_Allocate(&globalCtx->colCtx, globalCtx, colHeader); } // SceneTableEntry Header Command 0x04: Room List void Scene_HeaderCmdRoomList(GlobalContext* globalCtx, SceneCmd* cmd) { globalCtx->numRooms = cmd->roomList.num; - globalCtx->roomList = (RomFile*)Lib_SegmentedToVirtual(cmd->roomList.segment); + globalCtx->roomList = Lib_SegmentedToVirtual(cmd->roomList.segment); } // SceneTableEntry Header Command 0x06: Entrance List void Scene_HeaderCmdEntranceList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->setupEntranceList = (EntranceEntry*)Lib_SegmentedToVirtual(cmd->entranceList.segment); + globalCtx->setupEntranceList = Lib_SegmentedToVirtual(cmd->entranceList.segment); } // SceneTableEntry Header Command 0x07: Special Files @@ -228,7 +224,7 @@ void Scene_HeaderCmdSpecialFiles(GlobalContext* globalCtx, SceneCmd* cmd) { if (cmd->specialFiles.subKeepIndex != 0) { globalCtx->objectCtx.subKeepIndex = Object_Spawn(&globalCtx->objectCtx, cmd->specialFiles.subKeepIndex); // TODO: Segment number enum? - gSegments[5] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[globalCtx->objectCtx.subKeepIndex].segment); + gSegments[0x05] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[globalCtx->objectCtx.subKeepIndex].segment); } if (cmd->specialFiles.cUpElfMsgNum != 0) { @@ -248,19 +244,21 @@ void Scene_HeaderCmdRoomBehavior(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x0A: Mesh Header void Scene_HeaderCmdMesh(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->roomCtx.currRoom.mesh = (RoomMesh*)Lib_SegmentedToVirtual(cmd->mesh.segment); + globalCtx->roomCtx.currRoom.mesh = Lib_SegmentedToVirtual(cmd->mesh.segment); } // SceneTableEntry Header Command 0x0B: Object List void Scene_HeaderCmdObjectList(GlobalContext* globalCtx, SceneCmd* cmd) { - s32 i, j, k; + s32 i; + s32 j; + s32 k; ObjectStatus* firstObject; ObjectStatus* status; ObjectStatus* status2; s16* objectEntry; void* nextPtr; - objectEntry = (s16*)Lib_SegmentedToVirtual(cmd->objectList.segment); + objectEntry = Lib_SegmentedToVirtual(cmd->objectList.segment); k = 0; i = globalCtx->objectCtx.spawnedObjectCount; status = &globalCtx->objectCtx.status[i]; @@ -305,7 +303,7 @@ void Scene_HeaderCmdObjectList(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x0C: Light List void Scene_HeaderCmdLightList(GlobalContext* globalCtx, SceneCmd* cmd) { s32 i; - LightInfo* lightInfo = (LightInfo*)Lib_SegmentedToVirtual(cmd->lightList.segment); + LightInfo* lightInfo = Lib_SegmentedToVirtual(cmd->lightList.segment); for (i = 0; i < cmd->lightList.num; i++) { LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, lightInfo); @@ -315,14 +313,13 @@ void Scene_HeaderCmdLightList(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x0D: Path List void Scene_HeaderCmdPathList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->setupPathList = (Path*)Lib_SegmentedToVirtual(cmd->pathList.segment); + globalCtx->setupPathList = Lib_SegmentedToVirtual(cmd->pathList.segment); } // SceneTableEntry Header Command 0x0E: Transition Actor List void Scene_HeaderCmdTransiActorList(GlobalContext* globalCtx, SceneCmd* cmd) { globalCtx->doorCtx.numTransitionActors = cmd->transiActorList.num; - globalCtx->doorCtx.transitionActorList = - (TransitionActorEntry*)Lib_SegmentedToVirtual((void*)cmd->transiActorList.segment); + globalCtx->doorCtx.transitionActorList = Lib_SegmentedToVirtual(cmd->transiActorList.segment); func_80105818(globalCtx, globalCtx->doorCtx.numTransitionActors, globalCtx->doorCtx.transitionActorList); } @@ -334,14 +331,14 @@ void Door_InitContext(GameState* state, DoorContext* doorCtx) { // SceneTableEntry Header Command 0x0F: Environment Light Settings List void Scene_HeaderCmdEnvLightSettings(GlobalContext* globalCtx, SceneCmd* cmd) { globalCtx->envCtx.numLightSettings = cmd->lightSettingList.num; - globalCtx->envCtx.lightSettingsList = (void*)Lib_SegmentedToVirtual(cmd->lightSettingList.segment); + globalCtx->envCtx.lightSettingsList = Lib_SegmentedToVirtual(cmd->lightSettingList.segment); } /** * Loads different texture files for each region of the world. * These later are stored in segment 0x06, and used in maps. */ -s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) { +void Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) { static RomFile sceneTextureFiles[9] = { { 0, 0 }, // Default { SEGMENT_ROM_START(scene_texture_01), SEGMENT_ROM_END(scene_texture_01) }, @@ -358,10 +355,8 @@ s32 Scene_LoadAreaTextures(GlobalContext* globalCtx, s32 fileIndex) { if (size != 0) { globalCtx->roomCtx.unk74 = THA_AllocEndAlign16(&globalCtx->state.heap, size); - return DmaMgr_SendRequest0(globalCtx->roomCtx.unk74, vromStart, size); + DmaMgr_SendRequest0(globalCtx->roomCtx.unk74, vromStart, size); } - - // UB: Undefined behaviour to not have a return statement here, but it breaks matching to add one. } // SceneTableEntry Header Command 0x11: Skybox Settings @@ -374,51 +369,49 @@ void Scene_HeaderCmdSkyboxSettings(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x12: Skybox Disables void Scene_HeaderCmdSkyboxDisables(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->envCtx.unk_15 = cmd->skyboxDisables.unk4; - globalCtx->envCtx.unk_16 = cmd->skyboxDisables.unk5; + globalCtx->envCtx.skyboxDisabled = cmd->skyboxDisables.unk4; + globalCtx->envCtx.sunMoonDisabled = cmd->skyboxDisables.unk5; } // SceneTableEntry Header Command 0x10: Time Settings void Scene_HeaderCmdTimeSettings(GlobalContext* globalCtx, SceneCmd* cmd) { - u32 dayTime; - if (cmd->timeSettings.hour != 0xFF && cmd->timeSettings.min != 0xFF) { - gSaveContext.environmentTime = gSaveContext.time = + gSaveContext.environmentTime = gSaveContext.save.time = (u16)(((cmd->timeSettings.hour + (cmd->timeSettings.min / 60.0f)) * 60.0f) / 0.021972656f); } if (cmd->timeSettings.unk6 != 0xFF) { - globalCtx->envCtx.unk_2 = cmd->timeSettings.unk6; + globalCtx->envCtx.timeIncrement = cmd->timeSettings.unk6; } else { - globalCtx->envCtx.unk_2 = 0; + globalCtx->envCtx.timeIncrement = 0; } - if ((gSaveContext.inventory.items[0] == 0xFF) && (globalCtx->envCtx.unk_2 != 0)) { - globalCtx->envCtx.unk_2 = 5; + if ((gSaveContext.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) && (globalCtx->envCtx.timeIncrement != 0)) { + globalCtx->envCtx.timeIncrement = 5; } - if (gSaveContext.unk_3F58 == 0) { - REG(15) = globalCtx->envCtx.unk_2; + if (gSaveContext.sunsSongState == SUNSSONG_INACTIVE) { + REG(15) = globalCtx->envCtx.timeIncrement; } - dayTime = gSaveContext.time; - globalCtx->envCtx.unk_4 = -(Math_SinS(dayTime - 0x8000) * 120.0f) * 25.0f; - dayTime = gSaveContext.time; - globalCtx->envCtx.unk_8 = (Math_CosS(dayTime - 0x8000) * 120.0f) * 25.0f; - dayTime = gSaveContext.time; - globalCtx->envCtx.unk_C = (Math_CosS(dayTime - 0x8000) * 20.0f) * 25.0f; + globalCtx->envCtx.unk_4 = -(Math_SinS(((void)0, gSaveContext.save.time) - 0x8000) * 120.0f) * 25.0f; + globalCtx->envCtx.unk_8 = (Math_CosS(((void)0, gSaveContext.save.time) - 0x8000) * 120.0f) * 25.0f; + globalCtx->envCtx.unk_C = (Math_CosS(((void)0, gSaveContext.save.time) - 0x8000) * 20.0f) * 25.0f; - if (globalCtx->envCtx.unk_2 == 0 && gSaveContext.cutscene < 0xFFF0) { - gSaveContext.environmentTime = gSaveContext.time; + if (globalCtx->envCtx.timeIncrement == 0 && gSaveContext.save.cutscene < 0xFFF0) { + gSaveContext.environmentTime = gSaveContext.save.time; - if (gSaveContext.environmentTime >= 0x2AAA && gSaveContext.environmentTime < 0x4555) { - gSaveContext.environmentTime = 0x3555; - } else if (gSaveContext.environmentTime >= 0x4555 && gSaveContext.environmentTime < 0x5555) { - gSaveContext.environmentTime = 0x5555; - } else if (gSaveContext.environmentTime >= 0xAAAA && gSaveContext.environmentTime < 0xB555) { - gSaveContext.environmentTime = 0xB555; - } else if (gSaveContext.environmentTime >= 0xC000 && gSaveContext.environmentTime < 0xCAAA) { - gSaveContext.environmentTime = 0xCAAA; + if (gSaveContext.environmentTime >= CLOCK_TIME(4, 0) && gSaveContext.environmentTime < CLOCK_TIME(6, 30)) { + gSaveContext.environmentTime = CLOCK_TIME(5, 0); + } else if (gSaveContext.environmentTime >= CLOCK_TIME(6, 30) && + gSaveContext.environmentTime < CLOCK_TIME(8, 0)) { + gSaveContext.environmentTime = CLOCK_TIME(8, 0); + } else if (gSaveContext.environmentTime >= CLOCK_TIME(16, 0) && + gSaveContext.environmentTime < CLOCK_TIME(17, 0)) { + gSaveContext.environmentTime = CLOCK_TIME(17, 0); + } else if (gSaveContext.environmentTime >= CLOCK_TIME(18, 0) && + gSaveContext.environmentTime < CLOCK_TIME(19, 0)) { + gSaveContext.environmentTime = CLOCK_TIME(19, 0); } } } @@ -437,7 +430,7 @@ void Scene_HeaderCmdWindSettings(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x13: Exit List void Scene_HeaderCmdExitList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->setupExitList = (u16*)Lib_SegmentedToVirtual(cmd->exitList.segment); + globalCtx->setupExitList = Lib_SegmentedToVirtual(cmd->exitList.segment); } // SceneTableEntry Header Command 0x09: Undefined @@ -449,7 +442,7 @@ void Scene_HeaderCmdSoundSettings(GlobalContext* globalCtx, SceneCmd* cmd) { globalCtx->soundCtx.seqIndex = cmd->soundSettings.musicSeq; globalCtx->soundCtx.nightSeqIndex = cmd->soundSettings.nighttimeSFX; - if (gSaveContext.seqIndex == 0xFF || func_801A8A50(0) == 0x57) { + if (gSaveContext.seqIndex == (u8)NA_BGM_DISABLED || func_801A8A50(0) == NA_BGM_FINAL_HOURS) { audio_setBGM(cmd->soundSettings.bgmId); } } @@ -465,11 +458,11 @@ void Scene_HeaderCmdAltHeaderList(GlobalContext* globalCtx, SceneCmd* cmd) { SceneCmd* altHeader; if (gSaveContext.sceneSetupIndex) { - altHeaderList = (SceneCmd**)Lib_SegmentedToVirtual(cmd->altHeaders.segment); + altHeaderList = Lib_SegmentedToVirtual(cmd->altHeaders.segment); altHeader = altHeaderList[gSaveContext.sceneSetupIndex - 1]; if (altHeader != NULL) { - Scene_ProcessHeader(globalCtx, (SceneCmd*)Lib_SegmentedToVirtual(altHeader)); + Scene_ProcessHeader(globalCtx, Lib_SegmentedToVirtual(altHeader)); (cmd + 1)->base.code = 0x14; } } @@ -477,14 +470,13 @@ void Scene_HeaderCmdAltHeaderList(GlobalContext* globalCtx, SceneCmd* cmd) { // SceneTableEntry Header Command 0x17: Cutscene List void Scene_HeaderCmdCutsceneList(GlobalContext* globalCtx, SceneCmd* cmd) { - globalCtx->csCtx.sceneCsCount = (u8)cmd->base.data1; - globalCtx->csCtx.sceneCsList = (CutsceneEntry*)Lib_SegmentedToVirtual((void*)cmd->base.data2); + globalCtx->csCtx.sceneCsCount = cmd->base.data1; + globalCtx->csCtx.sceneCsList = Lib_SegmentedToVirtual(cmd->base.data2); } // SceneTableEntry Header Command 0x1B: Actor Cutscene List void Scene_HeaderCmdActorCutsceneList(GlobalContext* globalCtx, SceneCmd* cmd) { - ActorCutscene_Init(globalCtx, (ActorCutscene*)Lib_SegmentedToVirtual(cmd->cutsceneActorList.segment), - cmd->cutsceneActorList.num); + ActorCutscene_Init(globalCtx, Lib_SegmentedToVirtual(cmd->cutsceneActorList.segment), cmd->cutsceneActorList.num); } // SceneTableEntry Header Command 0x1C: Mini Maps @@ -525,7 +517,7 @@ void Scene_HeaderCmdSetAreaVisitedFlag(GlobalContext* globalCtx, SceneCmd* cmd) } if (i < ARRAY_COUNT(gScenesPerRegion)) { - gSaveContext.mapsVisited = (gBitFlags[i] | gSaveContext.mapsVisited) | gSaveContext.mapsVisited; + gSaveContext.save.mapsVisited = (gBitFlags[i] | gSaveContext.save.mapsVisited) | gSaveContext.save.mapsVisited; } } @@ -608,5 +600,5 @@ u16 Entrance_CreateIndex(s32 sceneIndex, s32 spawnIndex, s32 sceneSetup) { * Creates an entrance index from the current entrance index with the given spawn index. */ u16 Entrance_CreateIndexFromSpawn(s32 spawnIndex) { - return Entrance_CreateIndex(gSaveContext.entranceIndex >> 9, spawnIndex, 0); + return Entrance_CreateIndex(gSaveContext.save.entranceIndex >> 9, spawnIndex, 0); } diff --git a/src/code/z_scene_proc.c b/src/code/z_scene_proc.c index bdd3ea1ad..8f369008f 100644 --- a/src/code/z_scene_proc.c +++ b/src/code/z_scene_proc.c @@ -1,4 +1,3 @@ -#include "prevent_bss_reordering.h" #include "global.h" s32 sMatAnimStep; @@ -115,7 +114,7 @@ void AnimatedMat_DrawTwoTexScroll(GlobalContext* globalCtx, s32 segment, void* p * Generates a displaylist that sets the prim and env color, and stores it in the provided segment ID. */ void AnimatedMat_SetColor(GlobalContext* globalCtx, s32 segment, F3DPrimColor* primColorResult, F3DEnvColor* envColor) { - Gfx* colorDList = (Gfx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 4); + Gfx* colorDList = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 4); OPEN_DISPS(globalCtx->state.gfxCtx); @@ -142,13 +141,10 @@ void AnimatedMat_SetColor(GlobalContext* globalCtx, s32 segment, F3DPrimColor* p */ void AnimatedMat_DrawColor(GlobalContext* globalCtx, s32 segment, void* params) { AnimatedMatColorParams* colorAnimParams = (AnimatedMatColorParams*)params; - F3DPrimColor* primColor; + F3DPrimColor* primColor = Lib_SegmentedToVirtual(colorAnimParams->primColors); F3DEnvColor* envColor; - s32 curFrame; + s32 curFrame = sMatAnimStep % colorAnimParams->keyFrameLength; - primColor = (F3DPrimColor*)Lib_SegmentedToVirtual(colorAnimParams->primColors); - - curFrame = sMatAnimStep % colorAnimParams->keyFrameLength; primColor += curFrame; envColor = (colorAnimParams->envColors != NULL) ? (F3DEnvColor*)Lib_SegmentedToVirtual(colorAnimParams->envColors) + curFrame @@ -170,10 +166,10 @@ s32 AnimatedMat_Lerp(s32 min, s32 max, f32 norm) { */ void AnimatedMat_DrawColorLerp(GlobalContext* globalCtx, s32 segment, void* params) { AnimatedMatColorParams* colorAnimParams = (AnimatedMatColorParams*)params; - F3DPrimColor* primColorMax; + F3DPrimColor* primColorMax = Lib_SegmentedToVirtual(colorAnimParams->primColors); F3DEnvColor* envColorMax; - u16* keyFrames; - s32 curFrame; + u16* keyFrames = Lib_SegmentedToVirtual(colorAnimParams->keyFrames); + s32 curFrame = sMatAnimStep % colorAnimParams->keyFrameLength; s32 endFrame; s32 relativeFrame; // relative to the start frame s32 startFrame; @@ -184,9 +180,6 @@ void AnimatedMat_DrawColorLerp(GlobalContext* globalCtx, s32 segment, void* para F3DEnvColor envColorResult; s32 i; - primColorMax = (F3DPrimColor*)Lib_SegmentedToVirtual(colorAnimParams->primColors); - keyFrames = (u16*)Lib_SegmentedToVirtual(colorAnimParams->keyFrames); - curFrame = sMatAnimStep % colorAnimParams->keyFrameLength; keyFrames++; i = 1; @@ -212,7 +205,7 @@ void AnimatedMat_DrawColorLerp(GlobalContext* globalCtx, s32 segment, void* para primColorResult.lodFrac = AnimatedMat_Lerp(primColorMin->lodFrac, primColorMax->lodFrac, norm); if (colorAnimParams->envColors) { - envColorMax = (F3DEnvColor*)Lib_SegmentedToVirtual(colorAnimParams->envColors); + envColorMax = Lib_SegmentedToVirtual(colorAnimParams->envColors); envColorMax += i; envColorMin = envColorMax - 1; envColorResult.r = AnimatedMat_Lerp(envColorMin->r, envColorMax->r, norm); @@ -241,7 +234,7 @@ f32 Scene_LagrangeInterp(s32 n, f32 x[], f32 fx[], f32 xp) { s32 i; s32 j; - for (i = 0, weightsPtr = weights, xPtr1 = x, fxPtr = fx, weightsPtr = weightsPtr; i < n; i++) { + for (i = 0, xPtr1 = x, fxPtr = fx, weightsPtr = weights; i < n; i++) { for (xVal = *xPtr1, m = 1.0f, j = 0, xPtr2 = x; j < n; j++) { if (j != i) { m *= xVal - (*xPtr2); @@ -371,8 +364,8 @@ void AnimatedMat_DrawColorNonLinearInterp(GlobalContext* globalCtx, s32 segment, */ void AnimatedMat_DrawTexCycle(GlobalContext* globalCtx, s32 segment, void* params) { AnimatedMatTexCycleParams* texAnimParams = params; - void** texList = (void**)Lib_SegmentedToVirtual(texAnimParams->textureList); - u8* texId = (u8*)Lib_SegmentedToVirtual(texAnimParams->textureIndexList); + void** texList = Lib_SegmentedToVirtual(texAnimParams->textureList); + u8* texId = Lib_SegmentedToVirtual(texAnimParams->textureIndexList); s32 curFrame = sMatAnimStep % texAnimParams->keyFrameLength; void* tex = Lib_SegmentedToVirtual(texList[texId[curFrame]]); @@ -409,9 +402,9 @@ void AnimatedMat_DrawMain(GlobalContext* globalCtx, AnimatedMaterial* matAnim, f do { segment = matAnim->segment; segmentAbs = ((segment < 0) ? -segment : segment) + 7; - matAnimDrawHandlers[matAnim->type](globalCtx, segmentAbs, (void*)Lib_SegmentedToVirtual(matAnim->params)); + matAnimDrawHandlers[matAnim->type](globalCtx, segmentAbs, Lib_SegmentedToVirtual(matAnim->params)); matAnim++; - } while (segment > -1); + } while (segment >= 0); } } @@ -722,12 +715,12 @@ void Scene_DrawConfigGreatBayTemple(GlobalContext* globalCtx) { if (Flags_GetSwitch(globalCtx, 0x33) && Flags_GetSwitch(globalCtx, 0x34) && Flags_GetSwitch(globalCtx, 0x35) && Flags_GetSwitch(globalCtx, 0x36)) { - func_800C3C00(&globalCtx->colCtx, 1); + BgCheck_SetContextFlags(&globalCtx->colCtx, BGCHECK_FLAG_REVERSE_CONVEYOR_FLOW); } else { - func_800C3C14(&globalCtx->colCtx, 1); + BgCheck_UnsetContextFlags(&globalCtx->colCtx, BGCHECK_FLAG_REVERSE_CONVEYOR_FLOW); } - dList = (Gfx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 18); + dList = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 18); AnimatedMat_Draw(globalCtx, globalCtx->sceneMaterialAnims); diff --git a/src/code/z_schedule.c b/src/code/z_schedule.c new file mode 100644 index 000000000..4c57a57d4 --- /dev/null +++ b/src/code/z_schedule.c @@ -0,0 +1,283 @@ +#include "global.h" + +#define SCHEDULE_CALC_TIME(hour, minute, dest, temp) \ + (temp) = (hour)*60.0f; \ + (temp) += (minute); \ + (dest) = (temp) * (0x10000 / 60 / 24.0f); \ + (dest) = SCHEDULE_CONVERT_TIME(dest); + +s32 Schedule_CheckFlagS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckFlagS* cmd = (ScheduleCmdCheckFlagS*)*script; + u16 flag = (cmd->flagByte << 8) | cmd->flagMask; + + if (gSaveContext.save.weekEventReg[flag >> 8] & (flag & 0xFF)) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_CheckFlagL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckFlagL* cmd = (ScheduleCmdCheckFlagL*)*script; + u16 flag = (cmd->flagByte << 8) | cmd->flagMask; + + if (gSaveContext.save.weekEventReg[flag >> 8] & (flag & 0xFF)) { + *script += (s16)((cmd->offsetH << 8) | cmd->offsetL); + } + + return false; +} + +s32 Schedule_CheckTimeRangeS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + s32 inRange = false; + ScheduleCmdCheckTimeRangeS* cmd = (ScheduleCmdCheckTimeRangeS*)*script; + f32 f; + u16 start; + u16 end; + u16 now; + + SCHEDULE_CALC_TIME(cmd->startHr, cmd->startMin, start, f); + + SCHEDULE_CALC_TIME(cmd->endHr, cmd->endMin, end, f); + end--; + + now = SCHEDULE_TIME_NOW; + + if ((start <= now) && (now <= end)) { + inRange = true; + } + + if (inRange == true) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_CheckTimeRangeL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + s32 inRange = false; + ScheduleCmdCheckTimeRangeL* cmd = (ScheduleCmdCheckTimeRangeL*)*script; + f32 f; + u16 start; + u16 end; + u16 now; + + SCHEDULE_CALC_TIME(cmd->startHr, cmd->startMin, start, f); + + SCHEDULE_CALC_TIME(cmd->endHr, cmd->endMin, end, f); + end--; + + now = SCHEDULE_TIME_NOW; + + if ((start <= now) && (now <= end)) { + inRange = true; + } + + if (inRange == true) { + *script += (s16)((cmd->offsetH << 8) | cmd->offsetL); + } + + return false; +} + +s32 Schedule_ReturnValueL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdReturnValueL* cmd = (ScheduleCmdReturnValueL*)*script; + + //! @bug result is a u8, value is truncated + result->result = (cmd->retH << 8) | cmd->retL; + result->hasResult = true; + + return true; +} + +s32 Schedule_ReturnNone(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + result->hasResult = false; + + return true; +} + +s32 Schedule_ReturnEmpty(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + result->hasResult = true; + + return true; +} + +s32 Schedule_Nop(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + return false; +} + +s32 Schedule_CheckMiscS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckMiscS* cmd = (ScheduleCmdCheckMiscS*)*script; + + if (((cmd->which == SCHEDULE_CHECK_MISC_ROOM_KEY) && (INV_CONTENT(ITEM_ROOM_KEY) == ITEM_ROOM_KEY)) || + ((cmd->which == SCHEDULE_CHECK_MISC_LETTER_TO_KAFEI) && + (INV_CONTENT(ITEM_LETTER_TO_KAFEI) == ITEM_LETTER_TO_KAFEI)) || + ((cmd->which == SCHEDULE_CHECK_MISC_MASK_ROMANI) && (Player_GetMask(globalCtx) == PLAYER_MASK_ROMANI))) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_ReturnValueS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdReturnValueS* cmd = (ScheduleCmdReturnValueS*)*script; + + result->result = cmd->result; + result->hasResult = true; + + return true; +} + +s32 Schedule_CheckNotInSceneS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckNotInSceneS* cmd = (ScheduleCmdCheckNotInSceneS*)*script; + s16 scene = (cmd->sceneH << 8) | cmd->sceneL; + + if (scene != globalCtx->sceneNum) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_CheckNotInSceneL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckNotInSceneL* cmd = (ScheduleCmdCheckNotInSceneL*)*script; + s16 scene = (cmd->sceneH << 8) | cmd->sceneL; + + if (scene != globalCtx->sceneNum) { + *script = *script + (s16)((cmd->offsetH << 8) | cmd->offsetL); + } + + return false; +} + +s32 Schedule_CheckNotInDayS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckNotInDayS* cmd = (ScheduleCmdCheckNotInDayS*)*script; + s16 day = (cmd->dayH << 8) | cmd->dayL; + + if (day != (s16)gSaveContext.save.day) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_CheckNotInDayL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckNotInDayL* cmd = (ScheduleCmdCheckNotInDayL*)*script; + s16 day = (cmd->dayH << 8) | cmd->dayL; + + if (day != (s16)gSaveContext.save.day) { + *script += (s16)((cmd->offsetH << 8) | cmd->offsetL); + } + + return false; +} + +s32 Schedule_ReturnTime(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdReturnTime* cmd = (ScheduleCmdReturnTime*)*script; + f32 f; + u16 time0; + u16 time1; + + SCHEDULE_CALC_TIME(cmd->time0Hr, cmd->time0Min, time0, f); + + SCHEDULE_CALC_TIME(cmd->time1Hr, cmd->time1Min, time1, f); + time1--; + + result->result = cmd->result; + result->time0 = time0; + result->time1 = time1; + result->hasResult = true; + + return true; +} + +s32 Schedule_CheckBeforeTimeS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckBeforeTimeS* cmd = (ScheduleCmdCheckBeforeTimeS*)*script; + f32 f; + u16 testTime; + u16 now; + + SCHEDULE_CALC_TIME(cmd->timeHr, cmd->timeMin, testTime, f); + + now = SCHEDULE_TIME_NOW; + + if (now < testTime) { + *script += cmd->offset; + } + + return false; +} + +s32 Schedule_CheckBeforeTimeL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdCheckBeforeTimeL* cmd = (ScheduleCmdCheckBeforeTimeL*)*script; + f32 f; + u16 testTime; + u16 now; + + SCHEDULE_CALC_TIME(cmd->timeHr, cmd->timeMin, testTime, f); + + now = SCHEDULE_TIME_NOW; + + if (now < testTime) { + *script += (s16)((cmd->offsetH << 8) | cmd->offsetL); + } + + return false; +} + +s32 Schedule_BranchS(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdBranchS* cmd = (ScheduleCmdBranchS*)*script; + + *script += cmd->offset; + return false; +} + +s32 Schedule_BranchL(GlobalContext* globalCtx, u8** script, ScheduleResult* result) { + ScheduleCmdBranchL* cmd = (ScheduleCmdBranchL*)*script; + + *script += (s16)((cmd->offsetH << 8) | cmd->offsetL); + return false; +} + +static s32 (*sScheduleCmdFuncs[])(GlobalContext*, u8**, ScheduleResult*) = { + Schedule_CheckFlagS, Schedule_CheckFlagL, Schedule_CheckTimeRangeS, Schedule_CheckTimeRangeL, + Schedule_ReturnValueL, Schedule_ReturnNone, Schedule_ReturnEmpty, Schedule_Nop, + Schedule_CheckMiscS, Schedule_ReturnValueS, Schedule_CheckNotInSceneS, Schedule_CheckNotInSceneL, + Schedule_CheckNotInDayS, Schedule_CheckNotInDayL, Schedule_ReturnTime, Schedule_CheckBeforeTimeS, + Schedule_CheckBeforeTimeL, Schedule_BranchS, Schedule_BranchL, +}; + +static u8 sScheduleCmdSizes[] = { + sizeof(ScheduleCmdCheckFlagS), + sizeof(ScheduleCmdCheckFlagL), + sizeof(ScheduleCmdCheckTimeRangeS), + sizeof(ScheduleCmdCheckTimeRangeL), + sizeof(ScheduleCmdReturnValueL), + sizeof(ScheduleCmdBase), + sizeof(ScheduleCmdBase), + sizeof(ScheduleCmdNop), + sizeof(ScheduleCmdCheckMiscS), + sizeof(ScheduleCmdReturnValueS), + sizeof(ScheduleCmdCheckNotInSceneS), + sizeof(ScheduleCmdCheckNotInSceneL), + sizeof(ScheduleCmdCheckNotInDayS), + sizeof(ScheduleCmdCheckNotInDayL), + sizeof(ScheduleCmdReturnTime), + sizeof(ScheduleCmdCheckBeforeTimeS), + sizeof(ScheduleCmdCheckBeforeTimeL), + sizeof(ScheduleCmdBranchS), + sizeof(ScheduleCmdBranchL), +}; + +s32 Schedule_RunScript(GlobalContext* globalCtx, u8* script, ScheduleResult* result) { + u8 size; + s32 stop; + + do { + size = sScheduleCmdSizes[*script]; + stop = (*sScheduleCmdFuncs[*script])(globalCtx, &script, result); + script += size; + } while (!stop); + + return result->hasResult; +} diff --git a/src/code/z_shrink_window.c b/src/code/z_shrink_window.c index 194ee5083..5bfca86d9 100644 --- a/src/code/z_shrink_window.c +++ b/src/code/z_shrink_window.c @@ -2,6 +2,7 @@ * File: z_shrink_window.c * Description: Draws black top/bottom/side borders on the viewing window (e.g. Z-targeting, talking to NPC) */ +#include "prevent_bss_reordering.h" #include "global.h" ShrinkWindowContext gShrinkWindowContext; diff --git a/src/code/z_skelanime.c b/src/code/z_skelanime.c index 4cd9734f6..0a3334bc8 100644 --- a/src/code/z_skelanime.c +++ b/src/code/z_skelanime.c @@ -7,10 +7,10 @@ s32 LinkAnimation_Once(GlobalContext* globalCtx, SkelAnime* skelAnime); s32 SkelAnime_LoopFull(SkelAnime* skelAnime); s32 SkelAnime_LoopPartial(SkelAnime* skelAnime); s32 SkelAnime_Once(SkelAnime* skelAnime); -void Animation_PlayLoop(SkelAnime* skelAnime, AnimationHeader* animationSeg); +void Animation_PlayLoop(SkelAnime* skelAnime, AnimationHeader* animation); void SkelAnime_UpdateTranslation(SkelAnime* skelAnime, Vec3f* pos, s16 angle); -void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* linkAnimetionEntrySeg, - f32 playbackSpeed, f32 frame, f32 frameCount, u8 animationMode, f32 transitionRate); +void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAnimationHeader* animation, f32 playSpeed, + f32 frame, f32 frameCount, u8 animationMode, f32 morphFrames); void SkelAnime_CopyFrameTable(SkelAnime* skelAnime, Vec3s* dst, Vec3s* src); static AnimationEntryCallback sAnimationLoadDone[] = { @@ -33,8 +33,8 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); - limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + Matrix_Push(); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -44,7 +44,7 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele dList = limb->dLists[lod]; if ((overrideLimbDraw == NULL) || (overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor) == 0)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -63,7 +63,7 @@ void SkelAnime_DrawLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** skele SkelAnime_DrawLimbLod(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor, lod); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { SkelAnime_DrawLimbLod(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor, @@ -91,9 +91,9 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); - rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; pos.z = jointTable[0].z; @@ -102,7 +102,7 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa dList = rootLimb->dLists[lod]; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -123,7 +123,7 @@ void SkelAnime_DrawLod(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa lod); } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -143,9 +143,9 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); - limb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -157,7 +157,7 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s newDList = limbDList = limb->dLists[lod]; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { Matrix_ToMtx(*mtx); gSPMatrix(POLY_OPA_DISP++, *mtx, G_MTX_LOAD); @@ -178,7 +178,7 @@ void SkelAnime_DrawFlexLimbLod(GlobalContext* globalCtx, s32 limbIndex, void** s lod, mtx); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { SkelAnime_DrawFlexLimbLod(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor, @@ -202,7 +202,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi Gfx* limbDList; Vec3f pos; Vec3s rot; - Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); if (skeleton == NULL) { return; @@ -210,10 +210,10 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi OPEN_DISPS(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0xD, mtx); - Matrix_StatePush(); + gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); + Matrix_Push(); - rootLimb = (LodLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; pos.z = jointTable[0].z; @@ -223,7 +223,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi newDList = limbDList = rootLimb->dLists[lod]; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -246,7 +246,7 @@ void SkelAnime_DrawFlexLod(GlobalContext* globalCtx, void** skeleton, Vec3s* joi actor, lod, &mtx); } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -263,9 +263,9 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; pos.x = limb->jointPos.x; @@ -274,7 +274,7 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele dList = limb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -292,7 +292,7 @@ void SkelAnime_DrawLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skele SkelAnime_DrawLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { SkelAnime_DrawLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor); @@ -318,7 +318,7 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; @@ -329,7 +329,7 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa dList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -347,7 +347,7 @@ void SkelAnime_DrawOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTa SkelAnime_DrawLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor); } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -363,7 +363,7 @@ void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** s OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; @@ -376,7 +376,7 @@ void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** s newDList = limbDList = limb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { Matrix_ToMtx(*limbMatricies); gSPMatrix(POLY_OPA_DISP++, *limbMatricies, G_MTX_LOAD); @@ -397,7 +397,7 @@ void SkelAnime_DrawFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** s limbMatricies); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { SkelAnime_DrawFlexLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor, @@ -420,7 +420,7 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi Gfx* limbDList; Vec3f pos; Vec3s rot; - Mtx* mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); if (skeleton == NULL) { return; @@ -428,9 +428,9 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi OPEN_DISPS(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0xD, mtx); + gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); - Matrix_StatePush(); + Matrix_Push(); rootLimb = Lib_SegmentedToVirtual(skeleton[0]); @@ -442,7 +442,7 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi newDList = limbDList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -467,14 +467,14 @@ void SkelAnime_DrawFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* joi actor, &mtx); } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDraw unkDraw, - Actor* actor, Mtx** mtx) { +void SkelAnime_DrawTransformFlexLimbOpa(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, + TransformLimbDrawOpa transformLimbDraw, Actor* actor, Mtx** mtx) { StandardLimb* limb; Gfx* newDList; Gfx* limbDList; @@ -483,9 +483,9 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -496,11 +496,11 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec newDList = limbDList = limb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); - Matrix_StatePush(); + Matrix_TranslateRotateZYX(&pos, &rot); + Matrix_Push(); + + transformLimbDraw(globalCtx, limbIndex, actor); - //! @bug Does not check unkDraw is not NULL before calling it. - unkDraw(globalCtx, limbIndex, actor); if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -514,7 +514,7 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec (*mtx)++; } } - Matrix_StatePop(); + Matrix_Pop(); } if (postLimbDraw != NULL) { @@ -522,23 +522,32 @@ void func_80134148(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec } if (limb->child != LIMB_DONE) { - func_80134148(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { - func_80134148(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, mtx); } CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, - OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, UnkActorDraw unkDraw, - Actor* actor) { +/** + * Draw all limbs of type `StandardLimb` in a given flexible skeleton to the polyOpa buffer + * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. + * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. + * + * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb + * coordinates. + * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty. + */ +void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, + TransformLimbDrawOpa transformLimbDraw, Actor* actor) { StandardLimb* rootLimb; s32 pad; Gfx* newDList; @@ -553,13 +562,13 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, OPEN_DISPS(globalCtx->state.gfxCtx); - mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); - gSPSegment(POLY_OPA_DISP++, 0xD, mtx); + gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); - Matrix_StatePush(); + Matrix_Push(); - rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; @@ -569,11 +578,10 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, newDList = limbDList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &newDList, &pos, &rot, actor)) { - Matrix_JointPosition(&pos, &rot); - Matrix_StatePush(); + Matrix_TranslateRotateZYX(&pos, &rot); + Matrix_Push(); - //! @bug Does not check unkDraw is not NULL before calling it. - unkDraw(globalCtx, 1, actor); + transformLimbDraw(globalCtx, 1, actor); if (newDList != NULL) { Gfx* polyTemp = POLY_OPA_DISP; @@ -587,7 +595,7 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, Matrix_ToMtx(mtx++); } } - Matrix_StatePop(); + Matrix_Pop(); } if (postLimbDraw != NULL) { @@ -595,11 +603,11 @@ void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, } if (rootLimb->child != LIMB_DONE) { - func_80134148(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, unkDraw, actor, - &mtx); + SkelAnime_DrawTransformFlexLimbOpa(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, &mtx); } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -652,9 +660,9 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton Vec3f pos; Vec3s rot; - Matrix_StatePush(); + Matrix_Push(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -665,7 +673,7 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton dList = limb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &dList, &pos, &rot, actor, &gfx)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); gSPDisplayList(&gfx[1], dList); @@ -682,7 +690,7 @@ Gfx* SkelAnime_DrawLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton gfx); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { gfx = SkelAnime_DrawLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, actor, @@ -708,9 +716,9 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable return NULL; } - Matrix_StatePush(); + Matrix_Push(); - rootLimb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[0]); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); pos.x = jointTable[0].x; pos.y = jointTable[0].y; @@ -721,7 +729,7 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable dList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &dList, &pos, &rot, actor, &gfx)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (dList != NULL) { gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); gSPDisplayList(&gfx[1], dList); @@ -738,7 +746,7 @@ Gfx* SkelAnime_Draw(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable actor, gfx); } - Matrix_StatePop(); + Matrix_Pop(); return gfx; } @@ -755,9 +763,9 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel Vec3f pos; Vec3s rot; - Matrix_StatePush(); + Matrix_Push(); - limb = (StandardLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); limbIndex++; rot = jointTable[limbIndex]; @@ -768,7 +776,7 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel newDList = limbDList = limb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor, &gfx)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { gSPMatrix(&gfx[0], Matrix_ToMtx(*mtx), G_MTX_LOAD); gSPDisplayList(&gfx[1], newDList); @@ -791,7 +799,7 @@ Gfx* SkelAnime_DrawFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skel actor, mtx, gfx); } - Matrix_StatePop(); + Matrix_Pop(); if (limb->sibling != LIMB_DONE) { gfx = SkelAnime_DrawFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, @@ -820,11 +828,11 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT return NULL; } - mtx = (Mtx*)GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); + mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * dListCount)); - gSPSegment(gfx++, 0xD, mtx); + gSPSegment(gfx++, 0x0D, mtx); - Matrix_StatePush(); + Matrix_Push(); rootLimb = Lib_SegmentedToVirtual(skeleton[0]); @@ -837,7 +845,7 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT newDList = limbDList = rootLimb->dList; if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, 1, &newDList, &pos, &rot, actor, &gfx)) { - Matrix_JointPosition(&pos, &rot); + Matrix_TranslateRotateZYX(&pos, &rot); if (newDList != NULL) { gSPMatrix(&gfx[0], Matrix_ToMtx(mtx), G_MTX_LOAD); gSPDisplayList(&gfx[1], newDList); @@ -860,7 +868,7 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT actor, &mtx, gfx); } - Matrix_StatePop(); + Matrix_Pop(); return gfx; } @@ -869,8 +877,6 @@ Gfx* SkelAnime_DrawFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointT * Unpacks frame data for the animation at the given frame into frameTable * Used by the legacy animation format */ -#ifdef NON_MATCHING -// equivalent, minor reordering s16 SkelAnime_GetFrameDataLegacy(LegacyAnimationHeader* animation, s32 frame, Vec3s* frameTable) { LegacyAnimationHeader* animHeader = Lib_SegmentedToVirtual(animation); s16 limbCount = animHeader->limbCount; @@ -880,59 +886,21 @@ s16 SkelAnime_GetFrameDataLegacy(LegacyAnimationHeader* animation, s32 frame, Ve s16* dynamicData = &frameData[frame]; s32 i; - /** - *Equivalent to the following, but the compiler optimizes the loop in a way I can't replicate - */ - /* - for(i = 0, frameTable++, key++; i < limbCount + 1; i++, key++, frameTable++) { - frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; - frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; - frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; - } - */ frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; - i = 1; frameTable++; key++; - if (limbCount & 1) {} - - if (limbCount > 0) { - if (limbCount & 1) { - i++; - frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; - frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; - frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; - key++; - frameTable++; - if (limbCount + 1 == i) { - goto ret; - } - } - do { - i += 2; - frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; - frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; - frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; - key++; - frameTable++; - frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; - frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; - frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; - key++; - frameTable++; - } while (i != limbCount + 1); + for (i = 1; i <= limbCount; i++, key++, frameTable++) { + frameTable->x = frame < key->xMax ? dynamicData[key->x] : staticData[key->x]; + frameTable->y = frame < key->yMax ? dynamicData[key->y] : staticData[key->y]; + frameTable->z = frame < key->zMax ? dynamicData[key->z] : staticData[key->z]; } -ret: return limbCount; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skelanime/SkelAnime_GetFrameData2.s") -#endif /** * Used by legacy animation format @@ -1033,7 +1001,7 @@ void AnimationContext_SetLoadFrame(GlobalContext* globalCtx, LinkAnimationHeader AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMATION_LINKANIMETION); if (entry != NULL) { - LinkAnimationHeader* linkAnimHeader = (LinkAnimationHeader*)Lib_SegmentedToVirtual(animation); + LinkAnimationHeader* linkAnimHeader = Lib_SegmentedToVirtual(animation); u32 ram = frameTable; osCreateMesgQueue(&entry->data.load.msgQueue, &entry->data.load.msg, 1); @@ -1105,13 +1073,13 @@ void AnimationContext_SetCopyFalse(GlobalContext* globalCtx, s32 vecCount, Vec3s /** * Requests moving an actor according to the translation of its root limb */ -void AnimationContext_SetMoveActor(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 actor3) { +void AnimationContext_SetMoveActor(GlobalContext* globalCtx, Actor* actor, SkelAnime* skelAnime, f32 arg3) { AnimationEntry* entry = AnimationContext_AddEntry(&globalCtx->animationCtx, ANIMENTRY_MOVEACTOR); if (entry != NULL) { entry->data.move.actor = actor; entry->data.move.skelAnime = skelAnime; - entry->data.move.unk08 = actor3; + entry->data.move.unk08 = arg3; } } @@ -1270,9 +1238,9 @@ void SkelAnime_InitLink(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkel */ void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime) { if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) { - skelAnime->update = LinkAnimation_Loop; + skelAnime->update.link = LinkAnimation_Loop; } else { - skelAnime->update = LinkAnimation_Once; + skelAnime->update.link = LinkAnimation_Once; } skelAnime->morphWeight = 0.0f; } @@ -1282,7 +1250,7 @@ void LinkAnimation_SetUpdateFunction(SkelAnime* skelAnime) { * finishes. */ s32 LinkAnimation_Update(GlobalContext* globalCtx, SkelAnime* skelAnime) { - return skelAnime->update(globalCtx, skelAnime); + return skelAnime->update.link(globalCtx, skelAnime); } /** @@ -1387,7 +1355,7 @@ void LinkAnimation_Change(GlobalContext* globalCtx, SkelAnime* skelAnime, LinkAn SkelAnime_CopyFrameTable(skelAnime, skelAnime->morphTable, skelAnime->jointTable); morphFrames = -morphFrames; } else { - skelAnime->update = LinkAnimation_Morph; + skelAnime->update.link = LinkAnimation_Morph; AnimationContext_SetLoadFrame(globalCtx, animation, (s32)startFrame, skelAnime->limbCount, skelAnime->morphTable); } @@ -1608,7 +1576,7 @@ void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkel /** * Initializes a skeleton with SkinLimbs to a looping animation, dynamically allocating the frame tables. */ -void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, +void SkelAnime_InitSkin(GameState* gameState, SkelAnime* skelAnime, SkeletonHeader* skeletonHeaderSeg, AnimationHeader* animation) { SkeletonHeader* skeletonHeader; @@ -1631,11 +1599,11 @@ void SkelAnime_InitSkin(GlobalContext* globalCtx, SkelAnime* skelAnime, Skeleton */ void SkelAnime_SetUpdate(SkelAnime* skelAnime) { if (skelAnime->mode <= ANIMMODE_LOOP_INTERP) { - skelAnime->update = SkelAnime_LoopFull; + skelAnime->update.normal = SkelAnime_LoopFull; } else if (skelAnime->mode <= ANIMMODE_ONCE_INTERP) { - skelAnime->update = SkelAnime_Once; + skelAnime->update.normal = SkelAnime_Once; } else { - skelAnime->update = SkelAnime_LoopPartial; + skelAnime->update.normal = SkelAnime_LoopPartial; } } @@ -1644,7 +1612,7 @@ void SkelAnime_SetUpdate(SkelAnime* skelAnime) { * finishes. */ s32 SkelAnime_Update(SkelAnime* skelAnime) { - return skelAnime->update(skelAnime); + return skelAnime->update.normal(skelAnime); } /** @@ -1806,10 +1774,10 @@ void Animation_ChangeImpl(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames = -morphFrames; } else { if (taper != ANIMTAPER_NONE) { - skelAnime->update = SkelAnime_MorphTaper; + skelAnime->update.normal = SkelAnime_MorphTaper; skelAnime->taper = taper; } else { - skelAnime->update = SkelAnime_Morph; + skelAnime->update.normal = SkelAnime_Morph; } SkelAnime_GetFrameData(animation, startFrame, skelAnime->limbCount, skelAnime->morphTable); } @@ -1860,8 +1828,8 @@ void Animation_PlayOnce(SkelAnime* skelAnime, AnimationHeader* animation) { * animation. Negative morph frames start the new animation immediately, modified by the pose immediately before the * animation change. */ -void Animation_MorphToPlayOnce(SkelAnime* skelAnime, AnimationHeader* animationSeg, f32 morphFrames) { - Animation_Change(skelAnime, animationSeg, 1.0f, 0, Animation_GetLastFrame(&animationSeg->common), ANIMMODE_ONCE, +void Animation_MorphToPlayOnce(SkelAnime* skelAnime, AnimationHeader* animation, f32 morphFrames) { + Animation_Change(skelAnime, animation, 1.0f, 0, Animation_GetLastFrame(&animation->common), ANIMMODE_ONCE, morphFrames); } @@ -1893,9 +1861,9 @@ void Animation_MorphToLoop(SkelAnime* skelAnime, AnimationHeader* animation, f32 /** * Immediately changes to an animation that loops at the specified speed. */ -void Animation_PlayLoopSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playbackSpeed) { - Animation_Change(skelAnime, animation, playbackSpeed, 0.0f, Animation_GetLastFrame(&animation->common), - ANIMMODE_LOOP, 0.0f); +void Animation_PlayLoopSetSpeed(SkelAnime* skelAnime, AnimationHeader* animation, f32 playSpeed) { + Animation_Change(skelAnime, animation, playSpeed, 0.0f, Animation_GetLastFrame(&animation->common), ANIMMODE_LOOP, + 0.0f); } /** diff --git a/src/code/z_skin.c b/src/code/z_skin.c index f031b007f..de449c02d 100644 --- a/src/code/z_skin.c +++ b/src/code/z_skin.c @@ -1,23 +1,273 @@ #include "global.h" +#include "z64skin.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137970.s") +// 60 is an arbitrary number which specifies the max amount of limbs per skeleton this system supports +MtxF gSkinLimbMatrices[60]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137B34.s") +static s32 sUnused; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137EBC.s") +void Skin_UpdateVertices(MtxF* mtx, SkinVertex* skinVertices, SkinLimbModif* modifEntry, Vtx* vtxBuf, Vec3f* pos) { + SkinVertex* vertexEntry; + Vtx* vtx; + Vec3f wTemp; + Vec3f normal; + Vec3f sp44; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80137F58.s") + wTemp.x = mtx->xw; + wTemp.y = mtx->yw; + wTemp.z = mtx->zw; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138050.s") + mtx->xw = 0.0f; + mtx->yw = 0.0f; + mtx->zw = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138228.s") + for (vertexEntry = skinVertices; vertexEntry < &skinVertices[modifEntry->vtxCount]; vertexEntry++) { + vtx = &vtxBuf[vertexEntry->index]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138258.s") + vtx->n.ob[0] = pos->x; + vtx->n.ob[1] = pos->y; + vtx->n.ob[2] = pos->z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_8013828C.s") + sp44.x = vertexEntry->normX; + sp44.y = vertexEntry->normY; + sp44.z = vertexEntry->normZ; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_801382C4.s") + SkinMatrix_Vec3fMtxFMultXYZ(mtx, &sp44, &normal); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_80138300.s") + vtx->n.n[0] = normal.x; + vtx->n.n[1] = normal.y; + vtx->n.n[2] = normal.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin/func_8013835C.s") + mtx->xw = wTemp.x; + mtx->yw = wTemp.y; + mtx->zw = wTemp.z; +} + +void Skin_ApplyLimbModifications(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3) { + s32 modifCount; + SkinLimb** skeleton; + s32 pad; + SkinAnimatedLimbData* data; + s32 pad2[5]; + SkinLimbModif* modif; + SkinLimbVtx* vtxEntry; + s32 pad3; + s32 transformCount; + f32 scale; + SkinVertex* skinVertices; + Vec3f sp88; + Vtx* vtxBuf; + SkinTransformation* limbTransformations; + Vec3f spDC; + Vec3f spD0; + SkinTransformation* transformationEntry; + SkinLimb* limb; + SkinLimbModif* modifications; + + OPEN_DISPS(gfxCtx); + + skeleton = (SkinLimb**)Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + limb = (SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]); + data = Lib_SegmentedToVirtual(limb->segment); + modifications = (SkinLimbModif*)Lib_SegmentedToVirtual(data->limbModifications); + + vtxEntry = &skin->vtxTable[limbIndex]; + + vtxBuf = vtxEntry->buf[vtxEntry->index]; + modifCount = data->limbModifCount; + + for (modif = modifications; modif < &modifications[modifCount]; modif++) { + Vec3f spAC; + Vec3f spA0; + + skinVertices = (SkinVertex*)Lib_SegmentedToVirtual(modif->skinVertices); + limbTransformations = (SkinTransformation*)Lib_SegmentedToVirtual(modif->limbTransformations); + transformCount = modif->transformCount; + + if (transformCount == 1) { + spAC.x = limbTransformations[0].x; + spAC.y = limbTransformations[0].y; + spAC.z = limbTransformations[0].z; + + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[limbTransformations[0].limbIndex], &spAC, &spDC); + } else if (arg3) { + transformationEntry = &limbTransformations[modif->unk_04]; + + spA0.x = transformationEntry->x; + spA0.y = transformationEntry->y; + spA0.z = transformationEntry->z; + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[transformationEntry->limbIndex], &spA0, &spDC); + } else { + spDC.x = 0.0f; + spDC.y = 0.0f; + spDC.z = 0.0f; + + for (transformationEntry = limbTransformations; transformationEntry < &limbTransformations[transformCount]; + transformationEntry++) { + scale = transformationEntry->scale * 0.01f; + + sp88.x = transformationEntry->x; + sp88.y = transformationEntry->y; + sp88.z = transformationEntry->z; + + SkinMatrix_Vec3fMtxFMultXYZ(&gSkinLimbMatrices[transformationEntry->limbIndex], &sp88, &spD0); + + spDC.x += spD0.x * scale; + spDC.y += spD0.y * scale; + spDC.z += spD0.z * scale; + } + } + + Skin_UpdateVertices(&gSkinLimbMatrices[limbTransformations[modif->unk_04].limbIndex], skinVertices, modif, + vtxBuf, &spDC); + } + + gSPSegment(POLY_OPA_DISP++, 0x08, vtxEntry->buf[vtxEntry->index]); + + vtxEntry->index = (vtxEntry->index == 0); + + CLOSE_DISPS(gfxCtx); +} + +/** + * Draw a limb of type SKIN_LIMB_TYPE_ANIMATED, of the skeleton `skin` at index `limbIndex` + * The vertices of this limb are modified dynamically + */ +void Skin_DrawAnimatedLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, s32 arg3, s32 drawFlags) { + SkinLimb** skeleton; + s32 pad[3]; + SkinAnimatedLimbData* data; + + OPEN_DISPS(gfxCtx); + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + data = Lib_SegmentedToVirtual(((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_TRANSFORMS)) { + Skin_ApplyLimbModifications(gfxCtx, skin, limbIndex, arg3); + } + + gSPDisplayList(POLY_OPA_DISP++, data->dlist); + + CLOSE_DISPS(gfxCtx); +} + +/** + * Draw a limb of type SKIN_LIMB_TYPE_NORMAL, of the skeleton `skin` at index `limbIndex` + */ +void Skin_DrawLimb(GraphicsContext* gfxCtx, Skin* skin, s32 limbIndex, Gfx* dListOverride, s32 drawFlags) { + Gfx* gfx = dListOverride; + SkinLimb** skeleton; + + OPEN_DISPS(gfxCtx); + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + + if (dListOverride == NULL) { + gfx = ((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment; + } + + if (gfx != NULL) { + Mtx* mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &gSkinLimbMatrices[limbIndex]); + + if (mtx != NULL) { + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gfx); + gSPPopMatrix(POLY_OPA_DISP++, G_MTX_MODELVIEW); + gDPPipeSync(POLY_OPA_DISP++); + } + } + + CLOSE_DISPS(gfxCtx); +} + +void Skin_DrawImpl(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags) { + s32 i; + SkinLimb** skeleton; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_TRANSFORMS)) { + Skin_ApplyAnimTransformations(skin, gSkinLimbMatrices, actor, setTranslation); + } + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + + if (!(drawFlags & SKIN_DRAW_FLAG_CUSTOM_MATRIX)) { + Mtx* mtx; + + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &skin->mtx); + if (mtx == NULL) { + goto close_disps; + } + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + for (i = 0; i < skin->skeletonHeader->limbCount; i++) { + s32 shouldDraw = true; + s32 segmentType; + + if (overrideLimbDraw != NULL) { + shouldDraw = overrideLimbDraw(actor, globalCtx, i, skin); + } + + segmentType = ((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segmentType; + + if (segmentType == SKIN_LIMB_TYPE_ANIMATED && shouldDraw) { + Skin_DrawAnimatedLimb(gfxCtx, skin, i, arg6, drawFlags); + } else if (segmentType == SKIN_LIMB_TYPE_NORMAL && shouldDraw) { + Skin_DrawLimb(gfxCtx, skin, i, NULL, drawFlags); + } + } + + if (postDraw != NULL) { + postDraw(actor, globalCtx, skin); + } + +close_disps:; + CLOSE_DISPS(gfxCtx); +} + +// allows specifying postDraw and setTranslation +void func_80138228(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, s32 setTranslation) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, NULL, setTranslation, false, 0); +} + +// allows specifying OverrideLimbDraw, postDraw and setTranslation +void func_80138258(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, false, 0); +} + +// allows specifying OverrideLimbDraw, postDraw, setTranslation, and arg6 +void func_8013828C(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, arg6, 0); +} + +// allows specifying all variables +void func_801382C4(Actor* actor, GlobalContext* globalCtx, Skin* skin, SkinPostDraw postDraw, + SkinOverrideLimbDraw overrideLimbDraw, s32 setTranslation, s32 arg6, s32 drawFlags) { + Skin_DrawImpl(actor, globalCtx, skin, postDraw, overrideLimbDraw, setTranslation, arg6, drawFlags); +} + +void Skin_GetLimbPos(Skin* skin, s32 limbIndex, Vec3f* offset, Vec3f* dst) { + MtxF mtxf; + + SkinMatrix_MtxFMtxFMult(&skin->mtx, &gSkinLimbMatrices[limbIndex], &mtxf); + SkinMatrix_Vec3fMtxFMultXYZ(&mtxf, offset, dst); +} + +void Skin_GetVertexPos(Skin* skin, s32 limbIndex, s32 vtxIndex, Vec3f* dst) { + Vec3f pos; + Vtx* vtx = &skin->vtxTable[limbIndex].buf[skin->vtxTable[0].index][vtxIndex]; + + pos.x = vtx->n.ob[0]; + pos.y = vtx->n.ob[1]; + pos.z = vtx->n.ob[2]; + SkinMatrix_Vec3fMtxFMultXYZ(&skin->mtx, &pos, dst); +} diff --git a/src/code/z_skin_awb.c b/src/code/z_skin_awb.c index 22a1c637f..d45b9bc25 100644 --- a/src/code/z_skin_awb.c +++ b/src/code/z_skin_awb.c @@ -1,13 +1,204 @@ #include "global.h" +#include "z64skin.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138410.s") +void Skin_Setup(Skin* skin) { + skin->skeletonHeader = NULL; + skin->limbCount = 0; + skin->vtxTable = NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138424.s") +/** + * Initialises the Vtx buffers used for limb at index `limbIndex` + */ +void Skin_InitAnimatedLimb(GameState* gameState, Skin* skin, s32 limbIndex) { + s32 i; + SkinLimb** skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + SkinAnimatedLimbData* animatedLimbData = + Lib_SegmentedToVirtual(((SkinLimb*)Lib_SegmentedToVirtual(skeleton[limbIndex]))->segment); + SkinLimbModif* limbModifications = Lib_SegmentedToVirtual(animatedLimbData->limbModifications); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_8013859C.s") + for (i = 0; i < ARRAY_COUNT(skin->vtxTable->buf); i++) { + Vtx* vertices = skin->vtxTable[limbIndex].buf[i]; + SkinLimbModif* modifEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_80138700.s") + for (modifEntry = limbModifications; modifEntry < &limbModifications[animatedLimbData->limbModifCount]; + modifEntry++) { + SkinVertex* skinVertices = Lib_SegmentedToVirtual(modifEntry->skinVertices); + SkinVertex* skinVtxEntry; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_801387D4.s") + for (skinVtxEntry = skinVertices; skinVtxEntry < &skinVertices[modifEntry->vtxCount];) { + Vtx* vtx = &vertices[skinVtxEntry->index]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_skin_awb/func_801388E4.s") + skinVtxEntry++; + + vtx->n.flag = 0; + vtx->n.tc[0] = skinVtxEntry[-1].s; + vtx->n.tc[1] = skinVtxEntry[-1].t; + vtx->n.a = skinVtxEntry[-1].alpha; + } + } + } +} + +/** + * Initializes a skin skeleton to looping animation, dynamically allocating the frame tables, + * and dynamically allocating and initialising the Vtx and SkinLimbVtx buffers for its animated limbs + */ +void Skin_Init(GameState* gameState, Skin* skin, SkeletonHeader* skeletonHeader, AnimationHeader* animationHeader) { + s32 limbCount; + s32 i; + SkinLimb** skeleton; + SkeletonHeader* virtSkelHeader = Lib_SegmentedToVirtual(skeletonHeader); + + skin->limbCount = virtSkelHeader->limbCount; + skin->skeletonHeader = virtSkelHeader; + limbCount = skin->skeletonHeader->limbCount; + + skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + skin->vtxTable = ZeldaArena_Malloc(limbCount * sizeof(SkinLimbVtx)); + + for (i = 0; i < limbCount; i++) { + SkinLimbVtx* vtxEntry = &skin->vtxTable[i]; + + if ((((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segmentType != SKIN_LIMB_TYPE_ANIMATED) || + (((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segment == NULL)) { + vtxEntry->index = 0; + + vtxEntry->buf[0] = NULL; + vtxEntry->buf[1] = NULL; + } else { + SkinAnimatedLimbData* animatedLimbData = + Lib_SegmentedToVirtual((((SkinLimb*)Lib_SegmentedToVirtual(skeleton[i]))->segment)); + + { s32 tmp; } + + vtxEntry->index = 0; + vtxEntry->buf[0] = ZeldaArena_Malloc(animatedLimbData->totalVtxCount * sizeof(Vtx)); + vtxEntry->buf[1] = ZeldaArena_Malloc(animatedLimbData->totalVtxCount * sizeof(Vtx)); + + Skin_InitAnimatedLimb(gameState, skin, i); + } + } + + SkelAnime_InitSkin(gameState, &skin->skelAnime, skeletonHeader, animationHeader); +} + +/** + * Frees the dynamically allocated Vtx and SkinLimbVtx buffers and tables + */ +void Skin_Free(GameState* gameState, Skin* skin) { + if (skin->vtxTable != NULL) { + s32 i; + + for (i = 0; i < skin->limbCount; i++) { + if (skin->vtxTable[i].buf[0] != NULL) { + ZeldaArena_Free(skin->vtxTable[i].buf[0]); + skin->vtxTable[i].buf[0] = NULL; + } + if (skin->vtxTable[i].buf[1] != NULL) { + ZeldaArena_Free(skin->vtxTable[i].buf[1]); + skin->vtxTable[i].buf[1] = NULL; + } + } + + if (skin->vtxTable != NULL) { + ZeldaArena_Free(skin->vtxTable); + } + + SkelAnime_Free(&skin->skelAnime, (GlobalContext*)gameState); + } +} + +s32 func_801387D4(Skin* skin, SkinLimb** skeleton, MtxF* limbMatrices, u8 parentIndex, u8 limbIndex) { + s32 pad; + SkinLimb* limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); + MtxF* mtx; + s32 ret; + MtxF sp28; + + if (parentIndex == LIMB_DONE) { + SkinMatrix_GetClear(&mtx); + } else { + mtx = &limbMatrices[(s32)parentIndex]; + } + + SkinMatrix_MtxFMtxFMult(mtx, &limbMatrices[limbIndex], &sp28); + SkinMatrix_MtxFCopy(&sp28, &limbMatrices[limbIndex]); + + if (limb->child != LIMB_DONE) { + ret = func_801387D4(skin, skeleton, limbMatrices, limbIndex, limb->child); + if (ret) { + return ret; + } + } + + if (limb->sibling != LIMB_DONE) { + ret = func_801387D4(skin, skeleton, limbMatrices, parentIndex, limb->sibling); + if (ret) { + return ret; + } + } + + return false; +} + +/** + * Recursively applies matrix tranformations to each limb + */ +s32 Skin_ApplyAnimTransformations(Skin* skin, MtxF* limbMatrices, Actor* actor, s32 setTranslation) { + s32 i; + s32 pad; + f32 yRot; + f32 xRot; + f32 zRot; + s32 ret; + f32 yTransl; + f32 xTransl; + f32 zTransl; + SkinLimb** skeleton = Lib_SegmentedToVirtual(skin->skeletonHeader->segment); + Vec3s* jointRot = skin->skelAnime.jointTable; + + jointRot++; + xRot = jointRot->x; + yRot = jointRot->y; + zRot = jointRot->z; + + if (setTranslation) { + jointRot--; + xTransl = jointRot->x; + yTransl = jointRot->y; + zTransl = jointRot->z; + jointRot++; + + SkinMatrix_SetRotateRPYTranslate(limbMatrices, xRot, yRot, zRot, xTransl, yTransl, zTransl); + } else { + SkinMatrix_SetRotateRPYTranslate(limbMatrices, xRot, yRot, zRot, 0.0f, 0.0f, 0.0f); + } + + jointRot++; + + for (i = 1; i < skin->skeletonHeader->limbCount; i++) { + SkinLimb* limb = Lib_SegmentedToVirtual(skeleton[i]); + + xTransl = limb->jointPos.x; + yTransl = limb->jointPos.y; + zTransl = limb->jointPos.z; + xRot = jointRot->x; + yRot = jointRot->y; + zRot = jointRot->z; + jointRot++; + SkinMatrix_SetRotateRPYTranslate(&limbMatrices[i], xRot, yRot, zRot, xTransl, yTransl, zTransl); + } + + SkinMatrix_SetScaleRotateYRPTranslate( + &skin->mtx, actor->scale.x, actor->scale.y, actor->scale.z, actor->shape.rot.x, actor->shape.rot.y, + actor->shape.rot.z, actor->world.pos.x, actor->world.pos.y + (actor->shape.yOffset * actor->scale.y), + actor->world.pos.z); + + ret = func_801387D4(skin, Lib_SegmentedToVirtual(skin->skeletonHeader->segment), limbMatrices, LIMB_DONE, 0); + if (!ret) { + return ret; + } + + return false; +} diff --git a/src/code/z_skin_matrix.c b/src/code/z_skin_matrix.c index 1afc9a5d5..9b30a3c0b 100644 --- a/src/code/z_skin_matrix.c +++ b/src/code/z_skin_matrix.c @@ -1,13 +1,11 @@ #include "global.h" -// clang-format off -MtxF sMtxFClear = { - 1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f, -}; -// clang-format on +MtxF sMtxFClear = { { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f }, +} }; /** * Multiplies a 4 component row vector [ src , 1 ] by the matrix mf and writes the resulting 4 components to xyzDest @@ -16,10 +14,10 @@ MtxF sMtxFClear = { * \f[ [\texttt{xyzDest}, \texttt{wDest}] = [\texttt{src}, 1] \cdot [mf] \f] */ void SkinMatrix_Vec3fMtxFMultXYZW(MtxF* mf, Vec3f* src, Vec3f* xyzDest, f32* wDest) { - xyzDest->x = mf->wx + ((src->x * mf->xx) + (src->y * mf->yx) + (src->z * mf->zx)); - xyzDest->y = mf->wy + ((src->x * mf->xy) + (src->y * mf->yy) + (src->z * mf->zy)); - xyzDest->z = mf->wz + ((src->x * mf->xz) + (src->y * mf->yz) + (src->z * mf->zz)); - *wDest = mf->ww + ((src->x * mf->xw) + (src->y * mf->yw) + (src->z * mf->zw)); + xyzDest->x = mf->xw + ((src->x * mf->xx) + (src->y * mf->xy) + (src->z * mf->xz)); + xyzDest->y = mf->yw + ((src->x * mf->yx) + (src->y * mf->yy) + (src->z * mf->yz)); + xyzDest->z = mf->zw + ((src->x * mf->zx) + (src->y * mf->zy) + (src->z * mf->zz)); + *wDest = mf->ww + ((src->x * mf->wx) + (src->y * mf->wy) + (src->z * mf->wz)); } /** @@ -29,21 +27,22 @@ void SkinMatrix_Vec3fMtxFMultXYZW(MtxF* mf, Vec3f* src, Vec3f* xyzDest, f32* wDe */ void SkinMatrix_Vec3fMtxFMultXYZ(MtxF* mf, Vec3f* src, Vec3f* dest) { f32 mx = mf->xx; - f32 my = mf->yx; - f32 mz = mf->zx; - f32 mw = mf->wx; + f32 my = mf->xy; + f32 mz = mf->xz; + f32 mw = mf->xw; + dest->x = mw + ((src->x * mx) + (src->y * my) + (src->z * mz)); - mx = mf->xy; + mx = mf->yx; my = mf->yy; - mz = mf->zy; - mw = mf->wy; + mz = mf->yz; + mw = mf->yw; dest->y = mw + ((src->x * mx) + (src->y * my) + (src->z * mz)); - mx = mf->xz; - my = mf->yz; + mx = mf->zx; + my = mf->zy; mz = mf->zz; - mw = mf->wz; + mw = mf->zw; dest->z = mw + ((src->x * mx) + (src->y * my) + (src->z * mz)); } @@ -59,122 +58,122 @@ void SkinMatrix_MtxFMtxFMult(MtxF* mfB, MtxF* mfA, MtxF* dest) { //---COL1--- f32 cx = mfB->xx; - f32 cy = mfB->yx; - f32 cz = mfB->zx; - f32 cw = mfB->wx; + f32 cy = mfB->xy; + f32 cz = mfB->xz; + f32 cw = mfB->xw; //-------- rx = mfA->xx; - ry = mfA->xy; - rz = mfA->xz; - rw = mfA->xw; + ry = mfA->yx; + rz = mfA->zx; + rw = mfA->wx; dest->xx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->yx; + rx = mfA->xy; ry = mfA->yy; - rz = mfA->yz; - rw = mfA->yw; - dest->yx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - rx = mfA->zx; - ry = mfA->zy; - rz = mfA->zz; - rw = mfA->zw; - dest->zx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - rx = mfA->wx; - ry = mfA->wy; - rz = mfA->wz; - rw = mfA->ww; - dest->wx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - //---2Col--- - cx = mfB->xy; - cy = mfB->yy; - cz = mfB->zy; - cw = mfB->wy; - //-------- - rx = mfA->xx; - ry = mfA->xy; - rz = mfA->xz; - rw = mfA->xw; + rz = mfA->zy; + rw = mfA->wy; dest->xy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->yx; - ry = mfA->yy; - rz = mfA->yz; - rw = mfA->yw; - dest->yy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - rx = mfA->zx; - ry = mfA->zy; + rx = mfA->xz; + ry = mfA->yz; rz = mfA->zz; - rw = mfA->zw; - dest->zy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - rx = mfA->wx; - ry = mfA->wy; - rz = mfA->wz; - rw = mfA->ww; - dest->wy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - - //---3Col--- - cx = mfB->xz; - cy = mfB->yz; - cz = mfB->zz; - cw = mfB->wz; - //-------- - rx = mfA->xx; - ry = mfA->xy; - rz = mfA->xz; - rw = mfA->xw; + rw = mfA->wz; dest->xz = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->yx; + rx = mfA->xw; + ry = mfA->yw; + rz = mfA->zw; + rw = mfA->ww; + dest->xw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + //---2Col--- + cx = mfB->yx; + cy = mfB->yy; + cz = mfB->yz; + cw = mfB->yw; + //-------- + rx = mfA->xx; + ry = mfA->yx; + rz = mfA->zx; + rw = mfA->wx; + dest->yx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + rx = mfA->xy; ry = mfA->yy; - rz = mfA->yz; - rw = mfA->yw; + rz = mfA->zy; + rw = mfA->wy; + dest->yy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + rx = mfA->xz; + ry = mfA->yz; + rz = mfA->zz; + rw = mfA->wz; dest->yz = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->zx; - ry = mfA->zy; + rx = mfA->xw; + ry = mfA->yw; + rz = mfA->zw; + rw = mfA->ww; + dest->yw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + //---3Col--- + cx = mfB->zx; + cy = mfB->zy; + cz = mfB->zz; + cw = mfB->zw; + //-------- + rx = mfA->xx; + ry = mfA->yx; + rz = mfA->zx; + rw = mfA->wx; + dest->zx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + rx = mfA->xy; + ry = mfA->yy; + rz = mfA->zy; + rw = mfA->wy; + dest->zy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + + rx = mfA->xz; + ry = mfA->yz; rz = mfA->zz; - rw = mfA->zw; + rw = mfA->wz; dest->zz = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->wx; - ry = mfA->wy; - rz = mfA->wz; + rx = mfA->xw; + ry = mfA->yw; + rz = mfA->zw; rw = mfA->ww; - dest->wz = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + dest->zw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); //---4Col--- - cx = mfB->xw; - cy = mfB->yw; - cz = mfB->zw; + cx = mfB->wx; + cy = mfB->wy; + cz = mfB->wz; cw = mfB->ww; //-------- rx = mfA->xx; - ry = mfA->xy; - rz = mfA->xz; - rw = mfA->xw; - dest->xw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + ry = mfA->yx; + rz = mfA->zx; + rw = mfA->wx; + dest->wx = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->yx; + rx = mfA->xy; ry = mfA->yy; - rz = mfA->yz; - rw = mfA->yw; - dest->yw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + rz = mfA->zy; + rw = mfA->wy; + dest->wy = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->zx; - ry = mfA->zy; + rx = mfA->xz; + ry = mfA->yz; rz = mfA->zz; - rw = mfA->zw; - dest->zw = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); + rw = mfA->wz; + dest->wz = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); - rx = mfA->wx; - ry = mfA->wy; - rz = mfA->wz; + rx = mfA->xw; + ry = mfA->yw; + rz = mfA->zw; rw = mfA->ww; dest->ww = (cx * rx) + (cy * ry) + (cz * rz) + (cw * rw); } @@ -188,39 +187,39 @@ void SkinMatrix_GetClear(MtxF** mfp) { void SkinMatrix_Clear(MtxF* mf) { mf->xx = 1.0f; - mf->xy = 0.0f; - mf->xz = 0.0f; - mf->xw = 0.0f; mf->yx = 0.0f; - mf->yy = 1.0f; - mf->yz = 0.0f; - mf->yw = 0.0f; mf->zx = 0.0f; - mf->zy = 0.0f; - mf->zz = 1.0f; - mf->zw = 0.0f; mf->wx = 0.0f; + mf->xy = 0.0f; + mf->yy = 1.0f; + mf->zy = 0.0f; mf->wy = 0.0f; + mf->xz = 0.0f; + mf->yz = 0.0f; + mf->zz = 1.0f; mf->wz = 0.0f; + mf->xw = 0.0f; + mf->yw = 0.0f; + mf->zw = 0.0f; mf->ww = 1.0f; } void SkinMatrix_MtxFCopy(MtxF* src, MtxF* dest) { dest->xx = src->xx; - dest->xy = src->xy; - dest->xz = src->xz; - dest->xw = src->xw; dest->yx = src->yx; - dest->yy = src->yy; - dest->yz = src->yz; - dest->yw = src->yw; dest->zx = src->zx; - dest->zy = src->zy; - dest->zz = src->zz; - dest->zw = src->zw; dest->wx = src->wx; + dest->xy = src->xy; + dest->yy = src->yy; + dest->zy = src->zy; dest->wy = src->wy; + dest->xz = src->xz; + dest->yz = src->yz; + dest->zz = src->zz; dest->wz = src->wz; + dest->xw = src->xw; + dest->yw = src->yw; + dest->zw = src->zw; dest->ww = src->ww; } @@ -282,18 +281,18 @@ s32 SkinMatrix_Invert(MtxF* src, MtxF* dest) { * Produces a matrix which scales x,y,z components of vectors or x,y,z rows of matrices (when applied on LHS) */ void SkinMatrix_SetScale(MtxF* mf, f32 x, f32 y, f32 z) { - mf->xy = 0.0f; - mf->xz = 0.0f; - mf->xw = 0.0f; mf->yx = 0.0f; - mf->yz = 0.0f; - mf->yw = 0.0f; mf->zx = 0.0f; - mf->zy = 0.0f; - mf->zw = 0.0f; mf->wx = 0.0f; + mf->xy = 0.0f; + mf->zy = 0.0f; mf->wy = 0.0f; + mf->xz = 0.0f; + mf->yz = 0.0f; mf->wz = 0.0f; + mf->xw = 0.0f; + mf->yw = 0.0f; + mf->zw = 0.0f; mf->ww = 1.0f; mf->xx = x; mf->yy = y; @@ -307,16 +306,16 @@ void SkinMatrix_SetRotateRPY(MtxF* mf, s16 roll, s16 pitch, s16 yaw) { f32 cos2; f32 sin = Math_SinS(yaw); f32 cos = Math_CosS(yaw); - f32 yx; + f32 xy; f32 sin2; - f32 zx; + f32 xz; f32 yy; - f32 zy; + f32 yz; mf->yy = cos; - mf->yx = -sin; - mf->xw = mf->yw = mf->zw = 0; + mf->xy = -sin; mf->wx = mf->wy = mf->wz = 0; + mf->xw = mf->yw = mf->zw = 0; mf->ww = 1; if (pitch != 0) { @@ -324,19 +323,19 @@ void SkinMatrix_SetRotateRPY(MtxF* mf, s16 roll, s16 pitch, s16 yaw) { cos2 = Math_CosS(pitch); mf->xx = cos * cos2; - mf->zx = cos * sin2; + mf->xz = cos * sin2; - mf->xy = sin * cos2; - mf->zy = sin * sin2; - mf->xz = -sin2; + mf->yx = sin * cos2; + mf->yz = sin * sin2; + mf->zx = -sin2; mf->zz = cos2; } else { mf->xx = cos; if (1) {} if (1) {} - zx = sin; // required to match - mf->xy = sin; - mf->xz = mf->zx = mf->zy = 0; + xz = sin; // required to match + mf->yx = sin; + mf->zx = mf->xz = mf->yz = 0; mf->zz = 1; } @@ -344,22 +343,22 @@ void SkinMatrix_SetRotateRPY(MtxF* mf, s16 roll, s16 pitch, s16 yaw) { sin2 = Math_SinS(roll); cos2 = Math_CosS(roll); - yx = mf->yx; - zx = mf->zx; - mf->yx = (yx * cos2) + (zx * sin2); - mf->zx = (zx * cos2) - (yx * sin2); + xy = mf->xy; + xz = mf->xz; + mf->xy = (xy * cos2) + (xz * sin2); + mf->xz = (xz * cos2) - (xy * sin2); if (1) {} - zy = mf->zy; + yz = mf->yz; yy = mf->yy; - mf->yy = (yy * cos2) + (zy * sin2); - mf->zy = (zy * cos2) - (yy * sin2); + mf->yy = (yy * cos2) + (yz * sin2); + mf->yz = (yz * cos2) - (yy * sin2); if (cos2) {} - mf->yz = mf->zz * sin2; + mf->zy = mf->zz * sin2; mf->zz = mf->zz * cos2; } else { - mf->yz = 0; + mf->zy = 0; } } @@ -370,23 +369,23 @@ void SkinMatrix_SetRotateYRP(MtxF* mf, s16 yaw, s16 roll, s16 pitch) { f32 cos2; f32 sin; f32 cos; - f32 xz; + f32 zx; f32 sin2; - f32 yz; + f32 zy; f32 xx; - f32 yx; + f32 xy; sin = Math_SinS(roll); cos = Math_CosS(roll); mf->xx = cos; - mf->xz = -sin; - mf->zw = 0; - mf->yw = 0; - mf->xw = 0; + mf->zx = -sin; mf->wz = 0; mf->wy = 0; mf->wx = 0; + mf->zw = 0; + mf->yw = 0; + mf->xw = 0; mf->ww = 1; if (yaw != 0) { @@ -394,19 +393,19 @@ void SkinMatrix_SetRotateYRP(MtxF* mf, s16 yaw, s16 roll, s16 pitch) { cos2 = Math_CosS(yaw); mf->zz = cos * cos2; - mf->yz = cos * sin2; + mf->zy = cos * sin2; - mf->zx = sin * cos2; - mf->yx = sin * sin2; - mf->zy = -sin2; + mf->xz = sin * cos2; + mf->xy = sin * sin2; + mf->yz = -sin2; mf->yy = cos2; } else { mf->zz = cos; if (1) {} if (1) {} - yx = sin; // required to match - mf->zx = sin; - mf->yx = mf->yz = mf->zy = 0; + xy = sin; // required to match + mf->xz = sin; + mf->xy = mf->zy = mf->yz = 0; mf->yy = 1; } @@ -414,19 +413,19 @@ void SkinMatrix_SetRotateYRP(MtxF* mf, s16 yaw, s16 roll, s16 pitch) { sin2 = Math_SinS(pitch); cos2 = Math_CosS(pitch); xx = mf->xx; - yx = mf->yx; - mf->xx = (xx * cos2) + (yx * sin2); - mf->yx = yx * cos2 - (xx * sin2); + xy = mf->xy; + mf->xx = (xx * cos2) + (xy * sin2); + mf->xy = xy * cos2 - (xx * sin2); if (1) {} - yz = mf->yz; - xz = mf->xz; - mf->xz = (xz * cos2) + (yz * sin2); - mf->yz = (yz * cos2) - (xz * sin2); + zy = mf->zy; + zx = mf->zx; + mf->zx = (zx * cos2) + (zy * sin2); + mf->zy = (zy * cos2) - (zx * sin2); if (cos2) {} - mf->xy = mf->yy * sin2; + mf->yx = mf->yy * sin2; mf->yy = mf->yy * cos2; } else { - mf->xy = 0; + mf->yx = 0; } } @@ -434,22 +433,22 @@ void SkinMatrix_SetRotateYRP(MtxF* mf, s16 yaw, s16 roll, s16 pitch) { * Produces a matrix which translates a vector by amounts in the x, y and z directions */ void SkinMatrix_SetTranslate(MtxF* mf, f32 x, f32 y, f32 z) { - mf->xy = 0.0f; - mf->xz = 0.0f; - mf->xw = 0.0f; mf->yx = 0.0f; - mf->yz = 0.0f; - mf->yw = 0.0f; mf->zx = 0.0f; + mf->wx = 0.0f; + mf->xy = 0.0f; mf->zy = 0.0f; - mf->zw = 0.0f; + mf->wy = 0.0f; + mf->xz = 0.0f; + mf->yz = 0.0f; + mf->wz = 0.0f; mf->xx = 1.0f; mf->yy = 1.0f; mf->zz = 1.0f; mf->ww = 1.0f; - mf->wx = x; - mf->wy = y; - mf->wz = z; + mf->xw = x; + mf->yw = y; + mf->zw = z; } /** @@ -515,19 +514,19 @@ void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) { m1[0] = (temp >> 0x10); m1[16 + 0] = temp & 0xFFFF; - temp = src->xy * 0x10000; + temp = src->yx * 0x10000; m1[1] = (temp >> 0x10); m1[16 + 1] = temp & 0xFFFF; - temp = src->xz * 0x10000; + temp = src->zx * 0x10000; m1[2] = (temp >> 0x10); m1[16 + 2] = temp & 0xFFFF; - temp = src->xw * 0x10000; + temp = src->wx * 0x10000; m1[3] = (temp >> 0x10); m1[16 + 3] = temp & 0xFFFF; - temp = src->yx * 0x10000; + temp = src->xy * 0x10000; m1[4] = (temp >> 0x10); m1[16 + 4] = temp & 0xFFFF; @@ -535,19 +534,19 @@ void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) { m1[5] = (temp >> 0x10); m1[16 + 5] = temp & 0xFFFF; - temp = src->yz * 0x10000; + temp = src->zy * 0x10000; m1[6] = (temp >> 0x10); m1[16 + 6] = temp & 0xFFFF; - temp = src->yw * 0x10000; + temp = src->wy * 0x10000; m1[7] = (temp >> 0x10); m1[16 + 7] = temp & 0xFFFF; - temp = src->zx * 0x10000; + temp = src->xz * 0x10000; m1[8] = (temp >> 0x10); m1[16 + 8] = temp & 0xFFFF; - temp = src->zy * 0x10000; + temp = src->yz * 0x10000; m1[9] = (temp >> 0x10); m2[9] = temp & 0xFFFF; @@ -555,19 +554,19 @@ void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) { m1[10] = (temp >> 0x10); m2[10] = temp & 0xFFFF; - temp = src->zw * 0x10000; + temp = src->wz * 0x10000; m1[11] = (temp >> 0x10); m2[11] = temp & 0xFFFF; - temp = src->wx * 0x10000; + temp = src->xw * 0x10000; m1[12] = (temp >> 0x10); m2[12] = temp & 0xFFFF; - temp = src->wy * 0x10000; + temp = src->yw * 0x10000; m1[13] = (temp >> 0x10); m2[13] = temp & 0xFFFF; - temp = src->wz * 0x10000; + temp = src->zw * 0x10000; m1[14] = (temp >> 0x10); m2[14] = temp & 0xFFFF; @@ -577,12 +576,7 @@ void SkinMatrix_MtxFToMtx(MtxF* src, Mtx* dest) { } Mtx* SkinMatrix_MtxFToNewMtx(GraphicsContext* gfxCtx, MtxF* src) { - s32 pad; - Mtx* mtx; - - // TODO allocation should be a macro - mtx = (Mtx*)((int)gfxCtx->polyOpa.d - sizeof(Mtx)); - gfxCtx->polyOpa.d = (void*)mtx; + Mtx* mtx = GRAPH_ALLOC(gfxCtx, sizeof(Mtx)); if (mtx == NULL) { return NULL; @@ -617,21 +611,21 @@ void SkinMatrix_SetRotateAroundVec(MtxF* mf, s16 a, f32 x, f32 y, f32 z) { xz = x * z; mf->xx = (1.0f - xx) * cosA + xx; - mf->xy = (1.0f - cosA) * xy + z * sinA; - mf->xz = (1.0f - cosA) * xz - y * sinA; - mf->xw = 0.0f; + mf->yx = (1.0f - cosA) * xy + z * sinA; + mf->zx = (1.0f - cosA) * xz - y * sinA; + mf->wx = 0.0f; - mf->yx = (1.0f - cosA) * xy - z * sinA; + mf->xy = (1.0f - cosA) * xy - z * sinA; mf->yy = (1.0f - yy) * cosA + yy; - mf->yz = (1.0f - cosA) * yz + x * sinA; - mf->yw = 0.0f; + mf->zy = (1.0f - cosA) * yz + x * sinA; + mf->wy = 0.0f; - mf->zx = (1.0f - cosA) * xz + y * sinA; - mf->zy = (1.0f - cosA) * yz - x * sinA; + mf->xz = (1.0f - cosA) * xz + y * sinA; + mf->yz = (1.0f - cosA) * yz - x * sinA; mf->zz = (1.0f - zz) * cosA + zz; - mf->zw = 0.0f; + mf->wz = 0.0f; - mf->wx = mf->wy = mf->wz = 0.0f; + mf->xw = mf->yw = mf->zw = 0.0f; mf->ww = 1.0f; } @@ -647,27 +641,27 @@ void SkinMatrix_SetXRotation(MtxF* mf, s16 a) { cosA = 1.0f; } - mf->xy = 0.0f; - mf->xz = 0.0f; - mf->xw = 0.0f; - mf->yx = 0.0f; - mf->yw = 0.0f; - mf->zx = 0.0f; - mf->zw = 0.0f; - mf->wx = 0.0f; + + mf->xy = 0.0f; mf->wy = 0.0f; + + mf->xz = 0.0f; mf->wz = 0.0f; + mf->xw = 0.0f; + mf->yw = 0.0f; + mf->zw = 0.0f; + mf->xx = 1.0f; mf->ww = 1.0f; mf->yy = cosA; mf->zz = cosA; - mf->yz = sinA; - mf->zy = -sinA; + mf->zy = sinA; + mf->yz = -sinA; } void SkinMatrix_MulXRotation(MtxF* mf, s16 a) { @@ -680,25 +674,25 @@ void SkinMatrix_MulXRotation(MtxF* mf, s16 a) { sinA = Math_SinS(a); cosA = Math_CosS(a); - ry = mf->yx; - rz = mf->zx; - mf->yx = ry * cosA + rz * sinA; - mf->zx = rz * cosA - ry * sinA; + ry = mf->xy; + rz = mf->xz; + mf->xy = ry * cosA + rz * sinA; + mf->xz = rz * cosA - ry * sinA; ry = mf->yy; - rz = mf->zy; + rz = mf->yz; mf->yy = ry * cosA + rz * sinA; - mf->zy = rz * cosA - ry * sinA; + mf->yz = rz * cosA - ry * sinA; - ry = mf->yz; + ry = mf->zy; rz = mf->zz; - mf->yz = ry * cosA + rz * sinA; + mf->zy = ry * cosA + rz * sinA; mf->zz = rz * cosA - ry * sinA; - ry = mf->yw; - rz = mf->zw; - mf->yw = ry * cosA + rz * sinA; - mf->zw = rz * cosA - ry * sinA; + ry = mf->wy; + rz = mf->wz; + mf->wy = ry * cosA + rz * sinA; + mf->wz = rz * cosA - ry * sinA; } } @@ -714,27 +708,27 @@ void SkinMatrix_SetYRotation(MtxF* mf, s16 a) { cosA = 1.0f; } - mf->xy = 0.0f; - mf->xw = 0.0f; - mf->yx = 0.0f; - mf->yz = 0.0f; - mf->yw = 0.0f; - - mf->zy = 0.0f; - mf->zw = 0.0f; - mf->wx = 0.0f; + + mf->xy = 0.0f; + mf->zy = 0.0f; mf->wy = 0.0f; + + mf->yz = 0.0f; mf->wz = 0.0f; + mf->xw = 0.0f; + mf->yw = 0.0f; + mf->zw = 0.0f; + mf->yy = 1.0f; mf->ww = 1.0f; mf->xx = cosA; mf->zz = cosA; - mf->xz = -sinA; - mf->zx = sinA; + mf->zx = -sinA; + mf->xz = sinA; } void SkinMatrix_MulYRotation(MtxF* mf, s16 a) { @@ -748,24 +742,24 @@ void SkinMatrix_MulYRotation(MtxF* mf, s16 a) { cosA = Math_CosS(a); rx = mf->xx; - rz = mf->zx; + rz = mf->xz; mf->xx = rx * cosA - rz * sinA; - mf->zx = rx * sinA + rz * cosA; + mf->xz = rx * sinA + rz * cosA; - rx = mf->xy; - rz = mf->zy; - mf->xy = rx * cosA - rz * sinA; - mf->zy = rx * sinA + rz * cosA; + rx = mf->yx; + rz = mf->yz; + mf->yx = rx * cosA - rz * sinA; + mf->yz = rx * sinA + rz * cosA; - rx = mf->xz; + rx = mf->zx; rz = mf->zz; - mf->xz = rx * cosA - rz * sinA; + mf->zx = rx * cosA - rz * sinA; mf->zz = rx * sinA + rz * cosA; - rx = mf->xw; - rz = mf->zw; - mf->xw = rx * cosA - rz * sinA; - mf->zw = rx * sinA + rz * cosA; + rx = mf->wx; + rz = mf->wz; + mf->wx = rx * cosA - rz * sinA; + mf->wz = rx * sinA + rz * cosA; } } @@ -781,25 +775,25 @@ void SkinMatrix_SetZRotation(MtxF* mf, s16 a) { cosA = 1.0f; } - mf->xz = 0.0f; - mf->xw = 0.0f; - - mf->yz = 0.0f; - mf->yw = 0.0f; - mf->zx = 0.0f; - mf->zy = 0.0f; - mf->zw = 0.0f; - mf->wx = 0.0f; + + mf->zy = 0.0f; mf->wy = 0.0f; + + mf->xz = 0.0f; + mf->yz = 0.0f; mf->wz = 0.0f; + mf->xw = 0.0f; + mf->yw = 0.0f; + mf->zw = 0.0f; + mf->zz = 1.0f; mf->ww = 1.0f; mf->xx = cosA; mf->yy = cosA; - mf->xy = sinA; - mf->yx = -sinA; + mf->yx = sinA; + mf->xy = -sinA; } diff --git a/src/code/z_snap.c b/src/code/z_snap.c index 120861ff5..f85f33f0a 100644 --- a/src/code/z_snap.c +++ b/src/code/z_snap.c @@ -12,15 +12,15 @@ s32 func_8013A240(GlobalContext* globalCtx) { s32 seen; s32 count = 0; - gSaveContext.roomInf[123][3] = 0; - gSaveContext.roomInf[123][4] = 0; + gSaveContext.save.pictoFlags0 = 0; + gSaveContext.save.pictoFlags1 = 0; if (globalCtx->sceneNum == SCENE_20SICHITAI) { func_8013A41C(1); } for (; type < 12; type++) { - for (actor = globalCtx->actorCtx.actorList[type].first; actor != NULL; actor = actor->next) { + for (actor = globalCtx->actorCtx.actorLists[type].first; actor != NULL; actor = actor->next) { seen = 0; switch (globalCtx->sceneNum) { @@ -76,19 +76,19 @@ s32 func_8013A240(GlobalContext* globalCtx) { void func_8013A41C(s32 flag) { if (flag < 0x20) { - gSaveContext.roomInf[123][3] |= (1 << flag); + gSaveContext.save.pictoFlags0 |= (1 << flag); } else { flag &= 0x1F; - gSaveContext.roomInf[123][4] |= (1 << flag); + gSaveContext.save.pictoFlags1 |= (1 << flag); } } void func_8013A46C(s32 flag) { if (flag < 0x20) { - gSaveContext.roomInf[123][3] &= ~(1 << flag); + gSaveContext.save.pictoFlags0 &= ~(1 << flag); } else { flag &= 0x1F; - gSaveContext.roomInf[123][4] &= ~(1 << flag); + gSaveContext.save.pictoFlags1 &= ~(1 << flag); } } @@ -96,10 +96,10 @@ u32 func_8013A4C4(s32 flag) { SaveContext* saveCtx = &gSaveContext; if (flag < 0x20) { - return saveCtx->roomInf[123][3] & (1 << flag); + return saveCtx->save.pictoFlags0 & (1 << flag); } else { flag &= 0x1F; - return saveCtx->roomInf[123][4] & (1 << flag); + return saveCtx->save.pictoFlags1 & (1 << flag); } } @@ -113,45 +113,44 @@ s32 func_8013A530(GlobalContext* globalCtx, Actor* actor, s32 flag, Vec3f* pos, s16 x; s16 y; f32 distance; - CollisionPoly* unk1; - Camera* camera; + CollisionPoly* poly; + Camera* camera = GET_ACTIVE_CAM(globalCtx); Actor* actors[2]; s32 ret = 0; - u32 unk2; - - camera = GET_ACTIVE_CAM(globalCtx); + s32 bgId; distance = OLib_Vec3fDist(pos, &camera->eye); if ((distance < distanceMin) || (distanceMax < distance)) { - func_8013A41C(0x3f); - ret = 0x3f; + func_8013A41C(0x3F); + ret = 0x3F; } - x = func_8013A504(func_800DFCB4(camera) + rot->x); - y = func_8013A504(func_800DFCDC(camera) - (s16)(rot->y - 0x7FFF)); + x = func_8013A504(Camera_GetCamDirPitch(camera) + rot->x); + y = func_8013A504(Camera_GetCamDirYaw(camera) - BINANG_SUB(rot->y, 0x7FFF)); if ((0 < angleError) && ((angleError < x) || (angleError < y))) { - func_8013A41C(0x3e); - ret |= 0x3e; + func_8013A41C(0x3E); + ret |= 0x3E; } - func_800B4EDC(globalCtx, pos, &screenSpace, &distance); + Actor_GetProjectedPos(globalCtx, pos, &screenSpace, &distance); x = (s16)(screenSpace.x * distance * 160.0f + 160.0f) - 85; y = (s16)(screenSpace.y * distance * -120.0f + 120.0f) - 67; - if ((x < 0) || (0x96 < x) || (y < 0) || (0x69 < y)) { - func_8013A41C(0x3d); - ret |= 0x3d; + if ((x < 0) || (150 < x) || (y < 0) || (105 < y)) { + func_8013A41C(0x3D); + ret |= 0x3D; } - if (func_800C576C(&globalCtx->colCtx, pos, &camera->eye, &screenSpace, &unk1, 1, 1, 1, 1, &unk2) != 0) { - func_8013A41C(0x3c); - ret |= 0x3c; + if (BgCheck_ProjectileLineTest(&globalCtx->colCtx, pos, &camera->eye, &screenSpace, &poly, true, true, true, true, + &bgId)) { + func_8013A41C(0x3C); + ret |= 0x3C; } actors[0] = actor; actors[1] = &GET_PLAYER(globalCtx)->actor; - if (CollisionCheck_LineOCCheck(globalCtx, &globalCtx->colChkCtx, pos, &camera->eye, actors, 2) != 0) { - func_8013A41C(0x3b); - ret |= 0x3b; + if (CollisionCheck_LineOCCheck(globalCtx, &globalCtx->colChkCtx, pos, &camera->eye, actors, 2)) { + func_8013A41C(0x3B); + ret |= 0x3B; } if (ret == 0) { diff --git a/src/code/z_sound_source.c b/src/code/z_sound_source.c new file mode 100644 index 000000000..ba7036a4c --- /dev/null +++ b/src/code/z_sound_source.c @@ -0,0 +1,75 @@ +#include "global.h" + +void SoundSource_InitAll(GlobalContext* globalCtx) { + SoundSource* sources = &globalCtx->soundSources[0]; + s32 i; + + // clang-format off + for (i = 0; i < ARRAY_COUNT(globalCtx->soundSources); i++) { sources[i].countdown = 0; } + // clang-format on +} + +void SoundSource_UpdateAll(GlobalContext* globalCtx) { + SoundSource* source = &globalCtx->soundSources[0]; + s32 i; + + for (i = 0; i < ARRAY_COUNT(globalCtx->soundSources); i++) { + if (source->countdown != 0) { + if (DECR(source->countdown) == 0) { + Audio_StopSfxByPos(&source->projectedPos); + } else { + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &source->worldPos, &source->projectedPos); + if (source->playSfxEachFrame) { + Audio_PlaySfxAtPos(&source->projectedPos, source->sfxId); + } + } + } + + source++; + } +} + +void SoundSource_Add(GlobalContext* globalCtx, Vec3f* worldPos, u32 duration, u16 sfxId, u32 playSfxEachFrame) { + s32 countdown; + SoundSource* source; + s32 smallestCountdown = 0xFFFF; + SoundSource* backupSource = NULL; + s32 i; + + source = &globalCtx->soundSources[0]; + for (i = 0; i < ARRAY_COUNT(globalCtx->soundSources); i++) { + if (source->countdown == 0) { + break; + } + + // Store the sound source with the smallest remaining countdown + countdown = source->countdown; + if (countdown < smallestCountdown) { + smallestCountdown = countdown; + backupSource = source; + } + source++; + } + + // If no sound source is available, replace the sound source with the smallest remaining countdown + if (i >= ARRAY_COUNT(globalCtx->soundSources)) { + source = backupSource; + Audio_StopSfxByPos(&source->projectedPos); + } + + source->worldPos = *worldPos; + source->countdown = duration; + source->playSfxEachFrame = playSfxEachFrame; + source->sfxId = sfxId; + + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &source->worldPos, &source->projectedPos); + Audio_PlaySfxAtPos(&source->projectedPos, sfxId); +} + +void SoundSource_PlaySfxAtFixedWorldPos(GlobalContext* globalCtx, Vec3f* worldPos, u32 duration, u16 sfxId) { + SoundSource_Add(globalCtx, worldPos, duration, sfxId, false); +} + +void SoundSource_PlaySfxEachFrameAtFixedWorldPos(GlobalContext* globalCtx, Vec3f* worldPos, u32 duration, u16 sfxId) { + SoundSource_Add(globalCtx, worldPos, duration, sfxId, true); +} diff --git a/src/code/z_sram_NES.c b/src/code/z_sram_NES.c index 5b5b2f5f0..90b60809e 100644 --- a/src/code/z_sram_NES.c +++ b/src/code/z_sram_NES.c @@ -1,67 +1,1677 @@ #include "global.h" +#include "overlays/gamestates/ovl_file_choose/z_file_choose.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80143A10.s") +void func_80146EBC(SramContext* sramCtx, s32 curPage, s32 numPages); +void func_80147314(SramContext* sramCtx, s32 fileNum); +void func_80147414(SramContext* sramCtx, s32 fileNum, s32 arg2); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80143A54.s") +#define CHECK_NEWF(newf) \ + ((newf)[0] != 'Z' || (newf)[1] != 'E' || (newf)[2] != 'L' || (newf)[3] != 'D' || (newf)[4] != 'A' || \ + (newf)[5] != '3') -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80143AC4.s") +// default scene flags (?) +// indices of subarray: +// - 0: switch0 +// - 1: switch1 +// - 2: chest +// - 3: collectible +u32 D_801C5FC0[SCENE_MAX][4] = { + { 0xC00, 0, 0, 0x40000000 }, // SCENE_20SICHITAI2 + { 0, 0, 0, 0 }, // SCENE_UNSET_1 + { 0, 0, 0, 0 }, // SCENE_UNSET_2 + { 0, 0, 0, 0 }, // SCENE_UNSET_3 + { 0, 0, 0, 0 }, // SCENE_UNSET_4 + { 0, 0, 0, 0 }, // SCENE_UNSET_5 + { 0, 0, 0, 0 }, // SCENE_UNSET_6 + { 0, 0, 0, 0xC04 }, // SCENE_KAKUSIANA + { 0, 0, 0, 0 }, // SCENE_SPOT00 + { 0, 0, 0, 0 }, // SCENE_UNSET_9 + { 0, 0, 0, 0 }, // SCENE_WITCH_SHOP + { 0, 0, 0, 0x80000000 }, // SCENE_LAST_BS + { 0, 0, 0, 0x80000000 }, // SCENE_HAKASHITA + { 0, 0, 0, 0 }, // SCENE_AYASHIISHOP + { 0, 0, 0, 0 }, // SCENE_UNSET_E + { 0, 0, 0, 0 }, // SCENE_UNSET_F + { 0, 0, 0, 0 }, // SCENE_OMOYA + { 0, 0, 0, 0 }, // SCENE_BOWLING + { 0, 0, 0, 0 }, // SCENE_SONCHONOIE + { 0x100000, 0, 0, 0x40000002 }, // SCENE_IKANA + { 0, 0, 0, 0 }, // SCENE_KAIZOKU + { 0, 0, 0, 0 }, // SCENE_MILK_BAR + { 0x4000000, 0, 0, 0 }, // SCENE_INISIE_N + { 2, 0, 0, 0 }, // SCENE_TAKARAYA + { 0x4000000, 0, 0, 0 }, // SCENE_INISIE_R + { 0, 0, 0, 0 }, // SCENE_OKUJOU + { 0xF, 0, 0, 0 }, // SCENE_OPENINGDAN + { 0x70B000, 0, 0, 0 }, // SCENE_MITURIN + { 0, 0, 0, 0 }, // SCENE_13HUBUKINOMITI + { 0, 0x80000000, 0, 0x400 }, // SCENE_CASTLE + { 0, 0, 0, 0 }, // SCENE_DEKUTES + { 0, 0, 0, 0x80000000 }, // SCENE_MITURIN_BS + { 0, 0, 0, 0 }, // SCENE_SYATEKI_MIZU + { 0x1A00020, 0, 0, 0 }, // SCENE_HAKUGIN + { 0x400, 0, 0, 0 }, // SCENE_ROMANYMAE + { 0, 0, 0, 0x1000 }, // SCENE_PIRATE + { 0, 0, 0, 0 }, // SCENE_SYATEKI_MORI + { 0, 0, 0, 2 }, // SCENE_SINKAI + { 0x400, 0, 0, 0 }, // SCENE_YOUSEI_IZUMI + { 0, 0, 0, 0 }, // SCENE_KINSTA1 + { 0, 0, 0, 0x80000000 }, // SCENE_KINDAN2 + { 0, 0, 0, 0 }, // SCENE_TENMON_DAI + { 0, 0, 0, 2 }, // SCENE_LAST_DEKU + { 0, 0, 0, 0x40000000 }, // SCENE_22DEKUCITY + { 0, 0, 0, 0 }, // SCENE_KAJIYA + { 0x10, 0, 0, 0 }, // SCENE_00KEIKOKU + { 3, 0, 0, 0 }, // SCENE_POSTHOUSE + { 0, 0, 0, 0 }, // SCENE_LABO + { 0, 0, 0, 0x80000000 }, // SCENE_DANPEI2TEST + { 0, 0, 0, 0 }, // SCENE_UNSET_31 + { 0, 0, 0, 0 }, // SCENE_16GORON_HOUSE + { 0, 0, 0, 0 }, // SCENE_33ZORACITY + { 0, 0, 0, 0 }, // SCENE_8ITEMSHOP + { 0, 0, 0, 0 }, // SCENE_F01 + { 0, 0, 0, 0x80000000 }, // SCENE_INISIE_BS + { 0x100400, 0, 0, 0x22 }, // SCENE_30GYOSON + { 0x400, 0, 0, 0x80 }, // SCENE_31MISAKI + { 0, 0, 0, 0 }, // SCENE_TAKARAKUJI + { 0, 0, 0, 0 }, // SCENE_UNSET_3A + { 0x400, 0, 0, 0 }, // SCENE_TORIDE + { 0, 0, 0, 0 }, // SCENE_FISHERMAN + { 0, 0, 0, 0 }, // SCENE_GORONSHOP + { 0, 0, 0, 0 }, // SCENE_DEKU_KING + { 0, 0, 0, 2 }, // SCENE_LAST_GORON + { 0, 0, 0, 0x80000002 }, // SCENE_24KEMONOMITI + { 0, 0, 0, 0 }, // SCENE_F01_B + { 0, 0, 0, 0 }, // SCENE_F01C + { 0, 0, 0, 0 }, // SCENE_BOTI + { 0, 0, 0, 0x80000000 }, // SCENE_HAKUGIN_BS + { 0xC00, 0, 0, 0x40000000 }, // SCENE_20SICHITAI + { 0x102, 0, 0, 0x400 }, // SCENE_21MITURINMAE + { 0, 0, 0, 2 }, // SCENE_LAST_ZORA + { 0, 0, 0, 0x40000000 }, // SCENE_11GORONNOSATO2 + { 0x70, 0, 0, 0 }, // SCENE_SEA + { 0, 0, 0, 0 }, // SCENE_35TAKI + { 0, 0, 0, 0 }, // SCENE_REDEAD + { 0, 0, 0, 0x40000000 }, // SCENE_BANDROOM + { 0, 0, 0, 0x40000000 }, // SCENE_11GORONNOSATO + { 0, 0, 0, 0 }, // SCENE_GORON_HAKA + { 0, 0, 0, 0 }, // SCENE_SECOM + { 0x100000, 0, 0, 0x80000000 }, // SCENE_10YUKIYAMANOMURA + { 0, 0, 0, 0 }, // SCENE_TOUGITES + { 0, 0, 0, 0 }, // SCENE_DANPEI + { 0, 0, 0, 0 }, // SCENE_IKANAMAE + { 0, 0, 0, 0 }, // SCENE_DOUJOU + { 0, 0, 0, 0 }, // SCENE_MUSICHOUSE + { 0, 0, 0, 0 }, // SCENE_IKNINSIDE + { 0, 0, 0, 0 }, // SCENE_MAP_SHOP + { 0x400, 0, 0, 0 }, // SCENE_F40 + { 0x400, 0, 0, 0 }, // SCENE_F41 + { 0x100000, 0, 0, 0x80000000 }, // SCENE_10YUKIYAMANOMURA2 + { 0, 0, 0, 0x100 }, // SCENE_14YUKIDAMANOMITI + { 0x400, 0, 0, 0 }, // SCENE_12HAKUGINMAE + { 0, 0, 0, 0x80 }, // SCENE_17SETUGEN + { 0, 0, 0, 0x80 }, // SCENE_17SETUGEN2 + { 0, 0, 0, 0x80000000 }, // SCENE_SEA_BS + { 0, 0, 0, 0x400 }, // SCENE_RANDOM + { 0, 0, 0, 0 }, // SCENE_YADOYA + { 0, 0, 0, 0 }, // SCENE_KONPEKI_ENT + { 1, 0, 0, 0 }, // SCENE_INSIDETOWER + { 0, 0, 0, 0 }, // SCENE_26SARUNOMORI + { 0, 0, 0, 0 }, // SCENE_LOST_WOODS + { 0, 0, 0, 2 }, // SCENE_LAST_LINK + { 0, 0, 0, 0 }, // SCENE_SOUGEN + { 0, 0, 0, 0 }, // SCENE_BOMYA + { 0, 0, 0, 0 }, // SCENE_KYOJINNOMA + { 0, 0, 0, 0 }, // SCENE_KOEPONARACE + { 0, 0, 0, 0 }, // SCENE_GORONRACE + { 1, 0, 0, 0 }, // SCENE_TOWN + { 0, 0, 0, 0 }, // SCENE_ICHIBA + { 0, 0, 0, 0x400 }, // SCENE_BACKTOWN + { 0x100000, 0, 0, 0x400 }, // SCENE_CLOCKTOWER + { 0, 0, 1, 0 }, // SCENE_ALLEY +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80143B0C.s") +// Related to weekEventReg +u16 D_801C66D0[ARRAY_COUNT(gSaveContext.save.weekEventReg)] = { + 0xFFFC, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0, 0xC000, 0xC00, 0, 0xC0, 0, 0x300, + 0x3000, 0xC000, 0xC00, 0, 0, 0, 0, 0, 0, 0xC00C, 0xC00C, 0xC008, 3, + 0x3000, 0, 0, 0, 0xFF00, 0xC3F, 0x3F, 0, 0, 0xCFFF, 0, 0, 0xC00, + 0xC00, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3C, 0x20, + 0, 0x300C, 0x3000, 0, 0xC, 0xC0, 0, 0xFF0, 0x300, 0, 0, 0xC00, 0, + 0, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xC0, 0, 0xC000, 0, 3, + 0, 0xC000, 0, 0xC0, 0x300, 0, 0, 0, 0xC000, 0xFFF0, 0, 0, 0x300, + 0, 0xC000, 0xF0, 0, 0, 0, 0, 0, 0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_IncrementDay.s") +// used in other files +s32 D_801C6798[] = { + 0x00000020, 0x00001470, 0x000028C0, 0x00003D10, 0x00005160, 0x000065B0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_CalcChecksum.s") +u8 D_801C67B0[24] = { + ITEM_NONE, ITEM_BOW, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_BOMB, ITEM_BOMBCHU, + ITEM_STICK, ITEM_NUT, ITEM_MAGIC_BEANS, ITEM_NONE, ITEM_POWDER_KEG, ITEM_PICTO_BOX, ITEM_NONE, ITEM_NONE, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144628.s") +s32 D_801C67C8[] = { 0, 0x40, 0x80, 0xC0, 0x100, 0x180, 0x200, 0x280 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_GenerateRandomSaveFields.s") +s32 D_801C67E8[] = { 0x300, 0x380 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144890.s") +s32 D_801C67F0[] = { 0x40, 0x40, 0x40, 0x40, 0x80, 0x80, 0x80, 0x80 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_InitDebugSave.s") +s32 D_801C6810[] = { 1, 1 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144A94.s") +s32 D_801C6818[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80144E78.s") +s32 D_801C6838[] = { 1, 1 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_8014546C.s") +s32 D_801C6840[] = { 0x100, 0x180, 0x200, 0x280 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80145698.s") +s32 D_801C6850[] = { 0x80, 0x80, 0x80, 0x80, 0x300, 0x380, 1, 1 }; +s32 D_801C6870[] = { + sizeof(Save), + sizeof(Save), + sizeof(Save), + sizeof(Save), + offsetof(SaveContext, fileNum), + offsetof(SaveContext, fileNum), + offsetof(SaveContext, fileNum), + offsetof(SaveContext, fileNum), +}; + +u8 D_801C6890[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; + +u16 D_801F6AF0; +u8 D_801F6AF2; + +void Sram_ActivateOwl(u8 owlId) { + gSaveContext.save.playerData.owlActivationFlags = + ((void)0, gSaveContext.save.playerData.owlActivationFlags) | (u16)gBitFlags[owlId]; + + if (gSaveContext.save.playerData.unk_20 == 0xFF) { + gSaveContext.save.playerData.unk_20 = owlId; + } +} + +void Sram_ClearHighscores(void) { + gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF) | 0x130000; + gSaveContext.save.unk_EE8 = (gSaveContext.save.unk_EE8 & 0xFFFF0000) | 0xA; + gSaveContext.save.horseBackBalloonHighScore = 6000; // 60 seconds + gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF0000) | 0x27; + gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF) | 0xA0000; + + gSaveContext.save.dekuPlaygroundHighScores[0] = 7500; // 75 seconds + gSaveContext.save.dekuPlaygroundHighScores[1] = 7500; // 75 seconds + gSaveContext.save.dekuPlaygroundHighScores[2] = 7600; // 76 seconds +} + +/** + * Clears specific weekEventReg flags. Used by the "Dawn of the First Day" message + */ +void Sram_ClearFlagsAtDawnOfTheFirstDay(void) { + // Unconfirmed: "Link the Goron Claims His Reservation: 4:30 PM" + gSaveContext.save.weekEventReg[55] &= (u8)~2; + // Unconfirmed: "Postman fleeing town" + gSaveContext.save.weekEventReg[90] &= (u8)~1; + // Unconfirmed: "Postman is about to flee" + gSaveContext.save.weekEventReg[89] &= (u8)~0x40; + // Unconfirmed: "Postman has delivered priority mail" + gSaveContext.save.weekEventReg[89] &= (u8)~8; + // Unconfirmed: "Postman showing priority mail to Madame" + gSaveContext.save.weekEventReg[85] &= (u8)~0x80; +} + +/** + * Used by Song of Time (when clicking "Yes") and (indirectly) by the "Dawn of the New Day" cutscene + */ +void Sram_SaveEndOfCycle(GlobalContext* globalCtx) { + s16 sceneNum; + s32 j; + s32 i; + u8 temp; + u8 temp2; + + gSaveContext.save.daySpeed = 0; + gSaveContext.save.daysElapsed = 0; + gSaveContext.save.day = 0; + gSaveContext.save.time = CLOCK_TIME(6, 0) - 1; + + gSaveContext.save.playerData.deaths++; + if (gSaveContext.save.playerData.deaths > 999) { + gSaveContext.save.playerData.deaths = 999; + } + + sceneNum = Play_GetOriginalSceneNumber(globalCtx->sceneNum); + Play_SaveCycleSceneFlags(&globalCtx->state); + + globalCtx->actorCtx.flags.chest &= D_801C5FC0[sceneNum][2]; + globalCtx->actorCtx.flags.switches[0] &= D_801C5FC0[sceneNum][0]; + globalCtx->actorCtx.flags.switches[1] &= D_801C5FC0[sceneNum][1]; + globalCtx->actorCtx.flags.collectible[0] &= D_801C5FC0[sceneNum][3]; + globalCtx->actorCtx.flags.clearedRoom = 0; + + for (i = 0; i < SCENE_MAX; i++) { + gSaveContext.cycleSceneFlags[i].switch0 = ((void)0, gSaveContext.cycleSceneFlags[i].switch0) & D_801C5FC0[i][0]; + gSaveContext.cycleSceneFlags[i].switch1 = ((void)0, gSaveContext.cycleSceneFlags[i].switch1) & D_801C5FC0[i][1]; + gSaveContext.cycleSceneFlags[i].chest = ((void)0, gSaveContext.cycleSceneFlags[i].chest) & D_801C5FC0[i][2]; + gSaveContext.cycleSceneFlags[i].collectible = + ((void)0, gSaveContext.cycleSceneFlags[i].collectible) & D_801C5FC0[i][3]; + gSaveContext.cycleSceneFlags[i].clearedRoom = 0; + gSaveContext.save.permanentSceneFlags[i].unk_14 = 0; + gSaveContext.save.permanentSceneFlags[i].unk_18 = 0; + } + + for (; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.cycleSceneFlags[i].chest = 0; + gSaveContext.cycleSceneFlags[i].switch0 = 0; + gSaveContext.cycleSceneFlags[i].switch1 = 0; + gSaveContext.cycleSceneFlags[i].clearedRoom = 0; + gSaveContext.cycleSceneFlags[i].collectible = 0; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.maskMaskBit); i++) { + gSaveContext.maskMaskBit[i] = 0; + } + + if (gSaveContext.save.weekEventReg[84] & 0x20) { + func_801149A0(ITEM_MASK_FIERCE_DEITY, SLOT(ITEM_MASK_FIERCE_DEITY)); + } + + for (i = 0; i < ARRAY_COUNT(D_801C66D0); i++) { + u16 phi_v1_3 = D_801C66D0[i]; + + for (j = 0; j < ARRAY_COUNT(D_801C6890); j++) { + if ((phi_v1_3 & 3) == 0) { + gSaveContext.save.weekEventReg[i] = + ((void)0, gSaveContext.save.weekEventReg[i]) & (0xFF ^ D_801C6890[j]); + } + phi_v1_3 >>= 2; + } + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { + gSaveContext.eventInf[i] = 0; + } + + gSaveContext.eventInf[7] &= (u8)~1; + gSaveContext.eventInf[7] &= (u8)~2; + gSaveContext.eventInf[7] &= (u8)~4; + gSaveContext.eventInf[7] &= (u8)~8; + gSaveContext.eventInf[7] &= (u8)~0x10; + + if (gSaveContext.save.playerData.rupees != 0) { + gSaveContext.eventInf[7] |= 1; + } + + if (INV_CONTENT(ITEM_BOMB) == ITEM_BOMB) { + temp2 = INV_CONTENT(ITEM_BOMB); + if (AMMO(temp2) != 0) { + gSaveContext.eventInf[7] |= 2; + } + } + if (INV_CONTENT(ITEM_NUT) == ITEM_NUT) { + temp2 = INV_CONTENT(ITEM_NUT); + if (AMMO(temp2) != 0) { + gSaveContext.eventInf[7] |= 4; + } + } + if (INV_CONTENT(ITEM_STICK) == ITEM_STICK) { + temp2 = INV_CONTENT(ITEM_STICK); + if (AMMO(temp2) != 0) { + gSaveContext.eventInf[7] |= 8; + } + } + if (INV_CONTENT(ITEM_BOW) == ITEM_BOW) { + temp2 = INV_CONTENT(ITEM_BOW); + if (AMMO(temp2) != 0) { + gSaveContext.eventInf[7] |= 0x10; + } + } + + for (i = 0; i < ARRAY_COUNT(D_801C67B0); i++) { + if (D_801C67B0[i] != ITEM_NONE) { + if ((gSaveContext.save.inventory.items[i] != ITEM_NONE) && (i != SLOT_PICTO_BOX)) { + temp2 = gSaveContext.save.inventory.items[i]; + AMMO(temp2) = 0; + } + } + } + + for (i = SLOT_BOTTLE_1; i <= SLOT_BOTTLE_6; i++) { + // Check for all bottled items + if (gSaveContext.save.inventory.items[i] >= ITEM_POTION_RED) { + if (gSaveContext.save.inventory.items[i] <= ITEM_OBABA_DRINK) { + for (j = 1; j < 4; j++) { + if (GET_CUR_FORM_BTN_ITEM(j) == gSaveContext.save.inventory.items[i]) { + SET_CUR_FORM_BTN_ITEM(j, ITEM_BOTTLE); + func_80112B40(globalCtx, j); + } + } + gSaveContext.save.inventory.items[i] = ITEM_BOTTLE; + } + } + } + + REMOVE_QUEST_ITEM(QUEST_UNK_19); + + if (gSaveContext.save.playerData.health < 0x30) { + gSaveContext.save.playerData.health = 0x30; + } + + if (GET_CUR_EQUIP_VALUE(EQUIP_SWORD) < 3) { + SET_EQUIP_VALUE(EQUIP_SWORD, 1); + + if (CUR_FORM == 0) { + if ((STOLEN_ITEM_1 >= ITEM_SWORD_GILDED) || (STOLEN_ITEM_2 >= ITEM_SWORD_GILDED)) { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_SWORD_GILDED; + SET_EQUIP_VALUE(EQUIP_SWORD, 3); + } else { + BUTTON_ITEM_EQUIP(CUR_FORM, EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI; + } + } else { + if ((STOLEN_ITEM_1 >= ITEM_SWORD_GILDED) || (STOLEN_ITEM_2 >= ITEM_SWORD_GILDED)) { + BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_GILDED; + SET_EQUIP_VALUE(EQUIP_SWORD, 3); + } else { + BUTTON_ITEM_EQUIP(0, EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI; + } + } + } + + if ((STOLEN_ITEM_1 == ITEM_SWORD_GREAT_FAIRY) || (STOLEN_ITEM_2 == ITEM_SWORD_GREAT_FAIRY)) { + INV_CONTENT(ITEM_SWORD_GREAT_FAIRY) = ITEM_SWORD_GREAT_FAIRY; + } + + if (STOLEN_ITEM_1 == ITEM_BOTTLE) { + temp = SLOT(ITEM_BOTTLE); + for (i = 0; i < 6; i++) { + if (gSaveContext.save.inventory.items[temp + i] == ITEM_NONE) { + gSaveContext.save.inventory.items[temp + i] = ITEM_BOTTLE; + break; + } + } + } + + if (STOLEN_ITEM_2 == ITEM_BOTTLE) { + temp = SLOT(ITEM_BOTTLE); + for (i = 0; i < 6; i++) { + if (gSaveContext.save.inventory.items[temp + i] == ITEM_NONE) { + gSaveContext.save.inventory.items[temp + i] = ITEM_BOTTLE; + break; + } + } + } + + SET_STOLEN_ITEM_1(STOLEN_ITEM_NONE); + SET_STOLEN_ITEM_2(STOLEN_ITEM_NONE); + + // ?? + func_801149A0(ITEM_OCARINA_FAIRY, SLOT_TRADE_DEED); + func_801149A0(ITEM_SLINGSHOT, SLOT_TRADE_KEY_MAMA); + func_801149A0(ITEM_LONGSHOT, SLOT_TRADE_COUPLE); + + for (j = 1; j < 4; j++) { + if (GET_CUR_FORM_BTN_ITEM(j) >= ITEM_MOON_TEAR && GET_CUR_FORM_BTN_ITEM(j) <= ITEM_PENDANT_MEMORIES) { + SET_CUR_FORM_BTN_ITEM(j, ITEM_NONE); + func_80112B40(globalCtx, j); + } + } + + gSaveContext.save.skullTokenCount &= ~0xFFFF0000; + gSaveContext.save.skullTokenCount &= ~0x0000FFFF; + gSaveContext.save.unk_EC4 = 0; + + gSaveContext.save.unk_E88[0] = 0; + gSaveContext.save.unk_E88[1] = 0; + gSaveContext.save.unk_E88[2] = 0; + gSaveContext.save.unk_E88[3] = 0; + gSaveContext.save.unk_E88[4] = 0; + gSaveContext.save.unk_E88[5] = 0; + gSaveContext.save.unk_E88[6] = 0; + + Sram_ClearHighscores(); + + for (i = 0; i < 8; i++) { + gSaveContext.save.inventory.dungeonItems[i] &= (u8)~1; + gSaveContext.save.inventory.dungeonKeys[i] = 0; + gSaveContext.save.inventory.strayFairies[i] = 0; + } + + gSaveContext.save.playerData.rupees = 0; + gSaveContext.save.unk_F65 = 0; + gSaveContext.powderKegTimer = 0; + gSaveContext.unk_1014 = 0; + gSaveContext.jinxTimer = 0; + gSaveContext.rupeeAccumulator = 0; + + func_800F3B2C(globalCtx); +} + +void Sram_IncrementDay(void) { + if (CURRENT_DAY <= 3) { + gSaveContext.save.day++; + gSaveContext.save.daysElapsed++; + } + + gSaveContext.save.bombersCaughtNum = 0; + gSaveContext.save.bombersCaughtOrder[0] = 0; + gSaveContext.save.bombersCaughtOrder[1] = 0; + gSaveContext.save.bombersCaughtOrder[2] = 0; + gSaveContext.save.bombersCaughtOrder[3] = 0; + gSaveContext.save.bombersCaughtOrder[4] = 0; + + // Unconfirmed: "Bombers Hide & Seek started on Day 1???" + gSaveContext.save.weekEventReg[73] &= (u8)~0x10; + // Unconfirmed: "Bombers Hide & Seek in Progress" + gSaveContext.save.weekEventReg[85] &= (u8)~2; +} + +u16 Sram_CalcChecksum(void* data, size_t count) { + u8* dataPtr = data; + u16 chkSum = 0; + + while (count-- > 0) { + chkSum += *dataPtr; + dataPtr++; + } + return chkSum; +} + +// Resets `Save` substruct +void Sram_ResetSave(void) { + gSaveContext.save.entranceIndex = 0x1C00; + gSaveContext.save.equippedMask = 0; + gSaveContext.save.isFirstCycle = false; + gSaveContext.save.unk_06 = 0; + gSaveContext.save.linkAge = 0; + gSaveContext.save.isNight = false; + gSaveContext.save.daySpeed = 0; + gSaveContext.save.snowheadCleared = 0; + gSaveContext.save.hasTatl = false; + gSaveContext.save.isOwlSave = false; + + // Instead of bloating all save context accesses with an extra sub-struct, the size of the would-be sub-struct + // is calculated manually + bzero(&gSaveContext.save.playerData, sizeof(Save) - offsetof(Save, playerData)); +} + +/** + * Initializes with random values the following fields: + * - lotteryCodes + * - spiderHouseMaskOrder + * - bomberCode + */ +void Sram_GenerateRandomSaveFields(void) { + s32 randBombers; + s16 sp2A; + s16 pad; + s16 i; + s16 j; + s32 k; + s16 randSpiderHouse; + + Sram_ClearHighscores(); + + gSaveContext.save.lotteryCodes[0][0] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[0][1] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[0][2] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[1][0] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[1][1] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[1][2] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[2][0] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[2][1] = Rand_S16Offset(0, 10); + gSaveContext.save.lotteryCodes[2][2] = Rand_S16Offset(0, 10); + + // Needed to match... + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) {} + } + + i = 0; + sp2A = Rand_S16Offset(0, 16) & 3; + k = 6; + while (i != k) { + randSpiderHouse = Rand_S16Offset(0, 16) & 3; + if (sp2A != randSpiderHouse) { + gSaveContext.save.spiderHouseMaskOrder[i] = randSpiderHouse; + i++; + sp2A = randSpiderHouse; + } + } + + do { + randBombers = Rand_S16Offset(0, 6); + } while (randBombers <= 0 || randBombers >= 6); + + gSaveContext.save.bomberCode[0] = randBombers; + + i = 1; + while (i != 5) { + k = false; + + do { + randBombers = Rand_S16Offset(0, 6); + } while (randBombers <= 0 || randBombers >= 6); + + sp2A = 0; + do { + if (randBombers == gSaveContext.save.bomberCode[sp2A]) { + k = true; + } + sp2A++; + } while (sp2A < i); + + if (k == false) { + gSaveContext.save.bomberCode[i] = randBombers; + i++; + } + } +} + +SavePlayerData sSaveDefaultPlayerData = { + { '\0', '\0', '\0', '\0', '\0', '\0' }, // newf + 0, // deaths + { 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName " " + 0x30, // healthCapacity + 0x30, // health + 0, // magicLevel + 0x30, // magic + 0, // rupees + 0, // swordHealth + 0, // tatlTimer + 0, // magicAcquired + 0, // doubleMagic + 0, // doubleDefense + 0, // unk_1F + 0xFF, // unk_20 + 0x0000, // owlActivationFlags + 0xFF, // unk_24 + SCENE_SPOT00, // savedSceneNum +}; + +ItemEquips sSaveDefaultItemEquips = { + { + { ITEM_SWORD_KOKIRI, ITEM_NONE, ITEM_NONE, ITEM_NONE }, + { ITEM_SWORD_KOKIRI, ITEM_NONE, ITEM_NONE, ITEM_NONE }, + { ITEM_SWORD_KOKIRI, ITEM_NONE, ITEM_NONE, ITEM_NONE }, + { ITEM_UNK_FD, ITEM_NONE, ITEM_NONE, ITEM_NONE }, + }, + { + { SLOT_OCARINA, SLOT_NONE, SLOT_NONE, SLOT_NONE }, + { SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }, + { SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }, + { SLOT_NONE, SLOT_NONE, SLOT_NONE, SLOT_NONE }, + }, + 0x11, +}; + +Inventory sSaveDefaultInventory = { + // items + { + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, ITEM_NONE, + }, + // ammo + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + // upgrades + 0x120000, + // questItems + 0, + // dungeonItems + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + // dungeonKeys + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0 }, + // strayFairies + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + // dekuPlaygroundPlayerName + { + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + }, +}; + +u16 sSaveDefaultChecksum = 0; + +/** + * Initialize new save. + * This save has an empty inventory with 3 hearts, sword and shield. + */ +void Sram_InitNewSave(void) { + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.daysElapsed = 0; + gSaveContext.save.day = 0; + gSaveContext.save.time = CLOCK_TIME(6, 0) - 1; + Sram_ResetSave(); + + Lib_MemCpy(&gSaveContext.save.playerData, &sSaveDefaultPlayerData, sizeof(SavePlayerData)); + Lib_MemCpy(&gSaveContext.save.equips, &sSaveDefaultItemEquips, sizeof(ItemEquips)); + Lib_MemCpy(&gSaveContext.save.inventory, &sSaveDefaultInventory, sizeof(Inventory)); + Lib_MemCpy(&gSaveContext.save.checksum, &sSaveDefaultChecksum, sizeof(gSaveContext.save.checksum)); + + gSaveContext.save.horseData.scene = SCENE_F01; + gSaveContext.save.horseData.pos.x = -1420; + gSaveContext.save.horseData.pos.y = 257; + gSaveContext.save.horseData.pos.z = -1285; + gSaveContext.save.horseData.yaw = -0x7554; + + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.save.playerData.magicLevel = 0; + Sram_GenerateRandomSaveFields(); +} + +SavePlayerData sSaveDebugPlayerData = { + { 'Z', 'E', 'L', 'D', 'A', '3' }, // newf + 0x0000, // deaths + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, // playerName "LINK " + 0x80, // healthCapacity + 0x80, // health + 0, // magicLevel + 0x30, // magic + 0x32, // rupees + 0x64, // swordHealth + 0, // tatlTimer + 1, // magicAcquired + 0, // doubleMagic + 0, // doubleDefense + 0, // unk_1F + 0xFF, // unk_20 + 0, // owlActivationFlags + 0xFF, // unk_24 + SCENE_SPOT00, // savedSceneNum +}; + +ItemEquips sSaveDebugItemEquips = { + { + { ITEM_SWORD_KOKIRI, ITEM_BOW, ITEM_POTION_RED, ITEM_OCARINA }, + { ITEM_SWORD_KOKIRI, ITEM_BOW, ITEM_MASK_GORON, ITEM_OCARINA }, + { ITEM_SWORD_KOKIRI, ITEM_BOW, ITEM_MASK_ZORA, ITEM_OCARINA }, + { ITEM_NUT, ITEM_NUT, ITEM_MASK_DEKU, ITEM_OCARINA }, + }, + { + { SLOT_OCARINA, SLOT_BOW, SLOT_BOTTLE_2, SLOT_OCARINA }, + { SLOT_OCARINA, SLOT_MAGIC_BEANS, SLOT_MASK_GORON, SLOT_BOMBCHU }, + { SLOT_OCARINA, SLOT_POWDER_KEG, SLOT_MASK_ZORA, SLOT_BOMBCHU }, + { SLOT_OCARINA, SLOT_BOW, SLOT_MASK_DEKU, SLOT_BOMBCHU }, + }, + 0x11, +}; + +Inventory sSaveDebugInventory = { + // items + { + ITEM_OCARINA, + ITEM_BOW, + ITEM_ARROW_FIRE, + ITEM_ARROW_ICE, + ITEM_ARROW_LIGHT, + ITEM_MOON_TEAR, + ITEM_BOMB, + ITEM_BOMBCHU, + ITEM_STICK, + ITEM_NUT, + ITEM_MAGIC_BEANS, + ITEM_ROOM_KEY, + ITEM_POWDER_KEG, + ITEM_PICTO_BOX, + ITEM_LENS, + ITEM_HOOKSHOT, + ITEM_SWORD_GREAT_FAIRY, + ITEM_LETTER_TO_KAFEI, + ITEM_BOTTLE, + ITEM_POTION_RED, + ITEM_POTION_GREEN, + ITEM_POTION_BLUE, + ITEM_NONE, + ITEM_NONE, + ITEM_MASK_POSTMAN, + ITEM_MASK_ALL_NIGHT, + ITEM_MASK_BLAST, + ITEM_MASK_STONE, + ITEM_MASK_GREAT_FAIRY, + ITEM_MASK_DEKU, + ITEM_MASK_KEATON, + ITEM_MASK_BREMEN, + ITEM_MASK_BUNNY, + ITEM_MASK_DON_GERO, + ITEM_MASK_SCENTS, + ITEM_MASK_GORON, + ITEM_MASK_ROMANI, + ITEM_MASK_CIRCUS_LEADER, + ITEM_MASK_KAFEIS_MASK, + ITEM_MASK_COUPLE, + ITEM_MASK_TRUTH, + ITEM_MASK_ZORA, + ITEM_MASK_KAMARO, + ITEM_MASK_GIBDO, + ITEM_MASK_GARO, + ITEM_MASK_CAPTAIN, + ITEM_MASK_GIANT, + ITEM_MASK_FIERCE_DEITY, + }, + // ammo + { 1, 30, 1, 1, 1, 1, 30, 30, 30, 30, 1, 1, 1, 1, 30, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + // upgrades + 0x120009, + // questItems + (1 << QUEST_SONG_SONATA) | (1 << QUEST_SONG_LULLABY) | (1 << QUEST_SONG_BOSSA_NOVA) | (1 << QUEST_SONG_ELEGY) | + (1 << QUEST_SONG_OATH) | (1 << QUEST_SONG_TIME) | (1 << QUEST_SONG_HEALING) | (1 << QUEST_SONG_EPONA) | + (1 << QUEST_SONG_SOARING) | (1 << QUEST_SONG_STORMS) | (1 << QUEST_BOMBERS_NOTEBOOK) | + (1 << QUEST_SONG_LULLABY_INTRO), + // dungeonItems + { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }, + // dungeonKeys + { 8, 8, 8, 8, 8, 8, 8, 8, 8, 0 }, + // strayFairies + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + // dekuPlaygroundPlayerName + { + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + // "LINK " + { 0x15, 0x12, 0x17, 0x14, 0x3E, 0x3E, 0x3E, 0x3E }, + }, +}; + +u16 sSaveDebugChecksum = 0; + +u8 D_801C6A48[] = { + ITEM_MASK_FIERCE_DEITY, ITEM_MASK_GORON, ITEM_MASK_ZORA, ITEM_MASK_DEKU, ITEM_MASK_FIERCE_DEITY, +}; + +u8 D_801C6A50[] = { + SLOT_MASK_FIERCE_DEITY, SLOT_MASK_GORON, SLOT_MASK_ZORA, SLOT_MASK_DEKU, SLOT_MASK_FIERCE_DEITY, +}; + +/** + * Initialize debug save. This is also used on the Title Screen + * This save has a mostly full inventory, every mask and 10 hearts. + * + * Some noteable flags that are set: + * TODO: Investigate the flags + */ +void Sram_InitDebugSave(void) { + Sram_ResetSave(); + + Lib_MemCpy(&gSaveContext.save.playerData, &sSaveDebugPlayerData, sizeof(SavePlayerData)); + Lib_MemCpy(&gSaveContext.save.equips, &sSaveDebugItemEquips, sizeof(ItemEquips)); + Lib_MemCpy(&gSaveContext.save.inventory, &sSaveDebugInventory, sizeof(Inventory)); + Lib_MemCpy(&gSaveContext.save.checksum, &sSaveDebugChecksum, sizeof(gSaveContext.save.checksum)); + + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + BUTTON_ITEM_EQUIP(0, 2) = D_801C6A48[((void)0, gSaveContext.save.playerForm & 0xFF)]; + C_SLOT_EQUIP(0, 2) = D_801C6A50[((void)0, gSaveContext.save.playerForm & 0xFF)]; + } + + gSaveContext.save.hasTatl = true; + + gSaveContext.save.horseData.scene = SCENE_F01; + gSaveContext.save.horseData.pos.x = -1420; + gSaveContext.save.horseData.pos.y = 257; + gSaveContext.save.horseData.pos.z = -1285; + gSaveContext.save.horseData.yaw = -0x7554; + + gSaveContext.save.entranceIndex = 0x1C00; + gSaveContext.save.isFirstCycle = true; + + // + gSaveContext.save.weekEventReg[0x0F] |= 0x20; + // Unconfirmed: "Entered South Clock Town" + gSaveContext.save.weekEventReg[0x3B] |= 0x04; + // Unconfirmed: "Tatl's Second Cycle Text?" + gSaveContext.save.weekEventReg[0x1F] |= 0x04; + + gSaveContext.cycleSceneFlags[SCENE_INSIDETOWER].switch0 = 1; + gSaveContext.save.permanentSceneFlags[SCENE_INSIDETOWER].switch0 = 1; + gSaveContext.save.playerData.magicLevel = 0; + + Sram_GenerateRandomSaveFields(); +} + +// Unused +void func_80144A94(SramContext* sramCtx) { + s32 i; + s32 cutscene = gSaveContext.save.cutscene; + + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + + if (func_80185968(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2], D_801C67F0[gSaveContext.fileNum * 2]) != + 0) { + func_80185968(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2 + 1], + D_801C67F0[gSaveContext.fileNum * 2 + 1]); + } + Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save)); + if (CHECK_NEWF(gSaveContext.save.playerData.newf)) { + func_80185968(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2 + 1], + D_801C67F0[gSaveContext.fileNum * 2 + 1]); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save)); + } + gSaveContext.save.cutscene = cutscene; + + for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { + gSaveContext.eventInf[i] = 0; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.cycleSceneFlags[i].chest = gSaveContext.save.permanentSceneFlags[i].chest; + gSaveContext.cycleSceneFlags[i].switch0 = gSaveContext.save.permanentSceneFlags[i].switch0; + gSaveContext.cycleSceneFlags[i].switch1 = gSaveContext.save.permanentSceneFlags[i].switch1; + gSaveContext.cycleSceneFlags[i].clearedRoom = gSaveContext.save.permanentSceneFlags[i].clearedRoom; + gSaveContext.cycleSceneFlags[i].collectible = gSaveContext.save.permanentSceneFlags[i].collectible; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { + gSaveContext.unk_3DD0[i] = 0; + gSaveContext.unk_3DE0[i] = 0; + gSaveContext.unk_3E18[i] = 0; + gSaveContext.unk_3E50[i] = 0; + gSaveContext.unk_3E88[i] = 0; + gSaveContext.unk_3EC0[i] = 0; + } + + D_801BDAA0 = 1; + D_801BDA9C = 0; + gSaveContext.powderKegTimer = 0; + gSaveContext.unk_1014 = 0; + gSaveContext.jinxTimer = 0; +} + +u16 D_801C6A58[] = { 0x68B0, 0x6A60, 0xB230, 0x9A80, 0xD890, 0x3E40, 0x8640, 0x84A0, 0x2040, 0xAA30 }; + +#ifdef NON_MATCHING +// Small regalloc between v0/t6/t7 +void Sram_OpenSave(FileChooseContext* fileChooseCtx, SramContext* sramCtx) { + s32 i; + s32 pad; + s32 phi_t1; + s32 pad1[2]; + s32 fileNum; + + if (gSaveContext.unk_3F3F) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + + if (gSaveContext.fileNum == 0xFF) { + func_80185968(sramCtx->saveBuf, D_801C67C8[0], D_801C67F0[0]); + } else if (fileChooseCtx->unk_2446A[gSaveContext.fileNum] != 0) { + phi_t1 = gSaveContext.fileNum + 2; + phi_t1 *= 2; + + if (func_80185968(sramCtx->saveBuf, D_801C67C8[phi_t1], D_801C67F0[phi_t1]) != 0) { + func_80185968(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]); + } + } else { + phi_t1 = gSaveContext.fileNum; + phi_t1 *= 2; + + if (func_80185968(sramCtx->saveBuf, D_801C67C8[phi_t1], D_801C67F0[phi_t1]) != 0) { + func_80185968(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]); + } + } + + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[phi_t1]); + + if (CHECK_NEWF(gSaveContext.save.playerData.newf)) { + func_80185968(sramCtx->saveBuf, D_801C67C8[phi_t1 + 1], D_801C67F0[phi_t1 + 1]); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[phi_t1]); + } + } + + gSaveContext.save.playerData.magicLevel = 0; + + if (!gSaveContext.save.isOwlSave) { + for (i = 0; i < ARRAY_COUNT(gSaveContext.eventInf); i++) { + gSaveContext.eventInf[i] = 0; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.cycleSceneFlags[i].chest = gSaveContext.save.permanentSceneFlags[i].chest; + gSaveContext.cycleSceneFlags[i].switch0 = gSaveContext.save.permanentSceneFlags[i].switch0; + gSaveContext.cycleSceneFlags[i].switch1 = gSaveContext.save.permanentSceneFlags[i].switch1; + gSaveContext.cycleSceneFlags[i].clearedRoom = gSaveContext.save.permanentSceneFlags[i].clearedRoom; + gSaveContext.cycleSceneFlags[i].collectible = gSaveContext.save.permanentSceneFlags[i].collectible; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.unk_3DD0); i++) { + gSaveContext.unk_3DD0[i] = 0; + gSaveContext.unk_3DE0[i] = 0; + gSaveContext.unk_3E18[i] = 0; + gSaveContext.unk_3E50[i] = 0; + gSaveContext.unk_3E88[i] = 0; + gSaveContext.unk_3EC0[i] = 0; + } + + if (gSaveContext.save.isFirstCycle) { + gSaveContext.save.entranceIndex = 0xD800; + gSaveContext.save.day = 0; + gSaveContext.save.time = 0x3FFF; + } else { + gSaveContext.save.entranceIndex = 0x1C00; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + } + } else { + gSaveContext.save.entranceIndex = D_801C6A58[gSaveContext.save.owlSaveLocation]; + if (D_801C6A58[gSaveContext.save.owlSaveLocation] == 0x84A0 && (gSaveContext.save.weekEventReg[20] & 2)) { + // Unconfirmed weekEventReg: "Woodfall Temple Prison Entrance raised / Water cleansed" + gSaveContext.save.entranceIndex = 0xCA0; + } else if (D_801C6A58[gSaveContext.save.owlSaveLocation] == 0x9A80 && + (gSaveContext.save.weekEventReg[33] & 0x80)) { + // Unconfirmed weekEventReg: "Mountain Village Unfrozen" + gSaveContext.save.entranceIndex = 0xAE80; + } + + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.cycleSceneFlags[i].chest = gSaveContext.save.permanentSceneFlags[i].chest; + gSaveContext.cycleSceneFlags[i].switch0 = gSaveContext.save.permanentSceneFlags[i].switch0; + gSaveContext.cycleSceneFlags[i].switch1 = gSaveContext.save.permanentSceneFlags[i].switch1; + gSaveContext.cycleSceneFlags[i].clearedRoom = gSaveContext.save.permanentSceneFlags[i].clearedRoom; + gSaveContext.cycleSceneFlags[i].collectible = gSaveContext.save.permanentSceneFlags[i].collectible; + } + + if (gSaveContext.save.unk_F65) { + Lib_MemCpy(gScarecrowSpawnSongPtr, gSaveContext.save.scarecrowsSong, + sizeof(gSaveContext.save.scarecrowsSong)); + + for (i = 0; i != ARRAY_COUNT(gSaveContext.save.scarecrowsSong); i++) {} + } + + fileNum = gSaveContext.fileNum; + func_80147314(sramCtx, fileNum); + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_OpenSave.s") +#endif + +// Similar to func_80145698, but accounts for owl saves? +void func_8014546C(SramContext* sramCtx) { + s32 i; + + if (gSaveContext.save.isOwlSave) { + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.save.permanentSceneFlags[i].chest = gSaveContext.cycleSceneFlags[i].chest; + gSaveContext.save.permanentSceneFlags[i].switch0 = gSaveContext.cycleSceneFlags[i].switch0; + gSaveContext.save.permanentSceneFlags[i].switch1 = gSaveContext.cycleSceneFlags[i].switch1; + gSaveContext.save.permanentSceneFlags[i].clearedRoom = gSaveContext.cycleSceneFlags[i].clearedRoom; + gSaveContext.save.permanentSceneFlags[i].collectible = gSaveContext.cycleSceneFlags[i].collectible; + } + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = Sram_CalcChecksum(&gSaveContext, offsetof(SaveContext, fileNum)); + + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, offsetof(SaveContext, fileNum)); + } else { + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.save.permanentSceneFlags[i].chest = gSaveContext.cycleSceneFlags[i].chest; + gSaveContext.save.permanentSceneFlags[i].switch0 = gSaveContext.cycleSceneFlags[i].switch0; + gSaveContext.save.permanentSceneFlags[i].switch1 = gSaveContext.cycleSceneFlags[i].switch1; + gSaveContext.save.permanentSceneFlags[i].clearedRoom = gSaveContext.cycleSceneFlags[i].clearedRoom; + gSaveContext.save.permanentSceneFlags[i].collectible = gSaveContext.cycleSceneFlags[i].collectible; + } + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save)); + + if (gSaveContext.unk_3F3F) { + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, sizeof(Save)); + Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save)); + } + } +} + +/** + * Save permanent scene flags, calculate checksum, copy save context to the save buffer + */ +void func_80145698(SramContext* sramCtx) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(gSaveContext.cycleSceneFlags); i++) { + gSaveContext.save.permanentSceneFlags[i].chest = gSaveContext.cycleSceneFlags[i].chest; + gSaveContext.save.permanentSceneFlags[i].switch0 = gSaveContext.cycleSceneFlags[i].switch0; + gSaveContext.save.permanentSceneFlags[i].switch1 = gSaveContext.cycleSceneFlags[i].switch1; + gSaveContext.save.permanentSceneFlags[i].clearedRoom = gSaveContext.cycleSceneFlags[i].clearedRoom; + gSaveContext.save.permanentSceneFlags[i].collectible = gSaveContext.cycleSceneFlags[i].collectible; + } + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save)); + if (gSaveContext.unk_3F3F) { + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, sizeof(Save)); + Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save)); + } +} + +// Verifies save and use backup if corrupted? +#ifdef NON_EQUIVALENT +void func_801457CC(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) { + FileChooseContext* fileChooseCtx = fileChooseCtx2; + u16 sp7A; + // u16 sp78; + u16 sp76; + // u16 sp74; + u16 sp6E; //! + // s32 sp68; + // u16 sp66; + u16 phi_s2; //! + u16 sp64; + // s32 sp60; + // s32 sp5C; + // s32 sp58; + // u32 new_var; + u16 phi_s2_3; + // s16 fakevar; + + u16 temp_s2; + u16 temp_v0_2; + u16 phi_a0; // maskCount + + if (gSaveContext.unk_3F3F) { + D_801F6AF0 = gSaveContext.save.time; + D_801F6AF2 = gSaveContext.unk_3F3F; + sp64 = 0; + + for (sp76 = 0; sp76 < 5; sp76++, sp64 += 2) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + + phi_s2 = false; + sp6E = 0; + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64])) { + sp6E = 1; + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) { + phi_s2 = true; + } + } + + if (sp76 < 2) { + fileChooseCtx->unk_24468[sp76] = 0; + if (phi_s2) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + } else { + // Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + temp_s2 = gSaveContext.save.checksum; + gSaveContext.save.checksum = 0; + temp_v0_2 = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]); + gSaveContext.save.checksum = temp_s2; + + if (CHECK_NEWF(gSaveContext.save.playerData.newf) || (temp_s2 != temp_v0_2)) { + sp6E = 1; + if (CHECK_NEWF2(gSaveContext.save.playerData.newf)) {} + + phi_s2 = false; + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) { + phi_s2 = true; + } + + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + temp_s2 = gSaveContext.save.checksum; + gSaveContext.save.checksum = 0; + if (phi_s2 || CHECK_NEWF(gSaveContext.save.playerData.newf) || + (temp_s2 != Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]))) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save)); + sp6E = 999; + } + } + } + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = + Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed? + + for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.newf); sp7A++) { + fileChooseCtx->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A]; + } + + if (!CHECK_NEWF(fileChooseCtx->newf[sp76])) { + fileChooseCtx->unk_2440C[sp76] = gSaveContext.save.playerData.deaths; + + for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.playerName); sp7A++) { + fileChooseCtx->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A]; + } + + fileChooseCtx->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity; + fileChooseCtx->health[sp76] = gSaveContext.save.playerData.health; + fileChooseCtx->unk_24454[sp76] = gSaveContext.save.inventory.dungeonKeys[9]; + fileChooseCtx->unk_24444[sp76] = gSaveContext.save.inventory.questItems; + fileChooseCtx->unk_24458[sp76] = gSaveContext.save.time; + fileChooseCtx->unk_24460[sp76] = gSaveContext.save.day; + fileChooseCtx->unk_24468[sp76] = gSaveContext.save.isOwlSave; + fileChooseCtx->rupees[sp76] = gSaveContext.save.playerData.rupees; + fileChooseCtx->unk_24474[sp76] = CUR_UPG_VALUE(4); + + for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) { + if (gSaveContext.save.inventory.items[sp7A + 24] != 0xFF) { + phi_a0++; + } + } + fileChooseCtx->maskCount[sp76] = phi_a0; + fileChooseCtx->heartPieceCount[sp76] = + ((gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C); + } + + if (sp6E == 1) { + Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save)); + func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C6818[sp64]); + } else if (sp6E == 0) { // TODO: == 0? + temp_s2 = gSaveContext.save.checksum; + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) { + phi_s2_3 = 1; + } else { + Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save)); + phi_s2_3 = gSaveContext.save.checksum; + gSaveContext.save.checksum = 0; + sp7A = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save)); + } + + if (CHECK_NEWF(gSaveContext.save.playerData.newf) || (phi_s2_3 != sp7A) || (phi_s2_3 != temp_s2)) { + func_80185968(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64]); + Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save)); + Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save)); + func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C6818[sp64]); + } + } + } else if (sp76 < 4) { + fileChooseCtx->unk_24468[sp76] = 0; + + if (!CHECK_NEWF(fileChooseCtx->newf2[(s32)sp76])) { // TODO: Needed? + if (phi_s2) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, + D_801C6870[sp64]); // TODO: Needed? + } else { + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + temp_s2 = gSaveContext.save.checksum; + + gSaveContext.save.checksum = 0; + temp_v0_2 = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]); + gSaveContext.save.checksum = temp_s2; + if (CHECK_NEWF(gSaveContext.save.playerData.newf) || (temp_s2 != temp_v0_2)) { + sp6E = 1; + if ((gSaveContext.save.playerData.newf[0] == 'Z') && + (gSaveContext.save.playerData.newf[1] == 'E')) { + phi_s2 = false; + } + + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) { + phi_s2 = true; + } + + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + temp_s2 = gSaveContext.save.checksum; + gSaveContext.save.checksum = 0; + if (phi_s2 || CHECK_NEWF(gSaveContext.save.playerData.newf) || + (temp_s2 != Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]))) { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + sp6E = 999; + } + } + } + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = + Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64 & 0xFFFFFFFF]); // TODO: Needed? + + for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.newf); sp7A++) { + fileChooseCtx->newf[sp76][sp7A] = gSaveContext.save.playerData.newf[sp7A]; + } + + if (!CHECK_NEWF(fileChooseCtx->newf[sp76])) { + fileChooseCtx->unk_2440C[sp76] = gSaveContext.save.playerData.deaths; + + for (sp7A = 0; sp7A < ARRAY_COUNT(gSaveContext.save.playerData.playerName); sp7A++) { + phi_s2 += 0; // TODO: Needed? + fileChooseCtx->unk_24414[sp76][sp7A] = gSaveContext.save.playerData.playerName[sp7A]; + } + + fileChooseCtx->healthCapacity[sp76] = gSaveContext.save.playerData.healthCapacity; + fileChooseCtx->health[sp76] = gSaveContext.save.playerData.health; + fileChooseCtx->unk_24454[sp76] = gSaveContext.save.inventory.dungeonKeys[9]; + fileChooseCtx->unk_24444[sp76] = gSaveContext.save.inventory.questItems; + fileChooseCtx->unk_24458[sp76] = gSaveContext.save.time; + fileChooseCtx->unk_24460[sp76] = gSaveContext.save.day; + fileChooseCtx->unk_24468[sp76] = gSaveContext.save.isOwlSave; + fileChooseCtx->rupees[sp76] = gSaveContext.save.playerData.rupees; + fileChooseCtx->unk_24474[sp76] = CUR_UPG_VALUE(4); + + for (sp7A = 0, phi_a0 = 0; sp7A < 24; sp7A++) { + if (gSaveContext.save.inventory.items[sp7A + 24] != 0xFF) { + phi_a0++; + } + } + fileChooseCtx->maskCount[sp76] = phi_a0; + fileChooseCtx->heartPieceCount[sp76] = + ((gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C); + } + + if (sp6E == 1) { + func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]); + func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]); + } else if (!sp6E) { // TODO: == 0? + temp_s2 = gSaveContext.save.checksum; + if (func_80185968(sramCtx->saveBuf, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1])) { + phi_s2_3 = 1; + } else { + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + phi_s2_3 = gSaveContext.save.checksum; + gSaveContext.save.checksum = 0; + // phi_s2_3 = gSaveContext.save.checksum; + sp7A = Sram_CalcChecksum(&gSaveContext, D_801C6870[sp64]); + } + + if (CHECK_NEWF(gSaveContext.save.playerData.newf) || (phi_s2_3 != sp7A) || + (phi_s2_3 != temp_s2)) { + func_80185968(sramCtx->saveBuf, D_801C67C8[sp64], D_801C67F0[sp64]); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]); + func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]); + } + } + } else { + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, D_801C6870[sp64]); + func_80146EBC(sramCtx, D_801C67C8[sp64], D_801C67F0[sp64]); + func_80146EBC(sramCtx, D_801C67C8[sp64 + 1], D_801C67F0[sp64 + 1]); + } + } else { + if (phi_s2) { + gSaveContext.options.optionId = 0xA51D; + gSaveContext.options.language = 1; + gSaveContext.options.audioSetting = 0; + gSaveContext.options.languageSetting = 0; + gSaveContext.options.zTargetSetting = 0; + } else { + Lib_MemCpy(&gSaveContext.options, sramCtx->saveBuf, sizeof(SaveOptions)); + if (gSaveContext.options.optionId != 0xA51D) { + gSaveContext.options.optionId = 0xA51D; + gSaveContext.options.language = 1; + gSaveContext.options.audioSetting = 0; + gSaveContext.options.languageSetting = 0; + gSaveContext.options.zTargetSetting = 0; + } + } + func_801A3D98(gSaveContext.options.audioSetting); + } + } + + gSaveContext.save.time = D_801F6AF0; + gSaveContext.unk_3F3F = D_801F6AF2; + } + + gSaveContext.options.language = 1; +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_801457CC.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146580.s") +void func_80146580(FileChooseContext* fileChooseCtx2, SramContext* sramCtx, s32 fileNum) { + FileChooseContext* fileChooseCtx = fileChooseCtx2; + s32 pad; + if (gSaveContext.unk_3F3F) { + if (fileChooseCtx->unk_2446A[fileNum]) { + func_80147314(sramCtx, fileNum); + fileChooseCtx->unk_2446A[fileNum] = 0; + } + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, sizeof(Save)); + } + + gSaveContext.save.time = D_801F6AF0; + gSaveContext.unk_3F3F = D_801F6AF2; +} + +#ifdef NON_MATCHING +// v0/v1 +void func_80146628(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) { + FileChooseContext* fileChooseCtx = fileChooseCtx2; + u16 i; + s16 maskCount; + + if (gSaveContext.unk_3F3F) { + if (fileChooseCtx->unk_2446A[fileChooseCtx->unk_2448E]) { + func_80147414(sramCtx, fileChooseCtx->unk_2448E, fileChooseCtx->fileNum); + fileChooseCtx->unk_24410[fileChooseCtx->fileNum] = gSaveContext.save.playerData.deaths; + + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) { + fileChooseCtx->unk_24424[fileChooseCtx->fileNum][i] = gSaveContext.save.playerData.playerName[i]; + } + + fileChooseCtx->unk_24438[fileChooseCtx->fileNum] = gSaveContext.save.playerData.healthCapacity; + fileChooseCtx->unk_24440[fileChooseCtx->fileNum] = gSaveContext.save.playerData.health; + fileChooseCtx->unk_24456[fileChooseCtx->fileNum] = gSaveContext.save.inventory.dungeonKeys[9]; + fileChooseCtx->unk_2444C[fileChooseCtx->fileNum] = gSaveContext.save.inventory.questItems; + fileChooseCtx->unk_2445C[fileChooseCtx->fileNum] = gSaveContext.save.time; + fileChooseCtx->unk_24464[fileChooseCtx->fileNum] = gSaveContext.save.day; + fileChooseCtx->unk_2446A[fileChooseCtx->fileNum] = gSaveContext.save.isOwlSave; + fileChooseCtx->unk_24470[fileChooseCtx->fileNum] = gSaveContext.save.playerData.rupees; + // = CUR_UPG_VALUE(UPG_WALLET); + fileChooseCtx->unk_24476[fileChooseCtx->fileNum] = + (gSaveContext.save.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4]; + + for (i = 0, maskCount = 0; i < 24; i++) { + if (gSaveContext.save.inventory.items[i + 24] != ITEM_NONE) { + maskCount++; + } + } + + fileChooseCtx->unk_2447A[fileChooseCtx->fileNum] = maskCount; + fileChooseCtx->unk_2447E[fileChooseCtx->fileNum] = + (gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C; + } + + // clear buffer + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + // read to buffer + func_80185968(sramCtx->saveBuf, D_801C67C8[fileChooseCtx->unk_2448E * 2], + D_801C67F0[fileChooseCtx->unk_2448E * 2]); + + if (1) {} + func_80185968(&sramCtx->saveBuf[0x2000], D_801C67C8[fileChooseCtx->unk_2448E * 2 + 1], + D_801C67F0[fileChooseCtx->unk_2448E * 2 + 1]); + if (1) {} + + // copy buffer to save context + Lib_MemCpy(&gSaveContext.save, sramCtx->saveBuf, sizeof(Save)); + + fileChooseCtx->unk_2440C[fileChooseCtx->fileNum] = gSaveContext.save.playerData.deaths; + + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) { + fileChooseCtx->unk_24414[fileChooseCtx->fileNum][i] = gSaveContext.save.playerData.playerName[i]; + } + + fileChooseCtx->healthCapacity[fileChooseCtx->fileNum] = gSaveContext.save.playerData.healthCapacity; + fileChooseCtx->health[fileChooseCtx->fileNum] = gSaveContext.save.playerData.health; + fileChooseCtx->unk_24454[fileChooseCtx->fileNum] = gSaveContext.save.inventory.dungeonKeys[9]; + fileChooseCtx->unk_24444[fileChooseCtx->fileNum] = gSaveContext.save.inventory.questItems; + fileChooseCtx->unk_24458[fileChooseCtx->fileNum] = gSaveContext.save.time; + fileChooseCtx->unk_24460[fileChooseCtx->fileNum] = gSaveContext.save.day; + fileChooseCtx->unk_24468[fileChooseCtx->fileNum] = gSaveContext.save.isOwlSave; + fileChooseCtx->rupees[fileChooseCtx->fileNum] = gSaveContext.save.playerData.rupees; + // = CUR_UPG_VALUE(UPG_WALLET); + fileChooseCtx->unk_24474[fileChooseCtx->fileNum] = + (gSaveContext.save.inventory.upgrades & gUpgradeMasks[4]) >> gUpgradeShifts[4]; + + for (i = 0, maskCount = 0; i < 24; i++) { + if (gSaveContext.save.inventory.items[i + 24] != ITEM_NONE) { + maskCount++; + } + } + + fileChooseCtx->maskCount[fileChooseCtx->fileNum] = maskCount; + fileChooseCtx->heartPieceCount[fileChooseCtx->fileNum] = + (gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C; + } + + gSaveContext.save.time = D_801F6AF0; + gSaveContext.unk_3F3F = D_801F6AF2; +} +#else #pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146628.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146AA0.s") +void Sram_InitSave(FileChooseContext* fileChooseCtx2, SramContext* sramCtx) { + s32 phi_v0; + u16 i; + FileChooseContext* fileChooseCtx = fileChooseCtx2; + s16 maskCount; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146DF8.s") + if (gSaveContext.unk_3F3F) { + Sram_InitNewSave(); + if (fileChooseCtx->unk_24480 == 0) { + gSaveContext.save.cutscene = 0xFFF0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146E40.s") + for (phi_v0 = 0; phi_v0 < ARRAY_COUNT(gSaveContext.save.playerData.playerName); phi_v0++) { + gSaveContext.save.playerData.playerName[phi_v0] = + fileChooseCtx->unk_24414[fileChooseCtx->unk_24480][phi_v0]; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_Alloc.s") + gSaveContext.save.playerData.newf[0] = 'Z'; + gSaveContext.save.playerData.newf[1] = 'E'; + gSaveContext.save.playerData.newf[2] = 'L'; + gSaveContext.save.playerData.newf[3] = 'D'; + gSaveContext.save.playerData.newf[4] = 'A'; + gSaveContext.save.playerData.newf[5] = '3'; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146EBC.s") + gSaveContext.save.checksum = Sram_CalcChecksum(&gSaveContext.save, sizeof(Save)); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146EE8.s") + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext.save, sizeof(Save)); + Lib_MemCpy(&sramCtx->saveBuf[0x2000], &gSaveContext.save, sizeof(Save)); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80146F5C.s") + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.newf); i++) { + fileChooseCtx->newf[fileChooseCtx->unk_24480][i] = gSaveContext.save.playerData.newf[i]; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147008.s") + fileChooseCtx->unk_2440C[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.deaths; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147020.s") + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.playerData.playerName); i++) { + fileChooseCtx->unk_24414[fileChooseCtx->unk_24480][i] = gSaveContext.save.playerData.playerName[i]; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147068.s") + fileChooseCtx->healthCapacity[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.healthCapacity; + fileChooseCtx->health[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.health; + fileChooseCtx->unk_24454[fileChooseCtx->unk_24480] = gSaveContext.save.inventory.dungeonKeys[9]; + fileChooseCtx->unk_24444[fileChooseCtx->unk_24480] = gSaveContext.save.inventory.questItems; + fileChooseCtx->unk_24458[fileChooseCtx->unk_24480] = gSaveContext.save.time; + fileChooseCtx->unk_24460[fileChooseCtx->unk_24480] = gSaveContext.save.day; + fileChooseCtx->unk_24468[fileChooseCtx->unk_24480] = gSaveContext.save.isOwlSave; + fileChooseCtx->rupees[fileChooseCtx->unk_24480] = gSaveContext.save.playerData.rupees; + fileChooseCtx->unk_24474[fileChooseCtx->unk_24480] = CUR_UPG_VALUE(UPG_WALLET); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147138.s") + for (i = 0, maskCount = 0; i < 24; i++) { + if (gSaveContext.save.inventory.items[i + 24] != ITEM_NONE) { + maskCount++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147150.s") + fileChooseCtx->maskCount[fileChooseCtx->unk_24480] = maskCount; + fileChooseCtx->heartPieceCount[fileChooseCtx->unk_24480] = + (gSaveContext.save.inventory.questItems & 0xF0000000) >> 0x1C; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147198.s") + gSaveContext.save.time = D_801F6AF0; + gSaveContext.unk_3F3F = D_801F6AF2; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147314.s") +void func_80146DF8(SramContext* sramCtx) { + if (gSaveContext.unk_3F3F) { + // TODO: macros for languages + gSaveContext.options.language = 1; + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext.options, sizeof(SaveOptions)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/func_80147414.s") +void Sram_InitSram(GameState* gameState, SramContext* sramCtx) { + if (gSaveContext.save.entranceIndex) {} // Required to match -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sram_NES/Sram_nop8014750C.s") + func_801A3D98(gSaveContext.options.audioSetting); +} + +void Sram_Alloc(GameState* gamestate, SramContext* sramCtx) { + if (gSaveContext.unk_3F3F) { + sramCtx->saveBuf = THA_AllocEndAlign16(&gamestate->heap, SAVE_BUFFER_SIZE); + sramCtx->status = 0; + } +} + +/** + * Synchronous flash write + */ +void func_80146EBC(SramContext* sramCtx, s32 curPage, s32 numPages) { + sramCtx->curPage = curPage; + sramCtx->numPages = numPages; + func_80185F64(sramCtx->saveBuf, curPage, numPages); +} + +/** + * Saves the game on the very first time Player enters South Clock Town from the Clock Tower + */ +void Sram_SaveSpecialEnterClockTown(GlobalContext* globalCtx) { + s32 pad[2]; + SramContext* sramCtx = &globalCtx->sramCtx; + + gSaveContext.save.isFirstCycle = true; + gSaveContext.save.isOwlSave = false; + func_80145698(sramCtx); + func_80185F64(sramCtx->saveBuf, D_801C67C8[gSaveContext.fileNum * 2], D_801C6818[gSaveContext.fileNum * 2]); +} + +/** + * Saves when beating the game, after showing the "Dawn of the New Day" message + */ +void Sram_SaveSpecialNewDay(GlobalContext* globalCtx) { + s32 cutscene = gSaveContext.save.cutscene; + s32 day; + u16 time = gSaveContext.save.time; + + day = gSaveContext.save.day; + + // Unconfirmed: "Obtained Fierce Deity Mask?" + gSaveContext.save.weekEventReg[84] &= (u8)~0x20; + + Sram_SaveEndOfCycle(globalCtx); + func_8014546C(&globalCtx->sramCtx); + + gSaveContext.save.day = day; + gSaveContext.save.time = time; + gSaveContext.save.cutscene = cutscene; + func_80185F64(globalCtx->sramCtx.saveBuf, D_801C67C8[gSaveContext.fileNum * 2], + D_801C67F0[gSaveContext.fileNum * 2]); +} + +void func_80147008(SramContext* sramCtx, u32 curPage, u32 numPages) { + sramCtx->curPage = curPage; + sramCtx->numPages = numPages; + sramCtx->status = 1; +} + +void func_80147020(SramContext* sramCtx) { + // async flash write + func_80185DDC(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages); + + sramCtx->unk_18 = osGetTime(); + sramCtx->status = 2; +} + +void func_80147068(SramContext* sramCtx) { + if (sramCtx->status == 2) { + if (func_80185EC4() != 0) { // if task running + if (func_80185F04() == 0) { // wait for task done + // task success + sramCtx->status = 4; + } else { + // task failure + sramCtx->status = 4; + } + } + } else if (((osGetTime() - sramCtx->unk_18) * 0x40) / 3000 / 10000 >= 200) { + sramCtx->status = 0; + } +} + +void func_80147138(SramContext* sramCtx, s32 curPage, s32 numPages) { + sramCtx->curPage = curPage; + sramCtx->numPages = numPages; + sramCtx->status = 6; +} + +void func_80147150(SramContext* sramCtx) { + func_80185DDC(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages); + + sramCtx->unk_18 = osGetTime(); + sramCtx->status = 7; +} + +void func_80147198(SramContext* sramCtx) { + if (sramCtx->status == 7) { + if (func_80185EC4() != 0) { // Is task running + if (func_80185F04() == 0) { // Wait for task done + func_80185DDC(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages); + sramCtx->status = 8; + } else { + func_80185DDC(sramCtx->saveBuf, sramCtx->curPage + 0x80, sramCtx->numPages); + sramCtx->status = 8; + } + } + } else if (sramCtx->status == 8) { + if (func_80185EC4() != 0) { // Is task running + if (func_80185F04() == 0) { // Wait for task done + sramCtx->status = 4; + } else { + sramCtx->status = 4; + } + } + } else if (((osGetTime() - sramCtx->unk_18) * 0x40) / 3000 / 10000 >= 200) { + sramCtx->status = 0; + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + gSaveContext.save.isOwlSave = false; + gSaveContext.save.checksum = 0; + // flash read to buffer then copy to save context + func_80185968(sramCtx->saveBuf, sramCtx->curPage, sramCtx->numPages); + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, offsetof(SaveContext, fileNum)); + } +} + +void func_80147314(SramContext* sramCtx, s32 fileNum) { + s32 pad; + + gSaveContext.save.isOwlSave = false; + + gSaveContext.save.playerData.newf[0] = '\0'; + gSaveContext.save.playerData.newf[1] = '\0'; + gSaveContext.save.playerData.newf[2] = '\0'; + gSaveContext.save.playerData.newf[3] = '\0'; + gSaveContext.save.playerData.newf[4] = '\0'; + gSaveContext.save.playerData.newf[5] = '\0'; + + gSaveContext.save.checksum = 0; + gSaveContext.save.checksum = Sram_CalcChecksum(&gSaveContext, offsetof(SaveContext, fileNum)); + + Lib_MemCpy(sramCtx->saveBuf, &gSaveContext, offsetof(SaveContext, fileNum)); + func_80146EBC(sramCtx, D_801C6840[fileNum * 2], D_801C6850[fileNum * 2]); + func_80146EBC(sramCtx, D_801C6840[fileNum * 2 + 1], D_801C6850[fileNum * 2]); + + gSaveContext.save.isOwlSave = true; + + gSaveContext.save.playerData.newf[0] = 'Z'; + gSaveContext.save.playerData.newf[1] = 'E'; + gSaveContext.save.playerData.newf[2] = 'L'; + gSaveContext.save.playerData.newf[3] = 'D'; + gSaveContext.save.playerData.newf[4] = 'A'; + gSaveContext.save.playerData.newf[5] = '3'; +} + +void func_80147414(SramContext* sramCtx, s32 fileNum, s32 arg2) { + s32 pad; + + // Clear save buffer + bzero(sramCtx->saveBuf, SAVE_BUFFER_SIZE); + + // Read save file + if (func_80185968(sramCtx->saveBuf, D_801C6840[fileNum * 2], D_801C6850[fileNum * 2]) != 0) { + // If failed, read backup save file + func_80185968(sramCtx->saveBuf, D_801C6840[fileNum * 2 + 1], D_801C6850[fileNum * 2 + 1]); + } + + // Copy buffer to save context + Lib_MemCpy(&gSaveContext, sramCtx->saveBuf, offsetof(SaveContext, fileNum)); + + func_80146EBC(sramCtx, D_801C6840[arg2 * 2], D_801C6850[arg2 * 2]); + func_80146EBC(sramCtx, D_801C6840[arg2 * 2 + 1], D_801C6850[arg2 * 2]); +} + +void Sram_nop8014750C(UNK_TYPE4 arg0) { +} diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c index 1ab44acc1..3e5443bc6 100644 --- a/src/code/z_sub_s.c +++ b/src/code/z_sub_s.c @@ -1,16 +1,218 @@ +/* + * File: z_sub_s.c + * Description: Various miscellaneous helpers + */ + #include "global.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A7C0.s") +s16 sPathDayFlags[] = { 0x40, 0x20, 0x10, 8, 4, 2, 1, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s") +#include "code/sub_s/sub_s.c" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AB00.s") +Vec3f gOneVec3f = { 1.0f, 1.0f, 1.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD6C.s") +s32 D_801C5DBC[] = { 0, 1 }; // Unused -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AD9C.s") +/** + * Finds the first EnDoor instance with unk_1A4 == 5 and the specified switchFlag. + */ +EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 switchFlag) { + Actor* actor = NULL; + EnDoor* door; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AED4.s") + 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->switchFlag == (u8)switchFlag)) { + break; + } + + if (actor->next == NULL) { + door = NULL; + break; + } + + actor = actor->next; + } + + return door; +} + +Gfx* SubS_DrawTransformFlexLimb(GlobalContext* globalCtx, s32 limbIndex, void** skeleton, Vec3s* jointTable, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, + TransformLimbDraw transformLimbDraw, Actor* actor, Mtx** mtx, Gfx* gfx) { + StandardLimb* limb; + Gfx* newDList; + Gfx* limbDList; + Vec3f pos; + Vec3s rot; + + Matrix_Push(); + limb = Lib_SegmentedToVirtual(skeleton[limbIndex]); + limbIndex++; + rot = jointTable[limbIndex]; + pos.x = limb->jointPos.x; + pos.y = limb->jointPos.y; + pos.z = limb->jointPos.z; + newDList = limbDList = limb->dList; + + if ((overrideLimbDraw == NULL) || !overrideLimbDraw(globalCtx, limbIndex, &newDList, &pos, &rot, actor, &gfx)) { + Matrix_TranslateRotateZYX(&pos, &rot); + Matrix_Push(); + + transformLimbDraw(globalCtx, limbIndex, actor, &gfx); + + if (newDList != NULL) { + Matrix_ToMtx(*mtx); + gSPMatrix(gfx++, *mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, newDList); + (*mtx)++; + } else if (limbDList != NULL) { + Matrix_ToMtx(*mtx); + (*mtx)++; + } + Matrix_Pop(); + } + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, limbIndex, &limbDList, &rot, actor, &gfx); + } + if (limb->child != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->child, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx, gfx); + } + Matrix_Pop(); + if (limb->sibling != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, limb->sibling, skeleton, jointTable, overrideLimbDraw, postLimbDraw, + transformLimbDraw, actor, mtx, gfx); + } + return gfx; +} + +/** + * Draw all limbs of type `StandardLimb` in a given flexible skeleton + * Limbs in a flexible skeleton have meshes that can stretch to line up with other limbs. + * An array of matrices is dynamically allocated so each limb can access any transform to ensure its meshes line up. + * + * Also makes use of a `TransformLimbDraw`, which transforms limbs based on world coordinates, as opposed to local limb + * coordinates. + * Note that the `TransformLimbDraw` does not have a NULL check, so must be provided even if empty. + */ +Gfx* SubS_DrawTransformFlex(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, + TransformLimbDraw transformLimbDraw, Actor* actor, Gfx* gfx) { + StandardLimb* rootLimb; + s32 pad; + Gfx* newDlist; + Gfx* limbDList; + Vec3f pos; + Vec3s rot; + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(dListCount * sizeof(Mtx))); + + if (skeleton == NULL) { + return NULL; + } + + gSPSegment(gfx++, 0x0D, mtx); + Matrix_Push(); + rootLimb = Lib_SegmentedToVirtual(skeleton[0]); + pos.x = jointTable->x; + pos.y = jointTable->y; + pos.z = jointTable->z; + rot = jointTable[1]; + newDlist = rootLimb->dList; + limbDList = rootLimb->dList; + + if (overrideLimbDraw == NULL || !overrideLimbDraw(globalCtx, 1, &newDlist, &pos, &rot, actor, &gfx)) { + Matrix_TranslateRotateZYX(&pos, &rot); + Matrix_Push(); + + transformLimbDraw(globalCtx, 1, actor, &gfx); + + if (newDlist != NULL) { + Matrix_ToMtx(mtx); + gSPMatrix(gfx++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, newDlist); + mtx++; + } else if (limbDList != NULL) { + Matrix_ToMtx(mtx); + mtx++; + } + Matrix_Pop(); + } + + if (postLimbDraw != NULL) { + postLimbDraw(globalCtx, 1, &limbDList, &rot, actor, &gfx); + } + + if (rootLimb->child != LIMB_DONE) { + gfx = SubS_DrawTransformFlexLimb(globalCtx, rootLimb->child, skeleton, jointTable, overrideLimbDraw, + postLimbDraw, transformLimbDraw, actor, &mtx, gfx); + } + Matrix_Pop(); + return gfx; +} + +s32 SubS_InCsMode(GlobalContext* globalCtx) { + s32 inCsMode = false; + + if (Play_InCsMode(globalCtx)) { + inCsMode = true; + } + + return inCsMode; +} + +/** + * Computes a limb's position and rotation for use in TransformLimbDraws + * + * @param[in] newRotZ value to override newRot's Z value if override is true + * @param[in] newRotY value to override newRot's Y value if override is true + * @param[out] pos limb's computed position + * @param[out] rot limb's computed rotation + * @param[in] stepRot boolean, step towards newRot instead of setting directly + * @param[in] overrideRot boolean, override newRot with the specified input. + * + * Note: + * If overrideRot is true, the rotation will automatically step instead of setting directly + */ +s32 SubS_UpdateLimb(s16 newRotZ, s16 newRotY, Vec3f* pos, Vec3s* rot, s32 stepRot, s32 overrideRot) { + Vec3f newPos; + Vec3f zeroVec = gZeroVec3f; + Vec3s newRot; + MtxF curState; + + Matrix_MultVec3f(&zeroVec, &newPos); + Matrix_Get(&curState); + Matrix_MtxFToYXZRot(&curState, &newRot, MTXMODE_NEW); + *pos = newPos; + + if (!stepRot && !overrideRot) { + rot->x = newRot.x; + rot->y = newRot.y; + rot->z = newRot.z; + return true; + } + + if (overrideRot) { + newRot.z = newRotZ; + newRot.y = newRotY; + } + + Math_SmoothStepToS(&rot->x, newRot.x, 3, 0x2AA8, 0xB6); + Math_SmoothStepToS(&rot->y, newRot.y, 3, 0x2AA8, 0xB6); + Math_SmoothStepToS(&rot->z, newRot.z, 3, 0x2AA8, 0xB6); + return true; +} + +void SubS_UpdateFlags(u16* flags, u16 setBits, u16 unsetBits) { + *flags = (*flags & ~unsetBits) | setBits; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013AF00.s") @@ -24,88 +226,936 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013B878.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB34.s") +Path* SubS_GetAdditionalPath(GlobalContext* globalCtx, u8 pathIndex, s32 max) { + Path* path; + s32 i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB7C.s") + do { + path = &globalCtx->setupPathList[pathIndex]; + if (i >= max) { + break; + } + pathIndex = path->unk1; + i++; + } while (pathIndex != 0xFF); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BC6C.s") + return path; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BD40.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; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BEDC.s") + 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; +} + +s32 SubS_ChangeAnimationByInfoS(SkelAnime* skelAnime, AnimationInfoS* animations, s32 index) { + s32 endFrame; + s32 startFrame; + + animations += index; + endFrame = animations->frameCount; + if (animations->frameCount < 0) { + endFrame = Animation_GetLastFrame(&animations->animation->common); + } + startFrame = animations->startFrame; + if (startFrame >= endFrame || startFrame < 0) { + return false; + } + if (animations->playSpeed < 0.0f) { + SWAP(s32, endFrame, startFrame); + } + Animation_Change(skelAnime, animations->animation, animations->playSpeed, startFrame, endFrame, animations->mode, + animations->morphFrames); + return true; +} + +s32 SubS_HasReachedPoint(Actor* actor, Path* path, s32 pointIndex) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 count = path->count; + s32 index = pointIndex; + s32 reached = false; + f32 diffX; + f32 diffZ; + f32 px; + f32 pz; + f32 d; + Vec3f point; + + Math_Vec3s_ToVec3f(&point, &points[index]); + + if (index == 0) { + diffX = points[1].x - points[0].x; + diffZ = points[1].z - points[0].z; + } else if (index == count - 1) { + diffX = points[count - 1].x - points[count - 2].x; + diffZ = points[count - 1].z - points[count - 2].z; + } else { + diffX = points[index + 1].x - points[index - 1].x; + diffZ = points[index + 1].z - points[index - 1].z; + } + + func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d); + if (((px * actor->world.pos.x) + (pz * actor->world.pos.z) + d) > 0.0f) { + reached = true; + } + + return reached; +} + +Path* SubS_GetDayDependentPath(GlobalContext* globalCtx, u8 pathIndex, u8 max, s32* startPointIndex) { + Path* path = NULL; + s32 found = false; + s32 time = (((s16)TIME_TO_MINUTES_F(gSaveContext.save.time) % 60) + + ((s16)TIME_TO_MINUTES_F(gSaveContext.save.time) / 60) * 60) / + 30; + s32 day = CURRENT_DAY; + + if (pathIndex == max) { + return NULL; + } + + while (pathIndex != 0xFF) { + path = &globalCtx->setupPathList[pathIndex]; + if (sPathDayFlags[day] & path->unk2) { + found = true; + break; + } + pathIndex = path->unk1; + } + + if (found == true) { + *startPointIndex = time; + *startPointIndex = CLAMP(*startPointIndex, 0, path->count - 1); + } else { + *startPointIndex = 0; + } + + return path; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013C068.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013C624.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013C8B8.s") +s32 SubS_CopyPointFromPathCheckBounds(Path* path, s32 pointIndex, Vec3f* dst) { + Vec3s* point; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013C964.s") + if ((path == NULL) || (pointIndex >= path->count) || (pointIndex < 0)) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CC2C.s") + point = Lib_SegmentedToVirtual(path->points); + point = &point[pointIndex]; + dst->x = point->x; + dst->y = point->y; + dst->z = point->z; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CD64.s") +//! TODO: Needs docs with func_800B8500 +s32 func_8013C964(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 itemId, s32 type) { + s32 ret = false; + s16 x; + s16 y; + f32 xzDistToPlayerTemp; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013CF04.s") + Actor_GetScreenPos(globalCtx, actor, &x, &y); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D0E0.s") + switch (type) { + case 1: + yRange = fabsf(actor->playerHeightRel) + 1.0f; + xzRange = actor->xzDistToPlayer + 1.0f; + ret = Actor_PickUp(actor, globalCtx, itemId, xzRange, yRange); + break; + case 2: + if ((fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange)) { + ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId); + } + break; + case 3: + //! @bug: Both x and y conditionals are always true, || should be an && + if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT))) { + ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId); + } + break; + case 4: + yRange = fabsf(actor->playerHeightRel) + 1.0f; + xzRange = actor->xzDistToPlayer + 1.0f; + xzDistToPlayerTemp = actor->xzDistToPlayer; + actor->xzDistToPlayer = 0.0f; + actor->flags |= 0x10000; + ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId); + actor->xzDistToPlayer = xzDistToPlayerTemp; + break; + case 5: + //! @bug: Both x and y conditionals are always true, || should be an && + if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT)) && + (fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange) && actor->isTargeted) { + actor->flags |= 0x10000; + ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId); + } + break; + case 6: + //! @bug: Both x and y conditionals are always true, || should be an && + if (((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT)) && + (fabsf(actor->playerHeightRel) <= yRange) && (actor->xzDistToPlayer <= xzRange)) { + actor->flags |= 0x10000; + ret = func_800B8500(actor, globalCtx, xzRange, yRange, itemId); + } + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D2E0.s") +const u8 sShadowMaps[4][12][12] = { + { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + { + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + }, + { + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 }, + { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0 }, + { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0 }, + }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D5E8.s") +void SubS_FillShadowTex(s32 startCol, s32 startRow, u8* tex, s32 size) { + s32 i; + s32 j; + s32 start; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D648.s") + for (i = 0; i < 12; i++) { + start = ((startRow + i) * 64) + startCol - 390; + for (j = 0; j < 12; j++) { + if (sShadowMaps[size][i][j] != 0) { + if ((start + j >= 0) && (start + j < SUBS_SHADOW_TEX_SIZE)) { + tex[start + j] = 255; + } + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D68C.s") +void SubS_GenShadowTex(Vec3f bodyPartsPos[], Vec3f* worldPos, u8* tex, f32 tween, u8 bodyPartsNum, u8 sizes[], + s8 parentBodyParts[]) { + Vec3f pos; + Vec3f startVec; + s32 i; + s32 parentBodyPart; + Vec3f* bodyPartPos; + s32 startCol; + s32 startRow; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D720.s") + for (i = 0; i < bodyPartsNum; i++) { + if (parentBodyParts[i] >= 0) { + parentBodyPart = parentBodyParts[i]; + bodyPartPos = &bodyPartsPos[i]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D768.s") + pos.x = (bodyPartsPos[parentBodyPart].x - bodyPartPos->x) * tween + (bodyPartPos->x - worldPos->x); + pos.y = (bodyPartsPos[parentBodyPart].y - bodyPartPos->y) * tween + (bodyPartPos->y - worldPos->y); + pos.z = (bodyPartsPos[parentBodyPart].z - bodyPartPos->z) * tween + (bodyPartPos->z - worldPos->z); + } else { + bodyPartPos = &bodyPartsPos[i]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D83C.s") + pos.x = bodyPartPos->x - worldPos->x; + pos.y = bodyPartPos->y - worldPos->y; + pos.z = bodyPartPos->z - worldPos->z; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D8DC.s") + Matrix_MultVec3f(&pos, &startVec); + startCol = 64.0f + startVec.x; + startRow = 64.0f - startVec.z; + SubS_FillShadowTex(startCol >> 1, startRow >> 1, tex, sizes[i]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D924.s") +void SubS_DrawShadowTex(Actor* actor, GameState* gameState, u8* tex) { + s32 pad; + GraphicsContext* gfxCtx = gameState->gfxCtx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_ActorCategoryIterateById.s") + OPEN_DISPS(gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D9C8.s") + func_8012C28C(gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, 100); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0); + Matrix_Translate(actor->world.pos.x, 0.0f, actor->world.pos.z, MTXMODE_NEW); + Matrix_Scale(0.6f, 1.0f, 0.6f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gShadowDL); + gDPLoadTextureBlock(POLY_OPA_DISP++, tex, G_IM_FMT_I, G_IM_SIZ_8b, SUBS_SHADOW_TEX_WIDTH, SUBS_SHADOW_TEX_HEIGHT, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD); + gSPDisplayList(POLY_OPA_DISP++, gShadowVtxDL); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DB90.s") + CLOSE_DISPS(gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DC40.s") +/** + * Computes the rotation based on the options and target rotation value + * + * @param[in,out] rot the computed rotation + * @param[in] rotMax the max rotation in binary angles + * @param[in] target the target rotation value + * @param[in] slowness how slow to rotate, the larger the number the slower the rotation, cannot be 0 + * @param[in] stepMin the minimun step in degrees + * @param[in] stepMax the maximum step in degrees + */ +s16 SubS_ComputeTurnToPointRot(s16* rot, s16 rotMax, s16 target, f32 slowness, f32 stepMin, f32 stepMax) { + s16 prevRot = *rot; + f32 step; + f32 prevRotStep; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DCCC.s") + step = (f32)(target - *rot) * (360.0f / (f32)0x10000); + step *= gFramerateDivisorHalf; + prevRotStep = step; + if (step >= 0.0f) { + step /= slowness; + step = CLAMP(step, stepMin, stepMax); + *rot += (s16)((step * (f32)0x10000) / 360.0f); + if (prevRotStep < stepMin) { + *rot = target; + } + if (rotMax != 0) { + *rot = CLAMP(*rot, -rotMax, rotMax); + } + } else { + step = (step / slowness) * -1.0f; + step = CLAMP(step, stepMin, stepMax); + *rot -= (s16)((step * (f32)0x10000) / 360.0f); + if (-stepMin < prevRotStep) { + *rot = target; + } + if (rotMax != 0) { + *rot = CLAMP(*rot, -rotMax, rotMax); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DCE0.s") + return prevRot - *rot; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DE04.s") +/** + * Computes the necessary HeadRot and TorsoRot to smoothly turn an actors's head and torso to a point + * + * @param[in] point the point to turn to + * @param[in] focusPos the actor's focus postion + * @param[in] shapeRot the actor's shape rotation + * @param[in,out] turnTarget the intermediate target step that headRot and torsoRot step towards + * @param[in,out] headRot the computed head rotation + * @param[in,out] torsoRot the computed torso rotation + * @param[in] options various options to adjust how the actor turns, see `SubS_ComputeTurnToPointRot and + * TurnOptions/TurnOptionsSet` + * + */ +s32 SubS_TurnToPoint(Vec3f* point, Vec3f* focusPos, Vec3s* shapeRot, Vec3s* turnTarget, Vec3s* headRot, Vec3s* torsoRot, + TurnOptionsSet* options) { + s16 pitch; + s16 yaw; + s16 pad; + s16 targetY; + f32 diffX = point->x - focusPos->x; + s16 targetX; + f32 diffZ = point->z - focusPos->z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013DF3C.s") + yaw = Math_FAtan2F(diffZ, diffX); + pitch = Math_FAtan2F(sqrtf(SQ(diffX) + SQ(diffZ)), point->y - focusPos->y); + Math_SmoothStepToS(&turnTarget->x, pitch, 4, 0x2710, 0); + Math_SmoothStepToS(&turnTarget->y, yaw, 4, 0x2710, 0); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E054.s") + targetX = + SubS_ComputeTurnToPointRot(&headRot->x, options->headRotX.rotMax, turnTarget->x, options->headRotX.slowness, + options->headRotX.rotStepMin, options->headRotX.rotStepMax); + //! @bug: torsoRotX uses headRotX slowness + SubS_ComputeTurnToPointRot(&torsoRot->x, options->torsoRotX.rotMax, targetX, options->headRotX.slowness, + options->torsoRotX.rotStepMin, options->torsoRotX.rotStepMax); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E07C.s") + targetY = turnTarget->y - shapeRot->y; + SubS_ComputeTurnToPointRot(&headRot->y, options->headRotY.rotMax, targetY - torsoRot->y, options->headRotY.slowness, + options->headRotY.rotStepMin, options->headRotY.rotStepMax); + SubS_ComputeTurnToPointRot(&torsoRot->y, options->torsoRotY.rotMax, targetY - headRot->y, + options->torsoRotY.slowness, options->torsoRotY.rotStepMin, + options->torsoRotY.rotStepMax); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E0A4.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E1C8.s") +s32 SubS_AngleDiffLessEqual(s16 angleA, s16 threshold, s16 angleB) { + return (ABS_ALT(BINANG_SUB(angleB, angleA)) <= threshold) ? true : false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E2D4.s") +Path* SubS_GetPathByIndex(GlobalContext* globalCtx, s16 pathIndex, s16 max) { + return (pathIndex != max) ? &globalCtx->setupPathList[pathIndex] : NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E3B8.s") +s32 SubS_CopyPointFromPath(Path* path, s32 pointIndex, Vec3f* dst) { + Vec3s* point; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E4B0.s") + if (path == NULL) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E5CC.s") + point = Lib_SegmentedToVirtual(path->points); + point = &point[pointIndex]; + dst->x = point->x; + dst->y = point->y; + dst->z = point->z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E640.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E748.s") +s16 SubS_GetDistSqAndOrientPoints(Vec3f* vecA, Vec3f* vecB, f32* distSq) { + f32 diffX = vecA->x - vecB->x; + f32 diffZ = vecA->z - vecB->z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E7C0.s") + *distSq = SQ(diffX) + SQ(diffZ); + return Math_Atan2S(diffX, diffZ); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E8F8.s") +/** + * Returns true when the actor has reached the inputed point + */ +s32 SubS_MoveActorToPoint(Actor* actor, Vec3f* point, s16 rotStep) { + Vec3f offsetBefore; + Vec3f offsetAfter; + f32 distSqBefore; + f32 distSqAfter; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E950.s") + Actor_OffsetOfPointInActorCoords(actor, &offsetBefore, point); + Math_SmoothStepToS(&actor->world.rot.y, SubS_GetDistSqAndOrientPoints(point, &actor->world.pos, &distSqBefore), 4, + rotStep, 1); + actor->shape.rot.y = actor->world.rot.y; + Actor_MoveWithGravity(actor); + Actor_OffsetOfPointInActorCoords(actor, &offsetAfter, point); + SubS_GetDistSqAndOrientPoints(point, &actor->world.pos, &distSqAfter); + return ((offsetBefore.z > 0.0f) && (offsetAfter.z <= 0.0f)) ? true : false; +} + +s16 SubS_GetDistSqAndOrientPath(Path* path, s32 pointIndex, Vec3f* pos, f32* distSq) { + Vec3s* point; + f32 diffX = 0.0f; + f32 diffZ = 0.0f; + + if (path != NULL) { + point = Lib_SegmentedToVirtual(path->points); + point = &point[pointIndex]; + diffX = point->x - pos->x; + diffZ = point->z - pos->z; + } + + *distSq = SQ(diffX) + SQ(diffZ); + return Math_Atan2S(diffX, diffZ); +} + +s8 SubS_IsObjectLoaded(s8 index, GlobalContext* globalCtx) { + return !Object_IsLoaded(&globalCtx->objectCtx, index) ? false : true; +} + +s8 SubS_GetObjectIndex(s16 id, GlobalContext* globalCtx) { + return Object_GetIndex(&globalCtx->objectCtx, id); +} + +/** + * 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.actorLists[actorCategory].first; + } + + while (actor != NULL && actorId != actor->id) { + actor = actor->next; + } + + return actor; +} + +s32 SubS_FillLimbRotTables(GlobalContext* globalCtx, s16* limbRotTableY, s16* limbRotTableZ, s32 numLimbs) { + s32 i; + u32 frames = globalCtx->gameplayFrames; + + for (i = 0; i < numLimbs; i++) { + limbRotTableY[i] = (i * 50 + 0x814) * frames; + limbRotTableZ[i] = (i * 50 + 0x940) * frames; + } + + return true; +} + +s32 SubS_IsFloorAbove(GlobalContext* globalCtx, Vec3f* pos, f32 distAbove) { + CollisionPoly* outPoly; + Vec3f posA; + Vec3f posB; + Vec3f posResult; + s32 bgId; + + posA = posB = *pos; + posB.y += distAbove; + return BgCheck_EntityLineTest1(&globalCtx->colCtx, &posA, &posB, &posResult, &outPoly, false, true, false, true, + &bgId); +} + +s32 SubS_CopyPointFromPathList(Path* paths, s32 pathIndex, s32 pointIndex, Vec3f* dst) { + Path* path = &paths[pathIndex]; + Vec3s* point = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[pointIndex]; + + dst->x = point->x; + dst->y = point->y; + dst->z = point->z; + + return false; +} + +u8 SubS_GetPathCount(Path* paths, s32 index) { + Path* path = &paths[index]; + + return path->count; +} + +void SubS_ActorPathing_Init(GlobalContext* globalCtx, Vec3f* worldPos, Actor* actor, ActorPathing* actorPath, + Path* paths, s32 pathIndex, s32 begPointIndex, s32 endPointIndex, s32 curPointIndex, + u8 flags) { + Path* path; + + actorPath->setupPathList = globalCtx->setupPathList; + actorPath->pathIndex = pathIndex; + path = &paths[pathIndex]; + actorPath->points = Lib_SegmentedToVirtual(path->points); + actorPath->count = path->count; + actorPath->begPointIndex = begPointIndex; + if (endPointIndex == 0) { + actorPath->endPointIndex = actorPath->count - 1; + } else if (endPointIndex > 0) { + actorPath->endPointIndex = endPointIndex; + } else { + //! @bug: endPointIndex is negative, subtraction causes result to be past the end + actorPath->endPointIndex = (actorPath->count - endPointIndex) - 1; + } + actorPath->curPointIndex = curPointIndex; + actorPath->curPoint.x = actorPath->points[0].x; + actorPath->curPoint.y = actorPath->points[0].y; + actorPath->curPoint.z = actorPath->points[0].z; + Math_Vec3f_Copy(&actorPath->prevPoint, &actorPath->curPoint); + actorPath->worldPos = worldPos; + actorPath->actor = actor; + actorPath->flags = flags; + actorPath->prevFlags = flags; +} + +s32 SubS_ActorPathing_Update(GlobalContext* globalCtx, ActorPathing* actorPath, + ActorPathingComputeFunc computePointInfoFunc, ActorPathingUpdateFunc updateActorInfoFunc, + ActorPathingUpdateFunc moveFunc, ActorPathingUpdateFunc setNextPointFunc) { + s32 shouldSetNextPoint; + s32 reupdate; + + actorPath->computePointInfoFunc = computePointInfoFunc; + actorPath->updateActorInfoFunc = updateActorInfoFunc; + actorPath->moveFunc = moveFunc; + actorPath->setNextPointFunc = setNextPointFunc; + actorPath->flags &= ~ACTOR_PATHING_REACHED_TEMPORARY; + reupdate = false; + if (actorPath->flags & ACTOR_PATHING_MOVE_BACKWARDS) { + if (!(actorPath->prevFlags & ACTOR_PATHING_MOVE_BACKWARDS)) { + actorPath->curPointIndex--; + } + } else if (actorPath->prevFlags & ACTOR_PATHING_MOVE_BACKWARDS) { + actorPath->curPointIndex++; + } + do { + shouldSetNextPoint = false; + if (actorPath->computePointInfoFunc != NULL) { + actorPath->computePointInfoFunc(globalCtx, actorPath); + } + if (actorPath->updateActorInfoFunc != NULL) { + shouldSetNextPoint = actorPath->updateActorInfoFunc(globalCtx, actorPath); + } + if (shouldSetNextPoint) { + if (actorPath->setNextPointFunc != NULL) { + reupdate = actorPath->setNextPointFunc(globalCtx, actorPath); + } + } else if (actorPath->moveFunc != NULL) { + reupdate = actorPath->moveFunc(globalCtx, actorPath); + } + } while (reupdate); + actorPath->prevFlags = actorPath->flags; + return false; +} + +void SubS_ActorPathing_ComputePointInfo(GlobalContext* globalCtx, ActorPathing* actorPath) { + Vec3f diff; + + actorPath->curPoint.x = actorPath->points[actorPath->curPointIndex].x + actorPath->pointOffset.x; + actorPath->curPoint.y = actorPath->points[actorPath->curPointIndex].y + actorPath->pointOffset.y; + actorPath->curPoint.z = actorPath->points[actorPath->curPointIndex].z + actorPath->pointOffset.z; + diff.x = actorPath->curPoint.x - actorPath->worldPos->x; + diff.y = actorPath->curPoint.y - actorPath->worldPos->y; + diff.z = actorPath->curPoint.z - actorPath->worldPos->z; + actorPath->distSqToCurPointXZ = Math3D_XZLengthSquared(diff.x, diff.z); + actorPath->distSqToCurPoint = Math3D_LengthSquared(&diff); + actorPath->rotToCurPoint.y = Math_FAtan2F(diff.z, diff.x); + actorPath->rotToCurPoint.x = Math_FAtan2F(sqrtf(actorPath->distSqToCurPointXZ), -diff.y); + actorPath->rotToCurPoint.z = 0; +} + +s32 SubS_ActorPathing_MoveWithGravity(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor_MoveWithGravity(actorPath->actor); + return false; +} + +s32 SubS_ActorPathing_MoveWithoutGravityReverse(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor_MoveWithoutGravityReverse(actorPath->actor); + return false; +} + +s32 SubS_ActorPathing_SetNextPoint(GlobalContext* globalCtx, ActorPathing* actorPath) { + s32 reupdate = true; + + Math_Vec3f_Copy(&actorPath->prevPoint, &actorPath->curPoint); + if (!(actorPath->flags & ACTOR_PATHING_MOVE_BACKWARDS)) { + if (actorPath->curPointIndex >= actorPath->endPointIndex) { + if (actorPath->flags & ACTOR_PATHING_RETURN_TO_START) { + actorPath->curPointIndex = actorPath->begPointIndex; + } else if (actorPath->flags & ACTOR_PATHING_SWITCH_DIRECTION) { + actorPath->flags |= ACTOR_PATHING_MOVE_BACKWARDS; + } else { + reupdate = false; + } + actorPath->flags |= ACTOR_PATHING_REACHED_END; + } else { + actorPath->curPointIndex++; + } + actorPath->flags |= ACTOR_PATHING_REACHED_POINT; + } else { + if (actorPath->begPointIndex >= actorPath->curPointIndex) { + if (actorPath->flags & ACTOR_PATHING_RETURN_TO_START) { + actorPath->curPointIndex = actorPath->endPointIndex; + } else if (actorPath->flags & ACTOR_PATHING_SWITCH_DIRECTION) { + actorPath->flags &= ~ACTOR_PATHING_MOVE_BACKWARDS; + } else { + reupdate = false; + } + actorPath->flags |= ACTOR_PATHING_REACHED_END; + } else { + actorPath->curPointIndex--; + } + } + actorPath->flags |= ACTOR_PATHING_REACHED_POINT; + return reupdate; +} + +void SubS_ChangeAnimationBySpeedInfo(SkelAnime* skelAnime, AnimationSpeedInfo* animations, s32 nextIndex, + s32* curIndex) { + AnimationSpeedInfo* animation = &animations[nextIndex]; + f32 startFrame = skelAnime->curFrame; + f32 endFrame; + f32 morphFrames; + + if ((*curIndex < 0) || (nextIndex == *curIndex)) { + morphFrames = 0.0f; + if (*curIndex < 0) { + startFrame = 0.0f; + } + } else { + morphFrames = animation->morphFrames; + if (nextIndex != *curIndex) { + startFrame = 0.0f; + } + } + if (animation->playSpeed >= 0.0f) { + endFrame = Animation_GetLastFrame(&animation->animation->common); + } else { + startFrame = Animation_GetLastFrame(&animation->animation->common); + endFrame = 0.0f; + } + Animation_Change(skelAnime, animation->animation, animation->playSpeed, startFrame, endFrame, animation->mode, + morphFrames); + *curIndex = nextIndex; +} + +s32 SubS_StartActorCutscene(Actor* actor, s16 nextCutscene, s16 curCutscene, s32 type) { + s32 isStarted = false; + + if ((curCutscene != -1) && (ActorCutscene_GetCurrentIndex() == curCutscene)) { + ActorCutscene_Stop(curCutscene); + ActorCutscene_SetIntentToPlay(nextCutscene); + } else if (ActorCutscene_GetCanPlayNext(nextCutscene)) { + switch (type) { + case SUBS_CUTSCENE_SET_UNK_LINK_FIELDS: + ActorCutscene_StartAndSetUnkLinkFields(nextCutscene, actor); + break; + case SUBS_CUTSCENE_NORMAL: + ActorCutscene_Start(nextCutscene, actor); + break; + case SUBS_CUTSCENE_SET_FLAG: + ActorCutscene_StartAndSetFlag(nextCutscene, actor); + break; + } + isStarted = true; + } else { + ActorCutscene_SetIntentToPlay(nextCutscene); + } + + return isStarted; +} + +s32 SubS_FillCutscenesList(Actor* actor, s16 cutscenes[], s16 numCutscenes) { + s16 cs; + s32 i; + + for (i = 0; i < numCutscenes; i++) { + cutscenes[i] = -1; + } + + cs = actor->cutscene; + i = 0; + + while (cs != -1) { + // Note: Infinite loop if numCutscenes is less than possible additional cutscenes + if (i < numCutscenes) { + cutscenes[i] = cs; + cs = ActorCutscene_GetAdditionalCutscene(cs); + i++; + } + } + + return i; +} + +/** + * Computes a plane based on a point on the plane, a unit vector and two angles + * + * @param[in] point a point on the plane + * @param[in] unitVec the unit vector rotated that becomes the plane's normal + * @param[in] rot the angles to rotate with, uses just the x and y components + * @param[out] plane the computed plane + * + * Notes: + * The unit input vector is expected to already be normalized (only uses are with the z unit vector) + * + */ +void SubS_ConstructPlane(Vec3f* point, Vec3f* unitVec, Vec3s* rot, Plane* plane) { + f32 sin; + f32 cos; + f32 temp; + f32 unitVecZ; + f32 normY; + f32 unitVecYX; + + sin = Math_SinS(-rot->x); + cos = Math_CosS(-rot->x); + unitVecZ = unitVec->z; + unitVecYX = unitVec->y; + + // Apply a rotation by -x about the X axis + temp = (unitVecZ * cos) - (unitVecYX * sin); + normY = (unitVecZ * sin) + (unitVecYX * cos); + + sin = Math_SinS(rot->y); + cos = Math_CosS(rot->y); + unitVecYX = unitVec->x; + plane->normal.y = normY; + + // Apply a rotation by y about the Y axis + plane->normal.z = (temp * cos) - (unitVecYX * sin); + plane->normal.x = (temp * sin) + (unitVecYX * cos); + + plane->originDist = -((point->x * plane->normal.x) + (plane->normal.y * point->y) + (plane->normal.z * point->z)); +} + +s32 SubS_LineSegVsPlane(Vec3f* point, Vec3s* rot, Vec3f* unitVec, Vec3f* linePointA, Vec3f* linePointB, + Vec3f* intersect) { + s32 lineSegVsPlane; + Plane plane; + + SubS_ConstructPlane(point, unitVec, rot, &plane); + lineSegVsPlane = Math3D_LineSegVsPlane(plane.normal.x, plane.normal.y, plane.normal.z, plane.originDist, linePointA, + linePointB, intersect, false); + + return lineSegVsPlane ? true : false; +} + +/** + * 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.actorLists[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; +} + +//! TODO: Needs docs with func_800B8500 +s32 func_8013E748(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exchangeItemId, void* data, + func_8013E748_VerifyFunc verifyFunc) { + s32 ret = false; + + if ((verifyFunc == NULL) || ((verifyFunc != NULL) && verifyFunc(globalCtx, actor, data))) { + ret = func_800B8500(actor, globalCtx, xzRange, yRange, exchangeItemId); + } + return ret; +} + +s32 SubS_ActorAndPlayerFaceEachOther(GlobalContext* globalCtx, Actor* actor, void* data) { + Player* player = GET_PLAYER(globalCtx); + Vec3s* yawTols = (Vec3s*)data; + s16 playerYaw = ABS(BINANG_SUB(Actor_YawBetweenActors(&player->actor, actor), player->actor.shape.rot.y)); + s16 actorYaw = ABS(BINANG_SUB(actor->yawTowardsPlayer, actor->shape.rot.y)); + s32 areFacing = false; + s32 actorYawTol = ABS(yawTols->y); + s32 playerYawTol; + + if (actorYaw < (s16)actorYawTol) { + playerYawTol = ABS(yawTols->x); + if (playerYaw < (s16)playerYawTol) { + areFacing = true; + } + } + + return areFacing; +} + +//! TODO: Needs docs with func_800B8500 +s32 func_8013E8F8(Actor* actor, GlobalContext* globalCtx, f32 xzRange, f32 yRange, s32 exhangeItemId, s16 playerYawTol, + s16 actorYawTol) { + Vec3s yawTols; + + yawTols.x = playerYawTol; + yawTols.y = actorYawTol; + return func_8013E748(actor, globalCtx, xzRange, yRange, exhangeItemId, &yawTols, SubS_ActorAndPlayerFaceEachOther); +} + +/** + * Computes the necessary HeadRot and TorsoRot steps to be added to the normal rotation to smoothly turn an actors's + * head and torso to a point + * + * @param[in] worldPos the actor's world position + * @param[in] focusPos the actor's focus position + * @param[in] shapeYRot the actor's shape's Y rotation + * @param[in] yawTarget the target point to determine desired yaw + * @param[in] pitchTarget the target point to determine desired pitch + * @param[in,out] headZRotStep the computed actors' head's Z rotation step + * @param[in,out] headXRotStep the computed actors' head's X rotation step + * @param[in,out] torsoZRotStep the computed actors' torso's Z rotation step + * @param[in,out] torsoXRotStep the computed actors' torso's X rotation step + * @param[in] headZRotStepMax the max head's Z rotation step + * @param[in] headXRotStepMax the max head's X rotation step + * @param[in] torsoZRotStepMax the max torso's Z rotation step + * @param[in] torsoXRotStepMax the max torso's X rotation step + */ +s32 SubS_TurnToPointStep(Vec3f* worldPos, Vec3f* focusPos, s16 shapeYRot, Vec3f* yawTarget, Vec3f* pitchTarget, + s16* headZRotStep, s16* headXRotStep, s16* torsoZRotStep, s16* torsoXRotStep, + u16 headZRotStepMax, u16 headXRotStepMax, u16 torsoZRotStepMax, u16 torsoXRotStepMax) { + s16 yaw = Math_Vec3f_Yaw(worldPos, yawTarget) - shapeYRot; + s16 pad; + s16 pad2; + s16 pitch = Math_Vec3f_Pitch(focusPos, pitchTarget); + + if (BINANG_ADD(headXRotStepMax, torsoXRotStepMax) >= (s16)ABS(yaw)) { + Math_ApproachS(headXRotStep, yaw - *torsoXRotStep, 4, 0x2AA8); + *headXRotStep = CLAMP(*headXRotStep, -headXRotStepMax, headXRotStepMax); + Math_ApproachS(torsoXRotStep, yaw - *headXRotStep, 4, 0x2AA8); + *torsoXRotStep = CLAMP(*torsoXRotStep, -torsoXRotStepMax, torsoXRotStepMax); + } else { + Math_ApproachS(headXRotStep, 0, 4, 0x2AA8); + Math_ApproachS(torsoXRotStep, 0, 4, 0x2AA8); + } + + if (BINANG_ADD(headZRotStepMax, torsoZRotStepMax) >= (s16)ABS(pitch)) { + Math_ApproachS(headZRotStep, pitch - *torsoZRotStep, 4, 0x2AA8); + *headZRotStep = CLAMP(*headZRotStep, -headZRotStepMax, headZRotStepMax); + Math_ApproachS(torsoZRotStep, pitch - *headZRotStep, 4, 0x2AA8); + *torsoZRotStep = CLAMP(*torsoZRotStep, -torsoZRotStepMax, torsoZRotStepMax); + } else { + Math_ApproachS(headZRotStep, 0, 4, 0x2AA8); + Math_ApproachS(torsoZRotStep, 0, 4, 0x2AA8); + } + + return true; +} diff --git a/src/code/z_view.c b/src/code/z_view.c index c325fd563..915c196b7 100644 --- a/src/code/z_view.c +++ b/src/code/z_view.c @@ -43,7 +43,7 @@ void View_Init(View* view, GraphicsContext* gfxCtx) { view->zFar = 12800.0f; view->eye.z = -1.0f; - View_InitCameraQuake(view); + View_InitDistortion(view); } void View_SetViewOrientation(View* view, Vec3f* eye, Vec3f* at, Vec3f* up) { @@ -187,87 +187,93 @@ void View_SetScissorForLetterbox(View* view) { CLOSE_DISPS(view->gfxCtx); } -s32 View_SetQuakeRotation(View* view, f32 x, f32 y, f32 z) { - view->quakeRot.x = x; - view->quakeRot.y = y; - view->quakeRot.z = z; +s32 View_SetDistortionDirRot(View* view, f32 dirRotX, f32 dirRotY, f32 dirRotZ) { + view->distortionDirRot.x = dirRotX; + view->distortionDirRot.y = dirRotY; + view->distortionDirRot.z = dirRotZ; return 1; } -s32 View_SetQuakeScale(View* view, f32 x, f32 y, f32 z) { - view->quakeScale.x = x; - view->quakeScale.y = y; - view->quakeScale.z = z; +s32 View_SetDistortionScale(View* view, f32 scaleX, f32 scaleY, f32 scaleZ) { + view->distortionScale.x = scaleX; + view->distortionScale.y = scaleY; + view->distortionScale.z = scaleZ; return 1; } -s32 View_SetQuakeSpeed(View* view, f32 speed) { - view->quakeSpeed = speed; +s32 View_SetDistortionSpeed(View* view, f32 speed) { + view->distortionSpeed = speed; return 1; } -s32 View_InitCameraQuake(View* view) { - view->quakeRot.x = 0.0f; - view->quakeRot.y = 0.0f; - view->quakeRot.z = 0.0f; - view->quakeScale.x = 1.0f; - view->quakeScale.y = 1.0f; - view->quakeScale.z = 1.0f; - view->currQuakeRot = view->quakeRot; - view->currQuakeScale = view->quakeScale; - view->quakeSpeed = 0.0f; +s32 View_InitDistortion(View* view) { + view->distortionDirRot.x = 0.0f; + view->distortionDirRot.y = 0.0f; + view->distortionDirRot.z = 0.0f; + view->distortionScale.x = 1.0f; + view->distortionScale.y = 1.0f; + view->distortionScale.z = 1.0f; + view->curDistortionDirRot = view->distortionDirRot; + view->curDistortionScale = view->distortionScale; + view->distortionSpeed = 0.0f; return 1; } -s32 View_ClearQuake(View* view) { - view->quakeRot.x = 0.0f; - view->quakeRot.y = 0.0f; - view->quakeRot.z = 0.0f; - view->quakeScale.x = 1.0f; - view->quakeScale.y = 1.0f; - view->quakeScale.z = 1.0f; - view->quakeSpeed = 1.0f; +s32 View_ClearDistortion(View* view) { + view->distortionDirRot.x = 0.0f; + view->distortionDirRot.y = 0.0f; + view->distortionDirRot.z = 0.0f; + view->distortionScale.x = 1.0f; + view->distortionScale.y = 1.0f; + view->distortionScale.z = 1.0f; + view->distortionSpeed = 1.0f; return 1; } -s32 View_SetQuake(View* view, Vec3f rot, Vec3f scale, f32 speed) { - view->quakeRot = rot; - view->quakeScale = scale; - view->quakeSpeed = speed; +s32 View_SetDistortion(View* view, Vec3f dirRot, Vec3f scale, f32 speed) { + view->distortionDirRot = dirRot; + view->distortionScale = scale; + view->distortionSpeed = speed; return 1; } -s32 View_StepQuake(View* view, Mtx* matrix) { - MtxF mf; +s32 View_StepDistortion(View* view, Mtx* projectionMtx) { + MtxF projectionMtxF; - if (view->quakeSpeed == 0.0f) { - return 0; - } else if (view->quakeSpeed == 1.0f) { - view->currQuakeRot = view->quakeRot; - view->currQuakeScale = view->quakeScale; - view->quakeSpeed = 0.0f; + if (view->distortionSpeed == 0.0f) { + return false; + } else if (view->distortionSpeed == 1.0f) { + view->curDistortionDirRot = view->distortionDirRot; + view->curDistortionScale = view->distortionScale; + view->distortionSpeed = 0.0f; } else { - view->currQuakeRot.x += ((view->quakeRot.x - view->currQuakeRot.x) * view->quakeSpeed); - view->currQuakeRot.y += ((view->quakeRot.y - view->currQuakeRot.y) * view->quakeSpeed); - view->currQuakeRot.z += ((view->quakeRot.z - view->currQuakeRot.z) * view->quakeSpeed); + view->curDistortionDirRot.x = + F32_LERPIMP(view->curDistortionDirRot.x, view->distortionDirRot.x, view->distortionSpeed); + view->curDistortionDirRot.y = + F32_LERPIMP(view->curDistortionDirRot.y, view->distortionDirRot.y, view->distortionSpeed); + view->curDistortionDirRot.z = + F32_LERPIMP(view->curDistortionDirRot.z, view->distortionDirRot.z, view->distortionSpeed); - view->currQuakeScale.x += ((view->quakeScale.x - view->currQuakeScale.x) * view->quakeSpeed); - view->currQuakeScale.y += ((view->quakeScale.y - view->currQuakeScale.y) * view->quakeSpeed); - view->currQuakeScale.z += ((view->quakeScale.z - view->currQuakeScale.z) * view->quakeSpeed); + view->curDistortionScale.x = + F32_LERPIMP(view->curDistortionScale.x, view->distortionScale.x, view->distortionSpeed); + view->curDistortionScale.y = + F32_LERPIMP(view->curDistortionScale.y, view->distortionScale.y, view->distortionSpeed); + view->curDistortionScale.z = + F32_LERPIMP(view->curDistortionScale.z, view->distortionScale.z, view->distortionSpeed); } - 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_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_RotateStateAroundXAxis(-view->currQuakeRot.x); - Matrix_ToMtx(matrix); + Matrix_MtxToMtxF(projectionMtx, &projectionMtxF); + Matrix_Put(&projectionMtxF); + Matrix_RotateXFApply(view->curDistortionDirRot.x); + Matrix_RotateYF(view->curDistortionDirRot.y, MTXMODE_APPLY); + Matrix_RotateZF(view->curDistortionDirRot.z, MTXMODE_APPLY); + Matrix_Scale(view->curDistortionScale.x, view->curDistortionScale.y, view->curDistortionScale.z, MTXMODE_APPLY); + Matrix_RotateZF(-view->curDistortionDirRot.z, MTXMODE_APPLY); + Matrix_RotateYF(-view->curDistortionDirRot.y, MTXMODE_APPLY); + Matrix_RotateXFApply(-view->curDistortionDirRot.x); + Matrix_ToMtx(projectionMtx); - return 1; + return true; } void View_RenderView(View* view, s32 uParm2) { @@ -309,8 +315,8 @@ s32 View_RenderToPerspectiveMatrix(View* view) { guPerspective(projection, &view->normal, view->fovy, aspect, view->zNear, view->zFar, view->scale); view->projection = *projection; - //! @bug: This cast of `projection` is invalid - View_StepQuake(view, (Mtx*)projection); + + View_StepDistortion(view, projection); gSPPerspNormalize(POLY_OPA_DISP++, view->normal); gSPMatrix(POLY_OPA_DISP++, projection, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); diff --git a/src/code/z_vismono.c b/src/code/z_vismono.c index 4e02a0af2..6c0d1ef22 100644 --- a/src/code/z_vismono.c +++ b/src/code/z_vismono.c @@ -1,4 +1,5 @@ #include "global.h" +#include "system_malloc.h" #pragma GLOBAL_ASM("asm/non_matchings/code/z_vismono/func_801418B0.s") diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 9e949beac..29d1a1aca 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -103,7 +103,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); if (globalCtx->envCtx.unk_11 == 0) { @@ -120,7 +120,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy SEGMENT_ROM_START(d2_cloud_static), size, 0, &skyboxCtx->loadQueue, NULL); } - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); osCreateMesgQueue(&skyboxCtx->loadQueue, &skyboxCtx->loadMsg, 1); size = SEGMENT_ROM_SIZE(d2_fine_pal_static); @@ -129,7 +129,7 @@ void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyTy DmaMgr_SendRequestImpl(&skyboxCtx->unk1C8, skyboxCtx->skyboxPaletteStaticSegment, SEGMENT_ROM_START(d2_fine_pal_static), size, 0, &skyboxCtx->loadQueue, NULL); - osRecvMesg(&skyboxCtx->loadQueue, NULL, 1); + osRecvMesg(&skyboxCtx->loadQueue, NULL, OS_MESG_BLOCK); } } @@ -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..326fcb3e2 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_Translate(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateXFApply(skyboxCtx->rotX); + Matrix_RotateYF(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_RotateZF(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_Translate(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateXFApply(skyboxCtx->rotX); + Matrix_RotateYF(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_RotateZF(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/flash/osFlash.c b/src/libultra/flash/osFlash.c new file mode 100644 index 000000000..edba06fc2 --- /dev/null +++ b/src/libultra/flash/osFlash.c @@ -0,0 +1,325 @@ +#include "ultra64.h" +#include "global.h" + +s32 framDeviceInfo[4]; +OSIoMesg framDeviceInfoQuery; +OSMesgQueue __osFlashMessageQ; +OSPiHandle __osFlashHandler; +OSMesg __osFlashMsgBuf; +s32 __osFlashVersion; +UNK_TYPE1 D_801FD0FC[0x14]; + +typedef enum { + FLASH_OLD, + FLASH_NEW, +} FlashVersion; + +u32 osFlashGetAddr(u32 pageNum) { + s32 addr = (__osFlashVersion == FLASH_OLD) ? pageNum << 6 : pageNum << 7; + + return addr; +} + +OSPiHandle* osFlashReInit(u8 latency, u8 pulse, u8 pageSize, u8 relDuration, u32 start) { + __osFlashHandler.baseAddress = RDRAM_UNCACHED | start; + __osFlashHandler.type++; + __osFlashHandler.latency = latency; + __osFlashHandler.pulse = pulse; + __osFlashHandler.pageSize = pageSize; + __osFlashHandler.relDuration = relDuration; + __osFlashHandler.domain = 1; + + return &__osFlashHandler; +} + +void osFlashChange(u32 flash_num) { + __osFlashHandler.baseAddress = RDRAM_UNCACHED | (FRAM_STATUS_REGISTER + (flash_num << 17)); + __osFlashHandler.type = 8 + flash_num; + + return; +} + +OSPiHandle* osFlashInit(void) { + u32 flashType; + u32 flashVendor; + + osCreateMesgQueue(&__osFlashMessageQ, &__osFlashMsgBuf, 1); + + if (__osFlashHandler.baseAddress == (RDRAM_UNCACHED | FRAM_BASE_ADDRESS)) { + return &__osFlashHandler; + } + + __osFlashHandler.type = 8; + __osFlashHandler.baseAddress = (RDRAM_UNCACHED | FRAM_BASE_ADDRESS); + __osFlashHandler.latency = 5; + __osFlashHandler.pulse = 12; + __osFlashHandler.pageSize = 15; + __osFlashHandler.relDuration = 2; + __osFlashHandler.domain = 1; + __osFlashHandler.speed = 0; + bzero(&__osFlashHandler.transferInfo, sizeof(__OSTranxInfo)); + + osEPiLinkHandle(&__osFlashHandler); + osFlashReadId(&flashType, &flashVendor); + + if (flashVendor == 0x00C2001E || flashVendor == 0x00C20001 || flashVendor == 0x00C20000) { + __osFlashVersion = FLASH_OLD; + } else { + __osFlashVersion = FLASH_NEW; + } + + return &__osFlashHandler; +} + +void osFlashReadStatus(u8* flashStatus) { + u32 outFlashStatus; + + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE); + // read status using IO + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus); + + // why twice ? + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE); + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &outFlashStatus); + + *flashStatus = outFlashStatus & 0xFF; + + return; +} + +void osFlashReadId(u32* flashType, u32* flashVendor) { + u8 flashStatus; + + // why read status? + osFlashReadStatus(&flashStatus); + + // select silicon id read mode + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_STATUS_AND_STATUS); + + // read silicon id using DMA + framDeviceInfoQuery.hdr.pri = 0; + framDeviceInfoQuery.hdr.retQueue = &__osFlashMessageQ; + framDeviceInfoQuery.dramAddr = framDeviceInfo; + framDeviceInfoQuery.devAddr = 0; + framDeviceInfoQuery.size = 8; + + osInvalDCache(framDeviceInfo, sizeof(framDeviceInfo)); + osEPiStartDma(&__osFlashHandler, &framDeviceInfoQuery, OS_READ); + osRecvMesg(&__osFlashMessageQ, NULL, OS_MESG_BLOCK); + + *flashType = framDeviceInfo[0]; + *flashVendor = framDeviceInfo[1]; + + return; +} + +void osFlashClearStatus(void) { + // select status mode + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_EXECUTE); + // clear status + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress, 0); + + return; +} + +s32 osFlashAllErase(void) { + u32 status; + OSTimer timer; + OSMesgQueue mq; + OSMesg msg; + + // start chip erase operation + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_UNK_ERASE_OPERATION); + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS); + + // wait for completion by polling erase-busy flag + osCreateMesgQueue(&mq, &msg, 1); + do { + osSetTimer(&timer, OS_USEC_TO_CYCLES(15000), 0, &mq, &msg); + osRecvMesg(&mq, &msg, OS_MESG_BLOCK); + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + } while ((status & 2) == 2); + + // check erase operation status, clear status + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + osFlashClearStatus(); + + if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) { + return 0; + } else { + return -1; + } +} + +void osFlashAllEraseThrough(void) { + // start chip erase operation + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_UNK_ERASE_OPERATION); + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS); +} + +s32 osFlashCheckEraseEnd(void) { + u8 status; + + // check if erase operation is completed + osFlashReadStatus(&status); + if ((status & 0x02) == 0x02) { + return 2; // busy + } else { + // check erase operation status, clear status + osFlashReadStatus(&status); + } + osFlashClearStatus(); + + if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) { + return 0; + } else { + return -1; + } +} + +s32 osFlashSectorErase(u32 pageNum) { + u32 status; + OSTimer timer; + OSMesgQueue mq; + OSMesg msg; + + // start sector erase operation + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET | pageNum); + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS); + + // wait for completion by polling erase-busy flag + osCreateMesgQueue(&mq, &msg, 1); + do { + osSetTimer(&timer, OS_USEC_TO_CYCLES(12500), 0, &mq, &msg); + osRecvMesg(&mq, &msg, OS_MESG_BLOCK); + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + } while ((status & 2) == 2); + + // check erase operation status, clear status + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + osFlashClearStatus(); + + if (((status & 0xFF) == 0x08) || ((status & 0xFF) == 0x48) || ((status & 0x08) == 0x08)) { + return 0; + } else { + return -1; + } +} + +void osFlashSectorEraseThrough(u32 pageNum) { + // start sector erase operation + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET | pageNum); + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_ERASE_AND_STATUS); +} + +s32 osFlashWriteBuffer(OSIoMesg* mb, s32 priority, void* dramAddr, OSMesgQueue* mq) { + s32 ret; + + // select load page mode + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, FRAM_COMMAND_SET_MODE_WRITE); + + // DMA 128-byte page + mb->hdr.pri = priority; + mb->hdr.retQueue = mq; + mb->dramAddr = dramAddr; + mb->devAddr = 0; + mb->size = 0x80; + + ret = osEPiStartDma(&__osFlashHandler, mb, OS_WRITE); + + return ret; +} + +s32 osFlashWriteArray(u32 pageNum) { + u32 status; + OSTimer timer; + OSMesgQueue mq; + OSMesg msg; + + // only needed for new flash ? + if (__osFlashVersion == FLASH_NEW) { + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_WRITE); + } + + // start program page operation + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_ERASE_SECTOR_OFFSET_AND_STATUS | pageNum); + + // wait for completion by polling write-busy flag + osCreateMesgQueue(&mq, &msg, 1); + do { + osSetTimer(&timer, OS_USEC_TO_CYCLES(200), 0, &mq, &msg); + osRecvMesg(&mq, &msg, OS_MESG_BLOCK); + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + } while ((status & 0x01) == 0x01); + + // check program operation status, clear status + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &status); + osFlashClearStatus(); + + if (((status & 0xFF) == 0x04) || ((status & 0xFF) == 0x44) || ((status & 0x04) == 0x04)) { + return 0; + } else { + return -1; + } +} + +s32 osFlashReadArray(OSIoMesg* mb, s32 priority, u32 pageNum, void* dramAddr, u32 pageCount, OSMesgQueue* mq) { + s32 ret; + u32 dummy; + u32 last_page; + u32 pages; + + // select read array mode + osEPiWriteIo(&__osFlashHandler, __osFlashHandler.baseAddress | FRAM_COMMAND_REGISTER, + FRAM_COMMAND_SET_MODE_READ_AND_STATUS); + + // dummy read to initiate "fast-page" reads ? + osEPiReadIo(&__osFlashHandler, __osFlashHandler.baseAddress, &dummy); + + // DMA requested pages + mb->hdr.pri = priority; + mb->hdr.retQueue = mq; + mb->dramAddr = dramAddr; + + last_page = pageNum + pageCount - 1; + + if ((last_page & 0xF00) != (pageNum & 0xF00)) { + + pages = 256 - (pageNum & 0xFF); + pageCount -= pages; + mb->size = pages << 7; + mb->devAddr = osFlashGetAddr(pageNum); + osEPiStartDma(&__osFlashHandler, mb, OS_READ); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + pageNum = (pageNum + 256) & 0xF00; + mb->dramAddr = (void*)((uintptr_t)mb->dramAddr + mb->size); + } + + while (pageCount > 256) { + pages = 256; + pageCount -= 256; + mb->size = pages << 7; + mb->devAddr = osFlashGetAddr(pageNum); + osEPiStartDma(&__osFlashHandler, mb, OS_READ); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + pageNum += 256; + mb->dramAddr = (void*)((uintptr_t)mb->dramAddr + mb->size); + } + + mb->size = pageCount << 7; + mb->devAddr = osFlashGetAddr(pageNum); + ret = osEPiStartDma(&__osFlashHandler, mb, OS_READ); + + return ret; +} diff --git a/src/libultra/gu/cosf.c b/src/libultra/gu/cosf.c index 72d154d70..65330e9a6 100644 --- a/src/libultra/gu/cosf.c +++ b/src/libultra/gu/cosf.c @@ -1,22 +1,25 @@ -#include "math.h" +#include "libc/math.h" #include "macros.h" -// A slightly tweaked form of the coefficients of the Maclaurin series of sine up to x^9 -// [https://mathworld.wolfram.com/MaclaurinSeries.html]. -// The commented versions do not match. +#pragma weak cosf = __cosf + +// Coefficients of a degree 9 polynomial approximation of sine. It is not the Maclaurin polynamial, but some as-yet +// undetermined more uniform approximation. static const du P[] = { - { 1.0 }, // 1 - { -0.16666659550427756 }, // -1/3! = 1/6 - { 0.008333066246082155 }, // 1/5! = 1/120 - { -0.0001980960290193795 }, // -1/7! = -1/5040 - { 0.000002605780637968037 }, // 1/9! = 1/362880 + { 1.0 }, + { -0.16666659550427756 }, + { 0.008333066246082155 }, + { -0.0001980960290193795 }, + { 0.000002605780637968037 }, }; static const du rpi = { 1 / 3.14159265358979323846 }; // 1/M_PI, "reciprocal of pi" +// pihi + pilo is the closest double to pi, this representation allows more precise calculations since pi itself is not +// an exact float static const du pihi = { 3.1415926218032837 }; -static const du pilo = { 3.178650954705639E-8 }; // pihi + pilo is the closest double to pi +static const du pilo = { 3.178650954705639E-8 }; static const fu zero = { 0x00000000 }; @@ -28,7 +31,7 @@ f32 __cosf(f32 x) { f32 absx; f64 dx; // x promoted to double f64 xSq; // square of dx - f64 polyApprox; // Most of Maclaurin polynomial of sin(x) of degree 9 + f64 polyApprox; // Most of the polynomial approximation to sin(x) f64 dn; // n promoted to double s32 n; // number of multiples of pi away from the first half-period f64 result; diff --git a/src/libultra/gu/guS2DInitBg.c b/src/libultra/gu/guS2DInitBg.c index f4a2606e4..d2e5a2b04 100644 --- a/src/libultra/gu/guS2DInitBg.c +++ b/src/libultra/gu/guS2DInitBg.c @@ -1,3 +1,25 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/guS2DInitBg/guS2DInitBg.s") +void guS2DInitBg(uObjBg* bg) { + u32 size; + s32 tmem = (bg->b.imageFmt == G_IM_FMT_CI) ? 0x100 : 0x200; + u16 shift = (6 - bg->b.imageSiz); + + if (bg->b.imageLoad == G_BGLT_LOADBLOCK) { + bg->b.tmemW = bg->b.imageW >> shift; + bg->b.tmemH = (tmem / bg->b.tmemW) * 4; + bg->b.tmemSizeW = bg->b.tmemW * 2; + bg->b.tmemSize = bg->b.tmemH * bg->b.tmemSizeW; + bg->b.tmemLoadSH = (bg->b.tmemSize >> 1) - 1; + bg->b.tmemLoadTH = (0x7FF / bg->b.tmemW) + 1; + } else { // G_BGLT_LOADTILE + bg->b.tmemW = (bg->b.frameW >> shift) + 3; + bg->b.tmemH = (tmem / bg->b.tmemW) * 4; + bg->b.tmemSizeW = (bg->b.imageW >> shift) * 2; + + size = bg->b.tmemH * bg->b.tmemSizeW; + bg->b.tmemSize = (size >> 16); + bg->b.tmemLoadSH = (size >> 0) & 0xFFFF; + bg->b.tmemLoadTH = bg->b.tmemH - 1; + } +} diff --git a/src/libultra/gu/normalize.c b/src/libultra/gu/normalize.c deleted file mode 100644 index 3fdbbe880..000000000 --- a/src/libultra/gu/normalize.c +++ /dev/null @@ -1,3 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/boot/normalize/guNormalize.s") diff --git a/src/libultra/gu/perspective.c b/src/libultra/gu/perspective.c index 2af2d6ac5..d3dab2ef4 100644 --- a/src/libultra/gu/perspective.c +++ b/src/libultra/gu/perspective.c @@ -7,7 +7,7 @@ void guPerspectiveF(float mf[4][4], u16* perspNorm, float fovy, float aspect, fl guMtxIdentF(mf); fovy *= 3.1415926 / 180.0; - cot = __cosf(fovy / 2) / __sinf(fovy / 2); + cot = cosf(fovy / 2) / sinf(fovy / 2); mf[0][0] = cot / aspect; mf[1][1] = cot; diff --git a/src/libultra/gu/position.c b/src/libultra/gu/position.c index 589d4f4a3..95bd65fe3 100644 --- a/src/libultra/gu/position.c +++ b/src/libultra/gu/position.c @@ -13,12 +13,12 @@ void guPositionF(f32 mf[4][4], f32 rot, f32 pitch, f32 yaw, f32 scale, f32 x, f3 pitch *= D_80134D00; yaw *= D_80134D00; - sinr = __sinf(rot); - cosr = __cosf(rot); - sinp = __sinf(pitch); - cosp = __cosf(pitch); - sinh = __sinf(yaw); - cosh = __cosf(yaw); + sinr = sinf(rot); + cosr = cosf(rot); + sinp = sinf(pitch); + cosp = cosf(pitch); + sinh = sinf(yaw); + cosh = cosf(yaw); mf[0][0] = (cosp * cosh) * scale; mf[0][1] = (cosp * sinh) * scale; diff --git a/src/libultra/gu/rotate.c b/src/libultra/gu/rotate.c index c79c733bb..11d00ff73 100644 --- a/src/libultra/gu/rotate.c +++ b/src/libultra/gu/rotate.c @@ -16,8 +16,8 @@ void guRotateF(float m[4][4], float a, float x, float y, float z) { a = a * D_80097F90; - sine = __sinf(a); - cosine = __cosf(a); + sine = sinf(a); + cosine = cosf(a); ab = x * y * (1 - cosine); bc = y * z * (1 - cosine); diff --git a/src/libultra/gu/sinf.c b/src/libultra/gu/sinf.c index 5f3455ec5..963bc2022 100644 --- a/src/libultra/gu/sinf.c +++ b/src/libultra/gu/sinf.c @@ -1,22 +1,25 @@ -#include "math.h" +#include "libc/math.h" #include "macros.h" -// A slightly tweaked form of the coefficients of the Maclaurin series of sine up to x^9 -// [https://mathworld.wolfram.com/MaclaurinSeries.html]. -// The commented versions do not match. +#pragma weak sinf = __sinf + +// Coefficients of a degree 9 polynomial approximation of sine. It is not the Maclaurin polynamial, but some as-yet +// undetermined more uniform approximation. static const du P[] = { - { 1.0 }, // 1 - { -0.16666659550427756 }, // -1/3! = 1/6 - { 0.008333066246082155 }, // 1/5! = 1/120 - { -0.0001980960290193795 }, // -1/7! = -1/5040 - { 0.000002605780637968037 }, // 1/9! = 1/362880 + { 1.0 }, + { -0.16666659550427756 }, + { 0.008333066246082155 }, + { -0.0001980960290193795 }, + { 0.000002605780637968037 }, }; static const du rpi = { 1 / 3.14159265358979323846 }; // 1/M_PI, "reciprocal of pi" +// pihi + pilo is the closest double to pi, this representation allows more precise calculations since pi itself is not +// an exact float static const du pihi = { 3.1415926218032837 }; -static const du pilo = { 3.178650954705639E-8 }; // pihi + pilo is the closest double to pi +static const du pilo = { 3.178650954705639E-8 }; static const fu zero = { 0x00000000 }; @@ -26,7 +29,7 @@ static const fu zero = { 0x00000000 }; f32 __sinf(f32 x) { f64 dx; // x promoted to double f64 xSq; // square of dx - f64 polyApprox; // Most of Maclaurin polynomial of sin(x) of degree 9 + f64 polyApprox; // Most of the polynomial approximation to sin(x) f64 dn; // n promoted to double s32 n; // number of multiples of pi away from the first half-period f64 result; diff --git a/src/libultra/gu/sins.c b/src/libultra/gu/sins.c index 69b3b7e39..39bc7ce0c 100644 --- a/src/libultra/gu/sins.c +++ b/src/libultra/gu/sins.c @@ -1,4 +1,4 @@ -#include "math.h" +#include "libc/math.h" static s16 sintable[0x400] = { 0x0000, 0x0032, 0x0064, 0x0096, 0x00C9, 0x00FB, 0x012D, 0x0160, 0x0192, 0x01C4, 0x01F7, 0x0229, 0x025B, 0x028E, diff --git a/src/libultra/gu/visetevent.c b/src/libultra/gu/visetevent.c index 2d2e4bd3b..3a14ccbc1 100644 --- a/src/libultra/gu/visetevent.c +++ b/src/libultra/gu/visetevent.c @@ -3,7 +3,7 @@ void osViSetEvent(OSMesgQueue* mq, OSMesg m, u32 retraceCount) { register u32 saveMask = __osDisableInt(); - __osViNext->msgq = mq; + __osViNext->mq = mq; __osViNext->msg = m; __osViNext->retraceCount = retraceCount; diff --git a/src/libultra/io/aigetlen.c b/src/libultra/io/aigetlen.c index e3e7289ac..58d8db487 100644 --- a/src/libultra/io/aigetlen.c +++ b/src/libultra/io/aigetlen.c @@ -1,5 +1,5 @@ #include "global.h" u32 osAiGetLength(void) { - return *(u32*)0xA4500004; + return HW_REG(AI_LEN_REG, u32); } diff --git a/src/libultra/io/aisetfreq.c b/src/libultra/io/aisetfreq.c index ef0a8d2de..8702941b9 100644 --- a/src/libultra/io/aisetfreq.c +++ b/src/libultra/io/aisetfreq.c @@ -1,3 +1,20 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/aisetfreq/osAiSetFrequency.s") +s32 osAiSetFrequency(u32 frequency) { + u8 bitrate; + f32 dacRateF = ((f32)osViClock / frequency) + 0.5f; + u32 dacRate = dacRateF; + + if (dacRate < 132) { + return -1; + } + + bitrate = (dacRate / 66); + if (bitrate > 16) { + bitrate = 16; + } + + HW_REG(AI_DACRATE_REG, u32) = dacRate - 1; + HW_REG(AI_BITRATE_REG, u32) = bitrate - 1; + return osViClock / (s32)dacRate; +} diff --git a/src/libultra/io/cartrominit.c b/src/libultra/io/cartrominit.c index 6b96905c7..0825b472c 100644 --- a/src/libultra/io/cartrominit.c +++ b/src/libultra/io/cartrominit.c @@ -1,3 +1,63 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/cartrominit/osCartRomInit.s") +OSPiHandle CartRomHandle; + +OSPiHandle* osCartRomInit(void) { + register u32 initialConfig; + register s32 status; + register u32 prevInt; + register u32 lastLatency; + register u32 lastPageSize; + register u32 lastRelDuration; + register u32 lastPulse; + + static s32 sCartRomNeedsInit = true; + + __osPiGetAccess(); + + if (!sCartRomNeedsInit) { + __osPiRelAccess(); + return &CartRomHandle; + } + + sCartRomNeedsInit = false; + CartRomHandle.type = DEVICE_TYPE_CART; + CartRomHandle.baseAddress = 0xB0000000; + CartRomHandle.domain = 0; + CartRomHandle.speed = 0; + bzero(&CartRomHandle.transferInfo, sizeof(__OSTranxInfo)); + + /* Uses `status & PI_STATUS_ERROR` in OoT */ + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + ; + } + + lastLatency = HW_REG(PI_BSD_DOM1_LAT_REG, u32); + lastPageSize = HW_REG(PI_BSD_DOM1_PGS_REG, u32); + lastRelDuration = HW_REG(PI_BSD_DOM1_RLS_REG, u32); + lastPulse = HW_REG(PI_BSD_DOM1_PWD_REG, u32); + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = 0xFF; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = 0; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = 3; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = 0xFF; + + initialConfig = HW_REG(CartRomHandle.baseAddress, u32); + CartRomHandle.latency = initialConfig & 0xFF; + CartRomHandle.pageSize = (initialConfig >> 0x10) & 0xF; + CartRomHandle.relDuration = (initialConfig >> 0x14) & 0xF; + CartRomHandle.pulse = (initialConfig >> 8) & 0xFF; + + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = lastLatency; + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = lastPageSize; + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = lastRelDuration; + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = lastPulse; + + prevInt = __osDisableInt(); + CartRomHandle.next = __osPiTable; + __osPiTable = &CartRomHandle; + __osRestoreInt(prevInt); + __osPiRelAccess(); + + return &CartRomHandle; +} 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 42009674f..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; @@ -27,7 +63,7 @@ s32 __osIdCheckSum(u16* ptr, u16* checkSum, u16* idSum) { s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) { s32 ret = 0; - u8 temp[BLOCKSIZE]; + u8 buf[BLOCKSIZE]; u8 comp[BLOCKSIZE]; u8 mask = 0; s32 i, j = 0; @@ -38,46 +74,60 @@ s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) { newid->serialMid = badid->serialMid; newid->serialLow = badid->serialLow; - if ((pfs->activebank != 0) && ((ret = __osPfsSelectBank(pfs, 0)) != 0)) { - return ret; + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } } do { - if ((ret = __osPfsSelectBank(pfs, j)) != 0) { + ret = __osPfsSelectBank(pfs, j); + if (ret != 0) { return ret; } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, 0, temp)) != 0) { + ret = __osContRamRead(pfs->queue, pfs->channel, 0, buf); + if (ret != 0) { return ret; } - temp[0] = j | 0x80; + buf[0] = j | 0x80; for (i = 1; i < BLOCKSIZE; i++) { - temp[i] = ~temp[i]; + buf[i] = ~buf[i]; } - if ((ret = __osContRamWrite(pfs->queue, pfs->channel, 0, temp, 0)) != 0) { + ret = __osContRamWrite(pfs->queue, pfs->channel, 0, buf, 0); + if (ret != 0) { return ret; } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, 0, comp)) != 0) { + + ret = __osContRamRead(pfs->queue, pfs->channel, 0, comp); + if (ret != 0) { return (ret); } + for (i = 0; i < BLOCKSIZE; i++) { - if (comp[i] != temp[i]) { + if (comp[i] != buf[i]) { break; } } + if (i != BLOCKSIZE) { break; } if (j > 0) { - if ((ret = __osPfsSelectBank(pfs, 0)) != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { return ret; } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, 0, temp)) != 0) { + + ret = __osContRamRead(pfs->queue, pfs->channel, 0, buf); + if (ret != 0) { return ret; } - if (temp[0] != 0x80) { + + if (buf[0] != 0x80) { break; } } @@ -85,8 +135,11 @@ s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) { j++; } while (j < PFS_MAX_BANKS); - if ((pfs->activebank != 0) && (ret = __osPfsSelectBank(pfs, 0)) != 0) { - return ret; + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } } mask = (j > 0) ? 1 : 0; @@ -99,16 +152,21 @@ s32 __osRepairPackId(OSPfs* pfs, __OSPackId* badid, __OSPackId* newid) { index[1] = PFS_ID_1AREA; index[2] = PFS_ID_2AREA; index[3] = PFS_ID_3AREA; + for (i = 0; i < 4; i++) { - if ((ret = __osContRamWrite(pfs->queue, pfs->channel, index[i], (u8*)newid, PFS_FORCE)) != 0) { + ret = __osContRamWrite(pfs->queue, pfs->channel, index[i], (u8*)newid, PFS_FORCE); + if (ret != 0) { return ret; } } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, temp)) != 0) { + + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, buf); + if (ret != 0) { return ret; } + for (i = 0; i < BLOCKSIZE; i++) { - if (temp[i] != *(u8*)((s32)newid + i)) { + if (buf[i] != *(u8*)((s32)newid + i)) { return PFS_ERR_DEVICE; } } @@ -123,8 +181,11 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) { s32 i; s32 j; - if ((pfs->activebank != 0) && (ret = __osPfsSelectBank(pfs, 0)) != 0) { - return ret; + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } } index[0] = PFS_ID_0AREA; @@ -132,7 +193,8 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) { index[2] = PFS_ID_2AREA; index[3] = PFS_ID_3AREA; for (i = 1; i < 4; i++) { - if ((ret = __osContRamRead(pfs->queue, pfs->channel, index[i], (u8*)check)) != 0) { + ret = __osContRamRead(pfs->queue, pfs->channel, index[i], (u8*)check); + if (ret != 0) { return ret; } __osIdCheckSum((u16*)check, &sum, &idSum); @@ -146,7 +208,8 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) { for (j = 0; j < 4; j++) { if (j != i) { - if ((ret = __osContRamWrite(pfs->queue, pfs->channel, index[j], (u8*)check, PFS_FORCE)) != 0) { + ret = __osContRamWrite(pfs->queue, pfs->channel, index[j], (u8*)check, PFS_FORCE); + if (ret != 0) { return ret; } } @@ -157,27 +220,30 @@ s32 __osCheckPackId(OSPfs* pfs, __OSPackId* check) { s32 __osGetId(OSPfs* pfs) { u16 sum; u16 isum; - u8 temp[BLOCKSIZE]; + u8 buf[BLOCKSIZE]; __OSPackId* id; __OSPackId newid; s32 ret; if (pfs->activebank != 0) { - if ((ret = __osPfsSelectBank(pfs, 0)) != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { return ret; } } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, temp)) != 0) { + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, buf); + if (ret != 0) { return ret; } - __osIdCheckSum((u16*)temp, &sum, &isum); - id = (__OSPackId*)temp; + __osIdCheckSum((u16*)buf, &sum, &isum); + id = (__OSPackId*)buf; if ((id->checksum != sum) || (id->invertedChecksum != isum)) { - if ((ret = __osCheckPackId(pfs, id)) == PFS_ERR_ID_FATAL) { + ret = __osCheckPackId(pfs, id); + if (ret == PFS_ERR_ID_FATAL) { ret = __osRepairPackId(pfs, id, &newid); - if (ret) { + if (ret != 0) { return ret; } id = &newid; @@ -186,13 +252,13 @@ s32 __osGetId(OSPfs* pfs) { } } - if ((id->deviceid & 0x01) == 0) { + if (!(id->deviceid & 1)) { ret = __osRepairPackId(pfs, id, &newid); if (ret) { return ret; } id = &newid; - if ((id->deviceid & 0x01) == 0) { + if (!(id->deviceid & 1)) { return PFS_ERR_DEVICE; } } @@ -210,7 +276,8 @@ s32 __osGetId(OSPfs* pfs) { pfs->minode_table = (1 + pfs->banks) * PFS_ONE_PAGE; pfs->dir_table = pfs->minode_table + (pfs->banks * PFS_ONE_PAGE); - if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_LABEL_AREA, pfs->label)) != 0) { + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_LABEL_AREA, pfs->label); + if (ret != 0) { return ret; } @@ -218,29 +285,32 @@ s32 __osGetId(OSPfs* pfs) { } s32 __osCheckId(OSPfs* pfs) { - u8 temp[BLOCKSIZE]; + u8 buf[BLOCKSIZE]; s32 ret; if (pfs->activebank != 0) { - ret = __osPfsSelectBank(pfs, 0); + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); if (ret == PFS_ERR_NEW_PACK) { - ret = __osPfsSelectBank(pfs, 0); + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); } if (ret != 0) { return ret; } } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, temp)) != 0) { + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, buf); + if (ret != 0) { if (ret != PFS_ERR_NEW_PACK) { return ret; } - if ((ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, temp)) != 0) { + + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, buf); + if (ret != 0) { return ret; } } - if (bcmp(pfs->id, temp, BLOCKSIZE) != 0) { + if (bcmp(pfs->id, buf, BLOCKSIZE) != 0) { return PFS_ERR_NEW_PACK; } @@ -259,8 +329,11 @@ s32 __osPfsRWInode(OSPfs* pfs, __OSInode* inode, u8 flag, u8 bank) { return 0; } - if ((pfs->activebank != 0) && (ret = __osPfsSelectBank(pfs, 0)) != 0) { - return ret; + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } } offset = ((bank > 0) ? 1 : pfs->inodeStartPage); diff --git a/src/libultra/io/contquery.c b/src/libultra/io/contquery.c index 5c351241a..a9a944f54 100644 --- a/src/libultra/io/contquery.c +++ b/src/libultra/io/contquery.c @@ -5,15 +5,15 @@ s32 osContStartQuery(OSMesgQueue* mq) { __osSiGetAccess(); - if (__osContLastCmd != 0) { + if (__osContLastPoll != 0) { __osPackRequestData(0); - __osSiRawStartDma(1, &__osContPifRam); + __osSiRawStartDma(OS_WRITE, &__osContPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); } - ret = __osSiRawStartDma(0, &__osContPifRam); + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); - __osContLastCmd = 0; + __osContLastPoll = 0; __osSiRelAccess(); diff --git a/src/libultra/io/contramread.c b/src/libultra/io/contramread.c index 420be9d89..d993b47d7 100644 --- a/src/libultra/io/contramread.c +++ b/src/libultra/io/contramread.c @@ -1,3 +1,63 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/contramread/__osContRamRead.s") +#define BLOCKSIZE 32 + +s32 __osPfsLastChannel = -1; + +s32 __osContRamRead(OSMesgQueue* ctrlrqueue, s32 channel, u16 addr, u8* buffer) { + s32 ret; + s32 i; + u8* bufptr; + s32 retryCount = 2; + + __osSiGetAccess(); + do { + bufptr = (u8*)&__osPfsPifRam; + + if ((__osContLastPoll != 2) || (__osPfsLastChannel != channel)) { + __osContLastPoll = 2; + __osPfsLastChannel = channel; + // clang-format off + for (i = 0; i < channel; i++) { *bufptr++ = 0; } + // clang-format on + __osPfsPifRam.status = 1; + ((__OSContRamReadFormat*)bufptr)->dummy = 0xFF; + ((__OSContRamReadFormat*)bufptr)->txsize = 3; + ((__OSContRamReadFormat*)bufptr)->rxsize = 0x21; + ((__OSContRamReadFormat*)bufptr)->cmd = CONT_CMD_READ_MEMPACK; // read mempak; send byte 0 + ((__OSContRamReadFormat*)bufptr)->datacrc = 0xFF; // read mempak; send byte 0 + // Received bytes are 6-26 inclusive + bufptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END; // End of commands + } else { + bufptr += channel; + } + + ((__OSContRamReadFormat*)bufptr)->hi = addr >> 3; // send byte 1 + ((__OSContRamReadFormat*)bufptr)->lo = (s8)(__osContAddressCrc(addr) | (addr << 5)); // send byte 2 + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK); + __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(ctrlrqueue, NULL, OS_MESG_BLOCK); + + ret = (((__OSContRamReadFormat*)bufptr)->rxsize & 0xC0) >> 4; + if (!ret) { + if (((__OSContRamReadFormat*)bufptr)->datacrc != __osContDataCrc(bufptr + 6)) { + ret = __osPfsGetStatus(ctrlrqueue, channel); + if (ret) { + break; + } + ret = 4; // Retry + } else { + bcopy(bufptr + 6, buffer, BLOCKSIZE); + } + } else { + ret = 1; // Error + } + if (ret != 4) { + break; + } + } while (0 <= retryCount--); + __osSiRelAccess(); + + return ret; +} diff --git a/src/libultra/io/contramwrite.c b/src/libultra/io/contramwrite.c index e6f96b1ef..b2157a2a5 100644 --- a/src/libultra/io/contramwrite.c +++ b/src/libultra/io/contramwrite.c @@ -1,3 +1,68 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/contramwrite/__osContRamWrite.s") +s32 __osContRamWrite(OSMesgQueue* mq, s32 channel, u16 address, u8* buffer, s32 force) { + s32 ret = 0; + s32 i; + u8* ptr; + s32 retry = 2; + u8 crc; + + if ((force != PFS_FORCE) && (address < PFS_LABEL_AREA) && (address != 0)) { + return 0; + } + + __osSiGetAccess(); + + do { + ptr = (u8*)(&__osPfsPifRam); + + if (__osContLastPoll != CONT_CMD_WRITE_MEMPACK || __osPfsLastChannel != channel) { + __osContLastPoll = CONT_CMD_WRITE_MEMPACK; + __osPfsLastChannel = channel; + + // clang-format off + for (i = 0; i < channel; i++) { *ptr++ = 0; } + // clang-format on + + __osPfsPifRam.status = 1; + + ((__OSContRamReadFormat*)ptr)->dummy = 0xFF; + ((__OSContRamReadFormat*)ptr)->txsize = 35; + ((__OSContRamReadFormat*)ptr)->rxsize = 1; + ((__OSContRamReadFormat*)ptr)->cmd = CONT_CMD_WRITE_MEMPACK; + ((__OSContRamReadFormat*)ptr)->datacrc = 0xFF; + + ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END; + } else { + ptr += channel; + } + ((__OSContRamReadFormat*)ptr)->hi = address >> 3; + ((__OSContRamReadFormat*)ptr)->lo = ((address << 5) | __osContAddressCrc(address)); + + bcopy(buffer, ((__OSContRamReadFormat*)ptr)->data, BLOCKSIZE); + + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + crc = __osContDataCrc(buffer); + osRecvMesg(mq, (OSMesg*)NULL, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, (OSMesg*)NULL, OS_MESG_BLOCK); + + ret = ((((__OSContRamReadFormat*)ptr)->rxsize & 0xC0) >> 4); + if (!ret) { + if (crc != ((__OSContRamReadFormat*)ptr)->datacrc) { + if ((ret = __osPfsGetStatus(mq, channel))) { + break; + } else { + ret = PFS_ERR_CONTRFAIL; + } + } + } else { + ret = PFS_ERR_NOPACK; + } + } while ((ret == PFS_ERR_CONTRFAIL) && (retry-- >= 0)); + __osSiRelAccess(); + + return ret; +} diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index 035663486..b54d894f3 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -6,14 +6,14 @@ s32 osContStartReadData(OSMesgQueue* mq) { __osSiGetAccess(); - if (__osContLastCmd != 1) { + if (__osContLastPoll != 1) { __osPackReadData(); - __osSiRawStartDma(1, &__osContPifRam); - osRecvMesg(mq, NULL, 1); + __osSiRawStartDma(OS_WRITE, &__osContPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); } - ret = __osSiRawStartDma(0, &__osContPifRam); - __osContLastCmd = 1; + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); + __osContLastPoll = 1; __osSiRelAccess(); @@ -47,7 +47,7 @@ void __osPackReadData() { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = 1; + __osContPifRam.status = 1; readformat.dummy = 255; readformat.txsize = 1; readformat.rxsize = 4; diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index 21e376d58..bd8270993 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -3,7 +3,7 @@ UNK_TYPE4 D_80097E40 = 0; OSPifRam __osContPifRam; -u8 __osContLastCmd; +u8 __osContLastPoll; u8 __osMaxControllers; OSTimer __osEepromTimer; @@ -34,34 +34,34 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { __osPackRequestData(0); - ret = __osSiRawStartDma(1, &__osContPifRam); - osRecvMesg(mq, &dummy, 1); + ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); - ret = __osSiRawStartDma(0, &__osContPifRam); - osRecvMesg(mq, &dummy, 1); + ret = __osSiRawStartDma(OS_READ, &__osContPifRam); + osRecvMesg(mq, &dummy, OS_MESG_BLOCK); __osContGetInitData(bitpattern, data); - __osContLastCmd = 0; + __osContLastPoll = 0; __osSiCreateAccessQueue(); - osCreateMesgQueue(&D_8009CF38, D_8009CF50, 1); + osCreateMesgQueue(&D_8009CF38, D_8009CF50, ARRAY_COUNT(D_8009CF50)); return ret; } void __osContGetInitData(u8* pattern, OSContStatus* data) { u8* ptr; - __OSContRequesFormat requestformat; - int i; + __OSContRequestHeader requestHeader; + s32 i; u8 bits; bits = 0; ptr = (u8*)__osContPifRam.ramarray; - for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestformat), data++) { - requestformat = *(__OSContRequesFormat*)ptr; - data->errno = (requestformat.rxsize & 0xc0) >> 4; + for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestHeader), data++) { + requestHeader = *(__OSContRequestHeader*)ptr; + data->errno = (requestHeader.rxsize & 0xc0) >> 4; if (data->errno == 0) { - data->type = requestformat.typel << 8 | requestformat.typeh; - data->status = requestformat.status; + data->type = requestHeader.typel << 8 | requestHeader.typeh; + data->status = requestHeader.status; bits |= 1 << i; } @@ -69,29 +69,29 @@ void __osContGetInitData(u8* pattern, OSContStatus* data) { *pattern = bits; } -void __osPackRequestData(u8 cmd) { +void __osPackRequestData(u8 poll) { u8* ptr; - __OSContRequesFormat requestformat; - int i; + __OSContRequestHeader requestHeader; + s32 i; for (i = 0; i < 0xF; i++) { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = 1; + __osContPifRam.status = 1; ptr = (u8*)__osContPifRam.ramarray; - requestformat.dummy = 255; - requestformat.txsize = 1; - requestformat.rxsize = 3; - requestformat.cmd = cmd; - requestformat.typeh = 255; - requestformat.typel = 255; - requestformat.status = 255; - requestformat.dummy1 = 255; + requestHeader.align = 255; + requestHeader.txsize = 1; + requestHeader.rxsize = 3; + requestHeader.poll = poll; + requestHeader.typeh = 255; + requestHeader.typel = 255; + requestHeader.status = 255; + requestHeader.align1 = 255; for (i = 0; i < __osMaxControllers; i++) { - *(__OSContRequesFormat*)ptr = requestformat; - ptr += sizeof(requestformat); + *(__OSContRequestHeader*)ptr = requestHeader; + ptr += sizeof(requestHeader); } *ptr = 254; } diff --git a/src/libultra/io/contsetch.c b/src/libultra/io/contsetch.c index bd1c96698..e2740489c 100644 --- a/src/libultra/io/contsetch.c +++ b/src/libultra/io/contsetch.c @@ -8,7 +8,7 @@ s32 osContSetCh(u8 ch) { } else { __osMaxControllers = ch; } - __osContLastCmd = -2; + __osContLastPoll = -2; __osSiRelAccess(); return 0; diff --git a/src/libultra/io/crc.c b/src/libultra/io/crc.c index a96843fc1..acae7b408 100644 --- a/src/libultra/io/crc.c +++ b/src/libultra/io/crc.c @@ -1,5 +1,160 @@ +/** + * File: crc.c + * Description: Functions to compute Cyclic Redundancy Check for specific addresses and data. + * + * CRC notes: + * + * General + * === + * - CRC (Cyclic Redundancy Check) is a way of verifying that no errors were introduced in transmitted data. + * - It reads the entire message and generates a check number that is appended to it. + * - A CRC is specified by the length `n` of the check number and a number (called the generator) smaller than `1 << n`. + * - Different generators have different error-checking capabilities. The choice of a generator is a sophisticated + * mathematical problem. + * + * Mathematical basis + * === + * - The algorithm is based on division of polynomials. The polynomials have coefficients in the field with two + * elements, 0 and 1, with addition given by XOR and multiplication by AND (it turns out this really is a field). + * Subtraction is the same as addition. + * - There is a one-to-one correspondence between binary polynomials and binary numbers: just evaluate the polynomial at + * 2, or write down an \f$ X^k \f$ corresponding to each `1 << k` the number is composed of. + * - The message bits `m{L}m{L-1}...m{1}m{0}` correspond to a polynomial \f$ m(X) = m_L X^L + m_{L-1} X^{L-1} + \dotsb + + * m_1 X^1 + m_0 X^0 \f$. We multiply this by \f$ X^n \f$ to make a space to insert the remainder at the end; this new + * polynomial will be the dividend. + * - The generator `p{n-1}p{n-2}...p{1}p{0}` corresponds to a polynomial \f$ p(X) = X^n + p_{n-1} X^{n-1} + \dotsb + p_1 + * X^1 + p_0 X^0 \f$: the leading term is omitted in the binary description because it is always \f$ X^n \f$. The + * generator polynomial is the divisor. + * - The usual division algorithm is followed: we look along the dividend until we see a nonzero coefficient, then + * subtract an appropriate multiple of the divisor to cancel it out. We repeat this until we reach the end of the + * number. + * - Arithmetic in the field with two elements is particularly simple: subtraction is identical to addition, so also + * given by XOR, and the only multipliers required for subtracting the divisor are \f$ X^k \f$. + * - After applying the algorithm, the output is a polynomial \f$ R(X) \f$ so that we have + * \f[ m(X) X^n = Q(X) p(X) + R(X) \f] + * (\f$ R(X) \f$ is the *remainder after dividing by \f$ p(X) \f$*). + * - Therefore, \f$ m(X) X^n - R(X) \f$ is divisible by the generator polynomial. This means that if we append the + * binary number corresponding to \f$ R(X) \f$ to the message and rerun the algorithm, we will get 0 if no errors have + * been introduced. + * + * + * Implementation + * === + * - We translate the binary polynomials to binary numbers by evaluating them at 2. The leading term in the generator + * polynomial is always \f$ X^n \f$, so we discard it to save space. In the binary field, subtraction is the same as + * addition, and given by XOR. Multiplication by \f$ X \f$ is given by shifting left. + * - Instead of fixing the message and moving the divisor polynomial right, we scan the message from the most + * significant digit, adding it to the end of the return value, (that is, for 1s, we shift and add 1, for 0s we just + * shift, effectively using the return value as a shift register). + * - When the return value has a 1 in the nth position (corresponding to the leading term in the generator polynomial), + * we binary-subtract (i.e. XOR) the return value with the generator polynomial's number. + * - This is repeated until we reach the end of the message. + * - Finally, to take into account the final multiplication by \f$ X^n \f$, we run another loop, which acts like we + * passed \f$ n \f$ more digits in the message that are all zero. Remember this gives us the extra space at the end for + * the check digits to be added. + * + * + * - To specify a CRC, at minimum we need the length of the check (i.e. the degree of the generator polynomial), \f$ n + * \f$, and the rest of the generator polynomial. This is usually expressed in the binary form, written as hex for + * compactness. Algorithms may also reverse or invert certain parts of the data or check to improve particular aspects + * of the algorithm, but the libultra functions use the simplest version. + * + * + * Resources + * === + * - Wikipedia: [Cyclic redundancy check](https://en.wikipedia.org/wiki/Cyclic_redundancy_check), and more specifically + * [Computation of cyclic redundancy checks](https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks) + * - Ben Eater has two videos on CRCs, the last two linked on [Error Detection | Ben Eater](https://eater.net/crc) + * - A page that specifically describes the same shift-register-style algorithms as libultra uses: [Understanding and + * implementing CRC (Cyclic Redundancy Check) calculation + * ](http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html) + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/crc/__osContAddressCrc.s") +#define ADDRESS_CRC_MESSAGE_LENGTH 10 +#define ADDRESS_CRC_LENGTH 5 +#define ADDRESS_CRC_GENERATOR 0x15 +#define ADDRESS_CRC_MASK ((1 << ADDRESS_CRC_LENGTH) - 1) -#pragma GLOBAL_ASM("asm/non_matchings/boot/crc/__osContDataCrc.s") +/** + * CRC-5 with the generating polynomial \f$ x^5 + x^4 + x^2 + 1 \f$, AKA 0x15 = 0b(1)1 0101. + * It only works on the bits from 0x7FF = 11 11111111, i.e. 10 bits. + * + * Usually used as __osContAddressCrc(addr) | (addr << 5) to add the CRC to the end. The overall length of 10 + 5 bits + * allows the address + CRC to fit into one s16. + * + * `addr` is the address of a block in the mempak, only valid up to 0x7FF. + */ +u8 __osContAddressCrc(u16 addr) { + u32 addr32 = addr; + u32 ret = 0; + u32 bit; + s32 i; + + // ret is used as a shift register for the CRC + for (bit = (1 << ADDRESS_CRC_MESSAGE_LENGTH); bit != 0; bit >>= 1) { + ret <<= 1; + if (addr32 & bit) { + if (ret & (1 << ADDRESS_CRC_LENGTH)) { + // Same as ret++; ret ^= 0x15 since last bit always 0 after the shift + ret ^= ADDRESS_CRC_GENERATOR - 1; + } else { + ret++; + } + } else if (ret & (1 << ADDRESS_CRC_LENGTH)) { + ret ^= ADDRESS_CRC_GENERATOR; + } + } + // Acts like 5 bits of 0s are appended to addr + for (i = 0; i < ADDRESS_CRC_LENGTH; i++) { + ret <<= 1; + if (ret & (1 << ADDRESS_CRC_LENGTH)) { + ret ^= ADDRESS_CRC_GENERATOR; + } + } + + // Discard the irrelevant bits above the actual remainder + return ret & ADDRESS_CRC_MASK; +} + +#define DATA_CRC_MESSAGE_BYTES 32 +#define DATA_CRC_LENGTH 8 +#define DATA_CRC_GENERATOR 0x85 + +/** + * CRC-8 with generating polynomial \f$ x^8 + x^7 + x^2 + 1 \f$, AKA 0x85 = 0b(1) 1000 0101. + * Expects exactly 0x20 = 32 bytes of data. + */ +u8 __osContDataCrc(u8* data) { + s32 ret = 0; + u32 bit; + u32 byte; + + for (byte = DATA_CRC_MESSAGE_BYTES; byte != 0; byte--, data++) { + // Loop over each bit in the byte starting with most significant + for (bit = (1 << (DATA_CRC_LENGTH - 1)); bit != 0; bit >>= 1) { + ret <<= 1; + if (*data & bit) { + if (ret & (1 << DATA_CRC_LENGTH)) { + // Same as ret++; ret ^= 0x85 since last bit always 0 after the shift + ret ^= DATA_CRC_GENERATOR - 1; + } else { + ret++; + } + } else if (ret & (1 << DATA_CRC_LENGTH)) { + ret ^= DATA_CRC_GENERATOR; + } + } + } + // Act like a byte of zeros is appended to data + do { + ret <<= 1; + if (ret & (1 << DATA_CRC_LENGTH)) { + ret ^= DATA_CRC_GENERATOR; + } + byte++; + } while (byte < DATA_CRC_LENGTH); + + // Discarding the excess is done automatically by the return type + return ret; +} diff --git a/src/libultra/io/dpgetstat.c b/src/libultra/io/dpgetstat.c index 763c6622e..0c4b3073b 100644 --- a/src/libultra/io/dpgetstat.c +++ b/src/libultra/io/dpgetstat.c @@ -1,5 +1,5 @@ #include "global.h" u32 osDpGetStatus(void) { - return *(u32*)0xA410000C; + return HW_REG(DPC_STATUS_REG, u32); } diff --git a/src/libultra/io/dpsetstat.c b/src/libultra/io/dpsetstat.c index c653a0817..d2655626c 100644 --- a/src/libultra/io/dpsetstat.c +++ b/src/libultra/io/dpsetstat.c @@ -1,5 +1,5 @@ #include "global.h" void osDpSetStatus(u32 data) { - *(u32*)0xA410000C = data; + HW_REG(DPC_STATUS_REG, u32) = data; } diff --git a/src/libultra/io/epidma.c b/src/libultra/io/epidma.c index d3e0e36d2..0b8c847d6 100644 --- a/src/libultra/io/epidma.c +++ b/src/libultra/io/epidma.c @@ -16,9 +16,9 @@ s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) { } if (mb->hdr.pri == 1) { - result = osJamMesg(osPiGetCmdQueue(), mb, 0); + result = osJamMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } else { - result = osSendMesg(osPiGetCmdQueue(), mb, 0); + result = osSendMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); } return result; } diff --git a/src/libultra/io/epirawdma.c b/src/libultra/io/epirawdma.c index f9e2e0f97..cbe43ce82 100644 --- a/src/libultra/io/epirawdma.c +++ b/src/libultra/io/epirawdma.c @@ -1,3 +1,70 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/epirawdma/__osEPiRawStartDma.s") +s32 __osEPiRawStartDma(OSPiHandle* handle, s32 direction, u32 cartAddr, void* dramAddr, size_t size) { + s32 status; + OSPiHandle* curHandle; + + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + ; + } + + if (__osCurrentHandle[handle->domain]->type != handle->type) { + curHandle = __osCurrentHandle[handle->domain]; + + if (handle->domain == 0) { + if (curHandle->latency != handle->latency) { + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency; + } + + if (curHandle->pageSize != handle->pageSize) { + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize; + } + + if (curHandle->relDuration != handle->relDuration) { + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration; + } + + if (curHandle->pulse != handle->pulse) { + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse; + } + } else { + if (curHandle->latency != handle->latency) { + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency; + } + + if (curHandle->pageSize != handle->pageSize) { + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize; + } + + if (curHandle->relDuration != handle->relDuration) { + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration; + } + + if (curHandle->pulse != handle->pulse) { + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse; + } + } + + curHandle->type = handle->type; + curHandle->latency = handle->latency; + curHandle->pageSize = handle->pageSize; + curHandle->relDuration = handle->relDuration; + curHandle->pulse = handle->pulse; + } + + HW_REG(PI_DRAM_ADDR_REG, void*) = (void*)osVirtualToPhysical(dramAddr); + HW_REG(PI_CART_ADDR_REG, void*) = (void*)((handle->baseAddress | cartAddr) & 0x1fffffff); + + switch (direction) { + case OS_READ: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; + break; + case OS_WRITE: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; + break; + default: + return -1; + } + + return 0; +} diff --git a/src/libultra/io/epirawread.c b/src/libultra/io/epirawread.c index e910cee4d..df0c6b603 100644 --- a/src/libultra/io/epirawread.c +++ b/src/libultra/io/epirawread.c @@ -1,3 +1,57 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/epirawread/__osEPiRawReadIo.s") +s32 __osEPiRawReadIo(OSPiHandle* handle, uintptr_t devAddr, u32* data) { + s32 status; + OSPiHandle* curHandle; + + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) { + ; + } + + if (__osCurrentHandle[handle->domain]->type != handle->type) { + curHandle = __osCurrentHandle[handle->domain]; + + if (handle->domain == 0) { + if (curHandle->latency != handle->latency) { + HW_REG(PI_BSD_DOM1_LAT_REG, u32) = handle->latency; + } + + if (curHandle->pageSize != handle->pageSize) { + HW_REG(PI_BSD_DOM1_PGS_REG, u32) = handle->pageSize; + } + + if (curHandle->relDuration != handle->relDuration) { + HW_REG(PI_BSD_DOM1_RLS_REG, u32) = handle->relDuration; + } + + if (curHandle->pulse != handle->pulse) { + HW_REG(PI_BSD_DOM1_PWD_REG, u32) = handle->pulse; + } + } else { + if (curHandle->latency != handle->latency) { + HW_REG(PI_BSD_DOM2_LAT_REG, u32) = handle->latency; + } + + if (curHandle->pageSize != handle->pageSize) { + HW_REG(PI_BSD_DOM2_PGS_REG, u32) = handle->pageSize; + } + + if (curHandle->relDuration != handle->relDuration) { + HW_REG(PI_BSD_DOM2_RLS_REG, u32) = handle->relDuration; + } + + if (curHandle->pulse != handle->pulse) { + HW_REG(PI_BSD_DOM2_PWD_REG, u32) = handle->pulse; + } + } + + curHandle->type = handle->type; + curHandle->latency = handle->latency; + curHandle->pageSize = handle->pageSize; + curHandle->relDuration = handle->relDuration; + curHandle->pulse = handle->pulse; + } + + *data = HW_REG(handle->baseAddress | devAddr, u32); + return 0; +} diff --git a/src/libultra/io/epirawwrite.c b/src/libultra/io/epirawwrite.c index 7c5701e0d..1e0e694a7 100644 --- a/src/libultra/io/epirawwrite.c +++ b/src/libultra/io/epirawwrite.c @@ -1,12 +1,10 @@ #include "global.h" -s32 __osEPiRawWriteIo(OSPiHandle* handle, u32 devAddr, u32 data) { +s32 __osEPiRawWriteIo(OSPiHandle* handle, uintptr_t devAddr, u32 data) { s32 status; OSPiHandle* curHandle; - while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY | PI_STATUS_ERROR)) { - ; - } + while (status = HW_REG(PI_STATUS_REG, u32), status & (PI_STATUS_BUSY | PI_STATUS_IOBUSY)) {} if (__osCurrentHandle[handle->domain]->type != handle->type) { curHandle = __osCurrentHandle[handle->domain]; diff --git a/src/libultra/io/epiread.c b/src/libultra/io/epiread.c index efab23bbb..5a2205bdc 100644 --- a/src/libultra/io/epiread.c +++ b/src/libultra/io/epiread.c @@ -1,3 +1,11 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/epiread/osEPiReadIo.s") +s32 osEPiReadIo(OSPiHandle* handle, uintptr_t devAddr, u32* data) { + register s32 ret; + + __osPiGetAccess(); + ret = __osEPiRawReadIo(handle, devAddr, data); + __osPiRelAccess(); + + return ret; +} diff --git a/src/libultra/io/epiwrite.c b/src/libultra/io/epiwrite.c index a44fd169d..213250741 100644 --- a/src/libultra/io/epiwrite.c +++ b/src/libultra/io/epiwrite.c @@ -1,3 +1,11 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/epiwrite/osEPiWriteIo.s") +s32 osEPiWriteIo(OSPiHandle* handle, uintptr_t devAddr, u32 data) { + register s32 ret; + + __osPiGetAccess(); + ret = __osEPiRawWriteIo(handle, devAddr, data); + __osPiRelAccess(); + + return ret; +} diff --git a/src/libultra/io/motor.c b/src/libultra/io/motor.c index 25254c61b..649a8b368 100644 --- a/src/libultra/io/motor.c +++ b/src/libultra/io/motor.c @@ -1,12 +1,16 @@ -#include "ultra64.h" -#include "global.h" +#include "ultra64/motor.h" + +#include "io/controller.h" +#include "functions.h" #define BANK_ADDR 0x400 #define MOTOR_ID 0x80 +OSPifRam osPifBuffers[MAXCONTROLLERS]; + s32 __osPfsSelectBank(OSPfs* pfs, u8 bank); -s32 osSetRumble(OSPfs* pfs, u32 vibrate) { +s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) { s32 i; s32 ret; u8* buf = (u8*)&osPifBuffers[pfs->channel]; @@ -16,13 +20,13 @@ s32 osSetRumble(OSPfs* pfs, u32 vibrate) { } __osSiGetAccess(); - osPifBuffers[pfs->channel].pifstatus = 1; + osPifBuffers[pfs->channel].status = 1; buf += pfs->channel; for (i = 0; i < BLOCKSIZE; i++) { ((__OSContRamReadFormat*)buf)->data[i] = vibrate; } - __osContLastCmd = CONT_CMD_END; + __osContLastPoll = CONT_CMD_END; __osSiRawStartDma(OS_WRITE, &osPifBuffers[pfs->channel]); osRecvMesg(pfs->queue, NULL, OS_MESG_BLOCK); __osSiRawStartDma(OS_READ, &osPifBuffers[pfs->channel]); @@ -45,10 +49,11 @@ s32 osSetRumble(OSPfs* pfs, u32 vibrate) { return ret; } -void osSetUpMempakWrite(u32 channel, OSPifRam* buf) { + +void _MakeMotorData(s32 channel, OSPifRam* buf) { u8* bufptr = (u8*)buf; __OSContRamReadFormat mempakwr; - u32 i; + s32 i; mempakwr.dummy = 0xFF; mempakwr.txsize = 0x23; @@ -68,7 +73,7 @@ void osSetUpMempakWrite(u32 channel, OSPifRam* buf) { *bufptr = 0xFE; } -s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, OSPfs* pfs, u32 channel) { +s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel) { s32 ret; u8 sp24[BLOCKSIZE]; @@ -111,8 +116,8 @@ s32 osProbeRumblePak(OSMesgQueue* ctrlrqueue, OSPfs* pfs, u32 channel) { if (sp24[BLOCKSIZE - 1] != MOTOR_ID) { return 0xB; } - if ((pfs->status & PFS_MOTOR_INITIALIZED) == 0) { - osSetUpMempakWrite(channel, &osPifBuffers[channel]); + if (!(pfs->status & PFS_MOTOR_INITIALIZED)) { + _MakeMotorData(channel, &osPifBuffers[channel]); } pfs->status = PFS_MOTOR_INITIALIZED; diff --git a/src/libultra/io/osViModeMpalLan1.c b/src/libultra/io/osViModeMpalLan1.c new file mode 100644 index 000000000..c7c09f659 --- /dev/null +++ b/src/libultra/io/osViModeMpalLan1.c @@ -0,0 +1,34 @@ +#include "global.h" + +OSViMode osViModeMpalLan1 = { + OS_VI_MPAL_LAN1, // type + { + // comRegs + 0x311E, // ctrl + SCREEN_WIDTH, // width + 0x4651E39, // burst + 0x20D, // vSync + 0x40C11, // hSync + 0xC190C1A, // leap + 0x6C02EC, // hStart + 0x200, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x280, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + }, + { + // [1] + 0x280, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + } }, +}; diff --git a/src/libultra/io/osViModeNtscHpf1.c b/src/libultra/io/osViModeNtscHpf1.c new file mode 100644 index 000000000..ac0a1fa2b --- /dev/null +++ b/src/libultra/io/osViModeNtscHpf1.c @@ -0,0 +1,34 @@ +#include "global.h" + +OSViMode osViModeNtscHpf1 = { + OS_VI_NTSC_HPF1, // type + { + // comRegs + 0x324E, // ctrl + 640, // width + 0x3E52239, // burst + 0x20C, // vSync + 0xC15, // hSync + 0xC150C15, // leap + 0x6C02EC, // hStart + 0x400, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x500, // origin + 0x2000800, // yScale + 0x2301FD, // vStart + 0xE0204, // vBurst + 2, // vIntr + }, + { + // [1] + 0xA00, // origin + 0x2000800, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2 // vIntr + } }, +}; diff --git a/src/libultra/io/osViModeNtscLan1.c b/src/libultra/io/osViModeNtscLan1.c new file mode 100644 index 000000000..632d763f4 --- /dev/null +++ b/src/libultra/io/osViModeNtscLan1.c @@ -0,0 +1,34 @@ +#include "global.h" + +OSViMode osViModeNtscLan1 = { + OS_VI_NTSC_LAN1, // type + { + // comRegs + 0x311E, // ctrl + SCREEN_WIDTH, // width + 0x3E52239, // burst + 0x20D, // vSync + 0xC15, // hSync + 0xC150C15, // leap + 0x6C02EC, // hStart + 0x200, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x280, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + }, + { + // [1] + 0x280, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + } }, +}; diff --git a/src/libultra/io/osViModePalLan1.c b/src/libultra/io/osViModePalLan1.c new file mode 100644 index 000000000..174cbf142 --- /dev/null +++ b/src/libultra/io/osViModePalLan1.c @@ -0,0 +1,34 @@ +#include "global.h" + +OSViMode osViModePalLan1 = { + OS_VI_PAL_LAN1, // type + { + // comRegs + 0x311E, // ctrl + SCREEN_WIDTH, // width + 0x4541E3A, // burst + 0x271, // vSync + 0x170C69, // hSync + 0xC6F0C6D, // leap + 0x800300, // hStart + 0x200, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x280, // origin + 0x400, // yScale + 0x5F0239, // vStart + 0x9026B, // vBurst + 2, // vIntr + }, + { + // [1] + 0x280, // origin + 0x400, // yScale + 0x5F0239, // vStart + 0x9026B, // vBurst + 2 // vIntr + } }, +}; diff --git a/src/libultra/io/pfsallocatefile.c b/src/libultra/io/pfsallocatefile.c index fd7bdeef3..821568b87 100644 --- a/src/libultra/io/pfsallocatefile.c +++ b/src/libultra/io/pfsallocatefile.c @@ -1,5 +1,138 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsallocatefile/osPfsAllocateFile.s") +s32 osPfsAllocateFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName, s32 fileSize, s32* fileNo) { + s32 startPage; + s32 decleared; + s32 prevPage; + s32 oldPrevPage = 0; + s32 ret = 0; + s32 fileSizeInPages; + __OSInode inode; + __OSInode backupInode; + __OSDir dir; + u8 bank; + u8 prevBank = 0; + s32 firsttime = 0; + s32 bytes; + __OSInodeUnit fpage; -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsallocatefile/__osPfsDeclearPage.s") + if ((companyCode == 0) || (gameCode == 0)) { + return PFS_ERR_INVALID; + } + + fileSizeInPages = (fileSize + PFS_PAGE_SIZE - 1) / PFS_PAGE_SIZE; + + if (((ret = osPfsFindFile(pfs, companyCode, gameCode, gameName, extName, fileNo)) != 0) && + (ret != PFS_ERR_INVALID)) { + return ret; + } + if (*fileNo != -1) { + return PFS_ERR_EXIST; + } + + ret = osPfsFreeBlocks(pfs, &bytes); + if (fileSize > bytes) { + return PFS_DATA_FULL; + } + + if (fileSizeInPages == 0) { + return (PFS_ERR_INVALID); + } + + if (((ret = osPfsFindFile(pfs, 0, 0, NULL, NULL, fileNo)) != 0) && (ret != PFS_ERR_INVALID)) { + return ret; + } + if (*fileNo == -1) { + return PFS_DIR_FULL; + } + + for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) { + if ((ret = __osPfsRWInode(pfs, &inode, PFS_READ, bank)) != 0) { + return ret; + } + ret = __osPfsDeclearPage(pfs, &inode, fileSizeInPages, &startPage, bank, &decleared, &prevPage); + if (ret) { + return ret; + } + if (startPage != -1) { /* There is free space */ + if (firsttime == 0) { + fpage.inode_t.page = (u8)startPage; + fpage.inode_t.bank = bank; + } else { /* Writing previous bank inode */ + backupInode.inodePage[oldPrevPage].inode_t.bank = bank; + backupInode.inodePage[oldPrevPage].inode_t.page = (u8)startPage; + if ((ret = __osPfsRWInode(pfs, &backupInode, PFS_WRITE, prevBank)) != 0) { + return ret; + } + } + if (fileSizeInPages > decleared) { + bcopy(&inode, &backupInode, sizeof(__OSInode)); + oldPrevPage = prevPage; + prevBank = bank; + fileSizeInPages -= decleared; + firsttime++; + } else { + fileSizeInPages = 0; + if ((ret = __osPfsRWInode(pfs, &inode, PFS_WRITE, bank)) != 0) { + return ret; + } + break; + } + } + } + if ((fileSizeInPages > 0) || (startPage == -1)) { + return PFS_ERR_INCONSISTENT; + } + + dir.start_page = fpage; + dir.company_code = companyCode; + dir.game_code = gameCode; + dir.data_sum = 0; + + bcopy(gameName, dir.game_name, PFS_FILE_NAME_LEN); + bcopy(extName, dir.ext_name, PFS_FILE_EXT_LEN); + + return __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + *fileNo, (u8*)&dir, 0); +} + +s32 __osPfsDeclearPage(OSPfs* pfs, __OSInode* inode, s32 fileSizeInPages, s32* startPage, u8 bank, s32* decleared, + s32* finalPage) { + s32 j; + s32 spage, prevPage; + s32 ret = 0; + s32 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) { + break; + } + } + if (j == PFS_INODE_SIZE_PER_PAGE) { + *startPage = -1; + return ret; + } + + spage = j; + *decleared = 1; + prevPage = j; + j++; + while ((fileSizeInPages > *decleared) && (j < PFS_INODE_SIZE_PER_PAGE)) { + if (inode->inodePage[j].ipage == PFS_PAGE_NOT_USED) { + inode->inodePage[prevPage].inode_t.bank = bank; + inode->inodePage[prevPage].inode_t.page = j; + prevPage = j; + (*decleared)++; + } + j++; + } + + *startPage = spage; + if ((j == (PFS_INODE_SIZE_PER_PAGE)) && (fileSizeInPages > *decleared)) { + *finalPage = prevPage; + } else { + inode->inodePage[prevPage].ipage = PFS_EOF; + *finalPage = 0; + } + return ret; +} diff --git a/src/libultra/io/pfschecker.c b/src/libultra/io/pfschecker.c index d42ac505e..bf885a1a4 100644 --- a/src/libultra/io/pfschecker.c +++ b/src/libultra/io/pfschecker.c @@ -1,7 +1,213 @@ +#include "PR/pfs.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfschecker/osPfsChecker.s") +#define CHECK_IPAGE(p) \ + (((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/pfschecker/corrupted_init.s") +s32 corrupted_init(OSPfs* pfs, __OSInodeCache* cache); +s32 corrupted(OSPfs* pfs, __OSInodeUnit fpage, __OSInodeCache* cache); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfschecker/corrupted.s") +s32 osPfsChecker(OSPfs* pfs) { + s32 j; + s32 ret; + __OSInodeUnit next; + __OSInode checkedInode; + __OSInode tempInode; + __OSDir tempDir; + __OSInodeUnit nextNodeInFile[16]; + __OSInodeCache cache; + s32 fixed = 0; + u8 bank, prevBank = 254; + s32 cc, cl; + s32 offset; + + ret = __osCheckId(pfs); + if (ret == PFS_ERR_NEW_PACK) { + ret = __osGetId(pfs); + } + + if (ret != 0) { + return ret; + } + + ret = corrupted_init(pfs, &cache); + if (ret != 0) { + return ret; + } + + for (j = 0; j < pfs->dir_size; j++) { + ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + j, (u8*)&tempDir); + if (ret != 0) { + return ret; + } + + if ((tempDir.company_code != 0) || (tempDir.game_code != 0)) { + if ((tempDir.company_code == 0) || (tempDir.game_code == 0)) { + cc = -1; + } else { + next = tempDir.start_page; + cl = cc = 0; + bank = 255; + + while (CHECK_IPAGE(next)) { + if (bank != next.inode_t.bank) { + bank = next.inode_t.bank; + if (prevBank != bank) { + ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank); + prevBank = bank; + } + + if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) { + return ret; + } + } + + cc = corrupted(pfs, next, &cache) - cl; + if (cc != 0) { + break; + } + + cl = 1; + next = tempInode.inodePage[next.inode_t.page]; + } + } + + if ((cc != 0) || (next.ipage != PFS_EOF)) { + bzero(&tempDir, sizeof(__OSDir)); + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } + } + + ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + j, (u8*)&tempDir, 0); + if (ret != 0) { + return ret; + } + + fixed++; + } + } + } + + for (j = 0; j < pfs->dir_size; j++) { + ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + j, (u8*)&tempDir); + if (ret != 0) { + return ret; + } + + if ((tempDir.company_code != 0) && (tempDir.game_code != 0) && + (tempDir.start_page.ipage >= (u16)pfs->inodeStartPage)) { // cast required + nextNodeInFile[j].ipage = tempDir.start_page.ipage; + } else { + nextNodeInFile[j].ipage = 0; + } + } + + for (bank = 0; bank < pfs->banks; bank++) { + ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank); + if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) { + return (ret); + } + offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage); + for (j = 0; j < offset; j++) { + checkedInode.inodePage[j].ipage = tempInode.inodePage[j].ipage; + } + for (; j < PFS_INODE_SIZE_PER_PAGE; j++) { + checkedInode.inodePage[j].ipage = PFS_PAGE_NOT_USED; + } + + for (j = 0; j < pfs->dir_size; j++) { + while (nextNodeInFile[j].inode_t.bank == bank && + nextNodeInFile[j].ipage >= (u16)pfs->inodeStartPage) { // cast required + u8 val = nextNodeInFile[j].inode_t.page; + + nextNodeInFile[j] = checkedInode.inodePage[val] = tempInode.inodePage[val]; + } + } + + ret = __osPfsRWInode(pfs, &checkedInode, PFS_WRITE, bank); + if (ret != 0) { + return ret; + } + } + + if (fixed != 0) { + pfs->status |= PFS_CORRUPTED; + } else { + pfs->status &= ~PFS_CORRUPTED; + } + + return 0; +} + +s32 corrupted_init(OSPfs* pfs, __OSInodeCache* cache) { + s32 i; + s32 n; + s32 offset; + u8 bank; + __OSInodeUnit tpage; + __OSInode tempInode; + s32 ret; + + for (i = 0; i < PFS_INODE_DIST_MAP; i++) { + cache->map[i] = 0; + } + cache->bank = 255; + + for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) { + offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage); + ret = __osPfsRWInode(pfs, &tempInode, PFS_READ, bank); + if ((ret != 0) && (ret != PFS_ERR_INCONSISTENT)) { + return ret; + } + + for (i = offset; i < PFS_INODE_SIZE_PER_PAGE; i++) { + tpage = tempInode.inodePage[i]; + if ((tpage.ipage >= pfs->inodeStartPage) && (tpage.inode_t.bank != bank)) { + n = ((tpage.inode_t.page & 0x7F) / PFS_SECTOR_SIZE) + + PFS_SECTOR_PER_BANK * (tpage.inode_t.bank % PFS_BANK_LAPPED_BY); + cache->map[n] |= (1 << (bank % PFS_BANK_LAPPED_BY)); + } + } + } + return 0; +} + +s32 corrupted(OSPfs* pfs, __OSInodeUnit fpage, __OSInodeCache* cache) { + s32 j; + s32 n; + s32 hit = 0; + u8 bank; + s32 offset; + s32 ret = 0; + + n = (fpage.inode_t.page / PFS_SECTOR_SIZE) + PFS_SECTOR_PER_BANK * (fpage.inode_t.bank % PFS_BANK_LAPPED_BY); + + for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) { + offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage); + if ((bank == fpage.inode_t.bank) || (cache->map[n] & (1 << (bank % PFS_BANK_LAPPED_BY))) != 0) { + if (bank != cache->bank) { + ret = __osPfsRWInode(pfs, &(cache->inode), PFS_READ, bank); + if (ret && (ret != PFS_ERR_INCONSISTENT)) { + return ret; + } + cache->bank = bank; + } + + for (j = offset; ((hit < 2) && (j < PFS_INODE_SIZE_PER_PAGE)); j++) { + if (cache->inode.inodePage[j].ipage == fpage.ipage) { + hit++; + } + } + + if (hit >= 2) { + return 2; + } + } + } + + return hit; +} diff --git a/src/libultra/io/pfsdeletefile.c b/src/libultra/io/pfsdeletefile.c index d604ca7a4..39e9aa898 100644 --- a/src/libultra/io/pfsdeletefile.c +++ b/src/libultra/io/pfsdeletefile.c @@ -1,5 +1,86 @@ +#include "PR/pfs.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsdeletefile/osPfsDeleteFile.s") +s32 __osPfsReleasePages(OSPfs* pfs, __OSInode* inode, u8 initialPage, u8 bank, __OSInodeUnit* finalPage); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsdeletefile/__osPfsReleasePages.s") +s32 osPfsDeleteFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName) { + s32 file_no; + s32 ret; + __OSInode inode; + __OSDir dir; + __OSInodeUnit last_page; + u8 startpage; + u8 bank; + + if ((companyCode == 0) || (gameCode == 0)) { + return PFS_ERR_INVALID; + } + + ret = osPfsFindFile(pfs, companyCode, gameCode, gameName, extName, &file_no); + if (ret != 0) { + return ret; + } + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } + } + + ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + file_no, (u8*)&dir); + if (ret != 0) { + return ret; + } + + startpage = dir.start_page.inode_t.page; + for (bank = dir.start_page.inode_t.bank; bank < pfs->banks;) { + ret = __osPfsRWInode(pfs, &inode, PFS_READ, bank); + if (ret != 0) { + return ret; + } + + ret = __osPfsReleasePages(pfs, &inode, startpage, bank, &last_page); + if (ret != 0) { + return ret; + } + + ret = __osPfsRWInode(pfs, &inode, PFS_WRITE, bank); + if (ret != 0) { + return ret; + } + + if (last_page.ipage == PFS_EOF) { + break; + } + + bank = last_page.inode_t.bank; + startpage = last_page.inode_t.page; + } + + if (bank >= pfs->banks) { + return PFS_ERR_INCONSISTENT; + } + bzero(&dir, sizeof(__OSDir)); + + ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + file_no, (u8*)&dir, 0); + + return ret; +} + +s32 __osPfsReleasePages(OSPfs* pfs, __OSInode* inode, u8 initialPage, u8 bank, __OSInodeUnit* finalPage) { + __OSInodeUnit next; + __OSInodeUnit prev; + s32 ret = 0; + + next.ipage = (u16)((bank << 8) + initialPage); + + do { + prev = next; + next = inode->inodePage[next.inode_t.page]; + inode->inodePage[prev.inode_t.page].ipage = PFS_PAGE_NOT_USED; + } while (next.ipage >= pfs->inodeStartPage && next.inode_t.bank == bank); + + *finalPage = next; + + return ret; +} diff --git a/src/libultra/io/pfsfilestate.c b/src/libultra/io/pfsfilestate.c index ad6737ab1..a555199fc 100644 --- a/src/libultra/io/pfsfilestate.c +++ b/src/libultra/io/pfsfilestate.c @@ -1,3 +1,71 @@ +#include "PR/pfs.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsfilestate/osPfsFileState.s") +s32 osPfsFileState(OSPfs* pfs, s32 fileNo, OSPfsState* state) { + s32 ret; + s32 pages; + __OSInode inode; + __OSDir dir; + __OSInodeUnit page; + u8 bank; + + if (fileNo >= pfs->dir_size || fileNo < 0) { + return PFS_ERR_INVALID; + } + + if (!(pfs->status & PFS_INITIALIZED)) { + return PFS_ERR_INVALID; + } + + ret = __osCheckId(pfs); + if (ret != 0) { + return ret; + } + + if (pfs->activebank != 0) { + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } + } + + ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir); + if (ret != 0) { + return ret; + } + + if (dir.company_code == 0 || dir.game_code == 0) { + return PFS_ERR_INVALID; + } + + page = dir.start_page; + pages = 0; + bank = 0xFF; + + while (true) { + if (page.ipage < pfs->inodeStartPage) { + break; + } + if (page.inode_t.bank != bank) { + bank = page.inode_t.bank; + + ret = __osPfsRWInode(pfs, &inode, PFS_READ, bank); + if (ret != 0) { + return ret; + } + } + pages++; + page = inode.inodePage[page.inode_t.page]; + } + if (page.ipage != PFS_EOF) { + return PFS_ERR_INCONSISTENT; + } + + state->file_size = pages * PFS_ONE_PAGE * BLOCKSIZE; + state->company_code = dir.company_code; + state->game_code = dir.game_code; + bcopy(&dir.game_name, state->game_name, PFS_FILE_NAME_LEN); + bcopy(&dir.ext_name, state->ext_name, PFS_FILE_EXT_LEN); + + return __osPfsGetStatus(pfs->queue, pfs->channel); +} 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/pfsinitpak.c b/src/libultra/io/pfsinitpak.c index 6d8a59c1a..cc226f834 100644 --- a/src/libultra/io/pfsinitpak.c +++ b/src/libultra/io/pfsinitpak.c @@ -1,5 +1,124 @@ +#include "PR/pfs.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsinitpak/osPfsInitPak.s") +s32 __osPfsCheckRamArea(OSPfs* pfs); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsinitpak/__osPfsCheckRamArea.s") +s32 osPfsInitPak(OSMesgQueue* queue, OSPfs* pfs, s32 channel) { + s32 ret; + u16 sum; + u16 isum; + u8 buf[BLOCKSIZE]; + __OSPackId* id; + __OSPackId newid; + + __osSiGetAccess(); + + ret = __osPfsGetStatus(queue, channel); + + __osSiRelAccess(); + + if (ret != 0) { + return ret; + } + + pfs->queue = queue; + pfs->channel = channel; + pfs->status = 0; + + ret = __osPfsCheckRamArea(pfs); + if (ret != 0) { + return ret; + } + + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } + + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_ID_0AREA, buf); + if (ret != 0) { + return ret; + } + + __osIdCheckSum((u16*)buf, &sum, &isum); + id = (__OSPackId*)buf; + if ((id->checksum != sum) || (id->invertedChecksum != isum)) { + ret = __osCheckPackId(pfs, id); + if (ret != 0) { + pfs->status |= PFS_ID_BROKEN; + return ret; + } + } + + if (!(id->deviceid & 1)) { + ret = __osRepairPackId(pfs, id, &newid); + if (ret != 0) { + if (ret == PFS_ERR_ID_FATAL) { + pfs->status |= PFS_ID_BROKEN; + } + return ret; + } + id = &newid; + if (!(id->deviceid & 1)) { + return PFS_ERR_DEVICE; + } + } + + bcopy(id, pfs->id, BLOCKSIZE); + + pfs->version = id->version; + pfs->banks = id->banks; + pfs->inodeStartPage = 1 + DEF_DIR_PAGES + (2 * pfs->banks); + pfs->dir_size = DEF_DIR_PAGES * PFS_ONE_PAGE; + pfs->inode_table = 1 * PFS_ONE_PAGE; + pfs->minode_table = (1 + pfs->banks) * PFS_ONE_PAGE; + pfs->dir_table = pfs->minode_table + (pfs->banks * PFS_ONE_PAGE); + + ret = __osContRamRead(pfs->queue, pfs->channel, PFS_LABEL_AREA, pfs->label); + if (ret != 0) { + return ret; + } + + ret = osPfsChecker(pfs); + pfs->status |= PFS_INITIALIZED; + + return ret; +} + +s32 __osPfsCheckRamArea(OSPfs* pfs) { + s32 i = 0; + s32 ret = 0; + u8 writeBuf[BLOCKSIZE]; + u8 readBuf[BLOCKSIZE]; + u8 saveReg[BLOCKSIZE]; + + ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K); + if (ret != 0) { + return ret; + } + + ret = __osContRamRead(pfs->queue, pfs->channel, 0, saveReg); + if (ret != 0) { + return ret; + } + + for (i = 0; i < BLOCKSIZE; i++) { + writeBuf[i] = i; + } + + ret = __osContRamWrite(pfs->queue, pfs->channel, 0, writeBuf, 0); + if (ret != 0) { + return ret; + } + + ret = __osContRamRead(pfs->queue, pfs->channel, 0, readBuf); + if (ret != 0) { + return ret; + } + + if (bcmp(writeBuf, readBuf, BLOCKSIZE) != 0) { + return PFS_ERR_DEVICE; + } + + return __osContRamWrite(pfs->queue, pfs->channel, 0, saveReg, 0); +} diff --git a/src/libultra/io/pfsisplug.c b/src/libultra/io/pfsisplug.c index 2c479e35b..474c7f914 100644 --- a/src/libultra/io/pfsisplug.c +++ b/src/libultra/io/pfsisplug.c @@ -1,7 +1,97 @@ +#include "PR/pfs.h" +#include "io/controller.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsisplug/osPfsIsPlug.s") +void __osPfsRequestData(u8 poll); +void __osPfsGetInitData(u8* pattern, OSContStatus* contData); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsisplug/__osPfsRequestData.s") +s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) { + s32 ret = 0; + OSMesg msg; + u8 bitpattern; + OSContStatus contData[MAXCONTROLLERS]; + s32 channel; + u8 bits = 0; + s32 crcErrorCount = 3; -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsisplug/__osPfsGetInitData.s") + __osSiGetAccess(); + + do { + __osPfsRequestData(CONT_CMD_REQUEST_STATUS); + + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, &msg, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, &msg, OS_MESG_BLOCK); + + __osPfsGetInitData(&bitpattern, &contData[0]); + + for (channel = 0; channel < __osMaxControllers; channel++) { + if (!(contData[channel].status & CONT_ADDR_CRC_ER)) { + crcErrorCount--; + break; + } + } + if (channel == __osMaxControllers) { + crcErrorCount = 0; + } + } while (crcErrorCount > 0); + + for (channel = 0; channel < __osMaxControllers; channel++) { + if ((contData[channel].errno == 0) && (contData[channel].status & CONT_CARD_ON)) { + bits |= (1 << channel); + } + } + __osSiRelAccess(); + *pattern = bits; + return ret; +} + +void __osPfsRequestData(u8 poll) { + u8* bufPtr = (u8*)&__osPfsPifRam; + __OSContRequestHeader req; + s32 i; + + __osContLastPoll = poll; + + __osPfsPifRam.status = 1; + + req.align = 0xFF; + req.txsize = 1; + req.rxsize = 3; + req.poll = poll; + req.typeh = 0xFF; + req.typel = 0xFF; + req.status = 0xFF; + req.align1 = 0xFF; + + for (i = 0; i < __osMaxControllers; i++) { + *((__OSContRequestHeader*)bufPtr) = req; + bufPtr += sizeof(req); + } + *((u8*)bufPtr) = CONT_CMD_END; +} + +void __osPfsGetInitData(u8* pattern, OSContStatus* contData) { + u8* bufptr; + __OSContRequestHeader req; + s32 i; + u8 bits = 0; + + bufptr = (u8*)&__osPfsPifRam; + + for (i = 0; i < __osMaxControllers; i++, bufptr += sizeof(req), contData++) { + req = *((__OSContRequestHeader*)bufptr); + contData->errno = ((req.rxsize & 0xC0) >> 4); + + if (contData->errno) { + continue; + } + + contData->type = ((req.typel << 8) | req.typeh); + contData->status = req.status; + bits |= (1 << i); + } + *pattern = bits; +} 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/pfssearchfile.c b/src/libultra/io/pfssearchfile.c index 572e3d0a7..c5f8bcce4 100644 --- a/src/libultra/io/pfssearchfile.c +++ b/src/libultra/io/pfssearchfile.c @@ -1,3 +1,52 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfssearchfile/osPfsFindFile.s") +s32 osPfsFindFile(OSPfs* pfs, u16 companyCode, u32 gameCode, u8* gameName, u8* extName, s32* fileNo) { + s32 j; + s32 i; + __OSDir dir; + s32 ret = 0; + s32 err; + + if (!(pfs->status & PFS_INITIALIZED)) { + return PFS_ERR_INVALID; + } + + if ((ret = __osCheckId(pfs)) != 0) { + return ret; + } + + for (j = 0; j < pfs->dir_size; j++) { + if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + j, (u8*)&dir)) != 0) { + return ret; + } + if ((ret = __osPfsGetStatus(pfs->queue, pfs->channel)) != 0) { + return ret; + } + + if ((dir.company_code == companyCode) && (dir.game_code == gameCode)) { + err = 0; + if (gameName != 0) { + for (i = 0; i < PFS_FILE_NAME_LEN; i++) { + if (dir.game_name[i] != gameName[i]) { + err = 1; + break; + } + } + } + if ((extName != 0) && (err == 0)) { + for (i = 0; i < PFS_FILE_EXT_LEN; i++) { + if (dir.ext_name[i] != extName[i]) { + err = 1; + break; + } + } + } + if (err == 0) { + *fileNo = j; + return ret; + } + } + } + *fileNo = -1; + return PFS_ERR_INVALID; +} diff --git a/src/libultra/io/pfsselectbank.c b/src/libultra/io/pfsselectbank.c index 8353dc43c..6cc43a470 100644 --- a/src/libultra/io/pfsselectbank.c +++ b/src/libultra/io/pfsselectbank.c @@ -1,3 +1,18 @@ +#include "PR/pfs.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsselectbank/__osPfsSelectBank.s") +s32 __osPfsSelectBank(OSPfs* pfs, u8 bank) { + u8 buf[BLOCKSIZE]; + s32 i; + s32 ret = 0; + + for (i = 0; i < BLOCKSIZE; i++) { + buf[i] = bank; + } + + ret = __osContRamWrite(pfs->queue, pfs->channel, 0x8000 / BLOCKSIZE, buf, 0); + if (ret == 0) { + pfs->activebank = bank; + } + return ret; +} diff --git a/src/libultra/io/piacs.c b/src/libultra/io/piacs.c index 8e6f830c0..532b149e2 100644 --- a/src/libultra/io/piacs.c +++ b/src/libultra/io/piacs.c @@ -7,8 +7,8 @@ OSMesgQueue __osPiAccessQueue; void __osPiCreateAccessQueue(void) { __osPiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, 1); - osSendMesg(&__osPiAccessQueue, NULL, 0); + osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, ARRAY_COUNT(D_8009E3F0)); + osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK); } void __osPiGetAccess(void) { 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/pirawdma.c b/src/libultra/io/pirawdma.c index 242a91c24..07aa1b822 100644 --- a/src/libultra/io/pirawdma.c +++ b/src/libultra/io/pirawdma.c @@ -1,23 +1,22 @@ #include "global.h" -s32 __osPiRawStartDma(s32 direction, u32 devAddr, void* dramAddr, size_t size) { - register int stat; +s32 __osPiRawStartDma(s32 direction, uintptr_t devAddr, void* dramAddr, size_t size) { + register int status = HW_REG(PI_STATUS_REG, u32); - stat = *(vu32*)0xA4600010; - while (stat & (2 | 1)) { - stat = *(vu32*)0xA4600010; + while (status & (PI_STATUS_IOBUSY | PI_STATUS_BUSY)) { + status = HW_REG(PI_STATUS_REG, u32); } - *(u32*)0xA4600000 = osVirtualToPhysical(dramAddr); + HW_REG(PI_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr); - *(u32*)0xA4600004 = ((osRomBase | devAddr) & 0x1fffffff); + HW_REG(PI_CART_ADDR_REG, u32) = ((osRomBase | devAddr) & 0x1FFFFFFF); switch (direction) { - case 0: - *(u32*)0xA460000C = size - 1; + case OS_READ: + HW_REG(PI_WR_LEN_REG, u32) = size - 1; break; - case 1: - *(u32*)0xA4600008 = size - 1; + case OS_WRITE: + HW_REG(PI_RD_LEN_REG, u32) = size - 1; break; default: return -1; diff --git a/src/libultra/io/rumblepak.c b/src/libultra/io/rumblepak.c deleted file mode 100644 index 3353059da..000000000 --- a/src/libultra/io/rumblepak.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/boot/rumblepak/osSetRumble.s") - -#pragma GLOBAL_ASM("asm/non_matchings/boot/rumblepak/osSetUpMempakWrite.s") - -#pragma GLOBAL_ASM("asm/non_matchings/boot/rumblepak/osProbeRumblePak.s") diff --git a/src/libultra/io/si.c b/src/libultra/io/si.c index 6de5874b9..563c68276 100644 --- a/src/libultra/io/si.c +++ b/src/libultra/io/si.c @@ -1,11 +1,11 @@ #include "global.h" -int __osSiDeviceBusy() { - register u32 status; - status = *(u32*)0xA4800018; - if (status & 3) { - return 1; +s32 __osSiDeviceBusy() { + register u32 status = HW_REG(SI_STATUS_REG, u32); + + if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) { + return true; } else { - return 0; + return false; } } diff --git a/src/libultra/io/siacs.c b/src/libultra/io/siacs.c index 590f048ad..7a221408e 100644 --- a/src/libultra/io/siacs.c +++ b/src/libultra/io/siacs.c @@ -7,8 +7,8 @@ OSMesgQueue __osSiAccessQueue; void __osSiCreateAccessQueue() { __osSiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, 1); - osSendMesg(&__osSiAccessQueue, NULL, 0); + osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, ARRAY_COUNT(siAccessBuf)); + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); } void __osSiGetAccess(void) { @@ -16,9 +16,9 @@ void __osSiGetAccess(void) { if (!__osSiAccessQueueEnabled) { __osSiCreateAccessQueue(); } - osRecvMesg(&__osSiAccessQueue, &dummyMesg, 1); + osRecvMesg(&__osSiAccessQueue, &dummyMesg, OS_MESG_BLOCK); } void __osSiRelAccess(void) { - osSendMesg(&__osSiAccessQueue, NULL, 0); + osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); } diff --git a/src/libultra/io/sirawdma.c b/src/libultra/io/sirawdma.c index ff57e21c2..eb62fa2a3 100644 --- a/src/libultra/io/sirawdma.c +++ b/src/libultra/io/sirawdma.c @@ -1,24 +1,24 @@ #include "global.h" s32 __osSiRawStartDma(s32 direction, void* dramAddr) { - if ((*(u32*)0xA4800018 & 0x3) != 0) { + if (HW_REG(SI_STATUS_REG, u32) & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) { return -1; } - if (direction == 1) { - osWritebackDCache(dramAddr, 64); + if (direction == OS_WRITE) { + osWritebackDCache(dramAddr, PIF_RAM_SIZE); } - *(u32*)0xA4800000 = osVirtualToPhysical(dramAddr); + HW_REG(SI_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr); - if (direction == 0) { - *(u32*)0xA4800004 = 0x1FC007C0; + if (direction == OS_READ) { + HW_REG(SI_PIF_ADDR_RD64B_REG, void*) = (void*)PIF_RAM_START; } else { - *(u32*)0xA4800010 = 0x1FC007C0; + HW_REG(SI_PIF_ADDR_WR64B_REG, void*) = (void*)PIF_RAM_START; } - if (direction == 0) { - osInvalDCache(dramAddr, 64); + if (direction == OS_READ) { + osInvalDCache(dramAddr, PIF_RAM_SIZE); } return 0; } diff --git a/src/libultra/io/sp.c b/src/libultra/io/sp.c index 6c829b062..c028c7692 100644 --- a/src/libultra/io/sp.c +++ b/src/libultra/io/sp.c @@ -1,3 +1,11 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/sp/__osSpDeviceBusy.s") +s32 __osSpDeviceBusy(void) { + register u32 status = HW_REG(SP_STATUS_REG, u32); + + if (status & (SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL | SP_STATUS_IO_FULL)) { + return true; + } else { + return false; + } +} diff --git a/src/libultra/io/spgetstat.c b/src/libultra/io/spgetstat.c index 98a3dc23b..8987b2414 100644 --- a/src/libultra/io/spgetstat.c +++ b/src/libultra/io/spgetstat.c @@ -1,5 +1,5 @@ #include "global.h" u32 __osSpGetStatus() { - return *(vu32*)0xA4040010; + return HW_REG(SP_STATUS_REG, u32); } diff --git a/src/libultra/io/sprawdma.c b/src/libultra/io/sprawdma.c index 95395a29d..494f3db50 100644 --- a/src/libultra/io/sprawdma.c +++ b/src/libultra/io/sprawdma.c @@ -1,17 +1,17 @@ #include "global.h" s32 __osSpRawStartDma(s32 direction, void* devAddr, void* dramAddr, size_t size) { - if (__osSpDeviceBusy() != 0) { + if (__osSpDeviceBusy()) { return -1; } - *(vu32*)0xA4040000 = devAddr; - *(vu32*)0xA4040004 = osVirtualToPhysical(dramAddr); + HW_REG(SP_MEM_ADDR_REG, u32) = devAddr; + HW_REG(SP_DRAM_ADDR_REG, u32) = osVirtualToPhysical(dramAddr); - if (direction == 0) { - *(vu32*)0xA404000C = size - 1; + if (direction == OS_READ) { + HW_REG(SP_WR_LEN_REG, u32) = size - 1; } else { - *(vu32*)0xA4040008 = size - 1; + HW_REG(SP_RD_LEN_REG, u32) = size - 1; } return 0; diff --git a/src/libultra/io/spsetpc.c b/src/libultra/io/spsetpc.c index d87302bc2..2c3cc32ba 100644 --- a/src/libultra/io/spsetpc.c +++ b/src/libultra/io/spsetpc.c @@ -1,3 +1,13 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/spsetpc/__osSpSetPc.s") +s32 __osSpSetPc(void* pc) { + register u32 spStatus = HW_REG(SP_STATUS_REG, u32); + + if (!(spStatus & SP_STATUS_HALT)) { + return -1; + } else { + HW_REG(SP_PC_REG, void*) = pc; + } + + return 0; +} diff --git a/src/libultra/io/spsetstat.c b/src/libultra/io/spsetstat.c index 346577218..eb183eab4 100644 --- a/src/libultra/io/spsetstat.c +++ b/src/libultra/io/spsetstat.c @@ -1,5 +1,5 @@ #include "global.h" void __osSpSetStatus(u32 data) { - *(vu32*)0xA4040010 = data; + HW_REG(SP_STATUS_REG, u32) = data; } diff --git a/src/libultra/io/sptask.c b/src/libultra/io/sptask.c index 84a9624fb..aeaaf0f82 100644 --- a/src/libultra/io/sptask.c +++ b/src/libultra/io/sptask.c @@ -13,12 +13,12 @@ OSTask* _VirtualToPhysicalTask(OSTask* intp) { bcopy(intp, tp, sizeof(OSTask)); _osVirtualToPhysical(tp->t.ucode); - _osVirtualToPhysical(tp->t.ucode_data); - _osVirtualToPhysical(tp->t.dram_stack); - _osVirtualToPhysical(tp->t.output_buff); - _osVirtualToPhysical(tp->t.output_buff_size); - _osVirtualToPhysical(tp->t.data_ptr); - _osVirtualToPhysical(tp->t.yield_data_ptr); + _osVirtualToPhysical(tp->t.ucodeData); + _osVirtualToPhysical(tp->t.dramStack); + _osVirtualToPhysical(tp->t.outputBuff); + _osVirtualToPhysical(tp->t.outputBuffSize); + _osVirtualToPhysical(tp->t.dataPtr); + _osVirtualToPhysical(tp->t.yieldDataPtr); return tp; } @@ -27,34 +27,28 @@ void osSpTaskLoad(OSTask* intp) { OSTask* tp = _VirtualToPhysicalTask(intp); if (tp->t.flags & OS_TASK_YIELDED) { - tp->t.ucode_data = tp->t.yield_data_ptr; - tp->t.ucode_data_size = tp->t.yield_data_size; + tp->t.ucodeData = tp->t.yieldDataPtr; + tp->t.ucodeDataSize = tp->t.yieldDataSize; intp->t.flags &= ~OS_TASK_YIELDED; if (tp->t.flags & OS_TASK_LOADABLE) { - tp->t.ucode = HW_REG((u32)intp->t.yield_data_ptr + 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.ucode_boot, tp->t.ucode_boot_size) == -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/vi.c b/src/libultra/io/vi.c index dca456462..ec0b1de70 100644 --- a/src/libultra/io/vi.c +++ b/src/libultra/io/vi.c @@ -1,29 +1,32 @@ #include "global.h" +__OSViContext D_80098060[2] = { 0 }; +__OSViContext* __osViCurr = &D_80098060[0]; +__OSViContext* __osViNext = &D_80098060[1]; + void __osViInit(void) { bzero(D_80098060, sizeof(D_80098060)); __osViCurr = &D_80098060[0]; __osViNext = &D_80098060[1]; __osViNext->retraceCount = 1; __osViCurr->retraceCount = 1; - __osViNext->framep = (void*)0x80000000; - __osViCurr->framep = (void*)0x80000000; + __osViNext->buffer = (void*)0x80000000; + __osViCurr->buffer = (void*)0x80000000; - if (osTvType == 0) { + if (osTvType == OS_TV_PAL) { __osViNext->modep = &osViModePalLan1; - } else if (osTvType == 2) { + } else if (osTvType == OS_TV_MPAL) { __osViNext->modep = &osViModeMpalLan1; - } else { + } else { // OS_TV_NTSC or OS_TV_UNK28 __osViNext->modep = &osViModeNtscLan1; } __osViNext->state = 0x20; - __osViNext->control = __osViNext->modep->comRegs.ctrl; + __osViNext->features = __osViNext->modep->comRegs.ctrl; - while (*(vu32*)0xA4400010 > 10) { - ; - } - *(vu32*)0xA4400000 = 0; + while (HW_REG(VI_CURRENT_REG, u32) > 10) {} + + HW_REG(VI_STATUS_REG, u32) = 0; __osViSwapContext(); } diff --git a/src/libultra/io/viblack.c b/src/libultra/io/viblack.c index abc0b3b20..6b8fec953 100644 --- a/src/libultra/io/viblack.c +++ b/src/libultra/io/viblack.c @@ -8,7 +8,7 @@ void osViBlack(u8 active) { if (active) { __osViNext->state |= 0x20; } else { - __osViNext->state &= 0xffdf; + __osViNext->state &= ~0x20; } __osRestoreInt(saveMask); diff --git a/src/libultra/io/vigetcurrframebuf.c b/src/libultra/io/vigetcurrframebuf.c index 83feda93d..bace58ded 100644 --- a/src/libultra/io/vigetcurrframebuf.c +++ b/src/libultra/io/vigetcurrframebuf.c @@ -1,3 +1,10 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/vigetcurrframebuf/osViGetCurrentFramebuffer.s") +u32* osViGetCurrentFramebuffer(void) { + register u32 prevInt = __osDisableInt(); + u32* curBuf = __osViCurr->buffer; + + __osRestoreInt(prevInt); + + return curBuf; +} diff --git a/src/libultra/io/vigetnextframebuf.c b/src/libultra/io/vigetnextframebuf.c index dac52e5bd..21fd8ece7 100644 --- a/src/libultra/io/vigetnextframebuf.c +++ b/src/libultra/io/vigetnextframebuf.c @@ -2,13 +2,13 @@ void* osViGetNextFramebuffer(void) { register u32 saveMask; - void* framep; + void* buffer; saveMask = __osDisableInt(); - framep = __osViNext->framep; + buffer = __osViNext->buffer; __osRestoreInt(saveMask); - return framep; + return buffer; } diff --git a/src/libultra/io/vimgr.c b/src/libultra/io/vimgr.c index ecbb9b37c..07babf351 100644 --- a/src/libultra/io/vimgr.c +++ b/src/libultra/io/vimgr.c @@ -1,5 +1,107 @@ #include "global.h" +#include "osint.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/vimgr/osCreateViManager.s") +OSThread viThread; +u8 viThreadStack[0x1000]; +OSMesgQueue viEventQueue; +OSMesg viEventBuf[6]; +OSIoMesg viRetraceMsg; +OSIoMesg viCounterMsg; +OSMgrArgs __osViDevMgr = { 0 }; +u32 __additional_scanline = 0; -#pragma GLOBAL_ASM("asm/non_matchings/boot/vimgr/viMgrMain.s") +void viMgrMain(void*); + +void osCreateViManager(OSPri pri) { + u32 prevInt; + OSPri newPri; + OSPri currentPri; + + if (!__osViDevMgr.initialized) { + __osTimerServicesInit(); + __additional_scanline = 0; + osCreateMesgQueue(&viEventQueue, viEventBuf, ARRAY_COUNT(viEventBuf) - 1); + viRetraceMsg.hdr.type = OS_MESG_TYPE_VRETRACE; + viRetraceMsg.hdr.pri = OS_MESG_PRI_NORMAL; + viRetraceMsg.hdr.retQueue = NULL; + viCounterMsg.hdr.type = OS_MESG_TYPE_COUNTER; + viCounterMsg.hdr.pri = OS_MESG_PRI_NORMAL; + viCounterMsg.hdr.retQueue = NULL; + osSetEventMesg(OS_EVENT_VI, &viEventQueue, &viRetraceMsg); + osSetEventMesg(OS_EVENT_COUNTER, &viEventQueue, &viCounterMsg); + newPri = -1; + currentPri = osGetThreadPri(NULL); + if (currentPri < pri) { + newPri = currentPri; + osSetThreadPri(NULL, pri); + } + + prevInt = __osDisableInt(); + __osViDevMgr.initialized = true; + __osViDevMgr.mgrThread = &viThread; + __osViDevMgr.cmdQueue = &viEventQueue; + __osViDevMgr.eventQueue = &viEventQueue; + __osViDevMgr.accessQueue = NULL; + __osViDevMgr.piDmaCallback = NULL; + __osViDevMgr.epiDmaCallback = NULL; + + osCreateThread(&viThread, 0, &viMgrMain, &__osViDevMgr, viThreadStack + sizeof(viThreadStack), pri); + __osViInit(); + osStartThread(&viThread); + __osRestoreInt(prevInt); + if (newPri != -1) { + osSetThreadPri(NULL, newPri); + } + } +} + +void viMgrMain(void* vargs) { + OSMgrArgs* args; + static u16 viRetrace; + u32 addTime; + OSIoMesg* mesg; + u32 temp = 0; // always 0 + + mesg = NULL; + viRetrace = __osViGetCurrentContext()->retraceCount; + if (viRetrace == 0) { + viRetrace = 1; + } + + args = (OSMgrArgs*)vargs; + + while (true) { + osRecvMesg(args->eventQueue, (OSMesg)&mesg, OS_MESG_BLOCK); + switch (mesg->hdr.type) { + case OS_MESG_TYPE_VRETRACE: + __osViSwapContext(); + viRetrace--; + if (!viRetrace) { + __OSViContext* ctx = __osViGetCurrentContext(); + if (ctx->mq) { + osSendMesg(ctx->mq, ctx->msg, OS_MESG_NOBLOCK); + } + viRetrace = ctx->retraceCount; + } + + __osViIntrCount++; + + // block optimized out since temp is always 0, + // but it changes register allocation and ordering for __osCurrentTime + if (temp != 0) { + addTime = osGetCount(); + __osCurrentTime = addTime; + temp = 0; + } + + addTime = __osBaseCounter; + __osBaseCounter = osGetCount(); + addTime = __osBaseCounter - addTime; + __osCurrentTime = __osCurrentTime + addTime; + break; + case OS_MESG_TYPE_COUNTER: + __osTimerInterrupt(); + break; + } + } +} diff --git a/src/libultra/io/visetmode.c b/src/libultra/io/visetmode.c index f839875b3..6953bf63b 100644 --- a/src/libultra/io/visetmode.c +++ b/src/libultra/io/visetmode.c @@ -7,7 +7,7 @@ void osViSetMode(OSViMode* modep) { __osViNext->modep = modep; __osViNext->state = 1; - __osViNext->control = __osViNext->modep->comRegs.ctrl; + __osViNext->features = __osViNext->modep->comRegs.ctrl; __osRestoreInt(saveMask); } diff --git a/src/libultra/io/visetspecial.c b/src/libultra/io/visetspecial.c index 37d510ed3..a5ef1220a 100644 --- a/src/libultra/io/visetspecial.c +++ b/src/libultra/io/visetspecial.c @@ -3,34 +3,33 @@ void osViSetSpecialFeatures(u32 func) { register u32 saveMask = __osDisableInt(); - if (func & 1) { - __osViNext->control |= 8; + if (func & OS_VI_GAMMA_ON) { + __osViNext->features |= OS_VI_GAMMA; } - if (func & 2) { - __osViNext->control &= ~8; + if (func & OS_VI_GAMMA_OFF) { + __osViNext->features &= ~OS_VI_GAMMA; } - if (func & 4) { - __osViNext->control |= 4; + if (func & OS_VI_GAMMA_DITHER_ON) { + __osViNext->features |= OS_VI_GAMMA_DITHER; } - if (func & 8) { + if (func & OS_VI_GAMMA_DITHER_OFF) { + __osViNext->features &= ~OS_VI_GAMMA_DITHER; + } + if (func & OS_VI_DIVOT_ON) { - __osViNext->control &= ~4; + __osViNext->features |= OS_VI_DIVOT; } - if (func & 0x10) { + if (func & OS_VI_DIVOT_OFF) { - __osViNext->control |= 0x10; + __osViNext->features &= ~OS_VI_DIVOT; } - if (func & 0x20) { - - __osViNext->control &= ~0x10; + if (func & OS_VI_DITHER_FILTER_ON) { + __osViNext->features |= OS_VI_DITHER_FILTER; + __osViNext->features &= ~(OS_VI_UNK100 | OS_VI_UNK200); } - if (func & 0x40) { - __osViNext->control |= 0x10000; - __osViNext->control &= ~0x300; - } - if (func & 0x80) { - __osViNext->control &= ~0x10000; - __osViNext->control |= __osViNext->modep->comRegs.ctrl & 0x300; + if (func & OS_VI_DITHER_FILTER_OFF) { + __osViNext->features &= ~OS_VI_DITHER_FILTER; + __osViNext->features |= __osViNext->modep->comRegs.ctrl & (OS_VI_UNK100 | OS_VI_UNK200); } __osViNext->state |= 8; diff --git a/src/libultra/io/viswapbuf.c b/src/libultra/io/viswapbuf.c index 4d5f27788..c60918092 100644 --- a/src/libultra/io/viswapbuf.c +++ b/src/libultra/io/viswapbuf.c @@ -4,7 +4,7 @@ void osViSwapBuffer(void* frameBufPtr) { u32 saveMask = __osDisableInt(); - __osViNext->framep = frameBufPtr; + __osViNext->buffer = frameBufPtr; __osViNext->state |= 0x10; __osRestoreInt(saveMask); 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/os/seteventmesg.c b/src/libultra/os/seteventmesg.c index 723d1dafc..8be2ff9e2 100644 --- a/src/libultra/os/seteventmesg.c +++ b/src/libultra/os/seteventmesg.c @@ -17,7 +17,7 @@ void osSetEventMesg(OSEvent e, OSMesgQueue* mq, OSMesg m) { if (e == 14) { if (__osShutdown != 0 && D_80097F10 == 0) { - osSendMesg(mq, m, 0); + osSendMesg(mq, m, OS_MESG_NOBLOCK); } D_80097F10 = 1; } diff --git a/src/libultra/os/timerintr.c b/src/libultra/os/timerintr.c index 4c0083139..87f7129df 100644 --- a/src/libultra/os/timerintr.c +++ b/src/libultra/os/timerintr.c @@ -49,7 +49,7 @@ void __osTimerInterrupt(void) { t->next = NULL; t->prev = NULL; if (t->mq != NULL) { - osSendMesg(t->mq, t->msg, 0); + osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK); } if (t->interval != 0) { t->value = t->interval; diff --git a/src/libultra/os/virtualtophysical.c b/src/libultra/os/virtualtophysical.c index 40d286479..6bdb2ccb3 100644 --- a/src/libultra/os/virtualtophysical.c +++ b/src/libultra/os/virtualtophysical.c @@ -1,6 +1,6 @@ #include "PR/ultratypes.h" #include "osint.h" -#include "stdint.h" +#include "libc/stdint.h" #include "global.h" uintptr_t osVirtualToPhysical(void* virtualAddress) { diff --git a/src/libultra/rmon/xldtob.c b/src/libultra/rmon/xldtob.c index be5ad3acb..65ffc7a92 100644 --- a/src/libultra/rmon/xldtob.c +++ b/src/libultra/rmon/xldtob.c @@ -1,7 +1,275 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/xldtob/_Ldtob.s") +#define BUFF_LEN 0x20 -#pragma GLOBAL_ASM("asm/non_matchings/boot/xldtob/_Ldunscale.s") +s16 _Ldunscale(s16*, _Pft*); +void _Genld(_Pft*, u8, u8*, s16, s16); -#pragma GLOBAL_ASM("asm/non_matchings/boot/xldtob/_Genld.s") +const f64 digs[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L }; + +/* float properties */ +#define _D0 0 +#define _DBIAS 0x3ff +#define _DLONG 1 +#define _DOFF 4 +#define _FBIAS 0x7e +#define _FOFF 7 +#define _FRND 1 +#define _LBIAS 0x3ffe +#define _LOFF 15 +/* integer properties */ +#define _C2 1 +#define _CSIGN 1 +#define _ILONG 0 +#define _MBMAX 8 +#define NAN 2 +#define INF 1 +#define FINITE -1 +#define _DFRAC ((1 << _DOFF) - 1) +#define _DMASK (0x7fff & ~_DFRAC) +#define _DMAX ((1 << (15 - _DOFF)) - 1) +#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1)) +#define _DSIGN 0x8000 +#if _D0 == 3 +#define _D1 2 /* little-endian order */ +#define _D2 1 +#define _D3 0 +#else +#define _D1 1 /* big-endian order */ +#define _D2 2 +#define _D3 3 +#endif + +void _Ldtob(_Pft* args, u8 type) { + u8 buff[BUFF_LEN]; + u8* ptr = buff; + u32 sp70; + f64 val = args->v.ld; + /* maybe struct? */ + s16 err; + s16 nsig; + s16 exp; + s32 i; + s32 n; + f64 factor; + s32 gen; + s32 j; + s32 lo; + ldiv_t qr; + u8 drop; + s32 n2; + + if (args->prec < 0) { + args->prec = 6; + } else if (args->prec == 0 && (type == 'g' || type == 'G')) { + args->prec = 1; + } + err = _Ldunscale(&exp, (_Pft*)args); + if (err > 0) { + memcpy(args->s, err == 2 ? "NaN" : "Inf", args->n1 = 3); + return; + } + if (err == 0) { + nsig = 0; + exp = 0; + } else { + if (val < 0) { + val = -val; + } + exp = exp * 30103 / 0x000186A0 - 4; + if (exp < 0) { + n = (3 - exp) & ~3; + exp = -n; + for (i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + val *= digs[i]; + } + } + } else if (exp > 0) { + factor = 1; + exp &= ~3; + + for (n = exp, i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + factor *= digs[i]; + } + } + val /= factor; + } + gen = ((type == 'f') ? exp + 10 : 6) + args->prec; + if (gen > 0x13) { + gen = 0x13; + } + *ptr++ = '0'; + while (gen > 0 && 0 < val) { + lo = val; + if ((gen -= 8) > 0) { + val = (val - lo) * 1.0e8; + } + ptr = ptr + 8; + for (j = 8; lo > 0 && --j >= 0;) { + qr = ldiv(lo, 10); + *--ptr = qr.rem + '0'; + lo = qr.quot; + } + while (--j >= 0) { + ptr--; + *ptr = '0'; + } + ptr += 8; + } + + gen = ptr - &buff[1]; + for (ptr = &buff[1], exp += 7; *ptr == '0'; ptr++) { + --gen, --exp; + } + + nsig = ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)) + args->prec; + if (gen < nsig) { + nsig = gen; + } + if (nsig > 0) { + if (nsig < gen && ptr[nsig] > '4') { + drop = '9'; + } else { + drop = '0'; + } + + for (n2 = nsig; ptr[--n2] == drop;) { + nsig--; + } + if (drop == '9') { + ptr[n2]++; + } + if (n2 < 0) { + --ptr, ++nsig, ++exp; + } + } + } + _Genld((_Pft*)args, type, ptr, nsig, exp); +} + +s16 _Ldunscale(s16* pex, _Pft* px) { + u16* ps = (u16*)px; + s16 xchar = (ps[_D0] & _DMASK) >> _DOFF; + + if (xchar == _DMAX) { /* NaN or INF */ + *pex = 0; + return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF); + } else if (0 < xchar) { + ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF); + *pex = xchar - (_DBIAS - 1); + return FINITE; + } + if (0 > xchar) { + return NAN; + } else { + *pex = 0; + return 0; + } +} + +void _Genld(_Pft* px, u8 code, u8* p, s16 nsig, s16 xexp) { + u8 point = '.'; + + if (nsig <= 0) { + nsig = 1, + + p = (u8*)"0"; + } + + if (code == 'f' || ((code == 'g' || code == 'G') && (-4 <= xexp) && (xexp < px->prec))) { /* 'f' format */ + ++xexp; /* change to leading digit count */ + if (code != 'f') { /* fixup for 'g' */ + if (!(px->flags & FLAGS_HASH) && nsig < px->prec) { + px->prec = nsig; + } + if ((px->prec -= xexp) < 0) { + px->prec = 0; + } + } + if (xexp <= 0) { /* digits only to right of point */ + px->s[px->n1++] = '0'; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (px->prec < -xexp) { + xexp = -px->prec; + } + px->nz1 = -xexp; + px->prec += xexp; + if (px->prec < nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p, px->n2 = nsig); + px->nz2 = px->prec - nsig; + } else if (nsig < xexp) { /* zeros before point */ + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = xexp - nsig; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1] = point, ++px->n2; + } + px->nz2 = px->prec; + } else { /* enough digits before point */ + memcpy(&px->s[px->n1], p, xexp); + px->n1 += xexp; + nsig -= xexp; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (px->prec < nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p + xexp, nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + } else { /* 'e' format */ + if (code == 'g' || code == 'G') { /* fixup for 'g' */ + if (nsig < px->prec) { + px->prec = nsig; + } + if (--px->prec < 0) { + px->prec = 0; + } + code = code == 'g' ? 'e' : 'E'; + } + px->s[px->n1++] = *p++; + if (0 < px->prec || px->flags & FLAGS_HASH) { + px->s[px->n1++] = point; + } + if (0 < px->prec) { /* put fraction digits */ + if (px->prec < --nsig) { + nsig = px->prec; + } + memcpy(&px->s[px->n1], p, nsig); + px->n1 += nsig; + px->nz1 = px->prec - nsig; + } + p = (u8*)&px->s[px->n1]; /* put exponent */ + *p++ = code; + if (0 <= xexp) { + *p++ = '+'; + } else { /* negative exponent */ + *p++ = '-'; + xexp = -xexp; + } + if (100 <= xexp) { /* put oversize exponent */ + if (1000 <= xexp) { + *p++ = xexp / 1000 + '0', xexp %= 1000; + } + *p++ = xexp / 100 + '0', xexp %= 100; + } + *p++ = xexp / 10 + '0', xexp %= 10; + *p++ = xexp + '0'; + px->n2 = p - (u8*)&px->s[px->n1]; + } + if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */ + s32 n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2; + + if (n < px->width) { + px->nz0 = px->width - n; + } + } +} diff --git a/src/libultra/rmon/xlitob.c b/src/libultra/rmon/xlitob.c index e5a280c5e..f200e01a4 100644 --- a/src/libultra/rmon/xlitob.c +++ b/src/libultra/rmon/xlitob.c @@ -1,3 +1,56 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/xlitob/_Litob.s") +#define BUFF_LEN 0x18 + +u8 ldigs[] = "0123456789abcdef"; +u8 udigs[] = "0123456789ABCDEF"; + +void _Litob(_Pft* args, u8 type) { + u8 buff[BUFF_LEN]; + const u8* numMap; + s32 base; + s32 idx; + u64 num; + lldiv_t quotrem; + + if (type == 'X') { + numMap = udigs; + } else { + numMap = ldigs; + } + + base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); + idx = BUFF_LEN; + num = args->v.ll; + + if ((type == 'd' || type == 'i') && args->v.ll < 0) { + num = -num; + } + + if (num != 0 || args->prec != 0) { + buff[--idx] = numMap[num % base]; + } + + args->v.ll = num / base; + + while (args->v.ll > 0 && idx > 0) { + quotrem = lldiv(args->v.ll, base); + args->v.ll = quotrem.quot; + buff[--idx] = numMap[quotrem.rem]; + } + + args->n1 = BUFF_LEN - idx; + + memcpy(args->s, buff + idx, args->n1); + + if (args->n1 < args->prec) { + args->nz0 = args->prec - args->n1; + } + + if (args->prec < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { + idx = args->width - args->n0 - args->nz0 - args->n1; + if (idx > 0) { + args->nz0 += idx; + } + } +} diff --git a/src/libultra/rmon/xprintf.c b/src/libultra/rmon/xprintf.c index 0f4353f2a..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; \ @@ -25,12 +25,6 @@ } \ } -#define FLAGS_SPACE 1 -#define FLAGS_PLUS 2 -#define FLAGS_MINUS 4 -#define FLAGS_HASH 8 -#define FLAGS_ZERO 16 - char spaces[] = " "; char zeroes[] = "00000000000000000000000000000000"; diff --git a/src/libultra/voice/voicecontrolgain.c b/src/libultra/voice/voicecontrolgain.c index 9dc541cc5..d7ec8ef69 100644 --- a/src/libultra/voice/voicecontrolgain.c +++ b/src/libultra/voice/voicecontrolgain.c @@ -1,3 +1,5 @@ #include "global.h" +u8 D_80098180[] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0 }; + #pragma GLOBAL_ASM("asm/non_matchings/boot/voicecontrolgain/osVoiceControlGain.s") diff --git a/src/libultra/voice/voicecrc.c b/src/libultra/voice/voicecrc.c index cc23e89dd..35b7b8656 100644 --- a/src/libultra/voice/voicecrc.c +++ b/src/libultra/voice/voicecrc.c @@ -1,3 +1,48 @@ +/** + * File: voicecrc.c + * Description: CRC check used by the Voice library functions in libultra. + * + * For general information about CRC, see the crc.c file (that's a lot of c's!). + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/voicecrc/__osVoiceContDataCrc.s") +#define VOICE_CRC_LENGTH 8 +#define VOICE_CRC_GENERATOR 0x85 + +/** + * This function is essentially the same as __osContDataCrc, but allows for a variable message length, specified by + * `numBytes`. + */ +u8 __osVoiceContDataCrc(u8* data, size_t numBytes) { + s32 ret = 0; + u32 bit; + size_t byte; + + for (byte = numBytes; byte != 0; byte--, data++) { + // Loop over each bit in the byte starting with most significant + for (bit = (1 << (VOICE_CRC_LENGTH - 1)); bit != 0; bit >>= 1) { + ret <<= 1; + if (*data & bit) { + if (ret & (1 << VOICE_CRC_LENGTH)) { + // Same as ret++; ret ^= 0x85 since last bit always 0 after the shift + ret ^= VOICE_CRC_GENERATOR - 1; + } else { + ret++; + } + } else if (ret & (1 << VOICE_CRC_LENGTH)) { + ret ^= VOICE_CRC_GENERATOR; + } + } + } + // Act like a byte of zeros is appended to data + do { + ret <<= 1; + if (ret & (1 << VOICE_CRC_LENGTH)) { + ret ^= VOICE_CRC_GENERATOR; + } + byte++; + } while (byte < VOICE_CRC_LENGTH); + + // Discarding the excess is done automatically by the return type + return ret; +} diff --git a/src/libultra/voice/voicegetstatus.c b/src/libultra/voice/voicegetstatus.c index 1711eb56d..d8e7edb67 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 (ret != CONT_ERR_CONTRFAIL) { - __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osContPifRam.status = CONT_CMD_READ_BUTTON; for (i = 0; i < port; i++, *ptr++ = 0) { ; @@ -24,7 +24,7 @@ s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) { ptr += 4; *ptr = CONT_CMD_END; - __osContLastCmd = CONT_CMD_END; + __osContLastPoll = CONT_CMD_END; ret = __osSiRawStartDma(OS_WRITE, &__osContPifRam); osRecvMesg(mq, NULL, OS_MESG_BLOCK); } diff --git a/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c b/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c index 62bac2109..16aa93bd9 100644 --- a/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c +++ b/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.c @@ -1,6 +1,14 @@ -#include "z_arms_hook.h" +/* + * File: z_arms_hook.c + * Overlay: ovl_Arms_Hook + * Description: Hookshot tip + */ -#define FLAGS 0x00000030 +#include "z_arms_hook.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_link_child/object_link_child.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ArmsHook*)thisx) @@ -44,8 +52,6 @@ static ColliderQuadInit D_808C1BC0 = { { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -extern Gfx D_0601D960[]; - void ArmsHook_SetupAction(ArmsHook* this, ArmsHookActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -71,7 +77,7 @@ void ArmsHook_Destroy(Actor* thisx, GlobalContext* globalCtx) { void ArmsHook_Wait(ArmsHook* this, GlobalContext* globalCtx) { if (this->actor.parent == NULL) { ArmsHook_SetupAction(this, ArmsHook_Shoot); - func_800B6C04(&this->actor, 20.0f); + Actor_SetSpeeds(&this->actor, 20.0f); this->actor.parent = &GET_PLAYER(globalCtx)->actor; this->timer = 26; } @@ -84,7 +90,7 @@ void func_808C1154(ArmsHook* this) { s32 ArmsHook_AttachToPlayer(ArmsHook* this, Player* player) { player->actor.child = &this->actor; - player->leftHandActor = &this->actor; + player->heldActor = &this->actor; if (this->actor.child != NULL) { player->actor.parent = this->actor.child = NULL; return 1; @@ -102,7 +108,7 @@ void ArmsHook_DetachHookFromActor(ArmsHook* this) { s32 ArmsHook_CheckForCancel(ArmsHook* this) { Player* player = (Player*)this->actor.parent; if (func_801240C8(player)) { - if ((player->heldItemActionParam != player->itemActionParam) || ((player->actor.flags & 0x100)) || + if ((player->heldItemActionParam != player->itemActionParam) || ((player->actor.flags & ACTOR_FLAG_100)) || ((player->stateFlags1 & 0x4000080))) { this->timer = 0; ArmsHook_DetachHookFromActor(this); @@ -143,7 +149,7 @@ void ArmsHook_Shoot(ArmsHook* this, GlobalContext* globalCtx) { } } this->timer = 0; - func_8019F1C0(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_STICK_CRE); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_STICK_CRE); return; } @@ -164,7 +170,8 @@ void ArmsHook_Shoot(ArmsHook* this, GlobalContext* globalCtx) { } else { if (this->actor.child != NULL) { f32 sp94 = Actor_DistanceBetweenActors(&this->actor, grabbed); - f32 sp90 = sqrtf(SQ(this->unk1FC.x) + SQ(this->unk1FC.y) + SQ(this->unk1FC.z)); + f32 sp90 = sqrtf(SQXYZ(this->unk1FC)); + Math_Vec3f_Diff(&grabbed->world.pos, &this->unk1FC, &this->actor.world.pos); if (50.0f < (sp94 - sp90)) { ArmsHook_DetachHookFromActor(this); @@ -211,8 +218,7 @@ void ArmsHook_Shoot(ArmsHook* this, GlobalContext* globalCtx) { } } else { Math_Vec3f_Diff(&bodyDistDiffVec, &newPos, &player->actor.velocity); - player->actor.world.rot.x = - Math_FAtan2F(sqrtf(SQ(bodyDistDiffVec.x) + SQ(bodyDistDiffVec.z)), -bodyDistDiffVec.y); + player->actor.world.rot.x = Math_FAtan2F(sqrtf(SQXZ(bodyDistDiffVec)), -bodyDistDiffVec.y); } if (phi_f16 < 50.0f) { ArmsHook_DetachHookFromActor(this); @@ -226,40 +232,43 @@ void ArmsHook_Shoot(ArmsHook* this, GlobalContext* globalCtx) { } } else { CollisionPoly* poly; - u32 bgId; - Vec3f sp78; + s32 bgId; + Vec3f posResult; Vec3f prevFrameDiff; Vec3f sp60; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Math_Vec3f_Diff(&this->actor.world.pos, &this->actor.prevPos, &prevFrameDiff); Math_Vec3f_Sum(&this->unk1E0, &prevFrameDiff, &this->unk1E0); this->actor.shape.rot.x = Math_FAtan2F(this->actor.speedXZ, -this->actor.velocity.y); sp60.x = this->unk1EC.x - (this->unk1E0.x - this->unk1EC.x); sp60.y = this->unk1EC.y - (this->unk1E0.y - this->unk1EC.y); sp60.z = this->unk1EC.z - (this->unk1E0.z - this->unk1EC.z); - if (func_800C55C4(&globalCtx->colCtx, &sp60, &this->unk1E0, &sp78, &poly, 1, 1, 1, 1, &bgId) != 0 && - (func_800B90AC(globalCtx, &this->actor, poly, bgId, &sp78) == 0 || - func_800C576C(&globalCtx->colCtx, &sp60, &this->unk1E0, &sp78, &poly, 1, 1, 1, 1, &bgId) != 0)) { - f32 sp5C = poly->normal.x * (1 / SHT_MAX); - f32 sp58 = poly->normal.z * (1 / SHT_MAX); + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &sp60, &this->unk1E0, &posResult, &poly, true, true, true, true, + &bgId) && + (func_800B90AC(globalCtx, &this->actor, poly, bgId, &posResult) == 0 || + BgCheck_ProjectileLineTest(&globalCtx->colCtx, &sp60, &this->unk1E0, &posResult, &poly, true, true, true, + true, &bgId))) { + f32 nx = COLPOLY_GET_NORMAL(poly->normal.x); + f32 nz = COLPOLY_GET_NORMAL(poly->normal.z); - Math_Vec3f_Copy(&this->actor.world.pos, &sp78); - this->actor.world.pos.x += 10.0f * sp5C; - this->actor.world.pos.z += 10.0f * sp58; + Math_Vec3f_Copy(&this->actor.world.pos, &posResult); + this->actor.world.pos.x += 10.0f * nx; + this->actor.world.pos.z += 10.0f * nz; this->timer = 1; - if (func_800C9CEC(&globalCtx->colCtx, poly, bgId)) { + if (SurfaceType_IsHookshotSurface(&globalCtx->colCtx, poly, bgId)) { { DynaPolyActor* dynaPolyActor; - if (bgId != 0x32 && (dynaPolyActor = BgCheck_GetActorOfMesh(&globalCtx->colCtx, bgId)) != NULL) { + if (bgId != BGCHECK_SCENE && + (dynaPolyActor = DynaPoly_GetActor(&globalCtx->colCtx, bgId)) != NULL) { ArmsHook_AttachHookToActor(this, &dynaPolyActor->actor); } } func_808C1154(this); - func_8019F1C0(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_STICK_OBJ); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_STICK_OBJ); } else { CollisionCheck_SpawnShieldParticlesMetal(globalCtx, &this->actor.world.pos); - func_8019F1C0(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_REFLECT); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_IT_HOOKSHOT_REFLECT); } } else { if (CHECK_BTN_ANY(CONTROLLER1(globalCtx)->press.button, @@ -300,32 +309,31 @@ void ArmsHook_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); if ((ArmsHook_Shoot != this->actionFunc) || (this->timer <= 0)) { - Matrix_MultiplyVector3fByState(&D_808C1C10, &this->unk1E0); - Matrix_MultiplyVector3fByState(&D_808C1C28, &sp5C); - Matrix_MultiplyVector3fByState(&D_808C1C34, &sp50); - this->unk1C4 = 0; + Matrix_MultVec3f(&D_808C1C10, &this->unk1E0); + Matrix_MultVec3f(&D_808C1C28, &sp5C); + Matrix_MultVec3f(&D_808C1C34, &sp50); + this->unk1C4.active = false; } else { - Matrix_MultiplyVector3fByState(&D_808C1C1C, &this->unk1E0); - Matrix_MultiplyVector3fByState(&D_808C1C40, &sp5C); - Matrix_MultiplyVector3fByState(&D_808C1C4C, &sp50); + Matrix_MultVec3f(&D_808C1C1C, &this->unk1E0); + Matrix_MultVec3f(&D_808C1C40, &sp5C); + Matrix_MultVec3f(&D_808C1C4C, &sp50); } - func_80126440(globalCtx, &this->collider.base, &this->unk1C4, &sp5C, &sp50); + func_80126440(globalCtx, &this->collider, &this->unk1C4, &sp5C, &sp50); func_8012C28C(globalCtx->state.gfxCtx); func_80122868(globalCtx, player); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_0601D960); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, - MTXMODE_NEW); + gSPDisplayList(POLY_OPA_DISP++, object_link_child_DL_01D960); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); Math_Vec3f_Diff(&player->rightHandWorld.pos, &this->actor.world.pos, &sp68); sp48 = SQXZ(sp68); sp4C = sqrtf(SQXZ(sp68)); - Matrix_RotateY(Math_Atan2S(sp68.x, sp68.z), MTXMODE_APPLY); - Matrix_InsertXRotation_s(Math_Atan2S(-sp68.y, sp4C), MTXMODE_APPLY); + Matrix_RotateYS(Math_Atan2S(sp68.x, sp68.z), MTXMODE_APPLY); + Matrix_RotateXS(Math_Atan2S(-sp68.y, sp4C), MTXMODE_APPLY); f0 = sqrtf(SQ(sp68.y) + sp48); Matrix_Scale(0.015f, 0.015f, f0 * 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++, D_040008D0); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0008D0); func_801229A0(globalCtx, player); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.h b/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.h index ecccf5ff0..527d37b61 100644 --- a/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.h +++ b/src/overlays/actors/ovl_Arms_Hook/z_arms_hook.h @@ -10,8 +10,7 @@ typedef void (*ArmsHookActionFunc)(struct ArmsHook*, GlobalContext*); typedef struct ArmsHook { /* 0x000 */ Actor actor; /* 0x144 */ ColliderQuad collider; - /* 0x1C4 */ s32 unk1C4; - /* 0x1C8 */ char unk1C8[0x18]; + /* 0x1C4 */ WeaponInfo unk1C4; /* 0x1E0 */ Vec3f unk1E0; /* 0x1EC */ Vec3f unk1EC; /* 0x1F8 */ Actor* grabbed; diff --git a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c index eb941df6e..6a2590259 100644 --- a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c +++ b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.c @@ -1,6 +1,13 @@ -#include "z_arrow_fire.h" +/* + * File: z_arrow_fire.c + * Overlay: ovl_Arrow_Fire + * Description: Fire Arrow + */ -#define FLAGS 0x02000010 +#include "z_arrow_fire.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((ArrowFire*)thisx) @@ -9,19 +16,10 @@ void ArrowFire_Destroy(Actor* thisx, GlobalContext* globalCtx); void ArrowFire_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowFire_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80920440(ArrowFire* this, GlobalContext* globalCtx); -void func_8092058C(ArrowFire* this, GlobalContext* globalCtx); -void func_809207A0(ArrowFire* this, GlobalContext* globalCtx); +void FireArrow_ChargeAndWait(ArrowFire* this, GlobalContext* globalCtx); +void FireArrow_Fly(ArrowFire* this, GlobalContext* globalCtx); -void ArrowFire_SetupAction(ArrowFire* this, ArrowFireActionFunc actionFunc); - -#if 0 -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_80922230 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_TYPE_PLAYER, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0x08000000, 0x00, 0x02 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, - { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, -}; +#include "overlays/ovl_Arrow_fire/ovl_Arrow_Fire.c" const ActorInit Arrow_Fire_InitVars = { ACTOR_ARROW_FIRE, @@ -35,28 +33,264 @@ const ActorInit Arrow_Fire_InitVars = { (ActorFunc)ArrowFire_Draw, }; -#endif +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_TYPE_PLAYER, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x08000000, 0x00, 0x02 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, + { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, +}; -extern ColliderQuadInit D_80922230; +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), +}; -extern UNK_TYPE D_0E0002E0; +s32 sUnused; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_SetupAction.s") +void ArrowFire_SetupAction(ArrowFire* this, ArrowFireActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Init.s") +void ArrowFire_Init(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Destroy.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->radius = 0; + this->height = 1.0f; + ArrowFire_SetupAction(this, FireArrow_ChargeAndWait); + Actor_SetScale(&this->actor, 0.01f); + this->alpha = 160; + this->timer = 0; + this->screenFillIntensity = 0.0f; + Collider_InitAndSetQuad(globalCtx, &this->collider1, &this->actor, &sQuadInit); + Collider_InitAndSetQuad(globalCtx, &this->collider2, &this->actor, &sQuadInit); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_80920440.s") +void ArrowFire_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/FireArrow_Lerp.s") + func_80115D5C(&globalCtx->state); + Collider_DestroyQuad(globalCtx, &this->collider1); + Collider_DestroyQuad(globalCtx, &this->collider2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_8092058C.s") +void FireArrow_ChargeAndWait(ArrowFire* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_809207A0.s") + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + if (this->radius < 10) { + this->radius++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Update.s") + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/func_80920948.s") + func_800B9010(&this->actor, NA_SE_PL_ARROW_CHARGE_FIRE - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Fire/ArrowFire_Draw.s") + // if arrow has no parent, player has fired the arrow + if (arrow->actor.parent == NULL) { + this->firedPos = this->actor.world.pos; + this->radius = 10; + ArrowFire_SetupAction(this, FireArrow_Fly); + this->alpha = 255; + } +} + +void FireArrow_Lerp(Vec3f* firedPos, Vec3f* pos, f32 scale) { + VEC3F_LERPIMPDST(firedPos, firedPos, pos, scale); +} + +void FireArrow_Hit(ArrowFire* this, GlobalContext* globalCtx) { + f32 offset; + f32 scale; + u16 timer; + + if (this->actor.projectedW < 50.0f) { + scale = 10.0f; + } else if (this->actor.projectedW > 950.0f) { + scale = 310.0f; + } else { + scale = this->actor.projectedW; + scale = ((scale - 50.0f) * (1.0f / 3.0f)) + 10.0f; + } + + timer = this->timer; + if (timer != 0) { + this->timer--; + if (this->timer >= 8) { + offset = (this->timer - 8) * (1.0f / 24.0f); + offset = SQ(offset); + this->radius = (((1.0f - offset) * scale) + 10.0f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); + if (this->timer < 16) { + this->alpha = (this->timer * 35) - 280; + } + } + } + if (this->timer >= 9) { + if (this->screenFillIntensity < 1.0f) { + this->screenFillIntensity += 0.25f; + } + } else { + if (this->screenFillIntensity > 0.0f) { + this->screenFillIntensity -= 0.125f; + } + } + if (this->timer < 8) { + this->alpha = 0; + } + if (this->timer == 0) { + this->timer = 255; + Actor_MarkForDeath(&this->actor); + return; + } + if (this->timer >= 13) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } +} + +void FireArrow_Fly(ArrowFire* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; + s32 pad; + s32 pad2; + + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; + + this->height = Math_Vec3f_DistXYZ(&this->firedPos, &this->actor.world.pos) * (1.0f / 24.0f); + + if (this->height < 1.0f) { + this->height = 1.0f; + } + + FireArrow_Lerp(&this->firedPos, &this->actor.world.pos, 0.05f); + if (arrow->unk_261 & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_EXPLOSION_FRAME); + ArrowFire_SetupAction(this, FireArrow_Hit); + this->timer = 32; + this->alpha = 255; + return; + } + if (arrow->unk_260 < 34) { + if (this->alpha < 35) { + Actor_MarkForDeath(&this->actor); + return; + } + this->alpha -= 25; + } +} + +void ArrowFire_Update(Actor* thisx, GlobalContext* globalCtx) { + ArrowFire* this = (ArrowFire*)thisx; + + if ((globalCtx->msgCtx.msgMode == 0xE) || (globalCtx->msgCtx.msgMode == 0x12)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc(this, globalCtx); +} + +void FireArrow_SetQuadVerticies(ArrowFire* this) { + static Vec3f D_80922284 = { 100.0f, 700.0f, 0.0f }; + static Vec3f D_80922290 = { 400.0f, 27.0f, 0.0f }; + static Vec3f D_8092229C = { -100.0f, 700.0f, 0.0f }; + static Vec3f D_809222A8 = { -400, 27.0f, 0.0f }; + static Vec3f D_809222B4 = { 0.0f, 700.0f, 100.0f }; + static Vec3f D_809222C0 = { 0.0f, 27.0f, 400.0f }; + static Vec3f D_809222CC = { 0.0f, 700.0f, -100.0f }; + static Vec3f D_809222D8 = { 0.0f, 27.0f, -400.0f }; + Vec3f sp44; + Vec3f sp38; + Vec3f sp2C; + Vec3f sp20; + + Matrix_MultVec3f(&D_80922284, &sp44); + Matrix_MultVec3f(&D_80922290, &sp38); + Matrix_MultVec3f(&D_8092229C, &sp2C); + Matrix_MultVec3f(&D_809222A8, &sp20); + Collider_SetQuadVertices(&this->collider1, &sp44, &sp38, &sp2C, &sp20); + Matrix_MultVec3f(&D_809222B4, &sp44); + Matrix_MultVec3f(&D_809222C0, &sp38); + Matrix_MultVec3f(&D_809222CC, &sp2C); + Matrix_MultVec3f(&D_809222D8, &sp20); + Collider_SetQuadVertices(&this->collider2, &sp44, &sp38, &sp2C, &sp20); +} + +void ArrowFire_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnArrow* arrow; + ArrowFire* this = THIS; + u32 frames = globalCtx->state.frames; + s32 pad; + + arrow = (EnArrow*)this->actor.parent; + + if ((arrow != NULL) && (arrow->actor.update != NULL) && (this->timer < 255)) { + Actor* transform = (arrow->unk_261 & 2) ? &this->actor : &arrow->actor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + Matrix_Translate(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(transform->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(transform->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(transform->shape.rot.z, MTXMODE_APPLY); + + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + if (this->screenFillIntensity > 0.0f) { + POLY_XLU_DISP = func_8012BFC4(POLY_XLU_DISP); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s32)(this->screenFillIntensity * 40.0f) & 0xFF, 0, 0, + (s32)(150.0f * this->screenFillIntensity) & 0xFF); + + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); + + gSPDisplayList(POLY_XLU_DISP++, D_0E000000.fillRect); + } + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 200, 0, this->alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); + + Matrix_RotateZYX(0x4000, 0, 0, MTXMODE_APPLY); + + if (this->timer != 0) { + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_Translate(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); + } + + Matrix_Scale(this->radius * 0.2f, this->height * 4.0f, this->radius * 0.2f, MTXMODE_APPLY); + Matrix_Translate(0.0f, -700.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + FireArrow_SetQuadVerticies(this); + gSPDisplayList(POLY_XLU_DISP++, gFireArrowMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 255 - ((frames * 2) % 256), 0, 64, 32, 1, + 255 - (frames % 256), 511 - ((frames * 10) % 512), 64, 64)); + gSPDisplayList(POLY_XLU_DISP++, gFireArrowModelDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h index bf1143cd9..5f9617c65 100644 --- a/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h +++ b/src/overlays/actors/ovl_Arrow_Fire/z_arrow_fire.h @@ -8,12 +8,19 @@ struct ArrowFire; typedef void (*ArrowFireActionFunc)(struct ArrowFire*, GlobalContext*); typedef struct ArrowFire { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x114]; - /* 0x0258 */ ArrowFireActionFunc actionFunc; - /* 0x025C */ char unk_25C[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderQuad collider1; + /* 0x1C4 */ ColliderQuad collider2; + /* 0x244 */ Vec3f firedPos; + /* 0x250 */ f32 height; + /* 0x254 */ f32 screenFillIntensity; + /* 0x258 */ ArrowFireActionFunc actionFunc; + /* 0x25C */ s16 radius; + /* 0x25E */ u16 timer; + /* 0x260 */ u8 alpha; } ArrowFire; // size = 0x264 + extern const ActorInit Arrow_Fire_InitVars; #endif // Z_ARROW_FIRE_H diff --git a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c index ed513eef3..6ae539178 100644 --- a/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c +++ b/src/overlays/actors/ovl_Arrow_Ice/z_arrow_ice.c @@ -7,7 +7,7 @@ #include "z_arrow_ice.h" #include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((ArrowIce*)thisx) @@ -17,7 +17,6 @@ void ArrowIce_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx); void ArrowIce_Charge(ArrowIce* this, GlobalContext* globalCtx); -void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx); void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx); #include "overlays/ovl_Arrow_Ice/ovl_Arrow_Ice.c" @@ -40,8 +39,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), }; -extern Gfx D_0E0002E0[]; - void ArrowIce_SetupAction(ArrowIce* this, ArrowIceActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -96,7 +93,6 @@ void ArrowIce_LerpFiredPosition(Vec3f* firedPos, Vec3f* icePos, f32 scale) { void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx) { f32 scale; - f32 offset; u16 timer; if (this->actor.projectedW < 50.0f) { @@ -113,12 +109,12 @@ void ArrowIce_Hit(ArrowIce* this, GlobalContext* globalCtx) { this->timer--; if (this->timer >= 8) { - offset = ((this->timer - 8) * (1.0f / 24.0f)); + f32 offset = ((this->timer - 8) * (1.0f / 24.0f)); + offset = SQ(offset); this->radius = (((1.0f - offset) * scale) + 10.0f); - this->height += ((2.0f - this->height) * 0.1f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); if (this->timer < 16) { - if (1) {} this->alpha = ((this->timer * 35) - 280); } } @@ -164,7 +160,7 @@ void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx) { ArrowIce_LerpFiredPosition(&this->firedPos, &this->actor.world.pos, 0.05f); if (arrow->unk_261 & 1) { - Audio_PlayActorSound2(&this->actor, NA_SE_IT_EXPLOSION_ICE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_EXPLOSION_ICE); ArrowIce_SetupAction(this, ArrowIce_Hit); this->timer = 32; this->alpha = 255; @@ -180,7 +176,7 @@ void ArrowIce_Fly(ArrowIce* this, GlobalContext* globalCtx) { void ArrowIce_Update(Actor* thisx, GlobalContext* globalCtx) { ArrowIce* this = THIS; - if ((globalCtx->msgCtx.unk11F22 == 0xE) || (globalCtx->msgCtx.unk11F22 == 0x12)) { + if ((globalCtx->msgCtx.msgMode == 0xE) || (globalCtx->msgCtx.msgMode == 0x12)) { Actor_MarkForDeath(&this->actor); return; } else { @@ -200,10 +196,10 @@ void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); - Matrix_RotateY(transform->shape.rot.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(transform->shape.rot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(transform->shape.rot.z, MTXMODE_APPLY); + Matrix_Translate(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(transform->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(transform->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(transform->shape.rot.z, MTXMODE_APPLY); Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); // Draw blue effect over the screen when arrow hits @@ -214,27 +210,27 @@ void ArrowIce_Draw(Actor* thisx, GlobalContext* globalCtx) { (s32)(150.0f * this->blueingEffectMagnitude) & 0xFF); gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); - gSPDisplayList(POLY_XLU_DISP++, D_0E0002E0); + gSPDisplayList(POLY_XLU_DISP++, D_0E000000.fillRect); } // Draw ice on the arrow func_8012C2DC(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 170, 255, 255, (s32)(this->alpha * 0.5f) & 0xFF); gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 128); - Matrix_InsertRotation(0x4000, 0, 0, MTXMODE_APPLY); + Matrix_RotateZYX(0x4000, 0, 0, MTXMODE_APPLY); if (this->timer != 0) { - Matrix_InsertTranslation(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); } else { - Matrix_InsertTranslation(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); } Matrix_Scale(this->radius * 0.2f, this->height * 3.0f, this->radius * 0.2f, MTXMODE_APPLY); - Matrix_InsertTranslation(0.0f, -700.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, -700.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++, sIceArrowDL); + gSPDisplayList(POLY_XLU_DISP++, gIceArrowMaterialDL); gSPDisplayList(POLY_XLU_DISP++, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 511 - (stateFrames * 5) % 512, 0, 128, 32, 1, 511 - (stateFrames * 10) % 512, 511 - (stateFrames * 10) % 512, 4, 16)); - gSPDisplayList(POLY_XLU_DISP++, sIceArrowVtxDL); + gSPDisplayList(POLY_XLU_DISP++, gIceArrowModelDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c index e39d08570..1b25b8fbb 100644 --- a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c +++ b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.c @@ -1,6 +1,13 @@ -#include "z_arrow_light.h" +/* + * File: z_arrow_light.c + * Overlay: ovl_Arrow_Light + * Description: Light Arrow + */ -#define FLAGS 0x02000010 +#include "z_arrow_light.h" +#include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((ArrowLight*)thisx) @@ -9,13 +16,11 @@ void ArrowLight_Destroy(Actor* thisx, GlobalContext* globalCtx); void ArrowLight_Update(Actor* thisx, GlobalContext* globalCtx); void ArrowLight_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809243AC(ArrowLight* this, GlobalContext* globalCtx); -void func_809244F8(ArrowLight* this, GlobalContext* globalCtx); -void func_809246C4(ArrowLight* this, GlobalContext* globalCtx); +void ArrowLight_Charge(ArrowLight* this, GlobalContext* globalCtx); +void ArrowLight_Fly(ArrowLight* this, GlobalContext* globalCtx); -void ArrowLight_SetupAction(ArrowLight* this, ArrowLightActionFunc actionFunc); +#include "overlays/ovl_Arrow_Light/ovl_Arrow_Light.c" -#if 0 const ActorInit Arrow_Light_InitVars = { ACTOR_ARROW_LIGHT, ACTORCAT_ITEMACTION, @@ -28,33 +33,198 @@ const ActorInit Arrow_Light_InitVars = { (ActorFunc)ArrowLight_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809260A0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), }; -#endif +static s32 sUnused; -extern InitChainEntry D_809260A0[]; +void ArrowLight_SetupAction(ArrowLight* this, ArrowLightActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern UNK_TYPE D_0E0002E0; +void ArrowLight_Init(Actor* thisx, GlobalContext* globalCtx) { + ArrowLight* this = (ArrowLight*)thisx; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->radius = 0; + this->height = 1.0f; + ArrowLight_SetupAction(this, ArrowLight_Charge); + Actor_SetScale(&this->actor, 0.01f); + this->alpha = 130; + this->timer = 0; + this->screenFillIntensity = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/D_809260B0.s") +void ArrowLight_Destroy(Actor* thisx, GlobalContext* globalCtx) { + func_80115D5C(&globalCtx->state); + (void)"消滅"; // Unreferenced in retail, means "Disappearance" +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_SetupAction.s") +void ArrowLight_Charge(ArrowLight* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Init.s") + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Destroy.s") + if (this->radius < 10) { + this->radius++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809243AC.s") + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809244A0.s") + func_800B9010(&this->actor, NA_SE_PL_ARROW_CHARGE_LIGHT - SFX_FLAG); + if (arrow->actor.parent == NULL) { + this->firedPos = this->actor.world.pos; + this->radius = 10; + ArrowLight_SetupAction(this, ArrowLight_Fly); + this->alpha = 255; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809244F8.s") +void ArrowLight_Lerp(Vec3f* firedPos, Vec3f* pos, f32 scale) { + VEC3F_LERPIMPDST(firedPos, firedPos, pos, scale); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/func_809246C4.s") +void ArrowLight_Hit(ArrowLight* this, GlobalContext* globalCtx) { + f32 scale; + u16 timer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Update.s") + if (this->actor.projectedW < 50.0f) { + scale = 10.0f; + } else if (this->actor.projectedW > 950.0f) { + scale = 310.0f; + } else { + scale = this->actor.projectedW; + scale = ((scale - 50.0f) * (1.0f / 3.0f)) + 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Arrow_Light/ArrowLight_Draw.s") + timer = this->timer; + if (timer != 0) { + this->timer--; + if (this->timer >= 8) { + f32 offset = (this->timer - 8) * (1.0f / 24.0f); + + offset = SQ(offset); + this->radius = (((1.0f - offset) * scale) + 10.0f); + this->height = F32_LERPIMP(this->height, 2.0f, 0.1f); + if (this->timer < 16) { + this->alpha = (this->timer * 35) - 280; + } + } + } + if (this->timer >= 9) { + if (this->screenFillIntensity < 1.0f) { + this->screenFillIntensity += 0.25f; + } + } else { + if (this->screenFillIntensity > 0.0f) { + this->screenFillIntensity -= 0.125f; + } + } + if (this->timer < 8) { + this->alpha = 0; + } + if (this->timer == 0) { + this->timer = 255; + Actor_MarkForDeath(&this->actor); + return; + } +} + +void ArrowLight_Fly(ArrowLight* this, GlobalContext* globalCtx) { + EnArrow* arrow = (EnArrow*)this->actor.parent; + s32 pad[2]; + + if ((arrow == NULL) || (arrow->actor.update == NULL)) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.world.pos = arrow->actor.world.pos; + this->actor.shape.rot = arrow->actor.shape.rot; + + this->height = Math_Vec3f_DistXYZ(&this->firedPos, &this->actor.world.pos) * (1.0f / 24.0f); + if (this->height < 1.0f) { + this->height = 1.0f; + } + + ArrowLight_Lerp(&this->firedPos, &this->actor.world.pos, 0.05f); + + if (arrow->unk_261 & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_EXPLOSION_LIGHT); + ArrowLight_SetupAction(this, ArrowLight_Hit); + this->timer = 32; + this->alpha = 255; + return; + } + if (arrow->unk_260 < 34) { + if (this->alpha < 35) { + Actor_MarkForDeath(&this->actor); + return; + } + this->alpha -= 25; + } +} + +void ArrowLight_Update(Actor* thisx, GlobalContext* globalCtx) { + ArrowLight* this = THIS; + + if ((globalCtx->msgCtx.msgMode == 0xE) || (globalCtx->msgCtx.msgMode == 0x12)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc(this, globalCtx); +} + +void ArrowLight_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ArrowLight* this = (ArrowLight*)thisx; + u32 frames = globalCtx->state.frames; + EnArrow* arrow = (EnArrow*)this->actor.parent; + + if ((arrow != NULL) && (arrow->actor.update != NULL) && (this->timer < 255)) { + Actor* transform = (arrow->unk_261 & 2) ? &this->actor : &arrow->actor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(transform->world.pos.x, transform->world.pos.y, transform->world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(transform->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(transform->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(transform->shape.rot.z, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + if (this->screenFillIntensity > 0.0f) { + POLY_XLU_DISP = func_8012BFC4(POLY_XLU_DISP); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s32)(this->screenFillIntensity * 30.0f) & 0xFF, + (s32)(40.0f * this->screenFillIntensity) & 0xFF, 0, + (s32)(150.0f * this->screenFillIntensity) & 0xFF); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_DISABLE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_DISABLE); + gSPDisplayList(POLY_XLU_DISP++, D_0E000000.fillRect); + } + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 170, this->alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 0, 128); + + Matrix_RotateZYX(0x4000, 0, 0, MTXMODE_APPLY); + if (this->timer != 0) { + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_Translate(0.0f, 1500.0f, 0.0f, MTXMODE_APPLY); + } + Matrix_Scale(this->radius * 0.2f, this->height * 4.0f, this->radius * 0.2f, MTXMODE_APPLY); + Matrix_Translate(0.0f, -700.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++, gLightArrowMaterialDL); + gSPDisplayList(POLY_XLU_DISP++, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 511 - ((frames * 5) % 512), 0, 4, 32, 1, + 511 - ((frames * 10) % 512), 511 - ((frames * 30) % 512), 8, 16)); + gSPDisplayList(POLY_XLU_DISP++, gLightArrowModelDL); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h index ef462cfde..7b3f3088f 100644 --- a/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h +++ b/src/overlays/actors/ovl_Arrow_Light/z_arrow_light.h @@ -8,11 +8,17 @@ struct ArrowLight; typedef void (*ArrowLightActionFunc)(struct ArrowLight*, GlobalContext*); typedef struct ArrowLight { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; - /* 0x0160 */ ArrowLightActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ s16 radius; + /* 0x146 */ u16 timer; + /* 0x148 */ u8 alpha; + /* 0x14C */ Vec3f firedPos; + /* 0x158 */ f32 height; + /* 0x15C */ f32 screenFillIntensity; + /* 0x160 */ ArrowLightActionFunc actionFunc; } ArrowLight; // size = 0x164 + extern const ActorInit Arrow_Light_InitVars; #endif // Z_ARROW_LIGHT_H diff --git a/src/overlays/actors/ovl_Bg_Astr_Bombwall/z_bg_astr_bombwall.c b/src/overlays/actors/ovl_Bg_Astr_Bombwall/z_bg_astr_bombwall.c index 2e48496c2..f2608b583 100644 --- a/src/overlays/actors/ovl_Bg_Astr_Bombwall/z_bg_astr_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Astr_Bombwall/z_bg_astr_bombwall.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_astr_bombwall.c + * Overlay: ovl_Bg_Astr_Bombwall + * Description: Astral Observatory - Bombable Wall + */ + #include "z_bg_astr_bombwall.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Botihasira/z_bg_botihasira.c b/src/overlays/actors/ovl_Bg_Botihasira/z_bg_botihasira.c index 086ca1c9d..7ca6678ff 100644 --- a/src/overlays/actors/ovl_Bg_Botihasira/z_bg_botihasira.c +++ b/src/overlays/actors/ovl_Bg_Botihasira/z_bg_botihasira.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_botihasira.c + * Overlay: ovl_Bg_Botihasira + * Description: Captain Keeta Race - Gatepost + */ + #include "z_bg_botihasira.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c index cb97f62a5..b2fe546cf 100644 --- a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c +++ b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.c @@ -1,6 +1,21 @@ -#include "z_bg_breakwall.h" +/* + * File: z_bg_breakwall.c + * Overlay: ovl_Bg_Breakwall + * Description: Great Bay Temple? (or the weather around it?) + */ -#define FLAGS 0x00000030 +#include "z_bg_breakwall.h" +#include "objects/object_omoya_obj/object_omoya_obj.h" +#include "objects/object_yukimura_obj/object_yukimura_obj.h" +#include "objects/object_keikoku_obj/object_keikoku_obj.h" +#include "objects/object_posthouse_obj/object_posthouse_obj.h" +#include "objects/object_kumo30/object_kumo30.h" +#include "objects/object_mnk/object_mnk.h" +#include "objects/object_ikninside_obj/object_ikninside_obj.h" +#include "objects/object_kaizoku_obj/object_kaizoku_obj.h" +#include "objects/object_spot11_obj/object_spot11_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgBreakwall*)thisx) @@ -8,80 +23,418 @@ void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx); void BgBreakwall_Update(Actor* thisx, GlobalContext* globalCtx); void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc); +s32 func_808B736C(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B7380(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B73C4(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B73FC(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B7410(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B7460(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B74A8(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B74D8(BgBreakwall* this, GlobalContext* globalCtx); +s32 func_808B751C(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B76CC(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B77D0(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B77E0(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B782C(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B78A4(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B78DC(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B7914(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B7A10(BgBreakwall* this, GlobalContext* globalCtx); +void func_808B7A90(Actor* thisx, GlobalContext* globalCtx); +void func_808B7B54(Actor* thisx, GlobalContext* globalCtx); +void func_808B7D34(Actor* thisx, GlobalContext* globalCtx); +void BgBreakwall_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Breakwall_InitVars = { - ACTOR_BG_BREAKWALL, - ACTORCAT_ITEMACTION, - FLAGS, - GAMEPLAY_KEEP, - sizeof(BgBreakwall), - (ActorFunc)BgBreakwall_Init, - (ActorFunc)NULL, - (ActorFunc)BgBreakwall_Update, - (ActorFunc)NULL, + ACTOR_BG_BREAKWALL, ACTORCAT_ITEMACTION, FLAGS, + GAMEPLAY_KEEP, sizeof(BgBreakwall), (ActorFunc)BgBreakwall_Init, + (ActorFunc)NULL, (ActorFunc)BgBreakwall_Update, (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808B82E0[] = { +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x04 */ Gfx* unk_04; + /* 0x08 */ Gfx* unk_08; + /* 0x0C */ AnimatedMaterial* unk_0C; + /* 0x10 */ CollisionHeader* unk_10; + /* 0x14 */ BgBreakwallUnkFunc unk_14; + /* 0x18 */ BgBreakwallUnkFunc2 unk_18; + /* 0x1C */ ActorFunc unk_1C; +} BgBreakwallStruct; + +BgBreakwallStruct D_808B8140[] = { + { OBJECT_OMOYA_OBJ, object_omoya_obj_DL_0001A0, NULL, NULL, NULL, func_808B7380, func_808B77D0, NULL }, + { OBJECT_YUKIMURA_OBJ, object_yukimura_obj_DL_000F98, object_yukimura_obj_DL_000EB0, + object_yukimura_obj_Matanimheader_002090, NULL, func_808B73C4, func_808B77D0, NULL }, + { OBJECT_KEIKOKU_OBJ, object_keikoku_obj_DL_0027D8, NULL, object_keikoku_obj_Matanimheader_004290, NULL, + func_808B73FC, func_808B77D0, NULL }, + { OBJECT_KEIKOKU_OBJ, object_keikoku_obj_DL_0044A8, NULL, NULL, NULL, func_808B736C, func_808B77D0, NULL }, + { OBJECT_POSTHOUSE_OBJ, object_posthouse_obj_DL_000A50, NULL, NULL, NULL, func_808B7410, func_808B77E0, NULL }, + { OBJECT_POSTHOUSE_OBJ, object_posthouse_obj_DL_001870, NULL, NULL, &object_posthouse_obj_Colheader_002948, + func_808B7460, func_808B782C, NULL }, + { OBJECT_KUMO30, NULL, object_kumo30_DL_002A40, object_kumo30_Matanimheader_003368, NULL, func_808B74A8, + func_808B78A4, func_808B7A90 }, + { OBJECT_KUMO30, NULL, NULL, object_kumo30_Matanimheader_002890, NULL, func_808B736C, func_808B78DC, + func_808B7B54 }, + { OBJECT_MNK, object_mnk_DL_000F58, NULL, object_mnk_Matanimheader_002E28, &object_mnk_Colheader_0033E8, + func_808B74D8, func_808B7914, NULL }, + { OBJECT_IKNINSIDE_OBJ, NULL, object_ikninside_obj_DL_00AB10, object_ikninside_obj_Matanimheader_00BCC8, NULL, + func_808B751C, func_808B7A10, func_808B7D34 }, + { OBJECT_KAIZOKU_OBJ, object_kaizoku_obj_DL_00AD50, NULL, NULL, &object_kaizoku_obj_Colheader_00B868, func_808B736C, + func_808B77D0, NULL }, + { OBJECT_IKNINSIDE_OBJ, NULL, object_ikninside_obj_DL_00AEC0, object_ikninside_obj_Matanimheader_00BCB8, NULL, + func_808B751C, func_808B7A10, func_808B7D34 }, + { OBJECT_SPOT11_OBJ, object_spot11_obj_DL_0013F0, NULL, NULL, &object_spot11_obj_Colheader_001EB8, func_808B736C, + func_808B77D0, NULL }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), }; -#endif +Color_RGBA8 D_808B82F0[] = { + { 255, 230, 240, 255 }, + { 255, 255, 255, 255 }, + { 255, 230, 220, 255 }, + { 80, 120, 160, 255 }, +}; -extern InitChainEntry D_808B82E0[]; +Color_RGBA8 D_808B8300[] = { + { 140, 60, 70, 255 }, + { 50, 150, 150, 255 }, + { 140, 60, 50, 255 }, + { 30, 40, 160, 255 }, +}; -extern UNK_TYPE D_06000A50; +Color_RGBA8 D_808B8310[] = { + { 210, 160, 180, 255 }, + { 120, 150, 160, 255 }, + { 210, 170, 160, 255 }, + { 70, 100, 120, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/BgBreakwall_SetupAction.s") +Color_RGBA8 D_808B8320[] = { + { 255, 240, 255, 255 }, + { 255, 255, 255, 255 }, + { 255, 255, 240, 255 }, + { 150, 170, 180, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B736C.s") +Color_RGBA8 D_808B8330[] = { + { 60, 20, 40, 255 }, + { 0, 50, 50, 255 }, + { 60, 30, 30, 255 }, + { 0, 20, 30, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7380.s") +Color_RGBA8 D_808B8340[] = { + { 160, 120, 140, 255 }, + { 100, 160, 150, 255 }, + { 160, 150, 120, 255 }, + { 60, 110, 110, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B73C4.s") +void BgBreakwall_SetupAction(BgBreakwall* this, BgBreakwallActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B73FC.s") +s32 func_808B736C(BgBreakwall* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7410.s") +s32 func_808B7380(BgBreakwall* this, GlobalContext* globalCtx) { + if ((gSaveContext.save.day >= 2) && !(gSaveContext.save.weekEventReg[22] & 1)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7460.s") +s32 func_808B73C4(BgBreakwall* this, GlobalContext* globalCtx) { + return (gSaveContext.save.weekEventReg[33] & 0x80) || (gSaveContext.save.weekEventReg[21] & 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B74A8.s") +s32 func_808B73FC(BgBreakwall* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B74D8.s") +s32 func_808B7410(BgBreakwall* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->dyna.actor.draw = NULL; + } + Actor_SetScale(&this->dyna.actor, 0.1f); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B751C.s") +s32 func_808B7460(BgBreakwall* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->dyna.actor.scale.x = 0.1f; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/BgBreakwall_Init.s") +s32 func_808B74A8(BgBreakwall* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B767C.s") +s32 func_808B74D8(BgBreakwall* this, GlobalContext* globalCtx) { + if (!(gSaveContext.save.weekEventReg[9] & 0x80) || (gSaveContext.save.weekEventReg[23] & 0x20)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B76CC.s") +s32 func_808B751C(BgBreakwall* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->dyna.actor, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B77D0.s") + if ((BGBREAKWALL_SWITCHFLAG(&this->dyna.actor) != 0x7F) && + !Flags_GetSwitch(globalCtx, BGBREAKWALL_SWITCHFLAG(&this->dyna.actor))) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B77E0.s") + func_800FEA50(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B782C.s") + if (gSaveContext.save.isNight) { + this->unk_15E = 0; + } else { + this->unk_15E = 255; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B78A4.s") +void BgBreakwall_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgBreakwall* this = THIS; + BgBreakwallStruct* sp24 = &D_808B8140[BGBREAKWALL_GET_F(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B78DC.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_15C = Object_GetIndex(&globalCtx->objectCtx, sp24->unk_00); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7914.s") + if ((this->unk_15C < 0) || !sp24->unk_14(this, globalCtx)) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7A10.s") + BgBreakwall_SetupAction(this, func_808B76CC); + this->switchFlag = BGBREAKWALL_SWITCHFLAG(&this->dyna.actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/BgBreakwall_Update.s") +void BgBreakwall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgBreakwall* this = THIS; + BgBreakwallStruct* temp_s1 = &D_808B8140[BGBREAKWALL_GET_F(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7A90.s") + if (temp_s1->unk_10 != NULL) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7B54.s") +void func_808B76CC(BgBreakwall* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_15C)) { + BgBreakwallStruct* temp_s1 = &D_808B8140[BGBREAKWALL_GET_F(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7D34.s") + this->dyna.actor.objBankIndex = this->unk_15C; + this->dyna.actor.draw = BgBreakwall_Draw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Breakwall/func_808B7FE4.s") + if (((BGBREAKWALL_GET_F(&this->dyna.actor)) != BGBREAKWALL_F_7) && + ((BGBREAKWALL_GET_F(&this->dyna.actor)) != BGBREAKWALL_F_9) && + ((BGBREAKWALL_GET_F(&this->dyna.actor)) != BGBREAKWALL_F_11)) { + this->dyna.actor.flags &= ~ACTOR_FLAG_10; + } + + Actor_SetObjectDependency(globalCtx, &this->dyna.actor); + + if (temp_s1->unk_0C != NULL) { + temp_s1->unk_0C = Lib_SegmentedToVirtual(temp_s1->unk_0C); + } + + if (temp_s1->unk_10 != NULL) { + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, temp_s1->unk_10); + } + + BgBreakwall_SetupAction(this, temp_s1->unk_18); + this->dyna.actor.destroy = BgBreakwall_Destroy; + } +} + +void func_808B77D0(BgBreakwall* this, GlobalContext* globalCtx) { +} + +void func_808B77E0(BgBreakwall* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->dyna.actor.draw = BgBreakwall_Draw; + } else { + this->dyna.actor.draw = NULL; + } +} + +void func_808B782C(BgBreakwall* this, GlobalContext* globalCtx) { + f32 phi_f0; + + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + phi_f0 = 1.0f; + } else { + phi_f0 = 0.1f; + } + Math_SmoothStepToF(&this->dyna.actor.scale.x, phi_f0, 0.2f, 0.3f, 0.06f); +} + +void func_808B78A4(BgBreakwall* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void func_808B78DC(BgBreakwall* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->dyna.actor, 3.5f); + func_800B9010(&this->dyna.actor, NA_SE_EV_TORNADE - SFX_FLAG); +} + +void func_808B7914(BgBreakwall* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + Vec3f sp24; + + if ((globalCtx->gameplayFrames % 8) == 0) { + sp30.x = Rand_ZeroFloat(80.0f) + (this->dyna.actor.world.pos.x - 55.0f); + sp30.y = this->dyna.actor.world.pos.y + 70.0f; + sp30.z = Rand_ZeroFloat(80.0f) + (this->dyna.actor.world.pos.z - 130.0f); + + sp24.x = 0.0f; + sp24.y = 0.5f; + sp24.z = 0.0f; + + EffectSsIceSmoke_Spawn(globalCtx, &sp30, &sp24, &gZeroVec3f, -200 - (s32)(Rand_ZeroOne() * 50.0f)); + } +} + +void func_808B7A10(BgBreakwall* this, GlobalContext* globalCtx) { + if (gSaveContext.save.isNight) { + if (this->unk_15E < 245) { + this->unk_15E += 10; + } else { + this->unk_15E = 255; + } + } else if (this->unk_15E > 10) { + this->unk_15E -= 10; + } else { + this->unk_15E = 0; + } +} + +void BgBreakwall_Update(Actor* thisx, GlobalContext* globalCtx) { + BgBreakwall* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void func_808B7A90(Actor* thisx, GlobalContext* globalCtx) { + Color_RGBA8 sp2C; + Color_RGBA8 sp28; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_800FE7A8(D_808B82F0, &sp2C); + func_800FE7A8(D_808B8300, &sp28); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, sp2C.r, sp2C.g, sp2C.b, 255); + gDPSetEnvColor(POLY_XLU_DISP++, sp28.r, sp28.g, sp28.b, 255); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_808B7B54(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + Color_RGBA8 sp50; + Color_RGBA8 sp4C; + + 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); + + func_800FE7A8(D_808B8310, &sp50); + func_800FE7A8(D_808B8330, &sp4C); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, sp50.r, sp50.g, sp50.b, 255); + gDPSetEnvColor(POLY_XLU_DISP++, sp4C.r, sp4C.g, sp4C.b, 255); + gSPDisplayList(POLY_XLU_DISP++, object_posthouse_obj_DL_000A50); + + func_800FE7A8(D_808B8320, &sp50); + func_800FE7A8(D_808B8340, &sp4C); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, sp50.r, sp50.g, sp50.b, 255); + gDPSetEnvColor(POLY_XLU_DISP++, sp4C.r, sp4C.g, sp4C.b, 255); + gSPDisplayList(POLY_XLU_DISP++, object_kumo30_DL_000C98); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_808B7D34(Actor* thisx, GlobalContext* globalCtx) { + BgBreakwall* this = THIS; + s32 sp48; + s32 tempA; + s32 tempB; + s32 tempC; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + sp48 = 255 - this->unk_15E; + + tempA = (((sp48 * 245) + (this->unk_15E * 255)) & 0xFF00) >> 8; + tempB = (((sp48 * 145) + (this->unk_15E * 85)) & 0xFF00) >> 8; + tempC = (((sp48 * 135) + (this->unk_15E * 55)) & 0xFF00) >> 8; + + gSPSegment(POLY_XLU_DISP++, 0x09, Gfx_PrimColor(globalCtx->state.gfxCtx, 255, 255, tempA, tempB, tempC)); + + tempA = (((sp48 * 255) + (this->unk_15E * 150)) & 0xFF00) >> 8; + tempB = (((sp48 * 255) + (this->unk_15E * 100)) & 0xFF00) >> 8; + tempC = (((sp48 * 255) + (this->unk_15E * 75)) & 0xFF00) >> 8; + + gSPSegment(POLY_XLU_DISP++, 0x0A, Gfx_PrimColor(globalCtx->state.gfxCtx, 255, tempA, tempA, tempB, tempC)); + + tempA = (((sp48 * 185) + (this->unk_15E * 140)) & 0xFF00) >> 8; + tempB = (((sp48 * 235) + (this->unk_15E * 45)) & 0xFF00) >> 8; + + gSPSegment(POLY_XLU_DISP++, 0x0B, Gfx_PrimColor(globalCtx->state.gfxCtx, 255, 255, 255, tempA, tempB)); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void BgBreakwall_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgBreakwall* this = THIS; + BgBreakwallStruct* temp_s2 = &D_808B8140[BGBREAKWALL_GET_F(&this->dyna.actor)]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (temp_s2->unk_0C != NULL) { + AnimatedMat_Draw(globalCtx, temp_s2->unk_0C); + } + + if (temp_s2->unk_1C != NULL) { + temp_s2->unk_1C(&this->dyna.actor, globalCtx); + } + + if (temp_s2->unk_04 != NULL) { + 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++, temp_s2->unk_04); + } + + if (temp_s2->unk_08 != NULL) { + 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++, temp_s2->unk_08); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h index 279aba17b..322929344 100644 --- a/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h +++ b/src/overlays/actors/ovl_Bg_Breakwall/z_bg_breakwall.h @@ -6,10 +6,23 @@ struct BgBreakwall; typedef void (*BgBreakwallActionFunc)(struct BgBreakwall*, GlobalContext*); +typedef s32 (*BgBreakwallUnkFunc)(struct BgBreakwall*, GlobalContext*); +typedef void (*BgBreakwallUnkFunc2)(struct BgBreakwall*, GlobalContext*); + +#define BGBREAKWALL_GET_F(thisx) ((thisx)-> params & 0xF) +#define BGBREAKWALL_SWITCHFLAG(thisx) (((thisx)-> params & 0xFE00) >> 9) + +enum { + /* 7 */ BGBREAKWALL_F_7 = 7, + /* 9 */ BGBREAKWALL_F_9 = 9, + /* 11 */ BGBREAKWALL_F_11 = 11, +}; typedef struct BgBreakwall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ s8 unk_15C; + /* 0x015D */ u8 switchFlag; + /* 0x015E */ u8 unk_15E; /* 0x0160 */ BgBreakwallActionFunc actionFunc; } BgBreakwall; // size = 0x164 diff --git a/src/overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.c b/src/overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.c index dac778945..c5613248a 100644 --- a/src/overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.c +++ b/src/overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_crace_movebg.c + * Overlay: ovl_Bg_Crace_Movebg + * Description: Huge sliding doors in Deku Shrine + */ + #include "z_bg_crace_movebg.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgCraceMovebg*)thisx) 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 18b8a343c..6ac390ce5 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 @@ -5,20 +5,12 @@ */ #include "z_bg_ctower_gear.h" +#include "objects/object_ctower_rot/object_ctower_rot.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgCtowerGear*)thisx) -#define BGCTOWERGEAR_GET_TYPE(this) (((BgCtowerGear*)this)->dyna.actor.params & 3) - -typedef enum { - /* 0x00 */ CEILING_COG, - /* 0x01 */ CENTER_COG, - /* 0x02 */ WATER_WHEEL, - /* 0x03 */ ORGAN -} BgCtowerGearType; - void BgCtowerGear_Init(Actor* thisx, GlobalContext* globalCtx); void BgCtowerGear_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgCtowerGear_Update(Actor* thisx, GlobalContext* globalCtx); @@ -39,19 +31,14 @@ const ActorInit Bg_Ctower_Gear_InitVars = { (ActorFunc)BgCtowerGear_Draw, }; -extern Gfx D_06010828[]; -extern Gfx D_06015F30[]; -extern Gfx D_060160A0[]; -extern CollisionHeader D_06016E70; -extern Gfx D_06017018[]; -extern Gfx D_06018118[]; -extern CollisionHeader D_06018588; - -static Vec3f D_80AD3270[] = { - { -70.0f, -60.0f, 8.0f }, { -60.0f, -60.0f, -9.1f }, { -75.0f, -60.0f, -9.1f }, { -70.0f, -60.0f, -26.2f } +static Vec3f sExitSplashOffsets[] = { + { -70.0f, -60.0f, 8.0f }, + { -60.0f, -60.0f, -9.1f }, + { -75.0f, -60.0f, -9.1f }, + { -70.0f, -60.0f, -26.2f }, }; -static Vec3f D_80AD32A0[] = { +static Vec3f sEnterSplashOffsets[] = { { 85.0f, -60.0f, 8.0f }, { 80.0f, -60.0f, -9.1f }, { 85.0f, -60.0f, -26.2f }, @@ -75,29 +62,27 @@ static InitChainEntry sInitChainOrgan[] = { ICHAIN_F32(uncullZoneDownward, 570, ICHAIN_STOP), }; -static Gfx* D_80AD32E8[] = { D_06010828, D_06017018, D_06018118 }; +static Gfx* sDLists[] = { gClockTowerCeilingCogDL, gClockTowerCenterCogDL, gClockTowerWaterWheelDL }; void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { - int i; - s32 flags; + s32 i; + s32 flag40 = this->dyna.actor.flags & 0x40; Vec3f splashSpawnPos; Vec3f splashOffset; s32 pad; - int j; - s16 rotZ; + s32 j; + s16 rotZ = this->dyna.actor.shape.rot.z & 0x1FFF; - 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); + if (flag40 && (rotZ < 0x1B58) && (rotZ >= 0x1388)) { + Matrix_RotateYS(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(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); - splashOffset.y = D_80AD3270[i].y; - splashOffset.z = D_80AD3270[i].z; - Matrix_MultiplyVector3fByState(&splashOffset, &splashSpawnPos); + splashOffset.x = sExitSplashOffsets[i].x - (Rand_ZeroOne() * 30.0f); + splashOffset.y = sExitSplashOffsets[i].y; + splashOffset.z = sExitSplashOffsets[i].z; + Matrix_MultVec3f(&splashOffset, &splashSpawnPos); splashSpawnPos.x += this->dyna.actor.world.pos.x + ((Rand_ZeroOne() * 20.0f) - 10.0f); splashSpawnPos.y += this->dyna.actor.world.pos.y; splashSpawnPos.z += this->dyna.actor.world.pos.z + ((Rand_ZeroOne() * 20.0f) - 10.0f); @@ -106,16 +91,16 @@ 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); + if (flag40) { + Matrix_RotateYS(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(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); - splashOffset.y = D_80AD32A0[i].y; - splashOffset.z = D_80AD32A0[i].z; - Matrix_MultiplyVector3fByState(&splashOffset, &splashSpawnPos); + splashOffset.x = sEnterSplashOffsets[i].x + (Rand_ZeroOne() * 10.0f); + splashOffset.y = sEnterSplashOffsets[i].y; + splashOffset.z = sEnterSplashOffsets[i].z; + Matrix_MultVec3f(&splashOffset, &splashSpawnPos); splashSpawnPos.x += this->dyna.actor.world.pos.x + ((Rand_ZeroOne() * 20.0f) - 10.0f); splashSpawnPos.y += this->dyna.actor.world.pos.y; splashSpawnPos.z += this->dyna.actor.world.pos.z + ((Rand_ZeroOne() * 20.0f) - 10.0f); @@ -123,56 +108,53 @@ void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { } } } - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WATERWHEEL_LEVEL); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WATERWHEEL_LEVEL); } } void BgCtowerGear_Init(Actor* thisx, GlobalContext* globalCtx) { BgCtowerGear* this = THIS; - s32 type; + s32 type = BGCTOWERGEAR_GET_TYPE(&this->dyna.actor); - type = BGCTOWERGEAR_GET_TYPE(this); Actor_SetScale(&this->dyna.actor, 0.1f); - if (type == CENTER_COG) { + if (type == BGCTOWERGEAR_CENTER_COG) { Actor_ProcessInitChain(&this->dyna.actor, sInitChainCenterCog); - } else if (type == ORGAN) { + } else if (type == BGCTOWERGEAR_ORGAN) { Actor_ProcessInitChain(&this->dyna.actor, sInitChainOrgan); this->dyna.actor.draw = NULL; this->dyna.actor.update = BgCtowerGear_UpdateOrgan; } else { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); } - if (type == WATER_WHEEL) { - BcCheck3_BgActorInit(&this->dyna, 3); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06018588); - } else if (type == ORGAN) { - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06016E70); + if (type == BGCTOWERGEAR_WATER_WHEEL) { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClockTowerWaterWheelCol); + } else if (type == BGCTOWERGEAR_ORGAN) { + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClockTowerOrganCol); func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } } void BgCtowerGear_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgCtowerGear* this = THIS; - s32 type; + s32 type = BGCTOWERGEAR_GET_TYPE(&this->dyna.actor); - type = BGCTOWERGEAR_GET_TYPE(this); - if ((type == WATER_WHEEL) || (type == ORGAN)) { - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + if ((type == BGCTOWERGEAR_WATER_WHEEL) || (type == BGCTOWERGEAR_ORGAN)) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } } void BgCtowerGear_Update(Actor* thisx, GlobalContext* globalCtx) { BgCtowerGear* this = THIS; - s32 type; + s32 type = BGCTOWERGEAR_GET_TYPE(&this->dyna.actor); - type = BGCTOWERGEAR_GET_TYPE(this); - if (type == CEILING_COG) { + if (type == BGCTOWERGEAR_CEILING_COG) { this->dyna.actor.shape.rot.x -= 0x1F4; - } else if (type == CENTER_COG) { + } else if (type == BGCTOWERGEAR_CENTER_COG) { this->dyna.actor.shape.rot.y += 0x1F4; func_800B9010(&this->dyna.actor, NA_SE_EV_WINDMILL_LEVEL - SFX_FLAG); - } else if (type == WATER_WHEEL) { + } else if (type == BGCTOWERGEAR_WATER_WHEEL) { this->dyna.actor.shape.rot.z -= 0x1F4; BgCtowerGear_Splash(this, globalCtx); } @@ -181,8 +163,8 @@ void BgCtowerGear_Update(Actor* thisx, GlobalContext* globalCtx) { void BgCtowerGear_UpdateOrgan(Actor* thisx, GlobalContext* globalCtx) { BgCtowerGear* this = THIS; - if (func_800EE29C(globalCtx, 0x68)) { - switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x68)]->unk0) { + if (Cutscene_CheckActorAction(globalCtx, 104)) { + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 104)]->action) { case 1: this->dyna.actor.draw = NULL; func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); @@ -198,18 +180,17 @@ void BgCtowerGear_UpdateOrgan(Actor* thisx, GlobalContext* globalCtx) { } } -// Using BgCtowerGear *this = THIS causes regalloc issues void BgCtowerGear_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_80AD32E8[BGCTOWERGEAR_GET_TYPE(thisx)]); + Gfx_DrawDListOpa(globalCtx, sDLists[BGCTOWERGEAR_GET_TYPE(thisx)]); } void BgCtowerGear_DrawOrgan(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++, D_060160A0); + gSPDisplayList(POLY_OPA_DISP++, gClockTowerOrganDL); 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++, D_06015F30); + gSPDisplayList(POLY_XLU_DISP++, gClockTowerOrganPipesDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.h b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.h index caf8d3508..5da321679 100644 --- a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.h +++ b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.h @@ -5,6 +5,16 @@ struct BgCtowerGear; + +#define BGCTOWERGEAR_GET_TYPE(thisx) ((thisx)->params & 3) + +typedef enum { + /* 0x00 */ BGCTOWERGEAR_CEILING_COG, + /* 0x01 */ BGCTOWERGEAR_CENTER_COG, + /* 0x02 */ BGCTOWERGEAR_WATER_WHEEL, + /* 0x03 */ BGCTOWERGEAR_ORGAN +} BgCtowerGearType; + typedef struct BgCtowerGear { /* 0x000 */ DynaPolyActor dyna; } BgCtowerGear; // size = 0x15C diff --git a/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.c b/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.c index 68371797b..d562d1a7e 100644 --- a/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.c +++ b/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.c @@ -1,12 +1,13 @@ /* * File: z_bg_ctower_rot.c * Overlay: ovl_Bg_CtowerRot - * Description: Twisting path along with the Doors to Clock Tower + * Description: Twisting path along with the Stone Doors to Clock Tower */ #include "z_bg_ctower_rot.h" +#include "objects/object_ctower_rot/object_ctower_rot.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgCtowerRot*)thisx) @@ -32,42 +33,35 @@ const ActorInit Bg_Ctower_Rot_InitVars = { (ActorFunc)BgCtowerRot_Draw, }; -extern Gfx D_060129D0[]; -extern Gfx D_06012DA0[]; -extern CollisionHeader D_060142E8; -extern Gfx D_06017220[]; -extern CollisionHeader D_06017410; -extern Gfx D_060174E0[]; -extern CollisionHeader D_06017650; - static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -static Gfx* bgCtowerRotDlists[] = { D_06012DA0, D_06017220, D_060174E0 }; +static Gfx* sDLists[] = { gClockTowerCorridorDL, gClockTowerStoneDoorMainDL, gClockTowerStoneDoorDL }; void BgCtowerRot_Init(Actor* thisx, GlobalContext* globalCtx) { - BgCtowerRot* this = THIS; s32 pad; + BgCtowerRot* this = THIS; Player* player; Vec3f offset; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 1); - if (this->dyna.actor.params == CORRIDOR) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060142E8); + DynaPolyActor_Init(&this->dyna, 1); + if (this->dyna.actor.params == BGCTOWERROT_CORRIDOR) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClockTowerCorridorCol); this->actionFunc = BgCtowerRot_CorridorRotate; return; } + player = GET_PLAYER(globalCtx); - if (this->dyna.actor.params == MAIN_DOOR) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06017410); + if (this->dyna.actor.params == BGCTOWERROT_STONE_DOOR_MAIN) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClockTowerStoneDoorMainCol); this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y + 0x4000; } else { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06017650); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClockTowerStoneDoorCol); this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y - 0x4000; } - Actor_CalcOffsetOrientedToDrawRotation(&this->dyna.actor, &offset, &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &offset, &player->actor.world.pos); if (offset.z < 0.0f) { this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + (Math_SinS(this->dyna.actor.world.rot.y) * 80.0f); this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + (Math_CosS(this->dyna.actor.world.rot.y) * 80.0f); @@ -81,29 +75,20 @@ void BgCtowerRot_Init(Actor* thisx, GlobalContext* globalCtx) { void BgCtowerRot_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgCtowerRot* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgCtowerRot_CorridorRotate(BgCtowerRot* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); Vec3f offset; f32 rotZ; - f32 offsetDiffZ; - f32 rotZtmp; - Actor_CalcOffsetOrientedToDrawRotation(&this->dyna.actor, &offset, &player->actor.world.pos); - if (offset.z > 1100.0f) { - rotZ = 0.0f; - } else { - offsetDiffZ = 1100.0f - offset.z; - rotZtmp = (offsetDiffZ > 1000.0f) - ? 1000.0f - : offsetDiffZ; // Removing rotZtmp just causes regalloc issues and a missing instruction - rotZ = rotZtmp; - } - func_800DFAC8(globalCtx->cameraPtrs[0], 0x11); + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &offset, &player->actor.world.pos); + rotZ = CLAMP(1100.0f - offset.z, 0.0f, 1000.0f); + func_800DFAC8(globalCtx->cameraPtrs[CAM_ID_MAIN], 17); this->dyna.actor.shape.rot.z = rotZ * 16.384f; - if (globalCtx->csCtx.frames == 0x84) { + + if (globalCtx->csCtx.frames == 132) { play_sound(NA_SE_SY_SPIRAL_DASH); } } @@ -113,12 +98,12 @@ void BgCtowerRot_DoorDoNothing(BgCtowerRot* this, GlobalContext* globalCtx) { void BgCtowerRot_DoorClose(BgCtowerRot* this, GlobalContext* globalCtx) { if (!Math_SmoothStepToF(&this->timer, 0.0f, 0.1f, 15.0f, 0.1f)) { - if (this->dyna.actor.params == MAIN_DOOR) { - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); + if (this->dyna.actor.params == BGCTOWERROT_STONE_DOOR_MAIN) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); ActorCutscene_Stop(this->dyna.actor.cutscene); } this->actionFunc = BgCtowerRot_DoorDoNothing; - } else if (this->dyna.actor.params == 1) { + } else if (this->dyna.actor.params == BGCTOWERROT_STONE_DOOR_MAIN) { func_800B9010(&this->dyna.actor, NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG); } this->dyna.actor.world.pos.x = @@ -131,7 +116,7 @@ void BgCtowerRot_DoorIdle(BgCtowerRot* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); Vec3f offset; - Actor_CalcOffsetOrientedToDrawRotation(&this->dyna.actor, &offset, &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &offset, &player->actor.world.pos); if (offset.z > 30.0f) { this->unk160 = 0.0f; ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); @@ -141,7 +126,7 @@ void BgCtowerRot_DoorIdle(BgCtowerRot* this, GlobalContext* globalCtx) { void BgCtowerRot_SetupDoorClose(BgCtowerRot* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { - if (this->dyna.actor.params == MAIN_DOOR) { + if (this->dyna.actor.params == BGCTOWERROT_STONE_DOOR_MAIN) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); } this->actionFunc = BgCtowerRot_DoorClose; @@ -159,8 +144,8 @@ void BgCtowerRot_Update(Actor* thisx, GlobalContext* globalCtx) { void BgCtowerRot_Draw(Actor* thisx, GlobalContext* globalCtx) { BgCtowerRot* this = THIS; - func_800BDFC0(globalCtx, bgCtowerRotDlists[this->dyna.actor.params]); - if (this->dyna.actor.params == CORRIDOR) { - func_800BE03C(globalCtx, D_060129D0); + Gfx_DrawDListOpa(globalCtx, sDLists[this->dyna.actor.params]); + if (this->dyna.actor.params == BGCTOWERROT_CORRIDOR) { + Gfx_DrawDListXlu(globalCtx, gClockTowerCorridorFoliageDL); } } diff --git a/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.h b/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.h index 78ff6744b..b8b0dbfb0 100644 --- a/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.h +++ b/src/overlays/actors/ovl_Bg_Ctower_Rot/z_bg_ctower_rot.h @@ -8,10 +8,10 @@ struct BgCtowerRot; typedef void (*BgCtowerRotActionFunc)(struct BgCtowerRot*, GlobalContext*); typedef enum { - /* 0 */ CORRIDOR, - /* 1 */ MAIN_DOOR, // Main door controls cutscene flow (updating Link fields and playing sounds). It is the one on - // the left when entering from the Lost Woods - /* 2 */ DOOR, + /* 0 */ BGCTOWERROT_CORRIDOR, + /* 1 */ BGCTOWERROT_STONE_DOOR_MAIN, // Main door controls cutscene flow (updating Link fields and playing sounds). + // It is the one on the left when entering from the Lost Woods + /* 2 */ BGCTOWERROT_STONE_DOOR, } BgCtowerRotType; typedef struct BgCtowerRot { diff --git a/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.c b/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.c index 29fbd928d..1aada9272 100644 --- a/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.c +++ b/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_danpei_movebg.c + * Overlay: ovl_Bg_Danpei_Movebg + * Description: Moving platforms beneath Dampe's house + */ + #include "z_bg_danpei_movebg.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgDanpeiMovebg*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.h b/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.h index 297a01cd8..28dafc099 100644 --- a/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.h +++ b/src/overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.h @@ -8,10 +8,11 @@ struct BgDanpeiMovebg; typedef void (*BgDanpeiMovebgActionFunc)(struct BgDanpeiMovebg*, GlobalContext*); typedef struct BgDanpeiMovebg { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ BgDanpeiMovebgActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x78]; + /* 0x0160 */ char unk_160[0x6C]; + /* 0x01CC */ u16 unk_1CC; + /* 0x01CE */ char unk_1CE[0xA]; } BgDanpeiMovebg; // size = 0x1D8 extern const ActorInit Bg_Danpei_Movebg_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.c b/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.c index 03d9d60f6..0c5b92496 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.c +++ b/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_dblue_balance.c + * Overlay: ovl_Bg_Dblue_Balance + * Description: Great Bay Temple - See-Saw + */ + #include "z_bg_dblue_balance.h" +#include "objects/object_dblue_object/object_dblue_object.h" #define FLAGS 0x00000000 @@ -9,11 +16,19 @@ void BgDblueBalance_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgDblueBalance_Update(Actor* thisx, GlobalContext* globalCtx); void BgDblueBalance_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B82DC4(BgDblueBalance* this); void func_80B82DE0(BgDblueBalance* this, GlobalContext* globalCtx); +void func_80B8330C(Actor* thisx, GlobalContext* globalCtx); +void func_80B83344(BgDblueBalance* this); void func_80B8335C(BgDblueBalance* this, GlobalContext* globalCtx); +void func_80B833A8(BgDblueBalance* this); void func_80B833C4(BgDblueBalance* this, GlobalContext* globalCtx); +void func_80B83518(Actor* thisx, GlobalContext* globalCtx); +void func_80B83758(Actor* thisx, GlobalContext* globalCtx); + +AnimatedMaterial* D_80B83C70; +AnimatedMaterial* D_80B83C74; -#if 0 const ActorInit Bg_Dblue_Balance_InitVars = { ACTOR_BG_DBLUE_BALANCE, ACTORCAT_BG, @@ -26,56 +41,689 @@ const ActorInit Bg_Dblue_Balance_InitVars = { (ActorFunc)BgDblueBalance_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B83A98[] = { +typedef struct { + /* 0x00 */ Gfx* unk_00; + /* 0x04 */ CollisionHeader* unk_04; + /* 0x08 */ u32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ ActorFunc unk_14; + /* 0x18 */ ActorFunc unk_18; +} BgDblueBalanceStruct2; + +BgDblueBalanceStruct2 D_80B83A20[] = { + { + object_dblue_object_DL_00B8F8, + &object_dblue_object_Colheader_00BC08, + 0x10, + 360.0f, + 300.0f, + BgDblueBalance_Update, + BgDblueBalance_Draw, + }, + { + object_dblue_object_DL_00BF48, + &object_dblue_object_Colheader_00C180, + 0x10, + 210.0f, + 190.0f, + func_80B8330C, + BgDblueBalance_Draw, + }, + { + object_dblue_object_DL_00C4B8, + &object_dblue_object_Colheader_00C700, + 0x10, + 180.0f, + 180.0f, + func_80B8330C, + BgDblueBalance_Draw, + }, + { + object_dblue_object_DL_001E68, + &object_dblue_object_Colheader_002E78, + 0x30, + 1500.0f, + 1500.0f, + func_80B83518, + func_80B83758, + }, +}; + +s8 D_80B83A90[] = { + 0, + 4, +}; +s8 D_80B83A94[] = { + 0, + 2, + 4, + 6, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80B823B0(BgDblueBalance* this) { + s32 pad; + Vec3f sp28; -extern InitChainEntry D_80B83A98[]; + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); -extern UNK_TYPE D_0600CD10; -extern UNK_TYPE D_0600CE00; -extern UNK_TYPE D_0600D110; + sp28.x = -138.28f; + sp28.y = 0.0f; + sp28.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B823B0.s") + if (this->unk_15C != NULL) { + Matrix_MultVec3f(&sp28, &this->unk_15C->dyna.actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B82454.s") + sp28.x = 138.28f; + if (this->unk_160 != NULL) { + Matrix_MultVec3f(&sp28, &this->unk_160->dyna.actor.world.pos); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B8259C.s") +s32 func_80B82454(BgDblueBalance* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp58 = true; + BgDblueBalance* balance; + Vec3f sp48; + Vec3f sp3C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B8264C.s") + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B828E4.s") + sp48.x = -138.28f; + sp48.y = 0.0f; + sp48.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B8296C.s") + Matrix_MultVec3f(&sp48, &sp3C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B82B00.s") + this->unk_15C = (BgDblueBalance*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BG_DBLUE_BALANCE, sp3C.x, + sp3C.y, sp3C.z, 0, this->dyna.actor.shape.rot.y, 0, 0x100); + if (this->unk_15C == NULL) { + sp58 = false; + } else { + balance = this->unk_15C; + balance->unk_164 = this; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/BgDblueBalance_Init.s") + sp48.x = 138.28f; + Matrix_MultVec3f(&sp48, &sp3C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/BgDblueBalance_Destroy.s") + this->unk_160 = (BgDblueBalance*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BG_DBLUE_BALANCE, sp3C.x, + sp3C.y, sp3C.z, 0, this->dyna.actor.shape.rot.y, 0, 0x200); + if (this->unk_160 == NULL) { + sp58 = false; + } else { + balance = this->unk_160; + balance->unk_164 = this; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B82DC4.s") + return sp58; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B82DE0.s") +void func_80B8259C(BgDblueBalance* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* sp30; + f32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/BgDblueBalance_Update.s") + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.z, &sp2C, &sp30)) { + this->dyna.actor.depthInWater = sp2C - this->dyna.actor.world.pos.y; + this->unk_228 = sp2C; + if ((this->dyna.actor.depthInWater < 150.0f) && (this->dyna.actor.depthInWater > -150.0f)) { + this->unk_182 = true; + } else { + this->unk_182 = false; + } + } else { + this->unk_182 = false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B8330C.s") +void func_80B8264C(BgDblueBalance* this) { + s32 pad; + s32 i; + BgDblueBalanceStruct* phi_s0; + Vec3f sp78; + f32 temp_f0; + s16 phi_s2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B83344.s") + if (this->unk_170 != 0) { + if (this->unk_183 < 8) { + this->unk_183 = 0; + } else { + this->unk_183 -= 7; + } + } else { + if (this->unk_183 > 250) { + this->unk_183 = 255; + } else { + this->unk_183 += 4; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B8335C.s") + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B833A8.s") + for (i = 0, phi_s0 = &this->unk_188[0], phi_s2 = 0; i < ARRAY_COUNT(this->unk_188); + i++, phi_s2 += 0x2000, phi_s0++) { + phi_s0->unk_0C = this->dyna.actor.shape.rot.x + phi_s2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B833C4.s") + Matrix_Push(); + Matrix_RotateXS(phi_s0->unk_0C, MTXMODE_NEW); + Matrix_Translate(-545.0f, 0.0f, 270.0f, MTXMODE_APPLY); + Matrix_MultZero(&sp78); + Matrix_Pop(); + Matrix_MultVec3f(&sp78, &phi_s0->unk_00); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B83518.s") + temp_f0 = (sp78.z - 135.0f); + if (sp78.z > 135.0f) { + temp_f0 *= 1.8962963f; + if (temp_f0 > 255.0f) { + phi_s0->unk_0E = 0xFF; + phi_s0->unk_10 = 0.1f; + } else if (temp_f0 < 1.0f) { + phi_s0->unk_0E = 0; + phi_s0->unk_10 = 0.0f; + } else { + phi_s0->unk_0E = temp_f0; + phi_s0->unk_10 = temp_f0 * 0.000390625f; + } + } else { + phi_s0->unk_0E = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/BgDblueBalance_Draw.s") +void func_80B828E4(BgDblueBalance* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, BGDBLUEBALANCE_GET_7F(&this->dyna.actor)) && (this->unk_17D <= 0)) { + if (this->unk_183 >= 252) { + this->unk_183 = 255; + } else { + this->unk_183 += 3; + } + } else if (this->unk_183 < 7) { + this->unk_183 = 0; + } else { + this->unk_183 -= 6; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Balance/func_80B83758.s") +void func_80B8296C(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2) { + s32 i; + Vec3f sp60; + f32 temp_f0; + f32 temp_f20 = arg2 * 2; + + for (i = 0; i < ARRAY_COUNT(D_80B83A90); i++) { + sp60.x = ((Rand_ZeroOne() - 0.5f) * temp_f20) + arg1->x; + sp60.y = arg1->y; + sp60.z = ((Rand_ZeroOne() - 0.5f) * temp_f20) + arg1->z; + EffectSsGRipple_Spawn(globalCtx, &sp60, 500, 2000, D_80B83A90[i]); + } + + for (i = 0; i < ARRAY_COUNT(D_80B83A94); i++) { + temp_f0 = Rand_ZeroOne(); + temp_f20 = 1.0f - SQ(temp_f0); + if (Rand_Next() > 0) { + temp_f20 = -temp_f20; + } + + sp60.x = (temp_f20 * arg2) + arg1->x; + sp60.y = arg1->y; + + temp_f0 = Rand_ZeroOne(); + temp_f20 = 1.0f - SQ(temp_f0); + if (Rand_Next() > 0) { + temp_f20 = -temp_f20; + } + sp60.z = (temp_f20 * arg2) + arg1->z; + + EffectSsGRipple_Spawn(globalCtx, &sp60, 400, 800, D_80B83A94[i]); + } +} + +s32 func_80B82B00(s16 arg0, s16 arg1, s16 arg2) { + if (arg0 < arg1) { + return (arg0 < arg2 && arg1 >= arg2); + } + return (arg0 < arg2 || arg1 >= arg2); +} + +void BgDblueBalance_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueBalance* this = THIS; + s32 sp2C = BGDBLUEBALANCE_GET_300(&this->dyna.actor); + s32 pad2; + s32 sp24 = Flags_GetSwitch(globalCtx, BGDBLUEBALANCE_GET_7F(&this->dyna.actor)); + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + this->dyna.actor.flags = D_80B83A20[sp2C].unk_08; + this->dyna.actor.uncullZoneScale = D_80B83A20[sp2C].unk_0C; + this->dyna.actor.uncullZoneDownward = D_80B83A20[sp2C].unk_10; + this->dyna.actor.update = D_80B83A20[sp2C].unk_14; + this->dyna.actor.draw = D_80B83A20[sp2C].unk_18; + + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, D_80B83A20[sp2C].unk_04); + + if (sp2C == 3) { + D_80B83C70 = Lib_SegmentedToVirtual(object_dblue_object_Matanimheader_00CE00); + } else if (sp2C == 0) { + D_80B83C74 = Lib_SegmentedToVirtual(object_dblue_object_Matanimheader_00D250); + } + + if (sp2C == 0) { + if (sp24 != 0) { + this->dyna.actor.shape.rot.z = -0x1C72; + this->unk_174 = -0x1C72; + } else { + this->dyna.actor.shape.rot.z = 0x1C72; + this->unk_174 = 0x1C72; + } + func_80B82454(this, globalCtx); + func_80B8259C(this, globalCtx); + func_80B82DC4(this); + } else if (sp2C == 3) { + this->unk_16C = sp24; + this->unk_170 = sp24; + if (sp24 != 0) { + func_80B83344(this); + } else { + this->unk_178 = 0x1F4; + func_80B833A8(this); + } + } +} + +void BgDblueBalance_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueBalance* this = THIS; + s32 sp1C = BGDBLUEBALANCE_GET_300(&this->dyna.actor); + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + + if (sp1C == 0) { + if (this->unk_15C != NULL) { + this->unk_15C->unk_164 = NULL; + } + if (this->unk_160 != NULL) { + this->unk_160->unk_164 = NULL; + } + } else if (sp1C == 1) { + if (this->unk_164 != NULL) { + this->unk_164->unk_15C = NULL; + } + } else if (sp1C == 2) { + if (this->unk_164 != NULL) { + this->unk_164->unk_160 = NULL; + } + } +} + +void func_80B82DC4(BgDblueBalance* this) { + this->unk_17D = 20; + this->actionFunc = func_80B82DE0; +} + +void func_80B82DE0(BgDblueBalance* this, GlobalContext* globalCtx) { + s32 pad; + f32 sp88 = Math_CosS(this->dyna.actor.shape.rot.z * 2.2499313f); + Actor* actor = &this->dyna.actor; + s32 pad2; + s16 abs; + s32 phi_a0; + s32 phi_a1; + f32 phi_f2; + f32 temp2; + Vec3f sp60; + BgDblueBalance* sp5C; + Vec3f sp50; + s32 pad3; + Vec3f sp40; + BgDblueBalance* sp3C; + Vec3f sp30; + + if (Flags_GetSwitch(globalCtx, BGDBLUEBALANCE_GET_7F(&this->dyna.actor))) { + if (this->unk_17D > 0) { + this->unk_17D--; + } else { + this->unk_174 = -0x1C72; + this->unk_176 = (s32)(sp88 * -300.0f) - 60; + } + } else { + BgDblueBalance* balance1 = this->unk_160; + BgDblueBalance* balance2 = this->unk_15C; + + phi_a0 = 0; + phi_a1 = 1; + this->unk_17D = 20; + if (balance1 != NULL) { + if (balance1->unk_181 != 0) { + phi_a0 = 4; + } else if (balance1->unk_180 != 0) { + phi_a0 = 2; + } + } + + if (balance2 != NULL) { + if (balance2->unk_181 != 0) { + phi_a1 = 5; + } else if (balance2->unk_180 != 0) { + phi_a1 = 3; + } + } + + if (phi_a0 < phi_a1) { + this->unk_174 = 0x1C72; + this->unk_176 = (s32)(sp88 * 370.0f) + 80; + } else { + this->unk_174 = -0x1C72; + this->unk_176 = (s32)(sp88 * -160.0f) - 80; + } + } + + if (this->dyna.actor.shape.rot.z == this->unk_174) { + this->unk_178 = 0; + this->unk_17C = 0; + return; + } + + abs = this->dyna.actor.shape.rot.z - this->unk_174; + abs = ABS_ALT(abs); + + if ((this->unk_17C > 0) && (abs < 0x7D0)) { + phi_a0 = 3; + } else { + phi_a0 = 40; + this->unk_17C = 0; + } + + if (this->unk_176 >= 0) { + this->unk_178 += phi_a0; + if (this->unk_176 < this->unk_178) { + this->unk_178 = this->unk_176; + } + } else { + this->unk_178 -= phi_a0; + if (this->unk_178 < this->unk_176) { + this->unk_178 = this->unk_176; + } + } + + phi_f2 = this->unk_178; + temp2 = this->unk_17A; + if ((phi_f2 * temp2) <= 0.0f) { + func_801A7328(&this->dyna.actor.projectedPos, NA_SE_EV_SEESAW_INCLINE - SFX_FLAG); + } + + phi_f2 *= 0.0022222223f; + phi_f2 = fabsf(phi_f2); + if (phi_f2 > 1.0f) { + phi_f2 = 1.0f; + } + + func_8019FAD8(&this->dyna.actor.projectedPos, NA_SE_EV_SEESAW_INCLINE - SFX_FLAG, phi_f2 + 1.0f); + actor->shape.rot.z += this->unk_178; + + if (this->dyna.actor.shape.rot.z > 0x1C71) { + if (this->unk_17C < 2) { + actor->shape.rot.z = 0x1C71; + this->unk_178 *= -0.6f; + this->unk_17C++; + if (this->unk_182) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SEESAW_WATER_BOUND); + sp5C = this->unk_15C; + Matrix_Push(); + Matrix_RotateYS(BINANG_SUB(this->dyna.actor.shape.rot.y, 0x4000), MTXMODE_NEW); + Matrix_MultVecZ(45.0f, &sp60); + Matrix_Pop(); + + sp50.x = sp5C->dyna.actor.world.pos.x + sp60.x; + sp50.y = this->unk_228; + sp50.z = sp5C->dyna.actor.world.pos.z + sp60.z; + + func_80B8296C(globalCtx, &sp50, 70.0f); + } else { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SEESAW_BOUND); + } + } else { + this->dyna.actor.shape.rot.z = 0x1C72; + this->unk_178 = 0; + } + } else if (this->dyna.actor.shape.rot.z < -0x1C71) { + if (this->unk_17C < 2) { + actor->shape.rot.z = -0x1C71; + this->unk_178 *= -0.6f; + this->unk_17C++; + if (this->unk_182) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SEESAW_WATER_BOUND); + sp3C = this->unk_160; + Matrix_Push(); + Matrix_RotateYS(BINANG_ADD(this->dyna.actor.shape.rot.y, 0x4000), MTXMODE_NEW); + Matrix_MultVecZ(30.0f, &sp40); + Matrix_Pop(); + + sp30.x = sp3C->dyna.actor.world.pos.x + sp40.x; + sp30.y = this->unk_228; + sp30.z = sp3C->dyna.actor.world.pos.z + sp40.z; + + func_80B8296C(globalCtx, &sp30, 47.0f); + } else { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SEESAW_BOUND); + } + } else { + this->dyna.actor.shape.rot.z = -0x1C72; + this->unk_178 = 0; + } + } + func_80B823B0(this); +} + +void BgDblueBalance_Update(Actor* thisx, GlobalContext* globalCtx) { + BgDblueBalance* this = THIS; + + this->unk_17A = this->unk_178; + + this->actionFunc(this, globalCtx); + + func_80B828E4(this, globalCtx); +} + +void func_80B8330C(Actor* thisx, GlobalContext* globalCtx) { + BgDblueBalance* this = THIS; + + this->unk_180 = DynaPolyActor_IsInSwitchPressedState(&this->dyna); + this->unk_181 = DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna); +} + +void func_80B83344(BgDblueBalance* this) { + this->unk_178 = 0; + this->actionFunc = func_80B8335C; +} + +void func_80B8335C(BgDblueBalance* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, BGDBLUEBALANCE_GET_7F(&this->dyna.actor))) { + this->unk_178 = -0x14; + func_80B833A8(this); + } +} + +void func_80B833A8(BgDblueBalance* this) { + this->unk_186 = 0; + this->unk_187 = 0; + this->actionFunc = func_80B833C4; +} + +void func_80B833C4(BgDblueBalance* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp28 = false; + s16 sp26; + s16 sp24; + + if (this->unk_170 != 0) { + if ((this->unk_16C == 0) && (this->unk_17F == 0)) { + this->unk_17F = 1; + } + + if (this->unk_186 != 0) { + if (this->unk_178 >= 0x50) { + this->unk_178 -= 5; + } + } + } else { + this->unk_187 = Math_StepToS(&this->unk_178, 0x1F4, 5); + } + + sp26 = this->dyna.actor.shape.rot.x; + this->dyna.actor.shape.rot.x += this->unk_178; + sp24 = this->dyna.actor.shape.rot.x; + if (sp24) {} + + if (this->unk_170 != 0) { + if (this->unk_186 != 0) { + if (func_80B82B00(sp26, sp24, this->unk_184)) { + sp28 = true; + } + } else if (this->unk_187 != 0) { + if (func_80B82B00(sp26, sp24, 0x2097)) { + this->unk_184 = -0x8000; + this->unk_186 = 1; + } else if (func_80B82B00(sp26, sp24, -0x5F69)) { + this->unk_184 = 0; + this->unk_186 = 1; + } + } + } + + func_80B8264C(this); + + if (sp28) { + this->dyna.actor.shape.rot.x = this->unk_184; + func_80B83344(this); + } +} + +void func_80B83518(Actor* thisx, GlobalContext* globalCtx) { + BgDblueBalance* this = THIS; + + this->unk_170 = Flags_GetSwitch(globalCtx, BGDBLUEBALANCE_GET_7F(&this->dyna.actor)); + + this->actionFunc(this, globalCtx); + + if (this->unk_17F == 2) { + this->unk_17E--; + if (this->unk_17E <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->unk_17F = 0; + } + } else if ((this->unk_17F != 0) && (this->unk_17F == 1)) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->unk_17F = 2; + this->unk_17E = 0x50; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } + this->unk_16C = this->unk_170; +} + +void BgDblueBalance_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueBalance* this = THIS; + BgDblueBalanceStruct2* ptr2 = &D_80B83A20[BGDBLUEBALANCE_GET_300(&this->dyna.actor)]; + BgDblueBalance* sp38; + Gfx* gfx; + + Gfx_DrawDListOpa(globalCtx, ptr2->unk_00); + + if (!(BGDBLUEBALANCE_GET_300(&this->dyna.actor)) && (this->unk_160 != NULL)) { + AnimatedMat_Draw(globalCtx, D_80B83C74); + sp38 = this->unk_160; + Matrix_SetTranslateRotateYXZ(sp38->dyna.actor.world.pos.x, sp38->dyna.actor.world.pos.y, + sp38->dyna.actor.world.pos.z, &sp38->dyna.actor.shape.rot); + Matrix_Translate(30.0f, 15.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(sp38->dyna.actor.scale.x, sp38->dyna.actor.scale.y, sp38->dyna.actor.scale.z, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_XLU_DISP; + + gSPDisplayList(gfx++, &sSetupDL[6 * 25]); + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetEnvColor(gfx++, 0, 0, 0, this->unk_183); + gSPDisplayList(gfx++, object_dblue_object_DL_00D110); + + POLY_XLU_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_80B83758(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueBalance* this = THIS; + f32 temp_f0; + Gfx* gfx; + s32 i; + BgDblueBalanceStruct* ptr; + BgDblueBalanceStruct2* ptr2; + s32 temp; + + if (this->unk_178 != 0) { + if (this->unk_178 == 0x1F4) { + temp_f0 = 1.0f; + } else { + temp_f0 = this->unk_178 * 0.002f; + temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f); + } + func_8019FB0C(&this->dyna.actor.projectedPos, NA_SE_EV_SMALL_WATER_WHEEL - SFX_FLAG, temp_f0, 0x20); + } + + if (this->dyna.actor.flags & ACTOR_FLAG_40) { + ptr2 = &D_80B83A20[BGDBLUEBALANCE_GET_300(&this->dyna.actor)]; + Gfx_DrawDListOpa(globalCtx, ptr2->unk_00); + + if (this->unk_183 != 0) { + AnimatedMat_Draw(globalCtx, D_80B83C70); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_XLU_DISP; + + gSPDisplayList(gfx++, &sSetupDL[6 * 25]); + + for (i = 0, ptr = &this->unk_188[0]; i < ARRAY_COUNT(this->unk_188); i++, ptr++) { + if (ptr->unk_0E != 0) { + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(ptr->unk_0C, MTXMODE_APPLY); + Matrix_Scale(ptr->unk_10, ptr->unk_10, ptr->unk_10, MTXMODE_APPLY); + + temp = ptr->unk_0E * (f32)this->unk_183 * 0.003921569f; + gDPSetEnvColor(gfx++, 0, 0, 0, temp); + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, object_dblue_object_DL_00CD10); + } + } + + POLY_XLU_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} diff --git a/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.h b/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.h index 8750f4077..16eed26e3 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.h +++ b/src/overlays/actors/ovl_Bg_Dblue_Balance/z_bg_dblue_balance.h @@ -7,11 +7,41 @@ struct BgDblueBalance; typedef void (*BgDblueBalanceActionFunc)(struct BgDblueBalance*, GlobalContext*); +#define BGDBLUEBALANCE_GET_7F(thisx) ((thisx)->params & 0x7F) +#define BGDBLUEBALANCE_GET_300(thisx) (((thisx)->params >> 8) & 3) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ u8 unk_0E; + /* 0x10 */ f32 unk_10; +} BgDblueBalanceStruct; // size = 0x14 + typedef struct BgDblueBalance { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x24]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ struct BgDblueBalance* unk_15C; + /* 0x0160 */ struct BgDblueBalance* unk_160; + /* 0x0164 */ struct BgDblueBalance* unk_164; /* 0x0168 */ BgDblueBalanceActionFunc actionFunc; - /* 0x016C */ char unk_16C[0xC0]; + /* 0x016C */ s32 unk_16C; + /* 0x0170 */ s32 unk_170; + /* 0x0174 */ s16 unk_174; + /* 0x0176 */ s16 unk_176; + /* 0x0178 */ s16 unk_178; + /* 0x017A */ s16 unk_17A; + /* 0x017C */ s8 unk_17C; + /* 0x017D */ s8 unk_17D; + /* 0x017E */ s8 unk_17E; + /* 0x017F */ s8 unk_17F; + /* 0x0180 */ s8 unk_180; + /* 0x0181 */ s8 unk_181; + /* 0x0182 */ s8 unk_182; + /* 0x0183 */ u8 unk_183; + /* 0x0184 */ s16 unk_184; + /* 0x0186 */ s8 unk_186; + /* 0x0187 */ s8 unk_187; + /* 0x0188 */ BgDblueBalanceStruct unk_188[8]; + /* 0x0228 */ f32 unk_228; } BgDblueBalance; // size = 0x22C extern const ActorInit Bg_Dblue_Balance_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Dblue_Elevator/z_bg_dblue_elevator.c b/src/overlays/actors/ovl_Bg_Dblue_Elevator/z_bg_dblue_elevator.c index 708d13c6c..af6ed5fa2 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Elevator/z_bg_dblue_elevator.c +++ b/src/overlays/actors/ovl_Bg_Dblue_Elevator/z_bg_dblue_elevator.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_dblue_elevator.c + * Overlay: ovl_Bg_Dblue_Elevator + * Description: Great Bay Temple - Elevator + */ + #include "z_bg_dblue_elevator.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgDblueElevator*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.c b/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.c index 043b55d9f..857eb43cf 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.c +++ b/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.c @@ -1,6 +1,14 @@ -#include "z_bg_dblue_movebg.h" +/* + * File: z_bg_dblue_movebg.c + * Overlay: ovl_Bg_Dblue_Movebg + * Description: Great Bay Temple - Waterwheels and push switches + */ -#define FLAGS 0x00000030 +#include "z_bg_dblue_movebg.h" +#include "objects/object_dblue_object/object_dblue_object.h" +#include "overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgDblueMovebg*)thisx) @@ -9,7 +17,33 @@ void BgDblueMovebg_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgDblueMovebg_Update(Actor* thisx, GlobalContext* globalCtx); void BgDblueMovebg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A2A1E0(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A32C(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A444(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A670(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A688(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A714(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2A7F8(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2AAB8(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2AED0(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2B1A0(BgDblueMovebg* this, GlobalContext* globalCtx); +void func_80A2B274(Actor* thisx, GlobalContext* globalCtx); +void func_80A2B308(Actor* thisx, GlobalContext* globalCtx); + +BgDblueMovebg* D_80A2BBF0; + +typedef struct { + u8 unk_00; + u8 unk_01; +} BgDblueMovebgUnkStruct; + +BgDblueMovebgUnkStruct D_80A2BBF4; + +u8 D_80A2B870[][2] = { + { 0x01, 0x01 }, { 0x01, 0x00 }, { 0x02, 0x03 }, { 0x02, 0x01 }, { 0x02, 0x02 }, { 0x02, 0x00 }, { 0x03, 0x07 }, + { 0x03, 0x03 }, { 0x03, 0x05 }, { 0x03, 0x01 }, { 0x03, 0x06 }, { 0x03, 0x02 }, { 0x03, 0x04 }, { 0x03, 0x00 }, +}; + const ActorInit Bg_Dblue_Movebg_InitVars = { ACTOR_BG_DBLUE_MOVEBG, ACTORCAT_BG, @@ -22,46 +56,813 @@ const ActorInit Bg_Dblue_Movebg_InitVars = { (ActorFunc)BgDblueMovebg_Draw, }; -#endif +Gfx* D_80A2B8AC[] = { + NULL, + object_dblue_object_DL_0069D8, + NULL, + NULL, + NULL, + NULL, + object_dblue_object_DL_004848, + object_dblue_object_DL_0061B8, + NULL, + NULL, + NULL, + NULL, +}; -extern UNK_TYPE D_06004848; -extern UNK_TYPE D_060052B8; -extern UNK_TYPE D_06008778; +Gfx* D_80A2B8DC[] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, object_dblue_object_DL_00CAA0, NULL, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A29A80.s") +CollisionHeader* D_80A2B90C[] = { + NULL, + &object_dblue_object_Colheader_006EA8, + NULL, + NULL, + NULL, + &object_dblue_object_Colheader_00D3DC, + &object_dblue_object_Colheader_005D28, + &object_dblue_object_Colheader_00714C, + &object_dblue_object_Colheader_00AED0, + &object_dblue_object_Colheader_00AED0, + NULL, + NULL, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/BgDblueMovebg_Init.s") +AnimatedMaterial* D_80A2B93C[] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, object_dblue_object_Matanimheader_00CC18, NULL, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/BgDblueMovebg_Destroy.s") +s16 D_80A2B96C[] = { 0, 0x16C, -0x16C, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A128.s") +s16 D_80A2B974[] = { -1, -1 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A1E0.s") +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneScale, 1500, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 1100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A32C.s") +Vec3f D_80A2B988 = { 1785.0f, 0.0f, 220.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A444.s") +s32 func_80A29A80(GlobalContext* globalCtx, s32 arg1, s32 arg2) { + s32 sp2C = 1; + s32 val; + s32 val2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A670.s") + if (arg2 < 14) { + val = D_80A2B870[arg2][0]; + val2 = D_80A2B870[arg2][1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A688.s") + while (val--) { + if ((1 << val) & val2) { + if (!Flags_GetSwitch(globalCtx, arg1 + val)) { + sp2C = 0; + break; + } + } else if (Flags_GetSwitch(globalCtx, arg1 + val)) { + sp2C = 0; + break; + } + } + } else { + sp2C = 0; + switch (arg2) { + case 14: + if (!Flags_GetSwitch(globalCtx, arg1)) { + sp2C = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A714.s") + if (Flags_GetSwitch(globalCtx, arg1 + 1) && Flags_GetSwitch(globalCtx, arg1 + 2) && + Flags_GetSwitch(globalCtx, arg1 + 3)) { + sp2C += 2; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2A7F8.s") + case 15: + if (!Flags_GetSwitch(globalCtx, arg1) || + (Flags_GetSwitch(globalCtx, arg1 + 1) && Flags_GetSwitch(globalCtx, arg1 + 2) && + Flags_GetSwitch(globalCtx, arg1 + 3))) { + sp2C = 1; + } + break; + } + } + return sp2C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2AAB8.s") +void BgDblueMovebg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueMovebg* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2ABD0.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_160 = BGDBLUEMOVEBG_GET_F(thisx); + this->unk_1BC = BGDBLUEMOVEBG_GET_F000(thisx); + this->unk_1C0 = BGDBLUEMOVEBG_GET_FF0(thisx); + DynaPolyActor_Init(&this->dyna, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2AED0.s") + if ((this->unk_160 == 9) || (this->unk_160 == 8)) { + if (D_80A2BBF4.unk_00 != 0) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + this->unk_170 = this->dyna.actor.room; + this->dyna.actor.room = -1; + D_80A2BBF4.unk_00 = 1; + this->unk_171 = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + } else if (this->unk_160 == 6) { + if (D_80A2BBF4.unk_01 != 0) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + this->unk_171 = this->dyna.actor.world.rot.z; + this->unk_170 = this->dyna.actor.room; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.room = -1; + D_80A2BBF4.unk_01 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2B1A0.s") + if (D_80A2B90C[this->unk_160] != NULL) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, D_80A2B90C[this->unk_160]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/BgDblueMovebg_Update.s") + this->unk_164 = D_80A2B8AC[this->unk_160]; + this->unk_168 = D_80A2B8DC[this->unk_160]; + this->unk_16C = D_80A2B93C[this->unk_160]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2B274.s") + SubS_FillCutscenesList(&this->dyna.actor, this->unk_1B6, ARRAY_COUNT(this->unk_1B6)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/func_80A2B308.s") + switch (this->unk_160) { + case 1: + this->unk_1C4 = this->dyna.actor.world.rot.x; + this->unk_1C8 = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + if (func_80A29A80(globalCtx, this->unk_1C8, this->unk_1C4)) { + this->unk_172 |= 1; + } else { + this->unk_172 &= ~1; + } + this->unk_17E = 0; + this->unk_184 = 0.0f; + if (Flags_GetSwitch(globalCtx, this->unk_1C0)) { + this->unk_18C = 0x384; + } else { + this->unk_18C = 0; + } + this->dyna.actor.shape.rot.y += (s16)((this->unk_18C / 10.0f) * (0x10000 / 360.0f)); + this->actionFunc = func_80A2A714; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Movebg/BgDblueMovebg_Draw.s") + case 6: + this->unk_178 = func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC); + this->unk_1CC = D_80A2B96C[this->unk_178]; + this->unk_1CE = this->unk_1CC; + this->actionFunc = func_80A2A1E0; + break; + + case 7: + this->unk_1C4 = this->dyna.actor.world.rot.x; + this->unk_1C8 = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + if (Flags_GetSwitch(globalCtx, this->unk_1C0)) { + Actor_MarkForDeath(&this->dyna.actor); + break; + } + this->unk_18C = 0; + this->dyna.actor.draw = func_80A2B308; + this->unk_17E = 0; + this->unk_184 = 0.0f; + this->dyna.actor.shape.rot.y += (s16)((this->unk_18C / 10.0f) * (0x10000 / 360.0f)); + this->actionFunc = func_80A2A32C; + break; + + case 8: + case 9: + this->unk_2F8[1] = NULL; + this->unk_2F8[0] = NULL; + label: + for (i = 0; i < ARRAY_COUNT(D_80A2B974); i++) { + D_80A2B974[i] = this->unk_1B6[i]; + } + this->unk_178 = func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC); + this->unk_1CC = D_80A2B96C[this->unk_178]; + this->unk_1CE = this->unk_1CC; + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecX(2240.0f, &this->unk_190); + Matrix_MultVecX(-10.0f, &this->unk_19C); + Math_Vec3f_Sum(&this->unk_190, &this->dyna.actor.world.pos, &this->unk_190); + Math_Vec3f_Sum(&this->unk_19C, &this->dyna.actor.world.pos, &this->unk_19C); + D_80A2BBF0 = this; + this->dyna.actor.flags |= ACTOR_FLAG_20; + this->actionFunc = func_80A2AED0; + break; + + case 10: + this->actionFunc = func_80A2B1A0; + break; + + case 11: + this->unk_1CC = D_80A2B96C[func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC)]; + D_80A2BBF0 = this; + this->dyna.actor.flags |= ACTOR_FLAG_20; + this->dyna.actor.update = Actor_Noop; + this->dyna.actor.draw = func_80A2B274; + break; + } +} + +void BgDblueMovebg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgDblueMovebg* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + if ((this->unk_160 == 9) || (this->unk_160 == 8)) { + Audio_StopSfxByPos(&this->unk_1A8); + } +} + +void func_80A2A128(BgDblueMovebg* this, GlobalContext* globalCtx) { + Actor* phi_s0 = NULL; + + while (true) { + phi_s0 = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_BG, ACTOR_OBJ_HUNSUI); + if (phi_s0 != NULL) { + if ((OBJHUNSUI_GET_F000(phi_s0) == 5) && (phi_s0->update != NULL)) { + this->unk_2F8[1] = phi_s0; + } else if ((OBJHUNSUI_GET_F000(phi_s0) == 6) && (phi_s0->update != NULL)) { + this->unk_2F8[0] = phi_s0; + } + phi_s0 = phi_s0->next; + } + + if (phi_s0 == NULL) { + break; + } + } +} + +void func_80A2A1E0(BgDblueMovebg* this, GlobalContext* globalCtx) { + s32 temp_v0 = func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC); + + if (temp_v0 != this->unk_178) { + switch (temp_v0) { + case 1: + case 2: + this->unk_17E = 40; + break; + + case 0: + case 3: + this->unk_17E = 15; + break; + } + } + this->unk_178 = temp_v0; + + if (this->unk_17E <= 0) { + this->unk_1CE = D_80A2B96C[temp_v0]; + } else { + this->unk_17E--; + } + + Math_StepToS(&this->unk_1CC, this->unk_1CE, 12); + this->dyna.actor.shape.rot.y += this->unk_1CC; + + if (globalCtx->roomCtx.currRoom.num == 0) { + this->unk_164 = object_dblue_object_DL_004848; + } else if (globalCtx->roomCtx.currRoom.num == 8) { + this->unk_164 = NULL; + } + + if (globalCtx->roomCtx.currRoom.num != this->unk_170) { + if (globalCtx->roomCtx.currRoom.num != this->unk_171) { + if ((globalCtx->roomCtx.prevRoom.num != this->unk_170) && + (globalCtx->roomCtx.prevRoom.num != this->unk_171)) { + D_80A2BBF4.unk_01 = 0; + Actor_MarkForDeath(&this->dyna.actor); + } + } + } +} + +void func_80A2A32C(BgDblueMovebg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 phi_v0; + f32 phi_f0; + s32 phi_v1; + + if (this->dyna.pushForce != 0.0f) { + this->unk_18E = BINANG_SUB(this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer); + this->unk_184 = this->dyna.actor.xzDistToPlayer; + + if (this->dyna.pushForce >= 0.0f) { + phi_f0 = 1.0f; + } else { + phi_f0 = -1.0f; + } + + if (BINANG_SUB(this->dyna.actor.yawTowardsPlayer, player->actor.shape.rot.y) > 0) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + this->unk_17E = phi_v0 * phi_f0; + + phi_v1 = false; + if (this->unk_17E > 0) { + phi_v1 = true; + } + + if (phi_v1) { + this->unk_180 = func_800F2178(this->unk_1B6[0]); + this->unk_1D2 = this->unk_1B6[0]; + this->unk_172 |= 8; + this->actionFunc = func_80A2A444; + } else { + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + } +} + +void func_80A2A444(BgDblueMovebg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp20; + Player* temp_a3; + s16 temp_v0; + + this->unk_188++; + this->unk_188 = CLAMP_MAX(this->unk_188, 5); + + sp20 = Math_StepToS(&this->unk_18A, 900, this->unk_188); + temp_v0 = this->unk_18A * this->unk_17E; + this->dyna.actor.shape.rot.y = + (s32)((this->unk_18C + temp_v0) * 0.1f * (0x10000 / 360.0f)) + this->dyna.actor.home.rot.y; + + if ((player->stateFlags2 & 0x10) && (this->unk_184 > 0.0f)) { + player->actor.world.pos.x = + (Math_SinS(this->dyna.actor.shape.rot.y - this->unk_18E) * this->unk_184) + this->dyna.actor.home.pos.x; + player->actor.world.pos.z = + (Math_CosS(this->dyna.actor.shape.rot.y - this->unk_18E) * this->unk_184) + this->dyna.actor.home.pos.z; + } else { + this->unk_184 = 0.0f; + } + + if (sp20) { + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + Flags_SetSwitch(globalCtx, this->unk_1C0); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); + + if (func_80A29A80(globalCtx, this->unk_1C8, this->unk_1C4)) { + this->unk_172 |= 1; + } else { + this->unk_172 &= ~1; + } + + if (!(this->unk_174 & 1) && (this->unk_172 & 1)) { + func_801000CC(NA_SE_EV_PIPE_STREAM_START); + } + func_80A2A670(this, globalCtx); + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_COCK_SWITCH_ROLL - SFX_FLAG); + } +} + +void func_80A2A670(BgDblueMovebg* this, GlobalContext* globalCtx) { + this->actionFunc = func_80A2A688; +} + +void func_80A2A688(BgDblueMovebg* this, GlobalContext* globalCtx) { + this->unk_180--; + if (this->unk_180 <= 0) { + ActorCutscene_Stop(this->unk_1B6[0]); + } + + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y - 60.0f, 2.0f) && + (this->unk_180 <= 0)) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void func_80A2A714(BgDblueMovebg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 phi_v0; + f32 phi_f0; + + if (this->dyna.pushForce != 0.0f) { + this->unk_18E = BINANG_SUB(this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer); + this->unk_184 = this->dyna.actor.xzDistToPlayer; + if (this->dyna.pushForce >= 0.0f) { + phi_f0 = 1.0f; + } else { + phi_f0 = -1.0f; + } + + if (BINANG_SUB(this->dyna.actor.yawTowardsPlayer, player->actor.shape.rot.y) > 0) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + this->unk_17E = phi_v0 * phi_f0; + + this->unk_180 = func_800F2178(this->unk_1B6[0]); + this->unk_1D2 = this->unk_1B6[0]; + this->unk_172 |= 8; + this->actionFunc = func_80A2A7F8; + } +} + +void func_80A2A7F8(BgDblueMovebg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp28; + s16 sp26; + s32 temp; + + this->unk_188++; + this->unk_188 = CLAMP_MAX(this->unk_188, 5); + + sp28 = Math_StepToS(&this->unk_18A, 900, this->unk_188); + sp26 = this->unk_18A * this->unk_17E; + this->dyna.actor.shape.rot.y = + (s32)((this->unk_18C + sp26) * 0.1f * (0x10000 / 360.0f)) + this->dyna.actor.home.rot.y; + + if ((player->stateFlags2 & 0x10) && (this->unk_184 > 0.0f)) { + player->actor.world.pos.x = + (Math_SinS(this->dyna.actor.shape.rot.y - this->unk_18E) * this->unk_184) + this->dyna.actor.home.pos.x; + player->actor.world.pos.z = + (Math_CosS(this->dyna.actor.shape.rot.y - this->unk_18E) * this->unk_184) + this->dyna.actor.home.pos.z; + } else { + this->unk_184 = 0.0f; + } + + if (sp28) { + temp = (this->unk_18C + sp26 + 3600) % 3600; + + if ((temp == 900) || (temp == 2700)) { + Flags_SetSwitch(globalCtx, this->unk_1C0); + } else { + Flags_UnsetSwitch(globalCtx, this->unk_1C0); + } + + player->stateFlags1 |= 0x20; + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + this->unk_18C = (this->unk_18C + sp26 + 3600) % 3600; + this->unk_188 = 0; + this->unk_18A = 0; + this->unk_17E = 0; + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); + + if (func_80A29A80(globalCtx, this->unk_1C8, this->unk_1C4)) { + this->unk_172 |= 1; + } else { + this->unk_172 &= ~1; + } + + if (!(this->unk_174 & 1) && (this->unk_172 & 1)) { + func_801000CC(NA_SE_EV_PIPE_STREAM_START); + } + + this->unk_174 = this->unk_172; + this->unk_1D0 = 17; + this->actionFunc = func_80A2AAB8; + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_COCK_SWITCH_ROLL - SFX_FLAG); + } +} + +void func_80A2AAB8(BgDblueMovebg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp18; + + if (this->unk_180-- <= 0) { + ActorCutscene_Stop(this->unk_1B6[0]); + } + + sp18 = false; + if ((this->unk_1D0 > 0) && ((D_80A2B974[0] >= 0) || (D_80A2B974[1] >= 0))) { + if (ActorCutscene_GetCurrentIndex() != -1) { + sp18 = true; + } + } + + if (!sp18 && (this->unk_180 <= 0)) { + this->unk_1D0--; + + if (this->unk_1D0 == 1) { + this->dyna.pushForce = 0.0f; + player->stateFlags1 |= 0x20; + player->stateFlags2 &= ~0x10; + } + + if (this->unk_1D0 <= 0) { + player->stateFlags1 &= ~0x20; + this->actionFunc = func_80A2A714; + } + } +} + +void func_80A2ABD0(BgDblueMovebg* this, GlobalContext* globalCtx) { + Vec3f spAC; + f32 temp_f0; + f32 temp_f20; + s32 phi_v0; + s32 i; + s32 j; + + for (i = 0; i < ARRAY_COUNT(this->unk_2F8); i++) { + if (this->unk_2F8[i] == NULL) { + func_80A2A128(this, globalCtx); + continue; + } + + for (j = 0; j < ARRAY_COUNT(this->unk_1D8[0]); j++) { + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.shape.rot.x + (j * 0x2000), MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_80A2B988, &spAC); + Math_Vec3f_Sum(&this->dyna.actor.world.pos, &spAC, &spAC); + Math_Vec3f_Copy(&this->unk_238[i][j], &spAC); + temp_f20 = spAC.y - this->unk_2F8[i]->world.pos.y; + temp_f0 = Math_Vec3f_DistXZ(&this->unk_2F8[i]->world.pos, &spAC); + + if ((this->unk_300[i][j] != 0) && (temp_f20 <= 12.0f) && (temp_f20 >= 0.0f) && (temp_f0 <= 60.0f)) { + phi_v0 = 1; + } else { + phi_v0 = 1; + phi_v0 = (s64)phi_v0; + if (((temp_f20 >= 0.0f) && ((temp_f20 > 0.0f) || (temp_f0 > 60.f))) || + ((temp_f20 < 0.0f) && ((temp_f20 < -150.0f) || (temp_f0 > 40.0f)))) { + phi_v0 = 0; + } + } + + if (phi_v0) { + this->unk_300[i][j] = i + 1; + Math_StepToF(&this->unk_1F8[i][j], 1.0f, 0.2f); + Math_StepToS(&this->unk_1D8[i][j], 255, 20); + } else { + this->unk_300[i][j] = 0; + Math_StepToF(&this->unk_1F8[i][j], 0.0f, 0.01f); + Math_StepToS(&this->unk_1D8[i][j], 0, 20); + } + } + } +} + +void func_80A2AED0(BgDblueMovebg* this, GlobalContext* globalCtx) { + s32 pad; + s32 temp_v0_3; + + if (globalCtx->roomCtx.currRoom.num != this->unk_170) { + if (globalCtx->roomCtx.currRoom.num != this->unk_171) { + if ((globalCtx->roomCtx.prevRoom.num != this->unk_170) && + (globalCtx->roomCtx.prevRoom.num != this->unk_171)) { + D_80A2BBF4.unk_00 = 0; + Actor_MarkForDeath(&this->dyna.actor); + return; + } + } + } + + temp_v0_3 = func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC); + if (temp_v0_3 != this->unk_178) { + switch (temp_v0_3) { + case 1: + case 2: + this->unk_1D2 = this->unk_1B6[0]; + this->unk_17E = 40; + break; + + case 0: + case 3: + this->unk_1D2 = this->unk_1B6[1]; + this->unk_17E = 15; + break; + } + this->unk_172 |= 8; + } + this->unk_178 = temp_v0_3; + + if (!(this->unk_172 & 8)) { + if (this->unk_17E <= 0) { + this->unk_1CE = D_80A2B96C[temp_v0_3]; + } else { + this->unk_17E--; + } + } + + Math_StepToS(&this->unk_1CC, this->unk_1CE, 12); + this->dyna.actor.shape.rot.x += this->unk_1CC; + + if (this->unk_160 == 8) { + if (globalCtx->roomCtx.currRoom.num == 8) { + func_80A2ABD0(this, globalCtx); + this->unk_172 |= 0x20; + } else { + this->unk_172 &= ~0x20; + } + } + + if (globalCtx->roomCtx.currRoom.num == 0) { + this->unk_164 = object_dblue_object_DL_008778; + } else if (globalCtx->roomCtx.currRoom.num == 8) { + this->unk_164 = object_dblue_object_DL_00A528; + } + + if (this == D_80A2BBF0) { + Vec3f sp54; + f32 sp50; + + if (Math3D_PointDistToLine2D(globalCtx->view.eye.x, globalCtx->view.eye.z, this->unk_190.x, this->unk_190.z, + this->unk_19C.x, this->unk_19C.z, &sp54.x, &sp54.z, &sp50)) { + sp54.y = this->dyna.actor.world.pos.y; + } else { + if (Math_Vec3f_DistXYZ(&globalCtx->view.eye, &this->unk_190) <= + Math_Vec3f_DistXYZ(&globalCtx->view.eye, &this->unk_19C)) { + Math_Vec3f_Copy(&sp54, &this->unk_190); + } else { + Math_Vec3f_Copy(&sp54, &this->unk_19C); + } + } + + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &sp54, &this->unk_1A8); + this->unk_1D4 = ABS(this->unk_1CC) / 364.0f; + } +} + +void func_80A2B1A0(BgDblueMovebg* this, GlobalContext* globalCtx) { + switch (func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC)) { + case 1: + this->dyna.actor.shape.rot.z = this->dyna.actor.home.rot.z; + break; + + case 2: + this->dyna.actor.shape.rot.z = BINANG_ROT180(this->dyna.actor.home.rot.z); + break; + } +} + +void BgDblueMovebg_Update(Actor* thisx, GlobalContext* globalCtx) { + BgDblueMovebg* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->unk_172 & 8) { + if (SubS_StartActorCutscene(&this->dyna.actor, this->unk_1D2, -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + this->unk_172 &= ~8; + } + } +} + +void func_80A2B274(Actor* thisx, GlobalContext* globalCtx) { + BgDblueMovebg* this = THIS; + s16 temp_v1; + + if (this != D_80A2BBF0) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + temp_v1 = D_80A2B96C[func_80A29A80(globalCtx, this->unk_1C0, this->unk_1BC)]; + if (temp_v1 != 0) { + if (temp_v1 > 0) { + func_8019FC20(&this->dyna.actor.projectedPos, NA_SE_EV_DUMMY_WATER_WHEEL_RR - SFX_FLAG); + } else { + func_8019FC20(&this->dyna.actor.projectedPos, NA_SE_EV_DUMMY_WATER_WHEEL_LR - SFX_FLAG); + } + } +} + +void func_80A2B308(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueMovebg* 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++, this->unk_164); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void BgDblueMovebg_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + BgDblueMovebg* this = THIS; + s32 i; + s32 j; + Gfx* gfx; + Gfx* gfx2; + + Matrix_Push(); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->unk_160 == 9) || (this->unk_160 == 8) || (this->dyna.actor.flags & ACTOR_FLAG_40)) { + if (this->unk_16C != NULL) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(this->unk_16C)); + } + + if ((this->unk_164 != 0) || (this->unk_160 == 6)) { + gfx2 = Gfx_CallSetupDL(POLY_OPA_DISP, 0x19); + + gSPMatrix(&gfx2[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->unk_160 == 6) { + gSPDisplayList(&gfx2[1], object_dblue_object_DL_0052B8); + if (this->unk_164 != 0) { + gSPDisplayList(&gfx2[2], this->unk_164); + POLY_OPA_DISP = &gfx2[3]; + } else { + POLY_OPA_DISP = &gfx2[2]; + } + } else { + gSPDisplayList(&gfx2[1], this->unk_164); + POLY_OPA_DISP = &gfx2[2]; + } + } + + if (this->unk_168 != NULL) { + gfx = func_8012C2B4(POLY_XLU_DISP); + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], this->unk_168); + + POLY_XLU_DISP = &gfx[2]; + } + } + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if ((this->unk_160 == 8) && (this->unk_172 & 0x20)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_dblue_object_Matanimheader_00CE00)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + gfx = func_8012C2B4(POLY_XLU_DISP); + + for (i = 0; i < ARRAY_COUNT(this->unk_1D8[0]); i++) { + for (j = 0; j < ARRAY_COUNT(this->unk_1D8); j++) { + if (this->unk_1D8[j][i] > 0) { + if (this->unk_1F8[j][i] > 0.1f) { + gSPSegment( + gfx++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, + (s32)(((globalCtx->gameplayFrames % 128) * -9.0f) / this->unk_1F8[j][i]), + 0x20, 0x20, 1, 0, 0, 0x20, 0x20)); + } + Matrix_Push(); + Matrix_RotateXS(i * 0x2000, MTXMODE_APPLY); + Matrix_Translate(1785.0f, 0.0f, 270.0f, MTXMODE_APPLY); + if (j != 0) { + Matrix_RotateZS(-0x8000, MTXMODE_APPLY); + } + Matrix_Scale(this->unk_1F8[j][i] * this->dyna.actor.scale.x, + this->unk_1F8[j][i] * this->dyna.actor.scale.y, + this->unk_1F8[j][i] * this->dyna.actor.scale.z, MTXMODE_APPLY); + + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetEnvColor(gfx++, 255, 255, 255, this->unk_1D8[j][i]); + gSPDisplayList(gfx++, object_dblue_object_DL_00CD10); + + Matrix_Pop(); + } + } + } + POLY_XLU_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if ((this->unk_160 == 9) || (this->unk_160 == 8)) { + if (this->unk_1CC >= 0) { + func_8019FB0C(&this->unk_1A8, NA_SE_EV_BIG_WATER_WHEEL_RR - SFX_FLAG, this->unk_1D4, 32); + } else { + func_8019FB0C(&this->unk_1A8, NA_SE_EV_BIG_WATER_WHEEL_LR - SFX_FLAG, this->unk_1D4, 32); + } + } +} diff --git a/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.h b/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.h index aeef09c87..b48776238 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.h +++ b/src/overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.h @@ -7,11 +7,52 @@ struct BgDblueMovebg; typedef void (*BgDblueMovebgActionFunc)(struct BgDblueMovebg*, GlobalContext*); +#define BGDBLUEMOVEBG_GET_F(thisx) ((thisx)->params & 0xF) +#define BGDBLUEMOVEBG_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF) +#define BGDBLUEMOVEBG_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) + +#define BGDBLUEMOVEBG_F_8 8 + typedef struct BgDblueMovebg { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ BgDblueMovebgActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x210]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgDblueMovebgActionFunc actionFunc; + /* 0x160 */ s32 unk_160; + /* 0x164 */ Gfx* unk_164; + /* 0x168 */ Gfx* unk_168; + /* 0x16C */ TexturePtr unk_16C; + /* 0x170 */ s8 unk_170; + /* 0x171 */ s8 unk_171; + /* 0x172 */ u16 unk_172; + /* 0x174 */ u16 unk_174; + /* 0x178 */ s32 unk_178; + /* 0x17C */ UNK_TYPE1 unk17C[2]; + /* 0x17E */ s16 unk_17E; + /* 0x180 */ s16 unk_180; + /* 0x184 */ f32 unk_184; + /* 0x188 */ s16 unk_188; + /* 0x18A */ s16 unk_18A; + /* 0x18C */ s16 unk_18C; + /* 0x18E */ s16 unk_18E; + /* 0x190 */ Vec3f unk_190; + /* 0x19C */ Vec3f unk_19C; + /* 0x1A8 */ Vec3f unk_1A8; + /* 0x1B4 */ UNK_TYPE1 unk1B4[2]; + /* 0x1B6 */ s16 unk_1B6[2]; + /* 0x1BC */ s32 unk_1BC; + /* 0x1C0 */ s32 unk_1C0; + /* 0x1C4 */ s32 unk_1C4; + /* 0x1C8 */ s32 unk_1C8; + /* 0x1CC */ s16 unk_1CC; + /* 0x1CE */ s16 unk_1CE; + /* 0x1D0 */ s16 unk_1D0; + /* 0x1D2 */ s16 unk_1D2; + /* 0x1D4 */ f32 unk_1D4; + /* 0x1D8 */ s16 unk_1D8[2][8]; + /* 0x1F8 */ f32 unk_1F8[2][8]; + /* 0x238 */ Vec3f unk_238[2][8]; + /* 0x2F8 */ Actor* unk_2F8[2]; + /* 0x300 */ u8 unk_300[2][8]; + /* 0x310 */ UNK_TYPE1 unk310[0x60]; } BgDblueMovebg; // size = 0x370 extern const ActorInit Bg_Dblue_Movebg_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.c b/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.c index 97ddab138..fcec4ebb3 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.c +++ b/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.c @@ -1,6 +1,13 @@ -#include "z_bg_dblue_waterfall.h" +/* + * File: z_bg_dblue_waterfall.c + * Overlay: ovl_Bg_Dblue_Waterfall + * Description: Great Bay Temple - Freezable Geyser + */ -#define FLAGS 0x00000010 +#include "z_bg_dblue_waterfall.h" +#include "objects/object_dblue_object/object_dblue_object.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgDblueWaterfall*)thisx) @@ -9,12 +16,15 @@ void BgDblueWaterfall_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgDblueWaterfall_Update(Actor* thisx, GlobalContext* globalCtx); void BgDblueWaterfall_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B8484C(BgDblueWaterfall* this, GlobalContext* globalCtx); void func_80B84928(BgDblueWaterfall* this, GlobalContext* globalCtx); +void func_80B84AD4(BgDblueWaterfall* this, GlobalContext* globalCtx); void func_80B84AEC(BgDblueWaterfall* this, GlobalContext* globalCtx); +void func_80B84B9C(BgDblueWaterfall* this, GlobalContext* globalCtx); void func_80B84BCC(BgDblueWaterfall* this, GlobalContext* globalCtx); +void func_80B84EF0(BgDblueWaterfall* this, GlobalContext* globalCtx); void func_80B84F20(BgDblueWaterfall* this, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Dblue_Waterfall_InitVars = { ACTOR_BG_DBLUE_WATERFALL, ACTORCAT_PROP, @@ -27,69 +37,596 @@ const ActorInit Bg_Dblue_Waterfall_InitVars = { (ActorFunc)BgDblueWaterfall_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B85370 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00CBFBB0, 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_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00CBFBB0, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 50, 740, -740, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B853A8[] = { +Color_RGBA8 D_80B8539C = { 200, 255, 255, 255 }; +Color_RGBA8 D_80B853A0 = { 200, 200, 200, 0 }; + +s32 func_80B83C80(Vec3f* arg0, Vec3f* arg1) { + f32 temp_f0 = Math3D_LengthSquared(arg0); + f32 temp_f2; + + if (temp_f0 < 0.0000010000001f) { + return false; + } + + temp_f2 = 1.0f / sqrtf(temp_f0); + arg1->x = arg0->x * temp_f2; + arg1->y = arg0->y * temp_f2; + arg1->z = arg0->z * temp_f2; + + return true; +} + +s32 func_80B83D04(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 phi_v1; + s32 sp18 = BGDBLUEWATERFALL_GET_100(&this->actor); + + if (Flags_GetSwitch(globalCtx, BGDBLUEWATERFALL_GET_7F(&this->actor))) { + phi_v1 = true; + } else { + phi_v1 = false; + } + return phi_v1 ^ sp18; +} + +s32 func_80B83D58(Actor* thisx, GlobalContext* globalCtx) { + BgDblueWaterfall* this = THIS; + + if (Flags_GetSwitch(globalCtx, BGDBLUEWATERFALL_GET_7F(&this->actor))) { + return false; + } + return true; +} + +void func_80B83D94(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20 = BGDBLUEWATERFALL_GET_7F(&this->actor); + s32 sp1C = BGDBLUEWATERFALL_GET_100(&this->actor); + s32 phi_v0; + + if (Flags_GetSwitch(globalCtx, sp20)) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (phi_v0 != sp1C) { + if (phi_v0) { + Flags_UnsetSwitch(globalCtx, sp20); + } else { + Flags_SetSwitch(globalCtx, sp20); + } + } +} + +void func_80B83E1C(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20 = BGDBLUEWATERFALL_GET_7F(&this->actor); + s32 sp1C = BGDBLUEWATERFALL_GET_100(&this->actor); + s32 phi_v0; + + if (Flags_GetSwitch(globalCtx, sp20)) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (phi_v0 == sp1C) { + if (phi_v0) { + Flags_UnsetSwitch(globalCtx, sp20); + } else { + Flags_SetSwitch(globalCtx, sp20); + } + } +} + +void func_80B83EA4(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 i; + s32 temp_s1; + Vec3f spD4; + Vec3f spC8; + Vec3f spBC; + Vec3f spB0; + Vec3f spA4; + Vec3f sp98; + s32 phi_s3; + + if (this->collider.info.bumperFlags & BUMP_HIT) { + f32 temp_f0_2; + f32 temp_f20; + + spB0.x = this->collider.info.bumper.hitPos.x; + spB0.y = this->collider.info.bumper.hitPos.y; + spB0.z = this->collider.info.bumper.hitPos.z; + + sp98.x = spB0.x - this->actor.world.pos.x; + sp98.y = 0.0f; + sp98.z = spB0.z - this->actor.world.pos.z; + + if (!func_80B83C80(&sp98, &spA4)) { + Math_Vec3f_Copy(&spA4, &gZeroVec3f); + } + + sp98.y = 0.0f; + spBC.y = -1.4f; + + for (i = 0, phi_s3 = 0; i < 15; i++, phi_s3 += 0x1111) { + temp_s1 = (s32)(Rand_ZeroOne() * 4369.0f) + phi_s3; + temp_f0_2 = Rand_ZeroOne(); + temp_f20 = 1.0f - SQ(temp_f0_2); + + sp98.x = Math_SinS(temp_s1) * temp_f20; + sp98.z = Math_CosS(temp_s1) * temp_f20; + temp_f20 *= 5.0f; + + spD4.x = (sp98.x * temp_f20) + spB0.x; + spD4.y = ((Rand_ZeroOne() * 16.0f) - 8.0f) + spB0.y; + spD4.z = (sp98.z * temp_f20) + spB0.z; + + spC8.x = ((2.0f * Rand_ZeroOne()) - 1.0f) + ((spA4.x * 3.0f) + (sp98.x * 5.0f)); + spC8.y = (Rand_ZeroOne() * 10.0f) + 5.0f; + spC8.z = ((2.0f * Rand_ZeroOne()) - 1.0f) + ((spA4.z * 3.0f) + (sp98.z * 5.0f)); + + spBC.x = spC8.x * -0.02f; + spBC.z = spC8.z * -0.02f; + + EffectSsEnIce_Spawn(globalCtx, &spD4, (Rand_ZeroOne() * 0.3f) + 0.1f, &spC8, &spBC, &D_80B8539C, + &D_80B853A0, 30); + } + } +} + +void func_80B841A0(BgDblueWaterfall* this, GlobalContext* globalCtx) { + Vec3f sp94; + s32 i; + f32 temp_f0; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + f32 temp_f26; + s32 temp_s3; + s32 phi_s2; + + if (this->collider.info.bumperFlags & BUMP_HIT) { + temp_f22 = this->collider.info.bumper.hitPos.x; + temp_f24 = this->collider.info.bumper.hitPos.y; + temp_f26 = this->collider.info.bumper.hitPos.z; + + for (i = 0, phi_s2 = 0; i < 10; i++, phi_s2 += 0x1999) { + temp_s3 = (s32)(Rand_ZeroOne() * 6553.0f) + phi_s2; + temp_f0 = Rand_ZeroOne(); + temp_f20 = (1.0f - SQ(temp_f0)) * 14.0f; + + sp94.x = (Math_SinS(temp_s3) * temp_f20) + temp_f22; + sp94.y = ((Rand_ZeroOne() * 20.0f) - 10.0f) + temp_f24; + sp94.z = (Math_CosS(temp_s3) * temp_f20) + temp_f26; + + EffectSsGSplash_Spawn(globalCtx, &sp94, NULL, NULL, 0, 250); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_REFLECTION_WATER); + } +} + +void func_80B84348(BgDblueWaterfall* this, GlobalContext* globalCtx, f32 arg2, f32 arg3, f32 arg4, f32 arg5, f32 arg6, + f32 arg7, s32 arg8) { + static s16 D_80B853A4 = 0; + s32 pad; + f32 spB8 = 1.0f / arg8; + s32 i; + f32 spB0 = this->actor.world.pos.y + arg3; + s32 pad2; + f32 temp_f22; + f32 temp_f24; + Vec3f sp98; + Vec3f sp8C; + Vec3f sp80; + f32 temp_f26; + f32 temp_f20; + + for (i = 0; i < arg8; i++) { + D_80B853A4 += 0x4E20; + + temp_f20 = Math_SinS(D_80B853A4); + temp_f24 = (Rand_ZeroOne() * (arg2 - arg3)) + (spB8 * i); + temp_f22 = Math_CosS(D_80B853A4); + temp_f26 = ((Rand_ZeroOne() * 0.8f) + 0.2f) * arg4; + + sp8C.x = temp_f20 * temp_f26; + sp8C.y = (Rand_ZeroOne() * 4.0f) + arg5; + sp8C.z = temp_f22 * temp_f26; + + sp80.x = sp8C.x * -0.016f; + sp80.y = sp8C.y * -0.015f; + sp80.z = sp8C.z * -0.016f; + + sp98.x = (temp_f20 * 50.0f) + this->actor.world.pos.x; + sp98.y = temp_f24 + spB0; + sp98.z = (temp_f22 * 50.0f) + this->actor.world.pos.z; + + EffectSsIceSmoke_Spawn(globalCtx, &sp98, &sp8C, &sp80, (Rand_ZeroOne() * arg7) + arg6); + } +} + +void func_80B84568(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + CollisionPoly* sp40; + WaterBox* sp3C; + s32 sp38; + f32 sp34 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp40, &sp38, &this->actor, &this->actor.world.pos); + f32 sp30; + + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp30, + &sp3C)) { + if (sp30 < sp34) { + this->unk_198 = sp34; + } else { + this->unk_198 = sp30; + } + } else { + this->unk_198 = sp34; + } +} + +void func_80B84610(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad[2]; + Vec3f sp34; + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_1A7 <= 0) { + this->unk_1A7 = 16; + } else { + this->unk_1A7 -= (s8)((u32)Rand_Next() >> 0x1F); + } + + if (this->unk_1A7 >= 6) { + this->unk_1A8 += Rand_ZeroOne() * 0.1f; + if (this->unk_1A8 > 0.5f) { + this->unk_1A8 = 0.5f; + } else { + this->unk_1A8 = this->unk_1A8; + } + } else { + this->unk_1A8 -= Rand_ZeroOne() * 0.2f; + if (this->unk_1A8 > -0.5f) { + this->unk_1A8 = -0.5f; + } else { + this->unk_1A8 = this->unk_1A8; + } + } + + Matrix_Push(); + Matrix_RotateYS(BINANG_ADD(this->actor.yawTowardsPlayer, 0x4000), MTXMODE_NEW); + Matrix_MultVecZ(this->unk_1A8, &sp34); + Matrix_Pop(); + + player->actor.world.pos.x += sp34.x; + player->actor.world.pos.z += sp34.z; + if (this && this && this) {} + player->unk_B80 = 8.0f; + player->unk_B84 = this->actor.yawTowardsPlayer; +} + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1500, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1500, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void BgDblueWaterfall_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueWaterfall* this = THIS; -extern ColliderCylinderInit D_80B85370; -extern InitChainEntry D_80B853A8[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.shape.rot.z = 0; + this->actor.world.rot.z = 0; -extern UNK_TYPE D_0600B280; -extern UNK_TYPE D_0600B448; + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83C80.s") + this->unk_190 = Lib_SegmentedToVirtual(object_dblue_object_Matanimheader_00B448); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83D04.s") + Actor_SetFocus(&this->actor, -100.0f); + func_80B84568(this, globalCtx); + func_80B8484C(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83D58.s") +void BgDblueWaterfall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgDblueWaterfall* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83D94.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83E1C.s") +void func_80B8484C(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + s32 temp = func_80B83D04(this, globalCtx); + s32 sp1C = this->actor.home.rot.z * 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B83EA4.s") + if (temp) { + this->unk_19E = 0; + this->unk_19F = 255; + this->unk_1A0 = 0; + this->collider.dim.radius = 55; + this->collider.dim.height = 150; + this->collider.dim.yShift = -150; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + } else { + this->unk_19E = 255; + this->unk_19F = 0; + this->unk_1A0 = 0; + this->collider.dim.radius = 50; + this->collider.dim.height = 740; + this->collider.dim.yShift = -740; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B841A0.s") + if ((sp1C != 0) && !func_80B83D58(&this->actor, globalCtx)) { + this->unk_19C = sp1C; + } else { + this->unk_19C = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84348.s") + this->unk_1A3 = false; + this->actionFunc = func_80B84928; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84568.s") +void func_80B84928(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30 = func_80B83D04(this, globalCtx); + s32 sp2C = (this->collider.base.acFlags & AC_HIT) != 0; + s32 sp28 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84610.s") + if (sp2C) { + this->collider.base.acFlags &= ~AC_HIT; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/BgDblueWaterfall_Init.s") + if ((sp30 == 0) && (this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { + func_80B84610(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/BgDblueWaterfall_Destroy.s") + if (this->unk_19C > 0) { + this->unk_19C--; + if (this->unk_19C == 0) { + if (sp30 != 0) { + func_80B83D94(this, globalCtx); + func_80B84EF0(this, globalCtx); + } else { + func_80B83E1C(this, globalCtx); + func_80B84B9C(this, globalCtx); + } + sp28 = true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B8484C.s") + if (!sp28) { + if (sp2C) { + if (sp30 != 0) { + func_80B83EA4(this, globalCtx); + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x800) { + this->unk_1A4 = this->actor.cutscene; + func_80B84AD4(this, globalCtx); + } + } else { + func_80B841A0(this, globalCtx); + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x1000) { + this->unk_1A4 = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + func_80B84AD4(this, globalCtx); + } + } + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84928.s") +void func_80B84AD4(BgDblueWaterfall* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B84AEC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84AD4.s") +void func_80B84AEC(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84AEC.s") + if (ActorCutscene_GetCanPlayNext(this->unk_1A4)) { + sp20 = func_80B83D04(this, globalCtx); + ActorCutscene_StartAndSetUnkLinkFields(this->unk_1A4, &this->actor); + this->unk_1A3 = true; + if (sp20) { + func_80B83D94(this, globalCtx); + func_80B84EF0(this, globalCtx); + } else { + func_80B83E1C(this, globalCtx); + func_80B84B9C(this, globalCtx); + } + } else { + ActorCutscene_SetIntentToPlay(this->unk_1A4); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84B9C.s") +void func_80B84B9C(BgDblueWaterfall* this, GlobalContext* globalCtx) { + this->unk_19C = 60; + this->unk_19E = 255; + this->unk_19F = 0; + this->unk_1A0 = 0; + this->actionFunc = func_80B84BCC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84BCC.s") +void func_80B84BCC(BgDblueWaterfall* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84EF0.s") + this->unk_19C--; + if (this->unk_19C > 0) { + s32 sp38 = this->unk_19C & 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/func_80B84F20.s") + if (this->unk_19C > 56) { + func_80B84348(this, globalCtx, 0.0f, -5500.0f, 0.4f, -15.0f, 370.0f, 100.0f, 6); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/BgDblueWaterfall_Update.s") + if (!sp38) { + if ((this->unk_19C < 24) && (this->unk_19C > 10)) { + if (this->unk_198 > -32000.0f) { + func_80B84348(this, globalCtx, (this->unk_198 - this->actor.world.pos.y) + 50.0f, + (this->unk_198 - this->actor.world.pos.y), 7.0f, -1.0f, 280.0f, 100.0f, 3); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Dblue_Waterfall/BgDblueWaterfall_Draw.s") + if (this->unk_19C > 50) { + func_80B84348(this, globalCtx, 0.0f, -400.0f, 0.6f, -12.0f, 370.0f, 100.0f, 2); + } else if (this->unk_19C > 40) { + func_80B84348(this, globalCtx, 0.0f, -400.0f, 1.0f, -12.0f, 370.0f, 100.0f, 2); + } else if (this->unk_19C > 20) { + func_80B84348(this, globalCtx, 0.0f, -400.0f, 1.8f, -12.0f, 370.0f, 100.0f, 2); + } + } + + if (this->unk_19E > 6) { + this->unk_19E -= 6; + } else { + this->unk_19E = 0; + } + + if (this->unk_19C >= 55) { + if (this->unk_1A0 < 205) { + this->unk_1A0 += 50; + } else { + this->unk_1A0 = 255; + } + } else if (this->unk_19C >= 36) { + if (this->unk_1A0 >= 16) { + this->unk_1A0 -= 15; + } else { + this->unk_1A0 = 0; + } + } else { + this->unk_1A0 = 0; + } + + if (this->unk_19C < 60) { + if (this->unk_19F < 245) { + this->unk_19F += 10; + } else { + this->unk_19F = 255; + } + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } else { + if (this->unk_1A3) { + ActorCutscene_Stop(this->unk_1A4); + } + func_80B8484C(this, globalCtx); + } +} + +void func_80B84EF0(BgDblueWaterfall* this, GlobalContext* globalCtx) { + this->unk_19C = 60; + this->unk_19E = 0; + this->unk_19F = 255; + this->unk_1A0 = 0; + this->actionFunc = func_80B84F20; +} + +void func_80B84F20(BgDblueWaterfall* this, GlobalContext* globalCtx) { + this->unk_19C--; + + if (this->unk_19C > 0) { + if (this->unk_19C >= 58) { + func_80B84348(this, globalCtx, 100.0f, -100.0f, 4.0f, -6.0f, 370.0f, 100.0f, 0xC); + } + + if (this->unk_19C < 50) { + if (this->unk_19E < 250) { + this->unk_19E += 5; + } else { + this->unk_19E = 255; + } + } + + if (this->unk_19F >= 6) { + this->unk_19F -= 5; + } else { + this->unk_19F = 0; + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + } else { + if (this->unk_1A3) { + ActorCutscene_Stop(this->unk_1A4); + } + func_80B8484C(this, globalCtx); + } +} + +void BgDblueWaterfall_Update(Actor* thisx, GlobalContext* globalCtx) { + BgDblueWaterfall* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgDblueWaterfall_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgDblueWaterfall* this = THIS; + + 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); + + if (this->unk_19E > 0) { + s32 sp38 = this->unk_19E * 0.49803922f; + + AnimatedMat_Draw(globalCtx, this->unk_190); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x8A, 255, 255, 255, sp38); + gSPDisplayList(POLY_XLU_DISP++, object_dblue_object_DL_00B280); + } + + if (this->unk_19F > 0) { + if (this->unk_19F < 255) { + gSPSegment(POLY_XLU_DISP++, 0x09, D_801AEF88); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x9B, 255, 255, 255, this->unk_19F); + gSPDisplayList(POLY_XLU_DISP++, object_dblue_object_DL_003358); + } else { + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x09, D_801AEFA0); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x9B, 255, 255, 255, 255); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_dblue_object_DL_003358); + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0xFF, 255, 255, 255, this->unk_19F); + gSPDisplayList(POLY_XLU_DISP++, object_dblue_object_DL_003250); + } + + if (this->unk_1A0 > 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0xFF, 255, 255, 255, this->unk_1A0); + gSPDisplayList(POLY_XLU_DISP++, object_dblue_object_DL_003770); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.h b/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.h index eb12538fc..0fa908629 100644 --- a/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.h +++ b/src/overlays/actors/ovl_Bg_Dblue_Waterfall/z_bg_dblue_waterfall.h @@ -7,11 +7,25 @@ struct BgDblueWaterfall; typedef void (*BgDblueWaterfallActionFunc)(struct BgDblueWaterfall*, GlobalContext*); +#define BGDBLUEWATERFALL_GET_7F(thisx) ((thisx)->params & 0x7F) +#define BGDBLUEWATERFALL_GET_100(thisx) (((thisx)->params >> 8) & 1) + typedef struct BgDblueWaterfall { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x50]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ AnimatedMaterial* unk_190; /* 0x0194 */ BgDblueWaterfallActionFunc actionFunc; - /* 0x0198 */ char unk_198[0x14]; + /* 0x0198 */ f32 unk_198; + /* 0x019C */ s16 unk_19C; + /* 0x019E */ u8 unk_19E; + /* 0x019F */ u8 unk_19F; + /* 0x01A0 */ u8 unk_1A0; + /* 0x01A1 */ UNK_TYPE1 unk1A1[2]; + /* 0x01A3 */ s8 unk_1A3; + /* 0x01A4 */ s16 unk_1A4; + /* 0x01A6 */ UNK_TYPE1 unk1A6[1]; + /* 0x01A7 */ s8 unk_1A7; + /* 0x01A8 */ f32 unk_1A8; } BgDblueWaterfall; // size = 0x1AC extern const ActorInit Bg_Dblue_Waterfall_InitVars; 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 5761c8585..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,3 +1,9 @@ +/* + * File: z_bg_dkjail_ivy.c + * Overlay: ovl_Bg_Dkjail_Ivy + * Description: Cuttable Ivy wall (beneath Woodfall Temple, Swamp Spider House) + */ + #include "z_bg_dkjail_ivy.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c index 4e5993c5a..4e9bf5c63 100644 --- a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c +++ b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_dy_yoseizo.c + * Overlay: ovl_Bg_Dy_Yoseizo + * Description: Great Fairy + */ + #include "z_bg_dy_yoseizo.h" -#define FLAGS 0x02000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((BgDyYoseizo*)thisx) 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_Block/z_bg_f40_block.c b/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.c index 08c1a2fdd..1e8c369fb 100644 --- a/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.c +++ b/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.c @@ -1,6 +1,13 @@ -#include "z_bg_f40_block.h" +/* + * File: z_bg_f40_block.c + * Overlay: ovl_Bg_F40_Block + * Description: Stone Tower Block + */ -#define FLAGS 0x00000010 +#include "z_bg_f40_block.h" +#include "objects/object_f40_obj/object_f40_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgF40Block*)thisx) @@ -9,7 +16,16 @@ void BgF40Block_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgF40Block_Update(Actor* thisx, GlobalContext* globalCtx); void BgF40Block_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BC41AC(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC4228(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC4344(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC4380(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC43CC(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC4448(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC44F4(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC4530(BgF40Block* this, GlobalContext* globalCtx); +void func_80BC457C(BgF40Block* this, GlobalContext* globalCtx); + const ActorInit Bg_F40_Block_InitVars = { ACTOR_BG_F40_BLOCK, ACTORCAT_BG, @@ -22,55 +38,340 @@ const ActorInit Bg_F40_Block_InitVars = { (ActorFunc)BgF40Block_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BC4668[] = { +static Vec3f D_80BC4620[] = { + { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, + { -1.0f, 0.0f, 0.0f }, { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f, -1.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +s32 func_80BC3980(BgF40Block* this, GlobalContext* globalCtx) { + Vec3s* points; -extern InitChainEntry D_80BC4668[]; + this->unk_160 = 0; + this->unk_164 = 0; -extern UNK_TYPE D_060043D0; -extern UNK_TYPE D_06004640; + if (BGF40BLOCK_GET_PATH(&this->dyna.actor) != 0x3F) { + this->path = &globalCtx->setupPathList[BGF40BLOCK_GET_PATH(&this->dyna.actor)]; + if (this->path != NULL) { + points = Lib_SegmentedToVirtual(this->path->points); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC3980.s") + this->dyna.actor.world.pos.x = points->x; + this->dyna.actor.world.pos.y = points->y; + this->dyna.actor.world.pos.z = points->z; + } + } else { + this->path = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC3A2C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC3B00.s") +s32 func_80BC3A2C(BgF40Block* this, GlobalContext* globalCtx) { + Vec3s* points; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC3CA4.s") + this->unk_160 = this->path->count - 1; + this->unk_164 = this->path->count - 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC3D08.s") + if (BGF40BLOCK_GET_PATH(&this->dyna.actor) != 0x3F) { + this->path = &globalCtx->setupPathList[BGF40BLOCK_GET_PATH(&this->dyna.actor)]; + if (this->path != NULL) { + points = Lib_SegmentedToVirtual(this->path->points); + points += this->unk_164; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4038.s") + this->dyna.actor.world.pos.x = points->x; + this->dyna.actor.world.pos.y = points->y; + this->dyna.actor.world.pos.z = points->z; + } + } else { + this->path = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/BgF40Block_Init.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/BgF40Block_Destroy.s") +s32 func_80BC3B00(BgF40Block* this) { + s32 pad; + Path* path; + Vec3s* points; + Vec3f sp28; + Vec3f sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC41AC.s") + if (this->path == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4228.s") + if (this->unk_160 == this->unk_164) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4344.s") + path = this->path; + points = Lib_SegmentedToVirtual(path->points); + points += this->unk_164; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4380.s") + sp28.x = points->x; + sp28.y = points->y; + sp28.z = points->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC43CC.s") + if (this->unk_168 == 6) { + sp24.x = sp28.x - this->dyna.actor.world.pos.x; + sp24.y = sp28.y - this->dyna.actor.world.pos.y; + sp24.z = sp28.z - this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4448.s") + if (sp24.x > 10.0f) { + this->unk_168 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC44F4.s") + if (sp24.y > 10.0f) { + this->unk_168 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC4530.s") + if (sp24.z > 10.0f) { + this->unk_168 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/func_80BC457C.s") + if (sp24.x < -10.0f) { + this->unk_168 = 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/BgF40Block_Update.s") + if (sp24.y < -10.0f) { + this->unk_168 = 4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Block/BgF40Block_Draw.s") + if (sp24.z < -10.0f) { + this->unk_168 = 5; + } + } + + if (Math_Vec3f_StepTo(&this->dyna.actor.world.pos, &sp28, this->dyna.actor.speedXZ) <= 0.0f) { + this->unk_168 = 6; + this->unk_160 = this->unk_164; + return true; + } + return false; +} + +s32 func_80BC3CA4(BgF40Block* this) { + if (this->dyna.actor.cutscene == -1) { + return true; + } + + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + return true; + } + + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + return false; +} + +s32 func_80BC3D08(BgF40Block* this, GlobalContext* globalCtx, s32 arg2) { + CollisionPoly* sp54; + Vec3f sp48; + Vec3f sp3C; + Vec3f sp30; + + if (this->unk_168 == 6) { + return false; + } + + if (arg2 != 0) { + sp48.x = + (D_80BC4620[this->unk_168].x * ((800.0f * this->dyna.actor.scale.x) - (this->dyna.actor.speedXZ * 0.5f))) + + this->dyna.actor.world.pos.x; + sp48.y = + (D_80BC4620[this->unk_168].y * ((800.0f * this->dyna.actor.scale.y) - (this->dyna.actor.speedXZ * 0.5f))) + + this->dyna.actor.world.pos.y; + sp48.z = + (D_80BC4620[this->unk_168].z * ((800.0f * this->dyna.actor.scale.z) - (this->dyna.actor.speedXZ * 0.5f))) + + this->dyna.actor.world.pos.z; + + sp3C.x = (D_80BC4620[this->unk_168].x * this->dyna.actor.speedXZ) + sp48.x; + sp3C.y = (D_80BC4620[this->unk_168].y * this->dyna.actor.speedXZ) + sp48.y; + sp3C.z = (D_80BC4620[this->unk_168].z * this->dyna.actor.speedXZ) + sp48.z; + } else { + sp3C.x = (D_80BC4620[this->unk_168].x * 800.0f * this->dyna.actor.scale.x) + this->dyna.actor.world.pos.x; + sp3C.y = (D_80BC4620[this->unk_168].y * 800.0f * this->dyna.actor.scale.y) + this->dyna.actor.world.pos.y; + sp3C.z = (D_80BC4620[this->unk_168].z * 800.0f * this->dyna.actor.scale.z) + this->dyna.actor.world.pos.z; + + sp48.x = sp3C.x - (D_80BC4620[this->unk_168].x * this->dyna.actor.speedXZ * 1.5f); + sp48.y = sp3C.y - (D_80BC4620[this->unk_168].y * this->dyna.actor.speedXZ * 1.5f); + sp48.z = sp3C.z - (D_80BC4620[this->unk_168].z * this->dyna.actor.speedXZ * 1.5f); + } + + if (BgCheck_AnyLineTest1(&globalCtx->colCtx, &sp48, &sp3C, &sp30, &sp54, true)) { + if (arg2 == 0) { + this->dyna.actor.world.pos.x -= sp3C.x - sp30.x; + this->dyna.actor.world.pos.y -= sp3C.y - sp30.y; + this->dyna.actor.world.pos.z -= sp3C.z - sp30.z; + } + return true; + } + + return false; +} + +void func_80BC4038(BgF40Block* this) { + s32 temp = this->unk_160; + + this->unk_160 = this->unk_164; + this->unk_164 = temp; + this->unk_168 = 6; +} + +void BgF40Block_Init(Actor* thisx, GlobalContext* globalCtx) { + BgF40Block* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_f40_obj_Colheader_004640); + + if (BGF40BLOCK_GET_PATH(&this->dyna.actor) != 0x3F) { + this->path = &globalCtx->setupPathList[BGF40BLOCK_GET_PATH(&this->dyna.actor)]; + } else { + this->path = NULL; + } + + if (this->path != NULL) { + if (Flags_GetSwitch(globalCtx, BGF40BLOCK_GET_SWITCHFLAG(&this->dyna.actor))) { + this->actionFunc = func_80BC4530; + this->dyna.actor.speedXZ = 40.0f; + func_80BC3A2C(this, globalCtx); + } else { + this->actionFunc = func_80BC4380; + this->dyna.actor.speedXZ = 20.0f; + func_80BC3980(this, globalCtx); + } + } else { + this->actionFunc = func_80BC457C; + } + this->unk_168 = 6; +} + +void BgF40Block_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgF40Block* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80BC41AC(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3D08(this, globalCtx, 1)) { + if (!Flags_GetSwitch(globalCtx, BGF40BLOCK_GET_SWITCHFLAG(&this->dyna.actor))) { + func_80BC4038(this); + this->actionFunc = func_80BC44F4; + } + } else { + this->actionFunc = func_80BC4344; + } +} + +void func_80BC4228(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3B00(this)) { + this->dyna.actor.speedXZ = 20.0f; + if (this->unk_160 < (this->path->count - 1)) { + this->unk_164 = this->unk_160 + 1; + } else { + this->actionFunc = func_80BC4530; + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_STOP_C); + } + } + + if (func_80BC3D08(this, globalCtx, 0)) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->actionFunc = func_80BC41AC; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_STOP_F); + return; + } + + switch (this->unk_168) { + case 0: + case 3: + func_800B9010(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_MOVE_X - SFX_FLAG); + break; + + case 1: + case 4: + func_800B9010(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_MOVE_Y - SFX_FLAG); + break; + + case 2: + case 5: + func_800B9010(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_MOVE_Z - SFX_FLAG); + break; + } +} + +void func_80BC4344(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3CA4(this)) { + this->actionFunc = func_80BC4228; + } +} + +void func_80BC4380(BgF40Block* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, BGF40BLOCK_GET_SWITCHFLAG(&this->dyna.actor))) { + this->actionFunc = func_80BC4344; + } +} + +void func_80BC43CC(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3D08(this, globalCtx, 1)) { + if (Flags_GetSwitch(globalCtx, BGF40BLOCK_GET_SWITCHFLAG(&this->dyna.actor))) { + func_80BC4038(this); + this->actionFunc = func_80BC4344; + } + } else { + this->actionFunc = func_80BC44F4; + } +} + +void func_80BC4448(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3B00(this)) { + this->dyna.actor.speedXZ = 40.0f; + if (this->unk_160 > 0) { + this->unk_164 = this->unk_160 - 1; + } else { + this->actionFunc = func_80BC4380; + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_STOP_C); + } + } + + if (func_80BC3D08(this, globalCtx, 0)) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->actionFunc = func_80BC43CC; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_STOP_F); + } +} + +void func_80BC44F4(BgF40Block* this, GlobalContext* globalCtx) { + if (func_80BC3CA4(this)) { + this->actionFunc = func_80BC4448; + } +} + +void func_80BC4530(BgF40Block* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, BGF40BLOCK_GET_SWITCHFLAG(&this->dyna.actor))) { + this->actionFunc = func_80BC44F4; + } +} + +void func_80BC457C(BgF40Block* this, GlobalContext* globalCtx) { +} + +void BgF40Block_Update(Actor* thisx, GlobalContext* globalCtx) { + BgF40Block* this = THIS; + + this->actionFunc(this, globalCtx); + + Math_Vec3f_Copy(&this->dyna.actor.focus.pos, &this->dyna.actor.world.pos); +} + +void BgF40Block_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, object_f40_obj_DL_0043D0); +} diff --git a/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.h b/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.h index 92b1d1e9e..cf9dfb03b 100644 --- a/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.h +++ b/src/overlays/actors/ovl_Bg_F40_Block/z_bg_f40_block.h @@ -7,9 +7,15 @@ struct BgF40Block; typedef void (*BgF40BlockActionFunc)(struct BgF40Block*, GlobalContext*); +#define BGF40BLOCK_GET_PATH(thisx) (((thisx)->params & 0x1FC) >> 2) +#define BGF40BLOCK_GET_SWITCHFLAG(thisx) (((thisx)->params & 0xFE00) >> 9) + typedef struct BgF40Block { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x28]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ Path* path; + /* 0x0160 */ s32 unk_160; + /* 0x0164 */ s32 unk_164; + /* 0x0168 */ s32 unk_168; /* 0x016C */ BgF40BlockActionFunc actionFunc; } BgF40Block; // size = 0x170 diff --git a/src/overlays/actors/ovl_Bg_F40_Flift/z_bg_f40_flift.c b/src/overlays/actors/ovl_Bg_F40_Flift/z_bg_f40_flift.c index e449bf6b4..7805a6e54 100644 --- a/src/overlays/actors/ovl_Bg_F40_Flift/z_bg_f40_flift.c +++ b/src/overlays/actors/ovl_Bg_F40_Flift/z_bg_f40_flift.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_f40_flift.c + * Overlay: ovl_Bg_F40_Flift + * Description: Stone Tower Temple - Grey Square Stone Elevator + */ + #include "z_bg_f40_flift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgF40Flift*)thisx) diff --git a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c index ec1cf0553..5278a4b73 100644 --- a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c +++ b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.c @@ -1,6 +1,13 @@ -#include "z_bg_f40_switch.h" +/* + * File: z_bg_f40_switch.c + * Overlay: ovl_Bg_F40_Switch + * Description: Stone Tower Switch + */ -#define FLAGS 0x00000010 +#include "z_bg_f40_switch.h" +#include "objects/object_f40_switch/object_f40_switch.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgF40Switch*)thisx) @@ -9,13 +16,13 @@ void BgF40Switch_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgF40Switch_Update(Actor* thisx, GlobalContext* globalCtx); void BgF40Switch_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BC4B20(BgF40Switch* this, GlobalContext* globalCtx); -void func_80BC4B94(BgF40Switch* this, GlobalContext* globalCtx); -void func_80BC4BB8(BgF40Switch* this, GlobalContext* globalCtx); -void func_80BC4C68(BgF40Switch* this, GlobalContext* globalCtx); -void func_80BC4D30(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_CheckAll(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_Unpress(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_IdlePressed(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_Press(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_WaitToPress(BgF40Switch* this, GlobalContext* globalCtx); +void BgF40Switch_IdleUnpressed(BgF40Switch* this, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_F40_Switch_InitVars = { ACTOR_BG_F40_SWITCH, ACTORCAT_SWITCH, @@ -28,37 +35,159 @@ const ActorInit Bg_F40_Switch_InitVars = { (ActorFunc)BgF40Switch_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BC4E04[] = { +s32 sBgF40SwitchGlobalsInitialized = false; +u32 sBgF40SwitchLastUpdateFrame; + +/* + * Updates all instances of this actor in the current room, unless it's already been called this frame. + */ +void BgF40Switch_CheckAll(BgF40Switch* this, GlobalContext* globalCtx) { + if (globalCtx->gameplayFrames != sBgF40SwitchLastUpdateFrame) { + u32 pressedSwitchFlags[4] = { 0 }; + u32 pad; + s32 switchFlag; + s32 isPressed; + Actor* actor; + BgF40Switch* actorAsSwitch; + u32 inCsMode = Player_InCsMode(&globalCtx->state); + + for (actor = globalCtx->actorCtx.actorLists[ACTORCAT_SWITCH].first; actor != NULL; actor = actor->next) { + if (actor->id == ACTOR_BG_F40_SWITCH && actor->room == this->dyna.actor.room && actor->update != NULL) { + actorAsSwitch = (BgF40Switch*)actor; + actorAsSwitch->wasPressed = actorAsSwitch->isPressed; + isPressed = DynaPolyActor_IsInSwitchPressedState(&actorAsSwitch->dyna); + if (actorAsSwitch->isPressed && actorAsSwitch->actionFunc == BgF40Switch_IdlePressed) { + // Switch is fully pressed - if there's nothing keeping it pressed, wait a short time before + // reverting to unpressed state. + if (isPressed || inCsMode) { + actorAsSwitch->switchReleaseDelay = 6; + } else { + if (actorAsSwitch->switchReleaseDelay > 0) { + actorAsSwitch->switchReleaseDelay--; + } else { + actorAsSwitch->isPressed = isPressed; + } + } + } else { + // No delay when pressing switch, or releasing from a not-fully-pressed state. + actorAsSwitch->isPressed = isPressed; + } + if (actorAsSwitch->isPressed) { + switchFlag = BGF40SWITCH_GET_SWITCHFLAG(&actorAsSwitch->dyna.actor); + if (switchFlag >= 0 && switchFlag < 0x80) { + pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] |= 1 << (switchFlag & 0x1F); + if (!actorAsSwitch->wasPressed && actorAsSwitch->actionFunc == BgF40Switch_IdleUnpressed && + !Flags_GetSwitch(globalCtx, switchFlag)) { + actorAsSwitch->isInitiator = true; + } + } + } + } + } + for (actor = globalCtx->actorCtx.actorLists[ACTORCAT_SWITCH].first; actor != NULL; actor = actor->next) { + if (actor->id == ACTOR_BG_F40_SWITCH && actor->room == this->dyna.actor.room && actor->update != 0) { + switchFlag = BGF40SWITCH_GET_SWITCHFLAG(actor); + if (switchFlag >= 0 && switchFlag < 0x80 && Flags_GetSwitch(globalCtx, switchFlag) && + !(pressedSwitchFlags[(switchFlag & ~0x1F) >> 5] & (1 << (switchFlag & 0x1F)))) { + Flags_UnsetSwitch(globalCtx, switchFlag); + } + } + } + sBgF40SwitchLastUpdateFrame = globalCtx->gameplayFrames; + } +} + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 123, ICHAIN_STOP), }; -#endif +void BgF40Switch_Init(Actor* thisx, GlobalContext* globalCtx) { + BgF40Switch* this = THIS; -extern InitChainEntry D_80BC4E04[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.scale.y = 0.165f; + this->actionFunc = BgF40Switch_IdleUnpressed; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 1.0f; + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_f40_switch_Colheader_000118); + if (!sBgF40SwitchGlobalsInitialized) { + sBgF40SwitchLastUpdateFrame = globalCtx->gameplayFrames; + sBgF40SwitchGlobalsInitialized = true; + } +} -extern UNK_TYPE D_06000118; -extern UNK_TYPE D_06000438; +void BgF40Switch_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgF40Switch* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC47B0.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/BgF40Switch_Init.s") +void BgF40Switch_Unpress(BgF40Switch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y += 0.0495f; + if (this->dyna.actor.scale.y >= 0.165f) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_SWITCH); + this->actionFunc = BgF40Switch_IdleUnpressed; + this->dyna.actor.scale.y = 0.165f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/BgF40Switch_Destroy.s") +void BgF40Switch_IdlePressed(BgF40Switch* this, GlobalContext* globalCtx) { + if (!this->isPressed) { + this->actionFunc = BgF40Switch_Unpress; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC4B20.s") +void BgF40Switch_Press(BgF40Switch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y -= 0.0495f; + if (this->dyna.actor.scale.y <= 0.0165f) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_IKANA_BLOCK_SWITCH); + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + if (this->isInitiator) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->isInitiator = false; + } + this->actionFunc = BgF40Switch_IdlePressed; + this->dyna.actor.scale.y = 0.0165f; + this->switchReleaseDelay = 6; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC4B94.s") +void BgF40Switch_WaitToPress(BgF40Switch* this, GlobalContext* globalCtx) { + if (!this->isInitiator || this->dyna.actor.cutscene == -1) { + this->actionFunc = BgF40Switch_Press; + if (this->isInitiator) { + Flags_SetSwitch(globalCtx, BGF40SWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } + } else if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->actionFunc = BgF40Switch_Press; + if (this->isInitiator) { + Flags_SetSwitch(globalCtx, BGF40SWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC4BB8.s") +void BgF40Switch_IdleUnpressed(BgF40Switch* this, GlobalContext* globalCtx) { + if (this->isPressed) { + this->actionFunc = BgF40Switch_WaitToPress; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC4C68.s") +void BgF40Switch_Update(Actor* thisx, GlobalContext* globalCtx) { + BgF40Switch* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/func_80BC4D30.s") + BgF40Switch_CheckAll(this, globalCtx); + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/BgF40Switch_Update.s") +void BgF40Switch_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgF40Switch* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_F40_Switch/BgF40Switch_Draw.s") + Gfx_DrawDListOpa(globalCtx, object_f40_switch_DL_000438); + Gfx_DrawDListOpa(globalCtx, object_f40_switch_DL_000390); +} diff --git a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.h b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.h index 8b4f2b679..8d4e64603 100644 --- a/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.h +++ b/src/overlays/actors/ovl_Bg_F40_Switch/z_bg_f40_switch.h @@ -5,11 +5,18 @@ struct BgF40Switch; +#define BGF40SWITCH_GET_SWITCHFLAG(thisx) (((thisx)->params & 0xFE00) >> 9) + typedef void (*BgF40SwitchActionFunc)(struct BgF40Switch*, GlobalContext*); typedef struct BgF40Switch { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x20]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ s16 switchReleaseDelay; // frames until a pressed switch becomes released if nothing is still pressing it + /* 0x015E */ s8 isPressed; // Logical state of the switch (pressed or unpressed). Animation state may lag behind this slightly. + /* 0x015F */ s8 wasPressed; // used as temporary during update function + // true if this switch is the one that initiated a state change; false if this switch is changing as a result of another switch tied to the same flag. + // this is a temporary flag related to something currently happening, not a permanent property of the switch. + /* 0x0160 */ s8 isInitiator; /* 0x0164 */ BgF40SwitchActionFunc actionFunc; } BgF40Switch; // size = 0x168 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 48e3ef512..9d84f191c 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,6 +1,12 @@ +/* + * File: z_bg_f40_swlift.c + * Overlay: ovl_Bg_F40_Swlift + * Description: Unused Stone Tower vertically-oscillating platform + */ + #include "z_bg_f40_swlift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgF40Swlift*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.c b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.c index ac802e3bf..1f959e827 100644 --- a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.c +++ b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_fire_wall.c + * Overlay: ovl_Bg_Fire_Wall + * Description: Wall of fire spawned by ovl_Bg_Spout_Fire + */ + #include "z_bg_fire_wall.h" #define FLAGS 0x00000000 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_Kaiten/z_bg_fu_kaiten.c b/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.c index d85ace2f6..307d0fd0a 100644 --- a/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.c +++ b/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.c @@ -1,6 +1,13 @@ -#include "z_bg_fu_kaiten.h" +/* + * File: z_bg_fu_kaiten.c + * Overlay: ovl_Bg_Fu_Kaiten + * Description: Honey & Darling's Shop - Rotating Platform + */ -#define FLAGS 0x00000030 +#include "z_bg_fu_kaiten.h" +#include "objects/object_fu_kaiten/object_fu_kaiten.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgFuKaiten*)thisx) @@ -21,56 +28,58 @@ const ActorInit Bg_Fu_Kaiten_InitVars = { (ActorFunc)BgFuKaiten_Draw, }; -extern Gfx D_060005D0[]; -extern CollisionHeader D_06002D30; - void BgFuKaiten_Init(Actor* thisx, GlobalContext* globalCtx) { - UNK_TYPE pad0; - UNK_TYPE pad1; - CollisionHeader* header = 0; + s32 pad; + BgFuKaiten* this = THIS; + CollisionHeader* header = NULL; Actor_SetScale(thisx, 1.0); - BcCheck3_BgActorInit(&THIS->bg, 3); - BgCheck_RelocateMeshHeader(&D_06002D30, &header); - THIS->bg.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &THIS->bg, header); + DynaPolyActor_Init(&this->dyna, 3); + CollisionHeader_GetVirtual(&object_fu_kaiten_Colheader_002D30, &header); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, header); - THIS->bouceHeight = 0.0; - THIS->rotationSpeed = 0; - THIS->bounceSpeed = 0; - THIS->bounce = 0; + this->bounceHeight = 0.0; + this->rotationSpeed = 0; + this->bounceSpeed = 0; + this->bounce = 0; } void BgFuKaiten_Destroy(Actor* thisx, GlobalContext* globalCtx) { - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, THIS->bg.bgId); + BgFuKaiten* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgFuKaiten_UpdateRotation(BgFuKaiten* this) { f32 f0; - this->bg.actor.shape.rot.y += this->rotationSpeed; + + this->dyna.actor.shape.rot.y += this->rotationSpeed; if (this->rotationSpeed > 0) { - f0 = this->rotationSpeed * .002f; - func_8019FAD8(&this->bg.actor.projectedPos, 8310, f0); + f0 = this->rotationSpeed * 0.002f; + func_8019FAD8(&this->dyna.actor.projectedPos, NA_SE_EV_WOOD_GEAR - SFX_FLAG, f0); } } void BgFuKaiten_UpdateHeight(BgFuKaiten* this) { this->bounce += this->bounceSpeed; - this->bg.actor.world.pos.y = this->bg.actor.home.pos.y + this->elevation + this->bouceHeight; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->elevation + this->bounceHeight; - this->bg.actor.world.pos.y -= this->bouceHeight * Math_CosS(this->bounce); + this->dyna.actor.world.pos.y -= this->bounceHeight * Math_CosS(this->bounce); } void BgFuKaiten_Update(Actor* thisx, GlobalContext* globalCtx) { - BgFuKaiten_UpdateRotation(THIS); - BgFuKaiten_UpdateHeight(THIS); + BgFuKaiten* this = THIS; + + BgFuKaiten_UpdateRotation(this); + BgFuKaiten_UpdateHeight(this); } void BgFuKaiten_Draw(Actor* thisx, GlobalContext* globalCtx) { - GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; - UNK_TYPE pad; + OPEN_DISPS(globalCtx->state.gfxCtx); - func_8012C28C(gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); - gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gfxCtx->polyOpa.p++, D_060005D0); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_fu_kaiten_DL_0005D0); + CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.h b/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.h index 94b582bb3..6937fbf53 100644 --- a/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.h +++ b/src/overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.h @@ -6,14 +6,13 @@ struct BgFuKaiten; typedef struct BgFuKaiten { - /* 0x000 */ DynaPolyActor bg; + /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ UNK_TYPE1 pad15C[0x4]; /* 0x160 */ f32 elevation; - /* 0x164 */ f32 bouceHeight; + /* 0x164 */ f32 bounceHeight; /* 0x168 */ s16 rotationSpeed; /* 0x16A */ s16 bounceSpeed; /* 0x16C */ s16 bounce; - /* 0x16E */ UNK_TYPE1 pad16E[0x2]; } BgFuKaiten; // size = 0x170 extern const ActorInit Bg_Fu_Kaiten_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 27c04a7dd..a8d54222d 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,6 +1,12 @@ +/* + * File: z_bg_fu_mizu.c + * Overlay: ovl_Bg_Fu_Mizu + * Description: Water in Honey and Darling's Second Day game + */ + #include "z_bg_fu_mizu.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgFuMizu*)thisx) 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 e38fc77cf..d064a3cb4 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 @@ -1,6 +1,13 @@ -#include "z_bg_goron_oyu.h" +/* + * File: z_bg_goron_oyu.c + * Overlay: ovl_Bg_Goron_Oyu + * Description: Goron Hot Spring Water + */ -#define FLAGS 0x00000030 +#include "z_bg_goron_oyu.h" +#include "objects/object_oyu/object_oyu.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgGoronOyu*)thisx) @@ -9,7 +16,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, @@ -22,31 +35,158 @@ const ActorInit Bg_Goron_Oyu_InitVars = { (ActorFunc)BgGoronOyu_Draw, }; -#endif +void func_80B40080(BgGoronOyu* this) { + this->unk_17E = 1; + this->actionFunc = func_80B400C8; +} -extern UNK_TYPE D_06000968; -extern UNK_TYPE D_06000988; +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_80B40080.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_80B4009C.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_80B400C8.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_80B40100.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_80B40160.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_80B401F8.s") + Audio_PlaySfxAtPos(&D_80B40780, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40308.s") +void func_80B401F8(BgGoronOyu* this, GlobalContext* globalCtx) { + Player* player; + Vec3f dist; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40394.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_Init.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_Destroy.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) { + Actor_PickUp(&this->dyna.actor, globalCtx, GI_MAX, this->dyna.actor.xzDistToPlayer, + fabsf(this->dyna.actor.playerHeightRel)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Update.s") +void BgGoronOyu_UpdateWaterBoxInfo(BgGoronOyu* this, GlobalContext* globalCtx) { + WaterBox* waterBox; + f32 ySurface; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Draw.s") + 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(&object_oyu_Colheader_000988, &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(object_oyu_Matanimheader_000968)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &object_oyu_DL_000158); + gSPDisplayList(POLY_XLU_DISP++, &object_oyu_DL_000080); + 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_Haka_Bombwall/z_bg_haka_bombwall.c b/src/overlays/actors/ovl_Bg_Haka_Bombwall/z_bg_haka_bombwall.c index 02d54c529..3c535326e 100644 --- a/src/overlays/actors/ovl_Bg_Haka_Bombwall/z_bg_haka_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Haka_Bombwall/z_bg_haka_bombwall.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_haka_bombwall.c + * Overlay: ovl_Bg_Haka_Bombwall + * Description: Beneath the Grave - Bombable Wall + */ + #include "z_bg_haka_bombwall.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Haka_Curtain/z_bg_haka_curtain.c b/src/overlays/actors/ovl_Bg_Haka_Curtain/z_bg_haka_curtain.c index 1274b0bdc..576388d5c 100644 --- a/src/overlays/actors/ovl_Bg_Haka_Curtain/z_bg_haka_curtain.c +++ b/src/overlays/actors/ovl_Bg_Haka_Curtain/z_bg_haka_curtain.c @@ -1,6 +1,13 @@ -#include "z_bg_haka_curtain.h" +/* + * File: z_bg_haka_curtain.c + * Overlay: ovl_Bg_Haka_Curtain + * Description: Curtain That Lifts to Reveal Flat's Tomb + */ -#define FLAGS 0x00000010 +#include "z_bg_haka_curtain.h" +#include "objects/object_haka_obj/object_haka_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgHakaCurtain*)thisx) @@ -38,16 +45,13 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_06001588; -extern Gfx D_06001410[]; - void BgHakaCurtain_Init(Actor* thisx, GlobalContext* globalCtx) { BgHakaCurtain* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06001588); - if (Actor_GetRoomCleared(globalCtx, this->dyna.actor.room)) { + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_haka_obj_Colheader_001588); + if (Flags_GetClear(globalCtx, this->dyna.actor.room)) { func_80B6DE80(this); return; } @@ -57,7 +61,7 @@ void BgHakaCurtain_Init(Actor* thisx, GlobalContext* globalCtx) { void BgHakaCurtain_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgHakaCurtain* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void func_80B6DC98(BgHakaCurtain* this) { @@ -65,7 +69,7 @@ void func_80B6DC98(BgHakaCurtain* this) { } void func_80B6DCAC(BgHakaCurtain* this, GlobalContext* globalCtx) { - if (Actor_GetRoomCleared(globalCtx, this->dyna.actor.room)) { + if (Flags_GetClear(globalCtx, this->dyna.actor.room)) { func_80B6DCEC(this); } } @@ -121,9 +125,9 @@ void BgHakaCurtain_Update(Actor* thisx, GlobalContext* globalCtx) { BgHakaCurtain* this = THIS; CsCmdActorAction* actorAction; - if (func_800EE29C(globalCtx, 0x1D5)) { - actorAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1D5)]; - if (actorAction->startFrame == globalCtx->csCtx.frames && actorAction->unk0 == 2) { + if (Cutscene_CheckActorAction(globalCtx, 469)) { + actorAction = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 469)]; + if (actorAction->startFrame == globalCtx->csCtx.frames && actorAction->action == 2) { func_80B6DD80(this); } } @@ -131,5 +135,5 @@ void BgHakaCurtain_Update(Actor* thisx, GlobalContext* globalCtx) { } void BgHakaCurtain_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06001410); + Gfx_DrawDListOpa(globalCtx, object_haka_obj_DL_001410); } diff --git a/src/overlays/actors/ovl_Bg_Haka_Tomb/z_bg_haka_tomb.c b/src/overlays/actors/ovl_Bg_Haka_Tomb/z_bg_haka_tomb.c index 34ad8fb1f..6985878fe 100644 --- a/src/overlays/actors/ovl_Bg_Haka_Tomb/z_bg_haka_tomb.c +++ b/src/overlays/actors/ovl_Bg_Haka_Tomb/z_bg_haka_tomb.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_haka_tomb.c + * Overlay: ovl_Bg_Haka_Tomb + * Description: Flat's Tomb + */ + #include "z_bg_haka_tomb.h" +#include "objects/object_haka_obj/object_haka_obj.h" #define FLAGS 0x00000000 @@ -16,9 +23,6 @@ void func_80BD6768(BgHakaTomb* this, GlobalContext* globalCtx); void BgHakaTomb_SetupDoNothing(BgHakaTomb* this); void BgHakaTomb_DoNothing(BgHakaTomb* this, GlobalContext* globalCtx); -extern CollisionHeader D_06000EE8[]; -extern Gfx D_060007B0[]; - const ActorInit Bg_Haka_Tomb_InitVars = { ACTOR_BG_HAKA_TOMB, ACTORCAT_BG, @@ -41,16 +45,16 @@ void BgHakaTomb_Init(Actor* thisx, GlobalContext* globalCtx) { BgHakaTomb* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, D_06000EE8); - func_8013E3B8(&this->dyna.actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_haka_obj_Colheader_000EE8); + SubS_FillCutscenesList(&this->dyna.actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); func_80BD6624(this); } void BgHakaTomb_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgHakaTomb* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void func_80BD6624(BgHakaTomb* this) { @@ -78,17 +82,16 @@ s32 func_80BD6638(s16* arg0, s16* arg1, s32 arg2) { void func_80BD66AC(BgHakaTomb* this, GlobalContext* globalCtx) { s16 temp; - if (Actor_GetRoomCleared(globalCtx, this->dyna.actor.room)) { - this->dyna.actor.flags |= 9; + if (Flags_GetClear(globalCtx, this->dyna.actor.room)) { + this->dyna.actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); } - if (!func_80BD6638(&temp, this->cutscenes, 1) && (temp < 0) && - Actor_GetRoomCleared(globalCtx, this->dyna.actor.room)) { - this->dyna.actor.flags |= 1; + if (!func_80BD6638(&temp, this->cutscenes, 1) && (temp < 0) && Flags_GetClear(globalCtx, this->dyna.actor.room)) { + this->dyna.actor.flags |= ACTOR_FLAG_1; if (this->dyna.actor.isTargeted) { func_80BD6754(this); } } else { - this->dyna.actor.flags &= ~1; + this->dyna.actor.flags &= ~ACTOR_FLAG_1; } } @@ -97,7 +100,7 @@ void func_80BD6754(BgHakaTomb* this) { } void func_80BD6768(BgHakaTomb* this, GlobalContext* globalCtx) { - if (func_8013E2D4(&this->dyna.actor, this->cutscenes[0], -1, 0)) { + if (SubS_StartActorCutscene(&this->dyna.actor, this->cutscenes[0], -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { BgHakaTomb_SetupDoNothing(this); } } @@ -115,13 +118,13 @@ void BgHakaTomb_Update(Actor* thisx, GlobalContext* globalCtx) { Vec3f vec; this->actionFunc(this, globalCtx); - Matrix_RotateY(this->dyna.actor.world.rot.y, MTXMODE_NEW); - Matrix_InsertXRotation_s(this->dyna.actor.world.rot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->dyna.actor.world.rot.z, MTXMODE_APPLY); - Matrix_MultiplyVector3fByState(&D_80BD68A4, &vec); + Matrix_RotateYS(this->dyna.actor.world.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.world.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.world.rot.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_80BD68A4, &vec); Math_Vec3f_Sum(&this->dyna.actor.world.pos, &vec, &this->dyna.actor.focus.pos); } void BgHakaTomb_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_060007B0); + Gfx_DrawDListOpa(globalCtx, object_haka_obj_DL_0007B0); } diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c index c211e16c2..20d68e7a4 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_hakugin_bombwall.c + * Overlay: ovl_Bg_Hakugin_Bombwall + * Description: Snowhead Temple - Bombable Wall + */ + #include "z_bg_hakugin_bombwall.h" +#include "objects/object_hakugin_obj/object_hakugin_obj.h" #define FLAGS 0x00000000 @@ -9,7 +16,16 @@ void BgHakuginBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgHakuginBombwall_Update(Actor* thisx, GlobalContext* globalCtx); void BgHakuginBombwall_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80ABBFC0(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC2E0(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC58C(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABC7FC(BgHakuginBombwall* this, GlobalContext* globalCtx); +s32 func_80ABCB5C(Actor* thisx, GlobalContext* globalCtx); +s32 func_80ABCC00(Actor* thisx, GlobalContext* globalCtx); +void func_80ABCCE4(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABCD98(BgHakuginBombwall* this, GlobalContext* globalCtx); +void func_80ABCE60(BgHakuginBombwall* this, GlobalContext* globalCtx); + const ActorInit Bg_Hakugin_Bombwall_InitVars = { ACTOR_BG_HAKUGIN_BOMBWALL, ACTORCAT_BG, @@ -22,48 +38,399 @@ const ActorInit Bg_Hakugin_Bombwall_InitVars = { (ActorFunc)BgHakuginBombwall_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ABCF80 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000008, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000008, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 80, 80, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80ABD040[] = { +Color_RGBA8 D_80ABCFAC = { 210, 210, 210, 255 }; +Color_RGBA8 D_80ABCFB0 = { 140, 140, 140, 255 }; + +Vec3f D_80ABCFB4 = { 0.0f, 0.33f, 0.0f }; + +typedef struct { + /* 0x00 */ CollisionHeader* unk_00; + /* 0x04 */ Gfx* unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ s16 unk_14; + /* 0x16 */ s16 unk_16; + /* 0x18 */ s32 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ BgHakuginBombwallUnkFunc unk_20; + /* 0x24 */ BgHakuginBombwallUnkFunc2 unk_24; + /* 0x28 */ BgHakuginBombwallUnkFunc2 unk_28; + /* 0x2C */ s32 unk_2C; +} BgHakuginBombwallStruct; // size = 0x30 + +BgHakuginBombwallStruct D_80ABCFC0[] = { + { + &object_hakugin_obj_Colheader_009768, + object_hakugin_obj_DL_009658, + 70.0f, + 600.0f, + 400.0f, + 80, + 80, + 0x8, + 4225.0f, + func_80ABCB5C, + func_80ABBFC0, + func_80ABC58C, + 6, + }, + { + &object_hakugin_obj_Colheader_009AF0, + object_hakugin_obj_DL_0099A8, + 10.0f, + 600.0f, + 300.0f, + 50, + 20, + 0x408, + 4225.0f, + func_80ABCC00, + func_80ABC2E0, + func_80ABC7FC, + 18, + }, +}; + +s32 D_80ABD020[] = { -73, -40, -8, 24, 57 }; + +Vec3f D_80ABD034 = { 0.0f, 3.0f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80ABBFC0(BgHakuginBombwall* this, GlobalContext* globalCtx) { + f32 temp; + Vec3f spF0; + Vec3f spE4; + Vec3f spD8; + Vec3f spCC; + s32 pad; + s16 phi_s1; + s16 phi_s0; + s32 i; + s32 j; -extern ColliderCylinderInit D_80ABCF80; -extern InitChainEntry D_80ABD040[]; + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); -extern UNK_TYPE D_06009830; + for (i = 0; i < 6; i++) { + temp = (i + 1) * (80.0f / 3.0f); + for (j = 0; j < ARRAY_COUNT(D_80ABD020); j++) { + spD8.x = D_80ABD020[j] + (s32)((u32)Rand_Next() >> 0x1C); + spD8.y = ((Rand_ZeroOne() - 0.5f) * 15.0f) + temp; + spD8.z = (Rand_ZeroOne() * 20.0f) - 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABBFC0.s") + spCC.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (spD8.x * (7.0f / 90.0f)); + spCC.y = (Rand_ZeroOne() * 7.0f) - 2.0f; + spCC.z = spD8.z * 0.3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC2E0.s") + Matrix_MultVec3f(&spD8, &spF0); + Matrix_MultVec3f(&spCC, &spE4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC58C.s") + spF0.x += this->dyna.actor.world.pos.x; + spF0.y += this->dyna.actor.world.pos.y; + spF0.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABC7FC.s") + if ((Rand_Next() % 4) == 0) { + phi_s0 = 32; + } else { + phi_s0 = 64; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Init.s") + if (Rand_Next() > 0) { + phi_s0 |= 1; + phi_s1 = 1; + func_800B0E48(globalCtx, &spF0, &gZeroVec3f, &D_80ABCFB4, &D_80ABCFAC, &D_80ABCFB0, + ((u32)Rand_Next() >> 0x1B) + 70, ((u32)Rand_Next() >> 0x1A) + 60); + } else { + phi_s1 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Destroy.s") + EffectSsKakera_Spawn(globalCtx, &spF0, &spE4, &spF0, -550, phi_s0, 30, 0, 0, + (s32)(Rand_ZeroOne() * 22.0f) + 5, phi_s1, 0, 50, -1, OBJECT_HAKUGIN_OBJ, + object_hakugin_obj_DL_009830); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCB5C.s") +void func_80ABC2E0(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + s16 phi_s2; + s16 phi_v0; + s16 phi_v1; + s16 phi_t0; + s16 temp_s1; + Vec3f spC8; + Vec3f spBC; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCC00.s") + for (i = 0, phi_s2 = 0; i < 25; i++, phi_s2 += 0x4E20) { + temp_f20 = (25 - i) * 2.4f; + temp_f22 = Math_SinS(phi_s2) * temp_f20; + temp_f24 = Math_CosS(phi_s2) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCCE4.s") + spC8.x = this->dyna.actor.world.pos.x + temp_f22; + spC8.y = this->dyna.actor.world.pos.y; + spC8.z = this->dyna.actor.world.pos.z + temp_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCD98.s") + spBC.x = ((Rand_ZeroOne() - 0.5f) * 10.0f) + (temp_f22 * 0.13333334f); + spBC.y = (Rand_ZeroOne() * 17.0f) + 7.0f; + spBC.z = ((Rand_ZeroOne() - 0.5f) * 10.0f) + (temp_f24 * 0.13333334f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/func_80ABCE60.s") + temp_s1 = (Rand_Next() & 3) + (i >> 2) + 4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Update.s") + if ((Rand_Next() % 4) == 0) { + phi_v0 = 32; + } else { + phi_v0 = 64; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Bombwall/BgHakuginBombwall_Draw.s") + if (temp_s1 >= 8) { + phi_v0 |= 1; + phi_v1 = 1; + phi_t0 = -550; + } else { + phi_v1 = 0; + phi_t0 = -400; + } + + EffectSsKakera_Spawn(globalCtx, &spC8, &spBC, &spC8, phi_t0, phi_v0, 30, 0, 0, temp_s1, phi_v1, 0, 50, -1, + OBJECT_HAKUGIN_OBJ, object_hakugin_obj_DL_009830); + + if ((i & 1) == 0) { + func_800B0E48(globalCtx, &spC8, &D_80ABD034, &D_80ABCFB4, &D_80ABCFAC, &D_80ABCFB0, + ((u32)Rand_Next() >> 0x1B) + 60, ((u32)Rand_Next() >> 0x1A) + 50); + } + } +} + +void func_80ABC58C(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f spD8; + Vec3f spCC; + Vec3f spC0; + Vec3f spB4; + Vec3f spA8; + Vec3f sp9C; + s32 i; + s16 phi_s1; + f32 temp_f20; + f32 temp_f22; + + spA8.y = 0.0f; + spB4.y = 0.3f; + + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + + for (i = 0, phi_s1 = 0; i < 21; i++, phi_s1 += 0x618) { + temp_f20 = Math_SinS(phi_s1); + temp_f22 = Math_CosS(phi_s1); + + sp9C.x = (i - 10) * 9.0f; + sp9C.y = (Rand_ZeroOne() * 40.0f) + 15.0f; + sp9C.z = temp_f20 * 10.0f; + + spA8.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f22 * -12.0f); + spA8.z = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f20 * 16.0f); + + spB4.x = spA8.x * -0.09f; + spB4.z = spA8.z * -0.09f; + + Matrix_MultVec3f(&sp9C, &spC0); + Matrix_MultVec3f(&spA8, &spCC); + Matrix_MultVec3f(&spB4, &spD8); + + spC0.x += this->dyna.actor.world.pos.x; + spC0.y += this->dyna.actor.world.pos.y; + spC0.z += this->dyna.actor.world.pos.z; + + func_800B0E48(globalCtx, &spC0, &spCC, &spD8, &D_80ABCFAC, &D_80ABCFB0, ((u32)Rand_Next() >> 0x1A) + 60, + ((u32)Rand_Next() >> 0x1B) + 60); + } +} + +void func_80ABC7FC(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s16 phi_s0; + s32 i; + + spAC.y = 0.0f; + spB8.y = 0.3f; + + for (i = 0, phi_s0 = 0; i < 20; i++, phi_s0 += 0xCCC) { + temp_f20 = Math_SinS(phi_s0); + temp_f22 = Math_CosS(phi_s0); + temp_f24 = Rand_ZeroOne() * 60.0f; + + spA0.x = (temp_f22 * temp_f24) + this->dyna.actor.world.pos.x; + spA0.y = (Rand_ZeroOne() * 20.0f) + this->dyna.actor.world.pos.y; + spA0.z = (temp_f20 * temp_f24) + this->dyna.actor.world.pos.z; + + spAC.x = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f20 * 15.0f); + spAC.z = ((Rand_ZeroOne() - 0.5f) * 7.0f) + (temp_f22 * 15.0f); + + spB8.x = spAC.x * -0.095f; + spB8.z = spAC.z * -0.095f; + + func_800B0E48(globalCtx, &spA0, &spAC, &spB8, &D_80ABCFAC, &D_80ABCFB0, ((u32)Rand_Next() >> 0x1A) + 60, + ((u32)Rand_Next() >> 0x1B) + 60); + } +} + +void BgHakuginBombwall_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgHakuginBombwall* this = THIS; + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + Collider_InitCylinder(globalCtx, &this->collider); + + if (Flags_GetSwitch(globalCtx, BGHAKUGIN_BOMBWALL_SWITCHFLAG(&this->dyna.actor))) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, ptr->unk_00); + + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + this->collider.dim.radius = ptr->unk_14; + this->collider.dim.height = ptr->unk_16; + this->collider.info.bumper.dmgFlags = ptr->unk_18; + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + + Actor_SetFocus(&this->dyna.actor, ptr->unk_08); + this->dyna.actor.uncullZoneScale = ptr->unk_0C; + this->dyna.actor.uncullZoneDownward = ptr->unk_10; + this->actionFunc = func_80ABCCE4; +} + +void BgHakuginBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +s32 func_80ABCB5C(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + s32 pad; + + if (this->collider.base.acFlags & AC_HIT) { + if (this->collider.base.ac != NULL) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < + D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)].unk_1C) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 60, NA_SE_EV_WALL_BROKEN); + return true; + } + } + } + return false; +} + +s32 func_80ABCC00(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + s32 pad; + + if (this->collider.base.acFlags & AC_HIT) { + if (this->collider.info.acHitInfo->toucher.dmgFlags & 8) { + if (this->collider.base.ac != NULL) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < + D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)].unk_1C) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 50, + NA_SE_EV_WALL_BROKEN); + return true; + } + } + } else if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + label:; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 50, NA_SE_EV_WALL_BROKEN); + return true; + } + } + return false; +} + +void func_80ABCCE4(BgHakuginBombwall* this, GlobalContext* globalCtx) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + if (ptr->unk_20(&this->dyna.actor, globalCtx)) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + this->actionFunc = func_80ABCD98; + } else { + this->collider.base.acFlags &= ~AC_HIT; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80ABCD98(BgHakuginBombwall* this, GlobalContext* globalCtx) { + s32 pad; + + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + ptr->unk_24(this, globalCtx); + this->dyna.actor.draw = NULL; + this->unk_1AC = 20; + Flags_SetSwitch(globalCtx, BGHAKUGIN_BOMBWALL_SWITCHFLAG(&this->dyna.actor)); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->actionFunc = func_80ABCE60; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80ABCE60(BgHakuginBombwall* this, GlobalContext* globalCtx) { + BgHakuginBombwallStruct* ptr = &D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(&this->dyna.actor)]; + + this->unk_1AC--; + if (this->unk_1AC <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_MarkForDeath(&this->dyna.actor); + } else if (this->unk_1AC == ptr->unk_2C) { + ptr->unk_28(this, globalCtx); + } +} + +void BgHakuginBombwall_Update(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginBombwall* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgHakuginBombwall_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, D_80ABCFC0[BGHAKUGIN_BOMBWALL_100(thisx)].unk_04); +} diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h index 8522fd15c..869741214 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h +++ b/src/overlays/actors/ovl_Bg_Hakugin_Bombwall/z_bg_hakugin_bombwall.h @@ -6,12 +6,17 @@ struct BgHakuginBombwall; typedef void (*BgHakuginBombwallActionFunc)(struct BgHakuginBombwall*, GlobalContext*); +typedef s32 (*BgHakuginBombwallUnkFunc)(Actor*, GlobalContext*); +typedef void (*BgHakuginBombwallUnkFunc2)(struct BgHakuginBombwall*, GlobalContext*); + +#define BGHAKUGIN_BOMBWALL_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) +#define BGHAKUGIN_BOMBWALL_100(thisx) (((thisx)->params >> 8) & 1) typedef struct BgHakuginBombwall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; - /* 0x01A8 */ BgHakuginBombwallActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0x4]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ BgHakuginBombwallActionFunc actionFunc; + /* 0x1AC */ s32 unk_1AC; } BgHakuginBombwall; // size = 0x1B0 extern const ActorInit Bg_Hakugin_Bombwall_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Elvpole/z_bg_hakugin_elvpole.c b/src/overlays/actors/ovl_Bg_Hakugin_Elvpole/z_bg_hakugin_elvpole.c index 5b5637090..b61f66bb6 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Elvpole/z_bg_hakugin_elvpole.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Elvpole/z_bg_hakugin_elvpole.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_hakugin_elvpole.c + * Overlay: ovl_Bg_Hakugin_Elvpole + * Description: Raisable pillar in Snowhead Temple Map room + */ + #include "z_bg_hakugin_elvpole.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgHakuginElvpole*)thisx) 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 453bd919c..a7f20b7b4 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 @@ -4,9 +4,12 @@ * Description: Snowhead Temple Central Pillar */ +#include "prevent_bss_reordering.h" #include "z_bg_hakugin_post.h" +#include "objects/object_hakugin_obj/object_hakugin_obj.h" +#include "prevent_bss_reordering.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgHakuginPost*)thisx) @@ -32,13 +35,6 @@ void func_80A9D3E4(BgHakuginPost* this); void func_80A9D434(BgHakuginPost* this, GlobalContext* globalCtx); void func_80A9D61C(Actor* thisx, GlobalContext* globalCtx); -extern Gfx D_0600C1A8[]; -extern Gfx D_0600C568[]; -extern Gfx D_0600CA38[]; -extern Gfx D_0600CEC8[]; -extern Gfx D_0600D098[]; -extern CollisionHeader D_0600D3B0; - BgHakuginPostColliders D_80A9DDC0; BgHakuginPostUnkStruct D_80A9E028; @@ -93,7 +89,7 @@ static InitChainEntry sInitChain[] = { }; void func_80A9ACD0(BgHakuginPostUnkStruct* arg0) { - bzero((void*)arg0, sizeof(BgHakuginPostUnkStruct)); + bzero(arg0, sizeof(BgHakuginPostUnkStruct)); } void func_80A9ACF0(void) { @@ -187,7 +183,7 @@ void func_80A9B160(BgHakuginPostUnkStruct* unkStruct, GlobalContext* globalCtx) unkStruct->unk_0000[i].unk_24 = 0.0f; unkStruct->unk_0000[i].unk_34 = 1; if (D_80A9D880[unkStruct->unk_0000[i].unk_00].unk_04 != 0) { - Actor_UnsetSwitchFlag(globalCtx, unkStruct->unk_0000[i].unk_2E); + Flags_UnsetSwitch(globalCtx, unkStruct->unk_0000[i].unk_2E); } } } @@ -234,7 +230,7 @@ BgHakuginPostUnkStruct1* func_80A9B32C(BgHakuginPostUnkStruct* unkStruct, BgHaku } void func_80A9B384(Vec3f* arg0) { - MtxF* matrix = Matrix_GetCurrentState(); + MtxF* matrix = Matrix_GetCurrent(); matrix->mf[3][0] = arg0->x; matrix->mf[3][1] = arg0->y; @@ -261,7 +257,7 @@ void func_80A9B3BC(BgHakuginPost* this, GlobalContext* globalCtx) { } if (!(sp20 | sp1C)) { - Actor_SetSwitchFlag(globalCtx, sp28); + Flags_SetSwitch(globalCtx, sp28); this->unk_170 = true; } else { this->unk_170 = sp20; @@ -290,9 +286,9 @@ void func_80A9B46C(BgHakuginPost* this, GlobalContext* globalCtx) { } if (!this->unk_170 && (sp28 == 1)) { - Actor_UnsetSwitchFlag(globalCtx, sp2C); + Flags_UnsetSwitch(globalCtx, sp2C); } else if (!this->unk_174 && (sp24 == 1)) { - Actor_UnsetSwitchFlag(globalCtx, sp30); + Flags_UnsetSwitch(globalCtx, sp30); } this->unk_170 = sp28; @@ -362,7 +358,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); } @@ -523,7 +519,7 @@ void func_80A9C058(BgHakuginPost* this, GlobalContext* globalCtx, BgHakuginPostU sp44.x = this->dyna.actor.home.pos.x + unkStruct1->unk_14.x; sp44.y = this->unk_16C + unkStruct1->unk_14.y; sp44.z = this->dyna.actor.home.pos.z + unkStruct1->unk_14.z; - func_8013ECE0(Math3D_DistanceSquared(&sp44, &GET_PLAYER(globalCtx)->actor.world.pos), 255, 20, 150); + func_8013ECE0(Math3D_Vec3fDistSq(&sp44, &GET_PLAYER(globalCtx)->actor.world.pos), 255, 20, 150); quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); Quake_SetSpeed(quake, 20000); Quake_SetQuakeValues(quake, 7, 0, 0, 0); @@ -682,9 +678,9 @@ void func_80A9C854(BgHakuginPost* this, GlobalContext* globalCtx) { } if (sp38) { - Actor_SetSwitchFlag(globalCtx, this->dyna.actor.home.rot.x & 0x7F); + Flags_SetSwitch(globalCtx, this->dyna.actor.home.rot.x & 0x7F); } else { - Actor_UnsetSwitchFlag(globalCtx, this->dyna.actor.home.rot.x & 0x7F); + Flags_UnsetSwitch(globalCtx, this->dyna.actor.home.rot.x & 0x7F); } } @@ -704,8 +700,8 @@ void BgHakuginPost_Init(Actor* thisx, GlobalContext* globalCtx) { this->dyna.actor.world.rot.z = 0; this->dyna.actor.shape.rot.x = 0; this->dyna.actor.shape.rot.z = 0; - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_0600D3B0); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_hakugin_obj_Colheader_00D3B0); func_80A9B3BC(this, globalCtx); func_80A9CA94(this); } else { @@ -718,7 +714,7 @@ void BgHakuginPost_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgHakuginPost* this = THIS; if (BGHAKUGINPOST_GET_7(&this->dyna.actor) == 7) { - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); func_80A9AE3C(this, globalCtx); } } @@ -840,9 +836,9 @@ void func_80A9CE1C(BgHakuginPost* this, GlobalContext* globalCtx) { temp = (s16)(this->dyna.actor.yawTowardsPlayer + 0x58F0); D_80A9E028.unk_0000[i].unk_28 = ((s16)(player->actor.shape.rot.y - temp) / 3) + temp; D_80A9E028.unk_0000[i].unk_34 = 2; - func_800B8E58(&player->actor, NA_SE_IT_HAMMER_HIT); + func_800B8E58(player, NA_SE_IT_HAMMER_HIT); func_8019F128(NA_SE_EV_SLIDE_DOOR_OPEN); - Actor_SetSwitchFlag(globalCtx, D_80A9E028.unk_0000[i].unk_2E); + Flags_SetSwitch(globalCtx, D_80A9E028.unk_0000[i].unk_2E); this->unk_178 = 20; func_80A9D2C4(this, func_80A9CE00, D_80A9E028.unk_0000[i].unk_14.y + 50.0f, D_80A9E028.unk_0000[i].unk_2A, D_80A9E028.unk_0000[i].unk_2C); @@ -996,13 +992,14 @@ void BgHakuginPost_Update(Actor* thisx, GlobalContext* globalCtx) { void func_80A9D61C(Actor* thisx, GlobalContext* globalCtx) { static Gfx* D_80A9D900[] = { - D_0600C1A8, D_0600C568, NULL, NULL, D_0600CA38, D_0600CEC8, NULL, + object_hakugin_obj_DL_00C1A8, object_hakugin_obj_DL_00C568, NULL, NULL, + object_hakugin_obj_DL_00CA38, object_hakugin_obj_DL_00CEC8, NULL, }; static Gfx* D_80A9D91C[] = { - D_0600D098, - D_0600D098, - D_0600D098, - D_0600D098, + object_hakugin_obj_DL_00D098, + object_hakugin_obj_DL_00D098, + object_hakugin_obj_DL_00D098, + object_hakugin_obj_DL_00D098, }; BgHakuginPost* this = THIS; BgHakuginPostUnkStruct1* unkStruct1; @@ -1013,8 +1010,8 @@ void func_80A9D61C(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, - this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); for (i = 0; i < D_80A9E028.count; i++) { @@ -1035,8 +1032,8 @@ void func_80A9D61C(Actor* thisx, GlobalContext* globalCtx) { for (i = 0; i < ARRAY_COUNT(D_80A9E028.unk_02A4); i++) { unkStruct2 = &D_80A9E028.unk_02A4[i]; if (unkStruct2->unk_2C > 0) { - Matrix_SetStateRotationAndTranslation(unkStruct2->unk_04.x, unkStruct2->unk_04.y, unkStruct2->unk_04.z, - &unkStruct2->unk_20); + Matrix_SetTranslateRotateYXZ(unkStruct2->unk_04.x, unkStruct2->unk_04.y, unkStruct2->unk_04.z, + &unkStruct2->unk_20); Matrix_Scale(unkStruct2->unk_00, unkStruct2->unk_00, unkStruct2->unk_00, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.c b/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.c index 916b825d6..f5e035be7 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.c @@ -1,6 +1,13 @@ -#include "z_bg_hakugin_switch.h" +/* + * File: z_bg_hakugin_switch.c + * Overlay: ovl_Bg_Hakugin_Switch + * Description: Goron Link Switch + */ -#define FLAGS 0x00000010 +#include "z_bg_hakugin_switch.h" +#include "objects/object_goronswitch/object_goronswitch.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgHakuginSwitch*)thisx) @@ -9,7 +16,27 @@ void BgHakuginSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgHakuginSwitch_Update(Actor* thisx, GlobalContext* globalCtx); void BgHakuginSwitch_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B15A68(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15B1C(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15B74(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15E0C(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15E78(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15F3C(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B15F88(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B1606C(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B160DC(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B161A0(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B16244(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B162AC(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B163C4(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B16400(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B16494(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B16520(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B165A0(BgHakuginSwitch* this, GlobalContext* globalCtx); +void func_80B165E0(BgHakuginSwitch* this, GlobalContext* globalCtx); + +u32 D_80B16AF0; + const ActorInit Bg_Hakugin_Switch_InitVars = { ACTOR_BG_HAKUGIN_SWITCH, ACTORCAT_SWITCH, @@ -22,84 +49,489 @@ const ActorInit Bg_Hakugin_Switch_InitVars = { (ActorFunc)BgHakuginSwitch_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B16860 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000400, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000400, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 60, 10, 180, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B16904[] = { +typedef struct { + /* 0x00 */ f32 unk_0; + /* 0x04 */ f32 unk_4; + /* 0x08 */ f32 unk_8; + /* 0x0C */ f32 unk_C; + /* 0x10 */ Gfx* unk_10; + /* 0x14 */ u8 unk_14; +} BgHakuginSwitchStruct; + +BgHakuginSwitchStruct D_80B1688C[] = { + { -156.0f, -178.0f, 6.0f, 10.0f, object_goronswitch_DL_000268, 0xB4 }, + { -60.0f, -178.0f, 6.0f, 10.0f, object_goronswitch_DL_000268, 0x32 }, + { -60.0f, -178.0f, 6.0f, 10.0f, object_goronswitch_DL_000268, 0x31 }, + { -120.0f, -178.0f, 6.0f, 10.0f, object_goronswitch_DL_0007D8, 0x3A }, + { -156.0f, -178.0f, 6.0f, 10.0f, object_goronswitch_DL_0007D8, 0xB4 }, +}; + +static InitChainEntry sInitChain1[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 130, ICHAIN_STOP), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B16910[] = { +static InitChainEntry sInitChain2[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 260, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 360, ICHAIN_STOP), }; -#endif +void func_80B15790(BgHakuginSwitch* this, u16 sfxId) { + if (this->unk_1B2 <= 0) { + Actor_PlaySfxAtPos(&this->dyna.actor, sfxId); + } +} -extern ColliderCylinderInit D_80B16860; -extern InitChainEntry D_80B16904[]; -extern InitChainEntry D_80B16910[]; +void func_80B157C4(BgHakuginSwitch* this, u16 arg1) { + if (this->unk_1B2 <= 0) { + func_800B9010(&this->dyna.actor, arg1); + } +} -extern UNK_TYPE D_060005C8; +void BgHakuginSwitch_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitch* this = THIS; + s32 sp34 = BGHAKUGINSWITCH_GET_7(&this->dyna.actor); + s32 sp30; + s32 pad2; + s32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15790.s") + if (Flags_GetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor))) { + sp30 = true; + } else { + sp30 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B157C4.s") + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_goronswitch_Colheader_0005C8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/BgHakuginSwitch_Init.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/BgHakuginSwitch_Destroy.s") + this->unk_1B2 = 15; + if (!BGHAKUGINSWITCH_GET_10(&this->dyna.actor)) { + Actor_ProcessInitChain(&this->dyna.actor, sInitChain1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15A4C.s") + this->dyna.actor.scale.x = 0.07f; + this->dyna.actor.scale.y = 0.016f; + this->dyna.actor.scale.z = 0.07f; + this->collider.dim.radius = 46; + this->collider.dim.yShift = 0x1D; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15A68.s") + this->unk_1A8 = object_goronswitch_DL_000268; + this->unk_1B8 = this->dyna.actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15B1C.s") + if (sp34 == 0) { + this->unk_1BA = -1; + } else { + this->unk_1BA = ActorCutscene_GetAdditionalCutscene(this->unk_1B8); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15B74.s") + if (sp30) { + func_80B16494(this, globalCtx); + } else { + func_80B16244(this, globalCtx); + } + } else { + if (D_80B1688C[sp34].unk_14 & 4) { + sp28 = true; + } else { + sp28 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15E0C.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain2); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15E78.s") + this->unk_1A8 = D_80B1688C[sp34].unk_10; + this->unk_1B8 = this->dyna.actor.cutscene; + this->unk_1BA = ActorCutscene_GetAdditionalCutscene(this->unk_1B8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15F3C.s") + if (sp30 == sp28) { + func_80B15F3C(this, globalCtx); + } else { + func_80B15B1C(this, globalCtx); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B15F88.s") + this->unk_1C8 = 1.0f / this->dyna.actor.scale.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B1606C.s") +void BgHakuginSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginSwitch* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B160DC.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B16180.s") +void func_80B15A4C(BgHakuginSwitch* this, BgHakuginSwitchUnkFunc func, s32 arg2) { + this->unk_1B4 = func; + this->unk_1BC = arg2; + this->actionFunc = func_80B15A68; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B161A0.s") +void func_80B15A68(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitchStruct* s = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + s32 sp18 = !(s->unk_14 & 0x40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B16244.s") + if (ActorCutscene_GetCanPlayNext(this->unk_1BC)) { + if (sp18) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_1BC, &this->dyna.actor); + this->unk_1BF = 40; + } + this->unk_1B4(this, globalCtx); + } else if (sp18) { + ActorCutscene_SetIntentToPlay(this->unk_1BC); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B162AC.s") +void func_80B15B1C(BgHakuginSwitch* this, GlobalContext* globalCtx) { + BgHakuginSwitchStruct* s = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B163C4.s") + this->dyna.actor.world.pos.y = s->unk_0 + this->dyna.actor.home.pos.y; + this->unk_1C0 = 1; + this->unk_1B0 = 480; + this->actionFunc = func_80B15B74; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B16400.s") +void func_80B15B74(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitchStruct* sp38 = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + s32 sp34 = (this->collider.base.acFlags & AC_HIT) != 0; + s32 pad2; + s32 sp2C; + s32 sp28; + s32 sp24; + s32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B16494.s") + if (Flags_GetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor))) { + sp2C = 1; + } else { + sp2C = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B16520.s") + if (sp38->unk_14 & 4) { + sp28 = 1; + } else { + sp28 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B165A0.s") + sp24 = false; + sp20 = -1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/func_80B165E0.s") + if (sp34) { + this->collider.base.acFlags &= ~AC_HIT; + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + sp24 = true; + sp20 = sp28; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/BgHakuginSwitch_Update.s") + if (this->unk_1B0 > 0) { + this->unk_1B0--; + if (sp38->unk_14 & 8) { + func_800B9038(&this->dyna.actor, this->unk_1B0); + if (this->unk_1B0 == 0) { + sp24 = true; + sp20 = sp28; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Hakugin_Switch/BgHakuginSwitch_Draw.s") + if (sp2C == sp28) { + if ((sp38->unk_14 & 0xFF) & 0x10) { + if (D_80B16AF0 < globalCtx->gameplayFrames) { + sp24 = true; + } + } else { + sp24 = true; + } + } + + if (sp24) { + if (sp20 == 1) { + Flags_SetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } else if (sp20 == 0) { + Flags_UnsetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } + + D_80B16AF0 = globalCtx->gameplayFrames; + + if (sp38->unk_14 & 0x10) { + func_80B15A4C(this, func_80B15E0C, this->unk_1B8); + } else { + func_80B15E0C(this, globalCtx); + } + } else if (!(sp38->unk_14 & 1)) { + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B15E0C(BgHakuginSwitch* this, GlobalContext* globalCtx) { + BgHakuginSwitchStruct* s = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + + if ((s->unk_14 & 0x80)) { + func_80B15790(this, NA_SE_EV_STONE_SWITCH_ON); + } + this->unk_1C0 = 0; + this->actionFunc = func_80B15E78; +} + +void func_80B15E78(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitchStruct* sp20 = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + + if (Math_StepToF(&this->dyna.actor.world.pos.y, sp20->unk_4 + this->dyna.actor.home.pos.y, sp20->unk_C)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + } + func_80B15F3C(this, globalCtx); + } else if (!(sp20->unk_14 & 0x80)) { + func_80B157C4(this, NA_SE_EV_STONE_STATUE_OPEN - SFX_FLAG); + } +} + +void func_80B15F3C(BgHakuginSwitch* this, GlobalContext* globalCtx) { + BgHakuginSwitchStruct* s = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + + this->dyna.actor.world.pos.y = s->unk_4 + this->dyna.actor.home.pos.y; + this->unk_1C0 = 0; + this->actionFunc = func_80B15F88; +} + +void func_80B15F88(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 phi_a0; + BgHakuginSwitchStruct* sp18 = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + s32 phi_v1; + + if (Flags_GetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor))) { + phi_a0 = true; + } else { + phi_a0 = false; + } + + if (sp18->unk_14 & 4) { + phi_v1 = true; + } else { + phi_v1 = false; + } + + if (phi_a0 != phi_v1) { + if ((sp18->unk_14 & 0xFF) & 0x20) { + if (D_80B16AF0 < globalCtx->gameplayFrames) { + func_80B15A4C(this, func_80B1606C, this->unk_1BA); + } + } else { + func_80B1606C(this, globalCtx); + } + } +} + +void func_80B1606C(BgHakuginSwitch* this, GlobalContext* globalCtx) { + BgHakuginSwitchStruct* s = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + + if (s->unk_14 & 0x80) { + func_80B15790(this, NA_SE_EV_STONE_SWITCH_OFF); + } + this->unk_1C0 = 1; + this->actionFunc = func_80B160DC; +} + +void func_80B160DC(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitchStruct* sp18 = &D_80B1688C[BGHAKUGINSWITCH_GET_7(&this->dyna.actor)]; + + if (Math_StepToF(&this->dyna.actor.world.pos.y, sp18->unk_0 + this->dyna.actor.home.pos.y, sp18->unk_8)) { + func_80B15B1C(this, globalCtx); + } else if (!(sp18->unk_14 & 0x80)) { + func_80B157C4(this, NA_SE_EV_PILLAR_UP_FAST - SFX_FLAG); + } +} + +void func_80B16180(BgHakuginSwitch* this, BgHakuginSwitchUnkFunc func, s32 arg2, s32 arg3) { + this->unk_1B4 = func; + this->unk_1BE = arg2; + this->unk_1BC = arg3; + this->actionFunc = func_80B161A0; +} + +void func_80B161A0(BgHakuginSwitch* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->unk_1BC)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_1BC, &this->dyna.actor); + if (this->unk_1BE != 0) { + Flags_SetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } else { + Flags_UnsetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor)); + } + this->unk_1BF = 50; + this->unk_1B4(this, globalCtx); + } else { + ActorCutscene_SetIntentToPlay(this->unk_1BC); + } +} + +void func_80B16244(BgHakuginSwitch* this, GlobalContext* globalCtx) { + this->unk_1C0 = 1; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + if ((BGHAKUGINSWITCH_GET_7(&this->dyna.actor) == BGHAKUGINSWITCH_GET_7_1) && + (this->dyna.actor.category != ACTORCAT_SWITCH)) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->dyna.actor, 0); + } + this->actionFunc = func_80B162AC; +} + +void func_80B162AC(BgHakuginSwitch* this, GlobalContext* globalCtx) { + s32 sp34 = (this->collider.base.acFlags & AC_HIT) != 0; + s32 sp30 = BGHAKUGINSWITCH_GET_7(&this->dyna.actor); + s32 pad; + s32 sp28 = false; + s32 sp24 = false; + + if (sp34) { + this->collider.base.acFlags &= ~AC_HIT; + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + sp24 = true; + sp28 = true; + } + } + + if (sp30 == 1) { + if (Flags_GetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor))) { + sp24 = true; + } + } + + if (sp24) { + if (sp28) { + func_80B16180(this, func_80B163C4, 1, this->unk_1B8); + } else { + func_80B163C4(this, globalCtx); + } + } else { + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B163C4(BgHakuginSwitch* this, GlobalContext* globalCtx) { + func_80B15790(this, NA_SE_EV_STONE_SWITCH_ON); + this->unk_1C0 = 0; + this->actionFunc = func_80B16400; +} + +void func_80B16400(BgHakuginSwitch* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->dyna.actor.world.pos.y, + (this->dyna.actor.home.pos.y + 2.0f) - (1800.0f * this->dyna.actor.scale.y), 10.0f)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + } + func_80B16494(this, globalCtx); + } +} + +void func_80B16494(BgHakuginSwitch* this, GlobalContext* globalCtx) { + this->unk_1C0 = 0; + this->dyna.actor.world.pos.y = (this->dyna.actor.home.pos.y - (1800.0f * this->dyna.actor.scale.y)) + 2.0f; + if ((BGHAKUGINSWITCH_GET_7(&this->dyna.actor) == BGHAKUGINSWITCH_GET_7_1) && + (this->dyna.actor.category != ACTORCAT_PROP)) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->dyna.actor, ACTORCAT_PROP); + } + this->actionFunc = func_80B16520; +} + +void func_80B16520(BgHakuginSwitch* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, BGHAKUGINSWITCH_GET_SWITCHFLAG(&this->dyna.actor))) { + if (BGHAKUGINSWITCH_GET_7(&this->dyna.actor) == BGHAKUGINSWITCH_GET_7_1) { + func_80B16180(this, func_80B165A0, 0, this->unk_1BA); + } else { + func_80B165A0(this, globalCtx); + } + } +} + +void func_80B165A0(BgHakuginSwitch* this, GlobalContext* globalCtx) { + func_80B15790(this, NA_SE_EV_STONE_SWITCH_OFF); + this->unk_1C0 = 1; + this->actionFunc = func_80B165E0; +} + +void func_80B165E0(BgHakuginSwitch* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 6.0f)) { + func_80B16244(this, globalCtx); + } +} + +void BgHakuginSwitch_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgHakuginSwitch* this = THIS; + f32 sp24; + + if (this->unk_1B2 > 0) { + this->unk_1B2--; + } + + if (this->unk_1BF > 0) { + if ((this->actionFunc != func_80B15A68) && (this->actionFunc != func_80B161A0)) { + this->unk_1BF--; + if (this->unk_1BF == 0) { + ActorCutscene_Stop(this->unk_1BC); + } + } + } + + this->actionFunc(this, globalCtx); + + sp24 = this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y; + + if (this->unk_1C0 != 0) { + f32 phi_f0; + + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + if (DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) { + phi_f0 = (sp24 - -10.0f) * -0.21f; + } else { + phi_f0 = (sp24 - -3.0f) * -0.08f; + } + this->unk_1C4 += phi_f0; + this->unk_1C4 *= 0.75f; + this->dyna.actor.shape.yOffset += this->unk_1C4 * this->unk_1C8; + } else { + this->unk_1C4 += sp24 * -0.11f; + this->unk_1C4 *= 0.75f; + this->dyna.actor.shape.yOffset += this->unk_1C4 * this->unk_1C8; + this->dyna.actor.shape.yOffset = CLAMP_MAX(this->dyna.actor.shape.yOffset, 0.0f); + } + } else { + Math_StepToF(&this->dyna.actor.shape.yOffset, 0.0f, 2.0f * this->unk_1C8); + this->unk_1C4 = 0.0f; + } +} + +void BgHakuginSwitch_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgHakuginSwitch* this = THIS; + + Gfx_DrawDListOpa(globalCtx, this->unk_1A8); +} diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.h b/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.h index 58cbfed68..cc1363965 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.h +++ b/src/overlays/actors/ovl_Bg_Hakugin_Switch/z_bg_hakugin_switch.h @@ -6,12 +6,30 @@ struct BgHakuginSwitch; typedef void (*BgHakuginSwitchActionFunc)(struct BgHakuginSwitch*, GlobalContext*); +typedef void (*BgHakuginSwitchUnkFunc)(struct BgHakuginSwitch*, GlobalContext*); + +#define BGHAKUGINSWITCH_GET_7(thisx) ((thisx)->params & 7) +#define BGHAKUGINSWITCH_GET_10(thisx) (((thisx)->params >> 4) & 1) +#define BGHAKUGINSWITCH_GET_SWITCHFLAG(thisx) (((thisx)->params >> 8) & 0x7F) + +#define BGHAKUGINSWITCH_GET_7_1 1 typedef struct BgHakuginSwitch { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x68]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; + /* 0x01A8 */ Gfx* unk_1A8; /* 0x01AC */ BgHakuginSwitchActionFunc actionFunc; - /* 0x01B0 */ char unk_1B0[0x1C]; + /* 0x01B0 */ s16 unk_1B0; + /* 0x01B2 */ s8 unk_1B2; + /* 0x01B4 */ BgHakuginSwitchUnkFunc unk_1B4; + /* 0x01B8 */ s16 unk_1B8; + /* 0x01BA */ s16 unk_1BA; + /* 0x01BC */ s16 unk_1BC; + /* 0x01BE */ s8 unk_1BE; + /* 0x01BF */ s8 unk_1BF; + /* 0x01C0 */ s8 unk_1C0; + /* 0x01C4 */ f32 unk_1C4; + /* 0x01C8 */ f32 unk_1C8; } BgHakuginSwitch; // size = 0x1CC extern const ActorInit Bg_Hakugin_Switch_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Icefloe/z_bg_icefloe.c b/src/overlays/actors/ovl_Bg_Icefloe/z_bg_icefloe.c index 8d77107c2..e3270fb6e 100644 --- a/src/overlays/actors/ovl_Bg_Icefloe/z_bg_icefloe.c +++ b/src/overlays/actors/ovl_Bg_Icefloe/z_bg_icefloe.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_icefloe.c + * Overlay: ovl_Bg_Icefloe + * Description: Ice Platform Created by Ice Arrow + */ + #include "z_bg_icefloe.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIcefloe*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c b/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c index 5af83aad2..bf0851a5b 100644 --- a/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c +++ b/src/overlays/actors/ovl_Bg_Icicle/z_bg_icicle.c @@ -5,6 +5,7 @@ */ #include "z_bg_icicle.h" +#include "objects/object_icicle/object_icicle.h" #define FLAGS 0x00000000 @@ -56,13 +57,10 @@ const ActorInit Bg_Icicle_InitVars = { static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 1500, ICHAIN_CONTINUE), ICHAIN_F32(gravity, -3, ICHAIN_CONTINUE), - ICHAIN_F32(minVelocityY, -30, ICHAIN_CONTINUE), + ICHAIN_F32(terminalVelocity, -30, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_060000D0[]; -extern CollisionHeader D_06000294; - void BgIcicle_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; BgIcicle* this = THIS; @@ -70,8 +68,8 @@ void BgIcicle_Init(Actor* thisx, GlobalContext* globalCtx) { s32 paramsMid; Actor_ProcessInitChain(thisx, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000294); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_icicle_Colheader_000294); Collider_InitAndSetCylinder(globalCtx, &this->collider, thisx, &sCylinderInit); Collider_UpdateCylinder(thisx, &this->collider); @@ -94,7 +92,7 @@ void BgIcicle_Init(Actor* thisx, GlobalContext* globalCtx) { void BgIcicle_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgIcicle* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyCylinder(globalCtx, &this->collider); } @@ -107,7 +105,7 @@ void BgIcicle_Break(BgIcicle* this, GlobalContext* globalCtx, f32 arg2) { s32 j; s32 i; - Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); for (i = 0; i < 2; i++) { for (j = 0; j < 10; j++) { @@ -144,7 +142,7 @@ void BgIcicle_Shiver(BgIcicle* this, GlobalContext* globalCtx) { } if (!(this->shiverTimer % 4)) { - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_ICE_SWING); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_ICE_SWING); } if (this->shiverTimer == 0) { @@ -184,7 +182,7 @@ void BgIcicle_Fall(BgIcicle* this, GlobalContext* globalCtx) { return; } } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->dyna.actor); + Actor_MoveWithGravity(&this->dyna.actor); this->dyna.actor.world.pos.y += 40.0f; Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); this->dyna.actor.world.pos.y -= 40.0f; @@ -200,7 +198,7 @@ void BgIcicle_Regrow(BgIcicle* this, GlobalContext* globalCtx) { } void BgIcicle_UpdateAttacked(BgIcicle* this, GlobalContext* globalCtx) { - s32 sp24; + s32 dropItem00Id; if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; @@ -212,9 +210,9 @@ void BgIcicle_UpdateAttacked(BgIcicle* this, GlobalContext* globalCtx) { Item_DropCollectibleRandom(globalCtx, NULL, &this->dyna.actor.world.pos, this->unk_160 << 4); } } else if (this->dyna.actor.params == ICICLE_STALAGMITE_FIXED_DROP) { - sp24 = func_800A8150(this->unk_160); + dropItem00Id = func_800A8150(this->unk_160); BgIcicle_Break(this, globalCtx, 50.0f); - Item_DropCollectible(globalCtx, &this->dyna.actor.world.pos, (this->unk_161 << 8) | sp24); + Item_DropCollectible(globalCtx, &this->dyna.actor.world.pos, (this->unk_161 << 8) | dropItem00Id); } else { if (this->dyna.actor.params == ICICLE_STALACTITE_REGROW) { BgIcicle_Break(this, globalCtx, 40.0f); @@ -245,5 +243,5 @@ void BgIcicle_Update(Actor* thisx, GlobalContext* globalCtx) { } void BgIcicle_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_060000D0); + Gfx_DrawDListOpa(globalCtx, object_icicle_DL_0000D0); } diff --git a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c index c9026f529..b7ebb4f40 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.c @@ -1,6 +1,13 @@ -#include "z_bg_ikana_block.h" +/* + * File: z_bg_ikana_block.c + * Overlay: ovl_Bg_Ikana_Block + * Description: Stone Tower Temple - Rotating Room Pushblock + */ -#define FLAGS 0x00000010 +#include "z_bg_ikana_block.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIkanaBlock*)thisx) @@ -8,12 +15,16 @@ void BgIkanaBlock_Init(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBlock_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBlock_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80B7F00C(BgIkanaBlock* this); void func_80B7F034(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F0A4(BgIkanaBlock* this); void func_80B7F0D0(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F1A8(BgIkanaBlock* this); void func_80B7F290(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F360(BgIkanaBlock* this); void func_80B7F398(BgIkanaBlock* this, GlobalContext* globalCtx); +void func_80B7F564(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Ikana_Block_InitVars = { ACTOR_BG_IKANA_BLOCK, ACTORCAT_BG, @@ -26,58 +37,350 @@ const ActorInit Bg_Ikana_Block_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B7F640[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 250, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80B7EA60(BgIkanaBlock* this) { + s32 phi_v0; -extern InitChainEntry D_80B7F640[]; + this->unk_17A &= ~(0x8 | 0x4 | 0x2 | 0x1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EA60.s") + if (fabsf(this->dyna.pushForce) > 0.1f) { + if (this->dyna.pushForce > 0.0f) { + phi_v0 = this->dyna.yRotation; + } else { + phi_v0 = BINANG_ROT180(this->dyna.yRotation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB30.s") + if ((phi_v0 < -0x6000) || (phi_v0 >= 0x6000)) { + this->unk_17A |= 8; + } else if (phi_v0 < -0x2000) { + this->unk_17A |= 2; + } else if (phi_v0 < 0x2000) { + this->unk_17A |= 4; + } else { + this->unk_17A |= 1; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB64.s") +void func_80B7EB30(BgIkanaBlock* this) { + if (this->unk_17A & (0x8 | 0x4 | 0x2 | 0x1)) { + if (this->unk_17B < 127) { + this->unk_17B++; + } + } else { + this->unk_17B = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB7C.s") +s32 func_80B7EB64(BgIkanaBlock* this, GlobalContext* globalCtx) { + return !(this->unk_17C & 8); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EB94.s") +s32 func_80B7EB7C(BgIkanaBlock* this, GlobalContext* globalCtx) { + return this->unk_17B > 10; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7ECFC.s") +s32 func_80B7EB94(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + CollisionPoly* sp54; + s32 sp50; + s32 sp4C = false; + s16 phi_a0; + f32 phi_f12; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7ED54.s") + if (this->dyna.pushForce > 0.0f) { + sp4C = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EDC4.s") + if (sp4C) { + phi_a0 = this->dyna.yRotation; + } else { + phi_a0 = BINANG_ROT180(this->dyna.yRotation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EE70.s") + sp70.x = this->dyna.actor.world.pos.x; + sp70.y = this->dyna.actor.world.pos.y + this->unk_170 + 2.0f; + sp70.z = this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7EEB4.s") + Matrix_RotateYS(phi_a0, MTXMODE_NEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Init.s") + if (sp4C) { + phi_f12 = 89.0f; + } else { + phi_f12 = 119.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Destroy.s") + Matrix_MultVecZ(phi_f12, &sp64); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F00C.s") + sp64.x += this->dyna.actor.world.pos.x; + sp64.y += this->dyna.actor.world.pos.y + this->unk_170 + 2.0f; + sp64.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F034.s") + return !BgCheck_EntityLineTest3(&globalCtx->colCtx, &sp70, &sp64, &sp58, &sp54, true, false, false, true, &sp50, + &this->dyna.actor, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F0A4.s") +s32 func_80B7ECFC(BgIkanaBlock* this, GlobalContext* globalCtx) { + return func_80B7EB64(this, globalCtx) && func_80B7EB7C(this, globalCtx) && func_80B7EB94(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F0D0.s") +void func_80B7ED54(BgIkanaBlock* this) { + s32 pad; + Vec3f sp18; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F1A8.s") + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecY(30.0f, &sp18); + this->unk_170 = sp18.y - 30.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F290.s") +s32 func_80B7EDC4(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F360.s") + sp30.x = this->dyna.actor.world.pos.x; + sp30.y = this->dyna.actor.world.pos.y + this->unk_170 + 40.0f; + sp30.z = this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F398.s") + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor5_2( + globalCtx, &globalCtx->colCtx, &this->dyna.actor.floorPoly, &sp2C, &this->dyna.actor, &sp30); + this->dyna.actor.floorBgId = sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/BgIkanaBlock_Update.s") + return ((this->dyna.actor.world.pos.y + this->unk_170) - this->dyna.actor.floorHeight) < 2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Block/func_80B7F564.s") +s32 func_80B7EE70(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (func_80B7EDC4(this, globalCtx)) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight - this->unk_170; + return true; + } + return false; +} + +s32 func_80B7EEB4(BgIkanaBlock* this, GlobalContext* globalCtx) { + func_80B7EDC4(this, globalCtx); + + if (this->dyna.actor.floorHeight > (BGCHECK_Y_MIN + 1.0f)) { + if (DynaPoly_GetActor(&globalCtx->colCtx, this->dyna.actor.floorBgId)) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight - this->unk_170; + return true; + } + } + return false; +} + +void BgIkanaBlock_Init(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gameplay_dangeon_keep_Colheader_007498); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->unk_15C = Lib_SegmentedToVirtual(gameplay_dangeon_keep_Matanimheader_01B370); + this->unk_174 = this->dyna.actor.shape.rot; + func_80B7ED54(this); + func_80B7F00C(this); +} + +void BgIkanaBlock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80B7F00C(BgIkanaBlock* this) { + this->unk_17C &= ~7; + this->unk_17D = 40; + this->actionFunc = func_80B7F034; +} + +void func_80B7F034(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (this->unk_17D > 0) { + this->unk_17D--; + } + + if (func_80B7EEB4(this, globalCtx)) { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.draw = func_80B7F564; + func_80B7F0A4(this); + } +} + +void func_80B7F0A4(BgIkanaBlock* this) { + this->unk_17B = 0; + this->unk_17C &= ~7; + this->unk_17C |= 1; + this->actionFunc = func_80B7F0D0; +} + +void func_80B7F0D0(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 sp24 = 0; + s32 phi_v1; + + func_80B7EA60(this); + func_80B7EB30(this); + + if (this->unk_17C & 4) { + sp24 = 1; + } else if (func_80B7ECFC(this, globalCtx)) { + sp24 = 2; + } + + if ((sp24 != 2) && (this->unk_17A & (0x8 | 0x4 | 0x2 | 0x1))) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + + if (sp24 == 1) { + func_80B7F360(this); + } else if (sp24 == 2) { + func_80B7F1A8(this); + } +} + +void func_80B7F1A8(BgIkanaBlock* this) { + f32 temp_f0; + f32* phi_v0; + s32 phi_v0_2; + + if (this->unk_17A & (0x2 | 0x1)) { + this->unk_164 = &this->dyna.actor.world.pos.x; + phi_v0 = &this->dyna.actor.home.pos.x; + } else { + this->unk_164 = &this->dyna.actor.world.pos.z; + phi_v0 = &this->dyna.actor.home.pos.z; + } + + temp_f0 = (*this->unk_164 - *phi_v0) * 0.016666668f; + + if (temp_f0 >= 0.0f) { + temp_f0 += 0.5f; + } else { + temp_f0 -= 0.5f; + } + + if (this->unk_17A & (0x4 | 0x1)) { + phi_v0_2 = 1; + } else { + phi_v0_2 = -1; + } + + this->unk_168 = *phi_v0 + (((s32)temp_f0 + phi_v0_2) * 60.0f); + this->unk_16C = 0.0f; + this->unk_17C &= ~7; + this->unk_17C |= 2; + this->actionFunc = func_80B7F290; +} + +void func_80B7F290(BgIkanaBlock* this, GlobalContext* globalCtx) { + s32 pad; + + Math_StepToF(&this->unk_16C, 2.0f, 0.4f); + + if (Math_StepToF(this->unk_164, this->unk_168, this->unk_16C)) { + Player* player = GET_PLAYER(globalCtx); + + if (!func_80B7EB94(this, globalCtx)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + if (func_80B7EDC4(this, globalCtx)) { + func_80B7F0A4(this); + } else { + func_80B7F360(this); + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + } +} + +void func_80B7F360(BgIkanaBlock* this) { + this->unk_17C &= ~7; + this->unk_17C |= 4; + this->unk_17D = 1; + this->dyna.actor.velocity.y = 0.0f; + this->actionFunc = func_80B7F398; +} + +void func_80B7F398(BgIkanaBlock* this, GlobalContext* globalCtx) { + if (this->unk_17D > 0) { + this->unk_17D--; + return; + } + + this->dyna.actor.velocity.y -= 2.0f; + this->dyna.actor.velocity.y *= 0.95f; + + if (this->dyna.actor.velocity.y < -30.0f) { + this->dyna.actor.velocity.y = -30.0f; + } + + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; + + if (func_80B7EE70(this, globalCtx)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Actor_PlaySfxAtPos( + &this->dyna.actor, + SurfaceType_GetSfx(&globalCtx->colCtx, this->dyna.actor.floorPoly, this->dyna.actor.floorBgId) + SFX_FLAG); + func_80B7F0A4(this); + } +} + +void BgIkanaBlock_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBlock* this = THIS; + + if ((this->dyna.actor.shape.rot.x != this->unk_174.x) || (this->dyna.actor.shape.rot.y != this->unk_174.y) || + (this->dyna.actor.shape.rot.z != this->unk_174.z)) { + this->unk_174 = this->dyna.actor.shape.rot; + func_80B7ED54(this); + } + + this->actionFunc(this, globalCtx); + + Actor_SetFocus(&this->dyna.actor, 30.0f); + + if (this->unk_17E != 0) { + if (this->unk_17F > 0) { + this->unk_17F--; + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->unk_17E = 0; + } else if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->unk_17F = 30; + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } +} + +void func_80B7F564(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIkanaBlock* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + AnimatedMat_DrawStep(globalCtx, this->unk_15C, 0); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0xFF, 0xFF, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_dangeon_keep_DL_0182A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h index 48e65613f..3ad797cba 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h @@ -8,10 +8,20 @@ struct BgIkanaBlock; typedef void (*BgIkanaBlockActionFunc)(struct BgIkanaBlock*, GlobalContext*); typedef struct BgIkanaBlock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ AnimatedMaterial* unk_15C; /* 0x0160 */ BgIkanaBlockActionFunc actionFunc; - /* 0x0164 */ char unk_164[0x1C]; + /* 0x0164 */ f32* unk_164; + /* 0x0168 */ f32 unk_168; + /* 0x016C */ f32 unk_16C; + /* 0x0170 */ f32 unk_170; + /* 0x0174 */ Vec3s unk_174; + /* 0x017A */ u8 unk_17A; + /* 0x017B */ s8 unk_17B; + /* 0x017C */ u8 unk_17C; + /* 0x017D */ s8 unk_17D; + /* 0x017E */ s8 unk_17E; + /* 0x017F */ s8 unk_17F; } BgIkanaBlock; // size = 0x180 extern const ActorInit Bg_Ikana_Block_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.c b/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.c index acbdb6bc9..bc08c9451 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.c @@ -1,6 +1,13 @@ -#include "z_bg_ikana_bombwall.h" +/* + * File: z_bg_ikana_bombwall.c + * Overlay: ovl_Bg_Ikana_Bombwall + * Description: Stone Tower Temple - Bombable Tan Floor Tile + */ -#define FLAGS 0x10000000 +#include "z_bg_ikana_bombwall.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" + +#define FLAGS (ACTOR_FLAG_10000000) #define THIS ((BgIkanaBombwall*)thisx) @@ -9,7 +16,15 @@ void BgIkanaBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBombwall_Update(Actor* thisx, GlobalContext* globalCtx); void BgIkanaBombwall_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BD4F18(BgIkanaBombwall* this); +void func_80BD4F2C(BgIkanaBombwall* this, GlobalContext* globalCtx); +void func_80BD4F88(BgIkanaBombwall* this); +void func_80BD4F9C(BgIkanaBombwall* this, GlobalContext* globalCtx); +void func_80BD4FF8(BgIkanaBombwall* this); +void func_80BD503C(BgIkanaBombwall* this, GlobalContext* globalCtx); +void func_80BD5118(BgIkanaBombwall* this); +void func_80BD5134(BgIkanaBombwall* this, GlobalContext* globalCtx); + const ActorInit Bg_Ikana_Bombwall_InitVars = { ACTOR_BG_IKANA_BOMBWALL, ACTORCAT_BG, @@ -22,65 +37,335 @@ const ActorInit Bg_Ikana_Bombwall_InitVars = { (ActorFunc)BgIkanaBombwall_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD5270 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000008, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000008, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 80, 80, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD529C = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000008, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000008, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 50, 20, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BD52D0[] = { +s16 D_80BD52C8[] = { + 32, + 21, + 15, + 8, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), }; +Gfx* D_80BD52E0[] = { + object_ikana_obj_DL_000378, + object_ikana_obj_DL_000048, +}; + +#ifdef NON_MATCHING +void func_80BD4720(BgIkanaBombwall* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spE0; + Vec3f spD4; + Vec3f spC8; + Vec3f spBC; + f32 temp_fs0; + f32 phi_fs1; + s16 phi_s0; + s16 temp; + s16 phi_t0; + + Matrix_Push(); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + temp_fs0 = 0.0f; + phi_fs1 = 0.0f; + + for (i = 0; i < 30; i++) { + temp_fs0 += 60.0f + (Rand_ZeroOne() * 20.0f); + if (temp_fs0 > 75.0f) { + temp_fs0 -= 150.0f; + } + spC8.x = temp_fs0; + + phi_fs1 += 5; + spC8.y = phi_fs1; + + spC8.z = (Rand_ZeroOne() * 20.0f) - 10.0f; + + spBC.x = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (temp_fs0 * 0.053333335f); + spBC.y = (Rand_ZeroOne() * 7.0f) - 2.0f; + spBC.z = (Rand_ZeroOne() * 4.0f) - 2.0f; + + Matrix_MultVec3f(&spC8, &spE0); + Matrix_MultVec3f(&spBC, &spD4); + + spE0.x += this->dyna.actor.world.pos.x; + spE0.y += this->dyna.actor.world.pos.y; + spE0.z += this->dyna.actor.world.pos.z; + + if ((i & 3) == 0) { + phi_s0 = 32; + func_800BBFB0(globalCtx, &spE0, 50.0f, 2, 100, 120, 1); + } else { + phi_s0 = 64; + } + + if (i & 1) { + phi_s0 |= 1; + phi_t0 = 1; + } else { + phi_t0 = 0; + } + + if (D_80BD52C8[i & 3] >= 16) { + temp = -550; + } else { + temp = -450; + } + + EffectSsKakera_Spawn(globalCtx, &spE0, &spD4, &spE0, temp, phi_s0, 30, 0, 0, D_80BD52C8[i & 3], phi_t0, 0, 50, + -1, OBJECT_IKANA_OBJ, object_ikana_obj_DL_000288); + } + + Matrix_Pop(); +} +#else +void func_80BD4720(BgIkanaBombwall* this, GlobalContext* globalCtx); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4720.s") #endif -extern ColliderCylinderInit D_80BD5270; -extern ColliderCylinderInit D_80BD529C; -extern InitChainEntry D_80BD52D0[]; +void func_80BD4A14(BgIkanaBombwall* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spD8; + Vec3f spCC; + f32 temp_fs0; + f32 temp_fs1; + f32 temp_fs3; + s16 temp_v1; + s16 phi_s2; + s32 phi_t0; + s16 phi_v0; + s32 phi_v1; -extern UNK_TYPE D_06000288; -extern UNK_TYPE D_06000488; + temp_fs3 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4720.s") + for (i = 0, phi_s2 = 0; i < 28; i++, phi_s2 += 0x924) { + temp_fs3 += 20.0f + (Rand_ZeroOne() * 10.0f); + if (temp_fs3 > 60.0f) { + temp_fs3 -= 60.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4A14.s") + temp_fs0 = Math_SinS(phi_s2); + temp_fs1 = Math_CosS(phi_s2); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/BgIkanaBombwall_Init.s") + spD8.x = (temp_fs0 * temp_fs3) + this->dyna.actor.world.pos.x; + spD8.y = this->dyna.actor.world.pos.y; + spD8.z = (temp_fs1 * temp_fs3) + this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/BgIkanaBombwall_Destroy.s") + spCC.x = ((Rand_ZeroOne() - 0.5f) * 3.0f * temp_fs0) + ((temp_fs0 * temp_fs3) * 0.033333335f); + spCC.y = (Rand_ZeroOne() * 18.0f) + 4.0f; + spCC.z = ((Rand_ZeroOne() - 0.5f) * 3.0f * temp_fs1) + ((temp_fs1 * temp_fs3) * 0.033333335f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4E44.s") + temp_v1 = (Rand_Next() & 3) + (i >> 1) + 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4EAC.s") + if ((i & 3) == 0) { + phi_v0 = 32; + } else { + phi_v0 = 64; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4F18.s") + if (temp_v1 >= 15) { + phi_v0 |= 1; + phi_v1 = 1; + phi_t0 = -550; + } else { + phi_v1 = 0; + phi_t0 = -400; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4F2C.s") + EffectSsKakera_Spawn(globalCtx, &spD8, &spCC, &spD8, phi_t0, phi_v0, 30, 0, 0, temp_v1, phi_v1, 0, 50, -1, + OBJECT_IKANA_OBJ, object_ikana_obj_DL_000288); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4F88.s") + if ((i & 3) == 0) { + spD8.y += 30.0f; + func_800BBFB0(globalCtx, &spD8, 50.0f, 2, 70, 110, 1); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4F9C.s") +void BgIkanaBombwall_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIkanaBombwall* this = THIS; + s32 sp2C = BGIKANABOMBWALL_GET_100(&this->dyna.actor); + s32 sp28; + s32 sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD4FF8.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + Collider_InitCylinder(globalCtx, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD503C.s") + if (Flags_GetSwitch(globalCtx, BGIKANABOMBWALL_GET_SWITCHFLAG(&this->dyna.actor))) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD5118.s") + if (sp2C == 0) { + sp28 = &object_ikana_obj_Colheader_000488; + sp24 = &sCylinderInit1; + } else { + sp28 = &object_ikana_obj_Colheader_000128; + sp24 = &sCylinderInit2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/func_80BD5134.s") + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, sp28); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, sp24); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/BgIkanaBombwall_Update.s") + if (sp2C == 0) { + func_80BD4F18(this); + } else { + func_80BD4F88(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Bombwall/BgIkanaBombwall_Draw.s") +void BgIkanaBombwall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBombwall* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +s32 func_80BD4E44(BgIkanaBombwall* this) { + if (this->collider.base.acFlags & AC_HIT) { + if ((this->collider.base.ac != NULL) && + (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < SQ(75.0f))) { + return true; + } + } + return false; +} + +s32 func_80BD4EAC(BgIkanaBombwall* this) { + if (this->collider.base.acFlags & AC_HIT) { + if ((this->collider.base.ac != NULL) && + (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &this->collider.base.ac->world.pos) < SQ(80.0f))) { + return true; + } + } + return false; +} + +void func_80BD4F18(BgIkanaBombwall* this) { + this->actionFunc = func_80BD4F2C; +} + +void func_80BD4F2C(BgIkanaBombwall* this, GlobalContext* globalCtx) { + if (func_80BD4E44(this)) { + func_80BD4FF8(this); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80BD4F88(BgIkanaBombwall* this) { + this->actionFunc = func_80BD4F9C; +} + +void func_80BD4F9C(BgIkanaBombwall* this, GlobalContext* globalCtx) { + if (func_80BD4EAC(this)) { + func_80BD4FF8(this); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80BD4FF8(BgIkanaBombwall* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + this->actionFunc = func_80BD503C; +} + +void func_80BD503C(BgIkanaBombwall* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + if (!BGIKANABOMBWALL_GET_100(&this->dyna.actor)) { + func_80BD4720(this, globalCtx); + } else { + func_80BD4A14(this, globalCtx); + } + this->dyna.actor.draw = NULL; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 60, NA_SE_EV_WALL_BROKEN); + Flags_SetSwitch(globalCtx, BGIKANABOMBWALL_GET_SWITCHFLAG(&this->dyna.actor)); + if (!BGIKANABOMBWALL_GET_100(&this->dyna.actor)) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + func_80BD5118(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80BD5118(BgIkanaBombwall* this) { + this->unk_1AC = 30; + this->actionFunc = func_80BD5134; +} + +void func_80BD5134(BgIkanaBombwall* this, GlobalContext* globalCtx) { + if (!BGIKANABOMBWALL_GET_100(&this->dyna.actor)) { + this->unk_1AC--; + if (this->unk_1AC <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_MarkForDeath(&this->dyna.actor); + } + } else if (this->dyna.actor.cutscene >= 0) { + if (ActorCutscene_GetCurrentIndex() != this->dyna.actor.cutscene) { + Actor_MarkForDeath(&this->dyna.actor); + } + } else { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void BgIkanaBombwall_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaBombwall* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgIkanaBombwall_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, D_80BD52E0[BGIKANABOMBWALL_GET_100(thisx)]); +} diff --git a/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.h b/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.h index 42b0596d8..37921ba53 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Bombwall/z_bg_ikana_bombwall.h @@ -7,11 +7,14 @@ struct BgIkanaBombwall; typedef void (*BgIkanaBombwallActionFunc)(struct BgIkanaBombwall*, GlobalContext*); +#define BGIKANABOMBWALL_GET_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) +#define BGIKANABOMBWALL_GET_100(thisx) (((thisx)->params >> 8) & 1) + typedef struct BgIkanaBombwall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; /* 0x01A8 */ BgIkanaBombwallActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0x4]; + /* 0x01AC */ s8 unk_1AC; } BgIkanaBombwall; // size = 0x1B0 extern const ActorInit Bg_Ikana_Bombwall_InitVars; 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 350f45c20..2fb508c79 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,6 +1,12 @@ +/* + * File: z_bg_ikana_dharma.c + * Overlay: ovl_Bg_Ikana_Dharma + * Description: Stone Tower Temple - Punchable Pillar Segments + */ + #include "z_bg_ikana_dharma.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIkanaDharma*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c index 1e723ce82..de45de35b 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Mirror/z_bg_ikana_mirror.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_ikana_mirror.c + * Overlay: ovl_Bg_Ikana_Mirror + * Description: Stone Tower Temple - Mirror + */ + #include "z_bg_ikana_mirror.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIkanaMirror*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.c b/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.c index 10be85765..d0ec42522 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_ikana_ray.c + * Overlay: ovl_Bg_Ikana_Ray + * Description: Large light ray in Stone Tower Temple + */ + #include "z_bg_ikana_ray.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" #define FLAGS 0x00000000 @@ -53,9 +60,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_06001100[]; -extern AnimatedMaterial D_06001228[]; - void BgIkanaRay_Init(Actor* thisx, GlobalContext* globalCtx) { BgIkanaRay* this = THIS; ColliderCylinder* collision = &this->collision; @@ -65,9 +69,9 @@ void BgIkanaRay_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_SetCylinder(globalCtx, collision, &this->actor, &sCylinderInit); Collider_UpdateCylinder(&this->actor, &this->collision); - this->animatedTextures = (AnimatedMaterial*)Lib_SegmentedToVirtual(D_06001228); + this->animatedTextures = Lib_SegmentedToVirtual(object_ikana_obj_Matanimheader_001228); - if (Flags_GetSwitch(globalCtx, this->actor.params & 0x7F)) { + if (Flags_GetSwitch(globalCtx, BGIKANARAY_GET_SWITCH_FLAG(&this->actor))) { BgIkanaRay_SetActivated(this); } else { BgIkanaRay_SetDeactivated(this); @@ -83,20 +87,20 @@ void BgIkanaRay_Destroy(Actor* thisx, GlobalContext* globalCtx) { void BgIkanaRay_SetDeactivated(BgIkanaRay* this) { this->actor.draw = NULL; - this->actor.flags |= 0x10; - this->update = BgIkanaRay_UpdateCheckForActivation; + this->actor.flags |= ACTOR_FLAG_10; + this->actionFunc = BgIkanaRay_UpdateCheckForActivation; } void BgIkanaRay_UpdateCheckForActivation(BgIkanaRay* this, GlobalContext* globalCtx) { - if (Flags_GetSwitch(globalCtx, this->actor.params & 0x7F)) { + if (Flags_GetSwitch(globalCtx, BGIKANARAY_GET_SWITCH_FLAG(&this->actor))) { BgIkanaRay_SetActivated(this); } } void BgIkanaRay_SetActivated(BgIkanaRay* this) { this->actor.draw = BgIkanaRay_Draw; - this->actor.flags &= ~0x10; - this->update = BgIkanaRay_UpdateActivated; + this->actor.flags &= ~ACTOR_FLAG_10; + this->actionFunc = BgIkanaRay_UpdateActivated; } void BgIkanaRay_UpdateActivated(BgIkanaRay* this, GlobalContext* globalCtx) { @@ -106,12 +110,12 @@ void BgIkanaRay_UpdateActivated(BgIkanaRay* this, GlobalContext* globalCtx) { void BgIkanaRay_Update(Actor* thisx, GlobalContext* globalCtx) { BgIkanaRay* this = THIS; - this->update(this, globalCtx); + this->actionFunc(this, globalCtx); } void BgIkanaRay_Draw(Actor* thisx, GlobalContext* globalCtx) { BgIkanaRay* this = THIS; AnimatedMat_Draw(globalCtx, this->animatedTextures); - func_800BE03C(globalCtx, D_06001100); + Gfx_DrawDListXlu(globalCtx, object_ikana_obj_DL_001100); } diff --git a/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.h b/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.h index d17fbeed9..7c8d8c369 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Ray/z_bg_ikana_ray.h @@ -5,11 +5,15 @@ struct BgIkanaRay; +typedef void (*BgIkanaRayActionFunc)(struct BgIkanaRay*, GlobalContext*); + +#define BGIKANARAY_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) + typedef struct BgIkanaRay { /* 0x000 */ Actor actor; /* 0x144 */ ColliderCylinder collision; /* 0x190 */ AnimatedMaterial* animatedTextures; - /* 0x194 */ void (*update)(struct BgIkanaRay*, GlobalContext*); + /* 0x194 */ BgIkanaRayActionFunc actionFunc; } BgIkanaRay; // size = 0x198 extern const ActorInit Bg_Ikana_Ray_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c index ada046457..d395fd6ee 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.c @@ -1,6 +1,15 @@ -#include "z_bg_ikana_rotaryroom.h" +/* + * File: z_bg_ikana_rotaryroom.c + * Overlay: ovl_Bg_Ikana_Rotaryroom + * Description: Stone Tower Temple - Rotating Room + */ -#define FLAGS 0x00000030 +#include "z_bg_ikana_rotaryroom.h" +#include "overlays/actors/ovl_Bg_Ikana_Block/z_bg_ikana_block.h" +#include "overlays/actors/ovl_En_Torch2/z_en_torch2.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgIkanaRotaryroom*)thisx) @@ -10,8 +19,19 @@ void BgIkanaRotaryroom_Update(Actor* thisx, GlobalContext* globalCtx); void BgIkanaRotaryroom_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80B814B8(BgIkanaRotaryroom* this, GlobalContext* globalCtx); +void func_80B818B4(BgIkanaRotaryroom* this); +void func_80B818C8(Actor* thisx, GlobalContext* globalCtx); +void func_80B81978(BgIkanaRotaryroom* this); +void func_80B8198C(Actor* thisx, GlobalContext* globalCtx); +void func_80B819DC(BgIkanaRotaryroom* this); +void func_80B819F0(Actor* thisx, GlobalContext* globalCtx); +void func_80B81A64(BgIkanaRotaryroom* this); +void func_80B81A80(Actor* thisx, GlobalContext* globalCtx); +void func_80B81B84(BgIkanaRotaryroom* this); +void func_80B81BA0(Actor* thisx, GlobalContext* globalCtx); +void func_80B81DAC(BgIkanaRotaryroom* this); +void func_80B81DC8(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Ikana_Rotaryroom_InitVars = { ACTOR_BG_IKANA_ROTARYROOM, ACTORCAT_BG, @@ -24,108 +44,959 @@ const ActorInit Bg_Ikana_Rotaryroom_InitVars = { (ActorFunc)BgIkanaRotaryroom_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80B820E0[2] = { +static ColliderJntSphElementInit sJntSphElementsInit1[2] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00002000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00002000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 0, { { -3450, 450, 0 }, 60 }, 100 }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00002000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00002000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 0, { { 3450, 450, 0 }, 60 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B82128 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 2, D_80B820E0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit1 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit1, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80B82138[1] = { +static ColliderJntSphElementInit sJntSphElementsInit2[1] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00002000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00002000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 0, { { -3750, 1200, 0 }, 60 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B8215C = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 1, D_80B82138, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit2, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B82214[] = { +Vec3f D_80B8216C = { 225.0f, -280.0f, -210.0f }; + +Vec3f D_80B82178 = { -255.0f, -280.0f, 210.0f }; + +typedef struct { + /* 0x00 */ s8 unk_00; + /* 0x01 */ s8 unk_01; + /* 0x04 */ Vec3f unk_04; +} BgIkanaRotaryroomStruct4; // size = 0x10 + +BgIkanaRotaryroomStruct4 D_80B82184[2][2] = { + { { 0, 0, { -375.0f, -170.0f, 0.0f } }, { 0, 0, { 375.0f, -170.0f, 0.0f } } }, + { { 0, 0, { -435.0f, -180.0f, 0.0f } }, { 0, 1, { 435.0f, -180.0f, 0.0f } } }, +}; + +Vec3s D_80B821C4[] = { + { -150, 194, -120 }, { -120, 194, -30 }, { -150, 194, 120 }, { 120, 194, 120 }, { 180, 194, 30 }, + { 150, 194, -90 }, { 60, 194, -120 }, { -60, 194, 90 }, { 30, 194, 120 }, { 49, 194, -105 }, +}; + +f32 D_80B82200[] = { 64.0f, 66.0f, 66.0f, 30.0f, 41.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +CollisionHeader* D_80B82218[] = { &object_ikana_obj_Colheader_006368, &object_ikana_obj_Colheader_0084F8 }; -extern ColliderJntSphElementInit D_80B820E0[2]; -extern ColliderJntSphInit D_80B82128; -extern ColliderJntSphElementInit D_80B82138[1]; -extern ColliderJntSphInit D_80B8215C; -extern InitChainEntry D_80B82214[]; +void func_80B802E0(BgIkanaRotaryroom* this) { + s32 pad; -extern UNK_TYPE D_060048A0; -extern UNK_TYPE D_06007B68; + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B802E0.s") + Collider_UpdateSpheres(0, &this->collider); + if (!BGIKANAROTARYROOM_GET_1(&this->dyna.actor)) { + Collider_UpdateSpheres(1, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80358.s") +void func_80B80358(Vec3f* arg0) { + arg0->x += (arg0->x >= 0.0f) ? 0.5f : -0.5f; + arg0->y += (arg0->y >= 0.0f) ? 0.5f : -0.5f; + arg0->z += (arg0->z >= 0.0f) ? 0.5f : -0.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80440.s") + arg0->x = (s32)arg0->x; + arg0->y = (s32)arg0->y; + arg0->z = (s32)arg0->z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80550.s") +void func_80B80440(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp50; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80778.s") + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + if (Flags_GetSwitch(globalCtx, BGIKANAROTARYROOM_GET_7F00(&this->dyna.actor))) { + Matrix_Translate(D_80B82178.x, D_80B82178.y, D_80B82178.z, MTXMODE_APPLY); + } else { + Matrix_Translate(D_80B8216C.x, D_80B8216C.y, D_80B8216C.z, MTXMODE_APPLY); + } + Matrix_MultZero(&sp50); + func_80B80358(&sp50); + this->unk_204.unk_00 = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_BG_IKANA_BLOCK, sp50.x, sp50.y, sp50.z, this->dyna.actor.shape.rot.x, + this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, -1, + ActorCutscene_GetAdditionalCutscene(this->dyna.actor.cutscene), this->dyna.actor.unk20, NULL); + Matrix_Pop(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80894.s") +void func_80B80550(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad; + s32 spC8 = BGIKANAROTARYROOM_GET_1(&this->dyna.actor); + s32 spC4; + s32 pad2; + Vec3f spB4; + Actor* actor; + s32 i; + BgIkanaRotaryroomStruct4* ptr; + MtxF sp68; + Vec3s sp60; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80C88.s") + if (Flags_GetSwitch(globalCtx, BGIKANAROTARYROOM_GET_FE(&this->dyna.actor))) { + spC4 = 1; + } else { + spC4 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B80F08.s") + actor = globalCtx->actorCtx.actorLists[ACTORCAT_DOOR].first; + Matrix_Push(); + sp60.x = BINANG_ROT180(this->dyna.actor.home.rot.x); + sp60.y = this->dyna.actor.home.rot.y; + sp60.z = this->dyna.actor.home.rot.z; + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &sp60); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81010.s") + while (actor != NULL) { + if (actor->id == ACTOR_DOOR_SHUTTER) { + Math_Vec3f_Diff(&actor->world.pos, &this->dyna.actor.world.pos, &spB4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81234.s") + for (i = 0; i < ARRAY_COUNT(D_80B82184); i++) { + ptr = &D_80B82184[spC8][i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B814B8.s") + if ((Math3D_Vec3fDistSq(&spB4, &D_80B82184[spC8][i].unk_04) < SQ(250.0f)) && + ((ptr->unk_00 ^ spC4) && (ptr->unk_01 == 0))) { + Matrix_Push(); + Matrix_Translate(spB4.x, spB4.y, spB4.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y - this->dyna.actor.home.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x - this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z - this->dyna.actor.home.rot.z, MTXMODE_APPLY); + Matrix_MultZero(&actor->world.pos); + func_80B80358(&actor->world.pos); + Matrix_Get(&sp68); + Matrix_MtxFToYXZRot(&sp68, &actor->shape.rot, false); + Matrix_Pop(); + } + } + } + actor = actor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81570.s") + Matrix_Pop(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B816A4.s") +BgIkanaRotaryroomStruct4* func_80B80778(BgIkanaRotaryroom* this, GlobalContext* globalCtx, Actor* arg2) { + s32 i; + Vec3f sp68; + s32 pad[2]; + s32 temp_s3 = BGIKANAROTARYROOM_GET_1(&this->dyna.actor); + BgIkanaRotaryroomStruct4* sp58 = NULL; + BgIkanaRotaryroomStruct4* ptr; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/BgIkanaRotaryroom_Init.s") + if (1) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/BgIkanaRotaryroom_Destroy.s") + if (arg2->id == ACTOR_DOOR_SHUTTER) { + Matrix_Push(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B818B4.s") + for (i = 0; i < ARRAY_COUNT(D_80B82184); i++) { + ptr = &D_80B82184[temp_s3][i]; + if ((ptr->unk_01 == 0) && + (Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot), + Matrix_MultVec3f(&ptr->unk_04, &sp68), (Math3D_Vec3fDistSq(&arg2->world.pos, &sp68) < SQ(250.0f)))) { + sp58 = ptr; + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B818C8.s") + Matrix_Pop(); + } + return sp58; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81978.s") +void func_80B80894(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad[7]; + Actor* actor = this->unk_204.unk_00; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B8198C.s") + Matrix_Push(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B819DC.s") + Matrix_RotateZS(-this->dyna.actor.shape.rot.z, MTXMODE_NEW); + Matrix_RotateXS(-this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateYS(-this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(-this->dyna.actor.world.pos.x, -this->dyna.actor.world.pos.y, -this->dyna.actor.world.pos.z, + MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B819F0.s") + if (actor != NULL) { + Matrix_Push(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81A64.s") + Matrix_Translate(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&this->unk_204.unk_04); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81A80.s") + Matrix_Pop(); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81B84.s") + for (i = 0; i < ARRAY_COUNT(this->unk_248); i++) { + this->unk_248[i].unk_00 = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81BA0.s") + actor = globalCtx->actorCtx.actorLists[ACTORCAT_DOOR].first; + i = 0; + while (actor != NULL) { + if (func_80B80778(this, globalCtx, actor) && (i < 2)) { + this->unk_248[i].unk_00 = actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81DAC.s") + Matrix_Push(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/func_80B81DC8.s") + Matrix_Translate(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&this->unk_248[i].unk_04); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/BgIkanaRotaryroom_Update.s") + Matrix_Pop(); + i++; + } + actor = actor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ikana_Rotaryroom/BgIkanaRotaryroom_Draw.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { + this->unk_2D0[i].unk_00 = NULL; + } + + actor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + i = 0; + while (actor != NULL) { + if ((actor->id == ACTOR_EN_TORCH2) && (actor->update != NULL) && (i < ARRAY_COUNT(this->unk_2D0))) { + this->unk_2D0[i].unk_00 = actor; + + Matrix_Push(); + + Matrix_Translate(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&this->unk_2D0[i].unk_04); + + Matrix_Pop(); + i++; + } + actor = actor->next; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + this->unk_3E0[i].unk_00 = NULL; + } + + actor = globalCtx->actorCtx.actorLists[ACTORCAT_ENEMY].first; + i = 0; + while (actor != NULL) { + if ((actor->update != NULL) && (actor->id != ACTOR_EN_WATER_EFFECT) && (i < ARRAY_COUNT(this->unk_3E0))) { + this->unk_3E0[i].unk_00 = actor; + this->unk_3E0[i].unk_44 = actor->shape.rot; + this->unk_3E0[i].unk_4C = 0.0f; + + Matrix_Push(); + + Matrix_Translate(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&this->unk_3E0[i].unk_04); + + Matrix_Pop(); + i++; + } + actor = actor->next; + } + + actor = &GET_PLAYER(globalCtx)->actor; + if (actor->update != NULL) { + this->unk_520.unk_40 = actor->shape.rot; + + Matrix_Push(); + + Matrix_Translate(actor->world.pos.x, actor->world.pos.y, actor->world.pos.z, MTXMODE_APPLY); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&this->unk_520.unk_00); + + Matrix_Pop(); + } + + Matrix_Pop(); +} + +void func_80B80C88(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad[5]; + BgIkanaBlock* ikanaBlock = (BgIkanaBlock*)this->unk_204.unk_00; + Player* player; + Actor* ptr; + Actor* ptr2; + Actor* ptr3; + s32 i; + MtxF sp3C; + + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + + if (ikanaBlock != NULL) { + Matrix_Push(); + + Matrix_Mult(&this->unk_204.unk_04, MTXMODE_APPLY); + Matrix_MultZero(&ikanaBlock->dyna.actor.world.pos); + func_80B80358(&ikanaBlock->dyna.actor.world.pos); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &ikanaBlock->dyna.actor.shape.rot, false); + + Matrix_Pop(); + } + + for (i = 0; i < ARRAY_COUNT(this->unk_248); i++) { + ptr = this->unk_248[i].unk_00; + if (ptr != NULL) { + Matrix_Push(); + + Matrix_Mult(&this->unk_248[i].unk_04, MTXMODE_APPLY); + Matrix_MultZero(&ptr->world.pos); + func_80B80358(&ptr->world.pos); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &ptr->shape.rot, false); + + Matrix_Pop(); + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { + ptr2 = this->unk_2D0[i].unk_00; + if (ptr2 != NULL) { + Matrix_Push(); + + Matrix_Mult(&this->unk_2D0[i].unk_04, MTXMODE_APPLY); + Matrix_MultZero(&ptr2->world.pos); + func_80B80358(&ptr2->world.pos); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &ptr2->shape.rot, false); + + Matrix_Pop(); + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + ptr3 = this->unk_3E0[i].unk_00; + if (ptr3 != NULL) { + Matrix_Push(); + + Matrix_Mult(&this->unk_3E0[i].unk_04, MTXMODE_APPLY); + Matrix_MultZero(&ptr3->world.pos); + func_80B80358(&ptr3->world.pos); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &ptr3->shape.rot, false); + + Matrix_Pop(); + } + } + + player = GET_PLAYER(globalCtx); + if (player != NULL) { + Matrix_Push(); + + Matrix_Mult(&this->unk_520.unk_00, MTXMODE_APPLY); + Matrix_MultZero(&player->actor.world.pos); + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + func_80B80358(&player->actor.world.pos); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &player->actor.shape.rot, false); + + Matrix_Pop(); + player->actor.freezeTimer = 2; + } + + Matrix_Pop(); +} + +s32 func_80B80F08(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad; + BgIkanaBlock* ikanaBlock = (BgIkanaBlock*)this->unk_204.unk_00; + Vec3f sp34; + Vec3f sp28; + s32 sp24 = false; + + if (ikanaBlock != NULL) { + Matrix_Push(); + + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Translate(D_80B82178.x, D_80B82178.y, D_80B82178.z, MTXMODE_APPLY); + Matrix_MultZero(&sp34); + Matrix_SetTranslateRotateYXZ(ikanaBlock->dyna.actor.world.pos.x, + ikanaBlock->dyna.actor.world.pos.y + ikanaBlock->unk_170, + ikanaBlock->dyna.actor.world.pos.z, &ikanaBlock->dyna.actor.shape.rot); + Matrix_MultZero(&sp28); + + Matrix_Pop(); + + if (Math3D_Vec3fDistSq(&sp34, &sp28) < 3.0f) { + if (!Flags_GetSwitch(globalCtx, BGIKANAROTARYROOM_GET_7F00(&this->dyna.actor))) { + sp24 = true; + } + Flags_SetSwitch(globalCtx, BGIKANAROTARYROOM_GET_7F00(&this->dyna.actor)); + } + } + return sp24; +} + +void func_80B81010(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f0; + s32 temp_s2; + s32 phi_s7; + s32 i; + Actor* ptr; + Vec3f sp84; + BgIkanaRotaryroomStruct2* ptr2; + CollisionPoly* sp7C; + s32 sp78; + + if (ActorCutscene_GetCurrentIndex() == this->dyna.actor.cutscene) { + phi_s7 = true; + + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + ptr = this->unk_3E0[i].unk_00; + ptr2 = &this->unk_3E0[i]; + + if (ptr != NULL) { + temp_s2 = Math_ScaledStepToS(&ptr->shape.rot.x, ptr2->unk_44.x, 0xBB8) & 1; + temp_s2 &= Math_ScaledStepToS(&ptr->shape.rot.y, ptr2->unk_44.y, 0xBB8); + temp_s2 &= Math_ScaledStepToS(&ptr->shape.rot.z, ptr2->unk_44.z, 0xBB8); + + ptr2->unk_4C -= 2.0f; + if (ptr2->unk_4C < -30.0f) { + ptr2->unk_4C = -30.0f; + } + + Math_Vec3f_Copy(&ptr->prevPos, &ptr->world.pos); + + ptr->world.pos.y += ptr2->unk_4C; + + sp84.x = ptr->prevPos.x; + sp84.y = ptr->prevPos.y + 50.0f; + sp84.z = ptr->prevPos.z; + + temp_f0 = BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &sp7C, &sp78, NULL, &sp84); + if (ptr->world.pos.y <= temp_f0) { + ptr->world.pos.y = temp_f0; + } else { + temp_s2 = false; + } + + if (temp_s2) { + ptr2->unk_00 = NULL; + } else { + phi_s7 = false; + } + } + } + + if (phi_s7) { + this->unk_578 = NULL; + } + } else { + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + ptr = this->unk_3E0[i].unk_00; + if (ptr != NULL) { + ptr->shape.rot = this->unk_3E0[i].unk_44; + Math_Vec3f_Copy(&ptr->prevPos, &ptr->world.pos); + } + } + this->unk_578 = NULL; + } +} + +void func_80B81234(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player = GET_PLAYER(globalCtx); + BgIkanaRotaryroomStruct3* ptr; + s32 sp64; + Vec3f sp58; + Vec3f sp4C; + f32 temp_f0; + f32 sp44 = D_80B82200[player->transformation] * 0.5f; + CollisionPoly* sp40; + s32 sp3C; + + if (ActorCutscene_GetCurrentIndex() == this->dyna.actor.cutscene) { + if (player == NULL) { + return; + } + + ptr = &this->unk_520; + + if (player->actor.freezeTimer > 0) { + sp58.x = ptr->unk_4C.x; + sp58.y = ptr->unk_4C.y + 50.0f; + sp58.z = ptr->unk_4C.z; + + sp64 = Math_ScaledStepToS(&player->actor.shape.rot.x, ptr->unk_40.x, 2000) & 1; + sp64 &= Math_ScaledStepToS(&player->actor.shape.rot.y, ptr->unk_40.y, 2000); + sp64 &= Math_ScaledStepToS(&player->actor.shape.rot.z, ptr->unk_40.z, 2000); + + ptr->unk_48 = ptr->unk_48 - 2.1f; + ptr->unk_48 = ptr->unk_48 * 0.98f; + if (ptr->unk_48 < -30.0f) { + ptr->unk_48 = -30.0f; + } + ptr->unk_4C.y += ptr->unk_48; + + Matrix_Push(); + + Matrix_RotateYS(player->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(player->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(player->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecY(sp44, &sp4C); + + Matrix_Pop(); + + temp_f0 = BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &sp40, &sp3C, NULL, &sp58); + if (ptr->unk_4C.y <= temp_f0) { + ptr->unk_4C.y = temp_f0; + } else { + sp64 = 0; + } + + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + + player->actor.world.pos.x = ptr->unk_4C.x - sp4C.x; + player->actor.world.pos.y = (ptr->unk_4C.y - sp4C.y) + sp44; + player->actor.world.pos.z = ptr->unk_4C.z - sp4C.z; + + if (sp64 != 0) { + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + this->unk_57C = NULL; + } else { + player->actor.freezeTimer = 2; + } + } + } else { + if (player != NULL) { + player->actor.shape.rot = this->unk_520.unk_40; + Math_Vec3f_Copy(&player->actor.home.pos, &player->actor.world.pos); + } + this->unk_57C = NULL; + } +} + +void func_80B814B8(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCurrentIndex() == this->dyna.actor.cutscene) { + if (player->actor.bgCheckFlags & 0x100) { + func_800B8E58(player, NA_SE_VO_LI_DAMAGE_S + player->ageProperties->unk_92); + func_80169EFC(&globalCtx->state); + func_800B8E58(player, NA_SE_VO_LI_TAKEN_AWAY + player->ageProperties->unk_92); + globalCtx->unk_18845 = 1; + play_sound(NA_SE_OC_ABYSS); + this->actionFunc = NULL; + } + } else { + this->actionFunc = NULL; + } +} + +void func_80B81570(BgIkanaRotaryroom* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp70; + Vec3f sp64; + s32 pad; + s32 pad2; + + Matrix_Push(); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + + for (i = 0; i < ARRAY_COUNT(D_80B821C4); i++) { + sp64.x = D_80B821C4[i].x; + sp64.y = D_80B821C4[i].y; + sp64.z = D_80B821C4[i].z; + + Matrix_MultVec3f(&sp64, &sp70); + + sp70.x += this->dyna.actor.world.pos.x; + sp70.y += this->dyna.actor.world.pos.y; + sp70.z += this->dyna.actor.world.pos.z; + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, sp70.x, sp70.y, sp70.z, 0, 0, 0, 1); + } + + Matrix_Pop(); +} + +s32 func_80B816A4(BgIkanaRotaryroom* this) { + s32 i; + s32 count = 0; + + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + if (this->unk_3E0[i].unk_00 != NULL) { + count++; + } + } + + return count; +} + +void BgIkanaRotaryroom_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIkanaRotaryroom* this = THIS; + s32 sp34 = BGIKANAROTARYROOM_GET_1(&this->dyna.actor); + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + if (Flags_GetSwitch(globalCtx, BGIKANAROTARYROOM_GET_FE(&this->dyna.actor))) { + this->dyna.actor.shape.rot.x = -0x8000; + } else { + this->dyna.actor.shape.rot.x = 0; + } + + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, D_80B82218[sp34]); + + Collider_InitJntSph(globalCtx, &this->collider); + if (!sp34) { + Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit1, this->colliderElements); + } else { + Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit2, this->colliderElements); + } + + func_80B802E0(this); + + if (sp34 == true) { + this->unk_1FC = Lib_SegmentedToVirtual(&object_ikana_obj_Matanimheader_007B68); + } + + if (!sp34) { + func_80B80440(this, globalCtx); + } else { + func_80B81570(this, globalCtx); + } + + func_80B80550(this, globalCtx); + func_80B818B4(this); +} + +void BgIkanaRotaryroom_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void func_80B818B4(BgIkanaRotaryroom* this) { + this->unk_200 = func_80B818C8; +} + +void func_80B818C8(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + s32 sp20; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + sp20 = BGIKANAROTARYROOM_GET_FE(&this->dyna.actor); + if (Flags_GetSwitch(globalCtx, sp20)) { + Flags_UnsetSwitch(globalCtx, sp20); + } else { + Flags_SetSwitch(globalCtx, sp20); + } + func_80B81978(this); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B81978(BgIkanaRotaryroom* this) { + this->unk_200 = func_80B8198C; +} + +void func_80B8198C(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + + if (this->unk_204.unk_00 == NULL) { + func_80B819DC(this); + } else if (((BgIkanaBlock*)this->unk_204.unk_00)->unk_17C & 1) { + ((BgIkanaBlock*)this->unk_204.unk_00)->unk_17C |= 8; + func_80B819DC(this); + } +} + +void func_80B819DC(BgIkanaRotaryroom* this) { + this->unk_200 = func_80B819F0; +} + +void func_80B819F0(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + if (this->dyna.actor.cutscene >= 0) { + func_800B7298(globalCtx, &this->dyna.actor, 7); + } + func_80B81A64(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80B81A64(BgIkanaRotaryroom* this) { + this->unk_584 = 25; + this->unk_200 = func_80B81A80; +} + +void func_80B81A80(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + s32 pad; + s32 i; + BgIkanaRotaryroomStruct1* ptr; + + func_800B9010(thisx, NA_SE_EV_EARTHQUAKE - SFX_FLAG); + this->unk_584--; + + if (this->unk_584 <= 0) { + if (1) {} + if (1) {} + if (1) {} + if (1) {} + func_80B80894(this, globalCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { + ptr = &this->unk_2D0[i]; + if (ptr->unk_00 != NULL) { + ((EnTorch2*)ptr->unk_00)->state = 3; + } + } + + func_80B81B84(this); + } else if (this->unk_584 == 15) { + s16 sp26 = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(sp26, 0x7B30); + Quake_SetQuakeValues(sp26, 6, 0, 100, 0); + Quake_SetCountdown(sp26, 22); + } +} + +void func_80B81B84(BgIkanaRotaryroom* this) { + this->unk_584 = 0x2001; + this->unk_200 = func_80B81BA0; +} + +void func_80B81BA0(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + s32 sp30 = 0; + s32 i; + + func_800B9010(&this->dyna.actor, NA_SE_EV_EARTHQUAKE - SFX_FLAG); + + if (this->unk_584 > 0) { + this->unk_584--; + } + + thisx->shape.rot.x += 0x1F4; + + if (!(this->unk_584 & 7)) { + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 0x7B30); + Quake_SetQuakeValues(quake, (s32)(Rand_ZeroOne() * 2.5f) + 3, 0, 10, 0); + Quake_SetCountdown(quake, 15); + } + + if (Flags_GetSwitch(globalCtx, BGIKANAROTARYROOM_GET_FE(&this->dyna.actor))) { + if (this->dyna.actor.shape.rot.x < 0) { + this->dyna.actor.shape.rot.x = -0x8000; + sp30 = 1; + } + } else if (this->dyna.actor.shape.rot.x >= 0) { + this->dyna.actor.shape.rot.x = 0; + sp30 = 1; + } + + func_80B80C88(this, globalCtx); + + if (sp30 != 0) { + Player* player = GET_PLAYER(globalCtx); + BgIkanaRotaryroomStruct1* ptr; + BgIkanaBlock* block = (BgIkanaBlock*)this->unk_204.unk_00; + + if (block != NULL) { + block->unk_17C &= ~8; + block->unk_17C |= 4; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { + ptr = &this->unk_2D0[i]; + if (ptr->unk_00 != NULL) { + ((EnTorch2*)ptr->unk_00)->state = 4; + } + } + + this->unk_520.unk_48 = 0.0f; + this->unk_520.unk_4C.x = player->actor.world.pos.x; + this->unk_520.unk_4C.y = player->actor.world.pos.y - D_80B82200[player->transformation]; + this->unk_520.unk_4C.z = player->actor.world.pos.z; + + if (func_80B816A4(this) > 0) { + this->unk_578 = func_80B81010; + } + + this->unk_57C = func_80B81234; + this->actionFunc = func_80B814B8; + func_80B802E0(this); + func_80B81DAC(this); + } +} + +void func_80B81DAC(BgIkanaRotaryroom* this) { + this->unk_584 = 20; + this->unk_200 = func_80B81DC8; +} + +void func_80B81DC8(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgIkanaRotaryroom* this = THIS; + + if (this->unk_584 > 10) { + func_800B9010(&this->dyna.actor, NA_SE_EV_EARTHQUAKE - SFX_FLAG); + } + this->unk_584--; + + if (this->unk_584 <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + func_80B818B4(this); + } else if (this->unk_584 == 19) { + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 0x4E20); + Quake_SetQuakeValues(quake, 5, 0, 40, 60); + Quake_SetCountdown(quake, 17); + } +} + +void BgIkanaRotaryroom_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + BgIkanaRotaryroomStruct1* ptr; + BgIkanaRotaryroomStruct1* ptr2; + BgIkanaRotaryroomStruct2* ptr3; + s32 i; + + if ((this->unk_204.unk_00 != NULL) && (this->unk_204.unk_00->update == NULL)) { + this->unk_204.unk_00 = NULL; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_248); i++) { + ptr = &this->unk_248[i]; + if ((ptr->unk_00 != NULL) && (ptr->unk_00->update == NULL)) { + ptr->unk_00 = NULL; + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { + ptr2 = &this->unk_2D0[i]; + if ((ptr2->unk_00 != NULL) && (ptr2->unk_00->update == NULL)) { + ptr2->unk_00 = NULL; + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_3E0); i++) { + ptr3 = &this->unk_3E0[i]; + if ((ptr3->unk_00 != NULL) && (ptr3->unk_00->update == NULL)) { + ptr3->unk_00 = NULL; + } + } + + if (func_80B80F08(this, globalCtx)) { + if (this->unk_204.unk_00 != NULL) { + ((BgIkanaBlock*)this->unk_204.unk_00)->unk_17E = 1; + } + } + + this->unk_200(&this->dyna.actor, globalCtx); + + if (this->unk_578 != NULL) { + this->unk_578(this, globalCtx); + } + + if (this->unk_57C != NULL) { + this->unk_57C(this, globalCtx); + } + + if (this->actionFunc != NULL) { + this->actionFunc(this, globalCtx); + } +} + +void BgIkanaRotaryroom_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgIkanaRotaryroom* this = THIS; + s32 param = BGIKANAROTARYROOM_GET_1(&this->dyna.actor); + + if (!param) { + Gfx_DrawDListOpa(globalCtx, object_ikana_obj_DL_0048A0); + Gfx_DrawDListXlu(globalCtx, object_ikana_obj_DL_004710); + } else { + AnimatedMat_Draw(globalCtx, this->unk_1FC); + Gfx_DrawDListOpa(globalCtx, object_ikana_obj_DL_007448); + Gfx_DrawDListXlu(globalCtx, object_ikana_obj_DL_007360); + } +} diff --git a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.h b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.h index d446d5e92..1e27fb485 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.h +++ b/src/overlays/actors/ovl_Bg_Ikana_Rotaryroom/z_bg_ikana_rotaryroom.h @@ -6,12 +6,47 @@ struct BgIkanaRotaryroom; typedef void (*BgIkanaRotaryroomActionFunc)(struct BgIkanaRotaryroom*, GlobalContext*); +typedef void (*BgIkanaRotaryroomUnkFunc)(Actor*, GlobalContext*); +typedef void (*BgIkanaRotaryroomUnkFunc2)(struct BgIkanaRotaryroom*, GlobalContext*); + +#define BGIKANAROTARYROOM_GET_1(thisx) ((thisx)->params & 1) +#define BGIKANAROTARYROOM_GET_FE(thisx) (((thisx)->params >> 1) & 0x7F) +#define BGIKANAROTARYROOM_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + +typedef struct { + /* 0x00 */ Actor* unk_00; + /* 0x04 */ MtxF unk_04; +} BgIkanaRotaryroomStruct1; // size = 0x44 + +typedef struct { + /* 0x00 */ Actor* unk_00; + /* 0x04 */ MtxF unk_04; + /* 0x44 */ Vec3s unk_44; + /* 0x4C */ f32 unk_4C; +} BgIkanaRotaryroomStruct2; // size = 0x50 + +typedef struct { + /* 0x00 */ MtxF unk_00; + /* 0x40 */ Vec3s unk_40; + /* 0x48 */ f32 unk_48; + /* 0x4C */ Vec3f unk_4C; +} BgIkanaRotaryroomStruct3; // size = 0x58 typedef struct BgIkanaRotaryroom { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x43C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderJntSph collider; + /* 0x017C */ ColliderJntSphElement colliderElements[2]; + /* 0x01FC */ AnimatedMaterial* unk_1FC; + /* 0x0200 */ BgIkanaRotaryroomUnkFunc unk_200; + /* 0x0204 */ BgIkanaRotaryroomStruct1 unk_204; + /* 0x0248 */ BgIkanaRotaryroomStruct1 unk_248[2]; + /* 0x02D0 */ BgIkanaRotaryroomStruct1 unk_2D0[4]; + /* 0x03E0 */ BgIkanaRotaryroomStruct2 unk_3E0[4]; + /* 0x0520 */ BgIkanaRotaryroomStruct3 unk_520; + /* 0x0578 */ BgIkanaRotaryroomUnkFunc2 unk_578; + /* 0x057C */ BgIkanaRotaryroomUnkFunc2 unk_57C; /* 0x0580 */ BgIkanaRotaryroomActionFunc actionFunc; - /* 0x0584 */ char unk_584[0x4]; + /* 0x0584 */ s16 unk_584; } BgIkanaRotaryroom; // size = 0x588 extern const ActorInit Bg_Ikana_Rotaryroom_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Ikana_Shutter/z_bg_ikana_shutter.c b/src/overlays/actors/ovl_Bg_Ikana_Shutter/z_bg_ikana_shutter.c index 986b8b8ae..16060bbd2 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Shutter/z_bg_ikana_shutter.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Shutter/z_bg_ikana_shutter.c @@ -1,6 +1,13 @@ -#include "z_bg_ikana_shutter.h" +/* + * File: z_bg_ikana_shutter.c + * Overlay: ovl_Bg_Ikana_Shutter + * Description: Metal shutter in switch room of Stone Tower Temple + */ -#define FLAGS 0x00000010 +#include "z_bg_ikana_shutter.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIkanaShutter*)thisx) @@ -47,9 +54,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_06000F28; -extern Gfx D_06000CE8[]; - s32 BgIkanaShutter_AllSwitchesPressed(BgIkanaShutter* this, GlobalContext* globalCtx) { return Flags_GetSwitch(globalCtx, this->dyna.actor.params & 0x7F) && Flags_GetSwitch(globalCtx, (this->dyna.actor.params & 0x7F) + 1) && @@ -61,8 +65,8 @@ void BgIkanaShutter_Init(Actor* thisx, GlobalContext* globalCtx) { BgIkanaShutter* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000F28); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ikana_obj_Colheader_000F28); if (!((this->dyna.actor.params >> 8) & 1)) { if (BgIkanaShutter_AllSwitchesPressed(this, globalCtx)) { func_80BD599C(this); @@ -71,7 +75,7 @@ void BgIkanaShutter_Init(Actor* thisx, GlobalContext* globalCtx) { func_80BD5828(this); return; } - if (Actor_GetRoomCleared(globalCtx, this->dyna.actor.room)) { + if (Flags_GetClear(globalCtx, this->dyna.actor.room)) { BgIkanaShutter_SetupDoNothing(this); return; } @@ -81,7 +85,7 @@ void BgIkanaShutter_Init(Actor* thisx, GlobalContext* globalCtx) { void BgIkanaShutter_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgIkanaShutter* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void func_80BD5828(BgIkanaShutter* this) { @@ -160,7 +164,7 @@ void func_80BD5AE8(BgIkanaShutter* this) { } void func_80BD5B04(BgIkanaShutter* this, GlobalContext* globalCtx) { - if (Actor_GetRoomClearedTemp(globalCtx, this->dyna.actor.room)) { + if (Flags_GetClearTemp(globalCtx, this->dyna.actor.room)) { func_80BD5B44(this); } } @@ -173,7 +177,7 @@ void func_80BD5B44(BgIkanaShutter* this) { void func_80BD5B60(BgIkanaShutter* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); - Actor_SetRoomCleared(globalCtx, this->dyna.actor.room); + Flags_SetClear(globalCtx, this->dyna.actor.room); func_80BD5BC4(this); return; } @@ -207,5 +211,5 @@ void BgIkanaShutter_Update(Actor* thisx, GlobalContext* globalCtx) { } void BgIkanaShutter_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000CE8); + Gfx_DrawDListOpa(globalCtx, object_ikana_obj_DL_000CE8); } diff --git a/src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c b/src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c index 123a1248f..7e05d6977 100644 --- a/src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c +++ b/src/overlays/actors/ovl_Bg_Iknin_Susceil/z_bg_iknin_susceil.c @@ -1,6 +1,13 @@ -#include "z_bg_iknin_susceil.h" +/* + * File: z_bg_iknin_susceil.c + * Overlay: ovl_Bg_Iknin_Susceil + * Description: Ikana Castle - Hot Checkered Ceiling + */ -#define FLAGS 0x00000030 +#include "z_bg_iknin_susceil.h" +#include "objects/object_ikninside_obj/object_ikninside_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgIkninSusceil*)thisx) @@ -20,10 +27,6 @@ void func_80C0AD44(BgIkninSusceil* this); void func_80C0AD64(BgIkninSusceil* this, GlobalContext* globalCtx); void func_80C0AE5C(BgIkninSusceil* this, GlobalContext* globalCtx); -extern CollisionHeader D_0600CBAC; -extern AnimatedMaterial D_0600C670; -extern Gfx D_0600C308[]; - const ActorInit Bg_Iknin_Susceil_InitVars = { ACTOR_BG_IKNIN_SUSCEIL, ACTORCAT_BG, @@ -51,9 +54,9 @@ s32 func_80C0A740(BgIkninSusceil* this, GlobalContext* globalCtx) { Vec3f offset; Player* player = GET_PLAYER(globalCtx); - Actor_CalcOffsetOrientedToDrawRotation(&this->dyna.actor, &offset, &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &offset, &player->actor.world.pos); - return (D_80C0B0E8.x < offset.z) && (offset.z < D_80C0B0E8.y) && (offset.x > -240.0f) && (offset.x < D_80C0B0E4); + return (D_80C0B0E8.x < offset.z) && (offset.z < D_80C0B0E8.z) && (offset.x > -240.0f) && (offset.x < D_80C0B0E4); } void func_80C0A804(BgIkninSusceil* this, GlobalContext* globalCtx) { @@ -88,7 +91,7 @@ s32 func_80C0A95C(BgIkninSusceil* this, GlobalContext* globalCtx) { Vec3f offset; f32 temp1, temp2, temp3, temp4; - Actor_CalcOffsetOrientedToDrawRotation(&this->dyna.actor, &offset, &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &offset, &player->actor.world.pos); for (i = 0; i < 7; i++) { temp3 = (D_80C0B0F0[i] * 80.0f) + 0.5f; temp4 = (D_80C0B0F0[i] * 80.0f) + 79.5f; @@ -109,16 +112,16 @@ void BgIkninSusceil_Init(Actor* thisx, GlobalContext* globalCtx) { BgIkninSusceil* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_0600CBAC); - this->animatedTexture = Lib_SegmentedToVirtual(&D_0600C670); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ikninside_obj_Colheader_00CBAC); + this->animatedTexture = Lib_SegmentedToVirtual(object_ikninside_obj_Matanimheader_00C670); func_80C0AC74(this); } void BgIkninSusceil_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgIkninSusceil* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void func_80C0AB14(BgIkninSusceil* this) { @@ -149,8 +152,8 @@ void func_80C0ABA8(BgIkninSusceil* this, GlobalContext* globalCtx) { this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; if (this->dyna.actor.world.pos.y <= this->dyna.actor.home.pos.y) { func_80C0A86C(this, globalCtx, 4, 14, 1); - Actor_UnsetSwitchFlag(globalCtx, GET_SUSCEIL_SWITCHFLAG(this)); - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BIGWALL_BOUND); + Flags_UnsetSwitch(globalCtx, GET_SUSCEIL_SWITCHFLAG(this)); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIGWALL_BOUND); func_80C0AC74(this); } else { func_800B9010(&this->dyna.actor, NA_SE_EV_ICE_PILLAR_FALL - SFX_FLAG); @@ -223,7 +226,7 @@ void BgIkninSusceil_Update(Actor* thisx, GlobalContext* globalCtx) { if ((this->unk168 == 0) && (this->unk166 > 0) && (player->stateFlags3 & 0x100) && (player->unk_B48 > 1000.0f)) { this->unk168 = 2; if ((func_80C0A95C(this, globalCtx) != 0) && (this->actionFunc != func_80C0AE5C)) { - func_800B8E58(&player->actor, NA_SE_PL_BODY_HIT); + func_800B8E58(player, NA_SE_PL_BODY_HIT); func_80C0AE3C(this); } } @@ -254,5 +257,5 @@ void BgIkninSusceil_Draw(Actor* thisx, GlobalContext* globalCtx) { BgIkninSusceil* this = THIS; AnimatedMat_Draw(globalCtx, this->animatedTexture); - func_800BDFC0(globalCtx, D_0600C308); + Gfx_DrawDListOpa(globalCtx, object_ikninside_obj_DL_00C308); } diff --git a/src/overlays/actors/ovl_Bg_Ikninside/z_bg_ikninside.c b/src/overlays/actors/ovl_Bg_Ikninside/z_bg_ikninside.c index f5c7ea607..a09bcba87 100644 --- a/src/overlays/actors/ovl_Bg_Ikninside/z_bg_ikninside.c +++ b/src/overlays/actors/ovl_Bg_Ikninside/z_bg_ikninside.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_ikninside.c + * Overlay: ovl_Bg_Ikninside + * Description: Ancient Castle of Ikana Objects + */ + #include "z_bg_ikninside.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIkninside*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Iknv_Doukutu/z_bg_iknv_doukutu.c b/src/overlays/actors/ovl_Bg_Iknv_Doukutu/z_bg_iknv_doukutu.c index 980d20f93..92a109925 100644 --- a/src/overlays/actors/ovl_Bg_Iknv_Doukutu/z_bg_iknv_doukutu.c +++ b/src/overlays/actors/ovl_Bg_Iknv_Doukutu/z_bg_iknv_doukutu.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_iknv_doukutu.c + * Overlay: ovl_Bg_Iknv_Doukutu + * Description: Sharp's Cave + */ + #include "z_bg_iknv_doukutu.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgIknvDoukutu*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c index caa4021f1..023b4b706 100644 --- a/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c +++ b/src/overlays/actors/ovl_Bg_Iknv_Obj/z_bg_iknv_obj.c @@ -1,6 +1,13 @@ -#include "z_bg_iknv_obj.h" +/* + * File: z_bg_iknv_obj.c + * Overlay: ovl_Bg_Iknv_Obj + * Description: Ikana - waterwheel, stone tower door, sakon's hideout door + */ -#define FLAGS 0x00000010 +#include "z_bg_iknv_obj.h" +#include "objects/object_iknv_obj/object_iknv_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgIknvObj*)thisx) @@ -14,12 +21,6 @@ void BgIknvObj_UpdateWaterwheel(BgIknvObj* this, GlobalContext* globalCtx); void BgIknvObj_UpdateRaisedDoor(BgIknvObj* this, GlobalContext* globalCtx); void BgIknvObj_UpdateSakonDoor(BgIknvObj* this, GlobalContext* globalCtx); -extern CollisionHeader D_060119D4; -extern CollisionHeader D_06012CA4; -extern Gfx D_06011880[]; -extern Gfx D_060129C8[]; -extern Gfx D_06013058[]; - const ActorInit Bg_Iknv_Obj_InitVars = { ACTOR_BG_IKNV_OBJ, ACTORCAT_BG, @@ -61,30 +62,30 @@ void BgIknvObj_Init(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc = BgIknvObj_DoNothing; switch (IKNV_OBJ_TYPE(this)) { case IKNV_OBJ_WATERWHEEL: - this->displayListPtr = D_06013058; + this->displayListPtr = object_iknv_obj_DL_013058; this->actionFunc = BgIknvObj_UpdateWaterwheel; - this->dyna.actor.flags |= 0x100000; - this->dyna.actor.flags |= 0x10; + this->dyna.actor.flags |= ACTOR_FLAG_100000; + this->dyna.actor.flags |= ACTOR_FLAG_10; break; case IKNV_OBJ_RAISED_DOOR: - this->displayListPtr = D_06011880; - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck_RelocateMeshHeader(&D_060119D4, &colHeader); - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + this->displayListPtr = object_iknv_obj_DL_011880; + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&object_iknv_obj_Colheader_0119D4, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); this->actionFunc = BgIknvObj_UpdateRaisedDoor; this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 120.0f; break; case IKNV_OBJ_SAKON_DOOR: - this->displayListPtr = D_060129C8; + this->displayListPtr = object_iknv_obj_DL_0129C8; this->actionFunc = BgIknvObj_UpdateSakonDoor; - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck_RelocateMeshHeader(&D_06012CA4, &colHeader); - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&object_iknv_obj_Colheader_012CA4, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); Collider_UpdateCylinder(&this->dyna.actor, &this->collider); this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; - gSaveContext.weekEventReg[51] &= (u8)~0x10; - Actor_SetHeight(&this->dyna.actor, IREG(88)); + gSaveContext.save.weekEventReg[51] &= (u8)~0x10; + Actor_SetFocus(&this->dyna.actor, IREG(88)); break; default: Actor_MarkForDeath(&this->dyna.actor); @@ -97,12 +98,12 @@ void BgIknvObj_Destroy(Actor* thisx, GlobalContext* globalCtx) { if (IKNV_OBJ_TYPE(this) != IKNV_OBJ_RAISED_DOOR) { if (IKNV_OBJ_TYPE(this) == IKNV_OBJ_SAKON_DOOR) { Collider_DestroyCylinder(globalCtx, &this->collider); - gSaveContext.weekEventReg[51] &= (u8)~0x10; + gSaveContext.save.weekEventReg[51] &= (u8)~0x10; } else { return; } } - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } s32 func_80BD7CEC(BgIknvObj* this) { @@ -124,14 +125,14 @@ s32 func_80BD7CEC(BgIknvObj* this) { } void BgIknvObj_UpdateWaterwheel(BgIknvObj* this, GlobalContext* globalCtx) { - if (gSaveContext.weekEventReg[14] & 4) { + if (gSaveContext.save.weekEventReg[14] & 4) { this->dyna.actor.shape.rot.z -= 0x64; func_800B9098(&this->dyna.actor); func_800B9010(&this->dyna.actor, NA_SE_EV_WOOD_WATER_WHEEL - SFX_FLAG); } - if ((globalCtx->csCtx.state != 0) && (gSaveContext.sceneSetupIndex == 1) && (globalCtx->csCtx.unk_12 == 4) && - (globalCtx->csCtx.frames == 0x5D7)) { + if ((globalCtx->csCtx.state != 0) && (gSaveContext.sceneSetupIndex == 1) && + (globalCtx->csCtx.currentCsIndex == 4) && (globalCtx->csCtx.frames == 1495)) { func_8019F128(NA_SE_EV_DOOR_UNLOCK); } } @@ -148,23 +149,23 @@ s32 func_80BD7E0C(BgIknvObj* this, s16 targetRotation, GlobalContext* globalCtx) func_800B9010(&this->dyna.actor, NA_SE_EV_STONEDOOR_OPEN_S - SFX_FLAG); return false; } - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_STOP); return true; } void func_80BD7ED8(BgIknvObj* this, GlobalContext* globalCtx) { if (func_80BD7E0C(this, this->dyna.actor.home.rot.y, globalCtx)) { this->actionFunc = BgIknvObj_UpdateSakonDoor; - gSaveContext.weekEventReg[51] &= (u8)~0x10; + gSaveContext.save.weekEventReg[51] &= (u8)~0x10; } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } void func_80BD7F4C(BgIknvObj* this, GlobalContext* globalCtx) { - if (gSaveContext.time > 0xD000) { + if (gSaveContext.save.time > CLOCK_TIME(19, 30)) { this->actionFunc = func_80BD7ED8; } - if ((this->dyna.actor.home.rot.x == 1) && !(gSaveContext.weekEventReg[58] & 0x80)) { + if ((this->dyna.actor.home.rot.x == 1) && !(gSaveContext.save.weekEventReg[58] & 0x80)) { ActorCutscene_Stop(this->dyna.actor.cutscene); this->dyna.actor.home.rot.x = 0; } @@ -174,7 +175,7 @@ void func_80BD7F4C(BgIknvObj* this, GlobalContext* globalCtx) { void func_80BD7FDC(BgIknvObj* this, GlobalContext* globalCtx) { if (func_80BD7E0C(this, this->dyna.actor.home.rot.y + 0x4000, globalCtx)) { this->actionFunc = func_80BD7F4C; - gSaveContext.weekEventReg[51] |= 0x10; + gSaveContext.save.weekEventReg[51] |= 0x10; this->dyna.actor.home.rot.x = 1; } } @@ -187,9 +188,9 @@ void func_80BD8040(BgIknvObj* this, GlobalContext* globalCtx) { } void BgIknvObj_UpdateSakonDoor(BgIknvObj* this, GlobalContext* globalCtx) { - if (gSaveContext.weekEventReg[58] & 0x80) { + if (gSaveContext.save.weekEventReg[58] & 0x80) { this->actionFunc = func_80BD8040; - gSaveContext.weekEventReg[89] |= 0x80; + gSaveContext.save.weekEventReg[89] |= 0x80; } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } diff --git a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c index d374c5fa1..11936a9d2 100644 --- a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c +++ b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.c @@ -1,6 +1,13 @@ -#include "z_bg_ingate.h" +/* + * File: z_bg_ingate.c + * Overlay: ovl_Bg_Ingate + * Description: Swamp Tour Boat + */ -#define FLAGS 0x00000030 +#include "z_bg_ingate.h" +#include "objects/object_sichitai_obj/object_sichitai_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgIngate*)thisx) @@ -9,7 +16,16 @@ void BgIngate_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgIngate_Update(Actor* thisx, GlobalContext* globalCtx); void BgIngate_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +Actor* BgIngate_FindActor(BgIngate* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId); +s32 func_80953BEC(BgIngate* this); +void func_80953B40(BgIngate* this); +void func_80953F8C(BgIngate* this, GlobalContext* globalCtx); +void func_80953F9C(BgIngate* this, GlobalContext* globalCtx); +void func_809541B8(BgIngate* this, GlobalContext* globalCtx); +void func_809542A0(BgIngate* this, GlobalContext* globalCtx); +void func_80954340(BgIngate* this, GlobalContext* globalCtx); +void func_809543D4(BgIngate* this, GlobalContext* globalCtx); + const ActorInit Bg_Ingate_InitVars = { ACTOR_BG_INGATE, ACTORCAT_BG, @@ -22,41 +38,354 @@ const ActorInit Bg_Ingate_InitVars = { (ActorFunc)BgIngate_Draw, }; -#endif +/** + * @brief Searches for an actor based on the parameters given to the function. Returns Actor* of actor found or NULL + * + * @param this + * @param globalCtx + * @param actorCat - Category of Actor + * @param actorId - ID of actor to search for + * @return Actor* + */ +Actor* BgIngate_FindActor(BgIngate* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* foundActor = NULL; + Actor* tempActor; -extern UNK_TYPE D_060006B0; -extern UNK_TYPE D_060016DC; + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, actorCat, actorId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953A90.s") + if ((foundActor == NULL) || (((this != (BgIngate*)foundActor)) && (foundActor->update != NULL))) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953B40.s") + tempActor = foundActor->next; + if (tempActor == NULL) { + foundActor = NULL; + break; + } + foundActor = tempActor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953BEC.s") + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953DA8.s") +void func_80953B40(BgIngate* this) { + s32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953E38.s") + if (!(gSaveContext.eventInf[3] & 0x20)) { + this->unk180 = 0xFA0; + this->unk168 = 4; + } else { + this->unk180 = 0x7D0; + this->unk168 = 1; + } + temp = this->unk164->count - 2; + this->unk184 = this->unk180 / temp; + this->unk188 = 2; + this->unk18C = 0; + this->unk160 &= ~0x1; + this->unk160 &= ~0x2; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953EA4.s") +s32 func_80953BEC(BgIngate* this) { + f32 sp74[265]; + Vec3f sp68; + Vec3f sp5C; + Vec3f unkVec; + s16 yaw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953F14.s") + func_8013AF00(sp74, 3, this->unk164->count + 3); + if (!(this->unk160 & 1)) { + unkVec = gZeroVec3f; + func_8013B6B0(this->unk164, &this->unk17C, &this->unk18C, this->unk184, this->unk180, &this->unk188, sp74, + &unkVec, this->unk168); + this->unk160 |= 1; + } else { + unkVec = this->unk170; + } + this->dyna.actor.world.pos.x = unkVec.x; + this->dyna.actor.world.pos.z = unkVec.z; + this->unk170 = gZeroVec3f; + if (func_8013B6B0(this->unk164, &this->unk17C, &this->unk18C, this->unk184, this->unk180, &this->unk188, sp74, + &this->unk170, this->unk168) != 0) { + this->unk160 |= 2; + } else { + sp68 = this->dyna.actor.world.pos; + sp5C = this->unk170; + yaw = Math_Vec3f_Yaw(&sp68, &sp5C); + this->dyna.actor.world.rot.y = yaw; + this->dyna.actor.shape.rot.y = yaw; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953F8C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80953F9C.s") +s32 func_80953DA8(BgIngate* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_809541B8.s") + if (gSaveContext.eventInf[3] & 0x20) { + func_800B7298(globalCtx, &this->dyna.actor, 7); + } else { + gSaveContext.eventInf[4] |= 2; + } + func_800DFAC8(camera, 47); + globalCtx->unk_1887C = 0x63; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_809542A0.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_80954340.s") +void func_80953E38(GlobalContext* globalCtx) { + func_800DFAC8(Play_GetCamera(globalCtx, CAM_ID_MAIN), 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/func_809543D4.s") + if (!(gSaveContext.eventInf[3] & 0x20)) { + gSaveContext.eventInf[4] &= (u8)~2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/BgIngate_Init.s") + globalCtx->unk_1887C = -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/BgIngate_Destroy.s") +void func_80953EA4(BgIngate* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/BgIngate_Update.s") + func_800B7298(globalCtx, &this->dyna.actor, 0x3A); + player->unk_3A0.x = this->dyna.actor.world.pos.x; + player->unk_3A0.z = this->dyna.actor.world.pos.z; + this->unk160 &= ~0x4; + this->unk16A = 0x1E; + this->actionFunc = func_80954340; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Ingate/BgIngate_Draw.s") +void func_80953F14(BgIngate* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.shape.rot.y = this->dyna.actor.shape.rot.y; + player->actor.world.rot.y = player->actor.shape.rot.y; + player->currentYaw = player->actor.shape.rot.y; + player->actor.focus.rot.y = player->actor.shape.rot.y; + this->unk160 |= 0x10; + func_80953DA8(this, globalCtx); + if (this->unk164 != NULL) { + func_80953B40(this); + } + this->unk16E = -1; + this->actionFunc = func_80953F9C; +} + +void func_80953F8C(BgIngate* this, GlobalContext* globalCtx) { +} + +void func_80953F9C(BgIngate* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + + if (!(gSaveContext.eventInf[4] & 1)) { + + if (!(gSaveContext.eventInf[3] & 0x20) && (this->unk160 & 0x10) && (this->unk16C == 0)) { + this->dyna.actor.textId = 0x9E3; + Message_StartTextbox(globalCtx, this->dyna.actor.textId, NULL); + this->unk160 &= ~0x10; + } + + if (this->unk160 & 2) { + + if (this->unk164->unk1 != 0xFF) { + func_80953E38(globalCtx); + func_800B7298(globalCtx, &this->dyna.actor, 7); + this->dyna.actor.textId = 0x9E4; + Message_StartTextbox(globalCtx, this->dyna.actor.textId, NULL); + this->unk16C += 1; + gSaveContext.save.weekEventReg[90] |= 0x40; + this->actionFunc = func_809543D4; + } else { + + if (!(gSaveContext.eventInf[3] & 0x20)) { + gSaveContext.eventInf[4] &= (u8)~2; + } else { + gSaveContext.eventInf[4] |= 1; + } + this->actionFunc = func_809542A0; + } + } else if ((ActorCutscene_GetCurrentIndex() == -1) && (this->unk164 != NULL)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_CRUISER - SFX_FLAG); + func_80953BEC(this); + } + } + if (ActorCutscene_GetCurrentIndex() != this->unk16E) { + if (ActorCutscene_GetCurrentIndex() != -1) { + func_800DFAC8(camera, 1); + player->stateFlags1 |= 0x20; + globalCtx->actorCtx.unk5 &= ~0x4; + } else { + func_800DFAC8(camera, 47); + player->stateFlags1 &= ~0x20; + } + } + this->unk16E = ActorCutscene_GetCurrentIndex(); +} + +void func_809541B8(BgIngate* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk160 & 0x4) { + if ((player->transformation == PLAYER_FORM_HUMAN) && (player->actor.bgCheckFlags & 1) && + (this->dyna.actor.xzDistToPlayer < 40.0f)) { + if (this->dyna.actor.playerHeightRel > 15.0f) { + func_800B7298(globalCtx, &this->dyna.actor, 7); + this->dyna.actor.textId = 0x9E6; + Message_StartTextbox(globalCtx, this->dyna.actor.textId, NULL); + this->actionFunc = func_809543D4; + } + } + } else if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + this->unk160 |= 4; + } +} + +void func_809542A0(BgIngate* this, GlobalContext* globalCtx) { + if (gSaveContext.eventInf[5] & 1) { + globalCtx->nextEntranceIndex = 0xA820; + gSaveContext.eventInf[5] &= (u8)~1; + } else { + globalCtx->nextEntranceIndex = 0xA810; + } + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + this->actionFunc = func_80953F8C; + gSaveContext.save.weekEventReg[90] &= (u8)~0x40; + func_800FE498(); +} + +void func_80954340(BgIngate* this, GlobalContext* globalCtx) { + if (!DECR(this->unk16A)) { + if (this->unk164 != NULL) { + func_800B7298(globalCtx, &this->dyna.actor, 6); + this->unk164 = &globalCtx->setupPathList[this->unk164->unk1]; + func_80953F14(this, globalCtx); + func_800FE484(); + } + } +} + +void func_809543D4(BgIngate* this, GlobalContext* globalCtx) { + u8 talkState = Message_GetState(&globalCtx->msgCtx); + + if (((talkState == 4) || (talkState == 5)) && Message_ShouldAdvance(globalCtx)) { + switch (this->dyna.actor.textId) { + case 0x9E4: + this->dyna.actor.textId = 0x9E5; + func_80151938(globalCtx, this->dyna.actor.textId); + break; + case 0x9E5: + if (globalCtx->msgCtx.choiceIndex == 0) { + func_800B7298(globalCtx, &this->dyna.actor, 6); + this->unk160 &= ~0x4; + this->actionFunc = func_809541B8; + func_800FE498(); + func_8019F208(); + } else { + if (this->unk164 != NULL) { + this->unk164 = &globalCtx->setupPathList[this->unk164->unk1]; + } + func_80953F14(this, globalCtx); + gSaveContext.save.weekEventReg[90] &= (u8)~0x40; + func_8019F230(); + } + func_801477B4(globalCtx); + break; + case 0x9E6: + if (globalCtx->msgCtx.choiceIndex == 0) { + func_80953EA4(this, globalCtx); + gSaveContext.save.weekEventReg[90] &= (u8)~0x40; + func_8019F208(); + } else { + func_800B7298(globalCtx, &this->dyna.actor, 6); + this->unk160 &= ~0x4; + this->actionFunc = func_809541B8; + func_800FE498(); + func_8019F230(); + } + func_801477B4(globalCtx); + break; + } + } +} + +void BgIngate_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + BgIngate* this = THIS; + s32 phi_a2; + Vec3s* sp38; + Vec3f sp2C; + Vec3f sp20; + + if (BgIngate_FindActor(this, globalCtx, ACTORCAT_BG, ACTOR_BG_INGATE) == NULL) { + DynaPolyActor_Init(&this->dyna, 3); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gSichitaiBoatCol); + this->unk160 = 0; + this->unk160 |= 0x8; + this->unk160 |= 0x10; + Actor_SetScale(&this->dyna.actor, 1.0f); + this->unk164 = SubS_GetAdditionalPath(globalCtx, BGINGATE_GET_FF(&this->dyna.actor), 0); + this->dyna.actor.room = -1; + if (gSaveContext.save.weekEventReg[20] & 2) { + gSaveContext.save.weekEventReg[90] &= (u8)~0x40; + } + if (!(gSaveContext.eventInf[3] & 0x20) && (gSaveContext.save.weekEventReg[90] & 0x40)) { + phi_a2 = 1; + this->unk16C = 1; + this->actionFunc = func_809541B8; + } else { + phi_a2 = 0; + if (globalCtx->curSpawn == 6) { + func_80953F14(this, globalCtx); + if (gSaveContext.eventInf[3] & 0x20) { + func_80112AFC(globalCtx); + } else { + gSaveContext.eventInf[4] |= 2; + } + } else { + this->actionFunc = func_80953F8C; + } + } + this->unk164 = SubS_GetAdditionalPath(globalCtx, BGINGATE_GET_FF(&this->dyna.actor), phi_a2); + if (this->unk164 != NULL) { + sp38 = Lib_SegmentedToVirtual(this->unk164->points); + Math_Vec3s_ToVec3f(&sp2C, &sp38[0]); + Math_Vec3s_ToVec3f(&sp20, &sp38[1]); + this->dyna.actor.world.rot.y = Math_Vec3f_Yaw(&sp2C, &sp20); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + this->dyna.actor.world.pos.x = sp2C.x; + this->dyna.actor.world.pos.y = -15.0f; + this->dyna.actor.world.pos.z = sp2C.z; + } + this->unk164 = SubS_GetAdditionalPath(globalCtx, BGINGATE_GET_FF(&this->dyna.actor), 0); + } else { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void BgIngate_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgIngate* this = THIS; + + if (this->unk160 & 8) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} + +void BgIngate_Update(Actor* thisx, GlobalContext* globalCtx) { + BgIngate* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgIngate_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++, gSichitaiBoat); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.h b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.h index 8daa69d91..08d062e6c 100644 --- a/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.h +++ b/src/overlays/actors/ovl_Bg_Ingate/z_bg_ingate.h @@ -7,11 +7,23 @@ struct BgIngate; typedef void (*BgIngateActionFunc)(struct BgIngate*, GlobalContext*); +#define BGINGATE_GET_FF(thisx) ((thisx)->params & 0xFF) + typedef struct BgIngate { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ BgIngateActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x30]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgIngateActionFunc actionFunc; + /* 0x160 */ u16 unk160; + /* 0x164 */ Path* unk164; + /* 0x168 */ s16 unk168; + /* 0x16A */ s16 unk16A; + /* 0x16C */ s16 unk16C; + /* 0x16E */ s16 unk16E; + /* 0x170 */ Vec3f unk170; + /* 0x17C */ f32 unk17C; + /* 0x180 */ s32 unk180; + /* 0x184 */ s32 unk184; + /* 0x188 */ s32 unk188; + /* 0x18C */ s32 unk18C; } BgIngate; // size = 0x190 extern const ActorInit Bg_Ingate_InitVars; 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 f31b9da3b..9ae16fb1c 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 @@ -1,6 +1,13 @@ -#include "z_bg_inibs_movebg.h" +/* + * File: z_bg_inibs_movebg.c + * Overlay: ovl_Bg_Inibs_Movebg + * Description: Twinmold Arena + */ -#define FLAGS 0x00000030 +#include "z_bg_inibs_movebg.h" +#include "objects/object_inibs_object/object_inibs_object.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgInibsMovebg*)thisx) @@ -8,7 +15,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, @@ -21,17 +27,50 @@ const ActorInit Bg_Inibs_Movebg_InitVars = { (ActorFunc)BgInibsMovebg_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B96578[] = { +Gfx* D_80B96560[] = { object_inibs_object_DL_0062D8, object_inibs_object_DL_001DC0 }; +Gfx* D_80B96568[] = { object_inibs_object_DL_006140, object_inibs_object_DL_001C10 }; +AnimatedMaterial* D_80B96570[] = { object_inibs_object_Matanimheader_006858, object_inibs_object_Matanimheader_002598 }; + +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) { + Gfx_DrawDListOpa(globalCtx, this->unk_15C); + } + + dl2 = this->unk_160; + if (dl2 != NULL) { + Gfx_DrawDListXlu(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_Keikoku_Saku/z_bg_keikoku_saku.c b/src/overlays/actors/ovl_Bg_Keikoku_Saku/z_bg_keikoku_saku.c index b5ba51a05..0e7488a9a 100644 --- a/src/overlays/actors/ovl_Bg_Keikoku_Saku/z_bg_keikoku_saku.c +++ b/src/overlays/actors/ovl_Bg_Keikoku_Saku/z_bg_keikoku_saku.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_keikoku_saku.c + * Overlay: ovl_Bg_Keikoku_Saku + * Description: Termina Field Spiked Fence + */ + #include "z_bg_keikoku_saku.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Keikoku_Spr/z_bg_keikoku_spr.c b/src/overlays/actors/ovl_Bg_Keikoku_Spr/z_bg_keikoku_spr.c index 3d47988b9..28cea492c 100644 --- a/src/overlays/actors/ovl_Bg_Keikoku_Spr/z_bg_keikoku_spr.c +++ b/src/overlays/actors/ovl_Bg_Keikoku_Spr/z_bg_keikoku_spr.c @@ -5,6 +5,7 @@ */ #include "z_bg_keikoku_spr.h" +#include "objects/object_keikoku_obj/object_keikoku_obj.h" #define FLAGS 0x00000000 @@ -34,13 +35,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 20, ICHAIN_STOP), }; -extern Gfx D_06000100[]; -extern AnimatedMaterial D_060001F8; -extern Gfx D_06000300[]; -extern AnimatedMaterial D_060003F8; -extern Gfx D_06000500[]; -extern AnimatedMaterial D_060005F8; - void BgKeikokuSpr_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(thisx, sInitChain); } @@ -56,13 +50,13 @@ void BgKeikokuSpr_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_060001F8)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_keikoku_obj_Matanimheader_0001F8)); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_06000100); - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_060003F8)); - gSPDisplayList(POLY_XLU_DISP++, D_06000300); - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_060005F8)); - gSPDisplayList(POLY_XLU_DISP++, D_06000500); + gSPDisplayList(POLY_XLU_DISP++, object_keikoku_obj_DL_000100); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_keikoku_obj_Matanimheader_0003F8)); + gSPDisplayList(POLY_XLU_DISP++, object_keikoku_obj_DL_000300); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_keikoku_obj_Matanimheader_0005F8)); + gSPDisplayList(POLY_XLU_DISP++, object_keikoku_obj_DL_000500); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Bg_Kin2_Bombwall/z_bg_kin2_bombwall.c b/src/overlays/actors/ovl_Bg_Kin2_Bombwall/z_bg_kin2_bombwall.c index 116d6d5f7..5630bdd8f 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Bombwall/z_bg_kin2_bombwall.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Bombwall/z_bg_kin2_bombwall.c @@ -1,6 +1,12 @@ +/* + * File: z_bg_kin2_bombwall.c + * Overlay: ovl_Bg_Kin2_Bombwall + * Description: Ocean Spider House - Bombable Wall + */ + #include "z_bg_kin2_bombwall.h" -#define FLAGS 0x10000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_10000000) #define THIS ((BgKin2Bombwall*)thisx) 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 2d1fb8ca2..37d176f5a 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 @@ -1,6 +1,13 @@ -#include "z_bg_kin2_fence.h" +/* + * File: z_bg_kin2_fence.c + * Overlay: ovl_Bg_Kin2_Fence + * Description: Ocean Spider House - Fireplace Grate + */ -#define FLAGS 0x00000010 +#include "z_bg_kin2_fence.h" +#include "objects/object_kin2_obj/object_kin2_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgKin2Fence*)thisx) @@ -112,22 +119,19 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_06000828[]; -extern CollisionHeader D_06000908; - s32 BgKin2Fence_CheckHitMask(BgKin2Fence* this) { ColliderJntSphElement* elements = this->collider.elements; - if (elements[0].info.bumperFlags & 2) { + if (elements[0].info.bumperFlags & BUMP_HIT) { return 0; } - if (elements[1].info.bumperFlags & 2) { + if (elements[1].info.bumperFlags & BUMP_HIT) { return 1; } - if (elements[2].info.bumperFlags & 2) { + if (elements[2].info.bumperFlags & BUMP_HIT) { return 2; } - if (elements[3].info.bumperFlags & 2) { + if (elements[3].info.bumperFlags & BUMP_HIT) { return 3; } return -1; @@ -138,12 +142,12 @@ void BgKin2Fence_SpawnEyeSparkles(BgKin2Fence* this, GlobalContext* globalCtx, s Vec3f sp58; s32 pad[2]; - Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, - this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); for (i = 0; i < 2; i++) { - Matrix_MultiplyVector3fByState(&eyeSparkleSpawnPositions[mask][i], &sp58); - EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 6000, -10); + Matrix_MultVec3f(&eyeSparkleSpawnPositions[mask][i], &sp58); + EffectSsKirakira_SpawnDispersed(globalCtx, &sp58, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 6000, -10); } } @@ -152,12 +156,12 @@ void BgKin2Fence_Init(Actor* thisx, GlobalContext* globalCtx) { s32 i = 0; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000908); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_kin2_obj_Colheader_000908); Collider_InitJntSph(globalCtx, &this->collider); Collider_SetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, this->colliderElements); - Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, - this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); for (i = 0; i < 4; i++) { @@ -174,7 +178,7 @@ void BgKin2Fence_Init(Actor* thisx, GlobalContext* globalCtx) { void BgKin2Fence_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgKin2Fence* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyJntSph(globalCtx, &this->collider); } @@ -190,7 +194,7 @@ void BgKin2Fence_HandleMaskCode(BgKin2Fence* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { hitMask = BgKin2Fence_CheckHitMask(this); if (hitMask >= 0) { - nextMask = (s8)gSaveContext.spiderHouseMaskOrder[this->masksHit]; + nextMask = (s8)gSaveContext.save.spiderHouseMaskOrder[this->masksHit]; if (hitMask == nextMask) { play_sound(NA_SE_SY_TRE_BOX_APPEAR); this->masksHit += 1; @@ -222,7 +226,7 @@ void BgKin2Fence_SetupPlayOpenCutscene(BgKin2Fence* this) { void BgKin2Fence_PlayOpenCutscene(BgKin2Fence* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); - Actor_SetSwitchFlag(globalCtx, this->dyna.actor.params & 0x7F); + Flags_SetSwitch(globalCtx, this->dyna.actor.params & 0x7F); BgKin2Fence_SetupWaitBeforeOpen(this); return; } @@ -266,5 +270,5 @@ void BgKin2Fence_Update(Actor* thisx, GlobalContext* globalCtx) { } void BgKin2Fence_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000828); + Gfx_DrawDListOpa(globalCtx, object_kin2_obj_DL_000828); } diff --git a/src/overlays/actors/ovl_Bg_Kin2_Picture/z_bg_kin2_picture.c b/src/overlays/actors/ovl_Bg_Kin2_Picture/z_bg_kin2_picture.c index 01ec6fcda..e9326d8cd 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Picture/z_bg_kin2_picture.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Picture/z_bg_kin2_picture.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_kin2_picture.c + * Overlay: ovl_Bg_Kin2_Picture + * Description: Ocean Spider House - Skullkid Painting + */ + #include "z_bg_kin2_picture.h" #define FLAGS 0x00000000 @@ -49,7 +55,7 @@ static ColliderTrisInit D_80B6FA08 = { // static InitChainEntry sInitChain[] = { static InitChainEntry D_80B6FA24[] = { ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), diff --git a/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.c b/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.c index a9c0a2dec..499fb034a 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_kin2_shelf.c + * Overlay: ovl_Bg_Kin2_Shelf + * Description: Ocean Spider House - Drawers + */ + #include "z_bg_kin2_shelf.h" +#include "objects/object_kin2_obj/object_kin2_obj.h" #define FLAGS 0x00000000 @@ -9,7 +16,13 @@ void BgKin2Shelf_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgKin2Shelf_Update(Actor* thisx, GlobalContext* globalCtx); void BgKin2Shelf_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B700A8(BgKin2Shelf* this); +void func_80B700C0(BgKin2Shelf* this, GlobalContext* globalCtx); +void func_80B70214(BgKin2Shelf* this); +void func_80B70230(BgKin2Shelf* this, GlobalContext* globalCtx); +void func_80B70498(BgKin2Shelf* this); +void func_80B704B4(BgKin2Shelf* this, GlobalContext* globalCtx); + const ActorInit Bg_Kin2_Shelf_InitVars = { ACTOR_BG_KIN2_SHELF, ACTORCAT_BG, @@ -22,43 +35,345 @@ const ActorInit Bg_Kin2_Shelf_InitVars = { (ActorFunc)BgKin2Shelf_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B7077C[] = { +f32 D_80B70750[] = { 60.0f, 120.0f }; + +f32 D_80B70758[] = { 40.0f, 0.0f }; + +f32 D_80B70760[] = { 10.0f, 15.0f }; + +f32 D_80B70768[] = { 15.0f, 60.0f }; + +f32 D_80B70770[] = { 10.0f, 15.0f }; + +u8 D_80B70778[] = { 0x0F, 0x0A }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_STOP), }; -#endif +CollisionHeader* D_80B70780[] = { &object_kin2_obj_Colheader_001328, &object_kin2_obj_Colheader_000F80 }; -extern InitChainEntry D_80B7077C[]; +Gfx* D_80B70788[] = { object_kin2_obj_DL_0010F8, object_kin2_obj_DL_000CA8 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FB30.s") +s32 func_80B6FB30(BgKin2Shelf* this, GlobalContext* globalCtx) { + s32 temp_v1 = BGKIN2SHELF_GET_1(&this->dyna.actor); + f32 phi_f0; + f32 spA4; + s16 spA2; + Vec3f sp94; + Vec3f sp88; + Vec3f sp7C; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + CollisionPoly* sp54; + s32 sp50; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FCA4.s") + if (this->unk_164 & 2) { + spA2 = 0x4000; + } else { + spA2 = -0x4000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FE08.s") + spA4 = D_80B70750[temp_v1] + ((this->dyna.pushForce < 0.0f) ? 28.0f : -2.0f) + D_80B70768[temp_v1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FE48.s") + Matrix_Translate(0.0f, 10.0f, D_80B70760[temp_v1], MTXMODE_NEW); + Matrix_RotateYS(spA2, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FEBC.s") + sp58.x = 0.0f; + sp58.y = 0.0f; + sp58.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B6FF28.s") + Matrix_MultVec3f(&sp58, &sp94); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/BgKin2Shelf_Init.s") + sp58.z = spA4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/BgKin2Shelf_Destroy.s") + Matrix_MultVec3f(&sp58, &sp88); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_MultVec3f(&sp94, &sp7C); + Matrix_MultVec3f(&sp88, &sp70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B700A8.s") + return BgCheck_EntityLineTest3(&globalCtx->colCtx, &sp7C, &sp70, &sp64, &sp54, true, false, false, true, &sp50, + &this->dyna.actor, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B700C0.s") +s32 func_80B6FCA4(BgKin2Shelf* this, GlobalContext* globalCtx) { + s32 pad; + f32 spA0; + s16 sp9E; + Vec3f sp90; + Vec3f sp84; + Vec3f sp78; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + CollisionPoly* sp50; + s32 sp4C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B70214.s") + if (this->unk_164 & 1) { + sp9E = 0; + } else { + sp9E = -0x8000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B70230.s") + spA0 = D_80B70758[0] + ((this->dyna.pushForce < 0.0f) ? 28.0f : -2.0f) + D_80B70770[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B70498.s") + Matrix_Translate(0.0f, 10.0f, *D_80B70760, MTXMODE_NEW); + Matrix_RotateYS(sp9E, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/func_80B704B4.s") + sp54.x = 0.0f; + sp54.y = 0.0f; + sp54.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/BgKin2Shelf_Update.s") + Matrix_MultVec3f(&sp54, &sp90); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Kin2_Shelf/BgKin2Shelf_Draw.s") + sp54.z = spA0; + + Matrix_MultVec3f(&sp54, &sp84); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_MultVec3f(&sp90, &sp78); + Matrix_MultVec3f(&sp84, &sp6C); + + return BgCheck_EntityLineTest3(&globalCtx->colCtx, &sp78, &sp6C, &sp60, &sp50, true, false, false, true, &sp4C, + &this->dyna.actor, 0.0f); +} + +s32 func_80B6FE08(BgKin2Shelf* this, GlobalContext* globalCtx) { + if (this->unk_164 & (0x8 | 0x2)) { + return func_80B6FB30(this, globalCtx); + } + return func_80B6FCA4(this, globalCtx); +} + +s32 func_80B6FE48(BgKin2Shelf* this, GlobalContext* globalCtx) { + s32 params = BGKIN2SHELF_GET_1(&this->dyna.actor); + u8 temp_v1 = D_80B70778[params] & this->unk_164; + + if ((this->unk_166 != 0) && (this->unk_167 != 0)) { + return false; + } + + if ((this->unk_166 == 0) && (this->unk_167 == 0)) { + return temp_v1 != 0; + } + + if (this->unk_166 != 0) { + return temp_v1 & (0x8 | 0x2); + } + + return temp_v1 & 5; +} + +s32 func_80B6FEBC(BgKin2Shelf* this, GlobalContext* globalCtx) { + if (this->unk_164 & 1) { + return this->unk_167 < 1; + } + + if (this->unk_164 & 2) { + return this->unk_166 < 1; + } + + if (this->unk_164 & 4) { + return this->unk_167 >= 0; + } + + if (this->unk_164 & 8) { + return this->unk_166 >= 0; + } + return false; +} + +s32 func_80B6FF28(BgKin2Shelf* this, GlobalContext* globalCtx) { + return (this->unk_165 > 8) && func_80B6FE48(this, globalCtx) && func_80B6FEBC(this, globalCtx) && + !func_80B6FE08(this, globalCtx); +} + +void BgKin2Shelf_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgKin2Shelf* this = THIS; + s32 sp24 = BGKIN2SHELF_GET_1(&this->dyna.actor); + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + if (sp24 == 0) { + this->dyna.actor.uncullZoneScale = 150.0f; + this->dyna.actor.uncullZoneDownward = 140.0f; + Actor_SetScale(&this->dyna.actor, 0.1f); + } else { + this->dyna.actor.uncullZoneScale = 250.0f; + this->dyna.actor.uncullZoneDownward = 300.0f; + Actor_SetScale(&this->dyna.actor, 1.0f); + this->dyna.actor.flags |= ACTOR_FLAG_10000000; + } + + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, D_80B70780[sp24]); + func_80B700A8(this); +} + +void BgKin2Shelf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgKin2Shelf* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80B700A8(BgKin2Shelf* this) { + this->unk_165 = 0; + this->actionFunc = func_80B700C0; +} + +void func_80B700C0(BgKin2Shelf* this, GlobalContext* globalCtx) { + s16 temp_v0; + u8 phi_v0_2; + + if (fabsf(this->dyna.pushForce) > 0.1f) { + temp_v0 = this->dyna.yRotation - this->dyna.actor.shape.rot.y; + if (this->dyna.pushForce < 0.0f) { + temp_v0 = BINANG_ROT180(temp_v0); + } + + if ((temp_v0 < -0x6000) || (temp_v0 >= 0x6000)) { + phi_v0_2 = 4; + } else if (temp_v0 < -0x2000) { + phi_v0_2 = 8; + } else if (temp_v0 < 0x2000) { + phi_v0_2 = 1; + } else { + phi_v0_2 = 2; + } + + if ((phi_v0_2 == this->unk_164) || (this->unk_164 == 0)) { + this->unk_164 = phi_v0_2; + this->unk_165++; + } else { + this->unk_165 = 0; + this->unk_164 = 0; + } + + if (func_80B6FF28(this, globalCtx)) { + if (this->unk_164 & (0x8 | 0x2)) { + func_80B70214(this); + } else { + func_80B70498(this); + } + } else { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + } else { + this->unk_165 = 0; + this->unk_164 = 0; + } +} + +void func_80B70214(BgKin2Shelf* this) { + this->unk_160 = 0.0f; + this->actionFunc = func_80B70230; +} + +void func_80B70230(BgKin2Shelf* this, GlobalContext* globalCtx) { + f32 phi_f20; + s32 sp40 = BGKIN2SHELF_GET_1(&this->dyna.actor); + f32 phi_f2; + s32 pad; + s16 sp36 = BINANG_ADD(this->dyna.actor.shape.rot.y, 0x4000); + + if ((BGKIN2SHELF_GET_1(&this->dyna.actor)) == 0) { + phi_f2 = (Math_SinS(this->unk_160 * 0x8000) * 0.012f) + 0.014f; + } else { + phi_f2 = (Math_SinS(this->unk_160 * 0x8000) * 0.003f) + 0.009f; + } + this->unk_160 += phi_f2; + + if (this->unk_160 >= 1.0f) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_160 = 1.0f; + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + if (this->unk_164 & 8) { + this->unk_166--; + } else { + this->unk_166++; + } + + phi_f20 = this->unk_166; + + this->dyna.actor.world.pos.x = ((Math_SinS(sp36) * phi_f20) * D_80B70750[sp40]) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = ((Math_CosS(sp36) * phi_f20) * D_80B70750[sp40]) + this->dyna.actor.home.pos.z; + + if (this->unk_166 != 0) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + func_80B700A8(this); + } else { + if (this->unk_164 & 8) { + phi_f20 = this->unk_166 - this->unk_160; + } else { + phi_f20 = this->unk_166 + this->unk_160; + } + this->dyna.actor.world.pos.x = ((Math_SinS(sp36) * phi_f20) * D_80B70750[sp40]) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = ((Math_CosS(sp36) * phi_f20) * D_80B70750[sp40]) + this->dyna.actor.home.pos.z; + } +} + +void func_80B70498(BgKin2Shelf* this) { + this->unk_160 = 0.0f; + this->actionFunc = func_80B704B4; +} + +void func_80B704B4(BgKin2Shelf* this, GlobalContext* globalCtx) { + f32 temp_f20; + s32 sp40 = BGKIN2SHELF_GET_1(&this->dyna.actor); + f32 phi_f20; + s32 pad; + s16 sp36 = this->dyna.actor.shape.rot.y; + + this->unk_160 += (Math_SinS(this->unk_160 * 0x8000) * 0.022f) + 0.022f; + + if (this->unk_160 >= 1.0f) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_160 = 1.0f; + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + if (this->unk_164 & 4) { + this->unk_167--; + } else { + this->unk_167++; + } + + temp_f20 = this->unk_167; + this->dyna.actor.world.pos.x = ((Math_SinS(sp36) * temp_f20) * D_80B70758[sp40]) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = ((Math_CosS(sp36) * temp_f20) * D_80B70758[sp40]) + this->dyna.actor.home.pos.z; + + if (this->unk_167 != 0) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + func_80B700A8(this); + } else { + if (this->unk_164 & 4) { + temp_f20 = this->unk_167 - this->unk_160; + } else { + temp_f20 = this->unk_167 + this->unk_160; + } + this->dyna.actor.world.pos.x = ((Math_SinS(sp36) * temp_f20) * D_80B70758[sp40]) + this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.z = ((Math_CosS(sp36) * temp_f20) * D_80B70758[sp40]) + this->dyna.actor.home.pos.z; + } +} + +void BgKin2Shelf_Update(Actor* thisx, GlobalContext* globalCtx) { + BgKin2Shelf* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void BgKin2Shelf_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, D_80B70788[BGKIN2SHELF_GET_1(thisx)]); +} diff --git a/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.h b/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.h index d5cf40c2f..29a295851 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.h +++ b/src/overlays/actors/ovl_Bg_Kin2_Shelf/z_bg_kin2_shelf.h @@ -7,11 +7,16 @@ struct BgKin2Shelf; typedef void (*BgKin2ShelfActionFunc)(struct BgKin2Shelf*, GlobalContext*); +#define BGKIN2SHELF_GET_1(thisx) ((thisx)->params & 1) + typedef struct BgKin2Shelf { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ BgKin2ShelfActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x8]; + /* 0x0160 */ f32 unk_160; + /* 0x0164 */ u8 unk_164; + /* 0x0165 */ s8 unk_165; + /* 0x0166 */ s8 unk_166; + /* 0x0167 */ s8 unk_167; } BgKin2Shelf; // size = 0x168 extern const ActorInit Bg_Kin2_Shelf_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Ladder/z_bg_ladder.c b/src/overlays/actors/ovl_Bg_Ladder/z_bg_ladder.c index 0c391f43b..de9b891ac 100644 --- a/src/overlays/actors/ovl_Bg_Ladder/z_bg_ladder.c +++ b/src/overlays/actors/ovl_Bg_Ladder/z_bg_ladder.c @@ -5,8 +5,9 @@ */ #include "z_bg_ladder.h" +#include "objects/object_ladder/object_ladder.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgLadder*)thisx) @@ -19,16 +20,6 @@ void BgLadder_ActionStartCutscene(BgLadder* this, GlobalContext* globalCtx); void BgLadder_ActionFadeIn(BgLadder* this, GlobalContext* globalCtx); void BgLadder_ActionIdle(BgLadder* this, GlobalContext* globalCtx); -extern Gfx D_060000A0[]; -extern Gfx D_060002D0[]; -extern Gfx D_06000500[]; -extern Gfx D_06000730[]; - -extern CollisionHeader D_060001D8; -extern CollisionHeader D_06000408; -extern CollisionHeader D_06000638; -extern CollisionHeader D_06000868; - const ActorInit Bg_Ladder_InitVars = { ACTOR_BG_LADDER, ACTORCAT_PROP, @@ -46,10 +37,10 @@ static InitChainEntry sInitChain[] = { }; static Gfx* sLadderDLists[] = { - D_060000A0, // 12 Rung - D_060002D0, // 16 Rung - D_06000500, // 20 Rung - D_06000730, // 24 Rung + object_ladder_DL_0000A0, // 12 Rung + object_ladder_DL_0002D0, // 16 Rung + object_ladder_DL_000500, // 20 Rung + object_ladder_DL_000730, // 24 Rung }; void BgLadder_Init(Actor* thisx, GlobalContext* globalCtx) { @@ -61,17 +52,17 @@ void BgLadder_Init(Actor* thisx, GlobalContext* globalCtx) { // Has to be `thisx` instead of `&this->actor` to match this->switchFlag = GET_BGLADDER_SWITCHFLAG(thisx); thisx->params = GET_BGLADDER_SIZE(thisx); - BcCheck3_BgActorInit(&this->dyna, 0); + DynaPolyActor_Init(&this->dyna, 0); size = thisx->params; if (size == LADDER_SIZE_12RUNG) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060001D8); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ladder_Colheader_0001D8); } else if (size == LADDER_SIZE_16RUNG) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000408); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ladder_Colheader_000408); } else if (size == LADDER_SIZE_20RUNG) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000638); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ladder_Colheader_000638); } else if (size == LADDER_SIZE_24RUNG) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000868); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ladder_Colheader_000868); } else { Actor_MarkForDeath(&this->dyna.actor); return; @@ -80,7 +71,7 @@ void BgLadder_Init(Actor* thisx, GlobalContext* globalCtx) { if (Flags_GetSwitch(globalCtx, this->switchFlag)) { // If the flag is set, then the ladder draws immediately this->alpha = 255; - this->dyna.actor.flags &= ~0x10; // always update = off + this->dyna.actor.flags &= ~ACTOR_FLAG_10; // always update = off this->action = BgLadder_ActionIdle; } else { // Otherwise, the ladder doesn't draw; wait for the flag to be set @@ -94,7 +85,7 @@ void BgLadder_Init(Actor* thisx, GlobalContext* globalCtx) { void BgLadder_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgLadder* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgLadder_ActionWait(BgLadder* this, GlobalContext* globalCtx) { @@ -110,7 +101,7 @@ void BgLadder_ActionStartCutscene(BgLadder* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); this->dyna.actor.draw = BgLadder_Draw; - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_SECRET_LADDER_APPEAR); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SECRET_LADDER_APPEAR); this->action = BgLadder_ActionFadeIn; } else { ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); @@ -124,7 +115,7 @@ void BgLadder_ActionFadeIn(BgLadder* this, GlobalContext* globalCtx) { this->alpha = 255; ActorCutscene_Stop(this->dyna.actor.cutscene); func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); - this->dyna.actor.flags &= ~0x10; // always update = off + this->dyna.actor.flags &= ~ACTOR_FLAG_10; // always update = off this->action = BgLadder_ActionIdle; } } diff --git a/src/overlays/actors/ovl_Bg_Last_Bwall/z_bg_last_bwall.c b/src/overlays/actors/ovl_Bg_Last_Bwall/z_bg_last_bwall.c index 3e1eb0d0c..0e3a88029 100644 --- a/src/overlays/actors/ovl_Bg_Last_Bwall/z_bg_last_bwall.c +++ b/src/overlays/actors/ovl_Bg_Last_Bwall/z_bg_last_bwall.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_last_bwall.c + * Overlay: ovl_Bg_Last_Bwall + * Description: Link Moon Dungeon - Bombable, Climbable Wall + */ + #include "z_bg_last_bwall.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Bg_Lbfshot/z_bg_lbfshot.c b/src/overlays/actors/ovl_Bg_Lbfshot/z_bg_lbfshot.c index 673f41e20..b0ad9d32e 100644 --- a/src/overlays/actors/ovl_Bg_Lbfshot/z_bg_lbfshot.c +++ b/src/overlays/actors/ovl_Bg_Lbfshot/z_bg_lbfshot.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_lbfshot.c + * Overlay: ovl_Bg_Lbfshot + * Description: Rainbow Hookshot Pillar + */ + #include "z_bg_lbfshot.h" +#include "objects/object_lbfshot/object_lbfshot.h" #define FLAGS 0x00000000 @@ -24,22 +31,19 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_060014D8; -extern Gfx D_06000228[]; - void BgLbfshot_Init(Actor* thisx, GlobalContext* globalCtx) { BgLbfshot* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); this->dyna.actor.uncullZoneForward = 4000.0f; - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060014D8); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_lbfshot_Colheader_0014D8); } void BgLbfshot_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgLbfshot* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgLbfshot_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000228); + Gfx_DrawDListOpa(globalCtx, object_lbfshot_DL_000228); } diff --git a/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c b/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c index 40c60061c..71f1d2b6a 100644 --- a/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c +++ b/src/overlays/actors/ovl_Bg_Lotus/z_bg_lotus.c @@ -5,6 +5,7 @@ */ #include "z_bg_lotus.h" +#include "objects/object_lotus/object_lotus.h" #define FLAGS 0x00000000 @@ -35,19 +36,16 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_06000A20; // Lilypad collision -extern Gfx D_06000040[]; // Lilypad model - void BgLotus_Init(Actor* thisx, GlobalContext* globalCtx) { BgLotus* this = THIS; s32 pad; - s32 sp2C; + s32 bgId; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000A20); - this->dyna.actor.floorHeight = - func_800C411C(&globalCtx->colCtx, &thisx->floorPoly, &sp2C, &this->dyna.actor, &this->dyna.actor.world.pos); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_lotus_Colheader_000A20); + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &thisx->floorPoly, &bgId, + &this->dyna.actor, &this->dyna.actor.world.pos); this->timer2 = 96; this->dyna.actor.world.rot.y = Rand_Next() >> 0x10; this->actionFunc = BgLotus_Wait; @@ -56,7 +54,7 @@ void BgLotus_Init(Actor* thisx, GlobalContext* globalCtx) { void BgLotus_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgLotus* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgLotus_SetScaleXZ(BgLotus* this) { @@ -93,15 +91,15 @@ void BgLotus_Wait(BgLotus* this, GlobalContext* globalCtx) { } else { this->dyna.actor.world.pos.y = this->height; - if (func_800CAF70(&this->dyna)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { if (this->hasSpawnedRipples == 0) { EffectSsGRipple_Spawn(globalCtx, &this->dyna.actor.world.pos, 1000, 1400, 0); EffectSsGRipple_Spawn(globalCtx, &this->dyna.actor.world.pos, 1000, 1400, 8); this->timer = 40; } - if (gSaveContext.playerForm != 3) { + if (gSaveContext.save.playerForm != PLAYER_FORM_DEKU) { this->timer = 40; - this->dyna.actor.flags |= 0x10; + this->dyna.actor.flags |= ACTOR_FLAG_10; this->actionFunc = BgLotus_Sink; return; } @@ -154,7 +152,7 @@ void BgLotus_WaitToAppear(BgLotus* this, GlobalContext* globalCtx) { func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Actor_SetScale(&this->dyna.actor, 0.1f); this->dyna.actor.world.pos.y = CLAMP_MIN(this->height, this->dyna.actor.floorHeight); - this->dyna.actor.flags &= ~0x10; + this->dyna.actor.flags &= ~ACTOR_FLAG_10; this->timer2 = 96; this->actionFunc = BgLotus_Wait; this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x; @@ -167,11 +165,11 @@ void BgLotus_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; WaterBox* waterBox; - func_800CA1E8(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, - &this->height, &waterBox); + WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, + &this->height, &waterBox); this->actionFunc(this, globalCtx); } void BgLotus_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000040); + Gfx_DrawDListOpa(globalCtx, object_lotus_DL_000040); } 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 bf31ff8e7..e25aeaf67 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,6 +1,13 @@ -#include "z_bg_market_step.h" +/* + * File: z_bg_market_step.c + * Overlay: ovl_Bg_Market_Step + * Description: West Clocktown - most scenery + */ -#define FLAGS 0x10000020 +#include "z_bg_market_step.h" +#include "objects/object_market_obj/object_market_obj.h" + +#define FLAGS (ACTOR_FLAG_20 | ACTOR_FLAG_10000000) #define THIS ((BgMarketStep*)thisx) @@ -20,12 +27,8 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), }; -extern Gfx D_0601F050[]; -extern Gfx D_06018DA0[]; -extern Gfx D_0601EF10[]; -extern Gfx D_06018C60[]; -Gfx* D_80AF0120[] = { D_0601F050, D_06018DA0 }; -Gfx* D_80AF0128[] = { D_0601EF10, D_06018C60 }; +Gfx* D_80AF0120[] = { object_market_obj_DL_01F050, object_market_obj_DL_018DA0 }; +Gfx* D_80AF0128[] = { object_market_obj_DL_01EF10, object_market_obj_DL_018C60 }; void BgMarketStep_Init(Actor* thisx, GlobalContext* globalCtx) { BgMarketStep* this = THIS; @@ -35,6 +38,6 @@ void BgMarketStep_Init(Actor* thisx, GlobalContext* globalCtx) { void BgMarketStep_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 index = thisx->params & 1; - func_800BDFC0(globalCtx, D_80AF0120[index]); - func_800BDFC0(globalCtx, D_80AF0128[index]); + Gfx_DrawDListOpa(globalCtx, D_80AF0120[index]); + Gfx_DrawDListOpa(globalCtx, D_80AF0128[index]); } diff --git a/src/overlays/actors/ovl_Bg_Mbar_Chair/z_bg_mbar_chair.c b/src/overlays/actors/ovl_Bg_Mbar_Chair/z_bg_mbar_chair.c index bc3dc17dc..e5e300757 100644 --- a/src/overlays/actors/ovl_Bg_Mbar_Chair/z_bg_mbar_chair.c +++ b/src/overlays/actors/ovl_Bg_Mbar_Chair/z_bg_mbar_chair.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_mbar_chair.c + * Overlay: ovl_Bg_Mbar_Chair + * Description: Milk Bar - Chair + */ + #include "z_bg_mbar_chair.h" +#include "objects/object_mbar_obj/object_mbar_obj.h" #define FLAGS 0x00000000 @@ -28,26 +35,23 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_060019B4; -extern Gfx D_06000288[]; - void BgMbarChair_Init(Actor* thisx, GlobalContext* globalCtx) { BgMbarChair* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060019B4); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_mbar_obj_Colheader_0019B4); } void BgMbarChair_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgMbarChair* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgMbarChair_Update(Actor* thisx, GlobalContext* globalCtx) { } void BgMbarChair_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000288); + Gfx_DrawDListOpa(globalCtx, object_mbar_obj_DL_000288); } diff --git a/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.c b/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.c index f4e95a2b1..d30fd2d74 100644 --- a/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.c +++ b/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.c @@ -1,6 +1,14 @@ -#include "z_bg_numa_hana.h" +/* + * File: z_bg_numa_hana.c + * Overlay: ovl_Bg_Numa_Hana + * Description: Big wooden flower in Woodfall Temple + */ -#define FLAGS 0x00000410 +#include "z_bg_numa_hana.h" +#include "objects/object_numa_obj/object_numa_obj.h" +#include "objects/object_syokudai/object_syokudai.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((BgNumaHana*)thisx) @@ -9,14 +17,19 @@ void BgNumaHana_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgNumaHana_Update(Actor* thisx, GlobalContext* globalCtx); void BgNumaHana_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80A1AA28(BgNumaHana* this, GlobalContext* globalCtx); -void func_80A1AA4C(BgNumaHana* this, GlobalContext* globalCtx); -void func_80A1AB00(BgNumaHana* this, GlobalContext* globalCtx); -void func_80A1ABF0(BgNumaHana* this, GlobalContext* globalCtx); -void func_80A1ACE0(BgNumaHana* this, GlobalContext* globalCtx); -void func_80A1AE1C(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupDoNothing(BgNumaHana* this); +void BgNumaHana_DoNothing(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupClosedIdle(BgNumaHana* this); +void BgNumaHana_ClosedIdle(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupUnfoldInnerPetals(BgNumaHana* this); +void BgNumaHana_UnfoldInnerPetals(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupUnfoldOuterPetals(BgNumaHana* this); +void BgNumaHana_UnfoldOuterPetals(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupRaiseFlower(BgNumaHana* this); +void BgNumaHana_RaiseFlower(BgNumaHana* this, GlobalContext* globalCtx); +void BgNumaHana_SetupOpenedIdle(BgNumaHana* this); +void BgNumaHana_OpenedIdle(BgNumaHana* this, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Numa_Hana_InitVars = { ACTOR_BG_NUMA_HANA, ACTORCAT_BG, @@ -29,63 +42,379 @@ const ActorInit Bg_Numa_Hana_InitVars = { (ActorFunc)BgNumaHana_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A1B260 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x01CBFBB6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, 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_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0x01CBFBB6, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 18, 16, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A1B2A8[] = { +static FireObjInitParams sFireObjInit = { + 0.00405000010505f, 0.0500000007451f, 3, 1, 0, 0, 0, +}; + +static s16 sInitialAnglePerPetal[] = { 0x0000, 0x2AAA, 0x5555, 0x8000, 0xAAAA, 0xD555 }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 600, ICHAIN_STOP), }; -#endif +/** + * Spawns another wooden flower instance that handles the opened flower's collision. + * Returns true if this wooden flower instance was succesfully spawned. + */ +s32 BgNumaHana_SpawnOpenFlowerCollisionChild(BgNumaHana* this, GlobalContext* globalCtx) { + Actor* child; -extern ColliderCylinderInit D_80A1B260; -extern InitChainEntry D_80A1B2A8[]; + child = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_BG_NUMA_HANA, + this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + this->dyna.actor.shape.rot.x, this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, + BG_NUMA_HANA_TYPE_OPEN_FLOWER_COLLISION); -extern UNK_TYPE D_06009FE0; -extern UNK_TYPE D_0600B928; + return child != NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1A500.s") +void BgNumaHana_UpdatePetalPosRots(BgNumaHana* this) { + f32 outerPetalPosScale; + f32 innerPetalYPos; + f32 outerPetalYPos; + s16 angle; + WoodenFlowerPetalPosRot* innerPetalPosRot; + WoodenFlowerPetalPosRot* outerPetalPosRot; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1A56C.s") + innerPetalYPos = this->dyna.actor.world.pos.y + -10.0f; + angle = this->petalZRotation - 0x2000; + outerPetalPosScale = (Math_CosS(angle) * 77.42784f) + 74.95192f; + outerPetalYPos = (Math_SinS(this->petalZRotation) * 77.42784f) + this->dyna.actor.world.pos.y + -64.74976f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1A750.s") + for (i = 0; i < ARRAY_COUNT(this->innerPetalPosRot); i++) { + innerPetalPosRot = &this->innerPetalPosRot[i]; + outerPetalPosRot = &this->outerPetalPosRot[i]; + angle = sInitialAnglePerPetal[i] + this->dyna.actor.shape.rot.y + 0x1555; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/BgNumaHana_Init.s") + innerPetalPosRot->pos.x = (Math_SinS(angle) * 74.95192f) + this->dyna.actor.world.pos.x; + innerPetalPosRot->pos.y = innerPetalYPos; + innerPetalPosRot->pos.z = (Math_CosS(angle) * 74.95192f) + this->dyna.actor.world.pos.z; + innerPetalPosRot->rot.x = this->dyna.actor.shape.rot.x; + innerPetalPosRot->rot.y = angle - 0x4000; + innerPetalPosRot->rot.z = this->dyna.actor.shape.rot.z + this->petalZRotation; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/BgNumaHana_Destroy.s") + outerPetalPosRot->pos.x = (Math_SinS(angle) * outerPetalPosScale) + this->dyna.actor.world.pos.x; + outerPetalPosRot->pos.y = outerPetalYPos; + outerPetalPosRot->pos.z = (Math_CosS(angle) * outerPetalPosScale) + this->dyna.actor.world.pos.z; + outerPetalPosRot->rot.x = innerPetalPosRot->rot.x; + outerPetalPosRot->rot.y = innerPetalPosRot->rot.y; + outerPetalPosRot->rot.z = innerPetalPosRot->rot.z + this->outerPetalZRotation; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AA14.s") +/** + * As the pieces of the petals finish unfolding, they shake to appear + * as if they are "settling" into place. This function is responsible + * for computing the extra rotation for this "settling". + */ +void BgNumaHana_UpdateSettleRotation(s16* settleZRotation, s16* settleAngle, f32* settleScale, f32 scaleStep) { + *settleAngle += 0x32C8; + Math_StepToF(settleScale, 0.0f, scaleStep); + *settleZRotation += (s16)(Math_SinS(*settleAngle) * *settleScale); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AA28.s") +void BgNumaHana_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DynaPolyActor* child; + s32 type; + BgNumaHana* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AA38.s") + type = BG_NUMA_HANA_GET_TYPE(&this->dyna.actor); + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 3); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AA4C.s") + if (type == BG_NUMA_HANA_TYPE_OPEN_FLOWER_COLLISION) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gWoodenFlowerOpenedFlowerCol); + BgNumaHana_SetupDoNothing(this); + this->dyna.actor.draw = NULL; + } else { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gWoodenFlowerClosedFlowerCol); + FireObj_Init(globalCtx, &this->fire, &sFireObjInit, &this->dyna.actor); + Collider_InitCylinder(globalCtx, &this->torchCollider); + Collider_SetCylinder(globalCtx, &this->torchCollider, &this->dyna.actor, &sCylinderInit); + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + if (!BgNumaHana_SpawnOpenFlowerCollisionChild(this, globalCtx)) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AAE8.s") + if (gSaveContext.save.weekEventReg[12] & 1) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AB00.s") + this->petalZRotation = 0x2000; + this->innerPetalZRotation = 0x2000; + this->innerPetalZRotationalVelocity = 0; + this->settleZRotation = 0; + this->settleAngle = 0; + this->settleScale = 0.0f; + this->outerPetalZRotation = -0x4000; + this->outerPetalZRotationalVelocity = 0; + this->flowerRotationalVelocity = 0x147; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1ABD8.s") + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 210.0f; + FireObj_SetState2(&this->fire, 0.05f, 2); + Flags_SetSwitch(globalCtx, BG_NUMA_HANA_SWITCH_FLAG(&this->dyna.actor)); + BgNumaHana_SetupOpenedIdle(this); + } else { + child = (DynaPolyActor*)this->dyna.actor.child; + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, child->bgId); + Flags_UnsetSwitch(globalCtx, BG_NUMA_HANA_SWITCH_FLAG(&this->dyna.actor)); + BgNumaHana_SetupClosedIdle(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1ABF0.s") + BgNumaHana_UpdatePetalPosRots(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1ACCC.s") +void BgNumaHana_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgNumaHana* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1ACE0.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + if (BG_NUMA_HANA_GET_TYPE(&this->dyna.actor) == BG_NUMA_HANA_TYPE_NORMAL) { + FireObj_Destroy(globalCtx, &this->fire); + Collider_DestroyCylinder(globalCtx, &this->torchCollider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AE08.s") +void BgNumaHana_SetupDoNothing(BgNumaHana* this) { + this->actionFunc = BgNumaHana_DoNothing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/func_80A1AE1C.s") +void BgNumaHana_DoNothing(BgNumaHana* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/BgNumaHana_Update.s") +void BgNumaHana_SetupClosedIdle(BgNumaHana* this) { + this->actionFunc = BgNumaHana_ClosedIdle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Numa_Hana/BgNumaHana_Draw.s") +/** + * This function waits for the torch to be lit. Once it is, it starts + * the cutscene where the petals unfold. + */ +void BgNumaHana_ClosedIdle(BgNumaHana* this, GlobalContext* globalCtx) { + if (this->fire.state != 3) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FLAME_IGNITION); + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + gSaveContext.save.weekEventReg[12] |= 1; + Flags_SetSwitch(globalCtx, BG_NUMA_HANA_SWITCH_FLAG(&this->dyna.actor)); + BgNumaHana_SetupUnfoldInnerPetals(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } +} + +void BgNumaHana_SetupUnfoldInnerPetals(BgNumaHana* this) { + this->actionFunc = BgNumaHana_UnfoldInnerPetals; + this->transitionTimer = 0; +} + +/** + * Partially moves the flower to the "open" position by raising the "inner" + * parts of the petals that are closest to the stalk. + */ +void BgNumaHana_UnfoldInnerPetals(BgNumaHana* this, GlobalContext* globalCtx) { + Math_StepToS(&this->innerPetalZRotationalVelocity, 240, 14); + if (Math_ScaledStepToS(&this->innerPetalZRotation, 0x2000, this->innerPetalZRotationalVelocity)) { + if (this->transitionTimer >= 11) { + BgNumaHana_SetupUnfoldOuterPetals(this); + } else { + if (this->transitionTimer <= 0) { + this->settleZRotation = 0; + this->settleAngle = 0; + this->settleScale = 420.0f; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FLOWERPETAL_STOP); + } + this->transitionTimer++; + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_FLOWERPETAL_MOVE - SFX_FLAG); + } + + BgNumaHana_UpdateSettleRotation(&this->settleZRotation, &this->settleAngle, &this->settleScale, 20.0f); + this->petalZRotation = this->innerPetalZRotation + this->settleZRotation; + BgNumaHana_UpdatePetalPosRots(this); +} + +void BgNumaHana_SetupUnfoldOuterPetals(BgNumaHana* this) { + this->actionFunc = BgNumaHana_UnfoldOuterPetals; + this->transitionTimer = 0; +} + +/** + * Partially moves the flower to the "open" position by lowering the "outer" + * parts of the petals that are furthest to the stalk. + */ +void BgNumaHana_UnfoldOuterPetals(BgNumaHana* this, GlobalContext* globalCtx) { + Math_StepToS(&this->outerPetalZRotationalVelocity, 240, 14); + if (Math_ScaledStepToS(&this->outerPetalZRotation, -0x4000, this->outerPetalZRotationalVelocity)) { + if (this->transitionTimer >= 11) { + BgNumaHana_SetupRaiseFlower(this); + } else { + if (this->transitionTimer <= 0) { + this->settleZRotation = 0; + this->settleAngle = 0x5120; + this->settleScale = 130.0f; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FLOWERPETAL_STOP); + } + this->transitionTimer++; + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_FLOWERPETAL_MOVE - SFX_FLAG); + } + + BgNumaHana_UpdateSettleRotation(&this->settleZRotation, &this->settleAngle, &this->settleScale, 7.0f); + this->petalZRotation = this->innerPetalZRotation + this->settleZRotation; + BgNumaHana_UpdatePetalPosRots(this); +} + +void BgNumaHana_SetupRaiseFlower(BgNumaHana* this) { + this->actionFunc = BgNumaHana_RaiseFlower; +} + +/** + * This function slowly raises the flower to its final height and makes it start spinning. + */ +void BgNumaHana_RaiseFlower(BgNumaHana* this, GlobalContext* globalCtx) { + s32 pad; + DynaPolyActor* child; + + BgNumaHana_UpdateSettleRotation(&this->settleZRotation, &this->settleAngle, &this->settleScale, 10.0f); + this->petalZRotation = this->innerPetalZRotation + this->settleZRotation; + Math_StepToS(&this->flowerRotationalVelocity, 0x111, 0xA); + this->dyna.actor.shape.rot.y += this->flowerRotationalVelocity; + Math_StepToF(&this->dyna.actor.velocity.y, 3.0f, 0.3f); + + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 210.0f, + this->dyna.actor.velocity.y)) { + child = (DynaPolyActor*)this->dyna.actor.child; + + // Swaps out the "closed" flower collision for the "opened" collision. + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, child->bgId); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + + this->petalZRotation = 0x2000; + this->innerPetalZRotation = 0x2000; + this->innerPetalZRotationalVelocity = 0; + this->settleZRotation = 0; + this->settleAngle = 0; + this->outerPetalZRotation = -0x4000; + this->outerPetalZRotationalVelocity = 0; + this->flowerRotationalVelocity = 0x147; + this->settleScale = 0.0f; + + ActorCutscene_Stop(this->dyna.actor.cutscene); + BgNumaHana_SetupOpenedIdle(this); + } + + BgNumaHana_UpdatePetalPosRots(this); + func_800B9010(&this->dyna.actor, NA_SE_EV_FLOWER_ROLLING - SFX_FLAG); +} + +void BgNumaHana_SetupOpenedIdle(BgNumaHana* this) { + this->actionFunc = BgNumaHana_OpenedIdle; +} + +/** + * Spins the "opened" flower around the y-axis. + */ +void BgNumaHana_OpenedIdle(BgNumaHana* this, GlobalContext* globalCtx) { + this->dyna.actor.shape.rot.y += this->flowerRotationalVelocity; + this->petalZRotation = this->innerPetalZRotation + this->settleZRotation; + BgNumaHana_UpdatePetalPosRots(this); + func_800B9010(&this->dyna.actor, NA_SE_EV_FLOWER_ROLLING - SFX_FLAG); +} + +void BgNumaHana_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgNumaHana* this = THIS; + s32 type = BG_NUMA_HANA_GET_TYPE(&this->dyna.actor); + Vec3f firePos; + + if (type == BG_NUMA_HANA_TYPE_NORMAL) { + firePos.x = this->dyna.actor.world.pos.x; + firePos.y = this->dyna.actor.world.pos.y + 10.5f; + firePos.z = this->dyna.actor.world.pos.z; + FireObj_SetPosition(&this->fire, &firePos); + FireObj_Update(globalCtx, &this->fire, &this->dyna.actor); + } + + this->actionFunc(this, globalCtx); + + if (type == BG_NUMA_HANA_TYPE_NORMAL) { + this->dyna.actor.child->shape.rot = this->dyna.actor.shape.rot; + Collider_UpdateCylinder(&this->dyna.actor, &this->torchCollider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->torchCollider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->torchCollider.base); + } +} + +void BgNumaHana_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + BgNumaHana* this = THIS; + WoodenFlowerPetalPosRot* innerPetalPosRot; + WoodenFlowerPetalPosRot* outerPetalPosRot; + s32 objectIndex; + s32 i; + + 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++, gWoodenFlowerStalkDL); + + for (i = 0; i < ARRAY_COUNT(this->innerPetalPosRot); i++) { + innerPetalPosRot = &this->innerPetalPosRot[i]; + outerPetalPosRot = &this->outerPetalPosRot[i]; + + Matrix_SetTranslateRotateYXZ(innerPetalPosRot->pos.x, innerPetalPosRot->pos.y, innerPetalPosRot->pos.z, + &innerPetalPosRot->rot); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gWoodenFlowerInnerPetalDL); + + Matrix_SetTranslateRotateYXZ(outerPetalPosRot->pos.x, outerPetalPosRot->pos.y, outerPetalPosRot->pos.z, + &outerPetalPosRot->rot); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gWoodenFlowerOuterPetalDL); + } + + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_SYOKUDAI); + if ((objectIndex >= 0) && (Object_IsLoaded(&globalCtx->objectCtx, objectIndex))) { + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y - 64.5f, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(1.5f, 1.5f, 1.5f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objectIndex].segment); + gSPDisplayList(POLY_OPA_DISP++, gObjectSyokudaiTypeNoSwitchDL); + } + + FireObj_Draw(globalCtx, &this->fire); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.h b/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.h index f4974860a..19d30a34f 100644 --- a/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.h +++ b/src/overlays/actors/ovl_Bg_Numa_Hana/z_bg_numa_hana.h @@ -3,15 +3,41 @@ #include "global.h" +#define BG_NUMA_HANA_GET_TYPE(thisx) ((thisx)->params & 1) +#define BG_NUMA_HANA_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0x7F) + +typedef enum { + /* 0 */ BG_NUMA_HANA_TYPE_NORMAL, + /* 1 */ BG_NUMA_HANA_TYPE_OPEN_FLOWER_COLLISION, +} BgNumaHanaType; + struct BgNumaHana; typedef void (*BgNumaHanaActionFunc)(struct BgNumaHana*, GlobalContext*); +typedef struct { + /* 0x00 */ Vec3f pos; + /* 0x0C */ Vec3s rot; + /* 0x12 */ UNK_TYPE1 unk_12[0x2]; +} WoodenFlowerPetalPosRot; // size = 0x14 + typedef struct BgNumaHana { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xF0]; - /* 0x0234 */ BgNumaHanaActionFunc actionFunc; - /* 0x0238 */ char unk_238[0x108]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ FireObj fire; + /* 0x1E8 */ ColliderCylinder torchCollider; + /* 0x234 */ BgNumaHanaActionFunc actionFunc; + /* 0x238 */ WoodenFlowerPetalPosRot innerPetalPosRot[6]; + /* 0x2B0 */ WoodenFlowerPetalPosRot outerPetalPosRot[6]; + /* 0x328 */ s16 petalZRotation; + /* 0x32A */ s16 innerPetalZRotation; + /* 0x32C */ s16 innerPetalZRotationalVelocity; + /* 0x32E */ s16 settleZRotation; + /* 0x330 */ s16 settleAngle; + /* 0x334 */ f32 settleScale; + /* 0x338 */ s16 outerPetalZRotation; + /* 0x33A */ s16 outerPetalZRotationalVelocity; + /* 0x33C */ s16 flowerRotationalVelocity; + /* 0x33E */ s16 transitionTimer; } BgNumaHana; // size = 0x340 extern const ActorInit Bg_Numa_Hana_InitVars; 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 5b79969dd..f1fa69810 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,6 +1,12 @@ +/* + * File: z_bg_open_shutter.c + * Overlay: ovl_Bg_Open_Shutter + * Description: Sliding doors in opening dungeon + */ + #include "z_bg_open_shutter.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgOpenShutter*)thisx) diff --git a/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.c b/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.c index fe5ce47b7..48d2cd4f2 100644 --- a/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.c +++ b/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.c @@ -1,14 +1,21 @@ +/* + * File: z_bg_open_spot.c + * Overlay: ovl_Bg_Open_Spot + * Description: Spotlights that shine on the Skull Kid when he turns Link + * into a Deku Scrub. + */ #include "z_bg_open_spot.h" +#include "objects/object_open_obj/object_open_obj.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgOpenSpot*)thisx) void BgOpenSpot_Init(Actor* thisx, GlobalContext* globalCtx); void BgOpenSpot_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgOpenSpot_Update(Actor* thisx, GlobalContext* globalCtx); +void BgOpenSpot_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Open_Spot_InitVars = { ACTOR_BG_OPEN_SPOT, ACTORCAT_PROP, @@ -21,25 +28,49 @@ const ActorInit Bg_Open_Spot_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80ACB3B0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 560, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void BgOpenSpot_Init(Actor* thisx, GlobalContext* globalCtx) { + BgOpenSpot* this = THIS; -extern InitChainEntry D_80ACB3B0[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->texScrolls = Lib_SegmentedToVirtual(gSpotlightTexAnim); +} -extern UNK_TYPE D_06001A60; -extern UNK_TYPE D_06002CE0; +void BgOpenSpot_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Open_Spot/BgOpenSpot_Init.s") +void BgOpenSpot_Update(Actor* thisx, GlobalContext* globalCtx) { + BgOpenSpot* this = THIS; + u32 action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Open_Spot/BgOpenSpot_Destroy.s") + if (Cutscene_CheckActorAction(globalCtx, 0x7D)) { + action = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 0x7D)]->action; + if (action == 1) { + this->actor.draw = NULL; + } else if (action == 2) { + this->actor.draw = BgOpenSpot_Draw; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Open_Spot/BgOpenSpot_Update.s") +void BgOpenSpot_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgOpenSpot* this = (BgOpenSpot*)thisx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Open_Spot/func_80ACB2B0.s") + AnimatedMat_Draw(globalCtx, this->texScrolls); + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_BAYER); + gSPDisplayList(POLY_XLU_DISP++, gSpotlightLeftDL); + gSPDisplayList(POLY_XLU_DISP++, gSpotlightRightDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.h b/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.h index cf4fa2f8d..3a2b92125 100644 --- a/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.h +++ b/src/overlays/actors/ovl_Bg_Open_Spot/z_bg_open_spot.h @@ -7,7 +7,7 @@ struct BgOpenSpot; typedef struct BgOpenSpot { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ AnimatedMaterial* texScrolls; } BgOpenSpot; // size = 0x148 extern const ActorInit Bg_Open_Spot_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.c b/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.c index 0c8c72087..e5bba655d 100644 --- a/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.c +++ b/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.c @@ -1,6 +1,20 @@ -#include "z_bg_sinkai_kabe.h" +/* + * File: z_bg_sinkai_kabe.c + * Overlay: ovl_Bg_Sinkai_Kabe + * Description: Manages the Deep Pythons in Pinnacle Rock + * + * While its name describes one of its responsibilities ("Deep Sea Wall", aka the invisible + * wall blocking a Deep Python's den before you defeat it), it is also responsible for + * spawning in the Deep Pythons when the area first loads, as well as signalling to the + * Deep Python that it should extend its body. Furthermore, if the player defeats all + * eight Deep Pythons and spawns the second Seahorse, this actor is responsible for spawning + * it again if the player leaves and re-enters Pinnacle Rock. + */ -#define FLAGS 0x00000010 +#include "z_bg_sinkai_kabe.h" +#include "objects/object_sinkai_kabe/object_sinkai_kabe.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((BgSinkaiKabe*)thisx) @@ -8,7 +22,8 @@ void BgSinkaiKabe_Init(Actor* thisx, GlobalContext* globalCtx); void BgSinkaiKabe_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgSinkaiKabe_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void BgSinkaiKabe_WaitForPlayer(BgSinkaiKabe* this, GlobalContext* globalCtx); + const ActorInit Bg_Sinkai_Kabe_InitVars = { ACTOR_BG_SINKAI_KABE, ACTORCAT_ITEMACTION, @@ -21,14 +36,117 @@ const ActorInit Bg_Sinkai_Kabe_InitVars = { (ActorFunc)NULL, }; -#endif +static s32 sCurrentPythonIndex = 0; -extern UNK_TYPE D_06000048; +void BgSinkaiKabe_Init(Actor* thisx, GlobalContext* globalCtx) { + BgSinkaiKabe* this = THIS; + s32 pad; + CollisionHeader* colHeader = NULL; + Vec3f pos; + s32 pad2; + s32 shouldSpawnSeahorse; + s32 cs; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Sinkai_Kabe/BgSinkaiKabe_Init.s") + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&gPinnacleRockPythonDenCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + Math_Vec3f_Copy(&pos, &this->dyna.actor.world.pos); + pos.x += Math_SinS(this->dyna.actor.world.rot.y + 0x8000) * 3000.0f; + pos.z += Math_CosS(this->dyna.actor.world.rot.y + 0x8000) * 3000.0f; + cs = this->dyna.actor.cutscene; + i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Sinkai_Kabe/BgSinkaiKabe_Destroy.s") + // clang-format off + while (cs != -1) { this->cutscenes[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs); i++; } + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Sinkai_Kabe/func_80B6DA20.s") + this->dyna.actor.scale.x = 0.1f; + this->dyna.actor.scale.y = 0.1f; + this->dyna.actor.scale.z = 0.1f; + this->pythonIndex = sCurrentPythonIndex; + sCurrentPythonIndex++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Sinkai_Kabe/BgSinkaiKabe_Update.s") + if (!(gSaveContext.save.weekEventReg[13] & 1)) { + this->deepPython = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_EN_DRAGON, pos.x, pos.y, pos.z, + 0, this->dyna.actor.world.rot.y, 1, this->dyna.actor.params); + + if (this->deepPython != NULL) { + EnDragon* dragon = (EnDragon*)this->deepPython; + + dragon->grabCutsceneIndex = this->cutscenes[0]; + dragon->deathCutsceneIndex = this->cutscenes[1]; + dragon->actor.cutscene = this->dyna.actor.cutscene; + Math_Vec3f_Copy(&dragon->burrowEntrancePos, &this->dyna.actor.world.pos); + dragon->pythonIndex = this->pythonIndex; + } + } else { + shouldSpawnSeahorse = false; + if (((this->dyna.actor.params == 0) && (gSaveContext.save.weekEventReg[83] & 0x10)) || + ((this->dyna.actor.params == 1) && (gSaveContext.save.weekEventReg[83] & 0x20)) || + ((this->dyna.actor.params == 2) && (gSaveContext.save.weekEventReg[83] & 0x40)) || + ((this->dyna.actor.params == 3) && (gSaveContext.save.weekEventReg[83] & 0x80)) || + ((this->dyna.actor.params == 4) && (gSaveContext.save.weekEventReg[84] & 1)) || + ((this->dyna.actor.params == 5) && (gSaveContext.save.weekEventReg[84] & 2)) || + ((this->dyna.actor.params == 6) && (gSaveContext.save.weekEventReg[84] & 4)) || + ((this->dyna.actor.params == 7) && (gSaveContext.save.weekEventReg[84] & 8))) { + shouldSpawnSeahorse = true; + } + + Math_Vec3f_Copy(&pos, &this->dyna.actor.home.pos); + pos.x += (Math_SinS(this->dyna.actor.world.rot.y + 0x8000) * 500.0f); + pos.y += -100.0f; + pos.z += (Math_CosS(this->dyna.actor.world.rot.y + 0x8000) * 500.0f); + if (shouldSpawnSeahorse) { + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_OT, pos.x, pos.y, pos.z, 0, + this->dyna.actor.shape.rot.y, 0, 0x4000, this->dyna.actor.cutscene, + this->dyna.actor.unk20, NULL); + } + + Actor_MarkForDeath(&this->dyna.actor); + } + + this->actionFunc = BgSinkaiKabe_WaitForPlayer; +} + +void BgSinkaiKabe_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgSinkaiKabe* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +/** + * Extends this actor's Deep Python if the player gets close enough. + */ +void BgSinkaiKabe_WaitForPlayer(BgSinkaiKabe* this, GlobalContext* globalCtx) { + if (this->deepPython != NULL) { + if (this->deepPython->update != NULL) { + EnDragon* dragon = (EnDragon*)this->deepPython; + + if (dragon->action == DEEP_PYTHON_ACTION_IDLE) { + Player* player = GET_PLAYER(globalCtx); + + if ((this->dyna.actor.xzDistToPlayer < 500.0f) || + ((ABS_ALT(BINANG_SUB(this->dyna.actor.yawTowardsPlayer, this->dyna.actor.world.rot.y)) < 0x2000) && + (this->dyna.actor.xzDistToPlayer < 700.0f))) { + if (fabsf(this->dyna.actor.world.pos.y - player->actor.world.pos.y) < 400.0f) { + dragon->action = DEEP_PYTHON_ACTION_EXTEND; + } + } + } + } else { + this->deepPython = NULL; + } + } + + if (this->deepPython == NULL) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void BgSinkaiKabe_Update(Actor* thisx, GlobalContext* globalCtx) { + BgSinkaiKabe* this = THIS; + + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.h b/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.h index 5fb866529..1a29f512f 100644 --- a/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.h +++ b/src/overlays/actors/ovl_Bg_Sinkai_Kabe/z_bg_sinkai_kabe.h @@ -2,16 +2,19 @@ #define Z_BG_SINKAI_KABE_H #include "global.h" +#include "overlays/actors/ovl_En_Dragon/z_en_dragon.h" struct BgSinkaiKabe; typedef void (*BgSinkaiKabeActionFunc)(struct BgSinkaiKabe*, GlobalContext*); typedef struct BgSinkaiKabe { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ BgSinkaiKabeActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x10]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgSinkaiKabeActionFunc actionFunc; + /* 0x160 */ Actor* deepPython; + /* 0x164 */ s16 cutscenes[2]; + /* 0x168 */ UNK_TYPE1 unk_168[0x4]; + /* 0x16C */ s32 pythonIndex; } BgSinkaiKabe; // size = 0x170 extern const ActorInit Bg_Sinkai_Kabe_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.c b/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.c index ff0c8ad3e..5e3eed13b 100644 --- a/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.c +++ b/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.c @@ -1,4 +1,11 @@ +/* + * File: z_bg_spdweb.c + * Overlay: ovl_Bg_Spdweb + * Description: Spiderweb + */ + #include "z_bg_spdweb.h" +#include "objects/object_spdweb/object_spdweb.h" #define FLAGS 0x00000000 @@ -9,7 +16,14 @@ void BgSpdweb_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgSpdweb_Update(Actor* thisx, GlobalContext* globalCtx); void BgSpdweb_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809CE068(BgSpdweb* this); +void func_809CE234(BgSpdweb* this, GlobalContext* globalCtx); +void func_809CE4C8(BgSpdweb* this, GlobalContext* globalCtx); +void func_809CE830(BgSpdweb* this, GlobalContext* globalCtx); +void func_809CEBC0(BgSpdweb* this, GlobalContext* globalCtx); +void func_809CEE74(BgSpdweb* this); +void func_809CEEAC(BgSpdweb* this, GlobalContext* globalCtx); + const ActorInit Bg_Spdweb_InitVars = { ACTOR_BG_SPDWEB, ACTORCAT_BG, @@ -22,89 +36,491 @@ const ActorInit Bg_Spdweb_InitVars = { (ActorFunc)BgSpdweb_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[2] = { -static ColliderTrisElementInit D_809CF080[2] = { +static ColliderTrisElementInit sTrisElementsInit1[2] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000C00, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000C00, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 75.0f, -8.0f, 75.0f }, { 75.0f, -8.0f, -75.0f }, { -75.0f, -8.0f, -75.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000C00, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000C00, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 75.0f, -8.0f, 75.0f }, { -75.0f, -8.0f, -75.0f }, { -75.0f, -8.0f, 75.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_809CF0F8 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_2, COLSHAPE_TRIS, }, - 2, D_809CF080, // sTrisElementsInit, +static ColliderTrisInit sTrisInit1 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_TRIS, + }, + 2, + sTrisElementsInit1, }; -// static ColliderTrisElementInit sTrisElementsInit[4] = { -static ColliderTrisElementInit D_809CF108[4] = { +static ColliderTrisElementInit sTrisElementsInit2[4] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 70.0f, 160.0f, 15.0f }, { -70.0f, 160.0f, 15.0f }, { -70.0f, 20.0f, 15.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 70.0f, 160.0f, 15.0f }, { -70.0f, 20.0f, 15.0f }, { 70.0f, 20.0f, 15.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -70.0f, 160.0f, -15.0f }, { 70.0f, 160.0f, -15.0f }, { 70.0f, 20.0f, -15.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -70.0f, 160.0f, -15.0f }, { 70.0f, 20.0f, -15.0f }, { -70.0f, 20.0f, -15.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_809CF1F8 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_2, COLSHAPE_TRIS, }, - 4, D_809CF108, // sTrisElementsInit, +static ColliderTrisInit sTrisInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_TRIS, + }, + 4, + sTrisElementsInit2, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809CF210[] = { +Color_RGBA8 D_809CF208 = { 255, 255, 150, 170 }; + +Color_RGBA8 D_809CF20C = { 255, 0, 0, 0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 1500, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; +void BgSpdweb_Init(Actor* thisx, GlobalContext* globalCtx) { + BgSpdweb* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_161 = 0; + this->switchFlag = BGSPDWEB_GET_SWITCHFLAG(&this->dyna.actor); + thisx->params &= 0xFF; + DynaPolyActor_Init(&this->dyna, 1); + + if (this->dyna.actor.params == BGSPDWEB_FF_0) { + Collider_InitAndSetTris(globalCtx, &this->collider, &this->dyna.actor, &sTrisInit1, this->colliderElements); + func_809CE068(this); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_spdweb_Colheader_002678); + this->unk_2F8 = globalCtx->colCtx.dyna.bgActors[this->dyna.bgId].colHeader->vtxList; + this->unk_164 = 0.0f; + this->actionFunc = func_809CE4C8; + } else { + Collider_InitAndSetTris(globalCtx, &this->collider, &this->dyna.actor, &sTrisInit2, this->colliderElements); + func_809CE068(this); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_spdweb_Colheader_0011C0); + this->actionFunc = func_809CEBC0; + Actor_SetFocus(&this->dyna.actor, 30.0f); + } + + this->unk_162 = 0; + + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void BgSpdweb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgSpdweb* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyTris(globalCtx, &this->collider); +} + +void func_809CE068(BgSpdweb* this) { + Vec3f sp64[3]; + s32 i; + s32 j; + + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + + for (i = 0; i < this->collider.count; i++) { + for (j = 0; j < ARRAY_COUNT(sp64); j++) { + Matrix_MultVec3f(this->collider.elements[i].dim.vtx + j, &sp64[j]); + } + Collider_SetTrisVertices(&this->collider, i, &sp64[0], &sp64[1], &sp64[2]); + } +} + +void func_809CE15C(BgSpdweb* this) { + this->unk_2F8[0].y = this->unk_2F8[3].y = this->unk_2F8[10].y = this->unk_2F8[11].y = this->unk_2F8[12].y = + this->unk_2F8[13].y = this->unk_2F8[14].y = this->unk_2F8[15].y = + (this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y) * 10.0f; +} + +void func_809CE1D0(BgSpdweb* this, GlobalContext* globalCtx) { + this->unk_162 = 30; + Flags_SetSwitch(globalCtx, this->switchFlag); + + if (this->dyna.actor.params == BGSPDWEB_FF_0) { + this->actionFunc = func_809CE234; + } else { + this->actionFunc = func_809CE830; + } +} + +void func_809CE234(BgSpdweb* this, GlobalContext* globalCtx) { + Vec3f spB4; + Vec3f spA8; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s16 phi_s2; + s16 temp_s0; + s32 i; + + if (this->unk_162 != 0) { + this->unk_162--; + } + + if (this->unk_162 == 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + if ((this->unk_162 % 3) == 0) { + phi_s2 = Rand_ZeroOne() * 10922.0f; + spB4.y = 0.0f; + spA8.y = this->dyna.actor.world.pos.y; + + for (i = 0; i < 6; i++) { + temp_s0 = (s32)randPlusMinusPoint5Scaled(10240.0f) + phi_s2; + temp_f24 = Math_SinS(temp_s0); + temp_f22 = Math_CosS(temp_s0); + + spA8.x = this->dyna.actor.world.pos.x + (120.0f * temp_f24); + spA8.z = this->dyna.actor.world.pos.z + (120.0f * temp_f22); + + temp_f20 = Math_Vec3f_DistXZ(&this->dyna.actor.home.pos, &spA8) * (1.0f / 120.0f); + if (temp_f20 < 0.7f) { + temp_f20 = 1.0f - temp_f20; + temp_f24 = Math_SinS(BINANG_ROT180(temp_s0)); + temp_f22 = Math_CosS(BINANG_ROT180(temp_s0)); + } + + spB4.x = 7.0f * temp_f24 * temp_f20; + spB4.y = 0.0f; + spB4.z = 7.0f * temp_f22 * temp_f20; + + EffectSsDeadDb_Spawn(globalCtx, &this->dyna.actor.home.pos, &spB4, &gZeroVec3f, &D_809CF208, &D_809CF20C, + 0x32, 8, 0xE); + phi_s2 += 0x2AAA; + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.home.pos, 11, NA_SE_EN_EXTINCT); + } +} + +void func_809CE4C8(BgSpdweb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + ColliderTrisElement* element; + s16 sp3A; + s32 i; + f32 temp_f12; + + sp40.x = this->dyna.actor.world.pos.x; + sp40.y = this->dyna.actor.world.pos.y - 50.0f; + sp40.z = this->dyna.actor.world.pos.z; + sp3A = player->unk_B6A; + + if (func_80123F48(globalCtx, &sp40, 70.0f, 50.0f)) { + this->dyna.actor.home.pos.x = player->swordInfo[0].tip.x; + this->dyna.actor.home.pos.z = player->swordInfo[0].tip.z; + func_809CEE74(this); + return; + } + + if (this->collider.base.acFlags & AC_HIT) { + for (i = 0; i < 2; i++) { + element = &this->collider.elements[i]; + if (element->info.bumperFlags & BUMP_HIT) { + if (this->collider.elements[i].info.acHitInfo->toucher.dmgFlags & 0x800) { + Math_Vec3s_ToVec3f(&this->dyna.actor.home.pos, &element->info.bumper.hitPos); + func_809CEE74(this); + return; + } + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + sp3A = 300; + break; + } + } + } + } + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + temp_f12 = 2.0f * sqrtf(CLAMP_MIN(sp3A, 0)); + if ((this->unk_164 < temp_f12) && (temp_f12 > 2.0f)) { + this->unk_164 = temp_f12; + this->unk_162 = 12; + if (sp3A > 50) { + player->stateFlags1 |= 0x20; + this->unk_161 = 1; + } + } else if (player->actor.speedXZ != 0.0f) { + this->unk_164 = CLAMP_MIN(this->unk_164, 2.0f); + } + } + + if (this->unk_162 != 0) { + this->unk_162--; + } + + this->dyna.actor.world.pos.y = (sin_rad(this->unk_162 * (M_PI / 6)) * this->unk_164) + this->dyna.actor.home.pos.y; + Math_ApproachZeroF(&this->unk_164, 1.0f, 0.8f); + + if (this->unk_162 == 4) { + if ((this->unk_161 != 0) || + ((DynaPolyActor_IsInRidingMovingState(&this->dyna) != 0) && (this->unk_164 > 2.0f))) { + player->actor.velocity.y = this->unk_164 * 0.7f; + player->unk_B68 = (SQ(this->unk_164) * 0.15f) + this->dyna.actor.world.pos.y; + this->unk_161 = 0; + player->stateFlags1 &= ~0x20; + } + } else if (this->unk_162 == 11) { + if (this->unk_164 > 3.0f) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WEB_VIBRATION); + } else { + func_801A75E8(NA_SE_EV_WEB_VIBRATION); + } + } + + if (this->unk_162 == 0) { + this->unk_162 = 12; + } + + func_809CE15C(this); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +#ifdef NON_MATCHING +void func_809CE830(BgSpdweb* this, GlobalContext* globalCtx) { + Vec3f spDC; + Vec3f spD0; + Vec3f spC4; + f32 spB0; + f32 spA4; + f32 sp9C; + f32 sp94; + f32 sp90; + f32 temp_f20; + f32 temp_f22; + f32 temp_f28; + f32 temp_f30; + s32 i; + s16 temp_s0; + s16 temp_s3; + + if (this->unk_162 != 0) { + this->unk_162--; + } + + if (this->unk_162 == 0) { + if (ActorCutscene_GetLength(this->dyna.actor.cutscene) == -1) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + } + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + if ((this->unk_162 % 3) == 0) { + temp_s3 = Rand_ZeroOne() * 0x2AAA; + spB0 = Math_CosS(this->dyna.actor.shape.rot.x); + temp_f20 = Math_SinS(this->dyna.actor.shape.rot.x); + temp_f30 = Math_CosS(this->dyna.actor.shape.rot.y); + spA4 = Math_SinS(this->dyna.actor.shape.rot.y); + if (1) {} + + spC4.x = this->dyna.actor.world.pos.x + ((90.0f * temp_f20) * spA4); + spC4.y = this->dyna.actor.world.pos.y + (90.0f * spB0); + spC4.z = this->dyna.actor.world.pos.z + ((90.0f * temp_f20) * temp_f30); + + sp94 = temp_f20 * spA4; + sp90 = temp_f20 * temp_f30; + + for (i = 0; i < 6; i++) { + temp_s0 = (s32)randPlusMinusPoint5Scaled(0x2800) + temp_s3; + temp_f20 = Math_SinS(temp_s0); + temp_f22 = Math_CosS(temp_s0); + + spD0.x = spC4.x + (90.0f * ((sp94 * temp_f22) + (temp_f30 * temp_f20))); + spD0.y = spC4.y + ((90.0f * spB0) * temp_f22); + spD0.z = spC4.z + (90.0f * ((sp90 * temp_f22) - (spA4 * temp_f20))); + + temp_f28 = Math_Vec3f_DistXYZ(&this->dyna.actor.home.pos, &spD0) * (1.0f / 90.0f); + if (temp_f28 < 0.65f) { + temp_f28 = 1.0f - temp_f28; + temp_f20 = Math_SinS(BINANG_ROT180(temp_s0)); + temp_f22 = Math_CosS(BINANG_ROT180(temp_s0)); + } + + spDC.x = (6.5f * temp_f28) * ((temp_f30 * temp_f20) + (temp_f22 * sp94)); + spDC.y = temp_f22 * ((6.5f * temp_f28) * spB0); + spDC.z = (6.5f * temp_f28) * ((temp_f22 * sp90) - (spA4 * temp_f20)); + + EffectSsDeadDb_Spawn(globalCtx, &this->dyna.actor.home.pos, &spDC, &gZeroVec3f, &D_809CF208, &D_809CF20C, + 0x3C, 8, 0xE); + temp_s3 += 0x2AAA; + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.home.pos, 11, NA_SE_EN_EXTINCT); + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE830.s") #endif -extern ColliderTrisElementInit D_809CF080[2]; -extern ColliderTrisInit D_809CF0F8; -extern ColliderTrisElementInit D_809CF108[4]; -extern ColliderTrisInit D_809CF1F8; -extern InitChainEntry D_809CF210[]; +void func_809CEBC0(BgSpdweb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 sp58; + f32 temp_f10; + f32 temp_f18; + ColliderTrisElement* ptr; + s32 i; + Vec3f sp3C; + f32 sp38; + f32 sp34; + f32 sp30; + f32 sp2C; -extern UNK_TYPE D_06000060; -extern UNK_TYPE D_06002678; + if (this->collider.base.acFlags & AC_HIT) { + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + ptr = &this->collider.elements[i]; + if (ptr->info.bumperFlags & BUMP_HIT) { + Math_Vec3s_ToVec3f(&this->dyna.actor.home.pos, &ptr->info.bumper.hitPos); + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/BgSpdweb_Init.s") + if (i == ARRAY_COUNT(this->colliderElements)) { + this->dyna.actor.home.pos.x = + ((90.0f * Math_SinS(this->dyna.actor.shape.rot.x)) * Math_SinS(this->dyna.actor.shape.rot.y)) + + this->dyna.actor.world.pos.x; + this->dyna.actor.home.pos.y = + (90.0f * Math_CosS(this->dyna.actor.shape.rot.x)) + this->dyna.actor.world.pos.y; + this->dyna.actor.home.pos.z = + ((90.0f * Math_SinS(this->dyna.actor.shape.rot.x)) * Math_CosS(this->dyna.actor.shape.rot.y)) + + this->dyna.actor.world.pos.z; + } + func_809CEE74(this); + } else if ((player->itemActionParam == 7) && (player->unk_B28 != 0)) { + Math_Vec3f_Diff(&player->swordInfo[0].tip, &this->dyna.actor.world.pos, &sp3C); + sp38 = Math_SinS(-this->dyna.actor.shape.rot.x); + sp34 = Math_CosS(-this->dyna.actor.shape.rot.x); + sp30 = Math_SinS(-this->dyna.actor.shape.rot.y); + sp2C = Math_CosS(-this->dyna.actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/BgSpdweb_Destroy.s") + temp_f18 = ((sp3C.x * sp38 * sp30) + (sp3C.y * sp34)) - (sp3C.z * sp38 * sp2C); + sp58 = (-sp3C.x * sp34 * sp30) + (sp3C.y * sp38) + (sp3C.z * sp34 * sp2C); + temp_f10 = (sp3C.x * sp2C) + (sp3C.z * sp30); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE068.s") + if ((fabsf(temp_f10) < 70.0f) && (fabsf(sp58) < 10.0f) && (temp_f18 < 160.0f) && (temp_f18 > 20.0f)) { + Math_Vec3f_Copy(&this->dyna.actor.home.pos, &player->swordInfo[0].tip); + func_809CEE74(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE15C.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE1D0.s") +void func_809CEE74(BgSpdweb* this) { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + this->actionFunc = func_809CEEAC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE234.s") +void func_809CEEAC(BgSpdweb* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + func_809CE1D0(this, globalCtx); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE4C8.s") +void BgSpdweb_Update(Actor* thisx, GlobalContext* globalCtx) { + BgSpdweb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CE830.s") + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CEBC0.s") +void BgSpdweb_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx* gfx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CEE74.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/func_809CEEAC.s") + gfx = POLY_XLU_DISP; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/BgSpdweb_Update.s") + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Spdweb/BgSpdweb_Draw.s") + if (thisx->params == BGSPDWEB_FF_1) { + gSPMatrix(&gfx[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[2], object_spdweb_DL_000060); + } else { + Matrix_Translate(0.0f, (thisx->home.pos.y - thisx->world.pos.y) * 10.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(1.0f, ((thisx->home.pos.y - thisx->world.pos.y) + 10.0f) * 0.1f, 1.0f, MTXMODE_APPLY); + + gSPMatrix(&gfx[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[2], object_spdweb_DL_0012F0); + } + + POLY_XLU_DISP = &gfx[3]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.h b/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.h index 1809d6723..9a71c278f 100644 --- a/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.h +++ b/src/overlays/actors/ovl_Bg_Spdweb/z_bg_spdweb.h @@ -7,11 +7,21 @@ struct BgSpdweb; typedef void (*BgSpdwebActionFunc)(struct BgSpdweb*, GlobalContext*); +#define BGSPDWEB_GET_SWITCHFLAG(thisx) (((thisx)->params >> 8) & 0x7F) + +#define BGSPDWEB_FF_0 0 +#define BGSPDWEB_FF_1 1 + typedef struct BgSpdweb { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ BgSpdwebActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x19C]; + /* 0x0160 */ u8 switchFlag; + /* 0x0161 */ u8 unk_161; + /* 0x0162 */ s16 unk_162; + /* 0x0164 */ f32 unk_164; + /* 0x0168 */ ColliderTris collider; + /* 0x0188 */ ColliderTrisElement colliderElements[4]; + /* 0x02F8 */ Vec3s* unk_2F8; } BgSpdweb; // size = 0x2FC extern const ActorInit Bg_Spdweb_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.c b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.c index ab783a5ad..08a7087e3 100644 --- a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.c +++ b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_spout_fire.c + * Overlay: ovl_Bg_Spout_Fire + * Description: Proximity-Activated Fire Wall Spawner + */ + #include "z_bg_spout_fire.h" #define FLAGS 0x00000000 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_Bg_Tobira01/z_bg_tobira01.c b/src/overlays/actors/ovl_Bg_Tobira01/z_bg_tobira01.c index 72b196ab0..f9b76fd00 100644 --- a/src/overlays/actors/ovl_Bg_Tobira01/z_bg_tobira01.c +++ b/src/overlays/actors/ovl_Bg_Tobira01/z_bg_tobira01.c @@ -1,6 +1,13 @@ -#include "z_bg_tobira01.h" +/* + * File: z_bg_tobira01.c + * Overlay: ovl_Bg_Tobira01 + * Description: Gate to Goron Shrine + */ -#define FLAGS 0x00000030 +#include "z_bg_tobira01.h" +#include "objects/object_spot11_obj/object_spot11_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BgTobira01*)thisx) @@ -21,9 +28,6 @@ const ActorInit Bg_Tobira01_InitVars = { (ActorFunc)BgTobira01_Draw, }; -extern Gfx D_06000088[]; -extern CollisionHeader D_060011C0; - void BgTobira01_Open(BgTobira01* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 cutsceneId = this->dyna.actor.cutscene; @@ -34,21 +38,22 @@ void BgTobira01_Open(BgTobira01* this, GlobalContext* globalCtx) { ActorCutscene_Stop(0x7C); } else if (ActorCutscene_GetCanPlayNext(cutsceneId)) { ActorCutscene_StartAndSetUnkLinkFields(cutsceneId, &this->dyna.actor); - gSaveContext.weekEventReg[88] |= 0x40; + gSaveContext.save.weekEventReg[88] |= 0x40; this->playCutscene = false; } else { ActorCutscene_SetIntentToPlay(cutsceneId); } - } else if (!(gSaveContext.weekEventReg[88] & 0x40) && (this->timer == 0) && (globalCtx->actorCtx.unk1F5 != 0) && - (globalCtx->actorCtx.unk1F4 == 0) && - (func_800C99AC(&globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId) == 6)) { + } else if (!(gSaveContext.save.weekEventReg[88] & 0x40) && (this->timer == 0) && + (globalCtx->actorCtx.unk1F5 != 0) && (globalCtx->actorCtx.unk1F4 == 0) && + (SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId) == + 6)) { this->playCutscene = true; this->unk_16C = 0; // this variable is not used anywhere else } prevTimer = this->timer; - if (gSaveContext.weekEventReg[88] & 0x40) { + if (gSaveContext.save.weekEventReg[88] & 0x40) { this->timer++; } else { this->timer--; @@ -58,13 +63,13 @@ void BgTobira01_Open(BgTobira01* this, GlobalContext* globalCtx) { if (this->timer != prevTimer) { if (1) {} - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_STONEDOOR_OPEN_S - SFX_FLAG); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_STONEDOOR_OPEN_S - SFX_FLAG); this->dyna.actor.world.pos.y = (this->yOffset = (this->timer * (5.0f / 3.0f)) + this->dyna.actor.home.pos.y); this->timer2 = 180; } - if (!(player->stateFlags1 & 0x40) && (gSaveContext.weekEventReg[88] & 0x40) && (DECR(this->timer2) == 0)) { - gSaveContext.weekEventReg[88] &= (u8)~0x40; + if (!(player->stateFlags1 & 0x40) && (gSaveContext.save.weekEventReg[88] & 0x40) && (DECR(this->timer2) == 0)) { + gSaveContext.save.weekEventReg[88] &= (u8)~0x40; } } @@ -72,11 +77,11 @@ void BgTobira01_Init(Actor* thisx, GlobalContext* globalCtx) { BgTobira01* this = THIS; s32 pad; - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060011C0); - gSaveContext.weekEventReg[88] &= (u8)~0x40; + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_spot11_obj_Colheader_0011C0); + gSaveContext.save.weekEventReg[88] &= (u8)~0x40; Actor_SetScale(&this->dyna.actor, 1.0f); - this->timer2 = gSaveContext.isNight; + this->timer2 = gSaveContext.save.isNight; this->timer = 0; this->actionFunc = BgTobira01_Open; } @@ -85,7 +90,7 @@ void BgTobira01_Destroy(Actor* thisx, GlobalContext* globalCtx) { BgTobira01* this = THIS; s32 pad; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void BgTobira01_Update(Actor* thisx, GlobalContext* globalCtx) { @@ -100,7 +105,7 @@ void BgTobira01_Draw(Actor* thisx, GlobalContext* globalCtx) { 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_06000088); + gSPDisplayList(POLY_OPA_DISP++, object_spot11_obj_DL_000088); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c index a501fd117..72aa44fb7 100644 --- a/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c +++ b/src/overlays/actors/ovl_Bg_Umajump/z_bg_umajump.c @@ -1,3 +1,9 @@ +/* + * File: z_bg_umajump.c + * Overlay: ovl_Bg_Umajump + * Description: Horse Jumping Fence + */ + #include "z_bg_umajump.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Boss_01/z_boss_01.c b/src/overlays/actors/ovl_Boss_01/z_boss_01.c index 54264e0dc..4a6ef6e66 100644 --- a/src/overlays/actors/ovl_Boss_01/z_boss_01.c +++ b/src/overlays/actors/ovl_Boss_01/z_boss_01.c @@ -1,6 +1,12 @@ +/* + * File: z_boss_01.c + * Overlay: ovl_Boss_01 + * Description: Odolwa + */ + #include "z_boss_01.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss01*)thisx) 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 c2d70bb36..12d59b530 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -1,6 +1,17 @@ -#include "z_boss_02.h" +/* + * File: z_boss_02.c + * Overlay: ovl_Boss_02 + * Description: Twinmold + */ -#define FLAGS 0x00000035 +#include "prevent_bss_reordering.h" +#include "z_boss_02.h" +#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "overlays/actors/ovl_Item_B_Heart/z_item_b_heart.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "prevent_bss_reordering.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss02*)thisx) @@ -9,12 +20,29 @@ void Boss02_Destroy(Actor* thisx, GlobalContext* globalCtx); void Boss02_Update(Actor* thisx, GlobalContext* globalCtx); void Boss02_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_809DAA74(Boss02* this, GlobalContext* globalCtx); void func_809DAA98(Boss02* this, GlobalContext* globalCtx); +void func_809DAAA8(Boss02* this, GlobalContext* globalCtx); void func_809DAB78(Boss02* this, GlobalContext* globalCtx); +void func_809DC218(Actor* thisx, GlobalContext* globalCtx); +void func_809DC78C(Actor* thisx, GlobalContext* globalCtx); +void func_809DD0A8(Actor* thisx, GlobalContext* globalCtx); +void func_809DD0CC(GlobalContext* globalCtx); +void func_809DD2F8(GlobalContext* globalCtx); +void func_809DD934(Boss02* this, GlobalContext* globalCtx); +void func_809DEAC4(Boss02* this, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_809DF550 = { +static u8 D_809E0420; +static u8 D_809E0421; +static u8 D_809E0422; +static Boss02* D_809E0424; +static Boss02* D_809E0428; +static Boss02* D_809E042C; +static u8 D_809E0430; +static DoorWarp1* D_809E0434; +static Boss02Effects D_809E0438[150]; + +static DamageTable sDamageTable1 = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -49,8 +77,7 @@ static DamageTable D_809DF550 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static DamageTable sDamageTable = { -static DamageTable D_809DF570 = { +static DamageTable sDamageTable2 = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -97,186 +124,2126 @@ const ActorInit Boss_02_InitVars = { (ActorFunc)Boss02_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[22] = { -static ColliderJntSphElementInit D_809DF614[22] = { +static f32 D_809DF5B0 = 1.0f; + +static s16 D_809DF5B4[] = { + 0, 195, 190, 185, 180, 175, 170, 165, 160, 155, 150, 145, 140, 135, 130, 125, 120, 115, 110, 105, 100, 95, 90, 0, +}; + +static s16 D_809DF5E4[] = { + 0, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, 128, 124, 120, 116, 112, +}; + +static ColliderJntSphElementInit sJntSphElementsInit1[22] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 2, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 3, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 4, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 5, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 6, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 7, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 8, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 9, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 10, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 11, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 12, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 13, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 14, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 15, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 16, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 17, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 19, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 21, { { 0, 0, 0 }, 85 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 130 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809DF92C = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 22, D_809DF614, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit1 = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 22, + sJntSphElementsInit1, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_809DF93C[2] = { +static ColliderJntSphElementInit sJntSphElementsInit2[2] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 130 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 22, { { 0, 0, 0 }, 110 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809DF984 = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_809DF93C, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit2 = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit2, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809DF994 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x04, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x04, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 150, 200, 0, { 0, 0, 0 } }, }; -#endif +static Vec3f D_809DF9C0[] = { + { 0.0f, -200.0f, 1000.0f }, { 0.0f, 500.0f, 1000.0f }, { 0.0f, 1000.0f, 1000.0f }, + { 1000.0f, 500.0f, 1000.0f }, { 1000.0f, 1000.0f, -1000.0f }, { -1000.0f, 500.0f, -1000.0f }, + { -1000.0f, 500.0f, 1000.0f }, { -1000.0f, -1000.0f, -1000.0f }, { -1000.0f, -1000.0f, -1000.0f }, +}; -extern DamageTable D_809DF550; -extern DamageTable D_809DF570; -extern ColliderJntSphElementInit D_809DF614[22]; -extern ColliderJntSphInit D_809DF92C; -extern ColliderJntSphElementInit D_809DF93C[2]; -extern ColliderJntSphInit D_809DF984; -extern ColliderCylinderInit D_809DF994; +static Vec3f D_809DFA2C[] = { + { 0.0f, -200.0f, -800.0f }, { 0.0f, 800.0f, -800.0f }, { 800.0f, 300.0f, -800.0f }, + { -800.0f, 800.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, + { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, { -800.0f, -1000.0f, 0.0f }, +}; -extern UNK_TYPE D_060002E0; -extern UNK_TYPE D_060003A0; -extern UNK_TYPE D_06008650; -extern UNK_TYPE D_06009C78; +void func_809DA1D0(GlobalContext* globalCtx, u8 arg1, u8 arg2, u8 arg3, u8 arg4) { + MREG(64) = 1; + MREG(65) = arg1; + MREG(66) = arg2; + MREG(67) = arg3; + MREG(68) = arg4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA1D0.s") +void func_809DA22C(GlobalContext* globalCtx, u8 arg1) { + MREG(68) = arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA22C.s") +void func_809DA24C(GlobalContext* globalCtx) { + MREG(64) = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA24C.s") +void func_809DA264(Boss02Effects* effects, Vec3f* vec, f32 arg2) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA264.s") + for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) { + if (effects->unk_24 == 0) { + effects->unk_24 = 1; + effects->unk_00 = *vec; + effects->unk_0C.x = randPlusMinusPoint5Scaled(30.0f); + effects->unk_0C.y = Rand_ZeroFloat(7.0f) + 7.0f; + effects->unk_0C.z = randPlusMinusPoint5Scaled(30.0f); + effects->unk_18.y = -0.3f; + effects->unk_34 = arg2; + effects->unk_2C = 255; + effects->unk_26 = 0; + effects->unk_38 = 2.0f * arg2; + effects->unk_18.x = effects->unk_18.z = 0.0f; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA344.s") +void func_809DA344(Boss02Effects* effects, Vec3f* vec) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA460.s") + for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) { + if (effects->unk_24 == 0) { + effects->unk_24 = 3; + effects->unk_00 = *vec; + effects->unk_26 = Rand_ZeroFloat(20.0f); + effects->unk_0C.x = randPlusMinusPoint5Scaled(50.0f); + effects->unk_0C.y = randPlusMinusPoint5Scaled(50.0f); + effects->unk_0C.z = randPlusMinusPoint5Scaled(50.0f); + effects->unk_18.z = 0.0f; + effects->unk_18.x = 0.0f; + effects->unk_18.y = -1.5f; + effects->unk_34 = Rand_ZeroFloat(0.04f) + 0.02f; + effects->unk_30 = Rand_ZeroFloat(32767.0f); + effects->unk_2E = Rand_ZeroFloat(32767.0f); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DA50C.s") +void func_809DA460(Boss02Effects* effects, Vec3f* vec) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/Boss02_Init.s") + for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effects++) { + if ((effects->unk_24 == 0) || (effects->unk_24 == 3)) { + effects->unk_24 = 4; + effects->unk_00 = *vec; + Math_Vec3f_Copy(&effects->unk_0C, &gZeroVec3f); + Math_Vec3f_Copy(&effects->unk_18, &gZeroVec3f); + effects->unk_2C = 0xFF; + effects->unk_34 = 0.0f; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/Boss02_Destroy.s") +void func_809DA50C(s32 arg0, ColliderJntSph* collider, Vec3f* arg2) { + collider->elements[arg0].dim.worldSphere.center.x = arg2->x; + collider->elements[arg0].dim.worldSphere.center.y = arg2->y; + collider->elements[arg0].dim.worldSphere.center.z = arg2->z; + collider->elements[arg0].dim.worldSphere.radius = + collider->elements[arg0].dim.modelSphere.radius * collider->elements[arg0].dim.scale * D_809DF5B0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAA74.s") +void Boss02_Init(Actor* thisx, GlobalContext* globalCtx) { + Boss02* this = THIS; + s32 i; + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAA98.s") + if ((gSaveContext.save.weekEventReg[52] & 0x20) && (this->actor.params == 0)) { + D_809E0434 = (DoorWarp1*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_WARP1, + 0.0f, 60.0f, 0.0f, 0, 0, 0, 1); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAAA8.s") + this->actor.targetMode = 10; + this->unk_1D3C.z = this->unk_1D3C.x = 0.0f; + this->unk_1D3C.y = 1.0f; + if (this->actor.params == 200) { + D_809E042C = this; + globalCtx->specialEffects = (void*)D_809E0438; + this->actor.update = func_809DC78C; + this->actor.draw = func_809DD0A8; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_1D70 = 0.00999999977648f; + if ((KREG(64) != 0) || (gSaveContext.eventInf[5] & 0x20) || (D_809E0434 != NULL)) { + this->unk_1D20 = 0; + D_809E0430 = KREG(15) + 20; + } else { + this->unk_1D20 = 1; + } + XREG(41) = KREG(14) + 20; + this->unk_01AC = 1.0f; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON5, 0.0f, 1000.0f, 0.0f, 0, 0, + 0, 0); + } else if (this->actor.params == 100) { + this->actor.update = func_809DC218; + this->actor.draw = NULL; + this->actor.hintId = 0x2E; + } else { + if (this->actor.params != 35) { + this->actor.params = 0; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BOSS_02, 0.0f, 0.0f, 0.0f, 0, 0, 0, 200); + D_809E0424 = this; + D_809E0428 = (Boss02*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BOSS_02, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.world.rot.x, + this->actor.world.rot.y, this->actor.world.rot.z, 35); + D_809E0424->actor.colChkInfo.damageTable = &sDamageTable2; + D_809E0428->actor.colChkInfo.damageTable = &sDamageTable1; + D_809E0424->unk_1674 = D_809E0428; + D_809E0428->unk_1674 = D_809E0424; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAB78.s") + this->actor.colChkInfo.mass = MASS_HEAVY; + this->actor.colChkInfo.health = 20; + Actor_SetScale(&this->actor, 0.01f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gTwinmoldHeadSkel, &gTwinmoldHeadFlyAnim, this->jointTable, + this->morphTable, TWINMOLD_HEAD_LIMB_MAX); + Collider_InitAndSetJntSph(globalCtx, &this->colliderSphere1, &this->actor, &sJntSphInit1, + this->colliderSphere1Elements); + Collider_InitAndSetJntSph(globalCtx, &this->colliderSphere2, &this->actor, &sJntSphInit2, + this->colliderSphere2Elements); + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DBFB4.s") + if (D_809E0434 != NULL) { + func_809DAA74(this, globalCtx); + } else { + func_809DAAA8(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DC218.s") + for (i = 0; i < ARRAY_COUNT(this->unk_01BC); i++) { + this->unk_01BC[i].x = this->actor.world.pos.x; + this->unk_01BC[i].y = this->actor.world.pos.y; + this->unk_01BC[i].z = this->actor.world.pos.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/Boss02_Update.s") + this->unk_014C = Rand_ZeroFloat(1000.0f); + this->unk_1678 = 22; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_BOSS_02, 0.0f, 0.0f, 0.0f, 0, 0, 0, + 100); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DC78C.s") +void Boss02_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/Boss02_Draw.s") +void func_809DAA74(Boss02* this, GlobalContext* globalCtx) { + this->actionFunc = func_809DAA98; + this->actor.world.pos.y = -3000.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DD0A8.s") +void func_809DAA98(Boss02* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DD0CC.s") +void func_809DAAA8(Boss02* this, GlobalContext* globalCtx) { + this->actionFunc = func_809DAB78; + Animation_MorphToLoop(&this->skelAnime, &gTwinmoldHeadFlyAnim, 0.0f); + if (D_809E042C->unk_1D20 != 0) { + this->unk_0144 = 10; + } else { + this->unk_0144 = 100; + this->unk_01A8 = 25.0f; + D_809E042C->unk_1D7E = 100; + this->actor.world.pos.x = 0.0f; + if (D_809E0424 == this) { + this->actor.world.pos.z = -1000.0f; + } else { + this->actor.world.pos.z = 1400.0f; + } + } + this->actor.world.pos.y = -500.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DD2F8.s") +void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_809DFA98 = { 185, 140, 70, 255 }; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + CollisionPoly* spDC; + Vec3f spD0; + f32 spCC; + f32 spC8; + f32 spC4; + s32 i; + f32 temp_f0; + f32 phi_f2; + s16 temp_s0; + s16 temp_s2; + Boss02* spB0 = this->unk_1674; + Vec3f spA4; + f32 spA0; + f32 sp9C; + Vec3f sp90; + CollisionPoly* sp8C; + s32 sp88; + Vec3f sp7C; + Vec3f sp70; + Vec3f sp64; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DD934.s") + spCC = this->unk_01B0.x - this->actor.world.pos.x; + spC8 = this->unk_01B0.y - this->actor.world.pos.y; + spC4 = this->unk_01B0.z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DEAC4.s") + if ((this->unk_0144 != 10) && (this->unk_0144 <= 20)) { + SkelAnime_Update(&this->skelAnime); + temp_s0 = Math_Atan2S(spCC, spC4); + temp_s2 = Math_Atan2S(spC8, sqrtf(SQ(spCC) + SQ(spC4))); + Math_ApproachS(&this->actor.world.rot.y, temp_s0, 0x14, this->unk_0164); + Math_ApproachS(&this->actor.shape.rot.x, temp_s2, 0x14, this->unk_0164); + Math_ApproachS(&this->unk_0198, this->unk_019A, 1, 0x20); + this->unk_0196 += this->unk_0198; + Math_ApproachF(&this->unk_019C, this->unk_01A0, 0.1f, 100.0f); + this->unk_01A4 = Math_SinS(this->unk_0196) * this->unk_019C; + this->actor.world.rot.x = this->actor.shape.rot.x + this->unk_01A4; + + if (!(this->unk_014C & 0x1F) && (D_809E042C->unk_1D20 == 0)) { + this->unk_01A0 = Rand_ZeroFloat(0x1000) + 0x800; + this->unk_019A = Rand_ZeroFloat(0x400) + 0x200; + } + + if (this->unk_0195 != 0) { + Math_ApproachF(&this->unk_0164, this->unk_0168 * 1.25f, 1.0f, 62.5f); + } else { + Math_ApproachF(&this->unk_0164, this->unk_0168, 1.0f, 50.0f); + } + + this->unk_0168 = 2000.0f; + if (this->unk_0195 != 0) { + this->actor.speedXZ = this->unk_01A8 * D_809DF5B0 * 1.25f; + this->skelAnime.playSpeed = 2.0f; + } else { + this->actor.speedXZ = this->unk_01A8 * D_809DF5B0; + } + + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); + + spD0 = this->actor.world.pos; + if (D_809E0422 != 0) { + spD0.y = 5000.0f; + } else { + spD0.y = 2000.0f; + } + + temp_f0 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &spDC, &spD0); + if (((this->unk_017C.y < temp_f0) && (temp_f0 <= this->unk_0188.y)) || + ((temp_f0 < this->unk_017C.y) && (this->unk_0188.y <= temp_f0))) { + this->unk_0170 = this->unk_017C; + this->unk_0170.y = temp_f0; + this->unk_016C = 120; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_ROAR_OLD); + } + + this->actor.flags &= ~ACTOR_FLAG_1; + if (this->unk_0195 != 0) { + this->actor.world.rot.z = Math_SinS(this->unk_014C * 0x1200) * 0xE00; + } else { + this->actor.world.rot.z = Math_SinS(this->unk_014C * 0xC00) * 0xE00; + } + + this->unk_014E++; + if (this->unk_014E >= ARRAY_COUNT(this->unk_01BC)) { + this->unk_014E = 0; + } + + this->unk_01BC[this->unk_014E].x = this->actor.world.pos.x; + this->unk_01BC[this->unk_014E].y = this->actor.world.pos.y; + this->unk_01BC[this->unk_014E].z = this->actor.world.pos.z; + + this->unk_0B1C[this->unk_014E].x = BINANG_TO_RAD(this->actor.world.rot.x); + this->unk_0B1C[this->unk_014E].y = BINANG_TO_RAD(this->actor.world.rot.y); + this->unk_0B1C[this->unk_014E].z = BINANG_TO_RAD(this->actor.world.rot.z); + } + + if ((this->unk_0144 < 10) && (spB0->unk_0144 >= 20)) { + this->unk_01B0.y = -1000.0f * D_809DF5B0; + if (D_809E0422 != 0) { + this->unk_01B0.y += 3150.0f; + } + this->unk_0144 = 3; + this->unk_0146[0] = 50; + } + + switch (this->unk_0144) { + default: + return; + + case 0: + if ((this->actor.params == 0) && (Rand_ZeroOne() < 0.75f)) { + this->actor.world.pos.x = player->actor.world.pos.x; + this->actor.world.pos.z = player->actor.world.pos.z; + this->actor.world.pos.y = player->actor.world.pos.y - (600.0f * D_809DF5B0); + } else { + this->actor.world.pos.x = randPlusMinusPoint5Scaled(5000.0f * D_809DF5B0); + this->actor.world.pos.z = randPlusMinusPoint5Scaled(5000.0f * D_809DF5B0); + this->actor.world.pos.y = -500.0f * D_809DF5B0; + if (D_809E0422 != 0) { + this->actor.world.pos.y += 3150.0f; + } + } + + if ((fabsf(this->actor.world.pos.x) < (500.0f * D_809DF5B0)) && + (fabsf(this->actor.world.pos.z) < (500.0f * D_809DF5B0))) { + return; + } + + case 100: + this->actor.shape.rot.x = 0x4000; + this->unk_01B0.x = this->actor.world.pos.x; + this->unk_01B0.y = this->actor.world.pos.y + (1000.0f * D_809DF5B0); + this->unk_01B0.z = this->actor.world.pos.z; + this->unk_0146[0] = 100; + this->unk_0144 = 1; + + case 1: + if (this->unk_0146[0] == 0) { + if (Rand_ZeroOne() < 0.3f) { + this->unk_0144 = 5; + this->unk_0146[0] = 150; + } else { + this->unk_0144 = 2; + this->unk_01B0.x = randPlusMinusPoint5Scaled(3000.0f * D_809DF5B0); + this->unk_01B0.z = randPlusMinusPoint5Scaled(3000.0f * D_809DF5B0); + if ((fabsf(this->unk_01B0.x) < (500.0f * D_809DF5B0)) && + (fabsf(this->unk_01B0.z) < (500.0f * D_809DF5B0))) { + this->unk_01B0.x = 500.0f; + this->unk_01B0.z = 500.0f; + } + this->unk_01B0.y = Rand_ZeroFloat(800.0f * D_809DF5B0) + (200.0f * D_809DF5B0); + if (D_809E0422 != 0) { + this->unk_01B0.y += 3150.0f; + } + } + this->unk_0164 = 0.0f; + } + return; + + case 2: + if (this->unk_0195 != 0) { + phi_f2 = 700.0f; + } else { + phi_f2 = 500.0f; + } + if (sqrtf(SQ(spCC) + SQ(spC8) + SQ(spC4)) < (phi_f2 * D_809DF5B0)) { + this->unk_0144 = 3; + this->unk_01B0.y = -3000.0f * D_809DF5B0; + if (D_809E0422 != 0) { + this->unk_01B0.y += 3150.0f; + } + this->unk_0146[0] = 150; + this->unk_0164 = 0.0f; + } + return; + + case 3: + if (this->unk_0146[0] == 0) { + this->unk_0144 = 0; + } + return; + + case 5: + this->unk_01B0.x = player->actor.world.pos.x; + this->unk_01B0.y = player->actor.world.pos.y + (100.0f * D_809DF5B0); + this->unk_01B0.z = player->actor.world.pos.z; + if (this->unk_0146[0] == 0) { + this->unk_0144 = 3; + this->unk_01B0.x = randPlusMinusPoint5Scaled(500.0f * D_809DF5B0) + this->actor.world.pos.x; + this->unk_01B0.y = -3000.0f * D_809DF5B0; + if (D_809E0422 != 0) { + this->unk_01B0.y += 3150.0f; + } + this->unk_01B0.z = randPlusMinusPoint5Scaled(500.0f * D_809DF5B0) + this->actor.world.pos.z; + this->unk_0146[0] = 150; + this->unk_0164 = 0.0f; + } + return; + + case 10: + if (this->unk_1678 != 0) { + this->unk_019A = 0x500; + this->unk_01A0 = 0x1200; + } else { + this->colliderCylinder.dim.radius = 150.0f * D_809DF5B0; + this->colliderCylinder.dim.height = 200.0f * D_809DF5B0; + this->colliderCylinder.dim.yShift = 0; + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + return; + + case 11: + if (this == D_809E0424) { + this->unk_01B0.x = D_809DF9C0[this->unk_1D1A].x; + this->unk_01B0.y = D_809DF9C0[this->unk_1D1A].y; + this->unk_01B0.z = D_809DF9C0[this->unk_1D1A].z; + } else { + this->unk_01B0.x = D_809DFA2C[this->unk_1D1A].x; + this->unk_01B0.y = D_809DFA2C[this->unk_1D1A].y; + this->unk_01B0.z = D_809DFA2C[this->unk_1D1A].z; + } + this->actor.shape.rot.x = 0x4000; + this->unk_0144 = 12; + this->actor.world.pos.x = this->unk_01B0.x; + this->actor.world.pos.y = -200.0f; + this->actor.world.pos.z = this->unk_01B0.z; + this->unk_01A8 = 25.0f; + return; + + case 12: + if (sqrtf(SQ(spCC) + SQ(spC8) + SQ(spC4)) < 500.0f) { + this->unk_1D1A++; + this->unk_0164 = 0.0f; + if (this->unk_1D1A > 8) { + this->unk_1D1A = 8; + } + if (this == D_809E0424) { + this->unk_01B0.x = D_809DF9C0[this->unk_1D1A].x; + this->unk_01B0.y = D_809DF9C0[this->unk_1D1A].y; + this->unk_01B0.z = D_809DF9C0[this->unk_1D1A].z; + } else { + this->unk_01B0.x = D_809DFA2C[this->unk_1D1A].x; + this->unk_01B0.y = D_809DFA2C[this->unk_1D1A].y; + this->unk_01B0.z = D_809DFA2C[this->unk_1D1A].z; + } + } + return; + + case 20: + this->unk_0152 = 15; + if ((s16)(BREG(71) + 140) < this->unk_0146[1]) { + if (this->unk_0146[0] == 0) { + Matrix_RotateYS(Math_Atan2S(-player->actor.world.pos.x, -player->actor.world.pos.z), MTXMODE_NEW); + Matrix_MultVecZ(1500.0f * D_809DF5B0, &spA4); + this->unk_0146[0] = 50; + this->unk_01B0.x = player->actor.world.pos.x + spA4.x; + this->unk_01B0.y = randPlusMinusPoint5Scaled(500.0f * D_809DF5B0) + (600.0f * D_809DF5B0); + if (D_809E0422 != 0) { + this->unk_01B0.y += 3150.0f; + } + this->unk_01B0.z = player->actor.world.pos.z + spA4.z; + } + this->unk_0168 = 3000.0f; + } else { + this->unk_01B0.y += 10.0f * D_809DF5B0; + this->unk_0168 = 5000.0f; + } + this->unk_019A = 0x1000; + this->unk_01A8 = 25.0f; + this->unk_01A0 = 0x1800; + if (this->unk_0146[1] == 0) { + this->unk_015C = 1; + this->unk_0144 = 21; + this->unk_0146[0] = 20; + this->unk_0152 = 0; + D_809E042C->unk_1D20 = 102; + D_809E042C->unk_1D5C = 0.0f; + play_sound(NA_SE_EN_INBOSS_DEAD_PRE2_OLD); + } else if (!(this->unk_0146[1] & 0xF) && (Rand_ZeroOne() < 0.5f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_DAMAGE_OLD); + } + return; + + case 21: + this->unk_01A8 = 0.0f; + this->actor.speedXZ = 0.0f; + if (this->unk_0146[0] == 0) { + this->unk_0146[0] = 3; + + for (i = 0; i < 35; i++) { + func_809DA344(globalCtx->specialEffects, &this->unk_147C[this->unk_1678]); + } + + func_809DA460(globalCtx->specialEffects, &this->unk_147C[this->unk_1678]); + play_sound(NA_SE_EV_EXPLOSION); + + this->unk_1678--; + if (this->unk_1678 <= 0) { + this->unk_0144 = 22; + this->actor.gravity = -1.0f * D_809DF5B0; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -1000.0f * D_809DF5B0; + this->unk_0164 = randPlusMinusPoint5Scaled(0.05f); + + 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; + } + + 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; + } + + if (spB0->unk_0144 >= 10) { + Audio_QueueSeqCmd(NA_BGM_CLEAR_BOSS | 0x8000); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_DEAD_OLD); + } + } + return; + + case 22: + i = (this->unk_014E + 196) % ARRAY_COUNT(this->unk_01BC); + + Math_Vec3f_Copy(&this->unk_01BC[i], &this->actor.world.pos); + this->unk_0B1C[i].y += this->unk_0164; + Math_ApproachF(&this->unk_0B1C[i].x, -(M_PI / 2), 0.1f, 0.07f); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 150.0f, 100.0f, 4); + + if (this->actor.bgCheckFlags & 1) { + this->unk_0144 = 23; + this->actor.speedXZ = 0.0f; + this->unk_0170 = this->unk_017C; + this->unk_016C = 30; + this->unk_0170.y = this->actor.floorHeight; + D_809E042C->unk_1D20 = 103; + D_809E042C->unk_1D1C = 0; + D_809E042C->unk_0146[0] = 15; + D_809E042C->unk_0150 = 0; + play_sound(NA_SE_EV_LIGHTNING); + + for (i = 0; i < 30; i++) { + func_809DA344(globalCtx->specialEffects, &this->unk_0170); + } + + this->unk_0146[0] = 10; + } + break; + + case 23: + i = (this->unk_014E + 196) % ARRAY_COUNT(this->unk_01BC); + Math_Vec3f_Copy(&this->unk_01BC[i], &this->actor.world.pos); + Math_ApproachF(&this->unk_0B1C[i].x, -(M_PI / 2), 0.05f, 0.07f); + + if (this->unk_0146[0] & 1) { + sp9C = Rand_ZeroFloat(M_PI); + + for (i = 0; i < 15; i++) { + Matrix_RotateYF(((2.0f * (i * M_PI)) / 15.0f) + sp9C, MTXMODE_NEW); + Matrix_MultVecZ((10 - this->unk_0146[0]) * (D_809DF5B0 * 300.0f) * 0.1f, &sp90); + spD0.x = this->unk_0170.x + sp90.x; + spD0.y = this->unk_0170.y + (1000.0f * D_809DF5B0); + spD0.z = this->unk_0170.z + sp90.z; + if (BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &sp8C, &sp88, &spD0) != BGCHECK_Y_MIN) { + spA0 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp8C, &spD0); + Matrix_MultVecZ(5.0f * D_809DF5B0, &sp70); + sp70.y = 2.0f * D_809DF5B0; + sp64.y = 0.3f * D_809DF5B0; + sp64.z = 0.0f; + sp64.x = 0.0f; + sp7C.x = spD0.x; + sp7C.y = spA0; + sp7C.z = spD0.z; + func_800B0F18(globalCtx, &sp7C, &sp70, &sp64, &D_809DFA98, &D_809DFA98, + (Rand_ZeroFloat(500.0f) + 1200.0f) * D_809DF5B0, 20.0f * D_809DF5B0, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + } + } + + this->colliderCylinder.dim.radius = 150.0f * D_809DF5B0; + this->colliderCylinder.dim.height = 200.0f * D_809DF5B0; + this->colliderCylinder.dim.yShift = 0; + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); +} + +void func_809DBFB4(Boss02* this, GlobalContext* globalCtx) { + Boss02* temp_s6 = this->unk_1674; + s32 temp; + s32 i; + u8 damage; + + if (this->unk_0154 == 0) { + if (D_809E0422 != 0) { + temp = 0; + } else { + temp = 1; + } + + for (i = temp; i < ARRAY_COUNT(this->colliderSphere2Elements); i++) { + if (this->colliderSphere2.elements[i].info.bumperFlags & BUMP_HIT) { + this->colliderSphere2.elements[i].info.bumperFlags &= ~BUMP_HIT; + this->unk_0154 = 15; + this->unk_0156 = 15; + + if (i == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_DAMAGE_OLD); + this->unk_015C = 1; + } else { + Audio_PlaySfxAtPos(&this->unk_167C, NA_SE_EN_INBOSS_DAMAGE_OLD); + this->unk_015C = 10; + } + + if (D_809E0422 != 0) { + this->unk_0152 = 15; + } else { + this->unk_0152 = 12; + } + + damage = this->actor.colChkInfo.damage; + + if (temp_s6->unk_0144 < 20) { + do { + do { + this->actor.colChkInfo.health -= damage; + } while (0); + } while (0); + + if ((s8)this->actor.colChkInfo.health <= 0) { + Actor_MarkForDeath(this->actor.child); + this->actor.child = NULL; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->skelAnime.playSpeed = 2.0f; + this->unk_0144 = 20; + + if (temp_s6->unk_0144 >= 10) { + Audio_QueueSeqCmd(0x100100FF); + } else { + temp_s6->unk_0195 = 1; + } + + this->unk_0146[1] = BREG(70) + 170; + this->unk_0146[0] = 0; + this->actor.shape.rot.x = 0x4000; + + if (D_809E0422 == 0) { + if (this->actor.world.pos.y < -200.0f) { + this->actor.world.pos.y = -200.0f; + } + } else if (this->actor.world.pos.y < 3130.0f) { + this->actor.world.pos.y = 3130.0f; + } + + D_809E042C->unk_1D20 = 100; + + if (this == D_809E0424) { + D_809E042C->unk_0194 = 0; + } else { + D_809E042C->unk_0194 = 1; + } + } + } + } + } + } +} + +void func_809DC218(Actor* thisx, GlobalContext* globalCtx) { + Boss02* this = THIS; + s32 pad; + Vec3f sp24; + CollisionPoly* sp20; + + this->unk_014C++; + if ((this->unk_014C + this->actor.params) & 1) { + sp24 = this->actor.world.pos; + this->actor.focus.pos = this->actor.world.pos; + if (D_809E0422 != 0) { + sp24.y = 5000.0f; + } else { + sp24.y = 2000.0f; + } + + if ((this->actor.focus.pos.y < BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp20, &sp24)) || + (D_809E0422 != 0)) { + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + this->actor.flags |= ACTOR_FLAG_1; + } + } +} + +void Boss02_Update(Actor* thisx, GlobalContext* globalCtx) { + Vec3f sp3C; + Boss02* this = THIS; + s32 pad; + s16 i; + + if (D_809E0422 == 0) { + Actor_SetScale(&this->actor, 0.6f); + } else { + Actor_SetScale(&this->actor, 0.060000001f); + } + + if (D_809E042C->unk_1D18 == 0) { + for (i = 0; i < ARRAY_COUNT(this->unk_0146); i++) { + if (this->unk_0146[i] != 0) { + this->unk_0146[i]--; + } + } + + if (this->unk_016C != 0) { + this->unk_016C--; + } + + if (this->unk_0154 != 0) { + this->unk_0154--; + } + + if (this->unk_0156 != 0) { + this->unk_0156--; + } + + if (this->unk_0152 != 0) { + this->unk_0152--; + } + + this->unk_014C++; + + this->actionFunc(this, globalCtx); + + if (this->unk_016C != 0) { + if ((this->unk_016C == 60) && (this->unk_0144 < 20)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_ROAR_OLD); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_INBOSS_SAND_OLD - SFX_FLAG); + + if (this->unk_0144 > 20) { + sp3C.x = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.x; + sp3C.y = randPlusMinusPoint5Scaled(50.0f * D_809DF5B0) + this->unk_0170.y; + sp3C.z = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.z; + func_809DA264(globalCtx->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f); + } + + if ((this->unk_014C % 2) == 0) { + sp3C.x = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.x; + sp3C.y = randPlusMinusPoint5Scaled(50.0f * D_809DF5B0) + this->unk_0170.y; + sp3C.z = randPlusMinusPoint5Scaled(100.0f * D_809DF5B0) + this->unk_0170.z; + func_809DA264(globalCtx->specialEffects, &sp3C, Rand_ZeroFloat(3.0f) + 6.0f); + } + } + + if ((this->unk_0144 < 20) && (this->unk_0144 != 10)) { + func_809DBFB4(this, globalCtx); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere1.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere1.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere2.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere2.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere2.base); + } + + switch (this->unk_015C) { + case 1: + this->unk_015A = 0; + this->unk_0158 = this->unk_015A; + this->unk_015C++; + + case 2: + this->unk_015A += 2; + if (this->unk_015A > 20) { + this->unk_015C++; + } + this->unk_0156 |= 4; + break; + + case 3: + this->unk_0158 += 2; + if (this->unk_0158 > 20) { + this->unk_015C = 0; + } + this->unk_0156 |= 4; + break; + + case 10: + this->unk_015A = 21; + this->unk_0158 = this->unk_015A; + this->unk_015C++; + + case 11: + this->unk_0158 -= 2; + if (this->unk_0158 <= 0) { + this->unk_0158 = 0; + this->unk_015C++; + } + this->unk_0156 |= 4; + break; + + case 12: + this->unk_015A -= 2; + if (this->unk_015A <= 0) { + this->unk_015A = 0; + this->unk_015C = 0; + } + this->unk_0156 |= 4; + break; + } + } +} + +void func_809DC78C(Actor* thisx, GlobalContext* globalCtx) { + Boss02* this = THIS; + + this->unk_01AC = D_809DF5B0; + globalCtx->envCtx.sandstormState = 0xD; + + if (D_809E0434 != NULL) { + this->unk_1D74 = KREG(23) + -15.0f; + D_801F4E30 = 0; + globalCtx->envCtx.lightSettingOverride = 1; + globalCtx->skyboxId = 1; + } else if (D_809E0422 == 0) { + this->unk_1D74 = 0.0f; + D_801F4E30 = this->unk_1D7C; + globalCtx->envCtx.lightSettingOverride = 0; + globalCtx->skyboxId = 2; + } else { + this->unk_1D74 = KREG(23) + -15.0f; + D_801F4E30 = ((KREG(24) * 0.1f) + 1.0f) * this->unk_1D7C; + globalCtx->envCtx.lightSettingOverride = 1; + globalCtx->skyboxId = 1; + } + + Math_ApproachS(&this->unk_1D7C, this->unk_1D7E, 1, 3); + + if (this->unk_0146[0] != 0) { + this->unk_0146[0]--; + } + + if (D_809E0434 == NULL) { + if (D_809E0430 != 0) { + D_809E0430--; + if (D_809E0430 == 0) { + Audio_QueueSeqCmd(NA_BGM_BOSS | 0x8000); + } + } + } + + func_809DD0CC(globalCtx); + func_809DEAC4(this, globalCtx); + func_809DD934(this, globalCtx); +} + +void Boss02_Draw(Actor* thisx, GlobalContext* globalCtx2) { + static Gfx* D_809DFA9C[] = { + gTwinmoldBodySegment1DL, gTwinmoldBodySegment2DL, gTwinmoldBodySegment3DL, gTwinmoldBodySegment4DL, + gTwinmoldBodySegment5DL, gTwinmoldBodySegment6DL, gTwinmoldBodySegment7DL, gTwinmoldBodySegment8DL, + gTwinmoldBodySegment9DL, gTwinmoldBodySegment10DL, gTwinmoldBodySegment11DL, gTwinmoldBodySegment12DL, + gTwinmoldBodySegment13DL, gTwinmoldBodySegment14DL, gTwinmoldBodySegment15DL, gTwinmoldBodySegment16DL, + gTwinmoldBodySegment17DL, gTwinmoldBodySegment18DL, gTwinmoldBodySegment19DL, gTwinmoldBodySegment20DL, + gTwinmoldBodySegment21DL, gTwinmoldBodyTailDL, + }; + static Vec3f D_809DFAF4 = { -10000.0f, -100000.0f, -100000.0f }; + GlobalContext* globalCtx = globalCtx2; + Boss02* this = THIS; + s32 i; + s32 idx; + Mtx* mtx; + Mtx* mtxIter; + s32 phi_v0; + f32 phi_f12; + f32 spAC; + f32 spA8; + f32 spA4; + f32 spA0; + f32 sp9C; + f32 sp98; + + mtxIter = mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Mtx) * 23); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->actor.params == 0) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(gTwinmoldRedSkinTex)); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(gTwinmoldBlueSkinTex)); + } + + gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); + + if (D_809E0422 == 0) { + sp98 = -500.0f; + } else { + sp98 = 3100.0f; + } + + sp9C = this->unk_0152 * (M_PI / 4) * (1.0f / 15); + if (this->unk_0144 < 20) { + spAC = Math_SinS(this->unk_014C * 0x2200) * sp9C * 0.5f; + spA8 = Math_CosS(this->unk_014C * 0x3200) * sp9C; + } else { + spAC = Math_SinS(this->unk_014C * 0x1000) * sp9C * 0.5f; + spA8 = Math_CosS(this->unk_014C * 0x1500) * sp9C; + } + + idx = (this->unk_014E + 196) % ARRAY_COUNT(this->unk_01BC); + Matrix_Translate(this->unk_01BC[idx].x, this->unk_01BC[idx].y, this->unk_01BC[idx].z, MTXMODE_NEW); + Matrix_RotateYF(this->unk_0B1C[idx].y + spA8, MTXMODE_APPLY); + Matrix_RotateXFApply(spAC - this->unk_0B1C[idx].x); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 250.0f, MTXMODE_APPLY); + Matrix_MultVecZ(150.0f, &this->unk_147C[0]); + this->unk_0188 = this->unk_017C; + Matrix_MultVecZ(300.0f, &this->unk_017C); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->unk_017C); + + if ((this->unk_0156 & 1) && (this->unk_0158 == 0)) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 0x384, 0x44B); + } + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->actor); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + spA4 = 0.0f; + spA0 = 0.0f; + for (i = 0; i < ARRAY_COUNT(D_809DFA9C); i++, mtxIter++) { + if (this->unk_0195 != 0) { + phi_v0 = (D_809DF5E4[i + 1] + this->unk_014E) % ARRAY_COUNT(this->unk_01BC); + } else { + phi_v0 = (D_809DF5B4[i + 1] + this->unk_014E) % ARRAY_COUNT(this->unk_01BC); + } + + if ((i == 21) && (this->unk_0144 < 20)) { + spA4 = spAC; + spA0 = spA8; + } + + Matrix_Translate(this->unk_01BC[phi_v0].x, this->unk_01BC[phi_v0].y, this->unk_01BC[phi_v0].z, MTXMODE_NEW); + Matrix_RotateYF(this->unk_0B1C[phi_v0].y + spA0, MTXMODE_APPLY); + Matrix_RotateXFApply(spA4 - this->unk_0B1C[phi_v0].x); + Matrix_RotateZF(this->unk_0B1C[phi_v0].z, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYF(M_PI / 2, MTXMODE_APPLY); + Matrix_RotateXFApply(-(M_PI / 2)); + Matrix_ToMtx(mtxIter); + + gSPMatrix(POLY_OPA_DISP++, mtxIter, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if ((this->unk_0156 & 1) && (i >= this->unk_0158) && (this->unk_015A >= i)) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 0x384, 0x44B); + } + + if (i < this->unk_1678) { + if (sp98 < this->unk_01BC[phi_v0].y) { + gSPDisplayList(POLY_OPA_DISP++, D_809DFA9C[i]); + } + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } + + if (i == 21) { + phi_f12 = 600.0f; + } else { + phi_f12 = 200.0f; + } + + Matrix_MultVecX(phi_f12, &this->unk_147C[i + 1]); + + if (i == 21) { + Actor* child = this->actor.child; + + if (child != NULL) { + Matrix_MultVecX(500.0f, &this->actor.child->world.pos); + } + + func_809DA50C(1, &this->colliderSphere2, &this->unk_147C[i + 1]); + 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]); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (D_809E0422 == 0) { + func_809DA50C(0, &this->colliderSphere2, &D_809DFAF4); + func_809DA50C(21, &this->colliderSphere1, &this->unk_147C[0]); + } else { + func_809DA50C(0, &this->colliderSphere2, &this->unk_147C[0]); + func_809DA50C(21, &this->colliderSphere1, &D_809DFAF4); + } +} + +void func_809DD0A8(Actor* thisx, GlobalContext* globalCtx) { + func_809DD2F8(globalCtx); +} + +void func_809DD0CC(GlobalContext* globalCtx) { + Boss02Effects* effect = (Boss02Effects*)globalCtx->specialEffects; + f32 phi_f22; + s16 i; + + if (D_809E0422 == 0) { + phi_f22 = 0.0f; + } else { + phi_f22 = 3150.0f; + } + + for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effect++) { + if (effect->unk_24) { + effect->unk_26++; + effect->unk_00.x += effect->unk_0C.x * D_809DF5B0; + effect->unk_00.y += effect->unk_0C.y * D_809DF5B0; + effect->unk_00.z += effect->unk_0C.z * D_809DF5B0; + effect->unk_0C.y += effect->unk_18.y; + + if (effect->unk_24 < 3) { + Math_ApproachF(&effect->unk_34, effect->unk_38, 0.1f, 0.1f); + if (effect->unk_24 == 2) { + effect->unk_2C -= 18; + } else { + effect->unk_2C -= 15; + } + if (effect->unk_2C <= 0) { + effect->unk_24 = 0; + } + } else if (effect->unk_24 == 3) { + effect->unk_2E += 0x1000; + effect->unk_30 += 0x1500; + if ((effect->unk_00.y < phi_f22) || (effect->unk_26 > 50)) { + effect->unk_24 = 0; + } + } else if (effect->unk_24 == 4) { + Math_ApproachF(&effect->unk_34, 80.0f, 0.2f, 20.0f); + effect->unk_2C -= 15; + if (effect->unk_2C <= 0) { + effect->unk_24 = 0; + } + } + } + } +} + +void func_809DD2F8(GlobalContext* globalCtx) { + u8 flag = false; + Boss02Effects* effect = (Boss02Effects*)globalCtx->specialEffects; + s16 i; + u8 phi_a0; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(D_809E0438); i++, effect++) { + if (effect->unk_24 == 1) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); + gDPSetEnvColor(POLY_XLU_DISP++, 185, 140, 70, 128); + flag++; + } + + phi_a0 = effect->unk_2C; + if (effect->unk_2C > 255) { + phi_a0 = 255; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 185, 140, 70, phi_a0); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, effect->unk_26 + (i * 3), + (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustModelDL); + } + } + + effect = (Boss02Effects*)globalCtx->specialEffects; + for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) { + if (effect->unk_24 == 3) { + if (!flag) { + gDPSetCombineLERP(POLY_OPA_DISP++, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, 0, SHADE, 0, PRIMITIVE, + 0, SHADE, 0, PRIMITIVE, 0); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x01, 100, 100, 120, 255); + flag++; + } + Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); + Matrix_RotateYS(effect->unk_30, MTXMODE_APPLY); + Matrix_RotateXS(effect->unk_2E, MTXMODE_APPLY); + Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, + 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_01A620); + } + } + + effect = (Boss02Effects*)globalCtx->specialEffects; + for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) { + if (effect->unk_24 == 4) { + if (!flag) { //! @bug - dev forgot to set flag to 1, should only apply to first entry? + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)effect->unk_2C); + + Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); + } + } + + effect = (Boss02Effects*)globalCtx->specialEffects; + for (i = 0, flag = false; i < ARRAY_COUNT(D_809E0438); i++, effect++) { + if (effect->unk_24 == 2) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustMaterialDL); + gDPSetEnvColor(POLY_XLU_DISP++, 30, 30, 30, 128); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 30, 30, 30, (u8)effect->unk_2C); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, effect->unk_26 + (i * 3), + (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_Translate(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gTwinmoldDustModelDL); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_809DD934(Boss02* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 i; + Actor* temp_a0_5; + Vec3f sp58; + u8 sp57 = 0; + f32 phi_f0_2; + s16 phi_v1; + + this->unk_1D14++; + + switch (this->unk_1D18) { + case 0: + if (player->stateFlags1 & 0x100) { + Cutscene_Start(globalCtx, &globalCtx->csCtx); + this->unk_1D22 = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->unk_1D22, 7); + func_8016566C(150); + this->unk_1D14 = 0; + this->unk_1D5C = 0.0f; + this->unk_1D58 = 0.0f; + if (D_809E0422 == 0) { + this->unk_1D18 = 1; + this->unk_1D68 = 10.0f; + this->unk_1D64 = 60.0f; + this->unk_1D6C = 23.0f; + this->unk_1D70 = 0.01f; + this->unk_1D74 = 0.0f; + goto label1; + } else { + this->unk_1D18 = 10; + this->unk_1D68 = 10.0f; + this->unk_1D64 = 200.0f; + this->unk_1D6C = 273.0f; + this->unk_1D70 = 0.1f; + this->unk_1D74 = -100.0f; + sp57 = 1; + goto label2; + } + } + break; + + case 1: + if ((this->unk_1D14 < 80U) && (D_809E0420 != 0) && + CHECK_BTN_ANY(CONTROLLER1(globalCtx)->press.button, + BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) { + this->unk_1D18++; + this->unk_1D78 = 1; + this->unk_1D14 = 0; + } else { + label1: + if (this->unk_1D14 >= 50U) { + if (this->unk_1D14 == (u32)(BREG(43) + 60)) { + play_sound(NA_SE_PL_TRANSFORM_GIANT); + } + Math_ApproachF(&this->unk_1D64, 200.0f, 0.1f, this->unk_1D5C * 640.0f); + Math_ApproachF(&this->unk_1D6C, 273.0f, 0.1f, this->unk_1D5C * 150.0f); + Math_ApproachF(&this->unk_1D70, 0.1f, 0.2f, this->unk_1D5C * 0.1f); + Math_ApproachF(&this->unk_1D74, -100.0f, 1.0f, this->unk_1D5C * 100.0f); + Math_ApproachF(&this->unk_1D5C, 1.0f, 1.0f, 0.001f); + } else { + Math_ApproachF(&this->unk_1D64, 30.0f, 0.1f, 1.0f); + } + + if (this->unk_1D14 > 50U) { + Math_ApproachZeroF(&this->unk_1D58, 1.0f, 0.06f); + } else { + Math_ApproachF(&this->unk_1D58, 0.4f, 1.0f, 0.02f); + } + + if (this->unk_1D14 == 107U) { + this->unk_1D78 = 1; + } + + if (this->unk_1D14 < 121U) { + break; + } + + sp57 = 1; + D_809E0420 = 1; + goto block_38; + } + break; + + case 2: + if (this->unk_1D14 < 8U) { + break; + } + sp57 = 1; + goto block_38; + + case 10: + if ((this->unk_1D14 < 30U) && (D_809E0421 != 0) && + CHECK_BTN_ANY(CONTROLLER1(globalCtx)->press.button, + BTN_A | BTN_B | BTN_CUP | BTN_CDOWN | BTN_CLEFT | BTN_CRIGHT)) { + this->unk_1D18++; + this->unk_1D78 = 1; + this->unk_1D14 = 0; + break; + } + + label2: + if (this->unk_1D14 != 0U) { + if (this->unk_1D14 == (u32)(BREG(44) + 10)) { + play_sound(NA_SE_PL_TRANSFORM_NORAML); + } + Math_ApproachF(&this->unk_1D64, 60.0f, 0.1f, this->unk_1D5C * 640.0f); + Math_ApproachF(&this->unk_1D6C, 23.0f, 0.1f, this->unk_1D5C * 150.0f); + Math_ApproachF(&this->unk_1D70, 0.01f, 0.1f, 0.003f); + Math_ApproachF(&this->unk_1D74, 0.0f, 1.0f, this->unk_1D5C * 100.0f); + Math_ApproachF(&this->unk_1D5C, 2.0f, 1.0f, 0.01f); + } + + if (this->unk_1D14 == 42U) { + this->unk_1D78 = 1; + } + + if (this->unk_1D14 > 50U) { + D_809E0421 = 1; + goto block_38; + } + break; + + case 11: + if (this->unk_1D14 < 8U) { + break; + } + + block_38: + case 20: + this->unk_1D18 = 0; + func_80169AFC(globalCtx, this->unk_1D22, 0); + this->unk_1D22 = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + this->actor.flags |= ACTOR_FLAG_1; + player->stateFlags1 &= ~0x100; + this->unk_1D70 = 0.01f; + func_80165690(); + break; + } + + if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { + Actor_SetScale(&player->actor, this->unk_1D70 * 1.5f); + } else { + Actor_SetScale(&player->actor, this->unk_1D70); + } + + globalCtx->envCtx.lightSettings.fogNear = this->unk_1D74; + + if (sp57) { + D_809E0422 = 1 - D_809E0422; + if (D_809E0422 == 0) { + D_809DF5B0 = 1.0f; + } else { + D_809DF5B0 = 0.1f; + } + + this->unk_01AC = D_809DF5B0; + if (D_809E0422 == 0) { + if (D_809E0434 != NULL) { + D_809E0434->unk_203 = 0; + D_809E0434->unk_204 = 1.0f; + D_809E0434->dyna.actor.world.pos.y = 60.0f; + } + + player->actor.world.pos.x *= 10.0f; + player->actor.world.pos.y -= 3150.0f; + player->actor.world.pos.y *= 10.0f; + player->unk_B68 = player->actor.world.pos.y; + player->actor.world.pos.z *= 10.0f; + + if ((D_809E0434 != NULL) && ((SQ(player->actor.world.pos.z) + SQ(player->actor.world.pos.x)) < SQ(60.0f))) { + player->actor.world.pos.z = 60.0f; + player->actor.world.pos.x = 60.0f; + } + + D_809E0424->actor.world.pos.x *= 10.0f; + D_809E0424->actor.world.pos.y -= 3150.0f; + D_809E0424->actor.world.pos.y *= 10.0f; + D_809E0424->actor.world.pos.z *= 10.0f; + + D_809E0424->unk_0170.x *= 10.0f; + D_809E0424->unk_0170.y -= 3150.0f; + D_809E0424->unk_0170.y *= 10.0f; + D_809E0424->unk_0170.z *= 10.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_01BC); i++) { + D_809E0424->unk_01BC[i].x *= 10.0f; + D_809E0424->unk_01BC[i].y -= 3150.0f; + D_809E0424->unk_01BC[i].y *= 10.0f; + D_809E0424->unk_01BC[i].z *= 10.0f; + } + + D_809E0424->unk_01B0.x *= 10.0f; + D_809E0424->unk_01B0.y -= 3150.0f; + D_809E0424->unk_01B0.y *= 10.0f; + D_809E0424->unk_01B0.z *= 10.0f; + + D_809E0424->unk_017C.y -= 3150.0f; + D_809E0424->unk_017C.y *= 10.0f; + D_809E0424->unk_0188.y -= 3150.0f; + D_809E0424->unk_0188.y *= 10.0f; + + D_809E0428->actor.world.pos.x *= 10.0f; + D_809E0428->actor.world.pos.y -= 3150.0f; + D_809E0428->actor.world.pos.y *= 10.0f; + D_809E0428->actor.world.pos.z *= 10.0f; + + D_809E0428->unk_0170.x *= 10.0f; + D_809E0428->unk_0170.y -= 3150.0f; + D_809E0428->unk_0170.y *= 10.0f; + D_809E0428->unk_0170.z *= 10.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_01BC); i++) { + D_809E0428->unk_01BC[i].x *= 10.0f; + D_809E0428->unk_01BC[i].y -= 3150.0f; + D_809E0428->unk_01BC[i].y *= 10.0f; + D_809E0428->unk_01BC[i].z *= 10.0f; + } + + D_809E0428->unk_01B0.x *= 10.0f; + D_809E0428->unk_01B0.y -= 3150.0f; + D_809E0428->unk_01B0.y *= 10.0f; + D_809E0428->unk_01B0.z *= 10.0f; + + D_809E0428->unk_017C.y -= 3150.0f; + D_809E0428->unk_017C.y *= 10.0f; + D_809E0428->unk_0188.y -= 3150.0f; + D_809E0428->unk_0188.y *= 10.0f; + + } else { + if (D_809E0434 != 0) { + D_809E0434->unk_203 = 1; + D_809E0434->unk_204 = 0.1f; + D_809E0434->dyna.actor.world.pos.y = 3155.0f; + } + + player->actor.world.pos.x *= 0.1f; + player->actor.world.pos.y *= 0.1f; + player->actor.world.pos.y += 3150.0f; + player->unk_B68 = player->actor.world.pos.y; + player->actor.world.pos.z *= 0.1f; + + D_809E0424->actor.world.pos.x *= 0.1f; + D_809E0424->actor.world.pos.y *= 0.1f; + D_809E0424->actor.world.pos.y += 3150.0f; + D_809E0424->actor.world.pos.z *= 0.1f; + + D_809E0424->unk_0170.x *= 0.1f; + D_809E0424->unk_0170.y *= 0.1f; + D_809E0424->unk_0170.y += 3150.0f; + D_809E0424->unk_0170.z *= 0.1f; + + for (i = 0; i < ARRAY_COUNT(this->unk_01BC); i++) { + D_809E0424->unk_01BC[i].x *= 0.1f; + D_809E0424->unk_01BC[i].y *= 0.1f; + D_809E0424->unk_01BC[i].y += 3150.0f; + D_809E0424->unk_01BC[i].z *= 0.1f; + } + + D_809E0424->unk_01B0.x *= 0.1f; + D_809E0424->unk_01B0.y *= 0.1f; + D_809E0424->unk_01B0.y += 3150.0f; + D_809E0424->unk_01B0.z *= 0.1f; + + D_809E0424->unk_017C.y *= 0.1f; + D_809E0424->unk_017C.y += 3150.0f; + D_809E0424->unk_0188.y *= 0.1f; + D_809E0424->unk_0188.y += 3150.0f; + + D_809E0428->actor.world.pos.x *= 0.1f; + D_809E0428->actor.world.pos.y *= 0.1f; + D_809E0428->actor.world.pos.y += 3150.0f; + D_809E0428->actor.world.pos.z *= 0.1f; + + D_809E0428->unk_0170.x *= 0.1f; + D_809E0428->unk_0170.y *= 0.1f; + D_809E0428->unk_0170.y += 3150.0f; + D_809E0428->unk_0170.z *= 0.1f; + + for (i = 0; i < ARRAY_COUNT(this->unk_01BC); i++) { + D_809E0428->unk_01BC[i].x *= 0.1f; + D_809E0428->unk_01BC[i].y *= 0.1f; + D_809E0428->unk_01BC[i].y += 3150.0f; + D_809E0428->unk_01BC[i].z *= 0.1f; + } + + D_809E0428->unk_01B0.x *= 0.1f; + D_809E0428->unk_01B0.y *= 0.1f; + D_809E0428->unk_01B0.y += 3150.0f; + D_809E0428->unk_01B0.z *= 0.1f; + + D_809E0428->unk_017C.y *= 0.1f; + D_809E0428->unk_017C.y += 3150.0f; + D_809E0428->unk_0188.y *= 0.1f; + D_809E0428->unk_0188.y += 3150.0f; + } + + player->actor.home.pos = player->actor.world.pos; + player->actor.prevPos = player->actor.world.pos; + + temp_a0_5 = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; + while (temp_a0_5 != NULL) { + if (temp_a0_5->id == ACTOR_BG_INIBS_MOVEBG) { + Actor_MarkForDeath(temp_a0_5); + break; + } + temp_a0_5 = temp_a0_5->next; + } + { + f32 tmp = D_809E0422 ? 3150.0f : 0.0f; + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BG_INIBS_MOVEBG, 0, tmp, 0, 0, 0, 0, D_809E0422); + } + + temp_a0_5 = globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; + while (temp_a0_5 != NULL) { + if ((temp_a0_5->id == ACTOR_EN_TANRON5) || (temp_a0_5->id == ACTOR_ITEM_B_HEART)) { + if (D_809E0422 == 0) { + temp_a0_5->world.pos.y -= 3150.0f; + temp_a0_5->world.pos.y *= 10.0f; + + temp_a0_5->floorHeight -= 3150.0f; + temp_a0_5->floorHeight *= 10.0f; + + phi_f0_2 = 10.0f; + } else { + temp_a0_5->world.pos.y *= 0.1f; + temp_a0_5->world.pos.y += 3150.0f; + + temp_a0_5->floorHeight *= 0.1f; + temp_a0_5->floorHeight += 3150.0f; + + phi_f0_2 = 0.1f; + } + + temp_a0_5->world.pos.x *= phi_f0_2; + temp_a0_5->world.pos.z *= phi_f0_2; + + temp_a0_5->speedXZ *= phi_f0_2; + + temp_a0_5->velocity.x *= phi_f0_2; + temp_a0_5->velocity.y *= phi_f0_2; + temp_a0_5->velocity.z *= phi_f0_2; + + temp_a0_5->gravity *= phi_f0_2; + temp_a0_5->terminalVelocity *= phi_f0_2; + + temp_a0_5->scale.x *= phi_f0_2; + temp_a0_5->scale.y *= phi_f0_2; + temp_a0_5->scale.z *= phi_f0_2; + + if (temp_a0_5->id == ACTOR_ITEM_B_HEART) { + ((ItemBHeart*)temp_a0_5)->unk_168 *= phi_f0_2; + } + } + temp_a0_5 = temp_a0_5->next; + } + } + + switch (this->unk_1D78) { + case 0: + break; + + case 1: + this->unk_1D7A = 0; + func_809DA1D0(globalCtx, 255, 255, 255, 0); + this->unk_1D78 = 2; + play_sound(NA_SE_SY_TRANSFORM_MASK_FLASH); + + case 2: + this->unk_1D7A += 40; + if (this->unk_1D7A >= 400) { + this->unk_1D78 = 3; + } + phi_v1 = this->unk_1D7A; + if (phi_v1 > 255) { + phi_v1 = 255; + } + func_809DA22C(globalCtx, phi_v1); + break; + + case 3: + this->unk_1D7A -= 40; + if (this->unk_1D7A <= 0) { + this->unk_1D7A = 0; + this->unk_1D78 = 0; + func_809DA24C(globalCtx); + } else { + phi_v1 = this->unk_1D7A; + if (phi_v1 > 255) { + phi_v1 = 255; + } + func_809DA22C(globalCtx, phi_v1); + } + break; + } + + if ((this->unk_1D18 != 0) && (this->unk_1D22 != 0)) { + Matrix_RotateYS(player->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(this->unk_1D64, &sp58); + + this->unk_1D24.x = player->actor.world.pos.x + sp58.x; + this->unk_1D24.y = player->actor.world.pos.y + sp58.y + this->unk_1D68; + this->unk_1D24.z = player->actor.world.pos.z + sp58.z; + + this->unk_1D30.x = player->actor.world.pos.x; + this->unk_1D30.y = player->actor.world.pos.y + this->unk_1D6C; + this->unk_1D30.z = player->actor.world.pos.z; + + this->unk_1D54 = Math_SinS(this->unk_1D14 * 1512) * this->unk_1D58; + Matrix_RotateZF(this->unk_1D54, MTXMODE_APPLY); + Matrix_MultVecY(1.0f, &this->unk_1D3C); + Play_CameraSetAtEyeUp(globalCtx, this->unk_1D22, &this->unk_1D30, &this->unk_1D24, &this->unk_1D3C); + ShrinkWindow_SetLetterboxTarget(27); + } +} + +void func_809DEAC4(Boss02* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Boss02* sp68; + Vec3f sp5C; + f32 sp58 = 0.0f; + + this->unk_1D1C++; + if (this->unk_0194 == 0) { + sp68 = D_809E0424; + } else { + sp68 = D_809E0428; + } + + switch (this->unk_1D20) { + case 0: + break; + + case 1: + if ((gSaveContext.save.weekEventReg[52] & 0x20) || ((u32)(KREG(13) + 15) >= this->unk_1D1C)) { + break; + } + Cutscene_Start(globalCtx, &globalCtx->csCtx); + this->unk_1D22 = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->unk_1D22, 7); + this->unk_1D20 = 2; + this->unk_1D1C = 0; + + case 2: + player->actor.shape.rot.y = -0x8000; + player->actor.world.rot.y = player->actor.shape.rot.y; + this->unk_1D24.x = player->actor.world.pos.x - 20.0f; + this->unk_1D24.y = (Player_GetHeight(player) + player->actor.world.pos.y) - 29.0f; + this->unk_1D24.z = player->actor.world.pos.z - 50; + + this->unk_1D30.x = player->actor.world.pos.x; + this->unk_1D30.y = (Player_GetHeight(player) + player->actor.world.pos.y) - 17.0f; + this->unk_1D30.z = player->actor.world.pos.z; + if (this->unk_1D1C >= 30) { + if (this->unk_1D1C == 30) { + func_8013EC44(0.0f, 50, 200, 1); + } + this->unk_0150 += 0x4000; + sp58 = (Math_SinS(this->unk_0150) * (BREG(19) + 5)) * 0.1f; + Matrix_RotateZF(Math_SinS(this->unk_1D1C * 0x3000) * ((KREG(28) * 0.001f) + 0.017f), MTXMODE_NEW); + Matrix_MultVecY(1.0f, &this->unk_1D3C); + func_8019F128(NA_SE_EV_EARTHQUAKE_LAST - SFX_FLAG); + } + + if (this->unk_1D1C == 20) { + this->unk_1D7E = 100; + } + + if (this->unk_1D1C == 45) { + func_800B7298(globalCtx, &this->actor, 21); + D_809E0430 = KREG(91) + 43; + } + + if (this->unk_1D1C == 85) { + D_809E0424->unk_0144 = 11; + D_809E0424->unk_014C = 0; + } + + if (this->unk_1D1C == 92) { + func_8013EC44(0.0f, 255, 30, 100); + } + + if (this->unk_1D1C == 100) { + func_800B7298(globalCtx, &this->actor, 0x73); + } + + if (this->unk_1D1C == 112) { + this->unk_1D20 = 10; + this->unk_1D1C = 0; + } + break; + + case 10: + if (this->unk_1D1C < 310) { + this->unk_1D48 = sp68->actor.world.pos; + this->unk_1D24.x = (sp68->actor.world.pos.x * 50.0f) * 0.001f; + this->unk_1D24.y = (sp68->actor.world.pos.y * 50.0f) * 0.001f; + if (this->unk_1D24.y < 100.0f) { + this->unk_1D24.y = 100.0f; + } + this->unk_1D24.z = (sp68->actor.world.pos.z * 100) * 0.001f; + } + + Math_ApproachF(&this->unk_1D30.x, this->unk_1D48.x, 0.1f, 3000.0f); + Math_ApproachF(&this->unk_1D30.y, this->unk_1D48.y, 0.1f, 3000.0f); + Math_ApproachF(&this->unk_1D30.z, this->unk_1D48.z, 0.1f, 3000.0f); + + if (this->unk_1D1C == 100) { + D_809E0428->unk_0144 = 11; + D_809E0428->unk_014C = 0; + this->unk_0194 = 1; + } + + if (this->unk_1D1C == (u32)(KREG(92) + 125)) { + TitleCard_InitBossName(&globalCtx->state, &globalCtx->actorCtx.titleCtxt, + Lib_SegmentedToVirtual(gTwinmoldTitleCardTex), 160, 180, 128, 40); + } + + if (this->unk_1D1C == (u32)(BREG(27) + 335)) { + func_80169AFC(globalCtx, this->unk_1D22, 0); + this->unk_1D22 = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + this->actor.flags |= ACTOR_FLAG_1; + this->unk_1D20 = 0; + D_809E0424->unk_0144 = D_809E0428->unk_0144 = 3; + D_809E0424->unk_0146[0] = D_809E0428->unk_0146[0] = 60; + gSaveContext.eventInf[5] |= 0x20; + } + break; + + case 100: + if (ActorCutscene_GetCurrentIndex() == -1) { + Cutscene_Start(globalCtx, &globalCtx->csCtx); + this->unk_1D22 = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->unk_1D22, 7); + this->unk_1D20 = 101; + this->unk_1D1C = 0; + this->unk_1D5C = 1.0f; + this->unk_1D30 = sp68->actor.world.pos; + } else { + break; + } + + case 101: + case 102: + case_10x: + if ((this->unk_1D20 == 101) || (this->unk_1D20 == 103)) { + this->unk_1D48 = sp68->actor.world.pos; + } else { + this->unk_1D48 = sp68->unk_147C[sp68->unk_1678]; + } + + this->unk_1D24.x = player->actor.world.pos.x; + this->unk_1D24.y = player->actor.world.pos.y + 100.0f; + if (D_809E0422 == 0) { + if (this->unk_1D24.y < 100.0f) { + this->unk_1D24.y = 100.0f; + } + } else if (this->unk_1D24.y < 3160.0f) { + this->unk_1D24.y = 3160.0f; + } + + if (this->unk_1D48.y < (100.0f * D_809DF5B0)) { + this->unk_1D48.y = (100.0f * D_809DF5B0); + } + + this->unk_1D24.z = player->actor.world.pos.z; + Math_ApproachF(&this->unk_1D30.x, this->unk_1D48.x, 0.3f, this->unk_1D5C * 500.0f); + Math_ApproachF(&this->unk_1D30.y, this->unk_1D48.y, 0.3f, this->unk_1D5C * 500.0f); + Math_ApproachF(&this->unk_1D30.z, this->unk_1D48.z, 0.3f, this->unk_1D5C * 500.0f); + Math_ApproachF(&this->unk_1D5C, 1.0f, 1.0f, 0.02f); + break; + + case 103: + this->unk_0150 += 0x4000; + sp58 = Math_SinS(this->unk_0150); + sp58 = (sp58 * this->unk_0146[0]) * 1.5f; + if (this->unk_1D1C == 30) { + func_80169AFC(globalCtx, this->unk_1D22, 0); + this->unk_1D22 = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + this->unk_1D20 = 0; + this->actor.flags |= ACTOR_FLAG_1; + sp68->unk_0144 = 10; + if ((D_809E0424->unk_0144 >= 10) && (D_809E0428->unk_0144 >= 10)) { + f32 phi_f0; + + this->unk_1D7E = 0; + if (D_809E0422 == 0) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, 0.0f, 30.0f, -150.0f, 0, 1, 0, + 0); + phi_f0 = 60.0f; + } else { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, 0.0f, 3153.0f, -15.0f, 0, 1, 0, + 35); + phi_f0 = 3155.0f; + } + D_809E0434 = (DoorWarp1*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, + ACTOR_DOOR_WARP1, 0.0f, phi_f0, 0.0f, 0, 0, 0, 1); + + if (D_809E0422 == 0) { + D_809E0434->unk_203 = 0; + D_809E0434->unk_204 = 1.0f; + } else { + D_809E0434->unk_203 = 1; + D_809E0434->unk_204 = 0.1f; + } + } + } + goto case_10x; + } + + if ((this->unk_1D20 != 0) && (this->unk_1D22 != 0)) { + sp5C = this->unk_1D24; + sp5C.y += sp58 * D_809DF5B0; + Play_CameraSetAtEyeUp(globalCtx, this->unk_1D22, &this->unk_1D30, &sp5C, &this->unk_1D3C); + this->unk_1D3C.z = this->unk_1D3C.x = 0.0f; + this->unk_1D3C.y = 1.0f; + ShrinkWindow_SetLetterboxTarget(27); + } +} 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 4e000b3ee..6c20814fb 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -2,16 +2,95 @@ #define Z_BOSS_02_H #include "global.h" +#include "objects/object_boss02/object_boss02.h" struct Boss02; typedef void (*Boss02ActionFunc)(struct Boss02*, GlobalContext*); +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3f unk_18; + /* 0x24 */ u8 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ UNK_TYPE1 unk_28[0x4]; + /* 0x2C */ s16 unk_2C; + /* 0x2E */ s16 unk_2E; + /* 0x30 */ s16 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; +} Boss02Effects; // size = 0x3C + typedef struct Boss02 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x152C]; + /* 0x0144 */ u8 unk_0144; + /* 0x0146 */ s16 unk_0146[3]; + /* 0x014C */ s16 unk_014C; + /* 0x014E */ s16 unk_014E; + /* 0x0150 */ s16 unk_0150; + /* 0x0152 */ s16 unk_0152; + /* 0x0154 */ s16 unk_0154; + /* 0x0156 */ s16 unk_0156; + /* 0x0158 */ s16 unk_0158; + /* 0x015A */ s16 unk_015A; + /* 0x015C */ u8 unk_015C; + /* 0x015D */ UNK_TYPE1 unk015D[0x7]; + /* 0x0164 */ f32 unk_0164; + /* 0x0168 */ f32 unk_0168; + /* 0x016C */ s16 unk_016C; + /* 0x0170 */ Vec3f unk_0170; + /* 0x017C */ Vec3f unk_017C; + /* 0x0188 */ Vec3f unk_0188; + /* 0x0194 */ u8 unk_0194; + /* 0x0195 */ u8 unk_0195; + /* 0x0196 */ s16 unk_0196; + /* 0x0198 */ s16 unk_0198; + /* 0x019A */ s16 unk_019A; + /* 0x019C */ f32 unk_019C; + /* 0x01A0 */ f32 unk_01A0; + /* 0x01A4 */ s16 unk_01A4; + /* 0x01A8 */ f32 unk_01A8; + /* 0x01AC */ f32 unk_01AC; + /* 0x01B0 */ Vec3f unk_01B0; + /* 0x01BC */ Vec3f unk_01BC[200]; + /* 0x0B1C */ Vec3f unk_0B1C[200]; + /* 0x147C */ Vec3f unk_147C[23]; + /* 0x1590 */ SkelAnime skelAnime; + /* 0x15D4 */ Vec3s jointTable[TWINMOLD_HEAD_LIMB_MAX]; + /* 0x1622 */ Vec3s morphTable[TWINMOLD_HEAD_LIMB_MAX]; /* 0x1670 */ Boss02ActionFunc actionFunc; - /* 0x1674 */ char unk_1674[0x70C]; + /* 0x1674 */ struct Boss02* unk_1674; // points to the other's instance + /* 0x1678 */ s32 unk_1678; + /* 0x167C */ Vec3f unk_167C; + /* 0x1688 */ ColliderJntSph colliderSphere1; + /* 0x16A8 */ ColliderJntSphElement colliderSphere1Elements[22]; + /* 0x1C28 */ ColliderJntSph colliderSphere2; + /* 0x1C48 */ ColliderJntSphElement colliderSphere2Elements[2]; + /* 0x1CC8 */ ColliderCylinder colliderCylinder; + /* 0x1D14 */ u32 unk_1D14; + /* 0x1D18 */ s16 unk_1D18; + /* 0x1D1A */ s16 unk_1D1A; + /* 0x1D1C */ u32 unk_1D1C; + /* 0x1D20 */ s16 unk_1D20; + /* 0x1D22 */ s16 unk_1D22; + /* 0x1D24 */ Vec3f unk_1D24; + /* 0x1D30 */ Vec3f unk_1D30; + /* 0x1D3C */ Vec3f unk_1D3C; + /* 0x1D48 */ Vec3f unk_1D48; + /* 0x1D54 */ f32 unk_1D54; + /* 0x1D58 */ f32 unk_1D58; + /* 0x1D5C */ f32 unk_1D5C; + /* 0x1D60 */ UNK_TYPE1 unk1D60[0x4]; + /* 0x1D64 */ f32 unk_1D64; + /* 0x1D68 */ f32 unk_1D68; + /* 0x1D6C */ f32 unk_1D6C; + /* 0x1D70 */ f32 unk_1D70; + /* 0x1D74 */ f32 unk_1D74; + /* 0x1D78 */ u8 unk_1D78; + /* 0x1D7A */ s16 unk_1D7A; + /* 0x1D7C */ s16 unk_1D7C; + /* 0x1D7E */ s16 unk_1D7E; } Boss02; // size = 0x1D80 extern const ActorInit Boss_02_InitVars; diff --git a/src/overlays/actors/ovl_Boss_03/z_boss_03.c b/src/overlays/actors/ovl_Boss_03/z_boss_03.c index 7e335424b..1959ba26b 100644 --- a/src/overlays/actors/ovl_Boss_03/z_boss_03.c +++ b/src/overlays/actors/ovl_Boss_03/z_boss_03.c @@ -1,9 +1,82 @@ -#include "z_boss_03.h" +/* + * File: z_boss_03.c + * Overlay: ovl_Boss_03 + * Description: Gyorg + */ -#define FLAGS 0x00000035 +/** + * Some notes: + * + * Global flags: + * - gSaveContext.eventInf[5] & 0x40: Enabled when Gyorg's intro cutscene has been watched + * - gSaveContext.save.weekEventReg[55] & 0x80: Checked to know if Gyorg has been defeated + * + * Seaweed: + * - Refers to the seaweed at the bottom of the stage where Player fights Gyorg + * - The default Gyorg actor will spawn 5 other Gyorg instances using the parameter GYORG_PARAM_SEAWEED to spawn them + * - Seaweed can bend when the main Gyorg instance (the actual boss) or Player are near + * + * This actor makes some heavy assumptions about the positions of the room where it is spawned + * + * Cutscenes: + * - There are 3 cutscenes: + * - IntroCutscene: The cs which is played when Player falls into the main room. It also shows Gyorg's titlecard + * - SpawnSmallFishesCutscene: The short cs which is played when Gyorg is spawning the small fishes (EnTanron3). This + * is triggered when Gyorg reaches half of its life + * - DeathCutscene: Played when Gyorg dies. Showing it splashing and becoming smaller each time until it disappears + * - This actor mainly handles the 3 cutscenes it has manually (instead of relying on existing systems for it) + * + * Main behaviour: + * - Gyorg has two types of behaviour depending on Player's state: + * - If Player is standing on the main platform, then Gyorg follows the PrepareCharge -> Charge -> JumpOverPlatform + * branch + * - Otherwise, Gyorg follows the ChasePlayer -> CatchPlayer -> ChewPlayer branch + * - The main actionFunc which decides which branch should be taken is func_809E34B8 + * - Most of the actions of those two branches are constantly checking for the WORK_TIMER_CURRENT_ACTION timer. If it + * runs out, then the behaviour resets back to func_809E34B8 + * - Either branch behaviour can be interrupted at any time by a hit from Player + * - Being hit once makes Gyorg Stunned + * - When Gyorg is Stunned, it is vulnerable to be Damaged by Player + * - When Gyorg's health drops below half, it spawns the small fishes + * + * The collision logic is handled manually + * + * This file is more or less sectioned like this: + * - SpawnEffect + * - RNG + * - Gyorg + * - Init and actionFuncs + * - Cutscenes + * - More actionFuncs and Update + * - Draw + * - Effect Update/Draw + * - Seaweed + */ + +#include "z_boss_03.h" +#include "overlays/actors/ovl_Door_Warp1/z_door_warp1.h" +#include "overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_water_effect/object_water_effect.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss03*)thisx) +#define WORK_TIMER_UNK0_A 0 // used in func_809E34B8 +#define WORK_TIMER_CURRENT_ACTION 0 +#define WORK_TIMER_UNK0_C 0 // used in DeathCutscene + +#define WORK_TIMER_UNK1_A 1 // used in func_809E34B8 +#define WORK_TIMER_UNK1_B 1 // used in PrepareCharge + +#define WORK_TIMER_UNK2_A 2 // used in func_809E34B8 +#define WORK_TIMER_STUNNED 2 + +// The Y position of the top of the platform +#define PLATFORM_HEIGHT 440.0f +#define WATER_HEIGHT 430.0f + void Boss03_Init(Actor* thisx, GlobalContext* globalCtx); void Boss03_Destroy(Actor* thisx, GlobalContext* globalCtx); void Boss03_Update(Actor* thisx, GlobalContext* globalCtx); @@ -11,18 +84,200 @@ void Boss03_Draw(Actor* thisx, GlobalContext* globalCtx); void func_809E344C(Boss03* this, GlobalContext* globalCtx); void func_809E34B8(Boss03* this, GlobalContext* globalCtx); -void func_809E3968(Boss03* this, GlobalContext* globalCtx); -void func_809E3D98(Boss03* this, GlobalContext* globalCtx); -void func_809E421C(Boss03* this, GlobalContext* globalCtx); -void func_809E475C(Boss03* this, GlobalContext* globalCtx); -void func_809E497C(Boss03* this, GlobalContext* globalCtx); -void func_809E4C90(Boss03* this, GlobalContext* globalCtx); -void func_809E4E80(Boss03* this, GlobalContext* globalCtx); -void func_809E5B64(Boss03* this, GlobalContext* globalCtx); -void func_809E6640(Boss03* this, GlobalContext* globalCtx); -void func_809E6BC0(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupChasePlayer(Boss03* this, GlobalContext* globalCtx); +void Boss03_ChasePlayer(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupCatchPlayer(Boss03* this, GlobalContext* globalCtx, u8 arg2); +void Boss03_CatchPlayer(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupChewPlayer(Boss03* this, GlobalContext* globalCtx); +void Boss03_ChewPlayer(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupPrepareCharge(Boss03* this, GlobalContext* globalCtx); +void Boss03_PrepareCharge(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupCharge(Boss03* this, GlobalContext* globalCtx); +void Boss03_Charge(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupJumpOverPlatform(Boss03* this, GlobalContext* globalCtx); +void Boss03_JumpOverPlatform(Boss03* this, GlobalContext* globalCtx); +void Boss03_SetupIntroCutscene(Boss03* this, GlobalContext* globalCtx); +void Boss03_IntroCutscene(Boss03* this, GlobalContext* globalCtx); +void Boss03_DeathCutscene(Boss03* this, GlobalContext* globalCtx); +void Boss03_SpawnSmallFishesCutscene(Boss03* this, GlobalContext* globalCtx); +void Boss03_Stunned(Boss03* this, GlobalContext* globalCtx); +void Boss03_Damaged(Boss03* this, GlobalContext* globalCtx); + +void Boss03_UpdateEffects(GlobalContext* globalCtx); +void Boss03_DrawEffects(GlobalContext* globalCtx); + +void Boss03_SeaweedUpdate(Actor* thisx, GlobalContext* globalCtx); +void Boss03_SeaweedDraw(Actor* thisx, GlobalContext* globalCtx); + +u8 D_809E9840; +// Timer used to start playing the boss background music if the intro cutscene was skipped (because it was already +// watched) +u8 D_809E9841; +// Used to set the timer D_809E9841 in case the intro cutscene was skipped +u8 D_809E9842; + +// Set to Gyorg's projectedPos. sGyorgProjectedPos? +Vec3f D_809E9848; + +GyorgEffect sGyorgEffects[GYORG_EFFECT_COUNT]; + +// Used by the Seaweed variant to interact with the "real" Gyorg boss +Boss03* sGyorgBossInstance; + +void Boss03_PlayUnderwaterSfx(Vec3f* projectedPos, u16 sfxId) { + func_8019F420(projectedPos, sfxId); +} + +/* Start of SpawnEffect section */ + +void Boss03_SpawnEffectWetSpot(GlobalContext* globalCtx, Vec3f* pos) { + s16 i; + GyorgEffect* eff = globalCtx->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_WET_SPOT; + eff->pos = *pos; + eff->unk_34.x = 0.1f; + eff->unk_34.y = 0.4f; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->alpha = 150; + eff->alphaDelta = Rand_ZeroFloat(4.0f) + 5.0f; + return; + } + + eff++; + } +} + +void Boss03_SpawnEffectDroplet(GlobalContext* globalCtx, Vec3f* pos) { + s16 i; + GyorgEffect* eff = globalCtx->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_DROPLET; + eff->pos = *pos; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->accel.y = -2.0f; + eff->unk_34.x = 0.1f; + eff->unk_34.y = 0.0f; + eff->unk_34.z = Rand_ZeroFloat(2 * M_PI); + eff->unk_02 = Rand_ZeroFloat(100.0f); + eff->velocity.x = randPlusMinusPoint5Scaled(25.0f); + eff->velocity.z = randPlusMinusPoint5Scaled(25.0f); + return; + } + + eff++; + } +} + +void Boss03_SpawnEffectSplash(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity) { + Vec3f accel = { 0.0f, -1.0f, 0.0f }; + f32 temp_f2; + GyorgEffect* eff = globalCtx->specialEffects; + s16 i; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if ((eff->type == GYORG_EFFECT_NONE) || (eff->type == GYORG_EFFECT_BUBBLE)) { + eff->type = GYORG_EFFECT_SPLASH; + eff->pos = *pos; + eff->velocity = *velocity; + eff->accel = accel; + temp_f2 = Rand_ZeroFloat(0.02f) + 0.02f; + eff->unk_34.y = temp_f2; + eff->unk_34.x = temp_f2; + eff->unk_34.z = Rand_ZeroFloat(2 * M_PI); + eff->unk_02 = Rand_ZeroFloat(100.0f); + return; + } + + eff++; + } +} + +void Boss03_SpawnEffectBubble(GlobalContext* globalCtx, Vec3f* pos) { + s16 i; + GyorgEffect* eff = globalCtx->specialEffects; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++) { + if (eff->type == GYORG_EFFECT_NONE) { + eff->type = GYORG_EFFECT_BUBBLE; + eff->pos = *pos; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->accel.y = 0.2f; + eff->unk_34.x = Rand_ZeroFloat(0.3f) + 0.2f; + eff->unk_02 = 0; + return; + } + + eff++; + } +} + +/* End of SpawnEffect section */ + +void Boss03_UpdateSphereElement(s32 index, ColliderJntSph* collider, Vec3f* sphereCenter) { + ColliderJntSphElement* sphElement; + + collider->elements[index].dim.worldSphere.center.x = sphereCenter->x; + collider->elements[index].dim.worldSphere.center.y = sphereCenter->y; + collider->elements[index].dim.worldSphere.center.z = sphereCenter->z; + + sphElement = &collider->elements[index]; + sphElement->dim.worldSphere.radius = sphElement->dim.scale * sphElement->dim.modelSphere.radius; +} + +/* Start of RNG section */ + +static s32 sRandSeed0; +static s32 sRandSeed1; +static s32 sRandSeed2; + +void Boss03_SeedRand(s32 seed0, s32 seed1, s32 seed2) { + sRandSeed0 = seed0; + sRandSeed1 = seed1; + sRandSeed2 = seed2; +} + +f32 Boss03_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); +} + +/* End of RNG section */ + +// ACTOR_BG_DBLUE_MOVEBG is never spawned naturally on Gyorg's fight +Actor* Boss03_FindActorDblueMovebg(GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; + + while (actor != NULL) { + if (actor->id == ACTOR_BG_DBLUE_MOVEBG) { + return actor; + } + actor = actor->next; + } + + return NULL; +} + +/* Start of Gyorg's Init and actionFuncs section */ -#if 0 const ActorInit Boss_03_InitVars = { ACTOR_BOSS_03, ACTORCAT_BOSS, @@ -35,157 +290,2347 @@ const ActorInit Boss_03_InitVars = { (ActorFunc)Boss03_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_809E8ECC[2] = { +// The limbs referenced here are not used. The spheres are positioned manually by Boss03_PostLimbDraw +static ColliderJntSphElementInit sHeadJntSphElementsInit[] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 0, { { 0, 0, 0 }, 70 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_NONE, { { 0, 0, 0 }, 70 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 1, { { 0, 0, 0 }, 50 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_ROOT, { { 0, 0, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809E8F14 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_809E8ECC, // sJntSphElementsInit, +static ColliderJntSphInit sHeadJntSphInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sHeadJntSphElementsInit), + sHeadJntSphElementsInit, }; -// static ColliderJntSphElementInit sJntSphElementsInit[5] = { -static ColliderJntSphElementInit D_809E8F24[5] = { +// The limbs referenced here are not used. The spheres are positioned manually by Boss03_PostLimbDraw +static ColliderJntSphElementInit sBodyJntSphElementsInit[] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 2, { { 0, 0, 0 }, 20 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_HEAD, { { 0, 0, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 5, { { 0, 0, 0 }, 20 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_LOWER_TRUNK, { { 0, 0, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 6, { { 0, 0, 0 }, 70 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_TAIL, { { 0, 0, 0 }, 70 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 7, { { 0, 0, 0 }, 70 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_RIGHT_FIN_ROOT, { { 0, 0, 0 }, 70 }, 100 }, }, { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 8, { { 0, 0, 0 }, 30 }, 100 }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { GYORG_LIMB_UPPER_RIGHT_FIN, { { 0, 0, 0 }, 30 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809E8FD8 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 5, D_809E8F24, // sJntSphElementsInit, +static ColliderJntSphInit sBodyJntSphInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sBodyJntSphElementsInit), + sBodyJntSphElementsInit, }; -#endif +Vec3f sGyorgInitialPos = { 1216.0f, 140.0f, -1161.0f }; -extern ColliderJntSphElementInit D_809E8ECC[2]; -extern ColliderJntSphInit D_809E8F14; -extern ColliderJntSphElementInit D_809E8F24[5]; -extern ColliderJntSphInit D_809E8FD8; +// unused +Vec3f D_809E8FF4[] = { + { 261.0f, 140.0f, -1000.0f }, { -504.0f, 120.0f, -1276.0f }, { -1157.0f, 80.0f, -836.0f }, + { -1020.0f, 120.0f, 381.0f }, { -34.0f, 120.0f, 1213.0f }, { 803.0f, 80.0f, 1250.0f }, + { 1143.0f, 120.0f, 605.0f }, { 1228.0f, 140.0f, -244.0f }, { 1216.0f, 140.0f, -1161.0f }, + { 261.0f, 140.0f, -1000.0f }, { -504.0f, 120.0f, -890.0f }, { -1157.0f, 80.0f, -836.0f }, + { -1020.0f, 120.0f, 381.0f }, { -34.0f, 120.0f, 1213.0f }, { 803.0f, 80.0f, 1250.0f }, + { 1143.0f, 120.0f, 605.0f }, { 1228.0f, 140.0f, -244.0f }, { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, +}; -extern UNK_TYPE D_06007EB0; -extern UNK_TYPE D_06007EC8; -extern UNK_TYPE D_06009554; -extern UNK_TYPE D_060099D0; -extern UNK_TYPE D_06009C14; -extern UNK_TYPE D_06009CF8; -extern UNK_TYPE D_0600A6C8; +Color_RGBA8 sGyorgDustPrimColor = { 60, 50, 20, 255 }; +Color_RGBA8 sGyorgDustEnvColor = { 40, 30, 30, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2760.s") +/** + * Used when chasing Player and Gyorg is near the bottom + */ +void Boss03_SpawnDust(Boss03* this, GlobalContext* globalCtx) { + if (this->insideJawPos.y < 80.0f) { + u8 i; + Vec3f pos; + Vec3f velocity; + Vec3f accel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2788.s") + for (i = 0; i < 5; i++) { + velocity.x = randPlusMinusPoint5Scaled(10.0f); + velocity.y = Rand_ZeroFloat(2.0f) + 2.0f; + velocity.z = randPlusMinusPoint5Scaled(10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2880.s") + accel.y = -0.075f; + accel.z = 0.0f; + accel.x = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E299C.s") + pos.y = Rand_ZeroFloat(20.0f) + 5.0f; + pos.z = randPlusMinusPoint5Scaled(150.0f) + this->insideJawPos.z; + pos.x = randPlusMinusPoint5Scaled(150.0f) + this->insideJawPos.x; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2AB4.s") + func_800B0EB0(globalCtx, &pos, &velocity, &accel, &sGyorgDustPrimColor, &sGyorgDustEnvColor, + Rand_ZeroFloat(200.0f) + 400.0f, 10, Rand_ZeroFloat(10.0f) + 25.0f); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2B8C.s") +void Boss03_Init(Actor* thisx, GlobalContext* globalCtx2) { + Boss03* this = THIS; + s32 i; + GlobalContext* globalCtx = globalCtx2; + Vec3f sp70; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2C1C.s") + if (gSaveContext.save.weekEventReg[55] & 0x80) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_WARP1, 0.0f, PLATFORM_HEIGHT, + 200.0f, 0, 0, 0, ENDOORWARP1_FF_1); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, 0.0f, PLATFORM_HEIGHT, 0.0f, 0, 0, 0, 0); + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2C3C.s") + if (this->actor.params == GYORG_PARAM_SEAWEED) { + this->actor.update = Boss03_SeaweedUpdate; + this->actor.draw = Boss03_SeaweedDraw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2D64.s") + this->unk_240 = Rand_ZeroFloat(1000.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E2DA0.s") + this->actor.scale.x = Rand_ZeroFloat(0.0075f) + 0.027f; + this->actor.scale.y = 0.02f; + this->actor.scale.z = 0.015f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/Boss03_Init.s") + // Manually set the joint table of seaweed + for (i = 0; i < 6; i++) { + this->jointTable[i].x = Math_SinS(this->unk_240 * 0x100 + i * 15000) * 3000.0f; + this->jointTable[i].y = Math_SinS(this->unk_240 * 0x180 + i * 20000) * 2000.0f; + this->jointTable[i].z = Math_SinS(this->unk_240 * 0x10 + i * 19000) * 4000.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/Boss03_Destroy.s") + this->actor.flags &= ~ACTOR_FLAG_1; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E344C.s") + this->actor.world.pos = sGyorgInitialPos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E34B8.s") + // Since Boss03_RandZeroOne is only used on this Init function, the resulting values end up being deterministic + Boss03_SeedRand(1, 29093, 9786); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E38EC.s") + for (i = 0; i < 5; i++) { + f32 rand; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E3968.s") + rand = Boss03_RandZeroOne(); + Matrix_RotateYF((rand * M_PI * 0.2f) + ((2.0f * M_PI / 5.0f) * i), MTXMODE_NEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E3D34.s") + rand = Boss03_RandZeroOne(); + Matrix_MultVecZ((rand * 800.0f) + 400.0f, &sp70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E3D98.s") + rand = Boss03_RandZeroOne(); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BOSS_03, sp70.x, sp70.y, sp70.z, 0, rand * 0x10000, 0, + GYORG_PARAM_SEAWEED); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4180.s") + sGyorgBossInstance = this; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E421C.s") + globalCtx->specialEffects = sGyorgEffects; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4674.s") + for (i = 0; i < ARRAY_COUNT(sGyorgEffects); i++) { + sGyorgEffects[i].type = GYORG_EFFECT_NONE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E475C.s") + this->actor.targetMode = 5; + this->actor.colChkInfo.mass = MASS_HEAVY; + this->actor.colChkInfo.health = 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4910.s") + Collider_InitAndSetJntSph(globalCtx, &this->headCollider, &this->actor, &sHeadJntSphInit, + this->headColliderElements); + Collider_InitAndSetJntSph(globalCtx, &this->bodyCollider, &this->actor, &sBodyJntSphInit, + this->bodyColliderElements); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGyorgSkel, &gGyorgCrawlingAnim, this->jointTable, + this->morphTable, GYORG_LIMB_MAX); + Actor_SetScale(&this->actor, 0.2f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E497C.s") + // gSaveContext.eventInf[5] & 0x40: intro cutscene already watched + if ((KREG(64) != 0) || (gSaveContext.eventInf[5] & 0x40)) { + this->actionFunc = func_809E344C; + D_809E9842 = false; + Audio_QueueSeqCmd(NA_BGM_STOP | 0x10000); + } else { + Boss03_SetupIntroCutscene(this, globalCtx); + D_809E9842 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4C34.s") + this->numSpawnedSmallFish = -1; + this->waterHeight = WATER_HEIGHT; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4C90.s") +void Boss03_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Boss03* this = THIS; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4E2C.s") +/* Start of ActionFuncs section */ -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E4E80.s") +void func_809E344C(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E5ADC.s") + // Mid-air + if (player->actor.world.pos.y < 540.0f) { + this->actionFunc = func_809E34B8; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFastSwimmingAnim, -15.0f); + this->unk_274 = 0; + this->actor.flags |= ACTOR_FLAG_1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E5B64.s") +/** + * Swims randomly until WORK_TIMER_UNK1_A runs out + */ +void func_809E34B8(Boss03* this, GlobalContext* globalCtx) { + f32 xDiff; + f32 yDiff; + f32 zDiff; + f32 bodyYRotTarget; + s32 pad; + s16 i; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E65F4.s") + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_WAIT_OLD - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E6640.s") + this->unk_276 = 0x800; + this->skelAnime.playSpeed = 1.0f; + this->unk_27C = 1.0f; + this->unk_278 = 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E69A4.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E6A38.s") + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E6B70.s") + xDiff = this->unk_268.x - this->actor.world.pos.x; + yDiff = this->unk_268.y - this->actor.world.pos.y; + zDiff = this->unk_268.z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E6BC0.s") + Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff), 0xA, this->unk_274); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E6CB4.s") + bodyYRotTarget = + Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, this->unk_274, 0) * -0.5f; + Math_ApproachS(&this->bodyYRot, bodyYRotTarget, 5, 0x100); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/Boss03_Update.s") + Math_ApproachS(&this->unk_274, this->unk_276, 1, 0x100); + Math_ApproachF(&this->actor.speedXZ, this->unk_278, 1.0f, this->unk_27C); + Math_ApproachF(&this->unk_260, sinf(this->skelAnime.curFrame * (M_PI / 5.0f)) * 10.0f * 0.01f, 0.5f, 1.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E7920.s") + if ((this->workTimer[WORK_TIMER_UNK2_A] == 0) && (this->actor.bgCheckFlags & 8)) { + Matrix_MultVecZ(-500.0f, &this->unk_268); + this->unk_268.y = Rand_ZeroFloat(100.0f) + 150.0f; + this->workTimer[WORK_TIMER_UNK2_A] = 60; + this->workTimer[WORK_TIMER_UNK0_A] = Rand_ZeroFloat(60.0f) + 60.0f; + this->unk_274 = 0x100; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E79C4.s") + if (this->workTimer[WORK_TIMER_UNK2_A] == 0) { + if ((sqrtf(SQ(xDiff) + SQ(zDiff)) < 100.0f) || (this->workTimer[WORK_TIMER_UNK0_A] == 0)) { + for (i = 0; i < 200; i++) { + this->unk_268.x = randPlusMinusPoint5Scaled(2500.0f); + this->unk_268.y = Rand_ZeroFloat(100.0f) + 150.0f; + this->unk_268.z = randPlusMinusPoint5Scaled(2500.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E7AA8.s") + xDiff = this->unk_268.x - this->actor.world.pos.x; + zDiff = this->unk_268.z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/Boss03_Draw.s") + if (sqrtf(SQ(xDiff) + SQ(zDiff)) > 300.0f) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E7D00.s") + this->unk_274 = 0x100; + this->workTimer[WORK_TIMER_UNK0_A] = Rand_ZeroFloat(60.0f) + 60.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E81E4.s") + Actor_MoveWithoutGravityReverse(&this->actor); + Math_ApproachS(&this->actor.shape.rot.x, this->actor.world.rot.x, 2, this->unk_274 * 2); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, this->unk_274 * 2); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E8810.s") + if (this->workTimer[WORK_TIMER_UNK1_A] == 0) { + // Player is above water && Player is standing on ground + if ((this->waterHeight < player->actor.world.pos.y) && (player->actor.bgCheckFlags & 1)) { + Boss03_SetupPrepareCharge(this, globalCtx); + } else if ((player->transformation != PLAYER_FORM_GORON) && (player->transformation != PLAYER_FORM_DEKU)) { + if (KREG(70) == 0) { + Boss03_SetupChasePlayer(this, globalCtx); + } else if (this->numSpawnedSmallFish <= 0) { + Boss03_SetupChasePlayer(this, globalCtx); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_03/func_809E8BEC.s") +void Boss03_SetupChasePlayer(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_ChasePlayer; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFastSwimmingAnim, -10.0f); + this->workTimer[WORK_TIMER_CURRENT_ACTION] = 100; + this->unk_276 = 0x1000; + this->skelAnime.playSpeed = 1.5f; + this->unk_278 = 10.0f; + this->unk_27C = 1.0f; +} + +/** + * Approach Player until near enough, then try to catch Player, unless it has since got back on the platform + */ +void Boss03_ChasePlayer(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 xDiff; + f32 yDiff; + f32 zDiff; + f32 bodyYRotTarget; + Vec3f sp50; + s32 pad; + f32 phi_f2; + f32 sp44; + u8 sp43; + + this->unk_2BD = true; + + SkelAnime_Update(&this->skelAnime); + + xDiff = player->actor.world.pos.x - this->actor.world.pos.x; + yDiff = (player->actor.world.pos.y - this->actor.world.pos.y) + 50.0f; + zDiff = player->actor.world.pos.z - this->actor.world.pos.z; + + Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff), 0xA, this->unk_274); + bodyYRotTarget = + Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, this->unk_274, 0) * -0.5f; + Math_ApproachS(&this->bodyYRot, bodyYRotTarget, 5, 0x100); + + Math_ApproachS(&this->unk_274, this->unk_276, 1, 0x100); + Math_ApproachF(&this->actor.speedXZ, this->unk_278, 1.0f, this->unk_27C); + Math_ApproachF(&this->unk_260, sinf(this->skelAnime.curFrame * (M_PI / 5.0f)) * 10.0f * 0.01f, 0.5f, 1.0f); + Actor_MoveWithoutGravityReverse(&this->actor); + + Math_ApproachS(&this->actor.shape.rot.x, this->actor.world.rot.x, 2, this->unk_274 * 2); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, this->unk_274 * 2); + + // If either (Player is standing on ground && Player is above water) or (WORK_TIMER_CURRENT_ACTION timer runs out), + // then stop chasing + if (((player->actor.bgCheckFlags & 1) && (player->actor.shape.feetPos[0].y >= WATER_HEIGHT + 8.0f)) || + (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 0)) { + if (&this->actor == player->actor.parent) { + player->unk_AE8 = 101; + player->actor.parent = NULL; + player->csMode = 0; + } + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 100; + } else { + if ((this->waterHeight - 80.0f) < player->actor.world.pos.y) { + sp43 = 1; + phi_f2 = 100.0f; + sp44 = 50.0f; + } else { + sp43 = 0; + phi_f2 = 200.0f; + sp44 = 100.0f; + } + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); + Matrix_MultVecZ(sp44, &sp50); + + xDiff = sp50.x - player->actor.world.pos.x; + zDiff = sp50.z - player->actor.world.pos.z; + + if (sqrtf(SQ(xDiff) + SQ(zDiff)) < (2.0f * phi_f2)) { + Math_ApproachS(&this->jawZRot, 0x3200, 2, 0x1800); + this->unk_278 = 25.0f; + this->unk_27C = 5.0f; + this->skelAnime.playSpeed = 2.5f; + } + + // Near enough to Player? + if (sqrtf(SQ(xDiff) + SQ(zDiff)) < phi_f2) { + Boss03_SetupCatchPlayer(this, globalCtx, sp43); + + if (sp43 != 0) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, player->actor.world.pos.x, + this->waterHeight, player->actor.world.pos.z, 0, 0, 0x78, ENWATEREFFECT_777); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_SINK_OLD); + } + + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_UTSUBO_EAT); + } + } + + Boss03_SpawnDust(this, globalCtx); +} + +void Boss03_SetupCatchPlayer(Boss03* this, GlobalContext* globalCtx, u8 arg2) { + this->actionFunc = Boss03_CatchPlayer; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFastSwimmingAnim, -15.0f); + this->workTimer[WORK_TIMER_CURRENT_ACTION] = 100; + this->unk_2C4 = 0.0f; + this->unk_2B8 = 0.0f; + this->unk_242 = arg2; +} + +void Boss03_CatchPlayer(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 xDiff; + f32 yDiff; + f32 zDiff; + s32 pad; + + this->skelAnime.playSpeed = 2.0f; + this->unk_27C = 2.0f; + this->unk_276 = 0x1000; + this->unk_2BD = true; + this->unk_278 = 15.0f; + this->actor.flags &= ~ACTOR_FLAG_1; + + SkelAnime_Update(&this->skelAnime); + + xDiff = player->actor.world.pos.x - this->actor.world.pos.x; + yDiff = player->actor.world.pos.y - this->actor.world.pos.y; + zDiff = player->actor.world.pos.z - this->actor.world.pos.z; + + Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff), 0xA, this->unk_274); + Math_ApproachS(&this->bodyYRot, + Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, this->unk_274, 0) * + -0.5f, + 5, 0x100); + Math_ApproachS(&this->unk_274, this->unk_276, 1, 0x100); + Math_ApproachF(&this->actor.speedXZ, this->unk_278, 1.0f, this->unk_27C); + Math_ApproachF(&this->unk_260, sinf(this->skelAnime.curFrame * (M_PI / 5.0f)) * 10.0f * 0.01f, 0.5f, 1.0f); + Actor_MoveWithoutGravityReverse(&this->actor); + Math_ApproachS(&this->actor.shape.rot.x, this->actor.world.rot.x, 2, this->unk_274 * 2); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, this->unk_274 * 2); + + // If either (Player is standing on ground && Player is above water) or (WORK_TIMER_CURRENT_ACTION timer runs out) + // then stop trying to catch Player + if (((player->actor.bgCheckFlags & 1) && (player->actor.shape.feetPos[FOOT_LEFT].y >= WATER_HEIGHT + 8.0f)) || + (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 0)) { + if (&this->actor == player->actor.parent) { + player->unk_AE8 = 101; + player->actor.parent = NULL; + player->csMode = 0; + func_80165690(); + } + + func_809E344C(this, globalCtx); + // WORK_TIMER_UNK1_A wasn't set + } else { + f32 phi_f0; + + Math_ApproachF(&player->actor.world.pos.x, this->insideJawPos.x, 1.0f, this->unk_2B8); + Math_ApproachF(&player->actor.world.pos.y, this->insideJawPos.y, 1.0f, this->unk_2B8); + Math_ApproachF(&player->actor.world.pos.z, this->insideJawPos.z, 1.0f, this->unk_2B8); + + if (this->unk_242 != 0) { + phi_f0 = 10.0f; + } else { + phi_f0 = 2.0f; + } + + Math_ApproachF(&this->unk_2B8, 100.0f, 1.0f, phi_f0); + + if (this->unk_2B8 > 30.0f) { + if ((&this->actor != player->actor.parent) && (globalCtx->grabPlayer(globalCtx, player) != 0)) { + player->actor.parent = &this->actor; + Audio_PlaySfxGeneral(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, + &D_801DB4B8); + Boss03_SetupChewPlayer(this, globalCtx); + } + } else { + Math_ApproachS(&this->jawZRot, 0x3200, 2, 0xC00 * phi_f0); + } + + Math_ApproachS(&player->actor.world.rot.x, 0x4000, 1, 0x400); + Math_ApproachS(&player->actor.shape.rot.x, 0x4000, 1, 0x400); + Math_ApproachS(&player->actor.world.rot.y, this->unk_2A2.y, 1, 0x400); + Math_ApproachS(&player->actor.shape.rot.y, this->unk_2A2.y, 1, 0x400); + } + + Boss03_SpawnDust(this, globalCtx); +} + +void Boss03_SetupChewPlayer(Boss03* this, GlobalContext* globalCtx) { + s16 pitchAngle; + Vec3f out; + + this->actionFunc = Boss03_ChewPlayer; + + pitchAngle = Math_FAtan2F(this->actor.world.pos.z, this->actor.world.pos.x); + Matrix_RotateYS(pitchAngle, MTXMODE_NEW); + + out.x = 0.0f; + out.y = 200.0f; + out.z = 700.0f; + Matrix_MultVec3f(&out, &this->unk_268); + + this->unk_276 = 0x800; + this->unk_242 = 0; + this->workTimer[WORK_TIMER_CURRENT_ACTION] = 100; + this->skelAnime.playSpeed = 1.0f; +} + +void Boss03_ChewPlayer(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Input* input = CONTROLLER1(globalCtx); + f32 jawZRotTarget; + f32 xDiff; + f32 yDiff; + f32 zDiff; + + this->unk_2BD = true; + this->unk_25C = 15; + + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 90) { + func_8016566C(0x96); + } + + SkelAnime_Update(&this->skelAnime); + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); + + xDiff = this->unk_268.x - this->actor.world.pos.x; + yDiff = this->unk_268.y - this->actor.world.pos.y; + zDiff = this->unk_268.z - this->actor.world.pos.z; + + Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff), 0xA, this->unk_274); + Math_ApproachS(&this->bodyYRot, + Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, this->unk_274, 0) * + -0.5f, + 5, 0x100); + Math_ApproachS(&this->unk_274, this->unk_276, 1, 0x100); + Math_ApproachF(&this->unk_260, sinf(this->skelAnime.curFrame * (M_PI / 5.0f)) * 10.0f * 0.01f, 0.5f, 1.0f); + + switch (this->unk_242) { + case 0: + Math_ApproachF(&this->actor.speedXZ, 10.0f, 1.0f, 1.0f); + if (sqrtf(SQ(xDiff) + SQ(zDiff)) < 100.0f) { + this->unk_242 = 1; + Animation_MorphToLoop(&this->skelAnime, &gGyorgBackingUpAnim, -15.0f); + } + break; + + case 1: + Math_ApproachF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f); + Math_ApproachF(&this->actor.world.pos.y, 200.0f, 0.05f, 5.0f); + break; + } + + Actor_MoveWithoutGravityReverse(&this->actor); + + Math_ApproachS(&this->actor.shape.rot.x, this->actor.world.rot.x, 2, this->unk_274 * 2); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, this->unk_274 * 2); + + // Mashing A or B reduces the time Gyorg is chewing Player + if (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_B)) { + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] != 0) { + this->workTimer[WORK_TIMER_CURRENT_ACTION]--; + } + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] != 0) { + this->workTimer[WORK_TIMER_CURRENT_ACTION]--; + } + } + + // Stop chewing when the timer runs out + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 0) { + if (&this->actor == player->actor.parent) { + player->unk_AE8 = 101; + player->actor.parent = NULL; + player->csMode = 0; + func_80165690(); + func_800B8D50(globalCtx, NULL, 10.0f, this->actor.shape.rot.y, 0.0f, 0x20); + } + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = Rand_ZeroFloat(100.0f) + 200.0f; + + return; + } + + player->actor.world.pos = this->insideJawPos; + + jawZRotTarget = Math_SinS(this->unk_240 * 0x2000); + Math_ApproachS(&this->jawZRot, jawZRotTarget * 2000.0f, 2, 0x3000); + + player->actor.shape.rot.x = 0x4000; + player->actor.world.rot.x = player->actor.shape.rot.x; + + player->actor.world.rot.y = player->actor.shape.rot.y = this->unk_2A2.y; + + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] < 5) { + Math_ApproachS(&this->jawZRot, 0x3200, 2, 0x1800); + Math_ApproachF(&this->unk_2C4, 100.0f, 1.0f, 100.0f); + } else { + Math_ApproachF(&this->unk_2C4, -300.0f, 1.0f, 5.0f); + if ((this->unk_240 % 8) == 0) { + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_BITE_OLD); + } + } +} + +void Boss03_SetupPrepareCharge(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_PrepareCharge; + Animation_MorphToLoop(&this->skelAnime, &gGyorgBackingUpAnim, -15.0f); + this->workTimer[WORK_TIMER_CURRENT_ACTION] = Rand_ZeroFloat(30.0f) + 80.0f; + this->workTimer[WORK_TIMER_UNK1_B] = 50; + this->unk_274 = 0; + + if (sqrtf(SQXZ(this->actor.world.pos)) > 600.0f) { + if (Rand_ZeroOne() < 0.5f) { + this->unk_242 = 1; + } else { + this->unk_242 = 0; + } + } else { + this->unk_242 = 0; + } +} + +/** + * Slowly turns back while looking at Player during WORK_TIMER_CURRENT_ACTION frames, then prepares to charge + */ +void Boss03_PrepareCharge(Boss03* this, GlobalContext* globalCtx) { + f32 posYTarget; + Player* player = GET_PLAYER(globalCtx); + + if (this->workTimer[WORK_TIMER_UNK1_B] != 0) { + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_WAIT_OLD - SFX_FLAG); + } + + // Rotate towards Player + Math_ApproachS(&this->bodyYRot, + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, this->unk_274, 0) * + -0.7f, + 5, 0x200); + Math_ApproachS(&this->unk_274, 0x800, 1, 0x100); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 0x1000); + Math_ApproachS(&this->actor.world.rot.x, 0, 0xA, 0x200); + Math_ApproachS(&this->actor.shape.rot.x, 0, 0xA, 0x200); + + posYTarget = this->waterHeight - 70.0f; + if (posYTarget < this->actor.world.pos.y) { + Math_ApproachF(&this->actor.world.pos.y, posYTarget, 0.05f, 5.0f); + } + + SkelAnime_Update(&this->skelAnime); + + // Player is above water && Player is standing on ground + if ((this->waterHeight < player->actor.world.pos.y) && (player->actor.bgCheckFlags & 1)) { + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 0) { + Boss03_SetupCharge(this, globalCtx); + } + } else if (player->actor.world.pos.y <= this->waterHeight) { + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 20; + } + + // Turns back slowly + Math_ApproachF(&this->actor.speedXZ, -3.0f, 1.0f, 0.5f); + Actor_MoveWithoutGravityReverse(&this->actor); +} + +void Boss03_SetupCharge(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->actionFunc = Boss03_Charge; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFastSwimmingAnim, -15.0f); + this->unk_268 = player->actor.world.pos; +} + +/** + * Charge against the platform, either by clashing against the platform or by preparing to jump over it + */ +void Boss03_Charge(Boss03* this, GlobalContext* globalCtx) { + f32 xDiff; + f32 yDiff; + f32 zDiff; + Player* player = GET_PLAYER(globalCtx); + s16 rotXTarget; + + this->skelAnime.playSpeed = 2.0f; + SkelAnime_Update(&this->skelAnime); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_PREATTACK_OLD - SFX_FLAG); + + xDiff = this->unk_268.x - this->actor.world.pos.x; + yDiff = (this->unk_268.y - this->actor.world.pos.y) - 50.0f; + zDiff = this->unk_268.z - this->actor.world.pos.z; + + Math_ApproachS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, 0x1000); + + rotXTarget = Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff); + Math_ApproachS(&this->actor.world.rot.x, rotXTarget, 0xA, 0x1000); + + this->actor.shape.rot = this->actor.world.rot; + + Math_ApproachF(&this->actor.speedXZ, 25.0f, 1.0f, 3.0f); + Math_ApproachF(&this->unk_260, sinf(this->skelAnime.curFrame * (M_PI / 5.0f)) * 10.0f * 0.01f, 0.5f, 1.0f); + Actor_MoveWithoutGravityReverse(&this->actor); + + if (this->actor.speedXZ >= 20.0f) { + // Jump over platform + if (this->unk_242 == 1) { + if (sqrtf(SQXZ(this->actor.world.pos)) < 700.0f) { + Boss03_SetupJumpOverPlatform(this, globalCtx); + return; + } + } + + // Attack platform + if (this->actor.bgCheckFlags & 8) { + play_sound(NA_SE_IT_BIG_BOMB_EXPLOSION); + func_800BC848(&this->actor, globalCtx, 20, 15); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, 0.0f, this->waterHeight, 0.0f, 0, 0, + 0x96, ENWATEREFFECT_780); + + // Player is above water && Player is standing on ground + if ((this->waterHeight < player->actor.world.pos.y) && (player->actor.bgCheckFlags & 1)) { + func_800B8D50(globalCtx, NULL, 7.0f, Math_FAtan2F(player->actor.world.pos.z, player->actor.world.pos.x), + 7.0f, 0); + } + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 50; + } + } +} + +void Boss03_SetupJumpOverPlatform(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_JumpOverPlatform; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 30.0f; + this->actor.speedXZ = 25.0f; + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_JUMP_OLD); +} + +void Boss03_JumpOverPlatform(Boss03* this, GlobalContext* globalCtx) { + this->bubbleEffectSpawnCount = 0; + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_JUMP_LEV_OLD - SFX_FLAG); + + this->skelAnime.playSpeed = 2.0f; + SkelAnime_Update(&this->skelAnime); + + Math_ApproachS(&this->actor.world.rot.x, this->actor.velocity.y * -300.0f, 2, 0x2000); + this->actor.shape.rot.x = this->actor.world.rot.x; + + Actor_MoveWithGravity(&this->actor); + if ((this->actor.velocity.y < 0.0f) && (this->actor.world.pos.y < this->waterHeight + 50.0f)) { + this->bubbleEffectSpawnCount = 2; + this->actor.gravity = 0.0f; + Math_ApproachZeroF(&this->actor.velocity.y, 1.0f, 1.0f); + if (this->actor.velocity.y == 0.0f) { + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 50; + } + } else { + s16 i; + Vec3f sp30; + + for (i = 0; i < 3; i++) { + sp30.x = this->actor.world.pos.x + randPlusMinusPoint5Scaled(150.0f); + sp30.y = this->actor.world.pos.y; + sp30.z = this->actor.world.pos.z + randPlusMinusPoint5Scaled(150.0f); + Boss03_SpawnEffectDroplet(globalCtx, &sp30); + } + } +} + +/* End of Gyorg's Init and actionFuncs section */ + +/* Start of Gyorg's Cutscenes section */ + +void Boss03_SetupIntroCutscene(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_IntroCutscene; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFastSwimmingAnim, -10.0f); + this->skelAnime.playSpeed = 2.0f; +} + +Vec3f D_809E9104[] = { + { 770.0f, 200.0f, 720.0f }, + { 831.0f, 200.0f, -570.0f }, + { 0.0f, 450.0f, 0.0f }, +}; + +void Boss03_IntroCutscene(Boss03* this, GlobalContext* globalCtx) { + s16 i; + Vec3f effectPos; + f32 xDiff; + f32 yDiff; + f32 zDiff; + s32 pad; + f32 sp5C; + s16 sp5A; + s16 pad2; + s16 bubblesToSpawnNum = 0; + f32 phi_f2; + Player* player = GET_PLAYER(globalCtx); + + this->bubbleEffectSpawnCount = 0; + this->csTimer++; + this->unk_290 = 0; + + sp5A = 0x4BC; + + switch (this->csState) { + case 0: + if (player->actor.world.pos.y < 1350.0f) { + Cutscene_Start(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 7); + this->csCamId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->csCamId, 7); + + this->actor.world.rot.y = -0x7B30; + this->prevPlayerPos.y = 1850.0f; + + this->actor.world.pos.x = 1400.0f; + this->actor.world.pos.y = 130.0f; + this->actor.world.pos.z = 1400.0f; + + player->actor.shape.rot.y = 0; + player->actor.world.pos.y = 1850.0f; + player->actor.world.rot.y = player->actor.shape.rot.y; + + this->csCamAt.y = player->actor.world.pos.y + 30.0f; + this->csState = 1; + this->csTimer = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_2D5 = true; + + this->cameraFov = KREG(14) + 60.0f; + + case 1: + player->actor.world.pos.z = 0.0f; + player->actor.world.pos.x = 0.0f; + player->actor.speedXZ = 0.0f; + + this->csCamEye.x = 100.0f; + this->csCamEye.y = 540.0f; + + this->csCamEye.z = player->actor.world.pos.z + 100.0f; + this->csCamAt.x = player->actor.world.pos.x; + + Math_ApproachF(&this->csCamAt.y, player->actor.world.pos.y + 30.0f, 0.5f, 100.0f); + this->csCamAt.z = player->actor.world.pos.z; + + if (this->csTimer > 105) { + this->csState = 2; + this->csTimer = 0; + this->unk_240 = 0; + func_8016566C(0x96); + this->cameraFov = 80.0f; + + case 2: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_DEMO_MOVE_OLD - SFX_FLAG); + + xDiff = D_809E9104[this->unk_242].x - this->actor.world.pos.x; + yDiff = D_809E9104[this->unk_242].y - this->actor.world.pos.y; + zDiff = D_809E9104[this->unk_242].z - this->actor.world.pos.z; + + Math_ApproachS(&this->actor.world.rot.x, Math_FAtan2F(sqrtf(SQ(xDiff) + SQ(zDiff)), -yDiff), + 0xA, this->unk_274); + Math_ApproachS(&this->actor.world.rot.y, Math_FAtan2F(zDiff, xDiff), 0xA, this->unk_274); + Math_ApproachS(&this->unk_274, 0x200, 1, 0x10); + + if ((this->csTimer > 30) && (this->csTimer < 50)) { + bubblesToSpawnNum = 2; + } + + if ((this->csTimer == 40) || (this->csTimer == (u32)(KREG(91) + 270))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_WATER_DEEP); + } + + if (this->csTimer > 50) { + Math_ApproachF(&this->actor.speedXZ, this->unk_278, 1.0f, 0.1f); + } + + if (this->unk_242 < 2) { + if (sqrtf(SQ(xDiff) + SQ(zDiff)) < 100.0f) { + this->unk_242++; + this->unk_274 = 0; + if (this->unk_242 >= 2) { + this->csTimer = 100; + } + } + this->unk_278 = 5.0f; + } else { + this->unk_278 = 0.0f; + bubblesToSpawnNum = 1; + if ((this->actor.speedXZ == 0.0f) && (this->csTimer > 230)) { + this->csState = 3; + this->csTimer = 0; + } + if (this->csTimer == 165) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_WATER_MID); + } + if (this->csTimer == 180) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_WATER_DEEP); + } + } + } + } + break; + + case 3: + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_PREATTACK_OLD - SFX_FLAG); + sp5A = 0x1970; + Math_ApproachF(&this->actor.speedXZ, 15.0f, 1.0f, 2.0f); + if (this->csTimer > 20) { + this->csState = 4; + this->csTimer = 0; + } + break; + + case 4: + player->actor.world.rot.y = player->actor.shape.rot.y = 0; + + if (this->csTimer == 5) { + // Rotates Player towards Gyorg + func_800B7298(globalCtx, &this->actor, 8); + } + + this->csCamEye.x = player->actor.world.pos.x + 30.0f; + this->csCamEye.y = player->actor.world.pos.y + Player_GetHeight(player) - 4.0f + BREG(17); + this->csCamEye.z = player->actor.world.pos.z - 30.0f; + + this->csCamAt.x = player->actor.world.pos.x; + this->csCamAt.y = player->actor.world.pos.y + Player_GetHeight(player) - 18.0f + 6.0f + BREG(18); + this->csCamAt.z = player->actor.world.pos.z; + + if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { + this->csCamEye.y -= 60.0f; + this->csCamAt.y -= 35.0f; + } + + this->cameraFov = 60.0f; + if (this->csTimer == 16) { + this->csState = 5; + this->csTimer = 0; + this->unk_2D5 = false; + this->actor.speedXZ = -200.0f; + Actor_MoveWithoutGravityReverse(&this->actor); + this->actor.world.pos.y = this->waterHeight - 150.0f; + func_80165690(); + + case 5: + SkelAnime_Update(&this->skelAnime); + this->actor.speedXZ = 20.0f; + Actor_MoveWithoutGravityReverse(&this->actor); + player->actor.shape.rot.y = -0x1470; + player->actor.world.rot.y = player->actor.shape.rot.y; + + this->csCamEye.x = player->actor.world.pos.x + 30.0f - 90.0f + 300.0f; + this->csCamEye.y = player->actor.world.pos.y + 40.0f + 10.0f; + this->csCamEye.z = player->actor.world.pos.z - 30.0f + 160.0f + 300.0f; + + this->csCamAt.x = this->actor.world.pos.x; + this->csCamAt.y = this->actor.world.pos.y - 100.0f; + this->csCamAt.z = this->actor.world.pos.z; + + if (this->csTimer == 10) { + this->actor.velocity.y = 30.0f; + this->csState = 6; + this->csTimer = 0; + this->actor.gravity = -1.5f; + this->actor.speedXZ = 20.0f; + + Audio_QueueSeqCmd(NA_BGM_BOSS | 0x8000); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_JUMP_OLD); + this->skelAnime.playSpeed = 1.0f; + } + } + break; + + case 6: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_JUMP_LEV_OLD - SFX_FLAG); + + if (this->csTimer == 30) { + TitleCard_InitBossName(&globalCtx->state, &globalCtx->actorCtx.titleCtxt, + Lib_SegmentedToVirtual(gGyorgTitleCardTex), 160, 180, 128, 40); + } + + if ((this->csTimer < 24) || (this->csTimer >= 90)) { + SkelAnime_Update(&this->skelAnime); + Math_ApproachS(&this->actor.world.rot.x, this->actor.velocity.y * -300.0f, 3, 0x1000); + Actor_MoveWithGravity(&this->actor); + if ((this->actor.velocity.y <= 0.0f) && (this->actor.world.pos.y < (this->waterHeight + 50.0f))) { + this->bubbleEffectSpawnCount = 2; + this->actor.gravity = 0.0f; + Math_ApproachZeroF(&this->actor.velocity.y, 1.0f, 1.0f); + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.5f); + } else { + if (1) {} + if (1) {} + if (1) {} + + for (i = 0; i < 3; i++) { + effectPos.x = randPlusMinusPoint5Scaled(150.0f) + this->actor.world.pos.x; + effectPos.y = this->actor.world.pos.y; + effectPos.z = randPlusMinusPoint5Scaled(150.0f) + this->actor.world.pos.z; + + Boss03_SpawnEffectDroplet(globalCtx, &effectPos); + } + + this->csCamTargetAt.x = this->actor.world.pos.x; + this->csCamTargetAt.y = this->actor.world.pos.y - 100.0f; + this->csCamTargetAt.z = this->actor.world.pos.z; + } + } else { + Math_ApproachF(&this->csCamEye.x, player->actor.world.pos.x + 30.0f - 90.0f + 300.0f - 90.0f, 0.05f, + 3.0f); + Math_ApproachF(&this->csCamEye.y, player->actor.world.pos.y + 40.0f + 10.0f + 90.0f, 0.05f, 3.0f); + Math_ApproachF(&this->csCamEye.z, player->actor.world.pos.z - 30.0f + 160.0f + 300.0f - 90.0f, 0.05f, + 3.0f); + Math_ApproachF(&this->unk_568, 90.0f, 0.05f, 3.0f); + } + + Math_ApproachF(&this->csCamAt.x, this->csCamTargetAt.x, 0.5f, 100.0f); + Math_ApproachF(&this->csCamAt.y, this->csCamTargetAt.y + this->unk_568, 0.5f, 100.0f); + Math_ApproachF(&this->csCamAt.z, this->csCamTargetAt.z, 0.5f, 100.0f); + + if (this->csTimer == 145) { + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + + camera->eye = this->csCamEye; + camera->eyeNext = this->csCamEye; + camera->at = this->csCamAt; + + func_80169AFC(globalCtx, this->csCamId, 0); + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + this->csCamId = 0; + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 50; + + gSaveContext.eventInf[5] |= 0x40; + } + break; + } + + this->actor.shape.rot = this->actor.world.rot; + + if ((this->csState == 2) || (this->csState == 3)) { + Actor_MoveWithoutGravityReverse(&this->actor); + + phi_f2 = this->actor.speedXZ * 0.02f; + phi_f2 = CLAMP_MAX(phi_f2, 0.12f); + + sp5C = Math_SinS(this->unk_240 * sp5A) * phi_f2; + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); + Matrix_RotateYF(sp5C, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.world.rot.x, MTXMODE_APPLY); + Matrix_MultVecZ(100.0f, &this->csCamAt); + + this->csCamEye = this->actor.world.pos; + + for (i = 0; i < bubblesToSpawnNum; i++) { + effectPos.x = randPlusMinusPoint5Scaled(100.0f) + this->csCamAt.x; + effectPos.y = (randPlusMinusPoint5Scaled(100.0f) + this->csCamAt.y) - 150.0f; + effectPos.z = randPlusMinusPoint5Scaled(100.0f) + this->csCamAt.z; + + Boss03_SpawnEffectBubble(globalCtx, &effectPos); + } + } + + if (this->csCamId != 0) { + Play_CameraSetAtEye(globalCtx, this->csCamId, &this->csCamAt, &this->csCamEye); + Play_CameraSetFov(globalCtx, this->csCamId, this->cameraFov); + } +} + +void Boss03_SetupDeathCutscene(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_DeathCutscene; + Animation_MorphToLoop(&this->skelAnime, &gGyorgFloppingAnim, -10.0f); + this->floppingAnimLastFrame = Animation_GetLastFrame(&gGyorgFloppingAnim); + Audio_QueueSeqCmd(NA_BGM_STOP | 0x10000); + this->workTimer[WORK_TIMER_UNK0_C] = 0; + this->unk_242 = 0; + this->csState = 0; + this->actor.flags &= ~ACTOR_FLAG_1; +} + +void Boss03_DeathCutscene(Boss03* this, GlobalContext* globalCtx) { + s16 i; + Vec3f sp90; + Vec3f sp84; + Vec3f sp78; + f32 aux; + f32 aux2; + s32 pad; + f32 pad2; + f32 sp64; + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + Player* player; + f32 sp4C; + + aux2 = 0.0f; + player = GET_PLAYER(globalCtx); + sp64 = this->actor.scale.x * 5.0f; + + this->csTimer++; + + switch (this->csState) { + case 0: + if (ActorCutscene_GetCurrentIndex() == -1) { + Cutscene_Start(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 1); + this->csCamId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->csCamId, 7); + this->unk_2BE = Math_FAtan2F(this->actor.world.pos.z, this->actor.world.pos.x); + + // Player is above water && Player is standing on ground + if ((this->waterHeight < player->actor.world.pos.y) && (player->actor.bgCheckFlags & 1)) { + player->actor.world.pos.x = 0.0f; + player->actor.world.pos.z = -200.0f; + } + + case 1: + this->csTimer = 0; + this->csState = 2; + this->csCamEye.x = camera->eye.x; + this->csCamEye.y = camera->eye.y; + this->csCamEye.z = camera->eye.z; + this->csCamAt.x = camera->at.x; + this->csCamAt.y = camera->at.y; + this->csCamAt.z = camera->at.z; + + aux = this->csCamEye.x - this->actor.world.pos.x; + this->unk_568 = Math_Acot2F(this->csCamEye.z - this->actor.world.pos.z, aux); + + this->unk_570 = 0.0f; + this->unk_56C = 0.0f; + + case 2: + sp90.x = 0.0f; + sp90.y = (50.0f * sp64) + 150.0f; + sp90.z = (400.0f * sp64) + 300.0f; + + this->csCamTargetAt.x = this->actor.world.pos.x; + this->csCamTargetAt.y = this->actor.world.pos.y; + this->csCamTargetAt.z = this->actor.world.pos.z; + + this->unk_568 += this->unk_56C; + Matrix_RotateYF(this->unk_568, MTXMODE_NEW); + Matrix_MultVec3f(&sp90, &this->csCamTargetEye); + + this->csCamTargetEye.x += this->actor.world.pos.x; + this->csCamTargetEye.y += this->waterHeight; + this->csCamTargetEye.z += this->actor.world.pos.z; + + sp4C = 40.0f + aux2; + Math_ApproachF(&this->csCamEye.x, this->csCamTargetEye.x, 0.1f, sp4C); + Math_ApproachF(&this->csCamEye.y, this->csCamTargetEye.y, 0.1f, sp4C); + Math_ApproachF(&this->csCamEye.z, this->csCamTargetEye.z, 0.1f, sp4C); + sp4C = 70.0f + aux2; + Math_ApproachF(&this->csCamAt.x, this->csCamTargetAt.x, 0.1f, sp4C); + Math_ApproachF(&this->csCamAt.y, this->csCamTargetAt.y, 0.1f, sp4C); + Math_ApproachF(&this->csCamAt.z, this->csCamTargetAt.z, 0.1f, sp4C); + } + break; + } + + SkelAnime_Update(&this->skelAnime); + + switch (this->unk_242) { + case 0: + Math_ApproachF(&this->actor.world.pos.y, Math_SinS(this->unk_240 * 0x1000) * 80.0f + this->waterHeight, + 1.0f, 10.0f); + this->actor.shape.rot.z += 0x100; + Matrix_RotateYS(this->unk_2BE, MTXMODE_NEW); + Matrix_MultVecZ(500.0f, &sp84); + Math_ApproachF(&this->actor.world.pos.x, sp84.x, 0.1f, 5.0f); + Math_ApproachF(&this->actor.world.pos.z, sp84.z, 0.1f, 5.0f); + + if (Animation_OnFrame(&this->skelAnime, this->floppingAnimLastFrame)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_DEAD_JUMP2_OLD); + } + if (Animation_OnFrame(&this->skelAnime, this->floppingAnimLastFrame * 0.5f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_DEAD_JUMP_OLD); + } + + if ((this->workTimer[WORK_TIMER_UNK0_C] == 0) && ((this->waterHeight - 100.0f) < this->actor.world.pos.y)) { + this->workTimer[WORK_TIMER_UNK0_C] = Rand_ZeroFloat(15.0f) + 15.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x, + this->waterHeight, this->actor.world.pos.z, 0, 0, 0x78, ENWATEREFFECT_777); + + if (this->actionFunc == Boss03_DeathCutscene) { + if ((D_809E9840 % 2) != 0) { + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_JUMP_OLD); + } else { + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_SINK_OLD); + } + D_809E9840++; + } + + this->unk_284 = this->actor.world.pos.x; + this->unk_288 = this->waterHeight; + this->unk_28C = this->actor.world.pos.z; + + this->unk_280 = 27; + if ((fabsf(this->actor.world.pos.x - sp84.x) < 5.0f) && + (fabsf(this->actor.world.pos.z - sp84.z) < 5.0f)) { + this->unk_242 = 1; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 25.0f; + this->actor.speedXZ = 10.0f; + this->actor.world.rot.y = this->unk_2BE + 0x8000; + this->unk_240 = 0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_DEAD_JUMP2_OLD); + } + } + Math_ApproachF(&this->unk_56C, 0.01f, 1.0f, 0.0005f); + break; + + case 1: + if (this->unk_240 == 0x96) { + Audio_QueueSeqCmd(NA_BGM_CLEAR_BOSS | 0x8000); + } + Math_ApproachF(&this->unk_56C, 0.01f, 1.0f, 0.0005f); + Math_ApproachF(&this->actor.scale.x, 0.01f, 0.05f, 0.001f); + Actor_SetScale(&this->actor, this->actor.scale.x); + + if (this->actor.velocity.y < 0.0f) { + if (this->actor.world.pos.y < PLATFORM_HEIGHT + (100.0f * sp64)) { + this->actor.world.pos.y = PLATFORM_HEIGHT + (100.0f * sp64); + this->actor.velocity.y = ((Rand_ZeroFloat(10.0f) + 7.5f) * sp64) + 7.5f; + this->actor.speedXZ = ((Rand_ZeroFloat(5.0f) + 2.5f) * sp64) + 2.5f; + + if (Rand_ZeroOne() < 0.5f) { + this->shapeRotTargetX = + ((s16)randPlusMinusPoint5Scaled(500.0f) + this->shapeRotTargetX) + 0x8000; + } + + if (Rand_ZeroOne() < 0.5f) { + this->shapeRotTargetZ = + ((s16)randPlusMinusPoint5Scaled(500.0f) + this->shapeRotTargetZ) + 0x8000; + } + + if (Rand_ZeroOne() < 0.5f) { + this->shapeRotTargetY = Rand_ZeroFloat(65536.0f); + } + + this->actor.world.rot.y = Math_FAtan2F(-this->actor.world.pos.z, -this->actor.world.pos.x); + + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_BOUND_OLD); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_BOUND2_OLD); + } + } + + Math_ApproachS(&this->actor.shape.rot.y, this->shapeRotTargetY, 3, 0x500); + Math_ApproachS(&this->actor.shape.rot.x, this->shapeRotTargetX, 3, 0xA00); + Math_ApproachS(&this->actor.shape.rot.z, this->shapeRotTargetZ, 3, 0xA00); + + sp4C = 150.0f * sp64; + + for (i = 0; i < 1; i++) { + sp78.x = randPlusMinusPoint5Scaled(sp4C) + this->actor.world.pos.x; + sp78.y = this->actor.world.pos.y; + sp78.z = randPlusMinusPoint5Scaled(sp4C) + this->actor.world.pos.z; + Boss03_SpawnEffectDroplet(globalCtx, &sp78); + } + + Actor_MoveWithGravity(&this->actor); + if (this->actor.scale.x <= 0.0111f) { + this->unk_242 = 2; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_DOOR_WARP1, 0.0f, + PLATFORM_HEIGHT, 200.0f, 0, 0, 0, ENDOORWARP1_FF_1); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ITEM_B_HEART, this->actor.focus.pos.x, + PLATFORM_HEIGHT, this->actor.focus.pos.z, 0, 0, 0, 0); + this->csTimer = 0; + Actor_SetScale(&this->actor, 0.0f); + Audio_StopSfxByPos(&this->actor.projectedPos); + } + break; + + case 2: + Math_ApproachZeroF(&this->unk_56C, 1.0f, 0.0005f); + if (this->csTimer == 60) { + camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + camera->eye = this->csCamEye; + camera->eyeNext = this->csCamEye; + camera->at = this->csCamAt; + func_80169AFC(globalCtx, this->csCamId, 0); + this->csCamId = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + this->csState = 3; + func_80165690(); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_INIT_OLD); + Boss03_PlayUnderwaterSfx(&D_809E9848, NA_SE_EN_KONB_INIT_OLD); + } + break; + + case 3: + this->actor.world.pos.y = 5000.0f; + break; + } + + if (this->csCamId != 0) { + Play_CameraSetAtEye(globalCtx, this->csCamId, &this->csCamAt, &this->csCamEye); + } +} + +void Boss03_SetupSpawnSmallFishesCutscene(Boss03* this, GlobalContext* globalCtx) { + this->actionFunc = Boss03_SpawnSmallFishesCutscene; + Animation_MorphToLoop(&this->skelAnime, &gGyorgBackingUpAnim, -15.0f); + this->csState = 0; + this->csTimer = 0; +} + +void Boss03_SpawnSmallFishesCutscene(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + this->csTimer++; + switch (this->csState) { + case 0: + if (ActorCutscene_GetCurrentIndex() == -1) { + Cutscene_Start(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 1); + this->csCamId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->csCamId, 7); + this->csState = 1; + this->unk_2BE = 0xBB8; + + case 1: + if (player->actor.world.pos.y < 437.0f) { + player->actor.world.pos.z = 500.0f; + player->actor.world.pos.x = 500.0f; + } + + this->actor.shape.rot.z = 0; + this->actor.world.pos.z = 1000.0f; + this->actor.world.pos.x = 1000.0f; + this->actor.world.pos.y = 200.0f; + this->actor.shape.rot.x = this->actor.shape.rot.z; + + this->actor.shape.rot.y = this->actor.world.rot.y = + Math_FAtan2F(-this->actor.world.pos.x, -this->actor.world.pos.x); + this->unk_260 = 0.0f; + + player->actor.shape.rot.y = player->actor.world.rot.y = this->actor.world.rot.y + 0x8000; + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y + this->unk_2BE, MTXMODE_APPLY); + Matrix_MultVecZ(340.0f, &this->csCamEye); + + this->csCamAt.x = this->actor.world.pos.x; + this->csCamAt.y = this->actor.world.pos.y; + this->csCamAt.z = this->actor.world.pos.z; + + Math_ApproachS(&this->unk_2BE, -4000, 10, 70); + + if (this->csTimer >= 61) { + Math_ApproachS(&this->jawZRot, 0x3200, 5, 0x500); + if ((this->csTimer >= 90) && (this->csTimer < 130)) { + if ((this->csTimer % 2) != 0) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON3, + this->actor.world.pos.x - 110.0f, this->actor.world.pos.y - 20.0f, + this->actor.world.pos.z - 110.0f, 0, this->actor.shape.rot.y, 0, 0); + this->numSpawnedSmallFish++; + } + if ((this->csTimer % 8) == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_MINI_APPEAR); + } + } + } + + if (this->csTimer >= 150) { + Camera* camera; + + camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + camera->eye = this->csCamEye; + camera->eyeNext = this->csCamEye; + camera->at = this->csCamAt; + + func_80169AFC(globalCtx, this->csCamId, 0); + this->csCamId = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 50; + } + } + break; + } + + if (this->csCamId != 0) { + Play_CameraSetAtEye(globalCtx, this->csCamId, &this->csCamAt, &this->csCamEye); + } +} + +/* End of Gyorg's Cutscenes section */ + +/* Start of Gyorg's More actionFuncs and Update section */ + +void Boss03_SetupStunned(Boss03* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actionFunc != Boss03_Stunned) { + Animation_MorphToLoop(&this->skelAnime, &gGyorgStunnedAnim, -15.0f); + this->workTimer[WORK_TIMER_STUNNED] = 200; + this->actionFunc = Boss03_Stunned; + } + + if (&this->actor == player->actor.parent) { + player->unk_AE8 = 101; + player->actor.parent = NULL; + player->csMode = 0; + func_80165690(); + } + + this->unk_240 = 0; +} + +void Boss03_Stunned(Boss03* this, GlobalContext* globalCtx) { + this->actor.hintId = 0x29; + + if (this->unk_240 >= 16) { + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); + } + + SkelAnime_Update(&this->skelAnime); + + if ((this->waterHeight + 30.0f) < this->actor.world.pos.y) { + this->actor.gravity = -2.0f; + Actor_MoveWithGravity(&this->actor); + if (this->actor.bgCheckFlags & 2) { + play_sound(NA_SE_IT_WALL_HIT_HARD); + func_800BC848(&this->actor, globalCtx, 10, 10); + } + } else { + Math_ApproachS(&this->actor.shape.rot.z, -0x6000, 0xA, 0x900); + Math_ApproachS(&this->actor.world.rot.x, 0x800, 0xA, 0x1000); + this->actor.shape.rot.x = this->actor.world.rot.x; + + Math_ApproachF(&this->actor.world.pos.y, 100.0f, 0.05f, 5.0f); + Math_ApproachF(&this->actor.speedXZ, 0.0f, 1.0f, 1.5f); + Actor_MoveWithoutGravityReverse(&this->actor); + } + + if (this->workTimer[WORK_TIMER_STUNNED] == 0) { + func_809E344C(this, globalCtx); + // WORK_TIMER_UNK1_A wasn't set + } +} + +void Boss03_SetupDamaged(Boss03* this, GlobalContext* globalCtx) { + Animation_MorphToLoop(&this->skelAnime, &gGyorgFloppingAnim, -10.0f); + this->actionFunc = Boss03_Damaged; + this->workTimer[WORK_TIMER_CURRENT_ACTION] = 30; +} + +/** + * Invulnerability period by being damaged by Player + */ +void Boss03_Damaged(Boss03* this, GlobalContext* globalCtx) { + this->unk_25C = 15; + + SkelAnime_Update(&this->skelAnime); + + Math_ApproachS(&this->jawZRot, ((Math_SinS(this->unk_240 * 0x2000) * 3000.0f) + 0x3000), 2, 0x3000); + Math_ApproachF(&this->actor.world.pos.y, 200.0f, 0.05f, 10.0f); + + if (this->workTimer[WORK_TIMER_CURRENT_ACTION] == 0) { + if ((s8)this->actor.colChkInfo.health <= 5) { + if (!this->hasSpwanedSmallFishes) { + this->hasSpwanedSmallFishes++; + Boss03_SetupSpawnSmallFishesCutscene(this, globalCtx); + return; + } + } + + func_809E344C(this, globalCtx); + this->workTimer[WORK_TIMER_UNK1_A] = 100; + } +} + +/* End of ActionFuncs section */ + +void Boss03_UpdateCollision(Boss03* this, GlobalContext* globalCtx) { + ColliderInfo* hitbox; + u8 sp4B = true; + Player* player = GET_PLAYER(globalCtx); + s32 i; + s32 phi_v1; + u32 phi_v0; + Boss03ActionFunc stunnedActionFunc = Boss03_Stunned; + + if (((KREG(20) + (this->waterHeight - 50.0f)) < player->actor.world.pos.y) && + (player->transformation != PLAYER_FORM_FIERCE_DEITY)) { + sp4B = false; + } + + if (this->waterHeight < player->actor.world.pos.y) { + for (i = 0; i < ARRAY_COUNT(sHeadJntSphElementsInit); i++) { + if (this->headCollider.elements[i].info.toucherFlags & TOUCH_HIT) { + this->headCollider.elements[i].info.toucherFlags &= ~TOUCH_HIT; + player->unk_B84 = this->actor.shape.rot.y; + player->unk_B80 = 20.0f; + } + } + + for (i = 0; i < ARRAY_COUNT(sBodyJntSphElementsInit); i++) { + if (this->bodyCollider.elements[i].info.toucherFlags & TOUCH_HIT) { + this->bodyCollider.elements[i].info.toucherFlags &= ~TOUCH_HIT; + player->unk_B84 = this->actor.shape.rot.y; + player->unk_B80 = 20.0f; + } + } + } + + if (this->unk_25C == 0) { + if ((this->actionFunc == stunnedActionFunc) && sp4B) { + for (i = 0; i < ARRAY_COUNT(sBodyJntSphElementsInit); i++) { + if (this->bodyCollider.elements[i].info.bumperFlags & BUMP_HIT) { + hitbox = this->bodyCollider.elements[i].info.acHitInfo; + this->bodyCollider.elements[i].info.bumperFlags &= ~BUMP_HIT; + this->unk_25C = 15; + this->unk_25E = 15; + + // (DMG_SWORD_BEAM | DMG_SPIN_ATTACK | DMG_ZORA_PUNCH | DMG_ZORA_BARRIER | DMG_DEKU_LAUNCH | + // DMG_DEKU_SPIN | DMG_GORON_SPIKES | DMG_SWORD | DMG_GORON_PUNCH | DMG_DEKU_STICK) + phi_v0 = (hitbox->toucher.dmgFlags & 0x038AC302) + ? this->bodyCollider.elements[i].info.acHitInfo->toucher.damage + : 0; + + phi_v1 = phi_v0; + if (phi_v0 < 1) { + phi_v1 = 1; + } + this->actor.colChkInfo.health -= phi_v1; + + if ((s8)this->actor.colChkInfo.health <= 0) { + Boss03_PlayUnderwaterSfx(&D_809E9848, NA_SE_EN_KONB_DEAD_OLD); + Boss03_PlayUnderwaterSfx(&D_809E9848, NA_SE_EN_KONB_DEAD2_OLD); + Boss03_SetupDeathCutscene(this, globalCtx); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } else { + Boss03_SetupDamaged(this, globalCtx); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_DAMAGE_OLD); + } + return; + } + } + } + + for (i = 0; i < ARRAY_COUNT(sHeadJntSphElementsInit); i++) { + if (this->headCollider.elements[i].info.bumperFlags & BUMP_HIT) { + hitbox = this->headCollider.elements[i].info.acHitInfo; + this->headCollider.elements[i].info.bumperFlags &= ~BUMP_HIT; + this->unk_25C = 15; + + if (this->actionFunc != stunnedActionFunc) { + Boss03_SetupStunned(this, globalCtx); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_DAMAGE_OLD); + + if (&this->actor == player->actor.parent) { + player->unk_AE8 = 101; + player->actor.parent = NULL; + player->csMode = 0; + func_80165690(); + } + + continue; + } + + if (sp4B) { + this->unk_25E = 15; + + // (DMG_SWORD_BEAM | DMG_SPIN_ATTACK | DMG_ZORA_PUNCH | DMG_ZORA_BARRIER | DMG_DEKU_LAUNCH | + // DMG_DEKU_SPIN | DMG_GORON_SPIKES | DMG_SWORD | DMG_GORON_PUNCH | DMG_DEKU_STICK) + phi_v0 = (hitbox->toucher.dmgFlags & 0x038AC302) + ? (this->headCollider.elements[i].info.acHitInfo->toucher.damage) + : 0; + + phi_v1 = phi_v0; + if (phi_v0 < 1) { + phi_v1 = 1; + } + this->actor.colChkInfo.health -= phi_v1; + if ((s8)this->actor.colChkInfo.health <= 0) { + Boss03_PlayUnderwaterSfx(&D_809E9848, NA_SE_EN_KONB_DEAD_OLD); + Boss03_PlayUnderwaterSfx(&D_809E9848, NA_SE_EN_KONB_DEAD2_OLD); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Boss03_SetupDeathCutscene(this, globalCtx); + } else { + Boss03_SetupDamaged(this, globalCtx); + Boss03_PlayUnderwaterSfx(&this->actor.projectedPos, NA_SE_EN_KONB_DAMAGE_OLD); + } + } + return; + } + } + } +} + +void Boss03_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + Boss03* this = THIS; + Actor* dblueActor; + Player* player = GET_PLAYER(globalCtx); + s32 i; + Vec3f wetSpotPos; + Vec3f bubblePos; + Vec3f dropletPos; + s16 j; + f32 yRot; + + this->actor.hintId = 0x28; + + if (!D_809E9842 && (player->actor.world.pos.y < (PLATFORM_HEIGHT + 5.0f))) { + D_809E9842 = true; + D_809E9841 = 5; + } + + if (KREG(63) == 0) { + this->unk_290 = 1; + this->unk_240++; + this->unk_2BC = 1; + + this->unk_2BD = false; + + Math_Vec3f_Copy(&D_809E9848, &this->actor.projectedPos); + + for (i = 0; i < ARRAY_COUNT(this->workTimer); i++) { + if (this->workTimer[i] != 0) { + this->workTimer[i]--; + } + } + + if (this->unk_324 != 0) { + this->unk_324--; + } + + if (this->unk_25C != 0) { + this->unk_25C--; + } + + if (this->unk_25E != 0) { + this->unk_25E--; + } + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != Boss03_DeathCutscene) { + Math_ApproachS(&this->actor.shape.rot.z, 0, 0xA, 0x800); + this->actor.world.pos.y -= 100.0f; + this->actor.prevPos.y -= 100.0f; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 150.0f, 100.0f, 5); + this->actor.world.pos.y += 100.0f; + this->actor.prevPos.y += 100.0f; + } + } + + if ((this->actionFunc != Boss03_DeathCutscene) && (!this->unk_2D5)) { + // Going into or out of the water + if (((this->actor.world.pos.y < this->waterHeight + 50.0f) && + (this->waterHeight + 50.0f <= this->actor.prevPos.y)) || + ((this->waterHeight - 50.0f < this->actor.world.pos.y) && + (this->actor.prevPos.y <= this->waterHeight - 50.0f))) { + if ((this->actor.velocity.y < 0.0f) && (this->actionFunc != Boss03_DeathCutscene)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_SINK_OLD); + } + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x, + this->waterHeight, this->actor.world.pos.z, 0, 0, 0x78, ENWATEREFFECT_777); + + this->unk_280 = 27; + this->unk_284 = this->actor.world.pos.x; + this->unk_288 = this->waterHeight; + this->unk_28C = this->actor.world.pos.z; + } + } + + if (this->actionFunc != Boss03_DeathCutscene) { + if ((this->actionFunc == Boss03_Stunned) || (this->actionFunc == Boss03_Damaged)) { + this->bodyCollider.base.colType = COLTYPE_HIT3; + } else { + this->bodyCollider.base.colType = COLTYPE_METAL; + } + + Boss03_UpdateCollision(this, globalCtx); + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); + + if (player->transformation == PLAYER_FORM_HUMAN) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->headCollider.base); + } + + if (!this->unk_2BD) { + if (player->transformation != PLAYER_FORM_HUMAN) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->headCollider.base); + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->headCollider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); + } + + if ((this->actionFunc != Boss03_Stunned) && (!this->unk_2BD)) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->headCollider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); + } + } + + dblueActor = Boss03_FindActorDblueMovebg(globalCtx); + if (dblueActor != NULL) { + dblueActor->world.pos.y = this->waterHeight; + } + + Math_ApproachZeroF(&this->unk_260, 0.1f, 0.05f); + + if (this->unk_290 != 0) { + this->unk_294 += 0.1f; + this->unk_298 += 0.12f; + this->leftFinYRot = sinf(this->unk_294) * 1280.0f; + this->rightFinYRot = sinf(this->unk_298) * 1280.0f; + } else { + Math_ApproachS(&this->rightFinYRot, 0, 0xA, 0x100); + Math_ApproachS(&this->leftFinYRot, 0, 0xA, 0x100); + } + + Math_ApproachS(&this->bodyYRot, 0, 0xA, 0x100); + Math_ApproachS(&this->jawZRot, 0, 0xA, 0x200); + + if ((this->unk_240 % 2) == 0) { + for (i = 0; i < this->bubbleEffectSpawnCount; i++) { + bubblePos.x = randPlusMinusPoint5Scaled(100.0f) + this->actor.world.pos.x; + bubblePos.y = randPlusMinusPoint5Scaled(100.0f) + this->actor.world.pos.y; + bubblePos.z = randPlusMinusPoint5Scaled(100.0f) + this->actor.world.pos.z; + + Boss03_SpawnEffectBubble(globalCtx, &bubblePos); + } + } + + this->bubbleEffectSpawnCount = 1; + Boss03_UpdateEffects(globalCtx); + + if (D_809E9841 != 0) { + D_809E9841--; + if (D_809E9841 == 0) { + Audio_QueueSeqCmd(NA_BGM_BOSS | 0x8000); + } + } + + if (this->actionFunc != Boss03_CatchPlayer) { + Math_ApproachS(&player->actor.world.rot.x, 0, 1, 0x80); + Math_ApproachS(&player->actor.shape.rot.x, 0, 1, 0x80); + } + + if ((this->waterHeight < player->actor.world.pos.y) && (this->prevPlayerPos.y <= this->waterHeight)) { + this->wetSpotEffectSpawnCount = 20; + } + + // Player is standing on ground && Player is above water + if ((player->actor.bgCheckFlags & 1) && (player->actor.shape.feetPos[FOOT_LEFT].y >= WATER_HEIGHT + 8.0f)) { + if (this->wetSpotEffectSpawnCount != 0) { + this->wetSpotEffectSpawnCount--; + + wetSpotPos.x = randPlusMinusPoint5Scaled(50.0f) + player->actor.world.pos.x; + wetSpotPos.y = PLATFORM_HEIGHT; + wetSpotPos.z = randPlusMinusPoint5Scaled(50.0f) + player->actor.world.pos.z; + Boss03_SpawnEffectWetSpot(globalCtx, &wetSpotPos); + } + } + + this->prevPlayerPos = player->actor.world.pos; + + if (this->waterHeight < this->actor.world.pos.y) { + func_8019F540(0); + } else { + func_8019F540(1); + } + + if (this->unk_280 != 0) { + this->unk_280--; + } + + if ((this->unk_280 == 1) || (this->unk_280 == 5) || (this->unk_280 == 9)) { + yRot = 0.0f; + + for (j = 0, i = 0; i < 20; j++) { + Matrix_RotateYF(yRot, MTXMODE_NEW); + Matrix_MultVecZ(Rand_ZeroFloat(60.000004f) + 312.0f, &dropletPos); + dropletPos.x += this->unk_284 + randPlusMinusPoint5Scaled(40.0f); + dropletPos.y = PLATFORM_HEIGHT; + dropletPos.z += this->unk_28C + randPlusMinusPoint5Scaled(40.0f); + + if (sqrtf(SQ(dropletPos.x) + SQ(dropletPos.z)) < 355.0f) { + Boss03_SpawnEffectDroplet(globalCtx, &dropletPos); + i++; + } + + yRot += ((2.0f * M_PI) / 50.0f); + if (j >= 50) { + break; + } + } + } +} + +/* End of Gyorg's More actionFuncs and Update section */ + +/* Start of Gyorg's Draw section */ + +void Boss03_SetObject(GlobalContext* globalCtx, s16 objectId) { + s32 objectIndex = Object_GetIndex(&globalCtx->objectCtx, objectId); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[objectIndex].segment); + + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[objectIndex].segment); + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[objectIndex].segment); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 Boss03_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + Boss03* this = THIS; + + if ((limbIndex == GYORG_LIMB_UPPER_TRUNK) || (limbIndex == GYORG_LIMB_LOWER_TRUNK) || + (limbIndex == GYORG_LIMB_TAIL)) { + rot->y += this->bodyYRot; + } + if (limbIndex == GYORG_LIMB_UPPER_RIGHT_FIN) { + rot->y += this->rightFinYRot; + } + if (limbIndex == GYORG_LIMB_LOWER_RIGHT_FIN) { + rot->y += (s16)(2 * this->rightFinYRot); + } + if (limbIndex == GYORG_LIMB_UPPER_LEFT_FIN) { + rot->y -= this->leftFinYRot; + } + if (limbIndex == GYORG_LIMB_LOWER_LEFT_FIN) { + rot->y -= (s16)(2 * this->leftFinYRot); + } + if (limbIndex == GYORG_LIMB_JAW) { + rot->z += this->jawZRot; + } + + return false; +} + +/** + * Used to manually index the spheres elements of the two colliders + * Since there are two sets of ColliderJntSph, indices < 2 (ARRAY_COUNT(sHeadJntSphElementsInit)) refers to the first + * collider and indices >= 2 refers to the second one + */ +s8 sGyorgSphElementIndices[] = { + -1, // GYORG_LIMB_NONE, + -1, // GYORG_LIMB_ROOT, + 0, // GYORG_LIMB_HEAD, + -1, // GYORG_LIMB_BODY_ROOT, + 4, // GYORG_LIMB_UPPER_TRUNK, + 5, // GYORG_LIMB_LOWER_TRUNK, + 6, // GYORG_LIMB_TAIL, + -1, // GYORG_LIMB_RIGHT_FIN_ROOT, + 2, // GYORG_LIMB_UPPER_RIGHT_FIN, + -1, // GYORG_LIMB_LOWER_RIGHT_FIN, + -1, // GYORG_LIMB_LEFT_FIN_ROOT, + 3, // GYORG_LIMB_UPPER_LEFT_FIN, + -1, // GYORG_LIMB_LOWER_LEFT_FIN, + -1, // GYORG_LIMB_JAW_ROOT, + 1, // GYORG_LIMB_JAW, + -1, // GYORG_LIMB_MAX + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +Vec3f D_809E9148 = { 600.0f, -100.0f, 0.0f }; +Vec3f D_809E9154[] = { + { 450.0f, 0.0f, 0.0f }, { 140.0f, -60.0f, 0.0f }, { 350.0f, 0.0f, 0.0f }, { 350.0f, 0.0f, 0.0f }, + { 100.0f, 0.0f, 0.0f }, { 150.0f, 0.0f, 0.0f }, { 500.0f, 0.0f, 0.0f }, +}; +Vec3f D_809E91A8 = { 100000.0f, 100000.0f, 100000.0f }; +Vec3f D_809E91B4 = { 300.0f, -100.0f, -200.0f }; + +void Boss03_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Boss03* this = THIS; + s32 pad; + s8 sphereElementIndex; + Vec3f spherePos; + Player* player = GET_PLAYER(globalCtx); + + if (limbIndex == GYORG_LIMB_HEAD) { + Matrix_MultVec3f(&D_809E9148, &this->actor.focus.pos); + } + + sphereElementIndex = sGyorgSphElementIndices[limbIndex]; + if (sphereElementIndex >= 0) { + Matrix_MultVec3f(&D_809E9154[sphereElementIndex], &spherePos); + + if (sphereElementIndex < 2) { + if ((this->actionFunc == Boss03_Stunned) && (this->waterHeight < player->actor.world.pos.y)) { + Boss03_UpdateSphereElement(sphereElementIndex, &this->headCollider, &D_809E91A8); + } else { + Boss03_UpdateSphereElement(sphereElementIndex, &this->headCollider, &spherePos); + } + } else { + Boss03_UpdateSphereElement(sphereElementIndex - 2, &this->bodyCollider, &spherePos); + } + } + + if (limbIndex == GYORG_LIMB_JAW) { + MtxF mf; + + D_809E91B4.x = this->unk_2C4 + 300.0f; + Matrix_MultVec3f(&D_809E91B4, &this->insideJawPos); + Matrix_Get(&mf); + Matrix_MtxFToYXZRot(&mf, &this->unk_2A2, false); + } +} + +void Boss03_Draw(Actor* thisx, GlobalContext* globalCtx) { + Boss03* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (!this->unk_2D5) { + if ((this->unk_25E % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + Matrix_RotateYF(this->unk_260, MTXMODE_APPLY); + Matrix_Translate(0.0f, -600.0f, 0.0f, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, Boss03_OverrideLimbDraw, Boss03_PostLimbDraw, &this->actor); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } + + this->unk_2BC = 0; + + Boss03_DrawEffects(globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +/* End of Gyorg's Draw section */ + +/* Start of Effect Update/Draw section */ + +void Boss03_UpdateEffects(GlobalContext* globalCtx) { + GyorgEffect* eff = globalCtx->specialEffects; + s16 i; + Vec3f sp94; + Vec3f velocity; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + f32 phi_f0; + + if (eff->type == GYORG_EFFECT_NONE) { + continue; + } + + eff->unk_02++; + + eff->pos.x += eff->velocity.x; + eff->pos.y += eff->velocity.y; + eff->pos.z += eff->velocity.z; + + eff->velocity.y += eff->accel.y; + + if ((eff->unk_02 & 6) != 0) { + phi_f0 = 80.0f; + } else { + phi_f0 = 200.0f; + } + + Math_ApproachF(&eff->unk_40, phi_f0, 1.0f, 80.0f); + + if (eff->type == GYORG_EFFECT_DROPLET) { + eff->unk_34.z += 0.15f; + + Math_ApproachF(&eff->unk_34.x, 0.03f, 0.5f, 0.005f); + Math_ApproachF(&eff->unk_34.y, 0.5f, 0.5f, 0.02f); + + if (eff->pos.y <= WATER_HEIGHT) { + eff->type = GYORG_EFFECT_NONE; + eff->pos.y = WATER_HEIGHT; + EffectSsGRipple_Spawn(globalCtx, &eff->pos, 0, 80, 0); + } else if (eff->pos.y <= PLATFORM_HEIGHT) { + s16 j; + + eff->type = GYORG_EFFECT_WET_SPOT; + eff->pos.y = PLATFORM_HEIGHT; + eff->unk_34.x = 0.1f; + eff->unk_34.y = 0.6f; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->alpha = 150; + eff->alphaDelta = Rand_ZeroFloat(4.0f) + 5.0f; + + for (j = 0; j < 4; j++) { + Matrix_RotateYF((2.0f * (j * M_PI)) / 6.0f, MTXMODE_NEW); + sp94.x = 0.0f; + sp94.y = Rand_ZeroFloat(4.0f) + 2.0f; + sp94.z = Rand_ZeroFloat(1.5f) + 1.5f; + Matrix_MultVec3f(&sp94, &velocity); + Boss03_SpawnEffectSplash(globalCtx, &eff->pos, &velocity); + } + } + } else if (eff->type == GYORG_EFFECT_SPLASH) { + eff->unk_34.z += 0.15f; + + if (eff->velocity.y < -8.0f) { + eff->velocity.y = -8.0f; + } + + if ((eff->velocity.y < 0.0f) && (eff->pos.y <= PLATFORM_HEIGHT)) { + eff->type = GYORG_EFFECT_WET_SPOT; + eff->pos.y = PLATFORM_HEIGHT; + eff->unk_34.x = 0.05f; + eff->unk_34.y = 0.2f; + eff->velocity = gZeroVec3f; + eff->accel = gZeroVec3f; + eff->alpha = 150; + eff->alphaDelta = Rand_ZeroFloat(4.0f) + 5.0f; + } + } else if (eff->type == GYORG_EFFECT_WET_SPOT) { + Math_ApproachF(&eff->unk_34.x, eff->unk_34.y, 0.1f, 0.6f); + + eff->alpha -= eff->alphaDelta; + if (eff->alpha <= 0) { + eff->alpha = 0; + eff->type = GYORG_EFFECT_NONE; + } + } else if (eff->type == GYORG_EFFECT_BUBBLE) { + if (eff->velocity.y > 5.0f) { + eff->velocity.y = 5.0f; + } + if (sGyorgBossInstance->waterHeight < eff->pos.y) { + eff->type = GYORG_EFFECT_NONE; + } + } + } +} + +void Boss03_DrawEffects(GlobalContext* globalCtx) { + u8 flag = false; + s16 i; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 pad; + GyorgEffect* eff = globalCtx->specialEffects; + GyorgEffect* effFirst = eff; + + OPEN_DISPS(gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + func_8012C28C(gfxCtx); + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if (eff->type == GYORG_EFFECT_BUBBLE) { + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleMaterialDL); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0); + + flag = true; + } + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + Matrix_Scale(eff->unk_34.x, eff->unk_34.x, 1.0f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gGyorgBubbleModelDL); + } + } + + eff = effFirst; + + Boss03_SetObject(globalCtx, OBJECT_WATER_EFFECT); + + flag = false; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if ((eff->type == GYORG_EFFECT_DROPLET) || (eff->type == GYORG_EFFECT_SPLASH)) { + + if (!flag) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gDust1Tex)); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)eff->unk_40, (u8)((((void)0, eff->unk_40) + 55.0f)), 225, 150); + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + + if (eff->type == GYORG_EFFECT_DROPLET) { + Matrix_RotateYF(Camera_GetInputDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) * (M_PI / 0x8000), + MTXMODE_APPLY); + } else { // GYORG_EFFECT_SPLASH + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + } + + Matrix_Scale(eff->unk_34.x, eff->unk_34.y, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(eff->unk_34.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); + } + } + + eff = effFirst; + + flag = false; + + for (i = 0; i < GYORG_EFFECT_COUNT; i++, eff++) { + if (eff->type == GYORG_EFFECT_WET_SPOT) { + if (!flag) { + func_8012C448(gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gDust1Tex)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (s16)eff->unk_40, ((void)0, ((s16)eff->unk_40) + 55), 225, + eff->alpha); + + Matrix_Translate(eff->pos.x, eff->pos.y, eff->pos.z, MTXMODE_NEW); + + Matrix_Scale(eff->unk_34.x, 1.0f, eff->unk_34.x, MTXMODE_APPLY); + Matrix_RotateYF(eff->unk_34.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); + } + } + + Boss03_SetObject(globalCtx, OBJECT_BOSS03); + + CLOSE_DISPS(gfxCtx); +} + +/* End of Effect Update/Draw section */ + +/* Start of Seaweed section */ + +#define SEAWEED_FLAG_INTERACT_NONE 0 +#define SEAWEED_FLAG_INTERACT_PLAYER 1 +#define SEAWEED_FLAG_INTERACT_GYORG 2 + +void Boss03_SeaweedUpdate(Actor* thisx, GlobalContext* globalCtx) { + Boss03* this = THIS; + s16 i; + s16 pad; + s16 maxBendSpeed; + u8 flag; + Player* player = GET_PLAYER(globalCtx); + f32 distanceBetweenSeaweedAndDisturbance; + f32 disturbanceFactor; + f32 xDiff; + f32 yDiff; + f32 zDiff; + + flag = SEAWEED_FLAG_INTERACT_NONE; + this->unk_240++; + + for (i = 0; i < ARRAY_COUNT(this->seaweedSegmentPositions); i++) { + xDiff = player->actor.world.pos.x - this->seaweedSegmentPositions[i].x; + yDiff = player->actor.world.pos.y - this->seaweedSegmentPositions[i].y; + zDiff = player->actor.world.pos.z - this->seaweedSegmentPositions[i].z; + distanceBetweenSeaweedAndDisturbance = sqrtf(SQ(xDiff) + SQ(yDiff) + SQ(zDiff)); + disturbanceFactor = player->actor.speedXZ * 3.0f + 70.0f; + + // Player is standing on ground + if (player->actor.bgCheckFlags & 1) { + maxBendSpeed = 0; + } else { + maxBendSpeed = player->actor.speedXZ * 16.0f; + if (maxBendSpeed > 0x1000) { + maxBendSpeed = 0x1000; + } else if (maxBendSpeed < 0x100) { + maxBendSpeed = 0x100; + } + } + + if (distanceBetweenSeaweedAndDisturbance < disturbanceFactor) { + Math_ApproachS(&this->morphTable[i].x, (disturbanceFactor - distanceBetweenSeaweedAndDisturbance) * 200.0f, + 0xA, maxBendSpeed); + if (maxBendSpeed != 0) { + flag |= SEAWEED_FLAG_INTERACT_PLAYER; + } + } + } + + if (flag & SEAWEED_FLAG_INTERACT_PLAYER) { + Math_ApproachS(&this->actor.shape.rot.y, Math_FAtan2F(zDiff, xDiff), 0x14, 0x800); + } + + if (sGyorgBossInstance->actor.world.pos.y - 40.0f < sGyorgBossInstance->waterHeight) { + for (i = 0; i < 6; i++) { + xDiff = sGyorgBossInstance->actor.world.pos.x - this->seaweedSegmentPositions[i].x; + yDiff = sGyorgBossInstance->actor.world.pos.y - this->seaweedSegmentPositions[i].y; + zDiff = sGyorgBossInstance->actor.world.pos.z - this->seaweedSegmentPositions[i].z; + + distanceBetweenSeaweedAndDisturbance = sqrtf(SQ(xDiff) + SQ(yDiff) + SQ(zDiff)); + + if ((i == 0) && (distanceBetweenSeaweedAndDisturbance > 400.0f)) { + break; + } + + maxBendSpeed = sGyorgBossInstance->actor.speedXZ * 16.0f; + disturbanceFactor = sGyorgBossInstance->actor.speedXZ * 5.0f + 150.0f; + if (maxBendSpeed > 0x1000) { + maxBendSpeed = 0x1000; + } else if (maxBendSpeed < 0x100) { + maxBendSpeed = 0x0100; + } + + if (distanceBetweenSeaweedAndDisturbance < disturbanceFactor) { + Math_ApproachS(&this->morphTable[i].x, + (disturbanceFactor - distanceBetweenSeaweedAndDisturbance) * 200.0f, 0xA, maxBendSpeed); + if (maxBendSpeed != 0) { + flag |= SEAWEED_FLAG_INTERACT_GYORG; + } + } + } + + if (flag & SEAWEED_FLAG_INTERACT_GYORG) { + Math_ApproachS(&this->actor.shape.rot.y, Math_FAtan2F(zDiff, xDiff), 0x14, 0x800); + } + } + + if (flag == SEAWEED_FLAG_INTERACT_NONE) { + for (i = 0; i < 6; i++) { + Math_ApproachS(&this->morphTable[i].x, 0, 0x14, 0x80); + } + } +} + +Gfx* sGyorgSeaweedDLs[] = { + gGyorgSeaweedTopDL, gGyorgSeaweedPiece5DL, gGyorgSeaweedPiece4DL, + gGyorgSeaweedPiece3DL, gGyorgSeaweedPiece2DL, gGyorgSeaweedPiece1DL, +}; + +void Boss03_SeaweedDraw(Actor* thisx, GlobalContext* globalCtx) { + Boss03* this = THIS; + s16 i; + // Why 10 Mtxs? This seems to only use the first 6 elements + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Mtx) * 10); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0D, mtx); + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateZS(0x4000, MTXMODE_APPLY); + // The indices looks a bit random... + Matrix_RotateYS(this->jointTable[5].x * -5.0f * 0.1f, MTXMODE_APPLY); + Matrix_RotateXS(this->jointTable[3].y * -5.0f * 0.1f, MTXMODE_APPLY); + Matrix_RotateZS(this->jointTable[2].z * 6.0f * 0.1f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(sGyorgSeaweedDLs); i++, mtx++) { + Matrix_RotateYS(this->jointTable[i].x + this->morphTable[i].x, MTXMODE_APPLY); + Matrix_RotateXS(this->jointTable[i].y + this->morphTable[i].y, MTXMODE_APPLY); + Matrix_RotateZS(this->jointTable[i].z + this->morphTable[i].z, MTXMODE_APPLY); + + Matrix_ToMtx(mtx); + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, sGyorgSeaweedDLs[i]); + + Matrix_MultZero(&this->seaweedSegmentPositions[i]); + Matrix_Translate(4000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +/* End of Seaweed section */ 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..f5af516c0 100644 --- a/src/overlays/actors/ovl_Boss_03/z_boss_03.h +++ b/src/overlays/actors/ovl_Boss_03/z_boss_03.h @@ -2,18 +2,109 @@ #define Z_BOSS_03_H #include "global.h" +#include "objects/object_boss03/object_boss03.h" struct Boss03; typedef void (*Boss03ActionFunc)(struct Boss03*, GlobalContext*); +#define GYORG_WORK_TIMER_MAX 3 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x02 */ s16 unk_02; + /* 0x04 */ Vec3f pos; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f accel; + /* 0x28 */ UNK_TYPE1 unk_28[0x4]; + /* 0x2C */ s16 alpha; + /* 0x2E */ s16 alphaDelta; + /* 0x30 */ UNK_TYPE1 unk_30[0x4]; + /* 0x34 */ Vec3f unk_34; // it may not be a Vec3f + /* 0x40 */ f32 unk_40; // colorIntensity? +} GyorgEffect; // size = 0x44 + +#define GYORG_EFFECT_COUNT 150 + +typedef enum { + /* 0 */ GYORG_EFFECT_NONE, + /* 1 */ GYORG_EFFECT_BUBBLE, + /* 2 */ GYORG_EFFECT_DROPLET, + /* 3 */ GYORG_EFFECT_SPLASH, + /* 4 */ GYORG_EFFECT_WET_SPOT, +} GyorgEffectType; + typedef struct Boss03 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1E4]; + /* 0x0144 */ UNK_TYPE1 unk_144[0x04]; + /* 0x0148 */ SkelAnime skelAnime; + /* 0x018C */ Vec3s jointTable[GYORG_LIMB_MAX]; + /* 0x01E6 */ Vec3s morphTable[GYORG_LIMB_MAX]; + /* 0x0240 */ s16 unk_240; // generic timer? used by Gyorg and seaweed + /* 0x0242 */ u8 unk_242; + /* 0x0243 */ UNK_TYPE1 unk_243[0x09]; + /* 0x024C */ s16 workTimer[GYORG_WORK_TIMER_MAX]; + /* 0x0252 */ s8 numSpawnedSmallFish; // number of Tanron3 fish that are currently alive, -1 indexed + /* 0x0253 */ u8 hasSpwanedSmallFishes; // Tanron + /* 0x0254 */ s16 bubbleEffectSpawnCount; // Amount of bubble effect which will be spawned by Update + /* 0x0258 */ f32 waterHeight; // always 430.0f + /* 0x025C */ s16 unk_25C; // Timer related to collision? + /* 0x025E */ s16 unk_25E; + /* 0x0260 */ f32 unk_260; // rotY + /* 0x0264 */ UNK_TYPE1 unk_264[0x04]; + /* 0x0268 */ Vec3f unk_268; // set to player.world.pos or random values + /* 0x0274 */ s16 unk_274; + /* 0x0276 */ s16 unk_276; + /* 0x0278 */ f32 unk_278; + /* 0x027C */ f32 unk_27C; + /* 0x0280 */ s16 unk_280; + /* 0x0284 */ f32 unk_284; // Maybe a Vec3f + /* 0x0288 */ f32 unk_288; // Set but not used + /* 0x028C */ f32 unk_28C; + /* 0x0290 */ u8 unk_290; + /* 0x0294 */ f32 unk_294; + /* 0x0298 */ f32 unk_298; + /* 0x029C */ s16 leftFinYRot; + /* 0x029E */ s16 rightFinYRot; + /* 0x02A0 */ s16 bodyYRot; + /* 0x02A2 */ Vec3s unk_2A2; + /* 0x02A8 */ s16 jawZRot; + /* 0x02AC */ Vec3f insideJawPos; // used to grab player + /* 0x02B8 */ f32 unk_2B8; + /* 0x02BC */ u8 unk_2BC; // set but not used + /* 0x02BD */ u8 unk_2BD; // playerUnderwater? + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ UNK_TYPE1 unk_2C0[0x04]; + /* 0x02C0 */ f32 unk_2C4; + /* 0x02C8 */ Vec3f prevPlayerPos; + /* 0x02D4 */ u8 wetSpotEffectSpawnCount; + /* 0x02D5 */ u8 unk_2D5; // flag + /* 0x02D6 */ s16 shapeRotTargetX; + /* 0x02D8 */ s16 shapeRotTargetY; + /* 0x02DA */ s16 shapeRotTargetZ; + /* 0x02DC */ Vec3f seaweedSegmentPositions[6]; + /* 0x0324 */ s16 unk_324; // timer? set by Tanron3 /* 0x0328 */ Boss03ActionFunc actionFunc; - /* 0x032C */ char unk_32C[0x250]; + /* 0x032C */ ColliderJntSph headCollider; + /* 0x034C */ ColliderJntSphElement headColliderElements[2]; + /* 0x03CC */ ColliderJntSph bodyCollider; + /* 0x03EC */ ColliderJntSphElement bodyColliderElements[5]; + /* 0x052C */ f32 floppingAnimLastFrame; + /* 0x0530 */ u32 csTimer; + /* 0x0534 */ s16 csState; + /* 0x0536 */ s16 csCamId; + /* 0x0538 */ Vec3f csCamEye; + /* 0x0544 */ Vec3f csCamAt; + /* 0x0550 */ Vec3f csCamTargetEye; + /* 0x055C */ Vec3f csCamTargetAt; + /* 0x0568 */ f32 unk_568; + /* 0x056C */ f32 unk_56C; + /* 0x0570 */ f32 unk_570; // set but not used + /* 0x0574 */ UNK_TYPE1 unk_574[0x04]; + /* 0x0578 */ f32 cameraFov; } Boss03; // size = 0x57C - -extern const ActorInit Boss_03_InitVars; + +#define GYORG_PARAM_DEFAULT (0) +#define GYORG_PARAM_SEAWEED (0x23) #endif // Z_BOSS_03_H 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 58fd9a26e..659fdbe3f 100644 --- a/src/overlays/actors/ovl_Boss_04/z_boss_04.c +++ b/src/overlays/actors/ovl_Boss_04/z_boss_04.c @@ -1,6 +1,13 @@ -#include "z_boss_04.h" +/* + * File: z_boss_04.c + * Overlay: ovl_Boss_04 + * Description: Wart + */ -#define FLAGS 0x00000035 +#include "z_boss_04.h" +#include "objects/object_boss04/object_boss04.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss04*)thisx) @@ -9,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), @@ -63,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 (Flags_GetClear(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, true, false, false, + true, &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_RotateYS(phi_s0_2, MTXMODE_NEW); + Matrix_MultVecZ(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 &= ~ACTOR_FLAG_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_RotateYS(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; + Cutscene_Start(globalCtx, &globalCtx->csCtx); + this->unk_70A = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(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.actorLists[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) { + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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_MultVecZ(-100.0f, &this->unk_70C); + + this->unk_70C.x += player->actor.world.pos.x; + this->unk_70C.y = Player_GetHeight(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 = (Player_GetHeight(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_MultVecZ(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, CAM_ID_MAIN); + + 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; + Cutscene_End(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(27); + 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); + Play_CameraSetFov(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); + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ME_DEAD); + this->actor.flags &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_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); + SoundSource_PlaySfxAtFixedWorldPos(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; + Actor_PlaySfxAtPos(&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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 10.0f, MTXMODE_APPLY); + Matrix_MultZero(&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_RotateYS(this->unk_2DC, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2DE, MTXMODE_APPLY); + Matrix_Push(); + + for (i = 0; i < ARRAY_COUNT(this->unk_2E4); i++) { + Matrix_RotateXFApply(0.3926991f); + Matrix_MultVecZ(100.0f, &this->unk_2E4[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(38.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_3A4); i++) { + Matrix_RotateXFApply(0.41887903f); + Matrix_MultVecZ(92.0f, &this->unk_3A4[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(-38.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_458); i++) { + Matrix_RotateXFApply(0.41887903f); + Matrix_MultVecZ(92.0f, &this->unk_458[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(71.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_50C); i++) { + Matrix_RotateXFApply(0.5711987f); + Matrix_MultVecZ(71.0f, &this->unk_50C[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(-71.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_590); i++) { + Matrix_RotateXFApply(0.5711987f); + Matrix_MultVecZ(71.0f, &this->unk_590[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(92.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_614); i++) { + Matrix_RotateXFApply(1.0471976f); + Matrix_MultVecZ(38.0f, &this->unk_614[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(-92.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_65C); i++) { + Matrix_RotateXFApply(1.0471976f); + Matrix_MultVecZ(38.0f, &this->unk_65C[i]); + } + + Matrix_Pop(); + Matrix_Push(); + Matrix_Translate(100.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + Matrix_MultZero(&this->unk_6A4); + Matrix_Pop(); + Matrix_Translate(-100.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_MultZero(&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_MoveWithGravity(&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 |= ACTOR_FLAG_1; + } else { + this->actor.flags &= ~ACTOR_FLAG_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) { + Actor_PlaySfxAtPos(&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_MultVecY(-500.0f, &this->actor.focus.pos); + Matrix_MultVec3f(&D_809EE228, &sp18); + func_809EC040(0, &this->collider1, &sp18); + Matrix_MultVec3f(&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_Translate(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_Translate(this->unk_6BC.x, this->actor.floorHeight, this->unk_6BC.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(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..267688ab0 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 */ u8 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_05/z_boss_05.c b/src/overlays/actors/ovl_Boss_05/z_boss_05.c index 190b4693d..a88ad8008 100644 --- a/src/overlays/actors/ovl_Boss_05/z_boss_05.c +++ b/src/overlays/actors/ovl_Boss_05/z_boss_05.c @@ -1,6 +1,12 @@ +/* + * File: z_boss_05.c + * Overlay: ovl_Boss_05 + * Description: Bio Deku Baba + */ + #include "z_boss_05.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((Boss05*)thisx) diff --git a/src/overlays/actors/ovl_Boss_06/z_boss_06.c b/src/overlays/actors/ovl_Boss_06/z_boss_06.c index ed04e008d..07016aff9 100644 --- a/src/overlays/actors/ovl_Boss_06/z_boss_06.c +++ b/src/overlays/actors/ovl_Boss_06/z_boss_06.c @@ -1,6 +1,16 @@ -#include "z_boss_06.h" +/* + * File: z_boss_06.c + * Overlay: ovl_Boss_06 + * Description: Igos du Ikana window - curtains and ray effects + */ -#define FLAGS 0x00000035 +#include "prevent_bss_reordering.h" +#include "z_boss_06.h" +#include "overlays/actors/ovl_En_Knight/z_en_knight.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_knight/object_knight.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss06*)thisx) @@ -9,15 +19,22 @@ void Boss06_Destroy(Actor* thisx, GlobalContext* globalCtx); void Boss06_Update(Actor* thisx, GlobalContext* globalCtx); void Boss06_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_809F24A8(Boss06* this); void func_809F24C8(Boss06* this, GlobalContext* globalCtx); void func_809F2B64(Boss06* this, GlobalContext* globalCtx); void func_809F2C44(Boss06* this, GlobalContext* globalCtx); +void func_809F2E14(Boss06* this, GlobalContext* globalCtx); void func_809F2E34(Boss06* this, GlobalContext* globalCtx); +void func_809F2ED0(Boss06* this, GlobalContext* globalCtx); void func_809F2EE8(Boss06* this, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_809F4080 = { +static Vec3f D_809F4370[128]; +static EnKnight* D_809F4970; +static s32 D_809F4974; +static s32 D_809F4978; +static s32 D_809F497C; + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xF), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -64,47 +81,577 @@ const ActorInit Boss_06_InitVars = { (ActorFunc)Boss06_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809F40C0 = { - { 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, 0x04 }, { 0xF7FFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, 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, 0x04 }, + { 0xF7FFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 90, 140, 10, { 0, 0, 0 } }, }; +static Vec3f D_809F40EC[] = { + { 1081.0f, 235.0f, 3224.0f }, + { 676.0f, 235.0f, 3224.0f }, +}; + +void func_809F2120(s32 arg0, s32 arg1, s32 arg2) { + D_809F4974 = arg0; + D_809F4978 = arg1; + D_809F497C = arg2; +} + +f32 func_809F2140(void) { + f32 temp_f2; + + D_809F4974 = (D_809F4974 * 171) % 30269; + D_809F4978 = (D_809F4978 * 172) % 30307; + D_809F497C = (D_809F497C * 170) % 30323; + temp_f2 = (D_809F4974 / 30269.0f) + (D_809F4978 / 30307.0f) + (D_809F497C / 30323.0f); + + while (temp_f2 >= 1.0f) { + temp_f2 -= 1.0f; + } + + return fabsf(temp_f2); +} + +void Boss06_Init(Actor* thisx, GlobalContext* globalCtx) { + Boss06* this = THIS; + u8* temp_v0; + s32 i; + + D_809F4970 = (EnKnight*)this->actor.parent; + this->actor.colChkInfo.damageTable = &sDamageTable; + + if ((KREG(64) != 0) || (gSaveContext.eventInf[5] & 0x80)) { + this->actionFunc = func_809F2E14; + } else { + this->actionFunc = func_809F2B64; + } + + Actor_SetScale(&this->actor, 0.1f); + Math_Vec3f_Copy(&this->actor.world.pos, &D_809F40EC[ENBOSS06_GET_PARAMS(&this->actor)]); + this->actor.shape.rot.y = -0x8000; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + temp_v0 = SEGMENTED_TO_VIRTUAL(&object_knight_Tex_019490); + for (i = 0; i < ARRAY_COUNT(this->unk_200); i++) { + this->unk_200[i] = temp_v0[i]; + } + + this->actor.flags &= ~ACTOR_FLAG_1; +} + +void Boss06_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void func_809F23CC(Boss06* this) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if ((this->unk_1C9 == 0) && (D_809F4970->unk_68A == 0)) { + if (this->actor.colChkInfo.damageEffect == 2) { + func_809F24A8(this); + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + + this->unk_1B0 = -(this->actor.world.pos.x - this->collider.info.bumper.hitPos.x); + this->unk_1BC = this->unk_1B0 * 0.35f; + + this->unk_1B4 = -((this->actor.world.pos.y + 80.0f) - this->collider.info.bumper.hitPos.y); + this->unk_1C0 = this->unk_1B4 * -0.35f; + } + } + } +} + +void func_809F24A8(Boss06* this) { + this->actionFunc = func_809F24C8; + this->unk_A28 = 0.0f; + this->unk_1AC = 0.0f; +} + +#ifdef NON_MATCHING +// Weird loading of 1 +void func_809F24C8(Boss06* this, GlobalContext* globalCtx) { + s16 sp4E = 0; + Player* player = GET_PLAYER(globalCtx); + Actor* temp_s0; + Actor* temp_v0_2; + Actor* child; + + this->unk_1CA++; + + switch (this->unk_1C9) { + case 0: + if (ActorCutscene_GetCurrentIndex() != -1) { + break; + } + + Cutscene_Start(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 7); + this->unk_A00 = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->unk_A00, 7); + D_809F4970->unk_151 = 1; + this->unk_1C9 = 1; + this->unk_1C8 = 1; + this->unk_1E0 = 255.0f; + this->unk_1DC = 0.0f; + + temp_s0 = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + while (temp_s0 != NULL) { + if (temp_s0->id == ACTOR_EN_ARROW) { + Actor_MarkForDeath(temp_s0); + } + temp_s0 = temp_s0->next; + } + + case 1: + if (this->unk_1CA >= 10) { + Math_ApproachF(&this->unk_1E4, 30.0f, 0.2f, 1.0f); + globalCtx->envCtx.fillScreen = 1; + globalCtx->envCtx.screenFillColor[2] = 0; + globalCtx->envCtx.screenFillColor[1] = 0; + globalCtx->envCtx.screenFillColor[0] = 0; + globalCtx->envCtx.screenFillColor[3] = this->unk_A2C; + Math_ApproachF(&this->unk_A2C, 75.0f, 1.0f, 3.0f); + } + + if (this->unk_1CA >= 30) { + play_sound(NA_SE_EV_S_STONE_FLASH); + } + + if (this->unk_1CA >= 60) { + globalCtx->envCtx.fillScreen = 0; + this->unk_1C8 = 0; + this->unk_1DC = 0.0f; + this->unk_1D8 = 0.0f; + if (this->unk_1CA == 60) { + D_809F4970->unk_154++; + func_800B7298(globalCtx, &this->actor, 0x84); + player->actor.shape.rot.y = 0; + player->actor.world.rot.y = player->actor.shape.rot.y; + } + + this->unk_A04.x = player->actor.world.pos.x + 20.0f; + this->unk_A04.y = player->actor.world.pos.y + 20.0f; + this->unk_A04.z = player->actor.world.pos.z + 30.0f; + + this->unk_A10.x = player->actor.world.pos.x; + this->unk_A10.y = player->actor.world.pos.y + 26.0f; + this->unk_A10.z = player->actor.world.pos.z; + + if (this->unk_1CA >= 75) { + temp_v0_2 = globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; + while (temp_v0_2 != NULL) { + if ((temp_v0_2->id == ACTOR_EN_KNIGHT) && (&D_809F4970->actor == temp_v0_2) && + (D_809F4970->unk_680 != 0)) { + this->unk_A04.x = 1307.0f; + this->unk_A04.y = 142.0f; + this->unk_A04.z = 2897.0f; + + this->unk_A10.x = 1376.0f; + this->unk_A10.y = 132.0f; + this->unk_A10.z = 2860.0f; + + if (this->unk_1CA == 75) { + D_809F4970->unk_148 = 1; + } + sp4E = 17; + break; + } + temp_v0_2 = temp_v0_2->next; + } + } + + if ((s16)(sp4E + 80) < this->unk_1CA) { + this->unk_1C9 = 2; + this->unk_1CA = 0; + this->unk_1B4 = 0.0f; + this->unk_1B0 = 0.0f; + this->unk_144 = 2; + this->unk_1A4 = 0.0f; + this->unk_1A0 = 0.0f; + this->unk_1DC = 18.0f; + this->unk_1E0 = 255.0f; + this->unk_19C = 1.0f; + + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_MIR_RAY2, + this->actor.world.pos.x, this->actor.world.pos.y - 200.0f, + this->actor.world.pos.z - 170.0f, 15, 0, 0, 1); + + if (ENBOSS06_GET_PARAMS(&this->actor) == 0) { + this->unk_A04.x = this->actor.world.pos.x - 200.0f; + } else { + this->unk_A04.x = this->actor.world.pos.x + 200.0f; + } + this->unk_A04.y = (this->actor.world.pos.y - 200.0f) + 100.0f; + this->unk_A04.z = this->actor.world.pos.z - 200.0f; + + this->unk_A10.x = this->actor.world.pos.x; + this->unk_A10.y = this->actor.world.pos.y + 80.0f; + this->unk_A10.z = this->actor.world.pos.z; + } + } else { + this->unk_A10.z = this->actor.world.pos.z; + this->unk_A04.y = this->actor.world.pos.y + 60.0f; + this->unk_A04.x = this->actor.world.pos.x; + + this->unk_A04.z = this->actor.world.pos.z - 210.0f; + this->unk_A10.y = this->actor.world.pos.y + 80.0f; + this->unk_A10.x = this->actor.world.pos.x; + } + break; + + case 2: + child = this->actor.child; + + if (this->unk_1CA == 1) { + this->unk_A1C.x = fabsf(this->unk_A10.x - child->world.pos.x); + this->unk_A1C.y = fabsf(this->unk_A10.y - child->world.pos.y); + this->unk_A1C.z = fabsf(this->unk_A10.z - child->world.pos.z); + } + + Math_ApproachF(&this->unk_A10.x, child->world.pos.x, 0.15f, this->unk_A1C.x * this->unk_A28); + Math_ApproachF(&this->unk_A10.y, child->world.pos.y, 0.15f, this->unk_A1C.y * this->unk_A28); + Math_ApproachF(&this->unk_A10.z, child->world.pos.z, 0.15f, this->unk_A1C.z * this->unk_A28); + Math_ApproachF(&this->unk_A28, 1.0f, 1.0f, 0.001f); + + if (this->unk_1CA > 80) { + func_809F2ED0(this, globalCtx); + func_80169AFC(globalCtx, this->unk_A00, 0); + this->unk_A00 = 0; + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + D_809F4970->unk_151 = 0; + } + break; + } + + if (this->unk_A00 != 0) { + ShrinkWindow_SetLetterboxTarget(27); + Play_CameraSetAtEye(globalCtx, this->unk_A00, &this->unk_A10, &this->unk_A04); + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F24C8.s") #endif -extern DamageTable D_809F4080; -extern ColliderCylinderInit D_809F40C0; +void func_809F2B64(Boss06* this, GlobalContext* globalCtx) { + this->actionFunc = func_809F2C44; + this->unk_144 = 3; + this->unk_1A8 = 110.0f; + this->unk_1E0 = 200; + this->unk_1DC = 15.0f; + this->unk_1E4 = 30.0f; + this->unk_1AC = 0.0f; + this->unk_19C = 1.0f; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_MIR_RAY2, this->actor.world.pos.x, + this->actor.world.pos.y - 200.0f, this->actor.world.pos.z - 170.0f, 15, 0, 0, 1); + D_809F4970->unk_154++; +} -extern UNK_TYPE D_06018BD0; -extern UNK_TYPE D_06019490; +void func_809F2C44(Boss06* this, GlobalContext* globalCtx) { + if (D_809F4970->unk_153 != 0) { + this->unk_A28 = 0.008f; + Math_ApproachF(&this->unk_1E4, 0.0f, 0.2f, this->unk_A28 * 30.0f); + Math_ApproachF(&this->unk_1AC, -70.0f, 0.2f, this->unk_A28 * 70.0f); + Math_ApproachF(&this->unk_1A8, 0.0f, 0.2f, this->unk_A28 * 110.0f); + Math_ApproachF(&this->unk_1A0, -900.0f, 0.2f, this->unk_A28 * 900.0f); + Math_ApproachF(&this->unk_1A4, 1350.0f, 0.2f, this->unk_A28 * 1350.0f); + Math_ApproachF(&this->unk_1E0, 100.0f, 0.2f, this->unk_A28 * 100.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2120.s") + if (this->unk_1E4 < 5.0f) { + Math_ApproachF(&this->unk_19C, 0.0f, 1.0f, 0.03f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2140.s") + if ((this->unk_1E4 > 0.1f) && ENBOSS06_GET_PARAMS(&this->actor) == 0) { + play_sound(NA_SE_EV_CURTAIN_DOWN - SFX_FLAG); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/Boss06_Init.s") + if (D_809F4970->unk_153 == 2) { + Actor_MarkForDeath(this->actor.child); + this->actor.child = NULL; + func_809F2E14(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/Boss06_Destroy.s") +void func_809F2E14(Boss06* this, GlobalContext* globalCtx) { + this->actionFunc = func_809F2E34; + this->unk_144 = 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F23CC.s") +void func_809F2E34(Boss06* this, GlobalContext* globalCtx) { + this->unk_1E0 = 200.0f; + this->unk_1DC = 15.0f; + func_809F23CC(this); + Collider_UpdateCylinder(&this->actor, &this->collider); + this->collider.dim.pos.z = (this->actor.world.pos.z - 50.0f) + 100.0f; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F24A8.s") +void func_809F2ED0(Boss06* this, GlobalContext* globalCtx) { + this->actionFunc = func_809F2EE8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F24C8.s") +void func_809F2EE8(Boss06* this, GlobalContext* globalCtx) { + this->unk_1E0 = 100.0f; + this->unk_1DC = 13.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2B64.s") +void Boss06_Update(Actor* thisx, GlobalContext* globalCtx) { + Boss06* this = THIS; + s32 i; + Vec3f sp7C; + f32 temp_f22; + f32 phi_f26; + f32 phi_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2C44.s") + this->actionFunc(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2E14.s") + if (this->unk_146 != 0) { + this->unk_146--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2E34.s") + if (this->unk_148 != 0) { + this->unk_148--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2ED0.s") + if (this->unk_1E4 > 0.0f) { + if (ENBOSS06_GET_PARAMS(&this->actor) == 0) { + D_801F4E32 = 1; + D_801F4E38.x = this->actor.world.pos.x + this->unk_1B0; + D_801F4E38.y = this->actor.world.pos.y + 80.0f + this->unk_1B4 + this->unk_1AC; + D_801F4E38.z = this->actor.world.pos.z; + D_801F4E44 = this->unk_1E4; + D_801F4E48 = 10.0f; + D_801F4E4C = 0; + } else { + D_801F4E4E = 1; + D_801F4E50.x = this->actor.world.pos.x + this->unk_1B0; + D_801F4E50.y = this->actor.world.pos.y + 80.0f + this->unk_1B4 + this->unk_1AC; + D_801F4E50.z = this->actor.world.pos.z; + D_801F4E5C = this->unk_1E4; + D_801F4E60 = 10.0f; + D_801F4E64 = 0; + } + } else if (ENBOSS06_GET_PARAMS(&this->actor) == 0) { + D_801F4E32 = 0; + } else { + D_801F4E4E = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/func_809F2EE8.s") + if ((this->unk_1C8 != 0) && (this->unk_1C8 != 0)) { + play_sound(NA_SE_EV_FIRE_PLATE - SFX_FLAG); + this->unk_1CC += 0.6f; + this->unk_1D0 += 0.1f; + this->unk_1D4 += 0.0200000014156f; + this->unk_1D8 += 0.00016f; + this->unk_1DC += 0.4f; + Math_ApproachZeroF(&this->unk_1B0, 1.0f, 0.7f); + Math_ApproachZeroF(&this->unk_1B4, 1.0f, 0.7f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/Boss06_Update.s") + phi_f26 = 0.0f; + phi_f24 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_06/Boss06_Draw.s") + for (i = 0; i < 1024; i++) { + temp_f22 = (((sinf(phi_f24) * this->unk_1D4) + 1.0f) * ((sinf(phi_f26) * this->unk_1D0) + this->unk_1D0)) + + this->unk_1CC; + + phi_f26 += (M_PI / 64); + phi_f24 += 0.030679617f; + + Matrix_RotateZF(i * (M_PI / 512), MTXMODE_NEW); + Matrix_MultVecY(temp_f22, &sp7C); + + sp7C.x += 32.0f + this->unk_1BC; + sp7C.y += 32.0f + this->unk_1C0; + + if ((i % 8) == 0) { + Math_Vec3f_Copy(&D_809F4370[i / 8], &sp7C); + } + + if ((sp7C.x >= 0.0f) && (sp7C.y >= 0.0f) && (sp7C.x < 64.0f) && (sp7C.y < 64.0f)) { + s32 x = sp7C.x; + s32 idx = ((s32)sp7C.y << 5); + + idx += (x / 2); + + if ((x % 2) != 0) { + this->unk_200[idx] &= 0xF0; + } else { + this->unk_200[idx] &= 0xF; + } + } + } + } +} + +void Boss06_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + Boss06* this = THIS; + s32 i; + f32 spE0 = 0.0f; + s16 temp_s0; + s16 temp_f10; + Vtx* temp_v0_2; + u16 temp_v0; + u16 pad; + u8 spD3; + u8 spD2; + s32 maxColor = 255; //! FAKE: + f32 sp68; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + + temp_v0 = gSaveContext.save.time; + if (temp_v0 > CLOCK_TIME(12, 0)) { + temp_v0 = (DAY_LENGTH - 1) - temp_v0; + } + sp68 = (f32)temp_v0 / 0x8000; + spD3 = ((10.0f * sp68) + 105.0f) * this->unk_19C; + spD2 = ((40.0f * sp68) + 55.0f) * this->unk_19C; + + if (this->unk_144 & 2) { + temp_s0 = Math_SinS(D_809F4970->unk_144) * 1000.0f; + temp_f10 = (Math_CosS(D_809F4970->unk_144) * -2000.0f) - 2000.0f; + temp_v0_2 = SEGMENTED_TO_VIRTUAL(&object_knight_Vtx_018BD0); + + temp_v0_2[0].v.ob[1] = (s16)this->unk_1A0 + 0xE92; + temp_v0_2[3].v.ob[1] = (s16)this->unk_1A0 + 0xE92; + temp_v0_2[4].v.ob[1] = (s16)this->unk_1A0 + 0xE92; + temp_v0_2[7].v.ob[1] = (s16)this->unk_1A0 + 0xE92; + + temp_v0_2[5].v.ob[0] = temp_s0 + 0x2A3; + temp_v0_2[5].v.ob[2] = (temp_f10 + (s16)this->unk_1A4) - 0x708; + + temp_v0_2[6].v.ob[0] = temp_s0 - 0x2A3; + temp_v0_2[6].v.ob[2] = (temp_f10 + (s16)this->unk_1A4) - 0x708; + + temp_v0_2[9].v.ob[0] = temp_s0 + 0x2A3; + temp_v0_2[9].v.ob[2] = temp_f10 - 0x1C2; + + temp_v0_2[11].v.ob[0] = temp_s0 - 0x2A3; + temp_v0_2[11].v.ob[2] = temp_f10 - 0x1C2; + + temp_v0_2[12].v.ob[0] = temp_s0 + 0x2A3; + temp_v0_2[12].v.ob[2] = temp_f10 - 0x1C2; + + temp_v0_2[14].v.ob[0] = temp_s0 - 0x339; + temp_v0_2[14].v.ob[2] = temp_f10 - 0x79E; + + temp_v0_2[15].v.ob[0] = temp_s0 - 0x339; + temp_v0_2[15].v.ob[2] = temp_f10; + + temp_v0_2[16].v.ob[0] = temp_s0 + 0x339; + temp_v0_2[16].v.ob[2] = temp_f10; + + temp_v0_2[17].v.ob[0] = temp_s0 + 0x339; + temp_v0_2[17].v.ob[2] = temp_f10 - 0x79E; + + if (this->actor.child != NULL) { + Actor* child = this->actor.child; + + child->world.pos.x = this->actor.world.pos.x + (temp_s0 * 0.1f); + child->world.pos.z = (this->actor.world.pos.z - 170.0f) + (temp_f10 * 0.1f); + } + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_knight_Matanimheader_019360)); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y - 234.0f, this->actor.world.pos.z + 30.0f, + MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -1112.0f, 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, 155, 255, maxColor, (u8)((140.0f * sp68) + 115.0f), spD3); + gSPDisplayList(POLY_XLU_DISP++, object_knight_DL_018CF0); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, maxColor, (u8)((100.0f * sp68) + 65.0f), spD2); + gSPDisplayList(POLY_XLU_DISP++, object_knight_DL_018DE0); + + if (1) {} + } + + if (this->unk_144 & 1) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&this->unk_200)); + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + this->unk_1A8, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, 0.0f, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, 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_knight_DL_0193B0); + + if (this->unk_1D8 > 0.0f) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + 84.0f, this->actor.world.pos.z - 2.0f, + MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + func_809F2120(1, 0x71A5, 0x263A); + + gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 128, 255, 255, 0, 230); + + for (i = 0; i < ARRAY_COUNT(D_809F4370); i++) { + if ((fabsf(D_809F4370[i].x - 32.0f) < 30.0f) && (fabsf(D_809F4370[i].y - 32.0f) < 30.0f)) { + Matrix_Push(); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, + ((globalCtx->gameplayFrames + (i * 10)) * -20) % 512, 0x20, 0x80)); + + Matrix_Translate((D_809F4370[i].x - 32.0f) * -2.4f, (D_809F4370[i].y - 32.0f) * -2.4f, 0.0f, + MTXMODE_APPLY); + Matrix_RotateZF(i * (M_PI / 64), MTXMODE_APPLY); + + if (func_809F2140() < 0.5f) { + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + } + + Matrix_Scale(-0.02f / 10.0f, -this->unk_1D8, 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++, gGameplayKeepDrawFlameDL); + + Matrix_Pop(); + } + } + } else { + spE0 = 7.0f; + } + } + + if (this->unk_1DC > 0.0f) { + u8 temp_s2 = (this->unk_1E0 - 50.0f) + (50.0f * sp68); + + Matrix_Translate(this->actor.world.pos.x + this->unk_1B0, this->actor.world.pos.y + 84.0f + this->unk_1B4, + (this->actor.world.pos.z - 2.0f) + spE0, MTXMODE_NEW); + + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, (u8)((140.0f * sp68) + 115.0f), temp_s2); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 205, (u8)((100.0f * sp68) + 65.0f), 128); + + Matrix_Scale(this->unk_1DC, this->unk_1DC, 1.0f, MTXMODE_APPLY); + Matrix_RotateZS(globalCtx->gameplayFrames * 64, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Boss_06/z_boss_06.h b/src/overlays/actors/ovl_Boss_06/z_boss_06.h index b793b284b..d7e6875a2 100644 --- a/src/overlays/actors/ovl_Boss_06/z_boss_06.h +++ b/src/overlays/actors/ovl_Boss_06/z_boss_06.h @@ -7,11 +7,47 @@ struct Boss06; typedef void (*Boss06ActionFunc)(struct Boss06*, GlobalContext*); +#define ENBOSS06_GET_PARAMS(thisx) ((thisx)->params) + typedef struct Boss06 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x54]; + /* 0x0144 */ u8 unk_144; + /* 0x0146 */ s16 unk_146; + /* 0x0148 */ s16 unk_148; + /* 0x014C */ ColliderCylinder collider; /* 0x0198 */ Boss06ActionFunc actionFunc; - /* 0x019C */ char unk_19C[0x894]; + /* 0x019C */ f32 unk_19C; + /* 0x01A0 */ f32 unk_1A0; + /* 0x01A4 */ f32 unk_1A4; + /* 0x01A8 */ f32 unk_1A8; + /* 0x01AC */ f32 unk_1AC; + /* 0x01B0 */ f32 unk_1B0; + /* 0x01B4 */ f32 unk_1B4; + /* 0x01B8 */ UNK_TYPE1 unk1B8[4]; + /* 0x01BC */ f32 unk_1BC; + /* 0x01C0 */ f32 unk_1C0; + /* 0x01C4 */ UNK_TYPE1 unk1C4[4]; + /* 0x01C8 */ u8 unk_1C8; + /* 0x01C9 */ u8 unk_1C9; + /* 0x01CA */ s16 unk_1CA; + /* 0x01CC */ f32 unk_1CC; + /* 0x01D0 */ f32 unk_1D0; + /* 0x01D4 */ f32 unk_1D4; + /* 0x01D8 */ f32 unk_1D8; + /* 0x01DC */ f32 unk_1DC; + /* 0x01E0 */ f32 unk_1E0; + /* 0x01E4 */ f32 unk_1E4; + /* 0x01E8 */ UNK_TYPE1 unk1E8[0x15]; + /* 0x01FD */ u8 unk_1FD; + /* 0x01FE */ u8 unk_1FE; + /* 0x01FF */ u8 unk_1FF; + /* 0x0200 */ u8 unk_200[0x800]; + /* 0x0A00 */ s16 unk_A00; + /* 0x0A04 */ Vec3f unk_A04; + /* 0x0A10 */ Vec3f unk_A10; + /* 0x0A1C */ Vec3f unk_A1C; + /* 0x0A28 */ f32 unk_A28; + /* 0x0A2C */ f32 unk_A2C; } Boss06; // size = 0xA30 extern const ActorInit Boss_06_InitVars; diff --git a/src/overlays/actors/ovl_Boss_07/z_boss_07.c b/src/overlays/actors/ovl_Boss_07/z_boss_07.c index 4dbde29c7..3eaf66d90 100644 --- a/src/overlays/actors/ovl_Boss_07/z_boss_07.c +++ b/src/overlays/actors/ovl_Boss_07/z_boss_07.c @@ -1,8 +1,15 @@ +/* + * File: z_boss_07.c + * Overlay: ovl_Boss_07 + * Description: Majora + */ + #include "z_boss_07.h" #include "overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((Boss07*)thisx) @@ -263,7 +270,7 @@ static s32 sSeed1; static s32 sSeed2; void Boss07_Remains_DamageSfx(Boss07* this) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FOLLOWERS_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FOLLOWERS_DAMAGE); } void Boss07_InitRand(s32 seedInit0, s32 seedInit1, s32 seedInit2) { @@ -332,8 +339,8 @@ void Boss07_SmoothStop(Boss07* this, f32 maxStep) { } void func_809F4D10(Vec3f* dst, f32 scale) { - Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledZ(scale, dst); + Matrix_RotateYF(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); + Matrix_MultVecZ(scale, dst); } void Boss07_SpawnDust(Boss07* this, GlobalContext* globalCtx, u8 spawnInterval, u8 mode) { @@ -414,13 +421,13 @@ void Boss07_Wrath_Dodge(Boss07* this, GlobalContext* globalCtx, u8 arg2) { if (&this->actor == player->actor.parent) { player->unk_AE8 = 101; player->actor.parent = NULL; - player->unk_394 = 0; + player->csMode = 0; } } } void Boss07_Wrath_CheckExplosives(Boss07* this, GlobalContext* globalCtx) { - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; while (explosive != NULL) { f32 dx = explosive->world.pos.x - this->actor.world.pos.x; @@ -457,14 +464,14 @@ void Boss07_Wrath_BlastWhip(Vec3f* bombPos, Vec3f* pos, Vec3f* pull) { sp50.y = push; sp50.z = push; - Matrix_InsertYRotation_f(Math_Acot2F(dz, dx), MTXMODE_NEW); - Matrix_MultiplyVector3fByState(&sp50, pull); + Matrix_RotateYF(Math_Acot2F(dz, dx), MTXMODE_NEW); + Matrix_MultVec3f(&sp50, pull); } } } void Boss07_Wrath_BombWhips(Boss07* this, GlobalContext* globalCtx) { - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; while (explosive != NULL) { if (explosive->params == 1) { @@ -497,8 +504,8 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { MAJORA_REMAINS + REMAINS_GYORG, MAJORA_REMAINS + REMAINS_TWINMOLD, }; - static EffTireMarkInit sTopTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; - static EffTireMarkInit sMaskTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; + static EffectTireMarkInit sTopTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; + static EffectTireMarkInit sMaskTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; GlobalContext* globalCtx = globalCtx2; Boss07* this = THIS; s32 i; @@ -509,7 +516,7 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { this->actor.flags &= ~1; sMajoraStatic = this; sKillProjectiles = false; - globalCtx->envCtx.unk_C3 = 0; + globalCtx->envCtx.lightSettingOverride = 0; globalCtx->envCtx.unk_E0 = 2; } else { if (this->actor.params == MAJORA_BOSS) { @@ -553,7 +560,7 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { Boss07_Top_SetupThrown(this, globalCtx); this->actor.colChkInfo.damageTable = &sTopDmgTable; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, KREG(55) + 9.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, KREG(55) + 9.0f); this->actor.shape.shadowAlpha = 180; Collider_InitAndSetCylinder(globalCtx, &this->cyl2, &this->actor, &sTopCylInit); Effect_Add(globalCtx, &this->effectIndex, 4, 0, 0, &sTopTireMarkInit); @@ -567,7 +574,7 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { this->unk_181C = Rand_ZeroFloat(3.99f); } else if ((this->actor.params == MAJORA_MASK) || (this->actor.params == MAJORA_MASK_CS)) { this->actor.colChkInfo.damageTable = &sMaskDmgTable; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 15.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 15.0f); SkelAnime_Init(globalCtx, &this->skelAnime, &D_06019C58, &D_06019E48, this->jointTable, this->morphTable, MAJORA_MASK_LIMB_COUNT); if (this->actor.params == MAJORA_MASK) { @@ -617,7 +624,7 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { this->actor.draw = Boss07_Incarnation_Draw; Collider_InitAndSetJntSph(globalCtx, &this->sph1, &this->actor, &sIncarnationJntSphInit1, this->sphElems1); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 80.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 80.0f); this->csCamIndex = this->actor.shape.rot.z; if (this->csCamIndex != 0) { Boss07_Incarnation_SetupIntro(this, globalCtx); @@ -628,7 +635,7 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { this->unk_17B8[2] = 1.0f; this->unk_17B8[3] = 1.0f; this->unk_17B8[0] = 1.0f; - globalCtx->envCtx.unk_DC = 0.0f; + globalCtx->envCtx.lightBlend = 0.0f; } this->unk_17E0 = 1.0f; this->unk_17E4 = 1.0f; @@ -666,8 +673,8 @@ void Boss07_Init(Actor* thisx, GlobalContext* globalCtx2) { } #else static s16 sRemainsParams[4] = { 200, 201, 202, 203 }; -static EffTireMarkInit sTopTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; -static EffTireMarkInit sMaskTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; +static EffectTireMarkInit sTopTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; +static EffectTireMarkInit sMaskTireMarkInit = { 0, 40, { 0, 0, 15, 200 } }; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_07/Boss07_Init.s") #endif @@ -702,8 +709,8 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { this->unk_15C = 20; SkelAnime_Update(&this->skelAnime); this->unk_ABC8++; - 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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); switch (this->csState) { case 0: this->unk_ABC8 = 0; @@ -720,7 +727,7 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { } if (this->unk_ABC8 > 20) { if (this->unk_ABC8 == 21) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_GROW_HEAD_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_GROW_HEAD_OLD); } Math_ApproachS(&this->unk_17D8, 0, 5, 0x1000); this->unk_17DA = Math_SinS(this->unk_ABC8 * 0x1000) * this->unk_17E8; @@ -752,7 +759,7 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { Animation_MorphToPlayOnce(&this->skelAnime, &D_06025018, -15.0f); this->unk_1D4 = Animation_GetLastFrame(&D_06025018); func_8019FE1C(&this->actor.projectedPos, NA_SE_EV_ICE_PILLAR_RISING, 1.0f); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_SHOUT); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_SHOUT); } if (this->unk_ABC8 >= 110) { Math_ApproachF(&this->whipScale, 1.0f, 1.0f, 0.05f); @@ -763,15 +770,15 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { this->whipScale = 1.0f; } if (this->unk_ABC8 == 120) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP2_OLD); - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_KICK_OLD); - func_8019FE74(&D_801D6654, 0.0f, 0x3C); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_KICK_OLD); + func_8019FE74(&gSfxVolume, 0.0f, 0x3C); } if (this->unk_ABC8 == 112) { Audio_QueueSeqCmd(0x8069); } if (this->unk_ABC8 == 137) { - Actor_TitleCardCreate(globalCtx, &globalCtx->actorCtx.titleCtxt, + TitleCard_InitBossName(&globalCtx->state, &globalCtx->actorCtx.titleCtxt, Lib_SegmentedToVirtual(&D_06032040), 0xA0, 0xB4, 0x80, 0x28); } if (Animation_OnFrame(&this->skelAnime, this->unk_1D4)) { @@ -785,7 +792,7 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { sp48->at = this->csCamAt; func_80169AFC(globalCtx, this->csCamIndex, 0); this->csCamIndex = 0; - func_800EA0EC(globalCtx, &globalCtx->csCtx); + Cutscene_End(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 6); this->actor.flags |= 1; func_80165690(); @@ -798,8 +805,8 @@ void Boss07_Wrath_Intro(Boss07* this, GlobalContext* globalCtx) { } break; } - Matrix_MultiplyVector3fByState(&this->csCamNextEye, &this->csCamEye); - Matrix_MultiplyVector3fByState(&this->csCamNextAt, &this->csCamAt); + Matrix_MultVec3f(&this->csCamNextEye, &this->csCamEye); + Matrix_MultVec3f(&this->csCamNextAt, &this->csCamAt); if (this->csCamIndex != 0) { ShrinkWindow_SetLetterboxTarget(0x1B); Play_CameraSetAtEye(globalCtx, this->csCamIndex, &this->csCamAt, &this->csCamEye); @@ -843,12 +850,12 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCurrentIndex() != -1) { break; } - func_800EA0D4(globalCtx, &globalCtx->csCtx); + Cutscene_Start(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 1); - this->csCamIndex = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->csCamIndex, 7); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_DEAD_ROD); + this->csCamIndex = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, 0, 1); + Play_CameraChangeStatus(globalCtx, this->csCamIndex, 7); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_DEAD_ROD); case 1: this->unk_ABC8 = 0; this->csState = 2; @@ -867,16 +874,16 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { func_8016566C(150); case 2: if (this->unk_ABC8 == 20) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); } if (this->unk_ABC8 == 40) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); } if (this->unk_ABC8 == 60) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); } if (this->unk_ABC8 == 80) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); } spB4.x = 0.0f; spB4.y = -90.0f; @@ -887,7 +894,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { if ((this->unk_ABC8 >= 50) && (this->unk_ABC8 < 80)) { if (this->unk_ABC8 == 50) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND1_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND1_OLD); } spB4.x = 30.0f; spB4.z = 120.0f; @@ -897,7 +904,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { } else if ((this->unk_ABC8 >= 80) && (this->unk_ABC8 < 110)) { if (this->unk_ABC8 == 80) { this->skelAnime.curFrame -= 30.0f; - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND2_OLD); } spB4.x = -10.0f; spB4.z = 150.0f; @@ -906,7 +913,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { spA0 = 1.0f; } else if ((this->unk_ABC8 >= 110) && (this->unk_ABC8 < 140)) { if (this->unk_ABC8 == 110) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND3_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_DEAD_WIND3_OLD); } spB4.x = -70.0f; spB4.z = 110.0f; @@ -917,7 +924,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= (sREG(15) + 140)) { this->csState = 4; this->csCamEyeMod.y = sREG(16) + 270.0f + 50.0f; - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_DEAD_FLOAT); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_DEAD_FLOAT); } else { break; } @@ -939,7 +946,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { this->unk_1D8 = KREG(81) + 10; this->unk_AB48 = 1; - func_8019F1C0(&sSfxPoint, NA_SE_EV_BURN_OUT - SFX_FLAG); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EV_BURN_OUT - SFX_FLAG); } else { spB4.x = 0.0f; spB4.y = -190.0f; @@ -965,12 +972,12 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { func_801A479C(&sSfxPoint, NA_SE_EN_LAST3_DEAD_LIGHTS_OLD, 0x3C); } - globalCtx->envCtx.unk_E5 = 1; - globalCtx->envCtx.unk_E6[0] = globalCtx->envCtx.unk_E6[1] = globalCtx->envCtx.unk_E6[2] = 255; + globalCtx->envCtx.fillScreen = 1; + globalCtx->envCtx.screenFillColor[0] = globalCtx->envCtx.screenFillColor[1] = globalCtx->envCtx.screenFillColor[2] = 255; if (this->unk_ABC8 < 350) { sp98 = 0.5f; sp94 = 0.02f; - globalCtx->envCtx.unk_E6[3] = 0; + globalCtx->envCtx.screenFillColor[3] = 0; } else { sp98 = 5.0f; sp94 = 0.1f; @@ -978,9 +985,9 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { if (temp_a0 > 250) { temp_a0 = 250; } - globalCtx->envCtx.unk_E6[3] = temp_a0; + globalCtx->envCtx.screenFillColor[3] = temp_a0; if (this->unk_ABC8 == 400) { - func_8019FE74(&D_801D6654, 0.0f, 90); + func_8019FE74(&gSfxVolume, 0.0f, 90); } if (this->unk_ABC8 == (KREG(94) + 440)) { globalCtx->nextEntranceIndex = 0x5400; @@ -996,7 +1003,7 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { for (i = 0; i < ARRAY_COUNT(this->deathLightScale); i++) { Math_ApproachF(&this->deathLightScale[i], sp98, 1.0f, sp94); } - Math_ApproachF(&globalCtx->envCtx.unk_DC, 1.0f, 1.0f, 0.1f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, 1.0f, 1.0f, 0.1f); } } this->csCamRotY += this->csCamRotVel; @@ -1032,8 +1039,8 @@ void Boss07_Wrath_Death(Boss07* this, GlobalContext* globalCtx) { } break; } - Matrix_InsertYRotation_f(this->csCamRotY, MTXMODE_NEW); - Matrix_MultiplyVector3fByState(&spB4, &this->csCamNextEye); + Matrix_RotateYF(this->csCamRotY, MTXMODE_NEW); + Matrix_MultVec3f(&spB4, &this->csCamNextEye); this->csCamNextEye.x += this->actor.focus.pos.x; this->csCamNextEye.y += this->actor.focus.pos.y; this->csCamNextEye.z += this->actor.focus.pos.z; @@ -1120,9 +1127,9 @@ void Boss07_Wrath_StartJump(Boss07* this, GlobalContext* globalCtx) { } void Boss07_Wrath_Jump(Boss07* this, GlobalContext* globalCtx) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_MIBOSS_JUMP2 - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIBOSS_JUMP2 - SFX_FLAG); if (this->actionTimer == 13) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_LAUGH_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_LAUGH_OLD); } SkelAnime_Update(&this->skelAnime); if (this->actor.bgCheckFlags & 1) { @@ -1152,8 +1159,8 @@ void Boss07_Wrath_SetupFlip(Boss07* this, GlobalContext* globalCtx) { dx = -200.0f; Animation_MorphToPlayOnce(&this->skelAnime, &D_0603D7F0, -5.0f); } - Matrix_RotateY(this->actor.yawTowardsPlayer, MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledX(dx, &sp30); + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + Matrix_MultVecX(dx, &sp30); dx = sp30.x - this->actor.world.pos.x; dz = sp30.z - this->actor.world.pos.z; this->actor.world.rot.y = Math_Acot2F(dz, dx) * (0x8000 / M_PI); @@ -1162,14 +1169,14 @@ void Boss07_Wrath_SetupFlip(Boss07* this, GlobalContext* globalCtx) { } void Boss07_Wrath_Flip(Boss07* this, GlobalContext* globalCtx) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_MIBOSS_JUMP2 - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIBOSS_JUMP2 - SFX_FLAG); SkelAnime_Update(&this->skelAnime); this->leftWhip.stiffness = this->rightWhip.stiffness = 0.7f; this->leftWhip.drag = this->rightWhip.drag = 2.0f; this->leftWhip.gravity = this->rightWhip.gravity = -15.0f; this->leftWhip.tension = this->rightWhip.tension = 0.0f; if ((this->actionTimer == 10) && (Rand_ZeroOne() < 0.5f)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_LAUGH_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_LAUGH_OLD); } if ((this->actor.velocity.y < 0.0f) && (this->actor.bgCheckFlags & 1)) { if (Rand_ZeroOne() < 0.3f) { @@ -1194,7 +1201,7 @@ void Boss07_Wrath_SetupSidestep(Boss07* this, GlobalContext* globalCtx) { phi_f14 = -this->actor.world.pos.x; phi_f12 = -this->actor.world.pos.z; sp22 = this->actor.yawTowardsPlayer - (s16)(Math_Acot2F(phi_f12, phi_f14) * (0x8000 / M_PI)); - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); if (sp22 < 0) { this->skelAnime.playSpeed = 1.0f; phi_f14 = 300.0f; @@ -1202,7 +1209,7 @@ void Boss07_Wrath_SetupSidestep(Boss07* this, GlobalContext* globalCtx) { this->skelAnime.playSpeed = -1.0f; phi_f14 = -300.0f; } - Matrix_GetStateTranslationAndScaledX(phi_f14, &this->unk_164); + Matrix_MultVecX(phi_f14, &this->unk_164); this->unk_164.x += this->actor.world.pos.x; this->unk_164.z += this->actor.world.pos.z; this->timers[1] = 21; @@ -1214,11 +1221,11 @@ void Boss07_Wrath_SetupSidestep(Boss07* this, GlobalContext* globalCtx) { void Boss07_Wrath_Sidestep(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (this->actionTimer == 20) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_KICK_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_KICK_OLD); } this->unk_ABCC++; if ((this->unk_ABCC % 16) == 0) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_WALK2_OLD); } this->leftWhip.stiffness = this->rightWhip.stiffness = 0.7f; this->leftWhip.drag = this->rightWhip.drag = 2.0f; @@ -1308,7 +1315,7 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { switch (this->actionState) { case 0: if (this->actionTimer == (s16)(KREG(92) + 1)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } if ((this->actionTimer >= 15) && (this->actionTimer < 18)) { this->rightWhip.tension = 500.0f; @@ -1317,15 +1324,15 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { this->unk_14F = 11; } if (this->actionTimer == 1) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); } if (this->actionTimer == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); } break; case 1: if (this->actionTimer == (s16)(KREG(91) + 3)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_THROW_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_THROW_OLD); } if ((this->actionTimer >= 8) && (this->actionTimer <= 55)) { this->leftWhip.tension = this->rightWhip.tension = 300.0f; @@ -1333,14 +1340,14 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { play_sound(NA_SE_EN_LAST3_ROD_FLOOR_OLD); } if ((this->actionTimer % 4) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); } Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); } break; case 2: if (this->actionTimer == (s16)(KREG(84) + 5)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } if ((this->actionTimer >= 32) && (this->actionTimer <= 38)) { this->rightWhip.tension = 300.0f; @@ -1350,15 +1357,15 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { this->unk_14F = 11; } if (this->actionTimer == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); } if (this->actionTimer == 32) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); } break; case 3: if (this->actionTimer == (s16)(KREG(84) + 5)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } if ((this->actionTimer > 30) && (this->actionTimer <= 35)) { this->rightWhip.tension = 1200.0f; @@ -1369,19 +1376,19 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { Math_ApproachF(&this->unk_184, -0.1f, 0.5f, 0.1f); Math_ApproachF(&this->unk_188, 0.3f, 0.5f, 0.1f); if (this->actionTimer == 5) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); } if (this->actionTimer == 30) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); } break; case 4: if ((this->actionTimer > 16) && (this->actionTimer <= 40)) { this->leftWhip.tension = this->rightWhip.tension = 200.0f; if ((this->actionTimer % 8) == 0) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_KOMA_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_KOMA_OLD); } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_DANCE_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_DANCE_OLD - SFX_FLAG); Math_ApproachF(&this->actor.world.pos.x, this->unk_164.x, 0.1f, this->unk_170); Math_ApproachF(&this->actor.world.pos.z, this->unk_164.z, 0.1f, this->unk_170); Math_ApproachF(&this->unk_170, 20.0f, 1.0f, 4.0f); @@ -1392,7 +1399,7 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { case 7: this->unk_174 = false; if (this->actionTimer == 3) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_KICK_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_KICK_OLD); } break; case 5: @@ -1403,7 +1410,7 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { break; case 6: if (this->actionTimer == (s16)(KREG(85) + 5)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } if ((this->actionTimer >= 14) && (this->actionTimer < 19)) { this->rightWhip.tension = 150.0f; @@ -1416,15 +1423,15 @@ void Boss07_Wrath_Attack(Boss07* this, GlobalContext* globalCtx) { } Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); if (this->actionTimer == 20) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } if (this->actionTimer == 5) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_HOP2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_HOP2_OLD); } if (this->actionTimer == 41) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_ROD_OLD); } break; } @@ -1469,7 +1476,7 @@ void Boss07_Wrath_GrabPlayer(Boss07* this, GlobalContext* globalCtx) { this->unk_15A = 20; this->unk_F7C++; if (this->actionTimer > (s16)(46 - this->unk_F7E)) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_THROW_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_THROW_OLD); play_sound(NA_SE_EN_LAST3_COIL_ATTACK_OLD); this->actionFunc = Boss07_Wrath_ThrowPlayer; Animation_MorphToPlayOnce(&this->skelAnime, &D_06027270, -5.0f); @@ -1494,7 +1501,7 @@ void Boss07_Wrath_ThrowPlayer(Boss07* this, GlobalContext* globalCtx) { if (&this->actor == player->actor.parent) { player->unk_AE8 = 101; player->actor.parent = NULL; - player->unk_394 = 0; + player->csMode = 0; if (player->transformation == PLAYER_FORM_DEKU) { phi_f0 = 23.0f; phi_f2 = 20.0f; @@ -1557,7 +1564,7 @@ void Boss07_Wrath_Shock(Boss07* this, GlobalContext* globalCtx) { } } if (this->unk_784 == 0) { - Math_ApproachF(&globalCtx->envCtx.unk_DC, 1.0f, 1.0f, 0.3f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, 1.0f, 1.0f, 0.3f); Math_ApproachF(&this->unk_32C, 5.0f, 0.5f, 3.0f); play_sound(NA_SE_EN_BIRI_SPARK - SFX_FLAG); } else { @@ -1571,7 +1578,7 @@ void Boss07_Wrath_Shock(Boss07* this, GlobalContext* globalCtx) { if (&this->actor == player->actor.parent) { player->unk_AE8 = 101; player->actor.parent = NULL; - player->unk_394 = 0; + player->csMode = 0; } Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.focus.pos.x, this->actor.focus.pos.y - 10.0f, this->actor.focus.pos.z, 0, 0, 0, 4); @@ -1591,7 +1598,7 @@ void Boss07_Wrath_ShockStun(Boss07* this, GlobalContext* globalCtx) { Math_ApproachF(&this->unk_32C, 5.0f, 0.5f, 3.0f); Math_ApproachF(&this->unk_330, 2.5f, 0.5f, 2.0f); play_sound(NA_SE_EN_BIRI_SPARK - SFX_FLAG); - Math_ApproachF(&globalCtx->envCtx.unk_DC, 1.0f, 1.0f, 0.3f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, 1.0f, 1.0f, 0.3f); } if (Animation_OnFrame(&this->skelAnime, this->unk_1D4)) { Boss07_Wrath_Dodge(this, globalCtx, true); @@ -1605,7 +1612,7 @@ void Boss07_Wrath_SetupStunned(Boss07* this, GlobalContext* globalCtx) { this->unk_1D4 = Animation_GetLastFrame(&D_0603B330); } this->unk_158 = 10; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_DAMAGE_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_DAMAGE_OLD); } void Boss07_Wrath_SetupSpawnTop(Boss07* this, GlobalContext* globalCtx) { @@ -1629,10 +1636,10 @@ void Boss07_Wrath_SpawnTop(Boss07* this, GlobalContext* globalCtx) { } if (1) {} if (this->actionTimer == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_ROD_WIND_OLD); } if (this->actionTimer == (s16)(KREG(40) + 18)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_KOMA_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_KOMA_OLD); } if ((this->actionTimer < (s16)(KREG(40) + 14)) || ((s16)(KREG(41) + 17) < this->actionTimer)) { SkelAnime_Update(&this->skelAnime); @@ -1662,7 +1669,7 @@ void Boss07_Wrath_SpawnTop(Boss07* this, GlobalContext* globalCtx) { void Boss07_Wrath_Stunned(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - func_8019F1C0(&sSfxPoint, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); Boss07_SmoothStop(this, 2.0f); this->leftWhip.stiffness = this->rightWhip.stiffness = 0.7f; this->leftWhip.gravity = this->rightWhip.gravity = -15.0f; @@ -1679,14 +1686,14 @@ void Boss07_Wrath_SetupDamaged(Boss07* this, GlobalContext* globalCtx, u8 damage } if ((s8)this->actor.colChkInfo.health <= 0) { if (KREG(19) != 0) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST3_VOICE_DEAD_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST3_VOICE_DEAD_OLD); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_DEAD_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_DEAD_OLD); } this->unk_148 = true; Enemy_StartFinishingBlow(globalCtx, &this->actor); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST3_VOICE_DAMAGE2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST3_VOICE_DAMAGE2_OLD); if (this->actionFunc != Boss07_Wrath_Damaged) { Animation_MorphToPlayOnce(&this->skelAnime, &D_0601DEB4, -10.0f); this->actionFunc = Boss07_Wrath_Damaged; @@ -1706,7 +1713,7 @@ void Boss07_Wrath_Damaged(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->unk_ABCC++; if ((this->unk_ABCC % 16) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); } Boss07_SmoothStop(this, 2.0f); this->leftWhip.stiffness = this->rightWhip.stiffness = 0.7f; @@ -1728,7 +1735,7 @@ void Boss07_Wrath_WhipCollisionCheck(Vec3f* arg0, f32 arg1, Boss07* this, Global Vec3f sp7C; if ((arg1 >= 50.0f) && (this->unk_15A == 0)) { - Actor* prop = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + Actor* prop = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; while (prop != NULL) { if (prop->id == ACTOR_OBJ_TSUBO) { @@ -1767,7 +1774,7 @@ void Boss07_Wrath_WhipCollisionCheck(Vec3f* arg0, f32 arg1, Boss07* this, Global f32 dxz1; player->actor.parent = &this->actor; - func_801A5CFC(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, + Audio_PlaySfxGeneral(NA_SE_VO_LI_DAMAGE_S, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); this->unk_F7C = 0; this->unk_F7E = ((this->actor.xzDistToPlayer - 300.0f) / 22.0f) + 10.0f; @@ -1840,7 +1847,7 @@ void Boss07_Wrath_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { break; case 10: this->unk_1805 = 40; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); break; case 9: this->unk_1805 = 30; @@ -1867,7 +1874,7 @@ void Boss07_Wrath_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { if (&this->actor == player->actor.parent) { player->unk_AE8 = 101; player->actor.parent = NULL; - player->unk_394 = 0; + player->csMode = 0; } } break; @@ -1884,7 +1891,7 @@ void Boss07_Wrath_BreakIce(Boss07* this, GlobalContext* globalCtx) { Vec3f vel; s32 i; - Audio_PlaySoundAtPosition(globalCtx, this->bodyPartsPos, 30, NA_SE_EV_ICE_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, this->bodyPartsPos, 30, NA_SE_EV_ICE_BROKEN); for (i = 0; i < 30; i++) { vel.x = randPlusMinusPoint5Scaled(7.0f); vel.z = randPlusMinusPoint5Scaled(7.0f); @@ -1913,7 +1920,7 @@ void Boss07_Wrath_DamageEffects(Boss07* this, GlobalContext* globalCtx) { this->unk_1800 = 1.0f; this->unk_17F8 = 0.0f; this->unk_1805++; - func_800BCB70(&this->actor, 0x4000, 120, 0, 60); + Actor_SetColorFilter(&this->actor, 0x4000, 120, 0, 60); case 2: if (this->unk_1806 == 0) { Math_ApproachZeroF(&this->unk_1800, 1.0f, 0.02f); @@ -1993,7 +2000,7 @@ void Boss07_Wrath_Update(Actor* thisx, GlobalContext* globalCtx2) { globalCtx->envCtx.unk_C1 = 2; globalCtx->envCtx.unk_C2 = 0; this->actor.hintId = 52; - Math_ApproachF(&globalCtx->envCtx.unk_DC, 0.0f, 1.0f, 0.03f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, 0.0f, 1.0f, 0.03f); this->unk_149 = true; Math_Vec3f_Copy(&sSfxPoint, &this->actor.projectedPos); if (KREG(63) == 0) { @@ -2014,7 +2021,7 @@ void Boss07_Wrath_Update(Actor* thisx, GlobalContext* globalCtx2) { Math_ApproachZeroF(&this->unk_32C, 1.0f, 0.2f); Math_ApproachZeroF(&this->unk_330, 1.0f, 0.04f); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 100.0f, 100.0f, 5); if (this->unk_14F != 0) { this->unk_14F--; @@ -2097,7 +2104,7 @@ void Boss07_Wrath_Update(Actor* thisx, GlobalContext* globalCtx2) { } Boss07_Wrath_DamageEffects(this, globalCtx); if ((this->unk_156 == 1) || (this->unk_156 == 4)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); } if ((player->actor.world.pos.y > 100.0f) && (player->actor.world.pos.z < KREG(82) + -850.0f)) { player->actor.world.pos.z = KREG(82) + -850.0f; @@ -2107,7 +2114,7 @@ void Boss07_Wrath_Update(Actor* thisx, GlobalContext* globalCtx2) { } } -void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* base, Vec3f* pos, Vec3f* rot, Vec3f* pull, +void Boss07_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* base, Vec3f* pos, Vec3f* rot, Vec3f* pull, f32 gravity, f32 stiffness, f32 drag, f32 tension, Vec3s* baseRot, s16 argB, f32 scale, s32 whipHand) { s32 i; @@ -2138,19 +2145,19 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas } } spAC.z = 20.0f; - Matrix_RotateY(baseRot->y, MTXMODE_NEW); - Matrix_InsertXRotation_s(baseRot->x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(baseRot->z, MTXMODE_APPLY); - Matrix_RotateY(0x4000, MTXMODE_APPLY); - Matrix_GetStateTranslationAndScaledZ(spAC.z, &sp94); + Matrix_RotateYS(baseRot->y, MTXMODE_NEW); + Matrix_RotateXS(baseRot->x, MTXMODE_APPLY); + Matrix_RotateZS(baseRot->z, MTXMODE_APPLY); + Matrix_RotateYS(0x4000, MTXMODE_APPLY); + Matrix_MultVecZ(spAC.z, &sp94); if (argB != 0) { spAC.z = 200.0f; - Matrix_InsertYRotation_f(this->unk_F8C, MTXMODE_NEW); - Matrix_RotateStateAroundXAxis(this->unk_F90); + Matrix_RotateYF(this->unk_F8C, MTXMODE_NEW); + Matrix_RotateXFApply(this->unk_F90); } else { spAC.z = tension; } - Matrix_GetStateTranslationAndScaledZ(spAC.z, &sp7C); + Matrix_MultVecZ(spAC.z, &sp7C); pos++; rot++; @@ -2165,13 +2172,13 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas } else if (argB != 0) { if (argB <= i && i < (s16)(argB + this->unk_F7C)) { sp88.y = 0.0f; - sp88.x = __sinf(this->actor.yawTowardsPlayer * M_PI / 0x8000 + (phi_s6 * 1.4f)) * 100.0f; - sp88.z = __cosf(this->actor.yawTowardsPlayer * M_PI / 0x8000 + (phi_s6 * 1.4f)) * 100.0f; - sp7C = D_801D15B0; + sp88.x = sinf(this->actor.yawTowardsPlayer * M_PI / 0x8000 + (phi_s6 * 1.4f)) * 100.0f; + sp88.z = cosf(this->actor.yawTowardsPlayer * M_PI / 0x8000 + (phi_s6 * 1.4f)) * 100.0f; + sp7C = gZeroVec3f; phi_s6++; } } else { - sp88 = D_801D15B0; + sp88 = gZeroVec3f; } temp_f24 = pos->x + pull->x - (pos - 1)->x + sp88.x + sp7C.x; phi_f0 = pos->y + pull->y + gravity + sp88.y + sp7C.y; @@ -2182,9 +2189,9 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas temp1 = -Math_Acot2F(sqrtf(SQ(temp_f24) + SQ(temp_f20)), temp_f26); (rot - 1)->y = temp_f22; (rot - 1)->x = temp1; - Matrix_InsertYRotation_f(temp_f22, MTXMODE_NEW); - Matrix_RotateStateAroundXAxis(temp1); - Matrix_GetStateTranslationAndScaledZ(spB8.z, &spA0); + Matrix_RotateYF(temp_f22, MTXMODE_NEW); + Matrix_RotateXFApply(temp1); + Matrix_MultVecZ(spB8.z, &spA0); if (1) {} temp_f24 = pos->x; temp_f26 = pos->y; @@ -2198,7 +2205,7 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas spAC.x = 15.0f; spAC.y = -30.0f; spAC.z = -12.0f; - Matrix_MultiplyVector3fByState(&spAC, &spA0); + Matrix_MultVec3f(&spAC, &spA0); this->unk_F80.x = pos->x + spA0.x; this->unk_F80.y = pos->y + spA0.y; this->unk_F80.z = pos->z + spA0.z; @@ -2207,7 +2214,7 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas spAC.x = KREG(60); spAC.y = KREG(61); spAC.z = KREG(62); - Matrix_MultiplyVector3fByState(&spAC, &spA0); + Matrix_MultVec3f(&spAC, &spA0); this->unk_F80.x = pos->x + spA0.x; this->unk_F80.y = pos->y + spA0.y; this->unk_F80.z = pos->z + spA0.z; @@ -2237,7 +2244,7 @@ void Boss07_Wrath_UpdateWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* bas } } -void Boss07_Wrath_DrawWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* pos, Vec3f* rot, f32 arg4, s32 hand) { +void Boss07_DrawWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* pos, Vec3f* rot, f32 arg4, s32 hand) { s32 phi_s6; s32 i; f32 phi_f12; @@ -2251,10 +2258,10 @@ void Boss07_Wrath_DrawWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* pos, gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sREG(48) + 45, 35, 75, 255); phi_s6 = (hand == 0) ? this->unk_778 : 0; for (i = 0; i < (sWhipSegCount - phi_s6) - 1; i++, pos++, rot++) { - Matrix_InsertTranslation(pos->x, 0.0f, pos->z, MTXMODE_NEW); + Matrix_Translate(pos->x, 0.0f, pos->z, MTXMODE_NEW); Matrix_Scale(1.0f, 0.0f, 1.0f, MTXMODE_APPLY); - Matrix_InsertYRotation_f(rot->y, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(rot->x); + Matrix_RotateYF(rot->y, MTXMODE_APPLY); + Matrix_RotateXFApply(rot->x); phi_f12 = (i > 24) ? 0.025f : ((f32)(24 - i) * 1 * 0.001f) + 0.025f; Matrix_Scale(phi_f12, phi_f12, ((2 * arg4) + 0.5f) * 0.01f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -2265,9 +2272,9 @@ void Boss07_Wrath_DrawWhips(Boss07* this, GlobalContext* globalCtx, Vec3f* pos, gSPDisplayList(POLY_OPA_DISP++, D_0602EE50); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 155, 155, 80, 255); for (i = 0; i < (sWhipSegCount - phi_s6) - 1; i++, pos++, rot++) { - Matrix_InsertTranslation(pos->x, pos->y, pos->z, MTXMODE_NEW); - Matrix_InsertYRotation_f(rot->y, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(rot->x); + Matrix_Translate(pos->x, pos->y, pos->z, MTXMODE_NEW); + Matrix_RotateYF(rot->y, MTXMODE_APPLY); + Matrix_RotateXFApply(rot->x); phi_f12 = (i > 24) ? 0.025f : ((f32)(24 - i) * 1 * 0.001f) + 0.025f; Matrix_Scale(phi_f12, phi_f12, ((2 * arg4) + 0.5f) * 0.01f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -2308,36 +2315,36 @@ void Boss07_Wrath_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL sp6B = sWrathBodyParts[limbIndex]; if (sp6B >= 0) { - Matrix_GetStateTranslation(&this->bodyPartsPos[sp6B]); + Matrix_MultZero(&this->bodyPartsPos[sp6B]); } sp6B = sLimbColliderIndex[limbIndex]; if (sp6B >= 0) { if (this->unk_158 != 0) { - Matrix_GetStateTranslationAndScaledZ(100000.0f, &sp5C); + Matrix_MultVecZ(100000.0f, &sp5C); } else { - Matrix_MultiplyVector3fByState(&sWrathColliderOffsets[sp6B], &sp5C); + Matrix_MultVec3f(&sWrathColliderOffsets[sp6B], &sp5C); } Boss07_UpdateSpheres(sp6B, &this->sph1, &sp5C); } if (limbIndex == 26) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } if (limbIndex == 19) { - Matrix_MultiplyVector3fByState(&sWhipOffset, &this->rightWhip.basePos); + Matrix_MultVec3f(&sWhipOffset, &this->rightWhip.basePos); } if (limbIndex == 17) { - Matrix_CopyCurrentState(&sp1C); - func_8018219C(&sp1C, &this->rightWhip.baseRot, 0); + Matrix_Get(&sp1C); + Matrix_MtxFToYXZRot(&sp1C, &this->rightWhip.baseRot, 0); } if (limbIndex == 24) { - Matrix_MultiplyVector3fByState(&sWhipOffset, &this->leftWhip.basePos); + Matrix_MultVec3f(&sWhipOffset, &this->leftWhip.basePos); } if (limbIndex == 22) { - Matrix_CopyCurrentState(&sp1C); - func_8018219C(&sp1C, &this->leftWhip.baseRot, 0); + Matrix_Get(&sp1C); + Matrix_MtxFToYXZRot(&sp1C, &this->leftWhip.baseRot, 0); } if (limbIndex == 12) { - Matrix_GetStateTranslation(&sp5C); + Matrix_MultZero(&sp5C); Boss07_UpdateSpheres(0, &this->sph2, &sp5C); } } @@ -2352,7 +2359,7 @@ void Boss07_Wrath_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Act } } -void Boss07_Wrath_DrawShocks(Boss07* this, GlobalContext* globalCtx) { +void Boss07_DrawShocks(Boss07* this, GlobalContext* globalCtx) { s32 i; GraphicsContext* gfxCtx; @@ -2363,44 +2370,44 @@ void Boss07_Wrath_DrawShocks(Boss07* this, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 0, 0); if (this->unk_32C > 0.0f) { - gSPDisplayList(POLY_XLU_DISP++, D_04023348); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) { - Matrix_InsertTranslation(this->bodyPartsPos[i].x, this->bodyPartsPos[i].y, this->bodyPartsPos[i].z, + Matrix_Translate(this->bodyPartsPos[i].x, this->bodyPartsPos[i].y, this->bodyPartsPos[i].z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_32C, this->unk_32C, this->unk_32C, MTXMODE_APPLY); - Matrix_InsertZRotation_f(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); + Matrix_RotateZF(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } for (i = this->unk_780; i >= this->unk_784; i--) { - Matrix_InsertTranslation(this->rightWhip.pos[i].x, this->rightWhip.pos[i].y, this->rightWhip.pos[i].z, + Matrix_Translate(this->rightWhip.pos[i].x, this->rightWhip.pos[i].y, this->rightWhip.pos[i].z, 0); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(1.5f, 1.5f, 1.5f, MTXMODE_APPLY); - Matrix_InsertZRotation_f(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); + Matrix_RotateZF(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } } if (this->unk_330 > 0.0f) { - gSPDisplayList(POLY_XLU_DISP++, D_040233B8); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb2DL); for (i = 0; i < 2 * ARRAY_COUNT(this->bodyPartsPos); i++) { - Matrix_InsertTranslation(this->bodyPartsPos[i / 2].x + randPlusMinusPoint5Scaled(30.0f), + Matrix_Translate(this->bodyPartsPos[i / 2].x + randPlusMinusPoint5Scaled(30.0f), this->bodyPartsPos[i / 2].y + randPlusMinusPoint5Scaled(30.0f), this->bodyPartsPos[i / 2].z + randPlusMinusPoint5Scaled(30.0f), MTXMODE_NEW); Matrix_Scale(this->unk_330, this->unk_330, this->unk_330, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(2.0f * M_PI)); - Matrix_InsertZRotation_f(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); + Matrix_RotateXFApply(Rand_ZeroFloat(2.0f * M_PI)); + Matrix_RotateZF(Rand_ZeroFloat(2.0f * M_PI), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } } } CLOSE_DISPS(gfxCtx); } -void Boss07_Wrath_DrawDeathLights(Boss07* this, GlobalContext* globalCtx, Vec3f* arg2) { +void Boss07_DrawDeathLights(Boss07* this, GlobalContext* globalCtx, Vec3f* arg2) { s32 i; f32 temp_f12_2; f32 temp_f20; @@ -2417,13 +2424,13 @@ void Boss07_Wrath_DrawDeathLights(Boss07* this, GlobalContext* globalCtx, Vec3f* temp = sColorsYRGB[0]; gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, temp[0], temp[1], temp[2], 40); temp_f20 = (Boss07_RandZeroOne() * 40.0f) - 30.0f; - Matrix_InsertTranslation(this->bodyPartsPos[2].x, + Matrix_Translate(this->bodyPartsPos[2].x, this->bodyPartsPos[2].y - 30.0f + 50.0f + temp_f20 + 25.0f, this->bodyPartsPos[2].z, MTXMODE_NEW); - Matrix_InsertTranslation(arg2->x, arg2->y + temp_f20, arg2->z, MTXMODE_NEW); - Matrix_InsertYRotation_f(Boss07_RandZeroOne() * M_PI * 2.0f, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(-0.024999999f * temp_f20); - Matrix_InsertZRotation_f(Boss07_RandZeroOne() * M_PI * 2.0f, MTXMODE_APPLY); + Matrix_Translate(arg2->x, arg2->y + temp_f20, arg2->z, MTXMODE_NEW); + Matrix_RotateYF(Boss07_RandZeroOne() * M_PI * 2.0f, MTXMODE_APPLY); + Matrix_RotateXFApply(-0.024999999f * temp_f20); + Matrix_RotateZF(Boss07_RandZeroOne() * M_PI * 2.0f, MTXMODE_APPLY); if (this->deathLightScale[i] > 0.0f) { Matrix_Scale(this->deathLightScale[i], 1.0f, 12.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -2431,18 +2438,18 @@ void Boss07_Wrath_DrawDeathLights(Boss07* this, GlobalContext* globalCtx, Vec3f* } } func_8012C2DC(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_XLU_DISP++, D_04023348); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, (u8)(220 + sREG(18)), (u8)(170 + sREG(16))); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, (u8)(100 + sREG(22)), 128); - Matrix_InsertTranslation(this->bodyPartsPos[2].x, this->bodyPartsPos[2].y, this->bodyPartsPos[2].z, + Matrix_Translate(this->bodyPartsPos[2].x, this->bodyPartsPos[2].y, this->bodyPartsPos[2].z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); - Matrix_InsertZRotation_s(globalCtx->gameplayFrames * 0x80, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateZS(globalCtx->gameplayFrames * 0x80, MTXMODE_APPLY); temp_f12_2 = (sREG(17) + 800) * 0.01f * this->unk_AB4C; Matrix_Scale(temp_f12_2, temp_f12_2, 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_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } CLOSE_DISPS(gfxCtx); } @@ -2461,7 +2468,7 @@ void Boss07_Static_DrawLight(Boss07* this, GlobalContext* globalCtx) { func_8012C2DC(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(sREG(52) + 255)); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 0, 0); - gSPDisplayList(POLY_XLU_DISP++, D_04023348); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); if (player->transformation == PLAYER_FORM_GORON) { sp54 = -10.0f; @@ -2473,15 +2480,15 @@ void Boss07_Static_DrawLight(Boss07* this, GlobalContext* globalCtx) { sp54 -= 43.0f; } - Matrix_InsertTranslation(player->actor.world.pos.x, - player->actor.world.pos.y + func_800B6FC8(player) - 20.0f + sp54 + sREG(60), + Matrix_Translate(player->actor.world.pos.x, + player->actor.world.pos.y + Player_GetHeight(player) - 20.0f + sp54 + sREG(60), player->actor.world.pos.z + sREG(61) - 15.0f + sp50, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_AB44, this->unk_AB44, this->unk_AB44, MTXMODE_APPLY); - Matrix_InsertZRotation_s(globalCtx->gameplayFrames * 0x40, MTXMODE_APPLY); + Matrix_RotateZS(globalCtx->gameplayFrames * 0x40, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } CLOSE_DISPS(gfxCtx); } @@ -2499,35 +2506,35 @@ void Boss07_Wrath_Draw(Actor* thisx, GlobalContext* globalCtx2) { if ((this->unk_15E % 2) != 0) { POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); } - Matrix_InsertYRotation_f(this->unk_184, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(this->unk_188); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32)this->skelAnime.dListCount, + Matrix_RotateYF(this->unk_184, MTXMODE_APPLY); + Matrix_RotateXFApply(this->unk_188); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32)this->skelAnime.dListCount, Boss07_Wrath_OverrideLimbDraw, Boss07_Wrath_PostLimbDraw, Boss07_Wrath_TransformLimbDraw, &this->actor); POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); if (((KREG(63) == 0) || (KREG(63) == 2)) && this->unk_149) { - Boss07_Wrath_UpdateWhips(this, globalCtx, &this->rightWhip.basePos, this->rightWhip.pos, this->rightWhip.rot, + Boss07_UpdateWhips(this, globalCtx, &this->rightWhip.basePos, this->rightWhip.pos, this->rightWhip.rot, this->rightWhip.pull, this->rightWhip.gravity, this->rightWhip.stiffness, this->rightWhip.drag, this->rightWhip.tension, &this->rightWhip.baseRot, this->unk_F7E, this->whipScale, 0); - Boss07_Wrath_UpdateWhips(this, globalCtx, &this->leftWhip.basePos, this->leftWhip.pos, this->leftWhip.rot, + Boss07_UpdateWhips(this, globalCtx, &this->leftWhip.basePos, this->leftWhip.pos, this->leftWhip.rot, this->leftWhip.pull, this->leftWhip.gravity, this->leftWhip.stiffness, this->leftWhip.drag, this->leftWhip.tension, &this->leftWhip.baseRot, 0, this->whipScale, 1); } - Boss07_Wrath_DrawWhips(this, globalCtx, this->rightWhip.pos, this->rightWhip.rot, this->whipScale, 0); - Boss07_Wrath_DrawWhips(this, globalCtx, this->leftWhip.pos, this->leftWhip.rot, this->whipScale, 1); + Boss07_DrawWhips(this, globalCtx, this->rightWhip.pos, this->rightWhip.rot, this->whipScale, 0); + Boss07_DrawWhips(this, globalCtx, this->leftWhip.pos, this->leftWhip.rot, this->whipScale, 1); if (this->unk_AB48 == 0) { Boss07_Wrath_MakeShadowTex(shadowTex, this, globalCtx); Boss07_Wrath_DrawShadowTex(shadowTex, this, globalCtx); } - Boss07_Wrath_DrawShocks(this, globalCtx); + Boss07_DrawShocks(this, globalCtx); sp58.x = this->bodyPartsPos[2].x; sp58.y = this->bodyPartsPos[2].y - 30.0f + 50.0f; sp58.z = this->bodyPartsPos[2].z; - Boss07_Wrath_DrawDeathLights(this, globalCtx, &sp58); - func_800BE680(globalCtx, &this->actor, this->bodyPartsPos, 0xF, this->unk_17F8, this->unk_17FC, this->unk_1800, + Boss07_DrawDeathLights(this, globalCtx, &sp58); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, 0xF, this->unk_17F8, this->unk_17FC, this->unk_1800, this->unk_1804); this->unk_149 = false; CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -2564,7 +2571,7 @@ void Boss07_Wrath_MakeShadowCircles(Boss07* this, u8* shadowTex, f32 weight) { sp74.y = this->bodyPartsPos[i].y - this->actor.world.pos.y + 76.0f + 30.0f + 30.0f + 100.0f; sp74.z = this->bodyPartsPos[i].z - this->actor.world.pos.z; } - Matrix_MultiplyVector3fByState(&sp74, &sp68); + Matrix_MultVec3f(&sp74, &sp68); sp68.x *= 0.2f; sp68.y *= 0.2f; @@ -2619,7 +2626,7 @@ void Boss07_Wrath_MakeShadowTex(u8* shadowTex, Boss07* this, GlobalContext* glob for (i = 0; i < 0x400; i++, shadowTex32++) { *shadowTex32 = 0; } - Matrix_SetStateXRotation(1.0f); + Matrix_RotateXFNew(1.0f); for (i = 0; i < 6; i++) { Boss07_Wrath_MakeShadowCircles(this, shadowTex, i / 5.0f); } @@ -2638,7 +2645,7 @@ void Boss07_Wrath_DrawShadowTex(u8* shadowTex, Boss07* this, GlobalContext* glob phi_f0 = CLAMP_MAX(phi_f0, 1.0f); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(s32)(phi_f0 * 80.0f) & 0xFF); gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z - 20.0f, + Matrix_Translate(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z - 20.0f, MTXMODE_NEW); Matrix_Scale(1.75f, 1.0f, 1.75f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -2652,8 +2659,8 @@ void Boss07_Wrath_DrawShadowTex(u8* shadowTex, Boss07* this, GlobalContext* glob void func_809FCBC8(Boss07* this) { s32 phi_v0 = (Rand_ZeroOne() < 0.5f) ? 0x4000 : -0x4000; - Matrix_RotateY(this->actor.yawTowardsPlayer + phi_v0, MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledZ(200.0f, &this->unk_164); + Matrix_RotateYS(this->actor.yawTowardsPlayer + phi_v0, MTXMODE_NEW); + Matrix_MultVecZ(200.0f, &this->unk_164); this->timers[1] = 30; this->unk_164.x += this->actor.world.pos.x; this->unk_164.z += this->actor.world.pos.z; @@ -2675,8 +2682,8 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->unk_ABC8++; - 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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); sp58 = Math_SinS(this->actionTimer * 0x4500) * 0.3f; switch (this->csState) { case 0: @@ -2696,7 +2703,7 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= 20) { if (this->unk_ABC8 == 20) { this->unk_17C8[3] = 1.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_TRANSFORM); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_TRANSFORM); } Math_ApproachF(&this->unk_17B8[3], 1.0f + (this->unk_17C8[3] * sp58), 1.0f, 0.5f); } @@ -2715,21 +2722,21 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= 20) { if (this->unk_ABC8 == 20) { this->unk_17C8[2] = 1.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_TRANSFORM); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_TRANSFORM); } Math_ApproachF(&this->unk_17B8[2], 1.0f + (this->unk_17C8[2] * sp58), 1.0f, 0.5f); } if (this->unk_ABC8 >= 50) { if (this->unk_ABC8 == 50) { this->unk_17C8[1] = 1.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_TRANSFORM); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_TRANSFORM); } Math_ApproachF(&this->unk_17B8[1], (this->unk_17C8[1] * sp58) + 1.0f, 1.0f, 0.5f); } if (this->unk_ABC8 >= 60) { if (this->unk_ABC8 == 60) { this->unk_17C8[0] = 1.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_TRANSFORM); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_TRANSFORM); } Math_ApproachF(this->unk_17B8, (this->unk_17C8[0] * sp58) + 1.0f, 1.0f, 0.5f); } @@ -2750,7 +2757,7 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= 10) { if (this->unk_ABC8 == 10) { this->unk_17C8[3] = 1.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_GROW_HEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_GROW_HEAD); } Math_ApproachS(&this->unk_17D8, this->unk_17C8[3] * sp58 * 0x6000, 1, 0x4000); } @@ -2770,24 +2777,24 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= 20) { sREG(28) = this->unk_ABC8; if ((this->unk_ABC8 == (KREG(16) + 28)) || (this->unk_ABC8 == (KREG(17) + 60))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO2_OLD); } if ((this->unk_ABC8 == (KREG(18) + 38)) || (this->unk_ABC8 == (KREG(19) + 48)) || (this->unk_ABC8 == (KREG(20) + 68)) || (this->unk_ABC8 == (KREG(21) + 78))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_GYM_B_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_GYM_B_OLD); } if (this->unk_ABC8 == (KREG(38) + 93)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_UAUOO_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_UAUOO_OLD); } } if (this->unk_ABC8 == 45) { - Actor_TitleCardCreate(globalCtx, &globalCtx->actorCtx.titleCtxt, Lib_SegmentedToVirtual(&D_06030C40), + TitleCard_InitBossName(&globalCtx->state, &globalCtx->actorCtx.titleCtxt, Lib_SegmentedToVirtual(&D_06030C40), 0xA0, 0xB4, 0x80, 0x28); } if (this->unk_ABC8 == 20) { Audio_QueueSeqCmd(0x806A); this->unk_14A = 1; - globalCtx->envCtx.unk_DC = 0.0f; + globalCtx->envCtx.lightBlend = 0.0f; } Math_ApproachF(&this->csCamNextEye.x, -80.0f, 0.05f, this->csCamSpeedMod * 80.0f); Math_ApproachF(&this->csCamNextEye.y, 20.0f, 0.05f, this->csCamSpeedMod * 60.0f); @@ -2804,7 +2811,7 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { sp54->at = this->csCamAt; func_80169AFC(globalCtx, this->csCamIndex, 0); this->csCamIndex = 0; - func_800EA0EC(globalCtx, &globalCtx->csCtx); + Cutscene_End(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 6); this->actor.flags |= 1; } @@ -2813,8 +2820,8 @@ void Boss07_Incarnation_Intro(Boss07* this, GlobalContext* globalCtx) { for (i = 0; i < ARRAY_COUNT(this->unk_17C8); i++) { Math_ApproachZeroF(&this->unk_17C8[i], 0.5f, 0.1f); } - Matrix_MultiplyVector3fByState(&this->csCamNextEye, &this->csCamEye); - Matrix_MultiplyVector3fByState(&this->csCamNextAt, &this->csCamAt); + Matrix_MultVec3f(&this->csCamNextEye, &this->csCamEye); + Matrix_MultVec3f(&this->csCamNextAt, &this->csCamAt); if (this->csCamIndex != 0) { ShrinkWindow_SetLetterboxTarget(0x1B); Play_CameraSetAtEye(globalCtx, this->csCamIndex, &this->csCamAt, &this->csCamEye); @@ -2838,16 +2845,16 @@ void Boss07_Incarnation_Taunt(Boss07* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (this->actionState < 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_WAIT_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_WAIT_OLD - SFX_FLAG); } else if ((this->actionState == 2) && Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_JUMP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_JUMP_OLD); } SkelAnime_Update(&this->skelAnime); Boss07_SmoothStop(this, 2.0f); Math_ApproachS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 5, 0x2000); if ((this->timers[0] == 0) || (player->unk_D57 == 4) || (this->actor.xzDistToPlayer <= 300.0f)) { Boss07_Incarnation_SetupRun(this, globalCtx); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); } Boss07_SpawnDust(this, globalCtx, 1, false); } @@ -2868,14 +2875,14 @@ void Boss07_Incarnation_Stunned(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); Boss07_SmoothStop(this, 1.0f); if (this->timers[1] == 1) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_HIPLOOP_LAND); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_HIPLOOP_LAND); } if (Animation_OnFrame(&this->skelAnime, this->unk_1D4)) { Animation_MorphToLoop(&this->skelAnime, &D_06009EA8, -5.0f); this->unk_1D4 = 1000.0f; } if (this->unk_1D4 == 1000.0f) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_BIRD_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_BIRD_OLD - SFX_FLAG); } if (this->timers[0] == 0) { Boss07_Incarnation_SetupTaunt(this, globalCtx); @@ -2900,7 +2907,7 @@ void Boss07_Incarnation_SetupDamaged(Boss07* this, GlobalContext* globalCtx, u8 if (this->actor.colChkInfo.health != 0) { this->actor.colChkInfo.health -= arg2; if ((s8)this->actor.colChkInfo.health <= 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_DEAD_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_DEAD_OLD); this->unk_148 = true; this->unk_15C = 100; this->unk_158 = 100; @@ -2908,11 +2915,11 @@ void Boss07_Incarnation_SetupDamaged(Boss07* this, GlobalContext* globalCtx, u8 return; } } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_DAMAGE2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_DAMAGE2_OLD); } void Boss07_Incarnation_Damaged(Boss07* this, GlobalContext* globalCtx) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_BIRD2_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_BIRD2_OLD - SFX_FLAG); SkelAnime_Update(&this->skelAnime); Boss07_SmoothStop(this, 2.0f); if (Animation_OnFrame(&this->skelAnime, this->unk_1D4)) { @@ -2933,16 +2940,16 @@ void Boss07_Incarnation_Run(Boss07* this, GlobalContext* globalCtx) { f32 sp30; s32 sp2C; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_WALK_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_WALK_OLD - SFX_FLAG); this->unk_AB40++; if (this->unk_AB40 >= 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_WALK2_OLD); this->unk_AB40 = 0; } SkelAnime_Update(&this->skelAnime); if ((func_800B64FC(globalCtx, 5.0f, &this->actor.world.pos, &sp2C) >= 0.0f) && (sp2C == 0)) { Boss07_Incarnation_SetupStunned(this, globalCtx, 50); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_DAMAGE_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_DAMAGE_OLD); } else { sp34 = this->unk_164.x - this->actor.world.pos.x; sp30 = this->unk_164.z - this->actor.world.pos.z; @@ -3020,11 +3027,11 @@ void Boss07_Incarnation_Hopak(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 5.0f)) { if ((this->unk_ABC8 % 2) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO1_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO1_OLD); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO2_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_UAUOO2_OLD); } - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST2_JUMP_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST2_JUMP_OLD); this->unk_ABC8++; } Math_ApproachF(&this->actor.speedXZ, KREG(67) + 10.0f, 1.0f, 3.0f); @@ -3045,7 +3052,7 @@ void Boss07_Incarnation_Hopak(Boss07* this, GlobalContext* globalCtx) { if ((this->timers[0] == 0) || (this->actor.xzDistToPlayer <= 200.0f)) { Boss07_Incarnation_SetupRun(this, globalCtx); if (this->timers[0] != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); } } Boss07_SpawnDust(this, globalCtx, 7, false); @@ -3059,7 +3066,7 @@ void Boss07_Incarnation_SetupMoonwalk(Boss07* this, GlobalContext* globalCtx) { } void Boss07_Incarnation_Moonwalk(Boss07* this, GlobalContext* globalCtx) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_MOONWALK_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_MOONWALK_OLD - SFX_FLAG); SkelAnime_Update(&this->skelAnime); Math_ApproachF(&this->actor.speedXZ, KREG(69) + -10.0f, 1.0f, 3.0f); if (this->timers[1] == 0) { @@ -3090,7 +3097,7 @@ void Boss07_Incarnation_SetupPirouette(Boss07* this, GlobalContext* globalCtx) { } void Boss07_Incarnation_Pirouette(Boss07* this, GlobalContext* globalCtx) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_BALLET_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_BALLET_OLD - SFX_FLAG); SkelAnime_Update(&this->skelAnime); Math_ApproachF(&this->actor.speedXZ, KREG(69) + 10.0f, 1.0f, 1.0f); if (this->timers[1] == 0) { @@ -3110,7 +3117,7 @@ void Boss07_Incarnation_Pirouette(Boss07* this, GlobalContext* globalCtx) { if ((this->timers[0] == 0) || (this->actor.xzDistToPlayer <= 200.0f)) { Boss07_Incarnation_SetupRun(this, globalCtx); if (this->timers[0] != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_VOICE_SURPRISED_OLD); } } this->actor.shape.rot.y += 0x2000; @@ -3140,11 +3147,11 @@ void Boss07_Incarnation_Death(Boss07* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCurrentIndex() != -1) { break; } - func_800EA0D4(globalCtx, &globalCtx->csCtx); + Cutscene_Start(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 7); - this->csCamIndex = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->csCamIndex, 7); + this->csCamIndex = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, 0, 1); + Play_CameraChangeStatus(globalCtx, this->csCamIndex, 7); this->unk_ABC8 = 0; this->csState = 10; func_8016566C(150); @@ -3186,7 +3193,7 @@ void Boss07_Incarnation_Death(Boss07* this, GlobalContext* globalCtx) { player->actor.world.pos.x = this->actor.world.pos.x; player->actor.world.pos.z = this->actor.world.pos.z + 300.0f; player->actor.world.rot.y = player->actor.shape.rot.y = -0x8000; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); } break; case 2: @@ -3203,7 +3210,7 @@ void Boss07_Incarnation_Death(Boss07* this, GlobalContext* globalCtx) { this->csCamNextAt.z = -20.0f; this->unk_17E8 = 1.0f; this->unk_17EC = 0.4f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); } break; case 3: @@ -3220,14 +3227,14 @@ void Boss07_Incarnation_Death(Boss07* this, GlobalContext* globalCtx) { this->csCamNextAt.z = 0.0f; this->unk_17E8 = 1.0f; this->unk_17EC = 0.4f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); } break; case 4: sHeartbeatTimer = 5; sp4B = 2; if (this->unk_ABC8 == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_PUMP_UP_OLD); } if (this->unk_ABC8 == 40) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BOSS_07, this->actor.world.pos.x, @@ -3236,10 +3243,10 @@ void Boss07_Incarnation_Death(Boss07* this, GlobalContext* globalCtx) { } break; } - 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_MultiplyVector3fByState(&this->csCamNextEye, &this->csCamEye); - Matrix_MultiplyVector3fByState(&this->csCamNextAt, &this->csCamAt); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_MultVec3f(&this->csCamNextEye, &this->csCamEye); + Matrix_MultVec3f(&this->csCamNextAt, &this->csCamAt); if (sp4B == 1) { this->unk_17E0 = (Math_SinS(this->unk_ABC8 * 0x3000) * this->unk_17EC) + this->unk_17E8; Math_ApproachF(&this->unk_17E8, 2.0f, 1.0f, 0.05f); @@ -3285,7 +3292,7 @@ void Boss07_Incarnation_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { break; case 10: this->unk_1805 = 40; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); break; case 9: this->unk_1805 = 30; @@ -3303,7 +3310,7 @@ void Boss07_Incarnation_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { } else { this->unk_15C = 15; Boss07_Incarnation_SetupStunned(this, globalCtx, 150); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_DAMAGE_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_DAMAGE_OLD); } break; } @@ -3333,9 +3340,9 @@ void Boss07_Incarnation_Update(Actor* thisx, GlobalContext* globalCtx2) { if (this->unk_14A == 1) { s32 pad; - Math_ApproachF(&globalCtx->envCtx.unk_DC, 1.0f, 1.0f, 0.1f); - if (globalCtx->envCtx.unk_DC == 1.0f) { - globalCtx->envCtx.unk_DC = 0.0f; + Math_ApproachF(&globalCtx->envCtx.lightBlend, 1.0f, 1.0f, 0.1f); + if (globalCtx->envCtx.lightBlend == 1.0f) { + globalCtx->envCtx.lightBlend = 0.0f; this->unk_14B++; if (this->unk_14B >= 8) { this->unk_14B = 0; @@ -3344,7 +3351,7 @@ void Boss07_Incarnation_Update(Actor* thisx, GlobalContext* globalCtx2) { globalCtx->envCtx.unk_C2 = D_80A08198[this->unk_14B]; globalCtx->envCtx.unk_C1 = D_80A081A0[this->unk_14B]; } - Math_ApproachF(&globalCtx->envCtx.unk_DC, 0.0f, 1.0f, 0.03f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, 0.0f, 1.0f, 0.03f); if (KREG(63) == 0) { this->unk_174 = false; this->actor.shape.shadowAlpha = 130; @@ -3358,7 +3365,7 @@ void Boss07_Incarnation_Update(Actor* thisx, GlobalContext* globalCtx2) { Math_ApproachZeroF(&this->unk_330, 1.0f, 0.04f); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 200.0f, 100.0f, 5); if (this->unk_148 || KREG(88)) { KREG(88) = false; @@ -3441,32 +3448,32 @@ void Boss07_Incarnation_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gf s8 i; if (limbIndex == 24) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } i = sLimbBodyPartIndex[limbIndex]; if (i >= 0) { - Matrix_GetStateTranslation(&this->bodyPartsPos[i]); + Matrix_MultZero(&this->bodyPartsPos[i]); } i = sLimbColliderIndex[limbIndex]; if (i >= 0) { if (this->unk_158 != 0) { - Matrix_GetStateTranslationAndScaledZ(100000.0f, &sp28); + Matrix_MultVecZ(100000.0f, &sp28); } else { - Matrix_MultiplyVector3fByState(&sIncarnationColliderOffsets[i], &sp28); + Matrix_MultVec3f(&sIncarnationColliderOffsets[i], &sp28); } Boss07_UpdateSpheres(i, &this->sph1, &sp28); } if (limbIndex == 8) { - Matrix_GetStateTranslation(&this->unk_1788[0]); + Matrix_MultZero(&this->unk_1788[0]); } if (limbIndex == 23) { - Matrix_GetStateTranslation(&this->unk_1788[1]); + Matrix_MultZero(&this->unk_1788[1]); } if (limbIndex == 13) { - Matrix_GetStateTranslation(&this->unk_17AC); + Matrix_MultZero(&this->unk_17AC); } if (limbIndex == 18) { - Matrix_GetStateTranslation(&this->unk_17A0); + Matrix_MultZero(&this->unk_17A0); } i = sLimbPumpIndex[limbIndex]; if (i >= 0) { @@ -3500,11 +3507,11 @@ void Boss07_Incarnation_Draw(Actor* thisx, GlobalContext* globalCtx2) { if ((this->unk_15E % 2) != 0) { POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); } - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, Boss07_Incarnation_OverrideLimbDraw, Boss07_Incarnation_PostLimbDraw, Boss07_Incarnation_TransformLimbDraw, &this->actor); POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); - func_800BE680(globalCtx, &this->actor, this->bodyPartsPos, 0xF, this->unk_17F8, this->unk_17FC, this->unk_1800, + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, 0xF, this->unk_17F8, this->unk_17FC, this->unk_1800, this->unk_1804); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -3526,7 +3533,7 @@ void Boss07_Mask_Idle(Boss07* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); SkelAnime_Update(&this->skelAnime); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_FLOAT_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_FLOAT_OLD - SFX_FLAG); if (this->timers[0] == 0) { if (this->timers[2] == 0) { if (((s8)this->actor.colChkInfo.health <= 8) && (player->transformation != 0) && (Rand_ZeroOne() < 0.75f)) { @@ -3581,7 +3588,7 @@ void Boss07_Mask_SetupSpin(Boss07* this, GlobalContext* globalCtx) { this->csState = 0; this->timers[0] = 30; this->unk_18D4 = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_ATTACK_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_ATTACK_OLD); } void Boss07_Mask_Spin(Boss07* this, GlobalContext* globalCtx) { @@ -3617,7 +3624,7 @@ void Boss07_Mask_Spin(Boss07* this, GlobalContext* globalCtx) { this->unk_164.y = player->actor.world.pos.y + 10.0f; this->unk_164.z = player->actor.world.pos.z; } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_ROLLING_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_ROLLING_OLD - SFX_FLAG); } sp30 = this->unk_164.x - this->actor.world.pos.x; sp2C = this->unk_164.y - this->actor.world.pos.y; @@ -3638,7 +3645,7 @@ void Boss07_Mask_Spin(Boss07* this, GlobalContext* globalCtx) { this->unk_164.y = Rand_ZeroFloat(100.0f) + 100.0f; if (Rand_ZeroOne() < 0.3f) { this->timers[1] = 20; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_ATTACK_2ND_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_ATTACK_2ND_OLD); this->csState = 1; } else { this->timers[1] = 0; @@ -3668,12 +3675,12 @@ void Boss07_Mask_SetupStunned(Boss07* this, GlobalContext* globalCtx) { void Boss07_Mask_Stunned(Boss07* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - func_8019F1C0(&sSfxPoint, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_COMMON_WEAKENED - SFX_FLAG); Boss07_SmoothStop(this, 0.5f); Math_ApproachS(&this->actor.shape.rot.x, -0x1000 + 0x4B0 * Math_SinS(this->actionTimer * 0xBB8), 5, 0x800); Math_ApproachS(&this->actor.shape.rot.z, -0x1000 + 0x3E8 * Math_SinS(this->actionTimer * 0x9C4), 5, 0x800); if (this->actor.world.pos.y > 51.0f) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_FALL_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_FALL_OLD - SFX_FLAG); } Math_ApproachF(&this->actor.world.pos.y, 50.0f + 10.0f * Math_SinS(this->actionTimer * 0x5DC), 0.1f, this->unk_170); Math_ApproachF(&this->unk_170, 15.0f, 1.0f, 1.0f); @@ -3738,8 +3745,8 @@ void Boss07_Mask_Damaged(Boss07* this, GlobalContext* globalCtx) { if ((s8)this->actor.colChkInfo.health <= 0) { this->unk_148 = true; Enemy_StartFinishingBlow(globalCtx, &this->actor); - func_801A72CC(&this->actor.projectedPos); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DEAD_OLD); + Audio_StopSfxByPos(&this->actor.projectedPos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DEAD_OLD); } else { this->unk_164.x = this->actor.world.pos.x; this->unk_164.y = 200.0f; @@ -3782,7 +3789,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { CollisionPoly* sp158; Vec3f sp14C; u8 sp14B = 0; - u32 sp144; + s32 sp144; this->unk_15C = 20; Boss07_SmoothStop(this, 0.5f); @@ -3805,7 +3812,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { switch (this->actionState) { case 0: if (this->timers[0] == 25) { - func_8019F1C0(&sSfxPoint, NA_SE_EN_LAST1_BLOW_OLD); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EN_LAST1_BLOW_OLD); } if (this->timers[0] == 0) { this->actionState = 1; @@ -3839,7 +3846,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { sp180 = sqrtf(SQ(temp_f20) + SQ(temp_f12) + SQ(temp_f22)); Math_ApproachF(&this->unk_1894, sp180 * 0.2f, 1.0f, 7.0f); - if (func_800C55C4(&globalCtx->colCtx, &this->unk_189C, &this->unk_18A8, &sp14C, &sp158, 1, 1, 1, 1, + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->unk_189C, &this->unk_18A8, &sp14C, &sp158, 1, 1, 1, 1, &sp144) && (this->actionState != 5)) { Vec3f sp138; @@ -3861,9 +3868,9 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { sp16C.x = player->actor.world.pos.x - this->unk_189C.x; sp16C.y = player->actor.world.pos.y - this->unk_189C.y + 10.0f; sp16C.z = player->actor.world.pos.z - this->unk_189C.z; - Matrix_InsertXRotation_s(-this->actor.shape.rot.x, MTXMODE_NEW); - Matrix_RotateY(-this->actor.shape.rot.y, MTXMODE_APPLY); - Matrix_MultiplyVector3fByState(&sp16C, &sp160); + Matrix_RotateXS(-this->actor.shape.rot.x, MTXMODE_NEW); + Matrix_RotateYS(-this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_MultVec3f(&sp16C, &sp160); if ((fabsf(sp160.x) < 20.0f) && (fabsf(sp160.y) < 50.0f) && (sp160.z > 40.0f) && (sp160.z <= (this->unk_1894 * 20))) { if (func_8012405C(globalCtx) && (player->transformation == PLAYER_FORM_HUMAN) && @@ -3873,7 +3880,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { this->unk_1894 = sp180 * 0.05f; Math_ApproachF(&this->unk_18C0, sp180 * 0.2f, 1.0f, 7.0f); - func_8018219C(&player->shieldMf, &sp118, 0); + Matrix_MtxFToYXZRot(&player->shieldMf, &sp118, 0); sp118.y += 0x8000; sp118.x = -sp118.x; if (this->actionState == 3) { @@ -3892,10 +3899,10 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { sp16C.y = this->actor.world.pos.y - this->unk_18A8.y; sp16C.z = this->actor.world.pos.z - this->unk_18A8.z; sp180 = sqrtf(SQXYZ(sp16C)); - Matrix_InsertXRotation_s(-this->unk_18C4, MTXMODE_NEW); - Matrix_RotateY(-this->unk_18C6, MTXMODE_APPLY); - Matrix_StatePush(); - Matrix_MultiplyVector3fByState(&sp16C, &sp160); + Matrix_RotateXS(-this->unk_18C4, MTXMODE_NEW); + Matrix_RotateYS(-this->unk_18C6, MTXMODE_APPLY); + Matrix_Push(); + Matrix_MultVec3f(&sp16C, &sp160); if ((fabsf(sp160.x) < 60.0f) && (fabsf(sp160.y) < 60.0f) && (sp160.z > 40.0f) && (sp160.z <= (this->unk_18C0 * 16.666668f)) && (this->actionState != 5)) { s32 phi_s0_2; @@ -3920,8 +3927,8 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { } else { this->unk_15C = 50; this->unk_15E = 15; - func_801A72CC(&this->actor.projectedPos); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DAMAGE2_OLD); + Audio_StopSfxByPos(&this->actor.projectedPos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DAMAGE2_OLD); Boss07_Mask_SetupDamaged(this, globalCtx, 2, NULL); func_80A006D0(this); for (phi_s0_2 = 0; phi_s0_2 < 20; phi_s0_2++) { @@ -3943,7 +3950,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { } } } - Matrix_StatePop(); + Matrix_Pop(); for (sp178 = 0; sp178 < ARRAY_COUNT(sBossRemains); sp178++) { if (sBossRemains[sp178]->actionState >= 2) { continue; @@ -3952,7 +3959,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { sp16C.y = sBossRemains[sp178]->actor.world.pos.y - this->unk_18A8.y; sp16C.z = sBossRemains[sp178]->actor.world.pos.z - this->unk_18A8.z; sp180 = sqrtf(SQXYZ(sp16C)); - Matrix_MultiplyVector3fByState(&sp16C, &sp160); + Matrix_MultVec3f(&sp16C, &sp160); if ((fabsf(sp160.x) < 60.0f) && (fabsf(sp160.y) < 60.0f) && (sp160.z > 40.0f) && (sp160.z <= (this->unk_18C0 * 16.666668f)) && (this->actionState != 5)) { s32 pad; @@ -3978,7 +3985,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { } else { sBossRemains[sp178]->actionState = 2; sBossRemains[sp178]->unk_18D6 = 60; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FOLLOWERS_DEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FOLLOWERS_DEAD); for (pad = 0; pad < 20; pad++) { spE0.x = sBossRemains[sp178]->actor.world.pos.x + randPlusMinusPoint5Scaled(50.0f); @@ -3998,7 +4005,7 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { } } } - if (func_800C55C4(&globalCtx->colCtx, &this->unk_18A8, &this->unk_18B4, &sp14C, &sp158, 1, 1, 1, + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->unk_18A8, &this->unk_18B4, &sp14C, &sp158, 1, 1, 1, 1, &sp144) && (this->actionState != 5)) { Vec3f spBC; @@ -4027,14 +4034,14 @@ void Boss07_Mask_Beam(Boss07* this, GlobalContext* globalCtx) { player->flameTimers[pad2] = Rand_S16Offset(0, 200); } player->isBurning = true; - func_800B8E58(&player->actor, player->ageProperties->unk_92 + NA_SE_VO_LI_DEMO_DAMAGE); + func_800B8E58(player, player->ageProperties->unk_92 + NA_SE_VO_LI_DEMO_DAMAGE); } } if (sp14B) { if (sp14C.y == 0.0f) { temp_f20 = this->unk_18E0.x - sp14C.x; temp_f22 = this->unk_18E0.z - sp14C.z; - func_800AE930(&globalCtx->colCtx, Effect_GetParams(this->effectIndex), &sp14C, 15.0f, + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->effectIndex), &sp14C, 15.0f, Math_Atan2S(temp_f20, temp_f22), sp158, sp144); this->unk_18EC = 1; } @@ -4092,11 +4099,11 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { this->actor.world.pos.y = 277.0f; this->actor.world.pos.z = -922.5f; if ((player->actor.world.pos.z < 700.0f) && (ActorCutscene_GetCurrentIndex() == -1)) { - func_800EA0D4(globalCtx, &globalCtx->csCtx); + Cutscene_Start(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 7); - this->csCamIndex = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->csCamIndex, 7); + this->csCamIndex = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, 0, 1); + Play_CameraChangeStatus(globalCtx, this->csCamIndex, 7); this->unk_ABC8 = 0; this->csState = 1; this->unk_160 = KREG(76) + 150; @@ -4113,10 +4120,10 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { player->actor.shape.rot.y = -0x8000; player->actor.world.rot.y = player->actor.shape.rot.y; this->csCamEye.x = 0.0f; - this->csCamEye.y = func_800B6FC8(player) + player->actor.world.pos.y - 24.0f; + this->csCamEye.y = Player_GetHeight(player) + player->actor.world.pos.y - 24.0f; this->csCamEye.z = player->actor.world.pos.z - 60.0f; this->csCamAt.x = player->actor.world.pos.x; - this->csCamAt.y = func_800B6FC8(player) + player->actor.world.pos.y - 20.0f; + this->csCamAt.y = Player_GetHeight(player) + player->actor.world.pos.y - 20.0f; this->csCamAt.z = player->actor.world.pos.z; if (player->transformation == PLAYER_FORM_FIERCE_DEITY) { this->csCamAt.y -= 30.0f; @@ -4200,7 +4207,7 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { } if (this->unk_ABC8 >= 55) { if (this->unk_ABC8 == 55) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_PAMET_BREAK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_B_PAMET_BREAK); } this->unk_1884 = 0; } @@ -4211,7 +4218,7 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { Vec3f sp60; if (this->unk_ABC8 == 75) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DEMO_WALL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DEMO_WALL); } sp8C = 2.0f * (this->unk_ABC8 % 2); if ((this->unk_ABC8 % 2) != 0) { @@ -4243,15 +4250,15 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { if (this->unk_ABC8 >= 10) { Math_ApproachS(&this->unk_160, KREG(72), 1, KREG(73) + 2); if (this->unk_ABC8 == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DEMO_BREAK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DEMO_BREAK); } SkelAnime_Update(&this->skelAnime); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_FLOAT_OLD - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_FLOAT_OLD - SFX_FLAG); Math_ApproachF(&this->unk_1870, 1.0f, 1.0f, 0.02f); Math_ApproachF(&this->actor.world.pos.z, -642.5f, 0.05f, 30.0f); Math_ApproachF(&this->actor.world.pos.y, 350.0f, 0.03f, 2.0f); if (this->unk_ABC8 == 55) { - Actor_TitleCardCreate(globalCtx, &globalCtx->actorCtx.titleCtxt, + TitleCard_InitBossName(&globalCtx->state, &globalCtx->actorCtx.titleCtxt, Lib_SegmentedToVirtual(&D_0602F840), 0xA0, 0xB4, 0x80, 0x28); } if (this->unk_ABC8 == 30) { @@ -4283,7 +4290,7 @@ void Boss07_Mask_Intro(Boss07* this, GlobalContext* globalCtx) { sp5C->at = this->csCamAt; func_80169AFC(globalCtx, this->csCamIndex, 0); this->csCamIndex = 0; - func_800EA0EC(globalCtx, &globalCtx->csCtx); + Cutscene_End(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 6); this->actor.flags |= 1; gSaveContext.eventInf[6] |= 2; @@ -4334,16 +4341,16 @@ void Boss07_Mask_Death(Boss07* this, GlobalContext* globalCtx) { Math_ApproachF(&this->actor.world.pos.x, 0.0f, 0.05f, 5.0f); Math_ApproachF(&this->actor.world.pos.z, 0.0f, 0.05f, 5.0f); Math_ApproachF(&this->actor.world.pos.y, 130.0f, 0.05f, 3.0f); - 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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); switch (this->csState) { case 0: if (ActorCutscene_GetCurrentIndex() == -1) { - func_800EA0D4(globalCtx, &globalCtx->csCtx); + Cutscene_Start(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 1U); - this->csCamIndex = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->csCamIndex, 7); + this->csCamIndex = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, 0, 1); + Play_CameraChangeStatus(globalCtx, this->csCamIndex, 7); this->unk_ABC8 = 0; this->csState = 1; this->csCamNextAt.z = 0.0f; @@ -4354,8 +4361,8 @@ void Boss07_Mask_Death(Boss07* this, GlobalContext* globalCtx) { this->csCamNextEye.z = 270.0f; this->csCamNextAt.x = 0.0f; this->csCamNextAt.y = -30.0f; - Matrix_MultiplyVector3fByState(&this->csCamNextEye, &this->csCamEye); - Matrix_MultiplyVector3fByState(&this->csCamNextAt, &this->csCamAt); + Matrix_MultVec3f(&this->csCamNextEye, &this->csCamEye); + Matrix_MultVec3f(&this->csCamNextAt, &this->csCamAt); } else { break; } @@ -4386,8 +4393,8 @@ void Boss07_Mask_Death(Boss07* this, GlobalContext* globalCtx) { break; } - Matrix_MultiplyVector3fByState(&this->csCamNextEye, &this->csCamEye); - Matrix_MultiplyVector3fByState(&this->csCamNextAt, &sp60); + Matrix_MultVec3f(&this->csCamNextEye, &this->csCamEye); + Matrix_MultVec3f(&this->csCamNextAt, &sp60); Math_ApproachF(&this->csCamAt.x, sp60.x, 0.1f, 10.0f); Math_ApproachF(&this->csCamAt.y, sp60.y, 0.1f, 10.0f); Math_ApproachF(&this->csCamAt.z, sp60.z, 0.1f, 10.0f); @@ -4421,13 +4428,13 @@ void Boss07_Mask_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { damage = (hitbox->toucher.dmgFlags & 0xF7CFFFFF) ? this->actor.colChkInfo.damage : 0; this->unk_15C = 50; this->unk_15E = 15; - func_801A72CC(&this->actor.projectedPos); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DAMAGE2_OLD); + Audio_StopSfxByPos(&this->actor.projectedPos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DAMAGE2_OLD); Boss07_Mask_SetupDamaged(this, globalCtx, damage, hitActor); } else { this->unk_15C = 15; - func_801A72CC(&this->actor.projectedPos); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DAMAGE1_OLD); + Audio_StopSfxByPos(&this->actor.projectedPos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DAMAGE1_OLD); Boss07_Mask_SetupStunned(this, globalCtx); } } @@ -4458,7 +4465,7 @@ void Boss07_Mask_Update(Actor* thisx, GlobalContext* globalCtx2) { this->unk_149 = true; globalCtx->envCtx.unk_C1 = 2; globalCtx->envCtx.unk_C2 = 0; - Math_ApproachF(&globalCtx->envCtx.unk_DC, this->unk_1898, 1.0f, 0.1f); + Math_ApproachF(&globalCtx->envCtx.lightBlend, this->unk_1898, 1.0f, 0.1f); this->actionTimer++; if (KREG(63) == 0) { this->unk_174 = false; @@ -4478,18 +4485,18 @@ void Boss07_Mask_Update(Actor* thisx, GlobalContext* globalCtx2) { this->unk_18EC = 0; this->actionFunc(this, globalCtx); if ((this->unk_18EC == 0) && (this->unk_18ED != 0)) { - func_800AEF44(Effect_GetParams(this->effectIndex)); + func_800AEF44(Effect_GetByIndex(this->effectIndex)); } this->unk_18ED = this->unk_18EC; if (this->actionFunc != Boss07_Mask_Intro) { if (this->actionFunc != Boss07_Mask_Damaged) { - Actor_SetVelocityXYRotation(&this->actor); - Actor_ApplyMovement(&this->actor); + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); } else { if (this->actor.bgCheckFlags & 1) { this->actor.velocity.y = 0.0f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } if (this->unk_1888 == 0) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 60.0f, 100.0f, 5); @@ -4501,40 +4508,40 @@ void Boss07_Mask_Update(Actor* thisx, GlobalContext* globalCtx2) { this->actor.colChkInfo.health = 0; } Boss07_Mask_CollisionCheck(this, globalCtx); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + Matrix_Translate(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_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); sp6C.x = -55.0f; sp6C.y = 55.0f; sp6C.z = 10.0f; - Matrix_MultiplyVector3fByState(&sp6C, &sp9C); + Matrix_MultVec3f(&sp6C, &sp9C); sp6C.x = -55.0f; sp6C.y = -55.0f; - Matrix_MultiplyVector3fByState(&sp6C, &sp90); + Matrix_MultVec3f(&sp6C, &sp90); sp6C.x = 55.0f; sp6C.y = 55.0f; - Matrix_MultiplyVector3fByState(&sp6C, &sp84); + Matrix_MultVec3f(&sp6C, &sp84); sp6C.x = 55.0f; sp6C.y = -55.0f; - Matrix_MultiplyVector3fByState(&sp6C, &sp78); + Matrix_MultVec3f(&sp6C, &sp78); Collider_SetQuadVertices(&this->quad1, &sp9C, &sp90, &sp84, &sp78); sp68 = (player->stateFlags3 & 0x200) ? 70.0f : 40.0f; sp6C.x = -sp68; sp6C.y = sp68; sp6C.z = -10.0f; - Matrix_MultiplyVector3fByState(&sp6C, &sp9C); + Matrix_MultVec3f(&sp6C, &sp9C); sp6C.x = -sp68; sp6C.y = -sp68; - Matrix_MultiplyVector3fByState(&sp6C, &sp90); + Matrix_MultVec3f(&sp6C, &sp90); sp6C.x = sp68; sp6C.y = sp68; - Matrix_MultiplyVector3fByState(&sp6C, &sp84); + Matrix_MultVec3f(&sp6C, &sp84); sp6C.x = sp68; sp6C.y = -sp68; - Matrix_MultiplyVector3fByState(&sp6C, &sp78); + Matrix_MultVec3f(&sp6C, &sp78); Collider_SetQuadVertices(&this->quad2, &sp9C, &sp90, &sp84, &sp78); if (player->stateFlags3 & 0x200) { @@ -4565,7 +4572,7 @@ void Boss07_Mask_Update(Actor* thisx, GlobalContext* globalCtx2) { sp44.y = sp50.y * -0.05f; sp44.z = sp50.z * -0.05f; Boss07_SpawnEffect(globalCtx, &sp5C, &sp50, &sp44, Rand_ZeroFloat(10.0f) + 25.0f); - func_8019F1C0(&sSfxPoint, NA_SE_EV_BURN_OUT - SFX_FLAG); + Audio_PlaySfxAtPos(&sSfxPoint, NA_SE_EV_BURN_OUT - SFX_FLAG); } } } @@ -4588,16 +4595,16 @@ void Boss07_Mask_UpdateTentacles(Boss07* this, GlobalContext* globalCtx, Vec3f* if (this->unk_1874 != 0) { for (i = 0; i < MAJORA_TENT_LENGTH; i++) { - Matrix_StatePush(); - Matrix_InsertZRotation_f(arg9, MTXMODE_APPLY); + Matrix_Push(); + Matrix_RotateZF(arg9, MTXMODE_APPLY); sp98.x = Math_SinS((2 * i + this->actionTimer) * 0x1600) * 10; sp98.y = 10.0f; sp98.z = 0.0f; - Matrix_MultiplyVector3fByState(&sp98, &sp8C); + Matrix_MultVec3f(&sp98, &sp8C); pos[i].x += sp8C.x; pos[i].y += sp8C.y; pos[i].z += sp8C.z; - Matrix_StatePop(); + Matrix_Pop(); } } for (i = 0; i < MAJORA_TENT_LENGTH; i++, pull++) { @@ -4621,7 +4628,7 @@ void Boss07_Mask_UpdateTentacles(Boss07* this, GlobalContext* globalCtx, Vec3f* sp80.y = arg6->y * (MAJORA_TENT_LENGTH / 2 - i) * 0.2f; sp80.z = arg6->z * (MAJORA_TENT_LENGTH / 2 - i) * 0.2f; } else { - sp80 = D_801D15B0; + sp80 = gZeroVec3f; } temp_f24 = pos->x + pull->x - (pos - 1)->x + sp80.x; if (this->unk_1874 != 0) { @@ -4642,9 +4649,9 @@ void Boss07_Mask_UpdateTentacles(Boss07* this, GlobalContext* globalCtx, Vec3f* temp1 = -Math_Acot2F(temp2, temp_f22); (rot - 1)->y = temp_f26; (rot - 1)->x = temp1; - Matrix_InsertYRotation_f(temp_f26, MTXMODE_NEW); - Matrix_RotateStateAroundXAxis(temp1); - Matrix_GetStateTranslationAndScaledZ(sp98.z, &sp8C); + Matrix_RotateYF(temp_f26, MTXMODE_NEW); + Matrix_RotateXFApply(temp1); + Matrix_MultVecZ(sp98.z, &sp8C); temp_f24 = pos->x; temp_f22 = pos->y; temp_f20 = pos->z; @@ -4663,10 +4670,10 @@ void Boss07_Mask_DrawTentacles(Boss07* this, GlobalContext* globalCtx, Vec3f* ar OPEN_DISPS(globalCtx->state.gfxCtx); for (i = 0; i < MAJORA_TENT_LENGTH - 1; i++, arg2++, arg3++) { - Matrix_InsertTranslation(arg2->x, arg2->y, arg2->z, MTXMODE_NEW); - Matrix_InsertYRotation_f(arg3->y, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(arg3->x); - Matrix_InsertZRotation_f(arg5, MTXMODE_APPLY); + Matrix_Translate(arg2->x, arg2->y, arg2->z, MTXMODE_NEW); + Matrix_RotateYF(arg3->y, MTXMODE_APPLY); + Matrix_RotateXFApply(arg3->x); + Matrix_RotateZF(arg5, MTXMODE_APPLY); if (i <= (MAJORA_TENT_LENGTH - 1) / 2) { phi_f12 = 0.035f; } else { @@ -4689,73 +4696,73 @@ void Boss07_Mask_DrawBeam(Boss07* this, GlobalContext* globalCtx) { gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 60, 200); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 128); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + Matrix_Translate(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_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - Matrix_StatePush(); - Matrix_StatePush(); - Matrix_StatePush(); + Matrix_Push(); + Matrix_Push(); + Matrix_Push(); - Matrix_InsertTranslation(250.0f, 0.0f, 200.0f, MTXMODE_APPLY); - Matrix_RotateY(-0xA00, MTXMODE_APPLY); + Matrix_Translate(250.0f, 0.0f, 200.0f, MTXMODE_APPLY); + Matrix_RotateYS(-0xA00, MTXMODE_APPLY); Matrix_Scale(this->unk_1898 * 0.05f, this->unk_1898 * 0.05f, this->unk_188C * 0.05f, 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_0600C7D8); - Matrix_StatePop(); + Matrix_Pop(); - Matrix_InsertTranslation(-250.0f, 0.0f, 200.0f, MTXMODE_APPLY); - Matrix_RotateY(0xA00, MTXMODE_APPLY); + Matrix_Translate(-250.0f, 0.0f, 200.0f, MTXMODE_APPLY); + Matrix_RotateYS(0xA00, MTXMODE_APPLY); Matrix_Scale(this->unk_1898 * 0.05f, this->unk_1898 * 0.05f, this->unk_188C * 0.05f, 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_0600C7D8); - gSPDisplayList(POLY_XLU_DISP++, D_04023348); - Matrix_StatePop(); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + Matrix_Pop(); - Matrix_InsertTranslation(0.0f, 0.0f, 1200.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Translate(0.0f, 0.0f, 1200.0f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_1890 * 40.0f * this->unk_1898, this->unk_1890 * 40.0f * this->unk_1898, 0.0f, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->actionTimer * 0x100, MTXMODE_APPLY); + Matrix_RotateZS(this->actionTimer * 0x100, 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_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 60, sREG(89) + 80); Matrix_Scale(6.0f, 6.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertZRotation_s(0x4000, MTXMODE_APPLY); + Matrix_RotateZS(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++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 60, 200); - Matrix_StatePop(); + Matrix_Pop(); - Matrix_InsertTranslation(0.0f, 0.0f, 1150.0f, MTXMODE_APPLY); - Matrix_GetStateTranslation(&this->unk_189C); + Matrix_Translate(0.0f, 0.0f, 1150.0f, MTXMODE_APPLY); + Matrix_MultZero(&this->unk_189C); Matrix_Scale(this->unk_1898 * 0.05f, this->unk_1898 * 0.05f, (this->unk_1894 * 0.01f) - 0.01f, 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_0600C7D8); - Matrix_GetStateTranslationAndScaledZ(20100.0f, &this->unk_18A8); + Matrix_MultVecZ(20100.0f, &this->unk_18A8); if (this->unk_18C0 > 0.0f) { Vec3f sp50; - Matrix_GetStateTranslationAndScaledZ(20000.0f, &sp50); - Matrix_InsertTranslation(this->unk_18A8.x, this->unk_18A8.y, this->unk_18A8.z, MTXMODE_NEW); - Matrix_RotateY(this->unk_18C6, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_18C4, MTXMODE_APPLY); + Matrix_MultVecZ(20000.0f, &sp50); + Matrix_Translate(this->unk_18A8.x, this->unk_18A8.y, this->unk_18A8.z, MTXMODE_NEW); + Matrix_RotateYS(this->unk_18C6, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_18C4, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); Matrix_Scale(this->unk_1898 * 0.05f, this->unk_1898 * 0.05f, this->unk_18C0 * 0.01f, 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_0600C7D8); - Matrix_GetStateTranslationAndScaledZ(20100.0f, &this->unk_18B4); - Matrix_InsertTranslation(sp50.x, sp50.y, sp50.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_MultVecZ(20100.0f, &this->unk_18B4); + Matrix_Translate(sp50.x, sp50.y, sp50.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(this->unk_1898 * 5.0f, this->unk_1898 * 5.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->actionTimer * 0x100, MTXMODE_APPLY); + Matrix_RotateZS(this->actionTimer * 0x100, 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_04023348); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -4765,7 +4772,7 @@ void Boss07_Mask_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi Boss07* this = THIS; if (limbIndex == 2) { - Matrix_GetStateTranslationAndScaledX(500.0f, &this->unk_1878); + Matrix_MultVecX(500.0f, &this->unk_1878); } } @@ -4789,8 +4796,8 @@ void Boss07_Mask_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); temp_f20 = this->unk_186C * (M_PI / 4.0f) * 0.06666667f; temp_f22 = Math_SinS(this->unk_186C * 0x3500) * temp_f20 * 0.5f; - Matrix_InsertYRotation_f(Math_SinS(this->unk_186C * 0x4500) * temp_f20, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(temp_f22); + Matrix_RotateYF(Math_SinS(this->unk_186C * 0x4500) * temp_f20, MTXMODE_APPLY); + Matrix_RotateXFApply(temp_f22); if ((this->unk_15E % 2) != 0) { POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); } @@ -4806,25 +4813,25 @@ void Boss07_Mask_Draw(Actor* thisx, GlobalContext* globalCtx2) { ? 1 : 0; - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); - Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); - Matrix_GetStateTranslationAndScaledZ(-3.0f, &sp90); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecZ(-3.0f, &sp90); spA8.x = 0.0f; spA8.y = 20.0f; spA8.z = -2.0f; phi_f24 = 0.0f; for (i = 0; i < MAJORA_TENT_COUNT; i++) { - Matrix_StatePush(); - Matrix_StatePush(); - Matrix_InsertZRotation_f(phi_f24, MTXMODE_APPLY); - Matrix_MultiplyVector3fByState(&spA8, &sp9C); + Matrix_Push(); + Matrix_Push(); + Matrix_RotateZF(phi_f24, MTXMODE_APPLY); + Matrix_MultVec3f(&spA8, &sp9C); this->tentacles[i].base.x = this->unk_1878.x + sp9C.x; this->tentacles[i].base.y = this->unk_1878.y + sp9C.y; this->tentacles[i].base.z = this->unk_1878.z + sp9C.z; pad2 = (1 - (i * 0.008f)) * this->unk_1870; - Matrix_StatePop(); + Matrix_Pop(); if (this->unk_149) { Boss07_Mask_UpdateTentacles(this, globalCtx, &this->tentacles[i].base, this->tentacles[i].pos, this->tentacles[i].rot, this->tentacles[i].pull, &sp90, pad2, phi_s6, phi_f24); @@ -4833,7 +4840,7 @@ void Boss07_Mask_Draw(Actor* thisx, GlobalContext* globalCtx2) { phi_f24 += 0.5f; spA8.y += 1.0f; - Matrix_StatePop(); + Matrix_Pop(); } Boss07_Mask_DrawBeam(this, globalCtx); this->unk_149 = false; @@ -4852,7 +4859,7 @@ void Boss07_Projectile_Update(Actor* thisx, GlobalContext* globalCtx2) { this->actionTimer++; if (this->actor.params == MAJORA_REMAINS_SHOT) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FOLLOWERS_BEAM - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FOLLOWERS_BEAM - SFX_FLAG); } if (KREG(63) == 0) { Actor_SetScale(&this->actor, 3.5f); @@ -4868,14 +4875,14 @@ void Boss07_Projectile_Update(Actor* thisx, GlobalContext* globalCtx2) { this->actor.speedXZ = 30.0f; func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_ENEMY); if (this->actor.params == MAJORA_INCARNATION_SHOT) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST2_FIRE_OLD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST2_FIRE_OLD); } } for (i = 0; i < 3; i++) { DECR(this->timers[i]); } - Actor_SetVelocityXYRotation(&this->actor); - Actor_ApplyMovement(&this->actor); + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 31.0f, 100.0f, 7); this->actor.shape.rot.z += 0x1200; if ((this->actor.bgCheckFlags & 0x19) || (this->cyl2.base.atFlags & 2) || (this->cyl2.base.atFlags & 2) || @@ -4902,13 +4909,13 @@ void Boss07_Projectile_Draw(Actor* thisx, GlobalContext* globalCtx2) { sColorsWhite[this->unk_181C][2], 255); gDPSetEnvColor(POLY_XLU_DISP++, sColorsYRGB[this->unk_181C][0], sColorsYRGB[this->unk_181C][1], sColorsYRGB[this->unk_181C][2], 128); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, 0.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); - Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateZS(this->actor.shape.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++, D_04023348); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -4932,14 +4939,14 @@ void Boss07_Remains_CollisionCheck(Boss07* this, GlobalContext* globalCtx) { this->actionState = 2; this->unk_18DA = 1; Enemy_StartFinishingBlow(globalCtx, &this->actor); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FOLLOWERS_DEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FOLLOWERS_DEAD); } else { this->actionState = 0xA; this->timers[0] = 0xF; Boss07_Remains_DamageSfx(this); } - Matrix_RotateY(this->actor.yawTowardsPlayer, MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledZ(-20.0f, &sp2C); + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + Matrix_MultVecZ(-20.0f, &sp2C); this->unk_18CC = sp2C.x; this->unk_18D0 = sp2C.z; } @@ -5015,8 +5022,8 @@ void Boss07_Remains_Intro(Boss07* this, GlobalContext* globalCtx) { Math_ApproachS(&this->actor.world.rot.x, sp32, 5, this->unk_170); Math_ApproachF(&this->unk_170, sp40, 1.0f, sp3C); Math_ApproachF(&this->actor.speedXZ, sp38, 1.0f, sp34); - Actor_SetVelocityXYRotation(&this->actor); - Actor_ApplyMovement(&this->actor); + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); this->actor.shape.rot = this->actor.world.rot; break; case 2: @@ -5032,7 +5039,7 @@ void Boss07_Remains_Intro(Boss07* this, GlobalContext* globalCtx) { case 3: this->unk_ABCC++; if (this->unk_ABCC == 10) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FOLLOWERS_STAY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FOLLOWERS_STAY); } Actor_SetScale(&this->actor, 0.03f); Math_ApproachF(&this->actor.world.pos.x, sRemainsEnd[this->actor.params - MAJORA_REMAINS].x, 0.5f, 40.0f); @@ -5044,7 +5051,7 @@ void Boss07_Remains_Intro(Boss07* this, GlobalContext* globalCtx) { void Boss07_Remains_SetupFly(Boss07* this, GlobalContext* globalCtx) { this->actionFunc = Boss07_Remains_Fly; this->actor.gravity = -0.75f; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 40.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 40.0f); Collider_InitAndSetCylinder(globalCtx, &this->cyl2, &this->actor, &sRemainsCylInit); this->actor.colChkInfo.health = 5; this->actionState = 0; @@ -5063,21 +5070,21 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { switch (this->actionState) { case 20: - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MUJURA_FOLLOWERS_FLY - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MUJURA_FOLLOWERS_FLY - SFX_FLAG); this->timers[0] = 80; this->timers[2] = 100.0f + Rand_ZeroFloat(100.0f); this->unk_18C = 5.0f; this->actor.speedXZ = 5.0f; - this->unk_164 = D_801D15B0; + this->unk_164 = gZeroVec3f; this->actor.world.rot.y = Math_Atan2S(-this->actor.world.pos.x, -this->actor.world.pos.z); this->actionState = 1; this->unk_1888 = 100; this->cyl2.base.colType = 3; this->actor.flags |= 0x201; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LAST1_DEMO_BREAK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_DEMO_BREAK); break; case 1: - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MUJURA_FOLLOWERS_FLY - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MUJURA_FOLLOWERS_FLY - SFX_FLAG); if (this->timers[2] == 0) { this->unk_18DB = 1; this->timers[2] = Rand_ZeroFloat(200.0f) + 100.0f; @@ -5104,13 +5111,13 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { Math_ApproachS(&this->actor.world.rot.x, sp7E, 5, this->unk_170); Math_ApproachF(&this->unk_170, 2000.0f, 1.0f, 100.0f); Math_ApproachF(&this->actor.speedXZ, this->unk_18C, 1.0f, 1.0f); - if ((this->unk_18C < 8.0f) && (func_801690CC(globalCtx) == 0)) { + if ((this->unk_18C < 8.0f) && (Play_InCsMode(globalCtx) == 0)) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); } else { Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 0xA, 0x1000); } - Actor_SetVelocityXYRotation(&this->actor); - Actor_ApplyMovement(&this->actor); + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); if (this->unk_1888 == 0) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 100.0f, 100.0f, 5); } else { @@ -5120,7 +5127,7 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { break; case 2: Math_ApproachS(&this->actor.shape.rot.x, -0x4000, 1, 0x500); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 100.0f, 100.0f, 5); if (this->actor.bgCheckFlags & 1) { if (this->unk_18DA != 0) { @@ -5138,7 +5145,7 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { } break; case 10: - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); this->actor.world.pos.y -= 50.0f; this->actor.prevPos.y -= 50.0f; Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 35.0f, 60.0f, 60.0f, 5); @@ -5170,8 +5177,8 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { sp48.x = sp48.z = 0.0f; sp48.y = 0.03f; sp60.y = Rand_ZeroFloat(10.0f) + this->actor.world.pos.y; - EffectSsKFire_Spawn(globalCtx, &sp60, &D_801D15B0, &sp48, Rand_ZeroFloat(30.0f) + 30.0f, 0); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + EffectSsKFire_Spawn(globalCtx, &sp60, &gZeroVec3f, &sp48, Rand_ZeroFloat(30.0f) + 30.0f, 0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); } else { sp60.y = (Rand_ZeroFloat(30.0f) + this->actor.world.pos.y) - 15.0f; sp54.x = 0.0f; @@ -5181,7 +5188,7 @@ void Boss07_Remains_Fly(Boss07* this, GlobalContext* globalCtx) { sp48.y = sp54.y * -0.05f; sp48.z = sp54.z * -0.05f; Boss07_SpawnEffect(globalCtx, &sp60, &sp54, &sp48, Rand_ZeroFloat(10.0f) + 25.0f); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_BURN_OUT - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BURN_OUT - SFX_FLAG); } } } @@ -5237,8 +5244,8 @@ void Boss07_Remains_Draw(Actor* thisx, GlobalContext* globalCtx2) { } sp64 = this->unk_15C * (M_PI / 4.0f) * 0.06666667f; sp60 = Math_SinS(this->unk_15C * 0x3500) * sp64 * 0.5f; - Matrix_InsertYRotation_f(Math_SinS(this->unk_15C * 0x4500) * sp64, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(sp60); + Matrix_RotateYF(Math_SinS(this->unk_15C * 0x4500) * sp64, MTXMODE_APPLY); + Matrix_RotateXFApply(sp60); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); switch (this->actor.params) { case MAJORA_REMAINS + REMAINS_ODOLWA: @@ -5260,14 +5267,14 @@ void Boss07_Remains_Draw(Actor* thisx, GlobalContext* globalCtx2) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, 200); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 100, 128); - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); Matrix_Scale(this->unk_188C, this->unk_188C, 0.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); - Matrix_InsertZRotation_s(this->unk_18C8, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateZS(this->unk_18C8, 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_04023348); - gSPDisplayList(POLY_XLU_DISP++, D_04023428); + gSPDisplayList(POLY_XLU_DISP++, gLightOrb1DL); + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); } CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -5291,7 +5298,7 @@ void Boss07_Top_Thrown(Boss07* this, GlobalContext* globalCtx) { Boss07_Top_SetupGround(this, globalCtx); this->actor.speedXZ = -15.0f; CollisionCheck_SpawnShieldParticles(globalCtx, &this->actor.focus.pos); - Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); } } @@ -5316,7 +5323,7 @@ void Boss07_Top_Ground(Boss07* this, GlobalContext* globalCtx) { f32 sp48; func_8019FAD8(&this->actor.projectedPos, NA_SE_EN_LAST3_KOMA_OLD - SFX_FLAG, this->unk_17C * 1.1111112f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); this->actor.world.pos.x += this->unk_18CC; this->actor.world.pos.z += this->unk_18D0; Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 40.0f, 80.0f, 5); @@ -5329,7 +5336,7 @@ void Boss07_Top_Ground(Boss07* this, GlobalContext* globalCtx) { this->actor.speedXZ = -10.0f; } CollisionCheck_SpawnShieldParticles(globalCtx, &this->actor.focus.pos); - Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); } } if (this->actor.bgCheckFlags & 1) { @@ -5360,7 +5367,7 @@ void Boss07_Top_Ground(Boss07* this, GlobalContext* globalCtx) { Math_ApproachZeroF(&this->unk_18D0, 1.0f, 1.0f); if (this->actor.velocity.y < (sREG(40) + -2.0f)) { this->actor.velocity.y *= -(0.5f + (sREG(41) * 0.01f)); - Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); CollisionCheck_SpawnShieldParticles(globalCtx, &this->actor.world.pos); this->actor.speedXZ *= 0.5f + (sREG(57) * 0.01f); } else { @@ -5368,12 +5375,12 @@ void Boss07_Top_Ground(Boss07* this, GlobalContext* globalCtx) { } sp4C = this->actor.prevPos.x - this->actor.world.pos.x; sp48 = this->actor.prevPos.z - this->actor.world.pos.z; - func_800AE930(&globalCtx->colCtx, Effect_GetParams(this->effectIndex), &this->actor.world.pos, 3.0f, + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->effectIndex), &this->actor.world.pos, 3.0f, Math_Atan2S(sp4C, sp48), this->actor.floorPoly, this->actor.floorBgId); this->actionState = 1; } else if (this->actionState != 0) { this->actionState = 0; - func_800AEF44(Effect_GetParams(this->effectIndex)); + func_800AEF44(Effect_GetByIndex(this->effectIndex)); } this->actor.shape.rot.y = this->actor.world.rot.y; if (this->timers[1] == 0) { @@ -5398,7 +5405,7 @@ void Boss07_Top_Collide(Boss07* this, GlobalContext* globalCtx) { f32 dz; if (this->unk_158 == 0) { - top = (Boss07*)globalCtx->actorCtx.actorList[ACTORCAT_BOSS].first; + top = (Boss07*)globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; while (top != NULL) { if ((this != top) && (top->actor.params == MAJORA_TOP) && (top->unk_158 == 0)) { @@ -5440,7 +5447,7 @@ void Boss07_Top_Collide(Boss07* this, GlobalContext* globalCtx) { DECR(top->timers[1]); } } - Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); break; } } @@ -5544,10 +5551,10 @@ void Boss07_Top_Draw(Actor* thisx, GlobalContext* globalCtx2) { if ((this->unk_15E % 2) != 0) { POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 780, 1099); } - 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_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); - Matrix_InsertYRotation_f(this->unk_178, MTXMODE_APPLY); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateYF(this->unk_178, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.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_0602F640); @@ -5586,11 +5593,11 @@ void Boss07_Static_Update(Actor* thisx, GlobalContext* globalCtx2) { break; case 1: if (ActorCutscene_GetCurrentIndex() == -1) { - func_800EA0D4(globalCtx, &globalCtx->csCtx); + Cutscene_Start(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 7); - this->csCamIndex = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->csCamIndex, 7); + this->csCamIndex = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, 0, 1); + Play_CameraChangeStatus(globalCtx, this->csCamIndex, 7); this->unk_ABC8 = 0; this->csState = 2; func_8016566C(150); @@ -5656,7 +5663,7 @@ void Boss07_Static_Update(Actor* thisx, GlobalContext* globalCtx2) { this->csCamAt.y = sBossRemains[REMAINS_TWINMOLD]->actor.world.pos.y; this->csCamAt.z = sBossRemains[REMAINS_TWINMOLD]->actor.world.pos.z; if (this->unk_ABC8 == 40) { - Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM); + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); s32 i; this->csState = 6; @@ -5666,7 +5673,7 @@ void Boss07_Static_Update(Actor* thisx, GlobalContext* globalCtx2) { camera->at = this->csCamAt; func_80169AFC(globalCtx, this->csCamIndex, 0); this->csCamIndex = 0; - func_800EA0EC(globalCtx, &globalCtx->csCtx); + Cutscene_End(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 6); func_80165690(); for (i = 0; i < ARRAY_COUNT(sBossRemains); i++) { @@ -5753,8 +5760,8 @@ void Boss07_Static_DrawEffects(GlobalContext* globalCtx) { gSPSegment(POLY_XLU_DISP++, 8, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (3 * effect->scroll) % 0x80U, (15 * -effect->scroll) % 0x100U, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); - Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34, effect->unk_34, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_0600CEE8); diff --git a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c index 447c6c568..d8ebaf7eb 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.c @@ -1,6 +1,12 @@ +/* + * File: z_boss_hakugin.c + * Overlay: ovl_Boss_Hakugin + * Description: Goht + */ + #include "z_boss_hakugin.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((BossHakugin*)thisx) 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 4f5686aea..3b5882692 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h @@ -7,11 +7,22 @@ struct BossHakugin; typedef void (*BossHakuginActionFunc)(struct BossHakugin*, GlobalContext*); +typedef struct BossHakuginParticle { + /* 0x00 */ Vec3f unk_0; + /* 0x0C */ Vec3f unk_C; + /* 0x18 */ s16 unk_18; + /* 0x1A */ s16 unk_1A; + /* 0x1C */ Vec3s unk_1C; + /* 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[0x3684]; + /* 0x018C */ char unk_018C[0x86C]; + /* 0x09F8 */ BossHakuginParticle unk_9F8[180]; + /* 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 53bf05fd2..48ef3cd3d 100644 --- a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -1,6 +1,14 @@ -#include "z_demo_effect.h" +/* + * File: z_demo_effect.c + * Overlay: ovl_Demo_Effect + * Description: Various cutscene effects (blue warp in, Great Fairy vanish, etc.) + */ -#define FLAGS 0x00000030 +#include "z_demo_effect.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_efc_tw/object_efc_tw.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoEffect*)thisx) @@ -9,11 +17,14 @@ void DemoEffect_Destroy(Actor* thisx, GlobalContext* globalCtx); void DemoEffect_Update(Actor* thisx, GlobalContext* globalCtx); void func_808CD940(DemoEffect* this, GlobalContext* globalCtx); +void func_808CD998(DemoEffect* this, GlobalContext* globalCtx); void func_808CDBDC(DemoEffect* this, GlobalContext* globalCtx); void func_808CDCEC(DemoEffect* this, GlobalContext* globalCtx); void func_808CDD70(DemoEffect* this, GlobalContext* globalCtx); +void func_808CDDE0(DemoEffect* this, GlobalContext* globalCtx); +void func_808CDFF8(Actor* thisx, GlobalContext* globalCtx); +void func_808CE078(Actor* thisx, GlobalContext* globalCtx2); -#if 0 const ActorInit Demo_Effect_InitVars = { ACTOR_DEMO_EFFECT, ACTORCAT_BG, @@ -26,33 +37,287 @@ const ActorInit Demo_Effect_InitVars = { (ActorFunc)NULL, }; -#endif +void DemoEffect_Init(Actor* thisx, GlobalContext* globalCtx) { + static s16 D_808CE2C0[] = { + OBJECT_EFC_TW, OBJECT_EFC_TW, OBJECT_EFC_TW, OBJECT_EFC_TW, GAMEPLAY_KEEP, + GAMEPLAY_KEEP, GAMEPLAY_KEEP, GAMEPLAY_KEEP, GAMEPLAY_KEEP, + }; + s32 pad; + DemoEffect* this = THIS; + s32 sp3C = DEMOEFFECT_GET_FF(&this->actor); + s32 phi_v1; + s32 pad2; + Color_RGB8 sp24[] = { + { 200, 200, 0 }, { 255, 40, 100 }, { 50, 255, 0 }, { 0, 0, 255 }, { 255, 255, 80 }, + }; -extern UNK_TYPE D_06000050; -extern UNK_TYPE D_06000060; + if (D_808CE2C0[sp3C] == 1) { + phi_v1 = 0; + } else { + phi_v1 = Object_GetIndex(&globalCtx->objectCtx, D_808CE2C0[sp3C]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/DemoEffect_Init.s") + if (phi_v1 >= 0) { + this->unk_164 = phi_v1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/DemoEffect_Destroy.s") + Actor_SetScale(&this->actor, 0.2f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CD940.s") + switch (sp3C) { + case 0: + case 1: + this->actor.flags |= ACTOR_FLAG_2000000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CD998.s") + case 2: + case 3: + this->unk_174 = func_808CDFF8; + this->unk_170 = func_808CD998; + this->unk_168[0] = 0; + this->unk_168[1] = 100; + this->unk_168[2] = 255; + SkelCurve_Clear(&this->skelCurve); + this->unk_16C = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDAD0.s") + case 4: + case 5: + case 6: + case 7: + case 8: + this->unk_168[0] = sp24[sp3C - 4].r; + this->unk_168[1] = sp24[sp3C - 4].g; + this->unk_168[2] = sp24[sp3C - 4].b; + Actor_SetScale(&this->actor, 0.0f); + this->unk_174 = func_808CE078; + this->unk_170 = func_808CDDE0; + this->unk_16C = 0; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDBDC.s") + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + this->actionFunc = func_808CD940; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDCEC.s") +u8 D_808CE2D4[] = { + 1, 1, 2, 0, 1, 1, 2, 0, 1, 2, 0, 2, 1, 0, 1, 0, 2, 0, 2, 2, 0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDD70.s") +void DemoEffect_Destroy(Actor* thisx, GlobalContext* globalCtx) { + DemoEffect* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDDE0.s") + switch (DEMOEFFECT_GET_FF(&this->actor)) { + case 0: + case 1: + case 2: + case 3: + SkelCurve_Destroy(globalCtx, &this->skelCurve); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/DemoEffect_Update.s") +void func_808CD940(DemoEffect* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_164)) { + this->actor.objBankIndex = this->unk_164; + this->actor.draw = this->unk_174; + this->actionFunc = this->unk_170; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDE78.s") +void func_808CD998(DemoEffect* this, GlobalContext* globalCtx) { + s32 sp34 = DEMOEFFECT_GET_FF(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CDFF8.s") + if (SkelCurve_Init(globalCtx, &this->skelCurve, &object_efc_tw_Skel_0012E8, &object_efc_tw_CurveAnim_000050)) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Effect/func_808CE078.s") + SkelCurve_SetAnim(&this->skelCurve, &object_efc_tw_CurveAnim_000050, 1.0f, 59.0f, 1.0f, 1.7f); + SkelCurve_Update(globalCtx, &this->skelCurve); + this->actionFunc = func_808CDCEC; + + switch (sp34) { + case 0: + Actor_SetScale(&this->actor, 0.16800001f); + break; + + case 1: + Actor_SetScale(&this->actor, 0.08400001f); + break; + + case 2: + Actor_SetScale(&this->actor, 0.16800001f); + break; + + case 3: + Actor_SetScale(&this->actor, 0.28f); + break; + + default: + Actor_SetScale(&this->actor, 0.014f); + break; + } +} + +void func_808CDAD0(f32 arg0) { + s32 i; + Vtx* temp_v0 = Lib_SegmentedToVirtual(object_efc_tw_Vtx_000060); + u8 sp24[3]; + + sp24[0] = 0; + sp24[1] = (s8)(202.0f * arg0); + sp24[2] = (s8)(255.0f * arg0); + + for (i = 0; i < ARRAY_COUNT(D_808CE2D4); i++) { + if (D_808CE2D4[i] != 0) { + temp_v0[i].v.cn[3] = sp24[D_808CE2D4[i]]; + } + } +} + +void func_808CDBDC(DemoEffect* this, GlobalContext* globalCtx) { + s32 params = DEMOEFFECT_GET_FF(&this->actor); + f32 temp_f0; + f32 temp_f12; + + this->unk_16C++; + if (this->unk_16C <= 100) { + temp_f12 = (100 - this->unk_16C) * 0.01f; + temp_f0 = temp_f12 * 0.14f; + + switch (params) { + case 0: + temp_f0 *= 1.2f; + break; + + case 1: + temp_f0 *= 0.6f; + break; + + case 2: + temp_f0 *= 1.2f; + break; + + case 3: + temp_f0 *= 2.0f; + break; + } + + this->actor.scale.x = temp_f0; + this->actor.scale.z = temp_f0; + func_808CDAD0(temp_f12); + func_800B8FE8(&this->actor, NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); + } else { + func_808CDAD0(1.0f); + Actor_MarkForDeath(&this->actor); + } +} + +void func_808CDCEC(DemoEffect* this, GlobalContext* globalCtx) { + func_800B8FE8(&this->actor, NA_SE_EV_TIMETRIP_LIGHT - SFX_FLAG); + + if (SkelCurve_Update(globalCtx, &this->skelCurve)) { + SkelCurve_SetAnim(&this->skelCurve, &object_efc_tw_CurveAnim_000050, 1.0f, 60.0f, 59.0f, 0.0f); + this->actionFunc = func_808CDBDC; + this->unk_16C = 0; + } +} + +void func_808CDD70(DemoEffect* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->actor, this->actor.scale.x - 0.02f); + + this->unk_16C++; + if (this->actor.scale.x < 0.02f) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_808CDDE0(DemoEffect* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->actor, (this->actor.scale.x * 0.5f) + 0.2f); + + this->unk_16C++; + if (this->unk_16C >= 3) { + this->actionFunc = func_808CDD70; + } +} + +void DemoEffect_Update(Actor* thisx, GlobalContext* globalCtx) { + DemoEffect* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 func_808CDE78(GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, Actor* thisx) { + s32 pad; + DemoEffect* this = THIS; + u32 sp4C = globalCtx->gameplayFrames; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, this->unk_168[0], this->unk_168[1], this->unk_168[2], 255); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (sp4C * 6) % 1024, 255 - ((sp4C * 16) % 256), 0x100, 0x40, + 1, (sp4C * 4) % 512, 127 - ((sp4C * 12) % 128), 0x80, 0x20)); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (limbIndex == 0) { + LimbTransform* transform = skelCuve->transforms; + + transform->scale.x = 0x400; + transform->scale.y = 0x400; + transform->scale.z = transform->scale.x; + } + + return true; +} + +void func_808CDFF8(Actor* thisx, GlobalContext* globalCtx) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + DemoEffect* this = THIS; + + OPEN_DISPS(gfxCtx); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 25); + + Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY); + SkelCurve_Draw(&this->actor, globalCtx, &this->skelCurve, func_808CDE78, NULL, 1, &this->actor); + + CLOSE_DISPS(gfxCtx); +} + +void func_808CE078(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DemoEffect* this = THIS; + s16 sp46 = (this->unk_16C * 0x400) & 0xFFFF; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, this->unk_168[0], this->unk_168[1], this->unk_168[2], 255); + + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_Push(); + Matrix_RotateZS(sp46, 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_023288); + + Matrix_Pop(); + Matrix_RotateZS(sp46 * -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++, gameplay_keep_DL_023288); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + D_801F4E32 = 1; + D_801F4E38.x = thisx->world.pos.x; + D_801F4E38.y = thisx->world.pos.y; + D_801F4E38.z = thisx->world.pos.z; + + D_801F4E44 = thisx->scale.x * 60.0f; + D_801F4E48 = thisx->scale.x * 50.0f; + D_801F4E4C = thisx->scale.x * 250.0f; +} diff --git a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.h b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.h index 1943f4387..8216708c5 100644 --- a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.h +++ b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.h @@ -6,10 +6,20 @@ struct DemoEffect; typedef void (*DemoEffectActionFunc)(struct DemoEffect*, GlobalContext*); +typedef void (*DemoEffectUnkFunc)(struct DemoEffect*, GlobalContext*); +typedef void (*DemoEffectUnkFunc2)(Actor*, GlobalContext*); + +#define DEMOEFFECT_GET_FF(thisx) ((thisx)->params & 0xFF) typedef struct DemoEffect { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x34]; + /* 0x0144 */ SkelAnimeCurve skelCurve; + /* 0x0164 */ u8 unk_164; + /* 0x0165 */ UNK_TYPE1 unk_165[3]; + /* 0x0168 */ u8 unk_168[3]; + /* 0x016C */ s16 unk_16C; + /* 0x0170 */ DemoEffectUnkFunc unk_170; + /* 0x0174 */ DemoEffectUnkFunc2 unk_174; /* 0x0178 */ DemoEffectActionFunc actionFunc; } DemoEffect; // size = 0x17C 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 0853cc8b6..9e6661fd0 100644 --- a/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c +++ b/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c @@ -1,6 +1,12 @@ +/* + * File: z_demo_getitem.c + * Overlay: ovl_Demo_Getitem + * Description: Cutscene object for Great Fairy's Mask and Great Fairy's Sword + */ + #include "z_demo_getitem.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoGetitem*)thisx) 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 61ff3f7a2..2c676abbf 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -1,6 +1,14 @@ -#include "z_demo_kankyo.h" +/* + * File: z_demo_kankyo.c + * Overlay: ovl_Demo_Kankyo + * Description: Background Lost Woods/Giant's Chamber/Moon Particles + */ -#define FLAGS 0x00000030 +#include "z_demo_kankyo.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_bubble/object_bubble.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoKankyo*)thisx) @@ -9,12 +17,11 @@ void DemoKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx); void DemoKankyo_Update(Actor* thisx, GlobalContext* globalCtx); void DemoKankyo_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808CF06C(DemoKankyo* this, GlobalContext* globalCtx); -void func_808CF0CC(DemoKankyo* this, GlobalContext* globalCtx); +void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, GlobalContext* globalCtx); -void DemoKankyo_SetupAction(DemoKankyo* this, DemoKankyoActionFunc actionFunc); +static u8 sLostWoodsSparklesMutex = false; // make sure only one can exist at once +static s16 sLostWoodsSkyFishParticleNum = 0; -#if 0 const ActorInit Demo_Kankyo_InitVars = { ACTOR_DEMO_KANKYO, ACTORCAT_ITEMACTION, @@ -27,24 +34,656 @@ const ActorInit Demo_Kankyo_InitVars = { (ActorFunc)DemoKankyo_Draw, }; -#endif +static s32 sObjectBubbleIndex = OBJECT_BUBBLE | 0x10000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/DemoKankyo_SetupAction.s") +void DemoKankyo_SetupAction(DemoKankyo* this, DemoKankyoActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/func_808CE45C.s") +void DemoKakyo_LostWoodsSparkleActionFunc(DemoKankyo* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + f32 randSkyfishParticleNum; + f32 repositionLimit; // Distance from posCenter when particles are relocated. Always set to 130.0f + f32 eyeToAtNormX; + f32 eyeToAtNormY; + f32 eyeToAtNormZ; + f32 eyeToAtMag; + f32 posCenterX; + f32 posCenterY; + f32 posCenterZ; + Vec3f eyeToAt; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/func_808CF06C.s") + if (globalCtx->roomCtx.unk7A[1] != 0) { + if (globalCtx->envCtx.unk_F2[3] != 0) { + globalCtx->envCtx.unk_F2[3]--; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (globalCtx->envCtx.unk_F2[3] < DEMOKANKYO_PARTICLE_COUNT) { + globalCtx->envCtx.unk_F2[3] += 16; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/func_808CF0CC.s") + // note: DemoKankyo can crash if placed in an area that snows (ObjectKankyo) + // because they both use unk_F2 as a particle counter, + // causing DemoKankyo to write beyond its particle array boundry + // this crash can occur if the two actors are in different scenes connected by an exit + // e.g. if you add DemoKankyo to GoronShrine, you will crash entering/leaving through door + for (i = 0; i < globalCtx->envCtx.unk_F2[3]; i++) { + repositionLimit = 130.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/DemoKankyo_Init.s") + eyeToAt.x = globalCtx->view.at.x - globalCtx->view.eye.x; + eyeToAt.y = globalCtx->view.at.y - globalCtx->view.eye.y; + eyeToAt.z = globalCtx->view.at.z - globalCtx->view.eye.z; + eyeToAtMag = sqrtf(SQXYZ(eyeToAt)); + eyeToAtNormX = eyeToAt.x / eyeToAtMag; + eyeToAtNormY = eyeToAt.y / eyeToAtMag; + eyeToAtNormZ = eyeToAt.z / eyeToAtMag; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/DemoKankyo_Destroy.s") + switch (this->particles[i].state) { + case DEMO_KANKYO_STATE_INIT: + this->particles[i].posBase.x = globalCtx->view.eye.x + (eyeToAtNormX * 80.0f); + this->particles[i].posBase.y = globalCtx->view.eye.y + (eyeToAtNormY * 80.0f); + this->particles[i].posBase.z = globalCtx->view.eye.z + (eyeToAtNormZ * 80.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/DemoKankyo_Update.s") + this->particles[i].posOffset.x = (Rand_ZeroOne() - 0.5f) * 160.0f; + this->particles[i].posOffset.y = 30.0f; + this->particles[i].posOffset.z = (Rand_ZeroOne() - 0.5f) * 160.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/func_808CF970.s") + this->particles[i].speedTarget = (Rand_ZeroOne() * 1.6f) + 0.5f; + this->particles[i].alpha = 0; + this->particles[i].alphaClock = Rand_ZeroOne() * 65535; // random 0 to max of u16 + this->particles[i].scale = 0.1f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/func_808CFE04.s") + // speedClock is angles in radians, + // should have used Rand_ZeroOne() * 2 * M_PI + // however, due to properties of sine waves, this is effectively still random + this->particles[i].speedClock.x = Rand_ZeroOne() * 360.0f; + this->particles[i].speedClock.y = Rand_ZeroOne() * 360.0f; + this->particles[i].speedClock.z = Rand_ZeroOne() * 360.0f; + this->particles[i].pad50 = 0; + this->particles[i].state += DEMO_KANKYO_STATE_SINGLE; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Kankyo/DemoKankyo_Draw.s") + case DEMO_KANKYO_STATE_SINGLE: + case DEMO_KANKYO_STATE_SKYFISH: + this->particles[i].alphaClock++; + posCenterX = globalCtx->view.eye.x + (eyeToAtNormX * 80.0f); + posCenterY = globalCtx->view.eye.y + (eyeToAtNormY * 80.0f); + posCenterZ = globalCtx->view.eye.z + (eyeToAtNormZ * 80.0f); + this->particles[i].posOffsetPrev.x = this->particles[i].posOffset.x; + this->particles[i].posOffsetPrev.y = this->particles[i].posOffset.y; + this->particles[i].posOffsetPrev.z = this->particles[i].posOffset.z; + + if (this->particles[i].state == DEMO_KANKYO_STATE_SINGLE) { + + // The first 32 particles will become skyfish particles + // This block is also init code and only runs once + if (i < 32) { + if (Rand_ZeroOne() < 0.5f) { + this->particles[i].LostWoodsSkyFishSpeedXZ = (s16)(Rand_ZeroOne() * 200.0f) + 200; + } else { + this->particles[i].LostWoodsSkyFishSpeedXZ = -200 - (s16)(Rand_ZeroOne() * 200.0f); + } + this->particles[i].LostWoodsSkyFishPosOffsetMax = (s16)(Rand_ZeroOne() * 50.0f) + 15; + this->particles[i].LostWoodsSkyFishSpeedY = ((Rand_ZeroOne() * 10.0f) + 10.0f) * 0.01f; + + // Only the 31st particle matters as sLostWoodsSkyFishParticleNum will be overwritten + // every particle until the last skyfish particle is initialized + randSkyfishParticleNum = Rand_ZeroOne(); + if (randSkyfishParticleNum < 0.2f) { + sLostWoodsSkyFishParticleNum = 1; + } else if (randSkyfishParticleNum < 0.2f) { + // This case is never taken as the else-if conditional is identical to the previous one + sLostWoodsSkyFishParticleNum = 3; + } else if (randSkyfishParticleNum < 0.4f) { + sLostWoodsSkyFishParticleNum = 7; + } else { + sLostWoodsSkyFishParticleNum = 15; + } + + if ((i & sLostWoodsSkyFishParticleNum) == 0) { + // Head particle + this->particles[i].posOffset.y = 0.0f; + } + this->particles[i].state = DEMO_KANKYO_STATE_SKYFISH; + this->particles[i].speedTarget = 0.0f; + } + + Math_SmoothStepToF(&this->particles[i].scale, 0.1, 0.1f, 0.001f, 0.00001f); + Math_SmoothStepToF(&this->particles[i].speed, this->particles[i].speedTarget, 0.5f, 0.2f, 0.02f); + this->particles[i].posOffset.x += sinf(this->particles[i].speedClock.x) * this->particles[i].speed; + this->particles[i].posOffset.y += sinf(this->particles[i].speedClock.y) * this->particles[i].speed; + this->particles[i].posOffset.z += sinf(this->particles[i].speedClock.z) * this->particles[i].speed; + + switch ((i >> 1) & 3) { + case 0: + this->particles[i].speedClock.x += 0.008f; + this->particles[i].speedClock.y += 0.05f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.015f; + break; + + case 1: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.05f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.005f * Rand_ZeroOne(); + break; + + case 2: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.4f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.004f * Rand_ZeroOne(); + break; + + case 3: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.08f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.05f * Rand_ZeroOne(); + break; + } + + } else if (this->particles[i].state == DEMO_KANKYO_STATE_SKYFISH) { + if ((i & sLostWoodsSkyFishParticleNum) == 0) { + // Head particle + Math_SmoothStepToF(&this->particles[i].scale, 0.25f, 0.1f, 0.001f, 0.00001f); + + Math_SmoothStepToF(&this->particles[i].posBase.x, player->actor.world.pos.x, 0.5f, 1.0f, 0.2f); + Math_SmoothStepToF(&this->particles[i].posBase.y, player->actor.world.pos.y + 50.0f, 0.5f, 1.0f, + 0.2f); + Math_SmoothStepToF(&this->particles[i].posBase.z, player->actor.world.pos.z, 0.5f, 1.0f, 0.2f); + + Math_SmoothStepToF(&this->particles[i].posOffset.x, + Math_SinS(this->particles[i].LostWoodsSkyFishSpeedXZClock - 0x8000) * + this->particles[i].LostWoodsSkyFishPosOffsetMax, + 0.5f, 2.0f, 0.2f); + Math_SmoothStepToF(&this->particles[i].posOffset.z, + Math_CosS(this->particles[i].LostWoodsSkyFishSpeedXZClock - 0x8000) * + this->particles[i].LostWoodsSkyFishPosOffsetMax, + 0.5f, 2.0f, 0.2f); + this->particles[i].LostWoodsSkyFishSpeedXZClock += this->particles[i].LostWoodsSkyFishSpeedXZ; + this->particles[i].posOffset.y += sinf(this->particles[i].speedClock.y); + this->particles[i].speedClock.x += 0.2f * Rand_ZeroOne(); // unused calculation + this->particles[i].speedClock.y += this->particles[i].LostWoodsSkyFishSpeedY; + this->particles[i].speedClock.z += 0.1f * Rand_ZeroOne(); // unused calculation + + this->particles[i].posOffset.x = + Math_SinS(this->particles[i].LostWoodsSkyFishSpeedXZClock - 0x8000) * + this->particles[i].LostWoodsSkyFishPosOffsetMax; + this->particles[i].posOffset.z = + Math_CosS(this->particles[i].LostWoodsSkyFishSpeedXZClock - 0x8000) * + this->particles[i].LostWoodsSkyFishPosOffsetMax; + } else { + // Tail Particles + Math_SmoothStepToF(&this->particles[i].scale, 0.1, 0.1f, 0.001f, 0.00001f); + + // Unused calculation, speed only used in posOffset calculations, + // but posOffset gets overwritten for tail particles immediately below + Math_SmoothStepToF(&this->particles[i].speed, 1.5f, 0.5f, 0.1f, 0.0002f); + + // particles in the skyfish's tail are moved to the previous position of the particle directly + // in front + this->particles[i].posOffset.x = + this->particles[i - 1].posOffsetPrev.x + + (this->particles[i - 1].posBase.x - this->particles[i].posBase.x); + this->particles[i].posOffset.y = + this->particles[i - 1].posOffsetPrev.y + + (this->particles[i - 1].posBase.y - this->particles[i].posBase.y); + this->particles[i].posOffset.z = + this->particles[i - 1].posOffsetPrev.z + + (this->particles[i - 1].posBase.z - this->particles[i].posBase.z); + } + } + + if ((this->particles[i].state != DEMO_KANKYO_STATE_SKYFISH) && + ((((this->particles[i].posBase.x + this->particles[i].posOffset.x) - posCenterX) > + repositionLimit) || + (((this->particles[i].posBase.x + this->particles[i].posOffset.x) - posCenterX) < + -repositionLimit) || + (((this->particles[i].posBase.y + this->particles[i].posOffset.y) - posCenterY) > + repositionLimit) || + (((this->particles[i].posBase.y + this->particles[i].posOffset.y) - posCenterY) < + -repositionLimit) || + (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - posCenterZ) > + repositionLimit) || + (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - posCenterZ) < + -repositionLimit))) { + if (((this->particles[i].posOffset.x + this->particles[i].posBase.x) - posCenterX) > + repositionLimit) { + this->particles[i].posOffset.x = 0.0f; + this->particles[i].posBase.x = posCenterX - repositionLimit; + } + + if (((this->particles[i].posBase.x + this->particles[i].posOffset.x) - posCenterX) < + -repositionLimit) { + this->particles[i].posOffset.x = 0.0f; + this->particles[i].posBase.x = posCenterX + repositionLimit; + } + + if (((this->particles[i].posBase.y + this->particles[i].posOffset.y) - posCenterY) > 50.0f) { + this->particles[i].posOffset.y = 0.0f; + this->particles[i].posBase.y = posCenterY - 50.0f; + } + + if (((this->particles[i].posBase.y + this->particles[i].posOffset.y) - posCenterY) < -50.0f) { + this->particles[i].posOffset.y = 0.0f; + this->particles[i].posBase.y = posCenterY + 50.0f; + } + + if (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - posCenterZ) > + repositionLimit) { + this->particles[i].posOffset.z = 0.0f; + this->particles[i].posBase.z = posCenterZ - repositionLimit; + } + + if (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - posCenterZ) < + -repositionLimit) { + this->particles[i].posOffset.z = 0.0f; + this->particles[i].posBase.z = posCenterZ + repositionLimit; + } + } + break; + + case DEMO_KANKYO_STATE_DISABLED: + this->particles[i].state = DEMO_KANKYO_STATE_INIT; + break; + } + } +} + +void DemoKakyo_GiantObjectCheck(DemoKankyo* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->objectId)) { + this->isSafeToDrawGiants = true; + this->actor.objBankIndex = this->objectId; + DemoKankyo_SetupAction(this, DemoKakyo_MoonSparklesActionFunc); + } +} + +/* + * used by Moon AND giants types + */ +void DemoKakyo_MoonSparklesActionFunc(DemoKankyo* this, GlobalContext* globalCtx) { + s32 i; + Vec3f eyeToAt; + f32 eyeToAtNormX; + f32 eyeToAtNormY; + f32 eyeToAtNormZ; + f32 eyeToAtMag; + f32 halfScreenWidth; + f32 randZeroOne; + f32 pad0; + Vec3f newEye; + f32 halfScreenHeight; + s32 pad1; + Vec3f worldPos; + + if (globalCtx->envCtx.unk_F2[3] < DEMOKANKYO_PARTICLE_COUNT) { + globalCtx->envCtx.unk_F2[3] += 16; + } + + eyeToAt.x = globalCtx->view.at.x - globalCtx->view.eye.x; + eyeToAt.y = globalCtx->view.at.y - globalCtx->view.eye.y; + eyeToAt.z = globalCtx->view.at.z - globalCtx->view.eye.z; + eyeToAtMag = sqrtf(SQXYZ(eyeToAt)); + eyeToAtNormX = eyeToAt.x / eyeToAtMag; + eyeToAtNormY = eyeToAt.y / eyeToAtMag; + eyeToAtNormZ = eyeToAt.z / eyeToAtMag; + + halfScreenHeight = SCREEN_HEIGHT / 2; + + for (i = 0; i < globalCtx->envCtx.unk_F2[3]; i++) { + switch (this->particles[i].state) { + case DEMO_KANKYO_STATE_INIT: + this->particles[i].posBase.x = globalCtx->view.eye.x + (eyeToAtNormX * halfScreenHeight); + this->particles[i].posBase.y = globalCtx->view.eye.y + (eyeToAtNormY * halfScreenHeight); + this->particles[i].posBase.z = globalCtx->view.eye.z + (eyeToAtNormZ * halfScreenHeight); + + this->particles[i].posOffset.x = (Rand_ZeroOne() - 0.5f) * (2.0f * halfScreenHeight); + this->particles[i].posOffset.y = (Rand_ZeroOne() - 0.5f) * (2.0f * halfScreenHeight); + this->particles[i].posOffset.z = (Rand_ZeroOne() - 0.5f) * (2.0f * halfScreenHeight); + + this->particles[i].speedTarget = (Rand_ZeroOne() * 1.6f) + 0.5f; + this->particles[i].alpha = 0; + this->particles[i].alphaClock = (Rand_ZeroOne() * 65535); + this->particles[i].scale = 0.2f; + + // speedClock is angles in radians, + // should have used Rand_ZeroOne() * 2 * M_PI + // however, due to properties of sine waves, this is effectively still random + this->particles[i].speedClock.x = Rand_ZeroOne() * 360.0f; + this->particles[i].speedClock.y = Rand_ZeroOne() * 360.0f; + this->particles[i].speedClock.z = Rand_ZeroOne() * 360.0f; + + this->particles[i].pad50 = 0; + this->particles[i].state += DEMO_KANKYO_STATE_SINGLE; + break; + + case DEMO_KANKYO_STATE_SINGLE: + case DEMO_KANKYO_STATE_SKYFISH: + this->particles[i].alphaClock++; + + if (this->actor.params == DEMO_KANKYO_TYPE_MOON) { // this function gets reused for giants too + this->particles[i].posBase.y = + globalCtx->view.eye.y + (eyeToAtNormY * halfScreenHeight) + (SCREEN_HEIGHT / 3); + } + + newEye.x = globalCtx->view.eye.x + (eyeToAtNormX * halfScreenHeight); + newEye.y = globalCtx->view.eye.y + (eyeToAtNormY * halfScreenHeight); + newEye.z = globalCtx->view.eye.z + (eyeToAtNormZ * halfScreenHeight); + + Math_SmoothStepToF(&this->particles[i].scale, 0.2f, 0.1f, 0.001f, 0.00001f); + Math_SmoothStepToF(&this->particles[i].speed, this->particles[i].speedTarget, 0.5f, 0.2f, 0.02f); + + this->particles[i].posOffset.x += sinf(this->particles[i].speedClock.x) * this->particles[i].speed; + this->particles[i].posOffset.y += sinf(this->particles[i].speedClock.y) * this->particles[i].speed; + this->particles[i].posOffset.z += sinf(this->particles[i].speedClock.z) * this->particles[i].speed; + + switch ((i >> 1) & 3) { + case 0: + this->particles[i].speedClock.x += 0.008f; + this->particles[i].speedClock.y += 0.05f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.015f; + break; + + case 1: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.05f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.005f * Rand_ZeroOne(); + break; + + case 2: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.4f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.004f * Rand_ZeroOne(); + break; + + case 3: + this->particles[i].speedClock.x += 0.01f * Rand_ZeroOne(); + this->particles[i].speedClock.y += 0.08f * Rand_ZeroOne(); + this->particles[i].speedClock.z += 0.05f * Rand_ZeroOne(); + break; + } + + if (((this->particles[i].posBase.x + this->particles[i].posOffset.x) - newEye.x) > halfScreenHeight) { + this->particles[i].posBase.x = newEye.x - halfScreenHeight; + } + + if (((this->particles[i].posBase.x + this->particles[i].posOffset.x) - newEye.x) < -halfScreenHeight) { + this->particles[i].posBase.x = newEye.x + halfScreenHeight; + } + + worldPos.x = this->particles[i].posBase.x + this->particles[i].posOffset.x; + worldPos.y = this->particles[i].posBase.y + this->particles[i].posOffset.y; + worldPos.z = this->particles[i].posBase.z + this->particles[i].posOffset.z; + + randZeroOne = Math_Vec3f_DistXZ(&worldPos, &globalCtx->view.eye) / 200.0f; + randZeroOne = CLAMP(randZeroOne, 0.0f, 1.0f); + halfScreenWidth = 100.0f + randZeroOne + 60.0f; // range 160 to 161...? thats about half screen width + + // I think this code is shifting the particles 1 frame -> half screen at a time to keep it in-view + if (halfScreenWidth < ((this->particles[i].posBase.y + this->particles[i].posOffset.y) - newEye.y)) { + this->particles[i].posBase.y = newEye.y - halfScreenWidth; + } + + if (((this->particles[i].posBase.y + this->particles[i].posOffset.y) - newEye.y) < -halfScreenWidth) { + this->particles[i].posBase.y = newEye.y + halfScreenWidth; + } + + if (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - newEye.z) > halfScreenHeight) { + this->particles[i].posBase.z = newEye.z - halfScreenHeight; + } + + if (((this->particles[i].posBase.z + this->particles[i].posOffset.z) - newEye.z) < -halfScreenHeight) { + this->particles[i].posBase.z = newEye.z + halfScreenHeight; + } + + break; + + case DEMO_KANKYO_STATE_DISABLED: + this->particles[i].state = DEMO_KANKYO_STATE_INIT; + break; + } + } +} + +void DemoKankyo_Init(Actor* thisx, GlobalContext* globalCtx) { + DemoKankyo* this = THIS; + s32 pad; + s32 i; + s32 objId; + + // This must be a single line to match, possibly a macro? + // clang-format off + for (i = 0; i < ARRAY_COUNT(this->particles); i++) { this->particles[i].state = DEMO_KANKYO_STATE_INIT; } + // clang-format on + + if (1) {}; + + switch (this->actor.params) { + case DEMO_KANKYO_TYPE_LOSTWOODS: + objId = OBJECT_UNSET_0; + this->actor.room = -1; + if (sLostWoodsSparklesMutex == false) { + DemoKankyo_SetupAction(this, DemoKakyo_LostWoodsSparkleActionFunc); + sLostWoodsSparklesMutex = true; + } else { + Actor_MarkForDeath(&this->actor); + } + break; + + case DEMO_KANKYO_TYPE_GIANTS: + this->isSafeToDrawGiants = false; + objId = Object_GetIndex(&globalCtx->objectCtx, sObjectBubbleIndex); + DemoKankyo_SetupAction(this, DemoKakyo_GiantObjectCheck); + break; + + case DEMO_KANKYO_TYPE_MOON: + objId = OBJECT_UNSET_0; + this->isSafeToDrawGiants = true; + DemoKankyo_SetupAction(this, DemoKakyo_MoonSparklesActionFunc); + break; + + default: + //! @bug: this causes a crash because the actionfunc is never set + objId = -1; + break; + } + + if (objId > -1) { + this->objectId = objId; + } +} + +void DemoKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + DemoKankyo* this = THIS; + + Actor_MarkForDeath(&this->actor); +} + +void DemoKankyo_Update(Actor* thisx, GlobalContext* globalCtx) { + DemoKankyo* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DemoKankyo* this = THIS; + s16 i; + f32 scaleAlpha; + Vec3f worldPos; + Vec3f screenPos; + + // if not underwater + if (!(globalCtx->cameraPtrs[CAM_ID_MAIN]->flags2 & 0x100)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); + + for (i = 0; i < globalCtx->envCtx.unk_F2[3]; i++) { + worldPos.x = this->particles[i].posBase.x + this->particles[i].posOffset.x; + worldPos.y = this->particles[i].posBase.y + this->particles[i].posOffset.y; + worldPos.z = this->particles[i].posBase.z + this->particles[i].posOffset.z; + + func_80169474(globalCtx, &worldPos, &screenPos); // unnamed Play_ function, func_800C016C from OoT + + // checking if particle is on screen + if (screenPos.x >= 0.0f && screenPos.x < SCREEN_WIDTH && screenPos.y >= 0.0f && + screenPos.y < SCREEN_HEIGHT) { + Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); + scaleAlpha = this->particles[i].alpha / 50.0f; + if (scaleAlpha > 1.0f) { + scaleAlpha = 1.0f; + } + + Matrix_Scale(this->particles[i].scale * scaleAlpha, this->particles[i].scale * scaleAlpha, + this->particles[i].scale * scaleAlpha, MTXMODE_APPLY); + + // adjust transparency of this particle + if (i < 32) { + // Skyfish particles + if (this->particles[i].state != DEMO_KANKYO_STATE_SKYFISH) { + // still initializing + if (this->particles[i].alpha > 0) { // NOT DECR + this->particles[i].alpha--; + } + } else if (this->particles[i].alpha < 100) { + this->particles[i].alpha++; + } + } else if (this->particles[i].state != DEMO_KANKYO_STATE_SKYFISH) { + if ((this->particles[i].alphaClock & 31) < 16) { + if (this->particles[i].alpha < 235) { + this->particles[i].alpha += 20; + } + } else if (this->particles[i].alpha > 20) { + this->particles[i].alpha -= 20; + } + } else if ((this->particles[i].alphaClock & 15) < 8) { + if (this->particles[i].alpha < 255) { + this->particles[i].alpha += 100; + } + } else if (this->particles[i].alpha > 10) { + this->particles[i].alpha -= 10; + } + + gDPPipeSync(POLY_XLU_DISP++); + + switch (i & 1) { + case 0: // gold particles + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 155, this->particles[i].alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 180, 0, this->particles[i].alpha); + break; + + case 1: // silver particles + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, this->particles[i].alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, this->particles[i].alpha); + break; + } + + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZF(DEGF_TO_RADF(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); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +// draw, giants and moon +void DemoKankyo_DrawMoonAndGiant(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DemoKankyo* this = THIS; + s16 i; + f32 alphaScale; + + if (this->isSafeToDrawGiants != false) { + Vec3f worldPos; + Vec3f screenPos; + s32 pad; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + func_8012C2DC(gfxCtx); + + for (i = 0; i < globalCtx->envCtx.unk_F2[3]; i++) { + worldPos.x = this->particles[i].posBase.x + this->particles[i].posOffset.x; + worldPos.y = this->particles[i].posBase.y + this->particles[i].posOffset.y; + worldPos.z = this->particles[i].posBase.z + this->particles[i].posOffset.z; + + func_80169474(globalCtx, &worldPos, &screenPos); // unnamed Play_ function, func_800C016C from OoT + + // checking if particle is on screen + if (screenPos.x >= 0.0f && screenPos.x < SCREEN_WIDTH && screenPos.y >= 0.0f && + screenPos.y < SCREEN_HEIGHT) { + Matrix_Translate(worldPos.x, worldPos.y, worldPos.z, MTXMODE_NEW); + alphaScale = this->particles[i].alpha / 50.0f; + if (alphaScale > 1.0f) { + alphaScale = 1.0f; + } + Matrix_Scale(this->particles[i].scale * alphaScale, this->particles[i].scale * alphaScale, + this->particles[i].scale * alphaScale, MTXMODE_APPLY); + alphaScale = Math_Vec3f_DistXYZ(&worldPos, &globalCtx->view.eye) / 300.0f; + alphaScale = CLAMP(1.0f - alphaScale, 0.0f, 1.0f); + + if (this->actor.params == DEMO_KANKYO_TYPE_GIANTS) { + this->particles[i].alpha = 255.0f * alphaScale; + } else { + this->particles[i].alpha = 160.0f * alphaScale; + } + + gDPPipeSync(POLY_XLU_DISP++); + + switch (i & 1) { // half/half slightly different shades of yellow/tan + case 0: + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 230, 230, 220, this->particles[i].alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 230, 230, 30, this->particles[i].alpha); + break; + + case 1: + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 200, 200, 190, this->particles[i].alpha); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 30, this->particles[i].alpha); + break; + } + + gSPDisplayList(POLY_XLU_DISP++, &gLightOrb1DL); + + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + Matrix_RotateZF(DEGF_TO_RADF(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); + + if (this->actor.params == DEMO_KANKYO_TYPE_GIANTS) { + gSPDisplayList(POLY_XLU_DISP++, object_bubble_DL_001000); + } else { + gSPDisplayList(POLY_XLU_DISP++, gLightOrbVtxDL); + } + } + } + + CLOSE_DISPS(gfxCtx); + } +} + +void DemoKankyo_Draw(Actor* thisx, GlobalContext* globalCtx) { + DemoKankyo* this = THIS; + + switch (this->actor.params) { + case DEMO_KANKYO_TYPE_LOSTWOODS: + DemoKakyo_DrawLostWoodsSparkle(&this->actor, globalCtx); + break; + + case DEMO_KANKYO_TYPE_GIANTS: + case DEMO_KANKYO_TYPE_MOON: + DemoKankyo_DrawMoonAndGiant(&this->actor, globalCtx); + break; + } +} diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h index 9dfa597b4..d70616ed6 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.h @@ -7,13 +7,47 @@ struct DemoKankyo; typedef void (*DemoKankyoActionFunc)(struct DemoKankyo*, GlobalContext*); +typedef struct { + /* 0x000 */ u8 state; + /* 0x004 */ Vec3f posOffset; + /* 0x010 */ Vec3f posOffsetPrev; + /* 0x01C */ Vec3f posBase; + /* 0x028 */ Vec3f speedClock; // cycles in radians + /* 0x034 */ f32 speed; + /* 0x038 */ f32 speedTarget; + /* 0x03C */ u16 alphaClock; + /* 0x03E */ u16 LostWoodsSkyFishSpeedXZClock; + /* 0x040 */ u8 alpha; + /* 0x044 */ f32 scale; // size of the particle + /* 0x048 */ u16 LostWoodsSkyFishSpeedXZ; // the x-z speed (angular velocity) the lost woods skyfish oscillates around player. pos or neg 200-400 + /* 0x04A */ u16 LostWoodsSkyFishPosOffsetMax; // The x-z range the lost woods skyfish oscillates around player. random value between 15-65 + /* 0x04C */ f32 LostWoodsSkyFishSpeedY; // the y speed (angular velocity) the lost woods skyfish oscillates around player. + /* 0x050 */ u16 pad50; // unused, always assigned to 0, nothing else in this actor uses it +} DemoKankyoParticle; // size = 0x54 + +#define DEMOKANKYO_PARTICLE_COUNT 64 + typedef struct DemoKankyo { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1500]; + /* 0x0144 */ DemoKankyoParticle particles[DEMOKANKYO_PARTICLE_COUNT]; /* 0x1644 */ DemoKankyoActionFunc actionFunc; - /* 0x1648 */ char unk_1648[0x8]; + /* 0x1648 */ s32 objectId; + /* 0x164C */ u8 isSafeToDrawGiants; } DemoKankyo; // size = 0x1650 +typedef enum { + /* 0 */ DEMO_KANKYO_TYPE_LOSTWOODS, + /* 1 */ DEMO_KANKYO_TYPE_GIANTS, + /* 2 */ DEMO_KANKYO_TYPE_MOON, +} DemoKankyoType; + +typedef enum { + /* 0 */ DEMO_KANKYO_STATE_INIT, + /* 1 */ DEMO_KANKYO_STATE_SINGLE, + /* 2 */ DEMO_KANKYO_STATE_SKYFISH, + /* 3 */ DEMO_KANKYO_STATE_DISABLED, +} DemoKankyoStateType; + extern const ActorInit Demo_Kankyo_InitVars; #endif // Z_DEMO_KANKYO_H diff --git a/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c b/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c index 50b340953..9ed7a0c27 100644 --- a/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c +++ b/src/overlays/actors/ovl_Demo_Moonend/z_demo_moonend.c @@ -1,6 +1,12 @@ +/* + * File: z_demo_moonend.c + * Overlay: ovl_Demo_Moonend + * Description: Moon Disappearing (cutscene) + */ + #include "z_demo_moonend.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoMoonend*)thisx) diff --git a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c index d68e977e4..faedc1b74 100644 --- a/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c +++ b/src/overlays/actors/ovl_Demo_Shd/z_demo_shd.c @@ -1,6 +1,12 @@ +/* + * File: z_demo_shd.c + * Overlay: ovl_Demo_Shd + * Description: + */ + #include "z_demo_shd.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoShd*)thisx) 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 f4b42e580..72f101d18 100644 --- a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c +++ b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c @@ -1,6 +1,13 @@ -#include "z_demo_syoten.h" +/* + * File: z_demo_syoten.c + * Overlay: ovl_Demo_Syoten + * Description: Ikana Canyon Cleansing Cutscene Effects + */ -#define FLAGS 0x00000030 +#include "z_demo_syoten.h" +#include "objects/object_syoten/object_syoten.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DemoSyoten*)thisx) @@ -9,7 +16,15 @@ void DemoSyoten_Destroy(Actor* thisx, GlobalContext* globalCtx); void DemoSyoten_Update(Actor* thisx, GlobalContext* globalCtx); void DemoSyoten_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80C16A64(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C16A74(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C16BD4(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C16DD4(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C16EAC(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C17008(DemoSyoten* this, GlobalContext* globalCtx); +void func_80C173B4(Actor* thisx, GlobalContext* globalCtx); +void func_80C17690(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Demo_Syoten_InitVars = { ACTOR_DEMO_SYOTEN, ACTORCAT_ITEMACTION, @@ -22,45 +37,539 @@ const ActorInit Demo_Syoten_InitVars = { (ActorFunc)DemoSyoten_Draw, }; -#endif +u8 D_80C177D0[] = { + 0, 1, 1, 0, 2, 2, 2, 2, 0, 0, 1, 0, 2, 2, 0, 1, 0, 2, 2, 0, 1, 0, 2, 2, 0, 1, 0, + 2, 2, 0, 1, 0, 1, 2, 2, 1, 2, 2, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 0, 0, 1, 0, 2, 2, + 0, 1, 0, 2, 2, 0, 1, 0, 2, 2, 2, 0, 0, 2, 0, 1, 1, 0, 2, 2, 2, 0, 1, 0, 2, 2, 0, +}; -extern UNK_TYPE D_0600023C; -extern UNK_TYPE D_06001298; -extern UNK_TYPE D_060018C0; -extern UNK_TYPE D_06002880; +Color_RGBA8 D_80C17824[] = { + { 160, 100, 130, 255 }, + { 150, 120, 160, 255 }, + { 130, 90, 150, 255 }, + { 90, 70, 120, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/DemoSyoten_Init.s") +Color_RGBA8 D_80C17834[] = { + { 110, 50, 80, 255 }, + { 120, 100, 130, 255 }, + { 90, 40, 100, 255 }, + { 60, 50, 100, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/DemoSyoten_Destroy.s") +void DemoSyoten_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DemoSyoten* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16760.s") + Actor_SetScale(&this->actor, 0.3f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16818.s") + this->actionFunc = func_80C16A64; + this->unk_3E4 = 0; + this->unk_3E6 = 0; + this->unk_3DC = NULL; + this->unk_3E0 = NULL; + this->unk_3F2 = 0; + this->unk_3D8 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C168D0.s") + switch (DEMOSYOTEN_GET_F(&this->actor)) { + case DEMOSYOTEN_F_0: + func_80183430(&this->unk_144, &object_syoten_Blob_001328, &object_syoten_Blob_00023C, this->unk_174, + this->unk_2A6, 0); + func_801835EC(&this->unk_144, &object_syoten_Blob_00023C); + this->actor.draw = NULL; + this->actionFunc = func_80C16A74; + this->actor.child = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EFF_DUST, + this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, 0); + this->unk_3F0 = 0x215; + Actor_SetScale(&this->actor, 0.05f); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16974.s") + case DEMOSYOTEN_F_1: + Actor_SetScale(&this->actor, 0.1f); + this->unk_3DC = object_syoten_DL_001370; + this->unk_3E0 = Lib_SegmentedToVirtual(&object_syoten_Matanimheader_001448); + this->unk_3E4 |= 1; + this->actionFunc = func_80C16BD4; + this->unk_3F0 = 0x215; + Actor_SetScale(&this->actor, 0.05f); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16A64.s") + case DEMOSYOTEN_F_2: + this->unk_3DC = object_syoten_DL_001730; + this->unk_3E0 = Lib_SegmentedToVirtual(&object_syoten_Matanimheader_0018B8); + this->unk_3F0 = 0x216; + this->actionFunc = func_80C16DD4; + this->unk_3E4 |= 2; + Actor_SetScale(&this->actor, 4.0f); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16A74.s") + case DEMOSYOTEN_F_3: + this->unk_3DC = object_syoten_DL_001DD0; + this->unk_3E0 = Lib_SegmentedToVirtual(&object_syoten_Matanimheader_002B98); + this->unk_3F0 = 0x218; + this->unk_3E4 |= 8; + this->actionFunc = func_80C16EAC; + Actor_SetScale(&this->actor, 0.5f); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16BD4.s") + case DEMOSYOTEN_F_4: + this->unk_3DC = object_syoten_DL_002880; + this->unk_3E0 = Lib_SegmentedToVirtual(&object_syoten_Matanimheader_002B88); + this->unk_3E4 |= 2; + this->actionFunc = func_80C17008; + this->unk_3F0 = 0x217; + this->unk_3E4 |= 1; + this->unk_3E4 |= 8; + this->actor.draw = func_80C17690; + Actor_SetScale(&this->actor, 5.0f); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16DD4.s") +void DemoSyoten_Destroy(Actor* thisx, GlobalContext* globalCtx) { + DemoSyoten* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C16EAC.s") + if (DEMOSYOTEN_GET_F(&this->actor) == DEMOSYOTEN_F_0) { + func_8018349C(&this->unk_144); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C17008.s") +void func_80C16760(DemoSyoten* this, GlobalContext* globalCtx) { + s32 pad; + Vec3s* points; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/DemoSyoten_Update.s") + this->unk_3EC = 0; + if (DEMOSYOTEN_GET_7E00(&this->actor) != DEMOSYOTEN_7E00_3F) { + this->unk_3E8 = &globalCtx->setupPathList[DEMOSYOTEN_GET_7E00(&this->actor)]; + if (this->unk_3E8 != NULL) { + points = Lib_SegmentedToVirtual(this->unk_3E8->points); + Math_Vec3s_ToVec3f(&this->actor.world.pos, &points[0]); + this->unk_3EC++; + points++; + Math_Vec3s_ToVec3f(&sp2C, points); + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp2C); + this->actor.world.rot.x = Math_Vec3f_Pitch(&this->actor.world.pos, &sp2C); + } + } else { + this->unk_3E8 = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C170F8.s") +s32 func_80C16818(DemoSyoten* this) { + s32 pad; + Path* path = this->unk_3E8; + Vec3s* points; + Vec3f sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C173B4.s") + if (path == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C17468.s") + points = Lib_SegmentedToVirtual(this->unk_3E8->points); + points += this->unk_3EC; + Math_Vec3s_ToVec3f(&sp28, points); + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp28); + this->actor.world.rot.x = Math_Vec3f_Pitch(&this->actor.world.pos, &sp28); + Actor_MoveWithoutGravityReverse(&this->actor); + if (Math_Vec3f_DistXYZ(&this->actor.world.pos, &sp28) < 2.0f) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/DemoSyoten_Draw.s") +void func_80C168D0(DemoSyoten* this, GlobalContext* globalCtx) { + s32 pad; + Path* path = this->unk_3E8; + Vec3s* points; + Vec3f sp30; + Vec3f sp24; + f32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Demo_Syoten/func_80C17690.s") + if (path != NULL) { + points = Lib_SegmentedToVirtual(this->unk_3E8->points); + points += this->unk_3EC; + Math_Vec3s_ToVec3f(&sp30, points); + Actor_GetProjectedPos(globalCtx, &sp30, &sp24, &sp20); + Math_Vec3f_Copy(&sp30, &this->actor.projectedPos); + sp30.z = sp30.y; + sp24.z = sp24.y; + this->actor.shape.rot.z = -Math_Vec3f_Yaw(&sp24, &sp30); + } +} + +void func_80C16974(f32 arg0) { + Vtx* vtx = Lib_SegmentedToVirtual(&object_syotenVtx_0018C0); + u8 sp20[3]; + s32 i; + + arg0 = CLAMP_MAX(arg0, 1.0f); + + sp20[0] = (s8)0.0f; + sp20[1] = (s8)(152.0f * arg0); + sp20[2] = (s8)(255.0f * arg0); + + for (i = 0; i < ARRAY_COUNT(D_80C177D0); i++, vtx++) { + vtx->v.cn[3] = sp20[D_80C177D0[i]]; + } +} + +void func_80C16A64(DemoSyoten* this, GlobalContext* globalCtx) { +} + +void func_80C16A74(DemoSyoten* this, GlobalContext* globalCtx) { + u16 temp_a0; + + func_80183DE0(&this->unk_144); + if (Cutscene_CheckActorAction(globalCtx, this->unk_3F0)) { + if ((globalCtx->csCtx.frames >= 160) && (globalCtx->csCtx.frames < 322)) { + func_800B9010(&this->actor, NA_SE_EV_IKANA_SOUL_LV - SFX_FLAG); + } else if (globalCtx->csCtx.frames == 322) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_IKANA_SOUL_TRANSFORM); + } + + temp_a0 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->action; + if (this->unk_3F2 != temp_a0) { + this->unk_3F2 = temp_a0; + switch (temp_a0) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + this->actor.draw = func_80C173B4; + this->unk_3D8 = 1.0f; + break; + + case 3: + break; + + case 4: + this->actor.draw = NULL; + break; + } + } + + if (temp_a0 == 3) { + if (this->unk_3D8 > 0.0125f) { + this->unk_3D8 -= 0.0125f; + if (this->actor.child != NULL) { + this->actor.child->home.rot.z = 0x14; + } + } else { + this->actor.draw = NULL; + if (this->actor.child != NULL) { + this->actor.child->home.rot.z = 0; + } + } + } + } else { + this->actor.draw = NULL; + } +} + +void func_80C16BD4(DemoSyoten* this, GlobalContext* globalCtx) { + s32 pad; + u16 temp_a0; + + if (Cutscene_CheckActorAction(globalCtx, this->unk_3F0)) { + temp_a0 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->action; + if (this->unk_3F2 != temp_a0) { + this->unk_3F2 = temp_a0; + switch (temp_a0) { + default: + this->actor.draw = NULL; + break; + + case 1: + case 2: + this->actor.draw = NULL; + Actor_SetScale(&this->actor, 0.0f); + break; + + case 3: + this->actor.draw = DemoSyoten_Draw; + this->unk_3E4 &= ~4; + this->unk_3E4 |= 1; + this->actor.shape.rot.z = 0; + break; + + case 4: + this->actor.draw = DemoSyoten_Draw; + func_80C16760(this, globalCtx); + this->unk_3E4 |= 4; + this->unk_3E4 &= ~1; + break; + } + } + + switch (temp_a0) { + case 3: + if (this->actor.scale.x < 0.05f) { + this->actor.scale.x += 0.000625f; + } + Actor_SetScale(&this->actor, this->actor.scale.x); + break; + + case 4: + this->actor.speedXZ = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->urot.z * + 0.005493164f; + if (this->unk_3EC < this->unk_3E8->count) { + if (func_80C16818(this)) { + this->unk_3EC++; + } + func_80C168D0(this, globalCtx); + } + break; + } + } else { + this->actor.draw = NULL; + } +} + +void func_80C16DD4(DemoSyoten* this, GlobalContext* globalCtx) { + s32 pad; + u16 temp_a0; + + if (Cutscene_CheckActorAction(globalCtx, this->unk_3F0)) { + temp_a0 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->action; + if (this->unk_3F2 != temp_a0) { + this->unk_3F2 = temp_a0; + switch (temp_a0) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + this->actor.draw = DemoSyoten_Draw; + this->unk_3E6 = -6; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_DM_FLYING_GOD_DASH); + break; + } + } + + if ((temp_a0 == 2) && (this->unk_3E6 < 40)) { + this->unk_3E6++; + } + } else { + this->actor.draw = NULL; + } +} + +void func_80C16EAC(DemoSyoten* this, GlobalContext* globalCtx) { + s32 pad; + u16 temp_a0; + + if (Cutscene_CheckActorAction(globalCtx, this->unk_3F0)) { + temp_a0 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->action; + if (this->unk_3F2 != temp_a0) { + this->unk_3F2 = temp_a0; + switch (temp_a0) { + case 1: + this->actor.draw = NULL; + this->unk_3D8 = 0.0f; + Actor_SetScale(&this->actor, 0.5f); + break; + + case 2: + this->actor.draw = DemoSyoten_Draw; + break; + } + } + + if (temp_a0 == 2) { + if (this->actor.scale.x < 8.0f) { + this->actor.scale.x += 0.1875f; + } + + Actor_SetScale(&this->actor, this->actor.scale.x); + + if (this->unk_3D8 < 1.0f) { + this->unk_3D8 += 0.025f; + } + + if (this->unk_3D8 > 1.0f) { + this->unk_3D8 = 1.0f; + } + func_800B9010(&this->actor, NA_SE_EV_IKANA_PURIFICATION - SFX_FLAG); + } + } else { + this->actor.draw = NULL; + } + func_80C16974(this->unk_3D8); +} + +void func_80C17008(DemoSyoten* this, GlobalContext* globalCtx) { + u16 temp_a0; + + if (Cutscene_CheckActorAction(globalCtx, this->unk_3F0)) { + temp_a0 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_3F0)]->action; + if (this->unk_3F2 != temp_a0) { + this->unk_3F2 = temp_a0; + switch (temp_a0) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + this->actor.draw = func_80C17690; + this->unk_3E6 = -10; + break; + } + } + + if ((temp_a0 == 2) && (this->unk_3E6 < 15)) { + this->unk_3E6++; + } + } else { + this->actor.draw = NULL; + } +} + +void DemoSyoten_Update(Actor* thisx, GlobalContext* globalCtx) { + DemoSyoten* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 func_80C170F8(GlobalContext* globalCtx, UNK_TYPE arg1, s32 arg2, UNK_TYPE arg3, UNK_TYPE arg4, Actor* thisx) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + DemoSyoten* this = THIS; + + OPEN_DISPS(gfxCtx); + + switch (arg2) { + case 2: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 140, (s32)(this->unk_3D8 * 150.0f)); + break; + + case 4: + case 12: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 190, (s32)(this->unk_3D8 * 200.0f)); + break; + + case 6: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 150, (s32)(this->unk_3D8 * 150.0f)); + break; + + case 8: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 180, (s32)(this->unk_3D8 * 200.0f)); + break; + + case 10: + case 14: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 170, (s32)(this->unk_3D8 * 150.0f)); + break; + + case 16: + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 240, 160, (s32)(this->unk_3D8 * 200.0f)); + break; + } + + CLOSE_DISPS(gfxCtx); + return true; +} + +void func_80C173B4(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DemoSyoten* this = THIS; + Mtx* matrix; + + AnimatedMat_DrawXlu(globalCtx, Lib_SegmentedToVirtual(&object_syoten_Matanimheader_001298)); + + matrix = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * this->unk_144.unk_18->unk_1)); + + if (matrix != NULL) { + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + func_8018450C(globalCtx, &this->unk_144, matrix, (void*)func_80C170F8, 0, &this->actor); + } +} + +void func_80C17468(GlobalContext* globalCtx) { + Color_RGBA8 sp2C; + Color_RGBA8 sp28; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_800FE7A8(D_80C17824, &sp2C); + func_800FE7A8(D_80C17834, &sp28); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, sp2C.r, sp2C.g, sp2C.b, 255); + gDPSetEnvColor(POLY_XLU_DISP++, sp28.r, sp28.g, sp28.b, 255); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void DemoSyoten_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DemoSyoten* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + if (this->unk_3E4 & 4) { + Matrix_RotateZS(-this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Scale(1.0f, 5.0f, 1.0f, MTXMODE_APPLY); + } + + if (this->unk_3E4 & 1) { + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + } + + if (this->unk_3E4 & 8) { + func_80C17468(globalCtx); + } + + if (this->unk_3E0 != NULL) { + if (this->unk_3E4 & 2) { + AnimatedMat_DrawStepXlu(globalCtx, this->unk_3E0, this->unk_3E6); + } else { + AnimatedMat_DrawXlu(globalCtx, this->unk_3E0); + } + } + + if (this->unk_3DC != NULL) { + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, this->unk_3DC); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80C17690(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DemoSyoten* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), MTXMODE_APPLY); + + if (this->unk_3E4 & 8) { + func_80C17468(globalCtx); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + AnimatedMat_DrawStepXlu(globalCtx, this->unk_3E0, this->unk_3E6); + + gSPDisplayList(POLY_XLU_DISP++, object_syoten_DL_002880); + + AnimatedMat_DrawStepXlu(globalCtx, this->unk_3E0, this->unk_3E6 + 5); + + gSPDisplayList(POLY_XLU_DISP++, object_syoten_DL_002A20); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h index 26f9902eb..204243f47 100644 --- a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h +++ b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.h @@ -7,9 +7,33 @@ struct DemoSyoten; typedef void (*DemoSyotenActionFunc)(struct DemoSyoten*, GlobalContext*); +#define DEMOSYOTEN_GET_F(thisx) ((thisx)->params & 0xF) +#define DEMOSYOTEN_GET_7E00(thisx) (((thisx)->params & 0x7E00) >> 9) + +#define DEMOSYOTEN_7E00_3F 0x3F + +enum { + /* 0 */ DEMOSYOTEN_F_0, + /* 1 */ DEMOSYOTEN_F_1, + /* 2 */ DEMOSYOTEN_F_2, + /* 3 */ DEMOSYOTEN_F_3, + /* 4 */ DEMOSYOTEN_F_4 +}; + typedef struct DemoSyoten { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x2B0]; + /* 0x0144 */ SkeletonInfo unk_144; + /* 0x0174 */ Vec3s unk_174[51]; + /* 0x02A6 */ s16 unk_2A6[153]; + /* 0x03D8 */ f32 unk_3D8; + /* 0x03DC */ Gfx* unk_3DC; + /* 0x03E0 */ AnimatedMaterial* unk_3E0; + /* 0x03E4 */ u16 unk_3E4; + /* 0x03E6 */ s16 unk_3E6; + /* 0x03E8 */ Path* unk_3E8; + /* 0x03EC */ s32 unk_3EC; + /* 0x03F0 */ u16 unk_3F0; + /* 0x03F2 */ u16 unk_3F2; /* 0x03F4 */ DemoSyotenActionFunc actionFunc; } DemoSyoten; // size = 0x3F8 diff --git a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c index 32e38897a..060a201d7 100644 --- a/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c +++ b/src/overlays/actors/ovl_Demo_Tre_Lgt/z_demo_tre_lgt.c @@ -1,6 +1,12 @@ +/* + * File: z_demo_tre_lgt.c + * Overlay: ovl_Demo_Tre_Lgt + * Description: Light Radiating From Treasure Chest + */ + #include "z_demo_tre_lgt.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((DemoTreLgt*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Ah/z_dm_ah.c b/src/overlays/actors/ovl_Dm_Ah/z_dm_ah.c index ed3aae49d..ede7baa1d 100644 --- a/src/overlays/actors/ovl_Dm_Ah/z_dm_ah.c +++ b/src/overlays/actors/ovl_Dm_Ah/z_dm_ah.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_ah.c + * Overlay: ovl_Dm_Ah + * Description: Anju's Mother (cutscene) + */ + #include "z_dm_ah.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((DmAh*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Al/z_dm_al.c b/src/overlays/actors/ovl_Dm_Al/z_dm_al.c index 549cf52ca..d289b99ec 100644 --- a/src/overlays/actors/ovl_Dm_Al/z_dm_al.c +++ b/src/overlays/actors/ovl_Dm_Al/z_dm_al.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_al.c + * Overlay: ovl_Dm_Al + * Description: Madame Aroma (cutscene) + */ + #include "z_dm_al.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((DmAl*)thisx) diff --git a/src/overlays/actors/ovl_Dm_An/z_dm_an.c b/src/overlays/actors/ovl_Dm_An/z_dm_an.c index f780f8de3..19f7844ac 100644 --- a/src/overlays/actors/ovl_Dm_An/z_dm_an.c +++ b/src/overlays/actors/ovl_Dm_An/z_dm_an.c @@ -1,6 +1,14 @@ -#include "z_dm_an.h" +/* + * File: z_dm_an.c + * Overlay: ovl_Dm_An + * Description: Anju (cutscene) + */ -#define FLAGS 0x00000009 +#include "z_dm_an.h" +#include "objects/object_an4/object_an4.h" +#include "objects/object_msmo/object_msmo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((DmAn*)thisx) @@ -11,8 +19,8 @@ void DmAn_Update(Actor* thisx, GlobalContext* globalCtx); void func_80C1C958(DmAn* this, GlobalContext* globalCtx); void func_80C1CAB0(DmAn* this, GlobalContext* globalCtx); void func_80C1CC80(DmAn* this, GlobalContext* globalCtx); +void func_80C1D0B0(Actor* this, GlobalContext* globalCtx); -#if 0 const ActorInit Dm_An_InitVars = { ACTOR_DM_AN, ACTORCAT_NPC, @@ -25,37 +33,336 @@ const ActorInit Dm_An_InitVars = { (ActorFunc)NULL, }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_an1_Anim_007E08, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an1_Anim_0071E8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_006CC0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an1_Anim_013E1C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_007E3C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_0088C0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_0013C8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_002550, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_00353C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_004498, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_0060B4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_00041C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_004A78, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_00506C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern UNK_TYPE D_06000E70; -extern UNK_TYPE D_06012618; +s32 func_80C1C410(DmAn* this, GlobalContext* globalCtx) { + s8 objectIndex = this->actor.objBankIndex; + s8 objectIndex2; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C410.s") + if (this->unk_2C8 < 2) { + objectIndex2 = this->actor.objBankIndex; + } else { + objectIndex2 = this->unk_2AC; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C4D8.s") + if (objectIndex2 >= 0) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex2].segment); + ret = SkelAnime_Update(&this->skelAnime); + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex].segment); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C5B4.s") +s32 func_80C1C4D8(DmAn* this, GlobalContext* globalCtx, s32 arg2) { + s8 objectIndex = this->actor.objBankIndex; + s8 objectIndex2; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C62C.s") + if (arg2 < 2) { + objectIndex2 = this->actor.objBankIndex; + } else { + objectIndex2 = this->unk_2AC; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C83C.s") + if ((objectIndex2 >= 0) && (arg2 != this->unk_2C8)) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex2].segment); + this->unk_2C8 = arg2; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg2); + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex].segment); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C8E8.s") +void func_80C1C5B4(DmAn* this) { + if (DECR(this->unk_2BA) == 0) { + this->unk_2B8++; + if (this->unk_2B8 >= 4) { + this->unk_2BA = Rand_S16Offset(30, 30); + this->unk_2B8 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1C958.s") +s32 func_80C1C62C(DmAn* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1CAB0.s") + Math_Vec3f_Copy(&sp40, &this->unk_2B4->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1CC80.s") + Math_ApproachS(&this->unk_2C0, (sp32 - this->unk_2C4) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2C0 = CLAMP(this->unk_2C0, -0x1FFE, 0x1FFE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/DmAn_Init.s") + Math_ApproachS(&this->unk_2C4, (sp32 - this->unk_2C0) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2C4 = CLAMP(this->unk_2C4, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/DmAn_Destroy.s") + if (this->unk_2B4->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_2B4)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_2B4->focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/DmAn_Update.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + Math_ApproachS(&this->unk_2BE, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2C2, 4, 0x2AA8); + this->unk_2BE = CLAMP(this->unk_2BE, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1CD80.s") + Math_ApproachS(&this->unk_2C2, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2BE, 4, 0x2AA8); + this->unk_2C2 = CLAMP(this->unk_2C2, -0x1C70, 0x1C70); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1CEFC.s") +s32 func_80C1C83C(DmAn* this, GlobalContext* globalCtx) { + if (this->unk_2B4 != NULL) { + func_80C1C62C(this, globalCtx); + this->unk_2AE &= ~1; + this->unk_2AE |= 2; + } else if (this->unk_2AE & 2) { + this->unk_2AE &= ~2; + this->unk_2BE = 0; + this->unk_2C0 = 0; + this->unk_2C2 = 0; + this->unk_2C4 = 0; + this->unk_2BC = 20; + } else if (DECR(this->unk_2BC) == 0) { + this->unk_2AE |= 1; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_An/func_80C1D0B0.s") +Actor* func_80C1C8E8(GlobalContext* globalCtx) { + Actor* tempActor; + Actor* foundActor = NULL; + + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, ACTORCAT_NPC, ACTOR_DM_AH); + + if ((foundActor == NULL) || (foundActor->update != NULL)) { + break; + } + + tempActor = foundActor->next; + if (tempActor == NULL || NULL) { + foundActor = NULL; + break; + } + foundActor = tempActor; + } + return foundActor; +} + +void func_80C1C958(DmAn* this, GlobalContext* globalCtx) { + if ((this->unk_2AC >= 0) && SubS_IsObjectLoaded(this->unk_2AC, globalCtx) && (this->unk_2AD >= 0) && + SubS_IsObjectLoaded(this->unk_2AD, globalCtx)) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 14.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_an1_Skel_012618, NULL, this->jointTable, + this->morphTable, OBJECT_AN1_LIMB_MAX); + + this->unk_2C8 = -1; + func_80C1C4D8(this, globalCtx, 0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_SetScale(&this->actor, 0.01f); + this->unk_2AE |= 1; + this->actor.draw = func_80C1D0B0; + + if ((globalCtx->sceneNum == SCENE_YADOYA) && (globalCtx->curSpawn == 4)) { + this->unk_2B4 = func_80C1C8E8(globalCtx); + func_80C1C4D8(this, globalCtx, 1); + this->actionFunc = func_80C1CC80; + } else { + this->actionFunc = func_80C1CAB0; + } + } +} + +void func_80C1CAB0(DmAn* this, GlobalContext* globalCtx) { + s32 sp28[] = { 0, 0, 12, 2, 4, 6, 8, 10, 11, 3 }; + u16 action; + s32 sp20; + + if (globalCtx->csCtx.state != 0) { + if (this->unk_2D0 == 0) { + this->unk_2B0 = 255; + this->unk_2D0 = 1; + this->unk_2D4 = 0; + this->unk_2CC = this->unk_2C8; + } + + if (Cutscene_CheckActorAction(globalCtx, 0x22D)) { + sp20 = Cutscene_GetActorActionIndex(globalCtx, 0x22D); + action = globalCtx->csCtx.actorActions[sp20]->action; + + if (this->unk_2B0 != (action & 0xFF)) { + this->unk_2B0 = action; + this->unk_2D4 = 1; + func_80C1C4D8(this, globalCtx, sp28[action]); + } + + switch (this->unk_2B0) { + case 2: + case 4: + case 5: + case 6: + case 7: + case 8: + if ((this->unk_2C8 == 12) || (this->unk_2C8 == 4) || (this->unk_2C8 == 6) || (this->unk_2C8 == 8)) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80C1C4D8(this, globalCtx, this->unk_2C8 + 1); + } + } + break; + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, sp20); + } + } else if (this->unk_2D0 != 0) { + this->unk_2D0 = 0; + this->unk_2D4 = 0; + func_80C1C4D8(this, globalCtx, this->unk_2CC); + } +} + +void func_80C1CC80(DmAn* this, GlobalContext* globalCtx) { +} + +void DmAn_Init(Actor* thisx, GlobalContext* globalCtx) { + DmAn* this = THIS; + + this->unk_2AC = SubS_GetObjectIndex(OBJECT_AN4, globalCtx); + this->unk_2AD = SubS_GetObjectIndex(OBJECT_MSMO, globalCtx); + this->actionFunc = func_80C1C958; +} + +void DmAn_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void DmAn_Update(Actor* thisx, GlobalContext* globalCtx) { + DmAn* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80C1C83C(this, globalCtx); + + if (this->actor.draw != NULL) { + func_80C1C410(this, globalCtx); + func_80C1C5B4(this); + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); +} + +Vec3f D_80C1D2C8 = { 450.0f, 700.0f, -760.0f }; +Vec3s D_80C1D2D4 = { 0x238C, 0, -0x3FFC }; +Vec3f D_80C1D2DC = { 1000.0f, 0.0f, 0.0f }; + +void func_80C1CD80(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad[2]; + DmAn* this = THIS; + s8 sp2B = this->actor.objBankIndex; + s8 sp2A = this->unk_2AD; + + if ((limbIndex == OBJECT_AN1_LIMB_05) && (this->unk_2D4 != 0)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_TranslateRotateZYX(&D_80C1D2C8, &D_80C1D2D4); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[sp2A].segment); + gSPDisplayList(POLY_OPA_DISP++, gMoonMaskDL); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[sp2B].segment); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == OBJECT_AN1_LIMB_09) { + Matrix_MultVec3f(&D_80C1D2DC, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } +} + +void func_80C1CEFC(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + DmAn* this = THIS; + s16 stepRot; + s16 overrideRot; + + if (!(this->unk_2AE & 1)) { + if (this->unk_2AE & 2) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + stepRot = false; + overrideRot = false; + } + + if (limbIndex == OBJECT_AN1_LIMB_09) { + SubS_UpdateLimb(this->unk_2BE + this->unk_2C2 + 0x4000, + this->unk_2C0 + this->unk_2C4 + this->actor.shape.rot.y + 0x4000, &this->unk_18C, + &this->unk_1A4, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_18C.x, this->unk_18C.y, this->unk_18C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_1A4.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1A4.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1A4.z, MTXMODE_APPLY); + Matrix_Push(); + } else if (limbIndex == OBJECT_AN1_LIMB_02) { + SubS_UpdateLimb(this->unk_2C2 + 0x4000, this->unk_2C4 + this->actor.shape.rot.y + 0x4000, &this->unk_194, + &this->unk_1AA, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_194.x, this->unk_194.y, this->unk_194.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_1AA.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1AA.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1AA.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +TexturePtr D_80C1D2E8[] = { + object_an1_Tex_00E6E0, + object_an1_Tex_00F7A0, + object_an1_Tex_0101A0, +}; + +TexturePtr D_80C1D2F4[] = { + object_an1_Tex_00E1E0, object_an1_Tex_00EFA0, object_an1_Tex_00F3A0, object_an1_Tex_00EFA0, + object_an1_Tex_00FDA0, object_an1_Tex_00F9A0, object_an1_Tex_0103A0, +}; + +void func_80C1D0B0(Actor* thisx, GlobalContext* globalCtx) { + DmAn* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C1D2F4[this->unk_2B8])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C1D2E8[0])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, func_80C1CD80, func_80C1CEFC, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Dm_An/z_dm_an.h b/src/overlays/actors/ovl_Dm_An/z_dm_an.h index 70fcaa852..1b2b6f354 100644 --- a/src/overlays/actors/ovl_Dm_An/z_dm_an.h +++ b/src/overlays/actors/ovl_Dm_An/z_dm_an.h @@ -2,6 +2,7 @@ #define Z_DM_AN_H #include "global.h" +#include "objects/object_an1/object_an1.h" struct DmAn; @@ -9,9 +10,30 @@ typedef void (*DmAnActionFunc)(struct DmAn*, GlobalContext*); typedef struct DmAn { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ DmAnActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x14C]; + /* 0x018C */ Vec3f unk_18C; + /* 0x018C */ Vec3f unk_194; + /* 0x01A4 */ Vec3s unk_1A4; + /* 0x01A4 */ Vec3s unk_1AA; + /* 0x01B0 */ Vec3s jointTable[OBJECT_AN1_LIMB_MAX]; + /* 0x022E */ Vec3s morphTable[OBJECT_AN1_LIMB_MAX]; + /* 0x02AC */ s8 unk_2AC; + /* 0x02AD */ s8 unk_2AD; + /* 0x02AE */ u16 unk_2AE; + /* 0x02B0 */ u8 unk_2B0; + /* 0x02B4 */ Actor* unk_2B4; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA; + /* 0x02BC */ s16 unk_2BC; + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C2 */ s16 unk_2C2; + /* 0x02C4 */ s16 unk_2C4; + /* 0x02C8 */ s32 unk_2C8; + /* 0x02CC */ s32 unk_2CC; + /* 0x02D0 */ s32 unk_2D0; + /* 0x02D4 */ s32 unk_2D4; } DmAn; // size = 0x2D8 extern const ActorInit Dm_An_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Bal/z_dm_bal.c b/src/overlays/actors/ovl_Dm_Bal/z_dm_bal.c index 76b41dbc6..aa4abb91d 100644 --- a/src/overlays/actors/ovl_Dm_Bal/z_dm_bal.c +++ b/src/overlays/actors/ovl_Dm_Bal/z_dm_bal.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_bal.c + * Overlay: ovl_Dm_Bal + * Description: Tingle (cutscene) + */ + #include "z_dm_bal.h" -#define FLAGS 0x02000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((DmBal*)thisx) 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 43e140a51..ce9f844d0 100644 --- a/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c +++ b/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c @@ -1,6 +1,14 @@ -#include "z_dm_char00.h" +/* + * File: z_dm_char00.c + * Overlay: ovl_Dm_Char00 + * Description: Tatl and Tael (cutscene) + */ -#define FLAGS 0x00000030 +#include "z_dm_char00.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_delf/object_delf.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar00*)thisx) @@ -9,7 +17,9 @@ void DmChar00_Destroy(Actor* thisx, GlobalContext* globalCtx); void DmChar00_Update(Actor* thisx, GlobalContext* globalCtx); void DmChar00_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80AA67F8(DmChar00* this, GlobalContext* globalCtx); +void func_80AA695C(DmChar00* this, GlobalContext* globalCtx); + const ActorInit Dm_Char00_InitVars = { ACTOR_DM_CHAR00, ACTORCAT_ITEMACTION, @@ -22,56 +32,921 @@ const ActorInit Dm_Char00_InitVars = { (ActorFunc)DmChar00_Draw, }; -#endif +static AnimationInfo sAnimations[] = { + { &gameplay_keep_Anim_02B2E8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &gameplay_keep_Anim_029140, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_004FF4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0053A4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_005B68, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_006328, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00FB30, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_010590, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_005B68, 1.0f, 37.0f, 56.0f, 4, 0.0f }, + { &object_delf_Anim_006328, 1.0f, 37.0f, 56.0f, 4, 0.0f }, + { &object_delf_Anim_00E024, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00F0D0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_011C70, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_011FE0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_011088, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0118FC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_012388, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_012738, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_013BE0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_013E80, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_007B04, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0080A4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00859C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_008A44, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00EB18, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00EBB0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00EE30, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_012BBC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_012EF8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00C248, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00C588, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00BDFC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00C0BC, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_013040, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_013378, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_0091BC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0094B0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_009C4C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_009F40, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_009010, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0097C4, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00A7B4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00C588, 1.0f, 0.0f, -1.0f, 0, -10.0f }, + { &object_delf_Anim_004FF4, 1.0f, 0.0f, -1.0f, 2, -10.0f }, + { &object_delf_Anim_011C70, 1.0f, 0.0f, -1.0f, 0, -10.0f }, + { &object_delf_Anim_006B28, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_014190, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_01447C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_003FAC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_004798, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_0042E8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_004C44, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_01088C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_01498C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_014E9C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00CEE0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00D260, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00C690, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00C790, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00AF78, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00B2B8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00BCD8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_006D74, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00706C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_0072B0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_007570, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00A2A4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00A4B4, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_006614, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_015114, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00CCD4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00046C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_00065C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00377C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_003148, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_001410, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_0010F8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_00199C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_003BB4, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_001754, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_0008E0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_000A94, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_001ED4, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &object_delf_Anim_001B28, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &object_delf_Anim_000E44, 1.0f, 0.0f, -1.0f, 0, 0.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5580.s") +DmChar00Struct D_80AA77A8[] = { + { 250.0f, 255.0f, 230.0f, 255.0f }, + { 63.0f, 18.0f, 93.0f, 255.0f }, + { 255.0f, 235.0f, 220.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA561C.s") +DmChar00Struct D_80AA77D8[] = { + { 220.0f, 160.0f, 80.0f, 255.0f }, + { 250.0f, 40.0f, 10.0f, 255.0f }, + { 255.0f, 235.0f, 220.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5720.s") +Vec3f D_80AA7808 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA575C.s") +void func_80AA5580(SkelAnime* skelAnime, AnimationInfo* animation, u16 idx) { + f32 phi_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5890.s") + animation += idx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA58CC.s") + if (animation->frameCount < 0.0f) { + phi_f2 = Animation_GetLastFrame(animation->animation); + } else { + phi_f2 = animation->frameCount; + } + Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, phi_f2, + animation->mode, animation->morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5950.s") +void func_80AA561C(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames + 20) { + case 503: + case 926: + case 979: + case 1222: + case 1682: + case 2194: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5960.s") + case 1858: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_ATTACK); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA59E4.s") + case 2043: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + break; + } + } else { + switch (globalCtx->csCtx.frames + 20) { + case 503: + case 926: + case 979: + case 1234: + case 1687: + case 2194: + case 2210: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5A6C.s") + case 2043: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONDO_SURPRISE); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5AF4.s") +void func_80AA5720(DmChar00* this, GlobalContext* globalCtx) { + if ((DMCHAR00_GET(&this->actor) == DMCHAR00_0) && (globalCtx->csCtx.frames == 505)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SPOT_LIGHT_OPEN); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5BF8.s") +void func_80AA575C(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 474: + case 489: + case 495: + case 505: + case 854: + case 860: + case 866: + case 872: + case 877: + case 882: + case 887: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_ATTACK); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5CD4.s") + case 520: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BELL_SPIT); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5D10.s") + case 774: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5D6C.s") + case 904: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BELL_SIGH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5DC8.s") + case 813: + case 972: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BELL_BRAKE); + break; + } + } else if (globalCtx->csCtx.frames == 660) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONDO_SURPRISE); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5E2C.s") +void func_80AA5890(DmChar00* this, GlobalContext* globalCtx) { + if ((DMCHAR00_GET(&this->actor) == DMCHAR00_0) && (globalCtx->csCtx.frames == 20)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA5EBC.s") +void func_80AA58CC(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + if (globalCtx->csCtx.frames == 568) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + } + } else { + switch (globalCtx->csCtx.frames) { + case 375: + case 479: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/DmChar00_Init.s") + case 534: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_ATTACK); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/DmChar00_Destroy.s") +void func_80AA5950(DmChar00* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA62FC.s") +void func_80AA5960(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + if (globalCtx->csCtx.frames == 280) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + } + } else { + switch (globalCtx->csCtx.frames) { + case 87: + case 190: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA67F8.s") + case 244: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_ATTACK); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA695C.s") +void func_80AA59E4(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 125: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/DmChar00_Update.s") + case 1832: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_WHITE_OUT_INTO_MOON); + break; + } + } else if (globalCtx->csCtx.frames == 125) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/func_80AA6A6C.s") +void func_80AA5A6C(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 44: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char00/DmChar00_Draw.s") + case 891: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_WHITE_OUT_INTO_MOON); + break; + } + } else if (globalCtx->csCtx.frames == 44) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + } +} + +void func_80AA5AF4(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 352: + case 401: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + + case 440: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + + case 550: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BELL_BRAKE); + break; + } + } else { + switch (globalCtx->csCtx.frames) { + case 362: + case 401: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; + + case 454: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; + } + + if ((globalCtx->csCtx.frames >= 500) && (globalCtx->csCtx.frames < 602)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SHIVER - SFX_FLAG); + } + } +} + +void func_80AA5BF8(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 762: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_SHOT_DASH); + break; + case 797: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + } + } else { + switch (globalCtx->csCtx.frames) { + case 762: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_SHOT_DASH); + break; + + case 797: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; + } + } + + if ((this->unk_261 == 53) && Animation_OnFrame(&this->skelAnime, 16.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + } +} + +void func_80AA5CD4(DmChar00* this, GlobalContext* globalCtx) { + if ((DMCHAR00_GET(&this->actor) != DMCHAR00_0) && (globalCtx->csCtx.frames == 467)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + } +} + +void func_80AA5D10(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 8: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + break; + + case 130: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_NAVY_VANISH); + break; + } + } +} + +void func_80AA5D6C(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 2: + case 166: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + + case 31: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_SURPRISE); + break; + } + } +} + +void func_80AA5DC8(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_0) { + switch (globalCtx->csCtx.frames) { + case 233: + case 415: + case 593: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + + case 130: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_NAVY_VANISH); + break; + } + } +} + +void func_80AA5E2C(DmChar00* this, GlobalContext* globalCtx) { + if (DMCHAR00_GET(&this->actor) == DMCHAR00_1) { + switch (globalCtx->csCtx.frames) { + case 32: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + break; + + case 42: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BLACK_FAIRY_DASH); + break; + + case 192: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BELL_BRAKE); + break; + + case 215: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_INTO_WEED); + break; + } + } +} + +void func_80AA5EBC(DmChar00* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != 0) { + switch (globalCtx->sceneNum) { + case SCENE_LOST_WOODS: + if (gSaveContext.sceneSetupIndex == 1) { + func_80AA561C(this, globalCtx); + } + break; + + case SCENE_OPENINGDAN: + if (gSaveContext.sceneSetupIndex == 0) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA5720(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA575C(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 2) { + func_80AA5890(this, globalCtx); + } + } + break; + + case SCENE_OKUJOU: + if (gSaveContext.sceneSetupIndex == 0) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA58CC(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA5950(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 2) { + func_80AA5960(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 2) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA59E4(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA5A6C(this, globalCtx); + } + } + break; + + case SCENE_00KEIKOKU: + if (gSaveContext.sceneSetupIndex == 3) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA5AF4(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 2) { + func_80AA5E2C(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 7) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA5BF8(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA5CD4(this, globalCtx); + } + } + break; + + case SCENE_MITURIN: + if ((gSaveContext.sceneSetupIndex == 0) && (globalCtx->csCtx.currentCsIndex == 1)) { + func_80AA5DC8(this, globalCtx); + } + break; + + case SCENE_INSIDETOWER: + if ((gSaveContext.sceneSetupIndex == 0) && (globalCtx->csCtx.currentCsIndex == 0)) { + func_80AA5D10(this, globalCtx); + } + break; + + case SCENE_PIRATE: + if ((gSaveContext.sceneSetupIndex == 0) && (globalCtx->csCtx.currentCsIndex == 0)) { + func_80AA5D6C(this, globalCtx); + } + break; + } + } +} + +void DmChar00_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DmChar00* this = THIS; + + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && !Cutscene_IsPlaying(globalCtx)) { + Actor_MarkForDeath(thisx); + } + + this->unk_240 = D_80AA77A8[DMCHAR00_GET(thisx)]; + this->unk_250 = D_80AA77D8[DMCHAR00_GET(thisx)]; + + thisx->targetArrowOffset = 3000.0f; + this->unk_260 = 99; + this->unk_262 = DMCHAR00_GET_F800(thisx); + + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gameplay_keep_Skel_02AF58.sh, &gameplay_keep_Anim_029140, + this->jointTable, this->morphTable, 7); + ActorShape_Init(&thisx->shape, 0.0f, NULL, 15.0f); + func_80AA5580(&this->skelAnime, sAnimations, 0); + Actor_SetScale(thisx, 0.01f); + this->actionFunc = func_80AA67F8; +} + +void DmChar00_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void func_80AA62FC(DmChar00* this, GlobalContext* globalCtx) { + u16 sp26 = DMCHAR00_GET(&this->actor) + 113; + s32 temp_v0; + s32 pad; + + if (Cutscene_CheckActorAction(globalCtx, sp26)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, sp26); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[temp_v0]->startFrame) { + if (this->unk_260 != globalCtx->csCtx.actorActions[temp_v0]->action) { + this->unk_260 = globalCtx->csCtx.actorActions[temp_v0]->action; + + switch (globalCtx->csCtx.actorActions[temp_v0]->action) { + case 0x1: + this->unk_261 = 0; + break; + + case 0x2: + this->unk_261 = 2; + break; + + case 0x3: + this->unk_261 = 3; + break; + + case 0x4: + this->unk_261 = 4; + break; + + case 0x5: + this->unk_261 = 5; + break; + + case 0x6: + this->unk_261 = 6; + break; + + case 0x7: + this->unk_261 = 7; + break; + + case 0x8: + this->unk_261 = 20; + break; + + case 0x9: + this->unk_261 = 21; + break; + + case 0xA: + this->unk_261 = 14; + break; + + case 0xB: + this->unk_261 = 15; + break; + + case 0xC: + this->unk_261 = 18; + break; + + case 0xD: + this->unk_261 = 25; + break; + + case 0xE: + this->unk_261 = 27; + break; + + case 0xF: + this->unk_261 = 24; + break; + + case 0x10: + this->unk_261 = 10; + break; + + case 0x11: + this->unk_261 = 12; + break; + + case 0x12: + this->unk_261 = 13; + break; + + case 0x13: + this->unk_261 = 29; + break; + + case 0x14: + this->unk_261 = 31; + break; + + case 0x15: + this->unk_261 = 33; + break; + + case 0x16: + Actor_MarkForDeath(&this->actor); + break; + + case 0x17: + this->unk_261 = 35; + break; + + case 0x18: + this->unk_261 = 37; + break; + + case 0x19: + this->unk_261 = 39; + break; + + case 0x1A: + this->unk_261 = 41; + break; + + case 0x1B: + this->unk_261 = 45; + break; + + case 0x1C: + this->unk_261 = 46; + break; + + case 0x1E: + this->unk_261 = 48; + break; + + case 0x1F: + this->unk_261 = 50; + break; + + case 0x20: + this->unk_261 = 52; + break; + + case 0x21: + this->unk_261 = 53; + break; + + case 0x23: + this->unk_261 = 55; + break; + + case 0x24: + this->unk_261 = 57; + break; + + case 0x25: + this->unk_261 = 58; + break; + + case 0x26: + this->unk_261 = 59; + break; + + case 0x27: + this->unk_261 = 61; + break; + + case 0x28: + this->unk_261 = 62; + break; + + case 0x29: + this->unk_261 = 64; + break; + + case 0x2A: + this->unk_261 = 66; + break; + + case 0x2B: + this->unk_261 = 68; + break; + + case 0x2C: + this->unk_261 = 69; + break; + + case 0x2D: + this->unk_261 = 70; + break; + + case 0x2E: + this->unk_261 = 67; + break; + + case 0x2F: + this->unk_261 = 71; + break; + + case 0x30: + this->unk_261 = 73; + break; + + case 0x31: + this->unk_261 = 74; + break; + + case 0x32: + this->unk_261 = 75; + break; + + case 0x33: + this->unk_261 = 77; + break; + + case 0x34: + this->unk_261 = 78; + break; + + case 0x35: + this->unk_261 = 79; + break; + + case 0x36: + this->unk_261 = 80; + break; + + case 0x37: + this->unk_261 = 82; + break; + + case 0x38: + this->unk_261 = 83; + break; + + default: + this->unk_261 = 0; + break; + } + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + } + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, temp_v0); + } else { + this->unk_260 = 99; + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->unk_261) { + case 0x4: + case 0x5: + this->unk_261 += 4; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + this->skelAnime.curFrame = 37.0f; + break; + + case 0xE: + case 0xF: + case 0x14: + case 0x15: + this->unk_261 += 2; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + break; + + case 0xA: + case 0x12: + case 0x19: + case 0x1B: + case 0x1D: + case 0x1F: + case 0x21: + case 0x23: + case 0x25: + case 0x27: + case 0x2B: + case 0x2E: + case 0x30: + case 0x32: + case 0x35: + case 0x37: + case 0x3B: + case 0x3E: + case 0x40: + case 0x42: + case 0x47: + case 0x4B: + case 0x50: + case 0x53: + this->unk_261 += 1; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + break; + + case 0x2D: + this->unk_261 = 19; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + break; + + case 0x46: + case 0x4D: + this->unk_261 = 0; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + break; + } + } +} + +void func_80AA67F8(DmChar00* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((globalCtx->csCtx.state == 0) && (gSaveContext.sceneSetupIndex == 0) && + (globalCtx->csCtx.currentCsIndex == 1)) { + if (this->unk_261 != 42) { + this->unk_261 = 42; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + } + + Math_SmoothStepToF(&this->actor.world.pos.x, 0.0f, 0.5f, 0.5f, 0.001f); + Math_SmoothStepToF(&this->actor.world.pos.y, 30.0f, 0.5f, 0.5f, 0.001f); + Math_SmoothStepToF(&this->actor.world.pos.z, -560.0f, 0.5f, 20.0f, 0.001f); + + if (player->actor.world.pos.z < -625.0f) { + this->unk_261 = 43; + func_80AA5580(&this->skelAnime, &sAnimations[this->unk_261], 0); + this->actionFunc = func_80AA695C; + this->skelAnime.playSpeed = 1.5f; + } + } +} + +void func_80AA695C(DmChar00* this, GlobalContext* globalCtx) { + if (this->unk_261 == 44) { + Math_SmoothStepToF(&this->actor.world.pos.x, 0.0f, 0.5f, 0.5f, 0.001f); + Math_SmoothStepToF(&this->actor.world.pos.y, 30.0f, 0.5f, 0.5f, 0.001f); + Math_SmoothStepToF(&this->actor.world.pos.z, -680.0f, 0.5f, 10.0f, 0.001f); + } +} + +void DmChar00_Update(Actor* thisx, GlobalContext* globalCtx) { + DmChar00* this = THIS; + + SkelAnime_Update(&this->skelAnime); + + this->actionFunc(this, globalCtx); + + this->unk_262++; + func_80AA5EBC(this, globalCtx); + func_80AA62FC(this, globalCtx); +} + +s32 DmChar00_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + DmChar00* this = THIS; + f32 sp28; + Vec3f sp1C; + + if (limbIndex == 6) { + sp28 = ((Math_SinS(this->unk_262 * 0x1000) * 0.1f) + 1.0f) * 0.012f * (this->actor.scale.x * 124.99999f); + Matrix_MultVec3f(&D_80AA7808, &sp1C); + Matrix_Translate(sp1C.x, sp1C.y, sp1C.z, MTXMODE_NEW); + Matrix_Scale(sp28, sp28, sp28, MTXMODE_APPLY); + } + return false; +} + +void DmChar00_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DmChar00* this = THIS; + s32 phi_a0; + s32 pad; + Gfx* gfx = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 4); + + if ((globalCtx->csCtx.state == 0) && + ((globalCtx->sceneNum != SCENE_OPENINGDAN) || (gSaveContext.sceneSetupIndex != 0) || + (globalCtx->roomCtx.currRoom.num != 0) || (globalCtx->csCtx.currentCsIndex != 1) || + (DMCHAR00_GET(&this->actor) != DMCHAR00_0))) { + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C94C(globalCtx->state.gfxCtx); + + do { + phi_a0 = (this->unk_262 * 50) & 511; + if (phi_a0 >= 256) { + phi_a0 = 511 - phi_a0; + } + } while (0); + + gSPSegment(POLY_XLU_DISP++, 0x08, &gfx[0]); + + gDPPipeSync(gfx++); + gDPSetPrimColor(gfx++, 0, 0x01, (u8)this->unk_240.unk_00, (u8)this->unk_240.unk_04, (u8)this->unk_240.unk_08, + (u8)(this->unk_240.unk_0C * 1)); + gDPSetRenderMode(gfx++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + gSPEndDisplayList(gfx); + + gDPSetEnvColor(POLY_XLU_DISP++, (u8)(s8)this->unk_250.unk_00, (u8)(s8)this->unk_250.unk_04, + (u8)(s8)this->unk_250.unk_08, (u8)(s8)((f32)phi_a0 * 1)); + gDPSetDither(POLY_XLU_DISP++, G_CD_BAYER); + + POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + DmChar00_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.h b/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.h index 0bc9b9d0a..52adfe794 100644 --- a/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.h +++ b/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.h @@ -7,11 +7,32 @@ struct DmChar00; typedef void (*DmChar00ActionFunc)(struct DmChar00*, GlobalContext*); +#define DMCHAR00_GET(thisx) ((thisx)->params) +#define DMCHAR00_GET_F800(thisx) ((thisx)->params << 0xB) + +#define DMCHAR00_0 0 +#define DMCHAR00_1 1 + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; +} DmChar00Struct; // size = 0x10 + typedef struct DmChar00 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xF8]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[7]; + /* 0x01B2 */ UNK_TYPE1 unk_1B2[0x30]; + /* 0x01E2 */ Vec3s morphTable[7]; + /* 0x020C */ UNK_TYPE1 unk_20C[0x30]; /* 0x023C */ DmChar00ActionFunc actionFunc; - /* 0x0240 */ char unk_240[0x24]; + /* 0x0240 */ DmChar00Struct unk_240; + /* 0x0250 */ DmChar00Struct unk_250; + /* 0x0260 */ u8 unk_260; + /* 0x0261 */ u8 unk_261; + /* 0x0262 */ u16 unk_262; } DmChar00; // size = 0x264 extern const ActorInit Dm_Char00_InitVars; 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 22f51085b..375edda4a 100644 --- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c +++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c @@ -1,6 +1,13 @@ -#include "z_dm_char01.h" +/* + * File: z_dm_char01.c + * Overlay: ovl_Dm_Char01 + * Description: Woodfall scene objects (temple, water, walls, etc) + */ -#define FLAGS 0x02000030 +#include "z_dm_char01.h" +#include "objects/object_mtoride/object_mtoride.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((DmChar01*)thisx) @@ -9,7 +16,24 @@ void DmChar01_Destroy(Actor* thisx, GlobalContext* globalCtx); void DmChar01_Update(Actor* thisx, GlobalContext* globalCtx); void DmChar01_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80AA8698(DmChar01* this, GlobalContext* globalCtx); +void func_80AA884C(DmChar01* this, GlobalContext* globalCtx); +void func_80AA88A8(DmChar01* this, GlobalContext* globalCtx); +void func_80AA892C(DmChar01* this, GlobalContext* globalCtx); +void func_80AA8C28(DmChar01* this, GlobalContext* globalCtx); +void func_80AA8F1C(DmChar01* this, GlobalContext* globalCtx); +void func_80AA8F2C(DmChar01* this, GlobalContext* globalCtx); +void func_80AA9020(DmChar01* this, GlobalContext* globalCtx); +void func_80AA90AC(DmChar01* this, GlobalContext* globalCtx); +void func_80AA90F4(DmChar01* this, GlobalContext* globalCtx); + +s16 D_80AAAE20; +s16 D_80AAAE22; +s16 D_80AAAE24; +s16 D_80AAAE26; + +#include "overlays/ovl_Dm_Char01/ovl_Dm_Char01.c" + const ActorInit Dm_Char01_InitVars = { ACTOR_DM_CHAR01, ACTORCAT_ITEMACTION, @@ -22,44 +46,501 @@ const ActorInit Dm_Char01_InitVars = { (ActorFunc)DmChar01_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AAAAB0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 300, ICHAIN_STOP), }; -#endif +s16 D_80AAAAB4 = false; -extern InitChainEntry D_80AAAAB0[]; +void DmChar01_Init(Actor* thisx, GlobalContext* globalCtx) { + DmChar01* this = THIS; + s32 i; -extern UNK_TYPE D_06009E4C; -extern UNK_TYPE D_0600AA50; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, 1.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/DmChar01_Init.s") + this->unk_346 = 0; + this->unk_34D = false; + D_80AAAE24 = 0; + D_80AAAE26 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/DmChar01_Destroy.s") + switch (DMCHAR01_GET(&this->dyna.actor)) { + case DMCHAR01_0: + if (gSaveContext.save.weekEventReg[20] & 2) { + this->unk_34C = 2; + this->actionFunc = func_80AA8F1C; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA8698.s") + if (gSaveContext.sceneSetupIndex == 0) { + globalCtx->envCtx.unk_1F = 5; + globalCtx->envCtx.unk_20 = 5; + } + this->unk_348 = 255.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA884C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_1AC); i++) { + this->unk_1AC[i] = ovl_dm_char01_Vtx_1BE0[i].v.ob[1] * 409.6f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA88A8.s") + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_mtoride_Colheader_009E4C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA892C.s") + this->unk_34D = true; + if (gSaveContext.sceneSetupIndex == 1) { + this->unk_34C = 1; + this->actionFunc = func_80AA8C28; + } else { + this->unk_34C = 0; + this->actionFunc = func_80AA892C; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA8C28.s") + case DMCHAR01_1: + if ((gSaveContext.save.weekEventReg[20] & 2) || (gSaveContext.sceneSetupIndex == 1)) { + this->unk_34C = 1; + this->actionFunc = func_80AA8F1C; + } else { + this->actionFunc = func_80AA8698; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA8F0C.s") + case DMCHAR01_2: + this->unk_34C = 0; + if (!(gSaveContext.save.weekEventReg[20] & 1)) { + this->unk_34C = 1; + this->dyna.actor.world.pos.y -= 400.0f; + } + this->dyna.actor.world.rot.y += 0x8000; + this->dyna.actor.shape.rot.y += 0x8000; + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_mtoride_Colheader_010C3C); + this->unk_34D = true; + this->unk_348 = 200.0f; + this->actionFunc = func_80AA8F2C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA8F1C.s") + case DMCHAR01_3: + this->dyna.actor.world.rot.y += 0x8000; + this->dyna.actor.shape.rot.y += 0x8000; + if (!(gSaveContext.save.weekEventReg[20] & 1)) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA8F2C.s") + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, 0x80); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_mtoride_Colheader_00FE5C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA9020.s") + this->unk_34D = true; + if (!(gSaveContext.save.weekEventReg[20] & 2)) { + this->actionFunc = func_80AA9020; + this->dyna.actor.world.pos.y -= 120.0f; + } else { + this->actionFunc = func_80AA8F1C; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA90AC.s") + default: + this->actionFunc = func_80AA88A8; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/func_80AA90F4.s") +void DmChar01_Destroy(Actor* thisx, GlobalContext* globalCtx) { + DmChar01* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/DmChar01_Update.s") + if (this->unk_34D) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char01/DmChar01_Draw.s") +void func_80AA8698(DmChar01* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Player* player2 = GET_PLAYER(globalCtx); + + if (gSaveContext.save.weekEventReg[20] & 1) { + return; + } + + if ((player->stateFlags2 & 0x8000000) && (player2->actor.world.pos.x > -40.0f) && + (player2->actor.world.pos.x < 40.0f) && (player2->actor.world.pos.z > 1000.0f) && + (player2->actor.world.pos.z < 1078.0f)) { + if (!D_80AAAAB4) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + D_80AAAAB4 = true; + } + } else { + D_80AAAAB4 = false; + } + + if ((player->transformation == PLAYER_FORM_DEKU) && (globalCtx->msgCtx.ocarinaMode == 3) && + (globalCtx->msgCtx.unk1202E == 0)) { + + if ((player2->actor.world.pos.x > -40.0f) && (player2->actor.world.pos.x < 40.0f) && + (player2->actor.world.pos.z > 1000.0f) && (player2->actor.world.pos.z < 1078.0f)) { + gSaveContext.save.weekEventReg[20] |= 1; + this->actionFunc = func_80AA884C; + } + } +} + +void func_80AA884C(DmChar01* this, GlobalContext* globalCtx) { + s16 sp1E = this->dyna.actor.cutscene; + + if (ActorCutscene_GetCanPlayNext(sp1E)) { + ActorCutscene_Start(sp1E, &this->dyna.actor); + this->actionFunc = func_80AA88A8; + } else { + ActorCutscene_SetIntentToPlay(sp1E); + } +} + +void func_80AA88A8(DmChar01* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 135)) { + if (globalCtx->csCtx.frames == + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 135)]->startFrame) { + D_80AAAE24 = 1; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FORT_RISING); + } + } else { + D_80AAAE24 = 0; + } +} + +void func_80AA892C(DmChar01* this, GlobalContext* globalCtx) { + f32 temp_f18; + s32 temp_v0_4; + s32 i; + + switch (this->unk_346) { + case 0: + D_80AAAE22 = -2200; + D_80AAAE20 = 380; + this->unk_346++; + break; + + case 1: + if (D_80AAAE24 != 0) { + this->unk_34C = 1; + if (D_80AAAE22 > -2000) { + D_80AAAE26 = 1; + } + + D_80AAAE22 += 40; + if (D_80AAAE22 > 3400) { + if (D_80AAAE20 > 100) { + D_80AAAE20 -= 230; + } + this->unk_346++; + } + } + break; + + case 2: + D_80AAAE22 -= 40; + if (D_80AAAE22 <= -2200) { + if (D_80AAAE20 > 100) { + D_80AAAE20 -= 70; + } + this->unk_346--; + } + break; + } + + if (D_80AAAE24 == 0) { + this->unk_34C = 0; + } + + for (i = 0; i < ARRAY_COUNT(ovl_dm_char01_Vtx_1BE0); i++) { + s32 temp_s2 = sqrtf(SQ((f32)ovl_dm_char01_Vtx_1BE0[i].v.ob[2]) + SQ((f32)ovl_dm_char01_Vtx_1BE0[i].v.ob[0])); + f32 cos = Math_CosS((temp_s2 / 1892.0f) * 0x4000); + f32 temp_f20 = (1.0f - (ABS_ALT(temp_s2 - D_80AAAE22) / 1892.0f)) * D_80AAAE20 * cos; + + if (temp_f20 < 0.0f) { + temp_f20 = 0.0f; + } + + temp_f18 = Math_SinS(this->unk_1AC[i]) * 15.0f; + temp_f20 += temp_f18; + + this->unk_1AC[i] += 1600; + ovl_dm_char01_Vtx_1BE0[i].v.ob[1] = temp_f20; + } +} + +void func_80AA8C28(DmChar01* this, GlobalContext* globalCtx) { + f32 temp_f18; + s32 temp_v0_4; + s32 i; + + switch (this->unk_346) { + case 0: + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WATER_PURIFICATION); + D_80AAAE22 = -2200; + D_80AAAE20 = 100; + this->unk_346++; + break; + + case 1: + D_80AAAE22 += 40; + if (D_80AAAE22 > 3400) { + this->unk_346++; + } + break; + + case 2: + D_80AAAE22 -= 40; + if (D_80AAAE22 <= -2200) { + this->unk_346--; + } + break; + } + + for (i = 0; i < ARRAY_COUNT(ovl_dm_char01_Vtx_1BE0); i++) { + s32 temp_s2 = sqrtf(SQ((f32)ovl_dm_char01_Vtx_1BE0[i].v.ob[2]) + SQ((f32)ovl_dm_char01_Vtx_1BE0[i].v.ob[0])); + f32 cos = Math_CosS((temp_s2 / 1892.0f) * 0x4000); + f32 temp_f20 = (1.0f - (ABS_ALT(temp_s2 - D_80AAAE22) / 1892.0f)) * D_80AAAE20 * cos; + + if (temp_f20 < 0.0f) { + temp_f20 = 0.0f; + } + + temp_f18 = Math_SinS(this->unk_1AC[i]) * 15.0f; + temp_f20 += temp_f18; + + this->unk_1AC[i] += 1600; + ovl_dm_char01_Vtx_1BE0[i].v.ob[1] = temp_f20; + } + + Math_SmoothStepToF(&this->unk_348, 0.0f, 0.02f, 0.6f, 0.4f); + + if (this->unk_348 < 0.01f) { + this->unk_34C = 2; + this->actionFunc = func_80AA8F1C; + } +} + +void func_80AA8F0C(DmChar01* this, GlobalContext* globalCtx) { +} + +void func_80AA8F1C(DmChar01* this, GlobalContext* globalCtx) { +} + +void func_80AA8F2C(DmChar01* this, GlobalContext* globalCtx) { + if (D_80AAAE26 != 0) { + Math_SmoothStepToF(&this->dyna.actor.world.pos.y, 0.0f, 0.05f, 6.0f, 0.001f); + Math_SmoothStepToF(&this->unk_348, 0.0f, 0.01f, 0.5f, 0.4f); + if ((s32)this->dyna.actor.world.pos.y >= 0) { + D_80AAAE26 = 2; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ETCETERA, 5.0f, 202.0f, 294.0f, 0, 0, 0, 0x80); + this->actionFunc = func_80AA90F4; + } + } + func_80AA8F0C(this, globalCtx); +} + +void func_80AA9020(DmChar01* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 135)) { + CsCmdActorAction* temp_v1 = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 135)]; + + if ((temp_v1->startFrame == globalCtx->csCtx.frames) && (temp_v1->action == 2)) { + gSaveContext.save.weekEventReg[20] |= 2; + this->actionFunc = func_80AA90AC; + } + } +} + +void func_80AA90AC(DmChar01* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->dyna.actor.world.pos.y, 0.0f, 0.05f, 2.0f, 0.001f); +} + +void func_80AA90F4(DmChar01* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->unk_348, 0.0f, 0.02f, 0.8f, 0.4f); +} + +void DmChar01_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DmChar01* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->unk_34D) { + if (DMCHAR01_GET(&this->dyna.actor) == DMCHAR01_0) { + Player* player = GET_PLAYER(globalCtx); + + if (player->actor.world.pos.y > 5.0f) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } else { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + } + + if (DMCHAR01_GET(&this->dyna.actor) == DMCHAR01_2) { + if (this->dyna.actor.xzDistToPlayer > 600.0f) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } else { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + } + } +} + +void DmChar01_Draw(Actor* thisx, GlobalContext* globalCtx) { + static f32 D_80AAAAB8 = 0.0f; + static f32 D_80AAAABC = 0.0f; + static s16 D_80AAAAC0 = 0; + static s16 D_80AAAAC4 = 0; + static s16 D_80AAAAC8 = 0; + static s16 D_80AAAACC = 0; + DmChar01* this = THIS; + f32 temp_f12; + f32 spBC; + s32 i; + u8 spB7 = false; + + switch (DMCHAR01_GET(thisx)) { + case DMCHAR01_0: + switch (this->unk_34C) { + case 0: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_00AA50)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_00A8F8); + break; + + case 1: + if (gSaveContext.sceneSetupIndex == 1) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_0110B8)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_010FD8); + Gfx_DrawDListXlu(globalCtx, object_mtoride_DL_010EF0); + Matrix_Translate(0.0f, 10.0f, 0.0f, MTXMODE_APPLY); + } + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_009D70)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((u8)this->unk_348 == 255) { + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x96, 255, 255, 255, 255); + gSPSegment(POLY_OPA_DISP++, 0x0B, Lib_SegmentedToVirtual(ovl_dm_char01_Vtx_1BE0)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_mtoride_DL_009928); + } else { + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x96, 255, 255, 255, (u8)this->unk_348); + gSPSegment(POLY_XLU_DISP++, 0x0B, Lib_SegmentedToVirtual(ovl_dm_char01_Vtx_1BE0)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_mtoride_DL_009928); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + break; + + case 2: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_0110B8)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_010FD8); + Gfx_DrawDListXlu(globalCtx, object_mtoride_DL_010EF0); + break; + } + break; + + case DMCHAR01_1: + switch (this->unk_34C) { + case 0: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_00A5C0)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_00A398); + break; + + case 1: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_00B1A0)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_00AF98); + break; + } + break; + + case DMCHAR01_2: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_00FE90)); + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_00DF18); + + if ((this->unk_34C != 0) && ((u8)this->unk_348 != 0)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_mtoride_Matanimheader_00F768)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)this->unk_348); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, (u8)this->unk_348); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_mtoride_DL_00F3C0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (D_80AAAE24 != 0) { + if ((D_80AAAE22 > -1800) && (D_80AAAE22 < 3000)) { + temp_f12 = D_80AAAE22 - 640.0f; + if ((D_80AAAE20 == 380) && (D_80AAAE22 > 640)) { + D_80AAAAC0 = 2; + D_80AAAAC4 = 0; + D_80AAAAC8 = 900; + D_80AAAACC = 700; + spB7 = true; + if (D_80AAAE22 < 1350) { + f32 temp_f0 = temp_f12 / 2000.0f; + + D_80AAAAB8 = 420.0f - (420.0f * temp_f0); + D_80AAAABC = (200.0f * temp_f0) + 200.0f; + } else { + f32 temp_f0 = temp_f12 / 2000.0f; + + D_80AAAAB8 = 420.0f - (420.0f * temp_f0); + D_80AAAABC = 400.0f; + } + } + } + + if (spB7) { + for (i = 0; i < D_80AAAAC0 * 2; i++) { + Vec3f sp44; + f32 phi_f2 = D_80AAAABC; + s16 temp; + + spBC = Rand_ZeroOne() * D_80AAAAC8; + if ((globalCtx->state.frames % 2) != 0) { + sp44.x = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2); + sp44.y = D_80AAAAB8; + sp44.z = (Rand_ZeroOne() * D_80AAAAC4) + phi_f2; + temp = (s16)spBC + D_80AAAACC; + EffectSsGSplash_Spawn(globalCtx, &sp44, NULL, NULL, 0, temp); + } else { + sp44.x = -phi_f2 - (Rand_ZeroOne() * D_80AAAAC4); + sp44.y = D_80AAAAB8; + sp44.z = (Rand_ZeroOne() - 0.5f) * (2.0f * phi_f2); + temp = (s16)spBC + D_80AAAACC; + EffectSsGSplash_Spawn(globalCtx, &sp44, NULL, NULL, 0, temp); + } + } + } + } + + Gfx_DrawDListXlu(globalCtx, object_mtoride_DL_00DE50); + break; + + case DMCHAR01_3: + if (thisx->world.pos.y > -120.0f) { + Gfx_DrawDListOpa(globalCtx, object_mtoride_DL_00FAE8); + } + break; + } +} diff --git a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.h b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.h index a0d4fb336..b2c235f56 100644 --- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.h +++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.h @@ -7,11 +7,25 @@ struct DmChar01; typedef void (*DmChar01ActionFunc)(struct DmChar01*, GlobalContext*); +#define DMCHAR01_GET(thisx) ((thisx)->params) + +enum { + /* 0 */ DMCHAR01_0, + /* 1 */ DMCHAR01_1, + /* 2 */ DMCHAR01_2, + /* 3 */ DMCHAR01_3, +}; + typedef struct DmChar01 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x5C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ UNK_TYPE1 unk15C[0x44]; /* 0x01A0 */ DmChar01ActionFunc actionFunc; - /* 0x01A4 */ char unk_1A4[0x1AC]; + /* 0x01A4 */ UNK_TYPE1 unk1A4[0x8]; + /* 0x01AC */ s16 unk_1AC[205]; + /* 0x0346 */ s16 unk_346; + /* 0x0348 */ f32 unk_348; + /* 0x034C */ u8 unk_34C; + /* 0x034D */ u8 unk_34D; } DmChar01; // size = 0x350 extern const ActorInit Dm_Char01_InitVars; 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 4f379784c..72258b70b 100644 --- a/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c +++ b/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char02.c + * Overlay: ovl_Dm_Char02 + * Description: Ocarina of Time (dropped from Skull Kid's hand) + */ + #include "z_dm_char02.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar02*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Char03/z_dm_char03.c b/src/overlays/actors/ovl_Dm_Char03/z_dm_char03.c index 5baff6c4a..1508f95a2 100644 --- a/src/overlays/actors/ovl_Dm_Char03/z_dm_char03.c +++ b/src/overlays/actors/ovl_Dm_Char03/z_dm_char03.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char03.c + * Overlay: ovl_Dm_Char03 + * Description: + */ + #include "z_dm_char03.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar03*)thisx) 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 698eba116..eff96b7e5 100644 --- a/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c +++ b/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char04.c + * Overlay: ovl_Dm_Char04 + * Description: Unused(?) Tatl and Tael actors + */ + #include "z_dm_char04.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar04*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.c b/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.c index 67d59b3cf..94935db3c 100644 --- a/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.c +++ b/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.c @@ -1,6 +1,13 @@ -#include "z_dm_char05.h" +/* + * File: z_dm_char05.c + * Overlay: ovl_Dm_Char05 + * Description: Cutscene mask objects + */ -#define FLAGS 0x00000030 +#include "z_dm_char05.h" +#include "objects/object_dmask/object_dmask.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar05*)thisx) @@ -22,8 +29,12 @@ void func_80AACD1C(DmChar05* this, GlobalContext* globalCtx); void func_80AACD68(DmChar05* this, GlobalContext* globalCtx); void func_80AACE10(DmChar05* this, GlobalContext* globalCtx); void func_80AACE5C(DmChar05* this, GlobalContext* globalCtx); +void func_80AADD9C(GlobalContext* globalCtx, DmChar05* this); +void func_80AADE78(GlobalContext* globalCtx, DmChar05* this); +void func_80AADF54(GlobalContext* globalCtx, DmChar05* this); +void func_80AAE030(GlobalContext* globalCtx, DmChar05* this); +void func_80AAE114(GlobalContext* globalCtx, DmChar05* this); -#if 0 const ActorInit Dm_Char05_InitVars = { ACTOR_DM_CHAR05, ACTORCAT_ITEMACTION, @@ -36,86 +47,742 @@ const ActorInit Dm_Char05_InitVars = { (ActorFunc)DmChar05_Draw, }; -#endif +static AnimationInfo sAnimations[] = { + { &object_dmask_Anim_001090, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dmask_Anim_004288, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dmask_Anim_0001A8, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dmask_Anim_00017C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dmask_Anim_0011A0, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dmask_Anim_0013A4, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, +}; -extern UNK_TYPE D_060001D0; -extern UNK_TYPE D_060010B0; -extern UNK_TYPE D_060013D0; -extern UNK_TYPE D_06001E70; -extern UNK_TYPE D_060042B0; +void func_80AAC5A0(SkelAnime* skelAnime, AnimationInfo* animation, u16 arg2) { + f32 phi_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC5A0.s") + animation += arg2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC63C.s") + if (animation->frameCount < 0.0f) { + phi_f2 = Animation_GetLastFrame(animation->animation); + } else { + phi_f2 = animation->frameCount; + } + Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, phi_f2, + animation->mode, animation->morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC6E4.s") +void func_80AAC63C(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC770.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_dmask_Skel_010B0, NULL, NULL, NULL, 0); + if (DMCHAR05_GET(&this->actor) == DMCHAR05_0) { + func_80AAC5A0(&this->skelAnime, &sAnimations[0], 0); + } else { + func_80AAC5A0(&this->skelAnime, &sAnimations[1], 0); + } + this->actionFunc = func_80AACC48; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC7FC.s") +void func_80AAC6E4(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC888.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_dmask_Skel_042B0, NULL, NULL, NULL, 0); + func_80AAC5A0(&this->skelAnime, &sAnimations[1], 0); + this->actionFunc = func_80AACC48; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/DmChar05_Init.s") +void func_80AAC770(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/DmChar05_Destroy.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dmask_Skel_001D0, NULL, NULL, NULL, 0); + func_80AAC5A0(&this->skelAnime, &sAnimations[3], 0); + this->actionFunc = func_80AACC48; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC990.s") +void func_80AAC7FC(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAC9DC.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_dmask_Skel_013D0, NULL, NULL, NULL, 0); + func_80AAC5A0(&this->skelAnime, &sAnimations[4], 0); + this->actionFunc = func_80AACC48; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACA98.s") +void func_80AAC888(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACAE4.s") + this->actionFunc = func_80AACA98; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACBE4.s") +void DmChar05_Init(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACC48.s") + this->unk_18C = 0; + this->unk_18E = 0; + this->unk_19C = 0; + this->unk_1A0 = 0; + this->unk_1A4 = 0; + this->unk_1A8 = 0; + this->unk_1AC = 100; + this->unk_1B0 = 1000; + this->unk_1B4 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACC6C.s") + switch (DMCHAR05_GET(&this->actor)) { + case DMCHAR05_0: + func_80AAC63C(thisx, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACCD4.s") + case DMCHAR05_1: + func_80AAC6E4(thisx, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACD0C.s") + case DMCHAR05_2: + func_80AAC770(thisx, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACD1C.s") + case DMCHAR05_3: + func_80AAC7FC(thisx, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACD68.s") + case DMCHAR05_4: + func_80AAC888(thisx, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACE10.s") + case DMCHAR05_5: + case DMCHAR05_6: + case DMCHAR05_7: + case DMCHAR05_8: + case DMCHAR05_9: + case DMCHAR05_10: + case DMCHAR05_11: + case DMCHAR05_12: + this->actionFunc = func_80AACBE4; + break; + } + Actor_SetScale(&this->actor, 0.01f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACE5C.s") +void DmChar05_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AACF04.s") +void func_80AAC990(DmChar05* this, GlobalContext* globalCtx) { + s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GI_GOLONMASK); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD3F8.s") + if (objectIdx >= 0) { + this->unk_18F = objectIdx; + this->actionFunc = func_80AAC9DC; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD450.s") +void func_80AAC9DC(DmChar05* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 109) != 0) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 109); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD4A8.s") + if (globalCtx->csCtx.actorActions[actionIndex]->action == 4) { + this->unk_18E = 1; + this->unk_190.x = globalCtx->csCtx.actorActions[actionIndex]->startPos.x; + this->unk_190.y = globalCtx->csCtx.actorActions[actionIndex]->startPos.y; + this->unk_190.z = globalCtx->csCtx.actorActions[actionIndex]->startPos.z; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/DmChar05_Update.s") +void func_80AACA98(DmChar05* this, GlobalContext* globalCtx) { + s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GI_MASK13); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD964.s") + if (objectIdx >= 0) { + this->unk_18F = objectIdx; + this->actionFunc = func_80AACAE4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD980.s") +void func_80AACAE4(DmChar05* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 564)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 564); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAD998.s") + if (globalCtx->csCtx.actorActions[actionIndex]->action == 2) { + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + Item_Give(globalCtx, ITEM_MASK_COUPLE); + } + this->unk_18E = 1; + this->unk_190.x = globalCtx->csCtx.actorActions[actionIndex]->startPos.x; + this->unk_190.y = globalCtx->csCtx.actorActions[actionIndex]->startPos.y; + this->unk_190.z = globalCtx->csCtx.actorActions[actionIndex]->startPos.z; + } else { + this->unk_18E = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADA90.s") +void func_80AACBE4(DmChar05* this, GlobalContext* globalCtx) { + static s16 D_80AAE2F0[] = { + OBJECT_GI_MASK17, OBJECT_GI_MASK14, OBJECT_GI_MASK10, OBJECT_GI_MASK21, + OBJECT_GI_MASK11, OBJECT_GI_MASK20, OBJECT_GI_RABIT_MASK, OBJECT_GI_MASK12, + }; + s32 params = DMCHAR05_GET(&this->actor) - DMCHAR05_5; + s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, D_80AAE2F0[params]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADB4C.s") + if (objectIdx >= 0) { + this->unk_18F = objectIdx; + this->actionFunc = func_80AACD0C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADC00.s") +void func_80AACC48(DmChar05* this, GlobalContext* globalCtx) { + if (this->unk_1B4 != 0) { + this->actionFunc = func_80AACC6C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/DmChar05_Draw.s") +void func_80AACC6C(DmChar05* this, GlobalContext* globalCtx) { + if (this->unk_19C < 247) { + this->unk_19C += 8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADD9C.s") + if (this->unk_1A0 < 247) { + this->unk_1A0 += 8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADE78.s") + if (this->unk_1A4 < 247) { + this->unk_1A4 += 8; + } else { + this->unk_19C = 255; + this->unk_1A0 = 255; + this->unk_1A4 = 255; + this->actionFunc = func_80AACCD4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AADF54.s") +void func_80AACCD4(DmChar05* this, GlobalContext* globalCtx) { + if (this->unk_1AC < 975) { + this->unk_1AC += 25; + } else { + this->unk_1AC = 996; + this->actionFunc = func_80AACD0C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAE030.s") +void func_80AACD0C(DmChar05* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Char05/func_80AAE114.s") +void func_80AACD1C(DmChar05* this, GlobalContext* globalCtx) { + s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GI_ZORAMASK); + + if (objectIdx >= 0) { + this->unk_18F = objectIdx; + this->actionFunc = func_80AACD68; + } +} + +void func_80AACD68(DmChar05* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 473)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 473); + + this->unk_18E = 1; + this->unk_190.x = globalCtx->csCtx.actorActions[actionIndex]->startPos.x; + this->unk_190.y = globalCtx->csCtx.actorActions[actionIndex]->startPos.y; + this->unk_190.z = globalCtx->csCtx.actorActions[actionIndex]->startPos.z; + } +} + +void func_80AACE10(DmChar05* this, GlobalContext* globalCtx) { + s32 objectIdx = Object_GetIndex(&globalCtx->objectCtx, OBJECT_GI_MASK15); + + if (objectIdx >= 0) { + this->unk_18F = objectIdx; + this->actionFunc = func_80AACE5C; + } +} + +void func_80AACE5C(DmChar05* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 518)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 518); + + this->unk_18E = 1; + this->unk_190.x = globalCtx->csCtx.actorActions[actionIndex]->startPos.x; + this->unk_190.y = globalCtx->csCtx.actorActions[actionIndex]->startPos.y; + this->unk_190.z = globalCtx->csCtx.actorActions[actionIndex]->startPos.z; + } +} + +void func_80AACF04(DmChar05* this, GlobalContext* globalCtx) { + u8 sp2F = true; + s32 actionIndex; + + switch (DMCHAR05_GET(&this->actor)) { + case DMCHAR05_0: + if (Cutscene_CheckActorAction(globalCtx, 109)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 109); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + sp2F = false; + break; + + case 2: + this->unk_1B4 = 1; + break; + + case 3: + this->unk_18C = 0; + break; + + case 4: + Item_Give(globalCtx, ITEM_MASK_GORON); + sp2F = false; + this->actionFunc = func_80AAC990; + break; + + case 5: + sp2F = false; + Actor_MarkForDeath(&this->actor); + break; + + default: + sp2F = false; + break; + } + + if (sp2F) { + func_80AAC5A0(&this->skelAnime, &sAnimations[this->unk_18C], 0); + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } + break; + + case DMCHAR05_1: + if (Cutscene_CheckActorAction(globalCtx, 473)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 473); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + sp2F = false; + break; + + case 2: + this->unk_18C = 1; + this->unk_1B4 = 1; + break; + + case 3: + this->unk_18C = 1; + break; + + case 4: + Item_Give(globalCtx, ITEM_MASK_ZORA); + sp2F = false; + this->actionFunc = func_80AACD1C; + break; + + case 5: + sp2F = false; + Actor_MarkForDeath(&this->actor); + break; + + default: + sp2F = false; + break; + } + + if (sp2F) { + func_80AAC5A0(&this->skelAnime, &sAnimations[this->unk_18C], 0); + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } + break; + + case DMCHAR05_2: + if (Cutscene_CheckActorAction(globalCtx, 518)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 518); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + sp2F = false; + break; + + case 2: + this->unk_18C = 3; + break; + + case 3: + this->unk_18C = 2; + break; + + case 4: + Item_Give(globalCtx, ITEM_MASK_GIBDO); + sp2F = false; + this->actionFunc = func_80AACE10; + break; + + case 5: + sp2F = false; + Actor_MarkForDeath(&this->actor); + break; + + default: + sp2F = false; + break; + } + + if (sp2F) { + func_80AAC5A0(&this->skelAnime, &sAnimations[this->unk_18C], 0); + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } + break; + + case DMCHAR05_3: + if (Cutscene_CheckActorAction(globalCtx, 559)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 559); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + default: + sp2F = false; + break; + + case 1: + sp2F = false; + break; + + case 2: + this->unk_18C = 4; + break; + + case 3: + this->unk_18C = 5; + break; + + case 4: + this->unk_18C = 5; + break; + } + + if (sp2F) { + func_80AAC5A0(&this->skelAnime, &sAnimations[this->unk_18C], 0); + } + } + + if (globalCtx->csCtx.actorActions[actionIndex]->action != 4) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } else { + Cutscene_ActorTranslate(&this->actor, globalCtx, actionIndex); + } + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_18C == 4) { + this->unk_18C++; + func_80AAC5A0(&this->skelAnime, &sAnimations[this->unk_18C], 0); + } + } + break; + } +} + +void func_80AAD3F8(DmChar05* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.frames == 490) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EVIL_POWER); + } + + if (globalCtx->csCtx.frames > 550) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MASK_FLOAT - SFX_FLAG); + } +} + +void func_80AAD450(DmChar05* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.frames == 262) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EVIL_POWER); + } + + if (globalCtx->csCtx.frames > 318) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MASK_FLOAT - SFX_FLAG); + } +} + +void func_80AAD4A8(DmChar05* this, GlobalContext* globalCtx) { + if (DMCHAR05_GET(&this->actor) == DMCHAR05_0) { + if (Cutscene_CheckActorAction(globalCtx, 109) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 109)]->action == 3)) { + if (Animation_OnFrame(&this->skelAnime, 14.0f) || Animation_OnFrame(&this->skelAnime, 15.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_0); + } else if (Animation_OnFrame(&this->skelAnime, 19.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_1); + } + } + } else if (DMCHAR05_GET(&this->actor) == DMCHAR05_1) { + if (Cutscene_CheckActorAction(globalCtx, 473)) { + if ((globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 473)]->action == 3) && + Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_SAND); + } + } + } else if (DMCHAR05_GET(&this->actor) == DMCHAR05_2) { + if (Cutscene_CheckActorAction(globalCtx, 518) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 518)]->action == 2)) { + if (Animation_OnFrame(&this->skelAnime, 7.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_0); + } + + if (Animation_OnFrame(&this->skelAnime, 14.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_1); + } + + if (Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_MASK_BOUND_1); + } + } + } else if (DMCHAR05_GET(&this->actor) == DMCHAR05_3) { + if (globalCtx->sceneNum == SCENE_OKUJOU) { + if (gSaveContext.sceneSetupIndex == 2) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AAD3F8(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AAD450(this, globalCtx); + } + } + } else if (globalCtx->sceneNum == SCENE_SPOT00) { + if (gSaveContext.sceneSetupIndex == 9) { + if ((globalCtx->csCtx.currentCsIndex == 0) && (globalCtx->csCtx.frames == 255)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EVIL_POWER); + } + } else if ((gSaveContext.sceneSetupIndex == 0xB) && (globalCtx->csCtx.frames == 115)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EVIL_POWER_PREDEMO); + } + } + } +} + +void DmChar05_Update(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; + + func_80AACF04(this, globalCtx); + if (Cutscene_CheckActorAction(globalCtx, 109)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 109)]->action == 3) { + SkelAnime_Update(&this->skelAnime); + } + } else if (Cutscene_CheckActorAction(globalCtx, 473)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 473)]->action == 3) { + SkelAnime_Update(&this->skelAnime); + } + } else if (Cutscene_CheckActorAction(globalCtx, 518)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 518)]->action == 2) { + SkelAnime_Update(&this->skelAnime); + } + } else if (Cutscene_CheckActorAction(globalCtx, 559)) { + if ((globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 559)]->action == 2) || + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 559)]->action == 3)) { + SkelAnime_Update(&this->skelAnime); + } + + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 559)]->action == 4) { + this->actor.world.rot.y += 0x258; + this->actor.shape.rot.y += 0x258; + } + } + this->actionFunc(this, globalCtx); + func_80AAD4A8(this, globalCtx); +} + +s32 DmChar05_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + return false; +} + +void DmChar05_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +} + +void func_80AAD998(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; + s32 pad[2]; + + if (this->unk_18E == 0) { + if (Cutscene_CheckActorAction(globalCtx, 109) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 109)]->action != 1)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, this->unk_19C, this->unk_1A0, this->unk_1A4, this->unk_1A8, + this->unk_1AC, this->unk_1B0); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + DmChar05_OverrideLimbDraw, DmChar05_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } else if (this->unk_18E == 1) { + func_80AADD9C(globalCtx, this); + } +} + +void func_80AADA90(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; + + if (this->unk_18E == 0) { + if (Cutscene_CheckActorAction(globalCtx, 473) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 473)]->action != 1)) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + DmChar05_OverrideLimbDraw, DmChar05_PostLimbDraw, &this->actor); + } + } else if (this->unk_18E == 1) { + func_80AADE78(globalCtx, this); + } +} + +void func_80AADB4C(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; + + if (this->unk_18E == 0) { + if (Cutscene_CheckActorAction(globalCtx, 518) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 518)]->action != 1)) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, &this->actor); + } + } else if (this->unk_18E == 1) { + func_80AADF54(globalCtx, this); + } +} + +void func_80AADC00(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DmChar05* this = THIS; + s32 actionIndex; + + if (Cutscene_CheckActorAction(globalCtx, 559)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 559); + + if ((globalCtx->csCtx.actorActions[actionIndex]->action != 1) && + (globalCtx->csCtx.actorActions[actionIndex]->action != 4)) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + DmChar05_OverrideLimbDraw, DmChar05_PostLimbDraw, &this->actor); + } + + if (globalCtx->csCtx.actorActions[actionIndex]->action == 4) { + Matrix_Translate(-600.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Gfx_DrawDListOpa(globalCtx, object_dmask_DL_001E70); + } + } +} + +void DmChar05_Draw(Actor* thisx, GlobalContext* globalCtx) { + DmChar05* this = THIS; + + switch (DMCHAR05_GET(&this->actor)) { + case DMCHAR05_0: + func_80AAD998(thisx, globalCtx); + break; + + case DMCHAR05_1: + func_80AADA90(thisx, globalCtx); + break; + + case DMCHAR05_2: + func_80AADB4C(thisx, globalCtx); + break; + + case DMCHAR05_3: + func_80AADC00(thisx, globalCtx); + break; + + case DMCHAR05_4: + func_80AAE030(globalCtx, this); + break; + + case DMCHAR05_5: + case DMCHAR05_6: + case DMCHAR05_7: + case DMCHAR05_8: + case DMCHAR05_9: + case DMCHAR05_10: + case DMCHAR05_11: + case DMCHAR05_12: + func_80AAE114(globalCtx, this); + break; + } +} + +void func_80AADD9C(GlobalContext* globalCtx, DmChar05* this) { + if (this->actor.objBankIndex == this->unk_18F) { + Matrix_Translate(this->unk_190.x, this->unk_190.y, this->unk_190.z, MTXMODE_NEW); + Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + GetItem_Draw(globalCtx, GID_44); + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_18F)) { + this->actor.objBankIndex = this->unk_18F; + } +} + +void func_80AADE78(GlobalContext* globalCtx, DmChar05* this) { + if (this->actor.objBankIndex == this->unk_18F) { + Matrix_Translate(this->unk_190.x, this->unk_190.y, this->unk_190.z, MTXMODE_NEW); + Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + GetItem_Draw(globalCtx, GID_45); + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_18F)) { + this->actor.objBankIndex = this->unk_18F; + } +} + +void func_80AADF54(GlobalContext* globalCtx, DmChar05* this) { + if (this->actor.objBankIndex == this->unk_18F) { + Matrix_Translate(this->unk_190.x, this->unk_190.y, this->unk_190.z, MTXMODE_NEW); + Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + GetItem_Draw(globalCtx, GID_6B); + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_18F)) { + this->actor.objBankIndex = this->unk_18F; + } +} + +void func_80AAE030(GlobalContext* globalCtx, DmChar05* this) { + if (this->unk_18E != 0) { + if (this->actor.objBankIndex == this->unk_18F) { + Matrix_Translate(this->unk_190.x, this->unk_190.y, this->unk_190.z, MTXMODE_NEW); + Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + GetItem_Draw(globalCtx, GID_03); + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_18F)) { + this->actor.objBankIndex = this->unk_18F; + } + } +} + +void func_80AAE114(GlobalContext* globalCtx, DmChar05* this) { + s32 sp34; + s16 sp24[] = { + GID_02, GID_6A, GID_70, GID_3A, GID_0E, GID_0F, GID_3E, GID_71, + }; + + sp34 = DMCHAR05_GET(&this->actor) - DMCHAR05_5; + if (this->actor.objBankIndex == this->unk_18F) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateZYX(0, globalCtx->gameplayFrames * 1000, 0, MTXMODE_APPLY); + Matrix_Scale(0.2f, 0.2f, 0.2f, MTXMODE_APPLY); + GetItem_Draw(globalCtx, sp24[sp34]); + } + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_18F)) { + this->actor.objBankIndex = this->unk_18F; + } +} diff --git a/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.h b/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.h index a2e1a6208..83bb67948 100644 --- a/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.h +++ b/src/overlays/actors/ovl_Dm_Char05/z_dm_char05.h @@ -7,11 +7,39 @@ struct DmChar05; typedef void (*DmChar05ActionFunc)(struct DmChar05*, GlobalContext*); +#define DMCHAR05_GET(thisx) ((thisx)->params) + +enum { + /* 0 */ DMCHAR05_0, + /* 1 */ DMCHAR05_1, + /* 2 */ DMCHAR05_2, + /* 3 */ DMCHAR05_3, + /* 4 */ DMCHAR05_4, + /* 5 */ DMCHAR05_5, + /* 6 */ DMCHAR05_6, + /* 7 */ DMCHAR05_7, + /* 8 */ DMCHAR05_8, + /* 9 */ DMCHAR05_9, + /* 10 */ DMCHAR05_10, + /* 11 */ DMCHAR05_11, + /* 12 */ DMCHAR05_12, +}; + typedef struct DmChar05 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ DmChar05ActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x2C]; + /* 0x018C */ s16 unk_18C; + /* 0x018E */ u8 unk_18E; + /* 0x018F */ u8 unk_18F; + /* 0x0190 */ Vec3f unk_190; + /* 0x019C */ u32 unk_19C; + /* 0x01A0 */ u32 unk_1A0; + /* 0x01A4 */ u32 unk_1A4; + /* 0x01A8 */ s32 unk_1A8; + /* 0x01AC */ s32 unk_1AC; + /* 0x01B0 */ s32 unk_1B0; + /* 0x01B4 */ u8 unk_1B4; } DmChar05; // size = 0x1B8 extern const ActorInit Dm_Char05_InitVars; 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 e23886630..e35328af0 100644 --- a/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c +++ b/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char06.c + * Overlay: ovl_Dm_Char06 + * Description: Mountain Village Snowy landscape fadeout in post-Snowhead thawing cutscene + */ + #include "z_dm_char06.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar06*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Char07/z_dm_char07.c b/src/overlays/actors/ovl_Dm_Char07/z_dm_char07.c index c80f7222d..d2aac5a7c 100644 --- a/src/overlays/actors/ovl_Dm_Char07/z_dm_char07.c +++ b/src/overlays/actors/ovl_Dm_Char07/z_dm_char07.c @@ -5,8 +5,9 @@ */ #include "z_dm_char07.h" +#include "objects/object_milkbar/object_milkbar.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar07*)thisx) @@ -29,24 +30,6 @@ const ActorInit Dm_Char07_InitVars = { (ActorFunc)DmChar07_Draw, }; -extern Gfx D_06000100[]; -extern Gfx D_06000240[]; -extern Gfx D_06000650[]; -extern Gfx D_06000790[]; -extern Gfx D_06000B80[]; -extern Gfx D_06000CC0[]; -extern Gfx D_060010D0[]; -extern Gfx D_06001210[]; -extern Gfx D_060015E0[]; -extern Gfx D_060016B8[]; -extern Gfx D_06002BA0[]; -extern Gfx D_06002CD0[]; -extern CollisionHeader D_06006688; -extern Gfx D_060076A0[]; -extern Gfx D_06007918[]; -extern AnimatedMaterial D_060105F8; -extern Gfx D_06010D68[]; - void DmChar07_SetupAction(DmChar07* this, DmChar07ActionFunc actionFunc) { this->actionFunc = actionFunc; } @@ -61,8 +44,8 @@ void DmChar07_Init(Actor* thisx, GlobalContext* globalCtx) { if (this->dyna.actor.params == DMCHAR07_STAGE) { Actor_SetScale(&this->dyna.actor, 0.1f); this->isStage = 1; - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06006688); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_milkbar_Colheader_006688); } else { Actor_SetScale(&this->dyna.actor, 1.0f); } @@ -73,7 +56,7 @@ void DmChar07_Destroy(Actor* thisx, GlobalContext* globalCtx) { DmChar07* this = THIS; if (this->isStage) { - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } } @@ -96,36 +79,36 @@ void DmChar07_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); switch (this->dyna.actor.params) { case DMCHAR07_STAGE: - gSPDisplayList(POLY_OPA_DISP++, D_06002CD0); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_002CD0); break; case DMCHAR07_CREDITS_STAGE: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_060105F8)); - gSPDisplayList(POLY_OPA_DISP++, D_06007918); - gSPDisplayList(POLY_OPA_DISP++, D_06000240); - gSPDisplayList(POLY_OPA_DISP++, D_06000790); - gSPDisplayList(POLY_OPA_DISP++, D_06000CC0); - gSPDisplayList(POLY_OPA_DISP++, D_06001210); - gSPDisplayList(POLY_OPA_DISP++, D_060016B8); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_milkbar_Matanimheader_0105F8)); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_007918); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000240); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000790); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000CC0); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_001210); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_0016B8); break; case DMCHAR07_SPOTLIGHTS: if (this->spotlightFlags & DMCHAR07_STAGE_RIGHT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000240); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000240); } if (this->spotlightFlags & DMCHAR07_UPSTAGE_RIGHT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000790); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000790); } if (this->spotlightFlags & DMCHAR07_STAGE_CENTER_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000CC0); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000CC0); } if (this->spotlightFlags & DMCHAR07_UPSTAGE_LEFT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06001210); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_001210); } if (this->spotlightFlags & DMCHAR07_DOWNSTAGE_CENTER_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_060016B8); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_0016B8); } break; case DMCHAR07_DISHES: - gSPDisplayList(POLY_OPA_DISP++, D_06010D68); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_010D68); break; } @@ -133,31 +116,31 @@ void DmChar07_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); switch (this->dyna.actor.params) { case DMCHAR07_STAGE: - gSPDisplayList(POLY_XLU_DISP++, D_06002BA0); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_002BA0); break; case DMCHAR07_CREDITS_STAGE: - gSPDisplayList(POLY_XLU_DISP++, D_060076A0); - gSPDisplayList(POLY_XLU_DISP++, D_06000100); - gSPDisplayList(POLY_XLU_DISP++, D_06000650); - gSPDisplayList(POLY_XLU_DISP++, D_06000B80); - gSPDisplayList(POLY_XLU_DISP++, D_060010D0); - gSPDisplayList(POLY_XLU_DISP++, D_060015E0); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_0076A0); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_000100); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_000650); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_000B80); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_0010D0); + gSPDisplayList(POLY_XLU_DISP++, object_milkbar_DL_0015E0); break; case DMCHAR07_SPOTLIGHTS: if (this->spotlightFlags & DMCHAR07_STAGE_RIGHT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000100); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000100); } if (this->spotlightFlags & DMCHAR07_UPSTAGE_RIGHT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000650); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000650); } if (this->spotlightFlags & DMCHAR07_STAGE_CENTER_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_06000B80); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_000B80); } if (this->spotlightFlags & DMCHAR07_UPSTAGE_LEFT_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_060010D0); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_0010D0); } if (this->spotlightFlags & DMCHAR07_DOWNSTAGE_CENTER_SPOTLIGHT) { - gSPDisplayList(POLY_OPA_DISP++, D_060015E0); + gSPDisplayList(POLY_OPA_DISP++, object_milkbar_DL_0015E0); } break; case DMCHAR07_DISHES: diff --git a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c index ed83d46f3..f944c9c63 100644 --- a/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c +++ b/src/overlays/actors/ovl_Dm_Char08/z_dm_char08.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char08.c + * Overlay: ovl_Dm_Char08 + * Description: Large Great Bay Turtle + */ + #include "z_dm_char08.h" -#define FLAGS 0x02000000 +#define FLAGS (ACTOR_FLAG_2000000) #define THIS ((DmChar08*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c b/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c index ef98424c3..7fb20d1a0 100644 --- a/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c +++ b/src/overlays/actors/ovl_Dm_Char09/z_dm_char09.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_char09.c + * Overlay: ovl_Dm_Char09 + * Description: Pirates' Fortress cutscene characters + */ + #include "z_dm_char09.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmChar09*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.c b/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.c index 4f1440dd5..a6970e050 100644 --- a/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.c +++ b/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.c @@ -1,6 +1,14 @@ -#include "z_dm_gm.h" +/* + * File: z_dm_gm.c + * Overlay: ovl_Dm_Gm + * Description: Anju (cutscene) (duplicate of Dm_An?) + */ -#define FLAGS 0x00000009 +#include "z_dm_gm.h" +#include "objects/object_an4/object_an4.h" +#include "objects/object_msmo/object_msmo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((DmGm*)thisx) @@ -11,8 +19,8 @@ void DmGm_Update(Actor* thisx, GlobalContext* globalCtx); void func_80C248A8(DmGm* this, GlobalContext* globalCtx); void func_80C24A00(DmGm* this, GlobalContext* globalCtx); void func_80C24BD0(DmGm* this, GlobalContext* globalCtx); +void func_80C25000(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Dm_Gm_InitVars = { ACTOR_DM_GM, ACTORCAT_NPC, @@ -25,37 +33,337 @@ const ActorInit Dm_Gm_InitVars = { (ActorFunc)NULL, }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_an1_Anim_007E08, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an1_Anim_0071E8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_006CC0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_an1_Anim_013E1C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_an4_Anim_007E3C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_0088C0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_0013C8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_002550, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_00353C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_004498, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_an4_Anim_0060B4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_00041C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_004A78, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_an4_Anim_00506C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern UNK_TYPE D_06000E70; -extern UNK_TYPE D_06012618; +s32 func_80C24360(DmGm* this, GlobalContext* globalCtx) { + s8 objectIndex = this->actor.objBankIndex; + s8 objectIndex2; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24360.s") + if (this->unk_2C8 < 2) { + objectIndex2 = this->actor.objBankIndex; + } else { + objectIndex2 = this->unk_2AC; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24428.s") + if (objectIndex2 >= 0) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex2].segment); + ret = SkelAnime_Update(&this->skelAnime); + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex].segment); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24504.s") +s32 func_80C24428(DmGm* this, GlobalContext* globalCtx, s32 arg2) { + s8 objectIndex = this->actor.objBankIndex; + s8 objectIndex2; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C2457C.s") + if (arg2 < 2) { + objectIndex2 = this->actor.objBankIndex; + } else { + objectIndex2 = this->unk_2AC; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C2478C.s") + if ((objectIndex2 >= 0) && (arg2 != this->unk_2C8)) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex2].segment); + this->unk_2C8 = arg2; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg2); + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objectIndex].segment); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24838.s") +void func_80C24504(DmGm* this) { + if (DECR(this->unk_2BA) == 0) { + this->unk_2B8++; + if (this->unk_2B8 >= 4) { + this->unk_2BA = Rand_S16Offset(30, 30); + this->unk_2B8 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C248A8.s") +s32 func_80C2457C(DmGm* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24A00.s") + Math_Vec3f_Copy(&sp40, &this->unk_2B4->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24BD0.s") + Math_ApproachS(&this->unk_2C0, (sp32 - this->unk_2C4) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2C0 = CLAMP(this->unk_2C0, -0x1FFE, 0x1FFE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/DmGm_Init.s") + Math_ApproachS(&this->unk_2C4, (sp32 - this->unk_2C0) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2C4 = CLAMP(this->unk_2C4, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/DmGm_Destroy.s") + if (this->unk_2B4->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_2B4)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_2B4->focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/DmGm_Update.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + Math_ApproachS(&this->unk_2BE, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2C2, 4, 0x2AA8); + this->unk_2BE = CLAMP(this->unk_2BE, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24CD0.s") + Math_ApproachS(&this->unk_2C2, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2BE, 4, 0x2AA8); + this->unk_2C2 = CLAMP(this->unk_2C2, -0x1C70, 0x1C70); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C24E4C.s") +s32 func_80C2478C(DmGm* this, GlobalContext* globalCtx) { + if (this->unk_2B4 != NULL) { + func_80C2457C(this, globalCtx); + this->unk_2AE &= ~1; + this->unk_2AE |= 2; + } else if (this->unk_2AE & 2) { + this->unk_2AE &= ~2; + this->unk_2BE = 0; + this->unk_2C0 = 0; + this->unk_2C2 = 0; + this->unk_2C4 = 0; + this->unk_2BC = 20; + } else if (DECR(this->unk_2BC) == 0) { + this->unk_2AE |= 1; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Gm/func_80C25000.s") +Actor* func_80C24838(GlobalContext* globalCtx) { + Actor* tempActor; + Actor* foundActor = NULL; + + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, ACTORCAT_NPC, ACTOR_DM_AH); + + if ((foundActor == NULL) || (foundActor->update != NULL)) { + break; + } + + tempActor = foundActor->next; + if (tempActor == NULL || false) { + foundActor = NULL; + break; + } + foundActor = tempActor; + } + return foundActor; +} + +void func_80C248A8(DmGm* this, GlobalContext* globalCtx) { + if ((this->unk_2AC >= 0) && SubS_IsObjectLoaded(this->unk_2AC, globalCtx) && (this->unk_2AD >= 0) && + SubS_IsObjectLoaded(this->unk_2AD, globalCtx)) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 14.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_an1_Skel_012618, NULL, this->jointTable, + this->morphTable, OBJECT_AN1_LIMB_MAX); + + this->unk_2C8 = -1; + func_80C24428(this, globalCtx, 0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_SetScale(&this->actor, 0.01f); + this->unk_2AE |= 1; + this->actor.draw = func_80C25000; + + if ((globalCtx->sceneNum == SCENE_YADOYA) && (globalCtx->curSpawn == 4)) { + this->unk_2B4 = func_80C24838(globalCtx); + func_80C24428(this, globalCtx, 1); + this->actionFunc = func_80C24BD0; + } else { + this->actionFunc = func_80C24A00; + } + } +} + +void func_80C24A00(DmGm* this, GlobalContext* globalCtx) { + s32 sp28[] = { 0, 0, 12, 2, 4, 6, 8, 10, 11, 3 }; + u16 action; + s32 sp20; + + if (globalCtx->csCtx.state != 0) { + if (this->unk_2D0 == 0) { + this->unk_2B0 = 255; + this->unk_2D0 = 1; + this->unk_2D4 = 0; + this->unk_2CC = this->unk_2C8; + } + + if (Cutscene_CheckActorAction(globalCtx, 0x22D)) { + sp20 = Cutscene_GetActorActionIndex(globalCtx, 0x22D); + action = globalCtx->csCtx.actorActions[sp20]->action; + + if (this->unk_2B0 != (action & 0xFF)) { + this->unk_2B0 = action; + this->unk_2D4 = 1; + func_80C24428(this, globalCtx, sp28[action]); + } + + switch (this->unk_2B0) { + case 2: + case 4: + case 5: + case 6: + case 7: + case 8: + if ((this->unk_2C8 == 12) || (this->unk_2C8 == 4) || (this->unk_2C8 == 6) || (this->unk_2C8 == 8)) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80C24428(this, globalCtx, this->unk_2C8 + 1); + } + } + break; + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, sp20); + } + } else if (this->unk_2D0 != 0) { + this->unk_2D0 = 0; + this->unk_2D4 = 0; + func_80C24428(this, globalCtx, this->unk_2CC); + } +} + +void func_80C24BD0(DmGm* this, GlobalContext* globalCtx) { +} + +void DmGm_Init(Actor* thisx, GlobalContext* globalCtx) { + DmGm* this = THIS; + + this->unk_2AC = SubS_GetObjectIndex(OBJECT_AN4, globalCtx); + this->unk_2AD = SubS_GetObjectIndex(OBJECT_MSMO, globalCtx); + this->actionFunc = func_80C248A8; +} + +void DmGm_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void DmGm_Update(Actor* thisx, GlobalContext* globalCtx) { + DmGm* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80C2478C(this, globalCtx); + + if (this->actor.draw != NULL) { + func_80C24360(this, globalCtx); + func_80C24504(this); + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); +} + +Vec3f D_80C25218 = { 450.0f, 700.0f, -760.0f }; +Vec3s D_80C25224 = { 0x238C, 0, -0x3FFC }; +Vec3f D_80C2522C = { 1000.0f, 0.0f, 0.0f }; + +void DmGm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad[2]; + DmGm* this = THIS; + s8 sp2B = this->actor.objBankIndex; + s8 sp2A = this->unk_2AD; + + if ((limbIndex == OBJECT_AN1_LIMB_05) && (this->unk_2D4 != 0)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_TranslateRotateZYX(&D_80C25218, &D_80C25224); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[sp2A].segment); + gSPDisplayList(POLY_OPA_DISP++, gMoonMaskDL); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[sp2B].segment); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == OBJECT_AN1_LIMB_09) { + Matrix_MultVec3f(&D_80C2522C, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } +} + +void DmGm_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + DmGm* this = THIS; + s16 stepRot; + s16 overrideRot; + + if (!(this->unk_2AE & 1)) { + if (this->unk_2AE & 2) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + stepRot = false; + overrideRot = false; + } + + if (limbIndex == OBJECT_AN1_LIMB_09) { + SubS_UpdateLimb(this->unk_2BE + this->unk_2C2 + 0x4000, + this->unk_2C0 + this->unk_2C4 + this->actor.shape.rot.y + 0x4000, &this->unk_18C, + &this->unk_1A4, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_18C.x, this->unk_18C.y, this->unk_18C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_1A4.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1A4.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1A4.z, MTXMODE_APPLY); + Matrix_Push(); + } else if (limbIndex == OBJECT_AN1_LIMB_02) { + SubS_UpdateLimb(this->unk_2C2 + 0x4000, this->unk_2C4 + this->actor.shape.rot.y + 0x4000, &this->unk_194, + &this->unk_1AA, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_194.x, this->unk_194.y, this->unk_194.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_1AA.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1AA.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1AA.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +TexturePtr D_80C25238[] = { + object_an1_Tex_00E6E0, + object_an1_Tex_00F7A0, + object_an1_Tex_0101A0, +}; + +TexturePtr D_80C25244[] = { + object_an1_Tex_00E1E0, object_an1_Tex_00EFA0, object_an1_Tex_00F3A0, object_an1_Tex_00EFA0, + object_an1_Tex_00FDA0, object_an1_Tex_00F9A0, object_an1_Tex_0103A0, +}; + +void func_80C25000(Actor* thisx, GlobalContext* globalCtx) { + DmGm* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C25244[this->unk_2B8])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C25238[0])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, DmGm_PostLimbDraw, DmGm_TransformLimbDraw, + &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.h b/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.h index 8b416d7b7..6f2307378 100644 --- a/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.h +++ b/src/overlays/actors/ovl_Dm_Gm/z_dm_gm.h @@ -2,6 +2,7 @@ #define Z_DM_GM_H #include "global.h" +#include "objects/object_an1/object_an1.h" struct DmGm; @@ -9,9 +10,30 @@ typedef void (*DmGmActionFunc)(struct DmGm*, GlobalContext*); typedef struct DmGm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ DmGmActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x14C]; + /* 0x018C */ Vec3f unk_18C; + /* 0x018C */ Vec3f unk_194; + /* 0x01A4 */ Vec3s unk_1A4; + /* 0x01A4 */ Vec3s unk_1AA; + /* 0x01B0 */ Vec3s jointTable[OBJECT_AN1_LIMB_MAX]; + /* 0x022E */ Vec3s morphTable[OBJECT_AN1_LIMB_MAX]; + /* 0x02AC */ s8 unk_2AC; + /* 0x02AD */ s8 unk_2AD; + /* 0x02AE */ u16 unk_2AE; + /* 0x02B0 */ u8 unk_2B0; + /* 0x02B4 */ Actor* unk_2B4; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA; + /* 0x02BC */ s16 unk_2BC; + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C2 */ s16 unk_2C2; + /* 0x02C4 */ s16 unk_2C4; + /* 0x02C8 */ s32 unk_2C8; + /* 0x02CC */ s32 unk_2CC; + /* 0x02D0 */ s32 unk_2D0; + /* 0x02D4 */ s32 unk_2D4; } DmGm; // size = 0x2D8 extern const ActorInit Dm_Gm_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.c b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.c index 0bec5d023..a30e83620 100644 --- a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.c +++ b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_hina.c + * Overlay: ovl_Dm_Hina + * Description: Boss mask cutscene objects + */ + #include "z_dm_hina.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmHina*)thisx) 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_Nb/z_dm_nb.c b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c index 1e36f9e29..102ecd95e 100644 --- a/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c +++ b/src/overlays/actors/ovl_Dm_Nb/z_dm_nb.c @@ -5,8 +5,9 @@ */ #include "z_dm_nb.h" +#include "objects/object_nb/object_nb.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((DmNb*)thisx) @@ -27,17 +28,14 @@ const ActorInit Dm_Nb_InitVars = { (ActorFunc)DmNb_Draw, }; -extern AnimationHeader D_06000990; -extern FlexSkeletonHeader D_06008C40; - -static ActorAnimationEntryS D_80C1E200[] = { &D_06000990, 1.0f, 0, -1, 0, 0 }; +static AnimationInfoS D_80C1E200[] = { { &object_nb_Anim_000990, 1.0f, 0, -1, ANIMMODE_LOOP, 0 } }; s32 func_80C1DED0(DmNb* this, s32 arg1) { - s32 ret = 0; + s32 ret = false; if (arg1 != this->unk1F0) { this->unk1F0 = arg1; - ret = func_8013BC6C(&this->skelAnime, D_80C1E200, arg1); + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80C1E200, arg1); } return ret; } @@ -45,7 +43,7 @@ s32 func_80C1DED0(DmNb* this, s32 arg1) { void func_80C1DF18(DmNb* this, GlobalContext* globalCtx) { s32 sp2C[] = { 0, 0, 0, 0, 0 }; u16 actionUnk0; - u32 actionIndex; + s32 actionIndex; if (globalCtx->csCtx.state != 0) { if (this->unk1F8 == 0) { @@ -53,14 +51,14 @@ void func_80C1DF18(DmNb* this, GlobalContext* globalCtx) { this->unk1F8 = 1; this->unk1F4 = this->unk1F0; } - if (func_800EE29C(globalCtx, 0x232)) { - actionIndex = func_800EE200(globalCtx, 0x232); - actionUnk0 = globalCtx->csCtx.npcActions[actionIndex]->unk0; + if (Cutscene_CheckActorAction(globalCtx, 562)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 562); + actionUnk0 = globalCtx->csCtx.actorActions[actionIndex]->action; if (this->unk1EC != (actionUnk0 & 0xFF)) { this->unk1EC = actionUnk0; func_80C1DED0(this, sp2C[actionUnk0]); } - func_800EDF24(&this->actor, globalCtx, actionIndex); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); } } else if (this->unk1F8 != 0) { this->unk1F8 = 0; @@ -72,10 +70,11 @@ void DmNb_Init(Actor* thisx, GlobalContext* globalCtx) { DmNb* this = THIS; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06008C40, NULL, this->jointTable, this->morphTable, 8); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_nb_Skel_008C40, NULL, this->jointTable, this->morphTable, + 8); this->unk1F0 = -1; func_80C1DED0(this, 0); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; Actor_SetScale(&this->actor, 0.01f); this->actionFunc = func_80C1DF18; } @@ -91,13 +90,13 @@ void DmNb_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); } -void DmNb_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void DmNb_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void DmNb_Draw(Actor* thisx, GlobalContext* globalCtx) { DmNb* this = THIS; func_8012C5B0(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, - NULL, DmNb_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, DmNb_TransformLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_Dm_Opstage/z_dm_opstage.c b/src/overlays/actors/ovl_Dm_Opstage/z_dm_opstage.c index 531c293ce..ef81bc467 100644 --- a/src/overlays/actors/ovl_Dm_Opstage/z_dm_opstage.c +++ b/src/overlays/actors/ovl_Dm_Opstage/z_dm_opstage.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_opstage.c + * Overlay: ovl_Dm_Opstage + * Description: Lost Woods cutscene objects + */ + #include "z_dm_opstage.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmOpstage*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Ravine/z_dm_ravine.c b/src/overlays/actors/ovl_Dm_Ravine/z_dm_ravine.c index fca8d1452..25a68056e 100644 --- a/src/overlays/actors/ovl_Dm_Ravine/z_dm_ravine.c +++ b/src/overlays/actors/ovl_Dm_Ravine/z_dm_ravine.c @@ -6,7 +6,7 @@ #include "z_dm_ravine.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmRavine*)thisx) @@ -29,9 +29,10 @@ const ActorInit Dm_Ravine_InitVars = { }; void DmRavine_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; DmRavine* this = THIS; - u8 flag = gSaveContext.weekEventReg[0]; - if (((flag & 0x10) | cREG(0)) != 0) { + + if (((((void)0, gSaveContext.save.weekEventReg[0]) & 0x10) | cREG(0)) != 0) { Actor_MarkForDeath(&this->actor); return; } 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 02101b113..4d5a20114 100644 --- a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c +++ b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c @@ -1,6 +1,13 @@ -#include "z_dm_sa.h" +/* + * File: z_dm_sa.c + * Overlay: ovl_Dm_Sa + * Description: Glitched early version of Skull Kid stuck in a T-pose + */ -#define FLAGS 0x00000030 +#include "z_dm_sa.h" +#include "objects/object_stk/object_stk.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmSa*)thisx) @@ -23,15 +30,12 @@ const ActorInit Dm_Sa_InitVars = { (ActorFunc)DmSa_Draw, }; -extern FlexSkeletonHeader D_06013328; -extern AnimationHeader D_0600CC94; +static AnimationInfo D_80A2ED00[] = { { &object_stk_Anim_00CC94, 1.0f, 0, -1.0f, ANIMMODE_LOOP, 0 } }; -static ActorAnimationEntry D_80A2ED00[] = { { &D_0600CC94, 1.0f, 0, -1.0f, 0, 0 } }; - -void func_80A2E960(SkelAnime* arg0, ActorAnimationEntry* animations, u16 index) { +void func_80A2E960(SkelAnime* arg0, AnimationInfo* animations, u16 index) { f32 frameCount; - animations += index; + animations += index; if (animations->frameCount < 0.0f) { frameCount = Animation_GetLastFrame(animations->animation); } else { @@ -47,8 +51,8 @@ void DmSa_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk2E0 = 0; this->alpha = 0xFF; this->actor.targetArrowOffset = 3000.0f; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013328, NULL, 0, 0, 0); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_stk_Skel_013328, NULL, NULL, NULL, 0); func_80A2E960(&this->skelAnime, D_80A2ED00, 0); Actor_SetScale(&this->actor, 0.01f); this->actionFunc = DmSa_DoNothing; @@ -68,14 +72,14 @@ void DmSa_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } -s32 func_80A2EB10(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* actor) { - return 0; +s32 DmSa_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; } -void func_80A2EB2C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor) { +void DmSa_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80A2EB44(GlobalContext* globalCtx, s32 limbIndex, Actor* actor) { +void DmSa_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } Gfx* func_80A2EB58(GraphicsContext* gfxCtx, u32 alpha) { @@ -114,8 +118,9 @@ void DmSa_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x0C, func_80A2EBB0(globalCtx->state.gfxCtx, this->alpha)); } - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80A2EB10, func_80A2EB2C, func_80A2EB44, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, DmSa_OverrideLimbDraw, DmSa_PostLimbDraw, + DmSa_TransformLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 566c6f614..6c9d11170 100644 --- a/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c +++ b/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c @@ -1,6 +1,13 @@ -#include "z_dm_statue.h" +/* + * File: z_dm_statue.c + * Overlay: ovl_Dm_Statue + * Description: Pillars of water in Giant's Chamber + */ -#define FLAGS 0x04000030 +#include "z_dm_statue.h" +#include "objects/object_smtower/object_smtower.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_4000000) #define THIS ((DmStatue*)thisx) @@ -21,9 +28,6 @@ const ActorInit Dm_Statue_InitVars = { (ActorFunc)DmStatue_Draw, }; -extern AnimatedMaterial D_06001788; -extern Gfx D_06000520[]; - void DmStatue_Init(Actor* thisx, GlobalContext* globalCtx) { DmStatue* this = THIS; @@ -37,6 +41,6 @@ void DmStatue_Update(Actor* thisx, GlobalContext* globalCtx) { } void DmStatue_Draw(Actor* thisx, GlobalContext* globalCtx) { - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06001788)); - func_800BE03C(globalCtx, D_06000520); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_smtower_Matanimheader_001788)); + Gfx_DrawDListXlu(globalCtx, object_smtower_DL_000520); } 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 efeb8a82c..782ef8679 100644 --- a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c +++ b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c @@ -1,6 +1,15 @@ -#include "z_dm_stk.h" +/* + * File: z_dm_stk.c + * Overlay: ovl_Dm_Stk + * Description: Skull Kid (cutscene) + */ -#define FLAGS 0x02000030 +#include "z_dm_stk.h" +#include "objects/object_stk/object_stk.h" +#include "objects/object_stk2/object_stk2.h" +#include "objects/object_stk3/object_stk3.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((DmStk*)thisx) @@ -24,7 +33,6 @@ void func_80AA1C64(DmStk* this, GlobalContext* globalCtx); void func_80AA2720(DmStk* this, GlobalContext* globalCtx); void func_80AA27EC(DmStk* this, GlobalContext* globalCtx); -#if 0 const ActorInit Dm_Stk_InitVars = { ACTOR_DM_STK, ACTORCAT_ITEMACTION, @@ -37,18 +45,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), @@ -83,98 +102,1710 @@ static DamageTable D_80AA35D8 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -#endif +static AnimationInfo sAnimations[] = { + { &object_stk_Anim_01C21C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_01D3D0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_001030, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_01D008, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_01D008, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_015C14, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0070DC, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_00D830, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_00055C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_00130C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_00C270, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_00CBB8, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_01AA80, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_01D07C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_016910, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_018ED0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_01DDE0, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_01EF50, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_02DC64, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_02E9A0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_02DC64, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_02E9A0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0035C8, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_0049C8, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0259F4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_0266C8, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_026CF4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_01C114, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_004580, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_020CAC, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_02200C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_02336C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_002774, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_003068, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0101A4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_010B60, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_02A2D8, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_01F9E4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_029A04, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_02AD54, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_00BB2C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_00C964, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0110B4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_011FB0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_012A58, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_0141E4, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_00E6EC, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_00EEC0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_027CF4, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_028F28, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_03323C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_031210, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_0322FC, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_032AE0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_03021C, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_036964, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_016508, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk_Anim_015028, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk_Anim_014920, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_02FA70, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_037B94, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_03967C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_03967C, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk2_Anim_03A8F8, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk2_Anim_034FD8, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk3_Anim_005F44, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk3_Anim_002CD8, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk3_Anim_0039F0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk3_Anim_004554, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk3_Anim_0051C0, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_stk3_Anim_001374, 1.0f, 0.0f, -1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_stk3_Anim_001EDC, 1.0f, 0.0f, -1.0f, ANIMMODE_LOOP, 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, AnimationInfo* 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: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_SHAKEHEAD); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA01C0.s") + case 1285: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL03_LAUGH_BIG); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0264.s") + case 1343: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0420.s") + case 1410: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA05F0.s") + case 1603: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_WALK); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0634.s") + case 1610: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_REVERSE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA066C.s") + case 2095: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_SURPRISED); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA071C.s") + case 2190: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_JUMP); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA076C.s") + case 2212: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_ONGND); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA09DC.s") + case 2214: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL02_LAUGH_SHORT); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0B08.s") + case 2250: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL06_SURPRISED); + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Init.s") + case 173: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_GASAGOSO); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA16F4.s") + case 90: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1704.s") + case 142: + Actor_PlaySfxAtPos(&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(&gSfxVolume, 0.0f, 150); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA18D8.s") + case 560: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL02_LAUGH_SHORT); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA192C.s") + case 890: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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(&gSfxVolume, 0.0f, 80); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1B9C.s") + case 265: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL03_LAUGH_BIG); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1C64.s") + case 126: + Actor_PlaySfxAtPos(&player->actor, NA_SE_VO_DUMMY_150); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1D1C.s") + case 197: + Actor_PlaySfxAtPos(&player->actor, NA_SE_VO_DUMMY_134); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA26CC.s") + case 207: + Actor_PlaySfxAtPos(&player->actor, NA_SE_VO_DUMMY_135); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA2720.s") + case 217: + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_TURN); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Draw.s") + case 524: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_TURN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL04_ANGER); + break; + + case 534: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_ROLL); + break; + + case 678: + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_OTEDAMA1); + } else if (Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 40.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_OTEDAMA2); + } + } + + if (globalCtx->csCtx.frames >= 700) { + if (D_80AA3CB8 < 128) { + if ((D_80AA3CB8 & 0x1F) == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL20_CALL_MOON); + } else if ((D_80AA3CB8 & 0x1F) == 16) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL06_SURPRISED); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_DOWN_K); + } +} + +void func_80AA0634(DmStk* this, GlobalContext* globalCtx) { + if ((globalCtx->csCtx.frames >= 642) && (globalCtx->csCtx.frames < 845)) { + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_WATER2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_WALK); + break; + + case 186: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + break; + + case 230: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 93: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 245: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 269: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL11_LAUGH_SHY2); + break; + + case 327: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_SHAKEHEAD); + break; + + case 455: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 1730: + Audio_QueueSeqCmd(0x141400FF); + break; + + case 1395: + func_800B8E58(player, 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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + } + + if (Animation_OnFrame(&this->skelAnime, 28.0f)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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))) { + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_TURN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL04_ANGER); + break; + + case 244: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_ROLL); + break; + + case 388: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_STRETCH); + break; + } + + if (globalCtx->csCtx.frames >= 408) { + if (D_80AA3CBC < 128) { + if ((D_80AA3CBC & 0x1F) == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STAL20_CALL_MOON); + } else if ((D_80AA3CBC & 0x1F) == 16) { + Actor_PlaySfxAtPos(&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: + Audio_PlaySfxAtPos(&this->unk_310, NA_SE_EN_STAL06_SURPRISED); + break; + + case 327: + case 332: + case 335: + case 344: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 367: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_BODY_LEV); + break; + + case 470: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_HEADACHE); + break; + + case 486: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + Audio_PlaySfxAtPos(&this->unk_310, NA_SE_EN_STAL08_CRY_BIG); + break; + + case 496: + Audio_PlaySfxAtPos(&this->unk_310, NA_SE_EN_STAL09_SCREAM); + break; + + case 590: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 592: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 594: + Audio_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_BODY_LEV); + } else { + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_PULLED); + break; + + case 711: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 716: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_ONGND); + break; + } +} + +void func_80AA0E1C(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 311: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_PULLED); + break; + + case 365: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 372: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + Actor_PlaySfxAtPos(&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.currentCsIndex == 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.currentCsIndex == 0) { + func_80AA01C0(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA0264(this, globalCtx); + } + } + break; + + case SCENE_OKUJOU: + if (gSaveContext.sceneSetupIndex == 0) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA0420(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA05F0(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 2) { + func_80AA09DC(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 3) { + func_80AA0B08(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 2) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA0DA8(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA0E1C(this, globalCtx); + } + } + break; + + case SCENE_00KEIKOKU: + if (gSaveContext.sceneSetupIndex == 3) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA0634(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 2) { + func_80AA066C(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 7) { + if (globalCtx->csCtx.currentCsIndex == 0) { + func_80AA071C(this, globalCtx); + } else if (globalCtx->csCtx.currentCsIndex == 1) { + func_80AA076C(this, globalCtx); + } + } + break; + } + } + + if (this->unk_2E0 == 1) { + if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_CALM_HIT); + } + } else if (this->unk_2E0 == 14) { + if (Animation_OnFrame(&this->skelAnime, 3.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_PUT_OUT_ITEM); + } + } else if (this->unk_2E0 == 15) { + if (Animation_OnFrame(&this->skelAnime, 14.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_UNSKILLFUL_OCARINA); + } + + if (Animation_OnFrame(&this->skelAnime, 45.0f)) { + Actor_PlaySfxAtPos(&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.save.entranceIndex == 0x2C00) { + if (gSaveContext.sceneSetupIndex == 0) { + if (gSaveContext.unk_3DD0[3] == 0) { + func_8010E9F0(3, 300); + XREG(80) = 200; + XREG(81) = 115; + } + + if (gSaveContext.save.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) && !Cutscene_IsPlaying(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, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_stk_Skel_013328, 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.currentCsIndex > 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.save.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.save.day < 3) { + cutscene = sp1E; + } else if ((gSaveContext.save.weekEventReg[8] & 0x40) || + ((CURRENT_DAY == 3) && (gSaveContext.save.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)) { + Actor_PlaySfxAtPos(&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)) { + Message_StartTextbox(globalCtx, 0x2013, &this->actor); + } + } + + this->unk_2E0 = 39; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + Actor_PlaySfxAtPos(&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; + s32 temp_v0; + + if (Cutscene_CheckActorAction(globalCtx, 107)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, 107); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[temp_v0]->startFrame) { + if (this->unk_334 != globalCtx->csCtx.actorActions[temp_v0]->action) { + this->unk_334 = globalCtx->csCtx.actorActions[temp_v0]->action; + if (globalCtx->sceneNum == SCENE_CLOCKTOWER) { + this->unk_32D = 6; + } else { + this->unk_32D = 9; + } + + switch (globalCtx->csCtx.actorActions[temp_v0]->action) { + 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.save.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.save.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.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + this->unk_32D = 3; + } + break; + + case 27: + this->unk_2E0 = 36; + if (gSaveContext.save.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); + } + } + + Cutscene_ActorTranslateAndYaw(&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.save.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 |= ACTOR_FLAG_1; + this->unk_328++; + if (this->unk_328 > 800) { + this->unk_328 = 0; + if (!(player->stateFlags2 & 0x8000000)) { + Message_StartTextbox(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 |= ACTOR_FLAG_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; + + if (this->actor.params != 1) { + if (this->unk_2E0 == 33) { + Actor_SetFocus(&this->actor, 40.0f); + } else { + Actor_SetFocus(&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->state)) { + 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.msgMode != 0) && + (globalCtx->msgCtx.currentTextId == 0x5E6) && !FrameAdvance_IsEnabled(&globalCtx->state) && + (globalCtx->sceneLoadFlag == 0) && (ActorCutscene_GetCurrentIndex() == -1) && + (globalCtx->csCtx.state == 0)) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)REG(15); + if (REG(15) != 0) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.daySpeed); + } + } + } + + if ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 3) && + (globalCtx->csCtx.currentCsIndex > 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_MultZero(&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++, object_stk_DL_00AEC0); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_00AE30); + } else { + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_00A5C0); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_00A530); + } + + 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++, object_stk_DL_006BB0); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } else { + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_006BB0); + } + break; + + case 2: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_006BB0); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_005870); + + if (Cutscene_CheckActorAction(globalCtx, 513) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 513)]->action == 2) && + (this->unk_337 >= 0)) { + Matrix_Push(); + 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(object_stk2_Matanimheader_008658)); + Gfx_DrawDListOpa(globalCtx, object_stk2_DL_007840); + 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_Pop(); + } + 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++, object_stk_DL_009AC0); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0046B0); + break; + + case 1: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_009710); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0053C0); + break; + + case 3: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_009DA0); + + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && (gSaveContext.sceneSetupIndex == 1)) { + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_00CAD0); + } + break; + + case 5: + Matrix_Translate(-20.0f, -660.0f, 860.0f, MTXMODE_APPLY); + Matrix_RotateYS(0x6142, MTXMODE_APPLY); + Matrix_RotateXS(-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++, object_stk_DL_006BB0); + 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++, object_stk_DL_0084C0); + break; + + case 2: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0090C0); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0079F0); + break; + + case 3: + if ((globalCtx->sceneNum != SCENE_LOST_WOODS) || (gSaveContext.sceneSetupIndex != 1)) { + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_00CAD0); + } + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0090C0); + break; + + case 4: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0090C0); + break; + + case 6: + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_008A80); + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_016620); + break; + + case 9: + if (this->unk_2E4 == 255) { + gSPDisplayList(POLY_OPA_DISP++, object_stk_DL_0087B0); + } + 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) { + Gfx_DrawDListOpa(globalCtx, object_stk_DL_006BB0); + 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_Dm_Tag/z_dm_tag.c b/src/overlays/actors/ovl_Dm_Tag/z_dm_tag.c index 59fe0236b..6290b41e0 100644 --- a/src/overlays/actors/ovl_Dm_Tag/z_dm_tag.c +++ b/src/overlays/actors/ovl_Dm_Tag/z_dm_tag.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_tag.c + * Overlay: ovl_Dm_Tag + * Description: + */ + #include "z_dm_tag.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((DmTag*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Tsg/z_dm_tsg.c b/src/overlays/actors/ovl_Dm_Tsg/z_dm_tsg.c index 5abb5d8f9..9ed86ba2c 100644 --- a/src/overlays/actors/ovl_Dm_Tsg/z_dm_tsg.c +++ b/src/overlays/actors/ovl_Dm_Tsg/z_dm_tsg.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_tsg.c + * Overlay: ovl_Dm_Tsg + * Description: Handles all the masks scrolling by as Link falls in the intro + */ + #include "z_dm_tsg.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((DmTsg*)thisx) diff --git a/src/overlays/actors/ovl_Dm_Zl/z_dm_zl.c b/src/overlays/actors/ovl_Dm_Zl/z_dm_zl.c index 7b724b9f4..fc9d21b3d 100644 --- a/src/overlays/actors/ovl_Dm_Zl/z_dm_zl.c +++ b/src/overlays/actors/ovl_Dm_Zl/z_dm_zl.c @@ -1,6 +1,12 @@ +/* + * File: z_dm_zl.c + * Overlay: ovl_Dm_Zl + * Description: Child Zelda (Cutscenes) + */ + #include "z_dm_zl.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((DmZl*)thisx) diff --git a/src/overlays/actors/ovl_Door_Ana/z_door_ana.c b/src/overlays/actors/ovl_Door_Ana/z_door_ana.c index 4db7316e4..0d1daa6b5 100644 --- a/src/overlays/actors/ovl_Door_Ana/z_door_ana.c +++ b/src/overlays/actors/ovl_Door_Ana/z_door_ana.c @@ -1,6 +1,13 @@ -#include "z_door_ana.h" +/* + * File: z_door_ana.c + * Overlay: ovl_Door_Ana + * Description: Grotto Hole Entrance + */ -#define FLAGS 0x02000000 +#include "z_door_ana.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" + +#define FLAGS (ACTOR_FLAG_2000000) #define THIS ((DoorAna*)thisx) @@ -45,8 +52,7 @@ static ColliderCylinderInit sCylinderInit = { { 50, 10, 0, { 0, 0, 0 } }, }; -// entrances grottos can link to statically, type DOORANA_TYPE_ADJACENT uses scene exit addresses instead -static u16 entrances[] = { +static u16 sEntranceIndexes[] = { 0x1A00, 0x1400, 0x1410, 0x1420, 0x1430, 0x1440, 0x1450, 0x1460, 0x1470, 0x1480, 0x1490, 0x14A0, 0x14B0, 0x14C0, 0x14D0, }; @@ -57,14 +63,15 @@ void DoorAna_SetupAction(DoorAna* this, DoorAnaActionFunc actionFunction) { void DoorAna_Init(Actor* thisx, GlobalContext* globalCtx) { DoorAna* this = THIS; - s32 grottoType = GET_DOORANA_TYPE(this); + s32 grottoType = DOORANA_GET_TYPE(&this->actor); + this->actor.shape.rot.y = this->actor.shape.rot.z = 0; - if ((grottoType == DOORANA_TYPE_UNK) || (grottoType == DOORANA_TYPE_HIDDEN)) { - if (grottoType == DOORANA_TYPE_HIDDEN) { + if (grottoType == DOORANA_TYPE_HIDDEN_STORMS || grottoType == DOORANA_TYPE_HIDDEN_BOMB) { + if (grottoType == DOORANA_TYPE_HIDDEN_BOMB) { Collider_InitAndSetCylinder(globalCtx, &this->bombCollider, &this->actor, &sCylinderInit); } else { - this->actor.flags |= 0x10; // always update + this->actor.flags |= ACTOR_FLAG_10; // always update } Actor_SetScale(&this->actor, 0); @@ -79,27 +86,27 @@ void DoorAna_Init(Actor* thisx, GlobalContext* globalCtx) { void DoorAna_Destroy(Actor* thisx, GlobalContext* globalCtx) { DoorAna* this = THIS; - s32 grottoType = GET_DOORANA_TYPE(this); + s32 grottoType = DOORANA_GET_TYPE(&this->actor); - if (grottoType == DOORANA_TYPE_HIDDEN) { + if (grottoType == DOORANA_TYPE_HIDDEN_BOMB) { Collider_DestroyCylinder(globalCtx, &this->bombCollider); } } void DoorAna_WaitClosed(DoorAna* this, GlobalContext* globalCtx) { - s32 grottoIsOpen = 0; - u32 grottoType = GET_DOORANA_TYPE(this); + s32 grottoIsOpen = false; + u32 grottoType = DOORANA_GET_TYPE(&this->actor); - if (grottoType == DOORANA_TYPE_UNK) { - // in OOT decomp its marked as open with storms, but does not seem to open with storms in MM - if ((this->actor.xyzDistToPlayerSq < 40000.0f) && (func_800F13E8(globalCtx, 5))) { - grottoIsOpen = 1; - this->actor.flags &= ~0x10; // always update OFF + if (grottoType == DOORANA_TYPE_HIDDEN_STORMS) { + //! @bug Implementation from OoT is not updated for MM, grotto does not open on Song of Storms + if (this->actor.xyzDistToPlayerSq < SQ(200.0f) && EnvFlags_Get(globalCtx, 5)) { + grottoIsOpen = true; + this->actor.flags &= ~ACTOR_FLAG_10; // always update OFF } } else { if (this->bombCollider.base.acFlags & AC_HIT) { // bomb collision - grottoIsOpen = 1; + grottoIsOpen = true; Collider_DestroyCylinder(globalCtx, &this->bombCollider); } else { @@ -109,7 +116,7 @@ void DoorAna_WaitClosed(DoorAna* this, GlobalContext* globalCtx) { } if (grottoIsOpen) { - this->actor.params &= ~DOORANA_TYPE_BITRANGE; + DOORANA_SET_TYPE(&this->actor, DOORANA_TYPE_VISIBLE); DoorAna_SetupAction(this, DoorAna_WaitOpen); play_sound(NA_SE_SY_CORRECT_CHIME); } @@ -119,55 +126,44 @@ void DoorAna_WaitClosed(DoorAna* this, GlobalContext* globalCtx) { void DoorAna_WaitOpen(DoorAna* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - s32 dooranaType = GET_DOORANA_TYPE(this); - s8 pad[4]; - s32 entranceIndex; - f32 yDist; + s32 grottoType = DOORANA_GET_TYPE(&this->actor); - if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.001f) != 0) { - if ((this->actor.targetMode != 0) && (globalCtx->sceneLoadFlag == 0) && (globalCtx->unk_18B4A == 0) && - (player->stateFlags1 & 0x80000000) && (player->unk_AE7 == 0)) { + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.001f)) { + if (this->actor.targetMode != 0 && globalCtx->sceneLoadFlag == 0 && globalCtx->unk_18B4A == 0 && + (player->stateFlags1 & 0x80000000) && player->unk_AE7 == 0) { - if (dooranaType == DOORANA_TYPE_ADJACENT) { - s32 requiredScopeTemp; + if (grottoType == DOORANA_TYPE_VISIBLE_SCENE_EXIT) { + s32 exitIndex = DOORANA_GET_EXIT_INDEX(&this->actor); - // 300 uses scene exit addresses, not static DoorAna entrance addresses, - // eg. deku playground gets address in the NCT scene exit table - - entranceIndex = GET_DOORANA_ADJACENT_ENTRANCE(this); - globalCtx->nextEntranceIndex = globalCtx->setupExitList[entranceIndex]; + globalCtx->nextEntranceIndex = globalCtx->setupExitList[exitIndex]; } else { - // unused in vanilla, the highest params bits can directly index an address - entranceIndex = GET_DOORANA_DIRECT_ENTRANCE(this); + s32 destinationIdx = DOORANA_GET_ENTRANCE(&this->actor); - func_80169E6C(globalCtx, 3, 0x4FF); + Play_SetupRespawnPoint(&globalCtx->state, RESPAWN_MODE_UNK_3, 0x4FF); - gSaveContext.respawn[3].pos.y = this->actor.world.pos.y; - gSaveContext.respawn[3].yaw = this->actor.home.rot.y; + gSaveContext.respawn[RESPAWN_MODE_UNK_3].pos.y = this->actor.world.pos.y; + gSaveContext.respawn[RESPAWN_MODE_UNK_3].yaw = this->actor.home.rot.y; - // save the params lower byte for En_Torch to decide what item to use in the grotto chest - gSaveContext.respawn[3].data = GET_DOORANA_ITEMFLAGS(this); + // Stores item and chest flag that ACTOR_EN_TORCH uses for spawning the grotto chest + gSaveContext.respawn[RESPAWN_MODE_UNK_3].data = DOORANA_GET_ITEMFLAGS(&this->actor); - // most grottos in the game use their zrotation as their entrance index, not params - if (DOORANA_TYPE_ROTATION_ENTRANCE(entranceIndex)) { - entranceIndex = GET_DOORANA_ROTATION_ENTRANCE(this); + if (destinationIdx < 0) { + destinationIdx = DOORANA_GET_EX_ENTRANCE(&this->actor); } - globalCtx->nextEntranceIndex = entrances[entranceIndex]; + globalCtx->nextEntranceIndex = sEntranceIndexes[destinationIdx]; } DoorAna_SetupAction(this, DoorAna_GrabLink); - } else { - if ((func_801690CC(globalCtx) == 0) && ((player->stateFlags1 & 0x08800000) == 0) && - (this->actor.xzDistToPlayer <= 20.0f) && (yDist = this->actor.yDistToPlayer, (yDist >= -50.0f)) && - (yDist <= 15.0f)) { - player->stateFlags1 |= 0x80000000; - this->actor.targetMode = 1; + } else if (!Play_InCsMode(globalCtx) && !(player->stateFlags1 & 0x08800000) && + (this->actor.xzDistToPlayer <= 20.0f) && (this->actor.playerHeightRel >= -50.0f) && + (this->actor.playerHeightRel <= 15.0f)) { + player->stateFlags1 |= 0x80000000; + this->actor.targetMode = 1; - } else { - this->actor.targetMode = 0; - } + } else { + this->actor.targetMode = 0; } } @@ -186,10 +182,10 @@ void DoorAna_GrabLink(DoorAna* this, GlobalContext* globalCtx) { } } - if ((this->actor.yDistToPlayer <= 0.0f) && (this->actor.xzDistToPlayer > 20.0f)) { + if (this->actor.playerHeightRel <= 0.0f && this->actor.xzDistToPlayer > 20.0f) { player = GET_PLAYER(globalCtx); - player->actor.world.pos.x = (Math_SinS(this->actor.yawTowardsPlayer) * 20.0f) + this->actor.world.pos.x; - player->actor.world.pos.z = (Math_CosS(this->actor.yawTowardsPlayer) * 20.0f) + this->actor.world.pos.z; + player->actor.world.pos.x = Math_SinS(this->actor.yawTowardsPlayer) * 20.0f + this->actor.world.pos.x; + player->actor.world.pos.z = Math_CosS(this->actor.yawTowardsPlayer) * 20.0f + this->actor.world.pos.z; } } @@ -197,9 +193,9 @@ void DoorAna_Update(Actor* thisx, GlobalContext* globalCtx) { DoorAna* this = THIS; this->actionFunc(this, globalCtx); - this->actor.shape.rot.y = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); } void DoorAna_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BE03C(globalCtx, D_05000C40); + Gfx_DrawDListXlu(globalCtx, gameplay_field_keep_DL_000C40); } diff --git a/src/overlays/actors/ovl_Door_Ana/z_door_ana.h b/src/overlays/actors/ovl_Door_Ana/z_door_ana.h index aec6e70be..0cff726e9 100644 --- a/src/overlays/actors/ovl_Door_Ana/z_door_ana.h +++ b/src/overlays/actors/ovl_Door_Ana/z_door_ana.h @@ -15,18 +15,17 @@ typedef struct DoorAna { extern const ActorInit Door_Ana_InitVars; -#define DOORANA_TYPE_REGULAR 0x000 -#define DOORANA_TYPE_UNK 0x100 -#define DOORANA_TYPE_HIDDEN 0x200 -#define DOORANA_TYPE_ADJACENT 0x300 -#define DOORANA_TYPE_BITRANGE 0x300 +#define DOORANA_TYPE_BITMASK 0x300 +#define DOORANA_TYPE_VISIBLE 0x000 +#define DOORANA_TYPE_HIDDEN_STORMS 0x100 // Incomplete, leftover from OoT +#define DOORANA_TYPE_HIDDEN_BOMB 0x200 +#define DOORANA_TYPE_VISIBLE_SCENE_EXIT 0x300 // Destination dependent on scene exit list -#define GET_DOORANA_TYPE(this)(this->actor.params & 0x300) - -#define DOORANA_TYPE_ROTATION_ENTRANCE(directEntrance)(directEntrance < 0) -#define GET_DOORANA_DIRECT_ENTRANCE(this) ((((this)->actor.params >> 0xC) & 0x7) - 1) -#define GET_DOORANA_ADJACENT_ENTRANCE(this) ((this)->actor.params & 0x1F) -#define GET_DOORANA_ROTATION_ENTRANCE(this) (this->actor.home.rot.z + 1) -#define GET_DOORANA_ITEMFLAGS(this) ((this)->actor.params & 0xFF) +#define DOORANA_GET_TYPE(thisx) ((thisx)->params & DOORANA_TYPE_BITMASK) +#define DOORANA_GET_ENTRANCE(thisx) ((((thisx)->params >> 12) & 0x7) - 1) +#define DOORANA_GET_EX_ENTRANCE(thisx) ((thisx)->home.rot.z + 1) +#define DOORANA_GET_EXIT_INDEX(thisx) ((thisx)->params & 0x1F) +#define DOORANA_GET_ITEMFLAGS(thisx) ((thisx)->params & 0xFF) +#define DOORANA_SET_TYPE(thisx, t) ((thisx)->params = ((thisx)->params & ~DOORANA_TYPE_BITMASK) + (t)) #endif // Z_DOOR_ANA_H diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c index 7b870e03d..fe52a8288 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.c @@ -1,6 +1,24 @@ -#include "z_door_shutter.h" +/* + * File: z_door_shutter.c + * Overlay: ovl_Door_Shutter + * Description: Studded Lifting Door / Ikana Castle Rolling Door + */ -#define FLAGS 0x00000010 +#include "z_door_shutter.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_bdoor/object_bdoor.h" +#include "objects/object_numa_obj/object_numa_obj.h" +#include "objects/object_hakugin_obj/object_hakugin_obj.h" +#include "objects/object_dblue_object/object_dblue_object.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" +#include "objects/object_redead_obj/object_redead_obj.h" +#include "objects/object_ikninside_obj/object_ikninside_obj.h" +#include "objects/object_random_obj/object_random_obj.h" +#include "objects/object_kinsta1_obj/object_kinsta1_obj.h" +#include "objects/object_kaizoku_obj/object_kaizoku_obj.h" +#include "objects/object_last_obj/object_last_obj.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((DoorShutter*)thisx) @@ -8,7 +26,18 @@ void DoorShutter_Init(Actor* thisx, GlobalContext* globalCtx); void DoorShutter_Destroy(Actor* thisx, GlobalContext* globalCtx); void DoorShutter_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void DoorShutter_SetupType(DoorShutter* this, GlobalContext* globalCtx); +void func_808A0F88(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1080(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1090(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1548(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1618(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1684(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1784(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1B48(DoorShutter* this, GlobalContext* globalCtx); +void func_808A1C50(DoorShutter* this, GlobalContext* globalCtx); +void DoorShutter_Draw(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Door_Shutter_InitVars = { ACTOR_DOOR_SHUTTER, ACTORCAT_DOOR, @@ -21,64 +50,668 @@ const ActorInit Door_Shutter_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808A2248[] = { +typedef struct { + /* 0x0 */ s16 objectId; + /* 0x2 */ u8 index1; + /* 0x3 */ u8 index2; +} ShutterObjectInfo; // size = 0x4 + +ShutterObjectInfo D_808A2180[] = { + { OBJECT_BDOOR, 0, 0 }, { GAMEPLAY_KEEP, 1, 1 }, { OBJECT_NUMA_OBJ, 2, 2 }, + { OBJECT_HAKUGIN_OBJ, 3, 3 }, { OBJECT_DBLUE_OBJECT, 4, 4 }, { OBJECT_IKANA_OBJ, 5, 5 }, + { OBJECT_REDEAD_OBJ, 6, 6 }, { OBJECT_IKNINSIDE_OBJ, 7, 7 }, { OBJECT_LAST_OBJ, 11, 11 }, + { OBJECT_RANDOM_OBJ, 8, 8 }, { OBJECT_KINSTA1_OBJ, 9, 9 }, { OBJECT_KAIZOKU_OBJ, 10, 10 }, +}; + +typedef struct { + /* 0x0 */ Gfx* unk_00; + /* 0x4 */ Gfx* unk_04; + /* 0x8 */ u8 unk_08; + /* 0x9 */ u8 translateZ; + /* 0xA */ u8 unk_0A; + /* 0xB */ u8 unk_0B; +} ShutterInfo; // size = 0xC + +ShutterInfo D_808A21B0[] = { + { object_bdoor_DL_0000C0, NULL, 130, 12, 50, 15 }, + { gameplay_keep_DL_077990, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_numa_obj_DL_007150, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_hakugin_obj_DL_000128, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_dblue_object_DL_017D00, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_ikana_obj_DL_014A40, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_redead_obj_DL_0001A0, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_ikninside_obj_DL_004440, object_ikninside_obj_DL_005260, 130, 0, 20, 15 }, + { object_random_obj_DL_000190, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_kinsta1_obj_DL_000198, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_kaizoku_obj_DL_0001A0, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, + { object_last_obj_DL_0039C0, gameplay_keep_DL_078A80, 130, 12, 20, 15 }, +}; + +s8 D_808A2240[] = { + -1, -1, -1, -1, -1, 0, -1, -1, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), }; -#endif +typedef struct { + /* 0x00 */ s16 sceneNum; + /* 0x02 */ u8 index; +} ShutterSceneInfo; // size = 0x4 -extern InitChainEntry D_808A2248[]; +ShutterSceneInfo D_808A2258[] = { + { SCENE_MITURIN, 2 }, { SCENE_HAKUGIN, 3 }, { SCENE_SEA, 4 }, + { SCENE_INISIE_N, 5 }, { SCENE_INISIE_R, 5 }, { SCENE_REDEAD, 6 }, + { SCENE_IKNINSIDE, 7 }, { SCENE_CASTLE, 7 }, { SCENE_RANDOM, 9 }, + { SCENE_KINSTA1, 10 }, { SCENE_KAIZOKU, 11 }, { SCENE_PIRATE, 11 }, + { SCENE_TORIDE, 11 }, { SCENE_LAST_DEKU, 8 }, { SCENE_LAST_GORON, 8 }, + { SCENE_LAST_ZORA, 8 }, { SCENE_LAST_LINK, 8 }, { -1, 1 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A08F0.s") +typedef struct { + /* 0x00 */ s16 dungeonScene; + /* 0x02 */ s16 bossScene; + /* 0x04 */ u8 index; +} BossDoorInfo; // size = 0x6 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0900.s") +BossDoorInfo D_808A22A0[] = { + { SCENE_MITURIN, SCENE_MITURIN_BS, 1 }, { SCENE_HAKUGIN, SCENE_HAKUGIN_BS, 2 }, { SCENE_SEA, SCENE_SEA_BS, 3 }, + { SCENE_INISIE_N, SCENE_INISIE_BS, 4 }, { SCENE_INISIE_R, SCENE_INISIE_BS, 4 }, { -1, -1, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0974.s") +Vec3f D_808A22C4 = { 120.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/DoorShutter_Init.s") +Vec3f D_808A22D0 = { -90.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/DoorShutter_Destroy.s") +TexturePtr D_808A22DC[] = { + object_bdoor_Tex_006BA0, object_bdoor_Tex_005BA0, object_bdoor_Tex_0005C0, + object_bdoor_Tex_004BA0, object_bdoor_Tex_003BA0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0D0C.s") +void DoorShutter_SetupAction(DoorShutter* this, DoorShutterActionFunc actionFunc) { + this->actionFunc = actionFunc; + this->unk_167 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0D90.s") +s32 func_808A0900(DoorShutter* this, GlobalContext* globalCtx) { + TransitionActorEntry* transitionEntry = &globalCtx->doorCtx.transitionActorList[DOORSHUTTER_GET_FC00(&this->actor)]; + s8 frontRoom = transitionEntry->sides[0].room; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0E28.s") + if (frontRoom == transitionEntry->sides[1].room) { + if (ABS_ALT(BINANG_SUB(this->actor.shape.rot.y, this->actor.yawTowardsPlayer)) < 0x4000) { + frontRoom = -1; + } + } + return frontRoom == this->actor.room; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A0F88.s") +s32 DoorShutter_SetupDoor(DoorShutter* this, GlobalContext* globalCtx) { + ShutterObjectInfo* sp24 = &D_808A2180[this->unk_163]; + s32 doorType = this->doorType; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1080.s") + if (doorType != 4) { + if (func_808A0900(this, globalCtx)) { + if ((doorType == 7) || (doorType == 6)) { + doorType = 1; + } else if (doorType == 5) { + doorType = 3; + } else { + doorType = 0; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1090.s") + if (doorType == 0) { + this->unk_164 = sp24->index1; + } else { + this->unk_164 = sp24->index2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1288.s") + if (doorType == 1) { + if (!Flags_GetClear(globalCtx, this->actor.room)) { + DoorShutter_SetupAction(this, func_808A0F88); + this->unk_168 = 1.0f; + return true; + } + } else if ((doorType == 2) || (doorType == 7)) { + if (!Flags_GetSwitch(globalCtx, DOORSHUTTER_GET_7F(&this->actor))) { + DoorShutter_SetupAction(this, func_808A1548); + this->unk_168 = 1.0f; + return true; + } + DoorShutter_SetupAction(this, func_808A1618); + return false; + } else if (doorType == 3) { + DoorShutter_SetupAction(this, func_808A1080); + this->unk_168 = 1.0f; + return false; + } + DoorShutter_SetupAction(this, func_808A1090); + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1340.s") +void DoorShutter_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + DoorShutter* this = THIS; + s32 sp24; + s32 i; + s8 objId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1478.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->doorType = DOORSHUTTER_GET_380(&this->actor); + sp24 = D_808A2240[this->doorType]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1548.s") + if (sp24 < 0) { + ShutterSceneInfo* shutterSceneInfo = &D_808A2258[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1618.s") + for (i = 0; i < ARRAY_COUNT(D_808A2258) - 1; i++, shutterSceneInfo++) { + if (globalCtx->sceneNum == shutterSceneInfo->sceneNum) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1684.s") + sp24 = shutterSceneInfo->index; + if (sp24 == 6) { + this->actor.flags |= ACTOR_FLAG_10000000; + } + } else if (sp24 == 0) { + BossDoorInfo* bossDoorInfo = &D_808A22A0[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1784.s") + for (i = 0; i < ARRAY_COUNT(D_808A22A0) - 1; i++, bossDoorInfo++) { + if ((globalCtx->sceneNum == bossDoorInfo->dungeonScene) || + (globalCtx->sceneNum == bossDoorInfo->bossScene)) { + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1884.s") + this->unk_15E = bossDoorInfo->index; + } else { + this->actor.room = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1A70.s") + // clang-format off + objId = Object_GetIndex(&globalCtx->objectCtx, D_808A2180[sp24].objectId); this->requiredObjBankIndex = objId; if (objId < 0) { Actor_MarkForDeath(&this->actor); return; } + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1B48.s") + DoorShutter_SetupAction(this, DoorShutter_SetupType); + this->unk_163 = sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1C50.s") + if ((this->doorType == 4) || (this->doorType == 5)) { + if (!Flags_GetSwitch(globalCtx, DOORSHUTTER_GET_7F(&this->actor))) { + this->unk_166 = 10; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/DoorShutter_Update.s") + Actor_SetFocus(&this->actor, 60.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1D68.s") +void DoorShutter_Destroy(Actor* thisx, GlobalContext* globalCtx) { + DoorShutter* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Shutter/func_808A1E14.s") + if (this->actor.room >= 0) { + s32 transitionActorId = DOORSHUTTER_GET_FC00(&this->actor); + + globalCtx->doorCtx.transitionActorList[transitionActorId].id = + -globalCtx->doorCtx.transitionActorList[transitionActorId].id; + } +} + +void DoorShutter_SetupType(DoorShutter* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->requiredObjBankIndex) && ((MREG(64) == 0) || (MREG(68) == 0))) { + this->actor.objBankIndex = this->requiredObjBankIndex; + this->actor.draw = DoorShutter_Draw; + DoorShutter_SetupDoor(this, globalCtx); + } +} + +f32 func_808A0D90(GlobalContext* globalCtx, DoorShutter* this, f32 arg2, f32 arg3, f32 arg4) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp28; + Vec3f sp1C; + + sp28.x = player->actor.world.pos.x; + sp28.y = player->actor.world.pos.y + arg2; + sp28.z = player->actor.world.pos.z; + + Actor_OffsetOfPointInActorCoords(&this->actor, &sp1C, &sp28); + + if ((arg3 < fabsf(sp1C.x)) || (arg4 < fabsf(sp1C.y))) { + return FLT_MAX; + } + return sp1C.z; +} + +s32 func_808A0E28(DoorShutter* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (!Player_InCsMode(&globalCtx->state)) { + ShutterInfo* shutterInfo = &D_808A21B0[this->unk_164]; + f32 temp_f0 = func_808A0D90(globalCtx, this, 0.0f, shutterInfo->unk_0A, shutterInfo->unk_0B); + + if (fabsf(temp_f0) < 50.0f) { + s16 temp_v0_2 = BINANG_SUB(player->actor.shape.rot.y, this->actor.shape.rot.y); + + if (temp_f0 > 0.0f) { + temp_v0_2 = 0x8000 - temp_v0_2; + } + + if (ABS_ALT(temp_v0_2) < 0x3000) { + return (temp_f0 >= 0.0f) ? 1.0f : -1.0f; + } + } + } + return false; +} + +void func_808A0F88(DoorShutter* this, GlobalContext* globalCtx) { + if (Flags_GetClear(globalCtx, this->actor.room) || Flags_GetClearTemp(globalCtx, this->actor.room)) { + this->unk_160 = this->actor.cutscene; + if (this->doorType == 7) { + if (this->unk_160 != -1) { + this->unk_160 = ActorCutscene_GetAdditionalCutscene(this->unk_160); + } + } + + if (ActorCutscene_GetCanPlayNext(this->unk_160)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_160, &this->actor); + Flags_SetClear(globalCtx, this->actor.room); + DoorShutter_SetupAction(this, func_808A1784); + this->unk_167 = -1; + } else { + ActorCutscene_SetIntentToPlay(this->unk_160); + } + } else if (func_808A0E28(this, globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + + player->doorType = -1; + player->doorActor = &this->actor; + this->actor.textId = 0x1801; + func_80122F28(player); + } +} + +void func_808A1080(DoorShutter* this, GlobalContext* globalCtx) { +} + +void func_808A1090(DoorShutter* this, GlobalContext* globalCtx) { + if (this->unk_15C != 0) { + DoorShutter_SetupAction(this, func_808A1684); + this->actor.velocity.y = 0.0f; + if (this->unk_166 != 0) { + Flags_SetSwitch(globalCtx, DOORSHUTTER_GET_7F(&this->actor)); + if (this->doorType != 5) { + gSaveContext.save.inventory.dungeonKeys[gSaveContext.mapIndex]--; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHAIN_KEY_UNLOCK); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHAIN_KEY_UNLOCK_B); + } + } + } else { + s32 doorDirection = func_808A0E28(this, globalCtx); + + if (doorDirection != 0) { + Player* player = GET_PLAYER(globalCtx); + + player->doorType = 2; + player->doorDirection = doorDirection; + player->doorActor = &this->actor; + + if (this->unk_163 == 7) { + player->doorTimer = 12; + } else { + player->doorTimer = 0; + } + + if (this->doorType == 6) { + if (gSaveContext.save.playerData.healthCapacity < (DOORSHUTTER_GET_1F(&this->actor) * 0x10)) { + player->doorType = -1; + this->actor.textId = 0x14FC; + } + } else if (this->unk_166 != 0) { + if (this->doorType == 5) { + if (!CHECK_DUNGEON_ITEM(0, gSaveContext.mapIndex)) { + player->doorType = -1; + this->actor.textId = 0x1803; + } + player->doorTimer += 10; + } else if (DUNGEON_KEY_COUNT(gSaveContext.mapIndex) <= 0) { + player->doorType = -1; + this->actor.textId = 0x1802; + } else { + player->doorTimer += 10; + } + } + func_80122F28(player); + } + } +} + +void func_808A1288(DoorShutter* this, GlobalContext* globalCtx) { + if (this->actor.category == ACTORCAT_DOOR) { + Player* player = GET_PLAYER(globalCtx); + s32 sp38 = this->unk_164; + s32 sp34 = 0xF; + + if (DoorShutter_SetupDoor(this, globalCtx)) { + sp34 = 0x20; + } + + DoorShutter_SetupAction(this, func_808A1684); + + this->unk_164 = sp38; + this->unk_168 = 0.0f; + + func_800DFFAC(globalCtx->cameraPtrs[CAM_ID_MAIN], &this->actor, player->unk_3BA, this->unk_168, 12, sp34, 10); + } +} + +s32 func_808A1340(DoorShutter* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + if (this->actor.velocity.y == 0.0f) { + func_808A1288(this, globalCtx); + if (this->unk_163 != 7) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SLIDE_DOOR_OPEN); + } + } + + if (this->unk_163 == 7) { + s32 pad; + + if (this->unk_163 == 7) { + func_800B9010(&this->actor, NA_SE_EV_IKANA_DOOR_OPEN - SFX_FLAG); + } + + Lib_Vec3f_TranslateAndRotateY(&this->actor.home.pos, this->actor.shape.rot.y, + (this->unk_163 == 7) ? &D_808A22C4 : &D_808A22D0, &sp2C); + Math_StepToF(&this->actor.velocity.y, 5.0f, 0.5f); + + if (Math_Vec3f_StepToXZ(&this->actor.world.pos, &sp2C, this->actor.velocity.y) == 0.0f) { + return true; + } + } else { + Math_StepToF(&this->actor.velocity.y, 15.0f, 3.0f); + + if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 200.0f, this->actor.velocity.y)) { + return true; + } + } + return false; +} + +s32 func_808A1478(DoorShutter* this, GlobalContext* globalCtx, f32 arg2) { + f32 temp = 1.0f - arg2; + + if (temp == this->unk_168) { + if (arg2 == 1.0f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_METALDOOR_CLOSE); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_METALDOOR_OPEN); + } + + if ((this->unk_160 != -1) && (ActorCutscene_GetCurrentIndex() == this->unk_160)) { + func_800B724C(globalCtx, &this->actor, 1); + } + } + + if (Math_StepToF(&this->unk_168, arg2, 0.2f)) { + return true; + } + return false; +} + +void func_808A1548(DoorShutter* this, GlobalContext* globalCtx) { + if (func_808A1478(this, globalCtx, 1.0f)) { + if (Flags_GetSwitch(globalCtx, DOORSHUTTER_GET_7F(&this->actor))) { + this->unk_160 = this->actor.cutscene; + if (ActorCutscene_GetCanPlayNext(this->unk_160)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_160, &this->actor); + DoorShutter_SetupAction(this, func_808A1784); + this->unk_167 = -1; + } else { + ActorCutscene_SetIntentToPlay(this->unk_160); + } + } else if (func_808A0E28(this, globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + + player->doorType = -1; + player->doorActor = &this->actor; + this->actor.textId = 0x1800; + func_80122F28(player); + } + } +} + +void func_808A1618(DoorShutter* this, GlobalContext* globalCtx) { + if ((this->unk_15C == 0) && !Flags_GetSwitch(globalCtx, DOORSHUTTER_GET_7F(&this->actor))) { + DoorShutter_SetupAction(this, func_808A1548); + } else { + func_808A1090(this, globalCtx); + } +} + +void func_808A1684(DoorShutter* this, GlobalContext* globalCtx) { + f32 phi_f0; + + if ((DECR(this->unk_166) == 0) && (globalCtx->roomCtx.unk31 == 0) && func_808A1340(this, globalCtx)) { + if (this->doorType == 5) { + phi_f0 = 20.0f; + } else { + phi_f0 = 50.0f; + } + + if (phi_f0 < this->actor.xzDistToPlayer) { + if (this->unk_163 == 7) { + this->actor.velocity.y = 0.0f; + } else { + if (DoorShutter_SetupDoor(this, globalCtx)) { + this->actor.velocity.y = 30.0f; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SLIDE_DOOR_CLOSE); + } + DoorShutter_SetupAction(this, func_808A1B48); + } + } +} + +void func_808A1784(DoorShutter* this, GlobalContext* globalCtx) { + if (this->unk_167 != 0) { + if (func_800F22C4(this->unk_160, &this->actor)) { + if (this->unk_167 < 0) { + if ((globalCtx->state.frames % 2) != 0) { + this->unk_167++; + } + } else { + this->unk_167--; + } + } + } else if (func_808A1478(this, globalCtx, 0.0f)) { + u8 doorType = this->doorType; + + if ((doorType != 0) && (doorType != 1) && + (((doorType != 7) && (doorType != 6)) || !func_808A0900(this, globalCtx))) { + DoorShutter_SetupAction(this, func_808A1618); + } else { + DoorShutter_SetupAction(this, func_808A1090); + } + func_801A2ED8(); + } +} + +void func_808A1884(DoorShutter* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s8 room = this->actor.room; + Vec3f sp44; + + if (this->actor.room >= 0) { + Actor_OffsetOfPointInActorCoords(&this->actor, &sp44, &player->actor.world.pos); + + this->actor.room = globalCtx->doorCtx.transitionActorList[DOORSHUTTER_GET_FC00(&this->actor)] + .sides[(sp44.z < 0.0f) ? 0 : 1] + .room; + + if (room != this->actor.room) { + Room temp = globalCtx->roomCtx.currRoom; + + globalCtx->roomCtx.currRoom = globalCtx->roomCtx.prevRoom; + globalCtx->roomCtx.prevRoom = temp; + globalCtx->roomCtx.activeMemPage ^= 1; + } + func_8012EBF8(globalCtx, &globalCtx->roomCtx); + } + + this->unk_15C = 0; + this->actor.velocity.y = 0.0f; + + if (DoorShutter_SetupDoor(this, globalCtx) && !(player->stateFlags1 & 0x800)) { + DoorShutter_SetupAction(this, func_808A1C50); + if (ActorCutscene_GetCurrentIndex() == 0x7D) { + func_801226E0(globalCtx, ((void)0, gSaveContext.respawn[RESTART_MODE_DOWN].data)); + player->unk_A86 = -1; + func_800B7298(globalCtx, NULL, 0x73); + } + } +} + +s32 func_808A1A70(DoorShutter* this) { + if (this->unk_163 == 7) { + if (this->unk_163 == 7) { + func_800B9010(&this->actor, NA_SE_EV_IKANA_DOOR_CLOSE - SFX_FLAG); + } + + Math_StepToF(&this->actor.velocity.y, 5.0f, 0.5f); + + if (Math_Vec3f_StepToXZ(&this->actor.world.pos, &this->actor.home.pos, this->actor.velocity.y) == 0.0f) { + return true; + } + } else { + if (this->actor.velocity.y < 20.0f) { + Math_StepToF(&this->actor.velocity.y, 20.0f, 8.0f); + } + + if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, this->actor.velocity.y)) { + return true; + } + } + return false; +} + +void func_808A1B48(DoorShutter* this, GlobalContext* globalCtx) { + s16 quake; + + if (func_808A1A70(this)) { + if (this->actor.velocity.y > 20.0f) { + this->actor.floorHeight = this->actor.home.pos.y; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 45.0f, 10, 8.0f, 500, 10, 0); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BIGWALL_BOUND); + quake = Quake_Add(Play_GetCamera(globalCtx, 0), 3); + Quake_SetSpeed(quake, -32536); + Quake_SetQuakeValues(quake, 2, 0, 0, 0); + Quake_SetCountdown(quake, 10); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 180, 20, 100); + func_808A1884(this, globalCtx); + } +} + +void func_808A1C50(DoorShutter* this, GlobalContext* globalCtx) { + if (this->unk_167++ > 30) { + if (GET_PLAYER(globalCtx)->csMode == 0x73) { + func_800B7298(globalCtx, NULL, 6); + } + DoorShutter_SetupDoor(this, globalCtx); + } +} + +void DoorShutter_Update(Actor* thisx, GlobalContext* globalCtx) { + DoorShutter* this = THIS; + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags1 & 0x100004C0) || (this->actionFunc == DoorShutter_SetupType)) { + this->actionFunc(this, globalCtx); + + if (this->unk_163 == 7) { + this->actor.home.rot.z = Math_Vec3f_DistXZ(&this->actor.home.pos, &this->actor.world.pos) * -100.0f; + } + } +} + +s32 func_808A1D68(DoorShutter* this, GlobalContext* globalCtx) { + s32 temp_a0; + s32 temp_a1; + + if (Player_InCsMode(&globalCtx->state)) { + return true; + } + + temp_a0 = BINANG_SUB(Actor_YawToPoint(&this->actor, &globalCtx->view.eye), this->actor.shape.rot.y); + temp_a1 = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); + + temp_a0 = ABS_ALT(temp_a0); + temp_a1 = ABS_ALT(temp_a1); + + if (((temp_a1 < 0x4000) && (temp_a0 > 0x4000)) || ((temp_a1 > 0x4000) && (temp_a0 < 0x4000))) { + return false; + } + return true; +} + +void DoorShutter_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DoorShutter* this = THIS; + ShutterInfo* sp44; + + if (func_808A1D68(this, globalCtx)) { + sp44 = &D_808A21B0[this->unk_164]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_164 == 7) { + Matrix_Translate(0.0f, 64.96f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.home.rot.z, MTXMODE_APPLY); + Matrix_Translate(0.0f, -64.96f, 0.0f, MTXMODE_APPLY); + } + + if (sp44->unk_04 != 0) { + TransitionActorEntry* transitionEntry = + &globalCtx->doorCtx.transitionActorList[DOORSHUTTER_GET_FC00(&this->actor)]; + + if ((globalCtx->roomCtx.prevRoom.num >= 0) || + (transitionEntry->sides[0].room == transitionEntry->sides[1].room)) { + s16 yaw = this->actor.shape.rot.y - Math_Vec3f_Yaw(&globalCtx->view.eye, &this->actor.world.pos); + + if (ABS_ALT(yaw) < 0x4000) { + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + } + } else if (this->actor.room == transitionEntry->sides[0].room) { + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + } + } else if (this->doorType == 5) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_808A22DC[this->unk_15E])); + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sp44->unk_00); + + if ((this->unk_168 != 0.0f) && (sp44->unk_04 != 0)) { + Matrix_Translate(0.0f, sp44->unk_08 * (1.0f - this->unk_168), sp44->translateZ, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sp44->unk_04); + } + + if (this->unk_166 != 0) { + Matrix_Scale(0.01f, 0.01f, 0.025f, MTXMODE_APPLY); + Actor_DrawDoorLock(globalCtx, this->unk_166, (this->doorType == 5) ? DOORLOCK_BOSS : DOORLOCK_NORMAL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h index e9da6684b..0b796d442 100644 --- a/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h +++ b/src/overlays/actors/ovl_Door_Shutter/z_door_shutter.h @@ -7,9 +7,24 @@ struct DoorShutter; typedef void (*DoorShutterActionFunc)(struct DoorShutter*, GlobalContext*); +#define DOORSHUTTER_GET_1F(thisx) ((thisx)->params & 0x1F) +#define DOORSHUTTER_GET_7F(thisx) ((thisx)->params & 0x7F) +#define DOORSHUTTER_GET_380(thisx) (((thisx)->params >> 7) & 7) +#define DOORSHUTTER_GET_FC00(thisx) (((u16)(thisx)->params >> 0xA)) + typedef struct DoorShutter { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x28]; + /* 0x0144 */ UNK_TYPE1 unk144[0x18]; + /* 0x015C */ s16 unk_15C; + /* 0x015E */ s16 unk_15E; + /* 0x0160 */ s16 unk_160; + /* 0x0162 */ u8 doorType; + /* 0x0163 */ u8 unk_163; + /* 0x0164 */ u8 unk_164; + /* 0x0165 */ s8 requiredObjBankIndex; + /* 0x0166 */ s8 unk_166; + /* 0x0167 */ s8 unk_167; + /* 0x0168 */ f32 unk_168; /* 0x016C */ DoorShutterActionFunc actionFunc; } DoorShutter; // size = 0x170 diff --git a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c index 1978756a2..a2bc8a0be 100644 --- a/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c +++ b/src/overlays/actors/ovl_Door_Spiral/z_door_spiral.c @@ -1,6 +1,20 @@ -#include "z_door_spiral.h" +/* + * File: z_door_spiral.c + * Overlay: ovl_Door_Spiral + * Description: Staircase + */ -#define FLAGS 0x00000010 +#include "z_door_spiral.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_numa_obj/object_numa_obj.h" +#include "objects/object_hakugin_obj/object_hakugin_obj.h" +#include "objects/object_ikana_obj/object_ikana_obj.h" +#include "objects/object_ikninside_obj/object_ikninside_obj.h" +#include "objects/object_danpei_object/object_danpei_object.h" + +#define FLAGS (ACTOR_FLAG_10) + +#define THIS ((DoorSpiral*)thisx) #define GET_ORIENTATION_PARAM(this) ((((Actor*)(this))->params >> 7) & 0x1) #define GET_UNK145_PARAM(this) ((((Actor*)(this))->params >> 8) & 0x3) @@ -69,29 +83,16 @@ const ActorInit Door_Spiral_InitVars = { (ActorFunc)DoorSpiral_Draw, }; -extern Gfx D_06000590[]; -extern Gfx D_060007A8[]; -extern Gfx D_06000EA0[]; -extern Gfx D_060012C0[]; -extern Gfx D_060014C8[]; -extern Gfx D_06002110[]; -extern Gfx D_06004448[]; -extern Gfx D_060051B8[]; -extern Gfx D_06006128[]; -extern Gfx D_06009278[]; -extern Gfx D_06012B70[]; -extern Gfx D_06013EA8[]; - // Parameters for each staircase, indexed with SpiralType static SpiralInfo sSpiralInfo[] = { - { { NULL, NULL }, 0, 130, 12, 50, 15 }, // SPIRAL_OVERWORLD - { { D_050219E0, D_0501D980 }, 0, 130, 12, 50, 15 }, // SPIRAL_DUNGEON - { { D_06004448, D_060007A8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE - { { D_060051B8, D_060014C8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE_ALT - { { D_06009278, D_06006128 }, 0, 130, 12, 50, 15 }, // SPIRAL_SNOWHEAD_TEMPLE - { { D_06013EA8, D_06012B70 }, 0, 130, 12, 50, 15 }, // SPIRAL_STONE_TOWER - { { D_06000EA0, D_06000590 }, 0, 130, 12, 50, 15 }, // SPIRAL_IKANA_CASTLE - { { D_06002110, D_060012C0 }, 0, 130, 12, 50, 15 }, // SPIRAL_DAMPES_HOUSE + { { NULL, NULL }, 0, 130, 12, 50, 15 }, // SPIRAL_OVERWORLD + { { gameplay_dangeon_keep_DL_0219E0, gameplay_dangeon_keep_DL_01D980 }, 0, 130, 12, 50, 15 }, // SPIRAL_DUNGEON + { { object_numa_obj_DL_004448, object_numa_obj_DL_0007A8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE + { { object_numa_obj_DL_0051B8, object_numa_obj_DL_0014C8 }, 0, 130, 12, 50, 15 }, // SPIRAL_WOODFALL_TEMPLE_ALT + { { object_hakugin_obj_DL_009278, object_hakugin_obj_DL_006128 }, 0, 130, 12, 50, 15 }, // SPIRAL_SNOWHEAD_TEMPLE + { { object_ikana_obj_DL_013EA8, object_ikana_obj_DL_012B70 }, 0, 130, 12, 50, 15 }, // SPIRAL_STONE_TOWER + { { object_ikninside_obj_DL_000EA0, object_ikninside_obj_DL_000590 }, 0, 130, 12, 50, 15 }, // SPIRAL_IKANA_CASTLE + { { object_danpei_object_DL_002110, object_danpei_object_DL_0012C0 }, 0, 130, 12, 50, 15 }, // SPIRAL_DAMPES_HOUSE }; // Defines which object bank a staircase should use, and its index to `sSpiralInfo` @@ -124,7 +125,7 @@ s32 DoorSpiral_SetSpiralType(DoorSpiral* this, GlobalContext* globalCtx) { this->spiralType = SPIRAL_WOODFALL_TEMPLE_ALT; } - this->actor.flags |= 0x10000000; + this->actor.flags |= ACTOR_FLAG_10000000; } DoorSpiral_SetupAction(this, DoorSpiral_Wait); @@ -176,7 +177,7 @@ static InitChainEntry sInitChain[] = { }; void DoorSpiral_Init(Actor* thisx, GlobalContext* globalCtx) { - DoorSpiral* this = (DoorSpiral*)thisx; + DoorSpiral* this = THIS; s32 pad; s32 transition = GET_TRANSITION_ID_PARAM(thisx); s8 objBankId; @@ -199,7 +200,7 @@ void DoorSpiral_Init(Actor* thisx, GlobalContext* globalCtx) { } DoorSpiral_SetupAction(this, DoorSpiral_WaitForObject); - Actor_SetHeight(&this->actor, 60.0f); + Actor_SetFocus(&this->actor, 60.0f); } void DoorSpiral_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -231,7 +232,7 @@ f32 DoorSpiral_GetDistFromPlayer(GlobalContext* globalCtx, DoorSpiral* this, f32 target.y = player->actor.world.pos.y + yOffset; target.z = player->actor.world.pos.z; - Actor_CalcOffsetOrientedToDrawRotation(&this->actor, &offset, &target); + Actor_OffsetOfPointInActorCoords(&this->actor, &offset, &target); if ((spiralWidth < fabsf(offset.x)) || (spiralHeight < fabsf(offset.y))) { return FLT_MAX; @@ -246,7 +247,7 @@ f32 DoorSpiral_GetDistFromPlayer(GlobalContext* globalCtx, DoorSpiral* this, f32 s32 DoorSpiral_PlayerShouldClimb(DoorSpiral* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (!(func_801233E4(globalCtx))) { + if (!Player_InCsMode(&globalCtx->state)) { SpiralInfo* spiralInfo = &sSpiralInfo[this->spiralType]; f32 dist = DoorSpiral_GetDistFromPlayer(globalCtx, this, 0.0f, spiralInfo->spiralWidth, spiralInfo->spiralHeight); @@ -285,7 +286,7 @@ void DoorSpiral_Wait(DoorSpiral* this, GlobalContext* globalCtx) { transition = GET_TRANSITION_ID_PARAM(this); player->doorNext = ((u16)globalCtx->doorCtx.transitionActorList[transition].params) >> 10; - func_80122F28(player, globalCtx, &this->actor); + func_80122F28(player); } } @@ -302,7 +303,7 @@ void DoorSpiral_PlayerClimb(DoorSpiral* this, GlobalContext* globalCtx) { } void DoorSpiral_Update(Actor* thisx, GlobalContext* globalCtx) { - DoorSpiral* this = (DoorSpiral*)thisx; + DoorSpiral* this = THIS; s32 pad; Player* player = GET_PLAYER(globalCtx); @@ -313,7 +314,7 @@ void DoorSpiral_Update(Actor* thisx, GlobalContext* globalCtx) { void DoorSpiral_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 pad; - DoorSpiral* this = (DoorSpiral*)thisx; + DoorSpiral* this = THIS; if (this->actor.objBankIndex == this->bankIndex) { SpiralInfo* spiralInfo = &sSpiralInfo[this->spiralType]; 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 0759321af..6217361f2 100644 --- a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -1,4 +1,11 @@ +/* + * File: z_door_warp1.c + * Overlay: ovl_Door_Warp1 + * Description: Blue Warp + */ + #include "z_door_warp1.h" +#include "objects/object_warp1/object_warp1.h" #define FLAGS 0x00000000 @@ -9,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, @@ -41,92 +61,1093 @@ const ActorInit Door_Warp1_InitVars = { (ActorFunc)DoorWarp1_Draw, }; -#endif +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), +}; -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_SetupAction(DoorWarp1* this, DoorWarp1ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_SetupAction.s") +s32 func_808B849C(DoorWarp1* this, GlobalContext* globalCtx) { + s32 ret = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B849C.s") + 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; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8568.s") +void func_808B8568(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B866C.s") + 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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Init.s") +s32 func_808B866C(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Destroy.s") + 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; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8924.s") +void DoorWarp1_Init(Actor* thisx, GlobalContext* globalCtx) { + DoorWarp1* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8A7C.s") + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8C48.s") + this->unk_1D3 = 0; + this->unk_1D4 = 0; + this->unk_203 = 0; + this->unk_204 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8E78.s") + 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; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B900C.s") + switch (DOORWARP1_GET_FF(&this->dyna.actor)) { + case ENDOORWARP1_FF_0: + func_808B8924(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9094.s") + case ENDOORWARP1_FF_1: + func_808B8A7C(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B90CC.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B921C.s") + case ENDOORWARP1_FF_6: + func_808B8E78(this, globalCtx); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B93A0.s") + 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; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B94A4.s") +void DoorWarp1_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DoorWarp1* this = THIS; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9524.s") + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->unk_1DC); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->unk_1F0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B958C.s") + for (i = 0; i < ARRAY_COUNT(globalCtx->envCtx.lightSettings.diffuseColor1); i++) { + globalCtx->envCtx.lightSettings.diffuseColor1[i] = 0; + globalCtx->envCtx.lightSettings.fogColor[i] = globalCtx->envCtx.lightSettings.diffuseColor1[i]; + globalCtx->envCtx.lightSettings.ambientColor[i] = globalCtx->envCtx.lightSettings.diffuseColor1[i]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B96A0.s") + if (this->unk_1D3 != 0) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B96B0.s") +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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B977C.s") +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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9840.s") +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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B98A8.s") + 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); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9B30.s") +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.save.weekEventReg[86] & 0x80) { + this->unk_1D4 = 0; + DoorWarp1_SetupAction(this, func_808B921C); + } else { + DoorWarp1_SetupAction(this, func_808B9094); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9BE8.s") +s32 func_808B900C(DoorWarp1* this, GlobalContext* globalCtx) { + s32 index; + u8 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9CE8.s") + if (Cutscene_CheckActorAction(globalCtx, 569)) { + index = Cutscene_GetActorActionIndex(globalCtx, 569); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9E94.s") + if (this->unk_208 != globalCtx->csCtx.actorActions[index]->action) { + this->unk_208 = globalCtx->csCtx.actorActions[index]->action; + if (globalCtx->csCtx.actorActions[index]->action == 2) { + ret = true; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9ED8.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9F10.s") +void func_808B9094(DoorWarp1* this, GlobalContext* globalCtx) { + if (func_808B900C(this, globalCtx)) { + DoorWarp1_SetupAction(this, func_808B90CC); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9FD0.s") +void func_808B90CC(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad[2]; + s16 sp2E = 0; + f32 phi_f0 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BA10C.s") + 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; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BA550.s") + 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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BAAF4.s") + if (this->unk_1A4 < 0.1f) { + this->unk_1D0 = sp2E + 30; + this->unk_1D4 = 0; + DoorWarp1_SetupAction(this, func_808B921C); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BABF4.s") + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WARP_HOLE_ENERGY - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Update.s") +void func_808B921C(DoorWarp1* this, GlobalContext* globalCtx) { + if (this->unk_1D0 != 0) { + this->unk_1D0--; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BACCC.s") + 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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BAE9C.s") + if (func_808B866C(this, globalCtx) && !Play_InCsMode(globalCtx)) { + func_800B7298(globalCtx, &this->dyna.actor, 7); + Message_StartTextbox(globalCtx, 0xF2, &this->dyna.actor); + DoorWarp1_SetupAction(this, func_808B93A0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB4C4.s") + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB4F4.s") +void func_808B93A0(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Draw.s") + if (Message_GetState(&globalCtx->msgCtx) == 4 && Message_ShouldAdvance(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); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB8D4.s") +void func_808B94A4(DoorWarp1* this, GlobalContext* globalCtx) { + if (!func_808B866C(this, globalCtx) && (ActorCutscene_GetCurrentIndex() != globalCtx->playerActorCsIds[8])) { + DoorWarp1_SetupAction(this, func_808B921C); + } + func_808BB8D4(this, globalCtx, 1); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} + +void func_808B9524(DoorWarp1* this, GlobalContext* globalCtx) { + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[9]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[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); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_LINK_WARP - SFX_FLAG); +} + +void func_808B96A0(DoorWarp1* this, GlobalContext* globalCtx) { +} + +void func_808B96B0(DoorWarp1* this, GlobalContext* globalCtx) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + if (func_808B866C(this, globalCtx) && !Play_InCsMode(globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + + Audio_PlaySfxGeneral(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->playerActorCsIds[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[9]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[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->state); + } + } + } + + 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) { + Actor_PlaySfxAtPos(&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)) { + Actor_PickUp(&this->dyna.actor, globalCtx, func_808B849C(this, globalCtx) + 84, 30.0f, 80.0f); + return; + } + + switch (globalCtx->sceneNum) { + case SCENE_MITURIN_BS: + gSaveContext.save.unk_ECC[0] = + (((void)0, gSaveContext.save.unk_ECC[0]) & 0xFFFFFF00) | (((u8)gSaveContext.save.unk_ECC[1]) & 0xFF); + break; + + case SCENE_HAKUGIN_BS: + gSaveContext.save.unk_ECC[0] = (((void)0, gSaveContext.save.unk_ECC[0]) & 0xFFFF00FF) | + ((((u8)gSaveContext.save.unk_ECC[1]) & 0xFF) << 8); + break; + + case SCENE_INISIE_BS: + gSaveContext.save.unk_ECC[0] = (((void)0, gSaveContext.save.unk_ECC[0]) & 0xFF00FFFF) | + ((((u8)gSaveContext.save.unk_ECC[1]) & 0xFF) << 0x10); + break; + + case SCENE_SEA_BS: + gSaveContext.save.unk_ECC[0] = (((void)0, gSaveContext.save.unk_ECC[0]) & 0x00FFFFFF) | + ((((u8)gSaveContext.save.unk_ECC[1]) & 0xFF) << 0x18); + break; + } + + gSaveContext.save.unk_ECC[1] = + (gSaveContext.save.unk_ECC[1] & 0xFFFFFF00) | ((((u8)gSaveContext.save.unk_ECC[1]) + 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 (Message_GetState(&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) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + if ((this->unk_203 == 0) && func_808B866C(this, globalCtx) && !Play_InCsMode(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->playerActorCsIds[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[9]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[9], NULL); + Audio_PlaySfxGeneral(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.save.weekEventReg[7] |= 0x80; + } + + switch (phi_v0_2) { + case 0: + phi_a0 = gSaveContext.save.unk_ECC[0] & 0xFF; + break; + + case 1: + phi_a0 = (gSaveContext.save.unk_ECC[0] & 0xFF00) >> 8; + break; + + case 2: + phi_a0 = (gSaveContext.save.unk_ECC[0] & 0xFF0000) >> 0x10; + break; + + case 3: + phi_a0 = (gSaveContext.save.unk_ECC[0] & 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.save.weekEventReg[20] & 2) { + gSaveContext.save.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.save.weekEventReg[33] |= 0x80; + globalCtx->nextEntranceIndex = 0xAE70; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + break; + + case 3: + if (gSaveContext.save.weekEventReg[55] & 0x80) { + globalCtx->nextEntranceIndex = 0x6A90; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } else { + gSaveContext.save.weekEventReg[55] |= 0x80; + globalCtx->nextEntranceIndex = 0x6A80; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } + break; + + case 2: + gSaveContext.save.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->state); + } +} + +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.fillScreen = 1; + temp_f0 = (this->unk_1D0 - 140) / 20.0f; + if (temp_f0 > 1.0f) { + temp_f0 = 1.0f; + } + globalCtx->envCtx.screenFillColor[0] = 160; + globalCtx->envCtx.screenFillColor[1] = 160; + globalCtx->envCtx.screenFillColor[2] = 160; + globalCtx->envCtx.screenFillColor[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.lightSettings.diffuseColor1[i] = temp_f16; + globalCtx->envCtx.lightSettings.fogColor[i] = temp_f16; + globalCtx->envCtx.lightSettings.ambientColor[i] = temp_f16; + } + + globalCtx->envCtx.lightSettings.fogNear = -500.0f * temp_f0; + if (globalCtx->envCtx.lightSettings.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.save.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.save.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_Translate(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_Push(); + 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_Translate(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_Pop(); + + 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_Translate(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) { + Gfx_DrawDListOpa(globalCtx, object_warp1_DL_0076C0); +} + +void func_808BB4F4(DoorWarp1* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 pad; + Color_RGB8 sp64[] = { + { 50, 150, 0 }, + { 100, 150, 200 }, + { 0, 50, 200 }, + { 120, 150, 0 }, + }; + s32 sp60 = 0; + + if (this->unk_1D4 != 0) { + Matrix_Translate(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)); + Gfx_DrawDListXlu(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_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(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); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_warp1_Matanimheader_007238)); + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.world.rot.y, MTXMODE_APPLY); + Matrix_Scale(1.0f, 0.0f, 1.0f, MTXMODE_APPLY); + + 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); +} + +void DoorWarp1_Draw(Actor* thisx, GlobalContext* globalCtx) { + DoorWarp1* this = THIS; + + switch (DOORWARP1_GET_FF(&this->dyna.actor)) { + case ENDOORWARP1_FF_0: + func_808BAE9C(this, globalCtx); + break; + + case ENDOORWARP1_FF_1: + func_808BACCC(this, globalCtx); + func_808BAE9C(this, globalCtx); + break; + + case ENDOORWARP1_FF_2: + case ENDOORWARP1_FF_3: + case ENDOORWARP1_FF_4: + case ENDOORWARP1_FF_5: + func_808BB4C4(this, globalCtx); + break; + + case ENDOORWARP1_FF_6: + func_808BB4F4(this, globalCtx); + break; + } +} + +void func_808BB8D4(DoorWarp1* this, GlobalContext* globalCtx, s32 arg2) { + static Vec3f sVelocity = { 0.0f, 0.05f, 0.0f }; + static Vec3f sAccel = { 0.0f, 0.25f, 0.0f }; + Vec3f pos; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + s32 i; + s32 rand; + s16 scale; + s32 life; + + for (i = 0; i < arg2; i++) { + rand = (Rand_ZeroOne() * 0x10000); + + pos.x = (-Math_SinS(rand - 0x8000) * 35.0f) + this->dyna.actor.world.pos.x; + pos.y = this->dyna.actor.world.pos.y; + pos.z = (Math_CosS(rand - 0x8000) * 35.0f) + this->dyna.actor.world.pos.z; + + primColor.r = 255; + primColor.g = 255; + primColor.b = 255; + envColor.r = 200; + envColor.g = 200; + envColor.b = 255; + + sAccel.y = 0.25f; + sVelocity.x = 0.0f; + sVelocity.z = 0.0f; + + scale = (Rand_ZeroOne() * 1000.0f) + 800.0f; + + life = 27; + if (arg2 >= 2) { + life = 8; + sAccel.y = 1.8f; + sVelocity.x = -Math_SinS(rand - 0x8000) * 5.0f; + sVelocity.z = Math_CosS(rand - 0x8000) * 5.0f; + } + EffectSsKirakira_SpawnDispersed(globalCtx, &pos, &sVelocity, &sAccel, &primColor, &envColor, scale, life); + } +} 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 8085af445..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,16 +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[0x30]; + /* 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 */ 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 f9f6a77f8..d7bd601f0 100644 --- a/src/overlays/actors/ovl_Eff_Change/z_eff_change.c +++ b/src/overlays/actors/ovl_Eff_Change/z_eff_change.c @@ -1,6 +1,12 @@ +/* + * File: z_eff_change.c + * Overlay: ovl_Eff_Change + * Description: Elegy of Emptiness - Beam of Light When Creating Statue + */ + #include "z_eff_change.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EffChange*)thisx) 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..211b32412 100644 --- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -1,12 +1,14 @@ /* - * File z_eff_dust.c + * File: z_eff_dust.c * Overlay: ovl_Eff_Dust * Description: Dust effects */ #include "z_eff_dust.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "system_malloc.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EffDust*)thisx) @@ -281,20 +283,20 @@ void func_80919768(Actor* thisx, GlobalContext* globalCtx2) { for (i = 0; i < ARRAY_COUNT(this->distanceTraveled); i++) { if (*distanceTraveled < 1.0f) { aux = 1.0f - SQ(*distanceTraveled); - Matrix_InsertTranslation(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); - Matrix_RotateY(sp92, MTXMODE_APPLY); - Matrix_InsertTranslation(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)), - initialPositions->y * ((this->dy * aux) + (1.0f - this->dy)), - initialPositions->z * ((this->dz * aux) + (1.0f - this->dz)), MTXMODE_APPLY); + Matrix_Translate(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(sp92, MTXMODE_APPLY); + Matrix_Translate(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)), + initialPositions->y * ((this->dy * aux) + (1.0f - this->dy)), + 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_ReplaceRotation(&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); - gSPDisplayList(POLY_XLU_DISP++, D_04054A90); + gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); } @@ -337,20 +339,20 @@ void func_809199FC(Actor* thisx, GlobalContext* globalCtx2) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (*distanceTraveled * 255.0f)); aux = 1.0f - SQ(*distanceTraveled); - Matrix_InsertMatrix(&player->mf_CC4, MTXMODE_NEW); - Matrix_InsertTranslation(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)), - (initialPositions->y * (1.0f - *distanceTraveled)) + 320.0f, - (initialPositions->z * (1.0f - *distanceTraveled)) + -20.0f, MTXMODE_APPLY); + Matrix_Mult(&player->mf_CC4, MTXMODE_NEW); + Matrix_Translate(initialPositions->x * ((this->dx * aux) + (1.0f - this->dx)), + (initialPositions->y * (1.0f - *distanceTraveled)) + 320.0f, + (initialPositions->z * (1.0f - *distanceTraveled)) + -20.0f, MTXMODE_APPLY); Matrix_Scale(*distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&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); - gSPDisplayList(POLY_XLU_DISP++, D_04054A90); + gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); gSPSetGeometryMode(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 d127a76a0..687ae1b96 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,6 +1,12 @@ +/* + * File: z_eff_kamejima_wave.c + * Overlay: ovl_Eff_Kamejima_Wave + * Description: Wave Created by Turtle Awakening + */ + #include "z_eff_kamejima_wave.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EffKamejimaWave*)thisx) 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 378fe8e3b..3901c0179 100644 --- a/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c +++ b/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c @@ -1,6 +1,12 @@ +/* + * File: z_eff_lastday.c + * Overlay: ovl_Eff_Lastday + * Description: Moon Crash Cutscene Fire Wall + */ + #include "z_eff_lastday.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EffLastday*)thisx) 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 7e114b311..b54bba577 100644 --- a/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c +++ b/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c @@ -1,6 +1,12 @@ +/* + * File: z_eff_stk.c + * Overlay: ovl_Eff_Stk + * Description: Skullkid Effects (calling down moon / cursing Link) + */ + #include "z_eff_stk.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EffStk*)thisx) 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 ff1ee7986..8ed8c6db4 100644 --- a/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c +++ b/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c @@ -1,6 +1,12 @@ +/* + * File: z_eff_zoraband.c + * Overlay: ovl_Eff_Zoraband + * Description: Indigo-Go's (Mikau's healing cutscene) + */ + #include "z_eff_zoraband.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EffZoraband*)thisx) 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 bf27f5e21..372a21d11 100644 --- a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -1,6 +1,12 @@ +/* + * File: z_elf_msg.c + * Overlay: ovl_Elf_Msg + * Description: Tatl Hint (proximity-activated C-up hint?) + */ + #include "z_elf_msg.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg*)thisx) 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 4ebc208fe..5397ca5d6 100644 --- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c +++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c @@ -1,6 +1,12 @@ +/* + * File: z_elf_msg2.c + * Overlay: ovl_Elf_Msg2 + * Description: Tatl Hint (Z-target-activated C-up hint?) + */ + #include "z_elf_msg2.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg2*)thisx) 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 fd457ac2a..dc0e5eb72 100644 --- a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c +++ b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c @@ -1,6 +1,12 @@ +/* + * File: z_elf_msg3.c + * Overlay: ovl_Elf_Msg3 + * Description: Tatl Message (Proximity-activated dialogue?) + */ + #include "z_elf_msg3.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg3*)thisx) 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 3c0d1cca4..ca7981362 100644 --- a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c +++ b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c @@ -1,6 +1,12 @@ +/* + * File: z_elf_msg4.c + * Overlay: ovl_Elf_Msg4 + * Description: Tatl Hint (another proximity-activated C-up hint?) + */ + #include "z_elf_msg4.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg4*)thisx) 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 abd811d28..aceb36807 100644 --- a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c +++ b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c @@ -1,6 +1,12 @@ +/* + * File: z_elf_msg5.c + * Overlay: ovl_Elf_Msg5 + * Description: Tatl Message (Another proximity-activated dialogue?) + */ + #include "z_elf_msg5.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg5*)thisx) 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 ec07f5fef..68c22f2d1 100644 --- a/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c +++ b/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c @@ -1,6 +1,13 @@ -#include "z_elf_msg6.h" +/* + * File: z_elf_msg6.c + * Overlay: ovl_Elf_Msg6 + * Description: Tatl Hint (another proximity-activated C-up hint?) + */ -#define FLAGS 0x00000010 +#include "z_elf_msg6.h" +#include "overlays/actors/ovl_En_Elf/z_en_elf.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ElfMsg6*)thisx) @@ -16,7 +23,6 @@ void func_80BA2048(ElfMsg6* this, GlobalContext* globalCtx); void func_80BA215C(ElfMsg6* this, GlobalContext* globalCtx); void func_80BA21C4(ElfMsg6* this, GlobalContext* globalCtx); -#if 0 const ActorInit Elf_Msg6_InitVars = { ACTOR_ELF_MSG6, ACTORCAT_ITEMACTION, @@ -29,34 +35,380 @@ const ActorInit Elf_Msg6_InitVars = { (ActorFunc)NULL, }; -#endif +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA15A0.s") +s32 func_80BA15A0(void) { + if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA) && !(gSaveContext.save.weekEventReg[87] & 0x10)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA165C.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT) && !(gSaveContext.save.weekEventReg[87] & 0x20)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA16F4.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG) && !(gSaveContext.save.weekEventReg[87] & 0x40)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/ElfMsg6_Init.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD) && !(gSaveContext.save.weekEventReg[87] & 0x80)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/ElfMsg6_Destroy.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA1C00.s") +void func_80BA165C(void) { + if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA)) { + gSaveContext.save.weekEventReg[87] |= 0x10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA1C88.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT)) { + gSaveContext.save.weekEventReg[87] |= 0x20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA1CF8.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG)) { + gSaveContext.save.weekEventReg[87] |= 0x40; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA1E30.s") + if (CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { + gSaveContext.save.weekEventReg[87] |= 0x80; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA1F80.s") +s32 func_80BA16F4(ElfMsg6* this, GlobalContext* globalCtx) { + if (!(gSaveContext.save.weekEventReg[31] & 4) && (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU)) { + this->actor.textId = 0x216; + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA2038.s") + if (!func_80BA15A0()) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA2048.s") + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA)) { + this->actor.textId = 0x256; + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA215C.s") + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT)) { + if (gSaveContext.save.weekEventReg[31] & 1) { + this->actor.textId = 0x257; + } else { + this->actor.textId = 0x231; + } + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/func_80BA21C4.s") + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG)) { + if (gSaveContext.save.weekEventReg[31] & 2) { + this->actor.textId = 0x258; + } else { + this->actor.textId = 0x232; + } + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Elf_Msg6/ElfMsg6_Update.s") + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { + if (gSaveContext.save.weekEventReg[80] & 4) { + this->actor.textId = 0x259; + } else { + this->actor.textId = 0x233; + } + return false; + } + + return true; +} + +void ElfMsg6_Init(Actor* thisx, GlobalContext* globalCtx) { + ElfMsg6* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (ABS_ALT(this->actor.home.rot.x) == 0) { + this->actor.scale.z = 0.4f; + this->actor.scale.x = 0.4f; + } else { + this->actor.scale.x = this->actor.scale.z = ABS_ALT(this->actor.home.rot.x) * 0.04f; + } + + if (this->actor.home.rot.z == 0) { + this->actor.scale.y = 0.4f; + } else { + this->actor.scale.y = this->actor.home.rot.z * 0.04f; + } + + this->actor.shape.rot.x = this->actor.shape.rot.y = this->actor.shape.rot.z = 0; + + switch (ELFMSG6_GET_F(&this->actor)) { + case 0: + this->actionFunc = func_80BA1E30; + if (func_80BA16F4(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + + case 1: + this->actionFunc = func_80BA1F80; + if ((this->actor.cutscene == -1) || ((ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) && + Flags_GetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor)))) { + Actor_MarkForDeath(&this->actor); + return; + } + + switch (ELFMSG6_GET_F0(&this->actor)) { + case 0: + if (gSaveContext.save.inventory.items[ITEM_HOOKSHOT] != ITEM_HOOKSHOT) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + + case 1: + if (gSaveContext.save.weekEventReg[83] & 2) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + break; + + case 2: + if (INV_CONTENT(ITEM_OCARINA) == ITEM_OCARINA) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (gSaveContext.save.weekEventReg[8] & 0x40) { + if (gSaveContext.save.weekEventReg[88] & 0x20) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.textId = 0x25B; + } else { + if (!(gSaveContext.save.weekEventReg[74] & 0x20) || (gSaveContext.save.weekEventReg[79] & 0x10)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.textId = 0x224; + } + this->actionFunc = func_80BA1CF8; + break; + + case 3: + if (((ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) && + Flags_GetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor))) || + (gSaveContext.save.weekEventReg[88] & 0x10) || (gSaveContext.save.weekEventReg[91] & 1) || + (INV_CONTENT(ITEM_MASK_ZORA) == ITEM_MASK_ZORA)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc = func_80BA2048; + this->actor.textId = 0x24D; + break; + + case 4: + this->actionFunc = func_80BA215C; + this->actor.textId = 0x255; + break; + + case 5: + this->actionFunc = func_80BA21C4; + this->actor.textId = 0x25E; + break; + + case 6: + this->actionFunc = func_80BA21C4; + this->actor.textId = 0x25F; + break; + + default: + this->actionFunc = func_80BA2038; + break; + } +} + +void ElfMsg6_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +s32 func_80BA1C00(ElfMsg6* this) { + return (this->actor.xzDistToPlayer < (100.0f * this->actor.scale.x)) && + ((this->actor.playerHeightRel >= 0.0f) && (this->actor.playerHeightRel < (100.0f * this->actor.scale.y))); +} + +void func_80BA1C88(ElfMsg6* this, GlobalContext* globalCtx, s16 arg2) { + Player* player = GET_PLAYER(globalCtx); + EnElf* sp20 = (EnElf*)player->tatlActor; + + if (player->tatlActor != NULL) { + player->tatlTextId = arg2; + ActorCutscene_SetIntentToPlay(0x7C); + sp20->elfMsg = &this->actor; + if (this->actor.cutscene == -1) { + this->actor.cutscene = 0x7C; + } + } +} + +void func_80BA1CF8(ElfMsg6* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnElf* sp20 = (EnElf*)player->tatlActor; + + if (player->tatlActor == NULL) { + return; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + switch (this->actor.textId) { + case 0x224: + gSaveContext.save.weekEventReg[79] |= 0x10; + break; + + case 0x25B: + gSaveContext.save.weekEventReg[88] |= 0x20; + break; + } + Actor_MarkForDeath(&this->actor); + return; + } + + if ((this->actor.textId == 0x224) && (gSaveContext.save.weekEventReg[8] & 0x40)) { + this->actor.textId = 0x25B; + } else if (func_80BA1C00(this) && (player->actor.speedXZ > 1.0f)) { + player->tatlTextId = -this->actor.textId; + ActorCutscene_SetIntentToPlay(0x7C); + sp20->elfMsg = &this->actor; + if (this->actor.cutscene == -1) { + this->actor.cutscene = 0x7C; + } + } +} + +void func_80BA1E30(ElfMsg6* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnElf* sp20 = (EnElf*)player->tatlActor; + + if (player->tatlActor == NULL) { + return; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + switch (this->actor.textId) { + case 0x216: + gSaveContext.save.weekEventReg[31] |= 4; + break; + + case 0x231: + gSaveContext.save.weekEventReg[31] |= 1; + break; + + case 0x232: + gSaveContext.save.weekEventReg[31] |= 2; + break; + + case 0x233: + gSaveContext.save.weekEventReg[80] |= 4; + break; + } + func_80BA165C(); + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80BA1C00(this) && (player->actor.speedXZ > 1.0f)) { + player->tatlTextId = -this->actor.textId; + ActorCutscene_SetIntentToPlay(0x7C); + sp20->elfMsg = &this->actor; + if (this->actor.cutscene == -1) { + this->actor.cutscene = 0x7C; + } + } +} + +void func_80BA1F80(ElfMsg6* this, GlobalContext* globalCtx) { + if (((ELFMSG6_GET_F0(&this->actor)) == 1) && (gSaveContext.save.weekEventReg[83] & 2)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80BA1C00(this)) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, NULL); + Flags_SetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor)); + Actor_MarkForDeath(&this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +void func_80BA2038(ElfMsg6* this, GlobalContext* globalCtx) { +} + +void func_80BA2048(ElfMsg6* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + EnElf* sp20 = (EnElf*)GET_PLAYER(globalCtx)->tatlActor; + + sp20->unk_264 |= 0x20; + if (ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) { + Flags_SetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor)); + } + Actor_MarkForDeath(&this->actor); + return; + } + + if (((ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) && Flags_GetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor))) || + (gSaveContext.save.weekEventReg[88] & 0x10) || (gSaveContext.save.weekEventReg[91] & 1) || + (INV_CONTENT(ITEM_MASK_ZORA) == ITEM_MASK_ZORA)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80BA1C00(this)) { + func_80BA1C88(this, globalCtx, 0x24D); + } +} + +void func_80BA215C(ElfMsg6* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80BA1C00(this)) { + func_80BA1C88(this, globalCtx, -this->actor.textId); + } +} + +void func_80BA21C4(ElfMsg6* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + EnElf* sp20 = (EnElf*)GET_PLAYER(globalCtx)->tatlActor; + + sp20->unk_264 |= 0x20; + if (ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) { + Flags_SetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor)); + } + Actor_MarkForDeath(&this->actor); + return; + } + + if (((ELFMSG6_SWITCHFLAG(&this->actor) != 0x7F) && Flags_GetSwitch(globalCtx, ELFMSG6_SWITCHFLAG(&this->actor))) || + CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80BA1C00(this)) { + func_80BA1C88(this, globalCtx, this->actor.textId); + } +} + +void ElfMsg6_Update(Actor* thisx, GlobalContext* globalCtx) { + ElfMsg6* this = THIS; + + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.h b/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.h index 05713b146..78f970de0 100644 --- a/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.h +++ b/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.h @@ -7,6 +7,10 @@ struct ElfMsg6; typedef void (*ElfMsg6ActionFunc)(struct ElfMsg6*, GlobalContext*); +#define ELFMSG6_GET_F(thisx) ((thisx)->params & 0xF) +#define ELFMSG6_GET_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define ELFMSG6_SWITCHFLAG(thisx) (((thisx)->params & 0xFE00) >> 9) + typedef struct ElfMsg6 { /* 0x0000 */ Actor actor; /* 0x0144 */ ElfMsg6ActionFunc actionFunc; 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 1f68470d9..dd719d6fb 100644 --- a/src/overlays/actors/ovl_En_Ah/z_en_ah.c +++ b/src/overlays/actors/ovl_En_Ah/z_en_ah.c @@ -1,6 +1,13 @@ -#include "z_en_ah.h" +/* + * File: z_en_ah.c + * Overlay: ovl_En_Ah + * Description: Anju's Mother + */ -#define FLAGS 0x00000039 +#include "z_en_ah.h" +#include "objects/object_ah/object_ah.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnAh*)thisx) @@ -12,7 +19,34 @@ void EnAh_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BD36B8(EnAh* this, GlobalContext* globalCtx); void func_80BD3768(EnAh* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80BD3DB0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x21 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x0B - 0x08), + /* 0x08 */ SCHEDULE_CMD_RET_VAL_L(1), + /* 0x0B */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x20 - 0x0F), + /* 0x0F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 0, 23, 0, 0x1D - 0x15), + /* 0x15 */ SCHEDULE_CMD_CHECK_FLAG_S(0x32, 0x20, 0x1C - 0x19), + /* 0x19 */ SCHEDULE_CMD_RET_VAL_L(1), + /* 0x1C */ SCHEDULE_CMD_RET_NONE(), + /* 0x1D */ SCHEDULE_CMD_RET_VAL_L(3), + /* 0x20 */ SCHEDULE_CMD_RET_NONE(), + /* 0x21 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_OMOYA, 0x37 - 0x25), + /* 0x25 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x36 - 0x29), + /* 0x29 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x30 - 0x2F), + /* 0x2F */ SCHEDULE_CMD_RET_NONE(), + /* 0x30 */ SCHEDULE_CMD_RET_TIME(18, 0, 6, 0, 2), + /* 0x36 */ SCHEDULE_CMD_RET_NONE(), + /* 0x37 */ SCHEDULE_CMD_RET_NONE(), +}; + +s32 D_80BD3DE8[] = { 0x0E28FF0C, 0x10000000 }; + +s32 D_80BD3DF0[] = { 0x0E29000C, 0x10000000 }; + +s32 D_80BD3DF8[] = { 0x00330100, 0x050E28FE, 0x0C100E28, -0x03F3F000 }; + +s32 D_80BD3E08[] = { 0x0E28FD0C, 0x0F29540C, 0x10000000 }; + const ActorInit En_Ah_InitVars = { ACTOR_EN_AH, ACTORCAT_NPC, @@ -25,75 +59,576 @@ const ActorInit En_Ah_InitVars = { (ActorFunc)EnAh_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD3E34 = { - { 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, + }, { 10, 68, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BD3E60 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_ah_Anim_001860, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_ah_Anim_001860, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_ah_Anim_002280, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_ah_Anim_000968, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_ah_Anim_000DDC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern ColliderCylinderInit D_80BD3E34; -extern CollisionCheckInfoInit2 D_80BD3E60; +s16 D_80BD3EBC[] = { 0, 0, 1, 0 }; -extern UNK_TYPE D_06009E70; +PosRot D_80BD3EC4 = { { 100.0f, 0.0f, 67.0f }, { 0, 0x349C, 0 } }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2A30.s") +PosRot D_80BD3ED8 = { { 855.0f, 260.0f, 31.0f }, { 0, 0x7FF8, 0 } }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2AE0.s") +PosRot D_80BD3EEC = { { -395.0f, 210.0f, -162.0f }, { 0, 0xBE98, 0 } }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2B0C.s") +Vec3f D_80BD3F00 = { 1000.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2BA4.s") +TexturePtr D_80BD3F0C[] = { object_ah_Tex_008D70, object_ah_Tex_009570 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2BE8.s") +TexturePtr D_80BD3F14[] = { + object_ah_Tex_006D70, object_ah_Tex_007570, object_ah_Tex_007D70, object_ah_Tex_007570, object_ah_Tex_008570, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2C6C.s") +s32 func_80BD2A30(EnAh* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* tempActor; + Actor* foundActor = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2DA0.s") + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, actorCat, actorId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2DC8.s") + if ((foundActor == NULL) || (((EnAh*)foundActor != this) && (foundActor->update != NULL))) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD2FD0.s") + tempActor = foundActor->next; + if (tempActor == NULL) { + foundActor = NULL; + break; + } + foundActor = tempActor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD30C0.s") + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3118.s") +void func_80BD2AE0(EnAh* this) { + this->skelAnime.playSpeed = this->unk_2DC; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3198.s") +s32 func_80BD2B0C(EnAh* this, s32 arg1) { + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3294.s") + if ((arg1 == 0) || (arg1 == 1)) { + if ((this->unk_300 != 0) && (this->unk_300 != 1)) { + phi_v1 = true; + } + } else if (arg1 != this->unk_300) { + phi_v1 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3320.s") + if (phi_v1) { + this->unk_300 = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->unk_2DC = this->skelAnime.playSpeed; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3374.s") +void func_80BD2BA4(EnAh* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD33FC.s") +s32 func_80BD2BE8(EnAh* this, GlobalContext* globalCtx) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3484.s") + if (this->unk_2D8 & 7) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_2D8, 0, 7); + ret = true; + this->unk_2D8 |= 8; + this->actionFunc = func_80BD3768; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3548.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD35BC.s") +void func_80BD2C6C(EnAh* this) { + s32 phi_a3 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3658.s") + if (this->unk_2D8 & 0x40) { + if (DECR(this->unk_2F8) == 0) { + switch (this->unk_2F6) { + case 1: + case 2: + if ((this->unk_2FA == 4) || (this->unk_2FA == 2)) { + phi_a3 = true; + this->unk_2FA = 4; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD36B8.s") + if (!phi_a3 && (this->unk_2FA == 4)) { + this->unk_2FA = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3768.s") + if (!phi_a3) { + this->unk_2FA++; + if (this->unk_2FA >= 4) { + if (this->unk_2F6 == 0) { + this->unk_2F8 = Rand_S16Offset(30, 30); + } else { + this->unk_2F8 = 8; + } + this->unk_2FA = 0; + phi_a3 = true; + } + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/EnAh_Init.s") + if (phi_a3 == true) { + this->unk_2FC = D_80BD3EBC[this->unk_2F6]; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/EnAh_Destroy.s") +Actor* func_80BD2DA0(EnAh* this, GlobalContext* globalCtx) { + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/EnAh_Update.s") + if (this->unk_1DC == 3) { + actor = this->actor.child; + } else { + actor = &GET_PLAYER(globalCtx)->actor; + } + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3AA8.s") +void func_80BD2DC8(EnAh* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/func_80BD3AF8.s") + Math_Vec3f_Copy(&sp40, &this->unk_1E4->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ah/EnAh_Draw.s") + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); + + Math_ApproachS(&this->unk_2EE, (sp32 - this->unk_2F2) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2EE = CLAMP(this->unk_2EE, -0x1FFE, 0x1FFE); + + Math_ApproachS(&this->unk_2F2, (sp32 - this->unk_2EE) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_2F2 = CLAMP(this->unk_2F2, -0x1C70, 0x1C70); + + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + + if (this->unk_1E4->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_1E4)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_1E4->focus.pos); + } + + Math_ApproachS(&this->unk_2EC, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2F0, 4, 0x2AA8); + this->unk_2EC = CLAMP(this->unk_2EC, -0x1554, 0x1554); + + Math_ApproachS(&this->unk_2F0, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_2EC, 4, 0x2AA8); + this->unk_2F0 = CLAMP(this->unk_2F0, -0xE38, 0xE38); +} + +void func_80BD2FD0(EnAh* this, GlobalContext* globalCtx) { + this->unk_1E4 = func_80BD2DA0(this, globalCtx); + + if ((this->unk_2D8 & 8) && (this->unk_1E4 != NULL)) { + if (DECR(this->unk_2F4) == 0) { + func_80BD2DC8(this); + this->unk_2F0 = 0; + this->unk_2F2 = 0; + this->unk_2D8 &= ~0x80; + this->unk_2D8 |= 0x20; + return; + } + } + + if (this->unk_2D8 & 0x20) { + this->unk_2D8 &= ~0x20; + this->unk_2EC = 0; + this->unk_2EE = 0; + this->unk_2F0 = 0; + this->unk_2F2 = 0; + this->unk_2F4 = 20; + } else if (DECR(this->unk_2F4) == 0) { + this->unk_2D8 |= 0x80; + } +} + +s32 func_80BD30C0(EnAh* this, GlobalContext* globalCtx) { + switch (this->unk_1DC) { + case 1: + func_80BD2B0C(this, 0); + break; + + case 2: + func_80BD2B0C(this, 4); + break; + } + return false; +} + +void func_80BD3118(EnAh* this, GlobalContext* globalCtx) { + if (this->unk_2FE == 0) { + func_80BD2B0C(this, 2); + this->unk_2FE++; + } else if ((this->unk_2FE == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80BD2B0C(this, 3); + this->unk_2FE++; + } +} + +s32 func_80BD3198(EnAh* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 temp = globalCtx->msgCtx.currentTextId; + + if (player->stateFlags1 & 0x40) { + if (this->unk_2DA != temp) { + if (temp == 0x2954) { + this->unk_18C = func_80BD3118; + this->unk_2FE = 0; + } + + switch (temp) { + case 0x28FD: + this->unk_2F6 = 1; + this->unk_2F8 = 8; + break; + + case 0x2954: + this->unk_2F6 = 2; + this->unk_2F8 = 8; + break; + } + } + this->unk_2DA = temp; + this->unk_2D8 |= 0x100; + } else if (this->unk_2D8 & 0x100) { + this->unk_18C = NULL; + this->unk_2DA = 0; + this->unk_2D8 &= ~0x100; + this->unk_2F6 = 0; + this->unk_2F8 = 4; + func_80BD30C0(this, globalCtx); + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + return false; +} + +s32* func_80BD3294(EnAh* this, GlobalContext* globalCtx) { + s32 mask = Player_GetMask(globalCtx); + + if (PLAYER_MASK_KAFEIS_MASK == mask) { + return D_80BD3E08; + } + + switch (this->unk_1DC) { + case 1: + if (gSaveContext.save.day == 2) { + return D_80BD3DF0; + } + return D_80BD3DE8; + + case 2: + return D_80BD3DF8; + } + return NULL; +} + +s32 func_80BD3320(EnAh* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + s32 pad; + s32 ret = false; + Actor* temp_v0 = func_80BD2A30(this, globalCtx, actorCat, actorId); + + if (temp_v0 != NULL) { + this->actor.child = temp_v0; + ret = true; + } + return ret; +} + +s32 func_80BD3374(EnAh* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80BD3EC4.pos); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80BD3EC4.rot); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + func_80BD2B0C(this, 0); + SubS_UpdateFlags(&this->unk_2D8, 3, 7); + this->unk_2D8 |= 0x40; + return true; +} + +s32 func_80BD33FC(EnAh* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80BD3ED8.pos); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80BD3ED8.rot); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + func_80BD2B0C(this, 4); + SubS_UpdateFlags(&this->unk_2D8, 3, 7); + this->unk_2D8 |= (0x40 | 0x10); + return true; +} + +s32 func_80BD3484(EnAh* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + if (func_80BD3320(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AN)) { + if (sREG(81) == 0) { + Math_Vec3f_Copy(&this->actor.world.pos, &D_80BD3EEC.pos); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80BD3EEC.rot); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + } + func_80BD2B0C(this, 4); + this->unk_2D8 |= (0x40 | 0x8); + this->unk_2D8 |= 0x10; + this->unk_2D8 |= 0x80; + this->actor.gravity = 0.0f; + ret = true; + } + return ret; +} + +s32 func_80BD3548(EnAh* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret; + + this->unk_2D8 = 0; + + switch (arg2->result) { + default: + ret = false; + break; + + case 1: + ret = func_80BD3374(this, globalCtx, arg2); + break; + + case 2: + ret = func_80BD33FC(this, globalCtx, arg2); + break; + + case 3: + ret = func_80BD3484(this, globalCtx, arg2); + break; + } + return ret; +} + +s32 func_80BD35BC(EnAh* this, GlobalContext* globalCtx) { + s16 temp; + s16 temp2; + + switch (this->unk_1DC) { + default: + return false; + + case 2: + temp = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); + temp2 = ABS_ALT(temp); + if (temp2 < 0x3800) { + SubS_UpdateFlags(&this->unk_2D8, 3, 7); + } else { + SubS_UpdateFlags(&this->unk_2D8, 0, 7); + } + return false; + } +} + +void func_80BD3658(EnAh* this, GlobalContext* globalCtx) { + if ((this->unk_1DC == 1) || (this->unk_1DC == 2) || (this->unk_1DC == 3)) { + func_80BD35BC(this, globalCtx); + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80BD36B8(EnAh* this, GlobalContext* globalCtx) { + ScheduleResult sp18; + + if (!Schedule_RunScript(globalCtx, D_80BD3DB0, &sp18) || + ((this->unk_1DC != sp18.result) && !func_80BD3548(this, globalCtx, &sp18))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp18.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_1DC = sp18.result; + func_80BD3658(this, globalCtx); +} + +void func_80BD3768(EnAh* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + + if (func_8010BF58(&this->actor, globalCtx, func_80BD3294(this, globalCtx), NULL, &this->unk_1E0)) { + SubS_UpdateFlags(&this->unk_2D8, 3, 7); + this->unk_2D8 &= ~8; + this->unk_2D8 |= 0x80; + this->unk_2F4 = 20; + this->unk_1E0 = 0; + this->actionFunc = func_80BD36B8; + } else if (this->unk_1DC != 2) { + if (this->unk_1E4 != NULL) { + Math_Vec3f_Copy(&sp40, &this->unk_1E4->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&sp34, &sp40), 4, 0x2AA8); + } + } +} + +void EnAh_Init(Actor* thisx, GlobalContext* globalCtx) { + EnAh* this = THIS; + + if (func_80BD2A30(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AH)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ah_Skel_009E70, NULL, this->jointTable, this->morphTable, + 17); + this->unk_300 = -1; + func_80BD2B0C(this, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + this->actor.targetMode = 6; + Actor_SetScale(&this->actor, 0.01f); + this->unk_1DC = 0; + this->unk_2D8 = 0; + + this->actionFunc = func_80BD36B8; + this->actionFunc(this, globalCtx); +} + +void EnAh_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAh* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnAh_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAh* this = THIS; + f32 radius; + f32 height; + + func_80BD2BE8(this, globalCtx); + + this->actionFunc(this, globalCtx); + + if (this->unk_1DC != 0) { + func_80BD3198(this, globalCtx); + func_80BD2AE0(this); + func_80BD2C6C(this); + func_80BD2FD0(this, globalCtx); + radius = this->collider.dim.radius + 60; + height = this->collider.dim.height + 10; + + func_8013C964(&this->actor, globalCtx, radius, height, EXCH_ITEM_NONE, this->unk_2D8 & 7); + if (!(this->unk_2D8 & 0x10)) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } + func_80BD2BA4(this, globalCtx); + } +} + +void EnAh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnAh* this = THIS; + + if (limbIndex == 7) { + Matrix_MultVec3f(&D_80BD3F00, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } +} + +void EnAh_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnAh* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->unk_2D8 & 0x80)) { + if (this->unk_2D8 & 0x20) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + stepRot = false; + overrideRot = false; + } + + if (limbIndex == 7) { + SubS_UpdateLimb(BINANG_ADD(this->unk_2EC + this->unk_2F0, 0x4000), + BINANG_ADD(this->unk_2EE + this->unk_2F2 + this->actor.shape.rot.y, 0x4000), this->unk_1E8, + this->unk_200, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_1E8[0].x, this->unk_1E8[0].y, this->unk_1E8[0].z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_200[0].y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_200[0].x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_200[0].z, MTXMODE_APPLY); + Matrix_Push(); + } else if (limbIndex == 2) { + SubS_UpdateLimb(BINANG_ADD(this->unk_2F0, 0x4000), BINANG_ADD(this->unk_2F2 + this->actor.shape.rot.y, 0x4000), + &this->unk_1E8[1], &this->unk_200[1], stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_1E8[1].x, this->unk_1E8[1].y, this->unk_1E8[1].z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_200[1].y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_200[1].x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_200[1].z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnAh_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnAh* this = THIS; + + if (this->unk_1DC != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BD3F14[this->unk_2FA])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80BD3F0C[this->unk_2FC])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnAh_PostLimbDraw, EnAh_TransformLimbDraw, + &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Ah/z_en_ah.h b/src/overlays/actors/ovl_En_Ah/z_en_ah.h index 13dd73027..85263e04b 100644 --- a/src/overlays/actors/ovl_En_Ah/z_en_ah.h +++ b/src/overlays/actors/ovl_En_Ah/z_en_ah.h @@ -6,12 +6,36 @@ struct EnAh; typedef void (*EnAhActionFunc)(struct EnAh*, GlobalContext*); +typedef void (*EnAhUnkFunc)(struct EnAh*, GlobalContext*); typedef struct EnAh { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnAhActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x178]; + /* 0x018C */ EnAhUnkFunc unk_18C; + /* 0x0190 */ ColliderCylinder collider; + /* 0x01DC */ u8 unk_1DC; + /* 0x01E0 */ s32 unk_1E0; + /* 0x01E4 */ Actor* unk_1E4; + /* 0x01E8 */ Vec3f unk_1E8[2]; + /* 0x0200 */ Vec3s unk_200[2]; + /* 0x020C */ Vec3s jointTable[17]; + /* 0x0272 */ Vec3s morphTable[17]; + /* 0x02D8 */ u16 unk_2D8; + /* 0x02DA */ u16 unk_2DA; + /* 0x02DC */ f32 unk_2DC; + /* 0x02E0 */ UNK_TYPE1 unk2E0[0xC]; + /* 0x02EC */ s16 unk_2EC; + /* 0x02EE */ s16 unk_2EE; + /* 0x02F0 */ s16 unk_2F0; + /* 0x02F2 */ s16 unk_2F2; + /* 0x02F4 */ s16 unk_2F4; + /* 0x02F6 */ s16 unk_2F6; + /* 0x02F8 */ s16 unk_2F8; + /* 0x02FA */ s16 unk_2FA; + /* 0x02FC */ s16 unk_2FC; + /* 0x02FE */ s16 unk_2FE; + /* 0x0300 */ s32 unk_300; } EnAh; // size = 0x304 extern const ActorInit En_Ah_InitVars; 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 abbc3dfea..22b2a0228 100644 --- a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c +++ b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c @@ -1,6 +1,13 @@ -#include "z_en_akindonuts.h" +/* + * File: z_en_akindonuts.c + * Overlay: ovl_En_Akindonuts + * Description: Trade quest Business Scrubs + */ -#define FLAGS 0x00000039 +#include "z_en_akindonuts.h" +#include "objects/object_dnt/object_dnt.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnAkindonuts*)thisx) @@ -9,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, @@ -22,113 +43,1671 @@ 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 AnimationInfoS sAnimations[] = { + { &object_dnt_Anim_005488, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00B0B4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_004AA0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004E38, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_005CA8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0038CC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003CC0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004700, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003438, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001E2C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_000994, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_002268, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002F08, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00577C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 8, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 4, -1, ANIMMODE_ONCE, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002670, 1.0f, 0, -1, ANIMMODE_ONCE, 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_UpdatePos(&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.save.weekEventReg[63] |= 8; + gSaveContext.save.weekEventReg[63] &= (u8)~0x10; + } else if (player->transformation == PLAYER_FORM_ZORA) { + gSaveContext.save.weekEventReg[63] &= (u8)~8; + gSaveContext.save.weekEventReg[63] |= 0x10; + } else if (player->transformation == PLAYER_FORM_GORON) { + gSaveContext.save.weekEventReg[63] |= 8; + gSaveContext.save.weekEventReg[63] |= 0x10; + } else if (player->transformation == PLAYER_FORM_HUMAN) { + gSaveContext.save.weekEventReg[63] &= (u8)~8; + gSaveContext.save.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.save.weekEventReg[63] & 8) && !(gSaveContext.save.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_ZORA) { + if (!(gSaveContext.save.weekEventReg[63] & 8) && (gSaveContext.save.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_GORON) { + if ((gSaveContext.save.weekEventReg[63] & 8) && (gSaveContext.save.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (!(gSaveContext.save.weekEventReg[63] & 8) && !(gSaveContext.save.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.save.playerData.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 (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 3) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF83C.s") + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) < 2) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF9F0.s") + if (gSaveContext.save.playerData.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 (!Interface_HasEmptyBottle()) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/EnAkindonuts_Init.s") + if (gSaveContext.save.playerData.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 (!Interface_HasEmptyBottle()) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEFFB4.s") + if (gSaveContext.save.playerData.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.save.weekEventReg[61] & 0x20)) { + gSaveContext.save.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.msgMode = 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.save.weekEventReg[61] |= 0x10; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BED680(EnAkindonuts* this, GlobalContext* globalCtx) { + switch (this->unk_33C) { + case 0: + if (func_80BED140(globalCtx) && !(gSaveContext.save.weekEventReg[61] & 0x40)) { + gSaveContext.save.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.msgMode = 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; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 1)) { + gSaveContext.save.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.msgMode = 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.save.weekEventReg[61] |= 0x80; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 2)) { + gSaveContext.save.weekEventReg[62] |= 2; + 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.msgMode = 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; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 8)) { + gSaveContext.save.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.msgMode = 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.save.weekEventReg[62] |= 4; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 0x10)) { + gSaveContext.save.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.msgMode = 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; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 0x40)) { + gSaveContext.save.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.msgMode = 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.save.weekEventReg[62] |= 0x20; + this->unk_32C |= 0x20; + break; + + case 0x1629: + this->unk_32C |= 1; + break; + } + + Message_StartTextbox(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.save.weekEventReg[62] & 0x80)) { + gSaveContext.save.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.msgMode = 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; + } + + Message_StartTextbox(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->exchangeItemId = 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->exchangeItemId = 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->exchangeItemId = 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->exchangeItemId = 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.save.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.save.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.save.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.save.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].animation->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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actionFunc = func_80BEEDC0; + this->unk_338 = 3; + this->collider.dim.height = 64; + SubS_ChangeAnimationByInfoS(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 17); + } else if (this->unk_338 == 2) { + this->unk_338 = 16; + this->collider.dim.height = 32; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + SubS_ChangeAnimationByInfoS(&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; + SubS_ChangeAnimationByInfoS(&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; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 18); + } + } + } +} + +void func_80BEEDC0(EnAkindonuts* this, GlobalContext* globalCtx) { + if (this->skelAnime.curFrame == this->skelAnime.endFrame) { + this->actionFunc = func_80BEEE10; + SubS_ChangeAnimationByInfoS(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 4); + this->actionFunc = func_80BEEB20; + } +} + +void func_80BEEFA8(EnAkindonuts* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_32C & 1) { + this->unk_32C &= ~0x1; + globalCtx->msgCtx.msgMode = 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 &= ~ACTOR_FLAG_1; + this->unk_32C &= ~0x4; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_338 = 8; + this->unk_33C = 0; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->unk_338); + this->actionFunc = func_80BEF518; + } else { + this->unk_2DC(this, globalCtx); + } + } + } else if (temp_v0 == 4) { + if (Message_ShouldAdvance(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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0; + this->actionFunc = func_80BEEE10; + } +} + +void func_80BEF20C(EnAkindonuts* this, GlobalContext* globalCtx) { + u8 sp27 = Message_GetState(&globalCtx->msgCtx); + s16 sp24 = this->skelAnime.curFrame; + s16 sp22 = Animation_GetLastFrame(&sAnimations[this->unk_338].animation->common); + + if (this->unk_356 == 40) { + this->unk_338 = 5; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 5); + } + + this->unk_356++; + + if ((sp24 == sp22) && (this->unk_338 == 5)) { + this->unk_338 = 6; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 6); + } + + if ((sp27 == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_32C & 1) { + this->unk_32C &= ~0x1; + globalCtx->msgCtx.msgMode = 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 { + Actor_PickUp(&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 { + Actor_PickUp(&this->actor, globalCtx, func_80BECFBC(this), 300.0f, 300.0f); + } +} + +void func_80BEF450(EnAkindonuts* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + this->actionFunc = func_80BEF4B8; + } +} + +void func_80BEF4B8(EnAkindonuts* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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].animation->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; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->unk_338); + Actor_PlaySfxAtPos(&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].animation->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; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->unk_338); + Actor_PlaySfxAtPos(&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; + SubS_ChangeAnimationByInfoS(&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, ActorShadow_DrawCircle, 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 = SubS_GetPathByIndex(globalCtx, ENAKINDONUTS_GET_FC00(&this->actor), 0x3F); + if (this->path == NULL) { + Actor_MarkForDeath(&this->actor); + return; + } + } + + SubS_ChangeAnimationByInfoS(&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_SetFocus(&this->actor, 60.0f); + SkelAnime_Update(&this->skelAnime); + Actor_MoveWithGravity(&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 false; +} + +void EnAkindonuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +} + +void EnAkindonuts_TransformLimbDraw(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_RotateYS(this->unk_352, MTXMODE_APPLY); + } +} + +void EnAkindonuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnAkindonuts* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnAkindonuts_OverrideLimbDraw, EnAkindonuts_PostLimbDraw, + EnAkindonuts_TransformLimbDraw, &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 239997d36..a14b2e106 100644 --- a/src/overlays/actors/ovl_En_Al/z_en_al.c +++ b/src/overlays/actors/ovl_En_Al/z_en_al.c @@ -1,6 +1,13 @@ -#include "z_en_al.h" +/* + * File: z_en_al.c + * Overlay: ovl_En_Al + * Description: Madame Aroma + */ -#define FLAGS 0x00000039 +#include "z_en_al.h" +#include "objects/object_al/object_al.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnAl*)thisx) @@ -12,7 +19,72 @@ void EnAl_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BDF5E8(EnAl* this, GlobalContext* globalCtx); void func_80BDF6C4(EnAl* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80BDFC70[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x11 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x0B - 0x0A), + /* 0x0A */ SCHEDULE_CMD_RET_NONE(), + /* 0x0B */ SCHEDULE_CMD_RET_TIME(18, 0, 6, 0, 2), + /* 0x11 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(8, 0, 10, 0, 0x46 - 0x17), + /* 0x17 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 0, 10, 55, 0x40 - 0x1D), + /* 0x1D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 55, 11, 45, 0x30 - 0x23), + /* 0x23 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 45, 20, 0, 0x2A - 0x29), + /* 0x29 */ SCHEDULE_CMD_RET_NONE(), + /* 0x2A */ SCHEDULE_CMD_RET_TIME(11, 45, 20, 0, 1), + /* 0x30 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x3A - 0x34), + /* 0x34 */ SCHEDULE_CMD_RET_TIME(10, 55, 11, 45, 1), + /* 0x3A */ SCHEDULE_CMD_RET_TIME(10, 55, 11, 45, 3), + /* 0x40 */ SCHEDULE_CMD_RET_TIME(10, 0, 10, 55, 1), + /* 0x46 */ SCHEDULE_CMD_RET_VAL_L(1), +}; + +s32 D_80BDFCBC[] = { + 0x09000017, 0x0E27A50C, 0x09000018, 0x0E27A60C, 0x09000017, 0x0E27A70C, 0x09000018, 0x0E27A80C, + 0x09000017, 0x0E27A90C, 0x09000018, 0x0E27AA0C, 0x09000017, 0x0E27AB0C, 0x09000018, 0x0E27AC0C, + 0x09000017, 0x0E27AD2D, 0x000B2D00, 0x080C1159, 0x08090000, 0x10000000, +}; + +s32 D_80BDFD14[] = { + 0x00562000, 0xA2090000, 0x170E2AA6, 0x0C090000, 0x180E2AA7, 0x0C090000, 0x170E2AA8, 0x0C090000, + 0x180E2AA9, 0x0C090000, 0x170E2AAA, 0x0C090000, 0x180E2AAB, 0x0C090000, 0x170E2AAC, 0x0C090000, + 0x170E2AAD, 0x0C0F2AAE, 0x0C090000, 0x180E2AAF, 0x0C090000, 0x170E2AB0, 0x0C090000, 0x170E2AB1, + 0x0C090000, 0x180E2AB2, 0x0C090000, 0x170E2AB3, 0x0C090000, 0x180E2AB4, 0x0C090000, 0x170E2AB5, + 0x0C090000, 0x180E2AB6, 0x0C090000, 0x170E2AB7, 0x0C090000, 0x180E2AB8, 0x2D00082D, 0x00092D00, + 0x0A0C1156, 0x20121009, 0x0000170E, 0x2AEA0C09, 0x0000180E, 0x2AEB0C09, 0x00001210, +}; + +s32 D_80BDFDD0[] = { 0x005C0800, 0x0B0E2AE5, 0x2D000811, 0x5C080C10, 0x0E2AE62D, 0x00080C10 }; + +s32 D_80BDFDE8[] = { 0x0900000E, 0x2B192D00, 0x080C1509, 0x00001210 }; + +s32 D_80BDFDF8[] = { + 0x09000000, 0x39040071, 0x0E2B1A0C, 0x0F00FF1E, 0x00330018, 0x000D0000, 0x0E2B1B2D, 0x00080C15, 0x09000012, + 0x102C2B1C, 0x0C2F0000, 0x0C19FFDC, 0x2C2B1D0C, 0x2F00000C, 0x0F2B1E0C, 0x0F2B1F0C, 0x122A002E, 0x00390800, + 0x1306006F, 0x00001300, 0x6F2F0000, 0x2E2D0023, 0x0C07000C, 0x06000500, 0x00130005, 0x0C070000, 0x0E2B202D, + 0x00080C16, 0x11390411, 0x390819FF, 0xA60E2B3C, 0x2D00080C, 0x19FF9C00, +}; + +s32 D_80BDFE7C[] = { 0x0E2A9C2D, 0x00080C10 }; + +s32 D_80BDFE84[] = { 0x0E2A9D2D, 0x00080C10 }; + +s32 D_80BDFE8C[] = { + 0x00390200, 0x0F0E2A9E, 0x0C0F2A9F, 0x0C0F2AA0, 0x0C190004, 0x0E2AA00C, 0x05000000, 0x1A001A30, 0x0E2AA20C, + 0x1206008F, 0x00001300, 0x8F2F0000, 0x2E2D002C, 0x2D00080C, 0x10310E2A, 0xA12D0008, 0x0C113902, 0x10000000, +}; + +s32 D_80BDFED4[] = { + 0x0900002C, 0x2B1D0C2F, 0x00000C0F, 0x2B1E0C0F, 0x2B1F0C12, 0x2A002E00, 0x39080013, + 0x06006F00, 0x0013006F, 0x2F00002E, 0x2D00230C, 0x07000C06, 0x00050000, 0x1300050C, + 0x0700000E, 0x2B202D00, 0x080C1611, 0x39041139, 0x08150900, 0x00121000, +}; + +s32 D_80BDFF24[] = { + 0x0900002C, 0x2B1C0C0F, 0x00FF1E00, 0x33000DFF, 0xF000000E, 0x2B1B2D00, 0x080C1509, 0x00001210, + 0x2C2B1D0C, 0x2F00000C, 0x0F2B1E0C, 0x0F2B1F0C, 0x122A002E, 0x00390800, 0x1306006F, 0x00001300, + 0x6F2F0000, 0x2E2D0023, 0x0C07000C, 0x06000500, 0x00130005, 0x0C070000, 0x0E2B202D, 0x00080C16, + 0x11390411, 0x390819FF, 0xB10E2B3C, 0x2D00080C, 0x19FFA700, +}; + const ActorInit En_Al_InitVars = { ACTOR_EN_AL, ACTORCAT_NPC, @@ -25,87 +97,829 @@ const ActorInit En_Al_InitVars = { (ActorFunc)EnAl_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BDFFB8 = { - { 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 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BDFFE4 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_al_Anim_000C54, 1.0f, 0, -1, 0, -4 }, { &object_al_Anim_00DBE0, 1.0f, 0, -1, 0, 0 }, + { &object_al_Anim_00DBE0, 1.0f, 0, -1, 0, -4 }, { &object_al_Anim_00ACA0, 1.0f, 0, -1, 2, 0 }, + { &object_al_Anim_00ACA0, -1.0f, 0, -1, 2, 0 }, { &object_al_Anim_00CA28, 1.0f, 0, -1, 0, -4 }, + { &object_al_Anim_00BCA4, 1.0f, 0, -1, 2, 0 }, { &object_al_Anim_00A764, 1.0f, 0, -1, 0, -4 }, +}; -extern ColliderCylinderInit D_80BDFFB8; -extern CollisionCheckInfoInit2 D_80BDFFE4; +Vec3f D_80BE0070 = { 1000.0f, 0.0f, 0.0f }; -extern UNK_TYPE D_0600A0D8; +Gfx* D_80BE007C[] = { + object_al_DL_006598, object_al_DL_005920, object_al_DL_005878, + object_al_DL_0057D0, object_al_DL_005728, object_al_DL_005680, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE1A0.s") +Actor* func_80BDE1A0(EnAl* this, GlobalContext* globalCtx, u8 arg0, s16 arg1) { + Actor* foundActor = NULL; + Actor* temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE250.s") + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, arg0, arg1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE27C.s") + if (foundActor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE318.s") + if ((this != (EnAl*)foundActor) && (foundActor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE384.s") + temp = foundActor->next; + if (temp == NULL) { + foundActor = NULL; + break; + } + foundActor = temp; + } + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE408.s") +void func_80BDE250(EnAl* this) { + this->skelAnime.playSpeed = this->unk_4C8; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE484.s") +s32 func_80BDE27C(EnAl* this, s32 arg1) { + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE4E0.s") + if ((arg1 == 1) || (arg1 == 2)) { + if ((this->unk_4F8 != 1) && (this->unk_4F8 != 2)) { + phi_v1 = true; + } + } else if (arg1 != this->unk_4F8) { + phi_v1 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE678.s") + if (phi_v1) { + this->unk_4F8 = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->unk_4C8 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE7FC.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDE92C.s") +void func_80BDE318(EnAl* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEA14.s") + Collider_UpdateCylinder(&this->actor, &this->unk_310); + temp = this->actor.focus.pos.y - this->actor.world.pos.y; + this->unk_310.dim.height = temp; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->unk_310.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEABC.s") +Actor* func_80BDE384(EnAl* this, GlobalContext* globalCtx) { + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEC2C.s") + switch (this->unk_35C) { + case 2: + if (!(gSaveContext.save.weekEventReg[89] & 8) && (gSaveContext.save.weekEventReg[85] & 0x80)) { + actor = func_80BDE1A0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_PM); + } else { + actor = &GET_PLAYER(globalCtx)->actor; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDED20.s") + case 3: + actor = this->unk_368; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEE5C.s") + default: + actor = &GET_PLAYER(globalCtx)->actor; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEF3C.s") + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDEFE4.s") +s32 func_80BDE408(EnAl* this, s16 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF064.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_Al/func_80BDF244.s") +s16 func_80BDE484(EnAl* this, s32 arg1) { + s16 cs = this->actor.cutscene; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF308.s") + for (i = 0; i < arg1; i++) { + cs = ActorCutscene_GetAdditionalCutscene(cs); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF390.s") + return cs; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF414.s") +s32 func_80BDE4E0(EnAl* this, s16* arg1, s16 arg2) { + s32 ret = false; + s16 sp42; + Vec3f sp34; + Vec3f sp28; + s32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF568.s") + if ((this->unk_368 == NULL) || (this->unk_368->update == NULL)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF578.s") + if (arg2 == *arg1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHAIR_ROLL); + func_80BDE27C(this, 3); + this->unk_4E8 = 0; + (*arg1)++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF5E8.s") + if ((arg2 + 1) == *arg1) { + Math_Vec3f_Copy(&sp28, &this->unk_368->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp42 = Math_Vec3f_Yaw(&sp34, &sp28); + temp = sp42 / 364; + this->unk_4E8++; + if ((temp != (this->actor.world.rot.y / 364)) && (this->unk_4E8 < 20)) { + Math_ApproachS(&this->actor.world.rot.y, sp42, 3, 0x2AA8); + } else { + func_80BDE27C(this, 5); + this->actor.world.rot.y = sp42; + this->unk_4E8 = 0; + (*arg1)++; + ret = true; + } + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF6C4.s") +s32 func_80BDE678(EnAl* this, s16* arg1, s16 arg2) { + s32 ret = false; + s16 sp22; + s32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/EnAl_Init.s") + if ((this->unk_368 == NULL) || (this->unk_368->update == NULL)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/EnAl_Destroy.s") + if (arg2 == *arg1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHAIR_ROLL); + func_80BDE27C(this, 4); + this->unk_4E8 = 0; + (*arg1)++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/EnAl_Update.s") + if ((arg2 + 1) == *arg1) { + sp22 = this->actor.home.rot.y; + temp = sp22 / 364; + this->unk_4E8++; + if ((temp != (this->actor.world.rot.y / 364)) && (this->unk_4E8 < 20)) { + Math_ApproachS(&this->actor.world.rot.y, sp22, 3, 0x2AA8); + } else { + func_80BDE27C(this, 2); + this->actor.world.rot.y = sp22; + this->unk_4E8 = 0; + (*arg1)++; + ret = true; + } + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF914.s") +s32 func_80BDE7FC(EnAl* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A = func_80BDE484(this, 0); + s32 pad2; + s32 sp20 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDF950.s") + switch (this->unk_4E6) { + case 0: + if (!func_80BDE408(this, sp2A)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/func_80BDFA34.s") + case 2: + case 4: + case 6: + case 8: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), + this->actor.child); + } + this->unk_4E6++; + sp20 = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Al/EnAl_Draw.s") + case 1: + case 3: + case 5: + case 7: + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + this->unk_4E6++; + sp20 = true; + break; + + case 9: + ActorCutscene_Stop(sp2A); + this->unk_4E6++; + sp20 = true; + break; + } + return sp20; +} + +s32 func_80BDE92C(EnAl* this, GlobalContext* globalCtx) { + s32 pad[2]; + Actor* sp1C = func_80BDE1A0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_GM); + Actor* temp_v0 = func_80BDE1A0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TOTO); + + if ((sp1C == NULL) || (sp1C->update == NULL) || (temp_v0 == NULL) || (temp_v0->update == NULL)) { + this->unk_4E6++; + return true; + } + + switch (this->unk_4E6) { + case 0: + case 1: + case 3: + case 5: + case 8: + case 10: + case 11: + case 13: + case 15: + case 17: + this->actor.child = sp1C; + this->unk_4E6++; + break; + + case 7: + case 9: + case 12: + this->actor.child = temp_v0; + this->unk_4E6++; + break; + + case 2: + case 4: + case 6: + case 14: + case 16: + this->unk_4E6++; + break; + + default: + this->unk_4E6++; + break; + } + return true; +} + +s32 func_80BDEA14(EnAl* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp18 = false; + + switch (this->unk_4E6) { + case 0: + case 1: + if ((gSaveContext.save.weekEventReg[75] & 2)) { + sp18 = true; + } else if (func_80BDE4E0(this, &this->unk_4E6, 0)) { + sp18 = true; + } + break; + + case 2: + case 3: + if (func_80BDE678(this, &this->unk_4E6, 2)) { + sp18 = true; + } + break; + } + return sp18; +} + +s32* func_80BDEABC(EnAl* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_35C == 3) { + this->unk_4EC = func_80BDE92C; + return D_80BDFD14; + } + + switch (this->unk_35C) { + case 1: + if (player->transformation == PLAYER_FORM_DEKU) { + return D_80BDFDD0; + } + + if (INV_CONTENT(ITEM_MASK_KAFEIS_MASK) != ITEM_MASK_KAFEIS_MASK) { + return D_80BDFE8C; + } + + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + return D_80BDFE7C; + } + return D_80BDFE84; + + case 2: + if (!(gSaveContext.save.weekEventReg[89] & 8) && (gSaveContext.save.weekEventReg[85] & 0x80)) { + this->unk_4EC = func_80BDE7FC; + return D_80BDFCBC; + } + + this->unk_4EC = func_80BDEA14; + if (Player_GetMask(globalCtx) != PLAYER_MASK_KAFEIS_MASK) { + return D_80BDFDE8; + } + + if (this->unk_4C2 & 0x800) { + return D_80BDFED4; + } + + if (this->unk_4C2 & 0x1000) { + return D_80BDFF24; + } + return D_80BDFDF8; + } + return NULL; +} + +s32 func_80BDEC2C(EnAl* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; + + if ((this->unk_4C2 & 7) && Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_4C2 &= ~0x1800; + if (player->exchangeItemId == 0x33) { + this->unk_4C2 |= 0x800; + this->unk_4F4 = player->exchangeItemId; + } else if (player->exchangeItemId != 0) { + this->unk_4C2 |= 0x1000; + this->unk_4F4 = player->exchangeItemId; + } + SubS_UpdateFlags(&this->unk_4C2, 0, 7); + this->unk_4E6 = 0; + this->unk_4EC = 0; + this->actor.child = this->unk_368; + this->unk_360 = func_80BDEABC(this, globalCtx); + this->unk_4C2 |= 0x20; + this->actionFunc = func_80BDF6C4; + ret = true; + } + + return ret; +} + +void func_80BDED20(EnAl* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s32 pad2; + + Math_Vec3f_Copy(&sp40, &this->unk_368->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + + Math_ApproachS(&this->unk_4DE, Math_Vec3f_Yaw(&sp34, &sp40) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_4DE = CLAMP(this->unk_4DE, -0x1FFE, 0x1FFE); + + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + + if (this->unk_368->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_368)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_368->focus.pos); + } + + Math_ApproachS(&this->unk_4DC, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x2AA8); + this->unk_4DC = CLAMP(this->unk_4DC, -0x1554, 0x1554); +} + +void func_80BDEE5C(EnAl* this) { + if (this->unk_4C2 & 0x20) { + if ((this->unk_368 != NULL) && (this->unk_368->update != NULL)) { + if (DECR(this->unk_4E2) == 0) { + func_80BDED20(this); + this->unk_4C2 &= ~0x200; + this->unk_4C2 |= 0x80; + return; + } + } + } + + if (this->unk_4C2 & 0x80) { + this->unk_4C2 &= ~0x80; + this->unk_4DC = 0; + this->unk_4DE = 0; + this->unk_4E2 = 0x14; + } else if (DECR(this->unk_4E2) == 0) { + this->unk_4C2 |= 0x200; + } +} + +void func_80BDEF3C(EnAl* this, GlobalContext* globalCtx) { + if (this->unk_4E4 == 0) { + func_80BDE27C(this, 7); + this->unk_4C2 &= ~0x20; + this->unk_4C2 |= 0x200; + this->unk_4E4++; + } else if ((this->unk_4E4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80BDE27C(this, 0); + this->unk_4C2 &= ~0x200; + this->unk_4C2 |= 0x20; + this->unk_4E4++; + } +} + +void func_80BDEFE4(EnAl* this, GlobalContext* globalCtx) { + if (this->unk_4E4 == 0) { + func_80BDE27C(this, 6); + this->unk_4E4 += 1; + } else if ((this->unk_4E4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80BDE27C(this, 5); + this->unk_4E4 += 1; + } +} + +s32 func_80BDF064(EnAl* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 sp22 = globalCtx->msgCtx.currentTextId; + Actor* sp1C = func_80BDE1A0(this, globalCtx, 4, 0xA4); + Actor* temp_v0 = func_80BDE1A0(this, globalCtx, 4, 0x234); + + if (player->stateFlags1 & 0x40) { + this->unk_4C2 |= 0x400; + if (this->unk_4C4 != sp22) { + switch (sp22) { + case 0x2AA6: + case 0x2AAF: + case 0x2AB4: + if ((sp1C != NULL) && (sp1C->update != NULL)) { + this->unk_368 = sp1C; + } + break; + + case 0x2AAD: + case 0x2AB0: + if ((temp_v0 != NULL) && (temp_v0->update != NULL)) { + this->unk_368 = temp_v0; + } + break; + } + + switch (sp22) { + case 0x2AA1: + case 0x2AA2: + case 0x2AA7: + case 0x2AE6: + case 0x2AE8: + case 0x2AE9: + case 0x2AB4: + this->unk_18C = func_80BDEF3C; + this->unk_4E4 = 0; + break; + + case 0x27A6: + case 0x27A8: + case 0x27AA: + case 0x2B1E: + this->unk_18C = func_80BDEFE4; + this->unk_4E4 = 0; + break; + + case 0x2B19: + case 0x2B20: + case 0x2B3C: + func_80BDE27C(this, 5); + break; + } + } + this->unk_4C4 = sp22; + } else if (this->unk_4C2 & 0x400) { + this->unk_4C4 = 0; + this->unk_4C2 &= ~0x400; + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + return false; +} + +s32 func_80BDF244(EnAl* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + Actor* sp20 = func_80BDE1A0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_GM); + Actor* temp_v0 = func_80BDE1A0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TOTO); + + if ((sp20 != NULL) && (sp20->update != NULL) && (temp_v0 != NULL) && (temp_v0->update != NULL)) { + func_80BDE27C(this, 0); + SubS_UpdateFlags(&this->unk_4C2, 3, 7); + this->unk_368 = sp20; + this->unk_4C2 |= 0x20; + ret = true; + } + return ret; +} + +s32 func_80BDF308(EnAl* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + SubS_UpdateFlags(&this->unk_4C2, 3, 7); + + switch (arg2->result) { + case 1: + func_80BDE27C(this, 0); + break; + + case 2: + this->unk_4F0 = EXCH_ITEM_NONE; + this->unk_4EA = 0; + func_80BDE27C(this, 2); + break; + } + return true; +} + +s32 func_80BDF390(EnAl* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret; + + this->actor.flags |= ACTOR_FLAG_1; + this->actor.targetMode = 0; + this->unk_4F0 = EXCH_ITEM_NONE; + this->unk_4C2 = 0; + this->unk_4D4 = 40.0f; + + switch (arg2->result) { + case 3: + ret = func_80BDF244(this, globalCtx, arg2); + break; + + case 1: + case 2: + ret = func_80BDF308(this, globalCtx, arg2); + break; + + default: + ret = false; + break; + } + return ret; +} + +void func_80BDF414(EnAl* this, GlobalContext* globalCtx) { + s16 temp_v0; + + switch (this->unk_4EA) { + case 0: + case 1: + if (!(gSaveContext.save.weekEventReg[89] & 8)) { + if (gSaveContext.save.weekEventReg[85] & 0x80) { + func_80BDE4E0(this, &this->unk_4EA, 0); + } + } + break; + + case 2: + if (gSaveContext.save.weekEventReg[89] & 8) { + this->unk_4EA++; + } + break; + + case 3: + case 4: + func_80BDE678(this, &this->unk_4EA, 3); + break; + } + + temp_v0 = this->actor.world.rot.y - this->actor.yawTowardsPlayer; + if (((this->unk_4EA == 0) && (ABS_ALT(temp_v0) >= 0x5800)) || + ((this->unk_4EA == 5) && (ABS_ALT(temp_v0) >= 0x5800)) || (this->unk_4EA == 2)) { + SubS_UpdateFlags(&this->unk_4C2, 3, 7); + } else { + SubS_UpdateFlags(&this->unk_4C2, 0, 7); + } +} + +void func_80BDF568(EnAl* this, GlobalContext* globalCtx) { +} + +void func_80BDF578(EnAl* this, GlobalContext* globalCtx) { + switch (this->unk_35C) { + case 1: + case 3: + func_80BDF568(this, globalCtx); + break; + + case 2: + func_80BDF414(this, globalCtx); + break; + } + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80BDF5E8(EnAl* this, GlobalContext* globalCtx) { + ScheduleResult sp20; + + this->unk_4E0 = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BDFC70, &sp20) || + ((this->unk_35C != sp20.result) && !func_80BDF390(this, globalCtx, &sp20))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp20.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_35C = sp20.result; + this->unk_368 = func_80BDE384(this, globalCtx); + func_80BDF578(this, globalCtx); +} + +void func_80BDF6C4(EnAl* this, GlobalContext* globalCtx) { + if (func_8010BF58(&this->actor, globalCtx, this->unk_360, this->unk_4EC, &this->unk_364)) { + SubS_UpdateFlags(&this->unk_4C2, 3, 7); + this->unk_4C2 &= ~0x20; + this->unk_4C2 |= 0x200; + this->actor.child = NULL; + this->unk_4E2 = 20; + this->unk_364 = 0; + this->actionFunc = func_80BDF5E8; + } else { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); + } +} + +void EnAl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnAl* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_al_Skel_00A0D8, NULL, this->jointTable, this->morphTable, + 27); + this->unk_4F8 = -1; + func_80BDE27C(this, 1); + Collider_InitAndSetCylinder(globalCtx, &this->unk_310, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->unk_35C = 0; + this->actionFunc = func_80BDF5E8; + + this->actionFunc(this, globalCtx); +} + +void EnAl_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAl* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->unk_310); +} + +void EnAl_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAl* this = THIS; + + func_80BDEC2C(this, globalCtx); + + this->actionFunc(this, globalCtx); + + func_80BDF064(this, globalCtx); + + if (this->unk_35C != 0) { + func_80BDE250(this); + func_80BDEE5C(this); + func_8013C964(&this->actor, globalCtx, this->unk_4D4, 30.0f, this->unk_4F0, this->unk_4C2 & 7); + func_80BDE318(this, globalCtx); + } +} + +s32 EnAl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + switch (limbIndex) { + case 3: + case 11: + case 12: + case 13: + case 14: + case 15: + *dList = NULL; + break; + + case 16: + break; + } + return false; +} + +void EnAl_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnAl* this = THIS; + + switch (limbIndex) { + case 3: + Matrix_Get(&this->unk_190[0]); + break; + + case 11: + Matrix_Get(&this->unk_190[1]); + break; + + case 12: + Matrix_Get(&this->unk_190[2]); + break; + + case 13: + Matrix_Get(&this->unk_190[3]); + break; + + case 14: + Matrix_Get(&this->unk_190[4]); + break; + + case 15: + Matrix_Get(&this->unk_190[5]); + break; + + case 16: + Matrix_MultVec3f(&D_80BE0070, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + break; + } +} + +void EnAl_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnAl* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->unk_4C2 & 0x200)) { + if (this->unk_4C2 & 0x80) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + overrideRot = false; + stepRot = false; + } + + if (limbIndex == 16) { + SubS_UpdateLimb(this->unk_4DC + 0x4000, this->unk_4DE + this->actor.shape.rot.y + 0x4000, &this->unk_36C, + &this->unk_378, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_36C.x, this->unk_36C.y, this->unk_36C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_378.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_378.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_378.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnAl_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnAl* this = THIS; + s32 i; + + if (this->unk_35C != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(0.0f, 0.0f, 850.0f, MTXMODE_APPLY); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnAl_OverrideLimbDraw, EnAl_PostLimbDraw, + EnAl_TransformLimbDraw, &this->actor); + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) { + Matrix_Put(&this->unk_190[i]); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_80BE007C[i]); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Al/z_en_al.h b/src/overlays/actors/ovl_En_Al/z_en_al.h index a4a8cf999..9e5ee8872 100644 --- a/src/overlays/actors/ovl_En_Al/z_en_al.h +++ b/src/overlays/actors/ovl_En_Al/z_en_al.h @@ -6,12 +6,43 @@ struct EnAl; typedef void (*EnAlActionFunc)(struct EnAl*, GlobalContext*); +typedef s32 (*EnAlUnkFunc)(struct EnAl*, GlobalContext*); +typedef void (*EnAlUnkFunc2)(struct EnAl*, GlobalContext*); typedef struct EnAl { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnAlActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x374]; + /* 0x018C */ EnAlUnkFunc2 unk_18C; + /* 0x0190 */ MtxF unk_190[6]; + /* 0x0310 */ ColliderCylinder unk_310; + /* 0x035C */ u8 unk_35C; + /* 0x0360 */ s32* unk_360; + /* 0x0364 */ s32 unk_364; + /* 0x0368 */ Actor* unk_368; + /* 0x036C */ Vec3f unk_36C; + /* 0x0378 */ Vec3s unk_378; + /* 0x037E */ Vec3s jointTable[27]; + /* 0x0420 */ Vec3s morphTable[27]; + /* 0x04C2 */ u16 unk_4C2; + /* 0x04C4 */ u16 unk_4C4; + /* 0x04C8 */ f32 unk_4C8; + /* 0x04CC */ UNK_TYPE1 unk4CC[8]; + /* 0x04D4 */ f32 unk_4D4; + /* 0x04D8 */ UNK_TYPE1 unk4D8[4]; + /* 0x04DC */ s16 unk_4DC; + /* 0x04DE */ s16 unk_4DE; + /* 0x04E0 */ s16 unk_4E0; + /* 0x04E2 */ s16 unk_4E2; + /* 0x04E4 */ s16 unk_4E4; + /* 0x04E6 */ s16 unk_4E6; + /* 0x04E8 */ s16 unk_4E8; + /* 0x04EA */ s16 unk_4EA; + /* 0x04EC */ EnAlUnkFunc unk_4EC; + /* 0x04F0 */ s32 unk_4F0; + /* 0x04F4 */ s32 unk_4F4; + /* 0x04F8 */ s32 unk_4F8; + /* 0x04FC */ UNK_TYPE1 unk4FC[4]; } EnAl; // size = 0x500 extern const ActorInit En_Al_InitVars; 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 411b25f2b..00c07327e 100644 --- a/src/overlays/actors/ovl_En_Am/z_en_am.c +++ b/src/overlays/actors/ovl_En_Am/z_en_am.c @@ -1,6 +1,14 @@ -#include "z_en_am.h" +/* + * File: z_en_am.c + * Overlay: ovl_En_Am + * Description: Armos + */ -#define FLAGS 0x00000405 +#include "z_en_am.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "overlays/actors/ovl_En_Bombf/z_en_bombf.h" + +#define FLAGS (ACTOR_FLAG_400 | ACTOR_FLAG_4 | ACTOR_FLAG_1) #define THIS ((EnAm*)thisx) @@ -9,18 +17,26 @@ void EnAm_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnAm_Update(Actor* thisx, GlobalContext* globalCtx); void EnAm_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808B0040(EnAm* this, GlobalContext* globalCtx); -void func_808B0124(EnAm* this, GlobalContext* globalCtx); +void func_808AFF9C(EnAm* this); +void EnAm_RemoveEnemyTexture(EnAm* this, GlobalContext* globalCtx); +void EnAm_WakeUp(EnAm* this); +void EnAm_ApplyEnemyTexture(EnAm* this, GlobalContext* globalCtx); +void func_808B0358(EnAm* this); void func_808B03C0(EnAm* this, GlobalContext* globalCtx); +void func_808B0460(EnAm* this); void func_808B04A8(EnAm* this, GlobalContext* globalCtx); void func_808B0508(EnAm* this, GlobalContext* globalCtx); +void func_808B057C(EnAm* this); void func_808B05C8(EnAm* this, GlobalContext* globalCtx); +void func_808B0640(EnAm* this); void func_808B066C(EnAm* this, GlobalContext* globalCtx); +void EnAm_TakeDamage(EnAm* this, GlobalContext* globalCtx); void func_808B07A8(EnAm* this, GlobalContext* globalCtx); +void func_808B0820(EnAm* this); void func_808B0894(EnAm* this, GlobalContext* globalCtx); void func_808B0B4C(EnAm* this, GlobalContext* globalCtx); +void EnAm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor); -#if 0 const ActorInit En_Am_InitVars = { ACTOR_EN_AM, ACTORCAT_ENEMY, @@ -33,22 +49,47 @@ const ActorInit En_Am_InitVars = { (ActorFunc)EnAm_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808B1070 = { - { COLTYPE_HIT5, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0x81C2C788, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sEnemyCylinderInit = { + { + COLTYPE_HIT5, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0x81C2C788, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 23, 98, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808B109C = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x760D3877, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x760D3877, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 23, 98, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_808B10C8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xF), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0xF), @@ -83,81 +124,449 @@ static DamageTable D_808B10C8 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808B10E8 = { 1, 23, 98, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 1, 23, 98, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808B10F0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 14, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 19, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -4000, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP), }; -#endif +static Vec3f sVelocity = { 0.0f, -1.5f, 0.0f }; -extern ColliderCylinderInit D_808B1070; -extern ColliderCylinderInit D_808B109C; -extern DamageTable D_808B10C8; -extern CollisionCheckInfoInit D_808B10E8; -extern InitChainEntry D_808B10F0[]; +static Vec3f sAccel = { 0.0f, -(1.0f / 5.0f), 0.0f }; -extern UNK_TYPE D_06000238; -extern UNK_TYPE D_0600033C; -extern UNK_TYPE D_06005B3C; +static Color_RGBA8 D_808B1118 = { 100, 100, 100, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/EnAm_Init.s") +static Color_RGBA8 D_808B111C = { 40, 40, 40, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/EnAm_Destroy.s") +static Color_RGBA8 D_808B1120 = { 150, 150, 150, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808AFE38.s") +static Color_RGBA8 D_808B1124 = { 100, 100, 100, 150 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808AFF9C.s") +static Vec3f D_808B1128[] = { + { 4700.0f, -500.0f, 1800.0f }, { 4700.0f, -500.0f, -1800.0f }, { 2000.0f, -1500.0f, 0.0f }, + { 2000.0f, 0.0f, -1500.0f }, { 2000.0f, 0.0f, 1500.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0040.s") +static Vec3f D_808B1164[] = { + { 0.0f, -3000.0f, 0.0f }, + { 700.0f, -800.0f, 0.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B00D8.s") +static Vec3f D_808B117C[] = { + { 800.0f, 1000.0f, -1000.0f }, + { 800.0f, 1000.0f, 1000.0f }, + { 800.0f, -1000.0f, 1000.0f }, + { 800.0f, -1000.0f, -1000.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0124.s") +void EnAm_Init(Actor* thisx, GlobalContext* globalCtx) { + EnAm* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0208.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 300.0f / 7.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_am_Skel_005948, &gArmosPushedBackAnim, this->jointTable, + this->morphTable, OBJECT_AM_LIMB_MAX); + Collider_InitAndSetCylinder(globalCtx, &this->enemyCollider, &this->actor, &sEnemyCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->interactCollider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->actor.home.pos.x -= 9.0f * Math_SinS(this->actor.shape.rot.y); + this->actor.home.pos.z -= 9.0f * Math_CosS(this->actor.shape.rot.y); + this->actor.world.pos.x = this->actor.home.pos.x; + this->actor.world.pos.z = this->actor.home.pos.z; + func_808AFF9C(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0358.s") +void EnAm_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAm* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B03C0.s") + Collider_DestroyCylinder(globalCtx, &this->enemyCollider); + Collider_DestroyCylinder(globalCtx, &this->interactCollider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0460.s") +void EnAm_SpawnEffects(EnAm* this, GlobalContext* globalCtx) { + s32 i; + Vec3f effectPos; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B04A8.s") + // Dust Clouds that spawn from the hop + for (i = 4; i > 0; i--) { + effectPos.x = randPlusMinusPoint5Scaled(65.0f) + this->actor.world.pos.x; + effectPos.y = randPlusMinusPoint5Scaled(10.0f) + (this->actor.world.pos.y + 40.0f); + effectPos.z = randPlusMinusPoint5Scaled(65.0f) + this->actor.world.pos.z; + EffectSsKirakira_SpawnSmall(globalCtx, &effectPos, &sVelocity, &sAccel, &D_808B1118, &D_808B111C); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AMOS_WALK); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 4.0f, 3, 8.0f, 300, 15, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B04E4.s") +void func_808AFF9C(EnAm* this) { + f32 lastFrame = Animation_GetLastFrame(&gArmosPushedBackAnim); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0508.s") + Animation_Change(&this->skelAnime, &gArmosPushedBackAnim, 0.0f, lastFrame, lastFrame, 0, 0.0f); + this->enemyCollider.info.bumper.dmgFlags = 0x80000088; + this->interactCollider.info.bumper.dmgFlags = 0x77CFFF77; + if (this->actor.colChkInfo.health != 0) { + this->enemyCollider.base.atFlags &= ~AT_ON; + } + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actionFunc = EnAm_RemoveEnemyTexture; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B057C.s") +void EnAm_RemoveEnemyTexture(EnAm* this, GlobalContext* globalCtx) { + if (((this->enemyCollider.base.ocFlags1 & OC1_HIT) && (this->enemyCollider.base.ocFlags2 & OC2_HIT_PLAYER)) || + (this->interactCollider.base.acFlags & AC_HIT)) { + if (this->textureBlend == 0) { + EnAm_WakeUp(this); + } + } else if (this->textureBlend > 10) { + this->textureBlend -= 10; + } else { + this->textureBlend = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unkFlag = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B05C8.s") +void EnAm_WakeUp(EnAm* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AMOS_WAVE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AMOS_VOICE); + this->returnHomeTimer = 300; + this->actionFunc = EnAm_ApplyEnemyTexture; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0640.s") +void EnAm_ApplyEnemyTexture(EnAm* this, GlobalContext* globalCtx) { + s32 tempTextureBlend; + f32 cos; + u8 pad; + f32 rand; + f32 sin; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B066C.s") + if (this->textureBlend + 20 >= 255) { + this->textureBlend = 255; + this->actor.flags |= ACTOR_FLAG_1; + this->enemyCollider.info.bumper.dmgFlags = 0x81C2C788; + this->interactCollider.info.bumper.dmgFlags = 0x760D3877; + this->enemyCollider.base.atFlags |= AT_ON; + this->actor.shape.yOffset = 0.0f; + func_808B0358(this); + } else { + tempTextureBlend = this->textureBlend + 20; + rand = randPlusMinusPoint5Scaled(10.0f); + cos = Math_CosS(this->actor.shape.rot.y) * rand; + sin = Math_SinS(this->actor.shape.rot.y) * rand; + this->actor.world.pos.x = this->actor.home.pos.x + cos; + this->actor.world.pos.z = this->actor.home.pos.z + sin; + this->textureBlend = tempTextureBlend; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B06D0.s") +void func_808B0208(EnAm* this, GlobalContext* globalCtx) { + // If the armos is against a wall, rotate and turn away from it + if ((this->actor.speedXZ > 0.0f) && (this->actor.bgCheckFlags & 8)) { + this->actor.world.rot.y = (this->actor.wallYaw * 2) - this->actor.world.rot.y; + this->actor.world.pos.x += this->actor.speedXZ * Math_SinS(this->actor.world.rot.y); + this->actor.world.pos.z += this->actor.speedXZ * Math_CosS(this->actor.world.rot.y); + } + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 8.0f) != 0) { + this->actor.speedXZ = this->speed; + this->actor.velocity.y = 12.0f; + } else if (this->skelAnime.curFrame > 11.0f) { + if (!(this->actor.bgCheckFlags & 1)) { + this->skelAnime.curFrame = 11.0f; + } else { + Math_ScaledStepToS(&this->actor.world.rot.y, this->armosYaw, 0x1F40); + this->actor.speedXZ = 0.0f; + if (this->actor.bgCheckFlags & 2) { + EnAm_SpawnEffects(this, globalCtx); + } + } + } + if (this->actionFunc != func_808B0894) { + this->actor.shape.rot.y = this->actor.world.rot.y; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B07A8.s") +void func_808B0358(EnAm* this) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gArmosHopAnim, 4.0f); + this->explodeTimer = 3; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->speed = 6.0f; + this->actionFunc = func_808B03C0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0820.s") +void func_808B03C0(EnAm* this, GlobalContext* globalCtx) { + this->armosYaw = this->actor.yawTowardsPlayer; + func_808B0208(this, globalCtx); + if (this->actor.bgCheckFlags & 2) { + this->explodeTimer--; + } + if (this->explodeTimer == 0) { + func_808B0640(this); + } else if ((this->returnHomeTimer == 0) || Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 240.0f) { + func_808B0460(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0894.s") +void func_808B0460(EnAm* this) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->speed = 0.0f; + this->armosYaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + this->actionFunc = func_808B04A8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0AD0.s") +void func_808B04A8(EnAm* this, GlobalContext* globalCtx) { + func_808B0208(this, globalCtx); + if (this->armosYaw == this->actor.world.rot.y) { + func_808B057C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0B4C.s") +void func_808B04E4(EnAm* this) { + this->speed = 0.0f; + this->armosYaw = this->actor.home.rot.y; + this->actionFunc = func_808B0508; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0B9C.s") +void func_808B0508(EnAm* this, GlobalContext* globalCtx) { + func_808B0208(this, globalCtx); + if (!(this->actor.bgCheckFlags & 1)) { + Math_StepToF(&this->actor.world.pos.x, this->actor.home.pos.x, 2.0f); + Math_StepToF(&this->actor.world.pos.z, this->actor.home.pos.z, 2.0f); + } + if (this->actor.home.rot.y == this->actor.world.rot.y) { + func_808AFF9C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/EnAm_Update.s") +void func_808B057C(EnAm* this) { + this->speed = 6.0f; + this->armosYaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + this->explodeTimer = 1; + this->actionFunc = func_808B05C8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/func_808B0EA4.s") +void func_808B05C8(EnAm* this, GlobalContext* globalCtx) { + this->armosYaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + func_808B0208(this, globalCtx); + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 8.0f) { + func_808B04E4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Am/EnAm_Draw.s") +void func_808B0640(EnAm* this) { + this->explodeTimer = 40; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->speed = 0.0f; + this->actionFunc = func_808B066C; +} + +void func_808B066C(EnAm* this, GlobalContext* globalCtx) { + if (this->explodeTimer != 0) { + this->explodeTimer--; + } else { + this->armosYaw = this->actor.yawTowardsPlayer; + func_808B0208(this, globalCtx); + if (this->armosYaw == this->actor.shape.rot.y) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AMOS_VOICE); + func_808B0358(this); + } + } +} + +void EnAm_TakeDamage(EnAm* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gArmosTakeDamageAnim, 1.0f, 4.0f, + Animation_GetLastFrame(&gArmosTakeDamageAnim) - 6, 2, 0.0f); + func_800BE504(&this->actor, &this->enemyCollider); + this->actor.speedXZ = 6.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, Animation_GetLastFrame(&gArmosTakeDamageAnim) - 10); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_DAMAGE); + this->enemyCollider.base.acFlags &= ~AC_ON; + this->textureBlend = 255; + this->actionFunc = func_808B07A8; +} + +void func_808B07A8(EnAm* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actor.colChkInfo.health == 0) { + func_808B0820(this); + } else { + this->enemyCollider.base.acFlags |= AC_ON; + func_808B0358(this); + } + } +} + +void func_808B0820(EnAm* this) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gArmosHopAnim, 4.0f); + this->explodeTimer = 64; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.speedXZ = 0.0f; + this->speed = 6.0f; + this->actionFunc = func_808B0894; +} + +void func_808B0894(EnAm* this, GlobalContext* globalCtx) { + s32 i; + Vec3f dustPos; + s32 pad; + + this->explodeTimer--; + this->armosYaw = this->actor.yawTowardsPlayer; + func_808B0208(this, globalCtx); + if (this->explodeTimer == 1) { + 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, 2, 0); + if (bomb != NULL) { + bomb->timer = 0; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_DEAD); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xB0); + + for (i = 0; i < 8; i++) { + dustPos.x = (Math_SinS(0) * 7.0f) + this->actor.world.pos.x; + dustPos.y = (randPlusMinusPoint5Scaled(10.0f) * 6.0f) + (this->actor.world.pos.y + 40.0f); + dustPos.z = (Math_CosS(0) * 7.0f) + this->actor.world.pos.z; + + func_800B0EB0(globalCtx, &dustPos, &gZeroVec3f, &gZeroVec3f, &D_808B1120, &D_808B1124, 200, 45, 12); + } + } else if (this->explodeTimer == 0) { + Actor_MarkForDeath(&this->actor); + return; + } else if (!(this->explodeTimer & 3)) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 4); + } + if (this->actor.world.rot.z < 0x1F40) { + this->actor.world.rot.z += 0x320; + } + this->actor.shape.rot.y += this->actor.world.rot.z; +} + +void func_808B0AD0(EnAm* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gArmosPushedBackAnim, 1.0f, 0.0f, 8.0f, 2, 0.0f); + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.speedXZ = -6.0f; + this->actionFunc = func_808B0B4C; +} + +void func_808B0B4C(EnAm* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + if (SkelAnime_Update(&this->skelAnime)) { + func_808B0358(this); + } +} + +s32 EnAm_UpdateDamage(EnAm* this, GlobalContext* globalCtx) { + if (this->enemyCollider.base.acFlags & AC_HIT) { + this->enemyCollider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->enemyCollider.info); + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + if (this->actor.colChkInfo.damageEffect == 0xD) { + return true; + } + if (this->actor.colChkInfo.health != 0) { + this->enemyCollider.base.atFlags &= ~AT_ON; + } + this->enemyCollider.base.atFlags &= ~AT_HIT; + if (this->actor.colChkInfo.damageEffect == 0x4) { + this->drawDmgEffScale = 0.7f; + this->drawDmgEffAlpha = 4.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->enemyCollider.info.bumper.hitPos.x, + this->enemyCollider.info.bumper.hitPos.y, this->enemyCollider.info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_LARGE_LIGHT_RAYS); + } + EnAm_TakeDamage(this, globalCtx); + return true; + } + return false; +} + +void EnAm_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAm* this = THIS; + s32 pad; + + if (EnAm_UpdateDamage(this, globalCtx) == false) { + if (this->enemyCollider.base.atFlags & AT_BOUNCED) { + this->enemyCollider.base.atFlags &= ~(AT_BOUNCED | AT_HIT); + if (this->actor.colChkInfo.health == 0) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000; + } else { + func_808B0AD0(this, globalCtx); + } + } + } + if (this->returnHomeTimer != 0) { + this->returnHomeTimer--; + } + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 30.0f, 100.0f, 0x1D); + Actor_SetFocus(&this->actor, 64.0f); + Collider_UpdateCylinder(&this->actor, &this->enemyCollider); + Collider_UpdateCylinder(&this->actor, &this->interactCollider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->enemyCollider.base); + if (this->enemyCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->enemyCollider.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->interactCollider.base); + if (this->enemyCollider.base.atFlags & AC_ON) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->enemyCollider.base); + } + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.35f; + this->drawDmgEffScale = (this->drawDmgEffScale > 0.7f) ? 0.7f : this->drawDmgEffScale; +} + +void EnAm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 i; + s32 phi_s3; + Vec3f* phi_s1; + Vec3f* phi_s2; + EnAm* this = THIS; + + phi_s2 = 0; + phi_s1 = 0; + if (limbIndex == 4) { + phi_s2 = &this->limbPos[0]; + phi_s1 = D_808B1128; + phi_s3 = 5; + } else if (limbIndex == 13) { + phi_s2 = &this->limbPos[9]; + phi_s1 = D_808B117C; + phi_s3 = 4; + } else if ((limbIndex == 7) || (limbIndex == 10)) { + phi_s2 = (limbIndex == 7) ? &this->limbPos[5] : &this->limbPos[7]; + phi_s1 = D_808B1164; + phi_s3 = 2; + } else { + phi_s3 = 0; + } + for (i = 0; i < phi_s3; i++, phi_s2++, phi_s1++) { + Matrix_MultVec3f(phi_s1, phi_s2); + } +} + +void EnAm_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx* gfx; + EnAm* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_OPA_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + gDPSetEnvColor(&gfx[1], 0, 0, 0, this->textureBlend); + POLY_OPA_DISP = &gfx[2]; + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, EnAm_PostLimbDraw, + &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + 0.0f, this->drawDmgEffAlpha, ACTOR_DRAW_DMGEFF_LIGHT_ORBS); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Am/z_en_am.h b/src/overlays/actors/ovl_En_Am/z_en_am.h index 59d8abbad..2199a832f 100644 --- a/src/overlays/actors/ovl_En_Am/z_en_am.h +++ b/src/overlays/actors/ovl_En_Am/z_en_am.h @@ -2,6 +2,7 @@ #define Z_EN_AM_H #include "global.h" +#include "objects/object_am/object_am.h" struct EnAm; @@ -9,9 +10,21 @@ typedef void (*EnAmActionFunc)(struct EnAm*, GlobalContext*); typedef struct EnAm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xEC]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[OBJECT_AM_LIMB_MAX]; + /* 0x01DC */ Vec3s morphTable[OBJECT_AM_LIMB_MAX]; /* 0x0230 */ EnAmActionFunc actionFunc; - /* 0x0234 */ char unk_234[0x14C]; + /* 0x0234 */ u8 textureBlend; // 0 = statue textures; 255 = enemy textures + /* 0x0236 */ s16 explodeTimer; // timer counting down till armos explodes + /* 0x0238 */ s16 returnHomeTimer; // Timer that counts down till an armos will return to its spawn position + /* 0x023A */ s16 unkFlag; + /* 0x023C */ s16 armosYaw; // Yaw of Armos + /* 0x0240 */ f32 speed; // Hopping speed of Armos + /* 0x0244 */ f32 drawDmgEffAlpha; + /* 0x0248 */ f32 drawDmgEffScale; + /* 0x024C */ Vec3f limbPos[13]; + /* 0x02E8 */ ColliderCylinder enemyCollider; // Collider for when Armos is Hostile + /* 0x0334 */ ColliderCylinder interactCollider; // Collider for when an interactable Armos is docile } EnAm; // size = 0x380 extern const ActorInit En_Am_InitVars; 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 285d33447..9144d34fa 100644 --- a/src/overlays/actors/ovl_En_An/z_en_an.c +++ b/src/overlays/actors/ovl_En_An/z_en_an.c @@ -1,6 +1,12 @@ +/* + * File: z_en_an.c + * Overlay: ovl_En_An + * Description: Anju + */ + #include "z_en_an.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnAn*)thisx) 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 96de4702b..437bd1750 100644 --- a/src/overlays/actors/ovl_En_And/z_en_and.c +++ b/src/overlays/actors/ovl_En_And/z_en_and.c @@ -1,6 +1,12 @@ +/* + * File: z_en_and.c + * Overlay: ovl_En_And + * Description: Anju in Wedding Dress + */ + #include "z_en_and.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnAnd*)thisx) 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 9f8d2e22b..098d91be4 100644 --- a/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -1,15 +1,44 @@ +/* + * File: z_en_ani.c + * Overlay: ovl_En_Ani + * Description: Man in Tree in South Termina Field + * version in shop at night is EnOssan actor using object_ani + */ + #include "z_en_ani.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnAni*)thisx) +// clang-format off +#define ANI_STATE_STANDING (0) +#define ANI_STATE_UNK (1 << 0) +#define ANI_STATE_WRITHING (1 << 1) +#define ANI_STATE_CLIMBING (1 << 2) +#define ANI_STATE_FALLING (1 << 3) +// clang-format on + void EnAni_Init(Actor* thisx, GlobalContext* globalCtx); void EnAni_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnAni_Update(Actor* thisx, GlobalContext* globalCtx); void EnAni_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnAni_DefaultBlink(EnAni* this); +void EnAni_WaitForEyeClose(EnAni* this); +void EnAni_WaitForEyeOpen(EnAni* this); + +void EnAni_SetText(EnAni* this, GlobalContext* globalCtx, u16 textId); + +void EnAni_HangInTree(EnAni* this, GlobalContext* globalCtx); +void EnAni_LoseBalance(EnAni* this, GlobalContext* globalCtx); +void EnAni_FallToGround(EnAni* this, GlobalContext* globalCtx); +void EnAni_LandOnFoot(EnAni* this, GlobalContext* globalCtx); +void EnAni_FallOverInPain(EnAni* this, GlobalContext* globalCtx); +void EnAni_IdleInPain(EnAni* this, GlobalContext* globalCtx); +void EnAni_Talk(EnAni* this, GlobalContext* globalCtx); +void EnAni_IdleStanding(EnAni* this, GlobalContext* globalCtx); + const ActorInit En_Ani_InitVars = { ACTOR_EN_ANI, ACTORCAT_NPC, @@ -22,62 +51,304 @@ const ActorInit En_Ani_InitVars = { (ActorFunc)EnAni_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80968670 = { - { 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, }, +// two different colliders, but only one init for both +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 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8096869C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 850, ICHAIN_STOP), }; -#endif +void EnAni_DefaultBlink(EnAni* this) { + if (DECR(this->blinkTimer) == 0) { + this->blinkTimer = Rand_S16Offset(60, 60); + } -extern ColliderCylinderInit D_80968670; -extern InitChainEntry D_8096869C[]; + this->eyeState = this->blinkTimer; + if (this->eyeState >= 3) { + this->eyeState = 0; + } +} -extern UNK_TYPE D_06000C14; -extern UNK_TYPE D_060011CC; -extern UNK_TYPE D_060027A0; -extern UNK_TYPE D_06009220; -extern UNK_TYPE D_06009D34; +void EnAni_WaitForEyeClose(EnAni* this) { + if (this->blinkTimer > 0) { + this->blinkTimer--; + } else if (this->eyeState < 2) { + this->eyeState++; + } else { + this->blinkFunc = EnAni_WaitForEyeOpen; + this->blinkTimer = Rand_S16Offset(20, 20); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_809679D0.s") +void EnAni_WaitForEyeOpen(EnAni* this) { + if (this->blinkTimer > 0) { + this->blinkTimer--; + } else if (this->eyeState > 0) { + this->eyeState--; + } else { + this->blinkFunc = EnAni_WaitForEyeClose; + this->blinkTimer = Rand_S16Offset(10, 10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967A48.s") +void EnAni_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnAni* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967AB4.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gAniSkeleton, &gAniStandingNormalAnim, this->jointTable, + this->morphTable, ANI_LIMB_MAX); + Animation_PlayOnce(&this->skelAnime, &gAniStandingNormalAnim); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider2); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->stateFlags = ANI_STATE_STANDING; + this->unk2EE = 0; + this->treeReachTimer = 0; + this->blinkFunc = EnAni_DefaultBlink; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Init.s") + if (GET_ANI_TYPE(thisx) == ANI_TYPE_TREE_HANGING) { + Animation_Change(&this->skelAnime, &gAniTreeHangingAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gAniTreeHangingAnim), ANIMMODE_ONCE, 0.0f); + this->actionFunc = EnAni_HangInTree; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = 0.0f; + this->actor.gravity = 0.0f; + this->actor.flags |= ACTOR_FLAG_10; + this->stateFlags |= ANI_STATE_CLIMBING; + gSaveContext.eventInf[1] &= (u8)~0x10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Destroy.s") + } else { // ANI_TYPE_STANDING + // ( unused code ) + // for some reason standing he has a large collider + // possibly he was meant to be a blocking npc like bomber + this->collider2.dim.radius = 60; + this->actionFunc = EnAni_IdleStanding; + this->actor.velocity.y = -25.0f; + this->actor.terminalVelocity = -25.0f; + this->actor.gravity = -5.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967D20.s") +void EnAni_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAni* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967DA0.s") + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967DCC.s") +void EnAni_SetText(EnAni* this, GlobalContext* globalCtx, u16 textId) { + s16 diffAngle = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967E34.s") + this->actor.textId = textId; + if ((this->stateFlags & ANI_STATE_WRITHING) || ABS_ALT(diffAngle) <= 0x4300) { + if (this->actor.xzDistToPlayer < 100.0f) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967E90.s") +void EnAni_IdleStanding(EnAni* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967F20.s") +void EnAni_Talk(EnAni* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Message_GetState(&globalCtx->msgCtx) == 2 && globalCtx->msgCtx.currentTextId == 0x6DE) { + this->actionFunc = EnAni_IdleInPain; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80967FA4.s") +void EnAni_IdleInPain(EnAni* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = EnAni_Talk; + } else { + // telling you not to take his rupees you knocked from the tree + EnAni_SetText(this, globalCtx, 0x6DE); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_809680B0.s") +void EnAni_FallOverInPain(EnAni* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + this->blinkFunc = EnAni_WaitForEyeOpen; + this->actionFunc = EnAni_IdleInPain; + Animation_Change(&this->skelAnime, &gAniHoldingFootWrithingInPainAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gAniHoldingFootWrithingInPainAnim), ANIMMODE_LOOP, 0.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80968164.s") +void EnAni_LandOnFoot(EnAni* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + this->actionFunc = EnAni_FallOverInPain; + Animation_Change(&this->skelAnime, &gAniFallOverHoldingFootAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gAniFallOverHoldingFootAnim), ANIMMODE_ONCE, 0.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Update.s") +void EnAni_FallToGround(EnAni* this, GlobalContext* globalCtx) { + s32 pad; + s16 quakeValue; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_80968504.s") + if (this->actor.bgCheckFlags & 1) { // hit the ground + this->actor.flags &= ~ACTOR_FLAG_10; + this->actionFunc = EnAni_LandOnFoot; + this->actor.velocity.x = 0.0f; + this->actor.velocity.z = 0.0f; + // the animation gets cut short, (first 16 frames only) only the landing part is seen + Animation_Change(&this->skelAnime, &gAniLandingThenStandingUpAnim, 1.0f, 0.0f, 16.0f, ANIMMODE_ONCE, 0.0f); + this->stateFlags |= ANI_STATE_WRITHING; + quakeValue = Quake_Add(globalCtx->cameraPtrs[0], 3); + Quake_SetSpeed(quakeValue, 0x6978); + Quake_SetQuakeValues(quakeValue, 7, 0, 0, 0); + Quake_SetCountdown(quakeValue, 0x14); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_HAMMER_HIT); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/func_8096854C.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x2, 0x7D0, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ani/EnAni_Draw.s") +void EnAni_LoseBalance(EnAni* this, GlobalContext* globalCtx) { + s32 pad; + + if (SkelAnime_Update(&this->skelAnime)) { + this->actor.terminalVelocity = -20.0f; + this->actor.gravity = -5.0f; + this->actor.velocity.y = 0.0f; + this->actor.velocity.z = -4.0f; + // frame count : 0.0f, only first frame, rest is handled in next action func + Animation_Change(&this->skelAnime, &gAniLandingThenStandingUpAnim, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 5.0f); + this->actionFunc = EnAni_FallToGround; + gSaveContext.eventInf[1] |= 0x10; + } +} + +void EnAni_HangInTree(EnAni* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->treeReachTimer > 0) { + this->treeReachTimer--; + if (this->treeReachTimer > 0) { + Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingReachAnim); + } else { + Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingAnim); + } + } else if (Rand_ZeroFloat(1.0f) < 0.4f) { + Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingReachAnim); + this->treeReachTimer = 2; + } else { + Animation_PlayOnce(&this->skelAnime, &gAniTreeHangingAnim); + } + } + + // his bonk detection is based on his tilt, neat + if (this->actor.home.rot.x != 0) { + this->stateFlags |= ANI_STATE_FALLING; + this->actionFunc = EnAni_LoseBalance; + Animation_Change(&this->skelAnime, &gAniTreeHangLosingBalanceAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gAniTreeHangLosingBalanceAnim), ANIMMODE_ONCE, -5.0f); + } +} + +void EnAni_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAni* this = THIS; + f32 minVelocity; + + Collider_UpdateCylinder(&this->actor, &this->collider1); + Collider_UpdateCylinder(&this->actor, &this->collider2); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + if (!(this->stateFlags & ANI_STATE_UNK)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + + this->actor.velocity.y += this->actor.gravity; + minVelocity = this->actor.terminalVelocity; + if (this->actor.velocity.y < minVelocity) { + this->actor.velocity.y = minVelocity; + } + + Actor_UpdatePos(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + this->actionFunc(this, globalCtx); + if (this->actor.xzDistToPlayer < 100.0f && !(this->stateFlags & ANI_STATE_CLIMBING)) { + func_800E9250(globalCtx, &this->actor, &this->headRot, &this->chestRot, this->actor.focus.pos); + this->chestRot.x = this->chestRot.y = this->chestRot.z = 0; + } else { + Math_SmoothStepToS(&this->headRot.x, 0, 0x6, 0x1838, 0x64); + Math_SmoothStepToS(&this->headRot.y, 0, 0x6, 0x1838, 0x64); + Math_SmoothStepToS(&this->chestRot.x, 0, 0x6, 0x1838, 0x64); + Math_SmoothStepToS(&this->chestRot.y, 0, 0x6, 0x1838, 0x64); + } + + this->blinkFunc(this); + if (this->stateFlags & ANI_STATE_FALLING) { + if (this->actor.cutscene == -1) { + this->stateFlags &= ~ANI_STATE_FALLING; + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actor.cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + Camera_SetToTrackActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->actor.cutscene)), + &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +s32 EnAni_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnAni* this = THIS; + + if (limbIndex == ANI_LIMB_HEAD) { + rot->x += this->headRot.y; + rot->z += this->headRot.x; + } + + return false; +} + +void EnAni_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_809686A4 = { 800.0f, 500.0f, 0.0f }; + + if (limbIndex == ANI_LIMB_HEAD) { + Matrix_MultVec3f(&D_809686A4, &thisx->focus.pos); + } +} + +void EnAni_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sEyeTextures[] = { gAniOpenEyeTex, gAniClosingEyeTex, gAniClosedEyeTex }; + s32 pad; + EnAni* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(0.0f, 0.0f, -1000.0f, MTXMODE_APPLY); + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeState])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnAni_OverrideLimbDraw, EnAni_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Ani/z_en_ani.h b/src/overlays/actors/ovl_En_Ani/z_en_ani.h index 554c1bc8a..21dced2c1 100644 --- a/src/overlays/actors/ovl_En_Ani/z_en_ani.h +++ b/src/overlays/actors/ovl_En_Ani/z_en_ani.h @@ -2,18 +2,37 @@ #define Z_EN_ANI_H #include "global.h" +#include "objects/object_ani/object_ani.h" struct EnAni; typedef void (*EnAniActionFunc)(struct EnAni*, GlobalContext*); +typedef void (*EnAniBlinkFunc)(struct EnAni*); + typedef struct EnAni { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1B0]; - /* 0x02F4 */ EnAniActionFunc actionFunc; - /* 0x02F8 */ char unk_2F8[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider1; + /* 0x190 */ ColliderCylinder collider2; + /* 0x1DC */ SkelAnime skelAnime; + /* 0x220 */ Vec3s jointTable[ANI_LIMB_MAX]; + /* 0x280 */ Vec3s morphTable[ANI_LIMB_MAX]; + /* 0x2E0 */ Vec3s headRot; + /* 0x2E6 */ Vec3s chestRot; // unused + /* 0x2EC */ u16 stateFlags; + /* 0x2EE */ s16 unk2EE; // assigned to zero in init, never used after + /* 0x2F0 */ s16 treeReachTimer; + /* 0x2F4 */ EnAniBlinkFunc blinkFunc; + /* 0x2F8 */ s16 eyeState; + /* 0x2FA */ s16 blinkTimer; + /* 0x2FC */ EnAniActionFunc actionFunc; } EnAni; // size = 0x300 -extern const ActorInit En_Ani_InitVars; +enum EnAniType { + /* else */ ANI_TYPE_STANDING, // unfinshed and unused + /* 1 */ ANI_TYPE_TREE_HANGING = 1, +}; + +#define GET_ANI_TYPE(thisx) (thisx->params & 0xFF) #endif // 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 54af774ac..1d74c45ae 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,6 +1,14 @@ -#include "z_en_aob_01.h" +/* + * File: z_en_aob_01.c + * Overlay: ovl_En_Aob_01 + * Description: Mamamu Yan + */ -#define FLAGS 0x00000019 +#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" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnAob01*)thisx) @@ -22,8 +30,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, @@ -36,92 +44,1018 @@ 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 AnimationInfo D_809C3790[6] = { + { &gMamamuYanIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gMamamuYanLaughStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &gMamamuYanLaughLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gMamamuYanSurpriseStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &gMamamuYanSurpriseLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gMamamuYanIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -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->blinkTimer) == 0) { + this->eyeIndex++; + if (this->eyeIndex >= arg1) { + this->eyeIndex = 0; + this->blinkTimer = Rand_S16Offset(30, 30); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C10B0.s") +void func_809C1124(void) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)REG(15); + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.daySpeed); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1124.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_809C1158.s") + if (temp_s0 != 0x3F) { + do { + this->unk_1D8[i] = SubS_GetPathByIndex(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_809C11EC.s") +void func_809C11EC(EnAob01* this, GlobalContext* globalCtx) { + s32 unk; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1304.s") + func_809C1158(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1424.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_809C14D0.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_809C15BC.s") +void func_809C1304(EnAob01* this, GlobalContext* globalCtx) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C165C.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_809C16DC.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_809C1C9C.s") + if (this->unk_43C == 1) { + if (curFrame == lastFrame) { + this->unk_43C = 2; + Actor_ChangeAnimationByInfo(&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_809C1D64.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_809C1EC8.s") + if ((this->unk_43C == 0) || (this->unk_43C == 5)) { + if (curFrame == lastFrame) { + this->unk_43C = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 3); + return true; + } + } else if (this->unk_43C == 3) { + if (curFrame == lastFrame) { + this->unk_43C = 4; + Actor_ChangeAnimationByInfo(&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_809C2060.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_809C21E0.s") + if ((this->unk_43C != 0) && (this->unk_43C != 5)) { + if (curFrame == lastFrame) { + this->unk_43C = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 5); + return true; + } + } else { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2504.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2594.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_809C25E4.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_809C2680.s") + switch (this->unk_210) { + case 0: + case 0x3524: + case 0x3535: + case 0x3548: + case 0x3549: + case 0x354A: + switch (gSaveContext.save.day) { + case 1: + if (!gSaveContext.save.isNight) { + if (!(gSaveContext.save.weekEventReg[64] & 0x80)) { + gSaveContext.save.weekEventReg[64] |= 0x80; + this->unk_210 = 0x3520; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.save.weekEventReg[65] & 1)) { + gSaveContext.save.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_809C26E4.s") + case 2: + if (!gSaveContext.save.isNight) { + if (!(gSaveContext.save.weekEventReg[65] & 2)) { + gSaveContext.save.weekEventReg[65] |= 2; + this->unk_210 = 0x3531; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.save.weekEventReg[65] & 4)) { + gSaveContext.save.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_809C2730.s") + case 3: + if (!gSaveContext.save.isNight) { + if (!(gSaveContext.save.weekEventReg[65] & 8)) { + gSaveContext.save.weekEventReg[65] |= 8; + this->unk_210 = 0x3533; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.save.weekEventReg[65] & 0x10)) { + gSaveContext.save.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_809C2788.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_809C2824.s") + case 0x3521: + if (this->unk_2D2 & 2) { + this->unk_2D2 &= ~2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C28B8.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_809C2A64.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_809C2BE4.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_809C2C9C.s") + case PLAYER_FORM_HUMAN: + if (gSaveContext.save.playerData.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_809C2D0C.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_809C2EC4.s") + this->unk_210 = 0x3523; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2F34.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/func_809C2FA0.s") + this->unk_210 = 0x3523; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Init.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_Destroy.s") + this->unk_210 = 0x3526; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 4; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Update.s") + case 0x3527: + this->unk_210 = 0x3528; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C33D8.s") + case 0x3528: + if (gSaveContext.save.playerData.rupees < this->unk_434) { + this->unk_210 = 0x3536; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C35B4.s") + if (this->unk_434 == 0) { + this->unk_210 = 0x3537; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C35F4.s") + gSaveContext.unk_3F5C = this->unk_434; + globalCtx->msgCtx.bankRupees = this->unk_434; + this->unk_210 = 0x3529; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Draw.s") + case 0x3529: + if (this->unk_2D2 & 2) { + this->unk_2D2 &= ~2; + func_801159EC(-this->unk_434); + func_800B7298(globalCtx, NULL, 7); + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_809C1C9C; + return; + } + this->unk_210 = 0x3528; + break; + + case 0x3536: + case 0x3537: + this->unk_210 = 0x3528; + break; + } + + Message_StartTextbox(globalCtx, this->unk_210, &this->actor); +} + +void func_809C1C9C(EnAob01* this, GlobalContext* globalCtx) { + if (gSaveContext.rupeeAccumulator == 0) { + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.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 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 4) { + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.save.playerData.rupees < 10) { + play_sound(NA_SE_SY_ERROR); + this->unk_210 = 0x3524; + Message_StartTextbox(globalCtx, this->unk_210, &this->actor); + } else { + func_8019F208(); + this->unk_2D2 |= 4; + this->unk_2D2 |= 0x10; + this->unk_210 = 0x3522; + Message_StartTextbox(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C21E0; + } + break; + + case 1: + func_8019F230(); + this->unk_210 = 0x3535; + Message_StartTextbox(globalCtx, this->unk_210, &this->actor); + break; + } + } + } else if ((temp_v0 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_210 = 0; + this->actionFunc = func_809C2060; + } +} + +void func_809C1EC8(EnAob01* this, GlobalContext* globalCtx) { + static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + }; + Player* player = GET_PLAYER(globalCtx); + Vec3f point; + + SkelAnime_Update(&this->skelAnime); + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x36B0, this->actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->actor.focus.pos, &this->actor.shape.rot, &this->turnTarget, &this->headRot, + &this->torsoRot, &sTurnOptions); + } else { + Math_SmoothStepToS(&this->turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1); + } + func_809C10B0(this, 3); + SubS_FillLimbRotTables(globalCtx, this->unk_2F8, this->unk_318, ARRAY_COUNT(this->unk_2F8)); + 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 |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 100.0f); + this->unk_2D2 |= 8; + this->actionFunc = func_809C21E0; + } + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (this->unk_2D2 & 0x100)) { + this->unk_2D2 &= ~0x100; + this->unk_2E6 = this->turnTarget; + this->unk_2EC = this->headRot; + this->unk_2F2 = this->torsoRot; + 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 = Message_GetState(&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 &= ~ACTOR_FLAG_10000; + 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + 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; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + Message_StartTextbox(globalCtx, 0x354B, &this->actor); + } + this->unk_2D2 &= ~8; + } + } else if (sp2F == 4) { + if (Message_ShouldAdvance(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 (Message_ShouldAdvance(globalCtx)) { + this->unk_2D2 &= ~0x40; + if (this->unk_2D2 & 0x10) { + this->unk_2D2 &= ~0x10; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_809C2060; + } else { + func_809C16DC(this, globalCtx); + } + } + } else if ((sp2F == 14) && Message_ShouldAdvance(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.actorLists[ACTORCAT_NPC].first; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (func_800F2178(this->unk_430) == ((EnRacedog*)npc)->currentPoint)) { + 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.actorLists[ACTORCAT_NPC].first; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->index == ((EnRacedog*)npc)->selectedDogIndex)) { + this->unk_3F4 = npc; + return true; + } + npc = npc->next; + } + + return false; +} + +s32 func_809C25E4(EnAob01* this, GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; + s16 count = 0; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->raceStatus == RACEDOG_RACE_STATUS_FINISHED)) { + 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)) { + 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + 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; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_809C3790, 1); + break; + } + + Message_StartTextbox(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 = Message_GetState(&globalCtx->msgCtx); + + if (func_809C15BC(this)) { + if ((sp2F == 5) && Message_ShouldAdvance(globalCtx)) { + this->unk_434 = 0; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->turnTarget = this->unk_2E6; + this->headRot = this->unk_2EC; + this->torsoRot = this->unk_2F2; + this->actor.parent = NULL; + this->actor.shape.rot.y = this->actor.world.rot.y; + if (gSaveContext.save.weekEventReg[8] & 0x20) { + this->actionFunc = func_809C2BE4; + } else { + gSaveContext.save.weekEventReg[8] |= 0x20; + this->actionFunc = func_809C2BE4; + } + } else if (gSaveContext.save.weekEventReg[8] & 0x20) { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 300.0f, 300.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 300.0f, 300.0f); + } + } +} + +void func_809C2BE4(EnAob01* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (((temp_v0 == 5) || (temp_v0 == 6)) && Message_ShouldAdvance(globalCtx)) { + if (gSaveContext.save.weekEventReg[63] & 2) { + gSaveContext.save.weekEventReg[63] &= (u8)~2; + } + + if (gSaveContext.save.weekEventReg[63] & 1) { + gSaveContext.save.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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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 = Message_GetState(&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) && Message_ShouldAdvance(globalCtx)) { + this->unk_2D2 &= ~0x40; + this->unk_2D2 &= ~0x80; + if (this->unk_434 >= 150) { + this->unk_210 = 0x352E; + Message_StartTextbox(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C2A64; + } else { + this->turnTarget = this->unk_2E6; + this->headRot = this->unk_2EC; + this->torsoRot = this->unk_2F2; + + this->unk_434 = 0; + this->actor.shape.rot.y = this->actor.world.rot.y; + if (gSaveContext.save.weekEventReg[63] & 2) { + gSaveContext.save.weekEventReg[63] &= (u8)~2; + } + + if (gSaveContext.save.weekEventReg[63] & 1) { + gSaveContext.save.weekEventReg[63] &= (u8)~1; + } + + this->unk_210 = 0x354C; + Message_StartTextbox(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.actorLists[ACTORCAT_ENEMY].first; + + while (dog != NULL) { + if (dog->id == ACTOR_EN_DG) { + this->unk_432 = ((EnDg*)dog)->selectedDogIndex; + if (this->unk_432 == -1) { + return false; + } + + if (this->unk_432 == ENDG_GET_INDEX(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 rand; + u8 index; + 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++) { + rand = Rand_ZeroFloat(14.0f); + orig = sp34[i]; + + sp34[i] = sp34[rand]; + sp34[rand] = orig; + } + + for (i = 0; i < ARRAY_COUNT(sp44); i++) { + gSaveContext.save.weekEventReg[42 + i] = 0; + sp44[i] = 0; + } + + for (i = 0; i < ARRAY_COUNT(sp34); i++) { + orig2 = sp34[i]; + index = i / 2; + + if (i % 2) { + sp44[index] |= orig2 << 0x4; + gSaveContext.save.weekEventReg[42 + index] = + ((void)0, gSaveContext.save.weekEventReg[42 + index]) | sp44[index]; + } else { + sp44[index] |= 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, &gMamamuYanSkel, NULL, this->jointTable, this->morphTable, + MAMAMU_YAN_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_43C = 0; + Actor_ChangeAnimationByInfo(&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 |= ACTOR_FLAG_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 &= ~ACTOR_FLAG_1; + func_809C2F34(this, globalCtx); + this->actionFunc = func_809C2824; + break; + + case 3: + func_809C2FA0(); + func_809C11EC(this, globalCtx); + this->actor.flags |= ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10000; + this->actionFunc = func_809C28B8; + break; + } +} + +void EnAob01_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAob01* this = THIS; + + if (!(this->unk_2D2 & 0x20)) { + gSaveContext.save.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; + TexturePtr eyeTextures[] = { + gMamamuYanEyeOpenTex, + gMamamuYanEyeHalfTex, + gMamamuYanEyeClosedTex, + }; + + if (limbIndex == MAMAMU_YAN_LIMB_HEAD) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + *dList = gMamamuYanHeadDL; + + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(eyeTextures[this->eyeIndex])); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == MAMAMU_YAN_LIMB_HEAD) { + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->headRot.x * -1, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == MAMAMU_YAN_LIMB_TORSO) { + Matrix_RotateXS(this->torsoRot.y * -1, MTXMODE_APPLY); + Matrix_RotateZS(this->torsoRot.x * -1, MTXMODE_APPLY); + } + + if ((limbIndex == MAMAMU_YAN_LIMB_TORSO) || (limbIndex == MAMAMU_YAN_LIMB_LEFT_UPPER_ARM) || + (limbIndex == MAMAMU_YAN_LIMB_RIGHT_UPPER_ARM)) { + 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 == MAMAMU_YAN_LIMB_HEAD) { + Matrix_MultVec3f(&D_809C3968, &this->actor.focus.pos); + } +} + +void EnAob01_TransformLimbDraw(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++); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnAob01_OverrideLimbDraw, EnAob01_PostLimbDraw, + EnAob01_TransformLimbDraw, &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..d4ed3e71e 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 @@ -2,15 +2,44 @@ #define Z_EN_AOB_01_H #include "global.h" +#include "objects/object_aob/object_aob.h" 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[MAMAMU_YAN_LIMB_MAX]; + /* 0x272 */ Vec3s morphTable[MAMAMU_YAN_LIMB_MAX]; + /* 0x2D2 */ u16 unk_2D2; + /* 0x2D4 */ Vec3s turnTarget; + /* 0x2DA */ Vec3s headRot; + /* 0x2E0 */ Vec3s torsoRot; + /* 0x2E6 */ Vec3s unk_2E6; + /* 0x2EC */ Vec3s unk_2EC; + /* 0x2F2 */ Vec3s unk_2F2; + /* 0x2F8 */ s16 unk_2F8[MAMAMU_YAN_LIMB_MAX]; + /* 0x318 */ s16 unk_318[MAMAMU_YAN_LIMB_MAX]; + /* 0x338 */ UNK_TYPE1 unk338[0xB6]; + /* 0x3EE */ s16 eyeIndex; + /* 0x3F0 */ s16 blinkTimer; + /* 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 a4bacc799..0a8eeffce 100644 --- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c +++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c @@ -1,6 +1,14 @@ -#include "z_en_arrow.h" +/* + * File: z_en_arrow.c + * Overlay: ovl_En_Arrow + * Description: Arrows and other projectiles + */ -#define FLAGS 0x00000030 +#include "z_en_arrow.h" +#include "overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnArrow*)thisx) @@ -14,7 +22,6 @@ void func_8088ACE0(EnArrow* this, GlobalContext* globalCtx); void func_8088B630(EnArrow* this, GlobalContext* globalCtx); void func_8088B6B0(EnArrow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Arrow_InitVars = { ACTOR_EN_ARROW, ACTORCAT_ITEMACTION, @@ -27,45 +34,719 @@ const ActorInit En_Arrow_InitVars = { (ActorFunc)EnArrow_Draw, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_8088C1E0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_TYPE_PLAYER, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK2, { 0x00000020, 0x00, 0x02 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_TYPE_PLAYER, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK2, + { 0x00000020, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8088C230[] = { - ICHAIN_F32(minVelocityY, -150, ICHAIN_STOP), +static InitChainEntry sInitChain[] = { + ICHAIN_F32(terminalVelocity, -150, ICHAIN_STOP), }; +void EnArrow_Init(Actor* thisx, GlobalContext* globalCtx) { + static EffectBlureInit2 D_8088C234 = { + 0, 4, 0, { 0, 255, 200, 255 }, { 0, 255, 255, 255 }, { 0, 255, 200, 0 }, { 0, 255, 255, 0 }, 16, + 0, 1, 0, { 255, 255, 170, 255 }, { 0, 150, 0, 0 }, + }; + static EffectBlureInit2 D_8088C258 = { + 0, 4, 0, { 0, 255, 200, 255 }, { 0, 255, 255, 255 }, { 0, 255, 200, 0 }, { 0, 255, 255, 0 }, 16, + 0, 1, 0, { 255, 200, 0, 255 }, { 255, 0, 0, 0 }, + }; + static EffectBlureInit2 D_8088C27C = { + 0, 4, 0, { 0, 255, 200, 255 }, { 0, 255, 255, 255 }, { 0, 255, 200, 0 }, { 0, 255, 255, 0 }, 16, + 0, 1, 0, { 170, 255, 255, 255 }, { 0, 0x64, 255, 0 }, + }; + static EffectBlureInit2 D_8088C2A0 = { + 0, 4, 0, { 0, 255, 200, 255 }, { 0, 255, 255, 255 }, { 0, 255, 200, 0 }, { 0, 255, 255, 0 }, 16, + 0, 1, 0, { 255, 255, 170, 255 }, { 255, 255, 0, 0 }, + }; + EnArrow* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + if (this->actor.params == ENARROW_MINUS8) { + this->unk_263 = 1; + this->actor.params = 8; + } + + if (this->actor.params < ENARROW_6) { + SkelAnime_Init(globalCtx, &this->arrow.skelAnime, &gameplay_keep_Skel_014560, &gameplay_keep_Anim_0128BC, + this->arrow.jointTable, this->arrow.jointTable, 5); + if (this->actor.params < ENARROW_3) { + if (this->actor.params == ENARROW_1) { + D_8088C234.elemDuration = 4; + } else { + D_8088C234.elemDuration = 16; + } + Effect_Add(globalCtx, &this->unk_240, EFFECT_BLURE2, 0, 0, &D_8088C234); + } else if (this->actor.params == ENARROW_3) { + Effect_Add(globalCtx, &this->unk_240, EFFECT_BLURE2, 0, 0, &D_8088C258); + } else if (this->actor.params == ENARROW_4) { + Effect_Add(globalCtx, &this->unk_240, EFFECT_BLURE2, 0, 0, &D_8088C27C); + } else if (this->actor.params == ENARROW_5) { + Effect_Add(globalCtx, &this->unk_240, EFFECT_BLURE2, 0, 0, &D_8088C2A0); + } + } + + Collider_InitQuad(globalCtx, &this->collider); + Collider_SetQuad(globalCtx, &this->collider, &this->actor, &sQuadInit); + + if (this->actor.params < ENARROW_6) { + this->collider.info.toucherFlags &= ~(TOUCH_SFX_WOOD | TOUCH_SFX_HARD); + this->collider.info.toucherFlags |= 0; + } + + if (this->actor.params < ENARROW_0) { + this->collider.base.atFlags = (AT_TYPE_ENEMY | AT_ON); + } else { + this->collider.info.toucher.dmgFlags = func_800BC188(this->actor.params); + if (this->actor.params == ENARROW_8) { + this->collider.info.toucher.damage = 1; + } + + if (this->actor.params == ENARROW_7) { + Actor_SetScale(&this->actor, 1.0f); + } + } + this->actionFunc = func_8088A594; +} + +void EnArrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnArrow* this = THIS; + + if (this->actor.params < ENARROW_6) { + Effect_Destroy(globalCtx, this->unk_240); + } + + Collider_DestroyQuad(globalCtx, &this->collider); + + if ((this->unk_264 != NULL) && (this->unk_264->update != NULL)) { + this->unk_264->flags &= ~0x8000; + } + + if ((this->actor.params >= ENARROW_3) && (this->actor.params < ENARROW_6) && (this->actor.child == NULL)) { + func_80115D5C(&globalCtx->state); + } +} + +void func_8088A514(EnArrow* this) { + f32 temp_f0 = 16.0f - this->bubble.unk_144; + + Actor_SetSpeeds(&this->actor, CLAMP(temp_f0, 1.0f, 80.0f)); +} + +void func_8088A594(EnArrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actor.parent != NULL) { + if (this->actor.params == ENARROW_7) { + if (Math_SmoothStepToF(&this->bubble.unk_144, 16.0f, 0.07f, 1.8f, 0.0f) > 0.5f) { + func_800B9010(&this->actor, NA_SE_PL_DEKUNUTS_BUBLE_BREATH - SFX_FLAG); + return; + } + + this->bubble.unk_148++; + if (this->bubble.unk_148 > 20) { + this->actionFunc = func_8088ACE0; + func_80115D5C(&globalCtx->state); + } + } + } else { + if ((this->actor.params != ENARROW_8) && (player->unk_D57 == 0)) { + if (this->actor.params == ENARROW_7) { + func_80115D5C(&globalCtx->state); + } + Actor_MarkForDeath(&this->actor); + return; + } + + switch (this->actor.params) { + case ENARROW_6: + func_800B8E58(player, NA_SE_IT_SLING_SHOT); + break; + + case ENARROW_0: + case ENARROW_1: + case ENARROW_2: + func_800B8E58(player, NA_SE_IT_ARROW_SHOT); + break; + + case ENARROW_3: + case ENARROW_4: + case ENARROW_5: + func_800B8E58(player, NA_SE_IT_MAGIC_ARROW_SHOT); + + case ENARROW_7: + func_800B8E58(player, NA_SE_PL_DEKUNUTS_FIRE); + break; + } + + this->actionFunc = func_8088ACE0; + Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos); + + if (this->actor.params == ENARROW_7) { + this->bubble.unk_144 = CLAMP_MIN(this->bubble.unk_144, 3.5f); + func_8088A514(this); + this->unk_260 = 99; + func_80115D5C(&globalCtx->state); + } else if (this->actor.params >= ENARROW_6) { + if ((this->actor.params == ENARROW_8) && (this->actor.world.rot.x < 0)) { + Actor_SetScale(&this->actor, 0.009f); + this->unk_260 = 40; + } else { + Actor_SetSpeeds(&this->actor, 80.0f); + this->unk_260 = 15; + } + this->actor.shape.rot.x = 0; + this->actor.shape.rot.y = 0; + this->actor.shape.rot.z = 0; + } else { + Actor_SetSpeeds(&this->actor, 150.0f); + this->unk_260 = 16; + } + } +} + +void func_8088A7D8(GlobalContext* globalCtx, EnArrow* this) { + this->actionFunc = func_8088B6B0; + Animation_PlayOnce(&this->arrow.skelAnime, &gameplay_keep_Anim_012860); + this->actor.world.rot.y += (s32)(0x6000 * (Rand_ZeroOne() - 0.5f)) + 0x8000; + this->actor.speedXZ *= 0.02f + (0.02f * Rand_ZeroOne()); + this->actor.gravity = -1.5f; + this->unk_260 = 50; + this->unk_263 = 1; +} + +void func_8088A894(EnArrow* this, GlobalContext* globalCtx) { + CollisionPoly* sp74; + Vec3f sp68; + Vec3f sp5C; + Vec3f sp50; + f32 sp4C; + f32 temp_f0; + s32 sp44; + + Math_Vec3f_Diff(&this->actor.world.pos, &this->unk_228, &sp68); + sp4C = ((this->actor.world.pos.x - this->unk_264->world.pos.x) * sp68.x) + + ((this->actor.world.pos.y - this->unk_264->world.pos.y) * sp68.y) + + ((this->actor.world.pos.z - this->unk_264->world.pos.z) * sp68.z); + if (sp4C < 0.0f) { + return; + } + + temp_f0 = Math3D_LengthSquared(&sp68); + if (temp_f0 < 1.0f) { + return; + } + + temp_f0 = sp4C / temp_f0; + Math_Vec3f_Scale(&sp68, temp_f0); + Math_Vec3f_Sum(&this->unk_264->world.pos, &sp68, &sp5C); + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->unk_264->world.pos, &sp5C, &sp50, &sp74, true, true, true, + true, &sp44)) { + this->unk_264->world.pos.x = ((sp5C.x <= sp50.x) ? 1.0f : -1.0f) + sp50.x; + this->unk_264->world.pos.y = ((sp5C.y <= sp50.y) ? 1.0f : -1.0f) + sp50.y; + this->unk_264->world.pos.z = ((sp5C.z <= sp50.z) ? 1.0f : -1.0f) + sp50.z; + } else { + Math_Vec3f_Copy(&this->unk_264->world.pos, &sp5C); + } +} + +void func_8088AA98(EnArrow* this, GlobalContext* globalCtx) { + WaterBox* sp54; + f32 sp50 = this->actor.world.pos.y; + Vec3f sp44; + f32 temp_f0; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp50, + &sp54) && + (this->actor.world.pos.y < sp50) && !(this->actor.bgCheckFlags & 0x20)) { + this->actor.bgCheckFlags |= 0x20; + + Math_Vec3f_Diff(&this->actor.world.pos, &this->actor.home.pos, &sp44); + + if (sp44.y != 0.0f) { + temp_f0 = sqrtf(SQ(sp44.x) + SQ(sp44.z)); + if (temp_f0 != 0.0f) { + temp_f0 = (((sp50 - this->actor.home.pos.y) / sp44.y) * temp_f0) / temp_f0; + } + sp44.x = this->actor.home.pos.x + (sp44.x * temp_f0); + sp44.y = sp50; + sp44.z = this->actor.home.pos.z + (sp44.z * temp_f0); + EffectSsGSplash_Spawn(globalCtx, &sp44, NULL, NULL, 0, 300); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_INTO_WATER_L); + + EffectSsGRipple_Spawn(globalCtx, &sp44, 100, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &sp44, 100, 500, 4); + EffectSsGRipple_Spawn(globalCtx, &sp44, 100, 500, 8); + + if ((this->actor.params == ENARROW_4) || (this->actor.params == ENARROW_3)) { + if ((this->actor.params == ENARROW_4) && (func_8088B6B0 != this->actionFunc)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_BG_ICEFLOE, sp44.x, sp44.y, sp44.z, 0, 0, 0, 300); + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.params = ENARROW_2; + this->collider.info.toucher.dmgFlags = 0x20; + + if (this->actor.child != NULL) { + Actor_MarkForDeath(this->actor.child); + return; + } + + func_80115D5C(&globalCtx->state); + } + } +} + +#ifdef NON_MATCHING +// Stack. Scoped variable required to fix code gen at the bottom, likely sp60/54 there, +// but sp50 must be declared below those so maybe not? +void func_8088ACE0(EnArrow* this, GlobalContext* globalCtx) { + CollisionPoly* spAC; + s32 spA8; + Vec3f sp9C; + s32 phi_a2 = 0; + EffectSsSbnInitParams sp84; + u16 sp82; + Actor* sp7C; + f32 sp78; + f32 sp74; + f32 temp_f12_2; + Vec3f sp60; + Vec3f sp54; + s32 sp50; + + if ((DECR(this->unk_260) == 0) || + ((this->actor.params == ENARROW_7) && + ((this->unk_262 != 0) || (phi_a2 = (this->collider.base.atFlags & AT_HIT) != 0)))) { + if (this->actor.params == ENARROW_7) { + if (phi_a2 && (this->collider.info.atHitInfo->elemType != ELEMTYPE_UNK4) && + (this->collider.base.atFlags & AT_BOUNCED)) { + if ((this->collider.base.at != NULL) && (this->collider.base.at->id != ACTOR_OBJ_SYOKUDAI)) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + this->actor.world.rot.y += BINANG_ROT180((s16)randPlusMinusPoint5Scaled(8000.0f)); + this->actor.velocity.y = -this->actor.velocity.y; + this->bubble.unk_149 = -1; + return; + } + } + + if ((this->unk_262 != 0) || phi_a2) { + EffectSsStone1_Spawn(globalCtx, &this->actor.world.pos, 0); + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_IT_DEKUNUTS_BUBLE_VANISH); + + if ((this->unk_262 != 0) && (this->actor.wallBgId == BG_ACTOR_MAX)) { + + Math_Vec3f_Copy(&sp84.pos, &this->actor.world.pos); + sp84.colPoly = this->actor.wallPoly; + sp84.scale = this->bubble.unk_144; + EffectSs_Spawn(globalCtx, EFFECT_SS_SBN, 128, &sp84); + } + } + Actor_MarkForDeath(&this->actor); + return; + } + + sp50 = + (this->actor.params != ENARROW_0) && (this->actor.params < ENARROW_8) && (this->collider.base.atFlags & AT_HIT); + + if (sp50 || (this->unk_262 != 0)) { + if (this->actor.params >= ENARROW_6) { + if (sp50) { + this->actor.world.pos.x = (this->actor.world.pos.x + this->actor.prevPos.x) * 0.5f; + this->actor.world.pos.y = (this->actor.world.pos.y + this->actor.prevPos.y) * 0.5f; + this->actor.world.pos.z = (this->actor.world.pos.z + this->actor.prevPos.z) * 0.5f; + } + + if (this->actor.params == ENARROW_8) { + iREG(50) = -1; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_M_FIRE1, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, this->actor.speedXZ == 0.0f); + sp82 = NA_SE_IT_DEKU; + } else { + sp82 = NA_SE_IT_SLING_REFLECT; + } + EffectSsStone1_Spawn(globalCtx, &this->actor.world.pos, 0); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, sp82); + Actor_MarkForDeath(&this->actor); + } else { + EffectSsHitMark_SpawnCustomScale(globalCtx, 0, 150, &this->actor.world.pos); + + if (sp50 && (this->collider.info.atHitInfo->elemType != ELEMTYPE_UNK4)) { + sp7C = this->collider.base.at; + + if ((sp7C->update != NULL) && !(this->collider.base.atFlags & AT_BOUNCED) && (sp7C->flags & 0x4000)) { + this->unk_264 = sp7C; + func_8088A894(this, globalCtx); + Math_Vec3f_Diff(&sp7C->world.pos, &this->actor.world.pos, &this->unk_268); + sp7C->flags |= 0x8000; + this->collider.base.atFlags &= ~AT_HIT; + this->actor.speedXZ *= 0.5f; + this->actor.velocity.y *= 0.5f; + } else { + this->unk_261 |= 1; + this->unk_261 |= 2; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + func_8088A7D8(globalCtx, this); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_HOOKSHOT_STICK_CRE); + } + } else if (this->unk_262 != 0) { + this->actionFunc = func_8088B630; + Animation_PlayOnce(&this->arrow.skelAnime, &gameplay_keep_Anim_0128BC); + if (this->actor.params >= ENARROW_0) { + this->unk_260 = 60; + } else { + this->unk_260 = 20; + } + if ((this->actor.params >= ENARROW_3) && (this->actor.params < ENARROW_6)) { + this->actor.draw = NULL; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_ARROW_STICK_OBJ); + this->unk_261 |= 1; + } + } + } else { + func_8088AA98(this, globalCtx); + if (this->actor.params == ENARROW_7) { + if (this->bubble.unk_149 == 0) { + sp78 = sqrtf(SQ(this->actor.speedXZ) + SQ(this->actor.velocity.y)); + sp74 = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; + temp_f12_2 = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; + + this->actor.prevPos.x = this->actor.world.pos.x - (sp74 * (10.0f / sp78)); + this->actor.prevPos.y = this->actor.world.pos.y - (this->actor.velocity.y * (10.0f / sp78)); + this->actor.prevPos.z = this->actor.world.pos.z - (temp_f12_2 * (10.0f / sp78)); + + this->bubble.unk_149 = 1; + } + + if (Math_StepToF(&this->bubble.unk_144, 1.0f, 0.4f)) { + this->unk_260 = 0; + } else { + this->bubble.unk_14A += (s16)(this->bubble.unk_144 * (500.0f + Rand_ZeroFloat(1400.0f))); + this->actor.world.rot.x += (s16)(500.0f * Math_SinS(this->bubble.unk_14A)); + this->actor.shape.rot.x = this->actor.world.rot.x; + + this->bubble.unk_14C += (s16)(this->bubble.unk_144 * (500.0f + Rand_ZeroFloat(1400.0f))); + this->actor.world.rot.y += (s16)(500.0f * Math_SinS(this->bubble.unk_14C)); + + this->actor.shape.rot.y = this->actor.world.rot.y; + + func_8088A514(this); + } + func_800B9010(&this->actor, NA_SE_IT_DEKUNUTS_BUBLE_SHOT_LEVEL - SFX_FLAG); + } else if (this->unk_260 < 7) { + this->actor.gravity = -0.4f; + } + + Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos); + + if (this->actor.speedXZ == 0.0f) { + this->actor.velocity.y -= 1.0f; + if (this->actor.velocity.y < this->actor.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } + Actor_UpdatePos(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + this->unk_262 = BgCheck_ProjectileLineTest(&globalCtx->colCtx, &this->actor.prevPos, &this->actor.world.pos, + &sp9C, &this->actor.wallPoly, true, true, true, true, &spA8); + if (this->unk_262 != 0) { + func_800B90AC(globalCtx, &this->actor, this->actor.wallPoly, spA8, &sp9C); + Math_Vec3f_Copy(&this->actor.world.pos, &sp9C); + this->actor.wallBgId = spA8; + } + + if (this->actor.params < ENARROW_6) { + this->actor.shape.rot.x = Math_FAtan2F(this->actor.speedXZ, -this->actor.velocity.y); + } + } + + if (this->unk_264 != NULL) { + if (this->unk_264->update != NULL) { + s32 pad; + + Math_Vec3f_Sum(&this->unk_228, &this->unk_268, &sp60); + Math_Vec3f_Sum(&this->actor.world.pos, &this->unk_268, &sp54); + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &sp60, &sp54, &sp9C, &spAC, true, true, true, true, + &spA8)) { + this->unk_264->world.pos.x = ((sp54.x <= sp9C.x) ? 1.0f : -1.0f) + sp9C.x; + this->unk_264->world.pos.y = ((sp54.y <= sp9C.y) ? 1.0f : -1.0f) + sp9C.y; + this->unk_264->world.pos.z = ((sp54.z <= sp9C.z) ? 1.0f : -1.0f) + sp9C.z; + + Math_Vec3f_Diff(&this->unk_264->world.pos, &this->actor.world.pos, &this->unk_268); + this->unk_264->flags &= ~0x8000; + this->unk_264 = NULL; + } else { + Math_Vec3f_Sum(&this->actor.world.pos, &this->unk_268, &this->unk_264->world.pos); + } + + if ((this->unk_262 != 0) && (this->unk_264 != NULL)) { + this->unk_264->flags &= ~0x8000; + this->unk_264 = NULL; + } + } else { + this->unk_264 = NULL; + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088ACE0.s") #endif -extern ColliderQuadInit D_8088C1E0; -extern InitChainEntry D_8088C230[]; +void func_8088B630(EnArrow* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->arrow.skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/EnArrow_Init.s") + if (this->actor.wallBgId != BG_ACTOR_MAX) { + BgCheck2_UpdateActorAttachedToMesh(&globalCtx->colCtx, this->actor.wallBgId, &this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/EnArrow_Destroy.s") + if (DECR(this->unk_260) == 0) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088A514.s") +void func_8088B6B0(EnArrow* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->arrow.skelAnime); + Actor_MoveWithGravity(&this->actor); + func_8088AA98(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088A594.s") + if (DECR(this->unk_260) == 0) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088A7D8.s") +void EnArrow_Update(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f D_8088C2CC = { 0.0f, 0.5f, 0.0f }; + static Vec3f D_8088C2D8 = { 0.0f, 0.5f, 0.0f }; + static Color_RGBA8 D_8088C2E4 = { 255, 255, 100, 255 }; + static Color_RGBA8 D_8088C2E8 = { 255, 50, 0, 0 }; + s32 pad; + EnArrow* this = THIS; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088A894.s") + if ((this->unk_263 != 0) || + ((this->actor.params >= ENARROW_0) && ((this->actor.params == ENARROW_7) || (player->unk_D57 != 0))) || + !func_80123358(globalCtx, player)) { + this->actionFunc(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088AA98.s") + if ((this->actor.params >= ENARROW_3) && (this->actor.params < ENARROW_6)) { + s16 sp44[] = { ACTOR_ARROW_FIRE, ACTOR_ARROW_ICE, ACTOR_ARROW_LIGHT }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088ACE0.s") + if (this->actor.child == NULL) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, sp44[this->actor.params - ENARROW_3], + this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); + } + } else if (this->actor.params == ENARROW_0) { + func_800B0EB0(globalCtx, &this->unk_234, &D_8088C2CC, &D_8088C2D8, &D_8088C2E4, &D_8088C2E8, 100, 0, 8); + } + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.prevPos); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088B630.s") +typedef struct { + /* 0x00 */ Vec3f unk_00[2]; + /* 0x18 */ Vec3f unk_18[2][2]; + /* 0x48 */ Vec3f unk_48; +} EnArrowUnkStruct; // size = 0x54 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088B6B0.s") +void func_8088B88C(GlobalContext* globalCtx, EnArrow* this, EnArrowUnkStruct* arg2) { + Vec3f* sp4C; + Vec3f sp40; + Vec3f sp34; + s32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/EnArrow_Update.s") + Matrix_MultVec3f(&arg2->unk_48, &this->unk_234); + if (func_8088ACE0 == this->actionFunc) { + if (!this->unk_244.active) { + sp4C = arg2->unk_00; + } else { + sp4C = arg2->unk_18[globalCtx->gameplayFrames % 2]; + } + Matrix_MultVec3f(&sp4C[0], &sp40); + Matrix_MultVec3f(&sp4C[1], &sp34); + if (this->actor.params < ENARROW_8) { + sp30 = this->actor.params < ENARROW_6; + if (this->unk_264 == 0) { + sp30 &= func_80126440(globalCtx, &this->collider, &this->unk_244, &sp40, &sp34); + } else if (sp30 && (sp40.x == this->unk_244.tip.x) && (sp40.y == this->unk_244.tip.y) && + (sp40.z == this->unk_244.tip.z) && (sp34.x == this->unk_244.base.x) && + (sp34.y == this->unk_244.base.y) && (sp34.z == this->unk_244.base.z)) { + sp30 = false; + } + if (sp30) { + EffectBlure_AddVertex(Effect_GetByIndex(this->unk_240), &sp40, &sp34); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/func_8088B88C.s") +void EnArrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + static EnArrowUnkStruct D_8088C2EC[] = { + { + { + { 400.0f, 400.0f, 0.0f }, + { -400.0f, 400.0f, 0.0f }, + }, + { + { + { 400.0f, 400.0f, 1500.0f }, + { -400.0f, 400.0f, 1500.0f }, + }, + { + { 400.0f, 400.0f, 1500.0f }, + { -400.0f, 400.0f, 1500.0f }, + }, + }, + { 0.0f, 0.0f, -300.0f }, + }, + { + { + { 20.0f, -20.0f, 20.0f }, + { 20.0f, -20.0f, 20.0f }, + }, + { + { + { 20.0f, -20.0f, 20.0f }, + { -20.0f, 20.0f, 20.0f }, + }, + { + { -20.0f, -20.0f, 20.0f }, + { 20.0f, 20.0f, 20.0f }, + }, + }, + { 0.0f, 0.0f, 20.0f }, + }, + }; + EnArrow* this = THIS; + s32 phi_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Arrow/EnArrow_Draw.s") + if (this->actor.params < ENARROW_6) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawLod(globalCtx, this->arrow.skelAnime.skeleton, this->arrow.skelAnime.jointTable, NULL, NULL, + &this->actor, this->actor.projectedPos.z < 160.0f ? 0 : 1); + } else if (this->actor.params == ENARROW_7) { + s32 spA4 = 255 - (s32)(this->bubble.unk_144 * 4.0f); + f32 spA0 = (this->actor.speedXZ * 0.1f) + 1.0f; + f32 sp9C = (1.0f / spA0); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->bubble.unk_149 >= 0) { + func_8088B88C(globalCtx, this, &D_8088C2EC[1]); + } else { + Collider_ResetQuadAT(globalCtx, &this->collider.base); + } + + sp9C *= 0.002f; + spA0 *= 0.002f; + + Matrix_Scale(this->bubble.unk_144 * sp9C, this->bubble.unk_144 * sp9C, this->bubble.unk_144 * spA0, + MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 460.0f, MTXMODE_APPLY); + + if (this->actor.speedXZ == 0.0f) { + func_800B8118(&this->actor, globalCtx, MTXMODE_NEW); + + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_06F380); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gDPSetCombineLERP(POLY_XLU_DISP++, TEXEL1, 0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, + COMBINED, 0, ENVIRONMENT, 0, COMBINED, 0, ENVIRONMENT, 0); + gDPSetEnvColor(POLY_XLU_DISP++, 230, 225, 150, spA4); + + Matrix_ReplaceRotation(&gIdentityMtxF); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_06F9F0); + } else { + func_800B8050(&this->actor, globalCtx, MTXMODE_NEW); + + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06F380); + gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, 0, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIM_LOD_FRAC, TEXEL0, + COMBINED, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x7F, 230, 225, 150, 255); + 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_06FAE0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + return; + } else if (this->actor.speedXZ != 0.0f) { + u8 sp63 = (Math_CosS(this->unk_260 * 5000) * 127.5f) + 127.5f; + f32 sp5C; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C240(globalCtx->state.gfxCtx); + + gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + + if (this->actor.params == ENARROW_6) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 255, 255, sp63); + sp5C = 50.0f; + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 12, 0, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 0, sp63); + sp5C = 150.0f; + } + + Matrix_Push(); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + if (this->actor.speedXZ == 0.0f) { + phi_v0 = 0; + } else { + phi_v0 = (globalCtx->gameplayFrames % 256) * 4000; + } + + Matrix_RotateZS(phi_v0, MTXMODE_APPLY); + Matrix_Scale(sp5C, sp5C, sp5C, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); + + Matrix_Pop(); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (this->actor.velocity.y != 0.0f) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Mult(&globalCtx->billboardMtxF, 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_058BA0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + func_8088B88C(globalCtx, this, &D_8088C2EC[0]); +} diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h index 119507d4d..654e8bea6 100644 --- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h +++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.h @@ -7,15 +7,50 @@ struct EnArrow; typedef void (*EnArrowActionFunc)(struct EnArrow*, GlobalContext*); +enum { + /* -8 */ ENARROW_MINUS8 = -8, + /* 0 */ ENARROW_0 = 0, + /* 1 */ ENARROW_1, + /* 2 */ ENARROW_2, + /* 3 */ ENARROW_3, + /* 4 */ ENARROW_4, + /* 5 */ ENARROW_5, + /* 6 */ ENARROW_6, + /* 7 */ ENARROW_7, + /* 8 */ ENARROW_8, +}; + +typedef struct { + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[5]; +} EnArrowArrow; // size = 0x1A8 + +typedef struct { + /* 0x144 */ f32 unk_144; + /* 0x148 */ u8 unk_148; + /* 0x149 */ s8 unk_149; + /* 0x14A */ s16 unk_14A; + /* 0x14C */ s16 unk_14C; +} EnArrowBubble; // size = 0x150 + typedef struct EnArrow { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x7C]; - /* 0x01C0 */ s32 unk_1C0; - /* 0x01C4 */ char unk_1C4[0x9C]; - /* 0x0260 */ u8 unk_260; // timer in OoT - /* 0x0261 */ u8 unk_261; // hitFlags in OoT - /* 0x0262 */ char unk_262[0x12]; - /* 0x0274 */ EnArrowActionFunc actionFunc; + /* 0x000 */ Actor actor; + union { + EnArrowArrow arrow; + EnArrowBubble bubble; + }; + /* 0x1A8 */ ColliderQuad collider; + /* 0x228 */ Vec3f unk_228; + /* 0x234 */ Vec3f unk_234; + /* 0x240 */ s32 unk_240; + /* 0x244 */ WeaponInfo unk_244; + /* 0x260 */ u8 unk_260; // timer in OoT + /* 0x261 */ u8 unk_261; // hitFlags in OoT + /* 0x262 */ u8 unk_262; + /* 0x263 */ u8 unk_263; + /* 0x264 */ Actor* unk_264; + /* 0x268 */ Vec3f unk_268; + /* 0x274 */ EnArrowActionFunc actionFunc; } EnArrow; // size = 0x278 extern const ActorInit En_Arrow_InitVars; 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 c1342a0f3..548e1e68d 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,6 +1,13 @@ -#include "z_en_attack_niw.h" +/* + * File: z_en_attack_niw.c + * Overlay: ovl_En_Attack_Niw + * Description: Attacking Cucco + */ -#define FLAGS 0x00000010 +#include "z_en_attack_niw.h" +#include "overlays/actors/ovl_En_Niw/z_en_niw.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnAttackNiw*)thisx) @@ -9,11 +16,10 @@ void EnAttackNiw_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx); void EnAttackNiw_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80958634(EnAttackNiw* this, GlobalContext* globalCtx); -void func_80958974(EnAttackNiw* this, GlobalContext* globalCtx); -void func_80958BE4(EnAttackNiw* this, GlobalContext* globalCtx); +void EnAttackNiw_EnterViewFromOffscreen(EnAttackNiw* this, GlobalContext* globalCtx); +void EnAttackNiw_AimAtPlayer(EnAttackNiw* this, GlobalContext* globalCtx); +void EnAttackNiw_FlyAway(EnAttackNiw* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Attack_Niw_InitVars = { ACTOR_EN_ATTACK_NIW, ACTORCAT_ENEMY, @@ -26,35 +32,420 @@ const ActorInit En_Attack_Niw_InitVars = { (ActorFunc)EnAttackNiw_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80959120[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 1, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 0, ICHAIN_STOP), }; -#endif +void EnAttackNiw_Init(Actor* thisx, GlobalContext* globalCtx) { + EnAttackNiw* this = THIS; -extern InitChainEntry D_80959120[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gNiwSkeleton, &gNiwIdleAnim, this->jointTable, this->morphTable, + NIW_LIMB_MAX); -extern UNK_TYPE D_060000E8; + // probably copy pasted from EnNiw, which has this same code, but AttackNiw has no params + if (this->actor.params < 0) { + this->actor.params = ATTACK_NIW_REGULAR; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/EnAttackNiw_Init.s") + Actor_SetScale(&this->actor, 0.01f); + this->actor.gravity = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/EnAttackNiw_Destroy.s") + this->randomTargetCenterOffset.x = randPlusMinusPoint5Scaled(100.0f); + this->randomTargetCenterOffset.y = randPlusMinusPoint5Scaled(10.0f); + this->randomTargetCenterOffset.z = randPlusMinusPoint5Scaled(100.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_80958228.s") + Actor_SetScale(&this->actor, 0.01f); + this->actor.flags &= ~ACTOR_FLAG_1; // Unnecessary: this actor does not start with this flag + this->actor.shape.rot.y = this->actor.world.rot.y = (Rand_ZeroOne() - 0.5f) * 60000.0f; + this->actionFunc = EnAttackNiw_EnterViewFromOffscreen; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_809585B0.s") +void EnAttackNiw_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAttackNiw* this = THIS; + EnNiw* parent = (EnNiw*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_80958634.s") + if (this->actor.parent != NULL && this->actor.parent->update != NULL) { + if (parent->attackNiwCount > 0) { + parent->attackNiwCount--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_80958974.s") +/** + * Summary: instead of using SkelAnime animations AttackNiw modifies head+wings directly to create animations + * + * EnNiw has its own version of this function, probably copy paste since AttackNiw only uses two animationState (2/5) + */ +void EnAttackNiw_AnimateWingHead(EnAttackNiw* this, GlobalContext* globalCtx, s16 animationState) { + if (this->unkTimer24C == 0) { + if (animationState == 0) { + this->targetBodyRotY = 0.0f; + } else { + this->targetBodyRotY = -10000.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_80958BE4.s") + this->clearRotYToggleTimer++; + this->unkTimer24C = 3; + if ((this->clearRotYToggleTimer % 2) == 0) { + this->targetBodyRotY = 0.0f; + if (animationState == 0) { + this->unkTimer24C = Rand_ZeroFloat(30.0f); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/EnAttackNiw_Update.s") + if (this->unkTimer250 == 0) { + this->unkToggle28A++; + this->unkToggle28A &= 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/func_80958F6C.s") + switch (animationState) { // only case 2 and 5 are ever called in AttackNiw + case NIW_ANIMATION_STILL: + this->targetLeftWingRotZ = 0.0f; + this->targetRightWingRotZ = 0.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Attack_Niw/EnAttackNiw_Draw.s") + case NIW_ANIMATION_HEAD_PECKING: + this->unkTimer250 = 3; + this->targetLeftWingRotZ = 7000.0f; + this->targetRightWingRotZ = 7000.0f; + if (this->unkToggle28A == 0) { + this->targetLeftWingRotZ = 0.0f; + this->targetRightWingRotZ = 0.0f; + } + break; + + case NIW_ANIMATION_PECKING_AND_WAVING: + this->unkTimer250 = 2; + this->targetLeftWingRotZ = -10000.0f; + this->targetRightWingRotZ = -10000.0f; + this->targetLeftWingRotY = 25000.0f; + this->targetRightWingRotY = 25000.0f; + this->targetLeftWingRotX = 6000.0f; + this->targetRightWingRotX = 6000.0f; + if (this->unkToggle28A == 0) { + this->targetRightWingRotY = 8000.0f; + this->targetLeftWingRotY = 8000.0f; + } + break; + + case NIW_ANIMATION_PECKING_AND_FORFLAPPING: + this->unkTimer250 = 2; + this->targetRightWingRotY = 10000.0f; + this->targetLeftWingRotY = 10000.0f; + if (this->unkToggle28A == 0) { + this->targetRightWingRotY = 3000.0f; + this->targetLeftWingRotY = 3000.0f; + } + break; + + case NIW_ANIMATION_FREEZE: + this->unusedTimer24E = 5; + this->unkTimer24C = this->unusedTimer24E; + break; + + case NIW_ANIMATION_PECKING_SLOW_FORFLAPPING: + this->unkTimer250 = 5; + this->targetRightWingRotY = 14000.0f; + this->targetLeftWingRotY = 14000.0f; + if (this->unkToggle28A == 0) { + this->targetRightWingRotY = 10000.0f; + this->targetLeftWingRotY = 10000.0f; + } + break; + } + } + + if (this->targetHeadRotZ != this->headRotZ) { + Math_ApproachF(&this->headRotZ, this->targetHeadRotZ, 0.5f, 4000.0f); + } + + if (this->targetBodyRotY != this->upperBodyRotY) { + Math_ApproachF(&this->upperBodyRotY, this->targetBodyRotY, 0.5f, 4000.0f); + } + + if (this->targetLeftWingRotZ != this->leftWingRotZ) { + Math_ApproachF(&this->leftWingRotZ, this->targetLeftWingRotZ, 0.8f, 7000.0f); + } + + if (this->targetLeftWingRotY != this->leftWingRotY) { + Math_ApproachF(&this->leftWingRotY, this->targetLeftWingRotY, 0.8f, 7000.0f); + } + + if (this->targetLeftWingRotX != this->leftWingRotX) { + Math_ApproachF(&this->leftWingRotX, this->targetLeftWingRotX, 0.8f, 7000.0f); + } + + if (this->targetRightWingRotZ != this->rightWingRotZ) { + Math_ApproachF(&this->rightWingRotZ, this->targetRightWingRotZ, 0.8f, 7000.0f); + } + + if (this->targetRightWingRotY != this->rightWingRotY) { + Math_ApproachF(&this->rightWingRotY, this->targetRightWingRotY, 0.8f, 7000.0f); + } + + if (this->targetRightWingRotX != this->rightWingRotX) { + Math_ApproachF(&this->rightWingRotX, this->targetRightWingRotX, 0.8f, 7000.0f); + } +} + +s32 EnAttackNiw_IsOnScreen(EnAttackNiw* this, GlobalContext* globalCtx) { + s16 posX; + s16 posY; + + Actor_SetFocus(&this->actor, this->targetHeight); + Actor_GetScreenPos(globalCtx, &this->actor, &posX, &posY); + + if ((this->actor.projectedPos.z < -20.0f) || (posX < 0) || (posX > SCREEN_WIDTH) || (posY < 0) || + (posY > SCREEN_HEIGHT)) { + return false; + } + return true; +} + +void EnAttackNiw_EnterViewFromOffscreen(EnAttackNiw* this, GlobalContext* globalCtx) { + s16 posX; + s16 posY; + Vec3f viewOffset; + Vec3f flightTarget; + s32 pad; + + this->actor.speedXZ = 10.0f; + + // randomTargetCenterOffset is set in _Init, only needs to be set once + // but the view is moving, so now we need to re-calculate the spot in space + viewOffset.x = this->randomTargetCenterOffset.x + globalCtx->view.at.x - globalCtx->view.eye.x; + viewOffset.y = this->randomTargetCenterOffset.y + globalCtx->view.at.y - globalCtx->view.eye.y; + viewOffset.z = this->randomTargetCenterOffset.z + globalCtx->view.at.z - globalCtx->view.eye.z; + + // this is the 3D spot in space where the cucco is trying to fly into (until it lands or gets close) + flightTarget.x = globalCtx->view.at.x + viewOffset.x; + flightTarget.y = globalCtx->view.at.y + viewOffset.y; + flightTarget.z = globalCtx->view.at.z + viewOffset.z; + + this->targetRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &flightTarget); + this->targetRotX = Math_Vec3f_Pitch(&this->actor.world.pos, &flightTarget) * -1.0f; + + Math_SmoothStepToS(&this->actor.world.rot.y, this->targetRotY, 5, this->rotStep, 0); + Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 5, this->rotStep, 0); + Math_ApproachF(&this->rotStep, 5000.0f, 1.0f, 100.0f); + + Actor_SetFocus(&this->actor, this->targetHeight); + Actor_GetScreenPos(globalCtx, &this->actor, &posX, &posY); + + if (this->actor.bgCheckFlags & 8) { // touching a wall + this->targetRotY = this->actor.yawTowardsPlayer; + this->targetRotX = this->actor.world.rot.x - 3000.0f; + this->hopTimer = 0; + this->randomAngleChangeTimer = 100; + this->rotStep = 0.0f; + this->targetLeftWingRotX = 0.0f; + this->targetRightWingRotX = 0.0f; + this->unkTimer250 = this->hopTimer; + this->unusedTimer24E = this->hopTimer; + this->unkTimer24C = this->hopTimer; + this->actor.gravity = -0.2f; + this->targetHeadRotZ = 0.0f; + this->actionFunc = EnAttackNiw_AimAtPlayer; + this->targetXZSpeed = 5.0f; + + } else if (((this->actor.projectedPos.z > 0.0f) && (fabsf(flightTarget.x - this->actor.world.pos.x) < 50.0f) && + (fabsf(flightTarget.y - this->actor.world.pos.y) < 50.0f) && + (fabsf(flightTarget.z - this->actor.world.pos.z) < 50.0f)) || + (this->actor.bgCheckFlags & 1)) { // touching ground or with close distance of target + // reset state + this->hopTimer = 0; + this->unkTimer250 = this->hopTimer; + this->unusedTimer24E = this->hopTimer; + this->unkTimer24C = this->hopTimer; + this->rotStep = 0.0f; + this->targetRightWingRotX = 0.0f; + this->targetLeftWingRotX = 0.0f; + + this->targetRotY = this->actor.yawTowardsPlayer; // start turn to face player + this->targetRotX = this->actor.world.rot.x - 2000.0f; // bank into the turn + this->actor.gravity = -0.2f; // start gentle decent (no longer flying without gravity) + this->targetHeadRotZ = 0.0f; + this->actionFunc = EnAttackNiw_AimAtPlayer; + this->targetXZSpeed = 5.0f; + + } else { // keep flying at the flightTarget for now + this->unkTimer24C = 10; + this->targetBodyRotY = -10000.0f; + this->targetHeadRotZ = -3000.0f; + EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); + } +} + +void EnAttackNiw_AimAtPlayer(EnAttackNiw* this, GlobalContext* globalCtx) { + if (!EnAttackNiw_IsOnScreen(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->actor.bgCheckFlags & 1) { // touching floor + if (this->hopTimer == 0) { + this->hopTimer = 3; + this->actor.velocity.y = 3.5f; + } + + if (this->actor.gravity != -2.0f) { // first landing + this->targetRotY = this->actor.yawTowardsPlayer; + this->unkTimer25A = 50; + this->randomAngleChangeTimer = 100; + this->targetRightWingRotY = 14000.0f; + this->targetLeftWingRotY = 14000.0f; + this->targetRightWingRotX = 0.0f; + this->targetLeftWingRotX = 0.0f; + this->targetRightWingRotZ = 0.0f; + this->targetLeftWingRotZ = 0.0f; + this->targetRotX = 0.0f; + this->actor.gravity = -2.0f; + } + } + + if (this->randomAngleChangeTimer == 50) { + this->targetRotY = randPlusMinusPoint5Scaled(200.0f) + this->actor.yawTowardsPlayer; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, this->targetRotY, 2, this->rotStep, 0); + Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 2, this->rotStep, 0); + Math_ApproachF(&this->rotStep, 10000.0f, 1.0f, 1000.0f); + Math_ApproachF(&this->actor.speedXZ, this->targetXZSpeed, 0.9f, 1.0f); + + if (this->actor.gravity == -2.0f && this->unkTimer25A == 0 && + (this->actor.bgCheckFlags & 8 || this->randomAngleChangeTimer == 0)) { + this->targetXZSpeed = 0.0f; + this->actor.gravity = 0.0f; + this->rotStep = 0.0f; + this->targetRotX = this->actor.world.rot.x - 5000.0f; + this->actionFunc = EnAttackNiw_FlyAway; + + } else if (this->actor.bgCheckFlags & 1) { // touching floor + EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_SLOW_FORFLAPPING); + + } else { + EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); + } +} + +void EnAttackNiw_FlyAway(EnAttackNiw* this, GlobalContext* globalCtx) { + if (!EnAttackNiw_IsOnScreen(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + + Math_SmoothStepToS(&this->actor.world.rot.x, this->targetRotX, 5, this->rotStep, 0); + Math_ApproachF(&this->rotStep, 5000.0f, 1.0f, 100.0f); + Math_ApproachF(&this->actor.velocity.y, 5.0f, 0.3f, 1.0f); + EnAttackNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); +} + +void EnAttackNiw_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAttackNiw* this = THIS; + s32 pad; + EnNiw* parent; + Player* player = GET_PLAYER(globalCtx); + s32 pad2; + Vec3f splashPos; + + this->unusedCounter284++; + + DECR(this->unkTimer24C); + DECR(this->unkTimer250); + DECR(this->hopTimer); + DECR(this->crySfxTimer); + DECR(this->flutterSfxTimer); + DECR(this->randomAngleChangeTimer); + DECR(this->unkTimer25A); + + this->actor.shape.rot = this->actor.world.rot; + this->actor.shape.shadowScale = 15.0f; + + this->actionFunc(this, globalCtx); + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); + + if (this->actionFunc == EnAttackNiw_EnterViewFromOffscreen) { + Actor_MoveWithoutGravity(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + if (this->actor.floorHeight <= BGCHECK_Y_MIN) { // under the world + Actor_MarkForDeath(&this->actor); + + } else if ((this->actor.bgCheckFlags & 0x20) && // on or below water + (this->actionFunc != EnAttackNiw_FlyAway)) { + Math_Vec3f_Copy(&splashPos, &this->actor.world.pos); + splashPos.y += this->actor.depthInWater; + EffectSsGSplash_Spawn(globalCtx, &splashPos, NULL, NULL, 0, 400); + this->rotStep = 0.0f; + this->actor.gravity = 0.0f; + this->targetXZSpeed = 0.0f; + this->targetRotX = this->actor.world.rot.x - 5000.0f; + this->actionFunc = EnAttackNiw_FlyAway; + + } else { + f32 viewOffset = 20.0f; + + label: + + if (this->actor.xyzDistToPlayerSq < SQ(viewOffset)) { + parent = (EnNiw*)this->actor.parent; + if ((this->actor.parent->update != NULL) && (this->actor.parent != NULL) && (parent != NULL) && + (parent->unkAttackNiwTimer == 0) && (player->invincibilityTimer == 0)) { + // this updates some player values based on what we pass, need player decomp to know what this is doing + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.world.rot.y, 0.0f, 0x10); + parent->unkAttackNiwTimer = 70; + } + } + + if (this->crySfxTimer == 0) { + this->crySfxTimer = 30; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_A); + } + + if (this->flutterSfxTimer == 0) { + this->flutterSfxTimer = 7; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_CHICKEN_FLUTTER); + } + } +} + +s32 EnAttackNiw_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnAttackNiw* this = THIS; + + if (limbIndex == NIW_LIMB_UPPER_BODY) { + rot->y += (s16)this->upperBodyRotY; + } + + if (limbIndex == NIW_LIMB_HEAD) { + rot->z += (s16)this->headRotZ; + } + + if (limbIndex == NIW_LIMB_RIGHT_WING_ROOT) { + rot->x += (s16)this->rightWingRotX; + rot->y += (s16)this->rightWingRotY; + rot->z += (s16)this->rightWingRotZ; + } + + if (limbIndex == NIW_LIMB_LEFT_WING_ROOT) { + rot->x += (s16)this->leftWingRotX; + rot->y += (s16)this->leftWingRotY; + rot->z += (s16)this->leftWingRotZ; + } + return false; +} + +void EnAttackNiw_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnAttackNiw* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnAttackNiw_OverrideLimbDraw, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h index 27d5546a1..c4dcaf8d0 100644 --- a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h +++ b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h @@ -2,18 +2,61 @@ #define Z_EN_ATTACK_NIW_H #include "global.h" +#include "objects/object_niw/object_niw.h" struct EnAttackNiw; typedef void (*EnAttackNiwActionFunc)(struct EnAttackNiw*, GlobalContext*); typedef struct EnAttackNiw { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; - /* 0x0248 */ EnAttackNiwActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x94]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX]; + /* 0x248 */ EnAttackNiwActionFunc actionFunc; + /* 0x24C */ s16 unkTimer24C; // control behavior in _UpdateRotations + /* 0x24E */ s16 unusedTimer24E; // set never read + /* 0x250 */ s16 unkTimer250; // control behavior in _UpdateRotations + /* 0x252 */ s16 hopTimer; + /* 0x254 */ s16 randomAngleChangeTimer; + /* 0x256 */ s16 crySfxTimer; + /* 0x258 */ s16 flutterSfxTimer; + /* 0x25A */ s16 unkTimer25A; // set to 50 in run at player, locks fly away without water? + /* 0x25C */ f32 targetBodyRotY; + /* 0x260 */ f32 targetRightWingRotZ; + /* 0x264 */ f32 targetLeftWingRotZ; + /* 0x268 */ f32 unusedRotations[2]; // in EnNiw this is an array of targetRot + /* 0x270 */ f32 targetRightWingRotY; + /* 0x274 */ f32 targetRightWingRotX; + /* 0x278 */ f32 targetLeftWingRotY; + /* 0x27C */ f32 targetLeftWingRotX; + /* 0x280 */ f32 targetHeadRotZ; + /* 0x284 */ s16 unusedCounter284; // incremented in _Update, never read + /* 0x286 */ s16 clearRotYToggleTimer; + /* 0x288 */ UNK_TYPE1 pad288[2]; + /* 0x28A */ s16 unkToggle28A; + /* 0x28C */ UNK_TYPE1 pad28C[4]; + /* 0x290 */ Vec3f randomTargetCenterOffset; // see EnAttackNiw_EnterViewFromOffscreen + /* 0x29C */ f32 leftWingRotZ; + /* 0x2A0 */ f32 leftWingRotY; + /* 0x2A4 */ f32 leftWingRotX; + /* 0x2A8 */ f32 rightWingRotZ; + /* 0x2AC */ f32 rightWingRotY; + /* 0x2B0 */ f32 rightWingRotX; + /* 0x2B4 */ f32 upperBodyRotY; + /* 0x2B8 */ f32 headRotZ; + /* 0x2BC */ UNK_TYPE1 pad2BC[0xC]; // unused rotations? + /* 0x2C8 */ f32 targetRotX; + /* 0x2CC */ f32 targetRotY; + /* 0x2D0 */ UNK_TYPE1 pad2D0[4]; + /* 0x2D4 */ f32 rotStep; + /* 0x2D8 */ f32 targetXZSpeed; + /* 0x2DC */ f32 targetHeight; // never set, but sent to Actor_SetFocus } EnAttackNiw; // size = 0x2E0 extern const ActorInit En_Attack_Niw_InitVars; + +#define ATTACK_NIW_REGULAR 0 // spawned by EnNiw + #endif // Z_EN_ATTACK_NIW_H 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 6ce1660e9..f815991c1 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.c +++ b/src/overlays/actors/ovl_En_Az/z_en_az.c @@ -1,6 +1,12 @@ +/* + * File: z_en_az.c + * Overlay: ovl_En_Az + * Description: Beaver Bros + */ + #include "z_en_az.h" -#define FLAGS 0x80000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnAz*)thisx) 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 8c9021927..e6dd15a32 100644 --- a/src/overlays/actors/ovl_En_Baba/z_en_baba.c +++ b/src/overlays/actors/ovl_En_Baba/z_en_baba.c @@ -1,6 +1,14 @@ -#include "z_en_baba.h" +/* + * File: z_en_baba.c + * Overlay: ovl_En_Baba + * Description: Bomb Shop Lady + */ -#define FLAGS 0x00000019 +#include "z_en_baba.h" +#include "overlays/actors/ovl_En_Ossan/z_en_ossan.h" +#include "objects/object_bba/object_bba.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBaba*)thisx) @@ -21,7 +29,6 @@ void func_80BA9E00(EnBaba* this, GlobalContext* globalCtx); void func_80BA9E10(EnBaba* this, GlobalContext* globalCtx); void func_80BA9E48(EnBaba* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Baba_InitVars = { ACTOR_EN_BABA, ACTORCAT_NPC, @@ -34,18 +41,38 @@ const ActorInit En_Baba_InitVars = { (ActorFunc)EnBaba_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BAA430 = { - { 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 AnimationInfo sAnimations[] = { + { &gBbaIdleHoldingBagAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gBbaIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gBbaWalkingHoldingBagAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gBbaKnockedOverAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &gBbaLyingDownAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &gBbaWalkingAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.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 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BAA45C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80BAA468 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -80,67 +107,673 @@ static DamageTable D_80BAA468 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static u8 D_80BAA488[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(1, 0x1D - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_BACKTOWN, 0x1C - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 30, 0x16 - 0x0E), + /* 0x0E */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(0, 30, 0x15 - 0x12), + /* 0x12 */ SCHEDULE_CMD_RET_VAL_L(1), + /* 0x15 */ SCHEDULE_CMD_RET_NONE(), + /* 0x16 */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 30, 2), + /* 0x1C */ SCHEDULE_CMD_RET_NONE(), + /* 0x1D */ SCHEDULE_CMD_RET_NONE(), +}; -extern ColliderCylinderInit D_80BAA430; -extern CollisionCheckInfoInit2 D_80BAA45C; -extern DamageTable D_80BAA468; +s32 D_80BAA4A8[] = { -1, -1, 0 }; -extern UNK_TYPE D_06006B10; -extern UNK_TYPE D_060092A0; +static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8820.s") +s32 func_80BA8820(EnBaba* this, GlobalContext* globalCtx) { + this->unk_144 = (EnOssan*)SubS_FindActor(globalCtx, &this->unk_144->actor, ACTORCAT_NPC, ACTOR_EN_OSSAN); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA886C.s") + if (this->unk_144 != NULL) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8C4C.s") +void func_80BA886C(EnBaba* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8C90.s") + switch (this->unk_1E0) { + case 0: + if (this->unk_40A & 8) { + if (gSaveContext.save.weekEventReg[33] & 8) { + this->unk_1E0 = 0x2A34; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8D2C.s") + if (gSaveContext.save.weekEventReg[79] & 0x40) { + this->unk_40A |= 1; + this->unk_1E0 = 0x2A33; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8DF4.s") + this->unk_40A |= 1; + this->unk_1E0 = 0x2A32; + break; + } else if (player->transformation == PLAYER_FORM_DEKU) { + if (!(gSaveContext.save.weekEventReg[79] & 0x20)) { + gSaveContext.save.weekEventReg[79] |= 0x20; + this->unk_40A |= 1; + this->unk_1E0 = 0x2A37; + break; + } else { + this->unk_40A |= 1; + this->unk_1E0 = 0x2A38; + } + break; + } else if (!(gSaveContext.save.weekEventReg[33] & 8)) { + if (!(gSaveContext.save.weekEventReg[73] & 1)) { + this->unk_1E0 = 0x660; + break; + } + this->unk_1E0 = 0x662; + break; + } else { + if (!(gSaveContext.save.weekEventReg[73] & 2)) { + this->unk_1E0 = 0x65A; + break; + } + this->unk_1E0 = 0x65E; + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA8F88.s") + case 0x660: + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk_144->actor); + this->unk_1E0 = 0x661; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9110.s") + case 0x661: + Actor_ChangeFocus(&this->unk_144->actor, globalCtx, &this->actor); + this->unk_1E0 = 0x662; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9160.s") + case 0x662: + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk_144->actor); + this->unk_1E0 = 0x663; + gSaveContext.save.weekEventReg[73] |= 1; + this->unk_40A |= 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA93AC.s") + case 0x65A: + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk_144->actor); + this->unk_1E0 = 0x65B; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9480.s") + case 0x65B: + Actor_ChangeFocus(&this->unk_144->actor, globalCtx, &this->actor); + this->unk_1E0 = 0x65C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9758.s") + case 0x65C: + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk_144->actor); + this->unk_1E0 = 0x65D; + gSaveContext.save.weekEventReg[73] |= 2; + this->unk_40A |= 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9848.s") + case 0x65E: + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk_144->actor); + this->unk_1E0 = 0x65F; + this->unk_40A |= 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA98EC.s") + case 0x2A34: + if (INV_CONTENT(ITEM_MASK_BLAST) == ITEM_MASK_BLAST) { + this->unk_40A |= 1; + this->unk_1E0 = 0x2A36; + break; + } + this->unk_40A |= 0x20; + this->unk_1E0 = 0x2A35; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9AB8.s") + case 0x2A35: + this->unk_40A |= 1; + this->unk_1E0 = 0x2A36; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9B24.s") + case 0x2A30: + case 0x2A31: + this->unk_40A |= 1; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9B80.s") + Message_StartTextbox(globalCtx, this->unk_1E0, &this->actor); + if (this->unk_40A & 1) { + if (this->unk_40A & 0x40) { + this->unk_40A &= ~0x40; + func_80151BB4(globalCtx, 0x33); + } + func_80151BB4(globalCtx, 4); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9CD4.s") +void func_80BA8C4C(GlobalContext* globalCtx, u16 nextEntrance) { + globalCtx->nextEntranceIndex = nextEntrance; + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 0x40; + globalCtx->sceneLoadFlag = 0x14; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9E00.s") +void func_80BA8C90(EnBaba* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.world.pos.x + 5.0f; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.world.pos.z + 22.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9E10.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_En_Baba/func_80BA9E48.s") +s32 func_80BA8D2C(EnBaba* this, f32 arg1) { + s16 sp3E; + s32 ret = false; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/EnBaba_Init.s") + Math_SmoothStepToF(&this->actor.speedXZ, arg1, 0.4f, 1000.0f, 0.0f); + sp3E = this->actor.speedXZ * 400.0f; + if (SubS_CopyPointFromPath(this->path, this->unk_1E8, &sp2C) && SubS_MoveActorToPoint(&this->actor, &sp2C, sp3E)) { + this->unk_1E8++; + if (this->unk_1E8 >= this->path->count) { + ret = true; + } + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/EnBaba_Destroy.s") +void func_80BA8DF4(EnBaba* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/EnBaba_Update.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BA9FB0.s") + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x36B0, this->actor.yawTowardsPlayer) && + !(this->unk_40A & 4)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BAA198.s") + SubS_TurnToPoint(&point, &this->actor.focus.pos, &this->actor.shape.rot, &this->turnTarget, &this->headRot, + &this->torsoRot, &sTurnOptions); + } else { + Math_SmoothStepToS(&this->turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/func_80BAA20C.s") + SubS_FillLimbRotTables(globalCtx, this->unk_302, this->unk_326, ARRAY_COUNT(this->unk_302)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baba/EnBaba_Draw.s") + if (this->unk_40A & 2) { + func_80BA8C90(this, globalCtx); + } +} + +s32 func_80BA8F88(EnBaba* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp26 = (u16)(gSaveContext.save.time - 0x3FFC); + u16 temp; + u8 sp23 = ENBABA_GET_3F00(&this->actor); + + if (D_80BAA4A8[arg2->result] >= 0) { + this->unk_410 = SubS_GetAdditionalPath(globalCtx, sp23, D_80BAA4A8[arg2->result]); + } + + if (this->unk_410 == NULL) { + return false; + } + + if ((this->unk_434 != 0) && (this->unk_436 >= 0)) { + temp = sp26; + } else { + temp = arg2->time0; + } + + if (arg2->time1 < temp) { + this->unk_424 = (temp - arg2->time1) + 0xFFFF; + } else { + this->unk_424 = arg2->time1 - temp; + } + + this->unk_430 = sp26 - temp; + temp = this->unk_410->count - 2; + this->unk_428 = this->unk_424 / temp; + this->unk_438 = 0; + this->unk_42C = (this->unk_430 / this->unk_428) + 2; + this->unk_43C = 0; + return true; +} + +s32 func_80BA9110(EnBaba* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret; + + switch (arg2->result) { + default: + ret = false; + break; + + case 2: + ret = func_80BA8F88(this, globalCtx, arg2); + break; + + case 1: + ret = true; + break; + } + return ret; +} + +s32 func_80BA9160(EnBaba* this, GlobalContext* globalCtx) { + f32 sp7C[265]; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + s32 sp54 = 0; + s32 sp50 = 0; + s32 pad; + + func_8013AF00(sp7C, 3, this->unk_410->count + 3); + + if (this->unk_438 == 0) { + sp58 = gZeroVec3f; + + func_8013B6B0(this->unk_410, &this->unk_420, &this->unk_430, this->unk_428, this->unk_424, &this->unk_42C, sp7C, + &sp58, this->unk_436); + func_8013B878(globalCtx, this->unk_410, this->unk_42C, &sp58); + this->actor.world.pos.y = sp58.y; + this->unk_438 = 1; + } else { + sp58 = this->unk_414; + } + + this->actor.world.pos.x = sp58.x; + this->actor.world.pos.z = sp58.z; + + if (SubS_InCsMode(globalCtx)) { + sp54 = this->unk_430; + sp50 = this->unk_42C; + sp58 = this->actor.world.pos; + } + + this->unk_414 = gZeroVec3f; + + if (func_8013B6B0(this->unk_410, &this->unk_420, &this->unk_430, this->unk_428, this->unk_424, &this->unk_42C, sp7C, + &this->unk_414, this->unk_436)) { + this->unk_43C = 1; + } else { + sp70 = this->actor.world.pos; + sp64 = this->unk_414; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); + } + + if (SubS_InCsMode(globalCtx)) { + this->unk_430 = sp54; + this->unk_42C = sp50; + this->unk_414 = sp58; + } + + return false; +} + +void func_80BA93AC(EnBaba* this, GlobalContext* globalCtx) { + if (this->unk_434 != 1) { + if (this->unk_434 == 2) { + gSaveContext.save.weekEventReg[58] |= 0x40; + this->unk_40A |= 2; + func_80BA9160(this, globalCtx); + } + } else { + this->unk_40C = 3; + this->unk_1E0 = 10800; + this->actor.speedXZ = 0.0f; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->unk_40A |= 4; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_40C); + this->actionFunc = func_80BA9CD4; + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 4, 0x1554); +} + +void func_80BA9480(EnBaba* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gBbaSkel, &gBbaWalkingHoldingBagAnim, this->jointTable, + this->morphTable, 0x12); + + this->actor.draw = EnBaba_Draw; + this->unk_40A |= 0x80; + this->actor.flags |= ACTOR_FLAG_1; + + if (globalCtx->sceneNum == SCENE_BOMYA) { + this->unk_40A |= 2; + this->unk_40C = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actionFunc = func_80BA9758; + } else if (globalCtx->sceneNum == SCENE_BACKTOWN) { + if ((ENBABA_GET_C000(&this->actor) == ENBABA_C000_0) && (gSaveContext.save.entranceIndex != 0xD670) && + ((ENBABA_GET_3F00(&this->actor)) != ENBABA_3F00_3F)) { + if ((gSaveContext.save.weekEventReg[58] & 0x40) || + (!(gSaveContext.save.time < CLOCK_TIME(0, 20)) && (gSaveContext.save.time < CLOCK_TIME(6, 0)))) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->unk_404 = 50; + this->unk_40C = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80BA9B80; + } else if ((ENBABA_GET_C000(&this->actor) == ENBABA_C000_1) && (gSaveContext.save.entranceIndex == 0xD670)) { + if (gSaveContext.save.weekEventReg[81] & 2) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->unk_40A |= 2; + if (gSaveContext.save.weekEventReg[33] & 8) { + this->unk_40C = 0; + } else { + this->unk_40C = 1; + } + + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_40C); + this->unk_40A |= 8; + this->actionFunc = func_80BA9758; + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } else { + this->unk_40A |= 2; + if (ENBABA_GET_C000(&this->actor) == ENBABA_C000_2) { + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_40C = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + this->actionFunc = func_80BA9E00; + } else if ((ENBABA_GET_3F00(&this->actor)) != ENBABA_3F00_3F) { + this->unk_40C = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80BA9E10; + } else { + this->unk_40C = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80BA9E48; + } + } +} + +void func_80BA9758(EnBaba* this, GlobalContext* globalCtx) { + if ((this->unk_40A & 8) || (this->unk_144 != NULL) || func_80BA8820(this, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80BA886C(this, globalCtx); + if (this->unk_40A & 8) { + this->actor.flags &= ~ACTOR_FLAG_10000; + } + this->actionFunc = func_80BA98EC; + } else if (this->actor.xzDistToPlayer < 100.0f) { + if (this->unk_40A & 8) { + this->actor.flags |= ACTOR_FLAG_10000; + } + func_800B8614(&this->actor, globalCtx, 100.0f); + } + } +} + +void func_80BA9848(EnBaba* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (((temp_v0 == 5) || (temp_v0 == 6)) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BA9B80; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); +} + +void func_80BA98EC(EnBaba* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_40A & 1) { + this->unk_40A &= ~1; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + if (this->unk_40A & 8) { + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { + if (globalCtx->msgCtx.unk120B1 == 0) { + gSaveContext.save.weekEventReg[81] |= 2; + func_80BA8C4C(globalCtx, 0xD670); + return; + } + } else { + gSaveContext.save.weekEventReg[81] |= 2; + func_80BA8C4C(globalCtx, 0xD670); + } + } else { + this->unk_1E0 = 0; + this->actionFunc = func_80BA9758; + } + } else if (this->unk_40A & 0x20) { + this->unk_40A &= ~0x20; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BA9AB8; + } else { + func_80BA886C(this, globalCtx); + } + } + } else if (temp_v0 == 6) { + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.unk120B1 == 0)) { + gSaveContext.save.weekEventReg[81] |= 2; + func_80BA8C4C(globalCtx, 0xD670); + } + } +} + +void func_80BA9AB8(EnBaba* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->unk_40A |= 0x40; + this->actionFunc = func_80BA9B24; + } else { + Actor_PickUp(&this->actor, globalCtx, GI_MASK_BLAST, 300.0f, 300.0f); + } +} + +void func_80BA9B24(EnBaba* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80BA886C(this, globalCtx); + this->actionFunc = func_80BA98EC; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_80BA9B80(EnBaba* this, GlobalContext* globalCtx) { + ScheduleResult sp20; + + this->unk_436 = REG(15) + ((void)0, gSaveContext.save.daySpeed); + + if (!Schedule_RunScript(globalCtx, D_80BAA488, &sp20) || + ((this->unk_434 != sp20.result) && !func_80BA9110(this, globalCtx, &sp20))) { + this->unk_40A &= ~0x80; + this->actor.flags &= ~ACTOR_FLAG_1; + sp20.result = false; + } else { + this->unk_40A |= 0x80; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_434 = sp20.result; + + func_80BA93AC(this, globalCtx); + + if (this->unk_40A & 2) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x2A39, &this->actor); // "I'm sorry" + this->actionFunc = func_80BA9848; + } else if ((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) { + func_800B863C(&this->actor, globalCtx); + } + } + Actor_MoveWithGravity(&this->actor); +} + +void func_80BA9CD4(EnBaba* this, GlobalContext* globalCtx) { + s16 sp2E = this->skelAnime.curFrame; + s16 sp2C = Animation_GetLastFrame(sAnimations[this->unk_40C].animation); + + this->collider.dim.height = 37; + this->collider.dim.radius = 23; + + if (this->unk_40C == 3) { + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_BBVO00); + } + + if (sp2E == sp2C) { + this->unk_40C = 4; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + } + } else { + if ((gSaveContext.save.weekEventReg[79] & 0x40) && (DECR(this->unk_404) == 0)) { + Audio_QueueSeqCmd(0x101400FF); + func_80BA8C4C(globalCtx, 0xD670); + } else { + Actor_MoveWithGravity(&this->actor); + } + } +} + +void func_80BA9E00(EnBaba* this, GlobalContext* globalCtx) { +} + +void func_80BA9E10(EnBaba* this, GlobalContext* globalCtx) { + if (func_80BA8D2C(this, 1.0f)) { + this->unk_1E8 = 0; + } +} + +void func_80BA9E48(EnBaba* this, GlobalContext* globalCtx) { + this->actor.shape.rot = this->actor.world.rot; +} + +void EnBaba_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBaba* this = THIS; + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + this->path = SubS_GetPathByIndex(globalCtx, ENBABA_GET_3F00(&this->actor), ENBABA_3F00_3F); + + Actor_SetScale(&this->actor, 0.01f); + + this->actor.targetMode = 0; + this->actor.gravity = -4.0f; + this->actionFunc = func_80BA9480; +} + +void EnBaba_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBaba* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnBaba_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBaba* this = THIS; + + this->actionFunc(this, globalCtx); + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + func_80BA8DF4(this, globalCtx); +} + +s32 EnBaba_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBaba* this = THIS; + + if (limbIndex == 6) { + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == 5) { + Matrix_RotateXS(-this->torsoRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->torsoRot.x, MTXMODE_APPLY); + } + + if ((limbIndex == 6) && (this->unk_1E2 != 0) && ((globalCtx->state.frames % 2) == 0)) { + Matrix_Translate(40.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if ((limbIndex == 5) || (limbIndex == 10) || (limbIndex == 14)) { + rot->y += (s16)(Math_SinS(this->unk_302[limbIndex]) * 200.0f); + rot->z += (s16)(Math_CosS(this->unk_326[limbIndex]) * 200.0f); + } + + if (((this->unk_40C == 1) || (this->unk_40C == 3) || (this->unk_40C == 4) || + (ENBABA_GET_C000(&this->actor) == ENBABA_C000_2)) && + (limbIndex == 8)) { + *dList = NULL; + } + return 0; +} + +void EnBaba_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnBaba* this = THIS; + Vec3f sp18 = { 0.0f, 0.0f, 0.0f }; + + if (limbIndex == 7) { + this->actor.focus.pos.x = this->actor.world.pos.x; + this->actor.focus.pos.y = this->actor.world.pos.y; + this->actor.focus.pos.z = this->actor.world.pos.z; + Matrix_MultVec3f(&sp18, &this->actor.focus.pos); + } +} + +void EnBaba_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +} + +void EnBaba_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBaba* this = THIS; + Vec3f sp4C; + Vec3f sp40; + + if (this->unk_40A & 2) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(gBbaEyeTex)); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnBaba_OverrideLimbDraw, EnBaba_PostLimbDraw, + EnBaba_TransformLimbDraw, &this->actor); + + if (this->unk_40A & 0x80) { + if ((this->unk_40C == 3) || (this->unk_40C == 4)) { + func_8012C2DC(globalCtx->state.gfxCtx); + sp4C.x = this->actor.world.pos.x + 20.0f; + sp4C.y = this->actor.world.pos.y; + sp4C.z = this->actor.world.pos.z + 20.0f; + } else { + sp4C = this->actor.world.pos; + } + + sp40.x = sp40.y = sp40.z = 0.3f; + func_800BC620(&sp4C, &sp40, 255, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Baba/z_en_baba.h b/src/overlays/actors/ovl_En_Baba/z_en_baba.h index fdc0648b9..6a21168b6 100644 --- a/src/overlays/actors/ovl_En_Baba/z_en_baba.h +++ b/src/overlays/actors/ovl_En_Baba/z_en_baba.h @@ -7,11 +7,53 @@ struct EnBaba; typedef void (*EnBabaActionFunc)(struct EnBaba*, GlobalContext*); +#define ENBABA_GET_3F00(thisx) (((thisx)->params & 0x3F00) >> 8) +#define ENBABA_GET_C000(thisx) (((thisx)->params & 0xC000) >> 0xE) + +#define ENBABA_3F00_3F 0x3F + +enum { + /* 0 */ ENBABA_C000_0, + /* 1 */ ENBABA_C000_1, + /* 2 */ ENBABA_C000_2, +}; + typedef struct EnBaba { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4]; + /* 0x0144 */ struct EnOssan* unk_144; /* 0x0148 */ EnBabaActionFunc actionFunc; - /* 0x014C */ char unk_14C[0x2F4]; + /* 0x014C */ UNK_TYPE1 unk14C[4]; + /* 0x0150 */ SkelAnime skelAnime; + /* 0x0194 */ ColliderCylinder collider; + /* 0x01E0 */ u16 unk_1E0; + /* 0x01E2 */ u8 unk_1E2; + /* 0x01E4 */ Path* path; + /* 0x01E8 */ s16 unk_1E8; + /* 0x01EA */ UNK_TYPE1 unk1EA[0x1C]; + /* 0x0206 */ Vec3s jointTable[18]; + /* 0x0272 */ Vec3s morphTable[18]; + /* 0x02DE */ Vec3s turnTarget; + /* 0x02E4 */ Vec3s headRot; + /* 0x02EA */ Vec3s torsoRot; + /* 0x02F0 */ UNK_TYPE1 unk2F0[0x12]; + /* 0x0302 */ s16 unk_302[18]; + /* 0x0326 */ s16 unk_326[18]; + /* 0x034A */ UNK_TYPE1 unk34A[0xBA]; + /* 0x0404 */ s16 unk_404; + /* 0x0406 */ UNK_TYPE1 unk406[4]; + /* 0x040A */ u16 unk_40A; + /* 0x040C */ s32 unk_40C; + /* 0x0410 */ Path* unk_410; + /* 0x0414 */ Vec3f unk_414; + /* 0x0420 */ f32 unk_420; + /* 0x0424 */ s32 unk_424; + /* 0x0428 */ s32 unk_428; + /* 0x042C */ s32 unk_42C; + /* 0x0430 */ s32 unk_430; + /* 0x0434 */ u8 unk_434; + /* 0x0436 */ s16 unk_436; + /* 0x0438 */ s32 unk_438; + /* 0x043C */ s32 unk_43C; } EnBaba; // size = 0x440 extern const ActorInit En_Baba_InitVars; 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 52df1b78e..88fc11072 100644 --- a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c +++ b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c @@ -1,6 +1,13 @@ -#include "z_en_baguo.h" +/* + * File: z_en_baguo.c + * Overlay: ovl_En_Baguo + * Description: Nejiron + */ -#define FLAGS 0x00000005 +#include "z_en_baguo.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnBaguo*)thisx) @@ -8,7 +15,33 @@ void EnBaguo_Init(Actor* thisx, GlobalContext* globalCtx); void EnBaguo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBaguo_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnBaguo_UndergroundIdle(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_EmergeFromUnderground(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_Idle(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_Roll(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_SetupRetreatUnderground(EnBaguo* this); +void EnBaguo_RetreatUnderground(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_DrawBody(Actor* thisx, GlobalContext* globalCtx); +void EnBaguo_InitializeParticle(EnBaguo* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, + s16 timer); +void EnBaguo_UpdateParticles(EnBaguo* this, GlobalContext* globalCtx); +void EnBaguo_DrawRockParticles(EnBaguo* this, GlobalContext* globalCtx); + +typedef enum { + /* 0x0 */ NEJIRON_ACTION_INACTIVE, // The Nejiron is either underground or emerging from underground + /* 0x1 */ NEJIRON_ACTION_ACTIVE, // The Nejiron is above ground and actively chasing the player + /* 0x2 */ NEJIRON_ACTION_RETREATING, // The Nejiron is burrowing back underground + /* 0x3 */ NEJIRON_ACTION_EXPLODING // The Nejiron has detonated +} NejironAction; + +/** + * These directions are relative to the Nejiron. + */ +typedef enum { + /* 0x0 */ NEJIRON_DIRECTION_RIGHT, + /* 0x1 */ NEJIRON_DIRECTION_LEFT +} NejironRollDirection; + const ActorInit En_Baguo_InitVars = { ACTOR_EN_BAGUO, ACTORCAT_ENEMY, @@ -21,92 +54,461 @@ const ActorInit En_Baguo_InitVars = { (ActorFunc)NULL, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80A3C2F0[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 0 }, 1 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80A3C314 = { - { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80A3C2F0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static DamageTable sDamageTable = { -static DamageTable D_80A3C324 = { - /* Deku Nut */ DMG_ENTRY(0, 0xF), - /* Deku Stick */ DMG_ENTRY(0, 0xF), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xE), - /* Zora boomerang */ DMG_ENTRY(3, 0xE), - /* Normal arrow */ DMG_ENTRY(0, 0xF), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(3, 0xE), - /* Goron punch */ DMG_ENTRY(2, 0xE), - /* Sword */ DMG_ENTRY(1, 0xE), - /* Goron pound */ DMG_ENTRY(1, 0xE), - /* Fire arrow */ DMG_ENTRY(0, 0xF), - /* Ice arrow */ DMG_ENTRY(0, 0xF), - /* Light arrow */ DMG_ENTRY(1, 0xE), - /* Goron spikes */ DMG_ENTRY(2, 0xE), - /* Deku spin */ DMG_ENTRY(0, 0xF), - /* Deku bubble */ DMG_ENTRY(0, 0xF), - /* Deku launch */ DMG_ENTRY(1, 0xE), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0xF), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(0, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0xE), - /* Spin attack */ DMG_ENTRY(1, 0xE), - /* 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, 0xE), +typedef enum { + /* 0x0 */ NEJIRON_DMGEFF_NONE, // Does not interact with the Nejiron at all + /* 0xE */ NEJIRON_DMGEFF_KILL = 14, // Kills and detonates the Nejiron + /* 0xF */ NEJIRON_DMGEFF_RECOIL // Deals no damage, but displays the appropriate hit mark and recoil animation +} NejironDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Deku Stick */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Horse trample */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Zora boomerang */ DMG_ENTRY(3, NEJIRON_DMGEFF_KILL), + /* Normal arrow */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(3, NEJIRON_DMGEFF_KILL), + /* Goron punch */ DMG_ENTRY(2, NEJIRON_DMGEFF_KILL), + /* Sword */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Goron pound */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Fire arrow */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Ice arrow */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Light arrow */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Goron spikes */ DMG_ENTRY(2, NEJIRON_DMGEFF_KILL), + /* Deku spin */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Deku bubble */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Deku launch */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, NEJIRON_DMGEFF_RECOIL), + /* Zora barrier */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Normal shield */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Spin attack */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), + /* Sword beam */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, NEJIRON_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), }; -#endif +void EnBaguo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBaguo* this = THIS; -extern ColliderJntSphElementInit D_80A3C2F0[1]; -extern ColliderJntSphInit D_80A3C314; -extern DamageTable D_80A3C324; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gNejironSkel, NULL, this->jointTable, this->morphTable, + NEJIRON_LIMB_MAX); + this->actor.hintId = 0xB; + this->maxDistanceFromHome = 240.0f; + this->maxDistanceFromHome += this->actor.world.rot.z * 40.0f; + this->actor.world.rot.z = 0; + Actor_SetScale(&this->actor, 0.01f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 2; -extern UNK_TYPE D_060020E8; + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->collider.elements[0].dim.modelSphere.radius = 30; + this->collider.elements[0].dim.scale = 1.0f; + this->collider.elements[0].dim.modelSphere.center.x = 80; + this->collider.elements[0].dim.modelSphere.center.y = 80; + this->collider.elements[0].dim.modelSphere.center.z = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/EnBaguo_Init.s") + this->actor.shape.yOffset = -3000.0f; + this->actor.gravity = -3.0f; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + this->collider.base.acFlags |= AC_HARD; + this->actionFunc = EnBaguo_UndergroundIdle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/EnBaguo_Destroy.s") +void EnBaguo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBaguo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B220.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B2CC.s") +void EnBaguo_UndergroundIdle(EnBaguo* this, GlobalContext* globalCtx) { + this->action = NEJIRON_ACTION_INACTIVE; + if (this->actor.xzDistToPlayer < 200.0f && Player_GetMask(globalCtx) != PLAYER_MASK_STONE) { + this->actor.draw = EnBaguo_DrawBody; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BAKUO_APPEAR); + this->actor.world.rot.z = 0; + this->actor.world.rot.x = this->actor.world.rot.z; + this->actor.flags &= ~ACTOR_FLAG_8000000; + this->actor.flags |= ACTOR_FLAG_1; + this->actionFunc = EnBaguo_EmergeFromUnderground; + } + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B3E0.s") +void EnBaguo_EmergeFromUnderground(EnBaguo* this, GlobalContext* globalCtx) { + this->actor.world.rot.y += 0x1518; + this->actor.shape.rot.y = this->actor.world.rot.y; + if ((globalCtx->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale - 20.0f, + 10, 8.0f, 500, 10, 1); + } + Math_ApproachF(&this->actor.shape.shadowScale, 50.0f, 0.3f, 5.0f); + Math_ApproachF(&this->actor.shape.yOffset, 2700.0f, 100.0f, 500.0f); + if (this->actor.shape.yOffset > 2650.0f) { + this->action = NEJIRON_ACTION_ACTIVE; + this->actor.shape.yOffset = 2700.0f; + this->timer = 60; + this->actionFunc = EnBaguo_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B5E0.s") +void EnBaguo_Idle(EnBaguo* this, GlobalContext* globalCtx) { + s16 absoluteYaw; + s16 yaw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B794.s") + if (this->timer != 0) { + // Depending on how the last roll ended, this actor may be "sitting" on + // something other than its legs. This slowly corrects that. + Math_SmoothStepToS(&this->actor.world.rot.x, 0, 10, 100, 1000); + Math_SmoothStepToS(&this->actor.world.rot.z, 0, 10, 100, 1000); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B7B8.s") + // If this actor isn't mostly facing the player, do a discrete turn towards + // them. It takes 8 frames to turn, and we must wait 8 frames to do another. + if ((this->timer & 8) != 0) { + if (fabsf(this->actor.world.rot.y - this->actor.yawTowardsPlayer) > 200.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 30, 300, 1000); + if ((globalCtx->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale - 20.0f, 10, 8.0f, 500, 10, 1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BAKUO_VOICE); + } + } + } + this->actor.shape.rot.y = this->actor.world.rot.y; + } else { + yaw = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + absoluteYaw = ABS_ALT(yaw); + Math_Vec3f_Copy(&this->targetRotation, &gZeroVec3f); + Math_Vec3f_Copy(&this->currentRotation, &gZeroVec3f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B8F8.s") + if (absoluteYaw < 0x2000) { + this->targetRotation.x = 2000.0f; + } else { + this->zRollDirection = NEJIRON_DIRECTION_RIGHT; + this->targetRotation.z = 2000.0f; + if ((s16)(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0) { + this->zRollDirection = NEJIRON_DIRECTION_LEFT; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3B958.s") + this->timer = 38; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->bouncedFlag = 0; + this->actionFunc = EnBaguo_Roll; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/EnBaguo_Update.s") +void EnBaguo_Roll(EnBaguo* this, GlobalContext* globalCtx) { + f32 xDistanceFromHome = this->actor.home.pos.x - this->actor.world.pos.x; + f32 zDistanceFromHome = this->actor.home.pos.z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3BE24.s") + if ((sqrtf(SQ(xDistanceFromHome) + SQ(zDistanceFromHome)) > this->maxDistanceFromHome) || + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE)) { + EnBaguo_SetupRetreatUnderground(this); + } else if (this->timer == 0) { + this->timer = 100; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnBaguo_Idle; + this->actor.speedXZ = 0.0f; + } else { + if (!this->bouncedFlag && this->collider.base.atFlags & AT_BOUNCED) { + this->zRollDirection ^= 1; + this->bouncedFlag = 1; + this->actor.speedXZ = -7.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3BE60.s") + Math_ApproachF(&this->currentRotation.x, this->targetRotation.x, 0.2f, 1000.0f); + Math_ApproachF(&this->currentRotation.z, this->targetRotation.z, 0.2f, 1000.0f); + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 0.5f); + this->actor.world.rot.x += (s16)this->currentRotation.x; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3BF0C.s") + if (this->currentRotation.z != 0.0f) { + if (this->zRollDirection == NEJIRON_DIRECTION_RIGHT) { + this->actor.world.rot.z += (s16)this->currentRotation.z; + } else { + this->actor.world.rot.z -= (s16)this->currentRotation.z; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3C008.s") + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BAKUO_ROLL - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Baguo/func_80A3C17C.s") +void EnBaguo_SetupRetreatUnderground(EnBaguo* this) { + this->action = NEJIRON_ACTION_RETREATING; + this->actionFunc = EnBaguo_RetreatUnderground; + this->actor.speedXZ = 0.0f; +} + +void EnBaguo_RetreatUnderground(EnBaguo* this, GlobalContext* globalCtx) { + this->actor.world.rot.y -= 0x1518; + this->actor.shape.rot.y = this->actor.world.rot.y; + if ((globalCtx->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale - 20.0f, + 10, 8.0f, 500, 10, 1); + } + + Math_ApproachF(&this->actor.shape.yOffset, -3000.0f, 100.0f, 500.0f); + Math_ApproachZeroF(&this->actor.shape.shadowScale, 0.3f, 5.0f); + + if (this->actor.shape.yOffset < -2970.0f) { + this->actor.shape.yOffset = -3000.0f; + this->actor.draw = EnBaguo_DrawBody; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BAKUO_APPEAR); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = EnBaguo_UndergroundIdle; + } +} + +void EnBaguo_PostDetonation(EnBaguo* this, GlobalContext* globalCtx) { + if (this->timer == 0) { + Actor_MarkForDeath(&this->actor); + } + + if (this->timer >= 26) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnBaguo_CheckForDetonation(EnBaguo* this, GlobalContext* globalCtx) { + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3f acceleration = { 0.0f, 0.0f, 0.0f }; + s32 i; + + // In order to match, this variable must act as both a boolean to check if + // the Nejiron should forcibly explode and as a loop index. + i = false; + if (this->action != NEJIRON_ACTION_EXPLODING && this->action != NEJIRON_ACTION_RETREATING) { + if (!(this->actor.bgCheckFlags & 1) && this->actor.world.pos.y < (this->actor.home.pos.y - 100.0f)) { + // Force a detonation if we're off the ground and have fallen + // below our home position (e.g., we rolled off a ledge). + i = true; + } + if (this->actor.bgCheckFlags & 0x60 && this->actor.depthInWater >= 40.0f) { + // Force a detonation if we're too far below the water's surface. + i = true; + } + if ((this->collider.base.acFlags & AC_HIT || i)) { + this->collider.base.acFlags &= ~AC_HIT; + if (i || this->actor.colChkInfo.damageEffect == NEJIRON_DMGEFF_KILL) { + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); + this->action = NEJIRON_ACTION_EXPLODING; + this->actor.speedXZ = 0.0f; + this->actor.shape.shadowScale = 0.0f; + + for (i = 0; i < ARRAY_COUNT(this->particles); i++) { + acceleration.x = (Rand_ZeroOne() - 0.5f) * 8.0f; + acceleration.y = -1.0f; + acceleration.z = (Rand_ZeroOne() - 0.5f) * 8.0f; + velocity.x = (Rand_ZeroOne() - 0.5f) * 14.0f; + velocity.y = Rand_ZeroOne() * 30.0f; + velocity.z = (Rand_ZeroOne() - 0.5f) * 14.0f; + EnBaguo_InitializeParticle(this, &this->actor.focus.pos, &velocity, &acceleration, + (Rand_ZeroFloat(1.0f) * 0.01f) + 0.003f, 90); + } + + 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_POP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BAKUO_DEAD); + + this->timer = 30; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_SetScale(&this->actor, 0.0f); + this->collider.elements->dim.scale = 3.0f; + this->collider.elements->info.toucher.damage = 8; + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0xB0); + this->actionFunc = EnBaguo_PostDetonation; + } + } + } +} + +void EnBaguo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBaguo* this = THIS; + + Actor_SetFocus(&this->actor, 30.0f); + EnBaguo_UpdateParticles(this, globalCtx); + EnBaguo_CheckForDetonation(this, globalCtx); + this->actionFunc(this, globalCtx); + + DECR(this->blinkTimer); + DECR(this->timer); + + if (this->action != NEJIRON_ACTION_EXPLODING && this->action != NEJIRON_ACTION_INACTIVE) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->action != NEJIRON_ACTION_EXPLODING) { + this->actor.shape.rot.x = this->actor.world.rot.x; + this->actor.shape.rot.z = this->actor.world.rot.z; + + if (this->blinkTimer == 0) { + this->eyeIndex++; + if (this->eyeIndex >= 3) { + this->eyeIndex = 0; + this->blinkTimer = Rand_ZeroFloat(60.0f) + 20.0f; + } + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); + if (this->action != NEJIRON_ACTION_INACTIVE) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->action != NEJIRON_ACTION_EXPLODING) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void EnBaguo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnBaguo* this = THIS; + + Collider_UpdateSpheres(limbIndex, &this->collider); +} + +void EnBaguo_DrawBody(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sEyeTextures[] = { &gNejironEyeOpenTex, &gNejironEyeHalfTex, &gNejironEyeClosedTex }; + EnBaguo* this = THIS; + Gfx* gfx; + s32 eyeIndex; + void* virtualAddress; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + eyeIndex = this->eyeIndex; + virtualAddress = Lib_SegmentedToVirtual(sEyeTextures[eyeIndex]); + gSPSegment(&gfx[0], 0x08, virtualAddress); + + POLY_OPA_DISP = &gfx[1]; + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, EnBaguo_PostLimbDraw, + &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + EnBaguo_DrawRockParticles(this, globalCtx); +} + +void EnBaguo_InitializeParticle(EnBaguo* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, + s16 timer) { + s16 i; + NejironParticle* particle = this->particles; + + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (!particle->isVisible) { + particle->isVisible = true; + particle->position = *position; + particle->velocity = *velocity; + particle->acceleration = *acceleration; + particle->scale = scale; + particle->timer = timer; + particle->rotation.x = (s16)randPlusMinusPoint5Scaled(30000.0f); + particle->rotation.y = (s16)randPlusMinusPoint5Scaled(30000.0f); + particle->rotation.z = (s16)randPlusMinusPoint5Scaled(30000.0f); + return; + } + } +} + +void EnBaguo_UpdateParticles(EnBaguo* this, GlobalContext* globalCtx) { + s32 i; + NejironParticle* particle = this->particles; + + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (particle->isVisible) { + particle->position.x += particle->velocity.x; + particle->position.y += particle->velocity.y; + particle->position.z += particle->velocity.z; + particle->rotation.x += 0xBB8; + particle->rotation.y += 0xBB8; + particle->rotation.z += 0xBB8; + particle->velocity.x += particle->acceleration.x; + particle->velocity.y += particle->acceleration.y; + particle->velocity.z += particle->acceleration.z; + + if (particle->position.y < (this->actor.world.pos.y - 10.0f)) { + Math_ApproachZeroF(&particle->scale, 0.2f, 0.001f); + if (particle->scale <= 0.0001f) { + particle->timer = 0; + } + } + + if (particle->timer != 0) { + particle->timer--; + } else { + particle->isVisible = false; + } + } + } +} + +void EnBaguo_DrawRockParticles(EnBaguo* this, GlobalContext* globalCtx) { + s16 i; + NejironParticle* particle = this->particles; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (particle->isVisible) { + Matrix_Translate(particle->position.x, particle->position.y, particle->position.z, MTXMODE_NEW); + Matrix_RotateXS(particle->rotation.x, MTXMODE_APPLY); + Matrix_RotateYS(particle->rotation.y, MTXMODE_APPLY); + Matrix_RotateZS(particle->rotation.z, MTXMODE_APPLY); + 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++, gBoulderFragmentsDL); + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.h b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.h index c31dac7a0..133e68b3d 100644 --- a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.h +++ b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.h @@ -2,16 +2,44 @@ #define Z_EN_BAGUO_H #include "global.h" +#include "objects/object_gmo/object_gmo.h" struct EnBaguo; typedef void (*EnBaguoActionFunc)(struct EnBaguo*, GlobalContext*); +/** + * When a Nejiron explodes, rock particles fly out from where it exploded. + * This struct governs how these rock particles behave. + */ +typedef struct NejironParticle { + /* 0x00 */ u8 isVisible; + /* 0x04 */ Vec3f position; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f acceleration; + /* 0x28 */ Vec3s rotation; + /* 0x30 */ f32 scale; + /* 0x34 */ s16 timer; +} NejironParticle; // size = 0x38 + typedef struct EnBaguo { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x68]; - /* 0x01AC */ EnBaguoActionFunc actionFunc; - /* 0x01B0 */ char unk_1B0[0x71C]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[NEJIRON_LIMB_MAX]; + /* 0x19A */ Vec3s morphTable[NEJIRON_LIMB_MAX]; + /* 0x1AC */ EnBaguoActionFunc actionFunc; + /* 0x1B0 */ s16 eyeIndex; + /* 0x1B2 */ s16 blinkTimer; + /* 0x1B4 */ s16 timer; + /* 0x1B6 */ s16 action; + /* 0x1B8 */ s16 zRollDirection; + /* 0x1BC */ f32 maxDistanceFromHome; + /* 0x1C0 */ u8 bouncedFlag; + /* 0x1C4 */ Vec3f currentRotation; + /* 0x1D0 */ Vec3f targetRotation; + /* 0x1DC */ ColliderJntSph collider; + /* 0x1FC */ ColliderJntSphElement colliderElements[1]; + /* 0x23C */ NejironParticle particles[30]; } EnBaguo; // size = 0x8CC extern const ActorInit En_Baguo_InitVars; diff --git a/src/overlays/actors/ovl_En_Baisen/z_en_baisen.c b/src/overlays/actors/ovl_En_Baisen/z_en_baisen.c index d9bb0f9fc..193c899c9 100644 --- a/src/overlays/actors/ovl_En_Baisen/z_en_baisen.c +++ b/src/overlays/actors/ovl_En_Baisen/z_en_baisen.c @@ -5,8 +5,9 @@ */ #include "z_en_baisen.h" +#include "objects/object_bai/object_bai.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBaisen*)thisx) @@ -22,11 +23,6 @@ void func_80BE895C(EnBaisen* this, GlobalContext* globalCtx); void func_80BE8AAC(EnBaisen* this, GlobalContext* globalCtx); void func_80BE89D8(EnBaisen* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_06007908; -extern AnimationHeader D_060011C0; -extern AnimationHeader D_060008B4; -extern AnimationHeader D_06008198; - const ActorInit En_Baisen_InitVars = { ACTOR_EN_BAISEN, ACTORCAT_NPC, @@ -61,27 +57,30 @@ static ColliderCylinderInit sCylinderInit = { static u16 sTextIds[] = { 0x2ABD, 0x2ABB, 0x2AD5, 0x2AD6, 0x2AD7, 0x2AD8, 0x2AC6 }; -static AnimationHeader* D_80BE8E4C[] = { &D_060011C0, &D_060008B4, &D_06008198 }; +static AnimationHeader* D_80BE8E4C[] = { &object_bai_Anim_0011C0, &object_bai_Anim_0008B4, &object_bai_Anim_008198 }; -static u8 animModes[] = { 0, 0 }; +static u8 animModes[] = { ANIMMODE_LOOP, ANIMMODE_LOOP }; void EnBaisen_Init(Actor* thisx, GlobalContext* globalCtx) { EnBaisen* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06007908, &D_060011C0, this->jointTable, this->morphTable, 20); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_bai_Skel_007908, &object_bai_Anim_0011C0, this->jointTable, + this->morphTable, 20); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->paramCopy = this->actor.params; if (this->actor.params == 0) { this->unk290 = true; - if (!(gSaveContext.weekEventReg[63] & 0x80) && ((gSaveContext.day != 3) || !gSaveContext.isNight)) { + if (!(gSaveContext.save.weekEventReg[63] & 0x80) && + ((gSaveContext.save.day != 3) || !gSaveContext.save.isNight)) { Actor_MarkForDeath(&this->actor); } } else { this->collider.dim.radius = 30; this->collider.dim.height = 60; this->collider.dim.yShift = 0; - if ((gSaveContext.weekEventReg[63] & 0x80) || ((gSaveContext.day == 3) && (gSaveContext.isNight))) { + if ((gSaveContext.save.weekEventReg[63] & 0x80) || + ((gSaveContext.save.day == 3) && (gSaveContext.save.isNight))) { Actor_MarkForDeath(&this->actor); } } @@ -124,7 +123,7 @@ void func_80BE871C(EnBaisen* this) { } void func_80BE87B0(EnBaisen* this, GlobalContext* globalCtx) { - Actor* actorIterator = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* actorIterator = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (actorIterator != NULL) { if (actorIterator->id == ACTOR_EN_HEISHI) { @@ -151,15 +150,15 @@ void func_80BE87FC(EnBaisen* this) { } void func_80BE887C(EnBaisen* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80BE895C(this, globalCtx); } else { if (this->paramCopy != 0) { this->textIdIndex = 0; - if (gSaveContext.weekEventReg[60] & 8) { + if (gSaveContext.save.weekEventReg[60] & 8) { this->textIdIndex = 1; } - if (Player_GetMask(globalCtx) == PLAYER_MASK_COUPLES_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_COUPLE) { this->textIdIndex = 6; } if (this->unk2AC == 1) { @@ -176,7 +175,7 @@ void func_80BE895C(EnBaisen* this, GlobalContext* globalCtx) { if (this->unk2A4 != NULL) { this->unk290 = true; this->unk2AC = 1; - func_800B86C8(this->unk2A4, globalCtx, this->unk2A4); + Actor_ChangeFocus(this->unk2A4, globalCtx, this->unk2A4); } this->unk29C = 1; if (this->paramCopy == 0) { @@ -199,8 +198,8 @@ void func_80BE89D8(EnBaisen* this, GlobalContext* globalCtx) { EnBaisen_ChangeAnimation(this, 0); } } - if ((globalCtx->msgCtx.unk11F04 == 0x2AC6) || (globalCtx->msgCtx.unk11F04 == 0x2AC7) || - (globalCtx->msgCtx.unk11F04 == 0x2AC8)) { + if ((globalCtx->msgCtx.currentTextId == 0x2AC6) || (globalCtx->msgCtx.currentTextId == 0x2AC7) || + (globalCtx->msgCtx.currentTextId == 0x2AC8)) { this->skelAnime.playSpeed = 0.0f; this->unk29E = this->actor.yawTowardsPlayer; } @@ -223,7 +222,7 @@ void func_80BE8AAC(EnBaisen* this, GlobalContext* globalCtx) { EnBaisen_ChangeAnimation(this, 0); } } - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); this->textIdIndex++; if (this->textIdIndex < 6) { @@ -233,7 +232,7 @@ void func_80BE8AAC(EnBaisen* this, GlobalContext* globalCtx) { } else { this->unk2A4 = &this->actor; } - func_800B86C8(this->unk2A4, globalCtx, this->unk2A4); + Actor_ChangeFocus(this->unk2A4, globalCtx, this->unk2A4); } else { func_80BE87FC(this); } @@ -249,18 +248,18 @@ void EnBaisen_Update(Actor* thisx, GlobalContext* globalCtx) { this->unusedCounter--; } this->actor.shape.rot.y = this->actor.world.rot.y; - if ((this->paramCopy != 0) && (gSaveContext.day == 3) && gSaveContext.isNight) { + if ((this->paramCopy != 0) && (gSaveContext.save.day == 3) && gSaveContext.save.isNight) { Actor_MarkForDeath(&this->actor); return; } this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); Actor_SetScale(&this->actor, 0.01f); if (this->unk290) { func_80BE871C(this); } - Actor_SetHeight(&this->actor, 60.0f); + Actor_SetFocus(&this->actor, 60.0f); Math_SmoothStepToS(&this->headRotX, this->headRotXTarget, 1, 0xBB8, 0); Math_SmoothStepToS(&this->headRotY, this->headRotYTarget, 1, 0x3E8, 0); Collider_UpdateCylinder(&this->actor, &this->collider); 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 8c284396d..2f57c2804 100644 --- a/src/overlays/actors/ovl_En_Bal/z_en_bal.c +++ b/src/overlays/actors/ovl_En_Bal/z_en_bal.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bal.c + * Overlay: ovl_En_Bal + * Description: Tingle with Balloon + */ + #include "z_en_bal.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBal*)thisx) 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 4fb3df60a..ab76d88c8 100644 --- a/src/overlays/actors/ovl_En_Bat/z_en_bat.c +++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bat.c + * Overlay: ovl_En_Bat + * Description: Bad Bat + */ + #include "z_en_bat.h" -#define FLAGS 0x00005005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000) #define THIS ((EnBat*)thisx) 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 0d12dfc46..f48976cd6 100644 --- a/src/overlays/actors/ovl_En_Bb/z_en_bb.c +++ b/src/overlays/actors/ovl_En_Bb/z_en_bb.c @@ -1,6 +1,13 @@ -#include "z_en_bb.h" +/* + * File: z_en_bb.c + * Overlay: ovl_En_Bb + * Description: Blue Bubble + */ -#define FLAGS 0x00000205 +#include "z_en_bb.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200) #define THIS ((EnBb*)thisx) @@ -9,15 +16,25 @@ void EnBb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBb_Update(Actor* thisx, GlobalContext* globalCtx); void EnBb_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808C23EC(EnBb* this, GlobalContext* globalCtx); -void func_808C25E0(EnBb* this, GlobalContext* globalCtx); -void func_808C28CC(EnBb* this, GlobalContext* globalCtx); -void func_808C2B1C(EnBb* this, GlobalContext* globalCtx); -void func_808C2BD0(EnBb* this, GlobalContext* globalCtx); -void func_808C2CB4(EnBb* this, GlobalContext* globalCtx); -void func_808C2D78(EnBb* this, GlobalContext* globalCtx); +void EnBb_SetupFlyIdle(EnBb* this); +void EnBb_FlyIdle(EnBb* this, GlobalContext* globalCtx); +void EnBb_SetupAttack(EnBb* this); +void EnBb_Attack(EnBb* this, GlobalContext* globalCtx); +void EnBb_Down(EnBb* this, GlobalContext* globalCtx); +void EnBb_Dead(EnBb* this, GlobalContext* globalCtx); +void EnBb_Damage(EnBb* this, GlobalContext* globalCtx); +void EnBb_Frozen(EnBb* this, GlobalContext* globalCtx); +void EnBb_SetupWaitForRevive(EnBb* this); +void EnBb_WaitForRevive(EnBb* this, GlobalContext* globalCtx); +void EnBb_SetupRevive(EnBb* this); +void EnBb_Revive(EnBb* this, GlobalContext* globalCtx); + +typedef enum { + /* -1 */ BB_BODY_PART_DRAW_STATUS_BROKEN = -1, + /* 0 */ BB_BODY_PART_DRAW_STATUS_ALIVE, + /* 1 */ BB_BODY_PART_DRAW_STATUS_DEAD, +} EnBbBodyPartDrawStatus; -#if 0 const ActorInit En_Bb_InitVars = { ACTOR_EN_BB, ACTORCAT_ENEMY, @@ -30,118 +47,667 @@ const ActorInit En_Bb_InitVars = { (ActorFunc)EnBb_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_808C37A0 = { - { COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_HIT3, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }; -// static DamageTable sDamageTable = { -static DamageTable D_808C37CC = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(1, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x0), - /* Ice arrow */ DMG_ENTRY(2, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(1, 0x0), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 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, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), +typedef enum { + /* 0x0 */ EN_BB_DMGEFF_NONE, + /* 0x1 */ EN_BB_DMGEFF_STUN, + /* 0x3 */ EN_BB_DMGEFF_ICE_ARROW = 0x3, + /* 0x4 */ EN_BB_DMGEFF_LIGHT_ARROW, + /* 0x5 */ EN_BB_DMGEFF_ZORA_MAGIC, + /* 0xE */ EN_BB_DMGEFF_HOOKSHOT = 0xE, +} EnBbDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_BB_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, EN_BB_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Ice arrow */ DMG_ENTRY(2, EN_BB_DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, EN_BB_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, EN_BB_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_BB_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, EN_BB_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_BB_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_BB_DMGEFF_NONE), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808C37EC = { 2, 20, 40, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 20, 40, 50 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808C37F4[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 28, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 10, ICHAIN_STOP), }; -#endif +/** + * This maps a given limb based on its limbIndex to its appropriate index + * in the bodyPartsPos/Velocity arrays. An index of -1 indicates that the + * limb is not part of the bodyParts arrays. + */ +static s8 sLimbIndexToBodyPartsIndex[] = { + -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, -1, 2, -1, 3, +}; -extern ColliderSphereInit D_808C37A0; -extern DamageTable D_808C37CC; -extern CollisionCheckInfoInit D_808C37EC; -extern InitChainEntry D_808C37F4[]; +/** + * The last element of the bodyParts arrays is a duplicate of the cranium + * limb, which is then offset by a certain amount. There is no display list + * associated with this, so it is only used for effects. + */ +static Vec3f sDuplicateCraniumBodyPartOffset = { 1000.0f, -700.0f, 0.0f }; -extern UNK_TYPE D_06000184; -extern UNK_TYPE D_06000444; +void EnBb_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &gBubbleSkel, &gBubbleFlyingAnim, this->jointTable, this->morphTable, + BUBBLE_LIMB_MAX); + Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + ActorShape_Init(&this->actor.shape, 1500.0f, ActorShadow_DrawCircle, 35.0f); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Destroy.s") + this->flameScaleY = 0.8f; + this->flameScaleX = 1.0f; + this->actor.world.pos.y += 50.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1E94.s") + if (EN_BB_ATTACK_RANGE(&this->actor) == 0xFF) { + this->attackRange = 200.0f; + } else { + this->attackRange = EN_BB_ATTACK_RANGE(&this->actor) * 4.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1F00.s") + EnBb_SetupFlyIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1F74.s") +void EnBb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C1FF4.s") + Collider_DestroySphere(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C20D4.s") +/** + * Checks to see if the Bubble is touching a wall. If it is, and if the + * Bubble is facing directly "into" the wall, then rotate it away from + * the wall. + */ +void EnBb_CheckForWall(EnBb* this) { + s16 yawDiff; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2238.s") + if (this->actor.bgCheckFlags & 8) { + yawDiff = this->actor.shape.rot.y - this->actor.wallYaw; + if (ABS_ALT(yawDiff) > 0x4000) { + this->actor.shape.rot.y = ((this->actor.wallYaw * 2) - this->actor.shape.rot.y) - 0x8000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2344.s") + this->targetYRotation = this->actor.shape.rot.y; + this->actor.bgCheckFlags &= ~8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C23EC.s") +void EnBb_Freeze(EnBb* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.4f; + this->drawDmgEffFrozenSteamScale = 0.6f; + this->timer = 80; + this->drawDmgEffAlpha = 1.0f; + this->actor.flags &= ~ACTOR_FLAG_200; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C254C.s") +void EnBb_Thaw(EnBb* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), 2, 0.2f, + 0.15f); + this->actor.flags |= ACTOR_FLAG_200; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C25E0.s") +/** + * Updates certain variables that relate to flying like the Bubble's + * Y-position, bob phase, and flame scale. + */ +void EnBb_UpdateStateForFlying(EnBb* this) { + SkelAnime_Update(&this->skelAnime); + if (this->actor.floorHeight > BGCHECK_Y_MIN) { + Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + this->flyHeightMod, 0.5f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C272C.s") + this->actor.world.pos.y += Math_CosS(this->bobPhase); + this->bobPhase += 0x826; + Math_StepToF(&this->flameScaleY, 0.8f, 0.1f); + Math_StepToF(&this->flameScaleX, 1.0f, 0.1f); + EnBb_CheckForWall(this); + Math_StepToF(&this->actor.speedXZ, this->maxSpeed, 0.5f); + Math_ApproachS(&this->actor.shape.rot.y, this->targetYRotation, 5, 0x3E8); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C28CC.s") +void EnBb_SetupFlyIdle(EnBb* this) { + if (this->actionFunc != EnBb_FlyIdle) { + Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2A00.s") + if (this->actionFunc == EnBb_Attack) { + this->attackWaitTimer = 40; + } else { + this->attackWaitTimer = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2B1C.s") + this->timer = (s32)Rand_ZeroFloat(20.0f) + 40; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->flyHeightMod = (Math_CosS(this->bobPhase) * 10.0f) + 30.0f; + this->targetYRotation = Actor_YawToPoint(&this->actor, &this->actor.home.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2B94.s") + if ((this->actor.xzDistToPlayer < (this->attackRange + 120.0f)) || + (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 300.0f)) { + this->targetYRotation += (s16)(Rand_Next() >> 0x11); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2BD0.s") + this->collider.base.atFlags |= AT_ON; + this->maxSpeed = Rand_ZeroFloat(1.5f) + 1.0f; + this->actionFunc = EnBb_FlyIdle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2C38.s") +/** + * Makes the Bubble fly in circles around its home. + */ +void EnBb_FlyIdle(EnBb* this, GlobalContext* globalCtx) { + EnBb_UpdateStateForFlying(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2CB4.s") + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING); + } else if ((Animation_OnFrame(&this->skelAnime, 0.0f)) && (Rand_ZeroOne() < 0.1f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_LAUGH); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2CF0.s") + DECR(this->attackWaitTimer); + this->timer--; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2D78.s") + if ((this->attackWaitTimer == 0) && (this->actor.xzDistToPlayer < this->attackRange) && + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + EnBb_SetupAttack(this); + } else if (this->timer == 0) { + EnBb_SetupFlyIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C2E34.s") +void EnBb_SetupAttack(EnBb* this) { + Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim); + this->timer = (s32)Rand_ZeroFloat(20.0f) + 60; + this->flyHeightMod = (Math_CosS(this->bobPhase) * 10.0f) + 30.0f; + this->targetYRotation = this->actor.yawTowardsPlayer; + this->maxSpeed = Rand_ZeroFloat(1.5f) + 4.0f; + this->actionFunc = EnBb_Attack; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Update.s") +/** + * Makes the Bubble actively move towards the player. + */ +void EnBb_Attack(EnBb* this, GlobalContext* globalCtx) { + this->targetYRotation = this->actor.yawTowardsPlayer; + EnBb_UpdateStateForFlying(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C32EC.s") + if ((Animation_OnFrame(&this->skelAnime, 0.0f)) || (Animation_OnFrame(&this->skelAnime, 5.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_MOUTH); + } else if ((Animation_OnFrame(&this->skelAnime, 2.0f)) || (Animation_OnFrame(&this->skelAnime, 7.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING); + } else if ((Animation_OnFrame(&this->skelAnime, 0.0f)) && (Rand_ZeroOne() < 0.1f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_LAUGH); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/func_808C3324.s") + this->timer--; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bb/EnBb_Draw.s") + if (((this->attackRange + 120.0f) < this->actor.xzDistToPlayer) || (this->timer == 0) || + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || + (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 400.0f)) { + EnBb_SetupFlyIdle(this); + } +} + +void EnBb_SetupDown(EnBb* this) { + Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim); + this->collider.base.atFlags |= AT_ON; + this->timer = 140; + this->collider.base.acFlags |= AC_ON; + this->actor.speedXZ = 2.0f; + this->flameScaleY = 0.0f; + this->flameScaleX = 0.0f; + this->actor.gravity = -2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DOWN); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnBb_Down; +} + +/** + * Makes the Bubble hop along the ground. + */ +void EnBb_Down(EnBb* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + EnBb_CheckForWall(this); + + if (this->actor.bgCheckFlags & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + if (this->timer == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_UP); + EnBb_SetupFlyIdle(this); + return; + } + + if (this->actor.velocity.y < -14.0f) { + this->actor.velocity.y *= -0.7f; + } else { + this->actor.velocity.y = 10.0f; + } + + this->actor.bgCheckFlags &= ~1; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); + Math_ScaledStepToS(&this->actor.shape.rot.y, BINANG_ADD(this->actor.yawTowardsPlayer, 0x8000), 0xBB8); + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING); + } + + if (this->timer > 0) { + this->timer--; + } +} + +void EnBb_SetupDead(EnBb* this, GlobalContext* globalCtx) { + Vec3f* bodyPartVelocity; + Vec3f posDiff; + f32 magnitude; + s32 i; + + func_800BE568(&this->actor, &this->collider); + this->timer = 15; + this->actor.shape.rot.x += 0x4E20; + this->actor.speedXZ = 0.0f; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_BUBLE_DEAD); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x70); + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->bodyPartDrawStatus = BB_BODY_PART_DRAW_STATUS_DEAD; + this->actor.gravity = -1.5f; + + bodyPartVelocity = &this->bodyPartsVelocity[0]; + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++, bodyPartVelocity++) { + Math_Vec3f_Diff(&this->bodyPartsPos[i], &this->actor.world.pos, &posDiff); + magnitude = Math3D_Vec3fMagnitude(&posDiff); + if (magnitude > 1.0f) { + magnitude = 2.5f / magnitude; + } + + bodyPartVelocity->x = posDiff.x * magnitude; + bodyPartVelocity->z = posDiff.z * magnitude; + bodyPartVelocity->y = Rand_ZeroFloat(3.5f) + 10.0f; + } + + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = EnBb_Dead; +} + +void EnBb_Dead(EnBb* this, GlobalContext* globalCtx) { + s32 i; + + this->timer--; + Math_SmoothStepToS(&this->actor.world.rot.z, 0x4000, 4, 0x1000, 0x400); + + if (this->timer == 0) { + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) { + func_800B3030(globalCtx, &this->bodyPartsPos[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 2); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->bodyPartsPos[i], 11, NA_SE_EN_EXTINCT); + } + + EnBb_SetupWaitForRevive(this); + } else { + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) { + Math_Vec3f_Sum(&this->bodyPartsPos[i], &this->bodyPartsVelocity[i], &this->bodyPartsPos[i]); + this->bodyPartsVelocity[i].y += this->actor.gravity; + } + } +} + +void EnBb_SetupDamage(EnBb* this) { + this->collider.base.acFlags &= ~AC_ON; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DAMAGE); + func_800BE568(&this->actor, &this->collider); + + if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_ZORA_MAGIC) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffScale = 0.4f; + } else if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_STUN) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 20); + this->actor.speedXZ = 0.0f; + } else if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_HOOKSHOT) { + this->actor.speedXZ = 0.0f; + } else { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->actor.speedXZ = 7.0f; + } + + this->actor.gravity = -1.0f; + this->actionFunc = EnBb_Damage; +} + +void EnBb_Damage(EnBb* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); + if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ < 0.1f)) { + EnBb_SetupDown(this); + } +} + +void EnBb_SetupFrozen(EnBb* this) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = 0.0f; + } + + this->actor.gravity = -2.0f; + this->actionFunc = EnBb_Frozen; +} + +void EnBb_Frozen(EnBb* this, GlobalContext* globalCtx) { + DECR(this->timer); + + if (this->timer == 0) { + EnBb_Thaw(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + EnBb_SetupDead(this, globalCtx); + } else { + EnBb_SetupDown(this); + } + } +} + +void EnBb_SetupWaitForRevive(EnBb* this) { + this->actor.draw = NULL; + this->bodyPartDrawStatus = BB_BODY_PART_DRAW_STATUS_ALIVE; + this->drawDmgEffAlpha = 0.0f; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.shape.rot.x = 0; + this->actor.world.pos.y += 50.0f; + this->timer = 200; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + this->actionFunc = EnBb_WaitForRevive; +} + +void EnBb_WaitForRevive(EnBb* this, GlobalContext* globalCtx) { + this->timer--; + if (this->timer == 0) { + EnBb_SetupRevive(this); + } +} + +void EnBb_SetupRevive(EnBb* this) { + Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim); + this->actor.draw = EnBb_Draw; + this->actor.scale.x = 0.0f; + this->actor.scale.y = 0.015f; + this->actor.scale.z = 0.0f; + this->flameScaleX = 1.0f; + this->flameScaleY = 0.8f; + this->actor.colChkInfo.health = sColChkInfoInit.health; + this->actionFunc = EnBb_Revive; +} + +void EnBb_Revive(EnBb* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y += 0x1F00; + + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f)) { + this->actor.flags &= ~ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_1; + this->collider.base.acFlags |= AC_ON; + this->collider.base.atFlags |= AT_ON; + this->actor.world.rot.y = this->actor.shape.rot.y; + EnBb_SetupFlyIdle(this); + } + + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = ((0.01f - this->actor.scale.x) * 0.5f) + 0.01f; +} + +void EnBb_UpdateDamage(EnBb* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + this->collider.base.atFlags &= ~AT_ON; + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + Actor_SetDropFlag(&this->actor, &this->collider.info); + this->flameScaleY = 0.0f; + this->flameScaleX = 0.0f; + EnBb_Thaw(this, globalCtx); + + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_ICE_ARROW) { + EnBb_Freeze(this); + if (this->actor.colChkInfo.health == 0) { + this->timer = 3; + this->collider.base.acFlags &= ~AC_ON; + } + + EnBb_SetupFrozen(this); + } else if (this->actor.colChkInfo.health == 0) { + EnBb_SetupDead(this, globalCtx); + } else { + EnBb_SetupDamage(this); + } + + if (this->actor.colChkInfo.damageEffect == EN_BB_DMGEFF_LIGHT_ARROW) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.4f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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_SMALL_LIGHT_RAYS); + } + } + } else { + if (this->collider.base.atFlags & AT_BOUNCED) { + this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + if (this->actionFunc != EnBb_Down) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000; + this->actor.shape.rot.y = this->actor.world.rot.y; + EnBb_SetupDown(this); + } + } else if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000; + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_BITE); + + if (this->flameScaleX > 0.0f) { + gSaveContext.jinxTimer = 1200; + } + + if (this->actionFunc == EnBb_Attack) { + EnBb_SetupFlyIdle(this); + } + } + } +} + +void EnBb_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBb* this = THIS; + + EnBb_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + if ((this->actionFunc != EnBb_Dead) && (this->actionFunc != EnBb_WaitForRevive)) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 25.0f, 40.0f, 7); + + this->collider.dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.dim.worldSphere.center.y = this->actor.world.pos.y + 15.0f; + this->collider.dim.worldSphere.center.z = this->actor.world.pos.z; + this->collider.dim.worldSphere.radius = this->flameScaleX * 30.0f; + this->collider.dim.worldSphere.radius = CLAMP_MIN(this->collider.dim.worldSphere.radius, 20); + + Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.dim.worldSphere.center); + + if (this->collider.base.atFlags & AT_ON) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.ocFlags1 & OC1_ON) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.2f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.4f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.4f, 0.01f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + } +} + +s32 EnBb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnBb* this = THIS; + + if (this->bodyPartDrawStatus == BB_BODY_PART_DRAW_STATUS_BROKEN) { + this->limbDList = *dList; + *dList = NULL; + } + + return false; +} + +void EnBb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnBb* this = THIS; + MtxF* currentMatrixState; + + if (this->bodyPartDrawStatus == BB_BODY_PART_DRAW_STATUS_ALIVE) { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + if (sLimbIndexToBodyPartsIndex[limbIndex] == 0) { + Matrix_MultVecX(1000.0f, &this->bodyPartsPos[0]); + } else if (sLimbIndexToBodyPartsIndex[limbIndex] == 3) { + Matrix_MultVecX(-1000.0f, &this->bodyPartsPos[3]); + Matrix_MultVec3f(&sDuplicateCraniumBodyPartOffset, &this->bodyPartsPos[4]); + } else { + Matrix_MultZero(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]); + } + } + } else if (this->bodyPartDrawStatus > BB_BODY_PART_DRAW_STATUS_ALIVE) { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + Matrix_MultZero(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]); + } + + if (limbIndex == BUBBLE_LIMB_CRANIUM) { + this->bodyPartDrawStatus = BB_BODY_PART_DRAW_STATUS_BROKEN; + } + } else { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + currentMatrixState = Matrix_GetCurrent(); + currentMatrixState->mf[3][0] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].x; + currentMatrixState->mf[3][1] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].y; + currentMatrixState->mf[3][2] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].z; + Matrix_RotateZS(thisx->world.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++, this->limbDList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} + +void EnBb_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBb* this = THIS; + MtxF* currentMatrixState; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + POLY_OPA_DISP = &gfx[1]; + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnBb_OverrideLimbDraw, + EnBb_PostLimbDraw, &this->actor); + + if (this->flameScaleX > 0.0f) { + currentMatrixState = Matrix_GetCurrent(); + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_RotateYS( + ((Camera_GetCamDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) - this->actor.shape.rot.y) + 0x8000), + MTXMODE_APPLY); + Matrix_Scale(this->flameScaleX, this->flameScaleY, 1.0f, MTXMODE_APPLY); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 255, 0); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + (globalCtx->gameplayFrames * -20) & 0x1FF, 32, 128)); + currentMatrixState->mf[3][1] -= 47.0f * this->flameScaleY; + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bb/z_en_bb.h b/src/overlays/actors/ovl_En_Bb/z_en_bb.h index 513020bd2..7d5da25b3 100644 --- a/src/overlays/actors/ovl_En_Bb/z_en_bb.h +++ b/src/overlays/actors/ovl_En_Bb/z_en_bb.h @@ -2,16 +2,39 @@ #define Z_EN_BB_H #include "global.h" +#include "objects/object_bb/object_bb.h" + +#define EN_BB_ATTACK_RANGE(thisx) (((thisx)->params >> 8) & 0xFF) struct EnBb; typedef void (*EnBbActionFunc)(struct EnBb*, GlobalContext*); typedef struct EnBb { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; - /* 0x0248 */ EnBbActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x100]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[BUBBLE_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[BUBBLE_LIMB_MAX]; + /* 0x248 */ EnBbActionFunc actionFunc; + /* 0x24C */ s8 bodyPartDrawStatus; + /* 0x24D */ u8 drawDmgEffType; + /* 0x24E */ UNK_TYPE1 unk_24E[0x2]; + /* 0x250 */ s16 timer; + /* 0x252 */ s16 attackWaitTimer; // Cannot start attacking the player if this is non-zero + /* 0x254 */ s16 targetYRotation; + /* 0x256 */ s16 bobPhase; + /* 0x258 */ f32 maxSpeed; + /* 0x25C */ f32 flyHeightMod; + /* 0x260 */ f32 attackRange; + /* 0x264 */ f32 flameScaleX; + /* 0x268 */ f32 flameScaleY; + /* 0x26C */ f32 drawDmgEffAlpha; + /* 0x270 */ f32 drawDmgEffScale; + /* 0x274 */ f32 drawDmgEffFrozenSteamScale; + /* 0x278 */ Vec3f bodyPartsPos[5]; + /* 0x2B4 */ Vec3f bodyPartsVelocity[5]; + /* 0x2F0 */ Gfx* limbDList; + /* 0x2F4 */ ColliderSphere collider; } EnBb; // size = 0x34C extern const ActorInit En_Bb_InitVars; 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 9057a9672..f2c70dac8 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,6 +1,21 @@ -#include "z_en_bba_01.h" +/* + * File: z_en_bba_01.c + * Overlay: ovl_En_Bba_01 + * Description: Unused Bomb Shop Lady NPC + * + * Note: This actor was probably written with OOT's object_bba's skeleton in mind, and so this actor is very bugged. + * + * The main offender is that gBbaSkel has 18 limbs, while the system used (EnHy) expects 16 (see @bug in FinishInit + * below). + * + * The draw functions also use different limbs than expected, which results in, for example, EnBba01's right arm and bag + * following the player instead of her head and torso. + */ -#define FLAGS 0x00000019 +#include "z_en_bba_01.h" +#include "objects/object_bba/object_bba.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBba01*)thisx) @@ -9,12 +24,10 @@ void EnBba01_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBba01_Update(Actor* thisx, GlobalContext* globalCtx); void EnBba01_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809CC2F0(EnBba01* this, GlobalContext* globalCtx); -void func_809CC370(EnBba01* this, GlobalContext* globalCtx); -void func_809CC3A8(EnBba01* this, GlobalContext* globalCtx); -void func_809CC3CC(EnBba01* this, GlobalContext* globalCtx); +void EnBba01_Walk(EnHy* this, GlobalContext* globalCtx); +void EnBba01_FaceFoward(EnHy* this, GlobalContext* globalCtx); +void EnBba01_Talk(EnHy* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Bba_01_InitVars = { ACTOR_EN_BBA_01, ACTORCAT_NPC, @@ -27,84 +40,301 @@ const ActorInit En_Bba_01_InitVars = { (ActorFunc)EnBba01_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809CCC80 = { - { COLTYPE_HIT0, 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 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 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 64, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_809CCCAC = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_809CCCB8 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(0, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(0, 0x0), - /* Zora boomerang */ DMG_ENTRY(0, 0x0), - /* Normal arrow */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0x0), - /* Goron punch */ DMG_ENTRY(0, 0x0), - /* Sword */ DMG_ENTRY(0, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(0, 0x0), - /* Ice arrow */ DMG_ENTRY(0, 0x0), - /* Light arrow */ DMG_ENTRY(0, 0x0), - /* Goron spikes */ DMG_ENTRY(0, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x0), - /* Deku bubble */ DMG_ENTRY(0, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(0, 0x0), - /* Zora punch */ DMG_ENTRY(0, 0x0), - /* Spin attack */ DMG_ENTRY(0, 0x0), - /* 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(0, 0x0), +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, 0), + /* Deku Stick */ DMG_ENTRY(0, 0), + /* Horse trample */ DMG_ENTRY(0, 0), + /* Explosives */ DMG_ENTRY(0, 0), + /* Zora boomerang */ DMG_ENTRY(0, 0), + /* Normal arrow */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0), + /* Hookshot */ DMG_ENTRY(0, 0), + /* Goron punch */ DMG_ENTRY(0, 0), + /* Sword */ DMG_ENTRY(0, 0), + /* Goron pound */ DMG_ENTRY(0, 0), + /* Fire arrow */ DMG_ENTRY(0, 0), + /* Ice arrow */ DMG_ENTRY(0, 0), + /* Light arrow */ DMG_ENTRY(0, 0), + /* Goron spikes */ DMG_ENTRY(0, 0), + /* Deku spin */ DMG_ENTRY(0, 0), + /* Deku bubble */ DMG_ENTRY(0, 0), + /* Deku launch */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0), + /* Zora barrier */ DMG_ENTRY(0, 0), + /* Normal shield */ DMG_ENTRY(0, 0), + /* Light ray */ DMG_ENTRY(0, 0), + /* Thrown object */ DMG_ENTRY(0, 0), + /* Zora punch */ DMG_ENTRY(0, 0), + /* Spin attack */ DMG_ENTRY(0, 0), + /* Sword beam */ DMG_ENTRY(0, 0), + /* Normal Roll */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0), + /* Unblockable */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0), + /* Powder Keg */ DMG_ENTRY(0, 0), }; -#endif +static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, +}; -extern ColliderCylinderInit D_809CCC80; -extern CollisionCheckInfoInit2 D_809CCCAC; -extern DamageTable D_809CCCB8; +void EnBba01_UpdateModel(EnBba01* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f point; -extern UNK_TYPE D_06005EF0; + EnHy_UpdateSkelAnime(&this->enHy, globalCtx); + if (SubS_AngleDiffLessEqual(this->enHy.actor.shape.rot.y, 0x36B0, this->enHy.actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->enHy.actor.focus.pos, &this->enHy.actor.shape.rot, &this->enHy.turnTarget, + &this->enHy.headRot, &this->enHy.torsoRot, &sTurnOptions); + } else { + Math_SmoothStepToS(&this->enHy.turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.torsoRot.y, 0, 4, 0x3E8, 1); + } + SubS_FillLimbRotTables(globalCtx, this->enHy.limbRotTableY, this->enHy.limbRotTableZ, + ARRAY_COUNT(this->enHy.limbRotTableY)); + EnHy_UpdateCollider(&this->enHy, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC060.s") +s32 EnBba01_TestIsTalking(EnBba01* this, GlobalContext* globalCtx) { + s32 isTalking = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC1D4.s") + if (Actor_ProcessTalkRequest(&this->enHy.actor, &globalCtx->state)) { + isTalking = true; + this->enHy.textId = 0x10B9; // Invalid textId, produces empty textbox + this->enHy.tmpTurnTarget = this->enHy.turnTarget; + this->enHy.tmpHeadRot = this->enHy.headRot; + this->enHy.tmpTorsoRot = this->enHy.torsoRot; + this->enHy.tmpActionFunc = this->enHy.actionFunc; + this->enHy.actionFunc = EnBba01_Talk; + } + return isTalking; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC270.s") +s32 func_809CC270(EnBba01* this, GlobalContext* globalCtx) { + s16 x; + s16 y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC2F0.s") + Actor_GetScreenPos(globalCtx, &this->enHy.actor, &x, &y); + //! @bug: Both x and y conditionals are always true, || should be an && + if (!this->enHy.waitingOnInit && ((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT))) { + func_800B85E0(&this->enHy.actor, globalCtx, 30.0f, EXCH_ITEM_2E); + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC370.s") +void EnBba01_FinishInit(EnHy* this, GlobalContext* globalCtx) { + //! @bug: gBbaSkel does not match EnHy's skeleton assumptions. + //! Since gBbaSkel has more limbs than expected, joint and morph tables will overflow + if (EnHy_Init(this, globalCtx, &gBbaSkel, ENHY_ANIMATION_BBA_6)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.draw = EnBba01_Draw; + this->waitingOnInit = false; + if (ENBBA01_GET_PATH(&this->actor) == ENBBA01_NO_PATH) { + this->actionFunc = EnBba01_FaceFoward; + } else { + this->actionFunc = EnBba01_Walk; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC3A8.s") +void EnBba01_Walk(EnHy* this, GlobalContext* globalCtx) { + if (EnHy_MoveForwards(this, 1.0f)) { + this->curPoint = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC3CC.s") +void EnBba01_FaceFoward(EnHy* this, GlobalContext* globalCtx) { + this->actor.shape.rot = this->actor.world.rot; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/EnBba01_Init.s") +void EnBba01_Talk(EnHy* this, GlobalContext* globalCtx) { + s16 yaw; + u8 talkState; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/EnBba01_Destroy.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xFA0, 1); + talkState = Message_GetState(&globalCtx->msgCtx); + this->inMsgState3 = (talkState == 3) ? true : false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/EnBba01_Update.s") + switch (talkState) { + case 0: + yaw = ABS_ALT(this->actor.shape.rot.y - this->actor.yawTowardsPlayer); + if (yaw < 0x64) { + Message_StartTextbox(globalCtx, this->textId, NULL); + } + break; + case 2: + this->actor.textId = 0; + this->turnTarget = this->tmpTurnTarget; + this->headRot = this->tmpHeadRot; + this->torsoRot = this->tmpTorsoRot; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = this->tmpActionFunc; + this->tmpActionFunc = NULL; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC6F0.s") +void EnBba01_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBba01* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CC984.s") + this->enHy.animObjIndex = SubS_GetObjectIndex(OBJECT_BBA, globalCtx); + this->enHy.headObjIndex = SubS_GetObjectIndex(OBJECT_BBA, globalCtx); + this->enHy.skelUpperObjIndex = SubS_GetObjectIndex(OBJECT_BBA, globalCtx); + this->enHy.skelLowerObjIndex = SubS_GetObjectIndex(OBJECT_BBA, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/func_809CCA5C.s") + if ((this->enHy.animObjIndex < 0) || (this->enHy.headObjIndex < 0) || (this->enHy.skelUpperObjIndex < 0) || + (this->enHy.skelLowerObjIndex < 0)) { + Actor_MarkForDeath(&this->enHy.actor); + } + this->enHy.actor.draw = NULL; + Collider_InitCylinder(globalCtx, &this->enHy.collider); + Collider_SetCylinder(globalCtx, &this->enHy.collider, &this->enHy.actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->enHy.actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->enHy.actor.flags &= ~ACTOR_FLAG_1; + this->enHy.path = SubS_GetPathByIndex(globalCtx, ENBBA01_GET_PATH(&this->enHy.actor), ENBBA01_NO_PATH); + this->enHy.waitingOnInit = true; + Actor_SetScale(&this->enHy.actor, 0.01f); + this->enHy.actionFunc = EnBba01_FinishInit; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bba_01/EnBba01_Draw.s") +void EnBba01_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBba01* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->enHy.collider); +} + +void EnBba01_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBba01* this = THIS; + + EnBba01_TestIsTalking(this, globalCtx); + this->enHy.actionFunc(&this->enHy, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->enHy.actor, 0.0f, 0.0f, 0.0f, 4); + EnBba01_UpdateModel(this, globalCtx); + func_809CC270(this, globalCtx); +} + +s32 EnBba01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBba01* this = THIS; + s8 bodyPart; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + + bodyPart = gEnHyBodyParts[limbIndex]; + if (bodyPart >= 0) { + Matrix_MultVec3f(&zeroVec, &this->enHy.bodyPartsPos[bodyPart]); + } + + if (limbIndex == BBA_LIMB_RIGHT_LOWER_ARM_ROOT) { + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->enHy.headObjIndex].segment); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.headObjIndex].segment); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.skelLowerObjIndex].segment); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + if (limbIndex == BBA_LIMB_RIGHT_LOWER_ARM_ROOT) { + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->enHy.headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->enHy.headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == BBA_LIMB_BAG) { + Matrix_RotateXS(-this->enHy.torsoRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->enHy.torsoRot.x, MTXMODE_APPLY); + } + + if ((limbIndex == BBA_LIMB_RIGHT_LOWER_ARM_ROOT) && this->enHy.inMsgState3 && + ((globalCtx->state.frames % 2) == 0)) { + Matrix_Translate(40.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if ((limbIndex == BBA_LIMB_BAG) || (limbIndex == BBA_LIMB_TORSO) || (limbIndex == BBA_LIMB_LEFT_FOREARM)) { + rot->y += (s16)(Math_SinS(this->enHy.limbRotTableY[limbIndex]) * 200.0f); + rot->z += (s16)(Math_CosS(this->enHy.limbRotTableZ[limbIndex]) * 200.0f); + } + + return false; +} + +void EnBba01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnBba01* this = THIS; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + + if (limbIndex == BBA_LIMB_HEAD) { + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->enHy.skelUpperObjIndex].segment); + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.skelUpperObjIndex].segment); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == BBA_LIMB_RIGHT_LOWER_ARM_ROOT) { + Matrix_MultVec3f(&zeroVec, &this->enHy.actor.focus.pos); + } +} + +void EnBba01_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +} + +void EnBba01_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnBba01* this = THIS; + s32 i; + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, SUBS_SHADOW_TEX_SIZE); + u8* shadowTexIter; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, 255, 255, 255, 0)); + gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 55, 55, 255, 0)); + gDPPipeSync(POLY_OPA_DISP++); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->enHy.skelAnime.skeleton, this->enHy.skelAnime.jointTable, + this->enHy.skelAnime.dListCount, EnBba01_OverrideLimbDraw, EnBba01_PostLimbDraw, + EnBba01_TransformLimbDraw, &this->enHy.actor); + Matrix_RotateXS(0, MTXMODE_NEW); + + for (i = 0, shadowTexIter = shadowTex; i < SUBS_SHADOW_TEX_SIZE; i++) { + *shadowTexIter++ = 0; + } + for (i = 0; i < 5; i++) { + SubS_GenShadowTex(this->enHy.bodyPartsPos, &this->enHy.actor.world.pos, shadowTex, i / 5.0f, + ARRAY_COUNT(this->enHy.bodyPartsPos), gEnHyShadowSizes, gEnHyParentBodyParts); + } + SubS_DrawShadowTex(&this->enHy.actor, &globalCtx->state, shadowTex); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..b670dea01 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 @@ -1,16 +1,18 @@ #ifndef Z_EN_BBA_01_H #define Z_EN_BBA_01_H -#include "global.h" +#include "z_en_hy_code.h" struct EnBba01; typedef void (*EnBba01ActionFunc)(struct EnBba01*, GlobalContext*); +#define ENBBA01_GET_PATH(thisx) (((thisx)->params & 0x7E00) >> 9) +#define ENBBA01_NO_PATH 0x3F + typedef struct EnBba01 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnBba01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x000 */ EnHy enHy; + /* 0x3EC */ UNK_TYPE1 unk_3EC[0x230]; } 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 df6ef4f5c..9e55e8508 100644 --- a/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c +++ b/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c @@ -1,6 +1,13 @@ -#include "z_en_bbfall.h" +/* + * File: z_en_bbfall.c + * Overlay: ovl_En_Bbfall + * Description: Red Bubble + */ -#define FLAGS 0x00000215 +#include "z_en_bbfall.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_200) #define THIS ((EnBbfall*)thisx) @@ -9,16 +16,25 @@ void EnBbfall_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBbfall_Update(Actor* thisx, GlobalContext* globalCtx); void EnBbfall_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808BF734(EnBbfall* this, GlobalContext* globalCtx); -void func_808BF830(EnBbfall* this, GlobalContext* globalCtx); -void func_808BF8DC(EnBbfall* this, GlobalContext* globalCtx); -void func_808BFA3C(EnBbfall* this, GlobalContext* globalCtx); -void func_808BFB4C(EnBbfall* this, GlobalContext* globalCtx); -void func_808BFE58(EnBbfall* this, GlobalContext* globalCtx); -void func_808C00A0(EnBbfall* this, GlobalContext* globalCtx); -void func_808C0178(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_SetupWaitForPlayer(EnBbfall* this); +void EnBbfall_WaitForPlayer(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_SetupEmerge(EnBbfall* this); +void EnBbfall_Emerge(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_SetupFly(EnBbfall* this); +void EnBbfall_Fly(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_SetupSinkIntoLava(EnBbfall* this); +void EnBbfall_SinkIntoLava(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_Down(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_Dead(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_Damage(EnBbfall* this, GlobalContext* globalCtx); +void EnBbfall_Frozen(EnBbfall* this, GlobalContext* globalCtx); + +typedef enum { + /* -1 */ BBFALL_BODY_PART_DRAW_STATUS_BROKEN = -1, + /* 0 */ BBFALL_BODY_PART_DRAW_STATUS_ALIVE, + /* 1 */ BBFALL_BODY_PART_DRAW_STATUS_DEAD, +} EnBbfallBodyPartDrawStatus; -#if 0 const ActorInit En_Bbfall_InitVars = { ACTOR_EN_BBFALL, ACTORCAT_ENEMY, @@ -31,140 +47,720 @@ const ActorInit En_Bbfall_InitVars = { (ActorFunc)EnBbfall_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[3] = { -static ColliderJntSphElementInit D_808C0D30[3] = { +static ColliderJntSphElementInit sJntSphElementsInit[3] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x01, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x01, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x01, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x01, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808C0D9C = { - { COLTYPE_HIT3, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 3, D_808C0D30, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// static DamageTable sDamageTable = { -static DamageTable D_808C0DAC = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0x0), - /* Fire arrow */ DMG_ENTRY(1, 0x0), - /* Ice arrow */ DMG_ENTRY(2, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(1, 0x0), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 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, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), +typedef enum { + /* 0x0 */ EN_BBFALL_DMGEFF_NONE, + /* 0x1 */ EN_BBFALL_DMGEFF_STUN, + /* 0x3 */ EN_BBFALL_DMGEFF_ICE_ARROW = 0x3, + /* 0x4 */ EN_BBFALL_DMGEFF_LIGHT_ARROW, + /* 0x5 */ EN_BBFALL_DMGEFF_ZORA_MAGIC, + /* 0xE */ EN_BBFALL_DMGEFF_HOOKSHOT = 0xE, +} EnBbfallDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Ice arrow */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, EN_BBFALL_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_BBFALL_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_BBFALL_DMGEFF_NONE), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808C0DCC = { 2, 20, 40, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 20, 40, 50 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808C0DD4[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 36, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 10, ICHAIN_STOP), }; -#endif +/** + * This maps a given limb based on its limbIndex to its appropriate index + * in the bodyPartsPos/Velocity arrays. An index of -1 indicates that the + * limb is not part of the bodyParts arrays. + */ +static s8 sLimbIndexToBodyPartsIndex[] = { + -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, -1, 2, -1, 3, +}; -extern ColliderJntSphElementInit D_808C0D30[3]; -extern ColliderJntSphInit D_808C0D9C; -extern DamageTable D_808C0DAC; -extern CollisionCheckInfoInit D_808C0DCC; -extern InitChainEntry D_808C0DD4[]; +/** + * The last element of the bodyParts arrays is a duplicate of the cranium + * limb, which is then offset by a certain amount. There is no display list + * associated with this, so it is only used for effects. + */ +static Vec3f sDuplicateCraniumBodyPartOffset = { 1000.0f, -700.0f, 0.0f }; -extern UNK_TYPE D_06000184; -extern UNK_TYPE D_06000444; +void EnBbfall_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBbfall* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &gBubbleSkel, &gBubbleFlyingAnim, this->jointTable, this->morphTable, + BUBBLE_LIMB_MAX); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + ActorShape_Init(&this->actor.shape, 1500.0f, ActorShadow_DrawCircle, 35.0f); + this->timer = 0; + EnBbfall_SetupWaitForPlayer(this); + Actor_SetFocus(&this->actor, 0.0f); + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + this->collider.elements[i].dim.worldSphere.radius = this->collider.elements[i].dim.modelSphere.radius; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Destroy.s") +void EnBbfall_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBbfall* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF344.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF3B8.s") +void EnBbfall_Freeze(EnBbfall* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.4f; + this->drawDmgEffFrozenSteamScale = 0.6f; + this->timer = 80; + this->drawDmgEffAlpha = 1.0f; + this->actor.flags &= ~ACTOR_FLAG_200; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF438.s") +void EnBbfall_Thaw(EnBbfall* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), 2, 0.2f, + 0.15f); + this->actor.flags |= ACTOR_FLAG_200; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF4B4.s") +/** + * Returns true if the Bubble is touching a floor that it should "sink into" (i.e., if it's touching lava). + */ +s32 EnBbfall_IsTouchingLava(EnBbfall* this, GlobalContext* globalCtx) { + if (!SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId)) { + u32 floorType = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF514.s") + if ((floorType == 2) || (floorType == 3) || (floorType == 9)) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF578.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF5AC.s") +void EnBbfall_PlaySfx(EnBbfall* this) { + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_MOUTH); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF5E0.s") + func_800B9010(&this->actor, NA_SE_EN_BUBLEFALL_FIRE - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF734.s") +/** + * Checks to see if the Bubble is touching a wall. If it is, and if the + * Bubble is facing directly "into" the wall, then rotate it away from + * the wall. + */ +void EnBbfall_CheckForWall(EnBbfall* this) { + s16 yawDiff; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF7A0.s") + if (this->actor.bgCheckFlags & 8) { + yawDiff = this->actor.shape.rot.y - this->actor.wallYaw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF830.s") + if (ABS_ALT(yawDiff) > 0x4000) { + this->actor.shape.rot.y = ((this->actor.wallYaw * 2) - this->actor.shape.rot.y) - 0x8000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF894.s") + this->actor.bgCheckFlags &= ~8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BF8DC.s") +void EnBbfall_EnableColliders(EnBbfall* this) { + this->collider.elements[0].info.toucher.effect = ELEMTYPE_UNK1; // Fire + this->collider.elements[1].info.toucherFlags |= TOUCH_ON; + this->collider.elements[2].info.toucherFlags |= TOUCH_ON; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFA18.s") +void EnBbfall_DisableColliders(EnBbfall* this) { + this->collider.elements[0].info.toucher.effect = ELEMTYPE_UNK0; // Nothing + this->collider.elements[1].info.toucherFlags &= ~TOUCH_ON; + this->collider.elements[2].info.toucherFlags &= ~TOUCH_ON; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFA3C.s") +void EnBbfall_SetupWaitForPlayer(EnBbfall* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFAB4.s") + Animation_PlayLoop(&this->skelAnime, &gBubbleAttackAnim); + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; + this->flameScaleY = 0.8f; + this->flameScaleX = 1.0f; + this->flameOpacity = 255; + this->actor.colChkInfo.health = sColChkInfoInit.health; + this->actor.colorFilterTimer = 0; + this->isBgCheckCollisionEnabled = false; + this->actor.speedXZ = 0.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.world.pos.y -= 90.0f; + for (i = 0; i < ARRAY_COUNT(this->flamePos); i++) { + Math_Vec3f_Copy(&this->flamePos[i], &this->actor.world.pos); + this->flamePos[i].y -= 47.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFB4C.s") + this->actor.bgCheckFlags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = EnBbfall_WaitForPlayer; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFCCC.s") +void EnBbfall_WaitForPlayer(EnBbfall* this, GlobalContext* globalCtx) { + if (this->timer != 0) { + this->timer--; + } else if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && (this->actor.xyzDistToPlayerSq <= SQ(250.0f))) { + EnBbfall_SetupEmerge(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFE58.s") +void EnBbfall_SetupEmerge(EnBbfall* this) { + this->actor.gravity = -1.0f; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->collider.base.atFlags |= AT_ON; + this->collider.base.acFlags |= AC_ON; + this->collider.base.ocFlags1 |= OC1_ON; + this->actor.velocity.y = 17.0f; + EnBbfall_EnableColliders(this); + this->actor.flags |= ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLEFALL_APPEAR); + this->actionFunc = EnBbfall_Emerge; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808BFF8C.s") +void EnBbfall_Emerge(EnBbfall* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->actor.home.pos.y < this->actor.world.pos.y) { + EnBbfall_SetupFly(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C00A0.s") + EnBbfall_PlaySfx(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C013C.s") +void EnBbfall_SetupFly(EnBbfall* this) { + this->flameOpacity = 255; + this->isBgCheckCollisionEnabled = true; + this->actor.bgCheckFlags &= ~1; + this->actor.speedXZ = 5.0f; + this->actor.gravity = -1.0f; + this->actionFunc = EnBbfall_Fly; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C0178.s") +void EnBbfall_Fly(EnBbfall* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->flameScaleY, 0.8f, 0.1f); + Math_StepToF(&this->flameScaleX, 1.0f, 0.1f); + EnBbfall_CheckForWall(this); + if (this->actor.bgCheckFlags & 1) { + if (EnBbfall_IsTouchingLava(this, globalCtx)) { + EnBbfall_SetupSinkIntoLava(this); + } else { + // Bounce upwards off the ground + this->actor.velocity.y *= -1.2f; + this->actor.velocity.y = CLAMP(this->actor.velocity.y, 8.0f, 12.0f); + this->actor.shape.rot.y += (s16)randPlusMinusPoint5Scaled(73728.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C01E0.s") + this->actor.bgCheckFlags &= ~1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Update.s") + this->actor.world.rot.y = this->actor.shape.rot.y; + EnBbfall_PlaySfx(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C07D4.s") +void EnBbfall_SetupSinkIntoLava(EnBbfall* this) { + this->isBgCheckCollisionEnabled = false; + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = EnBbfall_SinkIntoLava; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/func_808C080C.s") +void EnBbfall_SinkIntoLava(EnBbfall* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->actor.world.pos.y < (this->actor.floorHeight - 90.0f)) { + this->timer = 10; + EnBbfall_SetupWaitForPlayer(this); + } else { + EnBbfall_PlaySfx(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bbfall/EnBbfall_Draw.s") +void EnBbfall_SetupDown(EnBbfall* this) { + Animation_PlayLoop(&this->skelAnime, &gBubbleFlyingAnim); + this->collider.base.atFlags |= AT_ON; + this->timer = 200; + this->flameOpacity = 0; + this->collider.base.acFlags |= AC_ON; + this->actor.speedXZ = 2.0f; + this->flameScaleY = 0.0f; + this->flameScaleX = 0.0f; + this->actor.gravity = -2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DOWN); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnBbfall_Down; +} + +void EnBbfall_Down(EnBbfall* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + EnBbfall_CheckForWall(this); + + if (this->actor.bgCheckFlags & 1) { + if (EnBbfall_IsTouchingLava(this, globalCtx)) { + EnBbfall_SetupSinkIntoLava(this); + return; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + if (this->timer == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_UP); + EnBbfall_EnableColliders(this); + this->actor.velocity.y = 8.0f; + EnBbfall_SetupFly(this); + return; + } + + if (this->actor.velocity.y < -14.0f) { + this->actor.velocity.y *= -0.7f; + } else { + this->actor.velocity.y = 10.0f; + } + + this->actor.bgCheckFlags &= ~1; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 7.0f, 2, 2.0f, 0, 0, 0); + Math_ScaledStepToS(&this->actor.shape.rot.y, BINANG_ADD(this->actor.yawTowardsPlayer, 0x8000), 0xBB8); + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_WING); + } + + if (this->timer > 0) { + this->timer--; + } +} + +void EnBbfall_SetupDead(EnBbfall* this, GlobalContext* globalCtx) { + Vec3f* bodyPartVelocity; + Vec3f posDiff; + f32 magnitude; + s32 i; + + func_800BE5CC(&this->actor, &this->collider, 0); + this->timer = 15; + this->actor.shape.rot.x += 0x4E20; + this->actor.speedXZ = 0.0f; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_BUBLE_DEAD); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x70); + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->bodyPartDrawStatus = BBFALL_BODY_PART_DRAW_STATUS_DEAD; + this->actor.gravity = -1.5f; + + bodyPartVelocity = &this->bodyPartsVelocity[0]; + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++, bodyPartVelocity++) { + Math_Vec3f_Diff(&this->bodyPartsPos[i], &this->actor.world.pos, &posDiff); + magnitude = Math3D_Vec3fMagnitude(&posDiff); + if (magnitude > 1.0f) { + magnitude = 2.5f / magnitude; + } + + bodyPartVelocity->x = posDiff.x * magnitude; + bodyPartVelocity->z = posDiff.z * magnitude; + bodyPartVelocity->y = Rand_ZeroFloat(3.5f) + 10.0f; + } + + this->actionFunc = EnBbfall_Dead; +} + +void EnBbfall_Dead(EnBbfall* this, GlobalContext* globalCtx) { + s32 i; + + this->timer--; + Math_SmoothStepToS(&this->actor.world.rot.z, 0x4000, 4, 0x1000, 0x400); + + if (this->timer == 0) { + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) { + func_800B3030(globalCtx, &this->bodyPartsPos[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 2); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->bodyPartsPos[i], 11, NA_SE_EN_EXTINCT); + } + + Actor_MarkForDeath(&this->actor); + } else { + for (i = 0; i < ARRAY_COUNT(this->bodyPartsPos); i++) { + Math_Vec3f_Sum(&this->bodyPartsPos[i], &this->bodyPartsVelocity[i], &this->bodyPartsPos[i]); + this->bodyPartsVelocity[i].y += this->actor.gravity; + } + } +} + +void EnBbfall_SetupDamage(EnBbfall* this) { + this->collider.base.acFlags &= ~AC_ON; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLE_DAMAGE); + func_800BE5CC(&this->actor, &this->collider, 0); + + if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_ZORA_MAGIC) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffScale = 0.4f; + } else if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_STUN) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 20); + this->actor.speedXZ = 0.0f; + } else if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_HOOKSHOT) { + this->actor.speedXZ = 0.0f; + } else { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->actor.speedXZ = 7.0f; + } + + this->actionFunc = EnBbfall_Damage; +} + +void EnBbfall_Damage(EnBbfall* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); + if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ < 0.1f)) { + if (EnBbfall_IsTouchingLava(this, globalCtx)) { + EnBbfall_SetupSinkIntoLava(this); + } else { + EnBbfall_SetupDown(this); + } + } +} + +void EnBbfall_SetupFrozen(EnBbfall* this) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = 0.0f; + } + + this->actor.gravity = -2.0f; + this->actionFunc = EnBbfall_Frozen; +} + +void EnBbfall_Frozen(EnBbfall* this, GlobalContext* globalCtx) { + DECR(this->timer); + + if (this->timer == 0) { + EnBbfall_Thaw(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + EnBbfall_SetupDead(this, globalCtx); + } else { + EnBbfall_SetupDown(this); + } + } +} + +void EnBbfall_UpdateDamage(EnBbfall* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + this->collider.base.atFlags &= ~AT_ON; + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider.elements[0].info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + Actor_SetDropFlagJntSph(&this->actor, &this->collider); + this->flameOpacity = 0; + this->flameScaleY = 0.0f; + this->flameScaleX = 0.0f; + EnBbfall_DisableColliders(this); + EnBbfall_Thaw(this, globalCtx); + + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_ICE_ARROW) { + EnBbfall_Freeze(this); + if (this->actor.colChkInfo.health == 0) { + this->timer = 3; + this->collider.base.acFlags &= ~AC_ON; + } + + EnBbfall_SetupFrozen(this); + } else if (this->actor.colChkInfo.health == 0) { + EnBbfall_SetupDead(this, globalCtx); + } else { + EnBbfall_SetupDamage(this); + } + + if (this->actor.colChkInfo.damageEffect == EN_BBFALL_DMGEFF_LIGHT_ARROW) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.4f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + 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_SMALL_LIGHT_RAYS); + } + } + } else { + if (this->collider.base.atFlags & AT_BOUNCED) { + this->collider.base.atFlags &= ~(AT_HIT | AT_BOUNCED); + EnBbfall_DisableColliders(this); + if (this->actionFunc != EnBbfall_Down) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer + 0x8000; + this->actor.shape.rot.y = this->actor.world.rot.y; + EnBbfall_SetupDown(this); + } + } + } +} + +void EnBbfall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBbfall* this = THIS; + Sphere16* sphere; + Vec3f diff; + s32 i; + f32 scale; + s32 pad[2]; + + EnBbfall_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + if (this->actionFunc != EnBbfall_Dead) { + Actor_MoveWithGravity(&this->actor); + if (this->isBgCheckCollisionEnabled) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 25.0f, 20.0f, 7); + } + + for (i = ARRAY_COUNT(this->flamePos) - 1; i >= 2; i--) { + Math_Vec3f_Diff(&this->flamePos[i - 2], &this->flamePos[i - 1], &diff); + Math_Vec3f_Scale(&diff, (i - 1) * 0.1f); + Math_Vec3f_Copy(&this->flamePos[i], &this->flamePos[i - 1]); + Math_Vec3f_Sum(&this->flamePos[i], &diff, &this->flamePos[i]); + } + + Math_Vec3f_Copy(&this->flamePos[1], &this->flamePos[0]); + Math_Vec3f_Copy(&this->flamePos[0], &this->actor.world.pos); + this->flamePos[0].y += 15.0f; + this->flamePos[0].y -= 47.0f * this->flameScaleY; + + for (i = 0, scale = this->flameScaleX; i < ARRAY_COUNT(this->colliderElements); i++, scale *= 0.7569f) { + sphere = &this->collider.elements[i].dim.worldSphere; + sphere->radius = 30.0f * scale; + sphere->center.x = this->flamePos[2 * i].x; + sphere->center.y = this->flamePos[2 * i].y + (47.0f * scale); + sphere->center.z = this->flamePos[2 * i].z; + } + + this->collider.elements[0].dim.worldSphere.radius = + CLAMP_MIN(this->collider.elements[0].dim.worldSphere.radius, 20); + + Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.elements->dim.worldSphere.center); + + if (this->collider.base.atFlags & AT_ON) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.ocFlags1 & OC1_ON) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.2f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.4f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.4f, 0.01f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + } +} + +s32 EnBbfall_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBbfall* this = THIS; + + if (this->bodyPartDrawStatus == BBFALL_BODY_PART_DRAW_STATUS_BROKEN) { + this->limbDList = *dList; + *dList = NULL; + } + + return false; +} + +void EnBbfall_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnBbfall* this = THIS; + MtxF* currentMatrixState; + + if (this->bodyPartDrawStatus == BBFALL_BODY_PART_DRAW_STATUS_ALIVE) { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + if (sLimbIndexToBodyPartsIndex[limbIndex] == 0) { + Matrix_MultVecX(1000.0f, &this->bodyPartsPos[0]); + } else if (sLimbIndexToBodyPartsIndex[limbIndex] == 3) { + Matrix_MultVecX(-1000.0f, &this->bodyPartsPos[3]); + Matrix_MultVec3f(&sDuplicateCraniumBodyPartOffset, &this->bodyPartsPos[4]); + } else { + Matrix_MultZero(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]); + } + } + } else if (this->bodyPartDrawStatus > BBFALL_BODY_PART_DRAW_STATUS_ALIVE) { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + Matrix_MultZero(&this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]]); + } + + if (limbIndex == BUBBLE_LIMB_CRANIUM) { + this->bodyPartDrawStatus = BBFALL_BODY_PART_DRAW_STATUS_BROKEN; + } + } else { + if (sLimbIndexToBodyPartsIndex[limbIndex] != -1) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + currentMatrixState = Matrix_GetCurrent(); + currentMatrixState->mf[3][0] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].x; + currentMatrixState->mf[3][1] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].y; + currentMatrixState->mf[3][2] = this->bodyPartsPos[sLimbIndexToBodyPartsIndex[limbIndex]].z; + Matrix_RotateZS(thisx->world.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++, this->limbDList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} + +void EnBbfall_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnBbfall* this = THIS; + MtxF* currentMatrixState; + Gfx* gfx; + s32 opacity; + Vec3f* pos; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + POLY_OPA_DISP = &gfx[1]; + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnBbfall_OverrideLimbDraw, + EnBbfall_PostLimbDraw, &this->actor); + + if (this->flameOpacity > 0) { + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_RotateYS( + ((Camera_GetCamDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) - this->actor.shape.rot.y) + 0x8000), + MTXMODE_APPLY); + Matrix_Scale(this->flameScaleX, this->flameScaleY, 1.0f, MTXMODE_APPLY); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + currentMatrixState = Matrix_GetCurrent(); + + opacity = this->flameOpacity; + pos = &this->flamePos[0]; + + for (i = 0; i < ARRAY_COUNT(this->flamePos); i++, pos++) { + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, + ((globalCtx->gameplayFrames + (i * 10)) * (-20 + i * 2)) & 0x1FF, 32, 128)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, opacity); + currentMatrixState->mf[3][0] = pos->x; + currentMatrixState->mf[3][1] = pos->y; + currentMatrixState->mf[3][2] = pos->z; + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + + opacity -= 35; + if (opacity < 0) { + break; + } + + Matrix_Scale(0.87f, 0.87f, 1.0f, MTXMODE_APPLY); + } + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.h b/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.h index 90c209b31..411c4b17f 100644 --- a/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.h +++ b/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.h @@ -2,16 +2,35 @@ #define Z_EN_BBFALL_H #include "global.h" +#include "objects/object_bb/object_bb.h" struct EnBbfall; typedef void (*EnBbfallActionFunc)(struct EnBbfall*, GlobalContext*); typedef struct EnBbfall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; - /* 0x0248 */ EnBbfallActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x218]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[BUBBLE_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[BUBBLE_LIMB_MAX]; + /* 0x248 */ EnBbfallActionFunc actionFunc; + /* 0x24C */ u8 flameOpacity; + /* 0x24D */ u8 isBgCheckCollisionEnabled; + /* 0x24E */ s8 bodyPartDrawStatus; + /* 0x24F */ u8 drawDmgEffType; + /* 0x250 */ s16 timer; + /* 0x254 */ f32 flameScaleY; + /* 0x258 */ f32 flameScaleX; + /* 0x25C */ f32 drawDmgEffAlpha; + /* 0x260 */ f32 drawDmgEffScale; + /* 0x264 */ f32 drawDmgEffFrozenSteamScale; + /* 0x268 */ Vec3f flamePos[6]; + /* 0x2B0 */ Vec3f bodyPartsPos[5]; + /* 0x2EC */ Vec3f bodyPartsVelocity[5]; + /* 0x328 */ Gfx* limbDList; + /* 0x32C */ UNK_TYPE1 unk_32C[0x58]; + /* 0x384 */ ColliderJntSph collider; + /* 0x3A4 */ ColliderJntSphElement colliderElements[3]; } EnBbfall; // size = 0x464 extern const ActorInit En_Bbfall_InitVars; 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 ca3c3decb..ecb64cb91 100644 --- a/src/overlays/actors/ovl_En_Bee/z_en_bee.c +++ b/src/overlays/actors/ovl_En_Bee/z_en_bee.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bee.c + * Overlay: ovl_En_Bee + * Description: Giant Bee + */ + #include "z_en_bee.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnBee*)thisx) 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 1bc0ea082..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,3 +1,9 @@ +/* + * File: z_en_bh.c + * Overlay: ovl_En_Bh + * Description: Brown Bird (on the Moon) + */ + #include "z_en_bh.h" #define FLAGS 0x00000000 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 8f11c38c8..e25d1e02a 100644 --- a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c +++ b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c @@ -1,6 +1,13 @@ -#include "z_en_bigokuta.h" +/* + * File: z_en_bigokuta.c + * Overlay: ovl_En_Bigokuta + * Description: Big Octo + */ -#define FLAGS 0x00000005 +#include "z_en_bigokuta.h" +#include "assets/objects/object_bigokuta/object_bigokuta.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnBigokuta*)thisx) @@ -9,7 +16,21 @@ void EnBigokuta_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBigokuta_Update(Actor* thisx, GlobalContext* globalCtx); void EnBigokuta_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80AC2B4C(GlobalContext* globalCtx, EnBigokuta* this); +void EnBigokuta_SetupIdle(EnBigokuta* this); +void EnBigokuta_Idle(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SetupRise(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_RiseOutOfWater(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SetupIdleAboveWater(EnBigokuta* this); +void EnBigokuta_IdleAboveWater(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SetupSuckInPlayer(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SuckInPlayer(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SetupHoldPlayer(EnBigokuta* this); +void EnBigokuta_HoldPlayer(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_PlayDeathCutscene(EnBigokuta* this, GlobalContext* globalCtx); +void EnBigokuta_SetupDeathEffects(EnBigokuta* this); +void EnBigokuta_PlayDeathEffects(EnBigokuta* this, GlobalContext* globalCtx); + const ActorInit En_Bigokuta_InitVars = { ACTOR_EN_BIGOKUTA, ACTORCAT_BOSS, @@ -22,25 +43,49 @@ const ActorInit En_Bigokuta_InitVars = { (ActorFunc)EnBigokuta_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AC4530 = { - { COLTYPE_HARD, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFC74F, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sShellCylinderInit = { + { + COLTYPE_HARD, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFC74F, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 75, 125, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AC455C = { - { COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x000038B0, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sBodyCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x000038B0, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 70, 125, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80AC4588 = { 4, 130, 120, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 4, 130, 120, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AC4590[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 2500, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), @@ -48,73 +93,586 @@ static InitChainEntry D_80AC4590[] = { ICHAIN_VEC3F_DIV1000(scale, 33, ICHAIN_STOP), }; -#endif +void EnBigokuta_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBigokuta* this = THIS; -extern ColliderCylinderInit D_80AC4530; -extern ColliderCylinderInit D_80AC455C; -extern CollisionCheckInfoInit D_80AC4588; -extern InitChainEntry D_80AC4590[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gBigOctoSkel, &gBigOctoIdleAnim, this->jointTable, + this->morphTable, BIGOKUTA_LIMB_MAX); -extern UNK_TYPE D_06000444; -extern UNK_TYPE D_06000A74; -extern UNK_TYPE D_060014B8; + Collider_InitAndSetCylinder(globalCtx, &this->shellCollider, &this->actor, &sShellCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->bodyCollider, &this->actor, &sBodyCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/EnBigokuta_Init.s") + if (gSaveContext.save.weekEventReg[20] & 2 || + ((this->actor.params != 0xFF) && Flags_GetSwitch(globalCtx, this->actor.params))) { + Actor_MarkForDeath(&this->actor); + } else { + this->actor.world.pos.y -= 99.0f; + EnBigokuta_SetupIdle(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/EnBigokuta_Destroy.s") + this->camAt.x = (Math_SinS(this->actor.home.rot.y) * 66.0f) + this->actor.world.pos.x; + this->camAt.y = (this->actor.home.pos.y - 49.5f) + 42.899998f; + this->camAt.z = (Math_CosS(this->actor.home.rot.y) * 66.0f) + this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC28B4.s") + this->unkFunc = func_80AC2B4C; // set but never called +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC299C.s") +void EnBigokuta_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBigokuta* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2A1C.s") + Collider_DestroyCylinder(globalCtx, &this->shellCollider); + Collider_DestroyCylinder(globalCtx, &this->bodyCollider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2A7C.s") +void EnBigokuta_SetupCutsceneCamera(EnBigokuta* this, GlobalContext* globalCtx, Vec3f* at, Vec3f* eye) { + s16 angle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2B4C.s") + ActorCutscene_Start(this->actor.cutscene, &this->actor); + this->camId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Play_CameraSetAtEye(globalCtx, this->camId, at, eye); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2B98.s") + angle = BINANG_SUB(Actor_YawToPoint(&this->actor, eye), this->actor.home.rot.y); + if (angle > 0) { + angle = BINANG_ADD(this->actor.home.rot.y, 0x1800); + } else { + angle = BINANG_SUB(this->actor.home.rot.y, 0x1800); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2C30.s") + this->camEye.x = (Math_SinS(angle) * 250.0f) + this->camAt.x; + this->camEye.y = this->camAt.y + 100.0f; + this->camEye.z = (Math_CosS(angle) * 250.0f) + this->camAt.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2C84.s") +void EnBigokuta_MoveCamera(EnBigokuta* this, GlobalContext* globalCtx) { + Camera* camera = Play_GetCamera(globalCtx, this->camId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2CE8.s") + Math_Vec3f_StepTo(&camera->eye, &this->camEye, 20.0f); + Math_Vec3f_StepTo(&camera->at, &this->camAt, 20.0f); + Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2DAC.s") +void EnBigokuta_ResetCamera(EnBigokuta* this, GlobalContext* globalCtx) { + Camera* camera; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2EBC.s") + if (this->camId != 0) { + camera = Play_GetCamera(globalCtx, this->camId); + Play_CameraSetAtEye(globalCtx, 0, &camera->at, &camera->eye); + this->camId = 0; + ActorCutscene_Stop(this->actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2F20.s") +void EnBigokuta_ShootPlayer(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC2F64.s") + if (&this->actor == player->actor.parent) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + player->actor.velocity.y = 0.0f; + player->actor.world.pos.x += 20.0f * Math_SinS(this->actor.home.rot.y); + player->actor.world.pos.z += 20.0f * Math_CosS(this->actor.home.rot.y); + func_800B8D50(globalCtx, &this->actor, 10.0f, this->actor.home.rot.y, 10.0f, 4); + } + EnBigokuta_ResetCamera(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC3054.s") +void func_80AC2B4C(GlobalContext* globalCtx, EnBigokuta* this) { + func_8013A530(globalCtx, &this->actor, 3, &this->actor.focus.pos, &this->actor.shape.rot, 280.0f, 1800.0f, -1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC30EC.s") +s32 EnBigokuta_IsInWater(EnBigokuta* this, GlobalContext* globalCtx) { + WaterBox* box; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC31EC.s") + this->actor.floorHeight = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, + &this->actor, &this->actor.world.pos); + if (!WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->actor.home.pos.y, &box) || + (this->actor.home.pos.y <= this->actor.floorHeight)) { + return false; + } else { + return true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC33A4.s") +void EnBigokuta_SpawnRipple(EnBigokuta* this, GlobalContext* globalCtx) { + Vec3f ripplePos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC33C0.s") + ripplePos.x = this->actor.world.pos.x; + ripplePos.y = this->actor.home.pos.y; + ripplePos.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &ripplePos, 1000, 1400, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC3460.s") +void EnBigokuta_SetupIdle(EnBigokuta* this) { + Animation_Change(&this->skelAnime, &gBigOctoIdleAnim, 0.5f, 0.0f, 0.0f, 1, -3.0f); + this->actionFunc = EnBigokuta_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC34A8.s") +void EnBigokuta_Idle(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC35E8.s") + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 99.0f, 2.5f); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000); + if ((this->actor.xzDistToPlayer < 300.0f) && ((player->actor.world.pos.y - this->actor.home.pos.y) < 100.0f)) { + EnBigokuta_SetupRise(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC3650.s") +void EnBigokuta_SetupRise(EnBigokuta* this, GlobalContext* globalCtx) { + Vec3f splashPos; + s32 i; + s16 angle = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC3930.s") + Animation_PlayOnce(&this->skelAnime, &gBigOctoRiseOutOfWaterAnim); + splashPos.y = this->actor.home.pos.y; + for (i = 0; i < 8; i++) { + splashPos.x = Math_SinS(angle) * 70.0f + this->actor.world.pos.x; + splashPos.z = Math_CosS(angle) * 70.0f + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &splashPos, NULL, NULL, 0, Rand_S16Offset(1000, 200)); + angle = BINANG_ADD(angle, 0x2000); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_LAND); + this->actionFunc = EnBigokuta_RiseOutOfWater; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC39A0.s") +void EnBigokuta_RiseOutOfWater(EnBigokuta* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 16.5f, 15.0f); + if (SkelAnime_Update(&this->skelAnime)) { + EnBigokuta_SetupIdleAboveWater(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/EnBigokuta_Update.s") +void EnBigokuta_SetupIdleAboveWater(EnBigokuta* this) { + Animation_MorphToLoop(&this->skelAnime, &gBigOctoIdleAnim, -5.0f); + this->actionFunc = EnBigokuta_IdleAboveWater; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC3D48.s") +void EnBigokuta_IdleAboveWater(EnBigokuta* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 16.5f, 2.5f); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/func_80AC4204.s") + if ((this->actor.xzDistToPlayer > 400.0f) || (this->actor.playerHeightRel > 200.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_SINK); + EnBigokuta_SetupIdle(this); + } else if ((this->actor.xzDistToPlayer < 200.0f) && globalCtx->grabPlayer(globalCtx, GET_PLAYER(globalCtx))) { + EnBigokuta_SetupSuckInPlayer(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigokuta/EnBigokuta_Draw.s") +void EnBigokuta_UpdateOrSetupCam(EnBigokuta* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + if (this->camId != 0) { + EnBigokuta_MoveCamera(this, globalCtx); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + Camera* camera = Play_GetCamera(globalCtx, 0); + + EnBigokuta_SetupCutsceneCamera(this, globalCtx, &camera->at, &camera->eye); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +void EnBigokuta_SetupSuckInPlayer(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.parent = &this->actor; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + Math_Vec3f_Copy(&this->playerPos, &player->actor.world.pos); + this->timer = 0; + + Animation_Change(&this->skelAnime, &gBigOctoIdleAnim, 1.0f, 12.0f, 12.0f, 2, -3.0f); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + + this->playerHoldPos.x = (Math_SinS(this->actor.shape.rot.y) * 66.0f) + this->actor.world.pos.x; + this->playerHoldPos.y = (this->actor.home.pos.y - 49.5f) + 42.899998f; + this->playerHoldPos.z = (Math_CosS(this->actor.shape.rot.y) * 66.0f) + this->actor.world.pos.z; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_SLIME_DEAD); + this->actionFunc = EnBigokuta_SuckInPlayer; +} + +void EnBigokuta_SuckInPlayer(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + EnBigokuta_UpdateOrSetupCam(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 49.5f, 10.0f); + + if (this->timer < 9) { + this->timer++; + } + + player->unk_AE8 = 0; + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerPos); + if (Math_Vec3f_StepTo(&player->actor.world.pos, &this->playerHoldPos, sqrtf(this->timer) * 5.0f) < 0.1f) { + s16 rotY = this->actor.shape.rot.y; + + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 0x800)) { + EnBigokuta_SetupHoldPlayer(this); + } + + this->playerHoldPos.x = (Math_SinS(this->actor.shape.rot.y) * 66.0f) + this->actor.world.pos.x; + this->playerHoldPos.y = (this->actor.home.pos.y - 49.5f) + 42.899998f; + this->playerHoldPos.z = (Math_CosS(this->actor.shape.rot.y) * 66.0f) + this->actor.world.pos.z; + + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerHoldPos); + Math_Vec3f_Copy(&this->playerPos, &player->actor.world.pos); + player->actor.shape.rot.y += BINANG_SUB(this->actor.shape.rot.y, rotY); + } else { + Math_Vec3f_Copy(&this->playerPos, &player->actor.world.pos); + player->actor.velocity.y = 0.0f; + } +} + +void EnBigokuta_SetupHoldPlayer(EnBigokuta* this) { + this->timer = 12; + this->actionFunc = EnBigokuta_HoldPlayer; +} + +void EnBigokuta_HoldPlayer(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->timer--; + if (this->timer >= 0) { + EnBigokuta_UpdateOrSetupCam(this, globalCtx); + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerHoldPos); + + if (this->timer == 0) { + EnBigokuta_ShootPlayer(this, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_REVERSE); + } + } else if (this->timer == -24) { + EnBigokuta_SetupIdleAboveWater(this); + } +} + +void EnBigokuta_SetupDeathCutscene(EnBigokuta* this) { + ActorCutscene_SetIntentToPlay(this->cutscene); + this->timer = 0; + this->bodyCollider.base.acFlags &= ~AC_ON; + this->actionFunc = EnBigokuta_PlayDeathCutscene; +} + +void EnBigokuta_PlayDeathCutscene(EnBigokuta* this, GlobalContext* globalCtx) { + Player* player; + + this->actor.colorFilterTimer = Animation_GetLastFrame(&gBigOctoDeathAnim); + + if (this->timer != 0) { + this->timer--; + if (this->timer == 0) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.5f, 0.35f); + EnBigokuta_SetupDeathEffects(this); + } + } else if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Start(this->cutscene, &this->actor); + + if (!(gSaveContext.eventInf[4] & 2) && !(gSaveContext.eventInf[3] & 0x20)) { + func_800B724C(globalCtx, &this->actor, 7); + } else { + player = GET_PLAYER(globalCtx); + player->stateFlags1 |= 0x20; + } + + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->timer = 3; + } else { + EnBigokuta_SetupDeathEffects(this); + } + } else { + ActorCutscene_SetIntentToPlay(this->cutscene); + } +} + +void EnBigokuta_SetupDeathEffects(EnBigokuta* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gBigOctoDeathAnim, -5.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_DEAD2); + this->actor.flags &= ~1; + this->timer = 10; + this->actionFunc = EnBigokuta_PlayDeathEffects; +} + +void EnBigokuta_PlayDeathEffects(EnBigokuta* this, GlobalContext* globalCtx) { + static Vec3f D_80AC45A4 = { 0.0f, -0.5f, 0.0f }; + static Color_RGBA8 D_80AC45B0 = { 255, 255, 255, 255 }; + static Color_RGBA8 D_80AC45B4 = { 100, 255, 255, 255 }; + static Color_RGBA8 D_80AC45B8 = { 150, 150, 150, 0 }; + + if (SkelAnime_Update(&this->skelAnime)) { + this->actor.world.pos.y -= 0.2f; + + if (this->timer > 0) { + this->timer--; + + if (this->timer == 6) { + Vec3f dustPos; + + dustPos.x = this->actor.world.pos.x; + dustPos.y = this->actor.world.pos.y + 150.0f; + dustPos.z = this->actor.world.pos.z; + + func_800B0DE0(globalCtx, &dustPos, &gZeroVec3f, &gZeroVec3f, &D_80AC45B0, &D_80AC45B4, 1200, 20); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OCTAROCK_DEAD2); + } + } else { + this->actor.world.pos.y -= 0.2f; + + if (Math_StepToF(&this->actor.scale.y, 0.001f, 0.001f)) { + s32 i; + Vec3f bubbleVel; + Vec3f bubblePos; + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 50, NA_SE_EN_COMMON_WATER_MID); + bubblePos.y = this->actor.world.pos.y; + + for (i = 0; i < 20; i++) { + bubbleVel.x = randPlusMinusPoint5Scaled(10.0f); + bubbleVel.y = Rand_ZeroFloat(5.5f) + 5.5f; + bubbleVel.z = randPlusMinusPoint5Scaled(10.0f); + bubblePos.x = this->actor.world.pos.x + (2.0f * bubbleVel.x); + bubblePos.z = this->actor.world.pos.z + (2.0f * bubbleVel.z); + + EffectSsDtBubble_SpawnCustomColor(globalCtx, &bubblePos, &bubbleVel, &D_80AC45A4, &D_80AC45B0, + &D_80AC45B8, Rand_S16Offset(150, 50), 25, 0); + } + + if (this->actor.params != 0xFF) { + Flags_SetSwitch(globalCtx, this->actor.params); + } + + ActorCutscene_Stop(this->cutscene); + Actor_MarkForDeath(&this->actor); + + if (!(gSaveContext.eventInf[4] & 2) && !(gSaveContext.eventInf[3] & 0x20)) { + func_800B724C(globalCtx, &this->actor, 6); + } else { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags1 &= ~0x20; + } + } + + if (this->drawDmgEffAlpha > 0.0f) { + this->drawDmgEffAlpha = this->actor.scale.y * 30.30303f; + } + } + } else { + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y - 16.5f, 15.0f); + } +} + +s32 EnBigokuta_IsNearSwampBoat(EnBigokuta* this, GlobalContext* globalCtx) { + this->actor.child = SubS_FindActor(globalCtx, NULL, ACTORCAT_BG, ACTOR_BG_INGATE); + + if ((this->actor.child != NULL) && (Actor_XZDistanceBetweenActors(&this->actor, this->actor.child) < 250.0f)) { + return true; + } else { + return false; + } +} + +void EnBigokuta_CheckOneHitKill(EnBigokuta* this, GlobalContext* globalCtx) { + if ((this->bodyCollider.base.acFlags & AC_ON) && + ((this->bodyCollider.base.acFlags & AC_HIT) || + ((globalCtx->sceneNum == SCENE_20SICHITAI || globalCtx->sceneNum == SCENE_20SICHITAI2) && + EnBigokuta_IsNearSwampBoat(this, globalCtx)))) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + + if (this->bodyCollider.base.acFlags & AC_HIT) { + if (this->bodyCollider.info.acHitInfo->toucher.dmgFlags & 0x1000) { // Ice Arrow + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 1.2f; + this->drawDmgEffFrozenSteamScale = 1.8000001f; + this->drawDmgEffAlpha = 1.0f; + } else if (this->bodyCollider.info.acHitInfo->toucher.dmgFlags & 0x2000) { // Light Arrow + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 1.2f; + this->drawDmgEffAlpha = 4.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->bodyCollider.info.bumper.hitPos.x, this->bodyCollider.info.bumper.hitPos.y, + this->bodyCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } + + this->bodyCollider.base.acFlags &= ~AC_HIT; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, Animation_GetLastFrame(&gBigOctoDeathAnim)); + EnBigokuta_ShootPlayer(this, globalCtx); + EnBigokuta_SetupDeathCutscene(this); + } +} + +void EnBigokuta_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBigokuta* this = THIS; + + if (!EnBigokuta_IsInWater(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (globalCtx->gameplayFrames % 7 == 0) { + EnBigokuta_SpawnRipple(this, globalCtx); + } + + EnBigokuta_CheckOneHitKill(this, globalCtx); + this->actionFunc(this, globalCtx); + + if ((this->bodyCollider.base.acFlags & AC_ON)) { + this->shellCollider.dim.pos.x = Math_SinS(this->actor.shape.rot.y) * -20.0f + this->actor.world.pos.x; + this->shellCollider.dim.pos.y = this->actor.world.pos.y; + this->shellCollider.dim.pos.z = Math_CosS(this->actor.shape.rot.y) * -20.0f + this->actor.world.pos.z; + + this->bodyCollider.dim.pos.x = this->shellCollider.dim.pos.x; + this->bodyCollider.dim.pos.y = this->shellCollider.dim.pos.y; + this->bodyCollider.dim.pos.z = this->shellCollider.dim.pos.z; + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bodyCollider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->shellCollider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->shellCollider.base); + Actor_SetFocus(&this->actor, 82.5f); + } + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.6f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 1.2f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 1.2f, 0.030000001f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 EnBigokuta_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + if (limbIndex == BIGOKUTA_LIMB_HEAD) { + EnBigokuta* this = THIS; + s32 envColor; + s16 rotX; + f32 lastFrame; + + if (this->actionFunc == EnBigokuta_PlayDeathEffects) { + lastFrame = Animation_GetLastFrame(&gBigOctoDeathAnim); + envColor = ((255.0f / lastFrame) * (lastFrame - this->skelAnime.curFrame)); + } else { + envColor = 255; + } + gDPPipeSync((*gfx)++); + gDPSetEnvColor((*gfx)++, envColor, envColor, envColor, envColor); + + if (this->actionFunc == EnBigokuta_SuckInPlayer) { + rotX = (s16)(this->timer * 6144.0f * (1 / 9.0f)); + rot->x -= rotX; + } else if (this->actionFunc == EnBigokuta_HoldPlayer) { + if (this->timer == 1) { + rotX = 0; + } else if (this->timer == 0) { + rotX = -0xC00; + } else if (this->timer > 0) { + rotX = 0x1800; + } else { + rotX = ((this->timer + 0x18) * 0.041666668f * -6144.0f); + } + rot->x -= rotX; + } + } else if (limbIndex == BIGOKUTA_LIMB_SNOUT_CENTER) { + EnBigokuta* this = THIS; + + if (this->actionFunc == EnBigokuta_PlayDeathEffects) { + if (this->timer < 5) { + Matrix_Scale(1.0f, 1.0f, (this->timer * 0.2f * 0.25f) + 1.0f, MTXMODE_APPLY); + } else if (this->timer < 8) { + f32 time = (this->timer - 5) * (1 / 12.0f); + + Matrix_Scale(1.0f + time, 1.0f + time, 1.25f - time, MTXMODE_APPLY); + } else { + Matrix_Scale(1.25f - ((this->timer - 8) * 0.125f), 1.25f - ((this->timer - 8) * 0.125f), 1.0f, + MTXMODE_APPLY); + } + } else if (this->actionFunc == EnBigokuta_SuckInPlayer) { + f32 sin = sin_rad(this->timer * (M_PI / 3.0f)) * 0.5f; + + Matrix_Scale(((this->timer * (2 / 90.0f)) * (0.5f + sin)) + 1.0f, + ((this->timer * (2 / 90.0f)) * (0.5f - sin)) + 1.0f, 1.0f - ((this->timer * 0.3f) / 9.0f), + MTXMODE_APPLY); + } else if (this->actionFunc == EnBigokuta_HoldPlayer && this->timer != 1) { + if (this->timer == 0) { + Matrix_Scale(0.9f, 0.9f, 1.15f, MTXMODE_APPLY); + } else if (this->timer > 0) { + f32 sin = sin_rad(this->timer * (M_PI / 3.0f)) * 0.5f; + + Matrix_Scale(((0.5f + sin) * 0.2f) + 1.0f, ((0.5f - sin) * 0.2f) + 1.0f, 0.7f, MTXMODE_APPLY); + } else { + Matrix_Scale(1.0f - ((this->timer + 0x18) * 0.2f * 0.041666668f), + 1.0f - ((this->timer + 0x18) * 0.2f * 0.041666668f), + ((this->timer + 0x18) * 0.3f * 0.041666668f) + 1.0f, MTXMODE_APPLY); + } + } + } + return false; +} + +void EnBigokuta_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + static s8 D_80AC45BC[] = { + -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, 8, 4, -1, 5, -1, -1, -1, -1, 6, 7, + }; + static Vec3f D_80AC45D0[] = { + { 0.0f, 2000.0f, 1000.0f }, { 0.0f, 2000.0f, -2000.0f }, { 1700.0f, 700.0f, -600.0f }, + { -1700.0f, 700.0f, -600.0f }, { 0.0f, 500.0f, -2500.0f }, + }; + EnBigokuta* this = THIS; + s32 i; + s8 limbPosIndex = D_80AC45BC[limbIndex]; + + if (limbPosIndex != -1) { + if (limbPosIndex < 6) { + Matrix_MultVecX(800.0f, &this->limbPos[limbPosIndex]); + } else if (limbPosIndex < 8) { + Matrix_MultZero(&this->limbPos[limbPosIndex]); + } else { + for (i = 0; i < ARRAY_COUNT(D_80AC45D0); i++) { + Matrix_MultVec3f(&D_80AC45D0[i], &this->limbPos[limbPosIndex + i]); + } + } + } +} + +void EnBigokuta_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBigokuta* this = THIS; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + if ((this->actionFunc != EnBigokuta_PlayDeathEffects) || (this->timer != 0)) { + Scene_SetRenderModeXlu(globalCtx, 0, 1); + gfx = POLY_OPA_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + gDPSetEnvColor(&gfx[1], 255, 255, 255, 255); + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnBigokuta_OverrideLimbDraw, + EnBigokuta_PostLimbDraw, &this->actor, &gfx[2]); + } else { + Scene_SetRenderModeXlu(globalCtx, 1, 2); + gfx = POLY_XLU_DISP; + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + gDPSetEnvColor(&gfx[1], 0, 0, 0, (this->actor.scale.y * 7727.273f)); + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnBigokuta_PostLimbDraw, &this->actor, &gfx[2]); + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h index 40b23d63c..0f07c4d7f 100644 --- a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h +++ b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.h @@ -6,12 +6,53 @@ struct EnBigokuta; typedef void (*EnBigokutaActionFunc)(struct EnBigokuta*, GlobalContext*); +typedef void (*EnBigokutaUnkFunc)(GlobalContext*, struct EnBigokuta*); + +typedef enum { + /* 00 */ BIGOKUTA_LIMB_NONE, + /* 01 */ BIGOKUTA_LIMB_BODY, + /* 02 */ BIGOKUTA_LIMB_ARM_BASE_RIGHT_FRONT, + /* 03 */ BIGOKUTA_LIMB_ARM_END_RIGHT_FRONT, + /* 04 */ BIGOKUTA_LIMB_ARM_BASE_LEFT_FRONT, + /* 05 */ BIGOKUTA_LIMB_ARM_END_LEFT_FRONT, + /* 06 */ BIGOKUTA_LIMB_ARM_BASE_RIGHT_BACK, + /* 07 */ BIGOKUTA_LIMB_ARM_END_RIGHT_BACK, + /* 08 */ BIGOKUTA_LIMB_ARM_BASE_LEFT_BACK, + /* 09 */ BIGOKUTA_LIMB_ARM_END_LEFT_BACK, + /* 10 */ BIGOKUTA_LIMB_HEAD, + /* 11 */ BIGOKUTA_LIMB_TENTACLE_BASE_LEFT, + /* 12 */ BIGOKUTA_LIMB_TENTACLE_TIP_LEFT, + /* 13 */ BIGOKUTA_LIMB_TENTACLE_BASE_RIGHT, + /* 14 */ BIGOKUTA_LIMB_TENTACLE_TIP_RIGHT, + /* 15 */ BIGOKUTA_LIMB_WEAK_POINT_LEFT, + /* 16 */ BIGOKUTA_LIMB_WEAK_POINT_RIGHT, + /* 17 */ BIGOKUTA_LIMB_SNOUT_CENTER, + /* 18 */ BIGOKUTA_LIMB_SNOUT_RIGHT, + /* 19 */ BIGOKUTA_LIMB_SNOUT_LEFT, + /* 20 */ BIGOKUTA_LIMB_MAX +} ObjectBigokutaLimbs; typedef struct EnBigokuta { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x48]; + /* 0x0144 */ EnBigokutaUnkFunc unkFunc; // possibly something to do with photographing + /* 0x0148 */ SkelAnime skelAnime; /* 0x018C */ EnBigokutaActionFunc actionFunc; - /* 0x0190 */ char unk_190[0x268]; + /* 0x0190 */ u8 drawDmgEffType; + /* 0x0192 */ s16 timer; + /* 0x0194 */ s16 camId; + /* 0x0196 */ s16 cutscene; + /* 0x0198 */ Vec3s jointTable[BIGOKUTA_LIMB_MAX]; + /* 0x0210 */ Vec3s morphTable[BIGOKUTA_LIMB_MAX]; + /* 0x0288 */ f32 drawDmgEffAlpha; + /* 0x028C */ f32 drawDmgEffScale; + /* 0x0290 */ f32 drawDmgEffFrozenSteamScale; // only affects DRAWEFFECT_ICE + /* 0x0294 */ Vec3f playerPos; + /* 0x02A0 */ Vec3f playerHoldPos; + /* 0x02AC */ Vec3f camAt; + /* 0x02B8 */ Vec3f camEye; + /* 0x02C4 */ Vec3f limbPos[13]; + /* 0x0360 */ ColliderCylinder shellCollider; + /* 0x03AC */ ColliderCylinder bodyCollider; } EnBigokuta; // size = 0x3F8 extern const ActorInit En_Bigokuta_InitVars; 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 ebfc25ddb..2fbd60927 100644 --- a/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c +++ b/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bigpamet.c + * Overlay: ovl_En_Bigpamet + * Description: Gekko & Snapper Miniboss - Snapper + */ + #include "z_en_bigpamet.h" -#define FLAGS 0x00000435 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_400) #define THIS ((EnBigpamet*)thisx) 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 2cb90b98d..acf465f83 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -1,12 +1,14 @@ /* - * 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 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_200 | ACTOR_FLAG_1000) #define THIS ((EnBigpo*)thisx) @@ -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 = { @@ -184,7 +175,7 @@ static Vec3f D_80B65084[] = { void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx2) { GlobalContext* globalCtx = globalCtx2; - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; EnBigpoFireEffect* firesPtr; s32 i; @@ -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); @@ -216,7 +207,7 @@ void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx2) { 255, 0); } - ActorShape_Init(&thisx->shape, 0.0f, func_800B3FC0, 45.0f); + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 45.0f); thisx->bgCheckFlags |= 0x400; this->savedHeight = thisx->home.pos.y + 100.0f; this->mainColor.r = 255; @@ -237,24 +228,23 @@ void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx2) { } } -void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; - GlobalContext* globalCtx2; +void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnBigpo* this = THIS; s32 fireCount; 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++) { - LightContext_RemoveLight(globalCtx2, &globalCtx2->lightCtx, this->fires[fireCount].light); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->fires[fireCount].light); } - Collider_DestroyCylinder(globalCtx2, &this->collider); + Collider_DestroyCylinder(globalCtx, &this->collider); } } -void func_80B61914(EnBigpo* this) { +void EnBigpo_RotateSpawnCutsceneFires(EnBigpo* this) { EnBigpoFireEffect* firePtr; s32 i; @@ -271,15 +261,17 @@ void EnBigpo_UpdateSpin(EnBigpo* this) { this->actor.shape.rot.y += this->rotVelocity; if ((oldYaw < 0) && (this->actor.shape.rot.y > 0)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL); // spinning sfx during spin attack + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_ROLL); // spinning sfx during spin attack } } -// 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; - if (this->cutsceneSubCamId != SUBCAM_FREE) { + if (this->cutsceneSubCamId != CAM_ID_MAIN) { subCam = Play_GetCamera(globalContext, this->cutsceneSubCamId); subCam->eye.y -= this->actor.velocity.y; if (this->actor.velocity.y > 0.0f) { @@ -291,7 +283,7 @@ void EnBigpo_LowerCutsceneSubCamera(EnBigpo* this, GlobalContext* globalContext) } void EnBigpo_InitWellBigpo(EnBigpo* this) { - this->actor.flags &= ~0x1; // targetable OFF + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF this->actionFunc = EnBigpo_WellWaitForProximity; this->fireRadius = 200.0f; } @@ -330,7 +322,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; @@ -340,7 +332,7 @@ void EnBigpo_SpawnCutsceneStage1(EnBigpo* this, GlobalContext* globalCtx) { this->actor.scale.y = 0.015f; this->actor.scale.z = 0.0f; - if (this->cutsceneSubCamId != SUBCAM_FREE) { + if (this->cutsceneSubCamId != CAM_ID_MAIN) { Vec3f subCamEye; subCamEye.x = ((this->actor.world.pos.x - this->fires[0].pos.x) * 1.8f) + this->actor.world.pos.x; @@ -383,7 +375,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,10 +394,10 @@ 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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); this->actionFunc = EnBigpo_SpawnCutsceneStage6; } @@ -420,7 +412,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; @@ -449,7 +441,7 @@ void EnBigpo_SpawnCutsceneStage6(EnBigpo* this, GlobalContext* globalCtx) { void EnBigpo_SpawnCutsceneStage7(EnBigpo* this) { this->idleTimer = 15; if (this->unkBool204 == false) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); this->unkBool204 = true; } this->actionFunc = EnBigpo_SpawnCutsceneStage8; @@ -468,10 +460,10 @@ void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx) { this->idleTimer--; if (this->idleTimer == 0) { subCam = Play_GetCamera(globalCtx, this->cutsceneSubCamId); - Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye); - this->cutsceneSubCamId = SUBCAM_FREE; + Play_CameraSetAtEye(globalCtx, CAM_ID_MAIN, &subCam->at, &subCam->eye); + this->cutsceneSubCamId = CAM_ID_MAIN; 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; @@ -491,9 +483,9 @@ void EnBigpo_SetupWarpOut(EnBigpo* this) { this->collider.base.ocFlags1 &= ~OC1_ON; this->rotVelocity = 0x2000; this->idleTimer = 32; - this->actor.flags &= ~0x1; // targetable OFF + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DISAPPEAR); this->actionFunc = EnBigpo_WarpingOut; } @@ -515,8 +507,8 @@ void EnBigpo_SetupWarpIn(EnBigpo* this, GlobalContext* globalCtx) { f32 distance = CLAMP_MIN(this->actor.xzDistToPlayer, 200.0f); s16 randomYaw = (Rand_Next() >> 0x14) + this->actor.yawTowardsPlayer; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); - Animation_PlayLoop(&this->skelAnime, &D_06001360); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + 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; @@ -535,7 +527,7 @@ void EnBigpo_WarpingIn(EnBigpo* this, GlobalContext* globalCtx) { if (this->idleTimer == 32) { this->mainColor.a = 255; // fully visible if (this->unkBool204 == false) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); this->unkBool204 = true; } EnBigpo_SetupIdleFlying(this); @@ -543,7 +535,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; @@ -552,7 +544,7 @@ void EnBigpo_SetupIdleFlying(EnBigpo* this) { this->actor.world.rot.y = this->actor.shape.rot.y; this->collider.base.acFlags |= AC_ON; this->collider.base.ocFlags1 |= OC1_ON; - this->actor.flags |= 0x1; // targetable ON + this->actor.flags |= ACTOR_FLAG_1; // targetable ON this->actionFunc = EnBigpo_IdleFlying; } @@ -654,8 +646,8 @@ void EnBigpo_SpinningDown(EnBigpo* this, GlobalContext* globalCtx) { * called by EnBigpo_ApplyDamage */ void EnBigpo_HitStun(EnBigpo* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06000454, -6.0f); - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x10); + Animation_MorphToPlayOnce(&this->skelAnime, &gBigpoShockAnim, -6.0f); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 0x10); this->collider.base.acFlags &= ~AC_ON; func_800BE504(&this->actor, &this->collider); this->actionFunc = EnBigpo_CheckHealth; @@ -691,36 +683,36 @@ void EnBigpo_SetupDeath(EnBigpo* this) { void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx) { Vec3f tempVec; f32 unkTemp2; // dont really know what these unktemps are doing - s16 cam; + s16 camYaw; s16 unkTemp; s16 modifiedTimer; this->idleTimer++; if (this->idleTimer < 8) { - cam = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) + 0x4800; + camYaw = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x4800; if (this->idleTimer < 5) { unkTemp = (this->idleTimer << 0xC) - 0x4000; // 1.4.0...1 is NOT 1.4, the rodata demands it tempVec.y = (((Math_SinS(unkTemp) * 23.0f) + 40.0f) * 1.4000001f) + this->actor.world.pos.y; unkTemp2 = Math_CosS(unkTemp) * 32.2f; - tempVec.x = (Math_SinS(cam) * unkTemp2) + this->actor.world.pos.x; - tempVec.z = (Math_CosS(cam) * unkTemp2) + this->actor.world.pos.z; + tempVec.x = (Math_SinS(camYaw) * unkTemp2) + this->actor.world.pos.x; + tempVec.z = (Math_CosS(camYaw) * unkTemp2) + this->actor.world.pos.z; } else { tempVec.y = this->actor.world.pos.y + ((40.0f + (15.0f * (this->idleTimer - 5))) * 1.4000001f); - tempVec.x = (Math_SinS(cam) * 32.2f) + this->actor.world.pos.x; - tempVec.z = (Math_CosS(cam) * 32.2f) + this->actor.world.pos.z; + tempVec.x = (Math_SinS(camYaw) * 32.2f) + this->actor.world.pos.x; + tempVec.z = (Math_CosS(camYaw) * 32.2f) + this->actor.world.pos.z; } // 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); @@ -735,16 +727,16 @@ void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx) { func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); // burning sfx } if (this->idleTimer == 18) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); } } void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx) { this->actor.draw = EnBigpo_DrawLantern; this->actor.shape.shadowDraw = NULL; - this->actor.world.pos.x = this->drawMtxF.wx; - this->actor.world.pos.y = this->drawMtxF.wy; - this->actor.world.pos.z = this->drawMtxF.wz; + this->actor.world.pos.x = this->drawMtxF.xw; + this->actor.world.pos.y = this->drawMtxF.yw; + this->actor.world.pos.z = this->drawMtxF.zw; Actor_SetScale(&this->actor, 0.014f); this->actor.gravity = -1.0f; @@ -753,7 +745,7 @@ void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx) { this->actor.velocity.y = 0.0f; this->actor.world.pos.y -= 15.0f; func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_MISC); - this->actor.flags &= ~(0x1 | 0x4); // targetable OFF, enemy music OFF + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); // targetable OFF, enemy music OFF this->actor.bgCheckFlags &= ~0x400; this->actionFunc = EnBigpo_LanternFalling; } @@ -761,10 +753,11 @@ void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx) { void EnBigpo_LanternFalling(EnBigpo* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 1 || this->actor.floorHeight == BGCHECK_Y_MIN) { if (this->switchFlags != 0xFF) { - Actor_SetSwitchFlag(globalCtx, this->switchFlags); + Flags_SetSwitch(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); } } @@ -782,7 +775,6 @@ void EnBigpo_AdjustPoAlpha(EnBigpo* this, s32 alphaDiff) { this->actor.scale.x = newXYScale; this->actor.scale.z = newXYScale; this->actor.scale.y = (0.007f - (0.007f * lowerAlpha)) + 0.007f; - lowerAlpha = lowerAlpha; } else { Actor_SetScale(&this->actor, lowerAlpha * 0.007f); this->actor.world.pos.y = this->savedHeight + (lowerAlpha * 15.0f); @@ -805,7 +797,7 @@ void EnBigpo_SpawnScoopSoul(EnBigpo* this) { this->actor.scale.x = 0.0f; this->actor.scale.y = 0.0f; this->savedHeight = this->actor.world.pos.y; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND); // misnamed? + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_METAL_BOX_BOUND); // misnamed? this->actionFunc = EnBigpo_ScoopSoulAppearing; } @@ -819,9 +811,9 @@ void EnBigpo_ScoopSoulAppearing(EnBigpo* this, GlobalContext* globalCtx) { void EnBigpo_SetupScoopSoulIdle(EnBigpo* this) { this->savedHeight = this->actor.world.pos.y; - Actor_SetHeight(&this->actor, -10.0f); - this->idleTimer = 400; // 20 seconds - this->actor.flags |= 0x1; // targetable ON + Actor_SetFocus(&this->actor, -10.0f); + this->idleTimer = 400; // 20 seconds + this->actor.flags |= ACTOR_FLAG_1; // targetable ON this->actionFunc = EnBigpo_ScoopSoulIdle; } @@ -831,16 +823,16 @@ void EnBigpo_ScoopSoulIdle(EnBigpo* this, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); } else if (this->idleTimer == 0) { // took too long, soul is leaving - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); EnBigpo_SetupScoopSoulLeaving(this); } else { - func_800B8A1C(&this->actor, globalCtx, 0xBA, 35.0f, 60.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 35.0f, 60.0f); this->actor.world.pos.y = (sin_rad(this->idleTimer * (M_PI / 20)) * 5.0f) + this->savedHeight; } } void EnBigpo_SetupScoopSoulLeaving(EnBigpo* this) { - this->actor.flags &= ~(0x1 | 0x10000); // targetable OFF and unknown OFF + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_10000); // targetable OFF and unknown OFF this->actionFunc = EnBigpo_ScoopSoulFadingAway; } @@ -852,7 +844,7 @@ void EnBigpo_ScoopSoulFadingAway(EnBigpo* this, GlobalContext* globalCtx) { } void EnBigpo_InitDampeMainPo(EnBigpo* this) { - this->actor.flags &= ~0x1; // targetable OFF + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF this->actionFunc = EnBigpo_SelectRandomFireLocations; } @@ -898,7 +890,7 @@ void EnBigpo_SelectRandomFireLocations(EnBigpo* this, GlobalContext* globalCtx) randomFirePo->actor.update = EnBigpo_UpdateFire; func_800BC154(globalCtx, &globalCtx->actorCtx, &randomFirePo->actor, ACTORCAT_PROP); randomFirePo->unk20C = fireIndex; - randomFirePo->actor.flags &= ~0x1; // targetable OFF + randomFirePo->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF // make invisible by size: 0 Actor_SetScale(&randomFirePo->actor, 0); @@ -962,7 +954,7 @@ void EnBigpo_SetupFlameCirclePositions(EnBigpo* this, GlobalContext* globalCtx) } // Setup sub camera - if (this->cutsceneSubCamId != SUBCAM_FREE) { + if (this->cutsceneSubCamId != CAM_ID_MAIN) { subCamEye.x = (Math_SinS(this->actor.yawTowardsPlayer) * 360.0f) + this->actor.world.pos.x; subCamEye.y = this->actor.world.pos.y + 150.0f; subCamEye.z = (Math_CosS(this->actor.yawTowardsPlayer) * 360.0f) + this->actor.world.pos.z; @@ -1021,7 +1013,6 @@ void EnBigpo_RevealedFireIdle(EnBigpo* this, GlobalContext* globalCtx) { if (this->idleTimer == 0) { //! @bug: unreachable code this->actor.params = ENBIGPO_UNK5; - return; } } else { if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.001f)) { @@ -1054,7 +1045,7 @@ void EnBigpo_FlameCircleCutscene(EnBigpo* this, GlobalContext* globalCtx) { this->idleTimer--; if (this->idleTimer == 0) { EnBigpo* parentPoh = (EnBigpo*)this->actor.parent; - Actor_SetSwitchFlag(globalCtx, this->switchFlags); + Flags_SetSwitch(globalCtx, this->switchFlags); Math_Vec3f_Copy(&parentPoh->fires[this->unk20C].pos, &this->actor.world.pos); Actor_MarkForDeath(&this->actor); if (this->unk20C == 0) { @@ -1096,7 +1087,7 @@ void EnBigpo_UpdateColor(EnBigpo* this) { // this might be a triple ternary but it matches and is easier to read spread out bplus5 = this->mainColor.b + 5; - if (this->mainColor.b >= 211) { + if (this->mainColor.b > 210) { bminus5 = this->mainColor.b - 5; if (bminus5 < 210) { this->mainColor.b = 210; @@ -1104,7 +1095,7 @@ void EnBigpo_UpdateColor(EnBigpo* this) { this->mainColor.b = bminus5; } } else { - if (bplus5 >= 211) { + if (bplus5 > 210) { this->mainColor.b = 210; } else { this->mainColor.b = bplus5; @@ -1131,20 +1122,20 @@ s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx) { } if (Actor_ApplyDamage(&this->actor) == 0) { - this->actor.flags &= ~0x1; // targetable OFF - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD); + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DEAD); Enemy_StartFinishingBlow(globalCtx, &this->actor); if (this->actor.params == ENBIGPO_SUMMONED) { // dampe type func_801A2ED8(); } } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DAMAGE); } // light arrows if (this->actor.colChkInfo.damageEffect == 4) { - this->unk21C = 4.0f; - this->unk220 = 1.0f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 1.0f; 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); @@ -1156,11 +1147,11 @@ s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx) { } void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; s32 pad; ColliderCylinder* thisCollider; - if ((this->actor.flags & 0x2000) == 0x2000) { + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { this->hoverHeightCycleTimer = 0; this->savedHeight = this->actor.world.pos.y; } @@ -1173,23 +1164,23 @@ void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk20C = 0; } if (this->unk20C == 40) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); EnBigpo_SetupWarpOut(this); } } this->actionFunc(this, globalCtx); if ((this->actionFunc != EnBigpo_SpawnCutsceneStage6) && (this->actionFunc != EnBigpo_SpawnCutsceneStage4)) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } if (this->actionFunc == EnBigpo_LanternFalling) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 27.0f, 60.0f, 4); } if (this->actor.draw == EnBigpo_DrawScoopSoul) { - Actor_SetHeight(&this->actor, -10.0f); + Actor_SetFocus(&this->actor, -10.0f); } else { - Actor_SetHeight(&this->actor, 42.0f); + Actor_SetFocus(&this->actor, 42.0f); } EnBigpo_UpdateColor(this); @@ -1208,15 +1199,15 @@ void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &thisCollider->base); } - if (this->unk21C > 0.0f) { - Math_StepToF(&this->unk21C, 0.0f, 0.05f); + if (this->drawDmgEffAlpha > 0.0f) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); if (this->mainColor.a != 255) { // NOT fully visible if (this->mainColor.a * (1.0f / 255.0f) < this->mainColor.a) { - this->unk21C = this->mainColor.a * (1.0f / 255.0f); + this->drawDmgEffAlpha = this->mainColor.a * (1.0f / 255.0f); } } - this->unk220 = ((this->unk21C + 1.0f) * 0.5f); - this->unk220 = CLAMP_MAX(this->unk220, 1.0f); + this->drawDmgEffScale = ((this->drawDmgEffAlpha + 1.0f) * 0.5f); + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 1.0f); } } @@ -1224,24 +1215,25 @@ void EnBigpo_Update(Actor* thisx, GlobalContext* globalCtx) { * alt update func: the revealed fires under dampe's house */ void EnBigpo_UpdateFire(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; - this->actor.shape.rot.y = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); + EnBigpo* this = THIS; + + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); this->actionFunc(this, globalCtx); } -s32 EnBigpo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* actor, +s32 EnBigpo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { - EnBigpo* this = (EnBigpo*)actor; + EnBigpo* this = THIS; // not fully invisible if (!(this->mainColor.a != 0 && limbIndex != 7) || (this->actionFunc == EnBigpo_BurnAwayDeath && this->idleTimer >= 2)) { *dList = NULL; } - return 0; + return false; } -void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* actor, Gfx** gfx) { - EnBigpo* this = (EnBigpo*)actor; +void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnBigpo* this = THIS; s8 limbByte; Vec3f* v1ptr; // todo: figure out better names Vec3f* v2ptr; @@ -1252,51 +1244,46 @@ 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) { // we scale the vec3f... then do nothing with it? - Matrix_GetStateTranslationAndScaledY(1400.0f, &unusedVec); + Matrix_MultVecY(1400.0f, &unusedVec); if ((this->actionFunc == EnBigpo_BurnAwayDeath) && (this->idleTimer > 18)) { if (this->actor.scale.x != 0.0f) { Matrix_Scale(0.014f / this->actor.scale.x, 0.014f / this->actor.scale.x, 0.014f / this->actor.scale.x, 1); } } - Matrix_CopyCurrentState(&this->drawMtxF); + Matrix_Get(&this->drawMtxF); } limbByte = D_80B65078[limbIndex]; if (limbByte != -1) { if (limbByte < 3) { - Matrix_GetStateTranslation(&this->limbPos[limbByte]); - return; - } - if (limbByte == 3) { - Matrix_GetStateTranslationAndScaledX(3000.0f, &this->limbPos[limbByte]); - return; - } - if (limbByte == 4) { - Matrix_GetStateTranslationAndScaledY(-2000.0f, &this->limbPos[limbByte]); - return; - } + Matrix_MultZero(&this->limbPos[limbByte]); + } else if (limbByte == 3) { + Matrix_MultVecX(3000.0f, &this->limbPos[limbByte]); + } else if (limbByte == 4) { + Matrix_MultVecY(-2000.0f, &this->limbPos[limbByte]); + } else { + v2ptr = &this->limbPos[limbByte + 1]; + v1ptr = D_80B65084; + Matrix_MultVecX(-4000.0f, &this->limbPos[limbByte]); - v2ptr = &this->limbPos[limbByte + 1]; - v1ptr = D_80B65084; - Matrix_GetStateTranslationAndScaledX(-4000.0f, &this->limbPos[limbByte]); - - for (i = limbByte + 1; i < ARRAY_COUNT(this->limbPos); i++) { - Matrix_MultiplyVector3fByState(v1ptr, v2ptr); - v2ptr++; - v1ptr++; + for (i = limbByte + 1; i < ARRAY_COUNT(this->limbPos); i++) { + Matrix_MultVec3f(v1ptr, v2ptr); + v2ptr++; + v1ptr++; + } } } CLOSE_DISPS(globalCtx->state.gfxCtx); } void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; Gfx* dispHead; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -1305,7 +1292,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 +1302,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)); @@ -1324,10 +1311,11 @@ void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { } // 71.428566f might be 500/7 context unknown - func_800BE680(globalCtx, &this->actor, this->limbPos, 9, this->actor.scale.x * 71.428566f * this->unk220, 0, - this->unk21C, 0x14); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->actor.scale.x * 71.428566f * this->drawDmgEffScale, 0.0f, this->drawDmgEffAlpha, + ACTOR_DRAW_DMGEFF_LIGHT_ORBS); - Matrix_SetCurrentState(&this->drawMtxF); + Matrix_Put(&this->drawMtxF); EnBigpo_DrawLantern(&this->actor, globalCtx); if (this->actionFunc == EnBigpo_SpawnCutsceneStage6) { EnBigpo_DrawCircleFlames(&this->actor, globalCtx); @@ -1337,7 +1325,7 @@ void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { } void EnBigpo_DrawScoopSoul(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; s32 pad; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -1356,21 +1344,17 @@ void EnBigpo_DrawScoopSoul(Actor* thisx, GlobalContext* globalCtx) { this->actor.world.pos.z, this->mainColor.r, this->mainColor.g, this->mainColor.b, this->mainColor.a * 2); - Matrix_RotateY(BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))), MTXMODE_APPLY); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), 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_06001BB0); + gSPDisplayList(POLY_XLU_DISP++, &gBigpoDrawSoulDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } -/* - * this matches without OPENDISPS but with it has stack issues, - * might be able to find an alternative match with the macros, so far no success - */ void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; f32 magnitude; f32 magnitude2; Gfx* dispHead; @@ -1384,59 +1368,58 @@ 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); } - { - GraphicsContext* gfx = globalCtx->state.gfxCtx; + OPEN_DISPS(globalCtx->state.gfxCtx); - // fully visible OR fully transparent - if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { - Scene_SetRenderModeXlu(globalCtx, 0, 1); - dispHead = gfx->polyOpa.p; - } else { - Scene_SetRenderModeXlu(globalCtx, 1, 2); - dispHead = gfx->polyXlu.p; - } - - gSPDisplayList(&dispHead[0], &sSetupDL[6 * 0x19]); - - gSPSegment(&dispHead[1], 0x0A, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 0, 255, this->mainColor.a)); - - Matrix_GetStateTranslationAndScaledY(1400.0f, &vec2); - Lights_PointGlowSetInfo(&this->fires[0].info, vec2.x + vec1.x, vec2.y + vec1.y, vec2.z + vec1.z, - this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, this->lanternColor.a); - - gDPSetEnvColor(&dispHead[2], this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, - this->mainColor.a); - - gSPMatrix(&dispHead[3], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - - gSPDisplayList(&dispHead[4], &D_060042C8); - - gSPDisplayList(&dispHead[5], &D_060043F8); - - // fully transparent OR fully invisible - if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { - gfx->polyOpa.p = &dispHead[6]; - } else { - gfx->polyXlu.p = &dispHead[6]; - } + // fully visible OR fully transparent + if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { + Scene_SetRenderModeXlu(globalCtx, 0, 1); + dispHead = POLY_OPA_DISP; + } else { + Scene_SetRenderModeXlu(globalCtx, 1, 2); + dispHead = POLY_XLU_DISP; } + + gSPDisplayList(&dispHead[0], &sSetupDL[6 * 0x19]); + + gSPSegment(&dispHead[1], 0x0A, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 0, 255, this->mainColor.a)); + + Matrix_MultVecY(1400.0f, &vec2); + Lights_PointGlowSetInfo(&this->fires[0].info, vec2.x + vec1.x, vec2.y + vec1.y, vec2.z + vec1.z, + this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, this->lanternColor.a); + + gDPSetEnvColor(&dispHead[2], this->lanternColor.r, this->lanternColor.g, this->lanternColor.b, this->mainColor.a); + + gSPMatrix(&dispHead[3], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(&dispHead[4], &gBigpoDrawLanternMainDL); + + gSPDisplayList(&dispHead[5], &gBigpoDrawLanternPurpleTopDL); + + // fully transparent OR fully invisible + if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { + POLY_OPA_DISP = &dispHead[6]; + } else { + POLY_XLU_DISP = &dispHead[6]; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); } void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; s32 pad[3]; s16 fireRadius; MtxF* mtfxPtr; s32 i; - mtfxPtr = Matrix_GetCurrentState(); + mtfxPtr = Matrix_GetCurrent(); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_RotateY(BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))), MTXMODE_NEW); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), MTXMODE_NEW); if (this->actionFunc == EnBigpo_SpawnCutsceneStage6) { Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); fireRadius = 500; @@ -1453,22 +1436,23 @@ void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx) { for (i = 0; i < ARRAY_COUNT(this->fires); i++) { EnBigpoFireEffect* firePtr = &this->fires[i]; + Lights_PointNoGlowSetInfo(&this->fires[i].info, this->fires[i].pos.x, this->fires[i].pos.y, this->fires[i].pos.z, 170, 255, 255, fireRadius); - mtfxPtr->wx = firePtr->pos.x; - mtfxPtr->wy = firePtr->pos.y; - mtfxPtr->wz = firePtr->pos.z; + mtfxPtr->xw = firePtr->pos.x; + mtfxPtr->yw = firePtr->pos.y; + mtfxPtr->zw = firePtr->pos.z; 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); } void EnBigpo_RevealedFire(Actor* thisx, GlobalContext* globalCtx) { - EnBigpo* this = (EnBigpo*)thisx; + EnBigpo* this = THIS; EnBigpo* parent = (EnBigpo*)thisx->parent; s32 pad; @@ -1488,7 +1472,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_Bigpo/z_en_bigpo.h b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h index 9ae87f9f3..c5d0bbe4c 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.h @@ -40,9 +40,8 @@ typedef struct EnBigpo { /* 0x212 */ s16 hoverHeightCycleTimer; // sin wave up and down bobbing /* 0x214 */ f32 fireRadius; // distance from center during conjunction cutscene /* 0x218 */ f32 savedHeight; // actual height while flying moves as part of bobbing - // both unk21C and unk220 are passed to func_800BE680, probably need that to know what they are - /* 0x21C */ f32 unk21C; // tied to color alpha, decremented to zero - /* 0x220 */ f32 unk220; // created from unk21C + /* 0x21C */ f32 drawDmgEffAlpha; + /* 0x220 */ f32 drawDmgEffScale; /* 0x224 */ Vec3f limbPos[9]; /* 0x290 */ Color_RGBA8 mainColor; /* 0x294 */ Color_RGBA8 lanternColor; 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 6aaa77956..1a507b5b6 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c @@ -1,45 +1,214 @@ -#include "z_en_bigslime.h" +/* + * File: z_en_bigslime.c + * Overlay: ovl_En_Bigslime + * Description: Mad Jelly & Gekko Miniboss: Fused Jellies & Gekko + */ -#define FLAGS 0x00000235 +#include "z_en_bigslime.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/object_bigslime/object_bigslime.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_200) #define THIS ((EnBigslime*)thisx) 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, @@ -48,289 +217,2941 @@ 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* globalCtx2) { + // gSaveContext.save.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 + }; + GlobalContext* globalCtx = globalCtx2; + EnBigslime* this = THIS; + 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 (Flags_GetClear(globalCtx, globalCtx->roomCtx.currRoom.num)) { + Actor_MarkForDeath(&this->actor); + if (!(gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->actor.params - 1] >> 8] & + (u8)isFrogReturnedFlags[this->actor.params - 1])) { + Actor_Spawn(&globalCtx->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(&globalCtx->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 &= ~ACTOR_FLAG_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); + Audio_StopSfxByPos(&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 &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_400); + this->actor.flags |= ACTOR_FLAG_200; + this->actor.hintId = 95; + this->gekkoRot.x = 0; + this->gekkoRot.y = 0; + this->actor.bgCheckFlags &= ~1; + this->formBigslimeTimer = 2; + EnBigslime_AddIceShardEffect(this, globalCtx); + Actor_PlaySfxAtPos(&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 != CAM_ID_MAIN) { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Play_CameraSetAtEye(globalCtx, CAM_ID_MAIN, &subCam->at, &subCam->eye); + this->subCamId = CAM_ID_MAIN; + 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.lightSettingOverride = 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) { + Audio_PlaySfxAtPos(&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->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->gekkoCollider.base.colType = COLTYPE_HIT3; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK0; + this->stunTimer = 2; + this->gekkoDrawDmgEffScale = 0.75f; + this->gekkoDrawDmgEffFrozenSteamScale = 1.125f; + this->gekkoDrawDmgEffAlpha = 1.0f; + this->actor.flags &= ~ACTOR_FLAG_200; +} + +void EnBigslime_GekkoThaw(EnBigslime* this, GlobalContext* globalCtx) { + if (this->gekkoDrawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->gekkoCollider.base.colType = COLTYPE_HIT6; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK1; + this->gekkoDrawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); + this->actor.flags |= ACTOR_FLAG_200; + } +} + +void EnBigslime_SetupCutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + + globalCtx->envCtx.lightSettingOverride = 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 |= ACTOR_FLAG_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.lightSettingOverride = 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 != CAM_ID_MAIN) { + 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 &= ~ACTOR_FLAG_200; + 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 != CAM_ID_MAIN) { + 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) { + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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, CAM_ID_MAIN); + 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 = Camera_GetCamDirYaw(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); + Actor_PlaySfxAtPos(&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.save.playerData.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, player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S); + 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) { + Actor_PlaySfxAtPos(&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.lightSettingOverride = 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 |= ACTOR_FLAG_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 (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { + this->actor.flags &= ~ACTOR_FLAG_2000; + } + + 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->gekkoDrawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + 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--; + Actor_PlaySfxAtPos(&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 &= ~ACTOR_FLAG_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 = Camera_GetCamDirYaw(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; + + SoundSource_PlaySfxAtFixedWorldPos(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) { + Flags_SetClearTemp(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.lightSettingOverride = 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->gekkoDrawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(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->gekkoDrawDmgEffAlpha = 4.0f; + this->gekkoDrawDmgEffScale = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else { + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->gekkoDrawDmgEffScale = 0.75f; + this->gekkoDrawDmgEffAlpha = 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; + Actor_PlaySfxAtPos(&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->gekkoDrawDmgEffAlpha = 3.0f; + this->gekkoDrawDmgEffScale = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else { + this->gekkoDrawDmgEffType = ACTOR_DRAW_DMGEFF_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); + } + } + + Actor_PlaySfxAtPos(&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->gekkoDrawDmgEffAlpha > 0.0f) { + if ((this->gekkoDrawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->actionFunc != EnBigslime_PlayCutscene)) { + Math_StepToF(&this->gekkoDrawDmgEffAlpha, 0.0f, 0.05f); + this->gekkoDrawDmgEffScale = 0.375f * (this->gekkoDrawDmgEffAlpha + 1.0f); + this->gekkoDrawDmgEffScale = CLAMP_MAX(this->gekkoDrawDmgEffScale, 0.75f); + } else if (!Math_StepToF(&this->gekkoDrawDmgEffFrozenSteamScale, 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.lightSettingOverride == 3) { + globalCtx->envCtx.lightSettingOverride = 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_MoveWithGravity(&this->actor); + } else { + Actor_MoveWithoutGravity(&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.lightSettingOverride == 3) { + globalCtx->envCtx.lightSettingOverride = 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_MoveWithGravity(&this->actor); + } else { + Actor_MoveWithoutGravity(&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 zx; + MtxF* sysMatrix = Matrix_GetCurrent(); + + 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); + zx = 1.0f - (yDistMinY * (1.0f / 1550.0f)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + sysMatrix->xx = zx; + sysMatrix->yy = 1.0f; + sysMatrix->zz = zx; + sysMatrix->zx = sysMatrix->yx = 0.0f; + sysMatrix->zy = sysMatrix->xy = 0.0f; + sysMatrix->yz = sysMatrix->xz = 0.0f; + sysMatrix->xw = pos->x; + sysMatrix->yw = GBT_ROOM_5_MIN_Y; + sysMatrix->zw = pos->z; + sysMatrix->wx = sysMatrix->wy = sysMatrix->wz = 0.0f; + sysMatrix->ww = 1.0f; + + Matrix_RotateYS(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 * zx)); + 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* globalCtx2) { + EnMinislime* minislime; + GlobalContext* globalCtx = globalCtx2; + 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(&globalCtx->lightCtx, globalCtx->state.gfxCtx); + Lights_BindAll(lights, globalCtx->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_SetTranslateRotateYXZ(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_Translate(0.0f, (0.1f - minislime->frozenScale) * -4000.0f, 0.0f, MTXMODE_APPLY); + 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_Put(&globalCtx->billboardMtxF); + Matrix_Scale(0.0050000003f, 0.0050000003f, 0.0050000003f, MTXMODE_APPLY); + billboardMtxF = Matrix_GetCurrent(); + + for (i = 0; i < 28; i++) { + bubblesInfoPtr = &bubblesInfo[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][bubblesInfoPtr->v]; + billboardMtxF->xw = + dynamicVtx->n.ob[0] * this->actor.scale.x * bubblesInfoPtr->scaleVtx + this->actor.world.pos.x; + billboardMtxF->yw = + dynamicVtx->n.ob[1] * this->actor.scale.y * bubblesInfoPtr->scaleVtx + this->actor.world.pos.y; + billboardMtxF->zw = + 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_MultZero(&this->actor.focus.pos); + this->actor.focus.rot.y = this->gekkoRot.y; + } + + if (limbPosIndex[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[limbPosIndex[limbIndex]]); + } + + if (limbIndex == GEKKO_LIMB_R_ANKLE) { + Matrix_MultVec3f(&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->gekkoDrawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + func_800AE434(globalCtx, &gekkoDamageColor, this->stunTimer, 80); + } else if (this->gekkoDrawDmgEffType == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL) { + 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_SetTranslateRotateYXZ(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, gCircleShadowDL, 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); + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->gekkoScale * (999.99991f / 7.0f) * this->gekkoDrawDmgEffScale, + this->gekkoDrawDmgEffFrozenSteamScale, this->gekkoDrawDmgEffAlpha, + this->gekkoDrawDmgEffType); +} + +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_Translate(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_SetTranslateRotateYXZ(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..579ec5d50 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h @@ -63,8 +63,8 @@ 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; - /* 0x02B5 */ u8 gekkoDrawEffect; + /* 0x02B4 */ u8 shockwaveAlpha; + /* 0x02B5 */ u8 gekkoDrawDmgEffType; /* 0x02B6 */ s16 gekkoYaw; /* 0x02B8 */ s16 cutscene; /* 0x02BA */ union { // multi-use timer @@ -95,33 +95,33 @@ 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; - /* 0x02CA */ s16 rotation; // is always 0, used in Matrix_RotateY + /* 0x02C6 */ s16 subCamId; + /* 0x02C8 */ s16 subCamYawGrabPlayer; + /* 0x02CA */ s16 rotation; // is always 0, used in Matrix_RotateYS /* 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 - /* 0x038C */ f32 unk_38C; // used as arg to func_800BE680 - /* 0x0390 */ f32 unk_390; // used as arg to func_800BE680 + /* 0x0388 */ f32 gekkoDrawDmgEffAlpha; + /* 0x038C */ f32 gekkoDrawDmgEffScale; + /* 0x0390 */ f32 gekkoDrawDmgEffFrozenSteamScale; /* 0x0394 */ f32 gekkoScale; /* 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 45370609b..c60971034 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 @@ -5,8 +5,9 @@ */ #include "z_en_bji_01.h" +#include "objects/object_bji/object_bji.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBji01*)thisx) @@ -26,17 +27,9 @@ void func_809CD6C0(EnBji01* this, GlobalContext* globalCtx); void func_809CD70C(EnBji01* this, GlobalContext* globalCtx); void func_809CD77C(EnBji01* this, GlobalContext* globalCtx); -s32 EnBji01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg); -void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg); - -extern AnimationHeader D_06000FDC; -extern AnimationHeader D_06005B58; -extern AnimationHeader D_06000AB0; -extern AnimationHeader D_0600066C; -extern void* D_060049F0[]; -extern void* D_06004E70[]; -extern void* D_06005270[]; -extern FlexSkeletonHeader D_0600578C; +s32 EnBji01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx); +void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); const ActorInit En_Bji_01_InitVars = { ACTOR_EN_BJI_01, @@ -71,27 +64,27 @@ static ColliderCylinderInit sCylinderInit = { }; /* Animations struct */ -static struct_80B8E1A8 D_809CDC7C[] = { - { &D_06000FDC, 1.0f, 0, 0.0f }, /* Looking through telescope */ - { &D_06005B58, 1.0f, 0, 10.0f }, /* Breathing? Unused? */ - { &D_06000AB0, 1.0f, 0, 0.0f }, /* Talking */ - { &D_0600066C, 1.0f, 2, -5.0f }, /* Scratching chin? */ +static AnimationSpeedInfo D_809CDC7C[] = { + { &object_bji_Anim_000FDC, 1.0f, ANIMMODE_LOOP, 0.0f }, /* Looking through telescope */ + { &object_bji_Anim_005B58, 1.0f, ANIMMODE_LOOP, 10.0f }, /* Breathing? Unused? */ + { &object_bji_Anim_000AB0, 1.0f, ANIMMODE_LOOP, 0.0f }, /* Talking */ + { &object_bji_Anim_00066C, 1.0f, ANIMMODE_ONCE, -5.0f }, /* Scratching chin? */ }; void func_809CCDE0(EnBji01* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp58; + Vec3f pitchTarget; s32 pad[2]; - Math_Vec3f_Copy(&sp58, &player->actor.world.pos); - sp58.y = player->bodyPartsPos[7].y + 3.0f; - func_8013E950(&this->actor.world.pos, &this->actor.focus.pos, this->actor.shape.rot.y, &player->actor.world.pos, - &sp58, &this->headZRotAdj, &this->headXRotAdj, &this->torsoZRotAdj, &this->torsoXRotAdj, 0x1554, - 0x1FFE, 0xE38, 0x1C70); + Math_Vec3f_Copy(&pitchTarget, &player->actor.world.pos); + pitchTarget.y = player->bodyPartsPos[7].y + 3.0f; + SubS_TurnToPointStep(&this->actor.world.pos, &this->actor.focus.pos, this->actor.shape.rot.y, + &player->actor.world.pos, &pitchTarget, &this->headZRotStep, &this->headXRotStep, + &this->torsoZRotStep, &this->torsoXRotStep, 0x1554, 0x1FFE, 0xE38, 0x1C70); } void func_809CCE98(EnBji01* this, GlobalContext* globalCtx) { - func_8013E1C8(&this->skelAnime, D_809CDC7C, 0, &this->animationIndex); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_809CDC7C, 0, &this->animationIndex); this->actor.textId = 0; this->actionFunc = func_809CCEE8; } @@ -99,14 +92,14 @@ void func_809CCE98(EnBji01* this, GlobalContext* globalCtx) { void func_809CCEE8(EnBji01* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 0x444); if (this->actor.params == ENBJI01_PARAMS_DEFAULT) { - if ((this->actor.xzDistToPlayer <= 60.0f) && (this->actor.yDistToPlayer <= 10.0f)) { - this->actor.flags |= 0x10000; + if ((this->actor.xzDistToPlayer <= 60.0f) && (this->actor.playerHeightRel <= 10.0f)) { + this->actor.flags |= ACTOR_FLAG_10000; } else { - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } } - if (func_800B84D0(&this->actor, globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.msgMode = 0; globalCtx->msgCtx.unk11F10 = 0; func_809CD028(this, globalCtx); } else { @@ -116,63 +109,62 @@ 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); + func_800B8500(&this->actor, globalCtx, 60.0f, 10.0f, EXCH_ITEM_NONE); } } void func_809CD028(EnBji01* this, GlobalContext* globalCtx) { - s32 tempDay; - f32 tempTimeBeforeMoonCrash; + f32 timeBeforeMoonCrash; switch (this->actor.params) { case ENBJI01_PARAMS_DEFAULT: case ENBJI01_PARAMS_FINISHED_CONVERSATION: - switch (gSaveContext.playerForm) { + switch (gSaveContext.save.playerForm) { case PLAYER_FORM_DEKU: - if (gSaveContext.weekEventReg[17] & 0x10) { - if (gSaveContext.weekEventReg[74] & 0x80) { + if (gSaveContext.save.weekEventReg[17] & 0x10) { + if (gSaveContext.save.weekEventReg[74] & 0x80) { this->textId = 0x5F4; } else { this->textId = 0x5E2; } } else { this->textId = 0x5EC; - gSaveContext.weekEventReg[17] |= 0x10; + gSaveContext.save.weekEventReg[17] |= 0x10; } break; case PLAYER_FORM_HUMAN: if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { this->textId = 0x236A; - } else if (gSaveContext.weekEventReg[74] & 0x10) { + } else if (gSaveContext.save.weekEventReg[74] & 0x10) { this->textId = 0x5F6; } else { this->textId = 0x5F5; - gSaveContext.weekEventReg[74] |= 0x10; + gSaveContext.save.weekEventReg[74] |= 0x10; } break; case PLAYER_FORM_GORON: case PLAYER_FORM_ZORA: - if (gSaveContext.weekEventReg[75] & 8) { + if (gSaveContext.save.weekEventReg[75] & 8) { this->textId = 0x5E4; } else { this->textId = 0x5DC; - gSaveContext.weekEventReg[75] |= 8; + gSaveContext.save.weekEventReg[75] |= 8; } break; } break; case ENBJI01_PARAMS_LOOKED_THROUGH_TELESCOPE: - switch (gSaveContext.playerForm) { + switch (gSaveContext.save.playerForm) { case PLAYER_FORM_DEKU: - if (gSaveContext.weekEventReg[74] & 0x80) { + if (gSaveContext.save.weekEventReg[74] & 0x80) { this->textId = 0x5F2; } else { this->textId = 0x5F1; } - func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.yDistToPlayer, 0); + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, + EXCH_ITEM_NONE); break; case PLAYER_FORM_HUMAN: this->textId = 0x5F7; @@ -187,10 +179,11 @@ void func_809CD028(EnBji01* this, GlobalContext* globalCtx) { this->textId = 0x5EA; break; case 3: - tempDay = gSaveContext.day; - tempTimeBeforeMoonCrash = - ((-(tempDay % 5 << 0x10) - ((u16)(gSaveContext.time - 0x4000))) + 0x40000); - if (tempTimeBeforeMoonCrash < 2730.6667f) { /* 1 hr */ + // Calculates the time left before the moon crashes. + // The day begins at CLOCK_TIME(6, 0) so it must be offset. + timeBeforeMoonCrash = (4 - CURRENT_DAY) * DAY_LENGTH - + (u16)(((void)0, gSaveContext.save.time) - CLOCK_TIME(6, 0)); + if (timeBeforeMoonCrash < CLOCK_TIME_F(1, 0)) { this->textId = 0x5E8; } else { this->textId = 0x5EB; @@ -200,22 +193,22 @@ void func_809CD028(EnBji01* this, GlobalContext* globalCtx) { } break; } - func_8013E1C8(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); this->actionFunc = EnBji01_DialogueHandler; } void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x444); func_809CCDE0(this, globalCtx); if (this->actor.shape.rot.y == this->actor.yawTowardsPlayer) { - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); } break; case 4: - if (func_80147624(globalCtx) != 0) { - this->actor.flags &= ~0x10000; + if (Message_ShouldAdvance(globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.params = ENBJI01_PARAMS_FINISHED_CONVERSATION; switch (globalCtx->msgCtx.choiceIndex) { case 0: @@ -225,7 +218,7 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { break; case 1: func_8019F230(); - switch (gSaveContext.playerForm) { + switch (gSaveContext.save.playerForm) { case PLAYER_FORM_DEKU: func_80151938(globalCtx, 0x5F0); break; @@ -242,11 +235,11 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { } break; case 5: - if (func_80147624(globalCtx) != 0) { - this->actor.flags &= ~0x10000; - switch (globalCtx->msgCtx.unk11F04) { + if (Message_ShouldAdvance(globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + switch (globalCtx->msgCtx.currentTextId) { case 0x5DE: - func_8013E1C8(&this->skelAnime, D_809CDC7C, 3, &this->animationIndex); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_809CDC7C, 3, &this->animationIndex); func_80151938(globalCtx, 0x5DF); break; case 0x5E4: @@ -266,7 +259,7 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { case 0x5EE: case 0x5F2: case 0x5F5: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x5F0: case 0x5F6: @@ -283,7 +276,7 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { case 0x5F7: case 0x5F8: func_801477B4(globalCtx); - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.params = ENBJI01_PARAMS_FINISHED_CONVERSATION; func_809CCE98(this, globalCtx); break; @@ -292,12 +285,12 @@ void EnBji01_DialogueHandler(EnBji01* this, GlobalContext* globalCtx) { break; case 6: this->actor.params = ENBJI01_PARAMS_FINISHED_CONVERSATION; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; func_809CCE98(this, globalCtx); break; } if ((this->animationIndex == 3) && (this->skelAnime.curFrame == this->skelAnime.endFrame)) { - func_8013E1C8(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); } } @@ -305,8 +298,8 @@ void func_809CD634(EnBji01* this, GlobalContext* globalCtx) { func_801A5BD0(0x6F); Audio_QueueSeqCmd(0xE0000101); globalCtx->nextEntranceIndex = 0x54A0; /* Termina Field from telescope */ - gSaveContext.respawn[0].entranceIndex = globalCtx->nextEntranceIndex; - func_80169EFC(globalCtx); /* Load new entrance? */ + gSaveContext.respawn[RESTART_MODE_DOWN].entranceIndex = globalCtx->nextEntranceIndex; + func_80169EFC(&globalCtx->state); /* Load new entrance? */ gSaveContext.respawnFlag = -2; this->actionFunc = EnBji01_DoNothing; } @@ -315,7 +308,7 @@ void EnBji01_DoNothing(EnBji01* this, GlobalContext* globalCtx) { } void func_809CD6C0(EnBji01* this, GlobalContext* globalCtx) { - func_8013E1C8(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_809CDC7C, 2, &this->animationIndex); this->actionFunc = func_809CD70C; } @@ -323,7 +316,7 @@ void func_809CD70C(EnBji01* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x444); func_809CCDE0(this, globalCtx); if (this->actor.shape.rot.y == this->actor.yawTowardsPlayer) { - func_800B86C8(&this->moonsTear->actor, globalCtx, &this->actor); /* Z-Target the Moon's Tear? */ + Actor_ChangeFocus(&this->moonsTear->actor, globalCtx, &this->actor); /* Z-Target the Moon's Tear? */ this->actionFunc = func_809CD77C; } } @@ -337,9 +330,9 @@ void func_809CD77C(EnBji01* this, GlobalContext* globalCtx) { void EnBji01_Init(Actor* thisx, GlobalContext* globalCtx) { EnBji01* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600578C, &D_06000FDC, this->jointTable, this->morphTable, - BJI_LIMB_MAX); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_bji_Skel_00578C, &object_bji_Anim_000FDC, this->jointTable, + this->morphTable, BJI_LIMB_MAX); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->actor.colChkInfo.mass = MASS_IMMOVABLE; @@ -348,19 +341,17 @@ void EnBji01_Init(Actor* thisx, GlobalContext* globalCtx) { this->animationIndex = -1; 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); + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); + this->moonsTear = (ObjMoonStone*)SubS_FindActor(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE); - switch (gSaveContext.entranceIndex) { + switch (gSaveContext.save.entranceIndex) { case 0x4C00: /* Observatory from ECT */ case 0x4C10: /* Observatory from Termina Field door */ this->actor.params = ENBJI01_PARAMS_DEFAULT; func_809CCE98(this, globalCtx); break; case 0x4C20: /* Observatory from Termina Field telescope */ - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_801A5BD0(0); Audio_QueueSeqCmd(0xE0000100); this->actor.params = ENBJI01_PARAMS_LOOKED_THROUGH_TELESCOPE; @@ -396,7 +387,7 @@ void EnBji01_Update(Actor* thisx, GlobalContext* globalCtx) { } } - Actor_SetHeight(&this->actor, 40.0f); + Actor_SetFocus(&this->actor, 40.0f); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } @@ -415,12 +406,12 @@ s32 EnBji01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis } switch (limbIndex) { case BJI_LIMB_TORSO: - rot->x += this->torsoXRotAdj; - rot->z += this->torsoZRotAdj; + rot->x += this->torsoXRotStep; + rot->z += this->torsoZRotStep; break; case BJI_LIMB_HEAD: - rot->x += this->headXRotAdj; - rot->z += this->headZRotAdj; + rot->x += this->headXRotStep; + rot->z += this->headZRotStep; break; } return false; @@ -437,12 +428,12 @@ void EnBji01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, sp20.x += temp_f4 * 0.1f; sp20.y += temp_f4 * 0.1f; sp20.z += temp_f4 * 0.1f; - Matrix_MultiplyVector3fByState(&sp20, &this->actor.focus.pos); + Matrix_MultVec3f(&sp20, &this->actor.focus.pos); } } void EnBji01_Draw(Actor* thisx, GlobalContext* globalCtx) { - static void* sEyeTextures[] = { D_060049F0, D_06004E70, D_06005270 }; + static TexturePtr sEyeTextures[] = { object_bji_Tex_0049F0, object_bji_Tex_004E70, object_bji_Tex_005270 }; EnBji01* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.h b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.h index b1ed3f8af..c49da8bd2 100644 --- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.h +++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.h @@ -45,10 +45,10 @@ typedef struct EnBji01 { /* 0x29C */ s16 eyeTexIndex; /* 0x29E */ s16 blinkSeqIndex; /* 0x2A0 */ s16 blinkTimer; - /* 0x2A2 */ s16 torsoZRotAdj; - /* 0x2A4 */ s16 torsoXRotAdj; - /* 0x2A6 */ s16 headZRotAdj; - /* 0x2A8 */ s16 headXRotAdj; + /* 0x2A2 */ s16 torsoZRotStep; + /* 0x2A4 */ s16 torsoXRotStep; + /* 0x2A6 */ s16 headZRotStep; + /* 0x2A8 */ s16 headXRotStep; /* 0x2AA */ u16 textId; /* 0x2AC */ s16 cutscenes[1]; /* 0x2B0 */ ObjMoonStone* moonsTear; 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 b08295107..dedb09d4c 100644 --- a/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c +++ b/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bjt.c + * Overlay: ovl_En_Bjt + * Description: ??? (Hand in toilet) + */ + #include "z_en_bjt.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBjt*)thisx) 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 5981567e7..5d827f4da 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,6 +1,12 @@ +/* + * File: z_en_boj_01.c + * Overlay: ovl_En_Boj_01 + * Description: [Empty] + */ + #include "z_en_boj_01.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBoj01*)thisx) 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 602a1016e..8e26fa09c 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,6 +1,12 @@ +/* + * File: z_en_boj_02.c + * Overlay: ovl_En_Boj_02 + * Description: [Empty] + */ + #include "z_en_boj_02.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBoj02*)thisx) 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 6c5736858..4f9325e9d 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,6 +1,12 @@ +/* + * File: z_en_boj_03.c + * Overlay: ovl_En_Boj_03 + * Description: [Empty] + */ + #include "z_en_boj_03.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBoj03*)thisx) 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 1cfd102ef..09eed96c7 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,6 +1,12 @@ +/* + * File: z_en_boj_04.c + * Overlay: ovl_En_Boj_04 + * Description: [Empty] + */ + #include "z_en_boj_04.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBoj04*)thisx) 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 8513d0f95..d6ccba734 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,6 +1,12 @@ +/* + * File: z_en_boj_05.c + * Overlay: ovl_En_Boj_05 + * Description: [Empty] + */ + #include "z_en_boj_05.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBoj05*)thisx) 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 62e63c7e9..48550b656 100644 --- a/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -1,6 +1,13 @@ -#include "z_en_bom.h" +/* + * File: z_en_bom.c + * Overlay: ovl_En_Bom + * Description: Bomb / Powder Keg + */ -#define FLAGS 0x00000030 +#include "z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnBom*)thisx) @@ -11,8 +18,19 @@ void EnBom_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80871058(EnBom* this, GlobalContext* globalCtx); void func_808714D4(EnBom* this, GlobalContext* globalCtx); +void func_80872648(GlobalContext* globalCtx, Vec3f* arg1); +void func_808726DC(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, s32 arg4); +void func_80872BC0(GlobalContext* globalCtx, s32 arg1); + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ s16 unk_18; + /* 0x1A */ s16 unk_1A; +} EnBomStruct; // size = 0x1C + +static EnBomStruct D_80874650[16]; -#if 0 const ActorInit En_Bom_InitVars = { ACTOR_EN_BOM, ACTORCAT_EXPLOSIVES, @@ -25,73 +43,762 @@ const ActorInit En_Bom_InitVars = { (ActorFunc)EnBom_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80872DC8 = { - { COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x00013828, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static f32 enBomScales[] = { 0.01f, 0.03f }; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0x00013828, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 6, 11, 14, { 0, 0, 0 } }, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80872DF4[1] = { +static ColliderJntSphElementInit sJntSphElementsInit1[1] = { { - { ELEMTYPE_UNK0, { 0x00000008, 0x00, 0x02 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000008, 0x00, 0x02 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 0 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80872E18 = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ALL, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 1, D_80872DF4, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit1 = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ALL, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit1, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80872E28[1] = { +static ColliderJntSphElementInit sJntSphElementsInit2[1] = { { - { ELEMTYPE_UNK0, { 0x80000008, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x80000008, 0x00, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 0 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80872E4C = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ALL, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 1, D_80872E28, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit2 = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ALL, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit2, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80872E5C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F(scale, 0, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -4000, ICHAIN_STOP), }; -#endif +void EnBom_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBom* this = THIS; + s32 params; -extern ColliderCylinderInit D_80872DC8; -extern ColliderJntSphElementInit D_80872DF4[1]; -extern ColliderJntSphInit D_80872E18; -extern ColliderJntSphElementInit D_80872E28[1]; -extern ColliderJntSphInit D_80872E4C; -extern InitChainEntry D_80872E5C[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 700.0f, ActorShadow_DrawCircle, 16.0f); + this->actor.colChkInfo.mass = 200; + this->actor.colChkInfo.cylRadius = 5; + this->actor.colChkInfo.cylHeight = 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/EnBom_Init.s") + this->flashSpeedScale = 7; + this->isPowderKeg = ENBOM_GETX_1(&this->actor); + if (this->isPowderKeg) { + globalCtx->actorCtx.unk5 |= 1; + this->timer = gSaveContext.powderKegTimer; + } else { + this->timer = 70; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/EnBom_Destroy.s") + Collider_InitCylinder(globalCtx, &this->collider1); + Collider_InitJntSph(globalCtx, &this->collider2); + Collider_SetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_80871058.s") + if (!this->isPowderKeg) { + Collider_SetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit1, &this->collider3); + this->collider1.dim.radius = 6; + this->collider1.dim.height = 11; + } else { + Collider_SetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit2, &this->collider3); + this->collider1.dim.radius = 20; + this->collider1.dim.height = 36; + func_80872648(globalCtx, &this->actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_808714D4.s") + this->collider3.info.toucher.damage += ENBOM_GETZ_FF00(thisx); + this->actor.shape.rot.z &= 0xFF; + if (ENBOM_GETZ_80(&this->actor)) { + this->actor.shape.rot.z |= 0xFF00; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_808715B8.s") + this->collider2.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider2.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y; + this->collider2.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/EnBom_Update.s") + this->actor.flags |= ACTOR_FLAG_100000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/EnBom_Draw.s") + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actionFunc = func_808714D4; + this->actor.room = -1; + Actor_SetScale(&this->actor, enBomScales[this->isPowderKeg]); + } else { + this->actionFunc = func_80871058; + gSaveContext.powderKegTimer = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_80872648.s") +void EnBom_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBom* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_808726DC.s") + Collider_DestroyJntSph(globalCtx, &this->collider2); + Collider_DestroyCylinder(globalCtx, &this->collider1); + if (this->isPowderKeg) { + globalCtx->actorCtx.unk5 &= ~1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom/func_80872BC0.s") +void func_80871058(EnBom* this, GlobalContext* globalCtx) { + static Vec3f D_80872E68[] = { + { 2.0f, -6.0f, -0.3f }, + { 1.5f, -5.0f, -0.6f }, + { 0.2f, -6.0f, -0.1f }, + }; + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actionFunc = func_808714D4; + this->actor.room = -1; + return; + } + + if ((this->actor.velocity.y > 0.0f) && (this->actor.bgCheckFlags & 0x10)) { + this->actor.velocity.y = -this->actor.velocity.y; + } + + if ((this->actor.speedXZ != 0.0f) && (this->actor.bgCheckFlags & 8)) { + s16 yDiff = BINANG_SUB(this->actor.wallYaw, this->actor.world.rot.y); + + if (ABS_ALT(yDiff) > 0x4000) { + this->actor.world.rot.y = + BINANG_SUB(this->actor.wallYaw - this->actor.world.rot.y + this->actor.wallYaw, 0x8000); + } + + Actor_PlaySfxAtPos(&this->actor, this->isPowderKeg ? NA_SE_EV_PUT_DOWN_WOODBOX : NA_SE_EV_BOMB_BOUND); + Actor_MoveWithGravity(&this->actor); + this->actor.speedXZ *= 0.7f; + this->actor.bgCheckFlags &= ~8; + } + + if (!(this->actor.bgCheckFlags & 1)) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.08f); + } else { + Vec3f* sp58; + u32 sp54 = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + Vec3f sp48; + s16 sp46; + f32 sp40; + f32 sp3C; + f32 sp38; + + sp58 = &D_80872E68[this->isPowderKeg]; + + if (sp54 == 5) { + sp58 = &D_80872E68[2]; + } + + if ((sp54 == 4) || (sp54 == 14) || (sp54 == 15)) { + s16 sp36; + + Math_ApproachF(&this->actor.shape.yOffset, 0.0f, 0.1f, 50.0f); + sp36 = this->actor.shape.shadowAlpha; + Math_ApproachS(&sp36, 0, 1, 20); + this->actor.shape.shadowAlpha = sp36; + } else { + Math_ApproachF(&this->actor.shape.yOffset, 700.0f, 1.0f, 700.0f); + } + + sp40 = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; + sp3C = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; + func_800B75A0(this->actor.floorPoly, &sp48, &sp46); + + sp40 += 3.0f * sp48.x; + sp3C += 3.0f * sp48.z; + sp38 = sqrtf(SQ(sp40) + SQ(sp3C)); + + if ((sp38 < this->actor.speedXZ) || + (SurfaceType_GetSlope(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 1)) { + if (sp38 > 16.0f) { + this->actor.speedXZ = 16.0f; + } else { + this->actor.speedXZ = sp38; + } + this->actor.world.rot.y = Math_FAtan2F(sp3C, sp40); + } + + if (!Math_StepToF(&this->actor.speedXZ, 0.0f, sp58->x)) { + s16 temp = this->actor.world.rot.y; + s32 pad; + + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->actor.shape.rot.y)) > 0x4000) { + temp = BINANG_ROT180(temp); + } + Math_ScaledStepToS(&this->actor.shape.rot.y, temp, this->actor.speedXZ * 100.0f); + this->unk_1FA += (s16)(this->actor.speedXZ * 800.0f); + } + + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, this->isPowderKeg ? NA_SE_EV_TRE_BOX_BOUND : NA_SE_EV_BOMB_BOUND); + if (this->actor.velocity.y < sp58->y) { + if ((sp54 == 4) || (sp54 == 14) || (sp54 == 15)) { + this->actor.velocity.y = 0.0f; + } else { + this->actor.velocity.y = this->actor.velocity.y * sp58->z; + } + this->actor.bgCheckFlags &= ~1; + } + } else if (this->timer >= 4) { + Actor_LiftActor(&this->actor, globalCtx); + } + } + + Actor_MoveWithGravity(&this->actor); +} + +void func_808714D4(EnBom* this, GlobalContext* globalCtx) { + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actionFunc = func_80871058; + this->actor.room = globalCtx->roomCtx.currRoom.num; + this->actor.flags &= ~ACTOR_FLAG_100000; + this->actor.bgCheckFlags &= ~1; + Math_Vec3s_ToVec3f(&this->actor.prevPos, &this->actor.home.rot); + if (this->isPowderKeg) { + gSaveContext.powderKegTimer = 0; + } + func_80871058(this, globalCtx); + } else { + Math_Vec3f_ToVec3s(&this->actor.home.rot, &this->actor.parent->world.pos); + if (this->isPowderKeg) { + gSaveContext.powderKegTimer = this->timer; + } + } + Math_ScaledStepToS(&this->unk_1FA, 0, 2000); +} + +void func_808715B8(EnBom* this, GlobalContext* globalCtx) { + static s16 D_80872E8C[] = { 100, 200 }; + static Color_RGBA8 D_80872E90 = { 185, 140, 70, 255 }; + static Color_RGBA8 D_80872E94 = { 255, 255, 255, 255 }; + s32 i; + s32 temp_s0; + f32 temp_f20; + s32 pad; + f32 spCC; + Vec3f spC0; + Vec3f spB4; + CollisionPoly* spB0; + s32 spAC; + Vec3f spA0; + Vec3f sp94; + Vec3f sp88; + Color_RGBA8 sp84; + Color_RGBA8 sp80; + + if (this->collider2.elements->dim.modelSphere.radius == 0) { + this->actor.flags |= ACTOR_FLAG_20; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + } + + this->collider2.elements->dim.worldSphere.radius = D_80872E8C[this->isPowderKeg]; + if (this->timer == 7) { + this->collider2.base.atFlags &= ~OC1_TYPE_1; + } + + if (this->actor.params == ENBOM_1) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[0] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[0] -= 25; + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[1] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[1] -= 25; + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[2] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[2] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[0] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[0] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[1] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[1] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[2] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[2] -= 25; + } + + if (this->timer == 0) { + func_80123590(globalCtx, &this->actor); + Actor_MarkForDeath(&this->actor); + } + + if ((this->timer & 1) == 0) { + spCC = Rand_ZeroFloat(M_PI); + + for (i = 0; i < 15; i++) { + Matrix_RotateYF(((2.0f * (i * M_PI)) / 15.0f) + spCC, MTXMODE_NEW); + Matrix_MultVecZ((10 - this->timer) * 300.0f * 0.1f, &spC0); + spB4.x = this->actor.world.pos.x + spC0.x; + spB4.y = this->actor.world.pos.y + 500.0f; + spB4.z = this->actor.world.pos.z + spC0.z; + if (BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &spB0, &spAC, &spB4) != BGCHECK_Y_MIN) { + temp_s0 = func_800C99D4(&globalCtx->colCtx, spB0, spAC); + temp_f20 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &spB0, &spB4); + + if ((temp_s0 == 4) || (temp_s0 == 15) || (temp_s0 == 14)) { + if (temp_s0 == 4) { + sp84 = D_80872E90; + sp80 = D_80872E90; + } else { + sp84 = D_80872E94; + sp80 = D_80872E94; + } + Matrix_MultVecZ(5.0f, &sp94); + sp88.x = sp88.z = 0.0f; + sp94.y = 2.0f; + sp88.y = 0.2f; + + spA0.x = spB4.x; + spA0.y = temp_f20; + spA0.z = spB4.z; + + temp_f20 = Rand_ZeroFloat(250.0f); + func_800B0F18(globalCtx, &spA0, &sp94, &sp88, &sp84, &sp80, temp_f20 + 950.0f, 10, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + } + } +} + +static s16 D_80872E98[] = { 3, 5 }; +static s16 D_80872E9C[] = { 10, 15 }; + +void EnBom_Update(Actor* thisx, GlobalContext* globalCtx) { + Vec3f spA4 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp98 = { 0.0f, 0.1f, 0.0f }; + Vec3f sp8C = { 0.0f, 0.0f, 0.0f }; + Vec3f sp80; + Vec3f sp74 = { 0.0f, 0.6f, 0.0f }; + Color_RGBA8 sp70 = { 255, 255, 255, 255 }; + EnBom* this = THIS; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if (player->stateFlags1 & 2) { + return; + } + + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIANT) { + Actor_MarkForDeath(thisx); + return; + } + + if (this->unk_1FC != 0) { + this->unk_1FC--; + Math_ApproachZeroF(&thisx->speedXZ, 1.0f, 1.0f); + Actor_MoveWithGravity(thisx); + Actor_UpdateBgCheckInfo(globalCtx, thisx, 35.0f, 10.0f, 36.0f, 4); + if (this->unk_1FC == 0) { + if (this->isPowderKeg) { + gSaveContext.powderKegTimer = 0; + } + Actor_MarkForDeath(thisx); + } + } else { + thisx->gravity = -1.2f; + if (this->timer != 0) { + if (!this->isPowderKeg || (func_808715B8 == this->actionFunc) || !Play_InCsMode(globalCtx)) { + this->timer--; + } + } + + if ((!this->isPowderKeg && (this->timer == 67)) || (this->isPowderKeg && (this->timer <= 2400))) { + Actor_PlaySfxAtPos(thisx, NA_SE_PL_TAKE_OUT_SHIELD); + Actor_SetScale(thisx, enBomScales[this->isPowderKeg]); + } + + if ((thisx->xzDistToPlayer >= 20.0f) || (fabsf(thisx->playerHeightRel) >= 80.0f)) { + this->unk_1F8 = 1; + } + + this->actionFunc(this, globalCtx); + + Actor_UpdateBgCheckInfo(globalCtx, thisx, 35.0f, 10.0f, 36.0f, 0x1F); + if (thisx->params == ENBOM_0) { + static Vec3us D_80872ED4[] = { + { 40, 20, 100 }, + { 300, 60, 600 }, + }; + Vec3us* sp60 = &D_80872ED4[this->isPowderKeg]; + + sp74.y = 0.2f; + Math_Vec3f_Copy(&sp80, &thisx->home.pos); + if ((globalCtx->gameplayFrames % 2) == 0) { + EffectSsGSpk_SpawnFuse(globalCtx, thisx, &sp80, &spA4, &sp8C); + } + if (this->isPowderKeg) { + func_801A0810(&thisx->projectedPos, NA_SE_IT_BIG_BOMB_IGNIT - SFX_FLAG, + (this->flashSpeedScale == 7) ? 0 + : (this->flashSpeedScale == 3) ? 1 + : 2); + } else { + Actor_PlaySfxAtPos(thisx, NA_SE_IT_BOMB_IGNIT - SFX_FLAG); + } + + sp80.y += 3.0f; + func_800B0DE0(globalCtx, &sp80, &spA4, &sp74, &sp70, &sp70, 50, 5); + + if ((this->collider1.base.acFlags & AC_HIT) || + ((this->collider1.base.ocFlags1 & OC1_HIT) && ((this->collider1.base.oc->category == ACTORCAT_ENEMY) || + (this->collider1.base.oc->category == ACTORCAT_BOSS)))) { + this->timer = 0; + thisx->shape.rot.z = 0; + } else if ((this->timer > 100) && (func_80123F48(globalCtx, &thisx->world.pos, 30.0f, 50.0f))) { + this->timer = 100; + } + + sp74.y = 0.2f; + sp80 = thisx->world.pos; + sp80.y += 10.0f; + + if ((this->timer == sp60->x) || (this->timer == sp60->y) || (this->timer == 3)) { + thisx->shape.rot.z = 0; + this->flashSpeedScale >>= 1; + } + + if ((this->timer < sp60->z) && (this->timer & (this->flashSpeedScale + 1))) { + Math_ApproachF(&this->unk_1F4, 140.0f, 1.0f, 140.0f / this->flashSpeedScale); + } else { + Math_ApproachZeroF(&this->unk_1F4, 1.0f, 140.0f / this->flashSpeedScale); + } + + if (this->timer < 3) { + Actor_SetScale(thisx, thisx->scale.x + 0.002f); + } + + if (this->timer == 0) { + sp80 = thisx->world.pos; + sp80.y += 10.0f; + if (Actor_HasParent(thisx, globalCtx)) { + sp80.y += 30.0f; + } + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, sp80.x, sp80.y - 10.0f, sp80.z, 0, 0, + 0, this->isPowderKeg); + func_800BC848(thisx, globalCtx, D_80872E98[this->isPowderKeg], D_80872E9C[this->isPowderKeg]); + globalCtx->envCtx.lightSettings.diffuseColor1[0] = globalCtx->envCtx.lightSettings.diffuseColor1[1] = + globalCtx->envCtx.lightSettings.diffuseColor1[2] = 250; + globalCtx->envCtx.lightSettings.ambientColor[0] = globalCtx->envCtx.lightSettings.ambientColor[1] = + globalCtx->envCtx.lightSettings.ambientColor[2] = 250; + func_800DFD04(&globalCtx->mainCamera, 2, 11, 8); + thisx->params = ENBOM_1; + this->timer = 10; + thisx->flags |= (0x100000 | 0x20); + this->actionFunc = func_808715B8; + if (this->isPowderKeg) { + gSaveContext.powderKegTimer = 0; + Actor_PlaySfxAtPos(thisx, NA_SE_IT_BIG_BOMB_EXPLOSION); + } else { + Actor_PlaySfxAtPos(thisx, NA_SE_IT_BOMB_EXPLOSION); + } + } + } + + Actor_SetFocus(thisx, 20.0f); + + if (thisx->params <= ENBOM_0) { + Collider_UpdateCylinder(thisx, &this->collider1); + if (!Actor_HasParent(thisx, globalCtx) && (this->unk_1F8 != 0)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + if ((enBomScales[this->isPowderKeg] <= thisx->scale.x) && (thisx->params != ENBOM_1)) { + if (thisx->depthInWater >= 20.0f) { + Vec3f sp54; + + sp54.x = thisx->world.pos.x; + sp54.y = thisx->world.pos.y + thisx->depthInWater; + sp54.z = thisx->world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp54, 70, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &sp54, 70, 500, 10); + sp54.y += 10.0f; + EffectSsGSplash_Spawn(globalCtx, &sp54, NULL, NULL, 1, 500); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, sp54.x, sp54.y, sp54.z, 0, 0, 1, 200); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &thisx->world.pos, 30, NA_SE_IT_BOMB_UNEXPLOSION); + this->unk_1F4 = 0.0f; + thisx->velocity.y = (KREG(83) * 0.1f) + -2.0f; + thisx->gravity = (KREG(84) * 0.1f) + -0.5f; + this->unk_1FC = KREG(81) + 10; + } else if (thisx->bgCheckFlags & 0x40) { + thisx->bgCheckFlags &= ~0x40; + Actor_PlaySfxAtPos(thisx, NA_SE_EV_BOMB_DROP_WATER); + } + } + } +} + +static Vec3f D_80872EE0 = { 0.0f, 800.0f, 0.0f }; +static Vec3f D_80872EEC = { -750.0f, 0.0f, 0.0f }; +static Vec3f D_80872EF8 = { -800.0f, 0.0f, 0.0f }; +static Vec3f D_80872F04 = { 0.0f, 0.0f, 0.0f }; + +#include "overlays/ovl_En_Bom/ovl_En_Bom.c" + +void EnBom_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBom* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->actor.params == ENBOM_0) { + func_8012C28C(globalCtx->state.gfxCtx); + + Collider_UpdateSpheres(0, &this->collider2); + + if (!this->isPowderKeg) { + func_800B8050(&this->actor, globalCtx, 0); + Matrix_MultVec3f(&D_80872EE0, &this->actor.home.pos); + + 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_015FA0); + + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateXS(0x4000, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, (s8)this->unk_1F4, 0, 40, 255); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, (s8)this->unk_1F4, 0, 40, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_015DB0); + } else { + Vec3f sp58; + Vec3f sp4C; + + if (this->unk_1FA != 0) { + s16 sp4A = this->actor.world.rot.y - this->actor.shape.rot.y; + f32 sp44 = (1000.0f / Math_CosS(ABS_ALT((s16)(this->unk_1FA % 10922)) - 0x1555)) + -1000.0f; + + Matrix_RotateYS(sp4A, MTXMODE_APPLY); + Matrix_Translate(0.0f, sp44, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1FA, MTXMODE_APPLY); + Matrix_RotateYS(-sp4A, MTXMODE_APPLY); + } + + Matrix_MultVec3f(&D_80872EEC, &this->actor.home.pos); + Matrix_MultVec3f(&D_80872EF8, &sp58); + Matrix_MultVec3f(&D_80872F04, &sp4C); + + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Bom_DL_80873CA0); + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Bom_DL_808742F8); + + func_808726DC(globalCtx, &this->actor.home.pos, &sp58, &sp4C, this->timer); + func_80872BC0(globalCtx, this->timer); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80872648(GlobalContext* globalCtx, Vec3f* arg1) { + EnBomStruct* ptr = &D_80874650[0]; + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_80874650); i++, ptr++) { + Math_Vec3f_Copy(&ptr->unk_00, arg1); + Math_Vec3f_Copy(&ptr->unk_0C, &gZeroVec3f); + ptr->unk_18 = 0; + ptr->unk_1A = 0x4000; + } +} + +void func_808726DC(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, s32 arg4) { + s32 i; + f32 temp_f20; + Vec3f spCC; + Vec3f spC0; + EnBomStruct* ptr = &D_80874650[0]; + EnBomStruct* ptr2 = &D_80874650[1]; + f32 temp_f26 = Math_Vec3f_DistXYZ(arg3, arg1); + s32 spB0; + f32 temp_f2; + f32 distXZ; + + Math_Vec3f_Copy(&ptr->unk_00, arg1); + Math_Vec3f_Diff(arg2, arg1, &spCC); + + ptr->unk_18 = Math_FAtan2F(spCC.z, spCC.x); + distXZ = sqrtf(SQXZ(spCC)); + ptr->unk_1A = Math_FAtan2F(distXZ, spCC.y); + + spB0 = (arg4 / 240) + 1; + + for (i = 0; i < spB0; i++, ptr++, ptr2++, arg4 -= 240) { + f32 phi_f22; + CollisionPoly* spA0; + s32 sp9C; + Vec3f sp90; + + if (arg4 >= 240) { + phi_f22 = 8.0f; + } else { + phi_f22 = (arg4 % 240) * (1.0f / 240) * 8.0f; + } + + Math_Vec3f_Sum(&ptr2->unk_00, &ptr2->unk_0C, &ptr2->unk_00); + temp_f20 = Math_Vec3f_DistXYZAndStoreDiff(arg3, &ptr2->unk_00, &spCC); + if (temp_f20 < temp_f26) { + if (temp_f20 == 0.0f) { + spCC.x = 0.0f; + spCC.y = temp_f26; + spCC.z = 0.0f; + } else { + temp_f20 = temp_f26 / temp_f20; + spCC.x *= temp_f20; + spCC.y *= temp_f20; + spCC.z *= temp_f20; + } + Math_Vec3f_Sum(arg3, &spCC, &ptr2->unk_00); + } + + if (Math_Vec3f_DistXYZAndStoreDiff(&ptr->unk_00, &ptr2->unk_00, &spCC) == 0.0f) { + spCC.x = 0.0f; + spCC.y = phi_f22; + spCC.z = 0.0f; + } + + ptr2->unk_18 = Math_FAtan2F(spCC.z, spCC.x); + distXZ = sqrtf(SQXZ(spCC)); + ptr2->unk_1A = Math_FAtan2F(distXZ, spCC.y); + + ptr2->unk_18 = (s16)CLAMP(BINANG_SUB(ptr2->unk_18, ptr->unk_18), -8000, 8000) + ptr->unk_18; + ptr2->unk_1A = (s16)CLAMP(BINANG_SUB(ptr2->unk_1A, ptr->unk_1A), -8000, 8000) + ptr->unk_1A; + + temp_f20 = Math_CosS(ptr2->unk_1A) * phi_f22; + spC0.x = Math_SinS(ptr2->unk_18) * temp_f20; + spC0.z = Math_CosS(ptr2->unk_18) * temp_f20; + spC0.y = Math_SinS(ptr2->unk_1A) * phi_f22; + + Math_Vec3f_Sum(&ptr->unk_00, &spC0, &ptr2->unk_00); + Math_Vec3f_Copy(&sp90, &ptr2->unk_00); + + sp90.y += 50.0f; + + temp_f2 = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &spA0, &sp9C, &sp90) - ptr2->unk_00.y; + if (temp_f2 >= 0.0f) { + spC0.y += temp_f2; + if (phi_f22 < spC0.y) { + spC0.y = phi_f22; + temp_f2 = 0.0f; + } else { + temp_f2 = sqrtf(SQ(phi_f22) - SQ(spC0.y)); + } + + if (temp_f20 == 0.0f) { + spC0.x = temp_f2; + } else { + temp_f2 /= temp_f20; + spC0.x *= temp_f2; + spC0.z *= temp_f2; + } + + Math_Vec3f_Sum(&ptr->unk_00, &spC0, &ptr2->unk_00); + Math_Vec3f_Copy(&ptr2->unk_0C, &gZeroVec3f); + } + + ptr2->unk_0C.y += -1.0f; + if (ptr2->unk_0C.y < -10.0f) { + ptr2->unk_0C.y = -10.0f; + } + } + + Math_Vec3f_Copy(arg1, &ptr->unk_00); +} + +void func_80872BC0(GlobalContext* globalCtx, s32 arg1) { + s32 temp_s5; + s32 i; + EnBomStruct* ptr = &D_80874650[0]; + EnBomStruct* ptr2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_RotateZYX(ptr->unk_1A, ptr->unk_18, 0, 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++, ovl_En_Bom_DL_80872F98); + + temp_s5 = (arg1 / 240) + 1; + ptr2 = &D_80874650[1]; + + for (i = 1; i < temp_s5; i++, ptr2++) { + Matrix_Translate(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, MTXMODE_NEW); + Matrix_RotateZYX(ptr2->unk_1A, ptr2->unk_18, 0, 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); + + if ((i % 2) == 0) { + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Bom_DL_80873020); + } else { + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Bom_DL_80873040); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.h b/src/overlays/actors/ovl_En_Bom/z_en_bom.h index 60cf065b3..a0555ab24 100644 --- a/src/overlays/actors/ovl_En_Bom/z_en_bom.h +++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.h @@ -7,13 +7,27 @@ struct EnBom; typedef void (*EnBomActionFunc)(struct EnBom*, GlobalContext*); +#define ENBOM_GETX_1(thisx) ((thisx)->shape.rot.x & 1) +#define ENBOM_GETZ_80(thisx) ((thisx)->shape.rot.z & 0x80) +#define ENBOM_GETZ_FF00(thisx) (((thisx)->shape.rot.z & 0xFF00) >> 8) + +enum { + /* 0 */ ENBOM_0, + /* 1 */ ENBOM_1, +}; + typedef struct EnBom { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xAC]; + /* 0x144 */ ColliderCylinder collider1; + /* 0x190 */ ColliderJntSph collider2; + /* 0x1B0 */ ColliderJntSphElement collider3; /* 0x1F0 */ s16 timer; - /* 0x1F2 */ char unk_1F2[0x7]; - /* 0x1F9 */ u8 unk_1F9; - /* 0x1FA */ char unk_1FA[0x6]; + /* 0x1F2 */ s16 flashSpeedScale; + /* 0x1F4 */ f32 unk_1F4; + /* 0x1F8 */ u8 unk_1F8; + /* 0x1F9 */ u8 isPowderKeg; + /* 0x1FA */ s16 unk_1FA; + /* 0x1FC */ u8 unk_1FC; /* 0x200 */ EnBomActionFunc actionFunc; } EnBom; // size = 0x204 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 dec58fb36..321468424 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,6 +1,13 @@ -#include "z_en_bom_bowl_man.h" +/* + * File: z_en_bom_bowl_man.c + * Overlay: ovl_En_Bom_Bowl_Man + * Description: Line of Bombers when they teach you the password + */ -#define FLAGS 0x00000009 +#include "z_en_bom_bowl_man.h" +#include "objects/object_cs/object_cs.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBomBowlMan*)thisx) @@ -9,18 +16,27 @@ void EnBomBowlMan_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBomBowlMan_Update(Actor* thisx, GlobalContext* globalCtx); void EnBomBowlMan_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_809C4BC4(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C4DA4(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C51B4(EnBomBowlMan* this, GlobalContext* globalCtx); +void func_809C52B4(EnBomBowlMan* this); void func_809C5310(EnBomBowlMan* this, GlobalContext* globalCtx); +void func_809C53A4(EnBomBowlMan* this); void func_809C5408(EnBomBowlMan* this, GlobalContext* globalCtx); +void func_809C5524(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C5598(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C5738(EnBomBowlMan* this, GlobalContext* globalCtx); +void func_809C59A4(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C59F0(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C5AA4(EnBomBowlMan* this, GlobalContext* globalCtx); void func_809C5B1C(EnBomBowlMan* this, GlobalContext* globalCtx); +void func_809C5BA0(EnBomBowlMan* this); void func_809C5BF4(EnBomBowlMan* this, GlobalContext* globalCtx); -#if 0 +s32 D_809C6100 = 0; + +s32 D_809C6104 = 0; + const ActorInit En_Bom_Bowl_Man_InitVars = { ACTOR_EN_BOM_BOWL_MAN, ACTORCAT_NPC, @@ -33,56 +49,644 @@ const ActorInit En_Bom_Bowl_Man_InitVars = { (ActorFunc)EnBomBowlMan_Draw, }; -#endif +static AnimationHeader* sAnimations[] = { + &gBomberIdleAnim, &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, +}; -extern UNK_TYPE D_060064B8; +u8 D_809C6178[] = { + 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Init.s") +u16 D_809C618C[] = { 0x710, 0x711, 0x715, 0x716, 0x717, 0x718 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Destroy.s") +u16 D_809C6198[] = { 0x74F, 0x750, 0x751, 0x752 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C493C.s") +Vec3f D_809C61A0[] = { + { -730.0f, 200.0f, -2350.0f }, { -690.0f, 200.0f, -2350.0f }, { -650.0f, 200.0f, -2350.0f }, + { -610.0f, 200.0f, -2350.0f }, { -570.0f, 200.0f, -2350.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C49CC.s") +void EnBomBowlMan_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBomBowlMan* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C4B50.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + this->actor.gravity = -3.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &gBomberIdleAnim, this->jointTable, + this->morphTable, 21); + this->unk_2F6 = ENBOMBOWLMAN_GET_F0(&this->actor); + this->unk_2F4 = ENBOMBOWLMAN_GET_F(&this->actor); + this->actor.targetMode = 6; + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C4B6C.s") + if (this->unk_2F6 == ENBOMBOWLMAN_F0_0) { + if (this->unk_2F4 == 0) { + func_809C4BC4(this, globalCtx); + } else { + this->unk_2F4--; + func_809C5BA0(this); + } + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C4BC4.s") + this->unk_29A = ENBOMBOWLMAN_GET_FF00(&this->actor); + this->path = SubS_GetPathByIndex(globalCtx, this->unk_29A, 0x3F); + this->unk_2C8 = 80.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C4DA4.s") + if ((gSaveContext.save.entranceIndex == 0xD220) && (gSaveContext.save.weekEventReg[73] & 0x80) && + !CHECK_QUEST_ITEM(ITEM_BOTTLE)) { + this->unk_2D6 = this->actor.cutscene; + if (this->unk_2D6 == 0) { + Actor_MarkForDeath(&this->actor); + } + func_809C52B4(this); + } else { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C51B4.s") +void EnBomBowlMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C52B4.s") +void func_809C493C(EnBomBowlMan* this, s32 arg1, f32 arg2) { + this->unk_2F8 = arg1; + this->unk_2C4 = Animation_GetLastFrame(sAnimations[arg1]); + Animation_Change(&this->skelAnime, sAnimations[this->unk_2F8], arg2, 0.0f, this->unk_2C4, D_809C6178[this->unk_2F8], + -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5310.s") +void func_809C49CC(EnBomBowlMan* this) { + if ((this->unk_2F8 == 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))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C53A4.s") + if ((this->unk_2F8 == 0xB) && + (Animation_OnFrame(&this->skelAnime, 4.0f) || Animation_OnFrame(&this->skelAnime, 8.0f) || + Animation_OnFrame(&this->skelAnime, 12.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5408.s") + if ((this->unk_2F8 == 0x12) && + (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 2.0f) || + Animation_OnFrame(&this->skelAnime, 4.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5524.s") + if ((this->unk_2F8 == 0xF) && Animation_OnFrame(&this->skelAnime, 15.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_LAND); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5598.s") + if ((this->unk_2F8 == 6) && Animation_OnFrame(&this->skelAnime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_LAND); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5738.s") +void func_809C4B50(EnBomBowlMan* this) { + this->unk_2B8 = 0; + this->unk_2BC = 0; + this->unk_2BA = 0; + this->unk_29E = 0; + this->unk_290 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C59A4.s") +void func_809C4B6C(EnBomBowlMan* this) { + if ((this->unk_29A != ENBOMBOWLMAN_FF00_MINUS1) && (this->path != NULL)) { + if (!SubS_CopyPointFromPath(this->path, this->unk_298, &this->unk_2A0)) { + Actor_MarkForDeath(&this->actor); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C59F0.s") +void func_809C4BC4(EnBomBowlMan* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + Vec3f sp7C; + EnBomBowlMan* bomBowlMan; + s8 code; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5AA4.s") + func_809C4B50(this); + func_809C493C(this, 0, 1.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5B1C.s") + for (i = 0; i < ARRAY_COUNT(gSaveContext.save.bomberCode); i++) { + Math_Vec3f_Copy(&sp7C, &this->actor.home.pos); + code = gSaveContext.save.bomberCode[i]; + if (code == 1) { + Math_Vec3f_Copy(&this->actor.world.pos, &D_809C61A0[i]); + this->unk_2D8[code] = this; + } else { + Math_Vec3f_Copy(&sp7C, &D_809C61A0[i]); + bomBowlMan = + (EnBomBowlMan*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOM_BOWL_MAN, + sp7C.x, sp7C.y, sp7C.z, 0, this->actor.world.rot.y, 0, code); + if (bomBowlMan != NULL) { + if (i == 2) { + this->unk_2D8[0] = bomBowlMan; + } + this->unk_2D8[code] = bomBowlMan; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5BA0.s") + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D0); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D0)) { + ActorCutscene_SetIntentToPlay(this->unk_2D0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5BF4.s") + func_809C493C(this, 3, 1.0f); + this->unk_2D4 = this->actor.yawTowardsPlayer; + this->unk_290 = this->actor.yawTowardsPlayer; + gSaveContext.save.weekEventReg[73] &= (u8)~0x10; + gSaveContext.save.weekEventReg[85] &= (u8)~2; + this->unk_29C = 0; + this->actionFunc = func_809C4DA4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Update.s") +void func_809C4DA4(EnBomBowlMan* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->unk_290, this->unk_2D4, 1, 5000, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/func_809C5F44.s") + if (this->unk_2B8 == 0) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Bowl_Man/EnBomBowlMan_Draw.s") + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D0); + return; + } + + if (!ActorCutscene_GetCanPlayNext(this->unk_2D0)) { + ActorCutscene_SetIntentToPlay(this->unk_2D0); + return; + } + + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D0, &this->actor); + this->unk_2B8 = 1; + this->unk_2C0 = 0; + this->unk_2D4 = this->actor.yawTowardsPlayer; + this->unk_290 = this->actor.yawTowardsPlayer; + if (player->transformation == PLAYER_FORM_HUMAN) { + Message_StartTextbox(globalCtx, D_809C618C[0], &this->actor); + } else { + Message_StartTextbox(globalCtx, D_809C6198[0], &this->actor); + } + } + + if ((this->unk_2BC == 0) && (Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + s32 sp28 = false; + + func_801477B4(globalCtx); + + switch (this->unk_2C0) { + case 0: + this->unk_2C0 = 1; + D_809C6104 = 1; + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->unk_2D0)), + &this->unk_2D8[0]->actor); + this->unk_2D4 = 0; + this->unk_2BC = 10; + func_809C493C(this, 17, 1.0f); + break; + + case 1: + D_809C6104 = 0; + func_809C493C(this, 3, 1.0f); + this->unk_2D4 = this->actor.yawTowardsPlayer; + this->unk_2C0 = 2; + if ((player->transformation == PLAYER_FORM_HUMAN) && CHECK_QUEST_ITEM(ITEM_BOTTLE)) { + this->unk_2C0 = 4; + } + break; + + case 2: + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_2B8 = 2; + ActorCutscene_Stop(this->unk_2D0); + func_809C59A4(this, globalCtx); + sp28 = true; + } else { + this->unk_2C0 = 3; + globalCtx->msgCtx.unk11F10 = 0; + func_809C493C(this, 1, 1.0f); + D_809C6100 = 1; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D2); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D2)) { + ActorCutscene_SetIntentToPlay(this->unk_2D2); + } + ActorCutscene_Stop(this->unk_2D0); + this->actionFunc = func_809C5B1C; + sp28 = true; + } + break; + + case 3: + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_2C0 = 4; + } else { + this->actionFunc = func_809C51B4; + return; + } + break; + + case 4: + if (this->unk_2B8 != 2) { + ActorCutscene_Stop(this->unk_2D0); + } + globalCtx->msgCtx.unk11F10 = 0; + func_809C493C(this, 1, 1.0f); + D_809C6100 = 1; + this->actionFunc = func_809C5B1C; + sp28 = true; + break; + + case 5: + func_80151BB4(globalCtx, 0x24); + func_80151BB4(globalCtx, 0x25); + func_80151BB4(globalCtx, 0); + this->actionFunc = func_809C51B4; + sp28 = true; + break; + } + + if (!sp28) { + if (player->transformation == PLAYER_FORM_HUMAN) { + func_80151938(globalCtx, D_809C618C[this->unk_2C0]); + } else { + func_80151938(globalCtx, D_809C6198[this->unk_2C0]); + } + } + } +} + +void func_809C51B4(EnBomBowlMan* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((globalCtx->msgCtx.unk120B1 == 0) && + ((globalCtx->msgCtx.msgMode == 0) || (Message_GetState(&globalCtx->msgCtx) == 6))) { + globalCtx->nextEntranceIndex = Entrance_CreateIndexFromSpawn(6); + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 0x56; + gSaveContext.nextTransition = 3; + gSaveContext.save.weekEventReg[75] &= (u8)~0x40; + if (player->transformation == PLAYER_FORM_HUMAN) { + gSaveContext.save.weekEventReg[84] |= 0x80; + gSaveContext.save.weekEventReg[77] &= (u8)~2; + } else { + gSaveContext.save.weekEventReg[73] |= 0x20; + gSaveContext.save.weekEventReg[85] &= (u8)~1; + } + } +} + +void func_809C52B4(EnBomBowlMan* this) { + this->actor.draw = NULL; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.world.pos.x = 1340.0f; + this->actor.world.pos.z = -1795.0f; + this->unk_29C = 3; + this->actionFunc = func_809C5310; +} + +void func_809C5310(EnBomBowlMan* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->actor.world.pos.x < 1510.0f) { + if (player->transformation != PLAYER_FORM_DEKU) { + if (this->actor.xzDistToPlayer < this->unk_2C8) { + func_800B7298(globalCtx, &this->actor, 7); + func_809C53A4(this); + } + } else { + Actor_MarkForDeath(&this->actor); + } + } +} + +void func_809C53A4(EnBomBowlMan* this) { + this->actor.draw = EnBomBowlMan_Draw; + this->actor.world.pos.x = 1360.0f; + this->actor.world.pos.z = -1870.0f; + func_809C493C(this, 18, 1.0f); + this->unk_29C = 3; + this->actionFunc = func_809C5408; +} + +void func_809C5408(EnBomBowlMan* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player = GET_PLAYER(globalCtx); + + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &player->actor.world.pos), 1, + 0x1388, 0); + Math_SmoothStepToS(&player->actor.shape.rot.y, Math_Vec3f_Yaw(&player->actor.world.pos, &this->actor.world.pos), 1, + 0x1388, 0); + player->actor.world.rot.y = player->actor.shape.rot.y; + Math_ApproachF(&this->actor.world.pos.x, 1350.0f, 0.3f, 2.0f); + Math_ApproachF(&this->actor.world.pos.z, -1800.0f, 0.3f, 2.0f); + if (sqrtf(SQ(this->actor.world.pos.x - 1350.0f) + SQ(this->actor.world.pos.z + 1800.0f)) < 4.0f) { + func_809C5524(this, globalCtx); + } +} + +void func_809C5524(EnBomBowlMan* this, GlobalContext* globalCtx) { + this->actor.textId = 0x730; + if (!(gSaveContext.save.weekEventReg[85] & 2)) { + this->actor.textId = 0x72F; + } + func_809C493C(this, 3, 1.0f); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + this->actionFunc = func_809C5598; +} + +void func_809C5598(EnBomBowlMan* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + if ((this->actor.textId == 0x72F) || (this->actor.textId == 0x730)) { + this->actor.textId = 0x731; + } else if (this->actor.textId == 0x731) { + this->actor.textId = 0x732; + } else if (this->actor.textId == 0x732) { + this->actor.textId = 0x733; + } else if (this->actor.textId == 0x733) { + this->actor.textId = 0x734; + } else if (this->actor.textId == 0x734) { + this->actor.textId = 0x715; + } else if (this->actor.textId == 0x715) { + func_800B7298(globalCtx, &this->actor, 6); + func_809C493C(this, 17, 1.0f); + func_809C59A4(this, globalCtx); + return; + } else if (this->actor.textId == 0x716) { + this->actor.textId = 0x735; + } else if (this->actor.textId == 0x735) { + this->unk_2C2 = 0; + func_809C493C(this, 17, 1.0f); + func_80151BB4(globalCtx, 0x24); + func_80151BB4(globalCtx, 0x25); + func_80151BB4(globalCtx, 0); + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = func_809C5738; + return; + } + func_80151938(globalCtx, this->actor.textId); + } +} + +void func_809C5738(EnBomBowlMan* this, GlobalContext* globalCtx) { + s32 pad[3]; + s16 yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A0); + + if (this->unk_2C2 == 0) { + if ((globalCtx->msgCtx.unk120B1 == 0) && + ((globalCtx->msgCtx.msgMode == 0) || (Message_GetState(&globalCtx->msgCtx) == 6))) { + this->unk_2C2 = 1; + func_809C4B6C(this); + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D6); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D6)) { + ActorCutscene_SetIntentToPlay(this->unk_2D6); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D6, &this->actor); + this->unk_2C2 = 2; + func_809C493C(this, 18, 1.0f); + } + } + } else if (this->unk_2C2 == 1) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D6); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D6)) { + ActorCutscene_SetIntentToPlay(this->unk_2D6); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D6, &this->actor); + this->unk_2C2 = 2; + func_809C493C(this, 18, 1.0f); + } + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, yaw, 1, 2000, 10); + Math_ApproachF(&this->actor.world.pos.x, this->unk_2A0.x, 0.5f, 6.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_2A0.z, 0.5f, 6.0f); + if ((sqrtf(SQ(this->actor.world.pos.x - this->unk_2A0.x) + SQ(this->actor.world.pos.z - this->unk_2A0.z)) < + 4.0f) && + (this->path != NULL)) { + this->unk_298++; + if (this->unk_298 >= this->path->count) { + gSaveContext.save.weekEventReg[84] |= 0x80; + gSaveContext.save.weekEventReg[83] &= (u8)~4; + ActorCutscene_Stop(this->unk_2D6); + Actor_MarkForDeath(&this->actor); + } else { + func_809C4B6C(this); + } + } + } +} + +void func_809C59A4(EnBomBowlMan* this, GlobalContext* globalCtx) { + Actor_PickUp(&this->actor, globalCtx, GI_50, 300.0f, 300.0f); + this->unk_29C = 1; + this->actionFunc = func_809C59F0; +} + +void func_809C59F0(EnBomBowlMan* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + if (this->unk_2F6 == ENBOMBOWLMAN_F0_0) { + this->unk_2C0 = 3; + this->actor.textId = D_809C618C[this->unk_2C0]; + } else { + this->actor.textId = 0x716; + } + func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, -1); + this->actionFunc = func_809C5AA4; + } else { + Actor_PickUp(&this->actor, globalCtx, GI_50, 300.0f, 300.0f); + } +} + +void func_809C5AA4(EnBomBowlMan* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (this->unk_2F6 == ENBOMBOWLMAN_F0_0) { + this->actionFunc = func_809C4DA4; + } else { + this->actionFunc = func_809C5598; + } + } else { + func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, -1); + } +} + +void func_809C5B1C(EnBomBowlMan* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D2); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D2)) { + ActorCutscene_SetIntentToPlay(this->unk_2D2); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D2, &this->actor); + func_809C5BA0(this); + } +} + +void func_809C5BA0(EnBomBowlMan* this) { + if (this->unk_2F4 != 0) { + func_809C493C(this, 0, 1.0f); + } else { + this->unk_2F8 = 0; + } + this->unk_29C = 2; + this->actionFunc = func_809C5BF4; +} + +void func_809C5BF4(EnBomBowlMan* this, GlobalContext* globalCtx) { + f32 sp2C = this->skelAnime.curFrame; + s32 sp28; + + if ((D_809C6104 != 0) && (this->unk_2F8 != 15)) { + func_809C493C(this, 15, 1.0f); + } + + if ((this->unk_2F8 == 15) && (this->unk_2C4 <= sp2C)) { + func_809C493C(this, 0, 1.0f); + } + + if (D_809C6100 != 0) { + if ((this->unk_2F8 == 0) && (D_809C6100 == (this->unk_2F4 + 1))) { + func_809C493C(this, 11, 1.0f); + } + + if ((this->unk_2F8 == 11) && (this->unk_2C4 <= sp2C)) { + func_809C493C(this, 12, 1.0f); + D_809C6100++; + } + + if (this->unk_2F4 == 0) { + sp28 = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->unk_2D2)); + + if (D_809C6100 > 5) { + Player* player = GET_PLAYER(globalCtx); + + func_801477B4(globalCtx); + Camera_SetTargetActor(sp28, &this->unk_2D8[0]->actor); + func_809C493C(this, 13, 1.0f); + D_809C6100 = 0; + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_2C0 = 5; + Message_StartTextbox(globalCtx, D_809C618C[this->unk_2C0], &this->actor); + } else { + this->unk_2C0 = 3; + Message_StartTextbox(globalCtx, D_809C6198[this->unk_2C0], &this->actor); + } + this->unk_29C = 0; + this->actionFunc = func_809C4DA4; + } else { + s32 idx = D_809C6100 - 1; + + Camera_SetTargetActor(sp28, &this->unk_2D8[1 + idx]->actor); + } + } + } +} + +void EnBomBowlMan_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBomBowlMan* this = THIS; + + if (this->unk_2BA != 0) { + this->unk_2BA--; + } + + if (this->unk_2BC != 0) { + this->unk_2BC--; + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y = this->actor.world.rot.y; + func_809C49CC(this); + Actor_SetFocus(&this->actor, 20.0f); + + this->actionFunc(this, globalCtx); + + Actor_MoveWithGravity(&this->actor); + Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 0x1388, 0); + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 0x3E8, 0); + + if (this->unk_2F2 == 0) { + this->unk_2F0++; + if (this->unk_2F0 >= 3) { + this->unk_2F0 = 0; + this->unk_2F2 = (s32)Rand_ZeroFloat(60.0f) + 20; + } + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); +} + +s32 EnBomBowlMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBomBowlMan* this = THIS; + + if (limbIndex == 15) { + *dList = NULL; + } + + if (limbIndex == 17) { + rot->x += this->unk_28A; + } + + if ((limbIndex == 19) && (this->unk_2F6 == ENBOMBOWLMAN_F0_2)) { + *dList = NULL; + } + + if ((limbIndex == 20) && (this->unk_2F6 == ENBOMBOWLMAN_F0_0)) { + *dList = NULL; + } + return false; +} + +#include "overlays/ovl_En_Bom_Bowl_Man/ovl_En_Bom_Bowl_Man.c" + +TexturePtr D_809C6200[] = { + gEnBomBowlMan_D_809C61E0, gEnBomBowlMan_D_809C61F0, gEnBomBowlMan_D_809C61F0, + gEnBomBowlMan_D_809C61F0, gEnBomBowlMan_D_809C61F0, +}; + +TexturePtr D_809C6214[] = { + object_cs_Tex_00C520, + object_cs_Tex_00CD20, + object_cs_Tex_00D520, +}; + +TexturePtr D_809C6220[] = { + object_cs_Tex_00E620, object_cs_Tex_00EA20, object_cs_Tex_00EE20, object_cs_Tex_00DD20, object_cs_Tex_00F220, +}; + +void EnBomBowlMan_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnBomBowlMan* 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_809C6214[this->unk_2F0])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_809C6220[this->unk_2F4])); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_809C6200[this->unk_2F4])); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnBomBowlMan_OverrideLimbDraw, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h index ba90b19c9..6246a6756 100644 --- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h +++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h @@ -7,11 +7,54 @@ struct EnBomBowlMan; typedef void (*EnBomBowlManActionFunc)(struct EnBomBowlMan*, GlobalContext*); +#define ENBOMBOWLMAN_GET_F(thisx) ((thisx)->params & 0xF) +#define ENBOMBOWLMAN_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) +#define ENBOMBOWLMAN_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +#define ENBOMBOWLMAN_F0_0 0 +#define ENBOMBOWLMAN_F0_2 2 + +#define ENBOMBOWLMAN_FF00_MINUS1 -1 + typedef struct EnBomBowlMan { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x140]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[21]; + /* 0x0206 */ Vec3s morphTable[21]; /* 0x0284 */ EnBomBowlManActionFunc actionFunc; - /* 0x0288 */ char unk_288[0x74]; + /* 0x0288 */ s16 unk_288; + /* 0x028A */ s16 unk_28A; + /* 0x028C */ UNK_TYPE1 unk28C[2]; + /* 0x028E */ s16 unk_28E; + /* 0x0290 */ s16 unk_290; + /* 0x0292 */ UNK_TYPE1 unk292[2]; + /* 0x0294 */ Path* path; + /* 0x0298 */ s16 unk_298; + /* 0x029A */ s16 unk_29A; + /* 0x029C */ s16 unk_29C; + /* 0x029E */ s16 unk_29E; + /* 0x02A0 */ Vec3f unk_2A0; + /* 0x02AC */ UNK_TYPE1 unk2AC[0xC]; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA; + /* 0x02BC */ s16 unk_2BC; + /* 0x02BE */ UNK_TYPE1 unk2BE[2]; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C2 */ s16 unk_2C2; + /* 0x02C4 */ f32 unk_2C4; + /* 0x02C8 */ f32 unk_2C8; + /* 0x02CC */ s16 unk_2CC[2]; + /* 0x02D0 */ s16 unk_2D0; + /* 0x02D2 */ s16 unk_2D2; + /* 0x02D4 */ s16 unk_2D4; + /* 0x02D6 */ s16 unk_2D6; + /* 0x02D8 */ struct EnBomBowlMan* unk_2D8[5]; + /* 0x02EC */ UNK_TYPE1 unk2EC[0x4]; + /* 0x02F0 */ s16 unk_2F0; + /* 0x02F2 */ s16 unk_2F2; + /* 0x02F4 */ s16 unk_2F4; + /* 0x02F6 */ s16 unk_2F6; + /* 0x02F8 */ s32 unk_2F8; } EnBomBowlMan; // size = 0x2FC extern const ActorInit En_Bom_Bowl_Man_InitVars; 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 e6e584bb8..541fc071c 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,19 +1,30 @@ -#include "z_en_bom_chu.h" +/* + * File: z_en_bom_chu.c + * Overlay: ovl_En_Bom_Chu + * Description: Bombchus + */ -#define FLAGS 0x00000010 +#include "z_en_bom_chu.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnBomChu*)thisx) +#define BOMBCHU_SCALE 0.01f + void EnBomChu_Init(Actor* thisx, GlobalContext* globalCtx); void EnBomChu_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBomChu_Update(Actor* thisx, GlobalContext* globalCtx); void EnBomChu_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_808F7868(EnBomChu* this, GlobalContext* globalCtx); -void func_808F7A84(EnBomChu* this, GlobalContext* globalCtx); -void func_808F7FA0(EnBomChu* this, GlobalContext* globalCtx); +void EnBomChu_WaitForRelease(EnBomChu* this, GlobalContext* globalCtx); +void EnBomChu_SetupMove(EnBomChu* this); +void EnBomChu_Move(EnBomChu* this, GlobalContext* globalCtx); +void EnBomChu_Explode(EnBomChu* this, GlobalContext* globalCtx); +void EnBomChu_WaitForDeath(EnBomChu* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Bom_Chu_InitVars = { ACTOR_EN_BOM_CHU, ACTORCAT_EXPLOSIVES, @@ -26,50 +37,536 @@ const ActorInit En_Bom_Chu_InitVars = { (ActorFunc)EnBomChu_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_808F88E0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_1 | OC1_TYPE_2, OC2_TYPE_2, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_1 | OC1_TYPE_2, + OC2_TYPE_2, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 13 }, 100 }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808F890C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), + ICHAIN_VEC3F_DIV1000(scale, 1000 * BOMBCHU_SCALE, ICHAIN_STOP), }; -#endif +static EffectBlureInit2 sBlureInit = { + 0, 0, 0, { 250, 0, 0, 250 }, { 200, 0, 0, 130 }, { 150, 0, 0, 100 }, { 100, 0, 0, 50 }, 16, + 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, +}; -extern ColliderSphereInit D_808F88E0; -extern InitChainEntry D_808F890C[]; +void EnBomChu_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBomChu* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/EnBomChu_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + this->collider.dim.worldSphere.radius = sSphereInit.dim.modelSphere.radius; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/EnBomChu_Destroy.s") + Effect_Add(globalCtx, &this->blure1Index, EFFECT_BLURE2, 0, 0, &sBlureInit); + Effect_Add(globalCtx, &this->blure2Index, EFFECT_BLURE2, 0, 0, &sBlureInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F75D0.s") + this->timer = 120; + this->actor.room = -1; + this->shouldTimerCountDown = true; + this->unk_174 = 0.0f; + this->actionFunc = EnBomChu_WaitForRelease; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F77E4.s") +void EnBomChu_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBomChu* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7868.s") + Effect_Destroy(globalCtx, this->blure1Index); + Effect_Destroy(globalCtx, this->blure2Index); + Collider_DestroySphere(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7944.s") +/** + * Returns true if floorPoly is valid for the Bombchu to move on, false otherwise. + */ +s32 EnBomChu_UpdateFloorPoly(EnBomChu* this, CollisionPoly* floorPoly, GlobalContext* globalCtx) { + Vec3f normal; + Vec3f vec; + f32 angle; + f32 magnitude; + f32 normDotUp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F79D4.s") + this->actor.floorPoly = floorPoly; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7A84.s") + // This NULL check means if the player releases a Bombchu with no collision + // below them, the game will not crash, unlike OoT. + if (floorPoly != NULL) { + normal.x = COLPOLY_GET_NORMAL(floorPoly->normal.x); + normal.y = COLPOLY_GET_NORMAL(floorPoly->normal.y); + normal.z = COLPOLY_GET_NORMAL(floorPoly->normal.z); + } else { + EnBomChu_Explode(this, globalCtx); + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7E74.s") + normDotUp = DOTXYZ(normal, this->axisUp); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7FA0.s") + if (fabsf(normDotUp) >= 0.999f) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F7FD0.s") + angle = func_80086C48(normDotUp); + if (angle < 0.001f) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F8080.s") + Math3D_CrossProduct(&this->axisUp, &normal, &vec); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/func_808F818C.s") + magnitude = Math3D_Vec3fMagnitude(&vec); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/EnBomChu_Update.s") + if (magnitude < 0.001f) { + EnBomChu_Explode(this, globalCtx); + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bom_Chu/EnBomChu_Draw.s") + Math_Vec3f_Scale(&vec, 1.0f / magnitude); + Matrix_RotateAxisF(angle, &vec, MTXMODE_NEW); + Matrix_MultVec3f(&this->axisLeft, &vec); + Math_Vec3f_Copy(&this->axisLeft, &vec); + Math3D_CrossProduct(&this->axisLeft, &normal, &this->axisForwards); + + magnitude = Math3D_Vec3fMagnitude(&this->axisForwards); + if (magnitude < 0.001f) { + EnBomChu_Explode(this, globalCtx); + return false; + } + + Math_Vec3f_Scale(&this->axisForwards, 1.0f / magnitude); + Math_Vec3f_Copy(&this->axisUp, &normal); + return true; +} + +void EnBomChu_UpdateRotation(EnBomChu* this) { + MtxF mf; + + mf.xx = this->axisLeft.x; + mf.yx = this->axisLeft.y; + mf.zx = this->axisLeft.z; + + mf.xy = this->axisUp.x; + mf.yy = this->axisUp.y; + mf.zy = this->axisUp.z; + + mf.xz = this->axisForwards.x; + mf.yz = this->axisForwards.y; + mf.zz = this->axisForwards.z; + + Matrix_MtxFToYXZRot(&mf, &this->actor.world.rot, false); + this->actor.world.rot.x = -this->actor.world.rot.x; +} + +void EnBomChu_WaitForRelease(EnBomChu* this, GlobalContext* globalCtx) { + Player* player; + + if (this->timer == 0) { + EnBomChu_Explode(this, globalCtx); + } else if (Actor_HasNoParent(&this->actor, globalCtx)) { + player = GET_PLAYER(globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &player->actor.world.pos); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + this->actor.shape.rot.y = player->actor.shape.rot.y; + this->actor.flags |= ACTOR_FLAG_1; + func_800B8EF4(globalCtx, &this->actor); + + this->isMoving = true; + this->actor.speedXZ = 8.0f; + this->movingSpeed = 8.0f; + EnBomChu_SetupMove(this); + } +} + +s32 EnBomChu_IsOnCollisionPoly(GlobalContext* globalCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, + CollisionPoly** poly, s32* bgId) { + if ((BgCheck_EntityLineTest1(&globalCtx->colCtx, posA, posB, posResult, poly, true, true, true, true, bgId)) && + (!(func_800C9A4C(&globalCtx->colCtx, *poly, *bgId) & 0x30))) { + return true; + } + + return false; +} + +void EnBomChu_SetupMove(EnBomChu* this) { + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &this->actor.shape.rot); + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + + Matrix_MultVecY(1.0f, &this->axisUp); + Matrix_MultVecZ(1.0f, &this->axisForwards); + Matrix_MultVecX(1.0f, &this->axisLeft); + + this->actor.world.rot.x = -this->actor.shape.rot.x; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.z = this->actor.shape.rot.z; + this->actionFunc = EnBomChu_Move; +} + +void EnBomChu_Move(EnBomChu* this, GlobalContext* globalCtx) { + CollisionPoly* polySide = NULL; + CollisionPoly* polyUpDown = NULL; + s32 bgIdSide; + s32 bgIdUpDown; + s32 i; + s32 isFloorPolyValid; + f32 lineLength; + Vec3f posA; + Vec3f posB; + Vec3f posSide; + Vec3f posUpDown; + + bgIdUpDown = bgIdSide = BGCHECK_SCENE; + isFloorPolyValid = false; + + this->actor.speedXZ = this->movingSpeed; + lineLength = 2.0f * this->movingSpeed; + + if ((this->timer == 0) || (this->collider.base.acFlags & AC_HIT) || (this->collider.base.ocFlags1 & OC1_HIT)) { + EnBomChu_Explode(this, globalCtx); + return; + } + + posA.x = this->actor.world.pos.x + (this->axisUp.x * 2.0f); + posA.y = this->actor.world.pos.y + (this->axisUp.y * 2.0f); + posA.z = this->actor.world.pos.z + (this->axisUp.z * 2.0f); + + posB.x = this->actor.world.pos.x - (this->axisUp.x * 4.0f); + posB.y = this->actor.world.pos.y - (this->axisUp.y * 4.0f); + posB.z = this->actor.world.pos.z - (this->axisUp.z * 4.0f); + + if (EnBomChu_IsOnCollisionPoly(globalCtx, &posA, &posB, &posUpDown, &polyUpDown, &bgIdUpDown)) { + // forwards + posB.x = (this->axisForwards.x * lineLength) + posA.x; + posB.y = (this->axisForwards.y * lineLength) + posA.y; + posB.z = (this->axisForwards.z * lineLength) + posA.z; + + if (EnBomChu_IsOnCollisionPoly(globalCtx, &posA, &posB, &posSide, &polySide, &bgIdSide)) { + isFloorPolyValid = EnBomChu_UpdateFloorPoly(this, polySide, globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &posSide); + this->actor.floorBgId = bgIdSide; + this->actor.speedXZ = 0.0f; + } else { + if (this->actor.floorPoly != polyUpDown) { + isFloorPolyValid = EnBomChu_UpdateFloorPoly(this, polyUpDown, globalCtx); + } + + Math_Vec3f_Copy(&this->actor.world.pos, &posUpDown); + this->actor.floorBgId = bgIdUpDown; + } + } else { + this->actor.speedXZ = 0.0f; + lineLength *= 3.0f; + Math_Vec3f_Copy(&posA, &posB); + + for (i = 0; i < 3; i++) { + if (i == 0) { + // backwards + posB.x = posA.x - (this->axisForwards.x * lineLength); + posB.y = posA.y - (this->axisForwards.y * lineLength); + posB.z = posA.z - (this->axisForwards.z * lineLength); + } else if (i == 1) { + // left + posB.x = posA.x + (this->axisLeft.x * lineLength); + posB.y = posA.y + (this->axisLeft.y * lineLength); + posB.z = posA.z + (this->axisLeft.z * lineLength); + } else { + // right + posB.x = posA.x - (this->axisLeft.x * lineLength); + posB.y = posA.y - (this->axisLeft.y * lineLength); + posB.z = posA.z - (this->axisLeft.z * lineLength); + } + + if (EnBomChu_IsOnCollisionPoly(globalCtx, &posA, &posB, &posSide, &polySide, &bgIdSide)) { + isFloorPolyValid = EnBomChu_UpdateFloorPoly(this, polySide, globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &posSide); + this->actor.floorBgId = bgIdSide; + break; + } + } + + if (i == 3) { + // no collision nearby + EnBomChu_Explode(this, globalCtx); + } + } + + if (isFloorPolyValid) { + EnBomChu_UpdateRotation(this); + this->actor.shape.rot.x = -this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + } + + if (this->isMoving) { + func_800B8F98(&this->actor, NA_SE_IT_BOMBCHU_MOVE - SFX_FLAG); + } + + if (this->actor.speedXZ != 0.0f) { + this->movingSpeed = this->actor.speedXZ; + } +} + +void EnBomChu_Explode(EnBomChu* this, GlobalContext* globalCtx) { + EnBom* bomb; + s32 i; + + 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); + + this->shouldTimerCountDown = true; + this->isMoving = false; + + if (bomb != NULL) { + bomb->timer = 0; + } + + this->timer = 1; + this->actor.speedXZ = 0.0f; + + if (this->actor.depthInWater > 0.0f) { + for (i = 0; i < 40; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 1.0f, 5.0f, 30.0f, 0.25f); + } + } + + this->actor.draw = NULL; + this->actionFunc = EnBomChu_WaitForDeath; +} + +void EnBomChu_WaitForDeath(EnBomChu* this, GlobalContext* globalCtx) { + if (this->timer == 0) { + Actor_MarkForDeath(&this->actor); + } +} + +/** + * Transform coordinates from actor coordinate space to world space, according to current orientation. + * `offset` is expected to already be at world scale. + */ +void EnBomChu_ActorCoordsToWorld(EnBomChu* this, Vec3f* offset, Vec3f* pos) { + f32 x = offset->x + this->visualJitter; + + pos->x = this->actor.world.pos.x + (this->axisLeft.x * x) + (this->axisUp.x * offset->y) + + (this->axisForwards.x * offset->z); + pos->y = this->actor.world.pos.y + (this->axisLeft.y * x) + (this->axisUp.y * offset->y) + + (this->axisForwards.y * offset->z); + pos->z = this->actor.world.pos.z + (this->axisLeft.z * x) + (this->axisUp.z * offset->y) + + (this->axisForwards.z * offset->z); +} + +void EnBomChu_SpawnRipplesAndSplashes(EnBomChu* this, GlobalContext* globalCtx, f32 y, s32 spawnExtraRipples) { + s32 pad; + Vec3f pos; + + pos.x = this->actor.world.pos.x; + pos.y = y; + pos.z = this->actor.world.pos.z; + + EffectSsGRipple_Spawn(globalCtx, &pos, 70, 500, 0); + + if (spawnExtraRipples) { + EffectSsGRipple_Spawn(globalCtx, &pos, 70, 500, 4); + EffectSsGRipple_Spawn(globalCtx, &pos, 70, 500, 8); + } else { + pos.x -= this->axisForwards.x * 10.0f; + pos.z -= this->axisForwards.z * 10.0f; + } + + pos.y += 5.0f; + EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 1, 450); +} + +void EnBomChu_HandleNonSceneCollision(EnBomChu* this, GlobalContext* globalCtx) { + Vec3f originalWorldPos; + Vec3f posA; + Vec3f posB; + Vec3f originalAxisUp; + s16 yaw; + f32 sin; + f32 cos; + f32 tempX; + CollisionPoly* poly = NULL; + s32 bgId = BGCHECK_SCENE; + s32 isFloorPolyValid; + + Math_Vec3f_Copy(&originalWorldPos, &this->actor.world.pos); + Math_Vec3f_Copy(&originalAxisUp, &this->axisUp); + yaw = this->actor.shape.rot.y; + BgCheck2_UpdateActorAttachedToMesh(&globalCtx->colCtx, this->actor.floorBgId, &this->actor); + + if (yaw != this->actor.shape.rot.y) { + yaw = this->actor.shape.rot.y - yaw; + + sin = Math_SinS(yaw); + cos = Math_CosS(yaw); + + tempX = this->axisForwards.x; + this->axisForwards.x = (sin * this->axisForwards.z) + (cos * tempX); + this->axisForwards.z = (cos * this->axisForwards.z) - (sin * tempX); + + tempX = this->axisUp.x; + this->axisUp.x = (sin * this->axisUp.z) + (cos * tempX); + this->axisUp.z = (cos * this->axisUp.z) - (sin * tempX); + + tempX = this->axisLeft.x; + this->axisLeft.x = (sin * this->axisLeft.z) + (cos * tempX); + this->axisLeft.z = (cos * this->axisLeft.z) - (sin * tempX); + } + + posA.x = originalWorldPos.x + (2.0f * originalAxisUp.x); + posA.y = originalWorldPos.y + (2.0f * originalAxisUp.y); + posA.z = originalWorldPos.z + (2.0f * originalAxisUp.z); + + posB.x = this->actor.world.pos.x + (2.0f * this->axisUp.x); + posB.y = this->actor.world.pos.y + (2.0f * this->axisUp.y); + posB.z = this->actor.world.pos.z + (2.0f * this->axisUp.z); + + if (EnBomChu_IsOnCollisionPoly(globalCtx, &posA, &posB, &originalWorldPos, &poly, &bgId)) { + isFloorPolyValid = EnBomChu_UpdateFloorPoly(this, poly, globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &originalWorldPos); + this->actor.floorBgId = bgId; + this->actor.speedXZ = 0.0f; + + if (isFloorPolyValid) { + EnBomChu_UpdateRotation(this); + this->actor.shape.rot.x = -this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + } + } +} + +void EnBomChu_Update(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f sBlureP1Offset = { 0.0f, 7.0f, -6.0f }; + static Vec3f sBlureP2LeftOffset = { 12.0f, 0.0f, -5.0f }; + static Vec3f sBlureP2RightOffset = { -12.0f, 0.0f, -5.0f }; + s32 pad; + EnBomChu* this = THIS; + Vec3f blureP1; + Vec3f blureP2; + WaterBox* waterBox; + f32 waterY; + + if (this->actor.floorBgId != BGCHECK_SCENE) { + EnBomChu_HandleNonSceneCollision(this, globalCtx); + } + + if (this->shouldTimerCountDown) { + this->timer--; + } + + this->actionFunc(this, globalCtx); + + if ((this->actionFunc != EnBomChu_WaitForDeath) && + (SurfaceType_IsWallDamage(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId))) { + EnBomChu_Explode(this, globalCtx); + return; + } + + Actor_MoveWithoutGravity(&this->actor); + + this->collider.dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.dim.worldSphere.center.y = this->actor.world.pos.y; + this->collider.dim.worldSphere.center.z = this->actor.world.pos.z; + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->actionFunc != EnBomChu_WaitForRelease) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + this->actor.focus.pos.x = this->actor.world.pos.x + (20.0f * this->axisUp.x); + this->actor.focus.pos.y = this->actor.world.pos.y + (20.0f * this->axisUp.y); + this->actor.focus.pos.z = this->actor.world.pos.z + (20.0f * this->axisUp.z); + + if (this->isMoving) { + this->visualJitter = + (5.0f + (Rand_ZeroOne() * 3.0f)) * Math_SinS((((s32)(Rand_ZeroOne() * 512.0f) + 0x3000) * this->timer)); + EnBomChu_ActorCoordsToWorld(this, &sBlureP1Offset, &blureP1); + + EnBomChu_ActorCoordsToWorld(this, &sBlureP2LeftOffset, &blureP2); + EffectBlure_AddVertex(Effect_GetByIndex(this->blure1Index), &blureP1, &blureP2); + + EnBomChu_ActorCoordsToWorld(this, &sBlureP2RightOffset, &blureP2); + EffectBlure_AddVertex(Effect_GetByIndex(this->blure2Index), &blureP1, &blureP2); + + waterY = this->actor.world.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &waterY, &waterBox)) { + this->actor.depthInWater = waterY - this->actor.world.pos.y; + + if (this->actor.depthInWater < 0.0f) { + if (this->actor.bgCheckFlags & 0x20) { + EnBomChu_SpawnRipplesAndSplashes(this, globalCtx, waterY, true); + } + + this->actor.bgCheckFlags &= ~0x20; + return; + } + + if (!(this->actor.bgCheckFlags & 0x20) && (this->timer != 120)) { + EnBomChu_SpawnRipplesAndSplashes(this, globalCtx, waterY, true); + } else { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, 3.0f, 15.0f, 0.25f); + } + + this->actor.bgCheckFlags |= 0x20; + } else { + this->actor.bgCheckFlags &= ~0x20; + this->actor.depthInWater = BGCHECK_Y_MIN; + } + } +} + +void EnBomChu_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnBomChu* this = THIS; + f32 colorIntensity; + s32 blinkHalfPeriod; + s32 blinkTime; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_800B8050(&this->actor, globalCtx, 0); + + if (this->timer >= 40) { + blinkTime = this->timer % 20; + blinkHalfPeriod = 10; + } else if (this->timer >= 10) { + blinkTime = this->timer % 10; + blinkHalfPeriod = 5; + } else { + blinkTime = this->timer & 1; + blinkHalfPeriod = 1; + } + + if (blinkTime > blinkHalfPeriod) { + blinkTime = 2 * blinkHalfPeriod - blinkTime; + } + + colorIntensity = blinkTime / (f32)blinkHalfPeriod; + gDPSetEnvColor(POLY_OPA_DISP++, (s32)(colorIntensity * 209.0f) + 9, (s32)(colorIntensity * 34.0f) + 9, + (s32)(colorIntensity * -35.0f) + 35, 255); + Matrix_Translate(this->visualJitter * (1.0f / BOMBCHU_SCALE), 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++, gBombchuDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..30a3dab9a 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 @@ -8,9 +8,21 @@ struct EnBomChu; typedef void (*EnBomChuActionFunc)(struct EnBomChu*, GlobalContext*); typedef struct EnBomChu { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnBomChuActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x98]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnBomChuActionFunc actionFunc; + /* 0x148 */ u8 shouldTimerCountDown; // the actor always sets this to true + /* 0x149 */ u8 isMoving; + /* 0x14A */ s16 timer; + /* 0x14C */ Vec3f axisForwards; + /* 0x158 */ Vec3f axisUp; + /* 0x164 */ Vec3f axisLeft; + /* 0x170 */ f32 visualJitter; + /* 0x174 */ f32 unk_174; // set but never used + /* 0x178 */ UNK_TYPE1 unk_178[0x4]; + /* 0x17C */ f32 movingSpeed; + /* 0x180 */ s32 blure1Index; + /* 0x184 */ s32 blure2Index; + /* 0x188 */ ColliderSphere collider; } 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 75eb00e81..479df5cd7 100644 --- a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c +++ b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bombal.c + * Overlay: ovl_En_Bombal + * Description: Bombers - Majora Balloon + */ + #include "z_en_bombal.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnBombal*)thisx) 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 7786d5c03..a76c901eb 100644 --- a/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c +++ b/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c @@ -1,6 +1,14 @@ -#include "z_en_bombers.h" +/* + * File: z_en_bombers.c + * Overlay: ovl_En_Bombers + * Description: Bombers - Blue-Hatted Bomber + */ -#define FLAGS 0x00000009 +#include "z_en_bombers.h" +#include "overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.h" +#include "objects/object_cs/object_cs.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBombers*)thisx) @@ -9,12 +17,14 @@ void EnBombers_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBombers_Update(Actor* thisx, GlobalContext* globalCtx); void EnBombers_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80C03ACC(EnBombers* this); void func_80C03AF4(EnBombers* this, GlobalContext* globalCtx); +void func_80C03F64(EnBombers* this); void func_80C03FAC(EnBombers* this, GlobalContext* globalCtx); +void func_80C042F8(EnBombers* this); void func_80C04354(EnBombers* this, GlobalContext* globalCtx); void func_80C043C8(EnBombers* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Bombers_InitVars = { ACTOR_EN_BOMBERS, ACTORCAT_NPC, @@ -27,45 +37,495 @@ const ActorInit En_Bombers_InitVars = { (ActorFunc)EnBombers_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C04770 = { - { 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 } }, }; -#endif +AnimationHeader* D_80C0479C[] = { + &gBomberIdleAnim, &object_cs_Anim_0053F4, &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, +}; -extern ColliderCylinderInit D_80C04770; +u8 D_80C047E0[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, + ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, +}; -extern UNK_TYPE D_060064B8; +#include "overlays/ovl_En_Bombers/ovl_En_Bombers.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/EnBombers_Init.s") +Gfx* D_80C04818[] = { + ovl_En_Bombers_DL_12C8, ovl_En_Bombers_DL_12D8, ovl_En_Bombers_DL_12D8, + ovl_En_Bombers_DL_12D8, ovl_En_Bombers_DL_12D8, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/EnBombers_Destroy.s") +TexturePtr D_80C0482C[] = { + object_cs_Tex_00C520, + object_cs_Tex_00CD20, + object_cs_Tex_00D520, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C03824.s") +TexturePtr D_80C04838[] = { + object_cs_Tex_00E620, object_cs_Tex_00EA20, object_cs_Tex_00EE20, object_cs_Tex_00DD20, object_cs_Tex_00F220, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C038B4.s") +void EnBombers_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBombers* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C039A8.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + this->actor.gravity = -1.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &gBomberIdleAnim, this->jointTable, + this->morphtable, 21); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.targetMode = 0; + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C03ACC.s") + this->unk_2BC = ENBOMBERS_GET_F0(&this->actor); + this->unk_2BE = ENBOMBERS_GET_F(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C03AF4.s") + if (this->unk_2BC == ENBOMBERS_F0_0) { + if ((gSaveContext.save.weekEventReg[73] & 0x10) || (gSaveContext.save.weekEventReg[85] & 2)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2BE++; + func_80C03ACC(this); + } + } else if (((gSaveContext.save.weekEventReg[73] & 0x10) || (gSaveContext.save.weekEventReg[85] & 2)) && + (((this->unk_2BE == ENBOMBERS_F_0) && (gSaveContext.save.weekEventReg[76] & 1)) || + ((this->unk_2BE == ENBOMBERS_F_1) && (gSaveContext.save.weekEventReg[76] & 2)) || + ((this->unk_2BE == ENBOMBERS_F_2) && (gSaveContext.save.weekEventReg[76] & 4)) || + ((this->unk_2BE == ENBOMBERS_F_3) && (gSaveContext.save.weekEventReg[76] & 8)) || + ((this->unk_2BE == ENBOMBERS_F_4) && (gSaveContext.save.weekEventReg[76] & 0x10)))) { + if (gSaveContext.save.weekEventReg[75] & 0x40) { + if (this->unk_2BE == ENBOMBERS_F_0) { + EnBomBowlMan* bomBowlMan = (EnBomBowlMan*)Actor_Spawn( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM_BOWL_MAN, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C03F64.s") + if (bomBowlMan != NULL) { + s32 cs = this->actor.cutscene; + s32 i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C03FAC.s") + // clang-format off + while (cs != -1) { bomBowlMan->unk_2CC[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs); i++; } + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C042F8.s") + gSaveContext.save.weekEventReg[76] &= (u8)~1; + gSaveContext.save.weekEventReg[76] &= (u8)~2; + gSaveContext.save.weekEventReg[76] &= (u8)~4; + gSaveContext.save.weekEventReg[76] &= (u8)~8; + gSaveContext.save.weekEventReg[76] &= (u8)~0x10; + } + } + Actor_MarkForDeath(&this->actor); + } else { + func_80C042F8(this); + } + } else { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C04354.s") +void EnBombers_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBombers* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C043C8.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/EnBombers_Update.s") +void func_80C03824(EnBombers* this, s32 arg1, f32 arg2) { + this->unk_2C4 = arg1; + this->unk_2B0 = Animation_GetLastFrame(D_80C0479C[arg1]); + Animation_Change(&this->skelAnime, D_80C0479C[this->unk_2C4], arg2, 0.0f, this->unk_2B0, D_80C047E0[this->unk_2C4], + -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/func_80C045B4.s") +void func_80C038B4(EnBombers* this) { + if ((this->unk_2C4 == 2) && + (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) || + Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 18.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers/EnBombers_Draw.s") + if ((this->unk_2C4 == 15) && + (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 2.0f) || + Animation_OnFrame(&this->skelAnime, 4.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } +} + +void func_80C039A8(EnBombers* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + this->unk_2A6 = 5; + + switch (player->transformation) { + case PLAYER_FORM_HUMAN: + this->actor.textId = 0x73D; + if (gSaveContext.save.weekEventReg[84] & 0x80) { + this->actor.textId = 0x74B; + } + break; + + case PLAYER_FORM_GORON: + this->actor.textId = 0x73E; + break; + + case PLAYER_FORM_ZORA: + this->actor.textId = 0x73F; + break; + + case PLAYER_FORM_DEKU: + if (gSaveContext.save.weekEventReg[73] & 0x20) { + this->actor.textId = 0x75A; + } else if (gSaveContext.save.weekEventReg[73] & 0x40) { + this->actor.textId = 0x749; + if (((this->unk_2BE == ENBOMBERS_F_1) && (gSaveContext.save.weekEventReg[74] & 1)) || + ((this->unk_2BE == ENBOMBERS_F_2) && (gSaveContext.save.weekEventReg[74] & 2)) || + ((this->unk_2BE == ENBOMBERS_F_3) && (gSaveContext.save.weekEventReg[74] & 4)) || + ((this->unk_2BE == ENBOMBERS_F_4) && (gSaveContext.save.weekEventReg[74] & 8))) { + this->actor.textId = 0x74A; + } + } else { + this->actor.textId = 0x744; + } + break; + } +} + +void func_80C03ACC(EnBombers* this) { + this->collider.dim.radius = 10; + this->collider.dim.height = 30; + this->unk_2C0 = 0; + this->actionFunc = func_80C03AF4; +} + +void func_80C03AF4(EnBombers* this, GlobalContext* globalCtx) { + CollisionPoly* colPoly; + f32 curFrame = this->skelAnime.curFrame; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + f32 x; + f32 z; + s32 sp48; + s16 abs; + + switch (this->unk_2A0) { + case 0: + if (this->unk_2A8 == 0) { + Math_Vec3f_Copy(&sp60, &this->actor.home.pos); + + sp60.x += randPlusMinusPoint5Scaled(150.0f); + sp60.z += randPlusMinusPoint5Scaled(150.0f); + + abs = ABS_ALT(BINANG_SUB(this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp60))); + if ((abs < 0x4000) && !BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp60, &sp6C, + &colPoly, true, false, false, true, &sp48)) { + func_80C03824(this, 2, 1.0f); + Math_Vec3f_Copy(&this->unk_294, &sp60); + this->unk_2AA = Rand_S16Offset(30, 50); + this->unk_2A0++; + } + } + break; + + case 1: + if (curFrame >= 0.0f) { + this->unk_2A4 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_294); + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2A4, 0xA, 0x7D0, 0x14); + } + + if ((s16)ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->unk_2A4)) < 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, &sp6C, &colPoly, true, + false, false, true, &sp48)) { + this->unk_2A8 = 0; + if (Rand_ZeroOne() < 0.5f) { + func_80C03824(this, 16, 1.0f); + } else { + func_80C03824(this, 0, 1.0f); + } + this->unk_2A0 = 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_2AA == 0) || (sqrtf(SQ(x) + SQ(z)) < 4.0f)) { + this->unk_2A8 = Rand_S16Offset(20, 20); + if (!(this->unk_2A8 & 1)) { + func_80C03824(this, 16, 1.0f); + } else { + func_80C03824(this, 0, 1.0f); + } + this->unk_2A0 = 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 (!Text_GetFaceReaction(globalCtx, 0x12)) { + func_80C039A8(this, globalCtx); + } else { + this->unk_2A6 = 5; + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x12); + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_2A4 = this->actor.yawTowardsPlayer; + this->collider.dim.radius = 20; + this->collider.dim.height = 60; + func_80C03F64(this); + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void func_80C03F64(EnBombers* this) { + this->unk_2A4 = this->actor.yawTowardsPlayer; + func_80C03824(this, 1, 1.0f); + this->unk_2C0 = 1; + this->actionFunc = func_80C03FAC; +} + +void func_80C03FAC(EnBombers* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp2A; + + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2A4, 1, 0x1388, 0); + + switch (player->transformation) { + case PLAYER_FORM_HUMAN: + this->unk_28E = -0xFA0; + break; + + case PLAYER_FORM_GORON: + case PLAYER_FORM_ZORA: + this->unk_28E = -0x1770; + break; + } + + if ((this->unk_2A6 == Message_GetState(&globalCtx->msgCtx)) && Message_ShouldAdvance(globalCtx)) { + sp2A = 0; + func_801477B4(globalCtx); + this->unk_2A6 = 5; + + if ((this->actor.textId == 0x73D) || (this->actor.textId == 0x73E) || (this->actor.textId == 0x73F)) { + this->actor.textId = 0x740; + this->unk_2A6 = 4; + sp2A = 1; + } else if (this->actor.textId == 0x740) { + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + this->actor.textId = 0x742; + sp2A = 1; + } else { + func_8019F230(); + this->actor.textId = 0x741; + sp2A = 1; + } + } else if (this->actor.textId == 0x742) { + this->actor.textId = 0x737; + sp2A = 1; + } else if (this->actor.textId == 0x737) { + this->actor.textId = 0x743; + sp2A = 1; + } else if (this->actor.textId == 0x74B) { + this->actor.textId = 0x74C; + this->unk_2A6 = 4; + sp2A = 1; + } else if (this->actor.textId == 0x74C) { + if (globalCtx->msgCtx.choiceIndex == 1) { + func_8019F230(); + this->actor.textId = 0x737; + sp2A = 1; + } else { + func_8019F208(); + this->actor.textId = 0x74D; + func_80C03824(this, 14, 1.0f); + sp2A = 1; + } + } else if (this->actor.textId == 0x744) { + s32 day = gSaveContext.save.day - 1; + + if (day == 2) { + this->actor.textId = 0x746; + sp2A = 1; + } else { + this->actor.textId = 0x745; + sp2A = 1; + } + } else if ((this->actor.textId == 0x745) || (this->actor.textId == 0x746)) { + this->actor.textId = 0x747; + sp2A = 1; + } else if (this->actor.textId == 0x747) { + this->actor.textId = 0x748; + sp2A = 1; + } else if (this->actor.textId == 0x748) { + switch (this->unk_2BE) { + case ENBOMBERS_F_1: + gSaveContext.save.weekEventReg[74] |= 1; + break; + + case ENBOMBERS_F_2: + gSaveContext.save.weekEventReg[74] |= 2; + break; + + case ENBOMBERS_F_3: + gSaveContext.save.weekEventReg[74] |= 4; + break; + + case ENBOMBERS_F_4: + gSaveContext.save.weekEventReg[74] |= 8; + break; + } + gSaveContext.save.weekEventReg[73] |= 0x40; + } + + switch (sp2A) { + case 0: + this->unk_28E = 0; + func_80C03ACC(this); + break; + + case 1: + func_80151938(globalCtx, this->actor.textId); + break; + } + } +} + +void func_80C042F8(EnBombers* this) { + if (this->unk_2C4 != 6) { + func_80C03824(this, 6, 1.0f); + } + this->actor.textId = 0x72D; + this->unk_28E = 0x1F40; + this->unk_2C0 = 2; + this->actionFunc = func_80C04354; +} + +void func_80C04354(EnBombers* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 0x3E8, 0); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_28E = 0; + this->actionFunc = func_80C043C8; + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void func_80C043C8(EnBombers* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 0x3E8, 0); + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80C042F8(this); + } +} + +void EnBombers_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBombers* this = THIS; + + if (this->unk_2AA != 0) { + this->unk_2AA--; + } + + if (this->unk_2A8 != 0) { + this->unk_2A8--; + } + + if (this->unk_2AC != 0) { + this->unk_2AC--; + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80C038B4(this); + Actor_SetFocus(&this->actor, 20.0f); + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 0x1388, 0); + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 0x1388, 0); + + if (this->unk_2BA == 0) { + this->unk_2B8++; + if (this->unk_2B8 >= 3) { + this->unk_2B8 = 0; + this->unk_2BA = (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 EnBombers_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBombers* this = THIS; + + if (limbIndex == OBJECT_CS_LIMB_0F) { + *dList = NULL; + } + + if (limbIndex == OBJECT_CS_LIMB_11) { + rot->x += this->unk_28A; + rot->z += this->unk_288; + } + + if (limbIndex == OBJECT_CS_LIMB_13) { + *dList = NULL; + } + + return false; +} + +void EnBombers_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnBombers* 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_80C0482C[this->unk_2B8])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C04838[this->unk_2BE])); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_80C04818[this->unk_2BE])); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnBombers_OverrideLimbDraw, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bombers/z_en_bombers.h b/src/overlays/actors/ovl_En_Bombers/z_en_bombers.h index 630c26e65..c51150df8 100644 --- a/src/overlays/actors/ovl_En_Bombers/z_en_bombers.h +++ b/src/overlays/actors/ovl_En_Bombers/z_en_bombers.h @@ -7,11 +7,47 @@ struct EnBombers; typedef void (*EnBombersActionFunc)(struct EnBombers*, GlobalContext*); +#define ENBOMBERS_GET_F(thisx) ((thisx)->params & 0xF) +#define ENBOMBERS_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) + +enum { + /* 0 */ ENBOMBERS_F_0, + /* 1 */ ENBOMBERS_F_1, + /* 2 */ ENBOMBERS_F_2, + /* 3 */ ENBOMBERS_F_3, + /* 4 */ ENBOMBERS_F_4, +}; + +#define ENBOMBERS_F0_0 0 + typedef struct EnBombers { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x140]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[21]; + /* 0x0206 */ Vec3s morphtable[21]; /* 0x0284 */ EnBombersActionFunc actionFunc; - /* 0x0288 */ char unk_288[0x8C]; + /* 0x0288 */ s16 unk_288; + /* 0x028A */ s16 unk_28A; + /* 0x028C */ UNK_TYPE1 unk28C[2]; + /* 0x028E */ s16 unk_28E; + /* 0x0290 */ s16 unk_290; + /* 0x0294 */ Vec3f unk_294; + /* 0x02A0 */ s16 unk_2A0; + /* 0x02A2 */ UNK_TYPE1 unk2A2[2]; + /* 0x02A4 */ s16 unk_2A4; + /* 0x02A6 */ s16 unk_2A6; + /* 0x02A8 */ s16 unk_2A8; + /* 0x02AA */ s16 unk_2AA; + /* 0x02AC */ s16 unk_2AC; + /* 0x02B0 */ f32 unk_2B0; + /* 0x02B4 */ f32 unk_2B4; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA; + /* 0x02BC */ s16 unk_2BC; + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C4 */ s32 unk_2C4; + /* 0x02C8 */ ColliderCylinder collider; } EnBombers; // size = 0x314 extern const ActorInit En_Bombers_InitVars; 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 6d7a8d43a..8b2fa6d90 100644 --- a/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c +++ b/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bombers2.c + * Overlay: ovl_En_Bombers2 + * Description: Bombers - Hideout Guard + */ + #include "z_en_bombers2.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBombers2*)thisx) @@ -12,8 +18,11 @@ void EnBombers2_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80C04BA0(EnBombers2* this, GlobalContext* globalCtx); void func_80C04D8C(EnBombers2* this, GlobalContext* globalCtx); void func_80C0520C(EnBombers2* this, GlobalContext* globalCtx); +void func_80C04B40(EnBombers2* this); +void EnBombers2_ChangeAnim(EnBombers2* this, s32 animIndex, f32 playSpeed); +void func_80C04D00(EnBombers2* this); +void func_80C050B8(EnBombers2* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Bombers2_InitVars = { ACTOR_EN_BOMBERS2, ACTORCAT_NPC, @@ -26,39 +35,404 @@ const ActorInit En_Bombers2_InitVars = { (ActorFunc)EnBombers2_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C058B0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static u16 sTextIds[] = { + 0x0727, 0x0728, 0x0726, 0x0729, 0x072B, 0x0725, 0x072A, 0x073C, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 35, 30, 0, { 0, 0, 0 } }, }; -#endif +static AnimationHeader* sAnimations[] = { + &gBomberIdleAnim, &object_cs_Anim_0053F4, &object_cs_Anim_01007C, &object_cs_Anim_00349C, + &object_cs_Anim_0060E8, &object_cs_Anim_005DC4, &object_cs_Anim_0026B0, +}; -extern ColliderCylinderInit D_80C058B0; +static u8 sAnimModes[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, +}; -extern UNK_TYPE D_060064B8; +static Gfx sSetPrimColorDL[] = { + gsDPSetPrimColor(0, 0xFF, 198, 140, 0, 255), + gsSPEndDisplayList(), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/EnBombers2_Init.s") +static Gfx* sSetPrimColorDlPtr = sSetPrimColorDL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/EnBombers2_Destroy.s") +static TexturePtr sEyeTextures[] = { + object_cs_Tex_00C520, + object_cs_Tex_00CD20, + object_cs_Tex_00D520, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C04AAC.s") +static TexturePtr D_80C05920 = object_cs_Tex_00E220; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C04B40.s") +void EnBombers2_Init(Actor* thisx, GlobalContext* globalCtx) { + f32 cos; + EnBombers2* this = (EnBombers2*)thisx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C04BA0.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &gBomberIdleAnim, this->morphTable, + this->jointTable, OBJECT_CS_LIMB_MAX); + this->actor.targetMode = 6; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + if ((gSaveContext.save.weekEventReg[73] & 0x80) || (gSaveContext.save.entranceIndex == 0xD220)) { + this->actor.world.pos.x += Math_SinS(this->actor.home.rot.y + 0xC100) * 50.0f; + cos = Math_CosS(this->actor.home.rot.y + 0xC100) * 50.0f; + this->unk_2AC = 1; + this->actor.world.pos.z += cos; + } + this->cutscene = this->actor.cutscene; + if (this->cutscene == 0) { + Actor_MarkForDeath(&this->actor); + } + func_80C04B40(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C04D00.s") +void EnBombers2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBombers2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C04D8C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C050B8.s") +void EnBombers2_ChangeAnim(EnBombers2* this, s32 animIndex, f32 playSpeed) { + f32 lastFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C0520C.s") + this->animIndex = animIndex; + lastFrame = Animation_GetLastFrame(sAnimations[this->animIndex]); + this->lastAnimFrame = lastFrame; + Animation_Change(&this->skelAnime, sAnimations[this->animIndex], playSpeed, 0.0f, lastFrame, + sAnimModes[this->animIndex], -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/EnBombers2_Update.s") +void func_80C04B40(EnBombers2* this) { + if (this->unk_2AC == 0) { + EnBombers2_ChangeAnim(this, 4, 1.0f); + } else { + EnBombers2_ChangeAnim(this, 0, 1.0f); + } + this->unk_2C0 = 0; + this->actionFunc = func_80C04BA0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/func_80C056D4.s") +void func_80C04BA0(EnBombers2* this, GlobalContext* globalCtx) { + s32 yawDiffAbs; + s16 yawDiff; + Player* player; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombers2/EnBombers2_Draw.s") + yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + yawDiffAbs = ABS_ALT(yawDiff); + player = GET_PLAYER(globalCtx); + + switch (player->transformation) { + case PLAYER_FORM_GORON: + case PLAYER_FORM_ZORA: + this->textIdIndex = 1; + this->unk_2CE = 5; + break; + case PLAYER_FORM_DEKU: + case PLAYER_FORM_HUMAN: + this->textIdIndex = 2; + this->unk_2CE = 5; + break; + } + if (this->unk_2AC != 0) { + this->textIdIndex = 7; + } + this->actor.textId = sTextIds[this->textIdIndex]; + + if (Text_GetFaceReaction(globalCtx, 0x15) != 0) { + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x15); + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_2B6 = this->actor.world.rot.y; + gSaveContext.save.weekEventReg[86] |= 2; + func_80C04D00(this); + return; + } + if (yawDiffAbs < 0x3BB5) { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void func_80C04D00(EnBombers2* this) { + if ((this->textIdIndex == 0) || (this->textIdIndex == 1)) { + EnBombers2_ChangeAnim(this, 5, 1.0f); + } else { + EnBombers2_ChangeAnim(this, 1, 1.0f); + } + + this->unk_2A8 = 0; + if (this->unk_2AC != 0) { + EnBombers2_ChangeAnim(this, 6, 1.0f); + } + this->unk_2C0 = 1; + this->actionFunc = func_80C04D8C; +} + +void func_80C04D8C(EnBombers2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 temp = this->skelAnime.curFrame; + + if ((this->unk_2AC == 0) && (this->lastAnimFrame <= temp)) { + if (!(this->unk_2A8 & 1)) { + EnBombers2_ChangeAnim(this, 1, 1.0f); + } else { + EnBombers2_ChangeAnim(this, 5, 1.0f); + } + this->unk_2A8++; + this->unk_2A8 &= 1; + } + switch (player->transformation) { + case PLAYER_FORM_HUMAN: + this->unk_28E = -0xFA0; + break; + case PLAYER_FORM_GORON: + case PLAYER_FORM_ZORA: + this->unk_28E = -0x1770; + break; + default: + break; + } + if ((this->unk_2CE == Message_GetState(&globalCtx->msgCtx)) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_2CE == 0xF) { + s32 i; + s32 correctDigits; + + for (i = 0; i < ARRAY_COUNT(this->correctDigitSlots); i++) { + if (!(this->correctDigitSlots[i]) && + (globalCtx->msgCtx.unk12054[i] == gSaveContext.save.bomberCode[i])) { + this->correctDigitSlots[i] = true; + } + } + for (i = 0, correctDigits = 0; i < ARRAY_COUNT(this->correctDigitSlots); i++) { + if (this->correctDigitSlots[i]) { + correctDigits++; + } + } + + if (correctDigits >= 5) { + this->textIdIndex = 6; + this->actor.textId = sTextIds[this->textIdIndex]; + func_80151938(globalCtx, this->actor.textId); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_PIECE_OF_HEART); + this->unk_2CE = 5; + return; + } + } + if (Text_GetFaceReaction(globalCtx, 0x15) != 0) { + this->unk_28E = 0; + func_801477B4(globalCtx); + func_80C04B40(this); + } else { + s32 j; + + switch (this->textIdIndex) { + case 0: + case 1: + case 5: + case 7: + this->unk_28E = 0; + func_801477B4(globalCtx); + func_80C04B40(this); + break; + case 2: + this->textIdIndex = 3; + this->actor.textId = sTextIds[this->textIdIndex]; + func_80151938(globalCtx, this->actor.textId); + this->unk_2CE = 0xF; + break; + case 3: + for (j = 0; j < ARRAY_COUNT(this->correctDigitSlots); j++) { + this->correctDigitSlots[j] = false; + } + this->textIdIndex = 4; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); + this->actor.textId = sTextIds[this->textIdIndex]; + func_80151938(globalCtx, this->actor.textId); + this->unk_2CE = 5; + break; + case 4: + this->textIdIndex = 5; + this->actor.textId = sTextIds[this->textIdIndex]; + func_80151938(globalCtx, this->actor.textId); + this->unk_2CE = 5; + break; + case 6: + globalCtx->msgCtx.unk11F10 = 0; + func_80C050B8(this, globalCtx); + break; + } + } + } +} + +void func_80C050B8(EnBombers2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 homeYawToPlayer; + + EnBombers2_ChangeAnim(this, 2, 1.0f); + this->unk_2A8 = 0; + homeYawToPlayer = Math_Vec3f_Yaw(&this->actor.home.pos, &player->actor.world.pos); + Math_Vec3f_Copy(&this->unk_29C, &this->actor.world.pos); + if (this->actor.home.rot.y < homeYawToPlayer) { + this->unk_29C.x += Math_SinS(this->actor.home.rot.y + 0xC100) * 50.0f; + this->unk_29C.z += Math_CosS(this->actor.home.rot.y + 0xC100) * 50.0f; + } else { + this->unk_29C.x += Math_SinS(this->actor.home.rot.y + 0x3F00) * 50.0f; + this->unk_29C.z += Math_CosS(this->actor.home.rot.y + 0x3F00) * 50.0f; + } + this->unk_2B6 = Math_Vec3f_Yaw(&this->actor.home.pos, &this->unk_29C); + this->unk_2C0 = 2; + this->actionFunc = func_80C0520C; +} + +void func_80C0520C(EnBombers2* this, GlobalContext* globalCtx) { + if (this->unk_2A8 == 0) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->cutscene) == 0) { + ActorCutscene_SetIntentToPlay(this->cutscene); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->cutscene, &this->actor); + this->unk_2A8 = 1; + } + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2B6, 1, 0xBB8, 0); + if ((fabsf(this->unk_29C.x - this->actor.world.pos.x) < 3.0f) && + (fabsf(this->unk_29C.z - this->actor.world.pos.z) < 3.0f)) { + this->unk_2B6 = this->actor.yawTowardsPlayer; + this->actor.speedXZ = 0.0f; + if (fabsf(this->actor.world.rot.y - this->actor.yawTowardsPlayer) < 100.0f) { + func_801477B4(globalCtx); + this->unk_2CE = 5; + this->textIdIndex = 7; + EnBombers2_ChangeAnim(this, 6, 1.0f); + this->unk_2A8 = 0; + this->unk_2C0 = 1; + gSaveContext.save.weekEventReg[73] |= 0x80; + ActorCutscene_Stop(this->cutscene); + this->unk_2AC = 1; + this->actor.textId = sTextIds[this->textIdIndex]; + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + this->actionFunc = func_80C04D8C; + } + } else { + Math_ApproachF(&this->actor.world.pos.x, this->unk_29C.x, 0.3f, 1.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_29C.z, 0.3f, 1.0f); + } + } +} + +void EnBombers2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBombers2* this = (EnBombers2*)thisx; + f32 temp_f4; + Vec3f sp34; + s32 yawDiffAbs; + + SkelAnime_Update(&this->skelAnime); + if (this->unk_2B2 != 0) { + this->unk_2B2--; + } + if ((this->animIndex == 2) && + (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) || + Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 18.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } + this->actor.shape.rot.y = this->actor.world.rot.y; + if (this->unk_2C0 != 2) { + + yawDiffAbs = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.world.rot.y)); + this->unk_290 = 0; + if (yawDiffAbs < 0x3A98) { + this->unk_290 = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + if (this->unk_290 >= 0x2711) { + this->unk_290 = 0x2710; + } else if (this->unk_290 < -0x2710) { + this->unk_290 = -0x2710; + } + } + } + Actor_SetFocus(&this->actor, 20.0f); + Actor_SetScale(&this->actor, 0.008f); + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 0xBB8, 0); + if (this->unk_2BE == 0) { + this->eyeIndex += 1; + if (this->eyeIndex >= 3) { + this->eyeIndex = 0; + this->unk_2BE = (s16)Rand_ZeroFloat(60.0f) + 0x14; + } + } + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + if (this->unk_2AC == 0) { + this->actor.world.pos.x = (Math_SinS((this->actor.world.rot.y + 0x8000)) * 26.0f) + sp34.x; + temp_f4 = Math_CosS(this->actor.world.rot.y + 0x8000) * 26.0f; + this->actor.world.pos.z = temp_f4 + sp34.z; + this->collider.dim.radius = 0x23; + this->collider.dim.height = 0x1E; + } else { + this->collider.dim.radius = 0xA; + this->collider.dim.height = 0x19; + } + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->unk_2AC == 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); + } + Math_Vec3f_Copy(&this->actor.world.pos, &sp34); +} + +s32 func_80C056D4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnBombers2* this = THIS; + + if (limbIndex == OBJECT_CS_LIMB_08) { + rot->x += this->unk_296; + } + if (limbIndex == OBJECT_CS_LIMB_11) { + rot->x += this->unk_28A; + rot->z += this->unk_288; + } + if ((limbIndex == OBJECT_CS_LIMB_0F) || (limbIndex == OBJECT_CS_LIMB_13) || (limbIndex == OBJECT_CS_LIMB_14)) { + *dList = NULL; + } + return false; +} + +void EnBombers2_Draw(Actor* thisx, GlobalContext* globalCtx) { + + EnBombers2* this = THIS; + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C05920)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(sSetPrimColorDlPtr)); + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80C056D4, NULL, &this->actor); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.h b/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.h index 25c5fd773..ed10a84db 100644 --- a/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.h +++ b/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.h @@ -3,15 +3,42 @@ #include "global.h" +#include "objects/object_cs/object_cs.h" + struct EnBombers2; typedef void (*EnBombers2ActionFunc)(struct EnBombers2*, GlobalContext*); typedef struct EnBombers2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x140]; + /* 0x014C */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s morphTable[OBJECT_CS_LIMB_MAX]; + /* 0x0206 */ Vec3s jointTable[OBJECT_CS_LIMB_MAX]; /* 0x0284 */ EnBombers2ActionFunc actionFunc; - /* 0x0288 */ char unk_288[0x94]; + /* 0x0288 */ s16 unk_288; + /* 0x028A */ s16 unk_28A; + /* 0x028C */ UNK_TYPE1 pad_28C[2]; + /* 0x028E */ s16 unk_28E; + /* 0x0290 */ s16 unk_290; + /* 0x0292 */ UNK_TYPE1 pad_292[4]; + /* 0x0296 */ s16 unk_296; + /* 0x0298 */ UNK_TYPE1 pad_298[4]; + /* 0x029C */ Vec3f unk_29C; + /* 0x02A8 */ s32 unk_2A8; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AE */ s16 animIndex; + /* 0x02B0 */ s16 cutscene; + /* 0x02B2 */ s16 unk_2B2; + /* 0x02B4 */ s16 unk_2B4; + /* 0x02B6 */ s16 unk_2B6; + /* 0x02B8 */ f32 lastAnimFrame; + /* 0x02BC */ s16 eyeIndex; + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C2 */ s16 textIdIndex; + /* 0x02C4 */ s16 correctDigitSlots[5]; + /* 0x02CE */ s16 unk_2CE; + /* 0x02D0 */ ColliderCylinder collider; } EnBombers2; // size = 0x31C extern const ActorInit En_Bombers2_InitVars; 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 8456301cd..d4633c02d 100644 --- a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c +++ b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c @@ -1,6 +1,13 @@ -#include "z_en_bombf.h" +/* + * File: z_en_bombf.c + * Overlay: ovl_En_Bombf + * Description: Bomb flower + */ -#define FLAGS 0x00000011 +#include "z_en_bombf.h" +#include "objects/object_bombf/object_bombf.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_10) #define THIS ((EnBombf*)thisx) @@ -9,13 +16,13 @@ void EnBombf_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBombf_Update(Actor* thisx, GlobalContext* globalCtx); void EnBombf_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnBombf_SetupAction(EnBombf* this, EnBombfActionFunc actionFunc); +void func_808AEAB8(EnBombf* this, s16 arg1); +void func_808AEAE0(EnBombf* this, GlobalContext* globalCtx); void func_808AEE3C(EnBombf* this, GlobalContext* globalCtx); void func_808AEF68(EnBombf* this, GlobalContext* globalCtx); void func_808AEFD4(EnBombf* this, GlobalContext* globalCtx); -void EnBombf_SetupAction(EnBombf* this, EnBombfActionFunc actionFunc); - -#if 0 const ActorInit En_Bombf_InitVars = { ACTOR_EN_BOMBF, ACTORCAT_PROP, @@ -28,53 +35,463 @@ const ActorInit En_Bombf_InitVars = { (ActorFunc)EnBombf_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808AFB20 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x00013A28, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0x00013A28, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 9, 18, 10, { 0, 0, 0 } }, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_808AFB4C[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000008, 0x00, 0x08 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000008, 0x00, 0x08 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 0 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808AFB70 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ALL, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 1, D_808AFB4C, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ALL, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -#endif +void EnBombf_SetupAction(EnBombf* this, EnBombfActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern ColliderCylinderInit D_808AFB20; -extern ColliderJntSphElementInit D_808AFB4C[1]; -extern ColliderJntSphInit D_808AFB70; +void EnBombf_Init(Actor* thisx, GlobalContext* globalCtx2) { + f32 yOffset = 0.0f; + GlobalContext* globalCtx = globalCtx2; + EnBombf* this = THIS; -extern UNK_TYPE D_06000340; + Actor_SetScale(thisx, 0.01f); + this->unk_1F8 = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/EnBombf_SetupAction.s") + Collider_InitCylinder(globalCtx, &this->colliderCylinder); + Collider_InitJntSph(globalCtx, &this->colliderJntSph); + Collider_SetCylinder(globalCtx, &this->colliderCylinder, thisx, &sCylinderInit); + Collider_SetJntSph(globalCtx, &this->colliderJntSph, thisx, &sJntSphInit, this->colliderJntSphElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/EnBombf_Init.s") + if (ENBOMBF_GET(thisx) == ENBOMBF_0) { + yOffset = 1000.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/EnBombf_Destroy.s") + ActorShape_Init(&thisx->shape, yOffset, ActorShadow_DrawCircle, 12.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AEAB8.s") + thisx->focus.pos = thisx->world.pos; + thisx->colChkInfo.cylRadius = 10; + thisx->colChkInfo.cylHeight = 10; + thisx->targetMode = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AEAE0.s") + if (ENBOMBF_GET(thisx) == ENBOMBF_0) { + this->timer = 140; + this->unk_1FE = 15; + thisx->gravity = -1.5f; + func_800BC154(globalCtx, &globalCtx->actorCtx, thisx, 3); + thisx->colChkInfo.mass = 200; + thisx->flags &= ~ACTOR_FLAG_1; + EnBombf_SetupAction(this, func_808AEE3C); + } else { + thisx->colChkInfo.mass = MASS_IMMOVABLE; + this->unk_1FC = 1; + this->unk_204 = 1.0f; + func_808AEAB8(this, ENBOMBF_GET(thisx)); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AEE3C.s") + thisx->uncullZoneScale += 31000.0f; + thisx->uncullZoneForward += 31000.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AEF68.s") +void EnBombf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBombf* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AEFD4.s") + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroyJntSph(globalCtx, &this->colliderJntSph); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/EnBombf_Update.s") +void func_808AEAB8(EnBombf* this, s16 arg1) { + EnBombf_SetupAction(this, func_808AEAE0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/func_808AF86C.s") +void func_808AEAE0(EnBombf* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + EnBombf* bombf; + Player* player = GET_PLAYER(globalCtx); + s32 pad3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bombf/EnBombf_Draw.s") + if (this->unk_204 >= 1.0f) { + if (Actor_HasParent(&this->actor, globalCtx)) { + bombf = (EnBombf*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOMBF, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, ENBOMBF_0); + if (bombf != NULL) { + func_800B8C20(&this->actor, &bombf->actor, globalCtx); + this->timer = 180; + this->unk_204 = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_PULL_UP_ROCK); + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + player->actor.child = NULL; + player->heldActor = NULL; + player->interactRangeActor = NULL; + this->actor.parent = NULL; + player->stateFlags1 &= ~0x800; + } + } else if ((this->colliderCylinder.base.acFlags & AC_HIT) && + ((this->colliderCylinder.info.acHitInfo->toucher.dmgFlags & 0x13828) || + ((this->colliderCylinder.info.acHitInfo->toucher.dmgFlags & 0x200) && + (player->transformation == PLAYER_FORM_GORON) && (player->actor.speedXZ > 15.0f)))) { + this->colliderCylinder.base.acFlags &= ~AC_HIT; + if (this->colliderCylinder.base.ac->category != ACTORCAT_BOSS) { + bombf = (EnBombf*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOMBF, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, ENBOMBF_0); + if (bombf != NULL) { + bombf->unk_1F8 = 1; + bombf->timer = 0; + this->timer = 180; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_204 = 0.0f; + } + } + } else { + if (func_80123F48(globalCtx, &this->actor.world.pos, 30.0f, 50.0f)) { + bombf = (EnBombf*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOMBF, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, ENBOMBF_0); + if (bombf != NULL) { + bombf->timer = 100; + this->timer = 180; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_204 = 0.0f; + } + } else { + if (!Actor_HasParent(&this->actor, globalCtx)) { + Actor_LiftActor(&this->actor, globalCtx); + return; + } + player->actor.child = NULL; + player->heldActor = NULL; + player->interactRangeActor = NULL; + this->actor.parent = NULL; + player->stateFlags1 &= ~0x800; + this->actor.world.pos = this->actor.home.pos; + } + } + } else { + if (this->timer == 0) { + this->unk_204 += 0.05f; + if (this->unk_204 >= 1.0f) { + this->actor.flags |= ACTOR_FLAG_1; + } + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + player->actor.child = NULL; + player->heldActor = NULL; + player->interactRangeActor = NULL; + this->actor.parent = NULL; + player->stateFlags1 &= ~0x800; + this->actor.world.pos = this->actor.home.pos; + } + } +} + +void func_808AEE3C(EnBombf* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->unk_204 = 0.0f; + EnBombf_SetupAction(this, func_808AEF68); + this->actor.room = -1; + return; + } + + this->unk_204 = 1.0f; + if (!(this->actor.bgCheckFlags & 1)) { + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.025f, 0.0f); + return; + } + + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 1.5f, 0.0f); + if (this->actor.bgCheckFlags & 2) { + func_800B8EF4(globalCtx, &this->actor); + if (this->actor.velocity.y < -6.0f) { + this->actor.velocity.y *= -0.3f; + this->actor.bgCheckFlags &= ~1; + } + } else if (this->timer >= 4) { + Actor_LiftActor(&this->actor, globalCtx); + } +} + +void func_808AEF68(EnBombf* this, GlobalContext* globalCtx) { + if (Actor_HasNoParent(&this->actor, globalCtx)) { + EnBombf_SetupAction(this, func_808AEE3C); + this->actor.bgCheckFlags &= ~1; + func_808AEE3C(this, globalCtx); + } else { + this->actor.velocity.y = 0.0f; + } +} + +void func_808AEFD4(EnBombf* this, GlobalContext* globalCtx) { + if (this->colliderJntSph.elements->dim.modelSphere.radius == 0) { + this->actor.flags |= ACTOR_FLAG_20; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + } + + this->colliderJntSph.elements->dim.modelSphere.radius = 100; + this->colliderJntSph.elements->dim.worldSphere.radius = 100; + + if (ENBOMBF_GET(&this->actor) == ENBOMBF_1) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[0] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[0] -= 25; + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[1] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[1] -= 25; + } + + if (globalCtx->envCtx.lightSettings.diffuseColor1[2] != 0) { + globalCtx->envCtx.lightSettings.diffuseColor1[2] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[0] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[0] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[1] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[1] -= 25; + } + + if (globalCtx->envCtx.lightSettings.ambientColor[2] != 0) { + globalCtx->envCtx.lightSettings.ambientColor[2] -= 25; + } + + if (this->timer == 0) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->stateFlags1 & 0x800) && (&this->actor == player->heldActor)) { + player->actor.child = NULL; + player->heldActor = NULL; + player->interactRangeActor = NULL; + player->stateFlags1 &= ~0x800; + } + Actor_MarkForDeath(&this->actor); + } +} + +void EnBombf_Update(Actor* thisx, GlobalContext* globalCtx) { + Vec3f sp8C = { 0.0f, 0.0f, 0.0f }; + Vec3f sp80 = { 0.0f, 0.1f, 0.0f }; + Vec3f sp74 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp68; + Vec3f sp5C = { 0.0f, 0.6f, 0.0f }; + Color_RGBA8 sp58 = { 255, 255, 255, 255 }; + EnBombf* this = THIS; + s32 pad; + + if ((this->unk_1F8 != 0) && (this->timer != 0)) { + this->timer--; + } + + if ((this->unk_1FC == 0) && !Actor_HasParent(&this->actor, globalCtx) && + ((this->actor.xzDistToPlayer >= 20.0f) || (fabsf(this->actor.playerHeightRel) >= 80.0f))) { + this->unk_1FC = 1; + } + + this->actionFunc(this, globalCtx); + + if (ENBOMBF_GET(&this->actor) == ENBOMBF_0) { + Actor_MoveWithGravity(&this->actor); + } + + if (this->actor.gravity != 0.0f) { + DREG(6) = 1; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 5.0f, 10.0f, 0.0f, 0x1F); + DREG(6) = 0; + } + + if (ENBOMBF_GET(&this->actor) == ENBOMBF_0) { + if ((this->actor.velocity.y > 0.0f) && (this->actor.bgCheckFlags & 0x10)) { + this->actor.velocity.y = -this->actor.velocity.y; + } + + if ((this->actor.speedXZ != 0.0f) && (this->actor.bgCheckFlags & 8)) { + s16 yDiff = BINANG_SUB(this->actor.wallYaw, this->actor.world.rot.y); + + if (ABS_ALT(yDiff) > 0x4000) { + this->actor.world.rot.y = + BINANG_SUB(this->actor.wallYaw - this->actor.world.rot.y + this->actor.wallYaw, 0x8000); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_BOUND); + Actor_MoveWithGravity(&this->actor); + DREG(6) = 1; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 5.0f, 10.0f, 0.0f, 0x1F); + DREG(6) = 0; + this->actor.speedXZ *= 0.7f; + this->actor.bgCheckFlags &= ~8; + } + + if ((this->colliderCylinder.base.acFlags & AC_HIT) || + ((this->colliderCylinder.base.ocFlags1 & OC1_HIT) && (this->colliderCylinder.base.oc->category == 5))) { + this->unk_1F8 = 1; + this->timer = 0; + } else if ((this->timer > 100) && func_80123F48(globalCtx, &this->actor.world.pos, 30.0f, 50.0f)) { + this->timer = 100; + } + + if (this->unk_1F8 != 0) { + sp5C.y = 0.2f; + sp68 = this->actor.world.pos; + sp68.y += 25.0f; + + if (this->timer < 127) { + if ((globalCtx->gameplayFrames % 2) == 0) { + EffectSsGSpk_SpawnFuse(globalCtx, &this->actor, &sp68, &sp8C, &sp74); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_IGNIT - SFX_FLAG); + sp68.y += 3.0f; + func_800B0DE0(globalCtx, &sp68, &sp8C, &sp5C, &sp58, &sp58, 0x32, 5); + } + + if ((this->timer == 3) || (this->timer == 30) || (this->timer == 50) || (this->timer == 70)) { + this->unk_1FE = this->unk_1FE >> 1; + } + + if ((this->timer < 100) && (this->timer & (this->unk_1FE + 1))) { + Math_SmoothStepToF(&this->unk_200, 150.0f, 1.0f, 150.0f / this->unk_1FE, 0.0f); + } else { + Math_SmoothStepToF(&this->unk_200, 0.0f, 1.0f, 150.0f / this->unk_1FE, 0.0f); + } + + if (this->timer < 3) { + Actor_SetScale(&this->actor, this->actor.scale.x + 0.002f); + } + + if (this->timer == 0) { + sp68 = this->actor.world.pos; + sp68.y += 10.0f; + + if (Actor_HasParent(&this->actor, globalCtx)) { + sp68.y += 30.0f; + } + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, sp68.x, sp68.y, sp68.z, 0, 0, 0, + CLEAR_TAG_SMALL_EXPLOSION); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + + globalCtx->envCtx.lightSettings.diffuseColor1[0] = globalCtx->envCtx.lightSettings.diffuseColor1[1] = + globalCtx->envCtx.lightSettings.diffuseColor1[2] = 250; + globalCtx->envCtx.lightSettings.ambientColor[0] = globalCtx->envCtx.lightSettings.ambientColor[1] = + globalCtx->envCtx.lightSettings.ambientColor[2] = 250; + + func_800DFD04(&globalCtx->mainCamera, 2, 11, 8); + + this->actor.params = ENBOMBF_1; + this->timer = 10; + this->actor.flags |= ACTOR_FLAG_20; + + EnBombf_SetupAction(this, func_808AEFD4); + } + } + } + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 10.0f; + + if (ENBOMBF_GET(&this->actor) <= ENBOMBF_0) { + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + if ((this->unk_204 >= 1.0f) && (this->unk_1FC != 0)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + + if ((this->actor.scale.x >= 0.01f) && (ENBOMBF_GET(&this->actor) != ENBOMBF_1)) { + if (this->actor.depthInWater >= 20.0f) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_IT_BOMB_UNEXPLOSION); + Actor_MarkForDeath(&this->actor); + } else if (this->actor.bgCheckFlags & 0x40) { + this->actor.bgCheckFlags &= ~0x40; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + } + } +} + +Gfx* func_808AF86C(GraphicsContext* gfxCtx, GlobalContext* globalCtx) { + Gfx* head = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 6); + Gfx* gfx = head; + + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + + gSPMatrix(gfx++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPEndDisplayList(gfx++); + + return head; +} + +void EnBombf_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBombf* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (ENBOMBF_GET(&this->actor) <= ENBOMBF_0) { + func_8012C28C(globalCtx->state.gfxCtx); + + if (ENBOMBF_GET(&this->actor) != ENBOMBF_0) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_bombf_DL_000340); + gSPDisplayList(POLY_OPA_DISP++, object_bombf_DL_000530); + + Matrix_Translate(0.0f, 1000.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(this->unk_204, this->unk_204, this->unk_204, MTXMODE_APPLY); + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 200, 255, 200, 255); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, (s8)this->unk_200, 20, 10, 0); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + { + Gfx* gfx = func_808AF86C(globalCtx->state.gfxCtx, globalCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(gfx)); + } + + gSPDisplayList(POLY_OPA_DISP++, object_bombf_DL_000408); + } else { + Collider_UpdateSpheres(0, &this->colliderJntSph); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h index 723d254cb..b72edce8c 100644 --- a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h +++ b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.h @@ -7,13 +7,23 @@ struct EnBombf; typedef void (*EnBombfActionFunc)(struct EnBombf*, GlobalContext*); +#define ENBOMBF_GET(thisx) ((thisx)->params) + +#define ENBOMBF_0 0 +#define ENBOMBF_1 1 + typedef struct EnBombf { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xAC]; + /* 0x0144 */ ColliderCylinder colliderCylinder; + /* 0x0190 */ ColliderJntSph colliderJntSph; + /* 0x01B0 */ ColliderJntSphElement colliderJntSphElements[1]; /* 0x01F0 */ s16 timer; - /* 0x01F2 */ char unk_1F2[0x2]; /* 0x01F4 */ EnBombfActionFunc actionFunc; - /* 0x01F8 */ char unk_1F8[0x10]; + /* 0x01F8 */ s32 unk_1F8; + /* 0x01FC */ u8 unk_1FC; + /* 0x01FE */ s16 unk_1FE; + /* 0x0200 */ f32 unk_200; + /* 0x0204 */ f32 unk_204; } EnBombf; // size = 0x208 extern const ActorInit En_Bombf_InitVars; 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 64336e59d..300679a4e 100644 --- a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c +++ b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c @@ -1,6 +1,14 @@ -#include "z_en_bomjima.h" +/* + * File: z_en_bomjima.c + * Overlay: ovl_En_Bomjima + * Description: Bombers - Jim + */ -#define FLAGS 0x00000019 +#include "overlays/actors/ovl_En_Bombal/z_en_bombal.h" +#include "z_en_bomjima.h" +#include "objects/object_cs/object_cs.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnBomjima*)thisx) @@ -10,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); @@ -20,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, @@ -39,83 +54,1045 @@ 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 } }, }; -#endif +u16 D_80C00A44[] = { 0x719, 0x71A, 0x71B, 0x708 }; -extern ColliderCylinderInit D_80C00A18; +u16 D_80C00A4C[] = { 0x739, 0x73A, 0x73B, 0x000 }; -extern UNK_TYPE D_060064B8; +u16 D_80C00A54[] = { + 0x739, 0x73A, 0x73B, 0x714, 0x709, 0x70A, 0x70B, 0x70C, 0x70D, 0x70E, 0x70F, 0x712, 0x713, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Init.s") +u16 D_80C00A70[] = { + 0x739, 0x73A, 0x73B, 0x759, 0x753, 0x754, 0x755, 0x756, 0x70D, 0x757, 0x758, 0x712, 0x713, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Destroy.s") +u16 D_80C00A8C[] = { 0x736, 0x737, 0x738, 0x74E }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE32C.s") +static AnimationHeader* sAnimations[] = { + &gBomberIdleAnim, &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, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE494.s") +u8 D_80C00AE4[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, + ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE524.s") +s16 D_80C00AF8[] = { + 0x4000, 60, 0x4000, 30, 0xC000, 30, 0xC000, 60, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE65C.s") +void EnBomjima_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBomjima* this = THIS; + s32 cs; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE67C.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + this->actor.gravity = -3.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &gBomberIdleAnim, this->jointTable, + this->morphTable, OBJECT_CS_LIMB_MAX); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + gSaveContext.save.weekEventReg[83] &= (u8)~4; + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEA94.s") + if (this->unk_2E6 == 0) { + cs = this->actor.cutscene; + i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB1C.s") + while (cs != -1) { + // clang-format off + this->unk_2D4[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs); + // clang-format on + i++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB64.s") + this->actionFunc = func_80BFEA94; + } else if (this->unk_2E6 == 2) { + func_80BFFCFC(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEFF0.s") + if ((gSaveContext.save.weekEventReg[75] & 0x40) || (gSaveContext.save.weekEventReg[73] & 0x10) || + (gSaveContext.save.weekEventReg[85] & 2)) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF03C.s") +void EnBomjima_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBomjima* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF120.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF174.s") +void func_80BFE32C(EnBomjima* this, GlobalContext* globalCtx, s32 arg2) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF3F0.s") + this->unk_2CA = arg2; + if (player->transformation == PLAYER_FORM_GORON) { + this->unk_2C8 = 1; + } + if (player->transformation == PLAYER_FORM_ZORA) { + this->unk_2C8 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF430.s") + switch (this->unk_2CA) { + case 0: + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = 0x759; + if (!(gSaveContext.save.weekEventReg[73] & 0x20)) { + this->actor.textId = 0x708; + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + this->actor.textId = 0x75A; + if (!(gSaveContext.save.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF4F4.s") + case 1: + this->actor.textId = D_80C00A4C[this->unk_2C8]; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF52C.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF6CC.s") + case 3: + this->actor.textId = D_80C00A8C[this->unk_2C8]; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF754.s") +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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF9B0.s") +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))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFB40.s") + 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))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFBC4.s") + if ((this->unk_2EC == 15) && Animation_OnFrame(&this->skelAnime, 15.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_LAND); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFCFC.s") + if ((this->unk_2EC == 6) && Animation_OnFrame(&this->skelAnime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMBERS_LAND); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFD48.s") +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; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFE48.s") +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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFF54.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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C0011C.s") + switch (this->unk_2A2) { + case 0: + if (this->unk_2C0 == 0) { + Math_Vec3f_Copy(&sp54, &this->actor.home.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00168.s") + sp54.x += randPlusMinusPoint5Scaled(150.0f); + sp54.z += randPlusMinusPoint5Scaled(150.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00234.s") + 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, true, false, false, true, &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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00284.s") + 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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Update.s") + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C007F4.s") + sp60.x += Math_SinS(this->actor.world.rot.y) * 60.0f; + sp60.z += Math_CosS(this->actor.world.rot.y) * 60.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Draw.s") + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp60, &sp6C, &sp50, true, + false, false, true, &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.actorLists[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.save.weekEventReg[73] & 0x20) { + this->unk_2C8 = 3; + func_80BFE32C(this, globalCtx, 3); + } else if (gSaveContext.save.weekEventReg[77] & 2) { + this->unk_2C8 = 11; + func_80BFE32C(this, globalCtx, 2); + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (gSaveContext.save.weekEventReg[84] & 0x80) { + this->unk_2C8 = 0; + func_80BFE32C(this, globalCtx, 3); + } else if (gSaveContext.save.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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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; + Actor_PlaySfxAtPos(&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; + + SoundSource_PlaySfxAtFixedWorldPos(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.save.weekEventReg[83] &= (u8)~4; + this->actor.world.rot.y = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)); + this->unk_2DC = Camera_GetCamDirYaw(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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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.save.weekEventReg[73] & 0x20) { + this->unk_2C8 = 3; + func_80BFE32C(this, globalCtx, 3); + } else { + if (!(gSaveContext.save.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.save.weekEventReg[84] & 0x80) { + this->unk_2C8 = 0; + func_80BFE32C(this, globalCtx, 3); + } else { + if (!(gSaveContext.save.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; + Actor_ChangeFocus(&this->actor, globalCtx, &bombal->actor); + gSaveContext.save.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 ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80BFE494(this, 1, 1.0f); + this->actionFunc = func_80BFF754; + } + } +} + +void func_80BFF754(EnBomjima* this, GlobalContext* globalCtx) { + 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 index = (i * 2) - 2; + + Math_Vec3f_Copy(&spA0, &this->actor.world.pos); + + spA0.x += Math_SinS(D_80C00AF8[(i * 2) - 2] + this->actor.world.rot.y) * D_80C00AF8[index + 1]; + spA0.z += Math_CosS(D_80C00AF8[index] + this->actor.world.rot.y) * D_80C00AF8[index + 1]; + + Math_Vec3f_Copy(&temp_s3->unk_2A4, &spA0); + } + } + + D_80C009F0 = 0; + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D4[1], &this->actor); + this->actionFunc = func_80BFF9B0; +} + +void func_80BFF9B0(EnBomjima* this, GlobalContext* globalCtx) { + if (D_80C009F0 >= 4) { + Player* player = GET_PLAYER(globalCtx); + + D_80C009F0 = 0; + this->unk_2C8 = 9; + if (player->transformation == PLAYER_FORM_DEKU) { + gSaveContext.save.weekEventReg[73] |= 0x10; + gSaveContext.save.weekEventReg[77] |= 2; + } else { + gSaveContext.save.weekEventReg[85] |= 2; + gSaveContext.save.weekEventReg[85] |= 1; + } + + gSaveContext.save.weekEventReg[11] &= (u8)~1; + gSaveContext.save.weekEventReg[11] &= (u8)~2; + gSaveContext.save.weekEventReg[11] &= (u8)~4; + gSaveContext.save.weekEventReg[11] &= (u8)~8; + gSaveContext.save.weekEventReg[11] &= (u8)~0x10; + + gSaveContext.save.weekEventReg[76] &= (u8)~1; + gSaveContext.save.weekEventReg[76] &= (u8)~2; + gSaveContext.save.weekEventReg[76] &= (u8)~4; + gSaveContext.save.weekEventReg[76] &= (u8)~8; + gSaveContext.save.weekEventReg[76] &= (u8)~0x10; + + gSaveContext.save.bombersCaughtNum = 0; + gSaveContext.save.bombersCaughtOrder[0] = 0; + gSaveContext.save.bombersCaughtOrder[1] = 0; + gSaveContext.save.bombersCaughtOrder[2] = 0; + gSaveContext.save.bombersCaughtOrder[3] = 0; + gSaveContext.save.bombersCaughtOrder[4] = 0; + + func_80BFE494(this, 3, 1.0f); + this->unk_2C8 = 9; + + 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; + } +} + +void func_80BFFB40(EnBomjima* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80BFE494(this, 15, 1.0f); + D_80C009F0 = 100; + this->unk_2DC = 0; + this->actionFunc = func_80BFFBC4; + } +} + +void func_80BFFBC4(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if ((this->unk_2EC != 1) && (this->unk_2CC <= curFrame)) { + func_80BFE494(this, 1, 1.0f); + } + + if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) { + this->unk_2C2 = Rand_S16Offset(5, 5); + } + + if (this->unk_2C2 == 1) { + this->unk_2DC = -10000; + } + + 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]); + } +} + +void func_80BFFCFC(EnBomjima* this) { + func_80BFE65C(this); + func_80BFE494(this, 18, 1.0f); + this->unk_2A0 = 6; + this->actionFunc = func_80BFFD48; +} + +void func_80BFFD48(EnBomjima* this, GlobalContext* globalCtx) { + s32 pad[2]; + + 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; + } +} + +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); + + 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; + } + } + } +} + +void func_80BFFF54(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + Math_SmoothStepToS(&this->unk_290, this->unk_2DC, 1, 5000, 0); + + if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) { + this->unk_2C2 = Rand_S16Offset(5, 5); + } + + if (this->unk_2C2 == 1) { + this->unk_2DC = -10000; + } + + 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; + } + + if (this->unk_2EC == 8) { + if ((D_80C009F4 == 1) && Animation_OnFrame(&this->skelAnime, 7.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HUMAN_BOUND); + D_80C009F4 = 2; + } + + if ((this->unk_2CC <= curFrame) && (this->unk_2C0 == 0)) { + this->unk_2C0 = 10; + } + + if (this->unk_2C0 == 1) { + D_80C009F0++; + } + } +} + +void func_80C0011C(EnBomjima* this) { + func_80BFE65C(this); + func_80BFE494(this, 0, 1.0f); + this->unk_2A0 = 7; + this->actionFunc = func_80C00168; +} + +void func_80C00168(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_2C8 = 4; + } else if (player->transformation == PLAYER_FORM_DEKU) { + this->unk_2C8 = 7; + } + + func_80BFE32C(this, globalCtx, 0); + func_80BFE67C(this, globalCtx); + + if (Text_GetFaceReaction(globalCtx, 0x11) != 0) { + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11); + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_2DC = this->actor.yawTowardsPlayer; + func_80C00234(this); + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +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; +} + +void func_80C00284(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 sp28 = this->skelAnime.curFrame; + + 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; + } + + switch (player->transformation) { + case PLAYER_FORM_HUMAN: + this->unk_28E = -0xFA0; + break; + + case PLAYER_FORM_GORON: + case PLAYER_FORM_ZORA: + this->unk_28E = -0x1770; + break; + } + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(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_SetFocus(&this->actor, 20.0f); + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&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 9833d0d77..1657e031c 100644 --- a/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c +++ b/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c @@ -1,6 +1,14 @@ -#include "z_en_bomjimb.h" +/* + * File: z_en_bomjimb.c + * Overlay: ovl_En_Bomjimb + * Description: Bombers when chasing them + */ -#define FLAGS 0x00000009 +#include "z_en_bomjimb.h" +#include "overlays/actors/ovl_En_Niw/z_en_niw.h" +#include "objects/object_cs/object_cs.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnBomjimb*)thisx) @@ -9,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, @@ -34,79 +52,870 @@ 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, ActorShadow_DrawCircle, 19.0f); + this->actor.gravity = -2.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &gBomberIdleAnim, this->jointTable, + this->morphTable, OBJECT_CS_LIMB_MAX); + 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.save.weekEventReg[73] & 0x10) || (gSaveContext.save.weekEventReg[85] & 2)) { + switch (this->unk_2C8) { + case ENBOMJIMB_F_0: + if (gSaveContext.save.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.save.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.save.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.save.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.save.weekEventReg[11] & 0x10) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01494.s") + if ((!(gSaveContext.save.weekEventReg[73] & 0x10) && !(gSaveContext.save.weekEventReg[85] & 2)) || + (gSaveContext.save.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[] = { + &gBomberIdleAnim, &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))) { + Actor_PlaySfxAtPos(&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))) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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 (!Play_InCsMode(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, true, false, false, true, &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, true, + false, false, true, &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)) { + Actor_PlaySfxAtPos(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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, true, false, false, + true, &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); + + 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); + Message_StartTextbox(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.save.weekEventReg[73] & 0x10)) || + ((player->transformation == PLAYER_FORM_HUMAN) && !(gSaveContext.save.weekEventReg[85] & 2))) { + func_80C0113C(this, 17, 1.0f); + Message_StartTextbox(globalCtx, 0x72E, &this->actor); + player->stateFlags1 |= 0x10000000; + player->actor.freezeTimer = 3; + func_80C012E0(this); + this->unk_2CA = 9; + this->actionFunc = func_80C02BCC; + return; + } + + Message_StartTextbox(globalCtx, D_80C03230[((void)0, gSaveContext.save.bombersCaughtNum)], &this->actor); + gSaveContext.save.bombersCaughtOrder[((void)0, gSaveContext.save.bombersCaughtNum)] = this->unk_2C8 + 1; + gSaveContext.save.bombersCaughtNum++; + + if (gSaveContext.save.bombersCaughtNum > 4) { + func_801A3098(0x922); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_PIECE_OF_HEART); + } + + switch (this->unk_2C8) { + case ENBOMJIMB_F_0: + gSaveContext.save.weekEventReg[76] |= 1; + gSaveContext.save.weekEventReg[11] |= 1; + break; + + case ENBOMJIMB_F_1: + gSaveContext.save.weekEventReg[76] |= 2; + gSaveContext.save.weekEventReg[11] |= 2; + break; + + case ENBOMJIMB_F_2: + gSaveContext.save.weekEventReg[76] |= 4; + gSaveContext.save.weekEventReg[11] |= 4; + break; + + case ENBOMJIMB_F_3: + gSaveContext.save.weekEventReg[76] |= 8; + gSaveContext.save.weekEventReg[11] |= 8; + break; + + case ENBOMJIMB_F_4: + gSaveContext.save.weekEventReg[76] |= 0x10; + gSaveContext.save.weekEventReg[11] |= 0x10; + break; + } + + if (!Play_InCsMode(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)) { + Actor_PlaySfxAtPos(&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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + if ((this->unk_2CA == 8) && (gSaveContext.save.bombersCaughtNum >= 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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(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.save.weekEventReg[75] |= 0x40; + gSaveContext.save.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_SetFocus(&this->actor, 20.0f); + + this->actionFunc(this, globalCtx); + + Actor_MoveWithGravity(&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 ffc840165..4c3f6b241 100644 --- a/src/overlays/actors/ovl_En_Boom/z_en_boom.c +++ b/src/overlays/actors/ovl_En_Boom/z_en_boom.c @@ -1,6 +1,13 @@ -#include "z_en_boom.h" +/* + * File: z_en_boom.c + * Overlay: ovl_En_Boom + * Description: Zora boomerangs + */ -#define FLAGS 0x00000030 +#include "z_en_boom.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnBoom*)thisx) @@ -9,11 +16,9 @@ void EnBoom_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBoom_Update(Actor* thisx, GlobalContext* globalCtx); void EnBoom_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnBoom_SetupAction(EnBoom* this, EnBoomActionFunc actionFunc); void func_808A2918(EnBoom* this, GlobalContext* globalCtx); -void EnBoom_SetupAction(EnBoom* this, EnBoomActionFunc actionFunc); - -#if 0 const ActorInit En_Boom_InitVars = { ACTOR_EN_BOOM, ACTORCAT_ITEMACTION, @@ -26,34 +31,315 @@ const ActorInit En_Boom_InitVars = { (ActorFunc)EnBoom_Draw, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_808A3010 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_TYPE_PLAYER, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK2, { 0x00000010, 0x00, 0x02 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_TYPE_PLAYER, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK2, + { 0x00000010, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_NEAREST | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808A3060[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(targetMode, 5, ICHAIN_CONTINUE), ICHAIN_VEC3S(shape.rot, 0, ICHAIN_STOP), }; -#endif +void EnBoom_SetupAction(EnBoom* this, EnBoomActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern ColliderQuadInit D_808A3010; -extern InitChainEntry D_808A3060[]; +void func_808A24DC(EnBoom* this, GlobalContext* globalCtx) { + WaterBox* sp54; + f32 sp50 = this->actor.world.pos.y; + u16 sp4E = this->actor.bgCheckFlags & 0x20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/EnBoom_SetupAction.s") + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp50, + &sp54) && + (this->actor.world.pos.y < sp50)) { + Vec3f sp40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/func_808A24DC.s") + this->actor.bgCheckFlags |= 0x20; + sp40.x = this->actor.world.pos.x; + sp40.y = this->actor.world.pos.y - 20.0f; + sp40.z = this->actor.world.pos.z; + EffectSsBubble_Spawn(globalCtx, &sp40, 20.0f, 10.0f, 20.0f, 0.13f); + } else { + this->actor.bgCheckFlags &= ~0x20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/EnBoom_Init.s") + if ((this->actor.bgCheckFlags & 0x40) && ((this->actor.bgCheckFlags & 0x20) != sp4E)) { + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/EnBoom_Destroy.s") + Math_Vec3f_Diff(&this->actor.world.pos, &this->actor.prevPos, &sp34); + if (sp34.y != 0.0f) { + f32 temp_fv0 = sqrtf(SQ(sp34.x) + SQ(sp34.z)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/func_808A2918.s") + if (temp_fv0 != 0.0f) { + temp_fv0 = (((sp50 - this->actor.prevPos.y) / sp34.y) * temp_fv0) / temp_fv0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/EnBoom_Update.s") + sp34.x = this->actor.prevPos.x + (sp34.x * temp_fv0); + sp34.y = sp50; + sp34.z = this->actor.prevPos.z + (sp34.z * temp_fv0); + EffectSsGSplash_Spawn(globalCtx, &sp34, NULL, NULL, 0, 300); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Boom/EnBoom_Draw.s") + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_INTO_WATER_L); + + EffectSsGRipple_Spawn(globalCtx, &sp34, 100, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &sp34, 100, 500, 4); + EffectSsGRipple_Spawn(globalCtx, &sp34, 100, 500, 8); + } + + this->actor.bgCheckFlags |= 0x40; +} + +void EnBoom_Init(Actor* thisx, GlobalContext* globalCtx) { + static u8 D_808A3068[4] = { 255, 255, 100, 255 }; + static u8 D_808A306C[4] = { 255, 255, 100, 64 }; + static u8 D_808A3070[4] = { 255, 255, 100, 0 }; + static u8 D_808A3074[4] = { 255, 255, 100, 0 }; + s32 pad; + EnBoom* this = THIS; + EffectBlureInit1 sp30; + s32 i; + + this->actor.room = -1; + Actor_ProcessInitChain(&this->actor, sInitChain); + + for (i = 0; i < 4; i++) { + sp30.p1StartColor[i] = D_808A3068[i]; + sp30.p2StartColor[i] = D_808A306C[i]; + sp30.p1EndColor[i] = D_808A3070[i]; + sp30.p2EndColor[i] = D_808A3074[i]; + } + + sp30.elemDuration = 8; + sp30.unkFlag = 0; + sp30.calcMode = 0; + + Effect_Add(globalCtx, &this->effectIndex, 1, 0, 0, &sp30); + + Collider_InitQuad(globalCtx, &this->collider); + Collider_SetQuad(globalCtx, &this->collider, &this->actor, &sQuadInit); + EnBoom_SetupAction(this, func_808A2918); +} + +void EnBoom_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBoom* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Actor* temp; + + if (player != NULL) { + Effect_Destroy(globalCtx, this->effectIndex); + Collider_DestroyQuad(globalCtx, &this->collider); + + temp = this->actor.child; + if (temp != NULL) { + temp->parent = NULL; + player->boomerangActor = temp; + } else { + temp = this->actor.parent; + if (temp != NULL) { + temp->child = NULL; + } else { + player->boomerangActor = NULL; + player->stateFlags1 &= ~0x2000000; + } + } + player->stateFlags3 |= 0x800000; + } +} + +void func_808A2918(EnBoom* this, GlobalContext* globalCtx) { + Actor* sp7C; + Player* player = GET_PLAYER(globalCtx); + s32 sp74; + s16 sp72; + s16 sp70; + s16 sp6E; + s16 sp6C; + Actor* temp; + f32 sp64; + f32 distXYZ; + + sp7C = this->player; + + if (sp7C != NULL) { + sp72 = Actor_YawToPoint(&this->actor, &sp7C->focus.pos); + sp70 = this->actor.world.rot.y - sp72; + sp6E = Actor_PitchToPoint(&this->actor, &sp7C->focus.pos); + sp6C = this->actor.world.rot.x - sp6E; + + sp64 = (200.0f - Math_Vec3f_DistXYZ(&this->actor.world.pos, &sp7C->focus.pos)) * 0.005f; + if (sp64 < 0.12f) { + sp64 = 0.12f; + } + + if ((&player->actor != sp7C) && ((sp7C->update == NULL) || ((this->unk_1CF < 0) && (ABS_ALT(sp70) > 0x4000)))) { + this->player = NULL; + } else { + if (this->unk_1CE != 0) { + this->unk_1CE--; + this->actor.world.rot.y += (this->actor.params == 0) ? 0x190 : -0x190; + } else { + if (this->unk_1CF > 0) { + this->unk_1CF--; + } else { + this->unk_1CF = -1; + } + + Math_ScaledStepToS(&this->actor.world.rot.y, sp72, + (this->unk_1CF > 0) ? 1000 : (s16)(((sp70 < 0) ? -sp70 : sp70) * sp64)); + } + + Math_ScaledStepToS(&this->actor.world.rot.x, sp6E, ABS_ALT(sp6C) * sp64); + } + } + + Actor_SetSpeeds(&this->actor, 12.0f); + Actor_MoveWithGravity(&this->actor); + func_808A24DC(this, globalCtx); + func_800B9010(&this->actor, NA_SE_IT_BOOMERANG_FLY - SFX_FLAG); + + if ((this->collider.base.atFlags & AT_HIT) && (((this->collider.base.at->id == ACTOR_EN_ITEM00) && + (this->collider.base.at->params != ITEM00_HEART_CONTAINER) && + (this->collider.base.at->params != ITEM00_HEART_PIECE)) || + (this->collider.base.at->id == ACTOR_EN_SI))) { + this->unk_1C8 = this->collider.base.at; + if (this->collider.base.at->id == ACTOR_EN_SI) { + this->collider.base.at->flags |= 0x2000; + } + } + + if (DECR(this->unk_1CC) != 0) { + s32 sp5C; + Vec3f sp50; + s32 pad; + + sp74 = BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.prevPos, &this->actor.world.pos, &sp50, + &this->actor.wallPoly, true, true, true, true, &sp5C); + if (sp74 != 0) { + if (func_800B90AC(globalCtx, &this->actor, this->actor.wallPoly, sp5C, &sp50)) { + sp74 = 0; + } else { + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, &sp50); + } + } + + if (sp74 != 0) { + this->actor.world.rot.x = -this->actor.world.rot.x; + this->actor.world.rot.y += 0x8000; + this->player = &player->actor; + this->unk_1CC = 0; + } + } + + if (this->unk_1CC <= 16) { + distXYZ = Math_Vec3f_DistXYZ(&this->actor.world.pos, &player->actor.focus.pos); + + if (&player->actor != this->player) { + if (this->player == 0) { + this->unk_1CE = 8; + } + this->player = &player->actor; + } + + if (distXYZ < 40.0f) { + sp7C = this->unk_1C8; + if (sp7C != NULL) { + Math_Vec3f_Copy(&sp7C->world.pos, &player->actor.world.pos); + if (sp7C->id == ACTOR_EN_ITEM00) { + sp7C->gravity = -0.9f; + sp7C->bgCheckFlags &= ~3; + } else { + sp7C->flags &= -0x2001; + } + } + Actor_MarkForDeath(&this->actor); + } + } + + sp7C = this->unk_1C8; + if (sp7C != NULL) { + if (sp7C->update == NULL) { + this->unk_1C8 = NULL; + } else { + Math_Vec3f_Copy(&sp7C->world.pos, &this->actor.world.pos); + } + } +} + +void EnBoom_Update(Actor* thisx, GlobalContext* globalCtx) { + EnBoom* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Actor* actor; + + if (!(player->stateFlags1 & 0x20000000)) { + this->actionFunc(this, globalCtx); + + if (((actor = this->actor.child) != NULL) || ((actor = this->actor.parent) != NULL)) { + this->actor.focus.pos.x = (this->actor.world.pos.x + actor->world.pos.x) * 0.5f; + this->actor.focus.pos.y = (this->actor.world.pos.y + actor->world.pos.y) * 0.5f; + this->actor.focus.pos.z = (this->actor.world.pos.z + actor->world.pos.z) * 0.5f; + } else { + Actor_SetFocus(&this->actor, 0.0f); + } + + if (this->actor.params != 0) { + this->unk_1CD--; + } else { + this->unk_1CD++; + } + } +} + +typedef struct { + /* 0x00 */ Gfx* unk_00; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; +} EnBoomStruct; + +EnBoomStruct D_808A3078[] = { + { gameplay_keep_DL_06FE20, { -960.0f, 0.0f, 0.0f }, { 960.0f, 0.0f, 0.0f } }, + { gameplay_keep_DL_06FF68, { -960.0f, 0.0f, 0.0f }, { 960.0f, 0.0f, 0.0f } }, +}; + +void EnBoom_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnBoom* this = THIS; + EnBoomStruct* sp58 = &D_808A3078[this->actor.params]; + Vec3f sp4C; + Vec3f sp40; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_APPLY); + Matrix_RotateZS((this->actor.params != 0) ? 0x1F40 : -0x1F40, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.world.rot.x, MTXMODE_APPLY); + Matrix_MultVec3f(&sp58->unk_04, &sp4C); + Matrix_MultVec3f(&sp58->unk_10, &sp40); + + if (func_80126440(globalCtx, &this->collider, &this->weaponInfo, &sp4C, &sp40)) { + EffectBlure_AddVertex(Effect_GetByIndex(this->effectIndex), &sp4C, &sp40); + } + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_RotateYS(this->unk_1CD * 0x2EE0, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sp58->unk_00); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Boom/z_en_boom.h b/src/overlays/actors/ovl_En_Boom/z_en_boom.h index 906e592a5..0aa09f15b 100644 --- a/src/overlays/actors/ovl_En_Boom/z_en_boom.h +++ b/src/overlays/actors/ovl_En_Boom/z_en_boom.h @@ -9,7 +9,15 @@ typedef void (*EnBoomActionFunc)(struct EnBoom*, GlobalContext*); typedef struct EnBoom { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xAC]; + /* 0x0144 */ ColliderQuad collider; + /* 0x01C4 */ Actor* player; + /* 0x01C8 */ Actor* unk_1C8; + /* 0x01CC */ u8 unk_1CC; + /* 0x01CD */ u8 unk_1CD; + /* 0x01CE */ u8 unk_1CE; + /* 0x01CF */ s8 unk_1CF; + /* 0x01D0 */ s32 effectIndex; + /* 0x01D4 */ WeaponInfo weaponInfo; /* 0x01F0 */ EnBoomActionFunc actionFunc; } EnBoom; // size = 0x1F4 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 46fb32162..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,3 +1,9 @@ +/* + * File: z_en_box.c + * Overlay: ovl_En_Box + * Description: Chest + */ + #include "z_en_box.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_En_Box/z_en_box.h b/src/overlays/actors/ovl_En_Box/z_en_box.h index ad688b9a0..aa7c425d2 100644 --- a/src/overlays/actors/ovl_En_Box/z_en_box.h +++ b/src/overlays/actors/ovl_En_Box/z_en_box.h @@ -9,7 +9,11 @@ typedef void (*EnBoxActionFunc)(struct EnBox*, GlobalContext*); typedef struct EnBox { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xBC]; + /* 0x0144 */ char unk_144[0xAC]; + /* 0x01F0 */ char unk_1F0[0x01]; + /* 0x01F1 */ u8 unk_1F1; + /* 0x01F2 */ char unk_1F2[0x02]; + /* 0x01F4 */ char unk_1F4[0x0C]; /* 0x0200 */ EnBoxActionFunc actionFunc; /* 0x0204 */ char unk_204[0x20]; } EnBox; // size = 0x224 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 bbf95860c..e80004a92 100644 --- a/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c +++ b/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bsb.c + * Overlay: ovl_En_Bsb + * Description: Captain Keeta + */ + #include "z_en_bsb.h" -#define FLAGS 0x02000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((EnBsb*)thisx) 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 8a7d39086..ec0a0a6c2 100644 --- a/src/overlays/actors/ovl_En_Bu/z_en_bu.c +++ b/src/overlays/actors/ovl_En_Bu/z_en_bu.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bu.c + * Overlay: ovl_En_Bu + * Description: Unused dummied-out enemy + */ + #include "z_en_bu.h" -#define FLAGS 0x00000001 +#define FLAGS (ACTOR_FLAG_1) #define THIS ((EnBu*)thisx) @@ -38,7 +44,7 @@ void EnBu_DoNothing(EnBu* this, GlobalContext* globalCtx) { void EnBu_Update(Actor* thisx, GlobalContext* globalCtx) { EnBu* this = THIS; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); this->actionFunc(this, globalCtx); } @@ -47,10 +53,10 @@ 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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(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 4a78ad3dc..0f54995be 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c @@ -1,6 +1,12 @@ +/* + * File: z_en_bubble.c + * Overlay: ovl_En_Bubble + * Description: Shabom (unused) + */ + #include "z_en_bubble.h" -#define FLAGS 0x00000001 +#define FLAGS (ACTOR_FLAG_1) #define THIS ((EnBubble*)thisx) 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 50ecc46fd..0042442ff 100644 --- a/src/overlays/actors/ovl_En_Butte/z_en_butte.c +++ b/src/overlays/actors/ovl_En_Butte/z_en_butte.c @@ -1,4 +1,12 @@ +/* + * File: z_en_butte.c + * Overlay: ovl_En_Butte + * Description: Butterflies + */ + #include "z_en_butte.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -9,24 +17,40 @@ void EnButte_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnButte_Update(Actor* thisx, GlobalContext* globalCtx); void EnButte_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_8091C748(EnButte* this); void func_8091C794(EnButte* this, GlobalContext* globalCtx); +void func_8091CB68(EnButte* this); void func_8091CBB4(EnButte* this, GlobalContext* globalCtx); +void func_8091CF64(EnButte* this); void func_8091CFB4(EnButte* this, GlobalContext* globalCtx); +void func_8091D070(EnButte* this); void func_8091D090(EnButte* this, GlobalContext* globalCtx); -#if 0 -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8091D2D0[1] = { +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_8091D2F4 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_8091D2D0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; const ActorInit En_Butte_InitVars = { @@ -41,54 +65,389 @@ const ActorInit En_Butte_InitVars = { (ActorFunc)EnButte_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8091D3B0[] = { +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ s16 unk_10; +} EnButteStruct; // size = 0x14 + +EnButteStruct D_8091D324[] = { + { 5, 35, 0.0f, 0.1f, 0.5f, 0 }, + { 10, 45, 1.1f, 0.1f, 0.25f, 1000 }, + { 10, 40, 1.5f, 0.1f, 0.3f, 2000 }, +}; + +EnButteStruct D_8091D360[] = { + { 3, 3, 0.8f, 0.1f, 0.2f, 0 }, + { 10, 20, 2.0f, 0.3f, 1.0f, 0 }, + { 10, 20, 2.4f, 0.3f, 1.0f, 0 }, +}; + +f32 D_8091D39C = 0.0f; + +s16 D_8091D3A0 = 0; + +Vec3f D_8091D3A4 = { 0.0f, 0.0f, -3.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 700, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 20, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 60, ICHAIN_STOP), }; -#endif +f32 D_8091D3C0[] = { 50.0f, 80.0f, 100.0f }; -extern ColliderJntSphElementInit D_8091D2D0[1]; -extern ColliderJntSphInit D_8091D2F4; -extern InitChainEntry D_8091D3B0[]; +f32 D_8091D3CC[] = { 30.0f, 40.0f, 50.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C0A0.s") +f32 D_8091D3D8[] = { 15.0f, 20.0f, 25.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C124.s") +f32 D_8091D3E4[] = { 7.5f, 10.0f, 12.5f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C140.s") +s32 D_8091D3F0 = 1500; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C178.s") +void func_8091C0A0(EnButte* this, EnButteStruct* arg1) { + if (this->unk_24E == 0) { + if (Rand_ZeroOne() < 0.6f) { + this->unk_24E = 1; + } else { + this->unk_24E = 2; + } + } else { + this->unk_24E = 0; + } + this->unk_24C = Rand_S16Offset(arg1->unk_00, arg1->unk_02); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/EnButte_Init.s") +void func_8091C124(void) { + D_8091D39C = 0.0f; + D_8091D3A0 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/EnButte_Destroy.s") +void func_8091C140(void) { + D_8091D39C += 0.003f; + D_8091D3A0 += 0xFA0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C524.s") +void func_8091C178(EnButte* this, GlobalContext* globalCtx) { + Vec3f sp4C; + s32 sp48; + Vec3s sp40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C5EC.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C6B4.s") + func_8012C240(globalCtx->state.gfxCtx); + sp48 = Math_SinS(D_8091D3A0) * 250.0f; + sp48 = CLAMP(sp48, 0, 255); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C748.s") + func_800DFC90(&sp40, GET_ACTIVE_CAM(globalCtx)); + Matrix_RotateYS(sp40.y, MTXMODE_NEW); + Matrix_RotateXS(sp40.x, MTXMODE_APPLY); + Matrix_RotateZS(sp40.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_8091D3A4, &sp4C); + Matrix_SetTranslateRotateYXZ(this->actor.focus.pos.x + sp4C.x, this->actor.focus.pos.y + sp4C.y, + this->actor.focus.pos.z + sp4C.z, &sp40); + Matrix_Scale(D_8091D39C, D_8091D39C, D_8091D39C, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091C794.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 200, 200, 180, sp48); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 210, 255); + gSPDisplayList(POLY_XLU_DISP++, gOwlStatueWhiteFlashDL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091CB68.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091CBB4.s") +void EnButte_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnButte* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091CF64.s") + if (ENBUTTE_GET(&this->actor) == ENBUTTE_MINUS1) { + this->actor.params = ENBUTTE_0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091CFB4.s") + this->actor.world.rot.y = Rand_Next(); + this->actor.home.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_ProcessInitChain(&this->actor, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091D070.s") + if ((ENBUTTE_GET_1(&this->actor) & 0xFF) == ENBUTTE_1) { + this->actor.uncullZoneScale = 200.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/func_8091D090.s") + SkelAnime_Init(globalCtx, &this->skelAnime, &gameplay_field_keep_Skel_002FA0, &gameplay_field_keep_Anim_001D20, + this->jointTable, this->morphTable, 8); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colldierElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/EnButte_Update.s") + this->collider.elements[0].dim.worldSphere.radius = + this->collider.elements[0].dim.scale * this->collider.elements[0].dim.modelSphere.radius; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Butte/EnButte_Draw.s") + this->actor.colChkInfo.mass = 0; + this->unk_254 = Rand_ZeroOne() * 0xFFFF; + this->unk_256 = Rand_ZeroOne() * 0xFFFF; + this->unk_258 = Rand_ZeroOne() * 0xFFFF; + + Animation_Change(&this->skelAnime, &gameplay_field_keep_Anim_001D20, 1.0f, 0.0f, 0.0f, 1, 0.0f); + func_8091C748(this); + this->actor.shape.rot.x -= 0x2320; + this->unk_250 = 1; +} + +void EnButte_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyJntSph(globalCtx, &THIS->collider); +} + +void func_8091C524(EnButte* this) { + this->actor.shape.yOffset += + (Math_SinS(this->unk_254) * D_8091D3C0[this->unk_24E]) + (Math_SinS(this->unk_256) * D_8091D3CC[this->unk_24E]); + this->actor.shape.yOffset = CLAMP(this->actor.shape.yOffset, -2000.0f, 2000.0f); +} + +void func_8091C5EC(EnButte* this) { + this->actor.shape.yOffset += + (Math_SinS(this->unk_254) * D_8091D3D8[this->unk_24E]) + (Math_SinS(this->unk_256) * D_8091D3E4[this->unk_24E]); + this->actor.shape.yOffset = CLAMP(this->actor.shape.yOffset, -500.0f, 500.0f); +} + +void func_8091C6B4(EnButte* this) { + s16 temp_a1 = BINANG_ROT180(this->actor.world.rot.y); + s16 temp_v0 = temp_a1 - this->actor.shape.rot.y; + + Math_ScaledStepToS(&this->actor.shape.rot.y, temp_a1, ABS_ALT(temp_v0) >> 3); + this->actor.shape.rot.x = (s16)(Math_SinS(this->unk_258) * 600.0f) - 0x2320; +} + +void func_8091C748(EnButte* this) { + func_8091C0A0(this, &D_8091D324[this->unk_24E]); + this->actionFunc = func_8091C794; +} + +void func_8091C794(EnButte* this, GlobalContext* globalCtx) { + EnButteStruct* sp4C = &D_8091D324[this->unk_24E]; + f32 distSq; + Player* player = GET_PLAYER(globalCtx); + f32 distFromHomeSq = Math3D_XZDistanceSquared(this->actor.world.pos.x, this->actor.world.pos.z, + this->actor.home.pos.x, this->actor.home.pos.z); + f32 playSpeed; + f32 sp38; + s32 pad; + s16 sp32; + s16 yaw; + + func_8091C524(this); + Math_SmoothStepToF(&this->actor.speedXZ, sp4C->unk_04, sp4C->unk_08, sp4C->unk_0C, 0.0f); + + if (this->unk_24F == 1) { + distSq = SQ(100.0f); + sp32 = 0x3E8; + } else { + distSq = SQ(35.0f); + sp32 = 0x258; + } + + sp38 = 0.0f; + this->unk_25C = this->actor.home.pos.y; + + if ((this->unk_24E != 0) && ((distSq < distFromHomeSq) || (this->unk_24C < 4))) { + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + if (!Math_ScaledStepToS(&this->actor.world.rot.y, yaw, sp4C->unk_10)) { + sp38 = 0.5f; + } + } else if ((this->unk_24F == 0) && (this->actor.child != NULL) && (&this->actor != this->actor.child)) { + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.child->world.pos); + if (!Math_ScaledStepToS(&this->actor.world.rot.y, yaw, sp32)) { + sp38 = 0.3f; + } + } else if (this->unk_24F == 1) { + if (!Math_ScaledStepToS(&this->actor.world.rot.y, + (s32)((Rand_ZeroOne() - 0.5f) * 0x6000) + this->actor.yawTowardsPlayer + 0x8000, + sp32)) { + sp38 = 0.4f; + } + } else { + this->actor.world.rot.y += (s16)(Math_SinS(this->unk_254) * 100.0f); + } + + func_8091C6B4(this); + + playSpeed = + (((this->actor.speedXZ * 0.5f) + (Rand_ZeroOne() * 0.2f)) + ((1.0f - Math_SinS(this->unk_258)) * 0.15f)) + + ((1.0f - Math_SinS(this->unk_256)) * 0.3f) + sp38; + this->skelAnime.playSpeed = CLAMP(playSpeed, 0.2f, 1.5f); + + SkelAnime_Update(&this->skelAnime); + + if (this->unk_24C <= 0) { + func_8091C0A0(this, &D_8091D324[this->unk_24E]); + } + + if ((ENBUTTE_GET_1(&this->actor) == ENBUTTE_1) && (player->itemActionParam == 7) && (this->unk_252 <= 0) && + ((Math3D_XZDistanceSquared(player->actor.world.pos.x, player->actor.world.pos.z, this->actor.home.pos.x, + this->actor.home.pos.z) < SQ(120.0f)) || + (this->actor.xzDistToPlayer < 60.0f))) { + func_8091CB68(this); + this->unk_24F = 2; + } else if (this->actor.xzDistToPlayer < 120.0f) { + this->unk_24F = 1; + } else { + this->unk_24F = 0; + } +} + +void func_8091CB68(EnButte* this) { + func_8091C0A0(this, &D_8091D360[this->unk_24E]); + this->actionFunc = func_8091CBB4; +} + +void func_8091CBB4(EnButte* this, GlobalContext* globalCtx) { + EnButteStruct* sp5C = &D_8091D360[this->unk_24E]; + Player* player = GET_PLAYER(globalCtx); + f32 playSpeed; + Vec3f sp48; + f32 distSq; + f32 sp40; + s32 pad; + s16 pad2; + s16 yaw; + + func_8091C5EC(this); + Math_SmoothStepToF(&this->actor.speedXZ, sp5C->unk_04, sp5C->unk_08, sp5C->unk_0C, 0.0f); + sp40 = 0.0f; + + if ((this->unk_24E != 0) && (this->unk_24C < 12)) { + sp48.x = player->swordInfo[0].tip.x + (Math_SinS(player->actor.shape.rot.y) * 10.0f); + sp48.y = player->swordInfo[0].tip.y; + sp48.z = player->swordInfo[0].tip.z + (Math_CosS(player->actor.shape.rot.y) * 10.0f); + + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &sp48); + if (Math_ScaledStepToS(&this->actor.world.rot.y, yaw + (s32)(Rand_ZeroOne() * D_8091D3F0), 0x7D0)) { + if ((globalCtx->gameplayFrames & 0x30) == 0x30) { + this->actor.world.rot.y += (s16)(Math_SinS(this->unk_254) * 60.0f); + } + } else { + sp40 = 0.3f; + } + } + + if (player->swordInfo[0].tip.y < player->actor.world.pos.y + 30.0f) { + this->unk_25C = player->actor.world.pos.y + 30.0f; + } else { + this->unk_25C = player->swordInfo[0].tip.y; + } + + func_8091C6B4(this); + + playSpeed = ((this->actor.speedXZ * 0.5f) + (Rand_ZeroOne() * 0.2f) + ((1.0f - Math_SinS(this->unk_258)) * 0.15f)) + + ((1.0f - Math_SinS(this->unk_256)) * 0.3f) + sp40; + this->skelAnime.playSpeed = CLAMP(playSpeed, 0.2f, 1.5f); + SkelAnime_Update(&this->skelAnime); + + if (this->unk_24C <= 0) { + func_8091C0A0(this, &D_8091D360[this->unk_24E]); + D_8091D3F0 = -D_8091D3F0; + } + + distSq = Math3D_XZDistanceSquared(this->actor.world.pos.x, this->actor.world.pos.z, this->actor.home.pos.x, + this->actor.home.pos.z); + if ((player->itemActionParam != 7) || !(fabsf(player->actor.speedXZ) < 1.8f) || (this->unk_252 > 0) || + !(distSq < SQ(320.0f))) { + func_8091C748(this); + } else if ((distSq > SQ(240.0f)) && + (Math3D_XZDistanceSquared(player->swordInfo[0].tip.x, player->swordInfo[0].tip.z, + this->actor.world.pos.x, this->actor.world.pos.z) < SQ(60.0f))) { + func_8091CF64(this); + } +} + +void func_8091CF64(EnButte* this) { + this->unk_24C = 9; + this->actor.flags |= ACTOR_FLAG_10; + this->skelAnime.playSpeed = 1.0f; + func_8091C124(); + this->actionFunc = func_8091CFB4; +} + +void func_8091CFB4(EnButte* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + func_8091C140(); + + if (this->unk_24C == 5) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 60, NA_SE_EV_BUTTERFRY_TO_FAIRY); + } else if (this->unk_24C == 4) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.focus.pos.x, this->actor.focus.pos.y, + this->actor.focus.pos.z, 0, this->actor.shape.rot.y, 0, 2); + this->unk_250 = 0; + } else if (this->unk_24C <= 0) { + func_8091D070(this); + } +} + +void func_8091D070(EnButte* this) { + this->unk_24C = 64; + this->actionFunc = func_8091D090; + this->actor.draw = NULL; +} + +void func_8091D090(EnButte* this, GlobalContext* globalCtx) { + if (this->unk_24C <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnButte_Update(Actor* thisx, GlobalContext* globalCtx) { + EnButte* this = THIS; + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (&this->actor != this->actor.child)) { + this->actor.child = NULL; + } + + if (this->unk_24C > 0) { + this->unk_24C--; + } + + this->unk_254 += 0x222; + this->unk_256 += 0x1000; + this->unk_258 += 0x600; + + if (ENBUTTE_GET_1(&this->actor) == ENBUTTE_1) { + if (GET_PLAYER(globalCtx)->swordState == 0) { + if (this->unk_252 > 0) { + this->unk_252--; + } + } else { + this->unk_252 = 80; + } + } + + this->actionFunc(this, globalCtx); + + if (this->actor.update != NULL) { + Actor_MoveWithGravity(&this->actor); + Math_StepToF(&this->actor.world.pos.y, this->unk_25C, 0.6f); + if (this->actor.xyzDistToPlayerSq < 5000.0f) { + 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; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + Actor_SetFocus(&this->actor, this->actor.shape.yOffset * this->actor.scale.y); + } +} + +void EnButte_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnButte* this = THIS; + + if (this->unk_250 != 0) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, NULL); + } + + if ((ENBUTTE_GET_1(&this->actor) == ENBUTTE_1) && (this->actionFunc == func_8091CFB4)) { + func_8091C178(this, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Butte/z_en_butte.h b/src/overlays/actors/ovl_En_Butte/z_en_butte.h index 1de720b8d..361096961 100644 --- a/src/overlays/actors/ovl_En_Butte/z_en_butte.h +++ b/src/overlays/actors/ovl_En_Butte/z_en_butte.h @@ -7,11 +7,30 @@ struct EnButte; typedef void (*EnButteActionFunc)(struct EnButte*, GlobalContext*); +#define ENBUTTE_GET(thisx) ((thisx)->params) +#define ENBUTTE_GET_1(thisx) ((thisx)->params & 1) + +#define ENBUTTE_MINUS1 -1 +#define ENBUTTE_0 0 +#define ENBUTTE_1 1 + typedef struct EnButte { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colldierElements[1]; + /* 0x01A4 */ SkelAnime skelAnime; + /* 0x01E8 */ Vec3s jointTable[8]; + /* 0x0218 */ Vec3s morphTable[8]; /* 0x0248 */ EnButteActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x14]; + /* 0x024C */ s16 unk_24C; + /* 0x024E */ u8 unk_24E; + /* 0x024F */ u8 unk_24F; + /* 0x0250 */ u8 unk_250; + /* 0x0252 */ s16 unk_252; + /* 0x0254 */ s16 unk_254; + /* 0x0256 */ s16 unk_256; + /* 0x0258 */ s16 unk_258; + /* 0x025C */ f32 unk_25C; } EnButte; // size = 0x260 extern const ActorInit En_Butte_InitVars; 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..ae704672d 100644 --- a/src/overlays/actors/ovl_En_Cha/z_en_cha.c +++ b/src/overlays/actors/ovl_En_Cha/z_en_cha.c @@ -5,6 +5,7 @@ */ #include "z_en_cha.h" +#include "objects/object_cha/object_cha.h" #define FLAGS 0x00000000 @@ -49,21 +50,18 @@ static ColliderCylinderInit sCylinderInit = { { 10, 40, 0, { 0, 0, 0 } }, }; -extern Gfx D_06000710[]; -extern Gfx D_06000958[]; - void EnCha_Init(Actor* thisx, GlobalContext* globalCtx) { EnCha* this = THIS; s32 pad; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Collider_UpdateCylinder(&this->actor, &this->collider); Actor_SetScale(&this->actor, 0.01f); this->actor.home.rot.z = 0; this->actionFunc = EnCha_Idle; this->actor.home.rot.x = this->actor.home.rot.z; - gSaveContext.weekEventReg[60] &= 0xFB; + gSaveContext.save.weekEventReg[60] &= (u8)~4; } void EnCha_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -85,16 +83,16 @@ void EnCha_Ring(EnCha* this, GlobalContext* globalCtx) { } void EnCha_Idle(EnCha* this, GlobalContext* globalCtx) { - if (gSaveContext.weekEventReg[60] & 4) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_DOOR_BELL); - gSaveContext.weekEventReg[60] &= 0xFB; + if (gSaveContext.save.weekEventReg[60] & 4) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DOOR_BELL); + gSaveContext.save.weekEventReg[60] &= (u8)~4; this->actor.home.rot.z = 0x7D0; } if (this->collider.base.acFlags & AC_HIT) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_DOOR_BELL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DOOR_BELL); this->actor.home.rot.z = 0x7D0; - if (!(gSaveContext.weekEventReg[51] & 4)) { - gSaveContext.weekEventReg[51] |= 4; + if (!(gSaveContext.save.weekEventReg[51] & 4)) { + gSaveContext.save.weekEventReg[51] |= 4; this->actionFunc = EnCha_Ring; } } @@ -103,22 +101,22 @@ void EnCha_Idle(EnCha* this, GlobalContext* globalCtx) { this->actor.home.rot.z *= 0.96f; } -void EnCha_Update(Actor* thisx, GlobalContext* globalCtx) { +void EnCha_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; EnCha* this = THIS; - GlobalContext* globalCtx2 = globalCtx; - CollisionCheck_SetOC(globalCtx, &globalCtx2->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); this->actionFunc(this, globalCtx); - if ((this->actor.shape.rot.z >= -0x1F3F) && (this->actor.shape.rot.z < 0x1F40)) { - CollisionCheck_SetAC(globalCtx, &globalCtx2->colChkCtx, &this->collider.base); + if ((this->actor.shape.rot.z > -0x1F40) && (this->actor.shape.rot.z < 0x1F40)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } void EnCha_Draw(Actor* thisx, GlobalContext* globalCtx) { EnCha* this = THIS; - func_800BDFC0(globalCtx, D_06000710); - Matrix_InsertTranslation(-1094.0f, 4950.0f, 9.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->actor.home.rot.x, 1); - func_800BDFC0(globalCtx, D_06000958); + Gfx_DrawDListOpa(globalCtx, object_cha_DL_000710); + Matrix_Translate(-1094.0f, 4950.0f, 9.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.home.rot.x, MTXMODE_APPLY); + Gfx_DrawDListOpa(globalCtx, object_cha_DL_000958); } 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 b7ad8e6f3..beb2f2d17 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,12 +1,13 @@ /* - * 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 */ #include "z_en_clear_tag.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnClearTag*)thisx) @@ -81,8 +82,18 @@ static f32 sLightRayMaxScale[] = { 25.0f, 100.0f, 48.0f, 20.0f, 32.0f, }; -static Gfx* sSplashTex[] = { - D_040378F0, D_04037DF0, D_040382F0, D_040387F0, D_04038CF0, D_040391F0, D_040396F0, D_04039BF0, NULL, NULL, NULL, +static TexturePtr sSplashTex[] = { + gExplosionSplashTex1, + gExplosionSplashTex2, + gExplosionSplashTex3, + gExplosionSplashTex4, + gExplosionSplashTex5, + gExplosionSplashTex6, + gExplosionSplashTex7, + gExplosionSplashTex8, + NULL, + NULL, + NULL, }; #include "overlays/ovl_En_Clear_Tag/ovl_En_Clear_Tag.c" @@ -399,7 +410,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { Vec3f vel; Vec3f accel; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; if (thisx->params >= 0) { this->activeTimer = 70; Math_Vec3f_Copy(&pos, &this->actor.world.pos); @@ -416,9 +427,9 @@ 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_RotateStateAroundXAxis(Rand_ZeroFloat(M_PI * 2)); - Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); + Matrix_RotateYF(Rand_ZeroFloat(M_PI * 2), MTXMODE_NEW); + Matrix_RotateXFApply(Rand_ZeroFloat(M_PI * 2)); + Matrix_MultVecZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; accel.y = vel.y * -0.03f; accel.z = vel.z * -0.03f; @@ -467,8 +478,8 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { if (thisx->params != CLEAR_TAG_POP) { pos.y = this->actor.world.pos.y; for (i = 0; i < 18; i++) { - vel.x = __sinf(i * (33.0f / 40.0f)) * i * .5f; - vel.z = __cosf(i * (33.0f / 40.0f)) * i * .5f; + vel.x = sinf(i * (33.0f / 40.0f)) * i * .5f; + vel.z = cosf(i * (33.0f / 40.0f)) * i * .5f; vel.y = Rand_ZeroFloat(8.0f) + 7.0f; vel.x += randPlusMinusPoint5Scaled(0.5f); @@ -489,9 +500,9 @@ 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_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); - Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); + Matrix_RotateYF(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); + Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI)); + Matrix_MultVecZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; accel.y = vel.y * -0.03f; accel.z = vel.z * -0.03f; @@ -510,7 +521,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Camera* camera; + Camera* mainCam; s32 pad; switch (this->cameraState) { @@ -533,19 +544,19 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { } break; case 1: - func_800EA0D4(globalCtx, &globalCtx->csCtx); - this->camId = func_801694DC(globalCtx); - func_80169590(globalCtx, 0, 1); - func_80169590(globalCtx, this->camId, 7); + Cutscene_Start(globalCtx, &globalCtx->csCtx); + this->subCamId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, this->subCamId, 7); func_800B7298(globalCtx, &this->actor, 4); - camera = Play_GetCamera(globalCtx, 0); - this->eye.x = camera->eye.x; - this->eye.y = camera->eye.y; - this->eye.z = camera->eye.z; - this->at.x = camera->at.x; - this->at.y = camera->at.y; - this->at.z = camera->at.z; - func_801518B0(globalCtx, 0xF, NULL); + mainCam = Play_GetCamera(globalCtx, CAM_ID_MAIN); + this->subCamEye.x = mainCam->eye.x; + this->subCamEye.y = mainCam->eye.y; + this->subCamEye.z = mainCam->eye.z; + this->subCamAt.x = mainCam->at.x; + this->subCamAt.y = mainCam->at.y; + this->subCamAt.z = mainCam->at.z; + Message_StartTextbox(globalCtx, 0xF, NULL); this->cameraState = 2; func_8019FDC8(&D_801DB4A4, NA_SE_VO_NA_LISTEN, 0x20); case 2: @@ -556,23 +567,23 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { } player->actor.speedXZ = 0.0f; - if (func_80152498(&globalCtx->msgCtx) == 0) { - camera = Play_GetCamera(globalCtx, 0); - camera->eye = this->eye; - camera->eyeNext = this->eye; - camera->at = this->at; - func_80169AFC(globalCtx, this->camId, 0); - func_800EA0EC(globalCtx, &globalCtx->csCtx); + if (Message_GetState(&globalCtx->msgCtx) == 0) { + mainCam = Play_GetCamera(globalCtx, CAM_ID_MAIN); + mainCam->eye = this->subCamEye; + mainCam->eyeNext = this->subCamEye; + mainCam->at = this->subCamAt; + func_80169AFC(globalCtx, this->subCamId, 0); + Cutscene_End(globalCtx, &globalCtx->csCtx); func_800B7298(globalCtx, &this->actor, 6); this->cameraState = 0; - this->camId = 0; + this->subCamId = CAM_ID_MAIN; this->activeTimer = 20; } break; } - if (this->camId != 0) { - Play_CameraSetAtEye(globalCtx, this->camId, &this->at, &this->eye); + if (this->subCamId != CAM_ID_MAIN) { + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->subCamAt, &this->subCamEye); } } @@ -642,7 +653,7 @@ void EnClearTag_UpdateEffects(EnClearTag* this, GlobalContext* globalCtx) { sphereCenter.y += 5.0f; // Check if the debris has hit the ground. - if (func_800C5A20(&globalCtx->colCtx, &sphereCenter, 11.0f)) { + if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sphereCenter, 11.0f)) { effect->position.y = originalYPosition; // Bounce the debris effect. @@ -798,10 +809,10 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { } // Draw the debris effect. - Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); Matrix_Scale(effect->scale, effect->scale, effect->scale, MTXMODE_APPLY); - Matrix_InsertYRotation_f(effect->rotationY, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(effect->rotationX); + Matrix_RotateYF(effect->rotationY, MTXMODE_APPLY); + Matrix_RotateXFApply(effect->rotationX); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, gClearTagDebrisEffectDL); } @@ -817,10 +828,10 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, (s8)effect->primColor.a); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)effect->primColor.a); func_800C0094(this->actor.floorPoly, effect->position.x, effect->position.y, effect->position.z, &mtxF); - Matrix_SetCurrentState(&mtxF); + Matrix_Put(&mtxF); Matrix_Scale(effect->scale, 1.0f, effect->scale, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_04030100); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_030100); } } } @@ -842,7 +853,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (s8)(effect->primColor.a * 0.7f)); func_800C0094(this->actor.floorPoly, effect->position.x, this->actor.floorHeight, effect->position.z, &mtxF); - Matrix_SetCurrentState(&mtxF); + Matrix_Put(&mtxF); Matrix_Scale(effect->scale * 3.0f, 1.0f, effect->scale * 3.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFlashEffectGroundDL); @@ -870,10 +881,10 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { gSPSegment( 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_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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); + Matrix_Translate(0.0f, 20.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectDL); } @@ -896,8 +907,8 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { gSPSegment( 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_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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); @@ -918,8 +929,8 @@ 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_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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); @@ -943,12 +954,12 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { // Draw the light ray effect. gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)effect->primColor.r, (u8)effect->primColor.g, (u8)effect->primColor.b, (u8)effect->primColor.a); - Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_InsertYRotation_f(effect->rotationY, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(effect->rotationX); - Matrix_InsertZRotation_f(effect->rotationZ, MTXMODE_APPLY); + Matrix_Translate(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); + Matrix_RotateYF(effect->rotationY, MTXMODE_APPLY); + Matrix_RotateXFApply(effect->rotationX); + Matrix_RotateZF(effect->rotationZ, MTXMODE_APPLY); Matrix_Scale(effect->scale * 0.5f, effect->scale * 0.5f, effect->maxScale * effect->scale, MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(M_PI / 2); + Matrix_RotateXFApply(M_PI / 2); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagLightRayEffectDL); } @@ -968,25 +979,24 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { // Apply material 16 times along a circle to give the appearance of a splash for (j = 0; j < 16; j++) { - Matrix_InsertYRotation_f(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledZ(effect->maxScale, &vec); + Matrix_RotateYF(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_NEW); + Matrix_MultVecZ(effect->maxScale, &vec); /** * Get the water surface at point (`x`, `ySurface`, `z`). `ySurface` doubles as position y input * returns true if point is within the xz boundaries of an active water box, else false * `ySurface` returns the water box's surface, while `outWaterBox` returns a pointer to the WaterBox */ ySurface = effect->position.y; - if (func_800CA1AC(globalCtx, &globalCtx->colCtx, effect->position.x + vec.x, effect->position.z + vec.z, - &ySurface, &waterBox)) { + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, effect->position.x + vec.x, + effect->position.z + vec.z, &ySurface, &waterBox)) { if ((effect->position.y - ySurface) < 200.0f) { // Draw the splash effect. - Matrix_InsertTranslation(effect->position.x + vec.x, ySurface, effect->position.z + vec.z, - MTXMODE_NEW); - Matrix_InsertYRotation_f(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_APPLY); - Matrix_RotateStateAroundXAxis(effect->rotationX); + Matrix_Translate(effect->position.x + vec.x, ySurface, effect->position.z + vec.z, MTXMODE_NEW); + Matrix_RotateYF(2.0f * (j * M_PI) * (1.0f / 16.0f), MTXMODE_APPLY); + Matrix_RotateXFApply(effect->rotationX); Matrix_Scale(effect->scale, effect->scale, effect->scale, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0403A0F0); + gSPDisplayList(POLY_XLU_DISP++, gExplosionSplashDL); } } } diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h index 453e6c0ac..61c4a638b 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.h @@ -45,10 +45,10 @@ typedef struct EnClearTag { /* 0x2E54 */ u8 cameraState; /* 0x2E56 */ s16 activeTimer; // Actor Marked for Death when timer runs out /* 0x2E58 */ UNK_TYPE1 unk2E58[0xC]; - /* 0x2E64 */ s16 camId; + /* 0x2E64 */ s16 subCamId; /* 0x2E66 */ Color_RGBA8 flashEnvColor; - /* 0x2E6C */ Vec3f eye; // Camera eye - /* 0x2E78 */ Vec3f at; // Camera lookAt + /* 0x2E6C */ Vec3f subCamEye; + /* 0x2E78 */ Vec3f subCamAt; } EnClearTag; // size = 0x2E84 extern const ActorInit En_Clear_Tag_InitVars; 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 fa6a977f9..1a35e8e50 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,6 +1,13 @@ -#include "z_en_cne_01.h" +/* + * File: z_en_cne_01.c + * Overlay: ovl_En_Cne_01 + * Description: Unused Market NPC + */ -#define FLAGS 0x00000019 +#include "z_en_cne_01.h" +#include "objects/object_cne/object_cne.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnCne01*)thisx) @@ -9,12 +16,10 @@ void EnCne01_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnCne01_Update(Actor* thisx, GlobalContext* globalCtx); void EnCne01_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809CB520(EnCne01* this, GlobalContext* globalCtx); -void func_809CB5A0(EnCne01* this, GlobalContext* globalCtx); -void func_809CB5D8(EnCne01* this, GlobalContext* globalCtx); -void func_809CB5FC(EnCne01* this, GlobalContext* globalCtx); +void EnCne01_Walk(EnHy* this, GlobalContext* globalCtx); +void EnCne01_FaceForward(EnHy* this, GlobalContext* globalCtx); +void EnCne01_Talk(EnHy* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Cne_01_InitVars = { ACTOR_EN_CNE_01, ACTORCAT_NPC, @@ -27,85 +32,301 @@ const ActorInit En_Cne_01_InitVars = { (ActorFunc)EnCne01_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809CBF00 = { - { COLTYPE_HIT0, 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 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 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 64, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_809CBF2C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_809CBF38 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(0, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(0, 0x0), - /* Zora boomerang */ DMG_ENTRY(0, 0x0), - /* Normal arrow */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0x0), - /* Goron punch */ DMG_ENTRY(0, 0x0), - /* Sword */ DMG_ENTRY(0, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(0, 0x0), - /* Ice arrow */ DMG_ENTRY(0, 0x0), - /* Light arrow */ DMG_ENTRY(0, 0x0), - /* Goron spikes */ DMG_ENTRY(0, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x0), - /* Deku bubble */ DMG_ENTRY(0, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(0, 0x0), - /* Zora punch */ DMG_ENTRY(0, 0x0), - /* Spin attack */ DMG_ENTRY(0, 0x0), - /* 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(0, 0x0), +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, 0), + /* Deku Stick */ DMG_ENTRY(0, 0), + /* Horse trample */ DMG_ENTRY(0, 0), + /* Explosives */ DMG_ENTRY(0, 0), + /* Zora boomerang */ DMG_ENTRY(0, 0), + /* Normal arrow */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0), + /* Hookshot */ DMG_ENTRY(0, 0), + /* Goron punch */ DMG_ENTRY(0, 0), + /* Sword */ DMG_ENTRY(0, 0), + /* Goron pound */ DMG_ENTRY(0, 0), + /* Fire arrow */ DMG_ENTRY(0, 0), + /* Ice arrow */ DMG_ENTRY(0, 0), + /* Light arrow */ DMG_ENTRY(0, 0), + /* Goron spikes */ DMG_ENTRY(0, 0), + /* Deku spin */ DMG_ENTRY(0, 0), + /* Deku bubble */ DMG_ENTRY(0, 0), + /* Deku launch */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0), + /* Zora barrier */ DMG_ENTRY(0, 0), + /* Normal shield */ DMG_ENTRY(0, 0), + /* Light ray */ DMG_ENTRY(0, 0), + /* Thrown object */ DMG_ENTRY(0, 0), + /* Zora punch */ DMG_ENTRY(0, 0), + /* Spin attack */ DMG_ENTRY(0, 0), + /* Sword beam */ DMG_ENTRY(0, 0), + /* Normal Roll */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0), + /* Unblockable */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0), + /* Powder Keg */ DMG_ENTRY(0, 0), }; -#endif +static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, +}; -extern ColliderCylinderInit D_809CBF00; -extern CollisionCheckInfoInit2 D_809CBF2C; -extern DamageTable D_809CBF38; +void EnCne01_UpdateModel(EnCne01* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f point; -extern UNK_TYPE D_060000F0; -extern UNK_TYPE D_06001300; + EnHy_UpdateSkelAnime(&this->enHy, globalCtx); + if (SubS_AngleDiffLessEqual(this->enHy.actor.shape.rot.y, 0x36B0, this->enHy.actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->enHy.actor.focus.pos, &this->enHy.actor.shape.rot, &this->enHy.turnTarget, + &this->enHy.headRot, &this->enHy.torsoRot, &sTurnOptions); + } else { + Math_SmoothStepToS(&this->enHy.turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->enHy.torsoRot.y, 0, 4, 0x3E8, 1); + } + SubS_FillLimbRotTables(globalCtx, this->enHy.limbRotTableY, this->enHy.limbRotTableZ, + ARRAY_COUNT(this->enHy.limbRotTableY)); + EnHy_UpdateCollider(&this->enHy, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB290.s") +s32 EnCne01_TestIsTalking(EnCne01* this, GlobalContext* globalCtx) { + s32 isTalking = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB404.s") + if (Actor_ProcessTalkRequest(&this->enHy.actor, &globalCtx->state)) { + isTalking = true; + this->enHy.textId = 0x10B9; // Invalid textId, produces empty textbox + this->enHy.tmpTurnTarget = this->enHy.turnTarget; + this->enHy.tmpHeadRot = this->enHy.headRot; + this->enHy.tmpTorsoRot = this->enHy.torsoRot; + this->enHy.tmpActionFunc = this->enHy.actionFunc; + this->enHy.actionFunc = EnCne01_Talk; + } + return isTalking; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB4A0.s") +s32 func_809CB4A0(EnCne01* this, GlobalContext* globalCtx) { + s16 x; + s16 y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB520.s") + Actor_GetScreenPos(globalCtx, &this->enHy.actor, &x, &y); + //! @bug: Both x and y conditionals are always true, || should be an && + if (!this->enHy.waitingOnInit && ((x >= 0) || (x < SCREEN_WIDTH)) && ((y >= 0) || (y < SCREEN_HEIGHT))) { + func_800B85E0(&this->enHy.actor, globalCtx, 30.0f, EXCH_ITEM_2E); + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB5A0.s") +void EnCne01_FinishInit(EnHy* this, GlobalContext* globalCtx) { + if (EnHy_Init(this, globalCtx, &gCneSkel, ENHY_ANIMATION_OS_ANIME_11)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.draw = EnCne01_Draw; + this->waitingOnInit = false; + if (ENCNE01_GET_PATH(&this->actor) == ENCNE01_NO_PATH) { + this->actionFunc = EnCne01_FaceForward; + } else { + this->actionFunc = EnCne01_Walk; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB5D8.s") +void EnCne01_Walk(EnHy* this, GlobalContext* globalCtx) { + if (EnHy_MoveForwards(this, 1.0f)) { + this->curPoint = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB5FC.s") +void EnCne01_FaceForward(EnHy* this, GlobalContext* globalCtx) { + this->actor.shape.rot = this->actor.world.rot; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/EnCne01_Init.s") +void EnCne01_Talk(EnHy* this, GlobalContext* globalCtx) { + s16 yaw; + u8 talkState; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/EnCne01_Destroy.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xFA0, 1); + talkState = Message_GetState(&globalCtx->msgCtx); + this->inMsgState3 = (talkState == 3) ? true : false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/EnCne01_Update.s") + switch (talkState) { + case 0: + yaw = ABS_ALT(this->actor.shape.rot.y - this->actor.yawTowardsPlayer); + if (yaw < 0x64) { + Message_StartTextbox(globalCtx, this->textId, NULL); + } + break; + case 2: + this->actor.textId = 0; + this->turnTarget = this->tmpTurnTarget; + this->headRot = this->tmpHeadRot; + this->torsoRot = this->tmpTorsoRot; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = this->tmpActionFunc; + this->tmpActionFunc = NULL; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CB920.s") +void EnCne01_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnCne01* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CBBC8.s") + this->enHy.animObjIndex = SubS_GetObjectIndex(OBJECT_OS_ANIME, globalCtx); + this->enHy.headObjIndex = SubS_GetObjectIndex(OBJECT_CNE, globalCtx); + this->enHy.skelUpperObjIndex = SubS_GetObjectIndex(OBJECT_CNE, globalCtx); + this->enHy.skelLowerObjIndex = SubS_GetObjectIndex(OBJECT_CNE, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/func_809CBCA0.s") + if ((this->enHy.animObjIndex < 0) || (this->enHy.headObjIndex < 0) || (this->enHy.skelUpperObjIndex < 0) || + (this->enHy.skelLowerObjIndex < 0)) { + Actor_MarkForDeath(&this->enHy.actor); + } + this->enHy.actor.draw = NULL; + Collider_InitCylinder(globalCtx, &this->enHy.collider); + Collider_SetCylinder(globalCtx, &this->enHy.collider, &this->enHy.actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->enHy.actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->enHy.actor.flags &= ~ACTOR_FLAG_1; + this->enHy.path = SubS_GetPathByIndex(globalCtx, ENCNE01_GET_PATH(&this->enHy.actor), ENCNE01_NO_PATH); + this->enHy.waitingOnInit = true; + Actor_SetScale(&this->enHy.actor, 0.01f); + this->enHy.actionFunc = EnCne01_FinishInit; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cne_01/EnCne01_Draw.s") +void EnCne01_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnCne01* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->enHy.collider); +} + +void EnCne01_Update(Actor* thisx, GlobalContext* globalCtx) { + EnCne01* this = THIS; + + EnCne01_TestIsTalking(this, globalCtx); + this->enHy.actionFunc(&this->enHy, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->enHy.actor, 0.0f, 0.0f, 0.0f, 4); + EnCne01_UpdateModel(this, globalCtx); + func_809CB4A0(this, globalCtx); +} + +s32 EnCne01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnCne01* this = THIS; + s8 bodyPart; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + + bodyPart = gEnHyBodyParts[limbIndex]; + if (bodyPart >= 0) { + Matrix_MultVec3f(&zeroVec, &this->enHy.bodyPartsPos[bodyPart]); + } + + if (limbIndex == CNE_LIMB_HEAD) { + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->enHy.headObjIndex].segment); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.headObjIndex].segment); + *dList = gCneHeadBrownHairDL; + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.skelLowerObjIndex].segment); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + if (limbIndex == CNE_LIMB_HEAD) { + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->enHy.headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->enHy.headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == CNE_LIMB_TORSO) { + Matrix_RotateXS(-this->enHy.torsoRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->enHy.torsoRot.x, MTXMODE_APPLY); + } + + if ((limbIndex == CNE_LIMB_HEAD) && this->enHy.inMsgState3 && ((globalCtx->state.frames % 2) == 0)) { + Matrix_Translate(40.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if ((limbIndex == CNE_LIMB_TORSO) || (limbIndex == CNE_LIMB_LEFT_UPPER_ARM) || + (limbIndex == CNE_LIMB_RIGHT_UPPER_ARM)) { + rot->y += (s16)(Math_SinS(this->enHy.limbRotTableY[limbIndex]) * 200.0f); + rot->z += (s16)(Math_CosS(this->enHy.limbRotTableZ[limbIndex]) * 200.0f); + } + + return false; +} + +void EnCne01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnCne01* this = THIS; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + + if (limbIndex == CNE_LIMB_RIGHT_FOOT) { + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->enHy.skelUpperObjIndex].segment); + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->enHy.skelUpperObjIndex].segment); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == CNE_LIMB_HEAD) { + Matrix_MultVec3f(&zeroVec, &this->enHy.actor.focus.pos); + } +} + +void EnCne01_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +} + +void EnCne01_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnCne01* this = THIS; + s32 i; + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, SUBS_SHADOW_TEX_SIZE); + u8* shadowTexIter; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 180, 255, 0)); + gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 180, 255, 0)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Gfx_EnvColor(globalCtx->state.gfxCtx, 160, 180, 255, 0)); + gDPPipeSync(POLY_OPA_DISP++); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->enHy.skelAnime.skeleton, this->enHy.skelAnime.jointTable, + this->enHy.skelAnime.dListCount, EnCne01_OverrideLimbDraw, EnCne01_PostLimbDraw, + EnCne01_TransformLimbDraw, &this->enHy.actor); + Matrix_RotateXS(0, MTXMODE_NEW); + + for (i = 0, shadowTexIter = shadowTex; i < SUBS_SHADOW_TEX_SIZE; i++) { + *shadowTexIter++ = 0; + } + for (i = 0; i < 5; i++) { + SubS_GenShadowTex(this->enHy.bodyPartsPos, &this->enHy.actor.world.pos, shadowTex, i / 5.0f, + ARRAY_COUNT(this->enHy.bodyPartsPos), gEnHyShadowSizes, gEnHyParentBodyParts); + } + SubS_DrawShadowTex(&this->enHy.actor, &globalCtx->state, shadowTex); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..840d1cf60 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 @@ -1,16 +1,18 @@ #ifndef Z_EN_CNE_01_H #define Z_EN_CNE_01_H -#include "global.h" +#include "z_en_hy_code.h" struct EnCne01; typedef void (*EnCne01ActionFunc)(struct EnCne01*, GlobalContext*); +#define ENCNE01_GET_PATH(thisx) (((thisx)->params & 0x7E00) >> 9) +#define ENCNE01_NO_PATH 0x3F + typedef struct EnCne01 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnCne01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x000 */ EnHy enHy; + /* 0x3EC */ UNK_TYPE1 unk_3EC[0x230]; } 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 a81f6a24a..6817c1830 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,23 +1,49 @@ -#include "z_en_col_man.h" +/* + * File: z_en_col_man.c + * Overlay: ovl_En_Col_Man + * Description: Lab HP, Garo Master falling rocks, Garo Master bomb + */ -#define FLAGS 0x00100000 +#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 (ACTOR_FLAG_100000) #define THIS ((EnColMan*)thisx) 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 } }, }; @@ -33,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, ActorShadow_DrawCircle, 10.0f); + func_80AFDD60(this); + break; + case EN_COL_MAN_FALLING_ROCK: + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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.save.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.save.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.save.weekEventReg[56] & 2)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 40.0f, 40.0f); + } else { + Actor_PickUp(&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 (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { + gSaveContext.save.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 |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_20; + 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; + Actor_PlaySfxAtPos(&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; + } + } + + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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 6a76160bb..c3396fe29 100644 --- a/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -1,6 +1,12 @@ +/* + * File: z_en_cow.c + * Overlay: ovl_En_Cow + * Description: Cow + */ + #include "z_en_cow.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnCow*)thisx) @@ -9,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, @@ -31,57 +39,397 @@ 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; +void EnCow_RotatePoint(Vec3f* vec, s16 angle) { + f32 x = (Math_CosS(angle) * vec->x) + (Math_SinS(angle) * vec->z); -extern UNK_TYPE D_060001CC; -extern UNK_TYPE D_06004010; -extern UNK_TYPE D_06004348; + 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_8099C290.s") +void EnCow_SetColliderPos(EnCow* this) { + Vec3f vec; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C328.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/func_8099C41C.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_Init.s") +void EnCow_SetTailPos(EnCow* this) { + Vec3f vec; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Destroy.s") + VEC_SET(vec, 0.0f, 57.0f, -36.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C880.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_8099CAA8.s") +void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnCow* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CB20.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 72.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CB68.s") + switch (EN_COW_TYPE(thisx)) { + case EN_COW_TYPE_DEFAULT: + case EN_COW_TYPE_ABDUCTED: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gCowSkel, NULL, this->jointTable, this->morphTable, + COW_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowChewAnim); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CBCC.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_8099CC68.s") + this->actionFunc = EnCow_Idle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CCF8.s") + if (!(gSaveContext.save.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_8099CDA0.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/func_8099CFAC.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/EnCow_Update.s") + D_801BDAA4 = 0; + func_801A5080(4); + break; + case EN_COW_TYPE_TAIL: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gCowTailSkel, NULL, this->jointTable, this->morphTable, + COW_TAIL_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowTailIdleAnim); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D3C0.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_8099D4AC.s") + EnCow_SetTailPos(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D4FC.s") + this->actor.flags &= ~ACTOR_FLAG_1; + this->animationTimer = Rand_ZeroFloat(1000.0f) + 40.0f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Draw.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D59C.s") + gSaveContext.save.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, &gCowChewAnim, 1.0f, this->skelAnime.curFrame, + Animation_GetLastFrame(&gCowChewAnim), 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 == &gCowChewAnim) { + 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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + func_801477B4(globalCtx); + this->actionFunc = EnCow_Idle; + } +} + +void EnCow_GiveMilkEnd(EnCow* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + 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 { + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } +} + +void EnCow_GiveMilk(EnCow* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + func_801477B4(globalCtx); + this->actionFunc = EnCow_GiveMilkWait; + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } +} + +void EnCow_CheckForEmptyBottle(EnCow* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (Interface_HasEmptyBottle()) { + 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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 |= ACTOR_FLAG_10000; + 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.ocarinaMode == 0) || (globalCtx->msgCtx.ocarinaMode == 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(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)) < 25000) { + D_801BDAA4 = 0; + this->actionFunc = EnCow_Talk; + this->actor.flags |= ACTOR_FLAG_10000; + 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.save.weekEventReg[87] & 1)) { + gSaveContext.save.weekEventReg[87] |= 1; + if (Interface_HasEmptyBottle()) { + 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 |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 170.0f); + this->actionFunc = EnCow_Talk; + } + } else { + gSaveContext.save.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, &gCowTailIdleAnim, 1.0f, this->skelAnime.curFrame, + Animation_GetLastFrame(&gCowTailIdleAnim), 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 == &gCowTailIdleAnim) { + 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_MoveWithGravity(&this->actor); + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &gCowChewAnim) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_COW_CRY); + Animation_Change(&this->skelAnime, &gCowMooAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gCowMooAnim), + ANIMMODE_ONCE, 1.0f); + } else { + Animation_Change(&this->skelAnime, &gCowChewAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gCowChewAnim), + 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 == &gCowTailIdleAnim) { + Animation_Change(&this->skelAnime, &gCowTailSwishAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gCowTailSwishAnim), ANIMMODE_ONCE, 1.0f); + } else { + Animation_Change(&this->skelAnime, &gCowTailIdleAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gCowTailIdleAnim), + 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_MultVec3f(&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..bb9319ad9 100644 --- a/src/overlays/actors/ovl_En_Cow/z_en_cow.h +++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.h @@ -2,6 +2,18 @@ #define Z_EN_COW_H #include "global.h" +#include "objects/object_cow/object_cow.h" + +#define EN_COW_TYPE(thisx) ((thisx)->params & 0xF) + +#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; @@ -9,7 +21,14 @@ typedef void (*EnCowActionFunc)(struct EnCow*, GlobalContext*); 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 dc32a698e..3ab93e1be 100644 --- a/src/overlays/actors/ovl_En_Crow/z_en_crow.c +++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.c @@ -1,6 +1,12 @@ +/* + * File: z_en_crow.c + * Overlay: ovl_En_Crow + * Description: Guay + */ + #include "z_en_crow.h" -#define FLAGS 0x00005005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000) #define THIS ((EnCrow*)thisx) @@ -9,14 +15,18 @@ void EnCrow_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnCrow_Update(Actor* thisx, GlobalContext* globalCtx); void EnCrow_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8099AC8C(EnCrow* this, GlobalContext* globalCtx); -void func_8099B0CC(EnCrow* this, GlobalContext* globalCtx); -void func_8099B584(EnCrow* this, GlobalContext* globalCtx); -void func_8099B6C4(EnCrow* this, GlobalContext* globalCtx); -void func_8099B838(EnCrow* this, GlobalContext* globalCtx); -void func_8099B9E8(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupFlyIdle(EnCrow* this); +void EnCrow_FlyIdle(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupDiveAttack(EnCrow* this); +void EnCrow_DiveAttack(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_CheckIfFrozen(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_Damaged(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupDie(EnCrow* this); +void EnCrow_Die(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_SetupRespawn(EnCrow* this); +void EnCrow_TurnAway(EnCrow* this, GlobalContext* globalCtx); +void EnCrow_Respawn(EnCrow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Crow_InitVars = { ACTOR_EN_CROW, ACTORCAT_ENEMY, @@ -29,25 +39,36 @@ const ActorInit En_Crow_InitVars = { (ActorFunc)EnCrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8099C070[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8099C094 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_8099C070, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_8099C0A4 = { 1, 15, 30, 30 }; +static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 30 }; -// static DamageTable sDamageTable = { -static DamageTable D_8099C0AC = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -82,60 +103,470 @@ static DamageTable D_8099C0AC = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8099C0D0[] = { +static s32 D_8099C0CC = 0; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 3000, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 88, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP), }; -#endif +void EnCrow_Init(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = THIS; -extern ColliderJntSphElementInit D_8099C070[1]; -extern ColliderJntSphInit D_8099C094; -extern CollisionCheckInfoInit D_8099C0A4; -extern DamageTable D_8099C0AC; -extern InitChainEntry D_8099C0D0[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderItems); + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); + D_8099C0CC = 0; + if (this->actor.parent != NULL) { + this->actor.flags &= ~ACTOR_FLAG_1; + } + EnCrow_SetupFlyIdle(this); +} -extern UNK_TYPE D_060000F0; +void EnCrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Init.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Destroy.s") +void EnCrow_SetupFlyIdle(EnCrow* this) { + this->timer = 100; + this->collider.base.acFlags |= AC_ON; + this->actionFunc = EnCrow_FlyIdle; + this->skelAnime.playSpeed = 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099AC58.s") +void EnCrow_FlyIdle(EnCrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 dist; + s32 onInitialAnimFrame; + s16 yaw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099AC8C.s") + SkelAnime_Update(&this->skelAnime); + onInitialAnimFrame = Animation_OnFrame(&this->skelAnime, 0.0f); + this->actor.speedXZ = (Rand_ZeroOne() * 1.5f) + 3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B098.s") + if ((this->actor.parent != NULL) && (this->actor.parent->home.rot.z == 0)) { + this->actor.home.pos.x = this->actor.parent->world.pos.x; + this->actor.home.pos.z = this->actor.parent->world.pos.z; + dist = Actor_XZDistanceToPoint(&this->actor, &this->actor.parent->world.pos); + } else { + dist = 450.0f; + this->actor.flags |= ACTOR_FLAG_1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B0CC.s") + if (this->actor.bgCheckFlags & 8) { + this->aimRotY = this->actor.wallYaw; + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 300.0f) { + this->aimRotY = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B318.s") + if ((Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 5, 0x300, 0x10) == 0) && onInitialAnimFrame && + (Rand_ZeroOne() < 0.1f)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B384.s") + yaw = (Actor_YawToPoint(&this->actor, &this->actor.home.pos) - this->actor.shape.rot.y); + if (yaw > 0) { + this->aimRotY += Rand_S16Offset(0x1000, 0x1000); + } else { + this->aimRotY -= Rand_S16Offset(0x1000, 0x1000); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B584.s") + if ((this->actor.depthInWater > -40.0f) || (this->actor.bgCheckFlags & 1)) { + this->aimRotX = -0x1000; + } else if (this->actor.world.pos.y < (this->actor.home.pos.y - 50.0f)) { + this->aimRotX = -Rand_S16Offset(0x800, 0x800); + } else if (this->actor.world.pos.y > (this->actor.home.pos.y + 50.0f)) { + this->aimRotX = Rand_S16Offset(0x800, 0x800); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B6AC.s") + if ((Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 0xA, 0x100, 8) == 0) && onInitialAnimFrame && + (Rand_ZeroOne() < 0.1f)) { + if (this->actor.home.pos.y < this->actor.world.pos.y) { + this->aimRotX -= Rand_S16Offset(0x400, 0x400); + } else { + this->aimRotX += Rand_S16Offset(0x400, 0x400); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B6C4.s") + this->aimRotX = CLAMP(this->aimRotX, -0x1000, 0x1000); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B778.s") + if (this->actor.bgCheckFlags & 1) { + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x100, 0x400); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B838.s") + if (this->timer != 0) { + this->timer--; + } + if ((this->timer == 0) && + (((this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & 0x800000)) || (dist < 300.0f)) && + (this->actor.depthInWater < -40.0f) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + if (dist < this->actor.xzDistToPlayer) { + this->actor.child = this->actor.parent; + } else { + this->actor.child = &player->actor; + } + EnCrow_SetupDiveAttack(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B8EC.s") +void EnCrow_SetupDiveAttack(EnCrow* this) { + this->timer = 300; + this->actionFunc = EnCrow_DiveAttack; + this->actor.speedXZ = 4.0f; + this->skelAnime.playSpeed = 2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099B9E8.s") +void EnCrow_DiveAttack(EnCrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 isFacingActor; + Vec3f pos; + s16 pitch; + s16 pitchTarget; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BAB4.s") + SkelAnime_Update(&this->skelAnime); + if (this->timer != 0) { + this->timer--; + } + isFacingActor = Actor_ActorAIsFacingActorB(&this->actor, this->actor.child, 0x2800); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Update.s") + if (isFacingActor) { + if (&player->actor == this->actor.child) { + pos.y = this->actor.child->world.pos.y + 20.0f; + } else { + pos.y = this->actor.child->world.pos.y + 40.0f; + } + pos.x = this->actor.child->world.pos.x; + pos.z = this->actor.child->world.pos.z; + pitch = Actor_PitchToPoint(&this->actor, &pos); + pitchTarget = CLAMP(pitch, -0x3000, 0x3000); + Math_SmoothStepToS(&this->actor.shape.rot.x, pitchTarget, 2, 0x400, 64); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 2, 0x100, 16); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BE48.s") + if (isFacingActor || (Actor_XZDistanceBetweenActors(&this->actor, this->actor.child) > 80.0f)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, this->actor.child), 4, 0xC00, + 0xC0); + } + if (((this->timer == 0) || ((&player->actor != this->actor.child) && (this->actor.child->home.rot.z != 0)) || + ((&player->actor == this->actor.child) && + ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (player->stateFlags1 & 0x800000))) || + ((this->collider.base.atFlags & AT_HIT) || (this->actor.bgCheckFlags & 9))) || + (this->actor.depthInWater > -40.0f)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/func_8099BF20.s") + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_ATTACK); + } + EnCrow_SetupFlyIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Crow/EnCrow_Draw.s") +void EnCrow_CheckIfFrozen(EnCrow* this, GlobalContext* globalCtx) { + if (this->deathMode == 10) { + this->deathMode = 0; + this->effectAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->bodyPartsPos, 4, 2, 0.2f, 0.2f); + } +} + +void EnCrow_SetupDamaged(EnCrow* this, GlobalContext* globalCtx) { + f32 scale; + + this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); + this->actor.velocity.y = 0.0f; + Animation_Change(&this->skelAnime, &gGuayFlyAnim, 0.4f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -3.0f); + this->actor.shape.yOffset = 0.0f; + this->actor.targetArrowOffset = 0.0f; + this->actor.bgCheckFlags &= ~1; + scale = (this->actor.scale.x * 100.0f); + this->actor.world.pos.y += 20.0f * scale; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_DEAD); + + if (this->actor.colChkInfo.damageEffect == 3) { + this->deathMode = 10; // Ice arrows + this->effectAlpha = 1.0f; + this->effectScale = 0.75f; + this->steamScale = 0.5f; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->deathMode = 20; // Light Arrows + this->effectAlpha = 4.0f; + this->steamScale = 0.5f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.elements->info.bumper.hitPos.x, + this->collider.elements->info.bumper.hitPos.y, this->collider.elements->info.bumper.hitPos.z, 0, 0, + 0, CLEAR_TAG_SMALL_LIGHT_RAYS); + } else if (this->actor.colChkInfo.damageEffect == 2) { + this->deathMode = 0; // Fire arrows + this->effectAlpha = 4.0f; + this->steamScale = 0.5f; + } + + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + if (this->actor.flags & ACTOR_FLAG_8000) { + this->actor.speedXZ = 0.0f; + } + + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= ACTOR_FLAG_10; + + this->actionFunc = EnCrow_Damaged; +} + +void EnCrow_Damaged(EnCrow* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + this->actor.colorFilterTimer = 40; + + if (!(this->actor.flags & ACTOR_FLAG_8000)) { + if (this->deathMode != 10) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200); + this->actor.shape.rot.z += 0x1780; + } + if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) { + EnCrow_CheckIfFrozen(this, globalCtx); + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, this->actor.scale.x * 10000.0f, + 0, 0); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + + if (this->actor.parent != NULL) { + Actor_MarkForDeath(&this->actor); + return; + } + EnCrow_SetupDie(this); + } + } +} + +void EnCrow_SetupDie(EnCrow* this) { + this->actor.colorFilterTimer = 0; + this->actionFunc = EnCrow_Die; +} + +void EnCrow_Die(EnCrow* this, GlobalContext* globalCtx) { + f32 stepScale; + + if (this->actor.params != 0) { + stepScale = 0.006f; + } else { + stepScale = 0.002f; + } + if (Math_StepToF(&this->actor.scale.x, 0.0f, stepScale) != 0) { + if (this->actor.params == 0) { + D_8099C0CC++; + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x80); + } else { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + } + EnCrow_SetupRespawn(this); + } + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; +} + +void EnCrow_SetupTurnAway(EnCrow* this) { + this->timer = 100; + this->aimRotX = -0x1000; + this->actor.speedXZ = 3.5f; + this->aimRotY = this->actor.yawTowardsPlayer + 0x8000; + this->skelAnime.playSpeed = 2.0f; + if (this->actor.colChkInfo.damageEffect == 1) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + } else { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = EnCrow_TurnAway; +} + +void EnCrow_TurnAway(EnCrow* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (this->actor.bgCheckFlags & 8) { + this->aimRotY = this->actor.wallYaw; + } else { + this->aimRotY = this->actor.yawTowardsPlayer + 0x8000; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->aimRotY, 3, 0xC00, 0xC0); + Math_SmoothStepToS(&this->actor.shape.rot.x, this->aimRotX, 5, 0x100, 0x10); + + if (this->timer != 0) { + this->timer--; + } + + if (this->timer == 0) { + EnCrow_SetupFlyIdle(this); + } +} + +void EnCrow_SetupRespawn(EnCrow* this) { + if (D_8099C0CC == 10) { + this->actor.params = 1; + D_8099C0CC = 0; + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius * 0.03f * 100.0f; + } else { + this->actor.params = 0; + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius; + } + Animation_PlayLoop(&this->skelAnime, &gGuayFlyAnim); + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->timer = 300; + this->actor.draw = NULL; + this->actor.shape.yOffset = 2000.0f; + this->actor.targetArrowOffset = 2000.0; + this->effectAlpha = 0.0f; + this->actionFunc = EnCrow_Respawn; +} + +void EnCrow_Respawn(EnCrow* this, GlobalContext* globalCtx) { + f32 target; + + if (this->timer != 0) { + this->timer--; + } + if (this->timer == 0) { + SkelAnime_Update(&this->skelAnime); + this->actor.draw = EnCrow_Draw; + if (this->actor.params != 0) { + target = 0.03f; + } else { + target = 0.01f; + } + if (Math_StepToF(&this->actor.scale.x, target, target * 0.1f)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.flags &= ~ACTOR_FLAG_10; + this->actor.colChkInfo.health = 1; + EnCrow_SetupFlyIdle(this); + } + this->actor.scale.z = this->actor.scale.y = this->actor.scale.x; + } +} + +void EnCrow_UpdateDamage(EnCrow* this, GlobalContext* globalCtx) { + + if (this->collider.base.acFlags & AT_HIT) { + this->collider.base.acFlags &= ~AT_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.elements->info); + + if (this->actor.colChkInfo.damageEffect == 1) { + EnCrow_SetupTurnAway(this); + + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->deathMode = 31; // Stunned via deku nuts or zora barrier + this->effectAlpha = 2.0f; + this->steamScale = 0.5f; + EnCrow_SetupTurnAway(this); + + } else { + this->actor.colChkInfo.health = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + EnCrow_SetupDamaged(this, globalCtx); + } + } +} + +void EnCrow_Update(Actor* thisx, GlobalContext* globalCtx) { + f32 pad; + EnCrow* this = (EnCrow*)thisx; + f32 height; + f32 scale; + + EnCrow_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + scale = this->actor.scale.x * 100.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -this->actor.shape.rot.x; + + if (this->actionFunc != EnCrow_Respawn) { + if (this->actor.colChkInfo.health != 0) { + height = 20.0f * scale; + Actor_MoveWithoutGravity(&this->actor); + } else { + height = 0.0f; + Actor_MoveWithGravity(&this->actor); + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f * scale, 25.0f * scale, 50.0f * scale, 7); + } else { + height = 0.0f; + } + + this->collider.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.elements[0].dim.worldSphere.center.y = this->actor.world.pos.y + height; + this->collider.elements[0].dim.worldSphere.center.z = this->actor.world.pos.z; + + if (this->actionFunc == EnCrow_DiveAttack) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (this->actionFunc != EnCrow_Respawn) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + Actor_SetFocus(&this->actor, height); + + if ((this->actor.colChkInfo.health != 0) && (Animation_OnFrame(&this->skelAnime, 3.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + } + if (this->effectAlpha > 0.0f) { + if (this->deathMode != 10) { + Math_StepToF(&this->effectAlpha, 0.0f, 0.05f); + this->steamScale = (this->effectAlpha + 1.0f) * 0.25f; + if (this->steamScale > 0.5f) { + this->steamScale = 0.5f; + } else { + this->steamScale = this->steamScale; + } + } else if (Math_StepToF(&this->effectScale, 0.5f, 0.0125f) == 0) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 EnCrow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnCrow* this = (EnCrow*)thisx; + + if (this->actor.colChkInfo.health != 0) { + if (limbIndex == OBJECT_CROW_LIMB_UPPER_TAIL) { + rot->y += (s16)(0xC00 * sin_rad(this->skelAnime.curFrame * (M_PI / 4))); + } else if (limbIndex == OBJECT_CROW_LIMB_TAIL) { + rot->y += (s16)(0x1400 * sin_rad((this->skelAnime.curFrame + 2.5f) * (M_PI / 4))); + } + } + return false; +} + +void EnCrow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnCrow* this = (EnCrow*)thisx; + + if (limbIndex == OBJECT_CROW_LIMB_BODY) { + Matrix_MultVecX(2500.0f, this->bodyPartsPos); + return; + } + if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) || + (limbIndex == OBJECT_CROW_LIMB_TAIL)) { + Matrix_MultZero(&this->bodyPartsPos[(limbIndex >> 1) - 1]); + } +} + +void EnCrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnCrow* this = (EnCrow*)thisx; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnCrow_OverrideLimbDraw, EnCrow_PostLimbDraw, &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->actor.scale.x * 100.0f * this->steamScale, this->effectScale, this->effectAlpha, + this->deathMode); +} diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.h b/src/overlays/actors/ovl_En_Crow/z_en_crow.h index e1d763142..9076a198c 100644 --- a/src/overlays/actors/ovl_En_Crow/z_en_crow.h +++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.h @@ -2,6 +2,7 @@ #define Z_EN_CROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" struct EnCrow; @@ -9,9 +10,20 @@ typedef void (*EnCrowActionFunc)(struct EnCrow*, GlobalContext*); typedef struct EnCrow { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnCrowActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x110]; + /* 0x18C */ u8 deathMode; + /* 0x18E */ s16 timer; + /* 0x190 */ s16 aimRotX; + /* 0x192 */ s16 aimRotY; + /* 0x194 */ Vec3s jointTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1CA */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; + /* 0x200 */ ColliderJntSph collider; + /* 0x220 */ ColliderJntSphElement colliderItems[1]; + /* 0x260 */ Vec3f bodyPartsPos[4]; + /* 0x290 */ f32 effectAlpha; + /* 0x294 */ f32 steamScale; + /* 0x298 */ f32 effectScale; } EnCrow; // size = 0x29C extern const ActorInit En_Crow_InitVars; 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..184a8b81b 100644 --- a/src/overlays/actors/ovl_En_Dai/z_en_dai.c +++ b/src/overlays/actors/ovl_En_Dai/z_en_dai.c @@ -5,8 +5,9 @@ */ #include "z_en_dai.h" +#include "objects/object_dai/object_dai.h" -#define FLAGS 0x02000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((EnDai*)thisx) @@ -18,24 +19,6 @@ void EnDai_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80B3F00C(EnDai* this, GlobalContext* globalCtx); void func_80B3EF90(EnDai* this, GlobalContext* globalCtx); -extern AnimationHeader D_060107B0; -extern AnimationHeader D_06010FB0; -extern AnimationHeader D_060117B0; -extern AnimationHeader D_06010FB0; -extern AnimationHeader D_06011FB0; -extern AnimationHeader D_060127B0; -extern AnimationHeader D_060079E4; -extern AnimationHeader D_06007354; -extern AnimationHeader D_06000CEC; -extern AnimationHeader D_060069DC; -extern AnimationHeader D_0600563C; -extern AnimationHeader D_06002E58; -extern AnimationHeader D_06006590; -extern FlexSkeletonHeader D_060130D0; -extern Gfx D_06000230[]; -extern Gfx D_060002E8[]; -extern Gfx D_0600C538[]; - const ActorInit En_Dai_InitVars = { ACTOR_EN_DAI, ACTORCAT_NPC, @@ -87,11 +70,11 @@ void func_80B3E168(EnDaiParticle* particle, GlobalContext* globalCtx2) { gDPPipeSync(POLY_XLU_DISP++); if (!isDisplayListSet) { - gSPDisplayList(POLY_XLU_DISP++, D_06000230); + gSPDisplayList(POLY_XLU_DISP++, object_dai_DL_000230); isDisplayListSet = true; } - Matrix_StatePush(); + Matrix_Push(); alpha = (particle->unk_02 / (f32)particle->unk_01); alpha *= 255.0f; @@ -102,15 +85,15 @@ void func_80B3E168(EnDaiParticle* particle, GlobalContext* globalCtx2) { Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (particle->unk_02 + (i * 3)) * 3, (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_Translate(particle->unk_10.x, particle->unk_10.y, particle->unk_10.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(particle->unk_34, particle->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++, D_060002E8); + gSPDisplayList(POLY_XLU_DISP++, object_dai_DL_0002E8); - Matrix_StatePop(); + Matrix_Pop(); } } @@ -147,14 +130,20 @@ s32 func_80B3E5B4(EnDai* this, GlobalContext* globalCtx) { } s32 func_80B3E5DC(EnDai* this, s32 arg1) { - static ActorAnimationEntryS D_80B3FBFC[] = { - { &D_060079E4, 1.0f, 0, -1, 0, 0 }, { &D_060079E4, 1.0f, 0, -1, 0, -4 }, { &D_06007354, 1.0f, 0, -1, 2, -4 }, - { &D_06000CEC, 1.0f, 0, -1, 2, -4 }, { &D_060069DC, 1.0f, 0, -1, 2, -4 }, { &D_0600563C, 1.0f, 0, -1, 2, 0 }, - { &D_0600563C, 1.0f, 0, -1, 2, -4 }, { &D_06002E58, 1.0f, 0, -1, 0, -4 }, { &D_06006590, 1.0f, 0, -1, 2, -4 }, + static AnimationInfoS D_80B3FBFC[] = { + { &object_dai_Anim_0079E4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dai_Anim_0079E4, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dai_Anim_007354, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dai_Anim_000CEC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dai_Anim_0069DC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dai_Anim_00563C, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dai_Anim_00563C, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dai_Anim_002E58, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dai_Anim_006590, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, }; s32 phi_v1 = false; - s32 ret = 0; + s32 ret = false; switch (arg1) { case 0: @@ -180,7 +169,7 @@ s32 func_80B3E5DC(EnDai* this, s32 arg1) { if (phi_v1) { this->unk_A70 = arg1; - ret = func_8013BC6C(&this->skelAnime, D_80B3FBFC, arg1); + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80B3FBFC, arg1); } return ret; @@ -190,9 +179,9 @@ s32 func_80B3E69C(EnDai* this, GlobalContext* globalCtx) { s32 ret = false; if ((globalCtx->csCtx.state != 0) && (globalCtx->sceneNum == SCENE_12HAKUGINMAE) && - (globalCtx->csCtx.unk_12 == 0) && !(gSaveContext.weekEventReg[30] & 1)) { + (globalCtx->csCtx.currentCsIndex == 0) && !(gSaveContext.save.weekEventReg[30] & 1)) { if (!(this->unk_1CE & 0x10)) { - Actor_SetSwitchFlag(globalCtx, 20); + Flags_SetSwitch(globalCtx, 20); this->unk_1CE |= (0x80 | 0x10); this->unk_1CE &= ~(0x100 | 0x20); this->unk_1CC = 0xFF; @@ -205,7 +194,7 @@ s32 func_80B3E69C(EnDai* this, GlobalContext* globalCtx) { } else if (this->unk_1CE & 0x10) { this->unk_1CE &= ~0x10; this->unk_1CE |= 0x200; - gSaveContext.weekEventReg[30] |= 1; + gSaveContext.save.weekEventReg[30] |= 1; this->actionFunc = func_80B3F00C; } @@ -216,8 +205,8 @@ s32 func_80B3E7C8(EnDai* this, GlobalContext* globalCtx) { s32 ret = false; if (this->unk_1CE & 7) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_8013AED4(&this->unk_1CE, 0, 7); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_1CE, 0, 7); this->actionFunc = func_80B3EF90; ret = true; } @@ -304,7 +293,7 @@ s32 func_80B3E96C(EnDai* this, GlobalContext* globalCtx) { break; case 1: - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SNOWSTORM_HARD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SNOWSTORM_HARD); Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WEATHER_TAG, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0x1388, 0x708, 0x3E8, 0); func_80B3E5DC(this, 3); @@ -424,7 +413,7 @@ void func_80B3EE8C(EnDai* this, GlobalContext* globalCtx) { void func_80B3EEDC(EnDai* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.unk1202A == 3) && + if ((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.ocarinaMode == 3) && (globalCtx->msgCtx.unk1202E == 1)) { func_80B3E5DC(this, 1); this->actionFunc = func_80B3EE8C; @@ -439,7 +428,7 @@ void func_80B3EEDC(EnDai* this, GlobalContext* globalCtx) { void func_80B3EF90(EnDai* this, GlobalContext* globalCtx) { if (func_8010BF58(&this->actor, globalCtx, D_80B3FC8C, NULL, &this->unk_1D0)) { - func_8013AED4(&this->unk_1CE, 3, 7); + SubS_UpdateFlags(&this->unk_1CE, 3, 7); this->unk_1D0 = 0; this->actionFunc = func_80B3F00C; } else { @@ -455,13 +444,12 @@ void func_80B3F044(EnDai* this, GlobalContext* globalCtx) { static s32 D_80B3FE38[] = { 0, 0, 6, 7, 8, }; - s32 sp2C = 0; s32 sp28; - if (func_800EE29C(globalCtx, 0x1D8)) { - sp2C = func_800EE200(globalCtx, 0x1D8); - sp28 = globalCtx->csCtx.npcActions[sp2C]->unk0; + if (Cutscene_CheckActorAction(globalCtx, 472)) { + sp2C = Cutscene_GetActorActionIndex(globalCtx, 472); + sp28 = globalCtx->csCtx.actorActions[sp2C]->action; if (this->unk_1CC != (u8)sp28) { func_80B3E5DC(this, D_80B3FE38[sp28]); switch (sp28) { @@ -470,7 +458,7 @@ void func_80B3F044(EnDai* this, GlobalContext* globalCtx) { break; case 2: - Audio_PlayActorSound2(&this->actor, NA_SE_EV_ROLL_AND_FALL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROLL_AND_FALL); break; case 3: @@ -493,40 +481,41 @@ void func_80B3F044(EnDai* this, GlobalContext* globalCtx) { case 2: if (globalCtx->csCtx.frames == 360) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DAIGOLON_SLEEP3 - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIGOLON_SLEEP3 - SFX_FLAG); } if (Animation_OnFrame(&this->skelAnime, 43.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_BOUND_1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_GORON_BOUND_1); } this->unk_1D6 = func_80B3E8BC(this, this->unk_1CC); break; case 3: if (Animation_OnFrame(&this->skelAnime, 6.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DAIGOLON_SLEEP1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIGOLON_SLEEP1); } this->unk_1D6 = func_80B3E8BC(this, this->unk_1CC); break; case 4: if (Animation_OnFrame(&this->skelAnime, 30.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DAIGOLON_SLEEP2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIGOLON_SLEEP2); } if (Animation_OnFrame(&this->skelAnime, 35.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_BOUND_0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_GORON_BOUND_0); } this->unk_1D6 = func_80B3E8BC(this, this->unk_1CC); break; } - func_800EDF24(&this->actor, globalCtx, sp2C); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, sp2C); } void EnDai_Init(Actor* thisx, GlobalContext* globalCtx) { EnDai* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 0.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060130D0, NULL, this->jointTable, this->morphTable, 19); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dai_Skel_0130D0, NULL, this->jointTable, this->morphTable, + 19); this->unk_A70 = -1; func_80B3E5DC(this, 0); Actor_SetScale(&this->actor, 0.2f); @@ -536,21 +525,21 @@ void EnDai_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_1CE = 0; this->unk_1D6 = 0; - if (gSaveContext.weekEventReg[33] & 0x80) { - func_8013AED4(&this->unk_1CE, 3, 7); + if (gSaveContext.save.weekEventReg[33] & 0x80) { + SubS_UpdateFlags(&this->unk_1CE, 3, 7); this->unk_1CE |= 0x80; this->unk_1CD = 0xFF; this->actionFunc = func_80B3F00C; return; } - if (gSaveContext.weekEventReg[30] & 1) { + if (gSaveContext.save.weekEventReg[30] & 1) { Actor_MarkForDeath(&this->actor); return; } this->unk_1CD = 0; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_1CE |= (0x100 | 0x20); this->unk_1CE |= 0x80; this->actionFunc = func_80B3EEDC; @@ -575,15 +564,15 @@ void EnDai_Update(Actor* thisx, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); func_80B3E834(this); if (!(this->unk_1CE & 0x200)) { - func_8013C964(&this->actor, globalCtx, 0.0f, 0.0f, 0, this->unk_1CE & 7); + func_8013C964(&this->actor, globalCtx, 0.0f, 0.0f, EXCH_ITEM_NONE, this->unk_1CE & 7); } func_80B3E460(this); } } } -s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, - Gfx** gfx) { +s32 EnDai_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { EnDai* this = THIS; if (!(this->unk_1CE & 0x40)) { @@ -591,17 +580,17 @@ s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == 11) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_1E4); + Matrix_MultVec3f(&gZeroVec3f, &this->unk_1E4); } if (limbIndex == 10) { *dList = NULL; } - return 0; + return false; } -void func_80B3F614(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { +void EnDai_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { static Vec3f D_80B3FE4C = { 0.0f, 0.0f, 0.0f }; EnDai* this = THIS; @@ -613,23 +602,23 @@ void func_80B3F614(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* D_80B3FE4C.x = sREG(0); D_80B3FE4C.y = sREG(1); D_80B3FE4C.z = sREG(2); - Matrix_MultiplyVector3fByState(&D_80B3FE4C, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80B3FE4C, &this->actor.focus.pos); Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); - Matrix_CopyCurrentState(&sp24); - func_8018219C(&sp24, &sp64, 0); + Matrix_Get(&sp24); + Matrix_MtxFToYXZRot(&sp24, &sp64, false); this->unk_1D4 = BINANG_SUB(sp64.y, 0x4000); break; case 10: - Matrix_CopyCurrentState(&this->unk_18C); + Matrix_Get(&this->unk_18C); break; } } -void func_80B3F6EC(GlobalContext* globalCtx, s32 arg1, Actor* thisx, Gfx** gfx) { +void EnDai_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { EnDai* this = THIS; - switch (arg1) { + switch (limbIndex) { case 9: if (this->unk_1CE & 0x100) { func_80B3EC84(this); @@ -647,10 +636,10 @@ void func_80B3F6EC(GlobalContext* globalCtx, s32 arg1, Actor* thisx, Gfx** gfx) } void func_80B3F78C(EnDai* this, GlobalContext* globalCtx) { - static AnimationHeader* D_80B3FE58[] = { - &D_060107B0, &D_06010FB0, &D_060117B0, &D_06010FB0, &D_06011FB0, &D_060127B0, + static TexturePtr D_80B3FE58[] = { + object_dai_Tex_0107B0, object_dai_Tex_010FB0, object_dai_Tex_0117B0, + object_dai_Tex_010FB0, object_dai_Tex_011FB0, object_dai_Tex_0127B0, }; - s32 pad; if (globalCtx->actorCtx.unkB != 0) { @@ -669,14 +658,14 @@ void func_80B3F78C(EnDai* this, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 255); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE58[this->unk_1D6])); - POLY_XLU_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_XLU_DISP); + POLY_XLU_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_XLU_DISP); if (this->unk_1CE & 0x40) { - Matrix_SetCurrentState(&this->unk_18C); + Matrix_Put(&this->unk_18C); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0600C538); + gSPDisplayList(POLY_XLU_DISP++, object_dai_DL_00C538); } func_80B3E5B4(this, globalCtx); @@ -685,8 +674,9 @@ void func_80B3F78C(EnDai* this, GlobalContext* globalCtx) { } void func_80B3F920(EnDai* this, GlobalContext* globalCtx) { - static AnimationHeader* D_80B3FE70[] = { - &D_060107B0, &D_06010FB0, &D_060117B0, &D_06010FB0, &D_06011FB0, &D_060127B0, + static TexturePtr D_80B3FE70[] = { + object_dai_Tex_0107B0, object_dai_Tex_010FB0, object_dai_Tex_0117B0, + object_dai_Tex_010FB0, object_dai_Tex_011FB0, object_dai_Tex_0127B0, }; s32 pad; @@ -701,13 +691,13 @@ void func_80B3F920(EnDai* this, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE70[this->unk_1D6])); - POLY_OPA_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_OPA_DISP); - Matrix_SetCurrentState(&this->unk_18C); + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_OPA_DISP); + Matrix_Put(&this->unk_18C); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_0600C538); + gSPDisplayList(POLY_OPA_DISP++, object_dai_DL_00C538); CLOSE_DISPS(globalCtx->state.gfxCtx); } else { @@ -720,13 +710,13 @@ void func_80B3F920(EnDai* this, GlobalContext* globalCtx) { gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1CD); gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3FE70[this->unk_1D6])); - POLY_XLU_DISP = - func_8013AB00(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80B3F598, func_80B3F614, func_80B3F6EC, &this->actor, POLY_XLU_DISP); - Matrix_SetCurrentState(&this->unk_18C); + POLY_XLU_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnDai_OverrideLimbDraw, EnDai_PostLimbDraw, + EnDai_TransformLimbDraw, &this->actor, POLY_XLU_DISP); + Matrix_Put(&this->unk_18C); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0600C538); + gSPDisplayList(POLY_XLU_DISP++, object_dai_DL_00C538); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 40eac8099..3d76b7391 100644 --- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -5,8 +5,9 @@ */ #include "z_en_daiku.h" +#include "objects/object_daiku/object_daiku.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDaiku*)thisx) @@ -20,22 +21,6 @@ void func_80943BC0(EnDaiku* this); void func_80943BDC(EnDaiku* this, GlobalContext* globalCtx); void func_809438F8(EnDaiku* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000600; -extern AnimationHeader D_06000C44; -extern AnimationHeader D_06001114; -extern AnimationHeader D_06002FA0; -extern FlexSkeletonHeader D_0600A850; -extern AnimationHeader D_0600ACD0; -extern AnimationHeader D_0600B690; -extern AnimationHeader D_0600BEAC; -extern AnimationHeader D_0600C234; -extern AnimationHeader D_0600C92C; -extern Gfx D_06006D70[]; -extern Gfx D_06006E80[]; -extern Gfx D_06006FB0[]; -extern Gfx D_060070C0[]; -extern Gfx D_06008EC8[]; - const ActorInit En_Daiku_InitVars = { ACTOR_EN_DAIKU, ACTORCAT_NPC, @@ -76,13 +61,13 @@ void EnDaiku_Init(Actor* thisx, GlobalContext* globalCtx) { EnDaiku* this = THIS; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 40.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 40.0f); this->actor.targetMode = 0; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->unk_278 = ENDAIKU_GET_FF(&this->actor); if (this->unk_278 == ENDAIKU_PARAMS_FF_3) { this->unk_288 = ENDAIKU_GET_FF00(&this->actor); - this->unk_258 = func_8013D648(globalCtx, this->unk_288, 0x3F); + this->unk_258 = SubS_GetPathByIndex(globalCtx, this->unk_288, 0x3F); } else if (this->unk_278 == ENDAIKU_PARAMS_FF_2) { this->unk_264 = -2000; } @@ -91,11 +76,12 @@ void EnDaiku_Init(Actor* thisx, GlobalContext* globalCtx) { this->collider.dim.radius = 30; this->collider.dim.height = 60; this->collider.dim.yShift = 0; - this->actor.flags |= 0x8000000; - if ((gSaveContext.weekEventReg[63] & 0x80) || ((gSaveContext.day == 3) && gSaveContext.isNight)) { + this->actor.flags |= ACTOR_FLAG_8000000; + if ((gSaveContext.save.weekEventReg[63] & 0x80) || + ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) { Actor_MarkForDeath(&this->actor); } - } else if ((gSaveContext.day == 3) && gSaveContext.isNight) { + } else if ((gSaveContext.save.day == 3) && gSaveContext.save.isNight) { Actor_MarkForDeath(&this->actor); } @@ -108,18 +94,18 @@ void EnDaiku_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_27E = this->unk_278 * 4 + 4; case ENDAIKU_PARAMS_FF_1: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A850, &D_06002FA0, this->jointTable, - this->morphTable, 17); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_daiku_Skel_00A850, &object_daiku_Anim_002FA0, + this->jointTable, this->morphTable, 17); break; case ENDAIKU_PARAMS_FF_2: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A850, &D_0600B690, this->jointTable, - this->morphTable, 17); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_daiku_Skel_00A850, &object_daiku_Anim_00B690, + this->jointTable, this->morphTable, 17); break; case ENDAIKU_PARAMS_FF_3: - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A850, &D_06001114, this->jointTable, - this->morphTable, 17); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_daiku_Skel_00A850, &object_daiku_Anim_001114, + this->jointTable, this->morphTable, 17); break; } @@ -134,8 +120,9 @@ void EnDaiku_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_8094373C(EnDaiku* this, s32 arg1) { static AnimationHeader* D_809440A4[] = { - &D_06002FA0, &D_0600ACD0, &D_0600C92C, &D_06000C44, &D_0600C234, - &D_06000600, &D_06001114, &D_0600B690, &D_0600BEAC, + &object_daiku_Anim_002FA0, &object_daiku_Anim_00ACD0, &object_daiku_Anim_00C92C, + &object_daiku_Anim_000C44, &object_daiku_Anim_00C234, &object_daiku_Anim_000600, + &object_daiku_Anim_001114, &object_daiku_Anim_00B690, &object_daiku_Anim_00BEAC, }; static u8 D_809440C8[] = { 0, 0, 0, 0, 2, 0, 0, 2, 2, @@ -147,14 +134,14 @@ void func_8094373C(EnDaiku* this, s32 arg1) { void func_809437C8(EnDaiku* this) { if ((this->unk_288 != -1) && (this->unk_258 != 0)) { - if (!func_8013D68C(this->unk_258, this->unk_25C, &this->unk_26C)) { + if (!SubS_CopyPointFromPath(this->unk_258, this->unk_25C, &this->unk_26C)) { Actor_MarkForDeath(&this->actor); } } } void func_80943820(EnDaiku* this) { - s32 day = gSaveContext.day - 1; + s32 day = gSaveContext.save.day - 1; switch (this->unk_278) { case 0: @@ -181,7 +168,7 @@ void func_80943820(EnDaiku* this) { void func_809438F8(EnDaiku* this, GlobalContext* globalCtx) { f32 currentFrame = this->skelAnime.curFrame; s32 pad; - s32 day = gSaveContext.day - 1; + s32 day = gSaveContext.save.day - 1; s32 pad2; if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { @@ -195,7 +182,7 @@ void func_809438F8(EnDaiku* this, GlobalContext* globalCtx) { this->actor.textId = sTextIds[this->unk_28C]; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80943BC0(this); return; } @@ -255,7 +242,7 @@ void func_80943BDC(EnDaiku* this, GlobalContext* globalCtx) { } } - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); func_80943820(this); } @@ -269,7 +256,7 @@ void EnDaiku_Update(Actor* thisx, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); } - if ((this->unk_278 == ENDAIKU_PARAMS_FF_0) && (gSaveContext.day == 3) && (gSaveContext.isNight)) { + if ((this->unk_278 == ENDAIKU_PARAMS_FF_0) && (gSaveContext.save.day == 3) && (gSaveContext.save.isNight)) { Actor_MarkForDeath(&this->actor); return; } @@ -286,8 +273,8 @@ void EnDaiku_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_SetScale(&this->actor, 0.01f); this->actor.shape.rot.y = this->actor.world.rot.y; - Actor_SetHeight(&this->actor, 65.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, 65.0f); + Actor_MoveWithGravity(&this->actor); Math_SmoothStepToS(&this->unk_260, this->unk_266, 1, 0xBB8, 0); Math_SmoothStepToS(&this->unk_25E, this->unk_264, 1, 0xBB8, 0); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); @@ -296,7 +283,8 @@ void EnDaiku_Update(Actor* thisx, GlobalContext* globalCtx) { CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } -s32 func_80943E18(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnDaiku_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnDaiku* this = THIS; if (limbIndex == 15) { @@ -304,11 +292,16 @@ s32 func_80943E18(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p rot->z += this->unk_25E; } - return 0; + return false; } -void func_80943E60(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { - static Gfx* D_809440D4[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70 }; +void EnDaiku_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Gfx* D_809440D4[] = { + object_daiku_DL_0070C0, + object_daiku_DL_006FB0, + object_daiku_DL_006E80, + object_daiku_DL_006D70, + }; EnDaiku* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -318,7 +311,7 @@ void func_80943E60(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* } if ((this->unk_278 == ENDAIKU_PARAMS_FF_3) && (limbIndex == 8)) { - gSPDisplayList(POLY_OPA_DISP++, D_06008EC8); + gSPDisplayList(POLY_OPA_DISP++, object_daiku_DL_008EC8); } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -354,7 +347,7 @@ void EnDaiku_Draw(Actor* thisx, GlobalContext* globalCtx) { } SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_80943E18, func_80943E60, &this->actor); + EnDaiku_OverrideLimbDraw, EnDaiku_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c index daa159788..167c11835 100644 --- a/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c +++ b/src/overlays/actors/ovl_En_Daiku2/z_en_daiku2.c @@ -6,8 +6,10 @@ #include "z_en_daiku2.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_daiku/object_daiku.h" +#include "objects/object_bombiwa/object_bombiwa.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDaiku2*)thisx) @@ -30,22 +32,6 @@ void func_80BE71D8(EnDaiku2* this, GlobalContext* globalCtx); void func_80BE7504(EnDaiku2* this, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, s16 arg5); void func_80BE7718(EnDaiku2* this, GlobalContext* globalCtx); -extern AnimationHeader D_06002134; -extern AnimationHeader D_06002FA0; -extern AnimationHeader D_0600ACD0; -extern AnimationHeader D_0600C92C; -extern AnimationHeader D_06000C44; -extern AnimationHeader D_0600C234; -extern AnimationHeader D_06000600; -extern AnimationHeader D_06001114; -extern AnimationHeader D_0600B690; -extern AnimationHeader D_06001A24; -extern AnimationHeader D_0600D328; -extern FlexSkeletonHeader D_0600A850; -extern Gfx D_06009638[]; -extern Gfx D_0600A390[]; -extern Gfx D_060009E0[]; - const ActorInit En_Daiku2_InitVars = { ACTOR_EN_DAIKU2, ACTORCAT_NPC, @@ -84,7 +70,7 @@ static ColliderCylinderInit sCylinderInit = { void func_80BE61D0(EnDaiku2* this) { if ((this->unk_27A != -1) && (this->unk_258 != 0)) { - if (func_8013D68C(this->unk_258, this->unk_25C, &this->unk_268) == 0) { + if (!SubS_CopyPointFromPath(this->unk_258, this->unk_25C, &this->unk_268)) { Actor_MarkForDeath(&this->actor); } } @@ -92,16 +78,17 @@ void func_80BE61D0(EnDaiku2* this) { void EnDaiku2_Init(Actor* thisx, GlobalContext* globalCtx) { EnDaiku2* this = THIS; - s32 day = gSaveContext.day; + s32 day = gSaveContext.save.day; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 40.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A850, &D_06002FA0, this->jointTable, this->morphTable, 17); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 40.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_daiku_Skel_00A850, &object_daiku_Anim_002FA0, + this->jointTable, this->morphTable, 17); this->actor.targetMode = 0; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->unk_278 = ENDAIKU2_GET_7F(&this->actor); this->unk_27A = ENDAIKU2_GET_1F80(&this->actor); - this->unk_258 = func_8013D648(globalCtx, this->unk_27A, 0x3F); + this->unk_258 = SubS_GetPathByIndex(globalCtx, this->unk_27A, 0x3F); this->unk_280 = ENDAIKU2_GET_8000(&this->actor); Actor_SetScale(&this->actor, 0.01f); if (!this->unk_280) { @@ -135,8 +122,9 @@ void EnDaiku2_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_80BE6408(EnDaiku2* this, s32 arg1) { static AnimationHeader* sAnimations[] = { - &D_06002FA0, &D_0600ACD0, &D_0600C92C, &D_06000C44, &D_0600C234, &D_06000600, - &D_06001114, &D_0600B690, &D_06001A24, &D_06002134, &D_0600D328, + &object_daiku_Anim_002FA0, &object_daiku_Anim_00ACD0, &object_daiku_Anim_00C92C, &object_daiku_Anim_000C44, + &object_daiku_Anim_00C234, &object_daiku_Anim_000600, &object_daiku_Anim_001114, &object_daiku_Anim_00B690, + &object_daiku_Anim_001A24, &object_daiku_Anim_002134, &object_daiku_Anim_00D328, }; static u8 D_80BE7958[] = { 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, @@ -158,11 +146,11 @@ s32 func_80BE64C0(EnDaiku2* this, GlobalContext* globalCtx) { Math_Vec3f_Copy(&sp30, &this->actor.world.pos); Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); - bomb = (EnBom*)func_800BE0B8(globalCtx, &this->actor, -1, ACTORCAT_EXPLOSIVES, BREG(7) + 240.0f); + bomb = (EnBom*)Actor_FindNearby(globalCtx, &this->actor, -1, ACTORCAT_EXPLOSIVES, BREG(7) + 240.0f); Math_Vec3f_Copy(&this->actor.world.pos, &sp30); if ((this->unk_278 >= ENDAIKU2_GET_7F_0) && !Flags_GetSwitch(globalCtx, this->unk_278) && (bomb != NULL) && (bomb->actor.id == ACTOR_EN_BOM)) { - if (bomb->unk_1F9 == 0) { + if (!bomb->isPowderKeg) { this->actor.textId = 0x32D3; } else { this->actor.textId = 0x32D4; @@ -175,10 +163,10 @@ s32 func_80BE64C0(EnDaiku2* this, GlobalContext* globalCtx) { } void func_80BE65B4(EnDaiku2* this, GlobalContext* globalCtx) { - switch (gSaveContext.day - 1) { + switch (gSaveContext.save.day - 1) { case 0: this->unk_28A = 0; - if (gSaveContext.weekEventReg[64] & 2) { + if (gSaveContext.save.weekEventReg[64] & 2) { this->unk_28A = 6; } func_80BE6408(this, 8); @@ -186,7 +174,7 @@ void func_80BE65B4(EnDaiku2* this, GlobalContext* globalCtx) { case 1: this->unk_28A = 2; - if (gSaveContext.weekEventReg[64] & 4) { + if (gSaveContext.save.weekEventReg[64] & 4) { this->unk_28A = 7; } func_80BE6408(this, 8); @@ -213,7 +201,7 @@ void func_80BE65B4(EnDaiku2* this, GlobalContext* globalCtx) { void func_80BE66E4(EnDaiku2* this, GlobalContext* globalCtx) { f32 sp9C = this->skelAnime.curFrame; - s32 sp98 = gSaveContext.day - 1; + s32 sp98 = gSaveContext.save.day - 1; s32 i; Vec3f sp88; Vec3f sp7C; @@ -233,7 +221,7 @@ void func_80BE66E4(EnDaiku2* this, GlobalContext* globalCtx) { this->actor.textId = sTextIds[this->unk_28A]; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80BE6B40(this, globalCtx); return; } @@ -245,7 +233,7 @@ void func_80BE66E4(EnDaiku2* this, GlobalContext* globalCtx) { func_800B8614(&this->actor, globalCtx, 80.0f); if ((this->unk_276 == 8) && Animation_OnFrame(&this->skelAnime, 6.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_ROCK_BROKEN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROCK_BROKEN); for (i = 0; i < 10; i++) { Math_Vec3f_Copy(&sp70, &this->actor.world.pos); @@ -274,8 +262,8 @@ void func_80BE66E4(EnDaiku2* this, GlobalContext* globalCtx) { if ((this->unk_276 == 5) || (this->unk_276 == 9)) { func_80BE6408(this, 10); } else if ((this->unk_276 == 10) && (this->unk_284 <= sp9C)) { - this->unk_284 = Animation_GetLastFrame(&D_06002134); - Animation_Change(&this->skelAnime, &D_06002134, -1.0f, this->unk_284, 0.0f, 2, -4.0f); + this->unk_284 = Animation_GetLastFrame(&object_daiku_Anim_002134); + Animation_Change(&this->skelAnime, &object_daiku_Anim_002134, -1.0f, this->unk_284, 0.0f, 2, -4.0f); this->unk_276 = 11; } else if ((this->unk_276 == 11) && (sp9C <= 0.0f)) { func_80BE6408(this, 8); @@ -291,7 +279,7 @@ void func_80BE66E4(EnDaiku2* this, GlobalContext* globalCtx) { } void func_80BE6B40(EnDaiku2* this, GlobalContext* globalCtx) { - s32 day = gSaveContext.day; + s32 day = gSaveContext.save.day; this->unk_288 = 1; if ((day != 3) && Flags_GetSwitch(globalCtx, this->unk_278)) { @@ -304,8 +292,8 @@ void func_80BE6B40(EnDaiku2* this, GlobalContext* globalCtx) { void func_80BE6BC0(EnDaiku2* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0x0); - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - s32 day = gSaveContext.day - 1; + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + s32 day = gSaveContext.save.day - 1; func_801477B4(globalCtx); @@ -319,11 +307,11 @@ void func_80BE6BC0(EnDaiku2* this, GlobalContext* globalCtx) { } else { switch (day) { case 0: - gSaveContext.weekEventReg[64] |= 2; + gSaveContext.save.weekEventReg[64] |= 2; break; case 1: - gSaveContext.weekEventReg[64] |= 4; + gSaveContext.save.weekEventReg[64] |= 4; break; } func_80BE65B4(this, globalCtx); @@ -342,7 +330,7 @@ void func_80BE6D40(EnDaiku2* this, GlobalContext* globalCtx) { s32 pad[3]; s16 sp3A = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_268); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80BE6BC0; return; } @@ -376,7 +364,7 @@ void func_80BE6EF0(EnDaiku2* this, GlobalContext* globalCtx) { Vec3f sp40; s16 var; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80BE6BC0; return; } @@ -460,8 +448,8 @@ void EnDaiku2_Update(Actor* thisx, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actionFunc(this, globalCtx); this->actor.shape.rot.y = this->actor.world.rot.y; - Actor_SetHeight(&this->actor, 65.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, 65.0f); + Actor_MoveWithGravity(&this->actor); Math_ApproachF(&this->unk_260, this->unk_264, 0.3f, 2.0f); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); @@ -479,11 +467,11 @@ void EnDaiku2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if (limbIndex == 14) { Matrix_Scale(this->unk_260, this->unk_260, this->unk_260, 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_06009638); + gSPDisplayList(POLY_OPA_DISP++, object_daiku_DL_009638); } if (limbIndex == 15) { - gSPDisplayList(POLY_OPA_DISP++, D_0600A390); + gSPDisplayList(POLY_OPA_DISP++, object_daiku_DL_00A390); } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -561,17 +549,17 @@ void func_80BE7718(EnDaiku2* this, GlobalContext* globalCtx) { for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { if (particle->isEnabled) { - Matrix_StatePush(); - Matrix_InsertTranslation(particle->unk_04.x, particle->unk_04.y, particle->unk_04.z, MTXMODE_NEW); - Matrix_InsertXRotation_s(particle->unk_28.x, MTXMODE_APPLY); - Matrix_RotateY(particle->unk_28.y, MTXMODE_APPLY); - Matrix_InsertZRotation_s(particle->unk_28.z, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Translate(particle->unk_04.x, particle->unk_04.y, particle->unk_04.z, MTXMODE_NEW); + Matrix_RotateXS(particle->unk_28.x, MTXMODE_APPLY); + Matrix_RotateYS(particle->unk_28.y, MTXMODE_APPLY); + Matrix_RotateZS(particle->unk_28.z, MTXMODE_APPLY); Matrix_Scale(particle->unk_30, particle->unk_30, particle->unk_30, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_060009E0); + gSPDisplayList(POLY_OPA_DISP++, object_bombiwa_DL_0009E0); - Matrix_StatePop(); + Matrix_Pop(); } } } 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 f309102bc..6292103ee 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.c +++ b/src/overlays/actors/ovl_En_Death/z_en_death.c @@ -1,6 +1,12 @@ +/* + * File: z_en_death.c + * Overlay: ovl_En_Death + * Description: Gomess + */ + #include "z_en_death.h" -#define FLAGS 0x00001035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_1000) #define THIS ((EnDeath*)thisx) 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 ecfd20483..1939a5bcc 100644 --- a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c +++ b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c @@ -1,6 +1,12 @@ +/* + * File: z_en_dekubaba.c + * Overlay: ovl_En_Dekubaba + * Description: Deku Baba + */ + #include "z_en_dekubaba.h" -#define FLAGS 0x00000405 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnDekubaba*)thisx) 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 39acd872d..9486507bc 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -7,7 +7,7 @@ #include "z_en_dekunuts.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnDekunuts*)thisx) @@ -38,20 +38,6 @@ void func_808BE4D4(EnDekunuts* this, GlobalContext* globalCtx); void func_808BE680(EnDekunuts* this); void func_808BE6C4(EnDekunuts* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000168; -extern Gfx D_06001E50[]; -extern Gfx D_06001F50[]; -extern SkeletonHeader D_06002468; -extern AnimationHeader D_0600259C; -extern AnimationHeader D_06002A5C; -extern AnimationHeader D_06002BD4; -extern AnimationHeader D_06002DD4; -extern AnimationHeader D_06002FA4; -extern AnimationHeader D_06003180; -extern AnimationHeader D_0600326C; -extern AnimationHeader D_060033E4; -extern AnimationHeader D_06003780; - const ActorInit En_Dekunuts_InitVars = { ACTOR_EN_DEKUNUTS, ACTORCAT_ENEMY, @@ -131,8 +117,9 @@ void EnDekunuts_Init(Actor* thisx, GlobalContext* globalCtx) { EnDekunuts* this = THIS; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06002468, &D_0600326C, this->jointTable, this->morphTable, 10); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 35.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuScrubSkel, &gDekuScrubIdleAnim, this->jointTable, + this->morphTable, DEKU_SCRUB_LIMB_MAX); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); this->unk_194 = ENDEKUNUTS_GET_FF00(&this->actor); @@ -142,7 +129,7 @@ void EnDekunuts_Init(Actor* thisx, GlobalContext* globalCtx) { } if (this->actor.params == ENDEKUNUTS_GET_FF00_1) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->collider.base.colType = COLTYPE_NONE; this->collider.info.bumperFlags |= (BUMP_NO_HITMARK | BUMP_NO_SWORD_SFX | BUMP_NO_DAMAGE | BUMP_NO_AT_INFO); } else if (this->actor.params == ENDEKUNUTS_GET_FF00_2) { @@ -159,26 +146,26 @@ void EnDekunuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void func_808BD348(EnDekunuts* this) { - this->unk_18E = 10; - this->unk_214 = 0.55f; - this->unk_218 = 0.82500005f; - this->unk_210 = 1.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffFrozenSteamScale = 0.82500005f; + this->drawDmgEffAlpha = 1.0f; this->collider.base.colType = COLTYPE_HIT3; this->unk_190 = 80; - func_800BCB70(&this->actor, 0x4000, 255, 0, 80); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); } void func_808BD3B4(EnDekunuts* this, GlobalContext* globalCtx) { - if (this->unk_18E == 10) { - this->unk_18E = 0; + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->collider.base.colType = COLTYPE_HIT6; - this->unk_210 = 0.0f; - func_800BF7CC(globalCtx, &this->actor, this->unk_21C, 8, 2, 0.2f, 0.2f); + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 8, 2, 0.2f, 0.2f); } } void func_808BD428(EnDekunuts* this) { - Animation_PlayOnceSetSpeed(&this->skelAnime, &D_06003180, 0.0f); + Animation_PlayOnceSetSpeed(&this->skelAnime, &gDekuScrubUpAnim, 0.0f); this->unk_190 = Rand_S16Offset(100, 50); this->collider.dim.height = 5; Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); @@ -200,17 +187,17 @@ void func_808BD49C(EnDekunuts* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 9.0f)) { this->collider.base.acFlags |= AC_ON; } else if (Animation_OnFrame(&this->skelAnime, 8.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_UP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); } this->collider.dim.height = (s32)((CLAMP(this->skelAnime.curFrame, 9.0f, 12.0f) - 9.0f) * 9.0f) + 5; - if (!phi_v1 && (this->actor.params == ENDEKUNUTS_GET_FF00_0) && - (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) && (this->actor.xzDistToPlayer < 120.0f)) { + if (!phi_v1 && (this->actor.params == ENDEKUNUTS_GET_FF00_0) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && + (this->actor.xzDistToPlayer < 120.0f)) { func_808BDC9C(this); } else if (SkelAnime_Update(&this->skelAnime)) { if (((this->unk_190 == 0) && (this->actor.xzDistToPlayer > 320.0f)) || - (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK)) { + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE)) { func_808BD78C(this); } else { if (this->actor.params == ENDEKUNUTS_GET_FF00_1) { @@ -224,8 +211,8 @@ void func_808BD49C(EnDekunuts* this, GlobalContext* globalCtx) { } if (phi_v1 && ((this->actor.xzDistToPlayer > 160.0f) || (this->actor.params != ENDEKUNUTS_GET_FF00_0)) && - (((this->actor.params == ENDEKUNUTS_GET_FF00_0) && (fabsf(this->actor.yDistToPlayer) < 120.0f)) || - ((this->actor.params == ENDEKUNUTS_GET_FF00_2) && (this->actor.yDistToPlayer > -60.0f)) || + (((this->actor.params == ENDEKUNUTS_GET_FF00_0) && (fabsf(this->actor.playerHeightRel) < 120.0f)) || + ((this->actor.params == ENDEKUNUTS_GET_FF00_2) && (this->actor.playerHeightRel > -60.0f)) || (this->actor.params == ENDEKUNUTS_GET_FF00_1)) && ((this->unk_190 == 0) || (this->actor.xzDistToPlayer < 480.0f))) { this->skelAnime.playSpeed = 1.0f; @@ -233,7 +220,7 @@ void func_808BD49C(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BD78C(EnDekunuts* this) { - Animation_PlayLoop(&this->skelAnime, &D_06002FA4); + Animation_PlayLoop(&this->skelAnime, &gDekuScrubLookAroundAnim); this->unk_190 = 2; this->actionFunc = func_808BD7D4; } @@ -247,13 +234,13 @@ void func_808BD7D4(EnDekunuts* this, GlobalContext* globalCtx) { } if ((this->unk_190 == 0) || - ((this->actor.xzDistToPlayer < 120.0f) && Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { + ((this->actor.xzDistToPlayer < 120.0f) && Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { func_808BDC9C(this); } } void func_808BD870(EnDekunuts* this) { - Animation_MorphToLoop(&this->skelAnime, &D_0600326C, -3.0f); + Animation_MorphToLoop(&this->skelAnime, &gDekuScrubIdleAnim, -3.0f); if (this->actionFunc == func_808BDA4C) { this->unk_190 = 4098; } else { @@ -277,13 +264,13 @@ void func_808BD8D8(EnDekunuts* this, GlobalContext* globalCtx) { if (this->unk_190 == 0x1000) { if ((this->actor.xzDistToPlayer > 480.0f) || ((this->actor.params == ENDEKUNUTS_GET_FF00_0) && (this->actor.xzDistToPlayer < 120.0f)) || - (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK)) { + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE)) { func_808BDC9C(this); } else { func_808BDA08(this); } } else if (this->unk_190 == 0) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) { func_808BDC9C(this); } else { func_808BDA08(this); @@ -292,7 +279,7 @@ void func_808BD8D8(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BDA08(EnDekunuts* this) { - Animation_PlayOnce(&this->skelAnime, &D_06000168); + Animation_PlayOnce(&this->skelAnime, &gDekuScrubSpitAnim); this->unk_190 = this->unk_194; this->actionFunc = func_808BDA4C; } @@ -333,10 +320,10 @@ void func_808BDA4C(EnDekunuts* this, GlobalContext* globalCtx) { if (Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_NUTSBALL, pos.x, pos.y, pos.z, this->actor.world.rot.x, this->actor.shape.rot.y, 0, params) != NULL) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_THROW); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_THROW); } } else if ((this->unk_190 >= 2) && Animation_OnFrame(&this->skelAnime, 12.0f)) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06000168, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuScrubSpitAnim, -3.0f); if (this->unk_190 != 0) { this->unk_190--; } @@ -344,17 +331,17 @@ void func_808BDA4C(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BDC9C(EnDekunuts* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06002A5C, -5.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuScrubBurrowAnim, -5.0f); this->unk_190 = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); this->actionFunc = func_808BDD54; } void func_808BDCF0(EnDekunuts* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06002A5C, -5.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuScrubBurrowAnim, -5.0f); this->collider.base.acFlags &= ~AC_ON; this->unk_190 = 80; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); this->actionFunc = func_808BDD54; } @@ -379,12 +366,12 @@ void func_808BDD54(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BDE7C(EnDekunuts* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06002DD4, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuScrubUnburrowAnim, -3.0f); this->collider.dim.height = 37; this->actor.colChkInfo.mass = 50; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DAMAGE); this->actor.world.rot.x = 0; - this->actor.flags |= 0x20; + this->actor.flags |= ACTOR_FLAG_20; this->collider.base.acFlags &= ~AC_ON; this->actionFunc = func_808BDEF8; } @@ -399,7 +386,7 @@ void func_808BDEF8(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BDF60(EnDekunuts* this) { - Animation_PlayLoop(&this->skelAnime, &D_06003780); + Animation_PlayLoop(&this->skelAnime, &gDekuScrubRunAnim); this->unk_190 = 2; this->unk_18C = 0; this->collider.base.acFlags |= AC_ON; @@ -418,7 +405,7 @@ void func_808BDFB8(EnDekunuts* this, GlobalContext* globalCtx) { } if (this->unk_18C != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); this->unk_18C = 0; } else { this->unk_18C = 1; @@ -447,7 +434,7 @@ void func_808BDFB8(EnDekunuts* this, GlobalContext* globalCtx) { if ((this->unk_18D == 0) && (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 20.0f) && (fabsf(this->actor.world.pos.y - this->actor.home.pos.y) < 2.0f)) { this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->actor.flags &= ~0x20; + this->actor.flags &= ~ACTOR_FLAG_20; this->actor.speedXZ = 0.0f; func_808BDC9C(this); } else if (this->unk_190 == 0) { @@ -456,7 +443,7 @@ void func_808BDFB8(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BE1CC(EnDekunuts* this) { - Animation_PlayLoop(&this->skelAnime, &D_060033E4); + Animation_PlayLoop(&this->skelAnime, &gDekuScrubPantingAnim); this->unk_190 = 3; this->actor.speedXZ = 0.0f; if (this->unk_18D != 0) { @@ -479,7 +466,7 @@ void func_808BE22C(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BE294(EnDekunuts* this, s32 arg1) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_0600259C, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDekuScrubDamageAnim, -3.0f); if (this->actor.params == ENDEKUNUTS_GET_FF00_0) { this->actor.speedXZ = 10.0f; if (arg1 != 0) { @@ -490,9 +477,9 @@ void func_808BE294(EnDekunuts* this, s32 arg1) { this->actor.world.rot.x = 0; this->collider.base.acFlags &= ~AC_ON; this->actionFunc = func_808BE358; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DAMAGE); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_CUTBODY); - func_800BCB70(&this->actor, 0x4000, 255, 0, Animation_GetLastFrame(&D_0600259C)); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_CUTBODY); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, Animation_GetLastFrame(&gDekuScrubDamageAnim)); } void func_808BE358(EnDekunuts* this, GlobalContext* globalCtx) { @@ -531,10 +518,10 @@ void func_808BE3FC(EnDekunuts* this, GlobalContext* globalCtx) { } void func_808BE484(EnDekunuts* this) { - Animation_PlayOnce(&this->skelAnime, &D_06002BD4); + Animation_PlayOnce(&this->skelAnime, &gDekuScrubDieAnim); this->actionFunc = func_808BE4D4; this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DEAD); } void func_808BE4D4(EnDekunuts* this, GlobalContext* globalCtx) { @@ -547,26 +534,27 @@ 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); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + EffectSsDeadDb_Spawn(globalCtx, &sp40, &gZeroVec3f, &gZeroVec3f, &D_808BEF90, &D_808BEF94, 200, 0, 13); + SoundSource_PlaySfxAtFixedWorldPos(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); Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xE0); Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ETCETERA, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, 0, this->actor.home.rot.y, 0, 0x80); - EffectSsHahen_SpawnBurst(globalCtx, &this->actor.home.pos, 6.0f, 0, 6, 2, 15, 64, 10, D_06001F50); + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.home.pos, 6.0f, 0, 6, 2, 15, 64, 10, + gDekuScrubFlowerFragmentDL); Actor_MarkForDeath(&this->actor); } } void func_808BE680(EnDekunuts* this) { - Animation_MorphToLoop(&this->skelAnime, &D_0600326C, -3.0f); + Animation_MorphToLoop(&this->skelAnime, &gDekuScrubIdleAnim, -3.0f); this->actionFunc = func_808BE6C4; } void func_808BE6C4(EnDekunuts* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) { + if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); } @@ -578,8 +566,9 @@ void func_808BE6C4(EnDekunuts* this, GlobalContext* globalCtx) { void func_808BE73C(EnDekunuts* 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_18E != 10) || !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + Actor_SetDropFlag(&this->actor, &this->collider.info); + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { func_808BD3B4(this, globalCtx); if ((this->actor.colChkInfo.mass == 50) || (this->actor.params != ENDEKUNUTS_GET_FF00_0)) { if ((this->actor.params != ENDEKUNUTS_GET_FF00_1) && !Actor_ApplyDamage(&this->actor)) { @@ -603,27 +592,27 @@ void func_808BE73C(EnDekunuts* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == 1) { this->unk_190 = 40; - func_800BCB70(&this->actor, 0, 255, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); func_808BE3A8(this); return; } if (this->actor.colChkInfo.damageEffect == 2) { - this->unk_210 = 4.0f; - this->unk_214 = 0.55f; - this->unk_18E = 0; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; } else if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_210 = 4.0f; - this->unk_214 = 0.55f; - this->unk_18E = 20; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; 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_SMALL_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == 5) { - this->unk_18E = 32; - this->unk_210 = 4.0f; - this->unk_214 = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; } func_808BE294(this, 1); @@ -651,7 +640,7 @@ void EnDekunuts_Update(Actor* thisx, GlobalContext* globalCtx) { func_808BE73C(this, globalCtx); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, this->collider.dim.radius, this->collider.dim.height, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); @@ -660,24 +649,26 @@ void EnDekunuts_Update(Actor* thisx, GlobalContext* globalCtx) { } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (this->unk_210 > 0.0f) { - if (this->unk_18E != 10) { - Math_StepToF(&this->unk_210, 0.0f, 0.05f); - this->unk_214 = (this->unk_210 + 1.0f) * 0.275f; - this->unk_214 = CLAMP_MAX(this->unk_214, 0.55f); - } else if ((this->unk_18E == 10) && !Math_StepToF(&this->unk_218, 0.55f, (33.0f / 1600.0f))) { + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } else if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + !Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, (33.0f / 1600.0f))) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } } -s32 func_808BEBD0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnDekunuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnDekunuts* this = THIS; f32 arg1, arg2, arg3; f32 currentFrame; if (this->actionFunc == func_808BDA4C) { - if (limbIndex == 5) { + if (limbIndex == DEKU_SCRUB_LIMB_SNOUT) { currentFrame = this->skelAnime.curFrame; if (currentFrame <= 6.0f) { arg2 = 1.0f - (currentFrame * 0.0833f); @@ -696,14 +687,14 @@ s32 func_808BEBD0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p return 0; } Matrix_Scale(arg1, arg2, arg3, MTXMODE_APPLY); - } else if ((limbIndex == 2) && (this->actor.params == ENDEKUNUTS_GET_FF00_2)) { + } else if ((limbIndex == DEKU_SCRUB_LIMB_HEAD) && (this->actor.params == ENDEKUNUTS_GET_FF00_2)) { rot->z = this->actor.world.rot.x; } } - return 0; + return false; } -void func_808BED30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDekunuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { static s8 D_808BEF98[] = { -1, -1, -1, 3, -1, 0, -1, 1, -1, 2, 0, 0, }; @@ -719,35 +710,35 @@ void func_808BED30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* if (value != -1) { if (value < 3) { - Matrix_GetStateTranslationAndScaledX(1000.0f, &this->unk_21C[value]); + Matrix_MultVecX(1000.0f, &this->limbPos[value]); } else { - Matrix_GetStateTranslation(&this->unk_21C[value]); + Matrix_MultZero(&this->limbPos[value]); ptr1 = &D_808BEFA4[0]; - ptr2 = &this->unk_21C[value + 1]; - for (i = value + 1; i < ARRAY_COUNT(this->unk_21C); i++) { - Matrix_MultiplyVector3fByState(ptr1, ptr2); + ptr2 = &this->limbPos[value + 1]; + for (i = value + 1; i < ARRAY_COUNT(this->limbPos); i++) { + Matrix_MultVec3f(ptr1, ptr2); ptr1++, ptr2++; } } } - if (limbIndex == 2) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + if (limbIndex == DEKU_SCRUB_LIMB_HEAD) { + Matrix_MultZero(&this->actor.focus.pos); } } void EnDekunuts_Draw(Actor* thisx, GlobalContext* globalCtx) { EnDekunuts* this = THIS; - SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, func_808BEBD0, func_808BED30, - &this->actor); - Matrix_SetStateRotationAndTranslation(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, - &this->actor.home.rot); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDekunuts_OverrideLimbDraw, + EnDekunuts_PostLimbDraw, &this->actor); + Matrix_SetTranslateRotateYXZ(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, + &this->actor.home.rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); if (this->actor.colorFilterTimer != 0) { func_800AE5A0(globalCtx); } - func_800BDFC0(globalCtx, D_06001E50); - func_800BE680(globalCtx, &this->actor, this->unk_21C, 8, this->unk_214, this->unk_218, this->unk_210, - this->unk_18E); + Gfx_DrawDListOpa(globalCtx, gDekuScrubFlowerDL); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); } diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.h b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.h index aa0b3e1bf..39d0dd954 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.h +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.h @@ -2,6 +2,7 @@ #define Z_EN_DEKUNUTS_H #include "global.h" +#include "objects/object_dekunuts/object_dekunuts.h" struct EnDekunuts; @@ -22,16 +23,16 @@ typedef struct EnDekunuts { /* 0x188 */ EnDekunutsActionFunc actionFunc; /* 0x18C */ u8 unk_18C; /* 0x18D */ u8 unk_18D; - /* 0x18E */ u8 unk_18E; + /* 0x18E */ u8 drawDmgEffType; /* 0x190 */ s16 unk_190; /* 0x192 */ s16 unk_192; /* 0x194 */ s16 unk_194; - /* 0x196 */ Vec3s jointTable[10]; - /* 0x1D2 */ Vec3s morphTable[10]; - /* 0x210 */ f32 unk_210; - /* 0x214 */ f32 unk_214; - /* 0x218 */ f32 unk_218; - /* 0x21C */ Vec3f unk_21C[8]; + /* 0x196 */ Vec3s jointTable[DEKU_SCRUB_LIMB_MAX]; + /* 0x1D2 */ Vec3s morphTable[DEKU_SCRUB_LIMB_MAX]; + /* 0x210 */ f32 drawDmgEffAlpha; + /* 0x214 */ f32 drawDmgEffScale; + /* 0x218 */ f32 drawDmgEffFrozenSteamScale; + /* 0x21C */ Vec3f limbPos[8]; /* 0x27C */ ColliderCylinder collider; } EnDekunuts; // size = 0x2C8 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 18cc974ed..76934448a 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,6 +1,13 @@ -#include "z_en_demo_heishi.h" +/* + * File: z_en_demo_heishi.c + * Overlay: ovl_En_Demo_heishi + * Description: Unused(?) version of Shiro + */ -#define FLAGS 0x00000009 +#include "z_en_demo_heishi.h" +#include "objects/object_sdn/object_sdn.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDemoheishi*)thisx) @@ -9,10 +16,22 @@ void EnDemoheishi_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnDemoheishi_Update(Actor* thisx, GlobalContext* globalCtx); void EnDemoheishi_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BE975C(EnDemoheishi* this, GlobalContext* globalCtx); -void func_80BE980C(EnDemoheishi* this, GlobalContext* globalCtx); +void EnDemoheishi_ChangeAnimation(EnDemoheishi* this, s32 animIndex); +void EnDemoheishi_SetupIdle(EnDemoheishi* this); +void EnDemoheishi_Idle(EnDemoheishi* this, GlobalContext* globalCtx); +void EnDemoheishi_SetupTalk(EnDemoheishi* this); +void EnDemoheishi_Talk(EnDemoheishi* this, GlobalContext* globalCtx); +s32 EnDemoheishi_OverrideLimbDraw(GlobalContext* globalctx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx); + +typedef enum { + /* 0 */ DEMOHEISHI_ANIMATION_STAND_HAND_ON_HIP, + /* 1 */ DEMOHEISHI_ANIMATION_CHEER_WITH_SPEAR, + /* 2 */ DEMOHEISHI_ANIMATION_WAVE, + /* 3 */ DEMOHEISHI_ANIMATION_SIT_AND_REACH, + /* 4 */ DEMOHEISHI_ANIMATION_STAND_UP +} EnDemoheishiAnimationIndex; -#if 0 const ActorInit En_Demo_heishi_InitVars = { ACTOR_EN_DEMO_HEISHI, ACTORCAT_NPC, @@ -25,37 +44,152 @@ const ActorInit En_Demo_heishi_InitVars = { (ActorFunc)EnDemoheishi_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BE9A50 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, 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_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 40, 40, 0, { 0, 0, 0 } }, }; -#endif +static u16 sTextIds[] = { 0x1473 }; // Shiro initial intro text -extern ColliderCylinderInit D_80BE9A50; +void EnDemoheishi_Init(Actor* thisx, GlobalContext* globalCtx) { + EnDemoheishi* this = THIS; -extern UNK_TYPE D_06003BFC; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gSoldierSkeleton, &gSoldierWave, this->jointTable, + this->morphTable, 17); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 6; + this->actor.gravity = -3.0f; + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + EnDemoheishi_SetupIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/EnDemoheishi_Init.s") +void EnDemoheishi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnDemoheishi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/EnDemoheishi_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE95EC.s") +void EnDemoheishi_ChangeAnimation(EnDemoheishi* this, s32 animIndex) { + static AnimationHeader* sAnimations[] = { + &gSoldierStandHandOnHip, &gSoldierCheerWithSpear, &gSoldierWave, &gSoldierSitAndReach, &gSoldierStandUp, + }; + static u8 sAnimModes[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE9678.s") + this->animIndex = animIndex; + this->frameCount = Animation_GetLastFrame(sAnimations[animIndex]); + Animation_Change(&this->skelAnime, sAnimations[this->animIndex], 1.0f, 0.0f, this->frameCount, + sAnimModes[this->animIndex], -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE970C.s") +void EnDemoheishi_SetHeadRotation(EnDemoheishi* this) { + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + s32 absYawDiff = ABS_ALT(yawDiff); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE975C.s") + this->headRotXTarget = 0; + if ((this->actor.xzDistToPlayer < 200.0f) && (absYawDiff < 0x4E20)) { + this->headRotXTarget = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + if (this->headRotXTarget > 0x2710) { + this->headRotXTarget = 0x2710; + } else if (this->headRotXTarget < -0x2710) { + this->headRotXTarget = -0x2710; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE97F0.s") +void EnDemoheishi_SetupIdle(EnDemoheishi* this) { + EnDemoheishi_ChangeAnimation(this, DEMOHEISHI_ANIMATION_STAND_HAND_ON_HIP); + this->textIdIndex = 0; + this->actor.textId = sTextIds[this->textIdIndex]; + this->isTalking = false; + this->actionFunc = EnDemoheishi_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE980C.s") +void EnDemoheishi_Idle(EnDemoheishi* this, GlobalContext* globalCtx) { + s32 absYawDiff; + s16 yawDiff; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/EnDemoheishi_Update.s") + this->actor.flags &= ~ACTOR_FLAG_8000000; + yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + absYawDiff = ABS_ALT(yawDiff); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/func_80BE9974.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + EnDemoheishi_SetupTalk(this); + } else if (absYawDiff <= 0x4BB8) { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Demo_heishi/EnDemoheishi_Draw.s") +void EnDemoheishi_SetupTalk(EnDemoheishi* this) { + this->isTalking = true; + this->actionFunc = EnDemoheishi_Talk; +} + +void EnDemoheishi_Talk(EnDemoheishi* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + EnDemoheishi_SetupIdle(this); + } +} + +void EnDemoheishi_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnDemoheishi* this = THIS; + + SkelAnime_Update(&this->skelAnime); + if (this->timer != 0) { + this->timer--; + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); + Actor_SetScale(&this->actor, 0.01f); + EnDemoheishi_SetHeadRotation(this); + + Actor_SetFocus(&this->actor, 60.0f); + Math_SmoothStepToS(&this->headRotX, this->headRotXTarget, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->headRotY, this->headRotYTarget, 1, 0x3E8, 0); + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); +} + +s32 EnDemoheishi_OverrideLimbDraw(GlobalContext* globalctx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnDemoheishi* this = THIS; + + if (limbIndex == DEMOHEISHI_LIMB_HEAD) { + rot->x += this->headRotX; + rot->y += this->headRotY; + rot->z += this->headRotZ; + } + + return false; +} + +void EnDemoheishi_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnDemoheishi* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnDemoheishi_OverrideLimbDraw, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.h b/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.h index 8dcdc899d..e6a2f9a91 100644 --- a/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.h +++ b/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.h @@ -7,12 +7,46 @@ struct EnDemoheishi; typedef void (*EnDemoheishiActionFunc)(struct EnDemoheishi*, GlobalContext*); +typedef enum { + /* 0 */ DEMOHEISHI_LIMB_NONE, + /* 1 */ DEMOHEISHI_LIMB_ROOT, + /* 2 */ DEMOHEISHI_LIMB_PELVIS, + /* 3 */ DEMOHEISHI_LIMB_LEFT_THIGH, + /* 4 */ DEMOHEISHI_LIMB_LEFT_SHIN, + /* 5 */ DEMOHEISHI_LIMB_LEFT_FOOT, + /* 6 */ DEMOHEISHI_LIMB_RIGHT_THIGH, + /* 7 */ DEMOHEISHI_LIMB_RIGHT_SHIN, + /* 8 */ DEMOHEISHI_LIMB_RIGHT_FOOT, + /* 9 */ DEMOHEISHI_LIMB_TORSO, + /* 10 */ DEMOHEISHI_LIMB_LEFT_SHOULDER, + /* 11 */ DEMOHEISHI_LIMB_LEFT_FOREARM, + /* 12 */ DEMOHEISHI_LIMB_LEFT_HAND, + /* 13 */ DEMOHEISHI_LIMB_RIGHT_SHOULDER, + /* 14 */ DEMOHEISHI_LIMB_RIGHT_FOREARM, + /* 15 */ DEMOHEISHI_LIMB_RIGHT_HAND_WITH_SPEAR, + /* 16 */ DEMOHEISHI_LIMB_HEAD, + /* 17 */ DEMOHEISHI_LIMB_MAX +} EnDemoheishiLimbs; + typedef struct EnDemoheishi { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x110]; - /* 0x0254 */ EnDemoheishiActionFunc actionFunc; - /* 0x0258 */ char unk_258[0x68]; -} EnDemoheishi; // size = 0x2C0 + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[DEMOHEISHI_LIMB_MAX]; + /* 0x1EE */ Vec3s morphTable[DEMOHEISHI_LIMB_MAX]; + /* 0x254 */ EnDemoheishiActionFunc actionFunc; + /* 0x258 */ s16 headRotY; + /* 0x25A */ s16 headRotX; + /* 0x25C */ s16 headRotZ; + /* 0x25E */ s16 headRotYTarget; + /* 0x260 */ s16 headRotXTarget; + /* 0x262 */ s16 headRotZTarget; + /* 0x264 */ s32 animIndex; + /* 0x268 */ s16 timer; + /* 0x26C */ f32 frameCount; + /* 0x270 */ s16 isTalking; + /* 0x272 */ s16 textIdIndex; + /* 0x274 */ ColliderCylinder colliderCylinder; +} EnDemoheishi; //size = 0x2C0 extern const ActorInit En_Demo_heishi_InitVars; diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.c b/src/overlays/actors/ovl_En_Dg/z_en_dg.c index c0c17367d..b56063880 100644 --- a/src/overlays/actors/ovl_En_Dg/z_en_dg.c +++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.c @@ -6,7 +6,7 @@ #include "z_en_dg.h" -#define FLAGS 0x00800019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnDg*)thisx) @@ -36,17 +36,6 @@ void func_8098BB10(EnDg* this, GlobalContext* globalCtx); void func_8098BBEC(EnDg* this, GlobalContext* globalCtx); void func_8098BC54(EnDg* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000998; -extern AnimationHeader D_06001048; -extern AnimationHeader D_06001348; -extern AnimationHeader D_06001560; -extern AnimationHeader D_060017C0; -extern AnimationHeader D_06001A84; -extern AnimationHeader D_06001BD8; -extern AnimationHeader D_06001FB0; -extern AnimationHeader D_060021C8; -extern FlexSkeletonHeader D_060080F0; - const ActorInit En_Dg_InitVars = { ACTOR_EN_DG, ACTORCAT_ENEMY, @@ -68,19 +57,32 @@ typedef struct { static D_8098C2A4_s D_8098C2A4 = { 0x0063, 0x0000 }; +/** + * Stores the state for the dogs milling about at the Doggy Racetrack. + */ typedef struct { - s16 unk_00; - s16 unk_02; - s16 unk_04; -} D_8098C2A8_s; + s16 color; // The dog's color, which is used as an index into sBaseSpeeds + s16 index; // The dog's index within sDogInfo + s16 textId; // The ID of the text to display when the dog is picked up +} RacetrackDogInfo; -static D_8098C2A8_s D_8098C2A8[] = { - { 3, 0, 0x3539 }, { 1, 1, 0x353A }, { 5, 2, 0x353B }, { 2, 3, 0x353C }, { 4, 4, 0x3538 }, - { 2, 5, 0x353E }, { 3, 6, 0x353F }, { 1, 7, 0x3540 }, { 1, 8, 0x3541 }, { 6, 9, 0x3542 }, - { 2, 10, 0x3543 }, { 3, 11, 0x3544 }, { 1, 12, 0x3545 }, { 4, 13, 0x3546 }, +/** + * A table of RacetrackDogInfo for every dog at the Doggy Racetrack. Note that the textId values + * in this table are updated by functions within this actor. + */ +static RacetrackDogInfo sRacetrackDogInfo[] = { + { DOG_COLOR_BEIGE, 0, 0x3539 }, { DOG_COLOR_WHITE, 1, 0x353A }, { DOG_COLOR_BLUE, 2, 0x353B }, + { DOG_COLOR_GRAY, 3, 0x353C }, { DOG_COLOR_BROWN, 4, 0x3538 }, { DOG_COLOR_GRAY, 5, 0x353E }, + { DOG_COLOR_BEIGE, 6, 0x353F }, { DOG_COLOR_WHITE, 7, 0x3540 }, { DOG_COLOR_WHITE, 8, 0x3541 }, + { DOG_COLOR_GOLD, 9, 0x3542 }, { DOG_COLOR_GRAY, 10, 0x3543 }, { DOG_COLOR_BEIGE, 11, 0x3544 }, + { DOG_COLOR_WHITE, 12, 0x3545 }, { DOG_COLOR_BROWN, 13, 0x3546 }, }; -static D_8098C2A8_s D_8098C2FC = { 0, -1, 0x353E }; +/** + * Stores the RacetrackDogInfo for the dog that is selected by the player. These values are just + * placeholders, and the actual value gets grabbed from sRacetrackDogInfo in func_80989E18. + */ +static RacetrackDogInfo sSelectedRacetrackDogInfo = { DOG_COLOR_DEFAULT, -1, 0x353E }; static ColliderCylinderInit sCylinderInit = { { @@ -139,31 +141,33 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -static ActorAnimationEntryS sAnimations[] = { - { &D_060021C8, 1.0f, 0, -1, 0, 0 }, { &D_060021C8, 1.0f, 0, -1, 0, -6 }, { &D_06001BD8, 1.0f, 0, -1, 0, 0 }, - { &D_06000998, 1.0f, 0, -1, 0, -6 }, { &D_06001FB0, 1.0f, 0, -1, 2, -6 }, { &D_06001FB0, 1.0f, 0, -1, 4, -6 }, - { &D_06001048, 1.0f, 0, -1, 2, -6 }, { &D_06001348, 1.0f, 0, -1, 0, -6 }, { &D_06001048, 1.0f, 0, 27, 2, -6 }, - { &D_06001048, 1.0f, 28, -1, 2, -6 }, { &D_06001048, 1.0f, 54, 54, 2, -6 }, { &D_060021C8, -1.5f, -1, 0, 0, -6 }, - { &D_06001560, 1.0f, 0, -1, 2, 0 }, { &D_06001A84, 1.2f, 0, -1, 2, 0 }, { &D_060017C0, 1.2f, 0, -1, 2, 0 }, - { &D_060021C8, 0.5f, 0, -1, 0, 0 }, +static AnimationInfoS sAnimations[] = { + { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogBarkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogSitAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -6 }, { &gDogSitAnim, 1.0f, 0, -1, ANIMMODE_LOOP_PARTIAL, -6 }, + { &gDogLyingDownAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -6 }, { &gDogLyingDownLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogLyingDownAnim, 1.0f, 0, 27, ANIMMODE_ONCE, -6 }, { &gDogLyingDownAnim, 1.0f, 28, -1, ANIMMODE_ONCE, -6 }, + { &gDogLyingDownAnim, 1.0f, 54, 54, ANIMMODE_ONCE, -6 }, { &gDogWalkAnim, -1.5f, -1, 0, ANIMMODE_LOOP, -6 }, + { &gDogJumpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogLongJumpAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gDogJump2Anim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 }, }; static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP), }; -void func_80989140(SkelAnime* skelAnime, ActorAnimationEntryS arg1[], s32 arg2) { +void func_80989140(SkelAnime* skelAnime, AnimationInfoS arg1[], s32 arg2) { f32 frameCount; arg1 += arg2; if (arg1->frameCount < 0) { - frameCount = Animation_GetLastFrame(arg1->animationSeg); + frameCount = Animation_GetLastFrame(arg1->animation); } else { frameCount = arg1->frameCount; } - Animation_Change(skelAnime, arg1->animationSeg, arg1->playbackSpeed + (BREG(88) * 0.1f), arg1->frame, frameCount, - arg1->mode, arg1->transitionRate); + Animation_Change(skelAnime, arg1->animation, arg1->playSpeed + (BREG(88) * 0.1f), arg1->startFrame, frameCount, + arg1->mode, arg1->morphFrames); } void func_80989204(EnDg* this, GlobalContext* globalCtx) { @@ -198,15 +202,15 @@ void func_8098933C(EnDg* this, Vec3f* arg1) { sp20 = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); sp1C = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); - __sinf(0.0f); - __cosf(0.0f); + sinf(0.0f); + cosf(0.0f); arg1->x = -Math_Acot2F(1.0f, -sp1C * sp20); arg1->z = Math_Acot2F(1.0f, -sp24 * sp20); } } s32 func_80989418(EnDg* this, Path* arg1, s32 arg2) { - Vec3s* sp5C = (Vec3s*)Lib_SegmentedToVirtual(arg1->points); + Vec3s* sp5C = Lib_SegmentedToVirtual(arg1->points); s32 count = arg1->count; s32 idx = arg2; s32 sp50 = false; @@ -221,7 +225,7 @@ s32 func_80989418(EnDg* this, Path* arg1, s32 arg2) { if (idx == 0) { phi_f12 = sp5C[1].x - sp5C[0].x; phi_f14 = sp5C[1].z - sp5C[0].z; - } else if ((idx + 1) == ((void)0, count)) { + } else if (idx == count - 1) { phi_f12 = sp5C[count - 1].x - sp5C[count - 2].x; phi_f14 = sp5C[count - 1].z - sp5C[count - 2].z; } else { @@ -229,7 +233,7 @@ s32 func_80989418(EnDg* this, Path* arg1, s32 arg2) { phi_f14 = sp5C[idx + 1].z - sp5C[idx - 1].z; } - func_8017B7F8(&sp30, func_80086B30(phi_f12, phi_f14) * 10430.378f, &sp44, &sp40, &sp3C); + 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; } @@ -243,7 +247,7 @@ s16 func_809895B4(Path* path, s32 idx, Vec3f* pos, f32* distSQ) { f32 diffZ; if (path != NULL) { - points = (Vec3s*)Lib_SegmentedToVirtual(path->points); + points = Lib_SegmentedToVirtual(path->points); points = &points[idx]; diffX = points->x - pos->x; diffZ = points->z - pos->z; @@ -261,29 +265,29 @@ void func_80989674(EnDg* this, GlobalContext* globalCtx) { s16 phi_a1; f32 sp30; - if (this->unk_1DC != NULL) { - phi_a1 = func_809895B4(this->unk_1DC, this->unk_1E0, &this->actor.world.pos, &sp30); + if (this->path != NULL) { + phi_a1 = func_809895B4(this->path, this->unk_1E0, &this->actor.world.pos, &sp30); if (this->actor.bgCheckFlags & 8) { phi_a1 = this->actor.wallYaw; } Math_SmoothStepToS(&this->actor.world.rot.y, phi_a1, 4, 0x3E8, 1); this->actor.shape.rot.y = this->actor.world.rot.y; - if (func_80989418(this, this->unk_1DC, this->unk_1E0)) { - if (this->unk_1E0 >= (this->unk_1DC->count - 1)) { + if (func_80989418(this, this->path, this->unk_1E0)) { + if (this->unk_1E0 >= (this->path->count - 1)) { this->unk_1E0 = 0; } else { this->unk_1E0++; } } - if ((this->unk_286 == 21) || ((this->unk_286 == 20) && (globalCtx->sceneNum == SCENE_OMOYA))) { + if ((this->index == 21) || ((this->index == 20) && (globalCtx->sceneNum == SCENE_OMOYA))) { Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f); - } else if (this->unk_286 == 20) { + } else if (this->index == 20) { Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f); } else if (globalCtx->sceneNum == SCENE_CLOCKTOWER) { Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f); - } else if (D_8098C2A8[this->unk_286].unk_04 & 0x11) { + } else if (sRacetrackDogInfo[this->index].textId & 0x11) { Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f); } else { Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f); @@ -298,53 +302,53 @@ void func_80989864(EnDg* this, GlobalContext* globalCtx) { s16 mod = (this->actor.speedXZ > 6.0f) ? 2 : 3; Vec3f sp38; - if (((this->unk_286 + frame) % mod) == 0) { + if (((this->index + frame) % mod) == 0) { sp38.x = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.x; sp38.y = this->actor.world.pos.y; sp38.z = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.z; - func_800BBDAC(globalCtx, &this->actor, &sp38, 10.0f, 0, 2.0f, 300, 0, 1); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &sp38, 10.0f, 0, 2.0f, 300, 0, 1); } } void func_80989974(EnDg* this) { if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 7.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MONKEY_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK); } } void func_809899C8(EnDg* this, f32 arg1) { if (Animation_OnFrame(&this->skelAnime, arg1)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK); } } void func_80989A08(EnDg* this, f32 arg1) { if (Animation_OnFrame(&this->skelAnime, arg1)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK); } } void func_80989A48(EnDg* this) { if (Animation_OnFrame(&this->skelAnime, 23.0f) || Animation_OnFrame(&this->skelAnime, 28.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_WHINE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_WHINE); } } void func_80989A9C(EnDg* this, f32 arg1) { if (Animation_OnFrame(&this->skelAnime, arg1)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); } } void func_80989ADC(EnDg* this, GlobalContext* globalCtx) { if (!(this->actor.bgCheckFlags & 0x20)) { - if ((this->unk_286 == 21) || ((this->unk_286 == 20) && (globalCtx->sceneNum == SCENE_OMOYA))) { + if ((this->index == 21) || ((this->index == 20) && (globalCtx->sceneNum == SCENE_OMOYA))) { func_80989140(&this->skelAnime, sAnimations, 1); - } else if (this->unk_286 == 20) { + } else if (this->index == 20) { func_80989140(&this->skelAnime, sAnimations, 2); } else if (globalCtx->sceneNum == SCENE_CLOCKTOWER) { func_80989140(&this->skelAnime, sAnimations, 2); - } else if (D_8098C2A8[this->unk_286].unk_04 & 0x11) { + } else if (sRacetrackDogInfo[this->index].textId & 0x11) { func_80989140(&this->skelAnime, sAnimations, 1); } else { func_80989140(&this->skelAnime, sAnimations, 2); @@ -354,93 +358,94 @@ void func_80989ADC(EnDg* this, GlobalContext* globalCtx) { } void func_80989BF8(EnDg* this) { - if (this->unk_286 < 14) { - if (this->unk_286 % 2) { - D_8098C2A8[this->unk_286].unk_04 = - 0x3538 + ((gSaveContext.weekEventReg[42 + (this->unk_286 / 2)] & 0xF0) >> 4); + if (this->index < 14) { + if (this->index % 2) { + sRacetrackDogInfo[this->index].textId = + 0x3538 + ((gSaveContext.save.weekEventReg[42 + (this->index / 2)] & (0x10 | 0x20 | 0x40 | 0x80)) >> 4); } else { - D_8098C2A8[this->unk_286].unk_04 = 0x3538 + (gSaveContext.weekEventReg[42 + (this->unk_286 / 2)] & 0xF); + sRacetrackDogInfo[this->index].textId = + 0x3538 + (gSaveContext.save.weekEventReg[42 + (this->index / 2)] & (1 | 2 | 4 | 8)); } } else { Actor_MarkForDeath(&this->actor); } - if ((D_8098C2A8[this->unk_286].unk_04 >= 0x3547) || (D_8098C2A8[this->unk_286].unk_04 < 0x3538)) { - D_8098C2A8[this->unk_286].unk_04 = 0x353E; + if ((sRacetrackDogInfo[this->index].textId >= 0x3547) || (sRacetrackDogInfo[this->index].textId < 0x3538)) { + sRacetrackDogInfo[this->index].textId = 0x353E; } - if (D_8098C2A8[this->unk_286].unk_04 == 0x353D) { - D_8098C2A8[this->unk_286].unk_04 = 0x3538; + if (sRacetrackDogInfo[this->index].textId == 0x353D) { + sRacetrackDogInfo[this->index].textId = 0x3538; } } void func_80989D38(EnDg* this, GlobalContext* globalCtx) { - if (this->unk_286 == 21) { + if (this->index == 21) { if (CURRENT_DAY == 1) { - func_801518B0(globalCtx, 0x91C, NULL); + Message_StartTextbox(globalCtx, 0x91C, NULL); } else { - func_801518B0(globalCtx, 0x91E, NULL); + Message_StartTextbox(globalCtx, 0x91E, NULL); } - } else if ((this->unk_286 >= 0) && (this->unk_286 < 14)) { - func_801518B0(globalCtx, D_8098C2A8[this->unk_286].unk_04, NULL); - } else if (this->unk_286 == 20) { - func_801518B0(globalCtx, 0x353D, NULL); + } else if ((this->index >= 0) && (this->index < 14)) { + Message_StartTextbox(globalCtx, sRacetrackDogInfo[this->index].textId, NULL); + } else if (this->index == 20) { + Message_StartTextbox(globalCtx, 0x353D, NULL); } else { - func_801518B0(globalCtx, 0x627, NULL); + Message_StartTextbox(globalCtx, 0x627, NULL); } } void func_80989E18(EnDg* this, GlobalContext* globalCtx) { - D_8098C2A8_s* temp; + RacetrackDogInfo* temp; if ((D_8098C2A0 != 0) && !(this->unk_280 & 1)) { - this->actor.flags |= 0x8000000; + this->actor.flags |= ACTOR_FLAG_8000000; this->unk_280 |= 1; } else if ((D_8098C2A0 == 0) && (this->unk_280 & 1)) { - this->actor.flags &= ~0x8000000; + this->actor.flags &= ~ACTOR_FLAG_8000000; this->unk_280 &= ~1; } if (Actor_HasParent(&this->actor, globalCtx)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK); this->unk_290 = 1; - D_8098C2FC = D_8098C2A8[this->unk_286]; + sSelectedRacetrackDogInfo = sRacetrackDogInfo[this->index]; if (D_8098C2A0 == 0) { - this->actor.flags |= 0x8000000; + this->actor.flags |= ACTOR_FLAG_8000000; D_8098C2A0 = 1; this->unk_280 |= 1; } func_80989140(&this->skelAnime, sAnimations, 5); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.speedXZ = 0.0f; - if (Player_GetMask(globalCtx) == PLAYER_MASK_MASK_OF_TRUTH) { - this->actor.flags |= 0x10000; + if (Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) { + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 100.0f); this->actionFunc = func_8098BBEC; } else { this->actionFunc = func_8098BA64; } } else { - func_800B8BB0(&this->actor, globalCtx); + Actor_LiftActor(&this->actor, globalCtx); } } s32 func_80989FC8(GlobalContext* globalCtx) { - EnDg* enemy = (EnDg*)globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first; + EnDg* enemy = (EnDg*)globalCtx->actorCtx.actorLists[ACTORCAT_ENEMY].first; f32 minDist = 9999.0f; f32 dist; while (enemy != NULL) { if (enemy->actor.id == ACTOR_EN_DG) { if (enemy->actor.isTargeted) { - D_8098C2A4.unk_00 = enemy->unk_286; + D_8098C2A4.unk_00 = enemy->index; return true; } dist = enemy->actor.xzDistToPlayer; if (dist < minDist) { - D_8098C2A4.unk_00 = enemy->unk_286; + D_8098C2A4.unk_00 = enemy->index; minDist = dist; } } @@ -462,7 +467,7 @@ void func_8098A064(EnDg* this, GlobalContext* globalCtx) { func_80989FC8(globalCtx); } - if (this->unk_286 == D_8098C2A4.unk_00) { + if (this->index == D_8098C2A4.unk_00) { if (!(this->unk_280 & 0x20)) { this->unk_280 |= 0x20; func_80989140(&this->skelAnime, sAnimations, 1); @@ -470,11 +475,11 @@ void func_8098A064(EnDg* this, GlobalContext* globalCtx) { } else if ((this->actionFunc == func_8098B004) || (this->actionFunc == func_8098AB48)) { if (DECR(this->unk_292) == 0) { this->unk_292 = 10; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK); } } } - } else if (this->unk_286 == D_8098C2A4.unk_00) { + } else if (this->index == D_8098C2A4.unk_00) { this->unk_280 &= ~0x20; D_8098C2A4.unk_00 = 99; func_80989ADC(this, globalCtx); @@ -567,7 +572,7 @@ void func_8098A468(EnDg* this, GlobalContext* globalCtx) { this->actor.velocity.y = 0.0f; this->actor.gravity = -3.0f; func_80989674(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (player->transformation == PLAYER_FORM_HUMAN) { func_80989E18(this, globalCtx); } @@ -619,7 +624,7 @@ void func_8098A618(EnDg* this, GlobalContext* globalCtx) { } this->actor.world.rot.y = this->actor.shape.rot.y; Math_ApproachF(&this->actor.speedXZ, -1.5f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } func_80989974(this); @@ -655,12 +660,12 @@ void func_8098A70C(EnDg* this, GlobalContext* globalCtx) { this->actor.speedXZ = 7.0f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_80989974(this); if (Animation_OnFrame(&this->skelAnime, 3.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_CRY); } else if (Animation_OnFrame(&this->skelAnime, 6.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MONKEY_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK); } } @@ -698,7 +703,7 @@ void func_8098A938(EnDg* this, GlobalContext* globalCtx) { this->actionFunc = func_8098AC34; } else { func_80989140(&this->skelAnime, sAnimations, 11); - sAnimations[11].playbackSpeed = -1.0f; + sAnimations[11].playSpeed = -1.0f; this->actionFunc = func_8098B198; } } @@ -707,7 +712,7 @@ void func_8098A938(EnDg* this, GlobalContext* globalCtx) { Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 1.0f); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_80989974(this); func_80989A08(this, 5.0f); } @@ -715,7 +720,7 @@ void func_8098A938(EnDg* this, GlobalContext* globalCtx) { void func_8098AAAC(EnDg* this, GlobalContext* globalCtx) { this->unk_280 &= ~8; Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.1f, 0.5f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (DECR(this->unk_28E) == 0) { this->unk_28E = 20; this->actionFunc = func_8098A938; @@ -773,7 +778,7 @@ void func_8098AC34(EnDg* this, GlobalContext* globalCtx) { if (sp26 < 9) { if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - sAnimations[14].playbackSpeed = randPlusMinusPoint5Scaled(1.0f) + 3.0f; + sAnimations[14].playSpeed = randPlusMinusPoint5Scaled(1.0f) + 3.0f; } func_80989864(this, globalCtx); } else { @@ -781,7 +786,7 @@ void func_8098AC34(EnDg* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 9.0f)) { f32 rand = randPlusMinusPoint5Scaled(1.5f); - sAnimations[14].playbackSpeed = 1.2f; + sAnimations[14].playSpeed = 1.2f; this->actor.velocity.y = 2.0f * rand + 3.0f; this->actor.speedXZ = 8.0f + rand; } else if (sp26 >= 0x15) { @@ -790,7 +795,7 @@ void func_8098AC34(EnDg* this, GlobalContext* globalCtx) { if (sp26 >= 0x18) { func_80989864(this, globalCtx); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } func_80989A9C(this, 10.0f); @@ -808,7 +813,7 @@ void func_8098AE58(EnDg* this, GlobalContext* globalCtx) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00); this->actor.world.rot.y = this->actor.shape.rot.y; Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } func_80989974(this); @@ -818,7 +823,7 @@ void func_8098AE58(EnDg* this, GlobalContext* globalCtx) { void func_8098AF44(EnDg* this, GlobalContext* globalCtx) { if (func_801A46F8() == 1) { this->unk_292 = 10; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_BARK); this->actionFunc = func_8098B004; } } @@ -829,7 +834,7 @@ void func_8098AF98(EnDg* this, GlobalContext* globalCtx) { this->actionFunc = func_8098A468; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_809899C8(this, 3.0f); } @@ -838,7 +843,7 @@ void func_8098B004(EnDg* this, GlobalContext* globalCtx) { this->actor.velocity.y = 0.0f; this->actor.gravity = -3.0f; - if ((this->actor.xzDistToPlayer < 60.0f) && (this->collider.base.ocFlags1 & 2)) { + if ((this->actor.xzDistToPlayer < 60.0f) && (this->collider.base.ocFlags1 & OC1_HIT)) { this->actor.shape.rot.y += 0x71C; } else { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 0xC00); @@ -859,7 +864,7 @@ void func_8098B004(EnDg* this, GlobalContext* globalCtx) { } func_8098A064(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_80989974(this); if (!(this->unk_280 & 0x20)) { func_809899C8(this, 3.0f); @@ -881,7 +886,7 @@ void func_8098B198(EnDg* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.shape.rot.y; Math_ApproachF(&this->actor.speedXZ, -1.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_80989974(this); func_80989A9C(this, 4.0f); } @@ -901,11 +906,11 @@ void func_8098B28C(EnDg* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.shape.rot.y; Math_ApproachF(&this->actor.speedXZ, -2.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } func_80989974(this); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); } void func_8098B390(EnDg* this, GlobalContext* globalCtx) { @@ -928,56 +933,56 @@ void func_8098B464(EnDg* this, GlobalContext* globalCtx) { Vec3f sp2C; sp2C.x = this->actor.world.pos.x; - sp2C.y = this->actor.world.pos.y + this->actor.yDistToWater; + sp2C.y = this->actor.world.pos.y + this->actor.depthInWater; sp2C.z = this->actor.world.pos.z + 20.0f; EffectSsGSplash_Spawn(globalCtx, &sp2C, NULL, NULL, 0, 800); EffectSsGRipple_Spawn(globalCtx, &sp2C, 100, 500, 30); - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { this->actor.gravity = 0.0f; this->actor.velocity.y = -3.0f; this->unk_284 = 10; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); this->actionFunc = func_8098B560; } Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_8098B560(EnDg* this, GlobalContext* globalCtx) { Vec3f sp54; - Vec3f sp48; + Vec3f pos; s16 sp46 = 0; - WaterBox* sp40; - f32 sp3C; - s32 sp38; + WaterBox* waterBox; + f32 waterSurface; + CollisionPoly* poly; f32 sp34; sp54.x = this->actor.world.pos.x; - sp54.y = this->actor.world.pos.y + this->actor.yDistToWater; + sp54.y = this->actor.world.pos.y + this->actor.depthInWater; sp54.z = this->actor.world.pos.z + 20.0f; - sp48.x = (Math_SinS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.x; - sp48.y = this->actor.home.pos.y + 100.0f; - sp48.z = (Math_CosS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.z; + pos.x = (Math_SinS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.x; + pos.y = this->actor.home.pos.y + 100.0f; + pos.z = (Math_CosS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.z; if (DECR(this->unk_284) == 0) { if (!(this->unk_280 & 4)) { this->unk_280 |= 4; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_OUT_OF_WATER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER); } this->unk_284 = 5; EffectSsGRipple_Spawn(globalCtx, &sp54, 100, 500, 30); } - if (this->actor.yDistToWater > 15.0f) { + if (this->actor.depthInWater > 15.0f) { this->actor.velocity.y = 0.5f; - } else if (this->actor.yDistToWater < 10.0f) { + } else if (this->actor.depthInWater < 10.0f) { this->actor.velocity.y = -0.5f; } - sp34 = func_800C4000(globalCtx, &globalCtx->colCtx, &sp38, &sp48); + sp34 = BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos); if (this->actor.bgCheckFlags & 8) { - if (!func_800CA1AC(globalCtx, &globalCtx->colCtx, sp48.x, sp48.z, &sp3C, &sp40)) { + if (!WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, pos.x, pos.z, &waterSurface, &waterBox)) { if (sp34 > -100.0f) { this->unk_280 &= ~4; this->actionFunc = func_8098B88C; @@ -985,7 +990,7 @@ void func_8098B560(EnDg* this, GlobalContext* globalCtx) { sp46 = this->actor.wallYaw; } } else if (sp34 > -100.0f) { - if (sp3C < sp34) { + if (waterSurface < sp34) { this->unk_280 &= ~4; this->actionFunc = func_8098B88C; } else { @@ -999,7 +1004,7 @@ void func_8098B560(EnDg* this, GlobalContext* globalCtx) { this->unk_280 &= ~4; this->unk_28C = 8; this->unk_282 = Rand_S16Offset(60, 60); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_OUT_OF_WATER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER); func_80989140(&this->skelAnime, sAnimations, 2); Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f); this->actionFunc = func_8098A468; @@ -1008,14 +1013,14 @@ void func_8098B560(EnDg* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.world.rot.y, sp46, 4, 0x3E8, 1); this->actor.shape.rot.y = this->actor.world.rot.y; Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_8098B88C(EnDg* this, GlobalContext* globalCtx) { Vec3f sp34; sp34.x = this->actor.world.pos.x; - sp34.y = this->actor.world.pos.y + this->actor.yDistToWater; + sp34.y = this->actor.world.pos.y + this->actor.depthInWater; sp34.z = this->actor.world.pos.z + 20.0f; if (DECR(this->unk_284) == 0) { @@ -1023,9 +1028,9 @@ void func_8098B88C(EnDg* this, GlobalContext* globalCtx) { EffectSsGRipple_Spawn(globalCtx, &sp34, 100, 500, 30); } - if (this->actor.yDistToWater > 15.0f) { + if (this->actor.depthInWater > 15.0f) { this->actor.velocity.y = 1.0f; - } else if (this->actor.yDistToWater < 10.0f) { + } else if (this->actor.depthInWater < 10.0f) { this->actor.velocity.y = -1.0f; } @@ -1040,7 +1045,7 @@ void func_8098B88C(EnDg* this, GlobalContext* globalCtx) { this->actor.velocity.y = 10.0f; this->actor.gravity = -3.0f; this->unk_282 = Rand_S16Offset(60, 60); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_OUT_OF_WATER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER); func_80989140(&this->skelAnime, sAnimations, 2); this->actionFunc = func_8098A468; Math_ApproachF(&this->actor.speedXZ, 3.5f, 0.2f, 1.0f); @@ -1048,22 +1053,22 @@ void func_8098B88C(EnDg* this, GlobalContext* globalCtx) { Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_8098BA64(EnDg* this, GlobalContext* globalCtx) { if (Actor_HasNoParent(&this->actor, globalCtx)) { this->unk_290 = 2; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; if (D_8098C2A0 != 0) { - this->actor.flags &= ~0x8000000; + this->actor.flags &= ~ACTOR_FLAG_8000000; D_8098C2A0 = 0; this->unk_280 &= ~1; } - this->unk_288 = -1; - D_8098C2FC.unk_02 = this->unk_288; + this->selectedDogIndex = -1; + sSelectedRacetrackDogInfo.index = this->selectedDogIndex; this->unk_28A = 100; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); this->unk_280 |= 0x10; this->actionFunc = func_8098BB10; } @@ -1075,7 +1080,7 @@ void func_8098BB10(EnDg* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 1) { if (this->unk_280 & 0x10) { this->unk_280 &= ~0x10; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MONKEY_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK); } this->actor.speedXZ = 0.0f; @@ -1091,12 +1096,12 @@ void func_8098BB10(EnDg* this, GlobalContext* globalCtx) { this->actionFunc = func_8098A468; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_8098BBEC(EnDg* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; func_80989D38(this, globalCtx); this->actionFunc = func_8098BC54; } else { @@ -1105,7 +1110,7 @@ void func_8098BBEC(EnDg* this, GlobalContext* globalCtx) { } void func_8098BC54(EnDg* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 2) { + if (Message_GetState(&globalCtx->msgCtx) == 2) { func_80989140(&this->skelAnime, sAnimations, 0); this->actionFunc = func_8098BA64; } @@ -1115,13 +1120,13 @@ void EnDg_Init(Actor* thisx, GlobalContext* globalCtx) { EnDg* this = THIS; s32 pad; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060080F0, NULL, this->jointTable, this->morphTable, 13); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gDogSkel, NULL, this->jointTable, this->morphTable, DOG_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); Actor_ProcessInitChain(&this->actor, sInitChain); - this->unk_1DC = func_8013D648(globalCtx, ENDG_GET_FC00(&this->actor), 0x3F); + this->path = SubS_GetPathByIndex(globalCtx, ENDG_GET_PATH(&this->actor), 0x3F); Actor_SetScale(&this->actor, 0.0075f); this->actor.targetMode = 1; this->actor.gravity = -3.0f; @@ -1129,7 +1134,7 @@ void EnDg_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_280 = 0; this->unk_28E = 20; this->unk_284 = 10; - this->unk_286 = ENDG_GET_3E0(&this->actor); + this->index = ENDG_GET_INDEX(&this->actor); this->unk_28C = 0; this->unk_290 = 0; if (globalCtx->sceneNum == SCENE_F01_B) { @@ -1151,7 +1156,7 @@ void EnDg_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; Vec3f sp28 = { 0.0f, 0.0f, 0.0f }; - this->unk_288 = D_8098C2FC.unk_02; + this->selectedDogIndex = sSelectedRacetrackDogInfo.index; if (!(player->stateFlags1 & 0x20) || (globalCtx->sceneNum != SCENE_CLOCKTOWER)) { if (func_8098A1B4(this, globalCtx)) { func_8098A234(this, globalCtx); @@ -1174,20 +1179,20 @@ void EnDg_Update(Actor* thisx, GlobalContext* globalCtx) { } } -s32 func_8098BFB8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { - return 0; +s32 EnDg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; } -void func_8098BFD4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDg* this = THIS; Vec3f sp20 = { 0.0f, 20.0f, 0.0f }; - if (limbIndex == 5) { + if (limbIndex == DOG_LIMB_HEAD) { if (this->actionFunc == func_8098BBEC) { sp20.x = 5000.0f; - Matrix_MultiplyVector3fByState(&sp20, &this->actor.focus.pos); + Matrix_MultVec3f(&sp20, &this->actor.focus.pos); } else if (this->actionFunc != func_8098BC54) { - Matrix_MultiplyVector3fByState(&sp20, &this->actor.focus.pos); + Matrix_MultVec3f(&sp20, &this->actor.focus.pos); } } } @@ -1201,37 +1206,43 @@ void EnDg_Draw(Actor* thisx, GlobalContext* globalCtx) { gDPPipeSync(POLY_OPA_DISP++); - switch (D_8098C2A8[this->unk_286].unk_00) { - case 3: + switch (sRacetrackDogInfo[this->index].color) { + case DOG_COLOR_BEIGE: gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 200, 0); break; - case 1: + + case DOG_COLOR_WHITE: gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 0); break; - case 5: + + case DOG_COLOR_BLUE: gDPSetEnvColor(POLY_OPA_DISP++, 79, 79, 143, 0); break; - case 6: + + case DOG_COLOR_GOLD: gDPSetEnvColor(POLY_OPA_DISP++, 255, 207, 47, 0); break; - case 4: + + case DOG_COLOR_BROWN: gDPSetEnvColor(POLY_OPA_DISP++, 143, 79, 47, 0); break; - case 2: + + case DOG_COLOR_GRAY: gDPSetEnvColor(POLY_OPA_DISP++, 143, 143, 143, 0); break; + default: gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 200, 0); break; } - Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); - Matrix_RotateStateAroundXAxis(this->unk_294.x); - Matrix_InsertZRotation_f(this->unk_294.z, MTXMODE_APPLY); - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateXFApply(this->unk_294.x); + Matrix_RotateZF(this->unk_294.z, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - func_8098BFB8, func_8098BFD4, &this->actor); + EnDg_OverrideLimbDraw, EnDg_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Dg/z_en_dg.h b/src/overlays/actors/ovl_En_Dg/z_en_dg.h index cfb474b18..ca85d4a4d 100644 --- a/src/overlays/actors/ovl_En_Dg/z_en_dg.h +++ b/src/overlays/actors/ovl_En_Dg/z_en_dg.h @@ -2,13 +2,24 @@ #define Z_EN_DG_H #include "global.h" +#include "objects/object_dog/object_dog.h" + +typedef enum { + /* 0 */ DOG_COLOR_DEFAULT, // ends up just being treated as beige + /* 1 */ DOG_COLOR_WHITE, + /* 2 */ DOG_COLOR_GRAY, + /* 3 */ DOG_COLOR_BEIGE, + /* 4 */ DOG_COLOR_BROWN, + /* 5 */ DOG_COLOR_BLUE, + /* 6 */ DOG_COLOR_GOLD, +} DogColors; struct EnDg; typedef void (*EnDgActionFunc)(struct EnDg*, GlobalContext*); -#define ENDG_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) -#define ENDG_GET_3E0(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENDG_GET_INDEX(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENDG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) typedef struct EnDg { /* 0x000 */ Actor actor; @@ -16,15 +27,15 @@ typedef struct EnDg { /* 0x148 */ UNK_TYPE1 unk_148[0x4]; /* 0x14C */ SkelAnime skelAnime; /* 0x190 */ ColliderCylinder collider; - /* 0x1DC */ Path* unk_1DC; + /* 0x1DC */ Path* path; /* 0x1E0 */ s32 unk_1E0; - /* 0x1E4 */ Vec3s jointTable[13]; - /* 0x232 */ Vec3s morphTable[13]; + /* 0x1E4 */ Vec3s jointTable[DOG_LIMB_MAX]; + /* 0x232 */ Vec3s morphTable[DOG_LIMB_MAX]; /* 0x280 */ u16 unk_280; /* 0x282 */ s16 unk_282; /* 0x284 */ s16 unk_284; - /* 0x286 */ s16 unk_286; - /* 0x288 */ s16 unk_288; + /* 0x286 */ s16 index; + /* 0x288 */ s16 selectedDogIndex; /* 0x28A */ s16 unk_28A; /* 0x28C */ s16 unk_28C; /* 0x28E */ s16 unk_28E; 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 8670600fe..d093f29ff 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c @@ -5,8 +5,9 @@ */ #include "z_en_dinofos.h" +#include "objects/object_dinofos/object_dinofos.h" -#define FLAGS 0x00000435 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_400) #define THIS ((EnDinofos*)thisx) @@ -56,25 +57,6 @@ void func_8089C398(EnDinofos* this); void func_8089C164(EnDinofos* this); void func_8089C244(EnDinofos* this); -extern FlexSkeletonHeader D_06009570; -extern AnimationHeader D_06002E40; -extern AnimationHeader D_060025B4; -extern AnimationHeader D_06000580; -extern AnimationHeader D_06001CCC; -extern AnimationHeader D_0600ABD0; -extern AnimationHeader D_0600D62C; -extern AnimationHeader D_06001040; -extern AnimationHeader D_060013C0; -extern AnimationHeader D_060017B8; -extern AnimationHeader D_0600C974; -extern AnimationHeader D_06009B70; -extern AnimationHeader D_06000AF0; -extern AnimationHeader D_0600D21C; -extern Gfx D_06008E30[]; -extern Gfx D_06009030[]; -extern Gfx D_06009230[]; -extern Gfx D_06009030[]; - const ActorInit En_Dinofos_InitVars = { ACTOR_EN_DINOFOS, ACTORCAT_ENEMY, @@ -259,11 +241,11 @@ static DamageTable sDamageTable = { static CollisionCheckInfoInit sColChkInfoInit = { 4, 40, 100, 80 }; -static Gfx* D_8089E33C[] = { - D_06008E30, - D_06009030, - D_06009230, - D_06009030, +static TexturePtr D_8089E33C[] = { + object_dinofos_Tex_008E30, + object_dinofos_Tex_009030, + object_dinofos_Tex_009230, + object_dinofos_Tex_009030, }; static s16 D_8089E34C = -1; @@ -278,7 +260,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 }, }; @@ -287,17 +269,18 @@ void EnDinofos_Init(Actor* thisx, GlobalContext* globalCtx) { ColliderJntSphElementDim* dim; 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); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawFeet, 90.0f); + 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); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06009570, &D_06002E40, this->jointTable, this->morphTable, 21); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dinofos_Skel_009570, &object_dinofos_Anim_002E40, + this->jointTable, this->morphTable, 21); if (D_8089E364 == 0) { for (i = 0; i < ARRAY_COUNT(D_8089E33C); i++) { - D_8089E33C[i] = (Gfx*)Lib_SegmentedToVirtual(D_8089E33C[i]); + D_8089E33C[i] = Lib_SegmentedToVirtual(D_8089E33C[i]); } D_8089E364 = 1; } @@ -312,7 +295,7 @@ void EnDinofos_Init(Actor* thisx, GlobalContext* globalCtx) { if (thisx->cutscene == -1) { func_8089B7B0(this); } else { - this->actor.flags |= 0x100000; + this->actor.flags |= ACTOR_FLAG_100000; this->actor.gravity = 0.0f; this->actor.velocity.y = 0.0f; D_8089E34C = thisx->cutscene; @@ -353,7 +336,7 @@ s32 func_8089A968(EnDinofos* this) { void func_8089A9B0(EnDinofos* this, GlobalContext* globalCtx) { if (func_8089A968(this)) { if (this->actor.xzDistToPlayer < 100.0f) { - if (!func_800BC5EC(globalCtx, &this->actor) && + if (!Actor_OtherIsTargeted(globalCtx, &this->actor) && (((this->actionFunc != func_8089C56C) && (Rand_ZeroOne() > 0.35f)) || ((this->actionFunc == func_8089C56C) && (Rand_ZeroOne() > 0.8f)))) { func_8089C4F8(this); @@ -380,11 +363,11 @@ void func_8089A9B0(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089ABF4(EnDinofos* this, GlobalContext* globalCtx) { - if (this->camId != 0) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); + if (this->subCamId != CAM_ID_MAIN) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); - Play_CameraSetAtEye(globalCtx, 0, &camera->at, &camera->eye); - this->camId = 0; + Play_CameraSetAtEye(globalCtx, CAM_ID_MAIN, &subCam->at, &subCam->eye); + this->subCamId = CAM_ID_MAIN; ActorCutscene_Stop(this->actor.cutscene); if (this->actor.colChkInfo.health == 0) { func_800B724C(globalCtx, &this->actor, 6); @@ -393,23 +376,23 @@ void func_8089ABF4(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089AC70(EnDinofos* this) { - this->unk_28A = 10; - this->unk_2B4 = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.55f; this->colliderJntSph.base.colType = COLTYPE_HIT3; - this->unk_2B8 = 0.82500005f; - this->unk_2B0 = 1.0f; + this->drawDmgEffFrozenSteamScale = 0.82500005f; + this->drawDmgEffAlpha = 1.0f; this->unk_290 = 80; - this->actor.flags &= ~0x400; - func_800BCB70(&this->actor, 0x4000, 255, 0, 80); + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); } void func_8089ACEC(EnDinofos* this, GlobalContext* globalCtx) { - if (this->unk_28A == 10) { - this->unk_28A = 0; + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->colliderJntSph.base.colType = COLTYPE_HIT0; - this->unk_2B0 = 0.0f; - func_800BF7CC(globalCtx, &this->actor, this->unk_2D4, 12, 2, 0.3f, 0.2f); - this->actor.flags |= 0x400; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 12, 2, 0.3f, 0.2f); + this->actor.flags |= ACTOR_FLAG_400; } } @@ -436,7 +419,7 @@ s32 func_8089AE00(EnDinofos* this, GlobalContext* globalCtx) { temp_v1 = (Actor_YawBetweenActors(&this->actor, temp_v0) - this->actor.shape.rot.y) - this->unk_28E; if (ABS_ALT(temp_v1) < 0x3000) { func_8089D11C(this, temp_v1 + this->unk_28E); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WARAU); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WARAU); return true; } } @@ -446,7 +429,7 @@ s32 func_8089AE00(EnDinofos* this, GlobalContext* globalCtx) { temp_v1_2 = (Actor_YawBetweenActors(&this->actor, temp_v0) - this->actor.shape.rot.y) - this->unk_28E; if (ABS_ALT(temp_v1_2) < 0x3000) { func_8089C024(this, 1); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WARAU); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WARAU); return true; } } @@ -457,17 +440,17 @@ s32 func_8089AE00(EnDinofos* this, GlobalContext* globalCtx) { } if ((this->actor.xzDistToPlayer < 100.0f) && (player->swordState != 0) && this->actor.isTargeted && - (Rand_ZeroOne() < 0.5f) && func_8089A968(this) && Actor_IsLinkFacingActor(&this->actor, 0x2000, globalCtx)) { + (Rand_ZeroOne() < 0.5f) && func_8089A968(this) && Player_IsFacingActor(&this->actor, 0x2000, globalCtx)) { if (Rand_ZeroOne() < 0.5f) { func_8089C024(this, 2); } else { func_8089C024(this, 3); } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WARAU); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WARAU); return true; } - if ((gSaveContext.playerForm == PLAYER_FORM_GORON) && (player->actor.velocity.y < -5.0f) && + if ((gSaveContext.save.playerForm == PLAYER_FORM_GORON) && (player->actor.velocity.y < -5.0f) && (player->unk_AE7 == 1) && (this->unk_28B == 0)) { this->unk_28B = 1; for (i = 0; i < ARRAY_COUNT(this->colliderJntSphElement) - 3; i++) { @@ -479,13 +462,14 @@ s32 func_8089AE00(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089B100(EnDinofos* this, GlobalContext* globalCtx) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); Player* player = GET_PLAYER(globalCtx); Vec3f sp3C; - Animation_Change(&this->skelAnime, &D_06001CCC, 1.0f, Animation_GetLastFrame(&D_06001CCC), - Animation_GetLastFrame(&D_06001CCC), 2, 0.0f); - func_800BE33C(&camera->eye, &camera->at, &this->unk_29A, 1); + Animation_Change(&this->skelAnime, &object_dinofos_Anim_001CCC, 1.0f, + Animation_GetLastFrame(&object_dinofos_Anim_001CCC), + Animation_GetLastFrame(&object_dinofos_Anim_001CCC), 2, 0.0f); + func_800BE33C(&subCam->eye, &subCam->at, &this->unk_29A, true); Math_Vec3f_Diff(&this->actor.world.pos, &player->actor.world.pos, &sp3C); this->unk_2BC.x = player->actor.world.pos.x + (0.4f * sp3C.x); this->unk_2BC.y = player->actor.world.pos.y + 5.0f; @@ -493,19 +477,19 @@ void func_8089B100(EnDinofos* this, GlobalContext* globalCtx) { this->unk_2C8.x = this->actor.world.pos.x; this->unk_2C8.y = this->actor.focus.pos.y - 400.0f; this->unk_2C8.z = this->actor.world.pos.z; - this->unk_2AC = Math_Vec3f_DistXYZ(&camera->eye, &this->unk_2BC) * 0.05f; - this->unk_2A8 = Math_Vec3f_DistXYZ(&camera->at, &this->unk_2C8) * 0.05f; + this->unk_2AC = Math_Vec3f_DistXYZ(&subCam->eye, &this->unk_2BC) * 0.05f; + this->unk_2A8 = Math_Vec3f_DistXYZ(&subCam->at, &this->unk_2C8) * 0.05f; this->unk_290 = 20; this->actionFunc = func_8089B288; } void func_8089B288(EnDinofos* this, GlobalContext* globalCtx) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); this->unk_290--; - Math_Vec3f_StepTo(&camera->eye, &this->unk_2BC, this->unk_2AC); - Math_Vec3f_StepTo(&camera->at, &this->unk_2C8, this->unk_2A8); - Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &camera->eye); + Math_Vec3f_StepTo(&subCam->eye, &this->unk_2BC, this->unk_2AC); + Math_Vec3f_StepTo(&subCam->at, &this->unk_2C8, this->unk_2A8); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCam->eye); if (this->unk_290 == 0) { func_8089B320(this); } @@ -513,7 +497,7 @@ void func_8089B288(EnDinofos* this, GlobalContext* globalCtx) { void func_8089B320(EnDinofos* this) { this->actor.gravity = -2.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_CRY); this->unk_2BC.x = (Math_SinS(this->actor.shape.rot.y - 0x0E00) * 86.0f) + this->actor.world.pos.x; this->unk_2BC.y = this->actor.floorHeight + 6.0f; this->unk_2BC.z = (Math_CosS(this->actor.shape.rot.y - 0x0E00) * 86.0f) + this->actor.world.pos.z; @@ -522,24 +506,24 @@ void func_8089B320(EnDinofos* this) { } void func_8089B3D4(EnDinofos* this, GlobalContext* globalCtx) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); - Vec3f sp28; + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamAt; - Math_Vec3f_StepTo(&camera->eye, &this->unk_2BC, 10.0f); + Math_Vec3f_StepTo(&subCam->eye, &this->unk_2BC, 10.0f); this->unk_290++; if (this->unk_290 == 10) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); } - sp28.x = this->actor.world.pos.x; - sp28.z = this->actor.world.pos.z; - if (this->actor.focus.pos.y <= camera->at.y) { - sp28.y = this->actor.focus.pos.y; + subCamAt.x = this->actor.world.pos.x; + subCamAt.z = this->actor.world.pos.z; + if (this->actor.focus.pos.y <= subCam->at.y) { + subCamAt.y = this->actor.focus.pos.y; } else { - sp28.y = camera->at.y; + subCamAt.y = subCam->at.y; } - Play_CameraSetAtEye(globalCtx, this->camId, &sp28, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCam->eye); if (this->actor.bgCheckFlags & 1) { func_8089B4A4(this); } @@ -547,40 +531,40 @@ void func_8089B3D4(EnDinofos* this, GlobalContext* globalCtx) { void func_8089B4A4(EnDinofos* this) { if (this->unk_290 < 10) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); } - Animation_PlayOnce(&this->skelAnime, &D_0600C974); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_00C974); this->unk_2BC.x = (Math_SinS(this->actor.shape.rot.y + 0x200) * 123.0f) + this->actor.world.pos.x; this->unk_2BC.y = this->actor.floorHeight + 11.0f; this->unk_2BC.z = (Math_CosS(this->actor.shape.rot.y + 0x200) * 123.0f) + this->actor.world.pos.z; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_BOMCHU_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOMCHU_WALK); this->unk_290 = 0; this->unk_292 = -1; this->actionFunc = func_8089B580; } void func_8089B580(EnDinofos* this, GlobalContext* globalCtx) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); this->unk_290++; if (this->unk_290 < 8) { - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, &subCam->eye); } if (this->skelAnime.curFrame > 35.0f) { if ((globalCtx->sceneNum == SCENE_MITURIN) && Animation_OnFrame(&this->skelAnime, 38.0f)) { - globalCtx->envCtx.unk_C3 = 11; + globalCtx->envCtx.lightSettingOverride = 11; } - Math_Vec3f_StepTo(&camera->eye, &this->unk_2BC, 10.0f); - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &camera->eye); + Math_Vec3f_StepTo(&subCam->eye, &this->unk_2BC, 10.0f); + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, &subCam->eye); if (this->skelAnime.curFrame <= 55.0f) { func_800B9010(&this->actor, NA_SE_EN_DODO_J_FIRE - SFX_FLAG); } } if ((globalCtx->sceneNum == SCENE_MITURIN) && Animation_OnFrame(&this->skelAnime, 55.0f)) { - globalCtx->envCtx.unk_C3 = 0xFF; + globalCtx->envCtx.lightSettingOverride = 0xFF; } if (SkelAnime_Update(&this->skelAnime)) { @@ -589,25 +573,25 @@ void func_8089B580(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089B6E8(EnDinofos* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06009B70, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dinofos_Anim_009B70, -3.0f); this->actionFunc = func_8089B72C; } void func_8089B72C(EnDinofos* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 2.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_ATTACK); } if (SkelAnime_Update(&this->skelAnime)) { func_8089ABF4(this, globalCtx); - this->actor.flags &= ~0x00100000; + this->actor.flags &= ~ACTOR_FLAG_100000; this->actor.cutscene = -1; func_8089B7B0(this); } } void func_8089B7B0(EnDinofos* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06002E40, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_dinofos_Anim_002E40, -4.0f); this->unk_290 = (s32)Rand_ZeroFloat(20.0f) + 40; this->unk_292 = 30; this->actor.speedXZ = 0.0f; @@ -635,8 +619,8 @@ void func_8089B8B0(EnDinofos* this, GlobalContext* globalCtx) { f32 phi_f0; if (this->actionFunc != func_8089B98C) { - Animation_MorphToLoop(&this->skelAnime, &D_06000580, -4.0f); - if (func_800BC5EC(globalCtx, &this->actor)) { + Animation_MorphToLoop(&this->skelAnime, &object_dinofos_Anim_000580, -4.0f); + if (Actor_OtherIsTargeted(globalCtx, &this->actor)) { phi_f0 = 170.0f; } else { phi_f0 = 70.0f; @@ -658,7 +642,7 @@ void func_8089B98C(EnDinofos* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (!func_8089AE00(this, globalCtx)) { - if (func_800BC5EC(globalCtx, &this->actor)) { + if (Actor_OtherIsTargeted(globalCtx, &this->actor)) { phi_f0 = 170.0f; } else { phi_f0 = 70.0f; @@ -683,14 +667,14 @@ void func_8089B98C(EnDinofos* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } } } void func_8089BAC0(EnDinofos* this) { if (this->actionFunc != func_8089BB60) { - Animation_MorphToLoop(&this->skelAnime, &D_06000580, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_dinofos_Anim_000580, -4.0f); this->actor.speedXZ = 0.0f; } if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y) > 0) { @@ -731,8 +715,8 @@ void func_8089BBB4(EnDinofos* this, GlobalContext* globalCtx) { if (this->actionFunc == func_8089D1E0) { this->skelAnime.playSpeed = this->actor.speedXZ * 0.166666671634f; } else { - Animation_Change(&this->skelAnime, &D_0600D62C, this->actor.speedXZ * 0.166666671634f, 0.0f, 0.0f, 0, - -4.0f); + Animation_Change(&this->skelAnime, &object_dinofos_Anim_00D62C, this->actor.speedXZ * 0.166666671634f, 0.0f, + 0.0f, 0, -4.0f); } this->actor.world.rot.y = BINANG_ADD(this->actor.shape.rot.y, 0x4000); @@ -782,7 +766,7 @@ void func_8089BD28(EnDinofos* this, GlobalContext* globalCtx) { } this->actor.world.rot.y = BINANG_ADD(this->actor.shape.rot.y, 0x4000); - if (func_800BC5EC(globalCtx, &this->actor)) { + if (Actor_OtherIsTargeted(globalCtx, &this->actor)) { sp2C = 100.0f; } @@ -804,17 +788,17 @@ void func_8089BD28(EnDinofos* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } } } void func_8089C024(EnDinofos* this, s32 arg1) { if (arg1 == 0) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001CCC, 2.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dinofos_Anim_001CCC, 2.0f); func_8089AD70(this); } else { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001CCC, -1.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dinofos_Anim_001CCC, -1.0f); if ((arg1 == 2) || (arg1 == 3)) { this->colliderJntSph.base.acFlags &= ~AC_ON; func_8089AD70(this); @@ -853,7 +837,7 @@ void func_8089C164(EnDinofos* this) { } this->actor.bgCheckFlags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_JUMP); this->actionFunc = func_8089C1F8; } @@ -868,7 +852,7 @@ void func_8089C244(EnDinofos* this) { this->actor.bgCheckFlags &= ~1; this->actor.speedXZ = 8.0f; this->actor.velocity.y = 16.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_JUMP); this->unk_290 = 0; this->unk_292 = -1; this->actionFunc = func_8089C2A8; @@ -878,10 +862,10 @@ void func_8089C2A8(EnDinofos* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->unk_290++; Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x1800); - if ((this->actor.velocity.y < 0.0f) && (this->skelAnime.animation == &D_06001CCC)) { + if ((this->actor.velocity.y < 0.0f) && (this->skelAnime.animation == &object_dinofos_Anim_001CCC)) { this->colliderQuad.base.atFlags |= AT_ON; this->colliderJntSph.base.acFlags |= AC_ON; - Animation_Change(&this->skelAnime, &D_060025B4, 1.0f, 7.0f, 13.0f, 2, -2.0f); + Animation_Change(&this->skelAnime, &object_dinofos_Anim_0025B4, 1.0f, 7.0f, 13.0f, 2, -2.0f); } if (this->actor.bgCheckFlags & 1) { @@ -892,9 +876,9 @@ void func_8089C2A8(EnDinofos* this, GlobalContext* globalCtx) { void func_8089C398(EnDinofos* this) { if (this->actionFunc != func_8089C2A8) { - Animation_PlayOnce(&this->skelAnime, &D_06000AF0); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_000AF0); } else { - this->skelAnime.endFrame = Animation_GetLastFrame(&D_060025B4); + this->skelAnime.endFrame = Animation_GetLastFrame(&object_dinofos_Anim_0025B4); } if (this->actor.speedXZ < 0.0f) { @@ -905,7 +889,7 @@ void func_8089C398(EnDinofos* this) { this->actor.speedXZ = 0.0f; func_8089AD70(this); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_BOMCHU_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOMCHU_WALK); this->actionFunc = func_8089C44C; } @@ -921,9 +905,9 @@ void func_8089C44C(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089C4F8(EnDinofos* this) { - Animation_PlayOnce(&this->skelAnime, &D_060025B4); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_0025B4); this->colliderQuad.base.atFlags &= ~AT_BOUNCED; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_CRY); this->unk_290 = 0; this->unk_292 = -1; this->actor.speedXZ = 0.0f; @@ -936,7 +920,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)) { @@ -945,14 +929,14 @@ void func_8089C56C(EnDinofos* this, GlobalContext* globalCtx) { } else if (Animation_OnFrame(&this->skelAnime, 13.0f)) { this->colliderQuad.base.atFlags &= ~AT_ON; } else if (Animation_OnFrame(&this->skelAnime, 11.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_ATTACK); } else if (this->skelAnime.curFrame < 7.0f) { func_8089AE00(this, globalCtx); } } void func_8089C690(EnDinofos* this) { - Animation_Change(&this->skelAnime, &D_060025B4, -1.0f, this->skelAnime.curFrame, 0.0f, 2, 0.0f); + Animation_Change(&this->skelAnime, &object_dinofos_Anim_0025B4, -1.0f, this->skelAnime.curFrame, 0.0f, 2, 0.0f); this->colliderQuad.base.atFlags &= ~(AT_ON | AT_BOUNCED); if (this->actionFunc != func_8089C2A8) { this->actor.world.rot.y = this->actor.shape.rot.y; @@ -1002,7 +986,7 @@ void func_8089C7B8(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089C87C(EnDinofos* this, s32 arg1) { - Animation_PlayOnce(&this->skelAnime, &D_0600D21C); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_00D21C); func_800BE5CC(&this->actor, &this->colliderJntSph, arg1); this->actor.shape.rot.y = BINANG_ROT180(this->actor.world.rot.y); this->actor.speedXZ = 10.0f; @@ -1010,9 +994,9 @@ void func_8089C87C(EnDinofos* this, s32 arg1) { this->actor.velocity.y = 0.0f; } this->unk_28E = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_DAMAGE); this->colliderJntSph.base.acFlags &= ~AC_ON; - func_800BCB70(&this->actor, 0x4000, 255, 0, 18); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 18); this->actionFunc = func_8089C938; } @@ -1035,7 +1019,7 @@ void func_8089C938(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089CA14(EnDinofos* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001040, -5.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dinofos_Anim_001040, -5.0f); this->colliderJntSph.base.acFlags |= AC_ON; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; @@ -1056,7 +1040,7 @@ void func_8089CB10(EnDinofos* this, GlobalContext* globalCtx) { s32 i; Sphere16* worldSphere; - Animation_PlayLoop(&this->skelAnime, &D_060013C0); + Animation_PlayLoop(&this->skelAnime, &object_dinofos_Anim_0013C0); this->unk_290 = 20; this->actor.speedXZ = 0.0f; this->colliderJntSph.base.atFlags |= AT_ON; @@ -1064,13 +1048,13 @@ void func_8089CB10(EnDinofos* this, GlobalContext* globalCtx) { for (i = 6; i < ARRAY_COUNT(this->colliderJntSphElement); i++) { worldSphere = &this->colliderJntSph.elements[i].dim.worldSphere; - worldSphere->center.x = this->unk_34C.x; - worldSphere->center.y = this->unk_34C.y; - worldSphere->center.z = this->unk_34C.z; + worldSphere->center.x = this->limbPos[10].x; + worldSphere->center.y = this->limbPos[10].y; + worldSphere->center.z = this->limbPos[10].z; } if (globalCtx->sceneNum == SCENE_MITURIN) { - globalCtx->envCtx.unk_C3 = 11; + globalCtx->envCtx.lightSettingOverride = 11; } this->actionFunc = func_8089CBEC; @@ -1102,7 +1086,7 @@ void func_8089CBEC(EnDinofos* this, GlobalContext* globalCtx) { sp7C.y = randPlusMinusPoint5Scaled(0.6f) + 1.4f; sp7C.z = 0.9f * temp_f22; func_800B9010(&this->actor, NA_SE_EN_DODO_J_FIRE - SFX_FLAG); - EffectSsDFire_Spawn(globalCtx, &this->unk_34C, &sp88, &sp7C, 30, 22, 255 - (temp_s0 * 20), 20, 3, 8); + EffectSsDFire_Spawn(globalCtx, &this->limbPos[10], &sp88, &sp7C, 30, 22, 255 - (temp_s0 * 20), 20, 3, 8); for (end = 6, i = 3; i > 0; i--) { if (this->unk_290 < (20 + -(i * 2))) { @@ -1115,9 +1099,9 @@ void func_8089CBEC(EnDinofos* this, GlobalContext* globalCtx) { dim = &this->colliderJntSph.elements[i].dim; temp_s3 = (s32)(cos_rad((this->unk_290 + ((i - 5) << 1)) * (M_PI / 20)) * 0x2C00) + this->actor.shape.rot.y; - dim->worldSphere.center.x = (s32)(Math_SinS(temp_s3) * dim->modelSphere.center.z) + (s32)this->unk_34C.x; - dim->worldSphere.center.y = (s32)this->unk_34C.y + (s32)dim->modelSphere.center.y; - dim->worldSphere.center.z = (s32)(Math_CosS(temp_s3) * dim->modelSphere.center.z) + (s32)this->unk_34C.z; + dim->worldSphere.center.x = (s32)this->limbPos[10].x + (s32)(Math_SinS(temp_s3) * dim->modelSphere.center.z); + dim->worldSphere.center.y = (s32)this->limbPos[10].y + (s32)dim->modelSphere.center.y; + dim->worldSphere.center.z = (s32)this->limbPos[10].z + (s32)(Math_CosS(temp_s3) * dim->modelSphere.center.z); } if (this->unk_290 != 0) { @@ -1128,10 +1112,10 @@ void func_8089CBEC(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089CF00(EnDinofos* this, GlobalContext* globalCtx) { - Animation_PlayOnce(&this->skelAnime, &D_060017B8); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_0017B8); this->colliderJntSph.base.atFlags &= ~AT_ON; if (globalCtx->sceneNum == SCENE_MITURIN) { - globalCtx->envCtx.unk_C3 = 255; + globalCtx->envCtx.lightSettingOverride = 255; } this->actionFunc = func_8089CF70; } @@ -1143,9 +1127,9 @@ void func_8089CF70(EnDinofos* this, GlobalContext* globalCtx) { } void func_8089CFAC(EnDinofos* this) { - Animation_PlayOnce(&this->skelAnime, &D_0600ABD0); - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_DEAD); + Animation_PlayOnce(&this->skelAnime, &object_dinofos_Anim_00ABD0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_DEAD); this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; this->actionFunc = func_8089D018; @@ -1167,13 +1151,13 @@ void func_8089D018(EnDinofos* this, GlobalContext* globalCtx) { this->unk_288 = temp_v0; } - if (this->unk_2B0 > 0.0f) { - this->unk_2B0 = this->unk_288 * (1.0f / 255.0f); + if (this->drawDmgEffAlpha > 0.0f) { + this->drawDmgEffAlpha = this->unk_288 * (1.0f / 255.0f); } this->actor.shape.shadowAlpha = this->unk_288; } else if (Animation_OnFrame(&this->skelAnime, 26.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_DOWN); } } @@ -1183,7 +1167,8 @@ void func_8089D11C(EnDinofos* this, s16 arg1) { } else { this->actor.speedXZ = 15.0f; } - Animation_Change(&this->skelAnime, &D_0600D62C, this->actor.speedXZ * (1.0f / 7.5f), 0.0f, 0.0f, 0, -4.0f); + Animation_Change(&this->skelAnime, &object_dinofos_Anim_00D62C, this->actor.speedXZ * (1.0f / 7.5f), 0.0f, 0.0f, 0, + -4.0f); this->actor.world.rot.y = BINANG_ADD(this->actor.shape.rot.y, 0x4000); this->unk_292 = 10; this->unk_2A4 = 0.0f; @@ -1206,7 +1191,7 @@ void func_8089D1E0(EnDinofos* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } } @@ -1216,7 +1201,7 @@ void func_8089D2E0(EnDinofos* this) { } void func_8089D318(EnDinofos* this, GlobalContext* globalCtx) { - Vec3f sp24; + Vec3f subCamEye; if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { if (this->actor.colChkInfo.health == 0) { @@ -1225,12 +1210,12 @@ void func_8089D318(EnDinofos* this, GlobalContext* globalCtx) { } else { ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); } - this->camId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + this->subCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); if (this->actor.colChkInfo.health == 0) { - sp24.x = (Math_SinS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.x; - sp24.y = this->actor.focus.pos.y; - sp24.z = (Math_CosS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.z; - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &sp24); + subCamEye.x = (Math_SinS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.x; + subCamEye.y = this->actor.focus.pos.y; + subCamEye.z = (Math_CosS(this->actor.shape.rot.y) * 150.0f) + this->actor.focus.pos.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, &subCamEye); func_8089CFAC(this); } else { func_8089B100(this, globalCtx); @@ -1249,7 +1234,7 @@ void func_8089D42C(EnDinofos* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->unk_28E, cos_rad(M_PI) * 0x2C00, 0x233); } else if (this->actionFunc == func_8089CBEC) { this->unk_28E = cos_rad(this->unk_290 * (M_PI / 20)) * 0x2C00; - } else if (!func_801690CC(globalCtx)) { + } else if (!Play_InCsMode(globalCtx)) { temp_v0_2 = this->unk_28E + this->actor.shape.rot.y; temp_v0_2 = BINANG_SUB(this->actor.yawTowardsPlayer, temp_v0_2); temp_v0_2 = CLAMP(temp_v0_2, -0x300, 0x300); @@ -1263,7 +1248,7 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { if (this->colliderJntSph.base.acFlags & AC_HIT) { this->colliderJntSph.base.acFlags &= ~AC_HIT; - func_800BE2B8(&this->actor, &this->colliderJntSph); + Actor_SetDropFlagJntSph(&this->actor, &this->colliderJntSph); for (i = 0; i < ARRAY_COUNT(this->colliderJntSphElement); i++) { if (this->colliderJntSph.elements[i].info.bumperFlags & BUMP_HIT) { @@ -1275,7 +1260,8 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { return false; } - if ((this->unk_28A == 10) && (this->colliderJntSph.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->colliderJntSph.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { return false; } @@ -1300,7 +1286,7 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { func_8089ACEC(this, globalCtx); func_8089AD70(this); if (globalCtx->sceneNum == SCENE_MITURIN) { - globalCtx->envCtx.unk_C3 = 255; + globalCtx->envCtx.lightSettingOverride = 255; } this->colliderQuad.base.atFlags &= ~(AT_ON | AT_BOUNCED); @@ -1317,31 +1303,31 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == 1) { this->unk_290 = 40; - func_800BCB70(&this->actor, 0, 255, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); func_8089C784(this); return true; } if (this->actor.colChkInfo.damageEffect == 5) { this->unk_290 = 40; - func_800BCB70(&this->actor, 0, 255, 0, 40); - this->unk_2B4 = 0.55f; - this->unk_2B0 = 2.0f; - this->unk_28A = 31; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + this->drawDmgEffScale = 0.55f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); func_8089C784(this); return true; } if (this->actor.colChkInfo.damageEffect == 2) { - this->unk_2B0 = 4.0f; - this->unk_2B4 = 0.55f; - this->unk_28A = 0; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; } else if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_2B0 = 4.0f; - this->unk_2B4 = 0.55f; - this->unk_28A = 20; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->colliderJntSph.elements[i].info.bumper.hitPos.x, this->colliderJntSph.elements[i].info.bumper.hitPos.y, @@ -1355,8 +1341,8 @@ s32 func_8089D60C(EnDinofos* this, GlobalContext* globalCtx) { } void EnDinofos_Update(Actor* thisx, GlobalContext* globalCtx2) { - EnDinofos* this = THIS; GlobalContext* globalCtx = globalCtx2; + EnDinofos* this = THIS; s32 pad; Vec3f sp30; @@ -1369,13 +1355,13 @@ void EnDinofos_Update(Actor* thisx, GlobalContext* globalCtx2) { } this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, 30.0f, 60.0f, 0x5D); if (this->actionFunc != func_8089C7B8) { - if ((this->actor.yDistToWater > 0.0f) && (this->actor.yDistToWater < 10.0f)) { + if ((this->actor.depthInWater > 0.0f) && (this->actor.depthInWater < 10.0f)) { if (!((globalCtx->gameplayFrames % 4) & 1)) { - Math_Vec3f_Copy(&sp30, &this->unk_2D4[1 + (globalCtx->gameplayFrames % 4)]); - sp30.y = this->actor.world.pos.y + this->actor.yDistToWater; + Math_Vec3f_Copy(&sp30, &this->limbPos[1 + (globalCtx->gameplayFrames % 4)]); + sp30.y = this->actor.world.pos.y + this->actor.depthInWater; EffectSsGRipple_Spawn(globalCtx, &sp30, 100, 320, 0); } } @@ -1388,7 +1374,7 @@ void EnDinofos_Update(Actor* thisx, GlobalContext* globalCtx2) { Math_ScaledStepToS(&this->unk_28E, 0, 2000); } - Math_Vec3f_Copy(&this->actor.focus.pos, &this->unk_304); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->limbPos[4]); this->actor.focus.rot.y = this->actor.shape.rot.y + this->unk_28E; if (this->colliderJntSph.base.acFlags & AC_ON) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); @@ -1403,12 +1389,12 @@ void EnDinofos_Update(Actor* thisx, GlobalContext* globalCtx2) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderQuad.base); } - if (this->unk_2B0 > 0.0f) { - if (this->unk_28A != 10) { - Math_StepToF(&this->unk_2B0, 0.0f, 0.05f); - this->unk_2B4 = (this->unk_2B0 + 1.0f) * (11.0f / 40.0f); - this->unk_2B4 = CLAMP_MAX(this->unk_2B4, 0.55f); - } else if (!Math_StepToF(&this->unk_2B8, 0.55f, 0.01375f)) { + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * (11.0f / 40.0f); + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.01375f)) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } @@ -1443,39 +1429,39 @@ void func_8089DC84(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* Collider_UpdateSpheres(limbIndex, &this->colliderJntSph); if (D_8089E3B0[limbIndex] != -1) { - Matrix_GetStateTranslation(&this->unk_2D4[D_8089E3B0[limbIndex]]); + Matrix_MultZero(&this->limbPos[D_8089E3B0[limbIndex]]); } if ((limbIndex == 14) && (this->unk_292 != this->unk_290) && ((this->actionFunc == func_8089C56C) || (this->actionFunc == func_8089C2A8))) { Math_Vec3f_Copy(&sp74, &this->colliderQuad.dim.quad[0]); Math_Vec3f_Copy(&sp80, &this->colliderQuad.dim.quad[1]); - Matrix_MultiplyVector3fByState(&D_8089E38C, &sp68); - Matrix_MultiplyVector3fByState(&D_8089E398, &sp5C); + Matrix_MultVec3f(&D_8089E38C, &sp68); + Matrix_MultVec3f(&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; } if (limbIndex == 4) { - Matrix_GetStateTranslationAndScaledX(300.0f, &this->actor.shape.feetPos[0]); + Matrix_MultVecX(300.0f, &this->actor.shape.feetPos[0]); } else if (limbIndex == 7) { - Matrix_GetStateTranslationAndScaledX(300.0f, &this->actor.shape.feetPos[1]); + Matrix_MultVecX(300.0f, &this->actor.shape.feetPos[1]); } if ((limbIndex == 16) && (this->actionFunc == func_8089B580)) { if ((this->skelAnime.curFrame > 38.0f) && (this->skelAnime.curFrame <= 55.0f) && (this->unk_292 != this->unk_290)) { - sp48 = Matrix_GetCurrentState(); + sp48 = Matrix_GetCurrent(); sp58 = 48 - (s32)this->skelAnime.curFrame; sp58 = CLAMP_MIN(sp58, 0); - Matrix_MultiplyVector3fByState(&D_8089E3A4, &sp4C); + Matrix_MultVec3f(&D_8089E3A4, &sp4C); 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->limbPos[10], &sp4C, &gZeroVec3f, 30, 22, 255 - (sp58 * 20), 20, 3, 8); this->unk_292 = this->unk_290; } } @@ -1510,8 +1496,8 @@ void EnDinofos_Draw(Actor* thisx, GlobalContext* globalCtx) { this->skelAnime.dListCount, func_8089DC4C, func_8089DC84, &this->actor, POLY_XLU_DISP); } - func_800BE680(globalCtx, &this->actor, this->unk_2D4, 12, this->unk_2B4, this->unk_2B8, this->unk_2B0, - this->unk_28A); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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..f5c7431f0 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h @@ -15,33 +15,28 @@ typedef struct EnDinofos { /* 0x284 */ EnDinofosActionFunc actionFunc; /* 0x288 */ u8 unk_288; /* 0x289 */ u8 unk_289; - /* 0x28A */ u8 unk_28A; + /* 0x28A */ u8 drawDmgEffType; /* 0x28B */ u8 unk_28B; /* 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; + /* 0x298 */ s16 subCamId; /* 0x29A */ Vec3s unk_29A; /* 0x2A0 */ s32 unk_2A0; /* 0x2A4 */ f32 unk_2A4; /* 0x2A8 */ f32 unk_2A8; /* 0x2AC */ f32 unk_2AC; - /* 0x2B0 */ f32 unk_2B0; - /* 0x2B4 */ f32 unk_2B4; - /* 0x2B8 */ f32 unk_2B8; + /* 0x2B0 */ f32 drawDmgEffAlpha; + /* 0x2B4 */ f32 drawDmgEffScale; + /* 0x2B8 */ f32 drawDmgEffFrozenSteamScale; /* 0x2BC */ Vec3f unk_2BC; /* 0x2C8 */ Vec3f unk_2C8; - /* 0x2D4 */ Vec3f unk_2D4[4]; - /* 0x304 */ Vec3f unk_304; - /* 0x310 */ UNK_TYPE1 unk_310[0x3C]; - /* 0x34C */ Vec3f unk_34C; - /* 0x358 */ UNK_TYPE1 unk_358[0xC]; + /* 0x2D4 */ Vec3f limbPos[12]; /* 0x364 */ ColliderJntSph colliderJntSph; /* 0x384 */ ColliderJntSphElement colliderJntSphElement[9]; /* 0x5C4 */ ColliderQuad colliderQuad; - } EnDinofos; // size = 0x644 extern const ActorInit En_Dinofos_InitVars; 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 780ce1cda..914e0f355 100644 --- a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c +++ b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c @@ -1,12 +1,14 @@ /* * File: z_en_dnb.c * Overlay: ovl_En_Dnb - * Description: + * Description: Unused invisible snowy mountain that explodes? */ #include "z_en_dnb.h" +#include "objects/object_hanareyama_obj/object_hanareyama_obj.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x000000B0 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_80) #define THIS ((EnDnb*)thisx) @@ -19,12 +21,6 @@ s32 func_80A507C0(EnDnbUnkStruct* arg0, Vec3f arg1, Vec3f arg2, u8 arg3, f32 arg s32 func_80A5086C(EnDnbUnkStruct* arg0); s32 func_80A50950(EnDnbUnkStruct* arg0, GlobalContext* globalCtx); -extern Gfx D_06000000[]; -extern Gfx D_06000020[]; -extern Gfx D_06004638[]; -extern Vec3s D_06004710[]; -extern CollisionHeader D_06004D8C; - const ActorInit En_Dnb_InitVars = { ACTOR_EN_DNB, ACTORCAT_BG, @@ -47,7 +43,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 +72,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 +82,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; @@ -108,10 +104,10 @@ void EnDnb_Init(Actor* thisx, GlobalContext* globalCtx) { s32 i; s16* alloc; - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06004D8C); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_hanareyama_obj_Colheader_004D8C); - alloc = (s16*)Lib_SegmentedToVirtual(D_06004710); + alloc = Lib_SegmentedToVirtual(object_hanareyama_obj_Vec_004710); for (i = 0; i < ARRAY_COUNT(this->particles); i++) { func_80A4FDD0(&this->particles[i], this, alloc, i); } @@ -122,7 +118,7 @@ void EnDnb_Init(Actor* thisx, GlobalContext* globalCtx) { void EnDnb_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnDnb* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void EnDnb_Update(Actor* thisx, GlobalContext* globalCtx) { @@ -156,24 +152,24 @@ void EnDnb_Update(Actor* thisx, GlobalContext* globalCtx) { void func_80A50510(EnDnb* this, GlobalContext* globalCtx) { s32 i; - Gfx** gfx = Lib_SegmentedToVirtual(D_06004638); + Gfx** gfx = Lib_SegmentedToVirtual(object_hanareyama_obj_DLArray_004638); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); for (i = 0; i < ARRAY_COUNT(this->particles); i++) { - Matrix_StatePush(); - Matrix_InsertTranslation(this->particles[i].unk_0C.x, this->particles[i].unk_0C.y, this->particles[i].unk_0C.z, - MTXMODE_NEW); - Matrix_InsertXRotation_s(this->particles[i].unk_18.x, MTXMODE_APPLY); - Matrix_RotateY(this->particles[i].unk_18.y, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->particles[i].unk_18.z, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Translate(this->particles[i].unk_0C.x, this->particles[i].unk_0C.y, this->particles[i].unk_0C.z, + MTXMODE_NEW); + Matrix_RotateXS(this->particles[i].unk_18.x, MTXMODE_APPLY); + Matrix_RotateYS(this->particles[i].unk_18.y, MTXMODE_APPLY); + Matrix_RotateZS(this->particles[i].unk_18.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++, gfx[i]); - Matrix_StatePop(); + Matrix_Pop(); } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -181,24 +177,24 @@ void func_80A50510(EnDnb* this, GlobalContext* globalCtx) { void func_80A5063C(EnDnb* this, GlobalContext* globalCtx) { s32 i; - Gfx** gfx = Lib_SegmentedToVirtual(D_06004638); + Gfx** gfx = Lib_SegmentedToVirtual(object_hanareyama_obj_DLArray_004638); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); for (i = 0; i < ARRAY_COUNT(this->particles); i++) { - Matrix_StatePush(); - Matrix_InsertTranslation(this->particles[i].unk_0C.x, this->particles[i].unk_0C.y, this->particles[i].unk_0C.z, - MTXMODE_NEW); - Matrix_InsertXRotation_s(this->particles[i].unk_18.x, MTXMODE_APPLY); - Matrix_RotateY(this->particles[i].unk_18.y, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->particles[i].unk_18.z, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Translate(this->particles[i].unk_0C.x, this->particles[i].unk_0C.y, this->particles[i].unk_0C.z, + MTXMODE_NEW); + Matrix_RotateXS(this->particles[i].unk_18.x, MTXMODE_APPLY); + Matrix_RotateYS(this->particles[i].unk_18.y, MTXMODE_APPLY); + Matrix_RotateZS(this->particles[i].unk_18.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++, gfx[i]); - Matrix_StatePop(); + Matrix_Pop(); } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -259,7 +255,7 @@ s32 func_80A5086C(EnDnbUnkStruct* arg0) { s32 func_80A50950(EnDnbUnkStruct* arg0, GlobalContext* globalCtx2) { static TexturePtr D_80A50CBC[] = { - D_0408F7E0, D_0408F3E0, D_0408EFE0, D_0408EBE0, D_0408E7E0, D_0408E3E0, D_0408DFE0, D_0408DBE0, + gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex, }; GlobalContext* globalCtx = globalCtx2; s32 isGfxSetup = false; @@ -275,28 +271,28 @@ s32 func_80A50950(EnDnbUnkStruct* arg0, GlobalContext* globalCtx2) { if (arg0->isEnabled == 1) { if (!isGfxSetup) { POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); - gSPDisplayList(POLY_XLU_DISP++, D_06000000); + gSPDisplayList(POLY_XLU_DISP++, object_hanareyama_obj_DL_000000); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 0); isGfxSetup = true; } - Matrix_StatePush(); + Matrix_Push(); if (1) {}; arg0->unk_24 = (arg0->unk_01 / (f32)arg0->unk_02) * 255.0f; gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)arg0->unk_24); - Matrix_InsertTranslation(arg0->unk_0C.x, arg0->unk_0C.y, arg0->unk_0C.z, MTXMODE_NEW); + Matrix_Translate(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_ReplaceRotation(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); idx = (arg0->unk_01 / (f32)arg0->unk_02) * 8.0f; gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A50CBC[idx])); - gSPDisplayList(POLY_XLU_DISP++, D_06000020); + gSPDisplayList(POLY_XLU_DISP++, object_hanareyama_obj_DL_000020); - Matrix_StatePop(); + Matrix_Pop(); sp5C += 1; } } diff --git a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.c b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.c index 21071691e..25fbaefac 100644 --- a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.c +++ b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.c @@ -1,6 +1,12 @@ +/* + * File: z_en_dnh.c + * Overlay: ovl_En_Dnh + * Description: Koume in boat house + */ + #include "z_en_dnh.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDnh*)thisx) 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 59a39f65a..62b040c9e 100644 --- a/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c +++ b/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c @@ -5,8 +5,11 @@ */ #include "z_en_dnk.h" +#include "objects/object_dnk/object_dnk.h" +#include "objects/object_hintnuts/object_hintnuts.h" +#include "objects/object_dekunuts/object_dekunuts.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDnk*)thisx) @@ -19,39 +22,6 @@ void EnDnk_DoNothing(EnDnk* this, GlobalContext* globalCtx); void func_80A52018(Actor* thisx, GlobalContext* globalCtx); void func_80A52134(EnDnk* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000168; -extern AnimationHeader D_0600031C; -extern AnimationHeader D_06000430; -extern AnimationHeader D_060006CC; -extern AnimationHeader D_06000894; -extern AnimationHeader D_06000B70; -extern UNK_PTR D_06001680[]; -extern UNK_PTR D_06001700[]; -extern UNK_PTR D_06001780[]; -extern SkeletonHeader D_060023B8; -extern SkeletonHeader D_06002468; -extern AnimationHeader D_060024CC; -extern AnimationHeader D_0600259C; -extern AnimationHeader D_060026C4; -extern SkeletonHeader D_06002848; -extern AnimationHeader D_06002894; -extern AnimationHeader D_06002950; -extern AnimationHeader D_060029BC; -extern AnimationHeader D_06002A08; -extern AnimationHeader D_06002A5C; -extern AnimationHeader D_06002B6C; -extern AnimationHeader D_06002B90; -extern AnimationHeader D_06002BD4; -extern AnimationHeader D_06002DD4; -extern AnimationHeader D_06002E84; -extern AnimationHeader D_06002F7C; -extern AnimationHeader D_06002FA4; -extern AnimationHeader D_06003128; -extern AnimationHeader D_06003180; -extern AnimationHeader D_0600326C; -extern AnimationHeader D_060033E4; -extern AnimationHeader D_06003780; - static s16 D_80A521A0 = 0; const ActorInit En_Dnk_InitVars = { @@ -123,19 +93,43 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06000B70, 1.0f, 0, -1, 2, 0 }, { &D_06000B70, 1.0f, 0, -1, 2, -4 }, { &D_06002A08, 1.0f, 0, -1, 0, -4 }, - { &D_0600031C, 1.0f, 0, -1, 0, -4 }, { &D_06000430, 1.0f, -1, -1, 2, 0 }, { &D_06000430, 1.0f, 0, -1, 2, -4 }, - { &D_06000894, 1.0f, 0, -1, 2, -4 }, { &D_06002B6C, 1.0f, 0, -1, 0, 0 }, { &D_06002B6C, 1.0f, 0, -1, 0, -4 }, - { &D_060006CC, 1.0f, 0, -1, 0, -4 }, { &D_06000168, 1.0f, 0, -1, 2, -4 }, { &D_060024CC, 1.0f, -1, -1, 2, 0 }, - { &D_060024CC, 1.0f, 0, -1, 2, -4 }, { &D_060026C4, 1.0f, 0, -1, 2, -4 }, { &D_06002894, 1.0f, 0, -1, 2, -4 }, - { &D_06002B90, 1.0f, 0, -1, 2, -4 }, { &D_06002F7C, 1.0f, 0, -1, 0, 0 }, { &D_06002F7C, 1.0f, 0, -1, 0, -4 }, - { &D_06003128, 1.0f, 0, -1, 0, 0 }, { &D_06003128, 1.0f, 0, -1, 0, -4 }, { &D_060029BC, 1.0f, 0, -1, 0, -4 }, - { &D_06002E84, 1.0f, 0, -1, 0, -4 }, { &D_06000168, 1.0f, 0, -1, 0, -4 }, { &D_0600259C, 1.0f, 0, -1, 2, -4 }, - { &D_06002A5C, 1.0f, 0, -1, 2, 0 }, { &D_06002A5C, 1.0f, 0, -1, 2, -4 }, { &D_06002BD4, 1.0f, 0, -1, 2, -4 }, - { &D_06002DD4, 1.0f, 0, -1, 2, -4 }, { &D_06002FA4, 1.0f, 0, -1, 0, -4 }, { &D_06003180, 1.0f, 0, -1, 2, -4 }, - { &D_0600326C, 1.0f, 0, -1, 0, 0 }, { &D_0600326C, 1.0f, 0, -1, 0, -4 }, { &D_060033E4, 1.0f, 0, -1, 0, -4 }, - { &D_06003780, 1.0f, 0, -1, 0, 0 }, { &D_06003780, 1.0f, 0, -1, 0, -4 }, { &D_06002950, 1.0f, 0, -1, 0, 0 }, +static AnimationInfoS sAnimations[] = { + { &gDekuPalaceGuardStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gDekuPalaceGuardStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuPalaceGuardWaitAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuPalaceGuardAttackAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuPalaceGuardDigAnim, 1.0f, -1, -1, ANIMMODE_ONCE, 0 }, + { &gDekuPalaceGuardDigAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuPalaceGuardJumpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuPalaceGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gDekuPalaceGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuPalaceGuardHappyAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_hintnuts_Anim_000168, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_hintnuts_Anim_0024CC, 1.0f, -1, -1, ANIMMODE_ONCE, 0 }, + { &object_hintnuts_Anim_0024CC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_hintnuts_Anim_0026C4, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_hintnuts_Anim_002894, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_hintnuts_Anim_002B90, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_hintnuts_Anim_002F7C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_hintnuts_Anim_002F7C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_hintnuts_Anim_003128, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_hintnuts_Anim_003128, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_hintnuts_Anim_0029BC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_hintnuts_Anim_002E84, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubSpitAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubDamageAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuScrubBurrowAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gDekuScrubBurrowAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuScrubDieAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuScrubUnburrowAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuScrubLookAroundAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubUpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &gDekuScrubIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gDekuScrubIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubPantingAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gDekuScrubRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gDekuScrubStandingIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, }; s32 func_80A514F0(SkelAnime* skelAnime, s16 animIndex) { @@ -144,18 +138,18 @@ s32 func_80A514F0(SkelAnime* skelAnime, s16 animIndex) { s32 sp30 = false; if (animIndex >= 0) { - if (animIndex < 36) { + if (animIndex < ARRAY_COUNT(sAnimations)) { sp30 = true; frameCount = sAnimations[animIndex].frameCount; if (frameCount < 0) { - frameCount = Animation_GetLastFrame(sAnimations[animIndex].animationSeg); + frameCount = Animation_GetLastFrame(sAnimations[animIndex].animation); } - frame = sAnimations[animIndex].frame; + frame = sAnimations[animIndex].startFrame; if (frame < 0) { frame = frameCount; } - Animation_Change(skelAnime, sAnimations[animIndex].animationSeg, sAnimations[animIndex].playbackSpeed, - frame, frameCount, sAnimations[animIndex].mode, sAnimations[animIndex].transitionRate); + Animation_Change(skelAnime, sAnimations[animIndex].animation, sAnimations[animIndex].playSpeed, frame, + frameCount, sAnimations[animIndex].mode, sAnimations[animIndex].morphFrames); } } return sp30; @@ -176,25 +170,28 @@ s32 func_80A515C4(EnDnk* this) { } void func_80A51648(EnDnk* this, GlobalContext* globalCtx) { - if (func_8013D8DC(this->unk_28E, globalCtx) == 1) { - gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->unk_28E].segment); + if (SubS_IsObjectLoaded(this->unk_28E, globalCtx) == true) { + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->unk_28E].segment); this->actor.draw = func_80A52018; this->actor.objBankIndex = this->unk_28E; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 18.0f); switch (ENDNK_GET_3(&this->actor)) { case ENDNK_GET_3_0: - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06002848, NULL, this->jointTable, this->morphTable, 11); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuPalaceGuardSkel, NULL, this->jointTable, + this->morphTable, DEKU_PALACE_GUARD_LIMB_MAX); func_80A514F0(&this->skelAnime, 7); break; case ENDNK_GET_3_1: - SkelAnime_Init(globalCtx, &this->skelAnime, &D_060023B8, NULL, this->jointTable, this->morphTable, 10); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_hintnuts_Skel_0023B8.sh, NULL, this->jointTable, + this->morphTable, 10); func_80A514F0(&this->skelAnime, 18); break; case ENDNK_GET_3_2: - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06002468, NULL, this->jointTable, this->morphTable, 10); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuScrubSkel, NULL, this->jointTable, this->morphTable, + DEKU_SCRUB_LIMB_MAX); func_80A514F0(&this->skelAnime, 35); break; } @@ -203,12 +200,12 @@ void func_80A51648(EnDnk* this, GlobalContext* globalCtx) { Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); if (ENDNK_GET_3C(&this->actor) == 4) { - this->actor.flags &= ~1; - this->actor.flags |= (0x10 | 0x20); + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); this->actionFunc = func_80A51890; Actor_SetScale(&this->actor, 0.1f); } else { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = EnDnk_DoNothing; Actor_SetScale(&this->actor, 0.01f); } @@ -216,8 +213,8 @@ void func_80A51648(EnDnk* this, GlobalContext* globalCtx) { } void func_80A51890(EnDnk* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x7E)) { - func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x7E)); + if (Cutscene_CheckActorAction(globalCtx, 126)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 126)); } } @@ -230,15 +227,15 @@ void EnDnk_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_28E = -1; switch (ENDNK_GET_3(&this->actor)) { case ENDNK_GET_3_1: - this->unk_28E = func_8013D924(0x12B, globalCtx); + this->unk_28E = SubS_GetObjectIndex(OBJECT_HINTNUTS, globalCtx); break; case ENDNK_GET_3_0: - this->unk_28E = func_8013D924(0x135, globalCtx); + this->unk_28E = SubS_GetObjectIndex(OBJECT_DNK, globalCtx); break; case ENDNK_GET_3_2: - this->unk_28E = func_8013D924(0x40, globalCtx); + this->unk_28E = SubS_GetObjectIndex(OBJECT_DEKUNUTS, globalCtx); break; } @@ -265,7 +262,7 @@ void EnDnk_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); SkelAnime_Update(&this->skelAnime); func_80A515C4(this); - Actor_SetHeight(&this->actor, 34.0f); + Actor_SetFocus(&this->actor, 34.0f); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); @@ -283,15 +280,15 @@ 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; if (limbIndex == 2) { - Matrix_MultiplyVector3fByState(&sp50, &sp44); - Matrix_CopyCurrentState(&sp5C); - func_8018219C(&sp5C, &sp3C, 0); - Matrix_InsertTranslation(sp44.x, sp44.y, sp44.z, MTXMODE_NEW); + Matrix_MultVec3f(&sp50, &sp44); + Matrix_Get(&sp5C); + Matrix_MtxFToYXZRot(&sp5C, &sp3C, false); + Matrix_Translate(sp44.x, sp44.y, sp44.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); if (this->unk_28C & 0x10) { if (this->unk_28C & 0x20) { @@ -314,9 +311,9 @@ void func_80A51AA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* this->unk_294 = sp3C.z; } - Matrix_RotateY(this->unk_292, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_290, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_294, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_292, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_290, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_294, MTXMODE_APPLY); } OPEN_DISPS(globalCtx->state.gfxCtx); @@ -328,10 +325,10 @@ void func_80A51AA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* } void func_80A51CB8(EnDnk* this, GlobalContext* globalCtx) { - static UNK_PTR D_80A5245C[] = { - D_06001680, - D_06001700, - D_06001780, + static TexturePtr D_80A5245C[] = { + gDekuPalaceGuardEyeOpenTex, + gDekuPalaceGuardEyeHalfTex, + gDekuPalaceGuardEyeClosedTex, }; s32 pad; @@ -359,15 +356,15 @@ 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; if (limbIndex == 2) { - Matrix_MultiplyVector3fByState(&sp50, &sp44); - Matrix_CopyCurrentState(&sp5C); - func_8018219C(&sp5C, &sp3C, 0); - Matrix_InsertTranslation(sp44.x, sp44.y, sp44.z, MTXMODE_NEW); + Matrix_MultVec3f(&sp50, &sp44); + Matrix_Get(&sp5C); + Matrix_MtxFToYXZRot(&sp5C, &sp3C, false); + Matrix_Translate(sp44.x, sp44.y, sp44.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); if (this->unk_28C & 0x10) { @@ -391,9 +388,9 @@ void func_80A51DA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* this->unk_294 = sp3C.z; } - Matrix_RotateY(this->unk_292, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_290, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_294, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_292, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_290, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_294, MTXMODE_APPLY); } OPEN_DISPS(globalCtx->state.gfxCtx); @@ -436,11 +433,11 @@ void func_80A52074(EnDnk* this, GlobalContext* globalCtx) { break; case 438: - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKNUTS_DANCE_BIG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKNUTS_DANCE_BIG); break; case 493: - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); break; } 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 ff7e3de3b..326f3fbf2 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c @@ -6,8 +6,10 @@ #include "z_en_dno.h" #include "overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_dno/object_dno.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnDno*)thisx) @@ -38,37 +40,17 @@ void func_80A732C8(EnDno* this, GlobalContext* globalCtx); s32 EnDno_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); -extern AnimationHeader D_06000470; -extern AnimationHeader D_060008F0; -extern AnimationHeader D_06000F6C; -extern AnimationHeader D_06001A50; -extern AnimationHeader D_06002530; -extern AnimationHeader D_06003320; -extern AnimationHeader D_060036D0; -extern AnimationHeader D_060041CC; -extern AnimationHeader D_06004DD8; -extern AnimationHeader D_060051E4; -extern AnimationHeader D_06005E20; -extern AnimationHeader D_06005F98; -extern AnimationHeader D_06006488; -extern AnimationHeader D_06006F84; -extern AnimationHeader D_060073E4; -extern AnimationHeader D_060077A8; -extern AnimationHeader D_06007CA4; -extern AnimationHeader D_06008324; -extern AnimationHeader D_06008AE4; -extern AnimationHeader D_06009100; -extern FlexSkeletonHeader D_0600E1F8; -extern u8 D_801C20C0; - -static struct_80B8E1A8 sAnimations[] = { - { &D_06000470, 1.0f, 2, 0.0f }, { &D_060008F0, 1.0f, 2, 0.0f }, { &D_06000F6C, 1.0f, 0, 0.0f }, - { &D_06001A50, 1.0f, 2, 0.0f }, { &D_06002530, 1.0f, 2, 0.0f }, { &D_06003320, 1.0f, 2, 0.0f }, - { &D_060036D0, 1.0f, 0, 0.0f }, { &D_060041CC, 1.0f, 2, 0.0f }, { &D_06004DD8, 1.0f, 2, 0.0f }, - { &D_06005F98, 1.0f, 0, 0.0f }, { &D_06006488, 1.0f, 2, 0.0f }, { &D_060073E4, 1.0f, 0, 0.0f }, - { &D_060077A8, 1.0f, 0, 0.0f }, { &D_06007CA4, 1.0f, 0, 0.0f }, { &D_06008324, 1.0f, 0, 0.0f }, - { &D_06008AE4, 1.0f, 2, 0.0f }, { &D_06009100, 1.0f, 2, 0.0f }, { &D_060051E4, 1.0f, 2, 0.0f }, - { &D_06005E20, 1.0f, 0, 0.0f }, { &D_06006F84, 1.0f, 0, 0.0f }, +static AnimationSpeedInfo sAnimations[] = { + { &object_dno_Anim_000470, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_dno_Anim_0008F0, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_000F6C, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_dno_Anim_001A50, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_002530, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_dno_Anim_003320, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_0036D0, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_dno_Anim_0041CC, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_004DD8, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_dno_Anim_005F98, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_dno_Anim_006488, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_dno_Anim_0073E4, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_dno_Anim_0077A8, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_dno_Anim_007CA4, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_dno_Anim_008324, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_dno_Anim_008AE4, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_009100, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_dno_Anim_0051E4, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_dno_Anim_005E20, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_dno_Anim_006F84, 1.0f, ANIMMODE_LOOP, 0.0f }, }; const ActorInit En_Dno_InitVars = { @@ -134,10 +116,10 @@ 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) { - Actor_SetSwitchFlag(globalCtx, ENDNO_GET_7F0(actor)); + Flags_SetSwitch(globalCtx, ENDNO_GET_7F0(actor)); } actor = actor->next; } @@ -164,15 +146,14 @@ 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)) { + if (SubS_LineSegVsPlane(&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_MultiplyVector3fByState(&sp7C, &sp70); + Matrix_RotateYS(-crace->actor.home.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&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,9 +168,9 @@ 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)); + Flags_UnsetSwitch(globalCtx, ENDNO_GET_7F0(actor)); actor = actor->next; } } while (actor != NULL); @@ -201,7 +182,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); @@ -212,15 +193,15 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) { if (actor == NULL) { Actor_ProcessInitChain(thisx, sInitChain); - ActorShape_Init(&thisx->shape, 0.0f, func_800B3FC0, 21.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600E1F8, &D_06007CA4, this->jointTable, - this->morphTable, 28); + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 21.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dno_Skel_00E1F8, &object_dno_Anim_007CA4, + this->jointTable, this->morphTable, 28); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, thisx, &sCylinderInit); Actor_UpdateBgCheckInfo(globalCtx, thisx, 0.0f, 0.0f, 0.0f, 4); - Animation_Change(&this->skelAnime, sAnimations[14].animationSeg, 1.0f, 0.0f, - Animation_GetLastFrame(sAnimations[14].animationSeg), sAnimations[14].mode, - sAnimations[14].transitionRate); + Animation_Change(&this->skelAnime, sAnimations[14].animation, 1.0f, 0.0f, + Animation_GetLastFrame(sAnimations[14].animation), sAnimations[14].mode, + sAnimations[14].morphFrames); this->unk_3BE = 0x3E93; this->unk_3C0 = 60.0f; this->unk_3B0 = 0; @@ -230,10 +211,10 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) { switch (ENDNO_GET_C000(thisx)) { case ENDNO_GET_C000_0: func_80A71788(this, globalCtx); - if (!(gSaveContext.weekEventReg[23] & 0x20) || (gSaveContext.weekEventReg[93] & 2)) { + if (!(gSaveContext.save.weekEventReg[23] & 0x20) || (gSaveContext.save.weekEventReg[93] & 2)) { Actor_MarkForDeath(thisx); } else { - func_8013E1C8(&this->skelAnime, sAnimations, 14, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C); thisx->room = -1; gSaveContext.unk_3DD0[1] = 5; this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); @@ -244,11 +225,11 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) { break; case ENDNO_GET_C000_1: - if (gSaveContext.weekEventReg[23] & 0x20) { + if (gSaveContext.save.weekEventReg[23] & 0x20) { 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); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); + this->unk_460 = SubS_FindActor(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_DNQ); if (this->unk_460 == NULL) { Actor_MarkForDeath(thisx); } else { @@ -275,7 +256,7 @@ void EnDno_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_80A71B04(EnDno* this, GlobalContext* globalCtx) { this->unk_452 = 0; - func_8013E1C8(&this->skelAnime, sAnimations, 19, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 19, &this->unk_32C); this->actionFunc = EnDno_DoNothing; } @@ -285,17 +266,17 @@ void EnDno_DoNothing(EnDno* this, GlobalContext* globalCtx) { void func_80A71B68(EnDno* this, GlobalContext* globalCtx) { this->unk_452 = 0; this->actor.textId = 0; - if (CHECK_QUEST_ITEM(6)) { - if (gSaveContext.weekEventReg[27] & 1) { + if (CHECK_QUEST_ITEM(QUEST_SONG_SONATA)) { + if (gSaveContext.save.weekEventReg[27] & 1) { if (!(this->unk_3B0 & 0x20)) { - func_8013E1C8(&this->skelAnime, sAnimations, 6, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 6, &this->unk_32C); this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, this->unk_460); } } else { - func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); } } else { - func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); } this->actionFunc = func_80A71C3C; } @@ -304,23 +285,23 @@ void func_80A71C3C(EnDno* this, GlobalContext* globalCtx) { switch (this->unk_32C) { case 9: case 16: - func_8013E1C8(&this->skelAnime, sAnimations, 10, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 10, &this->unk_32C); break; case 3: case 10: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); } break; case 11: - func_8013E1C8(&this->skelAnime, sAnimations, 15, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 15, &this->unk_32C); break; case 15: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 6, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 6, &this->unk_32C); } case 6: @@ -339,8 +320,8 @@ void func_80A71C3C(EnDno* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 0x222); } - if (func_800B84D0(&this->actor, globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.msgMode = 0; globalCtx->msgCtx.unk11F10 = 0; func_80A71E54(this, globalCtx); } else if (this->actor.xzDistToPlayer < 60.0f) { @@ -349,21 +330,21 @@ void func_80A71C3C(EnDno* this, GlobalContext* globalCtx) { } void func_80A71E54(EnDno* this, GlobalContext* globalCtx) { - if (CHECK_QUEST_ITEM(6)) { - if (gSaveContext.weekEventReg[27] & 1) { - this->unk_464 = 0x811; + if (CHECK_QUEST_ITEM(QUEST_SONG_SONATA)) { + if (gSaveContext.save.weekEventReg[27] & 1) { + this->textId = 0x811; } else { - this->unk_464 = 0x80F; - gSaveContext.weekEventReg[27] |= 1; + this->textId = 0x80F; + gSaveContext.save.weekEventReg[27] |= 1; } - } else if (gSaveContext.weekEventReg[26] & 0x80) { - this->unk_464 = 0x80B; + } else if (gSaveContext.save.weekEventReg[26] & 0x80) { + this->textId = 0x80B; } else { - this->unk_464 = 0x80C; - gSaveContext.weekEventReg[26] |= 0x80; + this->textId = 0x80C; + gSaveContext.save.weekEventReg[26] |= 0x80; } - if (this->unk_464 != 0x811) { + if (this->textId != 0x811) { this->unk_3B0 |= 0x10; } else { this->unk_3B0 &= ~0x10; @@ -374,25 +355,25 @@ void func_80A71E54(EnDno* this, GlobalContext* globalCtx) { void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->unk_466, 0, 0x16C); - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: if (!(this->unk_3B0 & 0x10) || Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xE38)) { - switch (this->unk_464) { + switch (this->textId) { case 0x80B: - func_8013E1C8(&this->skelAnime, sAnimations, 16, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 16, &this->unk_32C); case 0x811: - func_801518B0(globalCtx, this->unk_464, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); break; case 0x80C: case 0x80F: if (this->unk_32C == 13) { - func_8013E1C8(&this->skelAnime, sAnimations, 4, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 4, &this->unk_32C); } else if ((this->unk_32C == 4) && (this->skelAnime.curFrame == this->skelAnime.endFrame)) { - func_8013E1C8(&this->skelAnime, sAnimations, 11, &this->unk_32C); - func_801518B0(globalCtx, this->unk_464, &this->actor); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 11, &this->unk_32C); + Message_StartTextbox(globalCtx, this->textId, &this->actor); } break; } @@ -400,11 +381,11 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { break; case 3: - if (globalCtx->msgCtx.unk11F04 == 0x80B) { + if (globalCtx->msgCtx.currentTextId == 0x80B) { switch (this->unk_32C) { case 16: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 9, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 9, &this->unk_32C); } Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, this->unk_460), 0x71C); @@ -413,7 +394,7 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { case 10: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { func_801477B4(globalCtx); - func_8013E1C8(&this->skelAnime, sAnimations, 0xD, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); func_80A71B68(this, globalCtx); } break; @@ -424,26 +405,26 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { case 4: case 5: case 6: - switch (globalCtx->msgCtx.unk11F04) { + switch (globalCtx->msgCtx.currentTextId) { case 0x80B: switch (this->unk_32C) { case 16: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 9, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 9, &this->unk_32C); } break; case 9: - if (func_80147624(globalCtx)) { - func_8013E1C8(&this->skelAnime, sAnimations, 10, &this->unk_32C); - globalCtx->msgCtx.unk11F22 = 0x44; + if (Message_ShouldAdvance(globalCtx)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 10, &this->unk_32C); + globalCtx->msgCtx.msgMode = 0x44; } break; case 10: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { func_801477B4(globalCtx); - func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); func_80A71B68(this, globalCtx); } break; @@ -451,38 +432,38 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { break; case 0x80C: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x80D); } break; case 0x80D: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x80E); } break; case 0x80E: if (this->unk_32C == 11) { - func_8013E1C8(&this->skelAnime, sAnimations, 3, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 3, &this->unk_32C); } else if (this->unk_32C == 3) { if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 13, &this->unk_32C); } - } else if ((this->unk_32C == 13) && func_80147624(globalCtx)) { + } else if ((this->unk_32C == 13) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); func_80A71B68(this, globalCtx); } break; case 0x80F: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x810); } break; case 0x810: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->unk_3B0 |= 0x20; func_801477B4(globalCtx); func_80A71B68(this, globalCtx); @@ -491,19 +472,19 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { switch (this->unk_32C) { case 11: - func_8013E1C8(&this->skelAnime, sAnimations, 15, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 15, &this->unk_32C); break; case 15: if (this->skelAnime.curFrame == this->skelAnime.endFrame) { - func_8013E1C8(&this->skelAnime, sAnimations, 6, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 6, &this->unk_32C); } break; } break; case 0x811: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); func_80A71B68(this, globalCtx); } @@ -515,7 +496,7 @@ void func_80A71F18(EnDno* this, GlobalContext* globalCtx) { void func_80A72438(EnDno* this, GlobalContext* globalCtx) { this->unk_452 = 1; - func_8013E1C8(&this->skelAnime, sAnimations, 14, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C); this->actor.textId = 0; if (Flags_GetSwitch(globalCtx, ENDNO_GET_3F80(&this->actor))) { this->unk_454 = 1.0f; @@ -528,7 +509,7 @@ void func_80A724B8(EnDno* this, GlobalContext* globalCtx) { func_80A71424(&this->unk_466, 0, this->actor.yawTowardsPlayer, this->actor.home.rot.y, 0x2000, 0x2D8); } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80A725E0(this, globalCtx); } else if (this->actor.xzDistToPlayer < 60.0f) { func_800B8614(&this->actor, globalCtx, 60.0f); @@ -536,11 +517,11 @@ void func_80A724B8(EnDno* this, GlobalContext* globalCtx) { } void func_80A7256C(EnDno* this, GlobalContext* globalCtx) { - func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.yDistToPlayer, -1); + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, EXCH_ITEM_MINUS1); } void func_80A72598(EnDno* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80A725E0(this, globalCtx); } else { func_80A7256C(this, globalCtx); @@ -555,35 +536,35 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { s32 pad[2]; func_80A71424(&this->unk_466, 0, 0, 0, 0x2000, 0x16C); - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: switch (this->unk_328) { case 0: if (this->unk_32C == 14) { if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x2D8)) { - func_8013E1C8(&this->skelAnime, sAnimations, 5, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 5, &this->unk_32C); } } else if ((this->unk_32C == 5) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { if (Flags_GetSwitch(globalCtx, ENDNO_GET_3F80(&this->actor))) { - func_801518B0(globalCtx, 0x801, &this->actor); - } else if (Player_GetMask(globalCtx) == PLAYER_MASK_MASK_OF_SCENTS) { - func_801518B0(globalCtx, 0x806, &this->actor); + Message_StartTextbox(globalCtx, 0x801, &this->actor); + } else if (Player_GetMask(globalCtx) == PLAYER_MASK_SCENTS) { + Message_StartTextbox(globalCtx, 0x806, &this->actor); } else { - func_801518B0(globalCtx, 0x800, &this->actor); + Message_StartTextbox(globalCtx, 0x800, &this->actor); } - func_8013E1C8(&this->skelAnime, sAnimations, 14, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C); } break; case 2: if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x2D8)) { - gSaveContext.weekEventReg[93] |= 2; - func_801518B0(globalCtx, 0x802, &this->actor); + gSaveContext.save.weekEventReg[93] |= 2; + Message_StartTextbox(globalCtx, 0x802, &this->actor); } break; case 3: - func_801518B0(globalCtx, 0x804, &this->actor); + Message_StartTextbox(globalCtx, 0x804, &this->actor); break; } break; @@ -591,13 +572,13 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { case 1: case 2: case 3: - if (((globalCtx->msgCtx.unk11F04 == 0x800) || (globalCtx->msgCtx.unk11F04 == 0x801)) && + if (((globalCtx->msgCtx.currentTextId == 0x800) || (globalCtx->msgCtx.currentTextId == 0x801)) && (this->unk_32C == 8)) { Math_SmoothStepToF(&this->unk_454, 1.0f, 1.0f, 0.1f, 0.01f); if (this->skelAnime.curFrame <= 23.0f) { this->unk_452 = 3; if (Animation_OnFrame(&this->skelAnime, 23.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_OPEN_AMBRELLA); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OPEN_AMBRELLA); } } else if (this->skelAnime.curFrame <= 24.0f) { this->unk_452 = 4; @@ -606,8 +587,8 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - func_8013E1C8(&this->skelAnime, sAnimations, 12, &this->unk_32C); - func_801518B0(globalCtx, 0x803, &this->actor); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 12, &this->unk_32C); + Message_StartTextbox(globalCtx, 0x803, &this->actor); } } break; @@ -615,40 +596,40 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { case 4: case 5: case 6: - switch (globalCtx->msgCtx.unk11F04) { + switch (globalCtx->msgCtx.currentTextId) { case 0x800: case 0x801: - if (func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x44; + if (Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x44; this->unk_452 = 1; this->unk_454 = 0.0f; - func_8013E1C8(&this->skelAnime, sAnimations, 8, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 8, &this->unk_32C); } break; case 0x802: - if (func_80147624(globalCtx)) { - if (gSaveContext.inventory.items[D_801C20C0] == ITEM_MASK_SCENTS) { - this->unk_458 = 4; + if (Message_ShouldAdvance(globalCtx)) { + if (INV_CONTENT(ITEM_MASK_SCENTS) == ITEM_MASK_SCENTS) { + this->unk_458 = GI_RUPEE_RED; } else { - this->unk_458 = 142; + this->unk_458 = GI_MASK_SCENTS; } - func_800B8A1C(&this->actor, globalCtx, this->unk_458, 60.0f, 60.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk_458, 60.0f, 60.0f); func_801477B4(globalCtx); func_80A72B84(this, globalCtx); } break; case 0x803: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80A72AE4(this, globalCtx); } break; case 0x804: if (this->unk_32C == 14) { - if (func_80147624(globalCtx)) { - func_8013E1C8(&this->skelAnime, sAnimations, 5, &this->unk_32C); + if (Message_ShouldAdvance(globalCtx)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 5, &this->unk_32C); if (!(this->unk_3B0 & 0x40)) { func_80A72CF8(this, globalCtx); this->unk_3B0 |= 0x40; @@ -661,7 +642,7 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { break; case 0x806: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x800); } break; @@ -675,7 +656,7 @@ void func_80A725F8(EnDno* this, GlobalContext* globalCtx) { } void func_80A72AE4(EnDno* this, GlobalContext* globalCtx) { - func_8013E1C8(&this->skelAnime, sAnimations, 0, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->unk_32C); func_80A714B4(this, globalCtx); this->actionFunc = func_80A72B3C; } @@ -697,21 +678,23 @@ void func_80A72BA4(EnDno* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_80A72598; } else { - func_800B8A1C(&this->actor, globalCtx, this->unk_458, 60.0f, 60.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk_458, 60.0f, 60.0f); } } void func_80A72C04(EnDno* this, GlobalContext* globalCtx) { - func_8013E1C8(&this->skelAnime, sAnimations, 0, &this->unk_32C); - this->actor.flags |= 0x8000000; - this->actor.flags &= ~(8 | 1); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->unk_32C); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); Math_Vec3f_Copy(&this->unk_334, &this->actor.world.pos); - func_8013DCE0(globalCtx, &this->unk_334, &this->actor, &this->unk_340, globalCtx->setupPathList, - ENDNO_GET_7F(&this->actor), 1, 0, 1, 0); - func_8013DF3C(globalCtx, &this->unk_340); - this->actor.world.rot.y = this->unk_340.unk_56; - this->actor.world.rot.x = this->unk_340.unk_54; - Actor_SetSwitchFlag(globalCtx, ENDNO_GET_3F80(&this->actor)); + SubS_ActorPathing_Init(globalCtx, &this->unk_334, &this->actor, &this->actorPath, globalCtx->setupPathList, + ENDNO_GET_7F(&this->actor), 1, 0, 1, 0); + SubS_ActorPathing_ComputePointInfo(globalCtx, &this->actorPath); + + this->actor.world.rot.y = this->actorPath.rotToCurPoint.y; + this->actor.world.rot.x = this->actorPath.rotToCurPoint.x; + + Flags_SetSwitch(globalCtx, ENDNO_GET_3F80(&this->actor)); this->actionFunc = func_80A730A0; } @@ -721,8 +704,8 @@ void func_80A72CF8(EnDno* this, GlobalContext* globalCtx) { this->actor.floorHeight, this->actor.world.pos.z, 0, 0, 0, 0x201); } -s32 func_80A72D8C(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1) { - Actor* actor = arg1->unk_48; +s32 EnDno_ActorPathing_UpdateActorInfo(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor* thisx = actorPath->actor; s32 pad; s32 ret = false; f32 sp38; @@ -730,52 +713,52 @@ s32 func_80A72D8C(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1) { s32 temp_v0_2; s32 sp2C; - actor->gravity = 0.0f; - temp_v0 = actor->yawTowardsPlayer - actor->world.rot.y; + thisx->gravity = 0.0f; + temp_v0 = thisx->yawTowardsPlayer - thisx->world.rot.y; if ((temp_v0 <= 0x4000) && (temp_v0 >= -0x4000)) { - Math_SmoothStepToF(&actor->speedXZ, 15.0f, 0.8f, 1.0f, 0.01f); + Math_SmoothStepToF(&thisx->speedXZ, 15.0f, 0.8f, 1.0f, 0.01f); } else { - if (actor->xzDistToPlayer <= 80.0f) { - Math_SmoothStepToF(&actor->speedXZ, 8.0f, 0.5f, 0.5f, 0.01f); - } else if (actor->xzDistToPlayer <= 360.0f) { - Math_SmoothStepToF(&actor->speedXZ, 7.0f, 0.5f, 0.5f, 0.01f); + if (thisx->xzDistToPlayer <= 80.0f) { + Math_SmoothStepToF(&thisx->speedXZ, 8.0f, 0.5f, 0.5f, 0.01f); + } else if (thisx->xzDistToPlayer <= 360.0f) { + Math_SmoothStepToF(&thisx->speedXZ, 7.0f, 0.5f, 0.5f, 0.01f); } else { - Math_SmoothStepToF(&actor->speedXZ, 3.5f, 0.5f, 0.5f, 0.01f); + Math_SmoothStepToF(&thisx->speedXZ, 3.5f, 0.5f, 0.5f, 0.01f); } } - if (arg1->unk_50 < SQ(actor->speedXZ)) { + if (actorPath->distSqToCurPoint < SQ(thisx->speedXZ)) { ret = true; } else { - sp38 = actor->speedXZ / sqrtf(arg1->unk_4C); - sp2C = ABS(arg1->unk_54 - actor->world.rot.x); + sp38 = thisx->speedXZ / sqrtf(actorPath->distSqToCurPointXZ); + sp2C = ABS(actorPath->rotToCurPoint.x - thisx->world.rot.x); temp_v0_2 = sp2C; temp_v0_2 *= sp38; temp_v0_2 += 0x71C; - sp2C = ABS(arg1->unk_56 - actor->world.rot.y); + sp2C = ABS(actorPath->rotToCurPoint.y - thisx->world.rot.y); - Math_ScaledStepToS(&actor->world.rot.x, arg1->unk_54, temp_v0_2); - Math_ScaledStepToS(&actor->world.rot.y, arg1->unk_56, (s32)(sp2C * sp38) + 0x71C); + Math_ScaledStepToS(&thisx->world.rot.x, actorPath->rotToCurPoint.x, temp_v0_2); + Math_ScaledStepToS(&thisx->world.rot.y, actorPath->rotToCurPoint.y, (s32)(sp2C * sp38) + 0x71C); } return ret; } -s32 func_80A72FAC(GlobalContext* globalCtx, EnDno_ActorUnkStruct* arg1) { - Actor* actor = arg1->unk_48; - EnDno* dno = (EnDno*)actor; - f32 sp24 = Math_CosS(-actor->world.rot.x) * actor->speedXZ; +s32 EnDno_ActorPathing_Move(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor* thisx = actorPath->actor; + EnDno* this = (EnDno*)thisx; + f32 sp24 = Math_CosS(-thisx->world.rot.x) * thisx->speedXZ; f32 sp20 = gFramerateDivisorHalf; - actor->velocity.x = Math_SinS(actor->world.rot.y) * sp24; - actor->velocity.y = Math_SinS(-actor->world.rot.x) * actor->speedXZ; - actor->velocity.z = Math_CosS(actor->world.rot.y) * sp24; + thisx->velocity.x = Math_SinS(thisx->world.rot.y) * sp24; + thisx->velocity.y = Math_SinS(-thisx->world.rot.x) * thisx->speedXZ; + thisx->velocity.z = Math_CosS(thisx->world.rot.y) * sp24; - dno->unk_334.x += (dno->actor.velocity.x * sp20) + dno->actor.colChkInfo.displacement.x; - dno->unk_334.y += (dno->actor.velocity.y * sp20) + dno->actor.colChkInfo.displacement.y; - dno->unk_334.z += (dno->actor.velocity.z * sp20) + dno->actor.colChkInfo.displacement.z; + this->unk_334.x += (this->actor.velocity.x * sp20) + this->actor.colChkInfo.displacement.x; + this->unk_334.y += (this->actor.velocity.y * sp20) + this->actor.colChkInfo.displacement.y; + this->unk_334.z += (this->actor.velocity.z * sp20) + this->actor.colChkInfo.displacement.z; - return 0; + return false; } void func_80A730A0(EnDno* this, GlobalContext* globalCtx) { @@ -799,15 +782,17 @@ void func_80A730A0(EnDno* this, GlobalContext* globalCtx) { } if (phi_a2 >= 0) { - func_8013E1C8(&this->skelAnime, sAnimations, phi_a2, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, phi_a2, &this->unk_32C); } } - func_8013DE04(globalCtx, &this->unk_340, func_8013DF3C, func_80A72D8C, func_80A72FAC, func_8013E0A4); + SubS_ActorPathing_Update(globalCtx, &this->actorPath, SubS_ActorPathing_ComputePointInfo, + EnDno_ActorPathing_UpdateActorInfo, EnDno_ActorPathing_Move, + SubS_ActorPathing_SetNextPoint); this->unk_45C += 6553; - this->unk_340.unk_2C.x = 0.0f; - this->unk_340.unk_2C.y = 0.0f; - this->unk_340.unk_2C.z = 0.0f; + this->actorPath.pointOffset.x = 0.0f; + this->actorPath.pointOffset.y = 0.0f; + this->actorPath.pointOffset.z = 0.0f; Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_334); temp_f10 = (4.0f + Math_SinS(this->unk_3AE)) * Math_SinS(this->unk_3AC); this->actor.world.pos.y += temp_f10; @@ -815,9 +800,9 @@ void func_80A730A0(EnDno* this, GlobalContext* globalCtx) { this->unk_3AE += 1000; this->actor.shape.rot.y = this->actor.yawTowardsPlayer; func_80A715DC(this, globalCtx); - func_800B9010(&this->actor, 0x2153); - if (this->unk_340.unk_1C & 0x20) { - Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_340.unk_20); + func_800B9010(&this->actor, NA_SE_EV_BUTLER_FRY - SFX_FLAG); + if (this->actorPath.flags & ACTOR_PATHING_REACHED_END_PERMANENT) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actorPath.curPoint); this->actor.speedXZ = 0.0f; this->actor.velocity.x = 0.0f; this->actor.velocity.y = 0.0f; @@ -827,11 +812,11 @@ void func_80A730A0(EnDno* this, GlobalContext* globalCtx) { } void func_80A73244(EnDno* this, GlobalContext* globalCtx) { - this->actor.flags &= ~0x8000000; - this->actor.flags |= (8 | 1); + this->actor.flags &= ~ACTOR_FLAG_8000000; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); this->unk_328 = 2; this->actor.speedXZ = 0.0f; - Actor_UnsetSwitchFlag(globalCtx, ENDNO_GET_3F80(&this->actor)); + Flags_UnsetSwitch(globalCtx, ENDNO_GET_3F80(&this->actor)); gSaveContext.unk_3DD0[1] = 5; this->unk_44E = 0; this->actionFunc = func_80A732C8; @@ -844,11 +829,11 @@ void func_80A732C8(EnDno* this, GlobalContext* globalCtx) { if (Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x71C)) { this->unk_3B0 |= 4; this->unk_44E = 3; - func_8013E1C8(&this->skelAnime, sAnimations, 7, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 7, &this->unk_32C); } } else if (this->unk_44E == 3) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - func_8013E1C8(&this->skelAnime, sAnimations, 14, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 14, &this->unk_32C); func_80A72438(this, globalCtx); } else { if (this->skelAnime.curFrame >= 20.0f) { @@ -856,25 +841,25 @@ void func_80A732C8(EnDno* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 4.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOSE_AMBRELLA); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CLOSE_AMBRELLA); this->unk_452 = 4; } else if (Animation_OnFrame(&this->skelAnime, 5.0f)) { this->unk_452 = 3; } } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80A73408(EnDno* this, GlobalContext* globalCtx) { s32 phi_a2; u8 sp33 = true; - u32 temp_v0; + s32 temp_v0; - if (func_800EE29C(globalCtx, 0x1DB)) { - temp_v0 = func_800EE200(globalCtx, 0x1DB); - if (this->unk_468 != globalCtx->csCtx.npcActions[temp_v0]->unk0) { - switch (globalCtx->csCtx.npcActions[temp_v0]->unk0) { + if (Cutscene_CheckActorAction(globalCtx, 475)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, 475); + if (this->unk_468 != globalCtx->csCtx.actorActions[temp_v0]->action) { + switch (globalCtx->csCtx.actorActions[temp_v0]->action) { case 1: phi_a2 = 13; break; @@ -890,15 +875,15 @@ void func_80A73408(EnDno* this, GlobalContext* globalCtx) { } if (sp33) { - func_8013E1C8(&this->skelAnime, sAnimations, phi_a2, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, phi_a2, &this->unk_32C); } } - func_800EDF24(&this->actor, globalCtx, temp_v0); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, temp_v0); } if ((Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) && (this->unk_32C == 17)) { if (0) {}; - func_8013E1C8(&this->skelAnime, sAnimations, 18, &this->unk_32C); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 18, &this->unk_32C); } } @@ -914,7 +899,7 @@ void EnDno_Update(Actor* thisx, GlobalContext* globalCtx) { } Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - Actor_SetHeight(&this->actor, 51.0f); + Actor_SetFocus(&this->actor, 51.0f); } void EnDno_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -985,7 +970,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_RotateXS(this->unk_45C, MTXMODE_APPLY); } gfxOpa = POLY_OPA_DISP; @@ -1001,13 +986,13 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); + Matrix_Push(); frames = globalCtx->gameplayFrames; - Matrix_MultiplyVector3fByState(&D_80A73B40, &sp84); + Matrix_MultVec3f(&D_80A73B40, &sp84); func_80A711D0(this, globalCtx, &sp84); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(0.15f, 0.15f, 1.0f, MTXMODE_APPLY); - Matrix_InsertTranslation(0.0f, -3200.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, -3200.0f, 0.0f, MTXMODE_APPLY); gfxXlu = func_8012C2B4(POLY_XLU_DISP); gSPMatrix(gfxXlu, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -1015,11 +1000,11 @@ 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; - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.h b/src/overlays/actors/ovl_En_Dno/z_en_dno.h index a99162694..dcffee6c9 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.h +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.h @@ -7,7 +7,7 @@ struct EnDno; typedef void (*EnDnoActionFunc)(struct EnDno*, GlobalContext*); -#define ENDNO_GET_F(thisx) (u32)((thisx)->params & 0xF) +#define ENDNO_GET_F(thisx) ((thisx)->params & 0xF) #define ENDNO_GET_7F(thisx) ((thisx)->params & 0x7F) #define ENDNO_GET_7F0(thisx) (((thisx)->params >> 4) & 0x7F) #define ENDNO_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F) @@ -34,7 +34,7 @@ typedef struct EnDno { /* 0x32C */ s32 unk_32C; /* 0x330 */ UNK_TYPE1 unk_330[0x4]; /* 0x334 */ Vec3f unk_334; - /* 0x340 */ EnDno_ActorUnkStruct unk_340; + /* 0x340 */ ActorPathing actorPath; /* 0x3AC */ s16 unk_3AC; /* 0x3AE */ s16 unk_3AE; /* 0x3B0 */ u16 unk_3B0; @@ -51,7 +51,7 @@ typedef struct EnDno { /* 0x458 */ s32 unk_458; /* 0x45C */ s16 unk_45C; /* 0x460 */ Actor* unk_460; - /* 0x464 */ u16 unk_464; + /* 0x464 */ u16 textId; /* 0x466 */ s16 unk_466; /* 0x468 */ u8 unk_468; } EnDno; // size = 0x46C 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 7477bbcc5..a4ea26f37 100644 --- a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c +++ b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c @@ -5,8 +5,9 @@ */ #include "z_en_dnp.h" +#include "objects/object_dnp/object_dnp.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnDnp*)thisx) @@ -21,35 +22,6 @@ void func_80B3D338(EnDnp* this, GlobalContext* globalCtx); void func_80B3D3F8(EnDnp* this, GlobalContext* globalCtx); void func_80B3D558(EnDnp* this, GlobalContext* globalCtx); -extern AnimationHeader D_060007D8; -extern AnimationHeader D_0600125C; -extern AnimationHeader D_060017F8; -extern AnimationHeader D_06001C1C; -extern AnimationHeader D_060021DC; -extern AnimationHeader D_060026B8; -extern AnimationHeader D_06004D08; -extern AnimationHeader D_060057AC; -extern AnimationHeader D_0600625C; -extern AnimationHeader D_0600674C; -extern AnimationHeader D_06006B74; -extern AnimationHeader D_060071F4; -extern AnimationHeader D_06007960; -extern AnimationHeader D_06008588; -extern AnimationHeader D_0600923C; -extern AnimationHeader D_06009AA0; -extern AnimationHeader D_0600A900; -extern AnimationHeader D_0600AEB8; -extern AnimationHeader D_0600B324; -extern AnimationHeader D_0600B754; -extern AnimationHeader D_0600BAD8; -extern Gfx D_060103D0[]; -extern Gfx D_060105D0[]; -extern Gfx D_060107D0[]; -extern Gfx D_060109D0[]; -extern FlexSkeletonHeader D_06010D60; -extern AnimationHeader D_060115B8; -extern AnimationHeader D_06012428; - const ActorInit En_Dnp_InitVars = { ACTOR_EN_DNP, ACTORCAT_NPC, @@ -84,16 +56,33 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -static ActorAnimationEntryS sAnimations[] = { - { &D_060007D8, 1.0f, 0, -1, 2, -4 }, { &D_060021DC, 1.0f, 0, -1, 0, 0 }, { &D_060021DC, 1.0f, 0, -1, 0, -4 }, - { &D_060026B8, 1.0f, 0, -1, 2, -4 }, { &D_06004D08, 1.0f, 0, -1, 2, -4 }, { &D_060071F4, 1.0f, 0, -1, 2, -4 }, - { &D_06007960, 1.0f, 0, -1, 0, -4 }, { &D_06008588, 1.0f, 0, -1, 2, 0 }, { &D_0600A900, 1.0f, 0, -1, 0, -4 }, - { &D_0600AEB8, 1.0f, 0, -1, 0, -4 }, { &D_0600B754, 1.0f, 0, -1, 2, -4 }, { &D_0600674C, 1.0f, 0, -1, 0, -4 }, - { &D_0600BAD8, 1.0f, 0, -1, 2, -4 }, { &D_06006B74, 1.0f, 0, -1, 0, -4 }, { &D_06012428, 1.0f, 0, -1, 0, -4 }, - { &D_0600B324, 1.0f, 0, -1, 0, 0 }, { &D_0600B324, 1.0f, 0, -1, 0, -4 }, { &D_060115B8, 1.0f, 0, -1, 0, -4 }, - { &D_060115B8, 1.0f, 0, -1, 0, 0 }, { &D_0600923C, 1.0f, 0, -1, 2, -4 }, { &D_06009AA0, 1.0f, 0, -1, 0, -4 }, - { &D_0600125C, 1.0f, 0, -1, 2, -4 }, { &D_060017F8, 1.0f, 0, -1, 2, 0 }, { &D_06001C1C, 1.0f, 0, -1, 0, -4 }, - { &D_060057AC, 1.0f, 0, -1, 2, 0 }, { &D_0600625C, 1.0f, 0, -1, 0, -4 }, +static AnimationInfoS sAnimations[] = { + { &object_dnp_Anim_0007D8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_0021DC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnp_Anim_0021DC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_0026B8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_004D08, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_0071F4, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_007960, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_008588, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnp_Anim_00A900, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_00AEB8, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_00B754, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_00674C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_00BAD8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_006B74, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_012428, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_00B324, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnp_Anim_00B324, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_0115B8, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_0115B8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnp_Anim_00923C, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_009AA0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_00125C, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnp_Anim_0017F8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnp_Anim_001C1C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnp_Anim_0057AC, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnp_Anim_00625C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, }; static s32 D_80B3DE58[] = { @@ -104,37 +93,37 @@ s32 func_80B3CA20(EnDnp* this) { if ((this->unk_340 == 2) || (this->unk_340 == 9)) { if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 5.0f) || Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_TURN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_TURN); } } else if ((this->unk_340 == 24) || (this->unk_340 == 7)) { if (Animation_OnFrame(&this->skelAnime, 1.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_TURN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_TURN); } } else if (this->unk_340 == 14) { if (Animation_OnFrame(&this->skelAnime, 7.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_GREET); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_GREET); } if (Animation_OnFrame(&this->skelAnime, 22.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_GREET2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_GREET2); } } else if (this->unk_340 == 8) { if (Animation_OnFrame(&this->skelAnime, 9.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_GREET); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_GREET); } if (Animation_OnFrame(&this->skelAnime, 18.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_GREET2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_GREET2); } } else if ((this->unk_340 == 17) && (this->unk_340 == 18)) { if (Animation_OnFrame(&this->skelAnime, 7.0f) || Animation_OnFrame(&this->skelAnime, 15.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_WALK); } } else if (this->unk_340 == 21) { if (Animation_OnFrame(&this->skelAnime, 17.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_WALK); } } else if (this->unk_340 == 23) { if (Animation_OnFrame(&this->skelAnime, 3.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DEKUHIME_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKUHIME_WALK); } } @@ -146,7 +135,7 @@ s32 func_80B3CC38(EnDnp* this, s32 arg1) { if (arg1 != this->unk_340) { this->unk_340 = arg1; - ret = func_8013BC6C(&this->skelAnime, sAnimations, arg1); + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); } return ret; @@ -212,13 +201,13 @@ s32 func_80B3CEC0(EnDnp* this, GlobalContext* globalCtx) { s32 func_80B3CF60(EnDnp* this, GlobalContext* globalCtx) { s32 ret = false; - if ((this->unk_322 & 7) && func_800B84D0(&this->actor, globalCtx)) { - func_8013AED4(&this->unk_322, 0, 7); + if ((this->unk_322 & 7) && Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_322, 0, 7); this->unk_322 |= 8; this->actionFunc = func_80B3D3F8; ret = true; - } else if (!(gSaveContext.weekEventReg[23] & 0x20) && Actor_HasParent(&this->actor, globalCtx)) { - func_8013AED4(&this->unk_322, 0, 7); + } else if (!(gSaveContext.save.weekEventReg[23] & 0x20) && Actor_HasParent(&this->actor, globalCtx)) { + SubS_UpdateFlags(&this->unk_322, 0, 7); this->unk_322 &= ~0x500; this->actor.parent = NULL; this->unk_32E = 0; @@ -235,15 +224,15 @@ s32 func_80B3D044(EnDnp* this, GlobalContext* globalCtx) { if (globalCtx->csCtx.state != 0) { if (!(this->unk_322 & 0x200)) { this->unk_322 |= (0x200 | 0x10); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_324 = 0xFF; } - func_8013AED4(&this->unk_322, 0, 7); + SubS_UpdateFlags(&this->unk_322, 0, 7); this->actionFunc = func_80B3D11C; ret = true; } else if (this->unk_322 & 0x200) { - this->actor.flags |= 1; - func_8013AED4(&this->unk_322, 3, 7); + this->actor.flags |= ACTOR_FLAG_1; + SubS_UpdateFlags(&this->unk_322, 3, 7); this->unk_322 &= ~(0x200 | 0x10); this->actionFunc = func_80B3D2D4; } @@ -255,18 +244,18 @@ void func_80B3D11C(EnDnp* this, GlobalContext* globalCtx) { static s32 D_80B3DE74[] = { 0, 16, 14, 10, 18, 12, 5, 7, 2, 19, 21, 22, 24, 8, }; - u32 temp_v0; + s32 temp_v0; s32 val; - if (!(gSaveContext.weekEventReg[29] & 0x40) && (globalCtx->sceneNum == SCENE_MITURIN) && - (globalCtx->csCtx.unk_12 == 0)) { + if (!(gSaveContext.save.weekEventReg[29] & 0x40) && (globalCtx->sceneNum == SCENE_MITURIN) && + (globalCtx->csCtx.currentCsIndex == 0)) { this->unk_322 |= 0x20; - gSaveContext.weekEventReg[29] |= 0x40; + gSaveContext.save.weekEventReg[29] |= 0x40; } - if (func_800EE29C(globalCtx, 0x65)) { - temp_v0 = func_800EE200(globalCtx, 0x65); - val = globalCtx->csCtx.npcActions[temp_v0]->unk0; + if (Cutscene_CheckActorAction(globalCtx, 101)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, 101); + val = globalCtx->csCtx.actorActions[temp_v0]->action; if (this->unk_324 != (u8)val) { func_80B3CC38(this, D_80B3DE74[val]); if (this->unk_340 == 16) { @@ -276,7 +265,7 @@ void func_80B3D11C(EnDnp* this, GlobalContext* globalCtx) { } if (this->unk_340 == 19) { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_DHVO04); + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_DHVO04); } if (this->unk_340 == 24) { @@ -292,7 +281,7 @@ void func_80B3D11C(EnDnp* this, GlobalContext* globalCtx) { Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { func_80B3CC38(this, this->unk_340 + 1); } - func_800EDF24(&this->actor, globalCtx, temp_v0); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, temp_v0); } } @@ -307,22 +296,22 @@ void func_80B3D2D4(EnDnp* this, GlobalContext* globalCtx) { void func_80B3D338(EnDnp* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((this->unk_32E != 0) && (func_80152498(&globalCtx->msgCtx) == 2)) { + if ((this->unk_32E != 0) && (Message_GetState(&globalCtx->msgCtx) == 2)) { Actor_MarkForDeath(&this->actor); } else if (this->unk_32E == 0) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->unk_32E = 1; } else { this->actor.textId = 0x971; player->actor.textId = this->actor.textId; - func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, -1); + func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, EXCH_ITEM_MINUS1); } } } void func_80B3D3F8(EnDnp* this, GlobalContext* globalCtx) { if (func_8010BF58(&this->actor, globalCtx, D_80B3DE58, NULL, &this->unk_328)) { - func_8013AED4(&this->unk_322, 3, 7); + SubS_UpdateFlags(&this->unk_322, 3, 7); this->unk_322 &= ~8; this->actionFunc = func_80B3D2D4; } else { @@ -334,8 +323,8 @@ void func_80B3D47C(EnDnp* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 1) { Math_SmoothStepToF(&this->actor.scale.x, 0.0085f, 0.1f, 0.01f, 0.001f); if ((s32)(this->actor.scale.x * 10000.0f) >= 85) { - this->actor.flags |= 1; - func_8013AED4(&this->unk_322, 3, 7); + this->actor.flags |= ACTOR_FLAG_1; + SubS_UpdateFlags(&this->unk_322, 3, 7); this->unk_322 &= ~0x10; this->unk_322 |= 0x400; this->actor.scale.x = 0.0085f; @@ -348,7 +337,7 @@ void func_80B3D47C(EnDnp* this, GlobalContext* globalCtx) { void func_80B3D558(EnDnp* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); - gSaveContext.weekEventReg[23] |= 0x20; + gSaveContext.save.weekEventReg[23] |= 0x20; } else { ActorCutscene_SetIntentToPlay(this->actor.cutscene); } @@ -357,8 +346,9 @@ void func_80B3D558(EnDnp* this, GlobalContext* globalCtx) { void EnDnp_Init(Actor* thisx, GlobalContext* globalCtx) { EnDnp* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 16.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06010D60, NULL, this->jointTable, this->morphTable, 26); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 16.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dnp_Skel_010D60, NULL, this->jointTable, this->morphTable, + 26); this->unk_340 = -1; func_80B3CC38(this, 15); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); @@ -368,20 +358,20 @@ void EnDnp_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_322 |= (0x100 | 0x80 | 0x10); this->actor.gravity = -1.0f; if (ENDNP_GET_7(&this->actor) == ENDNP_GET_7_1) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; Actor_SetScale(&this->actor, 0.00085000007f); - func_8013AED4(&this->unk_322, 0, 7); + SubS_UpdateFlags(&this->unk_322, 0, 7); this->actor.shape.rot.x = 0; this->actor.world.rot.x = this->actor.shape.rot.x; this->actor.cutscene = 0x10; this->actionFunc = func_80B3D47C; - } else if (((ENDNP_GET_7(&this->actor) == ENDNP_GET_7_0) && !func_80114F2C(0x17) && - !(gSaveContext.weekEventReg[23] & 0x20)) || - ((ENDNP_GET_7(&this->actor) == ENDNP_GET_7_2) && (gSaveContext.weekEventReg[23] & 0x20))) { + } else if (((ENDNP_GET_7(&this->actor) == ENDNP_GET_7_0) && !Interface_HasItemInBottle(ITEM_DEKU_PRINCESS) && + !(gSaveContext.save.weekEventReg[23] & 0x20)) || + ((ENDNP_GET_7(&this->actor) == ENDNP_GET_7_2) && (gSaveContext.save.weekEventReg[23] & 0x20))) { Actor_SetScale(&this->actor, 0.0085f); - func_8013AED4(&this->unk_322, 3, 7); + SubS_UpdateFlags(&this->unk_322, 3, 7); this->unk_322 |= 0x400; - if ((globalCtx->sceneNum == SCENE_MITURIN) && (gSaveContext.weekEventReg[29] & 0x40)) { + if ((globalCtx->sceneNum == SCENE_MITURIN) && (gSaveContext.save.weekEventReg[29] & 0x40)) { this->unk_322 |= 0x20; func_80B3CC38(this, 1); } @@ -413,15 +403,15 @@ void EnDnp_Update(Actor* thisx, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); func_80B3CD1C(this); func_80B3CEC0(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); sp2C = this->collider.dim.radius + 50; sp28 = this->collider.dim.height + 30; - if ((this->unk_322 & 0x400) && !(gSaveContext.weekEventReg[23] & 0x20)) { - func_800B8A1C(&this->actor, globalCtx, 0xBA, sp2C, sp28); + if ((this->unk_322 & 0x400) && !(gSaveContext.save.weekEventReg[23] & 0x20)) { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, sp2C, sp28); } - func_8013C964(&this->actor, globalCtx, sp2C, sp28, 0, this->unk_322 & 7); - Actor_SetHeight(&this->actor, 30.0f); + func_8013C964(&this->actor, globalCtx, sp2C, sp28, EXCH_ITEM_NONE, this->unk_322 & 7); + Actor_SetFocus(&this->actor, 30.0f); func_80B3CC80(this, globalCtx); } @@ -435,9 +425,9 @@ 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_CopyCurrentState(&sp2C); - func_8018219C(&sp2C, &sp6C, 0); + Matrix_MultVec3f(&gZeroVec3f, &sp74); + Matrix_Get(&sp2C); + Matrix_MtxFToYXZRot(&sp2C, &sp6C, false); *arg2 = sp74; if (arg4 == 0) { if (arg5 != 0) { @@ -456,10 +446,10 @@ s32 func_80B3D974(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar return 1; } -void func_80B3DA88(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnDnp_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80B3DAA0(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnDnp_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnDnp* this = THIS; s32 phi_v1 = 1; s32 phi_v0; @@ -478,22 +468,22 @@ void func_80B3DAA0(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { if (limbIndex == 12) { func_80B3D974(this->unk_330 + 0x4000, this->unk_332 + this->actor.shape.rot.y + 0x4000, &this->unk_1D8, &this->unk_1E4, phi_v1, phi_v0); - Matrix_StatePop(); - Matrix_InsertTranslation(this->unk_1D8.x, this->unk_1D8.y, this->unk_1D8.z, MTXMODE_NEW); + Matrix_Pop(); + Matrix_Translate(this->unk_1D8.x, this->unk_1D8.y, this->unk_1D8.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - Matrix_RotateY(this->unk_1E4.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_1E4.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_1E4.z, MTXMODE_APPLY); - Matrix_StatePush(); + Matrix_RotateYS(this->unk_1E4.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1E4.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1E4.z, MTXMODE_APPLY); + Matrix_Push(); } } void EnDnp_Draw(Actor* thisx, GlobalContext* globalCtx) { - static Gfx* D_80B3DEAC[] = { - D_060103D0, - D_060105D0, - D_060107D0, - D_060109D0, + static TexturePtr D_80B3DEAC[] = { + object_dnp_Tex_0103D0, + object_dnp_Tex_0105D0, + object_dnp_Tex_0107D0, + object_dnp_Tex_0109D0, }; EnDnp* this = THIS; @@ -504,8 +494,9 @@ void EnDnp_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3DEAC[this->unk_336])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, - func_80B3DA88, func_80B3DAA0, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnDnp_PostLimbDraw, EnDnp_TransformLimbDraw, + &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Dnq/z_en_dnq.c b/src/overlays/actors/ovl_En_Dnq/z_en_dnq.c index e392e6d60..ae7f918f1 100644 --- a/src/overlays/actors/ovl_En_Dnq/z_en_dnq.c +++ b/src/overlays/actors/ovl_En_Dnq/z_en_dnq.c @@ -5,8 +5,9 @@ */ #include "z_en_dnq.h" +#include "objects/object_dnq/object_dnq.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDnq*)thisx) @@ -17,24 +18,6 @@ void EnDnq_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80A52FB8(EnDnq* this, GlobalContext* globalCtx); -extern AnimationHeader D_060006F0; -extern AnimationHeader D_06000BF8; -extern AnimationHeader D_06001100; -extern AnimationHeader D_06001AEC; -extern AnimationHeader D_06002690; -extern AnimationHeader D_06003408; -extern AnimationHeader D_06003DBC; -extern AnimationHeader D_060047B8; -extern AnimationHeader D_06004EA0; -extern AnimationHeader D_06005284; -extern AnimationHeader D_06005A14; -extern AnimationHeader D_06005E18; -extern AnimationHeader D_06006984; -extern AnimationHeader D_06007528; -extern AnimationHeader D_06008328; -extern FlexSkeletonHeader D_0600EB48; -extern AnimationHeader D_0600F504; - static s32 D_80A53400[] = { 0x00120100, 0x150E0899, 0x0C120F08, 0x9A0C0F08, 0x9B0C0F08, 0x9C0C1112, 0x01100E08, 0x980C1000, 0x00120200, 0x0C0E089D, 0x0C0F089E, 0x0C111202, 0x100E089F, 0x0C100000, 0x0E08A10C, 0x0F08A20C, 0x10000000, @@ -74,14 +57,27 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE }; -static ActorAnimationEntryS D_80A5349C[] = { - { &D_06008328, 1.0f, 0, -1, 0, 0 }, { &D_06008328, 1.0f, 0, -1, 0, -4 }, { &D_06007528, 1.0f, 0, -1, 2, -4 }, - { &D_060006F0, 1.0f, 0, -1, 2, 0 }, { &D_06000BF8, 1.0f, 0, -1, 0, -4 }, { &D_06002690, 0.0f, 0, -1, 2, 0 }, - { &D_06002690, 1.0f, 0, -1, 2, -4 }, { &D_06003408, 1.0f, 0, -1, 0, -4 }, { &D_06006984, 1.0f, 0, -1, 2, -4 }, - { &D_06005E18, 1.0f, 0, -1, 2, -4 }, { &D_06005A14, 1.0f, 0, -1, 2, -4 }, { &D_06005284, 1.0f, 0, -1, 2, -4 }, - { &D_06001AEC, 1.0f, 0, -1, 2, 0 }, { &D_06001100, 1.0f, 0, -1, 2, 0 }, { &D_06004EA0, 1.0f, 0, -1, 0, -4 }, - { &D_0600F504, 1.0f, 0, -1, 0, -4 }, { &D_060047B8, 1.0f, 0, -1, 0, -4 }, { &D_06003DBC, 1.0f, 0, -1, 2, -4 }, - { &D_06005A14, 1.0f, 0, -1, 0, -4 }, { &D_06003DBC, 1.0f, 0, -1, 0, -4 }, +static AnimationInfoS D_80A5349C[] = { + { &object_dnq_Anim_008328, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnq_Anim_008328, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_007528, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_0006F0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnq_Anim_000BF8, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_002690, 0.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnq_Anim_002690, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_003408, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_006984, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_005E18, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_005A14, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_005284, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_001AEC, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnq_Anim_001100, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnq_Anim_004EA0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_00F504, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_0047B8, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_003DBC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dnq_Anim_005A14, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnq_Anim_003DBC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, }; void func_80A52530(GlobalContext* globalCtx, EnDnq* this) { @@ -108,7 +104,7 @@ s32 func_80A5257C(EnDnq* this, s32 arg1) { if (phi_v1) { this->unk_398 = arg1; - ret = func_8013BC6C(&this->skelAnime, D_80A5349C, arg1); + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80A5349C, arg1); } return ret; @@ -124,18 +120,18 @@ s32 func_80A52648(EnDnq* this, GlobalContext* globalCtx) { if (globalCtx->csCtx.state != 0) { if (!(this->unk_37C & 0x20)) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_1DC = 0xFF; this->unk_37C |= 0x20; } - func_8013AED4(&this->unk_37C, 0, 7); + SubS_UpdateFlags(&this->unk_37C, 0, 7); ret = true; } else { if (this->unk_37C & 0x20) { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->unk_1DC = 0xFF; this->unk_37C &= ~0x20; - func_8013AED4(&this->unk_37C, 3, 7); + SubS_UpdateFlags(&this->unk_37C, 3, 7); } } @@ -258,7 +254,7 @@ s32 func_80A52A78(EnDnq* this, GlobalContext* globalCtx) { s32 func_80A52B68(EnDnq* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - u16 temp = globalCtx->msgCtx.unk11F04; + u16 temp = globalCtx->msgCtx.currentTextId; if ((player->stateFlags1 & 0x40) && (player->targetActor == &this->actor)) { switch (temp) { @@ -310,7 +306,7 @@ void func_80A52C6C(EnDnq* this, GlobalContext* globalCtx) { } s32* func_80A52CF8(EnDnq* this, GlobalContext* globalCtx) { - if (gSaveContext.weekEventReg[23] & 0x20) { + if (gSaveContext.save.weekEventReg[23] & 0x20) { return &D_80A53400[14]; } @@ -324,8 +320,8 @@ s32* func_80A52CF8(EnDnq* this, GlobalContext* globalCtx) { s32 func_80A52D44(EnDnq* this, GlobalContext* globalCtx) { s32 ret = false; - if ((this->unk_37C & 7) && func_800B84D0(&this->actor, globalCtx)) { - func_8013AED4(&this->unk_37C, 0, 7); + if ((this->unk_37C & 7) && Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_37C, 0, 7); this->unk_380 = func_80A52CF8(this, globalCtx); this->actionFunc = func_80A52FB8; ret = true; @@ -339,17 +335,17 @@ void func_80A52DC8(EnDnq* this, GlobalContext* globalCtx) { s16 yaw = this->actor.yawTowardsPlayer - this->actor.world.rot.y; if (yaw <= 0x3800) { - func_8013AED4(&this->unk_37C, 3, 7); + SubS_UpdateFlags(&this->unk_37C, 3, 7); } else { - func_8013AED4(&this->unk_37C, 0, 7); + SubS_UpdateFlags(&this->unk_37C, 0, 7); } - if (!(gSaveContext.weekEventReg[23] & 0x20)) { + if (!(gSaveContext.save.weekEventReg[23] & 0x20)) { this->unk_390 = 70.0f; - if (func_80114F2C(ITEM_DEKU_PRINCESS) && !func_801690CC(globalCtx) && - (func_80152498(&globalCtx->msgCtx) == 0) && (ActorCutscene_GetCurrentIndex() == -1)) { - if ((DECR(this->unk_384) == 0) && (gSaveContext.weekEventReg[29] & 0x40)) { - func_801518B0(globalCtx, 0x969, NULL); + if (Interface_HasItemInBottle(ITEM_DEKU_PRINCESS) && !Play_InCsMode(globalCtx) && + (Message_GetState(&globalCtx->msgCtx) == 0) && (ActorCutscene_GetCurrentIndex() == -1)) { + if ((DECR(this->unk_384) == 0) && (gSaveContext.save.weekEventReg[29] & 0x40)) { + Message_StartTextbox(globalCtx, 0x969, NULL); this->unk_384 = 200; } } @@ -362,7 +358,7 @@ void func_80A52DC8(EnDnq* this, GlobalContext* globalCtx) { this->actor.xzDistToPlayer = this->unk_394; - if (gSaveContext.weekEventReg[83] & 8) { + if (gSaveContext.save.weekEventReg[83] & 8) { func_80A52A78(this, globalCtx); } else if (this->unk_3A4 == 0) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); @@ -380,7 +376,7 @@ void func_80A52FB8(EnDnq* this, GlobalContext* globalCtx) { s16 sp2E = this->actor.yawTowardsPlayer; if (func_8010BF58(&this->actor, globalCtx, this->unk_380, NULL, &this->unk_1E0)) { - func_8013AED4(&this->unk_37C, 3, 7); + SubS_UpdateFlags(&this->unk_37C, 3, 7); this->unk_386 = 0; this->actionFunc = func_80A52DC8; } else { @@ -392,19 +388,19 @@ void func_80A53038(EnDnq* this, GlobalContext* globalCtx) { static s32 D_80A535FC[] = { 0, 1, 2, 3, 5, 6, }; - u32 temp_v0; + s32 temp_v0; u32 temp_v1; - if (func_800EE29C(globalCtx, 0x69)) { - temp_v0 = func_800EE200(globalCtx, 0x69); - temp_v1 = globalCtx->csCtx.npcActions[temp_v0]->unk0; + if (Cutscene_CheckActorAction(globalCtx, 105)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, 105); + temp_v1 = globalCtx->csCtx.actorActions[temp_v0]->action; if (this->unk_1DC != (u8)temp_v1) { func_80A5257C(this, D_80A535FC[temp_v1]); this->unk_1DC = temp_v1; } if ((this->unk_398 == 4) && Animation_OnFrame(&this->skelAnime, 2.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KINGNUTS_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KINGNUTS_DAMAGE); } if (((this->unk_398 == 3) || (this->unk_398 == 6)) && @@ -412,7 +408,7 @@ void func_80A53038(EnDnq* this, GlobalContext* globalCtx) { func_80A5257C(this, this->unk_398 + 1); } - func_800EDF24(&this->actor, globalCtx, temp_v0); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, temp_v0); } } @@ -420,7 +416,8 @@ void EnDnq_Init(Actor* thisx, GlobalContext* globalCtx) { EnDnq* this = THIS; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 14.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600EB48, NULL, this->jointTable, this->morphTable, 33); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dnq_Skel_00EB48, NULL, this->jointTable, this->morphTable, + 33); this->unk_398 = -1; func_80A5257C(this, 0); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); @@ -429,8 +426,8 @@ void EnDnq_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.targetMode = 1; this->unk_386 = 0; this->unk_37C = 0; - func_8013AED4(&this->unk_37C, 3, 7); - if (gSaveContext.weekEventReg[9] & 0x80) { + SubS_UpdateFlags(&this->unk_37C, 3, 7); + if (gSaveContext.save.weekEventReg[9] & 0x80) { this->unk_3A4 = 1; } else { this->unk_3A4 = 0; @@ -458,10 +455,10 @@ void EnDnq_Update(Actor* thisx, GlobalContext* globalCtx) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); this->unk_394 = this->actor.xzDistToPlayer; func_80A52C6C(this, globalCtx); - func_8013C964(&this->actor, globalCtx, this->unk_390, fabsf(this->actor.yDistToPlayer) + 1.0f, 0, + func_8013C964(&this->actor, globalCtx, this->unk_390, fabsf(this->actor.playerHeightRel) + 1.0f, EXCH_ITEM_NONE, this->unk_37C & 7); this->actor.xzDistToPlayer = this->unk_394; - Actor_SetHeight(&this->actor, 46.0f); + Actor_SetFocus(&this->actor, 46.0f); func_80A52604(this, globalCtx); } } 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 373e69880..1cad6dd8f 100644 --- a/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -6,7 +6,7 @@ #include "z_en_dns.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnDns*)thisx) @@ -19,19 +19,19 @@ void func_8092D330(EnDns* this, GlobalContext* globalCtx); void EnDns_DoNothing(EnDns* this, GlobalContext* globalCtx); void func_8092D4D8(EnDns* this, GlobalContext* globalCtx); -extern AnimationHeader D_060002A8; -extern AnimationHeader D_06000734; -extern AnimationHeader D_060008F4; -extern AnimationHeader D_06000BD8; -extern AnimationHeader D_06000D58; -extern AnimationHeader D_06000FEC; -extern TexturePtr D_060028E8; -extern TexturePtr D_06002968; -extern TexturePtr D_060029E8; -extern Gfx D_06002C48[]; -extern SkeletonHeader D_06002DD8; -extern AnimationHeader D_06003310; -extern AnimationHeader D_060034EC; +typedef enum { + /* 0 */ EN_DNS_ANIMATION_IDLE_1, + /* 1 */ EN_DNS_ANIMATION_IDLE_2, + /* 2 */ EN_DNS_ANIMATION_WALK_1, + /* 3 */ EN_DNS_ANIMATION_WALK_2, + /* 4 */ EN_DNS_ANIMATION_SURPRISE_START, + /* 5 */ EN_DNS_ANIMATION_SURPRISE_LOOP, + /* 6 */ EN_DNS_ANIMATION_RUN_START, + /* 7 */ EN_DNS_ANIMATION_RUN_LOOP, + /* 8 */ EN_DNS_ANIMATION_DANCE, + /* 9 */ EN_DNS_ANIMATION_FLIP, + /* 10 */ EN_DNS_ANIMATION_MAX, +} EnDnsAnimationIndex; static s32 D_8092DCB0[] = { 0x00172000, 0x050E082F, 0x0C100E08, 0x200C1000, 0x00172000, 0x050E0830, 0x0C100E08, 0x210C1000, @@ -73,50 +73,59 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06003310, 1.0f, 0, -1, 0, 0 }, { &D_06003310, 1.0f, 0, -1, 0, -4 }, { &D_060034EC, 1.0f, 0, -1, 0, 0 }, - { &D_060034EC, 1.0f, 0, -1, 0, -4 }, { &D_060008F4, 1.0f, 0, -1, 2, 0 }, { &D_06000BD8, 1.0f, 0, -1, 0, 0 }, - { &D_06000D58, 1.0f, 0, -1, 2, 0 }, { &D_06000FEC, 1.0f, 0, -1, 0, 0 }, { &D_060002A8, 1.0f, 0, -1, 2, 0 }, - { &D_06000734, 1.0f, 0, -1, 2, 0 }, +static AnimationInfoS sAnimations[] = { + { &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gKingsChamberDekuGuardSurpriseStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardSurpriseLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardRunStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardRunLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gKingsChamberDekuGuardDanceAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gKingsChamberDekuGuardFlipAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, }; void func_8092C5C0(EnDns* this) { s32 pad; - if (((this->unk_2F8 == 2) || (this->unk_2F8 == 3) || (this->unk_2F8 == 6) || (this->unk_2F8 == 7)) && + if (((this->animationIndex == EN_DNS_ANIMATION_WALK_1) || (this->animationIndex == EN_DNS_ANIMATION_WALK_2) || + (this->animationIndex == EN_DNS_ANIMATION_RUN_START) || (this->animationIndex == EN_DNS_ANIMATION_RUN_LOOP)) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 3.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); } } s32 func_8092C63C(EnDns* this, s32 arg1) { s32 phi_v1 = false; - s32 ret = 0; + s32 ret = false; switch (arg1) { - case 0: - case 1: - if ((this->unk_2F8 != 0) && (this->unk_2F8 != 1)) { + case EN_DNS_ANIMATION_IDLE_1: + case EN_DNS_ANIMATION_IDLE_2: + if ((this->animationIndex != EN_DNS_ANIMATION_IDLE_1) && + (this->animationIndex != EN_DNS_ANIMATION_IDLE_2)) { phi_v1 = true; } break; - case 2: - case 3: - if ((this->unk_2F8 != 2) && (this->unk_2F8 != 3)) { + case EN_DNS_ANIMATION_WALK_1: + case EN_DNS_ANIMATION_WALK_2: + if ((this->animationIndex != EN_DNS_ANIMATION_WALK_1) && + (this->animationIndex != EN_DNS_ANIMATION_WALK_2)) { phi_v1 = true; } break; default: - if (this->unk_2F8 != arg1) { + if (this->animationIndex != arg1) { phi_v1 = true; } } if (phi_v1) { - this->unk_2F8 = arg1; - ret = func_8013BC6C(&this->skelAnime, sAnimations, arg1); + this->animationIndex = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); } return ret; @@ -161,11 +170,11 @@ void func_8092C86C(EnDns* this, GlobalContext* globalCtx) { } void func_8092C934(EnDns* this) { - if ((this->unk_2C6 & 0x40) && (DECR(this->unk_2DE) == 0)) { - this->unk_2E0++; - if (this->unk_2E0 >= 4) { - this->unk_2DE = Rand_S16Offset(30, 30); - this->unk_2E0 = 0; + if ((this->unk_2C6 & 0x40) && (DECR(this->blinkTimer) == 0)) { + this->eyeIndex++; + if (this->eyeIndex >= 4) { + this->blinkTimer = Rand_S16Offset(30, 30); + this->eyeIndex = 0; } } } @@ -173,7 +182,7 @@ void func_8092C934(EnDns* this) { s32* func_8092C9BC(EnDns* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (!(gSaveContext.weekEventReg[23] & 0x20)) { + if (!(gSaveContext.save.weekEventReg[23] & 0x20)) { if (player->transformation != PLAYER_FORM_DEKU) { return &D_8092DCB0[16]; } else if (this->unk_2FC != 0) { @@ -201,16 +210,16 @@ s32* func_8092C9BC(EnDns* this, GlobalContext* globalCtx) { s32 func_8092CA74(EnDns* this) { switch (ENDNS_GET_7(&this->actor)) { case ENDNS_GET_7_0: - return 0x1D1; + return 465; case ENDNS_GET_7_1: - return 0x1D2; + return 466; case ENDNS_GET_7_2: - return 0x1D3; + return 467; case ENDNS_GET_7_3: - return 0x1D4; + return 468; } return 0; @@ -220,14 +229,14 @@ s32 func_8092CAD0(EnDns* this, GlobalContext* globalCtx) { s32 ret = false; if (this->unk_2C6 & 7) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_8013AED4(&this->unk_2C6, 0, 7); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_2C6, 0, 7); this->unk_2C6 &= ~0x10; if (ENDNS_GET_4000(&this->actor)) { this->unk_2F0 = 0.0f; if (this->unk_2D2 != 0) { this->unk_2F0 = this->skelAnime.curFrame; - func_8092C63C(this, 2); + func_8092C63C(this, EN_DNS_ANIMATION_WALK_1); } this->unk_2DA = this->actor.world.rot.y; } @@ -245,15 +254,15 @@ s32 func_8092CB98(EnDns* this, GlobalContext* globalCtx) { if (globalCtx->csCtx.state != 0) { if (!(this->unk_2C6 & 0x80)) { this->unk_2C8 = func_8092CA74(this); - this->actor.flags &= ~0x1; - func_8013AED4(&this->unk_2C6, 0, 7); + this->actor.flags &= ~ACTOR_FLAG_1; + SubS_UpdateFlags(&this->unk_2C6, 0, 7); this->unk_2C6 |= 0x80; this->unk_1D8 = 0xFF; } phi_v1 = 1; } else if (this->unk_2C6 & 0x80) { - this->actor.flags |= 1; - func_8013AED4(&this->unk_2C6, 3, 7); + this->actor.flags |= ACTOR_FLAG_1; + SubS_UpdateFlags(&this->unk_2C6, 3, 7); this->unk_2C6 &= ~0x80; } return phi_v1; @@ -265,9 +274,9 @@ s32 func_8092CC68(GlobalContext* globalCtx) { s32 ret = false; s16 bgId; - if (!func_801690CC(globalCtx) && (player->actor.bgCheckFlags & 1) && (player->transformation != PLAYER_FORM_DEKU)) { + if (!Play_InCsMode(globalCtx) && (player->actor.bgCheckFlags & 1) && (player->transformation != PLAYER_FORM_DEKU)) { bgId = player->actor.floorBgId; - if (func_800C99AC(&globalCtx->colCtx, player->actor.floorPoly, bgId) != 4) { + if (SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, player->actor.floorPoly, bgId) != 4) { ret = true; } } @@ -284,20 +293,20 @@ 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; - this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; return 1; } s32 func_8092CE38(EnDns* this) { - static s32 D_8092DE00[] = { 8, 8, 9 }; + static s32 D_8092DE00[] = { EN_DNS_ANIMATION_DANCE, EN_DNS_ANIMATION_DANCE, EN_DNS_ANIMATION_FLIP }; s16 frame; s32 pad; Vec3f sp2C; @@ -308,7 +317,7 @@ s32 func_8092CE38(EnDns* this) { this->unk_2C6 &= ~0x200; this->skelAnime.curFrame = 0.0f; if (this->unk_2D2 == 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_JUMP); } this->unk_2D2++; if (this->unk_2D2 >= 3) { @@ -321,7 +330,7 @@ s32 func_8092CE38(EnDns* this) { this->actor.world.rot.y = BINANG_ROT180(this->actor.world.rot.y); this->unk_2E4 = 0.0f; this->actor.shape.rot.y = this->actor.world.rot.y; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_JUMP); } else if (this->skelAnime.curFrame < 13.0f) { frame = this->skelAnime.curFrame; this->actor.shape.rot.y = this->actor.world.rot.y; @@ -332,7 +341,7 @@ s32 func_8092CE38(EnDns* this) { } else { if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 6.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); } if (this->skelAnime.curFrame > 7.0f) { @@ -352,14 +361,14 @@ s32 func_8092D068(EnDns* this) { s32 ret = false; if (ENDNS_GET_8000(&this->actor)) { - if (gSaveContext.weekEventReg[23] & 0x20) { + if (gSaveContext.save.weekEventReg[23] & 0x20) { ret = true; } } else if (ENDNS_GET_4000(&this->actor)) { - if ((gSaveContext.weekEventReg[9] & 0x80) && !(gSaveContext.weekEventReg[23] & 0x20)) { + if ((gSaveContext.save.weekEventReg[9] & 0x80) && !(gSaveContext.save.weekEventReg[23] & 0x20)) { ret = true; } - } else if (!(gSaveContext.weekEventReg[9] & 0x80) && !(gSaveContext.weekEventReg[23] & 0x20)) { + } else if (!(gSaveContext.save.weekEventReg[9] & 0x80) && !(gSaveContext.save.weekEventReg[23] & 0x20)) { ret = true; } @@ -371,12 +380,12 @@ void func_8092D108(EnDns* this, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); - Matrix_SetStateRotationAndTranslation(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, - &this->actor.home.rot); + Matrix_SetTranslateRotateYXZ(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, + &this->actor.home.rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.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_06002C48); + gSPDisplayList(POLY_OPA_DISP++, gKingsChamberDekuGuardDekuFlower); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -390,18 +399,19 @@ void func_8092D1B8(EnDns* this, GlobalContext* globalCtx) { } if (!ENDNS_GET_4000(&this->actor) || (this->unk_2D2 != 0)) { - if (!(gSaveContext.weekEventReg[23] & 0x20) && !(gSaveContext.eventInf[1] & 0x20) && func_8092CC68(globalCtx)) { + if (!(gSaveContext.save.weekEventReg[23] & 0x20) && !(gSaveContext.eventInf[1] & 0x20) && + func_8092CC68(globalCtx)) { player->stateFlags1 |= 0x20; this->unk_2C6 |= 0x100; - func_8013AED4(&this->unk_2C6, 4, 7); + SubS_UpdateFlags(&this->unk_2C6, 4, 7); play_sound(NA_SE_SY_FOUND); gSaveContext.eventInf[1] |= 0x20; this->unk_2F4 = func_8092CCEC; - func_8092C63C(this, 2); + func_8092C63C(this, EN_DNS_ANIMATION_WALK_1); this->actionFunc = EnDns_DoNothing; } else if (gSaveContext.eventInf[1] & 0x40) { func_8092CCEC(this, globalCtx); - func_8092C63C(this, 2); + func_8092C63C(this, EN_DNS_ANIMATION_WALK_1); this->actionFunc = func_8092D330; } Math_ApproachS(&this->actor.shape.rot.y, sp22, 3, 0x2AA8); @@ -413,7 +423,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) { @@ -426,7 +436,7 @@ void func_8092D330(EnDns* this, GlobalContext* globalCtx) { sp30.x = Math_SinS(this->unk_2D4) * this->unk_2EC; sp30.z = Math_CosS(this->unk_2D4) * this->unk_2EC; Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp30), 3, 0x2AA8); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } if ((this->unk_2C6 & 0x100) && (DECR(this->unk_2D0) == 0)) { this->unk_2C6 &= ~0x100; @@ -443,16 +453,16 @@ void func_8092D4D8(EnDns* this, GlobalContext* globalCtx) { if (ENDNS_GET_4000(&this->actor) && (this->unk_2D2 == 0)) { if (func_8092CE38(this)) { - func_8092C63C(this, 2); + func_8092C63C(this, EN_DNS_ANIMATION_WALK_1); } } else if (func_8010BF58(&this->actor, globalCtx, this->unk_1E0, this->unk_2F4, &this->unk_1DC)) { - func_8013AED4(&this->unk_2C6, 3, 7); + SubS_UpdateFlags(&this->unk_2C6, 3, 7); this->unk_2F4 = NULL; if (ENDNS_GET_4000(&this->actor)) { if (!(gSaveContext.eventInf[1] & 0x20)) { this->skelAnime.curFrame = this->unk_2F0; this->actor.world.rot.y = this->unk_2DA; - func_8092C63C(this, 8); + func_8092C63C(this, EN_DNS_ANIMATION_DANCE); } this->unk_2CC = 0; this->unk_2CE = 0; @@ -465,24 +475,30 @@ void func_8092D4D8(EnDns* this, GlobalContext* globalCtx) { } void func_8092D5E8(EnDns* this, GlobalContext* globalCtx) { - static s32 D_8092DE0C[] = { 0, 0, 4, 6 }; - u32 temp_v0; + static s32 D_8092DE0C[] = { + EN_DNS_ANIMATION_IDLE_1, + EN_DNS_ANIMATION_IDLE_1, + EN_DNS_ANIMATION_SURPRISE_START, + EN_DNS_ANIMATION_RUN_START, + }; + s32 temp_v0; u32 temp_v1; - if (func_800EE29C(globalCtx, this->unk_2C8)) { - temp_v0 = func_800EE200(globalCtx, this->unk_2C8); - temp_v1 = globalCtx->csCtx.npcActions[temp_v0]->unk0; + if (Cutscene_CheckActorAction(globalCtx, this->unk_2C8)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, this->unk_2C8); + temp_v1 = globalCtx->csCtx.actorActions[temp_v0]->action; if (this->unk_1D8 != (u8)temp_v1) { func_8092C63C(this, D_8092DE0C[temp_v1]); this->unk_1D8 = temp_v1; } - if (((this->unk_2F8 == 4) || (this->unk_2F8 == 6)) && + if (((this->animationIndex == EN_DNS_ANIMATION_SURPRISE_START) || + (this->animationIndex == EN_DNS_ANIMATION_RUN_START)) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - func_8092C63C(this, this->unk_2F8 + 1); + func_8092C63C(this, this->animationIndex + 1); } - func_800EDF24(&this->actor, globalCtx, temp_v0); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, temp_v0); } } @@ -495,9 +511,10 @@ void EnDns_Init(Actor* thisx, GlobalContext* globalCtx) { } ActorShape_Init(&this->actor.shape, 0.0f, NULL, 18.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06002DD8, NULL, this->jointTable, this->morphTable, 13); - this->unk_2F8 = -1; - func_8092C63C(this, 2); + SkelAnime_Init(globalCtx, &this->skelAnime, &gKingsChamberDekuGuardSkel, NULL, this->jointTable, this->morphTable, + KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX); + this->animationIndex = -1; + func_8092C63C(this, EN_DNS_ANIMATION_WALK_1); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); Actor_SetScale(&this->actor, 0.01f); @@ -505,10 +522,10 @@ void EnDns_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.gravity = -0.8f; this->unk_2D2 = 0; this->unk_2C6 = 0; - func_8013AED4(&this->unk_2C6, 3, 7); + SubS_UpdateFlags(&this->unk_2C6, 3, 7); this->unk_2C6 |= (0x40 | 0x10); this->unk_2C6 |= 0x200; - if (gSaveContext.weekEventReg[9] & 0x80) { + if (gSaveContext.save.weekEventReg[9] & 0x80) { this->unk_2FC = 1; } else { this->unk_2FC = 0; @@ -537,8 +554,8 @@ void EnDns_Update(Actor* thisx, GlobalContext* globalCtx) { func_8092C934(this); func_8092C86C(this, globalCtx); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); - func_8013C964(&this->actor, globalCtx, 80.0f, 40.0f, 0, this->unk_2C6 & 7); - Actor_SetHeight(&this->actor, 34.0f); + func_8013C964(&this->actor, globalCtx, 80.0f, 40.0f, EXCH_ITEM_NONE, this->unk_2C6 & 7); + Actor_SetFocus(&this->actor, 34.0f); func_8092C6FC(this, globalCtx); func_8092C5C0(this); } @@ -549,9 +566,9 @@ 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_CopyCurrentState(&sp2C); - func_8018219C(&sp2C, &sp6C, 0); + Matrix_MultVec3f(&gZeroVec3f, &sp74); + Matrix_Get(&sp2C); + Matrix_MtxFToYXZRot(&sp2C, &sp6C, false); *arg2 = sp74; if (arg4 == 0) { @@ -597,14 +614,14 @@ void EnDns_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } } - if (limbIndex == 2) { + if (limbIndex == KINGS_CHAMBER_DEKU_GUARD_LIMB_HEAD) { func_8092D954(this->unk_2CC, this->unk_2CE + this->actor.shape.rot.y, &this->unk_218, &this->unk_224, phi_v1, phi_v0); - Matrix_InsertTranslation(this->unk_218.x, this->unk_218.y, this->unk_218.z, MTXMODE_NEW); + Matrix_Translate(this->unk_218.x, this->unk_218.y, this->unk_218.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - Matrix_RotateY(this->unk_224.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_224.z, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_224.x, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_224.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_224.z, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_224.x, MTXMODE_APPLY); } OPEN_DISPS(globalCtx->state.gfxCtx); @@ -616,14 +633,19 @@ void EnDns_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } void EnDns_Draw(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr D_8092DE1C[] = { &D_060028E8, &D_06002968, &D_060029E8, &D_06002968 }; + static TexturePtr sEyeTextures[] = { + gKingsChamberDekuGuardEyeOpenTex, + gKingsChamberDekuGuardEyeHalfTex, + gKingsChamberDekuGuardEyeClosedTex, + gKingsChamberDekuGuardEyeHalfTex, + }; EnDns* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_8092DE1C[this->unk_2E0])); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); gDPPipeSync(POLY_OPA_DISP++); SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDns_OverrideLimbDraw, diff --git a/src/overlays/actors/ovl_En_Dns/z_en_dns.h b/src/overlays/actors/ovl_En_Dns/z_en_dns.h index 598dfff3b..257717502 100644 --- a/src/overlays/actors/ovl_En_Dns/z_en_dns.h +++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.h @@ -2,6 +2,7 @@ #define Z_EN_DNS_H #include "global.h" +#include "objects/object_dns/object_dns.h" struct EnDns; @@ -31,8 +32,8 @@ typedef struct EnDns { /* 0x1E4 */ Gfx* unk_1E4[13]; /* 0x218 */ Vec3f unk_218; /* 0x224 */ Vec3s unk_224; - /* 0x22A */ Vec3s jointTable[13]; - /* 0x278 */ Vec3s morphTable[13]; + /* 0x22A */ Vec3s jointTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX]; + /* 0x278 */ Vec3s morphTable[KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX]; /* 0x2C6 */ u16 unk_2C6; /* 0x2C8 */ u16 unk_2C8; /* 0x2CA */ UNK_TYPE1 unk_2CA[0x2]; @@ -45,14 +46,14 @@ typedef struct EnDns { /* 0x2D8 */ s16 unk_2D8; /* 0x2DA */ s16 unk_2DA; /* 0x2DC */ s16 unk_2DC; - /* 0x2DE */ s16 unk_2DE; - /* 0x2E0 */ s16 unk_2E0; + /* 0x2DE */ s16 blinkTimer; + /* 0x2E0 */ s16 eyeIndex; /* 0x2E4 */ f32 unk_2E4; /* 0x2E8 */ UNK_TYPE1 unk_2E8[0x4]; /* 0x2EC */ f32 unk_2EC; /* 0x2F0 */ f32 unk_2F0; /* 0x2F4 */ EnDnsFunc unk_2F4; - /* 0x2F8 */ s32 unk_2F8; + /* 0x2F8 */ s32 animationIndex; /* 0x2FC */ s32 unk_2FC; } EnDns; // size = 0x300 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 62cfddd0f..914ee2bca 100644 --- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -7,8 +7,9 @@ #include "z_en_dodongo.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" #include "overlays/actors/ovl_En_Bombf/z_en_bombf.h" +#include "objects/object_dodongo/object_dodongo.h" -#define FLAGS 0x00000405 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnDodongo*)thisx) @@ -34,16 +35,6 @@ void func_808786C8(EnDodongo* this, GlobalContext* globalCtx); void func_80878724(EnDodongo* this); void func_808787B0(EnDodongo* this, GlobalContext* globalCtx); -extern AnimationHeader D_060013C4; -extern AnimationHeader D_06001A44; -extern AnimationHeader D_060028F0; -extern AnimationHeader D_06003088; -extern AnimationHeader D_06003B14; -extern AnimationHeader D_060042C4; -extern AnimationHeader D_06004C20; -extern SkeletonHeader D_06008318; -extern AnimationHeader D_06008B1C; - const ActorInit En_Dodongo_InitVars = { ACTOR_EN_DODONGO, ACTORCAT_ENEMY, @@ -288,7 +279,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 }, }; @@ -302,9 +293,10 @@ void EnDodongo_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_330.r = 255; this->unk_330.g = 10; this->unk_330.a = 200; - Math_Vec3f_Copy(&this->unk_314, &D_801C5DB0); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 48.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06008318, &D_06004C20, this->jointTable, this->morphTable, 31); + Math_Vec3f_Copy(&this->unk_314, &gOneVec3f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 48.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_dodongo_Skel_008318, &object_dodongo_Anim_004C20, + this->jointTable, this->morphTable, 31); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); Collider_InitAndSetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit2, this->collider2Elements); Collider_InitAndSetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit1, this->collider1Elements); @@ -315,7 +307,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; @@ -366,7 +358,7 @@ void func_80876930(EnDodongo* this, GlobalContext* globalCtx, Vec3f* arg2) { s16 temp2; f32 temp3; - if (func_800C9BB8(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 14) { + if (func_800C9BB8(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == COLPOLY_SURFACE_SNOW) { sp80 = &D_8087932C; sp7C = &D_80879330; } else { @@ -384,7 +376,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); } } @@ -393,12 +385,12 @@ void func_80876B08(EnDodongo* this, GlobalContext* globalCtx) { s16 yDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; if (ABS_ALT(yDiff) < 0x4000) { - if (!(player->stateFlags1 & 0x00800000) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { + if (!(player->stateFlags1 & 0x00800000) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { func_808777A8(this); } else { func_80877494(this); } - } else if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) { + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) { func_80878354(this); } else { func_80877494(this); @@ -407,13 +399,13 @@ void func_80876B08(EnDodongo* this, GlobalContext* globalCtx) { void func_80876BD0(EnDodongo* this, GlobalContext* globalCtx, s32 arg2) { if (this->actor.colChkInfo.damageEffect == 2) { - this->unk_300 = 0; - this->unk_340 = 0.75f; - this->unk_33C = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; } else if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_300 = 20; - this->unk_340 = 0.75f; - this->unk_33C = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider1.elements[arg2].info.bumper.hitPos.x, this->collider1.elements[arg2].info.bumper.hitPos.y, @@ -422,25 +414,26 @@ void func_80876BD0(EnDodongo* this, GlobalContext* globalCtx, s32 arg2) { } void func_80876CAC(EnDodongo* this) { - this->unk_300 = 10; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; this->collider1.base.colType = COLTYPE_HIT3; - this->unk_340 = 0.75f; - this->unk_344 = 1.125f; - this->unk_33C = 1.0f; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffFrozenSteamScale = 1.125f; + this->drawDmgEffAlpha = 1.0f; this->timer = 80; - this->actor.flags &= ~0x400; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 80); + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 80); } void func_80876D28(EnDodongo* this, GlobalContext* globalCtx) { - if (this->unk_300 == 10) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { this->timer = 0; this->actor.colorFilterTimer = 0; - this->unk_300 = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->collider1.base.colType = COLTYPE_HIT0; - this->unk_33C = 0.0f; - func_800BF7CC(globalCtx, &this->actor, &this->unk_348[0], 9, 2, this->unk_334 * 0.3f, this->unk_334 * 0.2f); - this->actor.flags |= 0x400; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, &this->limbPos[0], 9, 2, this->unk_334 * 0.3f, + this->unk_334 * 0.2f); + this->actor.flags |= ACTOR_FLAG_400; } } @@ -455,7 +448,7 @@ void func_80876DC4(EnDodongo* this, GlobalContext* globalCtx) { f32 temp_f22; f32 temp_f20; - Math_Vec3f_Copy(&sp68, &this->unk_348[0]); + Math_Vec3f_Copy(&sp68, &this->limbPos[0]); sp66 = (Rand_Next() >> 0x12) + this->actor.shape.rot.y; temp_f20 = Math_CosS(sp66); temp_f22 = Math_SinS(sp66); @@ -503,8 +496,8 @@ void func_80876DC4(EnDodongo* this, GlobalContext* globalCtx) { sp74.z = (Rand_ZeroFloat(0.1f) + 0.15f) * -temp_f22 * this->unk_334; func_800B0EB0(globalCtx, &sp68, &sp80, &sp74, &this->unk_32C, &this->unk_330, sp64, sp62, 0x14); - sp68.x = this->unk_348[0].x + (temp_f20 * 6.0f * this->unk_334); - sp68.z = this->unk_348[0].z - (temp_f22 * 6.0f * this->unk_334); + sp68.x = this->limbPos[0].x + (temp_f20 * 6.0f * this->unk_334); + sp68.z = this->limbPos[0].z - (temp_f22 * 6.0f * this->unk_334); sp80.x *= -1.0f; sp80.z = sp80.z * -1.0f; sp74.x = (Rand_ZeroFloat(0.1f) + 0.15f) * -temp_f20 * this->unk_334; @@ -522,13 +515,13 @@ s32 func_8087721C(EnDodongo* this) { s32 func_80877278(EnDodongo* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; Vec3f sp44; // Bugfix from OoT while (explosive != NULL) { if (!explosive->params && (explosive->parent == NULL) && (explosive->update != NULL) && - (explosive != player->unk_388) && + (explosive != player->interactRangeActor) && (((explosive->id == ACTOR_EN_BOM) && (((EnBom*)explosive)->timer > 0)) || ((explosive->id == ACTOR_EN_BOMBF) && (((EnBombf*)explosive)->timer > 0)))) { Math_Vec3f_Diff(&explosive->world.pos, &this->unk_308, &sp44); @@ -544,7 +537,7 @@ s32 func_80877278(EnDodongo* this, GlobalContext* globalCtx) { } void func_808773C4(EnDodongo* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06004C20, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_dodongo_Anim_004C20, -4.0f); this->actor.speedXZ = 0.0f; this->timer = Rand_S16Offset(30, 50); this->actionFunc = func_80877424; @@ -564,7 +557,7 @@ void func_80877424(EnDodongo* this, GlobalContext* globalCtx) { } void func_80877494(EnDodongo* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06008B1C, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_dodongo_Anim_008B1C, -4.0f); this->actor.speedXZ = this->unk_334 * 1.5f; this->timer = Rand_S16Offset(50, 70); this->actionFunc = func_80877500; @@ -577,13 +570,13 @@ void func_80877500(EnDodongo* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 19.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_WALK); sp30.x = this->collider1Elements[2].dim.worldSphere.center.x; sp30.y = this->collider1Elements[2].dim.worldSphere.center.y; sp30.z = this->collider1Elements[2].dim.worldSphere.center.z; func_80876930(this, globalCtx, &sp30); } else if (Animation_OnFrame(&this->skelAnime, 39.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_WALK); sp30.x = this->collider1Elements[1].dim.worldSphere.center.x; sp30.y = this->collider1Elements[1].dim.worldSphere.center.y; sp30.z = this->collider1Elements[1].dim.worldSphere.center.z; @@ -591,18 +584,18 @@ void func_80877500(EnDodongo* this, GlobalContext* globalCtx) { } if ((Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 400.0f) && - (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { temp_v1 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x1F4); if (this->actor.xzDistToPlayer < (100.0f * this->unk_334)) { - if ((ABS_ALT(temp_v1) < 0x1388) && (this->actor.yDistToPlayer < 60.0f) && + if ((ABS_ALT(temp_v1) < 0x1388) && (this->actor.playerHeightRel < 60.0f) && !(player->stateFlags1 & 0x800000)) { func_808777A8(this); } } } else { if ((Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 150.0f) || - (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK)) { + (Player_GetMask(globalCtx) == PLAYER_MASK_STONE)) { Math_ScaledStepToS(&this->actor.world.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 0x1F4); } @@ -623,15 +616,15 @@ void func_808777A8(EnDodongo* this) { s32 i; Sphere16* sph; - Animation_MorphToPlayOnce(&this->skelAnime, &D_060028F0, -4.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dodongo_Anim_0028F0, -4.0f); this->actor.speedXZ = 0.0f; for (i = 0; i < ARRAY_COUNT(this->collider3Elements); i++) { sph = &this->collider3.elements[i].dim.worldSphere; - sph->center.x = this->unk_348[0].x; - sph->center.y = this->unk_348[0].y; - sph->center.z = this->unk_348[0].z; + sph->center.x = this->limbPos[0].x; + sph->center.y = this->limbPos[0].y; + sph->center.z = this->limbPos[0].z; sph->radius = 0; } @@ -649,7 +642,7 @@ void func_8087784C(EnDodongo* this, GlobalContext* globalCtx) { f32 temp_f12; if (Animation_OnFrame(&this->skelAnime, 24.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_CRY); } if (func_8087721C(this)) { @@ -665,10 +658,10 @@ void func_8087784C(EnDodongo* this, GlobalContext* globalCtx) { temp_f12 = Math_CosS(this->actor.shape.rot.y) * this->unk_334; for (i = 0; i < end; i++, element++) { - element->dim.worldSphere.center.x = this->unk_348[0].x + (element->dim.modelSphere.center.z * temp_f2); + element->dim.worldSphere.center.x = this->limbPos[0].x + (element->dim.modelSphere.center.z * temp_f2); element->dim.worldSphere.center.y = - this->unk_348[0].y + (element->dim.modelSphere.center.y * this->unk_334); - element->dim.worldSphere.center.z = this->unk_348[0].z + (element->dim.modelSphere.center.z * temp_f12); + this->limbPos[0].y + (element->dim.modelSphere.center.y * this->unk_334); + element->dim.worldSphere.center.z = this->limbPos[0].z + (element->dim.modelSphere.center.z * temp_f12); element->dim.worldSphere.radius = element->dim.modelSphere.radius; } @@ -676,7 +669,7 @@ void func_8087784C(EnDodongo* this, GlobalContext* globalCtx) { D_80879348.x = 2.5f * temp_f2; D_80879348.y = this->unk_334 * 1.4f; D_80879348.z = 2.5f * temp_f12; - EffectSsDFire_Spawn(globalCtx, &this->unk_348[0], &D_80879354, &D_80879348, this->unk_334 * 100.0f, + EffectSsDFire_Spawn(globalCtx, &this->limbPos[0], &D_80879354, &D_80879348, this->unk_334 * 100.0f, this->unk_334 * 35.0f, 0xFF - (frame * 10), 5, 0, 8); } else if ((this->skelAnime.curFrame >= 2.0f) && (this->skelAnime.curFrame <= 20.0f)) { func_800B9010(&this->actor, NA_SE_EN_DODO_J_BREATH - SFX_FLAG); @@ -688,7 +681,7 @@ void func_8087784C(EnDodongo* this, GlobalContext* globalCtx) { } void func_80877D50(EnDodongo* this) { - Animation_PlayOnce(&this->skelAnime, &D_06003088); + Animation_PlayOnce(&this->skelAnime, &object_dodongo_Anim_003088); this->actionFunc = func_80877D90; } @@ -700,8 +693,8 @@ void func_80877D90(EnDodongo* this, GlobalContext* globalCtx) { } void func_80877DE0(EnDodongo* this) { - Animation_Change(&this->skelAnime, &D_060028F0, -1.0f, 35.0f, 0.0f, 2, -4.0f); - this->actor.flags |= 0x10; + Animation_Change(&this->skelAnime, &object_dodongo_Anim_0028F0, -1.0f, 35.0f, 0.0f, 2, -4.0f); + this->actor.flags |= ACTOR_FLAG_10; this->timer = 25; this->actionFunc = func_80877E60; this->actor.speedXZ = 0.0f; @@ -713,7 +706,7 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { Vec3f sp84; Vec3f sp78; s16 i; - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; Vec3f sp64; s32 pad; s16 sp5E; @@ -736,12 +729,12 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 28.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_EAT); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_EAT); if (this->actor.child != NULL) { Actor_MarkForDeath(this->actor.child); this->actor.child = NULL; } - this->actor.flags &= ~0x10; + this->actor.flags &= ~ACTOR_FLAG_10; } else if (this->skelAnime.playSpeed > -0.5f) { this->timer--; if (this->timer == 10) { @@ -759,14 +752,14 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { this->unk_334 * 10.0f, 10); } - Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_EXPLOSION); if (this->actor.colChkInfo.health <= 4) { this->actor.colChkInfo.health = 0; Enemy_StartFinishingBlow(globalCtx, &this->actor); } else { this->actor.colChkInfo.health -= 4; } - func_800BCB70(&this->actor, 0x4000, 0x78, 0, 8); + Actor_SetColorFilter(&this->actor, 0x4000, 0x78, 0, 8); } } else if (Animation_OnFrame(&this->skelAnime, 24.0f)) { this->timer--; @@ -779,14 +772,14 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { } else { 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); + Math_Vec3f_Copy(&sp64, &this->limbPos[0]); + 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); - 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); + sp64.x = (2.0f * this->limbPos[0].x) - sp64.x; + sp64.z = (2.0f * this->limbPos[0].z) - sp64.z; + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); } } @@ -812,13 +805,13 @@ void func_80878354(EnDodongo* this) { this->unk_306 = (0xFFFF - ABS_ALT(yDiff)) / 15; if (yDiff >= 0) { - sp18 = &D_060042C4; + sp18 = &object_dodongo_Anim_0042C4; this->unk_306 = -this->unk_306; } else { - sp18 = &D_06003B14; + sp18 = &object_dodongo_Anim_003B14; } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_TAIL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_TAIL); Animation_PlayOnceSetSpeed(&this->skelAnime, sp18, 2.0f); this->timer = 0; this->collider1.base.atFlags |= AT_ON; @@ -832,7 +825,7 @@ void func_80878424(EnDodongo* this, GlobalContext* globalCtx) { this->timer++; if (SkelAnime_Update(&this->skelAnime)) { - if (!(player->stateFlags1 & 0x800000) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { + if (!(player->stateFlags1 & 0x800000) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { this->collider1.base.atFlags &= ~AT_ON; func_808777A8(this); } else { @@ -852,7 +845,7 @@ void func_80878424(EnDodongo* this, GlobalContext* globalCtx) { sp20.z = this->collider1Elements[2].dim.worldSphere.center.z; func_80876930(this, globalCtx, &sp20); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); - this->actor.flags |= 0x1000000; + this->actor.flags |= ACTOR_FLAG_1000000; } void func_80878594(EnDodongo* this) { @@ -878,12 +871,12 @@ void func_808785B0(EnDodongo* this, GlobalContext* globalCtx) { } void func_8087864C(EnDodongo* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001A44, -4.0f); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_DAMAGE); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dodongo_Anim_001A44, -4.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_DAMAGE); this->timer = 0; this->unk_304 = 0; this->actor.speedXZ = 0.0f; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); this->actionFunc = func_808786C8; } @@ -898,13 +891,13 @@ void func_808786C8(EnDodongo* this, GlobalContext* globalCtx) { } void func_80878724(EnDodongo* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_060013C4, -8.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_dodongo_Anim_0013C4, -8.0f); this->timer = 0; this->unk_304 = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_DODO_J_DEAD); - this->actor.flags &= ~1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_J_DEAD); + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.speedXZ = 0.0f; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); this->actionFunc = func_808787B0; } @@ -916,7 +909,7 @@ void func_808787B0(EnDodongo* this, GlobalContext* globalCtx) { func_80876DC4(this, globalCtx); } } else if (this->actor.colorFilterTimer == 0) { - func_800BCB70(&this->actor, 0x4000, 0x78, 0, 4); + Actor_SetColorFilter(&this->actor, 0x4000, 0x78, 0, 4); } if (SkelAnime_Update(&this->skelAnime)) { @@ -929,7 +922,7 @@ void func_808787B0(EnDodongo* this, GlobalContext* globalCtx) { this->timer = 8; } } else if (Animation_OnFrame(&this->skelAnime, 52.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_DOWN); } if (this->timer != 0) { @@ -960,7 +953,8 @@ void EnDodongo_UpdateDamage(EnDodongo* this, GlobalContext* globalCtx) { } if ((i != ARRAY_COUNT(this->collider2Elements)) && - ((this->unk_300 != 10) || !(this->collider2.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { + ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider2.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { func_80876D28(this, globalCtx); Math_Vec3s_ToVec3f(&sp3C, &this->collider2.elements[i].info.bumper.hitPos); if (this->actor.colChkInfo.damageEffect == 0xF) { @@ -974,7 +968,7 @@ void EnDodongo_UpdateDamage(EnDodongo* this, GlobalContext* globalCtx) { } else if (this->collider1.base.acFlags & AC_HIT) { this->collider2.base.acFlags &= ~AC_HIT; this->collider1.base.acFlags &= ~AC_HIT; - func_800BE2B8(&this->actor, &this->collider1); + Actor_SetDropFlagJntSph(&this->actor, &this->collider1); for (i = 0; i < ARRAY_COUNT(this->collider1Elements); i++) { if (this->collider1.elements[i].info.bumperFlags & BUMP_HIT) { @@ -983,7 +977,8 @@ void EnDodongo_UpdateDamage(EnDodongo* this, GlobalContext* globalCtx) { } if ((i != ARRAY_COUNT(this->collider1Elements)) && - ((this->unk_300 != 10) || !(this->collider1.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { + ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider1.elements[i].info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { func_80876D28(this, globalCtx); if (this->actor.colChkInfo.damageEffect != 0xF) { if (!Actor_ApplyDamage(&this->actor)) { @@ -1000,16 +995,16 @@ void EnDodongo_UpdateDamage(EnDodongo* this, GlobalContext* globalCtx) { } } else if (this->actor.colChkInfo.damageEffect == 1) { this->timer = 40; - func_800BCB70(&this->actor, 0, 0xFF, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); func_80878594(this); } else if (this->actor.colChkInfo.damageEffect == 5) { this->timer = 40; - func_800BCB70(&this->actor, 0, 0xFF, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); - this->unk_300 = 30; - this->unk_340 = 0.75f; - this->unk_33C = 2.0f; + Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 2.0f; func_80878594(this); } else if (this->actor.colChkInfo.damageEffect == 3) { func_80876CAC(this); @@ -1024,15 +1019,15 @@ void EnDodongo_UpdateDamage(EnDodongo* this, GlobalContext* globalCtx) { } void EnDodongo_Update(Actor* thisx, GlobalContext* globalCtx2) { - EnDodongo* this = THIS; GlobalContext* globalCtx = globalCtx2; + EnDodongo* this = THIS; EnDodongo_UpdateDamage(this, globalCtx); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 75.0f, 60.0f, 70.0f, 0x1D); if (this->actor.bgCheckFlags & 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_DOWN); } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); @@ -1050,12 +1045,12 @@ void EnDodongo_Update(Actor* thisx, GlobalContext* globalCtx2) { CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider3.base); } - if (this->unk_33C > 0.0f) { - if (this->unk_300 != 10) { - Math_StepToF(&this->unk_33C, 0.0f, 0.05f); - this->unk_340 = (this->unk_33C + 1.0f) * 0.375f; - this->unk_340 = (this->unk_340 > 0.75f) ? 0.75f : this->unk_340; - } else if (!Math_StepToF(&this->unk_344, 0.75f, 0.01875f)) { + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.375f; + this->drawDmgEffScale = (this->drawDmgEffScale > 0.75f) ? 0.75f : this->drawDmgEffScale; + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.01875f)) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } @@ -1086,20 +1081,20 @@ void EnDodongo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList Collider_UpdateSpheres(limbIndex, &this->collider1); Collider_UpdateSpheres(limbIndex, &this->collider2); if (D_80879388[limbIndex] != -1) { - Matrix_GetStateTranslation(&this->unk_348[D_80879388[limbIndex]]); + Matrix_MultZero(&this->limbPos[D_80879388[limbIndex]]); } if (limbIndex == 7) { - Matrix_MultiplyVector3fByState(&D_80879370, &this->unk_308); - Matrix_MultiplyVector3fByState(&D_8087937C, &this->unk_348[0]); - Matrix_GetStateTranslation(&this->actor.focus.pos); - Matrix_GetStateTranslationAndScaledY(-200.0f, &this->unk_348[1]); + Matrix_MultVec3f(&D_80879370, &this->unk_308); + Matrix_MultVec3f(&D_8087937C, &this->limbPos[0]); + Matrix_MultZero(&this->actor.focus.pos); + Matrix_MultVecY(-200.0f, &this->limbPos[1]); } else if (limbIndex == 13) { - Matrix_GetStateTranslationAndScaledX(1600.0f, &this->unk_320); + Matrix_MultVecX(1600.0f, &this->unk_320); } 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->limbPos[4]); this->unk_304 = this->timer; } } @@ -1110,6 +1105,7 @@ void EnDodongo_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDodongo_OverrideLimbDraw, EnDodongo_PostLimbDraw, &this->actor); - func_800BE680(globalCtx, &this->actor, this->unk_348, ARRAY_COUNT(this->unk_348), this->unk_340 * this->unk_334, - this->unk_344 * this->unk_334, this->unk_33C, this->unk_300); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale * this->unk_334, this->drawDmgEffFrozenSteamScale * this->unk_334, + this->drawDmgEffAlpha, this->drawDmgEffType); } diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h index 4a7fe8e9d..30562404f 100644 --- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h +++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.h @@ -13,7 +13,7 @@ typedef struct EnDodongo { /* 0x188 */ Vec3s jointTable[31]; /* 0x242 */ Vec3s morphTable[31]; /* 0x2FC */ EnDodongoActionFunc actionFunc; - /* 0x300 */ u8 unk_300; + /* 0x300 */ u8 drawDmgEffType; /* 0x302 */ s16 timer; /* 0x304 */ s16 unk_304; /* 0x306 */ s16 unk_306; @@ -24,10 +24,10 @@ typedef struct EnDodongo { /* 0x330 */ Color_RGBA8 unk_330; /* 0x334 */ f32 unk_334; /* 0x338 */ s32 unk_338; - /* 0x33C */ f32 unk_33C; - /* 0x340 */ f32 unk_340; - /* 0x344 */ f32 unk_344; - /* 0x348 */ Vec3f unk_348[9]; + /* 0x33C */ f32 drawDmgEffAlpha; + /* 0x340 */ f32 drawDmgEffScale; + /* 0x344 */ f32 drawDmgEffFrozenSteamScale; + /* 0x348 */ Vec3f limbPos[9]; /* 0x3B4 */ ColliderJntSph collider1; /* 0x3D4 */ ColliderJntSphElement collider1Elements[10]; /* 0x654 */ ColliderJntSph collider2; diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.c b/src/overlays/actors/ovl_En_Door/z_en_door.c index 894f11b48..fe65bb30d 100644 --- a/src/overlays/actors/ovl_En_Door/z_en_door.c +++ b/src/overlays/actors/ovl_En_Door/z_en_door.c @@ -1,6 +1,26 @@ -#include "z_en_door.h" +/* + * File: z_en_door.c + * Overlay: ovl_En_Door + * Description: Wooden Door + */ -#define FLAGS 0x00000010 +#include "z_en_door.h" +#include "objects/object_mkk/object_mkk.h" +#include "objects/object_dor01/object_dor01.h" +#include "objects/object_dor02/object_dor02.h" +#include "objects/object_dor03/object_dor03.h" +#include "objects/object_dor04/object_dor04.h" +#include "objects/object_wdor01/object_wdor01.h" +#include "objects/object_wdor02/object_wdor02.h" +#include "objects/object_wdor03/object_wdor03.h" +#include "objects/object_wdor04/object_wdor04.h" +#include "objects/object_wdor05/object_wdor05.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_numa_obj/object_numa_obj.h" +#include "objects/object_kaizoku_obj/object_kaizoku_obj.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnDoor*)thisx) @@ -9,7 +29,254 @@ void EnDoor_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnDoor_Update(Actor* thisx, GlobalContext* globalCtx); void EnDoor_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80866B20(EnDoor*, GlobalContext*); +void func_8086704C(EnDoor*, GlobalContext*); +void func_80866F94(EnDoor*, GlobalContext*); +void func_80867080(EnDoor*, GlobalContext*); +void func_80867144(EnDoor*, GlobalContext*); +void func_808670F0(EnDoor*, GlobalContext*); +void func_80866A5C(EnDoor*, GlobalContext*); + +u8 D_808675D0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x12 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 23, 0, 0x12 - 0x0A), + /* 0x0A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 6, 0, 0x12 - 0x10), + /* 0x10 */ SCHEDULE_CMD_RET_VAL_S(7), + /* 0x12 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808675E4[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(9, 0, 0x4B - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(12, 0, 0x1D - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(1, 0x1F - 0x0C), + /* 0x0C */ SCHEDULE_CMD_BRANCH_S(0x0), + /* 0x0E */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x1C - 0x12), + /* 0x12 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(15, 0, 0x1D - 0x16), + /* 0x16 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(0, 0, 0x1C - 0x1A), + /* 0x1A */ SCHEDULE_CMD_RET_VAL_S(9), + /* 0x1C */ SCHEDULE_CMD_RET_NONE(), + /* 0x1D */ SCHEDULE_CMD_RET_VAL_S(8), + /* 0x1F */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x3C - 0x23), + /* 0x23 */ SCHEDULE_CMD_CHECK_FLAG_S(0x1C, 0x08, 0x2E - 0x27), + /* 0x27 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x2D - 0x2B), + /* 0x2B */ SCHEDULE_CMD_RET_VAL_S(9), + /* 0x2D */ SCHEDULE_CMD_RET_NONE(), + /* 0x2E */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x1C - 0x32), + /* 0x32 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(17, 0, 0x1D - 0x36), + /* 0x36 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(0, 0, 0x1C - 0x3A), + /* 0x3A */ SCHEDULE_CMD_RET_VAL_S(9), + /* 0x3C */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x1C - 0x40), + /* 0x40 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x1D - 0x44), + /* 0x44 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(18, 0, 0x49 - 0x48), + /* 0x48 */ SCHEDULE_CMD_RET_NONE(), + /* 0x49 */ SCHEDULE_CMD_RET_VAL_S(9), + /* 0x4B */ SCHEDULE_CMD_RET_VAL_S(9), +}; + +u8 D_80867634[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 23, 0, 0x8 - 0x6), + /* 0x6 */ SCHEDULE_CMD_RET_VAL_S(28), + /* 0x8 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867640[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 0, 22, 0, 0x7 - 0x6), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), + /* 0x7 */ SCHEDULE_CMD_RET_VAL_S(11), +}; + +u8 D_8086764C[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(22, 0, 5, 0, 0x8 - 0x6), + /* 0x6 */ SCHEDULE_CMD_RET_VAL_S(10), + /* 0x8 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867658[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x13 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_FLAG_S(0x1C, 0x08, 0x0A - 0x08), + /* 0x08 */ SCHEDULE_CMD_RET_VAL_S(12), + /* 0x0A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 10, 22, 0, 0x12 - 0x10), + /* 0x10 */ SCHEDULE_CMD_RET_VAL_S(12), + /* 0x12 */ SCHEDULE_CMD_RET_NONE(), + /* 0x13 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x28 - 0x17), + /* 0x17 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(13, 0, 0x28 - 0x1B), + /* 0x1B */ SCHEDULE_CMD_CHECK_FLAG_S(0x33, 0x08, 0x21 - 0x1F), + /* 0x1F */ SCHEDULE_CMD_RET_VAL_S(12), + /* 0x21 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(22, 0, 0x27 - 0x25), + /* 0x25 */ SCHEDULE_CMD_RET_VAL_S(12), + /* 0x27 */ SCHEDULE_CMD_RET_NONE(), + /* 0x28 */ SCHEDULE_CMD_RET_VAL_S(12), +}; + +u8 D_80867684[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867688[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(22, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(15), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867690[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(22, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(16), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867698[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(22, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(17), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676A0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 0, 21, 0, 0x15 - 0x06), + /* 0x06 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(22, 0, 5, 0, 0x0E - 0x0C), + /* 0x0C */ SCHEDULE_CMD_RET_VAL_S(18), + /* 0x0E */ SCHEDULE_CMD_CHECK_MISC_S(SCHEDULE_CHECK_MISC_MASK_ROMANI, 0x13 - 0x11), + /* 0x11 */ SCHEDULE_CMD_RET_VAL_S(34), + /* 0x13 */ SCHEDULE_CMD_RET_VAL_S(33), + /* 0x15 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676B8[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_MISC_S(SCHEDULE_CHECK_MISC_ROOM_KEY, 0x17 - 0x03), + /* 0x03 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x0E - 0x07), + /* 0x07 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(8, 0, 0x0C - 0x0B), + /* 0x0B */ SCHEDULE_CMD_RET_NONE(), + /* 0x0C */ SCHEDULE_CMD_RET_VAL_S(19), + /* 0x0E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(8, 0, 20, 30, 0x16 - 0x14), + /* 0x14 */ SCHEDULE_CMD_RET_VAL_S(19), + /* 0x16 */ SCHEDULE_CMD_RET_NONE(), + /* 0x17 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676D0[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676D4[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676D8[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x9 - 0x4), + /* 0x4 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(18, 0, 0x9 - 0x8), + /* 0x8 */ SCHEDULE_CMD_RET_NONE(), + /* 0x9 */ SCHEDULE_CMD_RET_VAL_S(20), +}; + +u8 D_808676E4[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_MISC_S(SCHEDULE_CHECK_MISC_ROOM_KEY, 0x5 - 0x3), + /* 0x3 */ SCHEDULE_CMD_RET_VAL_S(22), + /* 0x5 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676EC[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_808676F0[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x9 - 0x4), + /* 0x4 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(10, 0, 0xF - 0x8), + /* 0x8 */ SCHEDULE_CMD_RET_NONE(), + /* 0x9 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 0, 20, 0, 0x8 - 0xF), + /* 0xF */ SCHEDULE_CMD_RET_VAL_S(21), +}; + +u8 D_80867704[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867708[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_8086770C[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867710[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867714[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(20, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(23), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_8086771C[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(1, 0x0B - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(2, 30, 0x0A - 0x08), + /* 0x08 */ SCHEDULE_CMD_RET_VAL_S(24), + /* 0x0A */ SCHEDULE_CMD_RET_NONE(), + /* 0x0B */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x0A - 0x0F), + /* 0x0F */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(20, 0, 0x0A - 0x13), + /* 0x13 */ SCHEDULE_CMD_RET_VAL_S(12), +}; + +u8 D_80867734[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(20, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(25), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_8086773C[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(20, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(26), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867744[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x08 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_FLAG_S(0x63, 0x80, 0x0E - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(20, 0, 0x14 - 0x0C), + /* 0x0C */ SCHEDULE_CMD_RET_VAL_S(27), + /* 0x0E */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(18, 0, 0x14 - 0x12), + /* 0x12 */ SCHEDULE_CMD_RET_VAL_S(27), + /* 0x14 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_8086775C[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_FLAG_S(0x34, 0x20, 0x1B - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_FLAG_S(0x4B, 0x20, 0x1B - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_FLAG_S(0x0E, 0x04, 0x0E - 0x0C), + /* 0x0C */ SCHEDULE_CMD_RET_VAL_S(29), + /* 0x0E */ SCHEDULE_CMD_CHECK_FLAG_S(0x3B, 0x01, 0x1A - 0x12), + /* 0x12 */ SCHEDULE_CMD_CHECK_FLAG_S(0x3D, 0x02, 0x18 - 0x16), + /* 0x16 */ SCHEDULE_CMD_RET_VAL_S(30), + /* 0x18 */ SCHEDULE_CMD_RET_VAL_S(31), + /* 0x1A */ SCHEDULE_CMD_RET_NONE(), + /* 0x1B */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867778[] = { + /* 0x0 */ SCHEDULE_CMD_RET_VAL_S(32), +}; + +u8 D_8086777C[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867780[] = { + /* 0x0 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8 D_80867784[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(22, 0, 0x6 - 0x4), + /* 0x4 */ SCHEDULE_CMD_RET_VAL_S(35), + /* 0x6 */ SCHEDULE_CMD_RET_NONE(), +}; + +u8* D_8086778C[] = { + D_808675D0, D_808675E4, D_80867634, D_80867640, D_8086764C, D_80867658, D_80867684, D_80867688, + D_80867690, D_80867698, D_808676A0, D_808676B8, D_808676D0, D_808676D4, D_808676D8, D_808676E4, + D_808676EC, D_808676F0, D_80867704, D_80867708, D_8086770C, D_80867710, D_80867714, D_8086771C, + D_80867734, D_8086773C, D_80867744, D_8086775C, D_80867778, D_8086777C, D_80867780, D_80867784, +}; + const ActorInit En_Door_InitVars = { ACTOR_EN_DOOR, ACTORCAT_DOOR, @@ -22,38 +289,394 @@ const ActorInit En_Door_InitVars = { (ActorFunc)EnDoor_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80867954[] = { +typedef struct { + /* 0x00 */ s16 sceneNum; + /* 0x02 */ u8 dListIndex; + /* 0x04 */ s16 objectId; +} EnDoorInfo; + +static EnDoorInfo sObjInfo[] = { + { SCENE_MITURIN, 0x01, OBJECT_NUMA_OBJ }, + { SCENE_TENMON_DAI, 0x02, OBJECT_DOR01 }, + { SCENE_00KEIKOKU, 0x02, OBJECT_DOR01 }, + { SCENE_30GYOSON, 0x02, OBJECT_DOR01 }, + { SCENE_LABO, 0x02, OBJECT_DOR01 }, + { SCENE_33ZORACITY, 0x03, OBJECT_DOR02 }, + { SCENE_UNSET_31, 0x03, OBJECT_DOR02 }, + { SCENE_BANDROOM, 0x03, OBJECT_DOR02 }, + { SCENE_20SICHITAI, 0x04, OBJECT_DOR03 }, + { SCENE_20SICHITAI2, 0x04, OBJECT_DOR03 }, + { SCENE_MAP_SHOP, 0x04, OBJECT_DOR03 }, + { SCENE_KAIZOKU, 0x0B, OBJECT_KAIZOKU_OBJ }, + { SCENE_PIRATE, 0x0B, OBJECT_KAIZOKU_OBJ }, + { SCENE_TORIDE, 0x0B, OBJECT_KAIZOKU_OBJ }, + { SCENE_KINDAN2, 0x0C, OBJECT_KINSTA2_OBJ }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x08, OBJECT_WDOR03 }, + { -1, 0x07, OBJECT_WDOR02 }, + { -1, 0x06, OBJECT_WDOR01 }, + { -1, 0x07, OBJECT_WDOR02 }, + { -1, 0x06, OBJECT_WDOR01 }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x09, OBJECT_WDOR04 }, + { -1, 0x08, OBJECT_WDOR03 }, + { -1, 0x08, OBJECT_WDOR03 }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x06, OBJECT_WDOR01 }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x00, GAMEPLAY_KEEP }, + { -1, 0x0A, OBJECT_WDOR05 }, + { -1, 0x0D, GAMEPLAY_FIELD_KEEP }, + { -1, 0x05, OBJECT_DOR04 }, + { -1, 0x09, OBJECT_WDOR04 }, + { -1, 0x04, OBJECT_DOR03 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_U16(shape.rot.x, 0, ICHAIN_CONTINUE), ICHAIN_U16(shape.rot.z, 0, ICHAIN_STOP), }; -#endif +static AnimationHeader* sAnimations[] = { + &gameplay_keep_Anim_020658, &gameplay_keep_Anim_022CA8, &gameplay_keep_Anim_020658, &gameplay_keep_Anim_022E68, + &gameplay_keep_Anim_0204B4, &gameplay_keep_Anim_022BE8, &gameplay_keep_Anim_022D90, &gameplay_keep_Anim_022BE8, + &gameplay_keep_Anim_022FF0, &gameplay_keep_Anim_0205A0, +}; +static u8 sAnimOpenFrames[10] = { + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +}; -extern InitChainEntry D_80867954[]; +static u8 sAnimCloseFrames[10] = { + 60, 60, 60, 70, 70, 60, 60, 60, 60, 70, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/EnDoor_Init.s") +static Gfx* D_808679A4[14][2] = { + { gDoorLeftDL, gDoorRightDL }, + { gWoodfallDoorDL, gWoodfallDoorDL }, + { object_dor01_DL_000448, object_dor01_DL_000448 }, + { gZoraHallDoorDL, gZoraHallDoorDL }, + { gSwampDoorDL, gSwampDoorDL }, + { gMagicHagPotionShopDoorDL, gMagicHagPotionShopDoorDL }, + { object_wdor01_DL_000548, object_wdor01_DL_000548 }, // Lottery Shop / Curiosity Shop / Mayor's House Door + { object_wdor02_DL_000548, object_wdor02_DL_000548 }, // Trading Post / Post Office Door + { object_wdor03_DL_000548, object_wdor03_DL_000548 }, // Stockpot Inn & Swordsman's School Door + { gMilkBarDoorDL, gMilkBarDoorDL }, + { gMusicBoxHouseDoorDL, gMusicBoxHouseDoorDL }, + { gPiratesFortressDoorDL, gPiratesFortressDoorDL }, + { object_mkk_DL_000310, object_mkk_DL_000310 }, + { gFieldWoodDoorLeftDL, gFieldWoodDoorRightDL }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/EnDoor_Destroy.s") +void EnDoor_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 objectBankIndex; + EnDoorInfo* objectInfo = sObjInfo; + EnDoor* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80866A5C.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80866B20.s") + this->unk_1A4 = ENDOOR_GET_PARAMS_7(thisx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80866F94.s") + this->switchFlag = ENDOOR_GET_PARAMS_7F(thisx); + if ((this->unk_1A4 == 7) && (this->switchFlag == 0)) { + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gDoorCol); + } + SkelAnime_Init(globalCtx, &this->skelAnime, &gDoorSkel, &gameplay_keep_Anim_020658, this->limbTable, + this->limbTable, 5); + if (this->unk_1A4 == 5) { + objectInfo = &sObjInfo[17 + this->switchFlag]; + } else { + for (i = 0; i < ARRAY_COUNT(sObjInfo) - 34; i++, objectInfo++) { + if (globalCtx->sceneNum == objectInfo->sceneNum) { + break; + } + } + if ((i >= ARRAY_COUNT(sObjInfo) - 34) && (Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_FIELD_KEEP) >= 0)) { + objectInfo++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_8086704C.s") + this->dlIndex = objectInfo->dListIndex; + objectBankIndex = Object_GetIndex(&globalCtx->objectCtx, objectInfo->objectId); + if (objectBankIndex < 0) { + objectInfo = &sObjInfo[15]; + objectBankIndex = Object_GetIndex(&globalCtx->objectCtx, objectInfo->objectId); + if (objectBankIndex != 0) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + } + this->requiredObjBankIndex = objectBankIndex; + this->dlIndex = objectInfo->dListIndex; // Set twice? + if (this->dyna.actor.objBankIndex == this->requiredObjBankIndex) { + func_80866A5C(this, globalCtx); + } else { + this->actionFunc = func_80866A5C; + } + Actor_SetFocus(&this->dyna.actor, 35.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80867080.s") +void EnDoor_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnDoor* this = (EnDoor*)thisx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_808670F0.s") + if (this->unk_1A4 != 7) { + TransitionActorEntry* transitionEntry = + &globalCtx->doorCtx.transitionActorList[(u16)this->dyna.actor.params >> 0xA]; + if (transitionEntry->id < 0) { + transitionEntry->id = -transitionEntry->id; + } + } else if (this->switchFlag == 0) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80867144.s") +void func_80866A5C(EnDoor* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->requiredObjBankIndex)) { + this->dyna.actor.objBankIndex = this->requiredObjBankIndex; + this->actionFunc = func_80866B20; + this->dyna.actor.world.rot.y = 0; + if (this->unk_1A4 == 1) { + if (!Flags_GetSwitch(globalCtx, this->switchFlag)) { + this->unk_1A6 = 10; + } + } else if ((this->unk_1A4 == 4) && + (Actor_XZDistanceBetweenActors(&this->dyna.actor, &GET_PLAYER(globalCtx)->actor) > 120.0f)) { + this->actionFunc = func_8086704C; + this->dyna.actor.world.rot.y = -0x1800; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/EnDoor_Update.s") +void func_80866B20(EnDoor* this, GlobalContext* globalCtx) { + static s32 D_80867BC0[4]; + Player* player = GET_PLAYER(globalCtx); + Vec3f playerPosRelToDoor; + s16 temp_a2; + s16 yawDiff; + s32 temp_a1_2; + s32 temp_t0; + u8 temp_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/func_80867350.s") + if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state) && (this->dyna.actor.textId == 0x1821)) { + D_80867BC0[0] = 1; + } + if (this->unk_1A1 != 0) { + this->actionFunc = func_80867144; + Animation_PlayOnceSetSpeed(&this->skelAnime, sAnimations[this->animIndex], + (player->stateFlags1 & 0x8000000) ? 0.75f : 1.5f); + if (this->unk_1A6 != 0) { + gSaveContext.save.inventory.dungeonKeys[gSaveContext.mapIndex]--; + Flags_SetSwitch(globalCtx, this->switchFlag); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_CHAIN_KEY_UNLOCK); + } + } else if (this->unk_1A7 != 0) { + this->actionFunc = func_80866F94; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DOOR_OPEN); + } else if (!Player_InCsMode(&globalCtx->state)) { + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &playerPosRelToDoor, &player->actor.world.pos); + if ((D_80867BC0[0] != 0) || ((fabsf(playerPosRelToDoor.y) < 20.0f) && (fabsf(playerPosRelToDoor.x) < 20.0f) && + (fabsf(playerPosRelToDoor.z) < 50.0f))) { + yawDiff = player->actor.shape.rot.y - this->dyna.actor.shape.rot.y; + if (playerPosRelToDoor.z > 0.0f) { + yawDiff = (0x8000 - yawDiff); + } + if (ABS_ALT(yawDiff) < 0x3000) { + player->doorType = 1; + player->doorDirection = playerPosRelToDoor.z >= 0.0f ? 1.0f : -1.0f; + player->doorActor = &this->dyna.actor; + if (this->unk_1A6 != 0) { + if (gSaveContext.save.inventory.dungeonKeys[((void)0, gSaveContext.mapIndex)] <= 0) { + player->doorType = -1; + this->dyna.actor.textId = 0x1802; + } else { + player->doorTimer = 10; + } + } else if (this->unk_1A4 == 4) { + player->doorType = -1; + this->dyna.actor.textId = 0x1800; + } else if ((this->unk_1A4 == 0) || (this->unk_1A4 == 2) || (this->unk_1A4 == 3)) { + s32 textIdOffset; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Door/EnDoor_Draw.s") + temp_t0 = (globalCtx->actorCtx.unkC & 0x2AA) >> 1; + temp_a2 = D_801AED48[this->switchFlag & 7]; + temp_a1_2 = globalCtx->actorCtx.unkC & 0x155; + textIdOffset = (this->switchFlag >> 3) & 0xF; + if (((this->unk_1A4 == 0) && (((temp_t0 | temp_a1_2) & temp_a2) == 0)) || + ((this->unk_1A4 == 2) && ((temp_a2 & temp_a1_2) == 0)) || + ((this->unk_1A4 == 3) && ((temp_a2 & temp_t0) == 0))) { + s16 baseTextId = 0x182D; + + if (this->unk_1A4 == 3) { + baseTextId = 0x180D; + } else if (this->unk_1A4 == 2) { + baseTextId = 0x181D; + } + player->doorType = -1; + this->dyna.actor.textId = baseTextId + textIdOffset; + } + } else if ((this->unk_1A4 == 5) && (playerPosRelToDoor.z > 0.0f)) { + ScheduleResult sp30; + + if (Schedule_RunScript(globalCtx, D_8086778C[this->switchFlag], &sp30) != 0) { + this->dyna.actor.textId = sp30.result + 0x1800; + + player->doorType = ((this->dyna.actor.textId == 0x1821) && (D_80867BC0[0] != 0)) ? 5 : -1; + } + } + func_80122F28(player); + } + } else if ((this->unk_1A4 == 4) && (this->dyna.actor.xzDistToPlayer > 240.0f)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DOOR_OPEN); + this->actionFunc = func_80867080; + } + } +} + +void func_80866F94(EnDoor* this, GlobalContext* globalCtx) { + s32 direction; + + if (this->unk_1A7 != 0) { + if (this->unk_1A7 >= 0) { + direction = 1; + } else { + direction = -1; + } + if (Math_ScaledStepToS(&this->dyna.actor.world.rot.y, direction * 0x3E80, 0x7D0)) { + Math_StepToC(&this->unk_1A7, 0, 1); + } + } else { + if (Math_ScaledStepToS(&this->dyna.actor.world.rot.y, 0, 0x7D0)) { + this->actionFunc = func_80866B20; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_AUTO_DOOR_CLOSE); + } + } +} + +void func_8086704C(EnDoor* this, GlobalContext* globalCtx) { + if (this->dyna.actor.xzDistToPlayer < 120.0f) { + this->actionFunc = func_808670F0; + } +} + +void func_80867080(EnDoor* this, GlobalContext* globalCtx) { + if (this->dyna.actor.xzDistToPlayer < 120.0f) { + this->actionFunc = func_808670F0; + } else if (Math_ScaledStepToS(&this->dyna.actor.world.rot.y, -0x1800, 0x100)) { + this->actionFunc = func_8086704C; + } +} + +void func_808670F0(EnDoor* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->dyna.actor.world.rot.y, 0, 0x700)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DOOR_CLOSE); + this->actionFunc = func_80866B20; + } +} + +void func_80867144(EnDoor* this, GlobalContext* globalCtx) { + s32 numEffects; + s32 i; + + if (DECR(this->unk_1A6) == 0) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + this->actionFunc = func_80866B20; + this->unk_1A1 = 0; + } else if (Animation_OnFrame(&this->skelAnime, sAnimOpenFrames[this->animIndex])) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_OC_DOOR_OPEN); + if (this->skelAnime.playSpeed < 1.5f) { + numEffects = (s32)(Rand_ZeroOne() * 30.0f) + 50; + for (i = 0; i < numEffects; i++) { + EffectSsBubble_Spawn(globalCtx, &this->dyna.actor.world.pos, 60.0, 100.0f, 50.0f, 0.15f); + } + } + } else if (Animation_OnFrame(&this->skelAnime, sAnimCloseFrames[this->animIndex])) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DOOR_CLOSE); + } + } +} + +void EnDoor_Update(Actor* thisx, GlobalContext* globalCtx) { + EnDoor* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 EnDoor_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + TransitionActorEntry* transitionEntry; + EnDoor* this = THIS; + + if (limbIndex == 4) { + Gfx** dl = D_808679A4[this->dlIndex]; + s16 temp; + s32 dlIndex; + + transitionEntry = NULL; + + if (this->unk_1A4 != 7) { + transitionEntry = &globalCtx->doorCtx.transitionActorList[(u16)this->dyna.actor.params >> 0xA]; + } + rot->z += this->dyna.actor.world.rot.y; + if ((this->unk_1A4 == 7) || (globalCtx->roomCtx.prevRoom.num >= 0) || + (transitionEntry->sides[0].room == transitionEntry->sides[1].room)) { + s32 pad; + + temp = (this->dyna.actor.shape.rot.y + this->skelAnime.jointTable[3].z + rot->z) - + Math_Vec3f_Yaw(&globalCtx->view.eye, &this->dyna.actor.world.pos); + *dList = (ABS_ALT(temp) < 0x4000) ? dl[0] : dl[1]; + + } else { + dlIndex = 0; + if (transitionEntry->sides[0].room != this->dyna.actor.room) { + dlIndex = 1; + } + *dList = dl[dlIndex]; + } + } + return false; +} + +void EnDoor_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnDoor* this = THIS; + + if (this->dyna.actor.objBankIndex == this->requiredObjBankIndex) { + OPEN_DISPS(globalCtx->state.gfxCtx); + if ((this->unk_1A4 == 7) && (this->switchFlag == 0)) { + Gfx_DrawDListOpa(globalCtx, gameplay_keep_DL_0221B8); + } else { + func_8012C28C(globalCtx->state.gfxCtx); + } + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnDoor_OverrideLimbDraw, + NULL, &this->dyna.actor); + if (this->dyna.actor.world.rot.y != 0) { + if (this->dyna.actor.world.rot.y > 0) { + gSPDisplayList(POLY_OPA_DISP++, gDoorRightDL); + } else { + gSPDisplayList(POLY_OPA_DISP++, gDoorLeftDL); + } + } + if (this->unk_1A6) { + Actor_DrawDoorLock(globalCtx, this->unk_1A6, 0); + } + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} 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 08ec52be6..bc94e150e 100644 --- a/src/overlays/actors/ovl_En_Door/z_en_door.h +++ b/src/overlays/actors/ovl_En_Door/z_en_door.h @@ -7,13 +7,24 @@ struct EnDoor; typedef void (*EnDoorActionFunc)(struct EnDoor*, GlobalContext*); +#define ENDOOR_GET_PARAMS_7(thisx) (((thisx)->params >> 7) & 7) +#define ENDOOR_GET_PARAMS_7F(thisx) (((thisx)->params) & 0x7F) + + typedef struct EnDoor { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x63]; - /* 0x01A7 */ s8 unk1A7; - /* 0x01A8 */ char unk_1A8[0x20]; - /* 0x01C8 */ EnDoorActionFunc actionFunc; -} EnDoor; // size = 0x1CC + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ SkelAnime skelAnime; + /* 0x1A0 */ u8 animIndex; + /* 0x1A1 */ u8 unk_1A1; + /* 0x1A2 */ s8 requiredObjBankIndex; + /* 0x1A3 */ s8 dlIndex; + /* 0x1A4 */ u8 unk_1A4; + /* 0x1A5 */ u8 switchFlag; + /* 0x1A6 */ u8 unk_1A6; + /* 0x1A7 */ s8 unk_1A7; + /* 0x1A8 */ Vec3s limbTable[5]; + /* 0x1C8 */ EnDoorActionFunc actionFunc; +} EnDoor; extern const ActorInit En_Door_InitVars; diff --git a/src/overlays/actors/ovl_En_Door_Etc/z_en_door_etc.c b/src/overlays/actors/ovl_En_Door_Etc/z_en_door_etc.c index 074739aa1..9b53c36d2 100644 --- a/src/overlays/actors/ovl_En_Door_Etc/z_en_door_etc.c +++ b/src/overlays/actors/ovl_En_Door_Etc/z_en_door_etc.c @@ -1,6 +1,12 @@ +/* + * File: z_en_door_etc.c + * Overlay: ovl_En_Door_Etc + * Description: Wooden Door + */ + #include "z_en_door_etc.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnDoorEtc*)thisx) diff --git a/src/overlays/actors/ovl_En_Dragon/z_en_dragon.c b/src/overlays/actors/ovl_En_Dragon/z_en_dragon.c index 8c16469f8..a37d8f828 100644 --- a/src/overlays/actors/ovl_En_Dragon/z_en_dragon.c +++ b/src/overlays/actors/ovl_En_Dragon/z_en_dragon.c @@ -1,6 +1,12 @@ +/* + * File: z_en_dragon.c + * Overlay: ovl_En_Dragon + * Description: Deep Python + */ + #include "z_en_dragon.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnDragon*)thisx) @@ -9,16 +15,41 @@ void EnDragon_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnDragon_Update(Actor* thisx, GlobalContext* globalCtx); void EnDragon_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80B5ED90(EnDragon* this, GlobalContext* globalCtx); -void func_80B5EE3C(EnDragon* this, GlobalContext* globalCtx); -void func_80B5EFD0(EnDragon* this, GlobalContext* globalCtx); -void func_80B5F418(EnDragon* this, GlobalContext* globalCtx); -void func_80B5F508(EnDragon* this, GlobalContext* globalCtx); -void func_80B5F8D8(EnDragon* this, GlobalContext* globalCtx); -void func_80B5FCC0(EnDragon* this, GlobalContext* globalCtx); -void func_80B5FD68(EnDragon* this, GlobalContext* globalCtx); +void EnDragon_SetupRetreatOrIdle(EnDragon* this); +void EnDragon_RetreatOrIdle(EnDragon* this, GlobalContext* globalCtx); +void EnDragon_SetupExtend(EnDragon* this); +void EnDragon_Extend(EnDragon* this, GlobalContext* globalCtx); +void EnDragon_Grab(EnDragon* this, GlobalContext* globalCtx); +void EnDragon_SetupAttack(EnDragon* this); +void EnDragon_Attack(EnDragon* this, GlobalContext* globalCtx); +void EnDragon_Dead(EnDragon* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ DEEP_PYTHON_ANIMATION_SMALL_SIDE_SWAY, + /* 1 */ DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY, + /* 2 */ DEEP_PYTHON_ANIMATION_VERTICAL_SWAY, + /* 3 */ DEEP_PYTHON_ANIMATION_IDLE +} DeepPythonAnimationIndex; + +typedef enum { + /* 0 */ DEEP_PYTHON_EXTEND_STATE_NOT_FULLY_EXTENDED, + /* 1 */ DEEP_PYTHON_EXTEND_STATE_FULLY_EXTENDED, + /* 2 */ DEEP_PYTHON_EXTEND_STATE_REPEAT_LARGE_SWAY, + /* 3 */ DEEP_PYTHON_EXTEND_STATE_REPEAT_SMALL_SWAY, +} DeepPythonExtendState; + +typedef enum { + /* 0 */ DEEP_PYTHON_GRAB_STATE_START, + /* 1 */ DEEP_PYTHON_GRAB_STATE_GRABBED, +} DeepPythonGrabState; + +typedef enum { + /* 0 */ DEEP_PYTHON_ATTACK_STATE_START, + /* 1 */ DEEP_PYTHON_ATTACK_STATE_RELEASED, +} DeepPythonAttackState; + +static s32 sNumPythonsDead = 0; -#if 0 const ActorInit En_Dragon_InitVars = { ACTOR_EN_DRAGON, ACTORCAT_ENEMY, @@ -31,130 +62,779 @@ const ActorInit En_Dragon_InitVars = { (ActorFunc)EnDragon_Draw, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B605F4 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(0, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0xF), - /* Normal arrow */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0x0), - /* Goron punch */ DMG_ENTRY(0, 0x0), - /* Sword */ DMG_ENTRY(0, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(0, 0x0), - /* Ice arrow */ DMG_ENTRY(0, 0x0), - /* Light arrow */ DMG_ENTRY(0, 0x0), - /* Goron spikes */ DMG_ENTRY(0, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x0), - /* Deku bubble */ DMG_ENTRY(0, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(1, 0xF), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(0, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0xF), - /* Spin attack */ DMG_ENTRY(0, 0x0), - /* 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 */ DEEP_PYTHON_DMGEFF_NONE, + /* 0xF */ DEEP_PYTHON_DMGEFF_DAMAGE = 0xF +} DeepPythonDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, DEEP_PYTHON_DMGEFF_DAMAGE), + /* Zora boomerang */ DMG_ENTRY(1, DEEP_PYTHON_DMGEFF_DAMAGE), + /* Normal arrow */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Goron punch */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Ice arrow */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Light arrow */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Goron spikes */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Deku bubble */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(1, DEEP_PYTHON_DMGEFF_DAMAGE), + /* Normal shield */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, DEEP_PYTHON_DMGEFF_DAMAGE), + /* Spin attack */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DEEP_PYTHON_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, DEEP_PYTHON_DMGEFF_DAMAGE), }; -// static ColliderJntSphElementInit sJntSphElementsInit[8] = { -static ColliderJntSphElementInit D_80B60614[8] = { +static ColliderJntSphElementInit sJntSphElementsInit[8] = { { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 13, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_HEAD, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 12, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_COLLAR, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 12, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_COLLAR, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 10, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_BODY_SEGMENT_1, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 10, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_BODY_SEGMENT_1, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 9, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_BODY_SEGMENT_2, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 9, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_BODY_SEGMENT_2, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK1, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 9, { { 0, 0, 0 }, 0 }, 1 }, + { + ELEMTYPE_UNK1, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { DEEP_PYTHON_LIMB_BODY_SEGMENT_2, { { 0, 0, 0 }, 0 }, 1 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B60734 = { - { COLTYPE_HIT6, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 8, D_80B60614, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT6, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -#endif +void EnDragon_Init(Actor* thisx, GlobalContext* globalCtx) { + EnDragon* this = THIS; -extern DamageTable D_80B605F4; -extern ColliderJntSphElementInit D_80B60614[8]; -extern ColliderJntSphInit D_80B60734; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gDeepPythonSkel, &gDeepPythonSmallSideSwayAnim, this->jointTable, + this->morphTable, DEEP_PYTHON_LIMB_MAX); -extern UNK_TYPE D_060048B8; + this->actor.colChkInfo.health = 4; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.targetMode = 0xA; + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/EnDragon_Init.s") + this->collider.elements[0].dim.scale = this->collider.elements[1].dim.scale = this->collider.elements[2].dim.scale = + this->collider.elements[3].dim.scale = this->collider.elements[4].dim.scale = + this->collider.elements[5].dim.scale = this->collider.elements[6].dim.scale = + this->collider.elements[7].dim.scale = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/EnDragon_Destroy.s") + this->collider.elements[0].dim.modelSphere.radius = 150; + this->collider.elements[0].dim.modelSphere.center.x = 420; + this->collider.elements[1].dim.modelSphere.radius = 160; + this->collider.elements[1].dim.modelSphere.center.x = 630; + this->collider.elements[2].dim.modelSphere.radius = 130; + this->collider.elements[2].dim.modelSphere.center.x = 630; + this->collider.elements[3].dim.modelSphere.radius = 170; + this->collider.elements[3].dim.modelSphere.center.x = 920; + this->collider.elements[4].dim.modelSphere.radius = 150; + this->collider.elements[4].dim.modelSphere.center.x = 530; + this->collider.elements[5].dim.modelSphere.radius = 140; + this->collider.elements[5].dim.modelSphere.center.x = 730; + this->collider.elements[6].dim.modelSphere.radius = 120; + this->collider.elements[6].dim.modelSphere.center.x = 430; + this->collider.elements[7].dim.modelSphere.radius = 110; + this->collider.elements[7].dim.modelSphere.center.x = 160; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EAA0.s") + this->pythonIndex = EN_DRAGON_GET_PYTHON_INDEX(&this->actor); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->action = DEEP_PYTHON_ACTION_IDLE; + this->actor.hintId = 0xE; + this->scale = 0.5f; + this->actor.flags &= ~ACTOR_FLAG_8000000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EB40.s") + EnDragon_SetupRetreatOrIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5ED90.s") +void EnDragon_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnDragon* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EDF0.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EE3C.s") +static AnimationHeader* sAnimations[] = { + &gDeepPythonSmallSideSwayAnim, + &gDeepPythonLargeSideSwayAnim, + &gDeepPythonVerticalSwayAnim, + &gDeepPythonSmallSideSwayAnim, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EF88.s") +static u8 sAnimationModes[] = { ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5EFD0.s") +void EnDragon_ChangeAnimation(EnDragon* this, s32 animationIndex) { + f32 startFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5F3A4.s") + this->animationIndex = animationIndex; + this->endFrame = Animation_GetLastFrame(sAnimations[animationIndex]); + startFrame = 0.0f; + if (this->animationIndex == DEEP_PYTHON_ANIMATION_IDLE) { + startFrame = this->endFrame; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5F418.s") + Animation_Change(&this->skelAnime, sAnimations[animationIndex], 1.0f, startFrame, this->endFrame, + sAnimationModes[this->animationIndex], -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5F508.s") +static Color_RGBA8 sBubblePrimColors[] = { + { 255, 255, 255, 255 }, + { 150, 255, 255, 255 }, + { 100, 255, 255, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5F888.s") +static Color_RGBA8 sBubbleEnvColors[] = { + { 150, 150, 150, 0 }, + { 0, 100, 0, 255 }, + { 0, 0, 255, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5F8D8.s") +void EnDragon_SpawnBubbles(EnDragon* this, GlobalContext* globalCtx, Vec3f basePos) { + static Vec3f sBubbleVelocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f sBubbleAccel = { 0.0f, 0.1f, 0.0f }; + s32 bubbleCount; + s16 colorIndex; + s16 scale; + Vec3f bubblePos; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5FCC0.s") + bubbleCount = (s32)randPlusMinusPoint5Scaled(5.0f) + 10; + colorIndex = 0; + if (this->action == DEEP_PYTHON_ACTION_DEAD) { + colorIndex = 1; + bubbleCount = (s32)randPlusMinusPoint5Scaled(5.0f) + 10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B5FD68.s") + for (i = 0; i < bubbleCount; i++) { + Math_Vec3f_Copy(&bubblePos, &basePos); + sBubbleVelocity.x = Rand_ZeroFloat(1.0f) * 23.0f; + sBubbleVelocity.y = Rand_ZeroFloat(1.0f) * 10.0f; + sBubbleVelocity.z = Rand_ZeroFloat(1.0f) * 23.0f; + bubblePos.x += randPlusMinusPoint5Scaled(i * 30.0f); + bubblePos.y += randPlusMinusPoint5Scaled(5.0f); + bubblePos.z += randPlusMinusPoint5Scaled(i * 30.0f); + sBubbleAccel.y = Rand_ZeroFloat(1.0f) * 20.0f * 3.0f; + scale = Rand_S16Offset(380, 240); + EffectSsDtBubble_SpawnCustomColor(globalCtx, &bubblePos, &sBubbleVelocity, &sBubbleAccel, + &sBubblePrimColors[colorIndex], &sBubbleEnvColors[colorIndex], scale, 30, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B60138.s") +void EnDragon_RetreatOnceTimerEnds(EnDragon* this, GlobalContext* globalCtx) { + if (this->timer == 0) { + func_800B8D50(globalCtx, &this->actor, 10.0f, this->actor.world.rot.y, 10.0f, 8); + EnDragon_SetupRetreatOrIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/EnDragon_Update.s") +void EnDragon_SetupRetreatOrIdle(EnDragon* this) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_IDLE); + this->state = 0; + this->unk_2CC = 0; + this->hasGrabbedPlayer = false; + this->grabTimer = 0; + this->timer = 30; + this->actionFunc = EnDragon_RetreatOrIdle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B6043C.s") +void EnDragon_RetreatOrIdle(EnDragon* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->action == DEEP_PYTHON_ACTION_EXTEND) { + EnDragon_SetupExtend(this); + } else if ((this->timer != 0) && (fabsf(this->actor.world.pos.x - this->actor.home.pos.x) > 101.0f) && + (fabsf(this->actor.world.pos.z - this->actor.home.pos.z) > 101.0f)) { + this->actor.speedXZ = -100.0f; + } else { + this->actor.speedXZ = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/func_80B60494.s") + if ((fabsf(this->actor.world.pos.x - this->actor.home.pos.x) > 4.0f) && + (fabsf(this->actor.world.pos.z - this->actor.home.pos.z) > 4.0f)) { + Math_ApproachF(&this->actor.world.pos.x, this->actor.home.pos.x, 0.3f, 200.0f); + Math_ApproachF(&this->actor.world.pos.z, this->actor.home.pos.z, 0.3f, 200.0f); + } else if (this->action != DEEP_PYTHON_ACTION_IDLE) { + this->action = DEEP_PYTHON_ACTION_IDLE; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Dragon/EnDragon_Draw.s") +void EnDragon_SetupExtend(EnDragon* this) { + this->state = 0; + this->behindJawRetreatTimer = this->state; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_APPEAR_TRG); + this->retreatTimer = 250; + this->actionFunc = EnDragon_Extend; +} + +void EnDragon_Extend(EnDragon* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 currentFrame = this->skelAnime.curFrame; + s16 yaw; + + EnDragon_SpawnBubbles(this, globalCtx, this->jawPos); + + if (this->action >= DEEP_PYTHON_ACTION_DAMAGE) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_BACK); + EnDragon_SetupRetreatOrIdle(this); + } else if (this->retreatTimer == 0) { + this->action = DEEP_PYTHON_ACTION_RETREAT; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_BACK); + EnDragon_SetupRetreatOrIdle(this); + } else if (this->state == DEEP_PYTHON_EXTEND_STATE_NOT_FULLY_EXTENDED) { + Vec3f extendedPos; + + Math_Vec3f_Copy(&extendedPos, &this->burrowEntrancePos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_APPEAR - SFX_FLAG); + extendedPos.x += Math_SinS(this->actor.world.rot.y) * -530.0f; + extendedPos.z += Math_CosS(this->actor.world.rot.y) * -530.0f; + this->actor.speedXZ = 40.0f; + Math_SmoothStepToS(&this->jawZRotation, 0xFA0, 5, 0xBB8, 0x14); + + if ((fabsf(this->actor.world.pos.x - extendedPos.x) < 51.0f) && + (fabsf(this->actor.world.pos.z - extendedPos.z) < 51.0f)) { + this->actor.speedXZ = 0.0f; + Math_ApproachF(&this->actor.world.pos.x, extendedPos.x, 0.3f, 50.0f); + Math_ApproachF(&this->actor.world.pos.z, extendedPos.z, 0.3f, 50.0f); + if ((fabsf(this->actor.world.pos.x - extendedPos.x) < 4.0f) && + (fabsf(this->actor.world.pos.z - extendedPos.z) < 4.0f)) { + if (this->animationIndex != DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY); + } + + this->state = DEEP_PYTHON_EXTEND_STATE_FULLY_EXTENDED; + } + } + } else { + Math_SmoothStepToS(&this->jawZRotation, 0, 5, 0xBB8, 0x14); + SkelAnime_Update(&this->skelAnime); + if (this->state == DEEP_PYTHON_EXTEND_STATE_FULLY_EXTENDED) { + if (currentFrame < this->endFrame) { + return; + } + + this->state = DEEP_PYTHON_EXTEND_STATE_REPEAT_LARGE_SWAY; + } + + yaw = ABS_ALT(BINANG_SUB(Math_Vec3f_Yaw(&this->jawPos, &player->actor.world.pos), this->actor.shape.rot.y)); + if (yaw < 0x5000) { + // Player is in front of the jaw + if ((this->endFrame <= currentFrame) && (this->largeSwayWaitTimer == 0)) { + if (this->animationIndex != DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY); + } + + this->state = DEEP_PYTHON_EXTEND_STATE_REPEAT_LARGE_SWAY; + } + + this->behindJawRetreatTimer = 0; + } else { + // Player is in behind the jaw + if (this->state == DEEP_PYTHON_EXTEND_STATE_REPEAT_LARGE_SWAY) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_SMALL_SIDE_SWAY); + this->largeSwayWaitTimer = Rand_ZeroFloat(20.0f) + this->endFrame; + this->state = DEEP_PYTHON_EXTEND_STATE_REPEAT_SMALL_SWAY; + } + + this->behindJawRetreatTimer++; + if (this->behindJawRetreatTimer > 60) { + this->action = DEEP_PYTHON_ACTION_RETREAT; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_BACK); + EnDragon_SetupRetreatOrIdle(this); + } + } + } +} + +void EnDragon_CameraSetAtEye(EnDragon* this, GlobalContext* globalCtx, Vec3f eye, Vec3f at) { + this->cameraId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Math_Vec3f_Copy(&this->cameraEye, &eye); + Math_Vec3f_Copy(&this->cameraAt, &at); + Play_CameraSetAtEye(globalCtx, this->cameraId, &this->cameraAt, &this->cameraEye); +} + +void EnDragon_SetupGrab(EnDragon* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f extendedPos; + s16 yaw; + + if (!ActorCutscene_GetCanPlayNext(this->grabCutsceneIndex)) { + ActorCutscene_SetIntentToPlay(this->grabCutsceneIndex); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->grabCutsceneIndex, &this->actor); + Math_Vec3f_Copy(&extendedPos, &this->burrowEntrancePos); + extendedPos.x += Math_SinS(this->actor.world.rot.y) * -530.0f; + extendedPos.z += Math_CosS(this->actor.world.rot.y) * -530.0f; + Math_Vec3f_Copy(&this->actor.world.pos, &extendedPos); + yaw = Math_Vec3f_Yaw(&player->actor.world.pos, &this->jawPos); + player->actor.shape.rot.y = yaw; + player->actor.world.rot.y = yaw; + this->state = DEEP_PYTHON_GRAB_STATE_START; + this->grabTimer = 0; + this->hasGrabbedPlayer = false; + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_IDLE); + this->actionFunc = EnDragon_Grab; + } +} + +static Vec3f sCameraEyePerPython[] = { + { 1600.0f, 0.0f, 1400.0f }, { 1400.0f, 0.0f, 400.0f }, { 1800.0f, 0.0f, 1400.f }, { 1100.0f, -200.0f, 1500.0f }, + { 2000.0f, 0.0f, 1500.0f }, { 1900.0f, 0.0f, 1800.0f }, { 1700.0f, 0.0f, 1100.0f }, { 1700.0f, 0.0f, 1100.0f }, +}; + +static Vec3f sCameraAtPerPython[] = { + { 300.0f, -100.0f, 1300.0f }, { 1500.0f, 0.0f, 2400.0f }, { 300.0f, -100.0f, 1300.0f }, { 1900.0f, 500.0f, 600.0f }, + { -1000.0f, 0.0f, 1000.0f }, { 1200.0f, 0.0f, 1500.0f }, { 1100.0f, 0.0f, 2000.0f }, { 1100.0f, 0.0f, 2000.0f }, +}; + +static s16 sZRotPerPython[] = { 0x07D0, 0x07D0, 0x07D0, 0x07D0, 0x07D0, 0x0BB8, 0x0000, 0x0000 }; + +static s32 sMaxGrabTimerPerPython[] = { 5, 5, 5, 4, 5, 8, 5, 5 }; + +void EnDragon_Grab(EnDragon* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp50; // used as both the extended position and the camera eye + Vec3f at; + + this->cameraId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + SkelAnime_Update(&this->skelAnime); + + if (this->grabTimer == 0) { + if (!this->hasGrabbedPlayer) { + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerGrabPosition); + Math_Vec3f_Copy(&this->playerGrabPositionTemp, &this->playerGrabPosition); + this->hasGrabbedPlayer = true; + } else { + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerGrabPositionTemp); + } + + Math_Vec3f_Copy(&sp50, &this->burrowEntrancePos); + sp50.x += Math_SinS(this->actor.world.rot.y) * -930.0f; + sp50.z += Math_CosS(this->actor.world.rot.y) * -930.0f; + Math_Vec3f_Copy(&this->actor.world.pos, &sp50); + this->jawZRotation = 0x1450; + this->actor.speedXZ = 60.0f; + } + + this->grabTimer++; + Math_SmoothStepToS(&this->actor.shape.rot.z, sZRotPerPython[this->pythonIndex], 0xA, 0x1F4, 0x14); + EnDragon_SpawnBubbles(this, globalCtx, this->jawPos); + + Math_Vec3f_Copy(&sp50, &this->burrowEntrancePos); + sp50.x += Math_SinS(this->actor.world.rot.y) * sCameraEyePerPython[this->pythonIndex].x; + sp50.y += sCameraEyePerPython[this->pythonIndex].y; + sp50.z += Math_CosS(this->actor.world.rot.y) * sCameraEyePerPython[this->pythonIndex].z; + + Math_Vec3f_Copy(&at, &this->actor.world.pos); + at.x += Math_SinS(this->actor.world.rot.y) * sCameraAtPerPython[this->pythonIndex].x; + at.y += sCameraAtPerPython[this->pythonIndex].y; + at.z += Math_CosS(this->actor.world.rot.y) * sCameraAtPerPython[this->pythonIndex].z; + + EnDragon_CameraSetAtEye(this, globalCtx, sp50, at); + + if (this->grabTimer > sMaxGrabTimerPerPython[this->pythonIndex]) { + if (this->state == DEEP_PYTHON_GRAB_STATE_START) { + func_800B7298(globalCtx, &this->actor, 6); + this->state = DEEP_PYTHON_GRAB_STATE_GRABBED; + } + + globalCtx->unk_18770(globalCtx, player); + player->actor.parent = &this->actor; + player->unk_AE8 = 50; + this->action = DEEP_PYTHON_ACTION_GRAB; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_EAT); + EnDragon_SetupAttack(this); + } +} + +void EnDragon_SetupAttack(EnDragon* this) { + if (this->animationIndex != DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY); + } + + this->behindJawRetreatTimer = 0; + this->grabTimer = 0; + this->state = DEEP_PYTHON_ATTACK_STATE_START; + this->actionFunc = EnDragon_Attack; +} + +void EnDragon_Attack(EnDragon* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 currentFrame = this->skelAnime.curFrame; + Vec3f sp4C; // used as both the extended position and the camera eye + Vec3f at; + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.shape.rot.z, 0, 0xA, 0x1388, 0); + if ((globalCtx->gameplayFrames % 16) == 0) { + globalCtx->damagePlayer(globalCtx, -2); + + //! @bug: This function should only pass Player*: it uses *(this + 0x153), which is meant to be + //! player->currentMask, but in this case is garbage in the skelAnime + func_800B8E58((Player*)this, player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_BITE); + CollisionCheck_GreenBlood(globalCtx, NULL, &player->actor.world.pos); + } + + Math_Vec3f_Copy(&sp4C, &this->actor.world.pos); + sp4C.x += Math_SinS(this->actor.world.rot.y) * 3000.0f; + sp4C.y += 600.0f; + sp4C.z += Math_CosS(this->actor.world.rot.y) * 3000.0f; + + Math_Vec3f_Copy(&at, &this->actor.world.pos); + at.x += Math_SinS(this->actor.world.rot.y) * 1200.0f; + at.y += -100.0f; + at.z += Math_CosS(this->actor.world.rot.y) * 1200.0f; + + EnDragon_CameraSetAtEye(this, globalCtx, sp4C, at); + + player->actor.world.rot.y = player->actor.shape.rot.y = this->actor.world.rot.y; + player->actor.world.rot.x = player->actor.shape.rot.x = this->actor.world.rot.x; + player->actor.world.rot.z = player->actor.shape.rot.z = this->actor.world.rot.z - 0x36B0; + Math_Vec3f_Copy(&player->actor.world.pos, &this->playerGrabPosition); + this->jawZRotation = 0xC8; + + Math_Vec3f_Copy(&sp4C, &this->burrowEntrancePos); + sp4C.x += Math_SinS(this->actor.world.rot.y) * -530.0f; + sp4C.z += Math_CosS(this->actor.world.rot.y) * -530.0f; + Math_ApproachF(&this->actor.world.pos.x, sp4C.x, 0.3f, 200.0f); + Math_ApproachF(&this->actor.world.pos.y, sp4C.y, 0.3f, 200.0f); + Math_ApproachF(&this->actor.world.pos.z, sp4C.z, 0.3f, 200.0f); + + if ((this->state <= DEEP_PYTHON_ATTACK_STATE_START) && (this->endFrame <= currentFrame)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_BITE); + if (this->animationIndex != DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY) { + EnDragon_ChangeAnimation(this, DEEP_PYTHON_ANIMATION_LARGE_SIDE_SWAY); + } + + this->state++; + } + + if (((this->state != DEEP_PYTHON_ATTACK_STATE_START) && (this->endFrame <= currentFrame)) || + (!(player->stateFlags2 & 0x80)) || ((this->collider.elements[0].info.bumperFlags & BUMP_HIT)) || + (this->collider.elements[1].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[2].info.bumperFlags & BUMP_HIT)) { + player->actor.parent = NULL; + this->grabWaitTimer = 30; + ActorCutscene_Stop(this->grabCutsceneIndex); + if (player->stateFlags2 & 0x80) { + player->unk_AE8 = 100; + } + + this->actor.flags &= ~ACTOR_FLAG_100000; + + if ((this->state != DEEP_PYTHON_ATTACK_STATE_START) && (this->endFrame <= currentFrame)) { + this->timer = 3; + this->actionFunc = EnDragon_RetreatOnceTimerEnds; + } else { + EnDragon_SetupRetreatOrIdle(this); + } + } +} + +void EnDragon_SetupDead(EnDragon* this, GlobalContext* globalCtx) { + if (!ActorCutscene_GetCanPlayNext(this->deathCutsceneIndex)) { + ActorCutscene_SetIntentToPlay(this->deathCutsceneIndex); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->deathCutsceneIndex, &this->actor); + this->endFrame = Animation_GetLastFrame(&gDeepPythonSmallSideSwayAnim); + Animation_Change(&this->skelAnime, &gDeepPythonSmallSideSwayAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f); + this->timer = 20; + this->actionFunc = EnDragon_Dead; + } +} + +void EnDragon_Dead(EnDragon* this, GlobalContext* globalCtx) { + Vec3f seahorsePos; + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.z += 0x1000; + this->jawZRotation = 0xFA0; + EnDragon_SpawnBubbles(this, globalCtx, this->jawPos); + + if ((this->timer != 0) && (fabsf(this->actor.world.pos.x - this->actor.home.pos.x) > 121.0f) && + (fabsf(this->actor.world.pos.z - this->actor.home.pos.z) > 121.0f)) { + this->actor.speedXZ = -120.0f; + if (((this->pythonIndex & 1) == 0) && (Rand_ZeroOne() < 0.5f)) { + //! @bug: !globalCtx->gameplayFrames is 0 essentially all the time, so this code never runs. + if (((!globalCtx->gameplayFrames) & 0x1F)) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->jawPos, 0x90); + } + } + + this->action = DEEP_PYTHON_ACTION_DEAD; + return; + } + + this->actor.speedXZ = 0.0f; + if ((fabsf(this->actor.world.pos.x - this->actor.home.pos.x) > 20.0f) && + (fabsf(this->actor.world.pos.z - this->actor.home.pos.z) > 20.0f)) { + Math_ApproachF(&this->actor.world.pos.x, this->actor.home.pos.x, 0.3f, 300.0f); + Math_ApproachF(&this->actor.world.pos.z, this->actor.home.pos.z, 0.3f, 300.0f); + return; + } + + sNumPythonsDead++; + if (sNumPythonsDead >= (BREG(39) + 8)) { + Math_Vec3f_Copy(&seahorsePos, &this->actor.parent->world.pos); + seahorsePos.x += (Math_SinS((this->actor.parent->world.rot.y + 0x8000)) * (500.0f + BREG(38))); + seahorsePos.y += -100.0f + BREG(33); + seahorsePos.z += (Math_CosS((this->actor.parent->world.rot.y + 0x8000)) * (500.0f + BREG(38))); + if (Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_OT, seahorsePos.x, seahorsePos.y, + seahorsePos.z, 0, this->actor.shape.rot.y, 0, 0x4000, this->actor.cutscene, + this->actor.unk20, NULL)) { + gSaveContext.save.weekEventReg[13] |= 1; + switch (this->pythonIndex) { + case 0: + gSaveContext.save.weekEventReg[83] |= 0x10; + break; + + case 1: + gSaveContext.save.weekEventReg[83] |= 0x20; + break; + + case 2: + gSaveContext.save.weekEventReg[83] |= 0x40; + break; + + case 3: + gSaveContext.save.weekEventReg[83] |= 0x80; + break; + case 4: + gSaveContext.save.weekEventReg[84] |= 1; + break; + + case 5: + gSaveContext.save.weekEventReg[84] |= 2; + break; + + case 6: + gSaveContext.save.weekEventReg[84] |= 4; + break; + + case 7: + gSaveContext.save.weekEventReg[84] |= 8; + break; + } + } + } + + Actor_MarkForDeath(&this->actor); +} + +void EnDragon_UpdateDamage(EnDragon* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u32 sp30; + + if (this->action == DEEP_PYTHON_ACTION_EXTEND) { + if ((this->collider.elements[2].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[3].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[4].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[5].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[6].info.bumperFlags & BUMP_HIT) || + (this->collider.elements[7].info.bumperFlags & BUMP_HIT)) { + Actor_ApplyDamage(&this->actor); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 25); + if (this->actor.colChkInfo.health > 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_DAMAGE); + this->action = DEEP_PYTHON_ACTION_DAMAGE; + } else { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_UTSUBO_DEAD); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_100000; + this->action = DEEP_PYTHON_ACTION_SETUP_DEAD; + this->actionFunc = EnDragon_SetupDead; + } + } + } + + if ((this->action == DEEP_PYTHON_ACTION_EXTEND) && (this->grabWaitTimer == 0) && + (player->invincibilityTimer == 0) && (this->collider.elements[0].info.ocElemFlags & OCELEM_HIT) && + (!(func_800B64FC(globalCtx, 1000.0f, &this->actor.world.pos, &sp30) >= 0.0f) || (sp30 != 1))) { + this->actor.speedXZ = 0.0f; + this->action = DEEP_PYTHON_ACTION_GRAB; + this->actor.flags |= ACTOR_FLAG_100000; + this->actionFunc = EnDragon_SetupGrab; + } +} + +void EnDragon_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnDragon* this = THIS; + + if (this->retreatTimer != 0) { + this->retreatTimer--; + } + + if (this->timer != 0) { + this->timer--; + } + + if (this->largeSwayWaitTimer != 0) { + this->largeSwayWaitTimer--; + } + + if (this->grabWaitTimer != 0) { + this->grabWaitTimer--; + } + + EnDragon_UpdateDamage(this, globalCtx); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_Vec3f_Copy(&this->actor.focus.pos, &this->focusPos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + Actor_SetScale(&this->actor, this->scale); + + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + + if (this->action != DEEP_PYTHON_ACTION_GRAB) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->action < DEEP_PYTHON_ACTION_DAMAGE) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +s32 EnDragon_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnDragon* this = THIS; + + if (limbIndex == DEEP_PYTHON_LIMB_JAW) { + rot->x += this->jawXRotation; + rot->y += this->jawYRotation; + rot->z += this->jawZRotation; + } + + return false; +} + +void EnDragon_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnDragon* this = THIS; + Vec3f playerGrabOffsetFromJawPos = { 350.0f, -120.0f, -60.0f }; + + if (limbIndex == DEEP_PYTHON_LIMB_JAW) { + Matrix_MultVec3f(&gZeroVec3f, &this->jawPos); + playerGrabOffsetFromJawPos.x = 350.0f; + playerGrabOffsetFromJawPos.y = -120.0f; + playerGrabOffsetFromJawPos.z = -60.0f; + Matrix_MultVec3f(&playerGrabOffsetFromJawPos, &this->playerGrabPosition); + } + + if (limbIndex == DEEP_PYTHON_LIMB_HEAD_AND_COLLAR_ROOT) { + Matrix_MultVec3f(&gZeroVec3f, &this->focusPos); + } + + Collider_UpdateSpheres(limbIndex, &this->collider); +} + +void EnDragon_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnDragon* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnDragon_OverrideLimbDraw, EnDragon_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Dragon/z_en_dragon.h b/src/overlays/actors/ovl_En_Dragon/z_en_dragon.h index f22874804..5fe44083b 100644 --- a/src/overlays/actors/ovl_En_Dragon/z_en_dragon.h +++ b/src/overlays/actors/ovl_En_Dragon/z_en_dragon.h @@ -2,16 +2,63 @@ #define Z_EN_DRAGON_H #include "global.h" +#include "objects/object_utubo/object_utubo.h" + +#define EN_DRAGON_GET_PYTHON_INDEX(thisx) (((thisx)->params >> 7) & 0x1F) + +typedef enum { + /* 0 */ DEEP_PYTHON_ACTION_IDLE, + /* 1 */ DEEP_PYTHON_ACTION_EXTEND, + /* 2 */ DEEP_PYTHON_ACTION_GRAB, + /* 3 */ DEEP_PYTHON_ACTION_DAMAGE, + /* 4 */ DEEP_PYTHON_ACTION_RETREAT, + /* 5 */ DEEP_PYTHON_ACTION_SETUP_DEAD, + /* 6 */ DEEP_PYTHON_ACTION_DEAD, +} DeepPythonAction; struct EnDragon; typedef void (*EnDragonActionFunc)(struct EnDragon*, GlobalContext*); typedef struct EnDragon { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; - /* 0x0248 */ EnDragonActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x2B0]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[DEEP_PYTHON_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[DEEP_PYTHON_LIMB_MAX]; + /* 0x248 */ EnDragonActionFunc actionFunc; + /* 0x24C */ s32 animationIndex; + /* 0x250 */ s32 pythonIndex; + /* 0x254 */ Vec3f jawPos; + /* 0x260 */ Vec3f burrowEntrancePos; // Vertically and horizontally centered on the burrow opening. Set by Bg_Sinkai_Kabe + /* 0x26C */ Vec3f playerGrabPosition; + /* 0x278 */ Vec3f cameraEye; + /* 0x278 */ Vec3f cameraAt; + /* 0x290 */ Vec3f playerGrabPositionTemp; + /* 0x29C */ Vec3f focusPos; + /* 0x2A8 */ s16 jawZRotation; + /* 0x2AA */ s16 jawYRotation; // Never initialized by the actor + /* 0x2AC */ s16 jawXRotation; // Never initialized by the actor + /* 0x2AE */ s16 retreatTimer; // If the Deep Python is extended and this timer reaches 0, it is forced to retreat back to its burrow + /* 0x2B0 */ s16 behindJawRetreatTimer; // If the player is behind the jaw, then this will count up. When it reaches 60, the Deep Python will retreat + /* 0x2B2 */ s16 largeSwayWaitTimer; // If the player is in front of the jaw, it won't play or replay the large sway animation unless this is zero. + /* 0x2B4 */ s16 timer; + /* 0x2B6 */ s16 grabWaitTimer; // Cannot grab the player if this is non-zero + /* 0x2B8 */ s16 hasGrabbedPlayer; + /* 0x2BA */ s16 action; + /* 0x2BC */ UNK_TYPE1 unk_2BC[0x2]; + /* 0x2BE */ s16 state; + /* 0x2C0 */ s16 grabCutsceneIndex; + /* 0x2C2 */ s16 deathCutsceneIndex; + /* 0x2C4 */ UNK_TYPE1 unk_2C4[0x4]; + /* 0x2C8 */ s16 cameraId; + /* 0x2CA */ s16 grabTimer; // Counts up from the time a grab starts until the time the actor begins attacking + /* 0x2CC */ s16 unk_2CC; // Initialized, but never used + /* 0x2CE */ UNK_TYPE1 unk_2CE[0x2]; + /* 0x2D0 */ f32 endFrame; + /* 0x2D4 */ f32 scale; + /* 0x2D8 */ UNK_TYPE1 unk_2D8[0x4]; + /* 0x2DC */ ColliderJntSph collider; + /* 0x2FC */ ColliderJntSphElement colliderElements[8]; } EnDragon; // size = 0x4FC extern const ActorInit En_Dragon_InitVars; diff --git a/src/overlays/actors/ovl_En_Drs/z_en_drs.c b/src/overlays/actors/ovl_En_Drs/z_en_drs.c index 3cc504594..74f4f19cc 100644 --- a/src/overlays/actors/ovl_En_Drs/z_en_drs.c +++ b/src/overlays/actors/ovl_En_Drs/z_en_drs.c @@ -1,3 +1,9 @@ +/* + * File: z_en_drs.c + * Overlay: ovl_En_Drs + * Description: Anju's Wedding Dress Mannequin + */ + #include "z_en_drs.h" #define FLAGS 0x00000000 @@ -7,11 +13,10 @@ void EnDrs_Init(Actor* thisx, GlobalContext* globalCtx); void EnDrs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnDrs_Update(Actor* thisx, GlobalContext* globalCtx); +void EnDrs_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80C1E2D4(EnDrs* this, GlobalContext* globalCtx); -void func_80C1E3DC(EnDrs* this, GlobalContext* globalCtx); +void EnDrs_Idle(EnDrs* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Drs_InitVars = { ACTOR_EN_DRS, ACTORCAT_PROP, @@ -24,36 +29,98 @@ const ActorInit En_Drs_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C1E5E0 = { - { 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, + }, { 16, 62, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80C1E60C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations = { &gWeddingDressMannequinIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }; -extern ColliderCylinderInit D_80C1E5E0; -extern CollisionCheckInfoInit2 D_80C1E60C; +void EnDrs_CollisionUpdate(EnDrs* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -extern UNK_TYPE D_06000E70; -extern UNK_TYPE D_06005A78; +void EnDrs_Setup(EnDrs* this, GlobalContext* globalCtx) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/func_80C1E290.s") + if ((this->moonMaskObjBankIndex >= 0) && SubS_IsObjectLoaded(this->moonMaskObjBankIndex, globalCtx)) { + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWeddingDressMannequinSkel, NULL, this->jointTable, + this->morphTable, WEDDING_DRESS_MANNEQUIN_LIMB_MAX); + SubS_ChangeAnimationByInfoS(&this->skelAnime, &sAnimations, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->actor.draw = EnDrs_Draw; + this->actionFunc = EnDrs_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/func_80C1E2D4.s") +void EnDrs_Idle(EnDrs* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/func_80C1E3DC.s") +void EnDrs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnDrs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/EnDrs_Init.s") + this->moonMaskObjBankIndex = SubS_GetObjectIndex(OBJECT_MSMO, globalCtx); + this->actionFunc = EnDrs_Setup; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/EnDrs_Destroy.s") +void EnDrs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnDrs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/EnDrs_Update.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/func_80C1E4B0.s") +void EnDrs_Update(Actor* thisx, GlobalContext* globalCtx) { + EnDrs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Drs/func_80C1E568.s") + this->actionFunc(this, globalCtx); + if (this->actor.draw != NULL) { + SkelAnime_Update(&this->skelAnime); + EnDrs_CollisionUpdate(this, globalCtx); + } +} + +void EnDrs_PostLimbDraw(GlobalContext* globalCtx2, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnDrs* this = THIS; + GlobalContext* globalCtx = globalCtx2; + s8 temp = this->moonMaskObjBankIndex; + s8 temp2 = this->actor.objBankIndex; + + // Anju removes the Moon Mask at the start of the Couple's Mask cutscene + // after that it will no longer be rendered. + if (!(gSaveContext.save.weekEventReg[87] & 2) && (limbIndex == WEDDING_DRESS_MANNEQUIN_LIMB_MASK)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[temp].segment); + gSPDisplayList(POLY_OPA_DISP++, &gMoonMaskDL); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[temp2].segment); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnDrs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnDrs* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, EnDrs_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Drs/z_en_drs.h b/src/overlays/actors/ovl_En_Drs/z_en_drs.h index 191f272d6..1f59d601b 100644 --- a/src/overlays/actors/ovl_En_Drs/z_en_drs.h +++ b/src/overlays/actors/ovl_En_Drs/z_en_drs.h @@ -2,17 +2,22 @@ #define Z_EN_DRS_H #include "global.h" +#include "objects/object_drs/object_drs.h" +#include "objects/object_msmo/object_msmo.h" struct EnDrs; typedef void (*EnDrsActionFunc)(struct EnDrs*, GlobalContext*); typedef struct EnDrs { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnDrsActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x80]; -} EnDrs; // size = 0x20C + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnDrsActionFunc actionFunc; + /* 0x18C */ ColliderCylinder collider; + /* 0x1D8 */ Vec3s jointTable[WEDDING_DRESS_MANNEQUIN_LIMB_MAX]; + /* 0x1F0 */ Vec3s morphTable[WEDDING_DRESS_MANNEQUIN_LIMB_MAX]; + /* 0x208 */ s8 moonMaskObjBankIndex; +} EnDrs; // size = 0x20C */ extern const ActorInit En_Drs_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 bf8d4b1db..c47961a6d 100644 --- a/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c +++ b/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ds2n.c + * Overlay: ovl_En_Ds2n + * Description: Potion Shop Owner from OoT (unused) + */ + #include "z_en_ds2n.h" -#define FLAGS 0x02000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnDs2n*)thisx) diff --git a/src/overlays/actors/ovl_En_Dt/z_en_dt.c b/src/overlays/actors/ovl_En_Dt/z_en_dt.c index 57e89b76b..0501b728c 100644 --- a/src/overlays/actors/ovl_En_Dt/z_en_dt.c +++ b/src/overlays/actors/ovl_En_Dt/z_en_dt.c @@ -1,6 +1,12 @@ +/* + * File: z_en_dt.c + * Overlay: ovl_En_Dt + * Description: Mayor Dotour + */ + #include "z_en_dt.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnDt*)thisx) diff --git a/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c b/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c index fbecb97a5..40e06787c 100644 --- a/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c +++ b/src/overlays/actors/ovl_En_Dy_Extra/z_en_dy_extra.c @@ -1,6 +1,13 @@ -#include "z_en_dy_extra.h" +/* + * File: z_en_dy_extra.c + * Overlay: ovl_En_Dy_Extra + * Description: Great Fairy beam + */ -#define FLAGS 0x00000030 +#include "z_en_dy_extra.h" +#include "objects/object_dy_obj/object_dy_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnDyExtra*)thisx) @@ -24,9 +31,6 @@ const ActorInit En_Dy_Extra_InitVars = { (ActorFunc)EnDyExtra_Draw, }; -extern Vtx D_0600DD40[]; -extern Gfx D_0600DEF0[]; - void EnDyExtra_Destroy(Actor* thisx, GlobalContext* globalCtx) { } @@ -76,17 +80,16 @@ void EnDyExtra_Update(Actor* thisx, GlobalContext* globalCtx) { EnDyExtra* this = THIS; DECR(this->unk14C); - Audio_PlayActorSound2(&this->actor, NA_SE_PL_SPIRAL_HEAL_BEAM - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_SPIRAL_HEAL_BEAM - SFX_FLAG); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void EnDyExtra_Draw(Actor* thisx, GlobalContext* globalCtx) { - static Color_RGBA8 D_80A61740[] = { { 255, 255, 170, 255 }, - { 255, 170, 255, 255 }, - { 255, 255, 170, 255 }, - { 170, 255, 255, 255 }, - { 255, 255, 170, 255 } }; + static Color_RGBA8 D_80A61740[] = { + { 255, 255, 170, 255 }, { 255, 170, 255, 255 }, { 255, 255, 170, 255 }, + { 170, 255, 255, 255 }, { 255, 255, 170, 255 }, + }; static Color_RGBA8 D_80A61754[] = { { 255, 100, 0, 255 }, { 255, 0, 100, 255 }, { 100, 255, 0, 255 }, { 0, 100, 255, 255 }, { 255, 230, 0, 255 } }; @@ -95,7 +98,7 @@ void EnDyExtra_Draw(Actor* thisx, GlobalContext* globalCtx) { EnDyExtra* this = THIS; s32 pad; GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; - Vtx* vertices = Lib_SegmentedToVirtual(D_0600DD40); + Vtx* vertices = Lib_SegmentedToVirtual(object_dy_obj_Vtx_00DD40); s32 i; u8 unk[3]; @@ -120,7 +123,7 @@ void EnDyExtra_Draw(Actor* thisx, GlobalContext* globalCtx) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, D_80A61740[this->type].r, D_80A61740[this->type].g, D_80A61740[this->type].b, 255); gDPSetEnvColor(POLY_XLU_DISP++, D_80A61754[this->type].r, D_80A61754[this->type].g, D_80A61754[this->type].b, 128); - gSPDisplayList(POLY_XLU_DISP++, D_0600DEF0); + gSPDisplayList(POLY_XLU_DISP++, object_dy_obj_DL_00DEF0); CLOSE_DISPS(gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Egblock/z_en_egblock.c b/src/overlays/actors/ovl_En_Egblock/z_en_egblock.c index 1dd7541b6..bea655d9a 100644 --- a/src/overlays/actors/ovl_En_Egblock/z_en_egblock.c +++ b/src/overlays/actors/ovl_En_Egblock/z_en_egblock.c @@ -1,6 +1,12 @@ +/* + * File: z_en_egblock.c + * Overlay: ovl_En_Egblock + * Description: Eyegore Block + */ + #include "z_en_egblock.h" -#define FLAGS 0x08000000 +#define FLAGS (ACTOR_FLAG_8000000) #define THIS ((EnEgblock*)thisx) diff --git a/src/overlays/actors/ovl_En_Egol/z_en_egol.c b/src/overlays/actors/ovl_En_Egol/z_en_egol.c index a005e8b57..0111c6cd7 100644 --- a/src/overlays/actors/ovl_En_Egol/z_en_egol.c +++ b/src/overlays/actors/ovl_En_Egol/z_en_egol.c @@ -1,6 +1,12 @@ +/* + * File: z_en_egol.c + * Overlay: ovl_En_Egol + * Description: Eyegore + */ + #include "z_en_egol.h" -#define FLAGS 0x80000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_80000000) #define THIS ((EnEgol*)thisx) 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 be9f5de3a..f71c0b30d 100644 --- a/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -1,6 +1,13 @@ -#include "z_en_elf.h" +/* + * File: z_en_elf.c + * Overlay: ovl_En_Elf + * Description: Fairies + */ -#define FLAGS 0x02000030 +#include "z_en_elf.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((EnElf*)thisx) @@ -9,16 +16,23 @@ 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); - -#if 0 const ActorInit En_Elf_InitVars = { ACTOR_EN_ELF, ACTORCAT_ITEMACTION, @@ -31,96 +45,1594 @@ 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) && Flags_GetCollectible(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, &gameplay_keep_Skel_02AF58.sh, &gameplay_keep_Anim_029140, + 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.save.playerData.tatlTimer >= 25800) || (gSaveContext.save.playerData.tatlTimer < 3000)) { + gSaveContext.save.playerData.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.jinxTimer = 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 = ActorShadow_DrawWhiteCircle; + 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_UpdatePos(&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_UpdatePos(&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_UpdatePos(&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_MoveWithGravity(&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_UpdatePos(&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) { + Flags_SetCollectible(globalCtx, this->unk_260); + } + Actor_MarkForDeath(&this->actor); + return; + } + + if (Player_InCsMode(&globalCtx->state)) { + 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.save.playerData.doubleMagic * 0x30) + 0x30); + } + gSaveContext.jinxTimer = 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) { + Flags_SetCollectible(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) { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 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); + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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 (Cutscene_CheckActorAction(globalCtx, 201)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 201)]->action == 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 (Cutscene_CheckActorAction(globalCtx, 201)) { + sp38 = Cutscene_GetActorActionIndex(globalCtx, 201); + func_808908D0(&nextPos, globalCtx, sp38); + this->actor.shape.rot.y = globalCtx->csCtx.actorActions[sp38]->urot.y; + this->actor.shape.rot.x = globalCtx->csCtx.actorActions[sp38]->urot.x; + if (globalCtx->csCtx.actorActions[sp38]->action == 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.currentCsIndex == 0) && + ((globalCtx->csCtx.frames == 149) || (globalCtx->csCtx.frames == 381) || + (globalCtx->csCtx.frames == 591))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + } + + if ((globalCtx->sceneNum == SCENE_SECOM) && (gSaveContext.sceneSetupIndex == 0) && + (globalCtx->csCtx.currentCsIndex == 4) && (globalCtx->csCtx.frames == 95)) { + Actor_PlaySfxAtPos(&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.arrowPointedActor; + 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) { + Actor_PlaySfxAtPos(&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 (!Cutscene_CheckActorAction(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.arrowPointedActor; + 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) { + Actor_PlaySfxAtPos(&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.fairyInner; + this->outerColor = globalCtx->actorCtx.targetContext.fairyOuter; + } else { + transitionRate = 0.25f / this->unk_238; + func_8088EF18(&this->innerColor, &globalCtx->actorCtx.targetContext.fairyInner, &this->innerColor, + transitionRate); + func_8088EF18(&this->outerColor, &globalCtx->actorCtx.targetContext.fairyOuter, &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) { + Actor_PlaySfxAtPos(&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 (Cutscene_CheckActorAction(globalCtx, 201)) { + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 201)]->action) { + 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.arrowPointedActor; + 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) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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 (Message_GetState(&globalCtx->msgCtx)) { + case 4: + if (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.currentTextId == 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.currentTextId - 1); + break; + + case 1: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + } + } + break; + + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + 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.save.isNight) { + func_80151938(globalCtx, 0x248); + } else if ((gSaveContext.save.time < CLOCK_TIME(6, 0)) && + (gSaveContext.save.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.save.playerData.tatlTimer = 0; + } + + if ((player->tatlTextId == 0) && (player->unk_730 == NULL)) { + if ((gSaveContext.save.playerData.tatlTimer >= 600) && (gSaveContext.save.playerData.tatlTimer <= 3000)) { + player->tatlTextId = ElfMessage_GetFirstCycleHint(globalCtx); + } + } + + if (player->tatlTextId < 0) { + thisx->flags |= 0x10000; + } + + if (Actor_ProcessTalkRequest(thisx, &globalCtx->state)) { + 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.save.playerData.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; + Actor_ChangeFocus(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 (!Play_InCsMode(globalCtx)) { + if (gSaveContext.save.playerData.tatlTimer < 25800) { + gSaveContext.save.playerData.tatlTimer++; + } else if (!(this->fairyFlags & 0x80)) { + gSaveContext.save.playerData.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_MultVec3f(&zeroVec, &sp34); + Matrix_Translate(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) && + (!Cutscene_CheckActorAction(globalCtx, 201) || + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 201)]->action != 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.actorActions[action]; + f32 lerp; + + startPos.x = npcAction->startPos.x; + startPos.y = npcAction->startPos.y; + startPos.z = npcAction->startPos.z; + + endPos.x = npcAction->endPos.x; + endPos.y = npcAction->endPos.y; + endPos.z = npcAction->endPos.z; + + lerp = Environment_LerpWeight(npcAction->endFrame, npcAction->startFrame, globalCtx->csCtx.frames); + 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 e8145f806..ec64038ce 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -5,8 +5,10 @@ */ #include "z_en_elfbub.h" +#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h" +#include "objects/object_bubble/object_bubble.h" -#define FLAGS 0x00000001 +#define FLAGS (ACTOR_FLAG_1) #define THIS ((EnElfbub*)thisx) @@ -50,8 +52,6 @@ static ColliderCylinderInit sCylinderInit = { { 16, 32, 0, { 0, 0, 0 } }, }; -extern Gfx D_06001000[]; - void EnElfbub_Init(Actor* thisx, GlobalContext* globalCtx) { EnElfbub* this = THIS; Actor* childActor; @@ -61,7 +61,7 @@ void EnElfbub_Init(Actor* thisx, GlobalContext* globalCtx) { return; } - ActorShape_Init(&this->actor.shape, 16.0f, func_800B3FC0, 0.2f); + ActorShape_Init(&this->actor.shape, 16.0f, ActorShadow_DrawCircle, 0.2f); this->actor.hintId = 0x16; Actor_SetScale(&this->actor, 1.25f); @@ -76,13 +76,13 @@ void EnElfbub_Init(Actor* thisx, GlobalContext* globalCtx) { childActor = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ELFORG, this->actor.world.pos.x, this->actor.world.pos.y + 12.0f, this->actor.world.pos.z, this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, - ((ENELFBUB_GET_SWITCHFLAG(&this->actor) & 0x7F) << 9) | 2); + ((ENELFBUB_GET_SWITCHFLAG(&this->actor) & 0x7F) << 9) | STRAY_FAIRY_TYPE_BUBBLE); if (childActor != NULL) { childActor->parent = &this->actor; } this->oscillationAngle = 0; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; } void EnElfbub_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -116,7 +116,7 @@ void EnElfbub_Pop(EnElfbub* this, GlobalContext* globalCtx) { Rand_S16Offset(100, 50), 25, 0); } - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 60, NA_SE_EN_AWA_BREAK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 60, NA_SE_EN_AWA_BREAK); Actor_MarkForDeath(&this->actor); } } @@ -142,7 +142,7 @@ void EnElfbub_Update(Actor* thisx, GlobalContext* globalCtx) { EnElfbub* this = THIS; Collider_UpdateCylinder(&this->actor, &this->collider); this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, this->actor.shape.yOffset); + Actor_SetFocus(&this->actor, this->actor.shape.yOffset); } void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx2) { @@ -153,15 +153,15 @@ 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_Translate(0.0f, 0.0f, 1.0f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->zRot, MTXMODE_APPLY); + Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZS(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); + gSPDisplayList(POLY_XLU_DISP++, object_bubble_DL_001000); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c index 0da225746..de1959ab4 100644 --- a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c +++ b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.c @@ -1,6 +1,13 @@ -#include "z_en_elfgrp.h" +/* + * File: z_en_elfgrp.c + * Overlay: ovl_En_Elfgrp + * Description: Group of Stray Fairies in Fairy Fountain + */ -#define FLAGS 0x00000010 +#include "z_en_elfgrp.h" +#include "overlays/actors/ovl_En_Elforg/z_en_elforg.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnElfgrp*)thisx) @@ -8,7 +15,24 @@ void EnElfgrp_Init(Actor* thisx, GlobalContext* globalCtx); void EnElfgrp_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnElfgrp_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +s32 func_80A39BD0(GlobalContext* globalCtx, s32 arg2); +s32 func_80A39C1C(GlobalContext* globalCtx, s32 arg1); +void func_80A39DC8(EnElfgrp* this, GlobalContext* globalCtx, s32 arg2, s32 arg3); +void func_80A3A0AC(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A0F4(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A210(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A274(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A398(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A484(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A4AC(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A520(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A600(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A610(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A6F4(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A77C(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A7FC(EnElfgrp* this, GlobalContext* globalCtx); +void func_80A3A8F8(EnElfgrp* this, GlobalContext* globalCtx); + const ActorInit En_Elfgrp_InitVars = { ACTOR_EN_ELFGRP, ACTORCAT_PROP, @@ -21,54 +45,544 @@ const ActorInit En_Elfgrp_InitVars = { (ActorFunc)NULL, }; -#endif +void func_80A396B0(EnElfgrp* this, s32 arg1) { + while (arg1 > 0) { + if (this->actor.cutscene == -1) { + break; + } + this->actor.cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A396B0.s") + arg1--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/EnElfgrp_Init.s") +void EnElfgrp_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnElfgrp* this = THIS; + s32 sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/EnElfgrp_Destroy.s") + this->unk_147 = ENELFGRP_GET(&this->actor); + this->unk_148 = 0; + this->unk_14A = 0; + this->actor.focus.pos.y += 40.0f; + this->actor.flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39BD0.s") + switch (this->unk_147) { + case ENELFGRP_1: + case ENELFGRP_2: + case ENELFGRP_3: + case ENELFGRP_4: + this->unk_148 = this->unk_147 - 1; + sp24 = func_80A39C1C(globalCtx, this->unk_147); + this->unk_146 = 1 << this->unk_147; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39C1C.s") + if (sp24 < 25) { + func_80A39DC8(this, globalCtx, sp24, 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39CD4.s") + if (sp24 >= 25) { + this->actionFunc = func_80A3A520; + func_80A396B0(this, 2); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39DC8.s") + if ((func_80A39BD0(globalCtx, this->unk_147) + sp24) >= 25) { + this->actionFunc = func_80A3A398; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39F50.s") + switch (this->unk_147) { + case ENELFGRP_1: + if (gSaveContext.save.weekEventReg[23] & 2) { + func_80A396B0(this, 1); + } else { + this->unk_14A |= 4; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A39FBC.s") + case ENELFGRP_2: + if (gSaveContext.save.playerData.doubleMagic == true) { + func_80A396B0(this, 1); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A044.s") + case ENELFGRP_3: + if (gSaveContext.save.playerData.doubleDefense) { + func_80A396B0(this, 1); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A0AC.s") + case ENELFGRP_4: + if (INV_CONTENT(ITEM_SWORD_GREAT_FAIRY) == ITEM_SWORD_GREAT_FAIRY) { + func_80A396B0(this, 1); + } else { + this->unk_14A |= 0x10; + } + break; + } + } else if (func_80A39BD0(globalCtx, this->unk_147)) { + this->actionFunc = func_80A3A7FC; + this->actor.textId = (this->unk_147 * 3) + 0x581; + } else { + this->actionFunc = func_80A3A8F8; + if ((gSaveContext.save.weekEventReg[9] & this->unk_146)) { + this->actor.textId = (this->unk_147 * 3) + 0x580; + } else { + this->actor.textId = (this->unk_147 * 3) + 0x57F; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A0F4.s") + default: + sp24 = func_80A39C1C(globalCtx, 0); + this->unk_146 = ENELFGRP_1; + if (sp24 >= 25) { + this->actionFunc = func_80A3A520; + if ((this->actor.home.rot.z != 0) && Flags_GetSwitch(globalCtx, this->actor.home.rot.z)) { + this->actionFunc = func_80A3A600; + } else if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { + func_80A396B0(this, 4); + } else if (INV_CONTENT(ITEM_MASK_DEKU) != ITEM_MASK_DEKU) { + func_80A396B0(this, 5); + } else { + this->unk_14A |= 2; + func_80A396B0(this, 6); + } + } else if ((gSaveContext.save.weekEventReg[8] & 0x80)) { + func_80A39DC8(this, globalCtx, 24, 0); + this->actionFunc = func_80A3A398; + if (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU) { + if (INV_CONTENT(ITEM_MASK_GREAT_FAIRY) == ITEM_MASK_GREAT_FAIRY) { + func_80A396B0(this, 2); + } else { + func_80A396B0(this, 3); + this->unk_14A |= 2; + } + } else if (gSaveContext.save.playerData.magicAcquired == true) { + func_80A396B0(this, 1); + } + } else { + func_80A39DC8(this, globalCtx, 24, 0); + this->actionFunc = func_80A3A8F8; + if ((gSaveContext.save.weekEventReg[9] & this->unk_146)) { + this->actor.textId = 0x580; + } else { + this->actor.textId = 0x578; + } + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A210.s") +void EnElfgrp_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A274.s") +s32 func_80A39BD0(GlobalContext* globalCtx, s32 arg2) { + if ((arg2 < 1) || (arg2 >= 5)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A398.s") + return (((void)0, gSaveContext.save.inventory.strayFairies[arg2 - 1]) - func_80A39C1C(globalCtx, arg2)) + 10; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A484.s") +s32 func_80A39C1C(GlobalContext* globalCtx, s32 arg1) { + // the permanentSceneFlags access here is in the form + // struct { + // u32 clockTown : 1; + // u32 fountains[4] : 5; + // } FairyFountains; + // where arg1 is: + // 0: clocktown + // 1: woodfall, + // 2: snowhead, + // 3: great bay, + // 4: stone tower + // clocktown is handled separately, and then the fountains are looked up as array indexing -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A4AC.s") + s32 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A520.s") + if ((arg1 < 0) || (arg1 >= 5)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A600.s") + if (arg1 == 0) { + if (gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 1) { + return 25; + } + return 24; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A610.s") + temp_v1 = (gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 >> (((arg1 - 1) * 5) + 1)) & 0x1F; + if (temp_v1 < 10) { + temp_v1 = 10; + } else if (temp_v1 > 25) { + temp_v1 = 25; + } + return temp_v1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A6F4.s") +void func_80A39CD4(GlobalContext* globalCtx, s32 arg1, s32 arg2) { + if ((arg1 < 0) || (arg1 > 4) || (arg2 < 10) || (arg2 > 25)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A77C.s") + if (arg1 == 0) { + if (arg2 == 25) { + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= 1; + } else { + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 &= ~1; + } + } else { + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 &= ~(0x1F << ((arg1 * 5) - 4)); + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= arg2 << ((arg1 * 5) - 4); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A7FC.s") +void func_80A39DC8(EnElfgrp* this, GlobalContext* globalCtx, s32 arg2, s32 arg3) { + s32 pad; + s32 i; + Actor* elforg; + s32 temp; + Vec3f sp6C; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/func_80A3A8F8.s") + if (arg3 == 0) { + this->unk_14A |= 8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elfgrp/EnElfgrp_Update.s") + if (arg3 == 0) { + sp6C = this->actor.world.pos; + sp6C.y += 20.0f; + temp = ((this->unk_147 & 7) << 6) | STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN; + } else { + sp6C = player->actor.world.pos; + sp6C.y += 20.0f; + temp = ((this->unk_147 & 7) << 6) | STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN; + } + + for (i = 0; i < arg2; i++) { + elforg = + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELFORG, randPlusMinusPoint5Scaled(20.0f) + sp6C.x, + sp6C.y, randPlusMinusPoint5Scaled(20.0f) + sp6C.z, 0, 0, 0, temp); + if (elforg == NULL) { + continue; + } + elforg->home.pos.x = this->actor.home.pos.x; + elforg->home.pos.y = this->actor.home.pos.y + 20.0f; + elforg->home.pos.z = this->actor.home.pos.z; + } +} + +s32 func_80A39F50(GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + EnElforg* elfOrg; + + while (itemAction != NULL) { + if ((itemAction->id != ACTOR_EN_ELFORG) || + ((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) && + (STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) { + itemAction = itemAction->next; + continue; + } + + elfOrg = (EnElforg*)itemAction; + if (!(elfOrg->flags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME)) { + elfOrg->flags |= STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME; + } + itemAction = itemAction->next; + } + + return 0; +} + +s32 func_80A39FBC(GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + EnElforg* elfOrg; + s32 phi_v1 = 30; + + while (itemAction != NULL) { + if ((itemAction->id != ACTOR_EN_ELFORG) || + ((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) && + (STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) { + itemAction = itemAction->next; + continue; + } + + elfOrg = (EnElforg*)itemAction; + if (!(elfOrg->flags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN)) { + elfOrg->flags |= STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; + if (phi_v1 >= 100) { + return phi_v1; + } + elfOrg->secondaryTimer = phi_v1; + phi_v1 += 5; + } + + itemAction = itemAction->next; + } + + return phi_v1; +} + +void func_80A3A044(GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + EnElforg* elfOrg; + + while (itemAction != NULL) { + if ((itemAction->id != ACTOR_EN_ELFORG) || + ((STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN) && + (STRAY_FAIRY_TYPE(itemAction) != STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN))) { + itemAction = itemAction->next; + continue; + } + + elfOrg = (EnElforg*)itemAction; + elfOrg->actor.home.rot.x = 0x14; + elfOrg->flags |= STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS; + + itemAction = itemAction->next; + } +} + +void func_80A3A0AC(EnElfgrp* this, GlobalContext* globalCtx) { + if (!Cutscene_CheckActorAction(globalCtx, 0x64)) { + this->actionFunc = func_80A3A600; + ActorCutscene_Stop(this->actor.cutscene); + } +} + +void func_80A3A0F4(EnElfgrp* this, GlobalContext* globalCtx) { + if (this->unk_144 == 10) { + play_sound(NA_SE_SY_WHITE_OUT_T); + if (ENELFGRP_GET(&this->actor) < ENELFGRP_4) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_DEMO_EFFECT, this->actor.world.pos.x, + this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, 0, 0, + ENELFGRP_GET(&this->actor) + ENELFGRP_4); + } else { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_DEMO_EFFECT, this->actor.world.pos.x, + this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, 0, 0, 4); + } + } + + if ((this->unk_144 > 10) && (this->unk_14A & 1)) { + func_800B9010(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG); + } + + if (this->unk_144 == 0) { + this->actionFunc = func_80A3A0AC; + } +} + +void func_80A3A210(EnElfgrp* this, GlobalContext* globalCtx) { + if (this->unk_144 == 0) { + this->actionFunc = func_80A3A0F4; + func_80A3A044(globalCtx); + this->unk_144 = 30; + } + + if (this->unk_14A & 1) { + func_800B9010(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG); + } +} + +void func_80A3A274(EnElfgrp* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 0x64)) { + if (this->unk_14A & 1) { + func_800B9010(&this->actor, NA_SE_PL_CHIBI_FAIRY_HEAL - SFX_FLAG); + } + + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 0x64)]->action) { + case 2: + if (!(this->unk_14A & 1)) { + if (this->unk_147 == ENELFGRP_0) { + func_80A39DC8(this, globalCtx, 1, 1); + } else { + func_80A39DC8(this, globalCtx, func_80A39BD0(globalCtx, this->unk_147), 1); + } + this->unk_14A |= 1; + func_80A39CD4(globalCtx, this->unk_147, 25); + } + break; + + case 3: + func_80A39F50(globalCtx); + this->actionFunc = func_80A3A210; + this->unk_144 = 90; + break; + } + } +} + +void func_80A3A398(EnElfgrp* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actionFunc = func_80A3A274; + Flags_UnsetSwitch(globalCtx, ENELFGRP_GET_FE00(&this->actor)); + if (this->unk_14A & 2) { + Item_Give(globalCtx, ITEM_MASK_GREAT_FAIRY); + } + + if ((this->unk_14A & 4) != 0) { + gSaveContext.save.weekEventReg[23] |= 2; + } + + if (this->unk_14A & 0x10) { + Item_Give(globalCtx, ITEM_SWORD_GREAT_FAIRY); + } + this->unk_14A &= ~8; + } else if (this->actor.xzDistToPlayer < 350.0f) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80A3A484(EnElfgrp* this, GlobalContext* globalCtx) { + if (this->unk_144 == 0) { + this->actionFunc = func_80A3A0F4; + this->unk_144 = 30; + } +} + +void func_80A3A4AC(EnElfgrp* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 0x64)) { + s32 temp = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 0x64)]->action; + if (temp == 3) { + this->actionFunc = func_80A3A484; + this->unk_144 = 90; + } + } +} + +void func_80A3A520(EnElfgrp* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 0x67)) { + this->actionFunc = func_80A3A600; + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actionFunc = func_80A3A4AC; + Flags_SetSwitch(globalCtx, ENELFGRP_GET_FE00(&this->actor)); + + if (this->unk_14A & 2) { + Item_Give(globalCtx, ITEM_MASK_GREAT_FAIRY); + } + + if (this->actor.home.rot.z != 0) { + Flags_SetSwitch(globalCtx, this->actor.home.rot.z); + } + } else if (this->actor.xzDistToPlayer < 350.0f) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80A3A600(EnElfgrp* this, GlobalContext* globalCtx) { +} + +void func_80A3A610(EnElfgrp* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_144 == 60) { + Parameter_AddMagic(globalCtx, + ((void)0, gSaveContext.unk_3F30) + (gSaveContext.save.playerData.doubleMagic * 0x30) + 0x30); + gSaveContext.healthAccumulator = 320; + } + + if (this->unk_144 > 0) { + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_GROUP_HEAL - SFX_FLAG); + } else { + player->actor.freezeTimer = 0; + player->stateFlags1 &= ~0x20000000; + this->actionFunc = func_80A3A600; + this->unk_14A |= 8; + } +} + +void func_80A3A6F4(EnElfgrp* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + this->unk_144 = func_80A39FBC(globalCtx); + this->actionFunc = func_80A3A610; + this->unk_14A &= ~8; + } +} + +void func_80A3A77C(EnElfgrp* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->unk_144 = func_80A39FBC(globalCtx); + this->actionFunc = func_80A3A610; + this->unk_14A &= ~8; + } +} + +void func_80A3A7FC(EnElfgrp* this, GlobalContext* globalCtx) { + s32 temp_s0; + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + gSaveContext.save.weekEventReg[9] |= this->unk_146; + this->actionFunc = func_80A3A6F4; + temp_s0 = func_80A39BD0(globalCtx, this->unk_147); + func_80A39DC8(this, globalCtx, temp_s0, 1); + temp_s0 += func_80A39C1C(globalCtx, this->unk_147); + if (temp_s0 > 25) { + temp_s0 = 25; + } + func_80A39CD4(globalCtx, this->unk_147, temp_s0); + } else if (this->actor.xzDistToPlayer < 280.0f) { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + } +} + +void func_80A3A8F8(EnElfgrp* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + gSaveContext.save.weekEventReg[9] |= this->unk_146; + this->actionFunc = func_80A3A6F4; + return; + } + + if (this->unk_147 != ENELFGRP_0) { + if (func_80A39BD0(globalCtx, this->unk_147) > 0) { + this->actionFunc = func_80A3A7FC; + return; + } + } + + if (this->actor.xzDistToPlayer < 30.0f) { + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { + this->actor.flags &= ~ACTOR_FLAG_10000; + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + this->actionFunc = func_80A3A77C; + gSaveContext.save.weekEventReg[9] |= this->unk_146; + } else { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 100.0f); + } + } else { + this->actor.flags &= ~ACTOR_FLAG_10000; + } +} + +void EnElfgrp_Update(Actor* thisx, GlobalContext* globalCtx) { + EnElfgrp* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->unk_14A & 8) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIRY_GROUP_FRY - SFX_FLAG); + } + + if (this->unk_144 != 0) { + this->unk_144--; + } +} diff --git a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.h b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.h index 7ecb7d71d..375dad55b 100644 --- a/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.h +++ b/src/overlays/actors/ovl_En_Elfgrp/z_en_elfgrp.h @@ -7,9 +7,24 @@ struct EnElfgrp; typedef void (*EnElfgrpActionFunc)(struct EnElfgrp*, GlobalContext*); +#define ENELFGRP_GET(thisx) ((thisx)->params & 0xF) +#define ENELFGRP_GET_FE00(thisx) (((thisx)->params & 0xFE00) >> 9) + +enum { + /* 0 */ ENELFGRP_0, + /* 2 */ ENELFGRP_1, + /* 2 */ ENELFGRP_2, + /* 3 */ ENELFGRP_3, + /* 4 */ ENELFGRP_4, +}; + typedef struct EnElfgrp { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x8]; + /* 0x0144 */ s16 unk_144; + /* 0x0146 */ u8 unk_146; + /* 0x0147 */ u8 unk_147; + /* 0x0148 */ s8 unk_148; + /* 0x014A */ u16 unk_14A; /* 0x014C */ EnElfgrpActionFunc actionFunc; } EnElfgrp; // size = 0x150 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 2302e1cca..16139fa08 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c @@ -1,6 +1,13 @@ -#include "z_en_elforg.h" +/* + * File: z_en_elforg.c + * Overlay: ovl_En_Elforg + * Description: Stray Fairy + */ -#define FLAGS 0x00000010 +#include "z_en_elforg.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnElforg*)thisx) @@ -9,7 +16,13 @@ void EnElforg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnElforg_Update(Actor* thisx, GlobalContext* globalCtx); void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnElforg_TrappedByBubble(EnElforg* this, GlobalContext* globalCtx); +void EnElforg_TurnInFairy(EnElforg* this, GlobalContext* globalCtx); +void EnElforg_FreeFloatingFairyFountain(EnElforg* this, GlobalContext* globalCtx); +void EnElforg_FreeFloating(EnElforg* this, GlobalContext* globalCtx); +void EnElforg_SetupTrappedByEnemy(EnElforg* this, GlobalContext* globalCtx); +void EnElforg_HiddenByCollider(EnElforg* this, GlobalContext* globalCtx); + const ActorInit En_Elforg_InitVars = { ACTOR_EN_ELFORG, ACTORCAT_ITEMACTION, @@ -22,63 +35,587 @@ const ActorInit En_Elforg_InitVars = { (ActorFunc)EnElforg_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ACDA30 = { - { 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 EnElforg_InitializeParams(EnElforg* this) { + this->actor.speedXZ = 1.0f; + this->targetSpeedXZ = 1.0f; + this->actor.velocity.y = 0.0f; + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x10000); + this->timer = 0; + this->secondaryTimer = Rand_ZeroFloat(100.0f); + this->actor.shape.yOffset = 0.0f; + this->skelAnime.curFrame = (s32)Rand_ZeroFloat(5.0f); +} -extern ColliderCylinderInit D_80ACDA30; +void EnElforg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnElforg* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACC470.s") + Actor_SetScale(&this->actor, 0.01f); + this->flags = 0; + this->direction = 0; + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/EnElforg_Init.s") + switch (STRAY_FAIRY_TYPE(&this->actor)) { + case STRAY_FAIRY_TYPE_CLOCK_TOWN: + if (gSaveContext.save.weekEventReg[8] & 0x80) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + case STRAY_FAIRY_TYPE_COLLECTIBLE: + if (Flags_GetCollectible(globalCtx, STRAY_FAIRY_FLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + default: + if (Flags_GetSwitch(globalCtx, STRAY_FAIRY_FLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + case STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN: + case STRAY_FAIRY_TYPE_BUBBLE: + case STRAY_FAIRY_TYPE_CHEST: + case STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN: + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/EnElforg_Destroy.s") + if (func_8010A074(globalCtx)) { + this->area = gSaveContext.unk_48C8 + 1; + } else { + // Needs to be thisx in order to match + this->area = STRAY_FAIRY_GET_PARAM_1C0(thisx) >> 6; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACC7E4.s") + switch (STRAY_FAIRY_TYPE(&this->actor)) { + case STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN: + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_FreeFloatingFairyFountain; + this->targetSpeedXZ = Rand_ZeroFloat(2.0f) + 1.0f; + this->targetDistanceFromHome = Rand_ZeroFloat(100.0f) + 50.0f; + break; + case STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN: + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_TurnInFairy; + this->secondaryTimer = 60; + break; + case STRAY_FAIRY_TYPE_BUBBLE: + this->timer = 0; + this->actionFunc = EnElforg_TrappedByBubble; + break; + case STRAY_FAIRY_TYPE_ENEMY: + this->actionFunc = EnElforg_SetupTrappedByEnemy; + EnElforg_SetupTrappedByEnemy(this, globalCtx); + this->actor.draw = NULL; + break; + case STRAY_FAIRY_TYPE_COLLIDER: + this->actionFunc = EnElforg_HiddenByCollider; + this->actor.draw = NULL; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + break; + default: + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_FreeFloating; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACC8D4.s") + this->actor.shape.rot.y = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACC934.s") +void EnElforg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnElforg* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACC994.s") + if (STRAY_FAIRY_TYPE(&this->actor) == STRAY_FAIRY_TYPE_COLLIDER) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCAC0.s") +void EnElforg_SpawnSparkles(EnElforg* this, GlobalContext* globalCtx, s32 life) { + static Vec3f sVelocity = { 0.0f, -0.05f, 0.0f }; + static Vec3f sAcceleration = { 0.0f, -0.025f, 0.0f }; + static Color_RGBA8 sPrimColors[] = { + { 255, 235, 220, 255 }, { 255, 220, 220, 255 }, { 220, 255, 220, 255 }, + { 220, 220, 255, 255 }, { 255, 255, 200, 255 }, + }; + static Color_RGBA8 sEnvColors[] = { + { 255, 150, 0, 255 }, { 255, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 0, 255, 255 }, { 255, 255, 0, 255 }, + }; + Vec3f pos; + s32 pad; + s32 index; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCBB8.s") + pos.x = randPlusMinusPoint5Scaled(6.0f) + this->actor.world.pos.x; + pos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y); + pos.z = randPlusMinusPoint5Scaled(6.0f) + this->actor.world.pos.z; + index = (this->area < STRAY_FAIRY_AREA_CLOCK_TOWN || this->area >= STRAY_FAIRY_AREA_MAX) + ? STRAY_FAIRY_AREA_CLOCK_TOWN + : this->area; + EffectSsKirakira_SpawnDispersed(globalCtx, &pos, &sVelocity, &sAcceleration, &sPrimColors[index], + &sEnvColors[index], 1000, life); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCBD0.s") +void EnElforg_ApproachTargetYPosition(EnElforg* this, Vec3f* targetPos) { + f32 yDifference = targetPos->y - this->actor.world.pos.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCC98.s") + if (fabsf(yDifference) < this->actor.speedXZ) { + this->actor.world.pos.y = targetPos->y; + } else if (yDifference > 0.0f) { + this->actor.world.pos.y += this->actor.speedXZ; + } else { + this->actor.world.pos.y -= this->actor.speedXZ; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCE4C.s") +void EnElforg_ApproachTargetSpeedXZ(EnElforg* this) { + if (this->actor.speedXZ > this->targetSpeedXZ) { + this->actor.speedXZ *= 0.9f; + } else if (this->actor.speedXZ < (this->targetSpeedXZ - 0.1f)) { + this->actor.speedXZ += 0.1f; + } else { + this->actor.speedXZ = this->targetSpeedXZ; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACCEB0.s") +void EnElforg_MoveToTargetFairyFountain(EnElforg* this, Vec3f* homePos) { + s32 pad[2]; + f32 xzDistance; + f32 zDifference; + f32 xDifference; + s16 angleAdjustment; + s16 targetAngle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD088.s") + this->actor.shape.yOffset += 100.0f * Math_SinS(this->timer << 9); + EnElforg_ApproachTargetYPosition(this, homePos); + xDifference = this->actor.world.pos.x - homePos->x; + zDifference = this->actor.world.pos.z - homePos->z; + targetAngle = Math_FAtan2F(-zDifference, -xDifference); + xzDistance = sqrtf(SQ(xDifference) + SQ(zDifference)); + if ((this->targetDistanceFromHome + 10.0f) < xzDistance) { + angleAdjustment = 0x1000; + } else if ((this->targetDistanceFromHome - 10.0f) > xzDistance) { + angleAdjustment = 0x6000; + } else { + angleAdjustment = 0x4000; + } + targetAngle += angleAdjustment; + Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 2, 4000, 1000); + EnElforg_ApproachTargetSpeedXZ(this); + Actor_MoveWithGravity(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD164.s") +/** + * Adjust's the Stray Fairy's speed, rotation, and y-position to bring it + * closer to targetPos. Since it doesn't directly point the fairy towards + * its target, it can take strange paths or even "orbit" the target. + */ +void EnElforg_MoveToTarget(EnElforg* this, Vec3f* targetPos) { + s16 targetAngle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD1B0.s") + this->actor.shape.yOffset += 100.0f * Math_SinS(this->timer << 9); + EnElforg_ApproachTargetYPosition(this, targetPos); + targetAngle = Math_FAtan2F(-(this->actor.world.pos.z - targetPos->z), -(this->actor.world.pos.x - targetPos->x)); + if (this->targetSpeedXZ > 2.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 2, 0x400, 0x100); + } else { + // If the speed is below a threshold, deliberately mess up the target + // angle so the fairy "orbits" the target instead of reaching it. + targetAngle += 0x2000; + Math_SmoothStepToS(&this->actor.world.rot.y, targetAngle, 10, 0x200, 0x80); + } + EnElforg_ApproachTargetSpeedXZ(this); + Actor_MoveWithGravity(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD1F0.s") +void func_80ACCBB8(EnElforg* this, GlobalContext* globalCtx) { + globalCtx->actorCtx.unk5 |= 8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD2E4.s") +void EnElforg_TrappedByBubble(EnElforg* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if ((this->actor.parent == NULL) || (this->actor.parent->update == NULL)) { + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_FreeFloating; + } else { + this->actor.shape.yOffset += 10.0f * Math_SinS(this->timer << 9); + this->actor.world.pos = this->actor.parent->world.pos; + this->actor.world.pos.y += 12.0f; + } + func_80ACCBB8(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD59C.s") +void EnElforg_TurnInFairy(EnElforg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 xzDistToPlayer; + s16 rotationTemp; + s16 newAngle; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD610.s") + // This code makes the fairy briefly circle the player before + // flying towards the fountain's center. + SkelAnime_Update(&this->skelAnime); + this->actor.shape.yOffset *= 0.9f; + this->actor.speedXZ = 5.0f; + EnElforg_ApproachTargetYPosition(this, &player->bodyPartsPos[0]); + xzDistToPlayer = this->actor.xzDistToPlayer; + if (xzDistToPlayer < 0.0f) { + xzDistToPlayer = 10.0f; + } + newAngle = 0x28000 / xzDistToPlayer; + Math_SmoothStepToF(&xzDistToPlayer, 40.0f, 0.2f, 100.0f, 1.0f); + rotationTemp = this->actor.yawTowardsPlayer - newAngle; + this->actor.world.pos.x = player->actor.world.pos.x - (Math_SinS(rotationTemp) * xzDistToPlayer); + this->actor.world.pos.z = player->actor.world.pos.z - (Math_CosS(rotationTemp) * xzDistToPlayer); + EnElforg_SpawnSparkles(this, globalCtx, 16); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD6A8.s") + if (this->secondaryTimer > 0) { + this->secondaryTimer--; + } else { + this->actor.world.rot.y = rotationTemp + 0x4000; + this->timer = 0; + this->secondaryTimer = Rand_ZeroFloat(100.0f); + this->actor.shape.yOffset = 0.0f; + this->targetSpeedXZ = 3.0f; + this->targetDistanceFromHome = 50.0f; + this->actionFunc = EnElforg_FreeFloatingFairyFountain; + this->flags &= ~STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD6EC.s") +void EnElforg_QuicklyCircleFairyFountain(EnElforg* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + EnElforg_MoveToTargetFairyFountain(this, &this->actor.home.pos); + if (this->secondaryTimer <= 30) { + this->actionFunc = EnElforg_TurnInFairy; + } + this->secondaryTimer--; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/EnElforg_Update.s") +void EnElforg_FreeFloatingFairyFountain(EnElforg* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/func_80ACD878.s") + if (this->flags & STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME) { + // This happens when "turning in" the last batch of Stray Fairies to + // a Fairy Fountain. The ones being "turned in" will fly very + // quickly to the center of the fountain. + if (this->targetSpeedXZ < 8.0f) { + this->targetSpeedXZ += 0.1f; + } + if (this->targetDistanceFromHome > 0.0f) { + this->targetDistanceFromHome -= 2.0f; + } + } else if ((this->timer & 127) == 127) { + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) > 150.0f) { + this->targetSpeedXZ = 5.0f; + } else { + this->targetSpeedXZ = Rand_ZeroFloat(2.0f) + 1.0f; + } + this->targetDistanceFromHome = Rand_ZeroFloat(100.0f) + 50.0f; + } + SkelAnime_Update(&this->skelAnime); + EnElforg_MoveToTargetFairyFountain(this, &this->actor.home.pos); + if (this->flags & STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN) { + // A small number of fairies will do this when the player walks into + // the center of the fountain to be healed. + this->actionFunc = EnElforg_QuicklyCircleFairyFountain; + } + if (this->flags & STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS) { + // This happens right before the Great Fairy appears once all + // Stray Fairies are saved. + if (this->actor.home.rot.x > 0) { + EnElforg_SpawnSparkles(this, globalCtx, 10); + this->actor.home.rot.x--; + } + Actor_SetScale(&this->actor, this->actor.scale.x * 0.9f); + if (this->actor.scale.x < 0.001f) { + Actor_MarkForDeath(&this->actor); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elforg/EnElforg_Draw.s") +void EnElforg_CirclePlayer(EnElforg* this, GlobalContext* globalCtx) { + s32 pad; + Actor* playerActor = &GET_PLAYER(globalCtx)->actor; + Player* player = GET_PLAYER(globalCtx); + f32 distanceFromPlayer; + + if (gSaveContext.save.playerForm == PLAYER_FORM_GORON) { + distanceFromPlayer = 40.0f; + } else { + distanceFromPlayer = 20.0f; + } + this->actor.world.pos.x = (Math_SinS(this->timer << 12) * distanceFromPlayer) + playerActor->world.pos.x; + this->actor.world.pos.z = (Math_CosS(this->timer << 12) * distanceFromPlayer) + playerActor->world.pos.z; + this->actor.world.pos.y = player->bodyPartsPos[0].y; + EnElforg_SpawnSparkles(this, globalCtx, 16); +} + +void EnElforg_FairyCollected(EnElforg* this, GlobalContext* globalCtx) { + EnElforg_CirclePlayer(this, globalCtx); + if (this->timer > 80) { + Actor_MarkForDeath(&this->actor); + return; + } + func_800B9010(&this->actor, NA_SE_PL_CHIBI_FAIRY_HEAL - SFX_FLAG); +} + +void EnElforg_SetupFairyCollected(EnElforg* this, GlobalContext* globalCtx) { + Actor* playerActor = &GET_PLAYER(globalCtx)->actor; + Player* player = GET_PLAYER(globalCtx); + + this->actor.world.pos.x = playerActor->world.pos.x; + this->actor.world.pos.y = player->bodyPartsPos[0].y; + this->actor.world.pos.z = playerActor->world.pos.z; + this->actionFunc = EnElforg_FairyCollected; + this->timer = 0; + this->secondaryTimer = 0; + this->actor.shape.yOffset = 0.0f; +} + +void EnElforg_ClockTownFairyCollected(EnElforg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + EnElforg_CirclePlayer(this, globalCtx); + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + player->actor.freezeTimer = 0; + player->stateFlags1 &= ~0x20000000; + Actor_MarkForDeath(&this->actor); + gSaveContext.save.weekEventReg[8] |= 0x80; + ActorCutscene_Stop(0x7C); + } else { + func_800B9010(&this->actor, NA_SE_PL_CHIBI_FAIRY_HEAL - SFX_FLAG); + if (ActorCutscene_GetCurrentIndex() != 0x7C) { + if (ActorCutscene_GetCanPlayNext(0x7C)) { + ActorCutscene_Start(0x7C, &this->actor); + } else { + ActorCutscene_SetIntentToPlay(0x7C); + } + } + } +} + +void EnElforg_FreeFloating(EnElforg* this, GlobalContext* globalCtx) { + Vec3f pos; + f32 scaledYDistance; + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + if (Player_GetMask(globalCtx) == PLAYER_MASK_GREAT_FAIRY) { + pos = player->bodyPartsPos[0]; + this->targetSpeedXZ = 5.0f; + EnElforg_MoveToTarget(this, &pos); + } else { + this->targetSpeedXZ = 1.0f; + EnElforg_MoveToTarget(this, &this->actor.home.pos); + } + + scaledYDistance = this->actor.playerHeightRel - (this->actor.shape.yOffset * this->actor.scale.y); + if (!Player_InCsMode(&globalCtx->state)) { + if ((this->actor.xzDistToPlayer < 30.0f) && (scaledYDistance < 12.0f) && (scaledYDistance > -68.0f)) { + EnElforg_SetupFairyCollected(this, globalCtx); + func_80115908(globalCtx, 48); + switch (STRAY_FAIRY_TYPE(&this->actor)) { + case STRAY_FAIRY_TYPE_COLLECTIBLE: + Flags_SetCollectible(globalCtx, STRAY_FAIRY_FLAG(&this->actor)); + break; + case STRAY_FAIRY_TYPE_CHEST: + Flags_SetTreasure(globalCtx, STRAY_FAIRY_FLAG(&this->actor)); + break; + default: + Flags_SetSwitch(globalCtx, STRAY_FAIRY_FLAG(&this->actor)); + break; + } + + if (STRAY_FAIRY_TYPE(&this->actor) == STRAY_FAIRY_TYPE_CLOCK_TOWN) { + player->actor.freezeTimer = 100; + player->stateFlags1 |= 0x20000000; + Message_StartTextbox(globalCtx, 0x579, NULL); + this->actionFunc = EnElforg_ClockTownFairyCollected; + ActorCutscene_SetIntentToPlay(0x7C); + return; + } + + if (func_8010A074(globalCtx)) { + gSaveContext.save.inventory.strayFairies[gSaveContext.unk_48C8]++; + Message_StartTextbox(globalCtx, 0x11, NULL); + if (gSaveContext.save.inventory.strayFairies[(void)0, gSaveContext.unk_48C8] >= 15) { + func_801A3098(NA_BGM_GET_ITEM | 0x900); + } + } + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 20.0f, 7); + func_80ACCBB8(this, globalCtx); + if (Player_GetMask(globalCtx) == PLAYER_MASK_GREAT_FAIRY) { + if (!(this->flags & STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED)) { + play_sound(NA_SE_SY_FAIRY_MASK_SUCCESS); + } + this->flags |= STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; + } else { + this->flags &= ~STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED; + } + } +} + +/** + * This finds the enemy that is "holding" the Stray Fairy hostage. When + * this enemy is killed, the Stray Fairy will spawn. This function only + * works if the enemy and the Stray Fairy have the exact same home + * coordinates when the Stray Fairy first spawns. + */ +Actor* EnElforg_GetHoldingEnemy(EnElforg* this, GlobalContext* globalCtx) { + Actor* enemy; + + for (enemy = globalCtx->actorCtx.actorLists[ACTORCAT_ENEMY].first; enemy != NULL; enemy = enemy->next) { + if ((enemy->home.pos.x == this->actor.home.pos.x) && (enemy->home.pos.y == this->actor.home.pos.y) && + (enemy->home.pos.z == this->actor.home.pos.z)) { + return enemy; + } + } + return NULL; +} + +void EnElforg_TrappedByEnemy(EnElforg* this, GlobalContext* globalCtx) { + f32 posTemp; + + if (this->enemy->update == NULL) { + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_FreeFloating; + this->actor.draw = EnElforg_Draw; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHIBI_FAIRY_SAVED); + } else { + // The enemy is still alive, so have the Stray Fairy + // track the enemy in case it's moving around. + posTemp = this->enemy->world.pos.x; + this->actor.world.pos.x = posTemp; + this->actor.home.pos.x = posTemp; + posTemp = this->enemy->world.pos.y + 30.0f; + this->actor.world.pos.y = posTemp; + this->actor.home.pos.y = posTemp; + posTemp = this->enemy->world.pos.z; + this->actor.world.pos.z = posTemp; + this->actor.home.pos.z = posTemp; + } + func_80ACCBB8(this, globalCtx); +} + +void EnElforg_SetupTrappedByEnemy(EnElforg* this, GlobalContext* globalCtx) { + Actor* enemy = EnElforg_GetHoldingEnemy(this, globalCtx); + + if (enemy != NULL && enemy->update != NULL) { + this->actionFunc = EnElforg_TrappedByEnemy; + this->enemy = enemy; + } +} + +void EnElforg_HiddenByCollider(EnElforg* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + EnElforg_InitializeParams(this); + this->actionFunc = EnElforg_FreeFloating; + this->actor.draw = EnElforg_Draw; + this->actor.world.pos.y += 40.0f; + this->actor.home.pos.y += 40.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHIBI_FAIRY_SAVED); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + func_80ACCBB8(this, globalCtx); +} + +void EnElforg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnElforg* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->timer == 0 && this->secondaryTimer > 0) { + this->secondaryTimer--; + } else { + this->timer++; + } + + if (this->direction < 0) { + this->direction++; + if (this->direction == 0) { + this->direction = Rand_ZeroFloat(20.0f) + 20.0f; + } + } else if (this->direction > 0) { + this->direction--; + } else { + this->direction = -Rand_ZeroFloat(20.0f) - 20.0f; + } +} + +s32 EnElforg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + EnElforg* this = THIS; + + if (this->direction < 0) { + if (limbIndex == STRAY_FAIRY_LIMB_LEFT_FACING_HEAD) { + *dList = NULL; + } + } else if (limbIndex == STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD) { + *dList = NULL; + } + + return false; +} + +void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + 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(gStrayFairyWoodfallTexAnim)); + break; + case STRAY_FAIRY_AREA_SNOWHEAD: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairySnowheadTexAnim)); + break; + case STRAY_FAIRY_AREA_GREAT_BAY: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyGreatBayTexAnim)); + break; + case STRAY_FAIRY_AREA_STONE_TOWER: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyStoneTowerTexAnim)); + break; + default: + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyClockTownTexAnim)); + break; + } + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnElforg_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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 cd3f037bf..fbf982beb 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h @@ -3,14 +3,68 @@ #include "global.h" +#define STRAY_FAIRY_TYPE(thisx) ((thisx)->params & 0xF) +#define STRAY_FAIRY_GET_PARAM_1C0(thisx) ((thisx)->params & 0x1C0) +#define STRAY_FAIRY_FLAG(thisx) (((thisx)->params & 0xFE00) >> 9) + +#define STRAY_FAIRY_FLAG_MOVES_QUICKLY_TO_HOME (1 << 0) +#define STRAY_FAIRY_FLAG_SPARKLES_AND_SHRINKS (1 << 1) +#define STRAY_FAIRY_FLAG_CIRCLES_QUICKLY_IN_FOUNTAIN (1 << 2) +#define STRAY_FAIRY_FLAG_GREAT_FAIRYS_MASK_EQUIPPED (1 << 3) + +typedef enum { + STRAY_FAIRY_TYPE_FREE_FLOATING, // The ones just floating around + STRAY_FAIRY_TYPE_FAIRY_FOUNTAIN, // The ones already present when you enter a Fairy Fountain + STRAY_FAIRY_TYPE_BUBBLE, // The ones trapped in bubbles + STRAY_FAIRY_TYPE_CLOCK_TOWN, // The free-floating Stray Fairies in Clock Town + STRAY_FAIRY_TYPE_ENEMY, // The ones trapped inside enemies + STRAY_FAIRY_TYPE_COLLIDER, // Unused in retail. The fairy is hidden until the collider is hit + STRAY_FAIRY_TYPE_CHEST, // The ones in treasure chests + STRAY_FAIRY_TYPE_COLLECTIBLE, // The ones in boxes, pots, beehives, etc. + STRAY_FAIRY_TYPE_TURN_IN_TO_FAIRY_FOUNTAIN // The ones you "turn in" by walking into a Fairy Fountain +} StrayFairyType; + +typedef enum { + STRAY_FAIRY_AREA_CLOCK_TOWN, + STRAY_FAIRY_AREA_WOODFALL, + STRAY_FAIRY_AREA_SNOWHEAD, + STRAY_FAIRY_AREA_GREAT_BAY, + STRAY_FAIRY_AREA_STONE_TOWER, + 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*); typedef struct EnElforg { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xE8]; - /* 0x022C */ EnElforgActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[STRAY_FAIRY_LIMB_MAX]; + /* 0x1C4 */ ColliderCylinder collider; + /* 0x210 */ Actor* enemy; + /* 0x214 */ u16 flags; + /* 0x216 */ s16 direction; // negative when facing right, positive when facing left + /* 0x218 */ s16 area; + /* 0x21C */ s32 timer; + /* 0x220 */ s32 secondaryTimer; + /* 0x224 */ f32 targetSpeedXZ; + /* 0x228 */ f32 targetDistanceFromHome; + /* 0x22C */ EnElforgActionFunc actionFunc; } EnElforg; // size = 0x230 extern const ActorInit En_Elforg_InitVars; 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 3d8c9161c..b9a186057 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -1,6 +1,12 @@ +/* + * File: z_en_encount1.c + * Overlay: ovl_En_Encount1 + * Description: Spawner for Dragonflies, Skullfish, and Wallmasters + */ + #include "z_en_encount1.h" -#define FLAGS 0x08100010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_8000000) #define THIS ((EnEncount1*)thisx) 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..3cf01bd8a 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,11 @@ typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, GlobalContext*); typedef struct EnEncount1 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEncount1ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1C]; + /* 0x0148 */ char unk_148[0x6]; + /* 0x014E */ s16 unk_14E; + /* 0x0150 */ char unk_150[0xA]; + /* 0x015A */ s16 unk_15A; + /* 0x015C */ char unk_15C[0x8]; } 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 ba444eb6c..ea7ee7aa4 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -1,6 +1,14 @@ -#include "z_en_encount2.h" +/* + * File: z_en_encount2.c + * Overlay: ovl_En_Encount2 + * Description: Astral Observatory - Majora's Mask Balloon + */ -#define FLAGS 0x00000010 +#include "z_en_encount2.h" +#include "objects/object_fusen/object_fusen.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnEncount2*)thisx) @@ -91,19 +99,15 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(0, 0xF), }; -extern Gfx D_06000A00[]; -extern Gfx D_06000D78[]; -extern CollisionHeader D_06002420; - void EnEncount2_Init(Actor* thisx, GlobalContext* globalCtx) { EnEncount2* this = THIS; s32 pad; CollisionHeader* colHeader = NULL; - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck_RelocateMeshHeader(&D_06002420, &colHeader); - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); - ActorShape_Init(&this->dyna.actor.shape, 0.0f, func_800B3FC0, 25.0f); + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&object_fusen_Colheader_002420, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->dyna.actor, &sJntSphInit, &this->colElement); @@ -133,7 +137,7 @@ void EnEncount2_Init(Actor* thisx, GlobalContext* globalCtx) { void EnEncount2_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnEncount2* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyJntSph(globalCtx, &this->collider); } @@ -166,7 +170,7 @@ void EnEncount2_Popped(EnEncount2* this, GlobalContext* globalCtx) { EnEncount2_InitParticles(this, &curPos, 10); } - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_MUJURA_BALLOON_BROKEN); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_MUJURA_BALLOON_BROKEN); this->deathTimer = 30; this->actionFunc = EnEncount2_Die; } @@ -174,7 +178,7 @@ void EnEncount2_Popped(EnEncount2* this, GlobalContext* globalCtx) { void EnEncount2_Die(EnEncount2* this, GlobalContext* globalCtx) { if (this->deathTimer == 0) { if (this->switchFlag >= 0) { - Actor_SetSwitchFlag(globalCtx, this->switchFlag); + Flags_SetSwitch(globalCtx, this->switchFlag); } Actor_MarkForDeath(&this->dyna.actor); } @@ -187,10 +191,10 @@ void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx) { DECR(this->deathTimer); this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; - Actor_SetHeight(&this->dyna.actor, 30.0f); + Actor_SetFocus(&this->dyna.actor, 30.0f); Actor_SetScale(&this->dyna.actor, this->scale); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->dyna.actor); + Actor_MoveWithGravity(&this->dyna.actor); EnEncount2_UpdateParticles(this, globalCtx); if (!this->isPopped) { @@ -203,8 +207,8 @@ void EnEncount2_Update(Actor* thisx, GlobalContext* globalCtx) { void EnEncount2_Draw(Actor* thisx, GlobalContext* globalCtx) { EnEncount2* this = THIS; if (this->isPopped != true) { - func_800BDFC0(globalCtx, D_06000A00); - func_800BDFC0(globalCtx, D_06000D78); + Gfx_DrawDListOpa(globalCtx, object_fusen_DL_000A00); + Gfx_DrawDListOpa(globalCtx, object_fusen_DL_000D78); } EnEncount2_DrawParticles(this, globalCtx); } @@ -270,19 +274,19 @@ void EnEncount2_DrawParticles(EnEncount2* this, GlobalContext* globalCtx) { func_8012C2DC(globalCtx->state.gfxCtx); for (i = 0; i < ARRAY_COUNT(this->particles); i++, sPtr++) { if (sPtr->enabled) { - Matrix_InsertTranslation(sPtr->pos.x, sPtr->pos.y, sPtr->pos.z, MTXMODE_NEW); + Matrix_Translate(sPtr->pos.x, sPtr->pos.y, sPtr->pos.z, MTXMODE_NEW); Matrix_Scale(sPtr->scale, sPtr->scale, sPtr->scale, MTXMODE_APPLY); POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); - gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(&D_04079B10)); - gSPDisplayList(POLY_XLU_DISP++, D_0407AB10); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); 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_InsertZRotation_f(DEGTORAD(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZF(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); - gSPDisplayList(POLY_XLU_DISP++, D_0407AB58); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); } } CLOSE_DISPS(gfxCtx); 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 13ba1ea33..b9681b5e1 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c @@ -1,6 +1,12 @@ +/* + * File: z_en_encount3.c + * Overlay: ovl_En_Encount3 + * Description: Garo spawner + */ + #include "z_en_encount3.h" -#define FLAGS 0x08000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_8000000) #define THIS ((EnEncount3*)thisx) 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 99c17f7c0..eaadd8133 100644 --- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c +++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c @@ -1,6 +1,12 @@ +/* + * File: z_en_encount4.c + * Overlay: ovl_En_Encount4 + * Description: Spawner for Stalchild and Fire Wall in Keeta chase + */ + #include "z_en_encount4.h" -#define FLAGS 0x08000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_8000000) #define THIS ((EnEncount4*)thisx) 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 089ee3788..b366a4dec 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,6 +1,13 @@ -#include "z_en_ending_hero.h" +/* + * File: z_en_ending_hero.c + * Overlay: ovl_En_Ending_Hero + * Description: Mayor Dotour at wedding during the credits + */ -#define FLAGS 0x00000009 +#include "z_en_ending_hero.h" +#include "objects/object_dt/object_dt.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero*)thisx) @@ -24,26 +31,16 @@ const ActorInit En_Ending_Hero_InitVars = { (ActorFunc)EnEndingHero_Draw, }; -extern FlexSkeletonHeader D_0600B0CC; -extern AnimationHeader D_06000BE0; -extern UNK_PTR D_06007350[]; -extern UNK_PTR D_06009590[]; -extern UNK_PTR D_06009F90[]; -extern UNK_PTR D_0600A790[]; -extern UNK_PTR D_0600AB90[]; -extern UNK_PTR D_06007750[]; -extern UNK_PTR D_0600A390[]; -extern UNK_PTR D_0600A490[]; - void EnEndingHero_Init(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero* this = THIS; - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.gravity = -3.0f; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600B0CC, &D_06000BE0, this->jointTable, this->morphTable, 15); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dt_Skel_00B0CC, &object_dt_Anim_000BE0, this->jointTable, + this->morphTable, 15); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); func_80C1E748(this); } @@ -70,12 +67,18 @@ void EnEndingHero_Update(Actor* thisx, GlobalContext* globalCtx) { } } this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } -static UNK_PTR D_80C1E970[] = { D_06007350, D_06009590, D_06009F90, D_0600A790, D_0600AB90 }; -static UNK_PTR D_80C1E984[] = { D_06007750, D_0600A390, D_0600A490 }; +static TexturePtr D_80C1E970[] = { + object_dt_Tex_007350, object_dt_Tex_009590, object_dt_Tex_009F90, object_dt_Tex_00A790, object_dt_Tex_00AB90, +}; +static TexturePtr D_80C1E984[] = { + object_dt_Tex_007750, + object_dt_Tex_00A390, + object_dt_Tex_00A490, +}; void EnEndingHero_Draw(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero* this = THIS; @@ -93,7 +96,7 @@ void EnEndingHero_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C1E984[index])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 0ff95496d..f3515787c 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,6 +1,13 @@ -#include "z_en_ending_hero2.h" +/* + * File: z_en_ending_hero2.c + * Overlay: ovl_En_Ending_Hero2 + * Description: Viscen watching moon disappearance and wedding + */ -#define FLAGS 0x00000009 +#include "z_en_ending_hero2.h" +#include "objects/object_bai/object_bai.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero2*)thisx) @@ -24,18 +31,16 @@ const ActorInit En_Ending_Hero2_InitVars = { (ActorFunc)EnEndingHero2_Draw, }; -extern FlexSkeletonHeader D_06007908; -extern AnimationHeader D_060011C0; - void EnEndingHero2_Init(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero2* this = THIS; - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.gravity = -3.0f; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06007908, &D_060011C0, this->jointTable, this->morphTable, 20); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_bai_Skel_007908, &object_bai_Anim_0011C0, this->jointTable, + this->morphTable, 20); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); func_80C232E8(this); } @@ -55,7 +60,7 @@ void EnEndingHero2_Update(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero2* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } @@ -65,5 +70,5 @@ void EnEndingHero2_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } 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 91a42c409..91c44e741 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,6 +1,13 @@ -#include "z_en_ending_hero3.h" +/* + * File: z_en_ending_hero3.c + * Overlay: ovl_En_Ending_Hero3 + * Description: Mutoh watching moon disappearance and wedding + */ -#define FLAGS 0x00000009 +#include "z_en_ending_hero3.h" +#include "objects/object_toryo/object_toryo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero3*)thisx) @@ -24,18 +31,16 @@ const ActorInit En_Ending_Hero3_InitVars = { (ActorFunc)EnEndingHero3_Draw, }; -extern FlexSkeletonHeader D_06007150; -extern AnimationHeader D_06000E50; - void EnEndingHero3_Init(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero3* this = THIS; - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.gravity = -3.0f; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06007150, &D_06000E50, this->jointTable, this->morphTable, 17); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_toryo_Skel_007150, &object_toryo_Anim_000E50, + this->jointTable, this->morphTable, 17); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); func_80C23518(this); } @@ -55,7 +60,7 @@ void EnEndingHero3_Update(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero3* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } @@ -65,5 +70,5 @@ void EnEndingHero3_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } 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 949999b57..1e54ee8b9 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,6 +1,13 @@ -#include "z_en_ending_hero4.h" +/* + * File: z_en_ending_hero4.c + * Overlay: ovl_En_Ending_Hero4 + * Description: Soldiers watching moon disappearance and Indigo-Go's + */ -#define FLAGS 0x00000009 +#include "z_en_ending_hero4.h" +#include "objects/object_sdn/object_sdn.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero4*)thisx) @@ -24,18 +31,16 @@ const ActorInit En_Ending_Hero4_InitVars = { (ActorFunc)EnEndingHero4_Draw, }; -extern FlexSkeletonHeader D_0600D640; -extern AnimationHeader D_06002A84; - void EnEndingHero4_Init(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero4* this = THIS; - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.gravity = -3.0f; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600D640, &D_06002A84, this->jointTable, this->morphTable, 17); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gSoldierSkeleton, &gSoldierCheerWithSpear, this->jointTable, + this->morphTable, 17); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); func_80C23748(this); } @@ -55,7 +60,7 @@ void EnEndingHero4_Update(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero4* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } @@ -65,5 +70,5 @@ void EnEndingHero4_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - 0, 0, &this->actor); + NULL, NULL, &this->actor); } 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 1e392ef12..23ac531f3 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,6 +1,13 @@ -#include "z_en_ending_hero5.h" +/* + * File: z_en_ending_hero5.c + * Overlay: ovl_En_Ending_Hero5 + * Description: Carpenters watching moon disappearance and Indigo-Go's + */ -#define FLAGS 0x00000009 +#include "z_en_ending_hero5.h" +#include "objects/object_daiku/object_daiku.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero5*)thisx) @@ -24,24 +31,16 @@ const ActorInit En_Ending_Hero5_InitVars = { (ActorFunc)EnEndingHero5_Draw, }; -extern FlexSkeletonHeader D_0600A850; -extern AnimationHeader D_06002FA0; - -extern Gfx D_060070C0[]; -extern Gfx D_06006FB0[]; -extern Gfx D_06006E80[]; -extern Gfx D_06006D70[]; -extern Gfx D_0600A390[]; - void EnEndingHero5_Init(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero5* this = THIS; - this->actor.colChkInfo.mass = 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); this->actor.targetMode = 6; this->actor.gravity = -3.0f; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A850, &D_06002FA0, this->jointTable, this->morphTable, 17); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_daiku_Skel_00A850, &object_daiku_Anim_002FA0, + this->jointTable, this->morphTable, 17); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); this->unk25C = this->actor.params; func_80C23980(this); } @@ -62,13 +61,14 @@ void EnEndingHero5_Update(Actor* thisx, GlobalContext* globalCtx) { EnEndingHero5* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } -Gfx* D_80C23BF0[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70, D_0600A390 }; +Gfx* D_80C23BF0[] = { object_daiku_DL_0070C0, object_daiku_DL_006FB0, object_daiku_DL_006E80, object_daiku_DL_006D70, + object_daiku_DL_00A390 }; -void func_80C23A30(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnEndingHero5_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnEndingHero5* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -106,7 +106,7 @@ void EnEndingHero5_Draw(Actor* thisx, GlobalContext* globalCtx) { } SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - NULL, func_80C23A30, &this->actor); + NULL, EnEndingHero5_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c index d692d4f11..82df507c2 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c +++ b/src/overlays/actors/ovl_En_Ending_Hero6/z_en_ending_hero6.c @@ -5,8 +5,13 @@ */ #include "z_en_ending_hero6.h" +#include "objects/object_dt/object_dt.h" +#include "objects/object_daiku/object_daiku.h" +#include "objects/object_bai/object_bai.h" +#include "objects/object_toryo/object_toryo.h" +#include "objects/object_sdn/object_sdn.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnEndingHero6*)thisx) @@ -19,36 +24,6 @@ void EnEndingHero6_InitSkelAnime(EnEndingHero6* this, s32 npcIndex); void EnEndingHero6_SetupIdle(EnEndingHero6* this); void EnEndingHero6_Idle(EnEndingHero6* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_0600B0CC; // object_dt -extern FlexSkeletonHeader D_06007908; // object_bai -extern FlexSkeletonHeader D_06007150; // object_toryo -extern FlexSkeletonHeader D_0600D640; // object_sdn -extern FlexSkeletonHeader D_0600A850; // object_daiku - -extern AnimationHeader D_06000BE0; // object_dt -extern AnimationHeader D_060011C0; // object_bai -extern AnimationHeader D_06000E50; // object_toryo -extern AnimationHeader D_06002A84; // object_sdn -extern AnimationHeader D_06002FA0; // object_daiku - -// object_daiku -extern Gfx D_060070C0[]; -extern Gfx D_06006FB0[]; -extern Gfx D_06006E80[]; -extern Gfx D_06006D70[]; -extern Gfx D_0600A390_dl[]; - -// object_dt -extern TexturePtr D_06007350; -extern TexturePtr D_06009590; -extern TexturePtr D_06009F90; -extern TexturePtr D_0600A790; -extern TexturePtr D_0600AB90; - -extern TexturePtr D_06007750; -extern TexturePtr D_0600A390_tex; -extern TexturePtr D_0600A490; - const ActorInit En_Ending_Hero6_InitVars = { ACTOR_EN_ENDING_HERO6, ACTORCAT_NPC, @@ -61,11 +36,17 @@ const ActorInit En_Ending_Hero6_InitVars = { (ActorFunc)EnEndingHero6_Draw, }; -static FlexSkeletonHeader* sSkeletons[] = { &D_0600B0CC, &D_06007908, &D_06007150, &D_0600D640, &D_0600A850, - &D_0600A850, &D_0600A850, &D_0600A850, &D_0600A850 }; +static FlexSkeletonHeader* sSkeletons[] = { + &object_dt_Skel_00B0CC, &object_bai_Skel_007908, &object_toryo_Skel_007150, + &gSoldierSkeleton, &object_daiku_Skel_00A850, &object_daiku_Skel_00A850, + &object_daiku_Skel_00A850, &object_daiku_Skel_00A850, &object_daiku_Skel_00A850, +}; -static AnimationHeader* sAnimations[] = { &D_06000BE0, &D_060011C0, &D_06000E50, &D_06002A84, &D_06002FA0, - &D_06002FA0, &D_06002FA0, &D_06002FA0, &D_06002FA0 }; +static AnimationHeader* sAnimations[] = { + &object_dt_Anim_000BE0, &object_bai_Anim_0011C0, &object_toryo_Anim_000E50, + &gSoldierCheerWithSpear, &object_daiku_Anim_002FA0, &object_daiku_Anim_002FA0, + &object_daiku_Anim_002FA0, &object_daiku_Anim_002FA0, &object_daiku_Anim_002FA0, +}; static s32 sLimbCounts[] = { 15, 20, 17, 17, 17, 17, 17, 17, 17 }; @@ -78,7 +59,7 @@ void EnEndingHero6_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.gravity = -3.0f; SkelAnime_InitFlex(globalCtx, &this->skelAnime, sSkeletons[this->npcIndex], sAnimations[this->npcIndex], this->jointTable, this->morphTable, sLimbCounts[this->npcIndex]); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); EnEndingHero6_SetupIdle(this); } @@ -119,12 +100,13 @@ void EnEndingHero6_Update(Actor* thisx, GlobalContext* globalCtx) { } this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); } void EnEndingHero6_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { - static Gfx* D_80C2426C[] = { D_060070C0, D_06006FB0, D_06006E80, D_06006D70, D_0600A390_dl }; + static Gfx* D_80C2426C[] = { object_daiku_DL_0070C0, object_daiku_DL_006FB0, object_daiku_DL_006E80, + object_daiku_DL_006D70, object_daiku_DL_00A390 }; EnEndingHero6* this = THIS; s32 index; @@ -139,8 +121,9 @@ void EnEndingHero6_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d } void EnEndingHero6_Draw(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr D_80C24280[] = { &D_06007350, &D_06009590, &D_06009F90, &D_0600A790, &D_0600AB90 }; - static TexturePtr D_80C24294[] = { &D_06007750, &D_0600A390_tex, &D_0600A490 }; + static TexturePtr D_80C24280[] = { object_dt_Tex_007350, object_dt_Tex_009590, object_dt_Tex_009F90, + object_dt_Tex_00A790, object_dt_Tex_00AB90 }; + static TexturePtr D_80C24294[] = { object_dt_Tex_007750, object_dt_Tex_00A390, object_dt_Tex_00A490 }; s32 pad; EnEndingHero6* this = THIS; s32 index = 0; diff --git a/src/overlays/actors/ovl_En_Estone/z_en_estone.c b/src/overlays/actors/ovl_En_Estone/z_en_estone.c index a3cd6bd21..b1ac6673a 100644 --- a/src/overlays/actors/ovl_En_Estone/z_en_estone.c +++ b/src/overlays/actors/ovl_En_Estone/z_en_estone.c @@ -1,6 +1,12 @@ +/* + * File: z_en_estone.c + * Overlay: ovl_En_Estone + * Description: Eyegore Rubble + */ + #include "z_en_estone.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnEstone*)thisx) 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 f56948ded..b84eb3d74 100644 --- a/src/overlays/actors/ovl_En_Fall/z_en_fall.c +++ b/src/overlays/actors/ovl_En_Fall/z_en_fall.c @@ -1,23 +1,65 @@ -#include "z_en_fall.h" +/* + * File: z_en_fall.c + * Overlay: ovl_En_Fall + * 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: + * - Moon: A high-detail moon, used in Termina Field, the Clock Tower, and a few cutscenes. + * - StoppedClosedMouthMoon: A high-detail moon, used in the Clock Tower after the Giants stop the moon from crashing. + * - StoppedOpenMouthMoon: A high-detail open-mouthed moon, used in the cutscene prior to warping to the moon. + * - CrashingMoon: An enlarged high-detail moon, used for when the moon is crashing. + * - LodMoon: A low-detail moon, used everywhere else. + * - MoonsTear: The Moon's Tear that can be seen falling from the telescope, along with its associated fire trail. + * - Fireball: The ball of fire that surrounds the moon when it is crashing. + * - RisingDebris: The debris that rises from the ground as the moon is crashing. + * - FireRing: The ring of fire that expands outward when the moon is almost done crashing. + */ -#define FLAGS 0x00000030 +#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 (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnFall*)thisx) +#define FLAG_FIRE_BALL_INTENSIFIES (1 << 0) +#define FLAG_FIRE_RING_APPEARS (1 << 1) + 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 modelIndex; + Vec3f pos; + Vec3f velocity; + Vec3s rot; +} EnFallDebrisParticle; + +EnFallDebrisParticle debrisParticles[50]; -#if 0 const ActorInit En_Fall_InitVars = { ACTOR_EN_FALL, ACTORCAT_ITEMACTION, @@ -30,75 +72,858 @@ 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.save.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6BF90.s") + case 1: + Actor_SetScale(&this->actor, this->scale * 2.4f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C1DC.s") + case 2: + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Init.s") + 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/EnFall_Destroy.s") +void EnFall_RisingDebris_ResetParticles(EnFall* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3AC.s") + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + debrisParticles[i].modelIndex = 3; + } + this->activeDebrisParticleCount = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3FC.s") +void EnFall_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + s32 objectIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C7C0.s") + this->eyeGlowIntensity = 0.0f; + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C9A8.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CA9C.s") + case 2: + this->scale = 0.04f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CB74.s") + case 3: + this->scale = 0.02f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD38.s") + case 4: + this->scale = 0.01f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD74.s") + default: + this->scale = 0.16f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CECC.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF60.s") + case EN_FALL_TYPE_MOONS_TEAR: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MOONSTON); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF70.s") + case EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Update.s") + default: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D100.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_80A6D220.s") +void EnFall_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D444.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.actorLists[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D504.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_80A6D698.s") +void EnFall_Setup(EnFall* this, GlobalContext* globalCtx) { + Actor* moon; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D75C.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D88C.s") + 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.save.weekEventReg[25] & 2)) { + Actor_MarkForDeath(&this->actor); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D98C.s") + 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.save.weekEventReg[25] & 2) { + Actor_MarkForDeath(&this->actor); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DA7C.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC20.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC40.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DD3C.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E07C.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E214.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E37C.s") + 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: + // used for EN_FALL_TYPE_TERMINA_FIELD_MOON and anything else that isn't in the enum + this->actor.draw = EnFall_Moon_Draw; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + } + } +} + +void EnFall_CrashingMoon_HandleGiantsCutscene(EnFall* this, GlobalContext* globalCtx) { + static s32 sGiantsCutsceneState = 0; + + if (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 1 && + globalCtx->csCtx.currentCsIndex == 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.save.weekEventReg[93] & 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.save.weekEventReg[93] |= 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; + } + } +} + +void EnFall_CrashingMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + EnFall_CrashingMoon_HandleGiantsCutscene(this, globalCtx); + if (Cutscene_CheckActorAction(globalCtx, 0x85)) { + if (Cutscene_CheckActorAction(globalCtx, 133) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action == 1) { + this->actor.draw = NULL; + } else { + this->actor.draw = EnFall_Moon_Draw; + if (Cutscene_CheckActorAction(globalCtx, 133) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action == 2) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 133)); + } + } + } else { + this->actor.draw = NULL; + } +} + +void EnFall_StoppedOpenMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 133)) { + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action) { + case 3: + if (this->eyeGlowIntensity == 0.0f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MOON_EYE_FLASH); + } + this->eyeGlowIntensity += 1 / 30.0f; + if (this->eyeGlowIntensity > 1.0f) { + this->eyeGlowIntensity = 1.0f; + } + break; + + case 4: + this->actor.draw = EnFall_OpenMouthMoon_Draw; + break; + } + } +} + +void EnFall_StoppedClosedMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 133)) { + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action) { + case 2: + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 133)); + break; + + case 4: + this->actor.draw = NULL; + break; + } + } + + if (globalCtx->sceneNum == SCENE_OKUJOU && gSaveContext.sceneSetupIndex == 2) { + switch (globalCtx->csCtx.currentCsIndex) { + case 0: + switch (globalCtx->csCtx.frames) { + case 1060: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + + case 1089: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MOON_CRY); + break; + + case 1303: + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + + case 590: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MOON_CRY); + break; + + case 737: + Actor_PlaySfxAtPos(&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; + } + } +} + +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); + } +} + +/** + * Used by the Moon in Termina Field, as well as all LodMoons. + */ +void EnFall_Moon_PerformDefaultActions(EnFall* this, GlobalContext* globalCtx) { + u16 currentDay; + + if (Cutscene_CheckActorAction(globalCtx, 133)) { + if (Cutscene_CheckActorAction(globalCtx, 133) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action == 1) { + this->actor.draw = NULL; + } else { + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.draw = EnFall_Moon_Draw; + if (Cutscene_CheckActorAction(globalCtx, 133) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 133)]->action == 2) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 133)); + } + } + } 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.save.time; + } + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + } +} + +void EnFall_MoonsTear_Initialize(EnFall* this) { + s32 pad[2]; + + 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; +} + +void EnFall_MoonsTear_DoNothing(EnFall* this, GlobalContext* globalCtx) { +} + +void EnFall_MoonsTear_Fall(EnFall* this, GlobalContext* globalCtx) { + s32 pad; + + if (Cutscene_CheckActorAction(globalCtx, 517) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 517)]->action == 2 && + this->actor.draw == NULL) { + EnFall_MoonsTear_Initialize(this); + } + + if (this->actor.draw != NULL) { + if (Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.home.pos, this->actor.speedXZ) <= 0.0f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_GORON_BOUND_1); + gSaveContext.save.weekEventReg[74] |= 0x80; + gSaveContext.save.weekEventReg[74] |= 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_MoonsTear_DoNothing; + } else { + func_800B9010(&this->actor, NA_SE_EV_MOONSTONE_FALL - SFX_FLAG); + } + } +} + +void EnFall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + this->actionFunc(this, globalCtx); +} + +/** + * 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, + }; + + s32 pad; + u8 perVertexAlphaTable[5]; + Vtx* vertices = Lib_SegmentedToVirtual(gMoonFireballVtx); + s32 i; + + 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.currentCsIndex == 2) { + globalCtx->skyboxCtx.rotY -= 0.05f; + } + + if (Cutscene_CheckActorAction(globalCtx, 450)) { + this->actor.draw = EnFall_Fireball_Draw; + if (this->flags & FLAG_FIRE_BALL_INTENSIFIES) { + this->fireballIntensity += 0.01f; + if (this->fireballIntensity > 1.0f) { + this->fireballIntensity = 1.0f; + } + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 450)); + + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 450)]->action) { + 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 |= FLAG_FIRE_BALL_INTENSIFIES; + break; + + case 5: + break; + } + } else { + this->actor.draw = NULL; + } + + if (Cutscene_CheckActorAction(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].modelIndex < 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].modelIndex = 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].modelIndex >= 3) { + debrisParticles[i].modelIndex = (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 (Cutscene_CheckActorAction(globalCtx, 451)) { + if (Cutscene_CheckActorAction(globalCtx, 451) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 451)]->action == 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 (Cutscene_CheckActorAction(globalCtx, 450) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 450)]->action == 5) { + if (!(this->flags & FLAG_FIRE_RING_APPEARS)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_DM_RING_EXPLOSION); + } + this->flags |= FLAG_FIRE_RING_APPEARS; + } + if (this->flags & FLAG_FIRE_RING_APPEARS) { + this->fireRingAlpha += 1 / 30.0f; + 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; + } + } +} + +/** + * Used for all closed-mouth high-detail moons, including + * StoppedClosedMouthMoon and CrashingMoon. + */ +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_MultVec3f(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++, gMoonDL); + + 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++, gOpenMouthMoonDL); + + 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++, gLodmoonEyesDL); + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); + gSPDisplayList(POLY_OPA_DISP++, gLodmoonMoonDL); + 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_Translate(translation.x, translation.y, translation.z, MTXMODE_NEW); + Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); + Matrix_RotateYS(thisx->shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(thisx->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(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); + + // For the 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)); + + // For the "flecks" of fire around the fireball + 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++, gMoonFireballDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_RisingDebris_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* sDebrisModelDLists[] = { gMoonDebrisModel1DL, gMoonDebrisModel2DL, gMoonDebrisModel3DL }; + 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++, gMoonDebrisMaterialDL); + 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].modelIndex < 3) { + Matrix_Translate(debrisParticles[i].pos.x, debrisParticles[i].pos.y, debrisParticles[i].pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_RotateZYX(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++, sDebrisModelDLists[debrisParticles[i].modelIndex]); + } + } + + 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(gMoonFireRingTexAnim)); + 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++, gMoonFireRingDL); + + 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(gFallingMoonsTearTexAnim)); + 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++, gFallingMoonsTearDL); + + 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++, gFallingMoonsTearFireDL); + + 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..620c0590a 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,51 @@ #include "global.h" +#define EN_FALL_SCALE(thisx) ((thisx)->params & 0x7F) +#define EN_FALL_TYPE(thisx) (((thisx)->params & 0xF80) >> 7) + +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_Fall2/z_en_fall2.c b/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c index 48514fd82..46c365cd3 100644 --- a/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c +++ b/src/overlays/actors/ovl_En_Fall2/z_en_fall2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_fall2.c + * Overlay: ovl_En_Fall2 + * Description: "Warp Beam" from Moon's Mouth in Cutscene? + */ + #include "z_en_fall2.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnFall2*)thisx) diff --git a/src/overlays/actors/ovl_En_Famos/z_en_famos.c b/src/overlays/actors/ovl_En_Famos/z_en_famos.c index 6636923a4..42ff95aba 100644 --- a/src/overlays/actors/ovl_En_Famos/z_en_famos.c +++ b/src/overlays/actors/ovl_En_Famos/z_en_famos.c @@ -1,6 +1,14 @@ -#include "z_en_famos.h" +/* + * File: z_en_famos.c + * Overlay: ovl_En_Famos + * Description: Death Armos (floating statue enemy in Inverted Stone Tower Temple) + */ -#define FLAGS 0x00000005 +#include "z_en_famos.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnFamos*)thisx) @@ -9,7 +17,39 @@ void EnFamos_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFamos_Update(Actor* thisx, GlobalContext* globalCtx); void EnFamos_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnFamos_SetupAttackDebris(EnFamos* this); +void EnFamos_SetupDeathDebris(EnFamos* this); +s32 EnFamos_IsPlayerSeen(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupStillIdle(EnFamos* this); +void EnFamos_StillIdle(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupPathingIdle(EnFamos* this); +void EnFamos_PathingIdle(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupTurnHome(EnFamos* this); +void EnFamos_TurnHome(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupReturnHome(EnFamos* this); +void EnFamos_ReturnHome(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupAlert(EnFamos* this); +void EnFamos_Alert(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupChase(EnFamos* this); +void EnFamos_Chase(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupAttackAim(EnFamos* this); +void EnFamos_AttackAim(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupAttack(EnFamos* this); +void EnFamos_Attack(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupFinishAttack(EnFamos* this); +void EnFamos_FinishAttack(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupAttackRebound(EnFamos* this); +void EnFamos_AttackRebound(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupScanForPlayer(EnFamos* this); +void EnFamos_ScanForPlayer(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupDeathSlam(EnFamos* this); +void EnFamos_DeathSlam(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupDeathExplosion(EnFamos* this); +void EnFamos_DeathExplosion(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_SetupDeathFade(EnFamos* this); +void EnFamos_DeathFade(EnFamos* this, GlobalContext* globalCtx); +void EnFamos_DrawDebris(EnFamos* this, GlobalContext* globalCtx); + const ActorInit En_Famos_InitVars = { ACTOR_EN_FAMOS, ACTORCAT_ENEMY, @@ -22,133 +62,810 @@ const ActorInit En_Famos_InitVars = { (ActorFunc)EnFamos_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808AE600 = { - { COLTYPE_METAL, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x20000000, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_METAL, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x20000000, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 80, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808AE62C = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 70, 10, 0, { 0, 0, 0 } }, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_808AE658[2] = { +// the emblem at the from and the back is one limb running front to back through the torso +// this is both sides of the emblem, front and back +static ColliderJntSphElementInit sJntSphElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00002000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { 2, { { 2500, 0, 0 }, 20 }, 100 }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00002000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { FAMOS_LIMB_EMBLEM, { { 2500, 0, 0 }, 20 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00002000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { 2, { { -1500, 0, 0 }, 20 }, 100 }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00002000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { FAMOS_LIMB_EMBLEM, { { -1500, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808AE6A0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_808AE658, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808AE6B8[] = { +typedef enum { + /* 0 */ FAMOS_ANIMATED_MAT_NORMAL, // normal is greenish + /* 1 */ FAMOS_ANIMATED_MAT_FLIPPED // flipped is orange/yellowish +} FamosAnimatedMatArrayIndexes; + +static AnimatedMaterial* sEmblemAnimatedMats[] = { + gFamosNormalGlowingEmblemTexAnim, + gFamosFlippedGlowingEmblemTexAnim, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 15, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 3500, ICHAIN_STOP), }; -#endif +static s32 sAnimatedMaterialsDesgmented = false; -extern ColliderCylinderInit D_808AE600; -extern ColliderCylinderInit D_808AE62C; -extern ColliderJntSphElementInit D_808AE658[2]; -extern ColliderJntSphInit D_808AE6A0; -extern InitChainEntry D_808AE6B8[]; +void EnFamos_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFamos* this = THIS; + Path* path; + s32 i; -extern UNK_TYPE D_060000F8; -extern UNK_TYPE D_06003DC8; + Actor_ProcessInitChain(&this->actor, sInitChain); + if (GET_FAMOS_PATH(thisx) != 0xFF) { + path = &globalCtx->setupPathList[this->actor.params]; + this->pathPoints = Lib_SegmentedToVirtual(path->points); + this->pathNodeCount = path->count; + if (this->pathNodeCount == 1) { + this->pathPoints = NULL; + this->pathNodeCount = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/EnFamos_Init.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawSquare, 30.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gFamosSkeleton, &gFamosIdleAnim, this->jointTable, this->morphTable, + FAMOS_LIMB_MAX); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); + Collider_InitAndSetJntSph(globalCtx, &this->emblemCollider, &this->actor, &sJntSphInit, + this->emblemColliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/EnFamos_Destroy.s") + if (!sAnimatedMaterialsDesgmented) { // init animated materials + for (i = 0; i < ARRAY_COUNT(sEmblemAnimatedMats); i++) { + sEmblemAnimatedMats[i] = Lib_SegmentedToVirtual(sEmblemAnimatedMats[i]); + } + sAnimatedMaterialsDesgmented = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ACB58.s") + this->actor.colChkInfo.mass = 250; + this->baseHeight = this->actor.world.pos.y; + // params: [this->actor.shape.rot.x] is used to set aggro distance + this->aggroDistance = (GET_FAMOS_AGGRO_DISTANCE(thisx) <= 0) ? (200.0f) : (this->actor.shape.rot.x * 40.0f * 0.1f); + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = 0; + this->hasFinishedRotating = true; + this->isCalm = true; + if (this->pathPoints != NULL) { + EnFamos_SetupPathingIdle(this); + } else { + EnFamos_SetupStillIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ACD2C.s") +void EnFamos_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFamos* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ACF1C.s") + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); + Collider_DestroyJntSph(globalCtx, &this->emblemCollider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ACF98.s") +/** + * Sets 20 rocks to draw from an explosion on the ground (slam attack). + */ +void EnFamos_SetupAttackDebris(EnFamos* this) { + EnFamosRock* rock; + f32 randFloat; + s16 randOffset; + s16 randVelDirection; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD05C.s") + this->debrisTimer = 40; + rock = &this->rocks[0]; + for (i = 0; i < ARRAY_COUNT(this->rocks); i++, rock++) { + randVelDirection = Rand_Next() >> 0x10; + randOffset = Rand_S16Offset(0x1800, 0x2800); + randFloat = Rand_ZeroFloat(5.0f) + 5.0f; + rock->velocity.x = randFloat * Math_CosS(randOffset) * Math_SinS(randVelDirection); + rock->velocity.y = Math_SinS(randOffset) * randFloat + 3.0f; + rock->velocity.z = randFloat * Math_CosS(randOffset) * Math_CosS(randVelDirection); + rock->rotation.x = Rand_Next() >> 0x10; + rock->rotation.y = Rand_Next() >> 0x10; + rock->rotation.z = Rand_Next() >> 0x10; + rock->pos.x = (Math_SinS(randVelDirection) * 20.0f) + this->actor.world.pos.x; + rock->pos.y = this->actor.floorHeight; + rock->pos.z = (Math_CosS(randVelDirection) * 20.0f) + this->actor.world.pos.z; + rock->scale = Rand_ZeroFloat(0.0015f) + (2.0f * 0.001f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD170.s") +/** + * Sets 20 rocks to draw from an explosion on death. + */ +void EnFamos_SetupDeathDebris(EnFamos* this) { + f32 randFloat; + s16 randSmaller; + s16 randVelDirection; + EnFamosRock* rock; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD18C.s") + this->debrisTimer = 40; + rock = &this->rocks[0]; + for (i = 0; i < ARRAY_COUNT(this->rocks); i++, rock++) { + randVelDirection = Rand_Next() >> 0x10; + randSmaller = (u32)Rand_Next() >> 0x12; + randFloat = Rand_ZeroFloat(6.0f) + 7.0f; + rock->velocity.x = randFloat * Math_CosS(randSmaller) * Math_SinS(randVelDirection); + rock->velocity.y = Math_SinS(randSmaller) * randFloat + 4.5f; + rock->velocity.z = randFloat * Math_CosS(randSmaller) * Math_CosS(randVelDirection); + rock->rotation.x = Rand_Next() >> 0x10; + rock->rotation.y = Rand_Next() >> 0x10; + rock->rotation.z = Rand_Next() >> 0x10; + rock->pos.x = Math_SinS(randVelDirection) * 20.0f + this->actor.world.pos.x; + rock->pos.y = randPlusMinusPoint5Scaled(60.0f) + (this->actor.world.pos.y + 40.0f); + rock->pos.z = Math_CosS(randVelDirection) * 20.0f + this->actor.world.pos.z; + rock->scale = Rand_ZeroFloat(0.002f) + (2.5f * 0.001f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD1F0.s") +s32 EnFamos_IsPlayerSeen(EnFamos* this, GlobalContext* globalCtx) { + if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && + (Actor_XZDistanceToPoint(&GET_PLAYER(globalCtx)->actor, &this->calmPos) < this->aggroDistance) && + Actor_IsFacingPlayer(&this->actor, 0x5000)) { + return true; + } else { + return false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD294.s") +void EnFamos_UpdateBobbingHeight(EnFamos* this) { + if (this->hoverTimer == 0) { + this->hoverTimer = 30; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD31C.s") + this->hoverTimer--; + this->actor.world.pos.y = (Math_SinS(this->hoverTimer * 0x888) * 10.0f) + this->baseHeight; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD378.s") + if (ABS_ALT(this->flipRot) > 0x4000) { // is famos upside down + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT_REVERSE - SFX_FLAG); + } else { + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD3E8.s") +/** + * Checks if emblem has been hit with light arrow. + * Also checks if previously flipped; handles flip status. + */ +void EnFamos_UpdateFlipStatus(EnFamos* this) { + u8 hasFinishedRotating; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD42C.s") + if (this->emblemCollider.base.acFlags & AC_HIT) { // light arrow collision, flip + this->emblemCollider.base.acFlags &= ~AC_HIT; + if (this->hasFinishedRotating == true) { + if (this->animatedMaterialIndex != FAMOS_ANIMATED_MAT_NORMAL) { + this->animatedMaterialIndex = FAMOS_ANIMATED_MAT_NORMAL; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FAMOS_REVERSE2); + } else { + this->animatedMaterialIndex = FAMOS_ANIMATED_MAT_FLIPPED; + this->flippedTimer = 100; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FAMOS_REVERSE1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_DAMAGE); + } + this->hasFinishedRotating = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD54C.s") + } else if (this->flippedTimer > 0) { + this->flippedTimer--; + if (this->flippedTimer == 0) { + if (this->animatedMaterialIndex != FAMOS_ANIMATED_MAT_NORMAL) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FAMOS_REVERSE2); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD5B0.s") + this->animatedMaterialIndex = FAMOS_ANIMATED_MAT_NORMAL; + this->hasFinishedRotating = false; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD66C.s") + if (this->hasFinishedRotating == false) { + if (this->animatedMaterialIndex != FAMOS_ANIMATED_MAT_NORMAL) { + hasFinishedRotating = Math_ScaledStepToS(&this->flipRot, -0x8000, 0x1000); + } else { + hasFinishedRotating = Math_ScaledStepToS(&this->flipRot, 0, 0x1000); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD68C.s") + this->hasFinishedRotating = hasFinishedRotating; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD7EC.s") +/** + * If Famos path is 0xFF, famos hovers stationary in the air + * facing forward, only bobbing up and down, without a path to follow. + */ +void EnFamos_SetupStillIdle(EnFamos* this) { + this->actionFunc = EnFamos_StillIdle; + this->actor.speedXZ = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD840.s") +void EnFamos_StillIdle(EnFamos* this, GlobalContext* globalCtx) { + EnFamos_UpdateBobbingHeight(this); + if (this->isCalm) { + Math_Vec3f_Copy(&this->calmPos, &this->actor.world.pos); + } + if (EnFamos_IsPlayerSeen(this, globalCtx)) { + EnFamos_SetupAlert(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD888.s") +/** + * Regular Famos follows a path until seeing the player. + */ +void EnFamos_SetupPathingIdle(EnFamos* this) { + if (this->isCalm) { + this->currentPathNode++; + if (this->currentPathNode == this->pathNodeCount) { + this->currentPathNode = 0; + } + } else { + this->isCalm = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AD8B8.s") + Math_Vec3s_ToVec3f(&this->targetDest, &this->pathPoints[this->currentPathNode]); + this->targetYaw = Actor_YawToPoint(&this->actor, &this->targetDest); + this->actionFunc = EnFamos_PathingIdle; + this->actor.speedXZ = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADA74.s") +void EnFamos_PathingIdle(EnFamos* this, GlobalContext* globalCtx) { + EnFamos_UpdateBobbingHeight(this); + if (this->isCalm) { + Math_Vec3f_Copy(&this->calmPos, &this->actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADAE8.s") + if (EnFamos_IsPlayerSeen(this, globalCtx)) { + EnFamos_SetupAlert(this); + } else if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->targetYaw, 0x200)) { + EnFamos_SetupReturnHome(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADB4C.s") +/** + * Famos lost player; Turning to face back toward home. + */ +void EnFamos_SetupTurnHome(EnFamos* this) { + this->targetYaw = Actor_YawToPoint(&this->actor, &this->calmPos); + Math_Vec3f_Copy(&this->targetDest, &this->calmPos); + this->actionFunc = EnFamos_TurnHome; + this->actor.speedXZ = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADB70.s") +void EnFamos_TurnHome(EnFamos* this, GlobalContext* globalCtx) { + EnFamos_UpdateBobbingHeight(this); + if (EnFamos_IsPlayerSeen(this, globalCtx)) { + EnFamos_SetupAlert(this); + } else if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->targetYaw, 0x200)) { + EnFamos_SetupReturnHome(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADC40.s") +/** + * Famos has finished rotating toward home; Take off flying in straight line. + */ +void EnFamos_SetupReturnHome(EnFamos* this) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.x = -Actor_PitchToPoint(&this->actor, &this->targetDest); + this->actionFunc = EnFamos_ReturnHome; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADC64.s") +void EnFamos_ReturnHome(EnFamos* this, GlobalContext* globalCtx) { + f32 distanceToHome = Actor_XZDistanceToPoint(&this->actor, &this->targetDest); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADD20.s") + this->actor.shape.rot.y = Actor_YawToPoint(&this->actor, &this->targetDest); + this->actor.world.rot.y = this->actor.shape.rot.y; + EnFamos_UpdateBobbingHeight(this); + if (this->isCalm) { + Math_Vec3f_Copy(&this->calmPos, &this->actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADDA8.s") + if (EnFamos_IsPlayerSeen(this, globalCtx)) { + EnFamos_SetupAlert(this); + } else if (distanceToHome < 20.0f) { + if (this->pathPoints != NULL) { + EnFamos_SetupPathingIdle(this); + } else { + EnFamos_SetupStillIdle(this); + } + } else if (distanceToHome < 40.0f) { + Math_StepToF(&this->actor.speedXZ, 0.5f, 0.3f); + } else { + Math_StepToF(&this->actor.speedXZ, 3.0f, 0.3f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADE00.s") +/** + * Famos has spotted the player; delayed by surprise. + */ +void EnFamos_SetupAlert(EnFamos* this) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->stateTimer = 8; + this->actor.speedXZ = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADE74.s") + if (this->isCalm == true) { + this->isCalm = false; + Math_Vec3f_Copy(&this->calmPos, &this->actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADFA4.s") + this->actionFunc = EnFamos_Alert; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808ADFF0.s") +void EnFamos_Alert(EnFamos* this, GlobalContext* globalCtx) { + if (ABS_ALT(this->flipRot) > 0x4000) { + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT_REVERSE - SFX_FLAG); + } else { + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT - SFX_FLAG); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AE030.s") + this->stateTimer--; + if (this->stateTimer == 0) { + this->actor.world.pos.y = this->baseHeight; + EnFamos_SetupChase(this); + } else { + this->actor.world.pos.y = Math_SinS(this->stateTimer * 0x1000) * 30.0f + this->baseHeight; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/EnFamos_Update.s") +/** + * Famos has spotted the player; Begin chasing to attack. + */ +void EnFamos_SetupChase(EnFamos* this) { + this->hoverTimer = 0; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnFamos_Chase; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AE304.s") +void EnFamos_Chase(EnFamos* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f abovePlayerPos; + u32 surfaceType; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AE3A8.s") + EnFamos_UpdateBobbingHeight(this); + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x800); + this->actor.world.rot.y = this->actor.shape.rot.y; + abovePlayerPos.x = player->actor.world.pos.x; + abovePlayerPos.y = player->actor.world.pos.y + 100.0f; + abovePlayerPos.z = player->actor.world.pos.z; + this->actor.world.rot.x = -Actor_PitchToPoint(&this->actor, &abovePlayerPos); + Math_StepToF(&this->actor.speedXZ, 6.0f, 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/func_808AE3FC.s") + surfaceType = func_800C9B18(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + if ((this->actor.xzDistToPlayer < 30.0f) && (this->actor.floorHeight > BGCHECK_Y_MIN) && // close enough + (surfaceType != 0xC && surfaceType != 0xD)) { + EnFamos_SetupAttackAim(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Famos/EnFamos_Draw.s") + } else if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || + (this->aggroDistance < Actor_XZDistanceToPoint(&GET_PLAYER(globalCtx)->actor, &this->calmPos)) || + !Actor_IsFacingPlayer(&this->actor, 0x6000)) { + EnFamos_SetupScanForPlayer(this); + } +} + +void EnFamos_SetupAttackAim(EnFamos* this) { + Animation_PlayOnce(&this->skelAnime, &gFamosShakeAnim); + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AMOS_VOICE); + this->actionFunc = EnFamos_AttackAim; +} + +void EnFamos_AttackAim(EnFamos* this, GlobalContext* globalCtx) { + func_800B9010(&this->actor, NA_SE_EN_LAST1_FALL_OLD - SFX_FLAG); + if (SkelAnime_Update(&this->skelAnime)) { + EnFamos_SetupAttack(this); + } +} + +void EnFamos_SetupAttack(EnFamos* this) { + this->actor.world.rot.x = -0x4000; + this->collider1.base.atFlags |= AT_ON; + this->stateTimer = 4; + this->actionFunc = EnFamos_Attack; +} + +void EnFamos_Attack(EnFamos* this, GlobalContext* globalCtx) { + s32 hitFloor; + u32 surfaceType; + + Math_StepToF(&this->actor.speedXZ, 20.0f, 2.0f); + this->stateTimer--; + if (this->stateTimer == 0) { + this->emblemCollider.base.acFlags &= ~AC_ON; + } + + surfaceType = func_800C9B18(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + hitFloor = this->actor.bgCheckFlags & 1; + if (hitFloor || (this->actor.floorHeight == BGCHECK_Y_MIN) || (surfaceType == 0xC) || (surfaceType == 0xD)) { + this->collider1.base.atFlags &= ~AT_ON; + this->collider2.base.atFlags |= AT_ON; + if (hitFloor) { + func_800DFD04(globalCtx->cameraPtrs[globalCtx->activeCamera], 2, 15, 10); // camera shake? + func_8013ECE0(this->actor.xyzDistToPlayerSq, 180, 20, 100); + EnFamos_SetupAttackDebris(this); + + // spawn crator on floor + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TEST, this->actor.world.pos.x, + this->actor.floorHeight, this->actor.world.pos.z, 0, 0, 0, 0x0); + + if (this->actor.child != NULL) { + Actor_SetScale(this->actor.child, 0.015f); + } + + if (this->animatedMaterialIndex != FAMOS_ANIMATED_MAT_NORMAL) { + this->cratorDespawnTimer = 70; + EnFamos_SetupDeathSlam(this); + } else { + this->cratorDespawnTimer = 20; + EnFamos_SetupFinishAttack(this); + } + } else { + this->emblemCollider.base.acFlags |= AC_ON; + EnFamos_SetupAttackRebound(this); + } + } else { + func_800B9010(&this->actor, NA_SE_EN_LAST1_FALL_OLD - SFX_FLAG); + } +} + +/** + * Attack has hit; Wait for animation to finish before recovering from attack. + */ +void EnFamos_SetupFinishAttack(EnFamos* this) { + Animation_PlayOnce(&this->skelAnime, &gFamosIdleAnim); + SkelAnime_Update(&this->skelAnime); + this->emblemCollider.base.acFlags |= AC_ON; + this->stateTimer = 3; + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_EXPLOSION); + this->actionFunc = EnFamos_FinishAttack; +} + +void EnFamos_FinishAttack(EnFamos* this, GlobalContext* globalCtx) { + if (this->stateTimer == 0) { + this->collider2.base.atFlags &= ~AT_ON; + } + + this->stateTimer--; + if (SkelAnime_Update(&this->skelAnime)) { + EnFamos_SetupAttackRebound(this); + } +} + +void EnFamos_SetupAttackRebound(EnFamos* this) { + this->actor.world.rot.x = 0x4000; + this->actionFunc = EnFamos_AttackRebound; + this->actor.speedXZ = 0.0f; +} + +void EnFamos_AttackRebound(EnFamos* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 5.0f, 0.3f); + if (this->actor.speedXZ > 1.0f) { + if (ABS_ALT(this->flipRot) > 0x4000) { + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT_REVERSE - SFX_FLAG); + } else { + func_800B9010(&this->actor, NA_SE_EN_FAMOS_FLOAT - SFX_FLAG); + } + } + + if ((this->baseHeight < this->actor.world.pos.y) || (this->actor.bgCheckFlags & 0x10)) { // touching ceiling + this->actor.speedXZ = 0.0f; + EnFamos_SetupChase(this); + } +} + +/** + * Looking around for player. + */ +void EnFamos_SetupScanForPlayer(EnFamos* this) { + this->stateTimer = 60; + this->actionFunc = EnFamos_ScanForPlayer; + this->actor.speedXZ = 0.0f; +} + +void EnFamos_ScanForPlayer(EnFamos* this, GlobalContext* globalCtx) { + EnFamos_UpdateBobbingHeight(this); + this->stateTimer--; + + if (EnFamos_IsPlayerSeen(this, globalCtx)) { + EnFamos_SetupAlert(this); + } else if (this->stateTimer == 0) { + EnFamos_SetupTurnHome(this); + } else { + this->actor.shape.rot.y = (s32)(Math_SinS(this->stateTimer * 0x888) * 8192.0f) + this->actor.world.rot.y; + } +} + +/** + * Famos was upside down and hit the ground headfirst. This kills the Famos. + */ +void EnFamos_SetupDeathSlam(EnFamos* this) { + this->emblemCollider.base.acFlags &= ~AC_ON; + this->stateTimer = 20; + this->actor.speedXZ = 0.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->flippedTimer = -1; + this->actor.world.pos.y = this->actor.floorHeight - 60.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_DEAD); + this->actionFunc = EnFamos_DeathSlam; +} + +void EnFamos_DeathSlam(EnFamos* this, GlobalContext* globalCtx) { + if (this->stateTimer == 17) { + this->collider2.base.atFlags &= ~AT_ON; + } + + if (this->stateTimer == 0) { + EnFamos_SetupDeathExplosion(this); + } else { + this->stateTimer--; + } +} + +void EnFamos_SetupDeathExplosion(EnFamos* this) { + this->actor.world.rot.x = 0x4000; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, false, 4); + this->stateTimer = 25; + Math_Vec3f_Copy(&this->targetDest, &this->actor.world.pos); + this->actor.flags |= ACTOR_FLAG_10; + this->actionFunc = EnFamos_DeathExplosion; +} + +void EnFamos_DeathExplosion(EnFamos* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 3.0f, 0.3f); + if (this->actor.colorFilterTimer == 0) { + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, false, 4); + } + + this->actor.world.pos.x = randPlusMinusPoint5Scaled(5.0f) + this->targetDest.x; + this->actor.world.pos.z = randPlusMinusPoint5Scaled(5.0f) + this->targetDest.z; + if (this->stateTimer == 1) { + EnBom* explosion = + (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x, + this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, ENBOM_0); + if (explosion != NULL) { + explosion->timer = 0; // instant explosion + } + this->stateTimer--; + + } else if (this->stateTimer == 0) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, + (0xD << 4)); // random item from droptable 0xD + EnFamos_SetupDeathFade(this); + + } else { + this->stateTimer--; + } +} + +void EnFamos_SetupDeathFade(EnFamos* this) { + EnFamos_SetupDeathDebris(this); + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.shape.shadowDraw = NULL; + this->actionFunc = EnFamos_DeathFade; + this->actor.speedXZ = 0.0f; +} + +void EnFamos_DeathFade(EnFamos* this, GlobalContext* globalCtx) { + Actor* enBom; + + if (this->debrisTimer == 0) { + enBom = this->actor.child; + if (enBom != NULL) { + enBom->parent = NULL; + } + Actor_MarkForDeath(&this->actor); + } +} + +void EnFamos_UpdateDebrisPosRot(EnFamos* this) { + EnFamosRock* rock; + s32 i; + + rock = &this->rocks[0]; + for (i = 0; i < ARRAY_COUNT(this->rocks); i++, rock++) { + rock->velocity.y -= 1.0f; + Math_Vec3f_Sum(&rock->pos, &rock->velocity, &rock->pos); + // all casts seem required + rock->rotation.x += (s16)(((u32)Rand_Next() >> 0x17) + 0x700); + rock->rotation.y += (s16)(((u32)Rand_Next() >> 0x17) + 0x900); + rock->rotation.z += (s16)(((u32)Rand_Next() >> 0x17) + 0xB00); + } +} + +void EnFamos_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFamos* this = THIS; + f32 oldHeight; + s32 oldHoverTimer; // save old value to test if changed + + if (this->debrisTimer <= 0 || + (this->debrisTimer--, EnFamos_UpdateDebrisPosRot(this), (this->actionFunc != EnFamos_DeathFade))) { + oldHoverTimer = this->hoverTimer; + EnFamos_UpdateFlipStatus(this); + if (this->cratorDespawnTimer > 0) { + this->cratorDespawnTimer--; + if (this->cratorDespawnTimer == 0) { + this->actor.child->parent = NULL; // child is EnTest (Crator after stomp) + } + } + + this->actionFunc(this, globalCtx); + oldHeight = this->actor.world.pos.y; + Actor_MoveWithoutGravity(&this->actor); + if (oldHoverTimer != this->hoverTimer) { // test if updated in actionFunc + this->baseHeight += this->actor.world.pos.y - oldHeight; + } + + if (this->flippedTimer >= 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 35.0f, 30.0f, 80.0f, 0x1F); + if ((this->actionFunc == EnFamos_Attack) && (this->animatedMaterialIndex != FAMOS_ANIMATED_MAT_NORMAL) && + (this->actor.bgCheckFlags & 1)) { // touch floor + this->actor.world.pos.y -= 60.0f; + } + } + + this->actor.focus.rot.y = this->actor.shape.rot.y; + Collider_UpdateCylinder(&this->actor, &this->collider1); + if (this->collider1.base.atFlags & AT_ON) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + if (this->emblemCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->emblemCollider.base); + } + + if (this->collider2.base.atFlags & AC_ON) { + Collider_UpdateCylinder(&this->actor, &this->collider2); + this->collider2.dim.pos.y = this->actor.floorHeight; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + } +} + +s32 EnFamos_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnFamos* this = THIS; + + if (limbIndex == FAMOS_LIMB_BODY) { + Matrix_Translate(0.0f, 4000.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->flipRot, MTXMODE_APPLY); + Matrix_Translate(0.0f, -4000.0f, 0.0f, MTXMODE_APPLY); + + } else if (this->flippedTimer < 0) { // if set to -1, famos is dying + if ((limbIndex == FAMOS_LIMB_SWORD) || (limbIndex == FAMOS_LIMB_SHIELD) || (limbIndex == FAMOS_LIMB_HEAD)) { + *dList = NULL; + } + } + + return false; +} + +void EnFamos_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFamos* this = THIS; + + if (limbIndex == FAMOS_LIMB_EMBLEM) { + Matrix_MultZero(&this->actor.focus.pos); + Collider_UpdateSpheres(limbIndex, &this->emblemCollider); + } +} + +void EnFamos_DrawDebris(EnFamos* this, GlobalContext* globalCtx) { + s32 i; + + if (this->debrisTimer > 0) { + Gfx* dispOpa; + EnFamosRock* rock; + + OPEN_DISPS(globalCtx->state.gfxCtx); + dispOpa = POLY_OPA_DISP; + + gSPDisplayList(&dispOpa[0], &sSetupDL[6 * 0x19]); + + gDPSetPrimColor(&dispOpa[1], 0, 0x80, 255, 255, 255, 255); + + gDPSetEnvColor(&dispOpa[2], 255, 255, 255, 255); + + rock = &this->rocks[0]; + for (i = 0; i < ARRAY_COUNT(this->rocks); i++, rock++) { + + Matrix_SetTranslateRotateYXZ(rock->pos.x, rock->pos.y, rock->pos.z, &rock->rotation); + Matrix_Scale(rock->scale, rock->scale, rock->scale, MTXMODE_APPLY); + + gSPMatrix(&dispOpa[3 + i * 2], Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(&dispOpa[4 + i * 2], &gameplay_keep_DL_06AB30); // greenish brown rock DL + } + + POLY_OPA_DISP = &dispOpa[3 + (ARRAY_COUNT(this->rocks) * 2)]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnFamos_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFamos* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->actionFunc != EnFamos_DeathFade) { + AnimatedMat_Draw(globalCtx, sEmblemAnimatedMats[this->animatedMaterialIndex]); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnFamos_OverrideLimbDraw, + EnFamos_PostLimbDraw, &this->actor); + if (this->actor.colorFilterTimer != 0) { + func_800AE5A0(globalCtx); + } + } + EnFamos_DrawDebris(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Famos/z_en_famos.h b/src/overlays/actors/ovl_En_Famos/z_en_famos.h index c38e87e7d..a3db181e6 100644 --- a/src/overlays/actors/ovl_En_Famos/z_en_famos.h +++ b/src/overlays/actors/ovl_En_Famos/z_en_famos.h @@ -2,18 +2,58 @@ #define Z_EN_FAMOS_H #include "global.h" +#include "objects/object_famos/object_famos.h" struct EnFamos; typedef void (*EnFamosActionFunc)(struct EnFamos*, GlobalContext*); +typedef struct EnFamosRock { + /* 00 */ Vec3f pos; + /* 0C */ Vec3f velocity; + /* 18 */ Vec3s rotation; + /* 20 */ f32 scale; +} EnFamosRock; // size = 0x24 + +#define GET_FAMOS_PATH(thisx) (thisx->params) +#define GET_FAMOS_AGGRO_DISTANCE(thisx) (thisx->shape.rot.x) + +// stateTimer gets reused: +// after spotting player, counts frames until first attack (8) +// after lost aggro, measures frames looking around before returning to home (60) +// before smash attack, counts frames before disabling emblem colider (4) +// after smash attack collision, counts frames before rising (3) +// after smash attack finish, counts frames rising above ground before next attempt (20) + typedef struct EnFamos { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x8C]; - /* 0x01D0 */ EnFamosActionFunc actionFunc; - /* 0x01D4 */ char unk_1D4[0x440]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[FAMOS_LIMB_MAX]; + /* 0x1AC */ Vec3s morphTable[FAMOS_LIMB_MAX]; + /* 0x1D0 */ EnFamosActionFunc actionFunc; + /* 0x1D4 */ u8 animatedMaterialIndex; + /* 0x1D5 */ u8 hasFinishedRotating; // stable up or down + /* 0x1D6 */ u8 pathNodeCount; + /* 0x1D7 */ u8 currentPathNode; + /* 0x1D8 */ u8 isCalm; // is NOT aware of player + /* 0x1DA */ s16 hoverTimer; // start 30, decr to 0, repeat: for trig height adjustment when hovering + /* 0x1DC */ s16 stateTimer; // reused for different actionFunc + /* 0x1DE */ s16 debrisTimer; // also counts frames until despawning bom after death + /* 0x1E0 */ s16 flippedTimer; // frames until it flips right side up + /* 0x1E2 */ s16 cratorDespawnTimer; + /* 0x1E4 */ s16 targetYaw; + /* 0x1E6 */ s16 flipRot; // is used to detect if the actor has been flipped upside down by light arrows + /* 0x1E8 */ Vec3s* pathPoints; + /* 0x1EC */ f32 baseHeight; // because hover can hit the floor, we need to keep track so famos cannot by adjusted/moved by terain + /* 0x1F0 */ f32 aggroDistance; + /* 0x1F4 */ Vec3f targetDest; + /* 0x200 */ Vec3f calmPos; + // havent figured out what the difference between the colliders are, only one cylinder is visible in KZ + /* 0x20C */ ColliderCylinder collider1; + /* 0x258 */ ColliderCylinder collider2; + /* 0x2A4 */ ColliderJntSph emblemCollider; + /* 0x2C4 */ ColliderJntSphElement emblemColliderElements[2]; + /* 0x344 */ EnFamosRock rocks[20]; } EnFamos; // size = 0x614 -extern const ActorInit En_Famos_InitVars; - #endif // Z_EN_FAMOS_H 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..bd3bd9e29 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.c +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.c @@ -5,8 +5,10 @@ */ #include "z_en_fg.h" +#include "objects/object_fr/object_fr.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00004209 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_200 | ACTOR_FLAG_4000) #define THIS ((EnFg*)thisx) @@ -22,14 +24,6 @@ void EnFg_AddDust(EnFgEffectDust* dustEffect, Vec3f* worldPos); void EnFg_UpdateDust(EnFgEffectDust* dustEffect); void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect); -extern AnimationHeader D_06001534; -extern AnimationHeader D_060011C0; -extern AnimationHeader D_060007BC; -extern Gfx* D_060059A0[]; -extern Gfx* D_0600B328[]; -extern Gfx* D_0600B338[]; -extern FlexSkeletonHeader D_0600B538; - const ActorInit En_Fg_InitVars = { ACTOR_EN_FG, ACTORCAT_NPC, @@ -101,11 +95,11 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06001534, 1.0f, 0, -1, 0, 0 }, - { &D_06001534, 1.0f, 0, -1, 0, -4 }, - { &D_060011C0, 1.0f, 0, -1, 0, -4 }, - { &D_060007BC, 1.0f, 0, -1, 2, -4 }, +static AnimationInfoS sAnimations[] = { + { &object_fr_Anim_001534, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_fr_Anim_001534, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_fr_Anim_0011C0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_fr_Anim_0007BC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, }; s32 EnFg_UpdateAnimation(SkelAnime* skelAnime, s16 animIndex) { @@ -117,11 +111,11 @@ s32 EnFg_UpdateAnimation(SkelAnime* skelAnime, s16 animIndex) { ret = true; frameCount = sAnimations[animIndex].frameCount; if (frameCount < 0) { - frameCount = Animation_GetLastFrame(sAnimations[animIndex].animationSeg); + frameCount = Animation_GetLastFrame(sAnimations[animIndex].animation); } - Animation_Change(skelAnime, sAnimations[animIndex].animationSeg, sAnimations[animIndex].playbackSpeed, - sAnimations[animIndex].frame, frameCount, sAnimations[animIndex].mode, - sAnimations[animIndex].transitionRate); + Animation_Change(skelAnime, sAnimations[animIndex].animation, sAnimations[animIndex].playSpeed, + sAnimations[animIndex].startFrame, frameCount, sAnimations[animIndex].mode, + sAnimations[animIndex].morphFrames); } return ret; } @@ -183,8 +177,8 @@ void EnFg_Idle(EnFg* this, GlobalContext* globalCtx) { switch (EnFg_GetDamageEffect(this)) { case FG_DMGEFFECT_DEKUSTICK: - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_CRY_1); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FROG_CRY_1); this->skelAnime.playSpeed = 0.0f; this->actor.shape.shadowDraw = NULL; this->actor.scale.x *= 1.5f; @@ -196,7 +190,7 @@ void EnFg_Idle(EnFg* this, GlobalContext* globalCtx) { case FG_DMGEFFECT_HOOKSHOT: break; case FG_DMGEFFECT_ARROW: - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->skelAnime.playSpeed = 0.0f; rotY = this->collider.base.ac->world.rot.y; rotX = this->collider.base.ac->world.rot.x; @@ -209,8 +203,8 @@ void EnFg_Idle(EnFg* this, GlobalContext* globalCtx) { this->actionFunc = EnFg_DoNothing; break; case FG_DMGEFFECT_EXPLOSION: - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_CRY_0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FROG_CRY_0); if (1) {} this->actor.params = FG_BLACK; this->skelAnime.playSpeed = 0.0f; @@ -226,14 +220,14 @@ void EnFg_Idle(EnFg* this, GlobalContext* globalCtx) { break; default: if (DECR(this->timer) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FROG_JUMP); EnFg_UpdateAnimation(&this->skelAnime, 3); this->actor.velocity.y = 10.0f; this->timer = Rand_S16Offset(30, 30); this->actionFunc = EnFg_Jump; } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void EnFg_Jump(EnFg* this, GlobalContext* globalCtx) { @@ -244,7 +238,7 @@ void EnFg_Jump(EnFg* this, GlobalContext* globalCtx) { switch (EnFg_GetDamageEffect(this)) { case FG_DMGEFFECT_ARROW: - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->skelAnime.playSpeed = 0.0f; ac = this->collider.base.ac; rotY = ac->world.rot.y; @@ -260,8 +254,8 @@ void EnFg_Jump(EnFg* this, GlobalContext* globalCtx) { case FG_DMGEFFECT_HOOKSHOT: break; case FG_DMGEFFECT_EXPLOSION: - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_CRY_0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FROG_CRY_0); EnFg_UpdateAnimation(&this->skelAnime, 0); this->actor.params = FG_BLACK; this->skelAnime.playSpeed = 0.0f; @@ -286,7 +280,7 @@ void EnFg_Jump(EnFg* this, GlobalContext* globalCtx) { this->actionFunc = EnFg_Idle; this->actor.velocity.y = 0.0f; } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } } } @@ -313,20 +307,21 @@ void EnFg_Knockback(EnFg* this, GlobalContext* globalCtx) { EnFg_AddDust(&this->dustEffect[0], &this->actor.world.pos); } this->actor.shape.rot.x += 0x1000; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } } void EnFg_Init(Actor* thisx, GlobalContext* globalCtx) { EnFg* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600B538, NULL, this->jointTable, this->morphTable, 24); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 10.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_fr_Skel_00B538, NULL, this->jointTable, this->morphTable, + 24); EnFg_UpdateAnimation(&this->skelAnime, 0); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2); - this->actor.flags |= 0x4000; + this->actor.flags |= ACTOR_FLAG_4000; Actor_SetScale(&this->actor, 0.01f); this->actor.gravity = -1.6f; this->actionFunc = EnFg_Idle; @@ -360,8 +355,8 @@ void EnFg_Update(Actor* thisx, GlobalContext* globalCtx) { func_80A2D348(this, globalCtx); } -s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnFg* this = (EnFg*)arg; +s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; if ((limbIndex == 7) || (limbIndex == 8)) { *dList = NULL; @@ -372,26 +367,26 @@ s32 EnFg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, *dList = NULL; } } - return 0; + return false; } -void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnFg* this = (EnFg*)arg; +void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFg* this = THIS; s16 pad; Vec3f vec1 = { 0.0f, 0.0f, 0.0f }; if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePush(); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Push(); + Matrix_ReplaceRotation(&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(); + Matrix_Pop(); CLOSE_DISPS(globalCtx->state.gfxCtx); } if (limbIndex == 4) { - Matrix_MultiplyVector3fByState(&vec1, &this->actor.focus.pos); + Matrix_MultVec3f(&vec1, &this->actor.focus.pos); } } @@ -403,17 +398,17 @@ void EnFg_Draw(Actor* thisx, GlobalContext* globalCtx) { { 120, 130, 230, 255 }, { 190, 190, 190, 255 }, { 0, 0, 0, 255 }, }; - Matrix_StatePush(); + Matrix_Push(); EnFg_DrawDust(globalCtx, &this->dustEffect[0]); - Matrix_StatePop(); + Matrix_Pop(); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); gDPPipeSync(POLY_OPA_DISP++); gDPSetEnvColor(POLY_OPA_DISP++, envColor[this->actor.params].r, envColor[this->actor.params].g, envColor[this->actor.params].b, envColor[this->actor.params].a); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_060059A0)); - gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(&D_060059A0)); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(object_fr_Tex_0059A0)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(object_fr_Tex_0059A0)); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnFg_OverrideLimbDraw, EnFg_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -451,7 +446,7 @@ void EnFg_UpdateDust(EnFgEffectDust* dustEffect) { } TexturePtr sDustTex[] = { - D_0408F7E0, D_0408F3E0, D_0408EFE0, D_0408EBE0, D_0408E7E0, D_0408E3E0, D_0408DFE0, D_0408DBE0, + gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex, }; void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { @@ -467,7 +462,7 @@ void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { if (dustEffect->type) { if (!firstDone) { POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); - gSPDisplayList(POLY_XLU_DISP++, D_0600B328); + gSPDisplayList(POLY_XLU_DISP++, object_fr_DL_00B328); gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 0); firstDone = true; } @@ -476,14 +471,14 @@ void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { alpha = (255.0f / 16.0f) * dustEffect->timer; 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_Translate(dustEffect->pos.x, dustEffect->pos.y, dustEffect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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); index = 0.5f * dustEffect->timer; gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(sDustTex[index])); - gSPDisplayList(POLY_XLU_DISP++, D_0600B338); + gSPDisplayList(POLY_XLU_DISP++, object_fr_DL_00B338); } } CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c b/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c index f4fb5dff8..77909d2ee 100644 --- a/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c +++ b/src/overlays/actors/ovl_En_Fire_Rock/z_en_fire_rock.c @@ -1,6 +1,12 @@ +/* + * File: z_en_fire_rock.c + * Overlay: ovl_En_Fire_Rock + * Description: [Empty] + */ + #include "z_en_fire_rock.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnFireRock*)thisx) diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c index 716c460a8..677edb81a 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.c @@ -6,8 +6,9 @@ #include "z_en_firefly.h" #include "overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.h" +#include "objects/object_firefly/object_firefly.h" -#define FLAGS 0x00005005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000) #define THIS ((EnFirefly*)thisx) @@ -119,21 +120,18 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 4000, ICHAIN_STOP), }; -extern AnimationHeader D_0600017C; -extern SkeletonHeader D_060018B8; -extern Gfx D_06001678[]; - void EnFirefly_Init(Actor* thisx, GlobalContext* globalCtx) { EnFirefly* this = THIS; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_060018B8, &D_0600017C, this->jointTable, this->morphTable, 28); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_firefly_Skel_0018B8, &object_firefly_Anim_00017C, + this->jointTable, this->morphTable, 28); Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); if (this->actor.params & KEESE_INVISIBLE) { - this->actor.flags |= 0x80; + this->actor.flags |= ACTOR_FLAG_80; this->actor.params = KEESE_GET_MAIN_TYPE(thisx); this->isInvisible = true; } @@ -170,10 +168,10 @@ void EnFirefly_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void EnFirefly_SpawnIceEffects(EnFirefly* this, GlobalContext* globalCtx) { - if (this->unk_18F == 0xA) { - this->unk_18F = 0; - this->unk_2E8.x = 0.0f; - func_800BF7CC(globalCtx, &this->actor, &this->unk_2F8, 3, 2, 0.2f, 0.2f); + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, &this->limbPos[0], 3, 2, 0.2f, 0.2f); } } @@ -223,7 +221,7 @@ s32 EnFirefly_ReturnToPerch(EnFirefly* this, GlobalContext* globalCtx) { } s32 EnFirefly_SeekTorch(EnFirefly* this, GlobalContext* globalCtx) { - ObjSyokudai* findTorch = (ObjSyokudai*)globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + ObjSyokudai* findTorch = (ObjSyokudai*)globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; ObjSyokudai* closestTorch = NULL; f32 currentMinDist = 35000.0f; f32 currentDist; @@ -323,7 +321,7 @@ void EnFirefly_FlyIdle(EnFirefly* this, GlobalContext* globalCtx) { } if ((this->timer == 0) && (this->actor.xzDistToPlayer < 200.0f) && - (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { EnFirefly_SetupDiveAttack(this); } } @@ -331,39 +329,39 @@ void EnFirefly_FlyIdle(EnFirefly* this, GlobalContext* globalCtx) { void EnFirefly_SetupFall(EnFirefly* this, GlobalContext* globalCtx) { this->timer = 40; this->actor.velocity.y = 0.0f; - Animation_Change(&this->skelAnime, &D_0600017C, 0.0f, 6.0f, 6.0f, 2, 0.0f); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FFLY_DEAD); - this->actor.flags |= 0x10; + Animation_Change(&this->skelAnime, &object_firefly_Anim_00017C, 0.0f, 6.0f, 6.0f, 2, 0.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_DEAD); + this->actor.flags |= ACTOR_FLAG_10; if (this->isInvisible) { - func_800BCB70(&this->actor, 0x4000, 255, 0x2000, 40); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0x2000, 40); } else { - func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); } if (this->actor.colChkInfo.damageEffect == 3) { - this->unk_18F = 0xA; - this->unk_2E8.x = 1.0f; - this->unk_2E8.y = 0.55f; - this->unk_2E8.z = 0.82500005f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffFrozenSteamScale = 0.82500005f; } else if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_18F = 0x14; - this->unk_2E8.x = 4.0f; - this->unk_2E8.y = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; 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_SMALL_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == 2) { - this->unk_18F = 0; - this->unk_2E8.x = 4.0f; - this->unk_2E8.y = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; } - if (this->unk_2E8.x > 0.0f) { + if (this->drawDmgEffAlpha > 0.0f) { this->auraType = KEESE_AURA_NONE; } - if (this->actor.flags & 0x8000) { + if (this->actor.flags & ACTOR_FLAG_8000) { this->actor.speedXZ = 0.0f; } @@ -375,8 +373,8 @@ void EnFirefly_Fall(EnFirefly* this, GlobalContext* globalCtx) { this->actor.colorFilterTimer = 40; Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); - if (!(this->actor.flags & 0x8000)) { - if (this->unk_18F != 0xA) { + if (!(this->actor.flags & ACTOR_FLAG_8000)) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { Math_ScaledStepToS(&this->actor.shape.rot.x, 0x6800, 0x200); this->actor.shape.rot.y -= 0x300; } @@ -412,7 +410,7 @@ void EnFirefly_Die(EnFirefly* this, GlobalContext* globalCtx) { void EnFirefly_SetupDiveAttack(EnFirefly* this) { this->timer = Rand_S16Offset(70, 100); this->skelAnime.playSpeed = 1.0f; - this->targetPitch = ((this->actor.yDistToPlayer > 0.0f) ? -0xC00 : 0xC00) + 0x1554; + this->targetPitch = ((this->actor.playerHeightRel > 0.0f) ? -0xC00 : 0xC00) + 0x1554; this->actionFunc = EnFirefly_DiveAttack; } @@ -431,7 +429,7 @@ void EnFirefly_DiveAttack(EnFirefly* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 8) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 2, 0xC00, 0x300); Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100); - } else if (Actor_IsActorFacingLink(&this->actor, 0x2800)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x2800)) { if (Animation_OnFrame(&this->skelAnime, 4.0f)) { this->skelAnime.playSpeed = 0.0f; this->skelAnime.curFrame = 4.0f; @@ -462,7 +460,7 @@ void EnFirefly_DiveAttack(EnFirefly* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.x, this->targetPitch, 0x100); } - if ((this->timer == 0) || (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK) || (player->stateFlags2 & 0x80) || + if ((this->timer == 0) || (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (player->stateFlags2 & 0x80) || (player->actor.freezeTimer > 0)) { EnFirefly_SetupFlyAway(this); } @@ -534,9 +532,9 @@ void EnFirefly_FlyAway(EnFirefly* this, GlobalContext* globalCtx) { void EnFirefly_SetupStunned(EnFirefly* this) { if (this->isInvisible) { - func_800BCB70(&this->actor, 0, 255, 0x2000, this->timer); + Actor_SetColorFilter(&this->actor, 0, 255, 0x2000, this->timer); } else { - func_800BCB70(&this->actor, 0, 255, 0, this->timer); + Actor_SetColorFilter(&this->actor, 0, 255, 0, this->timer); } if (this->actionFunc != EnFirefly_Stunned) { @@ -545,7 +543,7 @@ void EnFirefly_SetupStunned(EnFirefly* this) { } this->auraType = KEESE_AURA_NONE; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); this->actionFunc = EnFirefly_Stunned; } @@ -568,8 +566,8 @@ void EnFirefly_Stunned(EnFirefly* this, GlobalContext* globalCtx) { } else { this->actor.colorFilterTimer = 40; - if (this->unk_2E8.x > 0.0f) { - this->unk_2E8.x = 2.0f; + if (this->drawDmgEffAlpha > 0.0f) { + this->drawDmgEffAlpha = 2.0f; } } } @@ -633,21 +631,21 @@ void EnFirefly_DisturbDiveAttack(EnFirefly* this, GlobalContext* globalCtx) { void EnFirefly_UpdateDamage(EnFirefly* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - func_800BE258(&this->actor, &this->collider.info); + Actor_SetDropFlag(&this->actor, &this->collider.info); if (this->actor.colChkInfo.damageEffect == 1) { this->timer = 40; EnFirefly_SetupStunned(this); } else if (this->actor.colChkInfo.damageEffect == 5) { this->timer = 40; - this->unk_18F = 0x1F; - this->unk_2E8.x = 2.0f; - this->unk_2E8.y = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffScale = 0.55f; EnFirefly_SetupStunned(this); } else { Enemy_StartFinishingBlow(globalCtx, &this->actor); this->actor.colChkInfo.health = 0; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; // Negate effects of fire on Fire Keese and Ice on Ice Keese if (((this->currentType == KEESE_FIRE) && (this->actor.colChkInfo.damageEffect == 2)) || @@ -666,7 +664,7 @@ void EnFirefly_Update(Actor* thisx, GlobalContext* globalCtx2) { if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FFLY_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_ATTACK); if (this->currentType != KEESE_NORMAL) { EnFirefly_Extinguish(this); @@ -680,15 +678,15 @@ void EnFirefly_Update(Actor* thisx, GlobalContext* globalCtx2) { EnFirefly_UpdateDamage(this, globalCtx); this->actionFunc(this, globalCtx); - if (!(this->actor.flags & 0x8000)) { + if (!(this->actor.flags & ACTOR_FLAG_8000)) { if ((this->actor.colChkInfo.health == 0) || (this->actionFunc == EnFirefly_Stunned)) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } else { if (this->actionFunc != EnFirefly_Rebound) { this->actor.world.rot.x = 0x1554 - this->actor.shape.rot.x; } - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); } } @@ -706,18 +704,18 @@ void EnFirefly_Update(Actor* thisx, GlobalContext* globalCtx2) { this->actor.world.rot.y = this->actor.shape.rot.y; if (Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FFLY_FLY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FFLY_FLY); } } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (this->unk_2E8.x > 0.0f) { - if (this->unk_18F != 0xA) { - Math_StepToF(&this->unk_2E8.x, 0.0f, 0.05f); - this->unk_2E8.y = (this->unk_2E8.x + 1.0f) * 0.275f; - this->unk_2E8.y = CLAMP_MAX(this->unk_2E8.y, 0.55f); - } else if (!Math_StepToF(&this->unk_2E8.z, 0.55f, 0.01375f)) { + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.01375f)) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } @@ -757,12 +755,12 @@ void EnFirefly_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList EnFirefly* this = THIS; if ((this->currentType != KEESE_FIRE) && (limbIndex == 27)) { - gSPDisplayList((*gfx)++, D_06001678); + gSPDisplayList((*gfx)++, object_firefly_DL_001678); } else if ((this->unk_2F4 != globalCtx->gameplayFrames) && ((this->auraType == KEESE_AURA_FIRE) || (this->auraType == KEESE_AURA_ICE)) && ((limbIndex == 15) || (limbIndex == 21))) { if (this->actionFunc != EnFirefly_Die) { - Matrix_GetStateTranslation(&auraPos); + Matrix_MultZero(&auraPos); auraPos.x += Rand_ZeroFloat(5.0f); auraPos.y += Rand_ZeroFloat(5.0f); auraPos.z += Rand_ZeroFloat(5.0f); @@ -795,11 +793,11 @@ void EnFirefly_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList } if (limbIndex == 15) { - Matrix_GetStateTranslation(&this->unk_2F8); + Matrix_MultZero(&this->limbPos[0]); } else if (limbIndex == 21) { - Matrix_GetStateTranslation(&this->unk_304); + Matrix_MultZero(&this->limbPos[1]); } else if (limbIndex == 10) { - Matrix_GetStateTranslation(&this->unk_310); + Matrix_MultZero(&this->limbPos[2]); } } @@ -816,7 +814,7 @@ void EnFirefly_Draw(Actor* thisx, GlobalContext* globalCtx) { gfx = POLY_OPA_DISP; } - gSPDisplayList(gfx, &sSetupDL[150]); + gSPDisplayList(gfx, &sSetupDL[6 * 25]); if (this->currentType == KEESE_FIRE) { gDPSetEnvColor(&gfx[1], 0, 0, 0, 0); @@ -832,8 +830,9 @@ void EnFirefly_Draw(Actor* thisx, GlobalContext* globalCtx) { POLY_OPA_DISP = gfx; } - func_800BE680(globalCtx, NULL, &this->unk_2F8, 3, this->unk_2E8.y * this->actor.scale.y * 200.0f, this->unk_2E8.z, - this->unk_2E8.x, this->unk_18F); + Actor_DrawDamageEffects(globalCtx, NULL, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale * this->actor.scale.y * 200.0f, this->drawDmgEffFrozenSteamScale, + this->drawDmgEffAlpha, this->drawDmgEffType); this->unk_2F4 = globalCtx->gameplayFrames; CLOSE_DISPS(globalCtx->state.gfxCtx); 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..c8e24aa4f 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h @@ -24,17 +24,17 @@ typedef struct EnFirefly { /* 0x18C */ u8 auraType; /* 0x18D */ u8 currentType; /* 0x18E */ u8 isInvisible; - /* 0x18F */ u8 unk_18F; + /* 0x18F */ u8 drawDmgEffType; /* 0x190 */ s16 timer; /* 0x192 */ s16 targetPitch; /* 0x194 */ Vec3s jointTable[28]; /* 0x23C */ Vec3s morphTable[28]; /* 0x2E4 */ f32 maxAltitude; - /* 0x2E8 */ Vec3f unk_2E8; + /* 0x2E8 */ f32 drawDmgEffAlpha; + /* 0x2E8 */ f32 drawDmgEffScale; + /* 0x2E8 */ f32 drawDmgEffFrozenSteamScale; /* 0x2F4 */ u32 unk_2F4; - /* 0x2F8 */ Vec3f unk_2F8; - /* 0x304 */ Vec3f unk_304; - /* 0x304 */ Vec3f unk_310; + /* 0x2F8 */ Vec3f limbPos[3]; /* 0x31C */ ColliderSphere collider; } EnFirefly; // size = 0x374 diff --git a/src/overlays/actors/ovl_En_Firefly2/z_en_firefly2.c b/src/overlays/actors/ovl_En_Firefly2/z_en_firefly2.c index 9806e5cea..b076e2885 100644 --- a/src/overlays/actors/ovl_En_Firefly2/z_en_firefly2.c +++ b/src/overlays/actors/ovl_En_Firefly2/z_en_firefly2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_firefly2.c + * Overlay: ovl_En_Firefly2 + * Description: [Empty] + */ + #include "z_en_firefly2.h" -#define FLAGS 0x00005015 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000) #define THIS ((EnFirefly2*)thisx) 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 ab615c304..6c9f813fd 100644 --- a/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -1,4 +1,11 @@ +/* + * File: z_en_fish.c + * Overlay: ovl_En_Fish + * Description: Fish + */ + #include "z_en_fish.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -9,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 = { @@ -36,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.actorLists[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 |= ACTOR_FLAG_10; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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.terminalVelocity = 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.terminalVelocity = 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.terminalVelocity = 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.terminalVelocity = 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.terminalVelocity = -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) { + Actor_PlaySfxAtPos(&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.terminalVelocity = -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)) { + Actor_PlaySfxAtPos(&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.terminalVelocity = 0.0f; + this->actor.shape.yOffset = 0.0f; + this->actor.flags |= ACTOR_FLAG_10; + 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.terminalVelocity = -10.0f; + this->actor.shape.yOffset = 0.0f; + if (this->actor.velocity.y < -1.0f) { + this->actor.velocity.y = -1.0f; + } + this->actor.flags |= ACTOR_FLAG_10; + 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.terminalVelocity = 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_MoveWithGravity(&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_SetFocus(&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)) { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 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_MoveWithGravity(&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 a80fe52ce..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,9 +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 unk_144[0x138]; + /* 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 47e9c2efe..bceaa7225 100644 --- a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c +++ b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c @@ -1,6 +1,16 @@ -#include "z_en_fish2.h" +/* + * File: z_en_fish2.c + * Overlay: ovl_En_Fish2 + * Description: Marine Research Lab Fish + */ -#define FLAGS 0x00000019 +#include "overlays/actors/ovl_En_Fish/z_en_fish.h" +#include "overlays/actors/ovl_En_Mushi2/z_en_mushi2.h" +#include "z_en_fish2.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_fb/object_fb.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnFish2*)thisx) @@ -9,7 +19,36 @@ void EnFish2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFish2_Update(Actor* thisx, GlobalContext* globalCtx); void EnFish2_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B28B5C(EnFish2* this); +void func_80B28C14(EnFish2* this, GlobalContext* globalCtx); +void func_80B29128(EnFish2* this); +void func_80B2913C(EnFish2* this, GlobalContext* globalCtx); +void func_80B29194(EnFish2* this); +void func_80B29250(EnFish2* this, GlobalContext* globalCtx); +void func_80B2938C(EnFish2* this); +void func_80B293C4(EnFish2* this, GlobalContext* globalCtx); +void func_80B2951C(EnFish2* this); +void func_80B295A4(EnFish2* this, GlobalContext* globalCtx); +void func_80B29778(EnFish2* this); +void func_80B297FC(EnFish2* this, GlobalContext* globalCtx); +void func_80B29E5C(EnFish2* this, GlobalContext* globalCtx); +void func_80B29EE4(EnFish2* this, GlobalContext* globalCtx); +void func_80B2A01C(EnFish2* this, GlobalContext* globalCtx); +void func_80B2A094(EnFish2* this, GlobalContext* globalCtx); +void func_80B2A23C(EnFish2* this, GlobalContext* globalCtx); +void func_80B2A448(EnFish2* this); +void func_80B2A498(EnFish2* this, GlobalContext* globalCtx); +void func_80B2ADB0(EnFish2* this, Vec3f* vec, s16 arg2); +void func_80B2AF80(EnFish2* this, GlobalContext* globalCtx); +void func_80B2B180(EnFish2* this, GlobalContext* globalCtx); + +static s32 D_80B2B2E0 = 0; +static s32 D_80B2B2E4 = 0; +static s32 D_80B2B2E8 = 0; +static s32 D_80B2B2EC = 0; +static s32 D_80B2B2F0 = 0; +static Actor* D_80B2B2F4 = NULL; + const ActorInit En_Fish2_InitVars = { ACTOR_EN_FISH2, ACTORCAT_PROP, @@ -22,95 +61,1116 @@ const ActorInit En_Fish2_InitVars = { (ActorFunc)EnFish2_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80B2B318[2] = { +static ColliderJntSphElementInit sJntSphElementsInit[2] = { { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 0 }, 1 }, }, { - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 17, { { 0, 0, 0 }, 0 }, 1 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B2B360 = { - { COLTYPE_HARD, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_80B2B318, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HARD, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit, }; -#endif +static f32 D_80B2B370[] = { 0.01f, 0.012f, 0.014f, 0.017f }; +static f32 D_80B2B380[] = { 0.019f, 0.033f }; -extern ColliderJntSphElementInit D_80B2B318[2]; -extern ColliderJntSphInit D_80B2B360; +void func_80B28370(EnFish2* this, s32 arg0) { + static AnimationHeader* D_80B2B388[] = { + &object_fb_Anim_0013AC, &object_fb_Anim_0007D4, &object_fb_Anim_0006D8, + &object_fb_Anim_0006D8, &object_fb_Anim_001174, &object_fb_Anim_000ACC, + }; + static u8 D_80B2B3A0[] = { 0, 0, 2, 2, 2, 2 }; + f32 sp34; -extern UNK_TYPE D_060013AC; + this->unk_2AC = arg0; + this->unk_2CC = Animation_GetLastFrame(&D_80B2B388[arg0]->common); + sp34 = 0.0f; + if (this->unk_2AC == 3) { + sp34 = Animation_GetLastFrame(&D_80B2B388[this->unk_2AC]->common) - 21.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B28370.s") + if (this->unk_2AC == 2) { + this->unk_2CC = Animation_GetLastFrame(&D_80B2B388[this->unk_2AC]->common) - 21.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B28478.s") + Animation_Change(&this->skelAnime, D_80B2B388[this->unk_2AC], 1.0f, sp34, this->unk_2CC, D_80B2B3A0[this->unk_2AC], + -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/EnFish2_Init.s") +s32 func_80B28478(EnFish2* this) { + if (this->unk_2C8 == 0) { + if ((D_80B2B2E4 != 0) && ((D_80B2B2E0 != 1) || (this->unk_350 == NULL) || (this->unk_350->update == NULL)) && + (this->unk_2B0 == 0)) { + this->unk_2B4 = 0; + this->unk_2C4 = 0; + this->unk_2B6 = this->unk_2B4; + func_80B28B5C(this); + return true; + } + } else if ((this->unk_350 == NULL) || (this->unk_350->update == NULL)) { + this->unk_2B4 = 0; + this->unk_2C4 = 0; + this->unk_2B6 = this->unk_2B4; + func_80B28B5C(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/EnFish2_Destroy.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B287F4.s") +void EnFish2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFish2* this = THIS; + s32 i; + s32 cs; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B288E8.s") + Math_Vec3f_Copy(&this->unk_324, &this->actor.home.pos); + this->unk_344 = D_80B2B2F0; + D_80B2B2F0++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2899C.s") + if (this->actor.params == 0) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_fb_Skel_006190, &object_fb_Anim_0013AC, + this->jointTable, this->morphTable, 24); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + if (this->unk_344 == 0) { + if (gSaveContext.save.weekEventReg[81] & 0x10) { + this->unk_2C0 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B289DC.s") + if (gSaveContext.save.weekEventReg[81] & 0x20) { + this->unk_2C0 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B28B5C.s") + if (gSaveContext.save.weekEventReg[81] & 0x40) { + this->unk_2C0 = 3; + } + } else { + if (gSaveContext.save.weekEventReg[81] & 0x80) { + this->unk_2C0 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B28C14.s") + if (gSaveContext.save.weekEventReg[82] & 1) { + this->unk_2C0 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29128.s") + if (gSaveContext.save.weekEventReg[82] & 2) { + this->unk_2C0 = 3; + } + } + cs = this->actor.cutscene; + this->unk_330 = D_80B2B370[this->unk_2C0]; + i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2913C.s") + // clang-format off + while (cs != -1) { this->unk_2BA[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs); i++; } + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29194.s") + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->collider.elements[0].dim.modelSphere.radius = 5; + this->collider.elements[0].dim.scale = 1.0f; + this->collider.elements[0].dim.modelSphere.center.x = 1300; + this->collider.elements[0].dim.modelSphere.center.y = 0; + this->collider.elements[0].dim.modelSphere.center.z = 0; + this->collider.elements[1].dim.modelSphere.radius = 5; + this->collider.elements[1].dim.scale = 1.0f; + this->collider.elements[1].dim.modelSphere.center.x = 500; + this->collider.elements[1].dim.modelSphere.center.y = 0; + this->collider.elements[1].dim.modelSphere.center.z = 0; + this->actor.textId = 0x24C; + func_80B28B5C(this); + } else if (this->actor.params != 0) { + this->unk_2B4 = 10; + this->actor.draw = NULL; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actionFunc = func_80B2A01C; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29250.s") +void EnFish2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFish2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2938C.s") + if (this->actor.params != 1) { + Collider_DestroyJntSph(globalCtx, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B293C4.s") +void func_80B287F4(EnFish2* this, s32 arg1) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2951C.s") + if ((this->unk_354 != 0) && (this->unk_2C8 == 0)) { + if (this->unk_2C4 < 400) { + this->unk_2C4++; + } + this->unk_338 = 440.0f - this->unk_2C4; + if (arg1 == 0) { + this->unk_338 = 410.0f - this->unk_2C4; + } + Math_ApproachF(&this->unk_350->speedXZ, (D_80B2B380[0] - this->unk_330) * this->unk_338, 0.1f, 0.4f); + } + Math_Vec3f_Copy(&sp2C, &this->unk_350->world.pos); + this->unk_34A = Math_Vec3f_Yaw(&this->actor.world.pos, &sp2C); + this->unk_348 = Math_Vec3f_Pitch(&this->actor.world.pos, &sp2C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B295A4.s") +s32 func_80B288E8(EnFish2* this, Vec3f vec, s32 arg2) { + f32 temp_f2 = this->unk_350->world.pos.x - vec.x; + f32 temp_f12 = this->unk_350->world.pos.y - vec.y; + f32 temp_f14 = this->unk_350->world.pos.z - vec.z; + f32 dist = sqrtf(SQ(temp_f2) + SQ(temp_f12) + SQ(temp_f14)); + f32 phi_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29778.s") + if (arg2 == 0) { + phi_f2 = 40.0f; + } else { + phi_f2 = this->unk_330 * 2000.0f; + if (phi_f2 > 20.0f) { + phi_f2 = 20.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B297FC.s") + if (dist < phi_f2) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29E5C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B29EE4.s") +s32 func_80B2899C(EnFish2* this, GlobalContext* globalCtx) { + if (BgCheck_SphVsFirstWall(&globalCtx->colCtx, &this->unk_2F4, this->unk_33C)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2A01C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2A094.s") +void func_80B289DC(EnFish2* this, GlobalContext* globalCtx) { + WaterBox* sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2A23C.s") + if (this->unk_2B4 != 0) { + this->unk_348 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2A448.s") + if (this->unk_348 != 0) { + if (this->unk_348 > 0) { + if (this->unk_2D4 < this->actor.world.pos.y) { + this->actor.velocity.y = this->actor.world.rot.x * 0.001f * -0.1f; + if (this->actionFunc == func_80B297FC) { + this->actor.velocity.y *= 2.0f; + } + } else { + this->unk_348 = 0; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + } + } else if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_334, &sp2C)) { + if ((this->unk_334 != BGCHECK_Y_MIN) && (this->actor.world.pos.y < (this->unk_334 - this->unk_2D8))) { + this->actor.velocity.y = this->actor.world.rot.x * 0.001f * -0.1f; + if (this->actionFunc == func_80B297FC) { + this->actor.velocity.y *= 2.0f; + } + } + } else { + this->unk_348 = 0; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2A498.s") +void func_80B28B5C(EnFish2* this) { + func_80B28370(this, 0); + this->unk_2B4 = 0; + this->unk_348 = 0; + this->unk_2C4 = 0; + this->unk_2C8 = 0; + this->unk_334 = BGCHECK_Y_MIN; + this->unk_2B6 = this->unk_2B4; + this->unk_34C = this->unk_348; + this->unk_34A = this->actor.world.rot.y; + this->collider.elements[1].dim.modelSphere.radius = (s32)((this->unk_330 - 0.01f) * 1000.0f) + 5; + if (this->collider.elements[1].dim.modelSphere.radius > 15) { + this->collider.elements[1].dim.modelSphere.radius = 15; + } + this->actionFunc = func_80B28C14; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/EnFish2_Update.s") +void func_80B28C14(EnFish2* this, GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + WaterBox* waterbox; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2ABF4.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80B29128(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2AC20.s") + if ((this->unk_2B8 == 0) && (fabsf(this->actor.world.rot.y - this->unk_34A) < 100.0f)) { + if (func_80B2899C(this, globalCtx)) { + if (this->unk_340 == 0) { + this->unk_34A += 0x4000; + } else { + this->unk_34A -= 0x4000; + } + this->unk_2B8 = (s32)(this->unk_330 * 1000.0f) - 10; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/EnFish2_Draw.s") + func_80B289DC(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2ADB0.s") + if (this->unk_2B6 == 0) { + if (this->unk_2B4 == 0) { + this->unk_2B4 = (s32)Rand_ZeroFloat(20.0f) + 10; + } else if (this->unk_2B4 == 1) { + if ((this->unk_348 == 0) || (Rand_ZeroOne() < 0.6f)) { + this->unk_348 = randPlusMinusPoint5Scaled(0x2000); + } else { + this->unk_348 = Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_324); + if (this->unk_348 < -0x1000) { + this->unk_348 = -0x1000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2AF80.s") + if (this->unk_348 > 0x1000) { + this->unk_348 = 0x1000; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish2/func_80B2B180.s") + this->unk_2B6 = (s32)Rand_ZeroFloat(70.0f) + 30; + if (this->unk_2C0 >= 3) { + this->unk_2B6 -= (s32)Rand_ZeroFloat(20.0f); + } + } + } + + if ((this->unk_334 == BGCHECK_Y_MIN) && + !WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_334, &waterbox)) { + this->unk_334 = this->actor.world.pos.y; + } + + if (this->unk_2B4 == 0) { + Math_ApproachF(&this->actor.speedXZ, (D_80B2B380[0] - this->unk_330) * 400.0f, 0.3f, 0.3f); + if (this->actor.speedXZ > 3.0f) { + this->actor.speedXZ = 3.0f; + } else if (this->actor.speedXZ < 1.5f) { + this->actor.speedXZ = 1.5f; + } + } else { + Math_ApproachZeroF(&this->actor.speedXZ, 0.3f, 0.3f); + } + + if ((D_80B2B2E8 == 0) && (D_80B2B2E0 != 2)) { + while (itemAction != NULL) { + if ((itemAction->id != ACTOR_EN_FISH) && (itemAction->id != ACTOR_EN_MUSHI2)) { + itemAction = itemAction->next; + continue; + } + + if (itemAction->id == ACTOR_EN_MUSHI2) { + if ((itemAction->update != NULL) && (((EnMushi2*)itemAction)->unk_30C & 0x200)) { + this->unk_350 = itemAction; + this->unk_2C8 = 1; + func_80B29194(this); + break; + } + } else if ((itemAction->update != NULL) && (itemAction->params == 0) && + (fabsf(itemAction->world.pos.x - this->actor.world.pos.x) < 100.0f) && + (fabsf(itemAction->world.pos.z - this->actor.world.pos.z) < 100.0f) && + (itemAction->bgCheckFlags & 0x20)) { + this->unk_350 = itemAction; + if (D_80B2B2E0 == 0) { + EnFish2* fish; + + this->unk_354 = NULL; + fish = (EnFish2*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_FISH2, + this->unk_324.x, this->unk_324.y, this->unk_324.z, 0, 0, 0, 1); + this->unk_354 = fish; + if (this->unk_354 != NULL) { + D_80B2B2E4 = 0; + D_80B2B2E0 = 1; + fish->unk_2BA[0] = this->unk_2BA[0]; + fish->unk_350 = this->unk_350; + } + } + func_80B29194(this); + break; + } + itemAction = itemAction->next; + } + + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} + +void func_80B29128(EnFish2* this) { + this->actionFunc = func_80B2913C; +} + +void func_80B2913C(EnFish2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80B28B5C(this); + } +} + +void func_80B29194(EnFish2* this) { + if ((this->unk_354 != NULL) && (this->unk_2C8 == 0)) { + EnFish* fish = (EnFish*)this->unk_350; + fish->unk_277 = 1; + } + + this->unk_2C4 = 0; + this->actor.speedXZ = 0.0f; + if (this->unk_2C8 == 0) { + this->unk_34C = 400; + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_324); + this->actor.world.pos.y = this->actor.floorHeight + (this->unk_330 * 1200.0f); + } + + this->unk_34A = 0; + this->unk_340 = (s32)Rand_ZeroOne() & 1; + func_80B28370(this, 1); + this->actionFunc = func_80B29250; +} + +void func_80B29250(EnFish2* this, GlobalContext* globalCtx) { + if (!func_80B28478(this)) { + Math_ApproachF(&this->actor.speedXZ, (D_80B2B380[0] - this->unk_330) * 1000.0f, 0.3f, 0.3f); + + if (this->actor.speedXZ > 4.0f) { + this->actor.speedXZ = 4.0f; + } else if (this->actor.speedXZ < 2.0f) { + this->actor.speedXZ = 2.0f; + } + + func_80B287F4(this, 0); + func_80B289DC(this, globalCtx); + if (func_80B288E8(this, this->unk_300, 0) && + (((this->unk_2C8 == 0) && (D_80B2B2E4 == 1)) || (this->unk_2C8 != 0))) { + Math_Vec3f_Copy(&this->unk_30C, &this->unk_350->world.pos); + func_80B2938C(this); + } + } +} + +void func_80B2938C(EnFish2* this) { + func_80B28370(this, 5); + this->unk_348 = 0; + this->actionFunc = func_80B293C4; +} + +void func_80B293C4(EnFish2* this, GlobalContext* globalCtx) { + f32 currentFrame = this->skelAnime.curFrame; + + if (func_80B28478(this) == 0) { + func_80B287F4(this, 1); + Math_ApproachF(&this->actor.speedXZ, (*D_80B2B380 - this->unk_330) * 1000.0f, 0.3f, 0.3f); + + if (this->actor.speedXZ > 3.0f) { + this->actor.speedXZ = 3.0f; + } else if (this->actor.speedXZ < 1.0f) { + this->actor.speedXZ = 1.0f; + } + + if (this->unk_2CC <= currentFrame) { + func_80B28370(this, 1); + if (this->unk_2B0 == 0) { + this->actionFunc = func_80B29250; + } else { + this->actionFunc = func_80B29EE4; + } + } else { + func_80B289DC(this, globalCtx); + if (func_80B288E8(this, this->unk_318, 1)) { + func_80B2951C(this); + } + } + } +} + +void func_80B2951C(EnFish2* this) { + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + this->unk_348 = 0; + + if (this->unk_2C8 == 0) { + D_80B2B2E0 = 2; + } + + this->unk_2B4 = 10; + this->actor.speedXZ = 3.0f; + Actor_MarkForDeath(this->unk_350); + this->unk_350 = NULL; + D_80B2B2F4 = &this->actor; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DODO_M_EAT); + this->actionFunc = func_80B295A4; +} + +void func_80B295A4(EnFish2* this, GlobalContext* globalCtx) { + s32 i; + f32 currentFrame = this->skelAnime.curFrame; + s32 pad; + Vec3f sp60; + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &globalCtx->view.eye), 1, + 0x1388, 0); + Math_ApproachZeroF(&this->actor.speedXZ, 0.3f, 0.3f); + if (this->unk_2B4 != 0) { + Math_Vec3f_Copy(&sp60, &this->unk_318); + sp60.x += randPlusMinusPoint5Scaled(100.0f); + sp60.z += randPlusMinusPoint5Scaled(100.0f); + + for (i = 0; i < 2; i++) { + EffectSsBubble_Spawn(globalCtx, &sp60, 0.0f, 5.0f, 5.0f, Rand_ZeroFloat(this->unk_330 * 4.0f) + 0.1f); + } + } else if (this->unk_2CC <= currentFrame) { + if (this->unk_2AC != 5) { + func_80B28370(this, 5); + } else if (this->unk_2C8 == 0) { + func_80B29778(this); + } else { + this->unk_2B4 = 0; + this->unk_2C4 = 0; + this->unk_2B6 = this->unk_2B4; + func_80B28B5C(this); + } + } +} + +void func_80B29778(EnFish2* this) { + func_80B28370(this, 0); + this->unk_2B4 = 0; + this->unk_2C4 = 0; + this->unk_2B6 = this->unk_2B4; + if (this->unk_2B0 != 0) { + this->unk_324.x = this->actor.home.pos.x - 14.0f; + this->unk_324.z = this->actor.home.pos.z - 18.0f; + } + this->actionFunc = func_80B297FC; + this->unk_324.y = this->unk_2D4; + this->actor.speedXZ = 0.0f; +} + +void func_80B297FC(EnFish2* this, GlobalContext* globalCtx) { + f32 phi_f0 = 0.0f; + Vec3f sp48; + + switch (this->unk_2C4) { + case 0: + Math_Vec3f_Copy(&sp48, &this->unk_324); + sp48.y = this->unk_2D4; + this->unk_348 = Math_Vec3f_Pitch(&this->actor.world.pos, &sp48); + + if (this->unk_348 < -0x2000) { + this->unk_348 = -0x2000; + } + + if (this->unk_348 > 0x2000) { + this->unk_348 = 0x2000; + } + + this->unk_34A = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_324); + func_80B289DC(this, globalCtx); + Math_ApproachF(&this->actor.world.pos.x, this->unk_324.x, 0.3f, 3.0f); + Math_ApproachF(&this->actor.world.pos.y, this->unk_2D4, 0.3f, 3.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_324.z, 0.3f, 3.0f); + if ((fabsf(this->actor.world.pos.x - this->unk_324.x) < 2.0f) && + (this->actor.world.pos.y < (this->unk_2D4 + 3.0f)) && + (fabsf(this->actor.world.pos.z - this->unk_324.z) < 2.0f)) { + this->actor.speedXZ = 0.0f; + this->unk_34A = BINANG_ROT180(this->actor.home.rot.y); + this->unk_2C4++; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + } + break; + + case 1: + Math_SmoothStepToS(&this->unk_348, 0, 1, 0x7D0, 0); + if ((fabsf(this->actor.world.rot.y - this->unk_34A) < 100.0f) && (fabsf(this->actor.world.rot.x) < 30.0f)) { + this->unk_2C0++; + if (this->unk_344 == 0) { + if (this->unk_2C0 == 1) { + gSaveContext.save.weekEventReg[81] |= 0x10; + } else if (this->unk_2C0 == 2) { + gSaveContext.save.weekEventReg[81] |= 0x20; + } else if (this->unk_2C0 == 3) { + gSaveContext.save.weekEventReg[81] |= 0x40; + } + } else if (this->unk_2C0 == 1) { + gSaveContext.save.weekEventReg[81] |= 0x80; + } else if (this->unk_2C0 == 2) { + gSaveContext.save.weekEventReg[82] |= 1; + } else if (this->unk_2C0 == 3) { + gSaveContext.save.weekEventReg[82] |= 2; + } + + if (this->unk_2B0 != 0) { + this->unk_2C0 = 5; + } + + this->unk_2B6 = 4; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FISH_GROW_UP); + this->unk_2C4++; + } + break; + + case 2: + phi_f0 = 0.1f; + + case 4: + if (phi_f0 == 0) { + phi_f0 = 0.3f; + } + + case 6: + if (phi_f0 == 0) { + phi_f0 = 0.5f; + } + + Math_ApproachF(&this->unk_330, D_80B2B370[this->unk_2C0] * phi_f0, 0.3f, 0.004f); + + if (this->unk_2B6 == 0) { + Vec3f sp3C; + s32 i; + s32 pad2; + + Math_Vec3f_Copy(&sp3C, &this->actor.world.pos); + sp3C.y += -10.0f; + + for (i = 0; i < 30; i++) { + func_80B2ADB0(this, &sp3C, 0x46); + } + this->unk_2C4++; + this->unk_2B6 = 2; + } + break; + + case 3: + phi_f0 = 1.3f; + + case 5: + if (phi_f0 == 0) { + phi_f0 = 1.5f; + } + + case 7: + if (phi_f0 == 0) { + phi_f0 = 1.7f; + } + + Math_ApproachF(&this->unk_330, D_80B2B370[this->unk_2C0] * phi_f0, 0.3f, 0.004f); + + if (this->unk_2B6 == 0) { + this->unk_2B6 = 2; + this->unk_2C4++; + } + break; + + case 8: + Math_ApproachF(&this->unk_330, D_80B2B370[this->unk_2C0], 0.3f, 0.004f); + if (this->unk_2B6 == 0) { + this->unk_2B6 = 30; + this->unk_2C4++; + } + break; + + case 9: + if (this->unk_2B6 == 0) { + if (this->unk_2C0 > 3) { + this->unk_2C0 = 3; + this->unk_2C4 = 0; + if (this->unk_2B0 == 0) { + this->actionFunc = func_80B29E5C; + } else { + func_80B2A448(this); + } + } else { + this->unk_2B6 = 0; + this->unk_2B4 = 0; + this->unk_2C4 = 0; + if (D_80B2B2EC > 200) { + D_80B2B2E4 = 0; + D_80B2B2E0 = D_80B2B2EC = 0; + } else { + D_80B2B2E4 = 3; + } + + this->collider.elements[0].dim.modelSphere.radius = (s32)((this->unk_330 - 0.01f) * 1000.0f) + 5; + if (this->collider.elements[0].dim.modelSphere.radius > 15) { + this->collider.elements[0].dim.modelSphere.radius = 15; + } + + this->collider.elements[1].dim.modelSphere.radius = (s32)((this->unk_330 - 0.01f) * 1000.0f) + 5; + if (this->collider.elements[1].dim.modelSphere.radius > 15) { + this->collider.elements[1].dim.modelSphere.radius = 15; + } + func_80B28B5C(this); + } + } + break; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_34A, 1, 0xFA0, 0); +} + +void func_80B29E5C(EnFish2* this, GlobalContext* globalCtx) { + Actor* prop = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; + + while (prop != NULL) { + if (prop->id != ACTOR_EN_FISH2) { + prop = prop->next; + continue; + } + + if (&this->actor != prop) { + this->unk_350 = prop; + this->unk_2B0 = D_80B2B2E8 = 1; + func_80B28370(this, 0); + this->actionFunc = func_80B29EE4; + break; + } + + prop = prop->next; + } +} + +void func_80B29EE4(EnFish2* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + if (this->unk_2C4 < 400) { + this->unk_2C4++; + } + this->unk_338 = 410.0f - this->unk_2C4; + Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.3f, 0.3f); + Math_ApproachF(&this->unk_350->speedXZ, (D_80B2B380[0] - this->unk_330) * this->unk_338, 0.1f, 0.4f); + func_80B289DC(this, globalCtx); + Math_Vec3f_Copy(&sp2C, &this->unk_350->world.pos); + this->unk_34A = Math_Vec3f_Yaw(&this->actor.world.pos, &sp2C); + this->unk_348 = Math_Vec3f_Pitch(&this->actor.world.pos, &sp2C); + if (func_80B288E8(this, this->unk_300, 0)) { + Math_Vec3f_Copy(&this->unk_30C, &this->unk_350->world.pos); + func_80B2938C(this); + } +} + +void func_80B2A01C(EnFish2* this, GlobalContext* globalCtx) { + if (this->unk_2B4 == 0) { + if (!ActorCutscene_GetCanPlayNext(this->unk_2BA[0])) { + ActorCutscene_SetIntentToPlay(this->unk_2BA[0]); + } else { + this->unk_2B4 = 15; + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2BA[0], &this->actor); + this->actionFunc = func_80B2A094; + } + } +} + +void func_80B2A094(EnFish2* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + if (this->unk_2B4 == 0) { + D_80B2B2E4 = 1; + } + + this->unk_2CA = ActorCutscene_GetCurrentCamera(this->unk_2BA[0]); + + if (D_80B2B2EC != 0) { + D_80B2B2EC++; + if (D_80B2B2EC > 200) { + Actor_MarkForDeath(&this->actor); + ActorCutscene_Stop(this->unk_2BA[0]); + return; + } + } + + if ((this->unk_350 != NULL) && (this->unk_350->update != NULL)) { + Math_Vec3f_Copy(&sp2C, &this->unk_350->world.pos); + sp2C.x += Math_SinS(-0x3A98) * 110.0f; + sp2C.z += Math_CosS(-0x3A98) * 110.0f; + Math_Vec3f_Copy(&this->unk_2DC, &sp2C); + Math_Vec3f_Copy(&sp2C, &this->unk_350->world.pos); + sp2C.x += Math_SinS(-0x3A98) * 10.0f; + sp2C.z += Math_CosS(-0x3A98) * 10.0f; + Math_Vec3f_Copy(&this->unk_2E8, &sp2C); + } + + Play_CameraSetAtEye(globalCtx, this->unk_2CA, &this->unk_2E8, &this->unk_2DC); + if ((this->unk_350 == NULL) || (this->unk_350->update == NULL)) { + this->unk_350 = NULL; + this->unk_2B0++; + if (this->unk_2B0 > 10) { + this->unk_2B4 = 20; + this->actionFunc = func_80B2A23C; + } + } +} + +void func_80B2A23C(EnFish2* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + if (D_80B2B2E4 == 2) { + sp2C.x += (Math_SinS(-0x3A98) * 180.0f); + sp2C.y += 90.0f; + sp2C.z += Math_CosS(-0x3A98) * 180.0f; + Math_Vec3f_Copy(&this->unk_2DC, &sp2C); + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + sp2C.y += 70.0f; + Math_Vec3f_Copy(&this->unk_2E8, &sp2C); + } else if (D_80B2B2F4 != NULL) { + Math_Vec3f_Copy(&sp2C, &D_80B2B2F4->world.pos); + sp2C.x += Math_SinS(-0x3A98) * 110.0f; + sp2C.z += Math_CosS(-0x3A98) * 110.0f; + Math_Vec3f_Copy(&this->unk_2DC, &sp2C); + Math_Vec3f_Copy(&sp2C, &D_80B2B2F4->world.pos); + sp2C.x += Math_SinS(-0x3A98) * 10.0f; + sp2C.z += Math_CosS(-0x3A98) * 10.0f; + Math_Vec3f_Copy(&this->unk_2E8, &sp2C); + } + + Play_CameraSetAtEye(globalCtx, this->unk_2CA, &this->unk_2E8, &this->unk_2DC); + + if ((this->unk_2B4 == 0) && (D_80B2B2E4 == 3)) { + D_80B2B2E0 = D_80B2B2EC = D_80B2B2E4 = 0; + D_80B2B2F4 = NULL; + ActorCutscene_Stop(this->unk_2BA[0]); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B2A448(EnFish2* this) { + func_80B28370(this, 4); + this->unk_2B4 = 0; + this->unk_2C4 = 0; + this->unk_2B6 = this->unk_2B4; + D_80B2B2E4 = 2; + this->actionFunc = func_80B2A498; +} + +void func_80B2A498(EnFish2* this, GlobalContext* globalCtx) { + f32 currentFrame = this->skelAnime.curFrame; + Vec3f sp80; + + if ((this->unk_2AC == 4) && Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor* temp_v0; + + Math_Vec3f_Copy(&sp80, &this->unk_318); + temp_v0 = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_COL_MAN, sp80.x, sp80.y, sp80.z, 0, + this->actor.world.rot.y, 0, 0); + if (temp_v0 != NULL) { + temp_v0->speedXZ = 4.0f; + temp_v0->velocity.y = 15.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_PIECE_OF_HEART); + gSaveContext.save.weekEventReg[81] &= (u8)~0x10; + gSaveContext.save.weekEventReg[81] &= (u8)~0x20; + gSaveContext.save.weekEventReg[81] &= (u8)~0x40; + gSaveContext.save.weekEventReg[81] &= (u8)~0x80; + gSaveContext.save.weekEventReg[82] &= (u8)~1; + gSaveContext.save.weekEventReg[82] &= (u8)~2; + } + } + + if ((this->unk_2AC == 4) && + (Animation_OnFrame(&this->skelAnime, 13.0f) || Animation_OnFrame(&this->skelAnime, 31.0f))) { + WaterBox* sp78; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_334, &sp78)) { + Vec3f sp6C; + s32 i; + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_BOMB_DROP_WATER); + + for (i = 0; i < 10; i++) { + Math_Vec3f_Copy(&sp6C, &this->actor.world.pos); + sp6C.x += randPlusMinusPoint5Scaled(70.0f); + sp6C.y = this->unk_334 + 10.0f; + sp6C.z += randPlusMinusPoint5Scaled(70.0f); + EffectSsGSplash_Spawn(globalCtx, &sp6C, NULL, NULL, 0, (s32)randPlusMinusPoint5Scaled(50.0f) + 350); + } + } + } + + if ((this->unk_2CC <= currentFrame) && (this->unk_2AC == 4)) { + D_80B2B2E0 = 0; + D_80B2B2E4 = 3; + this->actor.world.pos.x = this->unk_324.x; + this->actor.world.pos.z = this->unk_324.z; + func_80B28370(this, 0); + } +} + +void EnFish2_Update(Actor* thisx, GlobalContext* globalCtx2) { + static f32 D_80B2B3A8[] = { + 0.0f, 40.0f, -40.0f, 0.0f, 0.0f, 0.0f, + }; + GlobalContext* globalCtx = globalCtx2; + EnFish2* this = THIS; + + if ((this->actionFunc != func_80B295A4) && (this->actor.params != 1)) { + SkelAnime_Update(&this->skelAnime); + } + + if (this->unk_2B8 != 0) { + this->unk_2B8--; + } + + if (this->unk_2B6 != 0) { + this->unk_2B6--; + } + + if (this->unk_2B4 == 0) { + } else { + this->unk_2B4--; + } + + this->actionFunc(this, globalCtx); + Actor_SetFocus(&this->actor, 0); + + if (this->actor.params != 1) { + WaterBox* sp6C; + s32 i; + Vec3f sp5C; + + if (this->actor.params == 0) { + Math_SmoothStepToS(&this->actor.world.rot.x, this->unk_348, 1, this->unk_34C + 200, 0); + if (this->actionFunc != func_80B297FC) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_34A, 1, 0xBB8, 0); + } + } + + if ((globalCtx->gameplayFrames % 8) == 0) { + Math_Vec3f_Copy(&sp5C, &this->unk_324); + sp5C.x += randPlusMinusPoint5Scaled(100.0f); + sp5C.y = this->actor.floorHeight; + sp5C.z += randPlusMinusPoint5Scaled(100.0f); + + for (i = 0; i < (s32)randPlusMinusPoint5Scaled(5.0f) + 10; i++) { + EffectSsBubble_Spawn(globalCtx, &sp5C, 0, 5.0f, 5.0f, Rand_ZeroFloat(this->unk_330 * 4.0f) + 0.1f); + } + } + + func_80B2AF80(this, globalCtx); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + Math_Vec3f_Copy(&this->unk_2F4, &this->actor.world.pos); + this->unk_2F4.x += (Math_SinS(this->actor.world.rot.y) * 25.0f) - this->unk_330; + this->unk_2F4.z += (Math_CosS(this->actor.world.rot.y) * 25.0f) - this->unk_330; + this->unk_33C = 25.0f - ((this->unk_330 - 0.01f) * 1000.0f); + Actor_SetScale(&this->actor, this->unk_330); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0, 15.0f, 10.0f, 7); + + if (this->actor.params != 2) { + this->unk_2D4 = this->actor.floorHeight + (this->unk_330 * 1000.0f); + this->unk_2D8 = this->unk_330 * 600.0f; + if (this->actor.world.pos.y < this->unk_2D4) { + this->actor.world.pos.y = this->unk_2D4 + 0.1f; + } + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_334, &sp6C)) { + if ((this->unk_334 != BGCHECK_Y_MIN) && (this->unk_334 - this->unk_2D8 < this->actor.world.pos.y)) { + this->actor.world.pos.y = this->unk_334 - this->unk_2D8; + } + } + + if ((D_80B2B2E8 == 0) && (this->actionFunc == func_80B28C14)) { + s32 temp_s0_2 = this->unk_344 * 2; + f32 phi_f2 = 0.0f; + f32 phi_f20 = 0; + WaterBox* sp4C; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, + this->actor.world.pos.z, &this->unk_334, &sp4C)) { + phi_f20 = D_80B2B3A8[temp_s0_2] + (this->unk_334 - this->unk_2D8); + phi_f2 = D_80B2B3A8[temp_s0_2 + 1] + this->unk_2D4; + } + + if ((phi_f20 < this->actor.world.pos.y) && (this->unk_348 < 0)) { + this->unk_348 = 0; + this->actor.velocity.y = 0; + this->actor.gravity = 0; + } + + if ((this->actor.world.pos.y < phi_f2) && (this->unk_348 > 0)) { + this->unk_348 = 0; + this->actor.velocity.y = 0; + this->actor.gravity = 0; + } + } + + if (D_80B2B2E8 == 0) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + } +} + +s32 EnFish2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnFish2* this = THIS; + + if ((limbIndex == 20) || (limbIndex == 21)) { + *dList = NULL; + } + + return false; +} + +void EnFish2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFish2* this = THIS; + s32 pad; + + if ((limbIndex == 20) || (limbIndex == 21)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_ReplaceRotation(&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_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == 14) { + Matrix_MultVec3f(&gZeroVec3f, &this->unk_318); + } + + if (limbIndex == 17) { + Matrix_MultVec3f(&gZeroVec3f, &this->unk_300); + } + + Collider_UpdateSpheres(limbIndex, &this->collider); +} + +void EnFish2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFish2* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnFish2_OverrideLimbDraw, EnFish2_PostLimbDraw, &this->actor); + func_80B2B180(this, globalCtx); +} + +void func_80B2ADB0(EnFish2* this, Vec3f* vec, s16 arg2) { + s16 i; + EnFish2UnkStruct* ptr = &this->unk_3F8[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++, ptr++) { + if (!ptr->unk_00) { + TexturePtr phi_v0; + + if (Rand_ZeroOne() < 0.5f) { + phi_v0 = gEffBubble2Tex; + } else { + phi_v0 = gEffBubble1Tex; + } + + ptr->unk_20 = VIRTUAL_TO_PHYSICAL(SEGMENTED_TO_VIRTUAL(phi_v0)); + ptr->unk_00 = true; + ptr->unk_04 = *vec; + ptr->unk_04.x += randPlusMinusPoint5Scaled(ptr->unk_00 + (this->unk_330 * 4000.0f)); + ptr->unk_04.y += randPlusMinusPoint5Scaled(20.0f); + ptr->unk_04.z += randPlusMinusPoint5Scaled(ptr->unk_00 + (this->unk_330 * 4000.0f)); + ptr->unk_18 = (this->unk_330 * 20.0f) - (Rand_ZeroFloat(5.0f) * 0.01f); + ptr->unk_1C = 0x42; + ptr->unk_10 = arg2; + break; + } + } +} + +void func_80B2AF80(EnFish2* this, GlobalContext* globalCtx) { + EnFish2UnkStruct* ptr = &this->unk_3F8[0]; + WaterBox* sp90; + f32 sp8C; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++, ptr++) { + if (ptr->unk_00) { + if ((ptr->unk_10 != 0) && (ptr->unk_1C != 0)) { + Math_ApproachF(&ptr->unk_14, ptr->unk_18, 0.4f, 0.5f); + ptr->unk_10--; + } else { + ptr->unk_00 = 0; + } + + if (ptr->unk_00) { + ptr->unk_04.x += (0.3f + (Rand_ZeroOne() * 0.5f)) - 0.55f; + ptr->unk_04.y += 1.0f + ((Rand_ZeroOne() - 0.3f) * 1.2f); + ptr->unk_04.z += (0.3f + (Rand_ZeroOne() * 0.5f)) - 0.55f; + sp8C = ptr->unk_04.y; + if (!WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, ptr->unk_04.x, ptr->unk_04.z, &sp8C, &sp90)) { + ptr->unk_00 = 0; + } else if (sp8C < ptr->unk_04.y) { + Vec3f sp7C; + + sp7C.x = ptr->unk_04.x; + sp7C.y = sp8C; + sp7C.z = ptr->unk_04.z; + EffectSsGRipple_Spawn(globalCtx, &sp7C, 0, 80, 0); + ptr->unk_00 = 0; + } + } + } + } +} + +void func_80B2B180(EnFish2* this, GlobalContext* globalCtx) { + s16 i; + EnFish2UnkStruct* ptr; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + ptr = &this->unk_3F8[0]; + func_8012C28C(gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++, ptr++) { + if (ptr->unk_00) { + Matrix_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_14, ptr->unk_14, ptr->unk_14, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0); + gSPSegment(POLY_OPA_DISP++, 0x08, ptr->unk_20); + gSPDisplayList(POLY_OPA_DISP++, gEffBubbleDL); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.h b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.h index f2714191f..7216d00c8 100644 --- a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.h +++ b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.h @@ -7,11 +7,58 @@ struct EnFish2; typedef void (*EnFish2ActionFunc)(struct EnFish2*, GlobalContext*); +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ s16 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ s16 unk_1C; + /* 0x20 */ void* unk_20; +} EnFish2UnkStruct; // size = 0x24 + typedef struct EnFish2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x164]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; /* 0x02A8 */ EnFish2ActionFunc actionFunc; - /* 0x02AC */ char unk_2AC[0x1D6C]; + /* 0x02AC */ s32 unk_2AC; + /* 0x02B0 */ s32 unk_2B0; + /* 0x02B4 */ s16 unk_2B4; + /* 0x02B6 */ s16 unk_2B6; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA[3]; + /* 0x02C0 */ s32 unk_2C0; + /* 0x02C4 */ s32 unk_2C4; + /* 0x02C8 */ u8 unk_2C8; + /* 0x02CA */ s16 unk_2CA; + /* 0x02CC */ f32 unk_2CC; + /* 0x02D0 */ char unk_2D0[0x4]; + /* 0x02D4 */ f32 unk_2D4; + /* 0x02D8 */ f32 unk_2D8; + /* 0x02DC */ Vec3f unk_2DC; + /* 0x02E8 */ Vec3f unk_2E8; + /* 0x02F4 */ Vec3f unk_2F4; + /* 0x0300 */ Vec3f unk_300; + /* 0x030C */ Vec3f unk_30C; + /* 0x0318 */ Vec3f unk_318; + /* 0x0324 */ Vec3f unk_324; + /* 0x0330 */ f32 unk_330; + /* 0x0334 */ f32 unk_334; + /* 0x0338 */ f32 unk_338; + /* 0x033C */ f32 unk_33C; + /* 0x0340 */ s32 unk_340; + /* 0x0344 */ s32 unk_344; + /* 0x0348 */ s16 unk_348; + /* 0x034A */ s16 unk_34A; + /* 0x034C */ s16 unk_34C; + /* 0x034E */ char unk_34E[0x02]; + /* 0x0350 */ Actor* unk_350; + /* 0x0354 */ struct EnFish2* unk_354; + /* 0x0358 */ ColliderJntSph collider; + /* 0x0378 */ ColliderJntSphElement colliderElements[2]; + /* 0x03F8 */ EnFish2UnkStruct unk_3F8[200]; } EnFish2; // size = 0x2018 extern const ActorInit En_Fish2_InitVars; 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..668033cd6 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,205 @@ /* * File: z_en_fishing.c * Overlay: ovl_En_Fishing - * Description: Fishing + * Description: Fishing Pond Elements (Owner, Fish, Props, Effects...) */ +#include "prevent_bss_reordering.h" #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 FLAGS (ACTOR_FLAG_10) #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 + +f32 D_809101B0; +f32 D_809101B4; +s16 D_809101B8; +f32 D_809101BC; +f32 D_809101C0; +f32 D_809101C4; +f32 D_809101C8; +s16 D_809101CC; +f32 D_809101D0; +Vec3f sRodTipPos; +Vec3f sReelLinePos[LINE_SEG_COUNT]; +Vec3f sReelLineRot[LINE_SEG_COUNT]; +Vec3f sReelLineUnk[LINE_SEG_COUNT]; +Vec3f sLureHookRefPos[2]; +f32 sLureHookRotY[2]; +u8 D_80911E28; +Vec3f sSinkingLurePos[SINKING_LURE_SEG_COUNT]; +s16 D_80911F20; +f32 sProjectedW; +Vec3f sCameraEye; +Vec3f sCameraAt; +s16 sCameraId; +f32 D_80911F48; +f32 D_80911F4C; +f32 D_80911F50; +Vec3f sSinkingLureBasePos; +f32 D_80911F64; +s32 sRandSeed0; +s32 sRandSeed1; +s32 sRandSeed2; +FishingProp sPondProps[POND_PROP_COUNT]; +FishingGroupFish sGroupFishes[GROUP_FISH_COUNT]; +f32 sFishGroupAngle1; +f32 sFishGroupAngle2; +f32 sFishGroupAngle3; +FishingEffect sFishingEffects[EFFECT_COUNT]; +Vec3f sStreamSoundProjectedPos; +EnFishing* sFishingMain; +u8 D_809171C8; +u8 sLinkAge; +u8 D_809171CA; +u8 D_809171CB; +f32 D_809171CC; +u8 D_809171D0; +u8 D_809171D1; +u8 D_809171D2; +s16 D_809171D4; +u8 D_809171D6; +u16 D_809171D8; +u16 D_809171DA; +s8 D_809171DC; +Vec3f sOwnerHeadPos; +Vec3s sEffOwnerHatRot; +u8 D_809171F2; +s16 D_809171F4; +s16 D_809171F6; +EnFishing* sFishingHookedFish; +s16 D_809171FC; +s16 D_809171FE; +s16 D_80917200; +s16 D_80917202; +s16 D_80917204; +u8 D_80917206; +Vec3f sLurePos; +Vec3f D_80917218; +Vec3f sLureRot; +Vec3f D_80917238; +Vec3f D_80917248; +f32 D_80917254; +f32 D_80917258; +f32 D_8091725C; +f32 D_80917260; +s8 D_80917264; +s16 D_80917266; +u8 D_80917268; +f32 D_8091726C; +u8 D_80917270; +s16 D_80917272; +u8 D_80917274; +Vec3f D_80917278; -#if 0 const ActorInit En_Fishing_InitVars = { ACTOR_EN_FISHING, ACTORCAT_NPC, @@ -24,181 +208,5482 @@ 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] = { +f32 D_8090CCD0 = 0.0f; +u8 D_8090CCD4 = 0; +f32 D_8090CCD8 = 0.0f; +Vec3f D_8090CCDC = { 0.0f, 0.0f, 0.0f }; +f32 D_8090CCE8 = 0.0f; +u8 sSinkingLureLocation = 0; +f32 D_8090CCF0 = 0.0f; +u8 D_8090CCF4 = true; +u16 D_8090CCF8 = 0; +u8 D_8090CCFC = 0; +s32 D_8090CD00 = 0; +s16 D_8090CD04 = 0; +u8 D_8090CD08 = 0; +u8 D_8090CD0C = 0; +u8 D_8090CD10 = 0; +s16 D_8090CD14 = 0; +Vec3f sFishMouthOffset = { 500.0f, 500.0f, 0.0f }; +u8 D_8090CD24 = 0; +f32 D_8090CD28 = 0; +f32 D_8090CD2C = 0; +f32 D_8090CD30 = 0.0f; +f32 D_8090CD34 = 0.0f; +f32 D_8090CD38 = 0.0f; +f32 D_8090CD3C = 0.0f; +f32 D_8090CD40 = 0.0f; +s16 D_8090CD44 = 0; +s16 D_8090CD48 = 0; +u8 D_8090CD4C = 0; +u8 D_8090CD50 = 0; +u8 D_8090CD54 = 0; + +static ColliderJntSphElementInit sJntSphElementsInit[] = { { - { 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, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8090D4D0[] = { +u8 D_8090CF18 = 0; +static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f }; +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_RotateYF(rot->y, MTXMODE_NEW); + Matrix_RotateXFApply(rot->x); + Matrix_MultVec3f(&velSrc, &effect->vel); + break; + } + + effect++; + } +} + +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++; + } +} + +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), }; -#endif +void EnFishing_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFishing* this = THIS; + u16 fishCount; -extern ColliderJntSphElementInit D_8090CD58[12]; -extern ColliderJntSphInit D_8090CF08; -extern InitChainEntry D_8090D4D0[]; + Actor_ProcessInitChain(thisx, sInitChain); + ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f); -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; + sLinkAge = gSaveContext.save.linkAge; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC6C0.s") + if (thisx->params < 100) { + s16 i; + FishingGroupFish* fish; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC770.s") + D_809171C8 = 0; + sFishingMain = this; + Collider_InitJntSph(globalCtx, &sFishingMain->collider); + Collider_SetJntSph(globalCtx, &sFishingMain->collider, thisx, &sJntSphInit, sFishingMain->colliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC790.s") + thisx->params = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC8B8.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingOwnerSkel, &gFishingOwnerAnim, NULL, NULL, 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingOwnerAnim, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC964.s") + thisx->update = EnFishing_UpdateOwner; + thisx->draw = EnFishing_DrawOwner; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCABC.s") + thisx->shape.rot.y = -0x6000; + thisx->world.pos.x = 160.0f; + thisx->world.pos.y = -2.0f; + thisx->world.pos.z = 1208.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCC0C.s") + Actor_SetScale(thisx, 0.011f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCDBC.s") + thisx->focus.pos = thisx->world.pos; + thisx->focus.pos.y += 75.0f; + thisx->flags |= 9; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCF60.s") + if (sLinkAge != 1) { + // HIGH_SCORE(HS_FISHING) from OoT + if (gSaveContext.save.unk_EE4 & 0x1000) { + D_8090CD08 = 0; + } else { + D_8090CD08 = 1; + } + } else { + D_8090CD08 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FD054.s") + D_8090CD04 = 20; + globalCtx->specialEffects = sFishingEffects; + REG(15) = 1; // gTimeIncrement in OoT + D_809171FC = 0; + D_809171F6 = 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Init.s") + Audio_QueueSeqCmd(0x100100FF); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Destroy.s") + if (sLinkAge == 1) { + if (gSaveContext.save.unk_EE4 & 0x7F) { + D_809171CC = gSaveContext.save.unk_EE4 & 0x7F; + } else { + D_809171CC = 40.0f; + } + } else if (gSaveContext.save.unk_EE4 & 0x7F000000) { + D_809171CC = (gSaveContext.save.unk_EE4 & 0x7F000000) >> 0x18; + } else { + D_809171CC = 45.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FDCDC.s") + D_809171D1 = (gSaveContext.save.unk_EE4 & 0xFF0000) >> 0x10; + if ((D_809171D1 & 7) == 7) { + globalCtx->roomCtx.unk7A[0] = 90; + D_809171CA = 1; + } else { + globalCtx->roomCtx.unk7A[0] = 40; + D_809171CA = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FE3F8.s") + if ((D_809171D1 & 7) == 6) { + D_809171CB = 100; + } else { + D_809171CB = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEE1C.s") + for (i = 0; i < EFFECT_COUNT; i++) { + sFishingEffects[i].type = FS_EFF_NONE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEF70.s") + for (i = 0; i < POND_PROP_COUNT; i++) { + sPondProps[i].type = FS_PROP_NONE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF064.s") + sFishGroupAngle1 = 0.7f; + sFishGroupAngle2 = 2.3f; + sFishGroupAngle3 = 4.6f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF5E0.s") + for (i = 0; i < GROUP_FISH_COUNT; i++) { + fish = &sGroupFishes[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF750.s") + fish->type = FS_GROUP_FISH_NORMAL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFC44.s") + 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; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFF3C.s") + fish->unk_10.y = fish->pos.y = -35.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900228.s") + fish->timer = Rand_ZeroFloat(100.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900A04.s") + fish->unk_3C = 0; + fish->unk_3E = 0; + fish->unk_40 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80901480.s") + if (sLinkAge != 1) { + if (((i >= 15) && (i < 20)) || ((i >= 35) && (i < 40)) || ((i >= 55) && (i < 60))) { + fish->type = FS_GROUP_FISH_NONE; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809033F0.s") + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809036BC.s") + if ((D_809171D1 & 3) == 3) { + if (sLinkAge != 1) { + fishCount = 16; + } else { + fishCount = 17; + } + } else { + fishCount = 15; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809038A4.s") + 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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903C60.s") + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903E20.s") + thisx->bgCheckFlags |= 0x800; // Added in MM -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Update.s") + 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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908554.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908674.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809086B4.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908734.s") + this->unk_1A4 += Rand_ZeroFloat(4.99999f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Draw.s") + if ((this->unk_1A4 >= 65.0f) && (Rand_ZeroOne() < 0.05f)) { + this->unk_1A4 += Rand_ZeroFloat(7.99999f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809089B8.s") + if (sLinkAge == 1) { + this->unk_1A4 *= 0.73f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908A64.s") +void EnFishing_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFishing* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908B4C.s") + SkelAnime_Free(&this->skelAnime, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908E08.s") + if (thisx->params == 200) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); + } else if (thisx->params == 1) { + Collider_DestroyJntSph(globalCtx, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909234.s") +void EnFishing_UpdateEffects(FishingEffect* effect, GlobalContext* globalCtx) { + f32 rippleY; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909AD0.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909CC0.s") + if (effect->type == FS_EFF_RIPPLE) { + Math_ApproachF(&effect->unk_30, effect->unk_34, 0.2f, effect->unk_38); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090AB6C.s") + if (effect->unk_2C == 0) { + effect->alpha += 20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C884.s") + if (effect->alpha >= effect->unk_2E) { + effect->alpha = effect->unk_2E; + effect->unk_2C++; + } + } else { + effect->alpha -= 8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C8BC.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C96C.s") + 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 = SQXZ(effect->pos); + + 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 = SQXZ(effect->pos); + 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) { + Message_StartTextbox(globalCtx, 0x40B3, NULL); + } + + if ((effect->unk_2C >= 100) && (Message_GetState(&globalCtx->msgCtx) == 5)) { + if (Message_ShouldAdvance(globalCtx) || Message_GetState(&globalCtx->msgCtx) == 0) { + 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_Push(); + + 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_Translate(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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_RotateYF(effect->unk_38, MTXMODE_APPLY); + Matrix_RotateXFApply(effect->unk_34); + Matrix_RotateZF(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_Translate(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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateYF(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_Translate(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_RotateYF((sEffOwnerHatRot.y * M_PI) / 32768, MTXMODE_APPLY); + Matrix_RotateXFApply((sEffOwnerHatRot.x * M_PI) / 32768); + Matrix_RotateZF((sEffOwnerHatRot.z * M_PI) / 32768, MTXMODE_APPLY); + Matrix_Scale(effect->unk_30, effect->unk_30, effect->unk_30, MTXMODE_APPLY); + Matrix_Translate(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXFApply(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_Pop(); + + 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_Translate(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_RotateYF(ry, MTXMODE_NEW); + Matrix_RotateXFApply(rx); + Matrix_MultVec3f(&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_RotateYF(ry, MTXMODE_NEW); + Matrix_RotateXFApply(rx); + Matrix_MultVec3f(&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_Push(); + + 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_RotateYF(ry, MTXMODE_NEW); + Matrix_RotateXFApply(rx); + Matrix_MultVec3f(&posSrc, &posStep); + + refPos->x = pos->x + posStep.x; + refPos->y = pos->y + posStep.y; + refPos->z = pos->z + posStep.z; + + Matrix_Translate(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_RotateYF(sLureHookRotY[hookIndex], MTXMODE_APPLY); + Matrix_RotateXFApply(rx); + Matrix_Scale(0.0039999997f, 0.0039999997f, 0.005f, MTXMODE_APPLY); + Matrix_RotateYF(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_RotateZF(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_Translate(250.0f, 0.0f, -1400.0f, MTXMODE_APPLY); + Matrix_Push(); + + if (D_8090CD10 != 0) { + FishingEffect* effect = globalCtx->specialEffects; + MtxF mf; + + Matrix_MultVec3f(&sZeroVec, &effect->pos); + Matrix_Get(&mf); + Matrix_MtxFToYXZRot(&mf, &sEffOwnerHatRot, false); + + D_8090CD10 = 0; + D_8090CD0C = 0; + + effect->type = FS_EFF_OWNER_HAT; + effect->unk_2C = 0; + effect->vel = sZeroVec; + effect->accel = sZeroVec; + } + + Matrix_Pop(); + Matrix_Translate(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXFApply(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_Pop(); + + 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_RotateYF(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW); + sp94.x = 5.0f; + sp94.y = 0.0f; + sp94.z = 3.0f; + Matrix_MultVec3f(&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_RotateYF(ry, MTXMODE_NEW); + Matrix_RotateXFApply(rx); + Matrix_MultVec3f(&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; + } +} + +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_Translate(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_ReplaceRotation(&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_Translate(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_ReplaceRotation(&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_Push(); + + 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_RotateYF(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW); + posSrc.x = 2.0f; + posSrc.y = 0.0f; + posSrc.z = 0.0f; + Matrix_MultVec3f(&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_Translate(sLurePos.x, sLurePos.y, sLurePos.z, MTXMODE_NEW); + Matrix_RotateYF(sLureRot.y + D_80917254, MTXMODE_APPLY); + Matrix_RotateXFApply(sLureRot.x); + Matrix_Scale(0.0039999997f, 0.0039999997f, 0.0039999997f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, D_80917258, MTXMODE_APPLY); + Matrix_RotateZF(M_PI / 2, MTXMODE_APPLY); + Matrix_RotateYF(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_MultVec3f(&posSrc, &D_80917218); + + posSrc.x = 500.0f; + posSrc.z = -300.0f; + Matrix_MultVec3f(&posSrc, &hookPos[0]); + EnFishing_DrawLureHook(globalCtx, &hookPos[0], &sLureHookRefPos[0], 0); + + posSrc.x = 2100.0f; + posSrc.z = -50.0f; + Matrix_MultVec3f(&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_Translate(sRodTipPos.x, sRodTipPos.y, sRodTipPos.z, MTXMODE_NEW); + Matrix_RotateYF(ry, MTXMODE_APPLY); + Matrix_RotateXFApply(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_Translate((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW); + Matrix_RotateYF(ry, MTXMODE_APPLY); + Matrix_RotateXFApply(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_Translate((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW); + Matrix_RotateYF((lineRot + i)->y, MTXMODE_APPLY); + Matrix_RotateXFApply((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_Pop(); + func_8012C2DC(globalCtx->state.gfxCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +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, +}; + +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, +}; + +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_Mult(&player->mf_CC4, MTXMODE_NEW); + + if (sLinkAge != 1) { + Matrix_Translate(0.0f, 400.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_Translate(0.0f, 230.0f, 0.0f, MTXMODE_APPLY); + } + + if (D_8090CD14 == 5) { + Matrix_RotateYF(1.7592919f, MTXMODE_APPLY); + } else { + Matrix_RotateYF(1.288053f, MTXMODE_APPLY); + } + + Matrix_RotateXFApply(-0.6283185f); + Matrix_RotateZF((player->unk_B08[0] * 0.5f) + 0.4712389f, MTXMODE_APPLY); + Matrix_RotateXFApply((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_Translate(0.0f, 0.0f, -1300.0f, MTXMODE_APPLY); + + for (i = 0; i < 22; i++) { + Matrix_RotateYF(sRodBendRatios[i] * D_8090CD28 * 0.5f, MTXMODE_APPLY); + Matrix_RotateXFApply(sRodBendRatios[i] * spC0 * 0.5f); + + Matrix_Push(); + 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_Pop(); + Matrix_Translate(0.0f, 0.0f, 500.0f, MTXMODE_APPLY); + + if (i == 21) { + Matrix_MultVec3f(&sRodTipOffset, &sRodTipPos); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +Vec3f D_8090D614 = { 0.0f, 0.0f, 0.0f }; + +void EnFishing_UpdateLure(EnFishing* this, GlobalContext* globalCtx) { + f32 spE4; + f32 spE0; + s16 i; + s16 spDC; + f32 spD8; + f32 spD4; + f32 spD0; + f32 phi_f16; + f32 spC8; + f32 phi_f0; + Player* player = GET_PLAYER(globalCtx); + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + Vec3f spA8; + Vec3f sp9C; + Vec3f sp90; + Input* input = CONTROLLER1(globalCtx); + + 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_RotateYF(BINANG_TO_RAD(player->actor.shape.rot.y), MTXMODE_NEW); + sp90.x = 0.0f; + sp90.y = 0.0f; + sp90.z = 25.0f; + Matrix_MultVec3f(&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; + Audio_PlaySfxAtPos(&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)) { + 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; + } + } + + spE0 = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx); + if (sLurePos.y <= spE0) { + sLurePos.y = spE0; + 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); + Audio_PlaySfxAtPos(&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; + + 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; + Audio_PlaySfxAtPos(&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); + Audio_PlaySfxAtPos(&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 pad; + f32 sp70; + Vec3f sp64; + Vec3f sp58; + + 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)) { + s8 requiredScopeTemp; + + 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; + Audio_PlaySfxAtPos(&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_RotateYF(sLureRot.y, MTXMODE_NEW); + + if (D_80917206 == 2) { + s8 requiredScopeTemp; + + Matrix_MultVec3f(&sp90, &sp64); + D_80917278.x = sp64.x; + D_80917278.z = sp64.z; + phi_f0 = 10.0f; + } else { + Matrix_MultVec3f(&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) { + s8 requiredScopeTemp; + + 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))) { + s8 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; // must be outside of the block + + 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; + } +} + +s32 func_809033F0(EnFishing* this, GlobalContext* globalCtx, u8 ignorePosCheck) { + s16 i; + s16 count; + f32 scale; + Vec3f pos; + Vec3f vel; + f32 speedXZ; + f32 angle; + + if ((this->actor.world.pos.y < (WATER_SURFACE_Y(globalCtx) - 10.0f)) && !ignorePosCheck) { + return false; + } + + // Necessary to match + if (this->unk_1A4) {} + + if (this->unk_1A4 >= 40.0f) { + count = 40; + scale = 1.2f; + } else { + count = 30; + scale = 1.0f; + } + + for (i = 0; i < count; i++) { + speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale; + angle = Rand_ZeroFloat(6.28f); + + vel.x = sinf(angle) * speedXZ; + vel.z = cosf(angle) * speedXZ; + vel.y = (Rand_ZeroFloat(3.0f) + 3.0f) * scale; + + pos = this->actor.world.pos; + pos.x += vel.x * 3.0f; + pos.y = WATER_SURFACE_Y(globalCtx); + pos.z += vel.z * 3.0f; + + EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel, + (Rand_ZeroFloat(0.02f) + 0.025f) * scale); + } + + pos = this->actor.world.pos; + pos.y = WATER_SURFACE_Y(globalCtx); + + EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &pos, 100.0f, 800.0f, 150, 90); + + this->unk_149 = 30; + + return true; +} + +void func_809036BC(EnFishing* this, GlobalContext* globalCtx) { + s16 count; + s16 i; + f32 scale; + Vec3f pos; + Vec3f vel; + f32 speedXZ; + f32 angle; + + // Necessary to match + if (this->unk_1A4) {} + + if (this->unk_1A4 >= 45.0f) { + count = 30; + scale = 0.5f; + } else { + count = 20; + scale = 0.3f; + } + + for (i = 0; i < count; i++) { + speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale; + angle = Rand_ZeroFloat(6.28f); + + vel.x = sinf(angle) * speedXZ; + vel.z = cosf(angle) * speedXZ; + vel.y = Rand_ZeroFloat(2.0f) + 2.0f; + + pos = this->actor.world.pos; + pos.x += (vel.x * 3.0f); + pos.y += (vel.y * 3.0f); + pos.z += (vel.z * 3.0f); + + EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel, + (Rand_ZeroFloat(0.02f) + 0.025f) * scale); + } +} + +void func_809038A4(EnFishing* this, Input* input) { + Vec3f sp34; + Vec3f sp28; + f32 sp24; + + 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; + + sp24 = SQ(sp34.x) + SQ(sp34.y) + SQ(sp34.z); + + if ((D_8090CD14 == 3) && (this->unk_19A == 0) && (D_8090CD0C == 0)) { + Matrix_RotateYF((-this->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW); + Matrix_MultVec3f(&sp34, &sp28); + + 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; + } + + 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; + } + + 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; + } +} + +void func_80903C60(EnFishing* this, u8 arg1) { + u16 sfxId; + u8 temp; + + if (this->unk_148 == 0) { + temp = this->unk_1A4; + } else { + temp = 2.0f * this->unk_1A4; + } + + 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; + } + } + + Actor_PlaySfxAtPos(&this->actor, sfxId); +} + +void EnFishing_HandleAquariumDialog(EnFishing* this, GlobalContext* globalCtx) { + if (sLinkAge == 1) { + if (gSaveContext.save.unk_EE4 & 0x7F) { + if (gSaveContext.save.unk_EE4 & 0x80) { + this->actor.textId = 0x40B1; + } else { + this->actor.textId = 0x4089; + } + } else { + this->actor.textId = 0x40AE; + } + } else if (gSaveContext.save.unk_EE4 & 0x7F000000) { + if (gSaveContext.save.unk_EE4 & 0x80000000) { + this->actor.textId = 0x40B1; + } else { + this->actor.textId = 0x4089; + } + } else { + this->actor.textId = 0x40AE; + } + + if (this->unk_1CB == 0) { + if (this->unk_1CC == 0) { + this->actor.flags |= ACTOR_FLAG_1; + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + D_8090CCF8 = D_809171CC; + this->unk_1CB = 1; + } else { + func_800B863C(&this->actor, globalCtx); + } + } else { + this->unk_1CC--; + this->actor.flags &= ~ACTOR_FLAG_1; + } + } else if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->unk_1CB = 0; + this->unk_1CC = 20; + } +} + +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 spF8; + 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; + f32 temp_f0; + f32 temp; + f32 temp2; + + this->actor.uncullZoneForward = 700.0f; + this->actor.uncullZoneScale = 50.0f; + + if (this->unk_148 == 0) { + sp118 = (player->actor.speedXZ * 0.15f) + 0.25f; + } else { + sp118 = (player->actor.speedXZ * 0.3f) + 0.25f; + } + + if ((D_80917200 != 0) || (sCameraId != CAM_ID_MAIN) || + ((player->actor.world.pos.z > 1150.0f) && (this->unk_150 != 100))) { + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + this->actor.flags |= ACTOR_FLAG_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; + } + + this->unk_154++; + + for (i = 0; i < ARRAY_COUNT(this->unk_172); i++) { + if (this->unk_172[i] != 0) { + this->unk_172[i]--; + } + } + + if (this->unk_19C != 0) { + this->unk_19C--; + } + + if (this->unk_19A != 0) { + this->unk_19A--; + } + + if (this->unk_198 != 0) { + this->unk_198--; + } + + if (this->unk_149 != 0) { + this->unk_149--; + } + + Math_ApproachF(&this->unk_190, this->unk_188, 1.0f, 0.2f); + + 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); + } + + Math_ApproachS(&this->unk_168, 0, 5, 500); + + if (this->unk_148 == 0) { + Actor_SetScale(&this->actor, this->unk_1A4 * 15.0f * 0.00001f); + + 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 (Message_GetState(&globalCtx->msgCtx) == 0) { + if ((gSaveContext.save.time >= CLOCK_TIME(18, 0)) && (gSaveContext.save.time <= 0xC01B)) { + this->unk_150 = 7; + this->unk_172[3] = Rand_ZeroFloat(150.0f) + 200.0f; + } + if ((gSaveContext.save.time >= CLOCK_TIME(5, 30)) && (gSaveContext.save.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 &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_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); + + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_CATCH_BOOMERANG); + break; + } + } + + Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f); + this->actor.flags &= ~ACTOR_FLAG_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_RotateYF(sLureRot.y, MTXMODE_NEW); + Matrix_MultVec3f(&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.save.time >= 0xB555) && (gSaveContext.save.time <= 0xCAAA)) { + multiplier *= 1.75f; + } else if ((gSaveContext.save.time >= 0x3555) && (gSaveContext.save.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_RotateYF(sLureRot.y, MTXMODE_NEW); + Matrix_MultVec3f(&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) { + s16 phi_v0; + + 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)) { + Actor_PlaySfxAtPos(&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) { + temp2 = (this->unk_1A4 * 3.0f) + 120.0f; + } else { + temp2 = (2.0f * this->unk_1A4) + 120.0f; + } + if (temp2 > 255.0f) { + temp2 = 255.0f; + } + + func_8013EC44(0.0f, temp2, 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)) { + u8 phi_v0_2; + f32 spA4; + + 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_RotateYF(randPlusMinusPoint5Scaled(2.3561945f) + + (((this->actor.yawTowardsPlayer + 0x8000) / 32768.0f) * M_PI), + MTXMODE_NEW); + Matrix_MultVec3f(&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.save.unk_EE4 & 0x400)) || + ((sLinkAge != 1) && (gSaveContext.save.unk_EE4 & 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++; + Cutscene_Start(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_RotateYF((player->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW); + Matrix_MultVec3f(&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_MultVec3f(&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 ((Message_GetState(&globalCtx->msgCtx) == 4) || Message_GetState(&globalCtx->msgCtx) == 0) { + if (Message_ShouldAdvance(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; + Message_StartTextbox(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 ((Message_GetState(&globalCtx->msgCtx) == 4) || Message_GetState(&globalCtx->msgCtx) == 0) { + if (Message_ShouldAdvance(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_UpdateVelocityWithoutGravity(&this->actor); + } + + Actor_UpdatePos(&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; + + Actor_PlaySfxAtPos(&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); + } + } +} + +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_MultVec3f(&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 false; +} + +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_MultVec3f(&sLoachMouthOffset, &this->fishMouthPos); + } +} + +void EnFishing_DrawFish(Actor* thisx, GlobalContext* globalCtx) { + EnFishing* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYF(((this->unk_15A + this->actor.shape.rot.y) / 32768.0f) * M_PI, MTXMODE_APPLY); + Matrix_RotateXFApply(((this->unk_158 + this->actor.shape.rot.x) / 32768.0f) * M_PI); + Matrix_RotateZF(((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_RotateYF((this->unk_164 * (M_PI / 32768)) - (M_PI / 2), MTXMODE_APPLY); + Matrix_Translate(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_Translate(0.0f, 0.0f, 3000.0f, MTXMODE_APPLY); + Matrix_RotateYF(this->unk_164 * (M_PI / 32768), MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -3000.0f, MTXMODE_APPLY); + Matrix_RotateYF(-(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.actorLists[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.actorLists[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 == CAM_ID_MAIN) { + 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_Push(); + + 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_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY); + Matrix_RotateYF(prop->rotY, MTXMODE_APPLY); + Matrix_RotateXFApply(prop->rotX); + Matrix_RotateYF(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_Translate(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_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, 1.0f, prop->scale, MTXMODE_APPLY); + Matrix_RotateYF(prop->lilyPadAngle * (M_PI / 32768), MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 20.0f, MTXMODE_APPLY); + Matrix_RotateYF(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_Translate(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY); + Matrix_RotateYF(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_Pop(); + + 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_Translate(fish->pos.x, fish->pos.y, fish->pos.z, MTXMODE_NEW); + Matrix_RotateYF(((f32)fish->unk_3E * M_PI) / 32768.0f, MTXMODE_APPLY); + Matrix_RotateXFApply((-(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); +} + +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.save.unk_EE4 & 0x100) && !(gSaveContext.save.unk_EE4 & 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (D_809171FC == 0) { + this->unk_154 = 1; + if (sLinkAge != 1) { + gSaveContext.save.unk_EE4 |= 0x200; + } else { + gSaveContext.save.unk_EE4 |= 0x100; + } + } else { + this->unk_154 = 10; + } + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } + break; + + case 1: + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.save.playerData.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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80151938(globalCtx, 0x407F); + this->unk_154 = 4; + } + break; + + case 3: + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + this->unk_154 = 0; + } + if (Message_GetState(&globalCtx->msgCtx) == 6) { + this->unk_154 = 0; + } + break; + + case 4: + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + + globalCtx->interfaceCtx.unk_27E = 1; + globalCtx->startPlayerFishing(globalCtx); + D_809171FC = 1; + D_8090CD04 = 20; + this->unk_154 = 0; + + if ((gSaveContext.save.unk_EE4 & 0xFF0000) < 0xFF0000) { + gSaveContext.save.unk_EE4 += 0x10000; + } + } + break; + + case 10: + if (D_8090CD0C != 0) { + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(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 ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(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 (((Message_GetState(&globalCtx->msgCtx) == 5) || Message_GetState(&globalCtx->msgCtx) == 0) && + Message_ShouldAdvance(globalCtx)) { + s32 getItemId; + + func_801477B4(globalCtx); + + if (D_809171D0 == 0) { + D_809171CC = D_8090CCF0; + D_8090CCF0 = 0.0f; + + if (sLinkAge == 1) { + f32 temp; + + gSaveContext.save.unk_EE4 &= 0xFFFFFF00; + gSaveContext.save.unk_EE4 |= ((s16)D_809171CC & 0x7F); + temp = (gSaveContext.save.unk_EE4 & 0x7F000000) >> 0x18; + if (temp < D_809171CC) { + gSaveContext.save.unk_EE4 &= 0xFFFFFF; + gSaveContext.save.unk_EE4 |= ((s16)D_809171CC & 0x7F) << 0x18; + + if (D_809171D2 == 2) { + gSaveContext.save.unk_EE4 |= 0x80000000; + } + } + + if (D_809171D2 == 2) { + gSaveContext.save.unk_EE4 |= 0x80; + this->unk_154 = 0; + break; + } + } else { + gSaveContext.save.unk_EE4 &= 0xFFFFFF; + gSaveContext.save.unk_EE4 |= ((s16)D_809171CC & 0x7F) << 0x18; + + if (D_809171D2 == 2) { + gSaveContext.save.unk_EE4 |= 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.save.unk_EE4 & 0x400)) { + gSaveContext.save.unk_EE4 |= 0x400; + getItemId = GI_HEART_PIECE; + sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f; + } + } else { + if ((D_809171CC >= 60.0f) && !(gSaveContext.save.unk_EE4 & 0x800)) { + gSaveContext.save.unk_EE4 |= 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; + Actor_PickUp(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + this->unk_154 = 23; + } + break; + + case 20: + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + this->unk_154 = 0; + } + break; + + case 21: + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(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 (Message_GetState(&globalCtx->msgCtx) == 0) { + 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 { + Actor_PickUp(&this->actor, globalCtx, GI_SCALE_GOLD, 2000.0f, 1000.0f); + } + break; + + case 24: + D_8090CCF4 = false; + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + if (D_809171D0 == 0) { + this->unk_154 = 0; + } else { + Message_StartTextbox(globalCtx, 0x409C, NULL); + this->unk_154 = 20; + } + } + break; + } +} + +s16 D_8090D644[] = { 0, 1, 2, 2, 1 }; + +Vec3f sStreamSoundPos = { 670.0f, 0.0f, -600.0f }; + +Vec3s sSinkingLureLocationPos[] = { + { -364, -30, -269 }, + { 1129, 3, -855 }, + { -480, 0, -1055 }, + { 553, -48, -508 }, +}; + +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; + Camera* camera; + Player* player = GET_PLAYER(globalCtx); + Input* input = CONTROLLER1(globalCtx); + + 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) || Message_GetState(&globalCtx->msgCtx)) { + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_20); + } + + if ((this->actor.xzDistToPlayer < 120.0f) || Message_GetState(&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; + Message_StartTextbox(globalCtx, 0x4087, NULL); + } + } + + if (D_8090CD08 == 0) { + gSaveContext.save.unk_EE4 |= 0x1000; + } else if (D_8090CD08 == 1) { + gSaveContext.save.unk_EE4 &= ~0x1000; + } + + if (D_8090CCFC != 0) { + D_8090CCFC--; + if (D_8090CCFC == 0) { + Message_StartTextbox(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 = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, sCameraId, 7); + camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + 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(27); + + spFC.x = sLurePos.x - player->actor.world.pos.x; + spFC.z = sLurePos.z - player->actor.world.pos.z; + lureDistXZ = sqrtf(SQXZ(spFC)); + Matrix_RotateYF(Math_Acot2F(spFC.z, spFC.x), MTXMODE_NEW); + + sp114.x = 0.0f; + sp114.y = 0.0f; + sp114.z = 100.0f; + Matrix_MultVec3f(&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_MultVec3f(&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_MultVec3f(&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, CAM_ID_MAIN); + + camera->eye = sCameraEye; + camera->eyeNext = sCameraEye; + camera->at = sCameraAt; + } + func_80169AFC(globalCtx, sCameraId, 0); + Cutscene_End(globalCtx, &globalCtx->csCtx); + D_8090CD4C = 0; + sCameraId = CAM_ID_MAIN; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.lightSettings.fogNear = 0; + player->unk_B28 = -5; + D_80917200 = 5; + break; + + case 10: + Cutscene_Start(globalCtx, &globalCtx->csCtx); + sCameraId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, sCameraId, 7); + func_800B7298(globalCtx, &this->actor, 4); + camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + 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; + Message_StartTextbox(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 (Message_GetState(&globalCtx->msgCtx) == 0) { + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + + camera->eye = sCameraEye; + camera->eyeNext = sCameraEye; + camera->at = sCameraAt; + func_80169AFC(globalCtx, sCameraId, 0); + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + D_8090CD4C = 0; + sCameraId = CAM_ID_MAIN; + D_8090CD50 = 30; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.lightSettings.fogNear = 0; + } + break; + + case 20: + Cutscene_Start(globalCtx, &globalCtx->csCtx); + sCameraId = Play_CreateSubCamera(globalCtx); + Play_CameraChangeStatus(globalCtx, CAM_ID_MAIN, 1); + Play_CameraChangeStatus(globalCtx, sCameraId, 7); + func_800B7298(globalCtx, &this->actor, 4); + camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + 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; + Message_StartTextbox(globalCtx, 0x409A, NULL); + D_8090CD4C = 21; + D_80911F48 = 45.0f; + D_8090CD50 = 10; + // fallthrough + + case 21: + if ((D_8090CD50 == 0) && Message_ShouldAdvance(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_RotateYF(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_MultVec3f(&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_MultVec3f(&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 ((Message_GetState(&globalCtx->msgCtx) == 4) || Message_GetState(&globalCtx->msgCtx) == 0) { + if (Message_ShouldAdvance(globalCtx)) { + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + + 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); + Cutscene_End(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); // arg2 changed from 7 to 6 in MM + D_8090CD4C = 0; + sCameraId = CAM_ID_MAIN; + player->unk_B28 = -5; + D_80917200 = 5; + D_8090CD54 = 0; + D_809171F6 = 20; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.lightSettings.fogNear = 0; + } + } + } + break; + + case 100: + break; + } + + if (sCameraId != CAM_ID_MAIN) { + 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.lightSettings.fogNear = -0xB2; + } else { + globalCtx->envCtx.lightSettings.fogNear = -0x2E; + } + } else { + func_800F6834(globalCtx, 0); + globalCtx->envCtx.lightSettings.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) && Message_GetState(&globalCtx->msgCtx) == 0 && ((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) { + f32 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.lightSettings.diffuseColor1[0] = globalCtx->envCtx.lightSettings.diffuseColor1[1] = + globalCtx->envCtx.lightSettings.diffuseColor1[2] = D_8090CCD8; + + if ((u8)D_8090CCD0 > 0) { + s32 pad; + s16 i; + Camera* camera = Play_GetCamera(globalCtx, CAM_ID_MAIN); + Vec3f pos; + Vec3f rot; + Vec3f projectedPos; + s32 pad2; + + rot.x = 1.6707964f; + rot.y = 1.0f; + rot.z = (Camera_GetInputDirYaw(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); + + Audio_PlaySfxAtPos(&sStreamSoundProjectedPos, NA_SE_EV_WATER_WALL - SFX_FLAG); + + if (gSaveContext.options.language == 0) { // Added in MM + gSaveContext.minigameScore = D_8090CCF8; + } else { + gSaveContext.minigameScore = (SQ((f32)D_8090CCF8) * 0.0036f) + 0.5f; + } +} + +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_MultVec3f(&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); + } +} + +TexturePtr 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_Translate(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 0cf1d6401..e7fb183c1 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -1,6 +1,12 @@ +/* + * File: z_en_floormas.c + * Overlay: ovl_En_Floormas + * Description: Floormaster + */ + #include "z_en_floormas.h" -#define FLAGS 0x00000405 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnFloormas*)thisx) @@ -9,30 +15,50 @@ void EnFloormas_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFloormas_Update(Actor* thisx, GlobalContext* globalCtx); void EnFloormas_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_808D0B08(EnFloormas* this); void func_808D0B50(EnFloormas* this, GlobalContext* globalCtx); +void func_808D0C14(EnFloormas* this); void func_808D0C58(EnFloormas* this, GlobalContext* globalCtx); +void func_808D0CE4(EnFloormas* this); void func_808D0D70(EnFloormas* this, GlobalContext* globalCtx); +void func_808D0ECC(EnFloormas* this); void func_808D0F14(EnFloormas* this, GlobalContext* globalCtx); +void func_808D0F50(EnFloormas* this); void func_808D0F80(EnFloormas* this, GlobalContext* globalCtx); +void func_808D108C(EnFloormas* this); void func_808D11BC(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1380(EnFloormas* this, GlobalContext* globalCtx); void func_808D1458(EnFloormas* this, GlobalContext* globalCtx); +void func_808D161C(EnFloormas* this); void func_808D1650(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1740(EnFloormas* this); void func_808D17EC(EnFloormas* this, GlobalContext* globalCtx); +void func_808D19D4(EnFloormas* this); void func_808D1B44(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1BCC(EnFloormas* this); void func_808D1C1C(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1D0C(EnFloormas* this); void func_808D1D6C(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1ED4(EnFloormas* this, GlobalContext* globalCtx); void func_808D1F7C(EnFloormas* this, GlobalContext* globalCtx); +void func_808D1FD4(EnFloormas* this); void func_808D2040(EnFloormas* this, GlobalContext* globalCtx); +void func_808D217C(EnFloormas* this, Player* player); void func_808D22C8(EnFloormas* this, GlobalContext* globalCtx); +void func_808D2484(EnFloormas* this); void func_808D24F0(EnFloormas* this, GlobalContext* globalCtx); +void func_808D2700(EnFloormas* this); void func_808D2764(EnFloormas* this, GlobalContext* globalCtx); +void func_808D2A20(EnFloormas* this); void func_808D2AA8(EnFloormas* this, GlobalContext* globalCtx); +void func_808D2AB8(EnFloormas* this); void func_808D2AF4(EnFloormas* this, GlobalContext* globalCtx); void func_808D2C08(EnFloormas* this, GlobalContext* globalCtx); +void func_808D2CDC(EnFloormas* this); void func_808D2D30(EnFloormas* this, GlobalContext* globalCtx); void func_808D2DC0(EnFloormas* this, GlobalContext* globalCtx); +void func_808D3754(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Floormas_InitVars = { ACTOR_EN_FLOORMAS, ACTORCAT_ENEMY, @@ -45,18 +71,29 @@ const ActorInit En_Floormas_InitVars = { (ActorFunc)EnFloormas_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808D38A0 = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7EFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7EFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 25, 40, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808D38CC = { 3, 30, 40, 150 }; +static CollisionCheckInfoInit sColChkInfoInit = { 3, 30, 40, 150 }; -// static DamageTable sDamageTable = { -static DamageTable D_808D38D4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -91,144 +128,1104 @@ static DamageTable D_808D38D4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808D38F4[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 49, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 5500, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -1000, ICHAIN_STOP), }; -#endif +static Vec3f D_808D3900[] = { + { 25.0f, 45.0f, -7.0f }, { 25.0f, 40.0f, -12.0f }, { 25.0f, 35.0f, -2.0f }, + { 10.0f, 20.0f, -4.0f }, { 15.0f, 25.0f, -2.0f }, +}; -extern ColliderCylinderInit D_808D38A0; -extern CollisionCheckInfoInit D_808D38CC; -extern DamageTable D_808D38D4; -extern InitChainEntry D_808D38F4[]; +static s8 D_808D393C[] = { + -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, -1, -1, 3, -1, 4, -1, -1, 5, -1, -1, -1, 6, 7, -1, 8, +}; -extern UNK_TYPE D_06000590; -extern UNK_TYPE D_06000EA4; -extern UNK_TYPE D_060019CC; -extern UNK_TYPE D_06002158; -extern UNK_TYPE D_060039B0; -extern UNK_TYPE D_060041F4; -extern UNK_TYPE D_06008688; -extern UNK_TYPE D_06009244; -extern UNK_TYPE D_06009520; -extern UNK_TYPE D_06009DB0; -extern UNK_TYPE D_0600A054; +static Color_RGBA8 D_808D3958 = { 0, 255, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/EnFloormas_Init.s") +void EnFloormas_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFloormas* this = THIS; + s32 pad; + s32 params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/EnFloormas_Destroy.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 50.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWallmasterSkel, &gWallmasterIdleAnim, this->jointTable, + this->morphTable, WALLMASTER_LIMB_MAX); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D08D0.s") + this->unk_192 = -1600; + params = ENFLOORMAS_GET_8000(&this->actor); + this->actor.params = ENFLOORMAS_GET_7FFF(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0908.s") + if (params != 0) { + this->actor.flags |= ACTOR_FLAG_80; + this->actor.draw = func_808D3754; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0930.s") + if (this->actor.params == ENFLOORMAS_GET_7FFF_10) { + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = func_808D2AA8; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D09CC.s") + this->actor.parent = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_FLOORMAS, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, params + 0x10, -1, this->actor.unk20, NULL); + if (this->actor.parent == NULL) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0A48.s") + this->actor.child = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_FLOORMAS, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, params + 0x10, -1, this->actor.unk20, NULL); + if (this->actor.child == NULL) { + Actor_MarkForDeath(this->actor.parent); + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0B08.s") + this->actor.parent->child = &this->actor; + this->actor.parent->parent = this->actor.child; + this->actor.child->parent = &this->actor; + this->actor.child->child = this->actor.parent; + func_808D0B08(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0B50.s") +void EnFloormas_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFloormas* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0C14.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0C58.s") +void func_808D08D0(EnFloormas* this) { + this->collider.base.colType = COLTYPE_HARD; + this->collider.base.acFlags |= AC_HARD; + this->collider.info.bumper.dmgFlags &= ~0x8000; + this->unk_190 = 40; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0CE4.s") +void func_808D0908(EnFloormas* this) { + this->collider.base.colType = COLTYPE_HIT0; + this->collider.base.acFlags &= ~AC_HARD; + this->collider.info.bumper.dmgFlags |= 0x8000; + this->unk_190 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0D70.s") +void func_808D0930(EnFloormas* this, GlobalContext* globalCtx) { + if (this->actor.scale.x > 0.009f) { + this->actor.shape.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); + func_808D19D4((EnFloormas*)this->actor.child); + func_808D19D4((EnFloormas*)this->actor.parent); + func_808D19D4(this); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KUSAMUSHI_HIDE); + } else { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + func_808D1ED4(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0ECC.s") +void func_808D09CC(EnFloormas* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffFrozenSteamScale = 0.82500005f; + this->drawDmgEffAlpha = 1.0f; + this->collider.base.colType = COLTYPE_HIT3; + this->unk_18E = 80; + this->actor.flags &= ~(ACTOR_FLAG_200 | ACTOR_FLAG_400); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0F14.s") +void func_808D0A48(EnFloormas* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider.base.colType = COLTYPE_HIT0; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, + this->actor.scale.x * 30.000002f, this->actor.scale.x * 20.0f); + if (this->actor.scale.x > 0.009f) { + this->actor.flags |= ACTOR_FLAG_400; + } else { + this->actor.flags |= ACTOR_FLAG_200; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0F50.s") +void func_808D0B08(EnFloormas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterIdleAnim); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D0B50; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D0F80.s") +void func_808D0B50(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if ((this->actor.xzDistToPlayer < 400.0f) && !Actor_IsFacingPlayer(&this->actor, 0x4000)) { + this->unk_190 = this->actor.yawTowardsPlayer; + func_808D108C(this); + } else if ((this->actor.xzDistToPlayer < 280.0f) && Actor_IsFacingPlayer(&this->actor, 0x2000)) { + func_808D1380(this, globalCtx); + } else { + func_808D0C14(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D108C.s") +void func_808D0C14(EnFloormas* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gWallmasterStandUpAnim, -3.0f); + this->actionFunc = func_808D0C58; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D11BC.s") +void func_808D0C58(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actor.scale.x > 0.009f) { + func_808D0CE4(this); + } else if (this->actor.params == ENFLOORMAS_GET_7FFF_20) { + func_808D1D0C(this); + } else { + func_808D1BCC(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1380.s") +void func_808D0CE4(EnFloormas* this) { + if (this->actionFunc != func_808D0F80) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gWallmasterWalkAnim, 1.5f); + } else { + this->skelAnime.playSpeed = 1.5f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1458.s") + this->unk_18E = Rand_S16Offset(2, 4); + this->actor.speedXZ = 1.5f; + this->actionFunc = func_808D0D70; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D14DC.s") +void func_808D0D70(EnFloormas* this, GlobalContext* globalCtx) { + s32 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D161C.s") + SkelAnime_Update(&this->skelAnime); + temp_v0 = Animation_OnFrame(&this->skelAnime, 0.0f); + if ((temp_v0 != 0) && (this->unk_18E != 0)) { + this->unk_18E--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1650.s") + if ((temp_v0 != 0) || Animation_OnFrame(&this->skelAnime, 12.0f) || Animation_OnFrame(&this->skelAnime, 24.0f) || + Animation_OnFrame(&this->skelAnime, 36.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1740.s") + if ((this->actor.xzDistToPlayer < 320.0f) && Actor_IsFacingPlayer(&this->actor, 0x4000)) { + func_808D0F50(this); + } else if (this->actor.bgCheckFlags & 8) { + this->unk_190 = this->actor.wallYaw; + func_808D108C(this); + } else if ((this->actor.xzDistToPlayer < 400.0f) && !Actor_IsFacingPlayer(&this->actor, 0x4000)) { + this->unk_190 = this->actor.yawTowardsPlayer; + func_808D108C(this); + } else if (this->unk_18E == 0) { + func_808D0ECC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D17EC.s") +void func_808D0ECC(EnFloormas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterStopWalkAnim); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D0F14; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D19D4.s") +void func_808D0F14(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + func_808D0B08(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1B44.s") +void func_808D0F50(EnFloormas* this) { + this->unk_18E = 0; + this->actor.speedXZ = 5.0f; + this->skelAnime.playSpeed = 3.0f; + this->actionFunc = func_808D0F80; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1BCC.s") +void func_808D0F80(EnFloormas* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f) || + Animation_OnFrame(&this->skelAnime, 24.0f) || Animation_OnFrame(&this->skelAnime, 36.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1C1C.s") + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0x71C); + if ((this->actor.xzDistToPlayer < 280.0f) && Actor_IsFacingPlayer(&this->actor, 0x2000) && + !(this->actor.bgCheckFlags & 8)) { + func_808D1380(this, globalCtx); + } else if (this->actor.xzDistToPlayer > 400.0f) { + func_808D0CE4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1D0C.s") +void func_808D108C(EnFloormas* this) { + s16 sp36 = this->unk_190 - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1D6C.s") + this->actor.speedXZ = 0.0f; + if (sp36 > 0) { + Animation_MorphToPlayOnce(&this->skelAnime, &gFloormasterTurnAnim, -3.0f); + } else { + Animation_Change(&this->skelAnime, &gFloormasterTurnAnim, -1.0f, Animation_GetLastFrame(&gFloormasterTurnAnim), + 0.0f, ANIMMODE_ONCE, -3.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1ED4.s") + if (this->actor.scale.x > 0.009f) { + this->unk_190 = sp36 * (1.0f / 15.0f); + } else { + this->skelAnime.playSpeed *= 2.0f; + this->unk_190 = sp36 * (2.0f / 15.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1F7C.s") + this->actionFunc = func_808D11BC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D1FD4.s") +void func_808D11BC(EnFloormas* this, GlobalContext* globalCtx) { + f32 frame; + f32 sp30; + f32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2040.s") + if (SkelAnime_Update(&this->skelAnime)) { + func_808D0C14(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D217C.s") + if (((this->skelAnime.playSpeed > 0.0f) && Animation_OnFrame(&this->skelAnime, 21.0f)) || + ((this->skelAnime.playSpeed < 0.0f) && Animation_OnFrame(&this->skelAnime, 6.0f))) { + if (this->actor.scale.x > 0.009f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_WALK); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_WALK); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D22C8.s") + frame = this->skelAnime.curFrame; + if ((frame >= 7.0f) && (frame < 22.0f)) { + sp30 = Math_SinS(this->actor.shape.rot.y + 0x4268); + sp2C = Math_CosS(this->actor.shape.rot.y + 0x4268); + this->actor.shape.rot.y += this->unk_190; + this->actor.world.pos.x -= this->actor.scale.x * 2700.0f * (Math_SinS(this->actor.shape.rot.y + 0x4268) - sp30); + this->actor.world.pos.z -= this->actor.scale.x * 2700.0f * (Math_CosS(this->actor.shape.rot.y + 0x4268) - sp2C); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2484.s") +void func_808D1380(EnFloormas* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gWallmasterHoverAnim, 3.0f, 0.0f, Animation_GetLastFrame(&gWallmasterHoverAnim), + ANIMMODE_ONCE, -3.0f); + this->actor.speedXZ = 0.0f; + this->actor.gravity = 0.0f; + func_808D08D0(this); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 300, 100, 1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_ATTACK); + this->actionFunc = func_808D1458; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D24F0.s") +void func_808D1458(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + func_808D161C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2700.s") + this->actor.shape.rot.x += 0x140; + this->actor.world.pos.y += 10.0f; + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0xAAA); + Math_StepToS(&this->unk_192, 1200, 100); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2764.s") +void func_808D14DC(EnFloormas* this, GlobalContext* globalCtx) { + Vec3f sp34; + Vec3f sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2A20.s") + sp34.x = this->actor.world.pos.x; + sp34.z = this->actor.world.pos.z; + sp34.y = this->actor.floorHeight; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2AA8.s") + sp28.y = 2.0f; + sp28.x = Math_SinS(this->actor.shape.rot.y + 0x6000) * 7.0f; + sp28.z = Math_CosS(this->actor.shape.rot.y + 0x6000) * 7.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2AB8.s") + 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, &gZeroVec3f, 0x1C2, 0x64); + func_800B9010(&this->actor, NA_SE_EN_FLOORMASTER_SLIDING - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2AF4.s") +void func_808D161C(EnFloormas* this) { + this->unk_18E = 25; + this->actor.gravity = -0.15f; + this->actor.speedXZ = 0.5f; + this->actionFunc = func_808D1650; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2B18.s") +void func_808D1650(EnFloormas* this, GlobalContext* globalCtx) { + f32 temp_f0_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2C08.s") + if (this->unk_18E != 0) { + this->unk_18E--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2CDC.s") + Math_StepToF(&this->actor.speedXZ, 15.0f, SQ(this->actor.speedXZ) * (1.0f / 3.0f)); + Math_ScaledStepToS(&this->actor.shape.rot.x, -0x1680, 0x140); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2D30.s") + temp_f0_2 = this->actor.world.pos.y - this->actor.floorHeight; + if (temp_f0_2 < 10.0f) { + this->actor.world.pos.y = this->actor.floorHeight + 10.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2D6C.s") + if (temp_f0_2 < 12.0f) { + func_808D14DC(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2DC0.s") + if ((this->actor.bgCheckFlags & 8) || (this->unk_18E == 0)) { + func_808D1740(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D2E34.s") +void func_808D1740(EnFloormas* this) { + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 1.0f, 41.0f, 42.0f, ANIMMODE_ONCE, 5.0f); + if ((this->actor.speedXZ < 0.0f) || (this->actionFunc != func_808D1650)) { + this->unk_18E = 30; + } else { + this->unk_18E = 45; + } + this->actor.gravity = -1.0f; + this->actionFunc = func_808D17EC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/EnFloormas_Update.s") +void func_808D17EC(EnFloormas* this, GlobalContext* globalCtx) { + s32 sp24 = this->actor.bgCheckFlags & 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D3488.s") + if (this->actor.bgCheckFlags & 2) { + if (this->actor.params != ENFLOORMAS_GET_7FFF_40) { + func_808D0908(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D34C4.s") + if (this->actor.velocity.y < -4.0f) { + if (this->actor.scale.x > 0.009f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_LAND); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_LAND); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/EnFloormas_Draw.s") + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Floormas/func_808D3754.s") + if (sp24 != 0) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 2.0f); + } + + if ((this->actor.speedXZ > 0.0f) && ((this->actor.world.pos.y - this->actor.floorHeight) < 12.0f)) { + func_808D14DC(this, globalCtx); + } + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_18E != 0) { + this->unk_18E--; + } + + if ((this->unk_18E == 0) && (sp24 != 0)) { + if (this->skelAnime.endFrame < 45.0f) { + this->skelAnime.endFrame = Animation_GetLastFrame(&gWallmasterJumpAnim); + } else if (this->actor.params == ENFLOORMAS_GET_7FFF_40) { + func_808D2700(this); + } else { + func_808D0C14(this); + this->unk_194 = 50; + } + } + } + + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x140); + Math_StepToS(&this->unk_192, -1600, 100); +} + +void func_808D19D4(EnFloormas* this) { + Actor* parent; + + this->actor.colorFilterTimer = 0; + this->drawDmgEffAlpha = 0.0f; + Actor_SetScale(&this->actor, 0.004f); + this->actor.flags |= ACTOR_FLAG_10; + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + this->actor.draw = func_808D3754; + } else { + this->actor.draw = EnFloormas_Draw; + } + + parent = this->actor.parent; + this->actor.shape.rot.y = parent->shape.rot.y + 0x5555; + this->actor.world.pos = parent->world.pos; + this->actor.params = ENFLOORMAS_GET_7FFF_10; + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 1.0f, 41.0f, Animation_GetLastFrame(&gWallmasterJumpAnim), + ANIMMODE_ONCE, 0.0f); + this->collider.dim.radius = sCylinderInit.dim.radius * 0.6f; + this->collider.dim.height = sCylinderInit.dim.height * 0.6f; + this->actor.flags &= ~ACTOR_FLAG_400; + this->actor.flags |= ACTOR_FLAG_200; + this->actor.colChkInfo.health = 1; + this->actor.speedXZ = 4.0f; + this->actor.velocity.y = 7.0f; + this->actionFunc = func_808D1B44; +} + +void func_808D1B44(EnFloormas* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 1) { + if (SkelAnime_Update(&this->skelAnime)) { + this->actor.flags |= ACTOR_FLAG_1; + this->unk_194 = 50; + func_808D0C14(this); + } + Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f); + } + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_LAND); + } +} + +void func_808D1BCC(EnFloormas* this) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gWallmasterWalkAnim, 4.5f); + this->actor.speedXZ = 5.0f; + this->actionFunc = func_808D1C1C; +} + +void func_808D1C1C(EnFloormas* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->unk_194 != 0) { + this->unk_194--; + } + + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_WALK); + } + + if (this->unk_194 == 0) { + func_808D1D0C(this); + } else if (this->actor.bgCheckFlags & 8) { + this->unk_190 = this->actor.wallYaw; + func_808D108C(this); + } else if (this->actor.xzDistToPlayer < 120.0f) { + Math_ScaledStepToS(&this->actor.shape.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 0x38E); + } +} + +void func_808D1D0C(EnFloormas* this) { + if (this->actionFunc != func_808D1C1C) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &gWallmasterWalkAnim, 4.5f); + } + this->actor.speedXZ = 5.0f; + this->actionFunc = func_808D1D6C; +} + +void func_808D1D6C(EnFloormas* this, GlobalContext* globalCtx) { + Actor* sp2C; + s32 flags; + + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_WALK); + } + + flags = this->actor.bgCheckFlags & 8; + if (flags) { + this->unk_190 = this->actor.wallYaw; + func_808D108C(this); + } else if (this->actor.params == ENFLOORMAS_GET_7FFF_20) { + if (this->actor.parent->params == ENFLOORMAS_GET_7FFF_40) { + sp2C = this->actor.parent; + } else if (this->actor.child->params == ENFLOORMAS_GET_7FFF_40) { + sp2C = this->actor.child; + } else { + this->actor.params = ENFLOORMAS_GET_7FFF_10; + return; + } + + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, sp2C), 0x38E); + + if (Actor_XZDistanceBetweenActors(&this->actor, sp2C) < 80.0f) { + func_808D2484(this); + } + } else { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0x71C); + if (this->actor.xzDistToPlayer < 80.0f) { + func_808D1FD4(this); + } + } +} + +void func_808D1ED4(EnFloormas* this, GlobalContext* globalCtx) { + Vec3f sp34; + + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + 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, &gZeroVec3f, &gZeroVec3f, 150, -10, 2); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + this->actionFunc = func_808D1F7C; +} + +void func_808D1F7C(EnFloormas* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.0015f)) { + func_808D2A20(this); + } + this->actor.scale.y = this->actor.scale.z = this->actor.scale.x; +} + +void func_808D1FD4(EnFloormas* this) { + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 2.0f, 0.0f, 41.0f, ANIMMODE_ONCE, 0.0f); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D2040; +} + +void func_808D2040(EnFloormas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + if (this->skelAnime.curFrame < 20.0f) { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); + } else if (Animation_OnFrame(&this->skelAnime, 20.0f)) { + this->actor.speedXZ = 5.0f; + this->actor.velocity.y = 7.0f; + } else if (this->actor.bgCheckFlags & 2) { + this->unk_18E = 50; + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_LAND); + func_808D1740(this); + } else if ((this->actor.playerHeightRel < -10.0f) && (this->collider.base.ocFlags1 & OC1_HIT) && + (&player->actor == this->collider.base.oc)) { + globalCtx->grabPlayer(globalCtx, player); + func_808D217C(this, player); + } +} + +void func_808D217C(EnFloormas* this, Player* player) { + Vec3f* ptr; + + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 1.0f, 36.0f, 45.0f, ANIMMODE_ONCE, -3.0f); + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + func_808D08D0(this); + ptr = &D_808D3900[(void)0, gSaveContext.save.playerForm]; + this->actor.home.pos.x = ptr->z * Math_SinS(this->actor.shape.rot.y); + this->actor.home.pos.y = CLAMP(-this->actor.playerHeightRel, ptr->x, ptr->y); + this->actor.home.pos.z = ptr->z * Math_CosS(this->actor.shape.rot.y); + Math_Vec3f_Sum(&player->actor.world.pos, &this->actor.home.pos, &this->actor.world.pos); + this->actor.shape.rot.x = -0x4CE0; + this->actionFunc = func_808D22C8; +} + +void func_808D22C8(EnFloormas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.playSpeed > 0.0f) { + this->skelAnime.playSpeed = -1.0f; + this->skelAnime.endFrame = 36.0f; + this->skelAnime.startFrame = 45.0f; + } else { + this->skelAnime.playSpeed = 1.0f; + this->skelAnime.endFrame = 45.0f; + this->skelAnime.startFrame = 36.0f; + } + } + + Math_Vec3f_Sum(&player->actor.world.pos, &this->actor.home.pos, &this->actor.world.pos); + + if (!(player->stateFlags2 & 0x80) || (player->invincibilityTimer < 0)) { + EnFloormas* parent = (EnFloormas*)this->actor.parent; + EnFloormas* child = (EnFloormas*)this->actor.child; + + if (((parent->actionFunc == func_808D22C8) || (parent->actionFunc == func_808D2AA8)) && + ((child->actionFunc == func_808D22C8) || (child->actionFunc == func_808D2AA8))) { + parent->actor.params = ENFLOORMAS_GET_7FFF_20; + child->actor.params = ENFLOORMAS_GET_7FFF_20; + this->actor.params = ENFLOORMAS_GET_7FFF_40; + } + + this->actor.shape.rot.x = 0; + this->actor.velocity.y = 6.0f; + this->actor.flags |= ACTOR_FLAG_1; + this->actor.speedXZ = -3.0f; + func_808D1740(this); + } else if ((this->unk_190 % 20) == 0) { + func_800B8E58(player, NA_SE_VO_LI_DAMAGE_S + player->ageProperties->unk_92); + globalCtx->damagePlayer(globalCtx, -4); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_STICK - SFX_FLAG); +} + +void func_808D2484(EnFloormas* this) { + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 2.0f, 0.0f, 41.0f, ANIMMODE_ONCE, 0.0f); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_808D24F0; +} + +void func_808D24F0(EnFloormas* this, GlobalContext* globalCtx) { + Actor* phi_s1; + + SkelAnime_Update(&this->skelAnime); + if (this->actor.parent->params == ENFLOORMAS_GET_7FFF_40) { + phi_s1 = this->actor.parent; + } else if (this->actor.child->params == ENFLOORMAS_GET_7FFF_40) { + phi_s1 = this->actor.child; + } else { + if (this->actor.bgCheckFlags & 2) { + this->actor.params = ENFLOORMAS_GET_7FFF_10; + func_808D1740(this); + } + return; + } + + if (Animation_OnFrame(&this->skelAnime, 20.0f)) { + this->actor.speedXZ = 5.0f; + this->actor.velocity.y = 7.0f; + } else if (this->skelAnime.curFrame < 20.0f) { + Math_ApproachS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, phi_s1), 2, 0xE38); + } else if (((phi_s1->world.pos.y - this->actor.world.pos.y) < -10.0f) && + (fabsf(this->actor.world.pos.x - phi_s1->world.pos.x) < 10.0f) && + (fabsf(this->actor.world.pos.z - phi_s1->world.pos.z) < 10.0f)) { + func_808D2A20(this); + this->collider.base.ocFlags1 |= OC1_ON; + } else if (this->actor.bgCheckFlags & 2) { + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_LAND); + func_808D1740(this); + } + + if ((fabsf(this->actor.world.pos.x - phi_s1->world.pos.x) < 5.0f) && + (fabsf(this->actor.world.pos.z - phi_s1->world.pos.z) < 5.0f)) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 2.0f); + } +} + +void func_808D2700(EnFloormas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterIdleAnim); + this->unk_18E = 0; + this->unk_194 = 1500; + this->actor.params = ENFLOORMAS_GET_7FFF_40; + this->actor.speedXZ = 0.0f; + func_808D08D0(this); + this->actionFunc = func_808D2764; +} + +void func_808D2764(EnFloormas* this, GlobalContext* globalCtx) { + EnFloormas* parent; + EnFloormas* child; + s32 phi_a2 = 0; + f32 temp_f2; + + if (this->unk_194 != 0) { + this->unk_194--; + } + + parent = (EnFloormas*)this->actor.parent; + child = (EnFloormas*)this->actor.child; + if (this->unk_194 == 0) { + if (parent->actionFunc != func_808D2AA8) { + func_808D1ED4(parent, globalCtx); + } + if (child->actionFunc != func_808D2AA8) { + func_808D1ED4(child, globalCtx); + } + } else { + if ((parent->actionFunc != func_808D2AA8) && (parent->actionFunc != func_808D1F7C)) { + phi_a2 = 1; + } + + if ((child->actionFunc != func_808D2AA8) && (child->actionFunc != func_808D1F7C)) { + phi_a2++; + } + } + + temp_f2 = this->actor.scale.x; + + if (phi_a2 == 1) { + Math_StepToF(&this->actor.scale.x, 0.007f, 0.0005f); + } else if (phi_a2 == 0) { + Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f); + } + + this->actor.scale.y = this->actor.scale.z = this->actor.scale.x; + + if (((temp_f2 == 0.007f) || (temp_f2 == 0.004f)) && (temp_f2 != this->actor.scale.x)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_EXPAND); + } + + this->collider.dim.radius = sCylinderInit.dim.radius * 100.0f * this->actor.scale.x; + this->collider.dim.height = sCylinderInit.dim.height * 100.0f * this->actor.scale.x; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actor.scale.x >= 0.01f) { + this->actor.flags &= ~ACTOR_FLAG_10; + func_808D0908(this); + this->actor.params = ENFLOORMAS_GET_7FFF_0; + this->actor.flags &= ~ACTOR_FLAG_200; + this->actor.flags |= ACTOR_FLAG_400; + this->actor.colChkInfo.health = sColChkInfoInit.health; + func_808D0C14(this); + } else if (this->unk_18E == 0) { + Animation_PlayOnce(&this->skelAnime, &gFloormasterTapFingerAnim); + this->unk_18E = 1; + } else { + Animation_PlayOnce(&this->skelAnime, &gWallmasterIdleAnim); + this->unk_18E = 0; + } + } + + func_800B9010(&this->actor, NA_SE_EN_FLOORMASTER_RESTORE - SFX_FLAG); +} + +void func_808D2A20(EnFloormas* this) { + EnFloormas* parent = (EnFloormas*)this->actor.parent; + EnFloormas* child = (EnFloormas*)this->actor.child; + + this->drawDmgEffAlpha = 0.0f; + + if ((parent->actionFunc == func_808D2AA8) && (child->actionFunc == func_808D2AA8)) { + func_808D2AB8(parent); + func_808D2AB8(child); + Actor_MarkForDeath(&this->actor); + } else { + this->actor.draw = NULL; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_10); + this->actionFunc = func_808D2AA8; + } +} + +void func_808D2AA8(EnFloormas* this, GlobalContext* globalCtx) { +} + +void func_808D2AB8(EnFloormas* this) { + this->collider.base.atFlags &= ~(AT_HIT | AT_ON); + this->collider.base.acFlags &= ~(AC_HIT | AC_ON); + this->collider.base.ocFlags1 &= ~(OC1_HIT | OC1_ON); + this->actionFunc = func_808D2AF4; +} + +void func_808D2AF4(EnFloormas* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} + +void func_808D2B18(EnFloormas* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gWallmasterDamageAnim, -3.0f); + func_800BE504(&this->actor, &this->collider); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->actor.speedXZ = 5.0f; + this->actor.velocity.y = 5.5f; + if (this->actor.params == ENFLOORMAS_GET_7FFF_40) { + EnFloormas* parent = (EnFloormas*)this->actor.parent; + + if ((parent->actionFunc != func_808D2AA8) && (parent->actor.colChkInfo.health > 0)) { + func_808D2700(parent); + } else { + EnFloormas* child = (EnFloormas*)this->actor.child; + + if ((child->actionFunc != func_808D2AA8) && (child->actor.colChkInfo.health > 0)) { + func_808D2700(child); + } + } + this->actor.params = ENFLOORMAS_GET_7FFF_20; + } + this->actionFunc = func_808D2C08; +} + +void func_808D2C08(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) && (this->actor.bgCheckFlags & 1)) { + if (this->actor.colChkInfo.health == 0) { + func_808D0930(this, globalCtx); + } else { + func_808D2CDC(this); + } + } + + if (Animation_OnFrame(&this->skelAnime, 13.0f)) { + if (this->actor.scale.x > 0.009f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + } + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); +} + +void func_808D2CDC(EnFloormas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterRecoverFromDamageAnim); + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_808D2D30; +} + +void func_808D2D30(EnFloormas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + func_808D0C14(this); + } +} + +void func_808D2D6C(EnFloormas* 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_808D2DC0; +} + +void func_808D2DC0(EnFloormas* this, GlobalContext* globalCtx) { + if (this->unk_18E != 0) { + this->unk_18E--; + } + + if (this->unk_18E == 0) { + func_808D0A48(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + this->collider.base.acFlags |= AC_ON; + func_808D0930(this, globalCtx); + } else { + func_808D0C14(this); + } + } +} + +void func_808D2E34(EnFloormas* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.info); + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + if (this->actor.colChkInfo.damageEffect == 0xE) { + func_808D0908(this); + this->actor.colorFilterTimer = 0; + this->actor.colChkInfo.damage = 4; + this->unk_192 = -1600; + this->actor.gravity = -1.0f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + } + + if (this->collider.base.colType != COLTYPE_HARD) { + if (!Actor_ApplyDamage(&this->actor)) { + if (this->actor.scale.x > 0.009f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_REVERSE); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FLOORMASTER_SM_DEAD); + } + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->actor.flags &= ~ACTOR_FLAG_1; + } else if (this->actor.colChkInfo.damage != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_DAMAGE); + } + + func_808D0A48(this, globalCtx); + + if (this->actor.colChkInfo.damageEffect != 0xF) { + if (this->actor.colChkInfo.damageEffect == 3) { + func_808D09CC(this); + if (this->actor.colChkInfo.health == 0) { + this->unk_18E = 3; + this->collider.base.acFlags &= ~AC_ON; + } + func_808D2D6C(this); + } else if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_18E = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_808D2D6C(this); + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_18E = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffScale = 0.55f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + func_808D2D6C(this); + } else { + if (this->actor.colChkInfo.damageEffect == 2) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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, + (this->actor.scale.x > 0.009f) ? CLEAR_TAG_LARGE_LIGHT_RAYS + : CLEAR_TAG_SMALL_LIGHT_RAYS); + } + func_808D2B18(this); + } + } + } + } + } +} + +void EnFloormas_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFloormas* this = THIS; + s32 pad; + + if (this->actionFunc != func_808D2AA8) { + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + this->actor.speedXZ *= -0.5f; + this->actor.speedXZ = CLAMP_MAX(this->actor.speedXZ, -5.0f); + this->actor.velocity.y = 5.0f; + func_808D1740(this); + } + + func_808D2E34(this, globalCtx); + this->actionFunc(this, globalCtx); + if (this->actionFunc != func_808D2AF4) { + if (this->actionFunc != func_808D2C08) { + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + if (this->actionFunc != func_808D22C8) { + Actor_MoveWithGravity(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, this->actor.scale.x * 3000.0f, 0.0f, 0x1D); + Collider_UpdateCylinder(&this->actor, &this->collider); + if (this->actionFunc == func_808D1650) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actionFunc != func_808D22C8) { + if ((this->actionFunc != func_808D1B44) && (this->actionFunc != func_808D2C08) && + (this->actionFunc != func_808D1F7C)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if ((this->actionFunc != func_808D24F0) || (this->skelAnime.curFrame < 20.0f)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + + Actor_SetFocus(&this->actor, this->actor.scale.x * 2500.0f); + if (this->collider.base.colType == COLTYPE_HARD) { + if (this->unk_190 != 0) { + this->unk_190--; + } + + if (this->unk_190 == 0) { + this->unk_190 = 40; + } + } + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.01375f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + } + } +} + +s32 EnFloormas_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + EnFloormas* this = THIS; + + if (limbIndex == WALLMASTER_LIMB_ROOT) { + pos->z += this->unk_192; + } + + return false; +} + +void EnFloormas_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnFloormas* this = THIS; + + if (D_808D393C[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[D_808D393C[limbIndex]]); + } + + if (limbIndex == WALLMASTER_LIMB_WRIST) { + Matrix_MultVecX(1000.0f, &this->limbPos[9]); + Matrix_MultVecX(-1000.0f, &this->limbPos[10]); + } else if (limbIndex == WALLMASTER_LIMB_HAND) { + Matrix_Push(); + Matrix_Translate(1600.0f, -700.0f, -1700.0f, MTXMODE_APPLY); + Matrix_RotateYF(M_PI / 3, MTXMODE_APPLY); + Matrix_RotateZF(M_PI / 12, MTXMODE_APPLY); + Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY); + + gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList((*gfx)++, gWallmasterLittleFingerDL); + + Matrix_Pop(); + } +} + +void EnFloormas_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFloormas* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->collider.base.colType == COLTYPE_HARD) { + func_800AE2A0(globalCtx, &D_808D3958, this->unk_190 % 40, 40); + } + + POLY_OPA_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnFloormas_OverrideLimbDraw, EnFloormas_PostLimbDraw, &this->actor, POLY_OPA_DISP); + if (this->collider.base.colType == COLTYPE_HARD) { + func_800AE5A0(globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + 100.0f * (this->drawDmgEffScale * this->actor.scale.x), + 100.0f * (this->drawDmgEffFrozenSteamScale * this->actor.scale.x), this->drawDmgEffAlpha, + this->drawDmgEffType); +} + +void func_808D3754(Actor* thisx, GlobalContext* globalCtx) { + EnFloormas* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + if (this->collider.base.colType == COLTYPE_HARD) { + func_800AE5E4(globalCtx, &D_808D3958, this->unk_190 % 40, 40); + } + + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnFloormas_OverrideLimbDraw, EnFloormas_PostLimbDraw, &this->actor, POLY_XLU_DISP); + if (this->collider.base.colType == COLTYPE_HARD) { + func_800AE8EC(globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale * this->actor.scale.x * 100.0f, + this->drawDmgEffFrozenSteamScale * this->actor.scale.x * 100.0f, this->drawDmgEffAlpha, + this->drawDmgEffType); +} diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.h b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.h index 14f2a738b..5c33ba886 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.h +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.h @@ -2,16 +2,38 @@ #define Z_EN_FLOORMAS_H #include "global.h" +#include "objects/object_wallmaster/object_wallmaster.h" struct EnFloormas; typedef void (*EnFloormasActionFunc)(struct EnFloormas*, GlobalContext*); +#define ENFLOORMAS_GET_7FFF(thisx) ((thisx)->params & 0x7FFF) +#define ENFLOORMAS_GET_8000(thisx) ((thisx)->params & 0x8000) + +enum { + /* 0x00 */ ENFLOORMAS_GET_7FFF_0, + /* 0x10 */ ENFLOORMAS_GET_7FFF_10 = 0x10, + /* 0x20 */ ENFLOORMAS_GET_7FFF_20 = 0x20, + /* 0x40 */ ENFLOORMAS_GET_7FFF_40 = 0x40, +}; + typedef struct EnFloormas { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnFloormasActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x214]; + /* 0x018C */ u8 drawDmgEffType; + /* 0x018E */ s16 unk_18E; + /* 0x0190 */ s16 unk_190; + /* 0x0192 */ s16 unk_192; + /* 0x0194 */ s16 unk_194; + /* 0x0196 */ Vec3s jointTable[WALLMASTER_LIMB_MAX]; + /* 0x022C */ Vec3s morphTable[WALLMASTER_LIMB_MAX]; + /* 0x02C4 */ f32 drawDmgEffAlpha; + /* 0x02C8 */ f32 drawDmgEffScale; + /* 0x02CC */ f32 drawDmgEffFrozenSteamScale; + /* 0x02D0 */ Vec3f limbPos[11]; + /* 0x0354 */ ColliderCylinder collider; } EnFloormas; // size = 0x3A0 extern const ActorInit En_Floormas_InitVars; 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 d8293b010..34b43ef66 100644 --- a/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -1,6 +1,12 @@ +/* + * File: z_en_fr.c + * Overlay: ovl_En_Fr + * Description: + */ + #include "z_en_fr.h" -#define FLAGS 0x40000000 +#define FLAGS (ACTOR_FLAG_40000000) #define THIS ((EnFr*)thisx) @@ -8,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, @@ -21,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 &= ~ACTOR_FLAG_40000000; + } else { + this->actor.flags |= ACTOR_FLAG_40000000; + } +} 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 606e5f955..670bafff2 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -5,8 +5,9 @@ */ #include "z_en_fsn.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnFsn*)thisx) @@ -45,24 +46,28 @@ void EnFsn_SelectItem(EnFsn* this, GlobalContext* globalCtx); void EnFsn_LookToShopkeeperFromShelf(EnFsn* this, GlobalContext* globalCtx); void EnFsn_PlayerCannotBuy(EnFsn* this, GlobalContext* globalCtx); -extern AnimationHeader D_06012C34; -extern AnimationHeader D_060131FC; -extern AnimationHeader D_0600C58C; -extern AnimationHeader D_0600E3EC; -extern AnimationHeader D_0600F00C; -extern AnimationHeader D_0600CB3C; -extern AnimationHeader D_0600D354; -extern AnimationHeader D_060138B0; -extern AnimationHeader D_0601430C; -extern AnimationHeader D_0600B9D8; -extern AnimationHeader D_0600C26C; -extern AnimationHeader D_0600DE34; -extern FlexSkeletonHeader D_06013320; -extern UNK_TYPE D_06005BC0; -extern UNK_TYPE D_06006D40; -extern UNK_TYPE D_06007140; -extern Gfx D_0600F180[]; -extern Gfx D_0600F218[]; +typedef enum { + /* 0 */ ENFSN_CUTSCENESTATE_STOPPED, + /* 1 */ ENFSN_CUTSCENESTATE_WAITING, + /* 2 */ ENFSN_CUTSCENESTATE_PLAYING +} EnFsnCutsceneState; + +typedef enum { + /* 00 */ FSN_ANIMATION_IDLE, + /* 01 */ FSN_ANIMATION_SCRATCH_BACK, + /* 02 */ FSN_ANIMATION_TURN_AROUND_FORWARD, + /* 03 */ FSN_ANIMATION_TURN_AROUND_REVERSE, + /* 04 */ FSN_ANIMATION_HANDS_ON_COUNTER_START, + /* 05 */ FSN_ANIMATION_HANDS_ON_COUNTER_LOOP, + /* 06 */ FSN_ANIMATION_HAND_ON_FACE_START, + /* 07 */ FSN_ANIMATION_HAND_ON_FACE_LOOP, + /* 08 */ FSN_ANIMATION_LEAN_FORWARD_START, + /* 09 */ FSN_ANIMATION_LEAN_FORWARD_LOOP, + /* 10 */ FSN_ANIMATION_SLAM_COUNTER_START, + /* 11 */ FSN_ANIMATION_SLAM_COUNTER_LOOP, + /* 12 */ FSN_ANIMATION_MAKE_OFFER, + /* 13 */ FSN_ANIMATION_MAX +} FsnAnimation; const ActorInit En_Fsn_InitVars = { ACTOR_EN_FSN, @@ -76,12 +81,20 @@ const ActorInit En_Fsn_InitVars = { (ActorFunc)EnFsn_Draw, }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06012C34, 1.0f, 0, -1, 0, 0 }, { &D_060131FC, 1.0f, 0, -1, 0, 0 }, { &D_0600C58C, 1.0f, 0, -1, 2, 0 }, - { &D_0600C58C, -1.0f, 0, -1, 2, 0 }, { &D_0600E3EC, 1.0f, 0, -1, 2, 0 }, { &D_0600F00C, 1.0f, 0, -1, 0, 0 }, - { &D_0600CB3C, 1.0f, 0, -1, 2, 0 }, { &D_0600D354, 1.0f, 0, -1, 0, 0 }, { &D_060138B0, 1.0f, 0, -1, 2, 0 }, - { &D_0601430C, 1.0f, 0, -1, 0, 0 }, { &D_0600B9D8, 1.0f, 0, -1, 2, 0 }, { &D_0600C26C, 1.0f, 0, -1, 0, 0 }, - { &D_0600DE34, 1.0f, 0, -1, 2, 0 }, +static AnimationInfoS sAnimations[] = { + { &gFsnIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnScratchBackAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnTurnAroundAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnTurnAroundAnim, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandsOnCounterStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandsOnCounterLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnHandOnFaceStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandOnFaceLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnLeanForwardStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnLeanForwardLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnSlamCounterStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnSlamCounterLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnMakeOfferAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, }; static ColliderCylinderInit sCylinderInit = { @@ -125,10 +138,10 @@ u16 EnFsn_GetWelcome(GlobalContext* globalCtx) { switch (Player_GetMask(globalCtx)) { case PLAYER_MASK_NONE: return 0x29CC; - case PLAYER_MASK_DEKU_MASK: + case PLAYER_MASK_DEKU: return 0x29FC; - case PLAYER_MASK_GORON_MASK: - case PLAYER_MASK_ZORA_MASK: + case PLAYER_MASK_GORON: + case PLAYER_MASK_ZORA: return 0x29FD; case PLAYER_MASK_KAFEIS_MASK: return 0x2364; @@ -140,7 +153,7 @@ u16 EnFsn_GetWelcome(GlobalContext* globalCtx) { void EnFsn_HandleConversationBackroom(EnFsn* this, GlobalContext* globalCtx) { switch (this->textId) { case 0: - if (!(gSaveContext.weekEventReg[0x50] & 0x10)) { + if (!(gSaveContext.save.weekEventReg[80] & 0x10)) { this->textId = 0x29E0; break; } else { @@ -153,7 +166,7 @@ void EnFsn_HandleConversationBackroom(EnFsn* this, GlobalContext* globalCtx) { this->flags |= ENFSN_GIVE_ITEM; this->flags |= ENFSN_GAVE_LETTER_TO_MAMA; this->getItemId = GI_LETTER_TO_MAMA; - gSaveContext.weekEventReg[0x50] |= 0x10; + gSaveContext.save.weekEventReg[80] |= 0x10; this->textId = 0x29F1; break; } else { @@ -173,7 +186,7 @@ void EnFsn_HandleConversationBackroom(EnFsn* this, GlobalContext* globalCtx) { this->flags |= ENFSN_GIVE_ITEM; this->flags |= ENFSN_GAVE_LETTER_TO_MAMA; this->getItemId = GI_LETTER_TO_MAMA; - gSaveContext.weekEventReg[0x50] |= 0x10; + gSaveContext.save.weekEventReg[80] |= 0x10; this->textId = 0x29F1; break; case 0x29F1: @@ -181,7 +194,7 @@ void EnFsn_HandleConversationBackroom(EnFsn* this, GlobalContext* globalCtx) { this->flags |= ENFSN_END_CONVERSATION; break; } - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); if (this->flags & ENFSN_END_CONVERSATION) { if (this->flags & ENFSN_GAVE_LETTER_TO_MAMA) { this->flags &= ~ENFSN_GAVE_LETTER_TO_MAMA; @@ -196,9 +209,10 @@ void EnFsn_HandleConversationBackroom(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_HandleSetupResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx) && this->cutsceneState == 0) { - func_800B84D0(&this->actor, globalCtx); - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx) && + this->cutsceneState == ENFSN_CUTSCENESTATE_STOPPED) { + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); if (ENFSN_IS_SHOP(&this->actor)) { this->actor.textId = 0; } @@ -214,19 +228,19 @@ void EnFsn_UpdateCollider(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_HandleLookToShopkeeperBuyingCutscene(EnFsn* this) { - if (this->cutsceneState == 2 && this->lookToShopkeeperBuyingCutscene != this->cutscene && - this->actor.textId == 0x29CE) { + if ((this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) && + (this->lookToShopkeeperBuyingCutscene != this->cutscene) && (this->actor.textId == 0x29CE)) { ActorCutscene_Stop(this->cutscene); if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); } this->cutscene = this->lookToShopkeeperBuyingCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); - this->cutsceneState = 1; - } else if (this->cutsceneState == 1) { + this->cutsceneState = ENFSN_CUTSCENESTATE_WAITING; + } else if (this->cutsceneState == ENFSN_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_Start(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; } else { ActorCutscene_SetIntentToPlay(this->cutscene); } @@ -287,8 +301,8 @@ void EnFsn_CursorLeftRight(EnFsn* this) { } s16 EnFsn_GetThirdDayItemId(void) { - if (!(gSaveContext.weekEventReg[0x21] & 4) && CURRENT_DAY == 3) { - if (!(gSaveContext.weekEventReg[0x21] & 8) && !(gSaveContext.weekEventReg[0x4F] & 0x40)) { + if (!(gSaveContext.save.weekEventReg[33] & 4) && CURRENT_DAY == 3) { + if (!(gSaveContext.save.weekEventReg[33] & 8) && !(gSaveContext.save.weekEventReg[79] & 0x40)) { return SI_BOMB_BAG_30_1; } return SI_MASK_ALL_NIGHT; @@ -314,23 +328,23 @@ s16 EnFsn_GetStolenItemId(u32 stolenItem) { s32 EnFsn_HasItemsToSell(void) { if (CURRENT_DAY != 3) { - if (((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) || - ((gSaveContext.roomInf[126][5] & 0xFF0000) >> 0x10)) { - return true; - } - return false; - } else { - if (((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) || - ((gSaveContext.roomInf[126][5] & 0xFF0000) >> 0x10) || !(gSaveContext.weekEventReg[0x21] & 4)) { + if ((STOLEN_ITEM_1 != STOLEN_ITEM_NONE) || (STOLEN_ITEM_2 != STOLEN_ITEM_NONE)) { return true; } return false; } + + if ((STOLEN_ITEM_1 != STOLEN_ITEM_NONE) || (STOLEN_ITEM_2 != STOLEN_ITEM_NONE) || + !(gSaveContext.save.weekEventReg[33] & 4)) { + return true; + } + + return false; } void EnFsn_GetShopItemIds(EnFsn* this) { - u32 stolenItem1 = (gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18; - u32 stolenItem2 = (gSaveContext.roomInf[126][5] & 0xFF0000) >> 0x10; + u32 stolenItem1 = STOLEN_ITEM_1; + u32 stolenItem2 = STOLEN_ITEM_2; s16 itemId; this->stolenItem1 = this->stolenItem2 = 0; @@ -372,12 +386,12 @@ void EnFsn_SpawnShopItems(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_EndInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (this->cutsceneState == 2) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); - this->cutsceneState = 0; + this->cutsceneState = ENFSN_CUTSCENESTATE_STOPPED; } - func_800B84D0(&this->actor, globalCtx); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; Interface_ChangeAlpha(50); this->drawCursor = 0; @@ -392,7 +406,7 @@ void EnFsn_EndInteraction(EnFsn* this, GlobalContext* globalCtx) { s32 EnFsn_TestEndInteraction(EnFsn* this, GlobalContext* globalCtx, Input* input) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { this->actor.textId = (CURRENT_DAY == 3) ? 0x29DF : 0x29D1; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); func_80151BB4(globalCtx, 3); this->actionFunc = EnFsn_SetupEndInteraction; return true; @@ -410,14 +424,14 @@ s32 EnFsn_TestCancelOption(EnFsn* this, GlobalContext* globalCtx, Input* input) } void EnFsn_UpdateCursorPos(EnFsn* this, GlobalContext* globalCtx) { - s16 sp2E; - s16 sp2C; + s16 x; + s16 y; f32 xOffset = 0.0f; f32 yOffset = 17.0f; - func_800B8898(globalCtx, &this->items[this->cursorIdx]->actor, &sp2E, &sp2C); - this->cursorPos.x = sp2E + xOffset; - this->cursorPos.y = sp2C + yOffset; + Actor_GetScreenPos(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); + this->cursorPos.x = x + xOffset; + this->cursorPos.y = y + yOffset; this->cursorPos.z = 1.2f; } @@ -427,19 +441,19 @@ s32 EnFsn_FacingShopkeeperDialogResult(EnFsn* this, GlobalContext* globalCtx) { func_8019F208(); if (CURRENT_DAY != 3) { this->actor.textId = 0x29FB; - } else if (gSaveContext.weekEventReg[0x21] & 4) { + } else if (gSaveContext.save.weekEventReg[33] & 4) { this->actor.textId = 0x29FF; - } else if (!(gSaveContext.weekEventReg[0x21] & 8) && !(gSaveContext.weekEventReg[0x4F] & 0x40)) { + } else if (!(gSaveContext.save.weekEventReg[33] & 8) && !(gSaveContext.save.weekEventReg[79] & 0x40)) { this->actor.textId = 0x29D7; } else { this->actor.textId = 0x29D8; } - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); return true; case 1: func_8019F230(); this->actor.textId = (CURRENT_DAY == 3) ? 0x29DF : 0x29D1; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); func_80151BB4(globalCtx, 3); this->actionFunc = EnFsn_SetupEndInteraction; return true; @@ -589,8 +603,7 @@ void EnFsn_UpdateCursorAnim(EnFsn* this) { void EnFsn_UpdateStickDirectionPromptAnim(EnFsn* this) { f32 arrowAnimTween = this->arrowAnimTween; f32 stickAnimTween = this->stickAnimTween; - s32 maxColor = 255; - f32 tmp; + s32 maxColor = 255; //! FAKE: if (this->arrowAnimState == 0) { arrowAnimTween += 0.05f; @@ -617,54 +630,51 @@ void EnFsn_UpdateStickDirectionPromptAnim(EnFsn* this) { stickAnimTween = 0.0f; this->stickAnimState = 0; } - - tmp = 155.0f * arrowAnimTween; - this->stickAnimTween = stickAnimTween; this->stickLeftPrompt.arrowColor.r = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.g = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); - this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100, arrowAnimTween); + this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowColor.r = (maxColor - ((s32)tmp)) & 0xFF; - this->stickRightPrompt.arrowColor.g = (255 - ((s32)tmp)) & 0xFF; + this->stickRightPrompt.arrowTexX = 290.0f; + + this->stickRightPrompt.arrowColor.r = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); + this->stickRightPrompt.arrowColor.g = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowTexX = 290.0f; this->stickLeftPrompt.arrowTexX = 33.0f; this->stickRightPrompt.stickTexX = 274.0f; this->stickRightPrompt.stickTexX += 8.0f * stickAnimTween; + this->stickLeftPrompt.stickTexX = 49.0f; this->stickLeftPrompt.stickTexX -= 8.0f * stickAnimTween; - this->stickLeftPrompt.arrowTexY = this->stickRightPrompt.arrowTexY = 91.0f; - this->stickLeftPrompt.stickTexY = this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + + this->stickRightPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.stickTexY = 95.0f; } void EnFsn_InitShop(EnFsn* this, GlobalContext* globalCtx) { - EnFsn* this2; - s32 maxColor = 255; - if (EnFsn_HasItemsToSell()) { EnFsn_SpawnShopItems(this, globalCtx); - this2 = this; - this2->cursorPos.x = 100.0f; - this2->cursorPos.y = 100.0f; - this2->stickAccumY = 0; - this2->stickAccumX = 0; + this->cursorPos.y = this->cursorPos.x = 100.0f; + this->stickAccumY = 0; + this->stickAccumX = 0; this->cursorPos.z = 1.2f; this->cursorColor.r = 0; this->cursorColor.g = 80; - this->cursorColor.b = maxColor; - this->cursorColor.a = maxColor; + this->cursorColor.b = 255; + this->cursorColor.a = 255; + this->cursorAnimTween = 0.0f; this->cursorAnimState = 0; this->drawCursor = 0; - this->cursorAnimTween = 0.0f; this->stickLeftPrompt.stickColor.r = 200; this->stickLeftPrompt.stickColor.g = 200; @@ -672,8 +682,8 @@ void EnFsn_InitShop(EnFsn* this, GlobalContext* globalCtx) { this->stickLeftPrompt.stickColor.a = 180; this->stickLeftPrompt.stickTexX = 49.0f; this->stickLeftPrompt.stickTexY = 95.0f; - this->stickLeftPrompt.arrowColor.r = maxColor; - this->stickLeftPrompt.arrowColor.g = maxColor; + this->stickLeftPrompt.arrowColor.r = 255; + this->stickLeftPrompt.arrowColor.g = 255; this->stickLeftPrompt.arrowColor.b = 0; this->stickLeftPrompt.arrowColor.a = 200; this->stickLeftPrompt.arrowTexX = 33.0f; @@ -687,7 +697,7 @@ void EnFsn_InitShop(EnFsn* this, GlobalContext* globalCtx) { this->stickRightPrompt.stickColor.a = 180; this->stickRightPrompt.stickTexX = 274.0f; this->stickRightPrompt.stickTexY = 95.0f; - this->stickRightPrompt.arrowColor.r = maxColor; + this->stickRightPrompt.arrowColor.r = 255; this->stickRightPrompt.arrowColor.g = 0; this->stickRightPrompt.arrowColor.b = 0; this->stickRightPrompt.arrowColor.a = 200; @@ -701,77 +711,79 @@ void EnFsn_InitShop(EnFsn* this, GlobalContext* globalCtx) { this->stickAnimTween = this->arrowAnimTween = 0.0f; } this->blinkTimer = 20; - this->animationIdx = 4; + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_START; this->eyeTextureIdx = 0; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); this->actionFunc = EnFsn_Idle; } void EnFsn_Idle(EnFsn* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (this->animationIdx == 4) { + if (this->animationIndex == FSN_ANIMATION_HANDS_ON_COUNTER_START) { s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animationSeg); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); if (curFrame == frameCount) { - this->animationIdx = 5; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); } - } else if (this->flags & ENFSN_HAGGLE) { - dummy:; + return; + } + + if (this->flags & ENFSN_HAGGLE) { this->actionFunc = EnFsn_Haggle; - } else { - dummy2:; - if (func_800B84D0(&this->actor, globalCtx)) { - if (this->cutsceneState == 0) { - if (ActorCutscene_GetCurrentIndex() == 0x7C) { - ActorCutscene_Stop(0x7C); - } - this->cutscene = this->lookToShopkeeperCutscene; - ActorCutscene_SetIntentToPlay(this->cutscene); - this->cutsceneState = 1; + return; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_STOPPED) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); } - this->actor.textId = EnFsn_GetWelcome(globalCtx); - func_801518B0(globalCtx, this->actor.textId, &this->actor); - player->actor.world.pos.x = 1.0f; - player->actor.world.pos.z = -34.0f; - this->actionFunc = EnFsn_BeginInteraction; - } else if (((player->actor.world.pos.x >= -50.0f) && (player->actor.world.pos.x <= 15.0f)) && - (player->actor.world.pos.y > 0.0f) && - ((player->actor.world.pos.z >= -35.0f) && (player->actor.world.pos.z <= -20.0f))) { - func_800B8614(&this->actor, globalCtx, 400.0f); + this->cutscene = this->lookToShopkeeperCutscene; + ActorCutscene_SetIntentToPlay(this->cutscene); + this->cutsceneState = ENFSN_CUTSCENESTATE_WAITING; } + this->actor.textId = EnFsn_GetWelcome(globalCtx); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + player->actor.world.pos.x = 1.0f; + player->actor.world.pos.z = -34.0f; + this->actionFunc = EnFsn_BeginInteraction; + } else if (((player->actor.world.pos.x >= -50.0f) && (player->actor.world.pos.x <= 15.0f)) && + (player->actor.world.pos.y > 0.0f) && + ((player->actor.world.pos.z >= -35.0f) && (player->actor.world.pos.z <= -20.0f))) { + func_800B8614(&this->actor, globalCtx, 400.0f); } } void EnFsn_Haggle(EnFsn* this, GlobalContext* globalCtx) { s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animationSeg); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); if (this->flags & ENFSN_ANGRY) { this->flags &= ~ENFSN_ANGRY; - this->animationIdx = 11; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_SLAM_COUNTER_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); } else { - if (this->animationIdx == 11 && Animation_OnFrame(&this->skelAnime, 18.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_HANKO); + if (this->animationIndex == FSN_ANIMATION_SLAM_COUNTER_LOOP && Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HANKO); } if (this->flags & ENFSN_CALM_DOWN) { this->flags &= ~ENFSN_CALM_DOWN; - this->animationIdx = 5; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); } else if (this->flags & ENFSN_OFFER_FINAL_PRICE) { this->flags &= ~ENFSN_OFFER_FINAL_PRICE; - this->animationIdx = 12; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_MAKE_OFFER; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); } else { - if (this->animationIdx == 12) { + if (this->animationIndex == FSN_ANIMATION_MAKE_OFFER) { if (curFrame == frameCount) { - this->animationIdx = 5; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); } else { if (Animation_OnFrame(&this->skelAnime, 28.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_HANKO); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HANKO); } return; } @@ -784,10 +796,10 @@ void EnFsn_Haggle(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_BeginInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (this->cutsceneState == 1) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; if (Player_GetMask(globalCtx) == PLAYER_MASK_NONE) { func_8011552C(globalCtx, 16); if (EnFsn_HasItemsToSell()) { @@ -806,28 +818,28 @@ void EnFsn_BeginInteraction(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_StartBuying(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); EnFsn_HandleLookToShopkeeperBuyingCutscene(this); - if (talkState == 5 && func_80147624(globalCtx)) { + if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { switch (this->actor.textId) { case 0x29CC: this->actor.textId = 0x29CD; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); break; case 0x29CD: this->actor.textId = 0x29CE; EnFsn_HandleLookToShopkeeperBuyingCutscene(this); - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); break; case 0x29CE: this->actor.textId = 0xFF; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_DeterminePrice; break; case 0x29CF: - player->unk_A87 = 0; + player->exchangeItemId = EXCH_ITEM_NONE; this->actionFunc = EnFsn_SetupDeterminePrice; break; } @@ -835,10 +847,10 @@ void EnFsn_StartBuying(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_AskBuyOrSell(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (talkState == 5) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->actor.textId) { case 0x29CC: if (CURRENT_DAY != 3) { @@ -846,39 +858,39 @@ void EnFsn_AskBuyOrSell(EnFsn* this, GlobalContext* globalCtx) { } else { this->actor.textId = 0x29D2; } - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); break; case 0x29D2: - if (gSaveContext.weekEventReg[0x21] & 4) { + if (gSaveContext.save.weekEventReg[33] & 4) { this->actor.textId = 0x2A01; - } else if (!(gSaveContext.weekEventReg[0x21] & 8) && !(gSaveContext.weekEventReg[0x4F] & 0x40)) { + } else if (!(gSaveContext.save.weekEventReg[33] & 8) && + !(gSaveContext.save.weekEventReg[79] & 0x40)) { this->actor.textId = 0x29D3; } else { this->actor.textId = 0x29D4; } - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); break; case 0x29D3: case 0x29D4: case 0x29FA: case 0x2A01: this->actor.textId = 0x29D5; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); break; } } } else if (talkState == 4) { func_8011552C(globalCtx, 6); - if (!EnFsn_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx)) && func_80147624(globalCtx)) { - u32 trueTmp = true; + if (!EnFsn_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx)) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); - this->isSelling = trueTmp; + this->isSelling = true; this->stickLeftPrompt.isEnabled = false; - this->stickRightPrompt.isEnabled = trueTmp; + this->stickRightPrompt.isEnabled = true; this->actor.textId = 0x29D6; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_FaceShopkeeperSelling; break; case 1: @@ -886,7 +898,7 @@ void EnFsn_AskBuyOrSell(EnFsn* this, GlobalContext* globalCtx) { this->isSelling = false; this->actor.textId = 0x29CE; EnFsn_HandleLookToShopkeeperBuyingCutscene(this); - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_StartBuying; break; } @@ -895,30 +907,30 @@ void EnFsn_AskBuyOrSell(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_SetupDeterminePrice(EnFsn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actor.textId = 0xFF; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_DeterminePrice; } } void EnFsn_DeterminePrice(EnFsn* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - s32 itemGiven; + s32 itemActionParam; u8 buttonItem; - if (func_80152498(&globalCtx->msgCtx) == 16) { - itemGiven = func_80123810(globalCtx); - if (itemGiven > 0) { + if (Message_GetState(&globalCtx->msgCtx) == 16) { + itemActionParam = func_80123810(globalCtx); + if (itemActionParam > PLAYER_AP_NONE) { if (player->heldItemButton == 0) { buttonItem = CUR_FORM_EQUIP(player->heldItemButton); } else { - buttonItem = gSaveContext.equips.buttonItems[0][player->heldItemButton]; + buttonItem = gSaveContext.save.equips.buttonItems[0][player->heldItemButton]; } - this->price = (buttonItem < 40) ? gItemPrices[buttonItem] : 0; + this->price = (buttonItem < ITEM_MOON_TEAR) ? gItemPrices[buttonItem] : 0; if (this->price > 0) { player->actor.textId = 0x29EF; - player->unk_A87 = buttonItem; + player->exchangeItemId = buttonItem; this->actionFunc = EnFsn_MakeOffer; } else { player->actor.textId = 0x29CF; @@ -926,13 +938,13 @@ void EnFsn_DeterminePrice(EnFsn* this, GlobalContext* globalCtx) { } this->actor.textId = player->actor.textId; func_801477B4(globalCtx); - } else if (itemGiven < 0) { + } else if (itemActionParam < PLAYER_AP_NONE) { if (CURRENT_DAY == 3) { this->actor.textId = 0x29DF; } else { this->actor.textId = 0x29D1; } - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); func_80151BB4(globalCtx, 3); this->actionFunc = EnFsn_SetupEndInteraction; } @@ -940,18 +952,18 @@ void EnFsn_DeterminePrice(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_MakeOffer(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); - if (talkState == 4 && func_80147624(globalCtx)) { + if (talkState == 4 && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; - if (this->cutsceneState == 2) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); - this->cutsceneState = 0; + this->cutsceneState = ENFSN_CUTSCENESTATE_STOPPED; } switch (this->price) { case 5: @@ -967,14 +979,14 @@ void EnFsn_MakeOffer(EnFsn* this, GlobalContext* globalCtx) { this->getItemId = GI_RUPEE_PURPLE; break; case 200: - this->getItemId = GI_RUPEE_GOLD; + this->getItemId = GI_RUPEE_HUGE; break; } this->actionFunc = EnFsn_GiveItem; break; case 1: func_8019F230(); - player->unk_A87 = 0; + player->exchangeItemId = EXCH_ITEM_NONE; this->actionFunc = EnFsn_SetupDeterminePrice; break; } @@ -983,24 +995,24 @@ void EnFsn_MakeOffer(EnFsn* this, GlobalContext* globalCtx) { void EnFsn_GiveItem(EnFsn* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { - if (this->isSelling == true && this->items[this->cursorIdx]->getItemId == GI_MASK_ALL_NIGHT) { + if ((this->isSelling == true) && (this->items[this->cursorIdx]->getItemId == GI_MASK_ALL_NIGHT)) { func_80151BB4(globalCtx, 45); func_80151BB4(globalCtx, 3); } this->actor.parent = NULL; if (ENFSN_IS_SHOP(&this->actor) && !this->isSelling) { - func_80123D50(globalCtx, GET_PLAYER(globalCtx), 18, 21); + func_80123D50(globalCtx, GET_PLAYER(globalCtx), ITEM_BOTTLE, PLAYER_AP_BOTTLE); } this->actionFunc = EnFsn_SetupResumeInteraction; } else if (this->isSelling == true) { - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); } else { - func_800B8A1C(&this->actor, globalCtx, this->getItemId, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, this->getItemId, 300.0f, 300.0f); } } void EnFsn_SetupResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (CHECK_QUEST_ITEM(18)) { + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { if (globalCtx->msgCtx.unk120B1 == 0) { EnFsn_HandleSetupResumeInteraction(this, globalCtx); } @@ -1010,7 +1022,7 @@ void EnFsn_SetupResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_ResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (ENFSN_IS_SHOP(&this->actor)) { if (!this->isSelling) { this->cutscene = this->lookToShopkeeperBuyingCutscene; @@ -1019,7 +1031,7 @@ void EnFsn_ResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { this->cutscene = this->lookToShopkeeperCutscene; this->actor.textId = (this->numSellingItems <= 0) ? 0x29DE : 0x29D6; } - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); } @@ -1030,15 +1042,15 @@ void EnFsn_ResumeInteraction(EnFsn* this, GlobalContext* globalCtx) { this->actionFunc = EnFsn_ConverseBackroom; } } else { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } void EnFsn_ResumeShoppingInteraction(EnFsn* this, GlobalContext* globalCtx) { - if (this->cutsceneState == 0) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; if (!this->isSelling) { this->actionFunc = EnFsn_AskCanBuyMore; } else if (this->actor.textId != 0x29D6) { @@ -1060,18 +1072,18 @@ void EnFsn_ResumeShoppingInteraction(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_LookToShelf(EnFsn* this, GlobalContext* globalCtx) { - if (this->cutsceneState == 2) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); } this->cutscene = this->lookToShelfCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); - this->cutsceneState = 1; - } else if (this->cutsceneState == 1) { + this->cutsceneState = ENFSN_CUTSCENESTATE_WAITING; + } else if (this->cutsceneState == ENFSN_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene) != 0) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; EnFsn_UpdateCursorPos(this, globalCtx); this->actionFunc = EnFsn_BrowseShelf; func_80151938(globalCtx, this->items[this->cursorIdx]->actor.textId); @@ -1082,7 +1094,7 @@ void EnFsn_LookToShelf(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_BrowseShelf(EnFsn* this, GlobalContext* globalCtx) { - u8 talkstate = func_80152498(&globalCtx->msgCtx); + u8 talkstate = Message_GetState(&globalCtx->msgCtx); s32 pad; u8 prevCursorIdx = this->cursorIdx; @@ -1108,18 +1120,18 @@ void EnFsn_BrowseShelf(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_LookToShopkeeperFromShelf(EnFsn* this, GlobalContext* globalCtx) { - if (this->cutsceneState == 2) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); } this->cutscene = this->lookToShopkeeperFromShelfCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); - this->cutsceneState = 1; - } else if (this->cutsceneState == 1) { + this->cutsceneState = ENFSN_CUTSCENESTATE_WAITING; + } else if (this->cutsceneState == ENFSN_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; this->stickLeftPrompt.isEnabled = false; this->stickRightPrompt.isEnabled = true; this->actor.textId = 0x29D6; @@ -1137,17 +1149,17 @@ void EnFsn_HandleCanPlayerBuyItem(EnFsn* this, GlobalContext* globalCtx) { switch (item->canBuyFunc(globalCtx, item)) { case CANBUY_RESULT_SUCCESS_2: func_8019F208(); - gSaveContext.weekEventReg[0x21] |= 4; + gSaveContext.save.weekEventReg[33] |= 4; case CANBUY_RESULT_SUCCESS_1: - if (this->cutsceneState == 2) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); - this->cutsceneState = 0; + this->cutsceneState = ENFSN_CUTSCENESTATE_STOPPED; } func_8019F208(); item = this->items[this->cursorIdx]; item->buyFanfareFunc(globalCtx, item); - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; Interface_ChangeAlpha(50); this->drawCursor = 0; @@ -1155,9 +1167,9 @@ void EnFsn_HandleCanPlayerBuyItem(EnFsn* this, GlobalContext* globalCtx) { item = this->items[this->cursorIdx]; item->boughtFunc(globalCtx, item); if (this->stolenItem1 == this->cursorIdx) { - gSaveContext.roomInf[126][5] &= ~0xFF000000; + SET_STOLEN_ITEM_1(STOLEN_ITEM_NONE); } else if (this->stolenItem2 == this->cursorIdx) { - gSaveContext.roomInf[126][5] &= ~0xFF0000; + SET_STOLEN_ITEM_2(STOLEN_ITEM_NONE); } this->numSellingItems--; this->itemIds[this->cursorIdx] = -1; @@ -1177,14 +1189,14 @@ void EnFsn_HandleCanPlayerBuyItem(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_SetupEndInteraction(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); - if ((talkState == 5 || talkState == 6) && func_80147624(globalCtx)) { - if (CHECK_QUEST_ITEM(18)) { + if ((talkState == 5 || talkState == 6) && Message_ShouldAdvance(globalCtx)) { + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { if (globalCtx->msgCtx.unk120B1 == 0) { EnFsn_EndInteraction(this, globalCtx); } else { - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; } } else { @@ -1194,11 +1206,11 @@ void EnFsn_SetupEndInteraction(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_SelectItem(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (EnFsn_TakeItemOffShelf(this) && talkState == 4) { func_8011552C(globalCtx, 6); - if (!EnFsn_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && func_80147624(globalCtx)) { + if (!EnFsn_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: EnFsn_HandleCanPlayerBuyItem(this, globalCtx); @@ -1213,19 +1225,19 @@ void EnFsn_SelectItem(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_PlayerCannotBuy(EnFsn* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->actionFunc = this->tmpActionFunc; func_80151938(globalCtx, this->items[this->cursorIdx]->actor.textId); } } void EnFsn_AskCanBuyMore(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); - if (this->cutsceneState == 0) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; } else { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -1235,28 +1247,28 @@ void EnFsn_AskCanBuyMore(EnFsn* this, GlobalContext* globalCtx) { } } if (talkState == 4) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); this->actor.textId = 0xFF; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_DeterminePrice; break; case 1: func_8019F230(); this->actor.textId = (CURRENT_DAY == 3) ? 0x29DF : 0x29D1; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); func_80151BB4(globalCtx, 3); break; } } - } else if ((talkState == 5 || talkState == 6) && func_80147624(globalCtx)) { - if (CHECK_QUEST_ITEM(18)) { + } else if ((talkState == 5 || talkState == 6) && Message_ShouldAdvance(globalCtx)) { + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { if (globalCtx->msgCtx.unk120B1 == 0) { EnFsn_EndInteraction(this, globalCtx); } else { - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; } } else { @@ -1266,12 +1278,12 @@ void EnFsn_AskCanBuyMore(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_AskCanBuyAterRunningOutOfItems(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); - if (this->cutsceneState == 0) { + if (this->cutsceneState == ENFSN_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); - this->cutsceneState = 2; + this->cutsceneState = ENFSN_CUTSCENESTATE_PLAYING; } else { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -1281,29 +1293,29 @@ void EnFsn_AskCanBuyAterRunningOutOfItems(EnFsn* this, GlobalContext* globalCtx) } } if (talkState == 4) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); this->isSelling = false; this->actor.textId = 0x29CE; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); this->actionFunc = EnFsn_StartBuying; break; case 1: func_8019F230(); this->actor.textId = (CURRENT_DAY == 3) ? 0x29DF : 0x29D1; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); func_80151BB4(globalCtx, 3); break; } } - } else if ((talkState == 5 || talkState == 6) && func_80147624(globalCtx)) { - if (CHECK_QUEST_ITEM(18)) { + } else if ((talkState == 5 || talkState == 6) && Message_ShouldAdvance(globalCtx)) { + if (CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { if (globalCtx->msgCtx.unk120B1 == 0) { EnFsn_EndInteraction(this, globalCtx); } else { - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; } } else { @@ -1313,13 +1325,13 @@ void EnFsn_AskCanBuyAterRunningOutOfItems(EnFsn* this, GlobalContext* globalCtx) } void EnFsn_FaceShopkeeperSelling(EnFsn* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); u8 cursorIdx; if (talkState == 4) { func_8011552C(globalCtx, 6); if (!EnFsn_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx)) && - (!func_80147624(globalCtx) || !EnFsn_FacingShopkeeperDialogResult(this, globalCtx)) && + (!Message_ShouldAdvance(globalCtx) || !EnFsn_FacingShopkeeperDialogResult(this, globalCtx)) && this->stickAccumX > 0) { cursorIdx = EnFsn_SetCursorIndexFromNeutral(this); if (cursorIdx != CURSOR_INVALID) { @@ -1330,21 +1342,21 @@ void EnFsn_FaceShopkeeperSelling(EnFsn* this, GlobalContext* globalCtx) { play_sound(NA_SE_SY_CURSOR); } } - } else if (talkState == 5 && func_80147624(globalCtx)) { + } else if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { this->actor.textId = 0x29D6; - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); if (globalCtx) {} } } void EnFsn_SetupEndInteractionImmediately(EnFsn* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { EnFsn_EndInteraction(this, globalCtx); } } void EnFsn_IdleBackroom(EnFsn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->textId = 0; EnFsn_HandleConversationBackroom(this, globalCtx); this->actionFunc = EnFsn_ConverseBackroom; @@ -1354,15 +1366,15 @@ void EnFsn_IdleBackroom(EnFsn* this, GlobalContext* globalCtx) { } void EnFsn_ConverseBackroom(EnFsn* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { if (this->flags & ENFSN_END_CONVERSATION) { this->flags &= ~ENFSN_END_CONVERSATION; - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = EnFsn_IdleBackroom; } else if (this->flags & ENFSN_GIVE_ITEM) { this->flags &= ~ENFSN_GIVE_ITEM; - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = EnFsn_GiveItem; } else { @@ -1394,18 +1406,19 @@ void EnFsn_Blink(EnFsn* this) { } void EnFsn_Init(Actor* thisx, GlobalContext* globalCtx) { - EnFsn* this = THIS; s32 pad; + EnFsn* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013320, &D_06012C34, this->jointTable, this->morphTable, 19); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFsnSkel, &gFsnIdleAnim, this->jointTable, this->morphTable, + FSN_LIMB_MAX + 1); if (ENFSN_IS_SHOP(&this->actor)) { this->actor.shape.rot.y = BINANG_ROT180(this->actor.shape.rot.y); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; EnFsn_GetCutscenes(this); EnFsn_InitShop(this, globalCtx); } else { - if ((gSaveContext.weekEventReg[0x21] & 8) || (gSaveContext.weekEventReg[0x4F] & 0x40)) { + if ((gSaveContext.save.weekEventReg[33] & 8) || (gSaveContext.save.weekEventReg[79] & 0x40)) { Actor_MarkForDeath(&this->actor); return; } @@ -1413,10 +1426,10 @@ void EnFsn_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->blinkTimer = 20; this->eyeTextureIdx = 0; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->actor.targetMode = 0; - this->animationIdx = 0; - func_8013BC6C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = FSN_ANIMATION_IDLE; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); this->actionFunc = EnFsn_IdleBackroom; } } @@ -1431,9 +1444,9 @@ void EnFsn_Update(Actor* thisx, GlobalContext* globalCtx) { EnFsn* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_800E9250(globalCtx, &this->actor, &this->headRot, &this->unk27A, this->actor.focus.pos); - func_8013D9C8(globalCtx, this->limbRotYTable, this->limbRotZTable, 19); + SubS_FillLimbRotTables(globalCtx, this->limbRotYTable, this->limbRotZTable, ARRAY_COUNT(this->limbRotYTable)); EnFsn_Blink(this); if (ENFSN_IS_SHOP(&this->actor) && EnFsn_HasItemsToSell()) { EnFsn_UpdateJoystickInputState(this, globalCtx); @@ -1448,7 +1461,10 @@ void EnFsn_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnFsn_DrawCursor(EnFsn* this, GlobalContext* globalCtx, f32 x, f32 y, f32 z, u8 drawCursor) { - s32 ulx, uly, lrx, lry; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; f32 w; s32 dsdx; s32 pad; @@ -1458,7 +1474,7 @@ void EnFsn_DrawCursor(EnFsn* this, GlobalContext* globalCtx, f32 x, f32 y, f32 z func_8012C654(globalCtx->state.gfxCtx); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, this->cursorColor.r, this->cursorColor.g, this->cursorColor.b, this->cursorColor.a); - gDPLoadTextureBlock_4b(OVERLAY_DISP++, &D_0401F740, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, + gDPLoadTextureBlock_4b(OVERLAY_DISP++, gSelectionCursorTex, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD); w = 16.0f * z; ulx = (x - w) * 4.0f; @@ -1474,9 +1490,14 @@ void EnFsn_DrawCursor(EnFsn* this, GlobalContext* globalCtx, f32 x, f32 y, f32 z void EnFsn_DrawTextRec(GlobalContext* globalCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t, f32 dx, f32 dy) { f32 unk; - s32 ulx, uly, lrx, lry; - f32 w, h; - s32 dsdx, dtdy; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; + f32 w; + f32 h; + s32 dsdx; + s32 dtdy; OPEN_DISPS(globalCtx->state.gfxCtx); gDPPipeSync(OVERLAY_DISP++); @@ -1506,15 +1527,9 @@ void EnFsn_DrawStickDirectionPrompts(EnFsn* this, GlobalContext* globalCtx) { if (drawStickRightPrompt || drawStickLeftPrompt) { func_8012C654(globalCtx->state.gfxCtx); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F8C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 191, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 23 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnFsn_DrawTextRec(globalCtx, this->stickLeftPrompt.arrowColor.r, this->stickLeftPrompt.arrowColor.g, this->stickLeftPrompt.arrowColor.b, this->stickLeftPrompt.arrowColor.a, @@ -1527,15 +1542,9 @@ void EnFsn_DrawStickDirectionPrompts(EnFsn* this, GlobalContext* globalCtx) { this->stickRightPrompt.arrowTexX, this->stickRightPrompt.arrowTexY, this->stickRightPrompt.texZ, 0, 0, 1.0f, 1.0f); } - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F7C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 127, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 15 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnFsn_DrawTextRec(globalCtx, this->stickLeftPrompt.stickColor.r, this->stickLeftPrompt.stickColor.g, this->stickLeftPrompt.stickColor.b, this->stickLeftPrompt.stickColor.a, @@ -1554,21 +1563,20 @@ void EnFsn_DrawStickDirectionPrompts(EnFsn* this, GlobalContext* globalCtx) { s32 EnFsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnFsn* this = THIS; - s16 tmp; s32 limbRotTableIdx; - if (limbIndex == 16) { - Matrix_InsertXRotation_s(this->headRot.y, MTXMODE_APPLY); + if (limbIndex == FSN_LIMB_HEAD) { + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); } if (ENFSN_IS_BACKROOM(&this->actor)) { switch (limbIndex) { - case 8: + case FSN_LIMB_TORSO: limbRotTableIdx = 0; break; - case 11: + case FSN_LIMB_LEFT_HAND: limbRotTableIdx = 1; break; - case 16: + case FSN_LIMB_HEAD: limbRotTableIdx = 2; break; default: @@ -1576,37 +1584,35 @@ s32 EnFsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, break; } if (limbRotTableIdx < 9) { - tmp = (s32)(Math_SinS(this->limbRotYTable[limbRotTableIdx]) * 200.0f); - rot->y += tmp; - tmp = (s32)(Math_CosS(this->limbRotZTable[limbRotTableIdx]) * 200.0f); - rot->z += tmp; + rot->y += (s16)(Math_SinS(this->limbRotYTable[limbRotTableIdx]) * 200.0f); + rot->z += (s16)(Math_CosS(this->limbRotZTable[limbRotTableIdx]) * 200.0f); } } - if (limbIndex == 17) { + if (limbIndex == FSN_LIMB_TOUPEE) { *dList = NULL; } - return 0; + return false; } void EnFsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnFsn* this = THIS; - if (limbIndex == 16) { + if (limbIndex == FSN_LIMB_HEAD) { this->actor.focus.pos.x = this->actor.world.pos.x; this->actor.focus.pos.y = this->actor.world.pos.y + 60.0f; this->actor.focus.pos.z = this->actor.world.pos.z; OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_0600F180); - gSPDisplayList(POLY_OPA_DISP++, D_0600F218); + gSPDisplayList(POLY_OPA_DISP++, gFsnGlassesFrameDL); + gSPDisplayList(POLY_OPA_DISP++, gFsnGlassesLensesDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } } void EnFsn_Draw(Actor* thisx, GlobalContext* globalCtx) { - static void* sEyeTextures[] = { &D_06005BC0, &D_06006D40, &D_06007140 }; - EnFsn* this = THIS; + static TexturePtr sEyeTextures[] = { gFsnEyeOpenTex, gFsnEyeHalfTex, gFsnEyeClosedTex }; s32 pad; + EnFsn* this = THIS; s16 i; OPEN_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.h b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.h index 139e145da..5fabf59ad 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.h +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.h @@ -3,6 +3,7 @@ #include "global.h" #include "overlays/actors/ovl_En_GirlA/z_en_girla.h" +#include "objects/object_fsn/object_fsn.h" #define ENFSN_IS_BACKROOM(thisx) ((thisx)->params & 1) #define ENFSN_IS_SHOP(thisx) (!((thisx)->params & 1)) @@ -27,8 +28,8 @@ typedef struct EnFsn { /* 0x24E */ s16 limbRotZTable[19]; /* 0x274 */ Vec3s headRot; /* 0x27A */ Vec3s unk27A; // Set but never used - /* 0x280 */ Vec3s jointTable[19]; - /* 0x2F2 */ Vec3s morphTable[19]; + /* 0x280 */ Vec3s jointTable[FSN_LIMB_MAX + 1]; + /* 0x2F2 */ Vec3s morphTable[FSN_LIMB_MAX + 1]; /* 0x364 */ s16 eyeTextureIdx; /* 0x366 */ s16 blinkTimer; /* 0x368 */ s16 cutsceneState; @@ -63,7 +64,7 @@ typedef struct EnFsn { /* 0x444 */ u8 arrowAnimState; /* 0x445 */ u8 stickAnimState; /* 0x448 */ f32 shopItemSelectedTween; - /* 0x44C */ s16 animationIdx; + /* 0x44C */ s16 animationIndex; /* 0x44E */ u16 flags; } EnFsn; // size = 0x450 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 550a54f62..77450f9ab 100644 --- a/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -4,14 +4,15 @@ * Description: Honey & Darling */ +#include "z_en_fu.h" #include "overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.h" #include "overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.h" -#include "overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.h" #include "overlays/actors/ovl_Bg_Fu_Kaiten/z_bg_fu_kaiten.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" -#include "z_en_fu.h" +#include "objects/object_mu/object_mu.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x0A000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000 | ACTOR_FLAG_8000000) #define THIS ((EnFu*)thisx) @@ -54,16 +55,6 @@ void func_80964694(EnFu* this, EnFuUnkStruct* ptr, Vec3f* arg2, s32 len); void func_809647EC(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len); void func_80964950(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len); -extern AnimationHeader D_06001F74; -extern AnimationHeader D_06002F64; -extern AnimationHeader D_06004904; -extern AnimationHeader D_06005304; -extern AnimationHeader D_060053E0; -extern Gfx D_0600B0A0[]; -extern Gfx D_0600B0E0[]; -extern FlexSkeletonHeader D_0600B2B0; -extern AnimationHeader D_0600BAC4; - const ActorInit En_Fu_InitVars = { ACTOR_EN_FU, ACTORCAT_NPC, @@ -82,11 +73,14 @@ static Vec3f D_80964B0C = { 0.0f, 60.0f, -8.0f }; static Vec3f D_80964B18 = { 0.0f, 55.0f, 12.0f }; static Vec3f D_80964B24 = { 0.0f, 60.0f, 0.0f }; -static ActorAnimationEntry sAnimations[] = { - { &D_060053E0, 1.0f, 0.0f, 0.0f, 0, -4.0f }, { &D_06001F74, 1.0f, 0.0f, 0.0f, 0, -4.0f }, - { &D_06002F64, 1.0f, 0.0f, 0.0f, 0, -4.0f }, { &D_06004904, 1.0f, 0.0f, 0.0f, 0, 0.0f }, - { &D_06005304, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &D_06005304, 1.0f, 0.0f, 0.0f, 0, 0.0f }, - { &D_0600BAC4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, +static AnimationInfo sAnimations[] = { + { &object_mu_Anim_0053E0, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_mu_Anim_001F74, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_mu_Anim_002F64, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_mu_Anim_004904, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_mu_Anim_005304, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &object_mu_Anim_005304, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_mu_Anim_00BAC4, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, }; static ColliderCylinderInit sCylinderInit = { @@ -117,7 +111,7 @@ void func_809616E0(EnFu* this, GlobalContext* globalCtx) { s16 spA0 = false; Vec3f sp94; - if ((gSaveContext.playerForm == PLAYER_FORM_DEKU) && (CURRENT_DAY == 3)) { + if ((gSaveContext.save.playerForm == PLAYER_FORM_DEKU) && (CURRENT_DAY == 3)) { spA0 = true; } this->unk_54C = 0; @@ -181,14 +175,14 @@ void func_809619D0(EnFu* this, GlobalContext* globalCtx) { } this->unk_520 = path->count; - this->unk_538 = (Vec3s*)Lib_SegmentedToVirtual(path->points); + this->unk_538 = Lib_SegmentedToVirtual(path->points); func_809616E0(this, globalCtx); } void EnFu_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnFu* this = THIS; - Actor* fuKaiten = globalCtx->actorCtx.actorList[ACTORCAT_BG].first; + Actor* fuKaiten = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; while (fuKaiten != NULL) { if (fuKaiten->id == ACTOR_BG_FU_KAITEN) { @@ -199,14 +193,14 @@ void EnFu_Init(Actor* thisx, GlobalContext* globalCtx) { } if (fuKaiten != NULL) { - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 36.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600B2B0, &D_06001F74, this->jointTable, this->morphTable, - 21); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_mu_Skel_00B2B0, &object_mu_Anim_001F74, + this->jointTable, this->morphTable, 21); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->actor.colChkInfo.mass = MASS_IMMOVABLE; Actor_SetScale(&this->actor, 0.01f); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.gravity = -0.2f; this->actor.shape.rot.y += 0x4000; this->actor.world.rot = this->actor.shape.rot; @@ -235,8 +229,8 @@ void EnFu_Init(Actor* thisx, GlobalContext* globalCtx) { void EnFu_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnFu* this = THIS; - gSaveContext.weekEventReg[63] &= (u8)~0x1; - gSaveContext.weekEventReg[8] &= (u8)~0x1; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[8] &= (u8)~1; Collider_DestroyCylinder(globalCtx, &this->collider); } @@ -257,14 +251,14 @@ s32 func_80961D10(EnFu* this) { } void func_80961D7C(GlobalContext* globalCtx) { - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; while (explosive != NULL) { if ((explosive->id == ACTOR_EN_BOM) && (explosive->bgCheckFlags & 1)) { EnBom* bomb = (EnBom*)explosive; if (bomb->actor.floorBgId != BGCHECK_SCENE) { - DynaPolyActor* fuKago = BgCheck_GetActorOfMesh(&globalCtx->colCtx, bomb->actor.floorBgId); + DynaPolyActor* fuKago = DynaPoly_GetActor(&globalCtx->colCtx, bomb->actor.floorBgId); if ((fuKago != NULL) && (fuKago->actor.id == ACTOR_EN_FU_KAGO)) { Math_SmoothStepToF(&bomb->actor.world.pos.x, fuKago->actor.world.pos.x, 0.1f, 1.0f, 0.5f); @@ -277,7 +271,7 @@ void func_80961D7C(GlobalContext* globalCtx) { } void func_80961E88(GlobalContext* globalCtx) { - Actor* explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; while (explosive != NULL) { Actor_MarkForDeath(explosive); @@ -286,7 +280,7 @@ void func_80961E88(GlobalContext* globalCtx) { } void func_80961EC8(GlobalContext* globalCtx) { - Actor* fuMato = globalCtx->actorCtx.actorList[ACTORCAT_BG].first; + Actor* fuMato = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; while (fuMato != NULL) { if (fuMato->id == ACTOR_EN_FU_MATO) { @@ -297,7 +291,7 @@ void func_80961EC8(GlobalContext* globalCtx) { } void func_80961F00(GlobalContext* globalCtx) { - Actor* fuKago = globalCtx->actorCtx.actorList[ACTORCAT_BG].first; + Actor* fuKago = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; while (fuKago != NULL) { if (fuKago->id == ACTOR_EN_FU_KAGO) { @@ -367,17 +361,17 @@ void func_8096209C(EnFu* this, GlobalContext* globalCtx) { sp34 = D_80964B24; } - Matrix_StatePush(); - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); - Matrix_MultiplyVector3fByState(&sp34, &this->actor.focus.pos); - Matrix_StatePop(); + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sp34, &this->actor.focus.pos); + Matrix_Pop(); this->actor.focus.pos.x += this->actor.world.pos.x; this->actor.focus.pos.y += this->actor.world.pos.y; this->actor.focus.pos.z += this->actor.world.pos.z; } void func_809622FC(EnFu* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actionFunc = func_80962340; } @@ -385,40 +379,40 @@ void func_80962340(EnFu* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (this->unk_54A == 2) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->unk_54A == 2) { if (this->unk_552 == 0x287D) { - if (gSaveContext.playerForm == PLAYER_FORM_DEKU) { - func_801518B0(globalCtx, 0x287E, &this->actor); + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { + Message_StartTextbox(globalCtx, 0x287E, &this->actor); this->unk_552 = 0x287E; - } else if ((CURRENT_DAY == 3) && (gSaveContext.weekEventReg[22] & 0x10) && - (gSaveContext.weekEventReg[22] & 0x20)) { - if ((gSaveContext.weekEventReg[22] & 0x40)) { - func_801518B0(globalCtx, 0x2883, &this->actor); + } else if ((CURRENT_DAY == 3) && (gSaveContext.save.weekEventReg[22] & 0x10) && + (gSaveContext.save.weekEventReg[22] & 0x20)) { + if ((gSaveContext.save.weekEventReg[22] & 0x40)) { + Message_StartTextbox(globalCtx, 0x2883, &this->actor); this->unk_552 = 0x2883; } else { - func_801518B0(globalCtx, 0x2880, &this->actor); + Message_StartTextbox(globalCtx, 0x2880, &this->actor); this->unk_552 = 0x2880; } } else { - func_801518B0(globalCtx, 0x287E, &this->actor); + Message_StartTextbox(globalCtx, 0x287E, &this->actor); this->unk_552 = 0x287E; } } else if ((gSaveContext.unk_3DE0[4] == 0) && (this->unk_552 != 0x2888)) { - func_801518B0(globalCtx, 0x2886, &this->actor); + Message_StartTextbox(globalCtx, 0x2886, &this->actor); this->unk_552 = 0x2886; } else { - func_801518B0(globalCtx, 0x2889, &this->actor); + Message_StartTextbox(globalCtx, 0x2889, &this->actor); this->unk_552 = 0x2889; } - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; player->stateFlags1 &= ~0x20; this->unk_54A = 1; } else { - func_801518B0(globalCtx, 0x283C, &this->actor); + Message_StartTextbox(globalCtx, 0x283C, &this->actor); this->unk_552 = 0x283C; } func_809628BC(this); @@ -431,21 +425,21 @@ void func_80962340(EnFu* this, GlobalContext* globalCtx) { } void func_80962588(EnFu* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx) && (this->unk_552 == 0x2871)) { + if (Message_ShouldAdvance(globalCtx) && (this->unk_552 == 0x2871)) { if (1) {} if (globalCtx->msgCtx.choiceIndex == 0) { - if (gSaveContext.rupees >= 10) { + if (gSaveContext.save.playerData.rupees >= 10) { func_8019F208(); func_801159EC(-10); func_80963DE4(this, globalCtx); } else { play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0x2873, &this->actor); + Message_StartTextbox(globalCtx, 0x2873, &this->actor); this->unk_552 = 0x2873; } } else { func_8019F230(); - func_801518B0(globalCtx, 0x2872, &this->actor); + Message_StartTextbox(globalCtx, 0x2872, &this->actor); this->unk_552 = 0x2872; } } @@ -454,7 +448,7 @@ void func_80962588(EnFu* this, GlobalContext* globalCtx) { void func_80962660(EnFu* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_552) { case 0x283C: func_80963F44(this, globalCtx); @@ -473,7 +467,7 @@ void func_80962660(EnFu* this, GlobalContext* globalCtx) { break; case 0x2846: - func_801518B0(globalCtx, 0x2849, &this->actor); + Message_StartTextbox(globalCtx, 0x2849, &this->actor); this->unk_552 = 0x2849; break; @@ -524,7 +518,7 @@ void func_80962660(EnFu* this, GlobalContext* globalCtx) { case 0x286A: case 0x286C: case 0x286E: - func_801518B0(globalCtx, 0x2871, &this->actor); + Message_StartTextbox(globalCtx, 0x2871, &this->actor); this->unk_552 = 0x2871; break; @@ -532,18 +526,18 @@ void func_80962660(EnFu* this, GlobalContext* globalCtx) { case 0x2878: case 0x287A: case 0x287C: - func_801518B0(globalCtx, 0x287D, &this->actor); + Message_StartTextbox(globalCtx, 0x287D, &this->actor); this->unk_552 = 0x287D; break; case 0x287D: - gSaveContext.weekEventReg[63] |= 0x1; - gSaveContext.weekEventReg[63] &= (u8)~0x2; + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; func_801477B4(globalCtx); player->stateFlags1 |= 0x20; this->unk_53C = 0; - func_800BDC5C(&this->skelAnime, sAnimations, 3); - func_801A2BB8(0x25); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + func_801A2BB8(NA_BGM_MINI_GAME_2); if (this->unk_542 == 0) { if (this->unk_546 == 1) { func_80961EC8(globalCtx); @@ -583,7 +577,7 @@ void func_809628BC(EnFu* this) { } void func_809628D0(EnFu* this, GlobalContext* globalCtx) { - u8 sp27 = func_80152498(&globalCtx->msgCtx); + u8 sp27 = Message_GetState(&globalCtx->msgCtx); switch (sp27) { case 0: @@ -601,7 +595,7 @@ void func_809628D0(EnFu* this, GlobalContext* globalCtx) { break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->unk_54A = 1; switch (this->unk_552) { case 0x287F: @@ -610,8 +604,8 @@ void func_809628D0(EnFu* this, GlobalContext* globalCtx) { case 0x2884: case 0x2887: case 0x288A: - gSaveContext.weekEventReg[63] &= (u8)~0x1; - gSaveContext.weekEventReg[63] &= (u8)~0x2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; func_809622FC(this); break; @@ -641,10 +635,10 @@ void func_80962A10(EnFu* this, GlobalContext* globalCtx) { BgFuKaiten* fuKaiten = (BgFuKaiten*)this->actor.child; this->unk_53C = 0; - if ((fuKaiten->rotationSpeed < 300) || (fuKaiten->bouceHeight < 40.0f) || (fuKaiten->bounceSpeed < 600)) { + if ((fuKaiten->rotationSpeed < 300) || (fuKaiten->bounceHeight < 40.0f) || (fuKaiten->bounceSpeed < 600)) { Math_SmoothStepToS(&fuKaiten->rotationSpeed, 300, 10, 5, 5); Math_SmoothStepToS(&fuKaiten->bounceSpeed, 600, 20, 10, 10); - Math_SmoothStepToF(&fuKaiten->bouceHeight, 40.0f, 0.1f, 1.0f, 1.0f); + Math_SmoothStepToF(&fuKaiten->bounceHeight, 40.0f, 0.1f, 1.0f, 1.0f); return; } @@ -657,10 +651,9 @@ void func_80962A10(EnFu* this, GlobalContext* globalCtx) { this->unk_546 = 1; } - if ((gSaveContext.playerForm == PLAYER_FORM_DEKU) && gSaveContext.magicAcquired) { - s16 temp = gSaveContext.unk_3F30; - - Parameter_AddMagic(globalCtx, temp + (gSaveContext.doubleMagic * 48) + 48); + if ((gSaveContext.save.playerForm == PLAYER_FORM_DEKU) && gSaveContext.save.playerData.magicAcquired) { + Parameter_AddMagic(globalCtx, + ((void)0, gSaveContext.unk_3F30) + (gSaveContext.save.playerData.doubleMagic * 48) + 48); } func_80962F10(this); @@ -678,11 +671,11 @@ void func_80962BCC(EnFu* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); BgFuKaiten* fuKaiten = (BgFuKaiten*)this->actor.child; - if ((fuKaiten->rotationSpeed < 100) || (fuKaiten->bouceHeight < 30.0f) || (fuKaiten->bounceSpeed < 600)) { + if ((fuKaiten->rotationSpeed < 100) || (fuKaiten->bounceHeight < 30.0f) || (fuKaiten->bounceSpeed < 600)) { Math_SmoothStepToS(&fuKaiten->rotationSpeed, 100, 10, 5, 5); Math_SmoothStepToS(&fuKaiten->bounceSpeed, 600, 20, 10, 10); Math_SmoothStepToF(&fuKaiten->elevation, 10.0f, 0.1f, 1.0f, 1.0f); - Math_SmoothStepToF(&fuKaiten->bouceHeight, 30.0f, 0.1f, 1.0f, 1.0f); + Math_SmoothStepToF(&fuKaiten->bounceHeight, 30.0f, 0.1f, 1.0f, 1.0f); return; } @@ -710,10 +703,10 @@ void func_80962D60(EnFu* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); BgFuKaiten* fuKaiten = (BgFuKaiten*)this->actor.child; - if ((fuKaiten->rotationSpeed < 100) || (fuKaiten->bouceHeight < 40.0f) || (fuKaiten->bounceSpeed < 600)) { + if ((fuKaiten->rotationSpeed < 100) || (fuKaiten->bounceHeight < 40.0f) || (fuKaiten->bounceSpeed < 600)) { Math_SmoothStepToS(&fuKaiten->rotationSpeed, 100, 10, 5, 5); Math_SmoothStepToS(&fuKaiten->bounceSpeed, 600, 20, 10, 10); - Math_SmoothStepToF(&fuKaiten->bouceHeight, 40.0f, 0.1f, 1.0f, 1.0f); + Math_SmoothStepToF(&fuKaiten->bounceHeight, 40.0f, 0.1f, 1.0f, 1.0f); return; } @@ -735,15 +728,16 @@ void func_80962D60(EnFu* this, GlobalContext* globalCtx) { void func_80962EBC(EnFu* this, GlobalContext* globalCtx) { if (this->unk_542 != 0) { if (this->actor.cutscene != -1) { - func_800DFB14(globalCtx->cameraPtrs[MAIN_CAM], ActorCutscene_GetCutscene(this->actor.cutscene)->unk4); + Camera_ChangeDataIdx(globalCtx->cameraPtrs[CAM_ID_MAIN], + ActorCutscene_GetCutscene(this->actor.cutscene)->csCamSceneDataId); } } } void func_80962F10(EnFu* this) { this->unk_548 = 0; - this->actor.flags &= ~1; - gSaveContext.weekEventReg[8] |= 1; + this->actor.flags &= ~ACTOR_FLAG_1; + gSaveContext.save.weekEventReg[8] |= 1; this->actionFunc = func_80962F4C; } @@ -753,7 +747,7 @@ void func_80962F4C(EnFu* this, GlobalContext* globalCtx) { switch (this->unk_542) { case 0: - if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { player->stateFlags3 |= 0x400; } break; @@ -778,20 +772,21 @@ void func_80962F4C(EnFu* this, GlobalContext* globalCtx) { } if (func_80961D10(this)) { - func_801518B0(globalCtx, 0x288B, &this->actor); + Message_StartTextbox(globalCtx, 0x288B, &this->actor); } - if ((!func_800CAF94((DynaPolyActor*)this->actor.child) && (player->actor.bgCheckFlags & 1)) || + if ((!DynaPolyActor_IsInRidingRotatingState((DynaPolyActor*)this->actor.child) && + (player->actor.bgCheckFlags & 1)) || (gSaveContext.unk_3DE0[4] < 1) || (this->unk_548 == this->unk_54C)) { player->stateFlags3 &= ~0x400000; func_80961E88(globalCtx); player->stateFlags1 |= 0x20; if (this->unk_548 < this->unk_54C) { if (gSaveContext.unk_3DE0[4] == 0) { - func_801518B0(globalCtx, 0x2885, &this->actor); + Message_StartTextbox(globalCtx, 0x2885, &this->actor); this->unk_552 = 0x2885; } else { - func_801518B0(globalCtx, 0x2888, &this->actor); + Message_StartTextbox(globalCtx, 0x2888, &this->actor); this->unk_552 = 0x2888; } func_801A2C20(); @@ -804,7 +799,7 @@ void func_80962F4C(EnFu* this, GlobalContext* globalCtx) { func_801A2C20(); gSaveContext.unk_3DE0[4] = 0; gSaveContext.unk_3DD0[4] = 5; - func_801A3098(0x922); + func_801A3098(NA_BGM_GET_ITEM | 0x900); func_8011B4E0(globalCtx, 1); this->unk_54A = 3; func_809632D0(this); @@ -825,11 +820,11 @@ void func_8096326C(EnFu* this, GlobalContext* globalCtx) { } void func_809632D0(EnFu* this) { - if (gSaveContext.playerForm == PLAYER_FORM_DEKU) { + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { Interface_ChangeAlpha(50); } - gSaveContext.weekEventReg[8] &= (u8)~0x1; + gSaveContext.save.weekEventReg[8] &= (u8)~1; if (this->unk_2D4 != NULL) { BgFuMizu* mizu = this->unk_2D4; @@ -837,7 +832,7 @@ void func_809632D0(EnFu* this) { mizu->unk_160 = 0; } - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->actionFunc = func_80963350; } @@ -845,8 +840,8 @@ void func_80963350(EnFu* this, GlobalContext* globalCtx) { static s32 D_80964C24 = 0; BgFuKaiten* fuKaiten = (BgFuKaiten*)this->actor.child; - if ((this->unk_54A == 0) && (((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) || - ((func_80152498(&globalCtx->msgCtx) == 2) && (globalCtx->msgCtx.unk12023 == 1)))) { + if ((this->unk_54A == 0) && (((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) || + ((Message_GetState(&globalCtx->msgCtx) == 2) && (globalCtx->msgCtx.unk12023 == 1)))) { func_801477B4(globalCtx); this->unk_54A = 2; D_80964C24 = 1; @@ -857,11 +852,11 @@ void func_80963350(EnFu* this, GlobalContext* globalCtx) { D_80964C24 = 1; } - if ((fuKaiten->rotationSpeed != 0) || (fuKaiten->bounceSpeed != 0) || (fuKaiten->bouceHeight > 0.0f) || + if ((fuKaiten->rotationSpeed != 0) || (fuKaiten->bounceSpeed != 0) || (fuKaiten->bounceHeight > 0.0f) || !func_809638F8(globalCtx)) { Math_SmoothStepToS(&fuKaiten->rotationSpeed, 0, 10, 10, 5); Math_SmoothStepToS(&fuKaiten->bounceSpeed, 0, 10, 15, 5); - Math_SmoothStepToF(&fuKaiten->bouceHeight, 0.0f, 0.1f, 1.0f, 1.0f); + Math_SmoothStepToF(&fuKaiten->bounceHeight, 0.0f, 0.1f, 1.0f, 1.0f); Math_SmoothStepToF(&fuKaiten->elevation, 0.0f, 0.1f, 1.0f, 1.0f); func_80962EBC(this, globalCtx); } else if (D_80964C24 == 1) { @@ -882,10 +877,10 @@ void func_80963560(EnFu* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; func_80963610(this); - } else if ((this->unk_552 == 0x2880) && !(gSaveContext.weekEventReg[22] & 0x80)) { - func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } else if ((this->unk_552 == 0x2880) && !(gSaveContext.save.weekEventReg[22] & 0x80)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); } this->actor.child->freezeTimer = 10; } @@ -898,48 +893,48 @@ void func_80963610(EnFu* this) { void func_80963630(EnFu* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { - if ((gSaveContext.weekEventReg[22] & 0x10) && (gSaveContext.weekEventReg[22] & 0x20) && (CURRENT_DAY == 3) && - (gSaveContext.playerForm == PLAYER_FORM_HUMAN)) { - if (gSaveContext.weekEventReg[22] & 0x40) { - func_801518B0(globalCtx, 0x2884, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if ((gSaveContext.save.weekEventReg[22] & 0x10) && (gSaveContext.save.weekEventReg[22] & 0x20) && + (CURRENT_DAY == 3) && (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN)) { + if (gSaveContext.save.weekEventReg[22] & 0x40) { + Message_StartTextbox(globalCtx, 0x2884, &this->actor); this->unk_552 = 0x2884; - } else if (!(gSaveContext.weekEventReg[22] & 0x80)) { - gSaveContext.weekEventReg[22] |= 0x80; - func_801518B0(globalCtx, 0x2882, &this->actor); + } else if (!(gSaveContext.save.weekEventReg[22] & 0x80)) { + gSaveContext.save.weekEventReg[22] |= 0x80; + Message_StartTextbox(globalCtx, 0x2882, &this->actor); this->unk_552 = 0x2882; } else { - func_801518B0(globalCtx, 0x2881, &this->actor); + Message_StartTextbox(globalCtx, 0x2881, &this->actor); this->unk_552 = 0x2881; } } else { - func_801518B0(globalCtx, 0x287F, &this->actor); + Message_StartTextbox(globalCtx, 0x287F, &this->actor); this->unk_552 = 0x287F; } - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.child->freezeTimer = 0; func_809628BC(this); - if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { switch (CURRENT_DAY) { case 1: - gSaveContext.weekEventReg[22] |= 0x10; + gSaveContext.save.weekEventReg[22] |= 0x10; break; case 2: - gSaveContext.weekEventReg[22] |= 0x20; + gSaveContext.save.weekEventReg[22] |= 0x20; break; case 3: - gSaveContext.weekEventReg[22] |= 0x40; + gSaveContext.save.weekEventReg[22] |= 0x40; break; } } player->stateFlags1 &= ~0x20; } else { this->actor.child->freezeTimer = 10; - func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + func_800B85E0(&this->actor, globalCtx, 500.0f, EXCH_ITEM_MINUS1); } } @@ -961,7 +956,7 @@ s32 func_80963810(GlobalContext* globalCtx, Vec3f pos) { } globalCtx->actorCtx.unk268 = 1; - func_800B6F20(globalCtx, globalCtx->actorCtx.pad26C, phi_f0, sp22); + func_800B6F20(globalCtx, &globalCtx->actorCtx.unk_26C, phi_f0, sp22); if (sp28 < 80.0f) { return true; @@ -972,46 +967,46 @@ s32 func_80963810(GlobalContext* globalCtx, Vec3f pos) { s32 func_809638F8(GlobalContext* globalCtx) { s32 ret = true; - if (globalCtx->envCtx.unk_8C.diffuseColor1[0] > 25) { - globalCtx->envCtx.unk_8C.diffuseColor1[0] -= 25; + if (globalCtx->envCtx.lightSettings.diffuseColor1[0] > 25) { + globalCtx->envCtx.lightSettings.diffuseColor1[0] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.diffuseColor1[0] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[0] = 0; } - if (globalCtx->envCtx.unk_8C.diffuseColor1[1] > 25) { - globalCtx->envCtx.unk_8C.diffuseColor1[1] -= 25; + if (globalCtx->envCtx.lightSettings.diffuseColor1[1] > 25) { + globalCtx->envCtx.lightSettings.diffuseColor1[1] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.diffuseColor1[1] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[1] = 0; } - if (globalCtx->envCtx.unk_8C.diffuseColor1[2] > 25) { - globalCtx->envCtx.unk_8C.diffuseColor1[2] -= 25; + if (globalCtx->envCtx.lightSettings.diffuseColor1[2] > 25) { + globalCtx->envCtx.lightSettings.diffuseColor1[2] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.diffuseColor1[2] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[2] = 0; } - if (globalCtx->envCtx.unk_8C.ambientColor[0] > 25) { - globalCtx->envCtx.unk_8C.ambientColor[0] -= 25; + if (globalCtx->envCtx.lightSettings.ambientColor[0] > 25) { + globalCtx->envCtx.lightSettings.ambientColor[0] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.ambientColor[0] = 0; + globalCtx->envCtx.lightSettings.ambientColor[0] = 0; } - if (globalCtx->envCtx.unk_8C.ambientColor[1] > 25) { - globalCtx->envCtx.unk_8C.ambientColor[1] -= 25; + if (globalCtx->envCtx.lightSettings.ambientColor[1] > 25) { + globalCtx->envCtx.lightSettings.ambientColor[1] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.ambientColor[1] = 0; + globalCtx->envCtx.lightSettings.ambientColor[1] = 0; } - if (globalCtx->envCtx.unk_8C.ambientColor[2] > 25) { - globalCtx->envCtx.unk_8C.ambientColor[2] -= 25; + if (globalCtx->envCtx.lightSettings.ambientColor[2] > 25) { + globalCtx->envCtx.lightSettings.ambientColor[2] -= 25; ret = false; } else { - globalCtx->envCtx.unk_8C.ambientColor[2] = 0; + globalCtx->envCtx.lightSettings.ambientColor[2] = 0; } return ret; } @@ -1019,99 +1014,99 @@ s32 func_809638F8(GlobalContext* globalCtx) { void func_809639D0(EnFu* this, GlobalContext* globalCtx) { switch (CURRENT_DAY) { case 1: - if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { if (CUR_UPG_VALUE(UPG_BOMB_BAG) == 0) { - func_801518B0(globalCtx, 0x2853, &this->actor); + Message_StartTextbox(globalCtx, 0x2853, &this->actor); this->unk_552 = 0x2853; - } else if (gSaveContext.weekEventReg[22] & 0x10) { - func_801518B0(globalCtx, 0x284D, &this->actor); + } else if (gSaveContext.save.weekEventReg[22] & 0x10) { + Message_StartTextbox(globalCtx, 0x284D, &this->actor); this->unk_552 = 0x284D; } else if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x284F, &this->actor); + Message_StartTextbox(globalCtx, 0x284F, &this->actor); this->unk_552 = 0x284F; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x2851, &this->actor); + Message_StartTextbox(globalCtx, 0x2851, &this->actor); this->unk_552 = 0x2851; } } else { - func_801518B0(globalCtx, 0x286F, &this->actor); + Message_StartTextbox(globalCtx, 0x286F, &this->actor); this->unk_552 = 0x286F; } break; case 2: - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - func_801518B0(globalCtx, 0x286F, &this->actor); + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + Message_StartTextbox(globalCtx, 0x286F, &this->actor); this->unk_552 = 0x286F; } else if (CUR_UPG_VALUE(UPG_BOMB_BAG) == 0) { - func_801518B0(globalCtx, 0x2853, &this->actor); + Message_StartTextbox(globalCtx, 0x2853, &this->actor); this->unk_552 = 0x2853; - } else if (!(gSaveContext.weekEventReg[22] & 0x10)) { + } else if (!(gSaveContext.save.weekEventReg[22] & 0x10)) { if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x285B, &this->actor); + Message_StartTextbox(globalCtx, 0x285B, &this->actor); this->unk_552 = 0x285B; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x285D, &this->actor); + Message_StartTextbox(globalCtx, 0x285D, &this->actor); this->unk_552 = 0x285D; } - } else if (gSaveContext.weekEventReg[22] & 0x20) { - func_801518B0(globalCtx, 0x2855, &this->actor); + } else if (gSaveContext.save.weekEventReg[22] & 0x20) { + Message_StartTextbox(globalCtx, 0x2855, &this->actor); this->unk_552 = 0x2855; } else if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x2857, &this->actor); + Message_StartTextbox(globalCtx, 0x2857, &this->actor); this->unk_552 = 0x2857; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x2859, &this->actor); + Message_StartTextbox(globalCtx, 0x2859, &this->actor); this->unk_552 = 0x2859; } break; case 3: - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - if (gSaveContext.playerForm == PLAYER_FORM_DEKU) { + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { func_80963EAC(this, globalCtx); } else { - func_801518B0(globalCtx, 0x2841, &this->actor); + Message_StartTextbox(globalCtx, 0x2841, &this->actor); this->unk_552 = 0x2841; } } else if (CUR_UPG_VALUE(UPG_QUIVER) == 0) { - func_801518B0(globalCtx, 0x284B, &this->actor); + Message_StartTextbox(globalCtx, 0x284B, &this->actor); this->unk_552 = 0x284B; - } else if (gSaveContext.weekEventReg[22] & 0x40) { - if ((gSaveContext.weekEventReg[22] & 0x10) && (gSaveContext.weekEventReg[22] & 0x20)) { - func_801518B0(globalCtx, 0x285F, &this->actor); + } else if (gSaveContext.save.weekEventReg[22] & 0x40) { + if ((gSaveContext.save.weekEventReg[22] & 0x10) && (gSaveContext.save.weekEventReg[22] & 0x20)) { + Message_StartTextbox(globalCtx, 0x285F, &this->actor); this->unk_552 = 0x285F; } else { - func_801518B0(globalCtx, 0x2861, &this->actor); + Message_StartTextbox(globalCtx, 0x2861, &this->actor); this->unk_552 = 0x2861; } - } else if ((gSaveContext.weekEventReg[22] & 0x10) && (gSaveContext.weekEventReg[22] & 0x20)) { + } else if ((gSaveContext.save.weekEventReg[22] & 0x10) && (gSaveContext.save.weekEventReg[22] & 0x20)) { if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x2863, &this->actor); + Message_StartTextbox(globalCtx, 0x2863, &this->actor); this->unk_552 = 0x2863; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x2865, &this->actor); + Message_StartTextbox(globalCtx, 0x2865, &this->actor); this->unk_552 = 0x2865; } - } else if ((gSaveContext.weekEventReg[22] & 0x10) || (gSaveContext.weekEventReg[22] & 0x20)) { + } else if ((gSaveContext.save.weekEventReg[22] & 0x10) || (gSaveContext.save.weekEventReg[22] & 0x20)) { if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x2867, &this->actor); + Message_StartTextbox(globalCtx, 0x2867, &this->actor); this->unk_552 = 0x2867; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x2869, &this->actor); + Message_StartTextbox(globalCtx, 0x2869, &this->actor); this->unk_552 = 0x2869; } } else if (this->unk_53E == 1) { - func_801518B0(globalCtx, 0x286B, &this->actor); + Message_StartTextbox(globalCtx, 0x286B, &this->actor); this->unk_552 = 0x286B; } else { this->unk_53E = 1; - func_801518B0(globalCtx, 0x286D, &this->actor); + Message_StartTextbox(globalCtx, 0x286D, &this->actor); this->unk_552 = 0x286D; } break; @@ -1121,39 +1116,39 @@ void func_809639D0(EnFu* this, GlobalContext* globalCtx) { void func_80963DE4(EnFu* this, GlobalContext* globalCtx) { switch (this->unk_542) { case 0: - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - func_801518B0(globalCtx, 0x2875, &this->actor); + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + Message_StartTextbox(globalCtx, 0x2875, &this->actor); this->unk_552 = 0x2875; } else { - func_801518B0(globalCtx, 0x2877, &this->actor); + Message_StartTextbox(globalCtx, 0x2877, &this->actor); this->unk_552 = 0x2877; } break; case 1: - func_801518B0(globalCtx, 0x2879, &this->actor); + Message_StartTextbox(globalCtx, 0x2879, &this->actor); this->unk_552 = 0x2879; break; case 2: - func_801518B0(globalCtx, 0x287B, &this->actor); + Message_StartTextbox(globalCtx, 0x287B, &this->actor); this->unk_552 = 0x287B; break; } } void func_80963EAC(EnFu* this, GlobalContext* globalCtx) { - if (gSaveContext.magicAcquired) { + if (gSaveContext.save.playerData.magicAcquired) { if (this->unk_540 == 1) { - func_801518B0(globalCtx, 0x2847, &this->actor); + Message_StartTextbox(globalCtx, 0x2847, &this->actor); this->unk_552 = 0x2847; } else { this->unk_540 = 1; - func_801518B0(globalCtx, 0x2845, &this->actor); + Message_StartTextbox(globalCtx, 0x2845, &this->actor); this->unk_552 = 0x2845; } } else { - func_801518B0(globalCtx, 0x2843, &this->actor); + Message_StartTextbox(globalCtx, 0x2843, &this->actor); this->unk_552 = 0x2843; } } @@ -1161,17 +1156,17 @@ void func_80963EAC(EnFu* this, GlobalContext* globalCtx) { void func_80963F44(EnFu* this, GlobalContext* globalCtx) { u16 sp1E = this->unk_552 + 1; - func_801518B0(globalCtx, sp1E, &this->actor); + Message_StartTextbox(globalCtx, sp1E, &this->actor); this->unk_552 = sp1E; } void func_80963F88(EnFu* this, GlobalContext* globalCtx) { if (this->unk_542 == 1) { - func_800DFAC8(globalCtx->cameraPtrs[MAIN_CAM], 75); + func_800DFAC8(globalCtx->cameraPtrs[CAM_ID_MAIN], 75); globalCtx->unk_1887E = 0; } else if (this->unk_542 == 2) { globalCtx->unk_1887D = 0; - func_800DFAC8(globalCtx->cameraPtrs[MAIN_CAM], 75); + func_800DFAC8(globalCtx->cameraPtrs[CAM_ID_MAIN], 75); } } @@ -1180,7 +1175,7 @@ void func_80963FF8(EnFu* this, GlobalContext* globalCtx) { if (player->stateFlags1 & 0x100000) { globalCtx->actorCtx.unk268 = 1; - globalCtx->actorCtx.unk278 = 0x8000; + globalCtx->actorCtx.unk_26C.press.button = 0x8000; } else { globalCtx->actorCtx.unk268 = 1; } @@ -1213,12 +1208,12 @@ void func_8096413C(EnFu* this, GlobalContext* globalCtx) { } void func_80964190(EnFu* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_552) { case 0x2842: case 0x2844: case 0x2848: - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); break; case 0x2840: @@ -1244,28 +1239,28 @@ void func_80964190(EnFu* this, GlobalContext* globalCtx) { case 0x286B: case 0x286D: case 0x2871: - func_800BDC5C(&this->skelAnime, sAnimations, 4); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); break; case 0x2860: - func_800BDC5C(&this->skelAnime, sAnimations, 5); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); break; case 0x285F: - func_800BDC5C(&this->skelAnime, sAnimations, 6); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); break; case 0x287E: case 0x2880: case 0x2883: - func_800BDC5C(&this->skelAnime, sAnimations, 2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); break; } } } void func_8096426C(EnFu* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_552) { case 0x2840: case 0x2841: @@ -1339,7 +1334,7 @@ void EnFu_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); func_809642E0(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_8096209C(this, globalCtx); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); SkelAnime_Update(&this->skelAnime); @@ -1352,17 +1347,17 @@ s32 EnFu_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, EnFu* this = THIS; if (limbIndex == 9) { - Matrix_InsertTranslation(1600.0f, 300.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_524[1], MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_524[0], MTXMODE_APPLY); - Matrix_RotateY(this->unk_524[2], MTXMODE_APPLY); - Matrix_InsertTranslation(-1600.0f, -300.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1600.0f, 300.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_524[1], MTXMODE_APPLY); + Matrix_RotateZS(this->unk_524[0], MTXMODE_APPLY); + Matrix_RotateYS(this->unk_524[2], MTXMODE_APPLY); + Matrix_Translate(-1600.0f, -300.0f, 0.0f, MTXMODE_APPLY); } else if (limbIndex == 20) { - Matrix_InsertTranslation(1800.0f, 200.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_52A[1], MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_52A[0], MTXMODE_APPLY); - Matrix_RotateY(this->unk_52A[2], MTXMODE_APPLY); - Matrix_InsertTranslation(-1800.0f, -200.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1800.0f, 200.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_52A[1], MTXMODE_APPLY); + Matrix_RotateZS(this->unk_52A[0], MTXMODE_APPLY); + Matrix_RotateYS(this->unk_52A[2], MTXMODE_APPLY); + Matrix_Translate(-1800.0f, -200.0f, 0.0f, MTXMODE_APPLY); } return false; } @@ -1373,9 +1368,9 @@ void EnFu_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec EnFu* this = THIS; if (limbIndex == 9) { - Matrix_MultiplyVector3fByState(&D_80964C28, &this->unk_508); + Matrix_MultVec3f(&D_80964C28, &this->unk_508); } else if (limbIndex == 20) { - Matrix_MultiplyVector3fByState(&D_80964C34, &this->unk_514); + Matrix_MultVec3f(&D_80964C34, &this->unk_514); } } @@ -1383,9 +1378,9 @@ void EnFu_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnFu* this = THIS; - Matrix_StatePush(); + Matrix_Push(); func_80964950(globalCtx, this->unk_2D8, ARRAY_COUNT(this->unk_2D8)); - Matrix_StatePop(); + Matrix_Pop(); OPEN_DISPS(globalCtx->state.gfxCtx); @@ -1425,7 +1420,7 @@ void func_80964694(EnFu* this, EnFuUnkStruct* ptr, Vec3f* arg2, s32 len) { void func_809647EC(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len) { Vec3f sp44 = { 0.0f, 0.0f, 0.0f }; - s16 activeCam = func_800DFC68(GET_ACTIVE_CAM(globalCtx)); + s16 yaw = Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx)); s32 i; for (i = 0; i < len; i++, ptr++) { @@ -1436,11 +1431,11 @@ void func_809647EC(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len) { ptr->unk_08.y += ptr->unk_20.y; ptr->unk_08.x += 2.0f * Math_SinS(ptr->unk_2C); ptr->unk_08.z += 2.0f * Math_CosS(ptr->unk_2C); - Matrix_StatePush(); - Matrix_InsertTranslation(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); - Matrix_RotateY(activeCam, MTXMODE_APPLY); - Matrix_MultiplyVector3fByState(&sp44, &ptr->unk_08); - Matrix_StatePop(); + Matrix_Push(); + Matrix_Translate(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); + Matrix_RotateYS(yaw, MTXMODE_APPLY); + Matrix_MultVec3f(&sp44, &ptr->unk_08); + Matrix_Pop(); ptr->unk_2C += 6000; } } @@ -1458,17 +1453,17 @@ void func_80964950(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len) { for (i = 0; i < len; i++, ptr++) { if (ptr->unk_36 == 1) { if (!flag) { - gSPDisplayList(POLY_OPA_DISP++, D_0600B0A0); + gSPDisplayList(POLY_OPA_DISP++, object_mu_DL_00B0A0); flag = true; } - Matrix_InsertTranslation(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Translate(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); Matrix_Scale(ptr->unk_00, ptr->unk_00, ptr->unk_00, MTXMODE_APPLY); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_0405E6F0)); + 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++, D_0600B0E0); + gSPDisplayList(POLY_OPA_DISP++, object_mu_DL_00B0E0); } } diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.h b/src/overlays/actors/ovl_En_Fu/z_en_fu.h index b16ea4620..6af75768f 100644 --- a/src/overlays/actors/ovl_En_Fu/z_en_fu.h +++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.h @@ -2,6 +2,7 @@ #define Z_EN_FU_H #include "global.h" +#include "overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.h" struct EnFu; diff --git a/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.c b/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.c index ed55f1055..ef4c8b6bb 100644 --- a/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.c +++ b/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.c @@ -1,6 +1,15 @@ -#include "z_en_fu_kago.h" +/* + * File: z_en_fu_kago.c + * Overlay: ovl_En_Fu_Kago + * Description: Honey & Darling's Shop - Bomb Basket + */ -#define FLAGS 0x00000030 +#include "z_en_fu_kago.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "overlays/actors/ovl_En_Fu/z_en_fu.h" +#include "objects/object_fu_mato/object_fu_mato.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnFuKago*)thisx) @@ -9,7 +18,15 @@ void EnFuKago_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFuKago_Update(Actor* thisx, GlobalContext* globalCtx); void EnFuKago_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80ACF994(EnFuKago* this); +void func_80ACF9A8(EnFuKago* this, GlobalContext* globalCtx); +void func_80ACF9DC(EnFuKago* this); +void func_80ACF9FC(EnFuKago* this, GlobalContext* globalCtx); +void func_80ACFA78(EnFuKago* this, GlobalContext* globalCtx); +void func_80AD0028(EnFuKago* this, GlobalContext* globalCtx); +void func_80AD0274(EnFuKago* this); +void func_80AD0288(EnFuKago* this, GlobalContext* globalCtx); + const ActorInit En_Fu_Kago_InitVars = { ACTOR_EN_FU_KAGO, ACTORCAT_BG, @@ -22,46 +39,368 @@ const ActorInit En_Fu_Kago_InitVars = { (ActorFunc)EnFuKago_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80AD05F0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK4, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK4, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 200 }, 100 }, }; -#endif +Gfx* D_80AD061C[] = { + object_fu_mato_DL_0006A0, object_fu_mato_DL_000740, object_fu_mato_DL_0007E0, + object_fu_mato_DL_000880, object_fu_mato_DL_000920, object_fu_mato_DL_0009C0, +}; -extern ColliderSphereInit D_80AD05F0; +Vec3f D_80AD0634[] = { + { -1.0f, 0.5f, 1.73f }, { 1.0f, 0.5f, 1.73f }, { 2.0f, 0.5f, 0.0f }, + { 1.0f, 0.5f, -1.73f }, { -1.0f, 0.5f, -1.73f }, { -2.0f, 0.5f, 0.0f }, +}; -extern UNK_TYPE D_060006A0; -extern UNK_TYPE D_060015C0; +Vec3f D_80AD067C[] = { + { -0.5f, 0.5f, 0.87f }, { 0.5f, 0.5f, 0.87f }, { 1.0f, 0.5f, 0.0f }, + { 0.5f, 0.5f, -0.87f }, { -0.5f, 0.5f, -0.87f }, { -1.0f, 0.5f, 0.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/EnFuKago_Init.s") +Vec3f D_80AD06C4[] = { + { -13.7f, 9.0f, 15.5f }, { 13.7f, 9.0f, 15.5f }, { 13.7f, 9.0f, 0.0f }, + { 13.7f, 9.0f, -15.5f }, { -13.7f, 9.0f, -15.5f }, { -13.7f, 9.0f, 0.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/EnFuKago_Destroy.s") +void EnFuKago_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFuKago* this = THIS; + CollisionHeader* sp34 = NULL; + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACF8B8.s") + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&object_fu_mato_Colheader_0015C0, &sp34); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp34); + Actor_SetScale(&this->dyna.actor, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACF994.s") + while (npc != NULL) { + if (npc->id == ACTOR_EN_FU) { + this->dyna.actor.parent = npc; + break; + } + npc = npc->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACF9A8.s") + if (npc == NULL) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACF9DC.s") + Collider_InitSphere(globalCtx, &this->collider); + Collider_SetSphere(globalCtx, &this->collider, &this->dyna.actor, &sSphereInit); + this->collider.dim.worldSphere.radius = 10; + this->unk_33A = 0; + this->unk_33C = 0; + this->dyna.actor.colChkInfo.health = 1; + func_80ACF994(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACF9FC.s") +void EnFuKago_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFuKago* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACFA78.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80ACFDAC.s") +s32 func_80ACF8B8(EnFuKago* this, GlobalContext* globalCtx) { + this->collider.dim.worldSphere.center.x = this->dyna.actor.world.pos.x; + this->collider.dim.worldSphere.center.y = this->dyna.actor.world.pos.y + 10.0f; + this->collider.dim.worldSphere.center.z = this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80AD0028.s") + if (this->collider.base.ocFlags1 & OC1_HIT) { + this->collider.base.ocFlags1 &= ~OC1_HIT; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80AD0274.s") + if (this->collider.base.oc->id == ACTOR_EN_BOM) { + this->dyna.actor.child = this->collider.base.oc; + } else if (this->collider.base.oc->id == ACTOR_PLAYER) { + func_80ACFA78(this, globalCtx); + return false; + } else { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80AD0288.s") + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + return true; + } else { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/EnFuKago_Update.s") +void func_80ACF994(EnFuKago* this) { + this->actionFunc = func_80ACF9A8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/func_80AD0340.s") +void func_80ACF9A8(EnFuKago* this, GlobalContext* globalCtx) { + if (func_80ACF8B8(this, globalCtx)) { + func_80ACF9DC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Kago/EnFuKago_Draw.s") +void func_80ACF9DC(EnFuKago* this) { + EnBom* bom = (EnBom*)this->dyna.actor.child; + + bom->timer = 20; + this->actionFunc = func_80ACF9FC; +} + +void func_80ACF9FC(EnFuKago* this, GlobalContext* globalCtx) { + EnBom* bom = (EnBom*)this->dyna.actor.child; + EnFu* fu = (EnFu*)this->dyna.actor.parent; + + if (this->dyna.actor.child->update == NULL) { + this->dyna.actor.child = NULL; + func_80ACF994(this); + } else if (bom->timer == 1) { + fu->unk_548++; + func_80ACFA78(this, globalCtx); + } else { + this->dyna.actor.child->world.pos.x = this->dyna.actor.world.pos.x; + this->dyna.actor.child->world.pos.z = this->dyna.actor.world.pos.z; + } +} + +void func_80ACFA78(EnFuKago* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp98; + Vec3s sp90; + Vec3s sp88 = { 0, 0, 0 }; + EnFuKagoStruct* ptr; + s16 y; + + this->dyna.actor.colChkInfo.health = 0; + sp98 = this->dyna.actor.world.pos; + sp90 = this->dyna.actor.shape.rot; + + ptr = &this->unk_1B8[0]; + y = sp90.y; + + for (i = 0; i < ARRAY_COUNT(this->unk_1B8); i++) { + ptr->unk_00 = sp98; + ptr->unk_30 = sp88; + + ptr->unk_0C.x = (Math_CosS(y) * D_80AD0634[i].x) + (Math_SinS(y) * D_80AD0634[i].z); + ptr->unk_0C.y = D_80AD0634[i].y + Rand_Centered(); + ptr->unk_0C.z = (Math_CosS(y) * D_80AD0634[i].z) - (Math_SinS(y) * D_80AD0634[i].x); + + ptr->unk_18.x = (Math_CosS(y) * D_80AD067C[i].x) + (Math_SinS(y) * D_80AD067C[i].z); + ptr->unk_18.y = D_80AD067C[i].y; + ptr->unk_18.z = (Math_CosS(y) * D_80AD067C[i].z) - (Math_SinS(y) * D_80AD067C[i].x); + + ptr->unk_36.x = (s16)Rand_Next() >> 5; + ptr->unk_36.y = 0; + ptr->unk_36.z = (s16)Rand_Next() >> 5; + + ptr->unk_24.x = D_80AD06C4[i].x; + ptr->unk_24.y = D_80AD06C4[i].y; + ptr->unk_24.z = D_80AD06C4[i].z; + + ptr->unk_3C = 0; + + ptr->unk_00.x += 18.0f * ptr->unk_0C.x; + ptr->unk_00.y += 18.0f * ptr->unk_0C.y; + ptr->unk_00.z += 18.0f * ptr->unk_0C.z; + + ptr++; + } + + this->dyna.actor.freezeTimer = 2; + EffectSsHahen_SpawnBurst(globalCtx, &this->dyna.actor.world.pos, 17.0f, 0, 15, 13, 20, -1, 10, NULL); + + this->unk_338 = 60; + this->unk_33A = 1; + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WOODBOX_BREAK); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->actionFunc = func_80AD0028; +} + +Vec3f D_80AD0714 = { 0.0f, 0.0f, 0.0f }; + +void func_80ACFDAC(EnFuKago* this, GlobalContext* globalCtx, EnFuKagoStruct* arg2) { + Vec3f sp34; + f32 temp_f0; + + if (arg2->unk_3C == 0) { + if (arg2->unk_00.y < 15.0f) { + sp34 = arg2->unk_00; + sp34.y = 30.0f; + EffectSsGSplash_Spawn(globalCtx, &sp34, NULL, NULL, 0, 800); + EffectSsGRipple_Spawn(globalCtx, &sp34, 250, 650, 0); + arg2->unk_3C = 1; + } + + Math_SmoothStepToF(&arg2->unk_18.x, 0.0f, 0.1f, 0.1f, 0.1f); + Math_SmoothStepToF(&arg2->unk_18.y, -1.0f, 0.1f, 0.1f, 0.1f); + Math_SmoothStepToF(&arg2->unk_18.z, 0.0f, 0.1f, 0.1f, 0.1f); + return; + } + + temp_f0 = Math_Vec3f_DistXZ(&arg2->unk_00, &D_80AD0714); + + arg2->unk_18.y = ((15.0f - arg2->unk_00.y) * 0.1f) - (0.2f * arg2->unk_0C.y); + arg2->unk_18.x = arg2->unk_0C.x * -0.1f; + arg2->unk_18.z = arg2->unk_0C.z * -0.1f; + + if (temp_f0 < 190.0f) { + arg2->unk_00.x *= 190.0f / temp_f0; + arg2->unk_00.z *= 190.0f / temp_f0; + } + + if (ABS_ALT(arg2->unk_36.x) > 100) { + Math_SmoothStepToS(&arg2->unk_36.x, 0, 0xA, 0x64, 0xA); + } + + if (ABS_ALT(arg2->unk_36.z) > 100) { + Math_SmoothStepToS(&arg2->unk_36.z, 0, 0xA, 0x64, 0xA); + } + + if ((globalCtx->gameplayFrames % 8) == 0) { + sp34 = arg2->unk_00; + sp34.y = 30.0f; + EffectSsGRipple_Spawn(globalCtx, &sp34, 250, 650, 0); + } +} + +void func_80AD0028(EnFuKago* this, GlobalContext* globalCtx) { + EnFuKagoStruct* ptr = this->unk_1B8; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_1B8); i++) { + func_80ACFDAC(this, globalCtx, ptr); + + ptr->unk_0C.x += ptr->unk_18.x; + ptr->unk_0C.y += ptr->unk_18.y; + ptr->unk_0C.z += ptr->unk_18.z; + + ptr->unk_00.x += ptr->unk_0C.x; + ptr->unk_00.y += ptr->unk_0C.y; + ptr->unk_00.z += ptr->unk_0C.z; + + ptr->unk_30.x += ptr->unk_36.x; + ptr->unk_30.y += ptr->unk_36.y; + ptr->unk_30.z += ptr->unk_36.z; + + ptr++; + } + + if (this->unk_338 == 59) { + this->unk_1B8[3].unk_0C.x *= -1.0f; + this->unk_1B8[3].unk_0C.z *= -1.0f; + + this->unk_1B8[4].unk_0C.x *= -1.0f; + this->unk_1B8[4].unk_0C.z *= -1.0f; + } else if (this->unk_338 == 58) { + Vec3f sp34 = this->unk_1B8[5].unk_0C; + + this->unk_1B8[5].unk_0C.x = sp34.z; + this->unk_1B8[5].unk_0C.z = -sp34.x; + + sp34 = this->unk_1B8[2].unk_0C; + this->unk_1B8[2].unk_0C.x = -sp34.z; + this->unk_1B8[2].unk_0C.z = sp34.x; + + this->unk_1B8[5].unk_36.x *= -1; + this->unk_1B8[5].unk_36.y *= -1; + this->unk_1B8[5].unk_36.z *= -1; + + this->unk_1B8[2].unk_36.x *= -1; + this->unk_1B8[2].unk_36.y *= -1; + this->unk_1B8[2].unk_36.z *= -1; + } else if (this->unk_338 == 0) { + func_80AD0274(this); + } + this->unk_338--; +} + +void func_80AD0274(EnFuKago* this) { + this->actionFunc = func_80AD0288; +} + +void func_80AD0288(EnFuKago* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f* scale = &this->dyna.actor.scale; + + Math_SmoothStepToF(&scale->x, 0.0f, 0.1f, 0.005f, 0.005f); + scale->z = scale->x; + scale->y = scale->x; + if (scale->x == 0.0f) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void EnFuKago_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFuKago* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->unk_33C == 1) { + func_80AD0274(this); + } +} + +void func_80AD0340(EnFuKago* this, GlobalContext* globalCtx) { + s32 pad[2]; + EnFuKagoStruct* ptr = &this->unk_1B8[0]; + s32 i; + Vec3f* scale = &this->dyna.actor.scale; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(D_80AD061C); i++, ptr++) { + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &this->dyna.actor.shape.rot); + Matrix_Translate(ptr->unk_24.x, ptr->unk_24.y, ptr->unk_24.z, MTXMODE_APPLY); + Matrix_RotateZYX(ptr->unk_30.x, ptr->unk_30.y, ptr->unk_30.z, MTXMODE_APPLY); + Matrix_Translate(-ptr->unk_24.x, -ptr->unk_24.y, -ptr->unk_24.z, MTXMODE_APPLY); + Matrix_Scale(scale->x, scale->y, scale->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_80AD061C[i]); + + Matrix_Pop(); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFuKago_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFuKago* this = THIS; + + if (this->unk_33A == 0) { + 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_fu_mato_DL_0006A0); + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_000740); + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_0007E0); + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_000880); + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_000920); + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_0009C0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + func_80AD0340(this, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.h b/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.h index db37f2f2d..19022093e 100644 --- a/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.h +++ b/src/overlays/actors/ovl_En_Fu_Kago/z_en_fu_kago.h @@ -7,11 +7,23 @@ struct EnFuKago; typedef void (*EnFuKagoActionFunc)(struct EnFuKago*, GlobalContext*); +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3f unk_18; + /* 0x24 */ Vec3f unk_24; + /* 0x30 */ Vec3s unk_30; + /* 0x36 */ Vec3s unk_36; + /* 0x3C */ s16 unk_3C; +} EnFuKagoStruct; // size = 0x40 + typedef struct EnFuKago { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ EnFuKagoActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x1DC]; + /* 0x0160 */ ColliderSphere collider; + /* 0x01B8 */ EnFuKagoStruct unk_1B8[6]; + /* 0x0338 */ s16 unk_338; + /* 0x033A */ s16 unk_33A; /* 0x033C */ s16 unk_33C; } EnFuKago; // size = 0x340 diff --git a/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.c b/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.c index 3963a7eb9..4591eab65 100644 --- a/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.c +++ b/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.c @@ -1,6 +1,14 @@ -#include "z_en_fu_mato.h" +/* + * File: z_en_fu_mato.c + * Overlay: ovl_En_Fu_Mato + * Description: Honey & Darling's Shop - Target + */ -#define FLAGS 0x00000030 +#include "z_en_fu_mato.h" +#include "overlays/actors/ovl_En_Fu/z_en_fu.h" +#include "objects/object_fu_mato/object_fu_mato.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnFuMato*)thisx) @@ -9,7 +17,15 @@ void EnFuMato_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFuMato_Update(Actor* thisx, GlobalContext* globalCtx); void EnFuMato_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80ACE4B4(EnFuMato* this); +void func_80ACE4C8(EnFuMato* this, GlobalContext* globalCtx); +void func_80ACE508(EnFuMato* this); +void func_80ACE51C(EnFuMato* this, GlobalContext* globalCtx); +void func_80ACE718(EnFuMato* this, GlobalContext* globalCtx); +void func_80ACECFC(EnFuMato* this, GlobalContext* globalCtx); +void func_80ACEFC4(EnFuMato* this); +void func_80ACEFD8(EnFuMato* this, GlobalContext* globalCtx); + const ActorInit En_Fu_Mato_InitVars = { ACTOR_EN_FU_MATO, ACTORCAT_BG, @@ -22,52 +38,447 @@ const ActorInit En_Fu_Mato_InitVars = { (ActorFunc)EnFuMato_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80ACF610 = { - { COLTYPE_HIT3, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK4, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_HIT3, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK4, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 200 }, 100 }, }; -#endif +Gfx* D_80ACF63C[] = { + object_fu_mato_DL_001C80, object_fu_mato_DL_001D68, object_fu_mato_DL_001E50, + object_fu_mato_DL_001F38, object_fu_mato_DL_002020, object_fu_mato_DL_002108, +}; -extern ColliderSphereInit D_80ACF610; +Vec2f D_80ACF654[] = { + { -1.0f, -1.73f }, { 1.0f, -1.73f }, { 2.0f, 0.0f }, { 1.0f, 1.73f }, { -1.0f, 1.73f }, { -2.0f, 0.0f }, +}; -extern UNK_TYPE D_060023D4; -extern UNK_TYPE D_06002720; +void EnFuMato_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFuMato* this = THIS; + CollisionHeader* sp2C = NULL; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; + EnFu* fu; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/EnFuMato_Init.s") + DynaPolyActor_Init(&this->dyna, 3); + CollisionHeader_GetVirtual(&object_fu_mato_Colheader_0023D4, &sp2C); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp2C); + Actor_SetScale(&this->dyna.actor, 0.1f); + Collider_InitSphere(globalCtx, &this->collider); + Collider_SetSphere(globalCtx, &this->collider, &this->dyna.actor, &sSphereInit); + this->collider.dim.worldSphere.radius = 20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/EnFuMato_Destroy.s") + while (actor != NULL) { + if (actor->id == ACTOR_EN_FU) { + this->dyna.actor.parent = actor; + break; + } + actor = actor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE4B4.s") + if (actor == NULL) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE4C8.s") + fu = (EnFu*)this->dyna.actor.parent; + if (fu->unk_542 == 2) { + this->collider.info.elemType = ELEMTYPE_UNK0; + this->collider.dim.worldSphere.radius = 30; + } else { + this->collider.dim.worldSphere.radius = 17; + this->unk_2F8 = fu->unk_538; + this->unk_2F4 = fu->unk_520; + this->unk_2F0 = ENFUMATO_GET(&this->dyna.actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE508.s") + this->unk_302 = 0; + this->unk_304 = 0; + func_80ACE4B4(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE51C.s") +void EnFuMato_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFuMato* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE680.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroySphere(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE718.s") +void func_80ACE4B4(EnFuMato* this) { + this->actionFunc = func_80ACE4C8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACE850.s") +void func_80ACE4C8(EnFuMato* this, GlobalContext* globalCtx) { + EnFu* fu = (EnFu*)this->dyna.actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACEB2C.s") + if ((fu->unk_54A == 0) && (fu->unk_542 == 0)) { + func_80ACE508(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACECFC.s") +void func_80ACE508(EnFuMato* this) { + this->actionFunc = func_80ACE51C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACEFC4.s") +void func_80ACE51C(EnFuMato* this, GlobalContext* globalCtx) { + EnFu* fu = (EnFu*)this->dyna.actor.parent; + Vec3f sp30; + f32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACEFD8.s") + sp30.x = this->unk_2F8[this->unk_2F0].x; + sp30.y = this->unk_2F8[this->unk_2F0].y; + sp30.z = this->unk_2F8[this->unk_2F0].z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACF04C.s") + sp2C = Math_Vec3f_DistXZ(&this->dyna.actor.world.pos, &sp30); + this->dyna.actor.world.rot.y = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &sp30); + this->dyna.actor.world.rot.x = Math_Vec3f_Pitch(&this->dyna.actor.world.pos, &sp30); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/EnFuMato_Update.s") + if (sp2C < 10.0f) { + if (this->unk_2F0 < (this->unk_2F4 - 1)) { + this->unk_2F0++; + } else { + this->unk_2F0 = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACF1F4.s") + this->dyna.actor.speedXZ = 2.0f; + this->dyna.actor.shape.rot.y = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &this->dyna.actor.parent->world.pos); + Actor_MoveWithGravity(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/func_80ACF3F4.s") + if (fu->unk_54A != 0) { + func_80ACE4B4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fu_Mato/EnFuMato_Draw.s") +void func_80ACE680(EnFuMato* this) { + this->dyna.actor.gravity = -0.5f; + this->dyna.actor.velocity.y = 1.0f; + this->dyna.actor.velocity.x = 2.0f * Rand_Centered(); + this->dyna.actor.velocity.z = 2.0f * Rand_Centered(); + this->unk_2FC.x = Rand_Next() & 0xFFF; + this->unk_2FC.y = Rand_Next() & 0xFFF; + this->unk_2FC.z = Rand_Next() & 0xFFF; + this->unk_302 = 3; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WOODPLATE_BOUND); + this->actionFunc = func_80ACE718; +} + +void func_80ACE718(EnFuMato* this, GlobalContext* globalCtx) { + this->dyna.actor.shape.rot.x += this->unk_2FC.x; + this->dyna.actor.shape.rot.y += this->unk_2FC.y; + this->dyna.actor.shape.rot.z += this->unk_2FC.z; + this->dyna.actor.velocity.y += this->dyna.actor.gravity; + + Actor_UpdatePos(&this->dyna.actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 60.0f, 5); + + if ((this->dyna.actor.bgCheckFlags & 1) || (this->dyna.actor.world.pos.y < -500.0f)) { + Vec3f sp3C = { 0.0f, 0.0f, 0.0f }; + Vec3f sp30 = { 0.0f, 2.0f, 0.0f }; + + func_800B3030(globalCtx, &this->dyna.actor.world.pos, &sp3C, &sp30, 20, 40, 2); + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void func_80ACE850(EnFuMato* this, GlobalContext* globalCtx) { + EnFuMatoStruct* ptr = this->unk_1B8; + s16 temp_s4 = this->dyna.actor.shape.rot.y; + s32 phi_s2; + s32 i; + + this->unk_308 = (u32)Rand_Next() % ARRAY_COUNT(this->unk_1B8); + this->unk_302 = 1; + this->dyna.actor.gravity = -1.0f; + this->dyna.actor.velocity.y = Rand_ZeroOne(); + + phi_s2 = this->unk_308; + + for (i = 0; i < 2; i++) { + ptr->unk_00 = this->dyna.actor.world.pos; + + ptr->unk_0C.x = Math_CosS(temp_s4) * D_80ACF654[phi_s2].x; + ptr->unk_0C.y = D_80ACF654[phi_s2].z; + ptr->unk_0C.z = -Math_SinS(temp_s4) * D_80ACF654[phi_s2].x; + + ptr->unk_0C.x += Rand_Centered(); + ptr->unk_0C.y += Rand_ZeroOne() * 0.5f; + ptr->unk_0C.z += Rand_Centered(); + + ptr->unk_18.x = 0.0f; + ptr->unk_18.y = -1.0f; + ptr->unk_18.z = 0.0f; + + ptr->unk_00.x += 9.0f * ptr->unk_0C.x; + ptr->unk_00.y += 9.0f * ptr->unk_0C.y; + ptr->unk_00.z += 9.0f * ptr->unk_0C.z; + + ptr->unk_24 = this->dyna.actor.shape.rot; + + ptr->unk_2A.x = (s16)Rand_Next() >> 6; + ptr->unk_2A.y = (s16)Rand_Next() >> 6; + ptr->unk_2A.z = (s16)Rand_Next() >> 6; + ptr->unk_30 = 1; + + phi_s2 = (phi_s2 + 3) % ARRAY_COUNT(this->unk_1B8); + ptr++; + } + + this->dyna.actor.freezeTimer = 2; + EffectSsHahen_SpawnBurst(globalCtx, &this->dyna.actor.world.pos, 13.0f, 0, 7, 8, 20, -1, 10, NULL); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WOODPLATE_BROKEN); + this->actionFunc = func_80ACECFC; +} + +void func_80ACEB2C(EnFuMato* this) { + EnFuMatoStruct sp18[2]; + s32 phi_v0 = this->unk_308; + s32 i; + s32 phi_v1; + s32 phi_a1; + + sp18[0] = this->unk_1B8[0]; + sp18[1] = this->unk_1B8[1]; + + for (i = 0; i < ARRAY_COUNT(sp18); i++) { + if (phi_v0 == 0) { + phi_v1 = 5; + } else { + phi_v1 = phi_v0 - 1; + } + + if (phi_v0 == 5) { + phi_a1 = 0; + } else { + phi_a1 = phi_v0 + 1; + } + + this->unk_1B8[phi_v0] = sp18[i]; + this->unk_1B8[phi_v1] = sp18[i]; + this->unk_1B8[phi_a1] = sp18[i]; + + phi_v0 = (phi_v0 + 3) % ARRAY_COUNT(this->unk_1B8); + } + + this->unk_302 = 2; + this->actionFunc = func_80ACECFC; +} + +void func_80ACECFC(EnFuMato* this, GlobalContext* globalCtx) { + EnFuMatoStruct* ptr = this->unk_1B8; + s32 phi_s3; + s32 i; + + this->dyna.actor.velocity.y += this->dyna.actor.gravity; + Actor_UpdatePos(&this->dyna.actor); + + if (this->dyna.actor.world.pos.y < -500.0f) { + this->dyna.actor.world.pos.y = -500.0f; + } + + if (this->unk_302 == 1) { + phi_s3 = 2; + } else { + phi_s3 = ARRAY_COUNT(this->unk_1B8); + } + + for (i = 0; i < phi_s3; i++, ptr++) { + ptr->unk_00.x += ptr->unk_0C.x; + ptr->unk_00.y += ptr->unk_0C.y; + ptr->unk_00.z += ptr->unk_0C.z; + + ptr->unk_0C.x += ptr->unk_18.x; + ptr->unk_0C.y += ptr->unk_18.y; + ptr->unk_0C.z += ptr->unk_18.z; + + ptr->unk_24.x += ptr->unk_2A.x; + ptr->unk_24.y += ptr->unk_2A.y; + ptr->unk_24.z += ptr->unk_2A.z; + + if ((this->unk_302 == 2) && (ptr->unk_30 == 1) && (ptr->unk_00.y < (this->dyna.actor.floorHeight + 10.0f))) { + if (ptr->unk_0C.y < 0.0f) { + ptr->unk_0C.y = -ptr->unk_0C.y; + } else { + ptr->unk_0C.y = ptr->unk_0C.y; + } + ptr->unk_0C.y *= 0.5f; + ptr->unk_0C.x *= (Rand_Centered() * 1.5f) + 2.0f; + ptr->unk_0C.z *= (Rand_Centered() * 1.5f) + 2.0f; + + ptr->unk_2A.x = (s16)Rand_Next() >> 5; + ptr->unk_2A.y = (s16)Rand_Next() >> 5; + ptr->unk_2A.z = (s16)Rand_Next() >> 5; + + ptr->unk_30 = 0; + } + } + + if (this->unk_302 == 1) { + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 60.0f, 5); + if (this->dyna.actor.bgCheckFlags & 1) { + func_80ACEB2C(this); + } + } + + if (this->unk_304 < 60) { + this->unk_304++; + } else { + func_80ACEFC4(this); + } +} + +void func_80ACEFC4(EnFuMato* this) { + this->actionFunc = func_80ACEFD8; +} + +void func_80ACEFD8(EnFuMato* this, GlobalContext* globalCtx) { + Vec3f* scale = &this->dyna.actor.scale; + + Math_SmoothStepToF(&scale->x, 0.0f, 0.1f, 0.005f, 0.005f); + scale->y = scale->z = scale->x; + if (scale->x == 0.0f) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +s32 func_80ACF04C(EnFuMato* this, GlobalContext* globalCtx) { + EnFu* fu = (EnFu*)this->dyna.actor.parent; + + this->collider.dim.worldSphere.center.x = this->dyna.actor.world.pos.x; + this->collider.dim.worldSphere.center.y = this->dyna.actor.world.pos.y; + this->collider.dim.worldSphere.center.z = this->dyna.actor.world.pos.z; + + if ((this->unk_302 == 0) && (((fu->unk_542 == 0) && (this->collider.base.acFlags & AC_HIT)) || + ((fu->unk_542 == 2) && (this->collider.base.ocFlags1 & OC1_HIT)))) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.ocFlags1 &= ~OC1_HIT; + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_SY_TRE_BOX_APPEAR); + + fu->unk_548++; + if ((fu->unk_542 == 2) || (gSaveContext.save.playerForm == PLAYER_FORM_DEKU)) { + fu->unk_546 = 1; + func_80ACE680(this); + } else { + func_80ACE850(this, globalCtx); + } + return true; + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + return false; +} + +void EnFuMato_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFuMato* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80ACF04C(this, globalCtx); + + if (this->unk_30A == 1) { + func_80ACEFC4(this); + } +} + +void func_80ACF1F4(EnFuMato* this, GlobalContext* globalCtx) { + EnFuMatoStruct* ptr = this->unk_1B8; + s32 temp_s4 = this->unk_308; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < 2; i++) { + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &ptr->unk_24); + Matrix_Scale(0.1f, 0.1f, 0.1f, 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_80ACF63C[temp_s4]); + + switch (temp_s4) { + case 0: + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[5]); + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[temp_s4 + 1]); + break; + + case 5: + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[temp_s4 - 1]); + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[0]); + break; + + default: + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[temp_s4 - 1]); + gSPDisplayList(POLY_OPA_DISP++, D_80ACF63C[temp_s4 + 1]); + break; + } + + Matrix_Pop(); + + temp_s4 = (temp_s4 + 3) % ARRAY_COUNT(this->unk_1B8); + ptr++; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80ACF3F4(EnFuMato* this, GlobalContext* globalCtx) { + EnFuMatoStruct* ptr = this->unk_1B8; + Vec3f* scale = &this->dyna.actor.scale; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(D_80ACF63C); i++, ptr++) { + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &ptr->unk_24); + Matrix_Scale(scale->x, scale->y, scale->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_80ACF63C[i]); + + Matrix_Pop(); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFuMato_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFuMato* 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); + + if ((this->unk_302 == 0) || (this->unk_302 == 3)) { + gSPDisplayList(POLY_OPA_DISP++, object_fu_mato_DL_002720); + } else if (this->unk_302 == 1) { + func_80ACF1F4(this, globalCtx); + } else { + func_80ACF3F4(this, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.h b/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.h index 51dbf177f..5666b71fc 100644 --- a/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.h +++ b/src/overlays/actors/ovl_En_Fu_Mato/z_en_fu_mato.h @@ -7,11 +7,30 @@ struct EnFuMato; typedef void (*EnFuMatoActionFunc)(struct EnFuMato*, GlobalContext*); +#define ENFUMATO_GET(thisx) ((thisx)->params) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3f unk_18; + /* 0x24 */ Vec3s unk_24; + /* 0x2A */ Vec3s unk_2A; + /* 0x30 */ s16 unk_30; +} EnFuMatoStruct; // size = 0x34 + typedef struct EnFuMato { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ EnFuMatoActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x1AA]; + /* 0x0160 */ ColliderSphere collider; + /* 0x01B8 */ EnFuMatoStruct unk_1B8[6]; + /* 0x02F0 */ s32 unk_2F0; + /* 0x02F4 */ s32 unk_2F4; + /* 0x02F8 */ Vec3s* unk_2F8; + /* 0x02FC */ Vec3s unk_2FC; + /* 0x0302 */ s16 unk_302; + /* 0x0304 */ s16 unk_304; + /* 0x0306 */ UNK_TYPE1 unk306[2]; + /* 0x0308 */ s16 unk_308; /* 0x030A */ s16 unk_30A; } EnFuMato; // size = 0x30C 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 abf79af80..bd6f66e34 100644 --- a/src/overlays/actors/ovl_En_Fz/z_en_fz.c +++ b/src/overlays/actors/ovl_En_Fz/z_en_fz.c @@ -1,6 +1,15 @@ -#include "z_en_fz.h" +/* + * File: z_en_fz.c + * Overlay: ovl_En_Fz + * Description: Freezard + */ -#define FLAGS 0x00000015 +#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 (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnFz*)thisx) @@ -9,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, @@ -22,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), @@ -79,96 +155,872 @@ 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 &= ~ACTOR_FLAG_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->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 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_Translate(sp5C.x, sp5C.y, sp5C.z, MTXMODE_NEW); + Matrix_RotateZYX(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_MultVec3f(&sp44, &this->unk_22C); + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &sp5C, &this->unk_22C, &sp50, &sp3C, true, false, false, true, + &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) || + !Actor_TestFloorInDirection(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Actor_PlaySfxAtPos(&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->drawDmgEffTimer = 40; + this->drawDmgEffAlpha = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933B48.s") + case 15: + Actor_ApplyDamage(&this->actor); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0x2000, 8); + if (this->actor.colChkInfo.health != 0) { + Actor_PlaySfxAtPos(&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; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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 &= ~ACTOR_FLAG_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 |= ACTOR_FLAG_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_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + + 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_MultVec3f(&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 &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_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 |= ACTOR_FLAG_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_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + + 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_MultVec3f(&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 |= ACTOR_FLAG_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->drawDmgEffTimer != 0) { + if (this->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; + } + + if (this->drawDmgEffTimer < 20) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 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_SetFocus(&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_MoveWithGravity(&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->drawDmgEffTimer > 0) { + s32 pad2[6]; + Vec3f limbPos[2]; + s32 pad3; + + limbPos[0] = this->actor.world.pos; + limbPos[1] = this->actor.world.pos; + limbPos[0].y += 20.0f; + limbPos[1].y += 40.0f; + Actor_DrawDamageEffects(globalCtx, NULL, limbPos, ARRAY_COUNT(limbPos), this->drawDmgEffScale * 4.0f, 0.5f, + this->drawDmgEffAlpha, ACTOR_DRAW_DMGEFF_LIGHT_ORBS); + } + + 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++, gFrozenSteamDL); + 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_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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++, gFrozenSteamVtxDL); + } + } + + 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..19f462d0a 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 drawDmgEffAlpha; + /* 0xBA0 */ f32 drawDmgEffScale; + /* 0xBA4 */ s16 drawDmgEffTimer; + /* 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_Gakufu/z_en_gakufu.c b/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.c index 4bea50eb4..de6a752d8 100644 --- a/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.c +++ b/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.c @@ -1,6 +1,13 @@ -#include "z_en_gakufu.h" +/* + * File: z_en_gakufu.c + * Overlay: ovl_En_Gakufu + * Description: Termina Field - 2D Song Buttons Appearing on Wall + */ -#define FLAGS 0x02000010 +#include "z_en_gakufu.h" +#include "interface/parameter_static/parameter_static.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnGakufu*)thisx) @@ -9,13 +16,15 @@ void EnGakufu_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGakufu_Update(Actor* thisx, GlobalContext* globalCtx); void EnGakufu_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80AFCB94(EnGakufu* this, GlobalContext* globalCtx); -void func_80AFCBD4(EnGakufu* this, GlobalContext* globalCtx); -void func_80AFCC14(EnGakufu* this, GlobalContext* globalCtx); -void func_80AFCD44(EnGakufu* this, GlobalContext* globalCtx); -void func_80AFCDC8(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_ProcessNotes(EnGakufu* this); +s32 EnGakufu_IsPlayerInRange(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_DisplayOnTimer(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_WaitForTimer(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_DoNothing(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_GiveReward(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_PlayRewardCutscene(EnGakufu* this, GlobalContext* globalCtx); +void EnGakufu_WaitForSong(EnGakufu* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Gakufu_InitVars = { ACTOR_EN_GAKUFU, ACTORCAT_ITEMACTION, @@ -28,28 +37,256 @@ const ActorInit En_Gakufu_InitVars = { (ActorFunc)EnGakufu_Draw, }; -#endif +Vec3f sRewardDropsSpawnTerminaFieldPos = { + -710.0f, + -123.0f, + -3528.0f, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFC960.s") +/** + * Determines which set of `sRewardDrops` to collect when successfully playing the notes on the wall. + * Rewards come in batches of three, and the reward you get depends on the time of day. + */ +u8 sRewardDropsIndex[] = { + 3, // CLOCK_TIME(0, 0) to CLOCKTIME(1, 0) + 12, // CLOCK_TIME(1, 0) to CLOCKTIME(2, 0) + 6, // CLOCK_TIME(2, 0) to CLOCKTIME(3, 0) + 12, // CLOCK_TIME(3, 0) to CLOCKTIME(4, 0) + 9, // CLOCK_TIME(4, 0) to CLOCKTIME(5, 0) + 12, // CLOCK_TIME(5, 0) to CLOCKTIME(6, 0) + 0, // CLOCK_TIME(6, 0) to CLOCKTIME(7, 0) + 12, // CLOCK_TIME(7, 0) to CLOCKTIME(8, 0) + 3, // CLOCK_TIME(8, 0) to CLOCKTIME(9, 0) + 12, // CLOCK_TIME(9, 0) to CLOCKTIME(10, 0) + 6, // CLOCK_TIME(10, 0) to CLOCKTIME(11, 0) + 12, // CLOCK_TIME(11, 0) to CLOCKTIME(12, 0) + 3, // CLOCK_TIME(12, 0) to CLOCKTIME(13, 0) + 12, // CLOCK_TIME(13, 0) to CLOCKTIME(14, 0) + 6, // CLOCK_TIME(14, 0) to CLOCKTIME(15, 0) + 12, // CLOCK_TIME(15, 0) to CLOCKTIME(16, 0) + 3, // CLOCK_TIME(16, 0) to CLOCKTIME(17, 0) + 12, // CLOCK_TIME(17, 0) to CLOCKTIME(18, 0) + 6, // CLOCK_TIME(18, 0) to CLOCKTIME(19, 0) + 12, // CLOCK_TIME(19, 0) to CLOCKTIME(20, 0) + 9, // CLOCK_TIME(20, 0) to CLOCKTIME(21, 0) + 12, // CLOCK_TIME(21, 0) to CLOCKTIME(22, 0) + 6, // CLOCK_TIME(22, 0) to CLOCKTIME(23, 0) + 12, // CLOCK_TIME(23, 0) to CLOCKTIME(0, 0) +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/EnGakufu_Init.s") +/** + * The set of rewards when the song notes on the wall are played. + * Should be thought of as a 2D array: sRewardDrops[5][3] + * i.e. there are 5 sets of possible rewards. And each set gives out three rewards + */ +u8 sRewardDrops[] = { + ITEM00_RUPEE_RED, ITEM00_RUPEE_RED, ITEM00_RUPEE_RED, // Set 1 (index 0) + ITEM00_RUPEE_RED, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, // Set 2 (index 3) + ITEM00_RUPEE_BLUE, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_BLUE, // Set 3 (index 6) + ITEM00_RUPEE_RED, ITEM00_RUPEE_BLUE, ITEM00_RUPEE_BLUE, // Set 4 (index 9) + ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, // Set 5 (index 12) +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/EnGakufu_Destroy.s") +// y-offsets of ocarina buttons drawn on wall +f32 sOcarinaBtnWallYOffsets[] = { + -4.0f, -2.0f, 0.0f, 1.0f, 3.0f, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCB94.s") +TexturePtr sOcarinaBtnWallTextures[] = { + gOcarinaATex, gOcarinaCDownTex, gOcarinaCRightTex, gOcarinaCLeftTex, gOcarinaCUpTex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCBD4.s") +#include "overlays/ovl_En_Gakufu/ovl_En_Gakufu.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCC14.s") +void EnGakufu_ProcessNotes(EnGakufu* this) { + OcarinaStaff* playbackStaff; + OcarinaSongButtons* ocarinaSongButtons; + s32 songNumButtons; + s32 i; + s32 songIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCC24.s") + AudioOcarina_TerminaWallGenerateNotes(); + AudioOcarina_SetInstrumentId(OCARINA_INSTRUMENT_DEFAULT); + AudioOcarina_StartDefault((1 << this->songIndex) | 0x80000000); + playbackStaff = AudioOcarina_GetPlaybackStaff(); + playbackStaff->pos = 0; + playbackStaff->state = 0xFF; + AudioOcarina_SetInstrumentId(OCARINA_INSTRUMENT_OFF); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCC58.s") + songIndex = this->songIndex; + ocarinaSongButtons = &gOcarinaSongButtons[songIndex]; + songNumButtons = gOcarinaSongButtons[this->songIndex].numButtons; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCD44.s") + for (i = 0; i < songNumButtons; i++) { + this->buttonIndex[i] = ocarinaSongButtons->buttonIndex[i]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/func_80AFCDC8.s") + for (; i < ARRAY_COUNT(this->buttonIndex); i++) { + this->buttonIndex[i] = OCARINA_BTN_INVALID; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/EnGakufu_Update.s") +void EnGakufu_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGakufu* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gakufu/EnGakufu_Draw.s") + this->songIndex = OCARINA_SONG_TERMINA_WALL; + EnGakufu_ProcessNotes(this); + Actor_SetScale(&this->actor, 1.0f); + + if (GAKUFU_GET_TYPE(&this->actor) == GAKUFU_MILK_BAR) { + this->actor.draw = NULL; + this->actionFunc = EnGakufu_WaitForTimer; + return; + } + + this->actor.flags &= ~ACTOR_FLAG_2000000; + + if (EnGakufu_IsPlayerInRange(this, globalCtx)) { + gSaveContext.eventInf[3] |= 2; + } else { + gSaveContext.eventInf[3] &= (u8)~2; + } + + this->actionFunc = EnGakufu_WaitForSong; + gSaveContext.eventInf[3] &= (u8)~4; +} + +void EnGakufu_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGakufu* this = THIS; + + if (GAKUFU_GET_TYPE(&this->actor) != GAKUFU_MILK_BAR) { + gSaveContext.eventInf[3] &= (u8)~2; + } +} + +/** + * Special behaviour for the Milk Bar: + * this->actor.home.rot.x acts as a timer. Draws the notes on the back of the stage + * until the timer runs out + */ +void EnGakufu_DisplayOnTimer(EnGakufu* this, GlobalContext* globalCtx) { + if (this->actor.home.rot.x > 0) { + this->actor.draw = EnGakufu_Draw; + this->actor.home.rot.x--; + } else { + this->actor.draw = NULL; + this->actor.home.rot.x = 0; + this->actionFunc = EnGakufu_WaitForTimer; + } +} + +/** + * Special behaviour for the Milk Bar: + * this->actor.home.rot.x acts as a timer. Waits for this timer to be set, + * then rerolls the notes and start displaying the notes + */ +void EnGakufu_WaitForTimer(EnGakufu* this, GlobalContext* globalCtx) { + if (this->actor.home.rot.x > 0) { + EnGakufu_ProcessNotes(this); + this->actionFunc = EnGakufu_DisplayOnTimer; + } +} + +void EnGakufu_DoNothing(EnGakufu* this, GlobalContext* globalCtx) { +} + +s32 EnGakufu_IsPlayerInRange(EnGakufu* this, GlobalContext* globalCtx) { + if (this->actor.xzDistToPlayer < 600.0f) { + return true; + } else { + return false; + } +} + +/** + * Reward the player with three item drops depending on the time of day + */ +void EnGakufu_GiveReward(EnGakufu* this, GlobalContext* globalCtx) { + s32 hour; + s32 i; + + play_sound(NA_SE_SY_CORRECT_CHIME); + + hour = gSaveContext.save.time * (24.0f / 0x10000); + for (i = 0; i < 3; i++) { + Item_DropCollectible(globalCtx, &sRewardDropsSpawnTerminaFieldPos, sRewardDrops[i + sRewardDropsIndex[hour]]); + } + + this->actionFunc = EnGakufu_DoNothing; +} + +void EnGakufu_PlayRewardCutscene(EnGakufu* this, GlobalContext* globalCtx) { + if (this->actor.cutscene == -1) { + EnGakufu_GiveReward(this, globalCtx); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + EnGakufu_GiveReward(this, globalCtx); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +/** + * Waits for the notes on the wall to be played and updates the corresponding flags + * (gSaveContext.eventInf[3] & 2) is checking if Player is within range of the wall + * (gSaveContext.eventInf[3] & 4) is checking if Player has played the notes of the wall + */ +void EnGakufu_WaitForSong(EnGakufu* this, GlobalContext* globalCtx) { + if (gSaveContext.eventInf[3] & 2) { + if (gSaveContext.eventInf[3] & 4) { + gSaveContext.eventInf[3] &= (u8)~2; + gSaveContext.eventInf[3] &= (u8)~4; + + this->actionFunc = EnGakufu_PlayRewardCutscene; + EnGakufu_PlayRewardCutscene(this, globalCtx); + this->actor.draw = NULL; + } else if (!EnGakufu_IsPlayerInRange(this, globalCtx)) { + gSaveContext.eventInf[3] &= (u8)~2; + } + } else if (EnGakufu_IsPlayerInRange(this, globalCtx)) { + gSaveContext.eventInf[3] |= 2; + } +} + +void EnGakufu_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGakufu* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void EnGakufu_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 i; + s32 pad; + EnGakufu* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_XLU_DISP++); + gSPSegment(POLY_XLU_DISP++, 0x02, globalCtx->interfaceCtx.parameterSegment); + + for (i = 0; (i < ARRAY_COUNT(this->buttonIndex)) && (this->buttonIndex[i] != OCARINA_BTN_INVALID); i++) { + Matrix_Push(); + Matrix_Translate(30 * i - 105, sOcarinaBtnWallYOffsets[this->buttonIndex[i]] * 7.5f, 1.0f, MTXMODE_APPLY); + Matrix_Scale(0.6f, 0.6f, 0.6f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE); + gDPLoadTextureBlock(POLY_XLU_DISP++, sOcarinaBtnWallTextures[this->buttonIndex[i]], G_IM_FMT_IA, G_IM_SIZ_8b, + 16, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 4, G_TX_NOLOD, + G_TX_NOLOD); + + if (this->buttonIndex[i] == OCARINA_BTN_A) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 80, 150, 255, 200); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 50, 200); + } + + gSPDisplayList(POLY_XLU_DISP++, gGakufuButtonIndexDL); + + Matrix_Pop(); + } + + gSPSegment(POLY_XLU_DISP++, 0x02, globalCtx->sceneSegment); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.h b/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.h index b4bf8643c..9ba96a724 100644 --- a/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.h +++ b/src/overlays/actors/ovl_En_Gakufu/z_en_gakufu.h @@ -7,10 +7,18 @@ struct EnGakufu; typedef void (*EnGakufuActionFunc)(struct EnGakufu*, GlobalContext*); +#define GAKUFU_GET_TYPE(thisx) ((thisx)->params & 0xF) + +typedef enum { + /* 0x00 */ GAKUFU_TERMINA_FIELD, + /* 0x01 */ GAKUFU_MILK_BAR +} GakufuType; + typedef struct EnGakufu { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC]; - /* 0x0150 */ EnGakufuActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ s32 songIndex; + /* 0x148 */ u8 buttonIndex[8]; + /* 0x150 */ EnGakufuActionFunc actionFunc; } EnGakufu; // size = 0x154 extern const ActorInit En_Gakufu_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 e80c311d1..16547c112 100644 --- a/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c +++ b/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c @@ -1,6 +1,12 @@ +/* + * File: z_en_gamelupy.c + * Overlay: ovl_En_Gamelupy + * Description: Deku Scrub Playground Rupees + */ + #include "z_en_gamelupy.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnGamelupy*)thisx) 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 c1f3b53bd..41783a1b7 100644 --- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c +++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c @@ -1,6 +1,13 @@ -#include "z_en_gb2.h" +/* + * File: z_en_gb2.c + * Overlay: ovl_En_Gb2 + * Description: Spirit House - Owner + */ -#define FLAGS 0x00000039 +#include "z_en_gb2.h" +#include "objects/object_ps/object_ps.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnGb2*)thisx) @@ -9,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); @@ -23,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, @@ -40,98 +48,983 @@ 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.save.weekEventReg[54] & 0x20)) { + gSaveContext.save.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.save.playerData.health > 48) { + return 0x14D2; + } + + this->unk_26C |= 2; + return 0x14D3; + + case 0x14E4: + if (gSaveContext.save.playerData.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.save.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.save.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.save.weekEventReg[80] & 0x40)) { + this->unk_26E = 0x14EB; + return false; + } + this->unk_26E = 0x14EE; + return true; + } + + if (!(gSaveContext.save.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.ocarinaMode == 3) && (globalCtx->msgCtx.unk1202E == 7)) { + globalCtx->msgCtx.ocarinaMode = 4; + gSaveContext.eventInf[4] |= 0x80; + this->unk_26E = 0x14D1; + this->unk_288 = 10; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(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 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.msgMode = 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); + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + } + } + } else if ((temp_v0 == 4) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_26E == 0x14D5) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.save.playerData.rupees < this->unk_288) { + play_sound(NA_SE_SY_ERROR); + this->unk_26E = 0x14D7; + this->unk_26C |= 2; + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + } else { + func_8019F208(); + this->unk_26E = 0x14D8; + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + } + break; + + case 1: + func_8019F230(); + this->unk_26E = 0x14D6; + this->unk_26C |= 2; + Message_StartTextbox(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.msgMode = 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; + Message_StartTextbox(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.save.playerData.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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + this->actor.flags &= ~ACTOR_FLAG_10000; + this->actionFunc = func_80B10634; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + } +} + +void func_80B10634(EnGb2* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.msgMode = 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); + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + } + } + } else if ((temp_v0 == 4) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.save.playerData.rupees < this->unk_288) { + play_sound(NA_SE_SY_ERROR); + this->unk_26E = 0x14D7; + this->unk_26C |= 2; + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + } else { + func_8019F208(); + func_801159EC(-this->unk_288); + globalCtx->msgCtx.msgMode = 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; + Message_StartTextbox(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.save.weekEventReg[54] & 0x40) { + sp24 = 5; + } else { + sp24 = 12; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + if (sp24 == 12) { + gSaveContext.save.weekEventReg[54] |= 0x40; + } else { + func_801159EC(50); + } + this->actionFunc = func_80B109DC; + } else { + Actor_PickUp(&this->actor, globalCtx, sp24, 300.0f, 300.0f); + } +} + +void func_80B109DC(EnGb2* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(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) { + Flags_SetSwitch(globalCtx, ENGB2_GET_7F8(&this->actor)); + Actor_MarkForDeath(&this->actor); + } else { + this->actor.draw = NULL; + this->unk_26C |= 0x100; + this->actor.flags &= ~ACTOR_FLAG_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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (this->unk_26C & 0x40)) { + if ((this->unk_26E == 0x14EE) || (this->unk_26E == 0x14F4)) { + this->unk_26C |= 2; + } + Message_StartTextbox(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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (this->unk_26C & 0x20)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + if (this->unk_26E == 0x14EB) { + gSaveContext.save.weekEventReg[80] |= 0x40; + } else if (this->unk_26E == 0x14EF) { + gSaveContext.save.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 |= ACTOR_FLAG_10000; + 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 { + Flags_SetSwitch(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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_26C & 2) { + this->unk_26C &= ~2; + globalCtx->msgCtx.msgMode = 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); + Message_StartTextbox(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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + Message_StartTextbox(globalCtx, this->unk_26E, &this->actor); + this->actionFunc = func_80B10DAC; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 200.0f); + } +} + +void func_80B110F8(EnGb2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_26C &= ~2; + this->actionFunc = func_80B10A48; + } else { + this->unk_26E = func_80B0F97C(this); + Message_StartTextbox(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 (Flags_GetClear(globalCtx, 2) && Flags_GetClear(globalCtx, 3) && Flags_GetClear(globalCtx, 4) && + Flags_GetClear(globalCtx, 5)) { + this->unk_28A = 0xFF; + this->unk_26C &= ~0x100; + this->actor.flags |= ACTOR_FLAG_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, ActorShadow_DrawCircle, 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.save.weekEventReg[54] & 0x80) { + Actor_MarkForDeath(&this->actor); + } else if (gSaveContext.save.weekEventReg[52] & 0x20) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F660.s") + if (gSaveContext.save.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 |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_2000000; -#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.save.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 (Flags_GetClear(globalCtx, 2) && Flags_GetClear(globalCtx, 3) && Flags_GetClear(globalCtx, 4) && + Flags_GetClear(globalCtx, 5)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FB24.s") + if (gSaveContext.save.weekEventReg[76] & 0x80) { + this->actor.draw = NULL; + this->unk_26C |= 0x100; + this->actor.flags &= ~ACTOR_FLAG_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) { + Matrix_RotateYS(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_MultVec3f(&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 c7e133471..935eacb8c 100644 --- a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ge1.c + * Overlay: ovl_En_Ge1 + * Description: White-clad Gerudo Pirate + */ + #include "z_en_ge1.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnGe1*)thisx) 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 3622ae5c9..b8522c2c6 100644 --- a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ge2.c + * Overlay: ovl_En_Ge2 + * Description: Purple-clad Gerudo Pirate + */ + #include "z_en_ge2.h" -#define FLAGS 0x80000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_80000000) #define THIS ((EnGe2*)thisx) 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 b5c793db2..593c57a5a 100644 --- a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ge3.c + * Overlay: ovl_En_Ge3 + * Description: Aviel + */ + #include "z_en_ge3.h" -#define FLAGS 0x80000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnGe3*)thisx) 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 de611989e..79e5a3480 100644 --- a/src/overlays/actors/ovl_En_Geg/z_en_geg.c +++ b/src/overlays/actors/ovl_En_Geg/z_en_geg.c @@ -1,6 +1,17 @@ -#include "z_en_geg.h" +/* + * File: z_en_geg.c + * Overlay: ovl_En_Geg + * Description: Goron With Don Gero's Mask + */ -#define FLAGS 0x00000019 +#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 (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnGeg*)thisx) @@ -25,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, @@ -38,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), @@ -91,87 +125,964 @@ static DamageTable D_80BB3ED4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_oF1d_map_Anim_0039D8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_taisou_Anim_0016C8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_004DD4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_00283C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_007764, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_005EE0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_002C48, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_0031D8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_005790, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_003650, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_hakugin_demo_Anim_002704, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_hakugin_demo_Anim_003378, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_oF1d_map_Anim_0135E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_oF1d_map_Anim_014CE0, 1.0f, 0, -1, ANIMMODE_LOOP, 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.actorLists[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)->isPowderKeg == 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); + SubS_ChangeAnimationByInfoS(&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_IsFacingAndNearPlayer(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (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; + } + Message_StartTextbox(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB2520; + this->actor.flags &= ~ACTOR_FLAG_10000; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->unk_230 |= 4; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + } + } else { + this->unk_230 &= ~4; + if (gSaveContext.save.weekEventReg[35] & 0x40) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (this->unk_230 & 8)) { + this->unk_496 = 0xD62; + Message_StartTextbox(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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) && (this->unk_230 & 8)) { + gSaveContext.save.weekEventReg[35] |= 0x40; + this->unk_496 = 0xD5E; + this->unk_49A = this->unk_49C[0]; + Message_StartTextbox(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB2520; + this->unk_230 &= ~8; + this->actor.flags &= ~ACTOR_FLAG_10000; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= ACTOR_FLAG_10000; + 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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(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.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_230 &= ~0x10; + this->actionFunc = func_80BB221C; + return; + } + + this->unk_496 = func_80BB16D0(this); + Message_StartTextbox(globalCtx, this->unk_496, &this->actor); + } +} + +void func_80BB27D4(EnGeg* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (this->unk_496) { + case 0xD63: + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB221C; + break; + + case 0xD69: + this->unk_49A = this->unk_49C[6]; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB2520; + break; + + case 0xD6D: + case 0xD6F: + case 0xD8A: + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB31B8; + break; + + case 0xD72: + case 0xD75: + case 0xD8B: + globalCtx->msgCtx.msgMode = 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); + Message_StartTextbox(globalCtx, this->unk_496, &this->actor); + break; + } + } +} + +void func_80BB2944(EnGeg* this, GlobalContext* globalCtx) { + u8 sp27 = Message_GetState(&globalCtx->msgCtx); + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_4AC].animation); + + if (this->unk_4AC == 19) { + if (curFrame == lastFrame) { + this->unk_4AC = 6; + func_80BB2020(this, globalCtx); + } + } else if ((sp27 == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_496 == 0xD67) { + globalCtx->msgCtx.msgMode = 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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_496 == 0xD65) { + ActorCutscene_Stop(this->unk_498); + this->unk_230 &= ~0x10; + this->unk_244 = 65; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB347C; + } else { + this->unk_496 = func_80BB16D0(this); + Message_StartTextbox(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.save.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].animation); + + 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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + } +} + +void func_80BB30B4(EnGeg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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; + } + Message_StartTextbox(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB27D4; + this->actor.flags &= ~ACTOR_FLAG_10000; + } else if (this->actor.xzDistToPlayer < 150.0f) { + this->actor.flags |= ACTOR_FLAG_10000; + 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.save.weekEventReg[61] |= 1; + if (getItemId == GI_MASK_DON_GERO) { + this->unk_230 |= 0x40; + } + this->actionFunc = func_80BB32AC; + } else { + Actor_PickUp(&this->actor, globalCtx, getItemId, 300.0f, 300.0f); + } +} + +void func_80BB32AC(EnGeg* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(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_MoveWithGravity(&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.save.weekEventReg[61] & 1) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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); + SubS_FillLimbRotTables(globalCtx, this->unk_238, this->unk_232, ARRAY_COUNT(this->unk_238)); + 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_MultVec3f(&sp70, &sp7C); + Matrix_Get(&sp28); + Matrix_MtxFToYXZRot(&sp28, &sp68, false); + *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_MultVec3f(&D_80BB407C, &this->unk_4B4); + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sp38, &this->unk_4C0[0]); + Matrix_MultVec3f(&sp2C, &this->unk_4C0[1]); + Matrix_Pop(); + } +} + +void EnGeg_TransformLimbDraw(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_Pop(); + Matrix_Translate(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_RotateYS(this->unk_47C.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_47C.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_47C.z, MTXMODE_APPLY); + Matrix_Push(); + 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_Pop(); + Matrix_Translate(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_RotateYS(this->unk_490.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_490.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_490.z, MTXMODE_APPLY); + Matrix_Push(); + 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++); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGeg_OverrideLimbDraw, EnGeg_PostLimbDraw, + EnGeg_TransformLimbDraw, &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_Translate(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset, + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Translate(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_RotateXS(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..f5e9ad34d 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,42 @@ 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[3]; + /* 0x238 */ s16 unk_238[3]; + /* 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_Gg/z_en_gg.c b/src/overlays/actors/ovl_En_Gg/z_en_gg.c index 20fc87b43..2683e1296 100644 --- a/src/overlays/actors/ovl_En_Gg/z_en_gg.c +++ b/src/overlays/actors/ovl_En_Gg/z_en_gg.c @@ -1,6 +1,14 @@ -#include "z_en_gg.h" +/* + * File: z_en_gg.c + * Overlay: ovl_En_Gg + * Description: Darmani's Ghost + */ -#define FLAGS 0x00000089 +#include "z_en_gg.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_gg/object_gg.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_80) #define THIS ((EnGg*)thisx) @@ -9,7 +17,15 @@ void EnGg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGg_Update(Actor* thisx, GlobalContext* globalCtx); void EnGg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B352A4(EnGg* this, GlobalContext* globalCtx); +void func_80B35450(EnGg* this, GlobalContext* globalCtx); +void func_80B3556C(EnGg* this, GlobalContext* globalCtx); +u16 func_80B357F0(EnGg* this); +void func_80B358D8(EnGg* this, GlobalContext* globalCtx); +void func_80B359DC(EnGg* this, GlobalContext* globalCtx); +void func_80B363E8(EnGgStruct* ptr, GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3); +void func_80B364D4(EnGgStruct* ptr, GlobalContext* globalCtx); + const ActorInit En_Gg_InitVars = { ACTOR_EN_GG, ACTORCAT_NPC, @@ -22,18 +38,29 @@ const ActorInit En_Gg_InitVars = { (ActorFunc)EnGg_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B36C00 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, 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_NONE, + 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, + }, { 24, 72, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B36C2C = { 0, 24, 72, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 24, 72, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80B36C38 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -68,62 +95,719 @@ static DamageTable D_80B36C38 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -#endif +static AnimationInfo sAnimations[] = { + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00D528, 1.0f, 0.0f, 0.0f, 2, -10.0f }, + { &object_gg_Anim_00D174, 1.0f, 0.0f, 0.0f, 2, -10.0f }, { &object_gg_Anim_00ECC0, 1.0f, 0.0f, 0.0f, 2, -10.0f }, + { &object_gg_Anim_00BAF0, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00AF40, 1.0f, 0.0f, 0.0f, 0, -10.0f }, + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00AF40, 1.0f, 0.0f, 0.0f, 0, -10.0f }, + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_0100C8, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gg_Anim_00CDA0, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gg_Anim_00B560, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gg_Anim_00A4B4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_gg_Anim_00E86C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gg_Anim_00D99C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_gg_Anim_00E2A4, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +}; -extern ColliderCylinderInit D_80B36C00; -extern CollisionCheckInfoInit2 D_80B36C2C; -extern DamageTable D_80B36C38; +void func_80B34F70(EnGg* this) { + this->actor.focus.pos.x = this->actor.world.pos.x; + this->actor.focus.pos.y = this->actor.world.pos.y + 80.0f; + this->actor.focus.pos.z = this->actor.world.pos.z; -extern UNK_TYPE D_0600F578; + 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_Gg/func_80B34F70.s") +s32 func_80B34FB4(EnGg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; + s16 pitch; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B34FB4.s") + sp40 = player->actor.world.pos; + sp40.y = player->bodyPartsPos[7].y + 3.0f; + sp34 = this->actor.world.pos; + sp34.y += 70.0f; + pitch = Math_Vec3f_Pitch(&sp34, &sp40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35108.s") + if ((this->actor.xzDistToPlayer < 250.0f) && (this->actor.xzDistToPlayer > 50.0f) && + (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80) || (gSaveContext.save.weekEventReg[19] & 0x80))) { + Math_SmoothStepToS(&this->unk_2E8, pitch, 4, 0x2AA8, 1); + } else { + Math_SmoothStepToS(&this->unk_2E8, 0, 4, 0x2AA8, 1); + } + this->unk_2E8 = CLAMP(this->unk_2E8, 0, 0x1C70); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B351A4.s") +void func_80B35108(EnGg* 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35250.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 30.0f, 30.0f, 7); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B352A4.s") +void func_80B351A4(EnGg* this) { + if ((this->unk_2E6 == 2) || (this->unk_2E6 == 3)) { + this->unk_2E2 = 3; + } else { + s16 temp = this->unk_2E4 - 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35450.s") + if (temp >= 3) { + this->unk_2E2 = 0; + this->unk_2E4 = temp; + } else if (temp == 0) { + this->unk_2E2 = 2; + this->unk_2E4 = (s32)(Rand_ZeroOne() * 60.0f) + 20; + } else { + this->unk_2E2 = 1; + this->unk_2E4 = temp; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B3556C.s") +void func_80B35250(EnGg* this) { + this->unk_2E4 = 20; + this->unk_2E2 = 0; + this->unk_2E6 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80B35450; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35634.s") +void func_80B352A4(EnGg* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E6].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B357F0.s") + if (sp26 == lastFrame) { + switch (this->actor.textId) { + case 0xCE5: + this->unk_2E6 = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B3584C.s") + case 0xCE6: + case 0xCEC: + this->unk_2E6 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B358D8.s") + case 0xCE8: + this->unk_2E6 = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35968.s") + case 0xCE9: + this->unk_2E6 = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B359DC.s") + case 0xCED: + case 0xCEE: + this->unk_2E6 = 4; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35B24.s") + default: + this->unk_2E6 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + break; + } + gSaveContext.save.weekEventReg[19] |= 0x80; + this->actionFunc = func_80B3556C; + } else if ((this->unk_2E6 == 0) && ((this->actor.textId == 0xCED) || (this->actor.textId == 0xCEE))) { + if (sp26 < (lastFrame - 1)) { + this->skelAnime.playSpeed = 2.0f; + } else { + this->unk_2E6 = 4; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35B44.s") +void func_80B35450(EnGg* this, GlobalContext* globalCtx) { + if ((gSaveContext.save.weekEventReg[91] & 0x10) && (globalCtx->csCtx.state == 0)) { + func_80B359DC(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B35C84.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + func_800B90F4(globalCtx); + } + this->unk_308 = 1; + this->actionFunc = func_80B352A4; + } else if ((this->actor.xzDistToPlayer < 200.0f) && (this->actor.xzDistToPlayer > 50.0f)) { + if (gSaveContext.save.weekEventReg[19] & 0x80) { + func_800B863C(&this->actor, globalCtx); + this->actor.textId = 0xCEE; + } else if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + func_800B863C(&this->actor, globalCtx); + this->actor.textId = 0xCE5; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B3610C.s") +void func_80B3556C(EnGg* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_2E6 == 4) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_308 = 0; + this->actor.flags &= ~ACTOR_FLAG_80; + func_80B35250(this); + } else { + this->actor.textId = func_80B357F0(this); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + this->actionFunc = func_80B352A4; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B363E8.s") +void func_80B35634(EnGg* this, GlobalContext* globalCtx) { + s32 pad; + s32 actionIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B364D4.s") + if (Cutscene_CheckActorAction(globalCtx, 119)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 119); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/EnGg_Init.s") + if (this->unk_2DB != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->unk_2DB = globalCtx->csCtx.actorActions[actionIndex]->action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/EnGg_Destroy.s") + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + this->unk_2DA = 0; + this->unk_2E6 = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/EnGg_Update.s") + case 2: + this->unk_2DA = 9; + this->unk_2E6 = 9; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B368B0.s") + case 3: + this->unk_2DA = 10; + this->unk_2E6 = 10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/func_80B368F0.s") + case 4: + do { + this->unk_344.unk_30 = this->unk_2DA = 11; + } while (0); + this->unk_2E6 = 11; + func_80B364D4(&this->unk_344, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg/EnGg_Draw.s") + case 5: + do { + this->unk_344.unk_30 = this->unk_2DA = 12; + } while (0); + this->unk_2E6 = 12; + break; + + case 6: + do { + this->unk_344.unk_30 = this->unk_2DA = 13; + } while (0); + this->unk_2E6 = 13; + break; + + case 7: + do { + this->unk_344.unk_30 = this->unk_2DA = 14; + } while (0); + this->unk_2E6 = 14; + func_80B364D4(&this->unk_344, globalCtx); + break; + + case 8: + Actor_MarkForDeath(&this->actor); + return; + + default: + this->unk_2DA = 0; + break; + } + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_2DA); + } + + if (this->unk_2DA == 14) { + func_80B358D8(this, globalCtx); + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + this->actor.shape.yOffset = 0.0f; + } else { + this->unk_2DB = 99; + } +} + +u16 func_80B357F0(EnGg* this) { + switch (this->actor.textId) { + case 0xCE5: + return 0xCE6; + case 0xCE6: + return 0xCE8; + case 0xCE8: + return 0xCE9; + case 0xCE9: + return 0xCEC; + case 0xCEC: + return 0xCED; + } + return 0; +} + +void func_80B3584C(EnGg* this) { + this->unk_30A += 0x72C; + this->actor.shape.yOffset = Math_SinS(this->unk_30A) * 100.0f; + this->actor.shape.shadowScale = 30.0f - (Math_SinS(this->unk_30A) * 5.0f); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80B358D8(EnGg* this, GlobalContext* globalCtx) { + s16 sp1E = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2DA].animation); + + if ((this->unk_2E6 == 14) && (sp1E == lastFrame)) { + this->unk_2E6 = 15; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 15); + } +} + +void func_80B35968(EnGg* this, GlobalContext* globalCtx) { + if (this->unk_344.unk_34 != NULL) { + this->unk_344.unk_34(&this->unk_344, globalCtx); + } else { + if ((this->unk_2DA == 11) || (this->unk_2DA == 14)) { + this->unk_344.unk_30 = this->unk_2DA; + } + func_80B363E8(&this->unk_344, globalCtx, &this->unk_320, &this->unk_32C, &this->unk_338); + } +} + +void func_80B359DC(EnGg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actor.xzDistToPlayer < 200.0f) { + if (this->unk_306 == 0) { + if (player->stateFlags2 & 0x8000000) { + this->unk_306 = 1; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + } else if (!(player->stateFlags2 & 0x8000000)) { + this->unk_306 = 0; + } + + if ((player->transformation == PLAYER_FORM_HUMAN) && (globalCtx->msgCtx.ocarinaMode == 3) && + (globalCtx->msgCtx.unk1202E == 7)) { + if (!(gSaveContext.save.weekEventReg[19] & 0x80)) { + gSaveContext.save.weekEventReg[19] |= 0x80; + } + this->unk_307 = true; + } + + if (ActorCutscene_GetCanPlayNext(this->unk_2DC)) { + ActorCutscene_Start(this->unk_2DC, &this->actor); + this->unk_307 = false; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + + if (this->unk_307) { + ActorCutscene_SetIntentToPlay(this->unk_2DC); + } + } + } else { + this->unk_307 = false; + } +} + +void func_80B35B24(EnGgStruct* ptr, GlobalContext* globalCtx) { + ptr->unk_34 = NULL; + ptr->unk_38 = NULL; + ptr->unk_3C = 0; + ptr->unk_40 = 0; + ptr->unk_44 = 0; +} + +void func_80B35B44(EnGgStruct* ptr, GlobalContext* globalCtx) { + if (ptr->unk_30 == 0xE) { + ptr->unk_40++; + if (ptr->unk_40 > 0x46) { + ptr->unk_48 = 1; + ptr->unk_40 = 0; + } + + if (ptr->unk_40 != 0x46) { + if (ptr->unk_48 != 0) { + ptr->unk_44 = 0x37; + } else { + ptr->unk_44 = ptr->unk_40 - 15; + if (ptr->unk_44 < 0) { + ptr->unk_44 = 0; + } + } + } else { + ptr->unk_44++; + if (ptr->unk_44 > 0x37) { + ptr->unk_44 = 0x37; + } + } + } else if ((ptr->unk_30 == 11) || (ptr->unk_30 == 12)) { + ptr->unk_40++; + if (ptr->unk_40 > 0x46) { + ptr->unk_48 = 1; + ptr->unk_40 = 0; + } + } else if (ptr->unk_30 == 0xD) { + ptr->unk_48 = 0; + ptr->unk_40++; + if (ptr->unk_40 > 0x46) { + ptr->unk_40 = 0x46; + } + + if (ptr->unk_40 != 0x46) { + ptr->unk_44 = ptr->unk_40 - 15; + if (ptr->unk_44 < 0) { + ptr->unk_44 = 0; + } + } else { + ptr->unk_44++; + if (ptr->unk_44 > 0x37) { + func_80B364D4(ptr, globalCtx); + } + } + } +} + +void func_80B35C84(EnGgStruct* ptr, GlobalContext* globalCtx) { + s32 sp74; + s32 phi_s7; + f32 temp_f22; + f32 temp_f24; + f32 temp_f26; + f32 temp_f20; + s32 i; + s32 temp = 10; + + if (ptr->unk_48 != 0) { + sp74 = ptr->unk_40 % temp; + ptr->unk_40 = sp74; + phi_s7 = 0x46; + } else if (ptr->unk_30 == 0xD) { + sp74 = ptr->unk_40; + phi_s7 = 0x46; + } else { + phi_s7 = ptr->unk_40 - ptr->unk_44; + sp74 = ptr->unk_40 % temp; + } + + if (phi_s7 <= 0) { + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + + for (i = sp74; i < phi_s7; i += temp) { + temp_f20 = i * 0.14f; + temp_f22 = ptr->unk_00.x + (ptr->unk_18.x * temp_f20) + (0.5f * ptr->unk_24.x * temp_f20 * temp_f20); + temp_f24 = ptr->unk_00.y - Math_SinS((i * 0x27FFB) / 70); + temp_f26 = ptr->unk_00.z + (ptr->unk_18.z * temp_f20) + (0.5f * ptr->unk_24.z * temp_f20 * temp_f20); + temp_f20 = Rand_ZeroOne() * 0.003f; + + if (1) {} + + Matrix_Translate(temp_f22, temp_f24, temp_f26, MTXMODE_NEW); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 150, 0, 255); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Mult(&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++, gOwlStatueWhiteFlashDL); + } + + Matrix_Pop(); + + Matrix_Push(); + + for (i = sp74; i < phi_s7; i += temp) { + temp_f20 = i * 0.14f; + temp_f22 = ptr->unk_0C.x + ((ptr->unk_18.x * temp_f20) + (0.5f * ptr->unk_24.x * temp_f20 * temp_f20)); + temp_f24 = ptr->unk_0C.y - Math_SinS((i * 0x27FFB) / 70); + temp_f26 = ptr->unk_0C.z + (ptr->unk_18.z * temp_f20) + (0.5f * ptr->unk_24.z * temp_f20 * temp_f20); + temp_f20 = Rand_ZeroOne() * 0.003f; + + Matrix_Translate(temp_f22, temp_f24, temp_f26, MTXMODE_NEW); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 150, 0, 255); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Mult(&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++, gOwlStatueWhiteFlashDL); + } + + Matrix_Pop(); + + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80B3610C(EnGgStruct* ptr, GlobalContext* globalCtx) { + f32 temp_f20; + f32 temp_f24; + f32 temp_f26; + f32 temp_f28; + f32 temp_f30; + s32 phi_s4; + f32 phi_f22; + s32 i; + + if (ptr->unk_48 != 0) { + phi_s4 = 0x46; + } else { + phi_s4 = ptr->unk_40; + } + + if (phi_s4 > 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + + for (i = 0; i < phi_s4; i++) { + if (ptr->unk_48 != 0) { + phi_f22 = phi_s4 / 70.0f; + } else { + phi_f22 = i / 70.0f; + } + temp_f24 = ptr->unk_0C.x + (ptr->unk_18.x * i) + (0.5f * ptr->unk_24.x * i * i); + temp_f26 = ptr->unk_0C.y + (ptr->unk_18.y * i) + (0.5f * ptr->unk_24.y * i * i); + temp_f28 = ptr->unk_0C.z + (ptr->unk_18.z * i) + (0.5f * ptr->unk_24.z * i * i); + temp_f20 = Rand_ZeroOne() * 0.003f; + + Matrix_Translate((Rand_Centered() * (100.0f * phi_f22)) + temp_f24, temp_f26, + ((30.0f * phi_f22) * Rand_Centered()) + temp_f28, MTXMODE_NEW); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 150, 0, 255); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Mult(&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++, gOwlStatueWhiteFlashDL); + } + + Matrix_Pop(); + + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_80B363E8(EnGgStruct* ptr, GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3) { + ptr->unk_34 = func_80B35B44; + ptr->unk_00 = *arg1; + ptr->unk_0C = *arg1; + ptr->unk_18 = *arg2; + ptr->unk_24 = *arg3; + ptr->unk_48 = 0; + + ptr->unk_00.x += -4.0f; + ptr->unk_0C.x += 4.0f; + + if ((ptr->unk_30 == 11) || (ptr->unk_30 == 12) || (ptr->unk_30 == 13)) { + ptr->unk_38 = func_80B35C84; + } else if (ptr->unk_30 == 14) { + ptr->unk_38 = func_80B3610C; + } +} + +void func_80B364D4(EnGgStruct* ptr, GlobalContext* globalCtx) { + ptr->unk_34 = NULL; + ptr->unk_38 = NULL; + func_80B35B24(ptr, globalCtx); +} + +void EnGg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGg* this = THIS; + + if (INV_CONTENT(ITEM_MASK_GORON) == ITEM_MASK_GORON) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->actor.bgCheckFlags |= 0x400; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_gg_Skel_00F6C0, &object_gg_Anim_00F578, this->jointTable, + this->morphTable, 20); + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + this->actor.flags &= ~ACTOR_FLAG_80; + this->unk_310 = this->actor.home.pos.y; + this->unk_2DC = this->actor.cutscene; + this->actor.flags |= ACTOR_FLAG_2000000; + this->unk_308 = 0; + this->unk_309 = 0; + this->unk_304 = 0; + this->unk_30A = 0; + this->actor.flags |= ACTOR_FLAG_10; + func_80B35B24(&this->unk_344, globalCtx); + func_80B35250(this); +} + +void EnGg_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnGg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGg* this = THIS; + + if (globalCtx->actorCtx.unk4 == 100) { + this->actor.flags |= ACTOR_FLAG_80; + this->actor.flags |= ACTOR_FLAG_1; + } else { + this->actor.flags &= ~ACTOR_FLAG_80; + this->actor.flags &= ~ACTOR_FLAG_1; + } + + if (gSaveContext.save.weekEventReg[19] & 0x80) { + if (globalCtx->csCtx.state == 0) { + this->actor.flags |= ACTOR_FLAG_1; + } else { + this->actor.flags &= ~ACTOR_FLAG_1; + } + } + + if ((globalCtx->csCtx.state == 0) && + ((this->unk_2DA != 14) && (this->unk_2DA != 11) && (this->unk_2DA != 12) && (this->unk_2DA != 13))) { + func_80B364D4(&this->unk_344, globalCtx); + } + + if (((this->unk_2DA == 14) || (this->unk_2DA == 11) || (this->unk_2DA == 12) || (this->unk_2DA == 13)) && + (this->unk_309 == 1)) { + func_80B35968(this, globalCtx); + } + + if (!(gSaveContext.save.weekEventReg[91] & 0x10) && + ((gSaveContext.save.weekEventReg[19] & 0x80) || CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80) || + (this->unk_308 == 1))) { + gSaveContext.save.weekEventReg[91] |= 0x10; + } + + this->actionFunc(this, globalCtx); + + func_80B34F70(this); + func_80B35108(this, globalCtx); + func_80B34FB4(this, globalCtx); + Actor_MoveWithoutGravity(&this->actor); + SkelAnime_Update(&this->skelAnime); + + if (globalCtx->csCtx.state == 0) { + func_80B3584C(this); + } else { + this->unk_2E8 = 0; + } + + func_80B35634(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_1D8, &this->unk_1DE, this->actor.focus.pos); + func_80B351A4(this); +} + +s32 EnGg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnGg* this = THIS; + + if (limbIndex == 2) { + Matrix_RotateZS(this->unk_2E8, MTXMODE_APPLY); + } + return false; +} + +void EnGg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + static Vec3f D_80B36DF0 = { 1800.0f, 300.0f, 200.0f }; + EnGg* this = THIS; + Vec3f sp30 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp24 = { 0.0f, 0.0f, 0.0f }; + + if (this->unk_2DA == 14) { + sp30.y = 3.0f; + sp30.z = -1.0f; + sp24.y = -0.07f; + this->unk_309 = 1; + } else if ((this->unk_2DA == 11) || (this->unk_2DA == 12) || (this->unk_2DA == 13)) { + sp30.x = 3.0f; + sp24.x = 0.5f; + this->unk_309 = 1; + } else { + this->unk_309 = 0; + } + + if (limbIndex == 4) { + Matrix_MultVec3f(&D_80B36DF0, &this->unk_320); + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sp30, &this->unk_32C); + Matrix_MultVec3f(&sp24, &this->unk_338); + Matrix_Pop(); + } +} + +TexturePtr D_80B36DFC[] = { + object_gg_Tex_009260, + object_gg_Tex_009660, + object_gg_Tex_009A60, + object_gg_Tex_009E60, +}; + +void EnGg_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGg* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_344.unk_38 != 0) { + this->unk_344.unk_38(&this->unk_344, globalCtx); + } + + if (gSaveContext.save.weekEventReg[19] & 0x80) { + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B36DFC[this->unk_2E2])); + + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGg_OverrideLimbDraw, EnGg_PostLimbDraw, + &this->actor, POLY_OPA_DISP); + } else if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80) || (this->unk_308 == 1)) { + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B36DFC[this->unk_2E2])); + + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGg_OverrideLimbDraw, EnGg_PostLimbDraw, + &this->actor, POLY_XLU_DISP); + } + func_8012C2DC(globalCtx->state.gfxCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gg/z_en_gg.h b/src/overlays/actors/ovl_En_Gg/z_en_gg.h index f96a59548..eeb83cbbd 100644 --- a/src/overlays/actors/ovl_En_Gg/z_en_gg.h +++ b/src/overlays/actors/ovl_En_Gg/z_en_gg.h @@ -4,14 +4,57 @@ #include "global.h" struct EnGg; +struct EnGgStruct; typedef void (*EnGgActionFunc)(struct EnGg*, GlobalContext*); +typedef void (*EnGgUnkFunc)(struct EnGgStruct*, GlobalContext*); + +typedef struct EnGgStruct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3f unk_18; + /* 0x24 */ Vec3f unk_24; + /* 0x30 */ u8 unk_30; + /* 0x34 */ EnGgUnkFunc unk_34; + /* 0x38 */ EnGgUnkFunc unk_38; + /* 0x3C */ s32 unk_3C; + /* 0x40 */ s32 unk_40; + /* 0x44 */ s32 unk_44; + /* 0x48 */ u8 unk_48; +} EnGgStruct; // size == 0x4C typedef struct EnGg { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnGgActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x1B8]; + /* 0x01D8 */ Vec3s unk_1D8; + /* 0x01DE */ Vec3s unk_1DE; + /* 0x01E4 */ Vec3s jointTable[20]; + /* 0x025C */ Vec3s morphTable[20]; + /* 0x02D4 */ UNK_TYPE1 unk_2D4[0x6]; + /* 0x02DA */ u8 unk_2DA; + /* 0x02DB */ u8 unk_2DB; + /* 0x02DC */ s16 unk_2DC; + /* 0x02DE */ UNK_TYPE1 unk2DE[4]; + /* 0x02E2 */ s16 unk_2E2; + /* 0x02E4 */ s16 unk_2E4; + /* 0x02E6 */ s16 unk_2E6; + /* 0x02E8 */ s16 unk_2E8; + /* 0x02EA */ UNK_TYPE1 unk2EA[0x1A]; + /* 0x0304 */ s16 unk_304; + /* 0x0306 */ u8 unk_306; + /* 0x0307 */ u8 unk_307; + /* 0x0308 */ u8 unk_308; + /* 0x0309 */ u8 unk_309; + /* 0x030A */ s16 unk_30A; + /* 0x030C */ UNK_TYPE1 unk30C[4]; + /* 0x0310 */ f32 unk_310; + /* 0x0314 */ UNK_TYPE1 unk314[0xC]; + /* 0x0320 */ Vec3f unk_320; + /* 0x032C */ Vec3f unk_32C; + /* 0x0338 */ Vec3f unk_338; + /* 0x0344 */ EnGgStruct unk_344; } EnGg; // size = 0x390 extern const ActorInit En_Gg_InitVars; diff --git a/src/overlays/actors/ovl_En_Gg2/z_en_gg2.c b/src/overlays/actors/ovl_En_Gg2/z_en_gg2.c index 7fe7d43fb..46f0b657c 100644 --- a/src/overlays/actors/ovl_En_Gg2/z_en_gg2.c +++ b/src/overlays/actors/ovl_En_Gg2/z_en_gg2.c @@ -1,6 +1,13 @@ -#include "z_en_gg2.h" +/* + * File: z_en_gg2.c + * Overlay: ovl_En_Gg2 + * Description: Darmani's Ghost (2) + */ -#define FLAGS 0x00000089 +#include "z_en_gg2.h" +#include "objects/object_gg/object_gg.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_80) #define THIS ((EnGg2*)thisx) @@ -9,7 +16,17 @@ void EnGg2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGg2_Update(Actor* thisx, GlobalContext* globalCtx); void EnGg2_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B3AE60(EnGg2* this, GlobalContext* globalCtx); +void func_80B3AFB0(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B05C(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B0A0(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B120(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B21C(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B294(EnGg2* this, GlobalContext* globalCtx); +void func_80B3B5D4(EnGg2* this, GlobalContext* globalCtx); +s32 func_80B3B648(EnGg2* this, Path* path, s32 arg2_); +f32 func_80B3B7E4(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3); + const ActorInit En_Gg2_InitVars = { ACTOR_EN_GG2, ACTORCAT_NPC, @@ -22,48 +39,456 @@ const ActorInit En_Gg2_InitVars = { (ActorFunc)EnGg2_Draw, }; -#endif +AnimationInfo D_80B3BF00[] = { + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00D528, 1.0f, 0.0f, 0.0f, 2, -10.0f }, + { &object_gg_Anim_00D174, 1.0f, 0.0f, 0.0f, 2, -10.0f }, { &object_gg_Anim_00ECC0, 1.0f, 0.0f, 0.0f, 2, -10.0f }, + { &object_gg_Anim_00BAF0, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00AF40, 1.0f, 0.0f, 0.0f, 0, -10.0f }, + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_00AF40, 1.0f, 0.0f, 0.0f, 0, -10.0f }, + { &object_gg_Anim_00F578, 1.0f, 0.0f, 0.0f, 0, -10.0f }, { &object_gg_Anim_0100C8, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gg_Anim_00CDA0, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gg_Anim_00B560, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gg_Anim_00A4B4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_gg_Anim_00E86C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gg_Anim_00D99C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_gg_Anim_00E2A4, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +}; -extern UNK_TYPE D_0600F578; +Color_RGBA8 D_80B3C080 = { 255, 255, 255, 255 }; +Color_RGBA8 D_80B3C084 = { 255, 150, 0, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3AC50.s") +Vec3f D_80B3C088 = { 0.0f, 0.0f, 0.0f }; +Vec3f D_80B3C094 = { 0.0f, 0.0f, 0.0f }; +Vec3f D_80B3C0A0 = { 1000.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3AC94.s") +TexturePtr D_80B3C0AC[] = { + object_gg_Tex_009260, + object_gg_Tex_009660, + object_gg_Tex_009A60, + object_gg_Tex_009E60, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3ADD8.s") +void func_80B3AC50(EnGg2* this) { + this->actor.focus.pos.x = this->actor.world.pos.x; + this->actor.focus.pos.y = this->actor.world.pos.y + 80.0f; + this->actor.focus.pos.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3AE60.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; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3AFB0.s") +s32 func_80B3AC94(EnGg2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; + s16 pitch; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B05C.s") + sp40 = player->actor.world.pos; + sp40.y = player->bodyPartsPos[7].y + 3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B0A0.s") + sp34 = this->actor.world.pos; + sp34.y += 70.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B120.s") + pitch = Math_Vec3f_Pitch(&sp34, &sp40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B21C.s") + if ((this->actor.xzDistToPlayer < 250.0f) && (this->actor.xzDistToPlayer > 50.0f) && + CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + Math_SmoothStepToS(&this->unk_2F4, pitch, 4, 0x2AA8, 1); + } else { + Math_SmoothStepToS(&this->unk_2F4, 0, 4, 0x2AA8, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B294.s") + this->unk_2F4 = CLAMP(this->unk_2F4, 0, 0x1C70); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B4B0.s") +void func_80B3ADD8(EnGg2* this) { + s16 temp_v0 = this->unk_2EC - 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B5D4.s") + if (temp_v0 >= 3) { + this->unk_2EA = 0; + this->unk_2EC = temp_v0; + } else if (temp_v0 == 0) { + this->unk_2EA = 2; + this->unk_2EC = (s32)(Rand_ZeroOne() * 60.0f) + 20; + } else { + this->unk_2EA = 1; + this->unk_2EC = temp_v0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B648.s") +void func_80B3AE60(EnGg2* this, GlobalContext* globalCtx) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(D_80B3BF00[this->unk_2EE].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B7E4.s") + if (curFrame == lastFrame) { + switch (this->unk_2EE) { + case 0: + this->unk_2EE = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 1); + this->actionFunc = func_80B3B0A0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3B8A4.s") + case 1: + case 8: + this->unk_2EE = 5; + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 5); + this->actionFunc = func_80B3B120; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/EnGg2_Init.s") + case 5: + this->unk_2EE = 6; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 0); + this->actionFunc = func_80B3B21C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/EnGg2_Destroy.s") + case 6: + this->unk_2EE = 7; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 5); + this->actionFunc = func_80B3B294; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/EnGg2_Update.s") + default: + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 0); + this->actionFunc = func_80B3AFB0; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3BD44.s") +void func_80B3AFB0(EnGg2* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_2F0 = 1; + this->actionFunc = func_80B3AE60; + } else if ((this->actor.xzDistToPlayer < 100.0f) && (this->actor.xzDistToPlayer > 50.0f) && + CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + func_800B863C(&this->actor, globalCtx); + this->actor.textId = 0xCE4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/func_80B3BDC0.s") +void func_80B3B05C(EnGg2* this, GlobalContext* globalCtx) { + if ((this->actor.xzDistToPlayer < 100.0f) && CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + this->actionFunc = func_80B3B5D4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gg2/EnGg2_Draw.s") +void func_80B3B0A0(EnGg2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_2F0 = 0; + this->actionFunc = func_80B3B5D4; + } +} + +void func_80B3B120(EnGg2* this, GlobalContext* globalCtx) { + Vec3s sp30; + + if (this->unk_1D8 != NULL) { + func_80B3B7E4(this->unk_1D8, this->unk_1DC, &this->actor.world.pos, &sp30); + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.shape.rot.x, sp30.x, 4, 0x3E8, 1); + this->actor.world.rot.x = -this->actor.shape.rot.x; + if (func_80B3B648(this, this->unk_1D8, this->unk_1DC) != 0) { + if (this->unk_1DC >= (this->unk_1D8->count - 2)) { + this->actionFunc = func_80B3AE60; + this->actor.speedXZ = 0.0f; + } else { + this->unk_1DC++; + } + } + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 1.0f); + } +} + +void func_80B3B21C(EnGg2* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + if ((this->actor.xzDistToPlayer < 100.0f) && CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80)) { + this->unk_2E4 = ActorCutscene_GetAdditionalCutscene(this->unk_2E4); + this->actionFunc = func_80B3B5D4; + } +} + +void func_80B3B294(EnGg2* this, GlobalContext* globalCtx) { + Vec3s sp30; + + if (this->unk_2F1 == 0) { + if (globalCtx->sceneNum == SCENE_11GORONNOSATO) { + gSaveContext.save.weekEventReg[20] |= 4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + } else if (globalCtx->sceneNum == SCENE_17SETUGEN) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] |= 8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + } else if (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] |= 0x10; + } + + if (this->unk_1D8 != NULL) { + func_80B3B7E4(this->unk_1D8, this->unk_1DC, &this->actor.world.pos, &sp30); + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.shape.rot.x, sp30.x, 4, 0x3E8, 1); + this->actor.world.rot.x = -this->actor.shape.rot.x; + + if (func_80B3B648(this, this->unk_1D8, this->unk_1DC)) { + if (this->unk_1DC < (this->unk_1D8->count - 1)) { + this->unk_1DC++; + } else { + this->unk_2F1 = 1; + if (globalCtx->sceneNum == SCENE_11GORONNOSATO) { + gSaveContext.save.weekEventReg[20] |= 4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + } else if (globalCtx->sceneNum == SCENE_17SETUGEN) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] |= 8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + } else if (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] |= 0x10; + } + } + } + } + } + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 1.0f); +} + +void func_80B3B4B0(EnGg2* this, GlobalContext* globalCtx) { + Vec3f sp64; + Color_RGBA8 sp60 = D_80B3C080; + Color_RGBA8 sp5C = D_80B3C084; + s32 i; + + for (i = 0; i < 5; i++) { + sp64.x = (Rand_Centered() * 50.0f) + this->unk_304.x; + sp64.y = this->unk_304.y; + sp64.z = (Rand_Centered() * 50.0f) + this->unk_304.z; + EffectSsKirakira_SpawnDispersed(globalCtx, &sp64, &D_80B3C088, &D_80B3C094, &sp60, &sp5C, 3000, 40); + } +} + +void func_80B3B5D4(EnGg2* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->unk_2E4)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2E4, &this->actor); + this->actionFunc = func_80B3AE60; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_2E4); + } +} + +s32 func_80B3B648(EnGg2* this, Path* path, s32 arg2_) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 arg2 = arg2_; + s32 ret = false; + f32 phi_f12; + f32 phi_f14; + f32 sp44; + f32 sp40; + f32 sp3C; + Vec3f sp30; + + Math_Vec3s_ToVec3f(&sp30, &points[arg2]); + + if (arg2 == 0) { + phi_f12 = points[1].x - points[0].x; + phi_f14 = points[1].z - points[0].z; + } else if ((sp58 - 1) == arg2) { + phi_f12 = points[sp58 - 1].x - points[sp58 - 2].x; + phi_f14 = points[sp58 - 1].z - points[sp58 - 2].z; + } else { + phi_f12 = points[arg2 + 1].x - points[arg2 - 1].x; + phi_f14 = points[arg2 + 1].z - points[arg2 - 1].z; + } + + 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) { + ret = true; + } + return ret; +} + +f32 func_80B3B7E4(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3) { + Vec3s* points; + Vec3f sp20; + + if (path != NULL) { + points = Lib_SegmentedToVirtual(path->points); + points = &points[arg1]; + sp20.x = points->x; + sp20.y = points->y; + sp20.z = points->z; + } + + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + return sp20.y - arg2->y; +} + +void func_80B3B8A4(EnGg2* this) { + f32 sp1C; + + if ((this->unk_2EE != 5) && (this->unk_2EE != 7)) { + this->unk_2F2 += 0x62C; + sp1C = 1100.0f; + } else { + this->unk_2F2 += 0x7BC; + sp1C = 950.0f; + } + + this->actor.shape.yOffset = Math_SinS(this->unk_2F2) * sp1C; + this->actor.shape.shadowScale = 30.0f - (Math_SinS(this->unk_2F2) * 5.0f); + this->unk_2F6 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; +} + +void EnGg2_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnGg2* this = THIS; + + if (INV_CONTENT(ITEM_MASK_GORON) == ITEM_MASK_GORON) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (gSaveContext.save.weekEventReg[91] & 0x10) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->actor.bgCheckFlags |= 0x400; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_gg_Skel_00F6C0, &object_gg_Anim_00F578, this->jointTable, + this->morphTable, 20); + this->unk_1D8 = SubS_GetPathByIndex(globalCtx, ENGG2_GET_FC00(&this->actor), 0x3F); + this->actor.flags &= ~ACTOR_FLAG_80; + this->unk_2F0 = 0; + this->unk_2F1 = 0; + this->unk_2F2 = 0; + this->unk_2F4 = 0; + this->unk_2F6 = 0; + this->unk_2E4 = this->actor.cutscene; + this->unk_2EC = 20; + this->unk_2EA = 0; + + if (globalCtx->sceneNum == SCENE_11GORONNOSATO) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + this->unk_2EE = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 0); + this->actionFunc = func_80B3AFB0; + } else if (globalCtx->sceneNum == SCENE_17SETUGEN) { + if ((gSaveContext.save.weekEventReg[20] & 4) && !(gSaveContext.save.weekEventReg[20] & 8) && + !(gSaveContext.save.weekEventReg[20] & 0x10)) { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + this->unk_2EE = 8; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 0); + this->actionFunc = func_80B3B05C; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA) { + if (!(gSaveContext.save.weekEventReg[20] & 4) && (gSaveContext.save.weekEventReg[20] & 8) && + !(gSaveContext.save.weekEventReg[20] & 0x10)) { + gSaveContext.save.weekEventReg[20] &= (u8)~8; + this->unk_2EE = 8; + Actor_ChangeAnimationByInfo(&this->skelAnime, D_80B3BF00, 0); + this->actionFunc = func_80B3B05C; + } else { + Actor_MarkForDeath(&this->actor); + } + } else { + gSaveContext.save.weekEventReg[20] &= (u8)~4; + gSaveContext.save.weekEventReg[20] &= (u8)~8; + gSaveContext.save.weekEventReg[20] &= (u8)~0x10; + Actor_MarkForDeath(&this->actor); + } +} + +void EnGg2_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnGg2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGg2* this = THIS; + + if (globalCtx->actorCtx.unk4 == 100) { + this->actor.flags |= ACTOR_FLAG_80; + this->actor.flags |= ACTOR_FLAG_1; + if ((this->unk_2EE == 5) && (this->unk_2EE == 7)) { + this->actor.flags &= ~ACTOR_FLAG_1; + } + } else { + this->actor.flags &= ~ACTOR_FLAG_80; + this->actor.flags &= ~ACTOR_FLAG_1; + } + + this->actionFunc(this, globalCtx); + + func_80B3AC50(this); + func_80B3AC94(this, globalCtx); + Actor_MoveWithoutGravity(&this->actor); + SkelAnime_Update(&this->skelAnime); + func_80B3B8A4(this); + func_800E9250(globalCtx, &this->actor, &this->unk_1E0, &this->unk_1E6, this->actor.focus.pos); + + if ((this->unk_2EE == 5) || (this->unk_2EE == 7)) { + func_800B9010(&this->actor, NA_SE_EN_SHARP_FLOAT - SFX_FLAG); + if ((globalCtx->actorCtx.unk4 == 100) && ((globalCtx->state.frames % 4) == 0)) { + func_80B3B4B0(this, globalCtx); + } + } + + func_80B3ADD8(this); +} + +s32 func_80B3BD44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnGg2* this = THIS; + + if ((this->unk_2EE != 5) && (this->unk_2EE != 7)) { + if (limbIndex == 1) { + Matrix_RotateYS(this->unk_2F6, MTXMODE_APPLY); + } + + if (limbIndex == 2) { + Matrix_RotateZS(this->unk_2F4, MTXMODE_APPLY); + } + } + return false; +} + +void func_80B3BDC0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnGg2* this = THIS; + + if (limbIndex == 4) { + Matrix_MultVec3f(&D_80B3C0A0, &this->unk_304); + } +} + +void EnGg2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnGg2* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_80) || (this->unk_2F0 == 1)) { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B3C0AC[this->unk_2EA])); + + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, func_80B3BD44, func_80B3BDC0, &this->actor, POLY_XLU_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gg2/z_en_gg2.h b/src/overlays/actors/ovl_En_Gg2/z_en_gg2.h index dc4684272..0fea44822 100644 --- a/src/overlays/actors/ovl_En_Gg2/z_en_gg2.h +++ b/src/overlays/actors/ovl_En_Gg2/z_en_gg2.h @@ -7,11 +7,32 @@ struct EnGg2; typedef void (*EnGg2ActionFunc)(struct EnGg2*, GlobalContext*); +#define ENGG2_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + typedef struct EnGg2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ UNK_TYPE1 unk144[0x4C]; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnGg2ActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x138]; + /* 0x01D8 */ Path* unk_1D8; + /* 0x01DC */ s32 unk_1DC; + /* 0x01E0 */ Vec3s unk_1E0; + /* 0x01E6 */ Vec3s unk_1E6; + /* 0x01EC */ Vec3s jointTable[20]; + /* 0x0264 */ Vec3s morphTable[20]; + /* 0x02DC */ UNK_TYPE1 unk2DC[0x8]; + /* 0x02E4 */ s16 unk_2E4; + /* 0x02E6 */ UNK_TYPE1 unk2E6[4]; + /* 0x02EA */ s16 unk_2EA; + /* 0x02EC */ s16 unk_2EC; + /* 0x02EE */ s16 unk_2EE; + /* 0x02F0 */ u8 unk_2F0; + /* 0x02F1 */ u8 unk_2F1; + /* 0x02F2 */ s16 unk_2F2; + /* 0x02F4 */ s16 unk_2F4; + /* 0x02F6 */ s16 unk_2F6; + /* 0x02F8 */ UNK_TYPE1 unk2F8[0xC]; + /* 0x0304 */ Vec3f unk_304; } EnGg2; // size = 0x310 extern const ActorInit En_Gg2_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 62da9b9f6..26dfcb756 100644 --- a/src/overlays/actors/ovl_En_Giant/z_en_giant.c +++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.c @@ -6,7 +6,7 @@ #include "z_en_giant.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnGiant*)thisx) @@ -19,6 +19,59 @@ void EnGiant_PerformClockTowerSuccessActions(EnGiant* this, GlobalContext* globa void EnGiant_PlayClockTowerFailureAnimation(EnGiant* this, GlobalContext* globalCtx); void EnGiant_PerformCutsceneActions(EnGiant* this, GlobalContext* globalCtx); +#define GIANT_TYPE_IS_NOT_TERMINA_FIELD(type) (type > GIANT_TYPE_OCEAN_TERMINA_FIELD) +#define GIANT_TYPE_IS_TERMINA_FIELD(type) (type <= GIANT_TYPE_OCEAN_TERMINA_FIELD) +#define GIANT_TYPE_IS_CLOCK_TOWER_SUCCESS(type) \ + (type >= GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_SUCCESS && type <= GIANT_TYPE_OCEAN_CLOCK_TOWER_SUCCESS) +#define GIANT_TYPE_IS_CHAMBER_OR_ENDING(type) \ + (type >= GIANT_TYPE_MOUNTAIN_GIANTS_CHAMBER_AND_ENDING && type <= GIANT_TYPE_OCEAN_GIANTS_CHAMBER_AND_ENDING) +#define GIANT_TYPE_IS_CLOCK_TOWER_FAILURE(type) \ + (type >= GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_FAILURE && type <= GIANT_TYPE_OCEAN_CLOCK_TOWER_FAILURE) + +/** + * These values are used to index into sAnimations to pick the appropriate animation. + */ +typedef enum { + /* 0 */ GIANT_ANIMATION_LOOK_UP_START, + /* 1 */ GIANT_ANIMATION_LOOK_UP_LOOP, + /* 2 */ GIANT_ANIMATION_FALLING_OVER, + /* 3 */ GIANT_ANIMATION_RAISED_ARMS_START, + /* 4 */ GIANT_ANIMATION_RAISED_ARMS_LOOP, + /* 5 */ GIANT_ANIMATION_STRUGGLE_START, + /* 6 */ GIANT_ANIMATION_STRUGGLE_LOOP, + /* 7 */ GIANT_ANIMATION_IDLE_LOOP, + /* 8 */ GIANT_ANIMATION_WALKING_LOOP, + /* 9 */ GIANT_ANIMATION_BIG_CALL_START, + /* 10 */ GIANT_ANIMATION_BIG_CALL_LOOP, + /* 11 */ GIANT_ANIMATION_BIG_CALL_END, + /* 12 */ GIANT_ANIMATION_SMALL_CALL_START, + /* 13 */ GIANT_ANIMATION_SMALL_CALL_LOOP, + /* 14 */ GIANT_ANIMATION_SMALL_CALL_END, + /* 15 */ GIANT_ANIMATION_MAX +} GiantAnimationIndex; + +/** + * Used as values for csAction. The UNKNOWN ones are never used in-game. + */ +typedef enum { + /* 0 */ GIANT_CS_ACTION_NONE, + /* 1 */ GIANT_CS_ACTION_IDLE, + /* 2 */ GIANT_CS_ACTION_WALKING, + /* 3 */ GIANT_CS_ACTION_LOOKING_UP, + /* 4 */ GIANT_CS_ACTION_RAISING_ARMS, + /* 5 */ GIANT_CS_ACTION_STRUGGLING, + /* 6 */ GIANT_CS_ACTION_FALLING_OVER, + /* 7 */ GIANT_CS_ACTION_IDLE_FADE_IN, + /* 8 */ GIANT_CS_ACTION_TALKING, + /* 9 */ GIANT_CS_ACTION_DONE_TALKING, + /* 10 */ GIANT_CS_ACTION_TEACHING_OATH_TO_ORDER, + /* 11 */ GIANT_CS_ACTION_PLAYER_LEARNED_OATH_TO_ORDER, + /* 12 */ GIANT_CS_ACTION_UNKNOWN_12, + /* 13 */ GIANT_CS_ACTION_UNKNOWN_13, + /* 14 */ GIANT_CS_ACTION_UNKNOWN_14, + /* 15 */ GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER +} GiantCsActionIndex; + const ActorInit En_Giant_InitVars = { ACTOR_EN_GIANT, ACTORCAT_NPC, @@ -31,41 +84,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; } @@ -77,7 +110,7 @@ s32 EnGiant_IsImprisoned(EnGiant* this) { case GIANT_TYPE_SWAMP_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_SWAMP_GIANTS_CHAMBER_AND_ENDING: case GIANT_TYPE_SWAMP_CLOCK_TOWER_FAILURE: - if (!CHECK_QUEST_ITEM(0)) { + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA)) { return true; } break; @@ -85,7 +118,7 @@ s32 EnGiant_IsImprisoned(EnGiant* this) { case GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_MOUNTAIN_GIANTS_CHAMBER_AND_ENDING: case GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_FAILURE: - if (!CHECK_QUEST_ITEM(1)) { + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT)) { return true; } break; @@ -93,7 +126,7 @@ s32 EnGiant_IsImprisoned(EnGiant* this) { case GIANT_TYPE_OCEAN_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_OCEAN_GIANTS_CHAMBER_AND_ENDING: case GIANT_TYPE_OCEAN_CLOCK_TOWER_FAILURE: - if (!CHECK_QUEST_ITEM(2)) { + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG)) { return true; } break; @@ -101,7 +134,7 @@ s32 EnGiant_IsImprisoned(EnGiant* this) { case GIANT_TYPE_CANYON_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_CANYON_GIANTS_CHAMBER_AND_ENDING: case GIANT_TYPE_CANYON_CLOCK_TOWER_FAILURE: - if (!CHECK_QUEST_ITEM(3)) { + if (!CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { return true; } break; @@ -118,59 +151,63 @@ 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; this->actor.draw = NULL; this->alpha = 0; this->actor.velocity.y = -10.0f; - this->actor.minVelocityY = -10.0f; + this->actor.terminalVelocity = -10.0f; this->actor.gravity = -5.0f; switch (type) { 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 = 454; 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 = 455; 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 = 456; break; default: - this->unk_24A = 0x1C5; + this->actorActionCommand = 453; break; } if (GIANT_TYPE_IS_CLOCK_TOWER_SUCCESS(type)) { - if (!(gSaveContext.weekEventReg[0x19] & 2)) { + if (!(gSaveContext.save.weekEventReg[25] & 2)) { 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; + this->actor.terminalVelocity = 0.0f; this->actor.gravity = 0.0f; } 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; + this->actor.terminalVelocity = 0.0f; this->actor.gravity = 0.0f; if (EnGiant_IsImprisoned(this)) { Actor_MarkForDeath(&this->actor); @@ -204,7 +241,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 +303,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; } } @@ -333,10 +371,10 @@ void EnGiant_PlaySound(EnGiant* this) { if (this->actor.draw != NULL && this->alpha > 0) { if (this->animationId == GIANT_ANIMATION_WALKING_LOOP && (Animation_OnFrame(&this->skelAnime, 40.0f) || Animation_OnFrame(&this->skelAnime, 100.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_KYOJIN_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KYOJIN_WALK); } if (this->animationId == GIANT_ANIMATION_FALLING_OVER && Animation_OnFrame(&this->skelAnime, 40.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_KYOJIN_VOICE_FAIL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KYOJIN_VOICE_FAIL); } if (this->sfxId != 0xFFFF && ((this->animationId == GIANT_ANIMATION_BIG_CALL_START && this->skelAnime.curFrame >= 18.0f) || @@ -351,21 +389,23 @@ void EnGiant_PlaySound(EnGiant* this) { } void EnGiant_UpdatePosition(EnGiant* this, GlobalContext* globalCtx, u32 actionIndex) { - CsCmdActorAction* actorAction = globalCtx->csCtx.npcActions[actionIndex]; - f32 floatUnk10 = actorAction->unk10; + CsCmdActorAction* actorAction = globalCtx->csCtx.actorActions[actionIndex]; + f32 startPosY = actorAction->startPos.y; s32 pad[2]; - f32 floatUnk1C = actorAction->unk1C; - f32 functionTemp; + f32 endPosY = actorAction->endPos.y; + f32 scale = Environment_LerpWeight(actorAction->endFrame, actorAction->startFrame, globalCtx->csCtx.frames); - 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 (Cutscene_CheckActorAction(globalCtx, this->actorActionCommand)) { + EnGiant_UpdatePosition(this, globalCtx, Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)); + if (this->csAction != + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)]->action) { + this->csAction = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)] + ->action; EnGiant_ChangeAnimationBasedOnCsAction(this); } EnGiant_UpdateAlpha(this); @@ -385,10 +425,14 @@ 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 (Cutscene_CheckActorAction(globalCtx, this->actorActionCommand)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)); + if (this->csAction != + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)]->action) { + this->csAction = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand)] + ->action; EnGiant_ChangeAnimationBasedOnCsAction(this); } EnGiant_UpdateAlpha(this); @@ -407,7 +451,7 @@ void EnGiant_Update(Actor* thisx, GlobalContext* globalCtx) { s32 blinkTimerTemp; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (this->blinkTimer == 0) { @@ -427,10 +471,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 +484,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_Get(&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 +517,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_Mult(&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..c8d45ad39 100644 --- a/src/overlays/actors/ovl_En_Giant/z_en_giant.h +++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.h @@ -2,13 +2,9 @@ #define Z_EN_GIANT_H #include "global.h" +#include "objects/object_giant/object_giant.h" #define GIANT_TYPE(thisx) ((thisx)->params & 0xF) -#define GIANT_TYPE_IS_NOT_TERMINA_FIELD(type) (type > GIANT_TYPE_OCEAN_TERMINA_FIELD) -#define GIANT_TYPE_IS_TERMINA_FIELD(type) (type <= GIANT_TYPE_OCEAN_TERMINA_FIELD) -#define GIANT_TYPE_IS_CLOCK_TOWER_SUCCESS(type) (type >= GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_SUCCESS && type <= GIANT_TYPE_OCEAN_CLOCK_TOWER_SUCCESS) -#define GIANT_TYPE_IS_CHAMBER_OR_ENDING(type) (type >= GIANT_TYPE_MOUNTAIN_GIANTS_CHAMBER_AND_ENDING && type <= GIANT_TYPE_OCEAN_GIANTS_CHAMBER_AND_ENDING) -#define GIANT_TYPE_IS_CLOCK_TOWER_FAILURE(type) (type >= GIANT_TYPE_MOUNTAIN_CLOCK_TOWER_FAILURE && type <= GIANT_TYPE_OCEAN_CLOCK_TOWER_FAILURE) /** * The giants are divided into types based on where in the game they appear. @@ -42,50 +38,6 @@ typedef enum { /* 15 */ GIANT_TYPE_OCEAN_CLOCK_TOWER_FAILURE, } GiantType; -/** - * These values are used to index into sAnimationTable to pick the appropriate animation. - */ -typedef enum { - /* 0 */ GIANT_ANIMATION_LOOK_UP_START, - /* 1 */ GIANT_ANIMATION_LOOK_UP_LOOP, - /* 2 */ GIANT_ANIMATION_FALLING_OVER, - /* 3 */ GIANT_ANIMATION_RAISED_ARMS_START, - /* 4 */ GIANT_ANIMATION_RAISED_ARMS_LOOP, - /* 5 */ GIANT_ANIMATION_STRUGGLE_START, - /* 6 */ GIANT_ANIMATION_STRUGGLE_LOOP, - /* 7 */ GIANT_ANIMATION_IDLE_LOOP, - /* 8 */ GIANT_ANIMATION_WALKING_LOOP, - /* 9 */ GIANT_ANIMATION_BIG_CALL_START, - /* 10 */ GIANT_ANIMATION_BIG_CALL_LOOP, - /* 11 */ GIANT_ANIMATION_BIG_CALL_END, - /* 12 */ GIANT_ANIMATION_SMALL_CALL_START, - /* 13 */ GIANT_ANIMATION_SMALL_CALL_LOOP, - /* 14 */ GIANT_ANIMATION_SMALL_CALL_END, - /* 15 */ GIANT_ANIMATION_MAX -} GiantAnimationIndex; - -/** - * Used as values for csAction. The UNKNOWN ones are never used in-game. - */ -typedef enum { - /* 0 */ GIANT_CS_ACTION_NONE, - /* 1 */ GIANT_CS_ACTION_IDLE, - /* 2 */ GIANT_CS_ACTION_WALKING, - /* 3 */ GIANT_CS_ACTION_LOOKING_UP, - /* 4 */ GIANT_CS_ACTION_RAISING_ARMS, - /* 5 */ GIANT_CS_ACTION_STRUGGLING, - /* 6 */ GIANT_CS_ACTION_FALLING_OVER, - /* 7 */ GIANT_CS_ACTION_IDLE_FADE_IN, - /* 8 */ GIANT_CS_ACTION_TALKING, - /* 9 */ GIANT_CS_ACTION_DONE_TALKING, - /* 10 */ GIANT_CS_ACTION_TEACHING_OATH_TO_ORDER, - /* 11 */ GIANT_CS_ACTION_PLAYER_LEARNED_OATH_TO_ORDER, - /* 12 */ GIANT_CS_ACTION_UNKNOWN_12, - /* 13 */ GIANT_CS_ACTION_UNKNOWN_13, - /* 14 */ GIANT_CS_ACTION_UNKNOWN_14, - /* 15 */ GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER -} GiantCsActionIndex; - struct EnGiant; typedef void (*EnGiantActionFunc)(struct EnGiant*, GlobalContext*); @@ -93,14 +45,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 9997acd54..300987214 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 @@ -1,6 +1,13 @@ -#include "z_en_ginko_man.h" +/* + * File: z_en_ginko_man.c + * Overlay: ovl_En_Ginko_Man + * Description: Bank Teller + */ -#define FLAGS 0x00000009 +#include "z_en_ginko_man.h" +#include "objects/object_boj/object_boj.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnGinkoMan*)thisx) @@ -23,14 +30,6 @@ void EnGinkoMan_Stamp(EnGinkoMan* this, GlobalContext* globalCtx); void EnGinkoMan_Dialogue(EnGinkoMan* this, GlobalContext* globalCtx); void EnGinkoMan_SwitchAnimation(EnGinkoMan* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_0600C240; // object_ginko_skeleton -extern Gfx D_0600B1D8[]; // object_ginko_limb15_dlist -extern AnimationHeader D_060008C0; // object_ginko_floorsmacking_anim -extern AnimationHeader D_060043F0; // object_ginko_sitting_anim -extern AnimationHeader D_06004A7C; // object_ginko_amazed_anim -extern AnimationHeader D_06004F40; // object_ginko_stamp_reach_anim -extern AnimationHeader D_06000AC4; // object_ginko_advertising_anim - const ActorInit En_Ginko_Man_InitVars = { ACTOR_EN_GINKO_MAN, ACTORCAT_NPC, @@ -43,12 +42,12 @@ const ActorInit En_Ginko_Man_InitVars = { (ActorFunc)EnGinkoMan_Draw, }; -ActorAnimationEntry animations[] = { - { &D_060008C0, 1.0f, 0.0f, 0.0f, 0, -4.0f }, - { &D_060043F0, 1.0f, 0.0f, 0.0f, 0, -4.0f }, - { &D_06004F40, 1.0f, 0.0f, 0.0f, 2, -4.0f }, - { &D_06000AC4, 1.0f, 0.0f, 0.0f, 0, -4.0f }, // looking around for customers - { &D_06004A7C, 1.0f, 0.0f, 0.0f, 0, -4.0f }, +static AnimationInfo sAnimations[] = { + { &object_boj_Anim_0008C0, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_boj_Anim_0043F0, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_boj_Anim_004F40, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0f }, + { &object_boj_Anim_000AC4, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, // looking around for customers + { &object_boj_Anim_004A7C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, }; void EnGinkoMan_Init(Actor* thisx, GlobalContext* globalCtx) { @@ -63,7 +62,8 @@ void EnGinkoMan_Init(Actor* thisx, GlobalContext* globalCtx) { this->isStampChecked = false; this->choiceDepositWithdrawl = GINKOMAN_CHOICE_RESET; this->serviceFee = 0; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600C240, &D_060043F0, this->jointTable, this->morphTable, 16); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_boj_Skel_00C240, &object_boj_Anim_0043F0, this->jointTable, + this->morphTable, 16); EnGinkoMan_SetupIdle(this); } @@ -71,8 +71,8 @@ void EnGinkoMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void EnGinkoMan_SetupIdle(EnGinkoMan* this) { - this->actor.flags |= 1; // targetable - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); + this->actor.flags |= ACTOR_FLAG_1; // targetable + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); this->actionFunc = EnGinkoMan_Idle; } @@ -80,18 +80,18 @@ void EnGinkoMan_Idle(EnGinkoMan* this, GlobalContext* globalCtx) { s32 yaw = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; EnGinkoMan_SwitchAnimation(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { // Listen for dialogue start? - if ((gSaveContext.roomInf[127][0] & 0xFFFF) == 0) { - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - func_801518B0(globalCtx, 0x44C, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if ((gSaveContext.save.bankRupees & 0xFFFF) == 0) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + Message_StartTextbox(globalCtx, 0x44C, &this->actor); this->curTextId = 0x44C; // would you like to make an account } else { - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - if ((CURRENT_DAY == 3) && (gSaveContext.isNight == 1)) { - func_801518B0(globalCtx, 0x467, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + if ((CURRENT_DAY == 3) && (gSaveContext.save.isNight == true)) { + Message_StartTextbox(globalCtx, 0x467, &this->actor); this->curTextId = 0x467; // "What's this? You need somethin' on a day like this? } else { - func_801518B0(globalCtx, 0x466, &this->actor); + Message_StartTextbox(globalCtx, 0x466, &this->actor); this->curTextId = 0x466; // What's this? You need somethin'? } } @@ -103,29 +103,29 @@ void EnGinkoMan_Idle(EnGinkoMan* this, GlobalContext* globalCtx) { // action func: non-input dialogue void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { - if (!func_80147624(globalCtx)) { + if (!Message_ShouldAdvance(globalCtx)) { return; } switch (this->curTextId) { case 0x44C: // "Hey there, little guy! Won't you deposit some Rupees? (first dialogue) - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - if (gSaveContext.weekEventReg[10] & 8) { - func_801518B0(globalCtx, 0x44E, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + if (gSaveContext.save.weekEventReg[10] & 8) { + Message_StartTextbox(globalCtx, 0x44E, &this->actor); this->curTextId = 0x44E; //" ...So, what'll it be? Deposit Rupees Don't deposit Rupees" } else { - func_801518B0(globalCtx, 0x44D, &this->actor); + Message_StartTextbox(globalCtx, 0x44D, &this->actor); this->curTextId = 0x44D; // "For example, if you deposit 200 Rupees, you'll get an item that holds a lot of Rupees." } break; case 0x44D: // "For example, if you deposit 200 Rupees, you'll get an item that holds a lot of Rupees." - func_801518B0(globalCtx, 0x44E, &this->actor); + Message_StartTextbox(globalCtx, 0x44E, &this->actor); this->curTextId = 0x44E; //" ...So, what'll it be? Deposit Rupees Don't deposit Rupees" break; case 0x44F: // "...So, what'll it be? Deposit Rupees Don't deposit Rupees" - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - func_801518B0(globalCtx, 0x450, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + Message_StartTextbox(globalCtx, 0x450, &this->actor); this->curTextId = 0x450; // "How much? How much? [rupee prompt] break; @@ -135,55 +135,55 @@ void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { if (this->isNewAccount == true) { this->isNewAccount = false; if (this->curTextId != 0x453) { // "That's it? That ain't nothing at all, big spender! - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); } - func_801518B0(globalCtx, 0x461, &this->actor); + Message_StartTextbox(globalCtx, 0x461, &this->actor); this->curTextId = 0x461; // So, little guy, what's your name? } else { if (this->curTextId == 0x453) { // "That's it? That ain't nothing at all, big spender! - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); } - globalCtx->msgCtx.bankRupees = gSaveContext.roomInf[127][0] & 0xFFFF; - func_801518B0(globalCtx, 0x45A, &this->actor); + globalCtx->msgCtx.bankRupees = gSaveContext.save.bankRupees & 0xFFFF; + Message_StartTextbox(globalCtx, 0x45A, &this->actor); this->curTextId = 0x45A; // "All right, little guy, now I've got a total of [rupees] from you!" } break; case 0x456: // "Is that so? Think about it, little guy!" case 0x459: // "Heyyy! You don't have that much! - func_801518B0(globalCtx, 0x44E, &this->actor); + Message_StartTextbox(globalCtx, 0x44E, &this->actor); this->curTextId = 0x44E; //" ...So, what'll it be? Deposit Rupees Don't deposit Rupees" break; case 0x45A: // "All right, little guy, now I've got a total of [rupees] from you!" - if (((gSaveContext.roomInf[127][0] & 0xFFFF) >= 200) && (this->previousBankValue < 200) && - !(gSaveContext.weekEventReg[59] & 0x40)) { - gSaveContext.weekEventReg[59] |= 0x40; - func_801518B0(globalCtx, 0x45B, &this->actor); + if (((gSaveContext.save.bankRupees & 0xFFFF) >= 200) && (this->previousBankValue < 200) && + !(gSaveContext.save.weekEventReg[59] & 0x40)) { + gSaveContext.save.weekEventReg[59] |= 0x40; + Message_StartTextbox(globalCtx, 0x45B, &this->actor); this->curTextId = 0x45B; // "What's this? You've already saved up 200 Rupees!?! - } else if (((gSaveContext.roomInf[127][0] & 0xFFFF) >= 1000) && ((this->previousBankValue) < 1000) && - !(gSaveContext.weekEventReg[59] & 0x80)) { - gSaveContext.weekEventReg[59] |= 0x80; - func_801518B0(globalCtx, 0x45C, &this->actor); + } else if (((gSaveContext.save.bankRupees & 0xFFFF) >= 1000) && ((this->previousBankValue) < 1000) && + !(gSaveContext.save.weekEventReg[59] & 0x80)) { + gSaveContext.save.weekEventReg[59] |= 0x80; + Message_StartTextbox(globalCtx, 0x45C, &this->actor); this->curTextId = 0x45C; // "What's this? You've already saved up 1000 Rupees!?! - } else if ((gSaveContext.roomInf[127][0] & 0xFFFF) >= 5000) { - if ((this->previousBankValue < 5000) && !(gSaveContext.weekEventReg[60] & 1)) { - gSaveContext.weekEventReg[60] |= 1; - func_801518B0(globalCtx, 0x45D, &this->actor); + } else if ((gSaveContext.save.bankRupees & 0xFFFF) >= 5000) { + if ((this->previousBankValue < 5000) && !(gSaveContext.save.weekEventReg[60] & 1)) { + gSaveContext.save.weekEventReg[60] |= 1; + Message_StartTextbox(globalCtx, 0x45D, &this->actor); this->curTextId = 0x45D; // "What's this? You've already saved up 5000 Rupees?! - } else if (this->previousBankValue < (s16)(gSaveContext.roomInf[127][0] & 0xFFFF)) { - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x45E, &this->actor); + } else if (this->previousBankValue < (s16)(gSaveContext.save.bankRupees & 0xFFFF)) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x45E, &this->actor); this->curTextId = 0x45E; // "...Hang on there, little guy. I can't take any more deposits. Sorry..." } else { - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - func_801518B0(globalCtx, 0x460, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + Message_StartTextbox(globalCtx, 0x460, &this->actor); this->curTextId = 0x460; // "Come back and deposit some after you save up a bunch!" } } else { - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - func_801518B0(globalCtx, 0x460, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + Message_StartTextbox(globalCtx, 0x460, &this->actor); this->curTextId = 0x460; // "Come back and deposit some after you save up a bunch!" } break; @@ -196,30 +196,30 @@ void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { EnGinkoMan_BankAward(this, globalCtx); break; case 0x461: // So, little guy, what's your name? - func_801518B0(globalCtx, 0x462, &this->actor); + Message_StartTextbox(globalCtx, 0x462, &this->actor); this->curTextId = 0x462; // Hmm... Link is it? break; case 0x462: // Hmm.. Link is it? - func_801518B0(globalCtx, 0x463, &this->actor); + Message_StartTextbox(globalCtx, 0x463, &this->actor); this->curTextId = 0x463; // Got it... I won't forget your deposits. Let me stamp you break; case 0x463: // Got it... I won't forget your deposits. Let me stamp you - func_801518B0(globalCtx, 0x464, &this->actor); + Message_StartTextbox(globalCtx, 0x464, &this->actor); this->curTextId = 0x464; // Hey, relax! It doesn't leave any marks break; case 0x464: // Hey, relax! It doesn't leave any marks - globalCtx->msgCtx.unk11F22 = 0x44; + globalCtx->msgCtx.msgMode = 0x44; EnGinkoMan_SetupStamp(this); // stamp player break; case 0x465: // "There! Now I'll know you when I see you!" - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - globalCtx->msgCtx.bankRupees = gSaveContext.roomInf[127][0] & 0xFFFF; - func_801518B0(globalCtx, 0x45A, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + globalCtx->msgCtx.bankRupees = gSaveContext.save.bankRupees & 0xFFFF; + Message_StartTextbox(globalCtx, 0x45A, &this->actor); this->curTextId = 0x45A; // "All right, little guy, now I've got a total of [rupees] from you!" break; case 0x466: // What's this? You need somethin'? case 0x467: // "What's this? You need somethin' on a day like this? You haven't evacuated yet? - func_801518B0(globalCtx, 0x468, &this->actor); + Message_StartTextbox(globalCtx, 0x468, &this->actor); this->curTextId = 0x468; // " Deposit Rupees Withdraw Rupees Nothing really" break; case 0x469: // "Excuse me, but let me take a look at you..." @@ -229,39 +229,39 @@ void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { case 0x46C: // "Ah, yes...[Link], right? If I remember, you're the little guy who deposited [rupees]." case 0x47E: // "Your deposits total [rupees]." if (this->choiceDepositWithdrawl == GINKOMAN_CHOICE_DEPOSIT) { - if ((u32)(gSaveContext.roomInf[127][0] & 0xFFFF) >= 5000) { - func_801518B0(globalCtx, 0x45F, &this->actor); + if ((u32)(gSaveContext.save.bankRupees & 0xFFFF) >= 5000) { + Message_StartTextbox(globalCtx, 0x45F, &this->actor); this->curTextId = 0x45F; // "Excuuuse me! But I can't take anymore deposits! - } else if (gSaveContext.rupees == 0) { - func_801518B0(globalCtx, 0x458, &this->actor); + } else if (gSaveContext.save.playerData.rupees == 0) { + Message_StartTextbox(globalCtx, 0x458, &this->actor); this->curTextId = 0x458; // "Hmm...You play mean jokes, little guy! You haven't even got a single Rupee! } else { - func_801518B0(globalCtx, 0x479, &this->actor); + Message_StartTextbox(globalCtx, 0x479, &this->actor); this->curTextId = 0x479; // "Well, are you gonna make a deposit?" } - } else if ((CURRENT_DAY == 3) && (gSaveContext.isNight == 1)) { - func_801518B0(globalCtx, 0x46D, &this->actor); + } else if ((CURRENT_DAY == 3) && (gSaveContext.save.isNight == true)) { + Message_StartTextbox(globalCtx, 0x46D, &this->actor); // "Look, little guy, if it's 'cause of the bad rumors going around, forget it! They're just rumors!" this->curTextId = 0x46D; } else { // GINKOMAN_CHOICE_WITHDRAWL - func_801518B0(globalCtx, 0x46B, &this->actor); + Message_StartTextbox(globalCtx, 0x46B, &this->actor); this->curTextId = 0x46B; // "So..." } this->choiceDepositWithdrawl = GINKOMAN_CHOICE_RESET; break; case 0x46B: // So... - func_801518B0(globalCtx, 0x46E, &this->actor); + Message_StartTextbox(globalCtx, 0x46E, &this->actor); this->curTextId = 0x46E; // "How much do you want? [rupee prompt] break; case 0x46D: // "Look, little guy, if it's 'cause of the bad rumors going around, forget it! They're just // rumors!" - func_801518B0(globalCtx, 0x46B, &this->actor); + Message_StartTextbox(globalCtx, 0x46B, &this->actor); this->curTextId = 0x46B; // So... break; case 0x470: // "Is that so? Come back and deposit some after saving up a bunch!" - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); this->isStampChecked = false; EnGinkoMan_SetupIdle(this); // change to waiting for approach @@ -269,34 +269,34 @@ void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { break; case 0x476: // "...You haven't deposited that many Rupees, so that much isn't available for withdrawal. Do the // math! - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); case 0x475: // "What's this? Look, little guy, you can't hold this many rupees! You got that?" case 0x47C: // "Is that so? Think it over, little guy! So what are you gonna do?" case 0x47D: // duplicate of 48 - func_801518B0(globalCtx, 0x468, &this->actor); + Message_StartTextbox(globalCtx, 0x468, &this->actor); this->curTextId = 0x468; // " Deposit Rupees Withdraw Rupees Nothing really" break; case 0x472: // "What's this? It's a waste to take out such a tiny bit! ...But if you say so!" case 0x473: // Use it wisely... case 0x474: // "Aw, you're taking out all that? If you spend it like that, it'll all be gone before you know // it!" - if ((gSaveContext.roomInf[127][0] & 0xFFFF) == 0) { - func_801518B0(globalCtx, 0x478, &this->actor); + if ((gSaveContext.save.bankRupees & 0xFFFF) == 0) { + Message_StartTextbox(globalCtx, 0x478, &this->actor); // "Look, little guy, all the Rupees you deposited are gone, so you can't use that stamp anymore." this->curTextId = 0x478; } else { - globalCtx->msgCtx.bankRupees = gSaveContext.roomInf[127][0] & 0xFFFF; - func_801518B0(globalCtx, 0x45A, &this->actor); + globalCtx->msgCtx.bankRupees = gSaveContext.save.bankRupees & 0xFFFF; + Message_StartTextbox(globalCtx, 0x45A, &this->actor); this->curTextId = 0x45A; // "All right, little guy, now I've got a total of [rupees] from you!" } break; case 0x477: // "...You know, at this time of day there's a 4 Rupee service charge on withdrawals!" - func_801518B0(globalCtx, 0x471, &this->actor); + Message_StartTextbox(globalCtx, 0x471, &this->actor); this->curTextId = 0x471; // "Are you really withdrawing [rupees selected]? Y/n" this->serviceFee = globalCtx->msgCtx.unk1206C; break; case 0x479: // Well, are you gonna make a deposit? - func_801518B0(globalCtx, 0x44F, &this->actor); + Message_StartTextbox(globalCtx, 0x44F, &this->actor); this->curTextId = 0x44F; // "All right! So..." break; } @@ -304,74 +304,73 @@ void EnGinkoMan_DepositDialogue(EnGinkoMan* this, GlobalContext* globalCtx) { // actionfunc: wait for player dialogue input void EnGinkoMan_WaitForDialogueInput(EnGinkoMan* this, GlobalContext* globalCtx) { - if (!func_80147624(globalCtx)) { + if (!Message_ShouldAdvance(globalCtx)) { return; } switch (this->curTextId) { case 0x44E: // "...So, what'll it be? if (globalCtx->msgCtx.choiceIndex == GINKOMAN_CHOICE_YES) { - if ((gSaveContext.roomInf[127][0] & 0xFFFF) >= 5000) { + if ((gSaveContext.save.bankRupees & 0xFFFF) >= 5000) { play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0x45F, &this->actor); + Message_StartTextbox(globalCtx, 0x45F, &this->actor); this->curTextId = 0x45F; // bank full, cannot accept more } else { - if (gSaveContext.rupees > 0) { + if (gSaveContext.save.playerData.rupees > 0) { func_8019F208(); - func_801518B0(globalCtx, 0x44F, &this->actor); + Message_StartTextbox(globalCtx, 0x44F, &this->actor); this->curTextId = 0x44F; // "All right! so..." } else { play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0x458, &this->actor); + Message_StartTextbox(globalCtx, 0x458, &this->actor); this->curTextId = 0x458; // you haven't even gotten a single rup } } } else { // GINKOMAN_CHOICE_NO func_8019F230(); - func_801518B0(globalCtx, 0x451, &this->actor); + Message_StartTextbox(globalCtx, 0x451, &this->actor); this->curTextId = 0x451; // dont say that, come on, trust me! } break; case 0x452: // Really? are you really depositing rupees? if (globalCtx->msgCtx.choiceIndex == GINKOMAN_CHOICE_YES) { - if (gSaveContext.rupees < globalCtx->msgCtx.bankRupeesSelected) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.bankRupeesSelected) { play_sound(NA_SE_SY_ERROR); - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x459, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x459, &this->actor); this->curTextId = 0x459; // HEY you dont have that much } else { func_8019F208(); if (globalCtx->msgCtx.bankRupeesSelected >= 100) { - func_801518B0(globalCtx, 0x455, &this->actor); + Message_StartTextbox(globalCtx, 0x455, &this->actor); this->curTextId = 0x455; // You're really going to be give me that much? Rich little guy! } else if (globalCtx->msgCtx.bankRupeesSelected >= 10) { - func_801518B0(globalCtx, 0x454, &this->actor); + Message_StartTextbox(globalCtx, 0x454, &this->actor); this->curTextId = 0x454; // Seriously? that's a lot. A lot! } else { - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x453, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x453, &this->actor); this->curTextId = 0x453; // That's it? That aint nothing at all } - if ((gSaveContext.roomInf[127][0] & 0xFFFF) == 0) { + if ((gSaveContext.save.bankRupees & 0xFFFF) == 0) { this->isNewAccount = true; } func_801159EC((s16)-globalCtx->msgCtx.bankRupeesSelected); - this->previousBankValue = gSaveContext.roomInf[127][0] & 0xFFFF; - if (1) {} // Needed to match - gSaveContext.roomInf[127][0] = - (gSaveContext.roomInf[127][0] & 0xFFFF0000) | - ((gSaveContext.roomInf[127][0] & 0xFFFF) + globalCtx->msgCtx.bankRupeesSelected); + this->previousBankValue = gSaveContext.save.bankRupees & 0xFFFF; + gSaveContext.save.bankRupees = + ((gSaveContext.save.bankRupees & 0xFFFF) + globalCtx->msgCtx.bankRupeesSelected) | + (gSaveContext.save.bankRupees & 0xFFFF0000); } } else { // GINKOMAN_CHOICE_NO func_8019F230(); - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - if ((gSaveContext.roomInf[127][0] & 0xFFFF) == 0) { - func_801518B0(globalCtx, 0x456, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + if ((gSaveContext.save.bankRupees & 0xFFFF) == 0) { + Message_StartTextbox(globalCtx, 0x456, &this->actor); this->curTextId = 0x456; // Is that so? think about it } else { - func_801518B0(globalCtx, 0x47D, &this->actor); + Message_StartTextbox(globalCtx, 0x47D, &this->actor); this->curTextId = 0x47D; // is that so? think it over } } @@ -379,57 +378,58 @@ void EnGinkoMan_WaitForDialogueInput(EnGinkoMan* this, GlobalContext* globalCtx) case 0x468: // Deposit OR withdrawl OR cancel screen if (globalCtx->msgCtx.choiceIndex == GINKOMAN_CHOICE_CANCEL) { func_8019F230(); - func_801518B0(globalCtx, 0x470, &this->actor); + Message_StartTextbox(globalCtx, 0x470, &this->actor); this->curTextId = 0x470; // "Is that so? Come back and deposit some after saving up a bunch!" } else { func_8019F208(); this->choiceDepositWithdrawl = globalCtx->msgCtx.choiceIndex; if (!this->isStampChecked) { this->isStampChecked = true; - func_801518B0(globalCtx, 0x469, &this->actor); + Message_StartTextbox(globalCtx, 0x469, &this->actor); this->curTextId = 0x469; // "Excuse me, but let me take a look at you..." } else { - func_801518B0(globalCtx, 0x47E, &this->actor); + Message_StartTextbox(globalCtx, 0x47E, &this->actor); this->curTextId = 0x47E; // "Your deposits total [rupees]." } } break; case 0x471: // Are you really withdrawling [selected rupees]? if (globalCtx->msgCtx.choiceIndex == GINKOMAN_CHOICE_YES) { - if ((s32)((gSaveContext.roomInf[127][0] & 0xFFFF)) < + if ((s32)((gSaveContext.save.bankRupees & 0xFFFF)) < ((s32)(globalCtx->msgCtx.bankRupeesSelected + this->serviceFee))) { play_sound(NA_SE_SY_ERROR); - func_800BDC5C(&this->skelAnime, animations, GINKO_FLOORSMACKING); - func_801518B0(globalCtx, 0x476, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_FLOORSMACKING); + Message_StartTextbox(globalCtx, 0x476, &this->actor); this->curTextId = 0x476; // you dont have enough deposited to withdrawl - } else if (CUR_CAPACITY(UPG_WALLET) < (globalCtx->msgCtx.bankRupeesSelected + gSaveContext.rupees)) { + } else if (CUR_CAPACITY(UPG_WALLET) < + (globalCtx->msgCtx.bankRupeesSelected + gSaveContext.save.playerData.rupees)) { // check if wallet is big enough play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0x475, &this->actor); + Message_StartTextbox(globalCtx, 0x475, &this->actor); this->curTextId = 0x475; // You can't hold that many in your wallet } else { func_8019F208(); if (globalCtx->msgCtx.bankRupeesSelected >= 100) { - func_801518B0(globalCtx, 0x474, &this->actor); + Message_StartTextbox(globalCtx, 0x474, &this->actor); this->curTextId = 0x474; // Aw, you're taking out all that? } else if (globalCtx->msgCtx.bankRupeesSelected >= 10) { - func_801518B0(globalCtx, 0x473, &this->actor); + Message_StartTextbox(globalCtx, 0x473, &this->actor); this->curTextId = 0x473; // use it wisely } else { - func_801518B0(globalCtx, 0x472, &this->actor); + Message_StartTextbox(globalCtx, 0x472, &this->actor); this->curTextId = 0x472; // It's a waste to take out such a tiny bit } - this->previousBankValue = (s16)(gSaveContext.roomInf[127][0] & 0xFFFF); - gSaveContext.roomInf[127][0] = - (gSaveContext.roomInf[127][0] & 0xFFFF0000) | - (((gSaveContext.roomInf[127][0] & 0xFFFF) - globalCtx->msgCtx.bankRupeesSelected) - - this->serviceFee); + this->previousBankValue = (s16)(gSaveContext.save.bankRupees & 0xFFFF); + gSaveContext.save.bankRupees = + (((gSaveContext.save.bankRupees & 0xFFFF) - globalCtx->msgCtx.bankRupeesSelected) - + this->serviceFee) | + (gSaveContext.save.bankRupees & 0xFFFF0000); func_801159EC(globalCtx->msgCtx.bankRupeesSelected); } } else { func_8019F230(); - func_801518B0(globalCtx, 0x47C, &this->actor); + Message_StartTextbox(globalCtx, 0x47C, &this->actor); this->curTextId = 0x47C; // "Is that so? Think it over, little guy! So what are you gonna do?" } break; @@ -437,27 +437,27 @@ void EnGinkoMan_WaitForDialogueInput(EnGinkoMan* this, GlobalContext* globalCtx) } void EnGinkoMan_WaitForRupeeCount(EnGinkoMan* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->curTextId) { case 0x450: // "How much? How much?" [rupee prompt] Set the amount with [Control Stick] and if (globalCtx->msgCtx.bankRupeesSelected == 0) { - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x457, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x457, &this->actor); this->curTextId = 0x457; // Zero Rupees? Cruel joke! } else { - func_801518B0(globalCtx, 0x452, &this->actor); + Message_StartTextbox(globalCtx, 0x452, &this->actor); this->curTextId = 0x452; // Really? are you really depositing [x]? Y/n } break; case 0x46E: // "How much do you want?" [rupee prompt] Set the amount with [Control Stick] if (globalCtx->msgCtx.bankRupeesSelected == 0) { - func_801518B0(globalCtx, 0x46F, &this->actor); + Message_StartTextbox(globalCtx, 0x46F, &this->actor); this->curTextId = 0x46F; // "Zero Rupees?!? That's a cruel joke!" - } else if (gSaveContext.isNight == 1) { - func_801518B0(globalCtx, 0x477, &this->actor); + } else if (gSaveContext.save.isNight == true) { + Message_StartTextbox(globalCtx, 0x477, &this->actor); this->curTextId = 0x477; // "...You know, at this time of day there's a 4 Rupee service charge... } else { - func_801518B0(globalCtx, 0x471, &this->actor); + Message_StartTextbox(globalCtx, 0x471, &this->actor); this->curTextId = 0x471; // "Are you really withdrawing [rupees selected]? Y/n this->serviceFee = 0; } @@ -471,7 +471,7 @@ void EnGinkoMan_SetupDialogue(EnGinkoMan* this) { } void EnGinkoMan_Dialogue(EnGinkoMan* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { // get dialogue state? + switch (Message_GetState(&globalCtx->msgCtx)) { case 2: EnGinkoMan_SetupIdle(this); break; @@ -482,7 +482,7 @@ void EnGinkoMan_Dialogue(EnGinkoMan* this, GlobalContext* globalCtx) { EnGinkoMan_DepositDialogue(this, globalCtx); break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->isStampChecked = false; EnGinkoMan_SetupIdle(this); } @@ -495,8 +495,9 @@ void EnGinkoMan_Dialogue(EnGinkoMan* this, GlobalContext* globalCtx) { break; } - if ((this->skelAnime.animation == &D_060008C0) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_BANK_MAN_HAND_HIT); + if ((this->skelAnime.animation == &object_boj_Anim_0008C0) && + Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BANK_MAN_HAND_HIT); } } @@ -506,21 +507,21 @@ void EnGinkoMan_SetupBankAward(EnGinkoMan* this) { void EnGinkoMan_BankAward(EnGinkoMan* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { - // ? when would bank have a parent? + // Parent is the player when starting to receive the award this->actor.parent = NULL; EnGinkoMan_SetupBankAward2(this); } else if (this->curTextId == 0x45B) { // "Whats this, you already saved up 200?" - if (!(gSaveContext.weekEventReg[10] & 8)) { - func_800B8A1C(&this->actor, globalCtx, CUR_UPG_VALUE(UPG_WALLET) + 8, 500.0f, 100.0f); + if (!(gSaveContext.save.weekEventReg[10] & 8)) { + Actor_PickUp(&this->actor, globalCtx, GI_WALLET_ADULT + CUR_UPG_VALUE(UPG_WALLET), 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, 2, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_BLUE, 500.0f, 100.0f); } } else if (this->curTextId == 0x45C) { // "Whats this, you already saved up 5000?" - func_800B8A1C(&this->actor, globalCtx, 2, 500.0f, 100.0f); - } else if (!(gSaveContext.weekEventReg[59] & 8)) { - func_800B8A1C(&this->actor, globalCtx, 12, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_BLUE, 500.0f, 100.0f); + } else if (!(gSaveContext.save.weekEventReg[59] & 8)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, 2, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_BLUE, 500.0f, 100.0f); } } @@ -529,60 +530,60 @@ void EnGinkoMan_SetupBankAward2(EnGinkoMan* this) { this->actionFunc = EnGinkoMan_BankAward2; } -// separate function to handle bank rewards... if the bank has a parent actor? might be unused +// separate function to handle bank rewards... called while the player is receiving the award void EnGinkoMan_BankAward2(EnGinkoMan* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - if (!(gSaveContext.weekEventReg[10] & 8) && (this->curTextId == 0x45B)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (!(gSaveContext.save.weekEventReg[10] & 8) && (this->curTextId == 0x45B)) { // "What's this? You've already saved up 200 Rupees!?! Well, little guy, here's your special gift. Take // it!" - gSaveContext.weekEventReg[10] |= 8; - func_801518B0(globalCtx, 0x47A, &this->actor); - this->curTextId = 0x47A; // "See! Doesn't it hold more than your old one? + gSaveContext.save.weekEventReg[10] |= 8; + Message_StartTextbox(globalCtx, 0x47A, &this->actor); + this->curTextId = 0x47A; // Message after receiving reward for depositing 200 rupees. } else { - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x47B, &this->actor); - this->curTextId = 0x47B; // "Is that so? Think it over, little guy! So what are you gonna do?" + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x47B, &this->actor); + this->curTextId = 0x47B; // Message after receiving reward for depositing 1000 rupees. } EnGinkoMan_SetupDialogue(this); } else if (this->curTextId == 0x45D) { // saved up 5000 rupees for HP - if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { - if (!(gSaveContext.weekEventReg[59] & 8)) { - gSaveContext.weekEventReg[59] |= 8; + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + if (!(gSaveContext.save.weekEventReg[59] & 8)) { + gSaveContext.save.weekEventReg[59] |= 8; } EnGinkoMan_SetupIdle(this); } } else { - func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + func_800B85E0(&this->actor, globalCtx, 500.0f, EXCH_ITEM_MINUS1); } } void EnGinkoMan_SetupStamp(EnGinkoMan* this) { - func_800BDC5C(&this->skelAnime, animations, GINKO_REACHING); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_REACHING); this->actionFunc = EnGinkoMan_Stamp; } void EnGinkoMan_Stamp(EnGinkoMan* this, GlobalContext* globalCtx) { if ((this->curTextId == 0x464) // "Hey, relax! It doesn't leave any marks, and it's not gonna hurt." && (Animation_OnFrame(&this->skelAnime, 10.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_HANKO); // "stamp" + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HANKO); // "stamp" } if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { switch (this->curTextId) { case 0x464: // "Hey, relax! It doesn't leave any marks, and it's not gonna hurt." - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - func_801518B0(globalCtx, 0x465, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + Message_StartTextbox(globalCtx, 0x465, &this->actor); this->curTextId = 0x465; // "There! Now I'll know you when I see you!" break; case 0x469: // "Excuse me, but let me take a look at you..." - func_800BDC5C(&this->skelAnime, animations, GINKO_SITTING); - globalCtx->msgCtx.bankRupees = (gSaveContext.roomInf[127][0] & 0xFFFF); - if ((CURRENT_DAY == 3) && (gSaveContext.isNight == 1)) { - func_801518B0(globalCtx, 0x46C, &this->actor); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_SITTING); + globalCtx->msgCtx.bankRupees = (gSaveContext.save.bankRupees & 0xFFFF); + if ((CURRENT_DAY == 3) && (gSaveContext.save.isNight == true)) { + Message_StartTextbox(globalCtx, 0x46C, &this->actor); this->curTextId = 0x46C; // "Ah, yes...[Link], right? } else { - func_801518B0(globalCtx, 0x46A, &this->actor); + Message_StartTextbox(globalCtx, 0x46A, &this->actor); this->curTextId = 0x46A; // "Ah, yes...[Link]. } break; @@ -595,14 +596,14 @@ void EnGinkoMan_Stamp(EnGinkoMan* this, GlobalContext* globalCtx) { void EnGinkoMan_SwitchAnimation(EnGinkoMan* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer > 160.0f) { if (this->animTimer == 0) { - if (this->skelAnime.animation != &D_06004A7C) { + if (this->skelAnime.animation != &object_boj_Anim_004A7C) { this->animTimer = 40; - func_800BDC5C(&this->skelAnime, animations, GINKO_ADVERTISING); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_ADVERTISING); } } - } else if ((this->animTimer == 0) && (this->skelAnime.animation != &D_06000AC4)) { + } else if ((this->animTimer == 0) && (this->skelAnime.animation != &object_boj_Anim_000AC4)) { this->animTimer = 40; - func_800BDC5C(&this->skelAnime, animations, GINKO_AMAZED); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, GINKO_AMAZED); } DECR(this->animTimer); @@ -610,7 +611,7 @@ void EnGinkoMan_SwitchAnimation(EnGinkoMan* this, GlobalContext* globalCtx) { void EnGinkoMan_FacePlayer(EnGinkoMan* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - if (this->skelAnime.animation != &D_06004A7C) { + if (this->skelAnime.animation != &object_boj_Anim_004A7C) { func_800E9250(globalCtx, &this->actor, &this->limb15Rot, &this->limb8Rot, this->actor.focus.pos); } else { func_800E8F08(&this->limb15Rot, &this->limb8Rot); @@ -627,27 +628,27 @@ void EnGinkoMan_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnGinkoMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { - EnGinkoMan* this = (EnGinkoMan*)arg; + Actor* thisx) { + EnGinkoMan* this = THIS; if (limbIndex == 15) { - *dList = D_0600B1D8; + *dList = object_boj_DL_00B1D8; } 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_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->limb15Rot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->limb15Rot.x, MTXMODE_APPLY); + Matrix_Translate(-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_RotateXS(-this->limb8Rot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->limb8Rot.x, MTXMODE_APPLY); } - return 0; + return false; } -void EnGinkoMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { +void EnGinkoMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } void EnGinkoMan_Draw(Actor* thisx, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c index 9473ee313..45fe0c132 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.c +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.c @@ -6,7 +6,7 @@ #include "z_en_girla.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnGirlA*)thisx) @@ -159,8 +159,8 @@ void EnGirlA_SetupAction(EnGirlA* this, EnGirlAActionFunc action) { void EnGirlA_InitObjIndex(EnGirlA* this, GlobalContext* globalCtx) { s16 params = this->actor.params; - //! @bug: Condition is impossible - if (params >= 43 && params < 0) { + //! @bug: Condition is impossible, && should be an || + if (params >= SI_MAX && params < SI_POTION_RED_1) { Actor_MarkForDeath(&this->actor); return; } @@ -185,59 +185,59 @@ void EnGirlA_Destroy(Actor* thisx, GlobalContext* globalCtx) { } s32 EnGirlA_CanBuyPotionRed(GlobalContext* globalCtx, EnGirlA* this) { - if (!func_80114E90()) { + if (!Interface_HasEmptyBottle()) { return CANBUY_RESULT_NEED_EMPTY_BOTTLE; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyPotionGreen(GlobalContext* globalCtx, EnGirlA* this) { - if (!func_80114E90()) { + if (!Interface_HasEmptyBottle()) { return CANBUY_RESULT_NEED_EMPTY_BOTTLE; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyPotionBlue(GlobalContext* globalCtx, EnGirlA* this) { - if (!(gSaveContext.weekEventReg[53] & 8)) { + if (!(gSaveContext.save.weekEventReg[53] & 8)) { return CANBUY_RESULT_CANNOT_GET_NOW; } - if (!func_80114E90()) { + if (!Interface_HasEmptyBottle()) { return CANBUY_RESULT_NEED_EMPTY_BOTTLE; } - if (!(gSaveContext.weekEventReg[53] & 0x10)) { + if (!(gSaveContext.save.weekEventReg[53] & 0x10)) { return CANBUY_RESULT_SUCCESS_2; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyArrows(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_QUIVER) == 0) { + if (GET_CUR_UPG_VALUE(UPG_QUIVER) == 0) { return CANBUY_RESULT_CANNOT_GET_NOW_2; } if (AMMO(ITEM_BOW) >= CUR_CAPACITY(UPG_QUIVER)) { return CANBUY_RESULT_NO_ROOM_2; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyNuts(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_CAPACITY(UPG_NUTS) != 0 && AMMO(ITEM_NUT) >= CUR_CAPACITY(UPG_NUTS)) { + if (CUR_CAPACITY(UPG_NUTS) != 0 && CUR_CAPACITY(UPG_NUTS) <= AMMO(ITEM_NUT)) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } if (func_80114978(ITEM_NUT) == ITEM_NONE) { @@ -247,20 +247,20 @@ s32 EnGirlA_CanBuyNuts(GlobalContext* globalCtx, EnGirlA* this) { } s32 EnGirlA_CanBuyShieldHero(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_EQUIP_VALUE_VOID(EQUIP_SHIELD) != 0) { + if (GET_CUR_EQUIP_VALUE(EQUIP_SHIELD) != 0) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuyStick(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_CAPACITY(UPG_STICK) != 0 && AMMO(ITEM_STICK) >= CUR_CAPACITY(UPG_STICK)) { + if (CUR_CAPACITY(UPG_STICKS) != 0 && AMMO(ITEM_STICK) >= CUR_CAPACITY(UPG_STICKS)) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } if (func_80114978(ITEM_STICK) == ITEM_NONE) { @@ -270,56 +270,56 @@ s32 EnGirlA_CanBuyStick(GlobalContext* globalCtx, EnGirlA* this) { } s32 EnGirlA_CanBuyMaskAllNight(GlobalContext* globalCtx, EnGirlA* this) { - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyBombBagCuriosityShop(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) >= 2) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) >= 2) { return CANBUY_RESULT_CANNOT_GET_NOW; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyBombBag20BombShop(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 1) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 1) { return CANBUY_RESULT_ALREADY_HAVE; } - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) >= 2) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) >= 2) { return CANBUY_RESULT_HAVE_BETTER; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuyBombBag30BombShop(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 2) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 2) { return CANBUY_RESULT_ALREADY_HAVE; } - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 3) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 3) { return CANBUY_RESULT_HAVE_BETTER; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuyBombchus(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 0) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 0) { return CANBUY_RESULT_CANNOT_GET_NOW; } if (AMMO(ITEM_BOMBCHU) >= CUR_CAPACITY(UPG_BOMB_BAG)) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } if (func_80114978(ITEM_BOMBCHU) == ITEM_NONE) { @@ -329,47 +329,47 @@ s32 EnGirlA_CanBuyBombchus(GlobalContext* globalCtx, EnGirlA* this) { } s32 EnGirlA_CanBuyBombs(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 0) { + if (GET_CUR_UPG_VALUE(UPG_BOMB_BAG) == 0) { return CANBUY_RESULT_CANNOT_GET_NOW; } if (AMMO(ITEM_BOMB) >= CUR_CAPACITY(UPG_BOMB_BAG)) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; } s32 EnGirlA_CanBuyBottle(GlobalContext* globalCtx, EnGirlA* this) { - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuySword(GlobalContext* globalCtx, EnGirlA* this) { - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuyShieldMirror(GlobalContext* globalCtx, EnGirlA* this) { - if (CUR_EQUIP_VALUE_VOID(EQUIP_SHIELD) != 0) { + if (GET_CUR_EQUIP_VALUE(EQUIP_SHIELD) != 0) { return CANBUY_RESULT_NO_ROOM; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_1; } s32 EnGirlA_CanBuyFairy(GlobalContext* globalCtx, EnGirlA* this) { - if (!func_80114E90()) { + if (!Interface_HasEmptyBottle()) { return CANBUY_RESULT_NEED_EMPTY_BOTTLE; } - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { return CANBUY_RESULT_NEED_RUPEES; } return CANBUY_RESULT_SUCCESS_2; @@ -377,24 +377,24 @@ s32 EnGirlA_CanBuyFairy(GlobalContext* globalCtx, EnGirlA* this) { void EnGirlA_BuyBottleItem(GlobalContext* globalCtx, EnGirlA* this) { switch (this->actor.params) { - case 0: - case 10: - case 18: - case 29: - case 32: - case 35: + case SI_POTION_RED_1: + case SI_POTION_RED_2: + case SI_POTION_RED_3: + case SI_POTION_RED_4: + case SI_POTION_RED_5: + case SI_POTION_RED_6: Item_Give(globalCtx, ITEM_POTION_RED); break; - case 1: - case 5: - case 14: + case SI_POTION_GREEN_1: + case SI_POTION_GREEN_2: + case SI_POTION_GREEN_3: Item_Give(globalCtx, ITEM_POTION_GREEN); break; - case 2: + case SI_POTION_BLUE: Item_Give(globalCtx, ITEM_POTION_BLUE); break; - case 3: - case 11: + case SI_FAIRY_1: + case SI_FAIRY_2: Item_Give(globalCtx, ITEM_FAIRY); break; } @@ -538,7 +538,7 @@ void EnGirlA_InitalUpdate(EnGirlA* this, GlobalContext* globalCtx) { ShopItemEntry* shopItem = &sShopItemEntries[params]; if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { - this->actor.flags &= ~0x10; + this->actor.flags &= ~ACTOR_FLAG_10; this->actor.objBankIndex = this->objIndex; this->actor.textId = shopItem->descriptionTextId; this->choiceTextId = shopItem->choiceTextId; @@ -558,7 +558,7 @@ void EnGirlA_InitalUpdate(EnGirlA* this, GlobalContext* globalCtx) { this->itemParams = shopItem->params; this->drawFunc = shopItem->drawFunc; this->getItemDrawId = shopItem->getItemDrawId; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; Actor_SetScale(&this->actor, 0.25f); this->actor.shape.yOffset = 24.0f; this->actor.shape.shadowScale = 4.0f; @@ -579,7 +579,7 @@ void EnGirlA_Update2(EnGirlA* this, GlobalContext* globalCtx) { this->actor.shape.shadowScale = 4.0f; EnGirlA_TrySetMaskItemDescription(this, globalCtx); this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, 5.0f); + Actor_SetFocus(&this->actor, 5.0f); this->actor.shape.rot.x = 0; if (this->isSelected) { this->rotY += 0x1F4; @@ -597,7 +597,7 @@ void EnGirlA_Update(Actor* thisx, GlobalContext* globalCtx) { void EnGirlA_Draw(Actor* thisx, GlobalContext* globalCtx) { EnGirlA* this = THIS; - Matrix_RotateY(this->rotY, MTXMODE_APPLY); + Matrix_RotateYS(this->rotY, MTXMODE_APPLY); if (this->drawFunc != NULL) { this->drawFunc(&this->actor, globalCtx, 0); } diff --git a/src/overlays/actors/ovl_En_GirlA/z_en_girla.h b/src/overlays/actors/ovl_En_GirlA/z_en_girla.h index 5e3d1b136..a3d8e0206 100644 --- a/src/overlays/actors/ovl_En_GirlA/z_en_girla.h +++ b/src/overlays/actors/ovl_En_GirlA/z_en_girla.h @@ -25,7 +25,7 @@ typedef struct ShopItemEntry { typedef struct EnGirlA { /* 0x000 */ Actor actor; - /* 0x144 */ char unk144[0x44]; + /* 0x144 */ UNK_TYPE1 unk144[0x44]; /* 0x188 */ EnGirlAActionFunc actionFunc; /* 0x18C */ s8 objIndex; /* 0x190 */ EnGirlAActionFunc mainActionFunc; @@ -104,6 +104,7 @@ typedef enum { /* 40 */ SI_SWORD_GILDED, /* 41 */ SI_SHIELD_HERO_4, /* 42 */ SI_SHIELD_MIRROR, + /* 43 */ SI_MAX } EnGirlAShopItemId; extern const ActorInit En_GirlA_InitVars; @@ -122,7 +123,7 @@ typedef struct { /* 0x28 */ f32 arrowTexX; /* 0x2C */ f32 arrowTexY; /* 0x30 */ f32 texZ; // Used for both stickTexZ and arrowTexZ - /* 0x34 */ s32 isEnabled; + /* 0x34 */ u32 isEnabled; } StickDirectionPrompt; // size = 0x38 typedef struct ShopItem { diff --git a/src/overlays/actors/ovl_En_Gk/z_en_gk.c b/src/overlays/actors/ovl_En_Gk/z_en_gk.c index fc77cba3e..ae9dd8553 100644 --- a/src/overlays/actors/ovl_En_Gk/z_en_gk.c +++ b/src/overlays/actors/ovl_En_Gk/z_en_gk.c @@ -1,6 +1,13 @@ -#include "z_en_gk.h" +/* + * File: z_en_gk.c + * Overlay: ovl_En_Gk + * Description: Goron Elder's Son + */ -#define FLAGS 0x00000009 +#include "z_en_gk.h" +#include "objects/object_gk/object_gk.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnGk*)thisx) @@ -9,7 +16,23 @@ void EnGk_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGk_Update(Actor* thisx, GlobalContext* globalCtx); void EnGk_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B51698(EnGk* this, GlobalContext* globalCtx); +void func_80B51760(EnGk* this, GlobalContext* globalCtx); +void func_80B51970(EnGk* this, GlobalContext* globalCtx); +void func_80B51B40(EnGk* this, GlobalContext* globalCtx); +void func_80B51D9C(EnGk* this, GlobalContext* globalCtx); +void func_80B51EA4(EnGk* this, GlobalContext* globalCtx); +void func_80B51FD0(EnGk* this, GlobalContext* globalCtx); +void func_80B5202C(EnGk* this, GlobalContext* globalCtx); +void func_80B5216C(EnGk* this, GlobalContext* globalCtx); +void func_80B521E8(EnGk* this, GlobalContext* globalCtx); +void func_80B5227C(EnGk* this, GlobalContext* globalCtx); +void func_80B52340(EnGk* this, GlobalContext* globalCtx); +void func_80B52430(EnGk* this, GlobalContext* globalCtx); +void func_80B5253C(EnGk* this, GlobalContext* globalCtx); +void func_80B525E0(EnGk* this, GlobalContext* globalCtx); +void func_80B52654(EnGk* this, GlobalContext* globalCtx); + const ActorInit En_Gk_InitVars = { ACTOR_EN_GK, ACTORCAT_NPC, @@ -22,18 +45,29 @@ const ActorInit En_Gk_InitVars = { (ActorFunc)EnGk_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B53210 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, 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_NONE, + 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, + }, { 24, 32, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B5323C = { 0, 24, 32, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 24, 32, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80B53248 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -68,89 +102,1184 @@ static DamageTable D_80B53248 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -#endif +static AnimationInfo sAnimations[] = { + { &object_gk_Anim_00787C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_007DC4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gk_Anim_0092C0, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_005EDC, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gk_Anim_009638, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_008774, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_gk_Anim_00AE34, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_00BD90, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gk_Anim_00C308, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_009858, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gk_Anim_009D88, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_gk_Anim_00A21C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_gk_Anim_00AAEC, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +}; -extern ColliderCylinderInit D_80B53210; -extern CollisionCheckInfoInit2 D_80B5323C; -extern DamageTable D_80B53248; +Color_RGBA8 D_80B533A0 = { 255, 255, 255, 255 }; +Color_RGBA8 D_80B533A4 = { 50, 150, 150, 0 }; -extern UNK_TYPE D_06006688; -extern UNK_TYPE D_0600787C; +u16 func_80B50410(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50410.s") + if (globalCtx->sceneNum == SCENE_17SETUGEN2) { + if (player->transformation == PLAYER_FORM_GORON) { + if (!(gSaveContext.save.weekEventReg[40] & 0x80)) { + switch (this->unk_31C) { + case 0xE7A: + return 0xE7B; + case 0xE7B: + return 0xE7C; + case 0xE7C: + return 0xE7D; + case 0xE7D: + return 0xE7E; + case 0xE7E: + return 0xE7F; + case 0xE7F: + gSaveContext.save.weekEventReg[40] |= 0x80; + this->unk_1E4 |= 1; + return 0xE80; + default: + return 0xE7A; + } + } else { + this->unk_1E4 |= 1; + return 0xE81; + } + } else if (!(gSaveContext.save.weekEventReg[41] & 1)) { + switch (this->unk_31C) { + case 0xE82: + return 0xE83; + case 0xE83: + return 0xE7D; + case 0xE7D: + return 0xE7E; + case 0xE7E: + return 0xE7F; + case 0xE7F: + gSaveContext.save.weekEventReg[41] |= 1; + this->unk_1E4 |= 1; + return 0xE80; + default: + return 0xE82; + } + } else { + this->unk_1E4 |= 1; + return 0xE81; + } + } else if (globalCtx->sceneNum == SCENE_GORONRACE) { + if (player->transformation == PLAYER_FORM_GORON) { + if (!(gSaveContext.save.weekEventReg[41] & 4)) { + if (this->unk_31C == 0xE88) { + if (!(gSaveContext.save.weekEventReg[41] & 8) || Interface_HasEmptyBottle()) { + return 0xE89; + } + gSaveContext.save.weekEventReg[41] |= 4; + this->unk_1E4 |= 1; + return 0xE94; + } + return 0xE88; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50710.s") + if ((this->unk_31C == 0xE8D) || (this->unk_31C == 0xE98)) { + if (!(gSaveContext.save.weekEventReg[41] & 8) || Interface_HasEmptyBottle()) { + return 0xE89; + } + gSaveContext.save.weekEventReg[41] |= 4; + this->unk_1E4 |= 1; + return 0xE94; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B507A0.s") + if (this->unk_1E4 & 0x10) { + return 0xE8D; + } + return 0xE98; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50854.s") + if (!(gSaveContext.save.weekEventReg[41] & 2)) { + switch (this->unk_31C) { + case 0xE85: + return 0xE86; + case 0xE86: + gSaveContext.save.weekEventReg[41] |= 2; + this->unk_1E4 |= 1; + return 0xE87; + default: + return 0xE85; + } + } else { + this->unk_1E4 |= 1; + return 0xE87; + } + } else { + return 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50954.s") +u16 func_80B50710(EnGk* this) { + switch (this->unk_31C) { + case 0xE8E: + gSaveContext.save.weekEventReg[41] |= 4; + this->unk_1E4 &= ~0x10; + this->unk_1E4 |= 1; + return 0xE8F; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B509A8.s") + case 0xE8A: + return 0xE8B; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50B38.s") + case 0xE8B: + gSaveContext.save.weekEventReg[41] |= 4; + this->unk_1E4 |= 0x10; + this->unk_1E4 |= 1; + return 0xE8C; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50C78.s") +void func_80B507A0(EnGk* 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50E14.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 30.0f, 30.0f, 7); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B50ED4.s") +s32 func_80B50854(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5100C.s") + if (!(this->unk_1E4 & 0x40)) { + if (player->stateFlags2 & 0x8000000) { + this->unk_1E4 |= 0x40; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + } else if (!(player->stateFlags2 & 0x8000000)) { + this->unk_1E4 &= ~0x40; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5123C.s") + if ((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.ocarinaMode == 3) && + (globalCtx->msgCtx.unk1202E == 1)) { + Flags_SetSwitch(globalCtx, ENGK_GET_3F00(&this->actor)); + this->unk_2E4 = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + this->actionFunc = func_80B521E8; + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51308.s") +void func_80B50954(EnGk* this) { + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLONKID_WALK); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51398.s") +void func_80B509A8(EnGk* this, GlobalContext* globalCtx) { + Vec3f sp4C; + s16 phi_s1 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51410.s") + this->unk_300.x += 2.0f * Rand_Centered(); + this->unk_300.y += Rand_ZeroOne(); + this->unk_300.z += 2.0f * Rand_Centered(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51510.s") + this->unk_30C.x += 2.0f * Rand_Centered(); + this->unk_30C.y += Rand_ZeroOne(); + this->unk_30C.z += 2.0f * Rand_Centered(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51698.s") + if (this->unk_2E4 == 0) { + sp4C.x = 0.0f; + sp4C.z = 0.0f; + sp4C.y = -1.2f; + phi_s1 = 25; + } else if ((this->unk_2E4 == 2) || (this->unk_2E4 == 9) || (this->unk_2E4 == 10) || (this->unk_2E4 == 11)) { + sp4C.x = 0.0f; + sp4C.z = 0.0f; + sp4C.y = -0.5f; + phi_s1 = 10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51760.s") + EffectSsDtBubble_SpawnCustomColor(globalCtx, &this->unk_2E8, &this->unk_300, &sp4C, &D_80B533A0, &D_80B533A4, + Rand_S16Offset(15, 15), phi_s1, 0); + EffectSsDtBubble_SpawnCustomColor(globalCtx, &this->unk_2F4, &this->unk_30C, &sp4C, &D_80B533A0, &D_80B533A4, + Rand_S16Offset(15, 15), phi_s1, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51970.s") +void func_80B50B38(EnGk* this, GlobalContext* globalCtx) { + s16 i; + s16 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51B40.s") + switch (this->unk_2E4) { + case 0: + this->unk_2E0 = 3; + for (i = 0; i < 2; i++) { + func_80B509A8(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51D9C.s") + case 2: + this->unk_2E0 = 3; + func_80B509A8(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51EA4.s") + case 1: + case 3: + case 12: + this->unk_2E0 = 2; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B51FD0.s") + case 9: + case 10: + case 11: + this->unk_2E0 = 3; + func_80B509A8(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5202C.s") + default: + temp = this->unk_2E2; + temp--; + if (temp >= 3) { + this->unk_2E0 = 0; + this->unk_2E2 = temp; + } else if (temp == 0) { + this->unk_2E0 = 2; + this->unk_2E2 = (s32)(Rand_ZeroOne() * 60.0f) + 20; + } else { + this->unk_2E0 = 1; + this->unk_2E2 = temp; + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5216C.s") +s32 func_80B50C78(EnGk* this, Path* path, s32 arg2_) { + Vec3s* sp5C = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 arg2 = arg2_; + s32 ret = false; + f32 phi_f12; + f32 phi_f14; + f32 sp44; + f32 sp40; + f32 sp3C; + Vec3f sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B521E8.s") + Math_Vec3s_ToVec3f(&sp30, &sp5C[arg2]); + if (arg2 == 0) { + phi_f12 = sp5C[1].x - sp5C[0].x; + phi_f14 = sp5C[1].z - sp5C[0].z; + } else if ((sp58 - 1) == arg2) { + phi_f12 = sp5C[sp58 - 1].x - sp5C[sp58 - 2].x; + phi_f14 = sp5C[sp58 - 1].z - sp5C[sp58 - 2].z; + } else { + phi_f12 = sp5C[arg2 + 1].x - sp5C[arg2 - 1].x; + phi_f14 = sp5C[arg2 + 1].z - sp5C[arg2 - 1].z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5227C.s") + func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(phi_f12, phi_f14)), &sp44, &sp40, &sp3C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52340.s") + if (((this->actor.world.pos.x * sp44) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) { + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52430.s") +f32 func_80B50E14(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3) { + Vec3s* points; + Vec3f sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B5253C.s") + if (path != NULL) { + points = Lib_SegmentedToVirtual(path->points); + points = &points[arg1]; + sp20.x = points[0].x; + sp20.y = points[0].y; + sp20.z = points[0].z; + } + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + return sp20.y - arg2->y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B525E0.s") +s32 func_80B50ED4(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 arg5) { + Vec3f sp7C; + Vec3f sp70 = gZeroVec3f; + Vec3s sp68; + MtxF sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52654.s") + Matrix_MultVec3f(&sp70, &sp7C); + Matrix_Get(&sp28); + Matrix_MtxFToYXZRot(&sp28, &sp68, false); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/EnGk_Init.s") + *arg2 = sp7C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/EnGk_Destroy.s") + if (!arg4 && !arg5) { + arg3->x = sp68.x; + arg3->y = sp68.y; + arg3->z = sp68.z; + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/EnGk_Update.s") + if (arg5) { + sp68.z = arg0; + sp68.y = arg1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52AD4.s") + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52AF0.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/func_80B52D8C.s") +s32 func_80B5100C(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gk/EnGk_Draw.s") + Math_SmoothStepToS(&this->unk_320, (this->actor.yawTowardsPlayer - this->unk_324) - this->actor.shape.rot.y, 4, + 0x2AA8, 1); + this->unk_320 = CLAMP(this->unk_320, -0x1FFE, 0x1FFE); + + Math_SmoothStepToS(&this->unk_324, (this->actor.yawTowardsPlayer - this->unk_320) - this->actor.shape.rot.y, 4, + 0x2AA8, 1); + this->unk_324 = CLAMP(this->unk_324, -0x1C70, 0x1C70); + + sp40 = player->actor.world.pos; + sp40.y = player->bodyPartsPos[7].y + 3.0f; + + sp34 = this->actor.world.pos; + sp34.y += 70.0f; + + Math_SmoothStepToS(&this->unk_31E, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_322, 4, 0x2AA8, 1); + this->unk_31E = CLAMP(this->unk_31E, -0x1C70, 0x1C70); + + Math_SmoothStepToS(&this->unk_322, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_31E, 4, 0x2AA8, 1); + this->unk_322 = CLAMP(this->unk_322, -0x1C70, 0x1C70); + return true; +} + +s32 func_80B5123C(EnGk* this, GlobalContext* globalCtx) { + s16 temp_v0; + s16 phi_v1; + + if (DECR(this->unk_34E) != 0) { + this->unk_31E = 0; + this->unk_320 = 0; + this->unk_1E4 &= ~8; + this->unk_322 = 0; + this->unk_324 = 0; + return true; + } + + if (Actor_IsFacingAndNearPlayer(&this->actor, 300.0f, 0x7FF8)) { + this->unk_1E4 |= 8; + func_80B5100C(this, globalCtx); + } else { + if (this->unk_1E4 & 8) { + this->unk_34E = 20; + } + this->unk_1E4 &= ~8; + this->unk_31E = 0; + this->unk_320 = 0; + this->unk_322 = 0; + this->unk_324 = 0; + } + return true; +} + +void func_80B51308(EnGk* this, GlobalContext* globalCtx) { + s16 sp1E = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_31A].animation); + + if ((this->unk_2E4 == 7) && (sp1E == lastFrame)) { + this->unk_2E4 = 8; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); + } +} + +void func_80B51398(EnGk* this, GlobalContext* globalCtx) { + s16 sp1E = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[9].animation); + + if ((this->unk_2E4 == 9) && (sp1E == lastFrame)) { + this->unk_2E4 = 10; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 10); + } +} + +void func_80B51410(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actor.xzDistToPlayer < 100.0f) { + if ((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.ocarinaMode == 3) && + (globalCtx->msgCtx.unk1202E == 0xE)) { + this->unk_1E4 |= 0x20; + } + + if (ActorCutscene_GetCanPlayNext(this->unk_318)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLONKID_SOB_TALK); + ActorCutscene_Start(this->unk_318, &this->actor); + this->unk_1E4 &= ~0x20; + return; + } + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + + if (this->unk_1E4 & 0x20) { + ActorCutscene_SetIntentToPlay(this->unk_318); + } + } else { + this->unk_1E4 &= ~0x20; + } +} + +void func_80B51510(EnGk* this, GlobalContext* globalCtx) { + s32 pad; + s32 actionIndex; + + if (this) {} + + if (Cutscene_CheckActorAction(globalCtx, 479)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 479); + + if (globalCtx->csCtx.actorActions[actionIndex]->action != this->unk_31B) { + this->unk_31B = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + this->unk_31A = 0; + this->unk_2E4 = 0; + break; + + case 2: + this->unk_31A = 2; + this->unk_2E4 = 2; + break; + + case 3: + this->unk_31A = 7; + this->unk_2E4 = 7; + break; + + case 4: + this->unk_31A = 3; + this->unk_2E4 = 3; + break; + + case 5: + this->unk_31A = 1; + this->unk_2E4 = 1; + this->unk_1E4 |= 0x80; + this->actionFunc = func_80B5227C; + break; + + case 6: + this->unk_31A = 12; + this->unk_2E4 = 12; + break; + + case 7: + Flags_SetSwitch(globalCtx, ENGK_GET_3F00(&this->actor)); + break; + } + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_31A); + } + + if (this->unk_31A == 7) { + func_80B51308(this, globalCtx); + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + this->actor.shape.yOffset = 0.0f; + } else { + this->unk_31B = 0x63; + } +} + +void func_80B51698(EnGk* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E4].animation); + + if (sp26 == lastFrame) { + switch (this->unk_2E4) { + case 0: + this->unk_2E4 = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80B5216C; + break; + + case 2: + this->unk_2E4 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80B5202C; + break; + } + } +} + +void func_80B51760(EnGk* this, GlobalContext* globalCtx) { + s16 sp2E = this->skelAnime.curFrame; + s16 lastFrame; + + if (this->unk_2E4 == 11) { + lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E4].animation); + if (sp2E == lastFrame) { + this->unk_2E4 = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_2E4); + } + } else if (this->unk_2E4 == 10) { + lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E4].animation); + if (sp2E == lastFrame) { + this->unk_2E4 = 11; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_2E4); + } + } else { + if (Flags_GetSwitch(globalCtx, ENGK_GET_3F00(&this->actor))) { + gSaveContext.save.weekEventReg[40] |= 0x40; + this->actionFunc = func_80B51D9C; + return; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_1E4 |= 4; + this->unk_31C = func_80B50410(this, globalCtx); + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + this->actionFunc = func_80B51970; + if (this->unk_31C == 0xE81) { + this->unk_2E4 = 0; + this->unk_1E4 |= 2; + } + } else if (((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) && + (gSaveContext.save.entranceIndex != 0xD010)) { + func_800B863C(&this->actor, globalCtx); + } + + if (this->unk_1E4 & 4) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + } +} + +void func_80B51970(EnGk* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (((temp_v0 == 6) || (temp_v0 == 5)) && Message_ShouldAdvance(globalCtx)) { + if ((this->unk_31C == 0xE84) || (this->unk_31C == 0xE99)) { + ActorCutscene_Stop(this->unk_318); + this->unk_318 = ActorCutscene_GetAdditionalCutscene(this->unk_318); + ActorCutscene_SetIntentToPlay(this->unk_318); + this->actionFunc = func_80B51D9C; + return; + } + + if (this->unk_1E4 & 1) { + this->unk_1E4 &= ~1; + this->unk_1E4 &= ~4; + if (this->unk_2E4 == 10) { + this->unk_1E4 &= ~2; + } + this->actionFunc = func_80B51760; + return; + } + + this->unk_31C = func_80B50410(this, globalCtx); + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + if (this->unk_31C == 0xE80) { + this->unk_1E4 |= 2; + } else if (this->unk_31C == 0xE89) { + this->actionFunc = func_80B51B40; + } + } + + if (this->unk_1E4 & 2) { + func_801A4748(&this->actor.projectedPos, NA_SE_EN_GOLON_KID_CRY - SFX_FLAG); + if (this->unk_2E4 != 10) { + if (this->unk_2E4 != 9) { + this->unk_2E4 = 9; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 9); + } else { + func_80B51398(this, globalCtx); + } + } + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->unk_2E4 == 6) { + func_80B50954(this); + } +} + +void func_80B51B40(EnGk* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 6) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_1E4 & 1) { + this->unk_1E4 &= ~1; + this->unk_1E4 &= ~4; + + if (this->unk_2E4 == 10) { + this->unk_1E4 &= ~2; + } + + if (this->unk_31C == 0xE8F) { + globalCtx->nextEntranceIndex = 0xD010; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + Parameter_AddMagic(globalCtx, ((void)0, gSaveContext.unk_3F30) + + (gSaveContext.save.playerData.doubleMagic * 0x30) + 0x30); + } else { + this->actionFunc = func_80B51760; + } + return; + } + + this->unk_31C = func_80B50710(this); + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + if (this->unk_31C == 0xE8C) { + this->unk_1E4 |= 2; + } + } + } else if ((temp_v0 == 4) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + this->unk_31C = 0xE8E; + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + break; + + case 1: + func_8019F230(); + this->unk_31C = 0xE8A; + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + break; + } + } + + if (this->unk_1E4 & 2) { + func_801A4748(&this->actor.projectedPos, NA_SE_EN_GOLON_KID_CRY - SFX_FLAG); + if (this->unk_2E4 != 10) { + if (this->unk_2E4 != 9) { + this->unk_2E4 = 9; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 9); + } else { + func_80B51398(this, globalCtx); + } + } + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80B51D9C(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCanPlayNext(this->unk_318)) { + ActorCutscene_StartAndSetFlag(this->unk_318, &this->actor); + if (this->unk_1E4 & 4) { + this->unk_1E4 &= ~4; + this->unk_2E4 = 6; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); + this->actionFunc = func_80B51EA4; + } else { + this->unk_1E4 |= 4; + if (player->transformation == PLAYER_FORM_GORON) { + this->unk_31C = 0xE84; + } else { + this->unk_31C = 0xE99; + } + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + this->actionFunc = func_80B51970; + } + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_318); + } + func_80B50954(this); +} + +void func_80B51EA4(EnGk* this, GlobalContext* globalCtx) { + Vec3s sp38; + s16 sp36; + + if (this->path != NULL) { + func_80B50E14(this->path, this->unk_1EC, &this->actor.world.pos, &sp38); + Math_SmoothStepToS(&this->actor.world.rot.y, sp38.y, 5, 0x1000, 0x100); + this->actor.shape.rot.y = this->actor.world.rot.y; + sp36 = this->actor.shape.rot.y - sp38.y; + if (func_80B50C78(this, this->path, this->unk_1EC)) { + if (this->unk_1EC >= (this->path->count - 1)) { + ActorCutscene_Stop(this->unk_318); + Actor_MarkForDeath(&this->actor); + } else { + this->unk_1EC++; + } + } + + if (this->actor.bgCheckFlags & 8) { + sp38.y = this->actor.wallYaw; + } + + if (ABS_ALT(sp36) < 0x2AAA) { + Math_ApproachF(&this->actor.speedXZ, 3.0f, 0.2f, 0.5f); + } + Actor_MoveWithGravity(&this->actor); + } + func_80B50954(this); +} + +void func_80B51FD0(EnGk* this, GlobalContext* globalCtx) { + if (!(gSaveContext.save.weekEventReg[22] & 4)) { + if (this->unk_1E4 & 2) { + func_801A4748(&this->actor.projectedPos, NA_SE_EN_GOLON_KID_CRY - SFX_FLAG); + } else { + this->unk_1E4 |= 2; + } + } +} + +void func_80B5202C(EnGk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (globalCtx->csCtx.state == 0) { + func_80B51410(this, globalCtx); + } + + if (!func_80B50854(this, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + gSaveContext.save.weekEventReg[24] |= 0x80; + this->actionFunc = func_80B51698; + } else if ((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) { + func_800B863C(&this->actor, globalCtx); + if (player->transformation == PLAYER_FORM_GORON) { + this->actor.textId = 0xE74; + } else { + this->actor.textId = 0xE76; + } + } + + if (this->unk_1E4 & 2) { + if ((globalCtx->msgCtx.ocarinaMode != 1) && (globalCtx->msgCtx.ocarinaMode != 3) && + (globalCtx->csCtx.state == 0)) { + func_801A4748(&this->actor.projectedPos, NA_SE_EN_GOLON_KID_CRY - SFX_FLAG); + } + } else { + this->unk_1E4 |= 2; + } + } +} + +void func_80B5216C(EnGk* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80B51698; + } +} + +void func_80B521E8(EnGk* this, GlobalContext* globalCtx) { + s16 sp1E = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E4].animation); + + if (sp1E == lastFrame) { + this->unk_2E4 = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actionFunc = func_80B5227C; + } +} + +void func_80B5227C(EnGk* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_2E4].animation); + + if ((sp26 + 1) == lastFrame) { + func_800B14D4(globalCtx, 20.0f, &this->actor.home.pos); + this->unk_350 = 60; + if (!(this->unk_1E4 & 0x80)) { + gSaveContext.save.weekEventReg[22] |= 4; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SIT_IMT); + this->unk_350 = 0x4000; + this->actionFunc = func_80B52654; + } +} + +void func_80B52340(EnGk* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_1E4 |= 4; + if (gSaveContext.eventInf[1] & 2) { + this->unk_31C = 0xE90; + this->actionFunc = func_80B52430; + } else { + this->unk_31C = 0xE93; + this->actionFunc = func_80B52430; + } + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + this->actor.flags &= ~ACTOR_FLAG_10000; + } else { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 100.0f); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80B52430(EnGk* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + switch (this->unk_31C) { + case 0xE93: + this->unk_31C = 0xE89; + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + this->actionFunc = func_80B51B40; + return; + + case 0xE90: + this->unk_31C = 0xE91; + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + return; + + case 0xE91: + this->actionFunc = func_80B5253C; + return; + + case 0xE92: + this->unk_1E4 &= ~4; + this->actionFunc = func_80B51760; + return; + } + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80B5253C(EnGk* this, GlobalContext* globalCtx) { + s32 sp24; + + if (gSaveContext.save.weekEventReg[41] & 8) { + sp24 = 0x93; + } else { + sp24 = 0x6A; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + if (sp24 == 0x6A) { + gSaveContext.save.weekEventReg[41] |= 8; + } + this->actionFunc = func_80B525E0; + } else { + Actor_PickUp(&this->actor, globalCtx, sp24, 300.0f, 300.0f); + } +} + +void func_80B525E0(EnGk* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_31C = 0xE92; + Message_StartTextbox(globalCtx, this->unk_31C, &this->actor); + this->actionFunc = func_80B52430; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_80B52654(EnGk* this, GlobalContext* globalCtx) { + this->unk_350 += 0x400; + if ((this->unk_1E4 & 0x80) && (globalCtx->csCtx.frames == 250)) { + gSaveContext.save.weekEventReg[22] |= 4; + } + + this->unk_354 = Math_SinS(this->unk_350) * 0.006f * 0.06f; + this->actor.scale.y = 0.006f - this->unk_354; + this->actor.scale.z = 0.006f - this->unk_354; + this->actor.scale.x = 0.006f + this->unk_354; + if (this->unk_350 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLONKID_SNORE); + } +} + +void EnGk_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGk* this = THIS; + + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_gk_Skel_0079C0, &object_gk_Anim_00787C, this->jointTable, + this->morphTable, 20); + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + this->unk_2E2 = 20; + this->unk_2E0 = 0; + this->unk_1E4 = 0; + this->unk_354 = 0.006f; + Actor_SetScale(&this->actor, 0.006f); + this->actor.gravity = -1.0f; + + if (ENGK_GET_F(&this->actor) == ENGK_F_1) { + this->unk_2E4 = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + if (globalCtx->sceneNum == SCENE_17SETUGEN2) { + if (Flags_GetSwitch(globalCtx, ENGK_GET_3F00(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_318 = this->actor.cutscene; + this->path = SubS_GetPathByIndex(globalCtx, ENGK_GET_F0(&this->actor), 15); + this->actionFunc = func_80B51760; + } + } else if (globalCtx->sceneNum == SCENE_GORONRACE) { + if (gSaveContext.save.weekEventReg[33] & 0x80) { + if (gSaveContext.save.entranceIndex == 0xD010) { + this->actionFunc = func_80B51760; + } else if (gSaveContext.save.entranceIndex == 0xD020) { + this->actionFunc = func_80B52340; + } else { + this->actionFunc = func_80B51760; + } + } else { + Actor_MarkForDeath(&this->actor); + } + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENGK_GET_F(&this->actor) == ENGK_F_2) { + if (!(gSaveContext.save.weekEventReg[22] & 4)) { + this->actionFunc = func_80B51FD0; + this->actor.draw = NULL; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (!(gSaveContext.save.weekEventReg[22] & 4)) { + this->unk_2E4 = 0; + this->unk_318 = this->actor.cutscene; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_2000000; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80B5202C; + } else { + this->actionFunc = func_80B52654; + } +} + +void EnGk_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGk* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnGk_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGk* this = THIS; + + this->actionFunc(this, globalCtx); + + if ((ENGK_GET_F(&this->actor) == ENGK_F_1) || + ((ENGK_GET_F(&this->actor) == ENGK_F_0) && !(gSaveContext.save.weekEventReg[22] & 4))) { + func_80B507A0(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + func_800E9250(globalCtx, &this->actor, &this->unk_1D8, &this->unk_1DE, this->actor.focus.pos); + if (ENGK_GET_F(&this->actor) == ENGK_F_1) { + func_80B5123C(this, globalCtx); + } + func_80B50B38(this, globalCtx); + } + + if (ENGK_GET_F(&this->actor) == ENGK_F_0) { + func_80B51510(this, globalCtx); + } +} + +s32 EnGk_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; +} + +void EnGk_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnGk* this = THIS; + Vec3f sp58 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp4C = { 0.0f, 0.0f, 0.0f }; + Vec3f sp40 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp34 = { 1100.0f, -100.0f, 0.0f }; + Vec3f sp28 = { 1100.0f, -100.0f, 0.0f }; + f32 phi_f0; + + sp34.x = 1100.0f; + sp34.z = 500.0f; + + sp28.x = 1100.0f; + sp28.z = -500.0f; + + if (this->unk_2E4 == 0) { + sp34.y = -100.0f; + sp28.y = -100.0f; + + sp40.x = 2.0f; + sp40.y = 5.8f; + sp40.z = 0.0f; + + sp4C = sp40; + sp4C.x *= -1.0f; + } else if ((this->unk_2E4 == 2) || (this->unk_2E4 == 9) || (this->unk_2E4 == 10) || (this->unk_2E4 == 11)) { + sp34.y = 400.0f; + sp28.y = 400.0f; + + sp40.x = 1.0f; + sp40.y = 0.8f; + sp40.z = 0.0f; + + sp4C = sp40; + sp4C.x *= -1.0f; + } + + if (limbIndex == 17) { + if (ENGK_GET_F(&this->actor) == ENGK_F_1) { + phi_f0 = 100.0f; + } else { + phi_f0 = 50.0f; + } + + this->actor.focus.pos.x = this->actor.world.pos.x; + this->actor.focus.pos.y = this->actor.world.pos.y + phi_f0; + this->actor.focus.pos.z = this->actor.world.pos.z; + + Matrix_MultVec3f(&sp58, &this->actor.focus.pos); + Matrix_MultVec3f(&sp34, &this->unk_2E8); + Matrix_MultVec3f(&sp28, &this->unk_2F4); + + Matrix_Push(); + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sp4C, &this->unk_30C); + Matrix_MultVec3f(&sp40, &this->unk_300); + + Matrix_Pop(); + } +} + +void EnGk_TransformDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGk* this = THIS; + s32 phi_v0; + s32 phi_v1; + + switch (limbIndex) { + case 18: + if (this->unk_1E4 & 8) { + phi_v1 = true; + } else { + phi_v1 = false; + } + + if (this->unk_34E != 0) { + phi_v0 = true; + } else { + phi_v0 = false; + } + func_80B50ED4(this->unk_31E + this->unk_322 + 0x4000, + this->unk_320 + this->unk_324 + this->actor.shape.rot.y + 0x4000, &this->unk_328, + &this->unk_334, phi_v0, phi_v1); + + Matrix_Pop(); + + Matrix_Translate(this->unk_328.x, this->unk_328.y, this->unk_328.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_334.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_334.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_334.z, MTXMODE_APPLY); + + Matrix_Push(); + break; + + case 9: + if (this->unk_1E4 & 8) { + phi_v1 = true; + } else { + phi_v1 = false; + } + + if (this->unk_34E != 0) { + phi_v0 = true; + } else { + phi_v0 = false; + } + func_80B50ED4(this->unk_322 + 0x4000, this->unk_324 + this->actor.shape.rot.y + 0x4000, &this->unk_33C, + &this->unk_348, phi_v0, phi_v1); + + Matrix_Pop(); + + Matrix_Translate(this->unk_33C.x, this->unk_33C.y, this->unk_33C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_348.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_348.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_348.z, MTXMODE_APPLY); + + Matrix_Push(); + break; + } +} + +TexturePtr D_80B533E4[] = { + object_gk_Tex_00F720, + object_gk_Tex_00FF20, + object_gk_Tex_010720, + object_gk_Tex_010F20, +}; + +void EnGk_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGk* this = THIS; + Vec3f sp5C; + Vec3f sp50; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if ((ENGK_GET_F(&this->actor) == ENGK_F_0) && (gSaveContext.save.weekEventReg[22] & 4)) { + Matrix_RotateXS(-0x4000, 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_gk_DL_006688); + gSPDisplayList(POLY_OPA_DISP++, object_gk_DL_006680); + + func_8012C2DC(globalCtx->state.gfxCtx); + + sp5C = this->actor.world.pos; + sp50.x = 0.2f; + sp50.y = 0.2f; + sp50.z = 0.2f; + + func_800BC620(&sp5C, &sp50, 255, globalCtx); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B533E4[this->unk_2E0])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGk_OverrideLimbDraw, EnGk_PostLimbDraw, + EnGk_TransformDraw, &this->actor); + + if (ENGK_GET_F(&this->actor) != ENGK_F_2) { + func_8012C2DC(globalCtx->state.gfxCtx); + if ((this->unk_2E4 == 0) || (this->unk_2E4 == 1) || (this->unk_2E4 == 2) || (this->unk_2E4 == 3) || + (this->unk_2E4 == 4)) { + sp5C.x = this->actor.world.pos.x - 15.0f; + sp5C.y = this->actor.world.pos.y; + sp5C.z = this->actor.world.pos.z; + + sp50.x = 0.2f; + sp50.y = 0.2f; + sp50.z = 0.2f; + } else { + sp5C = this->actor.world.pos; + sp50.x = 0.2f; + sp50.y = 0.2f; + sp50.z = 0.2f; + } + func_800BC620(&sp5C, &sp50, 255, globalCtx); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gk/z_en_gk.h b/src/overlays/actors/ovl_En_Gk/z_en_gk.h index 88a71cb16..21863c66f 100644 --- a/src/overlays/actors/ovl_En_Gk/z_en_gk.h +++ b/src/overlays/actors/ovl_En_Gk/z_en_gk.h @@ -7,11 +7,53 @@ struct EnGk; typedef void (*EnGkActionFunc)(struct EnGk*, GlobalContext*); +#define ENGK_GET_F(thisx) ((thisx)->params & 0xF) +#define ENGK_GET_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define ENGK_GET_3F00(thisx) (((thisx)->params & 0x3F00) >> 8) + +enum { + /* 0 */ ENGK_F_0, + /* 1 */ ENGK_F_1, + /* 2 */ ENGK_F_2, + /* 3 */ ENGK_F_3, + /* 4 */ ENGK_F_4, + /* 5 */ ENGK_F_5, +}; + typedef struct EnGk { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnGkActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x180]; + /* 0x01D8 */ Vec3s unk_1D8; + /* 0x01DE */ Vec3s unk_1DE; + /* 0x01E4 */ u16 unk_1E4; + /* 0x01E8 */ Path* path; + /* 0x01EC */ s32 unk_1EC; + /* 0x01F0 */ Vec3s jointTable[20]; + /* 0x01F0 */ Vec3s morphTable[20]; + /* 0x02E0 */ s16 unk_2E0; + /* 0x02E2 */ s16 unk_2E2; + /* 0x02E4 */ s16 unk_2E4; + /* 0x02E8 */ Vec3f unk_2E8; + /* 0x02F4 */ Vec3f unk_2F4; + /* 0x0300 */ Vec3f unk_300; + /* 0x030C */ Vec3f unk_30C; + /* 0x0318 */ s16 unk_318; + /* 0x031A */ u8 unk_31A; + /* 0x031B */ u8 unk_31B; + /* 0x031C */ u16 unk_31C; + /* 0x031E */ s16 unk_31E; + /* 0x0320 */ s16 unk_320; + /* 0x0322 */ s16 unk_322; + /* 0x0324 */ s16 unk_324; + /* 0x0328 */ Vec3f unk_328; + /* 0x0334 */ Vec3s unk_334; + /* 0x033C */ Vec3f unk_33C; + /* 0x0348 */ Vec3s unk_348; + /* 0x034E */ s16 unk_34E; + /* 0x0350 */ s16 unk_350; + /* 0x0354 */ f32 unk_354; } EnGk; // size = 0x358 extern const ActorInit En_Gk_InitVars; 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 2dfe45e80..07699e7de 100644 --- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -1,6 +1,14 @@ -#include "z_en_gm.h" +/* + * File: z_en_gm.c + * Overlay: ovl_En_Gm + * Description: Gorman + */ -#define FLAGS 0x00000019 +#include "z_en_gm.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_in2/object_in2.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnGm*)thisx) @@ -12,7 +20,141 @@ void EnGm_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80950CDC(EnGm* this, GlobalContext* globalCtx); void func_80950DB8(EnGm* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80951820[] = { + /* 0x000 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(1, 0x13B - 0x005), + /* 0x005 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x02E - 0x009), + /* 0x009 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 9, 0, 0x028 - 0x00F), + /* 0x00F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 0, 9, 10, 0x022 - 0x015), + /* 0x015 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 10, 9, 15, 0x01C - 0x01B), + /* 0x01B */ SCHEDULE_CMD_RET_NONE(), + /* 0x01C */ SCHEDULE_CMD_RET_TIME(9, 10, 9, 15, 15), + /* 0x022 */ SCHEDULE_CMD_RET_TIME(9, 0, 9, 10, 24), + /* 0x028 */ SCHEDULE_CMD_RET_TIME(6, 0, 9, 0, 6), + /* 0x02E */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x07B - 0x032), + /* 0x032 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 10, 9, 15, 0x075 - 0x038), + /* 0x038 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 15, 10, 0, 0x06F - 0x03E), + /* 0x03E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 0, 10, 5, 0x069 - 0x044), + /* 0x044 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 15, 12, 20, 0x063 - 0x04A), + /* 0x04A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 20, 12, 50, 0x05D - 0x050), + /* 0x050 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 50, 12, 55, 0x057 - 0x056), + /* 0x056 */ SCHEDULE_CMD_RET_NONE(), + /* 0x057 */ SCHEDULE_CMD_RET_TIME(12, 50, 12, 55, 12), + /* 0x05D */ SCHEDULE_CMD_RET_TIME(12, 20, 12, 50, 22), + /* 0x063 */ SCHEDULE_CMD_RET_TIME(12, 15, 12, 20, 11), + /* 0x069 */ SCHEDULE_CMD_RET_TIME(10, 0, 10, 5, 10), + /* 0x06F */ SCHEDULE_CMD_RET_TIME(9, 15, 10, 0, 21), + /* 0x075 */ SCHEDULE_CMD_RET_TIME(9, 10, 9, 15, 9), + /* 0x07B */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_L(SCENE_SONCHONOIE, 0x105 - 0x080), + /* 0x080 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 0, 10, 5, 0x0FF - 0x086), + /* 0x086 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 5, 10, 10, 0x0F9 - 0x08C), + /* 0x08C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 10, 10, 30, 0x0F3 - 0x092), + /* 0x092 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 30, 10, 40, 0x0ED - 0x098), + /* 0x098 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 40, 10, 45, 0x0E7 - 0x09E), + /* 0x09E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 45, 10, 55, 0x0E1 - 0x0A4), + /* 0x0A4 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 55, 11, 45, 0x0DB - 0x0AA), + /* 0x0AA */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 45, 11, 55, 0x0D5 - 0x0B0), + /* 0x0B0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 55, 12, 0, 0x0CF - 0x0B6), + /* 0x0B6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 0, 12, 15, 0x0C9 - 0x0BC), + /* 0x0BC */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 15, 12, 20, 0x0C3 - 0x0C2), + /* 0x0C2 */ SCHEDULE_CMD_RET_NONE(), + /* 0x0C3 */ SCHEDULE_CMD_RET_TIME(12, 15, 12, 20, 17), + /* 0x0C9 */ SCHEDULE_CMD_RET_TIME(12, 0, 12, 15, 29), + /* 0x0CF */ SCHEDULE_CMD_RET_TIME(11, 55, 12, 0, 19), + /* 0x0D5 */ SCHEDULE_CMD_RET_TIME(11, 45, 11, 55, 28), + /* 0x0DB */ SCHEDULE_CMD_RET_TIME(10, 55, 11, 45, 2), + /* 0x0E1 */ SCHEDULE_CMD_RET_TIME(10, 45, 10, 55, 27), + /* 0x0E7 */ SCHEDULE_CMD_RET_TIME(10, 40, 10, 45, 18), + /* 0x0ED */ SCHEDULE_CMD_RET_TIME(10, 30, 10, 40, 26), + /* 0x0F3 */ SCHEDULE_CMD_RET_TIME(10, 10, 10, 30, 1), + /* 0x0F9 */ SCHEDULE_CMD_RET_TIME(10, 5, 10, 10, 25), + /* 0x0FF */ SCHEDULE_CMD_RET_TIME(10, 0, 10, 5, 16), + /* 0x105 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0x13A - 0x109), + /* 0x109 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 55, 13, 0, 0x134 - 0x10F), + /* 0x10F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 0, 13, 25, 0x12E - 0x115), + /* 0x115 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 25, 21, 5, 0x128 - 0x11B), + /* 0x11B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 55, 5, 5, 0x122 - 0x121), + /* 0x121 */ SCHEDULE_CMD_RET_NONE(), + /* 0x122 */ SCHEDULE_CMD_RET_TIME(21, 55, 5, 5, 5), + /* 0x128 */ SCHEDULE_CMD_RET_TIME(13, 25, 21, 5, 3), + /* 0x12E */ SCHEDULE_CMD_RET_TIME(13, 0, 13, 25, 30), + /* 0x134 */ SCHEDULE_CMD_RET_TIME(12, 55, 13, 0, 20), + /* 0x13A */ SCHEDULE_CMD_RET_NONE(), + /* 0x13B */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(2, 0x1EB - 0x140), + /* 0x140 */ SCHEDULE_CMD_CHECK_FLAG_L(0x32, 0x01, 0x1CD - 0x145), + /* 0x145 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x17A - 0x149), + /* 0x149 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 18, 0, 0x174 - 0x14F), + /* 0x14F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 21, 0, 0x16E - 0x155), + /* 0x155 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 0, 21, 10, 0x168 - 0x15B), + /* 0x15B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 10, 21, 15, 0x162 - 0x161), + /* 0x161 */ SCHEDULE_CMD_RET_NONE(), + /* 0x162 */ SCHEDULE_CMD_RET_TIME(21, 10, 21, 15, 15), + /* 0x168 */ SCHEDULE_CMD_RET_TIME(21, 0, 21, 10, 24), + /* 0x16E */ SCHEDULE_CMD_RET_TIME(18, 0, 21, 0, 6), + /* 0x174 */ SCHEDULE_CMD_RET_TIME(6, 0, 18, 0, 7), + /* 0x17A */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x1A3 - 0x17E), + /* 0x17E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 10, 21, 15, 0x19D - 0x184), + /* 0x184 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 15, 21, 25, 0x197 - 0x18A), + /* 0x18A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 25, 21, 30, 0x191 - 0x190), + /* 0x190 */ SCHEDULE_CMD_RET_NONE(), + /* 0x191 */ SCHEDULE_CMD_RET_TIME(21, 25, 21, 30, 14), + /* 0x197 */ SCHEDULE_CMD_RET_TIME(21, 15, 21, 25, 23), + /* 0x19D */ SCHEDULE_CMD_RET_TIME(21, 10, 21, 15, 13), + /* 0x1A3 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0x1CC - 0x1A7), + /* 0x1A7 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 30, 21, 45, 0x1C6 - 0x1AD), + /* 0x1AD */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 45, 22, 10, 0x1C0 - 0x1B3), + /* 0x1B3 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(22, 10, 6, 0, 0x1BA - 0x1B9), + /* 0x1B9 */ SCHEDULE_CMD_RET_NONE(), + /* 0x1BA */ SCHEDULE_CMD_RET_TIME(22, 10, 6, 0, 5), + /* 0x1C0 */ SCHEDULE_CMD_RET_TIME(21, 45, 22, 10, 30), + /* 0x1C6 */ SCHEDULE_CMD_RET_TIME(21, 30, 21, 45, 20), + /* 0x1CC */ SCHEDULE_CMD_RET_NONE(), + /* 0x1CD */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x1EA - 0x1D1), + /* 0x1D1 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 18, 0, 0x1E4 - 0x1D7), + /* 0x1D7 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x1DE - 0x1DD), + /* 0x1DD */ SCHEDULE_CMD_RET_NONE(), + /* 0x1DE */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 0, 8), + /* 0x1E4 */ SCHEDULE_CMD_RET_TIME(6, 0, 18, 0, 7), + /* 0x1EA */ SCHEDULE_CMD_RET_NONE(), + /* 0x1EB */ SCHEDULE_CMD_RET_NONE(), +}; + +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, @@ -25,130 +167,1673 @@ 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 AnimationInfoS D_80951CC0[] = { + { &object_in2_Anim_009CDC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in2_Anim_009CDC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in2_Anim_00A5E0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in2_Anim_00A70C, 1.0f, 0, 1, ANIMMODE_LOOP, 0 }, + { &object_in2_Anim_008090, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in2_Anim_00898C, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_in2_Anim_009450, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_in2_Anim_00AD18, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in2_Anim_00AD18, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in2_Anim_00B8B0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_in2_Anim_00BA80, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in2_Anim_00C03C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in2_Anim_00B990, 1.0f, 0, -1, ANIMMODE_LOOP, -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 = SubS_ChangeAnimationByInfoS(&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 = SubS_GetObjectIndex(OBJECT_IN2, 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) || !SubS_IsObjectLoaded(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.save.weekEventReg[86] & 0x40) && (this->unk_3E0 == 2)) { + ActorCutscene_Stop(sp2A); + } else { + Camera_SetTargetActor(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)) { + Camera_SetTargetActor(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: + Actor_PlaySfxAtPos(&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)); + Camera_SetTargetActor(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)); + Camera_SetTargetActor(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: + Actor_PlaySfxAtPos(&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.save.weekEventReg[50] & 1) || (gSaveContext.save.weekEventReg[51] & 0x80) || + (gSaveContext.save.weekEventReg[75] & 2)) { + ret = true; + break; + } + Actor_PlaySfxAtPos(&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: + Actor_PlaySfxAtPos(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&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.save.weekEventReg[50] & 1) && + !(gSaveContext.save.weekEventReg[51] & 0x80) && !(gSaveContext.save.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.save.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 = Message_GetState(&globalCtx->msgCtx); + s32 var = globalCtx->msgCtx.currentTextId; + + 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_Translate(this->unk_3B0, 0.0f, 0.0f, MTXMODE_APPLY); + 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.currentTextId; + 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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HANKO); + } + + return false; +} + +s32 func_8094F7D0(EnGm* this, GlobalContext* globalCtx, ScheduleResult* 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->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80951A0C[arg2->result]); + } + + if ((actor != NULL) && (actor->update != NULL)) { + if (this->unk_234 != NULL) { + sp48 = 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, ScheduleResult* arg2) { + u16 sp56 = SCHEDULE_TIME_NOW; + u8 sp55 = ENGM_GET_FF(&this->actor); + EnDoor* door; + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + door = func_8094DF90(globalCtx, arg2->result); + + if (D_80951A0C[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp55, D_80951A0C[arg2->result]); + } + + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if (this->unk_234 != NULL) { + sp4C = 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, door->dyna.actor.shape.rot.y)) <= 0x4000) { + this->unk_261 = -75; + } else { + this->unk_261 = 75; + } + + this->unk_3B8 = arg2->time1 - arg2->time0; + this->unk_3BA = sp56 - arg2->time0; + this->actor.flags &= ~ACTOR_FLAG_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, ScheduleResult* arg2) { + u16 sp2E = SCHEDULE_TIME_NOW; + u16 phi_v1; + u8 sp2B = ENGM_GET_FF(&this->actor); + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + if (D_80951A0C[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp2B, D_80951A0C[arg2->result]); + } + + 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->time0; + } + + if (arg2->time1 < phi_v1) { + this->unk_248 = (phi_v1 - arg2->time1) + 0xFFFF; + } else { + this->unk_248 = arg2->time1 - 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; + SubS_UpdateFlags(&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, ScheduleResult* 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); + SubS_UpdateFlags(&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, ScheduleResult* arg2) { + s32 ret = false; + + if (func_8094F7D0(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_RECEPGIRL)) { + func_8094E054(this, globalCtx, 11); + SubS_UpdateFlags(&this->unk_3A4, 3, 7); + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + ret = true; + } + return ret; +} + +s32 func_8094FE10(EnGm* this, GlobalContext* globalCtx, ScheduleResult* 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); + SubS_UpdateFlags(&this->unk_3A4, 3, 7); + this->unk_268 = al; + if (!(gSaveContext.save.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, ScheduleResult* 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->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80951A0C[arg2->result]); + } + + if (this->unk_234 != NULL) { + sp48 = 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); + SubS_UpdateFlags(&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, ScheduleResult* 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); + SubS_UpdateFlags(&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, ScheduleResult* 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); + SubS_UpdateFlags(&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, ScheduleResult* 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; + SubS_UpdateFlags(&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, ScheduleResult* arg2) { + s32 phi_v1; + + this->actor.flags |= ACTOR_FLAG_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->result) { + 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 = ActorShadow_DrawCircle; + SubS_UpdateFlags(&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.save.weekEventReg[50] & 1) || (gSaveContext.save.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 = ActorShadow_DrawCircle; + SubS_UpdateFlags(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_GO_SLEEP); + this->unk_3B8 = 30; + } + break; + + case 8: + break; + } + + SubS_FillLimbRotTables(globalCtx, this->unk_3D8, this->unk_3D2, ARRAY_COUNT(this->unk_3D8)); + + return false; +} + +s32 func_80950804(EnGm* this, GlobalContext* globalCtx) { + EnDoor* door; + Vec3f sp38; + s32 pad; + f32 temp_f0; + + door = func_8094DF90(globalCtx, this->unk_258); + if (!SubS_InCsMode(globalCtx) && (this->unk_3C4 != 0)) { + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if ((this->unk_3BA / (f32)this->unk_3B8) <= 0.9f) { + door->unk_1A7 = this->unk_261; + } else { + door->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)) { + Actor_PlaySfxAtPos(&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 (SubS_InCsMode(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 (SubS_InCsMode(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)) { + Actor_PlaySfxAtPos(&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) { + ScheduleResult sp20; + + this->unk_3C4 = REG(15) + ((void)0, gSaveContext.save.daySpeed); + + if (!Schedule_RunScript(globalCtx, D_80951820, &sp20) || + ((this->unk_258 != sp20.result) && !func_80950280(this, globalCtx, &sp20))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp20.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_258 = sp20.result; + 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)) { + SubS_UpdateFlags(&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); + } + } + SubS_FillLimbRotTables(globalCtx, this->unk_3D8, this->unk_3D2, ARRAY_COUNT(this->unk_3D8)); +} + +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 (Cutscene_CheckActorAction(globalCtx, 526)) { + sp2C = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 526)]->action; + if (this->unk_259 != (sp2C & 0xFF)) { + if (sp2C == 3) { + Actor_PlaySfxAtPos(&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, ActorShadow_DrawCircle, 22.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_in2_Skel_0078B0, 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, EXCH_ITEM_NONE, this->unk_3A4 & 7); + if ((this->unk_258 != 3) && (this->unk_258 != 5) && (this->unk_258 != 8)) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } + func_8094E1DC(this, globalCtx); + } + } +} + +s32 EnGm_OverrideLimbDraw(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 EnGm_PostLimbDraw(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_MultVec3f(&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++, object_in2_DL_007528); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (limbIndex == 9) { + Matrix_MultVec3f(&gZeroVec3f, &sp30); + Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp30); + } +} + +void EnGm_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGm* this = THIS; + s32 overrideRot = true; + s32 stepRot = false; + + if (!(this->unk_3A4 & 0x200)) { + if (this->unk_3A4 & 0x80) { + overrideRot = true; + stepRot = true; + } else { + overrideRot = false; + stepRot = true; + } + } else { + overrideRot = false; + } + + if (limbIndex == 16) { + SubS_UpdateLimb(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, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(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_RotateYS(this->unk_2A8.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2A8.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2A8.z, MTXMODE_APPLY); + Matrix_Push(); + } else if (limbIndex == 9) { + SubS_UpdateLimb(BINANG_ADD(this->unk_3C0, 0x4000), BINANG_ADD(this->unk_3C2 + this->actor.shape.rot.y, 0x4000), + &this->unk_29C, &this->unk_2AE, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(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_RotateYS(this->unk_2AE.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2AE.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2AE.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnGm_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80951E30[] = { object_in2_Tex_0054A8, object_in2_Tex_005028, object_in2_Tex_006828, + object_in2_Tex_005028, object_in2_Tex_005CE8, object_in2_Tex_006C68 }; + 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])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGm_OverrideLimbDraw, EnGm_PostLimbDraw, + EnGm_TransformLimbDraw, &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 fcdaf8eaa..27c307777 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -1,6 +1,16 @@ -#include "z_en_go.h" +/* + * File: z_en_go.c + * Overlay: ovl_En_Go + * Description: Goron + */ -#define FLAGS 0x02000019 +#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 (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnGo*)thisx) @@ -17,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, @@ -31,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), @@ -91,156 +186,1902 @@ static DamageTable D_80A164C4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; +static AnimationInfoS sAnimations[] = { + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_oF1d_map_Anim_0039D8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_oF1d_map_Anim_003650, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_oF1d_map_Anim_0135E8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + + { &object_taisou_Anim_004DD4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_0016C8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_00283C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_007764, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_005EE0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_002C48, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_0031D8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_taisou_Anim_005790, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + + { &object_hakugin_demo_Anim_001420, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_hakugin_demo_Anim_001A4C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_hakugin_demo_Anim_002704, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_hakugin_demo_Anim_003378, 1.0f, 0, -1, ANIMMODE_LOOP, -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_Push(); + + 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_Translate(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Pop(); + 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[] = { + gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex, + }; + 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_Push(); + + 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_Translate(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_ReplaceRotation(&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_Pop(); + } + if (globalCtx->state.gfxCtx) {} + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +#ifdef NON_MATCHING +void func_80A118F8(EnGoStruct* ptr, 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, +}; +void func_80A118F8(EnGoStruct* ptr, Vec3f arg1); +#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_Push(); + Matrix_Translate(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_RotateZS(ptr->unk_0A.z, MTXMODE_APPLY); + Matrix_RotateXS(ptr->unk_0A.x, MTXMODE_APPLY); + Matrix_RotateYS(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_Pop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +void func_80A11EC0(EnGoStruct* ptr, GlobalContext* globalCtx, Gfx* arg2, Gfx* arg3, u8 arg4); #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.ocarinaMode == 3) && + (globalCtx->msgCtx.unk1202E == 1) && (this->unk_3EC == 0) && (this->actor.xzDistToPlayer < 400.0f)) || + (!(gSaveContext.save.weekEventReg[22] & 4) && (globalCtx->sceneNum == SCENE_16GORON_HOUSE) && + (gSaveContext.sceneSetupIndex == 0) && (this->unk_3EC == 0) && (globalCtx->csCtx.currentCsIndex == 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) || !Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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") + SubS_UpdateFlags(&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.currentCsIndex == 0)) { + if (this->unk_3F0 == 0) { + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_394 = 255; + this->unk_3F0 = 1; + this->unk_18C = this->actionFunc; + } + SubS_UpdateFlags(&this->unk_390, 0, 7); + this->actionFunc = func_80A14FC8; + } else if (this->unk_3F0 != 0) { + this->actor.flags |= ACTOR_FLAG_1; + this->unk_394 = 255; + this->unk_3F0 = 0; + SubS_UpdateFlags(&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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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 = false; -#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 = SubS_ChangeAnimationByInfoS(&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.currentTextId; + 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)) { + SubS_UpdateFlags(&this->unk_390, 3, 7); + } else if ((player->transformation != PLAYER_FORM_GORON) || (ABS_ALT(temp_v1) >= 0x1C70) || + (gSaveContext.save.weekEventReg[21] & 4) || (gSaveContext.save.weekEventReg[21] & 8)) { + SubS_UpdateFlags(&this->unk_390, 3, 7); + } else { + SubS_UpdateFlags(&this->unk_390, 4, 7); + } +} + +void func_80A133A8(EnGo* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[21] & 8) { + SubS_UpdateFlags(&this->unk_390, 3, 7); + } else { + SubS_UpdateFlags(&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.save.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, CAM_ID_MAIN), 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_Push(); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + Matrix_Translate(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_Pop(); + } +} + +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) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_LAND_BIG); + func_80A13728(this, globalCtx); + this->unk_3C4++; + this->unk_3C2 = 0; + gSaveContext.save.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.save.weekEventReg[88] |= 0x80; + break; + + case 1: + gSaveContext.save.weekEventReg[89] |= 4; + break; + + case 2: + gSaveContext.save.weekEventReg[89] |= 2; + break; + + case 3: + gSaveContext.save.weekEventReg[89] |= 1; + break; + } + ret = true; + } + break; + } + + Actor_MoveWithGravity(&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)) { + Actor_PlaySfxAtPos(&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 &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_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 &= ~ACTOR_FLAG_2000000; + SubS_CopyPointFromPathCheckBounds(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; + SubS_UpdateFlags(&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; + SubS_UpdateFlags(&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.save.entranceIndex == 0xD000) || (gSaveContext.save.entranceIndex == 0xD020)) && + (gSaveContext.save.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.save.entranceIndex == 0xD010) || (gSaveContext.save.entranceIndex == 0x1C00)) { + func_80A14104(this, globalCtx); + this->actionFunc = func_80A149B0; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80A144F4(EnGo* this, GlobalContext* globalCtx) { + if (gSaveContext.save.day >= 2) { + this->unk_284 = SubS_GetDayDependentPath(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.currentCsIndex == 0)) || + !(gSaveContext.save.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.save.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 &= ~ACTOR_FLAG_1; + this->actor.targetMode = 3; + this->unk_390 = 0; + this->actor.gravity = -1.0f; + SubS_UpdateFlags(&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) { + EffectTireMarkInit sp38 = { + 0, + 62, + { 0, 0, 15, 100 }, + }; + + if ((this->unk_288 < 0) || SubS_IsObjectLoaded(this->unk_288, globalCtx) || (this->unk_289 < 0) || + SubS_IsObjectLoaded(this->unk_289, globalCtx)) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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, EFFECT_TIRE_MARK, 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.save.entranceIndex == 0xD010)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_GORON_CHEER - SFX_FLAG); + } else if (ENGO_GET_F(&this->actor) != ENGO_F_8) { + if (func_80A1222C(this, globalCtx)) { + SubS_UpdateFlags(&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) { + SubS_UpdateFlags(&this->unk_390, 3, 7); + } else { + SubS_UpdateFlags(&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.save.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; + } + Actor_PlaySfxAtPos(&this->actor, sfxId); + } + this->unk_3AE += 0x400; + this->actor.shape.yOffset = (this->actor.scale.y / this->unk_3A4) * 14.0f; + SubS_UpdateFlags(&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; + } + + SubS_FillLimbRotTables(globalCtx, this->unk_3CE, this->unk_3C8, ARRAY_COUNT(this->unk_3CE)); + 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) { + Actor_PlaySfxAtPos(&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)) { + SubS_UpdateFlags(&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 actorActionCmd = 0; + s32 sp30; + s32 actionIndex; + + switch (ENGO_GET_70(&this->actor)) { + case ENGO_70_0: + actorActionCmd = 128; + break; + + case ENGO_70_1: + actorActionCmd = 129; + break; + } + + if ((actorActionCmd == 128) || (actorActionCmd == 129)) { + if (Cutscene_CheckActorAction(globalCtx, actorActionCmd)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, actorActionCmd); + sp30 = globalCtx->csCtx.actorActions[actionIndex]->action; + + 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) { + Actor_PlaySfxAtPos(&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 (actorActionCmd == 128) { + switch (globalCtx->csCtx.frames) { + case 55: + case 100: + case 130: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_COLD); + break; + + case 185: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_WAKE_UP); + break; + + case 250: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_EYE_BIG); + break; + + case 465: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IWAIGORON_SOLO); + break; + + case 490: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL); + break; + } + } else if (actorActionCmd == 129) { + switch (globalCtx->csCtx.frames) { + case 360: + case 390: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_COLD); + break; + + case 430: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_WAKE_UP); + break; + + case 450: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_EYE_BIG); + break; + + case 480: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL); + break; + } + } + + SubS_FillLimbRotTables(globalCtx, this->unk_3CE, this->unk_3C8, ARRAY_COUNT(this->unk_3CE)); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } + } +} + +void func_80A153FC(EnGo* this, GlobalContext* globalCtx) { + Vec3s* sp5C; + Vec3f sp50; + Vec3f sp44; + + if ((this->unk_390 & 0x1000) && (this->actor.colChkInfo.damageEffect == 0xF)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SNOWBALL_BROKEN); + + this->actor.flags &= ~ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_2000000; + + func_80A118F8(this->unk_3F8, this->actor.world.pos); + this->actor.shape.rot.x = 0; + this->actor.speedXZ = 0.0f; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_COLD); + + if (gSaveContext.save.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), 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 (SubS_HasReachedPoint(&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) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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); + } + SubS_FillLimbRotTables(globalCtx, this->unk_3CE, this->unk_3C8, ARRAY_COUNT(this->unk_3CE)); + 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; + SubS_UpdateFlags(&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 = SubS_GetObjectIndex(OBJECT_TAISOU, globalCtx); + this->unk_289 = SubS_GetObjectIndex(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, EXCH_ITEM_NONE, 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, EXCH_ITEM_NONE, 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_Translate(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset, + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Translate(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_RotateXS(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)) { + Matrix_MultZero(&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_TransfromLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGo* this = THIS; + u16 temp_v0; + s32 stepRot; + s32 overrideRot; + + if (this->unk_390 & 0x40) { + stepRot = false; + } else { + stepRot = true; + } + + if (this->unk_390 & 0x10) { + overrideRot = true; + } else { + overrideRot = false; + } + + if (!stepRot) { + overrideRot = false; + } + + switch (limbIndex) { + case 17: + SubS_UpdateLimb(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, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(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_RotateYS(this->unk_2A8.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2A8.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2A8.z, MTXMODE_APPLY); + Matrix_Push(); + break; + + case 10: + SubS_UpdateLimb(this->unk_3B4 + 0x4000, this->unk_3B6 + this->actor.shape.rot.y + 0x4000, &this->unk_29C, + &this->unk_2AE, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(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_RotateYS(this->unk_2AE.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2AE.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2AE.z, MTXMODE_APPLY); + Matrix_Push(); + break; + } +} + +void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr 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_Translate(0.0f, 0.0f, -4000.0f, MTXMODE_APPLY); + } + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGo_OverrideLimbDraw, NULL, EnGo_TransfromLimbDraw, + &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 49cf58f3d..f17a75f6a 100644 --- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c +++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c @@ -1,6 +1,14 @@ -#include "z_en_goroiwa.h" +/* + * File: z_en_goroiwa.c + * Overlay: ovl_En_Goroiwa + * Description: Rolling boulders + */ -#define FLAGS 0x80000010 +#include "z_en_goroiwa.h" +#include "objects/object_goroiwa/object_goroiwa.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnGoroiwa*)thisx) @@ -9,7 +17,21 @@ void EnGoroiwa_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx); void EnGoroiwa_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809419D0(EnGoroiwa* this); +void func_80941A10(EnGoroiwa* this, GlobalContext* globalCtx); +void func_809421E0(EnGoroiwa* this); +void func_8094220C(EnGoroiwa* this, GlobalContext* globalCtx); +void func_809425CC(EnGoroiwa* this); +void func_80942604(EnGoroiwa* this, GlobalContext* globalCtx); +void func_80941DB4(EnGoroiwa* this); +void func_80941E28(EnGoroiwa* this, GlobalContext* globalCtx); +void func_80941EB4(EnGoroiwa* this); +void func_80941F10(EnGoroiwa* this, GlobalContext* globalCtx); +void func_80941F54(EnGoroiwa* this); +void func_80941FA4(EnGoroiwa* this, GlobalContext* globalCtx); +void func_80942084(EnGoroiwa* this); +void func_809420F0(EnGoroiwa* this, GlobalContext* globalCtx); + const ActorInit En_Goroiwa_InitVars = { ACTOR_EN_GOROIWA, ACTORCAT_PROP, @@ -22,141 +44,1567 @@ const ActorInit En_Goroiwa_InitVars = { (ActorFunc)EnGoroiwa_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80942DC0[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 58 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80942DE4 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 1, D_80942DC0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80942DF4 = { 0, 12, 60, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80942E78[] = { - ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -26000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 160, ICHAIN_CONTINUE), +static f32 D_80942DFC[] = { + 10.0f, + 12.0f, + 14.0f, + 10.0f, +}; + +static Gfx* D_80942E0C[][3] = { + { object_goroiwa_DL_0042B0, object_goroiwa_DL_004960, object_goroiwa_DL_004EF0 }, + { object_goroiwa_DL_0003B0, object_goroiwa_DL_0028E0, object_goroiwa_DL_002D70 }, + { object_goroiwa_DL_0072F0, object_goroiwa_DL_0077D0, object_goroiwa_DL_007C60 }, +}; + +static Color_RGBA8 D_80942E30[] = { + { 190, 195, 200, 255 }, + { 170, 130, 90, 255 }, +}; + +static Color_RGBA8 D_80942E38 = { 250, 250, 250, 255 }; + +static Color_RGBA8 D_80942E3C[] = { + { 130, 135, 140, 255 }, + { 100, 60, 20, 255 }, +}; + +static Color_RGBA8 D_80942E44 = { 180, 180, 180, 255 }; + +static Vec3f D_80942E48 = { 0.0f, 0.0f, 0.0f }; +static Vec3f D_80942E54 = { 0.0f, 0.3f, 0.0f }; +static Vec3f D_80942E60 = { 0.0f, 1.0f, 0.0f }; +static Vec3f D_80942E6C = { 0.0f, 0.0f, 1.0f }; + +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(terminalVelocity, -26000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 160, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 350, ICHAIN_STOP), }; -#endif +static UNK_TYPE D_80942E8C[] = { + 0x0000003B, + 0x1A1A2864, +}; -extern ColliderJntSphElementInit D_80942DC0[1]; -extern ColliderJntSphInit D_80942DE4; -extern CollisionCheckInfoInit D_80942DF4; -extern InitChainEntry D_80942E78[]; +void func_8093E8A0(EnGoroiwa* this) { + s32 params = ENGOROIWA_GET_3000(&this->actor); + f32 phi_f2; -extern UNK_TYPE D_060032E0; + if (params == ENGOROIWA_3000_0) { + phi_f2 = 0.1f; + } else if (params == ENGOROIWA_3000_1) { + phi_f2 = 0.05f; + } else { + phi_f2 = (Rand_ZeroOne() * (f32)0.04) + 0.04f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093E8A0.s") + Actor_SetScale(&this->actor, phi_f2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093E91C.s") +void func_8093E91C(EnGoroiwa* this) { + this->unk_1DC = this->actor.scale.x * 595.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093E938.s") +void func_8093E938(EnGoroiwa* this) { + Sphere16* worldSphere = &this->collider.elements->dim.worldSphere; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093E9B0.s") + worldSphere->center.x = this->actor.world.pos.x; + worldSphere->center.y = this->actor.world.pos.y + this->unk_1DC; + worldSphere->center.z = this->actor.world.pos.z; + this->collider.elements->dim.worldSphere.radius = this->unk_1DC - 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EAB0.s") +void func_8093E9B0(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 pad[2]; + s32 params = ENGOROIWA_GET_C000(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EAD4.s") + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + func_8093E938(this); + this->collider.elements[0].dim.worldSphere.radius = this->unk_1DC - 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EB58.s") + if ((params == ENGOROIWA_C000_1) || (params == ENGOROIWA_C000_2)) { + this->collider.elements[0].info.bumper.dmgFlags |= (0x4000 | 0x400 | 0x100); + if (params == ENGOROIWA_C000_1) { + this->collider.base.colType = COLTYPE_WOOD; + } else { + this->collider.elements[0].info.bumper.dmgFlags &= ~(0x400000 | 0x200 | 0x2); + this->collider.elements[0].info.bumper.dmgFlags |= (0x80000000 | 0x800 | 0x8); + this->collider.base.colType = COLTYPE_NONE; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EB74.s") +void func_8093EAB0(EnGoroiwa* this, u8 arg0) { + this->unk_1E5 &= ~7; + this->unk_1E5 |= arg0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EC50.s") +s32 func_8093EAD4(Vec3f* arg0, Vec3f* arg1) { + f32 temp_f0 = Math3D_Vec3fMagnitude(arg1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093ECD4.s") + if (temp_f0 < 0.001f) { + return false; + } + arg0->x = arg1->x * (1.0f / temp_f0); + arg0->y = arg1->y * (1.0f / temp_f0); + arg0->z = arg1->z * (1.0f / temp_f0); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093ED80.s") +void func_8093EB58(EnGoroiwa* this, GlobalContext* globalCtx) { + this->unk_1E4 = (this->actor.home.rot.x >> 1) & 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EDB0.s") +f32 func_8093EB74(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 i; + Path* path = &globalCtx->setupPathList[ENGOROIWA_GET_FF(&this->actor)]; + s32 temp_s4 = path->count; + f32 temp_f20 = 0.0f; + Vec3f sp54; + Vec3f sp48; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EDD8.s") + Math_Vec3s_ToVec3f(&sp48, &this->unk_1D0[0]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EE18.s") + for (i = 1; i < temp_s4; i++) { + Math_Vec3f_Copy(&sp54, &sp48); + Math_Vec3s_ToVec3f(&sp48, &this->unk_1D0[i]); + temp_f20 += Math3D_Distance(&sp54, &sp48); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EE64.s") + return temp_f20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EEBC.s") +void func_8093EC50(EnGoroiwa* this) { + Vec3s* var = &this->unk_1D0[this->unk_1D8]; + Vec3f sp18; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EEDC.s") + sp18.x = var->x; + sp18.y = var->y; + sp18.z = var->z; + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp18); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093EF54.s") +void func_8093ECD4(EnGoroiwa* this) { + s32 params = ENGOROIWA_GET_300(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093F198.s") + if (this->unk_1D8 < 0) { + if ((params == ENGOROIWA_300_0) || (params == ENGOROIWA_300_1)) { + this->unk_1D8 = this->unk_1D4 - 1; + this->unk_1DA = -1; + this->unk_1D6 = this->unk_1D4; + } else if (params == ENGOROIWA_300_3) { + this->unk_1D6 = 0; + this->unk_1D8 = 1; + this->unk_1DA = 1; + } + } else if (this->unk_1D4 < this->unk_1D8) { + if ((params == ENGOROIWA_300_0) || (params == ENGOROIWA_300_1)) { + this->unk_1D6 = 0; + this->unk_1D8 = 1; + this->unk_1DA = 1; + } else if (params == ENGOROIWA_300_3) { + this->unk_1D6 = this->unk_1D4; + this->unk_1D8 = this->unk_1D4 - 1; + this->unk_1DA = -1; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093F34C.s") +void func_8093ED80(EnGoroiwa* this) { + this->unk_1D6 = this->unk_1D8; + this->unk_1D8 += this->unk_1DA; + func_8093ECD4(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093F498.s") +void func_8093EDB0(EnGoroiwa* this) { + this->unk_1DA = -this->unk_1DA; + this->unk_1D6 = this->unk_1D8; + this->unk_1D8 += this->unk_1DA; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093F5EC.s") +void func_8093EDD8(EnGoroiwa* this, GlobalContext* globalCtx) { + this->unk_1D4 = globalCtx->setupPathList[ENGOROIWA_GET_FF(&this->actor)].count - 1; + this->unk_1D6 = 0; + this->unk_1D8 = 1; + this->unk_1DA = 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093F6F8.s") +void func_8093EE18(EnGoroiwa* this, GlobalContext* globalCtx) { + this->unk_1D4 = globalCtx->setupPathList[ENGOROIWA_GET_FF(&this->actor)].count - 1; + this->unk_1D6 = this->actor.home.rot.y; + this->unk_1D8 = this->unk_1D6 + 1; + this->unk_1DA = 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093FAA4.s") +void func_8093EE64(EnGoroiwa* this, s32 arg1) { + Vec3s* temp_v0 = &this->unk_1D0[arg1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093FC00.s") + this->actor.world.pos.x = temp_v0->x; + this->actor.world.pos.y = temp_v0->y; + this->actor.world.pos.z = temp_v0->z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8093FC6C.s") +void func_8093EEBC(EnGoroiwa* this) { + this->unk_1B4.x = 1.0f; + this->unk_1C4 = 1.0f; + this->unk_1A8.x = 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80940090.s") +s32 func_8093EEDC(EnGoroiwa* this) { + Vec3s* temp_v1 = &this->unk_1D0[this->unk_1D8]; + Vec3s* temp_v0 = &this->unk_1D0[this->unk_1D6]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80940588.s") + if ((temp_v1->x == temp_v0->x) && (temp_v1->z == temp_v0->z)) { + if (temp_v0->y < temp_v1->y) { + return 1; + } + return -1; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80940A1C.s") +void func_8093EF54(GlobalContext* globalCtx, Vec3f* arg1, Color_RGBA8* arg2, Color_RGBA8* arg3, f32 arg4) { + Vec3f spC4; + f32 temp_f0; + f32 temp_f20; + f32 temp_f24; + f32 temp_f26; + s32 temp_f16; + s16 phi_s0; + s16 temp; + f32 temp_f28; + f32 temp_f30; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80940E38.s") + temp_f0 = (arg4 + 0.1f) * 0.5f; + temp_f16 = temp_f0 * 165.0f; + temp_f24 = 470.0f * arg4; + temp_f30 = 400.0f * arg4; + temp_f26 = 800.0f * temp_f0; + temp_f28 = 600.0f * temp_f0; + temp = 0x10000 / temp_f16; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941060.s") + for (i = 0, phi_s0 = 0; i < temp_f16; i++, phi_s0 += temp) { + // clang-format off + temp_f20 = Rand_ZeroOne(); spC4.x = (Math_SinS(phi_s0) * (temp_f24 * ((temp_f20 * 0.5f) + 0.5f))) + arg1->x; + spC4.y = ((Rand_ZeroOne() - 0.5f) * temp_f30) + arg1->y; + temp_f20 = Rand_ZeroOne(); spC4.z = (Math_CosS(phi_s0) * (temp_f24 * ((temp_f20 * 0.5f) + 0.5f))) + arg1->z; + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941274.s") + func_800B0E48(globalCtx, &spC4, &D_80942E48, &D_80942E54, arg2, arg3, (Rand_ZeroOne() * temp_f28) + temp_f26, + temp_f26); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/EnGoroiwa_Init.s") +void func_8093F198(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2) { + Vec3f sp74; + f32 temp_f20; + s32 temp_f16; + s16 temp_lo; + s16 phi_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/EnGoroiwa_Destroy.s") + temp_f16 = (arg2 + 0.1f) * 58.0f; + sp74.y = arg1->y; + temp_f20 = 550.0f * arg2; + temp_lo = 0x10000 / temp_f16; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8094156C.s") + for (i = 0, phi_s0 = 0; i < temp_f16; i++, phi_s0 += temp_lo) { + sp74.x = (Math_SinS((s32)(Rand_ZeroOne() * temp_lo) + phi_s0) * temp_f20) + arg1->x; + sp74.z = (Math_CosS((s32)(Rand_ZeroOne() * temp_lo) + phi_s0) * temp_f20) + arg1->z; + EffectSsGSplash_Spawn(globalCtx, &sp74, NULL, NULL, 0, 0x15E); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_809419D0.s") + EffectSsGRipple_Spawn(globalCtx, arg1, 0x1F4, 0x384, 4); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941A10.s") +s32 func_8093F34C(EnGoroiwa* this) { + s32 pad[3]; + Vec3s* temp_v0; + f32 tempX; + f32 tempZ; + f32 x; + f32 z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941DB4.s") + Math_StepToF(&this->actor.speedXZ, D_80942DFC[this->unk_1E4], 0.3f); + Actor_UpdateVelocityWithGravity(&this->actor); + temp_v0 = &this->unk_1D0[this->unk_1D8]; + this->actor.velocity.y *= 0.97f; + x = temp_v0->x; + z = temp_v0->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941E28.s") + tempX = x - this->actor.world.pos.x; + tempZ = z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941EB4.s") + if (SQ(this->actor.speedXZ + 1.0f) < (SQ(tempX) + SQ(tempZ))) { + this->actor.world.pos.x += this->actor.velocity.x; + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.z += this->actor.velocity.z; + this->unk_1E5 &= ~0x40; + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941F10.s") + this->actor.world.pos.x = x; + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.z = z; + this->unk_1E5 |= 0x40; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941F54.s") +s32 func_8093F498(EnGoroiwa* this) { + s32 pad; + f32 temp_f0; + Vec3f sp2C; + Vec3s* temp_v0 = &this->unk_1D0[this->unk_1D8]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80941FA4.s") + sp2C.x = temp_v0->x; + sp2C.y = temp_v0->y; + sp2C.z = temp_v0->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80942084.s") + Math_StepToF(&this->actor.speedXZ, D_80942DFC[this->unk_1E4], 0.3f); + Math_Vec3f_Diff(&sp2C, &this->actor.world.pos, &this->actor.velocity); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_809420F0.s") + temp_f0 = Math3D_Vec3fMagnitude(&this->actor.velocity); + if ((this->actor.speedXZ + 1.0f) < temp_f0) { + Math_Vec3f_Scale(&this->actor.velocity, this->actor.speedXZ / temp_f0); + this->actor.world.pos.x += this->actor.velocity.x; + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.z += this->actor.velocity.z; + this->unk_1E5 &= ~0x40; + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_809421E0.s") + this->actor.world.pos.x = sp2C.x; + this->actor.world.pos.y = sp2C.y; + this->actor.world.pos.z = sp2C.z; + this->unk_1E5 |= 0x40; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_8094220C.s") +s32 func_8093F5EC(EnGoroiwa* this) { + s32 pad; + Vec3s* sp18 = &this->unk_1D0[this->unk_1D8]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_809425CC.s") + if (this->actor.velocity.y < 0.0f) { + this->actor.velocity.y = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80942604.s") + Math_StepToF(&this->actor.velocity.y, D_80942DFC[this->unk_1E4] * 0.5f, 0.18f); + this->actor.world.pos.x = sp18->x; + this->actor.world.pos.z = sp18->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/EnGoroiwa_Update.s") + if (Math_StepToF(&this->actor.world.pos.y, sp18->y, fabsf(this->actor.velocity.y))) { + this->unk_1E5 |= 0x40; + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/func_80942B1C.s") + this->unk_1E5 &= ~0x40; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Goroiwa/EnGoroiwa_Draw.s") +s32 func_8093F6F8(EnGoroiwa* this, GlobalContext* globalCtx) { + f32 temp_f14; + Vec3s* sp80 = &this->unk_1D0[this->unk_1D8]; + f32 sp7C = sp80->y; + f32 sp78; + f32 temp_f2; + + Math_StepToF(&this->actor.velocity.y, -18.367346f, 1.0f); + this->actor.velocity.y *= 0.98f; + this->actor.world.pos.x = sp80->x; + this->actor.world.pos.z = sp80->z; + sp78 = this->actor.world.pos.y; + this->actor.world.pos.y += this->actor.velocity.y; + + if ((this->actor.velocity.y < 0.0f) && (this->actor.world.pos.y <= sp7C)) { + if (this->unk_1CA == 0) { + if (this->actor.xzDistToPlayer < 400.0f) { + s16 sp72 = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + Quake_SetSpeed(sp72, 0x4350); + Quake_SetQuakeValues(sp72, 3, 0, 0, 0); + Quake_SetCountdown(sp72, 7); + } + + this->unk_1C4 = 0.0f; + + if (!(this->unk_1E5 & 0x20)) { + CollisionPoly* poly; + Vec3f sp60; + s32 pad[2]; + s32 bgId; + Vec3f sp48; + + sp60.x = this->actor.world.pos.x; + sp60.y = this->actor.world.pos.y + 50.0f; + sp60.z = this->actor.world.pos.z; + + temp_f14 = + BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &poly, &bgId, &this->actor, &sp60); + temp_f2 = temp_f14 - this->actor.world.pos.y; + + if (fabsf(temp_f2) < (fabsf(this->actor.velocity.y) + 0.01f)) { + if (this->actor.flags & ACTOR_FLAG_40) { + sp48.x = this->actor.world.pos.x; + sp48.y = temp_f14 + 10.0f; + sp48.z = this->actor.world.pos.z; + + func_8093EF54(globalCtx, &sp48, &D_80942E30[ENGOROIWA_GET_C000(&this->actor)], + &D_80942E3C[ENGOROIWA_GET_C000(&this->actor)], this->actor.scale.x); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BIGBALL_BOUND); + } + } + } + + if (this->unk_1CA > 0) { + this->unk_1E5 |= 0x40; + return true; + } + + this->unk_1CA++; + this->actor.velocity.y *= -0.3f; + this->actor.world.pos.y = sp7C - ((this->actor.world.pos.y - sp7C) * 0.3f); + } + + if (this->unk_1CA == 0) { + WaterBox* sp44; + f32 sp40; + + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &sp40, &sp44)) { + if ((this->actor.world.pos.y + this->unk_1DC) <= sp40) { + this->unk_1E5 |= 0x20; + if (sp40 < (this->unk_1DC + sp78)) { + if (this->actor.flags & ACTOR_FLAG_40) { + Vec3f sp34; + + sp34.x = this->actor.world.pos.x; + sp34.y = sp40; + sp34.z = this->actor.world.pos.z; + func_8093F198(globalCtx, &sp34, this->actor.scale.x); + } + this->actor.velocity.y *= 0.2f; + } + + if (this->actor.velocity.y < -8.0f) { + this->actor.velocity.y = -8.0f; + } + } + } + } + + this->unk_1E5 &= ~0x40; + return false; +} + +void func_8093FAA4(EnGoroiwa* this, GlobalContext* globalCtx) { + f32 temp; + f32 tmp2; + f32 sp7C; + Vec3f sp70; + Vec3f sp64; + MtxF sp24; + + if (this->unk_1E5 & 0x10) { + sp7C = this->unk_1C0; + } else { + temp = Math3D_Distance(&this->actor.world.pos, &this->actor.prevPos); + tmp2 = temp / this->unk_1DC; + this->unk_1C0 = tmp2; + sp7C = this->unk_1C0; + } + + sp7C *= this->unk_1C4; + if (!(this->unk_1E5 & 0x10)) { + if (Math3D_LengthSquared(&this->actor.velocity) > 0.1f) { + Math_Vec3f_Copy(&this->unk_1A8, &this->actor.velocity); + } + } + + Math3D_CrossProduct(&D_80942E60, &this->unk_1A8, &sp70); + + if (func_8093EAD4(&sp64, &sp70)) { + this->unk_1B4 = sp64; + } else { + sp64 = this->unk_1B4; + } + + Matrix_RotateAxisF(sp7C, &sp64, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&sp24); + Matrix_MtxFToYXZRot(&sp24, &this->actor.shape.rot, false); +} + +void func_8093FC00(EnGoroiwa* this) { + s32 params = ENGOROIWA_GET_300(&this->actor); + + func_8093ED80(this); + if (((params == ENGOROIWA_300_0) || (params == ENGOROIWA_300_1)) && + ((this->unk_1D6 == 0) || (this->unk_1D6 == this->unk_1D4))) { + func_8093EE64(this, this->unk_1D6); + } +} + +void func_8093FC6C(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spC0; + Vec3f spB4; + Vec3f spA8; + s16 temp_s3; + s16 phi_s0; + s16 temp; + s32 pad; + s32 sp80; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + f32 temp_f28; + + temp_f24 = (this->actor.scale.x + 0.1f) * 0.5f; + sp80 = temp_f24 * 150.0f; + temp_f28 = this->actor.scale.x * 600.0f; + temp = 0x10000 / sp80; + + for (i = 0, phi_s0 = 0; i < sp80; i++, phi_s0 += temp) { + temp_s3 = (u32)Rand_Next() >> 0x10; + temp_f20 = Math_SinS(temp_s3); + temp_f22 = Math_CosS(temp_s3); + + spC0.x = Math_SinS(phi_s0); + spC0.z = Math_CosS(phi_s0); + + spB4.x = 2.0f * spC0.x; + spB4.y = (2.0f * Rand_ZeroOne()) + 1.0f; + spB4.z = 2.0f * spC0.z; + + spC0.x *= temp_f22 * temp_f28; + spC0.y = temp_f20 * temp_f28; + spC0.z *= (temp_f22 * temp_f28); + + spC0.x += this->actor.world.pos.x; + spC0.y += this->actor.world.pos.y; + spC0.z += this->actor.world.pos.z; + + spA8.x = spB4.x * -0.02f; + spA8.y = spB4.y * -0.05f; + spA8.z = spB4.z * -0.02f; + + EffectSsIceSmoke_Spawn(globalCtx, &spC0, &spB4, &spA8, + ((s32)(Rand_ZeroOne() * 170.0f) + 150) * temp_f24 * 10.0f); + } + + for (i = 0, phi_s0 = 0; i < sp80; i++, phi_s0 += temp) { + temp_f20 = (Rand_ZeroOne() * (450.0f * this->actor.scale.x)) + 50.0f; + + spC0.x = Math_SinS(phi_s0); + spC0.z = Math_CosS(phi_s0); + + spB4.x = spC0.x * 30.0f * temp_f24; + spB4.y = 0.0f; + spB4.z = spC0.z * 30.0f * temp_f24; + + spA8.x = spB4.x * -0.02f; + spA8.y = 0.03f; + spA8.z = spB4.z * -0.02f; + + spC0.x = (spC0.x * temp_f20) + this->actor.world.pos.x; + spC0.y = (Rand_ZeroOne() * 20.0f) + this->actor.world.pos.y; + spC0.z = (spC0.z * temp_f20) + this->actor.world.pos.z; + + EffectSsIceSmoke_Spawn(globalCtx, &spC0, &spB4, &spA8, (s32)(Rand_ZeroOne() * 1400.0f * temp_f24) + 100); + } +} + +void func_80940090(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + s32 i; + s32 sp120 = ENGOROIWA_GET_C000(&this->actor); + s32 phi_s0; + s32 phi_s3; + Vec3f sp10C; + Vec3f sp100; + Vec3f spF4; + s32 phi_s6; + f32 spEC; + Gfx* phi_s1; + s16 phi_s7; + f32 phi_f22; + s32 phi_s2; + s32 spD8; + s16 spA8; + f32 temp_f20; + s32 pad3; + + if (this->actor.flags & ACTOR_FLAG_40) { + spEC = (this->actor.scale.x + 0.1f) * 0.5f; + sp10C.x = this->actor.world.pos.x; + sp10C.y = this->actor.world.pos.y + this->unk_1DC; + sp10C.z = this->actor.world.pos.z; + if (1) {} + spD8 = spEC * 150.0f; + spA8 = 0x10000 / spD8; + + for (i = 0, phi_s7 = 0; i < spD8; i++, phi_s7 += spA8) { + if ((i & 3) == 0) { + phi_f22 = 1.0f; + phi_s1 = D_80942E0C[sp120][2]; + phi_s2 = -0x118; + phi_s3 = 0; + phi_s0 = 0x40; + } else { + phi_s2 = -0x190; + if ((i & 3) == 1) { + phi_s1 = D_80942E0C[sp120][1]; + phi_s2 = -0x154; + phi_s3 = 0; + phi_f22 = 0.9f; + if (Rand_ZeroOne() < 0.4f) { + phi_s0 = 0x20; + } else { + phi_s0 = 0x40; + } + } else { + phi_s1 = D_80942E0C[sp120][0]; + phi_s3 = 1; + phi_f22 = 0.8f; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } + } + + temp_f20 = (Rand_ZeroOne() * this->actor.scale.x * 400.0f) + 20.0f; + + sp100.x = Math_SinS((s32)(Rand_ZeroOne() * spA8) + phi_s7) * temp_f20; + sp100.y = (Rand_ZeroOne() - 0.4f) * temp_f20 * 1.6666666f; + sp100.z = Math_CosS((s32)(Rand_ZeroOne() * spA8) + phi_s7) * temp_f20; + + spF4.x = sp100.x * 0.16f * phi_f22; + spF4.y = (Rand_ZeroOne() * 16.0f) + 3.0f; + spF4.z = sp100.z * 0.16f * phi_f22; + + Math_Vec3f_Sum(&sp100, &sp10C, &sp100); + EffectSsKakera_Spawn(globalCtx, &sp100, &spF4, &sp100, phi_s2, phi_s0, 30, 0, 0, + ((Rand_ZeroOne() * 150.0f) + 300.0f) * this->actor.scale.x, phi_s3, 0, 0x32, -1, + OBJECT_GOROIWA, phi_s1); + if (this->unk_1E6 == 0) { + sp100.x += ((Rand_ZeroOne() * 1200.0f) - 600.0f) * this->actor.scale.x; + sp100.y += ((Rand_ZeroOne() * 1400.0f) - 600.0f) * this->actor.scale.y; + sp100.z += ((Rand_ZeroOne() * 1200.0f) - 600.0f) * this->actor.scale.z; + + func_800B0E48(globalCtx, &sp100, &D_80942E48, &D_80942E54, &D_80942E30[sp120], &D_80942E3C[sp120], + (Rand_ZeroOne() * 50.0f) + (400.0f * spEC), (Rand_ZeroOne() * 60.0f) + (500.0f * spEC)); + } + } + + if (this->unk_1E6 != 0) { + func_8093FC6C(this, globalCtx); + } + } +} + +void func_80940588(GlobalContext* globalCtx, Vec3f* arg1, Gfx* arg2[], Color_RGBA8* arg3, Color_RGBA8* arg4, f32 arg5) { + Gfx* phi_s7; + Vec3f sp100; + Vec3f spF4; + Vec3f spE8; + f32 temp_f20; + f32 spB0; + s32 j; + s32 i; + s32 phi_s0; + s32 spD0; + s16 spCE; + s16 spA8; + s16 phi_fp; + s16 spC8; + f32 spAC; + + spD0 = (s32)(arg5 * 35.0f) + 6; + temp_f20 = (arg5 + 0.1f) * 0.5f; + spB0 = 550.0f * temp_f20; + spAC = 500.0f * temp_f20; + spA8 = 0x10000 / spD0; + + for (i = 0, spCE = 0; i < spD0; i++, spCE += spA8) { + temp_f20 = (Rand_ZeroOne() * arg5 * 500.0f) + 20.0f; + + sp100.x = Math_SinS((s32)(Rand_ZeroOne() * spA8) + spCE) * temp_f20; + sp100.y = (Rand_ZeroOne() - 0.4f) * temp_f20 * 1.6666666f; + sp100.z = Math_CosS((s32)(Rand_ZeroOne() * spA8) + spCE) * temp_f20; + + spF4.x = sp100.x * 0.19f; + spF4.y = (Rand_ZeroOne() * 16.0f) + 3.0f; + spF4.z = sp100.z * 0.19f; + + Math_Vec3f_Sum(&sp100, arg1, &sp100); + + if ((i & 3) == 0) { + phi_s7 = arg2[0]; + phi_fp = -0x190; + spC8 = 1; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } else { + spC8 = 0; + if ((i & 3) == 1) { + phi_fp = -0x154; + phi_s7 = arg2[1]; + if (Rand_ZeroOne() < 0.4f) { + phi_s0 = 0x20; + } else { + phi_s0 = 0x40; + } + } else { + phi_fp = -0x118; + phi_s0 = 0x40; + phi_s7 = arg2[2]; + } + } + + EffectSsKakera_Spawn(globalCtx, &sp100, &spF4, &sp100, phi_fp, phi_s0, 30, 0, 0, + ((Rand_ZeroOne() * 100.0f) + 170.0f) * arg5, spC8, 0, 0x36, -1, OBJECT_GOROIWA, phi_s7); + + for (j = 0; j < 2; j++) { + spE8.x = (((Rand_ZeroOne() * 1000.0f) - 500.0f) * arg5) + sp100.x; + spE8.y = (((Rand_ZeroOne() * 1300.0f) - 500.0f) * arg5) + sp100.y; + spE8.z = (((Rand_ZeroOne() * 1000.0f) - 500.0f) * arg5) + sp100.z; + func_800B0E48(globalCtx, &spE8, &D_80942E48, &D_80942E54, arg3, arg4, (Rand_ZeroOne() * 80.0f) + spB0, + (Rand_ZeroOne() * 70.0f) + spAC); + } + } +} + +void func_80940A1C(GlobalContext* globalCtx, Vec3f* arg1, Gfx** arg2, Color_RGBA8* arg3, Color_RGBA8* arg4, f32 arg5) { + s32 i; + Vec3f spE8; + Vec3f spDC; + s32 phi_s2; + s32 phi_s0; + s32 phi_s3; + Gfx* phi_s1; + s32 spC8; + f32 temp_f20; + f32 spAC; + s16 spA8; + s16 phi_s6; + + spC8 = (s32)(arg5 * 35.0f) + 5; + temp_f20 = (arg5 + 0.1f) * 0.5f; + spAC = 600.0f * temp_f20; + spA8 = 0x10000 / spC8; + + for (i = 0, phi_s6 = 0; i < spC8; i++, phi_s6 += spA8) { + temp_f20 = (Rand_ZeroOne() * arg5 * 400.0f) + 20.0f; + + spE8.x = Math_SinS((s32)(Rand_ZeroOne() * spA8) + phi_s6) * temp_f20; + spE8.y = (Rand_ZeroOne() - 0.2f) * temp_f20 * 0.8f; + spE8.z = Math_CosS((s32)(Rand_ZeroOne() * spA8) + phi_s6) * temp_f20; + + spDC.x = spE8.x * 0.17f; + spDC.y = (Rand_ZeroOne() * 14.0f) + 3.0f; + spDC.z = spE8.z * 0.17f; + + Math_Vec3f_Sum(&spE8, arg1, &spE8); + + if ((i & 3) == 0) { + phi_s1 = arg2[2]; + phi_s2 = -0x118; + phi_s3 = 0; + phi_s0 = 0x40; + } else { + phi_s3 = 1; + if ((i & 3) == 1) { + phi_s1 = arg2[1]; + phi_s2 = -0x154; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } else { + phi_s1 = arg2[0]; + phi_s2 = -0x190; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } + } + + EffectSsKakera_Spawn(globalCtx, &spE8, &spDC, &spE8, phi_s2, phi_s0, 30, 0, 0, + ((Rand_ZeroOne() * 150.0f) + 250.0f) * arg5, phi_s3, 0, 0x36, -1, OBJECT_GOROIWA, phi_s1); + + spE8.x += ((Rand_ZeroOne() * 800.0f) - 400.0f) * arg5; + spE8.y += ((Rand_ZeroOne() * 800.0f) - 250.0f) * arg5; + spE8.z += ((Rand_ZeroOne() * 800.0f) - 400.0f) * arg5; + + func_800B0E48(globalCtx, &spE8, &D_80942E48, &D_80942E54, arg3, arg4, (Rand_ZeroOne() * 60.0f) + spAC, + (Rand_ZeroOne() * 30.0f) + spAC); + } +} + +void func_80940E38(EnGoroiwa* this, GlobalContext* globalCtx) { + f32 sp5C; + s32 pad; + f32 sp54; + Vec3f sp48; + s16 sp46; + s16 temp_a0; + + if (this->actor.flags & ACTOR_FLAG_40) { + if (this->actor.xzDistToPlayer < 1000.0f) { + sp5C = (1000.0f - this->actor.xzDistToPlayer) * 0.0012f * (this->actor.speedXZ * 0.1f); + if (Rand_ZeroOne() < sp5C) { + this->unk_1CE += 20000; + sp46 = (s32)Rand_ZeroFloat(20000.0f) + this->unk_1CE; + temp_a0 = sp46 - this->actor.world.rot.y; + if (ABS(temp_a0) < 0x4000) { + sp54 = Math_CosS(temp_a0) * 1.6f * this->unk_1DC; + } else { + sp54 = this->unk_1DC; + } + + sp48.x = (Math_SinS(sp46) * sp54) + this->actor.world.pos.x; + sp48.y = this->actor.world.pos.y + 20.0f; + sp48.z = (Math_CosS(sp46) * sp54) + this->actor.world.pos.z; + + func_800B0E48(globalCtx, &sp48, &D_80942E48, &D_80942E54, &D_80942E38, &D_80942E44, + (Rand_ZeroOne() * 600.0f) + (600.0f * (this->actor.scale.x + 0.1f) * 0.5f), + (s32)(Rand_ZeroOne() * 50.0f) + 30); + } + } + } +} + +void func_80941060(EnGoroiwa* this, GlobalContext* globalCtx) { + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + Vec3s* vec = &this->collider.elements[0].info.bumper.hitPos; + s32 i; + + for (i = 0; i < 4; i++) { + sp94.x = ((Rand_ZeroOne() * 14.0f) - 7.0f) + vec->x; + sp94.y = ((Rand_ZeroOne() * 14.0f) - 7.0f) + vec->y; + sp94.z = ((Rand_ZeroOne() * 14.0f) - 7.0f) + vec->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_80942E38, &D_80942E44, (s32)(Rand_ZeroOne() * 30.0f) + 15, + (s32)(Rand_ZeroOne() * 40.0f) + 30); + } +} + +void func_80941274(EnGoroiwa* this, GlobalContext* globalCtx) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EV_SNOWBALL_BROKEN); +} + +void EnGoroiwa_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGoroiwa* this = THIS; + f32 temp_f0; + s32 params = ENGOROIWA_GET_FF(&this->actor); + s32 sp28 = params * 8; + Path* sp2C = &globalCtx->setupPathList[params]; + + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.world.rot.x = 0; + this->actor.world.rot.z = 0; + this->actor.world.rot.y = Rand_Next() & 0xFFFF; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + func_8093E8A0(this); + func_8093E91C(this); + func_8093E9B0(this, globalCtx); + + if (sp28 == 0x7F8) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (sp2C->count < 2) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((this->actor.home.rot.y >= (sp2C->count - 1)) && (this->actor.home.rot.y < 0)) { + this->actor.home.rot.y = 0; + } + + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + ActorShape_Init(&this->actor.shape, 595.0f, ActorShadow_DrawCircle, 9.4f); + this->actor.shape.shadowAlpha = 200; + func_8093EB58(this, globalCtx); + + this->unk_1D0 = Lib_SegmentedToVirtual(sp2C->points); + + func_8093EE18(this, globalCtx); + func_8093EE64(this, this->actor.home.rot.y); + func_8093EEBC(this); + func_8093EC50(this); + + if (ENGOROIWA_GET_3000(&this->actor) == ENGOROIWA_3000_2) { + temp_f0 = func_8093EB74(this, globalCtx); + + if (temp_f0 < 0.1f) { + this->unk_1E0 = 0.0f; + } else { + this->unk_1E0 = (D_80942DFC[this->unk_1E4] * ((s32)globalCtx->state.framerateDivisor * 0.5f)) / temp_f0; + this->unk_1E0 *= 0.020000001f; + if (this->unk_1E0 > 0.00037f) { + this->unk_1E0 = 0.00037f; + } else if (this->unk_1E0 < 0.00015f) { + this->unk_1E0 = 0.00015f; + } + } + } + + Effect_Add(globalCtx, &this->unk_248, 4, 0, 0, &D_80942E8C); + func_809419D0(this); +} + +void EnGoroiwa_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGoroiwa* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); + Effect_Destroy(globalCtx, this->unk_248); +} + +s32 func_8094156C(EnGoroiwa* this, GlobalContext* globalCtx) { + Actor* actor = &this->actor; + s32 params = ENGOROIWA_GET_C000(&this->actor); + EnGoroiwaStruct* ptr; + s32 i; + s32 phi_s0_2 = false; + Vec3f sp80; + + if ((this->collider.base.acFlags & AC_HIT) && ((params == ENGOROIWA_C000_1) || (params == ENGOROIWA_C000_2))) { + if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x4000) { + s16 sp7E = BINANG_SUB(actor->yawTowardsPlayer, this->actor.world.rot.y); + f32 temp; + f32 temp2; + f32 temp3; + + this->unk_1CC = 50; + this->unk_1E8[0].unk_1E = BINANG_SUB(this->actor.yawTowardsPlayer, 0x4000); + this->unk_1E8[0].unk_24 = Rand_ZeroOne() * -600.0f; + this->unk_1E8[1].unk_1E = BINANG_ADD(this->actor.yawTowardsPlayer, 0x4000); + this->unk_1E8[1].unk_24 = Rand_ZeroOne() * 600.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_1E8); i++) { + ptr = &this->unk_1E8[i]; + + ptr->unk_00.x = this->actor.world.pos.x; + ptr->unk_00.y = this->actor.world.pos.y + this->unk_1DC; + ptr->unk_00.z = this->actor.world.pos.z; + + temp = Rand_ZeroOne(); + temp2 = Math_SinS(ptr->unk_1E); + temp3 = Math_SinS(this->actor.world.rot.y); + + ptr->unk_0C = ((1.0f / D_80942DFC[this->unk_1E4]) * (temp3 * 14.0f * this->actor.speedXZ)) + + (temp2 * (temp + 5.0f)); + + ptr->unk_10 = (Rand_ZeroOne() * 11.0f) + 20.0f; + + temp = Rand_ZeroOne(); + temp2 = Math_CosS(ptr->unk_1E); + temp3 = Math_CosS(this->actor.world.rot.y); + ptr->unk_14 = ((1.0f / D_80942DFC[this->unk_1E4]) * ((temp3 * 14.0f) * this->actor.speedXZ)) + + (temp2 * (temp + 5.0f)); + + ptr->unk_1C = 0; + ptr->unk_20 = 0; + ptr->unk_22 = (s32)(Rand_ZeroOne() * 400.0f) + 1100; + + temp3 = Rand_ZeroOne(); + temp2 = Math_CosS(sp7E); + ptr->unk_26 = (s32)(temp2 * 3000.0f) + (s32)(600.0f * (temp3 - 0.5f)); + ptr->unk_2D = 0; + ptr->unk_2C = 0; + } + + func_809421E0(this); + sp80.x = this->actor.world.pos.x; + sp80.y = this->actor.world.pos.y + this->unk_1DC; + sp80.z = this->actor.world.pos.z; + func_80940588(globalCtx, &sp80, D_80942E0C[params], &D_80942E30[params], &D_80942E3C[params], + this->actor.scale.x); + func_80941274(this, globalCtx); + phi_s0_2 = true; + } else if (((params == ENGOROIWA_C000_1) && + (this->collider.elements->info.acHitInfo->toucher.dmgFlags & (0x400 | 0x100))) || + ((params == ENGOROIWA_C000_2) && (this->collider.elements->info.acHitInfo->toucher.dmgFlags & + (0x80000000 | 0x800 | 0x400 | 0x100 | 0x8)))) { + this->unk_1CC = 50; + if ((params == ENGOROIWA_C000_2) && (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x800)) { + this->unk_1E6 = 1; + } + func_80940090(this, globalCtx); + func_80941274(this, globalCtx); + func_809425CC(this); + phi_s0_2 = true; + } else if ((params == ENGOROIWA_C000_2) && (this->unk_1E7 <= 0)) { + func_80941060(this, globalCtx); + this->unk_1E7 = 10; + } + } + + if (params == ENGOROIWA_C000_2) { + if (this->unk_1E7 > 0) { + this->unk_1E7--; + } + + if (phi_s0_2) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0x20); + } + } + return phi_s0_2; +} + +void func_809419D0(EnGoroiwa* this) { + this->actionFunc = func_80941A10; + func_8093EAB0(this, 7); + this->unk_1C4 = 1.0f; +} + +void func_80941A10(EnGoroiwa* this, GlobalContext* globalCtx) { + static EnGoroiwaUnkFunc D_80942E94[] = { + &func_8093F498, + &func_8093F34C, + }; + static u16 D_80942E9C[][2] = { + { NA_SE_EV_BIGBALL_ROLL - SFX_FLAG, NA_SE_EV_BIGBALL_ROLL_SR - SFX_FLAG }, + { NA_SE_EV_BIGBALL_ROLL_2 - SFX_FLAG, NA_SE_EV_BIGBALL_ROLL_SR_2 - SFX_FLAG }, + { NA_SE_EV_BIGBALL_ROLL_3 - SFX_FLAG, NA_SE_EV_BIGBALL_ROLL_SR_3 - SFX_FLAG }, + { NA_SE_EV_BIGBALL_ROLL - SFX_FLAG, NA_SE_EV_BIGBALL_ROLL_SR - SFX_FLAG }, + }; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + s32 sp44 = ENGOROIWA_GET_400(&this->actor); + s32 sp40 = ENGOROIWA_GET_3000(&this->actor); + s16 y; + s32 pad2; + + if (!func_8094156C(this, globalCtx)) { + if ((this->collider.base.atFlags & AT_HIT) && !(player->stateFlags3 & 0x80000)) { + s32 sp34 = this->actor.home.rot.z & 3; + + if (sp34 == 2) { + func_80940090(this, globalCtx); + if (sp40 == ENGOROIWA_3000_2) { + func_8093E8A0(this); + func_8093E91C(this); + } + func_80941274(this, globalCtx); + func_8093EDD8(this, globalCtx); + func_8093EE64(this, 0); + func_8093EEBC(this); + } else { + this->unk_1E5 &= ~8; + y = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + if ((y > -0x4000) && (y < 0x4000)) { + this->unk_1E5 |= 8; + if (sp44 || (sp34 != 1)) { + func_8093EDB0(this); + } + } + } + + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0); + + if (sp34 == 2) { + func_80941EB4(this); + } else if (!sp44) { + func_80941EB4(this); + } else { + func_80941DB4(this); + } + + func_800B8E58(player, NA_SE_PL_BODY_HIT); + + if ((sp34 == 1) || (sp34 == 2)) { + this->unk_1CC = 50; + } + } else { + if (D_80942E94[sp44](this)) { + s32 sp30 = ENGOROIWA_GET_300(&this->actor); + + if ((sp30 == ENGOROIWA_300_1) && ((this->unk_1D8 == 0) || (this->unk_1D8 == this->unk_1D4))) { + func_80940090(this, globalCtx); + func_80941274(this, globalCtx); + } + + if (((sp30 == ENGOROIWA_300_1) || (sp30 == ENGOROIWA_300_0)) && (sp40 == ENGOROIWA_3000_2) && + ((this->unk_1D8 == 0) || (this->unk_1D8 == this->unk_1D4))) { + func_8093E8A0(this); + func_8093E91C(this); + } + + func_8093FC00(this); + + if ((sp30 == ENGOROIWA_300_3) && ((this->unk_1D6 == 0) || (this->unk_1D6 == this->unk_1D4))) { + func_80941EB4(this); + } else if (!sp44 && (this->unk_1D6 != 0) && (this->unk_1D6 != this->unk_1D4)) { + sp30 = func_8093EEDC(this); + if (sp30 > 0) { + func_80941F54(this); + } else if (sp30 < 0) { + func_80942084(this); + } else { + func_809419D0(this); + } + } else { + func_809419D0(this); + } + } + } + + if (this->actor.bgCheckFlags & 1) { + Actor_PlaySfxAtPos(&this->actor, D_80942E9C[this->unk_1E4][this->actor.home.rot.x & 1]); + } + } +} + +void func_80941DB4(EnGoroiwa* this) { + this->actionFunc = func_80941E28; + func_8093EAB0(this, 6); + this->actor.gravity = -0.86f; + this->actor.terminalVelocity = -15.0f; + this->actor.speedXZ *= 0.15f; + this->actor.velocity.y = 5.0f; + this->unk_1C4 = 1.0f; +} + +void func_80941E28(EnGoroiwa* this, GlobalContext* globalCtx) { + func_8093F34C(this); + if ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f)) { + if ((this->unk_1E5 & 8) && ((this->actor.home.rot.z & 3) == 1)) { + func_8093EDB0(this); + } + func_80941EB4(this); + } +} + +void func_80941EB4(EnGoroiwa* this) { + static s16 D_80942EAC[] = { 20, 6, 20 }; + + this->actionFunc = func_80941F10; + this->actor.speedXZ = 0.0f; + func_8093EAB0(this, 6); + this->unk_1C8 = D_80942EAC[this->actor.home.rot.z & 3]; + this->unk_1C4 = 0.0f; +} + +void func_80941F10(EnGoroiwa* this, GlobalContext* globalCtx) { + if (!func_8094156C(this, globalCtx)) { + if (this->unk_1C8 > 0) { + this->unk_1C8--; + } else { + func_809419D0(this); + } + } +} + +void func_80941F54(EnGoroiwa* this) { + this->actionFunc = func_80941FA4; + func_8093EAB0(this, 7); + this->unk_1C4 = 0.0f; + this->actor.velocity.y = fabsf(this->actor.speedXZ) * 0.1f; +} + +void func_80941FA4(EnGoroiwa* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_8094156C(this, globalCtx) == 0) { + if ((this->collider.base.atFlags & AT_HIT) && !(player->stateFlags3 & 0x80000)) { + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0); + func_800B8E58(player, NA_SE_PL_BODY_HIT); + if (((this->actor.home.rot.z & 3) == 1) || ((this->actor.home.rot.z & 3) == 2)) { + this->unk_1CC = 50; + } + } else if (func_8093F5EC(this)) { + func_8093FC00(this); + func_809419D0(this); + this->actor.speedXZ = 0.0f; + } + } +} + +void func_80942084(EnGoroiwa* this) { + this->actionFunc = func_809420F0; + func_8093EAB0(this, 7); + this->unk_1C4 = 0.3f; + this->unk_1CA = 0; + this->actor.velocity.y = fabsf(this->actor.speedXZ) * -0.3f; + this->unk_1E5 |= 0x10; + this->unk_1E5 &= ~0x20; +} + +void func_809420F0(EnGoroiwa* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_8094156C(this, globalCtx) == 0) { + if ((this->collider.base.atFlags & AT_HIT) && !(player->stateFlags3 & 0x80000)) { + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0); + func_800B8E58(player, NA_SE_PL_BODY_HIT); + if (((this->actor.home.rot.z & 3) == 1) || ((this->actor.home.rot.z & 3) == 2)) { + this->unk_1CC = 50; + } + } else if (func_8093F6F8(this, globalCtx)) { + func_8093FC00(this); + func_809419D0(this); + this->unk_1E5 &= ~0x10; + this->actor.speedXZ = 0.0f; + } + } +} + +void func_809421E0(EnGoroiwa* this) { + this->actionFunc = func_8094220C; + func_8093EAB0(this, 0); +} + +void func_8094220C(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 pad; + EnGoroiwaStruct* ptr; + s32 i; + s32 spD0; + Vec3f spC4; + Vec3f spB8; + f32 phi_f12; + f32 temp_f20; + f32 spAC; + s32 params; + Vec3f sp9C; + s16 sp9A; + + for (i = 0; i < ARRAY_COUNT(this->unk_1E8); i++) { + ptr = &this->unk_1E8[i]; + + if (!(ptr->unk_2D & 1)) { + ptr->unk_10 -= 6.0f; + 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 += ptr->unk_22; + ptr->unk_1E += ptr->unk_24; + ptr->unk_20 += ptr->unk_26; + + spC4.x = ptr->unk_00.x; + spC4.y = ptr->unk_00.y + 25.0f; + spC4.z = ptr->unk_00.z; + + ptr->unk_18 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &ptr->unk_28, &spD0, &this->actor, &spC4); + + if (ptr->unk_10 <= 0.0f) { + Matrix_RotateZYX(ptr->unk_1C, ptr->unk_1E, ptr->unk_20, MTXMODE_NEW); + Matrix_MultVec3f(&D_80942E6C, &spB8); + temp_f20 = this->unk_1DC * 0.9f; + + if (spB8.y > 0.0f) { + if (Math3D_AngleBetweenVectors(&D_80942E60, &spB8, &spAC)) { + phi_f12 = 1.0f; + } else { + phi_f12 = 1.0f - SQ(spAC); + } + + if (phi_f12 <= 0.0f) { + temp_f20 = 0.0f; + } else { + temp_f20 *= sqrtf(phi_f12); + } + } + + if (((ptr->unk_00.y + (this->unk_1DC - temp_f20)) < ptr->unk_18) || + (ptr->unk_18 < (BGCHECK_Y_MIN + 10))) { + params = ENGOROIWA_GET_C000(&this->actor); + ptr->unk_2D |= 1; + sp9C.x = ptr->unk_00.x; + sp9C.y = (ptr->unk_00.y - ptr->unk_10) + 10.0f; + sp9C.z = ptr->unk_00.z; + func_80940A1C(globalCtx, &sp9C, D_80942E0C[params], &D_80942E30[params], &D_80942E3C[params], + this->actor.scale.x); + } + } + } + } + + if ((this->unk_1E8[0].unk_2D & 1) && (this->unk_1E8[1].unk_2D & 1)) { + func_809425CC(this); + return; + } + + sp9A = this->actor.shape.shadowAlpha; + Math_StepToS(&sp9A, 0, 40); + this->actor.shape.shadowAlpha = sp9A; + + for (i = 0; i < ARRAY_COUNT(this->unk_1E8); i++) { + ptr = &this->unk_1E8[i]; + + if (ptr->unk_2D & 1) { + ptr->unk_2C = 0; + } else { + sp9A = ptr->unk_2C; + Math_StepToS(&sp9A, 160, 24); + ptr->unk_2C = sp9A; + } + } +} + +void func_809425CC(EnGoroiwa* this) { + this->actionFunc = func_80942604; + func_8093EAB0(this, 0); + this->unk_1C8 = 100; +} + +void func_80942604(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp22 = this->actor.shape.shadowAlpha; + + Math_StepToS(&sp22, 0, 40); + this->actor.shape.shadowAlpha = sp22; + if (this->unk_1C8 > 0) { + this->unk_1C8--; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGoroiwa* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 bgId; + s32 sp5C = false; + Vec3f sp50; + f32 sp4C; + s32 sp48 = true; + u32 temp_v0_2; + CollisionPoly* tmp; + + if (!(player->stateFlags1 & (0x30000000 | 0x80 | 0x40))) { + if (this->unk_1CC > 0) { + this->unk_1CC--; + } + + if ((ENGOROIWA_GET_3000(&this->actor) == ENGOROIWA_3000_2) && (this->actor.bgCheckFlags & 1) && + (this->actionFunc == func_80941A10) && (this->actor.speedXZ > 2.0f)) { + Math_StepToF(&this->actor.scale.x, 0.16f, + (this->actor.xzDistToPlayer < 400.0f) ? this->unk_1E0 * 1.4f : this->unk_1E0); + + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + func_8093E91C(this); + sp5C = true; + + if (this->actor.flags & ACTOR_FLAG_40) { + tmp = this->actor.floorPoly; + if (tmp != NULL) { + temp_v0_2 = func_800C99D4(&globalCtx->colCtx, tmp, this->actor.floorBgId); + + if ((temp_v0_2 == 14) || (temp_v0_2 == 15)) { + if (!(this->unk_1E5 & 0x40)) { + sp50.x = this->actor.world.pos.x; + 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_GetByIndex(this->unk_248), &sp50, sp4C, + this->actor.world.rot.y, this->actor.floorPoly, this->actor.floorBgId); + } + sp48 = false; + } + } + } + } + + if (sp48) { + func_800AEF44(Effect_GetByIndex(this->unk_248)); + } + + this->actionFunc(this, globalCtx); + + if (this->actor.update != NULL) { + func_8093EC50(this); + + if (sp5C) { + func_80940E38(this, globalCtx); + } + + switch (ENGOROIWA_GET_400(&this->actor)) { + case ENGOROIWA_400_1: + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 0x1C); + break; + + case ENGOROIWA_400_0: + sp50.x = this->actor.world.pos.x; + sp50.y = this->actor.world.pos.y + 50.0f; + sp50.z = this->actor.world.pos.z; + this->actor.floorHeight = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, + &bgId, &this->actor, &sp50); + if (this->actor.floorHeight > BGCHECK_Y_MIN) { + this->actor.floorBgId = bgId; + if (this->actor.world.pos.y <= (this->actor.floorHeight + 2.0f)) { + this->actor.bgCheckFlags |= 1; + } else { + this->actor.bgCheckFlags &= ~1; + } + } else { + this->actor.bgCheckFlags &= ~1; + this->actor.floorBgId = 50; + } + break; + } + + func_8093FAA4(this, globalCtx); + + if (this->actor.flags & ACTOR_FLAG_40) { + s32 params = ENGOROIWA_GET_C000(&this->actor); + + func_8093E938(this); + + if ((this->unk_1E5 & 1) && (this->unk_1CC <= 0) && + (!(player->stateFlags3 & 0x2000000) || (player->transformation != PLAYER_FORM_GORON) || + ((params != ENGOROIWA_C000_1) && (params != ENGOROIWA_C000_2)))) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.atFlags &= ~AT_HIT; + } + + if (this->unk_1E5 & 2) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.acFlags &= ~AC_HIT; + } + + if ((this->unk_1E5 & 4) && (this->unk_1CC <= 0)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.ocFlags1 &= ~OC1_HIT; + } + } else { + this->collider.base.atFlags &= ~AT_HIT; + this->collider.base.ocFlags1 &= ~OC1_HIT; + this->collider.base.acFlags &= ~AC_HIT; + } + } + } +} + +void func_80942B1C(EnGoroiwa* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + s32 i; + EnGoroiwaStruct* ptr; + s32 params = ENGOROIWA_GET_C000(&this->actor); + Gfx* phi_fp; + MtxF sp88; + Vec3s sp80; + + if (params == ENGOROIWA_C000_1) { + phi_fp = object_goroiwa_DL_0032E0; + } else { + phi_fp = object_goroiwa_DL_0082D0; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_1E8); i++) { + ptr = &this->unk_1E8[i]; + + if (!(ptr->unk_2D & 1)) { + sp80.x = ptr->unk_1C; + sp80.y = ptr->unk_1E; + sp80.z = ptr->unk_20; + + Matrix_SetTranslateRotateYXZ(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); + Gfx_DrawDListOpa(globalCtx, phi_fp); + + if ((ptr->unk_28 != 0) && (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_Put(&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++, gCircleShadowDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } + } +} + +void EnGoroiwa_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* D_80942EB4[] = { + object_goroiwa_DL_005C20, + object_goroiwa_DL_003B40, + object_goroiwa_DL_008B90, + }; + EnGoroiwa* this = THIS; + s32 params = ENGOROIWA_GET_C000(&this->actor); + + if (this->actionFunc == func_8094220C) { + func_80942B1C(this, globalCtx); + } else if (this->actionFunc != func_80942604) { + Gfx_DrawDListOpa(globalCtx, D_80942EB4[params]); + } +} diff --git a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h index dfa60adf1..2a3ae2505 100644 --- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h +++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.h @@ -6,12 +6,79 @@ struct EnGoroiwa; typedef void (*EnGoroiwaActionFunc)(struct EnGoroiwa*, GlobalContext*); +typedef s32 (*EnGoroiwaUnkFunc)(struct EnGoroiwa*); + +#define ENGOROIWA_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) +#define ENGOROIWA_GET_3000(thisx) (((thisx)->params >> 0xC) & 3) +#define ENGOROIWA_GET_400(thisx) (((thisx)->params >> 0xA) & 1) +#define ENGOROIWA_GET_300(thisx) (((thisx)->params >> 0x8) & 3) +#define ENGOROIWA_GET_FF(thisx) ((thisx)->params & 0xFF) + +enum { + /* 0 */ ENGOROIWA_300_0, + /* 1 */ ENGOROIWA_300_1, + /* 3 */ ENGOROIWA_300_3 = 3, +}; + +enum { + /* 0 */ ENGOROIWA_400_0, + /* 1 */ ENGOROIWA_400_1, +}; + +enum { + /* 0 */ ENGOROIWA_3000_0, + /* 1 */ ENGOROIWA_3000_1, + /* 2 */ ENGOROIWA_3000_2, +}; + +enum { + /* 1 */ ENGOROIWA_C000_1 = 1, + /* 2 */ ENGOROIWA_C000_2, +}; + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ s16 unk_1C; + /* 0x1E */ s16 unk_1E; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; + /* 0x24 */ s16 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ CollisionPoly* unk_28; + /* 0x2C */ u8 unk_2C; + /* 0x2D */ u8 unk_2D; +} EnGoroiwaStruct; // size = 0x30 typedef struct EnGoroiwa { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x60]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colliderElements[1]; /* 0x01A4 */ EnGoroiwaActionFunc actionFunc; - /* 0x01A8 */ char unk_1A8[0xA4]; + /* 0x01A8 */ Vec3f unk_1A8; + /* 0x01B4 */ Vec3f unk_1B4; + /* 0x01C0 */ f32 unk_1C0; + /* 0x01C4 */ f32 unk_1C4; + /* 0x01C8 */ s16 unk_1C8; + /* 0x01CA */ s16 unk_1CA; + /* 0x01CC */ s16 unk_1CC; + /* 0x01CE */ s16 unk_1CE; + /* 0x01D0 */ Vec3s* unk_1D0; + /* 0x01D4 */ s16 unk_1D4; + /* 0x01D6 */ s16 unk_1D6; + /* 0x01D8 */ s16 unk_1D8; + /* 0x01DA */ s16 unk_1DA; + /* 0x01DC */ f32 unk_1DC; + /* 0x01E0 */ f32 unk_1E0; + /* 0x01E4 */ s8 unk_1E4; + /* 0x01E5 */ u8 unk_1E5; + /* 0x01E6 */ s8 unk_1E6; + /* 0x01E7 */ s8 unk_1E7; + /* 0x01E8 */ EnGoroiwaStruct unk_1E8[2]; + /* 0x0248 */ s32 unk_248; } EnGoroiwa; // size = 0x24C extern const ActorInit En_Goroiwa_InitVars; diff --git a/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.c b/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.c index f04e9c2b8..e19d2fa37 100644 --- a/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.c +++ b/src/overlays/actors/ovl_En_Grasshopper/z_en_grasshopper.c @@ -1,6 +1,12 @@ +/* + * File: z_en_grasshopper.c + * Overlay: ovl_En_Grasshopper + * Description: Dragonfly + */ + #include "z_en_grasshopper.h" -#define FLAGS 0x00000015 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnGrasshopper*)thisx) 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 cb95479b4..a97de7b80 100644 --- a/src/overlays/actors/ovl_En_Gs/z_en_gs.c +++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.c @@ -1,6 +1,14 @@ -#include "z_en_gs.h" +/* + * File: z_en_gs.c + * Overlay: ovl_En_Gs + * Description: Gossip stone + */ -#define FLAGS 0x02000019 +#include "z_en_gs.h" +#include "objects/object_gs/object_gs.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnGs*)thisx) @@ -9,7 +17,26 @@ 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); + const ActorInit En_Gs_InitVars = { ACTOR_EN_GS, ACTORCAT_PROP, @@ -22,18 +49,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), @@ -68,78 +106,1002 @@ 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.save.unk_EC4 >> (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], &gOneVec3f); + Math_Vec3f_Copy(&this->unk_1B0[1], &gOneVec3f); + SubS_FillCutscenesList(&this->actor, this->unk_212, ARRAY_COUNT(this->unk_212)); + 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 (Message_GetState(&globalCtx->msgCtx) == 0) { + if (this->actor.xzDistToPlayer <= D_8099A408[this->actor.params]) { + func_8013E8F8(&this->actor, globalCtx, D_8099A408[this->actor.params], D_8099A408[this->actor.params], + EXCH_ITEM_NONE, 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 (Message_GetState(&globalCtx->msgCtx)) { + case 0: + Message_StartTextbox(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 (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + 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 (SubS_StartActorCutscene(&this->actor, globalCtx->playerActorCsIds[0], -1, SUBS_CUTSCENE_NORMAL)) { + 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.ocarinaMode) { + 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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Flags_SetSwitch(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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Flags_SetSwitch(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.save.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.save.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.save.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->playerActorCsIds[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 (SubS_StartActorCutscene(&this->actor, this->unk_212[0], -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + Player* player = GET_PLAYER(globalCtx); + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(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.save.unk_EC4 = ((u32)gSaveContext.save.unk_EC4 & ~(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); + Actor_PlaySfxAtPos(&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[0]); + phi_v0 = 1; + + for (i = 0; i < 4; i++) { + if (((gSaveContext.save.unk_EC4 >> (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.save.weekEventReg[77] & 8)) { + this->unk_20C = 6; + gSaveContext.save.weekEventReg[77] |= 8; + } + break; + + case 3: + if (!(gSaveContext.save.weekEventReg[77] & 0x10)) { + this->unk_20C = 6; + gSaveContext.save.weekEventReg[77] |= 0x10; + } + break; + + case 2: + if (!(gSaveContext.save.weekEventReg[77] & 0x20)) { + this->unk_20C = 6; + gSaveContext.save.weekEventReg[77] |= 0x20; + } + break; + } + + if (!(gSaveContext.save.weekEventReg[90] & 0x10)) { + gSaveContext.save.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) { + Actor_PickUp(&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 { + Actor_PickUp(&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; + Actor_PlaySfxAtPos(&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) && !Play_InCsMode(globalCtx) && + (Message_GetState(&globalCtx->msgCtx) == 0)) { + this->unk_216 = 0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FAIVE_LUPY_COUNT); + Message_StartTextbox(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; + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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_SetFocus(&this->actor, 34.5f); + } else { + Actor_SetFocus(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.msgMode = 0; + globalCtx->msgCtx.unk11F10 = 0; + this->collider.base.acFlags &= ~AC_HIT; + func_80997DEC(this, globalCtx); + } else if (func_800B8718(&this->actor, &globalCtx->state)) { + 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 & ACTOR_FLAG_40) || (this->unk_19A & 0x100) || (this->unk_19A & 0x200)) { + func_80999BC8(&this->actor, globalCtx); + Actor_GetScreenPos(globalCtx, &this->actor, &sp2E, &sp2C); + if ((this->actor.xyzDistToPlayerSq > SQ(400.0f)) || (sp2E < 0) || (sp2E > SCREEN_WIDTH) || (sp2C < 0) || + (sp2C > SCREEN_HEIGHT)) { + 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_Push(); + + if (this->unk_19A & 1) { + Matrix_RotateYS(this->unk_19E[0].y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_19E[0].x, MTXMODE_APPLY); + Matrix_RotateZS(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_RotateYS(this->unk_19E[1].y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_19E[1].x, MTXMODE_APPLY); + Matrix_RotateZS(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++, object_gs_DL_000950); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1FA.r, this->unk_1FA.g, this->unk_1FA.b, 255); + gSPDisplayList(POLY_OPA_DISP++, object_gs_DL_0009D0); + gSPDisplayList(POLY_OPA_DISP++, object_gs_DL_000A60); + + Matrix_Pop(); + + if (this->unk_19A & 2) { + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_ReplaceRotation(&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..c76a0c346 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,56 @@ 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[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_Guard_Nuts/z_en_guard_nuts.c b/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.c index 6bf970c34..1394efff7 100644 --- a/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.c +++ b/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.c @@ -1,6 +1,12 @@ +/* + * File: z_en_guard_nuts.c + * Overlay: ovl_En_Guard_Nuts + * Description: Deku Palace - Entrance Guard + */ + #include "z_en_guard_nuts.h" -#define FLAGS 0x80100009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_100000 | ACTOR_FLAG_80000000) #define THIS ((EnGuardNuts*)thisx) @@ -9,7 +15,15 @@ void EnGuardNuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGuardNuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnGuardNuts_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnGuardNuts_ChangeAnim(EnGuardNuts* this, s32 index); +void EnGuardNuts_SetupWait(EnGuardNuts* this); +void EnGuardNuts_Wait(EnGuardNuts* this, GlobalContext* globalCtx); +void func_80ABB540(EnGuardNuts* this); +void func_80ABB590(EnGuardNuts* this, GlobalContext* globalCtx); +void EnGuardNuts_Burrow(EnGuardNuts* this, GlobalContext* globalCtx); +void EnGuardNuts_SetupUnburrow(EnGuardNuts* this, GlobalContext* globalCtx); +void EnGuardNuts_Unburrow(EnGuardNuts* this, GlobalContext* globalCtx); + const ActorInit En_Guard_Nuts_InitVars = { ACTOR_EN_GUARD_NUTS, ACTORCAT_NPC, @@ -22,42 +36,350 @@ const ActorInit En_Guard_Nuts_InitVars = { (ActorFunc)EnGuardNuts_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80ABBDF0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON | OCELEM_UNK3, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON | OCELEM_UNK3, + }, { 50, 50, 0, { 0, 0, 0 } }, }; -#endif +s32 sGuardCount = 0; -extern ColliderCylinderInit D_80ABBDF0; +s32 D_80ABBE20 = 0; -extern UNK_TYPE D_06002700; -extern UNK_TYPE D_06002A08; +static u16 sTextIDs[] = { 0x0824, 0x0825, 0x0826, 0x082D, 0x0827, 0x0828, 0x0829, 0x082A, 0x082B, 0x082C }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/EnGuardNuts_Init.s") +s16 D_80ABBE38[] = { 0x0000, 0x0000, 0x0002, 0x0001, 0x0000, 0x0000, 0x0002, 0x0000, 0x0000, 0x0002 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/EnGuardNuts_Destroy.s") +static AnimationHeader* sAnimations[] = { + &gDekuPalaceGuardWaitAnim, + &gDekuPalaceGuardWalkAnim, + &gDekuPalaceGuardDigAnim, + &gDekuPalaceGuardWalkAnim, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB210.s") +static u8 sAnimModes[] = { ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB29C.s") +static TexturePtr sEyeTextures[] = { + gDekuPalaceGuardEyeOpenTex, + gDekuPalaceGuardEyeHalfTex, + gDekuPalaceGuardEyeClosedTex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB2D4.s") +typedef enum { + /* 0 */ WAIT_HEAD_TILT_ANIM, + /* 1 */ WALK_ANIM, + /* 2 */ DIG_ANIM, + /* 3 */ WALK_ANIM_2, +} EnGuardNutsAnim; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB540.s") +typedef enum { + /* 0 */ GUARD_NUTS_WAIT_STATE, + /* 1 */ GUARD_NUTS_TALKING_STATE, + /* 3 */ GUARD_NUTS_BURROWED_STATE = 3, + /* 4 */ GUARD_NUTS_UNK_STATE +} EnGuardNutsState; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB590.s") +void EnGuardNuts_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGuardNuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB854.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuPalaceGuardSkel, &gDekuPalaceGuardWaitAnim, this->jointTable, + this->morphTable, DEKU_PALACE_GUARD_LIMB_MAX); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 1; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Actor_SetScale(&this->actor, 0.015f); + Math_Vec3f_Copy(&this->guardPos, &this->actor.world.pos); + this->guardNumber = sGuardCount; + sGuardCount++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB91C.s") + // If you have returned deku princess guards will init burrowed. + if (!(gSaveContext.save.weekEventReg[23] & 0x20)) { + EnGuardNuts_SetupWait(this); + } else { + EnGuardNuts_Burrow(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABB990.s") +void EnGuardNuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGuardNuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/EnGuardNuts_Update.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/func_80ABBC60.s") +/** + * @brief Changes the animation to the provided index. Updates animIndex and animFrameCount for the animation. + * + * @param this + * @param index the index of sAnimations to change to + */ +void EnGuardNuts_ChangeAnim(EnGuardNuts* this, s32 index) { + this->animIndex = index; + this->animFrameCount = Animation_GetLastFrame(sAnimations[this->animIndex]); + Animation_Change(&this->skelAnime, sAnimations[this->animIndex], 1.0f, 0.0f, this->animFrameCount, + sAnimModes[this->animIndex], -2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Guard_Nuts/EnGuardNuts_Draw.s") +void EnGuardNuts_SetupWait(EnGuardNuts* this) { + EnGuardNuts_ChangeAnim(this, WAIT_HEAD_TILT_ANIM); + this->state = GUARD_NUTS_WAIT_STATE; + this->actionFunc = EnGuardNuts_Wait; +} + +void EnGuardNuts_Wait(EnGuardNuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 phi_a1; + s16 yawDiff; + + SkelAnime_Update(&this->skelAnime); + yawDiff = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.home.rot.y)); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80ABB540(this); + return; + } + if (yawDiff > 0x6000) { + D_80ABBE20 = 2; + } + if (player->transformation == PLAYER_FORM_DEKU) { + // this is the palace of... + this->guardTextIndex = 0; + if ((gSaveContext.save.weekEventReg[17] & 4) && (!this->hasCompletedConversation)) { + // I told you not to enter!! + this->guardTextIndex = 7; + } else if (gSaveContext.save.weekEventReg[12] & 0x40) { + // come to see the monkey again? + this->guardTextIndex = 4; + } + } else { + // No place for an outsider + this->guardTextIndex = 3; + } + this->actor.textId = sTextIDs[this->guardTextIndex]; + phi_a1 = this->actor.world.rot.y; + if (D_80ABBE20 == 2) { + EnGuardNuts_Burrow(this, globalCtx); + return; + } + if (D_80ABBE20 == 1) { + if (this->animIndex != WALK_ANIM) { + EnGuardNuts_ChangeAnim(this, WALK_ANIM); + } + phi_a1 = (this->actor.home.rot.y + 0x8000); + } + if (fabsf((f32)(this->actor.shape.rot.y - phi_a1)) < 100.0f) { + this->actor.shape.rot.y = phi_a1; + if ((D_80ABBE20 == 1) && (this->animIndex != WALK_ANIM_2)) { + EnGuardNuts_ChangeAnim(this, WALK_ANIM_2); + } + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, phi_a1, 1, 0xBB8, 0); + } + if (this->targetHeadPos.x == 0) { + if (fabsf((f32)this->actor.world.rot.y - (f32)this->actor.yawTowardsPlayer) < 10000.0f) { + this->targetHeadPos.y = this->actor.world.rot.y - this->actor.yawTowardsPlayer; + this->targetHeadPos.y = -this->targetHeadPos.y; + } + } + func_800B8614(&this->actor, globalCtx, 70.0f); +} + +void func_80ABB540(EnGuardNuts* this) { + EnGuardNuts_ChangeAnim(this, WALK_ANIM); + this->targetHeadPos.x = this->targetHeadPos.y = 0; + this->timer = 16; + this->state = GUARD_NUTS_TALKING_STATE; + this->actionFunc = func_80ABB590; +} + +void func_80ABB590(EnGuardNuts* this, GlobalContext* globalCtx) { + s16 yaw = this->actor.yawTowardsPlayer; + f32 curFrame; + + if (D_80ABBE20 == 1) { + yaw = (this->actor.home.rot.y + 0x8000); + } + if (fabsf((this->actor.shape.rot.y - yaw)) < 100.0f) { + this->actor.shape.rot.y = yaw; + curFrame = this->skelAnime.curFrame; + if ((curFrame < this->animFrameCount) || (this->guardTextIndex >= 7)) { + SkelAnime_Update(&this->skelAnime); + } + } else { + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.shape.rot.y, yaw, 1, 0xBB8, 0); + } + if (Message_GetState(&globalCtx->msgCtx) == 5) { + this->targetHeadPos.y = 0; + this->targetHeadPos.x = 0; + if ((this->guardTextIndex == 3) && (this->animIndex == WAIT_HEAD_TILT_ANIM)) { + EnGuardNuts_ChangeAnim(this, WAIT_HEAD_TILT_ANIM); + } + if (Message_ShouldAdvance(globalCtx)) { + if (D_80ABBE38[this->guardTextIndex] != 1) { + if (D_80ABBE38[this->guardTextIndex] == 2) { + func_801477B4(globalCtx); + D_80ABBE20 = 2; + gSaveContext.save.weekEventReg[12] |= 0x40; + EnGuardNuts_Burrow(this, globalCtx); + } else { + this->guardTextIndex++; + Message_StartTextbox(globalCtx, sTextIDs[this->guardTextIndex], &this->actor); + if (D_80ABBE38[this->guardTextIndex] == 2) { + D_80ABBE20 = 1; + } + this->timer = 16; + } + } else if (this->guardTextIndex != 3) { + this->targetHeadPos.x = 0; + this->targetHeadPos.y = this->targetHeadPos.x; + func_801477B4(globalCtx); + this->state = GUARD_NUTS_UNK_STATE; + this->actionFunc = EnGuardNuts_Unburrow; + } else { + func_801477B4(globalCtx); + EnGuardNuts_SetupWait(this); + } + } + } else if ((Message_GetState(&globalCtx->msgCtx) >= 3) && (D_80ABBE20 == 0)) { + if ((this->guardTextIndex == 0) || (this->guardTextIndex == 3) || (this->guardTextIndex >= 7)) { + if (this->timer == 0) { + this->timer = 2; + this->targetHeadPos.y ^= 0x2000; + } + } else if (this->timer == 0) { + this->timer = 2; + this->targetHeadPos.x ^= 0x2000; + } + } +} + +void EnGuardNuts_Burrow(EnGuardNuts* this, GlobalContext* globalCtx) { + Vec3f digPos; + + EnGuardNuts_ChangeAnim(this, DIG_ANIM); + Math_Vec3f_Copy(&digPos, &this->actor.world.pos); + digPos.y = this->actor.floorHeight; + EffectSsHahen_SpawnBurst(globalCtx, &digPos, 4.0f, 0, 10, 3, 15, -1, 10, NULL); + this->targetHeadPos.y = 0; + this->actor.flags |= ACTOR_FLAG_8000000; + this->targetHeadPos.x = this->targetHeadPos.y; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + this->actionFunc = EnGuardNuts_SetupUnburrow; +} + +void EnGuardNuts_SetupUnburrow(EnGuardNuts* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + SkelAnime_Update(&this->skelAnime); + if (this->animFrameCount <= curFrame) { + this->state = GUARD_NUTS_BURROWED_STATE; + this->actionFunc = EnGuardNuts_Unburrow; + this->actor.world.rot.y = this->actor.home.rot.y; + this->actor.shape.rot.y = this->actor.home.rot.y; + } +} + +void EnGuardNuts_Unburrow(EnGuardNuts* this, GlobalContext* globalCtx) { + s16 yawDiff; + Vec3f digPos; + + // If you have returned Deku Princess, guards will not unburrow + if (!(gSaveContext.save.weekEventReg[23] & 0x20)) { + yawDiff = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.home.rot.y)); + if ((yawDiff < 0x4000) && ((D_80ABBE20 == 0) || (this->actor.xzDistToPlayer > 150.0f))) { + Math_Vec3f_Copy(&digPos, &this->actor.world.pos); + digPos.y = this->actor.floorHeight; + EffectSsHahen_SpawnBurst(globalCtx, &digPos, 4.0f, 0, 10, 3, 15, -1, 10, NULL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + D_80ABBE20 = 0; + if (this->guardTextIndex == 9) { + this->hasCompletedConversation = true; + } + this->actor.flags &= ~ACTOR_FLAG_8000000; + EnGuardNuts_SetupWait(this); + } + } +} + +void EnGuardNuts_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGuardNuts* this = THIS; + s32 pad; + + if (this->blinkTimer == 0) { + if (++(this->eyeState) >= 3) { + this->eyeState = 0; + this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20; + } + } + if ((this->animIndex == WALK_ANIM) && + ((Animation_OnFrame(&this->skelAnime, 1.0f)) || (Animation_OnFrame(&this->skelAnime, 5.0f)))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); + } + + this->actionFunc(this, globalCtx); + Actor_SetFocus(&this->actor, 40.0f); + Math_SmoothStepToS(&this->headRot.x, this->targetHeadPos.x, 1, 0xBB8, 0); + Math_SmoothStepToS(&this->headRot.y, this->targetHeadPos.y, 1, 0xBB8, 0); + + if (this->blinkTimer != 0) { + this->blinkTimer--; + } + if (this->timer != 0) { + this->timer--; + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 0x1D); + if ((this->state != GUARD_NUTS_BURROWED_STATE) && (this->state != GUARD_NUTS_UNK_STATE)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +s32 EnGuardNuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnGuardNuts* this = THIS; + + if (limbIndex == DEKU_PALACE_GUARD_LIMB_HEAD) { + rot->x += this->headRot.x; + rot->y += this->headRot.y; + rot->z += this->headRot.z; + } + return false; +} + +void EnGuardNuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnGuardNuts* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeState])); + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnGuardNuts_OverrideLimbDraw, + NULL, &this->actor); + Matrix_Translate(this->guardPos.x, this->actor.floorHeight, this->guardPos.z, MTXMODE_NEW); + Matrix_Scale(0.015f, 0.015f, 0.015f, 1); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, gDekuPalaceGuardFlower); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.h b/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.h index 13acc2237..4a42e4e5a 100644 --- a/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.h +++ b/src/overlays/actors/ovl_En_Guard_Nuts/z_en_guard_nuts.h @@ -2,16 +2,31 @@ #define Z_EN_GUARD_NUTS_H #include "global.h" +#include "objects/object_dnk/object_dnk.h" struct EnGuardNuts; typedef void (*EnGuardNutsActionFunc)(struct EnGuardNuts*, GlobalContext*); typedef struct EnGuardNuts { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC8]; - /* 0x020C */ EnGuardNutsActionFunc actionFunc; - /* 0x0210 */ char unk_210[0x80]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[DEKU_PALACE_GUARD_LIMB_MAX]; + /* 0x1CA */ Vec3s morphTable[DEKU_PALACE_GUARD_LIMB_MAX]; + /* 0x20C */ EnGuardNutsActionFunc actionFunc; + /* 0x210 */ s16 eyeState; + /* 0x212 */ s16 blinkTimer; + /* 0x214 */ s16 timer; + /* 0x218 */ s32 animIndex; + /* 0x21C */ s16 state; + /* 0x21E */ s16 guardNumber; // Unused - Number used to identify guard + /* 0x220 */ s32 guardTextIndex; + /* 0x224 */ u8 hasCompletedConversation; // Flag set when player has gone through all text. + /* 0x228 */ Vec3f guardPos; + /* 0x234 */ Vec3s headRot; + /* 0x23A */ Vec3s targetHeadPos; + /* 0x240 */ f32 animFrameCount; + /* 0x244 */ ColliderCylinder collider; } EnGuardNuts; // size = 0x290 extern const ActorInit En_Guard_Nuts_InitVars; diff --git a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c index 71e0c8cd0..3830864d1 100644 --- a/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c +++ b/src/overlays/actors/ovl_En_Guruguru/z_en_guruguru.c @@ -5,8 +5,9 @@ */ #include "z_en_guruguru.h" +#include "objects/object_fu/object_fu.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnGuruguru*)thisx) @@ -24,15 +25,7 @@ void func_80BC73F4(EnGuruguru* this); void func_80BC7440(EnGuruguru* this, GlobalContext* globalCtx); void func_80BC7520(EnGuruguru* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_06006C90; extern ColliderCylinderInit D_80BC79A0; -extern AnimationHeader D_06000B04; -extern AnimationHeader D_0600057C; - -extern u64 D_06005F20[]; -extern u64 D_06006320[]; -extern u64 D_06006720[]; -extern u64 D_06006920[]; const ActorInit En_Guruguru_InitVars = { ACTOR_EN_GURUGURU, @@ -69,29 +62,30 @@ static ColliderCylinderInit sCylinderInit = { { 15, 20, 0, { 0, 0, 0 } }, }; -static AnimationHeader* D_80BC79CC[] = { &D_06000B04, &D_0600057C }; +static AnimationHeader* D_80BC79CC[] = { &object_fu_Anim_000B04, &object_fu_Anim_00057C }; static u8 D_80BC79D4[] = { 0 }; static f32 D_80BC79D8[] = { 1.0f, 1.0f }; -static void* sEyeTextures[] = { D_06005F20, D_06006320 }; -static void* sMouthTextures[] = { D_06006720, D_06006920 }; +static TexturePtr sEyeTextures[] = { object_fu_Tex_005F20, object_fu_Tex_006320 }; +static TexturePtr sMouthTextures[] = { object_fu_Tex_006720, object_fu_Tex_006920 }; void EnGuruguru_Init(Actor* thisx, GlobalContext* globalCtx) { EnGuruguru* this = THIS; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 19.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06006C90, &D_06000B04, this->jointTable, this->morphTable, 16); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_fu_Skel_006C90, &object_fu_Anim_000B04, this->jointTable, + this->morphTable, 16); this->actor.targetMode = 0; if (this->actor.params != 2) { Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); } - if (!gSaveContext.isNight) { + if (!gSaveContext.save.isNight) { if (this->actor.params == 0) { func_80BC6E10(this); } else if (this->actor.params == 2) { - this->actor.flags |= 0x8000000; + this->actor.flags |= ACTOR_FLAG_8000000; this->actor.draw = NULL; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = EnGuruguru_DoNothing; } else { Actor_MarkForDeath(&this->actor); @@ -125,10 +119,10 @@ void func_80BC6E10(EnGuruguru* this) { this->textIdIndex = 0; this->unk270 = 0; if (this->actor.params == 0) { - if (gSaveContext.weekEventReg[38] & 0x10) { + if (gSaveContext.save.weekEventReg[38] & 0x10) { this->textIdIndex = 1; } - } else if (gSaveContext.weekEventReg[38] & 0x40) { + } else if (gSaveContext.save.weekEventReg[38] & 0x40) { this->textIdIndex = 2; } else { this->textIdIndex = 3; @@ -137,8 +131,8 @@ void func_80BC6E10(EnGuruguru* this) { this->headZRotTarget = 0; this->unk268 = 1; this->actor.textId = textIDs[this->textIdIndex]; - if ((this->textIdIndex == 0 || this->textIdIndex == 1) && (gSaveContext.weekEventReg[77] & 4)) { - if (!(gSaveContext.weekEventReg[88] & 4)) { + if ((this->textIdIndex == 0 || this->textIdIndex == 1) && (gSaveContext.save.weekEventReg[77] & 4)) { + if (!(gSaveContext.save.weekEventReg[88] & 4)) { this->actor.textId = 0x295F; } else { this->actor.textId = 0x2960; @@ -159,7 +153,7 @@ void func_80BC6F14(EnGuruguru* this, GlobalContext* globalCtx) { this->textIdIndex = 3; if (player->transformation == PLAYER_FORM_DEKU) { this->textIdIndex = 13; - if (gSaveContext.weekEventReg[79] & 4) { + if (gSaveContext.save.weekEventReg[79] & 4) { this->textIdIndex = 14; } } @@ -170,7 +164,7 @@ void func_80BC6F14(EnGuruguru* this, GlobalContext* globalCtx) { yawTemp = this->actor.yawTowardsPlayer - this->actor.world.rot.y; yaw = ABS_ALT(yawTemp); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80BC701C(this, globalCtx); } else if (yaw <= 0x2890) { func_800B8614(&this->actor, globalCtx, 60.0f); @@ -197,7 +191,7 @@ void func_80BC7068(EnGuruguru* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); } else if (this->unusedTimer == 0) { this->unusedTimer = 6; - if (func_80152498(&globalCtx->msgCtx) != 5) { + if (Message_GetState(&globalCtx->msgCtx) != 5) { if (this->unk266 == 0) { if (this->headZRotTarget != 0) { this->headZRotTarget = 0; @@ -213,21 +207,21 @@ void func_80BC7068(EnGuruguru* this, GlobalContext* globalCtx) { } } } - if ((func_80152498(&globalCtx->msgCtx) == 5) && (func_80147624(globalCtx))) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); this->headZRotTarget = 0; if ((this->textIdIndex == 13) || (this->textIdIndex == 14)) { func_80151BB4(globalCtx, 0x13); - gSaveContext.weekEventReg[79] |= 4; + gSaveContext.save.weekEventReg[79] |= 4; func_80BC6E10(this); return; } if (this->actor.params == 0) { if (this->actor.textId == 0x295F) { - gSaveContext.weekEventReg[88] |= 4; + gSaveContext.save.weekEventReg[88] |= 4; } if (this->actor.textId == 0x292A) { - gSaveContext.weekEventReg[38] |= 0x10; + gSaveContext.save.weekEventReg[38] |= 0x10; } func_80151BB4(globalCtx, 0x13); func_80BC6E10(this); @@ -238,7 +232,7 @@ void func_80BC7068(EnGuruguru* this, GlobalContext* globalCtx) { return; } if (this->textIdIndex == 12) { - gSaveContext.weekEventReg[38] |= 0x40; + gSaveContext.save.weekEventReg[38] |= 0x40; func_801A3B48(0); func_80151BB4(globalCtx, 0x36); func_80151BB4(globalCtx, 0x13); @@ -301,21 +295,21 @@ void func_80BC7440(EnGuruguru* this, GlobalContext* globalCtx) { this->textIdIndex++; this->actor.textId = textIDs[this->textIdIndex]; func_801A3B48(1); - func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, -1); + func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, EXCH_ITEM_MINUS1); this->unk268 = 0; - gSaveContext.weekEventReg[38] |= 0x40; + gSaveContext.save.weekEventReg[38] |= 0x40; this->actionFunc = func_80BC7520; } else { - func_800B8A1C(&this->actor, globalCtx, GI_MASK_BREMEN, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_BREMEN, 300.0f, 300.0f); } } void func_80BC7520(EnGuruguru* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80BC7068; } else { - func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, -1); + func_800B8500(&this->actor, globalCtx, 400.0f, 400.0f, EXCH_ITEM_MINUS1); } } @@ -325,7 +319,7 @@ void EnGuruguru_Update(Actor* thisx, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 yawTemp; - if (!gSaveContext.isNight) { + if (!gSaveContext.save.isNight) { if (this->actor.params == 1) { Actor_MarkForDeath(&this->actor); return; @@ -339,12 +333,12 @@ void EnGuruguru_Update(Actor* thisx, GlobalContext* globalCtx) { if (this->actor.params == 2) { if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 100.0f) { - func_801A1DB8(&this->actor.projectedPos, 0x2E, 540.0f); + func_801A1DB8(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); } return; } if (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 200.0f) { - func_801A1D44(&this->actor.projectedPos, 0x2E, 540.0f); + func_801A1D44(&this->actor.projectedPos, NA_BGM_SONG_OF_STORMS, 540.0f); } if (this->unusedTimer != 0) { this->unusedTimer--; @@ -365,8 +359,8 @@ void EnGuruguru_Update(Actor* thisx, GlobalContext* globalCtx) { } } Actor_SetScale(&this->actor, 0.01f); - Actor_SetHeight(&this->actor, 50.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, 50.0f); + Actor_MoveWithGravity(&this->actor); Math_SmoothStepToS(&this->headXRot, this->headXRotTarget, 1, 3000, 0); Math_SmoothStepToS(&this->headZRot, this->headZRotTarget, 1, 1000, 0); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); 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 560a86dee..d8551103d 100644 --- a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c +++ b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c @@ -1,6 +1,15 @@ -#include "z_en_hakurock.h" +/* + * File: z_en_hakurock.c + * Overlay: En_Hakurock + * Description: Goht Debris + */ -#define FLAGS 0x00000030 +#include "z_en_hakurock.h" +#include "overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_boss_hakugin/object_boss_hakugin.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnHakurock*)thisx) @@ -8,13 +17,21 @@ void EnHakurock_Init(Actor* thisx, GlobalContext* globalCtx); void EnHakurock_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHakurock_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80B21BE0(BossHakugin* parent, Vec3f* arg1, s32 arg2); +void func_80B21EA4(EnHakurock* this, s32 arg1); +void func_80B21FFC(EnHakurock* this); void func_80B22040(EnHakurock* this, GlobalContext* globalCtx); +void func_80B220A8(EnHakurock* this); void func_80B221E8(EnHakurock* this, GlobalContext* globalCtx); +void func_80B222AC(EnHakurock* this, GlobalContext* globalCtx); void func_80B2242C(EnHakurock* this, GlobalContext* globalCtx); +void func_80B224C0(EnHakurock* this); void func_80B22500(EnHakurock* this, GlobalContext* globalCtx); +void func_80B226AC(EnHakurock* this); void func_80B22750(EnHakurock* this, GlobalContext* globalCtx); +void func_80B228F4(Actor* thisx, GlobalContext* globalCtx); +void EnHakurock_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Hakurock_InitVars = { ACTOR_EN_HAKUROCK, ACTORCAT_ITEMACTION, @@ -27,53 +44,315 @@ const ActorInit En_Hakurock_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B22A80 = { - { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x00 }, { 0xF3CFBBFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x00 }, + { 0xF3CFBBFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON, + OCELEM_ON, + }, { 60, 60, -30, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80B22AAC = { 0, 60, 60, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 0, 60, 60, MASS_IMMOVABLE }; -#endif +// Stalactite -extern ColliderCylinderInit D_80B22A80; -extern CollisionCheckInfoInit D_80B22AAC; +void EnHakurock_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHakurock* this = THIS; -extern UNK_TYPE D_06011100; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 52.0f); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + if (this->actor.params == EN_HAKUROCK_TYPE_BOULDER) { + this->actor.gravity = -1.5f; + } else { + this->collider.base.ocFlags1 &= ~OC1_NO_PUSH; + this->actor.terminalVelocity = -100.0f; + this->actor.gravity = -7.0f; + } + func_80B21FFC(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/EnHakurock_Init.s") +void EnHakurock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHakurock* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/EnHakurock_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B21BE0.s") +void func_80B21BE0(BossHakugin* parent, Vec3f* arg1, s32 arg2) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B21EA4.s") + for (i = 0; i < ARRAY_COUNT(parent->unk_9F8); i++) { + BossHakuginParticle* gohtParticle = &parent->unk_9F8[i]; + if (gohtParticle->unk_18 < 0) { + s16 sp2E; + s16 sp2C; + f32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B21FFC.s") + Math_Vec3f_Copy(&gohtParticle->unk_0, arg1); + sp2C = Rand_S16Offset(0x1000, 0x3000); + sp2E = (u32)Rand_Next() >> 0x10; + sp28 = Rand_ZeroFloat(5.0f) + 10.0f; + gohtParticle->unk_C.x = (sp28 * Math_CosS(sp2C)) * Math_SinS(sp2E); + gohtParticle->unk_C.y = (Math_SinS(sp2C) * sp28); + gohtParticle->unk_C.z = (sp28 * Math_CosS(sp2C)) * Math_CosS(sp2E); + if ((arg2 == 1) || (arg2 == 3)) { + gohtParticle->unk_24 = ((Rand_ZeroFloat(5.0f) + 25.0f) * 0.0012f); + gohtParticle->unk_0.x = ((Rand_ZeroFloat(2.0f) + 9.0f) * gohtParticle->unk_C.x) + arg1->x; + gohtParticle->unk_0.y = ((Rand_ZeroFloat(2.0f) + 3.0f) * gohtParticle->unk_C.y) + arg1->y; + gohtParticle->unk_0.z = ((Rand_ZeroFloat(2.0f) + 9.0f) * gohtParticle->unk_C.z) + arg1->z; + gohtParticle->unk_1A = 1; + } else { + gohtParticle->unk_24 = ((Rand_ZeroFloat(5.0f) + 18.0f) * 0.0001f); + gohtParticle->unk_0.x = ((Rand_ZeroFloat(2.0f) + 3.0f) * gohtParticle->unk_C.x) + arg1->x; + gohtParticle->unk_0.y = ((Rand_ZeroFloat(3.0f) + 1.0f) * gohtParticle->unk_C.y) + arg1->y; + gohtParticle->unk_0.z = ((Rand_ZeroFloat(2.0f) + 3.0f) * gohtParticle->unk_C.z) + arg1->z; + gohtParticle->unk_1A = 0; + } + gohtParticle->unk_1C.x = Rand_Next() >> 0x10; + gohtParticle->unk_1C.y = Rand_Next() >> 0x10; + gohtParticle->unk_1C.z = Rand_Next() >> 0x10; + gohtParticle->unk_18 = 0x28; + return; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B22040.s") +void func_80B21EA4(EnHakurock* this, s32 arg1) { + Vec3f sp4C; + s32 i; + f32 scaleFactor; + s32 tmp; + s32 phi_s5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B220A8.s") + if (arg1 == 0) { + for (i = 0; i < 20; i++) { + func_80B21BE0((BossHakugin*)this->actor.parent, &this->actor.world.pos, arg1); + } + } else if (arg1 == 2) { + for (i = 0; i < 10; i++) { + func_80B21BE0((BossHakugin*)this->actor.parent, &this->actor.world.pos, arg1); + } + } else { + Math_Vec3f_Copy(&sp4C, &this->actor.world.pos); + scaleFactor = this->actor.scale.x * 600.0f; + if (arg1 == 1) { + sp4C.y -= scaleFactor; + i = 0; + } else { + i = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B221E8.s") + for (; i < 3; i++) { + tmp = (i * 5) + 5; + for (phi_s5 = 0; phi_s5 < tmp; phi_s5++) { + func_80B21BE0((BossHakugin*)this->actor.parent, &sp4C, arg1); + } + sp4C.y += scaleFactor; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B222AC.s") +void func_80B21FFC(EnHakurock* this) { + this->actor.bgCheckFlags &= ~1; + this->collider.base.atFlags &= ~AT_HIT; + this->collider.base.ocFlags1 &= ~OC1_HIT; + this->actor.draw = NULL; + this->actor.params = EN_HAKUROCK_TYPE_UNK_0; + this->actionFunc = func_80B22040; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B2242C.s") +void func_80B22040(EnHakurock* this, GlobalContext* globalCtx) { + if (this->actor.params == EN_HAKUROCK_TYPE_BOULDER) { + func_80B220A8(this); + } else if (this->actor.params == EN_HAKUROCK_TYPE_UNK_2) { + func_80B222AC(this, globalCtx); + } else if (this->actor.params == EN_HAKUROCK_TYPE_FENCE_PILLAR) { + func_80B226AC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B224C0.s") +void func_80B220A8(EnHakurock* this) { + this->actor.params = EN_HAKUROCK_TYPE_BOULDER; + this->actor.draw = func_80B228F4; + this->actor.speedXZ = Rand_ZeroFloat(3.5f) + 2.5f; + this->actor.velocity.y = Rand_ZeroFloat(4.5f) + 18.0f; + Actor_SetScale(&this->actor, (Rand_ZeroFloat(5.0f) + 15.0f) * 0.001f); + this->actor.world.rot.y = (Rand_Next() >> 0x12) + this->actor.parent->shape.rot.y + 0x8000; + this->actor.shape.rot.x = Rand_Next() >> 0x10; + this->actor.shape.rot.y = Rand_Next() >> 0x10; + this->actor.shape.rot.z = Rand_Next() >> 0x10; + this->collider.dim.radius = (this->actor.scale.x * 2500.0f); + this->collider.dim.yShift = -this->collider.dim.radius; + this->collider.dim.height = this->collider.dim.radius * 2; + this->counter = 10; + Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos); + this->actionFunc = func_80B221E8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B22500.s") +void func_80B221E8(EnHakurock* this, GlobalContext* globalCtx) { + if (this->counter > 0) { + this->counter--; + } + this->actor.shape.rot.x += 0x700; + this->actor.shape.rot.y += 0x900; + this->actor.shape.rot.z += 0xB00; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B226AC.s") + if (this->collider.base.atFlags & AT_HIT || ((this->counter == 0) && (this->collider.base.ocFlags1 & OC1_HIT)) || + ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROCK_BROKEN); + func_80B21EA4(this, 0); + func_80B21FFC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B22750.s") +void func_80B222AC(EnHakurock* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 angle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/EnHakurock_Update.s") + this->actor.draw = EnHakurock_Draw; + angle = (Rand_Next() >> 0x13) + player->actor.shape.rot.y; + this->actor.shape.rot.y = Rand_Next() >> 0x10; + this->actor.world.pos.x = (Math_SinS(angle) * 600.0f) + player->actor.world.pos.x; + this->actor.world.pos.y = player->actor.world.pos.y + 700.0f; + this->actor.world.pos.z = (Math_CosS(angle) * 600.0f) + player->actor.world.pos.z; + this->actor.shape.shadowScale = 5.0f; + this->actor.velocity.y = -10.0f; + Actor_SetScale(&this->actor, (Rand_ZeroFloat(5.0f) + 17.0f) * 0.01f); + this->actor.scale.x *= 0.6f; + this->actor.scale.z *= 0.6f; + this->collider.dim.radius = (this->actor.scale.x * 150.0f); + this->collider.dim.yShift = (this->actor.scale.y * -750.0f); + this->collider.dim.height = this->collider.dim.yShift * -2; + Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos); + this->actor.params = EN_HAKUROCK_TYPE_UNK_2; + this->actionFunc = func_80B2242C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B228F4.s") +void func_80B2242C(EnHakurock* this, GlobalContext* globalCtx) { + if ((this->collider.base.ocFlags1 & OC1_HIT) && (this->collider.base.oc == this->actor.parent)) { + func_80B21EA4(this, 1); + func_80B21FFC(this); + } else if ((this->actor.bgCheckFlags & 1)) { + func_80B21EA4(this, 2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OBJECT_STICK); + func_80B224C0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hakurock/func_80B229A4.s") +void func_80B224C0(EnHakurock* this) { + this->actor.params = EN_HAKUROCK_TYPE_STALACTITE; + this->counter = 10; + this->actor.shape.shadowScale = 0.0f; + this->actor.world.pos.y += 4.0f; + this->actionFunc = func_80B22500; +} + +void func_80B22500(EnHakurock* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->counter > 0) { + this->counter--; + if ((this->counter & 1) == 0) { + this->actor.world.pos.y = (sin_rad(this->counter * (M_PI / 20)) * 4.0f) + this->actor.floorHeight; + } else { + this->actor.world.pos.y = this->actor.floorHeight; + } + } + if (this->collider.base.ocFlags1 & OC1_HIT) { + if ((this->collider.base.oc == this->actor.parent) || + ((this->collider.base.oc->id == ACTOR_EN_HAKUROCK) && + (this->collider.base.oc->params == EN_HAKUROCK_TYPE_UNK_2))) { + func_80B21EA4(this, 3); + func_80B21FFC(this); + } else if ((&player->actor == this->collider.base.oc) && ((player->stateFlags3 & 0x81000) != 0) && + (player->linearVelocity > 8.0f)) { + player->unk_B08[0] = player->linearVelocity = -5.0f; + player->unk_B08[1] += (player->linearVelocity * 0.05f); + player->actor.velocity.y = 5.0f; + player->currentYaw = player->actor.world.rot.y; + player->actor.home.rot.y = player->actor.world.rot.y; + player->actor.shape.rot.y = player->actor.world.rot.y; + player->unk_B8C = 4; + } + + } else if ((this->actor.xzDistToPlayer > 1000.0f) && (this->actor.projectedPos.z < 0.0f)) { + func_80B21FFC(this); + } +} + +void func_80B226AC(EnHakurock* this) { + f32 shiftFactor; + + this->actor.draw = EnHakurock_Draw; + Actor_SetScale(&this->actor, 0.35f); + this->actor.scale.y = 0.5f; + this->collider.dim.radius = this->actor.scale.x * 270.0f; + shiftFactor = -750.0f; + this->collider.dim.yShift = 0.5f * shiftFactor; + this->counter = 0; + this->actor.shape.shadowScale = 0.0f; + this->collider.dim.height = this->collider.dim.yShift * -2; + this->actionFunc = func_80B22750; +} + +void func_80B22750(EnHakurock* this, GlobalContext* globalCtx) { + if (this->actor.params == EN_HAKUROCK_TYPE_UNK_0) { + func_80B21EA4(this, 3); + func_80B21FFC(this); + } +} + +void EnHakurock_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHakurock* this = THIS; + s16 rockParams; + + this->actionFunc(this, globalCtx); + rockParams = this->actor.params; + if ((rockParams == EN_HAKUROCK_TYPE_BOULDER) || (rockParams == EN_HAKUROCK_TYPE_UNK_2)) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, this->collider.dim.radius, 0.0f, 0x85); + if (this->actor.floorHeight == BGCHECK_Y_MIN) { + func_80B21FFC(this); + } else { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } else if ((rockParams == EN_HAKUROCK_TYPE_STALACTITE) || (rockParams == EN_HAKUROCK_TYPE_FENCE_PILLAR)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B228F4(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 185, 24, 255); + 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); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnHakurock_Draw(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(-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++, object_boss_hakugin_DL_011100); + gSPDisplayList(POLY_OPA_DISP++, object_boss_hakugin_DL_011178); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.h b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.h index 4890438aa..eb1c4eb5d 100644 --- a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.h +++ b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.h @@ -7,10 +7,19 @@ struct EnHakurock; typedef void (*EnHakurockActionFunc)(struct EnHakurock*, GlobalContext*); +typedef enum { + /* 0x0 */ EN_HAKUROCK_TYPE_UNK_0, + /* 0x1 */ EN_HAKUROCK_TYPE_BOULDER, + /* 0x2 */ EN_HAKUROCK_TYPE_UNK_2, + /* 0x3 */ EN_HAKUROCK_TYPE_STALACTITE, + /* 0x4 */ EN_HAKUROCK_TYPE_FENCE_PILLAR +} EnHakurockType; + typedef struct EnHakurock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnHakurockActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x50]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnHakurockActionFunc actionFunc; + /* 0x148 */ s32 counter; + /* 0x14C */ ColliderCylinder collider; } EnHakurock; // size = 0x198 extern const ActorInit En_Hakurock_InitVars; diff --git a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c index cda19b4fd..f90ed476b 100644 --- a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c +++ b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.c @@ -1,6 +1,13 @@ -#include "z_en_hanabi.h" +/* + * File: z_en_hanabi.c + * Overlay: ovl_En_Hanabi + * Description: Fireworks + */ -#define FLAGS 0x00000030 +#include "z_en_hanabi.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnHanabi*)thisx) @@ -12,8 +19,8 @@ void func_80B23894(EnHanabi* this, GlobalContext* globalCtx); void func_80B238D4(EnHanabi* this, GlobalContext* globalCtx); void func_80B23910(EnHanabi* this, GlobalContext* globalCtx); void func_80B23934(EnHanabi* this, GlobalContext* globalCtx); +void EnHanabi_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Hanabi_InitVars = { ACTOR_EN_HANABI, ACTORCAT_ITEMACTION, @@ -26,38 +33,322 @@ const ActorInit En_Hanabi_InitVars = { (ActorFunc)NULL, }; -#endif +Vec3s D_80B23AA0[] = { + { 85, 14, 49 }, { 70, -70, 0 }, { 85, 14, -49 }, { 90, -32, 28 }, { 90, -32, -28 }, { 98, 16, 0 }, + { 70, 70, 0 }, { 84, 45, 26 }, { 84, 45, -26 }, { 50, -50, 70 }, { 73, -19, 64 }, { 65, -65, 38 }, + { 50, -50, -70 }, { 65, -65, -38 }, { 73, -19, -64 }, { 0, 0, -100 }, { 14, 85, -49 }, { 49, 8, -86 }, + { 8, 49, -86 }, { 57, 57, -57 }, { 45, 84, -26 }, { 27, -27, -92 }, { -50, 50, -70 }, { -27, 27, -92 }, + { -19, 73, -64 }, { -70, 70, 0 }, { 14, 85, 49 }, { -32, 90, -28 }, { -32, 90, 28 }, { 16, 98, 0 }, + { 45, 84, 26 }, { -65, 65, -38 }, { -50, 50, 70 }, { -65, 65, 38 }, { -19, 73, 64 }, { 0, 0, 100 }, + { 8, 49, 86 }, { 49, 8, 86 }, { 57, 57, 57 }, { -27, 27, 92 }, { 27, -27, 92 }, { -14, -85, -49 }, + { -14, -85, 49 }, { 32, -90, -28 }, { 32, -90, 28 }, { -16, -98, 0 }, { -70, -70, 0 }, { -45, -84, -26 }, + { -45, -84, 26 }, { 19, -73, -64 }, { 19, -73, 64 }, { -85, -14, -49 }, { -49, -8, -86 }, { -8, -49, -86 }, + { -57, -57, -57 }, { -84, -45, -26 }, { -73, 19, -64 }, { -85, -14, 49 }, { -90, 32, 28 }, { -90, 32, -28 }, + { -98, -16, 0 }, { -84, -45, 26 }, { -73, 19, 64 }, { -8, -49, 86 }, { -49, -8, 86 }, { -57, -57, 57 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22C00.s") +u8 D_80B23C2C[] = { + 255, 255, 200, 255, 200, 255, 200, 255, 255, 255, 200, 200, 200, 255, 200, 200, 200, 255, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22C2C.s") +u8 D_80B23C40[] = { + 200, 200, 0, 200, 0, 200, 0, 200, 200, 200, 0, 0, 0, 200, 0, 0, 200, 200, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22C80.s") +void func_80B22C00(EnHanabiStruct* arg0) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22E0C.s") + for (i = 0; i < 400; i++, arg0++) { + arg0->unk_00 = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22F34.s") +void func_80B22C2C(EnHanabiStruct* arg0, s32 arg1) { + arg0->unk_01 = (s32)Rand_ZeroFloat(20.0f) + 60; + arg0->unk_02 = arg1; + arg0->unk_14.x = 0.7f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B22FA8.s") +s32 func_80B22C80(Vec3f* arg0, EnHanabiStruct* arg1, f32 arg2) { + Vec3s* phi_s1 = &D_80B23AA0[0]; + f32 temp_f22 = (Rand_ZeroFloat(0.2f) + 0.6f) * arg2; + s32 temp_s6 = (s32)Rand_ZeroFloat(6.0f) * 3; + s32 i; + s32 j; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/EnHanabi_Init.s") + for (i = 0, j = 0; j < ARRAY_COUNT(D_80B23AA0) && i < 400; i++, arg1++) { + if (arg1->unk_00 <= 0) { + arg1->unk_00 = 1; + Math_Vec3f_Copy(&arg1->unk_08, arg0); + arg1->unk_20.x = phi_s1->x * temp_f22; + arg1->unk_20.y = (phi_s1->y * temp_f22) + 50.0f; + arg1->unk_20.z = phi_s1->z * temp_f22; + arg1->unk_04 = 1.5f * arg2; + func_80B22C2C(arg1, temp_s6); + phi_s1++; + j++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/EnHanabi_Destroy.s") + return temp_s6; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B234C8.s") +void func_80B22E0C(EnHanabiStruct* arg0) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B235CC.s") + for (i = 0; i < 400; i++, arg0++) { + if (arg0->unk_00 == 1) { + arg0->unk_08.x += arg0->unk_20.x; + arg0->unk_08.y += arg0->unk_20.y; + arg0->unk_08.z += arg0->unk_20.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B236C8.s") + arg0->unk_20.x *= arg0->unk_14.x; + arg0->unk_20.z *= arg0->unk_14.x; + arg0->unk_20.y *= arg0->unk_14.x; + arg0->unk_20.y -= 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B23894.s") + arg0->unk_20.x += randPlusMinusPoint5Scaled(0.8f); + arg0->unk_20.y += randPlusMinusPoint5Scaled(0.8f); + arg0->unk_20.z += randPlusMinusPoint5Scaled(0.8f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B238D4.s") + if (arg0->unk_01 > 0) { + arg0->unk_01--; + } else { + arg0->unk_00 = 0; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B23910.s") +s32 func_80B22F34(EnHanabiStruct* arg0) { + s32 count = 0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B23934.s") + for (i = 0; i < 400; i++, arg0++) { + if (arg0->unk_00 == 1) { + count++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/EnHanabi_Update.s") + return count; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hanabi/func_80B23A38.s") +void func_80B22FA8(EnHanabiStruct* arg0, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s32 i; + u8 sp53; + + OPEN_DISPS(gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gSun1Tex)); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB10); + + sp53 = 0xFF; + if (sp53) {} + + for (i = 0; i < 400; i++, arg0++) { + if (arg0->unk_00 == 1) { + Matrix_Translate(arg0->unk_08.x, arg0->unk_08.y, arg0->unk_08.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + if (arg0->unk_01 < 40) { + Matrix_Scale(arg0->unk_04 * 0.025f * arg0->unk_01, arg0->unk_04 * 0.025f * arg0->unk_01, 1.0f, + MTXMODE_APPLY); + } else { + Matrix_Scale(arg0->unk_04, arg0->unk_04, 1.0f, MTXMODE_APPLY); + } + Matrix_RotateZS(globalCtx->gameplayFrames * 4864, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (sp53 != arg0->unk_02) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, D_80B23C40[arg0->unk_02], D_80B23C40[arg0->unk_02 + 1], + D_80B23C40[arg0->unk_02 + 2], 255); + + sp53 = arg0->unk_02; + } + + if (arg0->unk_01 < 6) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80B23C2C[arg0->unk_02], D_80B23C2C[arg0->unk_02 + 1], + D_80B23C2C[arg0->unk_02 + 2], arg0->unk_01 * 50); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80B23C2C[arg0->unk_02], D_80B23C2C[arg0->unk_02 + 1], + D_80B23C2C[arg0->unk_02 + 2], 255); + } + + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_07AB58); + } + } + + CLOSE_DISPS(gfxCtx); +} + +void EnHanabi_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnHanabi* this = THIS; + s32 i; + + if (1) {} + + Actor_SetScale(thisx, 1.0f); + this->actionFunc = func_80B23910; + this->unk_144 = 0; + func_80B22C00(this->unk_148); + + for (i = 0; i < ARRAY_COUNT(this->unk_4608); i++) { + Lights_PointNoGlowSetInfo(&this->unk_4608[i], thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 255, + 255, 255, -1); + this->unk_4634[i] = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->unk_4608[i]); + } + + if (ENHANABI_GET_1F(thisx) == ENHANABI_1F_1) { + this->actionFunc = func_80B23934; + this->actor.home.rot.x = 0x384; + } +} + +void EnHanabi_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnHanabi* this = THIS; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_4634); i++) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->unk_4634[i]); + } +} + +void func_80B234C8(EnHanabi* this) { + s16 phi_v1; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_4640); i++) { + if (this->unk_4640[i] > 0) { + this->unk_4640[i]--; + if (this->unk_4640[i] == 0) { + phi_v1 = -1; + } else { + if (this->unk_4640[i] >= 0xA) { + phi_v1 = 0x3E8; + } else { + phi_v1 = this->unk_4640[i] * 0x64; + } + + if (this->actor.home.rot.x >= 0x259) { + phi_v1 *= 2; + } + } + + Lights_PointSetColorAndRadius(&this->unk_4608[i], D_80B23C2C[this->unk_4648[i]], + D_80B23C2C[this->unk_4648[i] + 1], D_80B23C2C[this->unk_4648[i] + 2], phi_v1); + } + } +} + +void func_80B235CC(EnHanabi* this, Vec3f* arg1, s32 arg2) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_4640); i++) { + if (this->unk_4640[i] == 0) { + this->unk_4648[i] = arg2; + Lights_PointNoGlowSetInfo(&this->unk_4608[i], arg1->x, arg1->y, arg1->z, D_80B23C2C[arg2], + D_80B23C2C[arg2 + 1], D_80B23C2C[arg2 + 2], 0x3E8); + this->unk_4640[i] = 20; + break; + } + } +} + +void func_80B236C8(EnHanabi* this, GlobalContext* globalCtx) { + Vec3f sp34; + f32 sp30; + s32 pad; + s32 sp28; + + this->actor.draw = EnHanabi_Draw; + func_80B234C8(this); + if (this->actor.home.rot.x != 0) { + if (this->unk_144 > 0) { + this->unk_144--; + return; + } + + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + + if (this->actor.home.rot.x != 0) { + sp30 = Rand_ZeroFloat(200.0f) + this->actor.home.rot.x; + } else { + sp30 = Rand_ZeroFloat(200.0f) + 300.0f; + } + + sp34.x += sp30 * Math_SinS(this->actor.home.rot.y); + sp34.y += randPlusMinusPoint5Scaled(300.0f); + sp34.z += sp30 * Math_CosS(this->actor.home.rot.y); + + if (this->actor.home.rot.x >= 0x259) { + sp28 = func_80B22C80(&sp34, this->unk_148, 2.0f); + } else { + sp28 = func_80B22C80(&sp34, this->unk_148, 1.0f); + } + + this->actor.home.rot.y += (s16)((Rand_ZeroFloat(40.0f) + 80.0f) * 256.0f); + this->unk_144 = (s32)Rand_ZeroFloat(5.0f) + 20; + Actor_PlaySfxAtPos(&this->actor, NA_SE_OC_FIREWORKS); + func_80B235CC(this, &sp34, sp28); + } +} + +void func_80B23894(EnHanabi* this, GlobalContext* globalCtx) { + func_80B236C8(this, globalCtx); + if (func_80B22F34(this->unk_148) == 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B238D4(EnHanabi* this, GlobalContext* globalCtx) { + func_80B236C8(this, globalCtx); + if (this->actor.home.rot.x == 0) { + this->actionFunc = func_80B23894; + } +} + +void func_80B23910(EnHanabi* this, GlobalContext* globalCtx) { + if (this->actor.home.rot.x != 0) { + this->actionFunc = func_80B238D4; + } +} + +void func_80B23934(EnHanabi* this, GlobalContext* globalCtx) { + if ((gSaveContext.save.entranceIndex == 0x5410) && (gSaveContext.sceneSetupIndex == 7)) { + if (globalCtx->csCtx.frames > 1650) { + func_80B236C8(this, globalCtx); + func_800B8FE8(&this->actor, NA_SE_EV_FIREWORKS_LAUNCH - SFX_FLAG); + } + } + + if ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 7) && + (globalCtx->csCtx.currentCsIndex == 0) && (globalCtx->csCtx.frames == 610)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KYOJIN_GROAN); + } +} + +void EnHanabi_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHanabi* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80B22E0C(this->unk_148); +} + +void EnHanabi_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHanabi* this = THIS; + + Matrix_Push(); + func_80B22FA8(this->unk_148, globalCtx); + Matrix_Pop(); +} diff --git a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.h b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.h index 78f198ed4..ed4963daf 100644 --- a/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.h +++ b/src/overlays/actors/ovl_En_Hanabi/z_en_hanabi.h @@ -7,9 +7,28 @@ struct EnHanabi; typedef void (*EnHanabiActionFunc)(struct EnHanabi*, GlobalContext*); +#define ENHANABI_GET_1F(thisx) ((thisx)->params & 0x1F) + +#define ENHANABI_1F_1 1 + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; + /* 0x04 */ f32 unk_04; + /* 0x08 */ Vec3f unk_08; + /* 0x14 */ Vec3f unk_14; + /* 0x20 */ Vec3f unk_20; +} EnHanabiStruct; // size = 0x2C + typedef struct EnHanabi { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4510]; + /* 0x0144 */ s16 unk_144; + /* 0x0148 */ EnHanabiStruct unk_148[400]; + /* 0x4608 */ LightInfo unk_4608[3]; + /* 0x4634 */ LightNode* unk_4634[3]; + /* 0x4640 */ s16 unk_4640[3]; + /* 0x4648 */ s32 unk_4648[3]; /* 0x4654 */ EnHanabiActionFunc actionFunc; } EnHanabi; // size = 0x4658 diff --git a/src/overlays/actors/ovl_En_Hata/z_en_hata.c b/src/overlays/actors/ovl_En_Hata/z_en_hata.c index c849e8673..10c8df4e7 100644 --- a/src/overlays/actors/ovl_En_Hata/z_en_hata.c +++ b/src/overlays/actors/ovl_En_Hata/z_en_hata.c @@ -1,3 +1,9 @@ +/* + * File: z_en_hata.c + * Overlay: ovl_En_Hata + * Description: Red Flag on Post + */ + #include "z_en_hata.h" #define FLAGS 0x00000000 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 df4211818..bb2fb002b 100644 --- a/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c +++ b/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c @@ -1,6 +1,13 @@ -#include "z_en_heishi.h" +/* + * File: z_en_heishi.c + * Overlay: ovl_En_Heishi + * Description: Soldier (Mayor's Residence only) + */ -#define FLAGS 0x00000009 +#include "z_en_heishi.h" +#include "objects/object_sdn/object_sdn.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnHeishi*)thisx) @@ -9,9 +16,19 @@ void EnHeishi_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHeishi_Update(Actor* thisx, GlobalContext* globalCtx); void EnHeishi_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BE9214(EnHeishi* this, GlobalContext* globalCtx); +void EnHeishi_ChangeAnimation(EnHeishi* this, s32 animIndex); +void EnHeishi_SetHeadRotation(EnHeishi* this); +void EnHeishi_SetupIdle(EnHeishi* this); +void EnHeishi_Idle(EnHeishi* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ HEISHI_ANIMATION_STAND_HAND_ON_HIP, + /* 1 */ HEISHI_ANIMATION_CHEER_WITH_SPEAR, + /* 2 */ HEISHI_ANIMATION_WAVE, + /* 3 */ HEISHI_ANIMATION_SIT_AND_REACH, + /* 4 */ HEISHI_ANIMATION_STAND_UP +} EnHeishiAnimationIndex; -#if 0 const ActorInit En_Heishi_InitVars = { ACTOR_EN_HEISHI, ACTORCAT_NPC, @@ -24,33 +41,153 @@ const ActorInit En_Heishi_InitVars = { (ActorFunc)EnHeishi_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BE9450 = { - { 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, + }, { 20, 60, 0, { 0, 0, 0 } }, }; -#endif +void EnHeishi_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHeishi* this = THIS; -extern ColliderCylinderInit D_80BE9450; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gSoldierSkeleton, &gSoldierWave, this->jointTable, + this->morphTable, HEISHI_LIMB_MAX); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->paramsCopy = this->actor.params; + this->yawTowardsPlayer = this->actor.world.rot.y; -extern UNK_TYPE D_06003BFC; + if (this->paramsCopy == 0) { + this->shouldSetHeadRotation = 1; + if (!(gSaveContext.save.weekEventReg[63] & 0x80) && + !((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) { + Actor_MarkForDeath(&this->actor); + } + } else { + this->colliderCylinder.dim.radius = 30; + this->colliderCylinder.dim.height = 60; + this->colliderCylinder.dim.yShift = 0; + if ((gSaveContext.save.weekEventReg[63] & 0x80) || + ((gSaveContext.save.day == 3) && gSaveContext.save.isNight)) { + Actor_MarkForDeath(&this->actor); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/EnHeishi_Init.s") + this->actor.targetMode = 6; + this->actor.gravity = -3.0f; + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + this->actor.flags |= ACTOR_FLAG_8000000; + EnHeishi_SetupIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/EnHeishi_Destroy.s") +void EnHeishi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHeishi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/func_80BE90BC.s") + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/func_80BE9148.s") +void EnHeishi_ChangeAnimation(EnHeishi* this, s32 animIndex) { + static AnimationHeader* sAnimations[] = { + &gSoldierStandHandOnHip, &gSoldierCheerWithSpear, &gSoldierWave, &gSoldierSitAndReach, &gSoldierStandUp, + }; + static u8 sAnimModes[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/func_80BE91DC.s") + this->animIndex = animIndex; + this->frameCount = Animation_GetLastFrame(sAnimations[this->animIndex]); + Animation_Change(&this->skelAnime, sAnimations[this->animIndex], 1.0f, 0.0f, this->frameCount, + sAnimModes[this->animIndex], -10.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/func_80BE9214.s") +void EnHeishi_SetHeadRotation(EnHeishi* this) { + s16 yawDiff = this->yawTowardsPlayer - this->actor.world.rot.y; + s32 absYawDiff = ABS_ALT(yawDiff); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/EnHeishi_Update.s") + this->headRotXTarget = 0; + if ((this->actor.xzDistToPlayer < 200.0f) && (absYawDiff < 0x4E20)) { + this->headRotXTarget = this->yawTowardsPlayer - this->actor.world.rot.y; + if (this->headRotXTarget > 0x2710) { + this->headRotXTarget = 0x2710; + } else if (this->headRotXTarget < -0x2710) { + this->headRotXTarget = -0x2710; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/func_80BE9380.s") +void EnHeishi_SetupIdle(EnHeishi* this) { + s8 animIndex = HEISHI_ANIMATION_STAND_HAND_ON_HIP; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Heishi/EnHeishi_Draw.s") + EnHeishi_ChangeAnimation(this, animIndex); + this->unk278 = animIndex; + this->actionFunc = EnHeishi_Idle; +} + +void EnHeishi_Idle(EnHeishi* this, GlobalContext* globalCtx) { +} + +void EnHeishi_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHeishi* this = THIS; + + SkelAnime_Update(&this->skelAnime); + if (this->timer != 0) { + this->timer--; + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + if ((this->paramsCopy != 0) && (gSaveContext.save.day == 3) && gSaveContext.save.isNight) { + Actor_MarkForDeath(&this->actor); + } else { + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 29); + Actor_SetScale(&this->actor, 0.01f); + if (this->shouldSetHeadRotation) { + EnHeishi_SetHeadRotation(this); + } + + Actor_SetFocus(&this->actor, 60.0f); + Math_SmoothStepToS(&this->headRotX, this->headRotXTarget, 1, 3000, 0); + Math_SmoothStepToS(&this->headRotY, this->headRotYTarget, 1, 1000, 0); + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } +} + +s32 EnHeishi_OverrideLimbDraw(GlobalContext* globalctx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnHeishi* this = THIS; + + if (limbIndex == HEISHI_LIMB_HEAD) { + rot->x += this->headRotX; + rot->y += this->headRotY; + rot->z += this->headRotZ; + } + + return false; +} + +void EnHeishi_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHeishi* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnHeishi_OverrideLimbDraw, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Heishi/z_en_heishi.h b/src/overlays/actors/ovl_En_Heishi/z_en_heishi.h index 8ceb74a00..de65bac72 100644 --- a/src/overlays/actors/ovl_En_Heishi/z_en_heishi.h +++ b/src/overlays/actors/ovl_En_Heishi/z_en_heishi.h @@ -7,13 +7,48 @@ struct EnHeishi; typedef void (*EnHeishiActionFunc)(struct EnHeishi*, GlobalContext*); +typedef enum { + /* 0 */ HEISHI_LIMB_NONE, + /* 1 */ HEISHI_LIMB_ROOT, + /* 2 */ HEISHI_LIMB_PELVIS, + /* 3 */ HEISHI_LIMB_LEFT_THIGH, + /* 4 */ HEISHI_LIMB_LEFT_CALF, + /* 5 */ HEISHI_LIMB_LEFT_FOOT, + /* 6 */ HEISHI_LIMB_RIGHT_THIGH, + /* 7 */ HEISHI_LIMB_RIGHT_CALF, + /* 8 */ HEISHI_LIMB_RIGHT_FOOT, + /* 9 */ HEISHI_LIMB_TORSO, + /* 10 */ HEISHI_LIMB_LEFT_SHOULDER, + /* 11 */ HEISHI_LIMB_LEFT_FOREARM, + /* 12 */ HEISHI_LIMB_LEFT_HAND, + /* 13 */ HEISHI_LIMB_RIGHT_SHOULDER, + /* 14 */ HEISHI_LIMB_RIGHT_FOREARM, + /* 15 */ HEISHI_LIMB_RIGHT_HAND_WITH_SPEAR, + /* 16 */ HEISHI_LIMB_HEAD, + /* 17 */ HEISHI_LIMB_MAX +} EnHeishiLimbs; + typedef struct EnHeishi { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x110]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[HEISHI_LIMB_MAX]; + /* 0x01EE */ Vec3s morphTable[HEISHI_LIMB_MAX]; /* 0x0254 */ EnHeishiActionFunc actionFunc; - /* 0x0258 */ char unk_258[0x78]; + /* 0x0258 */ s16 headRotY; + /* 0x025A */ s16 headRotX; + /* 0x025C */ s16 headRotZ; + /* 0x025E */ s16 headRotYTarget; + /* 0x0260 */ s16 headRotXTarget; + /* 0x0262 */ s16 headRotZTarget; + /* 0x0264 */ s32 animIndex; + /* 0x0268 */ s32 paramsCopy; + /* 0x026C */ s32 shouldSetHeadRotation; + /* 0x0270 */ s16 timer; + /* 0x0272 */ s16 yawTowardsPlayer; + /* 0x0274 */ f32 frameCount; + /* 0x0278 */ s16 unk278; // set and not used + /* 0x027C */ UNK_TYPE1 unk_27C[0x8]; + /* 0x0284 */ ColliderCylinder colliderCylinder; } EnHeishi; // size = 0x2D0 -extern const ActorInit En_Heishi_InitVars; - #endif // Z_EN_HEISHI_H diff --git a/src/overlays/actors/ovl_En_Hg/z_en_hg.c b/src/overlays/actors/ovl_En_Hg/z_en_hg.c index 7de50c75d..2b77feacf 100644 --- a/src/overlays/actors/ovl_En_Hg/z_en_hg.c +++ b/src/overlays/actors/ovl_En_Hg/z_en_hg.c @@ -1,12 +1,13 @@ /* * File: z_en_hg.c - * Overlay: En_Hg + * Overlay: ovl_En_Hg * Description: Pamela's Father (Human) */ #include "z_en_hg.h" +#include "objects/object_harfgibud/object_harfgibud.h" -#define FLAGS 0x02100019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((EnHg*)thisx) @@ -27,19 +28,8 @@ void func_80BCF6D0(EnHg* this, GlobalContext* globalCtx); void func_80BCF8A0(EnHg* this, GlobalContext* globalCtx); void func_80BCF93C(EnHg* this); void func_80BCF95C(EnHg* this, GlobalContext* globalCtx); -s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg); -void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg); - -extern AnimationHeader D_06000370; -extern AnimationHeader D_06001138; -extern AnimationHeader D_060015D4; -extern AnimationHeader D_06001960; -extern AnimationHeader D_0600260C; -extern Gfx D_06005E28[]; -extern FlexSkeletonHeader D_06008580; -extern AnimationHeader D_06009D44; -extern AnimationHeader D_0600A164; -extern AnimationHeader D_0600AE1C; +s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); const ActorInit En_Hg_InitVars = { ACTOR_EN_HG, @@ -112,11 +102,15 @@ static CollisionCheckInfoInit2 sColChkInfoInit2 = { 0, 0, 0, 0, 0x80, }; -static ActorAnimationEntry sAnimations[] = { - { &D_0600260C, 1.0f, 0.0f, 0.0f, 0, -4.0f }, { &D_06009D44, 1.0f, 0.0f, 0.0f, 0, -4.0f }, - { &D_0600A164, 1.0f, 0.0f, 0.0f, 0, -4.0f }, { &D_06000370, 1.0f, 0.0f, 0.0f, 2, 0.0f }, - { &D_06001138, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_060015D4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, - { &D_06001960, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_0600AE1C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +static AnimationInfo sAnimations[] = { + { &object_harfgibud_Anim_00260C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_harfgibud_Anim_009D44, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_harfgibud_Anim_00A164, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_harfgibud_Anim_000370, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_harfgibud_Anim_001138, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_harfgibud_Anim_0015D4, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_harfgibud_Anim_001960, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_harfgibud_Anim_00AE1C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, }; static u32 D_80BD00C8 = false; @@ -127,12 +121,12 @@ void EnHg_Init(Actor* thisx, GlobalContext* globalCtx) { s32 i; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 36.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06008580, &D_0600260C, this->jointTable, this->morphTable, - HG_LIMB_MAX); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_harfgibud_Skel_008580, &object_harfgibud_Anim_00260C, + this->jointTable, this->morphTable, HG_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2); - if ((gSaveContext.weekEventReg[0x4B] & 0x20) || (gSaveContext.weekEventReg[0x34] & 0x20)) { + if ((gSaveContext.save.weekEventReg[75] & 0x20) || (gSaveContext.save.weekEventReg[52] & 0x20)) { Actor_MarkForDeath(&this->actor); } this->actor.targetMode = 1; @@ -155,25 +149,25 @@ void EnHg_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void func_80BCF354(EnHg* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->actionFunc = func_80BCF398; } void func_80BCF398(EnHg* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.health == 1) { - if ((this->actor.xzDistToPlayer < 200.0f && this->actor.yDistToPlayer < 40.0f) && - !func_800EE29C(globalCtx, 0x1E3)) { + if ((this->actor.xzDistToPlayer < 200.0f && this->actor.playerHeightRel < 40.0f) && + !Cutscene_CheckActorAction(globalCtx, 0x1E3)) { func_80BCF468(this); } - if ((gSaveContext.sceneSetupIndex == 0 && globalCtx->csCtx.unk_12 == 0) && + if ((gSaveContext.sceneSetupIndex == 0 && globalCtx->csCtx.currentCsIndex == 0) && (globalCtx->csCtx.frames == 20 || globalCtx->csCtx.frames == 60)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_HALF_REDEAD_SURPRISE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_HALF_REDEAD_SURPRISE); } } } void func_80BCF468(EnHg* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actionFunc = func_80BCF4AC; } @@ -182,10 +176,10 @@ void func_80BCF4AC(EnHg* this, GlobalContext* globalCtx) { s32 pad; this->actor.speedXZ = 1.6f; - if (!(player->stateFlags2 & 0x08000000) && !func_80152498(&globalCtx->msgCtx)) { + if (!(player->stateFlags2 & 0x08000000) && Message_GetState(&globalCtx->msgCtx) == 0) { if (((this->skelAnime.curFrame > 9.0f) && (this->skelAnime.curFrame < 16.0f)) || ((this->skelAnime.curFrame > 44.0f) && (this->skelAnime.curFrame < 51.0f))) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x3E8, 0x14); this->actor.world.rot.y = this->actor.shape.rot.y; } @@ -197,7 +191,7 @@ void func_80BCF4AC(EnHg* this, GlobalContext* globalCtx) { } void func_80BCF5F0(EnHg* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->actionFunc = func_80BCF634; } @@ -210,7 +204,7 @@ void func_80BCF634(EnHg* this, GlobalContext* globalCtx) { } void func_80BCF68C(EnHg* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); this->actionFunc = func_80BCF6D0; } @@ -221,9 +215,9 @@ void func_80BCF6D0(EnHg* this, GlobalContext* globalCtx) { } void func_80BCF710(EnHg* this, GlobalContext* globalCtx) { - if (!func_80152498(&globalCtx->msgCtx)) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x24F, &this->actor); + if (Message_GetState(&globalCtx->msgCtx) == 0) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x24F, &this->actor); } else { func_800B8614(&this->actor, globalCtx, 80.0f); } @@ -234,7 +228,7 @@ void func_80BCF778(EnHg* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.health == 1) { if (this->actionFunc == func_80BCF4AC || this->actionFunc == func_80BCF6D0 || this->actionFunc == func_80BCF634) { - func_800B9010(&this->actor, 0x32B7); + func_800B9010(&this->actor, NA_SE_EN_HALF_REDEAD_LOOP - SFX_FLAG); } } } @@ -277,24 +271,25 @@ void func_80BCF93C(EnHg* this) { } void func_80BCF95C(EnHg* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x1E4)) { - u32 actionIndex = func_800EE200(globalCtx, 0x1E4); - if (this->cutscenes[3] != globalCtx->csCtx.npcActions[actionIndex]->unk0) { - this->cutscenes[3] = globalCtx->csCtx.npcActions[actionIndex]->unk0; - switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + if (Cutscene_CheckActorAction(globalCtx, 484)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 484); + + if (this->cutscenes[3] != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->cutscenes[3] = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: this->currentAnimation = 0; - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); break; case 2: this->cutscenes[2] = 0; this->currentAnimation = 3; - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); break; case 3: this->cutscenes[2] = 0; this->currentAnimation = 5; - func_800BDC5C(&this->skelAnime, sAnimations, 5); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); break; case 4: this->cutscenes[2] = 0; @@ -302,14 +297,14 @@ void func_80BCF95C(EnHg* this, GlobalContext* globalCtx) { if ((this->unk218 == 1) || (this->unk218 == 3)) { func_8019F128(NA_SE_EN_HALF_REDEAD_TRANS); } - func_800BDC5C(&this->skelAnime, sAnimations, 7); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 7); break; case 5: this->currentAnimation = 1; - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); break; case 6: - gSaveContext.weekEventReg[0x4B] |= 0x20; + gSaveContext.save.weekEventReg[75] |= 0x20; Actor_MarkForDeath(&this->actor); break; } @@ -318,11 +313,11 @@ void func_80BCF95C(EnHg* this, GlobalContext* globalCtx) { switch (this->currentAnimation) { case 3: this->currentAnimation = 4; - func_800BDC5C(&this->skelAnime, sAnimations, 4); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); break; case 5: this->currentAnimation = 6; - func_800BDC5C(&this->skelAnime, sAnimations, 6); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); break; } } @@ -342,7 +337,7 @@ void func_80BCF95C(EnHg* this, GlobalContext* globalCtx) { } break; } - func_800EDF24(&this->actor, globalCtx, actionIndex); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); return; } else if (globalCtx->csCtx.state == 0) { func_80BCF354(this); @@ -353,7 +348,7 @@ void func_80BCF95C(EnHg* this, GlobalContext* globalCtx) { void func_80BCFC0C(EnHg* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (this->actor.colChkInfo.health == 1 && !(fabsf(this->actor.yDistToPlayer) >= 80.0f)) { + if (this->actor.colChkInfo.health == 1 && !(fabsf(this->actor.playerHeightRel) >= 80.0f)) { if (player->stateFlags2 & 0x08000000) { if (!D_80BD00C8) { play_sound(NA_SE_SY_TRE_BOX_APPEAR); @@ -362,9 +357,9 @@ void func_80BCFC0C(EnHg* this, GlobalContext* globalCtx) { } else { D_80BD00C8 = false; } - if (globalCtx->msgCtx.unk1202A == 3) { - if (globalCtx->msgCtx.unk1202E == 7 && gSaveContext.playerForm == PLAYER_FORM_HUMAN) { - if (INV_CONTENT(0x41) == 0x41) { + if (globalCtx->msgCtx.ocarinaMode == 3) { + if (globalCtx->msgCtx.unk1202E == 7 && gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + if (INV_CONTENT(ITEM_MASK_GIBDO) == ITEM_MASK_GIBDO) { this->unk218 = 3; } else { this->unk218 = 1; @@ -372,10 +367,10 @@ void func_80BCFC0C(EnHg* this, GlobalContext* globalCtx) { func_80BCF88C(this); } } else { - if (this->actor.xzDistToPlayer < 60.0f && fabsf(this->actor.yDistToPlayer) < 40.0f) { + if (this->actor.xzDistToPlayer < 60.0f && fabsf(this->actor.playerHeightRel) < 40.0f) { if ((this->actionFunc != func_80BCF8A0) && (this->actionFunc != func_80BCF95C)) { - if (!(gSaveContext.weekEventReg[0x3D] & 2)) { - gSaveContext.weekEventReg[0x3D] |= 2; + if (!(gSaveContext.save.weekEventReg[61] & 2)) { + gSaveContext.save.weekEventReg[61] |= 2; this->unk218 = 0; } else { this->unk218 = 2; @@ -401,15 +396,15 @@ void EnHg_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnHg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { - return 0; + return false; } void EnHg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnHg* this = THIS; if (limbIndex == HG_LIMB_HEAD) { - Matrix_CopyCurrentState(&this->unk1D8); + Matrix_Get(&this->unk1D8); } else if (limbIndex == HG_LIMB_PELVIS) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } } @@ -420,8 +415,8 @@ void EnHg_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnHg_OverrideLimbDraw, EnHg_PostLimbDraw, &this->actor); - Matrix_SetCurrentState(&this->unk1D8); + Matrix_Put(&this->unk1D8); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_06005E28); + gSPDisplayList(POLY_OPA_DISP++, object_harfgibud_DL_005E28); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 3a206e0c4..a16e0d94a 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c @@ -1,6 +1,13 @@ -#include "z_en_hgo.h" +/* + * File: z_en_hgo.c + * Overlay: ovl_En_Hgo + * Description: Pamela's Father (Gibdo) + */ -#define FLAGS 0x02000019 +#include "z_en_hgo.h" +#include "objects/object_harfgibud/object_harfgibud.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnHgo*)thisx) @@ -9,7 +16,18 @@ void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx); void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BD03EC(EnHgo* this); +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx); +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx); +void func_80BD049C(EnHgo* this); +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx); +void EnHgo_SetupDialogueHandler(EnHgo* this); +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx); +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx); +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx); +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx); + const ActorInit En_Hgo_InitVars = { ACTOR_EN_HGO, ACTORCAT_NPC, @@ -22,54 +40,342 @@ const ActorInit En_Hgo_InitVars = { (ActorFunc)EnHgo_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD0F48 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static AnimationInfo sAnimations[] = { + { &object_harfgibud_Anim_00B644, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_harfgibud_Anim_013684, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_harfgibud_Anim_0152EC, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_harfgibud_Anim_015C70, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_harfgibud_Anim_0165F0, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_harfgibud_Anim_014220, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_harfgibud_Anim_014A9C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 18, 46, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BD0F74 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static TexturePtr sEyeTextures[] = { + object_harfgibud_Tex_011138, + object_harfgibud_Tex_011938, + object_harfgibud_Tex_012138, +}; -extern ColliderCylinderInit D_80BD0F48; -extern CollisionCheckInfoInit2 D_80BD0F74; +void EnHgo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; -extern UNK_TYPE D_0600B644; -extern UNK_TYPE D_0600F248; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_harfgibud_Skel_012A58, &object_harfgibud_Anim_00B644, + this->jointTable, this->morphTable, HGO_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&thisx->colChkInfo, NULL, &sColChkInfoInit); + thisx->targetMode = 6; + this->unk_30C = 0; + this->unk_30E = 0; + this->unk_314 = 0; + this->unk_310 = 0; + this->unk_312 = 0; + if ((gSaveContext.save.weekEventReg[75] & 0x20) || (gSaveContext.save.weekEventReg[52] & 0x20)) { + func_80BD049C(this); + } else { + thisx->draw = NULL; + func_80BD03EC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Init.s") +void EnHgo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD03EC.s") +void func_80BD03EC(EnHgo* this) { + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = func_80BD0410; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0410.s") +void func_80BD0410(EnHgo* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0420.s") +void func_80BD0420(EnHgo* this) { + this->actionFunc = func_80BD0434; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0434.s") +void func_80BD0434(EnHgo* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.focus.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.focus.pos.z; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD049C.s") +void func_80BD049C(EnHgo* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80BD04E0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD04E0.s") +void func_80BD04E0(EnHgo* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { + if (!(this->unk_310 & 4)) { + this->unk_310 |= 4; + Message_StartTextbox(globalCtx, 0x15A5, &this->actor); + this->unk_314 = 0x15A5; // That mask is a gibdo -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD064C.s") + } else { + Message_StartTextbox(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; // can I research that mask + } + } else if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + if (!(this->unk_310 & 1)) { + this->unk_310 |= 1; + Message_StartTextbox(globalCtx, 0x158F, &this->actor); + this->unk_314 = 0x158F; // Isn't this a fairy + } else { + Message_StartTextbox(globalCtx, 0x1593, &this->actor); + this->unk_314 = 0x1593; // Never seen a fairy this lively + } + } else { + if (!(this->unk_310 & 2)) { + this->unk_310 |= 2; + Message_StartTextbox(globalCtx, 0x1595, &this->actor); + this->unk_314 = 0x1595; // ghost radar is reacting + } else { + Message_StartTextbox(globalCtx, 0x1598, &this->actor); + this->unk_314 = 0x1598; // you seem to be similar to a ghost + } + } + EnHgo_SetupDialogueHandler(this); + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0660.s") +void EnHgo_SetupDialogueHandler(EnHgo* this) { + this->actionFunc = EnHgo_DefaultDialogueHandler; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD06FC.s") +void EnHgo_DefaultDialogueHandler(EnHgo* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + case 3: + case 4: + break; + case 5: + func_80BD06FC(this, globalCtx); + break; + case 6: + if (Message_ShouldAdvance(globalCtx)) { + func_80BD049C(this); + } + } + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x71C, 0xB6); + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0898.s") +void func_80BD06FC(EnHgo* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + switch (this->unk_314) { + case 0x158F: + Message_StartTextbox(globalCtx, 0x1590, &this->actor); + this->unk_314 = 0x1590; + break; + case 0x1590: + if (gSaveContext.save.weekEventReg[14] & 4) { + Message_StartTextbox(globalCtx, 0x1591, &this->actor); + this->unk_314 = 0x1591; + break; + } + Message_StartTextbox(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1591: + Message_StartTextbox(globalCtx, 0x1592, &this->actor); + this->unk_314 = 0x1592; + break; + case 0x1593: + Message_StartTextbox(globalCtx, 0x1594, &this->actor); + this->unk_314 = 0x1594; + break; + case 0x1595: + Message_StartTextbox(globalCtx, 0x1596, &this->actor); + this->unk_314 = 0x1596; + break; + case 0x1596: + Message_StartTextbox(globalCtx, 0x1597, &this->actor); + this->unk_314 = 0x1597; + break; + case 0x1598: + Message_StartTextbox(globalCtx, 0x1599, &this->actor); + this->unk_314 = 0x1599; + break; + case 0x15A5: + Message_StartTextbox(globalCtx, 0x15A6, &this->actor); + this->unk_314 = 0x15A6; + break; + case 0x15A6: + Message_StartTextbox(globalCtx, 0x15A7, &this->actor); + this->unk_314 = 0x15A7; + break; + case 0x15A7: + func_801477B4(globalCtx); + func_80BD049C(this); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0B8C.s") +s32 func_80BD0898(EnHgo* this, GlobalContext* globalCtx) { + s32 actionIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Update.s") + if (Cutscene_CheckActorAction(globalCtx, 486)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 486); + if (this->unk_316 != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->unk_316 = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + this->unk_218 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + break; + case 2: + this->actor.draw = EnHgo_Draw; + this->unk_218 = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + break; + case 3: + this->unk_218 = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + break; + case 4: + this->unk_218 = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 4; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + break; + case 6: + this->unk_218 = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + break; + } + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->unk_218) { + case 1: + if ((Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) && (this->unk_312 == 0)) { + this->unk_312 = 1; + if ((gSaveContext.sceneSetupIndex == 0) && + ((globalCtx->csCtx.currentCsIndex == 2) || (globalCtx->csCtx.currentCsIndex == 4))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_GBVO02); + } + } + break; + case 2: + this->unk_218 = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + break; + case 5: + this->unk_218 = 6; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0CF0.s") + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + return true; + } + if ((globalCtx->csCtx.state == 0) && (((gSaveContext.save.weekEventReg[75]) & 0x20)) && + (this->actionFunc == func_80BD0410)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_ELF_MSG2, this->actor.focus.pos.x, this->actor.focus.pos.y, + this->actor.focus.pos.z, 7, 0, 0, 0x7F5A); + func_80BD0420(this); + } + this->unk_316 = 0x63; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/func_80BD0D38.s") +void func_80BD0B8C(EnHgo* this, GlobalContext* globalCtx) { + func_800E9250(globalCtx, &this->actor, &this->unk_300, &this->unk_306, this->actor.focus.pos); + if (this->unk_30E > 2) { + this->unk_30E--; + } else if (this->unk_30E == 2) { + this->unk_30C = 1; + this->unk_30E = 1; + } else if (this->unk_30E == 1) { + this->unk_30C = 2; + this->unk_30E = 0; + } else { + this->unk_30C = 0; + this->unk_30E = 60; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hgo/EnHgo_Draw.s") +void EnHgo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + s32 pad; + + this->actionFunc(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + if (func_80BD0898(this, globalCtx)) { + func_800E8F08(&this->unk_300, &this->unk_306); + } else if (this->actionFunc != func_80BD0410) { + if (this->actionFunc != func_80BD0434) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + func_80BD0B8C(this, globalCtx); + } + } +} + +s32 EnHgo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + rot->x += this->unk_300.y; + rot->z += this->unk_300.x; + } + return false; +} + +void EnHgo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* pos, Actor* thisx) { + EnHgo* this = THIS; + + if (limbIndex == HGO_LIMB_PELVIS) { + Matrix_Get(&this->unk_1D8); + Matrix_MultZero(&this->actor.focus.pos); + } +} + +void EnHgo_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHgo* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->unk_30C])); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnHgo_OverrideLimbDraw, &EnHgo_PostLimbDraw, &this->actor); + Matrix_Put(&this->unk_1D8); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_harfgibud_DL_00F248); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h index 3d7ff6e55..f39aab0fd 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.h @@ -7,11 +7,47 @@ struct EnHgo; typedef void (*EnHgoActionFunc)(struct EnHgo*, GlobalContext*); +// Shares the same setup as en_hg +typedef enum { + /* 00 */ HGO_LIMB_NONE, + /* 01 */ HGO_LIMB_ABDOMEN, + /* 02 */ HGO_LIMB_CHEST, + /* 03 */ HGO_LIMB_SHOULDER_LEFT, + /* 04 */ HGO_LIMB_ARM_LEFT, + /* 05 */ HGO_LIMB_HAND_LEFT, + /* 06 */ HGO_LIMB_SHOULDER_RIGHT, + /* 07 */ HGO_LIMB_ARM_RIGHT, + /* 08 */ HGO_LIMB_HAND_RIGHT, + /* 09 */ HGO_LIMB_EYEBROW, + /* 10 */ HGO_LIMB_HEAD, + /* 11 */ HGO_LIMB_PELVIS, + /* 12 */ HGO_LIMB_THIGH_LEFT, + /* 13 */ HGO_LIMB_LEG_LEFT, + /* 14 */ HGO_LIMB_FOOT_LEFT, + /* 15 */ HGO_LIMB_THIGH_RIGHT, + /* 16 */ HGO_LIMB_LEG_RIGHT, + /* 17 */ HGO_LIMB_FOOT_RIGHT, + /* 18 */ HGO_LIMB_UNK, + /* 19 */ HGO_LIMB_MAX, +} ObjectHgoLimbs; + typedef struct EnHgo { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; - /* 0x01D4 */ EnHgoActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x140]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ EnHgoActionFunc actionFunc; + /* 0x1D8 */ MtxF unk_1D8; + /* 0x218 */ s32 unk_218; + /* 0x21C */ Vec3s jointTable[HGO_LIMB_MAX]; + /* 0x28E */ Vec3s morphTable[HGO_LIMB_MAX]; + /* 0x300 */ Vec3s unk_300; + /* 0x306 */ Vec3s unk_306; + /* 0x30C */ s16 unk_30C; + /* 0x30E */ s16 unk_30E; + /* 0x310 */ s16 unk_310; + /* 0x312 */ s16 unk_312; + /* 0x314 */ u16 unk_314; + /* 0x316 */ u16 unk_316; } EnHgo; // size = 0x318 extern const ActorInit En_Hgo_InitVars; diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c index 03fb8e965..e1432c10a 100644 --- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c +++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.c @@ -1,6 +1,13 @@ -#include "z_en_hidden_nuts.h" +/* + * File: z_en_hidden_nuts.c + * Overlay: ovl_En_Hidden_Nuts + * Description: Swamp Spider House - Sleeping Deku Scrub + */ -#define FLAGS 0x02000009 +#include "z_en_hidden_nuts.h" +#include "objects/object_hintnuts/object_hintnuts.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_2000000) #define THIS ((EnHiddenNuts*)thisx) @@ -9,15 +16,20 @@ void EnHiddenNuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHiddenNuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnHiddenNuts_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80BDB268(EnHiddenNuts* this); void func_80BDB2B8(EnHiddenNuts* this, GlobalContext* globalCtx); +void func_80BDB580(EnHiddenNuts* this); void func_80BDB59C(EnHiddenNuts* this, GlobalContext* globalCtx); +void func_80BDB788(EnHiddenNuts* this); void func_80BDB7E8(EnHiddenNuts* this, GlobalContext* globalCtx); void func_80BDB8F4(EnHiddenNuts* this, GlobalContext* globalCtx); +void func_80BDB930(EnHiddenNuts* this); void func_80BDB978(EnHiddenNuts* this, GlobalContext* globalCtx); +void func_80BDBA28(EnHiddenNuts* this, GlobalContext* globalCtx); void func_80BDBB48(EnHiddenNuts* this, GlobalContext* globalCtx); +void func_80BDBE70(EnHiddenNuts* this, GlobalContext* globalCtx); void func_80BDBED4(EnHiddenNuts* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Hidden_Nuts_InitVars = { ACTOR_EN_HIDDEN_NUTS, ACTORCAT_PROP, @@ -30,51 +42,397 @@ const ActorInit En_Hidden_Nuts_InitVars = { (ActorFunc)EnHiddenNuts_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BDC0D0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, 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 | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 30, 20, 0, { 0, 0, 0 } }, }; -#endif +static AnimationHeader* D_80BDC0FC[] = { + &object_hintnuts_Anim_000168, &object_hintnuts_Anim_0024CC, &object_hintnuts_Anim_0026C4, + &object_hintnuts_Anim_002894, &object_hintnuts_Anim_002B90, &object_hintnuts_Anim_002F7C, + &object_hintnuts_Anim_003128, &object_hintnuts_Anim_0029BC, &object_hintnuts_Anim_0024CC, +}; -extern ColliderCylinderInit D_80BDC0D0; +u8 D_80BDC120[] = { + ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_ONCE, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_LOOP, +}; -extern UNK_TYPE D_060024CC; +void EnHiddenNuts_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHiddenNuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/EnHiddenNuts_Init.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_hintnuts_Skel_0023B8.sh, &object_hintnuts_Anim_0024CC, + this->jointTable, this->morphTable, 10); + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/EnHiddenNuts_Destroy.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB1B4.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB268.s") + this->unk_21E = ENHIDDENNUTS_GET_F80(&this->actor); + this->switchFlag = ENHIDDENNUTS_GET_SWITCHFLAG(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB2B8.s") + if (this->switchFlag == 0x7F) { + this->switchFlag = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB580.s") + if ((this->switchFlag >= 0) && Flags_GetSwitch(globalCtx, this->switchFlag)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB59C.s") + if (this->unk_21E == 0x1F) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB788.s") + this->path = SubS_GetPathByIndex(globalCtx, this->unk_21E, 0x3F); + this->unk_226 = this->actor.cutscene; + func_801A5080(2); + func_80BDB268(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB7E8.s") +void EnHiddenNuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHiddenNuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB8F4.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB930.s") +void func_80BDB1B4(EnHiddenNuts* this, s32 arg1) { + f32 sp34; + f32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDB978.s") + this->unk_220 = arg1; + sp34 = 0.0f; + sp30 = -4.0f; + this->unk_22C = Animation_GetLastFrame(D_80BDC0FC[arg1]); + if (this->unk_220 == 1) { + sp34 = this->unk_22C; + sp30 = 0.0f; + } + Animation_Change(&this->skelAnime, D_80BDC0FC[this->unk_220], 1.0f, sp34, this->unk_22C, D_80BDC120[this->unk_220], + sp30); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDBA28.s") +void func_80BDB268(EnHiddenNuts* this) { + this->actor.textId = 0x234; + this->unk_228 = 1600.0f; + this->actor.shape.yOffset = 1600.0f; + func_80BDB1B4(this, 1); + this->unk_21A = 0; + this->actionFunc = func_80BDB2B8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDBB48.s") +void func_80BDB2B8(EnHiddenNuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDBE70.s") + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NEMURI_SLEEP - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/func_80BDBED4.s") + if (player->stateFlags2 & 0x8000000) { + if (this->unk_20A == 0) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + this->unk_20A = 1; + } + } else { + this->unk_20A = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/EnHiddenNuts_Update.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + func_80BDB580(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hidden_Nuts/EnHiddenNuts_Draw.s") + if (this->unk_218 == 0) { + Vec3f sp94 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp88 = { 0.0f, 0.0f, 0.0f }; + Color_RGBA8 sp84 = { 255, 255, 255, 255 }; + Color_RGBA8 sp80 = { 150, 150, 150, 0 }; + Vec3f sp74; + + for (i = 0; i < 3; i++) { + sp94.y = Rand_ZeroFloat(1.0f) + 1.0f; + + Math_Vec3f_Copy(&sp74, &this->actor.world.pos); + + sp74.x += randPlusMinusPoint5Scaled(15.0f); + sp74.z += randPlusMinusPoint5Scaled(15.0f); + + EffectSsDtBubble_SpawnCustomColor(globalCtx, &sp74, &sp94, &sp88, &sp84, &sp80, Rand_S16Offset(120, 90), 30, + 1); + } + this->unk_218 = 30; + } + + if (!(this->actor.xzDistToPlayer > 120.0f)) { + if ((globalCtx->msgCtx.ocarinaMode == 3) && (globalCtx->msgCtx.unk1202E == 0)) { + globalCtx->msgCtx.ocarinaMode = 4; + func_80BDB788(this); + } else if (func_801A5100() == 2) { + func_80BDB788(this); + } else { + func_800B8614(&this->actor, globalCtx, BREG(13) + 100.0f); + } + } +} + +void func_80BDB580(EnHiddenNuts* this) { + this->unk_21A = 1; + this->actionFunc = func_80BDB59C; +} + +void func_80BDB59C(EnHiddenNuts* this, GlobalContext* globalCtx) { + s32 i; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NEMURI_SLEEP - SFX_FLAG); + + if (this->unk_218 == 0) { + Vec3f sp98 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp8C = { 0.0f, 0.0f, 0.0f }; + Color_RGBA8 sp88 = { 255, 255, 255, 255 }; + Color_RGBA8 sp84 = { 150, 150, 150, 0 }; + Vec3f sp78; + + for (i = 0; i < 3; i++) { + sp98.y = Rand_ZeroFloat(1.0f) + 1.0f; + + Math_Vec3f_Copy(&sp78, &this->actor.world.pos); + + sp78.x += randPlusMinusPoint5Scaled(15.0f); + sp78.z += randPlusMinusPoint5Scaled(15.0f); + + EffectSsDtBubble_SpawnCustomColor(globalCtx, &sp78, &sp98, &sp8C, &sp88, &sp84, Rand_S16Offset(120, 90), 30, + 1); + } + this->unk_218 = 30; + } + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + func_80BDB268(this); + } +} + +void func_80BDB788(EnHiddenNuts* this) { + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_8000000; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DEAD); + this->unk_21A = 2; + this->actionFunc = func_80BDB7E8; +} + +void func_80BDB7E8(EnHiddenNuts* this, GlobalContext* globalCtx) { + Vec3f sp3C; + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_226); + return; + } + + if (!ActorCutscene_GetCanPlayNext(this->unk_226)) { + ActorCutscene_SetIntentToPlay(this->unk_226); + return; + } + + ActorCutscene_StartAndSetUnkLinkFields(this->unk_226, &this->actor); + this->unk_228 = -1200.0f; + + Math_Vec3f_Copy(&sp3C, &this->actor.world.pos); + sp3C.y = this->actor.floorHeight + 30.0f; + + EffectSsHahen_SpawnBurst(globalCtx, &sp3C, 4.0f, 0, 10, 3, 15, -1, 10, NULL); + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + func_80BDB1B4(this, 7); + this->actionFunc = func_80BDB8F4; +} + +void func_80BDB8F4(EnHiddenNuts* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_22C <= curFrame) { + func_80BDB930(this); + } +} + +void func_80BDB930(EnHiddenNuts* this) { + func_80BDB1B4(this, 3); + this->unk_21A = 3; + this->unk_228 = 500.0f; + this->actionFunc = func_80BDB978; +} + +void func_80BDB978(EnHiddenNuts* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 8.0f) || + Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUT_FAINT); + } + + if (this->unk_22C <= curFrame) { + this->unk_224++; + if (this->unk_224 >= 2) { + func_80BDBA28(this, globalCtx); + } + } +} + +void func_80BDBA28(EnHiddenNuts* this, GlobalContext* globalCtx) { + Vec3f sp44; + + func_80BDB1B4(this, 2); + this->unk_228 = 0.0f; + + Math_Vec3f_Copy(&sp44, &this->actor.world.pos); + sp44.y = this->actor.floorHeight + 30.0f; + + EffectSsHahen_SpawnBurst(globalCtx, &sp44, 4.0f, 0, 10, 3, 15, -1, 10, NULL); + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + this->unk_208 = 1; + + if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, this->unk_208, &this->unk_20C)) { + Actor_MarkForDeath(&this->actor); + } + + this->actor.speedXZ = 2.0f; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 4.0f; + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_20C); + this->unk_21A = 4; + this->actionFunc = func_80BDBB48; +} + +void func_80BDBB48(EnHiddenNuts* this, GlobalContext* globalCtx) { + s32 pad[3]; + f32 sp58 = this->skelAnime.curFrame; + WaterBox* sp54; + f32 sp50; + s16 sp4E = 0; + Vec3f sp40; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp50, + &sp54) && + (this->actor.world.pos.y < sp50)) { + this->actor.velocity.y = 0.0f; + Math_Vec3f_Copy(&sp40, &this->actor.world.pos); + sp40.y = sp50; + this->actor.gravity = 0.0f; + + if ((globalCtx->gameplayFrames % 8) == 0) { + EffectSsGRipple_Spawn(globalCtx, &sp40, 650, 3150, 0); + } + + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f) || + Animation_OnFrame(&this->skelAnime, 10.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WALK_WATER); + sp4E = 1; + } + } + + if ((sp4E != 0) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f) || + Animation_OnFrame(&this->skelAnime, 10.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); + } + + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_20C), 1, 0x1388, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 1, 0x3E8, 0); + + if (this->unk_220 == 2) { + if (this->unk_22C <= sp58) { + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + func_80BDB1B4(this, 6); + } + } else { + Math_ApproachF(&this->actor.world.pos.x, this->unk_20C.x, 0.5f, + fabsf(Math_SinS(this->actor.world.rot.y) * (BREG(33) + 8.0f))); + Math_ApproachF(&this->actor.world.pos.z, this->unk_20C.z, 0.5f, + fabsf(Math_CosS(this->actor.world.rot.y) * (BREG(33) + 8.0f))); + + if ((sqrtf(SQ(this->actor.world.pos.x - this->unk_20C.x) + SQ(this->actor.world.pos.z - this->unk_20C.z)) < + 4.0f) && + (this->path != NULL)) { + this->unk_208++; + if (this->unk_208 >= this->path->count) { + func_80BDBE70(this, globalCtx); + } else if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, this->unk_208, &this->unk_20C)) { + Actor_MarkForDeath(&this->actor); + } + } + } +} + +void func_80BDBE70(EnHiddenNuts* this, GlobalContext* globalCtx) { + if (this->switchFlag >= 0) { + Flags_SetSwitch(globalCtx, this->switchFlag); + } + func_80BDB1B4(this, 8); + this->unk_21A = 5; + this->actionFunc = func_80BDBED4; +} + +void func_80BDBED4(EnHiddenNuts* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + Vec3f sp38; + + if (this->unk_22C <= curFrame) { + Math_Vec3f_Copy(&sp38, &this->actor.world.pos); + sp38.y = this->actor.floorHeight; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + EffectSsHahen_SpawnBurst(globalCtx, &sp38, 4.0f, 0, 10, 3, 15, -1, 10, NULL); + Actor_MarkForDeath(&this->actor); + } +} + +void EnHiddenNuts_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHiddenNuts* this = THIS; + + if (this->unk_218 != 0) { + this->unk_218--; + } + + Actor_SetFocus(&this->actor, 20.0f); + SkelAnime_Update(&this->skelAnime); + + this->actionFunc(this, globalCtx); + + Math_ApproachF(&this->actor.shape.yOffset, this->unk_228, 0.5f, 200.0f); + + if (this->unk_21A >= 4) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 40.0f, 0x1D); + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnHiddenNuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHiddenNuts* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h index 08dc574fe..baff911b6 100644 --- a/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h +++ b/src/overlays/actors/ovl_En_Hidden_Nuts/z_en_hidden_nuts.h @@ -7,11 +7,30 @@ struct EnHiddenNuts; typedef void (*EnHiddenNutsActionFunc)(struct EnHiddenNuts*, GlobalContext*); +#define ENHIDDENNUTS_GET_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) +#define ENHIDDENNUTS_GET_F80(thisx) (((thisx)->params >> 7) & 0x1F) + typedef struct EnHiddenNuts { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xBC]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[10]; + /* 0x01C4 */ Vec3s morphTable[10]; /* 0x0200 */ EnHiddenNutsActionFunc actionFunc; - /* 0x0204 */ char unk_204[0x7C]; + /* 0x0204 */ Path* path; + /* 0x0208 */ s16 unk_208; + /* 0x020A */ u8 unk_20A; + /* 0x020C */ Vec3f unk_20C; + /* 0x0218 */ s16 unk_218; + /* 0x021A */ s16 unk_21A; + /* 0x021C */ s16 switchFlag; + /* 0x021E */ s16 unk_21E; + /* 0x0220 */ s32 unk_220; + /* 0x0224 */ s16 unk_224; + /* 0x0226 */ s16 unk_226; + /* 0x0228 */ f32 unk_228; + /* 0x022C */ f32 unk_22C; + /* 0x0230 */ UNK_TYPE1 unk230[4]; + /* 0x0234 */ ColliderCylinder collider; } EnHiddenNuts; // size = 0x280 extern const ActorInit En_Hidden_Nuts_InitVars; diff --git a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c index c9436c9d9..c9b9485ce 100644 --- a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c +++ b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.c @@ -1,6 +1,13 @@ -#include "z_en_hint_skb.h" +/* + * File: z_en_hint_skb.c + * Overlay: ovl_En_Hint_Skb + * Description: Stalchild that gives hints in Oceanside Spider House + */ -#define FLAGS 0x00000019 +#include "z_en_hint_skb.h" +#include "objects/object_skb/object_skb.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnHintSkb*)thisx) @@ -9,19 +16,28 @@ void EnHintSkb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHintSkb_Update(Actor* thisx, GlobalContext* globalCtx); void EnHintSkb_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80C1FE0C(EnHintSkb* this); void func_80C1FE20(EnHintSkb* this, GlobalContext* globalCtx); void func_80C1FE80(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C1FF30(EnHintSkb* this); void func_80C1FF88(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C2003C(EnHintSkb* this); void func_80C200B8(EnHintSkb* this, GlobalContext* globalCtx); void func_80C2016C(EnHintSkb* this, GlobalContext* globalCtx); void func_80C20334(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C20484(EnHintSkb* this); void func_80C204F0(EnHintSkb* this, GlobalContext* globalCtx); void func_80C20590(EnHintSkb* this, GlobalContext* globalCtx); void func_80C2069C(EnHintSkb* this, GlobalContext* globalCtx); void func_80C2077C(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C208BC(EnHintSkb* this); void func_80C208D0(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C20B88(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C20C24(EnHintSkb* this, GlobalContext* globalCtx); +s32 func_80C21414(EnHintSkb* this); +void func_80C21468(EnHintSkb* this, GlobalContext* globalCtx); +void func_80C215E4(GlobalContext* globalCtx, EnHintSkb* this, Vec3f* arg2); -#if 0 const ActorInit En_Hint_Skb_InitVars = { ACTOR_EN_HINT_SKB, ACTORCAT_NPC, @@ -34,29 +50,47 @@ const ActorInit En_Hint_Skb_InitVars = { (ActorFunc)EnHintSkb_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80C21C80[2] = { +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_80C21CC8 = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_80C21C80, // 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_80C21CD8 = { 2, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 2, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80C21CE4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0xD), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -91,96 +125,787 @@ static DamageTable D_80C21CE4 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C21E3C[] = { +static AnimationInfo sAnimations[] = { + { &object_skb_Anim_0064E0, 0.96f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &object_skb_Anim_002190, 0.6f, 0.0f, 0.0f, ANIMMODE_ONCE_INTERP, 4.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0f }, + { &object_skb_Anim_00270C, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0f }, + { &object_skb_Anim_00697C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_006D90, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_001D1C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -16.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_0015EC, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_0009E4, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), }; -#endif +void EnHintSkb_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHintSkb* this = THIS; -extern ColliderJntSphElementInit D_80C21C80[2]; -extern ColliderJntSphInit D_80C21CC8; -extern CollisionCheckInfoInit2 D_80C21CD8; -extern DamageTable D_80C21CE4; -extern InitChainEntry D_80C21E3C[]; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_00697C, this->jointTable, + this->morphtable, 20); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElement); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.hintId = 0x55; + this->unk_3E4 = 0; + this->unk_3DE = 0; + this->unk_3E0 = 0; + this->unk_3DC = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + func_80C1FE0C(this); +} -extern UNK_TYPE D_06002190; -extern UNK_TYPE D_06003584; -extern UNK_TYPE D_0600697C; +void EnHintSkb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHintSkb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/EnHintSkb_Init.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/EnHintSkb_Destroy.s") +void func_80C1FE0C(EnHintSkb* this) { + this->actionFunc = func_80C1FE20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FE0C.s") +void func_80C1FE20(EnHintSkb* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FE20.s") +void func_80C1FE30(EnHintSkb* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actor.speedXZ = 1.6f; + this->actionFunc = func_80C1FE80; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FE30.s") +void func_80C1FE80(EnHintSkb* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 15.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_WALK); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 750, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Actor_IsFacingPlayer(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f)) { + func_80C1FF30(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FE80.s") +void func_80C1FF30(EnHintSkb* this) { + this->collider.base.atFlags &= ~AT_BOUNCED; + this->actor.speedXZ = 0.0f; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80C1FF88; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FF30.s") +void func_80C1FF88(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->collider.base.atFlags & AT_BOUNCED) { + this->collider.base.atFlags &= ~(AT_BOUNCED | AT_HIT); + func_80C2003C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C1FF88.s") + if (Animation_OnFrame(&this->skelAnime, 3.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2003C.s") + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (func_80C21414(this) && (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN)) { + func_80C1FF30(this); + } else { + func_80C1FE30(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C200B8.s") +void func_80C2003C(EnHintSkb* this) { + Animation_Change(&this->skelAnime, &object_skb_Anim_002190, -0.4f, this->skelAnime.curFrame - 1.0f, 0.0f, 3, 0.0f); + this->collider.base.atFlags &= ~AT_BOUNCED; + this->actionFunc = func_80C200B8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2011C.s") +void func_80C200B8(EnHintSkb* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (func_80C21414(this)) { + func_80C1FF30(this); + } else { + func_80C1FE30(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2016C.s") +void func_80C2011C(EnHintSkb* this) { + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = func_80C2016C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20274.s") +void func_80C2016C(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 2) { + this->actor.speedXZ = 0.0f; + } else if (this->actor.bgCheckFlags & 1) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.05f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20334.s") + if ((this->actor.colorFilterTimer == 0) && (this->actor.bgCheckFlags & 1)) { + if (this->actor.colChkInfo.health == 0) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80C20484(this); + } else if (this->skelAnime.animation == &object_skb_Anim_00697C) { + func_80C1FE0C(this); + } else if (func_80C21414(this)) { + func_80C1FF30(this); + } else { + func_80C1FE30(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20484.s") +void func_80C20274(EnHintSkb* this) { + if (this->skelAnime.animation == &object_skb_Anim_00697C) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); + this->actor.gravity = -1.0f; + this->actor.speedXZ = 1.0f; + } else { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = -4.0f; + } + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->actionFunc = func_80C20334; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C204F0.s") +void func_80C20334(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 2) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20540.s") + for (i = 0; i < 10; i++) { + func_80C215E4(globalCtx, this, &this->actor.world.pos); + } + this->actor.speedXZ = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20590.s") + if (this->actor.bgCheckFlags & 1) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.05f; + } else if (this->actor.speedXZ != 0.0f) { + this->actor.speedXZ -= 0.05f; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 2500, 0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2066C.s") + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 16, 2000, 100); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2069C.s") + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (this->actor.bgCheckFlags & 1)) { + this->actor.world.rot = this->actor.shape.rot; + func_80C1FE30(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2075C.s") +void func_80C20484(EnHintSkb* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + this->unk_3E8 |= 4; + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = -6.0f; + } + this->actionFunc = func_80C204F0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C2077C.s") +void func_80C204F0(EnHintSkb* this, GlobalContext* globalCtx) { + if (!(this->unk_3E8 & 8)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C208BC.s") + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x10); + Actor_MarkForDeath(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C208D0.s") +void func_80C20540(EnHintSkb* this) { + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = func_80C20590; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20A74.s") +void func_80C20590(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; + if (this->actor.colChkInfo.health != 0) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_3E8 |= 1; + func_80C20274(this); + } else { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80C20484(this); + } + } else if (this->drawDmgEffTimer == 1) { + func_80C21468(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20B88.s") +void func_80C2066C(EnHintSkb* this) { + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + this->actionFunc = func_80C2069C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20C24.s") +void func_80C2069C(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; + if (this->actor.colChkInfo.health != 0) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_3E8 |= 1; + func_80C20274(this); + } else { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80C20484(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20D64.s") +void func_80C2075C(EnHintSkb* this) { + this->unk_3E0 = 0; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80C2077C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C20E90.s") +void func_80C2077C(EnHintSkb* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_3E0 = 1; + if (this->unk_3DC == 0) { + this->unk_3DC = 1; + Message_StartTextbox(globalCtx, 0x1147, &this->actor); + this->unk_3E6 = 0x1147; + if (this->skelAnime.animation == &object_skb_Anim_00697C) { + globalCtx->msgCtx.msgMode = 0x44; + this->actor.speedXZ = 2.4f; + this->actor.gravity = -1.0f; + this->actor.velocity.y = 3.0f; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); + } + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 11); + Message_StartTextbox(globalCtx, 0x1148, &this->actor); + this->unk_3E6 = 0x1148; + } + func_80C208BC(this); + } else if ((this->actor.xzDistToPlayer < 100.0f) && !(this->collider.base.acFlags & AC_HIT)) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C21250.s") +void func_80C208BC(EnHintSkb* this) { + this->actionFunc = func_80C208D0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C21320.s") +void func_80C208D0(EnHintSkb* this, GlobalContext* globalCtx) { + this->unk_3DE = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C21414.s") + switch (Message_GetState(&globalCtx->msgCtx)) { + case 3: + if ((globalCtx->gameplayFrames % 2) != 0) { + this->unk_3DE = 1; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C21468.s") + case 4: + func_80C20B88(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C215E4.s") + case 5: + func_80C20C24(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/EnHintSkb_Update.s") + case 6: + if (Message_ShouldAdvance(globalCtx)) { + func_80C2075C(this); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C21858.s") + case 0: + case 1: + case 2: + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/func_80C219D4.s") + if (this->unk_3E6 == 0x1147) { + if (this->actor.bgCheckFlags & 2) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hint_Skb/EnHintSkb_Draw.s") + this->actor.speedXZ = 0.0f; + + for (i = 0; i < 10; i++) { + func_80C215E4(globalCtx, this, &this->actor.world.pos); + } + } + + if ((this->skelAnime.animation == &object_skb_Anim_003584) && + Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Message_StartTextbox(globalCtx, 0x1147, &this->actor); + this->unk_3E6 = 0x1147; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + } + } + + if (this->actor.bgCheckFlags & 1) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 5, 0x71C, 0xB6); + this->actor.shape.rot.y = this->actor.world.rot.y; + } +} + +void func_80C20A74(EnHintSkb* this, GlobalContext* globalCtx) { + s32 params = ENHINTSKB_GET_FF(&this->actor); + + switch (params) { + case 1: + Message_StartTextbox(globalCtx, 0x1149, &this->actor); + this->unk_3E6 = 0x1149; + break; + + case 2: + Message_StartTextbox(globalCtx, 0x114A, &this->actor); + this->unk_3E6 = 0x114A; + break; + + case 3: + Message_StartTextbox(globalCtx, 0x114B, &this->actor); + this->unk_3E6 = 0x114B; + break; + + case 4: + Message_StartTextbox(globalCtx, 0x114C, &this->actor); + this->unk_3E6 = 0x114C; + break; + + case 5: + Message_StartTextbox(globalCtx, 0x114D, &this->actor); + this->unk_3E6 = 0x114D; + break; + + case 6: + Message_StartTextbox(globalCtx, 0x114E, &this->actor); + this->unk_3E6 = 0x114E; + break; + + default: + Message_StartTextbox(globalCtx, 0x1149, &this->actor); + this->unk_3E6 = 0x1149; + break; + } +} + +void func_80C20B88(EnHintSkb* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + this->unk_3E8 |= 0x10; + Message_StartTextbox(globalCtx, 0x1150, &this->actor); + this->unk_3E6 = 0x1150; + } else { + func_8019F230(); + Message_StartTextbox(globalCtx, 0x1152, &this->actor); + this->unk_3E6 = 0x1152; + } + } +} + +void func_80C20C24(EnHintSkb* this, GlobalContext* globalCtx) { + if (!Message_ShouldAdvance(globalCtx)) { + return; + } + + switch (this->unk_3E6) { + case 0x1147: + Message_StartTextbox(globalCtx, 0x1148, &this->actor); + this->unk_3E6 = 0x1148; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 11); + break; + + case 0x1148: + func_80C20A74(this, globalCtx); + break; + + case 0x1149: + case 0x114A: + case 0x114B: + case 0x114C: + case 0x114D: + case 0x114E: + Message_StartTextbox(globalCtx, 0x114F, &this->actor); + this->unk_3E6 = 0x114F; + break; + + case 0x1152: + Message_StartTextbox(globalCtx, 0x1151, &this->actor); + this->unk_3E6 = 0x1151; + break; + + case 0x1150: + Message_StartTextbox(globalCtx, 0x1151, &this->actor); + this->unk_3E6 = 0x1151; + break; + + case 0x1151: + func_801477B4(globalCtx); + if (this->unk_3E8 & 0x10) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80C20484(this); + } else { + func_80C2075C(this); + } + break; + } +} + +void func_80C20D64(EnHintSkb* this, GlobalContext* globalCtx) { + if ((this->actionFunc == func_80C1FE20) || (this->actionFunc == func_80C2077C) || + (this->actionFunc == func_80C1FE80)) { + if (this->actionFunc != func_80C2077C) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.hintId = 255; + this->actor.textId = 0; + if (this->actionFunc == func_80C1FE80) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 12); + } + func_80C2075C(this); + } + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.hintId = 0x55; + this->actor.textId = 0; + if (this->skelAnime.animation == &object_skb_Anim_00697C) { + func_80C1FE0C(this); + } else { + func_80C1FE30(this); + } + } + } +} + +void func_80C20E90(EnHintSkb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((this->actor.bgCheckFlags & 0x60) && (this->actor.depthInWater >= 40.0f)) { + this->actor.colChkInfo.health = 0; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80C20484(this); + return; + } + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->actionFunc == func_80C20590) { + switch (this->actor.colChkInfo.damageEffect) { + case 1: + case 3: + case 4: + case 12: + case 13: + return; + + default: + case 2: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + if (this->drawDmgEffTimer > 1) { + func_80C21468(this, globalCtx); + } + this->drawDmgEffTimer = 0; + break; + } + } + + if (!Actor_ApplyDamage(&this->actor)) { + if ((this->actor.colChkInfo.damageEffect != 3) && (this->actor.colChkInfo.damageEffect != 4)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + this->unk_3E8 |= 4; + func_80C20484(this); + return; + } + } + + switch (this->actor.colChkInfo.damageEffect) { + case 11: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffTimer = 40; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0, 120, 0, 40); + func_80C2011C(this); + break; + + case 1: + Actor_SetColorFilter(&this->actor, 0, 120, 0, 40); + func_80C2011C(this); + break; + + case 2: + this->drawDmgEffTimer = 80; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_3E8 |= 1; + func_80C20274(this); + break; + case 3: + if (this->actor.colChkInfo.health != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->drawDmgEffTimer = 80; + } else { + this->drawDmgEffTimer = 3; + } + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + func_80C20540(this); + break; + case 4: + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + func_80C2066C(this); + break; + + case 12: + case 14: + this->unk_3E8 |= 1; + + case 15: + if ((player->swordAnimation == 4) || (player->swordAnimation == 11) || (player->swordAnimation == 22) || + (player->swordAnimation == 23)) { + this->unk_3E8 |= 1; + } + + case 13: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + func_80C20274(this); + break; + + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + break; + } + } +} + +void func_80C21250(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->unk_3E0 != 1) { + func_80C20E90(this, globalCtx); + if (this->actionFunc == func_80C1FF88) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if ((this->actionFunc != func_80C200B8) && (this->actionFunc != func_80C20334) && + (this->actionFunc != func_80C204F0)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80C21320(EnHintSkb* this, GlobalContext* globalCtx) { + if (this->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; + } + + if (this->actionFunc != func_80C20590) { + if (this->drawDmgEffTimer < 20) { + if (this->actionFunc == func_80C2069C) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.01f, 0.0f); + } + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.5f, 0.1f, 0.02f, 0.0f); + } + } +} + +s32 func_80C21414(EnHintSkb* this) { + if (Actor_IsFacingPlayer(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f)) { + return true; + } + return false; +} + +void func_80C21468(EnHintSkb* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_80C21E44 = { 170, 255, 255, 255 }; + static Color_RGBA8 D_80C21E48 = { 200, 200, 255, 255 }; + static Vec3f D_80C21E4C = { 0.0f, -1.0f, 0.0f }; + Vec3f sp84; + s32 phi_s4; + s16 temp_s1; + s32 i; + + if (this->unk_3E8 & 2) { + phi_s4 = ARRAY_COUNT(this->limbPos) - 1; + } else { + phi_s4 = ARRAY_COUNT(this->limbPos); + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + + for (i = 0; i < phi_s4; i++) { + temp_s1 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->limbPos[i]); + + sp84.x = Math_SinS(temp_s1) * 3.0f; + sp84.z = Math_CosS(temp_s1) * 3.0f; + sp84.y = (Rand_ZeroOne() * 4.0f) + 4.0f; + + EffectSsEnIce_Spawn(globalCtx, &this->limbPos[i], 0.6f, &sp84, &D_80C21E4C, &D_80C21E44, &D_80C21E48, 30); + } +} + +void func_80C215E4(GlobalContext* globalCtx, EnHintSkb* this, Vec3f* arg2) { + Vec3f sp5C; + Vec3f sp50 = { 0.0f, 8.0f, 0.0f }; + Vec3f sp44 = { 0.0f, -1.5f, 0.0f }; + f32 sp40 = (Rand_ZeroOne() - 0.5f) * 6.28f; + s32 pad; + + sp5C.y = this->actor.floorHeight; + sp5C.x = (sin_rad(sp40) * 15.0f) + arg2->x; + sp5C.z = (cos_rad(sp40) * 15.0f) + arg2->z; + + sp44.x = randPlusMinusPoint5Scaled(1.0f); + sp44.z = randPlusMinusPoint5Scaled(1.0f); + + sp50.y += (Rand_ZeroOne() - 0.5f) * 4.0f; + + EffectSsHahen_Spawn(globalCtx, &sp5C, &sp50, &sp44, 0, ((Rand_ZeroOne() * 5.0f) + 12.0f) * 0.8f, -1, 10, NULL); + func_800BBFB0(globalCtx, &sp5C, 10.0f, 1, 150, 0, 1); +} + +void EnHintSkb_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHintSkb* this = THIS; + + this->actionFunc(this, globalCtx); + + if ((this->actionFunc != func_80C2016C) && (this->actionFunc != func_80C20590) && + (this->actionFunc != func_80C2069C)) { + SkelAnime_Update(&this->skelAnime); + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 60.0f, 0x1D); + func_80C21250(this, globalCtx); + func_80C20D64(this, globalCtx); + func_80C21320(this, globalCtx); +} + +s32 EnHintSkb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnHintSkb* this = THIS; + f32 temp_f10; + + if (limbIndex == 11) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + temp_f10 = fabsf(Math_SinS(globalCtx->state.frames * 6000) * 95.0f) + 160.0f; + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, (s16)temp_f10, (s16)temp_f10, (s16)temp_f10, 255); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (limbIndex == 10) { + Matrix_MultZero(&this->actor.focus.pos); + } else if ((limbIndex == 12) && (this->unk_3DE == 1)) { + Matrix_RotateZS(0x71C, MTXMODE_APPLY); + } + + if (((limbIndex == 11) || (limbIndex == 12)) && (this->unk_3E8 & 2)) { + *dList = NULL; + } + + return false; +} + +void EnHintSkb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80C21E70 = { 800.0f, 1200.0f, 0.0f }; + EnHintSkb* this = THIS; + + if (!(this->unk_3E8 & 8)) { + Collider_UpdateSpheres(limbIndex, &this->collider); + + if ((limbIndex == 11) && (this->unk_3E8 & 1) && !(this->unk_3E8 & 2)) { + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); + this->unk_3E8 |= 2; + } else if ((this->unk_3E8 & 4) && !(this->unk_3E8 & 8) && ((limbIndex != 11) || !(this->unk_3E8 & 1)) && + (limbIndex != 12)) { + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); + } + + if (this->drawDmgEffTimer != 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_MultZero(&this->limbPos[this->limbCount]); + this->limbCount++; + } else if ((limbIndex == 11) && !(this->unk_3E8 & 2)) { + Matrix_MultVec3f(&D_80C21E70, &this->limbPos[this->limbCount]); + this->limbCount++; + } + } + } +} + +void EnHintSkb_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHintSkb* this = THIS; + + this->limbCount = 0; + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnHintSkb_OverrideLimbDraw, + EnHintSkb_PostLimbDraw, &this->actor); + if (this->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, this->limbCount, this->drawDmgEffScale, 0.5f, + this->drawDmgEffAlpha, this->drawDmgEffType); + } + + if (this->unk_3E8 & 4) { + this->unk_3E8 |= 8; + } +} diff --git a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.h b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.h index b6b98fc46..b67e56352 100644 --- a/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.h +++ b/src/overlays/actors/ovl_En_Hint_Skb/z_en_hint_skb.h @@ -7,11 +7,29 @@ struct EnHintSkb; typedef void (*EnHintSkbActionFunc)(struct EnHintSkb*, GlobalContext*); +#define ENHINTSKB_GET_FF(thisx) ((thisx)->params & 0xFF) + typedef struct EnHintSkb { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xE4]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colliderElement[2]; + /* 0x01E4 */ SkelAnime skelAnime; /* 0x0228 */ EnHintSkbActionFunc actionFunc; - /* 0x022C */ char unk_22C[0x1C0]; + /* 0x022C */ Vec3f limbPos[14]; + /* 0x02D4 */ f32 drawDmgEffAlpha; + /* 0x02D8 */ f32 drawDmgEffScale; + /* 0x02DC */ s32 limbCount; + /* 0x02E0 */ Vec3s jointTable[20]; + /* 0x0358 */ Vec3s morphtable[20]; + /* 0x03D0 */ UNK_TYPE1 unk3D0[0xC]; + /* 0x03DC */ s16 unk_3DC; + /* 0x03DE */ s16 unk_3DE; + /* 0x03E0 */ s16 unk_3E0; + /* 0x03E2 */ s16 drawDmgEffTimer; + /* 0x03E4 */ s16 unk_3E4; + /* 0x03E6 */ u16 unk_3E6; + /* 0x03E8 */ u8 unk_3E8; + /* 0x03E9 */ u8 drawDmgEffType; } EnHintSkb; // size = 0x3EC extern const ActorInit En_Hint_Skb_InitVars; 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 98f2eca76..78cfa14a0 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 @@ -1,6 +1,12 @@ +/* + * File: z_en_hit_tag.c + * Overlay: ovl_En_Hit_Tag + * Description: Invisible hitbox that can spawn rupees + */ + #include "z_en_hit_tag.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnHitTag*)thisx) @@ -8,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, @@ -23,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_Holl/z_en_holl.c b/src/overlays/actors/ovl_En_Holl/z_en_holl.c index b2e0a09d9..c3d577e7a 100644 --- a/src/overlays/actors/ovl_En_Holl/z_en_holl.c +++ b/src/overlays/actors/ovl_En_Holl/z_en_holl.c @@ -39,7 +39,7 @@ #include "z_en_holl.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnHoll*)thisx) @@ -108,7 +108,7 @@ void EnHoll_SetupAction(EnHoll* this) { void EnHoll_SetPlayerSide(GlobalContext* globalCtx, EnHoll* this, Vec3f* transformedPlayerPos) { Player* player = GET_PLAYER(globalCtx); - Actor_CalcOffsetOrientedToDrawRotation(&this->actor, transformedPlayerPos, &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->actor, transformedPlayerPos, &player->actor.world.pos); this->playerSide = (transformedPlayerPos->z < 0.0f) ? EN_HOLL_BEHIND : EN_HOLL_BEFORE; } @@ -223,8 +223,8 @@ void EnHoll_TransparentIdle(EnHoll* this, GlobalContext* globalCtx) { f32 enHollTop; f32 playerDistFromCentralPlane; - Actor_CalcOffsetOrientedToDrawRotation(&this->actor, &transformedPlayerPos, - useViewEye ? &globalCtx->view.eye : &player->actor.world.pos); + Actor_OffsetOfPointInActorCoords(&this->actor, &transformedPlayerPos, + useViewEye ? &globalCtx->view.eye : &player->actor.world.pos); enHollTop = (globalCtx->sceneNum == SCENE_PIRATE) ? EN_HOLL_TOP_PIRATE : EN_HOLL_TOP_DEFAULT; if ((transformedPlayerPos.y > EN_HOLL_BOTTOM_DEFAULT) && (transformedPlayerPos.y < enHollTop) && @@ -251,7 +251,7 @@ void EnHoll_VerticalBgCoverIdle(EnHoll* this, GlobalContext* globalCtx) { f32 playerDistFromCentralPlane; if ((this->actor.xzDistToPlayer < EN_HOLL_RADIUS) && - (playerDistFromCentralPlane = fabsf(this->actor.yDistToPlayer), + (playerDistFromCentralPlane = fabsf(this->actor.playerHeightRel), playerDistFromCentralPlane < EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL)) { if (playerDistFromCentralPlane < EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) { globalCtx->bgCoverAlpha = 255; @@ -260,7 +260,7 @@ void EnHoll_VerticalBgCoverIdle(EnHoll* this, GlobalContext* globalCtx) { } if (playerDistFromCentralPlane > EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) { s32 enHollId = EN_HOLL_GET_ID_CAST(this); - s32 playerSide = (this->actor.yDistToPlayer > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW; + s32 playerSide = (this->actor.playerHeightRel > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW; this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[playerSide].room; @@ -279,12 +279,12 @@ void EnHoll_VerticalBgCoverIdle(EnHoll* this, GlobalContext* globalCtx) { void EnHoll_VerticalIdle(EnHoll* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer < EN_HOLL_RADIUS) { - f32 playerDistFromCentralPlane = fabsf(this->actor.yDistToPlayer); + f32 playerDistFromCentralPlane = fabsf(this->actor.playerHeightRel); if (playerDistFromCentralPlane < EN_HOLL_ACTIVATION_PLANE_DISTANCE_VERTICAL && playerDistFromCentralPlane > EN_HOLL_LOADING_PLANE_DISTANCE_VERTICAL) { s32 enHollId = EN_HOLL_GET_ID_CAST(this); - s32 playerSide = (this->actor.yDistToPlayer > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW; + s32 playerSide = (this->actor.playerHeightRel > 0.0f) ? EN_HOLL_ABOVE : EN_HOLL_BELOW; this->actor.room = globalCtx->doorCtx.transitionActorList[enHollId].sides[playerSide].room; if ((this->actor.room != globalCtx->roomCtx.currRoom.num) && @@ -330,7 +330,7 @@ void EnHoll_Draw(Actor* thisx, GlobalContext* globalCtx) { } dl = Gfx_CallSetupDL(dl, dlIndex); if (this->playerSide == EN_HOLL_BEHIND) { - Matrix_InsertYRotation_f(M_PI, MTXMODE_APPLY); + Matrix_RotateYF(M_PI, MTXMODE_APPLY); } gSPMatrix(dl++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetPrimColor(dl++, 0, 0, 0, 0, 0, this->alpha); diff --git a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c index 19e79782c..aaea88252 100644 --- a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c +++ b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.c @@ -1,6 +1,12 @@ +/* + * File: z_en_honotrap.c + * Overlay: ovl_En_Honotrap + * Description: Eye switch that shoots fire + */ + #include "z_en_honotrap.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnHonotrap*)thisx) 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/z_en_horse.c b/src/overlays/actors/ovl_En_Horse/z_en_horse.c index 4eddd6b42..a0756abdf 100644 --- a/src/overlays/actors/ovl_En_Horse/z_en_horse.c +++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.c @@ -1,6 +1,13 @@ -#include "z_en_horse.h" +/* + * File: z_en_horse.c + * Overlay: ovl_En_Horse + * Description: Epona + */ -#define FLAGS 0x00000010 +#include "z_en_horse.h" +#include "objects/object_horse_link_child/object_horse_link_child.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnHorse*)thisx) @@ -9,7 +16,116 @@ void EnHorse_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHorse_Update(Actor* thisx, GlobalContext* globalCtx); void EnHorse_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_8087D540(Actor* thisx, GlobalContext* globalCtx); +void EnHorse_StartMountedIdleResetAnim(EnHorse* this); +void EnHorse_StartMountedIdle(EnHorse* this); +void EnHorse_MountedIdle(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_MountedIdleAnim(EnHorse* this); +void EnHorse_MountedIdleWhinney(EnHorse* this); +void EnHorse_StartTurning(EnHorse* this); +void EnHorse_StartWalkingFromIdle(EnHorse* this); +void EnHorse_StartWalkingInterruptable(EnHorse* this); +void EnHorse_StartWalking(EnHorse* this); +void EnHorse_StartTrotting(EnHorse* this); +void EnHorse_StartGallopingInterruptable(EnHorse* this); +void EnHorse_StartGalloping(EnHorse* this); +void EnHorse_StartBraking(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_StartReversingInterruptable(EnHorse* this); +void EnHorse_StartReversing(EnHorse* this); +void EnHorse_StartLowJump(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_StartHighJump(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_InitInactive(EnHorse* this); +void EnHorse_ChangeIdleAnimation(EnHorse* this, s32 anim, f32 morphFrames); +void EnHorse_ResetIdleAnimation(EnHorse* this); +void EnHorse_StartIdleRidable(EnHorse* this); +void EnHorse_StartMovingAnimation(EnHorse* this, s32 anim, f32 morphFrames, f32 startFrames); +void EnHorse_SetFollowAnimation(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_InitIngoHorse(EnHorse* this); +void EnHorse_UpdateIngoHorseAnim(EnHorse* this); +void func_80881290(EnHorse* this, GlobalContext* globalCtx); +void func_8088159C(EnHorse* this, GlobalContext* globalCtx); +void func_80881634(EnHorse* this); +void func_8088168C(EnHorse* this); +void EnHorse_CsMoveInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsMoveToPoint(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsPlayHighJumpAnim(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_CsJumpInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsJump(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsRearingInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsRearing(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_WarpMoveInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsWarpMoveToPoint(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsWarpRearingInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_CsWarpRearing(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void EnHorse_InitCutscene(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_InitHorsebackArchery(EnHorse* this); +void EnHorse_UpdateHbaAnim(EnHorse* this); +void func_80883BEC(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883CB0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883D64(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883DE0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883E10(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883EA0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883F18(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80883F98(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884010(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808840C4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884194(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_8088424C(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884314(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808843B4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884444(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808844E0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884564(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_80884604(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808846B4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808846DC(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action); +void func_808846F0(EnHorse* this, GlobalContext* globalCtx); +void func_80884994(EnHorse* this); +void func_80884D04(EnHorse* this, GlobalContext* globalCtx); +void EnHorse_StickDirection(Vec2f* curStick, f32* stickMag, s16* angle); +s32 EnHorse_GetMountSide(EnHorse* this, GlobalContext* globalCtx); + +typedef struct { + s32 csAction; + s32 csFuncIdx; +} CsActionEntry; + +typedef struct { + s16 x; + s16 y; + s16 z; + s16 speed; + s16 angle; +} RaceWaypoint; + +typedef struct { + s32 numWaypoints; + RaceWaypoint* waypoints; +} RaceInfo; + +static AnimationHeader* sEponaAnimHeaders[] = { + &object_horse_link_child_Anim_006D44, &object_horse_link_child_Anim_007468, &object_horse_link_child_Anim_005F64, + &object_horse_link_child_Anim_004DE8, &object_horse_link_child_Anim_007D50, &object_horse_link_child_Anim_0043AC, + &object_horse_link_child_Anim_002F98, &object_horse_link_child_Anim_0035B0, &object_horse_link_child_Anim_003D38, +}; + +static AnimationHeader* sHniAnimHeaders[] = { + &object_ha_Anim_00C850, &object_ha_Anim_00CE70, &object_ha_Anim_00B9C8, + &object_ha_Anim_00B00C, &object_ha_Anim_00D648, &object_ha_Anim_00A650, + &object_ha_Anim_009208, &object_ha_Anim_009858, &object_ha_Anim_00A05C, +}; + +static AnimationHeader** sAnimationHeaders[] = { + NULL, NULL, sEponaAnimHeaders, sHniAnimHeaders, sHniAnimHeaders, +}; + +static f32 sPlaybackSpeeds[] = { 2.0f / 3.0f, 2.0f / 3.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 2.0f / 3.0f, 2.0f / 3.0f }; + +static SkeletonHeader* sSkeletonHeaders[] = { + NULL, NULL, &object_horse_link_child_Skel_00A480, NULL, NULL, +}; + const ActorInit En_Horse_InitVars = { ACTOR_EN_HORSE, ACTORCAT_BG, @@ -22,370 +138,4572 @@ const ActorInit En_Horse_InitVars = { (ActorFunc)EnHorse_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80888F74 = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_PLAYER, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1 | OC2_UNK1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000004, 0x00, 0x02 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, - { 20, 70, 0, { 0, 0, 0 } }, -}; - -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80888FA0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1 | OC2_UNK1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, - { 20, 70, 0, { 0, 0, 0 } }, -}; - -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80888FCC[1] = { +static ColliderCylinderInit sCylinderInit1 = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00013820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_NO_AT_INFO | BUMP_NO_DAMAGE | BUMP_NO_SWORD_SFX | BUMP_NO_HITMARK, OCELEM_ON, }, + COLTYPE_NONE, + AT_NONE | AT_TYPE_PLAYER, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1 | OC2_UNK1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000004, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_ON, + }, + { 20, 70, 0, { 0, 0, 0 } }, +}; + +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1 | OC2_UNK1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, + { 20, 70, 0, { 0, 0, 0 } }, +}; + +static ColliderJntSphElementInit sJntSphElementsInit[] = { + { + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00013820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_NO_AT_INFO | BUMP_NO_DAMAGE | BUMP_NO_SWORD_SFX | BUMP_NO_HITMARK, + OCELEM_ON, + }, { 13, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80888FF0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1 | OC2_UNK1, COLSHAPE_JNTSPH, }, - 1, D_80888FCC, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1 | OC2_UNK1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80889000 = { 10, 35, 100, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 10, 35, 100, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80889010[] = { +static s32 sAnimSoundFrames[] = { + 0, + 16, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP), }; -#endif - -extern ColliderCylinderInit D_80888F74; -extern ColliderCylinderInit D_80888FA0; -extern ColliderJntSphElementInit D_80888FCC[1]; -extern ColliderJntSphInit D_80888FF0; -extern CollisionCheckInfoInit D_80889000; -extern InitChainEntry D_80889010[]; - -extern UNK_TYPE D_06008C68; -extern UNK_TYPE D_0600A8DC; -extern UNK_TYPE D_0600AD08; -extern UNK_TYPE D_0600B3E0; -extern UNK_TYPE D_0600BDE0; -extern UNK_TYPE D_0600D178; -extern UNK_TYPE D_0600D4E8; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087B730.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087B784.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087B7C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C0AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C178.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C1C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C208.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C288.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C2B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C38C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C43C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C590.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C8B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C8D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C8E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C9D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C9EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087C9F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087CA04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/EnHorse_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087D540.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/EnHorse_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087D70C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087D75C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087D814.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087D988.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087DDEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087DE28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087DF64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E080.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E0A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E18C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E2A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E350.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E564.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E5B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E5D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E684.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E6D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E92C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087E9D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EA1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EB54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EB78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EC20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EC78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087ED10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087EEC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F078.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F1FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F39C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F590.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F5B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F658.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F9A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087F9C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FB08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FB14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FD94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FDB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FF08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8087FF14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808801A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808801F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808802D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808804A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808804CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880500.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880534.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808806DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880844.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880978.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880DA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80880E00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881128.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088126C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881290.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881398.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088159C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881634.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088168C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808819D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881BDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881C54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881DC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881F10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80881F48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808821C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808822CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088247C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882564.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808826B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882820.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808829D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808829F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882A44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882B9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882D8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80882DC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883104.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883308.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883B70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883BEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883CB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883D64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883DE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883E10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883EA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883F18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80883F98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884010.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808840C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884194.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088424C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884314.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808843B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884444.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808844E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884564.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884604.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808846B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808846DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808846F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884718.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884868.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808848C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884994.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884A40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884D04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80884E0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885060.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808850DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885220.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808853E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_8088598C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885A80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885AF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885B4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885C90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80885DA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80886C00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80886DC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80886FA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808870A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_808871A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887270.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/EnHorse_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887D20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887D60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887E64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887EBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80887F58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80888C48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/func_80888D18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse/EnHorse_Draw.s") +static u8 sResetNoInput[] = { + false, false, false, false, false, false, true, true, true, true, true, true, + true, true, true, false, false, false, false, false, false, false, false, false, +}; + +static s32 sIdleAnimIds[] = { + 1, 3, 0, 3, 1, 0, +}; + +static s16 sIngoAnimations[] = { 7, 6, 2, 2, 1, 1, 0, 0, 0, 0 }; + +static EnHorseCsFunc sCutsceneInitFuncs[] = { + NULL, + EnHorse_CsMoveInit, + EnHorse_CsJumpInit, + EnHorse_CsRearingInit, + EnHorse_WarpMoveInit, + EnHorse_CsWarpRearingInit, +}; + +static EnHorseCsFunc sCutsceneActionFuncs[] = { + NULL, EnHorse_CsMoveToPoint, EnHorse_CsJump, EnHorse_CsRearing, EnHorse_CsWarpMoveToPoint, EnHorse_CsWarpRearing, +}; + +static CsActionEntry sCsActionTable[] = { + { 36, 1 }, { 37, 2 }, { 38, 3 }, { 64, 4 }, { 65, 5 }, +}; + +static RaceWaypoint sHbaWaypoints[] = { + { 3600, 1413, -5055, 11, 0x8001 }, { 3360, 1413, -5220, 5, 0xC000 }, { 3100, 1413, -4900, 5, 0x0000 }, + { 3600, 1413, -4100, 11, 0x0000 }, { 3600, 1413, 360, 11, 0x0000 }, +}; + +static RaceInfo sHbaInfo = { 5, sHbaWaypoints }; + +static EnHorseCsFunc D_808890F0[] = { + NULL, func_80883BEC, func_80883D64, func_80883E10, func_80883F18, func_80884010, + func_80884194, func_80884314, func_80884444, func_80884564, func_808846B4, +}; + +static EnHorseCsFunc D_8088911C[] = { + NULL, func_80883CB0, func_80883DE0, func_80883EA0, func_80883F98, func_808840C4, + func_8088424C, func_808843B4, func_808844E0, func_80884604, func_808846DC, +}; + +void EnHorse_RaceWaypointPos(RaceWaypoint* waypoints, s32 idx, Vec3f* pos) { + pos->x = waypoints[idx].x; + pos->y = waypoints[idx].y; + pos->z = waypoints[idx].z; +} + +void EnHorse_RotateToPoint(EnHorse* this, GlobalContext* globalCtx, Vec3f* pos, s16 turnAmount) { + func_800F415C(&this->actor, pos, turnAmount); +} + +void func_8087B7C0(EnHorse* this, GlobalContext* globalCtx, Path* path) { + s32 spA4; + Vec3s* spA0; + f32 phi_f12; + f32 phi_f14; + Vec3f sp8C; + Vec3f sp80; + f32 sp7C; + f32 sp78; + f32 sp74; + f32 sp70; + s32 i; + s32 sp68; + f32 sp64; + s32 sp60; + f32 temp_f0; + Vec3f sp50; + + spA4 = path->count; + spA0 = Lib_SegmentedToVirtual(path->points); + Math_Vec3s_ToVec3f(&sp8C, &spA0[this->curRaceWaypoint]); + + if (this->curRaceWaypoint == 0) { + phi_f12 = spA0[1].x - spA0[0].x; + phi_f14 = spA0[1].z - spA0[0].z; + } else if ((this->curRaceWaypoint + 1) == path->count) { + phi_f12 = spA0[path->count - 1].x - spA0[path->count - 2].x; + phi_f14 = spA0[path->count - 1].z - spA0[path->count - 2].z; + } else { + phi_f12 = spA0[this->curRaceWaypoint + 1].x - spA0[this->curRaceWaypoint - 1].x; + phi_f14 = spA0[this->curRaceWaypoint + 1].z - spA0[this->curRaceWaypoint - 1].z; + } + + func_8017B7F8(&sp8C, Math_Atan2S(phi_f12, phi_f14), &sp7C, &sp78, &sp74); + + if (((this->actor.world.pos.x * sp7C) + (sp78 * this->actor.world.pos.z) + sp74) > 0.0f) { + this->curRaceWaypoint++; + if (this->curRaceWaypoint >= spA4) { + this->curRaceWaypoint = spA4 - 1; + } + Math_Vec3s_ToVec3f(&sp8C, &spA0[this->curRaceWaypoint]); + } + + if (this->curRaceWaypoint == 0) { + Math_Vec3s_ToVec3f(&sp80, &spA0[1]); + } else { + Math_Vec3s_ToVec3f(&sp80, &spA0[this->curRaceWaypoint - 1]); + } + + func_8017D7C0(this->actor.world.pos.x, this->actor.world.pos.z, sp80.x, sp80.z, sp8C.x, sp8C.z, &sp70); + + if ((this->actor.bgCheckFlags & 8) || (this->unk_1EC & 4)) { + EnHorse_RotateToPoint(this, globalCtx, &sp8C, 0xC80); + if (this->unk_1EC & 4) { + this->unk_1EC &= ~4; + } + } else { + EnHorse_RotateToPoint(this, globalCtx, &sp8C, 0x320); + if (sp70 < SQ(100.0f)) { + if ((this->actor.xzDistToPlayer < 100.0f) || + (this->colliderJntSph.elements[0].info.ocElemFlags & OCELEM_HIT)) { + s32 pad; + + if (Math_SinS(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0.0f) { + this->actor.world.rot.y -= 0x1E0; + } else { + this->actor.world.rot.y += 0x1E0; + } + } else if (this->actor.xzDistToPlayer < 300.0f) { + if (Math_SinS(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0.0f) { + this->actor.world.rot.y += 0x1E0; + } else { + this->actor.world.rot.y -= 0x1E0; + } + } + this->actor.shape.rot.y = this->actor.world.rot.y; + } + } + + sp68 = this->curRaceWaypoint - 3; + if (sp68 < 0) { + sp68 = 0; + } + + sp64 = 1.0e+38; + sp60 = sp68 + 5; + if (path->count < sp60) { + sp60 = path->count; + } + + for (i = sp68; i < sp60; i++) { + Math_Vec3s_ToVec3f(&sp50, &spA0[i]); + temp_f0 = Math3D_Distance(&this->actor.world.pos, &sp50); + if (temp_f0 < sp64) { + sp64 = temp_f0; + sp68 = i; + } + } + + this->unk_398 = spA0[this->curRaceWaypoint].y * 0.01f; + if ((this->unk_1EC & 0x100) && !(this->stateFlags & ENHORSE_JUMPING) && + ((this->colliderCylinder1.base.acFlags & AC_HIT) || (this->colliderCylinder2.base.acFlags & AC_HIT) || + (this->unk_58C > 0))) { + if (this->unk_58C == 0) { + this->unk_590 = 0x1F4; + this->unk_58C = 0x2B; + } + this->unk_58C--; + if (this->actor.speedXZ > 5.0f) { + this->actor.speedXZ -= 0.5f; + } + } else if (this->unk_590 > 0) { + if (this->unk_590 == 0x1F4) { + if (this->rider != NULL) { + Actor_PlaySfxAtPos(&this->rider->actor, NA_SE_VO_IN_CRY_0); + } + } + this->unk_590--; + if (this->actor.speedXZ < this->unk_398) { + this->actor.speedXZ += 1.0f; + } else { + this->actor.speedXZ -= 0.5f; + } + } else if (this->actor.params == ENHORSE_5) { + s16 sp4A; + + if (sp68 >= this->curRaceWaypoint) { + if (this->actor.speedXZ < this->unk_398) { + this->actor.speedXZ += 0.5f; + } else { + this->actor.speedXZ -= 0.5f; + } + this->unk_394 |= 1; + return; + } + + sp4A = Actor_YawBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor) - this->actor.world.rot.y; + + if ((fabsf(Math_SinS(sp4A)) < 0.9f) && (Math_CosS(sp4A) > 0.0f)) { + if (this->actor.speedXZ < this->unk_398) { + this->actor.speedXZ += 0.5f; + } else { + this->actor.speedXZ -= 0.25f; + } + this->unk_394 |= 1; + } else { + if (this->actor.speedXZ < 13.0f) { + this->actor.speedXZ += 0.4f; + } else { + this->actor.speedXZ -= 0.2f; + } + this->unk_394 &= ~1; + } + } else if (sp68 >= this->curRaceWaypoint) { + if (this->actor.speedXZ < this->unk_398) { + this->actor.speedXZ += 0.5f; + } else { + this->actor.speedXZ -= 0.5f; + } + this->unk_394 |= 1; + } else if ((sp68 + 1) == this->curRaceWaypoint) { + s16 sp48 = Actor_YawBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor) - this->actor.world.rot.y; + + if ((fabsf(Math_SinS(sp48)) < 0.9f) && (Math_CosS(sp48) > 0.0f)) { + if (this->actor.speedXZ < this->unk_398) { + this->actor.speedXZ += 0.5f; + } else { + this->actor.speedXZ -= 0.25f; + } + this->unk_394 |= 1; + } else { + if (this->actor.speedXZ < 12.0f) { + this->actor.speedXZ += 0.4f; + } else { + this->actor.speedXZ -= 0.2f; + } + this->unk_394 &= ~1; + } + } else { + if (this->actor.speedXZ < 13.0f) { + this->actor.speedXZ += 0.4f; + } else { + this->actor.speedXZ -= 0.2f; + } + this->unk_394 &= ~1; + } +} + +void EnHorse_PlayWalkingSound(EnHorse* this) { + if (sAnimSoundFrames[this->soundTimer] < this->curFrame) { + if ((this->soundTimer == 0) && (sAnimSoundFrames[1] < this->curFrame)) { + return; + } + + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_WALK); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_WALK); + } + + this->soundTimer++; + if (this->soundTimer > 1) { + this->soundTimer = 0; + } + } +} + +void func_8087C178(EnHorse* this) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } +} + +void func_8087C1C0(EnHorse* this) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } +} + +f32 EnHorse_SlopeSpeedMultiplier(EnHorse* this, GlobalContext* globalCtx) { + f32 multiplier = 1.0f; + + if ((Math_CosS(this->actor.shape.rot.x) < 0.939262f) && (Math_SinS(this->actor.shape.rot.x) < 0.0f)) { + multiplier = 0.7f; + } + return multiplier; +} + +void func_8087C288(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, f32* arg3) { + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, arg1, arg2, arg3); +} + +s32 func_8087C2B8(GlobalContext* globalCtx, EnHorse* this, Vec3f* arg2, f32 arg3) { + f32 phi_f14; + + if ((arg2->z > 0.0f) && (arg2->z < (this->actor.uncullZoneForward + this->actor.uncullZoneScale))) { + if (arg3 < 1.0f) { + phi_f14 = 1.0f; + } else { + phi_f14 = 1.0f / arg3; + } + + if (((fabsf(arg2->x) * phi_f14) < 1.0f) && (((arg2->y + this->actor.uncullZoneDownward) * phi_f14) > -1.0f) && + (((arg2->y - this->actor.uncullZoneScale) * phi_f14) < 1.0f)) { + return true; + } + } + return false; +} + +s32 func_8087C38C(GlobalContext* globalCtx, EnHorse* this, Vec3f* arg2) { + Vec3f sp24; + f32 sp20; + f32 eyeDist; + + func_8087C288(globalCtx, arg2, &sp24, &sp20); + + if (fabsf(sp20) < 0.008f) { + return false; + } + + eyeDist = Math3D_Distance(arg2, &globalCtx->view.eye); + + return func_8087C2B8(globalCtx, this, &sp24, sp20) || (eyeDist < 100.0f); +} + +void EnHorse_IdleAnimSounds(EnHorse* this, GlobalContext* globalCtx) { + if ((this->animationIdx == ENHORSE_ANIM_IDLE) && + (((this->curFrame > 35.0f) && (this->type == HORSE_EPONA)) || + ((this->curFrame > 28.0f) && (this->type == HORSE_HNI)) || + ((this->curFrame > 25.0f) && (this->type == HORSE_2))) && + !(this->stateFlags & ENHORSE_SANDDUST_SOUND)) { + this->stateFlags |= ENHORSE_SANDDUST_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } + } else if ((this->animationIdx == 3) && (this->curFrame > 25.0f) && !(this->stateFlags & ENHORSE_LAND2_SOUND)) { + this->stateFlags |= ENHORSE_LAND2_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + } +} + +s32 EnHorse_Spawn(EnHorse* this, GlobalContext* globalCtx) { + s32 i; + f32 dist; + Path* path; + s32 spawn = false; + f32 minDist = 1.0e+38; + Player* player = GET_PLAYER(globalCtx); + Vec3f spawnPos; + s32 pathIdx = func_800F3940(globalCtx); + s32 pathCount; + Vec3s* pathPoints; + + if (pathIdx == -1) { + return false; + } + + path = &globalCtx->setupPathList[pathIdx]; + pathCount = path->count; + pathPoints = Lib_SegmentedToVirtual(path->points); + + for (i = 0; i < pathCount; i++) { + spawnPos.x = pathPoints[i].x; + spawnPos.y = pathPoints[i].y; + spawnPos.z = pathPoints[i].z; + dist = Math3D_Distance(&player->actor.world.pos, &spawnPos); + + if ((minDist < dist) || func_8087C38C(globalCtx, this, &spawnPos)) { + continue; + } + + minDist = dist; + this->actor.world.pos.x = spawnPos.x; + this->actor.world.pos.y = spawnPos.y; + this->actor.world.pos.z = spawnPos.z; + this->actor.prevPos = this->actor.world.pos; + this->actor.world.rot.y = 0; + this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor); + spawn = true; + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &this->actor.world.pos, &this->actor.projectedPos, + &this->actor.projectedW); + } + + if (spawn == true) { + return true; + } + + for (i = 0; i < pathCount; i++) { + spawnPos.x = pathPoints[i].x; + spawnPos.y = pathPoints[i].y; + spawnPos.z = pathPoints[i].z; + dist = Math3D_Distance(&player->actor.world.pos, &spawnPos); + + if (minDist < dist) { + continue; + } + + minDist = dist; + this->actor.world.pos.x = spawnPos.x; + this->actor.world.pos.y = spawnPos.y; + this->actor.world.pos.z = spawnPos.z; + this->actor.prevPos = this->actor.world.pos; + this->actor.world.rot.y = 0; + this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor); + spawn = true; + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &this->actor.world.pos, &this->actor.projectedPos, + &this->actor.projectedW); + } + + return spawn; +} + +void EnHorse_ResetCutscene(EnHorse* this, GlobalContext* globalCtx) { + this->cutsceneAction = -1; + this->cutsceneFlags = 0; +} + +void EnHorse_ResetRace(EnHorse* this, GlobalContext* globalCtx) { + this->inRace = false; +} + +s32 EnHorse_PlayerCanMove(EnHorse* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->stateFlags1 & 1) || (func_800B7128(GET_PLAYER(globalCtx)) == true) || + (player->stateFlags1 & 0x100000) || + (((this->stateFlags & ENHORSE_FLAG_19) || (this->stateFlags & ENHORSE_FLAG_29)) && !this->inRace) || + (this->action == 19) || (player->actor.flags & ACTOR_FLAG_100) || (globalCtx->csCtx.state != 0) || + (ActorCutscene_GetCurrentIndex() != -1) || (player->stateFlags1 & 0x20) || (player->csMode != 0)) { + return false; + } + return true; +} + +void EnHorse_ResetHorsebackArchery(EnHorse* this, GlobalContext* globalCtx) { + this->unk_39C = 0; + this->hbaStarted = 0; + this->hbaFlags = 0; +} + +void EnHorse_ClearDustFlags(u16* dustFlags) { + *dustFlags = 0; +} + +void func_8087C9F8(EnHorse* this) { +} + +void func_8087CA04(EnHorse* this, GlobalContext* globalCtx) { +} + +void EnHorse_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnHorse* this = THIS; + Skin* skin = &this->skin; + + Actor_ProcessInitChain(&this->actor, sInitChain); + EnHorse_ClearDustFlags(&this->dustFlags); + D_801BDAA4 = 0; + Skin_Setup(&this->skin); + this->riderPos = thisx->world.pos; + this->unk_52C = 0; + this->noInputTimer = 0; + this->riderPos.y += 70.0f; + this->noInputTimerMax = 0; + this->unk_1EC = 0; + this->unk_58C = 0; + this->unk_590 = 0; + this->unk_3E8 = 0.0f; + this->unk_528 = 100.0f; + + if (ENHORSE_GET_8000(&this->actor)) { + this->type = HORSE_4; + this->unk_528 = 80.0f; + this->boostSpeed = 12; + if ((this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_HA)) < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + this->unk_1EC |= 1; + thisx->update = func_8087D540; + } else if (ENHORSE_GET_4000(&this->actor)) { + this->type = HORSE_2; + this->unk_528 = 64.8f; + this->boostSpeed = 15; + if ((this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_HORSE_LINK_CHILD)) < 0) { + thisx->objBankIndex = Object_Spawn(&globalCtx->objectCtx, OBJECT_HORSE_LINK_CHILD); + Actor_SetObjectDependency(globalCtx, &this->actor); + Skin_Init(&globalCtx->state, &this->skin, sSkeletonHeaders[this->type], sAnimationHeaders[this->type][0]); + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + this->unk_1EC |= 0x200; + } else { + thisx->update = func_8087D540; + } + } else if (ENHORSE_GET_2000(&this->actor)) { + this->type = HORSE_3; + this->boostSpeed = 12; + if ((this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_HA)) < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + this->unk_1EC |= 1; + thisx->update = func_8087D540; + } else { + this->type = HORSE_EPONA; + this->boostSpeed = 15; + Actor_MarkForDeath(&this->actor); + } + + thisx->params &= ~0xE000; + if (thisx->params == 0x1FFF) { + thisx->params = ENHORSE_1; + } + + if (thisx->params == ENHORSE_3) { + this->stateFlags = ENHORSE_FLAG_19 | ENHORSE_CANT_JUMP | ENHORSE_UNRIDEABLE; + } else if (thisx->params == ENHORSE_8) { + this->stateFlags = ENHORSE_FLAG_19 | ENHORSE_CANT_JUMP; + if (CHECK_QUEST_ITEM(14)) { + this->stateFlags &= ~ENHORSE_CANT_JUMP; + this->stateFlags |= ENHORSE_FLAG_26; + } + } else if (thisx->params == ENHORSE_13) { + this->stateFlags = ENHORSE_FLAG_29; + this->unk_1EC |= 0x10; + } else if (thisx->params == ENHORSE_4) { + this->stateFlags = ENHORSE_FLAG_29 | ENHORSE_CANT_JUMP; + thisx->flags |= ACTOR_FLAG_80000000; + } else if (thisx->params == ENHORSE_5) { + this->stateFlags = ENHORSE_FLAG_29 | ENHORSE_CANT_JUMP; + thisx->flags |= ACTOR_FLAG_80000000; + } else if (thisx->params == ENHORSE_15) { + this->stateFlags = ENHORSE_UNRIDEABLE | ENHORSE_FLAG_7; + } else if (thisx->params == ENHORSE_17) { + this->stateFlags = 0; + this->unk_1EC |= 8; + } else if (thisx->params == ENHORSE_18) { + this->stateFlags = ENHORSE_FLAG_29 | ENHORSE_CANT_JUMP; + thisx->flags |= ACTOR_FLAG_80000000; + } else if (thisx->params == ENHORSE_1) { + this->stateFlags = ENHORSE_FLAG_7; + } else if ((thisx->params == ENHORSE_19) || (thisx->params == ENHORSE_20)) { + this->stateFlags = ENHORSE_CANT_JUMP | ENHORSE_UNRIDEABLE; + } else { + this->stateFlags = 0; + } + + if (((globalCtx->sceneNum == SCENE_KOEPONARACE) && ((gSaveContext.save.weekEventReg[92] & (1 | 2 | 4)) == 1)) || + ((gSaveContext.save.entranceIndex == 0x6400) && Cutscene_GetSceneSetupIndex(globalCtx))) { + this->stateFlags |= ENHORSE_FLAG_25; + } + + thisx->gravity = -3.5f; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawHorse, 20.0f); + this->action = ENHORSE_ACT_IDLE; + thisx->speedXZ = 0.0f; + + if (this->type == HORSE_2) { + sJntSphInit.elements[0].dim.limb = 13; + } else if ((this->type == HORSE_3) || (this->type == HORSE_4)) { + sJntSphInit.elements[0].dim.limb = 10; + } + + Collider_InitCylinder(globalCtx, &this->colliderCylinder1); + Collider_SetCylinder(globalCtx, &this->colliderCylinder1, &this->actor, &sCylinderInit1); + Collider_InitCylinder(globalCtx, &this->colliderCylinder2); + Collider_SetCylinder(globalCtx, &this->colliderCylinder2, &this->actor, &sCylinderInit2); + Collider_InitJntSph(globalCtx, &this->colliderJntSph); + Collider_SetJntSph(globalCtx, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElements); + + if (this->type == HORSE_2) { + this->colliderCylinder1.dim.radius = this->colliderCylinder1.dim.radius * 0.8f; + this->colliderCylinder2.dim.radius = this->colliderCylinder2.dim.radius * 0.8f; + this->colliderJntSph.elements[0].dim.modelSphere.radius *= 0.6f; + } else if (this->type == HORSE_4) { + this->colliderCylinder1.dim.radius = 50; + } + + CollisionCheck_SetInfo(&thisx->colChkInfo, NULL, &sColChkInfoInit); + + if (this->type == HORSE_2) { + Actor_SetScale(&this->actor, 0.00648f); + } else if (this->type == HORSE_4) { + Actor_SetScale(&this->actor, 0.008f); + } else { + Actor_SetScale(&this->actor, 0.01f); + } + + thisx->focus.pos = thisx->world.pos; + this->playerControlled = false; + thisx->focus.pos.y += 70.0f; + + if (!(this->unk_1EC & 1) && !(this->unk_1EC & 0x200) && (thisx->update == EnHorse_Update)) { + Skin_Init(&globalCtx->state, &this->skin, sSkeletonHeaders[this->type], sAnimationHeaders[this->type][0]); + } + + this->animationIdx = 0; + this->numBoosts = 6; + this->boostRegenTime = 0; + this->postDrawFunc = NULL; + this->blinkTimer = 0; + + EnHorse_ResetCutscene(this, globalCtx); + EnHorse_ResetRace(this, globalCtx); + EnHorse_ResetHorsebackArchery(this, globalCtx); + + if (thisx->params == ENHORSE_2) { + this->unk_53C = 0; + EnHorse_InitInactive(this); + } else if (thisx->params == ENHORSE_3) { + EnHorse_InitIngoHorse(this); + this->rider = + (EnIn*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_IN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, 1, 1); + this->unk_398 = 14.34f; + } else if (thisx->params == ENHORSE_4) { + func_80881634(this); + this->unk_398 = 14.34f; + this->rider = + (EnIn*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_IN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, 1, 1); + this->unk_1EC |= 0x100; + } else if (thisx->params == ENHORSE_5) { + func_80881634(this); + this->unk_398 = 14.525f; + this->rider = + (EnIn*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_IN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, 1, 2); + this->unk_1EC |= 0x100; + } else if (thisx->params == ENHORSE_9) { + EnHorse_InitCutscene(this, globalCtx); + } else if (thisx->params == ENHORSE_10) { + EnHorse_InitHorsebackArchery(this); + func_80112AFC(globalCtx); + } else if (thisx->params == ENHORSE_14) { + func_808846F0(this, globalCtx); + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && !Cutscene_IsPlaying(globalCtx)) { + Actor_MarkForDeath(&this->actor); + } + } else if (thisx->params == ENHORSE_16) { + func_8087C9F8(this); + } else if (thisx->params == ENHORSE_15) { + EnHorse_ResetIdleAnimation(this); + } else if (thisx->params == ENHORSE_18) { + func_80884994(this); + } else if (thisx->params == ENHORSE_19) { + EnIn* in; + + func_80884D04(this, globalCtx); + in = (EnIn*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_IN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, 1, 1); + this->rider = in; + in->unk4AC |= (0x20 | 0x4); + } else if (thisx->params == ENHORSE_20) { + EnIn* in; + + func_80884D04(this, globalCtx); + in = (EnIn*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_IN, thisx->world.pos.x, thisx->world.pos.y, + thisx->world.pos.z, thisx->shape.rot.x, thisx->shape.rot.y, 1, 1); + this->rider = in; + in->unk4AC |= (0x20 | 0x8 | 0x4); + } else { + EnHorse_StartIdleRidable(this); + } + + thisx->shape.rot.z = 0; + thisx->world.rot.z = thisx->shape.rot.z; + thisx->home.rot.z = thisx->shape.rot.z; + this->unk_3EC = thisx->world.rot.y; + this->unk_538 = 0; + + if (this->unk_1EC & 0x100) { + this->colliderCylinder1.base.colType = COLTYPE_HIT3; + this->colliderCylinder1.base.acFlags |= (AC_TYPE_PLAYER | AC_ON); + this->colliderCylinder1.info.bumperFlags |= BUMP_ON; + this->colliderCylinder1.info.bumper.dmgFlags = 0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20; + this->colliderCylinder2.base.colType = COLTYPE_HIT3; + this->colliderCylinder2.base.acFlags |= (AC_TYPE_PLAYER | AC_ON); + this->colliderCylinder2.info.bumperFlags |= BUMP_ON; + this->colliderCylinder2.info.bumper.dmgFlags = 0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20; + } +} + +void func_8087D540(Actor* thisx, GlobalContext* globalCtx) { + EnHorse* this = THIS; + + if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { + this->actor.objBankIndex = this->bankIndex; + Actor_SetObjectDependency(globalCtx, &this->actor); + this->actor.update = EnHorse_Update; + if (this->unk_1EC & 1) { + if (this->type == HORSE_3) { + SkelAnime_InitFlex(globalCtx, &this->skin.skelAnime, &object_ha_Skel_008C68, NULL, this->jointTable, + this->morphTable, OBJECT_HA_1_LIMB_MAX); + } else { + SkelAnime_InitFlex(globalCtx, &this->skin.skelAnime, &object_ha_Skel_0150D8, NULL, this->jointTable, + this->morphTable, OBJECT_HA_2_LIMB_MAX); + } + } else { + Skin_Init(&globalCtx->state, &this->skin, sSkeletonHeaders[this->type], sAnimationHeaders[this->type][0]); + } + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + } +} + +void EnHorse_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHorse* this = THIS; + + if (this->stateFlags & ENHORSE_DRAW) { + Audio_StopSfxByPos(&this->unk_218); + } + Skin_Free(&globalCtx->state, &this->skin); + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder1); + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder2); + Collider_DestroyJntSph(globalCtx, &this->colliderJntSph); +} + +void EnHorse_RotateToPlayer(EnHorse* this, GlobalContext* globalCtx) { + EnHorse_RotateToPoint(this, globalCtx, &GET_PLAYER(globalCtx)->actor.world.pos, 0x320); + if (this->stateFlags & ENHORSE_OBSTACLE) { + this->actor.world.rot.y += 1600; + } + this->actor.shape.rot.y = this->actor.world.rot.y; +} + +void EnHorse_Freeze(EnHorse* this, GlobalContext* globalCtx) { + if ((this->action != ENHORSE_ACT_HBA) && (this->action != ENHORSE_ACT_21) && + (this->action != ENHORSE_ACT_FLEE_PLAYER)) { + if (sResetNoInput[this->actor.params] && (this->actor.params != ENHORSE_6)) { + Player* player = GET_PLAYER(globalCtx); + + this->noInputTimerMax = 0; + this->noInputTimer = 0; + player->actor.world.pos = this->actor.world.pos; + player->actor.world.pos.y += 70.0f; + } + this->prevAction = this->action; + this->action = ENHORSE_ACT_FROZEN; + this->colliderCylinder1.base.ocFlags1 &= ~OC1_ON; + this->colliderCylinder2.base.ocFlags1 &= ~OC1_ON; + this->colliderJntSph.base.ocFlags1 &= ~OC1_ON; + this->animationIdx = ENHORSE_ANIM_IDLE; + } +} + +void EnHorse_Frozen(EnHorse* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + this->noInputTimer--; + if (this->noInputTimer < 0) { + this->colliderCylinder1.base.ocFlags1 |= OC1_ON; + this->colliderCylinder2.base.ocFlags1 |= OC1_ON; + this->colliderJntSph.base.ocFlags1 |= OC1_ON; + if (this->playerControlled == true) { + this->stateFlags &= ~ENHORSE_FLAG_7; + if (this->actor.params == ENHORSE_6) { + EnHorse_StartMountedIdleResetAnim(this); + } else if (this->actor.params == ENHORSE_11) { + this->actor.params = ENHORSE_7; + if (globalCtx->csCtx.state != 0) { + EnHorse_StartMountedIdle(this); + } else { + this->actor.speedXZ = 8.0f; + EnHorse_StartGalloping(this); + } + } else if (this->prevAction == ENHORSE_ACT_IDLE) { + EnHorse_StartMountedIdle(this); + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + + if (this->actor.params != ENHORSE_0) { + this->actor.params = ENHORSE_0; + } + } else if (this->prevAction == ENHORSE_ACT_MOUNTED_TURN) { + EnHorse_ChangeIdleAnimation(this, 0, 0.0f); + } else if (this->prevAction == ENHORSE_ACT_MOUNTED_WALK) { + EnHorse_ChangeIdleAnimation(this, 0, 0.0f); + } else { + EnHorse_ChangeIdleAnimation(this, 0, 0.0f); + } + } +} + +void EnHorse_UpdateSpeed(EnHorse* this, GlobalContext* globalCtx, f32 brakeDecel, f32 brakeAngle, f32 minStickMag, + f32 decel, f32 baseSpeed, s16 turnSpeed) { + f32 phi_f0; + f32 stickMag; + s16 stickAngle; + s16 turn; + f32 temp_f12; + + if (!EnHorse_PlayerCanMove(this, globalCtx)) { + if (this->actor.speedXZ > 8.0f) { + this->actor.speedXZ -= decel; + } else if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + return; + } + + baseSpeed *= EnHorse_SlopeSpeedMultiplier(this, globalCtx); + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + + if (Math_CosS(stickAngle) <= brakeAngle) { + this->actor.speedXZ -= brakeDecel; + this->actor.speedXZ = CLAMP_MIN(this->actor.speedXZ, 0.0f); + return; + } + + if (stickMag < minStickMag) { + this->stateFlags &= ~ENHORSE_BOOST; + this->stateFlags &= ~ENHORSE_BOOST_DECEL; + this->actor.speedXZ -= decel; + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + return; + } + + if (this->stateFlags & ENHORSE_BOOST) { + if ((16 - this->boostTimer) > 0) { + this->actor.speedXZ = + (((EnHorse_SlopeSpeedMultiplier(this, globalCtx) * this->boostSpeed) - this->actor.speedXZ) / + (16.0f - this->boostTimer)) + + this->actor.speedXZ; + } else { + this->actor.speedXZ = EnHorse_SlopeSpeedMultiplier(this, globalCtx) * this->boostSpeed; + } + + if ((EnHorse_SlopeSpeedMultiplier(this, globalCtx) * this->boostSpeed) <= this->actor.speedXZ) { + this->stateFlags &= ~ENHORSE_BOOST; + this->stateFlags |= ENHORSE_BOOST_DECEL; + } + } else if (this->stateFlags & ENHORSE_BOOST_DECEL) { + if (this->actor.speedXZ > baseSpeed) { + this->actor.speedXZ -= 0.06f; + } else if (this->actor.speedXZ < baseSpeed) { + this->actor.speedXZ = baseSpeed; + this->stateFlags &= ~ENHORSE_BOOST_DECEL; + } + } else { + if (this->actor.speedXZ <= (baseSpeed * (1.0f / 54.0f) * stickMag)) { + phi_f0 = 1.0f; + } else { + phi_f0 = -1.0f; + } + + this->actor.speedXZ += phi_f0 * 50.0f * 0.01f; + + if (this->actor.speedXZ > baseSpeed) { + this->actor.speedXZ -= decel; + if (this->actor.speedXZ < baseSpeed) { + this->actor.speedXZ = baseSpeed; + } + } + } + + temp_f12 = stickAngle * (1 / 32236.f); + turn = stickAngle * temp_f12 * temp_f12 * (2.2f - (this->actor.speedXZ * (1.0f / this->boostSpeed))); + turn = CLAMP(turn, -turnSpeed * (2.2f - (1.7f * this->actor.speedXZ * (1.0f / this->boostSpeed))), + turnSpeed * (2.2f - (1.7f * this->actor.speedXZ * (1.0f / this->boostSpeed)))); + this->actor.world.rot.y += turn; + this->actor.shape.rot.y = this->actor.world.rot.y; +} + +void EnHorse_StartMountedIdleResetAnim(EnHorse* this) { + this->skin.skelAnime.curFrame = 0.0f; + EnHorse_StartMountedIdle(this); + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; +} + +void EnHorse_StartMountedIdle(EnHorse* this) { + f32 curFrame; + + this->action = ENHORSE_ACT_MOUNTED_TURN; + this->animationIdx = ENHORSE_ANIM_IDLE; + + if (((this->curFrame > 35.0f) && (this->type == HORSE_EPONA)) || + ((this->curFrame > 28.0f) && (this->type == HORSE_HNI))) { + if (!(this->stateFlags & ENHORSE_SANDDUST_SOUND)) { + this->stateFlags |= ENHORSE_SANDDUST_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } + } + } + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedIdle(EnHorse* this, GlobalContext* globalCtx) { + f32 mag; + s16 angle = 0; + + this->actor.speedXZ = 0.0f; + EnHorse_StickDirection(&this->curStick, &mag, &angle); + if (mag > 10.0f) { + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if (Math_CosS(angle) <= -0.5f) { + EnHorse_StartReversingInterruptable(this); + } else if (Math_CosS(angle) <= 0.7071f) { + EnHorse_StartTurning(this); + } else { + EnHorse_StartWalkingFromIdle(this); + } + } else if (this->unk_3EC != this->actor.world.rot.y) { + EnHorse_StartTurning(this); + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + EnHorse_MountedIdleAnim(this); + } +} + +void EnHorse_MountedIdleAnim(EnHorse* this) { + this->skin.skelAnime.curFrame = 0.0f; + EnHorse_MountedIdleWhinney(this); +} + +void EnHorse_MountedIdleWhinney(EnHorse* this) { + f32 curFrame; + + this->action = ENHORSE_ACT_MOUNTED_WALK; + this->animationIdx = ENHORSE_ANIM_WHINNEY; + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][1]), ANIMMODE_ONCE, -3.0f); + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_GROAN); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_GROAN); + } + } +} + +void EnHorse_MountedIdleWhinneying(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle = 0; + + this->actor.speedXZ = 0.0f; + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + if (stickMag > 10.0f) { + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if (Math_CosS(stickAngle) <= -0.5f) { + EnHorse_StartReversingInterruptable(this); + } else if (Math_CosS(stickAngle) <= 0.7071f) { + EnHorse_StartTurning(this); + } else { + EnHorse_StartWalkingFromIdle(this); + } + } else if (this->unk_3EC != this->actor.world.rot.y) { + EnHorse_StartTurning(this); + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + EnHorse_StartMountedIdleResetAnim(this); + } +} + +void EnHorse_StartTurning(EnHorse* this) { + this->action = ENHORSE_ACT_MOUNTED_TROT; + this->soundTimer = 0; + this->animationIdx = ENHORSE_ANIM_WALK; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][4]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedTurn(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 clampedYaw; + s16 stickAngle; + + this->actor.speedXZ = 0.0f; + EnHorse_PlayWalkingSound(this); + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + if (stickMag > 10.0f) { + if (!EnHorse_PlayerCanMove(this, globalCtx)) { + EnHorse_StartMountedIdleResetAnim(this); + } else if (Math_CosS(stickAngle) <= -0.5f) { + EnHorse_StartReversingInterruptable(this); + } else if (Math_CosS(stickAngle) <= 0.7071f) { + clampedYaw = CLAMP(stickAngle, -1600.0f, 1600.0f); + this->actor.world.rot.y += clampedYaw; + this->actor.shape.rot.y = this->actor.world.rot.y; + } else { + EnHorse_StartWalkingInterruptable(this); + } + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if (Math_CosS(stickAngle) <= 0.7071f) { + EnHorse_StartTurning(this); + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } else if (this->unk_3EC != this->actor.world.rot.y) { + EnHorse_StartTurning(this); + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } +} + +void EnHorse_StartWalkingFromIdle(EnHorse* this) { + EnHorse_StartWalkingInterruptable(this); + if (!(this->stateFlags & ENHORSE_FLAG_8) && !(this->stateFlags & ENHORSE_FLAG_9)) { + this->stateFlags |= ENHORSE_FLAG_9; + this->waitTimer = 8; + } else { + this->waitTimer = 0; + } +} + +void EnHorse_StartWalkingInterruptable(EnHorse* this) { + this->noInputTimer = 0; + this->noInputTimerMax = 0; + EnHorse_StartWalking(this); +} + +void EnHorse_StartWalking(EnHorse* this) { + this->action = ENHORSE_ACT_MOUNTED_GALLOP; + this->soundTimer = 0; + this->animationIdx = ENHORSE_ANIM_WALK; + this->waitTimer = 0; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][4]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedWalkingReset(EnHorse* this) { + this->action = ENHORSE_ACT_MOUNTED_GALLOP; + this->soundTimer = 0; + this->animationIdx = ENHORSE_ANIM_WALK; + this->waitTimer = 0; + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); +} + +void EnHorse_MountedWalk(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle; + + EnHorse_PlayWalkingSound(this); + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + + if ((this->noInputTimerMax == 0) || + ((this->noInputTimer > 0) && (this->noInputTimer < (this->noInputTimerMax - 20)))) { + EnHorse_UpdateSpeed(this, globalCtx, 0.3f, -0.5f, 10.0f, 0.06f, 3.0f, 0x320); + } else { + this->actor.speedXZ = 3.0f; + } + + if (this->actor.speedXZ == 0.0f) { + this->stateFlags &= ~ENHORSE_FLAG_9; + EnHorse_StartMountedIdleResetAnim(this); + this->noInputTimer = 0; + this->noInputTimerMax = 0; + } else if (this->actor.speedXZ > 3.0f) { + this->stateFlags &= ~ENHORSE_FLAG_9; + EnHorse_StartTrotting(this); + this->noInputTimer = 0; + this->noInputTimerMax = 0; + } + + if (this->noInputTimer > 0) { + this->noInputTimer--; + if (this->noInputTimer <= 0) { + this->noInputTimerMax = 0; + } + } + + if (this->waitTimer <= 0) { + this->stateFlags &= ~ENHORSE_FLAG_9; + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.75f; + if ((SkelAnime_Update(&this->skin.skelAnime) || (this->actor.speedXZ == 0.0f)) && (this->noInputTimer <= 0)) { + if (this->actor.speedXZ > 3.0f) { + EnHorse_StartTrotting(this); + this->noInputTimer = 0; + this->noInputTimerMax = 0; + } else if ((stickMag < 10.0f) || (Math_CosS(stickAngle) <= -0.5f)) { + EnHorse_StartMountedIdleResetAnim(this); + this->noInputTimer = 0; + this->noInputTimerMax = 0; + } else { + EnHorse_MountedWalkingReset(this); + } + } + } else { + this->waitTimer--; + this->actor.speedXZ = 0.0f; + } +} + +void EnHorse_StartTrotting(EnHorse* this) { + this->action = ENHORSE_ACT_MOUNTED_REARING; + this->animationIdx = ENHORSE_ANIM_TROT; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedTrotReset(EnHorse* this) { + this->action = ENHORSE_ACT_MOUNTED_REARING; + this->animationIdx = ENHORSE_ANIM_TROT; + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); +} + +void EnHorse_MountedTrot(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle; + + EnHorse_UpdateSpeed(this, globalCtx, 0.3f, -0.5f, 10.0f, 0.06f, 6.0f, 800); + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + if (this->actor.speedXZ < 3.0f) { + EnHorse_StartWalkingInterruptable(this); + } + + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.375f; + + if (SkelAnime_Update(&this->skin.skelAnime)) { + func_8087C178(this); + func_8013ECE0(0.0f, 60, 8, 255); + if (this->actor.speedXZ >= 6.0f) { + EnHorse_StartGallopingInterruptable(this); + } else if (this->actor.speedXZ < 3.0f) { + EnHorse_StartWalkingInterruptable(this); + } else { + EnHorse_MountedTrotReset(this); + } + } +} + +void EnHorse_StartGallopingInterruptable(EnHorse* this) { + this->noInputTimer = 0; + this->noInputTimerMax = 0; + EnHorse_StartGalloping(this); +} + +void EnHorse_StartGalloping(EnHorse* this) { + this->action = ENHORSE_ACT_STOPPING; + this->animationIdx = ENHORSE_ANIM_GALLOP; + this->unk_230 = 0; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedGallopReset(EnHorse* this) { + this->noInputTimer = 0; + this->noInputTimerMax = 0; + this->action = ENHORSE_ACT_STOPPING; + this->animationIdx = ENHORSE_ANIM_GALLOP; + this->unk_230 = 0; + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); +} + +void EnHorse_JumpLanding(EnHorse* this, GlobalContext* globalCtx) { + Vec3s* jointTable; + f32 y; + + this->action = ENHORSE_ACT_STOPPING; + this->animationIdx = ENHORSE_ANIM_GALLOP; + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y += y * 0.01f * this->unk_528 * 0.01f; + this->postDrawFunc = NULL; +} + +void EnHorse_MountedGallop(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle; + + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + + if (this->noInputTimer <= 0) { + EnHorse_UpdateSpeed(this, globalCtx, 0.3f, -0.5f, 10.0f, 0.06f, 8.0f, 800); + } else if (this->noInputTimer > 0) { + this->noInputTimer--; + this->actor.speedXZ = 8.0f; + } + + if (this->actor.speedXZ < 6.0f) { + EnHorse_StartTrotting(this); + } + + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; + + if (SkelAnime_Update(&this->skin.skelAnime)) { + func_8087C1C0(this); + func_8013ECE0(0.0f, 120, 8, 255); + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if ((stickMag >= 10.0f) && (Math_CosS(stickAngle) <= -0.5f)) { + EnHorse_StartBraking(this, globalCtx); + } else if (this->actor.speedXZ < 6.0f) { + EnHorse_StartTrotting(this); + } else { + EnHorse_MountedGallopReset(this); + } + } else { + EnHorse_MountedGallopReset(this); + } + } +} + +void EnHorse_StartRearing(EnHorse* this) { + this->action = ENHORSE_ACT_REVERSE; + this->animationIdx = ENHORSE_ANIM_REARING; + + if (sAnimationHeaders[this->type][this->animationIdx] == NULL) { + if (Rand_ZeroOne() > 0.5f) { + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + func_8013ECE0(0.0f, 180, 20, 100); + this->stateFlags &= ~ENHORSE_STOPPING_NEIGH_SOUND; + } + EnHorse_StartMountedIdleResetAnim(this); + } + + this->stateFlags &= ~ENHORSE_LAND2_SOUND; + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + + func_8013ECE0(0.0f, 180, 20, 100); + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_MountedRearing(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle; + + this->actor.speedXZ = 0.0f; + if (this->curFrame > 25.0f) { + if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { + this->stateFlags |= ENHORSE_LAND2_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + func_8013ECE0(0.0f, 180, 20, 100); + } + } + + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + + if (SkelAnime_Update(&this->skin.skelAnime)) { + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if (this->stateFlags & ENHORSE_FORCE_REVERSING) { + this->noInputTimer = 100; + this->noInputTimerMax = 100; + this->stateFlags &= ~ENHORSE_FORCE_REVERSING; + EnHorse_StartReversing(this); + } else if (this->stateFlags & ENHORSE_FORCE_WALKING) { + this->noInputTimer = 100; + this->noInputTimerMax = 100; + this->stateFlags &= ~ENHORSE_FORCE_WALKING; + EnHorse_StartWalking(this); + } else if (Math_CosS(stickAngle) <= -0.5f) { + EnHorse_StartReversingInterruptable(this); + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } +} + +void EnHorse_StartBraking(EnHorse* this, GlobalContext* globalCtx) { + this->action = ENHORSE_ACT_LOW_JUMP; + this->animationIdx = ENHORSE_ANIM_STOPPING; + if (sAnimationHeaders[this->type][this->animationIdx] == NULL) { + if (Rand_ZeroOne() > 0.5f) { + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + func_8013ECE0(0.0f, 180, 20, 100); + this->stateFlags &= ~ENHORSE_STOPPING_NEIGH_SOUND; + } + EnHorse_StartMountedIdleResetAnim(this); + } + + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_SLIP); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_SLIP); + } + + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + this->stateFlags |= ENHORSE_STOPPING_NEIGH_SOUND; + this->stateFlags &= ~ENHORSE_BOOST; +} + +void EnHorse_Stopping(EnHorse* this, GlobalContext* globalCtx) { + if (this->actor.speedXZ > 0.0f) { + this->actor.speedXZ -= 0.6f; + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + } + + if ((this->stateFlags & ENHORSE_STOPPING_NEIGH_SOUND) && (this->skin.skelAnime.curFrame > 29.0f)) { + this->actor.speedXZ = 0.0f; + if ((Rand_ZeroOne() > 0.5f) && + ((gSaveContext.save.entranceIndex != 0x6400) || !Cutscene_GetSceneSetupIndex(globalCtx))) { + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + func_8013ECE0(0.0f, 180, 20, 100); + this->stateFlags &= ~ENHORSE_STOPPING_NEIGH_SOUND; + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } + + if (this->skin.skelAnime.curFrame > 29.0f) { + this->actor.speedXZ = 0.0f; + } else if ((this->actor.speedXZ > 3.0f) && (this->stateFlags & ENHORSE_FORCE_REVERSING)) { + this->actor.speedXZ = 3.0f; + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + if (this->stateFlags & ENHORSE_FORCE_REVERSING) { + this->noInputTimer = 100; + this->noInputTimerMax = 100; + EnHorse_StartReversing(this); + this->stateFlags &= ~ENHORSE_FORCE_REVERSING; + } else { + EnHorse_StartMountedIdleResetAnim(this); + } + } +} + +void EnHorse_StartReversingInterruptable(EnHorse* this) { + this->noInputTimer = 0; + this->noInputTimerMax = 0; + EnHorse_StartReversing(this); +} + +void EnHorse_StartReversing(EnHorse* this) { + this->action = ENHORSE_ACT_HIGH_JUMP; + this->animationIdx = ENHORSE_ANIM_WALK; + this->soundTimer = 0; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_LOOP, -3.0f); +} + +void EnHorse_Reverse(EnHorse* this, GlobalContext* globalCtx) { + f32 stickMag; + s16 stickAngle; + s16 turnAmount; + Player* player = GET_PLAYER(globalCtx); + + EnHorse_PlayWalkingSound(this); + EnHorse_StickDirection(&this->curStick, &stickMag, &stickAngle); + if (EnHorse_PlayerCanMove(this, globalCtx) == true) { + if ((this->noInputTimerMax == 0) || + ((this->noInputTimer > 0) && (this->noInputTimer < (this->noInputTimerMax - 20)))) { + if ((stickMag < 10.0f) && (this->noInputTimer <= 0)) { + EnHorse_StartMountedIdleResetAnim(this); + this->actor.speedXZ = 0.0f; + return; + } else if (stickMag < 10.0f) { + stickAngle = -0x7FFF; + } else if (Math_CosS(stickAngle) > -0.5f) { + this->noInputTimerMax = 0; + EnHorse_StartMountedIdleResetAnim(this); + this->actor.speedXZ = 0.0f; + return; + } + } else if (stickMag < 10.0f) { + stickAngle = -0x7FFF; + } + } else if ((player->actor.flags & ACTOR_FLAG_100) || (globalCtx->csCtx.state != 0) || + (ActorCutscene_GetCurrentIndex() != -1) || (player->stateFlags1 & 0x20)) { + EnHorse_StartMountedIdleResetAnim(this); + this->actor.speedXZ = 0.0f; + return; + } else { + stickAngle = -0x7FFF; + } + + this->actor.speedXZ = -2.0f; + turnAmount = -0x8000 - stickAngle; + turnAmount = CLAMP(turnAmount, -2400.0f, 2400.0f); + this->actor.world.rot.y += turnAmount; + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (this->noInputTimer > 0) { + this->noInputTimer--; + if (this->noInputTimer <= 0) { + this->noInputTimerMax = 0; + } + } + + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.5f * 1.5f; + + if (SkelAnime_Update(&this->skin.skelAnime) && (this->noInputTimer <= 0) && + (EnHorse_PlayerCanMove(this, globalCtx) == true)) { + if ((stickMag > 10.0f) && (Math_CosS(stickAngle) <= -0.5f)) { + this->noInputTimerMax = 0; + EnHorse_StartReversingInterruptable(this); + } else if (stickMag < 10.0f) { + this->noInputTimerMax = 0; + EnHorse_StartMountedIdleResetAnim(this); + } else { + EnHorse_StartReversing(this); + } + } +} + +void EnHorse_LowJumpInit(EnHorse* this, GlobalContext* globalCtx) { + this->skin.skelAnime.curFrame = 0.0f; + EnHorse_StartLowJump(this, globalCtx); +} + +void EnHorse_StartLowJump(EnHorse* this, GlobalContext* globalCtx) { + f32 curFrame; + Vec3s* jointTable; + f32 y; + + this->action = ENHORSE_ACT_BRIDGE_JUMP; + this->animationIdx = ENHORSE_ANIM_LOW_JUMP; + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + this->postDrawFunc = NULL; + this->jumpStartY = this->actor.world.pos.y; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y -= ((y * 0.01f) * this->unk_528) * 0.01f; + + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } + func_8013ECE0(0.0f, 170, 10, 10); +} + +void EnHorse_Stub1(EnHorse* this) { +} + +void EnHorse_LowJump(EnHorse* this, GlobalContext* globalCtx) { + Vec3f pad; + f32 temp_f0; + f32 curFrame; + Vec3s* jointTable; + + this->stateFlags |= ENHORSE_JUMPING; + + if (this->actor.speedXZ < 12.0f) { + this->actor.speedXZ = 12.0f; + } + + if (this->actor.floorHeight != BGCHECK_Y_MIN) { + CollisionPoly* colPoly; + s32 floorBgId; + Vec3f pos = this->actor.world.pos; + + pos.y = this->actor.floorHeight - 5.0f; + temp_f0 = + BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &colPoly, &floorBgId, &this->actor, &pos); + if ((this->actor.floorHeight - 120.0f) < temp_f0) { + this->actor.floorHeight = temp_f0; + this->actor.floorPoly = colPoly; + this->actor.floorBgId = floorBgId; + } + } + + curFrame = this->skin.skelAnime.curFrame; + + if (curFrame > 17.0f) { + this->actor.gravity = -3.5f; + if (this->actor.velocity.y == 0.0f) { + this->actor.velocity.y = -6.0f; + } + if (this->actor.world.pos.y < (this->actor.floorHeight + 90.0f)) { + this->skin.skelAnime.playSpeed = 1.5f; + } else { + this->skin.skelAnime.playSpeed = 0.0f; + } + } else { + jointTable = this->skin.skelAnime.jointTable; + temp_f0 = jointTable->y; + + this->actor.world.pos.y = this->jumpStartY + (temp_f0 * 0.01f * this->unk_528 * 0.01f); + } + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((curFrame > 17.0f) && + (this->actor.world.pos.y < ((this->actor.floorHeight - this->actor.velocity.y) + 80.0f)))) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } + func_8013ECE0(0.0f, 255, 10, 80); + this->stateFlags &= ~ENHORSE_JUMPING; + this->actor.gravity = -3.5f; + this->actor.world.pos.y = this->actor.floorHeight; + EnHorse_JumpLanding(this, globalCtx); + } +} + +void EnHorse_HighJumpInit(EnHorse* this, GlobalContext* globalCtx) { + this->skin.skelAnime.curFrame = 0.0f; + EnHorse_StartHighJump(this, globalCtx); +} + +void EnHorse_StartHighJump(EnHorse* this, GlobalContext* globalCtx) { + f32 curFrame; + Vec3s* jointTable; + f32 y; + + this->action = ENHORSE_ACT_CS_UPDATE; + this->animationIdx = ENHORSE_ANIM_HIGH_JUMP; + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + + this->postDrawFunc = NULL; + this->jumpStartY = this->actor.world.pos.y; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y -= ((y * 0.01f) * this->unk_528) * 0.01f; + + this->stateFlags |= ENHORSE_CALC_RIDER_POS; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } + func_8013ECE0(0.0f, 170, 10, 10); +} + +void EnHorse_Stub2(EnHorse* this) { +} + +void EnHorse_HighJump(EnHorse* this, GlobalContext* globalCtx) { + Vec3f pad; + f32 temp_f0; + f32 curFrame; + Vec3s* jointTable; + + this->stateFlags |= ENHORSE_JUMPING; + + if (this->actor.speedXZ < 13.0f) { + this->actor.speedXZ = 13.0f; + } + + if (this->actor.floorHeight != BGCHECK_Y_MIN) { + CollisionPoly* colPoly; + s32 floorBgId; + Vec3f pos = this->actor.world.pos; + + pos.y = this->actor.floorHeight - 5.0f; + temp_f0 = + BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &colPoly, &floorBgId, &this->actor, &pos); + if ((this->actor.floorHeight - 120.0f) < temp_f0) { + this->actor.floorHeight = temp_f0; + this->actor.floorPoly = colPoly; + this->actor.floorBgId = floorBgId; + } + } + + curFrame = this->skin.skelAnime.curFrame; + + if (curFrame > 23.0f) { + this->actor.gravity = -3.5f; + if (this->actor.velocity.y == 0.0f) { + this->actor.velocity.y = -10.5f; + } + if (this->actor.world.pos.y < (this->actor.floorHeight + 90.0f)) { + this->skin.skelAnime.playSpeed = 1.5f; + } else { + this->skin.skelAnime.playSpeed = 0.0f; + } + } else { + jointTable = this->skin.skelAnime.jointTable; + temp_f0 = jointTable->y; + this->actor.world.pos.y = this->jumpStartY + (temp_f0 * 0.01f * this->unk_528 * 0.01f); + } + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((curFrame > 23.0f) && + (this->actor.world.pos.y < ((this->actor.floorHeight - this->actor.velocity.y) + 80.0f)))) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } + func_8013ECE0(0.0f, 255, 10, 80); + this->stateFlags &= ~ENHORSE_JUMPING; + this->actor.gravity = -3.5f; + this->actor.world.pos.y = this->actor.floorHeight; + func_800B1598(globalCtx, 25.0f, &this->actor.world.pos); + EnHorse_JumpLanding(this, globalCtx); + } +} + +void EnHorse_InitInactive(EnHorse* this) { + this->colliderCylinder1.base.ocFlags1 &= ~OC1_ON; + this->colliderCylinder2.base.ocFlags1 &= ~OC1_ON; + this->colliderJntSph.base.ocFlags1 &= ~OC1_ON; + this->action = ENHORSE_ACT_INACTIVE; + this->animationIdx = ENHORSE_ANIM_WALK; + this->stateFlags |= ENHORSE_INACTIVE; + this->followTimer = 0; +} + +void EnHorse_Inactive(EnHorse* this, GlobalContext* globalCtx) { + if ((D_801BDAA4 != 0) && (this->type == HORSE_2)) { + D_801BDAA4 = 0; + if (EnHorse_Spawn(this, globalCtx)) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_NEIGH); + } + this->stateFlags &= ~ENHORSE_INACTIVE; + } + } + + if (!(this->stateFlags & ENHORSE_INACTIVE)) { + this->followTimer = 0; + EnHorse_SetFollowAnimation(this, globalCtx); + this->actor.params = ENHORSE_0; + this->colliderCylinder1.base.ocFlags1 |= OC1_ON; + this->colliderCylinder2.base.ocFlags1 |= OC1_ON; + this->colliderJntSph.base.ocFlags1 |= OC1_ON; + } +} + +void EnHorse_PlayIdleAnimation(EnHorse* this, s32 anim, f32 morphFrames, f32 startFrames) { + this->action = ENHORSE_ACT_IDLE; + this->actor.speedXZ = 0.0f; + + if ((anim != ENHORSE_ANIM_IDLE) && (anim != ENHORSE_ANIM_WHINNEY) && (anim != ENHORSE_ANIM_REARING)) { + anim = ENHORSE_ANIM_IDLE; + } + + if (sAnimationHeaders[this->type][anim] == NULL) { + anim = ENHORSE_ANIM_IDLE; + } + + if (anim != this->animationIdx) { + this->animationIdx = anim; + if (anim == ENHORSE_ANIM_IDLE) { + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; + } else { + if (this->animationIdx == ENHORSE_ANIM_WHINNEY) { + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_GROAN); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_GROAN); + } + } + } else if (this->animationIdx == ENHORSE_ANIM_REARING) { + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + this->stateFlags &= ~ENHORSE_LAND2_SOUND; + } + } + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, startFrames, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + morphFrames); + } +} + +void EnHorse_ChangeIdleAnimation(EnHorse* this, s32 anim, f32 morphFrames) { + EnHorse_PlayIdleAnimation(this, anim, morphFrames, this->curFrame); +} + +void EnHorse_ResetIdleAnimation(EnHorse* this) { + this->animationIdx = ENHORSE_ANIM_WALK; + EnHorse_PlayIdleAnimation(this, this->animationIdx, 0.0f, 0.0f); +} + +void EnHorse_StartIdleRidable(EnHorse* this) { + EnHorse_ResetIdleAnimation(this); + this->stateFlags &= ~ENHORSE_UNRIDEABLE; +} + +void EnHorse_Idle(EnHorse* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + EnHorse_IdleAnimSounds(this, globalCtx); + + if ((D_801BDAA4 != 0) && (this->type == HORSE_2)) { + D_801BDAA4 = 0; + if (!func_8087C38C(globalCtx, this, &this->actor.world.pos)) { + if (EnHorse_Spawn(this, globalCtx)) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_NEIGH); + } + this->followTimer = 0; + EnHorse_SetFollowAnimation(this, globalCtx); + } + } else { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_NEIGH); + } + this->followTimer = 0; + EnHorse_StartMovingAnimation(this, 6, -3.0f, 0.0f); + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + s32 idleAnimIdx = 0; + + if (this->animationIdx != 0) { + if (this->animationIdx == 1) { + idleAnimIdx = 1; + } else if (this->animationIdx == 3) { + idleAnimIdx = 2; + } + } + // Play one of the two other idle animations + EnHorse_PlayIdleAnimation(this, sIdleAnimIds[((Rand_ZeroOne() > 0.5f) ? 0 : 1) + idleAnimIdx * 2], 0.0f, 0.0f); + } +} + +void EnHorse_StartMovingAnimation(EnHorse* this, s32 anim, f32 morphFrames, f32 startFrames) { + this->action = ENHORSE_ACT_FOLLOW_PLAYER; + this->stateFlags &= ~ENHORSE_TURNING_TO_PLAYER; + + if ((anim != ENHORSE_ANIM_TROT) && (anim != ENHORSE_ANIM_GALLOP) && (anim != ENHORSE_ANIM_WALK)) { + anim = ENHORSE_ANIM_WALK; + } + + if (anim != this->animationIdx) { + this->animationIdx = anim; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, startFrames, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + morphFrames); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, startFrames, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void EnHorse_SetFollowAnimation(EnHorse* this, GlobalContext* globalCtx) { + s32 anim = ENHORSE_ANIM_WALK; + f32 distToPlayer = Actor_XZDistanceBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor); + + if (distToPlayer > 400.0f) { + anim = ENHORSE_ANIM_GALLOP; + } else if (!(distToPlayer <= 300.0f) && (distToPlayer <= 400.0f)) { + anim = ENHORSE_ANIM_TROT; + } + + if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + if (distToPlayer > 400.0f) { + anim = ENHORSE_ANIM_GALLOP; + } else { + anim = ENHORSE_ANIM_TROT; + } + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + if (distToPlayer > 400.0f) { + anim = ENHORSE_ANIM_GALLOP; + } else if (distToPlayer < 300.0f) { + anim = ENHORSE_ANIM_WALK; + } else { + anim = ENHORSE_ANIM_TROT; + } + } else if (this->animationIdx == ENHORSE_ANIM_WALK) { + if (distToPlayer > 300.0f) { + anim = ENHORSE_ANIM_TROT; + } else { + anim = ENHORSE_ANIM_WALK; + } + } + + EnHorse_StartMovingAnimation(this, anim, -3.0f, 0.0f); +} + +void EnHorse_FollowPlayer(EnHorse* this, GlobalContext* globalCtx) { + f32 distToPlayer; + + D_801BDAA4 = 0; + distToPlayer = Actor_XZDistanceBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor); + + if (((this->playerDir == PLAYER_DIR_BACK_R) || (this->playerDir == PLAYER_DIR_BACK_L)) && (distToPlayer > 300.0f) && + !(this->stateFlags & ENHORSE_TURNING_TO_PLAYER)) { + f32 angleDiff; + + this->animationIdx = ENHORSE_ANIM_REARING; + this->stateFlags |= ENHORSE_TURNING_TO_PLAYER; + this->angleToPlayer = Actor_YawBetweenActors(&this->actor, &GET_PLAYER(globalCtx)->actor); + + angleDiff = (f32)this->angleToPlayer - this->actor.world.rot.y; + if (angleDiff > 0x7FFF) { + angleDiff -= 0x7FFF; + } else if (angleDiff < -0x7FFF) { + angleDiff += 0x7FFF; + } + + this->followPlayerTurnSpeed = + angleDiff / Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]); + + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + this->skin.skelAnime.playSpeed = 1.0f; + this->stateFlags &= ~ENHORSE_LAND2_SOUND; + } else if (this->stateFlags & ENHORSE_TURNING_TO_PLAYER) { + this->actor.world.rot.y += this->followPlayerTurnSpeed; + this->actor.shape.rot.y = this->actor.world.rot.y; + if ((this->curFrame > 25.0f) && !(this->stateFlags & ENHORSE_LAND2_SOUND)) { + this->stateFlags |= ENHORSE_LAND2_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + } + } else { + EnHorse_RotateToPlayer(this, globalCtx); + } + + if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + this->actor.speedXZ = 8.0f; + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; + } else { + if (this->animationIdx == ENHORSE_ANIM_TROT) { + this->actor.speedXZ = 6.0f; + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.375f; + } else if (this->animationIdx == ENHORSE_ANIM_WALK) { + this->actor.speedXZ = 3.0f; + EnHorse_PlayWalkingSound(this); + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.75f; + } else { + this->actor.speedXZ = 0.0f; + this->skin.skelAnime.playSpeed = 1.0f; + } + } + + if (!(this->stateFlags & ENHORSE_TURNING_TO_PLAYER)) { + this->followTimer++; + if (this->followTimer > 300) { + EnHorse_StartIdleRidable(this); + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + func_8087C1C0(this); + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + func_8087C178(this); + } + + this->stateFlags &= ~ENHORSE_TURNING_TO_PLAYER; + + if (distToPlayer < 100.0f) { + EnHorse_StartIdleRidable(this); + } else { + EnHorse_SetFollowAnimation(this, globalCtx); + } + } +} + +void EnHorse_InitIngoHorse(EnHorse* this) { + this->curRaceWaypoint = 0; + this->soundTimer = 0; + this->actor.speedXZ = 0.0f; + EnHorse_UpdateIngoHorseAnim(this); + if (this->stateFlags & ENHORSE_DRAW) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_IT_INGO_HORSE_NEIGH); + } +} + +void EnHorse_SetIngoAnimation(s32 anim, f32 curFrame, s32 arg2, s16* animIdxOut) { + *animIdxOut = sIngoAnimations[anim]; + if (arg2 == 1) { + if (anim == 5) { + *animIdxOut = 4; + } else if (anim == 6) { + *animIdxOut = 3; + } + } +} + +void EnHorse_UpdateIngoHorseAnim(EnHorse* this) { + s32 animChanged = false; + f32 animSpeed; + + this->action = ENHORSE_ACT_INGO_RACE; + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; + + if (this->actor.speedXZ == 0.0f) { + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_IDLE; + } else if (this->actor.speedXZ <= 3.0f) { + if (this->animationIdx != ENHORSE_ANIM_WALK) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_WALK; + } else if (this->actor.speedXZ <= 6.0f) { + if (this->animationIdx != ENHORSE_ANIM_TROT) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_TROT; + } else { + if (this->animationIdx != ENHORSE_ANIM_GALLOP) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_GALLOP; + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + animSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + animSpeed = this->actor.speedXZ * 0.25f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + animSpeed = this->actor.speedXZ * 0.2f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + } else { + animSpeed = 1.0f; + } + + if (animChanged == true) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * animSpeed * 1.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * animSpeed * 1.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void EnHorse_UpdateIngoRace(EnHorse* this, GlobalContext* globalCtx) { + f32 playSpeed; + + if ((this->animationIdx == ENHORSE_ANIM_IDLE) || (this->animationIdx == ENHORSE_ANIM_WHINNEY)) { + EnHorse_IdleAnimSounds(this, globalCtx); + } else if (this->animationIdx == ENHORSE_ANIM_WALK) { + EnHorse_PlayWalkingSound(this); + } + + if (!this->inRace) { + this->actor.speedXZ = 0.0f; + this->rider->actor.speedXZ = 0.0f; + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + EnHorse_UpdateIngoHorseAnim(this); + } + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + playSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == 5) { + playSpeed = this->actor.speedXZ * 0.25f; + } else if (this->animationIdx == 6) { + playSpeed = this->actor.speedXZ * 0.2f; + } else { + playSpeed = 1.0f; + } + this->skin.skelAnime.playSpeed = playSpeed; + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((this->animationIdx == ENHORSE_ANIM_IDLE) && (this->actor.speedXZ != 0.0f))) { + EnHorse_UpdateIngoHorseAnim(this); + } +} + +void func_8088126C(EnHorse* this, GlobalContext* globalCtx) { + this->skin.skelAnime.curFrame = 0.0f; + func_80881290(this, globalCtx); +} + +void func_80881290(EnHorse* this, GlobalContext* globalCtx) { + f32 curFrame; + + this->action = ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING; + this->animationIdx = ENHORSE_ANIM_HIGH_JUMP; + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + this->postDrawFunc = NULL; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->jumpStartY = this->actor.world.pos.y; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } + func_8013ECE0(0.0f, 170, 10, 10); +} + +void func_80881398(EnHorse* this, GlobalContext* globalCtx) { + Vec3s* jointTable; + f32 y; + s32 animeUpdated; + f32 curFrame; + + this->stateFlags |= ENHORSE_JUMPING; + if (this->actor.speedXZ < 14.0f) { + this->actor.speedXZ = 14.0f; + } + + animeUpdated = SkelAnime_Update(&this->skin.skelAnime); + curFrame = this->skin.skelAnime.curFrame; + + if (curFrame > 23.0f) { + this->actor.gravity = -3.5f; + if (this->actor.velocity.y == 0.0f) { + this->actor.velocity.y = -10.5f; + } + if (this->actor.world.pos.y < (this->actor.floorHeight + 90.0f)) { + this->skin.skelAnime.playSpeed = 1.5f; + } else { + this->skin.skelAnime.playSpeed = 0.0f; + } + } else { + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->actor.world.pos.y = this->jumpStartY + (y * 0.01f * this->unk_528 * 0.01f); + } + + if (animeUpdated || ((curFrame > 17.0f) && + (this->actor.world.pos.y < ((this->actor.floorHeight - this->actor.velocity.y) + 80.0f)))) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } + func_8013ECE0(0.0f, 255, 10, 80); + this->stateFlags &= ~ENHORSE_JUMPING; + this->stateFlags &= ~ENHORSE_FLAG_30; + this->actor.gravity = -3.5f; + this->actor.world.pos.y = this->actor.floorHeight; + func_800B1598(globalCtx, 25.0f, &this->actor.world.pos); + func_8088159C(this, globalCtx); + } +} + +void func_8088159C(EnHorse* this, GlobalContext* globalCtx) { + Vec3s* jointTable; + f32 y; + + this->action = ENHORSE_ACT_MOUNTED_IDLE; + this->animationIdx = ENHORSE_ANIM_GALLOP; + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y += y * 0.01f * this->unk_528 * 0.01f; + this->postDrawFunc = NULL; +} + +void func_80881634(EnHorse* this) { + this->curRaceWaypoint = 0; + this->soundTimer = 0; + this->actor.speedXZ = 0.0f; + func_8088168C(this); + if (this->stateFlags & ENHORSE_DRAW) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_IT_INGO_HORSE_NEIGH); + } +} + +void func_8088168C(EnHorse* this) { + s32 animChanged = false; + f32 animSpeed; + f32 finalAnimSpeed; + + this->action = ENHORSE_ACT_MOUNTED_IDLE; + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; + + if (this->actor.speedXZ == 0.0f) { + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_IDLE; + } else if (this->actor.speedXZ <= 3.0f) { + if (this->animationIdx != ENHORSE_ANIM_WALK) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_WALK; + } else if (this->actor.speedXZ <= 6.0f) { + if (this->animationIdx != ENHORSE_ANIM_TROT) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_TROT; + } else { + if (this->animationIdx != ENHORSE_ANIM_GALLOP) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_GALLOP; + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + animSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + animSpeed = this->actor.speedXZ * 0.25f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + animSpeed = this->actor.speedXZ * 0.2f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + } else { + animSpeed = 1.0f; + } + + finalAnimSpeed = sPlaybackSpeeds[this->animationIdx] * animSpeed * 1.5f; + if (finalAnimSpeed < 1.0f) { + finalAnimSpeed = 1.0f; + } + + if (animChanged == true) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], finalAnimSpeed, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], finalAnimSpeed, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void func_808819D8(EnHorse* this, GlobalContext* globalCtx) { + Path* path; + f32 animSpeed; + + if ((this->animationIdx == ENHORSE_ANIM_IDLE) || (this->animationIdx == ENHORSE_ANIM_WHINNEY)) { + EnHorse_IdleAnimSounds(this, globalCtx); + } else if (this->animationIdx == ENHORSE_ANIM_WALK) { + EnHorse_PlayWalkingSound(this); + } + + if (!this->inRace) { + this->actor.speedXZ = 0.0f; + this->rider->actor.speedXZ = 0.0f; + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + EnHorse_UpdateIngoHorseAnim(this); + } + } + + if (this->actor.params == ENHORSE_4) { + path = &globalCtx->setupPathList[0]; + func_8087B7C0(this, globalCtx, path); + } else if (this->actor.params == ENHORSE_5) { + path = &globalCtx->setupPathList[1]; + func_8087B7C0(this, globalCtx, path); + } + + if (!this->inRace) { + this->actor.speedXZ = 0.0f; + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + func_8088168C(this); + } + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + animSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + animSpeed = this->actor.speedXZ * 0.25f; + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + animSpeed = this->actor.speedXZ * 0.2f; + } else { + animSpeed = 1.0f; + } + this->skin.skelAnime.playSpeed = animSpeed; + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((this->animationIdx == ENHORSE_ANIM_IDLE) && (this->actor.speedXZ != 0.0f))) { + func_8088168C(this); + } + + if ((gSaveContext.save.weekEventReg[92] & (1 | 2 | 4)) == 3) { + this->rider->unk488 = 7; + } else { + EnHorse_SetIngoAnimation(this->animationIdx, this->skin.skelAnime.curFrame, this->unk_394 & 1, + &this->rider->unk488); + } +} + +void EnHorse_CsMoveInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->animationIdx = ENHORSE_ANIM_GALLOP; + this->cutsceneAction = 1; + Animation_PlayOnceSetSpeed(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + this->actor.speedXZ * 0.2f * 1.5f); +} + +void EnHorse_CsMoveToPoint(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Vec3f endPos; + s32 pad; + + endPos.x = action->endPos.x; + endPos.y = action->endPos.y; + endPos.z = action->endPos.z; + + if (Math3D_Distance(&endPos, &this->actor.world.pos) > 8.0f) { + EnHorse_RotateToPoint(this, globalCtx, &endPos, 0x320); + this->actor.speedXZ = 8.0f; + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; + } else { + this->actor.world.pos = endPos; + this->actor.speedXZ = 0.0f; + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + func_8087C1C0(this); + func_8013ECE0(0.0f, 120, 8, 255); + Animation_PlayOnceSetSpeed(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + this->actor.speedXZ * 0.3f); + } +} + +void EnHorse_CsSetAnimHighJump(EnHorse* this, GlobalContext* globalCtx) { + this->skin.skelAnime.curFrame = 0.0f; + EnHorse_CsPlayHighJumpAnim(this, globalCtx); +} + +void EnHorse_CsPlayHighJumpAnim(EnHorse* this, GlobalContext* globalCtx) { + f32 curFrame; + f32 y; + Vec3s* jointTable; + + this->animationIdx = ENHORSE_ANIM_HIGH_JUMP; + curFrame = this->skin.skelAnime.curFrame; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.5f, curFrame, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + this->postDrawFunc = NULL; + this->jumpStartY = this->actor.world.pos.y; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y -= y * 0.01f * this->unk_528 * 0.01f; + + this->stateFlags |= ENHORSE_ANIM_HIGH_JUMP; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_JUMP); + } + func_8013ECE0(0.0f, 170, 10, 10); +} + +void EnHorse_CsJumpInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + EnHorse_CsSetAnimHighJump(this, globalCtx); + this->cutsceneAction = 2; + this->cutsceneFlags &= ~1; +} + +void EnHorse_CsJump(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + f32 curFrame; + f32 y; + Vec3s* jointTable; + s32 pad[2]; + + if (this->cutsceneFlags & 1) { + EnHorse_CsMoveToPoint(this, globalCtx, action); + return; + } + + curFrame = this->skin.skelAnime.curFrame; + this->actor.speedXZ = 13.0f; + this->stateFlags |= ENHORSE_JUMPING; + + if (curFrame > 19.0f) { + this->actor.gravity = -3.5f; + if (this->actor.velocity.y == 0.0f) { + this->actor.velocity.y = -10.5f; + } + if (this->actor.world.pos.y < (this->actor.floorHeight + 90.0f)) { + this->skin.skelAnime.playSpeed = 1.5f; + } else { + this->skin.skelAnime.playSpeed = 0.0f; + } + } else { + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + + this->actor.world.pos.y = this->jumpStartY + (y * 0.01f * this->unk_528 * 0.01f); + } + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((curFrame > 19.0f) && + (this->actor.world.pos.y < ((this->actor.floorHeight - this->actor.velocity.y) + 80.0f)))) { + this->cutsceneFlags |= 1; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_LAND); + } + func_8013ECE0(0.0f, 255, 10, 80); + this->stateFlags &= ~ENHORSE_JUMPING; + this->actor.gravity = -3.5f; + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y = this->actor.floorHeight; + func_800B1598(globalCtx, 25.0f, &this->actor.world.pos); + this->animationIdx = ENHORSE_ANIM_GALLOP; + Animation_PlayOnceSetSpeed(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[6]); + + jointTable = this->skin.skelAnime.jointTable; + y = jointTable->y; + this->riderPos.y += y * 0.01f * this->unk_528 * 0.01f; + + this->postDrawFunc = NULL; + } +} + +void EnHorse_CsRearingInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->animationIdx = ENHORSE_ANIM_REARING; + this->cutsceneAction = 3; + this->cutsceneFlags &= ~4; + this->stateFlags &= ~ENHORSE_LAND2_SOUND; + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_CsRearing(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->actor.speedXZ = 0.0f; + if (this->curFrame > 25.0f) { + if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { + this->stateFlags |= ENHORSE_LAND2_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + this->animationIdx = ENHORSE_ANIM_IDLE; + if (!(this->cutsceneFlags & 4)) { + this->cutsceneFlags |= 4; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_LOOP, + 0.0f); + } + } +} + +void EnHorse_WarpMoveInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->actor.world.pos.x = action->startPos.x; + this->actor.world.pos.y = action->startPos.y; + this->actor.world.pos.z = action->startPos.z; + this->actor.prevPos = this->actor.world.pos; + + this->actor.world.rot.y = action->urot.y; + this->actor.shape.rot = this->actor.world.rot; + + this->animationIdx = ENHORSE_ANIM_GALLOP; + this->cutsceneAction = 4; + Animation_PlayOnceSetSpeed(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + this->actor.speedXZ * 0.3f); +} + +void EnHorse_CsWarpMoveToPoint(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Vec3f endPos; + s32 pad; + + endPos.x = action->endPos.x; + endPos.y = action->endPos.y; + endPos.z = action->endPos.z; + + if (Math3D_Distance(&endPos, &this->actor.world.pos) > 8.0f) { + EnHorse_RotateToPoint(this, globalCtx, &endPos, 0x320); + this->actor.speedXZ = 8.0f; + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; + } else { + this->actor.world.pos = endPos; + this->actor.speedXZ = 0.0f; + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + func_8087C1C0(this); + func_8013ECE0(0.0f, 120, 8, 255); + Animation_PlayOnceSetSpeed(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + this->actor.speedXZ * 0.3f); + } +} + +void EnHorse_CsWarpRearingInit(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->actor.world.pos.x = action->startPos.x; + this->actor.world.pos.y = action->startPos.y; + this->actor.world.pos.z = action->startPos.z; + this->actor.prevPos = this->actor.world.pos; + + this->actor.world.rot.y = action->urot.y; + this->actor.shape.rot = this->actor.world.rot; + + this->animationIdx = ENHORSE_ANIM_REARING; + this->cutsceneAction = 5; + this->cutsceneFlags &= ~4; + this->stateFlags &= ~ENHORSE_LAND2_SOUND; + + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void EnHorse_CsWarpRearing(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + this->actor.speedXZ = 0.0f; + if (this->curFrame > 25.0f) { + if (!(this->stateFlags & ENHORSE_LAND2_SOUND)) { + this->stateFlags |= ENHORSE_LAND2_SOUND; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + } + } + + if (SkelAnime_Update(&this->skin.skelAnime)) { + this->animationIdx = ENHORSE_ANIM_IDLE; + if (!(this->cutsceneFlags & 4)) { + this->cutsceneFlags |= 4; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_LOOP, + 0.0f); + } + } +} + +void EnHorse_InitCutscene(EnHorse* this, GlobalContext* globalCtx) { + this->playerControlled = false; + this->action = ENHORSE_ACT_HBA; + this->cutsceneAction = 0; + this->actor.speedXZ = 0.0f; +} + +s32 EnHorse_GetCutsceneFunctionIndex(s32 csAction) { + s32 numActions = ARRAY_COUNT(sCsActionTable); // prevents unrolling + s32 i; + + for (i = 0; i < numActions; i++) { + if (csAction == sCsActionTable[i].csAction) { + return sCsActionTable[i].csFuncIdx; + } + + if (csAction < sCsActionTable[i].csAction) { + return 0; + } + } + return 0; +} + +void EnHorse_CutsceneUpdate(EnHorse* this, GlobalContext* globalCtx) { + s32 csFunctionIdx; + CsCmdActorAction* playerAction = globalCtx->csCtx.playerAction; + + if (globalCtx->csCtx.state == 3) { + this->playerControlled = true; + this->actor.params = ENHORSE_12; + this->action = ENHORSE_ACT_IDLE; + EnHorse_Freeze(this, globalCtx); + return; + } + + if (playerAction != NULL) { + csFunctionIdx = EnHorse_GetCutsceneFunctionIndex(playerAction->action); + if (csFunctionIdx != 0) { + if (csFunctionIdx != this->cutsceneAction) { + if (this->cutsceneAction == 0) { + this->actor.world.pos.x = playerAction->startPos.x; + this->actor.world.pos.y = playerAction->startPos.y; + this->actor.world.pos.z = playerAction->startPos.z; + + this->actor.world.rot.y = playerAction->urot.y; + this->actor.shape.rot = this->actor.world.rot; + this->actor.prevPos = this->actor.world.pos; + } + this->cutsceneAction = csFunctionIdx; + sCutsceneInitFuncs[csFunctionIdx](this, globalCtx, playerAction); + } + sCutsceneActionFuncs[this->cutsceneAction](this, globalCtx, playerAction); + } + } +} + +s32 EnHorse_UpdateHbaRaceInfo(EnHorse* this, GlobalContext* globalCtx, RaceInfo* raceInfo) { + Vec3f pos; + f32 px; + f32 pz; + f32 d; + + EnHorse_RaceWaypointPos(raceInfo->waypoints, this->curRaceWaypoint, &pos); + func_8017B7F8(&pos, raceInfo->waypoints[this->curRaceWaypoint].angle, &px, &pz, &d); + + if ((this->curRaceWaypoint >= (raceInfo->numWaypoints - 1)) && + (Math3D_Distance(&pos, &this->actor.world.pos) < DREG(8))) { + this->hbaFlags |= 2; + } + + if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) { + this->curRaceWaypoint++; + if (this->curRaceWaypoint >= raceInfo->numWaypoints) { + this->hbaFlags |= 1; + return true; + } + } + + if (!(this->hbaFlags & 1)) { + EnHorse_RotateToPoint(this, globalCtx, &pos, 0x640); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + if ((this->actor.speedXZ < raceInfo->waypoints[this->curRaceWaypoint].speed) && !(this->hbaFlags & 1)) { + this->actor.speedXZ += 0.4f; + } else { + this->actor.speedXZ -= 0.4f; + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + } + return false; +} + +void EnHorse_InitHorsebackArchery(EnHorse* this) { + this->hbaStarted = 0; + this->soundTimer = 0; + this->curRaceWaypoint = 0; + this->hbaTimer = 0; + this->actor.speedXZ = 0.0f; + EnHorse_UpdateHbaAnim(this); +} + +void EnHorse_UpdateHbaAnim(EnHorse* this) { + s32 animChanged = false; + f32 animSpeed; + + this->action = ENHORSE_ACT_FLEE_PLAYER; + if (this->actor.speedXZ == 0.0f) { + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_IDLE; + } else if (this->actor.speedXZ <= 3.0f) { + if (this->animationIdx != ENHORSE_ANIM_WALK) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_WALK; + } else if (this->actor.speedXZ <= 6.0f) { + if (this->animationIdx != ENHORSE_ANIM_TROT) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_TROT; + } else { + if (this->animationIdx != ENHORSE_ANIM_GALLOP) { + animChanged = true; + } + this->animationIdx = ENHORSE_ANIM_GALLOP; + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + animSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + animSpeed = this->actor.speedXZ * 0.25f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + func_8013ECE0(0.0f, 60, 8, 255); + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + animSpeed = this->actor.speedXZ * 0.2f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_RUN); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + func_8013ECE0(0.0f, 120, 8, 255); + } else { + animSpeed = 1.0f; + } + + if (animChanged == true) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * animSpeed * 1.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * animSpeed * 1.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void EnHorse_UpdateHorsebackArchery(EnHorse* this, GlobalContext* globalCtx) { + f32 playSpeed; + s32 sp28; + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + EnHorse_PlayWalkingSound(this); + } + + if (globalCtx->interfaceCtx.hbaAmmo == 0) { + this->hbaTimer++; + } + + sp28 = Audio_IsSequencePlaying(0x41); + EnHorse_UpdateHbaRaceInfo(this, globalCtx, &sHbaInfo); + + if (((this->hbaFlags & 1) || (this->hbaTimer > 45)) && (sp28 != 1) && (gSaveContext.minigameState != 3)) { + gSaveContext.save.cutscene = 0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 0x40; + } + + if (globalCtx->interfaceCtx.hbaAmmo) {} + + if (((globalCtx->interfaceCtx.hbaAmmo == 0) || (this->hbaFlags & 2)) && (this->hbaFlags & 4)) { + this->hbaFlags &= ~4; + Audio_QueueSeqCmd(0x8041); + } + + if (this->hbaStarted == 0) { + this->actor.speedXZ = 0.0f; + if (this->animationIdx != ENHORSE_ANIM_IDLE) { + EnHorse_UpdateHbaAnim(this); + } + } + + if (this->animationIdx == ENHORSE_ANIM_WALK) { + playSpeed = this->actor.speedXZ * 0.5f; + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + playSpeed = this->actor.speedXZ * 0.25f; + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + playSpeed = this->actor.speedXZ * 0.2f; + } else { + playSpeed = 1.0f; + } + this->skin.skelAnime.playSpeed = playSpeed; + + if (SkelAnime_Update(&this->skin.skelAnime) || + ((this->animationIdx == ENHORSE_ANIM_IDLE) && (this->actor.speedXZ != 0.0f))) { + EnHorse_UpdateHbaAnim(this); + } +} + +void EnHorse_FleePlayer(EnHorse* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 distToHome; + f32 playerDistToHome; + f32 distToPlayer; + s32 nextAnim = this->animationIdx; + s32 animFinished; + s16 yaw; + + if ((D_801BDAA4 != 0) || (this->type == HORSE_HNI)) { + EnHorse_StartIdleRidable(this); + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_NEIGH); + } + } + + distToHome = Math3D_Distance(&this->actor.home.pos, &this->actor.world.pos); + playerDistToHome = Math3D_Distance(&player->actor.world.pos, &this->actor.home.pos); + distToPlayer = Math3D_Distance(&player->actor.world.pos, &this->actor.world.pos); + + if (playerDistToHome > 300.0f) { + if (distToHome > 150.0f) { + this->actor.speedXZ += 0.4f; + if (this->actor.speedXZ > 8.0f) { + this->actor.speedXZ = 8.0f; + } + } else { + this->actor.speedXZ -= 0.5f; + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + } + } else if (distToPlayer < 300.0f) { + this->actor.speedXZ += 0.4f; + if (this->actor.speedXZ > 8.0f) { + this->actor.speedXZ = 8.0f; + } + } else { + this->actor.speedXZ -= 0.5f; + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } + } + + if (this->actor.speedXZ >= 6.0f) { + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.3f; + nextAnim = ENHORSE_ANIM_GALLOP; + } else if (this->actor.speedXZ >= 3.0f) { + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.375f; + nextAnim = ENHORSE_ANIM_TROT; + } else if (this->actor.speedXZ > 0.1f) { + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.75f; + nextAnim = ENHORSE_ANIM_WALK; + EnHorse_PlayWalkingSound(this); + } else { + if (Rand_ZeroOne() > 0.5f) { + nextAnim = ENHORSE_ANIM_WHINNEY; + } else { + nextAnim = ENHORSE_ANIM_IDLE; + } + EnHorse_IdleAnimSounds(this, globalCtx); + this->skin.skelAnime.playSpeed = 1.0f; + } + + if ((nextAnim == ENHORSE_ANIM_GALLOP) || (nextAnim == ENHORSE_ANIM_TROT) || (nextAnim == ENHORSE_ANIM_WALK)) { + if (playerDistToHome < 300.0f) { + yaw = player->actor.shape.rot.y; + yaw += ((Actor_YawBetweenActors(&this->actor, &player->actor) > 0) ? 1 : -1) * 0x3FFF; + } else { + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos) - this->actor.world.rot.y; + } + + if (yaw > 800.0f) { + this->actor.world.rot.y += 0x320; + } else if (yaw < -800.0f) { + this->actor.world.rot.y += -0x320; + } else { + this->actor.world.rot.y += yaw; + } + this->actor.shape.rot.y = this->actor.world.rot.y; + } + + animFinished = SkelAnime_Update(&this->skin.skelAnime); + + if (((this->animationIdx == ENHORSE_ANIM_IDLE) || (this->animationIdx == ENHORSE_ANIM_WHINNEY)) && + ((nextAnim == ENHORSE_ANIM_GALLOP) || (nextAnim == ENHORSE_ANIM_TROT) || (nextAnim == ENHORSE_ANIM_WALK))) { + this->animationIdx = nextAnim; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][nextAnim]), ANIMMODE_ONCE, -3.0f); + if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + func_8087C1C0(this); + } else if (this->animationIdx == ENHORSE_ANIM_TROT) { + func_8087C178(this); + } + } else if (animFinished) { + if (nextAnim == ENHORSE_ANIM_GALLOP) { + func_8087C1C0(this); + } else if (nextAnim == ENHORSE_ANIM_TROT) { + func_8087C178(this); + } + + if ((this->animationIdx == ENHORSE_ANIM_IDLE) || (this->animationIdx == ENHORSE_ANIM_WHINNEY)) { + if (nextAnim != this->animationIdx) { + this->animationIdx = nextAnim; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), + ANIMMODE_ONCE, -3.0f); + } else { + if (Rand_ZeroOne() > 0.5f) { + this->animationIdx = ENHORSE_ANIM_IDLE; + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; + } else { + this->animationIdx = ENHORSE_ANIM_WHINNEY; + if (this->stateFlags & ENHORSE_DRAW) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_GROAN); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_GROAN); + } + } + } + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), + ANIMMODE_ONCE, -3.0f); + } + } else if (nextAnim != this->animationIdx) { + this->animationIdx = nextAnim; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } + } else if ((this->animationIdx == ENHORSE_ANIM_WALK) && + ((nextAnim == ENHORSE_ANIM_IDLE) || (nextAnim == ENHORSE_ANIM_WHINNEY))) { + this->animationIdx = nextAnim; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + -3.0f); + } +} + +void func_80883B70(EnHorse* this, CsCmdActorAction* action) { + this->actor.world.pos.x = action->startPos.x; + this->actor.world.pos.y = action->startPos.y; + this->actor.world.pos.z = action->startPos.z; + + this->actor.world.rot.y = action->urot.y; + this->actor.shape.rot = this->actor.world.rot; + + this->actor.prevPos = this->actor.world.pos; +} + +void func_80883BEC(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->animationIdx = ENHORSE_ANIM_IDLE; + this->unk_3E0 = 1; + this->stateFlags &= ~ENHORSE_SANDDUST_SOUND; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, 0.0f); + this->stateFlags |= ENHORSE_SANDDUST_SOUND; +} + +void func_80883CB0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + EnHorse_IdleAnimSounds(this, globalCtx); + if (SkelAnime_Update(&this->skin.skelAnime)) { + this->animationIdx = ENHORSE_ANIM_IDLE; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void func_80883D64(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->unk_3E0 = 2; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00A8DC, 0.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00A8DC), ANIMMODE_ONCE, 0.0f); +} + +void func_80883DE0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + SkelAnime_Update(&this->skin.skelAnime); +} + +void func_80883E10(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->unk_3E0 = 3; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00A8DC, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00A8DC), ANIMMODE_ONCE, -3.0f); + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); +} + +void func_80883EA0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00B3E0, 1.0f, 11.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00B3E0), ANIMMODE_ONCE, 0.0f); + } +} + +void func_80883F18(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->unk_3E0 = 4; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00AD08, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00AD08), ANIMMODE_ONCE, -3.0f); +} + +void func_80883F98(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + if (Animation_OnFrame(&this->skin.skelAnime, Animation_GetLastFrame(&object_horse_link_child_Anim_00AD08) - 1.0f)) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_LAND2); + } + SkelAnime_Update(&this->skin.skelAnime); +} + +void func_80884010(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->unk_3E0 = 5; + this->animationIdx = ENHORSE_ANIM_WALK; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void func_808840C4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + EnHorse_PlayWalkingSound(this); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, this->unk_530); + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } +} + +void func_80884194(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + func_80883B70(this, action); + this->unk_3E0 = 6; + this->animationIdx = ENHORSE_ANIM_GALLOP; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); + func_8087C1C0(this); +} + +void func_8088424C(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, this->unk_530); + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + func_8087C1C0(this); + } +} + +void func_80884314(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 20.0f); + func_80883B70(this, action); + this->unk_3E0 = 7; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00D178, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00D178), ANIMMODE_ONCE, 0.0f); + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); +} + +void func_808843B4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + SkelAnime_Update(&this->skin.skelAnime); + if (this->curFrame > 42.0f) { + if (((s32)this->curFrame % 11) == 0) { + func_8087C1C0(this); + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, this->unk_530); + } +} + +void func_80884444(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 20.0f); + func_80883B70(this, action); + this->cutsceneAction = 8; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00D4E8, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00D4E8), ANIMMODE_ONCE, 0.0f); + func_8087C1C0(this); +} + +void func_808844E0(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, this->unk_530); + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00D4E8, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00D4E8), ANIMMODE_ONCE, 0.0f); + func_8087C1C0(this); + } +} + +void func_80884564(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 20.0f); + func_80883B70(this, action); + this->cutsceneAction = 8; + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00BDE0, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00BDE0), ANIMMODE_ONCE, -3.0f); + func_8087C1C0(this); +} + +void func_80884604(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, this->unk_530); + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, &object_horse_link_child_Anim_00BDE0, 1.0f, 0.0f, + Animation_GetLastFrame(&object_horse_link_child_Anim_00BDE0), ANIMMODE_ONCE, 0.0f); + } + + if (((s32)this->curFrame % 11) == 0) { + func_8087C1C0(this); + } +} + +void func_808846B4(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { + Actor_MarkForDeath(&this->actor); +} + +void func_808846DC(EnHorse* this, GlobalContext* globalCtx, CsCmdActorAction* action) { +} + +void func_808846F0(EnHorse* this, GlobalContext* globalCtx) { + this->playerControlled = false; + this->action = ENHORSE_ACT_21; + this->unk_3E0 = -1; + this->actor.speedXZ = 0.0f; +} + +void func_80884718(EnHorse* this, GlobalContext* globalCtx) { + CsCmdActorAction* action; + + if (Cutscene_CheckActorAction(globalCtx, 0x70)) { + this->unk_530 = Cutscene_GetActorActionIndex(globalCtx, 0x70); + action = globalCtx->csCtx.actorActions[this->unk_530]; + + this->unk_1EC |= 0x20; + if (this->unk_3E0 != action->action) { + if (this->unk_3E0 == -1) { + this->actor.world.pos.x = action->startPos.x; + this->actor.world.pos.y = action->startPos.y; + this->actor.world.pos.z = action->startPos.z; + + this->actor.world.rot.y = action->urot.y; + this->actor.shape.rot = this->actor.world.rot; + + this->actor.prevPos = this->actor.world.pos; + } + + this->unk_3E0 = action->action; + if (D_808890F0[this->unk_3E0] != NULL) { + D_808890F0[this->unk_3E0](this, globalCtx, action); + } + } + + if (D_8088911C[this->unk_3E0] != NULL) { + D_8088911C[this->unk_3E0](this, globalCtx, action); + } + } +} + +void func_80884868(EnHorse* this) { + this->action = ENHORSE_ACT_23; + this->animationIdx = ENHORSE_ANIM_WALK; + Animation_PlayLoop(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + this->stateFlags |= ENHORSE_UNRIDEABLE; +} + +void func_808848C8(EnHorse* this, GlobalContext* globalCtx) { + Vec3f sp24 = { -1916.0f, -106.0f, -523.0f }; + + EnHorse_PlayWalkingSound(this); + this->actor.speedXZ = 4.0f; + func_800F415C(&this->actor, &sp24, 2000); + this->skin.skelAnime.playSpeed = this->actor.speedXZ * 0.75f; + SkelAnime_Update(&this->skin.skelAnime); + if (Math3D_Distance(&sp24, &this->actor.world.pos) < 30.0f) { + this->stateFlags &= ~ENHORSE_UNRIDEABLE; + EnHorse_StartIdleRidable(this); + } +} + +void func_80884994(EnHorse* this) { + this->unk_534 = -1; + this->animationIdx = ENHORSE_ANIM_TROT; + this->action = ENHORSE_ACT_24; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 2.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, -3.0f); +} + +void func_80884A40(EnHorse* this, GlobalContext* globalCtx) { + s32 sp44[] = { 5, 6, 0 }; + s32 sp40; + s32 temp_v0; + + if (this->animationIdx == ENHORSE_ANIM_WHINNEY) { + temp_v0 = 0; + } else { + temp_v0 = this->animationIdx; + } + + sp40 = sp44[this->unk_538] != temp_v0; + + if (SkelAnime_Update(&this->skin.skelAnime) || sp40) { + this->animationIdx = sp44[this->unk_538]; + if ((this->animationIdx == ENHORSE_ANIM_IDLE) && (Rand_ZeroOne() < 0.5f)) { + this->animationIdx = ENHORSE_ANIM_WHINNEY; + } + + if (sp40) { + if (this->animationIdx == ENHORSE_ANIM_IDLE) { + Animation_MorphToPlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + -3.0f); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 2.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), + ANIMMODE_ONCE, -3.0f); + } + } else if (this->animationIdx == ENHORSE_ANIM_IDLE) { + Animation_PlayOnce(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx]); + } else { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], 2.0f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + } + + if ((this->unk_538 == 0) || (this->unk_538 == 1)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HORSE_RUN); + } else if (this->unk_538 == 2) { + if (this->animationIdx == ENHORSE_ANIM_IDLE) { + EnHorse_IdleAnimSounds(this, globalCtx); + } else if (this->animationIdx == ENHORSE_ANIM_WHINNEY) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HORSE_GROAN); + } + } + } +} + +void func_80884D04(EnHorse* this, GlobalContext* globalCtx) { + f32 playSpeed; + + this->actor.speedXZ = 10.0f; + this->action = ENHORSE_ACT_25; + this->unk_540 = this->actor.world.pos; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_INGO_HORSE_NEIGH); + this->animationIdx = ENHORSE_ANIM_GALLOP; + playSpeed = this->actor.speedXZ * 0.2f; + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * playSpeed * 2.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, 0.0f); +} + +void func_80884E0C(EnHorse* this, GlobalContext* globalCtx) { + f32 playSpeed = (this->unk_56C * 0.2f * 0.5f) + 1.0f; + Vec3f pos; + CollisionPoly* sp3C; + + this->skin.skelAnime.playSpeed = playSpeed; + + if (SkelAnime_Update(&this->skin.skelAnime)) { + Animation_Change(&this->skin.skelAnime, sAnimationHeaders[this->type][this->animationIdx], + sPlaybackSpeeds[this->animationIdx] * playSpeed * 2.5f, 0.0f, + Animation_GetLastFrame(sAnimationHeaders[this->type][this->animationIdx]), ANIMMODE_ONCE, + 0.0f); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_HORSE_RUN); + } + + this->unk_57C = this->actor.world.pos; + this->actor.world.pos.x = this->unk_570.x; + this->actor.world.pos.z = this->unk_570.z; + + this->unk_56C = Math3D_Distance(&this->actor.world.pos, &this->actor.prevPos); + if (((this->unk_550 == 5) || (this->unk_550 == 7)) && (Player_GetMask(globalCtx) != PLAYER_MASK_CIRCUS_LEADER)) { + this->rider->unk488 = 7; + } else { + EnHorse_SetIngoAnimation(this->animationIdx, this->skin.skelAnime.curFrame, this->unk_394 & 1, + &this->rider->unk488); + } + + pos = this->actor.world.pos; + pos.y += 10.0f; + + if (BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp3C, &pos) != BGCHECK_Y_MIN) { + this->actor.velocity.y += this->actor.gravity; + if (this->actor.velocity.y < this->actor.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } + this->actor.world.pos.y += this->actor.velocity.y * 0.5f; + } else { + this->actor.world.pos.y = this->unk_570.y; + } +} + +void EnHorse_Vec3fOffset(Vec3f* src, s16 yaw, f32 dist, f32 height, Vec3f* dst) { + dst->x = (Math_SinS(yaw) * dist) + src->x; + dst->y = src->y + height; + dst->z = (Math_CosS(yaw) * dist) + src->z; +} + +s32 EnHorse_CalcFloorHeight(EnHorse* this, GlobalContext* globalCtx, Vec3f* pos, CollisionPoly** polyFloor, + f32* floorHeight, s32* bgId) { + f32 waterY; + WaterBox* waterbox; + + *polyFloor = NULL; + *floorHeight = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, polyFloor, bgId, pos); + if (*floorHeight == BGCHECK_Y_MIN) { + return 1; // No floor + } + + if ((WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, pos->x, pos->z, &waterY, &waterbox) == 1) && + (*floorHeight < waterY)) { + return 2; // Water + } + + if ((COLPOLY_GET_NORMAL((*polyFloor)->normal.y) < 0.81915206f) || + SurfaceType_IsHorseBlocked(&globalCtx->colCtx, *polyFloor, *bgId) || + (func_800C99D4(&globalCtx->colCtx, *polyFloor, *bgId) == 7)) { + return 3; // Horse blocked surface + } + + return 0; +} + +/** + * obstacleType: + * 1: Water in front + * 2: Water behind? + * 3: ? + * 4: Obstructed in front + * 5: Obstructed behind + */ +void EnHorse_ObstructMovement(EnHorse* this, GlobalContext* globalCtx, s32 obstacleType, s32 galloping) { + if (this->action != ENHORSE_ACT_HBA) { + if ((this->action == ENHORSE_ACT_MOUNTED_IDLE) || (this->action == ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING)) { + this->actor.world.pos = this->actor.prevPos; + this->actor.world.rot.y -= 0x640; + this->actor.speedXZ = 0.0f; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_1EC |= 4; + } else if (this->action == ENHORSE_ACT_25) { + this->unk_1EC |= 0x80; + this->actor.world.pos = this->actor.prevPos; + this->actor.speedXZ = 0.0f; + } else if ((globalCtx->sceneNum != SCENE_KOEPONARACE) || (this->unk_1EC & 2)) { + this->unk_1EC &= ~2; + this->actor.world.pos = this->lastPos; + this->stateFlags |= ENHORSE_OBSTACLE; + if (this->playerControlled == 0) { + if (this->animationIdx != 3) {} + } else if (this->action != ENHORSE_ACT_REVERSE) { + if (this->stateFlags & ENHORSE_JUMPING) { + this->stateFlags &= ~ENHORSE_JUMPING; + this->actor.gravity = -3.5f; + this->actor.world.pos.y = this->actor.floorHeight; + } + + if ((obstacleType == 1) || (obstacleType == 4)) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + } else if ((obstacleType == 2) || (obstacleType == 5)) { + this->stateFlags |= ENHORSE_FORCE_WALKING; + } + + if (galloping == true) { + EnHorse_StartRearing(this); + } + } + } + } +} + +void EnHorse_CheckFloors(EnHorse* this, GlobalContext* globalCtx) { + s32 pad; + CollisionPoly* frontFloor; + CollisionPoly* backFloor; + s32 bgId; + s16 floorSlope; + Vec3f frontPos; + Vec3f backPos; + Vec3f pos; + f32 nx; + f32 ny; + f32 nz; + s32 galloping = this->actor.speedXZ > 8.0f; + s32 status; + f32 waterHeight; + WaterBox* waterbox; + f32 dist; + + if ((WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &waterHeight, &waterbox) == true) && + (this->actor.floorHeight < waterHeight)) { + EnHorse_ObstructMovement(this, globalCtx, 1, galloping); + return; + } + + if (this->type != HORSE_2) { + EnHorse_Vec3fOffset(&this->actor.world.pos, this->actor.shape.rot.y, 30.0f, 55.0f, &frontPos); + } else { + EnHorse_Vec3fOffset(&this->actor.world.pos, this->actor.shape.rot.y, 15.0f, 30.0f, &frontPos); + } + + status = EnHorse_CalcFloorHeight(this, globalCtx, &frontPos, &frontFloor, &this->yFront, &this->unk_24C); + if (status == 1) { + this->actor.shape.rot.x = 0; + EnHorse_ObstructMovement(this, globalCtx, 4, galloping); + return; + } + + if (status == 3) { + this->unk_1EC |= 2; + EnHorse_ObstructMovement(this, globalCtx, 4, galloping); + return; + } + + if (this->type != HORSE_2) { + EnHorse_Vec3fOffset(&this->actor.world.pos, this->actor.shape.rot.y, -30.0f, 55.0f, &backPos); + } else { + EnHorse_Vec3fOffset(&this->actor.world.pos, this->actor.shape.rot.y, -15.0f, 30.0f, &backPos); + } + + status = EnHorse_CalcFloorHeight(this, globalCtx, &backPos, &backFloor, &this->yBack, &bgId); + if (status == 1) { + this->actor.shape.rot.x = 0; + EnHorse_ObstructMovement(this, globalCtx, 5, galloping); + return; + } + + if (status == 3) { + this->unk_1EC |= 2; + EnHorse_ObstructMovement(this, globalCtx, 5, galloping); + return; + } + + floorSlope = Math_Atan2S(this->yBack - this->yFront, 60.0f); + if (this->actor.floorPoly != NULL) { + nx = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x); + ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); + nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); + + pos = frontPos; + pos.y = this->yFront; + + dist = Math3D_DistPlaneToPos(nx, ny, nz, this->actor.floorPoly->dist, &pos); + if ((frontFloor != this->actor.floorPoly) && (this->actor.speedXZ >= 0.0f) && + ((!(this->stateFlags & ENHORSE_JUMPING) && (dist < -40.0f)) || + ((this->stateFlags & ENHORSE_JUMPING) && (dist < -200.0f)))) { + EnHorse_ObstructMovement(this, globalCtx, 4, galloping); + return; + } + + pos = backPos; + pos.y = this->yBack; + + dist = Math3D_DistPlaneToPos(nx, ny, nz, this->actor.floorPoly->dist, &pos); + if ((backFloor != this->actor.floorPoly) && (this->actor.speedXZ <= 0.0f) && + ((!(this->stateFlags & ENHORSE_JUMPING) && (dist < -40.0f)) || + ((this->stateFlags & ENHORSE_JUMPING) && (dist < -200.0f)))) { + EnHorse_ObstructMovement(this, globalCtx, 5, galloping); + return; + } + + if ((ny < 0.81915206f) || + SurfaceType_IsHorseBlocked(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) || + (func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 7)) { + if (this->actor.speedXZ >= 0.0f) { + EnHorse_ObstructMovement(this, globalCtx, 4, galloping); + } else { + EnHorse_ObstructMovement(this, globalCtx, 5, galloping); + } + } else if (this->stateFlags & 4) { + this->actor.shape.rot.x = 0; + } else if ((this->actor.floorHeight + 4.0f) < this->actor.world.pos.y) { + this->actor.shape.rot.x = 0; + } else if (!(fabsf(floorSlope) > 0x1FFF)) { + this->actor.shape.rot.x = floorSlope; + this->actor.shape.yOffset = + ((this->yFront + (((this->yBack - this->yFront) * 20.0f) / 45.0f)) - this->actor.floorHeight) + + this->unk_3E8; + } + } +} + +void EnHorse_MountDismount(EnHorse* this, GlobalContext* globalCtx) { + s32 mountSide = EnHorse_GetMountSide(this, globalCtx); + + if ((mountSide != 0) && !(this->stateFlags & ENHORSE_UNRIDEABLE)) { + Actor_SetRideActor(globalCtx, &this->actor, mountSide); + } + + if ((this->playerControlled == false) && (Actor_HasRider(globalCtx, &this->actor) == true)) { + this->noInputTimer = 26; + this->noInputTimerMax = 26; + this->playerControlled = true; + EnHorse_Freeze(this, globalCtx); + } else if ((this->playerControlled == true) && (Actor_HasNoRider(globalCtx, &this->actor) == true)) { + this->noInputTimer = 35; + this->noInputTimerMax = 35; + this->stateFlags &= ~ENHORSE_UNRIDEABLE; + this->playerControlled = false; + EnHorse_Freeze(this, globalCtx); + } +} + +void EnHorse_StickDirection(Vec2f* curStick, f32* stickMag, s16* angle) { + *stickMag = sqrtf(SQ(curStick->x) + SQ(curStick->z)); + *stickMag = CLAMP_MAX(*stickMag, 60.0f); + *angle = Math_Atan2S(-curStick->x, curStick->z); +} + +void EnHorse_UpdateStick(EnHorse* this, GlobalContext* globalCtx) { + Input* input = &globalCtx->state.input[this->unk_52C]; + + this->lastStick = this->curStick; + this->curStick.x = input->rel.stick_x; + this->curStick.z = input->rel.stick_y; +} + +void EnHorse_ResolveCollision(EnHorse* this, GlobalContext* globalCtx, CollisionPoly* colPoly) { + f32 dist; + f32 nx; + f32 ny; + f32 nz; + f32 offset; + + nx = COLPOLY_GET_NORMAL(colPoly->normal.x); + ny = COLPOLY_GET_NORMAL(colPoly->normal.y); + nz = COLPOLY_GET_NORMAL(colPoly->normal.z); + + if (!(Math_CosS(BINANG_ROT180(this->actor.world.rot.y - Math_Atan2S(colPoly->normal.x, colPoly->normal.z))) < + 0.7071f)) { // cos(45 degrees) + dist = Math3D_DistPlaneToPos(nx, ny, nz, colPoly->dist, &this->actor.world.pos); + offset = (1.0f / sqrtf(SQ(nx) + SQ(nz))); + offset = (30.0f - dist) * offset; + this->actor.world.pos.x += offset * nx; + this->actor.world.pos.z += offset * nz; + } +} + +void EnHorse_BgCheckSlowMoving(EnHorse* this, GlobalContext* globalCtx) { + f32 yOffset = 40.0f; + Vec3f start; + Vec3f end; + Vec3f intersect; + CollisionPoly* colPoly; + s32 bgId; + + Math_Vec3f_Copy(&start, &this->actor.world.pos); + start.y += yOffset; + + Math_Vec3f_Copy(&end, &start); + end.x += 30.0f * Math_SinS(this->actor.world.rot.y); + end.y += 30.0f * Math_SinS(-this->actor.shape.rot.x); + end.z += 30.0f * Math_CosS(this->actor.world.rot.y); + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &start, &end, &intersect, &colPoly, true, false, false, true, + &bgId)) { + EnHorse_ResolveCollision(this, globalCtx, colPoly); + } +} + +void EnHorse_UpdateBgCheckInfo(EnHorse* this, GlobalContext* globalCtx) { + s32 pad2[2]; + Vec3f startPos; + Vec3f endPos; + Vec3f obstaclePos; + f32 temp_f0; + f32 intersectDist; + CollisionPoly* wall = NULL; + CollisionPoly* obstacleFloor = NULL; + s32 bgId; + f32 obstacleHeight; + f32 behindObstacleHeight; + DynaPolyActor* horseJump; + s32 movingFast; + s16 sp7E = 0; + DynaPolyActor* horseGameCheck = NULL; + s32 pad6; + s32 pad; + Vec3f intersect; + Vec3f obstacleTop; + s32 pad5; + s32 pad4; + + if ((this->actor.params != ENHORSE_4) && (this->actor.params != ENHORSE_5) && (this->actor.params != ENHORSE_19) && + (this->actor.params != ENHORSE_20) && (this->actor.params != ENHORSE_18)) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 35.0f, 100.0f, 0x1D); + } else { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 35.0f, 100.0f, 0x1C); + } + + if ((this->actor.bgCheckFlags & 8) && (Math_CosS(this->actor.wallYaw - this->actor.world.rot.y) < -0.3f)) { + if (this->actor.speedXZ > 4.0f) { + this->actor.speedXZ -= 1.0f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } + } + } + + horseJump = DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId); + + if (!(this->stateFlags & ENHORSE_JUMPING)) { + if ((horseJump != NULL) && (horseJump->actor.id == ACTOR_EN_HORSE_GAME_CHECK) && + ((horseJump->actor.params & 0xFF) == 5)) { + this->stateFlags |= ENHORSE_FLAG_28; + this->unk_3E8 += ((-10.0f / this->actor.scale.y) - this->unk_3E8) * 0.5f; + if (this->actor.speedXZ > 2.0f) { + this->actor.speedXZ -= 1.0f; + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } else { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_EV_KID_HORSE_SANDDUST); + } + } + } else { + this->stateFlags &= ~ENHORSE_FLAG_28; + this->unk_3E8 *= 0.5f; + } + } + + if ((this->stateFlags & ENHORSE_JUMPING) || (this->stateFlags & ENHORSE_FLAG_28) || (this->actor.speedXZ < 0.0f) || + (this->action == ENHORSE_ACT_LOW_JUMP) || (this->action == ENHORSE_ACT_REVERSE)) { + return; + } + + if (this->actor.speedXZ > 8.0f) { + if (this->actor.speedXZ < 12.8f) { + intersectDist = 160.0f; + movingFast = false; + } else { + intersectDist = 230.0f; + movingFast = true; + } + } else { + EnHorse_BgCheckSlowMoving(this, globalCtx); + return; + } + + startPos = this->actor.world.pos; + startPos.y += 19.0f; + + endPos = startPos; + endPos.x += intersectDist * Math_SinS(this->actor.world.rot.y); + endPos.y += intersectDist * Math_SinS(-this->actor.shape.rot.x); + endPos.z += intersectDist * Math_CosS(this->actor.world.rot.y); + + intersect = endPos; + wall = NULL; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &startPos, &endPos, &intersect, &wall, true, false, false, true, + &bgId) == true) { + intersectDist = sqrtf(Math3D_Vec3fDistSq(&startPos, &intersect)); + this->stateFlags |= ENHORSE_OBSTACLE; + } + + if (wall != NULL) { + if (intersectDist < 30.0f) { + EnHorse_ResolveCollision(this, globalCtx, wall); + } + + sp7E = BINANG_ROT180(this->actor.world.rot.y - Math_Atan2S(wall->normal.x, wall->normal.z)); + + if ((Math_CosS(sp7E) < 0.5f) || SurfaceType_IsHorseBlocked(&globalCtx->colCtx, wall, bgId)) { + return; + } + + if (((movingFast == false) && (intersectDist < 80.0f)) || ((movingFast == true) && (intersectDist < 150.0f))) { + if ((globalCtx->sceneNum != SCENE_KOEPONARACE) && (Math_CosS(sp7E) < 0.9f) && + (this->playerControlled == true)) { + if (movingFast == false) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + } else if (movingFast == true) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + } + return; + } + + horseJump = DynaPoly_GetActor(&globalCtx->colCtx, bgId); + if ((this->stateFlags & ENHORSE_FLAG_26) && + (((horseJump != NULL) && (horseJump->actor.id != ACTOR_BG_UMAJUMP)) || (horseJump == NULL))) { + if (this->playerControlled == true) { + if (movingFast == false) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + } else if (movingFast == true) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + } + return; + } + } + + intersectDist += 5.0f; + obstaclePos = startPos; + + obstaclePos.x += intersectDist * Math_SinS(this->actor.world.rot.y); + obstaclePos.y = this->actor.world.pos.y + 120.0f; + obstaclePos.z += intersectDist * Math_CosS(this->actor.world.rot.y); + + obstacleTop = obstaclePos; + obstacleTop.y = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &obstacleFloor, &bgId, &obstaclePos); + + if (obstacleTop.y == BGCHECK_Y_MIN) { + return; + } + + obstacleHeight = obstacleTop.y - this->actor.world.pos.y; + + if ((this->actor.floorPoly == NULL) || (obstacleFloor == NULL)) { + return; + } + + if ((Math3D_DistPlaneToPos(COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x), + COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y), + COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z), this->actor.floorPoly->dist, + &obstacleTop) < -40.0f) && + (Math3D_DistPlaneToPos(COLPOLY_GET_NORMAL(obstacleFloor->normal.x), COLPOLY_GET_NORMAL(obstacleFloor->normal.y), + COLPOLY_GET_NORMAL(obstacleFloor->normal.z), obstacleFloor->dist, + &this->actor.world.pos) > 40.0f)) { + if ((movingFast == true) && (this->playerControlled == true) && (this->action != ENHORSE_ACT_LOW_JUMP) && + (globalCtx->sceneNum != SCENE_KOEPONARACE)) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + this->stateFlags |= ENHORSE_OBSTACLE; + return; + } + + temp_f0 = COLPOLY_GET_NORMAL(obstacleFloor->normal.y); + if ((temp_f0 < 0.81915206f) || SurfaceType_IsHorseBlocked(&globalCtx->colCtx, obstacleFloor, bgId) || + (func_800C99D4(&globalCtx->colCtx, obstacleFloor, bgId) == 7)) { + if ((Math_CosS(sp7E) < 0.9f) && (movingFast == true) && (this->playerControlled == true) && + (this->action != ENHORSE_ACT_LOW_JUMP) && (globalCtx->sceneNum != SCENE_KOEPONARACE)) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + return; + } + + if (wall == NULL) { + horseGameCheck = DynaPoly_GetActor(&globalCtx->colCtx, bgId); + if ((horseGameCheck == NULL) || (horseGameCheck->actor.id != ACTOR_EN_HORSE_GAME_CHECK) || + ((horseGameCheck->actor.params & 0xFF) != 5)) { + return; + } + } + + if (((obstacleTop.y < intersect.y) && + ((horseGameCheck == NULL) || (horseGameCheck->actor.id != ACTOR_EN_HORSE_GAME_CHECK) || + ((horseGameCheck->actor.params & 0xFF) != 5))) || + ((this->stateFlags & ENHORSE_CANT_JUMP) && (this->action != ENHORSE_ACT_MOUNTED_IDLE))) { + return; + } + + if ((this->action == ENHORSE_ACT_MOUNTED_IDLE) && !(this->stateFlags & ENHORSE_FLAG_30)) { + horseGameCheck = DynaPoly_GetActor(&globalCtx->colCtx, bgId); + if ((horseGameCheck != NULL) && (horseGameCheck->actor.id == ACTOR_EN_HORSE_GAME_CHECK) && + ((horseGameCheck->actor.params & 0xFF) == 5)) { + this->stateFlags |= ENHORSE_FLAG_30; + this->postDrawFunc = func_8088126C; + } + } + + if (this->playerControlled == false) { + return; + } + + obstaclePos = startPos; + obstaclePos.y = this->actor.world.pos.y + 120.0f; + + if (movingFast == false) { + obstaclePos.x += 276.0f * Math_SinS(this->actor.world.rot.y); + obstaclePos.z += 276.0f * Math_CosS(this->actor.world.rot.y); + } else { + obstaclePos.x += 390.0f * Math_SinS(this->actor.world.rot.y); + obstaclePos.z += 390.0f * Math_CosS(this->actor.world.rot.y); + } + + obstacleTop = obstaclePos; + obstacleTop.y = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &obstacleFloor, &bgId, &obstaclePos); + + if (obstacleTop.y == BGCHECK_Y_MIN) { + return; + } + + behindObstacleHeight = obstacleTop.y - this->actor.world.pos.y; + + if (obstacleFloor == NULL) { + return; + } + + temp_f0 = COLPOLY_GET_NORMAL(obstacleFloor->normal.y); + if ((temp_f0 < 0.81915206f) || SurfaceType_IsHorseBlocked(&globalCtx->colCtx, obstacleFloor, bgId) || + (func_800C99D4(&globalCtx->colCtx, obstacleFloor, bgId) == 7)) { + if ((movingFast == true) && (this->playerControlled == true) && (this->action != ENHORSE_ACT_LOW_JUMP) && + (globalCtx->sceneNum != SCENE_KOEPONARACE)) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + } else if (behindObstacleHeight < -70.0f) { + if ((movingFast == true) && (this->playerControlled == true) && (this->action != ENHORSE_ACT_LOW_JUMP) && + (globalCtx->sceneNum != SCENE_KOEPONARACE)) { + this->stateFlags |= ENHORSE_FORCE_REVERSING; + EnHorse_StartBraking(this, globalCtx); + } + } else { + temp_f0 = (this->actor.scale.y * 100.0f); + + if ((horseGameCheck == NULL) || (horseGameCheck->actor.id != ACTOR_EN_HORSE_GAME_CHECK) || + ((horseGameCheck->actor.params & 0xFF) != 5)) { + if ((movingFast == false) && ((19.0f * temp_f0) < obstacleHeight) && + (obstacleHeight <= (40.0f * temp_f0))) { + EnHorse_Stub1(this); + this->postDrawFunc = EnHorse_LowJumpInit; + } else if ((movingFast == true) && + (((this->actor.speedXZ < 13.8f) && ((19.0f * temp_f0) < obstacleHeight) && + (obstacleHeight <= (72.0f * temp_f0))) || + ((this->actor.speedXZ > 13.8f) && (obstacleHeight <= (112.0f * temp_f0))))) { + EnHorse_Stub2(this); + this->postDrawFunc = EnHorse_HighJumpInit; + } + } else if (movingFast == false) { + EnHorse_Stub1(this); + this->postDrawFunc = EnHorse_LowJumpInit; + } else if (movingFast == true) { + EnHorse_Stub2(this); + this->postDrawFunc = EnHorse_HighJumpInit; + } + } +} + +void func_80886C00(EnHorse* this, GlobalContext* globalCtx) { + Input* input = &globalCtx->state.input[this->unk_52C]; + + if (((this->action == ENHORSE_ACT_MOUNTED_GALLOP) || (this->action == ENHORSE_ACT_MOUNTED_REARING) || + (this->action == ENHORSE_ACT_STOPPING)) && + (CHECK_BTN_ALL(input->press.button, BTN_A) || (func_801A5100() == 5)) && + (globalCtx->interfaceCtx.unk_212 == 8) && !(this->stateFlags & ENHORSE_BOOST) && + !(this->stateFlags & ENHORSE_FLAG_8) && !(this->stateFlags & ENHORSE_FLAG_9)) { + if (this->numBoosts > 0) { + func_8013ECE0(0.0f, 180, 20, 100); + this->stateFlags |= ENHORSE_BOOST; + this->stateFlags |= ENHORSE_FIRST_BOOST_REGEN; + this->stateFlags |= ENHORSE_FLAG_8; + this->numBoosts--; + this->boostTimer = 0; + if (this->numBoosts == 0) { + this->boostRegenTime = 140; + } else if (this->type == HORSE_EPONA) { + if (this->stateFlags & ENHORSE_FIRST_BOOST_REGEN) { + this->boostRegenTime = 60; + this->stateFlags &= ~ENHORSE_FIRST_BOOST_REGEN; + } else { + this->boostRegenTime = 8; + } + } else { + this->boostRegenTime = 70; + } + } else if ((this->stateFlags & ENHORSE_DRAW) && (Rand_ZeroOne() < 0.1f)) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + } +} + +void EnHorse_RegenBoost(EnHorse* this, GlobalContext* globalCtx) { + s32 playSfx; + + if ((this->numBoosts < 6) && (this->numBoosts > 0)) { + this->boostRegenTime--; + this->boostTimer++; + if (this->boostRegenTime <= 0) { + this->numBoosts++; + if (((this->action == ENHORSE_ACT_MOUNTED_TURN) || (this->action == ENHORSE_ACT_FROZEN) || + (this->action == ENHORSE_ACT_MOUNTED_WALK)) && + !(this->stateFlags & ENHORSE_FLAG_19) && !(this->stateFlags & ENHORSE_FLAG_25)) { + playSfx = true; + } else { + playSfx = false; + } + + if (!playSfx) { + play_sound(NA_SE_SY_CARROT_RECOVER); + } + + if (this->numBoosts < 6) { + this->boostRegenTime = 11; + } + } + } else if (this->numBoosts == 0) { + this->boostRegenTime--; + this->boostTimer++; + if (this->boostRegenTime <= 0) { + this->boostRegenTime = 0; + this->numBoosts = 6; + if (((this->action == ENHORSE_ACT_MOUNTED_TURN) || (this->action == ENHORSE_ACT_FROZEN) || + (this->action == ENHORSE_ACT_MOUNTED_WALK)) && + !(this->stateFlags & ENHORSE_FLAG_19) && !(this->stateFlags & ENHORSE_FLAG_25)) { + playSfx = true; + } else { + playSfx = false; + } + + if (!playSfx) { + play_sound(NA_SE_SY_CARROT_RECOVER); + } + } + } + + if (this->boostTimer == 8) { + if ((Rand_ZeroOne() < 0.25f) && (this->stateFlags & ENHORSE_DRAW)) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + } + + globalCtx->interfaceCtx.numHorseBoosts = this->numBoosts; +} + +void EnHorse_UpdatePlayerDir(EnHorse* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 angle = Actor_YawBetweenActors(&this->actor, &player->actor) - this->actor.world.rot.y; + f32 s = Math_SinS(angle); + f32 c = Math_CosS(angle); + + if (s > 0.8660254f) { // sin(60 degrees) + this->playerDir = PLAYER_DIR_SIDE_L; + } else if (s < -0.8660254f) { // -sin(60 degrees) + this->playerDir = PLAYER_DIR_SIDE_R; + } else if (c > 0.0f) { + if (s > 0.0f) { + this->playerDir = PLAYER_DIR_FRONT_L; + } else { + this->playerDir = PLAYER_DIR_FRONT_R; + } + } else if (s > 0.0f) { + this->playerDir = PLAYER_DIR_BACK_L; + } else { + this->playerDir = PLAYER_DIR_BACK_R; + } +} + +void EnHorse_TiltBody(EnHorse* this, GlobalContext* globalCtx) { + f32 speed; + f32 rollDiff; + s32 targetRoll; + s16 turnVel; + + speed = this->actor.speedXZ / this->boostSpeed; + turnVel = this->actor.shape.rot.y - this->lastYaw; + targetRoll = -((s16)((2730.0f * speed) * (turnVel / 960.00006f))); + rollDiff = targetRoll - this->actor.world.rot.z; + + if (fabsf(targetRoll) < 100.0f) { + this->actor.world.rot.z = 0; + } else if (fabsf(rollDiff) < 100.0f) { + this->actor.world.rot.z = targetRoll; + } else if (rollDiff > 0.0f) { + this->actor.world.rot.z += 0x64; + } else { + this->actor.world.rot.z -= 0x64; + } + + this->actor.shape.rot.z = this->actor.world.rot.z; +} + +s32 EnHorse_UpdateConveyors(EnHorse* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 conveyorDir; + + if ((this->actor.floorPoly == NULL) || (&this->actor != player->rideActor) || + !SurfaceType_GetConveyorSpeed(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId)) { + return false; + } + + conveyorDir = SurfaceType_GetConveyorDirection(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + conveyorDir = (conveyorDir * 0x400) - this->actor.world.rot.y; + if (conveyorDir > 0x640) { + this->actor.world.rot.y += 0x640; + } else if (conveyorDir < -0x640) { + this->actor.world.rot.y -= 0x640; + } else { + this->actor.world.rot.y += conveyorDir; + } + this->actor.shape.rot.y = this->actor.world.rot.y; + return true; +} + +s32 EnHorse_RandInt(f32 arg0) { + return Rand_ZeroOne() * arg0; +} + +static EnHorseActionFunc sActionFuncs[] = { + EnHorse_Frozen, + EnHorse_Inactive, + EnHorse_Idle, + EnHorse_FollowPlayer, + EnHorse_UpdateIngoRace, + func_808819D8, + func_80881398, + EnHorse_MountedIdle, + EnHorse_MountedIdleWhinneying, + EnHorse_MountedTurn, + EnHorse_MountedWalk, + EnHorse_MountedTrot, + EnHorse_MountedGallop, + EnHorse_MountedRearing, + EnHorse_Stopping, + EnHorse_Reverse, + EnHorse_LowJump, + EnHorse_HighJump, + EnHorse_CutsceneUpdate, + EnHorse_UpdateHorsebackArchery, + EnHorse_FleePlayer, + func_80884718, + func_8087CA04, + func_808848C8, + func_80884A40, + func_80884E0C, +}; +void EnHorse_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnHorse* this = THIS; + Vec3f dustAcc = { 0.0f, 0.0f, 0.0f }; + Vec3f dustVel = { 0.0f, 1.0f, 0.0f }; + Player* player = GET_PLAYER(globalCtx); + + if (this->type == HORSE_2) { + Actor_SetScale(&this->actor, 0.00648f); + } else if (this->type == HORSE_4) { + Actor_SetScale(&this->actor, 0.008f); + } else { + Actor_SetScale(&this->actor, 0.01f); + } + + this->lastYaw = thisx->shape.rot.y; + EnHorse_UpdateStick(this, globalCtx); + EnHorse_UpdatePlayerDir(this, globalCtx); + + if (!(this->stateFlags & ENHORSE_INACTIVE)) { + EnHorse_MountDismount(this, globalCtx); + } + + if (this->stateFlags & ENHORSE_FLAG_19) { + if ((this->stateFlags & ENHORSE_FLAG_20) && (this->inRace == true)) { + this->stateFlags &= ~ENHORSE_FLAG_20; + EnHorse_StartRearing(this); + } else if (!(this->stateFlags & ENHORSE_FLAG_20) && (this->stateFlags & ENHORSE_FLAG_21) && + (this->action != ENHORSE_ACT_REVERSE) && (this->inRace == true)) { + this->stateFlags &= ~ENHORSE_FLAG_21; + EnHorse_StartRearing(this); + } + } + + sActionFuncs[this->action](this, globalCtx); + + this->stateFlags &= ~ENHORSE_OBSTACLE; + this->unk_3EC = thisx->world.rot.y; + if ((this->animationIdx == ENHORSE_ANIM_STOPPING) || (this->animationIdx == ENHORSE_ANIM_REARING)) { + this->skin.skelAnime.jointTable[0].y += 0x154; + } + + this->curFrame = this->skin.skelAnime.curFrame; + this->lastPos = thisx->world.pos; + + if (!(this->stateFlags & ENHORSE_INACTIVE)) { + if ((this->action == ENHORSE_ACT_STOPPING) || (this->action == ENHORSE_ACT_MOUNTED_REARING) || + (this->action == ENHORSE_ACT_MOUNTED_GALLOP)) { + func_80886C00(this, globalCtx); + } + + if (this->playerControlled == true) { + EnHorse_RegenBoost(this, globalCtx); + } + + if (ActorCutscene_GetCurrentIndex() != -1) { + thisx->speedXZ = 0.0f; + } + + if (this->action != ENHORSE_ACT_25) { + Actor_MoveWithGravity(&this->actor); + } + + if (this->rider != NULL) { + if ((this->action == ENHORSE_ACT_INGO_RACE) || (this->action == ENHORSE_ACT_MOUNTED_IDLE) || + (this->action == ENHORSE_ACT_25)) { + this->rider->actor.world.pos.x = thisx->world.pos.x; + this->rider->actor.world.pos.y = thisx->world.pos.y + 10.0f; + this->rider->actor.world.pos.z = thisx->world.pos.z; + this->rider->actor.shape.rot.x = thisx->shape.rot.x; + this->rider->actor.shape.rot.y = thisx->shape.rot.y; + } else if (this->action == ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING) { + EnIn* in = this->rider; + s16 jnt = in->jointTable[0].y; + + in->actor.world.pos.x = this->riderPos.x; + in->actor.world.pos.y = this->riderPos.y - (jnt * 0.01f * this->unk_528 * 0.01f); + in->actor.world.pos.z = this->riderPos.z; + in->actor.shape.rot.x = thisx->shape.rot.x; + in->actor.shape.rot.y = thisx->shape.rot.y; + } + } + + if (this->colliderJntSph.elements->info.ocElemFlags & OCELEM_HIT) { + if (thisx->speedXZ > 10.0f) { + thisx->speedXZ -= 1.0f; + } + } + + if ((this->colliderJntSph.base.acFlags & AC_HIT) && (this->stateFlags & ENHORSE_DRAW)) { + if (this->type == HORSE_2) { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_KID_HORSE_NEIGH); + } else { + Audio_PlaySfxAtPos(&this->unk_218, NA_SE_EV_HORSE_NEIGH); + } + } + + if ((this->action != ENHORSE_ACT_INGO_RACE) && (this->action != ENHORSE_ACT_MOUNTED_IDLE) && + (this->action != ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING)) { + EnHorse_TiltBody(this, globalCtx); + } + + if ((this->playerControlled == false) && (this->unk_1EC & 8)) { + if ((this->colliderJntSph.elements->info.ocElemFlags & OCELEM_HIT) && + (this->colliderJntSph.base.oc->id == ACTOR_EN_IN)) { + func_80884868(this); + } + + if ((this->colliderCylinder1.base.ocFlags1 & OC1_HIT) && + (this->colliderCylinder1.base.oc->id == ACTOR_EN_IN)) { + func_80884868(this); + } + + if ((this->colliderCylinder2.base.ocFlags1 & OC1_HIT) && + (this->colliderCylinder2.base.oc->id == ACTOR_EN_IN)) { + func_80884868(this); + } + } + + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder1); + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder2); + + if (this->type == HORSE_2) { + this->colliderCylinder1.dim.pos.x = + (s16)(Math_SinS(thisx->shape.rot.y) * 11.0f) + this->colliderCylinder1.dim.pos.x; + this->colliderCylinder1.dim.pos.z = + (s16)(Math_CosS(thisx->shape.rot.y) * 11.0f) + this->colliderCylinder1.dim.pos.z; + this->colliderCylinder2.dim.pos.x = + (s16)(Math_SinS(thisx->shape.rot.y) * -18.0f) + this->colliderCylinder2.dim.pos.x; + this->colliderCylinder2.dim.pos.z = + (s16)(Math_CosS(thisx->shape.rot.y) * -18.0f) + this->colliderCylinder2.dim.pos.z; + } else { + this->colliderCylinder1.dim.pos.x = + (s16)(Math_SinS(thisx->shape.rot.y) * 6.6000004f) + this->colliderCylinder1.dim.pos.x; + this->colliderCylinder1.dim.pos.z = + (s16)(Math_CosS(thisx->shape.rot.y) * 6.6000004f) + this->colliderCylinder1.dim.pos.z; + this->colliderCylinder2.dim.pos.x = + (s16)(Math_SinS(thisx->shape.rot.y) * -10.8f) + this->colliderCylinder2.dim.pos.x; + this->colliderCylinder2.dim.pos.z = + (s16)(Math_CosS(thisx->shape.rot.y) * -10.8f) + this->colliderCylinder2.dim.pos.z; + } + + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder1.base); + if (!(this->stateFlags & ENHORSE_JUMPING) && !(this->unk_1EC & 0x20)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder1.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder2.base); + } else { + this->unk_1EC &= ~0x20; + } + + if (this->unk_1EC & 0x100) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder2.base); + } + + if ((player->stateFlags1 & ENHORSE_BOOST) && (player->rideActor != NULL)) { + EnHorse_UpdateConveyors(this, globalCtx); + } + + EnHorse_UpdateBgCheckInfo(this, globalCtx); + EnHorse_CheckFloors(this, globalCtx); + if (thisx->world.pos.y < this->yFront) { + if (thisx->world.pos.y < this->yBack) { + if (this->yBack < this->yFront) { + thisx->world.pos.y = this->yBack; + } else { + thisx->world.pos.y = this->yFront; + } + } + } + + thisx->focus.pos = thisx->world.pos; + thisx->focus.pos.y += 70.0f; + + if ((Rand_ZeroOne() < 0.025f) && (this->blinkTimer == 0)) { + this->blinkTimer++; + } else if (this->blinkTimer > 0) { + this->blinkTimer++; + if (this->blinkTimer > 3) { + this->blinkTimer = 0; + } + } + + if ((thisx->speedXZ == 0.0f) && !(this->stateFlags & ENHORSE_FLAG_19)) { + thisx->colChkInfo.mass = MASS_IMMOVABLE; + } else { + thisx->colChkInfo.mass = MASS_HEAVY; + } + + if (thisx->speedXZ >= 5.0f) { + this->colliderCylinder1.base.atFlags |= AT_ON; + } else { + this->colliderCylinder1.base.atFlags &= ~AT_ON; + } + + if (this->dustFlags & 1) { + this->dustFlags &= ~1; + func_800B12F0(globalCtx, &this->frontRightHoof, &dustVel, &dustAcc, EnHorse_RandInt(100.0f) + 200, + EnHorse_RandInt(10.0f) + 30, EnHorse_RandInt(20.0f) + 30); + } else if (this->dustFlags & 2) { + this->dustFlags &= ~2; + func_800B12F0(globalCtx, &this->frontLeftHoof, &dustVel, &dustAcc, EnHorse_RandInt(100.0f) + 200, + EnHorse_RandInt(10.0f) + 30, EnHorse_RandInt(20.0f) + 30); + } else if (this->dustFlags & 4) { + this->dustFlags &= ~4; + func_800B12F0(globalCtx, &this->backRightHoof, &dustVel, &dustAcc, EnHorse_RandInt(100.0f) + 200, + EnHorse_RandInt(10.0f) + 30, EnHorse_RandInt(20.0f) + 30); + } else if (this->dustFlags & 8) { + this->dustFlags &= ~8; + func_800B12F0(globalCtx, &this->backLeftHoof, &dustVel, &dustAcc, EnHorse_RandInt(100.0f) + 200, + EnHorse_RandInt(10.0f) + 30, EnHorse_RandInt(20.0f) + 30); + } + this->stateFlags &= ~ENHORSE_DRAW; + } +} + +s32 EnHorse_PlayerDirToMountSide(EnHorse* this, GlobalContext* globalCtx, Player* player) { + if (this->playerDir == PLAYER_DIR_SIDE_L) { + return -1; + } + + if (this->playerDir == PLAYER_DIR_SIDE_R) { + return 1; + } + + return 0; +} + +s32 EnHorse_MountSideCheck(EnHorse* this, GlobalContext* globalCtx, Player* player) { + s32 mountSide; + + if (Actor_XZDistanceBetweenActors(&this->actor, &player->actor) > 75.0f) { + return 0; + } + + if (fabsf(this->actor.world.pos.y - player->actor.world.pos.y) > 30.0f) { + return 0; + } + + if (Math_CosS(Actor_YawBetweenActors(&player->actor, &this->actor) - player->actor.world.rot.y) < + 0.17364818f) { // cos(80 degrees) + return 0; + } + + mountSide = EnHorse_PlayerDirToMountSide(this, globalCtx, player); + if (mountSide == -1) { + return -1; + } + + if (mountSide == 1) { + return 1; + } + + return 0; +} + +s32 EnHorse_GetMountSide(EnHorse* this, GlobalContext* globalCtx) { + if (this->action != ENHORSE_ACT_IDLE) { + return 0; + } + + if ((this->animationIdx != ENHORSE_ANIM_IDLE) && (this->animationIdx != ENHORSE_ANIM_WHINNEY)) { + return 0; + } + + return EnHorse_MountSideCheck(this, globalCtx, GET_PLAYER(globalCtx)); +} + +void EnHorse_RandomOffset(Vec3f* src, f32 dist, Vec3f* dst) { + dst->x = ((Rand_ZeroOne() * (2.0f * dist)) + src->x) - dist; + dst->y = ((Rand_ZeroOne() * (2.0f * dist)) + src->y) - dist; + dst->z = ((Rand_ZeroOne() * (2.0f * dist)) + src->z) - dist; +} + +void EnHorse_PostDraw(Actor* thisx, GlobalContext* globalCtx, Skin* skin) { + s32 pad; + EnHorse* this = THIS; + Vec3f sp7C = { 0.0f, 0.0f, 0.0f }; + Vec3f hoofOffset = { 5.0f, -4.0f, 5.0f }; + Vec3f sp64; + f32 curFrame = this->skin.skelAnime.curFrame; + Vec3f center; + Vec3f newCenter; + s32 i; + Vec3f sp38; + f32 sp34; + + if (!(this->stateFlags & ENHORSE_CALC_RIDER_POS)) { + if (this->type == HORSE_2) { + Skin_GetVertexPos(skin, 5, 120, &this->riderPos); + this->riderPos.y += 13.0f; + } else { + Vec3f riderOffset = { 600.0f, -1670.0f, 0.0f }; + + Skin_GetLimbPos(skin, 30, &riderOffset, &this->riderPos); + } + this->riderPos.x -= this->actor.world.pos.x; + this->riderPos.y -= this->actor.world.pos.y; + this->riderPos.z -= this->actor.world.pos.z; + } else { + this->stateFlags &= ~ENHORSE_CALC_RIDER_POS; + } + + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 13, &sp7C, &sp38); + } else { + Skin_GetLimbPos(skin, 13, &sp7C, &sp38); + } + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sp38, &this->unk_218, &sp34); + + if ((this->animationIdx == ENHORSE_ANIM_IDLE) && (this->action != ENHORSE_ACT_FROZEN) && + (((curFrame > 40.0f) && (curFrame < 45.0f) && (this->type == 0)) || + ((curFrame > 28.0f) && (curFrame < 33.0f) && (this->type == 1)))) { + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 1; + Skin_GetLimbPos(skin, 28, &hoofOffset, &this->frontRightHoof); + this->frontRightHoof.y -= 5.0f; + } + } else { + if (this->action == ENHORSE_ACT_LOW_JUMP) { + if (((curFrame > 10.0f) && (curFrame < 13.0f)) || ((curFrame > 25.0f) && (curFrame < 33.0f))) { + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 2; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 20, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 20, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->frontLeftHoof); + } + + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 1; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 28, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 28, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->frontRightHoof); + } + } + + if (((curFrame > 6.0f) && (curFrame < 10.0f)) || ((curFrame > 23.0f) && (curFrame < 29.0f))) { + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 8; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 36, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 37, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backLeftHoof); + } + } + + if ((((curFrame > 7.0f) && (curFrame < 14.0f)) || ((curFrame > 26.0f) && (curFrame < 30.0f))) && + (Rand_ZeroOne() < 0.02f)) { + this->dustFlags |= 4; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 44, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 45, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backRightHoof); + } + } else if (this->animationIdx == ENHORSE_ANIM_GALLOP) { + if ((curFrame > 14.0f) && (curFrame < 16.0f) && (Rand_ZeroOne() < 0.02f)) { + this->dustFlags |= 1; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 28, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 28, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 5.0f, &this->frontRightHoof); + } else if ((curFrame > 8.0f) && (curFrame < 10.0f) && (Rand_ZeroOne() < 0.02f)) { + this->dustFlags |= 2; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 20, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 20, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->frontLeftHoof); + } else if ((curFrame > 1.0f) && (curFrame < 3.0f) && (Rand_ZeroOne() < 0.02f)) { + this->dustFlags |= 4; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 44, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 45, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backRightHoof); + } else if ((curFrame > 26.0f) && (curFrame < 28.0f) && (Rand_ZeroOne() < 0.02f)) { + this->dustFlags |= 8; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 36, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 37, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backLeftHoof); + } + } else if ((this->action == ENHORSE_ACT_BRIDGE_JUMP) && (curFrame > 6.0f) && + (Rand_ZeroOne() < (1.0f - ((curFrame - 6.0f) * (1.0f / 17.0f))))) { + if (Rand_ZeroOne() < 0.05f) { + this->dustFlags |= 8; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 36, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 37, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backLeftHoof); + } + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 4; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 44, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 45, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backRightHoof); + } + } else if ((this->action == ENHORSE_ACT_CS_UPDATE) && (curFrame > 5.0f)) { + if (Rand_ZeroOne() < (1.0f - ((curFrame - 5.0f) * 0.04f))) { + if (Rand_ZeroOne() < 0.05f) { + this->dustFlags |= 8; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 36, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 37, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backLeftHoof); + } + + if (Rand_ZeroOne() < 0.02f) { + this->dustFlags |= 4; + if (this->type == HORSE_2) { + Skin_GetLimbPos(skin, 44, &hoofOffset, &sp64); + } else { + Skin_GetLimbPos(skin, 45, &hoofOffset, &sp64); + } + EnHorse_RandomOffset(&sp64, 10.0f, &this->backRightHoof); + } + } + } + } + + for (i = 0; i < this->colliderJntSph.count; i++) { + center.x = this->colliderJntSph.elements[i].dim.modelSphere.center.x; + center.y = this->colliderJntSph.elements[i].dim.modelSphere.center.y; + center.z = this->colliderJntSph.elements[i].dim.modelSphere.center.z; + + Skin_GetLimbPos(skin, this->colliderJntSph.elements[i].dim.limb, ¢er, &newCenter); + + this->colliderJntSph.elements[i].dim.worldSphere.center.x = newCenter.x; + this->colliderJntSph.elements[i].dim.worldSphere.center.y = newCenter.y; + this->colliderJntSph.elements[i].dim.worldSphere.center.z = newCenter.z; + + this->colliderJntSph.elements[i].dim.worldSphere.radius = + this->colliderJntSph.elements[i].dim.modelSphere.radius * this->colliderJntSph.elements[i].dim.scale; + } + + //! @bug Setting colliders in a draw function allows for duplicate entries to be added to their respective lists + //! under certain conditions, like when pausing and unpausing the game. + //! Actors will draw for a couple of frames between the pauses, but some important logic updates will not occur. + //! In the case of OC, this can cause unwanted effects such as a very large amount of displacement being applied to + //! a colliding actor. + if (!(this->stateFlags & ENHORSE_JUMPING)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + } +} + +s32 EnHorse_OverrideLimbDraw(Actor* thisx, GlobalContext* globalCtx, s32 limbIndex, Skin* skin) { + static TexturePtr D_80889204[] = { + object_horse_link_child_Tex_001D28, + object_horse_link_child_Tex_001928, + object_horse_link_child_Tex_001B28, + }; + static u8 D_80889210[] = { 0, 1, 2, 1 }; + EnHorse* this = THIS; + s32 drawOriginalLimb = true; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((limbIndex != 13) || (this->type != HORSE_EPONA)) { + if ((limbIndex == 13) && (this->type == HORSE_2)) { + u8 idx = D_80889210[this->blinkTimer]; + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80889204[idx])); + } else if ((this->type == HORSE_HNI) && (this->stateFlags & ENHORSE_FLAG_18) && (limbIndex == 30)) { + drawOriginalLimb = false; + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + return drawOriginalLimb; +} + +s32 func_80888D18(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + Vec3f sp1C = { -98.0f, -1454.0f, 0.0f }; + EnHorse* this = THIS; + + if (limbIndex == 3) { + Matrix_MultVec3f(&sp1C, &this->riderPos); + } + return false; +} + +void EnHorse_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHorse* this = THIS; + + if (!(this->stateFlags & ENHORSE_INACTIVE) && (this->actor.update != func_8087D540)) { + func_8012C28C(globalCtx->state.gfxCtx); + this->stateFlags |= ENHORSE_DRAW; + if (!(this->unk_1EC & 1)) { + if (this->stateFlags & ENHORSE_JUMPING) { + func_80138258(&this->actor, globalCtx, &this->skin, EnHorse_PostDraw, EnHorse_OverrideLimbDraw, false); + } else { + func_80138258(&this->actor, globalCtx, &this->skin, EnHorse_PostDraw, EnHorse_OverrideLimbDraw, true); + } + } else { + if (this->stateFlags & ENHORSE_JUMPING) { + this->skin.skelAnime.jointTable->x = 0; + this->skin.skelAnime.jointTable->y = 0; + this->skin.skelAnime.jointTable->z = 0; + } + SkelAnime_DrawFlexOpa(globalCtx, this->skin.skelAnime.skeleton, this->skin.skelAnime.jointTable, + this->skin.skelAnime.dListCount, func_80888D18, NULL, &this->actor); + } + + if (this->postDrawFunc != NULL) { + this->postDrawFunc(this, globalCtx); + } + } +} diff --git a/src/overlays/actors/ovl_En_Horse/z_en_horse.h b/src/overlays/actors/ovl_En_Horse/z_en_horse.h index 7efae12fc..2dc5e44f5 100644 --- a/src/overlays/actors/ovl_En_Horse/z_en_horse.h +++ b/src/overlays/actors/ovl_En_Horse/z_en_horse.h @@ -2,14 +2,218 @@ #define Z_EN_HORSE_H #include "global.h" +#include "z64skin.h" +#include "overlays/actors/ovl_En_In/z_en_in.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_ha/object_ha.h" struct EnHorse; +typedef void (*EnHorseActionFunc)(struct EnHorse*, GlobalContext*); +typedef void (*EnHorsePostdrawFunc)(struct EnHorse*, GlobalContext*); +typedef void (*EnHorseCsFunc)(struct EnHorse*, GlobalContext*, CsCmdActorAction*); + +#define ENHORSE_BOOST (1 << 0) /* 0x1 */ +#define ENHORSE_BOOST_DECEL (1 << 1) /* 0x2 */ +#define ENHORSE_JUMPING (1 << 2) /* 0x4 */ +#define ENHORSE_CALC_RIDER_POS (1 << 3) /* 0x8 */ +#define ENHORSE_FORCE_REVERSING (1 << 4) /* 0x10 */ +#define ENHORSE_FORCE_WALKING (1 << 5) /* 0x20 */ +#define ENHORSE_FLAG_6 (1 << 6) /* 0x40 */ +#define ENHORSE_FLAG_7 (1 << 7) /* 0x80 */ +#define ENHORSE_FLAG_8 (1 << 8) /* 0x100 */ +#define ENHORSE_FLAG_9 (1 << 9) /* 0x200 */ +#define ENHORSE_STOPPING_NEIGH_SOUND (1 << 10) /* 0x400 */ +#define ENHORSE_LAND2_SOUND (1 << 11) /* 0x800 */ +#define ENHORSE_SANDDUST_SOUND (1 << 12) /* 0x1000 */ +#define ENHORSE_INACTIVE (1 << 13) /* 0x2000 */ +#define ENHORSE_OBSTACLE (1 << 14) /* 0x4000 */ +#define ENHORSE_TURNING_TO_PLAYER (1 << 15) /* 0x8000 */ +#define ENHORSE_UNRIDEABLE (1 << 16) /* 0x10000 */ +#define ENHORSE_CANT_JUMP (1 << 17) /* 0x20000 */ +#define ENHORSE_FLAG_18 (1 << 18) /* 0x40000 */ +#define ENHORSE_FLAG_19 (1 << 19) /* 0x80000 */ +#define ENHORSE_FLAG_20 (1 << 20) /* 0x100000 */ +#define ENHORSE_FLAG_21 (1 << 21) /* 0x200000 */ +#define ENHORSE_FIRST_BOOST_REGEN (1 << 22) /* 0x400000 */ +#define ENHORSE_INGO_WON (1 << 23) /* 0x800000 */ +#define ENHORSE_FLAG_24 (1 << 24) /* 0x1000000 */ +#define ENHORSE_FLAG_25 (1 << 25) /* 0x2000000 */ +#define ENHORSE_FLAG_26 (1 << 26) /* 0x4000000 */ +#define ENHORSE_DRAW (1 << 27) /* 0x8000000 */ +#define ENHORSE_FLAG_28 (1 << 28) /* 0x10000000 */ +#define ENHORSE_FLAG_29 (1 << 29) /* 0x20000000 */ +#define ENHORSE_FLAG_30 (1 << 30) /* 0x40000000 */ +#define ENHORSE_FLAG_31 (1 << 31) /* 0x80000000 */ + +typedef enum { + /* 0 */ ENHORSE_ACT_FROZEN, + /* 1 */ ENHORSE_ACT_INACTIVE, + /* 2 */ ENHORSE_ACT_IDLE, + /* 3 */ ENHORSE_ACT_FOLLOW_PLAYER, + /* 4 */ ENHORSE_ACT_INGO_RACE, + /* 5 */ ENHORSE_ACT_MOUNTED_IDLE, + /* 6 */ ENHORSE_ACT_MOUNTED_IDLE_WHINNEYING, + /* 7 */ ENHORSE_ACT_MOUNTED_TURN, + /* 8 */ ENHORSE_ACT_MOUNTED_WALK, + /* 9 */ ENHORSE_ACT_MOUNTED_TROT, + /* 10 */ ENHORSE_ACT_MOUNTED_GALLOP, + /* 11 */ ENHORSE_ACT_MOUNTED_REARING, + /* 12 */ ENHORSE_ACT_STOPPING, + /* 13 */ ENHORSE_ACT_REVERSE, + /* 14 */ ENHORSE_ACT_LOW_JUMP, + /* 15 */ ENHORSE_ACT_HIGH_JUMP, + /* 16 */ ENHORSE_ACT_BRIDGE_JUMP, + /* 17 */ ENHORSE_ACT_CS_UPDATE, + /* 18 */ ENHORSE_ACT_HBA, + /* 19 */ ENHORSE_ACT_FLEE_PLAYER, + /* 20 */ ENHORSE_ACT_20, + /* 21 */ ENHORSE_ACT_21, + /* 22 */ ENHORSE_ACT_22, + /* 23 */ ENHORSE_ACT_23, + /* 24 */ ENHORSE_ACT_24, + /* 25 */ ENHORSE_ACT_25, +} EnHorseAction; + +typedef enum { + /* 0 */ PLAYER_DIR_FRONT_R, + /* 1 */ PLAYER_DIR_FRONT_L, + /* 2 */ PLAYER_DIR_BACK_R, + /* 3 */ PLAYER_DIR_BACK_L, + /* 4 */ PLAYER_DIR_SIDE_R, + /* 5 */ PLAYER_DIR_SIDE_L +} EnHorsePlayerDir; + +typedef enum { + /* 0 */ ENHORSE_ANIM_IDLE, + /* 1 */ ENHORSE_ANIM_WHINNEY, + /* 2 */ ENHORSE_ANIM_STOPPING, + /* 3 */ ENHORSE_ANIM_REARING, + /* 4 */ ENHORSE_ANIM_WALK, + /* 5 */ ENHORSE_ANIM_TROT, + /* 6 */ ENHORSE_ANIM_GALLOP, + /* 7 */ ENHORSE_ANIM_LOW_JUMP, + /* 8 */ ENHORSE_ANIM_HIGH_JUMP +} EnHorseAnimationIndex; + +typedef enum { + /* 0 */ HORSE_EPONA, + /* 1 */ HORSE_HNI, + /* 2 */ HORSE_2, + /* 3 */ HORSE_3, + /* 4 */ HORSE_4 +} HorseType; + +#define ENHORSE_GET_2000(thisx) ((thisx)->params & 0x2000) +#define ENHORSE_GET_4000(thisx) ((thisx)->params & 0x4000) +#define ENHORSE_GET_8000(thisx) ((thisx)->params & 0x8000) + +enum { + /* 0 */ ENHORSE_0, + /* 1 */ ENHORSE_1, + /* 2 */ ENHORSE_2, + /* 3 */ ENHORSE_3, + /* 4 */ ENHORSE_4, + /* 5 */ ENHORSE_5, + /* 6 */ ENHORSE_6, + /* 7 */ ENHORSE_7, + /* 8 */ ENHORSE_8, + /* 9 */ ENHORSE_9, + /* 10 */ ENHORSE_10, + /* 11 */ ENHORSE_11, + /* 12 */ ENHORSE_12, + /* 13 */ ENHORSE_13, + /* 14 */ ENHORSE_14, + /* 15 */ ENHORSE_15, + /* 16 */ ENHORSE_16, + /* 17 */ ENHORSE_17, + /* 18 */ ENHORSE_18, + /* 19 */ ENHORSE_19, + /* 20 */ ENHORSE_20, +}; + typedef struct EnHorse { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x00C]; - /* 0x150 */ s32 unk_150; - /* 0x154 */ char unk_154[0x440]; + /* 0x144 */ s32 action; + /* 0x148 */ s32 noInputTimer; + /* 0x14C */ s32 noInputTimerMax; + /* 0x150 */ s32 type; + /* 0x154 */ s8 bankIndex; + /* 0x158 */ Skin skin; + /* 0x1E8 */ s32 stateFlags; + /* 0x1EC */ s32 unk_1EC; + /* 0x1F0 */ Vec3f lastPos; + /* 0x1FC */ s16 lastYaw; + /* 0x200 */ s32 curRaceWaypoint; + /* 0x204 */ s32 boostSpeed; + /* 0x208 */ s32 playerControlled; + /* 0x20C */ s32 animationIdx; + /* 0x210 */ f32 curFrame; + /* 0x214 */ s32 soundTimer; + /* 0x218 */ Vec3f unk_218; + /* 0x224 */ UNK_TYPE1 unk224[0xC]; + /* 0x230 */ s32 unk_230; + /* 0x234 */ u8 numBoosts; + /* 0x238 */ s32 boostRegenTime; + /* 0x23C */ s32 boostTimer; + /* 0x240 */ EnHorsePostdrawFunc postDrawFunc; + /* 0x244 */ f32 yFront; + /* 0x248 */ f32 yBack; + /* 0x24C */ s32 unk_24C; + /* 0x250 */ s16 followTimer; + /* 0x254 */ s32 prevAction; + /* 0x258 */ Vec3f riderPos; + /* 0x264 */ Vec2f curStick; + /* 0x26C */ Vec2f lastStick; + /* 0x274 */ f32 jumpStartY; + /* 0x278 */ ColliderCylinder colliderCylinder1; + /* 0x2C4 */ ColliderCylinder colliderCylinder2; + /* 0x310 */ ColliderJntSph colliderJntSph; + /* 0x330 */ ColliderJntSphElement colliderJntSphElements[1]; + /* 0x370 */ s32 playerDir; + /* 0x374 */ UNK_TYPE1 unk374[0x2]; + /* 0x376 */ s16 angleToPlayer; + /* 0x378 */ s16 followPlayerTurnSpeed; + /* 0x37A */ u8 blinkTimer; + /* 0x37C */ s16 waitTimer; + /* 0x380 */ s32 cutsceneAction; + /* 0x384 */ u16 cutsceneFlags; + /* 0x388 */ s32 inRace; + /* 0x38C */ struct EnIn* rider; + /* 0x390 */ UNK_TYPE1 unk390[0x4]; + /* 0x394 */ u16 unk_394; + /* 0x398 */ f32 unk_398; + /* 0x39C */ s32 unk_39C; + /* 0x3A0 */ s32 hbaStarted; + /* 0x3A4 */ s32 hbaFlags; + /* 0x3A8 */ s32 hbaTimer; + /* 0x3AC */ u16 dustFlags; + /* 0x3B0 */ Vec3f frontRightHoof; + /* 0x3BC */ Vec3f frontLeftHoof; + /* 0x3C8 */ Vec3f backRightHoof; + /* 0x3D4 */ Vec3f backLeftHoof; + /* 0x3E0 */ s32 unk_3E0; + /* 0x3E4 */ UNK_TYPE1 unk3E4[0x4]; + /* 0x3E8 */ f32 unk_3E8; + /* 0x3EC */ s16 unk_3EC; + /* 0x3EE */ Vec3s jointTable[OBJECT_HA_1_LIMB_MAX]; + /* 0x48A */ Vec3s morphTable[OBJECT_HA_1_LIMB_MAX]; + /* 0x528 */ f32 unk_528; + /* 0x52C */ s32 unk_52C; + /* 0x530 */ s32 unk_530; + /* 0x534 */ s32 unk_534; + /* 0x538 */ s32 unk_538; + /* 0x53C */ s32 unk_53C; + /* 0x540 */ Vec3f unk_540; + /* 0x54C */ UNK_TYPE1 unk54C[0x4]; + /* 0x550 */ s32 unk_550; + /* 0x554 */ UNK_TYPE1 unk554[0x18]; + /* 0x56C */ f32 unk_56C; + /* 0x570 */ Vec3f unk_570; + /* 0x57C */ Vec3f unk_57C; + /* 0x588 */ UNK_TYPE1 unk588[0x4]; + /* 0x58C */ s32 unk_58C; + /* 0x590 */ s32 unk_590; } EnHorse; // size = 0x594 extern const ActorInit En_Horse_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 593f56e35..ae5f25c87 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,6 +1,13 @@ -#include "z_en_horse_game_check.h" +/* + * File: z_en_horse_game_check.c + * Overlay: ovl_En_Horse_Game_Check + * Description: Dirt patches you can jump over on Gorman Race Track + */ -#define FLAGS 0x00000010 +#include "z_en_horse_game_check.h" +#include "objects/object_horse_game_check/object_horse_game_check.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnHorseGameCheck*)thisx) @@ -9,7 +16,25 @@ void EnHorseGameCheck_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHorseGameCheck_Update(Actor* thisx, GlobalContext* globalCtx); void EnHorseGameCheck_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +s32 func_808F8AA0(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F8C24(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F8C5C(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F8C70(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F8CCC(EnHorseGameCheck* this, GlobalContext* globalCtx2); +s32 func_808F8E94(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F8FAC(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F96E4(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F9830(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F9868(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F987C(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F990C(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F9944(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F9958(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F999C(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F99B0(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F99C4(EnHorseGameCheck* this, GlobalContext* globalCtx); +s32 func_808F99D8(EnHorseGameCheck* this, GlobalContext* globalCtx); + const ActorInit En_Horse_Game_Check_InitVars = { ACTOR_EN_HORSE_GAME_CHECK, ACTORCAT_BG, @@ -22,63 +47,454 @@ const ActorInit En_Horse_Game_Check_InitVars = { (ActorFunc)EnHorseGameCheck_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808F9BDC[] = { +#include "overlays/ovl_En_Horse_Game_Check/ovl_En_Horse_Game_Check.c" + +s32 func_808F8AA0(EnHorseGameCheck* this, GlobalContext* globalCtx) { + s32 pad[3]; + CollisionHeader* sp78 = NULL; + MtxF sp38; + + this->dyna.actor.scale.x = this->dyna.actor.scale.y = this->dyna.actor.scale.z = this->unk_160 * 0.001f; + this->dyna.actor.flags |= ACTOR_FLAG_400000; + + DynaPolyActor_Init(&this->dyna, 0); + + if (GET_RACE_FLAGS != RACE_FLAG_START) { + Actor_MarkForDeath(&this->dyna.actor); + return false; + } + + CollisionHeader_GetVirtual(&object_horse_game_check_Colheader_003918, &sp78); + + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp78); + this->unk_15C = ENHORSEGAMECHECK_FF_5; + this->dyna.actor.floorPoly = NULL; + this->dyna.actor.world.pos.y += 100.0f; + + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor2( + globalCtx, &globalCtx->colCtx, &this->dyna.actor.floorPoly, &this->dyna.actor.world.pos); + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight + 3.0f; + func_800C0094(this->dyna.actor.floorPoly, this->dyna.actor.world.pos.x, this->dyna.actor.floorHeight, + this->dyna.actor.world.pos.z, &sp38); + + Matrix_Put(&sp38); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.y, MTXMODE_APPLY); + Matrix_Get(&sp38); + + Matrix_MtxFToYXZRot(&sp38, &this->dyna.actor.shape.rot, true); + this->dyna.actor.world.rot = this->dyna.actor.shape.rot; + return true; +} + +s32 func_808F8C24(EnHorseGameCheck* this, GlobalContext* globalCtx) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + return true; +} + +s32 func_808F8C5C(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} + +s32 func_808F8C70(EnHorseGameCheck* this, GlobalContext* globalCtx) { + if (Matrix_NewMtx(globalCtx->state.gfxCtx) == NULL) { + return true; + } else { + Gfx_DrawDListXlu(globalCtx, object_horse_game_check_DL_003030); + Gfx_DrawDListOpa(globalCtx, object_horse_game_check_DL_0030C0); + } + return true; +} + +s32 func_808F8CCC(EnHorseGameCheck* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 pad; + Vec3f sp4C = { -1262.0f, 15.0f, 780.0f }; + Vec3f sp40 = { -1262.0f, -26.0f, 470.0f }; + + this->unk_164 = 0; + this->unk_168 = 0; + this->unk_174 = 0; + + if (GET_RACE_FLAGS != RACE_FLAG_START) { + Actor_MarkForDeath(&this->dyna.actor); + return false; + } + + func_8010E9F0(4, 0); + globalCtx->interfaceCtx.unk_280 = 1; + + this->horse1 = (EnHorse*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HORSE, -1149.0f, -106.0f, 470.0f, 0, + 0x7FFF, 0, 0x2004); + if (this->horse1 == NULL) { + __assert("../z_en_horse_game_check.c", 1517); + } + + this->horse2 = (EnHorse*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HORSE, -1376.0f, -106.0f, 470.0f, 0, + 0x7FFF, 0, 0x2005); + if (this->horse2 == NULL) { + __assert("../z_en_horse_game_check.c", 1526); + } + + this->unk_17C = -1; + func_800DFAC8(globalCtx->cameraPtrs[CAM_ID_MAIN], 10); + Play_CameraSetAtEye(globalCtx, 0, &sp40, &sp4C); + Play_CameraSetFov(globalCtx, 0, 45.0f); + func_800FE484(); + return false; +} + +s32 func_808F8E94(EnHorseGameCheck* this, GlobalContext* globalCtx) { + gSaveContext.unk_3DD0[4] = 0; + return true; +} + +s32 func_808F8EB0(EnHorseGameCheck* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (globalCtx->nextEntranceIndex == 0xCE20) { + return false; + } + + if (GET_RACE_FLAGS == RACE_FLAG_3) { + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 2; + } else if (GET_RACE_FLAGS == RACE_FLAG_2) { + globalCtx->unk_1887F = 0x50; + gSaveContext.nextTransition = 3; + } else if (GET_RACE_FLAGS == RACE_FLAG_4) { + SET_RACE_FLAGS(RACE_FLAG_3); + globalCtx->unk_1887F = 2; + gSaveContext.nextTransition = 2; + } + + D_801BDA9C = 0; + if (player->stateFlags1 & 0x800000) { + D_801BDAA0 = 1; + } + globalCtx->nextEntranceIndex = 0xCE20; + globalCtx->sceneLoadFlag = 0x14; + return false; +} + +f32 D_808F9BAC[] = { + -1825.0f, + -237.0f, + -2867.0f, + -1987.0f, +}; + +f32 D_808F9BBC[] = { + 1564.0f, + 3395.0f, + -1665.0f, + -200.0f, +}; + +f32 D_808F9BCC[] = { + -22.0f, + 2005.0f, + 3869.0f, + 5368.0f, +}; + +s32 func_808F8FAC(EnHorseGameCheck* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player = GET_PLAYER(globalCtx); + s32 pad2; + EnHorse* horse = (EnHorse*)player->rideActor; + s32 pad3[2]; + EnHorseGameCheck* horseGameCheck; + + if (horse == NULL) { + return true; + } + + if ((this->unk_168 > 50) && !(this->unk_164 & 2)) { + this->unk_164 |= 2; + } else if ((globalCtx->interfaceCtx.unk_280 >= 8) && !(this->unk_164 & 1)) { + this->unk_164 |= 1; + horse->inRace = true; + } else if ((globalCtx->interfaceCtx.unk_280 >= 8) && !(this->unk_164 & 8)) { + EnHorse* horse = this->horse1; + + horse->inRace = true; + horse = this->horse2; + horse->inRace = true; + + this->unk_164 |= 8; + this->unk_17C = this->unk_168; + } + + if ((this->unk_17C != -1) && ((this->unk_168 - this->unk_17C) > 10)) { + this->unk_17C = -1; + func_800DFAC8(globalCtx->cameraPtrs[CAM_ID_MAIN], 4); + } + + this->unk_168++; + if ((this->unk_164 & 0x4000) && (this->unk_164 & 0x200000)) { + if (!(this->unk_164 & 0x10)) { + this->unk_164 |= 0x10; + } + } + + if ((this->unk_164 & 0x800) || (this->unk_164 & 0x40000) || (this->unk_164 & 0x02000000)) { + if (this->unk_174 > 0) { + this->unk_174--; + } else { + func_808F8EB0(this, globalCtx); + } + return true; + } + + if (gSaveContext.unk_3DE0[4] >= 0x4650) { + Audio_QueueSeqCmd(0x8041); + play_sound(NA_SE_SY_START_SHOT); + this->unk_164 |= 0x40000; + gSaveContext.unk_3DD0[4] = 6; + SET_RACE_FLAGS(RACE_FLAG_4); + this->unk_174 = 60; + } + + if (!(this->unk_164 & 0x1000)) { + if (Math3D_XZBoundCheck(D_808F9BAC[0], D_808F9BAC[1], D_808F9BAC[2], D_808F9BAC[3], + this->horse1->actor.world.pos.x, this->horse1->actor.world.pos.z)) { + this->unk_164 |= 0x1000; + } + } + + if (!(this->unk_164 & 0x2000) && (this->unk_164 & 0x1000)) { + if (Math3D_XZBoundCheck(D_808F9BBC[0], D_808F9BBC[1], D_808F9BBC[2], D_808F9BBC[3], + this->horse1->actor.world.pos.x, this->horse1->actor.world.pos.z)) { + this->unk_164 |= 0x2000; + } + } + + if (!(this->unk_164 & 0x4000) && (this->unk_164 & 0x2000)) { + if (Math3D_XZBoundCheck(D_808F9BCC[0], D_808F9BCC[1], D_808F9BCC[2], D_808F9BCC[3], + this->horse1->actor.world.pos.x, this->horse1->actor.world.pos.z)) { + this->unk_164 |= 0x4000; + } + } + + horseGameCheck = (EnHorseGameCheck*)DynaPoly_GetActor(&globalCtx->colCtx, this->horse1->unk_24C); + if ((this->unk_164 & 0x4000) && (horseGameCheck != NULL) && + (horseGameCheck->dyna.actor.id == ACTOR_EN_HORSE_GAME_CHECK) && + (horseGameCheck->unk_15C == ENHORSEGAMECHECK_FF_7) && !(this->unk_164 & 0x40000)) { + Audio_QueueSeqCmd(0x8041); + play_sound(NA_SE_SY_START_SHOT); + this->unk_164 |= 0x40000; + gSaveContext.unk_3DD0[4] = 6; + SET_RACE_FLAGS(RACE_FLAG_3); + this->unk_174 = 60; + } + + if (!(this->unk_164 & 0x80000)) { + if (Math3D_XZBoundCheck(D_808F9BAC[0], D_808F9BAC[1], D_808F9BAC[2], D_808F9BAC[3], + this->horse2->actor.world.pos.x, this->horse2->actor.world.pos.z)) { + this->unk_164 |= 0x80000; + } + } + + if (!(this->unk_164 & 0x100000) && (this->unk_164 & 0x80000)) { + if (Math3D_XZBoundCheck(D_808F9BBC[0], D_808F9BBC[1], D_808F9BBC[2], D_808F9BBC[3], + this->horse2->actor.world.pos.x, this->horse2->actor.world.pos.z)) { + this->unk_164 |= 0x100000; + } + } + + if (!(this->unk_164 & 0x200000) && (this->unk_164 & 0x100000)) { + if (Math3D_XZBoundCheck(D_808F9BCC[0], D_808F9BCC[1], D_808F9BCC[2], D_808F9BCC[3], + this->horse2->actor.world.pos.x, this->horse2->actor.world.pos.z)) { + this->unk_164 |= 0x200000; + } + } + + horseGameCheck = (EnHorseGameCheck*)DynaPoly_GetActor(&globalCtx->colCtx, this->horse2->unk_24C); + if ((this->unk_164 & 0x200000) && (horseGameCheck != NULL) && + (horseGameCheck->dyna.actor.id == ACTOR_EN_HORSE_GAME_CHECK) && + (horseGameCheck->unk_15C == ENHORSEGAMECHECK_FF_7) && !(this->unk_164 & 0x02000000)) { + Audio_QueueSeqCmd(0x8041); + play_sound(NA_SE_SY_START_SHOT); + this->unk_164 |= 0x02000000; + gSaveContext.unk_3DD0[4] = 6; + SET_RACE_FLAGS(RACE_FLAG_3); + this->unk_174 = 60; + } + + if (!(this->unk_164 & 0x20) && Math3D_XZBoundCheck(D_808F9BAC[0], D_808F9BAC[1], D_808F9BAC[2], D_808F9BAC[3], + horse->actor.world.pos.x, horse->actor.world.pos.z)) { + this->unk_164 |= 0x20; + } + + if (!(this->unk_164 & 0x40) && (this->unk_164 & 0x20) && + Math3D_XZBoundCheck(D_808F9BBC[0], D_808F9BBC[1], D_808F9BBC[2], D_808F9BBC[3], horse->actor.world.pos.x, + horse->actor.world.pos.z)) { + this->unk_164 |= 0x40; + } + + if (!(this->unk_164 & 0x80) && (this->unk_164 & 0x40) && + Math3D_XZBoundCheck(D_808F9BCC[0], D_808F9BCC[1], D_808F9BCC[2], D_808F9BCC[3], horse->actor.world.pos.x, + horse->actor.world.pos.z)) { + this->unk_164 |= 0x80; + } + + horseGameCheck = (EnHorseGameCheck*)DynaPoly_GetActor(&globalCtx->colCtx, horse->unk_24C); + if ((this->unk_164 & 0x80) && (horseGameCheck != NULL) && + (horseGameCheck->dyna.actor.id == ACTOR_EN_HORSE_GAME_CHECK) && + (horseGameCheck->unk_15C == ENHORSEGAMECHECK_FF_7) && !(this->unk_164 & 0x800)) { + Audio_QueueSeqCmd(0x8041); + play_sound(NA_SE_SY_START_SHOT); + this->unk_164 |= 0x800; + gSaveContext.unk_3DD0[4] = 6; + SET_RACE_FLAGS(RACE_FLAG_2); + this->unk_174 = 60; + } + return true; +} + +s32 func_808F96E4(EnHorseGameCheck* this, GlobalContext* globalCtx) { + s32 pad[3]; + CollisionHeader* sp78 = NULL; + MtxF sp38; + + this->dyna.actor.scale.x = this->dyna.actor.scale.y = this->dyna.actor.scale.z = this->unk_160 * 0.01f; + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&ovl_En_Horse_Game_Check_Colheader_0010C8, &sp78); + + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp78); + this->unk_15C = ENHORSEGAMECHECK_FF_7; + this->dyna.actor.floorPoly = NULL; + this->dyna.actor.world.pos.y += 100.0f; + + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor2( + globalCtx, &globalCtx->colCtx, &this->dyna.actor.floorPoly, &this->dyna.actor.world.pos); + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight + 1.0f; + func_800C0094(this->dyna.actor.floorPoly, this->dyna.actor.world.pos.x, this->dyna.actor.floorHeight, + this->dyna.actor.world.pos.z, &sp38); + + Matrix_Put(&sp38); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.y, MTXMODE_APPLY); + Matrix_Get(&sp38); + + Matrix_MtxFToYXZRot(&sp38, &this->dyna.actor.shape.rot, true); + this->dyna.actor.world.rot = this->dyna.actor.shape.rot; + return true; +} + +s32 func_808F9830(EnHorseGameCheck* this, GlobalContext* globalCtx) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + return true; +} + +s32 func_808F9868(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 2400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP), }; -#endif +s32 func_808F987C(EnHorseGameCheck* this, GlobalContext* globalCtx) { + s32 pad[3]; + CollisionHeader* sp28 = NULL; + s32 pad2; -extern InitChainEntry D_808F9BDC[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.scale.z = 1.0f; + this->dyna.actor.scale.y = 1.0f; + this->dyna.actor.scale.x = 1.0f; + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&object_horse_game_check_Colheader_002FB8, &sp28); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp28); + this->unk_15C = ENHORSEGAMECHECK_FF_8; + return true; +} -extern UNK_TYPE D_060014B0; -extern UNK_TYPE D_06002FB8; -extern UNK_TYPE D_06003030; -extern UNK_TYPE D_06003918; +s32 func_808F990C(EnHorseGameCheck* this, GlobalContext* globalCtx) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8AA0.s") +s32 func_808F9944(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8C24.s") +s32 func_808F9958(EnHorseGameCheck* this, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, object_horse_game_check_DL_0014B0); + Gfx_DrawDListOpa(globalCtx, object_horse_game_check_DL_0013A0); + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8C5C.s") +s32 func_808F999C(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8C70.s") +s32 func_808F99B0(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8CCC.s") +s32 func_808F99C4(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8E94.s") +s32 func_808F99D8(EnHorseGameCheck* this, GlobalContext* globalCtx) { + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8EB0.s") +EnHorseGameCheckUnkFunc D_808F9BE4[] = { + NULL, NULL, NULL, NULL, NULL, func_808F8AA0, func_808F8CCC, func_808F96E4, func_808F987C, func_808F999C, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F8FAC.s") +EnHorseGameCheckUnkFunc D_808F9C0C[] = { + NULL, NULL, NULL, NULL, NULL, func_808F8C24, func_808F8E94, func_808F9830, func_808F990C, func_808F99B0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F96E4.s") +EnHorseGameCheckUnkFunc D_808F9C34[] = { + NULL, NULL, NULL, NULL, NULL, func_808F8C5C, func_808F8FAC, func_808F9868, func_808F9944, func_808F99C4, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F9830.s") +EnHorseGameCheckUnkFunc D_808F9C5C[] = { + NULL, NULL, NULL, NULL, NULL, func_808F8C70, NULL, NULL, func_808F9958, func_808F99D8, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F9868.s") +void EnHorseGameCheck_Init(Actor* thisx, GlobalContext* globalCtx) { + EnHorseGameCheck* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F987C.s") + this->unk_15C = ENHORSEGAMECHECK_GET_FF(&this->dyna.actor); + this->unk_160 = ENHORSEGAMECHECK_GET_FF00(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F990C.s") + if (this->unk_15C >= ENHORSEGAMECHECK_FF_MAX) { + this->unk_15C = ENHORSEGAMECHECK_FF_0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F9944.s") + if (D_808F9BE4[this->unk_15C] != NULL) { + D_808F9BE4[this->unk_15C](this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F9958.s") +void EnHorseGameCheck_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHorseGameCheck* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F999C.s") + if (D_808F9C0C[this->unk_15C] != NULL) { + D_808F9C0C[this->unk_15C](this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F99B0.s") +void EnHorseGameCheck_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHorseGameCheck* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F99C4.s") + if (D_808F9C34[this->unk_15C] != NULL) { + D_808F9C34[this->unk_15C](this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/func_808F99D8.s") +void EnHorseGameCheck_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHorseGameCheck* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/EnHorseGameCheck_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/EnHorseGameCheck_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/EnHorseGameCheck_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Horse_Game_Check/EnHorseGameCheck_Draw.s") + if (D_808F9C5C[this->unk_15C] != NULL) { + D_808F9C5C[this->unk_15C](this, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h index 4c0461982..886187b49 100644 --- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h +++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h @@ -2,12 +2,57 @@ #define Z_EN_HORSE_GAME_CHECK_H #include "global.h" +#include "overlays/actors/ovl_En_Horse/z_en_horse.h" struct EnHorseGameCheck; +typedef s32 (*EnHorseGameCheckUnkFunc)(struct EnHorseGameCheck*, GlobalContext*); + +#define ENHORSEGAMECHECK_GET_FF(thisx) ((thisx)->params & 0xFF) +#define ENHORSEGAMECHECK_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + +enum { + /* 0 */ ENHORSEGAMECHECK_FF_0, + /* 1 */ ENHORSEGAMECHECK_FF_1, + /* 2 */ ENHORSEGAMECHECK_FF_2, + /* 3 */ ENHORSEGAMECHECK_FF_3, + /* 4 */ ENHORSEGAMECHECK_FF_4, + /* 5 */ ENHORSEGAMECHECK_FF_5, + /* 6 */ ENHORSEGAMECHECK_FF_6, + /* 7 */ ENHORSEGAMECHECK_FF_7, + /* 8 */ ENHORSEGAMECHECK_FF_8, + /* 9 */ ENHORSEGAMECHECK_FF_9, + /* 10 */ ENHORSEGAMECHECK_FF_MAX, +}; + +#define RACE_FLAG_END 0 +#define RACE_FLAG_START 1 +#define RACE_FLAG_2 2 +#define RACE_FLAG_3 3 +#define RACE_FLAG_4 4 +#define RACE_FLAGS 7 + +#define GET_RACE_FLAGS (gSaveContext.save.weekEventReg[92] & RACE_FLAGS) + +#define SET_RACE_FLAGS(flag) \ + { \ + gSaveContext.save.weekEventReg[92] &= (u8)~RACE_FLAGS; \ + gSaveContext.save.weekEventReg[92] = \ + gSaveContext.save.weekEventReg[92] | (u8)((gSaveContext.save.weekEventReg[92] & ~RACE_FLAGS) | (flag)); \ + } (void)0 + typedef struct EnHorseGameCheck { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x74]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ s32 unk_15C; + /* 0x160 */ s32 unk_160; + /* 0x164 */ s32 unk_164; + /* 0x168 */ s32 unk_168; + /* 0x16C */ EnHorse* horse1; + /* 0x170 */ EnHorse* horse2; + /* 0x174 */ s32 unk_174; + /* 0x178 */ UNK_TYPE1 pad178[0x4]; + /* 0x17C */ s32 unk_17C; + /* 0x180 */ UNK_TYPE1 pad180[0x38]; } EnHorseGameCheck; // size = 0x1B8 extern const ActorInit En_Horse_Game_Check_InitVars; diff --git a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c index 8057ca491..da62a57e0 100644 --- a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c +++ b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.c @@ -1,6 +1,12 @@ +/* + * File: z_en_horse_link_child.c + * Overlay: ovl_En_Horse_Link_Child + * Description: Child Epona + */ + #include "z_en_horse_link_child.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnHorseLinkChild*)thisx) diff --git a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h index 16ac6a616..ecc816c52 100644 --- a/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h +++ b/src/overlays/actors/ovl_En_Horse_Link_Child/z_en_horse_link_child.h @@ -2,6 +2,7 @@ #define Z_EN_HORSE_LINK_CHILD_H #include "global.h" +#include "z64skin.h" struct EnHorseLinkChild; diff --git a/src/overlays/actors/ovl_En_Hs/z_en_hs.c b/src/overlays/actors/ovl_En_Hs/z_en_hs.c index ca2f01e56..1e9fdfbf9 100644 --- a/src/overlays/actors/ovl_En_Hs/z_en_hs.c +++ b/src/overlays/actors/ovl_En_Hs/z_en_hs.c @@ -1,6 +1,12 @@ +/* + * File: z_en_hs.c + * Overlay: ovl_En_Hs + * Description: Grog + */ + #include "z_en_hs.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnHs*)thisx) @@ -12,12 +18,11 @@ void EnHs_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80952FE0(EnHs* this, GlobalContext* globalCtx); void func_80953098(EnHs* this, GlobalContext* globalCtx); void func_80953180(EnHs* this, GlobalContext* globalCtx); -void func_809532C0(EnHs* this, GlobalContext* globalCtx); -void func_809532D0(EnHs* this, GlobalContext* globalCtx); +void EnHs_DoNothing(EnHs* this, GlobalContext* globalCtx); +void EnHs_SceneTransitToBunnyHoodDialogue(EnHs* this, GlobalContext* globalCtx); void func_80953354(EnHs* this, GlobalContext* globalCtx); void func_8095345C(EnHs* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Hs_InitVars = { ACTOR_EN_HS, ACTORCAT_NPC, @@ -30,51 +35,328 @@ const ActorInit En_Hs_InitVars = { (ActorFunc)EnHs_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80953910 = { - { 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, + }, { 40, 40, 0, { 0, 0, 0 } }, }; -#endif +Vec3f D_8095393C = { 300.0f, 1000.0f, 0.0f }; -extern ColliderCylinderInit D_80953910; +void func_80952C50(EnHs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; -extern UNK_TYPE D_060005C0; + for (i = 0; i < ARRAY_COUNT(this->nwcPos); i++) { + Math_Vec3f_Copy(&this->nwcPos[i], &player->actor.world.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80952C50.s") + this->actor.home.rot.x = 0; // reset adult transformed count + this->actor.home.rot.z = 0; // reset chick count +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/EnHs_Init.s") +void EnHs_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/EnHs_Destroy.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gHsSkeleton, &gHsIdleAnim, this->jointTable, this->morphTable, + OBJECT_HS_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gHsIdleAnim); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = func_8095345C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80952DFC.s") + if (globalCtx->curSpawn == 1) { + this->actor.flags |= ACTOR_FLAG_10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80952E50.s") + this->stateFlags = 0; + this->actor.targetMode = 6; + func_80952C50(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80952F00.s") +void EnHs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80952FE0.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80953098.s") +void func_80952DFC(GlobalContext* globalCtx) { + if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { + func_80151BB4(globalCtx, 0x2E); + } + func_80151BB4(globalCtx, 0x10); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80953180.s") +void EnHs_UpdateChickPos(Vec3f* dst, Vec3f src, f32 offset) { + Vec3f diff; + f32 distance; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_809532C0.s") + Math_Vec3f_Diff(&src, dst, &diff); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_809532D0.s") + distance = SQ(diff.x) + SQ(diff.z); // gets un-squared after we check if we are too close -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80953354.s") + if (SQ(offset) > distance) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_809533A0.s") + distance = sqrtf(distance); + diff.x *= (distance - offset) / distance; + diff.z *= (distance - offset) / distance; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_8095345C.s") + dst->x += diff.x; + dst->z += diff.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/EnHs_Update.s") +void func_80952F00(EnHs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + f32 offset; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_8095376C.s") + if (this->actor.home.rot.z >= 20) { // current chick count >= 10 + offset = 15.0f; + } else { + offset = 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/func_80953848.s") + EnHs_UpdateChickPos(&this->nwcPos[0], player->actor.world.pos, offset); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hs/EnHs_Draw.s") + for (i = 1; i < ARRAY_COUNT(this->nwcPos); i++) { + EnHs_UpdateChickPos(&this->nwcPos[i], this->nwcPos[i - 1], offset); + } +} + +void func_80952FE0(EnHs* this, GlobalContext* globalCtx) { + if (this->stateTimer < 40) { + Math_SmoothStepToS(&this->headRot.y, 0x1F40, 6, 0x1838, 0x64); + } else if (this->stateTimer < 80) { + Math_SmoothStepToS(&this->headRot.y, -0x1F40, 6, 0x1838, 0x64); + } else { + this->actionFunc = func_80953180; + this->stateFlags &= ~4; + func_80151938(globalCtx, 0x33F6); + func_80952DFC(globalCtx); + } + this->stateTimer++; +} + +void func_80953098(EnHs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_8095345C; + this->actor.flags |= ACTOR_FLAG_10000; + this->stateFlags |= 0x10; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } else { + this->stateFlags |= 8; + if (INV_CONTENT(ITEM_MASK_BUNNY) == ITEM_MASK_BUNNY) { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 10000.0f, 50.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_MASK_BUNNY, 10000.0f, 50.0f); + } + } +} + +void func_80953180(EnHs* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x33F4: // text: laughing that they are all roosters (!) + case 0x33F6: // text: Grog regrets not being able to see his chicks reach adult hood + func_801477B4(globalCtx); + this->actionFunc = func_8095345C; + break; + + case 0x33F7: // text: notice his chicks are grown up, happy, wants to give you bunny hood + this->actor.flags &= ~ACTOR_FLAG_10000; + func_801477B4(globalCtx); + this->actionFunc = func_80953098; + func_80953098(this, globalCtx); + break; + + case 0x33F9: // text: laughing that they are all roosters (.) + this->actor.flags &= ~ACTOR_FLAG_10000; + func_801477B4(globalCtx); + this->actionFunc = func_8095345C; + break; + + case 0x33F5: // He heard from his gramps (?) the moon is going to fall + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80952FE0; + this->stateTimer = 0; + this->headRot.z = 0; + this->stateFlags |= 4; + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_8095345C; + break; + } + } +} + +void EnHs_DoNothing(EnHs* this, GlobalContext* globalCtx) { +} + +void EnHs_SceneTransitToBunnyHoodDialogue(EnHs* this, GlobalContext* globalCtx) { + if (DECR(this->stateTimer) == 0) { + globalCtx->nextEntranceIndex = globalCtx->setupExitList[HS_GET_EXIT_INDEX(&this->actor)]; + globalCtx->sceneLoadFlag = 0x14; + gSaveContext.save.weekEventReg[25] |= 8; + this->actionFunc = EnHs_DoNothing; + } +} + +void func_80953354(EnHs* this, GlobalContext* globalCtx) { + if (!Play_InCsMode(globalCtx)) { + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = EnHs_SceneTransitToBunnyHoodDialogue; + } +} + +void func_809533A0(EnHs* this, GlobalContext* globalCtx) { + u16 sp1E; + + if ((globalCtx->curSpawn == 1) && !(this->stateFlags & 0x20)) { + sp1E = 0x33F7; + this->stateFlags |= 0x20; + } else if (this->stateFlags & 0x10) { + sp1E = 0x33F9; + this->stateFlags &= ~0x10; + } else if (gSaveContext.save.weekEventReg[25] & 8) { + sp1E = 0x33F4; + } else { + sp1E = 0x33F5; + } + + Message_StartTextbox(globalCtx, sp1E, &this->actor); + + if (sp1E == 0x33F4) { + func_80952DFC(globalCtx); + } +} + +void func_8095345C(EnHs* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80953180; + func_809533A0(this, globalCtx); + if (this->stateFlags & 8) { + func_80952DFC(globalCtx); + this->stateFlags &= ~8; + } + } else if (this->actor.home.rot.x >= 20) { // chicks turned adult >= 10 + this->actionFunc = func_80953354; + this->stateTimer = 40; + } else if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_10000)) { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + this->stateFlags |= 1; + } else if ((this->actor.xzDistToPlayer < 120.0f) && Player_IsFacingActor(&this->actor, 0x2000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 130.0f); + this->stateFlags |= 1; + } else { + this->stateFlags &= ~1; + } +} + +void EnHs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHs* this = THIS; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + if (SkelAnime_Update(&this->skelAnime)) { + this->skelAnime.curFrame = 0.0f; + } + + this->actionFunc(this, globalCtx); + + func_80952F00(this, globalCtx); + + if (this->stateFlags & 4) { + Math_SmoothStepToS(&this->headRot.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unusedRot.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unusedRot.y, 0, 6, 0x1838, 0x64); + } else if (this->stateFlags & 1) { + func_800E9250(globalCtx, &this->actor, &this->headRot, &this->unusedRot, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->headRot.x, 0x3200, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->headRot.y, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unusedRot.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unusedRot.y, 0, 6, 0x1838, 0x64); + } +} + +s32 EnHs_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnHs* this = THIS; + + switch (limbIndex) { + case HS_LIMB_HEAD: + rot->x += this->headRot.y; + rot->z += this->headRot.x; + break; + + case HS_LIMB_HAIR_SPIKES: + rot->x += this->headRot.y; + rot->z += this->headRot.x; + break; + + case HS_LIMB_HIDDEN_HAIR: + // for some reason this hair is always removed here in the Override limb + // if you do re-enable, make sure you add the head rot like above + *dList = NULL; + return false; + + // these two limbs both have empty enddisplaylist, they do nothing + // at the same time (params == HS_TYPE_UNK1) is always false, because vanilla params is 0xFE01 + case OBJECT_HS_LIMB_0C: + if (this->actor.params == HS_TYPE_UNK1) { + *dList = NULL; + return false; + } + break; + + case OBJECT_HS_LIMB_0D: + if (this->actor.params == HS_TYPE_UNK1) { + *dList = NULL; + return false; + } + break; + } + return false; +} + +void EnHs_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnHs* this = THIS; + + if (limbIndex == HS_LIMB_HEAD) { + Matrix_MultVec3f(&D_8095393C, &this->actor.focus.pos); + } +} + +void EnHs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnHs* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnHs_OverrideLimbDraw, EnHs_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Hs/z_en_hs.h b/src/overlays/actors/ovl_En_Hs/z_en_hs.h index b9442c03d..62fc1d2a1 100644 --- a/src/overlays/actors/ovl_En_Hs/z_en_hs.h +++ b/src/overlays/actors/ovl_En_Hs/z_en_hs.h @@ -2,14 +2,35 @@ #define Z_EN_HS_H #include "global.h" +#include "objects/object_hs/object_hs.h" struct EnHs; typedef void (*EnHsActionFunc)(struct EnHs*, GlobalContext*); +#define HS_GET_EXIT_INDEX(thisx) ((thisx)->params & 0xF) + +#define HS_TYPE_UNK1 1 + +// params mystery: Vanilla Grog is 0xFE01 +// 0xFE00 space is never checked in Grog code +// at the same time, type UNK1 is only checked directly with params == 1, no &F +// so HS_TYPE_UNK1 is never valid and is unused, as 0xFE00 is still present even if its not doing anything else + +// The count of [chicks following the player] is stored in [this->actor.home.rot.z] (incremented by 2) +// The count of [chicks transformed into adult] is stored in [this->actor.home.rot.x] (incremented by 2) + typedef struct EnHs { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x250]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; + /* 0x01D4 */ Vec3s jointTable[OBJECT_HS_LIMB_MAX]; + /* 0x0234 */ Vec3s morphTable[OBJECT_HS_LIMB_MAX]; + /* 0x0294 */ Vec3s headRot; + /* 0x029A */ Vec3s unusedRot; // probably not chest, as chest is same limb as lower body + /* 0x02A0 */ u16 stateFlags; + /* 0x02A2 */ s16 stateTimer; // reused for different actionFunc + /* 0x02A4 */ Vec3f nwcPos[20]; // actual chick position are even values, odd values seem to be extra values for smoother chain /* 0x0394 */ EnHsActionFunc actionFunc; } EnHs; // size = 0x398 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 0cebfccd9..02625ff9e 100644 --- a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c +++ b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_hs2.c + * Overlay: ovl_En_Hs2 + * Description: Blue Target Spot (?) + */ + #include "z_en_hs2.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnHs2*)thisx) diff --git a/src/overlays/actors/ovl_En_Ig/z_en_ig.c b/src/overlays/actors/ovl_En_Ig/z_en_ig.c index b8e6e91d6..e687b770d 100644 --- a/src/overlays/actors/ovl_En_Ig/z_en_ig.c +++ b/src/overlays/actors/ovl_En_Ig/z_en_ig.c @@ -1,6 +1,14 @@ -#include "z_en_ig.h" +/* + * File: z_en_ig.c + * Overlay: ovl_En_Ig + * Description: The Goron named the same as the player + */ -#define FLAGS 0x00000019 +#include "z_en_ig.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_dai/object_dai.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnIg*)thisx) @@ -12,7 +20,75 @@ void EnIg_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BF2AF8(EnIg* this, GlobalContext* globalCtx); void func_80BF2BD4(EnIg* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80BF3260[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(1, 0xB6 - 0x05), + /* 0x05 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x57 - 0x09), + /* 0x09 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 25, 15, 45, 0x51 - 0x0F), + /* 0x0F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 45, 15, 50, 0x4B - 0x15), + /* 0x15 */ SCHEDULE_CMD_CHECK_FLAG_S(0x4B, 0x10, 0x1A - 0x19), + /* 0x19 */ SCHEDULE_CMD_RET_NONE(), + /* 0x1A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 50, 16, 55, 0x45 - 0x20), + /* 0x20 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 55, 17, 15, 0x3F - 0x26), + /* 0x26 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(17, 15, 18, 0, 0x39 - 0x2C), + /* 0x2C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x33 - 0x32), + /* 0x32 */ SCHEDULE_CMD_RET_NONE(), + /* 0x33 */ SCHEDULE_CMD_RET_TIME(18, 0, 6, 0, 4), + /* 0x39 */ SCHEDULE_CMD_RET_TIME(17, 15, 6, 0, 2), + /* 0x3F */ SCHEDULE_CMD_RET_TIME(16, 55, 17, 15, 11), + /* 0x45 */ SCHEDULE_CMD_RET_TIME(16, 50, 16, 55, 6), + /* 0x4B */ SCHEDULE_CMD_RET_TIME(15, 45, 15, 50, 5), + /* 0x51 */ SCHEDULE_CMD_RET_TIME(15, 25, 15, 45, 10), + /* 0x57 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0xB5 - 0x5B), + /* 0x5B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 45, 15, 50, 0xAF - 0x61), + /* 0x61 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 50, 16, 10, 0xA9 - 0x67), + /* 0x67 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 10, 16, 30, 0xA3 - 0x6D), + /* 0x6D */ SCHEDULE_CMD_CHECK_FLAG_S(0x4B, 0x10, 0x8A - 0x71), + /* 0x71 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 30, 16, 50, 0x84 - 0x77), + /* 0x77 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 50, 16, 55, 0x7E - 0x7D), + /* 0x7D */ SCHEDULE_CMD_RET_NONE(), + /* 0x7E */ SCHEDULE_CMD_RET_TIME(16, 50, 16, 55, 8), + /* 0x84 */ SCHEDULE_CMD_RET_TIME(16, 30, 16, 50, 13), + /* 0x8A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 30, 16, 50, 0x9D - 0x90), + /* 0x90 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 50, 16, 55, 0x97 - 0x96), + /* 0x96 */ SCHEDULE_CMD_RET_NONE(), + /* 0x97 */ SCHEDULE_CMD_RET_TIME(16, 50, 16, 55, 9), + /* 0x9D */ SCHEDULE_CMD_RET_TIME(16, 30, 16, 50, 14), + /* 0xA3 */ SCHEDULE_CMD_RET_TIME(16, 10, 16, 30, 3), + /* 0xA9 */ SCHEDULE_CMD_RET_TIME(15, 50, 16, 10, 12), + /* 0xAF */ SCHEDULE_CMD_RET_TIME(15, 45, 15, 50, 7), + /* 0xB5 */ SCHEDULE_CMD_RET_NONE(), + /* 0xB6 */ SCHEDULE_CMD_RET_NONE(), +}; + +static s32 D_80BF3318[] = { -1, -1, 3, 1, 3, 1, 2, 0, 3, 5, 0, 3, 1, 2, 4 }; + +static s32 D_80BF3354[] = { + 0x0E28B00C, + 0x10000000, +}; + +static s32 D_80BF335C[] = { + 0x09000000, 0x4B10001F, 0x170E28B1, 0x0C090000, 0x180E28B2, 0x0C090000, 0x170E28B3, 0x2D000111, 0x37020C09, + 0x00001000, 0x5610002F, 0x170E28B1, 0x0C090000, 0x180E28B5, 0x0C090000, 0x170E28B6, 0x0C090000, 0x180E28B7, + 0x0C090000, 0x170E28B8, 0x2D00010C, 0x09000011, 0x56101009, 0x0000180E, 0x29560C09, 0x0000170E, 0x29570C09, + 0x0000180E, 0x29580C09, 0x0000170E, 0x29592D00, 0x010C0900, 0x00121000, +}; + +static s32 D_80BF33E0[] = { + 0x0E28B90C, + 0x10000000, +}; + +static s32 D_80BF33E8[] = { + 0x0E28B40C, + 0x10000000, +}; + +static s32 D_80BF33F0[] = { + 0x0E295B0C, + 0x10000000, +}; + const ActorInit En_Ig_InitVars = { ACTOR_EN_IG, ACTORCAT_NPC, @@ -25,105 +101,955 @@ const ActorInit En_Ig_InitVars = { (ActorFunc)EnIg_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BF3418 = { - { 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, + }, { 28, 62, 0, { 0, 0, 0 } }, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80BF3444 = { - { 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_80BF3470 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_dai_Anim_0048B4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dai_Anim_0048B4, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dai_Anim_005100, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dai_Anim_005100, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dai_Anim_0010F8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dai_Anim_001E44, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dai_Anim_0014BC, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dai_Anim_003CAC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_dai_Anim_0040E0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dai_Anim_0040E0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, +}; -extern ColliderCylinderInit D_80BF3418; -extern ColliderSphereInit D_80BF3444; -extern CollisionCheckInfoInit2 D_80BF3470; +Actor* func_80BF1150(EnIg* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* foundActor = NULL; + Actor* temp_v0; -extern UNK_TYPE D_06008710; -extern UNK_TYPE D_0600C538; -extern UNK_TYPE D_060130D0; + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, actorCat, actorId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1150.s") + if (foundActor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1200.s") + if ((this != (EnIg*)foundActor) && (foundActor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1258.s") + temp_v0 = foundActor->next; + if (temp_v0 == NULL) { + foundActor = NULL; + break; + } + foundActor = temp_v0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1284.s") + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1354.s") +EnDoor* func_80BF1200(GlobalContext* globalCtx, s32 arg1) { + s32 phi_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF13E4.s") + switch (arg1) { + case 5: + case 6: + case 7: + case 9: + phi_a1 = 11; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF146C.s") + case 8: + phi_a1 = 15; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF14B0.s") + default: + phi_a1 = -1; + break; + } + return SubS_FindDoor(globalCtx, phi_a1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF15EC.s") +void func_80BF1258(EnIg* this) { + this->skelAnime.playSpeed = this->unk_3D4; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF16C8.s") +s32 func_80BF1284(EnIg* this, s32 arg1) { + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1744.s") + switch (arg1) { + case 0: + case 1: + if ((this->unk_3FC != 0) && (this->unk_3FC != 1)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF17BC.s") + case 2: + case 3: + if ((this->unk_3FC != 2) && (this->unk_3FC != 3)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1920.s") + default: + if (arg1 != this->unk_3FC) { + phi_v1 = true; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF19A0.s") + if (phi_v1) { + this->unk_3FC = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->unk_3D4 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1A60.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1AE0.s") +void func_80BF1354(EnIg* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider1); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + this->collider2.dim.worldSphere.radius = this->collider2.dim.modelSphere.radius * this->collider2.dim.scale; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1B40.s") +void func_80BF13E4(EnIg* this) { + if ((this->unk_3D0 & 0x100) && (DECR(this->unk_3F0) == 0)) { + this->unk_3F2++; + if (this->unk_3F2 >= 4) { + this->unk_3F0 = Rand_S16Offset(30, 30); + this->unk_3F2 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1C44.s") +Actor* func_80BF146C(EnIg* this, GlobalContext* globalCtx) { + Actor* retActor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1D78.s") + if (this->scheduleResult == 3) { + retActor = func_80BF1150(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AN); + } else { + retActor = &GET_PLAYER(globalCtx)->actor; + } + return retActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1DF4.s") +void func_80BF14B0(EnIg* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s32 pad2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF1FA8.s") + Math_Vec3f_Copy(&sp40, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->unk_3EA, Math_Vec3f_Yaw(&sp34, &sp40) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3EA = CLAMP(this->unk_3EA, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF219C.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2368.s") + if (this->unk_2A8->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_2A8)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_2A8->focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2400.s") + Math_ApproachS(&this->unk_3E8, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x2AA8); + this->unk_3E8 = CLAMP(this->unk_3E8, -0xE38, 0xE38); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2470.s") +void func_80BF15EC(EnIg* this) { + if ((this->unk_3D0 & 0x20) && (this->unk_2A8 != 0)) { + if (DECR(this->unk_3EE) == 0) { + func_80BF14B0(this); + this->unk_3D0 &= ~0x200; + this->unk_3D0 |= 0x80; + return; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF25E8.s") + if (this->unk_3D0 & 0x80) { + this->unk_3D0 &= ~0x80; + this->unk_3E4 = 0; + this->unk_3E6 = 0; + this->unk_3E8 = 0; + this->unk_3EA = 0; + this->unk_3EE = 20; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2890.s") + if (DECR(this->unk_3EE) == 0) { + this->unk_3D0 |= 0x200; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF293C.s") +s32 func_80BF16C8(EnIg* this, s16 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2A50.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_Ig/func_80BF2AF8.s") +s16 func_80BF1744(EnIg* this, s32 arg1) { + s16 cs = -1; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2BD4.s") + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + cs = this->actor.child->cutscene; + for (i = 0; i < arg1; i++) { + cs = ActorCutscene_GetAdditionalCutscene(cs); + } + } + return cs; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Init.s") +s32 func_80BF17BC(EnIg* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A; + s32 ret; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Destroy.s") + sp2A = func_80BF1744(this, 0); + ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Update.s") + switch (this->unk_3F6) { + case 0: + if (func_80BF16C8(this, sp2A)) { + case 2: + case 4: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), + this->actor.child); + } + this->unk_3F6++; + ret = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2EDC.s") + case 1: + case 3: + if (!(gSaveContext.save.weekEventReg[75] & 0x10) && (this->unk_3F6 == 3)) { + ActorCutscene_Stop(sp2A); + this->unk_3F6 = 5; + } else { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + } + this->unk_3F6++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF2EFC.s") + case 5: + ActorCutscene_Stop(sp2A); + this->unk_3F6++; + ret = true; + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/func_80BF302C.s") +s32* func_80BF1920(EnIg* this, GlobalContext* globalCtx) { + switch (this->scheduleResult) { + case 3: + this->unk_3F8 = func_80BF17BC; + return D_80BF335C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ig/EnIg_Draw.s") + case 4: + return D_80BF33F0; + + case 2: + case 11: + case 14: + return D_80BF33E0; + + case 10: + case 12: + return D_80BF3354; + + case 13: + return D_80BF33E8; + + default: + return NULL; + } +} + +s32 func_80BF19A0(EnIg* this, GlobalContext* globalCtx) { + s32 ret = false; + + if (this->unk_3D0 & 7) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_3D0, 0, 7); + this->unk_3F6 = 0; + this->unk_3F8 = NULL; + this->actor.child = this->unk_2A8; + this->unk_29C = func_80BF1920(this, globalCtx); + if ((this->scheduleResult != 2) && (this->scheduleResult != 3) && (this->scheduleResult != 4)) { + this->unk_3D0 |= 0x20; + } + this->actionFunc = func_80BF2BD4; + ret = true; + } + } + return ret; +} + +void func_80BF1A60(EnIg* this, GlobalContext* globalCtx) { + if (this->unk_3F4 == 0) { + func_80BF1284(this, 4); + this->unk_3F4++; + } else if ((this->unk_3F4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80BF1284(this, 5); + this->unk_3F4++; + } +} + +s32 func_80BF1AE0(EnIg* this, GlobalContext* globalCtx) { + switch (this->scheduleResult) { + case 3: + func_80BF1284(this, 0); + break; + + case 10: + case 11: + case 12: + case 13: + case 14: + func_80BF1284(this, 2); + break; + } + return true; +} + +s32 func_80BF1B40(EnIg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 temp = globalCtx->msgCtx.currentTextId; + s32 pad; + + if (player->stateFlags1 & 0xC40) { + this->unk_3D0 |= 0x400; + if (this->unk_3D2 != temp) { + if ((this->unk_3FC == 2) || (this->unk_3FC == 3)) { + func_80BF1284(this, 0); + } + + if ((temp == 0x28B0) || (temp == 0x28B7)) { + this->unk_18C = func_80BF1A60; + this->unk_3F4 = 0; + } + } + this->unk_3D2 = temp; + } else if (this->unk_3D0 & 0x400) { + this->unk_3D2 = 0; + this->unk_3D0 &= ~0x400; + if (1) {} + func_80BF1AE0(this, globalCtx); + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + return false; +} + +s32 func_80BF1C44(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2, s32 arg3, s32 arg4) { + u8 sp4F = ENIG_GET_FF(&this->actor); + Vec3s* sp48; + Vec3f sp3C; + Vec3f sp30; + Actor* sp2C; + s32 pad; + s32 sp24 = false; + + sp2C = func_80BF1150(this, globalCtx, arg3, arg4); + this->unk_274 = NULL; + + if (D_80BF3318[arg2->result] >= 0) { + this->unk_274 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80BF3318[arg2->result]); + } + + if ((sp2C != NULL) && (sp2C->update != NULL)) { + if (this->unk_274 != NULL) { + sp48 = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp3C, &sp48[this->unk_274->count - 2]); + Math_Vec3s_ToVec3f(&sp30, &sp48[this->unk_274->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); + sp24 = true; + } + } + return sp24; +} + +s32 func_80BF1D78(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 sp2C = 0; + + if (func_80BF1C44(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_AN)) { + func_80BF1284(this, 0); + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x20; + this->unk_3D0 |= 0x100; + sp2C = true; + } + return sp2C; +} + +s32 func_80BF1DF4(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp56 = SCHEDULE_TIME_NOW; + u8 sp55 = ENIG_GET_FF(&this->actor); + EnDoor* door; + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s32 pad; + s32 ret = false; + + this->unk_274 = NULL; + door = func_80BF1200(globalCtx, arg2->result); + + if (D_80BF3318[arg2->result] >= 0) { + this->unk_274 = SubS_GetAdditionalPath(globalCtx, sp55, D_80BF3318[arg2->result]); + } + + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if (this->unk_274 != NULL) { + sp4C = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp40, &sp4C[0]); + Math_Vec3s_ToVec3f(&sp34, &sp4C[1]); + Math_Vec3f_Copy(&this->unk_2B0, &sp40); + Math_Vec3f_Copy(&this->unk_2BC, &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, door->dyna.actor.shape.rot.y)) <= 0x4000) { + this->unk_2A4 = -75; + } else { + this->unk_2A4 = 75; + } + + this->unk_3E0 = arg2->time1 - arg2->time0; + this->unk_3E2 = sp56 - arg2->time0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_3D0 |= 0x100; + func_80BF1284(this, 3); + this->actor.gravity = 0.0f; + ret = true; + } + } + return ret; +} + +s32 func_80BF1FA8(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp2E = SCHEDULE_TIME_NOW; + u16 phi_v1; + u8 sp2B = ENIG_GET_FF(&this->actor); + s32 temp_t8; + s32 ret = false; + + this->unk_274 = NULL; + + if (D_80BF3318[arg2->result] >= 0) { + this->unk_274 = SubS_GetAdditionalPath(globalCtx, sp2B, D_80BF3318[arg2->result]); + } + + if ((this->unk_274 != NULL) && (this->unk_274->count < 3)) { + this->unk_274 = NULL; + } + + if (this->unk_274 != NULL) { + temp_t8 = this->scheduleResult; + if ((temp_t8 < 10) && (temp_t8 != 0) && (this->unk_3EC >= 0)) { + phi_v1 = sp2E; + } else { + phi_v1 = arg2->time0; + } + + if (arg2->time1 < phi_v1) { + this->unk_288 = (phi_v1 - arg2->time1) + 0xFFFF; + } else { + this->unk_288 = arg2->time1 - phi_v1; + } + + this->unk_294 = sp2E - phi_v1; + + phi_v1 = (this->unk_274->count - 2) & 0xFFFF; + + this->unk_28C = this->unk_288 / phi_v1; + this->unk_290 = (this->unk_294 / this->unk_28C) + 2; + + this->unk_3D0 &= ~0x8; + this->unk_3D0 &= ~0x10; + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 2); + this->actor.gravity = -1.0f; + ret = true; + } + return ret; +} + +s32 func_80BF219C(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u8 sp4F = ENIG_GET_FF(&this->actor); + Vec3f sp40; + Vec3f sp34; + Vec3s* sp30; + s32 pad; + s32 ret = false; + + this->unk_274 = NULL; + + if (D_80BF3318[arg2->result] >= 0) { + this->unk_274 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80BF3318[arg2->result]); + } + + if ((this->unk_274 != 0) && (this->unk_274->count >= 2)) { + sp30 = Lib_SegmentedToVirtual(this->unk_274->points); + Math_Vec3s_ToVec3f(&sp40, &sp30[this->unk_274->count - 1]); + Math_Vec3s_ToVec3f(&sp34, &sp30[this->unk_274->count - 2]); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp34, &sp40); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + Math_Vec3f_Copy(&this->actor.prevPos, &sp40); + + switch (arg2->result) { + case 2: + this->actor.home.rot.y = this->actor.world.rot.y; + this->actor.home.rot.y += 0x8000; + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 1); + break; + + case 4: + this->actor.world.rot.y += 0x8000; + this->actor.shape.rot.y = this->actor.world.rot.y; + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + this->unk_3D0 |= 0x100; + func_80BF1284(this, 8); + break; + } + ret = true; + } + return ret; +} + +s32 func_80BF2368(EnIg* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + this->actor.targetMode = 0; + this->unk_3D0 = 0; + this->actor.flags |= ACTOR_FLAG_1; + + switch (arg2->result) { + case 5: + case 6: + case 7: + case 8: + case 9: + ret = func_80BF1DF4(this, globalCtx, arg2); + break; + + case 10: + case 11: + case 12: + case 13: + case 14: + ret = func_80BF1FA8(this, globalCtx, arg2); + break; + + case 2: + case 4: + ret = func_80BF219C(this, globalCtx, arg2); + break; + + case 3: + ret = func_80BF1D78(this, globalCtx, arg2); + break; + } + return ret; +} + +s32 func_80BF2400(EnIg* this, GlobalContext* globalCtx) { + Vec3f sp2C; + Vec3f sp20; + + if ((this->unk_2A8 != NULL) && (this->unk_2A8->update != NULL)) { + Math_Vec3f_Copy(&sp2C, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp20, &this->actor.world.pos); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp20, &sp2C); + } + + return true; +} + +s32 func_80BF2470(EnIg* this, GlobalContext* globalCtx) { + EnDoor* door = func_80BF1200(globalCtx, this->scheduleResult); + Vec3f sp38; + f32 temp; + s32 pad; + + if (!SubS_InCsMode(globalCtx) && (this->unk_3EC != 0)) { + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if (((f32)this->unk_3E2 / this->unk_3E0) <= 0.9f) { + door->unk_1A7 = this->unk_2A4; + } else { + door->unk_1A7 = 0; + } + } + this->unk_3E2 = CLAMP(this->unk_3E2, 0, this->unk_3E0); + temp = Math_Vec3f_DistXZ(&this->unk_2B0, &this->unk_2BC) / this->unk_3E0; + sp38.x = 0.0f; + sp38.y = 0.0f; + sp38.z = this->unk_3E2 * temp; + Lib_Vec3f_TranslateAndRotateY(&this->unk_2B0, this->actor.world.rot.y, &sp38, &this->actor.world.pos); + this->unk_3E2 += this->unk_3EC; + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PIRATE_WALK); + } + } + return false; +} + +s32 func_80BF25E8(EnIg* this, GlobalContext* globalCtx) { + f32 sp7C[265]; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + s32 sp54 = 0; + s32 sp50 = 0; + s32 pad; + + func_8013AF00(sp7C, 3, this->unk_274->count + 3); + if (!(this->unk_3D0 & 8)) { + sp58 = gZeroVec3f; + func_8013B6B0(this->unk_274, &this->unk_284, &this->unk_294, this->unk_28C, this->unk_288, &this->unk_290, sp7C, + &sp58, this->unk_3EC); + func_8013B878(globalCtx, this->unk_274, this->unk_290, &sp58); + this->actor.world.pos.y = sp58.y; + this->unk_3D0 |= 8; + } else { + sp58 = this->unk_278; + } + + this->actor.world.pos.x = sp58.x; + this->actor.world.pos.z = sp58.z; + + if (SubS_InCsMode(globalCtx)) { + sp54 = this->unk_294; + sp50 = this->unk_290; + sp58 = this->actor.world.pos; + } + + this->unk_278 = gZeroVec3f; + + if (func_8013B6B0(this->unk_274, &this->unk_284, &this->unk_294, this->unk_28C, this->unk_288, &this->unk_290, sp7C, + &this->unk_278, this->unk_3EC)) { + this->unk_3D0 |= 0x10; + } else { + sp70 = this->actor.world.pos; + sp64 = this->unk_278; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); + } + + if (SubS_InCsMode(globalCtx)) { + this->unk_294 = sp54; + this->unk_290 = sp50; + this->unk_278 = sp58; + } else if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PIRATE_WALK); + } + return false; +} + +s32 func_80BF2890(EnIg* this, GlobalContext* globalCtx) { + if ((this->unk_3D0 & 0x100) && (this->unk_3F2 == 2)) { + this->unk_3D0 &= ~0x100; + } + + if (!(this->unk_3D0 & 0x100) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_408 != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SNORE1); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SNORE2); + } + this->unk_408 ^= 1; + } + return true; +} + +s32 func_80BF293C(EnIg* this, GlobalContext* globalCtx) { + if (this->actor.world.rot.y != this->actor.home.rot.y) { + if ((this->actor.world.rot.y / 182) != (this->actor.home.rot.y / 182)) { + Math_ApproachS(&this->actor.world.rot.y, this->actor.home.rot.y, 3, 0x2AA8); + } else { + this->actor.world.rot.y = this->actor.home.rot.y; + func_80BF1284(this, 7); + } + } else if ((this->unk_3FC == 7) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + func_80BF1284(this, 9); + } + return true; +} + +void func_80BF2A50(EnIg* this, GlobalContext* globalCtx) { + switch (this->scheduleResult) { + case 10: + case 11: + case 12: + case 13: + case 14: + func_80BF25E8(this, globalCtx); + break; + + case 5: + case 6: + case 7: + case 8: + case 9: + func_80BF2470(this, globalCtx); + break; + + case 2: + func_80BF293C(this, globalCtx); + break; + + case 3: + func_80BF2400(this, globalCtx); + break; + + case 4: + func_80BF2890(this, globalCtx); + break; + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80BF2AF8(EnIg* this, GlobalContext* globalCtx) { + ScheduleResult sp20; + + this->unk_3EC = REG(15) + ((void)0, gSaveContext.save.daySpeed); + + if (!Schedule_RunScript(globalCtx, D_80BF3260, &sp20) || + ((this->scheduleResult != sp20.result) && !func_80BF2368(this, globalCtx, &sp20))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp20.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_2A8 = func_80BF146C(this, globalCtx); + this->scheduleResult = sp20.result; + func_80BF2A50(this, globalCtx); +} + +void func_80BF2BD4(EnIg* this, GlobalContext* globalCtx) { + s16 yaw; + Vec3f sp38; + Vec3f sp2C; + + if (func_8010BF58(&this->actor, globalCtx, this->unk_29C, this->unk_3F8, &this->unk_2A0)) { + SubS_UpdateFlags(&this->unk_3D0, 3, 7); + this->unk_3D0 &= ~0x20; + this->unk_3D0 |= 0x200; + this->unk_3EE = 20; + this->unk_2A0 = 0; + this->actionFunc = func_80BF2AF8; + } else if (((this->scheduleResult != 2) && (this->scheduleResult != 4)) && + ((this->unk_2A8 != NULL) && (this->unk_2A8->update != NULL))) { + Math_Vec3f_Copy(&sp38, &this->unk_2A8->world.pos); + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + yaw = Math_Vec3f_Yaw(&sp2C, &sp38); + Math_ApproachS(&this->actor.shape.rot.y, yaw, 4, 0x2AA8); + } +} + +void EnIg_Init(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dai_Skel_0130D0, NULL, this->jointTable, this->morphTable, + 19); + this->unk_3FC = -1; + func_80BF1284(this, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); + Collider_InitAndSetSphere(globalCtx, &this->collider2, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->scheduleResult = 0; + this->actor.gravity = 0.0f; + this->actionFunc = func_80BF2AF8; + this->actionFunc(this, globalCtx); +} + +void EnIg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroySphere(globalCtx, &this->collider2); +} + +void EnIg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnIg* this = THIS; + + func_80BF19A0(this, globalCtx); + + this->actionFunc(this, globalCtx); + + func_80BF1B40(this, globalCtx); + + if (this->scheduleResult != 0) { + func_80BF1258(this); + func_80BF13E4(this); + func_80BF15EC(this); + func_8013C964(&this->actor, globalCtx, 60.0f, 30.0f, EXCH_ITEM_NONE, this->unk_3D0 & 7); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + func_80BF1354(this, globalCtx); + } +} + +s32 EnIg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnIg* this = THIS; + + if (limbIndex == 10) { + *dList = NULL; + } + return false; +} + +void EnIg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + static Vec3f D_80BF351C = { 1800.0f, -2000.0f, 0.0f }; + static Vec3f D_80BF3528 = { 0.0f, 0.0f, 0.0f }; + s32 pad; + EnIg* this = THIS; + Vec3f sp2C; + + if (limbIndex == 11) { + Matrix_MultVec3f(&D_80BF3528, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + + gSPDisplayList((*gfx)++, object_dai_DL_008710); + gSPDisplayList((*gfx)++, object_dai_DL_0087B8); + } + + if (limbIndex == 12) { + gSPDisplayList((*gfx)++, object_dai_DL_0089D8); + } + + if (limbIndex == 9) { + gSPDisplayList((*gfx)++, object_dai_DL_008B00); + Matrix_MultVec3f(&D_80BF351C, &sp2C); + Math_Vec3f_ToVec3s(&this->collider2.dim.worldSphere.center, &sp2C); + } + + if (limbIndex == 10) { + Matrix_Get(&this->unk_190); + } +} + +void EnIg_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { + EnIg* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->unk_3D0 & 0x200)) { + if (this->unk_3D0 & 0x80) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + overrideRot = false; + stepRot = false; + } + + if (limbIndex == 9) { + SubS_UpdateLimb(this->unk_3E8 + 0x4000, this->unk_3EA + this->actor.shape.rot.y + 0x4000, &this->unk_2D4, + &this->unk_2E6, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_2D4.x, this->unk_2D4.y, this->unk_2D4.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_2E6.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2E6.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2E6.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnIg_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80BF3534[] = { + object_dai_Tex_0107B0, object_dai_Tex_010FB0, object_dai_Tex_0117B0, + object_dai_Tex_011FB0, object_dai_Tex_0127B0, + }; + s32 pad; + EnIg* this = THIS; + + if (this->scheduleResult != 0) { + func_8012C28C(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BF3534[this->unk_3F2])); + + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnIg_OverrideLimbDraw, EnIg_PostLimbDraw, + EnIg_TransformLimbDraw, &this->actor, POLY_OPA_DISP); + Matrix_Put(&this->unk_190); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_dai_DL_00C538); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Ig/z_en_ig.h b/src/overlays/actors/ovl_En_Ig/z_en_ig.h index 19050087e..21abb08ac 100644 --- a/src/overlays/actors/ovl_En_Ig/z_en_ig.h +++ b/src/overlays/actors/ovl_En_Ig/z_en_ig.h @@ -6,12 +6,60 @@ struct EnIg; typedef void (*EnIgActionFunc)(struct EnIg*, GlobalContext*); +typedef s32 (*EnIgUnkFunc)(struct EnIg*, GlobalContext*); +typedef void (*EnIgUnkFunc2)(struct EnIg*, GlobalContext*); + +#define ENIG_GET_FF(thisx) ((thisx)->params & 0xFF) typedef struct EnIg { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnIgActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x280]; + /* 0x018C */ EnIgUnkFunc2 unk_18C; + /* 0x0190 */ MtxF unk_190; + /* 0x01D0 */ ColliderCylinder collider1; + /* 0x021C */ ColliderSphere collider2; + /* 0x0274 */ Path* unk_274; + /* 0x0278 */ Vec3f unk_278; + /* 0x0284 */ f32 unk_284; + /* 0x0288 */ s32 unk_288; + /* 0x028C */ s32 unk_28C; + /* 0x0290 */ s32 unk_290; + /* 0x0294 */ s32 unk_294; + /* 0x0298 */ u8 scheduleResult; + /* 0x029C */ s32* unk_29C; + /* 0x02A0 */ s32 unk_2A0; + /* 0x02A4 */ s8 unk_2A4; + /* 0x02A8 */ Actor* unk_2A8; + /* 0x02AC */ UNK_TYPE1 unk2AC[0x4]; + /* 0x02B0 */ Vec3f unk_2B0; + /* 0x02BC */ Vec3f unk_2BC; + /* 0x02C8 */ UNK_TYPE1 unk2C8[0xC]; + /* 0x02D4 */ Vec3f unk_2D4; + /* 0x02E0 */ UNK_TYPE1 unk2E0[0x6]; + /* 0x02E6 */ Vec3s unk_2E6; + /* 0x02EC */ Vec3s jointTable[19]; + /* 0x035E */ Vec3s morphTable[19]; + /* 0x03D0 */ u16 unk_3D0; + /* 0x03D2 */ u16 unk_3D2; + /* 0x03D4 */ f32 unk_3D4; + /* 0x03D8 */ UNK_TYPE1 unk3D8[0x8]; + /* 0x03E0 */ s16 unk_3E0; + /* 0x03E2 */ s16 unk_3E2; + /* 0x03E4 */ s16 unk_3E4; + /* 0x03E6 */ s16 unk_3E6; + /* 0x03E8 */ s16 unk_3E8; + /* 0x03EA */ s16 unk_3EA; + /* 0x03EC */ s16 unk_3EC; + /* 0x03EE */ s16 unk_3EE; + /* 0x03F0 */ s16 unk_3F0; + /* 0x03F2 */ s16 unk_3F2; + /* 0x03F4 */ s16 unk_3F4; + /* 0x03F6 */ s16 unk_3F6; + /* 0x03F8 */ EnIgUnkFunc unk_3F8; + /* 0x03FC */ s32 unk_3FC; + /* 0x0400 */ UNK_TYPE1 unk400[0x8]; + /* 0x0408 */ s32 unk_408; } EnIg; // size = 0x40C extern const ActorInit En_Ig_InitVars; diff --git a/src/overlays/actors/ovl_En_Ik/z_en_ik.c b/src/overlays/actors/ovl_En_Ik/z_en_ik.c index 4b61b88ed..b782b82a3 100644 --- a/src/overlays/actors/ovl_En_Ik/z_en_ik.c +++ b/src/overlays/actors/ovl_En_Ik/z_en_ik.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ik.c + * Overlay: ovl_En_Ik + * Description: Iron Knuckle + */ + #include "z_en_ik.h" -#define FLAGS 0x00000405 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnIk*)thisx) 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 fe421558f..ef4db6f9e 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -1,29 +1,17 @@ /* - * File z_en_in.c + * File: z_en_in.c * Overlay: ovl_En_In * Description: Gorman Bros */ #include "z_en_in.h" +#include "objects/object_in/object_in.h" +#include "overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnIn*)thisx) -#define SET_FLAGS_FINISH_RACE \ - { \ - gSaveContext.weekEventReg[92] &= (u8) ~(1 | 2 | 4); \ - gSaveContext.weekEventReg[92] = \ - gSaveContext.weekEventReg[92] | (u8)(gSaveContext.weekEventReg[92] & ~(1 | 2 | 4)); \ - } - -#define SET_FLAGS_START_RACE \ - { \ - gSaveContext.weekEventReg[92] &= (u8) ~(1 | 2 | 4); \ - gSaveContext.weekEventReg[92] = \ - gSaveContext.weekEventReg[92] | (u8)((gSaveContext.weekEventReg[92] & ~(1 | 2 | 4)) | 1); \ - } - void EnIn_Init(Actor* thisx, GlobalContext* globalCtx); void EnIn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnIn_Update(Actor* thisx, GlobalContext* globalCtx); @@ -46,54 +34,6 @@ const ActorInit En_In_InitVars = { (ActorFunc)EnIn_Draw, }; -extern FlexSkeletonHeader D_06014EA8; -extern AnimationHeader D_06015E38; -extern AnimationHeader D_06016484; -extern AnimationHeader D_06016A60; -extern AnimationHeader D_060170DC; -extern AnimationHeader D_060177AC; -extern AnimationHeader D_06018240; -extern AnimationHeader D_060187C8; -extern AnimationHeader D_060198A8; -extern Gfx D_06007A70[]; -extern Gfx D_06007C48[]; -extern Gfx D_0601C528[]; -extern AnimatedMaterial D_06001C30; -extern UNK_TYPE D_06003520; -extern UNK_TYPE D_060035E0; -extern UNK_TYPE D_06004820; -extern UNK_TYPE D_06004C20; -extern UNK_TYPE D_060043E0; -extern AnimationHeader D_06001D10; -extern AnimationHeader D_06014F8C; -extern AnimationHeader D_06000CB0; -extern AnimationHeader D_060003B4; -extern AnimationHeader D_06001BE0; -extern AnimationHeader D_06015918; -extern AnimationHeader D_0601C0B0; -extern AnimationHeader D_0601A140; -extern AnimationHeader D_0601B904; -extern AnimationHeader D_0601B3C4; -extern AnimationHeader D_06019EB4; -extern Gfx D_060137A0[]; -extern Gfx D_06014420[]; -extern Gfx D_06014040[]; -extern Gfx D_06013670[]; -extern Gfx D_06014AE0[]; -extern Gfx D_06012A78[]; -extern Gfx D_06013DE0[]; -extern Gfx D_060138D0[]; -extern Gfx D_06013540[]; -extern Gfx D_06012DF8[]; -extern Gfx D_060145D8[]; -extern Gfx D_06014860[]; -extern Gfx D_06014710[]; -extern Gfx D_06013A00[]; -extern Gfx D_06013F10[]; -extern Gfx D_06014C30[]; -extern Gfx D_060149A8[]; -extern Gfx D_06013440[]; - static ColliderCylinderInit sCylinderInit = { { COLTYPE_HIT0, @@ -178,17 +118,32 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06001D10, 1.0f, 0, -1, 0, 0 }, { &D_06001D10, 1.0f, 0, -1, 0, -4 }, { &D_06014F8C, 1.0f, 0, -1, 0, 0 }, - { &D_06014F8C, 1.0f, 0, -1, 0, -4 }, { &D_06000CB0, 1.0f, 0, -1, 0, -4 }, { &D_060003B4, 1.0f, 0, -1, 0, -4 }, - { &D_06001BE0, 1.0f, 0, -1, 0, -4 }, { &D_06015918, 1.0f, 0, -1, 0, -4 }, { &D_0601C0B0, 1.0f, 0, -1, 0, 0 }, - { &D_0601C0B0, 1.0f, 0, -1, 0, -4 }, { &D_0601A140, 1.0f, 0, -1, 0, 0 }, { &D_0601A140, 1.0f, 0, -1, 0, -4 }, - { &D_0601B904, 1.0f, 0, -1, 0, 0 }, { &D_0601B904, 1.0f, 0, -1, 0, -4 }, { &D_0601B3C4, 1.0f, 0, -1, 0, 0 }, - { &D_0601B3C4, 0.0f, 0, -1, 2, 0 }, { &D_0601B3C4, 1.0f, 0, -1, 0, -4 }, { &D_06019EB4, 1.0f, 0, -1, 2, -4 }, +static AnimationInfoS sAnimations[] = { + { &object_in_Anim_001D10, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_001D10, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_014F8C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_014F8C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_000CB0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_0003B4, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_001BE0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_015918, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_01C0B0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_01C0B0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_01A140, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_01A140, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_01B904, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_01B904, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_01B3C4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_in_Anim_01B3C4, 0.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_in_Anim_01B3C4, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_in_Anim_019EB4, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, }; -static s16 D_808F6C0C[] = { - 4000, 4, 1, 3, 6000, 4, 1, 6, 4000, 4, 1, 3, 6000, 4, 1, 6, +static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, }; s32 func_808F30B0(SkelAnime* skelAnime, s16 animIndex) { @@ -199,11 +154,11 @@ s32 func_808F30B0(SkelAnime* skelAnime, s16 animIndex) { ret = true; frameCount = sAnimations[animIndex].frameCount; if (frameCount < 0) { - frameCount = Animation_GetLastFrame(sAnimations[animIndex].animationSeg); + frameCount = Animation_GetLastFrame(sAnimations[animIndex].animation); } - Animation_Change(skelAnime, sAnimations[animIndex].animationSeg, sAnimations[animIndex].playbackSpeed, - sAnimations[animIndex].frame, frameCount, sAnimations[animIndex].mode, - sAnimations[animIndex].transitionRate); + Animation_Change(skelAnime, sAnimations[animIndex].animation, sAnimations[animIndex].playSpeed, + sAnimations[animIndex].startFrame, frameCount, sAnimations[animIndex].mode, + sAnimations[animIndex].morphFrames); } return ret; } @@ -213,14 +168,15 @@ s32 func_808F3178(EnIn* this, GlobalContext* globalCtx) { u8 prevUnk261 = this->unk261; u8 tmp; - this->unk260 = tmp = func_8013DB90(globalCtx, &this->unk248, -6.0f); - if (this->unk260 != 0 && prevUnk260 == 0 && tmp & 0xFF) { - Audio_PlayActorSound2(&this->actor, 0x802); + this->unk260 = tmp = SubS_IsFloorAbove(globalCtx, &this->unk248, -6.0f); + if (this->unk260 != 0 && prevUnk260 == 0 && tmp) { + Actor_PlaySfxAtPos(&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) { - Audio_PlayActorSound2(&this->actor, 0x802); + this->unk261 = tmp = SubS_IsFloorAbove(globalCtx, &this->unk254, -6.0f); + if (this->unk261 != 0 && prevUnk261 == 0 && tmp) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_CONCRETE); } + return 0; } @@ -258,46 +214,45 @@ s32 func_808F3334(EnIn* this, GlobalContext* globalCtx) { if (this->colliderJntSph.base.atFlags & AT_BOUNCED) { return 0; } - Audio_PlayActorSound2(&player->actor, 0x83E); + Actor_PlaySfxAtPos(&player->actor, NA_SE_PL_BODY_HIT); func_800B8D98(globalCtx, &this->actor, 3.0f, this->actor.yawTowardsPlayer, 6.0f); } return 1; } s32 func_808F33B8(void) { - s32 ret; + s32 ret = (((gSaveContext.save.day == 1) && + ((gSaveContext.save.time >= CLOCK_TIME(5, 30)) && (gSaveContext.save.time <= CLOCK_TIME(6, 0)))) || + (gSaveContext.save.day >= 2)) && + !(gSaveContext.save.weekEventReg[22] & 1); - if (((ret = gSaveContext.day == 1) && (ret = gSaveContext.time >= 0x3AAA) && (ret = gSaveContext.time <= 0x4000)) || - (ret = gSaveContext.day >= 2)) { - ret = (gSaveContext.weekEventReg[22] & 1) == 0; - } return ret; } void func_808F3414(EnIn* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp30; + Vec3f point; if (this->unk23D == 0) { this->unk494 = SkelAnime_Update(&this->skelAnime); } - if (func_8013D5E8(this->actor.shape.rot.y, 0x2710, 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, &this->actor.shape, &this->unk352, &this->unk358, &this->unk35E, - D_808F6C0C); + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x2710, this->actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->actor.focus.pos, &this->actor.shape.rot, &this->turnTarget, &this->headRot, + &this->torsoRot, &sTurnOptions); } else { - Math_SmoothStepToS(&this->unk352, 0, 4, 1000, 1); - Math_SmoothStepToS(&this->unk354, 0, 4, 1000, 1); - Math_SmoothStepToS(&this->unk358, 0, 4, 1000, 1); - Math_SmoothStepToS(&this->unk35A, 0, 4, 1000, 1); - Math_SmoothStepToS(&this->unk35E, 0, 4, 1000, 1); - Math_SmoothStepToS(&this->unk360, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1); } func_808F322C(this, 3); func_808F3178(this, globalCtx); - func_8013D9C8(globalCtx, this->unk376, this->unk39E, 20); + SubS_FillLimbRotTables(globalCtx, this->unk376, this->unk39E, ARRAY_COUNT(this->unk376)); } void func_808F35AC(EnIn* this, GlobalContext* globalCtx) { @@ -330,11 +285,11 @@ void func_808F3618(EnIn* this, GlobalContext* globalCtx) { void func_808F3690(EnIn* this, GlobalContext* globalCtx) { s16 sp36; - Vec3f sp28; // unsure if Vec3f, but it is probably size 0xC + Vec3f sp28; Math_SmoothStepToF(&this->actor.speedXZ, 1.0f, 0.4f, 1000.0f, 0.0f); sp36 = this->actor.speedXZ * 400.0f; - if (func_8013D68C(this->path, this->unk244, &sp28) && func_8013D768(&this->actor, &sp28, sp36)) { + if (SubS_CopyPointFromPath(this->path, this->unk244, &sp28) && SubS_MoveActorToPoint(&this->actor, &sp28, sp36)) { this->unk244++; if (this->unk244 >= this->path->count) { this->unk244 = 0; @@ -343,25 +298,28 @@ void func_808F3690(EnIn* this, GlobalContext* globalCtx) { } void func_808F374C(EnIn* this, GlobalContext* globalCtx) { - AnimationHeader* animations[] = { &D_06015E38, &D_06016A60, &D_060177AC, &D_06016484, - &D_060170DC, &D_06018240, &D_060187C8, &D_060198A8 }; + AnimationHeader* sAnimations[] = { + &object_in_Anim_015E38, &object_in_Anim_016A60, &object_in_Anim_0177AC, &object_in_Anim_016484, + &object_in_Anim_0170DC, &object_in_Anim_018240, &object_in_Anim_0187C8, &object_in_Anim_0198A8, + }; - if (this->skelAnime.animation == &D_06016484 || this->skelAnime.animation == &D_060170DC) { + if (this->skelAnime.animation == &object_in_Anim_016484 || this->skelAnime.animation == &object_in_Anim_0170DC) { if (Animation_OnFrame(&this->skelAnime, 8.0f)) { func_8019F88C(&this->actor.projectedPos, NA_SE_VO_IN_LASH_0, 2); if (Rand_ZeroOne() < 0.3f) { - func_8019F1C0(&this->actor.projectedPos, NA_SE_IT_INGO_HORSE_NEIGH); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_IT_INGO_HORSE_NEIGH); } - func_8019F1C0(&this->actor.projectedPos, NA_SE_IT_LASH); + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_IT_LASH); } } - if (this->skelAnime.animation == &D_060198A8 && Animation_OnFrame(&this->skelAnime, 20.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_CRY_0); + if (this->skelAnime.animation == &object_in_Anim_0198A8 && Animation_OnFrame(&this->skelAnime, 20.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_IN_CRY_0); } if (SkelAnime_Update(&this->skelAnime)) { - this->unk486 = this->unk488 %= 8; - Animation_Change(&this->skelAnime, animations[this->unk488], 1.0f, 0.0f, - Animation_GetLastFrame(animations[this->unk488]), 2, -10.0f); + this->unk488 %= ARRAY_COUNT(sAnimations); + this->unk486 = this->unk488; + Animation_Change(&this->skelAnime, sAnimations[this->unk488], 1.0f, 0.0f, + Animation_GetLastFrame(sAnimations[this->unk488]), 2, -10.0f); } } @@ -369,7 +327,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; } @@ -378,11 +336,11 @@ void func_808F38F8(EnIn* this, GlobalContext* globalCtx) { } void func_808F395C(EnIn* this, GlobalContext* globalCtx) { - if (this->unk4B0 == 0) { + if (this->unk4B0 == RACE_FLAG_END) { this->actionFunc = func_808F5A94; } - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; this->actionFunc = func_808F5A34; this->unk48C = 1; } else { @@ -393,44 +351,44 @@ void func_808F395C(EnIn* this, GlobalContext* globalCtx) { void func_808F39DC(EnIn* this, GlobalContext* globalCtx) { u16 textId = 0; - if (gSaveContext.day != 3) { - switch (gSaveContext.weekEventReg[92] & (1 | 2 | 4)) { - case 2: + if (gSaveContext.save.day != 3) { + switch (GET_RACE_FLAGS) { + case RACE_FLAG_2: textId = 0x347A; break; - case 3: + case RACE_FLAG_3: textId = 0x3476; break; } - SET_FLAGS_FINISH_RACE; + SET_RACE_FLAGS(RACE_FLAG_END); } else { - switch (gSaveContext.weekEventReg[92] & (1 | 2 | 4)) { - case 2: + switch (GET_RACE_FLAGS) { + case RACE_FLAG_2: textId = 0x349D; break; - case 3: + case RACE_FLAG_3: textId = 0x3499; break; } - SET_FLAGS_FINISH_RACE; + SET_RACE_FLAGS(RACE_FLAG_END); } - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; this->actor.textId = textId; this->actionFunc = func_808F395C; - if (this->unk4B0 == 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_LOST); + if (this->unk4B0 == RACE_FLAG_2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_IN_LOST); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_JOY0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_IN_JOY0); } } void func_808F3AD4(EnIn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; this->unk48C = 1; this->actionFunc = func_808F5A94; } else { - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -439,22 +397,22 @@ void func_808F3B40(EnIn* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; this->actionFunc = func_808F3AD4; - textId = gSaveContext.day != 3 ? 0x3481 : 0x34A4; + textId = gSaveContext.save.day != 3 ? 0x3481 : 0x34A4; this->actor.textId = textId; } else { - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); } } void func_808F3BD4(EnIn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; this->unk48C = 1; this->actionFunc = func_808F5A94; } else { - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -463,22 +421,22 @@ void func_808F3C40(EnIn* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; this->actionFunc = func_808F3BD4; - textId = gSaveContext.day != 3 ? 0x346A : 0x3492; + textId = gSaveContext.save.day != 3 ? 0x346A : 0x3492; this->actor.textId = textId; } else { - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); } } void func_808F3CD4(EnIn* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; this->unk48C = 1; this->actionFunc = func_808F5A94; } else { - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -488,21 +446,21 @@ void func_808F3D40(EnIn* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; this->actionFunc = func_808F3CD4; - textId = gSaveContext.day != 3 ? 0x347D : 0x34A0; + textId = gSaveContext.save.day != 3 ? 0x347D : 0x34A0; this->actor.textId = textId; - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; } else { - func_800B8A1C(&this->actor, globalCtx, 0x81, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_GARO, 500.0f, 100.0f); } } u16 func_808F3DD4(GlobalContext* globalCtx, EnIn* this, u32 arg2) { u16 textId = 0; - if (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADERS_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADER) { s32 requiredScopeTemp; - if (!(gSaveContext.weekEventReg[63] & 0x40)) { + if (!(gSaveContext.save.weekEventReg[63] & 0x40)) { return 0x34A9; } else if (this->unk4AC & 8) { return 0x34B1; @@ -512,40 +470,43 @@ u16 func_808F3DD4(GlobalContext* globalCtx, EnIn* this, u32 arg2) { } else { switch (arg2) { case 0: - if ((gSaveContext.playerForm == 2) || (gSaveContext.playerForm == 1)) { + if ((gSaveContext.save.playerForm == PLAYER_FORM_ZORA) || + (gSaveContext.save.playerForm == PLAYER_FORM_GORON)) { textId = 0x345C; - } else if (gSaveContext.playerForm == 3) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { textId = 0x3460; - } else if (!(gSaveContext.weekEventReg[15] & 8)) { + } else if (!(gSaveContext.save.weekEventReg[15] & 8)) { textId = 0x3458; } else { textId = 0x345B; } break; case 1: - if (!(gSaveContext.weekEventReg[15] & 0x10)) { + if (!(gSaveContext.save.weekEventReg[15] & 0x10)) { textId = 0x3463; } else { textId = 0x346B; } break; case 3: - if (gSaveContext.playerForm == 3) { + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { textId = 0x3485; - } else if (gSaveContext.playerForm == 2 || gSaveContext.playerForm == 1) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA || + gSaveContext.save.playerForm == PLAYER_FORM_GORON) { textId = 0x3484; - } else if (!(gSaveContext.weekEventReg[56] & 4)) { + } else if (!(gSaveContext.save.weekEventReg[56] & 4)) { textId = 0x346D; } else { textId = 0x3482; } break; case 4: - if (gSaveContext.playerForm == 2 || gSaveContext.playerForm == 1) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA || + gSaveContext.save.playerForm == PLAYER_FORM_GORON) { textId = 0x348A; - } else if (gSaveContext.playerForm == 3) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { textId = 0x348B; - } else if (!(gSaveContext.weekEventReg[16] & 1)) { + } else if (!(gSaveContext.save.weekEventReg[16] & 1)) { textId = 0x3486; } else { textId = 0x3489; @@ -554,18 +515,19 @@ u16 func_808F3DD4(GlobalContext* globalCtx, EnIn* this, u32 arg2) { case 5: if (func_808F33B8()) { textId = 0x34B3; - } else if (!(gSaveContext.weekEventReg[16] & 2)) { + } else if (!(gSaveContext.save.weekEventReg[16] & 2)) { textId = 0x348E; } else { textId = 0x3493; } break; case 7: - if (gSaveContext.playerForm == 3) { + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { textId = 0x34A8; - } else if (gSaveContext.playerForm == 2 || gSaveContext.playerForm == 1) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA || + gSaveContext.save.playerForm == PLAYER_FORM_GORON) { textId = 0x34A7; - } else if (!(gSaveContext.weekEventReg[16] & 4)) { + } else if (!(gSaveContext.save.weekEventReg[16] & 4)) { textId = 0x3495; } else { textId = 0x34A5; @@ -604,7 +566,7 @@ void func_808F4054(GlobalContext* globalCtx, EnIn* this, s32 arg2, u16 textId) { } void func_808F4108(EnIn* this, GlobalContext* globalCtx, u16 textId) { - func_800B86C8(&this->actor, globalCtx, &this->unk4A4->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->unk4A4->actor); this->actor.textId = 0; this->unk4A4->actor.textId = textId; this->unk4A4->unk48C = 2; @@ -616,9 +578,9 @@ s32 func_808F4150(GlobalContext* globalCtx, EnIn* this, s32 arg2, MessageContext if (msgCtx->choiceIndex == 0) { func_8019F208(); - if (gSaveContext.rupees >= globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees >= globalCtx->msgCtx.unk1206C) { func_801159EC(-globalCtx->msgCtx.unk1206C); - if (!(gSaveContext.weekEventReg[57] & 1)) { + if (!(gSaveContext.save.weekEventReg[57] & 1)) { func_808F4108(this, globalCtx, 0x3474); } else if (this->unk4AC & 8) { func_808F4108(this, globalCtx, 0x3475); @@ -642,9 +604,9 @@ s32 func_808F4270(GlobalContext* globalCtx, EnIn* this, s32 arg2, MessageContext if (msgCtx->choiceIndex == 0) { func_8019F208(); - if (gSaveContext.rupees >= fee) { + if (gSaveContext.save.playerData.rupees >= fee) { func_801159EC(-fee); - if (!(gSaveContext.weekEventReg[57] & 1)) { + if (!(gSaveContext.save.weekEventReg[57] & 1)) { if (arg4 != 0) { func_800E8EA0(globalCtx, &this->actor, 0x3474); } else { @@ -675,7 +637,7 @@ s32 func_808F4270(GlobalContext* globalCtx, EnIn* this, s32 arg2, MessageContext s32 func_808F43E0(EnIn* this) { this->unk48C = 0; this->actor.textId = 0; - SET_FLAGS_FINISH_RACE; + SET_RACE_FLAGS(RACE_FLAG_END); return 0; } @@ -692,7 +654,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x34A9: func_808F4108(this, globalCtx, 0x34AA); - gSaveContext.weekEventReg[63] |= 0x40; + gSaveContext.save.weekEventReg[63] |= 0x40; ret = false; break; case 0x34AA: @@ -723,7 +685,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0: switch (textId) { case 0x3458: - gSaveContext.weekEventReg[15] |= 8; + gSaveContext.save.weekEventReg[15] |= 8; func_800E8EA0(globalCtx, &this->actor, 0x3459); ret = false; break; @@ -772,7 +734,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 1: switch (textId) { case 0x3463: - gSaveContext.weekEventReg[15] |= 16; + gSaveContext.save.weekEventReg[15] |= 0x10; func_800E8EA0(globalCtx, &this->actor, 0x3464); ret = false; break; @@ -787,10 +749,10 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0x3466: if (msgCtx->choiceIndex == 0) { func_8019F208(); - if (gSaveContext.rupees >= globalCtx->msgCtx.unk1206C) { - if (func_80114E90()) { + if (gSaveContext.save.playerData.rupees >= globalCtx->msgCtx.unk1206C) { + if (Interface_HasEmptyBottle()) { this->actionFunc = func_808F3C40; - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); func_801159EC(-globalCtx->msgCtx.unk1206C); ret = true; } else { @@ -848,21 +810,21 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x3472: func_808F43E0(this); - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; func_80151BB4(globalCtx, 0x11); ret = true; break; case 0x3473: - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; func_80151BB4(globalCtx, 0x11); break; case 0x3475: - SET_FLAGS_START_RACE; - func_800FD750(0x40); + SET_RACE_FLAGS(RACE_FLAG_START); + func_800FD750(NA_BGM_HORSE); globalCtx->nextEntranceIndex = 0xCE50; globalCtx->unk_1887F = 5; globalCtx->sceneLoadFlag = 0x14; - gSaveContext.weekEventReg[57] |= 1; + gSaveContext.save.weekEventReg[57] |= 1; break; case 0x3478: if (msgCtx->choiceIndex == 0) { @@ -870,14 +832,14 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { ret = false; } else { func_8019F230(); - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; func_808F4108(this, globalCtx, 0x3479); ret = false; } break; case 0x347B: func_808F4108(this, globalCtx, 0x347C); - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; ret = false; break; } @@ -886,8 +848,8 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { switch (textId) { case 0x346D: func_808F4108(this, globalCtx, 0x346E); - gSaveContext.weekEventReg[56] |= 4; - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 4; + gSaveContext.save.weekEventReg[56] |= 8; ret = false; break; case 0x346F: @@ -896,7 +858,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x3482: func_808F4108(this, globalCtx, 0x3483); - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 8; ret = false; break; case 0x3484: @@ -916,7 +878,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { ret = false; break; case 0x3477: - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 8; func_808F4108(this, globalCtx, 0x3478); ret = false; break; @@ -927,16 +889,16 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { func_800E8EA0(globalCtx, &this->actor, 0x347E); ret = false; } else { - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 8; func_808F4108(this, globalCtx, 0x347B); ret = false; } break; case 0x347E: func_808F35D8(this, globalCtx); - if (func_80114E90()) { + if (Interface_HasEmptyBottle()) { this->actionFunc = func_808F3B40; - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); ret = true; } else { func_800E8EA0(globalCtx, &this->actor, 0x347F); @@ -960,7 +922,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x347C: this->actionFunc = func_808F3D40; - func_800B8A1C(&this->actor, globalCtx, 0x81, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_GARO, 500.0f, 100.0f); func_808F35D8(this, globalCtx); ret = true; break; @@ -983,7 +945,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { switch (textId) { case 0x3486: func_800E8EA0(globalCtx, &this->actor, 0x3487); - gSaveContext.weekEventReg[16] |= 1; + gSaveContext.save.weekEventReg[16] |= 1; ret = false; break; case 0x3487: @@ -1024,7 +986,7 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0x348E: case 0x34B3: func_800E8EA0(globalCtx, &this->actor, 0x348F); - gSaveContext.weekEventReg[16] |= 2; + gSaveContext.save.weekEventReg[16] |= 2; ret = false; break; case 0x3493: @@ -1039,10 +1001,10 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { case 0x3490: if (msgCtx->choiceIndex == 0) { func_8019F208(); - if (gSaveContext.rupees >= globalCtx->msgCtx.unk1206C) { - if (func_80114E90()) { + if (gSaveContext.save.playerData.rupees >= globalCtx->msgCtx.unk1206C) { + if (Interface_HasEmptyBottle()) { this->actionFunc = func_808F3C40; - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); func_801159EC(-globalCtx->msgCtx.unk1206C); ret = true; } else { @@ -1076,8 +1038,8 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x3495: func_808F4108(this, globalCtx, 0x3496); - gSaveContext.weekEventReg[16] |= 4; - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[16] |= 4; + gSaveContext.save.weekEventReg[56] |= 8; ret = false; break; case 0x3497: @@ -1092,11 +1054,11 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x34A5: func_808F4108(this, globalCtx, 0x34A6); - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 8; ret = false; break; case 0x3473: - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; func_80151BB4(globalCtx, 0x11); break; case 0x3474: @@ -1104,12 +1066,12 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { ret = false; break; case 0x3475: - SET_FLAGS_START_RACE; - func_800FD750(0x40); + SET_RACE_FLAGS(RACE_FLAG_START); + func_800FD750(NA_BGM_HORSE); globalCtx->nextEntranceIndex = 0xCE50; globalCtx->unk_1887F = 5; globalCtx->sceneLoadFlag = 0x14; - gSaveContext.weekEventReg[57] |= 1; + gSaveContext.save.weekEventReg[57] |= 1; break; case 0x349D: func_808F30B0(&this->skelAnime, 1); @@ -1118,14 +1080,14 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { func_800E8EA0(globalCtx, &this->actor, 0x34A1); ret = false; } else { - gSaveContext.weekEventReg[56] |= 8; + gSaveContext.save.weekEventReg[56] |= 8; func_808F4108(this, globalCtx, 0x349E); ret = false; } break; case 0x349F: this->actionFunc = func_808F3D40; - func_800B8A1C(&this->actor, globalCtx, 0x81, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_GARO, 500.0f, 100.0f); func_808F35D8(this, globalCtx); ret = true; break; @@ -1138,9 +1100,9 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x34A1: func_808F35D8(this, globalCtx); - if (func_80114E90()) { + if (Interface_HasEmptyBottle()) { this->actionFunc = func_808F3B40; - func_800B8A1C(&this->actor, globalCtx, 0x92, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK, 500.0f, 100.0f); ret = true; } else { func_800E8EA0(globalCtx, &this->actor, 0x34A2); @@ -1201,13 +1163,13 @@ s32 func_808F4414(GlobalContext* globalCtx, EnIn* this, s32 arg2) { break; case 0x3472: func_808F43E0(this); - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; func_80151BB4(globalCtx, 0x11); ret = true; break; case 0x349E: func_808F4108(this, globalCtx, 0x349F); - gSaveContext.weekEventReg[56] &= (u8)~8; + gSaveContext.save.weekEventReg[56] &= (u8)~8; ret = false; break; } @@ -1220,14 +1182,14 @@ s32 func_808F5674(GlobalContext* globalCtx, EnIn* this, s32 arg2) { s32 pad; s32 ret = false; - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 2: func_808F4054(globalCtx, this, arg2, this->actor.textId); ret = true; break; case 4: case 5: - if (func_80147624(globalCtx) && func_808F4414(globalCtx, this, arg2)) { + if (Message_ShouldAdvance(globalCtx) && func_808F4414(globalCtx, this, arg2)) { func_801477B4(globalCtx); ret = true; } @@ -1239,14 +1201,13 @@ s32 func_808F5674(GlobalContext* globalCtx, EnIn* this, s32 arg2) { s32 func_808F5728(GlobalContext* globalCtx, EnIn* this, s32 arg2, s32* arg3) { s16 rotDiff; s16 yawDiff; - s16 yawDiffA; Player* player; if (*arg3 == 4) { return 0; } if (*arg3 == 2) { - func_801518B0(globalCtx, this->actor.textId, &this->actor); + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); *arg3 = 1; return 0; } @@ -1255,7 +1216,7 @@ s32 func_808F5728(GlobalContext* globalCtx, EnIn* this, s32 arg2, s32* arg3) { *arg3 = 1; return 0; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { *arg3 = 1; return 1; } @@ -1284,9 +1245,8 @@ s32 func_808F5728(GlobalContext* globalCtx, EnIn* this, s32 arg2, s32* arg3) { if (!func_800B8934(globalCtx, &this->actor)) { return 0; } - yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - yawDiffA = ABS_ALT(yawDiff); - if (yawDiffA >= 0x4300) { + yawDiff = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)); + if (yawDiff >= 0x4300) { return 0; } if (this->actor.xyzDistToPlayerSq > SQ(160.0f) && !this->actor.isTargeted) { @@ -1320,7 +1280,7 @@ s32 func_808F5994(EnIn* this, GlobalContext* globalCtx, Vec3f* arg2, s16 arg3) { } void func_808F5A34(EnIn* this, GlobalContext* globalCtx) { - if (gSaveContext.day != 3) { + if (gSaveContext.save.day != 3) { func_808F5728(globalCtx, this, 3, &this->unk48C); } else { func_808F5728(globalCtx, this, 7, &this->unk48C); @@ -1329,13 +1289,13 @@ void func_808F5A34(EnIn* this, GlobalContext* globalCtx) { void func_808F5A94(EnIn* this, GlobalContext* globalCtx) { if (func_800F41E4(globalCtx, &globalCtx->actorCtx)) { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { func_808F5728(globalCtx, this, 7, &this->unk48C); } else { func_808F5728(globalCtx, this, 3, &this->unk48C); } } else { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { func_808F5728(globalCtx, this, 5, &this->unk48C); } else { func_808F5728(globalCtx, this, 1, &this->unk48C); @@ -1345,17 +1305,17 @@ void func_808F5A94(EnIn* this, GlobalContext* globalCtx) { void func_808F5B58(EnIn* this, GlobalContext* globalCtx) { if (func_800F41E4(globalCtx, &globalCtx->actorCtx)) { - if ((Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADERS_MASK && gSaveContext.weekEventReg[63] & 0x40) || - gSaveContext.weekEventReg[56] & 8) { - if (gSaveContext.day == 3) { + if ((Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADER && gSaveContext.save.weekEventReg[63] & 0x40) || + gSaveContext.save.weekEventReg[56] & 8) { + if (gSaveContext.save.day == 3) { func_808F5728(globalCtx, this, 6, &this->unk48C); } else { func_808F5728(globalCtx, this, 2, &this->unk48C); } } - } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CIRCUS_LEADERS_MASK || - (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADERS_MASK && gSaveContext.weekEventReg[63] & 0x40)) { - if (gSaveContext.day == 3) { + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CIRCUS_LEADER || + (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADER && gSaveContext.save.weekEventReg[63] & 0x40)) { + if (gSaveContext.save.day == 3) { func_808F5728(globalCtx, this, 4, &this->unk48C); } else { func_808F5728(globalCtx, this, 0, &this->unk48C); @@ -1364,22 +1324,22 @@ void func_808F5B58(EnIn* this, GlobalContext* globalCtx) { } void func_808F5C98(EnIn* this, GlobalContext* globalCtx) { - if (this->unk4B0 == 0) { + if (this->unk4B0 == RACE_FLAG_END) { this->actionFunc = func_808F5B58; } - if ((Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADERS_MASK && gSaveContext.weekEventReg[63] & 0x40) || - gSaveContext.weekEventReg[56] & 8) { - if (gSaveContext.day != 3) { + if ((Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADER && gSaveContext.save.weekEventReg[63] & 0x40) || + gSaveContext.save.weekEventReg[56] & 8) { + if (gSaveContext.save.day != 3) { func_808F5728(globalCtx, this, 2, &this->unk48C); } else { func_808F5728(globalCtx, this, 6, &this->unk48C); } } if (this->unk4A8 == 2) { - if (this->unk4B0 == 2) { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_LOST); + if (this->unk4B0 == RACE_FLAG_2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_IN_LOST); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_VO_IN_JOY0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_IN_JOY0); } this->unk4A8 = 3; } else if (this->unk4A8 < 3) { @@ -1398,8 +1358,9 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { s16 type; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06014EA8, NULL, this->jointTable, this->morphTable, 20); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_in_Skel_014EA8, NULL, this->jointTable, this->morphTable, + 20); func_808F30B0(&this->skelAnime, 0); Collider_InitCylinder(globalCtx, &this->colliderCylinder); Collider_SetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); @@ -1408,14 +1369,15 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk48C = 0; this->unk4AC = 0; type = ENIN_GET_TYPE(thisx); - this->unk4B0 = gSaveContext.weekEventReg[92] & (1 | 2 | 4); - if (type == ENIN_HORSE_RIDER_BLUE_SHIRT || type == 4) { + this->unk4B0 = GET_RACE_FLAGS; + if (type == ENIN_HORSE_RIDER_BLUE_SHIRT || type == ENIN_BLUE_SHIRT) { this->unk4AC |= 8; } if (type == ENIN_HORSE_RIDER_YELLOW_SHIRT || type == ENIN_HORSE_RIDER_BLUE_SHIRT) { ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); this->unk488 = 1; - Animation_Change(&this->skelAnime, &D_06016A60, 1.0f, 0.0f, Animation_GetLastFrame(&D_06016A60), 2, 0.0f); + Animation_Change(&this->skelAnime, &object_in_Anim_016A60, 1.0f, 0.0f, + Animation_GetLastFrame(&object_in_Anim_016A60), 2, 0.0f); Actor_SetScale(&this->actor, 0.01f); this->unk23C = 0; this->unk23D = 1; @@ -1425,23 +1387,22 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_SetJntSph(globalCtx, &this->colliderJntSph, &this->actor, &sJntSphInit, &this->colliderJntSphElement); Actor_SetScale(&this->actor, 0.01f); this->actor.gravity = -4.0f; - this->path = func_8013D648(globalCtx, ENIN_GET_PATH(&this->actor), 0x3F); + this->path = SubS_GetPathByIndex(globalCtx, ENIN_GET_PATH(&this->actor), 0x3F); this->unk23D = 0; if (type == ENIN_YELLOW_SHIRT || type == ENIN_BLUE_SHIRT) { - if ((gSaveContext.weekEventReg[92] & (1 | 2 | 4)) == 2 || - (gSaveContext.weekEventReg[92] & (1 | 2 | 4)) == 3) { - gSaveContext.weekEventReg[56] &= (u8)~8; + if (GET_RACE_FLAGS == RACE_FLAG_2 || GET_RACE_FLAGS == RACE_FLAG_3) { + gSaveContext.save.weekEventReg[56] &= (u8)~8; this->unk4A8 = 0; this->unk4AC |= 2; func_808F35AC(this, globalCtx); this->unk23C = 0; D_801BDAA0 = 0; - if ((gSaveContext.weekEventReg[92] & (1 | 2 | 4)) == 2) { + if (GET_RACE_FLAGS == RACE_FLAG_2) { func_808F30B0(&this->skelAnime, 6); } else { func_808F30B0(&this->skelAnime, 4); } - if ((gSaveContext.weekEventReg[92] & (1 | 2 | 4)) == 2) { + if (GET_RACE_FLAGS == RACE_FLAG_2) { this->skelAnime.curFrame = ((Rand_ZeroOne() * 0.6f) + 0.2f) * this->skelAnime.endFrame; } if (this->unk4AC & 8) { @@ -1450,8 +1411,8 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc = func_808F5C98; } } else { - if ((gSaveContext.weekEventReg[92] & (1 | 2 | 4)) != 1) { - gSaveContext.weekEventReg[56] &= (u8)~8; + if (GET_RACE_FLAGS != RACE_FLAG_START) { + gSaveContext.save.weekEventReg[56] &= (u8)~8; this->unk23C = 0; this->unk4AC |= 2; if (type == ENIN_BLUE_SHIRT) { @@ -1459,7 +1420,7 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { func_808F30B0(&this->skelAnime, 0); this->actionFunc = func_808F5A94; } else { - if (gSaveContext.weekEventReg[52] & 1) { + if (gSaveContext.save.weekEventReg[52] & 1) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_KANBAN, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, this->actor.shape.rot.y, this->actor.shape.rot.z, 0xF); @@ -1470,7 +1431,7 @@ void EnIn_Init(Actor* thisx, GlobalContext* globalCtx) { } } } else { - if (gSaveContext.weekEventReg[52] & 1) { + if (gSaveContext.save.weekEventReg[52] & 1) { Actor_MarkForDeath(&this->actor); } else { func_808F30B0(&this->skelAnime, 7); @@ -1502,7 +1463,7 @@ void EnIn_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk4AC &= ~2; func_808F38F8(this, globalCtx); } - if (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADERS_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_CIRCUS_LEADER) { this->unk4AC |= 0x40; } else { this->unk4AC &= ~0x40; @@ -1517,13 +1478,13 @@ void func_808F6334(EnIn* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 newUnk4C8; - newUnk4C8 = func_80152498(&globalCtx->msgCtx); + newUnk4C8 = Message_GetState(&globalCtx->msgCtx); this->unk4C4 += this->unk4C0 != 0.0f ? 40.0f : -40.0f; this->unk4C4 = CLAMP(this->unk4C4, 0.0f, 80.0f); - Matrix_InsertTranslation(this->unk4C4, 0.0f, 0.0f, MTXMODE_APPLY); - if (this == (EnIn*)player->targetActor && - !(globalCtx->msgCtx.unk11F04 >= 0xFF && globalCtx->msgCtx.unk11F04 <= 0x200) && newUnk4C8 == 3 && + Matrix_Translate(this->unk4C4, 0.0f, 0.0f, MTXMODE_APPLY); + if (&this->actor == player->targetActor && + !(globalCtx->msgCtx.currentTextId >= 0xFF && globalCtx->msgCtx.currentTextId <= 0x200) && newUnk4C8 == 3 && this->unk4C8 == 3) { if (!(globalCtx->state.frames & 1)) { this->unk4C0 = this->unk4C0 != 0.0f ? 0.0f : 1.0f; @@ -1534,13 +1495,30 @@ void func_808F6334(EnIn* this, GlobalContext* globalCtx) { this->unk4C8 = newUnk4C8; } -s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnIn* this = (EnIn*)arg; +s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnIn* this = THIS; s32 pad; Gfx* sp50[] = { - NULL, NULL, D_060149A8, D_06014AE0, D_06014C30, D_060145D8, D_06014710, - D_06014860, D_06014420, D_06012A78, D_06013DE0, D_06013F10, D_06014040, D_060137A0, - D_060138D0, D_06013A00, D_06012DF8, D_06013670, D_06013540, D_06013440, + NULL, + NULL, + object_in_DL_0149A8, + object_in_DL_014AE0, + object_in_DL_014C30, + object_in_DL_0145D8, + object_in_DL_014710, + object_in_DL_014860, + object_in_DL_014420, + object_in_DL_012A78, + object_in_DL_013DE0, + object_in_DL_013F10, + object_in_DL_014040, + object_in_DL_0137A0, + object_in_DL_0138D0, + object_in_DL_013A00, + object_in_DL_012DF8, + object_in_DL_013670, + object_in_DL_013540, + object_in_DL_013440, }; if (this->unk23C != 0 && limbIndex != 16) { @@ -1549,29 +1527,31 @@ s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } } if (this->unk4AC & 4 && limbIndex == 16) { - *dList = D_0601C528; + *dList = object_in_DL_01C528; } OPEN_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 16) { - void* sp38[] = { &D_060035E0, &D_06004820, &D_06004C20, &D_060043E0 }; + TexturePtr sp38[] = { object_in_Tex_0035E0, object_in_Tex_004820, object_in_Tex_004C20, object_in_Tex_0043E0 }; + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp38[this->unk482])); - gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(&D_06003520)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(object_in_Tex_003520)); } else { - AnimatedMat_DrawStep(globalCtx, Lib_SegmentedToVirtual(&D_06001C30), this->unk4AC & 8 ? 1 : 0); + AnimatedMat_DrawStep(globalCtx, Lib_SegmentedToVirtual(object_in_Matanimheader_001C30), + this->unk4AC & 8 ? 1 : 0); } CLOSE_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 16) { - Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk35A, MTXMODE_APPLY); - Matrix_InsertZRotation_s(-this->unk358, MTXMODE_APPLY); - Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); func_808F6334(this, globalCtx); } if (limbIndex == 9) { - Matrix_RotateY(this->unk360, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk35E, MTXMODE_APPLY); + Matrix_RotateYS(this->torsoRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->torsoRot.x, MTXMODE_APPLY); } if (limbIndex == 9 || limbIndex == 10 || limbIndex == 13) { rot->y += (s16)(Math_SinS(this->unk376[limbIndex]) * 200.0f); @@ -1595,31 +1575,31 @@ s32 EnIn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, return 0; } -void EnIn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnIn* this = (EnIn*)arg; +void EnIn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnIn* this = THIS; Vec3f sp50 = { 1600.0f, 0.0f, 0.0f }; Vec3f sp44 = { 0.0f, 0.0f, 0.0f }; if (limbIndex == 16) { - Matrix_MultiplyVector3fByState(&sp50, &this->unk4B4); + Matrix_MultVec3f(&sp50, &this->unk4B4); Math_Vec3f_Copy(&this->actor.focus.pos, &this->unk4B4); } if (this->unk23D == 0) { Collider_UpdateSpheres(limbIndex, &this->colliderJntSph); if (limbIndex == 4) { - Matrix_MultiplyVector3fByState(&sp44, &this->unk248); + Matrix_MultVec3f(&sp44, &this->unk248); } if (limbIndex == 7) { - Matrix_MultiplyVector3fByState(&sp44, &this->unk254); + Matrix_MultVec3f(&sp44, &this->unk254); } if (this->unk23C == 0) { if (!(this->unk4AC & 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 12) { - gSPDisplayList(POLY_OPA_DISP++, D_06007A70); + gSPDisplayList(POLY_OPA_DISP++, object_in_DL_007A70); } if (limbIndex == 15) { - gSPDisplayList(POLY_OPA_DISP++, D_06007C48); + gSPDisplayList(POLY_OPA_DISP++, object_in_DL_007C48); } CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -1628,7 +1608,7 @@ void EnIn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec if (this->unk4AC & 0x20) { OPEN_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 12) { - gSPDisplayList(POLY_OPA_DISP++, D_06007C48); + gSPDisplayList(POLY_OPA_DISP++, object_in_DL_007C48); } CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_In/z_en_in.h b/src/overlays/actors/ovl_En_In/z_en_in.h index ca67df431..ae339ecaa 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.h +++ b/src/overlays/actors/ovl_En_In/z_en_in.h @@ -36,15 +36,10 @@ typedef struct EnIn { /* 0x261 */ u8 unk261; /* 0x262 */ Vec3s jointTable[20]; /* 0x2DA */ Vec3s morphTable[20]; - /* 0x352 */ s16 unk352; - /* 0x354 */ s16 unk354; - /* 0x356 */ char unk356[0x2]; - /* 0x358 */ s16 unk358; - /* 0x35A */ s16 unk35A; - /* 0x35C */ char unk35C[0x2]; - /* 0x35E */ s16 unk35E; - /* 0x360 */ s16 unk360; - /* 0x362 */ char unk362[0x14]; + /* 0x352 */ Vec3s turnTarget; + /* 0x358 */ Vec3s headRot; + /* 0x35E */ Vec3s torsoRot; + /* 0x364 */ char unk364[0x12]; /* 0x376 */ s16 unk376[20]; /* 0x39E */ s16 unk39E[20]; /* 0x3C6 */ char unk3C6[0xBC]; diff --git a/src/overlays/actors/ovl_En_Insect/z_en_insect.c b/src/overlays/actors/ovl_En_Insect/z_en_insect.c index cc07e58dd..75c70113e 100644 --- a/src/overlays/actors/ovl_En_Insect/z_en_insect.c +++ b/src/overlays/actors/ovl_En_Insect/z_en_insect.c @@ -1,4 +1,11 @@ +/* + * File: z_en_insect.c + * Overlay: ovl_En_Insect + * Description: Single freestanding bug that doesn't burrow + */ + #include "z_en_insect.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -9,15 +16,22 @@ void EnInsect_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnInsect_Update(Actor* thisx, GlobalContext* globalCtx); void EnInsect_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_8091AC78(EnInsect* this); void func_8091ACC4(EnInsect* this, GlobalContext* globalCtx); +void func_8091AE10(EnInsect* this); void func_8091AE5C(EnInsect* this, GlobalContext* globalCtx); +void func_8091B030(EnInsect* this); void func_8091B07C(EnInsect* this, GlobalContext* globalCtx); void func_8091B2D8(EnInsect* this, GlobalContext* globalCtx); +void func_8091B3D0(EnInsect* this); void func_8091B440(EnInsect* this, GlobalContext* globalCtx); +void func_8091B618(EnInsect* this); void func_8091B670(EnInsect* this, GlobalContext* globalCtx); +void func_8091B928(EnInsect* this); void func_8091B984(EnInsect* this, GlobalContext* globalCtx); -#if 0 +s16 D_8091BD60 = 0; + const ActorInit En_Insect_InitVars = { ACTOR_EN_INSECT, ACTORCAT_ITEMACTION, @@ -30,74 +44,466 @@ const ActorInit En_Insect_InitVars = { (ActorFunc)EnInsect_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8091BD84[1] = { +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_8091BDA8 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_8091BD84, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8091BDBC[] = { +u16 D_8091BDB8[] = { 0, 5 }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 700, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 20, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 30, ICHAIN_STOP), }; -#endif +Vec3f D_8091BDCC = { 0.0f, 0.0f, 0.0f }; -extern ColliderJntSphElementInit D_8091BD84[1]; -extern ColliderJntSphInit D_8091BDA8; -extern InitChainEntry D_8091BDBC[]; +void func_8091A8A0(EnInsect* this) { + this->unk_30C = D_8091BDB8[ENINSECT_GET_1(&this->actor)]; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091A8A0.s") +f32 EnInsect_XZDistanceSquared(Vec3f* arg0, Vec3f* arg1) { + return SQ(arg0->x - arg1->x) + SQ(arg0->z - arg1->z); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091A8C4.s") +s32 EnInsect_InBottleRange(EnInsect* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091A8F4.s") + if (this->actor.xzDistToPlayer < 32.0f) { + sp1C.x = player->actor.world.pos.x + (Math_SinS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 16.0f); + sp1C.y = player->actor.world.pos.y; + sp1C.z = player->actor.world.pos.z + (Math_CosS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 16.0f); + if (EnInsect_XZDistanceSquared(&sp1C, &this->actor.world.pos) <= SQ(20.0f)) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091A9E4.s") +void func_8091A9E4(EnInsect* this) { + if (this->unk_316 > 0) { + this->unk_316--; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/EnInsect_Init.s") + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MUSI_WALK); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/EnInsect_Destroy.s") + this->unk_316 = 3.0f / CLAMP_MIN(this->skelAnime.playSpeed, 0.1f); + if (this->unk_316 < 2) { + this->unk_316 = 2; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091AC78.s") +void EnInsect_Init(Actor* thisx, GlobalContext* globalCtx) { + EnInsect* this = THIS; + f32 rand; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091ACC4.s") + this->actor.world.rot.y = Rand_Next() & 0xFFFF; + this->actor.home.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.y = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091AE10.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + func_8091A8A0(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091AE5C.s") + SkelAnime_Init(globalCtx, &this->skelAnime, &gameplay_keep_Skel_0527A0, &gameplay_keep_Anim_05140C, + this->jointTable, this->morphTable, 24); + Animation_Change(&this->skelAnime, &gameplay_keep_Anim_05140C, 1.0f, 0.0f, 0.0f, 1, 0.0f); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B030.s") + { + ColliderJntSphElement* colliderElement = &this->collider.elements[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B07C.s") + colliderElement->dim.worldSphere.radius = colliderElement->dim.modelSphere.radius * colliderElement->dim.scale; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B274.s") + this->actor.colChkInfo.mass = 30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B2D8.s") + if (this->unk_30C & 1) { + this->actor.gravity = -0.2f; + this->actor.terminalVelocity = -2.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B3D0.s") + if (this->unk_30C & 4) { + this->unk_314 = Rand_S16Offset(200, 40); + this->actor.flags |= ACTOR_FLAG_10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B440.s") + rand = Rand_ZeroOne(); + if (rand < 0.3f) { + func_8091AC78(this); + } else if (rand < 0.4f) { + func_8091AE10(this); + } else { + func_8091B030(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B618.s") +void EnInsect_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyJntSph(globalCtx, &THIS->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B670.s") +void func_8091AC78(EnInsect* this) { + this->unk_312 = Rand_S16Offset(5, 35); + this->actionFunc = func_8091ACC4; + this->unk_30C |= 0x100; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B928.s") +void func_8091ACC4(EnInsect* this, GlobalContext* globalCtx) { + f32 temp_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/func_8091B984.s") + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.5f, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/EnInsect_Update.s") + temp_f2 = (Rand_ZeroOne() * 0.8f) + (this->actor.speedXZ * 1.2f); + if (temp_f2 < 0.0f) { + this->skelAnime.playSpeed = 0.0f; + } else { + f32 clamped = CLAMP_MAX(temp_f2, 1.9f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Insect/EnInsect_Draw.s") + this->skelAnime.playSpeed = clamped; + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (this->unk_312 <= 0) { + func_8091AE10(this); + } + + if ((this->unk_30C & 4) && (this->unk_314 <= 0)) { + func_8091B3D0(this); + } else if ((this->unk_30C & 1) && (this->actor.bgCheckFlags & 0x40)) { + func_8091B618(this); + } else if (this->actor.xzDistToPlayer < 40.0f) { + func_8091B030(this); + } +} + +void func_8091AE10(EnInsect* this) { + this->unk_312 = Rand_S16Offset(10, 45); + this->actionFunc = func_8091AE5C; + this->unk_30C |= 0x100; +} + +void func_8091AE5C(EnInsect* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f0; + + Math_SmoothStepToF(&this->actor.speedXZ, 1.5f, 0.1f, 0.5f, 0.0f); + + if ((EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(40.0f)) || + (this->unk_312 < 4)) { + Math_ScaledStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos), + 0x7D0); + } else if ((this->actor.child != NULL) && (&this->actor != this->actor.child)) { + Math_ScaledStepToS(&this->actor.world.rot.y, + Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.child->world.pos), 0x7D0); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + + temp_f0 = this->actor.speedXZ * 1.4f; + this->skelAnime.playSpeed = CLAMP(temp_f0, 0.7f, 1.9f); + SkelAnime_Update(&this->skelAnime); + + if (this->unk_312 <= 0) { + func_8091AC78(this); + } + + if ((this->unk_30C & 4) && (this->unk_314 <= 0)) { + func_8091B3D0(this); + } else if ((this->unk_30C & 1) && (this->actor.bgCheckFlags & 0x40)) { + func_8091B618(this); + } else if (this->actor.xzDistToPlayer < 40.0f) { + func_8091B030(this); + } +} + +void func_8091B030(EnInsect* this) { + this->unk_312 = Rand_S16Offset(10, 40); + this->actionFunc = func_8091B07C; + this->unk_30C |= 0x100; +} + +void func_8091B07C(EnInsect* this, GlobalContext* globalCtx) { + s32 pad; + f32 speed; + s16 frames; + s16 yaw; + s32 sp38 = this->actor.xzDistToPlayer < 40.0f; + + Math_SmoothStepToF(&this->actor.speedXZ, 1.8f, 0.1f, 0.5f, 0.0f); + + if ((EnInsect_XZDistanceSquared(&this->actor.world.pos, &this->actor.home.pos) > SQ(160.0f)) || + (this->unk_312 < 4)) { + Math_ScaledStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos), + 0x7D0); + } else if (sp38) { + frames = globalCtx->state.frames; + yaw = BINANG_ROT180(this->actor.yawTowardsPlayer); + if ((frames & 0x10) != 0) { + if ((frames & 0x20) != 0) { + yaw += 0x2000; + } + } else if ((frames & 0x20) != 0) { + yaw -= 0x2000; + } + + if (globalCtx) {} + Math_ScaledStepToS(&this->actor.world.rot.y, yaw, 0x7D0); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + + speed = this->actor.speedXZ * 1.6f; + this->skelAnime.playSpeed = CLAMP(speed, 0.8f, 1.9f); + SkelAnime_Update(&this->skelAnime); + + if ((this->unk_312 <= 0) || !sp38) { + func_8091AC78(this); + } else if ((this->unk_30C & 1) && (this->actor.bgCheckFlags & 0x40)) { + func_8091B618(this); + } +} + +void func_8091B274(EnInsect* this) { + this->unk_312 = 200; + Actor_SetScale(&this->actor, 0.001f); + this->actor.draw = NULL; + this->actor.speedXZ = 0.0f; + this->skelAnime.playSpeed = 0.3f; + this->actionFunc = func_8091B2D8; + this->unk_30C &= ~0x100; +} + +void func_8091B2D8(EnInsect* this, GlobalContext* globalCtx) { + if ((this->unk_312 == 20) && !(this->unk_30C & 4)) { + this->actor.draw = EnInsect_Draw; + } else if (this->unk_312 == 0) { + if (this->unk_30C & 4) { + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_SetScale(&this->actor, 0.01f); + func_8091AC78(this); + } else if (this->unk_312 < 20) { + Actor_SetScale(&this->actor, CLAMP_MAX(this->actor.scale.x + 0.001f, 0.01f)); + SkelAnime_Update(&this->skelAnime); + } +} + +void func_8091B3D0(EnInsect* this) { + this->unk_312 = 60; + this->skelAnime.playSpeed = 1.9f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTURA_BOUND); + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); + this->actionFunc = func_8091B440; + this->unk_30C &= ~0x100; + this->unk_30C |= 8; +} + +void func_8091B440(EnInsect* this, GlobalContext* globalCtx) { + s32 pad[2]; + Vec3f sp34; + + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.5f, 0.0f); + Math_StepToS(&this->actor.shape.rot.x, 0x2AAA, 0x160); + Actor_SetScale(&this->actor, CLAMP_MIN(this->actor.scale.x - 0.0002f, 0.001f)); + + this->actor.shape.yOffset -= 0.8f; + this->actor.world.pos.x = (Rand_ZeroOne() + this->actor.home.pos.x) - 0.5f; + this->actor.world.pos.z = (Rand_ZeroOne() + this->actor.home.pos.z) - 0.5f; + + SkelAnime_Update(&this->skelAnime); + + if ((this->unk_312 > 20) && (Rand_ZeroOne() < 0.1f)) { + sp34.x = Math_SinS(this->actor.shape.rot.y) * -0.6f; + sp34.y = Math_SinS(this->actor.shape.rot.x) * 0.6f; + sp34.z = Math_CosS(this->actor.shape.rot.y) * -0.6f; + func_800B1210(globalCtx, &this->actor.world.pos, &sp34, &D_8091BDCC, (Rand_ZeroOne() * 5.0f) + 8.0f, + (Rand_ZeroOne() * 5.0f) + 8.0f); + } + + if (this->unk_312 <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_8091B618(EnInsect* this) { + this->unk_312 = Rand_S16Offset(120, 50); + this->unk_310 = 0; + this->unk_30E = this->unk_310; + this->actionFunc = func_8091B670; + this->unk_30C &= ~0x100; +} + +void func_8091B670(EnInsect* this, GlobalContext* globalCtx) { + s32 pad[2]; + s16 temp; + Vec3f sp40; + + if (this->unk_312 > 80) { + Math_StepToF(&this->actor.speedXZ, 0.6f, 0.08f); + } else { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.02f); + } + + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y += this->actor.depthInWater; + + this->skelAnime.playSpeed = CLAMP(this->unk_312 * 0.018f, 0.1f, 1.9f); + SkelAnime_Update(&this->skelAnime); + + if (this->unk_312 > 80) { + this->unk_30E += Rand_S16Offset(-50, 100); + this->unk_310 += Rand_S16Offset(-300, 600); + } + + temp = this->skelAnime.playSpeed * 200.0f; + this->unk_30E = CLAMP(this->unk_30E, -temp, temp); + this->actor.world.rot.y += this->unk_30E; + + temp = this->skelAnime.playSpeed * 1000.0f; + this->unk_310 = CLAMP(this->unk_310, -temp, temp); + + this->actor.shape.rot.y += this->unk_310; + Math_ScaledStepToS(&this->actor.world.rot.x, 0, 0xBB8); + this->actor.shape.rot.x = this->actor.world.rot.x; + + if (Rand_ZeroOne() < 0.03f) { + sp40.x = this->actor.world.pos.x; + sp40.y = this->actor.world.pos.y + this->actor.depthInWater; + sp40.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp40, 40, 200, 4); + } + + if ((this->unk_312 <= 0) || ((this->unk_30C & 4) && (this->unk_314 <= 0))) { + func_8091B928(this); + } else if (!(this->actor.bgCheckFlags & 0x40)) { + func_8091AC78(this); + } +} + +void func_8091B928(EnInsect* this) { + this->unk_312 = 100; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->actor.terminalVelocity = -0.8f; + this->actor.gravity = -0.04f; + this->unk_30C &= ~1; + this->actionFunc = func_8091B984; + this->unk_30C &= ~0x100; + this->unk_30C |= 8; +} + +void func_8091B984(EnInsect* this, GlobalContext* globalCtx) { + this->actor.shape.rot.x -= 0x1F4; + this->actor.shape.rot.y += 0xC8; + Actor_SetScale(&this->actor, CLAMP_MIN(this->actor.scale.x - 0.00005f, 0.001f)); + + if ((this->actor.depthInWater > 5.0f) && (this->actor.depthInWater < 30.0f) && (Rand_ZeroOne() < 0.3f)) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, -5.0f, 5.0f, 5.0f, (Rand_ZeroOne() * 0.04f) + 0.02f); + } + + if (this->unk_312 <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnInsect_Update(Actor* thisx, GlobalContext* globalCtx) { + EnInsect* this = THIS; + s32 phi_v0; + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (&this->actor != this->actor.child)) { + this->actor.child = NULL; + } + + if (this->unk_312 > 0) { + this->unk_312--; + } + + if (this->unk_314 > 0) { + this->unk_314--; + } + + this->actionFunc(this, globalCtx); + + if (this->actor.update != NULL) { + Actor_MoveWithGravity(&this->actor); + if (this->unk_30C & 0x100) { + if (this->unk_30C & 1) { + if (this->actor.bgCheckFlags & 1) { + func_8091A9E4(this); + } + } else { + func_8091A9E4(this); + } + } + + phi_v0 = 0; + if (this->unk_30C & 1) { + phi_v0 = 4; + } + + if (phi_v0 != 0) { + phi_v0 |= 0x40; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 8.0f, 5.0f, 0.0f, phi_v0); + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_8091B274(this); + } else if ((this->actor.xzDistToPlayer < 50.0f) && (this->actionFunc != func_8091B2D8)) { + if (!(this->unk_30C & 0x20) && (this->unk_314 < 180)) { + ColliderJntSphElement* colliderElement = &this->collider.elements[0]; + + colliderElement->dim.worldSphere.center.x = this->actor.world.pos.x; + colliderElement->dim.worldSphere.center.y = this->actor.world.pos.y; + colliderElement->dim.worldSphere.center.z = this->actor.world.pos.z; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (!(this->unk_30C & 8) && (D_8091BD60 < 4) && EnInsect_InBottleRange(this, globalCtx) && + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 60.0f, 30.0f)) { + D_8091BD60++; + } + } + + Actor_SetFocus(&this->actor, 0.0f); + } +} + +void EnInsect_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnInsect* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, NULL); + D_8091BD60 = 0; +} diff --git a/src/overlays/actors/ovl_En_Insect/z_en_insect.h b/src/overlays/actors/ovl_En_Insect/z_en_insect.h index be1ea96dd..612c6ab20 100644 --- a/src/overlays/actors/ovl_En_Insect/z_en_insect.h +++ b/src/overlays/actors/ovl_En_Insect/z_en_insect.h @@ -7,11 +7,22 @@ struct EnInsect; typedef void (*EnInsectActionFunc)(struct EnInsect*, GlobalContext*); +#define ENINSECT_GET_1(thisx) ((thisx)->params & 1) + typedef struct EnInsect { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C4]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colliderElements[1]; + /* 0x01A4 */ SkelAnime skelAnime; + /* 0x01E8 */ Vec3s jointTable[24]; + /* 0x0278 */ Vec3s morphTable[24]; /* 0x0308 */ EnInsectActionFunc actionFunc; - /* 0x030C */ char unk_30C[0xC]; + /* 0x030C */ u16 unk_30C; + /* 0x030E */ s16 unk_30E; + /* 0x0310 */ s16 unk_310; + /* 0x0312 */ s16 unk_312; + /* 0x0314 */ s16 unk_314; + /* 0x0316 */ s16 unk_316; } EnInsect; // size = 0x318 extern const ActorInit En_Insect_InitVars; 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 42b9a6c91..2eace7815 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -1,13 +1,20 @@ /* - * File z_en_invadepoh.c + * File: z_en_invadepoh.c * Overlay: ovl_En_Invadepoh * Description: Ranch nighttime actors */ +#include "prevent_bss_reordering.h" #include "z_en_invadepoh.h" #include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_ma1/object_ma1.h" +#include "objects/object_ma2/object_ma2.h" +#include "objects/object_dog/object_dog.h" +#include "objects/object_cow/object_cow.h" +#include "objects/object_uch/object_uch.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnInvadepoh*)thisx) @@ -170,58 +177,7 @@ void func_80B45A4C(EnInvadePohStruct* s, unkstructInvadepoh4** u); void func_80B45A94(EnInvadePohStruct* s, unkstructInvadepoh4** u); void func_80B45B1C(EnInvadePohStruct* s, unkstructInvadepoh4** u); -extern AnimatedMaterial D_06000550; -extern AnimatedMaterial D_06000560; - -extern AnimationHeader D_06000608; -extern AnimationHeader D_060006C8; -extern AnimationHeader D_06000998; -extern AnimationHeader D_06001560; -extern AnimationHeader D_06001674; -extern AnimationHeader D_06001BD8; -extern AnimationHeader D_06001D80; -extern AnimationHeader D_060021C8; -extern AnimationHeader D_06002A8C; -extern AnimationHeader D_06004264; -extern AnimationHeader D_06004E98; -extern AnimationHeader D_06007328; -extern AnimationHeader D_06009E58; -extern AnimationHeader D_0600A174; -extern AnimationHeader D_06014088; -extern AnimationHeader D_06016720; - -extern FlexSkeletonHeader D_060080F0; -extern FlexSkeletonHeader D_06004010; -extern FlexSkeletonHeader D_06004C30; -extern FlexSkeletonHeader D_06004E50; -extern FlexSkeletonHeader D_06013928; -extern FlexSkeletonHeader D_06015C28; - -extern Gfx D_0600FFC8[]; -extern Gfx D_060107C8[]; -extern Gfx D_06010FC8[]; -extern Gfx D_060117C8[]; -extern Gfx D_06011FC8[]; -extern Gfx D_060127C8[]; -extern Gfx D_06012BC8[]; -extern Gfx D_06012FC8[]; -extern Gfx D_060133C8[]; -extern Gfx D_06011AD8[]; -extern Gfx D_060122D8[]; -extern Gfx D_06012AD8[]; -extern Gfx D_060132D8[]; -extern Gfx D_06013AD8[]; -extern Gfx D_060142D8[]; -extern Gfx D_06014AD8[]; -extern Gfx D_06014ED8[]; -extern Gfx D_060152D8[]; -extern Gfx D_060156D8[]; -extern Gfx D_060003B0[]; -extern Gfx D_06000720[]; -extern Gfx D_06000080[]; - extern s32 D_801BDA9C; -extern Vec3s D_801D15BC; const ActorInit En_Invadepoh_InitVars = { ACTOR_EN_INVADEPOH, @@ -299,28 +255,29 @@ static Vec3f D_80B4E934 = { 216.0f, -20.0f, 1395.0f }; static s32 D_80B4E940 = 0; -static Gfx* D_80B4E944[] = { - D_0600FFC8, D_060107C8, D_06010FC8, D_060117C8, D_06011FC8, +static TexturePtr D_80B4E944[] = { + object_ma1_Tex_00FFC8, object_ma1_Tex_0107C8, object_ma1_Tex_010FC8, object_ma1_Tex_0117C8, object_ma1_Tex_011FC8, }; -static Gfx* D_80B4E958[] = { - D_060127C8, - D_06012BC8, - D_06012FC8, - D_060133C8, +static TexturePtr D_80B4E958[] = { + object_ma1_Tex_0127C8, + object_ma1_Tex_012BC8, + object_ma1_Tex_012FC8, + object_ma1_Tex_0133C8, }; static s8 D_80B4E968 = 0; -static Gfx* D_80B4E96C[] = { - D_06011AD8, D_060122D8, D_06012AD8, D_060132D8, D_06013AD8, D_060142D8, +static TexturePtr D_80B4E96C[] = { + object_ma2_Tex_011AD8, object_ma2_Tex_0122D8, object_ma2_Tex_012AD8, + object_ma2_Tex_0132D8, object_ma2_Tex_013AD8, object_ma2_Tex_0142D8, }; -static Gfx* D_80B4E984[] = { - D_06014AD8, - D_06014ED8, - D_060152D8, - D_060156D8, +static TexturePtr D_80B4E984[] = { + object_ma2_Tex_014AD8, + object_ma2_Tex_014ED8, + object_ma2_Tex_0152D8, + object_ma2_Tex_0156D8, }; static s8 D_80B4E994 = 0; @@ -562,7 +519,7 @@ static InitChainEntry sInitChainRomani[] = { static InitChainEntry D_80B4EC68[] = { ICHAIN_F32(uncullZoneForward, 20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE), ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), - ICHAIN_F32(minVelocityY, -100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), + ICHAIN_F32(terminalVelocity, -100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), }; static InitChainEntry sInitChainDog[] = { @@ -673,10 +630,10 @@ void func_80B439B0(s32 arg0, s32 arg1) { } if (!(arg0 & 1)) { - gSaveContext.roomInf[124][arg0 >> 1] = (gSaveContext.roomInf[124][arg0 >> 1] & 0xFFFF0000) | (arg1 & 0xFFFF); + gSaveContext.save.unk_E88[arg0 >> 1] = (gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF0000) | (arg1 & 0xFFFF); } else { - gSaveContext.roomInf[124][arg0 >> 1] = - (gSaveContext.roomInf[124][arg0 >> 1] & 0xFFFF) | ((arg1 & 0xFFFF) << 0x10); + gSaveContext.save.unk_E88[arg0 >> 1] = + (gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF) | ((arg1 & 0xFFFF) << 0x10); } } @@ -684,19 +641,19 @@ s32 func_80B43A24(s32 arg0) { u32 phi_v1; if ((arg0 & 1) == 0) { - phi_v1 = gSaveContext.roomInf[124][arg0 >> 1] & 0xFFFF; + phi_v1 = gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF; } else { - phi_v1 = (gSaveContext.roomInf[124][arg0 >> 1] & 0xFFFF0000) >> 0x10; + phi_v1 = (gSaveContext.save.unk_E88[arg0 >> 1] & 0xFFFF0000) >> 0x10; } return phi_v1 + 0x1AAA; } void func_80B43A74(s32 arg0) { - gSaveContext.roomInf[124][4] = (gSaveContext.roomInf[124][4] & ~0xFF) | (arg0 & 0xFF); + gSaveContext.save.unk_E88[4] = (gSaveContext.save.unk_E88[4] & ~0xFF) | (arg0 & 0xFF); } s32 func_80B43A9C(void) { - return (gSaveContext.roomInf[124][4] >> 0) & 0xFF; + return (gSaveContext.save.unk_E88[4] >> 0) & 0xFF; } s32 func_80B43AB0(void) { @@ -710,7 +667,7 @@ s32 func_80B43AB0(void) { } void func_80B43AF0(s32 arg0) { - s32 currentTime = gSaveContext.time; + s32 currentTime = gSaveContext.save.time; if (((CURRENT_DAY == 1) && (currentTime >= CLOCK_TIME(2, 30))) && (currentTime < CLOCK_TIME(5, 15))) { s32 adjustment = (0xC - func_80B43A9C()) * 25.0f; @@ -906,7 +863,7 @@ s32 func_80B44234(EnInvadepoh* this, Vec3f* vec) { for (i = 0, arr = this->pathPoints; i < temp_s3; i++, arr++) { Math_Vec3s_ToVec3f(&sp48, arr); - distance = Math3D_DistanceSquared(&sp48, vec); + distance = Math3D_Vec3fDistSq(&sp48, vec); if (distance < min) { min = distance; ret = i; @@ -917,9 +874,7 @@ s32 func_80B44234(EnInvadepoh* this, Vec3f* vec) { } void func_80B442E4(EnInvadepoh* this) { - s32 pad; - s32 sp18 = gSaveContext.time; - s32 temp_v1_2 = sp18 - func_80B43A24(this->actor.params & 7); + s32 temp_v1_2 = ((void)0, (s32)gSaveContext.save.time) - func_80B43A24(this->actor.params & 7); if (D_80B4E940 == 1) { this->clockTime = 0.0f; @@ -991,7 +946,7 @@ void func_80B44540(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B44570(EnInvadepoh* this) { - s32 currentTime = gSaveContext.time; + s32 currentTime = gSaveContext.save.time; if ((currentTime < CLOCK_TIME(2, 0)) || (currentTime >= CLOCK_TIME(6, 0))) { this->clockTime = 0.0f; @@ -1035,7 +990,7 @@ void func_80B446D0(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B44700(EnInvadepoh* this) { - s32 currentTime = gSaveContext.time; + s32 currentTime = gSaveContext.save.time; s32 new_var4 = 0xFFFF2AAB; if ((currentTime < CLOCK_TIME(20, 0)) && (currentTime >= CLOCK_TIME(6, 0))) { @@ -1044,6 +999,7 @@ void func_80B44700(EnInvadepoh* this) { this->clockTime = 1.0f; } else { f32 new_var = 0.00153374229558f; + this->clockTime = (currentTime + new_var4) * new_var; this->clockTime = CLAMP(this->clockTime, 0.0f, 1.0f); } @@ -1132,7 +1088,7 @@ void func_80B44A90(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.velocity.y *= 0.8f; this->actor.speedXZ *= 0.8f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 40.0f, 0.0f, 5); } @@ -1208,7 +1164,7 @@ s32 func_80B44C80(EnInvadepoh* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.world.rot.y, Math_FAtan2F(((sp60.z + temp_f0_2) * 0.9f) + sp6C.z, ((sp60.x + temp_f0_3) * 0.9f) + sp6C.x), 4, 0xFA0, 0x64); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (func_80B440B8(this, 50.0f, 15.0f)) { phi_v0 = 4; } else { @@ -1221,7 +1177,7 @@ s32 func_80B44C80(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B44E90(EnInvadepoh* this, GlobalContext* globalCtx) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 15.0f, 0.0f, 5); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x1F40, 0x64); } @@ -1238,7 +1194,7 @@ void func_80B44EFC(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B44F58(void) { s32 i; - Gfx** iter; + TexturePtr* iter; if (!D_80B4E968) { D_80B4E968 = true; @@ -1254,7 +1210,7 @@ void func_80B44F58(void) { void func_80B44FEC(void) { s32 i; - Gfx** iter; + TexturePtr* iter; if (!D_80B4E994) { D_80B4E994 = true; @@ -1269,8 +1225,8 @@ void func_80B44FEC(void) { } void func_80B45080(void) { - D_80B50400 = Lib_SegmentedToVirtual(&D_06000560); - D_80B503FC = Lib_SegmentedToVirtual(&D_06000550); + D_80B50400 = Lib_SegmentedToVirtual(object_uch_Matanimheader_000560); + D_80B503FC = Lib_SegmentedToVirtual(object_uch_Matanimheader_000550); } s32 func_80B450C0(f32* x1, f32* z1, f32 x2, f32 z2, f32 speed) { @@ -1308,7 +1264,7 @@ void func_80B451A0(EnInvadepoh* this, GlobalContext* globalCtx) { if (CURRENT_DAY <= 0) { D_80B4E940 = 1; } else if (CURRENT_DAY == 1) { - currentTime = gSaveContext.time; + currentTime = gSaveContext.save.time; if ((currentTime < CLOCK_TIME(2, 30)) || (currentTime >= CLOCK_TIME(6, 0))) { D_80B4E940 = 1; } else if (currentTime < CLOCK_TIME(5, 15)) { @@ -1329,7 +1285,7 @@ void func_80B451A0(EnInvadepoh* this, GlobalContext* globalCtx) { } if (D_80B4E940 == 0) { - if (gSaveContext.weekEventReg[22] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { D_80B4E940 = 3; } else { D_80B4E940 = 4; @@ -1369,23 +1325,23 @@ void func_80B454BC(EnInvadepoh* this, GlobalContext* globalCtx) { } void EnInvadepoh_SetSysMatrix(Vec3f* vec) { - MtxF* sysMatrix = Matrix_GetCurrentState(); + MtxF* sysMatrix = Matrix_GetCurrent(); - sysMatrix->wx = vec->x; - sysMatrix->wy = vec->y; - sysMatrix->wz = vec->z; + sysMatrix->xw = vec->x; + sysMatrix->yw = vec->y; + sysMatrix->zw = vec->z; } s32 func_80B45550(EnInvadepoh* this, GlobalContext* globalCtx, f32 range, s32 arg3) { s32 pad; - Actor* actorIterator = globalCtx->actorCtx.actorList[ACTORCAT_DOOR].first; + Actor* actorIterator = globalCtx->actorCtx.actorLists[ACTORCAT_DOOR].first; s32 retVal = false; while (actorIterator != NULL) { if ((actorIterator->id == ACTOR_EN_DOOR) && (actorIterator->update != NULL) && (actorIterator->room == this->actor.room) && - Math3D_DistanceSquared(&actorIterator->world.pos, &this->actor.world.pos) < range) { - ((EnDoor*)actorIterator)->unk1A7 = arg3; + Math3D_Vec3fDistSq(&actorIterator->world.pos, &this->actor.world.pos) < range) { + ((EnDoor*)actorIterator)->unk_1A7 = arg3; retVal = true; break; } @@ -1396,7 +1352,7 @@ s32 func_80B45550(EnInvadepoh* this, GlobalContext* globalCtx, f32 range, s32 ar void EnInvadepoh_SetTextID(EnInvadepoh* this, GlobalContext* globalCtx, u16 arg2) { this->textId = arg2; - func_801518B0(globalCtx, arg2, &this->actor); + Message_StartTextbox(globalCtx, arg2, &this->actor); } void func_80B45648(EnInvadepoh* this) { @@ -1413,7 +1369,7 @@ s32 func_80B456A8(GlobalContext* globalCtx, Vec3f* vec) { Vec3f multDest; f32 wDest; - func_800B4EDC(globalCtx, vec, &multDest, &wDest); + Actor_GetProjectedPos(globalCtx, vec, &multDest, &wDest); if (((multDest.z > 1.0f) && (fabsf(multDest.x * wDest) < 1.0f)) && (fabsf(multDest.y * wDest) < 1.0f)) { s32 wX = (multDest.x * wDest * 160.0f) + 160.0f; s32 wY = (multDest.y * wDest * -120.0f) + 120.0f; @@ -1435,7 +1391,7 @@ void func_80B457A0(EnInvadepoh* this) { for (i = 0; i < this->unk379; i++) { if ((D_80B50320[i] != NULL) && D_80B50320[i]->drawAlien) { - distanceSquared = Math3D_DistanceSquared(&D_80B50320[i]->actor.world.pos, &this->actor.world.pos); + distanceSquared = Math3D_Vec3fDistSq(&D_80B50320[i]->actor.world.pos, &this->actor.world.pos); if (distanceSquared < phi_f20) { phi_f20 = distanceSquared; phi_s5 = i; @@ -1621,7 +1577,7 @@ void func_80B45EC8(EnInvadepoh* this, GlobalContext* globalCtx, s32 arg2) { spA8.y = ((Rand_ZeroOne() * 180.0f) + this->actor.world.pos.y) - 90.0f; spA8.z = (spA8.z * 100.0f) + this->actor.world.pos.z; - EffectSsKiraKira_SpawnDispersed(globalCtx, &spA8, &sp9C, &sp90, &D_80B4EC18, &D_80B4EC1C, 6000, -40); + EffectSsKirakira_SpawnDispersed(globalCtx, &spA8, &sp9C, &sp90, &D_80B4EC18, &D_80B4EC1C, 6000, -40); } } @@ -1675,7 +1631,7 @@ void func_80B4627C(EnInvadepoh* this, GlobalContext* globalCtx) { s32 invadepohType; s32 i; - this->actor.flags |= 0x20; + this->actor.flags |= ACTOR_FLAG_20; invadepohType = (this->actor.params >> 8) & 0x7F; for (i = 1; i < 8; i++) { @@ -1694,19 +1650,19 @@ void func_80B4627C(EnInvadepoh* this, GlobalContext* globalCtx) { if (D_80B4E940 == 1) { func_80B46DA8(this); } else if (D_80B4E940 == 2) { - if (gSaveContext.time < CLOCK_TIME(2, 31)) { + if (gSaveContext.save.time < CLOCK_TIME(2, 31)) { func_80B46DA8(this); } else { func_80B454BC(this, globalCtx); func_80B452EC(this, globalCtx); - Audio_QueueSeqCmd(0x800D); + Audio_QueueSeqCmd(NA_BGM_ALIEN_INVASION | 0x8000); func_80B46F88(this); } } else if (D_80B4E940 == 3) { - if (gSaveContext.entranceIndex == 0x6460) { + if (gSaveContext.save.entranceIndex == 0x6460) { func_80B471C0(this); - } else if (gSaveContext.entranceIndex == 0x6470) { + } else if (gSaveContext.save.entranceIndex == 0x6470) { func_80B47248(this); } else { func_80B47248(this); @@ -1721,16 +1677,16 @@ void EnInvadepoh_InitAlien(EnInvadepoh* this, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, D_80B4EC24); Collider_InitCylinder(globalCtx, &this->collider); - ActorShape_Init(&this->actor.shape, 6800.0f, func_800B4088, 150.0f); + ActorShape_Init(&this->actor.shape, 6800.0f, ActorShadow_DrawWhiteCircle, 150.0f); this->actor.shape.shadowAlpha = 140; - this->actor.flags = 0x80001010; + this->actor.flags = (ACTOR_FLAG_10 | ACTOR_FLAG_1000 | ACTOR_FLAG_80000000); if (INVADEPOH_TYPE(this) == TYPE_ALIEN1) { this->actor.update = func_80B4D670; this->actor.world.pos.y = this->actor.home.pos.y + 150.0f; } else { this->actor.update = func_80B47BAC; Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitAlien); - this->actor.colChkInfo.mass = 0x28; + this->actor.colChkInfo.mass = 40; } this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_UCH); if (this->bankIndex < 0) { @@ -1769,7 +1725,7 @@ void EnInvadepoh_InitRomani(EnInvadepoh* this, GlobalContext* globalCtx) { func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_NPC); Collider_InitCylinder(globalCtx, &this->collider); if (temp != 4) { - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 18.0f); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 18.0f); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitRomaniAndCremia); this->actor.colChkInfo.mass = MASS_IMMOVABLE; } @@ -1777,7 +1733,7 @@ void EnInvadepoh_InitRomani(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.update = func_80B48620; } else if (temp == 5) { this->actor.update = func_80B48FB0; - this->actor.flags = 0x19; + this->actor.flags = (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10); } else if (temp == 7) { this->actor.update = func_80B49F88; } else if (temp == 8) { @@ -1793,23 +1749,23 @@ void EnInvadepoh_InitRomani(EnInvadepoh* this, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); } if (temp == 5) { - if (gSaveContext.weekEventReg[22] & 0x1) { + if (gSaveContext.save.weekEventReg[22] & 1) { Actor_MarkForDeath(&this->actor); return; } } else if (temp == 7) { - if (gSaveContext.time < CLOCK_TIME(6, 0) && gSaveContext.time >= CLOCK_TIME(2, 15)) { + if (gSaveContext.save.time < CLOCK_TIME(6, 0) && gSaveContext.save.time >= CLOCK_TIME(2, 15)) { Actor_MarkForDeath(&this->actor); return; } } else if (temp != 8) { if (temp == 9) { - if (gSaveContext.entranceIndex != 0x6460) { + if (gSaveContext.save.entranceIndex != 0x6460) { Actor_MarkForDeath(&this->actor); return; } } else if (temp == 0xC) { - if (!(gSaveContext.weekEventReg[22] & 0x1)) { + if (!(gSaveContext.save.weekEventReg[22] & 1)) { Actor_MarkForDeath(&this->actor); } D_80B503F4 = this; @@ -1822,7 +1778,7 @@ void func_80B468B4(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.update = func_80B49B1C; this->actor.draw = func_80B4E3F0; func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_NPC); - if (D_80B4E940 == 1 || gSaveContext.time < CLOCK_TIME(2, 31)) { + if (D_80B4E940 == 1 || gSaveContext.save.time < CLOCK_TIME(2, 31)) { this->actor.world.pos.x += D_80B4E934.x; this->actor.world.pos.y += D_80B4E934.y + 3000.0f; this->actor.world.pos.z += D_80B4E934.z; @@ -1842,8 +1798,8 @@ void EnInvadepoh_InitDog(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.update = func_80B4B8BC; Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitDog); - this->actor.colChkInfo.mass = 0x50; - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 24.0f); + this->actor.colChkInfo.mass = 80; + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 24.0f); this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_DOG); if (this->bankIndex < 0) { Actor_MarkForDeath(&this->actor); @@ -1859,12 +1815,12 @@ void EnInvadepoh_InitCremia(EnInvadepoh* this, GlobalContext* globalCtx) { Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInitRomaniAndCremia); this->actor.colChkInfo.mass = MASS_HEAVY; - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 18.0f); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 18.0f); this->bankIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MA2); if (this->bankIndex < 0) { Actor_MarkForDeath(&this->actor); } - if (!(gSaveContext.weekEventReg[0x16] & 1)) { + if (!(gSaveContext.save.weekEventReg[22] & 1)) { Actor_MarkForDeath(&this->actor); } D_80B503F8 = this; @@ -1945,7 +1901,7 @@ void func_80B46DA8(EnInvadepoh* this) { } void func_80B46DC8(EnInvadepoh* this, GlobalContext* globalCtx) { - if ((gSaveContext.time < CLOCK_TIME(6, 0)) && (gSaveContext.time >= CLOCK_TIME(2, 30))) { + if ((gSaveContext.save.time < CLOCK_TIME(6, 0)) && (gSaveContext.save.time >= CLOCK_TIME(2, 30))) { func_80B454BC(this, globalCtx); func_80B452EC(this, globalCtx); func_80B46E20(this); @@ -1987,7 +1943,7 @@ void func_80B46EE8(EnInvadepoh* this, GlobalContext* globalCtx) { this->actionTimer--; if (this->actionTimer <= 0) { ActorCutscene_Stop(D_80B50404[0]); - Audio_QueueSeqCmd(0x800D); + Audio_QueueSeqCmd(NA_BGM_ALIEN_INVASION | 0x8000); func_80B46F88(this); } } @@ -2000,8 +1956,8 @@ void func_80B46F88(EnInvadepoh* this) { void func_80B46FA8(EnInvadepoh* this, GlobalContext* globalCtx) { s32 i; - if ((gSaveContext.time < CLOCK_TIME(6, 0)) && (gSaveContext.time >= CLOCK_TIME(5, 15))) { - gSaveContext.weekEventReg[22] |= 1; + if ((gSaveContext.save.time < CLOCK_TIME(6, 0)) && (gSaveContext.save.time >= CLOCK_TIME(5, 15))) { + gSaveContext.save.weekEventReg[22] |= 1; func_80B47064(this); } else { func_80B457A0(this); @@ -2036,7 +1992,7 @@ void func_80B470E0(EnInvadepoh* this) { void func_80B47108(EnInvadepoh* this, GlobalContext* globalCtx) { if (this->actionTimer == 100) { - func_801A3098(0x19); + func_801A3098(NA_BGM_CLEAR_EVENT); } this->actionTimer--; if (this->actionTimer <= 0) { @@ -2086,7 +2042,7 @@ void func_80B47298(EnInvadepoh* this, GlobalContext* globalCtx) { globalCtx->sceneLoadFlag = 0x14; globalCtx->unk_1887F = 0x48; gSaveContext.nextTransition = 0x48; - gSaveContext.weekEventReg[89] |= 0x10; + gSaveContext.save.weekEventReg[89] |= 0x10; func_80B47304(this); } @@ -2110,10 +2066,10 @@ void EnInvadepoh_Update(Actor* thisx, GlobalContext* globalCtx) { } void func_80B47380(EnInvadepoh* this) { - this->collider.base.atFlags &= ~1; - this->collider.base.acFlags &= ~1; - this->collider.base.ocFlags1 &= ~1; - this->actor.flags &= ~0x80000000; + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; + this->actor.flags &= ~ACTOR_FLAG_80000000; this->alienAlpha = 0; this->actor.draw = NULL; this->drawAlien = false; @@ -2135,10 +2091,10 @@ void func_80B473E4(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B47478(EnInvadepoh* this) { - this->collider.base.atFlags &= ~1; - this->collider.base.acFlags &= ~1; - this->collider.base.ocFlags1 &= ~1; - this->actor.flags &= ~0x80000000; + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; + this->actor.flags &= ~ACTOR_FLAG_80000000; this->alienAlpha = 0; this->actor.draw = NULL; this->drawAlien = false; @@ -2160,16 +2116,16 @@ void func_80B474DC(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B47568(EnInvadepoh* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06001D80, -6.0f); - this->collider.base.atFlags &= ~0x1; - this->collider.base.acFlags &= ~0x1; - this->collider.base.ocFlags1 &= ~0x1; + Animation_MorphToLoop(&this->skelAnime, &object_uch_Anim_001D80, -6.0f); + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; this->alienAlpha = 0; this->actor.draw = func_80B4DB14; this->drawAlien = true; this->drawAlienDeathEffect = false; this->alienBeamAlpha = 0; - this->actor.flags |= 0x80000000; + this->actor.flags |= ACTOR_FLAG_80000000; this->actionFunc = func_80B47600; } @@ -2187,9 +2143,9 @@ void func_80B47600(EnInvadepoh* this, GlobalContext* globalCtx) { this->alienAlpha += 6; } if (this->alienAlpha > 128) { - this->collider.base.atFlags |= 1; - this->collider.base.acFlags |= 1; - this->collider.base.ocFlags1 |= 1; + this->collider.base.atFlags |= AT_ON; + this->collider.base.acFlags |= AC_ON; + this->collider.base.ocFlags1 |= OC1_ON; } if (this->alienAlpha == 255) { if (this->alienBeamAlpha >= 245) { @@ -2202,18 +2158,18 @@ void func_80B47600(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B4770C(EnInvadepoh* this) { - if (this->skelAnime.animation != &D_06001D80) { - Animation_MorphToLoop(&this->skelAnime, &D_06001D80, -6.0f); + if (this->skelAnime.animation != &object_uch_Anim_001D80) { + Animation_MorphToLoop(&this->skelAnime, &object_uch_Anim_001D80, -6.0f); } - this->collider.base.atFlags |= 1; - this->collider.base.acFlags |= 1; - this->collider.base.ocFlags1 |= 1; + this->collider.base.atFlags |= AT_ON; + this->collider.base.acFlags |= AC_ON; + this->collider.base.ocFlags1 |= OC1_ON; this->alienAlpha = 255; this->actor.draw = func_80B4DB14; this->drawAlien = true; this->drawAlienDeathEffect = false; this->alienBeamAlpha = 255; - this->actor.flags |= 0x80000000; + this->actor.flags |= ACTOR_FLAG_80000000; this->actionFunc = func_80B477B4; } @@ -2228,11 +2184,11 @@ void func_80B477B4(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B47830(EnInvadepoh* this) { - this->collider.base.atFlags &= ~1; - this->collider.base.acFlags &= ~1; - this->collider.base.ocFlags1 |= 1; - Animation_PlayLoop(&this->skelAnime, &D_060006C8); - func_800BCB70(&this->actor, 0x4000, 255, 0, 16); + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 |= OC1_ON; + Animation_PlayLoop(&this->skelAnime, &object_uch_Anim_0006C8); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 16); this->alienAlpha = 255; this->actor.draw = func_80B4DB14; this->drawAlien = true; @@ -2240,7 +2196,7 @@ void func_80B47830(EnInvadepoh* this) { this->alienBeamAlpha = 0; this->actionTimer = 8; this->counter = 0; - this->actor.flags |= 0x80000000; + this->actor.flags |= ACTOR_FLAG_80000000; this->actionFunc = func_80B478F4; } @@ -2253,18 +2209,18 @@ void func_80B478F4(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B47938(EnInvadepoh* this) { - this->collider.base.atFlags &= ~1; - this->collider.base.acFlags &= ~1; - this->collider.base.ocFlags1 &= ~1; - Animation_PlayLoop(&this->skelAnime, &D_06000608); - this->actor.flags &= ~1; + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.ocFlags1 &= ~OC1_ON; + Animation_PlayLoop(&this->skelAnime, &object_uch_Anim_000608); + this->actor.flags &= ~ACTOR_FLAG_1; this->actionTimer = 10; this->alienAlpha = 255; this->actor.draw = func_80B4DB14; this->drawAlien = true; this->drawAlienDeathEffect = false; this->alienBeamAlpha = 255; - this->actor.flags |= 0x80000000; + this->actor.flags |= ACTOR_FLAG_80000000; this->actionFunc = func_80B479E8; } @@ -2324,18 +2280,18 @@ void func_80B47BAC(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); func_80B45080(); this->actor.update = func_80B47D30; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004E50, &D_06001D80, this->jointTable, this->morphTable, - 14); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_uch_Skel_004E50, &object_uch_Anim_001D80, + this->jointTable, this->morphTable, 14); this->skelAnime.curFrame = (this->actor.params & 7) * this->skelAnime.endFrame * 0.125f; func_80B444BC(this, globalCtx); func_80B442E4(this); func_80B447C0(this, globalCtx); func_80B43F0C(this); func_80B4516C(this); - if (D_80B4E940 == 1 || gSaveContext.time < CLOCK_TIME(2, 31)) { + if (D_80B4E940 == 1 || gSaveContext.save.time < CLOCK_TIME(2, 31)) { func_80B47380(this); } else if (D_80B4E940 == 2) { if (this->clockTime >= 0.0001f) { @@ -2363,7 +2319,7 @@ void func_80B47D30(Actor* thisx, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); return; } - } else if (this->collider.base.acFlags & 2) { + } else if (this->collider.base.acFlags & AC_HIT) { Actor* acAttached = this->collider.base.ac; thisx->speedXZ = acAttached->speedXZ * 0.5f; @@ -2372,7 +2328,7 @@ void func_80B47D30(Actor* thisx, GlobalContext* globalCtx) { thisx->gravity = 0.0f; thisx->velocity.y = acAttached->velocity.y * 0.5f; thisx->velocity.y = CLAMP(thisx->velocity.y, -30.0f, 30.0f); - Audio_PlaySoundAtPosition(globalCtx, &thisx->world.pos, 50, NA_SE_EN_INVADER_DEAD); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &thisx->world.pos, 50, NA_SE_EN_INVADER_DEAD); func_80B47830(this); } @@ -2407,11 +2363,12 @@ void func_80B47FA8(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, thisx); + Actor_SetObjectDependency(globalCtx, thisx); this->actor.update = func_80B48060; this->actor.draw = func_80B4E158; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004010, NULL, this->jointTable, this->morphTable, 6); - Animation_PlayLoop(&this->skelAnime, &D_06004264); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gCowSkel, NULL, this->jointTable, this->morphTable, + COW_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowMooAnim); } } @@ -2431,16 +2388,16 @@ void func_80B48060(Actor* thisx, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); Math_ScaledStepToS(&this->actor.shape.rot.x, D_80B4EDC0[temp], 0x32); if (this->actor.child != NULL) { - Matrix_StatePush(); - Matrix_SetStateRotationAndTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, - &this->actor.shape.rot); - Matrix_InsertTranslation(0, 57.0f, -36.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->actor.shape.rot.x * -0.7f, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->actor.shape.rot.z * -0.7f, MTXMODE_APPLY); - Matrix_GetStateTranslation(&this->actor.child->world.pos); - Matrix_CopyCurrentState(&unkMtx); - func_8018219C(&unkMtx, &this->actor.child->shape.rot, 0); - Matrix_StatePop(); + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Translate(0, 57.0f, -36.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x * -0.7f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z * -0.7f, MTXMODE_APPLY); + Matrix_MultZero(&this->actor.child->world.pos); + Matrix_Get(&unkMtx); + Matrix_MtxFToYXZRot(&unkMtx, &this->actor.child->shape.rot, false); + Matrix_Pop(); } } @@ -2450,11 +2407,12 @@ void func_80B481C4(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); this->actor.update = func_80B4827C; this->actor.draw = func_80B4E1B0; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004C30, NULL, this->jointTable, this->morphTable, 6); - Animation_PlayLoop(&this->skelAnime, &D_06004E98); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gCowTailSkel, NULL, this->jointTable, this->morphTable, + COW_TAIL_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &gCowTailSwishAnim); } } @@ -2471,7 +2429,7 @@ void func_80B4827C(Actor* thisx, GlobalContext* globalCtx) { void func_80B482D4(EnInvadepoh* this) { this->actionTimer = 40; - Animation_MorphToLoop(&this->skelAnime, &D_06002A8C, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_002A8C, -10.0f); this->actor.draw = NULL; this->actionFunc = func_80B48324; } @@ -2487,7 +2445,7 @@ void func_80B48324(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B48374(EnInvadepoh* this) { this->actionTimer = 60; - Animation_MorphToLoop(&this->skelAnime, &D_06002A8C, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_002A8C, -10.0f); this->actor.draw = func_80B4E324; this->actionFunc = func_80B483CC; } @@ -2519,7 +2477,7 @@ void func_80B4843C(EnInvadepoh* this) { this->behaviorInfo.unk44 = 0.1f; this->behaviorInfo.unk48 = 2000; this->actionTimer = 50; - Animation_Change(&this->skelAnime, &D_06007328, 2.0f, 0.0f, 0.0f, 0, -5.0f); + Animation_Change(&this->skelAnime, &object_ma1_Anim_007328, 2.0f, 0.0f, 0.0f, 0, -5.0f); this->actor.draw = func_80B4E324; this->actionFunc = func_80B484EC; } @@ -2549,7 +2507,7 @@ void func_80B48588(EnInvadepoh* this) { this->behaviorInfo.unk42 = 0; this->behaviorInfo.unk44 = 0.28f; this->behaviorInfo.unk48 = 7000; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->actor.draw = func_80B4E324; this->actionFunc = func_80B48610; } @@ -2563,13 +2521,13 @@ void func_80B48620(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); func_80B44F58(); 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); - Animation_PlayLoop(&this->skelAnime, &D_06009E58); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_009E58, + this->jointTable, this->morphTable, 23); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &gZeroVec3s, 5000, 0.05f, 0.3f, 0.12f); + Animation_PlayLoop(&this->skelAnime, &object_ma1_Anim_009E58); func_80B482D4(this); } } @@ -2602,7 +2560,7 @@ void func_80B487B4(EnInvadepoh* this) { substruct->unk26.z = 0; substruct->unk30 = 0.1f; substruct->unk2C = 800; - Animation_MorphToLoop(&this->skelAnime, &D_06014088, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_014088, -10.0f); this->actionFunc = func_80B48848; } @@ -2618,9 +2576,9 @@ void func_80B48848(EnInvadepoh* this, GlobalContext* globalCtx) { Math_StepToS(&this->behaviorInfo.unk4C, 0x7D0, 0x46); } func_80B43E6C(this, 6, this->behaviorInfo.unk4C, 0x46); - if (((this->actor.flags & 0x40) == 0x40) && + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 7.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->actionTimer > 0) { this->actionTimer--; @@ -2636,7 +2594,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) { @@ -2662,7 +2620,7 @@ void func_80B48948(EnInvadepoh* this) { substruct->unk2C = 1000; } - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->actionFunc = func_80B48AD4; } @@ -2702,7 +2660,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); @@ -2733,7 +2691,7 @@ void func_80B48DE4(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; this->actor.speedXZ = 0.0f; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->behaviorInfo.unk4C = 0; substruct->unk30 = 0.05f; substruct->unk2C = 1200; @@ -2755,7 +2713,7 @@ void func_80B48E4C(EnInvadepoh* this, GlobalContext* globalCtx) { diff = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); temp_v1 = diff * 0.7f; substruct->unk26.y = CLAMP(temp_v1, -0x1F40, 0x1F40); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { func_80B48948(this); } } @@ -2765,14 +2723,14 @@ void func_80B48FB0(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); func_80B44F58(); this->actor.update = func_80B490F0; this->actor.draw = func_80B4E324; 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); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_009E58, + this->jointTable, this->morphTable, 23); + 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); @@ -2784,8 +2742,8 @@ void func_80B48FB0(Actor* thisx, GlobalContext* globalCtx) { void func_80B490F0(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnInvadepoh* this = THIS; - s32 sp2C = (this->actor.flags & 0x40) == 0x40; - s32 isTalking = func_800B84D0(&this->actor, globalCtx); + s32 sp2C = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); + s32 isTalking = Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); if (isTalking) { func_80151BB4(globalCtx, 5); @@ -2816,7 +2774,7 @@ void func_80B49228(EnInvadepoh* this, GlobalContext* globalCtx) { s32 pad; f32 temp_f0; - Actor_SetVelocityYRotationAndGravity(&this->actor); + Actor_UpdateVelocityWithGravity(&this->actor); this->actor.velocity.y *= 0.97f; temp_f0 = Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y + D_80B4E934.y + 300.0f, 0.7f, fabsf(this->actor.velocity.y), 1.0f); @@ -2845,7 +2803,7 @@ void func_80B4934C(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.gravity = -2.0f; } this->actor.velocity.y *= 0.96f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_800B9010(&this->actor, NA_SE_EV_UFO_APPEAR - SFX_FLAG); this->actionTimer--; if (this->actionTimer <= 0) { @@ -2880,7 +2838,7 @@ void func_80B49454(EnInvadepoh* this, GlobalContext* globalCtx) { } Math_Vec3f_Sum(&D_80B4EDD0[this->unk3AC], &this->actor.home.pos, &sp30); - if (Math3D_DistanceSquared(&this->actor.world.pos, &sp30) < SQ(400.0f)) { + if (Math3D_Vec3fDistSq(&this->actor.world.pos, &sp30) < SQ(400.0f)) { this->actor.speedXZ *= 0.8f; } else { Math_StepToF(&this->actor.speedXZ, 170.0f, 21.0f); @@ -2932,7 +2890,7 @@ void func_80B49670(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.gravity = 2.0f; } this->actor.velocity.y *= 0.97f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (D_80B4E940 == 3) { func_80B499BC(this); } @@ -2962,7 +2920,7 @@ void func_80B497EC(EnInvadepoh* this, GlobalContext* globalCtx) { this->actor.gravity = 2.0f; } this->actor.velocity.y *= 0.97f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (this->actionTimer > 0) { this->actionTimer--; } else { @@ -2982,7 +2940,7 @@ void func_80B49904(EnInvadepoh* this) { void func_80B4994C(EnInvadepoh* this, GlobalContext* globalCtx) { Math_StepToF(&this->actor.speedXZ, 150.0f, 4.0f); this->actor.velocity.y *= 0.95f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (this->actionTimer > 0) { this->actionTimer--; } else { @@ -3014,7 +2972,7 @@ void func_80B49A00(EnInvadepoh* this, GlobalContext* globalCtx) { } else { this->actor.gravity = 2.0f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); if (this->actionTimer > 0) { this->actionTimer--; @@ -3040,7 +2998,7 @@ void func_80B49B1C(Actor* thisx, GlobalContext* globalCtx) { void func_80B49BD0(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToLoop(&this->skelAnime, &D_06014088, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_014088, -10.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; @@ -3065,15 +3023,15 @@ void func_80B49C38(EnInvadepoh* this, GlobalContext* globalCtx) { this->unk378 = func_80B45550(this, globalCtx, SQ(80.0f), temp_v0_2); } } - this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); } else { this->unk378 = 0; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); } - if (((this->actor.flags & 0x40) == 0x40) && + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 7.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->clockTime >= 0.9999f) { Actor_MarkForDeath(&this->actor); @@ -3084,7 +3042,7 @@ void func_80B49DA0(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 2000; this->behaviorInfo.unk4C = 0; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->actionFunc = func_80B49DFC; } @@ -3103,9 +3061,9 @@ void func_80B49DFC(EnInvadepoh* this, GlobalContext* globalCtx) { temp_v1 = diff; temp_v1 *= 0.7f; substruct->unk26.y = CLAMP(temp_v1, -0x1F40, 0x1F40); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { if (this->actor.textId == 0x332D) { - gSaveContext.weekEventReg[54] |= 0x10; + gSaveContext.save.weekEventReg[54] |= 0x10; this->actor.textId = 0x332E; } func_80B49BD0(this); @@ -3118,20 +3076,20 @@ void func_80B49F88(Actor* thisx, GlobalContext* globalCtx) { s32 sp38; if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { - sp38 = gSaveContext.time; + sp38 = gSaveContext.save.time; this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); 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); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_014088, + this->jointTable, this->morphTable, 23); + 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); func_80B43F0C(this); func_80B4516C(this); - if (0x20 & gSaveContext.weekEventReg[21]) { - if (gSaveContext.weekEventReg[54] & 0x10) { + if (0x20 & gSaveContext.save.weekEventReg[21]) { + if (gSaveContext.save.weekEventReg[54] & 0x10) { this->actor.textId = 0x332E; } else { this->actor.textId = 0x332D; @@ -3157,7 +3115,7 @@ void func_80B49F88(Actor* thisx, GlobalContext* globalCtx) { void func_80B4A168(Actor* thisx, GlobalContext* globalCtx) { EnInvadepoh* this = THIS; - if ((gSaveContext.time < CLOCK_TIME(6, 0)) && (gSaveContext.time >= CLOCK_TIME(2, 0))) { + if ((gSaveContext.save.time < CLOCK_TIME(6, 0)) && (gSaveContext.save.time >= CLOCK_TIME(2, 0))) { this->actor.update = func_80B4A1B8; this->actor.draw = func_80B4E324; func_80B49BD0(this); @@ -3167,8 +3125,8 @@ void func_80B4A168(Actor* thisx, GlobalContext* globalCtx) { void func_80B4A1B8(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnInvadepoh* this = THIS; - s32 sp2C = (this->actor.flags & 0x40) == 0x40; - s32 isTalking = func_800B84D0(&this->actor, globalCtx); + s32 sp2C = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); + s32 isTalking = Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); if (isTalking) { func_80151BB4(globalCtx, 5); @@ -3189,7 +3147,7 @@ void func_80B4A1B8(Actor* thisx, GlobalContext* globalCtx) { void func_80B4A2C0(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; @@ -3197,7 +3155,7 @@ void func_80B4A2C0(EnInvadepoh* this) { substruct->unk2C = 1500; this->actionTimer = Rand_S16Offset(200, 200); this->unk304 = this->actor.shape.rot.y; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); this->actionFunc = func_80B4A350; } @@ -3248,13 +3206,13 @@ void func_80B4A350(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4A570(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06002A8C, -10.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_ma1_Anim_002A8C, -10.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; substruct->unk30 = 0.1f; substruct->unk2C = 800; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); this->actionFunc = func_80B4A5E4; } @@ -3267,7 +3225,7 @@ void func_80B4A5E4(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4A614(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToLoop(&this->skelAnime, &D_06014088, 0.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_014088, 0.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; @@ -3292,14 +3250,14 @@ void func_80B4A67C(EnInvadepoh* this, GlobalContext* globalCtx) { if (this->unk378 == 0) { this->unk378 = func_80B45550(this, globalCtx, SQ(80.0f), -0xF); } - this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); } else { this->unk378 = 0; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); } - if (((this->actor.flags & 0x40) == 0x40) && + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 7.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->pathIndex == this->endPoint) { func_80B4A2C0(this); @@ -3310,7 +3268,7 @@ void func_80B4A7C0(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 2000; this->behaviorInfo.unk4C = 0; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, 0.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, 0.0f); this->actionFunc = func_80B4A81C; } @@ -3330,9 +3288,9 @@ void func_80B4A81C(EnInvadepoh* this, GlobalContext* globalCtx) { temp_v1 *= 0.7f; substruct->unk26.y = CLAMP(temp_v1, -0x1F40, 0x1F40); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { if (this->actor.textId == 0x332D) { - gSaveContext.weekEventReg[54] |= 0x10; + gSaveContext.save.weekEventReg[54] |= 0x10; this->actor.textId = 0x332E; } if (this->pathIndex == this->endPoint) { @@ -3349,13 +3307,13 @@ void func_80B4A9C8(Actor* thisx, GlobalContext* globalCtx) { s32 sp38; if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { - sp38 = gSaveContext.time; + sp38 = gSaveContext.save.time; this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); 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); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_014088, + this->jointTable, this->morphTable, 23); + 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; @@ -3371,8 +3329,8 @@ void func_80B4A9C8(Actor* thisx, GlobalContext* globalCtx) { func_80B43F0C(this); func_800B4AEC(globalCtx, &this->actor, 50.0f); func_80B4516C(this); - if (gSaveContext.weekEventReg[21] & 0x20) { - if (gSaveContext.weekEventReg[54] & 0x10) { + if (gSaveContext.save.weekEventReg[21] & 0x20) { + if (gSaveContext.save.weekEventReg[54] & 0x10) { this->actor.textId = 0x332E; } else { this->actor.textId = 0x332D; @@ -3386,7 +3344,7 @@ void func_80B4A9C8(Actor* thisx, GlobalContext* globalCtx) { void func_80B4AB8C(Actor* thisx, GlobalContext* globalCtx) { EnInvadepoh* this = THIS; - if ((gSaveContext.time < CLOCK_TIME(6, 0)) && (gSaveContext.time >= CLOCK_TIME(2, 15))) { + if ((gSaveContext.save.time < CLOCK_TIME(6, 0)) && (gSaveContext.save.time >= CLOCK_TIME(2, 15))) { this->actor.update = func_80B4ABDC; this->actor.draw = func_80B4E324; func_80B4A614(this); @@ -3396,8 +3354,8 @@ void func_80B4AB8C(Actor* thisx, GlobalContext* globalCtx) { void func_80B4ABDC(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnInvadepoh* this = THIS; - s32 sp2C = (this->actor.flags & 0x40) == 0x40; - s32 isTalking = func_800B84D0(&this->actor, globalCtx); + s32 sp2C = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); + s32 isTalking = Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); if (isTalking) { func_80151BB4(globalCtx, 5); @@ -3420,20 +3378,20 @@ void func_80B4ACDC(EnInvadepoh* this) { } void func_80B4ACF0(EnInvadepoh* this, GlobalContext* globalCtx) { - if (gSaveContext.weekEventReg[22] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { this->actor.draw = func_80B4E324; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); func_80B4AD3C(this); } } void func_80B4AD3C(EnInvadepoh* this) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; this->actionFunc = func_80B4AD60; } void func_80B4AD60(EnInvadepoh* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnInvadepoh_SetTextID(this, globalCtx, 0x3331); func_80B4ADB8(this); } else { @@ -3446,9 +3404,9 @@ void func_80B4ADB8(EnInvadepoh* this) { } void func_80B4ADCC(EnInvadepoh* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { if (this->textId == 0x3331) { - if (gSaveContext.weekEventReg[22] & 2) { + if (gSaveContext.save.weekEventReg[22] & 2) { EnInvadepoh_SetTextID(this, globalCtx, 0x3334); func_80151BB4(globalCtx, 0x1D); func_80151BB4(globalCtx, 5); @@ -3480,10 +3438,10 @@ void func_80B4AEDC(EnInvadepoh* this, GlobalContext* globalCtx) { } if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - gSaveContext.weekEventReg[22] |= 2; + gSaveContext.save.weekEventReg[22] |= 2; func_80B4AF80(this); } else { - func_800B8A1C(&this->actor, globalCtx, GI_MILK_BOTTLE, 2000.0f, 2000.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MILK_BOTTLE, 2000.0f, 2000.0f); } } @@ -3492,27 +3450,27 @@ void func_80B4AF80(EnInvadepoh* this) { } void func_80B4AF94(EnInvadepoh* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnInvadepoh_SetTextID(this, globalCtx, 0x3334); func_80151BB4(globalCtx, 0x1E); func_80151BB4(globalCtx, 0x1D); func_80151BB4(globalCtx, 5); func_80B4ADB8(this); } else { - func_800B85E0(&this->actor, globalCtx, 2000.0f, -1); + func_800B85E0(&this->actor, globalCtx, 2000.0f, EXCH_ITEM_MINUS1); } } void func_80B4B024(EnInvadepoh* this) { - this->actor.flags &= ~9; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); this->actionFunc = func_80B4B048; } void func_80B4B048(EnInvadepoh* this, GlobalContext* globalCtx) { if (globalCtx->msgCtx.unk120B1 == 0) { - if (globalCtx->msgCtx.unk11F22 == 0) { + if (globalCtx->msgCtx.msgMode == 0) { D_80B4E998 = 1; - } else if ((func_80152498(&globalCtx->msgCtx) == 6) || (func_80152498(&globalCtx->msgCtx) == 5)) { + } else if ((Message_GetState(&globalCtx->msgCtx) == 6) || (Message_GetState(&globalCtx->msgCtx) == 5)) { D_80B4E998 = 1; } } @@ -3525,14 +3483,14 @@ void func_80B4B0C4(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); func_80B44F58(); this->actor.update = func_80B4B218; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, - 23); - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_014088, + this->jointTable, this->morphTable, 23); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, 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); @@ -3545,7 +3503,7 @@ void func_80B4B218(Actor* thisx, GlobalContext* globalCtx) { s16 diff; EnInvadepoh* this = THIS; s16 temp_v1; - s32 sp38 = (this->actor.flags & 0x40) == 0x40; + s32 sp38 = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); Player* player; AlienBehaviorInfo* substruct = &this->behaviorInfo; @@ -3572,12 +3530,12 @@ void func_80B4B3DC(EnInvadepoh* this) { s32 pad; if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 7.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_MONKEY_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK); } } void func_80B4B430(EnInvadepoh* this) { - Animation_MorphToLoop(&this->skelAnime, &D_060021C8, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &gDogWalkAnim, -6.0f); this->actionTimer = Rand_S16Offset(50, 80); this->actionFunc = func_80B4B484; } @@ -3600,7 +3558,7 @@ void func_80B4B484(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B4B510(EnInvadepoh* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06001BD8, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &gDogRunAnim, -6.0f); this->actionTimer = Rand_S16Offset(50, 200); this->actionFunc = func_80B4B564; } @@ -3614,7 +3572,7 @@ void func_80B4B564(EnInvadepoh* this, GlobalContext* globalCtx) { if (this->unk3BC >= 0) { Math_Vec3s_ToVec3f(&sp28, &this->pathPoints[this->unk3BC]); - temp_f0 = Math3D_DistanceSquared(&this->actor.world.pos, &sp28); + temp_f0 = Math3D_Vec3fDistSq(&this->actor.world.pos, &sp28); if (temp_f0 < SQ(80.0f)) { this->actor.speedXZ *= 0.85f; } else if (temp_f0 < SQ(150.0f)) { @@ -3635,7 +3593,7 @@ void func_80B4B564(EnInvadepoh* this, GlobalContext* globalCtx) { this->actionTimer--; } else if (this->unk3BC >= 0) { if ((D_80B50348 == 0) && (Rand_ZeroOne() < 0.4f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_GROAN); } func_80B4B724(this); } else { @@ -3644,7 +3602,7 @@ void func_80B4B564(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B4B724(EnInvadepoh* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06000998, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDogBarkAnim, -6.0f); this->actionFunc = func_80B4B768; } @@ -3656,7 +3614,7 @@ void func_80B4B768(EnInvadepoh* this, GlobalContext* globalCtx) { 0x64); func_80B44E90(this, globalCtx); if (Animation_OnFrame(&this->skelAnime, 13.0f) || Animation_OnFrame(&this->skelAnime, 19.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SMALL_DOG_ANG_BARK); } if (this->animPlayFlag) { func_80B4B510(this); @@ -3664,7 +3622,7 @@ void func_80B4B768(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B4B820(EnInvadepoh* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001560, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gDogJumpAnim, -6.0f); this->actionFunc = func_80B4B864; } @@ -3682,10 +3640,10 @@ void func_80B4B8BC(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.objBankIndex = this->bankIndex; - 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); + Actor_SetObjectDependency(globalCtx, &this->actor); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gDogSkel, &gDogWalkAnim, this->jointTable, this->morphTable, + DOG_LIMB_MAX); + 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); @@ -3694,7 +3652,7 @@ void func_80B4B8BC(Actor* thisx, GlobalContext* globalCtx) { if (D_80B4E940 == 2) { this->actor.update = func_80B4BA84; this->actor.draw = func_80B4E660; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; func_80B4B430(this); } else if (D_80B4E940 == 1) { this->actor.update = func_80B4BA30; @@ -3711,7 +3669,7 @@ void func_80B4BA30(Actor* thisx, GlobalContext* globalCtx) { if (D_80B4E940 == 2) { this->actor.update = func_80B4BA84; this->actor.draw = func_80B4E660; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; func_80B4B430(this); } } @@ -3719,7 +3677,7 @@ void func_80B4BA30(Actor* thisx, GlobalContext* globalCtx) { void func_80B4BA84(Actor* thisx, GlobalContext* globalCtx) { EnInvadepoh* this = THIS; s32 temp_v0_3; - s32 sp34 = (this->actor.flags & 0x40) == 0x40; + s32 sp34 = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); s32 temp_v1_2; s32 sp2C; s32 temp_v0_2; @@ -3764,7 +3722,7 @@ void func_80B4BA84(Actor* thisx, GlobalContext* globalCtx) { void func_80B4BBE0(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToLoop(&this->skelAnime, &D_06016720, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma2_Anim_016720, -6.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; @@ -3790,16 +3748,16 @@ void func_80B4BC4C(EnInvadepoh* this, GlobalContext* globalCtx) { if (temp_v0 == 0) { this->xzPosAdjFactor = 40.0f; this->unk304 = -0x8000; - this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); } else if (temp_v0 < (temp_t6->endPoint - 1)) { this->xzPosAdjFactor = 40.0f; Math_ScaledStepToS(&this->unk304, -0x4800, 0xC8); - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); } else { Math_StepToF(&this->xzPosAdjFactor, 5.0f, 3.0f); Math_ScaledStepToS(&this->unk304, -0x8000, 0x12C); - this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); } temp_a0 = this->unk304 + temp_t6->actor.world.rot.y; this->actor.world.pos.x = (Math_SinS(temp_a0) * this->xzPosAdjFactor) + temp_t6->actor.world.pos.x; @@ -3808,7 +3766,7 @@ void func_80B4BC4C(EnInvadepoh* this, GlobalContext* globalCtx) { func_800B4AEC(globalCtx, &this->actor, 50.0f); func_80B4516C(this); Math_StepToS(&this->behaviorInfo.unk4C, 0xBB8, 0x1F5); - if (Math3D_DistanceSquared(&this->actor.prevPos, &this->actor.world.pos) > SQ(0.01f)) { + if (Math3D_Vec3fDistSq(&this->actor.prevPos, &this->actor.world.pos) > SQ(0.01f)) { Math_SmoothStepToS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&this->actor.prevPos, &this->actor.world.pos), 3, this->behaviorInfo.unk4C, 0x1F4); } @@ -3831,11 +3789,11 @@ void func_80B4BC4C(EnInvadepoh* this, GlobalContext* globalCtx) { } } - if (((this->actor.flags & 0x40) == 0x40) && + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } - if (gSaveContext.time > CLOCK_TIME(20, 15)) { + if (gSaveContext.save.time > CLOCK_TIME(20, 15)) { Actor_MarkForDeath(&this->actor); } else if ((temp_t6 != NULL) && (temp_t6->actionFunc == func_80B4CB0C)) { func_80B4C1BC(this); @@ -3845,7 +3803,7 @@ void func_80B4BC4C(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4BFFC(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 2000; - Animation_MorphToLoop(&this->skelAnime, &D_0600A174, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma2_Anim_00A174, -6.0f); this->behaviorInfo.unk4C = 0; this->actionFunc = func_80B4C058; } @@ -3869,7 +3827,7 @@ void func_80B4C058(EnInvadepoh* this, GlobalContext* globalCtx) { substruct->unk26.y = CLAMP(temp_v1, -0x1F40, 0x1F40); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { func_80B4BBE0(this); } } @@ -3877,7 +3835,7 @@ void func_80B4C058(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4C1BC(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 2000; - Animation_MorphToLoop(&this->skelAnime, &D_0600A174, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma2_Anim_00A174, -6.0f); this->behaviorInfo.unk4C = 0; this->actionFunc = func_80B4C218; } @@ -3912,14 +3870,14 @@ void func_80B4C3A0(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { s32 pad[2]; - s32 currentTime = gSaveContext.time; + s32 currentTime = gSaveContext.save.time; this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); 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); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma2_Skel_015C28, &object_ma2_Anim_016720, + this->jointTable, this->morphTable, 22); + 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; @@ -3948,7 +3906,7 @@ void func_80B4C3A0(Actor* thisx, GlobalContext* globalCtx) { void func_80B4C568(Actor* thisx, GlobalContext* globalCtx) { EnInvadepoh* this = THIS; - if ((gSaveContext.time >= 0xD573) && (gSaveContext.time < CLOCK_TIME(20, 15))) { + if ((gSaveContext.save.time >= 0xD573) && (gSaveContext.save.time < CLOCK_TIME(20, 15))) { this->actor.update = func_80B4C5C0; this->actor.draw = func_80B4E7BC; func_80B4BBE0(this); @@ -3958,8 +3916,8 @@ void func_80B4C568(Actor* thisx, GlobalContext* globalCtx) { void func_80B4C5C0(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnInvadepoh* this = THIS; - s32 sp2C = (this->actor.flags & 0x40) == 0x40; - s32 isTalking = func_800B84D0(&this->actor, globalCtx); + s32 sp2C = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); + s32 isTalking = Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); if (isTalking) { func_80151BB4(globalCtx, 6); @@ -3980,7 +3938,7 @@ void func_80B4C5C0(Actor* thisx, GlobalContext* globalCtx) { void func_80B4C6C8(EnInvadepoh* this) { AlienBehaviorInfo* substruct = &this->behaviorInfo; - Animation_MorphToLoop(&this->skelAnime, &D_06014088, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_014088, -10.0f); substruct->unk26.x = 0; substruct->unk26.y = 0; substruct->unk26.z = 0; @@ -3999,21 +3957,14 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { Vec3f sp4C; Vec3f sp40; s16 diff; - s8 temp_v1; + s16 pad; s16 sp3A; - s8 temp_v0; + s16 pad2; func_80B44700(this); func_80B44EFC(this, globalCtx); func_80B43E6C(this, 6, 2000, 100); - if (1) {} - temp_v1 = this->pathIndex; - temp_v0 = this->endPoint; - phi_a2 = temp_v0 - 1; - if (temp_v1 < temp_v0) { - phi_a2 = temp_v1; - } else if (temp_v1_3) { - } + phi_a2 = ((this->pathIndex < this->endPoint) ? this->pathIndex : this->endPoint - 1); Math_Vec3s_ToVec3f(&sp4C, &this->pathPoints[phi_a2]); Math_Vec3s_ToVec3f(&sp40, &this->pathPoints[phi_a2 + 1]); @@ -4027,10 +3978,10 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { } } - this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); } else { this->unk378 = 0; - this->actor.flags |= (0x8 | 0x1); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); } temp_v1_3 = globalCtx->gameplayFrames % 128; @@ -4052,9 +4003,9 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { substruct->unk26.y = CLAMP(temp_v1_4, -8000, 8000); } - if (((this->actor.flags & 0x40) == 0x40) && + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40) && (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 7.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } if (this->clockTime >= 0.9999f) { @@ -4070,7 +4021,7 @@ void func_80B4C730(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4CAB0(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 4000; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->behaviorInfo.unk4C = 0; this->actionFunc = func_80B4CB0C; } @@ -4091,7 +4042,7 @@ void func_80B4CB0C(EnInvadepoh* this, GlobalContext* globalCtx) { temp_v1 = diff; temp_v1 *= 0.7f; substruct->unk26.y = CLAMP(temp_v1, -0x1F40, 0x1F40); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { func_80B4C6C8(this); } } @@ -4099,7 +4050,7 @@ void func_80B4CB0C(EnInvadepoh* this, GlobalContext* globalCtx) { void func_80B4CC70(EnInvadepoh* this) { this->behaviorInfo.unk30 = 0.08f; this->behaviorInfo.unk2C = 2000; - Animation_MorphToLoop(&this->skelAnime, &D_06009E58, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_ma1_Anim_009E58, -10.0f); this->behaviorInfo.unk4C = 0; this->actionFunc = func_80B4CCCC; } @@ -4133,14 +4084,14 @@ void func_80B4CE54(Actor* thisx, GlobalContext* globalCtx) { s32 sp38; if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { - sp38 = gSaveContext.time; + sp38 = gSaveContext.save.time; this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); 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); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, &object_ma1_Anim_014088, + this->jointTable, this->morphTable, 23); + 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); @@ -4164,7 +4115,7 @@ void func_80B4CE54(Actor* thisx, GlobalContext* globalCtx) { void func_80B4CFFC(Actor* thisx, GlobalContext* globalCtx) { EnInvadepoh* this = THIS; - if ((gSaveContext.time >= CLOCK_TIME(20, 0)) && (gSaveContext.time < 0xD7E1)) { + if ((gSaveContext.save.time >= CLOCK_TIME(20, 0)) && (gSaveContext.save.time < 0xD7E1)) { this->actor.update = func_80B4D054; this->actor.draw = func_80B4E324; func_80B4C6C8(this); @@ -4174,8 +4125,8 @@ void func_80B4CFFC(Actor* thisx, GlobalContext* globalCtx) { void func_80B4D054(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnInvadepoh* this = THIS; - s32 sp2C = (this->actor.flags & 0x40) == 0x40; - s32 isTalking = func_800B84D0(&this->actor, globalCtx); + s32 sp2C = CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_40); + s32 isTalking = Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); if (isTalking) { func_80151BB4(globalCtx, 5); @@ -4198,7 +4149,7 @@ void func_80B4D15C(EnInvadepoh* this) { s32 temp_v1 = this->actor.params & 7; unkstruct80B4EE0C* temp_v0; - Animation_PlayLoop(&this->skelAnime, &D_06001674); + Animation_PlayLoop(&this->skelAnime, &object_uch_Anim_001674); this->skelAnime.curFrame = ((this->actor.params & 7) * this->skelAnime.endFrame) * 0.25f; this->alienAlpha = 255; this->actor.draw = func_80B4DB14; @@ -4250,7 +4201,7 @@ void func_80B4D290(EnInvadepoh* this, GlobalContext* globalCtx) { } void func_80B4D3E4(EnInvadepoh* this) { - Animation_PlayLoop(&this->skelAnime, &D_06001674); + Animation_PlayLoop(&this->skelAnime, &object_uch_Anim_001674); this->skelAnime.curFrame = (this->actor.params & 7) * this->skelAnime.endFrame * 0.25f; this->alienAlpha = 255; this->actor.draw = NULL; @@ -4324,11 +4275,11 @@ void func_80B4D670(Actor* thisx, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { invadepohType = this->actor.params & 7; this->actor.objBankIndex = this->bankIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); func_80B45080(); this->actor.update = func_80B4D760; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004E50, &D_06001674, this->jointTable, this->morphTable, - 14); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_uch_Skel_004E50, &object_uch_Anim_001674, + this->jointTable, this->morphTable, 14); if (invadepohType < 3) { func_80B453F4(this, globalCtx, invadepohType); func_80B4D15C(this); @@ -4363,7 +4314,7 @@ void func_80B4D7B8(GlobalContext* globalCtx) { temp_v0 = globalCtx->gameplayFrames; temp_s5 = (temp_v0 + ((0x10 * i) & 0xFFU)) & 0x7F; temp_s6 = (u8)(temp_v0 * -0xF); - Matrix_InsertTranslation(phi_s2->unk4.x, phi_s2->unk4.y, phi_s2->unk4.z, MTXMODE_NEW); + Matrix_Translate(phi_s2->unk4.x, phi_s2->unk4.y, phi_s2->unk4.z, MTXMODE_NEW); Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 170, phi_s2->unk2); @@ -4373,7 +4324,7 @@ void func_80B4D7B8(GlobalContext* globalCtx) { Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, temp_s5, 0, 0x20, 0x40, 1, 0, temp_s6, 0x20, 0x40)); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, &D_0402E510); + gSPDisplayList(POLY_XLU_DISP++, &gameplay_keep_DL_02E510); } } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -4392,22 +4343,22 @@ void func_80B4D9F4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* EnInvadepoh* this = THIS; if ((limbIndex == 12) && (this->alienBeamAlpha != 0)) { - Matrix_StatePush(); - Matrix_InsertZRotation_s(-0x53ED, MTXMODE_APPLY); - Matrix_RotateY(-0x3830, MTXMODE_APPLY); + Matrix_Push(); + Matrix_RotateZS(-0x53ED, MTXMODE_APPLY); + Matrix_RotateYS(-0x3830, MTXMODE_APPLY); Matrix_Scale(1.0f, 1.0f, 1.5f, MTXMODE_APPLY); - Matrix_CopyCurrentState(&D_80B502A0); - Matrix_StatePop(); + Matrix_Get(&D_80B502A0); + Matrix_Pop(); } else if ((limbIndex == 13) && (this->alienBeamAlpha != 0)) { - Matrix_StatePush(); - Matrix_InsertZRotation_s(-0x53ED, MTXMODE_APPLY); - Matrix_RotateY(-0x47D0, MTXMODE_APPLY); + Matrix_Push(); + Matrix_RotateZS(-0x53ED, MTXMODE_APPLY); + Matrix_RotateYS(-0x47D0, MTXMODE_APPLY); Matrix_Scale(1.0f, 1.0f, 1.5f, MTXMODE_APPLY); - Matrix_CopyCurrentState(&D_80B502E0); - Matrix_StatePop(); + Matrix_Get(&D_80B502E0); + Matrix_Pop(); } if (limbIndex == 11) { - Matrix_MultiplyVector3fByState(&D_80B4EE24, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80B4EE24, &this->actor.focus.pos); } } @@ -4418,7 +4369,7 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(spCC); func_8012C2DC(spCC); - Matrix_StatePush(); + Matrix_Push(); if (this->drawAlien) { Gfx* new_var6; Gfx* spBC; @@ -4448,24 +4399,24 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { gDPPipeSync(spBC++); gDPSetPrimColor(spBC++, 0, 255, 240, 180, 100, 60); gDPSetEnvColor(spBC++, 255, 255, 255, this->alienBeamAlpha * (150.0f / 255.0f)); - Matrix_InsertMatrix(&D_80B502A0, MTXMODE_NEW); + Matrix_Mult(&D_80B502A0, MTXMODE_NEW); gSPMatrix(spBC++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(spBC++, D_06000080); - Matrix_InsertMatrix(&D_80B502E0, MTXMODE_NEW); + gSPDisplayList(spBC++, object_uch_DL_000080); + Matrix_Mult(&D_80B502E0, MTXMODE_NEW); gSPMatrix(spBC++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(spBC++, D_06000080); + gSPDisplayList(spBC++, object_uch_DL_000080); spB8->polyXlu.p = spBC; } } if (this->drawAlienDeathEffect) { - Matrix_SetStateRotationAndTranslation(this->actor.world.pos.x, this->actor.world.pos.y + 68.0f, - this->actor.world.pos.z, &this->actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y + 68.0f, this->actor.world.pos.z, + &this->actor.shape.rot); Matrix_Scale(this->alienDeathEffectScale.x, this->alienDeathEffectScale.y, this->alienDeathEffectScale.z, MTXMODE_APPLY); gSPMatrix(spCC->polyXlu.p++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(spCC->polyXlu.p++, D_06000720); + gSPDisplayList(spCC->polyXlu.p++, object_uch_DL_000720); } if (this->drawAlien) { @@ -4477,21 +4428,21 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { gfx = sp6C->polyXlu.p; gfx = func_8012C868(gfx); - gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); + gDPSetDither(gfx++, G_CD_NOISE); 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_GetStateTranslationAndScaledZ(60.0f, &sp80); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_NEW); + Matrix_MultVecZ(60.0f, &sp80); sp74.x = thisx->world.pos.x + sp80.x; sp74.y = thisx->world.pos.y + sp80.y + 68.0f; sp74.z = thisx->world.pos.z + sp80.z; - Matrix_InsertTranslation(sp74.x, sp74.y, sp74.z, MTXMODE_NEW); + Matrix_Translate(sp74.x, sp74.y, sp74.z, MTXMODE_NEW); Matrix_Scale(0.25f, 0.25f, 0.25f, MTXMODE_APPLY); alpha2 = this->alienAlpha * (100.0f / 255.0f); - gSPDisplayList(gfx++, D_04029CB0); + gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); gDPSetPrimColor(gfx++, 0, 0, 240, 180, 100, alpha2); gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gfx++, D_04029CF0); + gSPDisplayList(gfx++, gameplay_keep_DL_029CF0); sp6C->polyXlu.p = gfx; if ((this->alienAlpha > 128) && func_80B456A8(globalCtx, &sp74)) { func_800F9824(globalCtx, &globalCtx->envCtx, &globalCtx->view, globalCtx->state.gfxCtx, sp74, 10.0f, 9.0f, @@ -4499,7 +4450,7 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { } } - Matrix_StatePop(); + Matrix_Pop(); CLOSE_DISPS(spCC); } @@ -4548,10 +4499,10 @@ void func_80B4E2AC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* if (limbIndex == 19) { OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_060003B0); + gSPDisplayList(POLY_OPA_DISP++, object_ma1_DL_0003B0); CLOSE_DISPS(globalCtx->state.gfxCtx); } else if (limbIndex == 14) { - Matrix_MultiplyVector3fByState(&D_80B4EE30, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80B4EE30, &this->actor.focus.pos); } } @@ -4571,22 +4522,22 @@ void func_80B4E3F0(Actor* thisx, GlobalContext* globalCtx) { s32 pad[2]; Vec3f sp5C; - Matrix_StatePush(); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_NEW); - Matrix_GetStateTranslationAndScaledZ(200.0f, &sp5C); - Matrix_StatePop(); + Matrix_Push(); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_NEW); + Matrix_MultVecZ(200.0f, &sp5C); + Matrix_Pop(); 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_InsertZRotation_s(((EnInvadepoh*)thisx)->unk304, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateZS(((EnInvadepoh*)thisx)->unk304, MTXMODE_APPLY); 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++, 0xFF, 0x80, 255, 255, 0, 180); gDPSetEnvColor(POLY_XLU_DISP++, 255, 50, 0, 0); - gSPDisplayList(POLY_XLU_DISP++, D_04023210); + gSPDisplayList(POLY_XLU_DISP++, gOwlStatueWhiteFlashDL); if (func_80B456A8(globalCtx, &sp5C)) { func_800F9824(globalCtx, &globalCtx->envCtx, &globalCtx->view, globalCtx->state.gfxCtx, sp5C, 20.0f, 9.0f, 0, 0); @@ -4596,7 +4547,8 @@ void func_80B4E3F0(Actor* thisx, GlobalContext* globalCtx) { } s32 func_80B4E5B0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { - if ((limbIndex == 5) || (limbIndex == 6) || (limbIndex == 7)) { + if ((limbIndex == DOG_LIMB_HEAD) || (limbIndex == DOG_LIMB_RIGHT_FACE_HAIR) || + (limbIndex == DOG_LIMB_LEFT_FACE_HAIR)) { EnInvadepoh* this = THIS; rot->x += this->behaviorInfo.unk20.x; @@ -4610,8 +4562,8 @@ s32 func_80B4E5B0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p void func_80B4E61C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnInvadepoh* this = THIS; - if (limbIndex == 5) { - Matrix_GetStateTranslationAndScaledY(20.0f, &this->actor.focus.pos); + if (limbIndex == DOG_LIMB_HEAD) { + Matrix_MultVecY(20.0f, &this->actor.focus.pos); } } @@ -4645,7 +4597,7 @@ void func_80B4E784(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* EnInvadepoh* this = THIS; if (limbIndex == 9) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } } diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c index 5d0b78a23..5696764dd 100644 --- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c +++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.c @@ -1,6 +1,12 @@ +/* + * File: z_en_invadepoh_demo.c + * Overlay: ovl_En_Invadepoh_Demo + * Description: + */ + #include "z_en_invadepoh_demo.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnInvadepohDemo*)thisx) @@ -62,7 +68,7 @@ static InitChainEntry D_80C1AAB0[] = { ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_CONTINUE), ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), - ICHAIN_F32(minVelocityY, -100, ICHAIN_CONTINUE), + ICHAIN_F32(terminalVelocity, -100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 800, ICHAIN_STOP), }; 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 9935eb67a..360927533 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 @@ -1,3 +1,9 @@ +/* + * File: z_en_invisible_ruppe.c + * Overlay: ovl_En_Invisible_Ruppe + * Description: Invisible Rupee + */ + #include "z_en_invisible_ruppe.h" #define FLAGS 0x00000000 @@ -8,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, @@ -24,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) { + Flags_SetSwitch(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 d74a917fb..9b60a41dd 100644 --- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -1,6 +1,15 @@ -#include "z_en_ishi.h" +/* + * File: z_en_ishi.c + * Overlay: ovl_En_Ishi + * Description: Liftable rocks and silver boulders + */ -#define FLAGS 0x00800010 +#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 (ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnIshi*)thisx) @@ -8,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, @@ -28,109 +54,705 @@ 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(terminalVelocity, -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(terminalVelocity, -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, GAMEPLAY_FIELD_KEEP, 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_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecY(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_Pop(); + } + } +} -#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.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } +} -#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 = ActorShadow_DrawCircle; + 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* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnIshi* this = THIS; + + 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 &= ~ACTOR_FLAG_10; + 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); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, D_8095F7AC[sp38]); + if (ENISHI_GET_2(&this->actor)) { + func_8095E204(this, globalCtx); + } + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + 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); + SoundSource_PlaySfxAtFixedWorldPos(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) { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 80.0f, 20.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 50.0f, 10.0f); + } + } + } +} + +void func_8095E934(EnIshi* this) { + this->actionFunc = func_8095E95C; + this->actor.room = -1; + this->actor.flags |= ACTOR_FLAG_10; +} + +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) { + Flags_SetSwitch(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_UpdatePos(&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)) { + SoundSource_PlaySfxAtFixedWorldPos(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.terminalVelocity = -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; + + SoundSource_PlaySfxAtFixedWorldPos(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_UpdatePos(&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 |= ACTOR_FLAG_10; + 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); + SoundSource_PlaySfxAtFixedWorldPos(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))) { + Gfx_DrawDListOpa(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) { + Gfx_DrawDListOpa(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_Ja/z_en_ja.c b/src/overlays/actors/ovl_En_Ja/z_en_ja.c index 8fd60081a..5659e5ba9 100644 --- a/src/overlays/actors/ovl_En_Ja/z_en_ja.c +++ b/src/overlays/actors/ovl_En_Ja/z_en_ja.c @@ -1,6 +1,13 @@ -#include "z_en_ja.h" +/* + * File: z_en_ja.c + * Overlay: ovl_En_Ja + * Description: Juggler + */ -#define FLAGS 0x00000019 +#include "z_en_ja.h" +#include "objects/object_boj/object_boj.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnJa*)thisx) @@ -11,8 +18,38 @@ void EnJa_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BC21A8(EnJa* this, GlobalContext* globalCtx); void func_80BC22F4(EnJa* this, GlobalContext* globalCtx); +void func_80BC2EA4(EnJa* this); +void func_80BC32D8(EnJa* this, GlobalContext* globalCtx); +void func_80BC3594(EnJa* this, GlobalContext* globalCtx); + +static u8 D_80BC35F0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x05 - 0x04), + /* 0x04 */ SCHEDULE_CMD_RET_NONE(), + /* 0x05 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(6, 0, 18, 0, 0x13 - 0x0B), + /* 0x0B */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x12 - 0x0F), + /* 0x0F */ SCHEDULE_CMD_RET_VAL_L(2), + /* 0x12 */ SCHEDULE_CMD_RET_NONE(), + /* 0x13 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x1A - 0x17), + /* 0x17 */ SCHEDULE_CMD_RET_VAL_L(1), + /* 0x1A */ SCHEDULE_CMD_RET_NONE(), +}; + +s32 D_80BC360C[] = { + 0x0E29370C, 0x170E2938, 0x0C180E29, 0x390C170E, 0x293A0C09, 0x0000180E, 0x293B0C09, 0x00001000, +}; + +s32 D_80BC362C[] = { + 0x0E29400C, 0x170E2941, 0x0C180E29, 0x420C170E, 0x29430C09, 0x0000180E, 0x293B0C09, 0x00001000, +}; + +s32 D_80BC364C[] = { + 0x0E293C0C, 0x170E293D, 0x0C180E29, 0x3E0C170E, 0x293F0C09, 0x0000180E, 0x293B0C09, 0x00001000, +}; + +s32 D_80BC366C[] = { + 0x0E29440C, 0x170E2945, 0x0C180E29, 0x460C170E, 0x29470C09, 0x0000180E, 0x293B0C09, 0x00001000, +}; -#if 0 const ActorInit En_Ja_InitVars = { ACTOR_EN_JA, ACTORCAT_NPC, @@ -25,81 +62,707 @@ const ActorInit En_Ja_InitVars = { (ActorFunc)EnJa_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BC36DC = { - { 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, }, +Vec3f D_80BC36AC = { -10.0f, 56.0f, 25.0f }; +Vec3f D_80BC36B8 = { 0.0f, 60.0f, 20.0f }; +Vec3f D_80BC36C4 = { 10.0f, 60.0f, 25.0f }; +Vec3f D_80BC36D0 = { 0.0f, 58.0f, 20.0f }; + +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, + }, { 12, 64, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BC3708 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_boj_Anim_002734, 1.0f, 0, -1, 0, 0 }, { &object_boj_Anim_0033B0, 1.0f, 0, -1, 0, 0 }, + { &object_boj_Anim_002734, 1.0f, 0, -1, 0, -4 }, { &object_boj_Anim_0033B0, 1.0f, 0, -1, 0, -4 }, + { &object_boj_Anim_004078, 1.0f, 0, -1, 0, 0 }, { &object_boj_Anim_005CE4, 1.0f, 0, -1, 0, 0 }, +}; -extern ColliderCylinderInit D_80BC36DC; -extern CollisionCheckInfoInit2 D_80BC3708; +void func_80BC1900(EnJa* this) { + this->skelAnime.playSpeed = this->unk_344; + SkelAnime_Update(&this->skelAnime); +} -extern UNK_TYPE D_0600BA30; -extern UNK_TYPE D_0600BCC8; -extern UNK_TYPE D_0600C240; +s32 func_80BC192C(EnJa* this, s32 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1900.s") + if (arg1 != this->unk_36C) { + this->unk_36C = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->unk_344 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC192C.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1984.s") +void func_80BC1984(EnJa* this, GlobalContext* globalCtx) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC19FC.s") + Collider_UpdateCylinder(&this->actor, &this->collider); + this->collider.dim.height = (s16)fabsf(this->actor.focus.pos.y - this->actor.world.pos.y) + 5; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1A68.s") +s32 func_80BC19FC(EnJa* this, GlobalContext* globalCtx) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1AE0.s") + if ((this->unk_340 & 7) && Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_340, 0, 7); + this->actionFunc = func_80BC22F4; + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1B50.s") +void func_80BC1A68(EnJa* this) { + if (DECR(this->unk_360) == 0) { + this->unk_362++; + if (this->unk_362 >= 4) { + this->unk_360 = Rand_S16Offset(30, 30); + this->unk_362 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1B60.s") +s32 func_80BC1AE0(EnJa* this, GlobalContext* globalCtx) { + Actor* ja = SubS_FindNearestActor(&this->actor, globalCtx, ACTORCAT_NPC, ACTOR_EN_JA); + Vec3f sp30; + Vec3f sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1D70.s") + if (ja != NULL) { + this->actor.child = ja; + Math_Vec3f_Copy(&sp24, &ja->world.pos); + Math_Vec3f_Copy(&sp30, &this->actor.world.pos); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp30, &sp24); + } else { + this->actor.child = NULL; + } + return this->actor.child; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1E40.s") +Player* func_80BC1B50(EnJa* this, GlobalContext* globalCtx) { + return GET_PLAYER(globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC1FC8.s") +s32 func_80BC1B60(EnJa* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC203C.s") + Math_Vec3f_Copy(&sp40, &this->unk_1D8.player->actor.world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); + Math_ApproachS(&this->unk_356, (sp32 - this->unk_35A) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_356 = CLAMP(this->unk_356, -0x1FFE, 0x1FFE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC20D0.s") + Math_ApproachS(&this->unk_35A, (sp32 - this->unk_356) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_35A = CLAMP(this->unk_35A, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC213C.s") + if (this->unk_1D8.player->actor.id == ACTOR_PLAYER) { + sp40.y = this->unk_1D8.player->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_1D8.player->actor.focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC2150.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + Math_ApproachS(&this->unk_354, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_358, 4, 0x2AA8); + this->unk_354 = CLAMP(this->unk_354, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC21A8.s") + Math_ApproachS(&this->unk_358, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_354, 4, 0x2AA8); + this->unk_358 = CLAMP(this->unk_358, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC2274.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC22F4.s") +s32 func_80BC1D70(EnJa* this, GlobalContext* globalCtx) { + if (this->unk_340 & 8) { + this->unk_1D8.player = func_80BC1B50(this, globalCtx); + if (this->unk_1D8.player != NULL) { + func_80BC1B60(this, globalCtx); + } + this->unk_340 &= ~0x10; + this->unk_340 |= 0x20; + } else if (this->unk_340 & 0x20) { + this->unk_340 &= ~0x20; + this->unk_354 = 0; + this->unk_356 = 0; + this->unk_358 = 0; + this->unk_35A = 0; + this->unk_35E = 20; + } else if (DECR(this->unk_35E) == 0) { + this->unk_340 |= 0x10; + this->unk_35E = 20; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/EnJa_Init.s") +void func_80BC1E40(EnJa* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp20 = Message_GetState(&globalCtx->msgCtx); + f32 phi_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/EnJa_Destroy.s") + if (((globalCtx->msgCtx.currentTextId < 0xFF) || (globalCtx->msgCtx.currentTextId > 0x200)) && (sp20 == 3) && + (this->unk_374 == 3) && (&this->actor == player->targetActor)) { + if ((globalCtx->state.frames % 2) == 0) { + if (this->unk_348 != 0.0f) { + this->unk_348 = 0.0f; + } else { + this->unk_348 = 1.0f; + } + } + } else { + this->unk_348 = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/EnJa_Update.s") + this->unk_34C += (this->unk_348 != 0.0f) ? 60.0f : -60.0f; + this->unk_34C = CLAMP(this->unk_34C, 0.0f, 120.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC25E0.s") + Matrix_Translate(this->unk_34C, 0.0f, 0.0f, MTXMODE_APPLY); + this->unk_374 = sp20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC2620.s") +s32 func_80BC1FC8(EnJa* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC2B30.s") + if (func_80BC1AE0(this, globalCtx)) { + SubS_UpdateFlags(&this->unk_340, 3, 7); + this->unk_340 |= 0x10; + func_80BC192C(this, 5); + func_80BC2EA4(this); + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/EnJa_Draw.s") +s32 func_80BC203C(EnJa* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC2EA4.s") + if (func_80BC1AE0(this, globalCtx)) { + if (ENJA_GET_3(&this->actor) == 0) { + func_80BC192C(this, 1); + } else { + func_80BC192C(this, 4); + } + SubS_UpdateFlags(&this->unk_340, 3, 7); + this->actor.shape.shadowDraw = NULL; + this->unk_340 |= 0x50; + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC3154.s") +s32 func_80BC20D0(EnJa* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC32D8.s") + this->unk_340 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC33C0.s") + switch (arg2->result) { + case 1: + ret = func_80BC1FC8(this, globalCtx, arg2); + if (ret == 1) {} + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ja/func_80BC3594.s") + case 2: + ret = func_80BC203C(this, globalCtx, arg2); + break; + } + return ret; +} + +s32 func_80BC213C(EnJa* this, GlobalContext* globalCtx) { + return true; +} + +void func_80BC2150(EnJa* this, GlobalContext* globalCtx) { + if ((this->unk_1D8.unk_00 == 1) || (this->unk_1D8.unk_00 == 2)) { + func_80BC213C(this, globalCtx); + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 4, 0x1554); +} + +void func_80BC21A8(EnJa* this, GlobalContext* globalCtx) { + ScheduleResult sp18; + + this->unk_35C = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BC35F0, &sp18) || + ((this->unk_1D8.unk_00 != sp18.result) && !func_80BC20D0(this, globalCtx, &sp18))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp18.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_1D8.unk_00 = sp18.result; + func_80BC2150(this, globalCtx); +} + +s32* func_80BC2274(EnJa* this, GlobalContext* globalCtx) { + switch (this->unk_1D8.unk_00) { + case 1: + if (ENJA_GET_3(&this->actor) == 0) { + return D_80BC360C; + } + return D_80BC364C; + + case 2: + if (ENJA_GET_3(&this->actor) == 0) { + return D_80BC362C; + } + return D_80BC366C; + } + return D_80BC360C; +} + +void func_80BC22F4(EnJa* this, GlobalContext* globalCtx) { + if (func_8010BF58(&this->actor, globalCtx, func_80BC2274(this, globalCtx), this->unk_368, &this->unk_1D8.unk_04)) { + this->unk_340 &= ~8; + SubS_UpdateFlags(&this->unk_340, 3, 7); + this->unk_1D8.unk_04 = 0; + this->unk_340 |= 0x10; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = func_80BC21A8; + } +} + +void EnJa_Init(Actor* thisx, GlobalContext* globalCtx) { + EnJa* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_boj_Skel_00C240, NULL, this->jointTable, this->morphTable, + 16); + this->unk_36C = -1; + func_80BC192C(this, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->actor.targetMode = 0; + this->actor.uncullZoneForward = 800.0f; + this->actor.gravity = 0.0f; + SubS_UpdateFlags(&this->unk_340, 0, 7); + this->unk_340 |= 0x10; + this->unk_1D8.unk_00 = 0; + this->unk_368 = NULL; + this->actionFunc = func_80BC21A8; +} + +void EnJa_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnJa* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnJa_Update(Actor* thisx, GlobalContext* globalCtx) { + EnJa* this = THIS; + f32 height; + f32 radius; + + func_80BC19FC(this, globalCtx); + + this->actionFunc(this, globalCtx); + + if (this->unk_1D8.unk_00 != 0) { + func_80BC1900(this); + func_80BC1A68(this); + func_80BC1D70(this, globalCtx); + + radius = this->collider.dim.radius + 30; + height = this->collider.dim.height + 10; + func_8013C964(&this->actor, globalCtx, radius, height, EXCH_ITEM_NONE, this->unk_340 & 7); + + if (this->unk_1D8.unk_00 != 2) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } + func_80BC1984(this, globalCtx); + } + + if (this->unk_1D8.unk_00 == 1) { + func_80BC32D8(this, globalCtx); + } +} + +s32 EnJa_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnJa* this = THIS; + + if (limbIndex == 15) { + func_80BC1E40(this, globalCtx); + } + return false; +} + +void EnJa_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80BC3774 = { -87.0f, 444.0f, -49.0f }; + static Vec3f D_80BC3780 = { 600.0f, 0.0f, 0.0f }; + static Vec3f D_80BC378C = { 400.0f, 0.0f, -400.0f }; + static Vec3f D_80BC3798 = { 400.0, 0.0f, 400.0f }; + static Vec3s D_80BC37A4 = { 0x7770, -0x4BC, -0x251C }; + s32 pad; + EnJa* this = THIS; + s32 pad2; + + if (limbIndex == 15) { + Matrix_MultVec3f(&D_80BC3780, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } else if ((this->unk_340 & 0x40) && (limbIndex == 11)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_TranslateRotateZYX(&D_80BC3774, &D_80BC37A4); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_00BA30); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (this->unk_1D8.unk_00 == 1) { + if ((limbIndex == 11) && (((this->skelAnime.curFrame >= 0.0f) && (this->skelAnime.curFrame <= 6.0f)) || + ((this->skelAnime.curFrame >= 35.0f) && (this->skelAnime.curFrame <= 47.0f)))) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_Translate(D_80BC378C.x, D_80BC378C.y, D_80BC378C.z, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + + gDPPipeSync(POLY_OPA_DISP++); + + switch (this->unk_364) { + case 0: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 1: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 0, 0, 255); + break; + + case 2: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 3: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255); + break; + + default: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + break; + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_00BCC8); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (limbIndex == 14) { + if ((this->skelAnime.curFrame >= 0.0f) && (this->skelAnime.curFrame <= 18.0f)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + + Matrix_Translate(D_80BC3798.x, D_80BC3798.y, D_80BC3798.z, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + + gDPPipeSync(POLY_OPA_DISP++); + + switch (this->unk_366) { + case 0: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 1: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 0, 0, 255); + break; + + case 2: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 3: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255); + break; + + default: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + break; + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_00BCC8); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } + } +} + +void EnJa_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnJa* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (this->unk_340 & 0x10) { + stepRot = false; + } else { + stepRot = true; + } + + if (this->unk_340 & 0x20) { + overrideRot = true; + } else { + overrideRot = false; + } + + if (!stepRot) { + overrideRot = false; + } + + if (limbIndex != 8) { + if (limbIndex == 15) { + SubS_UpdateLimb(this->unk_354 + this->unk_358 + 0x4000, + this->unk_356 + this->unk_35A + this->actor.shape.rot.y + 0x4000, &this->unk_1EC, + &this->unk_274, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(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); + Matrix_RotateYS(this->unk_274.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_274.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_274.z, MTXMODE_APPLY); + Matrix_Push(); + } + } else { + SubS_UpdateLimb(this->unk_358 + 0x4000, this->unk_35A + this->actor.shape.rot.y + 0x4000, &this->unk_1F8, + &this->unk_27A, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_1F8.x, this->unk_1F8.y, this->unk_1F8.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_27A.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_27A.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_27A.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnJa_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Color_RGBA8 D_80BC37AC[] = { + { 200, 0, 80, 0 }, + { 0, 130, 220, 0 }, + }; + static Color_RGBA8 D_80BC37B4[] = { + { 255, 255, 255, 0 }, + { 255, 255, 255, 0 }, + }; + static TexturePtr D_80BC37BC[] = { + object_boj_Tex_0062B0, + object_boj_Tex_0063B0, + object_boj_Tex_0064B0, + object_boj_Tex_0063B0, + }; + s32 pad; + EnJa* this = THIS; + s32 phi_t2; + + if (ENJA_GET_3(&this->actor) == 0) { + phi_t2 = 0; + } else { + phi_t2 = 1; + } + + if (this->unk_1D8.unk_00 != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, + Gfx_EnvColor(globalCtx->state.gfxCtx, D_80BC37AC[phi_t2].r, D_80BC37AC[phi_t2].g, + D_80BC37AC[phi_t2].b, D_80BC37AC[phi_t2].a)); + gSPSegment(POLY_OPA_DISP++, 0x09, + Gfx_EnvColor(globalCtx->state.gfxCtx, D_80BC37B4[phi_t2].r, D_80BC37B4[phi_t2].g, + D_80BC37B4[phi_t2].b, D_80BC37B4[phi_t2].a)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_80BC37BC[this->unk_362])); + gDPPipeSync(POLY_OPA_DISP++); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnJa_OverrideLimbDraw, EnJa_PostLimbDraw, + EnJa_TransformLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (this->unk_1D8.unk_00 == 1) { + func_80BC3594(this, globalCtx); + } +} + +void func_80BC2EA4(EnJa* this) { + f32 sp44; + f32 sp40; + f32 sp3C; + f32 sp38; + s32 i; + Vec3f sp28; + + sp44 = Math_SinS(this->actor.shape.rot.y); + sp40 = Math_CosS(this->actor.shape.rot.y); + sp3C = Math_SinS(this->actor.child->shape.rot.y); + sp38 = Math_CosS(this->actor.child->shape.rot.y); + + for (i = 0; i < ARRAY_COUNT(this->unk_234); i++) { + this->unk_234[i].unk_0E = i * 0x30; + this->unk_234[i].unk_0C = i; + } + + sp28 = this->actor.world.pos; + this->unk_210 = sp28; + this->unk_204 = sp28; + + sp28 = this->actor.child->world.pos; + this->unk_228 = sp28; + this->unk_21C = sp28; + + this->unk_204.x += (D_80BC36AC.z * sp44) + (D_80BC36AC.x * sp40); + this->unk_204.y += D_80BC36AC.y; + this->unk_204.z += (D_80BC36AC.z * sp40) - (D_80BC36AC.x * sp44); + + this->unk_210.x += (D_80BC36B8.z * sp44) + (D_80BC36B8.x * sp40); + this->unk_210.y += D_80BC36B8.y; + this->unk_210.z += (D_80BC36B8.z * sp40) - (D_80BC36B8.x * sp44); + + this->unk_21C.x += (D_80BC36C4.z * sp3C) + (D_80BC36C4.x * sp38); + this->unk_21C.y += D_80BC36C4.y; + this->unk_21C.z += (D_80BC36C4.z * sp38) - (D_80BC36C4.x * sp3C); + + this->unk_228.x += (D_80BC36D0.z * sp3C) + (D_80BC36D0.x * sp38); + this->unk_228.y += D_80BC36D0.y; + this->unk_228.z += (D_80BC36D0.z * sp38) - (D_80BC36D0.x * sp3C); + + this->unk_364 = 2; + this->unk_366 = 0; +} + +void func_80BC3154(EnJa* this, EnJaStruct* ptr) { + if ((ptr->unk_0E >= 18) && (ptr->unk_0E < 83)) { + f32 temp_f0 = ptr->unk_0E - 18; + + ptr->unk_00.x = (((65.0f - temp_f0) * this->unk_204.x) + (temp_f0 * this->unk_228.x)) / 65.0f; + ptr->unk_00.y = (((65.0f - temp_f0) * this->unk_204.y) + (temp_f0 * this->unk_228.y)) / 65.0f; + ptr->unk_00.z = (((65.0f - temp_f0) * this->unk_204.z) + (temp_f0 * this->unk_228.z)) / 65.0f; + + temp_f0 -= 32.5f; + temp_f0 = SQ(temp_f0); + + ptr->unk_00.y += -0.11360947f * temp_f0 + 120.0f; + } else if ((ptr->unk_0E >= 102) && (ptr->unk_0E < 191)) { + f32 temp_f0 = ptr->unk_0E - 102; + + ptr->unk_00.x = (((89.0f - temp_f0) * this->unk_21C.x) + (temp_f0 * this->unk_210.x)) / 89.0f; + ptr->unk_00.y = (((89.0f - temp_f0) * this->unk_21C.y) + (temp_f0 * this->unk_210.y)) / 89.0f; + ptr->unk_00.z = (((89.0f - temp_f0) * this->unk_21C.z) + (temp_f0 * this->unk_210.z)) / 89.0f; + + temp_f0 -= 44.5f; + temp_f0 = SQ(temp_f0); + + ptr->unk_00.y += -0.08079788f * temp_f0 + 160.0f; + } +} + +void func_80BC32D8(EnJa* this, GlobalContext* globalCtx) { + EnJaStruct* phi_s0 = &this->unk_234[0]; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_234); i++, phi_s0++) { + func_80BC3154(this, phi_s0); + if (phi_s0->unk_0E != 191) { + phi_s0->unk_0E++; + } else { + phi_s0->unk_0E = 0; + } + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_366 > 0) { + this->unk_366--; + } else { + this->unk_366 = 3; + } + } else if (Animation_OnFrame(&this->skelAnime, 34.0f)) { + if (this->unk_364 > 0) { + this->unk_364--; + } else { + this->unk_364 = 3; + } + } +} + +void func_80BC33C0(EnJaStruct* ptr, GlobalContext* globalCtx) { + s32 pad; + + if (((ptr->unk_0E < 0) || (ptr->unk_0E >= 19)) && ((ptr->unk_0E < 83) || (ptr->unk_0E >= 103))) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + + switch (ptr->unk_0C) { + case 0: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 1: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 0, 0, 255); + break; + + case 2: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 255, 255); + break; + + case 3: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 0, 255); + break; + + default: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + break; + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_00BCC8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_80BC3594(EnJa* this, GlobalContext* globalCtx) { + EnJaStruct* phi_s0 = this->unk_234; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_234); i++, phi_s0++) { + func_80BC33C0(phi_s0, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Ja/z_en_ja.h b/src/overlays/actors/ovl_En_Ja/z_en_ja.h index 1df6d8962..561f76f55 100644 --- a/src/overlays/actors/ovl_En_Ja/z_en_ja.h +++ b/src/overlays/actors/ovl_En_Ja/z_en_ja.h @@ -7,11 +7,57 @@ struct EnJa; typedef void (*EnJaActionFunc)(struct EnJa*, GlobalContext*); +#define ENJA_GET_3(thisx) (((thisx)->params & 3) & 0xFF) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ s16 unk_0E; +} EnJaStruct; // size = 0x10 + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x04 */ s32 unk_04; + /* 0x08 */ Player* player; +} EnJaStruct2; // size = 0x10 + typedef struct EnJa { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnJaActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x1EC]; + /* 0x018C */ ColliderCylinder collider; + /* 0x01D8 */ EnJaStruct2 unk_1D8; + /* 0x01E4 */ Vec3s unk_1E4; + /* 0x01EC */ Vec3f unk_1EC; + /* 0x01F8 */ Vec3f unk_1F8; + /* 0x0204 */ Vec3f unk_204; + /* 0x0210 */ Vec3f unk_210; + /* 0x021C */ Vec3f unk_21C; + /* 0x0228 */ Vec3f unk_228; + /* 0x0234 */ EnJaStruct unk_234[4]; + /* 0x0274 */ Vec3s unk_274; + /* 0x027A */ Vec3s unk_27A; + /* 0x0280 */ Vec3s jointTable[16]; + /* 0x02E0 */ Vec3s morphTable[16]; + /* 0x0340 */ u16 unk_340; + /* 0x0344 */ f32 unk_344; + /* 0x0348 */ f32 unk_348; + /* 0x034C */ f32 unk_34C; + /* 0x0350 */ UNK_TYPE1 unk350[0x4]; + /* 0x0354 */ s16 unk_354; + /* 0x0356 */ s16 unk_356; + /* 0x0358 */ s16 unk_358; + /* 0x035A */ s16 unk_35A; + /* 0x035C */ s16 unk_35C; + /* 0x035E */ s16 unk_35E; + /* 0x0360 */ s16 unk_360; + /* 0x0362 */ s16 unk_362; + /* 0x0364 */ s16 unk_364; + /* 0x0366 */ s16 unk_366; + /* 0x0368 */ void* unk_368; + /* 0x036C */ s32 unk_36C; + /* 0x0370 */ UNK_TYPE1 unk370[4]; + /* 0x0374 */ s32 unk_374; } EnJa; // size = 0x378 extern const ActorInit En_Ja_InitVars; diff --git a/src/overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.c b/src/overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.c index 7390d9f7c..6afe9c1a0 100644 --- a/src/overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.c +++ b/src/overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.c @@ -5,8 +5,9 @@ */ #include "z_en_jc_mato.h" +#include "objects/object_tru/object_tru.h" -#define FLAGS 0x00004030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_4000) #define THIS ((EnJcMato*)thisx) @@ -86,17 +87,15 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -extern Gfx D_06000390[]; - s32 EnJcMato_CheckForHit(EnJcMato* this, GlobalContext* globalCtx) { this->collider.dim.worldSphere.center.x = this->pos.x; this->collider.dim.worldSphere.center.y = this->pos.y; this->collider.dim.worldSphere.center.z = this->pos.z; if ((this->collider.base.acFlags & AC_HIT) && !this->hitFlag && (this->actor.colChkInfo.damageEffect == 0xF)) { this->collider.base.acFlags &= ~AC_HIT; - Audio_PlayActorSound2(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); globalCtx->interfaceCtx.unk_25C = 1; - this->hitFlag = 1; + this->hitFlag = true; return 1; } else { CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); @@ -112,7 +111,7 @@ void EnJcMato_SetupIdle(EnJcMato* this) { void EnJcMato_Idle(EnJcMato* this, GlobalContext* globalCtx) { s16 shouldDespawn; - if (this->hitFlag != 0) { + if (this->hitFlag) { if (this->despawnTimer == 0) { shouldDespawn = 0; } else { @@ -128,13 +127,13 @@ void EnJcMato_Idle(EnJcMato* this, GlobalContext* globalCtx) { void EnJcMato_Init(Actor* thisx, GlobalContext* globalCtx) { EnJcMato* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); Collider_InitSphere(globalCtx, &this->collider); Collider_SetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); this->collider.dim.worldSphere.radius = 0xF; this->actor.colChkInfo.damageTable = &sDamageTable; Actor_SetScale(&this->actor, 0.008f); - this->hitFlag = 0; + this->hitFlag = false; this->despawnTimer = 25; EnJcMato_SetupIdle(this); } @@ -162,7 +161,7 @@ void EnJcMato_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++, D_06000390); - Matrix_MultiplyVector3fByState(&movement, &this->pos); + gSPDisplayList(POLY_OPA_DISP++, object_tru_DL_000390); + Matrix_MultVec3f(&movement, &this->pos); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Jg/z_en_jg.c b/src/overlays/actors/ovl_En_Jg/z_en_jg.c index 240c6cb40..8f2408495 100644 --- a/src/overlays/actors/ovl_En_Jg/z_en_jg.c +++ b/src/overlays/actors/ovl_En_Jg/z_en_jg.c @@ -1,15 +1,69 @@ -#include "z_en_jg.h" +/* + * File: z_en_jg.c + * Overlay: ovl_En_Jg + * Description: Goron Elder + */ -#define FLAGS 0x00000019 +#include "z_en_jg.h" +#include "overlays/actors/ovl_En_S_Goro/z_en_s_goro.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnJg*)thisx) +#define FLAG_SHRINE_GORON_ARMS_RAISED (1 << 0) +#define FLAG_LOOKING_AT_PLAYER (1 << 2) +#define FLAG_DRUM_SPAWNED (1 << 3) + void EnJg_Init(Actor* thisx, GlobalContext* globalCtx); void EnJg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnJg_Update(Actor* thisx, GlobalContext* globalCtx); void EnJg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnJg_GoronShrineTalk(EnJg* this, GlobalContext* globalCtx); +void EnJg_GoronShrineCheer(EnJg* this, GlobalContext* globalCtx); +void EnJg_AlternateTalkOrWalkInPlace(EnJg* this, GlobalContext* globalCtx); +void EnJg_Walk(EnJg* this, GlobalContext* globalCtx); +void EnJg_Talk(EnJg* this, GlobalContext* globalCtx); +void EnJg_SetupWalk(EnJg* this, GlobalContext* globalCtx); +void EnJg_FrozenIdle(EnJg* this, GlobalContext* globalCtx); +void EnJg_EndFrozenInteraction(EnJg* this, GlobalContext* globalCtx); +void EnJg_TeachLullabyIntro(EnJg* this, GlobalContext* globalCtx); +void EnJg_LullabyIntroCutsceneAction(EnJg* this, GlobalContext* globalCtx); +s32 EnJg_GetNextTextId(EnJg* this); +s32 EnJg_GetStartingConversationTextId(EnJg* this, GlobalContext* globalCtx); +void EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer(EnJg* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ EN_JG_ANIMATION_IDLE, + /* 1 */ EN_JG_ANIMATION_WALK, + /* 2 */ EN_JG_ANIMATION_WAVING, + /* 3 */ EN_JG_ANIMATION_SHAKING_HEAD, + /* 4 */ EN_JG_ANIMATION_SURPRISE_START, + /* 5 */ EN_JG_ANIMATION_SURPRISE_LOOP, + /* 6 */ EN_JG_ANIMATION_ANGRY, + /* 7 */ EN_JG_ANIMATION_FROZEN_START, + /* 8 */ EN_JG_ANIMATION_FROZEN_LOOP, + /* 9 */ EN_JG_ANIMATION_WALK_2, + /* 10 */ EN_JG_ANIMATION_TAKING_OUT_DRUM, + /* 11 */ EN_JG_ANIMATION_DRUM_IDLE, + /* 12 */ EN_JG_ANIMATION_PLAYING_DRUM, + /* 13 */ EN_JG_ANIMATION_THINKING, + /* 14 */ EN_JG_ANIMATION_REMEMBERING, + /* 15 */ EN_JG_ANIMATION_STRONG_REMEMBERING, + /* 16 */ EN_JG_ANIMATION_DEPRESSED, + /* 17 */ EN_JG_ANIMATION_CUTSCENE_IDLE, + /* 18 */ EN_JG_ANIMATION_CRADLE, + /* 19 */ EN_JG_ANIMATION_MAX, +} EnJgAnimationIndex; + +typedef enum { + /* 0x0 */ EN_JG_ACTION_FIRST_THAW, + /* 0x1 */ EN_JG_ACTION_SPAWNING, + /* 0x2 */ EN_JG_ACTION_FROZEN_OR_NON_FIRST_THAW, + /* 0x3 */ EN_JG_ACTION_LULLABY_INTRO_CS, +} EnJgAction; + const ActorInit En_Jg_InitVars = { ACTOR_EN_JG, ACTORCAT_NPC, @@ -22,18 +76,29 @@ const ActorInit En_Jg_InitVars = { (ActorFunc)EnJg_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B75820 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, 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_NONE, + 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, + }, { 60, 80, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B7584C = { 0, 50, 80, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 50, 80, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80B75858 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -68,70 +133,905 @@ static DamageTable D_80B75858 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -#endif +static AnimationInfoS sAnimations[] = { + { &gGoronElderIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderWavingAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderHeadShakeAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderSurpriseStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -10 }, + { &gGoronElderSurpriseLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderAngryAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderSurpriseStartAnim, 2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gGoronElderSurpriseStartAnim, -2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gGoronElderWalkAnim, -1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gGoronElderTakeOutDrumAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gGoronElderDrumIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gGoronElderPlayingDrumAnim, 1.0f, 1, 44, ANIMMODE_ONCE, 0 }, + { &gGoronElderThinkingAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gGoronElderRememberingAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gGoronElderStrongRememberingAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gGoronElderDepressedAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gGoronElderIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gGoronElderCradleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern ColliderCylinderInit D_80B75820; -extern CollisionCheckInfoInit2 D_80B7584C; -extern DamageTable D_80B75858; +static Vec3f sSfxPos = { 0.0f, 0.0f, 0.0f }; -extern UNK_TYPE D_0601ADC0; +static Vec3f sFocusOffset = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73A90.s") +static Vec3f sBreathPosOffset = { 1000.0f, -500.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73AE4.s") +static Vec3f sBreathVelOffset = { 0.0f, 0.0f, 0.75f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73B98.s") +static Vec3f sBreathAccelOffset = { 0.0f, 0.0f, -0.070000000298f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73C58.s") +/** + * When the elder and the Gorons in the shrine are doing a cheer + * for Darmani, the camera will focus on specific Gorons for + * certain parts of the cheer. This function is responsible for + * returning a pointer to the specified Goron so the camera + * can focus on them. + */ +Actor* EnJg_GetShrineGoronToFocusOn(GlobalContext* globalCtx, u8 focusedShrineGoronParam) { + Actor* actorIterator = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73DF4.s") + while (actorIterator != NULL) { + if ((actorIterator->id == ACTOR_EN_S_GORO) && + (EN_S_GORO_GET_PARAM_F(actorIterator) == focusedShrineGoronParam)) { + return actorIterator; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73E3C.s") + actorIterator = actorIterator->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B73F1C.s") + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B7406C.s") +void EnJg_UpdateCollision(EnJg* 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B7408C.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 30.0f, 30.0f, 7); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74134.s") +s16 EnJg_GetWalkingYRotation(Path* path, s32 pointIndex, Vec3f* pos, f32* distSQ) { + Vec3s* points; + f32 diffX; + f32 diffZ; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B741F8.s") + if (path != NULL) { + points = Lib_SegmentedToVirtual(path->points); + points = &points[pointIndex]; + diffX = points[0].x - pos->x; + diffZ = points[0].z - pos->z; + } else { + diffX = 0.0f; + diffZ = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B742F8.s") + *distSQ = SQ(diffX) + SQ(diffZ); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74440.s") + return RADF_TO_BINANG(Math_Acot2F(diffZ, diffX)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74550.s") +s32 EnJg_ReachedPoint(EnJg* 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_Jg/func_80B747C8.s") + Math_Vec3s_ToVec3f(&point, &points[pointIndex]); + 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_Jg/func_80B74840.s") + func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B749D0.s") + 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_Jg/func_80B74AD8.s") + return reached; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74B54.s") +s16 EnJg_GetCutsceneForTeachingLullabyIntro(EnJg* this) { + s16 temp = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74BC8.s") + if (temp > 0) { + return this->actor.cutscene; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B74E5C.s") + return ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B750A0.s") +void EnJg_SetupGoronShrineCheer(EnJg* this) { + ActorCutscene_Stop(this->cutscene); + if (this->focusedShrineGoronParam == 10) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + this->actionFunc = EnJg_GoronShrineTalk; + } else { + this->cutscene = 0x7C; + } + } else { + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->cutscene); + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B7517C.s") + ActorCutscene_SetIntentToPlay(this->cutscene); + this->actionFunc = EnJg_GoronShrineCheer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B751F8.s") + switch (this->textId) { + case 0xDD0: // The greatest Goron hero of all? + case 0xDD2: // The immortal Goron? + case 0xDD3: // The star we wish upon? + case 0xDD4: // "Darmani, greatest of Gorons!" + case 0xDD6: // Darmani, greatest in the world! + this->flags |= FLAG_SHRINE_GORON_ARMS_RAISED; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/EnJg_Init.s") + default: + this->flags &= ~FLAG_SHRINE_GORON_ARMS_RAISED; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/EnJg_Destroy.s") +void EnJg_SetupTalk(EnJg* this, GlobalContext* globalCtx) { + switch (this->textId) { + case 0xDAC: // What was I doing? + this->animationIndex = EN_JG_ANIMATION_SHAKING_HEAD; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Talk; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/EnJg_Update.s") + case 0xDAD: // I must hurry! + this->animationIndex = EN_JG_ANIMATION_SURPRISE_START; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_AlternateTalkOrWalkInPlace; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B75658.s") + case 0xDB7: // You're Darmani! + this->animationIndex = EN_JG_ANIMATION_SURPRISE_START; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Talk; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/func_80B75708.s") + case 0xDAE: // Do you have business with the Elder? + case 0xDB3: // As Elder, I must do something + case 0xDB6: // "Hunh???" + case 0xDBA: // I've been made a fool of! + case 0xDBD: // "...What?" + case 0xDC4: // It's so cold I can't play + this->animationIndex = EN_JG_ANIMATION_IDLE; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Talk; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jg/EnJg_Draw.s") + case 0xDB0: // It's this cold snap + case 0xDBB: // If I can see past the illusion, you'll vanish + case 0xDBC: // Following me won't do you any good + case 0xDC6: // I am counting on you + this->animationIndex = EN_JG_ANIMATION_ANGRY; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Talk; + break; + + case 0xDB4: // This is our problem (first) + case 0xDB5: // This is our problem (repeat) + this->animationIndex = EN_JG_ANIMATION_WAVING; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Talk; + break; + } +} + +void EnJg_Idle(EnJg* this, GlobalContext* globalCtx) { + EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer(this, globalCtx); +} + +void EnJg_GoronShrineIdle(EnJg* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->flags |= FLAG_LOOKING_AT_PLAYER; + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->actionFunc = EnJg_GoronShrineTalk; + } else if ((this->actor.xzDistToPlayer < 100.0f) || (this->actor.isTargeted)) { + func_800B863C(&this->actor, globalCtx); + this->textId = EnJg_GetStartingConversationTextId(this, globalCtx); + } +} + +void EnJg_GoronShrineTalk(EnJg* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if ((this->textId == 0xDCC) || (this->textId == 0xDDD) || (this->textId == 0xDE0)) { + // There is nothing more to say after these lines, so end the current conversation. + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->flags &= ~FLAG_LOOKING_AT_PLAYER; + this->actionFunc = EnJg_GoronShrineIdle; + } else { + this->textId = EnJg_GetNextTextId(this); + Message_StartTextbox(globalCtx, this->textId, &this->actor); + } + } +} + +void EnJg_GoronShrineCheer(EnJg* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + switch (this->textId) { + case 0xDD0: // The greatest Goron hero of all? + case 0xDD2: // The immortal Goron? + case 0xDD3: // The star we wish upon? + case 0xDD4: // "Darmani, greatest of Gorons!" + case 0xDD6: // Darmani, greatest in the world! + // Focus on a specifc Goron for these lines + this->shrineGoron = EnJg_GetShrineGoronToFocusOn(globalCtx, this->focusedShrineGoronParam); + ActorCutscene_Start(this->cutscene, this->shrineGoron); + Camera_SetTargetActor(globalCtx->cameraPtrs[CAM_ID_MAIN], this->shrineGoron); + break; + + default: + // Focus on the whole group for these lines + ActorCutscene_Start(this->cutscene, &this->actor); + Camera_SetTargetActor(globalCtx->cameraPtrs[CAM_ID_MAIN], this->shrineGoron); + break; + } + this->actionFunc = EnJg_GoronShrineTalk; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + if (this->focusedShrineGoronParam == 10) { + this->actionFunc = EnJg_GoronShrineTalk; + } else { + ActorCutscene_Stop(0x7C); + } + } + ActorCutscene_SetIntentToPlay(this->cutscene); + } +} + +/** + * You need to reach a certain point in the conversation when talking with the elder before + * he starts walking for the first time. This function specifically handles this scenario; the + * reason they used this instead of EnJg_Talk is seemingly to bypass EnJg_SetupWalk resetting + * the freeze timer. + * + * Additionally, when the elder has reached the end of his specified path, this function will + * set his speed to 0, causing him to walk in place. + */ +void EnJg_AlternateTalkOrWalkInPlace(EnJg* this, GlobalContext* globalCtx) { + u8 messageState = Message_GetState(&globalCtx->msgCtx); + s16 currentFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); + + if (this->animationIndex == EN_JG_ANIMATION_SURPRISE_START) { + if (currentFrame == lastFrame) { + this->animationIndex = EN_JG_ANIMATION_SURPRISE_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + } + } else if (this->animationIndex == EN_JG_ANIMATION_SURPRISE_LOOP) { + if ((messageState == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->flags &= ~FLAG_LOOKING_AT_PLAYER; + this->animationIndex = EN_JG_ANIMATION_WALK; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Walk; + } + } else if (this->animationIndex == EN_JG_ANIMATION_WALK) { + Math_ApproachF(&this->actor.speedXZ, 0.0f, 0.2f, 1.0f); + EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer(this, globalCtx); + } +} + +void EnJg_Walk(EnJg* this, GlobalContext* globalCtx) { + s16 yRotation; + f32 distSQ; + + if (this->path != NULL) { + yRotation = EnJg_GetWalkingYRotation(this->path, this->currentPoint, &this->actor.world.pos, &distSQ); + if (this->actor.bgCheckFlags & 8) { + yRotation = this->actor.wallYaw; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (EnJg_ReachedPoint(this, this->path, this->currentPoint)) { + if (this->currentPoint >= (this->path->count - 1)) { + // Force the elder to walk in place + this->animationIndex = EN_JG_ANIMATION_WALK; + this->actionFunc = EnJg_AlternateTalkOrWalkInPlace; + } else { + this->currentPoint++; + Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f); + } + } else { + Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f); + } + } + + EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer(this, globalCtx); +} + +void EnJg_Talk(EnJg* this, GlobalContext* globalCtx) { + u8 messageState = Message_GetState(&globalCtx->msgCtx); + s16 currentFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); + u16 temp; + + if ((this->animationIndex == EN_JG_ANIMATION_SURPRISE_START) && (currentFrame == lastFrame)) { + this->animationIndex = EN_JG_ANIMATION_SURPRISE_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + } + + if ((messageState == 5) && Message_ShouldAdvance(globalCtx)) { + temp = this->textId; + if ((temp == 0xDB4) || (temp == 0xDB5) || (temp == 0xDC4) || (temp == 0xDC6)) { + // There is nothing more to say after these lines, so end the current conversation. + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->flags &= ~FLAG_LOOKING_AT_PLAYER; + this->actionFunc = EnJg_SetupWalk; + return; + } + + temp = this->textId; + if ((temp == 0xDBB) || (temp == 0xDBC)) { + if (!(gSaveContext.save.weekEventReg[24] & 0x80)) { + // The player hasn't talked to the Goron Child at least once, so they can't learn + // the Lullaby Intro. End the current conversation with the player. + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->flags &= ~FLAG_LOOKING_AT_PLAYER; + this->actionFunc = EnJg_SetupWalk; + } else if (((gSaveContext.save.weekEventReg[24] & 0x40)) || + (CHECK_QUEST_ITEM(QUEST_SONG_LULLABY) || CHECK_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO))) { + // The player already has the Lullaby or Lullaby Intro, so say "I'm counting on you" + this->textId = EnJg_GetNextTextId(this); + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->actionFunc = EnJg_SetupTalk; + } else { + // To get to this point, the player *has* talked to the Goron Child, but doesn't + // already have the Lullaby or Lullaby Intro. End the current conversation and + // start the cutscene that teaches the Lullaby Intro. + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->flags &= ~FLAG_LOOKING_AT_PLAYER; + this->cutscene = EnJg_GetCutsceneForTeachingLullabyIntro(this); + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->cutscene); + this->actionFunc = EnJg_TeachLullabyIntro; + } + } else { + this->textId = EnJg_GetNextTextId(this); + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->actionFunc = EnJg_SetupTalk; + } + } +} + +void EnJg_SetupWalk(EnJg* this, GlobalContext* globalCtx) { + if (this->animationIndex != EN_JG_ANIMATION_WALK) { + this->animationIndex = EN_JG_ANIMATION_WALK; + this->freezeTimer = 1000; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Walk; + } else { + this->freezeTimer = 1000; + this->actionFunc = EnJg_Walk; + } +} + +void EnJg_Freeze(EnJg* this, GlobalContext* globalCtx) { + s16 currentFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); + + if (this->action == EN_JG_ACTION_SPAWNING) { + this->action = EN_JG_ACTION_FROZEN_OR_NON_FIRST_THAW; + this->freezeTimer = 1000; + this->skelAnime.curFrame = lastFrame; + this->icePoly = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.world.rot.x, + this->actor.world.rot.y, this->actor.world.rot.z, 0xFF50); + this->animationIndex = EN_JG_ANIMATION_FROZEN_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_FrozenIdle; + } else if (this->animationIndex == EN_JG_ANIMATION_FROZEN_START) { + this->action = EN_JG_ACTION_FROZEN_OR_NON_FIRST_THAW; + if (currentFrame == lastFrame) { + this->freezeTimer = 1000; + this->icePoly = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.world.rot.x, + this->actor.world.rot.y, this->actor.world.rot.z, 0xFF50); + this->animationIndex = EN_JG_ANIMATION_FROZEN_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_FrozenIdle; + } + } +} + +void EnJg_FrozenIdle(EnJg* this, GlobalContext* globalCtx) { + if (this->icePoly->update == NULL) { + this->icePoly = NULL; + if (this->animationIndex == EN_JG_ANIMATION_FROZEN_LOOP) { + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + this->animationIndex = EN_JG_ANIMATION_IDLE; + + // If you've never talked to the elder before, he stands + // around idle until you've talked to him at least once. + // Otherwise, he immediately begins walking after being + // thawed out. + if (this->textId == 0xDAC) { + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Idle; + } else { + this->freezeTimer = 1000; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Walk; + } + } + } + } else { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x236, &this->actor); // The old Goron is frozen solid! + this->actionFunc = EnJg_EndFrozenInteraction; + } else if (this->actor.isTargeted) { + func_800B863C(&this->actor, globalCtx); + } + } +} + +void EnJg_EndFrozenInteraction(EnJg* this, GlobalContext* globalCtx) { + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = EnJg_FrozenIdle; + } +} + +void EnJg_TeachLullabyIntro(EnJg* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Start(this->cutscene, &this->actor); + this->actionFunc = EnJg_LullabyIntroCutsceneAction; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->cutscene); + } +} + +void EnJg_LullabyIntroCutsceneAction(EnJg* this, GlobalContext* globalCtx) { + s32 pad; + + if (Cutscene_CheckActorAction(globalCtx, 470)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 470); + + if (this->csAction != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->csAction = globalCtx->csCtx.actorActions[actionIndex]->action; + + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_CUTSCENE_IDLE; + if (this->drum != NULL) { + Actor_MarkForDeath(this->drum); + this->drum = NULL; + } + break; + + case 2: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_TAKING_OUT_DRUM; + break; + + case 3: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_DRUM_IDLE; + break; + + case 4: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_PLAYING_DRUM; + break; + + case 5: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_THINKING; + break; + + case 6: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_REMEMBERING; + break; + + case 7: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_STRONG_REMEMBERING; + break; + + case 8: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_DEPRESSED; + break; + + case 9: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_CRADLE; + break; + + default: + this->cutsceneAnimationIndex = EN_JG_ANIMATION_IDLE; + break; + } + + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->cutsceneAnimationIndex); + } + + if ((!(this->flags & FLAG_DRUM_SPAWNED)) && + (((this->cutsceneAnimationIndex == EN_JG_ANIMATION_TAKING_OUT_DRUM) && + (Animation_OnFrame(&this->skelAnime, 14.0f)) && (this->action != EN_JG_ACTION_LULLABY_INTRO_CS)) || + (((this->cutsceneAnimationIndex == EN_JG_ANIMATION_DRUM_IDLE) || + (this->cutsceneAnimationIndex == EN_JG_ANIMATION_PLAYING_DRUM)) && + (this->action == EN_JG_ACTION_LULLABY_INTRO_CS)))) { + this->flags |= FLAG_DRUM_SPAWNED; + this->drum = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_OBJ_JG_GAKKI, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, this->actor.shape.rot.x, this->actor.shape.rot.y, this->actor.shape.rot.z, + this->actor.params, this->actor.cutscene, this->actor.unk20, NULL); + } + + if (this->cutsceneAnimationIndex == EN_JG_ANIMATION_TAKING_OUT_DRUM) { + if (Animation_OnFrame(&this->skelAnime, 23.0f)) { + Audio_PlaySfxAtPos(&sSfxPos, NA_SE_EV_WOOD_BOUND_S); + } else if (Animation_OnFrame(&this->skelAnime, 38.0f)) { + Audio_PlaySfxAtPos(&sSfxPos, NA_SE_EV_OBJECT_SLIDE); + } + } + } else { + this->csAction = 99; + this->freezeTimer = 1000; + gSaveContext.save.weekEventReg[24] |= 0x40; + this->actionFunc = EnJg_Idle; + } +} + +/** + * Returns the "next" text ID that the elder should use based on his current text ID. + * Note that the results here can be counterintuitive, because his current text ID can + * cause multiple text boxes to display in sequence; this function will return the text + * ID that starts the *next* sequence. + * + * Sequences generally seem to be tied to text IDs that should all share the same animation. + */ +s32 EnJg_GetNextTextId(EnJg* this) { + switch (this->textId) { + case 0xDAC: // What was I doing? + return 0xDAD; // I must hurry! + + case 0xDAE: // Do you have business with the Elder? + return 0xDB0; // It's this cold snap + + case 0xDB0: // It's this cold snap + return 0xDB3; // As Elder, I must do something + + case 0xDB3: // As Elder, I must do something + return 0xDB4; // This is our problem (first) + + case 0xDB6: // "Hunh???" + return 0xDB7; // You're Darmani! + + case 0xDB7: // You're Darmani! + return 0xDBA; // I've been made a fool of! + + case 0xDBA: // I've been made a fool of! + return 0xDBB; // If I can see past the illusion, you'll vanish + + case 0xDBB: // If I can see past the illusion, you'll vanish + case 0xDBC: // Following me won't do you any good + return 0xDC6; // I am counting on you + + case 0xDCB: // Welcome to spring + return 0xDCC; // We're holding the Goron Races + + case 0xDDE: // Come back after entering the race + return 0xDDF; // My son is waiting for you + + case 0xDDF: // My son is waiting for you + return 0xDE0; // Go beyond Twin Islands Cave + + case 0xDCD: // I've been waiting impatiently for you + return 0xDCE; // I heard you sealed the blizzard + + case 0xDCE: // I heard you sealed the blizzard + return 0xDCF; // Spring has come thanks to you + + case 0xDCF: // Spring has come thanks to you + this->focusedShrineGoronParam = 3; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->cutscene); + this->actionFunc = EnJg_GoronShrineCheer; + return 0xDD0; // The greatest Goron hero of all? + + case 0xDD0: // The greatest Goron hero of all? + EnJg_SetupGoronShrineCheer(this); + return 0xDD1; // "Darmani!" + + case 0xDD1: // "Darmani!" + switch (this->focusedShrineGoronParam) { + case 3: + this->focusedShrineGoronParam = 4; + EnJg_SetupGoronShrineCheer(this); + return 0xDD2; // The immortal Goron? + + case 4: + this->focusedShrineGoronParam = 5; + EnJg_SetupGoronShrineCheer(this); + return 0xDD3; // The star we wish upon? + + case 5: + this->focusedShrineGoronParam = 6; + EnJg_SetupGoronShrineCheer(this); + return 0xDD4; // "Darmani, greatest of Gorons!" + + default: + return 0xDD4; // "Darmani, greatest of Gorons!" + } + break; + + case 0xDD2: // The immortal Goron? + EnJg_SetupGoronShrineCheer(this); + return 0xDD1; // "Darmani!" + + case 0xDD3: // The star we wish upon? + EnJg_SetupGoronShrineCheer(this); + return 0xDD1; // "Darmani!" + + case 0xDD4: // "Darmani, greatest of Gorons!" + EnJg_SetupGoronShrineCheer(this); + return 0xDD5; // "Greatest of Gorons!" + + case 0xDD5: // "Greatest of Gorons!" + this->focusedShrineGoronParam = 7; + EnJg_SetupGoronShrineCheer(this); + return 0xDD6; // Darmani, greatest in the world! + + case 0xDD6: // Darmani, greatest in the world! + EnJg_SetupGoronShrineCheer(this); + return 0xDD7; // "Greatest in the world!" + + case 0xDD7: // "Greatest in the world!" + this->focusedShrineGoronParam = 10; + EnJg_SetupGoronShrineCheer(this); + this->flags &= ~FLAG_SHRINE_GORON_ARMS_RAISED; + return 0xDD8; // My son went to see the races + + case 0xDD8: // My son went to see the races + return 0xDD9; // I yield to a younger one + + case 0xDD9: // I yield to a younger one + return 0xDDA; // A Goron who takes care of all + + case 0xDDA: // A Goron who takes care of all + return 0xDDB; // The chosen one, Darmani! + + case 0xDDB: // The chosen one, Darmani! + return 0xDDC; // Everyone would accept you + + case 0xDDC: // Everyone would accept you + gSaveContext.save.weekEventReg[77] |= 0x80; + return 0xDDD; // Think it over slowly + + default: + return 0; + } +} + +/** + * Returns the text ID of the first thing the elder should say when you talk to him + * under most circumstances. Some circumstances (like the very first time the player + * talks to him after he thaws) bypass this function. + */ +s32 EnJg_GetStartingConversationTextId(EnJg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (!EN_JG_IS_IN_GORON_SHRINE(&this->actor)) { + if (player->transformation == PLAYER_FORM_GORON) { + if ((gSaveContext.save.weekEventReg[24] & 0x10) || CHECK_QUEST_ITEM(QUEST_SONG_LULLABY) || + CHECK_QUEST_ITEM(QUEST_SONG_LULLABY_INTRO)) { + // The player has already talked as a Goron at least once. + return 0xDBC; // Following me won't do you any good + } + + // The player has never talked as a Goron. + return 0xDB6; // "Hunh???" + } + + if (gSaveContext.save.weekEventReg[24] & 0x20) { + // The player has already talked as a non-Goron at least once. + return 0xDB5; // This is our problem (repeat) + } + + // The player has never talked as a non-Goron. + return 0xDAE; // Do you have business with the Elder? + } + + if (player->transformation == PLAYER_FORM_GORON) { + if (gSaveContext.save.weekEventReg[77] & 0x80) { + // The player has heard the Goron Shrine cheer as a Goron at least once. + return 0xDDE; // Come back after entering the race + } + + // The player has never heard the Goron Shrine cheer as a Goron. + return 0xDCD; // I've been waiting impatiently for you + } + + // The player is talking to the elder in Goron Shrine as a non-Goron. + return 0xDCB; // Welcome to spring +} + +void EnJg_SpawnBreath(EnJg* this, GlobalContext* globalCtx) { + s16 scale = (Rand_ZeroOne() * 20.0f) + 30.0f; + + if (globalCtx->state.frames % 8 == 0) { + EffectSsIceSmoke_Spawn(globalCtx, &this->breathPos, &this->breathVelocity, &this->breathAccel, scale); + } +} + +/** + * This function has two purposes: + * - If the player starts talking to the elder, this stops him from moving, makes him face + * towards the player, updates certain weekEventRegs, and calls EnJg_SetupTalk. + * - If the player is *not* talking to the elder, this decrements his freeze timer. If his + * freeze timer is 0 or negative, this function starts the process of freezing him before + * handing it off to EnJg_Freeze. + */ +void EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer(EnJg* this, GlobalContext* globalCtx) { + s16 currentFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->flags |= FLAG_LOOKING_AT_PLAYER; + this->actor.speedXZ = 0.0f; + + if (this->textId == 0xDAC) { + this->action = EN_JG_ACTION_FIRST_THAW; + } else if (this->textId == 0xDAE) { + gSaveContext.save.weekEventReg[24] |= 0x20; + } else if (this->textId == 0xDB6) { + gSaveContext.save.weekEventReg[24] |= 0x10; + } + + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->actionFunc = EnJg_SetupTalk; + } else { + if ((this->actor.xzDistToPlayer < 100.0f) || (this->actor.isTargeted)) { + func_800B863C(&this->actor, globalCtx); + if (this->action == EN_JG_ACTION_FIRST_THAW) { + this->textId = EnJg_GetStartingConversationTextId(this, globalCtx); + } + } + + this->freezeTimer--; + if ((this->freezeTimer <= 0) && (currentFrame == lastFrame)) { + this->animationIndex = EN_JG_ANIMATION_FROZEN_START; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + Audio_PlaySfxAtPos(&sSfxPos, NA_SE_EV_FREEZE_S); + this->actionFunc = EnJg_Freeze; + } + } +} + +void EnJg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnJg* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGoronElderSkel, &gGoronElderIdleAnim, this->jointTable, + this->morphTable, GORON_ELDER_LIMB_MAX); + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + Actor_SetScale(&this->actor, 0.01f); + + if (!EN_JG_IS_IN_GORON_SHRINE(thisx)) { + if ((globalCtx->sceneNum == SCENE_SPOT00) && (gSaveContext.sceneSetupIndex == 7) && + (globalCtx->csCtx.currentCsIndex == 0)) { + // This is the elder that appears in the cutscene for learning the full Goron Lullaby. + this->animationIndex = EN_JG_ANIMATION_IDLE; + this->action = EN_JG_ACTION_LULLABY_INTRO_CS; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_LullabyIntroCutsceneAction; + } else { + // This is the elder that appears in Mountain Village or the Path to Goron Village in winter. + this->path = SubS_GetPathByIndex(globalCtx, EN_JG_GET_PATH(thisx), 0x3F); + this->animationIndex = EN_JG_ANIMATION_SURPRISE_START; + this->action = EN_JG_ACTION_SPAWNING; + this->freezeTimer = 1000; + this->textId = 0xDAC; // What was I doing? + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_Freeze; + } + } else { + // This is the elder that appears in Goron Shrine in spring. + this->animationIndex = EN_JG_ANIMATION_IDLE; + this->cutscene = this->actor.cutscene; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, this->animationIndex); + this->actionFunc = EnJg_GoronShrineIdle; + } +} + +void EnJg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnJg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnJg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnJg* this = THIS; + + if ((this->actionFunc != EnJg_FrozenIdle) && (this->actionFunc != EnJg_EndFrozenInteraction)) { + EnJg_UpdateCollision(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + SkelAnime_Update(&this->skelAnime); + + if ((this->action != EN_JG_ACTION_LULLABY_INTRO_CS) && (!EN_JG_IS_IN_GORON_SHRINE(&this->actor))) { + EnJg_SpawnBreath(this, globalCtx); + } + + func_800E9250(globalCtx, &this->actor, &this->unusedRotation1, &this->unusedRotation2, this->actor.focus.pos); + } + this->actionFunc(this, globalCtx); +} + +s32 EnJg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnJg* this = THIS; + + if (limbIndex == GORON_ELDER_LIMB_ROOT) { + if (this->flags & FLAG_LOOKING_AT_PLAYER) { + Math_SmoothStepToS(&this->rootRotationWhenTalking, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, + 5, 0x1000, 0x100); + Matrix_RotateYS(this->rootRotationWhenTalking, MTXMODE_APPLY); + } else { + Math_SmoothStepToS(&this->rootRotationWhenTalking, 0, 5, 0x1000, 0x100); + Matrix_RotateYS(this->rootRotationWhenTalking, MTXMODE_APPLY); + } + } + + return false; +} + +void EnJg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnJg* this = THIS; + + if (limbIndex == GORON_ELDER_LIMB_HEAD) { + Matrix_MultVec3f(&sFocusOffset, &this->actor.focus.pos); + } + + if (limbIndex == GORON_ELDER_LIMB_LOWER_LIP) { + Matrix_MultVec3f(&sBreathPosOffset, &this->breathPos); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sBreathVelOffset, &this->breathVelocity); + Matrix_MultVec3f(&sBreathAccelOffset, &this->breathAccel); + } +} + +void EnJg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnJg* this = THIS; + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnJg_OverrideLimbDraw, EnJg_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Jg/z_en_jg.h b/src/overlays/actors/ovl_En_Jg/z_en_jg.h index 3a860feb2..67ba1d638 100644 --- a/src/overlays/actors/ovl_En_Jg/z_en_jg.h +++ b/src/overlays/actors/ovl_En_Jg/z_en_jg.h @@ -2,16 +2,42 @@ #define Z_EN_JG_H #include "global.h" +#include "objects/object_jg/object_jg.h" + +#define EN_JG_IS_IN_GORON_SHRINE(thisx) ((thisx)->params & 0x1) +#define EN_JG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 10) struct EnJg; typedef void (*EnJgActionFunc)(struct EnJg*, GlobalContext*); typedef struct EnJg { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x98]; - /* 0x01DC */ EnJgActionFunc actionFunc; - /* 0x01E0 */ char unk_1E0[0x1F4]; + /* 0x000 */ Actor actor; + /* 0x144 */ Actor* shrineGoron; + /* 0x148 */ Actor* icePoly; + /* 0x14C */ ColliderCylinder collider; + /* 0x198 */ SkelAnime skelAnime; + /* 0x1DC */ EnJgActionFunc actionFunc; + /* 0x1E0 */ Path* path; + /* 0x1E4 */ s32 currentPoint; + /* 0x1E8 */ Actor* drum; + /* 0x1EC */ Vec3s unusedRotation1; // probably meant to be a head rotation to look at the player + /* 0x1F2 */ Vec3s unusedRotation2; // probably meant to be a body rotation to look at the player + /* 0x1F8 */ Vec3s jointTable[GORON_ELDER_LIMB_MAX]; + /* 0x2CA */ Vec3s morphTable[GORON_ELDER_LIMB_MAX]; + /* 0x39C */ s16 rootRotationWhenTalking; + /* 0x39E */ s16 animationIndex; + /* 0x3A0 */ s16 action; + /* 0x3A2 */ s16 freezeTimer; + /* 0x3A4 */ Vec3f breathPos; + /* 0x3B0 */ Vec3f breathVelocity; + /* 0x3BC */ Vec3f breathAccel; + /* 0x3C8 */ s16 cutscene; + /* 0x3CA */ u8 cutsceneAnimationIndex; + /* 0x3CB */ u8 csAction; + /* 0x3CC */ u16 flags; + /* 0x3CE */ u16 textId; + /* 0x3D0 */ u8 focusedShrineGoronParam; } EnJg; // size = 0x3D4 extern const ActorInit En_Jg_InitVars; diff --git a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c index 7148c01de..c16fa4147 100644 --- a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c +++ b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.c @@ -1,6 +1,13 @@ -#include "z_en_jgame_tsn.h" +/* + * File: z_en_jgame_tsn.c + * Overlay: ovl_En_Jgame_Tsn + * Description: Fisherman's Jumping Game - Fisherman + */ -#define FLAGS 0x02000019 +#include "z_en_jgame_tsn.h" +#include "overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnJgameTsn*)thisx) @@ -9,7 +16,26 @@ void EnJgameTsn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnJgameTsn_Update(Actor* thisx, GlobalContext* globalCtx); void EnJgameTsn_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80C13A2C(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C13B74(EnJgameTsn* this); +void func_80C13BB8(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C13E6C(EnJgameTsn* this); +void func_80C13E90(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C13F9C(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C14030(EnJgameTsn* this); +void func_80C14044(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C1418C(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C141DC(EnJgameTsn* this); +void func_80C14230(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C144F8(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C14554(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C145FC(EnJgameTsn* this); +void func_80C14610(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C14684(EnJgameTsn* this, GlobalContext* globalCtx); +void func_80C147B4(EnJgameTsn* this, GlobalContext* globalCtx); +s32 func_80C149B0(GlobalContext* globalCtx, EnJgameTsnStruct* arg1); +s32 func_80C14BCC(EnJgameTsn* this, GlobalContext* globalCtx); + const ActorInit En_Jgame_Tsn_InitVars = { ACTOR_EN_JGAME_TSN, ACTORCAT_NPC, @@ -22,81 +48,600 @@ const ActorInit En_Jgame_Tsn_InitVars = { (ActorFunc)EnJgameTsn_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C15078 = { - { 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 AnimationInfo sAnimations[] = { + { &object_tsn_Anim_0092FC, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f }, + { &object_tsn_Anim_000964, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f }, + { &object_tsn_Anim_001198, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f }, +}; + +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 +TexturePtr D_80C150A4[] = { + object_tsn_Tex_0073B8, + object_tsn_Tex_0085B8, +}; -extern ColliderCylinderInit D_80C15078; +void EnJgameTsn_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnJgameTsn* this = THIS; -extern UNK_TYPE D_060092FC; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tsn_Skel_008AB8, &object_tsn_Anim_0092FC, this->jointTable, + this->morphTable, OBJECT_TSN_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/EnJgameTsn_Init.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13A2C.s") + this->actor.targetMode = 6; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.velocity.y = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/EnJgameTsn_Destroy.s") + if (gSaveContext.save.entranceIndex == 0x68D0) { + this->actor.flags |= ACTOR_FLAG_10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13B74.s") + this->unk_2F8 = 0; + this->unk_2FA = 0; + this->unk_21C = 0; + this->unk_2FE = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13BB8.s") + func_80C13A2C(this, globalCtx); + func_80C13B74(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13E6C.s") +void func_80C13A2C(EnJgameTsn* this, GlobalContext* globalCtx) { + Path* path = &globalCtx->setupPathList[ENJGAMETSN_GET_FF(&this->actor)]; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13E90.s") + if (path == NULL) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13F88.s") + for (i = 0; i < ARRAY_COUNT(this->unk_1D8); i++) { + this->unk_1D8[i].points = Lib_SegmentedToVirtual(path->points); + this->unk_1D8[i].count = path->count; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C13F9C.s") + path = &globalCtx->setupPathList[path->unk1]; + if (path == NULL) { + Actor_MarkForDeath(&this->actor); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14030.s") + this->unk_1F8.points = Lib_SegmentedToVirtual(path->points); + this->unk_1F8.count = path->count; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14044.s") + path = &globalCtx->setupPathList[path->unk1]; + if (path == NULL) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C1410C.s") + this->unk_200.points = Lib_SegmentedToVirtual(path->points); + this->unk_200.count = path->count; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C1418C.s") +void EnJgameTsn_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnJgameTsn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C141DC.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + gSaveContext.save.weekEventReg[90] &= (u8)~0x20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14230.s") +void func_80C13B74(EnJgameTsn* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80C13BB8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C144E4.s") +void func_80C13BB8(EnJgameTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C144F8.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (this->actor.flags & ACTOR_FLAG_10000) { + this->actor.flags &= ~ACTOR_FLAG_10000; + if (gSaveContext.unk_3DE0[4] > 0) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + Message_StartTextbox(globalCtx, 0x10A2, &this->actor); + this->unk_300 = 0x10A2; + } else if (gSaveContext.minigameScore < 20) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + Message_StartTextbox(globalCtx, 0x10A2, &this->actor); + this->unk_300 = 0x10A2; + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x10A3, &this->actor); + this->unk_300 = 0x10A3; + } + } else if (((gSaveContext.save.time > CLOCK_TIME(4, 0)) && (gSaveContext.save.time < CLOCK_TIME(7, 0))) || + ((gSaveContext.save.time > CLOCK_TIME(16, 0)) && (gSaveContext.save.time < CLOCK_TIME(19, 0)))) { + Message_StartTextbox(globalCtx, 0x1094, &this->actor); + this->unk_300 = 0x1094; + } else if (this->unk_2F8 == 0) { + this->unk_2F8 = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + Message_StartTextbox(globalCtx, 0x1095, &this->actor); + this->unk_300 = 0x1095; + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + Message_StartTextbox(globalCtx, 0x1096, &this->actor); + this->unk_300 = 0x1096; + } + func_80C14030(this); + } else if (this->actor.flags & ACTOR_FLAG_10000) { + func_800B8614(&this->actor, globalCtx, 200.0f); + } else { + func_800B8614(&this->actor, globalCtx, 80.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14540.s") + if ((player->actor.bgCheckFlags & 1) && !(player->stateFlags1 & 0x2000) && (this->unk_2FE == 0) && + (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) && func_80C149B0(globalCtx, &this->unk_1F8)) { + this->unk_2FE = 1; + func_80C13E6C(this); + } else if (!(player->actor.bgCheckFlags & 1)) { + this->unk_2FE = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14554.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 5, 0x71C, 0xB6); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C145FC.s") +void func_80C13E6C(EnJgameTsn* this) { + this->actor.flags |= ACTOR_FLAG_10000; + this->actionFunc = func_80C13E90; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14610.s") +void func_80C13E90(EnJgameTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + if (((gSaveContext.save.time > CLOCK_TIME(4, 0)) && (gSaveContext.save.time < CLOCK_TIME(7, 0))) || + ((gSaveContext.save.time > CLOCK_TIME(16, 0)) && (gSaveContext.save.time < CLOCK_TIME(19, 0)))) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x1094, &this->actor); + this->unk_300 = 0x1094; + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + Message_StartTextbox(globalCtx, 0x1098, &this->actor); + this->unk_300 = 0x1098; + } + func_80C14030(this); + } else { + func_800B8614(&this->actor, globalCtx, 1000.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14684.s") +void func_80C13F88(EnJgameTsn* this) { + this->actionFunc = func_80C13F9C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C1476C.s") +void func_80C13F9C(EnJgameTsn* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + func_80C14030(this); + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } else { + func_80C14030(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C147B4.s") +void func_80C14030(EnJgameTsn* this) { + this->actionFunc = func_80C14044; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14960.s") +void func_80C14044(EnJgameTsn* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + case 3: + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C149B0.s") + case 4: + func_80C14684(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14BCC.s") + case 5: + func_80C147B4(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14D14.s") + case 6: + if (Message_ShouldAdvance(globalCtx)) { + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + ActorCutscene_Stop(this->actor.cutscene); + } + func_80C13B74(this); + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14D58.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x71C, 0xB6); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/EnJgameTsn_Update.s") +void func_80C1410C(EnJgameTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14E64.s") + player->stateFlags1 |= 0x20; + func_801A2BB8(0x25); + globalCtx->interfaceCtx.unk_280 = 1; + func_80112AFC(globalCtx); + gSaveContext.save.weekEventReg[90] |= 0x20; + func_8010E9F0(4, 0x78); + this->actionFunc = func_80C1418C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/func_80C14EE4.s") +void func_80C1418C(EnJgameTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Jgame_Tsn/EnJgameTsn_Draw.s") + if (globalCtx->interfaceCtx.unk_280 == 8) { + func_80C141DC(this); + player->stateFlags1 &= ~0x20; + } +} + +void func_80C141DC(EnJgameTsn* this) { + this->unk_218 = Rand_Next() & 3; + this->unk_2FC = 0; + *this->unk_208[this->unk_218] |= 1; + this->actionFunc = func_80C14230; +} + +void func_80C14230(EnJgameTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + s32 rand; + + if ((this->unk_2FC > 100) || func_80C14BCC(this, globalCtx)) { + rand = (u32)Rand_Next() % 3; + + this->unk_2FC = 0; + if (rand < this->unk_218) { + this->unk_218 = rand; + } else { + this->unk_218 = rand + 1; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_208); i++) { + if (i == this->unk_218) { + *this->unk_208[i] |= 1; + *this->unk_208[i] &= ~8; + } else { + *this->unk_208[i] |= 8; + } + } + } + + this->unk_2FC++; + + if ((player->actor.bgCheckFlags & 2) && func_80C149B0(globalCtx, &this->unk_200)) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x109F, &this->actor); + this->unk_300 = 0x109F; + player->stateFlags1 |= 0x20; + *this->unk_208[this->unk_218] &= ~1; + func_801A2C20(); + func_80C14030(this); + } else if ((player->actor.bgCheckFlags & 0x40) || (player->actor.bgCheckFlags & 0x20)) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x10A0, &this->actor); + this->unk_300 = 0x10A0; + player->stateFlags1 |= 0x20; + *this->unk_208[this->unk_218] &= ~1; + func_801A2C20(); + func_80C14030(this); + } + + if (gSaveContext.unk_3DE0[4] == 0) { + Message_StartTextbox(globalCtx, 0x10A1, &this->actor); + this->unk_300 = 0x10A1; + player->stateFlags1 |= 0x20; + *this->unk_208[this->unk_218] &= ~1; + func_801A2C20(); + func_80C14030(this); + } +} + +void func_80C144E4(EnJgameTsn* this) { + this->actionFunc = func_80C144F8; +} + +void func_80C144F8(EnJgameTsn* this, GlobalContext* globalCtx) { + globalCtx->nextEntranceIndex = 0x68D0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 0x50; + gSaveContext.nextTransition = 3; +} + +void func_80C14540(EnJgameTsn* this) { + this->actionFunc = func_80C14554; +} + +void func_80C14554(EnJgameTsn* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + if (!(gSaveContext.save.weekEventReg[82] & 0x10)) { + gSaveContext.save.weekEventReg[82] |= 0x10; + } + func_80C145FC(this); + } else if (gSaveContext.save.weekEventReg[82] & 0x10) { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } +} + +void func_80C145FC(EnJgameTsn* this) { + this->actionFunc = func_80C14610; +} + +void func_80C14610(EnJgameTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x10A4, &this->actor); + this->unk_300 = 0x10A4; + func_80C14030(this); + } else { + func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + } +} + +void func_80C14684(EnJgameTsn* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + if (gSaveContext.save.playerData.rupees >= 20) { + Message_StartTextbox(globalCtx, 0x109E, &this->actor); + this->unk_300 = 0x109E; + func_801159EC(-20); + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x109D, &this->actor); + this->unk_300 = 0x109D; + } + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + Message_StartTextbox(globalCtx, 0x109C, &this->actor); + this->unk_300 = 0x109C; + } + } +} + +void func_80C1476C(EnJgameTsn* this, GlobalContext* globalCtx) { + Actor* prop = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; + + while (prop != NULL) { + if (prop->id == ACTOR_OBJ_JGAME_LIGHT) { + this->unk_208[OBJJGAMELIGHT_GET_7F(prop)] = &prop->colChkInfo.health; + } + prop = prop->next; + } +} + +void func_80C147B4(EnJgameTsn* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + switch (this->unk_300) { + case 0x1095: + Message_StartTextbox(globalCtx, 0x1096, &this->actor); + this->unk_300 = 0x1096; + break; + + case 0x1096: + Message_StartTextbox(globalCtx, 0x1097, &this->actor); + this->unk_300 = 0x1097; + break; + + case 0x1098: + Message_StartTextbox(globalCtx, 0x1099, &this->actor); + this->unk_300 = 0x1099; + func_80C13F88(this); + break; + + case 0x1099: + Message_StartTextbox(globalCtx, 0x109A, &this->actor); + this->unk_300 = 0x109A; + break; + + case 0x109A: + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + Message_StartTextbox(globalCtx, 0x109B, &this->actor); + this->unk_300 = 0x109B; + break; + + case 0x109E: + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + ActorCutscene_Stop(this->actor.cutscene); + } + func_801477B4(globalCtx); + func_80C1476C(this, globalCtx); + func_80C1410C(this, globalCtx); + break; + + case 0x109F: + case 0x10A0: + case 0x10A1: + func_801477B4(globalCtx); + gSaveContext.minigameState = 3; + gSaveContext.unk_3DD0[4] = 5; + gSaveContext.save.weekEventReg[90] &= (u8)~0x20; + func_80C144E4(this); + break; + + case 0x10A3: + func_801477B4(globalCtx); + func_80C14540(this); + func_80C14554(this, globalCtx); + break; + } + } +} + +s32 func_80C14960(Vec2f arg0, Vec2f arg1) { + s32 phi_v1; + + if ((arg1.x * arg0.z) < (arg0.x * arg1.z)) { + phi_v1 = 1; + } else { + phi_v1 = -1; + } + return phi_v1; +} + +s32 func_80C149B0(GlobalContext* globalCtx, EnJgameTsnStruct* arg1) { + s32 i = 1; + s32 temp_s3; + Player* player = GET_PLAYER(globalCtx); + Vec2f sp64; + Vec2f sp5C; + s32 sp58 = true; + s32 pad; + s32 sp50 = 0; + f32 temp_f20 = player->actor.world.pos.z; + f32 temp_f22 = player->actor.world.pos.x; + + sp64.x = arg1->points[0].z - temp_f20; + sp64.z = arg1->points[0].x - temp_f22; + sp5C.x = arg1->points[1].z - temp_f20; + sp5C.z = arg1->points[1].x - temp_f22; + temp_s3 = func_80C14960(sp64, sp5C); + + while (i != 0) { + sp50++; + if (i < (arg1->count - 1)) { + i++; + } else { + i = 0; + } + + sp64.x = arg1->points[sp50].z - temp_f20; + sp64.z = arg1->points[sp50].x - temp_f22; + sp5C.x = arg1->points[i].z - temp_f20; + sp5C.z = arg1->points[i].x - temp_f22; + + if (func_80C14960(sp64, sp5C) != temp_s3) { + sp58 = false; + break; + } + } + + return sp58; +} + +s32 func_80C14BCC(EnJgameTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + s32 phi_s3 = -1; + + if (player->actor.bgCheckFlags & 2) { + for (i = 0; i < ARRAY_COUNT(this->unk_1D8); i++) { + if (func_80C149B0(globalCtx, &this->unk_1D8[i])) { + phi_s3 = i; + } + } + + if (phi_s3 == -1) { + return false; + } + + if (phi_s3 == this->unk_218) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + *this->unk_208[phi_s3] |= 2; + globalCtx->interfaceCtx.unk_25C = 1; + return true; + } + + if (*this->unk_208[phi_s3] & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + *this->unk_208[phi_s3] |= 2; + globalCtx->interfaceCtx.unk_25C = 1; + } else { + *this->unk_208[phi_s3] |= 4; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); + } + } + + return false; +} + +void func_80C14D14(EnJgameTsn* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80C14D58(EnJgameTsn* this, GlobalContext* globalCtx) { + func_800E9250(globalCtx, &this->actor, &this->unk_2EC, &this->unk_2F2, this->actor.focus.pos); + + if (DECR(this->unk_2FA) == 0) { + this->unk_2FA = Rand_S16Offset(60, 60); + } + + if ((this->unk_2FA == 1) || (this->unk_2FA == 3)) { + this->unk_21C = 1; + } else { + this->unk_21C = 0; + } +} + +void EnJgameTsn_Update(Actor* thisx, GlobalContext* globalCtx) { + EnJgameTsn* this = THIS; + + this->actionFunc(this, globalCtx); + + SkelAnime_Update(&this->skelAnime); + func_80C14D14(this, globalCtx); + func_80C14D58(this, globalCtx); +} + +s32 EnJgamesTsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnJgameTsn* this = THIS; + s16 temp_v0 = this->unk_2EC.x >> 1; + + if (limbIndex == OBJECT_TSN_LIMB_0F) { + rot->x += this->unk_2EC.y; + rot->z += temp_v0; + } else if (limbIndex == OBJECT_TSN_LIMB_08) { + rot->x += this->unk_2F2.y; + rot->z += temp_v0; + } + return false; +} + +void EnJgamesTsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + if (limbIndex == OBJECT_TSN_LIMB_0F) { + Matrix_MultZero(&thisx->focus.pos); + } +} + +void EnJgameTsn_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnJgameTsn* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C150A4[this->unk_21C])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C150A4[this->unk_21C])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnJgamesTsn_OverrideLimbDraw, EnJgamesTsn_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.h b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.h index c7e53da1a..08d07376d 100644 --- a/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.h +++ b/src/overlays/actors/ovl_En_Jgame_Tsn/z_en_jgame_tsn.h @@ -2,16 +2,39 @@ #define Z_EN_JGAME_TSN_H #include "global.h" +#include "objects/object_tsn/object_tsn.h" struct EnJgameTsn; typedef void (*EnJgameTsnActionFunc)(struct EnJgameTsn*, GlobalContext*); +#define ENJGAMETSN_GET_FF(thisx) ((thisx)->params & 0xFF) + +typedef struct { + /* 0x00 */ Vec3s* points; + /* 0x04 */ s32 count; +} EnJgameTsnStruct; // size = 0x8 + typedef struct EnJgameTsn { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnJgameTsnActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x12C]; + /* 0x01D8 */ EnJgameTsnStruct unk_1D8[4]; + /* 0x01F8 */ EnJgameTsnStruct unk_1F8; + /* 0x0200 */ EnJgameTsnStruct unk_200; + /* 0x0208 */ u8* unk_208[4]; + /* 0x0218 */ s32 unk_218; + /* 0x021C */ s32 unk_21C; + /* 0x0220 */ Vec3s jointTable[OBJECT_TSN_LIMB_MAX]; + /* 0x0286 */ Vec3s morphTable[OBJECT_TSN_LIMB_MAX]; + /* 0x02EC */ Vec3s unk_2EC; + /* 0x02F2 */ Vec3s unk_2F2; + /* 0x02F8 */ s16 unk_2F8; + /* 0x02FA */ s16 unk_2FA; + /* 0x02FC */ s16 unk_2FC; + /* 0x02FE */ s16 unk_2FE; + /* 0x0300 */ u16 unk_300; } EnJgameTsn; // size = 0x304 extern const ActorInit En_Jgame_Tsn_InitVars; diff --git a/src/overlays/actors/ovl_En_Js/z_en_js.c b/src/overlays/actors/ovl_En_Js/z_en_js.c index cab6ca7f2..15426db82 100644 --- a/src/overlays/actors/ovl_En_Js/z_en_js.c +++ b/src/overlays/actors/ovl_En_Js/z_en_js.c @@ -1,6 +1,12 @@ +/* + * File: z_en_js.c + * Overlay: ovl_En_Js + * Description: Moon Child + */ + #include "z_en_js.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnJs*)thisx) diff --git a/src/overlays/actors/ovl_En_Jso/z_en_jso.c b/src/overlays/actors/ovl_En_Jso/z_en_jso.c index 3248c716e..3c7e5ce75 100644 --- a/src/overlays/actors/ovl_En_Jso/z_en_jso.c +++ b/src/overlays/actors/ovl_En_Jso/z_en_jso.c @@ -1,6 +1,12 @@ +/* + * File: z_en_jso.c + * Overlay: ovl_En_Jso + * Description: Garo + */ + #include "z_en_jso.h" -#define FLAGS 0x00000015 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnJso*)thisx) diff --git a/src/overlays/actors/ovl_En_Jso2/z_en_jso2.c b/src/overlays/actors/ovl_En_Jso2/z_en_jso2.c index 4b978eb16..8d29b9383 100644 --- a/src/overlays/actors/ovl_En_Jso2/z_en_jso2.c +++ b/src/overlays/actors/ovl_En_Jso2/z_en_jso2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_jso2.c + * Overlay: ovl_En_Jso2 + * Description: Garo Master + */ + #include "z_en_jso2.h" -#define FLAGS 0x80100035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_100000 | ACTOR_FLAG_80000000) #define THIS ((EnJso2*)thisx) diff --git a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c index 5cb041458..721e8c1a4 100644 --- a/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c +++ b/src/overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.c @@ -1,6 +1,12 @@ +/* + * File: z_en_kaizoku.c + * Overlay: ovl_En_Kaizoku + * Description: Fighter pirate + */ + #include "z_en_kaizoku.h" -#define FLAGS 0x00100015 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_100000) #define THIS ((EnKaizoku*)thisx) 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 16d9f8271..78441bc41 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -1,6 +1,13 @@ -#include "z_en_kakasi.h" +/* + * File: z_en_kakasi.c + * Overlay: ovl_En_Kakasi + * Description: Pierre the Scarecorw + */ -#define FLAGS 0x02000019 +#include "z_en_kakasi.h" +#include "objects/object_ka/object_ka.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnKakasi*)thisx) @@ -9,28 +16,53 @@ void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx); void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8096FCC4(EnKakasi* this, GlobalContext* globalCtx); -void func_8096FE00(EnKakasi* this, GlobalContext* globalCtx); -void func_8097006C(EnKakasi* this, GlobalContext* globalCtx); -void func_80970658(EnKakasi* this, GlobalContext* globalCtx); -void func_80970740(EnKakasi* this, GlobalContext* globalCtx); -void func_80970978(EnKakasi* this, GlobalContext* globalCtx); -void func_80970A9C(EnKakasi* this, GlobalContext* globalCtx); -void func_80970F20(EnKakasi* this, GlobalContext* globalCtx); -void func_80971064(EnKakasi* this, GlobalContext* globalCtx); -void func_80971430(EnKakasi* this, GlobalContext* globalCtx); -void func_809714BC(EnKakasi* this, GlobalContext* globalCtx); -void func_809717D0(EnKakasi* this, GlobalContext* globalCtx); -void func_8097185C(EnKakasi* this, GlobalContext* globalCtx); -void func_8097193C(EnKakasi* this, GlobalContext* globalCtx); -void func_80971A64(EnKakasi* this, GlobalContext* globalCtx); -void func_80971AD4(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupPostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_InitTimeSkipDialogue(EnKakasi* this); +void EnKakasi_SetupIdleStanding(EnKakasi* this); + +void EnKakasi_8096F88C(GlobalContext* globalCtx, EnKakasi* this); + +void EnKakasi_TimeSkipDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_IdleStanding(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_OcarinaRemark(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_TeachingSong(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_PostSongLearnTwirl(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_PostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupDigAway(EnKakasi* this); +void EnKakasi_DiggingAway(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RisenDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupIdleUnderground(EnKakasi* this); +void EnKakasi_IdleUnderground(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupIdleRisen(EnKakasi* this); +void EnKakasi_IdleRisen(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupRiseOutOfGround(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RisingOutOfGround(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_DancingRemark(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupDanceNightAway(EnKakasi* this); +void EnKakasi_DancingNightAway(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_DoNothing(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_RegularDialogue(EnKakasi* this, GlobalContext* globalCtx); +void EnKakasi_SetupSongTeach(EnKakasi* this, GlobalContext* globalCtx); + +void EnKakasi_SetupDialogue(EnKakasi* this); -#if 0 -// static ColliderCylinderInit sCylinderInit = { static ColliderCylinderInit D_80971D80 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 70, 0, { 0, 0, 0 } }, }; @@ -46,80 +78,1083 @@ const ActorInit En_Kakasi_InitVars = { (ActorFunc)EnKakasi_Draw, }; -#endif +static Vec3f D_80971DCC[] = { + { 0.0f, 60.0f, 60.0f }, { 40.0f, 40.0f, 50.0f }, { -40.0f, 40.0f, 50.0f }, + { 40.0f, 20.0f, 110.0f }, { -40.0f, 20.0f, 110.0f }, { 0.0f, 80.0f, 60.0f }, + { 50.0f, 40.0f, -30.0f }, { -50.0f, 40.0f, -30.0f }, { 0.0f, 50.0f, 60.0f }, +}; +Vec3f D_80971E38[] = { + { 0.0f, 55.0f, 60.0f }, { 0.0f, 55.0f, 60.0f }, { -80.0f, 35.0f, 15.0f }, { 80.0f, 45.0f, 15.0f }, + { -10.0f, 35.0f, 65.0f }, { 0.0f, 110.0f, 180.0f }, { 0.0f, 60.0f, 70.0f }, { 0.0f, 60.0f, 70.0f }, + { -80.0f, 50.0f, 40.0f }, { 0.0f, -10.0f, 50.0f }, { 80.0f, 50.0f, 40.0f }, { 0.0f, 120.0f, 40.0f }, + { 0.0f, 28.0f, -50.0f }, { 0.0f, 60.0f, 50.0f }, { 0.0f, 80.0f, 160.0f }, +}; -extern ColliderCylinderInit D_80971D80; +Vec3f D_80971EEC[] = { + { 12.0f, 1.0f, 2.0f }, { 12.0f, 1.0f, 2.0f }, { 2.0f, -6.0f, 0.0f }, { 12.0f, -6.0f, -10.0f }, + { -88.0f, 14.0, -10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, + { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, { 0.0f, -10.0f, 0.0f }, + { 0.0f, -10.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, +}; -extern UNK_TYPE D_06000214; +Vec3f D_80971FA0[] = { + { -50.0f, 160.0f, -40.0f }, { -50.0f, 160.0f, -40.0f }, { -20.0f, 80.0f, 60.0f }, + { 57.0f, 60.0f, 120.0f }, { 27.0f, 80.0f, 60.0f }, { -3.0f, 50.0f, 70.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Destroy.s") +Vec3f D_80971FE8[] = { + { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { -10.0f, -5.0f, 0.0f }, + { 10.0f, -10.0f, 7.0f }, { 20.0f, 5.0f, 2.0f }, { 10.0f, 5.0f, 2.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Init.s") +// both use in digging away function +Vec3f D_80972030 = { -3.0f, 50.0f, 90.0f }; +Vec3f D_8097203C = { 10.0f, -15.0f, 2.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F800.s") +typedef enum { + /* 0x0 */ ENKAKASI_ANIM_ARMS_CROSSED_ROCKING, // arms crossed and rocking back and forth + /* 0x1 */ ENKAKASI_ANIM_SIDEWAYS_SHAKING, + /* 0x2 */ ENKAKASI_ANIM_HOPPING_REGULAR, // bounce bounce bounce (repeat) + /* 0x3 */ ENKAKASI_ANIM_SPIN_REACH_OFFER, // spin and then reaching toward player + /* 0x4 */ ENKAKASI_ANIM_TWIRL, // slower cinimatic twirl + /* 0x5 */ ENKAKASI_ANIM_ARMS_CROSSED_STILL, // arms crossed but still, also some noise sfx + /* 0x6 */ ENKAKASI_ANIM_WAVE, // "wave" short sideways shake, stops early, partial? unused? + /* 0x7 */ ENKAKASI_ANIM_SLOWROLL, // partial bounch, ends looking left, OFFER anim takes over + /* 0x8 */ ENKAKASI_ANIM_IDLE, // slow stretching wiggle, ends in regular position +} EnKakasi_Animations; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F88C.s") +static AnimationHeader* kakasiAnimations[] = { + &object_ka_Anim_007444, &object_ka_Anim_00686C, &object_ka_Anim_0081A4, + &object_ka_Anim_007B90, &object_ka_Anim_0071EC, &object_ka_Anim_007444, + &object_ka_Anim_00686C, &object_ka_Anim_0081A4, &object_ka_Anim_000214, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096F8D8.s") +static u8 sAnimModes[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE, + ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_ONCE, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FA18.s") +void EnKakasi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FAAC.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FBB8.s") +void EnKakasi_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + s32 tempCutscene; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FC8C.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &D_80971D80); + SkelAnime_InitFlex(globalCtx, &this->skelanime, &object_ka_Skel_0065B0, &object_ka_Anim_000214, 0, 0, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FCC4.s") + this->songSummonDist = GET_KAKASI_SUMMON_DISTANCE(this) * 20.0f; + if (this->songSummonDist < 40.0f) { + this->songSummonDist = 40.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FDE8.s") + this->unkHeight = (this->actor.world.rot.z * 20.0f) + 60.0f; + this->actor.world.rot.z = 0; + this->actor.targetMode = 0; + if (this->actor.world.rot.x > 0 && this->actor.world.rot.x < 8) { + this->actor.targetMode = this->actor.world.rot.x - 1; + } + this->actor.shape.rot.y = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8096FE00.s") + this->aboveGroundStatus = GET_KAKASI_ABOVE_GROUND(this); + this->actor.world.rot.x = 0; + this->actor.flags |= ACTOR_FLAG_400; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970008.s") + i = 0; + tempCutscene = this->actor.cutscene; + while (tempCutscene != -1) { + //! FAKE: + tempCutscene = ActorCutscene_GetAdditionalCutscene(this->actorCutscenes[i] = tempCutscene); + i++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097006C.s") + if (this->aboveGroundStatus) { + if (gSaveContext.save.weekEventReg[79] & 8) { + this->aboveGroundStatus = ENKAKASI_ABOVE_GROUND_TYPE; + this->songSummonDist = 80.0f; + EnKakasi_SetupIdleUnderground(this); + } else { + Actor_SetFocus(&this->actor, 60.0f); + this->unkFunc = EnKakasi_8096F88C; + if (gSaveContext.save.weekEventReg[83] & 1) { + EnKakasi_InitTimeSkipDialogue(this); + } else { + EnKakasi_SetupIdleStanding(this); + } + } + } else { + EnKakasi_SetupIdleUnderground(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809705E4.s") +void EnKakasi_SetAnimation(EnKakasi* this, s32 index) { + this->animIndex = index; + this->animeFrameCount = Animation_GetLastFrame(&kakasiAnimations[this->animIndex]->common); + // 1: regular playback speed, 0: starting frame + Animation_Change(&this->skelanime, kakasiAnimations[this->animIndex], 1.0f, 0.0f, this->animeFrameCount, + sAnimModes[this->animIndex], -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970658.s") +/* + * set by init, called... nowhere? left over from OOT? + */ +void EnKakasi_8096F88C(GlobalContext* globalCtx, EnKakasi* this) { + func_8013A530(globalCtx, &this->actor, 0x7, &this->actor.focus.pos, &this->actor.shape.rot, 280.0f, 1800.0f, -1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970740.s") +void EnKakasi_CheckAnimationSfx(EnKakasi* this) { + if (this->animIndex == ENKAKASI_ANIM_SIDEWAYS_SHAKING || this->animIndex == ENKAKASI_ANIM_ARMS_CROSSED_STILL) { + if (Animation_OnFrame(&this->skelanime, 1.0f) || Animation_OnFrame(&this->skelanime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KAKASHI_SWING); + } + } + if (this->animIndex == ENKAKASI_ANIM_HOPPING_REGULAR || this->animIndex == ENKAKASI_ANIM_SLOWROLL) { + if (Animation_OnFrame(&this->skelanime, 4.0f) || Animation_OnFrame(&this->skelanime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KAKASHI_SWING); + } + if (Animation_OnFrame(&this->skelanime, 1.0f) || Animation_OnFrame(&this->skelanime, 9.0f) || + Animation_OnFrame(&this->skelanime, 16.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_KAKASHI_JUMP); + } + if (Animation_OnFrame(&this->skelanime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KAKASHI_ROLL); + } + } + if (this->animIndex == ENKAKASI_ANIM_SPIN_REACH_OFFER || this->animIndex == ENKAKASI_ANIM_TWIRL) { + if (Animation_OnFrame(&this->skelanime, 1.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_KAKASH_LONGI_ROLL); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970978.s") +/* + * moves the player's position relative to scarecrow during song teach, also each frame of dance the night away + */ +void EnKakasi_CheckPlayerPosition(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970A10.s") + if (globalCtx->sceneNum == SCENE_8ITEMSHOP) { + player->actor.world.pos.x = -50.0f; + player->actor.world.pos.z = 155.0f; + } else if (globalCtx->sceneNum == SCENE_TENMON_DAI) { + player->actor.world.pos.x = 60.0f; + player->actor.world.pos.z = -190.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970A9C.s") + Math_SmoothStepToS(&player->actor.shape.rot.y, (this->actor.yawTowardsPlayer + 0x8000), 5, 1000, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970F20.s") +/* + * this goes off every frame of dancing the night away, and song teaching + * something to do with cutscene camera? + */ +void func_8096FAAC(EnKakasi* this, GlobalContext* globalCtx) { + if (this->cutsceneCamId != CAM_ID_MAIN) { + Math_ApproachF(&this->unk214.x, this->unk238.x, 0.4f, 4.0f); + Math_ApproachF(&this->unk214.y, this->unk238.y, 0.4f, 4.0f); + Math_ApproachF(&this->unk214.z, this->unk238.z, 0.4f, 4.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80970FF8.s") + Math_ApproachF(&this->unk220.x, this->unk244.x, 0.4f, 4.0f); + Math_ApproachF(&this->unk220.y, this->unk244.y, 0.4f, 4.0f); + Math_ApproachF(&this->unk220.z, this->unk244.z, 0.4f, 4.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971064.s") + Math_ApproachF(&this->unk20C, this->unk210, 0.3f, 10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971430.s") + Play_CameraSetAtEye(globalCtx, this->cutsceneCamId, &this->unk220, &this->unk214); + Play_CameraSetFov(globalCtx, this->cutsceneCamId, this->unk20C); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971440.s") +/* + * goes off every frame of song teach, but... doing what? + */ +void func_8096FBB8(EnKakasi* this, GlobalContext* globalCtx) { + if (globalCtx->msgCtx.unk12048 == 0 || globalCtx->msgCtx.unk12048 == 1 || globalCtx->msgCtx.unk12048 == 2 || + globalCtx->msgCtx.unk12048 == 3 || globalCtx->msgCtx.unk12048 == 4) { + // why not 0 < x < 4? fewer branches + this->unk190++; + } + if (this->unk190 != 0 && this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (this->unk190 > 8) { + this->unk190 = 8; + } + if (this->unk190 != 0) { + Math_ApproachF(&this->skelanime.playSpeed, 1.0f, 0.1f, 0.2f); + this->actor.shape.rot.y += 0x800; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809714BC.s") +void EnKakasi_InitTimeSkipDialogue(EnKakasi* this) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SLOWROLL); + this->actionFunc = EnKakasi_TimeSkipDialogue; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971794.s") +void EnKakasi_TimeSkipDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_809717D0.s") + if (gSaveContext.respawnFlag != -4 && gSaveContext.respawnFlag != -8) { + if (gSaveContext.save.time != CLOCK_TIME(6, 0) && gSaveContext.save.time != CLOCK_TIME(18, 0) && + !(gSaveContext.eventInf[1] & 0x80)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097185C.s") + if (this->actor.textId == 0) { + // dialogue after skipped time 'did you feel that? went by in an instant' + this->actor.textId = 0x1653; + gSaveContext.save.weekEventReg[83] &= (u8)~1; + this->unkMsgState1AC = 5; + player->stateFlags1 |= 0x20; + this->actor.flags |= ACTOR_FLAG_10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_8097193C.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + player->stateFlags1 &= ~0x20; + this->unkState196 = 2; + this->actor.flags &= ~ACTOR_FLAG_10000; + this->actionFunc = EnKakasi_RegularDialogue; + } else { + func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, -1); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971A38.s") +void EnKakasi_SetupIdleStanding(EnKakasi* this) { + this->unkState196 = 0; + this->actionFunc = EnKakasi_IdleStanding; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971A64.s") +void EnKakasi_IdleStanding(EnKakasi* this, GlobalContext* globalCtx) { + u32 saveContextDay = gSaveContext.save.day; + s16 x; + s16 y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971AD4.s") + // first talk to scarecrow dialogue + this->actor.textId = 0x1644; + if (func_800B8718(&this->actor, &globalCtx->state)) { + this->skelanime.playSpeed = 1.0f; + EnKakasi_SetupSongTeach(this, globalCtx); + return; + } + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->skelanime.playSpeed = 1.0f; + EnKakasi_SetupDialogue(this); + return; + } + if (globalCtx->actorCtx.unk5 & 0x4) { + Actor_GetScreenPos(globalCtx, &this->actor, &x, &y); + if (this->actor.projectedPos.z > -20.0f && x > 0 && x < SCREEN_WIDTH && y > 0 && y < SCREEN_HEIGHT && + this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + // faster shaking + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + this->skelanime.playSpeed = 2.0f; + } + } else if (Player_GetMask(globalCtx) == PLAYER_MASK_KAMARO) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + this->skelanime.playSpeed = 2.0f; + } + } else if (saveContextDay == 3 && gSaveContext.save.isNight) { + this->skelanime.playSpeed = 1.0f; + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, 1); + } + } else if (this->animIndex != ENKAKASI_ANIM_IDLE) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_IDLE); + } + if (this->actor.xzDistToPlayer < 120.0f) { + func_800B8614(&this->actor, globalCtx, 100.0f); + func_800B874C(&this->actor, globalCtx, 100.0f, 80.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Update.s") +void EnKakasi_SetupDialogue(EnKakasi* this) { + // bug? starts one animation then changes it a few lines down? + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/func_80971CE0.s") + this->unkMsgState1AC = 5; + this->unkState196 = 1; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + this->actionFunc = EnKakasi_RegularDialogue; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kakasi/EnKakasi_Draw.s") +void EnKakasi_RegularDialogue(EnKakasi* this, GlobalContext* globalCtx) { + u32 saveContextDay = gSaveContext.save.day; + f32 currentAnimeFrame = this->skelanime.curFrame; + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 2000, 0); + // if first dialogue + if (this->actor.textId != 0x1644 && this->animeFrameCount <= currentAnimeFrame && + this->animIndex == ENKAKASI_ANIM_SLOWROLL) { + + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + this->unkCounter1A4 = 0; + } + + // if dialogue: oh sorry come back again + if (this->actor.textId == 0x1651 || this->actor.textId == 0x1659) { + if (this->animeFrameCount <= currentAnimeFrame && this->animIndex != ENKAKASI_ANIM_SPIN_REACH_OFFER) { + if (++this->unkCounter1A4 >= 2) { + this->unkCounter1A4 = 0; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + } + } + } + + if (this->unkState1A8 == 2 && this->unkState196 == 2) { + func_800B7298(globalCtx, &this->actor, 0x49); + this->unkState1A8 = 0; + } + + if ((this->unkMsgState1AC == Message_GetState(&globalCtx->msgCtx)) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + if (this->unkMsgState1AC == 5) { + // bad song input + if (this->unkState196 == 2 && this->actor.textId == 0x1647) { + func_800B7298(globalCtx, &this->actor, 6); + } + + // after timeskip + if (this->actor.textId == 0x1653) { + u32 saveContextDay2 = gSaveContext.save.day; + + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + + if (saveContextDay2 == 3 && gSaveContext.save.isNight) { + // text: dangerous outside + this->actor.textId = 0x164F; + } else if (gSaveContext.save.isNight) { + // text: would you like to skip time? + this->actor.textId = 0x164E; + } else { + // text: would you like to skip time? 2 + this->actor.textId = 0x1645; + } + + func_80151938(globalCtx, this->actor.textId); + return; + + } else if (this->actor.textId == 0x165D || this->actor.textId == 0x165F || this->actor.textId == 0x1660 || + this->actor.textId == 0x1652) { + func_800B7298(globalCtx, &this->actor, 4); + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_DancingRemark; + } else { + if (!ActorCutscene_GetCanPlayNext(this->actorCutscenes[0])) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_DancingRemark; + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + this->actionFunc = EnKakasi_DancingRemark; + } + } + return; + + } else if (this->actor.textId == 0x1645 || this->actor.textId == 0x164E) { + this->actor.textId = 0x1650; // "Shall we dance? No Yes" + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x1644) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (gSaveContext.save.isNight) { + this->actor.textId = 0x164E; + } else { + this->actor.textId = 0x1645; + } + + } else if (this->actor.textId == 0x164F) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->actor.textId = 0x165A; + } else if (this->actor.textId == 0x1651) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->actor.textId = 0x1654; + } else if (this->actor.textId == 0x1654) { + this->actor.textId = 0x1655; + } else if (this->actor.textId == 0x1655) { + this->actor.textId = 0x1656; + this->unkMsgState1AC = 4; + } else if (this->actor.textId == 0x1658) { + this->actor.textId = 0x1659; + } else if (this->actor.textId == 0x165A) { + this->actor.textId = 0x165B; + } else if (this->actor.textId == 0x165B) { + this->actor.textId = 0x165C; + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x165E) { + this->actor.textId = 0x165F; + } else { + EnKakasi_SetupIdleStanding(this); + return; + } + } else { + this->unkMsgState1AC = 5; + + if (globalCtx->msgCtx.choiceIndex == 1) { + func_8019F208(); + if (this->actor.textId == 0x1656) { + this->actor.textId = 0x1658; + } else if (this->actor.textId == 0x165C) { + this->actor.textId = 0x165E; + } else if (saveContextDay == 3 && gSaveContext.save.isNight) { + this->actor.textId = 0x164F; + } else { + this->actor.textId = 0x1652; + } + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + } else { + func_8019F230(); + if (this->actor.textId == 0x1656) { // would you like to learn a song? yes/no + this->actor.textId = 0x1657; + } else if (this->actor.textId == 0x165C) { // would you like to learn a song? yes/no + this->actor.textId = 0x165D; + } else { + this->actor.textId = 0x1651; + } + this->unkCounter1A4 = 0; + if (this->animIndex != ENKAKASI_ANIM_ARMS_CROSSED_ROCKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +void EnKakasi_SetupSongTeach(EnKakasi* this, GlobalContext* globalCtx) { + this->actor.textId = 0x1646; + Message_StartTextbox(globalCtx, this->actor.textId, &this->actor); + this->cutsceneCamId = CAM_ID_MAIN; + this->unk20C = 0.0f; + this->unk210 = 60.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + this->unkState196 = 2; + this->actionFunc = EnKakasi_OcarinaRemark; +} + +/* + * you took out ocarina hes talking about how he wants to hear you play him a song + * before actually teaching + */ +void EnKakasi_OcarinaRemark(EnKakasi* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_80152434(globalCtx, 0x35); + this->unkState1A8 = 0; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_TeachingSong; + + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + this->actionFunc = EnKakasi_TeachingSong; + + } else { + this->unkState1A8 = 1; + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->actionFunc = EnKakasi_TeachingSong; + } + } +} + +void EnKakasi_TeachingSong(EnKakasi* this, GlobalContext* globalCtx) { + Vec3f tempVec; + + EnKakasi_CheckPlayerPosition(this, globalCtx); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + if (this->unkState1A8 == 0) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->unkState1A8 = 1; + this->unkState1A8 = 1; + } + + if (this->unkState1A8 == 1) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + this->unk238.x = D_80971DCC[this->unk190].x; + this->unk238.y = D_80971DCC[this->unk190].y; + this->unk238.z = D_80971DCC[this->unk190].z; + + Math_Vec3f_Copy(&tempVec, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &tempVec, &this->unk238, 1); + Math_Vec3f_Copy(&this->unk244, &this->unk22C); + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + func_8096FAAC(this, globalCtx); + func_8096FBB8(this, globalCtx); + + if (globalCtx->msgCtx.ocarinaMode == 4) { // song failed + this->unk190 = 0; + this->unkCounter1A4 = 0; + ActorCutscene_Stop(this->actorCutscenes[0]); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YASE_DEAD); + if (this) {} + this->unkState196 = 2; + this->cutsceneCamId = CAM_ID_MAIN; + this->actor.textId = 0x1647; + this->unkState1A8 = 2; + this->unkMsgState1AC = 5; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + this->actionFunc = EnKakasi_RegularDialogue; + + } else if (globalCtx->msgCtx.ocarinaMode == 3) { // song success + this->postTeachTimer = 30; + this->skelanime.playSpeed = 2.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + this->actionFunc = EnKakasi_PostSongLearnTwirl; + } + } +} + +void EnKakasi_PostSongLearnTwirl(EnKakasi* this, GlobalContext* globalCtx) { + f32 animeFrame = this->skelanime.curFrame; + + if (this->postTeachTimer == 0 && this->animIndex != ENKAKASI_ANIM_TWIRL) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + this->skelanime.playSpeed = 2.0f; + } + if (this->postTeachTimer == 0 && this->animIndex == ENKAKASI_ANIM_TWIRL && this->animeFrameCount <= animeFrame) { + EnKakasi_SetupPostSongLearnDialogue(this, globalCtx); + } +} + +void EnKakasi_SetupPostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx) { + ActorCutscene_Stop(this->actorCutscenes[0]); + globalCtx->msgCtx.ocarinaMode = 4; + this->unk190 = 0; + this->unkCounter1A4 = 0; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_HOPPING_REGULAR); + this->cutsceneCamId = CAM_ID_MAIN; + this->unkMsgState1AC = 5; + this->unkState1A8 = 1; + this->actionFunc = EnKakasi_PostSongLearnDialogue; + this->unk20C = 0.0f; + this->unk210 = 60.0f; +} + +void EnKakasi_PostSongLearnDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 tempAnimFrame = this->skelanime.curFrame; + Vec3f vec3fCopy; + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + Math_SmoothStepToS(&player->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 5, 1000, 0); + + if (this->unk190 == 0) { + func_801477B4(globalCtx); + func_800B7298(globalCtx, &this->actor, 0x56); + this->actor.textId = 0x1648; + Message_StartTextbox(globalCtx, (this->actor.textId), &this->actor); + this->unkState1A8 = 0; + this->unk190 = 1; + } + + if (this->actor.textId == 0x1648 && this->animIndex == ENKAKASI_ANIM_HOPPING_REGULAR && + this->animeFrameCount <= tempAnimFrame) { + this->unkCounter1A4++; + if (this->unkCounter1A4 >= 2) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + } + + if (this->actor.textId == 0x164B && this->animIndex == ENKAKASI_ANIM_ARMS_CROSSED_ROCKING && + this->animeFrameCount <= tempAnimFrame) { + this->unkCounter1A4++; + if (this->unkCounter1A4 >= 2) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SPIN_REACH_OFFER); + } + } + + if (this->unkState1A8 == 0) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + return; + } + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + func_800B7298(globalCtx, &this->actor, 0x56); + this->unkState1A8 = 1; + } + + if (this->cutsceneCamId != CAM_ID_MAIN) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + EnKakasi_CheckPlayerPosition(this, globalCtx); + this->unk238.x = D_80971FA0[this->unk190].x; + this->unk238.y = D_80971FA0[this->unk190].y; + this->unk238.z = D_80971FA0[this->unk190].z; + Math_Vec3f_Copy(&vec3fCopy, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &vec3fCopy, &this->unk238, 1); + this->unk244.x = D_80971FE8[this->unk190].x + this->unk22C.x; + this->unk244.y = D_80971FE8[this->unk190].y + this->unk22C.y; + this->unk244.z = D_80971FE8[this->unk190].z + this->unk22C.z; + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + } + + func_8096FAAC(this, globalCtx); + + if ((this->unkState1A8 != 0) && (Message_GetState(&globalCtx->msgCtx) == this->unkMsgState1AC) && + Message_ShouldAdvance(globalCtx)) { + + func_801477B4(globalCtx); + + if (this->unkMsgState1AC == 5) { + this->unk190++; + if (this->unk190 > 5) { + this->unk190 = 5; + } + + if (this->actor.textId == 0x1648) { + func_800B7298(globalCtx, &this->actor, 7); + this->actor.textId = 0x1649; + if (this->animIndex != ENKAKASI_ANIM_ARMS_CROSSED_ROCKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_ARMS_CROSSED_ROCKING); + } + + } else if (this->actor.textId == 0x1649) { + this->actor.textId = 0x1660; + this->unkMsgState1AC = 4; + + } else if (this->actor.textId == 0x164A) { + this->actor.textId = 0x164B; + + } else if (this->actor.textId == 0x164B) { + this->actor.textId = 0x164C; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + + } else { + if (this->actor.textId == 0x164C || this->actor.textId == 0x1661) { + EnKakasi_SetupDigAway(this); + return; + } + } + + } else { + this->unkMsgState1AC = 5; + if (globalCtx->msgCtx.choiceIndex == 1) { + func_8019F208(); // play 0x4808 sfx (decide) and calls func_801A75E8 + this->actor.textId = 0x164A; + } else { + func_8019F230(); // play 0x480A sfx (cancel) and calls func_801A75E8 + this->actor.textId = 0x1661; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +/* + * talking before dancing the night away, and cutscene setup + */ +void EnKakasi_DancingRemark(EnKakasi* this, GlobalContext* globalCtx) { + u32 currentDay = gSaveContext.save.day; + + this->unkState196 = 3; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[0]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[0]); + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[0], &this->actor); + this->cutsceneCamId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + if (currentDay == 3 && gSaveContext.save.isNight) { + EnKakasi_SetupDigAway(this); + } else { + func_801A2BB8(NA_BGM_SARIAS_SONG); + EnKakasi_SetupDanceNightAway(this); + } + } +} + +void EnKakasi_SetupDanceNightAway(EnKakasi* this) { + this->unk190 = 0; + this->unkCounter1A4 = 0; + this->unk20C = 0.0f; + this->unk210 = 60.0f; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_TWIRL); + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + func_8016566C(0xB4); + this->actionFunc = EnKakasi_DancingNightAway; +} + +void EnKakasi_DancingNightAway(EnKakasi* this, GlobalContext* globalCtx) { + f32 currentFrame; + Vec3f localVec3f; + Player* player; + + currentFrame = this->skelanime.curFrame; + EnKakasi_CheckPlayerPosition(this, globalCtx); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 3000, 0); + this->unk22C.y = this->actor.home.pos.y + 50.0f; + + this->unk238.x = D_80971E38[this->unk190].x; + this->unk238.y = D_80971E38[this->unk190].y; + this->unk238.z = D_80971E38[this->unk190].z; + Math_Vec3f_Copy(&localVec3f, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &localVec3f, &this->unk238, 1); + + if (1) {} + this->unk244.x = D_80971EEC[this->unk190].x + this->unk22C.x; + this->unk244.y = D_80971EEC[this->unk190].y + this->unk22C.y; + this->unk244.z = D_80971EEC[this->unk190].z + this->unk22C.z; + if (this->unk190 != 6 && this->unk190 != 7) { + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + } + if (this->unk190 >= 7 && this->unk190 != 0xE) { + this->actor.shape.rot.y += 0x800; + } + + func_8096FAAC(this, globalCtx); + + // switching through manual cutscene states + switch (this->unk190) { + case 0: + // twirling + this->unk204 = 0x28; + this->unk190++; + return; + case 1: + // end of twirl, start shaking back and forth + if (this->unk204 == 0 && this->animeFrameCount <= currentFrame) { + this->unk204 = 0x14; + this->unk190++; + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + return; + case 2: + // camera view on the left + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 3: + // camera view on the right + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 4: + // camera view close up front + if (this->unk204 == 0) { + this->unk204 = 0x14; + this->unk190++; + } + return; + case 5: + // camera view zoomed out front + if (this->unk204 == 0) { + this->unk204 = 0xF; + this->unk190++; + } + return; + case 6: + // zoom in and sweep down in from case 5 + if (this->unk204 == 0) { + this->unk204 = 0xF; + this->unk190++; + } + return; + case 7: + // zoom in close from case 6 + if (this->unk204 == 0) { + this->unk204 = 0xA; + this->unk190++; + } + return; + + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + // multiple quick angle cuts viewing from multiple sides + if (this->unk204 == 0) { + this->unk190++; + this->unk204 = 0xA; + if (this->unk190 == 0xE) { + func_800B7298(globalCtx, &this->actor, 0x49); + func_80165690(); + this->unk204 = 0x14; + } + } + return; + case 14: + // goes off once for some camera changes, + // otherwise its the end when camera is back to normal and link is confused + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + if (this->unk204 == 0) { + player = GET_PLAYER(globalCtx); + + Play_SetRespawnData(&globalCtx->state, RESTART_MODE_DOWN, Entrance_CreateIndexFromSpawn(0), + player->unk_3CE, 0xBFF, &player->unk_3C0, player->unk_3CC); + func_80169EFC(&globalCtx->state); + + if (0) {} + if (gSaveContext.save.time > CLOCK_TIME(18, 0) || gSaveContext.save.time < CLOCK_TIME(6, 0)) { + gSaveContext.save.time = CLOCK_TIME(6, 0); + gSaveContext.respawnFlag = -4; + gSaveContext.eventInf[2] |= 0x80; + } else { + gSaveContext.save.time = CLOCK_TIME(18, 0); + gSaveContext.respawnFlag = -8; + } + gSaveContext.save.weekEventReg[83] |= 1; + this->unk190 = 0; + this->actionFunc = EnKakasi_DoNothing; + } + } +} + +void EnKakasi_DoNothing(EnKakasi* this, GlobalContext* globalCtx) { +} + +void EnKakasi_SetupDigAway(EnKakasi* this) { + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + this->unk190 = 0; + this->unkCounter1A4 = 0; + this->unk210 = 60.0f; + this->unk20C = 60.0f; + Math_Vec3f_Copy(&this->unk22C, &this->actor.home.pos); + this->unkState196 = 4; + this->actionFunc = EnKakasi_DiggingAway; +} + +void EnKakasi_DiggingAway(EnKakasi* this, GlobalContext* globalCtx) { + Vec3f tempunk238; + Vec3f tempWorldPos; + + if (this->cutsceneCamId != CAM_ID_MAIN) { + this->unk22C.y = this->actor.home.pos.y + 50.0f; + this->unk238.x = D_80972030.x; + this->unk238.y = D_80972030.y; + this->unk238.z = D_80972030.z; + + Math_Vec3f_Copy(&tempunk238, &this->unk238); + OLib_DbCameraVec3fSum(&this->actor.home, &tempunk238, &this->unk238, 1); + this->unk244.x = ((f32)D_8097203C.x) + this->unk22C.x; // cast req + this->unk244.y = ((f32)D_8097203C.y) + this->unk22C.y; + this->unk244.z = ((f32)D_8097203C.z) + this->unk22C.z; + Math_Vec3f_Copy(&this->unk214, &this->unk238); + Math_Vec3f_Copy(&this->unk220, &this->unk244); + func_8096FAAC(this, globalCtx); + } + + if (this->unkCounter1A4 < 15) { + this->unkCounter1A4++; + return; + } + + this->actor.shape.rot.y += 0x3000; + Math_SmoothStepToS(&this->unk190, 500, 5, 50, 0); + if ((globalCtx->gameplayFrames % 4) == 0) { + Math_Vec3f_Copy(&tempWorldPos, &this->actor.world.pos); + tempWorldPos.y = this->actor.floorHeight; + tempWorldPos.x += randPlusMinusPoint5Scaled(2.0f); + tempWorldPos.z += randPlusMinusPoint5Scaled(2.0f); + + if (globalCtx->sceneNum == SCENE_8ITEMSHOP) { + EffectSsGSplash_Spawn(globalCtx, &tempWorldPos, 0, 0, 0, randPlusMinusPoint5Scaled(100.0f) + 200.0f); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &tempWorldPos, 0x32, NA_SE_EV_BOMB_DROP_WATER); + + } else { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale - 20.0f, 5, 4.0f, 200, 10, 1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + } + } + + Math_ApproachF(&this->actor.shape.yOffset, -6000.0f, 0.5f, 200.0f); + if (fabsf(this->actor.shape.yOffset + 6000.0f) < 10.0f) { + gSaveContext.save.weekEventReg[79] |= 8; + func_800B7298(globalCtx, &this->actor, 6); + ActorCutscene_Stop(this->actorCutscenes[0]); + this->aboveGroundStatus = ENKAKASI_ABOVE_GROUND_TYPE; + this->songSummonDist = 80.0f; + EnKakasi_SetupIdleUnderground(this); + } +} + +void EnKakasi_SetupIdleUnderground(EnKakasi* this) { + this->actor.shape.yOffset = -7000.0; + this->actor.draw = NULL; + this->actor.flags |= ACTOR_FLAG_8000000; + this->unkState196 = 5; + this->actionFunc = EnKakasi_IdleUnderground; +} + +void EnKakasi_IdleUnderground(EnKakasi* this, GlobalContext* globalCtx) { + if ((gSaveContext.save.weekEventReg[79] & 8) && this->actor.xzDistToPlayer < this->songSummonDist && + (BREG(1) != 0 || globalCtx->msgCtx.ocarinaMode == 0xD)) { + this->actor.flags &= ~ACTOR_FLAG_8000000; + globalCtx->msgCtx.ocarinaMode = 4; + this->actionFunc = EnKakasi_SetupRiseOutOfGround; + } +} + +void EnKakasi_SetupRiseOutOfGround(EnKakasi* this, GlobalContext* globalCtx) { + s32 cutsceneIndex; + + cutsceneIndex = 0; + if (this->aboveGroundStatus == ENKAKASI_ABOVE_GROUND_TYPE) { + cutsceneIndex = 1; + } + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actorCutscenes[cutsceneIndex]); + + } else if (ActorCutscene_GetCanPlayNext(this->actorCutscenes[cutsceneIndex]) == 0) { + ActorCutscene_SetIntentToPlay(this->actorCutscenes[cutsceneIndex]); + + } else { + ActorCutscene_StartAndSetUnkLinkFields(this->actorCutscenes[cutsceneIndex], &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actor.draw = EnKakasi_Draw; + this->unkState196 = 6; + this->actionFunc = EnKakasi_RisingOutOfGround; + } +} + +void EnKakasi_RisingOutOfGround(EnKakasi* this, GlobalContext* globalCtx) { + this->actor.shape.rot.y += 0x3000; + + if (this->animIndex != ENKAKASI_ANIM_SIDEWAYS_SHAKING) { + EnKakasi_SetAnimation(this, ENKAKASI_ANIM_SIDEWAYS_SHAKING); + } + if (this->actor.shape.yOffset < -10.0f) { + if ((globalCtx->gameplayFrames % 8) == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, + this->actor.shape.shadowScale - 20.0f, 10, 8.0f, 500, 10, 1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + } + Math_ApproachF(&this->actor.shape.yOffset, 0.0f, 0.5f, 200.0f); + } else { + EnKakasi_SetupIdleRisen(this); + } +} + +void EnKakasi_SetupIdleRisen(EnKakasi* this) { + // text: great to see you again + this->actor.textId = 0x164D; + this->unkState196 = 7; + this->actionFunc = EnKakasi_IdleRisen; + this->actor.shape.yOffset = 0.0f; +} + +void EnKakasi_IdleRisen(EnKakasi* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = EnKakasi_RisenDialogue; + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void EnKakasi_RisenDialogue(EnKakasi* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 1000, 0); + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + EnKakasi_SetupIdleRisen(this); + } +} + +void EnKakasi_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + s32 pad; + + SkelAnime_Update(&this->skelanime); + if (this->actor.draw != NULL) { + EnKakasi_CheckAnimationSfx(this); + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + DECR(this->postTeachTimer); + DECR(this->unk204); + + if (this->unkState196 != 5) { + if (this->unk1BC.x != 0.0f || this->unk1BC.z != 0.0f) { + Math_Vec3f_Copy(&this->actor.focus.pos, &this->unk1BC); + this->actor.focus.pos.y += 10.0f; + if (this->cutsceneCamId == CAM_ID_MAIN) { + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } else { + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.home.rot); + } + } + } else { + Actor_SetFocus(&this->actor, this->unkHeight); + } + + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 50.0f, 100.0f, 0x1C); + if (this->actor.draw != NULL) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnKakasi_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnKakasi* this = THIS; + + if (limbIndex == 4) { + Matrix_MultVec3f(&gZeroVec3f, &this->unk1BC); + } +} + +void EnKakasi_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKakasi* this = THIS; + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelanime.skeleton, this->skelanime.jointTable, this->skelanime.dListCount, + NULL, EnKakasi_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h index b9a18adc5..2cb4f6cba 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.h @@ -6,14 +6,46 @@ struct EnKakasi; typedef void (*EnKakasiActionFunc)(struct EnKakasi*, GlobalContext*); +typedef void (*EnKakasiUnkFunc)(GlobalContext*, struct EnKakasi*); typedef struct EnKakasi { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4]; - /* 0x0148 */ EnKakasiActionFunc actionFunc; - /* 0x014C */ char unk_14C[0x154]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnKakasiUnkFunc unkFunc; // used for one z_snap calling function? + /* 0x148 */ EnKakasiActionFunc actionFunc; + /* 0x14C */ SkelAnime skelanime; + /* 0x190 */ s16 unk190; // camera index for song teaching angles? + /* 0x192 */ s16 postTeachTimer; + /* 0x194 */ s16 aboveGroundStatus; // from params, changed to 2 in init + /* 0x196 */ s16 unkState196; + /* 0x19A */ UNK_TYPE1 pad198[0x8]; + /* 0x1A0 */ s32 animIndex; + /* 0x1A4 */ s32 unkCounter1A4; // counter, counts up to F while he digs away, reused elsewhere + /* 0x1A8 */ s32 unkState1A8; + /* 0x1AC */ s16 unkMsgState1AC; // might be dialog state, compared against func(msgCtx) + /* 0x1AE */ s16 actorCutscenes[3]; + /* 0x1B4 */ f32 animeFrameCount; + /* 0x1B8 */ f32 unkHeight; + /* 0x1BC */ Vec3f unk1BC; // set by post limbdraw func for one limb + /* 0x1C8 */ UNK_TYPE1 pad1C8[0x3C]; + /* 0x204 */ s16 unk204; // set to A, F, 0x14, 0x28 frequently + /* 0x206 */ UNK_TYPE1 pad206[2]; + /* 0x208 */ s16 cutsceneCamId; + /* 0x20C */ f32 unk20C; // passed to unknown function + /* 0x210 */ f32 unk210; // used as a target for 20C to approach + /* 0x214 */ Vec3f unk214; // copied from unk238 regularly + /* 0x220 */ Vec3f unk220; //EnKakasi_TeachingSong + /* 0x22C */ Vec3f unk22C; //actor home copied to here + /* 0x238 */ Vec3f unk238; //copied from D_80971E38[unk190] + /* 0x244 */ Vec3f unk244; + /* 0x250 */ f32 songSummonDist; + /* 0x254 */ ColliderCylinder collider; } EnKakasi; // size = 0x2A0 extern const ActorInit En_Kakasi_InitVars; +#define ENKAKASI_ABOVE_GROUND_TYPE 2 + +#define GET_KAKASI_SUMMON_DISTANCE(this) ((this->actor.params >> 0x8) & 0xFF) +#define GET_KAKASI_ABOVE_GROUND(this) (this->actor.params & 0x1) + #endif // Z_EN_KAKASI_H 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 c932fd054..d2a1f9902 100644 --- a/src/overlays/actors/ovl_En_Kame/z_en_kame.c +++ b/src/overlays/actors/ovl_En_Kame/z_en_kame.c @@ -1,6 +1,13 @@ -#include "z_en_kame.h" +/* + * File: z_en_kame.c + * Overlay: ovl_En_Kame + * Description: Snapper Turtle + */ -#define FLAGS 0x00000405 +#include "z_en_kame.h" +#include "objects/object_tl/object_tl.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnKame*)thisx) @@ -9,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, @@ -36,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), @@ -82,107 +110,735 @@ 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, ActorShadow_DrawCircle, 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->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.6f; + this->drawDmgEffFrozenSteamScale = 0.90000004f; + this->drawDmgEffAlpha = 1.0f; + this->collider.base.colType = COLTYPE_HIT3; + this->unk_2A2 = 80; + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider.base.colType = COLTYPE_HIT6; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 10, 2, 0.3f, 0.2f); + this->actor.flags |= ACTOR_FLAG_400; + } +} -#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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&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 |= ACTOR_FLAG_10; + 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) { + Actor_PlaySfxAtPos(&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 &= ~ACTOR_FLAG_10; + 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 &= ~ACTOR_FLAG_10; + this->actor.shape.rot.z = 0; + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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 = ActorShadow_DrawCircle; + 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); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, sp36); + Actor_PlaySfxAtPos(&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); + Actor_SetColorFilter(&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 &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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) { + Actor_SetColorFilter(&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) { + SoundSource_PlaySfxEachFrameAtFixedWorldPos(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; + + Actor_SetDropFlag(&this->actor, &this->collider.info); + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (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; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffScale = 0.6f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + func_80AD7FA4(this); + } else if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2A2 = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&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->drawDmgEffScale = 0.6f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffScale = 0.6f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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 < SQ(200.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_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 60.0f, 40.0f, 0x1F); + + if (this->actor.shape.shadowDraw != NULL) { + Actor_SetFocus(&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->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.3f; + if (this->drawDmgEffScale > 0.6f) { + this->drawDmgEffScale = 0.6f; + } else { + this->drawDmgEffScale = this->drawDmgEffScale; + } + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 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_MultZero(&this->limbPos[D_80AD8EA4[limbIndex]]); + } + + if (limbIndex == 1) { + s32 i; + Vec3f* ptr; + Vec3f* ptr2; + + if (this->actor.shape.shadowDraw == NULL) { + Matrix_MultZero(&this->actor.world.pos); + } + + ptr2 = D_80AD8E68; + ptr = &this->limbPos[5]; + for (i = 0; i < ARRAY_COUNT(D_80AD8E68); i++) { + Matrix_MultVec3f(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); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); + + if (this->actor.shape.shadowDraw == NULL) { + ActorShadow_DrawCircle(&this->actor, NULL, globalCtx); + Actor_SetFocus(&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..d47e96d54 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 drawDmgEffType; + /* 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 drawDmgEffAlpha; + /* 0x02B4 */ f32 drawDmgEffScale; + /* 0x02B8 */ f32 drawDmgEffFrozenSteamScale; + /* 0x02BC */ Vec3f unk_2BC; + /* 0x02C8 */ Vec3f limbPos[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.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c index cccece638..921cb9633 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.c @@ -1,6 +1,14 @@ -#include "z_en_kanban.h" +/* + * File: z_en_kanban.c + * Overlay: ovl_En_Kanban + * Description: Square signpost + */ -#define FLAGS 0x00000019 +#include "z_en_kanban.h" +#include "objects/object_kanban/object_kanban.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnKanban*)thisx) @@ -9,7 +17,6 @@ void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx); void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kanban_InitVars = { ACTOR_EN_KANBAN, ACTORCAT_PROP, @@ -22,27 +29,1015 @@ const ActorInit En_Kanban_InitVars = { (ActorFunc)EnKanban_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80957300 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF3CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF3CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 50, 5, { 0, 0, 0 } }, }; +static u16 sPartFlags[] = { + PART_UPPER_LEFT, PART_LEFT_UPPER, PART_LEFT_LOWER, PART_RIGHT_UPPER, PART_RIGHT_LOWER, PART_LOWER_LEFT, + PART_UPPER_RIGHT, PART_LOWER_RIGHT, PART_POST_UPPER, PART_POST_LOWER, PART_POST_STAND, +}; + +static Vec3f sPieceOffsets[] = { + /* WHOLE_SIGN */ { 0.0f, 44.0f, 0.0f }, + /* UPPER_HALF */ { 0.0f, 50.0f, 0.0f }, + /* LOWER_HALF */ { 0.0f, 38.0f, 0.0f }, + /* RIGHT_HALF */ { 10.0f, 44.0f, 0.0f }, + /* LEFT_HALF */ { -10.0f, 44.0f, 0.0f }, + /* 2ND_QUAD */ { -10.0f, 50.0f, 0.0f }, + /* 1ST_QUAD */ { 10.0f, 50.0f, 0.0f }, + /* 3RD_QUAD */ { -10.0f, 38.0f, 0.0f }, + /* 4TH_QUAD */ { 10.0f, 38.0f, 0.0f }, + /* UPPER_LEFT */ { -7.5f, 51.0f, 0.0f }, + /* LEFT_UPPER */ { -12.5f, 48.0f, 0.0f }, + /* LEFT_LOWER */ { -12.5f, 40.0f, 0.0f }, + /* LOWER_LEFT */ { -7.5f, 37.0f, 0.0f }, + /* UPPER_RIGHT */ { 7.5f, 51.0f, 0.0f }, + /* RIGHT_UPPER */ { 12.5f, 48.0f, 0.0f }, + /* RIGHT_LOWER */ { 12.5f, 40.0f, 0.0f }, + /* LOWER_RIGHT */ { 7.5f, 37.0f, 0.0f }, + /* POST_UPPER */ { 0.0f, 50.0f, 0.0f }, + /* POST_LOWER */ { 0.0f, 38.0f, 0.0f }, +}; + +static Vec3f sPieceSizes[] = { + /* WHOLE_SIGN */ { 1500.0f, 1000.0f, 0.0f }, + /* UPPER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* LOWER_HALF */ { 1500.0f, 500.0f, 0.0f }, + /* RIGHT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* LEFT_HALF */ { 700.0f, 1000.0f, 0.0f }, + /* 2ND_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 1ST_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 3RD_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* 4TH_QUAD */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* LEFT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_LEFT */ { 700.0f, 500.0f, 0.0f }, + /* UPPER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_UPPER */ { 700.0f, 500.0f, 0.0f }, + /* RIGHT_LOWER */ { 700.0f, 500.0f, 0.0f }, + /* LOWER_RIGHT */ { 700.0f, 500.0f, 0.0f }, + /* POST_UPPER */ { 200.0f, 500.0f, 0.0f }, + /* POST_LOWER */ { 200.0f, 500.0f, 0.0f }, +}; + +static u8 sCutTypes[] = { + /* 1H_OVER */ CUT_VERT_L, /* 2H_OVER */ CUT_VERT_L, + /* 1H_COMBO */ CUT_DIAG_R, /* 2H_COMBO */ CUT_DIAG_R, + /* 1H_LEFT */ CUT_HORIZ, /* 2H_LEFT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_RIGHT */ CUT_HORIZ, /* 2H_RIGHT */ CUT_HORIZ, + /* 1H_COMBO */ CUT_HORIZ, /* 2H_COMBO */ CUT_HORIZ, + /* 1H_STAB */ CUT_POST, /* 2H_STAB */ CUT_POST, + /* 1H_COMBO */ CUT_POST, /* 2H_COMBO */ CUT_POST, + /* FLIP_START */ CUT_VERT_L, /* JUMP_START */ CUT_VERT_L, + /* FLIP_END */ CUT_VERT_L, /* JUMP_END */ CUT_VERT_L, + /* */ CUT_VERT_L, /* */ CUT_VERT_L, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* */ CUT_HORIZ, /* */ CUT_HORIZ, + /* BACK_LEFT */ CUT_HORIZ, /* BACK_RIGHT */ CUT_HORIZ, + /* OVER_HAMMER */ CUT_POST, /* SIDE_HAMMER */ CUT_POST, + /* 1H_SPIN_ATK */ CUT_POST, /* 2H_SPIN_ATK */ CUT_POST, + /* 1H_BIG_SPIN */ CUT_POST, /* 2H_BIG_SPIN */ CUT_POST, +}; + +static u16 sCutFlags[] = { + /* CUT_POST */ ALL_PARTS, /* CUT_VERT_L */ LEFT_HALF, + /* CUT_HORIZ */ UPPER_HALF, /* CUT_DIAG_L */ UPPERLEFT_HALF, + /* CUT_DIAG_R */ UPPERRIGHT_HALF, /* CUT_VERT_R */ RIGHT_HALF, +}; + +void func_80954960(EnKanban* this) { + f32 nx; + f32 ny; + f32 nz; + + if (this->actor.floorPoly != NULL) { + nx = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.x); + ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); + nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); + + this->floorRot.x = -func_80086B30(-nz * ny, 1.0f); + this->floorRot.z = func_80086B30(-nx * ny, 1.0f); + } +} + +void EnKanban_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + Actor_SetScale(&this->actor, 0.01f); + if (this->actor.params != ENKANBAN_PIECE) { + this->actor.targetMode = 0; + this->actor.flags |= ACTOR_FLAG_1; + this->unk_19A = Rand_ZeroFloat(1.9f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + if (this->actor.params == ENKANBAN_FISHING) { + if (LINK_IS_CHILD) { + this->actor.textId = 0x409D; + } else { + this->actor.textId = 0x4090; + } + } else { + this->actor.textId = this->actor.params | ENKANBAN_FISHING; + } + + this->bounceX = 1; + this->partFlags = 0xFFFF; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + } +} + +void EnKanban_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + + if (this->actionState == ENKANBAN_SIGN) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} + +void func_80954BE8(EnKanban* this, GlobalContext* globalCtx) { + s16 yaw; + + if (!this->msgFlag) { + if (this->msgTimer == 0) { + yaw = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (ABS_ALT(yaw) < 0x2800) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->msgFlag = true; + } else { + func_800B8614(&this->actor, globalCtx, 68.0f); + } + } + } else { + this->msgTimer--; + } + } else if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->msgFlag = false; + this->msgTimer = 20; + } +} + +#ifdef NON_MATCHING +// Lots of branch likely stuff +void EnKanban_Update(Actor* thisx, GlobalContext* globalCtx) { + // GlobalContext* globalCtx = globalCtx2; + u8 bounced = false; + s32 pad; + EnKanban* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Vec3f offset; + EnKanban* piece; + EnKanban* signpost; + s32 temp_v0_18; + f32 phi_f0; + s32 pad2; + + this->frameCount++; + + switch (this->actionState) { + case ENKANBAN_SIGN: + if (this->invincibilityTimer != 0) { + this->invincibilityTimer--; + } + + if (this->zTargetTimer != 0) { + this->zTargetTimer--; + } + + if (DECR(this->unk_1A0) == 0) { + this->unk_19C = NULL; + } + + if (this->zTargetTimer == 1) { + this->actor.flags &= ~ACTOR_FLAG_1; + } + + if (this->partFlags == 0xFFFF) { + func_80954BE8(this, globalCtx); + } + + if ((this->invincibilityTimer == 0) && (this->collider.base.acFlags & AC_HIT)) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_19C != this->collider.base.ac) { + this->unk_19C = this->collider.base.ac; + this->unk_1A0 = 3; + this->invincibilityTimer = 6; + + piece = (EnKanban*)Actor_SpawnAsChild( + &globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_KANBAN, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, ENKANBAN_PIECE); + if (piece != NULL) { + ColliderInfo* hitItem = this->collider.info.acHitInfo; + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + u8 i; + + if (hitItem->toucher.dmgFlags & 0x200) { + this->cutType = sCutTypes[player->swordAnimation]; + } else if (hitItem->toucher.dmgFlags & 0x10) { + this->invincibilityTimer = 0; + this->cutType = this->unk_19A + 3; + this->unk_19A = 1 - this->unk_19A; + if (this->unk_199 == 0) { + this->unk_199++; + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.focus.pos, 0x60); + } + } else { + this->cutType = 0; + } + + if ((ABS_ALT(yawDiff) > 0x4000) && !(hitItem->toucher.dmgFlags & 0x10)) { + if (this->cutType == 4) { + this->cutType = 3; + } else if (this->cutType == 1) { + this->cutType = 5; + } + } + + piece->partFlags = sCutFlags[this->cutType] & this->partFlags; + if (piece->partFlags == 0) { + Actor_MarkForDeath(&piece->actor); + return; + } + + piece->partCount = 0; + for (i = 0; i < 11; i++) { + if (sPartFlags[i] & piece->partFlags) { + piece->partCount++; + } + } + + this->partFlags &= ~sCutFlags[this->cutType]; + if ((this->partFlags & 0x3FF) == 0) { + this->zTargetTimer = 10; + } + + if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_WHOLE_SIGN; + } else if ((piece->partFlags & PART_LEFT_UPPER) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_UPPER_HALF; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_RIGHT_LOWER)) { + piece->pieceType = PIECE_LOWER_HALF; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_RIGHT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_LEFT_HALF; + } else if ((piece->partFlags & PART_UPPER_LEFT) && (piece->partFlags & PART_LEFT_UPPER)) { + piece->pieceType = PIECE_2ND_QUAD; + } else if ((piece->partFlags & PART_UPPER_RIGHT) && (piece->partFlags & PART_RIGHT_UPPER)) { + piece->pieceType = PIECE_1ST_QUAD; + } else if ((piece->partFlags & PART_LEFT_LOWER) && (piece->partFlags & PART_LOWER_LEFT)) { + piece->pieceType = PIECE_3RD_QUAD; + } else if ((piece->partFlags & PART_RIGHT_LOWER) && (piece->partFlags & PART_LOWER_RIGHT)) { + piece->pieceType = PIECE_4TH_QUAD; + } else if (piece->partFlags & PART_UPPER_LEFT) { + piece->pieceType = PIECE_UPPER_LEFT; + } else if (piece->partFlags & PART_LEFT_UPPER) { + piece->pieceType = PIECE_LEFT_UPPER; + } else if (piece->partFlags & PART_LEFT_LOWER) { + piece->pieceType = PIECE_LEFT_LOWER; + } else if (piece->partFlags & PART_LOWER_LEFT) { + piece->pieceType = PIECE_LOWER_LEFT; + } else if (piece->partFlags & PART_UPPER_RIGHT) { + piece->pieceType = PIECE_UPPER_RIGHT; + } else if (piece->partFlags & PART_RIGHT_UPPER) { + piece->pieceType = PIECE_RIGHT_UPPER; + } else if (piece->partFlags & PART_RIGHT_LOWER) { + piece->pieceType = PIECE_RIGHT_LOWER; + } else if (piece->partFlags & PART_LOWER_RIGHT) { + piece->pieceType = PIECE_LOWER_RIGHT; + } else if (piece->partFlags & PART_POST_UPPER) { + piece->pieceType = PIECE_POST_UPPER; + } else if (piece->partFlags & PART_POST_LOWER) { + piece->pieceType = PIECE_POST_LOWER; + } else { + piece->pieceType = PIECE_OTHER; + } + + if (piece->pieceType == PIECE_OTHER) { + piece->pieceType = PIECE_WHOLE_SIGN; + } + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sPieceOffsets[piece->pieceType], &offset); + piece->actor.world.pos.x += offset.x; + piece->actor.world.pos.y += offset.y; + piece->actor.world.pos.z += offset.z; + + piece->offset.x = -sPieceOffsets[piece->pieceType].x / this->actor.scale.x; + piece->offset.y = -sPieceOffsets[piece->pieceType].y / this->actor.scale.x; + piece->offset.z = -sPieceOffsets[piece->pieceType].z / this->actor.scale.x; + + piece->pieceWidth = sPieceSizes[piece->pieceType].x; + piece->pieceHeight = sPieceSizes[piece->pieceType].y; + piece->actionState = ENKANBAN_AIR; + piece->actor.gravity = -1.0f; + piece->actor.world.rot.y = + BINANG_ROT180((s32)randPlusMinusPoint5Scaled(0x4000) + this->actor.yawTowardsPlayer); + + if ((hitItem->toucher.dmgFlags & 0x10) || (hitItem->toucher.dmgFlags & 8) || + (hitItem->toucher.dmgFlags & 0x80000000)) { + piece->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; + piece->actor.speedXZ = Rand_ZeroFloat(4.0f) + 6.0f; + } else { + piece->actor.velocity.y = Rand_ZeroFloat(2.0f) + 3.0f; + piece->actor.speedXZ = Rand_ZeroFloat(2.0f) + 3.0f; + } + + if (piece->partCount >= 4) { + piece->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + piece->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + } else { + piece->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + piece->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + } + + piece->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + piece->direction = 1; + } else { + piece->direction = -1; + } + piece->airTimer = 100; + piece->actor.flags &= ~ACTOR_FLAG_1; + piece->actor.flags |= ACTOR_FLAG_2000000; + this->cutMarkTimer = 5; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SWORD_STRIKE); + } + } + } + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 44.0f; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actor.xzDistToPlayer > 500.0f) { + this->actor.flags |= ACTOR_FLAG_1; + this->partFlags = 0xFFFF; + } + + if (this->cutMarkTimer != 0) { + if (this->cutMarkTimer >= 5) { + this->cutMarkAlpha += 255; + if (this->cutMarkAlpha > 255) { + this->cutMarkAlpha = 255; + } + } else { + this->cutMarkAlpha -= 65; + if (this->cutMarkAlpha < 0) { + this->cutMarkAlpha = 0; + } + } + this->cutMarkTimer--; + } + break; + + case ENKANBAN_AIR: + case ENKANBAN_UNUSED: { + f32 tempX; + f32 tempY; + f32 tempZ; + f32 tempWaterDepth; + u16 tempBgFlags; + u8 onGround; + + if (this->unk_198 != 0) { + this->actor.velocity.y = -2.0f; + Actor_UpdatePos(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 10.0f, 50.0f, 5); + + tempX = this->actor.world.pos.x; + tempY = this->actor.world.pos.y; + tempZ = this->actor.world.pos.z; + tempBgFlags = this->actor.bgCheckFlags; + tempWaterDepth = this->actor.depthInWater; + this->actor.world.pos.z += ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 4); + func_80954960(this); + + this->actor.world.pos.x = tempX; + this->actor.world.pos.y = tempY; + this->actor.world.pos.z = tempZ; + this->actor.bgCheckFlags = tempBgFlags; + this->actor.depthInWater = tempWaterDepth; + + if (1) {} + + onGround = (this->actor.bgCheckFlags & 1); + + if (this->spinXFlag != 0) { + this->spinRot.x += this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x <= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } else { + this->spinRot.x -= this->spinVel.x; + this->spinVel.x -= 0x800; + if ((this->spinRot.x >= 0) && onGround) { + this->spinRot.x = 0; + this->spinVel.x = 0; + } + } + + if (this->spinVel.x < -0xC00) { + this->spinVel.x = -0xC00; + } + + if (this->spinZFlag != 0) { + this->spinRot.z += this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z <= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } else { + this->spinRot.z -= this->spinVel.z; + this->spinVel.z -= 0x800; + if ((this->spinRot.z >= 0) && onGround) { + this->spinRot.z = 0; + this->spinVel.z = 0; + } + } + + if (this->spinVel.z < -0xC00) { + this->spinVel.z = -0xC00; + } + + if (this->actor.bgCheckFlags & 8) { + if (!(this->actor.bgCheckFlags & 1)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + this->actor.speedXZ *= -0.5f; + } + + if (this->actor.bgCheckFlags & 0x40) { + this->actionState = ENKANBAN_WATER; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + this->bounceX = this->bounceZ = 0; + this->actor.world.pos.y += this->actor.depthInWater; + EffectSsGSplash_Spawn(globalCtx, &this->actor.world.pos, NULL, NULL, 0, (this->partCount * 20) + 300); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 150, 650, 0); + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, 300, 800, 5); + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + break; + } + + if (onGround) { + temp_v0_18 = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + + if ((temp_v0_18 == 15) || (temp_v0_18 == 14)) { + this->unk_197 = 1; + } else if (temp_v0_18 == 5) { + this->unk_197 = -1; + } + + if (this->bounceCount <= 0) { + this->bounceCount++; + if (this->unk_197 != 0) { + this->actor.velocity.y = 0.0f; + } else { + this->actor.velocity.y *= -0.3f; + this->actor.world.rot.y += (s16)randPlusMinusPoint5Scaled(0x4000); + } + bounced = true; + } else { + this->actor.velocity.y = 0.0f; + } + + if (this->unk_197 != 0) { + if (this->unk_197 > 0) { + this->actor.speedXZ = 0.0f; + } else if ((this->floorRot.x > 0.1f) || (this->floorRot.z > 0.1f)) { + this->airTimer = 10; + if (this->actor.bgCheckFlags & 8) { + this->actionState = ENKANBAN_GROUND; + this->actor.speedXZ = 0.0f; + goto nextCase; + } else { + Vec3f spC8; + + Matrix_RotateXFNew(this->floorRot.x); + Matrix_RotateZF(this->floorRot.z, MTXMODE_APPLY); + Matrix_MultVecY(KREG(20) + 10.0f, &spC8); + Math_ApproachF(&this->actor.velocity.x, spC8.x, 0.5f, (KREG(21) * 0.01f) + 0.1f); + Math_ApproachF(&this->actor.velocity.z, spC8.z, 0.5f, (KREG(21) * 0.01f) + 0.3f); + this->actor.world.rot.y = Math_Atan2S(spC8.x, spC8.z); + this->unk_198 = 1; + this->actor.speedXZ = sqrtf(SQXZ(this->actor.velocity)); + } + } else { + this->unk_198 = 0; + Math_ApproachZeroF(&this->actor.speedXZ, 1, 0.1f); + } + } else { + this->actor.speedXZ *= 0.7f; + } + + if (this->spinRot.x == 0) { + if (this->bounceX != 0) { + bounced = true; + if (this->unk_197 != 0) { + this->spinRot.x = 0; + this->bounceX = 0; + } else { + this->spinVel.x = this->bounceX << 9; + if (this->bounceX != 0) { + this->bounceX -= 5; + if (this->bounceX <= 0) { + this->bounceX = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinXFlag = 1; + } else { + this->spinXFlag = 0; + } + } + } + } + + if (this->spinRot.z == 0) { + if (this->bounceZ != 0) { + bounced = 1; + if (this->unk_197 != 0) { + this->spinRot.z = 0; + this->bounceZ = 0; + } else { + this->spinVel.z = this->bounceZ << 9; + if (this->bounceZ != 0) { + this->bounceZ -= 5; + if (this->bounceZ <= 0) { + this->bounceZ = 0; + } + } + + if (Rand_ZeroOne() < 0.5f) { + this->spinZFlag = 1; + } else { + this->spinZFlag = 0; + } + } + } + } + + Math_ApproachS(&this->actor.shape.rot.x, this->direction << 0xE, 1, 0x2000); + } else { + this->actor.shape.rot.y += this->spinVel.y; + this->actor.shape.rot.x += this->direction * 0x7D0; + } + + if (bounced) { + if (this->unk_197 > 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_SNOW); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + } + } + + if (bounced && (this->unk_197 >= 0)) { + s16 dustCount; + s16 j; + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; + static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; + Vec3f accel; + Vec3f pos; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + if (this->unk_197 != 0) { + primColor = D_8095754C; + envColor = D_8095754C; + } else { + primColor = D_80957548; + envColor = D_80957548; + } + + accel.x = 0.0f; + accel.y = 0.1f; + accel.z = 0.0f; + + pos.y = this->actor.floorHeight + 3.0f; + dustCount = this->partCount * 0.5f; + + for (j = 0; j < dustCount + 3; j++) { + pos.x = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.x; + pos.z = randPlusMinusPoint5Scaled((this->partCount * 0.5f) + 20.0f) + this->actor.world.pos.z; + func_800B0F18(globalCtx, &pos, &velocity, &accel, &primColor, &envColor, 100, 5, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + + if (DECR(this->airTimer) == 0) { + this->actionState = ENKANBAN_GROUND; + } + } + + case ENKANBAN_GROUND: + case ENKANBAN_WATER: + nextCase: + signpost = (EnKanban*)this->actor.parent; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + phi_f0 = 0.0f; + if (this->unk_197 > 0) { + phi_f0 = -150.0f; + } + + Math_ApproachF(&this->actor.shape.yOffset, 100.0f + phi_f0, 1.0f, 5.0f); + + if (this->actionState == ENKANBAN_WATER) { + s16 rippleDelay; + s32 rippleScale; + + if ((player->actor.speedXZ > 0.0f) && (player->actor.world.pos.y < this->actor.world.pos.y) && + (this->actor.xyzDistToPlayerSq < SQ(50.0f))) { + Math_ApproachF(&this->actor.speedXZ, player->actor.speedXZ, 1.0f, 0.2f); + if (this->actor.speedXZ > 1.0f) { + this->actor.speedXZ = 1.0f; + } + + if (Math_SmoothStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 1, + 0x1000, 0) > 0) { + this->spinVel.y = this->actor.speedXZ * 1000.0f; + } else { + this->spinVel.y = this->actor.speedXZ * -1000.0f; + } + } + + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = 0.0f; + } + + Actor_MoveWithGravity(&this->actor); + + if (this->actor.speedXZ != 0.0f) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 50.0f, 5); + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ *= -0.5f; + if (this->spinVel.y > 0) { + this->spinVel.y = -2000; + } else { + this->spinVel.y = 2000; + } + } + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.15f); + } + this->actor.shape.rot.y += this->spinVel.y; + Math_ApproachS(&this->spinVel.y, 0, 1, 0x3A); + Math_ApproachS(&this->actor.shape.rot.x, this->direction * 0x4000, 2, 0x1000); + Math_ApproachS(&this->spinRot.x, Math_SinS(this->frameCount * 2500) * 500.0f, 2, 0x1000); + Math_ApproachS(&this->spinRot.z, Math_CosS(this->frameCount * 3000) * 500.0f, 2, 0x1000); + Math_ApproachZeroF(&this->floorRot.x, 0.5f, 0.2f); + Math_ApproachZeroF(&this->floorRot.z, 0.5f, 0.2f); + + if (fabsf(this->actor.speedXZ) > 1.0f) { + rippleDelay = 0; + } else if (fabsf(this->actor.speedXZ) > 0.5f) { + rippleDelay = 3; + } else { + rippleDelay = 7; + } + + if (!(this->frameCount & rippleDelay)) { + if (this->partCount < 3) { + rippleScale = 0; + } else if (this->partCount < 6) { + rippleScale = 100; + } else { + rippleScale = 200; + } + EffectSsGRipple_Spawn(globalCtx, &this->actor.world.pos, rippleScale, rippleScale + 500, 0); + } + } else if ((globalCtx->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < SQ(100.0f))) { + f32 hammerStrength = (100.0f - sqrtf(this->actor.xyzDistToPlayerSq)) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x10000); + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.0f); + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 3.0f + hammerStrength; + this->actor.speedXZ = Rand_ZeroFloat(1.5f); + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + if (this->bounceX == 0) { + Actor* explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + f32 dx; + f32 dy; + f32 dz; + + while (explosive != NULL) { + if (explosive->params != 1) { + explosive = explosive->next; + continue; + } + + dx = this->actor.world.pos.x - explosive->world.pos.x; + dy = this->actor.world.pos.y - explosive->world.pos.y; + dz = this->actor.world.pos.z - explosive->world.pos.z; + + if (sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 100.0f) { + f32 bombStrength = (100.0f - sqrtf(SQ(dx) + SQ(dy) + SQ(dz))) * 0.05f; + + this->actionState = ENKANBAN_AIR; + this->actor.gravity = -1.0f; + this->actor.world.rot.y = Math_Atan2S(dx, dz); + + if (this->partCount >= 4) { + this->bounceX = Rand_ZeroFloat(10.0f) + 6.0f; + this->bounceZ = Rand_ZeroFloat(10.0f) + 6.0f; + this->actor.velocity.y = 2.5f + bombStrength; + this->actor.speedXZ = 3.0f + bombStrength; + } else { + this->bounceX = Rand_ZeroFloat(7.0f) + 3.0f; + this->bounceZ = Rand_ZeroFloat(7.0f) + 3.0f; + this->actor.velocity.y = 5.0f + bombStrength; + this->actor.speedXZ = 4.0f + bombStrength; + } + + this->spinVel.y = randPlusMinusPoint5Scaled(0x1800); + + if (Rand_ZeroOne() < 0.5f) { + this->direction = 1; + } else { + this->direction = -1; + } + this->airTimer = 70; + } + + explosive = explosive->next; + } + } + + switch (this->ocarinaFlag) { + case 0: + if (globalCtx->msgCtx.ocarinaMode == 1) { + this->ocarinaFlag = 1; + } + break; + + case 1: + if ((globalCtx->msgCtx.ocarinaMode == 4) && (globalCtx->msgCtx.unk1202E == 7)) { + this->actionState = ENKANBAN_REPAIR; + this->bounceX = 1; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + break; + } + break; + + case ENKANBAN_REPAIR: { + f32 distX; + f32 distY; + f32 distZ; + s16 pDiff; + s16 yDiff; + s16 rDiff; + + signpost = (EnKanban*)this->actor.parent; + signpost->invincibilityTimer = 5; + + if (signpost->partFlags == 0xFFFF) { + Actor_MarkForDeath(&this->actor); + } + + Matrix_RotateYS(signpost->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&sPieceOffsets[this->pieceType], &offset); + distX = + Math_SmoothStepToF(&this->actor.world.pos.x, signpost->actor.world.pos.x + offset.x, 1.0f, 3.0f, 0.0f); + distY = + Math_SmoothStepToF(&this->actor.world.pos.y, signpost->actor.world.pos.y + offset.y, 1.0f, 3.0f, 0.0f); + distZ = + Math_SmoothStepToF(&this->actor.world.pos.z, signpost->actor.world.pos.z + offset.z, 1.0f, 3.0f, 0.0f); + pDiff = Math_SmoothStepToS(&this->actor.shape.rot.x, signpost->actor.shape.rot.x, 1, 0x200, 0); + yDiff = Math_SmoothStepToS(&this->actor.shape.rot.y, signpost->actor.shape.rot.y, 1, 0x200, 0); + rDiff = Math_SmoothStepToS(&this->actor.shape.rot.z, signpost->actor.shape.rot.z, 1, 0x200, 0); + Math_ApproachS(&this->spinRot.x, 0, 1, 0x200); + Math_ApproachS(&this->spinRot.z, 0, 1, 0x200); + Math_ApproachZeroF(&this->floorRot.x, 1.0f, 0.05f); + Math_ApproachZeroF(&this->floorRot.z, 1.0f, 0.05f); + Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, 2.0f); + if (((distX + distY + distZ) == 0.0f) && + ((pDiff + yDiff + rDiff + this->spinRot.x + this->spinRot.z) == 0) && (this->floorRot.x == 0.0f) && + (this->floorRot.z == 0.0f)) { + signpost->partFlags |= this->partFlags; + signpost->actor.flags |= ACTOR_FLAG_1; + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + } +} +#else +static Vec3f D_8095753C = { 0.0f, 0.0f, 0.0f }; +static Color_RGBA8 D_80957548 = { 185, 140, 70, 255 }; +static Color_RGBA8 D_8095754C = { 255, 255, 255, 255 }; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") #endif -extern ColliderCylinderInit D_80957300; +static Gfx* sDisplayLists[] = { + object_kanban_DL_000CB0, object_kanban_DL_000DB8, object_kanban_DL_000E78, object_kanban_DL_000F38, + object_kanban_DL_000FF8, object_kanban_DL_0010B8, object_kanban_DL_0011C0, object_kanban_DL_0012C8, + object_kanban_DL_0013D0, object_kanban_DL_001488, object_kanban_DL_001540, +}; -extern UNK_TYPE D_06000C30; +#include "z_en_kanban_gfx.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954960.s") +static f32 sCutAngles[] = { + /* CUT_POST */ 0.50f * M_PI, + /* CUT_VERT_L */ 0.00f * M_PI, + /* CUT_HORIZ */ 0.50f * M_PI, + /* CUT_DIAG_L */ 0.66f * M_PI, + /* CUT_DIAG_R */ 0.34f * M_PI, + /* CUT_VERT_R */ 0.00f * M_PI, + /* */ 0.00f * M_PI, + /* */ 0.00f * M_PI, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Init.s") +#include "overlays/ovl_En_Kanban/ovl_En_Kanban.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Destroy.s") +void EnKanban_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKanban* this = THIS; + f32 zShift; + f32 zShift2; + s32 i; + Player* player = GET_PLAYER(globalCtx); + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, ARRAY_COUNT(sShadowTexFlags)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/func_80954BE8.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Update.s") + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kanban/EnKanban_Draw.s") + gSPDisplayList(POLY_OPA_DISP++, object_kanban_DL_000C30); + + if (this->actionState != ENKANBAN_SIGN) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateXFApply(this->floorRot.x); + Matrix_RotateZF(this->floorRot.z, MTXMODE_APPLY); + Matrix_Translate(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + + zShift = fabsf(Math_SinS(this->spinRot.x) * this->pieceHeight); + zShift2 = fabsf(Math_SinS(this->spinRot.z) * this->pieceWidth); + zShift = CLAMP_MIN(zShift, zShift2); + zShift *= -(f32)this->direction; + + Matrix_Translate(0.0f, 0.0f, zShift, MTXMODE_APPLY); + Matrix_RotateXS(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateYS(this->spinRot.z, MTXMODE_APPLY); + Matrix_Translate(this->offset.x, this->offset.y, this->offset.z - 100.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } else { + f32 phi_f0 = 0.0f; + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + phi_f0 = -15.0f; + } + this->actor.world.pos.y = this->actor.home.pos.y + phi_f0; + Matrix_Translate(0.0f, 0.0f, -100.0f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->partFlags == 0xFFFF) { + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05AED0); + } else { + for (i = 0; i < ARRAY_COUNT(sPartFlags); i++) { + if (sPartFlags[i] & this->partFlags) { + gSPDisplayList(POLY_OPA_DISP++, sDisplayLists[i]); + } + } + } + + if (this->cutMarkAlpha != 0) { + f32 cutOffset = (this->cutType == CUT_POST) ? -1200.0f : 0.0f; + + Matrix_Translate(0.0f, 4400.0f + cutOffset, 200.0f, MTXMODE_APPLY); + Matrix_RotateZF(sCutAngles[this->cutType], MTXMODE_APPLY); + Matrix_Scale(0.0f, 10.0f, 2.0f, MTXMODE_APPLY); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 255, 255, 255, this->cutMarkAlpha); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 150, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_kanban_DL_001630); + } + } + + if ((this->actor.projectedPos.z <= 400.0f) && (this->actor.projectedPos.z > 0.0f) && + (this->actor.floorHeight > -3000.0f) && ((this->bounceX != 0) || (this->bounceZ != 0))) { + u16 dayTime = gSaveContext.save.time; + f32 shadowAlpha; + + if (dayTime >= CLOCK_TIME(12, 0)) { + dayTime = (DAY_LENGTH - 1) - dayTime; + } + + shadowAlpha = (dayTime * 0.00275f) + 10.0f; + if (this->actor.projectedPos.z > 300.0f) { + shadowAlpha *= (400.0f - this->actor.projectedPos.z) * 0.01f; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 0, 0, 0, (s8)shadowAlpha); + + if ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_DEKU)) { + zShift = 0.0f; + } else { + zShift = ((this->actor.world.pos.y - this->actor.floorHeight) * -50.0f) / 100.0f; + } + + Matrix_Translate(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z + zShift, + MTXMODE_NEW); + Matrix_RotateXFApply(this->floorRot.x); + Matrix_RotateZF(this->floorRot.z, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, 0.0f, this->actor.scale.z, MTXMODE_APPLY); + + if (this->actionState == ENKANBAN_SIGN) { + Matrix_RotateXFApply(-M_PI / 5); + } + + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateXS(this->spinRot.x, MTXMODE_APPLY); + Matrix_RotateYS(this->spinRot.z, MTXMODE_APPLY); + Matrix_Translate(this->offset.x, this->offset.y, this->offset.z, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < ARRAY_COUNT(sShadowTexFlags); i++) { + if (sShadowTexFlags[i] & this->partFlags) { + shadowTex[i] = 0xFF; + } else { + shadowTex[i] = 0; + } + } + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(shadowTex)); + gSPDisplayList(POLY_XLU_DISP++, gEnKanban_D_80957DE0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..201364bc0 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h @@ -5,11 +5,106 @@ struct EnKanban; +#define PART_UPPER_LEFT (1 << 0) +#define PART_LEFT_UPPER (1 << 1) +#define PART_LEFT_LOWER (1 << 2) +#define PART_RIGHT_UPPER (1 << 3) +#define PART_RIGHT_LOWER (1 << 4) +#define PART_LOWER_LEFT (1 << 5) +#define PART_UPPER_RIGHT (1 << 6) +#define PART_LOWER_RIGHT (1 << 7) +#define PART_POST_UPPER (1 << 8) +#define PART_POST_LOWER (1 << 9) +#define PART_POST_STAND (1 << 10) +#define LEFT_HALF (PART_UPPER_LEFT | PART_LEFT_UPPER | PART_LEFT_LOWER | PART_LOWER_LEFT) +#define RIGHT_HALF (PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_RIGHT_LOWER | PART_LOWER_RIGHT) +#define UPPER_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERLEFT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_LEFT_LOWER | PART_UPPER_LEFT | PART_LEFT_UPPER) +#define UPPERRIGHT_HALF (PART_POST_UPPER | PART_UPPER_RIGHT | PART_RIGHT_UPPER | PART_UPPER_LEFT | PART_RIGHT_LOWER) +#define ALL_PARTS (LEFT_HALF | RIGHT_HALF | PART_POST_UPPER | PART_POST_LOWER) + +typedef enum { + /* 0 */ ENKANBAN_SIGN, + /* 1 */ ENKANBAN_AIR, + /* 2 */ ENKANBAN_UNUSED, + /* 3 */ ENKANBAN_GROUND, + /* 4 */ ENKANBAN_WATER, + /* 5 */ ENKANBAN_REPAIR +} EnKanbanActionState; + +typedef enum { + /* 0 */ PIECE_WHOLE_SIGN, + /* 1 */ PIECE_UPPER_HALF, + /* 2 */ PIECE_LOWER_HALF, + /* 3 */ PIECE_RIGHT_HALF, + /* 4 */ PIECE_LEFT_HALF, + /* 5 */ PIECE_2ND_QUAD, + /* 6 */ PIECE_1ST_QUAD, + /* 7 */ PIECE_3RD_QUAD, + /* 8 */ PIECE_4TH_QUAD, + /* 9 */ PIECE_UPPER_LEFT, + /* 10 */ PIECE_LEFT_UPPER, + /* 11 */ PIECE_LEFT_LOWER, + /* 12 */ PIECE_LOWER_LEFT, + /* 13 */ PIECE_UPPER_RIGHT, + /* 14 */ PIECE_RIGHT_UPPER, + /* 15 */ PIECE_RIGHT_LOWER, + /* 16 */ PIECE_LOWER_RIGHT, + /* 17 */ PIECE_POST_UPPER, + /* 18 */ PIECE_POST_LOWER, + /* 100 */ PIECE_OTHER = 100 +} EnKanbanPiece; + +typedef enum { + /* 0 */ CUT_POST, + /* 1 */ CUT_VERT_L, + /* 2 */ CUT_HORIZ, + /* 3 */ CUT_DIAG_L, // lower left to upper right + /* 4 */ CUT_DIAG_R, // upper left to lower right + /* 5 */ CUT_VERT_R +} EnKanbanCutType; + typedef struct EnKanban { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xAC]; + /* 0x144 */ UNK_TYPE1 unk_144[4]; // actionFunc? + /* 0x148 */ u8 frameCount; + /* 0x14A */ s16 airTimer; + /* 0x14C */ u8 actionState; + /* 0x14E */ u16 partFlags; + /* 0x150 */ u8 partCount; + /* 0x152 */ s16 invincibilityTimer; + /* 0x154 */ Vec3f offset; + /* 0x160 */ Vec3s spinRot; + /* 0x166 */ Vec3s spinVel; + /* 0x16C */ s8 spinXFlag; + /* 0x16D */ s8 spinZFlag; + /* 0x16E */ s16 bounceX; + /* 0x170 */ s16 bounceZ; + /* 0x172 */ u8 bounceCount; + /* 0x174 */ f32 pieceWidth; + /* 0x178 */ f32 pieceHeight; + /* 0x17C */ s16 direction; + /* 0x180 */ Vec3f floorRot; + /* 0x18C */ u8 cutType; + /* 0x18D */ u8 pieceType; + /* 0x18E */ s16 cutMarkTimer; + /* 0x190 */ s16 cutMarkAlpha; + /* 0x192 */ s16 zTargetTimer; + /* 0x194 */ u8 msgFlag; + /* 0x195 */ u8 msgTimer; + /* 0x196 */ u8 ocarinaFlag; + /* 0x197 */ s8 unk_197; + /* 0x198 */ s8 unk_198; + /* 0x199 */ u8 unk_199; + /* 0x19A */ u8 unk_19A; + /* 0x19C */ Actor* unk_19C; + /* 0x1A0 */ s16 unk_1A0; + /* 0x1A4 */ ColliderCylinder collider; } EnKanban; // size = 0x1F0 +#define ENKANBAN_PIECE ((s16)0xFFDD) +#define ENKANBAN_FISHING 0x300 + extern const ActorInit En_Kanban_InitVars; #endif // Z_EN_KANBAN_H diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c new file mode 100644 index 000000000..c38e9df94 --- /dev/null +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban_gfx.c @@ -0,0 +1,68 @@ +#include "z_en_kanban.h" + +static u16 sShadowTexFlags[] = { + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, + 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x100, 0x100, + 0x100, 0x100, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, + 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x040, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x001, 0x001, 0x101, 0x101, + 0x140, 0x140, 0x040, 0x040, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x002, 0x102, 0x301, + 0x340, 0x108, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, 0x008, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x204, 0x220, + 0x280, 0x210, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, 0x010, 0x010, 0x010, + 0x004, 0x004, 0x004, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x220, + 0x280, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x010, 0x010, 0x010, + 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x020, 0x220, 0x620, + 0x680, 0x280, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, 0x080, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, + 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x400, 0x400, + 0x400, 0x400, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, +}; diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c index 1d2d13da1..94452e054 100644 --- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c +++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.c @@ -1,6 +1,14 @@ -#include "z_en_karebaba.h" +/* + * File: z_en_karebaba.c + * Overlay: ovl_En_Karebaba + * Description: Wilted Deku Baba + */ -#define FLAGS 0x00000005 +#include "z_en_karebaba.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_dekubaba/object_dekubaba.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnKarebaba*)thisx) @@ -9,19 +17,28 @@ void EnKarebaba_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKarebaba_Update(Actor* thisx, GlobalContext* globalCtx); void EnKarebaba_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_808F155C(EnKarebaba* this); void func_808F15B0(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F1648(EnKarebaba* this); void func_808F169C(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F16FC(EnKarebaba* this); void func_808F1778(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F1878(EnKarebaba* this); void func_808F190C(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F1A3C(EnKarebaba* this); void func_808F1A58(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F1BF8(EnKarebaba* this); void func_808F1C84(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F1FAC(EnKarebaba* this); void func_808F200C(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F20FC(EnKarebaba* this, GlobalContext* globalCtx); void func_808F21A4(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F220C(EnKarebaba* this); void func_808F228C(EnKarebaba* this, GlobalContext* globalCtx); +void func_808F238C(EnKarebaba* this); void func_808F241C(EnKarebaba* this, GlobalContext* globalCtx); void func_808F254C(EnKarebaba* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Karebaba_InitVars = { ACTOR_EN_KAREBABA, ACTORCAT_ENEMY, @@ -34,25 +51,49 @@ const ActorInit En_Karebaba_InitVars = { (ActorFunc)EnKarebaba_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808F2DA0 = { - { COLTYPE_HARD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HARD, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 7, 25, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808F2DCC = { - { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_WOOD, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_WOOD, + BUMP_NONE, + OCELEM_ON, + }, { 4, 25, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808F2DF8 = { 1, 15, 80, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 80, MASS_HEAVY }; -// static DamageTable sDamageTable = { -static DamageTable D_808F2E00 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(3, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -87,79 +128,613 @@ static DamageTable D_808F2E00 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808F2E20[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2500, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 1, ICHAIN_STOP), }; -#endif +Color_RGBA8 D_808F2E28 = { 0, 0, 0, 0 }; -extern ColliderCylinderInit D_808F2DA0; -extern ColliderCylinderInit D_808F2DCC; -extern CollisionCheckInfoInit D_808F2DF8; -extern DamageTable D_808F2E00; -extern InitChainEntry D_808F2E20[]; +Gfx* D_808F2E2C[] = { object_dekubaba_DL_001330, object_dekubaba_DL_001628, object_dekubaba_DL_001828 }; -extern UNK_TYPE D_060002B8; -extern UNK_TYPE D_06003070; +void EnKarebaba_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKarebaba* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/EnKarebaba_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 22.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_dekubaba_Skel_002A40, &object_dekubaba_Anim_0002B8, + this->jointTable, this->morphTable, 8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/EnKarebaba_Destroy.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit1); + Collider_UpdateCylinder(&this->actor, &this->collider2); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit2); + Collider_UpdateCylinder(&this->actor, &this->collider1); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1374.s") + this->unk_22C = NULL; + if (this->actor.params == ENKAREBABA_2) { + this->actor.hintId = 2; + } else { + this->actor.hintId = 9; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F13FC.s") + if (this->actor.params == ENKAREBABA_0) { + func_808F155C(this); + } else { + func_808F1648(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F152C.s") +void EnKarebaba_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKarebaba* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F155C.s") + Collider_DestroyCylinder(globalCtx, &this->collider2); + Collider_DestroyCylinder(globalCtx, &this->collider1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F15B0.s") +void func_808F1374(EnKarebaba* this, GlobalContext* globalCtx) { + s32 phi_a3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1648.s") + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + if (this->actor.params == ENKAREBABA_2) { + phi_a3 = 1; + } else { + phi_a3 = 4; + } + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, phi_a3, 4, 0.3f, 0.2f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F169C.s") +void func_808F13FC(EnKarebaba* this, GlobalContext* globalCtx) { + if (this->actor.colChkInfo.damageEffect == 2) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 3.0f; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffScale = 0.75f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 3.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider2.info.bumper.hitPos.x, + this->collider2.info.bumper.hitPos.y, this->collider2.info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_SMALL_LIGHT_RAYS); + } else if (this->actor.colChkInfo.damageEffect == 3) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffFrozenSteamScale = 1.125f; + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 3.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F16FC.s") +void func_808F152C(EnKarebaba* this) { + this->collider2.dim.radius = 7; + this->collider2.dim.height = 25; + this->collider2.base.colType = COLTYPE_HARD; + this->collider2.base.acFlags |= AC_HARD; + this->collider1.dim.height = 25; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1778.s") +void func_808F155C(EnKarebaba* this) { + Actor_SetScale(&this->actor, 0.0f); + this->actor.shape.rot.x = -0x4000; + this->unk_1EE = 0; + this->actor.world.pos.y = this->actor.home.pos.y + 14.0f; + this->actionFunc = func_808F15B0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1878.s") +void func_808F15B0(EnKarebaba* this, GlobalContext* globalCtx) { + f32 sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F190C.s") + this->unk_1EE++; + sp1C = this->unk_1EE * 0.05f; + Actor_SetScale(&this->actor, 0.005f * sp1C); + this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * sp1C); + if (this->unk_1EE == 20) { + func_808F1648(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1A3C.s") +void func_808F1648(EnKarebaba* this) { + Actor_SetScale(&this->actor, 0.005f); + this->actor.shape.rot.x = -0x4000; + this->actor.world.pos.y = this->actor.home.pos.y + 14.0f; + this->actionFunc = func_808F169C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1A58.s") +void func_808F169C(EnKarebaba* this, GlobalContext* globalCtx) { + if ((this->actor.xzDistToPlayer < 200.0f) && (fabsf(this->actor.playerHeightRel) < 30.0f)) { + func_808F16FC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1BF8.s") +void func_808F16FC(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, 4.0f, 0.0f, + Animation_GetLastFrame(&object_dekubaba_Anim_0002B8), 0, -3.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_WAKEUP); + this->actionFunc = func_808F1778; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1C84.s") +void func_808F1778(EnKarebaba* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F1FAC.s") + if (Math_StepToF(&this->actor.scale.x, 0.01f, 0.0005f) && (this->actor.params == ENKAREBABA_2)) { + func_808F1878(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F200C.s") + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.x; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F20FC.s") + if ((this->actor.params == ENKAREBABA_1) && + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 60.0f, 5.0f)) { + func_808F1878(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F21A4.s") + this->actor.shape.rot.y += 0x1999; + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.home.pos, 3.0f, 0, 12, 5, 1, -1, 10, NULL); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F220C.s") +void func_808F1878(EnKarebaba* this) { + if (this->actionFunc != func_808F1A58) { + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F228C.s") + this->collider2.base.colType = COLTYPE_HIT6; + this->collider2.base.acFlags &= ~AC_HARD; + this->collider2.dim.radius = 15; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F238C.s") + if (this->actor.params == ENKAREBABA_1) { + this->collider2.dim.height = 80; + this->collider1.dim.height = 80; + } else { + this->collider2.dim.height = 35; + this->collider1.dim.height = 35; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F241C.s") + this->unk_1EE = 40; + this->actionFunc = func_808F190C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F24F8.s") +void func_808F190C(EnKarebaba* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F254C.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/EnKarebaba_Update.s") + if (this->unk_1EE != 0) { + this->unk_1EE--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/func_808F280C.s") + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Karebaba/EnKarebaba_Draw.s") + if (this->collider2.base.acFlags & AC_HIT) { + func_808F13FC(this, globalCtx); + if (this->actor.params == ENKAREBABA_1) { + func_808F1BF8(this); + } else { + func_808F1FAC(this); + } + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } else if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) > 240.0f) { + func_808F220C(this); + } else if ((this->unk_1EE == 0) && (this->actor.params == ENKAREBABA_1)) { + func_808F1A3C(this); + } +} + +void func_808F1A3C(EnKarebaba* this) { + this->unk_1EE = 40; + this->actionFunc = func_808F1A58; +} + +void func_808F1A58(EnKarebaba* this, GlobalContext* globalCtx) { + s32 phi_v0; + f32 sp28; + + if (this->unk_1EE != 0) { + this->unk_1EE--; + } + + SkelAnime_Update(&this->skelAnime); + + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA1_MOUTH); + } + + phi_v0 = 20 - this->unk_1EE; + phi_v0 = 20 - ABS_ALT(phi_v0); + if (phi_v0 > 10) { + phi_v0 = 10; + } + + this->collider1.dim.radius = sCylinderInit2.dim.radius + (phi_v0 * 2); + this->actor.shape.rot.x = 0xC000 - (phi_v0 << 8); + this->actor.shape.rot.y += phi_v0 * 0x2C0; + this->actor.world.pos.y = (Math_SinS(this->actor.shape.rot.x) * -60.0f) + this->actor.home.pos.y; + + sp28 = Math_CosS(this->actor.shape.rot.x) * 60.0f; + this->actor.world.pos.x = (Math_SinS(this->actor.shape.rot.y) * sp28) + this->actor.home.pos.x; + this->actor.world.pos.z = (Math_CosS(this->actor.shape.rot.y) * sp28) + this->actor.home.pos.z; + + if (this->collider2.base.acFlags & AC_HIT) { + func_808F13FC(this, globalCtx); + func_808F1BF8(this); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } else if (this->unk_1EE == 0) { + func_808F1878(this); + } +} + +void func_808F1BF8(EnKarebaba* this) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->unk_1EE = 0; + this->actor.gravity = -0.8f; + this->actor.velocity.y = 4.0f; + this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); + this->actor.speedXZ = 3.0f; + } else { + this->unk_1EE = 3; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_JR_DEAD); + this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); + this->actionFunc = func_808F1C84; +} + +void func_808F1C84(EnKarebaba* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp78; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->unk_1EE--; + if (this->unk_1EE == 0) { + this->actor.gravity = -0.8f; + this->actor.speedXZ = 3.0f; + this->actor.velocity.y = 4.0f; + this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); + func_808F1374(this, globalCtx); + } + } else { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f); + + if (this->unk_1EE == 0) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4800, 0x71C); + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 3.0f, 0, 12, 5, 1, -1, 10, NULL); + + if ((this->actor.scale.x > 0.005f) && ((this->actor.bgCheckFlags & 2) || (this->actor.bgCheckFlags & 8))) { + this->actor.scale.z = 0.0f; + this->actor.scale.y = 0.0f; + this->actor.scale.x = 0.0f; + this->actor.speedXZ = 0.0f; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 3.0f, 0, 12, 5, 15, -1, 10, NULL); + } + + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + this->unk_1EE = 1; + } + } else if (this->unk_1EE == 1) { + Math_Vec3f_Copy(&sp78, &this->actor.world.pos); + + temp_f24 = Math_SinS(this->actor.shape.rot.x) * 20.0f; + temp_f20 = (-20.0f * Math_CosS(this->actor.shape.rot.x)) * Math_SinS(this->actor.shape.rot.y); + temp_f22 = (-20.0f * Math_CosS(this->actor.shape.rot.x)) * Math_CosS(this->actor.shape.rot.y); + + for (i = 0; i < 4; i++) { + func_800B1210(globalCtx, &sp78, &gZeroVec3f, &gZeroVec3f, 500, 50); + sp78.x += temp_f20; + sp78.y += temp_f24; + sp78.z += temp_f22; + } + + func_800B1210(globalCtx, &this->actor.home.pos, &gZeroVec3f, &gZeroVec3f, 500, 100); + func_808F20FC(this, globalCtx); + } + } +} + +void func_808F1FAC(EnKarebaba* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEKU_JR_DEAD); + this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); + this->actor.flags &= ~ACTOR_FLAG_1; + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->unk_1EE = 3; + } + this->actionFunc = func_808F200C; +} + +void func_808F200C(EnKarebaba* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->unk_1EE--; + if (this->unk_1EE == 0) { + func_808F1374(this, globalCtx); + } + } else { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.0005f)) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_NUTS_1); + func_808F238C(this); + } else { + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 3.0f, 0, 12, 5, 1, -1, 10, NULL); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 1.0f); + } + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + } +} + +void func_808F20FC(EnKarebaba* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->actor, 0.03f); + this->actor.shape.rot.x -= 0x4000; + this->actor.shape.yOffset = 1000.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.shape.shadowScale = 3.0f; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 8); + this->unk_1EE = 200; + this->actor.flags &= ~ACTOR_FLAG_20; + this->drawDmgEffAlpha = 0.0f; + this->actionFunc = func_808F21A4; +} + +void func_808F21A4(EnKarebaba* this, GlobalContext* globalCtx) { + if (this->unk_1EE != 0) { + this->unk_1EE--; + } + + if (Actor_HasParent(&this->actor, globalCtx) || (this->unk_1EE == 0)) { + func_808F238C(this); + } else { + Actor_PickUpNearby(&this->actor, globalCtx, GI_STICKS_1); + } +} + +void func_808F220C(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, -3.0f, + Animation_GetLastFrame(&object_dekubaba_Anim_0002B8), 0.0f, 2, -3.0f); + func_808F152C(this); + this->actionFunc = func_808F228C; +} + +void func_808F228C(EnKarebaba* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Math_StepToF(&this->actor.scale.x, 0.005f, 0.0005f) && (this->actor.params == ENKAREBABA_2)) { + func_808F1648(this); + } + + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.x; + + if ((this->actor.params == ENKAREBABA_1) && + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 14.0f, 5.0f)) { + func_808F1648(this); + } + + this->actor.shape.rot.y += 0x1999; + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.home.pos, 3.0f, 0, 12, 5, 1, -1, 10, NULL); +} + +void func_808F238C(EnKarebaba* this) { + Animation_Change(&this->skelAnime, &object_dekubaba_Anim_0002B8, 0.0f, 0.0f, 0.0f, 2, 0.0f); + func_808F152C(this); + this->actor.shape.rot.x = -0x4000; + this->unk_1EE = 200; + this->actor.parent = NULL; + this->actor.shape.shadowScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actionFunc = func_808F254C; +} + +void func_808F241C(EnKarebaba* this, GlobalContext* globalCtx) { + f32 sp1C; + + this->unk_1EE++; + sp1C = this->unk_1EE * 0.05f; + Actor_SetScale(&this->actor, 0.005f * sp1C); + this->actor.world.pos.y = this->actor.home.pos.y + (14.0f * sp1C); + + if (this->unk_1EE == 20) { + this->actor.flags &= ~ACTOR_FLAG_10; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); + if (this->actor.params == ENKAREBABA_1) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 5); + } + func_808F1648(this); + } +} + +void func_808F24F8(EnKarebaba* this) { + this->actor.shape.yOffset = 0.0f; + this->actor.shape.shadowScale = 22.0f; + this->collider1.dim.radius = sCylinderInit2.dim.radius; + Actor_SetScale(&this->actor, 0.0f); + this->actionFunc = func_808F241C; +} + +void func_808F254C(EnKarebaba* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (this->unk_1EE != 0) { + this->unk_1EE--; + } + + if (this->unk_1EE == 0) { + func_808F24F8(this); + } +} + +void EnKarebaba_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnKarebaba* this = THIS; + f32 max; + + this->actionFunc(this, globalCtx); + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.375f; + if (this->drawDmgEffScale > 0.75f) { + this->drawDmgEffScale = 0.75f; + } else { + this->drawDmgEffScale = this->drawDmgEffScale; + } + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.01875f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + + if (this->actionFunc != func_808F254C) { + if (this->actionFunc == func_808F1C84) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 15.0f, 10.0f, 5); + } else { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + if (this->unk_22C == 0) { + this->unk_22C = this->actor.floorPoly; + } + } + + if ((this->actionFunc != func_808F1C84) && (this->actionFunc != func_808F200C) && + (this->actionFunc != func_808F21A4)) { + if ((this->actionFunc != func_808F241C) && (this->actionFunc != func_808F15B0)) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + Actor_SetFocus(&this->actor, (this->actor.scale.x * 10.0f) / 0.01f); + + max = this->actor.home.pos.y + 40.0f; + this->actor.focus.pos.x = this->actor.home.pos.x; + this->actor.focus.pos.y = CLAMP_MAX(this->actor.focus.pos.y, max); + this->actor.focus.pos.z = this->actor.home.pos.z; + } + } +} + +void func_808F280C(EnKarebaba* this, GlobalContext* globalCtx) { + MtxF sp40; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C448(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 255); + + func_800C0094(this->unk_22C, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, &sp40); + Matrix_Mult(&sp40, MTXMODE_NEW); + Matrix_Scale(0.15f, 1.0f, 0.15f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gCircleShadowDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnKarebaba_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKarebaba* this = THIS; + s32 i; + s32 sp94; + s16 limbCount; + f32 sp8C = 0.01f; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Math_Vec3f_Copy(this->limbPos, &this->actor.world.pos); + + if (this->actionFunc == func_808F21A4) { + if ((this->unk_1EE > 40) || (this->unk_1EE & 1)) { + Matrix_Translate(0.0f, 0.0f, 200.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++, object_dekubaba_DL_003070); + } + } else if (this->actionFunc != func_808F254C) { + func_800AE2A0(globalCtx, &D_808F2E28, 1, 2); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, NULL); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + + if ((this->actionFunc == func_808F241C) || (this->actionFunc == func_808F200C) || + (this->actionFunc == func_808F15B0)) { + sp8C = this->unk_1EE * 0.0005f; + } + + Matrix_Scale(sp8C, sp8C, sp8C, MTXMODE_APPLY); + Matrix_RotateZYX(this->actor.shape.rot.x, this->actor.shape.rot.y, 0, MTXMODE_APPLY); + + if (this->actor.params == ENKAREBABA_2) { + sp94 = 1; + } else if (this->actionFunc == func_808F1C84) { + sp94 = 2; + } else { + sp94 = 3; + } + + for (i = 0; i < sp94; i++) { + Matrix_Translate(0.0f, 0.0f, -2000.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_808F2E2C[i]); + + Matrix_MultZero(&this->limbPos[1 + i]); + if ((i == 0) && (this->actionFunc == func_808F1C84)) { + Matrix_MultZero(&this->actor.focus.pos); + } + } + + func_800AE5A0(globalCtx); + } + + func_800AE2A0(globalCtx, &D_808F2E28, 1, 2); + Matrix_Translate(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, MTXMODE_NEW); + + if (this->actionFunc != func_808F15B0) { + sp8C = 0.01f; + } + + Matrix_Scale(sp8C, sp8C, sp8C, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.home.rot.y, 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_dekubaba_DL_0010F0); + + if (this->actionFunc == func_808F1C84) { + Matrix_RotateZYX(-0x4000, this->actor.shape.rot.y - this->actor.home.rot.y, 0, 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_dekubaba_DL_001828); + + Matrix_MultZero(&this->limbPos[3]); + } + + func_800AE5A0(globalCtx); + + if (this->actor.params == ENKAREBABA_2) { + limbCount = 1; + } else { + limbCount = ARRAY_COUNT(this->limbPos); + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, limbCount, this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); + + if (this->unk_22C != 0) { + func_808F280C(this, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h index 094876643..e91e151ae 100644 --- a/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h +++ b/src/overlays/actors/ovl_En_Karebaba/z_en_karebaba.h @@ -7,11 +7,27 @@ struct EnKarebaba; typedef void (*EnKarebabaActionFunc)(struct EnKarebaba*, GlobalContext*); +enum { + /* 0 */ ENKAREBABA_0, + /* 1 */ ENKAREBABA_1, + /* 2 */ ENKAREBABA_2, +}; + typedef struct EnKarebaba { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnKarebabaActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x13C]; + /* 0x018C */ Vec3s jointTable[8]; + /* 0x01BC */ Vec3s morphTable[8]; + /* 0x01EC */ u8 drawDmgEffType; + /* 0x01EE */ s16 unk_1EE; + /* 0x01F0 */ f32 drawDmgEffAlpha; + /* 0x01F4 */ f32 drawDmgEffScale; + /* 0x01F8 */ f32 drawDmgEffFrozenSteamScale; + /* 0x01FC */ Vec3f limbPos[4]; + /* 0x022C */ CollisionPoly* unk_22C; + /* 0x0230 */ ColliderCylinder collider1; + /* 0x027C */ ColliderCylinder collider2; } EnKarebaba; // size = 0x2C8 extern const ActorInit En_Karebaba_InitVars; diff --git a/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c b/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c index 159ce61f0..095378137 100644 --- a/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c +++ b/src/overlays/actors/ovl_En_Kbt/z_en_kbt.c @@ -1,6 +1,12 @@ +/* + * File: z_en_kbt.c + * Overlay: ovl_En_Kbt + * Description: Zubora + */ + #include "z_en_kbt.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnKbt*)thisx) @@ -9,10 +15,13 @@ void EnKbt_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKbt_Update(Actor* thisx, GlobalContext* globalCtx); void EnKbt_Draw(Actor* thisx, GlobalContext* globalCtx); +s32 func_80B33E64(GlobalContext* globalCtx); +s32 func_80B33E8C(GlobalContext* globalCtx); +void func_80B33EF0(EnKbt* this, s16 arg1); +Actor* func_80B3403C(GlobalContext* globalCtx); void func_80B34314(EnKbt* this, GlobalContext* globalCtx); void func_80B34598(EnKbt* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kbt_InitVars = { ACTOR_EN_KBT, ACTORCAT_NPC, @@ -25,36 +34,543 @@ const ActorInit En_Kbt_InitVars = { (ActorFunc)EnKbt_Draw, }; -#endif +void EnKbt_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKbt* this = THIS; -extern UNK_TYPE D_06004274; + Actor_SetScale(&this->actor, 0.01f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_kbt_Skel_00DEE8, &object_kbt_Anim_004274, this->jointTable, + this->morphTable, OBJECT_KBT_LIMB_MAX); + this->unk_27C = 0; + this->actor.home.rot.z = 0; + this->unk_27E = 4; + this->unk_27F = 0; + this->unk_280 = 13; + this->unk_282 = 13; + this->unk_278 = func_80B3403C(globalCtx); + this->unk_284 = 0; + this->actor.textId = 0; + if (func_80B33E64(globalCtx)) { + func_80B33EF0(this, 6); + this->unk_282 = 11; + if (func_80B33E8C(globalCtx)) { + this->actor.textId = 0xC50; + } else { + this->actor.textId = 0xC4E; + this->unk_27C |= 1; + } + this->actionFunc = func_80B34314; + } else { + func_80B33EF0(this, 0); + this->unk_282 = 0; + this->actionFunc = func_80B34598; + } + this->actor.flags &= ~ACTOR_FLAG_1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/EnKbt_Init.s") +void EnKbt_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/EnKbt_Destroy.s") +s32 func_80B33E64(GlobalContext* globalCtx) { + return gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B33E64.s") +s32 func_80B33E8C(GlobalContext* globalCtx) { + if ((CURRENT_DAY == 3) || + ((CURRENT_DAY == 2) && (gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 2))) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B33E8C.s") +void func_80B33EF0(EnKbt* this, s16 arg1) { + static AnimationHeader* sAnimations[] = { + &object_kbt_Anim_000670, &object_kbt_Anim_001674, &object_kbt_Anim_002084, &object_kbt_Anim_000FE8, + &object_kbt_Anim_001940, &object_kbt_Anim_00E7BC, &object_kbt_Anim_00F0C8, &object_kbt_Anim_002710, + &object_kbt_Anim_002DE0, &object_kbt_Anim_003414, &object_kbt_Anim_003D24, &object_kbt_Anim_001BF4, + &object_kbt_Anim_002084, + }; + u8 sp38[] = { + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_LOOP, + ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_ONCE, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B33EF0.s") + if (arg1 != this->unk_280) { + if (arg1 >= 12) { + Animation_Change(&this->skelAnime, sAnimations[arg1], -1.0f, + Animation_GetLastFrame(sAnimations[arg1]) - 1.0f, 0.0f, sp38[arg1], -5.0f); + } else { + Animation_Change(&this->skelAnime, sAnimations[arg1], 1.0f, 0.0f, Animation_GetLastFrame(sAnimations[arg1]), + sp38[arg1], -5.0f); + } + this->unk_280 = arg1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B3403C.s") +Actor* func_80B3403C(GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B34078.s") + while (npc != NULL) { + if (npc->id == ACTOR_EN_KGY) { + return npc; + } + npc = npc->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B3415C.s") + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B34314.s") +void func_80B34078(EnKbt* this) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_284 > 0) { + this->unk_284--; + } else { + switch (this->unk_280) { + case 2: + switch (this->unk_282) { + case 0: + func_80B33EF0(this, 12); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B34574.s") + case 5: + this->actor.home.rot.z = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B34598.s") + default: + func_80B33EF0(this, 5); + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/EnKbt_Update.s") + case 12: + func_80B33EF0(this, 0); + this->actor.home.rot.z = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B349C8.s") + case 4: + func_80B33EF0(this, 1); + this->unk_27E = 2; + this->actor.home.rot.z = 0; + break; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/func_80B34A00.s") +void func_80B3415C(EnKbt* this) { + if (this->unk_27C & 2) { + if (this->unk_284 > 0) { + this->unk_284--; + } else { + this->unk_27F = 0; + this->unk_282 = 3; + this->unk_27C &= ~2; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kbt/EnKbt_Draw.s") + switch (this->unk_282) { + case 0: + if ((this->unk_280 != 2) && (this->unk_280 != 12)) { + func_80B33EF0(this, 0); + } + break; + + case 1: + func_80B33EF0(this, 2); + this->unk_282 = 0; + break; + + case 2: + if (this->unk_280 != 12) { + func_80B33EF0(this, 3); + } + break; + + case 3: + if (this->unk_280 != 1) { + func_80B33EF0(this, 4); + } + break; + + case 10: + func_80B33EF0(this, 11); + break; + + case 4: + func_80B33EF0(this, 2); + this->unk_282 = 6; + break; + + case 6: + if (this->unk_280 != 2) { + func_80B33EF0(this, 5); + } + break; + + case 11: + func_80B33EF0(this, 6); + break; + + case 7: + if (this->unk_280 != 2) { + func_80B33EF0(this, 7); + } + break; + + case 8: + if (this->unk_280 != 2) { + func_80B33EF0(this, 8); + } + break; + + case 9: + if (this->unk_280 != 2) { + func_80B33EF0(this, 9); + } + break; + + case 12: + func_80B33EF0(this, 10); + break; + } +} + +void func_80B34314(EnKbt* this, GlobalContext* globalCtx) { + s32 playerForm; + + func_80B34078(this); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80B34598; + Actor_ChangeFocus(&this->actor, globalCtx, this->unk_278); + this->unk_278->textId = this->actor.textId; + this->unk_27C &= ~4; + if (this->actor.textId == 0xC4E) { + this->unk_27C |= 0x10; + } + } else if (this->actor.xzDistToPlayer < 250.0f) { + if ((this->unk_278 != NULL) && (this->unk_278->xzDistToPlayer < 250.0f)) { + if (this->unk_27C & 4) { + playerForm = gSaveContext.save.playerForm; + if (((playerForm ^ 0) != PLAYER_FORM_HUMAN) || ((CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_KOKIRI) && + (CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_RAZOR) && + (CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_GILDED))) { + this->actor.textId = 0xC38; + } else if (CURRENT_DAY == 3) { + this->actor.textId = 0xC39; + } else if (this->unk_27C & 8) { + this->actor.textId = 0xC3E; + } else { + this->actor.textId = 0xC3A; + } + } + + if (this->actor.textId != 0xC37) { + if (((this->actor.textId == 0xC4E) || (this->actor.textId == 0xC4F) || (this->actor.textId == 0xC50)) && + (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN)) { + this->actor.textId = 0xC37; + } + } else if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + if (func_80B33E8C(globalCtx)) { + this->actor.textId = 0xC50; + } else { + this->actor.textId = 0xC4E; + } + } + func_800B8614(&this->actor, globalCtx, 260.0f); + } + } + func_80B3415C(this); +} + +void func_80B34574(EnKbt* this) { + this->unk_27E = 0; + this->unk_27F = 0; + this->unk_282 = 6; + this->actionFunc = func_80B34314; +} + +void func_80B34598(EnKbt* this, GlobalContext* globalCtx) { + func_80B34078(this); + + switch (this->actor.textId) { + case 0x1: + this->unk_27E = 4; + this->unk_27F = 0; + this->unk_282 = 0; + break; + + case 0x2: + func_80B34574(this); + this->actor.textId = 0xC3E; + this->unk_27C |= 0x4; + this->unk_27C |= 0x8; + return; + + case 0x3: + func_80B34574(this); + this->actor.textId = 0xC58; + return; + + case 0x4: + func_80B34574(this); + this->actor.textId = 0xC4B; + return; + + case 0x5: + this->unk_27E = 4; + this->unk_27F = 0; + this->unk_282 = 0; + func_80B33EF0(this, 12); + break; + + case 0x6: + func_80B34574(this); + this->actor.textId = 0xC3A; + this->unk_27C |= 4; + return; + + case 0x7: + this->unk_27E = 4; + this->unk_27F = 0; + this->unk_282 = 11; + if (func_80B33E8C(globalCtx)) { + this->actor.textId = 0xC50; + } else if (this->unk_27C & 0x10) { + this->actor.textId = 0xC4F; + } else { + this->actor.textId = 0xC4E; + } + this->actionFunc = func_80B34314; + return; + + case 0x8: + func_80B34574(this); + this->actor.textId = 0xC56; + return; + + case 0xC1E: + this->unk_27E = 2; + this->unk_27F = 1; + break; + + case 0xC1F: + case 0xC2E: + this->unk_27E = 2; + this->unk_27F = 1; + this->unk_282 = 1; + this->unk_284 = 20; + break; + + case 0xC20: + case 0xC23: + case 0xC2F: + this->unk_27E = 0; + this->unk_282 = 2; + break; + + case 0xC21: + case 0xC29: + this->unk_284 = 10; + this->unk_27C |= 2; + break; + + case 0xC22: + case 0xC2A: + this->unk_27F = 1; + break; + + case 0xC2C: + this->unk_27E = 0; + this->unk_27F = 0; + this->unk_282 = 2; + break; + + case 0xC31: + this->unk_27E = 2; + this->unk_27F = 1; + this->unk_282 = 4; + break; + + case 0xC32: + this->unk_27E = 1; + this->unk_282 = 7; + break; + + case 0xC34: + this->unk_27E = 0; + this->unk_282 = 8; + break; + + case 0xC35: + this->unk_27E = 4; + this->unk_27F = 0; + func_80B33EF0(this, 2); + this->unk_282 = 5; + break; + + case 0xC36: + this->unk_27E = 1; + this->unk_27F = 1; + func_80B33EF0(this, 7); + this->unk_282 = 7; + break; + + case 0xC37: + func_80B33EF0(this, 10); + this->unk_27E = 0; + this->unk_27F = 1; + break; + + case 0xC38: + case 0xC39: + func_80B33EF0(this, 7); + this->unk_27E = 0; + this->unk_27F = 1; + break; + + case 0xC3A: + case 0xC4D: + case 0xC58: + this->unk_27E = 0; + this->unk_27F = 1; + this->unk_282 = 8; + break; + + case 0xC3C: + case 0xC57: + this->unk_27E = 1; + this->unk_282 = 7; + break; + + case 0xC3D: + this->unk_27E = 0; + break; + + case 0xC3E: + this->unk_27F = 1; + this->unk_282 = 8; + break; + + case 0xC3F: + case 0xC47: + case 0xC4C: + this->unk_27E = 1; + this->unk_27F = 1; + this->unk_282 = 7; + break; + + case 0xC40: + this->unk_27E = 3; + this->unk_282 = 6; + break; + + case 0xC45: + case 0xC4B: + case 0xC56: + this->unk_27E = 0; + this->unk_27F = 1; + this->unk_282 = 7; + break; + + case 0xC46: + this->unk_27E = 1; + this->unk_27F = 1; + this->unk_282 = 9; + break; + + case 0xC48: + this->unk_27E = 2; + this->unk_27F = 0; + this->unk_282 = 10; + break; + + case 0xC49: + this->unk_27F = 1; + break; + + case 0xC4A: + this->unk_27E = 0; + this->unk_282 = 7; + break; + + case 0xC4E: + this->unk_27E = 1; + this->unk_27F = 1; + this->unk_282 = 12; + break; + + case 0xC4F: + this->unk_27E = 2; + this->unk_27F = 1; + this->unk_282 = 12; + break; + + case 0xC50: + this->unk_27E = 0; + this->unk_27F = 1; + this->unk_282 = 12; + break; + } + + this->actor.textId = 0; + func_80B3415C(this); +} + +void EnKbt_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKbt* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 EnKbt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnKbt* this = THIS; + + if (!(this->unk_27C & 1) && (limbIndex == OBJECT_KBT_LIMB_0E)) { + *dList = NULL; + } + return false; +} + +Vec3f D_80B34B84 = { 500.0f, 500.0f, 0.0f }; + +void EnKbt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnKbt* this = THIS; + + if (limbIndex == OBJECT_KBT_LIMB_09) { + Matrix_MultVec3f(&D_80B34B84, &this->actor.focus.pos); + } +} + +TexturePtr D_80B34B90[] = { + object_kbt_Tex_00A5B8, + object_kbt_Tex_00ADB8, +}; + +TexturePtr D_80B34B98[] = { + object_kbt_Tex_00B5B8, object_kbt_Tex_00BDB8, object_kbt_Tex_00C5B8, object_kbt_Tex_00CDB8, object_kbt_Tex_00D5B8, +}; + +void EnKbt_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKbt* this = THIS; + Gfx* gfx; + TexturePtr tex; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + tex = Lib_SegmentedToVirtual(D_80B34B98[this->unk_27E]); + gSPSegment(&gfx[0], 0x08, tex); + + tex = Lib_SegmentedToVirtual(D_80B34B90[this->unk_27F]); + gSPSegment(&gfx[1], 0x09, tex); + + POLY_OPA_DISP = &gfx[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnKbt_OverrideLimbDraw, EnKbt_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Kbt/z_en_kbt.h b/src/overlays/actors/ovl_En_Kbt/z_en_kbt.h index 9d68dce1d..7556e3f5c 100644 --- a/src/overlays/actors/ovl_En_Kbt/z_en_kbt.h +++ b/src/overlays/actors/ovl_En_Kbt/z_en_kbt.h @@ -2,6 +2,7 @@ #define Z_EN_KBT_H #include "global.h" +#include "objects/object_kbt/object_kbt.h" struct EnKbt; @@ -9,7 +10,16 @@ typedef void (*EnKbtActionFunc)(struct EnKbt*, GlobalContext*); typedef struct EnKbt { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x144]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[OBJECT_KBT_LIMB_MAX]; + /* 0x0200 */ Vec3s morphTable[OBJECT_KBT_LIMB_MAX]; + /* 0x0278 */ Actor* unk_278; + /* 0x027C */ u16 unk_27C; + /* 0x027E */ u8 unk_27E; + /* 0x027F */ u8 unk_27F; + /* 0x0280 */ s16 unk_280; + /* 0x0282 */ s16 unk_282; + /* 0x0284 */ s16 unk_284; /* 0x0288 */ EnKbtActionFunc actionFunc; } EnKbt; // size = 0x28C diff --git a/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.c b/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.c index 142dfece7..92053374a 100644 --- a/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.c +++ b/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.c @@ -1,6 +1,14 @@ -#include "z_en_kendo_js.h" +/* + * File: z_en_kendo_js.c + * Overlay: ovl_En_Kendo_Js + * Description: Swordsman + */ -#define FLAGS 0x0A000019 +#include "z_en_kendo_js.h" +#include "overlays/actors/ovl_En_Maruta/z_en_maruta.h" +#include "objects/object_js/object_js.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000 | ACTOR_FLAG_8000000) #define THIS ((EnKendoJs*)thisx) @@ -9,7 +17,26 @@ void EnKendoJs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKendoJs_Update(Actor* thisx, GlobalContext* globalCtx); void EnKendoJs_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B26538(EnKendoJs* this); +void func_80B2654C(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B26AE8(EnKendoJs* this); +void func_80B26AFC(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B2701C(EnKendoJs* this); +void func_80B27030(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B2714C(EnKendoJs* this); +void func_80B27188(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B273D0(EnKendoJs* this); +void func_80B2740C(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B274BC(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B276C4(EnKendoJs* this); +void func_80B276D8(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B27760(EnKendoJs* this); +void func_80B27774(EnKendoJs* this, GlobalContext* globalCtx); +void func_80B2783C(EnKendoJs* this, GlobalContext* globalCtx); +s32 func_80B278C4(GlobalContext* globalCtx, Vec3f arg1); +void func_80B279F0(EnKendoJs* this, GlobalContext* globalCtx, s32 arg2); +void func_80B27A90(EnKendoJs* this, GlobalContext* globalCtx); + const ActorInit En_Kendo_Js_InitVars = { ACTOR_EN_KENDO_JS, ACTORCAT_NPC, @@ -22,86 +49,720 @@ const ActorInit En_Kendo_Js_InitVars = { (ActorFunc)EnKendoJs_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B27C30 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, 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_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 18, 30, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B27C5C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfo sAnimations[] = { + { &object_js_Anim_000C7C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &object_js_Anim_000F4C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &object_js_Anim_00016C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &object_js_Anim_0003DC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, + { &object_js_Anim_000AD4, 1.0f, 0.0f, 0.0f, 0, -8.0f }, +}; -extern ColliderCylinderInit D_80B27C30; -extern CollisionCheckInfoInit2 D_80B27C5C; +s16 D_80B27CE0[][3] = { + { 0x2731, 0x2732, 0x2733 }, + { 0x2734, 0x2735, 0x2736 }, + { 0x2737, 0x2738, 0x2739 }, +}; -extern UNK_TYPE D_0600016C; -extern UNK_TYPE D_06000F4C; +s16 D_80B27CF4[][3] = { + { 0x2710, 0x2712, 0x2714 }, + { 0x2711, 0x2713, 0x2715 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/EnKendoJs_Init.s") +s16 D_80B27D00[] = { + 0x271C, 0x271E, 0x2720, 0x2722, 0x2724, 0x2726, 0x2728, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/EnKendoJs_Destroy.s") +s16 D_80B27D10[] = { + 0x271B, 0x271D, 0x271F, 0x2721, 0x2723, 0x2725, 0x2727, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26538.s") +void EnKendoJs_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnKendoJs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B2654C.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26758.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B269A4.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_js_Skel_006990, &object_js_Anim_000F4C, this->jointTable, + this->morphTable, 13); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26AE8.s") + if ((CURRENT_DAY == 3) && + !((gSaveContext.save.time <= CLOCK_TIME(23, 0)) && (gSaveContext.save.time >= CLOCK_TIME(6, 0)))) { + if (ENKENDOJS_GET_FF(&this->actor) != ENKENDOJS_FF_1) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_KANBAN, this->actor.home.pos.x, + this->actor.home.pos.y, this->actor.home.pos.z - 10.0f, this->actor.home.rot.x, + this->actor.home.rot.y, this->actor.home.rot.z, 0x10); + Actor_MarkForDeath(&this->actor); + } else { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + } + } else if (ENKENDOJS_GET_FF(&this->actor) == ENKENDOJS_FF_1) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26AFC.s") + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26BF8.s") + if (ENKENDOJS_GET_FF(&this->actor) != ENKENDOJS_FF_1) { + Path* path = &globalCtx->setupPathList[ENKENDOJS_GET_FF00(&this->actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26EB4.s") + this->unk_274 = Lib_SegmentedToVirtual(path->points); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26F14.s") + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 30.0f; + this->actor.child = NULL; + this->unk_28A = 0; + this->unk_28C = 0; + this->unk_28E = 0; + this->unk_286 = 0; + func_80B26538(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B26F6C.s") +void EnKendoJs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKendoJs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B2701C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + gSaveContext.save.weekEventReg[82] &= (u8)~8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27030.s") +void func_80B26538(EnKendoJs* this) { + this->actionFunc = func_80B2654C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B2714C.s") +void func_80B2654C(EnKendoJs* this, GlobalContext* globalCtx) { + s32 phi_v0; + s32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27188.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { + if (CURRENT_DAY != 0) { + sp30 = CURRENT_DAY - 1; + } else { + sp30 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B273D0.s") + if (ENKENDOJS_GET_FF(&this->actor) == ENKENDOJS_FF_1) { + Message_StartTextbox(globalCtx, 0x273C, &this->actor); + this->unk_288 = 0x273C; + } else if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + switch (gSaveContext.save.playerForm) { + case PLAYER_FORM_DEKU: + phi_v0 = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B2740C.s") + case PLAYER_FORM_GORON: + phi_v0 = 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B274BC.s") + case PLAYER_FORM_ZORA: + phi_v0 = 2; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B276C4.s") + default: + phi_v0 = 0; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B276D8.s") + Message_StartTextbox(globalCtx, D_80B27CE0[phi_v0][sp30], &this->actor); + this->unk_288 = D_80B27CE0[phi_v0][sp30]; + } else if ((Player_GetMask(globalCtx) != PLAYER_MASK_NONE) && (Player_GetMask(globalCtx) < PLAYER_MASK_GIANT)) { + u16 sp2E = Player_GetMask(globalCtx) + 0x273C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27760.s") + if (0) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27774.s") + Message_StartTextbox(globalCtx, sp2E, &this->actor); + this->unk_288 = sp2E; + } else { + if (this->unk_28A == 0) { + this->unk_28A = 1; + phi_v0 = 0; + } else { + phi_v0 = 1; + } + Message_StartTextbox(globalCtx, D_80B27CF4[phi_v0][sp30], &this->actor); + this->unk_288 = D_80B27CF4[phi_v0][sp30]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B2783C.s") + func_80B26AE8(this); + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27880.s") +void func_80B26758(EnKendoJs* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx) && (this->unk_288 == 0x2716)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (GET_CUR_EQUIP_VALUE(EQUIP_SWORD) == EQUIP_SWORD) { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x272C, &this->actor); + this->unk_288 = 0x272C; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + } else if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x2718, &this->actor); + this->unk_288 = 0x2718; + } else { + func_8019F208(); + func_801159EC(-globalCtx->msgCtx.unk1206C); + Message_StartTextbox(globalCtx, 0x2719, &this->actor); + this->unk_288 = 0x2719; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B278C4.s") + case 1: + if (GET_CUR_EQUIP_VALUE(EQUIP_SWORD) == EQUIP_SWORD) { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x272C, &this->actor); + this->unk_288 = 0x272C; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + } else if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk12070) { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x2718, &this->actor); + this->unk_288 = 0x2718; + } else { + func_8019F208(); + func_801159EC(-globalCtx->msgCtx.unk12070); + Message_StartTextbox(globalCtx, 0x273A, &this->actor); + this->unk_288 = 0x273A; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B279AC.s") + case 2: + func_8019F230(); + Message_StartTextbox(globalCtx, 0x2717, &this->actor); + this->unk_288 = 0x2717; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B279F0.s") +void func_80B269A4(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27A90.s") + if (!Message_ShouldAdvance(globalCtx)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/EnKendoJs_Update.s") + switch (this->unk_288) { + case 0x2710: + case 0x2711: + case 0x2712: + case 0x2713: + case 0x2714: + case 0x2715: + Message_StartTextbox(globalCtx, 0x2716, &this->actor); + this->unk_288 = 0x2716; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27B54.s") + case 0x2719: + func_801477B4(globalCtx); + player->stateFlags1 |= 0x20; + func_80B2701C(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/func_80B27B8C.s") + case 0x271A: + func_801477B4(globalCtx); + func_80B2714C(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kendo_Js/EnKendoJs_Draw.s") + case 0x273A: + Message_StartTextbox(globalCtx, 0x273B, &this->actor); + this->unk_288 = 0x273B; + break; + + case 0x273B: + func_801477B4(globalCtx); + func_80112AFC(globalCtx); + player->stateFlags1 |= 0x20; + func_80B273D0(this); + break; + + case 0x272D: + func_801477B4(globalCtx); + gSaveContext.minigameState = 3; + func_80B276C4(this); + func_80B276D8(this, globalCtx); + break; + } +} + +void func_80B26AE8(EnKendoJs* this) { + this->actionFunc = func_80B26AFC; +} + +void func_80B26AFC(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 4: + func_80B26758(this, globalCtx); + break; + + case 5: + func_80B269A4(this, globalCtx); + break; + + case 6: + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_288 == 0x272C) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + } + + if ((this->unk_288 == 0x272E) || (this->unk_288 == 0x272F) || (this->unk_288 == 0x2730)) { + gSaveContext.minigameState = 3; + } + + player->stateFlags1 &= ~0x20; + func_80B26538(this); + } + + case 0: + case 1: + case 2: + case 3: + break; + } +} + +s32 func_80B26BF8(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_284) { + case 0: + if (func_80122FCC(globalCtx)) { + return 0; + } + + if ((player->swordState != 0) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + return 1; + } + break; + + case 1: + if ((player->stateFlags3 & 0x8000000)) { + return 0; + } + + if ((player->swordState != 0) || (player->stateFlags2 & 0x80000)) { + return 1; + } + break; + + case 2: + if (func_80122F9C(globalCtx)) { + return 0; + } + + if ((player->swordState != 0) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + return 1; + } + this->unk_28E = 0; + break; + + case 3: + if ((this->unk_28E == 1) && ((player->swordAnimation == 4) || (player->swordAnimation == 6))) { + this->unk_28E = 0; + return 0; + } + + if ((this->unk_28E == 1) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + this->unk_28E = 0; + return 1; + } + break; + + case 4: + if ((this->unk_28E == 1) && ((player->swordAnimation == 0) || (player->swordAnimation == 2))) { + this->unk_28E = 0; + return 0; + } + + if ((this->unk_28E == 1) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + this->unk_28E = 0; + return 1; + } + break; + + case 5: + if ((this->unk_28E == 1) && (player->swordAnimation == 12)) { + this->unk_28E = 0; + return 0; + } + + if ((this->unk_28E == 1) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + this->unk_28E = 0; + return 1; + } + break; + + case 6: + if ((this->unk_28E == 1) && ((player->swordAnimation == 17) || (player->swordAnimation == 20))) { + this->unk_28E = 0; + return 0; + } + + if ((this->unk_28E == 1) || (player->stateFlags3 & 0x8000000) || (player->stateFlags2 & 0x80000)) { + this->unk_28E = 0; + return 1; + } + break; + } + return 2; +} + +void func_80B26EB4(EnKendoJs* this, GlobalContext* globalCtx) { + Message_StartTextbox(globalCtx, D_80B27D00[this->unk_284], &this->actor); + this->unk_288 = D_80B27D00[this->unk_284]; + this->unk_284++; +} + +void func_80B26F14(EnKendoJs* this, GlobalContext* globalCtx) { + Message_StartTextbox(globalCtx, D_80B27D10[this->unk_284], &this->actor); + this->unk_288 = D_80B27D10[this->unk_284]; +} + +s32 func_80B26F6C(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_288) { + case 0x271D: + if (func_80124190(player)) { + Message_StartTextbox(globalCtx, 0x272A, &this->actor); + this->unk_288 = 0x272A; + return true; + } + break; + + case 0x2721: + if (this->unk_292 != 0) { + Message_StartTextbox(globalCtx, 0x272B, &this->actor); + this->unk_288 = 0x272B; + return true; + } + break; + } + return false; +} + +void func_80B2701C(EnKendoJs* this) { + this->actionFunc = func_80B27030; +} + +void func_80B27030(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp20 = this->actor.world.pos; + + sp20.z += 200.0f; + + if (func_80B278C4(globalCtx, sp20)) { + this->actor.flags |= ACTOR_FLAG_10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + player->stateFlags1 &= ~0x20; + func_80B279F0(this, globalCtx, 0); + Message_StartTextbox(globalCtx, 0x271A, &this->actor); + this->unk_288 = 0x271A; + func_80B26AE8(this); + } else { + func_800B8614(&this->actor, globalCtx, 800.0f); + } + } +} + +void func_80B2714C(EnKendoJs* this) { + gSaveContext.save.weekEventReg[82] |= 8; + this->unk_28C = 1; + this->unk_290 = 0; + this->unk_284 = 0; + this->unk_286 = 1; + this->actionFunc = func_80B27188; +} + +void func_80B27188(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_288 == 0x2729) { + func_80B26F14(this, globalCtx); + } else if (!func_80B26F6C(this, globalCtx)) { + if (this->skelAnime.animation == &object_js_Anim_00016C) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + } + this->unk_286 = 2; + func_801477B4(globalCtx); + player->stateFlags1 &= ~0x20; + } + } else if (this->unk_286 == 2) { + this->unk_286 = 1; + } + + if (this->unk_286 == 1) { + switch (func_80B26BF8(this, globalCtx)) { + case 0: + this->unk_286 = 0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + player->stateFlags1 |= 0x20; + func_80B26EB4(this, globalCtx); + break; + + case 1: + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); + this->unk_286 = 0; + player->stateFlags1 |= 0x20; + Message_StartTextbox(globalCtx, 0x2729, &this->actor); + this->unk_288 = 0x2729; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + break; + + default: + if (this->unk_28C == 0) { + this->unk_290++; + if (this->unk_290 == 30) { + this->unk_290 = 0; + func_80B279F0(this, globalCtx, 0); + } + } + break; + } + + if ((this->skelAnime.animation == &object_js_Anim_0003DC) && + Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + } + + if (this->unk_284 == 7) { + gSaveContext.save.weekEventReg[82] &= (u8)~8; + func_80B26AE8(this); + } + } +} + +void func_80B273D0(EnKendoJs* this) { + gSaveContext.save.weekEventReg[82] |= 8; + this->unk_290 = 120; + this->unk_284 = 0; + this->unk_286 = 1; + this->actionFunc = func_80B2740C; +} + +void func_80B2740C(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp18 = this->actor.world.pos; + + sp18.z += 300.0f; + + if (func_80B278C4(globalCtx, sp18)) { + this->unk_28C = 0; + player->stateFlags1 &= ~0x20; + this->actionFunc = func_80B274BC; + } +} + +void func_80B274BC(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_290 >= 140) { + if (this->unk_284 == 5) { + if (gSaveContext.minigameScore == 30) { + Message_StartTextbox(globalCtx, 0x272D, &this->actor); + this->unk_288 = 0x272D; + } else { + Message_StartTextbox(globalCtx, 0x272E, &this->actor); + this->unk_288 = 0x272E; + } + player->stateFlags1 |= 0x20; + gSaveContext.save.weekEventReg[82] &= (u8)~8; + func_80B26AE8(this); + return; + } + + play_sound(NA_SE_SY_FOUND); + func_80B279F0(this, globalCtx, ((Rand_Next() & 0xFF) % 3) + 1); + func_80B279F0(this, globalCtx, ((Rand_Next() & 0xFF) % 3) + 4); + this->unk_290 = 0; + this->unk_284++; + } else if (this->unk_290 == 120) { + func_80B27A90(this, globalCtx); + this->unk_290++; + } else { + this->unk_290++; + } + + if (this->unk_28E == 1) { + if ((player->swordAnimation == 17) || (player->swordAnimation == 20)) { + globalCtx->interfaceCtx.unk_25C = 3; + if (gSaveContext.minigameScore >= 27) { + player->stateFlags1 |= 0x20; + } + } else if (player->swordAnimation == 12) { + globalCtx->interfaceCtx.unk_25C = 2; + } else { + globalCtx->interfaceCtx.unk_25C = 1; + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + this->unk_28E = 0; + } + func_80B2783C(this, globalCtx); +} + +void func_80B276C4(EnKendoJs* this) { + this->actionFunc = func_80B276D8; +} + +void func_80B276D8(EnKendoJs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_80B27760(this); + } else if (!(gSaveContext.save.weekEventReg[63] & 0x20)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 800.0f, 100.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 800.0f, 100.0f); + } +} + +void func_80B27760(EnKendoJs* this) { + this->actionFunc = func_80B27774; +} + +void func_80B27774(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (!(gSaveContext.save.weekEventReg[63] & 0x20)) { + gSaveContext.save.weekEventReg[63] |= 0x20; + Message_StartTextbox(globalCtx, 0x272F, &this->actor); + this->unk_288 = 0x272F; + } else { + Message_StartTextbox(globalCtx, 0x2730, &this->actor); + this->unk_288 = 0x2730; + } + func_80B26AE8(this); + player->stateFlags1 &= ~0x20; + } else { + func_800B85E0(&this->actor, globalCtx, 1000.0f, -1); + } +} + +void func_80B2783C(EnKendoJs* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + Camera_ChangeDataIdx(globalCtx->cameraPtrs[CAM_ID_MAIN], + ActorCutscene_GetCutscene(this->actor.cutscene)->csCamSceneDataId); + } +} + +void func_80B27880(EnKendoJs* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 temp_f0 = this->actor.world.pos.z + 70.0f; + + if ((ENKENDOJS_GET_FF(&this->actor) != ENKENDOJS_FF_1) && (player->actor.world.pos.z < temp_f0)) { + player->actor.world.pos.z = temp_f0; + } +} + +s32 func_80B278C4(GlobalContext* globalCtx, Vec3f arg1) { + Player* player = GET_PLAYER(globalCtx); + f32 temp_f0; + f32 sp28; + s16 sp22 = Math_Vec3f_Yaw(&player->actor.world.pos, &arg1); + + temp_f0 = Math_Vec3f_DistXZ(&player->actor.world.pos, &arg1); + + if (temp_f0 < 20.0f) { + sp28 = 10.0f; + } else if (temp_f0 < 40.0f) { + sp28 = 40.0f; + } else { + sp28 = 80.0f; + } + + globalCtx->actorCtx.unk268 = 1; + func_800B6F20(globalCtx, &globalCtx->actorCtx.unk_26C, sp28, sp22); + + if (temp_f0 < 20.0f) { + return true; + } else { + return false; + } +} + +void func_80B279AC(EnKendoJs* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80B279F0(EnKendoJs* this, GlobalContext* globalCtx, s32 arg2) { + f32 x = this->unk_274[arg2].x; + f32 y = this->unk_274[arg2].y; + f32 z = this->unk_274[arg2].z; + + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_MARUTA, x, y, z, 0, 0, 0, 0); + this->unk_28C++; +} + +void func_80B27A90(EnKendoJs* this, GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; + + while (actor != NULL) { + if (actor->id == ACTOR_EN_MARUTA) { + ((EnMaruta*)actor)->unk_220 = 1; + } + actor = actor->next; + } + + this->unk_28C = 0; +} + +void EnKendoJs_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKendoJs* this = THIS; + + this->actionFunc(this, globalCtx); + + SkelAnime_Update(&this->skelAnime); + func_800E9250(globalCtx, &this->actor, &this->unk_278, &this->unk_27E, this->actor.focus.pos); + func_80B279AC(this, globalCtx); + func_80B27880(this, globalCtx); +} + +s32 EnKendoJs_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnKendoJs* this = THIS; + + if (limbIndex == 12) { + rot->y -= this->unk_278.y; + } + return false; +} + +void EnKendoJs_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +} + +void EnKendoJs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKendoJs* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnKendoJs_OverrideLimbDraw, EnKendoJs_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.h b/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.h index 33da3ea09..2820aac21 100644 --- a/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.h +++ b/src/overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.h @@ -7,11 +7,29 @@ struct EnKendoJs; typedef void (*EnKendoJsActionFunc)(struct EnKendoJs*, GlobalContext*); +#define ENKENDOJS_GET_FF(thisx) ((thisx)->params & 0xFF) +#define ENKENDOJS_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + +#define ENKENDOJS_FF_1 1 + typedef struct EnKendoJs { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnKendoJsActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0xBC]; + /* 0x01D8 */ Vec3s jointTable[13]; + /* 0x0226 */ Vec3s morphTable[13]; + /* 0x0274 */ Vec3s* unk_274; + /* 0x0278 */ Vec3s unk_278; + /* 0x027E */ Vec3s unk_27E; + /* 0x0284 */ s16 unk_284; + /* 0x0286 */ s16 unk_286; + /* 0x0288 */ s16 unk_288; + /* 0x028A */ s16 unk_28A; + /* 0x028C */ s16 unk_28C; + /* 0x028E */ s16 unk_28E; + /* 0x0290 */ s16 unk_290; + /* 0x0292 */ u8 unk_292; } EnKendoJs; // size = 0x294 extern const ActorInit En_Kendo_Js_InitVars; 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 26bf172bc..cc184cfed 100644 --- a/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c +++ b/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c @@ -7,8 +7,10 @@ #include "overlays/actors/ovl_En_Kbt/z_en_kbt.h" #include "overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h" #include "z_en_kgy.h" +#include "objects/object_kgy/object_kgy.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnKgy*)thisx) @@ -31,24 +33,6 @@ void func_80B425A0(EnKgy* this, GlobalContext* globalCtx); void func_80B42714(EnKgy* this, GlobalContext* globalCtx); void func_80B42D28(EnKgy* this, GlobalContext* globalCtx); -extern AnimationHeader D_060008FC; -extern AnimationHeader D_06001764; -extern Gfx D_04001D00[]; -extern AnimationHeader D_06001EA4; -extern Gfx D_040021A8[]; -extern AnimationHeader D_0600292C; -extern AnimationHeader D_06003334; -extern AnimationHeader D_06003D88; -extern AnimationHeader D_060042E4; -extern AnimationHeader D_06004B98; -extern Gfx D_0600E8F0[]; -extern Gfx D_0600EE58[]; -extern Gfx D_0600F180[]; -extern Gfx D_0600F6A0[]; -extern FlexSkeletonHeader D_0600F910; -extern AnimationHeader D_06010B84; -extern AnimationHeader D_060101F0; - const ActorInit En_Kgy_InitVars = { ACTOR_EN_KGY, ACTORCAT_NPC, @@ -67,18 +51,19 @@ void EnKgy_Init(Actor* thisx, GlobalContext* globalCtx) { s32 i; Actor_SetScale(&this->actor, 0.01f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600F910, &D_06004B98, this->jointTable, this->morphTable, 23); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_kgy_Skel_00F910, &object_kgy_Anim_004B98, this->jointTable, + this->morphTable, 23); this->unk_2D2 = -1; this->unk_29C = 0; this->unk_2E4 = 0; this->unk_2E2 = -1; this->zubora = EnKgy_FindZubora(globalCtx); this->iceBlock = EnKgy_FindIceBlock(globalCtx); - Actor_UnsetSwitchFlag(globalCtx, ENKGY_GET_FE00(&this->actor) + 1); - if (Flags_GetSwitch(globalCtx, ENKGY_GET_FE00(&this->actor)) || (gSaveContext.weekEventReg[33] & 0x80)) { - Actor_SetSwitchFlag(globalCtx, ENKGY_GET_FE00(&this->actor) + 1); - globalCtx->envCtx.unk_C3 = 1; - gSaveContext.weekEventReg[21] |= 1; + Flags_UnsetSwitch(globalCtx, ENKGY_GET_FE00(&this->actor) + 1); + if (Flags_GetSwitch(globalCtx, ENKGY_GET_FE00(&this->actor)) || (gSaveContext.save.weekEventReg[33] & 0x80)) { + Flags_SetSwitch(globalCtx, ENKGY_GET_FE00(&this->actor) + 1); + globalCtx->envCtx.lightSettingOverride = 1; + gSaveContext.save.weekEventReg[21] |= 1; if (!func_80B40D64(globalCtx)) { EnKgy_ChangeAnim(this, 4, 0, 0); this->actionFunc = func_80B425A0; @@ -95,7 +80,7 @@ void EnKgy_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.textId = 0xC50; } } else { - if (gSaveContext.weekEventReg[20] & 0x80) { + if (gSaveContext.save.weekEventReg[20] & 0x80) { EnKgy_ChangeAnim(this, 4, 0, 0); } else { EnKgy_ChangeAnim(this, 0, 0, 0); @@ -116,7 +101,7 @@ void EnKgy_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.world.pos.z, 255, 64, 64, -1); this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); this->unk_300 = -1; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; } void EnKgy_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -127,8 +112,9 @@ void EnKgy_Destroy(Actor* thisx, GlobalContext* globalCtx) { void EnKgy_ChangeAnim(EnKgy* this, s16 animIndex, u8 mode, f32 transitionRate) { static AnimationHeader* sAnimations[] = { - &D_06004B98, &D_060008FC, &D_0600292C, &D_060042E4, &D_060101F0, - &D_06001764, &D_06003334, &D_06010B84, &D_06001EA4, &D_06003D88, + &object_kgy_Anim_004B98, &object_kgy_Anim_0008FC, &object_kgy_Anim_00292C, &object_kgy_Anim_0042E4, + &object_kgy_Anim_0101F0, &object_kgy_Anim_001764, &object_kgy_Anim_003334, &object_kgy_Anim_010B84, + &object_kgy_Anim_001EA4, &object_kgy_Anim_003D88, }; Animation_Change(&this->skelAnime, sAnimations[animIndex], 1.0f, 0.0f, @@ -143,7 +129,7 @@ void func_80B40BC0(EnKgy* this, s16 arg1) { } EnKbt* EnKgy_FindZubora(GlobalContext* globalCtx) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (actor != NULL) { if (actor->id == ACTOR_EN_KBT) { @@ -155,7 +141,7 @@ EnKbt* EnKgy_FindZubora(GlobalContext* globalCtx) { } ObjIcePoly* EnKgy_FindIceBlock(GlobalContext* globalCtx) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; while (actor != NULL) { if (actor->id == ACTOR_OBJ_ICE_POLY) { @@ -167,32 +153,33 @@ ObjIcePoly* EnKgy_FindIceBlock(GlobalContext* globalCtx) { } void func_80B40C74(GlobalContext* globalCtx) { - gSaveContext.roomInf[globalCtx->sceneNum][5] |= 1; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= 1; if (CURRENT_DAY == 1) { - gSaveContext.roomInf[globalCtx->sceneNum][5] |= 2; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= 2; } else { - gSaveContext.roomInf[globalCtx->sceneNum][5] &= ~2; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 &= ~2; } } void func_80B40D00(GlobalContext* globalCtx) { - gSaveContext.roomInf[globalCtx->sceneNum][5] |= 4; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= 4; } void func_80B40D30(GlobalContext* globalCtx) { - gSaveContext.roomInf[globalCtx->sceneNum][5] &= ~7; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 &= ~7; } s32 func_80B40D64(GlobalContext* globalCtx) { - return gSaveContext.roomInf[globalCtx->sceneNum][5] & 1; + return gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 1; } s32 func_80B40D8C(GlobalContext* globalCtx) { - return gSaveContext.roomInf[globalCtx->sceneNum][5] & 4; + return gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 4; } s32 func_80B40DB4(GlobalContext* globalCtx) { - if ((CURRENT_DAY == 3) || ((CURRENT_DAY == 2) && (gSaveContext.roomInf[globalCtx->sceneNum][5] & 2))) { + if ((CURRENT_DAY == 3) || + ((CURRENT_DAY == 2) && (gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 2))) { return true; } return false; @@ -258,7 +245,7 @@ void func_80B40EE8(EnKgy* this, GlobalContext* globalCtx) { f32 sp34; f32 temp_f0; - func_800B4EDC(globalCtx, &this->unk_2B4, &sp38, &sp34); + Actor_GetProjectedPos(globalCtx, &this->unk_2B4, &sp38, &sp34); temp_f0 = sp38.x * sp34; if (this->unk_2E6 > 0) { this->unk_2E6--; @@ -375,7 +362,7 @@ void func_80B413C8(EnKgy* this) { } s32 func_80B41460(void) { - if ((gSaveContext.playerForm != PLAYER_FORM_HUMAN) || + if ((gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) || ((CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_KOKIRI) && (CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_RAZOR) && (CUR_FORM_EQUIP(EQUIP_SLOT_B) != ITEM_SWORD_GILDED))) { return 0xC38; @@ -401,7 +388,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 +413,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) { @@ -458,7 +445,7 @@ void func_80B4163C(EnKgy* this, GlobalContext* globalCtx) { this->lightInfo.params.point.y = this->unk_2C0.y; this->lightInfo.params.point.z = this->unk_2C0.z; this->unk_300 = 200; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SWORD_FORGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SWORD_FORGE); break; } @@ -470,10 +457,10 @@ void func_80B4163C(EnKgy* this, GlobalContext* globalCtx) { void func_80B417B8(EnKgy* this, GlobalContext* globalCtx) { func_80B4163C(this, globalCtx); - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); func_80B413C8(this); - this->actor.flags &= ~0x100; + this->actor.flags &= ~ACTOR_FLAG_100; this->actionFunc = func_80B419B0; func_80B40E18(this, 7); } @@ -494,14 +481,14 @@ void func_80B41858(EnKgy* this, GlobalContext* globalCtx) { void func_80B418C4(EnKgy* this, GlobalContext* globalCtx) { func_80B4163C(this, globalCtx); if ((this->unk_2E4 <= 0) && !(this->unk_29C & 2) && (func_80B40E54(this) == 0) && - (func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx) && - ((globalCtx->msgCtx.unk11F04 == 0xC4E) || (globalCtx->msgCtx.unk11F04 == 0xC4F))) { + (Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx) && + ((globalCtx->msgCtx.currentTextId == 0xC4E) || (globalCtx->msgCtx.currentTextId == 0xC4F))) { func_801477B4(globalCtx); this->actor.textId = 0xC4F; func_80B413C8(this); ActorCutscene_SetIntentToPlay(this->unk_2D4[5]); this->actionFunc = func_80B41858; - this->actor.flags &= ~0x100; + this->actor.flags &= ~ACTOR_FLAG_100; } func_80B40EE8(this, globalCtx); } @@ -511,7 +498,7 @@ void func_80B419B0(EnKgy* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); func_80B4163C(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx) || (&this->actor == player->targetActor)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) || (&this->actor == player->targetActor)) { func_80B411DC(this, globalCtx, 4); func_80B40E18(this, this->actor.textId); if (this->actor.textId == 0xC37) { @@ -533,19 +520,19 @@ void func_80B41A48(EnKgy* this, GlobalContext* globalCtx) { } void func_80B41ACC(EnKgy* this, GlobalContext* globalCtx) { - s32 temp_v0; + s32 itemActionParam; Player* player = GET_PLAYER(globalCtx); SkelAnime_Update(&this->skelAnime); - if (func_80152498(&globalCtx->msgCtx) == 0x10) { - temp_v0 = func_80123810(globalCtx); - if (temp_v0 != 0) { + if (Message_GetState(&globalCtx->msgCtx) == 0x10) { + itemActionParam = func_80123810(globalCtx); + if (itemActionParam != PLAYER_AP_NONE) { this->actionFunc = func_80B41E18; } - if (temp_v0 > 0) { + if (itemActionParam > PLAYER_AP_NONE) { func_801477B4(globalCtx); - if (temp_v0 == 0x1B) { + if (itemActionParam == PLAYER_AP_BOTTLE_GOLD_DUST) { if (this->unk_29C & 0x10) { this->actor.textId = 0xC55; player->actor.textId = 0xC55; @@ -562,7 +549,7 @@ void func_80B41ACC(EnKgy* this, GlobalContext* globalCtx) { player->actor.textId = 0xC47; } this->unk_29C |= 8; - } else if (temp_v0 < 0) { + } else if (itemActionParam < PLAYER_AP_NONE) { if (this->unk_29C & 0x10) { this->actor.textId = 0xC57; } else { @@ -586,22 +573,22 @@ void func_80B41C30(EnKgy* this, GlobalContext* globalCtx) { void func_80B41C54(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = func_80B41C30; - this->actor.flags &= ~0x100; + this->actor.flags &= ~ACTOR_FLAG_100; } func_80B40EE8(this, globalCtx); } void func_80B41CBC(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; func_80B40E18(this, this->actor.textId); this->actionFunc = func_80B41E18; func_80B411DC(this, globalCtx, 4); } else { - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_MINUS1); } } @@ -609,10 +596,10 @@ void func_80B41D64(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Actor_HasParent(&this->actor, globalCtx)) { this->actionFunc = func_80B41CBC; - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_MINUS1); } else { - func_800B8A1C(&this->actor, globalCtx, this->unk_2EA, 2000.0f, 1000.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk_2EA, 2000.0f, 1000.0f); } func_80B40EE8(this, globalCtx); } @@ -627,16 +614,16 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { } if ((this->unk_2E4 <= 0) && !(this->unk_29C & 2) && func_80B40E54(this) == 0) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: - if (func_80147624(globalCtx)) { - temp = globalCtx->msgCtx.unk11F04; + if (Message_ShouldAdvance(globalCtx)) { + temp = globalCtx->msgCtx.currentTextId; switch (temp) { case 0xC3B: switch (globalCtx->msgCtx.choiceIndex) { case 0: - if (gSaveContext.rupees < globalCtx->msgCtx.unk1206C) { + if (gSaveContext.save.playerData.rupees < globalCtx->msgCtx.unk1206C) { play_sound(NA_SE_SY_ERROR); func_80B40E74(this, globalCtx, 0xC3F); } else { @@ -671,8 +658,8 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { break; case 5: - if (func_80147624(globalCtx)) { - temp = globalCtx->msgCtx.unk11F04; + if (Message_ShouldAdvance(globalCtx)) { + temp = globalCtx->msgCtx.currentTextId; switch (temp) { case 0xC35: @@ -731,7 +718,7 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { func_80B41368(this, globalCtx, 0); this->actor.textId = 0xC43; CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_NONE; - TAKE_EQUIPPED_ITEM(EQUIP_SWORD); + SET_EQUIP_VALUE(EQUIP_SWORD, 0); func_80112B40(globalCtx, 0); func_80B40C74(globalCtx); break; @@ -758,8 +745,8 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { case 0xC46: case 0xC55: - func_80123D50(globalCtx, GET_PLAYER(globalCtx), 0x12, 0x15); - player->unk_A87 = 0; + func_80123D50(globalCtx, GET_PLAYER(globalCtx), ITEM_BOTTLE, PLAYER_AP_BOTTLE); + player->exchangeItemId = EXCH_ITEM_NONE; this->unk_29C &= ~0x8; globalCtx->msgCtx.unk11F10 = 0; func_80B41368(this, globalCtx, 4); @@ -774,7 +761,7 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { case 0xC47: func_80B40BC0(this, 1); if (this->unk_29C & 8) { - player->unk_A87 = 0; + player->exchangeItemId = EXCH_ITEM_NONE; this->unk_29C &= ~8; } func_80B40EBC(this, globalCtx, temp); @@ -813,7 +800,7 @@ void func_80B41E18(EnKgy* this, GlobalContext* globalCtx) { func_801477B4(globalCtx); this->actionFunc = func_80B41D64; func_80B413C8(this); - func_800B8A1C(&this->actor, globalCtx, this->unk_2EA, 2000.0f, 1000.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk_2EA, 2000.0f, 1000.0f); break; case 0xC51: @@ -846,7 +833,7 @@ void func_80B42508(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actor.focus.pos = this->unk_2A8; - if (func_800B84D0(&this->actor, globalCtx) || (&this->actor == player->targetActor)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) || (&this->actor == player->targetActor)) { this->actionFunc = func_80B41E18; func_80B411DC(this, globalCtx, 4); func_80B40E18(this, this->actor.textId); @@ -856,7 +843,7 @@ void func_80B42508(EnKgy* this, GlobalContext* globalCtx) { void func_80B425A0(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actor.focus.pos = this->unk_2A8; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B41E18; func_80B40BC0(this, 1); func_80B411DC(this, globalCtx, 0); @@ -869,10 +856,10 @@ void func_80B425A0(EnKgy* this, GlobalContext* globalCtx) { void func_80B42660(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actor.focus.pos = this->unk_2A8; - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); func_80B413C8(this); - this->actor.flags &= ~0x100; + this->actor.flags &= ~ACTOR_FLAG_100; this->actionFunc = func_80B42714; func_80B40E18(this, 7); } @@ -885,7 +872,7 @@ void func_80B42714(EnKgy* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actor.focus.pos = this->unk_2A8; - if (func_800B84D0(&this->actor, globalCtx) || (&this->actor == player->targetActor)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) || (&this->actor == player->targetActor)) { func_80B411DC(this, globalCtx, 4); func_80B40E18(this, this->actor.textId); if (this->actor.textId == 0xC37) { @@ -910,8 +897,8 @@ void func_80B427C8(EnKgy* this, GlobalContext* globalCtx) { } if ((this->unk_2E4 <= 0) && !(this->unk_29C & 2) && (func_80B40E54(this) == 0) && - (func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - temp_a2 = globalCtx->msgCtx.unk11F04; + (Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + temp_a2 = globalCtx->msgCtx.currentTextId; switch (temp_a2) { case 0xC30: @@ -951,7 +938,7 @@ void func_80B4296C(EnKgy* this, GlobalContext* globalCtx) { } this->actor.focus.pos = this->unk_2A8; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B427C8; if (this->unk_2D2 == 4) { func_80B40BC0(this, 7); @@ -960,10 +947,10 @@ void func_80B4296C(EnKgy* this, GlobalContext* globalCtx) { } func_80B411DC(this, globalCtx, 0); func_80B40E18(this, this->actor.textId); - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } else { - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_NONE); } } @@ -982,8 +969,8 @@ void func_80B42A8C(EnKgy* this, GlobalContext* globalCtx) { } if ((this->unk_2E4 <= 0) && !(this->unk_29C & 2) && (func_80B40E54(this) == 0) && - (func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - temp_a2 = globalCtx->msgCtx.unk11F04; + (Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + temp_a2 = globalCtx->msgCtx.currentTextId; switch (temp_a2) { case 0xC1D: case 0xC2D: @@ -1063,13 +1050,13 @@ void func_80B42D28(EnKgy* this, GlobalContext* globalCtx) { } this->actor.focus.pos = this->unk_2A8; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B42A8C; if (this->actor.textId == 0xC2D) { func_80B40BC0(this, 1); } else { EnKgy_ChangeAnim(this, 5, 2, -5.0f); - gSaveContext.weekEventReg[20] |= 0x80; + gSaveContext.save.weekEventReg[20] |= 0x80; } func_80B411DC(this, globalCtx, 0); func_80B40E18(this, this->actor.textId); @@ -1077,7 +1064,7 @@ void func_80B42D28(EnKgy* this, GlobalContext* globalCtx) { if (Flags_GetSwitch(globalCtx, ENKGY_GET_FE00(&this->actor))) { this->actor.textId = 0xC30; this->actionFunc = func_80B4296C; - gSaveContext.weekEventReg[21] |= 1; + gSaveContext.save.weekEventReg[21] |= 1; } else if (this->actor.xzDistToPlayer < 200.0f) { if (this->unk_2D2 == 4) { this->actor.textId = 0xC2D; @@ -1134,11 +1121,11 @@ void EnKgy_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve EnKgy* this = THIS; if (limbIndex == 11) { - Matrix_MultiplyVector3fByState(&D_80B432D8, &this->unk_2A8); + Matrix_MultVec3f(&D_80B432D8, &this->unk_2A8); } if (limbIndex == 16) { - Matrix_MultiplyVector3fByState(&D_80B432E4, &this->unk_2C0); + Matrix_MultVec3f(&D_80B432E4, &this->unk_2C0); } } @@ -1150,31 +1137,31 @@ void func_80B43074(EnKgy* this, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); func_800B8050(&this->actor, globalCtx, MTXMODE_NEW); - Matrix_StatePush(); - Matrix_InsertTranslation(-800.0f, 3100.0f, 8400.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(0x4000, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Translate(-800.0f, 3100.0f, 8400.0f, MTXMODE_APPLY); + Matrix_RotateXS(0x4000, MTXMODE_APPLY); if (func_80B40D8C(globalCtx)) { - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(D_0600F6A0)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_kgy_Matanimheader_00F6A0)); } else { - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(D_0600EE58)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_kgy_Matanimheader_00EE58)); } gfx = POLY_OPA_DISP; gSPMatrix(gfx, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (func_80B40D8C(globalCtx)) { - gSPDisplayList(&gfx[1], D_04001D00); - gSPDisplayList(&gfx[2], D_0600F180); + gSPDisplayList(&gfx[1], gameplay_keep_DL_001D00); + gSPDisplayList(&gfx[2], object_kgy_DL_00F180); } else { - gSPDisplayList(&gfx[1], D_040021A8); - gSPDisplayList(&gfx[2], D_0600E8F0); + gSPDisplayList(&gfx[1], gameplay_keep_DL_0021A8); + gSPDisplayList(&gfx[2], object_kgy_DL_00E8F0); } POLY_OPA_DISP = &gfx[3]; CLOSE_DISPS(globalCtx->state.gfxCtx); - Matrix_StatePop(); + Matrix_Pop(); } void EnKgy_Draw(Actor* thisx, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_Kitan/z_en_kitan.c b/src/overlays/actors/ovl_En_Kitan/z_en_kitan.c index fa391cafd..5a83ecad4 100644 --- a/src/overlays/actors/ovl_En_Kitan/z_en_kitan.c +++ b/src/overlays/actors/ovl_En_Kitan/z_en_kitan.c @@ -1,6 +1,12 @@ +/* + * File: z_en_kitan.c + * Overlay: ovl_En_Kitan + * Description: + */ + #include "z_en_kitan.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnKitan*)thisx) diff --git a/src/overlays/actors/ovl_En_Knight/z_en_knight.c b/src/overlays/actors/ovl_En_Knight/z_en_knight.c index 64f1d78df..8f6464411 100644 --- a/src/overlays/actors/ovl_En_Knight/z_en_knight.c +++ b/src/overlays/actors/ovl_En_Knight/z_en_knight.c @@ -1,6 +1,12 @@ +/* + * File: z_en_knight.c + * Overlay: ovl_En_Knight + * Description: Igos du Ikana and his lackeys + */ + #include "z_en_knight.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnKnight*)thisx) diff --git a/src/overlays/actors/ovl_En_Knight/z_en_knight.h b/src/overlays/actors/ovl_En_Knight/z_en_knight.h index 00c48db91..8191b13a2 100644 --- a/src/overlays/actors/ovl_En_Knight/z_en_knight.h +++ b/src/overlays/actors/ovl_En_Knight/z_en_knight.h @@ -9,9 +9,21 @@ typedef void (*EnKnightActionFunc)(struct EnKnight*, GlobalContext*); typedef struct EnKnight { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x2DC]; + /* 0x0144 */ s16 unk_144; + /* 0x0146 */ char unk_146[0x2]; + /* 0x0148 */ s8 unk_148; + /* 0x0149 */ char pad149[8]; + /* 0x0151 */ s8 unk_151; + /* 0x0152 */ char pad152[1]; + /* 0x0153 */ u8 unk_153; + /* 0x0154 */ u8 unk_154; + /* 0x0155 */ char pad155[0x2CB]; /* 0x0420 */ EnKnightActionFunc actionFunc; - /* 0x0424 */ char unk_424[0x2B0]; + /* 0x0424 */ char unk_424[0x25C]; + /* 0x0680 */ u8 unk_680; + /* 0x0681 */ char pad681[9]; + /* 0x068A */ s16 unk_68A; + /* 0x068C */ char pad68C[0x48]; } EnKnight; // size = 0x6D4 extern const ActorInit En_Knight_InitVars; diff --git a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.c b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.c index dfc0a1173..caf235b05 100644 --- a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.c +++ b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.c @@ -1,6 +1,15 @@ -#include "z_en_kujiya.h" +/* + * File: z_en_kujiya.c + * Overlay: ovl_En_Kujiya + * Description: Clock Town - Lottery Shop + * + * (kuji = lottery, ya = shop) + */ -#define FLAGS 0x08000009 +#include "z_en_kujiya.h" +#include "objects/object_kujiya/object_kujiya.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_8000000) #define THIS ((EnKujiya*)thisx) @@ -9,14 +18,22 @@ void EnKujiya_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKujiya_Update(Actor* thisx, GlobalContext* globalCtx); void EnKujiya_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BB09BC(EnKujiya* this, GlobalContext* globalCtx); -void func_80BB0E58(EnKujiya* this, GlobalContext* globalCtx); -void func_80BB0F38(EnKujiya* this, GlobalContext* globalCtx); -void func_80BB0FA8(EnKujiya* this, GlobalContext* globalCtx); -void func_80BB1180(EnKujiya* this, GlobalContext* globalCtx); -void func_80BB1268(EnKujiya* this, GlobalContext* globalCtx); +void EnKujiya_SetupWait(EnKujiya* this); +void EnKujiya_Wait(EnKujiya* this, GlobalContext* globalCtx); +void EnKujiya_SetupTalk(EnKujiya* this); +void EnKujiya_Talk(EnKujiya* this, GlobalContext* globalCtx); +void EnKujiya_SetupGivePrize(EnKujiya* this); +void EnKujiya_GivePrize(EnKujiya* this, GlobalContext* globalCtx); +void EnKujiya_SetupFinishGivePrize(EnKujiya* this); +void EnKujiya_FinishGivePrize(EnKujiya* this, GlobalContext* globalCtx); +s32 EnKujiya_CheckBoughtTicket(void); +void EnKujiya_SetBoughtTicket(void); +void EnKujiya_UnsetBoughtTicket(void); +void EnKujiya_SetupTurnToOpen(EnKujiya* this); +void EnKujiya_TurnToOpen(EnKujiya* this, GlobalContext* globalCtx); +void EnKujiya_SetupTurnToClosed(EnKujiya* this); +void EnKujiya_TurnToClosed(EnKujiya* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kujiya_InitVars = { ACTOR_EN_KUJIYA, ACTORCAT_NPC, @@ -29,48 +46,332 @@ const ActorInit En_Kujiya_InitVars = { (ActorFunc)EnKujiya_Draw, }; -#endif +#define CHECK_LOTTERY_NUMBERS \ + (((u32)((void)0, gSaveContext.save.lotteryCodes[CURRENT_DAY - 1][0]) == \ + ((((void)0, gSaveContext.save.lotteryCodeGuess & 0xFFFF) & 0xF00) >> 8)) && \ + ((u32)((void)0, gSaveContext.save.lotteryCodes[CURRENT_DAY - 1][1]) == \ + ((((void)0, gSaveContext.save.lotteryCodeGuess & 0xFFFF) & 0xF0) >> 4)) && \ + ((u32)((void)0, gSaveContext.save.lotteryCodes[CURRENT_DAY - 1][2]) == \ + (((void)0, gSaveContext.save.lotteryCodeGuess & 0xFFFF) & 0xF))) -extern UNK_TYPE D_06006198; +void EnKujiya_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKujiya* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/EnKujiya_Init.s") + Actor_SetScale(&this->actor, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/EnKujiya_Destroy.s") + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.targetMode = 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB09A8.s") + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 30.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB09BC.s") + if (EnKujiya_CheckBoughtTicket() && (gSaveContext.save.time >= CLOCK_TIME(6, 0)) && + (gSaveContext.save.time < CLOCK_TIME(18, 0))) { + this->actor.shape.rot.y = 0; + } else { + this->actor.shape.rot.y = 0x7555; + } + EnKujiya_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0B28.s") +void EnKujiya_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0BF8.s") +void EnKujiya_SetupWait(EnKujiya* this) { + this->actionFunc = EnKujiya_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0E44.s") +void EnKujiya_Wait(EnKujiya* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if ((gSaveContext.save.time >= CLOCK_TIME(6, 0)) && (gSaveContext.save.time < CLOCK_TIME(18, 0))) { + if (EnKujiya_CheckBoughtTicket()) { + Message_StartTextbox(globalCtx, 0x2B61, &this->actor); + this->textId = 0x2B61; // Come back tomorrow + } else { + Message_StartTextbox(globalCtx, 0x2B5C, &this->actor); + this->textId = 0x2B5C; // Pick 3 numbers + } + } else if (EnKujiya_CheckBoughtTicket()) { + Message_StartTextbox(globalCtx, 0x2B64, &this->actor); + this->textId = 0x2B64; // Announce winning numbers + } else { + Message_StartTextbox(globalCtx, 0x2B63, &this->actor); + this->textId = 0x2B63; // Exchanging winning tickets + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0E58.s") + EnKujiya_SetupTalk(this); + } else if ((gSaveContext.save.time >= CLOCK_TIME(18, 0)) && EnKujiya_CheckBoughtTicket() && + (this->actor.shape.rot.y == 0)) { + EnKujiya_SetupTurnToOpen(this); + } else if (this->actor.xzDistToPlayer < 100.0f) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0F24.s") +void EnKujiya_HandlePlayerChoice(EnKujiya* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { // Buy + if (gSaveContext.save.playerData.rupees < 10) { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x2B62, &this->actor); + this->textId = 0x2B62; // Not enough Rupees + } else { + func_8019F208(); + func_801159EC(-10); + Message_StartTextbox(globalCtx, 0x2B5F, &this->actor); + this->textId = 0x2B5F; // Enter number + } + } else { // Don't buy + func_8019F230(); + Message_StartTextbox(globalCtx, 0x2B5E, &this->actor); + this->textId = 0x2B5E; // Too bad + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0F38.s") +void EnKujiya_ChooseNextDialogue(EnKujiya* this, GlobalContext* globalCtx) { + // Build suspense + if (this->textId == 0x2B65) { // Your numbers vs winning numbers + if (this->timer != 0) { + this->timer--; + return; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0F94.s") + if (Message_ShouldAdvance(globalCtx)) { + switch (this->textId) { + case 0x2B5C: + Message_StartTextbox(globalCtx, 0x2B5D, &this->actor); + this->textId = 0x2B5D; // Buy or not + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0FA8.s") + case 0x2B60: + EnKujiya_SetBoughtTicket(); + func_801477B4(globalCtx); + EnKujiya_SetupTurnToClosed(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB0FF8.s") + case 0x2B64: + EnKujiya_UnsetBoughtTicket(); + this->timer = 20; + Message_StartTextbox(globalCtx, 0x2B65, &this->actor); + this->textId = 0x2B65; // Your numbers vs winning numbers + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB1088.s") + case 0x2B65: + if (CHECK_LOTTERY_NUMBERS) { + Message_StartTextbox(globalCtx, 0x2B66, &this->actor); + this->textId = 0x2B66; // Won 50 Rupees + } else { + Message_StartTextbox(globalCtx, 0x2B67, &this->actor); + this->textId = 0x2B67; // Lost, come back tomorrow + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB10F8.s") + case 0x2B66: + func_801477B4(globalCtx); + EnKujiya_SetupGivePrize(this); + EnKujiya_GivePrize(this, globalCtx); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB1168.s") +void EnKujiya_SetupTalk(EnKujiya* this) { + this->actionFunc = EnKujiya_Talk; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB1180.s") +void EnKujiya_Talk(EnKujiya* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB1250.s") + case 4: + EnKujiya_HandlePlayerChoice(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/func_80BB1268.s") + case 5: + EnKujiya_ChooseNextDialogue(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/EnKujiya_Update.s") + case 6: + if (Message_ShouldAdvance(globalCtx)) { + EnKujiya_SetupWait(this); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kujiya/EnKujiya_Draw.s") + case 17: + if (Message_ShouldAdvance(globalCtx)) { + Inventory_SaveLotteryCodeGuess(globalCtx); + Message_StartTextbox(globalCtx, 0x2B60, &this->actor); + this->textId = 0x2B60; // Will announce winning numbers after 6 + } + break; + } +} + +void EnKujiya_SetupGivePrize(EnKujiya* this) { + this->actionFunc = EnKujiya_GivePrize; +} + +void EnKujiya_GivePrize(EnKujiya* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + EnKujiya_SetupFinishGivePrize(this); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + } +} + +void EnKujiya_SetupFinishGivePrize(EnKujiya* this) { + this->actionFunc = EnKujiya_FinishGivePrize; +} + +void EnKujiya_FinishGivePrize(EnKujiya* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + EnKujiya_SetupWait(this); + } +} + +s32 EnKujiya_CheckBoughtTicket(void) { + switch (CURRENT_DAY) { + case 1: + if (gSaveContext.save.weekEventReg[33] & 0x10) { + return true; + } + break; + + case 2: + if (gSaveContext.save.weekEventReg[33] & 0x20) { + return true; + } + break; + + case 3: + if (gSaveContext.save.weekEventReg[33] & 0x40) { + return true; + } + break; + } + return false; +} + +void EnKujiya_SetBoughtTicket(void) { + switch (CURRENT_DAY) { + case 1: + gSaveContext.save.weekEventReg[33] |= 0x10; + break; + + case 2: + gSaveContext.save.weekEventReg[33] |= 0x20; + break; + + case 3: + gSaveContext.save.weekEventReg[33] |= 0x40; + break; + } +} + +/** + * Used when player turns in a ticket + */ +void EnKujiya_UnsetBoughtTicket(void) { + switch (CURRENT_DAY) { + case 1: + gSaveContext.save.weekEventReg[33] &= (u8)~0x10; + break; + + case 2: + gSaveContext.save.weekEventReg[33] &= (u8)~0x20; + break; + + case 3: + gSaveContext.save.weekEventReg[33] &= (u8)~0x40; + break; + } +} + +void EnKujiya_SetupTurnToOpen(EnKujiya* this) { + this->timer = 0; + this->actionFunc = EnKujiya_TurnToOpen; +} + +void EnKujiya_TurnToOpen(EnKujiya* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } + + if (!Math_SmoothStepToS(&this->actor.shape.rot.y, 0x7555, 0xA, 0x16C, 0x16C)) { + if (this->timer > 20) { + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + ActorCutscene_Stop(this->actor.cutscene); + } + EnKujiya_SetupWait(this); + } else { + this->timer++; + } + } else { + func_800B9010(&this->actor, NA_SE_EV_WINDMILL_LEVEL - SFX_FLAG); + } +} + +void EnKujiya_SetupTurnToClosed(EnKujiya* this) { + this->timer = 0; + this->actionFunc = EnKujiya_TurnToClosed; +} + +void EnKujiya_TurnToClosed(EnKujiya* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } + + if (!Math_SmoothStepToS(&this->actor.shape.rot.y, 0, 0xA, 0x16C, 0x16C)) { + if (this->timer > 20) { + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + ActorCutscene_Stop(this->actor.cutscene); + } + EnKujiya_SetupWait(this); + } else { + this->timer++; + } + } else { + func_800B9010(&this->actor, NA_SE_EV_WINDMILL_LEVEL - SFX_FLAG); + } +} + +void EnKujiya_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKujiya* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void EnKujiya_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKujiya* this = THIS; + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gLotteryShopTexAnim)); + + 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++, gLotteryShopCylinderDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopBackSignDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopOpenBoxDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopScrollingEffectsDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopRedRupeesDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopGreenRupeesDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopBlueRupeesDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopTargetArrowAndSignDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopScrollingArrowDL); + gSPDisplayList(POLY_OPA_DISP++, gLotteryShopMaskDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..b95a5bb36 100644 --- a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h +++ b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h @@ -8,9 +8,10 @@ struct EnKujiya; typedef void (*EnKujiyaActionFunc)(struct EnKujiya*, GlobalContext*); typedef struct EnKujiya { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnKujiyaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnKujiyaActionFunc actionFunc; + /* 0x148 */ s16 timer; + /* 0x14A */ s16 textId; } EnKujiya; // size = 0x14C extern const ActorInit En_Kujiya_InitVars; diff --git a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c index 5684c89dd..1767f3c86 100644 --- a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c +++ b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.c @@ -1,6 +1,16 @@ -#include "z_en_kusa.h" +/* + * File: z_en_kusa.c + * Overlay: ovl_En_Kusa + * Description: Grass / Bush + */ -#define FLAGS 0x00800010 +#include "prevent_bss_reordering.h" +#include "z_en_kusa.h" +#include "objects/object_kusa/object_kusa.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnKusa*)thisx) @@ -8,15 +18,46 @@ void EnKusa_Init(Actor* thisx, GlobalContext* globalCtx); void EnKusa_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKusa_Update(Actor* thisx, GlobalContext* globalCtx); -void func_809358D8(EnKusa* this, GlobalContext* globalCtx); -void func_809359AC(EnKusa* this, GlobalContext* globalCtx); -void func_80935BBC(EnKusa* this, GlobalContext* globalCtx); -void func_80935D64(EnKusa* this, GlobalContext* globalCtx); -void func_809361A4(EnKusa* this, GlobalContext* globalCtx); -void func_80936220(EnKusa* this, GlobalContext* globalCtx); -void func_809362D8(EnKusa* this, GlobalContext* globalCtx); +s32 EnKusa_SnapToFloor(EnKusa* this, GlobalContext* globalCtx, f32 yOffset); +void EnKusa_DropCollectible(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_UpdateVelY(EnKusa* this); +void EnKusa_RandScaleVecToZero(Vec3f* vec, f32 scaleFactor); +void EnKusa_SetScaleSmall(EnKusa* this); +s32 EnKusa_GetWaterBox(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupWaitObject(EnKusa* this); +void EnKusa_WaitObject(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_WaitForInteract(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupLiftedUp(EnKusa* this); +void EnKusa_LiftedUp(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_WaitObject(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupInteract(EnKusa* this); +void EnKusa_SetupFall(EnKusa* this); +void EnKusa_Fall(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupCut(EnKusa* this); +void EnKusa_CutWaitRegrow(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_DoNothing(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupUprootedWaitRegrow(EnKusa* this); +void EnKusa_UprootedWaitRegrow(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_SetupRegrow(EnKusa* this); +void EnKusa_Regrow(EnKusa* this, GlobalContext* globalCtx); +void EnKusa_DrawBush(Actor* thisx, GlobalContext* globalCtx2); +void EnKusa_DrawGrass(Actor* thisx, GlobalContext* globalCtx); + +s16 rotSpeedXtarget = 0; +s16 rotSpeedX = 0; +s16 rotSpeedYtarget = 0; +s16 rotSpeedY = 0; +s16 D_809366B0 = 0; +u8 D_809366B4 = true; + +u32 kusaGameplayFrames; +MtxF D_80936AD8[8]; +s16 D_80936CD8; +s16 D_80936CDA; +s16 D_80936CDC; +s16 D_80936CDE; +s16 D_80936CE0; -#if 0 const ActorInit En_Kusa_InitVars = { ACTOR_EN_KUSA, ACTORCAT_PROP, @@ -29,92 +70,665 @@ const ActorInit En_Kusa_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809366E0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x0580C71C, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, +static s16 objectIds[] = { GAMEPLAY_FIELD_KEEP, OBJECT_KUSA, OBJECT_KUSA, OBJECT_KUSA }; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x0580C71C, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 6, 44, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_8093670C = { 0, 12, 30, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 30, MASS_IMMOVABLE }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80936754[] = { +static Vec3f sUnitDirections[] = { + { 0.0f, 0.7071f, 0.7071f }, + { 0.7071f, 0.7071f, 0.0f }, + { 0.0f, 0.7071f, -0.7071f }, + { -0.7071f, 0.7071f, 0.0f }, +}; + +static s16 sFragmentScales[] = { 108, 102, 96, 84, 66, 55, 42, 38 }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -3200, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -17000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif +/** + * @brief Applies a "swaying" motion to the provided matrix + * + */ +void EnKusa_ApplySway(MtxF* matrix) { + MtxF* mtxState = Matrix_GetCurrent(); + f32* tmp = &mtxState->mf[0][0]; + f32* tmp2 = &matrix->mf[0][0]; + s32 i; -extern ColliderCylinderInit D_809366E0; -extern CollisionCheckInfoInit D_8093670C; -extern InitChainEntry D_80936754[]; + for (i = 0; i < 16; i++) { + *tmp++ += *tmp2++; + } +} -extern UNK_TYPE D_060002E0; +/** + * @brief Updates the matrix controlling movement of the leaves of grass to simulate a swaying motion from the wind + * blowing. + */ +void EnKusa_Sway(void) { + s32 i; + s32 pad; + f32 sin_6CDA; + f32* ptr; + f32 sin_6CDE; + f32 sin_6CE0; + f32 tempf1; + f32 tempf2; + f32 tempf3; + f32 tempf4; + f32 tempf5; + f32 sp7C[8]; + f32 cos_6CE0; + f32 cos_6CDA; + f32 cos_6CDC; + f32 cos_6CDE; + f32 cos_6CD8; + f32 sin_6CD8; + f32 sin_6CDC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809349E0.s") + D_80936CD8 += 0x46; + D_80936CDA += 0x12C; + D_80936CDC += 0x2BC; + D_80936CDE += 0x514; + D_80936CE0 += 0x22C4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80934AB4.s") + sin_6CD8 = Math_SinS(D_80936CD8); + sin_6CDA = Math_SinS(D_80936CDA); + sin_6CDC = Math_SinS(D_80936CDC); + sin_6CDE = Math_SinS(D_80936CDE) * 1.2f; + sin_6CE0 = Math_SinS(D_80936CE0) * 1.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80934F58.s") + cos_6CD8 = Math_CosS(D_80936CD8); + cos_6CDA = Math_CosS(D_80936CDA); + cos_6CDC = Math_CosS(D_80936CDC); + cos_6CDE = Math_CosS(D_80936CDE) * 1.3f; + cos_6CE0 = Math_CosS(D_80936CE0) * 1.7f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80934FFC.s") + sp7C[0] = (sin_6CD8 - cos_6CDA) * sin_6CDC * cos_6CD8 * sin_6CD8 * 0.0015f; + sp7C[1] = (sin_6CDA - cos_6CDC) * sin_6CDE * cos_6CDA * sin_6CD8 * 0.0015f; + sp7C[2] = (sin_6CDC - cos_6CDE) * cos_6CDC * sin_6CD8 * cos_6CD8 * 0.0015f; + sp7C[3] = (sin_6CDE - cos_6CDA) * cos_6CDE * sin_6CDA * cos_6CD8 * 0.0015f; + sp7C[4] = (sin_6CD8 - cos_6CDC) * sin_6CD8 * sin_6CDA * sin_6CE0 * 0.0015f; + sp7C[5] = (sin_6CDA - cos_6CDE) * sin_6CDC * sin_6CDE * sin_6CE0 * 0.0015f; + sp7C[6] = (sin_6CDC - cos_6CD8) * cos_6CD8 * cos_6CDA * cos_6CE0 * 0.0015f; + sp7C[7] = (sin_6CDE - cos_6CDA) * cos_6CDC * cos_6CDE * cos_6CE0 * 0.0015f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809350C4.s") + for (i = 0; i < ARRAY_COUNT(D_80936AD8); i++) { + ptr = &D_80936AD8[i].mf[0][0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809350F8.s") + tempf1 = sp7C[i & 7]; + tempf2 = sp7C[(i + 1) & 7]; + tempf3 = sp7C[(i + 2) & 7]; + tempf4 = sp7C[(i + 3) & 7]; + tempf5 = sp7C[(i + 4) & 7]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_8093517C.s") + ptr[0] = sp7C[1] * 0.2f; + ptr[1] = tempf1; + ptr[2] = tempf2; + ptr[3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809351A0.s") + ptr[4] = tempf3; + ptr[5] = sp7C[0]; + ptr[6] = tempf3; + ptr[7] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809354F8.s") + ptr[8] = tempf4; + ptr[9] = tempf5; + ptr[10] = sp7C[3] * 0.2f; + ptr[11] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809355A4.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_En_Kusa/func_8093561C.s") +/** + * @brief Detects if a bush is able to snap to the floor. BgCheck_EntityRaycastFloor5 will give the intersect point + * if no poit is found, a false value is returned. + * + * @param this + * @param globalCtx + * @param yOffset offset of Y coordinate, can be positive or negative. + * @return true/false if the bush is able to snap to the floor and is above BGCHECK_Y_MIN + */ +s32 EnKusa_SnapToFloor(EnKusa* this, GlobalContext* globalCtx, f32 yOffset) { + s32 pad; + CollisionPoly* poly; + Vec3f pos; + s32 bgId; + f32 floorY; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/EnKusa_Init.s") + pos.x = this->actor.world.pos.x; + pos.y = this->actor.world.pos.y + 30.0f; + pos.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/EnKusa_Destroy.s") + floorY = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &poly, &bgId, &this->actor, &pos); + if (floorY > BGCHECK_Y_MIN) { + this->actor.world.pos.y = floorY + yOffset; + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); + return true; + } else { + return false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809358C4.s") +void EnKusa_DropCollectible(EnKusa* this, GlobalContext* globalCtx) { + s32 collectible; + s32 collectableParams; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809358D8.s") + if ((GET_KUSA_TYPE(&this->actor) == ENKUSA_TYPE_GRASS) || (GET_KUSA_TYPE(&this->actor) == ENKUSA_TYPE_BUSH)) { + if (!(KUSA_GET_PARAMS_0C(&this->actor))) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, + KUSA_GET_RAND_COLLECTIBLE_ID(&this->actor) * 0x10); + } + } else if (GET_KUSA_TYPE(&this->actor) == ENKUSA_TYPE_REGROWING_GRASS) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, 3); + } else { + collectible = func_800A8150(KUSA_GET_PARAMS_3F(&this->actor)); + if (collectible >= 0) { + collectableParams = KUSA_GET_COLLECTIBLE_ID(&this->actor); + Item_DropCollectible(globalCtx, &this->actor.world.pos, (collectableParams << 8) | collectible); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80935988.s") +void EnKusa_UpdateVelY(EnKusa* this) { + this->actor.velocity.y += this->actor.gravity; + if (this->actor.velocity.y < this->actor.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809359AC.s") +/** + * @brief Scales a vector down by provided scale factor + * + * @param vec vector to be scaled + * @param scaleFactor scale factor to be applied to vector + */ +void EnKusa_RandScaleVecToZero(Vec3f* vec, f32 scaleFactor) { + scaleFactor += ((Rand_ZeroOne() * 0.2f) - 0.1f) * scaleFactor; + vec->x -= vec->x * scaleFactor; + vec->y -= vec->y * scaleFactor; + vec->z -= vec->z * scaleFactor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80935B94.s") +void EnKusa_SetScaleSmall(EnKusa* this) { + this->actor.scale.y = 160.0f * 0.001f; + this->actor.scale.x = 120.0f * 0.001f; + this->actor.scale.z = 120.0f * 0.001f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80935BBC.s") +void EnKusa_SpawnFragments(EnKusa* this, GlobalContext* globalCtx) { + Vec3f velocity; + Vec3f pos; + s32 i; + s32 scaleIndex; + Vec3f* directon; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80935CE8.s") + for (i = 0; i < ARRAY_COUNT(sUnitDirections); i++) { + directon = &sUnitDirections[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80935D64.s") + pos.x = this->actor.world.pos.x + (directon->x * this->actor.scale.x * 20.0f); + pos.y = this->actor.world.pos.y + (directon->y * this->actor.scale.y * 20.0f) + 10.0f; + pos.z = this->actor.world.pos.z + (directon->z * this->actor.scale.z * 20.0f); + velocity.x = (Rand_ZeroOne() - 0.5f) * 8.0f; + velocity.y = Rand_ZeroOne() * 10.0f; + velocity.z = (Rand_ZeroOne() - 0.5f) * 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80936120.s") + scaleIndex = (s32)(Rand_ZeroOne() * 111.1f) & 7; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80936168.s") + EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -100, 64, 40, 3, 0, sFragmentScales[scaleIndex], 0, 0, + 0x50, -1, 1, gKakeraLeafMiddle); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809361A4.s") + pos.x = this->actor.world.pos.x + (directon->x * this->actor.scale.x * 40.0f); + pos.y = this->actor.world.pos.y + (directon->y * this->actor.scale.y * 40.0f) + 10.0f; + pos.z = this->actor.world.pos.z + (directon->z * this->actor.scale.z * 40.0f); + velocity.x = (Rand_ZeroOne() - 0.5f) * 6.0f; + velocity.y = Rand_ZeroOne() * 10.0f; + velocity.z = (Rand_ZeroOne() - 0.5f) * 6.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809361B4.s") + scaleIndex = (s32)(Rand_ZeroOne() * 111.1f) % 7; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80936220.s") + EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -100, 64, 40, 3, 0, sFragmentScales[scaleIndex], 0, 0, + 0x50, -1, 1, gKakeraLeafTip); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80936290.s") +void EnKusa_SpawnBugs(EnKusa* this, GlobalContext* globalCtx) { + u32 numBugs; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809362D8.s") + for (numBugs = 0; numBugs < 3; numBugs++) { + Actor* bug = 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, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/EnKusa_Update.s") + if (bug == NULL) { + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_80936414.s") +s32 EnKusa_GetWaterBox(EnKusa* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* waterBox; + f32 ySurface; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa/func_809365CC.s") + if (WaterBox_GetSurfaceImpl(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &ySurface, &waterBox, &bgId) && + (this->actor.world.pos.y < ySurface)) { + return true; + } + return false; +} + +void EnKusa_InitCollider(Actor* thisx, GlobalContext* globalCtx) { + EnKusa* this = THIS; + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(thisx, &this->collider); +} + +void EnKusa_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKusa* this = THIS; + s32 pad; + s32 kusaType = GET_KUSA_TYPE(&this->actor); + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (globalCtx->csCtx.state != 0) { + this->actor.uncullZoneForward += 1000.0f; + } + EnKusa_InitCollider(&this->actor, globalCtx); + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + + if (kusaType == ENKUSA_TYPE_BUSH) { + this->actor.shape.shadowScale = 1.0f; + this->actor.shape.shadowAlpha = 60; + } else { + this->actor.shape.shadowScale = 0.9f; + this->actor.shape.shadowAlpha = 70; + } + + if (this->actor.shape.rot.y == 0) { + this->actor.shape.rot.y = ((u32)Rand_Next() >> 0x10); + this->actor.home.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + } + if (!EnKusa_SnapToFloor(this, globalCtx, 0.0f)) { + Actor_MarkForDeath(&this->actor); + return; + } + if (EnKusa_GetWaterBox(this, globalCtx)) { + this->isInWater |= 1; + } + + this->objIndex = Object_GetIndex(&globalCtx->objectCtx, objectIds[(GET_KUSA_TYPE(&this->actor))]); + if (this->objIndex < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + EnKusa_SetupWaitObject(this); + if (D_809366B4) { + D_80936CD8 = ((u32)Rand_Next() >> 0x10); + D_80936CDA = ((u32)Rand_Next() >> 0x10); + D_80936CDC = ((u32)Rand_Next() >> 0x10); + D_80936CDE = ((u32)Rand_Next() >> 0x10); + D_80936CE0 = ((u32)Rand_Next() >> 0x10); + D_809366B4 = false; + EnKusa_Sway(); + kusaGameplayFrames = globalCtx->gameplayFrames; + } + this->kusaMtxIdx = D_809366B0 & 7; + D_809366B0++; +} + +void EnKusa_Destroy(Actor* thisx, GlobalContext* globalCtx) { + GlobalContext* globalCtx2 = globalCtx; + EnKusa* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnKusa_SetupWaitObject(EnKusa* this) { + this->actionFunc = EnKusa_WaitObject; +} + +void EnKusa_WaitObject(EnKusa* this, GlobalContext* globalCtx) { + s32 pad; + + if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { + s32 kusaType = GET_KUSA_TYPE(&this->actor); + + if (this->isCut) { + EnKusa_SetupCut(this); + } else { + EnKusa_SetupInteract(this); + } + if (kusaType == ENKUSA_TYPE_BUSH) { + this->actor.draw = EnKusa_DrawBush; + } else { + this->actor.draw = EnKusa_DrawGrass; + } + this->actor.objBankIndex = this->objIndex; + this->actor.flags &= ~ACTOR_FLAG_10; + } +} + +void EnKusa_SetupInteract(EnKusa* this) { + this->actionFunc = EnKusa_WaitForInteract; + this->actor.flags &= ~ACTOR_FLAG_10; +} + +void EnKusa_WaitForInteract(EnKusa* this, GlobalContext* globalCtx) { + s32 pad; + + if (Actor_HasParent(&this->actor, globalCtx)) { + EnKusa_SetupLiftedUp(this); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT); + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + + } else if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + EnKusa_SpawnFragments(this, globalCtx); + EnKusa_DropCollectible(this, globalCtx); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN); + + if (KUSA_SHOULD_SPAWN_BUGS(&this->actor)) { + if (GET_KUSA_TYPE(&this->actor) != ENKUSA_TYPE_GRASS_2) { + EnKusa_SpawnBugs(this, globalCtx); + } + } + if (GET_KUSA_TYPE(&this->actor) == ENKUSA_TYPE_BUSH) { + Actor_MarkForDeath(&this->actor); + } else { + EnKusa_SetupCut(this); + this->isCut = true; + } + + } else { + if (!(this->collider.base.ocFlags1 & OC1_TYPE_PLAYER) && (this->actor.xzDistToPlayer > 12.0f)) { + this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; + } + + if (this->actor.xzDistToPlayer < 600.0f) { + Collider_UpdateCylinder(&this->actor, &this->collider); + 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) { + if (GET_KUSA_TYPE(&this->actor) != ENKUSA_TYPE_GRASS_2) { + Actor_LiftActor(&this->actor, globalCtx); + } + } + } + } + } +} + +void EnKusa_SetupLiftedUp(EnKusa* this) { + this->actionFunc = EnKusa_LiftedUp; + this->actor.room = -1; + this->actor.flags |= ACTOR_FLAG_10; +} + +void EnKusa_LiftedUp(EnKusa* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f pos; + s32 bgId; + + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actor.room = globalCtx->roomCtx.currRoom.num; + EnKusa_SetupFall(this); + this->actor.velocity.x = this->actor.speedXZ * Math_SinS(this->actor.world.rot.y); + this->actor.velocity.z = this->actor.speedXZ * Math_CosS(this->actor.world.rot.y); + this->actor.colChkInfo.mass = 80; + this->actor.gravity = -0.1f; + EnKusa_UpdateVelY(this); + EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.005f); + Actor_UpdatePos(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); + this->actor.gravity = -3.2f; + } else { + pos.x = this->actor.world.pos.x; + pos.y = this->actor.world.pos.y + 20.0f; + pos.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, &this->actor, &pos); + } +} + +void EnKusa_SetupFall(EnKusa* this) { + this->actionFunc = EnKusa_Fall; + rotSpeedXtarget = -0xBB8; + rotSpeedYtarget = (Rand_ZeroOne() - 0.5f) * 1600.0f; + rotSpeedX = 0; + rotSpeedY = 0; + this->timer = 0; +} + +void EnKusa_Fall(EnKusa* this, GlobalContext* globalCtx) { + s32 pad; + s32 wasHit; + Vec3f contactPos; + s32 i; + s16 angleOffset; + + wasHit = (this->collider.base.atFlags & AT_HIT) != 0; + + if (wasHit) { + this->collider.base.atFlags &= ~AT_HIT; + } + this->timer++; + if ((this->actor.bgCheckFlags & 0xB) || wasHit || (this->timer >= 100)) { + if (!(this->actor.bgCheckFlags & 0x20)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN); + } + EnKusa_SpawnFragments(this, globalCtx); + EnKusa_DropCollectible(this, globalCtx); + switch (GET_KUSA_TYPE(&this->actor)) { + case ENKUSA_TYPE_BUSH: + case ENKUSA_TYPE_GRASS: + Actor_MarkForDeath(&this->actor); + break; + + case ENKUSA_TYPE_REGROWING_GRASS: + EnKusa_SetupUprootedWaitRegrow(this); + this->actor.shape.shadowDraw = NULL; + break; + } + + } else { + if (this->actor.bgCheckFlags & 0x40) { + contactPos.y = this->actor.world.pos.y + this->actor.depthInWater; + for (angleOffset = 0, i = 0; i < 4; i++, angleOffset += 0x4000) { + contactPos.x = + (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 15.0f) + this->actor.world.pos.x; + contactPos.z = + (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 15.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &contactPos, NULL, NULL, 0, 190); + } + contactPos.x = this->actor.world.pos.x; + contactPos.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &contactPos, NULL, NULL, 0, 280); + EffectSsGRipple_Spawn(globalCtx, &contactPos, 300, 700, 0); + this->actor.terminalVelocity = -3.0f; + this->actor.velocity.x *= 0.1f; + this->actor.velocity.y *= 0.4f; + this->actor.velocity.z *= 0.1f; + this->actor.gravity *= 0.5f; + rotSpeedX >>= 1; + rotSpeedXtarget >>= 1; + rotSpeedY >>= 1; + rotSpeedYtarget >>= 1; + this->actor.bgCheckFlags &= ~0x40; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + } + EnKusa_UpdateVelY(this); + Math_StepToS(&rotSpeedX, rotSpeedXtarget, 500); + Math_StepToS(&rotSpeedY, rotSpeedYtarget, 170); + this->actor.shape.rot.x += rotSpeedX; + this->actor.shape.rot.y += rotSpeedY; + EnKusa_RandScaleVecToZero(&this->actor.velocity, 0.05f); + Actor_UpdatePos(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnKusa_SetupCut(EnKusa* this) { + switch (GET_KUSA_TYPE(&this->actor)) { + case ENKUSA_TYPE_GRASS: + case ENKUSA_TYPE_GRASS_2: + this->actionFunc = EnKusa_DoNothing; + break; + case ENKUSA_TYPE_REGROWING_GRASS: + this->actionFunc = EnKusa_CutWaitRegrow; + break; + } + this->timer = 0; +} + +void EnKusa_CutWaitRegrow(EnKusa* this, GlobalContext* globalCtx) { + this->timer++; + if (this->timer >= 120) { + EnKusa_SetupRegrow(this); + } +} + +void EnKusa_DoNothing(EnKusa* this, GlobalContext* globalCtx) { +} + +void EnKusa_SetupUprootedWaitRegrow(EnKusa* this) { + this->actor.world.pos.x = this->actor.home.pos.x; + this->actor.world.pos.y = this->actor.home.pos.y - 9.0f; + this->actor.world.pos.z = this->actor.home.pos.z; + EnKusa_SetScaleSmall(this); + this->timer = 0; + this->actor.shape.rot = this->actor.home.rot; + this->actionFunc = EnKusa_UprootedWaitRegrow; +} + +void EnKusa_UprootedWaitRegrow(EnKusa* this, GlobalContext* globalCtx) { + this->timer++; + if (this->timer > 120) { + if (Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.6f) && (this->timer >= 170)) { + EnKusa_SetupRegrow(this); + } + } +} + +void EnKusa_SetupRegrow(EnKusa* this) { + this->actionFunc = EnKusa_Regrow; + EnKusa_SetScaleSmall(this); + this->isCut = false; + this->actor.shape.rot = this->actor.home.rot; +} + +void EnKusa_Regrow(EnKusa* this, GlobalContext* globalCtx) { + s32 isFullyGrown = 1; + + isFullyGrown &= Math_StepToF(&this->actor.scale.y, 0.4f, 0.014f); + isFullyGrown &= Math_StepToF(&this->actor.scale.x, 0.4f, 0.011f); + this->actor.scale.z = this->actor.scale.x; + if (isFullyGrown) { + Actor_SetScale(&this->actor, 0.4f); + EnKusa_SetupInteract(this); + this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; + } +} + +void EnKusa_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnKusa* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->isCut) { + this->actor.shape.yOffset = -6.25f; + } else { + this->actor.shape.yOffset = 0.0f; + } + if ((kusaGameplayFrames != globalCtx->gameplayFrames) && (globalCtx->roomCtx.currRoom.unk3 == 0)) { + EnKusa_Sway(); + kusaGameplayFrames = globalCtx->gameplayFrames; + } +} + +void EnKusa_DrawBush(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnKusa* this = THIS; + + if ((this->actor.projectedPos.z <= 1200.0f) || ((this->isInWater & 1) && (this->actor.projectedPos.z < 1300.0f))) { + + if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actionFunc == EnKusa_WaitForInteract) && + (this->actor.projectedPos.z > -150.0f) && (this->actor.projectedPos.z < 400.0f)) { + EnKusa_ApplySway(&D_80936AD8[this->kusaMtxIdx]); + } + + Gfx_DrawDListOpa(globalCtx, gKusaBushType1); + + } else if (this->actor.projectedPos.z < 1300.0f) { + s32 alpha; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + alpha = (1300.0f - this->actor.projectedPos.z) * 2.55f; + 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, alpha); + gSPDisplayList(POLY_XLU_DISP++, gKusaBushType2); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnKusa_DrawGrass(Actor* thisx, GlobalContext* globalCtx) { + EnKusa* this = THIS; + + if (this->isCut) { + Gfx_DrawDListOpa(globalCtx, gKusaStump); + } else { + if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actionFunc == EnKusa_WaitForInteract)) { + if ((this->actor.projectedPos.z > -150.0f) && (this->actor.projectedPos.z < 400.0f)) { + EnKusa_ApplySway(&D_80936AD8[this->kusaMtxIdx]); + } + } + Gfx_DrawDListOpa(globalCtx, gKusaSprout); + } +} 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..2f0d29dd9 100644 --- a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h +++ b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h @@ -7,12 +7,33 @@ struct EnKusa; typedef void (*EnKusaActionFunc)(struct EnKusa*, GlobalContext*); +typedef enum { + /* 0 */ ENKUSA_TYPE_BUSH, + /* 1 */ ENKUSA_TYPE_REGROWING_GRASS, + /* 2 */ ENKUSA_TYPE_GRASS, + /* 3 */ ENKUSA_TYPE_GRASS_2 +} EnKusaType; + typedef struct EnKusa { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnKusaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x54]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnKusaActionFunc actionFunc; + /* 0x148 */ ColliderCylinder collider; + /* 0x194 */ u8 timer; + /* 0x195 */ s8 objIndex; + /* 0x196 */ s8 kusaMtxIdx; + /* 0x197 */ u8 isCut; + /* 0x198 */ u8 isInWater; } EnKusa; // size = 0x19C extern const ActorInit En_Kusa_InitVars; +#define KUSA_GET_COLLECTIBLE_ID(thisx) ((((thisx)->params >> 8) & 0x7F)) +#define KUSA_GET_RAND_COLLECTIBLE_ID(thisx) (((thisx)->params >> 8) & 0xF) +#define KUSA_SHOULD_SPAWN_BUGS(thisx) (((thisx)->params >> 0x4) & 1) +#define KUSA_GET_PARAMS_0C(thisx) (((thisx)->params >> 0xC) & 0x1) +#define KUSA_GET_PARAMS_3F(thisx) (((thisx)->params >> 0x2) & 0x3F) + + +#define GET_KUSA_TYPE(thisx)((thisx)->params & 0x3) + #endif // Z_EN_KUSA_H 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 cb6fe757c..6ba532cef 100644 --- a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c +++ b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c @@ -1,6 +1,15 @@ -#include "z_en_kusa2.h" +/* + * File: z_en_kusa2.c + * Overlay: ovl_En_Kusa2 + * Description: Keaton grass + */ -#define FLAGS 0x00800010 +#include "prevent_bss_reordering.h" +#include "z_en_kusa2.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnKusa2*)thisx) @@ -9,18 +18,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, @@ -33,146 +66,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_GetCurrent(); + 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 & ACTOR_FLAG_40) { + 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); + SoundSource_PlaySfxAtFixedWorldPos(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 & AC_HIT) { + s32 pad; + + func_80A5CF44(this); + func_80A5BD14(this, globalCtx, (this->collider.info.acHitInfo->toucher.dmgFlags & 0x1000000) ? 1 : 0); + SoundSource_PlaySfxAtFixedWorldPos(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(terminalVelocity, -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 |= ACTOR_FLAG_20; + 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)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT); + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + 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 = ActorShadow_DrawCircle; + 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; + Actor_PlaySfxAtPos(&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) { + Actor_LiftActor(&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_MoveWithGravity(&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) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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); + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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); + SoundSource_PlaySfxAtFixedWorldPos(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_MoveWithGravity(&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.terminalVelocity = -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_MoveWithGravity(&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[] = { + gKakeraLeafTip, + gKakeraLeafMiddle, + }; + 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_SetTranslateRotateYXZ(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++, gKusaBushType2); + + 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); + } + Gfx_DrawDListOpa(globalCtx, gKusaBushType1); + } 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_SetTranslateRotateYXZ(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); + Gfx_DrawDListOpa(globalCtx, gKusaBushType1); +} + +void func_80A5EA48(Actor* thisx, GlobalContext* globalCtx) { + EnKusa2* this = THIS; + + if (this->unk_1CF == 0xFF) { + Gfx_DrawDListOpa(globalCtx, gKusaBushType1); + } 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_Lift_Nuts/z_en_lift_nuts.c b/src/overlays/actors/ovl_En_Lift_Nuts/z_en_lift_nuts.c index b35b39df0..8669a3544 100644 --- a/src/overlays/actors/ovl_En_Lift_Nuts/z_en_lift_nuts.c +++ b/src/overlays/actors/ovl_En_Lift_Nuts/z_en_lift_nuts.c @@ -1,6 +1,12 @@ +/* + * File: z_en_lift_nuts.c + * Overlay: ovl_En_Lift_Nuts + * Description: Deku Scrub Playground - Employee + */ + #include "z_en_lift_nuts.h" -#define FLAGS 0x02000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnLiftNuts*)thisx) diff --git a/src/overlays/actors/ovl_En_Light/z_en_light.c b/src/overlays/actors/ovl_En_Light/z_en_light.c index ba02662ae..9dc919e0e 100644 --- a/src/overlays/actors/ovl_En_Light/z_en_light.c +++ b/src/overlays/actors/ovl_En_Light/z_en_light.c @@ -1,4 +1,11 @@ +/* + * File: z_en_light.c + * Overlay: ovl_En_Light + * Description: Deku Shrine - Flames of Varying Colours + */ + #include "z_en_light.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -9,7 +16,8 @@ void EnLight_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnLight_Update(Actor* thisx, GlobalContext* globalCtx); void EnLight_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80865F38(Actor* thisx, GlobalContext* globalCtx); + const ActorInit En_Light_InitVars = { ACTOR_EN_LIGHT, ACTORCAT_ITEMACTION, @@ -22,16 +30,173 @@ const ActorInit En_Light_InitVars = { (ActorFunc)EnLight_Draw, }; -#endif +typedef struct { + /* 0x00 */ Color_RGBA8 unk_00; + /* 0x04 */ Color_RGB8 unk_04; + /* 0x07 */ u8 unk_07; +} EnLightStruct; // size = 0x8 -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/EnLight_Init.s") +EnLightStruct D_808666D0[] = { + { { 255, 200, 0, 255 }, { 255, 0, 0 }, 75 }, { { 255, 235, 175, 255 }, { 255, 0, 0 }, 75 }, + { { 0, 170, 255, 255 }, { 0, 0, 255 }, 75 }, { { 170, 255, 0, 255 }, { 0, 150, 0 }, 75 }, + { { 255, 200, 0, 255 }, { 255, 0, 0 }, 40 }, { { 255, 200, 0, 255 }, { 255, 0, 0 }, 75 }, + { { 170, 255, 0, 255 }, { 0, 150, 0 }, 75 }, { { 0, 170, 255, 255 }, { 0, 0, 255 }, 75 }, + { { 255, 0, 170, 255 }, { 200, 0, 0 }, 75 }, { { 255, 255, 170, 255 }, { 255, 50, 0 }, 75 }, + { { 255, 255, 170, 255 }, { 255, 255, 0 }, 75 }, { { 255, 255, 170, 255 }, { 100, 255, 0 }, 75 }, + { { 255, 170, 255, 255 }, { 255, 0, 100 }, 75 }, { { 255, 170, 255, 255 }, { 100, 0, 255 }, 75 }, + { { 170, 255, 255, 255 }, { 0, 0, 255 }, 75 }, { { 170, 255, 255, 255 }, { 0, 150, 255 }, 75 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/EnLight_Destroy.s") +void EnLight_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnLight* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/func_80865BF8.s") + if (!ENLIGHT_GET_4000(&this->actor)) { + if ((gSaveContext.gameMode == 3) || ENLIGHT_GET_2000(&this->actor)) { + Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, + ((this->actor.params < 0) ? 1 : 40) + (s32)this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 180, -1); + } else { + Lights_PointGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, + ((this->actor.params < 0) ? 1 : 40) + (s32)this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 180, -1); + } + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/EnLight_Update.s") + Actor_SetScale(&this->actor, D_808666D0[ENLIGHT_GET_F(&this->actor)].unk_07 * 0.0001f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/func_80865F38.s") + this->unk_144 = (s8)(Rand_ZeroOne() * 255.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Light/EnLight_Draw.s") + if (ENLIGHT_GET_800(&this->actor)) { + this->actor.update = func_80865F38; + if (ENLIGHT_GET_1000(&this->actor) && Flags_GetSwitch(globalCtx, ENLIGHT_SWITCHFLAG(&this->actor))) { + Actor_SetScale(&this->actor, 0.0f); + } + } else if (ENLIGHT_GET_2000(&this->actor)) { + this->actor.draw = NULL; + } +} + +void EnLight_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnLight* this = THIS; + + if (!ENLIGHT_GET_4000(&this->actor)) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); + } +} + +void func_80865BF8(EnLight* this, GlobalContext* globalCtx) { + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); + + if (this->actor.parent != NULL) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.parent->world.pos); + this->actor.world.pos.y += 17.0f; + } + + this->unk_144++; +} + +void EnLight_Update(Actor* thisx, GlobalContext* globalCtx) { + EnLight* this = THIS; + + if (!ENLIGHT_GET_4000(&this->actor)) { + EnLightStruct* sp28 = &D_808666D0[ENLIGHT_GET_F(&this->actor)]; + f32 temp_f2 = (Rand_ZeroOne() * 0.5f) + 0.5f; + s32 radius = (this->actor.params < 0) ? 100 : ENLIGHT_GET_2000(&this->actor) ? 730 : 300; + + Lights_PointSetColorAndRadius(&this->lightInfo, (u8)(sp28->unk_00.r * temp_f2), (u8)(sp28->unk_00.g * temp_f2), + (u8)(sp28->unk_00.b * temp_f2), radius); + } + + func_80865BF8(this, globalCtx); + + if ((this->actor.params >= 0) && !ENLIGHT_GET_4000(&this->actor)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_TORCH - SFX_FLAG); + } +} + +void func_80865F38(Actor* thisx, GlobalContext* globalCtx) { + EnLight* this = THIS; + EnLightStruct* sp38 = &D_808666D0[ENLIGHT_GET_F(&this->actor)]; + f32 temp_f2; + f32 sp30 = this->actor.scale.x / (sp38->unk_07 * 0.0001f); + s32 sp2C = false; + + if (ENLIGHT_GET_1000(&this->actor)) { + if (Flags_GetSwitch(globalCtx, ENLIGHT_SWITCHFLAG(&this->actor))) { + Math_StepToF(&sp30, 1.0f, 0.05f); + sp2C = true; + } else { + if (sp30 < 0.1f) { + Actor_SetScale(&this->actor, 0.0f); + sp30 = 0.0f; + } + Math_StepToF(&sp30, 0.0f, 0.05f); + } + } else if (Flags_GetSwitch(globalCtx, ENLIGHT_SWITCHFLAG(&this->actor))) { + if (sp30 < 0.1f) { + Actor_SetScale(&this->actor, 0.0f); + sp30 = 0.0f; + } + Math_StepToF(&sp30, 0.0f, 0.05f); + } else { + Math_StepToF(&sp30, 1.0f, 0.05f); + sp2C = true; + } + + Actor_SetScale(&this->actor, sp38->unk_07 * 0.0001f * sp30); + + if (!ENLIGHT_GET_4000(&this->actor)) { + temp_f2 = (Rand_ZeroOne() * 0.5f) + 0.5f; + Lights_PointSetColorAndRadius(&this->lightInfo, (u8)(sp38->unk_00.r * temp_f2), (u8)(sp38->unk_00.g * temp_f2), + (u8)(sp38->unk_00.b * temp_f2), 300.0f * sp30); + } + + func_80865BF8(this, globalCtx); + + if ((this->actor.params >= 0) && (sp2C == true)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_TORCH - SFX_FLAG); + } +} + +void EnLight_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnLight* this = THIS; + EnLightStruct* sp6C = &D_808666D0[ENLIGHT_GET_F(&this->actor)]; + Gfx* sp68; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + if (this->actor.params >= 0) { + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (this->unk_144 * -20) & 0x1FF, + 0x20, 0x80)); + sp68 = gGameplayKeepDrawFlameDL; + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, sp6C->unk_00.r, sp6C->unk_00.g, sp6C->unk_00.b, sp6C->unk_00.a); + gDPSetEnvColor(POLY_XLU_DISP++, sp6C->unk_04.r, sp6C->unk_04.g, sp6C->unk_04.b, 0); + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x10, 0x20, 1, (this->unk_144 * 2) & 0x3F, + (this->unk_144 * -6) & 0x7F, 0x10, 0x20)); + sp68 = gameplay_keep_DL_01ACF0; + gDPSetPrimColor(POLY_XLU_DISP++, 0xC0, 0xC0, 255, 200, 0, 0); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + } + + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - this->actor.shape.rot.y), + MTXMODE_APPLY); + + if (ENLIGHT_GET_1(&this->actor)) { + Matrix_RotateYF(M_PI, MTXMODE_APPLY); + } + + 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); + gSPDisplayList(POLY_XLU_DISP++, sp68); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Light/z_en_light.h b/src/overlays/actors/ovl_En_Light/z_en_light.h index f1aff8de9..b17f55fd7 100644 --- a/src/overlays/actors/ovl_En_Light/z_en_light.h +++ b/src/overlays/actors/ovl_En_Light/z_en_light.h @@ -5,9 +5,19 @@ struct EnLight; +#define ENLIGHT_GET_1(thisx) ((thisx)->params & 1) +#define ENLIGHT_GET_F(thisx) ((thisx)->params & 0xF) +#define ENLIGHT_GET_800(thisx) ((thisx)->params & 0x800) +#define ENLIGHT_SWITCHFLAG(thisx) (((thisx)->params & 0x7F0) >> 4) +#define ENLIGHT_GET_1000(thisx) ((thisx)->params & 0x1000) +#define ENLIGHT_GET_2000(thisx) ((thisx)->params & 0x2000) +#define ENLIGHT_GET_4000(thisx) ((thisx)->params & 0x4000) + typedef struct EnLight { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x144 */ u8 unk_144; + /* 0x148 */ LightNode* lightNode; + /* 0x14C */ LightInfo lightInfo; } EnLight; // size = 0x15C extern const ActorInit En_Light_InitVars; diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c index 915164eed..774acf118 100644 --- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c +++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.c @@ -1,6 +1,12 @@ +/* + * File: z_en_look_nuts.c + * Overlay: ovl_En_Look_Nuts + * Description: Deku Palace - Patrolling Deku Guard + */ + #include "z_en_look_nuts.h" -#define FLAGS 0x80000000 +#define FLAGS (ACTOR_FLAG_80000000) #define THIS ((EnLookNuts*)thisx) @@ -9,7 +15,14 @@ void EnLookNuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnLookNuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnLookNuts_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnLookNuts_SetupPatrol(EnLookNuts* this); +void EnLookNuts_Patrol(EnLookNuts* this, GlobalContext* globalCtx); +void EnLookNuts_SetupStandAndWait(EnLookNuts* this); +void EnLookNuts_StandAndWait(EnLookNuts* this, GlobalContext* globalCtx); +void EnLookNuts_RunToPlayer(EnLookNuts* this, GlobalContext* globalCtx); +void EnLookNuts_SetupSendPlayerToSpawn(EnLookNuts* this); +void EnLookNuts_SendPlayerToSpawn(EnLookNuts* this, GlobalContext* globalCtx); + const ActorInit En_Look_Nuts_InitVars = { ACTOR_EN_LOOK_NUTS, ACTORCAT_NPC, @@ -22,15 +35,29 @@ const ActorInit En_Look_Nuts_InitVars = { (ActorFunc)EnLookNuts_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A68600 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 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_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 20, 50, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80A68630 = { +s32 D_80A6862C = 0; + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0xF), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(1, 0xF), @@ -65,34 +92,304 @@ static DamageTable D_80A68630 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -#endif +typedef enum { + /* 0x01 */ PALACE_GUARD_PATROLLING, + /* 0x01 */ PALACE_GUARD_WAITING, + /* 0x02 */ PALACE_GUARD_RUNNING_TO_PLAYER, + /* 0x03 */ PALACE_GUARD_CAUGHT_PLAYER +} PalaceGuardState; -extern ColliderCylinderInit D_80A68600; -extern DamageTable D_80A68630; +void EnLookNuts_Init(Actor* thisx, GlobalContext* globalCtx) { + EnLookNuts* this = THIS; -extern UNK_TYPE D_06000430; -extern UNK_TYPE D_06002B6C; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuPalaceGuardSkel, &gDekuPalaceGuardDigAnim, this->jointTable, + this->morphTable, DEKU_PALACE_GUARD_LIMB_MAX); + Actor_SetScale(&this->actor, 0.01f); + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.targetMode = 1; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.flags |= ACTOR_FLAG_8000000; + this->pathLocation = LOOKNUTS_GET_PATROL_LOCATION(&this->actor); + this->switchFlag = LOOKNUTS_GET_SCENE_FLAG(&this->actor); + this->spawnIndex = LOOKNUTS_GET_SPAWN_INDEX(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/EnLookNuts_Init.s") + if (this->switchFlag == 0x7F) { + this->switchFlag = -1; + } + if ((this->switchFlag >= 0) && (Flags_GetSwitch(globalCtx, this->switchFlag))) { + Actor_MarkForDeath(&this->actor); + return; + } + if (this->pathLocation == 0x1F) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/EnLookNuts_Destroy.s") + this->state = PALACE_GUARD_PATROLLING; + EnLookNuts_SetupPatrol(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67A34.s") +void EnLookNuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnLookNuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67AA8.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67C48.s") +void EnLookNuts_SetupPatrol(EnLookNuts* this) { + Animation_Change(&this->skelAnime, &gDekuPalaceGuardWalkAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuPalaceGuardWalkAnim), 0, -10.0f); + this->state = PALACE_GUARD_PATROLLING; + this->actionFunc = EnLookNuts_Patrol; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67D0C.s") +void EnLookNuts_Patrol(EnLookNuts* this, GlobalContext* globalCtx) { + f32 sp34 = 0.0f; + f32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67F30.s") + SkelAnime_Update(&this->skelAnime); + if (Play_InCsMode(globalCtx)) { + this->actor.speedXZ = 0.0f; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A67FC4.s") + this->actor.speedXZ = 2.0f; + if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A68080.s") + if (D_80A6862C != 0) { + Math_ApproachZeroF(&this->actor.speedXZ, 0.3f, 1.0f); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/func_80A680FC.s") + this->path = SubS_GetPathByIndex(globalCtx, this->pathLocation, 0x1F); + if (this->path != NULL) { + sp34 = SubS_GetDistSqAndOrientPath(this->path, this->currentPathIndex, &this->actor.world.pos, &sp30); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/EnLookNuts_Update.s") + //! @bug sp30 is uninitialised if path == NULL. Fix by enclosing everything in the path NULL check. + if (sp30 < 10.0f) { + if (this->path != NULL) { + this->currentPathIndex++; + if (this->currentPathIndex >= this->path->count) { + this->currentPathIndex = 0; + } + if (Rand_ZeroOne() < 0.6f) { + EnLookNuts_SetupStandAndWait(this); + return; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Look_Nuts/EnLookNuts_Draw.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, sp34, 1, 0x1388, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void EnLookNuts_SetupStandAndWait(EnLookNuts* this) { + Animation_Change(&this->skelAnime, &gDekuPalaceGuardWalkAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuPalaceGuardWalkAnim), 2, -10.0f); + this->waitTimer = Rand_S16Offset(1, 3); + this->headRotTarget.y = 10000.0f; + + if (Rand_ZeroOne() < 0.5f) { + this->headRotTarget.y = -10000.0f; + } + this->eventTimer = 10; + this->state = PALACE_GUARD_WAITING; + this->actionFunc = EnLookNuts_StandAndWait; +} + +// Patrol Guards will stand in place and wait for a maximum of ~12 frames. +void EnLookNuts_StandAndWait(EnLookNuts* this, GlobalContext* globalCtx) { + s16 randOffset; + + SkelAnime_Update(&this->skelAnime); + Math_ApproachZeroF(&this->actor.speedXZ, 0.3f, 1.0f); + if (!Play_InCsMode(globalCtx) && (D_80A6862C == 0) && (this->eventTimer == 0)) { + this->eventTimer = 10; + switch (this->waitTimer) { + case 0: + case 1: + case 2: + case 3: + case 4: + this->waitTimer++; + this->headRotTarget.y *= -1.0f; + break; + case 5: + this->headRotTarget.y = 0.0f; + randOffset = Rand_S16Offset(1, 2); + this->eventTimer = 0; + this->waitTimer += randOffset; + break; + case 6: + if (fabsf(this->headRotTarget.y - this->headRotation.y) < 10.0f) { + this->waitTimer = 10; + this->headRotTarget.x = 4000.0f; + this->eventTimer = 5; + } + break; + case 7: + if (fabsf(this->headRotTarget.y - this->headRotation.y) < 10.0f) { + this->headRotTarget.z = 4000.0f; + this->waitTimer++; + } + break; + case 8: + this->waitTimer = 10; + this->eventTimer = 20; + this->headRotTarget.z = -8000.0f; + break; + case 10: + Math_Vec3f_Copy(&this->headRotTarget, &gZeroVec3f); + this->waitTimer = 11; + break; + case 11: + if ((fabsf(this->headRotation.x) < 30.0f) && (fabsf(this->headRotation.y) < 30.0f) && + (fabsf(this->headRotation.z) < 30.0f)) { + this->waitTimer = 12; + } + break; + } + if (this->waitTimer == 12) { + this->waitTimer = 0; + EnLookNuts_SetupPatrol(this); + } + } +} + +void EnLookNuts_DetectedPlayer(EnLookNuts* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gDekuPalaceGuardWalkAnim, 2.0f, 0.0f, + Animation_GetLastFrame(&gDekuPalaceGuardWalkAnim), 0, -10.0f); + this->state = PALACE_GUARD_RUNNING_TO_PLAYER; + this->eventTimer = 300; + Message_StartTextbox(globalCtx, 0x833, &this->actor); + this->actionFunc = EnLookNuts_RunToPlayer; +} + +void EnLookNuts_RunToPlayer(EnLookNuts* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 1.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_WALK); + } + + this->actor.speedXZ = 4.0f; + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); + if ((this->actor.xzDistToPlayer < 70.0f) || (this->eventTimer == 0)) { + this->actor.speedXZ = 0.0f; + EnLookNuts_SetupSendPlayerToSpawn(this); + } +} + +void EnLookNuts_SetupSendPlayerToSpawn(EnLookNuts* this) { + Animation_Change(&this->skelAnime, &gDekuPalaceGuardWalkAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuPalaceGuardWalkAnim), 2, -10.0f); + this->state = PALACE_GUARD_CAUGHT_PLAYER; + this->actionFunc = EnLookNuts_SendPlayerToSpawn; +} + +void EnLookNuts_SendPlayerToSpawn(EnLookNuts* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + globalCtx->nextEntranceIndex = Entrance_CreateIndexFromSpawn(this->spawnIndex); + gSaveContext.nextCutsceneIndex = 0; + Scene_SetExitFade(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + gSaveContext.save.weekEventReg[17] |= 4; + } +} + +static Vec3f effectVecInitialize = { 0.0f, 0.0f, 0.0f }; + +void EnLookNuts_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnLookNuts* this = THIS; + Vec3f effectVelOffset; + Vec3f effectPos; + Vec3f effectVel; + + if (this->blinkTimer == 0) { + this->eyeState++; + if (this->eyeState >= 3) { + this->eyeState = 0; + this->blinkTimer = (s16)Rand_ZeroFloat(60.0f) + 20; + } + } + this->actionFunc(this, globalCtx); + if (this->blinkTimer != 0) { + this->blinkTimer--; + } + if (this->eventTimer != 0) { + this->eventTimer--; + } + Actor_MoveWithGravity(&this->actor); + if (D_80A6862C == 0) { + if ((this->state < 2) && (this->actor.xzDistToPlayer < 320.0f) && (this->actor.playerHeightRel < 80.0f)) { + effectVelOffset = effectVecInitialize; + Math_Vec3f_Copy(&effectPos, &this->actor.world.pos); + effectPos.x += Math_SinS((this->actor.world.rot.y + (s16)this->headRotation.y)) * 10.0f; + effectPos.y += 30.0f; + effectPos.z += Math_CosS((this->actor.world.rot.y + (s16)this->headRotation.y)) * 10.0f; + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + effectVelOffset.z = 20.0f; + Matrix_MultVec3f(&effectVelOffset, &effectVel); + Matrix_Pop(); + if (!this->isPlayerDetected) { + s16 drawFlag = 1; + if (gSaveContext.save.isNight) { + drawFlag = 0; + } + if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) { + EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, 50, + &this->isPlayerDetected, drawFlag); + } + } + + if ((this->isPlayerDetected == true) || (this->actor.xzDistToPlayer < 20.0f)) { + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags3 & 0x100) && !Play_InCsMode(globalCtx)) { + Math_Vec3f_Copy(&this->headRotTarget, &gZeroVec3f); + this->state = PALACE_GUARD_RUNNING_TO_PLAYER; + play_sound(NA_SE_SY_FOUND); + func_800B7298(globalCtx, &this->actor, 0x1A); + D_80A6862C = 1; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_10); + this->actor.gravity = 0.0f; + EnLookNuts_DetectedPlayer(this, globalCtx); + } else { + this->isPlayerDetected = false; + } + } + } + Math_ApproachF(&this->headRotation.x, this->headRotTarget.x, 1.0f, 3000.0f); + Math_ApproachF(&this->headRotation.y, this->headRotTarget.y, 1.0f, 6000.0f); + Math_ApproachF(&this->headRotation.z, this->headRotTarget.z, 1.0f, 2000.0f); + this->actor.shape.rot.y = this->actor.world.rot.y; + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +static TexturePtr sEyeTextures[] = { + gDekuPalaceGuardEyeOpenTex, + gDekuPalaceGuardEyeHalfTex, + gDekuPalaceGuardEyeClosedTex, +}; + +void EnLookNuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnLookNuts* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeState])); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h index cb011be7a..e6eb6597a 100644 --- a/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h +++ b/src/overlays/actors/ovl_En_Look_Nuts/z_en_look_nuts.h @@ -2,16 +2,37 @@ #define Z_EN_LOOK_NUTS_H #include "global.h" +#include "objects/object_dnk/object_dnk.h" struct EnLookNuts; typedef void (*EnLookNutsActionFunc)(struct EnLookNuts*, GlobalContext*); +#define LOOKNUTS_GET_SPAWN_INDEX(thisx) (((thisx)->params >> 0xC) & 0xF) +#define LOOKNUTS_GET_SCENE_FLAG(thisx) ((thisx)->params & 0x7F) +#define LOOKNUTS_GET_PATROL_LOCATION(thisx) (((thisx)->params >> 0x7) & 0x1F) + typedef struct EnLookNuts { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC8]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[DEKU_PALACE_GUARD_LIMB_MAX]; + /* 0x01CA */ Vec3s morphTable[DEKU_PALACE_GUARD_LIMB_MAX]; /* 0x020C */ EnLookNutsActionFunc actionFunc; - /* 0x0210 */ char unk_210[0x80]; + /* 0x0210 */ Path *path; + /* 0x0214 */ s16 currentPathIndex; // Index for the point where the deku guard is in its path + /* 0x0216 */ s16 eyeState; + /* 0x0218 */ s16 blinkTimer; + /* 0x021A */ s16 eventTimer; // Timer to trigger when another event within the actor will happen + /* 0x021C */ s16 state; + /* 0x021E */ s16 switchFlag; + /* 0x0220 */ s16 pathLocation; // Determines path that a guard will patrol + /* 0x0222 */ s16 isPlayerDetected; + /* 0x0224 */ s16 waitTimer; // Timer for how long the deku guard will take a break for + /* 0x0226 */ s16 spawnIndex; + /* 0x0228 */ UNK_TYPE4 pad228; // Unused necessary padding + /* 0x022C */ Vec3f headRotation; + /* 0x0238 */ Vec3f headRotTarget; // Target value for head rotation + /* 0x0244 */ ColliderCylinder collider; } EnLookNuts; // size = 0x290 extern const ActorInit En_Look_Nuts_InitVars; diff --git a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c index 117c19ee5..4da43c3cf 100644 --- a/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c +++ b/src/overlays/actors/ovl_En_M_Fire1/z_en_m_fire1.c @@ -1,3 +1,9 @@ +/* + * File: z_en_m_fire1.c + * Overlay: ovl_En_M_Fire1 + * Description: Deku Nut Effect + */ + #include "z_en_m_fire1.h" #define FLAGS 0x00000000 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 03140ab1f..a7f83a42c 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,6 +1,12 @@ +/* + * File: z_en_m_thunder.c + * Overlay: ovl_En_M_Thunder + * Description: Spin attack and sword beams + */ + #include "z_en_m_thunder.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnMThunder*)thisx) diff --git a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c index e2ff014c9..226059ae2 100644 --- a/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c +++ b/src/overlays/actors/ovl_En_Ma4/z_en_ma4.c @@ -5,8 +5,9 @@ */ #include "z_en_ma4.h" +#include "objects/object_ma1/object_ma1.h" -#define FLAGS 0x02000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((EnMa4*)thisx) @@ -54,35 +55,6 @@ typedef enum { /* 3 */ MA4_STATE_AFTERDESCRIBETHEMCS, } EnMa4State; -extern FlexSkeletonHeader D_06013928; - -extern AnimationHeader D_06009E58; -extern AnimationHeader D_06002A8C; -extern AnimationHeader D_06018948; -extern AnimationHeader D_0601B76C; -extern AnimationHeader D_06007328; -extern AnimationHeader D_06014088; -extern AnimationHeader D_06015B7C; -extern AnimationHeader D_06007D98; -extern AnimationHeader D_0600852C; -extern AnimationHeader D_06008F6C; - -extern u64 D_0600FFC8[]; -extern u64 D_060107C8[]; -extern u64 D_06010FC8[]; -extern u64 D_060117C8[]; -extern u64 D_06011FC8[]; - -extern u64 D_060127C8[]; -extern u64 D_06012BC8[]; -extern u64 D_06012FC8[]; -extern u64 D_060133C8[]; - -extern Gfx D_060003B0[]; - -// Box -extern Gfx D_06000A20[]; - const ActorInit En_Ma4_InitVars = { ACTOR_EN_MA4, ACTORCAT_NPC, @@ -117,15 +89,15 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit2 D_80AC00DC = { 0, 0, 0, 0, MASS_IMMOVABLE }; -static void* sEyeTextures[] = { - D_0600FFC8, D_060107C8, D_06010FC8, D_060117C8, D_06011FC8, +static TexturePtr sEyeTextures[] = { + object_ma1_Tex_00FFC8, object_ma1_Tex_0107C8, object_ma1_Tex_010FC8, object_ma1_Tex_0117C8, object_ma1_Tex_011FC8, }; -static void* sMouthTextures[] = { - D_060127C8, - D_06012BC8, - D_06012FC8, - D_060133C8, +static TexturePtr sMouthTextures[] = { + object_ma1_Tex_0127C8, + object_ma1_Tex_012BC8, + object_ma1_Tex_012FC8, + object_ma1_Tex_0133C8, }; void EnMa4_UpdateEyes(EnMa4* this) { @@ -140,32 +112,42 @@ void EnMa4_UpdateEyes(EnMa4* this) { } } -static struct_80B8E1A8 sAnimationInfo[] = { - { &D_06009E58, 1.0f, 0, 0.0f }, { &D_06009E58, 1.0f, 0, -6.0f }, // Idle anim - { &D_06002A8C, 1.0f, 0, 0.0f }, { &D_06002A8C, 1.0f, 0, -6.0f }, // Looking around anim - { &D_06018948, 1.0f, 2, 0.0f }, { &D_06018948, 1.0f, 2, -6.0f }, // Starts holding hands anim - { &D_0601B76C, 1.0f, 0, 0.0f }, { &D_0601B76C, 1.0f, 0, -6.0f }, // Holnding hands anim - { &D_06007328, 1.0f, 0, 0.0f }, { &D_06007328, 1.0f, 0, -6.0f }, // Walking anim - { &D_06014088, 1.0f, 0, 0.0f }, { &D_06014088, 1.0f, 0, -6.0f }, // - { &D_06015B7C, 1.0f, 2, 0.0f }, { &D_06015B7C, 1.0f, 2, -6.0f }, // Shoot arrow anim - { &D_06007D98, 1.0f, 0, 0.0f }, { &D_06007D98, 1.0f, 0, -6.0f }, // Sitting anim - { &D_0600852C, 1.0f, 0, 0.0f }, { &D_0600852C, 1.0f, 0, -6.0f }, // Sitting traumatized anim - { &D_06008F6C, 1.0f, 0, 0.0f }, { &D_06008F6C, 1.0f, 0, -6.0f }, // Sitting sad anim +static AnimationSpeedInfo sAnimationInfo[] = { + { &object_ma1_Anim_009E58, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_009E58, 1.0f, ANIMMODE_LOOP, -6.0f }, // Idle anim + { &object_ma1_Anim_002A8C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_002A8C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Looking around anim + { &object_ma1_Anim_018948, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_ma1_Anim_018948, 1.0f, ANIMMODE_ONCE, -6.0f }, // Starts holding hands anim + { &object_ma1_Anim_01B76C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_01B76C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Holnding hands anim + { &object_ma1_Anim_007328, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_007328, 1.0f, ANIMMODE_LOOP, -6.0f }, // Walking anim + { &object_ma1_Anim_014088, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_014088, 1.0f, ANIMMODE_LOOP, -6.0f }, // + { &object_ma1_Anim_015B7C, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_ma1_Anim_015B7C, 1.0f, ANIMMODE_ONCE, -6.0f }, // Shoot arrow anim + { &object_ma1_Anim_007D98, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_007D98, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting anim + { &object_ma1_Anim_00852C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_00852C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting traumatized anim + { &object_ma1_Anim_008F6C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_008F6C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting sad anim }; void EnMa4_ChangeAnim(EnMa4* this, s32 index) { - Animation_Change(&this->skelAnime, sAnimationInfo[index].animationSeg, 1.0f, 0.0f, - Animation_GetLastFrame(sAnimationInfo[index].animationSeg), sAnimationInfo[index].mode, - sAnimationInfo[index].transitionRate); + Animation_Change(&this->skelAnime, sAnimationInfo[index].animation, 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationInfo[index].animation), sAnimationInfo[index].mode, + sAnimationInfo[index].morphFrames); } void func_80ABDD9C(EnMa4* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 flag; - if (this->unk_1D8.unk_00 == 0 && - ((this->skelAnime.animation == &D_06007328) || (this->skelAnime.animation == &D_06002A8C) || - (this->skelAnime.animation == &D_06015B7C))) { + if (this->unk_1D8.unk_00 == 0 && ((this->skelAnime.animation == &object_ma1_Anim_007328) || + (this->skelAnime.animation == &object_ma1_Anim_002A8C) || + (this->skelAnime.animation == &object_ma1_Anim_015B7C))) { flag = 1; } else { flag = (this->type == MA4_TYPE_ALIENS_WON && this->actionFunc != EnMa4_DialogueHandler) ? 1 : 0; @@ -200,8 +182,8 @@ void EnMa4_Init(Actor* thisx, GlobalContext* globalCtx) { EnMa4* this = THIS; s32 pad; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 18.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, NULL, this->jointTable, this->morphTable, + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, NULL, this->jointTable, this->morphTable, MA1_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); @@ -220,24 +202,24 @@ void EnMa4_Init(Actor* thisx, GlobalContext* globalCtx) { if (CURRENT_DAY == 1) { this->type = MA4_TYPE_DAY1; - } else if (gSaveContext.weekEventReg[0x16] & 1) { // Aliens defeated + } else if (gSaveContext.save.weekEventReg[22] & 1) { // Aliens defeated this->type = MA4_TYPE_ALIENS_DEFEATED; } else { this->type = MA4_TYPE_ALIENS_WON; this->hasBow = false; } - if (func_800EE1D8(globalCtx) != 0) { // if (sceneSetupIndex != 0) + if (Cutscene_GetSceneSetupIndex(globalCtx) != 0) { // if (sceneSetupIndex != 0) EnMa4_ChangeAnim(this, 0); this->state = MA4_STATE_HORSEBACKGAME; EnMa4_InitHorsebackGame(this, globalCtx); } else { EnMa4_InitPath(this, globalCtx); - if (gSaveContext.entranceIndex == 0x6410) { + if (gSaveContext.save.entranceIndex == 0x6410) { EnMa4_ChangeAnim(this, 0); this->state = MA4_STATE_AFTERHORSEBACKGAME; - } else if (gSaveContext.entranceIndex == 0x64A0) { + } else if (gSaveContext.save.entranceIndex == 0x64A0) { EnMa4_ChangeAnim(this, 0); this->state = MA4_STATE_AFTERDESCRIBETHEMCS; } else { @@ -258,7 +240,7 @@ void EnMa4_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnMa4* this = THIS; Collider_DestroyCylinder(globalCtx, &this->collider); - gSaveContext.weekEventReg[0x8] &= (u8)~0x01; + gSaveContext.save.weekEventReg[8] &= (u8)~1; } // Running in circles in the ranch @@ -287,7 +269,7 @@ void EnMa4_RunInCircles(EnMa4* this, GlobalContext* globalCtx) { } if (sCurrentAnim == 13 && Animation_OnFrame(&this->skelAnime, 37.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_ROMANI_BOW_FLICK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROMANI_BOW_FLICK); } sp34.x = this->pathPoints[this->pathIndex].x; @@ -317,10 +299,10 @@ void EnMa4_RunInCircles(EnMa4* this, GlobalContext* globalCtx) { } Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); - if (this->skelAnime.animation == &D_06007328) { // Walking animation + Actor_MoveWithGravity(&this->actor); + if (this->skelAnime.animation == &object_ma1_Anim_007328) { // Walking animation if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_ROMANI_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_ROMANI_WALK); } } } @@ -350,7 +332,7 @@ void EnMa4_Wait(EnMa4* this, GlobalContext* globalCtx) { s16 yaw = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; if ((this->state == MA4_STATE_AFTERHORSEBACKGAME) || (this->state == MA4_STATE_AFTERDESCRIBETHEMCS)) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; } else if (this->type != MA4_TYPE_ALIENS_WON) { EnMa4_RunInCircles(this, globalCtx); } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { @@ -363,7 +345,7 @@ void EnMa4_Wait(EnMa4* this, GlobalContext* globalCtx) { } } - if (func_800B84D0(&this->actor, globalCtx) != 0) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { EnMa4_StartDialogue(this, globalCtx); EnMa4_SetupDialogueHandler(this); } else if (this->type != MA4_TYPE_ALIENS_WON || ABS_ALT(yaw) < 0x4000) { @@ -375,16 +357,16 @@ void EnMa4_Wait(EnMa4* this, GlobalContext* globalCtx) { // Chooses the next dialogue based on player's selection void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx) != 0) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x3339: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - func_801518B0(globalCtx, 0x333A, &this->actor); + Message_StartTextbox(globalCtx, 0x333A, &this->actor); this->textId = 0x333A; } else { func_8019F208(); - func_801518B0(globalCtx, 0x333B, &this->actor); + Message_StartTextbox(globalCtx, 0x333B, &this->actor); this->textId = 0x333B; } break; @@ -392,13 +374,13 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { case 0x3341: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - gSaveContext.weekEventReg[0x15] |= 0x20; - func_801518B0(globalCtx, 0x3343, &this->actor); + gSaveContext.save.weekEventReg[21] |= 0x20; + Message_StartTextbox(globalCtx, 0x3343, &this->actor); this->textId = 0x3343; } else { func_8019F230(); EnMa4_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x3342, &this->actor); + Message_StartTextbox(globalCtx, 0x3342, &this->actor); this->textId = 0x3342; this->state = MA4_STATE_DEFAULT; func_80151BB4(globalCtx, 5); @@ -408,13 +390,13 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { case 0x3346: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - gSaveContext.weekEventReg[0x15] |= 0x20; - func_801518B0(globalCtx, 0x3343, &this->actor); + gSaveContext.save.weekEventReg[21] |= 0x20; + Message_StartTextbox(globalCtx, 0x3343, &this->actor); this->textId = 0x3343; } else { func_8019F230(); EnMa4_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x3342, &this->actor); + Message_StartTextbox(globalCtx, 0x3342, &this->actor); this->textId = 0x3342; } break; @@ -422,11 +404,11 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { case 0x3347: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - func_801518B0(globalCtx, 0x3349, &this->actor); + Message_StartTextbox(globalCtx, 0x3349, &this->actor); this->textId = 0x3349; } else { func_8019F230(); - func_801518B0(globalCtx, 0x3348, &this->actor); + Message_StartTextbox(globalCtx, 0x3348, &this->actor); this->textId = 0x3348; func_80151BB4(globalCtx, 5); } @@ -437,16 +419,16 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { s32 aux; func_8019F208(); - func_801518B0(globalCtx, 0x334E, &this->actor); + Message_StartTextbox(globalCtx, 0x334E, &this->actor); this->textId = 0x334E; - if (CHECK_QUEST_ITEM(14)) { + if (CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { func_80151BB4(globalCtx, 0x1C); } func_80151BB4(globalCtx, 5); } else { // No. func_8019F230(); EnMa4_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x334C, &this->actor); + Message_StartTextbox(globalCtx, 0x334C, &this->actor); this->textId = 0x334C; } break; @@ -454,12 +436,12 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { case 0x3354: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - func_801518B0(globalCtx, 0x3349, &this->actor); + Message_StartTextbox(globalCtx, 0x3349, &this->actor); this->textId = 0x3349; } else { func_8019F230(); EnMa4_SetFaceExpression(this, 1, 0); - func_801518B0(globalCtx, 0x3355, &this->actor); + Message_StartTextbox(globalCtx, 0x3355, &this->actor); this->textId = 0x3355; func_80151BB4(globalCtx, 5); } @@ -475,13 +457,13 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { if (this->type == MA4_TYPE_ALIENS_DEFEATED) { func_8019F230(); EnMa4_SetFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x3357, &this->actor); + Message_StartTextbox(globalCtx, 0x3357, &this->actor); this->textId = 0x3357; func_80151BB4(globalCtx, 5); } else { func_8019F230(); EnMa4_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x335B, &this->actor); + Message_StartTextbox(globalCtx, 0x335B, &this->actor); this->textId = 0x335B; func_80151BB4(globalCtx, 5); } @@ -491,12 +473,12 @@ void EnMa4_HandlePlayerChoice(EnMa4* this, GlobalContext* globalCtx) { case 0x3359: if (globalCtx->msgCtx.choiceIndex == 0) { func_8019F208(); - func_801518B0(globalCtx, 0x3349, &this->actor); + Message_StartTextbox(globalCtx, 0x3349, &this->actor); this->textId = 0x3349; } else { func_8019F230(); EnMa4_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x335A, &this->actor); + Message_StartTextbox(globalCtx, 0x335A, &this->actor); this->textId = 0x335A; func_80151BB4(globalCtx, 5); } @@ -509,7 +491,7 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 aux; - if (func_80147624(globalCtx) != 0) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x2390: func_801477B4(globalCtx); @@ -518,31 +500,31 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { case 0x3335: EnMa4_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3336, &this->actor); + Message_StartTextbox(globalCtx, 0x3336, &this->actor); this->textId = 0x3336; func_80151BB4(globalCtx, 5); break; case 0x3338: - func_801518B0(globalCtx, 0x3339, &this->actor); + Message_StartTextbox(globalCtx, 0x3339, &this->actor); this->textId = 0x3339; break; case 0x333A: case 0x333B: EnMa4_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x333C, &this->actor); + Message_StartTextbox(globalCtx, 0x333C, &this->actor); this->textId = 0x333C; break; case 0x333C: EnMa4_SetFaceExpression(this, 0, 2); - func_801518B0(globalCtx, 0x333D, &this->actor); + Message_StartTextbox(globalCtx, 0x333D, &this->actor); this->textId = 0x333D; break; case 0x333D: - func_801518B0(globalCtx, 0x333E, &this->actor); + Message_StartTextbox(globalCtx, 0x333E, &this->actor); this->textId = 0x333E; break; @@ -552,34 +534,34 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { break; case 0x333F: - func_801518B0(globalCtx, 0x3340, &this->actor); + Message_StartTextbox(globalCtx, 0x3340, &this->actor); this->textId = 0x3340; break; case 0x3340: EnMa4_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3341, &this->actor); + Message_StartTextbox(globalCtx, 0x3341, &this->actor); this->textId = 0x3341; break; case 0x3343: EnMa4_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x3344, &this->actor); + Message_StartTextbox(globalCtx, 0x3344, &this->actor); this->textId = 0x3344; break; case 0x3344: - func_801518B0(globalCtx, 0x3345, &this->actor); + Message_StartTextbox(globalCtx, 0x3345, &this->actor); this->textId = 0x3345; break; case 0x3345: - func_801518B0(globalCtx, 0x3349, &this->actor); + Message_StartTextbox(globalCtx, 0x3349, &this->actor); this->textId = 0x3349; break; case 0x3349: - func_801518B0(globalCtx, 0x334A, &this->actor); + Message_StartTextbox(globalCtx, 0x334A, &this->actor); this->textId = 0x334A; break; @@ -589,7 +571,7 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { break; case 0x334C: - func_801518B0(globalCtx, 0x334D, &this->actor); + Message_StartTextbox(globalCtx, 0x334D, &this->actor); this->textId = 0x334D; break; @@ -598,10 +580,10 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { case 0x335D: case 0x335E: if (this->type == MA4_TYPE_DAY1) { - func_801518B0(globalCtx, 0x3352, &this->actor); + Message_StartTextbox(globalCtx, 0x3352, &this->actor); this->textId = 0x3352; } else { - func_801518B0(globalCtx, 0x3356, &this->actor); + Message_StartTextbox(globalCtx, 0x3356, &this->actor); this->textId = 0x3356; } break; @@ -611,8 +593,8 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { EnMa4_SetFaceExpression(this, 0, 0); // Check if player has Epona's song - if (CHECK_QUEST_ITEM(14)) { - func_801518B0(globalCtx, 0x334C, &this->actor); + if (CHECK_QUEST_ITEM(QUEST_SONG_EPONA)) { + Message_StartTextbox(globalCtx, 0x334C, &this->actor); this->textId = 0x334C; } else { func_801477B4(globalCtx); @@ -623,12 +605,12 @@ void EnMa4_ChooseNextDialogue(EnMa4* this, GlobalContext* globalCtx) { break; case 0x3358: - if ((gSaveContext.playerForm != PLAYER_FORM_HUMAN) || !(CHECK_QUEST_ITEM(14))) { - func_801518B0(globalCtx, 0x335C, &this->actor); + if ((gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) || !(CHECK_QUEST_ITEM(QUEST_SONG_EPONA))) { + Message_StartTextbox(globalCtx, 0x335C, &this->actor); this->textId = 0x335C; func_80151BB4(globalCtx, 5); } else { - func_801518B0(globalCtx, 0x3359, &this->actor); + Message_StartTextbox(globalCtx, 0x3359, &this->actor); this->textId = 0x3359; } break; @@ -648,7 +630,7 @@ void EnMa4_SetupDialogueHandler(EnMa4* this) { void EnMa4_DialogueHandler(EnMa4* this, GlobalContext* globalCtx) { s32 temp_v0; - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { default: break; @@ -661,8 +643,8 @@ void EnMa4_DialogueHandler(EnMa4* this, GlobalContext* globalCtx) { break; case 6: // End conversation - if (func_80147624(globalCtx) != 0) { - if ((globalCtx->msgCtx.unk120B1 == 0) || !CHECK_QUEST_ITEM(18)) { + if (Message_ShouldAdvance(globalCtx)) { + if ((globalCtx->msgCtx.unk120B1 == 0) || !CHECK_QUEST_ITEM(QUEST_BOMBERS_NOTEBOOK)) { EnMa4_SetupWait(this); } } @@ -692,9 +674,9 @@ void EnMa4_BeginHorsebackGame(EnMa4* this, GlobalContext* globalCtx) { } void EnMa4_HorsebackGameCheckPlayerInteractions(EnMa4* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { // "You're feeling confident" - func_801518B0(globalCtx, 0x336E, &this->actor); + Message_StartTextbox(globalCtx, 0x336E, &this->actor); this->actionFunc = EnMa4_HorsebackGameTalking; } else if ((gSaveContext.unk_3DE0[4] < 115 * 100)) { // timer < 115 seconds func_800B8614(&this->actor, globalCtx, 100.0f); @@ -702,7 +684,7 @@ void EnMa4_HorsebackGameCheckPlayerInteractions(EnMa4* this, GlobalContext* glob } void EnMa4_HorsebackGameTalking(EnMa4* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actionFunc = EnMa4_HorsebackGameWait; } } @@ -712,7 +694,7 @@ void EnMa4_InitHorsebackGame(EnMa4* this, GlobalContext* globalCtx) { globalCtx->interfaceCtx.unk_280 = 1; func_8010E9F0(4, 0); - gSaveContext.weekEventReg[0x8] |= 0x01; + gSaveContext.save.weekEventReg[8] |= 1; func_80112AFC(globalCtx); player->stateFlags1 |= 0x20; this->actionFunc = EnMa4_SetupHorsebackGameWait; @@ -748,10 +730,10 @@ void EnMa4_HorsebackGameWait(EnMa4* this, GlobalContext* globalCtx) { } void EnMa4_SetupHorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { - gSaveContext.weekEventReg[0x8] &= (u8)~0x01; + gSaveContext.save.weekEventReg[8] &= (u8)~1; this->actionFunc = EnMa4_HorsebackGameEnd; Audio_QueueSeqCmd(NA_BGM_STOP); - Audio_QueueSeqCmd(0x8041); + Audio_QueueSeqCmd(NA_BGM_HORSE_GOAL | 0x8000); } void EnMa4_HorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { @@ -760,17 +742,17 @@ void EnMa4_HorsebackGameEnd(EnMa4* this, GlobalContext* globalCtx) { if (player->stateFlags1 & 0x100000) { globalCtx->actorCtx.unk268 = 1; - globalCtx->actorCtx.unk278 = 0x8000; + globalCtx->actorCtx.unk_26C.press.button = BTN_A; } else { globalCtx->actorCtx.unk268 = 1; } if (sFrameCounter == 25) { if (this->poppedBalloonCounter == 10) { - func_801518B0(globalCtx, 0x334F, &this->actor); + Message_StartTextbox(globalCtx, 0x334F, &this->actor); this->textId = 0x334F; } else { - func_801518B0(globalCtx, 0x334B, &this->actor); + Message_StartTextbox(globalCtx, 0x334B, &this->actor); this->textId = 0x334B; } } else if (sFrameCounter == 50) { @@ -820,15 +802,15 @@ void EnMa4_SetupEponasSongCs(EnMa4* this) { static u16 D_80AC0260 = 99; void EnMa4_EponasSongCs(EnMa4* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x78) != 0) { - u32 actionIndex = func_800EE200(globalCtx, 0x78); + if (Cutscene_CheckActorAction(globalCtx, 120)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 120); - if (globalCtx->csCtx.frames == globalCtx->csCtx.npcActions[actionIndex]->startFrame) { - if (globalCtx->csCtx.npcActions[actionIndex]->unk0 != D_80AC0260) { - D_80AC0260 = globalCtx->csCtx.npcActions[actionIndex]->unk0; + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + if (globalCtx->csCtx.actorActions[actionIndex]->action != D_80AC0260) { + D_80AC0260 = globalCtx->csCtx.actorActions[actionIndex]->action; this->animTimer = 0; - switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: this->hasBow = true; EnMa4_ChangeAnim(this, 1); @@ -842,7 +824,7 @@ void EnMa4_EponasSongCs(EnMa4* this, GlobalContext* globalCtx) { } } - func_800EDF24(&this->actor, globalCtx, actionIndex); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); if (D_80AC0260 == 2 && this->animTimer == 0 && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { EnMa4_ChangeAnim(this, 7); } @@ -850,7 +832,7 @@ void EnMa4_EponasSongCs(EnMa4* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); player->stateFlags1 |= 0x20; - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); D_80AC0260 = 99; this->hasBow = true; EnMa4_SetupEndEponasSongCs(this); @@ -864,15 +846,15 @@ void EnMa4_SetupEndEponasSongCs(EnMa4* this) { void EnMa4_EndEponasSongCs(EnMa4* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - this->actor.flags |= 0x10000; - if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->actor.flags |= ACTOR_FLAG_10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) { player->stateFlags1 &= ~0x20; - func_801518B0(globalCtx, 0x334C, &this->actor); + Message_StartTextbox(globalCtx, 0x334C, &this->actor); this->textId = 0x334C; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; EnMa4_SetupDialogueHandler(this); } else { - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -894,129 +876,129 @@ void EnMa4_StartDialogue(EnMa4* this, GlobalContext* globalCtx) { switch (this->type) { case MA4_TYPE_DAY1: - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - if ((gSaveContext.weekEventReg[0x15] & 0x80)) { + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + if ((gSaveContext.save.weekEventReg[21] & 0x80)) { EnMa4_SetFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x3337, &this->actor); + Message_StartTextbox(globalCtx, 0x3337, &this->actor); this->textId = 0x3337; func_80151BB4(globalCtx, 5); } else { - func_801518B0(globalCtx, 0x3335, &this->actor); + Message_StartTextbox(globalCtx, 0x3335, &this->actor); this->textId = 0x3335; - gSaveContext.weekEventReg[0x15] |= 0x80; + gSaveContext.save.weekEventReg[21] |= 0x80; } } else if (this->state == MA4_STATE_DEFAULT) { - if ((gSaveContext.weekEventReg[0x15] & 0x40)) { - if (!(gSaveContext.weekEventReg[0x15] & 0x20)) { - func_801518B0(globalCtx, 0x3346, &this->actor); + if ((gSaveContext.save.weekEventReg[21] & 0x40)) { + if (!(gSaveContext.save.weekEventReg[21] & 0x20)) { + Message_StartTextbox(globalCtx, 0x3346, &this->actor); this->textId = 0x3346; } else { - func_801518B0(globalCtx, 0x3347, &this->actor); + Message_StartTextbox(globalCtx, 0x3347, &this->actor); this->textId = 0x3347; } } else { - func_801518B0(globalCtx, 0x3338, &this->actor); + Message_StartTextbox(globalCtx, 0x3338, &this->actor); this->textId = 0x3338; - gSaveContext.weekEventReg[0x15] |= 0x40; + gSaveContext.save.weekEventReg[21] |= 0x40; } } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { // "Too bad Grasshopper" EnMa4_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x336D, &this->actor); + Message_StartTextbox(globalCtx, 0x336D, &this->actor); this->textId = 0x336D; } else { time = gSaveContext.unk_3DE0[4]; - if ((s32)time < (s32)gSaveContext.roomInf[127][4]) { + if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { // [Score] New record! - gSaveContext.roomInf[127][4] = time; + gSaveContext.save.horseBackBalloonHighScore = time; EnMa4_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3350, &this->actor); + Message_StartTextbox(globalCtx, 0x3350, &this->actor); this->textId = 0x3350; } else { // [Score] Great. - func_801518B0(globalCtx, 0x3351, &this->actor); + Message_StartTextbox(globalCtx, 0x3351, &this->actor); this->textId = 0x3351; } } this->state = MA4_STATE_DEFAULT; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } else if (this->state == MA4_STATE_AFTERDESCRIBETHEMCS) { // "Cremia doesn't believe me..." - func_801518B0(globalCtx, 0x3340, &this->actor); + Message_StartTextbox(globalCtx, 0x3340, &this->actor); this->textId = 0x3340; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } break; case MA4_TYPE_ALIENS_DEFEATED: - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - if ((gSaveContext.weekEventReg[0x15] & 0x80)) { + if (gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) { + if ((gSaveContext.save.weekEventReg[21] & 0x80)) { EnMa4_SetFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x3337, &this->actor); + Message_StartTextbox(globalCtx, 0x3337, &this->actor); this->textId = 0x3337; func_80151BB4(globalCtx, 5); } else { - func_801518B0(globalCtx, 0x3335, &this->actor); + Message_StartTextbox(globalCtx, 0x3335, &this->actor); this->textId = 0x3335; - gSaveContext.weekEventReg[0x15] |= 0x80; + gSaveContext.save.weekEventReg[21] |= 0x80; } } else if (this->state == MA4_STATE_DEFAULT) { - func_801518B0(globalCtx, 0x3354, &this->actor); + Message_StartTextbox(globalCtx, 0x3354, &this->actor); this->textId = 0x3354; } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { // "Try again?" - func_801518B0(globalCtx, 0x3356, &this->actor); + Message_StartTextbox(globalCtx, 0x3356, &this->actor); this->textId = 0x3356; } else { time = gSaveContext.unk_3DE0[4]; - if ((s32)time < (s32)gSaveContext.roomInf[127][4]) { - gSaveContext.roomInf[127][4] = time; + if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { + gSaveContext.save.horseBackBalloonHighScore = time; EnMa4_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3350, &this->actor); + Message_StartTextbox(globalCtx, 0x3350, &this->actor); this->textId = 0x3350; } else { - func_801518B0(globalCtx, 0x3351, &this->actor); + Message_StartTextbox(globalCtx, 0x3351, &this->actor); this->textId = 0x3351; } } this->state = MA4_STATE_DEFAULT; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } break; case MA4_TYPE_ALIENS_WON: if (this->state == MA4_STATE_DEFAULT) { // "Huh... You?" - func_801518B0(globalCtx, 0x3358, &this->actor); + Message_StartTextbox(globalCtx, 0x3358, &this->actor); this->textId = 0x3358; } else if (this->state == MA4_STATE_AFTERHORSEBACKGAME) { if (gSaveContext.unk_3DE0[4] >= 2 * 60 * 100) { // "Try again?" - func_801518B0(globalCtx, 0x3356, &this->actor); + Message_StartTextbox(globalCtx, 0x3356, &this->actor); this->textId = 0x3356; } else { time = gSaveContext.unk_3DE0[4]; - if ((s32)time < (s32)gSaveContext.roomInf[127][4]) { + if ((s32)time < (s32)gSaveContext.save.horseBackBalloonHighScore) { // New record - gSaveContext.roomInf[127][4] = time; - func_801518B0(globalCtx, 0x335D, &this->actor); + gSaveContext.save.horseBackBalloonHighScore = time; + Message_StartTextbox(globalCtx, 0x335D, &this->actor); this->textId = 0x335D; } else { // "Old record was: [record]" - func_801518B0(globalCtx, 0x335E, &this->actor); + Message_StartTextbox(globalCtx, 0x335E, &this->actor); this->textId = 0x335E; } } this->state = MA4_STATE_DEFAULT; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } break; default: // Dead code - func_801518B0(globalCtx, 0x3335, &this->actor); + Message_StartTextbox(globalCtx, 0x3335, &this->actor); this->textId = 0x3335; break; } @@ -1070,11 +1052,11 @@ void EnMa4_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve Vec3f sp28 = { 800.0f, 0.0f, 0.0f }; if (limbIndex == MA1_LIMB_HEAD) { - Matrix_MultiplyVector3fByState(&sp28, &this->actor.focus.pos); + Matrix_MultVec3f(&sp28, &this->actor.focus.pos); } else if (limbIndex == MA1_LIMB_HAND_LEFT) { if (this->hasBow == true) { OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_060003B0); + gSPDisplayList(POLY_OPA_DISP++, object_ma1_DL_0003B0); CLOSE_DISPS(globalCtx->state.gfxCtx); } } @@ -1086,7 +1068,7 @@ void EnMa4_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); if (this->type == MA4_TYPE_ALIENS_WON) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_06000A20); + gSPDisplayList(POLY_OPA_DISP++, object_ma1_DL_000A20); } func_8012C28C(globalCtx->state.gfxCtx); 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 9d9969e68..52c6a2998 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 @@ -5,8 +5,9 @@ */ #include "z_en_ma_yto.h" +#include "objects/object_ma2/object_ma2.h" -#define FLAGS 0x02100009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((EnMaYto*)thisx) @@ -21,7 +22,6 @@ void EnMaYto_ChooseAction(EnMaYto* this, GlobalContext* globalCtx); s32 EnMaYto_TryFindRomani(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupKeepLookingForRomani(EnMaYto* this); void EnMaYto_KeepLookingForRomani(EnMaYto* this, GlobalContext* globalCtx); - void EnMaYto_SetupDefaultWait(EnMaYto* this); void EnMaYto_DefaultWait(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupDefaultDialogueHandler(EnMaYto* this); @@ -43,7 +43,6 @@ void EnMaYto_SetupAfterMilkRunInit(EnMaYto* this); void EnMaYto_AfterMilkRunInit(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupAfterMilkRunDialogueHandler(EnMaYto* this); void EnMaYto_AfterMilkRunDialogueHandler(EnMaYto* this, GlobalContext* globalCtx); - void EnMaYto_AfterMilkRunChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupPostMilkRunGiveReward(EnMaYto* this); void EnMaYto_PostMilkRunGiveReward(EnMaYto* this, GlobalContext* globalCtx); @@ -52,7 +51,6 @@ void EnMaYto_PostMilkRunExplainReward(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupBeginWarmFuzzyFeelingCs(EnMaYto* this); void EnMaYto_BeginWarmFuzzyFeelingCs(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupWarmFuzzyFeelingCs(EnMaYto* this); - void EnMaYto_WarmFuzzyFeelingCs(EnMaYto* this, GlobalContext* globalCtx); void EnMaYto_SetupPostMilkRunWaitDialogueEnd(EnMaYto* this); void EnMaYto_PostMilkRunWaitDialogueEnd(EnMaYto* this, GlobalContext* globalCtx); @@ -67,9 +65,8 @@ void func_80B90E50(EnMaYto* this, s16); void EnMaYto_SetRomaniFaceExpression(EnMaYto* this, s16 overrideEyeTexIndex, s16 mouthTexIndex); void EnMaYto_SetFaceExpression(EnMaYto* this, s16 overrideEyeTexIndex, s16 mouthIndex); void EnMaYto_InitFaceExpression(EnMaYto* this); -s32 EnMaYto_HasSpokeToPlayerToday(); - -s32 EnMaYto_HasSpokeToPlayer(void); +s32 EnMaYto_HasSpokenToPlayerToday(void); +s32 EnMaYto_HasSpokenToPlayer(void); void EnMaYto_SetTalkedFlag(void); const ActorInit En_Ma_Yto_InitVars = { @@ -108,60 +105,31 @@ static CollisionCheckInfoInit2 sColChkInfoInit2 = { 0, 0, 0, 0, MASS_IMMOVABLE, }; -extern FlexSkeletonHeader D_06015C28; - -extern AnimationHeader D_0600A174; -extern AnimationHeader D_0600AF7C; -extern AnimationHeader D_06000CC0; -extern AnimationHeader D_06016720; -extern AnimationHeader D_06005314; -extern AnimationHeader D_060093E8; -extern AnimationHeader D_06007E28; -extern AnimationHeader D_060070EC; -extern AnimationHeader D_06003D54; -extern AnimationHeader D_06001FD0; -extern AnimationHeader D_060030B4; -extern AnimationHeader D_06004370; - -extern void* D_06014AD8[]; -extern void* D_06014ED8[]; -extern void* D_060152D8[]; -extern void* D_060156D8[]; - -extern void* D_06011AD8[]; -extern void* D_060122D8[]; -extern void* D_06012AD8[]; -extern void* D_060132D8[]; -extern void* D_06013AD8[]; -extern void* D_060142D8[]; - -// gCremiaWoodenBox -extern Gfx D_06005430[]; - -static struct_80B8E1A8 sAnimationInfo[] = { - { &D_0600A174, 1.0f, 0, 0.0f }, { &D_0600A174, 1.0f, 0, -6.0f }, // - { &D_0600AF7C, 1.0f, 2, 0.0f }, { &D_0600AF7C, 1.0f, 2, -6.0f }, // - { &D_06000CC0, 1.0f, 0, 0.0f }, { &D_06000CC0, 1.0f, 0, -6.0f }, // - { &D_06016720, 1.0f, 0, 0.0f }, { &D_06016720, 1.0f, 0, -8.0f }, // - { &D_06005314, 1.0f, 0, 0.0f }, { &D_06005314, 1.0f, 0, -8.0f }, // - { &D_060093E8, 1.0f, 0, 0.0f }, { &D_060093E8, 1.0f, 0, -10.0f }, // - { &D_06007E28, 1.0f, 0, 0.0f }, { &D_06007E28, 1.0f, 0, -8.0f }, // - { &D_060070EC, 1.0f, 0, 0.0f }, { &D_060070EC, 1.0f, 0, -8.0f }, // - { &D_06003D54, 1.0f, 0, 0.0f }, { &D_06003D54, 1.0f, 0, -8.0f }, // - { &D_06001FD0, 1.0f, 0, 0.0f }, { &D_06001FD0, 1.0f, 0, -8.0f }, // - { &D_060030B4, 1.0f, 0, 0.0f }, { &D_060030B4, 1.0f, 0, -8.0f }, // - { &D_06004370, 1.0f, 0, 0.0f }, { &D_06004370, 1.0f, 0, -8.0f }, // +static AnimationSpeedInfo sAnimationInfo[] = { + { &object_ma2_Anim_00A174, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_00A174, 1.0f, ANIMMODE_LOOP, -6.0f }, // + { &object_ma2_Anim_00AF7C, 1.0f, ANIMMODE_ONCE, 0.0f }, { &object_ma2_Anim_00AF7C, 1.0f, ANIMMODE_ONCE, -6.0f }, // + { &object_ma2_Anim_000CC0, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_000CC0, 1.0f, ANIMMODE_LOOP, -6.0f }, // + { &object_ma2_Anim_016720, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_016720, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_005314, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_005314, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_0093E8, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_0093E8, 1.0f, ANIMMODE_LOOP, -10.0f }, // + { &object_ma2_Anim_007E28, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_007E28, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_0070EC, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_0070EC, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_003D54, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_003D54, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_001FD0, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_001FD0, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_0030B4, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_0030B4, 1.0f, ANIMMODE_LOOP, -8.0f }, // + { &object_ma2_Anim_004370, 1.0f, ANIMMODE_LOOP, 0.0f }, { &object_ma2_Anim_004370, 1.0f, ANIMMODE_LOOP, -8.0f }, // }; -static void* sMouthTextures[] = { - D_06014AD8, - D_06014ED8, - D_060152D8, - D_060156D8, +static TexturePtr sMouthTextures[] = { + object_ma2_Tex_014AD8, + object_ma2_Tex_014ED8, + object_ma2_Tex_0152D8, + object_ma2_Tex_0156D8, }; -static void* sEyesTextures[] = { - D_06011AD8, D_060122D8, D_06012AD8, D_060132D8, D_06013AD8, D_060142D8, +static TexturePtr sEyesTextures[] = { + object_ma2_Tex_011AD8, object_ma2_Tex_0122D8, object_ma2_Tex_012AD8, + object_ma2_Tex_0132D8, object_ma2_Tex_013AD8, object_ma2_Tex_0142D8, }; void EnMaYto_Init(Actor* thisx, GlobalContext* globalCtx) { @@ -174,7 +142,7 @@ void EnMaYto_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk320 = 0; this->eyeTexIndex = 0; - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { EnMaYto_SetFaceExpression(this, 0, 1); } else { EnMaYto_SetFaceExpression(this, 5, 2); @@ -188,8 +156,8 @@ void EnMaYto_Init(Actor* thisx, GlobalContext* globalCtx) { return; } - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 18.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06015C28, NULL, this->jointTable, this->morphTable, + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma2_Skel_015C28, NULL, this->jointTable, this->morphTable, MA2_LIMB_MAX); EnMaYto_InitAnimation(this, globalCtx); @@ -208,34 +176,34 @@ void EnMaYto_Init(Actor* thisx, GlobalContext* globalCtx) { s32 EnMaYto_CheckValidSpawn(EnMaYto* this, GlobalContext* globalCtx) { switch (this->type) { case MA_YTO_TYPE_DEFAULT: - if (CURRENT_DAY == 3 && !(gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 3 && !(gSaveContext.save.weekEventReg[22] & 1)) { return false; } break; case MA_YTO_TYPE_DINNER: - if (CURRENT_DAY != 1 && (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY != 1 && (gSaveContext.save.weekEventReg[22] & 1)) { return false; } break; case MA_YTO_TYPE_BARN: - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { if (((this->actor.params & 0x0F00) >> 8) != 0) { return false; } } else if (((this->actor.params & 0x0F00) >> 8) == 0) { return false; } - if (gSaveContext.time >= CLOCK_TIME(20, 0) && CURRENT_DAY == 3) { + if (gSaveContext.save.time >= CLOCK_TIME(20, 0) && CURRENT_DAY == 3) { return false; } break; case MA_YTO_TYPE_AFTERMILKRUN: - // if (!(ProtectedCremia) && !(gSaveContext.weekEventReg[0x34] & 2)) || (PlayedMilkMinigame)) - if ((!(gSaveContext.weekEventReg[0x34] & 1) && !(gSaveContext.weekEventReg[0x34] & 2)) || - (gSaveContext.weekEventReg[0xE] & 1)) { + // if (!(ProtectedCremia) && !(gSaveContext.save.weekEventReg[52] & 2)) || (PlayedMilkMinigame)) + if ((!(gSaveContext.save.weekEventReg[52] & 1) && !(gSaveContext.save.weekEventReg[52] & 2)) || + (gSaveContext.save.weekEventReg[14] & 1)) { return false; } break; @@ -263,7 +231,7 @@ void EnMaYto_InitAnimation(EnMaYto* this, GlobalContext* globalCtx) { case MA_YTO_TYPE_BARN: // if (AliensDefeated) - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { EnMaYto_ChangeAnim(this, 12); } else { EnMaYto_ChangeAnim(this, 8); @@ -301,7 +269,7 @@ void EnMaYto_ChooseAction(EnMaYto* this, GlobalContext* globalCtx) { case MA_YTO_TYPE_AFTERMILKRUN: this->unk310 = 0; - if (INV_CONTENT(ITEM_MASK_ROMANIS) == ITEM_MASK_ROMANIS && (gSaveContext.weekEventReg[0x34] & 1) && + if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI && (gSaveContext.save.weekEventReg[52] & 1) && (Rand_Next() & 0x80)) { EnMaYto_SetupBeginWarmFuzzyFeelingCs(this); } else { @@ -310,7 +278,7 @@ void EnMaYto_ChooseAction(EnMaYto* this, GlobalContext* globalCtx) { break; case MA_YTO_TYPE_4: - this->actor.flags |= 0x10; + this->actor.flags |= ACTOR_FLAG_10; EnMaYto_SetupWarmFuzzyFeelingCs(this); break; @@ -321,7 +289,7 @@ void EnMaYto_ChooseAction(EnMaYto* this, GlobalContext* globalCtx) { } s32 EnMaYto_SearchRomani(EnMaYto* this, GlobalContext* globalCtx) { - Actor* npcActor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* npcActor = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (npcActor != NULL) { if (npcActor->id == ACTOR_EN_MA_YTS) { @@ -356,7 +324,7 @@ s32 EnMaYto_TryFindRomani(EnMaYto* this, GlobalContext* globalCtx) { return 0; case MA_YTO_TYPE_DINNER: - if (!(gSaveContext.weekEventReg[0x16] & 1) && CURRENT_DAY == 2) { + if (!(gSaveContext.save.weekEventReg[22] & 1) && CURRENT_DAY == 2) { return 0; } if (EnMaYto_SearchRomani(this, globalCtx)) { @@ -366,7 +334,7 @@ s32 EnMaYto_TryFindRomani(EnMaYto* this, GlobalContext* globalCtx) { case MA_YTO_TYPE_BARN: // if (AliensDefeated) - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { if (EnMaYto_SearchRomani(this, globalCtx)) { return 2; } @@ -425,7 +393,7 @@ void EnMaYto_DefaultWait(EnMaYto* this, GlobalContext* globalCtx) { EnMaYto_ChangeAnim(this, 11); } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnMaYto_DefaultStartDialogue(this, globalCtx); EnMaYto_SetupDefaultDialogueHandler(this); } else if (ABS_ALT(direction) < 0x1555) { @@ -440,7 +408,7 @@ void EnMaYto_SetupDefaultDialogueHandler(EnMaYto* this) { } void EnMaYto_DefaultDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: EnMaYto_DefaultHandlePlayerChoice(this, globalCtx); break; @@ -450,7 +418,7 @@ void EnMaYto_DefaultDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->unk31E = 0; EnMaYto_SetupDefaultWait(this); } @@ -464,54 +432,54 @@ void EnMaYto_DefaultDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { } Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x3000, 0x100); - if (this->textId == 0x3395 && this->skelAnime.animation == &D_0600AF7C && + if (this->textId == 0x3395 && this->skelAnime.animation == &object_ma2_Anim_00AF7C && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { EnMaYto_ChangeAnim(this, 4); } } void EnMaYto_DefaultHandlePlayerChoice(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex == 0) { // Yes func_8019F208(); EnMaYto_SetFaceExpression(this, 0, 3); // "Milk Road is fixed!" - func_801518B0(globalCtx, 0x3392, &this->actor); + Message_StartTextbox(globalCtx, 0x3392, &this->actor); this->textId = 0x3392; } else { // No func_8019F230(); // "Don't lie!" - func_801518B0(globalCtx, 0x3391, &this->actor); + Message_StartTextbox(globalCtx, 0x3391, &this->actor); this->textId = 0x3391; } } } void EnMaYto_DefaultChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x3391: EnMaYto_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3392, &this->actor); + Message_StartTextbox(globalCtx, 0x3392, &this->actor); this->textId = 0x3392; break; case 0x3392: EnMaYto_SetFaceExpression(this, 3, 1); - func_801518B0(globalCtx, 0x3393, &this->actor); + Message_StartTextbox(globalCtx, 0x3393, &this->actor); this->textId = 0x3393; func_80151BB4(globalCtx, 6); break; case 0x3394: EnMaYto_ChangeAnim(this, 2); - func_801518B0(globalCtx, 0x3395, &this->actor); + Message_StartTextbox(globalCtx, 0x3395, &this->actor); this->textId = 0x3395; break; case 0x3395: EnMaYto_ChangeAnim(this, 1); - func_801518B0(globalCtx, 0x3396, &this->actor); + Message_StartTextbox(globalCtx, 0x3396, &this->actor); this->textId = 0x3396; func_80151BB4(globalCtx, 6); break; @@ -520,7 +488,7 @@ void EnMaYto_DefaultChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) } void EnMaYto_SetupDinnerWait(EnMaYto* this) { - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { func_80B90E50(this, 0); this->unk31E = 0; } else { @@ -535,14 +503,14 @@ void EnMaYto_SetupDinnerWait(EnMaYto* this) { void EnMaYto_DinnerWait(EnMaYto* this, GlobalContext* globalCtx) { s16 direction = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnMaYto_DinnerStartDialogue(this, globalCtx); EnMaYto_SetupDinnerDialogueHandler(this); } else { Actor* child = this->actor.child; - if (child != NULL && func_800B84D0(child, globalCtx)) { - func_800B86C8(&this->actor, globalCtx, &this->actor); + if (child != NULL && Actor_ProcessTalkRequest(child, &globalCtx->state)) { + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); EnMaYto_DinnerStartDialogue(this, globalCtx); EnMaYto_SetupDinnerDialogueHandler(this); } else if (ABS_ALT(direction) < 0x4000) { @@ -561,7 +529,7 @@ void EnMaYto_DinnerWait(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_SetupDinnerDialogueHandler(EnMaYto* this) { - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { func_80B90E50(this, 1); } else { func_80B90E50(this, 2); @@ -572,7 +540,7 @@ void EnMaYto_SetupDinnerDialogueHandler(EnMaYto* this) { } void EnMaYto_DinnerDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: EnMaYto_DinnerHandlePlayerChoice(this, globalCtx); break; @@ -582,7 +550,7 @@ void EnMaYto_DinnerDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnMaYto_SetupDinnerWait(this); } break; @@ -596,65 +564,65 @@ void EnMaYto_DinnerDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_DinnerHandlePlayerChoice(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex == 0) { // Yes func_8019F208(); EnMaYto_SetFaceExpression(this, 0, 3); // "Milk Road is fixed!" - func_801518B0(globalCtx, 0x3399, &this->actor); + Message_StartTextbox(globalCtx, 0x3399, &this->actor); this->textId = 0x3399; } else { // No func_8019F230(); // "Don't lie!" - func_801518B0(globalCtx, 0x3398, &this->actor); + Message_StartTextbox(globalCtx, 0x3398, &this->actor); this->textId = 0x3398; } } } void EnMaYto_DinnerChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x3398: EnMaYto_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x3399, &this->actor); + Message_StartTextbox(globalCtx, 0x3399, &this->actor); this->textId = 0x3399; break; case 0x3399: EnMaYto_SetFaceExpression(this, 3, 1); - func_801518B0(globalCtx, 0x339A, &this->actor); + Message_StartTextbox(globalCtx, 0x339A, &this->actor); this->textId = 0x339A; break; case 0x339A: this->unk31E = 1; EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x339B, &this->actor); + Message_StartTextbox(globalCtx, 0x339B, &this->actor); this->textId = 0x339B; break; case 0x339B: - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); func_80B90E50(this, 0); EnMaYto_SetRomaniFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x339C, &this->actor); + Message_StartTextbox(globalCtx, 0x339C, &this->actor); this->textId = 0x339C; break; case 0x339C: this->unk31E = 1; - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); EnMaYto_SetFaceExpression(this, 0, 2); - func_801518B0(globalCtx, 0x339D, &this->actor); + Message_StartTextbox(globalCtx, 0x339D, &this->actor); this->textId = 0x339D; break; case 0x339D: func_80B90E50(this, 1); - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); EnMaYto_SetRomaniFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x339E, &this->actor); + Message_StartTextbox(globalCtx, 0x339E, &this->actor); this->textId = 0x339E; func_80151BB4(globalCtx, 6); func_80151BB4(globalCtx, 5); @@ -662,48 +630,48 @@ void EnMaYto_DinnerChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { case 0x339F: this->unk31E = 0; - func_801518B0(globalCtx, 0x33A0, &this->actor); + Message_StartTextbox(globalCtx, 0x33A0, &this->actor); this->textId = 0x33A0; break; case 0x33A0: - func_801518B0(globalCtx, 0x33A1, &this->actor); + Message_StartTextbox(globalCtx, 0x33A1, &this->actor); this->textId = 0x33A1; break; case 0x33A1: func_80B90E50(this, 1); - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); EnMaYto_SetRomaniFaceExpression(this, 0, 2); - func_801518B0(globalCtx, 0x33A2, &this->actor); + Message_StartTextbox(globalCtx, 0x33A2, &this->actor); this->textId = 0x33A2; break; case 0x33A2: this->unk31E = 1; - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); EnMaYto_SetFaceExpression(this, 4, 3); - func_801518B0(globalCtx, 0x33A3, &this->actor); + Message_StartTextbox(globalCtx, 0x33A3, &this->actor); this->textId = 0x33A3; break; case 0x33A3: this->unk31E = 0; EnMaYto_SetFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x33A4, &this->actor); + Message_StartTextbox(globalCtx, 0x33A4, &this->actor); this->textId = 0x33A4; func_80151BB4(globalCtx, 6); func_80151BB4(globalCtx, 5); break; case 0x33A5: - func_801518B0(globalCtx, 0x33A6, &this->actor); + Message_StartTextbox(globalCtx, 0x33A6, &this->actor); this->textId = 0x33A6; func_80151BB4(globalCtx, 6); break; case 0x33A7: - func_801518B0(globalCtx, 0x33A8, &this->actor); + Message_StartTextbox(globalCtx, 0x33A8, &this->actor); this->textId = 0x33A8; func_80151BB4(globalCtx, 6); break; @@ -712,7 +680,7 @@ void EnMaYto_DinnerChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_SetupBarnWait(EnMaYto* this) { - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { EnMaYto_ChangeAnim(this, 13); func_80B90E50(this, 0); this->unk31E = 0; @@ -730,17 +698,17 @@ void EnMaYto_BarnWait(EnMaYto* this, GlobalContext* globalCtx) { s16 direction = this->actor.shape.rot.y + 0x471C; direction -= this->actor.yawTowardsPlayer; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnMaYto_BarnStartDialogue(this, globalCtx); EnMaYto_SetupBarnDialogueHandler(this); } else { Actor* child = this->actor.child; - if (child != NULL && func_800B84D0(child, globalCtx)) { - func_800B86C8(&this->actor, globalCtx, &this->actor); + if (child != NULL && Actor_ProcessTalkRequest(child, &globalCtx->state)) { + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); EnMaYto_BarnStartDialogue(this, globalCtx); EnMaYto_SetupBarnDialogueHandler(this); - } else if (!(gSaveContext.weekEventReg[0x16] & 1) || ABS_ALT(direction) < 0x2000) { + } else if (!(gSaveContext.save.weekEventReg[22] & 1) || ABS_ALT(direction) < 0x2000) { func_800B8614(&this->actor, globalCtx, 100.0f); child = this->actor.child; @@ -752,7 +720,7 @@ void EnMaYto_BarnWait(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_SetupBarnDialogueHandler(EnMaYto* this) { - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { func_80B90E50(this, 1); } else { func_80B90E50(this, 2); @@ -762,13 +730,13 @@ void EnMaYto_SetupBarnDialogueHandler(EnMaYto* this) { } void EnMaYto_BarnDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 5: EnMaYto_BarnChooseNextDialogue(this, globalCtx); break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->unk31E = 0; EnMaYto_SetupBarnWait(this); } @@ -784,35 +752,35 @@ void EnMaYto_BarnDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_BarnChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x33A9: func_80B90E50(this, 0); - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); EnMaYto_SetRomaniFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x33AA, &this->actor); + Message_StartTextbox(globalCtx, 0x33AA, &this->actor); this->textId = 0x33AA; break; case 0x33AA: - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); this->unk31E = 1; - func_801518B0(globalCtx, 0x33AB, &this->actor); + Message_StartTextbox(globalCtx, 0x33AB, &this->actor); this->textId = 0x33AB; break; case 0x33AB: func_80B90E50(this, 1); - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); EnMaYto_SetRomaniFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33AC, &this->actor); + Message_StartTextbox(globalCtx, 0x33AC, &this->actor); this->textId = 0x33AC; break; case 0x33AC: this->unk31E = 0; - func_800B86C8(&this->actor, globalCtx, &this->actor); - func_801518B0(globalCtx, 0x33AD, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); + Message_StartTextbox(globalCtx, 0x33AD, &this->actor); this->textId = 0x33AD; func_80151BB4(globalCtx, 6); func_80151BB4(globalCtx, 5); @@ -820,17 +788,17 @@ void EnMaYto_BarnChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { case 0x33AE: func_80B90E50(this, 1); - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); EnMaYto_SetRomaniFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x33AF, &this->actor); + Message_StartTextbox(globalCtx, 0x33AF, &this->actor); this->textId = 0x33AF; break; case 0x33AF: this->unk31E = 1; - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); EnMaYto_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x33B0, &this->actor); + Message_StartTextbox(globalCtx, 0x33B0, &this->actor); this->textId = 0x33B0; func_80151BB4(globalCtx, 6); func_80151BB4(globalCtx, 5); @@ -840,54 +808,54 @@ void EnMaYto_BarnChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { this->unk31E = 2; EnMaYto_SetFaceExpression(this, 5, 3); // "I should had believed what Romani said" - func_801518B0(globalCtx, 0x33B2, &this->actor); + Message_StartTextbox(globalCtx, 0x33B2, &this->actor); this->textId = 0x33B2; func_80151BB4(globalCtx, 6); break; case 0x33C6: - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); this->unk31E = 0; EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33C7, &this->actor); + Message_StartTextbox(globalCtx, 0x33C7, &this->actor); this->textId = 0x33C7; break; case 0x33C7: - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); this->unk31E = 1; EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33C8, &this->actor); + Message_StartTextbox(globalCtx, 0x33C8, &this->actor); this->textId = 0x33C8; break; case 0x33C8: - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); func_80B90E50(this, 1); EnMaYto_SetRomaniFaceExpression(this, 0, 2); - func_801518B0(globalCtx, 0x33C9, &this->actor); + Message_StartTextbox(globalCtx, 0x33C9, &this->actor); this->textId = 0x33C9; break; case 0x33C9: - func_800B86C8(&this->actor, globalCtx, &this->actor); + Actor_ChangeFocus(&this->actor, globalCtx, &this->actor); this->unk31E = 1; EnMaYto_SetFaceExpression(this, 3, 1); - func_801518B0(globalCtx, 0x33CA, &this->actor); + Message_StartTextbox(globalCtx, 0x33CA, &this->actor); this->textId = 0x33CA; break; case 0x33CA: this->unk31E = 1; - func_801518B0(globalCtx, 0x33CB, &this->actor); + Message_StartTextbox(globalCtx, 0x33CB, &this->actor); this->textId = 0x33CB; break; case 0x33CB: - func_800B86C8(&this->actor, globalCtx, this->actor.child); + Actor_ChangeFocus(&this->actor, globalCtx, this->actor.child); func_80B90E50(this, 1); EnMaYto_SetRomaniFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x33CC, &this->actor); + Message_StartTextbox(globalCtx, 0x33CC, &this->actor); this->textId = 0x33CC; func_80151BB4(globalCtx, 6); func_80151BB4(globalCtx, 5); @@ -900,31 +868,31 @@ void EnMaYto_BarnChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { } void EnMaYto_SetupAfterMilkRunInit(EnMaYto* this) { - if (gSaveContext.weekEventReg[0x34] & 1) { // if (ProtectedCremia) + if (gSaveContext.save.weekEventReg[52] & 1) { // if (ProtectedCremia) EnMaYto_SetFaceExpression(this, 3, 1); } else { - func_801A3098(9); + func_801A3098(NA_BGM_FAILURE_1); EnMaYto_SetFaceExpression(this, 5, 2); } this->actionFunc = EnMaYto_AfterMilkRunInit; } void EnMaYto_AfterMilkRunInit(EnMaYto* this, GlobalContext* globalCtx) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; - if (gSaveContext.weekEventReg[0x34] & 1) { // if (ProtectedCremia) - func_801518B0(globalCtx, 0x33C1, &this->actor); + if (gSaveContext.save.weekEventReg[52] & 1) { // if (ProtectedCremia) + Message_StartTextbox(globalCtx, 0x33C1, &this->actor); this->textId = 0x33C1; } else { // Fails milk minigame EnMaYto_SetFaceExpression(this, 5, 2); - func_801518B0(globalCtx, 0x33C0, &this->actor); + Message_StartTextbox(globalCtx, 0x33C0, &this->actor); this->textId = 0x33C0; // Attempted Cremia Cart Ride - gSaveContext.weekEventReg[0xE] |= 0x1; + gSaveContext.save.weekEventReg[14] |= 1; this->unk310 = 4; EnMaYto_SetupPostMilkRunWaitDialogueEnd(this); func_80151BB4(globalCtx, 6); @@ -942,7 +910,7 @@ void EnMaYto_SetupAfterMilkRunDialogueHandler(EnMaYto* this) { } void EnMaYto_AfterMilkRunDialogueHandler(EnMaYto* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: case 1: case 2: @@ -960,12 +928,12 @@ void EnMaYto_AfterMilkRunDialogueHandler(EnMaYto* this, GlobalContext* globalCtx } void EnMaYto_AfterMilkRunChooseNextDialogue(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x33C1: EnMaYto_SetFaceExpression(this, 3, 1); // "Thank you. You were cool back there." - func_801518B0(globalCtx, 0x33C2, &this->actor); + Message_StartTextbox(globalCtx, 0x33C2, &this->actor); this->textId = 0x33C2; break; @@ -985,11 +953,11 @@ void EnMaYto_SetupPostMilkRunGiveReward(EnMaYto* this) { void EnMaYto_PostMilkRunGiveReward(EnMaYto* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { EnMaYto_SetupPostMilkRunExplainReward(this); - } else if (INV_CONTENT(ITEM_MASK_ROMANIS) == ITEM_MASK_ROMANIS) { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_GOLD, 500.0f, 100.0f); + } else if (INV_CONTENT(ITEM_MASK_ROMANI) == ITEM_MASK_ROMANI) { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_HUGE, 500.0f, 100.0f); this->unk310 = 2; } else { - func_800B8A1C(&this->actor, globalCtx, GI_MASK_ROMANIS, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_ROMANI, 500.0f, 100.0f); this->unk310 = 1; } } @@ -999,14 +967,14 @@ void EnMaYto_SetupPostMilkRunExplainReward(EnMaYto* this) { } void EnMaYto_PostMilkRunExplainReward(EnMaYto* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->unk310 == 1) { // Romani's mask explanation EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33C3, &this->actor); + Message_StartTextbox(globalCtx, 0x33C3, &this->actor); this->textId = 0x33C3; // Attempted Cremia Cart Ride - gSaveContext.weekEventReg[0xE] |= 0x1; + gSaveContext.save.weekEventReg[14] |= 1; this->unk310 = 3; func_80151BB4(globalCtx, 0x20); func_80151BB4(globalCtx, 0x1F); @@ -1015,16 +983,16 @@ void EnMaYto_PostMilkRunExplainReward(EnMaYto* this, GlobalContext* globalCtx) { } else { // You already have the mask EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33D0, &this->actor); + Message_StartTextbox(globalCtx, 0x33D0, &this->actor); this->textId = 0x33D0; // Attempted Cremia Cart Ride - gSaveContext.weekEventReg[0xE] |= 0x1; + gSaveContext.save.weekEventReg[14] |= 1; this->unk310 = 3; func_80151BB4(globalCtx, 6); EnMaYto_SetupPostMilkRunWaitDialogueEnd(this); } } else { - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -1052,11 +1020,11 @@ void EnMaYto_SetupWarmFuzzyFeelingCs(EnMaYto* this) { static u16 D_80B915F0 = 99; void EnMaYto_WarmFuzzyFeelingCs(EnMaYto* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x22C) != 0) { - u32 csActionIndex = func_800EE200(globalCtx, 0x22C); + if (Cutscene_CheckActorAction(globalCtx, 556)) { + s32 csActionIndex = Cutscene_GetActorActionIndex(globalCtx, 556); - if (globalCtx->csCtx.frames == globalCtx->csCtx.npcActions[csActionIndex]->startFrame) { - u16 action = globalCtx->csCtx.npcActions[csActionIndex]->unk0; + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[csActionIndex]->startFrame) { + u16 action = globalCtx->csCtx.actorActions[csActionIndex]->action; if (1) {} @@ -1069,7 +1037,7 @@ void EnMaYto_WarmFuzzyFeelingCs(EnMaYto* this, GlobalContext* globalCtx) { case 2: // Attempted Cremia Cart Ride - gSaveContext.weekEventReg[0xE] |= 1; + gSaveContext.save.weekEventReg[14] |= 1; EnMaYto_ChangeAnim(this, 18); break; @@ -1080,8 +1048,8 @@ void EnMaYto_WarmFuzzyFeelingCs(EnMaYto* this, GlobalContext* globalCtx) { } } - func_800EDF24(&this->actor, globalCtx, csActionIndex); - if (D_80B915F0 == 2 && this->skelAnime.animation == &D_06001FD0 && + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, csActionIndex); + if (D_80B915F0 == 2 && this->skelAnime.animation == &object_ma2_Anim_001FD0 && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { EnMaYto_ChangeAnim(this, 20); } @@ -1095,14 +1063,14 @@ void EnMaYto_SetupPostMilkRunWaitDialogueEnd(EnMaYto* this) { } void EnMaYto_PostMilkRunWaitDialogueEnd(EnMaYto* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 || func_80152498(&globalCtx->msgCtx) == 5) { - if (func_80147624(globalCtx) && func_80152498(&globalCtx->msgCtx) == 5) { + if (Message_GetState(&globalCtx->msgCtx) == 6 || Message_GetState(&globalCtx->msgCtx) == 5) { + if (Message_ShouldAdvance(globalCtx) && Message_GetState(&globalCtx->msgCtx) == 5) { func_800B7298(globalCtx, &this->actor, 7); func_801477B4(globalCtx); } } - if (func_80152498(&globalCtx->msgCtx) == 0 && globalCtx->msgCtx.unk120B1 == 0) { + if (Message_GetState(&globalCtx->msgCtx) == 0 && globalCtx->msgCtx.unk120B1 == 0) { EnMaYto_SetupPostMilkRunEnd(this); } } @@ -1127,56 +1095,56 @@ void EnMaYto_PostMilkRunEnd(EnMaYto* this, GlobalContext* globalCtx) { void EnMaYto_DefaultStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { if (CURRENT_DAY == 1) { - if (Player_GetMask(globalCtx) != PLAYER_MASK_NONE && gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (Player_GetMask(globalCtx) != PLAYER_MASK_NONE && gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { switch (Player_GetMask(globalCtx)) { - case PLAYER_MASK_ROMANIS_MASK: - func_801518B0(globalCtx, 0x235D, &this->actor); + case PLAYER_MASK_ROMANI: + Message_StartTextbox(globalCtx, 0x235D, &this->actor); this->textId = 0x235D; break; - case PLAYER_MASK_CIRCUS_LEADERS_MASK: + case PLAYER_MASK_CIRCUS_LEADER: EnMaYto_SetFaceExpression(this, 1, 3); - func_801518B0(globalCtx, 0x235E, &this->actor); + Message_StartTextbox(globalCtx, 0x235E, &this->actor); this->textId = 0x235E; break; case PLAYER_MASK_KAFEIS_MASK: EnMaYto_SetFaceExpression(this, 1, 2); - func_801518B0(globalCtx, 0x235F, &this->actor); + Message_StartTextbox(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; break; - case PLAYER_MASK_COUPLES_MASK: - func_801518B0(globalCtx, 0x2360, &this->actor); + case PLAYER_MASK_COUPLE: + Message_StartTextbox(globalCtx, 0x2360, &this->actor); this->textId = 0x2360; break; default: - func_801518B0(globalCtx, 0x2361, &this->actor); + Message_StartTextbox(globalCtx, 0x2361, &this->actor); this->textId = 0x2361; break; } } else { - if (EnMaYto_HasSpokeToPlayer()) { - func_801518B0(globalCtx, 0x3394, &this->actor); + if (EnMaYto_HasSpokenToPlayer()) { + Message_StartTextbox(globalCtx, 0x3394, &this->actor); this->textId = 0x3394; } else { EnMaYto_SetTalkedFlag(); // Asks the player if he came from town. - func_801518B0(globalCtx, 0x3390, &this->actor); + Message_StartTextbox(globalCtx, 0x3390, &this->actor); this->textId = 0x3390; } } } else if (CURRENT_DAY == 3) { - if (EnMaYto_HasSpokeToPlayerToday()) { + if (EnMaYto_HasSpokenToPlayerToday()) { EnMaYto_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x33C5, &this->actor); + Message_StartTextbox(globalCtx, 0x33C5, &this->actor); this->textId = 0x33C5; func_80151BB4(globalCtx, 6); } else { EnMaYto_SetTalkedFlag(); EnMaYto_SetFaceExpression(this, 0, 3); - func_801518B0(globalCtx, 0x33C4, &this->actor); + Message_StartTextbox(globalCtx, 0x33C4, &this->actor); this->textId = 0x33C4; func_80151BB4(globalCtx, 6); } @@ -1186,65 +1154,65 @@ void EnMaYto_DefaultStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { void EnMaYto_DinnerStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { switch (CURRENT_DAY) { case 1: - if (Player_GetMask(globalCtx) != PLAYER_MASK_NONE && gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + if (Player_GetMask(globalCtx) != PLAYER_MASK_NONE && gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { switch (Player_GetMask(globalCtx)) { - case PLAYER_MASK_ROMANIS_MASK: - func_801518B0(globalCtx, 0x235D, &this->actor); + case PLAYER_MASK_ROMANI: + Message_StartTextbox(globalCtx, 0x235D, &this->actor); this->textId = 0x235D; break; - case PLAYER_MASK_CIRCUS_LEADERS_MASK: - func_801518B0(globalCtx, 0x235E, &this->actor); + case PLAYER_MASK_CIRCUS_LEADER: + Message_StartTextbox(globalCtx, 0x235E, &this->actor); this->textId = 0x235E; break; case PLAYER_MASK_KAFEIS_MASK: - func_801518B0(globalCtx, 0x235F, &this->actor); + Message_StartTextbox(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; break; - case PLAYER_MASK_COUPLES_MASK: - func_801518B0(globalCtx, 0x2360, &this->actor); + case PLAYER_MASK_COUPLE: + Message_StartTextbox(globalCtx, 0x2360, &this->actor); this->textId = 0x2360; break; default: - func_801518B0(globalCtx, 0x2361, &this->actor); + Message_StartTextbox(globalCtx, 0x2361, &this->actor); this->textId = 0x2361; break; } } else { - if (EnMaYto_HasSpokeToPlayer()) { - func_801518B0(globalCtx, 0x339F, &this->actor); + if (EnMaYto_HasSpokenToPlayer()) { + Message_StartTextbox(globalCtx, 0x339F, &this->actor); this->textId = 0x339F; } else { EnMaYto_SetTalkedFlag(); - func_801518B0(globalCtx, 0x3397, &this->actor); + Message_StartTextbox(globalCtx, 0x3397, &this->actor); this->textId = 0x3397; } } break; case 2: - if (EnMaYto_HasSpokeToPlayer()) { - func_801518B0(globalCtx, 0x33A6, &this->actor); + if (EnMaYto_HasSpokenToPlayer()) { + Message_StartTextbox(globalCtx, 0x33A6, &this->actor); this->textId = 0x33A6; func_80151BB4(globalCtx, 6); } else { EnMaYto_SetTalkedFlag(); - func_801518B0(globalCtx, 0x33A5, &this->actor); + Message_StartTextbox(globalCtx, 0x33A5, &this->actor); this->textId = 0x33A5; } break; case 3: - if (EnMaYto_HasSpokeToPlayer()) { - func_801518B0(globalCtx, 0x33A8, &this->actor); + if (EnMaYto_HasSpokenToPlayer()) { + Message_StartTextbox(globalCtx, 0x33A8, &this->actor); this->textId = 0x33A8; func_80151BB4(globalCtx, 6); } else { EnMaYto_SetTalkedFlag(); - func_801518B0(globalCtx, 0x33A7, &this->actor); + Message_StartTextbox(globalCtx, 0x33A7, &this->actor); this->textId = 0x33A7; } break; @@ -1253,49 +1221,49 @@ void EnMaYto_DinnerStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { void EnMaYto_BarnStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { // if (AliensDefeated) - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { if (CURRENT_DAY == 2) { if (this->unk310 == 1) { - func_801518B0(globalCtx, 0x33AE, &this->actor); + Message_StartTextbox(globalCtx, 0x33AE, &this->actor); this->textId = 0x33AE; } else { this->unk310 = 1; EnMaYto_SetTalkedFlag(); - func_801518B0(globalCtx, 0x33A9, &this->actor); + Message_StartTextbox(globalCtx, 0x33A9, &this->actor); this->textId = 0x33A9; } } else if (CURRENT_DAY == 3) { if (this->unk310 == 1) { - func_801518B0(globalCtx, 0x33CB, &this->actor); + Message_StartTextbox(globalCtx, 0x33CB, &this->actor); this->textId = 0x33CB; } else { this->unk310 = 1; EnMaYto_SetTalkedFlag(); EnMaYto_SetFaceExpression(this, 0, 1); - func_801518B0(globalCtx, 0x33C6, &this->actor); + Message_StartTextbox(globalCtx, 0x33C6, &this->actor); this->textId = 0x33C6; } } } else { - if (EnMaYto_HasSpokeToPlayer()) { + if (EnMaYto_HasSpokenToPlayer()) { this->unk31E = 2; EnMaYto_SetFaceExpression(this, 5, 3); - func_801518B0(globalCtx, 0x33B3, &this->actor); + Message_StartTextbox(globalCtx, 0x33B3, &this->actor); this->textId = 0x33B3; func_80151BB4(globalCtx, 6); } else { EnMaYto_SetTalkedFlag(); EnMaYto_SetFaceExpression(this, 5, 3); - func_801518B0(globalCtx, 0x33B1, &this->actor); + Message_StartTextbox(globalCtx, 0x33B1, &this->actor); this->textId = 0x33B1; } } } void EnMaYto_ChangeAnim(EnMaYto* this, s32 index) { - Animation_Change(&this->skelAnime, sAnimationInfo[index].animationSeg, 1.0f, 0.0f, - Animation_GetLastFrame(sAnimationInfo[index].animationSeg), sAnimationInfo[index].mode, - sAnimationInfo[index].transitionRate); + Animation_Change(&this->skelAnime, sAnimationInfo[index].animation, 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationInfo[index].animation), sAnimationInfo[index].mode, + sAnimationInfo[index].morphFrames); } void func_80B90C78(EnMaYto* this, GlobalContext* globalCtx) { @@ -1376,7 +1344,7 @@ void EnMaYto_SetFaceExpression(EnMaYto* this, s16 overrideEyeTexIndex, s16 mouth } void EnMaYto_InitFaceExpression(EnMaYto* this) { - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { EnMaYto_SetFaceExpression(this, 0, 1); EnMaYto_SetRomaniFaceExpression(this, 0, 0); } else { @@ -1385,22 +1353,22 @@ void EnMaYto_InitFaceExpression(EnMaYto* this) { } } -s32 EnMaYto_HasSpokeToPlayerToday(void) { +s32 EnMaYto_HasSpokenToPlayerToday(void) { switch (CURRENT_DAY) { case 1: - if (gSaveContext.weekEventReg[0xD] & 0x4) { + if (gSaveContext.save.weekEventReg[13] & 4) { return true; } break; case 2: - if (gSaveContext.weekEventReg[0xD] & 0x8) { + if (gSaveContext.save.weekEventReg[13] & 8) { return true; } break; case 3: - if (gSaveContext.weekEventReg[0xD] & 0x10) { + if (gSaveContext.save.weekEventReg[13] & 0x10) { return true; } break; @@ -1408,21 +1376,21 @@ s32 EnMaYto_HasSpokeToPlayerToday(void) { return false; } -s32 EnMaYto_HasSpokeToPlayer(void) { +s32 EnMaYto_HasSpokenToPlayer(void) { // Please note each case doesn't have their respective `break`s. switch (CURRENT_DAY) { case 3: - if (gSaveContext.weekEventReg[0xD] & 0x10) { + if (gSaveContext.save.weekEventReg[13] & 0x10) { return true; } case 2: - if (gSaveContext.weekEventReg[0xD] & 0x8) { + if (gSaveContext.save.weekEventReg[13] & 8) { return true; } case 1: - if (gSaveContext.weekEventReg[0xD] & 0x4) { + if (gSaveContext.save.weekEventReg[13] & 4) { return true; } } @@ -1432,15 +1400,15 @@ s32 EnMaYto_HasSpokeToPlayer(void) { void EnMaYto_SetTalkedFlag(void) { switch (CURRENT_DAY) { case 1: - gSaveContext.weekEventReg[0xD] |= 0x4; + gSaveContext.save.weekEventReg[13] |= 4; break; case 2: - gSaveContext.weekEventReg[0xD] |= 0x8; + gSaveContext.save.weekEventReg[13] |= 8; break; case 3: - gSaveContext.weekEventReg[0xD] |= 0x10; + gSaveContext.save.weekEventReg[13] |= 0x10; break; } } @@ -1464,12 +1432,14 @@ s32 EnMaYto_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis rot->x += sp4.y; rot->z += sp4.x; } else if (limbIndex == MA2_LIMB_TORSO) { - if (this->skelAnime.animation != &D_06007E28 && this->skelAnime.animation != &D_06003D54) { + if (this->skelAnime.animation != &object_ma2_Anim_007E28 && + this->skelAnime.animation != &object_ma2_Anim_003D54) { sp4 = this->unk_1D8.unk_0E; rot->x += sp4.y; - if (this->skelAnime.animation == &D_0600A174 || this->skelAnime.animation == &D_060070EC || - this->skelAnime.animation == &D_06003D54) { + if (this->skelAnime.animation == &object_ma2_Anim_00A174 || + this->skelAnime.animation == &object_ma2_Anim_0070EC || + this->skelAnime.animation == &object_ma2_Anim_003D54) { rot->z += sp4.x; } } @@ -1481,7 +1451,7 @@ void EnMaYto_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, EnMaYto* this = THIS; if (limbIndex == MA2_LIMB_HEAD) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } } @@ -1490,9 +1460,9 @@ void EnMaYto_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 pad; OPEN_DISPS(globalCtx->state.gfxCtx); - if (this->type == MA_YTO_TYPE_BARN && (gSaveContext.weekEventReg[0x16] & 1)) { // Alieans defeated + if (this->type == MA_YTO_TYPE_BARN && (gSaveContext.save.weekEventReg[22] & 1)) { // Aliens defeated gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_06005430); + gSPDisplayList(POLY_OPA_DISP++, gCremiaWoodenBox); } func_8012C28C(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c b/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c index 266ba90e9..f5bf0625b 100644 --- a/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c +++ b/src/overlays/actors/ovl_En_Ma_Yts/z_en_ma_yts.c @@ -5,8 +5,9 @@ */ #include "z_en_ma_yts.h" +#include "objects/object_ma1/object_ma1.h" -#define FLAGS 0x02100009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((EnMaYts*)thisx) @@ -29,40 +30,6 @@ void EnMaYts_SetFaceExpression(EnMaYts* this, s16 overrideEyeTexIndex, s16 mouth void EnMaYts_DrawSleeping(Actor* thisx, GlobalContext* globalCtx); -extern AnimationHeader D_06009E58; -extern AnimationHeader D_06018948; -extern AnimationHeader D_0601B76C; -extern AnimationHeader D_06007328; -extern AnimationHeader D_06014088; -extern AnimationHeader D_06002A8C; -extern AnimationHeader D_06015B7C; -extern AnimationHeader D_06007D98; -extern AnimationHeader D_0600852C; -extern AnimationHeader D_06008F6C; -extern AnimationHeader D_060180DC; - -extern u64 D_060127C8[]; -extern u64 D_06012BC8[]; -extern u64 D_06012FC8[]; -extern u64 D_060133C8[]; - -extern u64 D_0600FFC8[]; -extern u64 D_060107C8[]; -extern u64 D_06010FC8[]; -extern u64 D_060117C8[]; -extern u64 D_06011FC8[]; - -extern FlexSkeletonHeader D_06013928; - -extern AnimationHeader D_06009E58; -extern AnimationHeader D_06007D98; - -// Bow -extern Gfx D_060003B0[]; - -// Sleeping -extern Gfx D_060043A0[]; - const ActorInit En_Ma_Yts_InitVars = { ACTOR_EN_MA_YTS, ACTORCAT_NPC, @@ -111,35 +78,46 @@ static CollisionCheckInfoInit2 sColChkInfoInit2 = { 0, 0, 0, 0, MASS_IMMOVABLE, }; -static struct_80B8E1A8 sAnimationInfo[] = { - { &D_06009E58, 1.0f, 0, 0.0f }, { &D_06009E58, 1.0f, 0, -6.0f }, // Idle anim - { &D_06018948, 1.0f, 2, 0.0f }, { &D_06018948, 1.0f, 2, -6.0f }, // Starts holding hands anim - { &D_0601B76C, 1.0f, 0, 0.0f }, { &D_0601B76C, 1.0f, 0, -6.0f }, // Holnding hands anim - { &D_06007328, 1.0f, 0, 0.0f }, { &D_06007328, 1.0f, 0, -6.0f }, // Walking anim - { &D_06014088, 1.0f, 0, 0.0f }, { &D_06014088, 1.0f, 0, -6.0f }, // - { &D_06002A8C, 1.0f, 0, 0.0f }, { &D_06002A8C, 1.0f, 0, -6.0f }, // Looking around anim - { &D_06015B7C, 1.0f, 0, 0.0f }, { &D_06015B7C, 1.0f, 0, -6.0f }, // Shoot arrow anim - { &D_06007D98, 1.0f, 0, 0.0f }, { &D_06007D98, 1.0f, 0, -6.0f }, // Sitting anim - { &D_0600852C, 1.0f, 0, 0.0f }, { &D_0600852C, 1.0f, 0, -6.0f }, // Sitting traumatized anim - { &D_06008F6C, 1.0f, 0, 0.0f }, { &D_06008F6C, 1.0f, 0, -6.0f }, // Sitting sad anim - { &D_060180DC, 1.0f, 2, 0.0f }, { &D_060180DC, 1.0f, 2, -6.0f }, // Turns around anim +static AnimationSpeedInfo sAnimationInfo[] = { + { &object_ma1_Anim_009E58, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_009E58, 1.0f, ANIMMODE_LOOP, -6.0f }, // Idle anim + { &object_ma1_Anim_018948, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_ma1_Anim_018948, 1.0f, ANIMMODE_ONCE, -6.0f }, // Starts holding hands anim + { &object_ma1_Anim_01B76C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_01B76C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Holnding hands anim + { &object_ma1_Anim_007328, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_007328, 1.0f, ANIMMODE_LOOP, -6.0f }, // Walking anim + { &object_ma1_Anim_014088, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_014088, 1.0f, ANIMMODE_LOOP, -6.0f }, // + { &object_ma1_Anim_002A8C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_002A8C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Looking around anim + { &object_ma1_Anim_015B7C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_015B7C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Shoot arrow anim + { &object_ma1_Anim_007D98, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_007D98, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting anim + { &object_ma1_Anim_00852C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_00852C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting traumatized anim + { &object_ma1_Anim_008F6C, 1.0f, ANIMMODE_LOOP, 0.0f }, + { &object_ma1_Anim_008F6C, 1.0f, ANIMMODE_LOOP, -6.0f }, // Sitting sad anim + { &object_ma1_Anim_0180DC, 1.0f, ANIMMODE_ONCE, 0.0f }, + { &object_ma1_Anim_0180DC, 1.0f, ANIMMODE_ONCE, -6.0f }, // Turns around anim }; -static void* sMouthTextures[] = { - D_060127C8, - D_06012BC8, - D_06012FC8, - D_060133C8, +static TexturePtr sMouthTextures[] = { + object_ma1_Tex_0127C8, + object_ma1_Tex_012BC8, + object_ma1_Tex_012FC8, + object_ma1_Tex_0133C8, }; -static void* sEyeTextures[] = { - D_0600FFC8, D_060107C8, D_06010FC8, D_060117C8, D_06011FC8, +static TexturePtr sEyeTextures[] = { + object_ma1_Tex_00FFC8, object_ma1_Tex_0107C8, object_ma1_Tex_010FC8, object_ma1_Tex_0117C8, object_ma1_Tex_011FC8, }; void EnMaYts_ChangeAnim(EnMaYts* this, s32 index) { - Animation_Change(&this->skelAnime, sAnimationInfo[index].animationSeg, 1.0f, 0.0f, - Animation_GetLastFrame(sAnimationInfo[index].animationSeg), sAnimationInfo[index].mode, - sAnimationInfo[index].transitionRate); + Animation_Change(&this->skelAnime, sAnimationInfo[index].animation, 1.0f, 0.0f, + Animation_GetLastFrame(sAnimationInfo[index].animation), sAnimationInfo[index].mode, + sAnimationInfo[index].morphFrames); } void func_80B8D12C(EnMaYts* this, GlobalContext* globalCtx) { @@ -167,7 +145,7 @@ void EnMaYts_InitAnimation(EnMaYts* this, GlobalContext* globalCtx) { case MA_YTS_TYPE_SITTING: this->actor.targetMode = 6; // Day 1 or "Winning" the alien invasion - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { EnMaYts_ChangeAnim(this, 14); } else { EnMaYts_ChangeAnim(this, 18); @@ -200,14 +178,14 @@ s32 EnMaYts_CheckValidSpawn(EnMaYts* this, GlobalContext* globalCtx) { case 2: // Failing the alien invasion - if (!(gSaveContext.weekEventReg[0x16] & 1)) { + if (!(gSaveContext.save.weekEventReg[22] & 1)) { return false; } break; case 3: // "Winning" the alien invasion - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { return false; } break; @@ -216,16 +194,16 @@ s32 EnMaYts_CheckValidSpawn(EnMaYts* this, GlobalContext* globalCtx) { case MA_YTS_TYPE_BARN: // Failing the alien invasion - if (!(gSaveContext.weekEventReg[0x16] & 1)) { + if (!(gSaveContext.save.weekEventReg[22] & 1)) { return false; - } else if (gSaveContext.time >= CLOCK_TIME(20, 0) && CURRENT_DAY == 3) { + } else if (gSaveContext.save.time >= CLOCK_TIME(20, 0) && CURRENT_DAY == 3) { return false; } break; case MA_YTS_TYPE_SLEEPING: // "Winning" the alien invasion - if (gSaveContext.weekEventReg[0x16] & 1) { + if (gSaveContext.save.weekEventReg[22] & 1) { return false; } break; @@ -245,8 +223,9 @@ void EnMaYts_Init(Actor* thisx, GlobalContext* globalCtx) { if (!EnMaYts_CheckValidSpawn(this, globalCtx)) { Actor_MarkForDeath(&this->actor); } - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 18.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, NULL, this->jointTable, this->morphTable, + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 18.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ma1_Skel_013928, NULL, this->jointTable, this->morphTable, MA1_LIMB_MAX); EnMaYts_InitAnimation(this, globalCtx); @@ -271,7 +250,7 @@ void EnMaYts_Init(Actor* thisx, GlobalContext* globalCtx) { this->hasBow = false; } - if (CURRENT_DAY == 1 || (gSaveContext.weekEventReg[0x16] & 1)) { + if (CURRENT_DAY == 1 || (gSaveContext.save.weekEventReg[22] & 1)) { this->overrideEyeTexIndex = 0; this->eyeTexIndex = 0; this->mouthTexIndex = 0; @@ -289,7 +268,7 @@ void EnMaYts_Init(Actor* thisx, GlobalContext* globalCtx) { this->mouthTexIndex = 0; this->unk_32C = 2; EnMaYts_SetupEndCreditsHandler(this); - } else if (CURRENT_DAY == 2 && gSaveContext.isNight == 1 && (gSaveContext.weekEventReg[0x16] & 1)) { + } else if (CURRENT_DAY == 2 && gSaveContext.save.isNight == 1 && (gSaveContext.save.weekEventReg[22] & 1)) { EnMaYts_SetupStartDialogue(this); } else { EnMaYts_SetupDoNothing(this); @@ -317,48 +296,48 @@ void EnMaYts_SetupStartDialogue(EnMaYts* this) { void EnMaYts_StartDialogue(EnMaYts* this, GlobalContext* globalCtx) { s16 sp26 = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; - if (func_800B84D0(&this->actor, globalCtx)) { // if (Actor_IsTalking) - if (!(gSaveContext.playerForm == PLAYER_FORM_HUMAN)) { - if (!(gSaveContext.weekEventReg[0x41] & 0x80)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (!(gSaveContext.save.playerForm == PLAYER_FORM_HUMAN)) { + if (!(gSaveContext.save.weekEventReg[65] & 0x80)) { // Saying to non-human Link: "Cremia went to town." - gSaveContext.weekEventReg[0x41] |= 0x80; + gSaveContext.save.weekEventReg[65] |= 0x80; EnMaYts_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x335F, &this->actor); + Message_StartTextbox(globalCtx, 0x335F, &this->actor); this->textId = 0x335F; } else { // Saying to non-human Link: "Pretend you did not hear that." EnMaYts_SetFaceExpression(this, 4, 3); - func_801518B0(globalCtx, 0x3362, &this->actor); + Message_StartTextbox(globalCtx, 0x3362, &this->actor); this->textId = 0x3362; func_80151BB4(globalCtx, 5); } } else if (Player_GetMask(globalCtx) != PLAYER_MASK_NONE) { - if (!(gSaveContext.weekEventReg[0x41] & 0x40)) { - gSaveContext.weekEventReg[0x41] |= 0x40; + if (!(gSaveContext.save.weekEventReg[65] & 0x40)) { + gSaveContext.save.weekEventReg[65] |= 0x40; EnMaYts_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x3363, &this->actor); + Message_StartTextbox(globalCtx, 0x3363, &this->actor); this->textId = 0x3363; } else { EnMaYts_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x3366, &this->actor); + Message_StartTextbox(globalCtx, 0x3366, &this->actor); this->textId = 0x3366; func_80151BB4(globalCtx, 5); } - } else if (!(gSaveContext.weekEventReg[0x15] & 0x20)) { + } else if (!(gSaveContext.save.weekEventReg[21] & 0x20)) { EnMaYts_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x3367, &this->actor); + Message_StartTextbox(globalCtx, 0x3367, &this->actor); this->textId = 0x3367; } else { - if (!(gSaveContext.weekEventReg[0x41] & 0x20)) { + if (!(gSaveContext.save.weekEventReg[65] & 0x20)) { // Saying to Grasshopper: "Cremia went to town." - gSaveContext.weekEventReg[0x41] |= 0x20; + gSaveContext.save.weekEventReg[65] |= 0x20; EnMaYts_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x3369, &this->actor); + Message_StartTextbox(globalCtx, 0x3369, &this->actor); this->textId = 0x3369; } else { // Saying to Grasshopper: "You're our bodyguard." EnMaYts_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x336C, &this->actor); + Message_StartTextbox(globalCtx, 0x336C, &this->actor); this->textId = 0x336C; func_80151BB4(globalCtx, 5); } @@ -374,13 +353,13 @@ void EnMaYts_SetupDialogueHandler(EnMaYts* this) { } void EnMaYts_DialogueHandler(EnMaYts* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 5: // End message block EnMaYts_ChooseNextDialogue(this, globalCtx); break; case 6: // End conversation - if (func_80147624(globalCtx) != 0) { + if (Message_ShouldAdvance(globalCtx)) { EnMaYts_SetupStartDialogue(this); } break; @@ -395,21 +374,21 @@ void EnMaYts_DialogueHandler(EnMaYts* this, GlobalContext* globalCtx) { } void EnMaYts_SetupEndCreditsHandler(EnMaYts* this) { - this->actor.flags |= 0x10; + this->actor.flags |= ACTOR_FLAG_10; EnMaYts_SetFaceExpression(this, 0, 0); this->actionFunc = EnMaYts_EndCreditsHandler; } static u16 D_80B8E32C = 99; void EnMaYts_EndCreditsHandler(EnMaYts* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, 0x78) != 0) { - u32 actionIndex = func_800EE200(globalCtx, 0x78); + if (Cutscene_CheckActorAction(globalCtx, 120)) { + s32 actionIndex = Cutscene_GetActorActionIndex(globalCtx, 120); - if (globalCtx->csCtx.frames == globalCtx->csCtx.npcActions[actionIndex]->startFrame) { - if (globalCtx->csCtx.npcActions[actionIndex]->unk0 != D_80B8E32C) { - D_80B8E32C = globalCtx->csCtx.npcActions[actionIndex]->unk0; + if (globalCtx->csCtx.frames == globalCtx->csCtx.actorActions[actionIndex]->startFrame) { + if (globalCtx->csCtx.actorActions[actionIndex]->action != D_80B8E32C) { + D_80B8E32C = globalCtx->csCtx.actorActions[actionIndex]->action; this->endCreditsFlag = 0; - switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: this->hasBow = true; EnMaYts_ChangeAnim(this, 0); @@ -433,9 +412,9 @@ void EnMaYts_EndCreditsHandler(EnMaYts* this, GlobalContext* globalCtx) { } } - func_800EDF24(&this->actor, globalCtx, actionIndex); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); if ((D_80B8E32C == 2) && (this->endCreditsFlag == 0) && - (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) != 0)) { + Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->endCreditsFlag++; EnMaYts_ChangeAnim(this, 5); } @@ -447,50 +426,50 @@ void EnMaYts_EndCreditsHandler(EnMaYts* this, GlobalContext* globalCtx) { // Select the following dialogue based on the current one, and an appropiate face expression void EnMaYts_ChooseNextDialogue(EnMaYts* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx) != 0) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x335F: EnMaYts_SetFaceExpression(this, 0, 2); - func_801518B0(globalCtx, 0x3360, &this->actor); + Message_StartTextbox(globalCtx, 0x3360, &this->actor); this->textId = 0x3360; break; case 0x3360: EnMaYts_SetFaceExpression(this, 4, 3); - func_801518B0(globalCtx, 0x3361, &this->actor); + Message_StartTextbox(globalCtx, 0x3361, &this->actor); this->textId = 0x3361; func_80151BB4(globalCtx, 5); break; case 0x3363: EnMaYts_SetFaceExpression(this, 1, 1); - func_801518B0(globalCtx, 0x3364, &this->actor); + Message_StartTextbox(globalCtx, 0x3364, &this->actor); this->textId = 0x3364; break; case 0x3364: EnMaYts_SetFaceExpression(this, 4, 2); - func_801518B0(globalCtx, 0x3365, &this->actor); + Message_StartTextbox(globalCtx, 0x3365, &this->actor); this->textId = 0x3365; func_80151BB4(globalCtx, 5); break; case 0x3367: EnMaYts_SetFaceExpression(this, 4, 3); - func_801518B0(globalCtx, 0x3368, &this->actor); + Message_StartTextbox(globalCtx, 0x3368, &this->actor); this->textId = 0x3368; func_80151BB4(globalCtx, 5); break; case 0x3369: EnMaYts_SetFaceExpression(this, 0, 0); - func_801518B0(globalCtx, 0x336A, &this->actor); + Message_StartTextbox(globalCtx, 0x336A, &this->actor); this->textId = 0x336A; break; case 0x336A: EnMaYts_SetFaceExpression(this, 3, 3); - func_801518B0(globalCtx, 0x336B, &this->actor); + Message_StartTextbox(globalCtx, 0x336B, &this->actor); this->textId = 0x336B; func_80151BB4(globalCtx, 5); break; @@ -522,14 +501,16 @@ void EnMaYts_Update(Actor* thisx, GlobalContext* globalCtx) { func_80B8D12C(this, globalCtx); } -s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnMaYts* this = (EnMaYts*)arg; +s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnMaYts* this = THIS; Vec3s sp4; if (limbIndex == MA1_LIMB_HEAD) { sp4 = this->unk_1D8.unk_08; rot->x += sp4.y; - if ((this->skelAnime.animation == &D_06009E58) || (this->skelAnime.animation == &D_06007D98)) { + if ((this->skelAnime.animation == &object_ma1_Anim_009E58) || + (this->skelAnime.animation == &object_ma1_Anim_007D98)) { rot->z += sp4.x; } } else if (limbIndex == MA1_LIMB_TORSO) { @@ -538,18 +519,18 @@ s32 EnMaYts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis rot->z += sp4.x; } - return 0; + return false; } -void EnMaYts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnMaYts* this = (EnMaYts*)arg; +void EnMaYts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMaYts* this = THIS; if (limbIndex == MA1_LIMB_HEAD) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } else if (limbIndex == MA1_LIMB_HAND_LEFT) { if (this->hasBow == true) { OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_060003B0); + gSPDisplayList(POLY_OPA_DISP++, object_ma1_DL_0003B0); CLOSE_DISPS(globalCtx->state.gfxCtx); } } @@ -576,7 +557,7 @@ void EnMaYts_DrawSleeping(Actor* thisx, GlobalContext* globalCtx) { 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_060043A0); + gSPDisplayList(POLY_OPA_DISP++, object_ma1_DL_0043A0); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.c b/src/overlays/actors/ovl_En_Mag/z_en_mag.c index 3fdf1766a..907ba619b 100644 --- a/src/overlays/actors/ovl_En_Mag/z_en_mag.c +++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.c @@ -1,6 +1,13 @@ -#include "z_en_mag.h" +/* + * File: z_en_mag.c + * Overlay: ovl_En_Mag + * Description: Title Logo + */ -#define FLAGS 0x00000030 +#include "z_en_mag.h" +#include "objects/object_mag/object_mag.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnMag*)thisx) @@ -9,7 +16,75 @@ void EnMag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMag_Update(Actor* thisx, GlobalContext* globalCtx); void EnMag_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +/** + * Steps `var` towards `target` linearly, so that it will arrive in `timeRemaining` seconds. Can be used from either + * direction. `timeRemaining` must be decremented separately for this to work properly, and obviously timeRemaining = 0 + * must be handled separately. + * + * @param var Variable to step. + * @param target Target to step towards. + * @param timeRemaining Number of times this function should be run for `var` to reach `target` + * @param stepVar Variable to use for the step (required to match). + * + * The progression is not quite linear because of truncation in the division, but the variable will always reach + * `target` at the appropriate time since the last step is always the full difference. + */ +#define TIMED_STEP_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + if (var >= target) { \ + var -= stepVar; \ + } else { \ + var += stepVar; \ + } \ + } \ + (void)0 + +/** + * Similar to `TIMED_STEP_TO`, but will always increase `var`. If var > target, this will eventually increase `var` by + * an amount that is at most ( timeRemaining + 1 ) * | var - target |, but which depends on the amount lost to + * truncation from the divisions. + */ +#define TIMED_STEP_UP_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + var += stepVar; \ + } \ + (void)0 + +/** + * Similar to `TIMED_STEP_TO`, but will always increase `var`. If var < target, this will eventually dncrease `var` by + * an amount that is at most ( timeRemaining + 1 ) * | var - target |, but which depends on the amount lost to + * truncation from the divisions. + */ +#define TIMED_STEP_DOWN_TO(var, target, timeRemaining, stepVar) \ + { \ + stepVar = ABS_ALT(var - target) / timeRemaining; \ + var -= stepVar; \ + } \ + (void)0 + +typedef enum { + /* 0 */ MAG_STATE_INITIAL, + /* 1 */ MAG_STATE_FADE_IN_MASK_EFFECTS, + /* 2 */ MAG_STATE_FADE_IN_MASK, + /* 3 */ MAG_STATE_FADE_IN_MAIN_TITLE, + /* 5 */ MAG_STATE_FADE_IN_SUBTITLE = 5, + /* 6 */ MAG_STATE_FADE_IN_COPYRIGHT, // And PRESS START + /* 10 */ MAG_STATE_CALLED = 10, // by a button press + /* 13 */ MAG_STATE_DISPLAY = 13, // Buttons will trigger File Select state + /* 20 */ MAG_STATE_FADE_OUT = 20, + /* 21 */ MAG_STATE_POST_DISPLAY // Go to next scene +} EnMagState; + +static s16 sInputDelayTimer = 0; + +static s16 sZeldaEffectColorTimer = 30; +static s16 sZeldaEffectColorTargetIndex = 0; + +static s16 sTextAlphaTargetIndex = 0; +static s16 sTextAlphaTimer = 20; + const ActorInit En_Mag_InitVars = { ACTOR_EN_MAG, ACTORCAT_PROP, @@ -22,28 +97,878 @@ const ActorInit En_Mag_InitVars = { (ActorFunc)EnMag_Draw, }; -#endif +void EnMag_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMag* this = THIS; + u16 i; -extern UNK_TYPE D_06011E48; + this->unk11F54 = 6; + this->unk11F56 = 10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Init.s") + for (i = 0; i < 6; i++) { + this->effectScrollSs[i] = 0; + this->effectScrollTs[i] = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Destroy.s") + this->appearEffectPrimColor[0] = 255; + this->appearEffectPrimColor[1] = 155; + this->appearEffectPrimColor[2] = 255; + this->appearEffectEnvColor[0] = 0; + this->appearEffectEnvColor[1] = 255; + this->appearEffectEnvColor[2] = 155; + this->appearEffectPrimLodFrac = 20; + this->appearEffectAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096B604.s") + this->displayEffectPrimColor[0] = 255; + this->displayEffectPrimColor[1] = 155; + this->displayEffectPrimColor[2] = 255; + this->displayEffectEnvColor[0] = 0; + this->displayEffectEnvColor[1] = 255; + this->displayEffectEnvColor[2] = 155; + this->displayEffectPrimLodFrac = 55; + this->displayEffectAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Update.s") + this->majorasMaskAlpha = 0; + this->majorasMaskEnvColor[0] = this->majorasMaskEnvColor[1] = this->majorasMaskEnvColor[2] = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096C998.s") + this->mainTitleAlpha = this->subtitleAlpha = this->unk11F32 = this->copyrightAlpha = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096CBB0.s") + this->unk11F02 = 30; + this->unk11F00 = this->state = MAG_STATE_INITIAL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096CDC8.s") + if (gSaveContext.unk_3F1E != 0) { + this->mainTitleAlpha = 210; + this->unk11F32 = 255; + this->copyrightAlpha = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D230.s") + this->appearEffectPrimLodFrac = 100; + this->appearEffectAlpha = 255; + this->appearEffectPrimColor[0] = 255; + this->appearEffectPrimColor[1] = 255; + this->appearEffectPrimColor[2] = 255; + this->appearEffectEnvColor[0] = 0; + this->appearEffectEnvColor[1] = 255; + this->appearEffectEnvColor[2] = 155; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D60C.s") + this->displayEffectPrimLodFrac = 100; + this->displayEffectAlpha = 255; + this->displayEffectPrimColor[0] = 255; + this->displayEffectPrimColor[1] = 255; + this->displayEffectPrimColor[2] = 255; + this->displayEffectEnvColor[0] = 0; + this->displayEffectEnvColor[1] = 255; + this->displayEffectEnvColor[2] = 155; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/func_8096D74C.s") + gSaveContext.unk_3F1E = 0; + this->state = MAG_STATE_FADE_IN_MASK; + sInputDelayTimer = 20; + gSaveContext.fadeDuration = 1; + gSaveContext.fadeSpeed = 255; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mag/EnMag_Draw.s") + Font_LoadOrderedFont(&this->font); + + this->unk11F58 = 0; + this->unk11F5A = 0; + this->unk11F5C = 0; + this->unk11F60 = 0; + + this->majorasMaskEffectsFadeInTimer = 25; + this->majorasMaskFadeInTimer = 25; + this->mainTitleAlphaFadeInTimer = 20; + this->effectAlphaFadeInTimer = 40; + this->subtitleFadeInTimer = 10; + this->copyrightFadeInTimer = 10; + this->fadeOutTimer = 15; + + sZeldaEffectColorTimer = 30; + sZeldaEffectColorTargetIndex = 0; +} + +void EnMag_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnMag_UpdateDisplayEffectColors(Actor* thisx) { + static s16 sDisplayEffectPrimRedTargets[] = { 155, 255 }; + static s16 sDisplayEffectPrimGreenTargets[] = { 255, 155 }; + static s16 sDisplayEffectPrimBlueTargets[] = { 55, 255 }; + static s16 sDisplayEffectEnvRedTargets[] = { 255, 0 }; + static s16 sDisplayEffectEnvBlueTargets[] = { 255, 155 }; + EnMag* this = THIS; + s16 colorStep; + + TIMED_STEP_TO(this->displayEffectPrimColor[0], sDisplayEffectPrimRedTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectPrimColor[1], sDisplayEffectPrimGreenTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectPrimColor[2], sDisplayEffectPrimBlueTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + TIMED_STEP_TO(this->displayEffectEnvColor[0], sDisplayEffectEnvRedTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + // Skips 1, i.e. green. + TIMED_STEP_TO(this->displayEffectEnvColor[2], sDisplayEffectEnvBlueTargets[sZeldaEffectColorTargetIndex], + sZeldaEffectColorTimer, colorStep); + + sZeldaEffectColorTimer--; + if (sZeldaEffectColorTimer == 0) { + this->displayEffectPrimColor[0] = sDisplayEffectPrimRedTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectPrimColor[1] = sDisplayEffectPrimGreenTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectPrimColor[2] = sDisplayEffectPrimBlueTargets[sZeldaEffectColorTargetIndex]; + this->displayEffectEnvColor[0] = sDisplayEffectEnvRedTargets[sZeldaEffectColorTargetIndex]; + // Skips 1, i.e. green. + this->displayEffectEnvColor[2] = sDisplayEffectEnvBlueTargets[sZeldaEffectColorTargetIndex]; + sZeldaEffectColorTimer = 30; + sZeldaEffectColorTargetIndex ^= 1; + } +} + +/** + * Controls the actions performed using a switch and the `state` struct variable rather than action functions. Most of + * these are to do with fading various parts in and out. + */ +void EnMag_Update(Actor* thisx, GlobalContext* globalCtx) { + static s16 sAppearEffectPrimGreenTargets[] = { 255, 155 }; + static s16 sAppearEffectEnvRedTargets[] = { 255, 0 }; + static s16 sAppearEffectEnvBlueTargets[] = { 0, 155 }; + s16 step; + s32 pad[2]; + EnMag* this = THIS; + + if (gSaveContext.fileNum != 0xFEDC) { + if (this->state == MAG_STATE_INITIAL) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + + if (!EnvFlags_Get(globalCtx, 4)) { + play_sound(NA_SE_SY_PIECE_OF_HEART); + this->state = MAG_STATE_CALLED; + this->unk11F00 = 0; + this->unk11F02 = 30; + sInputDelayTimer = 20; + gSaveContext.fadeDuration = 1; + gSaveContext.fadeSpeed = 255; + } + } + } else { + switch (this->state) { + case MAG_STATE_FADE_IN_MASK_EFFECTS: + TIMED_STEP_TO(this->appearEffectPrimColor[1], sAppearEffectPrimGreenTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[0], sAppearEffectEnvRedTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[2], sAppearEffectEnvBlueTargets[0], + this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectAlpha, 255, this->majorasMaskEffectsFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectPrimLodFrac, 32, this->majorasMaskEffectsFadeInTimer, step); + + this->majorasMaskEffectsFadeInTimer--; + if (this->majorasMaskEffectsFadeInTimer == 0) { + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[0]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[0]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[0]; + this->appearEffectAlpha = 255; + this->state = MAG_STATE_FADE_IN_MASK; + this->delayTimer = 5; + } + break; + + case MAG_STATE_FADE_IN_MASK: + if (this->delayTimer == 0) { + TIMED_STEP_TO(this->appearEffectPrimColor[1], sAppearEffectPrimGreenTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[0], sAppearEffectEnvRedTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_TO(this->appearEffectEnvColor[2], sAppearEffectEnvBlueTargets[1], + this->majorasMaskFadeInTimer, step); + TIMED_STEP_UP_TO(this->appearEffectPrimLodFrac, 128, this->majorasMaskFadeInTimer, step); + TIMED_STEP_UP_TO(this->majorasMaskAlpha, 255, this->majorasMaskFadeInTimer, step); + + this->majorasMaskFadeInTimer--; + if (this->majorasMaskFadeInTimer == 0) { + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[1]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[1]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[1]; + this->appearEffectPrimLodFrac = 128; + this->majorasMaskAlpha = 255; + this->state = MAG_STATE_FADE_IN_MAIN_TITLE; + this->delayTimer = 5; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_MAIN_TITLE: + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->mainTitleAlpha, 255, this->mainTitleAlphaFadeInTimer, step); + + this->mainTitleAlphaFadeInTimer--; + if (this->mainTitleAlphaFadeInTimer == 0) { + this->mainTitleAlphaFadeInTimer = 1; + this->mainTitleAlpha = 255; + } + + TIMED_STEP_DOWN_TO(this->appearEffectAlpha, 60, this->effectAlphaFadeInTimer, step); + TIMED_STEP_UP_TO(this->displayEffectAlpha, 255, this->effectAlphaFadeInTimer, step); + TIMED_STEP_UP_TO(this->displayEffectPrimLodFrac, 128, this->effectAlphaFadeInTimer, step); + + this->effectAlphaFadeInTimer--; + + if (this->effectAlphaFadeInTimer == 0) { + this->appearEffectAlpha = 60; + this->displayEffectAlpha = 255; + this->displayEffectPrimLodFrac = 128; + this->state = MAG_STATE_FADE_IN_SUBTITLE; + this->delayTimer = 20; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_SUBTITLE: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->subtitleAlpha, 255, this->subtitleFadeInTimer, step); + + this->subtitleFadeInTimer--; + if (this->subtitleFadeInTimer == 0) { + this->displayEffectAlpha = 255; + this->state = MAG_STATE_FADE_IN_COPYRIGHT; + this->delayTimer = 20; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_FADE_IN_COPYRIGHT: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (this->delayTimer == 0) { + TIMED_STEP_UP_TO(this->copyrightAlpha, 255, this->copyrightFadeInTimer, step); + + this->copyrightFadeInTimer--; + if (this->copyrightFadeInTimer == 0) { + this->copyrightAlpha = 255; + this->state = MAG_STATE_DISPLAY; + } + } else { + this->delayTimer--; + } + break; + + case MAG_STATE_CALLED: + this->appearEffectPrimColor[1] = sAppearEffectPrimGreenTargets[0]; + this->appearEffectEnvColor[0] = sAppearEffectEnvRedTargets[0]; + this->appearEffectEnvColor[2] = sAppearEffectEnvBlueTargets[0]; + this->appearEffectAlpha = 60; + this->appearEffectPrimLodFrac = 128; + this->majorasMaskAlpha = 255; + this->mainTitleAlpha = 255; + this->displayEffectAlpha = 255; + this->displayEffectPrimLodFrac = 128; + this->subtitleAlpha = 255; + this->copyrightAlpha = 255; + this->state = MAG_STATE_DISPLAY; + break; + + case MAG_STATE_DISPLAY: + EnMag_UpdateDisplayEffectColors(&this->actor); + + if (sInputDelayTimer == 0) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + if (globalCtx->sceneLoadFlag != 0x14) { + Audio_SetCutsceneFlag(false); + D_801BB12C++; + if (D_801BB12C >= 2) { + D_801BB12C = 0; + } + play_sound(NA_SE_SY_PIECE_OF_HEART); + gSaveContext.gameMode = 2; // Go to FileChoose + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + globalCtx->nextEntranceIndex = 0x1C00; + gSaveContext.save.cutscene = 0; + gSaveContext.sceneSetupIndex = 0; + } + this->unk11F54 = 15; + this->unk11F56 = 25; + this->state = MAG_STATE_FADE_OUT; + } + } else { + sInputDelayTimer--; + } + break; + + case MAG_STATE_FADE_OUT: + TIMED_STEP_DOWN_TO(this->appearEffectAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->majorasMaskAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->displayEffectAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->mainTitleAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->subtitleAlpha, 0, this->fadeOutTimer, step); + TIMED_STEP_DOWN_TO(this->copyrightAlpha, 0, this->fadeOutTimer, step); + + this->fadeOutTimer--; + if (this->fadeOutTimer == 0) { + this->appearEffectAlpha = 0; + this->majorasMaskAlpha = 0; + this->mainTitleAlpha = 0; + this->subtitleAlpha = 0; + this->displayEffectAlpha = 0; + this->copyrightAlpha = 0; + this->state = MAG_STATE_POST_DISPLAY; + } + break; + } + + // Appear fully immediately if called during fade-in states. + if ((this->state > MAG_STATE_INITIAL) && (this->state < MAG_STATE_CALLED)) { + if (CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_START) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_A) || + CHECK_BTN_ALL(CONTROLLER1(globalCtx)->press.button, BTN_B)) { + play_sound(NA_SE_SY_PIECE_OF_HEART); + this->state = MAG_STATE_CALLED; + } + } + } + } + + if (this->state == MAG_STATE_INITIAL) { + if (EnvFlags_Get(globalCtx, 3)) { + this->unk11F02 = 40; + this->state = MAG_STATE_FADE_IN_MASK_EFFECTS; + } + } else if (this->state < MAG_STATE_FADE_OUT) { + if (EnvFlags_Get(globalCtx, 4)) { + this->state = MAG_STATE_FADE_OUT; + } + } +} + +/** + * Draws an i8 texture. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] texWidth Width of the texture. + * @param[in] texHeight Height of the texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawTextureI8(Gfx** gfxp, TexturePtr texture, s16 texWidth, s16 texHeight, s16 rectLeft, s16 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_I, G_IM_SIZ_8b, texWidth, texHeight, 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); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + texWidth) << 2, (rectTop + texHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an ia8 texture. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] texWidth Width of the texture. + * @param[in] texHeight Height of the texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawTextureIA8(Gfx** gfxp, TexturePtr texture, s16 texWidth, s16 texHeight, s16 rectLeft, s16 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock(gfx++, texture, G_IM_FMT_IA, G_IM_SIZ_8b, texWidth, texHeight, 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); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + texWidth) << 2, (rectTop + texHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an i8 effect texture, masking it with an i4 mask, with shifting + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] maskTex Texture with which to mask, i4. + * @param[in] effectTex Effect texture to draw, i8. + * @param[in] maskWidth Width of masking texture. + * @param[in] maskHeight Height of masking texture. + * @param[in] effectWidth Width of effect texture. + * @param[in] effectHeight Height of effect texture. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + * @param[in] shifts Shift to apply to effect texture's S coordinate to control LOD. + * @param[in] shiftt Shift to apply to effect texture's T coordinate to control LOD. + * @param[in] index Index into the scrolling arrays to use for gDPSetTileSize. + * @param[in] this Pointer to EnMag instance. + */ +void EnMag_DrawEffectTextures(Gfx** gfxp, TexturePtr maskTex, TexturePtr effectTex, s16 maskWidth, s16 maskHeight, + s16 effectWidth, s16 effectHeight, s16 rectLeft, s16 rectTop, u16 shifts, u16 shiftt, + u16 index, EnMag* this) { + Gfx* gfx = *gfxp; + + gDPLoadMultiBlock_4b(gfx++, maskTex, 0x0000, G_TX_RENDERTILE, G_IM_FMT_I, maskWidth, maskHeight, 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); + + gDPLoadMultiBlock(gfx++, effectTex, 0x0100, 1, G_IM_FMT_I, G_IM_SIZ_8b, effectWidth, effectHeight, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 5, 5, shifts, shiftt); + + gDPSetTileSize(gfx++, 1, this->effectScrollSs[index] & 0x7F, this->effectScrollTs[index] & 0x7F, + (this->effectScrollSs[index] & 0x7F) + 15, (this->effectScrollTs[index] & 0x7F) + 15); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + maskWidth) << 2, (rectTop + maskHeight) << 2, + G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + *gfxp = gfx; +} + +/** + * Draws an rgba32 texture. Because these are so large, this will draw the texture in horizontal stripes, each narrow + * enough that that part of the texture will fit into TMEM's 4kB. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] centerX X coordinate of the center of the draw position. + * @param[in] centerY Y coordinate of the center of the draw position. + * @param[in] source Texture to draw. + * @param[in] width Width of the texture. + * @param[in] height Height of the texture. + */ +void EnMag_DrawImageRGBA32(Gfx** gfxp, s16 centerX, s16 centerY, TexturePtr source, u32 width, u32 height) { + Gfx* gfx = *gfxp; + uintptr_t curTexture; + s32 textureCount; + u32 rectLeft; + u32 rectTop; + u32 textureHeight; + s32 remainingSize; + s32 textureSize; + s32 pad; + s32 i; + + func_8012CA0C(&gfx); + + curTexture = source; + rectLeft = centerX - (width / 2); + rectTop = centerY - (height / 2); + textureHeight = TMEM_SIZE / (width << 2); + remainingSize = (width * height) << 2; + textureSize = (width * textureHeight) << 2; + textureCount = remainingSize / textureSize; + if ((remainingSize % textureSize) != 0) { + textureCount++; + } + + gDPSetTileCustom(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, textureHeight, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + remainingSize -= textureSize; + + for (i = 0; i < textureCount; i++) { + gDPSetTextureImage(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, curTexture); + + gDPLoadSync(gfx++); + gDPLoadTile(gfx++, G_TX_LOADTILE, 0, 0, (width - 1) << 2, (textureHeight - 1) << 2); + + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + (s32)width) << 2, + (rectTop + textureHeight) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + + curTexture += textureSize; + rectTop += textureHeight; + + if ((remainingSize - textureSize) < 0) { + if (remainingSize > 0) { + textureHeight = remainingSize / (s32)(width << 2); + remainingSize -= textureSize; + + gDPSetTileCustom(gfx++, G_IM_FMT_RGBA, G_IM_SIZ_32b, width, textureHeight, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, + G_TX_NOLOD, G_TX_NOLOD); + } + } else { + remainingSize -= textureSize; + } + } + + *gfxp = gfx; +} + +/** + * Draws one character, expected to be a 16 by 16 i4 texture. It will draw shrunk to 10 by 10. + * + * @param[in,out] gfxp Pointer to current displaylist. + * @param[in] texture Texture to draw. + * @param[in] rectLeft X coordinate of the top-left of the draw position. + * @param[in] rectTop Y coordinate of the top-left of the draw position. + */ +void EnMag_DrawCharTexture(Gfx** gfxp, TexturePtr texture, s32 rectLeft, s32 rectTop) { + Gfx* gfx = *gfxp; + + gDPLoadTextureBlock_4b(gfx++, texture, G_IM_FMT_I, 16, 16, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); + + // The dsdx and dtdy are roughly 1.587 * 0x400, to fit the texture into 10 by 10 pixels. It is not the more + // obvious 1.6 * 0x400 = 1656. + gSPTextureRectangle(gfx++, rectLeft << 2, rectTop << 2, (rectLeft + 10) << 2, (rectTop + 10) << 2, G_TX_RENDERTILE, + 0, 0, 1625, 1625); + + *gfxp = gfx; +} + +#define EFFECT_MASK_TEX_WIDTH 64 +#define EFFECT_MASK_TEX_HEIGHT 64 +#define EFFECT_TEX_WIDTH 32 +#define EFFECT_TEX_HEIGHT 32 +#define EFFECT_TEX_LEFT 38 +#define EFFECT_TEX_TOP 57 + +#define MAJORAS_MASK_TEX_WIDTH 128 +#define MAJORAS_MASK_TEX_HEIGHT 112 +#define MAJORAS_MASK_TEX_CENTER_X 124 +#define MAJORAS_MASK_TEX_CENTER_Y 103 + +#define ZELDA_TEX_WIDTH 144 +#define ZELDA_TEX_HEIGHT 64 +#define ZELDA_TEX_CENTER_X 177 +#define ZELDA_TEX_CENTER_Y 105 + +#define SUBTITLE_TEX_WIDTH 104 +#define SUBTITLE_TEX_HEIGHT 16 +#define SUBTITLE_TEX_LEFT 151 +#define SUBTITLE_TEX_TOP 124 + +#define THE_LEGEND_OF_TEX_WIDTH 72 +#define THE_LEGEND_OF_TEX_HEIGHT 8 +#define THE_LEGEND_OF_TEX_LEFT 158 +#define THE_LEGEND_OF_TEX_TOP 71 + +#define COPYRIGHT_TEX_WIDTH 128 +#define COPYRIGHT_TEX_HEIGHT 16 +#define COPYRIGHT_TEX_LEFT 94 +#define COPYRIGHT_TEX_TOP 198 + +#define NO_CONTROLLER_FIRST_TEX_WIDTH 256 +#define NO_CONTROLLER_FIRST_TEX_HEIGHT 9 +#define NO_CONTROLLER_FIRST_TEX_LEFT 35 +#define NO_CONTROLLER_FIRST_TEX_TOP 175 + +#define NO_CONTROLLER_SECOND_TEX_WIDTH 144 +#define NO_CONTROLLER_SECOND_TEX_HEIGHT 9 +#define NO_CONTROLLER_SECOND_TEX_LEFT 91 +#define NO_CONTROLLER_SECOND_TEX_TOP 188 + +// Top-left of the text itself, not the shadow +#define PRESS_START_LEFT 119 +#define PRESS_START_TOP 174 +#define PRESS_START_CHAR_SPACING 7 // Amount of rightward shift before printing next char +#define PRESS_START_SPACE 5 // Extra space between the words + +/** + * Loads title, PRESS START text, etc. graphics to gfxp, which is made to live on + * POLY_OPA_DISP, but is used by OVERLAY_DISP. + */ +void EnMag_DrawInner(Actor* thisx, GlobalContext* globalCtx, Gfx** gfxp) { + static u8 pressStartFontIndices[] = { + 0x19, 0x1B, 0x0E, 0x1C, 0x1C, 0x1C, 0x1D, 0x0A, 0x1B, 0x1D, + }; // Indices into this->font.fontBuf + static TexturePtr sAppearEffectMaskTextures[] = { + gTitleScreenAppearEffectMask00Tex, gTitleScreenAppearEffectMask01Tex, gTitleScreenAppearEffectMask02Tex, + gTitleScreenAppearEffectMask10Tex, gTitleScreenAppearEffectMask11Tex, gTitleScreenAppearEffectMask12Tex, + }; // Visible when mask appearing + static TexturePtr sDisplayEffectMaskTextures[] = { + gTitleScreenDisplayEffectMask00Tex, gTitleScreenDisplayEffectMask01Tex, gTitleScreenDisplayEffectMask02Tex, + gTitleScreenDisplayEffectMask10Tex, gTitleScreenDisplayEffectMask11Tex, gTitleScreenDisplayEffectMask12Tex, + }; // Visible when full game logo displayed + static TexturePtr sEffectTextures[] = { + gTitleScreenFlame0Tex, gTitleScreenFlame1Tex, gTitleScreenFlame1Tex, + gTitleScreenFlame2Tex, gTitleScreenFlame3Tex, gTitleScreenFlame3Tex, + }; + static s16 sEffectScrollVelocitySs[] = { -1, 1, 1, -1, 1, 1 }; + static s16 sEffectScrollVelocityTs[] = { -2, -2, -2, 2, 2, 2 }; + static s16 sTextAlpha = 0; // For drawing both the No Controller message and "PRESS START" + static s16 sTextAlphaTargets[] = { 255, 0 }; + s32 pad; + EnMag* this = THIS; + Font* font = &this->font; + Gfx* gfx = *gfxp; + u16 i; + u16 j; + u16 k; + s32 rectLeft; + s32 rectTop; + s16 step; + + // Set segment 6 to the object, since this will be read by OVERLAY_DISP where it is not set by default. + gSPSegment(gfx++, 0x06, globalCtx->objectCtx.status[this->actor.objBankIndex].segment); + + func_8012C680(&gfx); + + // Mask appearing effects + gDPPipeSync(gfx++); + gDPSetCycleType(gfx++, G_CYC_2CYCLE); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + gDPSetRenderMode(gfx++, G_RM_PASS, G_RM_CLD_SURF2); + gDPSetCombineLERP(gfx++, TEXEL1, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL1, 1, PRIM_LOD_FRAC, TEXEL0, PRIMITIVE, + ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, this->appearEffectPrimLodFrac, this->appearEffectPrimColor[0], + this->appearEffectPrimColor[1], this->appearEffectPrimColor[2], this->appearEffectAlpha); + gDPSetEnvColor(gfx++, this->appearEffectEnvColor[0], this->appearEffectEnvColor[1], this->appearEffectEnvColor[2], + 255); + + if (this->appearEffectPrimLodFrac != 0) { + for (k = 0, i = 0, rectTop = EFFECT_TEX_LEFT; i < 2; i++, rectTop += EFFECT_MASK_TEX_HEIGHT) { + for (j = 0, rectLeft = EFFECT_TEX_TOP; j < 3; j++, k++, rectLeft += EFFECT_MASK_TEX_WIDTH) { + this->effectScrollSs[k] += sEffectScrollVelocitySs[k]; + this->effectScrollTs[k] += sEffectScrollVelocityTs[k]; + EnMag_DrawEffectTextures(&gfx, sAppearEffectMaskTextures[k], sEffectTextures[k], EFFECT_MASK_TEX_WIDTH, + EFFECT_MASK_TEX_HEIGHT, EFFECT_TEX_WIDTH, EFFECT_TEX_HEIGHT, rectLeft, rectTop, + 1, 1, k, this); + } + } + } + + func_8012C680(&gfx); + + if (this->majorasMaskAlpha != 0) { + gDPSetCombineLERP(gfx++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE, + ENVIRONMENT, TEXEL0, ENVIRONMENT, TEXEL0, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, 0, 255, 255, 255, this->majorasMaskAlpha); + gDPSetEnvColor(gfx++, this->majorasMaskEnvColor[0], this->majorasMaskEnvColor[1], this->majorasMaskEnvColor[2], + 255); + + EnMag_DrawImageRGBA32(&gfx, MAJORAS_MASK_TEX_CENTER_X, MAJORAS_MASK_TEX_CENTER_Y, gTitleScreenMajorasMaskTex, + MAJORAS_MASK_TEX_WIDTH, MAJORAS_MASK_TEX_HEIGHT); + } + + // Flame glow effects on full game logo when displayed + gDPPipeSync(gfx++); + gDPSetCycleType(gfx++, G_CYC_2CYCLE); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + gDPSetRenderMode(gfx++, G_RM_PASS, G_RM_CLD_SURF2); + gDPSetCombineLERP(gfx++, TEXEL1, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL1, 1, PRIM_LOD_FRAC, TEXEL0, PRIMITIVE, + ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, PRIMITIVE, 0); + + gDPSetPrimColor(gfx++, 0, this->displayEffectPrimLodFrac, this->displayEffectPrimColor[0], + this->displayEffectPrimColor[1], this->displayEffectPrimColor[2], this->displayEffectAlpha); + gDPSetEnvColor(gfx++, this->displayEffectEnvColor[0], this->displayEffectEnvColor[1], + this->displayEffectEnvColor[2], 255); + + if (this->displayEffectPrimLodFrac != 0) { + for (k = 0, i = 0, rectTop = EFFECT_TEX_LEFT; i < 2; i++, rectTop += EFFECT_MASK_TEX_HEIGHT) { + for (j = 0, rectLeft = EFFECT_TEX_TOP; j < 3; j++, k++, rectLeft += EFFECT_MASK_TEX_WIDTH) { + EnMag_DrawEffectTextures(&gfx, sDisplayEffectMaskTextures[k], sEffectTextures[k], EFFECT_MASK_TEX_WIDTH, + EFFECT_MASK_TEX_HEIGHT, EFFECT_TEX_WIDTH, EFFECT_TEX_HEIGHT, rectLeft, rectTop, + 1, 1, k, this); + } + } + } + + if (this->subtitleAlpha != 0) { + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, this->subtitleAlpha); + gDPSetEnvColor(gfx++, 100, 0, 100, 255); + + EnMag_DrawTextureI8(&gfx, gTitleScreenMajorasMaskSubtitleMaskTex, SUBTITLE_TEX_WIDTH, SUBTITLE_TEX_HEIGHT, + SUBTITLE_TEX_LEFT, SUBTITLE_TEX_TOP); + } + + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 120, 208, 102, 222, this->subtitleAlpha); + + EnMag_DrawTextureI8(&gfx, gTitleScreenMajorasMaskSubtitleTex, SUBTITLE_TEX_WIDTH, SUBTITLE_TEX_HEIGHT, + SUBTITLE_TEX_LEFT, SUBTITLE_TEX_TOP); + + func_8012C680(&gfx); + + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + + if (this->mainTitleAlpha != 0) { + gDPSetPrimColor(gfx++, 0, 0, 255, 255, 255, this->mainTitleAlpha); + + EnMag_DrawImageRGBA32(&gfx, ZELDA_TEX_CENTER_X, ZELDA_TEX_CENTER_Y, gTitleScreenZeldaLogoTex, ZELDA_TEX_WIDTH, + ZELDA_TEX_HEIGHT); + + gDPPipeSync(gfx++); + + if (this->mainTitleAlpha < 100) { + gDPSetRenderMode(gfx++, G_RM_CLD_SURF, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(gfx++, G_RM_XLU_SURF, G_RM_XLU_SURF2); + } + + gDPSetPrimColor(gfx++, 0, 0, 208, 102, 222, this->mainTitleAlpha); + + EnMag_DrawTextureI8(&gfx, gTitleScreenTheLegendOfTextTex, THE_LEGEND_OF_TEX_WIDTH, THE_LEGEND_OF_TEX_HEIGHT, + THE_LEGEND_OF_TEX_LEFT, THE_LEGEND_OF_TEX_TOP); + } + + func_8012C680(&gfx); + + if (this->copyrightAlpha != 0) { + gDPSetAlphaCompare(gfx++, G_AC_NONE); + gDPSetCombineMode(gfx++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPSetPrimColor(gfx++, 0, 0, this->copyrightAlpha, this->copyrightAlpha, this->copyrightAlpha, + this->copyrightAlpha); + + EnMag_DrawTextureIA8(&gfx, gTitleScreenCopyright2000NintendoTex, COPYRIGHT_TEX_WIDTH, COPYRIGHT_TEX_HEIGHT, + COPYRIGHT_TEX_LEFT, COPYRIGHT_TEX_TOP); + } + + if (gSaveContext.fileNum == 0xFEDC) { + // Draw No controller message + + TIMED_STEP_TO(sTextAlpha, sTextAlphaTargets[sTextAlphaTargetIndex], sTextAlphaTimer, step); + + gDPPipeSync(gfx++); + gDPSetAlphaCompare(gfx++, G_AC_THRESHOLD); + + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + gDPLoadTextureBlock_4b(gfx++, gTitleScreenControllerNotConnectedTextTex, G_IM_FMT_I, + NO_CONTROLLER_FIRST_TEX_WIDTH, NO_CONTROLLER_FIRST_TEX_HEIGHT, 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); + // Texture shadow + gSPTextureRectangle(gfx++, (NO_CONTROLLER_FIRST_TEX_LEFT + 1) << 2, (NO_CONTROLLER_FIRST_TEX_TOP + 1) << 2, + (NO_CONTROLLER_FIRST_TEX_LEFT + 1 + NO_CONTROLLER_FIRST_TEX_WIDTH) << 2, + (NO_CONTROLLER_FIRST_TEX_TOP + 1 + NO_CONTROLLER_FIRST_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + // Actual texture + gDPSetPrimColor(gfx++, 0, 0, 205, 255, 255, sTextAlpha); + gSPTextureRectangle(gfx++, NO_CONTROLLER_FIRST_TEX_LEFT << 2, NO_CONTROLLER_FIRST_TEX_TOP << 2, + (NO_CONTROLLER_FIRST_TEX_LEFT + NO_CONTROLLER_FIRST_TEX_WIDTH) << 2, + (NO_CONTROLLER_FIRST_TEX_TOP + NO_CONTROLLER_FIRST_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, 0, + 1 << 10, 1 << 10); + + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + gDPLoadTextureBlock_4b(gfx++, gTitleScreenInsertControllerTextTex, G_IM_FMT_I, NO_CONTROLLER_SECOND_TEX_WIDTH, + NO_CONTROLLER_SECOND_TEX_HEIGHT, 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); + // Texture shadow + gSPTextureRectangle(gfx++, (NO_CONTROLLER_SECOND_TEX_LEFT + 1) << 2, (NO_CONTROLLER_SECOND_TEX_TOP + 1) << 2, + (NO_CONTROLLER_SECOND_TEX_LEFT + 1 + NO_CONTROLLER_SECOND_TEX_WIDTH) << 2, + (NO_CONTROLLER_SECOND_TEX_TOP + 1 + NO_CONTROLLER_SECOND_TEX_HEIGHT) << 2, G_TX_RENDERTILE, + 0, 0, 1 << 10, 1 << 10); + // Actual texture + gDPSetPrimColor(gfx++, 0, 0, 205, 255, 255, sTextAlpha); + gSPTextureRectangle(gfx++, NO_CONTROLLER_SECOND_TEX_LEFT << 2, NO_CONTROLLER_SECOND_TEX_TOP << 2, + (NO_CONTROLLER_SECOND_TEX_LEFT + NO_CONTROLLER_SECOND_TEX_WIDTH) << 2, + (NO_CONTROLLER_SECOND_TEX_TOP + NO_CONTROLLER_SECOND_TEX_HEIGHT) << 2, G_TX_RENDERTILE, 0, + 0, 1 << 10, 1 << 10); + + sTextAlphaTimer--; + if (sTextAlphaTimer == 0) { + sTextAlpha = sTextAlphaTargets[sTextAlphaTargetIndex]; + if (gSaveContext.fileNum == 0xFEDC) { + sTextAlphaTimer = 40; + } else { + sTextAlphaTimer = 20; + } + sTextAlphaTargetIndex ^= 1; + } + } else if (this->copyrightAlpha != 0) { + // Draw "PRESS START" characters + + TIMED_STEP_TO(sTextAlpha, sTextAlphaTargets[sTextAlphaTargetIndex], sTextAlphaTimer, step); + + // Text shadow + gDPPipeSync(gfx++); + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + gDPSetPrimColor(gfx++, 0, 0, 0, 0, 0, sTextAlpha); + + rectLeft = PRESS_START_LEFT + 1; + for (i = 0; i < ARRAY_COUNT(pressStartFontIndices); i++) { + EnMag_DrawCharTexture(&gfx, font->fontBuf + pressStartFontIndices[i] * FONT_CHAR_TEX_SIZE, rectLeft, + PRESS_START_TOP + 1); + + rectLeft += PRESS_START_CHAR_SPACING; + if (i == 4) { + rectLeft += PRESS_START_SPACE; + } + } + + // Actual text + gDPPipeSync(gfx++); + gDPSetPrimColor(gfx++, 0, 0, 255, 30, 30, sTextAlpha); + + rectLeft = PRESS_START_LEFT; + for (i = 0; i < ARRAY_COUNT(pressStartFontIndices); i++) { + EnMag_DrawCharTexture(&gfx, font->fontBuf + pressStartFontIndices[i] * FONT_CHAR_TEX_SIZE, rectLeft, + PRESS_START_TOP); + rectLeft += PRESS_START_CHAR_SPACING; + if (i == 4) { + rectLeft += PRESS_START_SPACE; + } + } + + sTextAlphaTimer--; + if (sTextAlphaTimer == 0) { + sTextAlpha = sTextAlphaTargets[sTextAlphaTargetIndex]; + if (gSaveContext.fileNum == 0xFEDC) { + sTextAlphaTimer = 40; + } else { + sTextAlphaTimer = 20; + } + sTextAlphaTargetIndex ^= 1; + } + } + + *gfxp = gfx; +} + +/** + * Jumps drawing to POLY_OPA_DISP to take advantage of the extra space available, but jmups back and actually draws + * using OVERLAY_DISP. + */ +void EnMag_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + Gfx* gfx; + Gfx* gfxRef; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfxRef = POLY_OPA_DISP; + gfx = Graph_GfxPlusOne(gfxRef); + gSPDisplayList(OVERLAY_DISP++, gfx); + + EnMag_DrawInner(thisx, globalCtx, &gfx); + + gSPEndDisplayList(gfx++); + Graph_BranchDlist(gfxRef, gfx); + POLY_OPA_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Mag/z_en_mag.h b/src/overlays/actors/ovl_En_Mag/z_en_mag.h index 3543b5cea..c116ae98d 100644 --- a/src/overlays/actors/ovl_En_Mag/z_en_mag.h +++ b/src/overlays/actors/ovl_En_Mag/z_en_mag.h @@ -7,7 +7,45 @@ struct EnMag; typedef struct EnMag { /* 0x00000 */ Actor actor; - /* 0x00144 */ char unk_00144[0x11E34]; + /* 0x00144 */ UNK_TYPE1 unk144[0x2C]; + /* 0x00170 */ Font font; + /* 0x11EFC */ UNK_TYPE1 unk11EFC[4]; + /* 0x11F00 */ s16 unk11F00; // Set and not used. + /* 0x11F02 */ s16 unk11F02; // Set and not used. + /* 0x11F04 */ s16 state; // State of whole actor, uses EnMagState enum + /* 0x11F06 */ s16 appearEffectPrimLodFrac; + /* 0x11F08 */ s16 appearEffectPrimColor[3]; + /* 0x11F08 */ s16 appearEffectEnvColor[3]; + /* 0x11F14 */ s16 appearEffectAlpha; + /* 0x11F16 */ s16 displayEffectPrimLodFrac; + /* 0x11F18 */ s16 displayEffectPrimColor[3]; + /* 0x11F18 */ s16 displayEffectEnvColor[3]; + /* 0x11F24 */ s16 displayEffectAlpha; + /* 0x11F26 */ s16 majorasMaskAlpha; + /* 0x11F28 */ s16 majorasMaskEnvColor[3]; + /* 0x11F2E */ s16 mainTitleAlpha; + /* 0x11F30 */ s16 subtitleAlpha; + /* 0x11F32 */ s16 unk11F32; // Set but not used, likely a spare alpha. + /* 0x11F34 */ s16 copyrightAlpha; + /* 0x11F36 */ s16 effectScrollSs[6]; + /* 0x11F42 */ UNK_TYPE1 unk11F42[2]; + /* 0x11F44 */ s16 effectScrollTs[6]; + /* 0x11F50 */ UNK_TYPE1 unk11F50[4]; + /* 0x11F54 */ s16 unk11F54; // Set but not used. + /* 0x11F56 */ s16 unk11F56; // Set but not used. + /* 0x11F58 */ s16 unk11F58; // Set but not used. + /* 0x11F5A */ s16 unk11F5A; // Set but not used. + /* 0x11F5C */ s32 unk11F5C; // Set but not used. + /* 0x11F60 */ s32 unk11F60; // Set but not used. + /* 0x11F64 */ s16 majorasMaskEffectsFadeInTimer; + /* 0x11F66 */ s16 majorasMaskFadeInTimer; + /* 0x11F68 */ s16 mainTitleAlphaFadeInTimer; + /* 0x11F6A */ s16 effectAlphaFadeInTimer; + /* 0x11F6C */ s16 subtitleFadeInTimer; + /* 0x11F6E */ s16 copyrightFadeInTimer; + /* 0x11F70 */ s16 fadeOutTimer; + /* 0x11F72 */ s16 delayTimer; // Delays start of next action in Update. + /* 0x11F74 */ UNK_TYPE1 unk11F74[4]; } EnMag; // size = 0x11F78 extern const ActorInit En_Mag_InitVars; diff --git a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.c b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.c index 01b47bf00..cc56a5e5e 100644 --- a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.c +++ b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.c @@ -1,6 +1,14 @@ -#include "z_en_maruta.h" +/* + * File: z_en_maruta.c + * Overlay: ovl_En_Maruta + * Description: Swordsman's School - Practice Log + */ -#define FLAGS 0x00000011 +#include "z_en_maruta.h" +#include "overlays/actors/ovl_En_Kendo_Js/z_en_kendo_js.h" +#include "objects/object_maruta/object_maruta.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_10) #define THIS ((EnMaruta*)thisx) @@ -9,16 +17,25 @@ void EnMaruta_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMaruta_Update(Actor* thisx, GlobalContext* globalCtx); void EnMaruta_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B372B8(EnMaruta* this); void func_80B372CC(EnMaruta* this, GlobalContext* globalCtx); +void func_80B37364(EnMaruta* this); void func_80B3738C(EnMaruta* this, GlobalContext* globalCtx); +void func_80B373F4(EnMaruta* this); void func_80B37428(EnMaruta* this, GlobalContext* globalCtx); void func_80B374FC(EnMaruta* this, GlobalContext* globalCtx); +void func_80B37590(EnMaruta* this, GlobalContext* globalCtx); void func_80B37950(EnMaruta* this, GlobalContext* globalCtx); void func_80B379C0(EnMaruta* this, GlobalContext* globalCtx); +void func_80B37A14(EnMaruta* this); void func_80B37A64(EnMaruta* this, GlobalContext* globalCtx); void func_80B37AA0(EnMaruta* this, GlobalContext* globalCtx); +void func_80B37C04(s16* arg0); +void func_80B37EC0(EnMaruta* this, GlobalContext* globalCtx); +void func_80B38060(EnMaruta* this, Vec3f* arg1); +void func_80B3828C(Vec3f* arg0, Vec3f* arg1, s16 arg2, s16 arg3, s32 arg4); +void func_80B382E4(GlobalContext* globalCtx, Vec3f arg1); -#if 0 const ActorInit En_Maruta_InitVars = { ACTOR_EN_MARUTA, ACTORCAT_PROP, @@ -31,15 +48,94 @@ const ActorInit En_Maruta_InitVars = { (ActorFunc)EnMaruta_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B38AFC = { - { 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 | BUMP_HOOKABLE, OCELEM_ON, }, +Gfx* D_80B386A0[] = { + object_maruta_DL_002220, object_maruta_DL_0023D0, object_maruta_DL_002568, object_maruta_DL_002660, + object_maruta_DL_002758, object_maruta_DL_002850, object_maruta_DL_002948, object_maruta_DL_002AE0, +}; + +u8 D_80B386C0[] = { + 0xFF, 0x2B, 0xD4, 0x17, 0xE8, 0x55, 0xAA, 0x0F, 0xF0, +}; + +s32 D_80B386CC[] = { + 5, 5, 3, 3, 7, 7, 7, 7, 3, 3, 3, 3, 7, 7, 3, 3, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, +}; + +Vec3f D_80B38754 = { -2.0f, 3.0f, 0.0f }; +Vec3f D_80B38760 = { -2.0f, 3.0f, 0.0f }; +Vec3f D_80B3876C = { 2.0f, 3.0f, 0.0f }; +Vec3f D_80B38778 = { -2.0f, 10.0f, 0.0f }; +Vec3f D_80B38784 = { -2.5f, 5.0f, 0.0f }; +Vec3f D_80B38790 = { -3.0f, 10.0f, 0.0f }; +Vec3f D_80B3879C = { 2.5f, 5.0f, 0.0f }; +Vec3f D_80B387A8 = { 3.0f, 10.0f, 0.0f }; +Vec3f D_80B387B4 = { -1.0f, 7.0f, -1.0f }; +Vec3f D_80B387C0 = { 1.0f, 7.0f, -1.0f }; +Vec3f D_80B387CC = { 0.0f, 8.0f, -1.5f }; +Vec3f D_80B387D8 = { 0.0f, 8.0f, -1.5f }; + +Vec3f D_80B387E4[] = { + { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { -10.0f, 460.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, { 10.0f, 460.0f, 0.0f }, { -40.0f, 315.0f, 0.0f }, + { 40.0f, 315.0f, 0.0f }, { 0.0f, 140.0f, 0.0f }, { 0.0f, 445.0f, 0.0f }, +}; + +Vec3f D_80B38850[] = { + { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, + { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f, -1.0f }, { -1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, +}; + +Vec3f D_80B388BC[] = { + { 90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, 78.0f }, { 90.0f, 630.0f, 78.0f }, + { 90.0f, 350.0f, -78.0f }, { -90.0f, 170.0f, -78.0f }, { -90.0f, 170.0f, 78.0f }, { 90.0f, 350.0f, 78.0f }, +}; + +Vec3f D_80B3891C[] = { + { 90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, 78.0f }, { 90.0f, 630.0f, 78.0f }, + { 90.0f, 170.0f, -78.0f }, { -90.0f, 350.0f, -78.0f }, { -90.0f, 350.0f, 78.0f }, { 90.0f, 170.0f, 78.0f }, +}; + +Vec3f D_80B3897C[] = { + { 0.0f, 630.0f, -104.0f }, { -90.0f, 630.0f, -52.0f }, { -90.0f, 630.0f, 52.0f }, { 0.0f, 630.0f, 104.0f }, + { 0.0f, 0.0f, -104.0f }, { -90.0f, 0.0f, -52.0f }, { -90.0f, 0.0f, 52.0f }, { 0.0f, 0.0f, 104.0f }, +}; + +Vec3f D_80B389DC[] = { + { 0.0f, 630.0f, -104.0f }, { 90.0f, 630.0f, -52.0f }, { 90.0f, 630.0f, 52.0f }, { 0.0f, 630.0f, 104.0f }, + { 0.0f, 0.0f, -104.0f }, { 90.0f, 0.0f, -52.0f }, { 90.0f, 0.0f, 52.0f }, { 0.0f, 0.0f, 104.0f }, +}; + +Vec3f D_80B38A3C[] = { + { 90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, -78.0f }, { -90.0f, 630.0f, 78.0f }, { 90.0f, 630.0f, 78.0f }, + { 90.0f, 260.0f, -78.0f }, { -90.0f, 260.0f, -78.0f }, { -90.0f, 260.0f, 78.0f }, { 90.0f, 260.0f, 78.0f }, +}; + +Vec3f D_80B38A9C[] = { + { 90.0f, 260.0f, -78.0f }, { -90.0f, 260.0f, -78.0f }, { -90.0f, 260.0f, 78.0f }, { 90.0f, 260.0f, 78.0f }, + { 90.0f, 20.0f, -78.0f }, { -90.0f, 20.0f, -78.0f }, { -90.0f, 20.0f, 78.0f }, { 90.0f, 20.0f, 78.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 | BUMP_HOOKABLE, + OCELEM_ON, + }, { 12, 65, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B38B28 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -74,71 +170,530 @@ static DamageTable D_80B38B28 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B38B48 = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -#endif +Vec3f D_80B38B54 = { 0.0f, 0.0f, 0.0f }; -extern ColliderCylinderInit D_80B38AFC; -extern DamageTable D_80B38B28; -extern CollisionCheckInfoInit2 D_80B38B48; +void EnMaruta_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMaruta* this = THIS; + s32 i; -extern UNK_TYPE D_06002EC0; + Actor_SetScale(&this->actor, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/EnMaruta_Init.s") + this->actor.targetMode = 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/EnMaruta_Destroy.s") + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 50.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B372B8.s") + this->actor.colChkInfo.health = 1; + this->actor.world.pos.y -= 4.0f; + this->actor.home.pos.y -= 4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B372CC.s") + this->unk_210 = ENMARUTA_GET_FF00(&this->actor); + this->unk_218 = 0; + this->unk_21A = 0; + this->unk_1A0 = NULL; + this->unk_21C = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37364.s") + this->unk_194.x = 0.0f; + this->unk_194.y = 0.0f; + this->unk_194.z = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B3738C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_1A4); i++) { + this->unk_1A4[i] = D_80B38B54; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B373F4.s") + this->unk_214 = -1; + this->unk_220 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37428.s") + if (this->unk_210 == 0) { + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B374B8.s") + if (this->unk_210 == 0) { + if (ENMARUTA_GET_FF(&this->actor) == 0xFF) { + func_80B372B8(this); + } else { + func_80B37364(this); + } + } else { + func_80B37590(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B374FC.s") +void EnMaruta_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMaruta* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37590.s") + if (this->unk_210 == 0) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37950.s") +void func_80B372B8(EnMaruta* this) { + this->actionFunc = func_80B372CC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37998.s") +void func_80B372CC(EnMaruta* this, GlobalContext* globalCtx) { + s16 temp_v1 = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B379C0.s") + if (temp_v1 > 0x1555) { + this->actor.shape.rot.y += 0x2AAA; + } else if (temp_v1 < -0x1555) { + this->actor.shape.rot.y -= 0x2AAA; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37A14.s") + if (this->unk_220 == 1) { + func_80B373F4(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37A64.s") + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_KENDO_JS)) { + EnKendoJs* kendoJs = (EnKendoJs*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37A8C.s") + kendoJs->unk_292 = this->actor.isTargeted; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37AA0.s") +void func_80B37364(EnMaruta* this) { + this->actor.world.pos.y = this->actor.home.pos.y - 630.0f; + this->actionFunc = func_80B3738C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37B78.s") +void func_80B3738C(EnMaruta* this, GlobalContext* globalCtx) { + if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.4f, 100.0f, 10.0f) == 0.0f) { + func_80B372B8(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37C04.s") +void func_80B373F4(EnMaruta* this) { + this->collider.base.acFlags |= AC_HIT; + this->actor.velocity.y = 0.0f; + this->actor.gravity = -2.0f; + this->actionFunc = func_80B37428; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37C60.s") +void func_80B37428(EnMaruta* this, GlobalContext* globalCtx) { + if ((this->actor.floorHeight - 630.0f) < this->actor.world.pos.y) { + this->actor.velocity.y += this->actor.gravity; + this->actor.world.pos.y += this->actor.velocity.y; + } else { + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_KENDO_JS)) { + EnKendoJs* kendoJs = (EnKendoJs*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37CA0.s") + kendoJs->unk_28C--; + } + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B37EC0.s") +void func_80B374B8(EnMaruta* this) { + this->actor.flags &= ~ACTOR_FLAG_1; + if (this->actionFunc != func_80B37428) { + this->unk_21E = 0; + this->actor.gravity = -2.0f; + this->actionFunc = func_80B374FC; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B38028.s") +void func_80B374FC(EnMaruta* this, GlobalContext* globalCtx) { + if (this->unk_21E == 40) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B38060.s") + if (((this->actor.floorHeight - 630.0f) < this->actor.world.pos.y) && (this->unk_21E > 30)) { + this->actor.velocity.y += this->actor.gravity; + this->actor.world.pos.y += this->actor.velocity.y; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B3828C.s") + this->unk_21E++; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/func_80B382E4.s") +void func_80B37590(EnMaruta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp48; + s16 sp46; + Vec3f sp38; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/EnMaruta_Update.s") + this->unk_21E = 0; + this->unk_21C = 0; + this->actor.gravity = -2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Maruta/EnMaruta_Draw.s") + switch (this->unk_210) { + case 2: + sp48 = D_80B38754; + this->unk_1A0 = D_80B388BC; + break; + + case 4: + if (player->swordAnimation == 8) { + sp48 = D_80B3876C; + } else { + sp48 = D_80B38778; + } + this->unk_1A0 = D_80B3891C; + break; + + case 5: + if (player->swordAnimation == 0) { + sp48 = D_80B38784; + } else { + sp48 = D_80B38790; + } + this->unk_1A0 = D_80B3897C; + break; + + case 6: + if (player->swordAnimation == 0) { + sp48 = D_80B3879C; + } else { + sp48 = D_80B387A8; + } + this->unk_1A0 = D_80B389DC; + break; + + case 8: + if (player->swordAnimation == 4) { + sp48 = D_80B387B4; + } else { + sp48 = D_80B387C0; + } + this->unk_1A0 = D_80B38A3C; + break; + + case 7: + sp48 = D_80B387CC; + this->unk_1A0 = D_80B38A9C; + break; + + default: + sp48 = D_80B38B54; + break; + } + + sp46 = this->actor.shape.rot.y; + this->actor.velocity.x = (sp48.x * Math_CosS(sp46) + (Math_SinS(sp46) * sp48.z)); + this->actor.velocity.y = sp48.y; + this->actor.velocity.z = (-sp48.x * Math_SinS(sp46) + (Math_CosS(sp46) * sp48.z)); + + sp38 = D_80B38850[this->unk_210]; + + func_80B3828C(&sp38, &this->unk_194, Rand_Next() & 0xFFF, Rand_Next() & 0xFFF, 0); + this->unk_21A = Rand_Next() & 0x7FF; + + if (this->unk_210 == 7) { + this->unk_21A |= 0x3F; + } else { + this->unk_21A |= 0xFF; + } + + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = func_80B37950; +} + +void func_80B37950(EnMaruta* this, GlobalContext* globalCtx) { + this->unk_218 += this->unk_21A; + this->actor.velocity.y += this->actor.gravity; + func_80B37EC0(this, globalCtx); + Actor_UpdatePos(&this->actor); +} + +void func_80B37998(EnMaruta* this) { + this->unk_21E = 0; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->unk_21A = 0; + this->actionFunc = func_80B379C0; +} + +void func_80B379C0(EnMaruta* this, GlobalContext* globalCtx) { + if (this->unk_21E == 40) { + func_80B37A14(this); + } else { + this->unk_21E++; + } + func_80B37C04(&this->unk_218); +} + +void func_80B37A14(EnMaruta* this) { + s16 temp = this->unk_218 & 0x7FFF; + + if (((this->unk_210 == 5) || (this->unk_210 == 6)) && !temp) { + this->unk_21E = 100; + } else { + this->unk_21E = 0; + } + this->actionFunc = func_80B37A64; +} + +void func_80B37A64(EnMaruta* this, GlobalContext* globalCtx) { + if (this->unk_21E > 100) { + this->actor.colChkInfo.health = 0; + } else { + this->unk_21E++; + } +} + +void func_80B37A8C(EnMaruta* this) { + this->actionFunc = func_80B37AA0; +} + +void func_80B37AA0(EnMaruta* this, GlobalContext* globalCtx) { + if (this->actor.scale.y == 0.0f) { + if (this->actor.scale.x == 0.0f) { + Actor_MarkForDeath(&this->actor); + return; + } + Math_SmoothStepToF(&this->actor.scale.x, 0.0f, 0.2f, 0.01f, 0.001f); + Math_SmoothStepToF(&this->actor.scale.z, 0.0f, 0.2f, 0.01f, 0.001f); + } else { + Math_SmoothStepToF(&this->actor.scale.y, 0.0f, 0.2f, 0.003f, 0.001f); + } +} + +s32 func_80B37B78(EnMaruta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 temp_v1 = BINANG_SUB(this->actor.yawTowardsPlayer, 0x8000); + + temp_v1 = BINANG_SUB(temp_v1, player->actor.shape.rot.y); + if ((ABS_ALT(temp_v1) < 0x1555) || + ((player->swordState != 0) && ((player->swordAnimation == 4) || (player->swordAnimation == 6) || + (player->swordAnimation == 0x1E) || (player->swordAnimation == 0x20)))) { + return true; + } + return false; +} + +void func_80B37C04(s16* arg0) { + s16 temp_a1 = *arg0 & 0xC000; + s16 temp = *arg0 & 0x3FFF; + + if (temp > 0x2000) { + temp_a1 += 0x4000; + } + Math_SmoothStepToS(arg0, temp_a1, 1, 0xAAA, 0xB6); +} + +void func_80B37C60(EnMaruta* this) { + if ((this->actionFunc != func_80B37AA0) && (this->actor.colChkInfo.health == 0)) { + func_80B37A8C(this); + } +} + +void func_80B37CA0(EnMaruta* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((this->actionFunc == func_80B372CC) || (this->actionFunc == func_80B3738C) || + (this->actionFunc == func_80B374FC) || (this->actionFunc == func_80B37AA0) || + ((this->actionFunc == func_80B37428) && !(this->actor.world.pos.y < (this->actor.floorHeight - 20.0f)))) { + if ((this->collider.base.acFlags & AC_HIT) && (this->actionFunc == func_80B372CC)) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SWORD_STRIKE); + + if (D_80B386CC[player->swordAnimation] != 0) { + s32 temp = D_80B386CC[player->swordAnimation] + 1; + + temp = (temp << 8) & 0xFF00; + this->unk_210 = D_80B386CC[player->swordAnimation]; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_MARUTA, + this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, + this->actor.shape.rot.y, 0, temp); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->unk_210 == 5) || ((this->unk_210 == 7) && (player->swordAnimation == 0xC))) { + func_80B37590(this, globalCtx); + } else { + func_80B374B8(this); + } + + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_KENDO_JS)) { + EnKendoJs* kendoJs = (EnKendoJs*)this->actor.parent; + + kendoJs->unk_28E = 1; + kendoJs->unk_28C--; + } + return; + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (func_80B37B78(this, globalCtx) && (this->actionFunc == func_80B372CC)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void func_80B37EC0(EnMaruta* this, GlobalContext* globalCtx) { + Vec3f sp34 = this->unk_204; + s32 phi_a2 = -1; + s32 i; + f32 temp; + + for (i = 0; i < ARRAY_COUNT(this->unk_1A4); i++) { + if (this->unk_1A4[i].y < sp34.y) { + sp34 = this->unk_1A4[i]; + phi_a2 = i; + } + this->unk_214 = phi_a2; + } + + if (sp34.y < this->actor.floorHeight) { + this->unk_218 -= this->unk_21A; + + temp = this->actor.floorHeight - sp34.y; + this->actor.velocity.y -= this->actor.gravity; + this->actor.velocity.x *= 0.6f; + this->actor.velocity.z *= 0.6f; + this->actor.world.pos.y += temp; + + if (this->actor.velocity.y < -this->actor.gravity) { + func_80B382E4(globalCtx, sp34); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_LOG_BOUND); + this->actor.velocity.y *= -0.6f; + func_80B38060(this, &sp34); + } + } +} + +f32 func_80B38028(Vec3f* arg0, Vec3f* arg1, Vec3f* arg2) { + f32 x0 = arg0->x; + f32 z0 = arg0->z; + f32 dx = arg2->x - arg1->x; + f32 dz = arg2->z - arg1->z; + + return z0 * dx - x0 * dz; +} + +void func_80B38060(EnMaruta* this, Vec3f* arg1) { + Vec3f sp44; + s32 pad; + f32 temp_f0; + f32 phi_f2; + + func_80B3828C(&this->unk_194, &sp44, 0, this->actor.shape.rot.y, 0); + temp_f0 = func_80B38028(&sp44, &this->unk_204, arg1); + + if ((this->unk_210 == 5) || (this->unk_210 == 6)) { + phi_f2 = 8.0f; + } else if (this->unk_210 == 4) { + phi_f2 = 5.0f; + } else { + phi_f2 = 2.0f; + } + + if ((temp_f0 < phi_f2) && (-phi_f2 < temp_f0)) { + phi_f2 = 3.0f; + } else { + phi_f2 = 1.2f; + } + + if (temp_f0 > 0.0f) { + if (this->unk_21A > 0) { + this->unk_21A *= phi_f2; + } else { + this->unk_21A *= -0.8f; + } + } else { + if (this->unk_21A > 0) { + this->unk_21A *= -0.8f; + } else { + this->unk_21A *= phi_f2; + } + } + + if ((ABS_ALT(this->unk_21A) < 0x38E) && + (((this->unk_218 & 0x3FFF) < 0x71C) || ((this->unk_218 & 0x3FFF) >= 0x38E4))) { + this->actor.gravity *= 0.8f; + this->unk_21C++; + if (this->unk_21C == 2) { + func_80B37998(this); + } + } else if (ABS_ALT(this->unk_21A) > 0x38E) { + if (this->unk_21A < 0) { + this->unk_21A = -0x38E; + } else { + this->unk_21A = 0x38E; + } + } +} + +void func_80B3828C(Vec3f* arg0, Vec3f* arg1, s16 arg2, s16 arg3, s32 arg4) { + Matrix_Push(); + Matrix_RotateZYX(arg2, arg3, arg4, MTXMODE_NEW); + Matrix_MultVec3f(arg0, arg1); + Matrix_Pop(); +} + +void func_80B382E4(GlobalContext* globalCtx, Vec3f arg1) { + Vec3f sp84 = arg1; + Vec3f sp78; + Vec3f sp6C; + Color_RGBA8 sp68 = { 170, 130, 90, 255 }; + Color_RGBA8 sp64 = { 100, 60, 20, 255 }; + s32 i; + + sp6C.y = 0.0f; + sp84.y += 15.0f; + + for (i = 0; i < 10; i++) { + sp78.x = Rand_Centered() * 10.0f; + sp78.y = 2.0f * Rand_ZeroOne(); + sp78.z = Rand_Centered() * 10.0f; + sp6C.x = -0.2f * sp78.x; + sp6C.z = -0.2f * sp78.z; + func_800B0EB0(globalCtx, &sp84, &sp78, &sp6C, &sp68, &sp64, 60, 20, 10); + } +} + +void EnMaruta_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMaruta* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80B37CA0(this, globalCtx); + func_80B37C60(this); +} + +void EnMaruta_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMaruta* this = THIS; + Vec3f sp50; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_210 == 0) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_maruta_DL_002EC0); + } else { + sp50 = D_80B387E4[this->unk_210]; + + Matrix_Push(); + Matrix_Translate(sp50.x, sp50.y, sp50.z, MTXMODE_APPLY); + Matrix_RotateAxisS(this->unk_218, &this->unk_194, MTXMODE_APPLY); + Matrix_Translate(-sp50.x, -sp50.y, -sp50.z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0; i < 8; i++) { + if (D_80B386C0[this->unk_210] & (1 << i)) { + gSPDisplayList(POLY_OPA_DISP++, D_80B386A0[i]); + } + } + + if (this->unk_1A0 != NULL) { + for (i = 0; i < ARRAY_COUNT(this->unk_1A4); i++) { + Matrix_MultVec3f(&this->unk_1A0[i], &this->unk_1A4[i]); + } + Matrix_MultVec3f(&sp50, &this->unk_204); + } + + Matrix_Pop(); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..162618fc6 100644 --- a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h +++ b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h @@ -7,10 +7,24 @@ struct EnMaruta; typedef void (*EnMarutaActionFunc)(struct EnMaruta*, GlobalContext*); +#define ENMARUTA_GET_FF(thisx) ((thisx)->params & 0xFF) +#define ENMARUTA_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + typedef struct EnMaruta { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMarutaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xDC]; + /* 0x0148 */ ColliderCylinder collider; + /* 0x0194 */ Vec3f unk_194; + /* 0x01A0 */ Vec3f* unk_1A0; + /* 0x01A4 */ Vec3f unk_1A4[8]; + /* 0x0204 */ Vec3f unk_204; + /* 0x0210 */ s32 unk_210; + /* 0x0214 */ s32 unk_214; + /* 0x0218 */ s16 unk_218; + /* 0x021A */ s16 unk_21A; + /* 0x021C */ s16 unk_21C; + /* 0x021E */ s16 unk_21E; + /* 0x0220 */ s16 unk_220; } 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 955cf8fc7..d5e15c04d 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c @@ -1,6 +1,12 @@ +/* + * File: z_en_minideath.c + * Overlay: ovl_En_Minideath + * Description: Gomess's bats + */ + #include "z_en_minideath.h" -#define FLAGS 0x00000015 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnMinideath*)thisx) 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 9de59a963..d8b4296cb 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -5,8 +5,10 @@ */ #include "z_en_minifrog.h" +#include "objects/object_fr/object_fr.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnMinifrog*)thisx) @@ -24,12 +26,6 @@ void EnMinifrog_UpdateMissingFrog(Actor* thisx, GlobalContext* globalCtx); void EnMinifrog_YellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx); void EnMinifrog_SetupYellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx); -extern AnimationHeader D_060007BC; -extern AnimationHeader D_06001534; -extern FlexSkeletonHeader D_0600B538; -extern UNK_TYPE4 D_060059A0; -extern UNK_TYPE4 D_06005BA0; - const ActorInit En_Minifrog_InitVars = { ACTOR_EN_MINIFROG, ACTORCAT_NPC, @@ -65,12 +61,12 @@ static ColliderCylinderInit sCylinderInit = { static CollisionCheckInfoInit sColChkInfoInit = { 1, 12, 14, MASS_IMMOVABLE }; // sEyeTextures??? -static UNK_TYPE4* D_808A4D74[] = { - &D_060059A0, - &D_06005BA0, +static TexturePtr D_808A4D74[] = { + object_fr_Tex_0059A0, + object_fr_Tex_005BA0, }; -// gSaveContext.weekEventReg[KEY] = VALUE +// gSaveContext.save.weekEventReg[KEY] = VALUE // KEY | VALUE static u16 isFrogReturnedFlags[] = { (0 << 8) | 0x00, // NULL @@ -91,8 +87,9 @@ void EnMinifrog_Init(Actor* thisx, GlobalContext* globalCtx) { int i; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 15.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600B538, &D_06001534, this->jointTable, this->morphTable, 24); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 15.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_fr_Skel_00B538, &object_fr_Anim_001534, this->jointTable, + this->morphTable, 24); CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); @@ -117,7 +114,7 @@ void EnMinifrog_Init(Actor* thisx, GlobalContext* globalCtx) { if (1) {} if (!EN_MINIFROG_IS_RETURNED(this)) { if ((this->frogIndex == MINIFROG_YELLOW) || - ((gSaveContext.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] & + ((gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] & (u8)isFrogReturnedFlags[this->frogIndex]))) { Actor_MarkForDeath(&this->actor); } else { @@ -132,18 +129,18 @@ void EnMinifrog_Init(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc = EnMinifrog_SetupYellowFrogDialog; // Not spoken to MINIFROG_YELLOW - if (!(gSaveContext.weekEventReg[34] & 1)) { - this->actor.flags |= 0x10000; + if (!(gSaveContext.save.weekEventReg[34] & 1)) { + this->actor.flags |= ACTOR_FLAG_10000; } this->actor.home.rot.x = this->actor.home.rot.z = 0; this->frog = NULL; } else { this->frog = EnMinifrog_GetFrog(globalCtx); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; // Frog has been returned - if ((gSaveContext.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] & + if ((gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] & (u8)isFrogReturnedFlags[this->frogIndex])) { this->actionFunc = EnMinifrog_SetupNextFrogInit; } else { @@ -164,7 +161,7 @@ void EnMinifrog_Destroy(Actor* thisx, GlobalContext* globalCtx) { } EnMinifrog* EnMinifrog_GetFrog(GlobalContext* globalCtx) { - EnMinifrog* frog = (EnMinifrog*)globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + EnMinifrog* frog = (EnMinifrog*)globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (frog != NULL) { if ((frog->actor.id != ACTOR_EN_MINIFROG) || (frog->actor.params & 0xF)) { @@ -180,7 +177,7 @@ EnMinifrog* EnMinifrog_GetFrog(GlobalContext* globalCtx) { void EnMinifrog_SetJumpState(EnMinifrog* this) { if (this->jumpState == MINIFROG_STATE_GROUND) { this->jumpState = MINIFROG_STATE_JUMP; - Animation_Change(&this->skelAnime, &D_060007BC, 1.0f, 0.0f, 7.0f, 2, -5.0f); + Animation_Change(&this->skelAnime, &object_fr_Anim_0007BC, 1.0f, 0.0f, 7.0f, 2, -5.0f); } } @@ -200,14 +197,14 @@ void EnMinifrog_Jump(EnMinifrog* this) { if (Animation_OnFrame(&this->skelAnime, 4.0f)) { this->actor.bgCheckFlags &= ~1; this->actor.velocity.y = 6.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FROG_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FROG_JUMP); this->jumpState = MINIFROG_STATE_AIR; } break; case MINIFROG_STATE_AIR: if (this->actor.bgCheckFlags & 1) { this->jumpState = MINIFROG_STATE_GROUND; - Animation_MorphToLoop(&this->skelAnime, &D_06001534, -2.5f); + Animation_MorphToLoop(&this->skelAnime, &object_fr_Anim_001534, -2.5f); SkelAnime_Update(&this->skelAnime); } break; @@ -227,22 +224,22 @@ void EnMinifrog_TurnToMissingFrog(EnMinifrog* this) { static Color_RGBA8 sPrimColor = { 255, 255, 255, 255 }; static Color_RGBA8 sEnvColor = { 80, 80, 80, 255 }; -void EnMinifrog_SetCamera(EnMinifrog* this, GlobalContext* globalCtx) { +void EnMinifrog_SpawnDust(EnMinifrog* this, GlobalContext* globalCtx) { Vec3f pos; Vec3f vec5; Vec3f vel; Vec3f accel; s16 yaw; s16 pitch; - Vec3f eye; + Vec3f eye = GET_ACTIVE_CAM(globalCtx)->eye; s32 i; - eye = GET_ACTIVE_CAM(globalCtx)->eye; yaw = Math_Vec3f_Yaw(&eye, &this->actor.world.pos); pitch = -Math_Vec3f_Pitch(&eye, &this->actor.world.pos); vec5.x = this->actor.world.pos.x - (5.0f * Math_SinS(yaw) * Math_CosS(pitch)); vec5.y = this->actor.world.pos.y - (5.0f * Math_SinS(pitch)); vec5.z = this->actor.world.pos.z - (5.0f * Math_CosS(yaw) * Math_CosS(pitch)); + for (i = 0; i < 5; i++) { vel.x = randPlusMinusPoint5Scaled(4.0f); vel.y = randPlusMinusPoint5Scaled(4.0f); @@ -258,37 +255,38 @@ void EnMinifrog_SetCamera(EnMinifrog* this, GlobalContext* globalCtx) { } void EnMinifrog_ReturnFrogCutscene(EnMinifrog* this, GlobalContext* globalCtx) { - u8 flag; - EnMinifrog_TurnToPlayer(this); EnMinifrog_Jump(this); - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { EnMinifrog_SetJumpState(this); - switch (globalCtx->msgCtx.unk11F04) { + switch (globalCtx->msgCtx.currentTextId) { case 0xD81: // "Ah! Don Gero! It has been so long." case 0xD83: // "Could it be... Has spring finally come to the mountains?" case 0xD84: // "That look...It is true! Winter was so long that I began to lose all hope." case 0xD86: // "Could it be... You came all this way looking for me?" case 0xD87: // "Ah! You need not say a thing. Upon seeing that face, I understand!" ... - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; - case 0xD82: // "What has brought you all this way?" - if (gSaveContext.weekEventReg[33] & 0x80) { // Mountain village is unfrozen + + case 0xD82: // "What has brought you all this way?" + if (gSaveContext.save.weekEventReg[33] & 0x80) { // Mountain village is unfrozen func_80151938(globalCtx, 0xD83); // "Could it be... Has spring finally come to the mountains?" } else { func_80151938(globalCtx, 0xD86); // "Could it be... You came all this way looking for me?" } - flag = gSaveContext.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8]; - gSaveContext.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] = - flag | (u8)isFrogReturnedFlags[this->frogIndex]; + gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8] = + ((void)0, gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->frogIndex] >> 8]) | + (u8)isFrogReturnedFlags[this->frogIndex]; break; + case 0xD85: // "I understand. I shall head for the mountains immediately." default: func_801477B4(globalCtx); - EnMinifrog_SetCamera(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_NPC_FADEAWAY); + EnMinifrog_SpawnDust(this, globalCtx); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_NPC_FADEAWAY); if (this->actor.cutscene != -1) { if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { ActorCutscene_Stop(this->actor.cutscene); @@ -329,13 +327,13 @@ void EnMinifrog_Idle(EnMinifrog* this, GlobalContext* globalCtx) { EnMinifrog_TurnToPlayer(this); EnMinifrog_Jump(this); EnMinifrog_JumpTimer(this); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = EnMinifrog_ReturnFrogCutscene; if (this->actor.cutscene != -1) { this->flags |= 1; } - } else if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && - (Player_GetMask(globalCtx) == PLAYER_MASK_DON_GEROS_MASK)) { + } else if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + (Player_GetMask(globalCtx) == PLAYER_MASK_DON_GERO)) { func_800B8614(&this->actor, globalCtx, 110.0f); } } @@ -413,7 +411,7 @@ void EnMinifrog_NextFrogReturned(EnMinifrog* this, GlobalContext* globalCtx) { this->actionFunc = EnMinifrog_ContinueChoirCutscene; this->flags &= ~(0x2 << MINIFROG_YELLOW | 0x2 << MINIFROG_CYAN | 0x2 << MINIFROG_PINK | 0x2 << MINIFROG_BLUE | 0x2 << MINIFROG_WHITE); - globalCtx->setPlayerTalkAnim(globalCtx, &D_0400DEA8, 0); + globalCtx->setPlayerTalkAnim(globalCtx, &gameplay_keep_Linkanim_00DEA8, 0); } } @@ -444,7 +442,7 @@ void EnMinifrog_SetupNextFrogChoir(EnMinifrog* this, GlobalContext* globalCtx) { this->flags &= ~0x100; this->flags &= ~(0x2 << MINIFROG_YELLOW | 0x2 << MINIFROG_CYAN | 0x2 << MINIFROG_PINK | 0x2 << MINIFROG_BLUE | 0x2 << MINIFROG_WHITE); - globalCtx->setPlayerTalkAnim(globalCtx, &D_0400DEA8, 0); + globalCtx->setPlayerTalkAnim(globalCtx, &gameplay_keep_Linkanim_00DEA8, 0); } else if (this->timer <= 0) { this->actionFunc = EnMinifrog_NextFrogReturned; this->timer = 30; @@ -462,9 +460,9 @@ void EnMinifrog_BeginChoirCutscene(EnMinifrog* this, GlobalContext* globalCtx) { ActorCutscene_Start(this->actor.cutscene, &this->actor); this->actionFunc = EnMinifrog_SetupNextFrogChoir; this->timer = 5; - func_801A1F00(3, 0x5A); + func_801A1F00(3, NA_BGM_FROG_SONG); this->flags |= 0x100; - globalCtx->setPlayerTalkAnim(globalCtx, &D_0400E2A8, 0); + globalCtx->setPlayerTalkAnim(globalCtx, &gameplay_keep_Linkanim_00E2A8, 0); } else { ActorCutscene_SetIntentToPlay(this->actor.cutscene); } @@ -473,11 +471,11 @@ void EnMinifrog_BeginChoirCutscene(EnMinifrog* this, GlobalContext* globalCtx) { void EnMinifrog_EndChoir(EnMinifrog* this, GlobalContext* globalCtx) { EnMinifrog_TurnToPlayer(this); EnMinifrog_Jump(this); - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0xD7E, &this->actor); // "Let us do it again sometime." + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0xD7E, &this->actor); // "Let us do it again sometime." this->actionFunc = EnMinifrog_YellowFrogDialog; } else { - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_MINUS1); } } @@ -487,19 +485,19 @@ void EnMinifrog_GetFrogHP(EnMinifrog* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; this->actionFunc = EnMinifrog_EndChoir; - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_NONE); } else { - func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 50.0f); + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 10000.0f, 50.0f); } } void EnMinifrog_YellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx) { EnMinifrog_TurnToPlayer(this); EnMinifrog_Jump(this); - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: // Yes func_8019F208(); @@ -514,32 +512,32 @@ void EnMinifrog_YellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx) { } break; case 5: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnMinifrog_SetJumpState(this); - switch (globalCtx->msgCtx.unk11F04) { + switch (globalCtx->msgCtx.currentTextId) { case 0xD76: // "I have been waiting for you, Don Gero. Forgive me if I'm mistaken, but it looks like // you've lost a little weight..." - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); - this->actor.flags &= ~0x10000; - gSaveContext.weekEventReg[34] |= 1; // Spoken to MINIFROG_YELLOW + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + this->actor.flags &= ~ACTOR_FLAG_10000; + gSaveContext.save.weekEventReg[34] |= 1; // Spoken to MINIFROG_YELLOW break; case 0xD78: // "Unfortunately, it seems not all of our members have gathered." case 0xD79: // "Perhaps it is because winter was too long? They must not have realized that spring // has come to the mountains..." case 0xD7A: // "And when the great Don Gero has come for us, too...What a pity." case 0xD7F: // "Well, if it isn't the great Don Gero." - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0xD77: // "Let us begin our chorus" this->actionFunc = EnMinifrog_BeginChoirCutscene; globalCtx->msgCtx.unk11F10 = 0; break; case 0xD7C: // "The conducting was spectacular. And all of our members rose to the occasion!" - if (gSaveContext.weekEventReg[35] & 0x80) { // Obtained Heart Piece + if (gSaveContext.save.weekEventReg[35] & 0x80) { // Obtained Heart Piece func_80151938(globalCtx, 0xD7E); } else { func_80151938(globalCtx, 0xD7D); // Get Heart Piece - gSaveContext.weekEventReg[35] |= 0x80; + gSaveContext.save.weekEventReg[35] |= 0x80; } break; case 0xD7D: // "This is how deeply we were moved by your spectacular conducting..." @@ -552,7 +550,7 @@ void EnMinifrog_YellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx) { default: func_801477B4(globalCtx); this->actionFunc = EnMinifrog_SetupYellowFrogDialog; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; break; } } @@ -565,19 +563,19 @@ void EnMinifrog_SetupYellowFrogDialog(EnMinifrog* this, GlobalContext* globalCtx EnMinifrog_TurnToPlayer(this); EnMinifrog_Jump(this); EnMinifrog_JumpTimer(this); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = EnMinifrog_YellowFrogDialog; - if (!(gSaveContext.weekEventReg[34] & 1)) { // Not spoken with MINIFROG_YELLOW - func_801518B0(globalCtx, 0xD76, - &this->actor); // "I have been waiting for you, Don Gero. Forgive me if I'm mistaken, but it - // looks like you've lost a little weight..." + if (!(gSaveContext.save.weekEventReg[34] & 1)) { // Not spoken with MINIFROG_YELLOW + Message_StartTextbox(globalCtx, 0xD76, + &this->actor); // "I have been waiting for you, Don Gero. Forgive me if I'm mistaken, + // but it looks like you've lost a little weight..." } else { - func_801518B0(globalCtx, 0xD7F, &this->actor); // "Well, if it isn't the great Don Gero." + Message_StartTextbox(globalCtx, 0xD7F, &this->actor); // "Well, if it isn't the great Don Gero." } } else if ((this->actor.xzDistToPlayer < 150.0f) && - (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) || - ((this->actor.flags & 0x10000) == 0x10000)) && - Player_GetMask(globalCtx) == PLAYER_MASK_DON_GEROS_MASK) { + (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) || + CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_10000)) && + Player_GetMask(globalCtx) == PLAYER_MASK_DON_GERO) { func_800B8614(&this->actor, globalCtx, 160.0f); } } @@ -587,7 +585,7 @@ void EnMinifrog_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, 12.0f, 0.0f, 0x1D); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); @@ -605,7 +603,7 @@ void EnMinifrog_UpdateMissingFrog(Actor* thisx, GlobalContext* globalCtx) { } s32 EnMinifrog_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { + Actor* thisx) { if (limbIndex == 1) { pos->z -= 500.0f; } @@ -614,22 +612,22 @@ s32 EnMinifrog_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d *dList = NULL; } - return 0; + return false; } -void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnMinifrog* this = (EnMinifrog*)arg; +void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMinifrog* this = THIS; if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_ReplaceRotation(&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); } if (limbIndex == 4) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } } 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 18be1dc95..4efc18714 100644 --- a/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c +++ b/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c @@ -7,7 +7,7 @@ #include "z_en_minislime.h" #include "overlays/actors/ovl_En_Bigslime/z_en_bigslime.h" -#define FLAGS 0x00000235 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_200) #define THIS ((EnMinislime*)thisx) @@ -121,7 +121,7 @@ static DamageTable sDamageTable = { void EnMinislime_Init(Actor* thisx, GlobalContext* globalCtx) { EnMinislime* this = THIS; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); this->id = this->actor.params; @@ -202,7 +202,7 @@ void EnMinislime_AddIceShardEffect(EnMinislime* this) { } this->frozenAlpha = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ICE_BROKEN); } void EnMinislime_AddIceSmokeEffect(EnMinislime* this, GlobalContext* globalCtx) { @@ -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) { @@ -391,7 +391,7 @@ void EnMinislime_SetupGrowAndShrink(EnMinislime* this) { this->actor.scale.x = 0.19f; this->actor.scale.y = 0.044999998f; this->actor.scale.z = 0.19f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_SLIME_JUMP2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_SLIME_JUMP2); this->actionFunc = EnMinislime_GrowAndShrink; } @@ -453,7 +453,7 @@ void EnMinislime_Idle(EnMinislime* this, GlobalContext* globalCtx) { void EnMinislime_SetupBounce(EnMinislime* this) { this->actor.speedXZ = 0.0f; this->bounceTimer = (this->actionFunc == EnMinislime_GrowAndShrink) ? 1 : 4; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_SLIME_JUMP1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_SLIME_JUMP1); this->actionFunc = EnMinislime_Bounce; } @@ -506,8 +506,8 @@ void EnMinislime_SetupMoveToBigslime(EnMinislime* this) { } this->frozenAlpha = 0; - if ((this->actor.flags & 0x2000) == 0x2000) { - this->actor.flags &= ~0x2000; + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { + this->actor.flags &= ~ACTOR_FLAG_2000; } this->actionFunc = EnMinislime_MoveToBigslime; } @@ -562,8 +562,8 @@ void EnMinislime_SetupDefeatIdle(EnMinislime* this) { } this->frozenAlpha = 0; - if ((this->actor.flags & 0x2000) == 0x2000) { - this->actor.flags &= ~0x2000; + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { + this->actor.flags &= ~ACTOR_FLAG_2000; } this->actor.shape.rot.x = 0; @@ -630,8 +630,8 @@ void EnMinislime_SetupMoveToGekko(EnMinislime* this) { this->actor.velocity.y = 0.0f; this->collider.base.acFlags &= ~AC_ON; this->collider.base.ocFlags1 &= ~OC1_ON; - if ((this->actor.flags & 0x2000) == 0x2000) { - this->actor.flags &= ~0x2000; + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { + this->actor.flags &= ~ACTOR_FLAG_2000; } this->actionFunc = EnMinislime_MoveToGekko; @@ -720,7 +720,7 @@ void EnMinislime_Update(Actor* thisx, GlobalContext* globalCtx) { } else if ((this->actor.params == MINISLIME_FORM_BIGSLIME) && (this->actionFunc != EnMinislime_MoveToBigslime)) { EnMinislime_SetupMoveToBigslime(this); } else { - if ((this->actor.flags & 0x2000) == 0x2000) { + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000)) { this->collider.base.acFlags &= ~AC_HIT; return; } @@ -736,9 +736,9 @@ void EnMinislime_Update(Actor* thisx, GlobalContext* globalCtx) { if ((this->actionFunc != EnMinislime_Disappear) && (this->actionFunc != EnMinislime_Despawn)) { if (this->actionFunc == EnMinislime_MoveToBigslime) { - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } EnMinislime_CheckBackgroundCollision(this); @@ -765,7 +765,7 @@ void EnMinislime_Update(Actor* thisx, GlobalContext* globalCtx) { player = GET_PLAYER(globalCtx); vec1.x = this->actor.world.pos.x; vec1.z = this->actor.world.pos.z; - vec1.y = player->actor.world.pos.y + player->actor.yDistToWater; + vec1.y = player->actor.world.pos.y + player->actor.depthInWater; EffectSsGRipple_Spawn(globalCtx, &vec1, 500, 720, 0); } } diff --git a/src/overlays/actors/ovl_En_Mk/z_en_mk.c b/src/overlays/actors/ovl_En_Mk/z_en_mk.c index 2122321d3..b0e468ab2 100644 --- a/src/overlays/actors/ovl_En_Mk/z_en_mk.c +++ b/src/overlays/actors/ovl_En_Mk/z_en_mk.c @@ -1,6 +1,12 @@ +/* + * File: z_en_mk.c + * Overlay: ovl_En_Mk + * Description: Marine Researcher + */ + #include "z_en_mk.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnMk*)thisx) @@ -9,6 +15,7 @@ void EnMk_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMk_Update(Actor* thisx, GlobalContext* globalCtx); void EnMk_Draw(Actor* thisx, GlobalContext* globalCtx); +s32 func_80959524(GlobalContext* globalCtx); void func_809596A0(EnMk* this, GlobalContext* globalCtx); void func_80959774(EnMk* this, GlobalContext* globalCtx); void func_80959A24(EnMk* this, GlobalContext* globalCtx); @@ -16,7 +23,6 @@ void func_80959C94(EnMk* this, GlobalContext* globalCtx); void func_80959D28(EnMk* this, GlobalContext* globalCtx); void func_80959E18(EnMk* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Mk_InitVars = { ACTOR_EN_MK, ACTORCAT_NPC, @@ -29,49 +35,453 @@ const ActorInit En_Mk_InitVars = { (ActorFunc)EnMk_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8095A260 = { - { 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 +s32 func_809592E0(EnMk* this, s16 index) { + AnimationHeader* sAnimations[] = { + &object_mk_Anim_001C38, &object_mk_Anim_000438, &object_mk_Anim_0007D8, + &object_mk_Anim_0010F4, &object_mk_Anim_001964, + }; -extern ColliderCylinderInit D_8095A260; + if (index == this->unk_27C) { + return false; + } -extern UNK_TYPE D_06001C38; + if ((index < 0) || (index >= 5)) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_809592E0.s") + Animation_PlayLoop(&this->skelAnime, sAnimations[index]); + this->unk_27C = index; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/EnMk_Init.s") +void EnMk_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMk* this = THIS; + s16 cs; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/EnMk_Destroy.s") + this->actor.terminalVelocity = -4.0f; + this->actor.gravity = -1.0f; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_mk_Skel_006CA0, &object_mk_Anim_001C38, this->jointTable, + this->morphTable, OBJECT_MK_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959524.s") + this->unk_27C = -1; + func_809592E0(this, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_8095954C.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959624.s") + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_809596A0.s") + this->actionFunc = func_80959E18; + this->unk_27A = 0; + this->actor.targetMode = 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959774.s") + if (func_80959524(globalCtx) < 7) { + this->unk_27A |= 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959844.s") + cs = this->actor.cutscene; + for (i = 0; i < ARRAY_COUNT(this->unk_276); i++) { + this->unk_276[i] = cs; + if (cs != -1) { + this->actor.cutscene = cs; + cs = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959A24.s") + this->actor.cutscene = this->unk_276[0]; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959C94.s") +void EnMk_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMk* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959D28.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_80959E18.s") +s32 func_80959524(GlobalContext* globalCtx) { + return gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 7; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/EnMk_Update.s") +void func_8095954C(EnMk* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 0x7F)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 0x7F)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_8095A150.s") + switch (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 0x7F)]->action) { + case 1: + case 2: + case 3: + case 4: + case 5: + func_809592E0(this, + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 0x7F)]->action - 1); + break; + } + } else { + func_809592E0(this, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/func_8095A198.s") +void func_80959624(EnMk* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mk/EnMk_Draw.s") + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (this->unk_27A & 4) { + textId = 0xFB9; + } else if (gSaveContext.save.weekEventReg[55] & 0x80) { + textId = 0xFBC; + } else { + textId = 0xFBB; + } + } else { + textId = 0xFBA; + } + Message_StartTextbox(globalCtx, textId, &this->actor); +} + +void func_809596A0(EnMk* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if ((globalCtx->msgCtx.currentTextId == 0xFB9) || (globalCtx->msgCtx.currentTextId == 0xFBB) || + (globalCtx->msgCtx.currentTextId == 0xFBC)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0x400, 0x80); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 5: + if (Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = func_80959774; + } + break; + + case 2: + this->actionFunc = func_80959774; + break; + } +} + +void func_80959774(EnMk* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 3, 0x400, 0x80); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80959624(this, globalCtx); + this->actionFunc = func_809596A0; + } else if ((this->actor.xzDistToPlayer < 120.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 130.0f); + } + + func_8095954C(this, globalCtx); +} + +void func_80959844(EnMk* this, GlobalContext* globalCtx) { + u16 textId; + + if ((this->unk_27A & 2) && (func_80959524(globalCtx) >= 7)) { + textId = 0xFB3; + } else if (gSaveContext.save.weekEventReg[20] & 0x40) { + textId = 0xFB9; + } else if (gSaveContext.save.weekEventReg[19] & 0x40) { + textId = 0xFB5; + } else if (func_80959524(globalCtx) >= 7) { + textId = 0xFB3; + } else { + switch (gSaveContext.save.playerForm) { + case PLAYER_FORM_DEKU: + if (gSaveContext.save.weekEventReg[19] & 0x10) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + textId = 0xFAF; + } else { + textId = 0xFAE; + } + } else { + textId = 0xFAC; + } + break; + + case PLAYER_FORM_GORON: + if (gSaveContext.save.weekEventReg[19] & 8) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + textId = 0xFAB; + } else { + textId = 0xFAA; + } + } else { + textId = 0xFA8; + } + break; + + case PLAYER_FORM_FIERCE_DEITY: + case PLAYER_FORM_HUMAN: + if (func_80959524(globalCtx) > 0) { + textId = 0xFA7; + } else if (gSaveContext.save.weekEventReg[19] & 4) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + textId = 0xFBF; + } else { + textId = 0xFA6; + } + } else { + textId = 0xFA0; + } + break; + + default: + if (func_80959524(globalCtx) > 0) { + textId = 0xFB0; + } else if (gSaveContext.save.weekEventReg[19] & 0x20) { + textId = 0xFB2; + } else { + textId = 0xFB1; + } + break; + } + } + Message_StartTextbox(globalCtx, textId, &this->actor); +} + +void func_80959A24(EnMk* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + this->unk_27A |= 1; + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 2: + break; + + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0xFA1: + case 0xFA3: + case 0xFA4: + case 0xFAA: + case 0xFAE: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0xFA2: + if (gSaveContext.save.weekEventReg[55] & 0x80) { + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + break; + } + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0xFA5: + case 0xFA6: + case 0xFA7: + case 0xFA9: + case 0xFAB: + case 0xFAD: + case 0xFAF: + case 0xFB0: + case 0xFB2: + case 0xFBD: + case 0xFBE: + case 0xFBF: + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + break; + + case 0xFA0: + gSaveContext.save.weekEventReg[19] |= 4; + func_80151938(globalCtx, 0xFA1); + break; + + case 0xFA8: + gSaveContext.save.weekEventReg[19] |= 8; + if (gSaveContext.save.weekEventReg[55] & 0x80) { + func_80151938(globalCtx, 0xFBD); + break; + } + func_80151938(globalCtx, 0xFA9); + break; + + case 0xFAC: + gSaveContext.save.weekEventReg[19] |= 0x10; + if (gSaveContext.save.weekEventReg[55] & 0x80) { + func_80151938(globalCtx, 0xFBE); + break; + } + func_80151938(globalCtx, 0xFAD); + break; + + case 0xFB1: + gSaveContext.save.weekEventReg[19] |= 0x20; + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + break; + + case 0xFB3: + case 0xFB4: + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + this->actor.flags &= ~ACTOR_FLAG_10000; + break; + + case 0xFB5: + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80959E18; + break; + } + } + break; + } +} + +void func_80959C94(EnMk* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80959A24; + this->unk_27A &= ~2; + Message_StartTextbox(globalCtx, 0xFB3, &this->actor); + } else { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 350.0f, 1000.0f, -1); + } +} + +void func_80959D28(EnMk* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if ((globalCtx->csCtx.state == 0) && (this->actor.cutscene == -1)) { + if (gSaveContext.save.weekEventReg[20] & 0x40) { + this->unk_27A &= ~1; + this->actionFunc = func_80959774; + this->actor.home.rot.y += 0x4E20; + this->unk_27A |= 4; + } else { + this->actionFunc = func_80959E18; + } + this->actor.cutscene = this->unk_276[0]; + } else { + if (this->actor.cutscene != -1) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actor.cutscene = -1; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } + func_8095954C(this, globalCtx); + } +} + +void func_80959E18(EnMk* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp22 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + SkelAnime_Update(&this->skelAnime); + + if (gSaveContext.save.weekEventReg[20] & 0x40) { + this->unk_27A &= ~1; + this->actionFunc = func_80959774; + this->actor.home.rot.y += 0x4E20; + return; + } + + if (func_800B8718(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.ocarinaMode = 4; + this->actionFunc = func_80959D28; + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + this->actor.cutscene = this->unk_276[0]; + gSaveContext.save.weekEventReg[20] |= 0x40; + Item_Give(globalCtx, ITEM_SONG_NOVA); + } else { + this->actor.cutscene = this->unk_276[1]; + } + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80959844(this, globalCtx); + this->actionFunc = func_80959A24; + this->unk_27A |= 1; + } else if ((this->unk_27A & 2) && (func_80959524(globalCtx) >= 7)) { + this->actionFunc = func_80959C94; + } else if ((this->actor.xzDistToPlayer < 120.0f) && (ABS_ALT(sp22) <= 0x4300)) { + this->unk_27A |= 1; + func_800B8614(&this->actor, globalCtx, 200.0f); + if (!(gSaveContext.save.weekEventReg[20] & 0x40) && (gSaveContext.save.weekEventReg[19] & 0x40)) { + func_800B874C(&this->actor, globalCtx, 200.0f, 100.0f); + } + } else { + this->unk_27A &= ~1; + } + func_8095954C(this, globalCtx); +} + +void EnMk_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMk* this = THIS; + Vec3s sp38; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + this->actionFunc(this, globalCtx); + + if ((this->unk_27A & 1) && !Cutscene_CheckActorAction(globalCtx, 0x7F)) { + func_800E9250(globalCtx, &this->actor, &this->unk_270, &sp38, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_270.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_270.y, 0, 6, 0x1838, 0x64); + } +} + +s32 EnMk_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnMk* this = THIS; + + if (limbIndex == OBJECT_MK_LIMB_0B) { + rot->y -= this->unk_270.y; + rot->z += this->unk_270.x; + } + return false; +} + +Vec3f D_8095A2A0 = { 1000.0f, -100.0f, 0.0f }; + +void EnMk_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMk* this = THIS; + + if (limbIndex == OBJECT_MK_LIMB_0B) { + Matrix_MultVec3f(&D_8095A2A0, &this->actor.focus.pos); + } +} + +void EnMk_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMk* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnMk_OverrideLimbDraw, EnMk_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Mk/z_en_mk.h b/src/overlays/actors/ovl_En_Mk/z_en_mk.h index 715a07c84..fee132ccd 100644 --- a/src/overlays/actors/ovl_En_Mk/z_en_mk.h +++ b/src/overlays/actors/ovl_En_Mk/z_en_mk.h @@ -2,6 +2,7 @@ #define Z_EN_MK_H #include "global.h" +#include "objects/object_mk/object_mk.h" struct EnMk; @@ -9,7 +10,14 @@ typedef void (*EnMkActionFunc)(struct EnMk*, GlobalContext*); typedef struct EnMk { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x13C]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; + /* 0x01D4 */ Vec3s jointTable[OBJECT_MK_LIMB_MAX]; + /* 0x0222 */ Vec3s morphTable[OBJECT_MK_LIMB_MAX]; + /* 0x0270 */ Vec3s unk_270; + /* 0x0276 */ s16 unk_276[2]; + /* 0x027A */ u16 unk_27A; + /* 0x027C */ s16 unk_27C; /* 0x0280 */ EnMkActionFunc actionFunc; } EnMk; // size = 0x284 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 81ba9a6ec..45eff8050 100644 --- a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c +++ b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c @@ -1,6 +1,12 @@ +/* + * File: z_en_mkk.c + * Overlay: ovl_En_Mkk + * Description: Black and White Boe (Name origin: Makkurokurosuke) + */ + #include "z_en_mkk.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnMkk*)thisx) @@ -79,7 +85,7 @@ static DamageTable D_80A4F754 = { // static InitChainEntry sInitChain[] = { static InitChainEntry D_80A4F774[] = { ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE), - ICHAIN_F32(minVelocityY, -5, ICHAIN_CONTINUE), + ICHAIN_F32(terminalVelocity, -5, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 3000, ICHAIN_STOP), }; 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_Mm/z_en_mm.c b/src/overlays/actors/ovl_En_Mm/z_en_mm.c index fc6859542..7cdddfcfd 100644 --- a/src/overlays/actors/ovl_En_Mm/z_en_mm.c +++ b/src/overlays/actors/ovl_En_Mm/z_en_mm.c @@ -1,6 +1,13 @@ -#include "z_en_mm.h" +/* + * File: z_en_mm.c + * Overlay: ovl_En_Mm + * Description: Rock Sirloin + */ -#define FLAGS 0x00000010 +#include "z_en_mm.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnMm*)thisx) @@ -12,10 +19,8 @@ void EnMm_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80965D3C(EnMm* this, GlobalContext* globalCtx); void func_80965DB4(EnMm* this, GlobalContext* globalCtx); void func_8096611C(EnMm* this, GlobalContext* globalCtx); - void EnMm_SetupAction(EnMm* this, EnMmActionFunc actionFunc); -#if 0 const ActorInit En_Mm_InitVars = { ACTOR_EN_MM, ACTORCAT_ITEMACTION, @@ -28,38 +33,190 @@ const ActorInit En_Mm_InitVars = { (ActorFunc)EnMm_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80966340 = { - { COLTYPE_METAL, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00100000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00100000, 0x00, 0x00 }, + { 0x01000202, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 6, 30, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8096636C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 270, ICHAIN_STOP), }; -#endif +void EnMm_SetupAction(EnMm* this, EnMmActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern ColliderCylinderInit D_80966340; -extern InitChainEntry D_8096636C[]; +void func_80965BBC(EnMm* this) { + EnMm_SetupAction(this, func_8096611C); + this->actor.room = -1; + if (this->actor.parent->id == ACTOR_PLAYER) { + gSaveContext.unk_1014 = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/EnMm_SetupAction.s") +void EnMm_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMm* this = THIS; + EnMmActionFunc action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/func_80965BBC.s") + if ((this->actor.params >= 0) && ((!(gSaveContext.save.weekEventReg[37] & 0x10)) || + (gSaveContext.save.weekEventReg[37] & 8) || (gSaveContext.unk_1014 != 0))) { + Actor_MarkForDeath(&this->actor); + return; + } + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 50.0f, ActorShadow_DrawCircle, 1.2f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + if (this->actor.parent != NULL) { + func_80965BBC(this); + return; + } + if (this->actor.cutscene >= 0) { + action = func_80965D3C; + } else { + action = func_80965DB4; + } + EnMm_SetupAction(this, action); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/EnMm_Init.s") +void EnMm_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMm* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/EnMm_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/func_80965D3C.s") +void func_80965D3C(EnMm* this, GlobalContext* globalCtx) { + s16 cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/func_80965DB4.s") + if (ActorCutscene_GetCanPlayNext(cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(cutscene, &this->actor); + EnMm_SetupAction(this, func_80965DB4); + } else { + ActorCutscene_SetIntentToPlay(cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/func_8096611C.s") +void func_80965DB4(EnMm* this, GlobalContext* globalCtx) { + s16 direction; + Vec3f sp50; + s16 unused; + f32 temp_f14; + f32 temp_f12; + f32 temp_f2; + s32 angle; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/EnMm_Update.s") + if (Actor_HasParent(&this->actor, globalCtx)) { + func_80965BBC(this); + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_PULL_UP_ROCK); + } else { + if ((this->actor.velocity.y > 0.0f) && (this->actor.bgCheckFlags & 0x10)) { + this->actor.velocity.y = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm/EnMm_Draw.s") + if ((this->actor.speedXZ != 0.0f) && (this->actor.bgCheckFlags & 8)) { + angle = BINANG_SUB(this->actor.world.rot.y, BINANG_ROT180(this->actor.wallYaw)); + this->actor.world.rot.y += BINANG_SUB(0x8000, (s16)(angle * 2)); + this->actor.speedXZ *= 0.5f; + CollisionCheck_SpawnShieldParticles(globalCtx, &this->actor.world.pos); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HUMAN_BOUND); + } + + if (!(this->actor.bgCheckFlags & 1)) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.08f); + } else { + temp_f14 = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; + temp_f12 = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; + func_800B75A0(this->actor.floorPoly, &sp50, &unused); + temp_f14 += 3.0f * sp50.x; + temp_f12 += 3.0f * sp50.z; + temp_f2 = sqrtf(SQ(temp_f14) + SQ(temp_f12)); + + if ((temp_f2 < this->actor.speedXZ) || + (SurfaceType_GetSlope(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 1)) { + this->actor.speedXZ = CLAMP_MAX(temp_f2, 16.0f); + this->actor.world.rot.y = Math_FAtan2F(temp_f12, temp_f14); + } + + if (!Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f)) { + direction = this->actor.world.rot.y; + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->actor.shape.rot.y)) > 0x4000) { + direction = BINANG_ROT180(direction); + } + Math_ScaledStepToS(&this->actor.shape.rot.y, direction, this->actor.speedXZ * 100.0f); + this->unk_190 += (s16)(this->actor.speedXZ * 800.0f); + } + + if (this->actor.bgCheckFlags & 2) { + if (this->actor.velocity.y < -6.0f) { + this->actor.velocity.y *= -0.3f; + this->actor.bgCheckFlags &= ~1; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HUMAN_BOUND); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 50.0f, 30.0f); + } + } + + Actor_MoveWithGravity(&this->actor); + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_8096611C(EnMm* this, GlobalContext* globalCtx) { + if (Actor_HasNoParent(&this->actor, globalCtx)) { + EnMm_SetupAction(this, func_80965DB4); + this->actor.room = globalCtx->roomCtx.currRoom.num; + this->actor.bgCheckFlags &= ~1; + Math_Vec3s_ToVec3f(&this->actor.prevPos, &this->actor.home.rot); + gSaveContext.unk_1014 = 0; + } else { + Math_Vec3f_ToVec3s(&this->actor.home.rot, &this->actor.parent->world.pos); + } + Math_ScaledStepToS(&this->unk_190, 0, 2000); +} + +void EnMm_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMm* this = THIS; + + Collider_ResetCylinderAC(globalCtx, &this->collider.base); + this->actionFunc(this, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 10.0f, 20.0f, 31); + Actor_SetFocus(&this->actor, 20.0f); +} + +void EnMm_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMm* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + if (this->unk_190 != 0) { + s16 rotY = this->actor.world.rot.y - this->actor.shape.rot.y; + + Matrix_RotateYS(rotY, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_190, MTXMODE_APPLY); + Matrix_RotateYS(-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++, gameplay_keep_DL_055628); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Mm/z_en_mm.h b/src/overlays/actors/ovl_En_Mm/z_en_mm.h index bfda85e4a..d83ebc961 100644 --- a/src/overlays/actors/ovl_En_Mm/z_en_mm.h +++ b/src/overlays/actors/ovl_En_Mm/z_en_mm.h @@ -9,10 +9,9 @@ typedef void (*EnMmActionFunc)(struct EnMm*, GlobalContext*); typedef struct EnMm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x50]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ s16 unk_190; /* 0x0194 */ EnMmActionFunc actionFunc; } EnMm; // size = 0x198 -extern const ActorInit En_Mm_InitVars; - #endif // Z_EN_MM_H 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 4d008e947..79b4987e9 100644 --- a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c +++ b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_mm2.c + * Overlay: ovl_En_Mm2 + * Description: Postman's Letter to Himself + */ + #include "z_en_mm2.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnMm2*)thisx) @@ -9,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, @@ -25,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 = Message_GetState(&globalCtx->msgCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Update.s") + if (talkState != 2) { + if (talkState == 5 && Message_ShouldAdvance(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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x277B, &this->actor); + this->actionFunc = EnMm2_Reading; + } else if ((this->actor.xzDistToPlayer < 60.0f) && (Player_IsFacingActor(&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_Mm3/z_en_mm3.c b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c index 8e2e633cf..6ee806d2e 100644 --- a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c +++ b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.c @@ -1,6 +1,13 @@ -#include "z_en_mm3.h" +/* + * File: z_en_mm3.c + * Overlay: ovl_En_Mm3 + * Description: Counting Game Postman + */ -#define FLAGS 0x00000019 +#include "z_en_mm3.h" +#include "objects/object_mm/object_mm.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnMm3*)thisx) @@ -9,7 +16,19 @@ void EnMm3_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMm3_Update(Actor* thisx, GlobalContext* globalCtx); void EnMm3_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A6F270(EnMm3* this); +void func_80A6F2C8(EnMm3* this, GlobalContext* globalCtx); +void func_80A6F9C8(EnMm3* this); +void func_80A6F9DC(EnMm3* this, GlobalContext* globalCtx); +void func_80A6FBA0(EnMm3* this); +void func_80A6FBFC(EnMm3* this, GlobalContext* globalCtx); +void func_80A6FE1C(EnMm3* this); +void func_80A6FE30(EnMm3* this, GlobalContext* globalCtx); +void func_80A6FED8(EnMm3* this); +void func_80A6FEEC(EnMm3* this, GlobalContext* globalCtx); +s32 func_80A6FFAC(EnMm3* this, GlobalContext* globalCtx); +void func_80A70084(EnMm3* this, GlobalContext* globalCtx); + const ActorInit En_Mm3_InitVars = { ACTOR_EN_MM3, ACTORCAT_NPC, @@ -22,61 +41,525 @@ const ActorInit En_Mm3_InitVars = { (ActorFunc)EnMm3_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A703F0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 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_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 63, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80A7041C = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfo sAnimations[] = { + { &object_mm_Anim_002238, 1.0f, 0.0f, 0.0f, 0, -7.0f }, { &object_mm_Anim_00A4E0, -1.0f, 0.0f, 0.0f, 2, -7.0f }, + { &object_mm_Anim_00C640, 1.0f, 0.0f, 0.0f, 0, -7.0f }, { &object_mm_Anim_00A4E0, 1.0f, 0.0f, 0.0f, 2, -7.0f }, + { &object_mm_Anim_000468, 1.0f, 0.0f, 0.0f, 0, -7.0f }, { &object_mm_Anim_00CD90, 1.0f, 0.0f, 0.0f, 0, -12.0f }, + { &object_mm_Anim_00DA50, 1.0f, 0.0f, 0.0f, 0, -12.0f }, { &object_mm_Anim_00DA50, 1.0f, 0.0f, 10.0f, 2, -10.0f }, +}; -extern ColliderCylinderInit D_80A703F0; -extern CollisionCheckInfoInit2 D_80A7041C; +#include "overlays/ovl_En_Mm3/ovl_En_Mm3.c" -extern UNK_TYPE D_0600A4E0; +Vec3f D_80A704F0 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/EnMm3_Init.s") +TexturePtr D_80A704FC[] = { object_mm_Tex_002950, object_mm_Tex_002750 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/EnMm3_Destroy.s") +void EnMm3_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMm3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F22C.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 21.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_mm_Skel_0096E8, &object_mm_Anim_00A4E0, this->jointTable, + this->morphTable, 16); + Animation_Change(&this->skelAnime, &object_mm_Anim_00A4E0, -1.0f, Animation_GetLastFrame(&object_mm_Anim_00A4E0), + 0.0f, 2, 0.0f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + this->actor.parent = NULL; + this->actor.targetMode = 0; + this->unk_1DC = 1; + this->unk_2B4 = 0; + this->unk_2AE = 0; + this->unk_2B0 &= ~1; + this->actor.world.pos.y = this->actor.floorHeight; + func_80A6F270(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F270.s") +void EnMm3_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMm3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F2C8.s") + gSaveContext.save.weekEventReg[63] &= (u8)~1; + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F3B4.s") +s32 func_80A6F22C(EnMm3* this) { + s16 abs = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F5E4.s") + abs = ABS_ALT(abs); + if (abs < 0x4000) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F9C8.s") +void func_80A6F270(EnMm3* this) { + this->unk_1DC = 1; + this->unk_2B0 &= ~1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + this->actionFunc = func_80A6F2C8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6F9DC.s") +void func_80A6F2C8(EnMm3* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x278A, &this->actor); + this->unk_2B4 = 0x278A; + func_80A6F9C8(this); + } else if (func_80A6F22C(this)) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FBA0.s") + Math_SmoothStepToS(&this->unk_2A0.x, 0, 5, 0x1000, 0x100); + Math_SmoothStepToS(&this->unk_2A0.y, 0, 5, 0x1000, 0x100); + Math_SmoothStepToS(&this->unk_2A6.x, 0, 5, 0x1000, 0x100); + Math_SmoothStepToS(&this->unk_2A6.y, 0, 5, 0x1000, 0x100); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FBFC.s") +void func_80A6F3B4(EnMm3* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(globalCtx)) { + switch (this->unk_2B4) { + case 0x278E: + if (globalCtx->msgCtx.choiceIndex == 0) { + if (this->unk_2B2 & 0x20) { + if (gSaveContext.save.playerData.rupees >= globalCtx->msgCtx.unk1206C) { + func_8019F208(); + Message_StartTextbox(globalCtx, 0x2790, &this->actor); + this->unk_2B4 = 0x2790; + func_801159EC(-globalCtx->msgCtx.unk1206C); + } else { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x279C, &this->actor); + this->unk_2B4 = 0x279C; + func_80151BB4(globalCtx, 0xB); + } + } else { + func_8019F208(); + Message_StartTextbox(globalCtx, 0x2790, &this->actor); + this->unk_2B4 = 0x2790; + } + } else { + func_8019F230(); + Message_StartTextbox(globalCtx, 0x278F, &this->actor); + this->unk_2B4 = 0x278F; + func_80151BB4(globalCtx, 0xB); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FE1C.s") + case 0x279A: + if (globalCtx->msgCtx.choiceIndex == 0) { + if (gSaveContext.save.playerData.rupees >= globalCtx->msgCtx.unk1206C) { + func_8019F208(); + Message_StartTextbox(globalCtx, 0x2790, &this->actor); + this->unk_2B4 = 0x2790; + func_801159EC(-globalCtx->msgCtx.unk1206C); + } else { + play_sound(NA_SE_SY_ERROR); + Message_StartTextbox(globalCtx, 0x279C, &this->actor); + this->unk_2B4 = 0x279C; + func_80151BB4(globalCtx, 0xB); + } + } else { + func_8019F230(); + Message_StartTextbox(globalCtx, 0x279B, &this->actor); + this->unk_2B4 = 0x279B; + func_80151BB4(globalCtx, 0xB); + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FE30.s") +void func_80A6F5E4(EnMm3* this, GlobalContext* globalCtx) { + if (((this->unk_2B4 != 0x2791) || (this->unk_2AC == 0)) && Message_ShouldAdvance(globalCtx)) { + switch (this->unk_2B4) { + case 0x278A: + if (func_80A6FFAC(this, globalCtx)) { + Message_StartTextbox(globalCtx, 0x279D, &this->actor); + this->unk_2B4 = 0x279D; + } else { + func_80A70084(this, globalCtx); + if (Player_GetMask(globalCtx) == PLAYER_MASK_BUNNY) { + Message_StartTextbox(globalCtx, 0x27A0, &this->actor); + this->unk_2B4 = 0x27A0; + } else { + Message_StartTextbox(globalCtx, 0x278B, &this->actor); + this->unk_2B4 = 0x278B; + } + } + this->unk_1DC = 0; + this->unk_2B0 |= 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 7); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FED8.s") + case 0x278B: + case 0x27A0: + this->unk_2AE = 0; + Message_StartTextbox(globalCtx, 0x278C, &this->actor); + this->unk_2B4 = 0x278C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FEEC.s") + case 0x278C: + Message_StartTextbox(globalCtx, 0x278D, &this->actor); + this->unk_2B4 = 0x278D; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A6FFAC.s") + case 0x279D: + this->unk_2AE = 0; + Message_StartTextbox(globalCtx, 0x279E, &this->actor); + this->unk_2B4 = 0x279E; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A70084.s") + case 0x279E: + this->unk_2B2 |= 0x20; + Message_StartTextbox(globalCtx, 0x279F, &this->actor); + this->unk_2B4 = 0x279F; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/EnMm3_Update.s") + case 0x278D: + case 0x279F: + Message_StartTextbox(globalCtx, 0x278E, &this->actor); + this->unk_2B4 = 0x278E; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A701E0.s") + case 0x2791: + if (gSaveContext.unk_3DE0[0] == 1000) { + Message_StartTextbox(globalCtx, 0x2792, &this->actor); + this->unk_2B4 = 0x2792; + } else if ((gSaveContext.unk_3DE0[0] >= 1500)) { + Message_StartTextbox(globalCtx, 0x2797, &this->actor); + this->unk_2B4 = 0x2797; + } else if ((gSaveContext.unk_3DE0[0] <= 1050) && (gSaveContext.unk_3DE0[0] >= 950)) { + Message_StartTextbox(globalCtx, 0x2795, &this->actor); + this->unk_2B4 = 0x2795; + } else { + Message_StartTextbox(globalCtx, 0x2796, &this->actor); + this->unk_2B4 = 0x2796; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/func_80A702B0.s") + case 0x2792: + Message_StartTextbox(globalCtx, 0x2793, &this->actor); + this->unk_2B4 = 0x2793; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm3/EnMm3_Draw.s") + case 0x2793: + func_801477B4(globalCtx); + func_80A6FE1C(this); + func_80A6FE30(this, globalCtx); + break; + + case 0x2795: + case 0x2796: + case 0x2797: + if (gSaveContext.save.weekEventReg[63] & 2) { + Message_StartTextbox(globalCtx, 0x279B, &this->actor); + this->unk_2B4 = 0x279B; + func_80151BB4(globalCtx, 0xB); + } else { + Message_StartTextbox(globalCtx, 0x2798, &this->actor); + this->unk_2B4 = 0x2798; + } + break; + + case 0x2798: + Message_StartTextbox(globalCtx, 0x2799, &this->actor); + this->unk_2B4 = 0x2799; + break; + + case 0x2799: + Message_StartTextbox(globalCtx, 0x279A, &this->actor); + this->unk_2B4 = 0x279A; + break; + } + } else if ((this->unk_2AC > 0) && (this->unk_2B4 == 0x2791)) { + this->unk_2AC--; + if (this->unk_2AC == 0) { + if (gSaveContext.unk_3DE0[0] == 1000) { + func_801A3098(0x922); + } else { + play_sound(NA_SE_SY_ERROR); + } + } + } +} + +void func_80A6F9C8(EnMm3* this) { + this->actionFunc = func_80A6F9DC; +} + +void func_80A6F9DC(EnMm3* this, GlobalContext* globalCtx) { + this->unk_2B0 &= ~2; + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + break; + + case 3: + this->unk_2B0 |= 2; + break; + + case 4: + func_80A6F3B4(this, globalCtx); + break; + + case 5: + func_80A6F5E4(this, globalCtx); + break; + + case 6: + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_2B4 == 0x2790) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags1 |= 0x20; + if (Player_GetMask(globalCtx) == PLAYER_MASK_BUNNY) { + func_8010EA9C(0, 2); + } else { + func_8010EA9C(0, 0); + } + func_801477B4(globalCtx); + play_sound(NA_SE_SY_START_SHOT); + func_80A6FBA0(this); + } else { + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; + func_80A6F270(this); + } + } + break; + } + + if ((this->skelAnime.mode == 2) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + } + + if (((this->unk_2B4 == 0x279D) || (this->unk_2B4 == 0x27A0) || (this->unk_2B4 == 0x278B)) && + Animation_OnFrame(&this->skelAnime, 8.0f) && (this->unk_2AE == 0)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_LIE_DOWN_ON_BED); + this->unk_2AE = 1; + } +} + +void func_80A6FBA0(EnMm3* this) { + func_801A5BD0(0x6F); + func_801A0238(0, 5); + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; + this->actionFunc = func_80A6FBFC; +} + +void func_80A6FBFC(EnMm3* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (gSaveContext.unk_3DD0[0] == 0x10) { + player->stateFlags1 &= ~0x20; + this->actor.flags |= ACTOR_FLAG_10000; + if (gSaveContext.unk_3DE0[0] > 1500) { + gSaveContext.unk_3DE0[0] = 1500; + } else if ((((void)0, gSaveContext.unk_3DE0[0]) >= (OSTime)(995 - XREG(16))) && + (((void)0, gSaveContext.unk_3DE0[0]) <= (OSTime)(1005 + XREG(17)))) { + gSaveContext.unk_3DE0[0] = 1000; + } + } else if (gSaveContext.unk_3DE0[0] > 1500) { + gSaveContext.unk_3DD0[0] = 15; + gSaveContext.unk_3DC8 = osGetTime(); + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_801A5BD0(0); + func_801A0238(0x7F, 5); + Message_StartTextbox(globalCtx, 0x2791, &this->actor); + this->unk_2B4 = 0x2791; + this->unk_2AC = 7; + gSaveContext.unk_3DD0[0] = 0; + this->actor.flags &= ~ACTOR_FLAG_10000; + play_sound(NA_SE_SY_START_SHOT); + func_80A6F9C8(this); + } else { + func_800B8614(&this->actor, globalCtx, this->actor.xzDistToPlayer + 10.0f); + func_80123E90(globalCtx, &this->actor); + if (Player_GetMask(globalCtx) == PLAYER_MASK_BUNNY) { + play_sound(NA_SE_SY_STOPWATCH_TIMER_INF - SFX_FLAG); + } else { + play_sound(NA_SE_SY_STOPWATCH_TIMER_3 - SFX_FLAG); + } + } +} + +void func_80A6FE1C(EnMm3* this) { + this->actionFunc = func_80A6FE30; +} + +void func_80A6FE30(EnMm3* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + if (!(gSaveContext.save.weekEventReg[77] & 1)) { + gSaveContext.save.weekEventReg[77] |= 1; + } + this->actor.parent = NULL; + func_80A6FED8(this); + } else if (gSaveContext.save.weekEventReg[77] & 1) { + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } +} + +void func_80A6FED8(EnMm3* this) { + this->actionFunc = func_80A6FEEC; +} + +void func_80A6FEEC(EnMm3* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + player->stateFlags1 &= ~0x20; + Message_StartTextbox(globalCtx, 0x2794, &this->actor); + this->unk_2B4 = 0x2794; + func_80151BB4(globalCtx, 0xB); + func_80151BB4(globalCtx, 0x2B); + this->actor.flags &= ~ACTOR_FLAG_10000; + func_80A6F9C8(this); + } else { + func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + } +} + +s32 func_80A6FFAC(EnMm3* this, GlobalContext* globalCtx) { + switch (gSaveContext.save.playerForm) { + case 4: + if (Player_GetMask(globalCtx) == PLAYER_MASK_BUNNY) { + if (this->unk_2B2 & 0x10) { + return true; + } + } else if (this->unk_2B2 & 1) { + return true; + } + break; + + case 3: + if (this->unk_2B2 & 2) { + return true; + } + break; + + case 2: + if (this->unk_2B2 & 4) { + return true; + } + break; + + case 1: + if (this->unk_2B2 & 8) { + return true; + } + break; + } + + return false; +} + +void func_80A70084(EnMm3* this, GlobalContext* globalCtx) { + switch (gSaveContext.save.playerForm) { + case 4: + if (Player_GetMask(globalCtx) == PLAYER_MASK_BUNNY) { + this->unk_2B2 |= 0x10; + this->unk_2B2 |= 1; + } else { + this->unk_2B2 |= 1; + } + break; + + case 3: + this->unk_2B2 |= 2; + break; + + case 2: + this->unk_2B2 |= 4; + break; + + case 1: + this->unk_2B2 |= 8; + break; + } +} + +void EnMm3_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMm3* this = THIS; + + this->actionFunc(this, globalCtx); + + SkelAnime_Update(&this->skelAnime); + + if (this->unk_2B0 & 1) { + func_800E9250(globalCtx, &this->actor, &this->unk_2A0, &this->unk_2A6, this->actor.focus.pos); + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +s32 EnMm3_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnMm3* this = THIS; + + if (limbIndex == 8) { + rot->x += this->unk_2A6.y; + rot->y -= this->unk_2A6.x; + } else if (limbIndex == 15) { + rot->x += this->unk_2A0.y; + rot->z += this->unk_2A0.x; + if ((this->unk_2B0 & 2) && ((globalCtx->gameplayFrames % 3) == 0)) { + Matrix_Translate(40.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + } + return false; +} + +void EnMm3_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnMm3* this = THIS; + + if (limbIndex == 15) { + Matrix_MultVec3f(&D_80A704F0, &this->actor.focus.pos); + } +} + +void EnMm3_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMm3* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A704FC[this->unk_1DC])); + gSPSegment(POLY_OPA_DISP++, 0x0C, sEnMm3DL); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnMm3_OverrideLimbDraw, EnMm3_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h index b3a8c2893..fe2e7ba06 100644 --- a/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h +++ b/src/overlays/actors/ovl_En_Mm3/z_en_mm3.h @@ -9,9 +9,20 @@ typedef void (*EnMm3ActionFunc)(struct EnMm3*, GlobalContext*); typedef struct EnMm3 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ ColliderCylinder collider; /* 0x01D4 */ EnMm3ActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0xE0]; + /* 0x01D8 */ UNK_TYPE1 unk1D8[4]; + /* 0x01DC */ s32 unk_1DC; + /* 0x01E0 */ Vec3s jointTable[16]; + /* 0x0240 */ Vec3s morphTable[16]; + /* 0x02A0 */ Vec3s unk_2A0; + /* 0x02A6 */ Vec3s unk_2A6; + /* 0x02AC */ s16 unk_2AC; + /* 0x02AE */ s16 unk_2AE; + /* 0x02B0 */ u16 unk_2B0; + /* 0x02B2 */ u16 unk_2B2; + /* 0x02B4 */ u16 unk_2B4; } EnMm3; // size = 0x2B8 extern const ActorInit En_Mm3_InitVars; diff --git a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c index e0b247f54..85996fe6c 100644 --- a/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c +++ b/src/overlays/actors/ovl_En_Mnk/z_en_mnk.c @@ -1,6 +1,12 @@ +/* + * File: z_en_mnk.c + * Overlay: ovl_En_Mnk + * Description: Monkey + */ + #include "z_en_mnk.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnMnk*)thisx) 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 3126b899b..4135fe701 100644 --- a/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -1,6 +1,13 @@ -#include "z_en_ms.h" +/* + * File: z_en_ms.c + * Overlay: ovl_En_Ms + * Description: Bean Seller + */ -#define FLAGS 0x00000009 +#include "z_en_ms.h" +#include "objects/object_ms/object_ms.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnMs*)thisx) @@ -9,7 +16,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, @@ -22,38 +33,154 @@ 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 +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -extern ColliderCylinderInit D_80952BA0; -extern InitChainEntry D_80952BCC[]; + Actor_ProcessInitChain(thisx, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ms_Skel_003DC0, &object_ms_Anim_0005EC, 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, ActorShadow_DrawCircle, 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; +} -extern UNK_TYPE D_060005EC; +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Init.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Destroy.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_80952734.s") + if (gSaveContext.save.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_809527F8.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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_809529AC.s") +void EnMs_Talk(EnMs* this, GlobalContext* globalCtx) { + switch (Message_GetState(&globalCtx->msgCtx)) { + case 6: + if (Message_ShouldAdvance(globalCtx)) { + this->actionFunc = EnMs_Wait; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_80952A1C.s") + case 5: + if (Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + Actor_PickUp(&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_Update.s") + case 4: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: // yes + func_801477B4(globalCtx); + if (gSaveContext.save.playerData.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(); + Actor_PickUp(&this->actor, globalCtx, GI_MAGIC_BEANS, 90.0f, 10.0f); + func_801159EC(-10); + this->actionFunc = EnMs_Sell; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Draw.s") + 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 { + Actor_PickUp(&this->actor, globalCtx, GI_MAGIC_BEANS, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void EnMs_TalkAfterPurchase(EnMs* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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_SetFocus(&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 0a1497130..aa96b13c1 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,6 +1,12 @@ +/* + * File: z_en_mt_tag.c + * Overlay: ovl_En_Mt_tag + * Description: Controls the Goron Race minigame + */ + #include "z_en_mt_tag.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnMttag*)thisx) @@ -8,15 +14,20 @@ void EnMttag_Init(Actor* thisx, GlobalContext* globalCtx); void EnMttag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMttag_Update(Actor* thisx, GlobalContext* globalCtx); -void func_809CF9A0(EnMttag* this, GlobalContext* globalCtx); -void func_809CFA00(EnMttag* this, GlobalContext* globalCtx); -void func_809CFA54(EnMttag* this, GlobalContext* globalCtx); -void func_809CFC38(EnMttag* this, GlobalContext* globalCtx); -void func_809CFD98(EnMttag* this, GlobalContext* globalCtx); -void func_809CFE28(EnMttag* this, GlobalContext* globalCtx); -void func_809CFF94(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_ShowIntroCutscene(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_WaitForIntroCutsceneToEnd(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_RaceStart(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_Race(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_RaceFinish(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_PotentiallyRestartRace(EnMttag* this, GlobalContext* globalCtx); +void EnMttag_HandleCantWinChoice(EnMttag* this, GlobalContext* globalCtx); + +typedef enum { + GORON_RACE_CHEAT_NO_CHEATING, + GORON_RACE_CHEAT_FALSE_START, + GORON_RACE_CHEAT_TRYING_TO_REACH_GOAL_FROM_BEHIND, +} PlayerCheatStatus; -#if 0 const ActorInit En_Mt_tag_InitVars = { ACTOR_EN_MT_TAG, ACTORCAT_BG, @@ -29,42 +40,475 @@ const ActorInit En_Mt_tag_InitVars = { (ActorFunc)NULL, }; -#endif +static s32 sStartingCheckpointPerSceneExitIndex[] = { + 0, 0, 0, 0, 1, 9, 12, 16, 19, 22, 26, 29, 30, 32, 34, 36, 39, 42, 45, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF350.s") +// The Y-positions here are never used by any part of this actor. +static Vec3f sCheckpointPositions[] = { + { -105.0f, 1000.0f, -240.0f }, { -1751.0f, 1000.0f, -240.0f }, { -3138.0f, 1000.0f, -74.0f }, + { -4617.0f, 1000.0f, 277.0f }, { -5060.0f, 1000.0f, 388.0f }, { -5412.0f, 1000.0f, 573.0f }, + { -5523.0f, 1000.0f, 1035.0f }, { -5393.0f, 1000.0f, 1405.0f }, { -5060.0f, 1000.0f, 1553.0f }, + { -3933.0f, 1000.0f, 1479.0f }, { -3212.0f, 1000.0f, 1461.0f }, { -2805.0f, 1000.0f, 1645.0f }, + { -2638.0f, 1000.0f, 2071.0f }, { -2823.0f, 1000.0f, 2422.0f }, { -3212.0f, 1000.0f, 2607.0f }, + { -3785.0f, 1000.0f, 2977.0f }, { -4321.0f, 1000.0f, 3501.0f }, { -4654.0f, 1000.0f, 4185.0f }, + { -4802.0f, 1000.0f, 4779.0f }, { -4672.0f, 1000.0f, 5426.0f }, { -4339.0f, 1000.0f, 6037.0f }, + { -3748.0f, 1000.0f, 6314.0f }, { -2749.0f, 1000.0f, 6478.0f }, { -2453.0f, 1000.0f, 6922.0f }, + { -2269.0f, 1000.0f, 7754.0f }, { -2453.0f, 1000.0f, 8309.0f }, { -3008.0f, 1000.0f, 8438.0f }, + { -3304.0f, 1000.0f, 8179.0f }, { -3600.0f, 1000.0f, 7606.0f }, { -3600.0f, 1000.0f, 6885.0f }, + { -3618.0f, 1000.0f, 4392.0f }, { -3600.0f, 1000.0f, 3855.0f }, { -3396.0f, 1000.0f, 3189.0f }, + { -3396.0f, 1000.0f, 2283.0f }, { -3600.0f, 1000.0f, 818.0f }, { -3803.0f, 1000.0f, -88.0f }, + { -4543.0f, 1000.0f, -2457.0f }, { -4543.0f, 1000.0f, -2938.0f }, { -4543.0f, 1000.0f, -3530.0f }, + { -4284.0f, 1000.0f, -4333.0f }, { -3581.0f, 1000.0f, -4795.0f }, { -2805.0f, 1000.0f, -4850.0f }, + { -1825.0f, 1000.0f, -4703.0f }, { -1326.0f, 1000.0f, -4166.0f }, { -1122.0f, 1000.0f, -3186.0f }, + { -1085.0f, 1000.0f, -2059.0f }, { -1067.0f, 1000.0f, -912.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF394.s") +/** + * Returns true if the specified position is in the finish line. + * The range extends a little bit beyond the finish line's in-game visual. + */ +s32 EnMttag_IsInFinishLine(Vec3f* pos) { + return Math3D_XZBoundCheck(-1261.0f, -901.0f, -1600.0f, -1520.0f, pos->x, pos->z); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF444.s") +/** + * Returns a value in PlayerCheatStatus that indicates if the player is cheating + * and, if so, what kind of cheating the player is performing. + */ +s32 EnMttag_CheckPlayerCheatStatus(Vec3f* pos) { + if (!(gSaveContext.eventInf[1] & 1)) { + if (Math3D_XZBoundCheck(-466.0f, -386.0f, -687.0f, 193.0f, pos->x, pos->z)) { + // The race hasn't started yet, but the player is beyond the starting line. + return GORON_RACE_CHEAT_FALSE_START; + } + } else if (Math3D_XZBoundCheck(-1127.0f, -1007.0f, -867.0f, -787.0f, pos->x, pos->z)) { + // The goal is actually quite close to the start, just behind a large wall. + // This checks if the player is in an area "behind" the goal that is not accessible + // in normal play; it can only be reached by climbing the wall somehow. Perhaps they + // were worried that players would find a way to climb the wall with a glitch, or + // perhaps they just wanted to punish people using cheat codes. + return GORON_RACE_CHEAT_TRYING_TO_REACH_GOAL_FROM_BEHIND; + } + return GORON_RACE_CHEAT_NO_CHEATING; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF4EC.s") +/** + * This function tries to find all four Race Gorons present in the racetrack. + * If it finds them, it stores a pointer to each one in the actor's struct. + * Returns true if all four Race Gorons are found. + */ +s32 EnMttag_AreFourRaceGoronsPresent(EnMttag* this, GlobalContext* globalCtx) { + Actor* actor = NULL; + s32 i = 0; + s32 areGoronsPresent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF67C.s") + do { + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_RG); + if (actor != NULL) { + this->raceGorons[i] = (EnRg*)actor; + i++; + } else if ((actor == NULL) || (actor->next == NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF848.s") + actor = actor->next; + } while (i < ARRAY_COUNT(this->raceGorons)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF8EC.s") + if (i < ARRAY_COUNT(this->raceGorons)) { + areGoronsPresent = false; + } else { + areGoronsPresent = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF950.s") + return areGoronsPresent; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CF9A0.s") +/** + * Returns the checkpoint number for the supplied actor. + * At the start of the race, all race entrants are at checkpoint 1, and their + * checkpoint number gradually increases as they move forward through the racetrack. + * The player can have a checkpoint number of -1 if they move far enough backwards + * from the starting line. + */ +s32 EnMttag_GetCurrentCheckpoint(Actor* actor, GlobalContext* globalCtx, s32* upcomingCheckpoint, + f32* outPerpendicularPointX, f32* outPerpendicularPointZ) { + s32 curentCheckpoint = -1; + s32 hasSetCurrentCheckpointOnce = false; + f32 minLineLengthSq = 0.0f; + s32 sceneExitIndex; + f32 perpendicularPointX; + f32 perpendicularPointZ; + f32 lineLenSq; + s32 checkpointIterator; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFA00.s") + // The Goron Racetrack is configured such that the sceneExitIndex for any given floor polygon + // gradually increases as you move forward through the racetrack. + sceneExitIndex = SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, actor->floorPoly, actor->floorBgId); + if ((sceneExitIndex < 4) || (sceneExitIndex >= 19)) { + //! @bug - upcomingCheckpoint is not initialized here + return -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFA54.s") + checkpointIterator = sStartingCheckpointPerSceneExitIndex[sceneExitIndex]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFBC4.s") + // Iterates through all possible checkpoints that are associated with this sceneExitIndex. + do { + if ((Math3D_PointDistToLine2D( + actor->world.pos.x, actor->world.pos.z, (&sCheckpointPositions[checkpointIterator])[-1].x, + (&sCheckpointPositions[checkpointIterator])[-1].z, (&sCheckpointPositions[checkpointIterator])[1].x, + (&sCheckpointPositions[checkpointIterator])[1].z, &perpendicularPointX, &perpendicularPointZ, + &lineLenSq)) && + (!hasSetCurrentCheckpointOnce || ((curentCheckpoint + 1) == checkpointIterator) || + (lineLenSq < minLineLengthSq))) { + minLineLengthSq = lineLenSq; + curentCheckpoint = checkpointIterator; + *outPerpendicularPointX = perpendicularPointX; + *outPerpendicularPointZ = perpendicularPointZ; + hasSetCurrentCheckpointOnce = true; + } + checkpointIterator++; + } while (checkpointIterator < sStartingCheckpointPerSceneExitIndex[sceneExitIndex + 1]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFC38.s") + *upcomingCheckpoint = curentCheckpoint + 1; + return curentCheckpoint; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFD98.s") +/** + * Returns true if the player is almost certainly going to lose the race. + * Specifically, it checks if the player's current checkpoint is 24 or more + * checkpoints behind the leading racer. This value was probably chosen because + * falling off the wooden bridge in the middle of the track can set the player + * back up to 23 checkpoints. + * + * This function also has the side effect of updating the number of checkpoints + * ahead of the player each Race Goron is. + */ +s32 EnMttag_UpdateCheckpoints(EnMttag* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnRg* rg; + s32 currentCheckpoints[5]; + s32 upcomingCheckpoints[5]; + f32 perpendicularPointsX[5]; + f32 perpendicularPointsZ[5]; + s32 highestCurrentCheckpoint; + s32 i; + s32 playerIsLikelyToLose = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFE28.s") + highestCurrentCheckpoint = -1; + currentCheckpoints[0] = EnMttag_GetCurrentCheckpoint(&player->actor, globalCtx, &upcomingCheckpoints[0], + &perpendicularPointsX[0], &perpendicularPointsZ[0]); + for (i = 1; i < ARRAY_COUNT(this->raceGorons) + 1; i++) { + currentCheckpoints[i] = + EnMttag_GetCurrentCheckpoint(&this->raceGorons[i - 1]->actor, globalCtx, &upcomingCheckpoints[i], + &perpendicularPointsX[i], &perpendicularPointsZ[i]); + if (highestCurrentCheckpoint < currentCheckpoints[i]) { + highestCurrentCheckpoint = currentCheckpoints[i]; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/func_809CFF94.s") + for (i = 1; i < ARRAY_COUNT(this->raceGorons) + 1; i++) { + rg = this->raceGorons[i - 1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/EnMttag_Init.s") + // Because of the bug described in EnMttag_GetCurrentCheckpoint, these values may not be initialized. + //! @bug When initialized, this check is pointless because upcomingCheckpoint is always 0 or higher. + if ((upcomingCheckpoints[i] != -1) && (upcomingCheckpoints[0] != -1)) { + rg->numCheckpointsAheadOfPlayer = (upcomingCheckpoints[i] - upcomingCheckpoints[0]); + } else { + rg->numCheckpointsAheadOfPlayer = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/EnMttag_Destroy.s") + if ((currentCheckpoints[0] > 0) && (currentCheckpoints[0] < highestCurrentCheckpoint) && + (player->actor.bgCheckFlags & 1) && ((highestCurrentCheckpoint - currentCheckpoints[0]) >= 24)) { + playerIsLikelyToLose = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mt_tag/EnMttag_Update.s") + return playerIsLikelyToLose; +} + +/** + * Exits the race and returns the player back to "normal" gameplay. + * Whether the player won or lost the race is determined by arg1 and nextTransition. + */ +s32 EnMttag_ExitRace(GlobalContext* globalCtx, s32 arg1, s32 nextTransition) { + CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_SWORD_KOKIRI; + globalCtx->nextEntranceIndex = 0xD020; + if ((gSaveContext.save.weekEventReg[33] & 0x80)) { + // Spring + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // Winter + gSaveContext.nextCutsceneIndex = 0; + } + + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = arg1; + gSaveContext.nextTransition = nextTransition; + func_801477B4(globalCtx); + return 1; +} + +/** + * Displays the text which says that the player has made a false start. + */ +void EnMttag_ShowFalseStartMessage(EnMttag* this, GlobalContext* globalCtx) { + gSaveContext.unk_3DD0[4] = 0; + Message_StartTextbox(globalCtx, 0xE95, NULL); // An entrant made a false start + func_800B7298(globalCtx, &this->actor, 7); + Audio_QueueSeqCmd(0x101400FF); + this->actionFunc = EnMttag_PotentiallyRestartRace; +} + +/** + * Displays the text from the Goron Elder's child which tells the player that + * they probably can't win the race. + */ +void EnMttag_ShowCantWinMessage(EnMttag* this, GlobalContext* globalCtx) { + Message_StartTextbox(globalCtx, 0xE97, NULL); // You can't win now... + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = EnMttag_HandleCantWinChoice; +} + +/** + * Shows the cutscene that pans over the race track and shows all five race entrants. + */ +void EnMttag_ShowIntroCutscene(EnMttag* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actionFunc = EnMttag_WaitForIntroCutsceneToEnd; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +/** + * When the intro cutscene concludes, this sets the weekEventReg to prevent it + * from showing again and starts the race. + */ +void EnMttag_WaitForIntroCutsceneToEnd(EnMttag* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) { + gSaveContext.save.weekEventReg[12] |= 2; + this->actionFunc = EnMttag_RaceStart; + } +} + +/** + * Handles the race from when the Gorons are first lined up at the + * starting block to when the countdown finishes. + */ +void EnMttag_RaceStart(EnMttag* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 playerCheatStatus; + + if (this->raceInitialized == true) { + playerCheatStatus = EnMttag_CheckPlayerCheatStatus(&player->actor.world.pos); + if (playerCheatStatus != GORON_RACE_CHEAT_NO_CHEATING) { + if (playerCheatStatus == GORON_RACE_CHEAT_FALSE_START) { + this->shouldRestartRace = true; + } else { + this->shouldRestartRace = false; + } + + EnMttag_ShowFalseStartMessage(this, globalCtx); + gSaveContext.eventInf[1] |= 8; + } else { + if (DECR(this->timer) == 60) { + func_8010E9F0(4, 0); + globalCtx->interfaceCtx.unk_280 = 1; + Audio_QueueSeqCmd(NA_BGM_GORON_RACE | 0x8000); + globalCtx->envCtx.unk_E4 = 0xFE; + player->stateFlags1 &= ~0x20; + } else if ((this->timer < 60) && (globalCtx->interfaceCtx.unk_280 == 8)) { + this->timer = 0; + gSaveContext.eventInf[1] |= 1; + this->actionFunc = EnMttag_Race; + } + } + } else { + if (EnMttag_AreFourRaceGoronsPresent(this, globalCtx)) { + this->raceInitialized = true; + } + } +} + +/** + * Returns true if any Race Goron is over the finish line. + */ +s32 EnMttag_IsAnyRaceGoronOverFinishLine(EnMttag* this) { + s32 isAnyRaceGoronOverFinishLine = false; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->raceGorons); i++) { + if ((EnMttag_IsInFinishLine(&this->raceGorons[i]->actor.world.pos)) && + (this->raceGorons[i]->actor.update != NULL)) { + isAnyRaceGoronOverFinishLine = true; + break; + } + } + return isAnyRaceGoronOverFinishLine; +} + +/** + * Handles the race from when the countdown finishes to when + * any race entrant crosses the finish line. + */ +void EnMttag_Race(EnMttag* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f* playerPos = &player->actor.world.pos; + s32 playerCheatStatus; + + if (EnMttag_IsInFinishLine(playerPos)) { + gSaveContext.unk_3DD0[4] = 6; + play_sound(NA_SE_SY_START_SHOT); + Audio_QueueSeqCmd(NA_BGM_GORON_GOAL | 0x8000); + this->timer = 55; + gSaveContext.eventInf[1] |= 2; + this->actionFunc = EnMttag_RaceFinish; + } else if (EnMttag_IsAnyRaceGoronOverFinishLine(this)) { + gSaveContext.unk_3DD0[4] = 6; + play_sound(NA_SE_SY_START_SHOT); + Audio_QueueSeqCmd(NA_BGM_GORON_GOAL | 0x8000); + this->timer = 55; + gSaveContext.eventInf[1] |= 4; + this->actionFunc = EnMttag_RaceFinish; + } else { + playerCheatStatus = EnMttag_CheckPlayerCheatStatus(playerPos); + if (playerCheatStatus != GORON_RACE_CHEAT_NO_CHEATING) { + if (playerCheatStatus == GORON_RACE_CHEAT_FALSE_START) { + this->shouldRestartRace = true; + } else { + this->shouldRestartRace = false; + } + + EnMttag_ShowFalseStartMessage(this, globalCtx); + gSaveContext.eventInf[1] |= 8; + } else if ((EnMttag_UpdateCheckpoints(this, globalCtx)) && (this->timer == 0)) { + EnMttag_ShowCantWinMessage(this, globalCtx); + gSaveContext.eventInf[1] |= 8; + } + } +} + +/** + * Handles the race after any race entrant crosses the finish line. + * This function simply waits for a bit before exiting the race. + */ +void EnMttag_RaceFinish(EnMttag* this, GlobalContext* globalCtx) { + if (DECR(this->timer) == 0) { + if ((gSaveContext.eventInf[1] & 2)) { + // Player won + EnMttag_ExitRace(globalCtx, 3, 3); + } else { + // A non-player Goron won + EnMttag_ExitRace(globalCtx, 2, 2); + } + + Actor_MarkForDeath(&this->actor); + } +} + +/** + * Restarts the race if this->shouldRestartRace is true. Otherwise, it exits the race. + * In practice, the only time this exits the race is if the player tries to cheat by + * reaching the goal from behind. + */ +void EnMttag_PotentiallyRestartRace(EnMttag* this, GlobalContext* globalCtx) { + u8 talkState = Message_GetState(&globalCtx->msgCtx); + + if (((talkState == 5 && Message_ShouldAdvance(globalCtx)) || talkState == 2)) { + if (this->shouldRestartRace) { + globalCtx->nextEntranceIndex = 0xD010; + + if (gSaveContext.save.weekEventReg[33] & 0x80) { + // Spring + gSaveContext.nextCutsceneIndex = 0xFFF0; + } else { + // Winter + gSaveContext.nextCutsceneIndex = 0; + } + + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + gSaveContext.nextTransition = 2; + func_801477B4(globalCtx); + func_800B7298(globalCtx, &this->actor, 7); + Parameter_AddMagic(globalCtx, + ((void)0, gSaveContext.unk_3F30) + (gSaveContext.save.playerData.doubleMagic * 48) + 48); + + gSaveContext.eventInf[1] &= (u8)~1; + gSaveContext.eventInf[1] &= (u8)~2; + gSaveContext.eventInf[1] &= (u8)~4; + gSaveContext.eventInf[1] &= (u8)~8; + gSaveContext.eventInf[2] = ((gSaveContext.eventInf[2] & 0xF) + 1) | (gSaveContext.eventInf[2] & 0xF0); + } else { + EnMttag_ExitRace(globalCtx, 2, 2); + } + Actor_MarkForDeath(&this->actor); + } +} + +/** + * This function either exits the race or resumes it based on how the player + * responded to the Goron Elder's son's question. + */ +void EnMttag_HandleCantWinChoice(EnMttag* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex != 0) { + // Exit the race + func_8019F230(); + gSaveContext.unk_3DD0[4] = 0; + EnMttag_ExitRace(globalCtx, 2, 2); + gSaveContext.eventInf[1] &= (u8)~8; + gSaveContext.eventInf[1] |= 4; + Actor_MarkForDeath(&this->actor); + } else { + // Keep racing + func_8019F208(); + func_801477B4(globalCtx); + func_800B7298(globalCtx, &this->actor, 6); + gSaveContext.eventInf[1] &= (u8)~8; + this->timer = 100; + this->actionFunc = EnMttag_Race; + } + } +} + +void EnMttag_Init(Actor* thisx, GlobalContext* globalCtx) { + Player* player; + EnMttag* this = THIS; + + if (gSaveContext.save.entranceIndex == 0xD010) { + player = GET_PLAYER(globalCtx); + player->stateFlags1 |= 0x20; + this->raceInitialized = false; + this->timer = 100; + + gSaveContext.eventInf[1] &= (u8)~1; + gSaveContext.eventInf[1] &= (u8)~2; + gSaveContext.eventInf[1] &= (u8)~4; + gSaveContext.eventInf[1] &= (u8)~8; + + if (!(gSaveContext.save.weekEventReg[12] & 2)) { + this->actionFunc = EnMttag_ShowIntroCutscene; + } else { + s32 requiredScopeTemp; + + this->actionFunc = EnMttag_RaceStart; + } + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnMttag_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMttag* this = THIS; + if (gSaveContext.unk_3DD0[4] != 6) { + gSaveContext.unk_3DD0[4] = 5; + } +} + +void EnMttag_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMttag* this = THIS; + this->actionFunc(this, globalCtx); +} 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..796dff17a 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 @@ -2,15 +2,20 @@ #define Z_EN_MT_TAG_H #include "global.h" +#include "overlays/actors/ovl_En_Rg/z_en_rg.h" struct EnMttag; typedef void (*EnMttagActionFunc)(struct EnMttag*, GlobalContext*); typedef struct EnMttag { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnMttagActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x20]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnMttagActionFunc actionFunc; + /* 0x148 */ EnRg* raceGorons[4]; + /* 0x158 */ u16 raceInitialized; + /* 0x15A */ s16 timer; + /* 0x15C */ UNK_TYPE1 unk_15C[0x8]; + /* 0x164 */ s32 shouldRestartRace; } 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 6c774240c..4afae5793 100644 --- a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c +++ b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c @@ -1,6 +1,14 @@ -#include "z_en_mushi2.h" +/* + * File: z_en_mushi2.c + * Overlay: ovl_En_Mushi2 + * Description: Group of three bugs that burrow underground + */ -#define FLAGS 0x00000010 +#include "overlays/actors/ovl_Obj_Bean/z_obj_bean.h" +#include "z_en_mushi2.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnMushi2*)thisx) @@ -9,15 +17,21 @@ void EnMushi2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMushi2_Update(Actor* thisx, GlobalContext* globalCtx); void EnMushi2_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A6A300(EnMushi2* this); void func_80A6A36C(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6A508(Actor* thisx); void func_80A6A5C0(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6A794(EnMushi2* this); void func_80A6A824(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6A984(EnMushi2* this); void func_80A6A9E4(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6AAA4(EnMushi2* this); void func_80A6AB08(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6AE14(EnMushi2* this); void func_80A6AE7C(EnMushi2* this, GlobalContext* globalCtx); +void func_80A6B078(EnMushi2* this); void func_80A6B0D8(EnMushi2* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Mushi2_InitVars = { ACTOR_EN_MUSHI2, ACTORCAT_ITEMACTION, @@ -30,134 +44,1195 @@ const ActorInit En_Mushi2_InitVars = { (ActorFunc)EnMushi2_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80A6B950[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 5 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80A6B974 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80A6B950, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A6BA04[] = { +static Color_RGBA8 D_80A6B984[] = { + { 170, 130, 90, 255 }, + { 250, 250, 250, 255 }, +}; + +static Color_RGBA8 D_80A6B98C[] = { + { 100, 60, 20, 255 }, + { 180, 180, 180, 255 }, +}; + +static s32 D_80A6B994 = 0; + +static EnMushi2Struct D_80A6B998[] = { + { 1, 0x1F40 }, + { 2, 0xE0C0 }, +}; + +static Vec3f D_80A6B9A0 = { 1.0f, 0.0f, 0.0f }; +static Vec3f D_80A6B9AC = { 0.0f, 1.0f, 0.0f }; +static Vec3f D_80A6B9B8 = { 0.0f, 0.0f, 1.0f }; + +static MtxF D_80A6B9C4 = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 700, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 20, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 20, ICHAIN_STOP), }; -#endif +static f32 D_80A6BA14[] = { 0.06f, 0.1f, 0.13f }; -extern ColliderJntSphElementInit D_80A6B950[1]; -extern ColliderJntSphInit D_80A6B974; -extern InitChainEntry D_80A6BA04[]; +void func_80A687A0(EnMushi2* this) { + MtxF* matrix = Matrix_GetCurrent(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A687A0.s") + matrix->mf[3][0] += this->unk_348 * this->unk_31C.x; + matrix->mf[3][1] += this->unk_348 * this->unk_31C.y; + matrix->mf[3][2] += this->unk_348 * this->unk_31C.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68808.s") +void func_80A68808(EnMushi2* this) { + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Collider_UpdateSpheres(0, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68860.s") +s32 func_80A68860(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp40; + CollisionPoly* sp3C; + f32 temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp3C, &sp40, &this->actor, &this->actor.world.pos); + WaterBox* sp34; + f32 sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68910.s") + if ((temp_f0 > (BGCHECK_Y_MIN + 1)) && ((this->actor.world.pos.y - 150.0f) < temp_f0)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68A78.s") + return WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &sp30, &sp34); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68B3C.s") +s32 func_80A68910(EnMushi2* this, GlobalContext* globalCtx) { + Actor* bean = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + f32 minDistSq = SQ(100.0f); + s32 ret = false; + f32 temp_f0; + f32 temp_f2; + s32 params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68B6C.s") + this->unk_34C = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68BA0.s") + while (bean != NULL) { + if (bean->id == ACTOR_OBJ_BEAN) { + params = OBJBEAN_GET_C000(bean); + if (((params == ENOBJBEAN_GET_C000_1) || (params == ENOBJBEAN_GET_C000_2)) && + (bean->room == this->actor.room)) { + temp_f0 = Math3D_XZDistanceSquared(this->actor.world.pos.x, this->actor.world.pos.z, bean->world.pos.x, + bean->world.pos.z); + temp_f2 = bean->world.pos.y - this->actor.world.pos.y; + if ((temp_f0 < minDistSq) && (temp_f2 < 100.0f) && (temp_f2 > -50.0f)) { + ret = true; + minDistSq = temp_f0; + this->unk_34C = (ObjBean*)bean; + if (params == ENOBJBEAN_GET_C000_1) { + this->unk_350 = SQ(30.0f); + } else { + this->unk_350 = SQ(39.0f); + } + } + } + } + bean = bean->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68BC8.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68C5C.s") +void func_80A68A78(EnMushi2* this, GlobalContext* globalCtx) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68CE4.s") + for (i = 0; i < ARRAY_COUNT(D_80A6B998); i++) { + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_MUSHI2, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y + (D_80A6B998 + i)->unk_02, this->actor.shape.rot.z, + (D_80A6B998 + i)->unk_00, this->actor.cutscene, this->actor.unk20, NULL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68DD4.s") +void func_80A68B3C(EnMushi2* this) { + if (!(this->unk_30C & 0x100)) { + this->unk_30C |= 0x100; + D_80A6B994++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68ED8.s") +void func_80A68B6C(EnMushi2* this) { + if (this->unk_30C & 0x100) { + this->unk_30C &= ~0x100; + D_80A6B994--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68F24.s") +s32 func_80A68BA0(EnMushi2* this) { + return (D_80A6B994 > 3) && this->unk_34C == NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A68F9C.s") +void func_80A68BC8(EnMushi2* this) { + if (this->unk_36C > 0) { + this->unk_36C--; + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MUSI_WALK); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A690C4.s") + this->unk_36C = 3.0f / CLAMP_MIN(this->skelAnime.playSpeed, 0.12f); + if (this->unk_36C < 2) { + this->unk_36C = 2; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A691EC.s") +s32 func_80A68C5C(Vec3f* arg0, Vec3f* arg1) { + f32 temp_f0 = Math3D_Vec3fMagnitude(arg0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69388.s") + if (temp_f0 < 0.005f) { + Math_Vec3f_Copy(arg0, &gZeroVec3f); + return false; + } else { + arg1->x = arg0->x * (1.0f / temp_f0); + arg1->y = arg0->y * (1.0f / temp_f0); + arg1->z = arg0->z * (1.0f / temp_f0); + return true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69424.s") +s32 func_80A68CE4(Vec3f* arg0, Vec3f* arg1, f32 arg2) { + Vec3f sp34; + f32 temp_f0; + f32 temp_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69468.s") + Math_Vec3f_Diff(arg1, arg0, &sp34); + temp_f0 = Math3D_LengthSquared(&sp34); + temp_f2 = arg2 + 0.01f; + if (temp_f0 <= SQ(temp_f2)) { + Math_Vec3f_Copy(arg0, arg1); + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6958C.s") + Math_Vec3f_Scale(&sp34, arg2 / sqrtf(temp_f0)); + sp34.x += arg0->x; + sp34.y += arg0->y; + sp34.z += arg0->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6969C.s") + if (func_80A68C5C(&sp34, arg0)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A697C4.s") + Math_Vec3f_Copy(arg0, arg1); + return -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A699E4.s") +s32 func_80A68DD4(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + Player* player; + s16 sp2E; + s32 pad2; + f32 sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69AA8.s") + if ((this->actor.xzDistToPlayer < 32.0f) && (this->actor.playerHeightRel > -10.0f) && + (this->actor.playerHeightRel < 31.0f)) { + player = GET_PLAYER(globalCtx); + sp2E = BINANG_ROT180(this->actor.yawTowardsPlayer); + sp24 = Math_SinS(sp2E); + if (Math3D_XZDistanceSquared((sp24 * 16.0f) + player->actor.world.pos.x, + (Math_CosS(sp2E) * 16.0f) + player->actor.world.pos.z, this->actor.world.pos.x, + this->actor.world.pos.z) < SQ(20.0f)) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69ADC.s") +void func_80A68ED8(EnMushi2* this) { + this->actor.velocity.x = this->actor.speedXZ * this->unk_328.x; + this->actor.velocity.y = this->actor.speedXZ * this->unk_328.y; + this->actor.velocity.z = this->actor.speedXZ * this->unk_328.z; + Actor_UpdatePos(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69CE0.s") +void func_80A68F24(EnMushi2* this) { + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_80A6B9A0, &this->unk_310); + Matrix_MultVec3f(&D_80A6B9AC, &this->unk_31C); + Matrix_MultVec3f(&D_80A6B9B8, &this->unk_328); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69D3C.s") +s32 func_80A68F9C(EnMushi2* this, s16 arg1) { + MtxF* matrix; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69EE4.s") + if (arg1 == 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A69F5C.s") + matrix = Matrix_GetCurrent(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A024.s") + matrix->mf[0][0] = this->unk_310.x; + matrix->mf[0][1] = this->unk_310.y; + matrix->mf[0][2] = this->unk_310.z; + matrix->mf[0][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A058.s") + matrix->mf[1][0] = this->unk_31C.x; + matrix->mf[1][1] = this->unk_31C.y; + matrix->mf[1][2] = this->unk_31C.z; + matrix->mf[1][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A094.s") + matrix->mf[2][0] = this->unk_328.x; + matrix->mf[2][1] = this->unk_328.y; + matrix->mf[2][2] = this->unk_328.z; + matrix->mf[2][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A0D8.s") + matrix->mf[3][0] = 0.0f; + matrix->mf[3][1] = 0.0f; + matrix->mf[3][2] = 0.0f; + matrix->mf[3][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/EnMushi2_Init.s") + Matrix_RotateYS(arg1, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/EnMushi2_Destroy.s") + this->unk_310.x = matrix->mf[0][0]; + this->unk_310.y = matrix->mf[0][1]; + this->unk_310.z = matrix->mf[0][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A300.s") + this->unk_31C.x = matrix->mf[1][0]; + this->unk_31C.y = matrix->mf[1][1]; + this->unk_31C.z = matrix->mf[1][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A36C.s") + this->unk_328.x = matrix->mf[2][0]; + this->unk_328.y = matrix->mf[2][1]; + this->unk_328.z = matrix->mf[2][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A508.s") + this->unk_30C |= 0x40; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A5C0.s") +s32 func_80A690C4(EnMushi2* this, s16 arg1) { + MtxF* matrix; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A794.s") + if (arg1 == 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A824.s") + matrix = Matrix_GetCurrent(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A984.s") + matrix->mf[0][0] = this->unk_310.x; + matrix->mf[0][1] = this->unk_310.y; + matrix->mf[0][2] = this->unk_310.z; + matrix->mf[0][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6A9E4.s") + matrix->mf[1][0] = this->unk_31C.x; + matrix->mf[1][1] = this->unk_31C.y; + matrix->mf[1][2] = this->unk_31C.z; + matrix->mf[1][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6AAA4.s") + matrix->mf[2][0] = this->unk_328.x; + matrix->mf[2][1] = this->unk_328.y; + matrix->mf[2][2] = this->unk_328.z; + matrix->mf[2][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6AB08.s") + matrix->mf[3][0] = 0.0f; + matrix->mf[3][1] = 0.0f; + matrix->mf[3][2] = 0.0f; + matrix->mf[3][3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6AE14.s") + Matrix_RotateXS(arg1, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6AE7C.s") + this->unk_310.x = matrix->mf[0][0]; + this->unk_310.y = matrix->mf[0][1]; + this->unk_310.z = matrix->mf[0][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6B078.s") + this->unk_31C.x = matrix->mf[1][0]; + this->unk_31C.y = matrix->mf[1][1]; + this->unk_31C.z = matrix->mf[1][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/func_80A6B0D8.s") + this->unk_328.x = matrix->mf[2][0]; + this->unk_328.y = matrix->mf[2][1]; + this->unk_328.z = matrix->mf[2][2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/EnMushi2_Update.s") + this->unk_30C |= 0x40; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mushi2/EnMushi2_Draw.s") +s32 func_80A691EC(EnMushi2* this, CollisionPoly* floorPoly, f32 arg2) { + Vec3f sp64; + Vec3f sp58; + Vec3f sp4C; + Vec3f sp40; + Vec3f sp34; + s32 sp30; + + if (arg2 > 0.0f) { + Vec3f sp24; + + sp24.x = COLPOLY_GET_NORMAL(floorPoly->normal.x); + sp24.y = COLPOLY_GET_NORMAL(floorPoly->normal.y); + sp24.z = COLPOLY_GET_NORMAL(floorPoly->normal.z); + Math_Vec3f_Copy(&sp4C, &this->unk_31C); + sp30 = func_80A68CE4(&sp4C, &sp24, arg2); + } else { + sp4C.x = COLPOLY_GET_NORMAL(floorPoly->normal.x); + sp4C.y = COLPOLY_GET_NORMAL(floorPoly->normal.y); + sp4C.z = COLPOLY_GET_NORMAL(floorPoly->normal.z); + sp30 = 1; + } + + Math3D_CrossProduct(&this->unk_310, &sp4C, &sp40); + Math3D_CrossProduct(&sp4C, &sp40, &sp64); + + if (func_80A68C5C(&sp64, &sp58) && func_80A68C5C(&sp40, &sp34)) { + Math_Vec3f_Copy(&this->unk_31C, &sp4C); + Math_Vec3f_Copy(&this->unk_310, &sp58); + Math_Vec3f_Copy(&this->unk_328, &sp34); + this->unk_30C |= 0x40; + return sp30; + } + + return -1; +} + +void func_80A69388(EnMushi2* this) { + D_80A6B9C4.mf[0][0] = this->unk_310.x; + D_80A6B9C4.mf[0][1] = this->unk_310.y; + D_80A6B9C4.mf[0][2] = this->unk_310.z; + + D_80A6B9C4.mf[1][0] = this->unk_31C.x; + D_80A6B9C4.mf[1][1] = this->unk_31C.y; + D_80A6B9C4.mf[1][2] = this->unk_31C.z; + + D_80A6B9C4.mf[2][0] = this->unk_328.x; + D_80A6B9C4.mf[2][1] = this->unk_328.y; + D_80A6B9C4.mf[2][2] = this->unk_328.z; + + Matrix_MtxFToYXZRot(&D_80A6B9C4, &this->actor.world.rot, false); + this->actor.shape.rot = this->actor.world.rot; +} + +void func_80A69424(EnMushi2* this, GlobalContext* globalCtx) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 8.0f, 9.0f, 0.0f, 0x45); +} + +s32 func_80A69468(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp68; + Vec3f posB; + Vec3f sp50; + f32 x; + f32 y; + f32 z; + + sp50.x = 2.0f * this->unk_31C.x; + sp50.y = 2.0f * this->unk_31C.y; + sp50.z = 2.0f * this->unk_31C.z; + + Math_Vec3f_Sum(&sp50, &this->actor.prevPos, &sp68); + + x = (this->unk_328.x * 4.0f); + y = (this->unk_328.y * 4.0f); + z = (this->unk_328.z * 4.0f); + + posB.x = (x + sp50.x) + this->actor.world.pos.x; + posB.y = (y + sp50.y) + this->actor.world.pos.y; + posB.z = (z + sp50.z) + this->actor.world.pos.z; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.prevPos, &posB, &this->unk_33C, &this->poly, true, + true, true, true, &this->polyBgId)) { + this->unk_30C |= 6; + return true; + } + return false; +} + +s32 func_80A6958C(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f posA; + Vec3f posB; + + posA.x = (2.0f * this->unk_31C.x) + this->actor.world.pos.x; + posA.y = (2.0f * this->unk_31C.y) + this->actor.world.pos.y; + posA.z = (2.0f * this->unk_31C.z) + this->actor.world.pos.z; + + posB.x = (this->unk_31C.x * -4.0f) + this->actor.world.pos.x; + posB.y = (this->unk_31C.y * -4.0f) + this->actor.world.pos.y; + posB.z = (this->unk_31C.z * -4.0f) + this->actor.world.pos.z; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &posA, &posB, &this->unk_33C, &this->poly, true, true, true, true, + &this->polyBgId)) { + this->unk_30C |= 0xA; + return true; + } + return false; +} + +s32 func_80A6969C(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f posA; + Vec3f posB; + Vec3f sp38; + + sp38.x = this->unk_31C.x * -4.0f; + sp38.y = this->unk_31C.y * -4.0f; + sp38.z = this->unk_31C.z * -4.0f; + + Math_Vec3f_Sum(&sp38, &this->actor.world.pos, &posA); + + posB.x = this->actor.prevPos.x + sp38.x + (this->unk_328.x * -4.0f); + posB.y = this->actor.prevPos.y + sp38.y + (this->unk_328.y * -4.0f); + posB.z = this->actor.prevPos.z + sp38.z + (this->unk_328.z * -4.0f); + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &posA, &posB, &this->unk_33C, &this->poly, true, true, true, true, + &this->polyBgId)) { + this->unk_30C |= (0x10 | 0x2); + return true; + } + return false; +} + +void func_80A697C4(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + CollisionPoly* poly = this->poly; + s32 bgId = this->polyBgId; + + if (!(this->unk_30C & (0x10 | 0x4))) { + WaterBox* sp30; + f32 sp2C; + + this->unk_30C &= ~(0x40 | 0x8 | 0x2); + if (!func_80A69468(this, globalCtx) && !func_80A6958C(this, globalCtx)) { + func_80A6969C(this, globalCtx); + } + + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &sp2C, &sp30)) { + this->actor.depthInWater = sp2C - this->actor.world.pos.y; + if (this->actor.depthInWater >= 1.0f) { + this->unk_30C |= 0x20; + } else { + this->unk_30C &= ~0x20; + } + } else { + this->actor.depthInWater = BGCHECK_Y_MIN; + this->unk_30C &= ~0x20; + } + } + + if (this->unk_30C & 4) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_33C); + if (func_80A691EC(this, this->poly, 0.4f) == 1) { + this->unk_30C &= ~0x4; + } + } else if (this->unk_30C & 0x10) { + if (func_80A691EC(this, this->poly, 0.4f) == 1) { + this->unk_30C &= ~0x10; + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_33C); + } else { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + } + } else if (this->unk_30C & 8) { + if (!(this->unk_30C & 0x20)) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_33C); + func_80A691EC(this, this->poly, -1.0f); + } + } else if (!(this->unk_30C & 2)) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + Math_Vec3f_Copy(&this->unk_33C, &this->actor.prevPos); + this->poly = poly; + this->polyBgId = bgId; + } +} + +s32 func_80A699E4(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* sp40; + f32 sp3C; + + if (this->unk_328.y < 0.0f) { + f32 x = (2.0f * this->unk_328.x) + this->actor.world.pos.x; + f32 y = (2.0f * this->unk_328.y) + this->actor.world.pos.y; + f32 z = (2.0f * this->unk_328.z) + this->actor.world.pos.z; + + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, x, z, &sp3C, &sp40) && (y <= sp3C)) { + return true; + } + } + return false; +} + +f32 func_80A69AA8(f32 x, f32 y, f32 z, Vec3f* pos) { + return -((pos->x * x) + (y * pos->y) + (z * pos->z)); +} + +void func_80A69ADC(Actor* thisx) { + EnMushi2* this = THIS; + ObjBean* bean = this->unk_34C; + f32 sp44; + f32 sp40; + f32 sp3C; + s32 pad2; + + if (this->unk_358 < 1.0f) { + sp44 = Math3D_SignedDistanceFromPlane( + this->unk_310.x, this->unk_310.y, this->unk_310.z, + func_80A69AA8(this->unk_310.x, this->unk_310.y, this->unk_310.z, &this->actor.world.pos), + &bean->dyna.actor.world.pos); + sp40 = Math3D_SignedDistanceFromPlane( + this->unk_328.x, this->unk_328.y, this->unk_328.z, + func_80A69AA8(this->unk_328.x, this->unk_328.y, this->unk_328.z, &this->actor.world.pos), + &bean->dyna.actor.world.pos); + sp3C = Math3D_XZLength(sp44, sp40); + + if (fabsf(sp3C) > 0.1f) { + this->unk_360 = (Rand_ZeroOne() * 3000.0f * (this->unk_358 - 1.0f)) + (((sp40 / sp3C) - 1.0f) * -1500.0f); + this->unk_364 = 0; + if (Rand_ZeroOne() < this->unk_358) { + this->unk_366 = (sp44 >= 0.0f) ? 2000 : -2000; + } else { + this->unk_366 = (Rand_Next() > 0) ? 2000 : -2000; + } + this->unk_366 += (s16)(((Rand_ZeroOne() * (1.0f - this->unk_358)) - 0.5f) * 0x400); + } else { + this->unk_360 = 0.0f; + this->unk_364 = -0x8000; + this->unk_366 = 0; + } + } +} + +void func_80A69CE0(Actor* thisx) { + EnMushi2* this = THIS; + + this->unk_360 = Rand_ZeroOne() * 1500.0f; + this->unk_364 = 0; + if (Rand_Next() > 0) { + this->unk_366 = 2000; + } else { + this->unk_366 = -2000; + } +} + +void func_80A69D3C(EnMushi2* this) { + s32 pad; + f32 sp40; + f32 sp3C; + f32 sp38; + + if ((this->unk_34C != NULL) && (this->unk_358 > 0.999f)) { + sp40 = Math3D_SignedDistanceFromPlane( + this->unk_310.x, this->unk_310.y, this->unk_310.z, + func_80A69AA8(this->unk_310.x, this->unk_310.y, this->unk_310.z, &this->actor.world.pos), + &this->unk_34C->dyna.actor.world.pos); + sp3C = Math3D_SignedDistanceFromPlane( + this->unk_328.x, this->unk_328.y, this->unk_328.z, + func_80A69AA8(this->unk_328.x, this->unk_328.y, this->unk_328.z, &this->actor.world.pos), + &this->unk_34C->dyna.actor.world.pos); + sp38 = Math3D_XZLengthSquared(sp40, sp3C); + + if (fabsf(sp38) > 0.010000001f) { + s16 temp_v0 = Math_FAtan2F(sp3C, sp40); + temp_v0 = CLAMP(temp_v0, -3000, 3000); + func_80A68F9C(this, temp_v0); + } + } else { + this->unk_364 += this->unk_366; + if (this->unk_366 >= 0) { + if (this->unk_364 < 0) { + this->unk_364 = -0x8000; + } + } else if (this->unk_364 > 0) { + this->unk_364 = -0x8000; + } + func_80A68F9C(this, Math_SinS(this->unk_364) * this->unk_360); + } +} + +s32 func_80A69EE4(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* waterBox; + f32 waterSurface; + s32 bgId; + + if (WaterBox_GetSurfaceImpl(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &waterSurface, &waterBox, &bgId) && + (this->actor.world.pos.y < waterSurface)) { + return true; + } + return false; +} + +void func_80A69F5C(Actor* thisx, GlobalContext* globalCtx) { + EnMushi2* this = THIS; + s32 i; + + for (i = 0; i < 7; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, -10.0f, 10.0f, 10.0f, (Rand_ZeroOne() * 0.09f) + 0.05f); + } +} + +s32 func_80A6A024(EnMushi2* this) { + ObjBean* bean = this->unk_34C; + + if ((this->unk_34C != NULL) && (bean->unk_1E4 == 0)) { + bean->unk_1E4 = 1; + return true; + } + return false; +} + +s32 func_80A6A058(EnMushi2* this) { + ObjBean* bean = this->unk_34C; + + if ((this->unk_34C != NULL) && (bean->unk_1E4 == 2)) { + bean->unk_1E0++; + return true; + } + return false; +} + +s32 func_80A6A094(EnMushi2* this) { + if (this->unk_34C != NULL) { + ObjBean* bean = this->unk_34C; + + if ((bean->unk_1E4 == 2) || (bean->unk_1E4 == 1)) { + bean->unk_1E4 = 4; + return true; + } + } + return false; +} + +void func_80A6A0D8(EnMushi2* this) { + if (this->unk_34C != NULL) { + this->unk_34C = NULL; + } +} + +void EnMushi2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMushi2* this = THIS; + s32 pad; + s32 sp3C; + + Actor_ProcessInitChain(&this->actor, sInitChain); + if (!ENMUSHI2_GET_3(&this->actor)) { + func_80A68A78(this, globalCtx); + } + this->actor.shape.rot.y += Rand_S16Offset(-2000, 4000); + this->actor.home.rot.y = this->actor.shape.rot.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80A68F24(this); + SkelAnime_Init(globalCtx, &this->skelAnime, &gameplay_keep_Skel_0527A0, &gameplay_keep_Anim_05140C, + this->jointTable, this->morphTable, 24); + Animation_Change(&this->skelAnime, &gameplay_keep_Anim_05140C, 1.0f, 0.0f, 0.0f, 1, 0.0f); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + func_80A68808(this); + this->actor.colChkInfo.mass = 30; + sp3C = func_80A69EE4(this, globalCtx); + + if ((sp3C == 0) && func_80A68860(this, globalCtx) && func_80A68910(this, globalCtx) && + !ENMUSHI2_GET_3(&this->actor)) { + func_80A6A024(this); + } + + this->unk_358 = 0.0f; + this->unk_36A = Rand_S16Offset(240, 40); + this->unk_30C = 1; + + if (sp3C != 0) { + func_80A69F5C(&this->actor, globalCtx); + this->actor.world.rot.y = (u32)Rand_Next() >> 0x10; + func_80A6AE14(this); + } else { + func_80A6A300(this); + } + + func_80A68B3C(this); +} + +void EnMushi2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMushi2* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); + func_80A68B6C(this); +} + +void func_80A6A300(EnMushi2* this) { + this->unk_368 = 100; + this->actor.gravity = -0.25f; + this->actor.terminalVelocity = -3.5f; + this->unk_370 = Rand_S16Offset(-1000, 2000); + this->skelAnime.playSpeed = 1.5f; + this->actionFunc = func_80A6A36C; +} + +void func_80A6A36C(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20 = false; + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); + this->actor.velocity.y -= this->actor.velocity.y * D_80A6BA14[ENMUSHI2_GET_3(&this->actor)]; + Actor_MoveWithGravity(&this->actor); + func_80A69424(this, globalCtx); + this->actor.shape.rot.y += this->unk_370; + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->actor.floorHeight < this->actor.world.pos.y) && + (this->actor.world.pos.y < (this->actor.floorHeight + 4.0f))) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 0x1770); + this->actor.shape.rot.z += Rand_S16Offset(-2000, 4000); + } + + if (this->actor.floorHeight <= (BGCHECK_Y_MIN + 1)) { + sp20 = true; + func_80A6A094(this); + func_80A6A0D8(this); + } + + if (sp20 && (this->unk_36A <= 0)) { + Actor_MarkForDeath(&this->actor); + } else if (this->actor.bgCheckFlags & 0x20) { + func_80A6AAA4(this); + } else if (this->actor.bgCheckFlags & 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_WALK); + func_80A68F24(this); + func_80A691EC(this, this->actor.floorPoly, -1.0f); + func_80A69388(this); + func_80A6A508(&this->actor); + } +} + +void func_80A6A508(Actor* thisx) { + EnMushi2* this = THIS; + + if (this->unk_36A > 100) { + this->unk_35C = Rand_ZeroOne() + 1.0f; + } else { + this->unk_35C = (Rand_ZeroOne() * 0.8f) + 1.5f; + } + + this->unk_368 = Rand_S16Offset(10, 30); + if (this->unk_34C == NULL) { + func_80A69CE0(thisx); + } else { + func_80A69ADC(thisx); + } + this->actionFunc = func_80A6A5C0; +} + +void func_80A6A5C0(EnMushi2* this, GlobalContext* globalCtx) { + EnMushi2* this2 = this; + + func_80A69D3C(this); + Math_SmoothStepToF(&this->actor.speedXZ, this->unk_35C, 0.1f, 0.5f, 0.0f); + if (this->unk_354 < SQ(40.0f)) { + f32 temp = 1.0f - ((SQ(40.0f) - this->unk_354) * (1.0f / (10.0f * SQ(40.0f)))); + + this->actor.speedXZ *= temp; + } + + func_80A68ED8(this); + func_80A697C4(this, globalCtx); + if (this->unk_30C & 0x40) { + func_80A69388(this); + } + + this->skelAnime.playSpeed = this->actor.speedXZ * 1.6f; + this2->skelAnime.playSpeed = CLAMP(this2->skelAnime.playSpeed, 0.1f, 1.9f); + + if ((this->unk_36A <= 0) || func_80A68BA0(this)) { + func_80A6B078(this); + } else if (!(this->unk_30C & 2)) { + func_80A6A984(this); + } else if (this->unk_30C & 0x20) { + func_80A6AAA4(this); + } else if (this->unk_368 <= 0) { + func_80A6A794(this); + } else if (((globalCtx->gameplayFrames % 2) != 0) && func_80A699E4(this, globalCtx)) { + func_80A6A984(this); + } +} + +void func_80A6A794(EnMushi2* this) { + if (this->unk_354 < SQ(40.0f)) { + this->unk_368 = Rand_S16Offset(2, 4); + } else { + this->unk_368 = Rand_S16Offset(5, 10); + } + + this->unk_35C = Rand_ZeroOne() * 0.4f; + this->actionFunc = func_80A6A824; +} + +void func_80A6A824(EnMushi2* this, GlobalContext* globalCtx) { + EnMushi2* this2 = this; + + Math_SmoothStepToF(&this->actor.speedXZ, this->unk_35C, 0.1f, 0.5f, 0.0f); + func_80A68ED8(this); + func_80A697C4(this, globalCtx); + + if (this->unk_30C & 0x40) { + func_80A69388(this); + } + + this->skelAnime.playSpeed = (Rand_ZeroOne() * 0.8f) + (this->actor.speedXZ * 1.2f); + this2->skelAnime.playSpeed = CLAMP(this2->skelAnime.playSpeed, 0.0f, 1.9f); + + if ((this->unk_36A <= 0) || func_80A68BA0(this)) { + func_80A6B078(this); + } else if (!(this->unk_30C & 2)) { + func_80A6A984(this); + } else if (this->unk_30C & 0x20) { + func_80A6AAA4(this); + } else if (this->unk_368 <= 0) { + func_80A6A508(&this->actor); + } +} + +void func_80A6A984(EnMushi2* this) { + if (Rand_Next() & 1) { + this->unk_370 = 0x800; + } else { + this->unk_370 = -0x800; + } + this->skelAnime.playSpeed = 1.2f; + this->unk_368 = 17; + this->actionFunc = func_80A6A9E4; +} + +void func_80A6A9E4(EnMushi2* this, GlobalContext* globalCtx) { + func_80A68F9C(this, this->unk_370); + func_80A69388(this); + if ((this->unk_36A <= 0) || func_80A68BA0(this)) { + func_80A6B078(this); + } else if (this->unk_368 <= 0) { + func_80A697C4(this, globalCtx); + if (this->unk_30C & 0x40) { + func_80A69388(this); + } + + if (this->unk_30C & 2) { + func_80A6A508(&this->actor); + } else { + func_80A6B078(this); + } + } +} + +void func_80A6AAA4(EnMushi2* this) { + this->actor.velocity.y = -1.2f; + this->actor.terminalVelocity = -1.2f; + this->actor.gravity = -0.5f; + this->unk_368 = Rand_S16Offset(120, 50); + this->unk_36E = 0; + this->unk_370 = 0; + this->actionFunc = func_80A6AB08; +} + +void func_80A6AB08(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad; + s16 temp; + + if (this->unk_368 > 80) { + Math_StepToF(&this->actor.speedXZ, 0.6f, 0.08f); + } else { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.02f); + } + + Actor_MoveWithGravity(&this->actor); + func_80A69424(this, globalCtx); + Math_StepToF(&this->actor.world.pos.y, this->actor.world.pos.y + this->actor.depthInWater, 2.8f); + this->skelAnime.playSpeed = this->unk_368 * 0.018f; + this->skelAnime.playSpeed = CLAMP(this->skelAnime.playSpeed, 0.1f, 1.9f); + + if (this->unk_368 > 80) { + this->unk_36E += Rand_S16Offset(-50, 100); + this->unk_370 += Rand_S16Offset(-300, 600); + } + + temp = this->skelAnime.playSpeed * 200.0f; + this->unk_36E = CLAMP(this->unk_36E, -temp, temp); + + temp = this->skelAnime.playSpeed * 1000.0f; + this->unk_370 = CLAMP(this->unk_370, -temp, temp); + + this->actor.world.rot.y += this->unk_36E; + this->actor.shape.rot.y += this->unk_370; + Math_ScaledStepToS(&this->actor.world.rot.x, 0, 0xBB8); + this->actor.shape.rot.x = this->actor.world.rot.x; + Math_ScaledStepToS(&this->actor.world.rot.z, 0, 0xBB8); + this->actor.shape.rot.z = this->actor.world.rot.z; + + if ((this->actor.flags & ACTOR_FLAG_40) && (Rand_ZeroOne() < 0.03f)) { + Vec3f sp3C; + + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y + this->actor.depthInWater; + sp3C.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp3C, 40, 200, 4); + } + + if ((this->unk_368 <= 0) || (this->unk_36A <= 0) || func_80A68BA0(this)) { + func_80A6A094(this); + func_80A6A0D8(this); + func_80A6AE14(this); + } else if (!(this->actor.bgCheckFlags & 0x20)) { + func_80A6A794(this); + } +} + +void func_80A6AE14(EnMushi2* this) { + this->unk_30C &= ~1; + this->unk_368 = 100; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -0.8f; + this->actor.gravity = -0.04f; + func_80A68B6C(this); + this->actionFunc = func_80A6AE7C; +} + +void func_80A6AE7C(EnMushi2* this, GlobalContext* globalCtx) { + f32 temp_f2; + + this->actor.shape.rot.x -= 0x1F4; + this->actor.shape.rot.y += 0xC8; + this->actor.speedXZ += (Rand_ZeroOne() - 0.5f) * 0.16f; + this->actor.speedXZ *= 0.9f; + this->actor.world.rot.y += (s16)((Rand_ZeroOne() - 0.5f) * 2000.0f); + this->actor.gravity = -0.04f - (Rand_ZeroOne() * 0.02f); + this->actor.velocity.y *= 0.95f; + Actor_MoveWithGravity(&this->actor); + func_80A69424(this, globalCtx); + temp_f2 = this->actor.scale.x - (1.0f / 20000.0f); + Actor_SetScale(&this->actor, CLAMP_MIN(temp_f2, 0.001f)); + if ((this->actor.flags & ACTOR_FLAG_40) && (this->actor.depthInWater > 5.0f) && + (this->actor.depthInWater < 30.0f) && ((Rand_Next() & 0x1FF) < this->unk_368)) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, -5.0f, 5.0f, 5.0f, + ((Rand_ZeroOne() * 4.0f) + 2.0f) * this->actor.scale.x); + } + + if (this->unk_368 <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80A6B078(EnMushi2* this) { + this->unk_30C &= ~1; + this->unk_368 = 50; + this->skelAnime.playSpeed = 1.9f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTURA_BOUND); + func_80A68B6C(this); + this->actionFunc = func_80A6B0D8; +} + +void func_80A6B0D8(EnMushi2* this, GlobalContext* globalCtx) { + s32 pad[2]; + f32 temp_f2; + + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.4f, 1.2f, 0.0f); + temp_f2 = this->actor.scale.x - 0.0002f; + Actor_SetScale(&this->actor, CLAMP_MIN(temp_f2, 0.001f)); + + if (this->unk_368 > 20) { + func_80A690C4(this, 0x160); + } + + if (this->unk_30C & 0x40) { + func_80A69388(this); + } + + if ((globalCtx->gameplayFrames % 2) != 0) { + temp_f2 = 0.6f; + } else { + temp_f2 = -0.6f; + } + + this->actor.velocity.x = + (this->actor.speedXZ * this->unk_328.x) + (-0.01f * this->unk_31C.x) + (this->unk_310.x * temp_f2); + this->actor.velocity.y = + (this->actor.speedXZ * this->unk_328.y) + (-0.01f * this->unk_31C.y) + (this->unk_310.y * temp_f2); + this->actor.velocity.z = + (this->actor.speedXZ * this->unk_328.z) + (-0.01f * this->unk_31C.z) + (this->unk_310.z * temp_f2); + + if ((this->actor.flags & ACTOR_FLAG_40) && (this->unk_368 > 20) && (Rand_ZeroOne() < 0.15f)) { + Vec3f sp48; + s32 sp44 = 0; + + if (this->poly != NULL) { + u32 temp_v0 = func_800C99D4(&globalCtx->colCtx, this->poly, this->polyBgId); + if ((temp_v0 == 5) || (temp_v0 == 14) || (temp_v0 == 15)) { + sp44 = 1; + } + } + 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, &gZeroVec3f, &D_80A6B984[sp44], &D_80A6B98C[sp44], + (Rand_ZeroOne() * 5.0f) + 8.0f, (Rand_ZeroOne() * 5.0f) + 8.0f); + } + + if (this->unk_368 <= 0) { + if (this->unk_30C & 0x80) { + func_80A6A058(this); + func_80A6A0D8(this); + } else { + func_80A6A094(this); + func_80A6A0D8(this); + } + Actor_MarkForDeath(&this->actor); + } +} + +void EnMushi2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMushi2* this = THIS; + s32 pad; + f32 sp4C; + f32 phi_f0; + s32 temp; + + if ((this->unk_34C != NULL) && (this->unk_34C->dyna.actor.update == NULL)) { + this->unk_34C = NULL; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + func_80A6A094(this); + func_80A6A0D8(this); + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->unk_368 > 0) { + this->unk_368--; + } + + if (this->unk_36A > 0) { + this->unk_36A--; + } + + if ((this->unk_34C != NULL) && ((this->actionFunc == func_80A6A5C0) || (this->actionFunc == func_80A6A824)) && + (this->unk_354 < SQ(3.0f))) { + this->unk_30C |= 0x80; + func_80A6B078(this); + } + + if (this->unk_354 < SQ(70.0f)) { + phi_f0 = 0.017f; + } else { + phi_f0 = 0.025f; + } + this->unk_358 += phi_f0; + + if (this->unk_358 > 1.0f) { + this->unk_358 = 1.0f; + } + + temp = this->polyBgId; + if ((temp != BGCHECK_SCENE) && + ((this->actionFunc == func_80A6A5C0) || (this->actionFunc == func_80A6A824) || + (this->actionFunc == func_80A6A9E4) || (this->actionFunc == func_80A6B0D8)) && + BgCheck2_UpdateActorAttachedToMesh(&globalCtx->colCtx, temp, &this->actor)) { + func_80A68F24(this); + } + + this->actionFunc(this, globalCtx); + + if (this->actor.update != NULL) { + if ((this->actionFunc == func_80A6AB08) || (this->actionFunc == func_80A6AE7C)) { + this->unk_30C |= 0x200; + } else { + this->unk_30C &= ~0x200; + } + + if ((this->actionFunc == func_80A6A5C0) || (this->actionFunc == func_80A6A824) || + (this->actionFunc == func_80A6A9E4)) { + func_80A68BC8(this); + } + + if (this->unk_34C != NULL) { + sp4C = 0.0f; + + this->unk_354 = Math3D_Vec3fDistSq(&this->actor.world.pos, &this->unk_34C->dyna.actor.world.pos); + if (this->unk_354 < this->unk_350) { + f32 dist = Math3D_DistPlaneToPos(COLPOLY_GET_NORMAL(this->unk_34C->dyna.actor.floorPoly->normal.x), + COLPOLY_GET_NORMAL(this->unk_34C->dyna.actor.floorPoly->normal.y), + COLPOLY_GET_NORMAL(this->unk_34C->dyna.actor.floorPoly->normal.z), + this->unk_34C->dyna.actor.floorPoly->dist, &this->actor.world.pos); + + if (fabsf(dist) < 3.0f) { + sp4C = 1.9f; + } + } + Math_StepToF(&this->unk_348, sp4C, 0.7f); + } + + SkelAnime_Update(&this->skelAnime); + + if (this->actor.flags & ACTOR_FLAG_40) { + if ((this->actionFunc != func_80A6AE7C) && (this->actionFunc != func_80A6B0D8) && + ((this->actionFunc != func_80A6A36C) || (this->unk_36A < 0xDD)) && + (((this->actionFunc != func_80A6A5C0) && (this->actionFunc != func_80A6A824) && + (this->actionFunc != func_80A6A9E4)) || + !(this->unk_358 > 0.999f) || !(this->unk_354 < SQ(20.0f)))) { + s32 phi_v0 = true; + + if (this->unk_34C == NULL) { + this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; + } else { + this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; + if ((this->unk_358 > 0.999f) && (this->unk_354 < SQ(20.0f))) { + phi_v0 = false; + } + } + + if (phi_v0) { + 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; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + } + + if ((this->unk_30C & 1) && func_80A68DD4(this, globalCtx)) { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 60.0f, 30.0f); + } + } +} + +void EnMushi2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMushi2* this = THIS; + + func_80A687A0(this); + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, NULL); +} diff --git a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.h b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.h index eb22a4973..f773cd746 100644 --- a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.h +++ b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.h @@ -7,11 +7,42 @@ struct EnMushi2; typedef void (*EnMushi2ActionFunc)(struct EnMushi2*, GlobalContext*); +#define ENMUSHI2_GET_3(thisx) ((thisx)->params & 3) + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; +} EnMushi2Struct; + typedef struct EnMushi2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C4]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ ColliderJntSph collider; + /* 0x02C8 */ ColliderJntSphElement colliderElements[1]; /* 0x0308 */ EnMushi2ActionFunc actionFunc; - /* 0x030C */ char unk_30C[0x68]; + /* 0x030C */ s32 unk_30C; + /* 0x0310 */ Vec3f unk_310; + /* 0x031C */ Vec3f unk_31C; + /* 0x0328 */ Vec3f unk_328; + /* 0x0334 */ CollisionPoly* poly; + /* 0x0338 */ s32 polyBgId; + /* 0x033C */ Vec3f unk_33C; + /* 0x0348 */ f32 unk_348; + /* 0x034C */ struct ObjBean* unk_34C; + /* 0x0350 */ f32 unk_350; + /* 0x0354 */ f32 unk_354; + /* 0x0358 */ f32 unk_358; + /* 0x035C */ f32 unk_35C; + /* 0x0360 */ f32 unk_360; + /* 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; } EnMushi2; // size = 0x374 extern const ActorInit En_Mushi2_InitVars; 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 041fad748..c4b2beffc 100644 --- a/src/overlays/actors/ovl_En_Muto/z_en_muto.c +++ b/src/overlays/actors/ovl_En_Muto/z_en_muto.c @@ -5,8 +5,9 @@ */ #include "z_en_muto.h" +#include "objects/object_toryo/object_toryo.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnMuto*)thisx) @@ -23,9 +24,6 @@ void EnMuto_SetupDialogue(EnMuto* this, GlobalContext* globalCtx); void EnMuto_InDialogue(EnMuto* this, GlobalContext* globalCtx); s32 EnMuto_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); -extern AnimationHeader D_06000E50; -extern FlexSkeletonHeader D_06007150; - const ActorInit En_Muto_InitVars = { ACTOR_EN_MUTO, ACTORCAT_NPC, @@ -64,18 +62,19 @@ void EnMuto_Init(Actor* thisx, GlobalContext* globalCtx) { EnMuto* this = THIS; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 40.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06007150, &D_06000E50, this->jointTable, this->morphTable, 17); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 40.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_toryo_Skel_007150, &object_toryo_Anim_000E50, + this->jointTable, this->morphTable, 17); this->isInMayorsRoom = this->actor.params; if (!this->isInMayorsRoom) { this->shouldSetHeadRotation = true; this->textIdIndex = 2; - if (gSaveContext.weekEventReg[60] & 0x80) { + if (gSaveContext.save.weekEventReg[60] & 0x80) { this->textIdIndex = 3; } - if (gSaveContext.day != 3 || !gSaveContext.isNight) { + if (gSaveContext.save.day != 3 || !gSaveContext.save.isNight) { Actor_MarkForDeath(&this->actor); } } else { @@ -83,7 +82,7 @@ void EnMuto_Init(Actor* thisx, GlobalContext* globalCtx) { this->collider.dim.height = 60; this->collider.dim.yShift = 0; - if (gSaveContext.weekEventReg[63] & 0x80 || (gSaveContext.day == 3 && gSaveContext.isNight)) { + if (gSaveContext.save.weekEventReg[63] & 0x80 || (gSaveContext.save.day == 3 && gSaveContext.save.isNight)) { Actor_MarkForDeath(&this->actor); } } @@ -101,8 +100,8 @@ void EnMuto_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void EnMuto_ChangeAnim(EnMuto* this, s32 animIndex) { - static AnimationHeader* sAnimations[] = { &D_06000E50, &D_06000E50 }; - static u8 sAnimationModes[] = { 0, 2 }; + static AnimationHeader* sAnimations[] = { &object_toryo_Anim_000E50, &object_toryo_Anim_000E50 }; + static u8 sAnimationModes[] = { ANIMMODE_LOOP, ANIMMODE_ONCE }; this->animIndex = animIndex; this->frameIndex = Animation_GetLastFrame(&sAnimations[animIndex]->common); @@ -134,11 +133,14 @@ void EnMuto_Idle(EnMuto* this, GlobalContext* globalCtx) { Player* player; this->actor.textId = sTextIds[this->textIdIndex]; - if (!this->isInMayorsRoom && (player = GET_PLAYER(globalCtx))->transformation == PLAYER_FORM_DEKU) { - if (!(gSaveContext.weekEventReg[0x58] & 8)) { - this->actor.textId = 0x62C; - } else { - this->actor.textId = 0x62B; + if (!this->isInMayorsRoom) { + player = GET_PLAYER(globalCtx); + if (player->transformation == PLAYER_FORM_DEKU) { + if (!(gSaveContext.save.weekEventReg[88] & 8)) { + this->actor.textId = 0x62C; + } else { + this->actor.textId = 0x62B; + } } } @@ -148,7 +150,7 @@ void EnMuto_Idle(EnMuto* this, GlobalContext* globalCtx) { this->actor.textId = 0x2363; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { EnMuto_SetupDialogue(this, globalCtx); return; } @@ -162,10 +164,10 @@ void EnMuto_Idle(EnMuto* this, GlobalContext* globalCtx) { } } else { this->textIdIndex = 0; - if (gSaveContext.weekEventReg[0x3C] & 8) { + if (gSaveContext.save.weekEventReg[60] & 8) { this->textIdIndex = 1; } - if (Player_GetMask(globalCtx) == PLAYER_MASK_COUPLES_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_COUPLE) { this->textIdIndex = 4; } @@ -186,7 +188,7 @@ void EnMuto_SetupDialogue(EnMuto* this, GlobalContext* globalCtx) { if (this->targetActor != NULL) { this->shouldSetHeadRotation = true; this->cutsceneState = 1; - func_800B86C8(this->targetActor, globalCtx, this->targetActor); + Actor_ChangeFocus(this->targetActor, globalCtx, this->targetActor); } this->isInDialogue = true; @@ -196,14 +198,14 @@ void EnMuto_SetupDialogue(EnMuto* this, GlobalContext* globalCtx) { void EnMuto_InDialogue(EnMuto* this, GlobalContext* globalCtx) { if (!this->isInMayorsRoom) { this->yawTowardsTarget = this->actor.yawTowardsPlayer; - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); if (this->actor.textId == 0x62C) { - gSaveContext.weekEventReg[88] |= 8; + gSaveContext.save.weekEventReg[88] |= 8; } if (this->actor.textId == 0x624) { - gSaveContext.weekEventReg[60] |= 0x80; + gSaveContext.save.weekEventReg[60] |= 0x80; } this->textIdIndex = 3; @@ -227,13 +229,13 @@ void EnMuto_InDialogue(EnMuto* this, GlobalContext* globalCtx) { } } - if (globalCtx->msgCtx.unk11F04 == 0x2AC6 || globalCtx->msgCtx.unk11F04 == 0x2AC7 || - globalCtx->msgCtx.unk11F04 == 0x2AC8) { + if (globalCtx->msgCtx.currentTextId == 0x2AC6 || globalCtx->msgCtx.currentTextId == 0x2AC7 || + globalCtx->msgCtx.currentTextId == 0x2AC8) { this->skelAnime.playSpeed = 0.0f; this->yawTowardsTarget = this->actor.yawTowardsPlayer; this->skelAnime.curFrame = 30.0f; } - if (globalCtx->msgCtx.unk11F04 == 0x2ACF) { + if (globalCtx->msgCtx.currentTextId == 0x2ACF) { this->skelAnime.playSpeed = 0.0f; } @@ -252,7 +254,7 @@ void EnMuto_Update(Actor* thisx, GlobalContext* globalCtx2) { EnMuto_SetHeadRotation(this); } - if (this->isInMayorsRoom && gSaveContext.day == 3 && gSaveContext.isNight) { + if (this->isInMayorsRoom && gSaveContext.save.day == 3 && gSaveContext.save.isNight) { Actor_MarkForDeath(&this->actor); return; } @@ -263,8 +265,8 @@ void EnMuto_Update(Actor* thisx, GlobalContext* globalCtx2) { Actor_SetScale(&this->actor, 0.01f); this->actor.shape.rot.y = this->actor.world.rot.y; - Actor_SetHeight(&this->actor, 60.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, 60.0f); + Actor_MoveWithGravity(&this->actor); Math_SmoothStepToS(&this->headRot.y, this->headRotTarget.y, 1, 0xBB8, 0); Math_SmoothStepToS(&this->headRot.x, this->headRotTarget.x, 1, 0x3E8, 0); diff --git a/src/overlays/actors/ovl_En_Nb/z_en_nb.c b/src/overlays/actors/ovl_En_Nb/z_en_nb.c index 773945393..5f24e5b01 100644 --- a/src/overlays/actors/ovl_En_Nb/z_en_nb.c +++ b/src/overlays/actors/ovl_En_Nb/z_en_nb.c @@ -1,6 +1,12 @@ +/* + * File: z_en_nb.c + * Overlay: ovl_En_Nb + * Description: Anju's Grandma + */ + #include "z_en_nb.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnNb*)thisx) 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 c2548d548..591d4ddcb 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,6 +1,13 @@ -#include "z_en_neo_reeba.h" +/* + * File: z_en_neo_reeba.c + * Overlay: ovl_En_Neo_Reeba + * Description: (New) Leevers + */ -#define FLAGS 0x00000205 +#include "z_en_neo_reeba.h" +#include "objects/object_rb/object_rb.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200) #define THIS ((EnNeoReeba*)thisx) @@ -9,7 +16,26 @@ void EnNeoReeba_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnNeoReeba_Update(Actor* thisx, GlobalContext* globalCtx); void EnNeoReeba_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnNeoReeba_SetupWaitUnderground(EnNeoReeba* this); +void EnNeoReeba_WaitUnderground(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_ChooseAction(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupSink(EnNeoReeba* this); +void EnNeoReeba_Sink(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupRise(EnNeoReeba* this); +void EnNeoReeba_RiseOutOfGround(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupMove(EnNeoReeba* this); +void EnNeoReeba_Move(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupReturnHome(EnNeoReeba* this); +void EnNeoReeba_ReturnHome(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_Bounce(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_Stunned(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_Frozen(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupDamageAnim(EnNeoReeba* this); +void EnNeoReeba_DamageAnim(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SetupDeathEffects(EnNeoReeba* this); +void EnNeoReeba_PlayDeathEffects(EnNeoReeba* this, GlobalContext* globalCtx); +void EnNeoReeba_SpawnIce(EnNeoReeba* this, GlobalContext* globalCtx); + const ActorInit En_Neo_Reeba_InitVars = { ACTOR_EN_NEO_REEBA, ACTORCAT_ENEMY, @@ -22,118 +48,701 @@ const ActorInit En_Neo_Reeba_InitVars = { (ActorFunc)EnNeoReeba_Draw, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B7E500 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(1, 0xE), - /* Horse trample */ DMG_ENTRY(1, 0xF), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0xE), - /* Normal arrow */ DMG_ENTRY(1, 0xE), - /* UNK_DMG_0x06 */ DMG_ENTRY(1, 0xF), - /* Hookshot */ DMG_ENTRY(0, 0xC), - /* Goron punch */ DMG_ENTRY(1, 0xF), - /* Sword */ DMG_ENTRY(1, 0xF), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(2, 0x2), - /* Ice arrow */ DMG_ENTRY(2, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0x1), - /* Deku bubble */ DMG_ENTRY(1, 0xE), - /* Deku launch */ DMG_ENTRY(2, 0xF), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0xD), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* 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_NEO_REEBA_DMGEFF_IMMUNE, // No effect on the leever + /* 0x1 */ EN_NEO_REEBA_DMGEFF_STUN, // Turns blue, frozen in place + /* 0x2 */ EN_NEO_REEBA_DMGEFF_FIRE, + /* 0x3 */ EN_NEO_REEBA_DMGEFF_FREEZE, // Ice effects, frozen in place + /* 0x4 */ EN_NEO_REEBA_DMGEFF_LIGHT, + /* 0xC */ EN_NEO_REEBA_DMGEFF_HOOKSHOT = 0xC, // No damage, used only for hookshot + /* 0xD */ EN_NEO_REEBA_DMGEFF_ELECTRIC_STUN, // Electric effects, frozen in place + /* 0xE */ EN_NEO_REEBA_DMGEFF_NONE, // Normal hit + /* 0xF */ EN_NEO_REEBA_DMGEFF_SHATTER, // Normal hit that can break ice if leever is frozen +} EnNeoReebaDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Deku Stick */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Explosives */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Zora boomerang */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Hookshot */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Sword */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Goron pound */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Fire arrow */ DMG_ENTRY(2, EN_NEO_REEBA_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(2, EN_NEO_REEBA_DMGEFF_FREEZE), + /* Light arrow */ DMG_ENTRY(2, EN_NEO_REEBA_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Deku spin */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, EN_NEO_REEBA_DMGEFF_SHATTER), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Zora barrier */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_ELECTRIC_STUN), + /* Normal shield */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Light ray */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Thrown object */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Zora punch */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Spin attack */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), + /* Sword beam */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Normal Roll */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Unblockable */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_NEO_REEBA_DMGEFF_IMMUNE), + /* Powder Keg */ DMG_ENTRY(1, EN_NEO_REEBA_DMGEFF_SHATTER), }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B7E520 = { - { COLTYPE_HIT5, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x08, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT5, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x08, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 18, 30, 0, { 0, 0, 0 } }, }; -#endif +void EnNeoReeba_Init(Actor* thisx, GlobalContext* globalCtx) { + EnNeoReeba* this = THIS; -extern DamageTable D_80B7E500; -extern ColliderCylinderInit D_80B7E520; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gLeeverSkel, &gLeeverSpinAnim, this->jointTable, this->morphTable, + LEEVER_LIMB_MAX); -extern UNK_TYPE D_060001E4; + if (!EN_NEO_REEBA_IS_LARGE(&this->actor)) { + Actor_SetScale(&this->actor, 0.04f); + this->actor.colChkInfo.mass = 90; + this->actor.colChkInfo.health = 1; + } else { + Actor_SetScale(&this->actor, 0.05f); + this->actor.colChkInfo.mass = 180; + this->actor.colChkInfo.health = 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/EnNeoReeba_Init.s") + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.targetMode = 2; + this->actor.hintId = 0x47; + this->actor.gravity = -0.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/EnNeoReeba_Destroy.s") + this->targetPos = gZeroVec3f; + this->velToTarget = gZeroVec3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CA34.s") + this->rotationAngle = 0; + this->sfxTimer = 0; + this->stunTimer = 0; + this->actionTimer = 0; + this->sinkRiseRate = 0.0f; + this->rotationSpeed = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CA70.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CB3C.s") + EnNeoReeba_SetupWaitUnderground(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CB88.s") +void EnNeoReeba_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnNeoReeba* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CCE0.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CD28.s") +void EnNeoReeba_SetupWaitUnderground(EnNeoReeba* this) { + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.draw = NULL; + this->actionTimer = 10; + this->actionFunc = EnNeoReeba_WaitUnderground; + this->actor.shape.yOffset = -2000.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CE34.s") +void EnNeoReeba_WaitUnderground(EnNeoReeba* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CE94.s") + if ((Actor_XZDistanceToPoint(&player->actor, &this->actor.home.pos) < 200.0f) && + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && (fabsf(this->actor.playerHeightRel) < 100.0f)) { + EnNeoReeba_SetupRise(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CFA0.s") + if (this->actionTimer == 0) { + this->actor.world.pos = this->actor.home.pos; + this->actionTimer = -1; + } else { + this->actionTimer--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7CFFC.s") +void EnNeoReeba_SetupChooseAction(EnNeoReeba* this) { + this->actor.shape.yOffset = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D130.s") + if (this->actionFunc == EnNeoReeba_Move) { + this->actionTimer = 20; + } else { + this->actionTimer = 10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D150.s") + this->actionFunc = EnNeoReeba_ChooseAction; + this->skelAnime.playSpeed = 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D254.s") +void EnNeoReeba_ChooseAction(EnNeoReeba* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 distToPlayer = Actor_XZDistanceToPoint(&player->actor, &this->actor.home.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D2E4.s") + if ((distToPlayer > 200.0f) || (fabsf(this->actor.playerHeightRel) > 100.0f)) { + EnNeoReeba_SetupSink(this); + } else { + if (this->actionTimer == 0) { + if ((distToPlayer < 140.0f) && (fabsf(this->actor.playerHeightRel) < 100.0f)) { + this->targetPos = player->actor.world.pos; + this->targetPos.x += 10.0f * player->actor.speedXZ * Math_SinS(player->actor.world.rot.y); + this->targetPos.z += 10.0f * player->actor.speedXZ * Math_CosS(player->actor.world.rot.y); + EnNeoReeba_SetupMove(this); + } else { + EnNeoReeba_SetupReturnHome(this); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D360.s") + if (this->actionTimer != 0) { + this->actionTimer--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D398.s") +void EnNeoReeba_SetupSink(EnNeoReeba* this) { + this->sinkRiseRate = 0.0f; + this->skelAnime.playSpeed = 2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actionFunc = EnNeoReeba_Sink; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D3EC.s") +void EnNeoReeba_Sink(EnNeoReeba* this, GlobalContext* globalCtx) { + if (Math_SmoothStepToF(&this->actor.shape.yOffset, -2000.0f, 0.5f, this->sinkRiseRate, 10.0f) == 0.0f) { + EnNeoReeba_SetupWaitUnderground(this); + } else if (globalCtx->gameplayFrames % 4 == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, + 8.0f, 500, 10, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D47C.s") + if (this->sinkRiseRate < 300.0f) { + this->sinkRiseRate += 20.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D4FC.s") + Math_ApproachF(&this->actor.shape.shadowScale, 0.0f, 1.0f, 1.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D5A4.s") +void EnNeoReeba_SetupRise(EnNeoReeba* this) { + this->actor.draw = EnNeoReeba_Draw; + this->sinkRiseRate = 300.0f; + this->skelAnime.playSpeed = 2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_APPEAR); + this->actor.flags |= ACTOR_FLAG_1; + this->actionFunc = EnNeoReeba_RiseOutOfGround; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D6D0.s") +void EnNeoReeba_RiseOutOfGround(EnNeoReeba* this, GlobalContext* globalCtx) { + if (Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 0.5f, this->sinkRiseRate, 10.0f) == 0.0f) { + EnNeoReeba_SetupChooseAction(this); + } else if (globalCtx->gameplayFrames % 4 == 0) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, + 8.0f, 500, 10, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D788.s") + if (this->sinkRiseRate > 20.0f) { + this->sinkRiseRate -= 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7D9B8.s") + Math_ApproachF(&this->actor.shape.shadowScale, 12.0f, 1.0f, 1.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7DC80.s") +void EnNeoReeba_SetupMove(EnNeoReeba* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIVA_MOVE); + this->sfxTimer = 10; + this->actionTimer = 60; + this->actionFunc = EnNeoReeba_Move; + this->skelAnime.playSpeed = 2.0f; + this->actor.speedXZ = 14.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7DD7C.s") +void EnNeoReeba_Move(EnNeoReeba* this, GlobalContext* globalCtx) { + f32 remainingDist = Math_Vec3f_StepToXZ(&this->actor.world.pos, &this->targetPos, this->actor.speedXZ); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7DF34.s") + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, 4.0f, + 0xFA, 0xA, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7E0BC.s") + if (remainingDist < 2.0f) { + EnNeoReeba_SetupChooseAction(this); + } else if (remainingDist < 40.0f && this->actor.speedXZ > 3.0f) { + this->actor.speedXZ -= 2.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7E260.s") + if (this->sfxTimer == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIVA_MOVE); + this->sfxTimer = 10; + } else { + this->sfxTimer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/EnNeoReeba_Update.s") + if (this->actionTimer == 0) { + EnNeoReeba_SetupChooseAction(this); + } else { + this->actionTimer--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/func_80B7E378.s") +void EnNeoReeba_SetupReturnHome(EnNeoReeba* this) { + this->actionFunc = EnNeoReeba_ReturnHome; + this->actor.speedXZ = 6.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Neo_Reeba/EnNeoReeba_Draw.s") +void EnNeoReeba_ReturnHome(EnNeoReeba* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + f32 remainingDist = Math_Vec3f_StepToXZ(&this->actor.world.pos, &this->actor.home.pos, this->actor.speedXZ); + + if (remainingDist < 2.0f) { + EnNeoReeba_SetupChooseAction(this); + } else if (remainingDist < 40.0f && this->actor.speedXZ > 3.0f) { + this->actor.speedXZ -= 1.0f; + } + + if (Actor_XZDistanceToPoint(&player->actor, &this->actor.home.pos) > 200.0f || + fabsf(this->actor.playerHeightRel) > 100.0f) { + EnNeoReeba_SetupSink(this); + } +} + +void EnNeoReeba_SetupBounce(EnNeoReeba* this) { + this->actionTimer = 60; + this->targetPos = this->actor.world.pos; + this->targetPos.x -= 20.0f * Math_SinS(this->actor.yawTowardsPlayer); + this->targetPos.z -= 20.0f * Math_CosS(this->actor.yawTowardsPlayer); + this->actionFunc = EnNeoReeba_Bounce; +} + +void EnNeoReeba_Bounce(EnNeoReeba* this, GlobalContext* globalCtx) { + if (Math_Vec3f_StepToXZ(&this->actor.world.pos, &this->targetPos, this->actor.speedXZ) < 2.0f) { + EnNeoReeba_SetupChooseAction(this); + } + + if (this->actionTimer == 0) { + EnNeoReeba_SetupChooseAction(this); + } else { + this->actionTimer--; + } +} + +void EnNeoReeba_SetupStun(EnNeoReeba* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = EnNeoReeba_Stunned; +} + +void EnNeoReeba_Stunned(EnNeoReeba* this, GlobalContext* globalCtx) { + if (this->stunTimer > 0) { + this->stunTimer--; + } else { + this->drawEffectAlpha = 0.0f; + this->drawEffectScale = 0.0f; + } + + if (this->actor.colorFilterTimer == 0) { + this->stunTimer = 0; + EnNeoReeba_SetupChooseAction(this); + } +} + +void EnNeoReeba_SetupFrozen(EnNeoReeba* this) { + this->drawEffectType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + this->drawEffectScale = 0.5f; + this->drawEffectAlpha = 1.0f; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + this->drawEffectScale *= 1.5f; + } + + if (this->actor.colChkInfo.health != 0) { + this->stunTimer = 80; + } else { + this->stunTimer = 12; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = EnNeoReeba_Frozen; +} + +void EnNeoReeba_Frozen(EnNeoReeba* this, GlobalContext* globalCtx) { + if (this->stunTimer == 0) { + this->stunTimer = 0; + this->drawEffectScale = 0.0f; + this->drawEffectAlpha = 0.0f; + + if (this->actor.colChkInfo.health != 0) { + EnNeoReeba_SetupDamageAnim(this); + } else { + EnNeoReeba_SetupDeathEffects(this); + } + } else if (this->stunTimer == 1) { + this->stunTimer--; + EnNeoReeba_SpawnIce(this, globalCtx); + } else { + this->stunTimer--; + } +} + +void EnNeoReeba_SetupDamageAnim(EnNeoReeba* this) { + this->actionTimer = 10; + this->skelAnime.playSpeed = 1.0f; + this->velToTarget.x = Math_SinS(this->actor.yawTowardsPlayer) * -12.0f; + this->velToTarget.z = Math_CosS(this->actor.yawTowardsPlayer) * -12.0f; + this->rotationSpeed = 4551.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 25); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIVA_DAMAGE); + this->actionFunc = EnNeoReeba_DamageAnim; +} + +static f32 sDamageAnimXZScales[] = { 0.04, 0.04, 0.039, 0.042, 0.045, 0.043, 0.04, 0.035, 0.03, 0.033, 0.04 }; +static f32 sDamageAnimYScales[] = { 0.04f, 0.04f, 0.041f, 0.038f, 0.035f, 0.037f, 0.04f, 0.045f, 0.05f, 0.047f, 0.04f }; + +void EnNeoReeba_DamageAnim(EnNeoReeba* this, GlobalContext* globalCtx) { + if (this->actionTimer == 0) { + this->rotationSpeed = 0.0f; + EnNeoReeba_SetupChooseAction(this); + } else { + this->rotationAngle -= 0x1F40; + Math_SmoothStepToF(&this->rotationSpeed, 0.0f, 0.5f, 182.0f, 18.0f); + this->actor.scale.x = this->actor.scale.z = sDamageAnimXZScales[this->actionTimer]; + this->actor.scale.y = sDamageAnimYScales[this->actionTimer]; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + this->actor.scale.x *= 1.5f; + this->actor.scale.y *= 1.5f; + this->actor.scale.z *= 1.5f; + } + + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, this->actor.shape.shadowScale, 1, + 4.0f, 250, 10, 1); + this->actionTimer--; + } +} + +void EnNeoReeba_SetupDeathEffects(EnNeoReeba* this) { + this->actionTimer = 10; + + this->velToTarget.x = Math_SinS(this->actor.yawTowardsPlayer) * -12.0f; + this->velToTarget.z = Math_CosS(this->actor.yawTowardsPlayer) * -12.0f; + + this->rotationSpeed = 3640.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 25); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIVA_DEAD); + this->actionFunc = EnNeoReeba_PlayDeathEffects; +} + +void EnNeoReeba_PlayDeathEffects(EnNeoReeba* this, GlobalContext* globalCtx) { + static Vec3f sDeadDbVel = { 0.0f, 0.0f, 0.0f }; + static Vec3f sDeadDbAccel = { 0.0f, 4.0f, 0.0f }; + + if (this->actionTimer == 0) { + Math_ApproachZeroF(&this->actor.scale.x, 0.1f, 0.01f); + Math_ApproachZeroF(&this->actor.scale.y, 0.1f, 0.01f); + Math_ApproachZeroF(&this->actor.scale.z, 0.1f, 0.01f); + Math_ApproachZeroF(&this->drawEffectAlpha, 0.1f, 0.1f); + Math_ApproachZeroF(&this->drawEffectScale, 0.1f, 0.1f); + + if (this->actor.scale.x < 0.01f) { + func_800B3030(globalCtx, &this->actor.world.pos, &sDeadDbAccel, &sDeadDbVel, 120, 0, 0); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60); + Actor_MarkForDeath(&this->actor); + } + } else { + if (this->actionTimer <= 10) { + this->rotationAngle -= 0x1388; + this->actor.scale.x = this->actor.scale.z = sDamageAnimXZScales[this->actionTimer]; + this->actor.scale.y = sDamageAnimYScales[this->actionTimer]; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + this->actor.scale.x *= 1.5f; + this->actor.scale.y *= 1.5f; + this->actor.scale.z *= 1.5f; + } + } + + if (this->drawEffectType == ACTOR_DRAW_DMGEFF_FIRE) { + f32 target = 1.2f; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + target *= 1.5f; + } + + Math_SmoothStepToF(&this->drawEffectScale, target, 0.5f, 0.3f, 0.0f); + } else { + f32 target = 1.6f; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + target *= 1.5f; + } + + Math_SmoothStepToF(&this->drawEffectScale, target, 0.5f, 0.3f, 0.0f); + } + this->actionTimer--; + } +} + +void EnNeoReeba_HandleHit(EnNeoReeba* this, GlobalContext* globalCtx) { + Actor_SetFocus(&this->actor, 20.0f); + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actionFunc == EnNeoReeba_Frozen) { + switch (this->actor.colChkInfo.damageEffect) { + case EN_NEO_REEBA_DMGEFF_STUN: + case EN_NEO_REEBA_DMGEFF_FREEZE: + case EN_NEO_REEBA_DMGEFF_LIGHT: + case EN_NEO_REEBA_DMGEFF_ELECTRIC_STUN: + case EN_NEO_REEBA_DMGEFF_NONE: + return; + default: + if (this->stunTimer >= 2) { + EnNeoReeba_SpawnIce(this, globalCtx); + } + this->stunTimer = 0; + } + } + + Actor_ApplyDamage(&this->actor); + + switch (this->actor.colChkInfo.damageEffect) { + case EN_NEO_REEBA_DMGEFF_FREEZE: + EnNeoReeba_SetupFrozen(this); + break; + + case EN_NEO_REEBA_DMGEFF_FIRE: + case EN_NEO_REEBA_DMGEFF_LIGHT: + if (this->actor.colChkInfo.damageEffect == EN_NEO_REEBA_DMGEFF_FIRE) { + this->drawEffectType = ACTOR_DRAW_DMGEFF_FIRE; + this->stunTimer = 80; + } else { + this->drawEffectType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->stunTimer = 40; + } + this->drawEffectAlpha = 1.0f; + this->drawEffectScale = 0.0f; + /* fallthrough */ + case EN_NEO_REEBA_DMGEFF_NONE: + case EN_NEO_REEBA_DMGEFF_SHATTER: + if ((this->actor.colChkInfo.damageEffect == EN_NEO_REEBA_DMGEFF_SHATTER) || + (this->actor.colChkInfo.damageEffect == EN_NEO_REEBA_DMGEFF_NONE)) { + this->stunTimer = 0; + } + if (this->actor.colChkInfo.health > 0) { + EnNeoReeba_SetupDamageAnim(this); + } else { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + EnNeoReeba_SetupDeathEffects(this); + } + break; + + case EN_NEO_REEBA_DMGEFF_ELECTRIC_STUN: + this->drawEffectType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->stunTimer = 40; + this->drawEffectAlpha = 1.0f; + this->drawEffectScale = 2.0f; + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 40); + EnNeoReeba_SetupStun(this); + break; + + case EN_NEO_REEBA_DMGEFF_STUN: + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 40); + EnNeoReeba_SetupStun(this); + break; + } + } else { + if (((this->collider.base.ocFlags2 & OC2_HIT_PLAYER) || (this->collider.base.atFlags & AT_BOUNCED)) && + (this->actionFunc == EnNeoReeba_Move)) { + EnNeoReeba_SetupBounce(this); + } + } + if ((this->actionFunc != EnNeoReeba_WaitUnderground) && (this->actionFunc != EnNeoReeba_Sink) && + (this->actionFunc != EnNeoReeba_RiseOutOfGround) && (this->actionFunc != EnNeoReeba_DamageAnim) && + (this->actionFunc != EnNeoReeba_PlayDeathEffects)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actionFunc != EnNeoReeba_Stunned) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void EnNeoReeba_UpdatePosition(EnNeoReeba* this, GlobalContext* globalCtx) { + if ((this->actionFunc != EnNeoReeba_WaitUnderground) && (this->actionFunc != EnNeoReeba_Sink) && + (this->actionFunc != EnNeoReeba_RiseOutOfGround)) { + this->actor.velocity.y += this->actor.gravity; + + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.x += this->actor.colChkInfo.displacement.x; + this->actor.world.pos.z += this->actor.colChkInfo.displacement.z; + + this->actor.world.pos.x += this->velToTarget.x; + this->actor.world.pos.z += this->velToTarget.z; + + Math_ApproachZeroF(&this->velToTarget.x, 1.0f, 2.0f); + Math_ApproachZeroF(&this->velToTarget.z, 1.0f, 2.0f); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 40.0f, 40.0f, 5); + } +} + +void EnNeoReeba_DrawFrozenEffects(EnNeoReeba* this, GlobalContext* globalCtx) { + s32 i; + f32 limbPosScale = 10.0f; + f32 phi_f2 = 20.0f; + f32 drawEffectScale = 0.8f; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + limbPosScale *= 1.5f; + phi_f2 *= 1.5f; + drawEffectScale *= 1.5f; + } + + for (i = 0; i < ARRAY_COUNT(this->limbPos) - 1; i++) { + this->limbPos[i] = this->actor.world.pos; + + this->limbPos[i].x += limbPosScale * Math_SinS(BINANG_ADD(this->actor.shape.rot.y, i * 0x5555)); + this->limbPos[i].z += limbPosScale * Math_CosS(BINANG_ADD(this->actor.shape.rot.y, i * 0x5555)); + this->limbPos[i].y += 5.0f; + } + + this->limbPos[ARRAY_COUNT(this->limbPos) - 1] = this->actor.world.pos; + this->limbPos[ARRAY_COUNT(this->limbPos) - 1].y += phi_f2; + + this->drawEffectScale = drawEffectScale; + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), drawEffectScale, 0.5f, + this->drawEffectAlpha, this->drawEffectType); +} + +void EnNeoReeba_DrawEffects(EnNeoReeba* this, GlobalContext* globalCtx) { + s32 i; + f32 scale = 15.0f; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + scale *= 1.5f; + } + + if ((this->drawEffectType == ACTOR_DRAW_DMGEFF_FIRE) || (this->drawEffectType == ACTOR_DRAW_DMGEFF_LIGHT_ORBS) || + (this->drawEffectType == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL)) { + for (i = 0; i < ARRAY_COUNT(this->limbPos) - 1; i++) { + this->limbPos[i] = this->actor.world.pos; + this->limbPos[i].x += scale * Math_SinS(BINANG_ADD(this->actor.shape.rot.y, i * 0x5555)); + this->limbPos[i].z += scale * Math_CosS(BINANG_ADD(this->actor.shape.rot.y, i * 0x5555)); + this->limbPos[i].y += -20.0f; + } + + this->limbPos[ARRAY_COUNT(this->limbPos) - 1] = this->actor.world.pos; + Actor_DrawDamageEffects(globalCtx, NULL, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawEffectScale, 0.5f, + this->drawEffectAlpha, this->drawEffectType); + } +} + +void EnNeoReeba_SpawnIce(EnNeoReeba* this, GlobalContext* globalCtx) { + static Color_RGBA8 sIcePrimColor = { 170, 255, 255, 255 }; + static Color_RGBA8 sIceEnvColor = { 200, 200, 255, 255 }; + static Vec3f sIceAccel = { 0.0f, -1.0f, 0.0f }; + Vec3f iceVel; + f32 xVel; + f32 zVel; + s32 i; + s16 yaw; + s32 j; + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->limbPos[i]); + xVel = Math_SinS(yaw) * 3.0f; + zVel = Math_CosS(yaw) * 3.0f; + + for (j = 0; j < 4; j++) { + iceVel.x = (Rand_Centered() * 3.0f) + xVel; + iceVel.z = (Rand_Centered() * 3.0f) + zVel; + iceVel.y = (Rand_ZeroOne() * 6.0f) + 4.0f; + EffectSsEnIce_Spawn(globalCtx, &this->limbPos[i], 0.7f, &iceVel, &sIceAccel, &sIcePrimColor, &sIceEnvColor, + 30); + } + } +} + +void EnNeoReeba_SinkIfStoneMask(EnNeoReeba* this, GlobalContext* globalCtx) { + if ((this->actionFunc == EnNeoReeba_ChooseAction) || (this->actionFunc == EnNeoReeba_Move) || + (this->actionFunc == EnNeoReeba_ReturnHome)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) { + EnNeoReeba_SetupSink(this); + } + } +} + +void EnNeoReeba_Update(Actor* thisx, GlobalContext* globalCtx) { + EnNeoReeba* this = THIS; + + if (EN_NEO_REEBA_IS_LARGE(&this->actor)) { + this->collider.dim.radius = 27; + this->collider.dim.height = 45; + } + + this->actionFunc(this, globalCtx); + + if ((this->actionFunc != EnNeoReeba_WaitUnderground) && (this->actionFunc != EnNeoReeba_Stunned) && + (this->actionFunc != EnNeoReeba_Frozen)) { + SkelAnime_Update(&this->skelAnime); + } + + EnNeoReeba_HandleHit(this, globalCtx); + EnNeoReeba_UpdatePosition(this, globalCtx); + EnNeoReeba_SinkIfStoneMask(this, globalCtx); +} + +s32 EnNeoReeba_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnNeoReeba* this = THIS; + + if ((limbIndex == OBJECT_RB_LIMB_03) && (this->rotationSpeed != 0.0f)) { + rot->y += (s16)(this->rotationSpeed * Math_SinS(this->rotationAngle)); + rot->z += (s16)(this->rotationSpeed * Math_CosS(this->rotationAngle)); + } + + return false; +} + +void EnNeoReeba_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnNeoReeba* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + OPEN_DISPS(globalCtx->state.gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x01, 255, 255, 255, 255); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnNeoReeba_OverrideLimbDraw, + NULL, &this->actor); + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (this->stunTimer > 0) { + if (this->drawEffectType == ACTOR_DRAW_DMGEFF_FROZEN_SFX) { + EnNeoReeba_DrawFrozenEffects(this, globalCtx); + } else { + EnNeoReeba_DrawEffects(this, globalCtx); + } + } +} diff --git a/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.h b/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.h index 8d1091dfc..df6aaab1d 100644 --- a/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.h +++ b/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.h @@ -2,16 +2,33 @@ #define Z_EN_NEO_REEBA_H #include "global.h" +#include "objects/object_rb/object_rb.h" + +#define EN_NEO_REEBA_IS_LARGE(thisx) ((thisx)->params & 0x8000) struct EnNeoReeba; typedef void (*EnNeoReebaActionFunc)(struct EnNeoReeba*, GlobalContext*); typedef struct EnNeoReeba { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x168]; - /* 0x02AC */ EnNeoReebaActionFunc actionFunc; - /* 0x02B0 */ char unk_2B0[0x64]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ ColliderCylinder collider; + /* 0x1D4 */ Vec3s jointTable[LEEVER_LIMB_MAX]; + /* 0x240 */ Vec3s morphTable[LEEVER_LIMB_MAX]; + /* 0x2AC */ EnNeoReebaActionFunc actionFunc; + /* 0x2B0 */ Vec3f targetPos; + /* 0x2BC */ Vec3f velToTarget; + /* 0x2C8 */ Vec3f limbPos[4]; + /* 0x2F8 */ f32 sinkRiseRate; + /* 0x2FC */ f32 rotationSpeed; + /* 0x300 */ f32 drawEffectAlpha; + /* 0x304 */ f32 drawEffectScale; + /* 0x308 */ s16 rotationAngle; + /* 0x30A */ s16 actionTimer; + /* 0x30C */ s16 sfxTimer; + /* 0x30E */ s16 stunTimer; + /* 0x310 */ u8 drawEffectType; } EnNeoReeba; // size = 0x314 extern const ActorInit En_Neo_Reeba_InitVars; diff --git a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c index 2206589bf..779de0b8a 100644 --- a/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c +++ b/src/overlays/actors/ovl_En_Nimotsu/z_en_nimotsu.c @@ -1,6 +1,12 @@ +/* + * File: z_en_nimotsu.c + * Overlay: ovl_En_Nimotsu + * Description: Bomb Shop Bag Stolen by Sakon + */ + #include "z_en_nimotsu.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnNimotsu*)thisx) 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 4bad3b031..493666856 100644 --- a/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -5,8 +5,9 @@ */ #include "z_en_niw.h" +#include "overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.h" -#define FLAGS 0x00800010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_800000) #define THIS ((EnNiw*)thisx) @@ -29,17 +30,23 @@ void EnNiw_Held(EnNiw* this, GlobalContext* globalCtx); void EnNiw_UpdateFeather(EnNiw* this, GlobalContext* globalCtx); void EnNiw_DrawFeathers(EnNiw* this, GlobalContext* globalCtx); void EnNiw_CheckRage(EnNiw* this, GlobalContext* globalCtx); -void func_80891320(EnNiw* this, GlobalContext* globalCtx, s16 arg2); +void EnNiw_AnimateWingHead(EnNiw* this, GlobalContext* globalCtx, s16 animationState); void EnNiw_SpawnFeather(EnNiw* this, Vec3f* pos, Vec3f* vel, Vec3f* accel, f32 scale); -extern FlexSkeletonHeader D_06002530; -extern AnimationHeader D_060000E8; -extern Gfx D_060023B0[]; // gNiwFeatherMaterialDL -extern Gfx D_06002428[]; // gNiwFeatherDL +s16 sCuccoStormActive = false; -// turned on during cucco storm, but not read by anything? -// maybe read by En_Attack_Niw -s16 D_80893460 = false; +// why wouldnt they just use actionFunc? +enum EnNiwState { + /* 0 */ NIW_STATE_IDLE, + /* 1 */ NIW_STATE_ANGRY1, // 1/2/3 are stages of summoning cucco storm + /* 2 */ NIW_STATE_ANGRY2, + /* 3 */ NIW_STATE_ANGRY3, + /* 4 */ NIW_STATE_HELD, + /* 5 */ NIW_STATE_FALLING, + /* 6 */ NIW_STATE_SWIMMING, + /* 7 */ NIW_STATE_RUNNING, + /* 8 */ NIW_STATE_HOPPING, +}; const ActorInit En_Niw_InitVars = { ACTOR_EN_NIW, @@ -53,15 +60,11 @@ const ActorInit En_Niw_InitVars = { (ActorFunc)EnNiw_Draw, }; -static f32 D_80893484[] = { - 5000.0f, - -5000.0f, -}; -static f32 D_80893486[] = { - 5000.0f, - 3000.0f, - 4000.0f, -}; +static f32 sHeadRotations[] = { 5000.0f, -5000.0f }; + +static f32 sRunningAngles[] = { 5000.0f, 3000.0f }; + +static f32 sUnusedValue = 4000.0f; static ColliderCylinderInit sCylinderInit = { { @@ -110,11 +113,11 @@ static Vec3f D_808934E8 = { static s32 pad = 0; void EnNiw_Init(Actor* thisx, GlobalContext* globalCtx) { - EnNiw* this = (EnNiw*)thisx; + EnNiw* this = THIS; Vec3f dTemp = D_808934C4; - if (this->actor.params < 0) { // all neg values become zero - this->actor.params = ENNIW_TYPE_REGULAR; + if (this->actor.params < 0) { // all scene spawned cucco are (-1) + this->actor.params = NIW_TYPE_REGULAR; } Math_Vec3f_Copy(&this->unk2BC, &dTemp); @@ -122,36 +125,40 @@ void EnNiw_Init(Actor* thisx, GlobalContext* globalCtx) { this->niwType = this->actor.params; Actor_ProcessInitChain(&this->actor, sInitChain); - this->actor.flags |= 0x1; // targetable ON + this->actor.flags |= ACTOR_FLAG_1; // targetable ON - ActorShape_Init(&thisx->shape, 0.0f, func_800B3FC0, 25.0f); + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 25.0f); - SkelAnime_InitFlex(globalCtx, &this->skelanime, &D_06002530, &D_060000E8, this->jointTable, this->morphTable, - ENNIW_LIMBCOUNT); + SkelAnime_InitFlex(globalCtx, &this->skelanime, &gNiwSkeleton, &gNiwIdleAnim, this->jointTable, this->morphTable, + NIW_LIMB_MAX); Math_Vec3f_Copy(&this->unk2A4, &this->actor.world.pos); Math_Vec3f_Copy(&this->unk2B0, &this->actor.world.pos); this->unk308 = 10.0f; Actor_SetScale(&this->actor, 0.01f); - if (this->niwType == ENNIW_TYPE_UNK1) { + if (this->niwType == NIW_TYPE_UNK1) { + // @Bug this unused variant is broken and crashes on spawn (EnNiw_Update expects a parent, NULL) + // if modified to change niwType to TYPE_REGULAR here, new size is smaller than normal + // theory: was meant to be a small hand held cucco for grog to show the player Actor_SetScale(&this->actor, (BREG(86) / 10000.0f) + 0.004f); } // random health between 10-20 + // health at zero triggers cucco storm not death this->actor.colChkInfo.health = Rand_ZeroFloat(9.99f) + 10.0f; this->actor.colChkInfo.mass = MASS_IMMOVABLE; - if (this->niwType == ENNIW_TYPE_REGULAR) { + if (this->niwType == NIW_TYPE_REGULAR) { Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); } - if (this->niwType == ENNIW_TYPE_UNK2) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + if (this->niwType == NIW_TYPE_HELD) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); this->sfxTimer1 = 30; - this->unkTimer250 = 30; - this->actor.flags &= ~0x1; // targetable OFF - this->unknownState28E = 4; + this->heldTimer = 30; + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF + this->niwState = NIW_STATE_HELD; this->actionFunc = EnNiw_Held; this->actor.speedXZ = 0.0f; this->unk2BC.z = 0.0f; @@ -163,107 +170,121 @@ void EnNiw_Init(Actor* thisx, GlobalContext* globalCtx) { } void EnNiw_Destroy(Actor* thisx, GlobalContext* globalCtx) { - EnNiw* this = (EnNiw*)thisx; + EnNiw* this = THIS; - if (this->niwType == ENNIW_TYPE_REGULAR) { + if (this->niwType == NIW_TYPE_REGULAR) { Collider_DestroyCylinder(globalCtx, &this->collider); } } -void func_80891320(EnNiw* this, GlobalContext* globalCtx, s16 arg2) { - f32 tempOne = 1.0f; +/** + * Summary: instead of using SkelAnime animations, Niw modifies head+wings directly to create animations + * + * AttackNiw has a copy of this function that it barely uses + */ +void EnNiw_AnimateWingHead(EnNiw* this, GlobalContext* globalCtx, s16 animationState) { + f32 tempOne = 1.0f; // hopefully fake match, but no luck if (this->unkTimer24C == 0) { - if (arg2 == 0) { - this->unk264[0] = 0.0f; + // targetLimbRots[0] is bodyRotY + if (animationState == NIW_ANIMATION_STILL) { + this->targetLimbRots[0] = 0.0f; } else { - this->unk264[0] = (-10000.0f) * tempOne; + this->targetLimbRots[0] = -10000.0f * tempOne; } + this->unk292 += 1; this->unkTimer24C = 3; if ((this->unk292 % 2) == 0) { - this->unk264[0] = 0.0f; - if (arg2 == 0) { + this->targetLimbRots[0] = 0.0f; + if (animationState == NIW_ANIMATION_STILL) { this->unkTimer24C = Rand_ZeroFloat(30.0f); } } } + if (this->unkTimer24E == 0) { - this->unk296++; - this->unk296 &= 1; - switch (arg2) { - case 0: - this->unk264[2] = 0.0f; - this->unk264[1] = 0.0f; + this->unkToggle296++; + this->unkToggle296 &= 1; + + switch (animationState) { + case NIW_ANIMATION_STILL: + this->targetLimbRots[2] = 0.0f; // both wingRotZ + this->targetLimbRots[1] = 0.0f; break; - case 1: + case NIW_ANIMATION_HEAD_PECKING: this->unkTimer24E = 3; - this->unk264[2] = 7000.0f * tempOne; - this->unk264[1] = 7000.0f * tempOne; - if (this->unk296 == 0) { - this->unk264[2] = 0.0f; - this->unk264[1] = 0.0f; + this->targetLimbRots[2] = 7000.0f * tempOne; // both wingRotZ + this->targetLimbRots[1] = 7000.0f * tempOne; + if (this->unkToggle296 == 0) { + this->targetLimbRots[2] = 0.0f; // both wingRotZ + this->targetLimbRots[1] = 0.0f; } break; - case 2: + + case NIW_ANIMATION_PECKING_AND_WAVING: this->unkTimer24E = 2; - this->unk264[2] = -10000.0f; - this->unk264[1] = -10000.0f; - this->unk264[7] = 25000.0f; - this->unk264[5] = 25000.0f; - this->unk264[8] = 6000.0f; - this->unk264[6] = 6000.0f; - if (this->unk296 == 0) { - this->unk264[7] = 8000.0f; - this->unk264[5] = 8000.0f; + this->targetLimbRots[2] = -10000.0f; // both wingRotZ + this->targetLimbRots[1] = -10000.0f; + this->targetLimbRots[7] = 25000.0f; // both wingRotY + this->targetLimbRots[5] = 25000.0f; + this->targetLimbRots[8] = 6000.0f; // both wingRotX + this->targetLimbRots[6] = 6000.0f; + if (this->unkToggle296 == 0) { + this->targetLimbRots[7] = 8000.0f; // both wingRotY + this->targetLimbRots[5] = 8000.0f; } break; - case 3: + + case NIW_ANIMATION_PECKING_AND_FORFLAPPING: this->unkTimer24E = 2; - this->unk264[5] = 10000.0f; - this->unk264[7] = 10000.0f; - if (this->unk296 == 0) { - this->unk264[5] = 3000.0f; - this->unk264[7] = 3000.0f; + this->targetLimbRots[5] = 10000.0f; // both wingRotY + this->targetLimbRots[7] = 10000.0f; + if (this->unkToggle296 == 0) { + this->targetLimbRots[5] = 3000.0f; // both wingRotY + this->targetLimbRots[7] = 3000.0f; } break; - case 4: + + case NIW_ANIMATION_FREEZE: this->unkTimer24C = 5; break; - case 5: + + case NIW_ANIMATION_PECKING_SLOW_FORFLAPPING: this->unkTimer24E = 5; - this->unk264[5] = 14000.0f; - this->unk264[7] = 14000.0f; - if (this->unk296 == 0) { - this->unk264[5] = 10000.0f; - this->unk264[7] = 10000.0f; + this->targetLimbRots[5] = 14000.0f; // both wingRotY + this->targetLimbRots[7] = 14000.0f; + if (this->unkToggle296 == 0) { + this->targetLimbRots[5] = 10000.0f; // both wingRotY + this->targetLimbRots[7] = 10000.0f; } break; } } - if (this->unk264[9] != this->limbFRot) { - Math_ApproachF(&this->limbFRot, this->unk264[9], 0.5f, 4000.0f); + + if (this->targetLimbRots[9] != this->headRotY) { + Math_ApproachF(&this->headRotY, this->targetLimbRots[9], 0.5f, 4000.0f); } - if (this->unk264[0] != this->limbDRot) { - Math_ApproachF(&this->limbDRot, this->unk264[0], 0.5f, 4000.0f); + if (this->targetLimbRots[0] != this->upperBodyRotY) { + Math_ApproachF(&this->upperBodyRotY, this->targetLimbRots[0], 0.5f, 4000.0f); } - if (this->unk264[2] != this->limb7Rotz) { - Math_ApproachF(&this->limb7Rotz, this->unk264[2], 0.8f, 7000.0f); + if (this->targetLimbRots[2] != this->leftWingRotZ) { + Math_ApproachF(&this->leftWingRotZ, this->targetLimbRots[2], 0.8f, 7000.0f); } - if (this->unk264[7] != this->limb7Roty) { - Math_ApproachF(&this->limb7Roty, this->unk264[7], 0.8f, 7000.0f); + if (this->targetLimbRots[7] != this->leftWingRotY) { + Math_ApproachF(&this->leftWingRotY, this->targetLimbRots[7], 0.8f, 7000.0f); } - if (this->unk264[8] != this->limb7Rotx) { - Math_ApproachF(&this->limb7Rotx, this->unk264[8], 0.8f, 7000.0f); + if (this->targetLimbRots[8] != this->leftWingRotX) { + Math_ApproachF(&this->leftWingRotX, this->targetLimbRots[8], 0.8f, 7000.0f); } - if (this->unk264[1] != this->limbBRotz) { - Math_ApproachF(&this->limbBRotz, this->unk264[1], 0.8f, 7000.0f); + if (this->targetLimbRots[1] != this->rightWingRotZ) { + Math_ApproachF(&this->rightWingRotZ, this->targetLimbRots[1], 0.8f, 7000.0f); } - if (this->unk264[5] != this->limbBRoty) { - Math_ApproachF(&this->limbBRoty, this->unk264[5], 0.8f, 7000.0f); + if (this->targetLimbRots[5] != this->rightWingRotY) { + Math_ApproachF(&this->rightWingRotY, this->targetLimbRots[5], 0.8f, 7000.0f); } - if (this->unk264[6] != this->limbBRotx) { - Math_ApproachF(&this->limbBRotx, this->unk264[6], 0.8f, 7000.0f); + if (this->targetLimbRots[6] != this->rightWingRotX) { + Math_ApproachF(&this->rightWingRotX, this->targetLimbRots[6], 0.8f, 7000.0f); } } @@ -274,7 +295,7 @@ void EnNiw_SpawnAttackNiw(EnNiw* this, GlobalContext* globalCtx) { Vec3f newNiwPos; Actor* attackNiw; - if ((this->unkTimer252 == 0) && (this->unk290 < 7)) { + if (this->attackNiwSpawnTimer == 0 && this->attackNiwCount < 7) { xView = globalCtx->view.at.x - globalCtx->view.eye.x; yView = globalCtx->view.at.y - globalCtx->view.eye.y; zView = globalCtx->view.at.z - globalCtx->view.eye.z; @@ -282,53 +303,57 @@ void EnNiw_SpawnAttackNiw(EnNiw* this, GlobalContext* globalCtx) { newNiwPos.y = randPlusMinusPoint5Scaled(0.3f) + (globalCtx->view.eye.y + 50.0f + (yView * 0.5f)); newNiwPos.z = ((Rand_ZeroOne() - 0.5f) * zView) + globalCtx->view.eye.z; attackNiw = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ATTACK_NIW, newNiwPos.x, - newNiwPos.y, newNiwPos.z, 0, 0, 0, 0); + newNiwPos.y, newNiwPos.z, 0, 0, 0, ATTACK_NIW_REGULAR); - if (attackNiw) { - this->unk290++; - this->unkTimer252 = 10; + if (attackNiw != NULL) { + this->attackNiwCount++; + this->attackNiwSpawnTimer = 10; } } } -void func_808917F8(EnNiw* this, GlobalContext* globalCtx, s32 arg2) { - f32 phi_f2; +void EnNiw_UpdateRunning(EnNiw* this, GlobalContext* globalCtx, s32 isStormCucco) { + f32 runningDirection; f32 targetRotY; - f32* D_8089348CPtr = D_80893486; + f32* runningAngles = sRunningAngles; - if (this->unkTimer250 == 0) { - this->unkTimer250 = 3; - if (this->actor.bgCheckFlags & 1) { - // hit floor - this->actor.velocity.y = 3.5f; // hop up? + if (this->hopTimer == 0) { + this->hopTimer = 3; + if (this->actor.bgCheckFlags & 1) { // hit floor + this->actor.velocity.y = 3.5f; // hopping up while running away } } - if (this->unkTimer252 == 0) { - this->unk29A++; - this->unk29A &= 1; - this->unkTimer252 = 5; + + if (this->runningDirectionTimer == 0) { + this->isRunningRight++; + this->isRunningRight &= 1; + this->runningDirectionTimer = 5; } - if (this->unk29A == 0) { - phi_f2 = D_8089348CPtr[arg2]; + + if (this->isRunningRight == false) { + runningDirection = runningAngles[isStormCucco]; } else { - phi_f2 = -D_8089348CPtr[arg2]; + runningDirection = -runningAngles[isStormCucco]; } - if (arg2 == 1 && (this->unkTimer254 == 0 || (this->actor.bgCheckFlags & 8))) { - this->unkTimer254 = 150; + + if (isStormCucco == true && + (this->runAwayTimer == 0 || (this->actor.bgCheckFlags & 8))) { // bgCheckFlags 8: hit a wall + this->runAwayTimer = 150; if (this->yawTimer == 0) { this->yawTimer = 70; this->yawTowardsPlayer = this->actor.yawTowardsPlayer; } } - targetRotY = this->yawTowardsPlayer + phi_f2; + + targetRotY = this->yawTowardsPlayer + runningDirection; Math_SmoothStepToS(&this->actor.world.rot.y, targetRotY, 3, this->unk300, 0); Math_ApproachF(&this->unk300, 3000.0f, 1.0f, 500.0f); - func_80891320(this, globalCtx, 5); + EnNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_SLOW_FORFLAPPING); } void EnNiw_SetupIdle(EnNiw* this) { - Animation_Change(&this->skelanime, &D_060000E8, 1.0f, 0.0f, Animation_GetLastFrame(&D_060000E8), 0, -10.0f); - this->unknownState28E = 0; + Animation_Change(&this->skelanime, &gNiwIdleAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gNiwIdleAnim), 0, -10.0f); + this->niwState = NIW_STATE_IDLE; this->actionFunc = EnNiw_Idle; } @@ -337,40 +362,39 @@ void EnNiw_Idle(EnNiw* this, GlobalContext* globalCtx) { f32 posZ2; f32 posX1 = randPlusMinusPoint5Scaled(100.0f); f32 posZ1 = randPlusMinusPoint5Scaled(100.0f); - s16 s16tmp; + s16 nextAnimation; - if (this->niwType == ENNIW_TYPE_REGULAR) { - if (Actor_HasParent(&this->actor, globalCtx)) { - // picked up - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + if (this->niwType == NIW_TYPE_REGULAR) { + if (Actor_HasParent(&this->actor, globalCtx)) { // picked up + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow this->sfxTimer1 = 30; - this->unkTimer250 = 30; - this->actor.flags &= ~0x1; // targetable OFF - this->unknownState28E = 4; + this->heldTimer = 30; + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF + this->niwState = NIW_STATE_HELD; this->actor.speedXZ = 0.0f; this->actionFunc = EnNiw_Held; return; } else { - func_800B8BB0(&this->actor, globalCtx); + Actor_LiftActor(&this->actor, globalCtx); } - } else { - this->unkTimer252 = 10; + } else { // NIW_TYPE_UNK1 || NIW_TYPE_HELD + this->unkIdleTimer2 = 10; } - s16tmp = 0; - if (this->unkTimer252 != 0) { + nextAnimation = NIW_ANIMATION_STILL; // probably a scoped variable here, where their scope was different + if (this->unkIdleTimer2 != 0) { if (Rand_ZeroFloat(3.99f) < 1.0f) { - this->unk2EA++; - this->unk2EA &= 1; + this->headRotationToggle++; + this->headRotationToggle &= 1; } - Math_ApproachF(&this->unk264[9], D_80893484[this->unk2EA], 0.5f, 4000.0f); + + Math_ApproachF(&this->targetLimbRots[9], sHeadRotations[this->headRotationToggle], 0.5f, 4000.0f); // head rot } - if ((this->unkTimer252 == 0) && (this->unkTimer250 == 0)) { + if (this->unkIdleTimer2 == 0 && this->unkIdleTimer == 0) { this->unk298++; - if (this->unk298 > 7) { - this->unkTimer252 = Rand_ZeroFloat(30.0f); + this->unkIdleTimer2 = Rand_ZeroFloat(30.0f); this->unk298 = Rand_ZeroFloat(3.99f); if (posX1 < 0.0f) { @@ -388,17 +412,17 @@ void EnNiw_Idle(EnNiw* this, GlobalContext* globalCtx) { this->unk2B0.z = this->unk2A4.z + posZ1; } else { - this->unkTimer250 = 4; - if (this->actor.bgCheckFlags & 1) { + this->unkIdleTimer = 4; + if (this->actor.bgCheckFlags & 1) { // hit floor this->actor.speedXZ = 0.0f; - this->actor.velocity.y = 3.5f; + this->actor.velocity.y = 3.5f; // hopping up and down } } } - if (this->unkTimer250 != 0) { - Math_ApproachZeroF(&this->unk264[9], 0.5f, 4000.0f); - s16tmp = 1; + if (this->unkIdleTimer != 0) { + Math_ApproachZeroF(&this->targetLimbRots[9], 0.5f, 4000.0f); // head rot + nextAnimation = NIW_ANIMATION_HEAD_PECKING; Math_ApproachF(&this->actor.world.pos.x, this->unk2B0.x, 1.0f, this->unk300); Math_ApproachF(&this->actor.world.pos.z, this->unk2B0.z, 1.0f, this->unk300); Math_ApproachF(&this->unk300, 3.0f, 1.0f, 0.3f); @@ -414,34 +438,35 @@ void EnNiw_Idle(EnNiw* this, GlobalContext* globalCtx) { } if ((posX2 == 0.0f) && (posZ2 == 0.0f)) { - this->unkTimer250 = 0; + this->unkIdleTimer = 0; this->unk298 = 7; } Math_SmoothStepToS(&this->actor.world.rot.y, Math_Atan2S(posX2, posZ2), 3, this->unk304, 0); Math_ApproachF(&this->unk304, 10000.0f, 1.0f, 1000.0f); } - func_80891320(this, globalCtx, s16tmp); + + EnNiw_AnimateWingHead(this, globalCtx, nextAnimation); } void EnNiw_Held(EnNiw* this, GlobalContext* globalCtx) { Vec3f vec3fcopy = D_808934DC; s16 rotZ; - if (this->unkTimer250 == 0) { + if (this->heldTimer == 0) { this->unk29E = 2; - this->unkTimer250 = (s32)(Rand_ZeroFloat(1.0f) * 10.0f) + 10; + this->heldTimer = (s32)(Rand_ZeroFloat(1.0f) * 10.0f) + 10; } this->actor.shape.rot.x = (s16)randPlusMinusPoint5Scaled(5000.0f) + this->actor.world.rot.x; this->actor.shape.rot.y = (s16)randPlusMinusPoint5Scaled(5000.0f) + this->actor.world.rot.y; this->actor.shape.rot.z = (s16)randPlusMinusPoint5Scaled(5000.0f) + this->actor.world.rot.z; - if (this->niwType == ENNIW_TYPE_REGULAR) { + if (this->niwType == NIW_TYPE_REGULAR) { if (Actor_HasNoParent(&this->actor, globalCtx)) { this->actor.shape.rot.z = 0; rotZ = this->actor.shape.rot.z; - this->unknownState28E = 5; - this->actor.flags |= 0x1; // targetable ON + this->niwState = NIW_STATE_FALLING; + this->actor.flags |= ACTOR_FLAG_1; // targetable ON this->actionFunc = EnNiw_Thrown; this->actor.shape.rot.y = rotZ; this->actor.shape.rot.x = rotZ; @@ -452,39 +477,39 @@ void EnNiw_Held(EnNiw* this, GlobalContext* globalCtx) { this->actor.velocity.y = 8.0f; this->actor.speedXZ = 4.0f; this->actor.gravity = -2.0f; - this->unknownState28E = 5; + this->niwState = NIW_STATE_FALLING; this->unk2EC = 0; - this->niwType = ENNIW_TYPE_REGULAR; + this->niwType = NIW_TYPE_REGULAR; this->actor.shape.rot.y = rotZ; this->actor.shape.rot.x = rotZ; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); Math_Vec3f_Copy(&this->unk2BC, &vec3fcopy); - this->actor.flags |= 0x1; // targetable ON + this->actor.flags |= ACTOR_FLAG_1; // targetable ON this->actionFunc = EnNiw_Thrown; } - func_80891320(this, globalCtx, 2); + + EnNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); } -// action function: recently thrown, and also hopping on the floor void EnNiw_Thrown(EnNiw* this, GlobalContext* globalCtx) { if (this->unk2EC == 0) { - if (this->actor.bgCheckFlags & 1) { + if (this->actor.bgCheckFlags & 1) { // hit floor this->unk2EC = 1; - this->unkTimer252 = 80; // hop timer + this->hoppingTimer = 80; // hop timer this->actor.speedXZ = 0.0f; this->actor.velocity.y = 4.0f; } else { return; // wait until back on floor } } else { - if (this->actor.bgCheckFlags & 1) { + if (this->actor.bgCheckFlags & 1) { // hit floor this->sfxTimer1 = 0; this->actor.velocity.y = 4.0f; // vertical hop this->unk29E = 1; } - if (this->unkTimer252 == 0) { - this->unkTimer254 = 100; - this->unkTimer250 = 0; + if (this->hoppingTimer == 0) { + this->runAwayTimer = 100; + this->heldTimer = 0; this->unk2EC = 0; EnNiw_SetupRunAway(this); return; @@ -493,23 +518,22 @@ void EnNiw_Thrown(EnNiw* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { // picked up again before could run off - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow this->sfxTimer1 = 30; this->unk2EC = 0; - this->unkTimer250 = 30; - this->actor.flags &= ~0x1; // targetable OFF - this->unknownState28E = 4; + this->heldTimer = 30; + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF + this->niwState = NIW_STATE_HELD; this->actionFunc = EnNiw_Held; this->actor.speedXZ = 0.0f; } else { - if (this->unkTimer252 > 5) { - func_800B8BB0(&this->actor, globalCtx); + if (this->hoppingTimer > 5) { + Actor_LiftActor(&this->actor, globalCtx); } - func_80891320(this, globalCtx, 2); + EnNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); } } -// action func: swimming and flying away after swimming void EnNiw_Swimming(EnNiw* this, GlobalContext* globalCtx) { Vec3f ripplePos; @@ -520,73 +544,74 @@ void EnNiw_Swimming(EnNiw* this, GlobalContext* globalCtx) { } this->actor.speedXZ = 2.0f; - if (this->actor.bgCheckFlags & 0x20) { - // still touching water + if (this->actor.bgCheckFlags & 0x20) { // touching water this->actor.gravity = 0.0f; - if (this->actor.yDistToWater > 15.0f) { + if (this->actor.depthInWater > 15.0f) { this->actor.world.pos.y += 2.0f; } - if (this->unkTimer250 == 0) { - this->unkTimer250 = 30; + if (this->swimRippleTimer == 0) { + this->swimRippleTimer = 30; Math_Vec3f_Copy(&ripplePos, &this->actor.world.pos); - ripplePos.y += this->actor.yDistToWater; + ripplePos.y += this->actor.depthInWater; EffectSsGRipple_Spawn(globalCtx, &ripplePos, 100, 500, 30); } - if (this->actor.bgCheckFlags & 8) { - this->actor.velocity.y = 10.0f; + if (this->actor.bgCheckFlags & 8) { // hit a wall + this->actor.velocity.y = 10.0f; // fly up in straight line this->actor.speedXZ = 1.0f; } } else { this->actor.gravity = -2.0f; - if (this->actor.bgCheckFlags & 8) { - // has hit a wall - this->actor.velocity.y = 10.0f; // to the moon + if (this->actor.bgCheckFlags & 8) { // hit a wall + this->actor.velocity.y = 10.0f; // fly up in straight line this->actor.speedXZ = 1.0f; this->actor.gravity = 0.0f; } else { this->actor.speedXZ = 4.0f; } - if (this->actor.bgCheckFlags & 1) { + if (this->actor.bgCheckFlags & 1) { // hit floor this->actor.gravity = -2.0f; - this->unkTimer254 = 100; - this->unkTimer250 = 0; + this->runAwayTimer = 100; + this->swimRippleTimer = 0; this->actor.velocity.y = 0.0f; if (!this->isStormActive) { EnNiw_SetupRunAway(this); } else { - this->unknownState28E = 3; + this->niwState = NIW_STATE_ANGRY3; this->actionFunc = EnNiw_CuccoStorm; } } } - func_80891320(this, globalCtx, 2); + + EnNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); } void EnNiw_Trigger(EnNiw* this, GlobalContext* globalCtx) { - s32 value; + s32 state; + + // Possible Fake Match: the weird way this state is set if (1) { - value = 1; + state = NIW_STATE_ANGRY1; } - this->unkTimer252 = 10; - this->unknownState28E = this->unk29C = value; + this->cuccoStormTimer = 10; + this->niwState = this->nextAnimation = state; // NIW_ANIMATION_HEAD_PECKING this->actionFunc = EnNiw_Upset; } void EnNiw_Upset(EnNiw* this, GlobalContext* globalCtx) { // assumption: CuccoStorm is split into smaller parts because it used to be a cutscene in OOT this->sfxTimer1 = 100; - if (this->unkTimer252 == 0) { - this->unkTimer252 = 60; + if (this->cuccoStormTimer == 0) { + this->cuccoStormTimer = 60; this->unkTimer24C = 10; - this->unk29C = 4; - this->unknownState28E = 2; + this->nextAnimation = NIW_ANIMATION_FREEZE; + this->niwState = NIW_STATE_ANGRY2; this->actionFunc = EnNiw_SetupCuccoStorm; } - func_80891320(this, globalCtx, this->unk29C); + EnNiw_AnimateWingHead(this, globalCtx, this->nextAnimation); } // the long crow with head back before they descend @@ -594,44 +619,46 @@ void EnNiw_SetupCuccoStorm(EnNiw* this, GlobalContext* globalCtx) { f32 viewY; this->sfxTimer1 = 100; - if (this->unkTimer252 == 40) { + if (this->cuccoStormTimer == 40) { viewY = 14000.0f; - this->unk264[0] = 10000.0f; - this->unk264[7] = this->unk264[5] = viewY; - this->unk264[6] = 0.0f; - this->unk264[8] = 0.0f; - this->unk264[1] = 0.0f; - this->unk264[2] = 0.0f; + this->targetLimbRots[0] = 10000.0f; // body rot + this->targetLimbRots[7] = this->targetLimbRots[5] = viewY; + this->targetLimbRots[6] = 0.0f; + this->targetLimbRots[8] = 0.0f; + this->targetLimbRots[1] = 0.0f; + this->targetLimbRots[2] = 0.0f; this->unkTimer24C = 10; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); } - if (this->unkTimer252 == 0) { - this->unkTimer252 = 10; + + if (this->cuccoStormTimer == 0) { + this->cuccoStormTimer = 10; this->yawTowardsPlayer = this->actor.yawTowardsPlayer; - this->actor.flags &= ~0x1; // targetable OFF - this->unknownState28E = 3; + this->actor.flags &= ~ACTOR_FLAG_1; // targetable OFF + this->niwState = NIW_STATE_ANGRY3; this->actionFunc = EnNiw_CuccoStorm; } - func_80891320(this, globalCtx, this->unk29C); + + EnNiw_AnimateWingHead(this, globalCtx, this->nextAnimation); } void EnNiw_CuccoStorm(EnNiw* this, GlobalContext* globalCtx) { EnNiw_SpawnAttackNiw(this, globalCtx); - if (this->unkTimer252 == 1) { + if (this->cuccoStormTimer == 1) { // not countdown to 0? mistype? this->actor.speedXZ = 3.0f; - this->unk29A = Rand_ZeroFloat(1.99f); - this->unkTimer250 = 0; - this->unkTimer24E = this->unkTimer250; - this->unkTimer24C = this->unkTimer250; + this->isRunningRight = Rand_ZeroFloat(1.99f); + this->generalTimer1 = 0; + this->unkTimer24E = this->generalTimer1; + this->unkTimer24C = this->generalTimer1; } else { - func_808917F8(this, globalCtx, 1); + EnNiw_UpdateRunning(this, globalCtx, true); } } void EnNiw_SetupRunAway(EnNiw* this) { - Animation_Change(&this->skelanime, &D_060000E8, 1.0f, 0.0f, Animation_GetLastFrame(&D_060000E8), 0, -10.0f); - this->unk29A = Rand_ZeroFloat(1.99f); - this->unknownState28E = 7; + Animation_Change(&this->skelanime, &gNiwIdleAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gNiwIdleAnim), 0, -10.0f); + this->isRunningRight = Rand_ZeroFloat(1.99f); + this->niwState = NIW_STATE_RUNNING; this->actionFunc = EnNiw_RunAway; this->actor.speedXZ = 4.0f; } @@ -643,22 +670,21 @@ void EnNiw_RunAway(EnNiw* this, GlobalContext* globalCtx) { f32 dX; f32 dZ; - if (this->unkTimer254 == 0) { + if (this->runAwayTimer == 0) { this->unk2A4.x = this->unk2B0.x = this->actor.world.pos.x; this->unk2A4.y = this->unk2B0.y = this->actor.world.pos.y; this->unk2A4.z = this->unk2B0.z = this->actor.world.pos.z; - - this->unkTimer252 = this->unkTimer250 = this->unk298 = 0; + this->generalTimer2 = this->generalTimer1 = this->unk298 = 0; this->unk300 = this->unk304 = 0; - this->actor.speedXZ = 0; - - this->unk264[8] = 0; - this->unk264[6] = 0; - this->unk264[5] = 0; - this->unk264[7] = 0; + this->targetLimbRots[8] = 0; + this->targetLimbRots[6] = 0; + this->targetLimbRots[5] = 0; + this->targetLimbRots[7] = 0; Math_Vec3f_Copy(&this->unk2BC, &tempVec3f); + EnNiw_SetupIdle(this); + } else { if (this->unk2BC.x != 90000.0f) { dX = this->actor.world.pos.x - this->unk2BC.x; @@ -668,25 +694,27 @@ void EnNiw_RunAway(EnNiw* this, GlobalContext* globalCtx) { dZ = this->actor.world.pos.z - player->actor.world.pos.z; } this->yawTowardsPlayer = Math_Atan2S(dX, dZ); - func_808917F8(this, globalCtx, 0); - func_80891320(this, globalCtx, 2); + EnNiw_UpdateRunning(this, globalCtx, false); + EnNiw_AnimateWingHead(this, globalCtx, NIW_ANIMATION_PECKING_AND_WAVING); } } void EnNiw_LandBeforeIdle(EnNiw* this, GlobalContext* globalCtx) { - if (this->actor.bgCheckFlags & 1) { + if (this->actor.bgCheckFlags & 1) { // hit floor EnNiw_SetupIdle(this); } } void EnNiw_CheckRage(EnNiw* this, GlobalContext* globalCtx) { - if (!this->isStormActive && (this->unkTimer260 == 0) && (this->niwType == ENNIW_TYPE_REGULAR)) { - if ((this->unknownState28E != 7) && (this->unk2BC.x != 90000.0f)) { - this->unkTimer260 = 10; + if (!this->isStormActive && this->iframeTimer == 0 && this->niwType == NIW_TYPE_REGULAR) { + + // is this used? this is before we even know if we've been hit + if (this->niwState != NIW_STATE_RUNNING && this->unk2BC.x != 90000.0f) { + this->iframeTimer = 10; this->sfxTimer1 = 30; this->unk29E = 1; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow - this->unkTimer254 = 100; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + this->runAwayTimer = 100; this->unk2EC = 0; EnNiw_SetupRunAway(this); } @@ -698,32 +726,32 @@ void EnNiw_CheckRage(EnNiw* this, GlobalContext* globalCtx) { this->actor.colChkInfo.health--; } - if ((!D_80893460) && (this->actor.colChkInfo.health == 0)) { - // now you've done it - this->unkTimer254 = 100; - D_80893460 = true; + if (!sCuccoStormActive && this->actor.colChkInfo.health == 0) { + this->runAwayTimer = 100; // main cucco will run away after storm starts + sCuccoStormActive = true; this->unk298 = 0; this->sfxTimer1 = 10000; this->unk2A4.x = this->unk2B0.x = this->actor.world.pos.x; this->unk2A4.y = this->unk2B0.y = this->actor.world.pos.y; this->unk2A4.z = this->unk2B0.z = this->actor.world.pos.z; - this->unkTimer252 = this->unkTimer250 = this->unk298; + this->generalTimer2 = this->generalTimer1 = this->unk298; - this->unk264[8] = 0.0f; - this->unk264[6] = 0.0f; - this->unk264[5] = 0.0f; - this->unk264[7] = 0.0f; + this->targetLimbRots[8] = 0.0f; + this->targetLimbRots[6] = 0.0f; + this->targetLimbRots[5] = 0.0f; + this->targetLimbRots[7] = 0.0f; this->isStormActive = true; this->actionFunc = EnNiw_Trigger; this->unk304 = 0.0f; this->unk300 = 0.0f; this->actor.speedXZ = 0.0f; + } else { - this->unkTimer260 = 10; + this->iframeTimer = 10; this->sfxTimer1 = 30; this->unk29E = 1; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow - this->unkTimer254 = 100; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); // crow + this->runAwayTimer = 100; this->unk2EC = 0; EnNiw_SetupRunAway(this); } @@ -732,35 +760,34 @@ void EnNiw_CheckRage(EnNiw* this, GlobalContext* globalCtx) { } void EnNiw_Update(Actor* thisx, GlobalContext* globalCtx) { - EnNiw* this = (EnNiw*)thisx; + EnNiw* this = THIS; s8 pad0; s16 i; Player* player = GET_PLAYER(globalCtx); s16 pad1; s16 featherCount; Vec3f pos; - Vec3f spB8; - Vec3f spAC; - s32 pad2[9]; - s16 temp29C; + Vec3f vel; + Vec3f accel; + s32 pad2[10]; f32 featherScale; - f32 camResult; + f32 viewAtToEyeNormY; f32 floorHeight; f32 dist = 20.0f; s32 pad3; this->unusedCounter28C++; - if (this->niwType == ENNIW_TYPE_UNK1) { + if (this->niwType == NIW_TYPE_UNK1) { this->actor.shape.rot.y = this->actor.world.rot.y = this->actor.parent->shape.rot.y; } - if (this->unknownState28E != 0) { - this->unk264[9] = 0.0f; + if (this->niwState != NIW_STATE_IDLE) { + this->targetLimbRots[9] = 0.0f; // head rot } if (this->unk29E != 0) { - featherCount = ENNIW_FEATHERCOUNT; + featherCount = NIW_FEATHER_COUNT; if (this->unk29E == 2) { featherCount = 4; } @@ -770,20 +797,20 @@ void EnNiw_Update(Actor* thisx, GlobalContext* globalCtx) { pos.z = randPlusMinusPoint5Scaled(10.0f) + this->actor.world.pos.z; featherScale = Rand_ZeroFloat(6.0f) + 6.0f; - if ((this->unk29E == 2) && (this->unk308 != 0)) { + if (this->unk29E == 2 && this->unk308 != 0) { pos.y += 10.0f; } if (this->unk308 == 0) { featherScale = Rand_ZeroFloat(2.0f) + 2.0f; } - spB8.x = randPlusMinusPoint5Scaled(3.0f); - spB8.y = (Rand_ZeroFloat(2.0f) * 0.5f) + 2.0f; - spB8.z = randPlusMinusPoint5Scaled(3.0f); - spAC.z = spAC.x = 0.0f; - spAC.y = -0.15000000596f; + vel.x = randPlusMinusPoint5Scaled(3.0f); + vel.y = Rand_ZeroFloat(2.0f) * 0.5f + 2.0f; + vel.z = randPlusMinusPoint5Scaled(3.0f); + accel.z = accel.x = 0.0f; + accel.y = -0.15f; - EnNiw_SpawnFeather(this, &pos, &spB8, &spAC, featherScale); + EnNiw_SpawnFeather(this, &pos, &vel, &accel, featherScale); } this->unk29E = 0; } @@ -792,35 +819,37 @@ void EnNiw_Update(Actor* thisx, GlobalContext* globalCtx) { DECR(this->unkTimer24C); DECR(this->unkTimer24E); - DECR(this->unkTimer250); - DECR(this->unkTimer252); - DECR(this->unkTimer254); + DECR(this->generalTimer1); + DECR(this->generalTimer2); + DECR(this->runAwayTimer); DECR(this->sfxTimer1); DECR(this->flutterSfxTimer); DECR(this->unusedTimer25A); DECR(this->yawTimer); - DECR(this->unusedTimer25E); - DECR(this->unkTimer260); + DECR(this->unkAttackNiwTimer); + DECR(this->iframeTimer); this->actor.shape.rot = this->actor.world.rot; this->actor.shape.shadowScale = 15.0f; this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, this->unk308); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, this->unk308); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 0x1F); - if ((this->actor.floorHeight <= BGCHECK_Y_MIN) || (this->actor.floorHeight >= 32000.0f)) { - // if cucco is off the map? - Vec3f camera; - camera.x = globalCtx->view.at.x - globalCtx->view.eye.x; - camera.y = globalCtx->view.at.y - globalCtx->view.eye.y; - camera.z = globalCtx->view.at.z - globalCtx->view.eye.z; - camResult = camera.y / sqrtf(SQXYZ(camera)); + // if cucco is off the map + if (this->actor.floorHeight <= BGCHECK_Y_MIN || this->actor.floorHeight >= BGCHECK_Y_MAX) { + Vec3f viewAtToEye; + + // Direction vector for the direction the camera is facing + viewAtToEye.x = globalCtx->view.at.x - globalCtx->view.eye.x; + viewAtToEye.y = globalCtx->view.at.y - globalCtx->view.eye.y; + viewAtToEye.z = globalCtx->view.at.z - globalCtx->view.eye.z; + viewAtToEyeNormY = viewAtToEye.y / sqrtf(SQXYZ(viewAtToEye)); this->actor.world.pos.x = this->actor.home.pos.x; this->actor.world.pos.z = this->actor.home.pos.z; - this->actor.world.pos.y = (this->actor.home.pos.y + globalCtx->view.eye.y) + (camResult * 160.0f); + this->actor.world.pos.y = this->actor.home.pos.y + globalCtx->view.eye.y + (viewAtToEyeNormY * 160.0f); if (this->actor.world.pos.y < this->actor.home.pos.y) { this->actor.world.pos.y = this->actor.home.pos.y + 300.0f; @@ -833,113 +862,112 @@ void EnNiw_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk304 = 0.0f; this->unk300 = 0.0f; - this->unusedFloat2FC = 0.0f; + this->unusedFloat2FC = 0.0f; // assigned here but never used after this->unusedFloat2F8 = 0.0f; this->unusedFloat2F4 = 0.0f; - this->limbBRotx = 0.0f; - this->limbBRoty = 0.0f; - this->limbBRotz = 0.0f; - this->limb7Rotx = 0.0f; - this->limb7Roty = 0.0f; - this->limb7Rotz = 0.0f; - this->limbDRot = 0.0f; - this->limbFRot = 0.0f; + this->rightWingRotX = 0.0f; + this->rightWingRotY = 0.0f; + this->rightWingRotZ = 0.0f; + this->leftWingRotX = 0.0f; + this->leftWingRotY = 0.0f; + this->leftWingRotZ = 0.0f; + this->upperBodyRotY = 0.0f; + this->headRotY = 0.0f; // clang-format off - this->isStormActive = this->unusedCounter28C = this->unk292 = this->unk29E = this->unk298 = this->unk29A = this->unk29C = 0; + this->isStormActive = this->unusedCounter28C = this->unk292 = this->unk29E = this->unk298 = this->isRunningRight = this->nextAnimation = 0; // clang-format on for (i = 0; i < 10; i++) { - this->unk264[i] = 0.0f; + this->targetLimbRots[i] = 0.0f; } - this->unknownState28E = 8; + this->niwState = NIW_STATE_HOPPING; this->isStormActive = false; this->actionFunc = EnNiw_LandBeforeIdle; return; + } - } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.yDistToWater > 15.0f) && - (this->unknownState28E != 6)) { + if ((this->actor.bgCheckFlags & 0x20) && // touching water + this->actor.depthInWater > 15.0f && this->niwState != NIW_STATE_SWIMMING) { this->actor.velocity.y = 0.0f; this->actor.gravity = 0.0f; Math_Vec3f_Copy(&pos, &this->actor.world.pos); - pos.y += this->actor.yDistToWater; - this->unkTimer250 = 30; + pos.y += this->actor.depthInWater; + this->swimRippleTimer = 30; EffectSsGSplash_Spawn(globalCtx, &pos, 0, 0, 0, 400); - this->unkTimer252 = 0; - this->unknownState28E = 6; + this->generalTimer2 = 0; + this->niwState = NIW_STATE_SWIMMING; this->actionFunc = EnNiw_Swimming; + return; + } - } else { - if (this->isStormActive && (this->actor.xyzDistToPlayerSq < (SQ(dist))) && (player->invincibilityTimer == 0)) { - func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.world.rot.y, 0.0f, 0x10); + if (this->isStormActive && (this->actor.xyzDistToPlayerSq < SQ(dist)) && player->invincibilityTimer == 0) { + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.world.rot.y, 0.0f, 0x10); + } + + EnNiw_CheckRage(this, globalCtx); + if (this->flutterSfxTimer == 0 && this->niwState == NIW_STATE_HELD) { + this->flutterSfxTimer = 7; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_CHICKEN_FLUTTER); + } + + if (this->sfxTimer1 == 0) { + if (this->niwState != NIW_STATE_IDLE) { + this->sfxTimer1 = 30; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_A); + } else { + this->sfxTimer1 = 300; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_N); } + } - EnNiw_CheckRage(this, globalCtx); - if ((this->flutterSfxTimer == 0) && (this->unknownState28E == 4)) { - this->flutterSfxTimer = 7; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_CHICKEN_FLUTTER); - } + if (!this->isStormActive && this->niwType == NIW_TYPE_REGULAR) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (this->sfxTimer1 == 0) { - if (this->unknownState28E != 0) { - this->sfxTimer1 = 30; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_A); // attack cluck - } else { - this->sfxTimer1 = 300; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHICKEN_CRY_N); // cluck - } - } + if (globalCtx) {} - if (!this->isStormActive) { - if (this->niwType == ENNIW_TYPE_REGULAR) { - Collider_UpdateCylinder(&this->actor, &this->collider); - CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - - if (globalCtx) {} - - if ((this->unknownState28E != 4) && (this->unknownState28E != 5)) { - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - } - } + if (this->niwState != NIW_STATE_HELD && this->niwState != NIW_STATE_FALLING) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } } -s32 EnNiw_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { +s32 EnNiw_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { EnNiw* this = THIS; - if (limbIndex == 13) { - rot->y += (s16)this->limbDRot; + if (limbIndex == NIW_LIMB_UPPER_BODY) { + rot->y += (s16)this->upperBodyRotY; } - if (limbIndex == 15) { - rot->y += (s16)this->limbFRot; + if (limbIndex == NIW_LIMB_HEAD) { + rot->y += (s16)this->headRotY; } - if (limbIndex == 11) { - rot->x += (s16)this->limbBRotx; - rot->y += (s16)this->limbBRoty; - rot->z += (s16)this->limbBRotz; + if (limbIndex == NIW_LIMB_RIGHT_WING_ROOT) { + rot->x += (s16)this->rightWingRotX; + rot->y += (s16)this->rightWingRotY; + rot->z += (s16)this->rightWingRotZ; } - if (limbIndex == 7) { - rot->x += (s16)this->limb7Rotx; - rot->y += (s16)this->limb7Roty; - rot->z += (s16)this->limb7Rotz; + if (limbIndex == NIW_LIMB_LEFT_WING_ROOT) { + rot->x += (s16)this->leftWingRotX; + rot->y += (s16)this->leftWingRotY; + rot->z += (s16)this->leftWingRotZ; } - return 0; + return false; } void EnNiw_Draw(Actor* thisx, GlobalContext* globalCtx) { - EnNiw* this = (EnNiw*)thisx; + EnNiw* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawFlexOpa(globalCtx, this->skelanime.skeleton, this->skelanime.jointTable, this->skelanime.dListCount, - EnNiw_LimbDraw, NULL, &this->actor); + EnNiw_OverrideLimbDraw, NULL, &this->actor); EnNiw_DrawFeathers(this, globalCtx); } void EnNiw_SpawnFeather(EnNiw* this, Vec3f* pos, Vec3f* vel, Vec3f* accel, f32 scale) { s16 i; - EnNiwFeather* feather = this->feathers; + EnNiwFeather* feather = &this->feathers[0]; for (i = 0; i < ARRAY_COUNT(this->feathers); i++, feather++) { if (feather->isEnabled == false) { @@ -957,7 +985,7 @@ void EnNiw_SpawnFeather(EnNiw* this, Vec3f* pos, Vec3f* vel, Vec3f* accel, f32 s } void EnNiw_UpdateFeather(EnNiw* this, GlobalContext* globalCtx) { - EnNiwFeather* feather = this->feathers; + EnNiwFeather* feather = &this->feathers[0]; f32 featherVelocityGoal = 0.05f; s16 i; @@ -988,7 +1016,6 @@ void EnNiw_UpdateFeather(EnNiw* this, GlobalContext* globalCtx) { } } -// feather draw function void EnNiw_DrawFeathers(EnNiw* this, GlobalContext* globalCtx) { GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; u8 isMaterialApplied = false; @@ -1002,19 +1029,19 @@ void EnNiw_DrawFeathers(EnNiw* this, GlobalContext* globalCtx) { if (feather->isEnabled == true) { // Apply the feather material if it has not already been applied. if (!isMaterialApplied) { - gSPDisplayList(POLY_XLU_DISP++, D_060023B0); + gSPDisplayList(POLY_XLU_DISP++, gNiwFeatherMaterialDL); isMaterialApplied++; } - Matrix_InsertTranslation(feather->pos.x, feather->pos.y, feather->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_Translate(feather->pos.x, feather->pos.y, feather->pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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); + Matrix_RotateZF(feather->zRot, MTXMODE_APPLY); + Matrix_Translate(0.0f, -1000.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_06002428); + gSPDisplayList(POLY_XLU_DISP++, gNiwFeatherDL); } } diff --git a/src/overlays/actors/ovl_En_Niw/z_en_niw.h b/src/overlays/actors/ovl_En_Niw/z_en_niw.h index 5a03215bc..7c8b3e07e 100644 --- a/src/overlays/actors/ovl_En_Niw/z_en_niw.h +++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.h @@ -2,6 +2,7 @@ #define Z_EN_NIW_H #include "global.h" +#include "objects/object_niw/object_niw.h" struct EnNiw; @@ -19,55 +20,67 @@ typedef struct { /* 0x0034 */ u8 timer; } EnNiwFeather; // size = 0x38 -#define ENNIW_LIMBCOUNT 16 -#define ENNIW_FEATHERCOUNT 20 +#define NIW_FEATHER_COUNT 20 typedef struct EnNiw { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelanime; - /* 0x188 */ Vec3s jointTable[ENNIW_LIMBCOUNT]; - /* 0x1E8 */ Vec3s morphTable[ENNIW_LIMBCOUNT]; + /* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX]; /* 0x248 */ EnNiwActionFunc actionFunc; - /* 0x24C */ s16 unkTimer24C; + /* 0x24C */ s16 unkTimer24C; // set to 10, checked in mystery func /* 0x24E */ s16 unkTimer24E; - /* 0x250 */ s16 unkTimer250; - /* 0x252 */ s16 unkTimer252; - /* 0x254 */ s16 unkTimer254; + /* 0x250 */ union { + s16 generalTimer1; // default name for reset/decr + s16 hopTimer; // every 3 frames while running/idling + s16 swimRippleTimer; // how often swimming cucco spawns ripples + s16 heldTimer; // timer until updating unk29E + s16 unkIdleTimer; // not sure what _Idle is doing with it yet + }; + /* 0x252 */ union { + s16 generalTimer2; // default name for reset/decr + s16 hoppingTimer; // hopping after being thrown before running + s16 attackNiwSpawnTimer; // delay between re-attempting to spawn more attack_niw + s16 runningDirectionTimer; // delay between direction changes when running + s16 cuccoStormTimer; // delay between stages of summoning the storm + s16 unkIdleTimer2; // not sure what _Idle is doing with it yet + }; + /* 0x254 */ s16 runAwayTimer; /* 0x256 */ s16 sfxTimer1; /* 0x258 */ s16 flutterSfxTimer; /* 0x25A */ s16 unusedTimer25A; - /* 0x25C */ s16 yawTimer; // every 70 frames rechecks yawToPlayer - /* 0x25E */ s16 unusedTimer25E; - /* 0x260 */ s16 unkTimer260; - /* 0x264 */ f32 unk264[10]; + /* 0x25C */ s16 yawTimer; // every 70 frames rechecks yawToPlayer + /* 0x25E */ s16 unkAttackNiwTimer; // every 70 frames, updates some player unk values + /* 0x260 */ s16 iframeTimer; + /* 0x264 */ f32 targetLimbRots[10]; /* 0x28C */ s16 unusedCounter28C; - /* 0x28E */ s16 unknownState28E; - /* 0x290 */ s16 unk290; + /* 0x28E */ s16 niwState; + /* 0x290 */ s16 attackNiwCount; /* 0x292 */ s16 unk292; /* 0x294 */ s16 pad294; - /* 0x296 */ s16 unk296; + /* 0x296 */ s16 unkToggle296; /* 0x298 */ s16 unk298; - /* 0x29C */ s16 unk29A; - /* 0x29C */ u16 unk29C; - /* 0x29E */ s16 unk29E; - /* 0x2A0 */ s16 isStormActive; + /* 0x29C */ s16 isRunningRight; // toggle (direction cucco is turning while running) + /* 0x29C */ u16 nextAnimation; + /* 0x29E */ s16 unk29E; // three states 0/1/2 + /* 0x2A0 */ s16 isStormActive; // we have a data value shared between all cucco, this shouldn't need to exist /* 0x2A2 */ s16 niwType; /* 0x2A4 */ Vec3f unk2A4; /* 0x2B0 */ Vec3f unk2B0; - /* 0x2BC */ Vec3f unk2BC; - /* 0x2C8 */ f32 limb7Rotz; - /* 0x2CC */ f32 limb7Roty; - /* 0x2D0 */ f32 limb7Rotx; - /* 0x2D4 */ f32 limbBRotz; - /* 0x2D8 */ f32 limbBRoty; - /* 0x2DC */ f32 limbBRotx; - /* 0x2E0 */ f32 limbDRot; - /* 0x2E4 */ f32 limbFRot; + /* 0x2BC */ Vec3f unk2BC; // init from data (90000 on all three) + /* 0x2C8 */ f32 leftWingRotZ; + /* 0x2CC */ f32 leftWingRotY; + /* 0x2D0 */ f32 leftWingRotX; + /* 0x2D4 */ f32 rightWingRotZ; + /* 0x2D8 */ f32 rightWingRotY; + /* 0x2DC */ f32 rightWingRotX; + /* 0x2E0 */ f32 upperBodyRotY; + /* 0x2E4 */ f32 headRotY; /* 0x2E8 */ s16 yawTowardsPlayer; - /* 0x2EA */ s16 unk2EA; + /* 0x2EA */ s16 headRotationToggle; /* 0x2EC */ s16 unk2EC; /* 0x2EE */ UNK_TYPE1 pad2EE[0x6]; - /* 0x2F4 */ f32 unusedFloat2F4; + /* 0x2F4 */ f32 unusedFloat2F4; // set in EnNiw_Update if Cucco falls off map, never read /* 0x2F8 */ f32 unusedFloat2F8; /* 0x2FC */ f32 unusedFloat2FC; /* 0x300 */ f32 unk300; @@ -75,16 +88,26 @@ typedef struct EnNiw { /* 0x308 */ f32 unk308; /* 0x30C */ s32 pad30C; /* 0x310 */ ColliderCylinder collider; - /* 0x35C */ EnNiwFeather feathers[ENNIW_FEATHERCOUNT]; + /* 0x35C */ EnNiwFeather feathers[NIW_FEATHER_COUNT]; } EnNiw; // size = 0x7BC // in init, any value below zero becomes zero -// however, in vanilla, only 0xFFFF (-1) exists -#define ENNIW_TYPE_VANILLA 0xFFFF -#define ENNIW_TYPE_REGULAR 0 -#define ENNIW_TYPE_UNK1 1 -#define ENNIW_TYPE_UNK2 2 -// the attacking cuccos are not here, they are a different actor: -// ovl_En_Attack_Niw +// however, in vanilla, only 0xFFFF (-1) exists in scene spawns, actors can spawn 0x0 +#define NIW_TYPE_VANILLA 0xFFFF +#define NIW_TYPE_REGULAR 0 +#define NIW_TYPE_UNK1 1 +#define NIW_TYPE_HELD 2 // spawns held by the bomber kid in east clock town during hide and seek +// the attacking cuccos are not here, they are a different actor: [ ovl_En_Attack_Niw ] + +typedef enum { + /* 0 */ NIW_ANIMATION_STILL, + /* 1 */ NIW_ANIMATION_HEAD_PECKING, // forward and backward, feeding + /* 2 */ NIW_ANIMATION_PECKING_AND_WAVING, // wings move along their axis, like human hand waving + /* 3 */ NIW_ANIMATION_PECKING_AND_FORFLAPPING, // (unused) low (yaw based) flapping, forward and back + /* 4 */ NIW_ANIMATION_FREEZE, // used during Cucco Storm + /* 5 */ NIW_ANIMATION_PECKING_SLOW_FORFLAPPING, // wing speed half that of 3 + +} EnNiwHeadAndWingAnimationState; + #endif // Z_EN_NIW_H diff --git a/src/overlays/actors/ovl_En_Nnh/z_en_nnh.c b/src/overlays/actors/ovl_En_Nnh/z_en_nnh.c index 5ff712d7e..1400e3c06 100644 --- a/src/overlays/actors/ovl_En_Nnh/z_en_nnh.c +++ b/src/overlays/actors/ovl_En_Nnh/z_en_nnh.c @@ -1,6 +1,13 @@ -#include "z_en_nnh.h" +/* + * File: z_en_nnh.c + * Overlay: ovl_En_Nnh + * Description: Twisted Corpse of Deku Butler's Son + */ -#define FLAGS 0x00000019 +#include "z_en_nnh.h" +#include "objects/object_nnh/object_nnh.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnNnh*)thisx) @@ -46,8 +53,6 @@ static ColliderCylinderInit sCylinderInit = { { 20, 50, 0, { 0, 0, 0 } }, }; -extern Gfx D_06001510[]; - void EnNnh_Init(Actor* thisx, GlobalContext* globalCtx) { EnNnh* this = THIS; @@ -71,8 +76,8 @@ void func_80C08828(EnNnh* this) { } void func_80C0883C(EnNnh* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x228U, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x228U, &this->actor); func_80C088A4(this); return; } @@ -84,7 +89,7 @@ void func_80C088A4(EnNnh* this) { } void func_80C088B8(EnNnh* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { func_80C08828(this); } } @@ -104,5 +109,5 @@ void EnNnh_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(gfxCtx); gSPMatrix(gfxCtx->polyOpa.p++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gfxCtx->polyOpa.p++, D_06001510); + gSPDisplayList(gfxCtx->polyOpa.p++, object_nnh_DL_001510); } 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 b9aa32a0c..87100d17f 100644 --- a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c +++ b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c @@ -1,7 +1,14 @@ +/* + * File: z_en_nutsball.c + * Overlay: ovl_En_Nutsball + * Description: Deku nut Projectile + */ + #include "z_en_nutsball.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnNutsball*)thisx) @@ -47,7 +54,7 @@ static ColliderCylinderInit sCylinderInit = { void EnNutsball_Init(Actor* thisx, GlobalContext* globalCtx) { EnNutsball* this = THIS; - ActorShape_Init(&this->actor.shape, 400.0f, (ActorShadowFunc)func_800B3FC0, 13.0f); + ActorShape_Init(&this->actor.shape, 400.0f, ActorShadow_DrawCircle, 13.0f); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->actor.shape.rot.y = 0; this->actor.speedXZ = 10.0f; @@ -79,16 +86,15 @@ void EnNutsball_InitColliderParams(EnNutsball* this) { this->collider.info.toucher.damage = 2; } -void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { +void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; EnNutsball* this = THIS; - GlobalContext* globalCtx2 = globalCtx; - Player* player = GET_PLAYER(globalCtx); Vec3f worldPos; Vec3s worldRot; Vec3f spawnBurstPos; f32 spdXZ; - u32 bgId; + s32 bgId; CollisionPoly* poly; if (!(player->stateFlags1 & 0x300000C0)) { @@ -106,7 +112,7 @@ void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { if ((player->currentShield == PLAYER_SHIELD_HEROS_SHIELD) && (this->collider.base.atFlags & AT_HIT) && (this->collider.base.atFlags & AT_TYPE_ENEMY) && (this->collider.base.atFlags & AT_BOUNCED)) { EnNutsball_InitColliderParams(this); - func_8018219C(&player->shieldMf, &worldRot, 0); + Matrix_MtxFToYXZRot(&player->shieldMf, &worldRot, false); this->actor.world.rot.y = BINANG_ROT180(worldRot.y); this->timer = 20; } else { @@ -115,9 +121,9 @@ void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { spawnBurstPos.z = this->actor.world.pos.z; EffectSsHahen_SpawnBurst(globalCtx, &spawnBurstPos, 6.0f, 0, 7, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); if (this->actor.params == 1) { - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_NUTS_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_NUTS_BROKEN); } else { - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EN_OCTAROCK_ROCK); } Actor_MarkForDeath(&this->actor); } @@ -127,16 +133,16 @@ void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { } } - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); Math_Vec3f_Copy(&worldPos, &this->actor.world.pos); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 5.0f, 10.0f, 0x7); if (this->actor.bgCheckFlags & 8) { - if (func_800C9A4C(&globalCtx2->colCtx, this->actor.wallPoly, this->actor.wallBgId) & 0x30) { + if (func_800C9A4C(&globalCtx->colCtx, this->actor.wallPoly, this->actor.wallBgId) & 0x30) { this->actor.bgCheckFlags &= ~8; - if (func_800C55C4(&globalCtx2->colCtx, &this->actor.prevPos, &worldPos, &this->actor.world.pos, &poly, - 1, 0, 0, 1, &bgId)) { - if (func_800C9A4C(&globalCtx2->colCtx, poly, bgId) & 0x30) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.prevPos, &worldPos, &this->actor.world.pos, + &poly, true, false, false, true, &bgId)) { + if (func_800C9A4C(&globalCtx->colCtx, poly, bgId) & 0x30) { this->actor.world.pos.x += this->actor.velocity.x * 0.01f; this->actor.world.pos.z += this->actor.velocity.z * 0.01f; } else { @@ -149,13 +155,13 @@ void EnNutsball_Update(Actor* thisx, GlobalContext* globalCtx) { } Collider_UpdateCylinder(&this->actor, &this->collider); - this->actor.flags |= 0x1000000; + this->actor.flags |= ACTOR_FLAG_1000000; CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); if (this->timer < this->timerThreshold) { - CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx2->colChkCtx, &this->collider.base); } } } @@ -165,9 +171,9 @@ 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_InsertZRotation_s(this->actor.home.rot.z, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(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); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_058BA0); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c index 2d6e56e58..8d254b728 100644 --- a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c +++ b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.c @@ -1,6 +1,17 @@ -#include "z_en_nwc.h" +/* + * File: z_en_nwc.c + * Overlay: ovl_En_Nwc + * Description: Cucco chick + * + * This actor requires object_niw to be present for the transformation during Breman Mask March + * EnHs (Grog) must also be present to maintain the count of the EnNwc in the march + */ -#define FLAGS 0x00000010 +#include "z_en_nwc.h" +#include "overlays/actors/ovl_En_Niw/z_en_niw.h" +#include "objects/object_nwc/object_nwc.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnNwc*)thisx) @@ -9,15 +20,27 @@ void EnNwc_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnNwc_Update(Actor* thisx, GlobalContext* globalCtx); void EnNwc_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809448A4(EnNwc* this, GlobalContext* globalCtx); -void func_809449D0(EnNwc* this, GlobalContext* globalCtx); -void func_80944A50(EnNwc* this, GlobalContext* globalCtx); -void func_80944E44(EnNwc* this, GlobalContext* globalCtx); -void func_80944EFC(EnNwc* this, GlobalContext* globalCtx); -void func_80944FA8(EnNwc* this, GlobalContext* globalCtx); -void func_8094506C(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_LoadNiwSkeleton(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_CrowAtTheEnd(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_Follow(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_HopForward(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_RunAway(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_Turn(EnNwc* this, GlobalContext* globalCtx); +void EnNwc_CheckForBreman(EnNwc* this, GlobalContext* globalCtx); + +void EnNwc_DrawAdultBody(Actor* thisx, GlobalContext* globalCtx); +s32 EnNwc_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx); +EnHs* EnNwc_FindGrog(GlobalContext* globalCtx); + +enum EnNiwState { + /* -1 */ NWC_STATE_NIW_LOADED = -1, // set after loading object_niw + /* 0 */ NWC_STATE_CHECK_BREMAN = 0, // checking for breman mask + /* 1 */ NWC_STATE_TURNING, // turning to face a new direction to explore + /* 2 */ NWC_STATE_HOPPING_FORWARD, // hopping to go explore + /* 3 */ NWC_STATE_FOLLOWING, // following the player + /* 4 */ NWC_STATE_RUNNING, // running from the player after failed breman march +}; -#if 0 const ActorInit En_Nwc_InitVars = { ACTOR_EN_NWC, ACTORCAT_PROP, @@ -30,47 +53,474 @@ const ActorInit En_Nwc_InitVars = { (ActorFunc)EnNwc_Draw, }; -#endif +Color_RGBA8 sPrimColor = { 255, 255, 255, 255 }; -extern UNK_TYPE D_060000E8; -extern UNK_TYPE D_060002E8; +Color_RGBA8 sEnvColor = { 80, 80, 80, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Init.s") +void EnNwc_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 niwObjectIndex; + EnNwc* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Destroy.s") + niwObjectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_NIW); + if (niwObjectIndex < 0) { + // niw object does not exist, we need it for tranformation, despawn + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944320.s") + if (gSaveContext.save.weekEventReg[25] & 8) { + // if breman mask was already used, replace with adult EnNiw + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_NIW, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, NIW_TYPE_REGULAR); + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944554.s") + this->niwObjectIndex = niwObjectIndex; + this->nwcObjectIndex = this->actor.objBankIndex; + this->grog = EnNwc_FindGrog(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944590.s") + this->footRotY = this->footRotZ = 0; + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = EnNwc_LoadNiwSkeleton; + this->hasGrownUp = false; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 6.0f); + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809445D4.s") +void EnNwc_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnNwc* this = THIS; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944630.s") +void EnNwc_SpawnDust(EnNwc* this, GlobalContext* globalCtx) { + Vec3f pos; + Vec3f vec5; + Vec3f vel; + Vec3f accel; + s16 yaw; + s16 pitch; + Vec3f eye = GET_ACTIVE_CAM(globalCtx)->eye; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809447A8.s") + yaw = Math_Vec3f_Yaw(&eye, &this->actor.world.pos); + pitch = -Math_Vec3f_Pitch(&eye, &this->actor.world.pos); + vec5.x = this->actor.world.pos.x - 5.0f * Math_SinS(yaw) * Math_CosS(pitch); + vec5.y = this->actor.world.pos.y - 5.0f * Math_SinS(pitch); + vec5.z = this->actor.world.pos.z - 5.0f * Math_CosS(yaw) * Math_CosS(pitch); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944818.s") + for (i = 0; i < 5; i++) { + vel.x = randPlusMinusPoint5Scaled(4.0f); + vel.y = randPlusMinusPoint5Scaled(4.0f); + vel.z = randPlusMinusPoint5Scaled(4.0f); + accel.x = -vel.x * 0.1f; + accel.y = -vel.y * 0.1f; + accel.z = -vel.z * 0.1f; + pos.x = vec5.x + vel.x; + pos.y = vec5.y + vel.y; + pos.z = vec5.z + vel.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809448A4.s") + func_800B0F80(globalCtx, &pos, &vel, &accel, &sPrimColor, &sEnvColor, 300, 30, 10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_809449D0.s") +EnHs* EnNwc_FindGrog(GlobalContext* globalCtx) { + Actor* grogSearch = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944A50.s") + while (grogSearch != NULL) { + if (grogSearch->id == ACTOR_EN_HS) { + return (EnHs*)grogSearch; + } + grogSearch = grogSearch->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944E44.s") + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944EFC.s") +s32 EnNwc_PlayerReleasedBremanMarch(EnNwc* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80944FA8.s") + // Weird: home.rot.x holds count of chicks having transformed into adult. + // Weird: Its incremented by 1 unlike chicks following, so it should max at 10. + if (this->grog->actor.home.rot.x >= 20) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_8094506C.s") + if (player->stateFlags3 & 0x20000000) { // breman mask march + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Update.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/EnNwc_Draw.s") +/** + * Summary: Checks 1) if grog exists, 2) player is using breman mask, 3) and within range. + * Used to identify if the chick should be captured by breman mask. + */ +s32 EnNwc_IsFound(EnNwc* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_8094529C.s") + if (this->grog == NULL) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Nwc/func_80945310.s") + if (player->stateFlags3 & 0x20000000 && // breman mask march + this->actor.xzDistToPlayer < 100.0f) { + return true; + } + + return false; +} + +void EnNwc_ChangeState(EnNwc* this, s16 newState) { + this->actor.speedXZ = 0.0f; + switch (newState) { + case NWC_STATE_CHECK_BREMAN: + this->stateTimer = 10; + this->actionFunc = EnNwc_CheckForBreman; + break; + case NWC_STATE_TURNING: + this->stateTimer = Rand_ZeroFloat(20.0f) + 15.0f; + this->actionFunc = EnNwc_Turn; + this->fallingRotY = (s16)(s32)randPlusMinusPoint5Scaled(65536.0f); + break; + case NWC_STATE_HOPPING_FORWARD: + this->stateTimer = Rand_ZeroFloat(20.0f) + 15.0f; + this->actionFunc = EnNwc_HopForward; + break; + case NWC_STATE_FOLLOWING: + this->actionFunc = EnNwc_Follow; + this->transformTimer = 0; + this->randomRot = (s16)(s32)randPlusMinusPoint5Scaled(10000.0f); + break; + case NWC_STATE_RUNNING: + this->actor.world.rot.y = this->actor.home.rot.z * 0x3000 & 0xFFFF; // Fake Match?: & 0xFFFF + this->actor.shape.rot.y = this->actor.world.rot.y; + this->stateTimer = Rand_ZeroFloat(40.0f) + 120.0f; + this->actionFunc = EnNwc_RunAway; + break; + } + + this->state = newState; +} + +/** + * Summary: Changes the current actor state + * If previously random behavior -> check if breman mask is active + * If previously checking for breman -> select random (NWC_STATE_TURNING, NWC_STATE_HOPPING_FORWARD) + */ +void EnNwc_ToggleState(EnNwc* this) { + this->actor.speedXZ = 0.0f; + if (this->state != NWC_STATE_CHECK_BREMAN) { + EnNwc_ChangeState(this, NWC_STATE_CHECK_BREMAN); + } else { + EnNwc_ChangeState(this, Rand_ZeroFloat(2.0f) + 1.0f); + } +} + +void EnNwc_CheckFound(EnNwc* this, GlobalContext* globalCtx) { + if (EnNwc_IsFound(this, globalCtx)) { + u8 currentChickCount = (this->grog->actor.home.rot.z / 2); + + if (currentChickCount > 9) { + currentChickCount = 9; + } + + // save our current chick order + this->actor.home.rot.z = this->grog->actor.home.rot.z + 1; + + // if < 10 chicks, increment grog's chick counter + if (this->grog->actor.home.rot.z < 20) { + this->grog->actor.home.rot.z += 2; + } + + EnNwc_ChangeState(this, NWC_STATE_FOLLOWING); + func_801A0868(&D_801DB4A4, NA_SE_SY_CHICK_JOIN_CHIME, currentChickCount); + } +} + +void EnNwc_LoadNiwSkeleton(EnNwc* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->niwObjectIndex)) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->niwObjectIndex].segment); + + SkelAnime_InitFlex(globalCtx, &this->niwSkeleton, &gNiwSkeleton, &gNiwIdleAnim, this->jointTable, + this->morphTable, NIW_LIMB_MAX); + Animation_Change(&this->niwSkeleton, &gNiwIdleAnim, 1.0f, 0.0f, Animation_GetLastFrame(&gNiwIdleAnim), 0, 0.0f); + + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->nwcObjectIndex].segment); + this->state = NWC_STATE_NIW_LOADED; + EnNwc_ToggleState(this); + } +} + +void EnNwc_CrowAtTheEnd(EnNwc* this, GlobalContext* globalCtx) { + // I guess grog handles the scene transit? + Math_SmoothStepToS(&this->upperBodyRotY, 0x2710, 2, 0x1B58, 0x3E8); + Math_SmoothStepToS(&this->footRotZ, 0, 2, 0x1B58, 0x3E8); + Math_SmoothStepToS(&this->footRotY, 0x36B0, 2, 0x1B58, 0x3E8); +} + +/** + * Summary: Controls the Chick when following Breman Mask. + * + * ActionFunc for NWC Type: NWC_STATE_FOLLOWING + */ +void EnNwc_Follow(EnNwc* this, GlobalContext* globalCtx) { + Vec3f* chickCoords = this->grog->nwcPos; + Vec3f targetVector; + s32 pad; + s16 newRotY; + + this->stateTimer++; + if (this->hasGrownUp & 1) { + s16 targetUpperBodyRot = 0; + s16 targetFootRot = 0; + + if (this->actor.speedXZ > 0.0f) { + if (this->stateTimer & 4) { + targetFootRot = 0x1B58; + targetUpperBodyRot = -0x2710; + } + if ((this->stateTimer & 3) == 3) { + this->actor.velocity.y = 2.0f; // hop up and down + } + } + Math_SmoothStepToS(&this->footRotZ, targetFootRot, 2, 0x1B58, 0x3E8); + Math_SmoothStepToS(&this->upperBodyRotY, targetUpperBodyRot, 2, 0x1B58, 0x3E8); + + } else { // NOT grown up + if ((this->stateTimer & 3) == 3 && this->stateTimer & 20) { + this->actor.velocity.y = 2.0f; // hop up and down + } + if ((this->stateTimer & 0x1B) == 24) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG); + } + } + + if (this->grog->actor.home.rot.z >= 20 && // all 10 chicks have been found + (this->hasGrownUp & 1) == false) { + this->transformTimer += 2; + if (this->transformTimer >= (s32)(s16)((this->actor.home.rot.z * 0x1E) + 0x1E)) { + // it is our turn to transform + this->hasGrownUp |= 1; + this->grog->actor.home.rot.x += 2; // increment grog's adult tranformation counter + EnNwc_SpawnDust(this, globalCtx); + Actor_SetScale(&this->actor, 0.002f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_TO_CHICKEN); + } + } + + Math_Vec3f_Diff(&chickCoords[this->actor.home.rot.z], &this->actor.world.pos, &targetVector); + if (SQXZ(targetVector) < SQ(5.0f)) { // too close to keep moving, stop + this->actor.speedXZ = 0.0f; + + // first nwc in the line follows player, the rest follow the previous one + if (this->actor.home.rot.z == 1) { + newRotY = this->actor.yawTowardsPlayer; + } else { + // for some reason the array is 10 * 2, incremented by 2, so this is "index - 1" + newRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &chickCoords[this->actor.home.rot.z - 2]); + } + + } else { // not too close: keep moving + this->randomRot += (s16)randPlusMinusPoint5Scaled(1500.0f); + if (this->randomRot > 0x1388) { + this->randomRot = 0x1388; + } else if (this->randomRot < -0x1388) { + this->randomRot = -0x1388; + } + this->actor.speedXZ = 2.0f; + newRotY = Math_Vec3f_Yaw(&this->actor.world.pos, &chickCoords[this->actor.home.rot.z]) + this->randomRot; + } + + this->actor.world.rot.y = newRotY; + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 2, 0xBB8, 0xC8); + + if (EnNwc_PlayerReleasedBremanMarch(this, globalCtx)) { + this->grog->actor.home.rot.x = 0; // reset adult count + this->grog->actor.home.rot.z = 0; // reset chick follow count + + EnNwc_ChangeState(this, NWC_STATE_RUNNING); + + if (this->hasGrownUp & 1) { + EnNwc_SpawnDust(this, globalCtx); + } + + this->hasGrownUp &= ~1; + Actor_SetScale(&this->actor, 0.01f); + } + + if (this->actor.scale.x < 0.01f) { + this->actor.scale.x += 0.002f; + Actor_SetScale(&this->actor, this->actor.scale.x); + } + + if (this->grog->actor.home.rot.x >= 20) { // all chicks have turned into adult cucco, stop and crow + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICKEN_CRY_M); + this->actionFunc = EnNwc_CrowAtTheEnd; + this->actor.speedXZ = 0.0f; + Actor_SetScale(&this->actor, 0.01f); + } +} + +/** + * Summary: Chick is Walking (Hopping) in a straight line. + * + * ActionFunc for NWC Type: NWC_STATE_HOPPING_FORWARD + */ +void EnNwc_HopForward(EnNwc* this, GlobalContext* globalCtx) { + if (DECR(this->stateTimer) == 0) { + EnNwc_ToggleState(this); + return; + } + + if ((this->stateTimer & 3) == 3) { + this->actor.velocity.y = 2.0f; // hop up and down + } + if ((this->stateTimer & 0xB) == 8) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG); + } + + // they only move forward while off the ground, which gives the visual of them hopping to move + if (this->actor.bgCheckFlags & 0x1) { // touching floor + this->actor.speedXZ = 0.0f; + } else { + this->actor.speedXZ = 2.0f; + } +} + +/** + * Summary: Chick is Running Away from player (Breman Mask was dropped). + * + * ActionFunc for NWC Type: NWC_STATE_RUNNING + */ +void EnNwc_RunAway(EnNwc* this, GlobalContext* globalCtx) { + if (DECR(this->stateTimer) == 0) { + EnNwc_ToggleState(this); + return; + } + + if ((this->stateTimer & 3) == 3) { + this->actor.velocity.y = 2.0f; // hop up and down + } + if ((this->stateTimer & 0xB) == 8) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG); + } + + this->actor.speedXZ = 2.0f; + if (this->actor.bgCheckFlags & 0x8) { // touching wall + EnNwc_ToggleState(this); + } +} + +/** + * Summary: Chick is turning to face a new direction. + * + * ActionFunc for NWC Type: NWC_STATE_TURNING + */ +void EnNwc_Turn(EnNwc* this, GlobalContext* globalCtx) { + if (DECR(this->stateTimer) == 0) { + EnNwc_ToggleState(this); + return; + } + + if ((this->stateTimer & 7) == 7) { + this->actor.velocity.y = 2.0f; // vertical hop + } + + if ((this->stateTimer & 0xB) == 8) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CHICK_SONG); + } + + // they only rotate when off the ground, giving the visual that they turn by hopping + if (!(this->actor.bgCheckFlags & 0x1)) { // NOT touching floor + Math_SmoothStepToS(&this->actor.shape.rot.y, this->fallingRotY, 0xA, 0x1000, 0x800); + this->actor.world.rot.y = this->actor.shape.rot.y; + } +} + +/** + * Summary: Chick is standing still. + * Looking around, can see the player with the Breman Mask + * + * ActionFunc for NWC Type: NWC_STATE_CHECK_BREMAN + */ +void EnNwc_CheckForBreman(EnNwc* this, GlobalContext* globalCtx) { + if (DECR(this->stateTimer) == 0) { + EnNwc_ToggleState(this); + } + + EnNwc_CheckFound(this, globalCtx); +} + +void EnNwc_Update(Actor* thisx, GlobalContext* globalCtx) { + EnNwc* this = THIS; + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 5); + this->actionFunc(this, globalCtx); + if (this->hasGrownUp & 1) { + this->actor.objBankIndex = this->niwObjectIndex; + this->actor.draw = EnNwc_DrawAdultBody; + this->actor.shape.shadowScale = 15.0f; + } else { + this->actor.objBankIndex = this->nwcObjectIndex; + this->actor.draw = EnNwc_Draw; + this->actor.shape.shadowScale = 6.0f; + } + + if (DECR(this->blinkTimer) == 0) { + this->blinkTimer = Rand_S16Offset(0x3C, 0x3C); + } + + if (this->blinkTimer == 1 || this->blinkTimer == 3) { + this->blinkState = true; + } else { + this->blinkState = false; + } +} + +void EnNwc_Draw(Actor* thisx, GlobalContext* globalCtx) { + TexturePtr eyeTextures[] = { gNwcEyeOpenTex, gNwcEyeClosedTex }; + EnNwc* this = THIS; + Gfx* dispHead; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + dispHead = POLY_OPA_DISP; + + gSPSegment(&dispHead[0], 0x08, Lib_SegmentedToVirtual(eyeTextures[this->blinkState])); + + gSPMatrix(&dispHead[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(&dispHead[2], &gNwcBodyDL); + + POLY_OPA_DISP = &dispHead[3]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 EnNwc_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnNwc* this = THIS; + + if (limbIndex == NIW_LIMB_UPPER_BODY) { + rot->y += this->upperBodyRotY; + } + if (limbIndex == NIW_LIMB_RIGHT_WING_ROOT || limbIndex == NIW_LIMB_LEFT_WING_ROOT) { + rot->y += this->footRotY; + rot->z += this->footRotZ; + } + + return false; +} + +void EnNwc_DrawAdultBody(Actor* thisx, GlobalContext* globalCtx) { + EnNwc* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->niwSkeleton.skeleton, this->niwSkeleton.jointTable, + this->niwSkeleton.dListCount, EnNwc_OverrideLimbDraw, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h index ccdfb59bb..3815852af 100644 --- a/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h +++ b/src/overlays/actors/ovl_En_Nwc/z_en_nwc.h @@ -2,15 +2,37 @@ #define Z_EN_NWC_H #include "global.h" +#include "objects/object_niw/object_niw.h" +#include "overlays/actors/ovl_En_Hs/z_en_hs.h" // grog + struct EnNwc; typedef void (*EnNwcActionFunc)(struct EnNwc*, GlobalContext*); typedef struct EnNwc { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x120]; - /* 0x0264 */ EnNwcActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime niwSkeleton; // this skeleton is for when the chicks grow up into adults during the breman march + /* 0x188 */ Vec3s jointTable[NIW_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[NIW_LIMB_MAX]; + /* 0x248 */ s8 niwObjectIndex; + /* 0x249 */ s8 nwcObjectIndex; + /* 0x24A */ s16 blinkState; + /* 0x24C */ s16 blinkTimer; + /* 0x250 */ EnHs* grog; + /* 0x254 */ s16 stateTimer; // count frames to next state change + /* 0x256 */ union { + s16 mixedValue256; // default name for reset + s16 transformTimer; // frames since transformation sequence started + s16 fallingRotY; // target rotation if off the ground in state 1 + }; + /* 0x258 */ s16 randomRot; + /* 0x25A */ s16 state; + /* 0x25C */ u16 hasGrownUp; // treated as both a boolean and a flag variable (0x1) + /* 0x25E */ s16 footRotY; + /* 0x260 */ s16 footRotZ; + /* 0x262 */ s16 upperBodyRotY; + /* 0x264 */ EnNwcActionFunc actionFunc; } EnNwc; // size = 0x268 extern const ActorInit En_Nwc_InitVars; 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 4ae96bafb..c87e30329 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,6 +1,12 @@ +/* + * File: z_en_okarina_effect.c + * Overlay: ovl_En_Okarina_Effect + * Description: Manages the storm created when playing Song of Storms + */ + #include "z_en_okarina_effect.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnOkarinaEffect*)thisx) @@ -52,7 +58,7 @@ void func_8096B104(EnOkarinaEffect* this, GlobalContext* globalCtx) { void func_8096B174(EnOkarinaEffect* this, GlobalContext* globalCtx) { DECR(this->unk144); if (!globalCtx->pauseCtx.state && !globalCtx->gameOverCtx.state && !globalCtx->msgCtx.unk11F10 && - !FrameAdvance_IsEnabled(globalCtx) && this->unk144 == 0) { + !FrameAdvance_IsEnabled(&globalCtx->state) && this->unk144 == 0) { EnOkarinaEffect_SetupAction(this, func_8096B1FC); } } diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c index 606f723e2..5a54da7b1 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.c @@ -1,6 +1,12 @@ +/* + * File: z_en_okarina_tag.c + * Overlay: ovl_En_Okarina_Tag + * Description: + */ + #include "z_en_okarina_tag.h" -#define FLAGS 0x0A000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000 | ACTOR_FLAG_8000000) #define THIS ((EnOkarinaTag*)thisx) 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_Okuta/z_en_okuta.c b/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c index 2ccb7c91b..b11997b82 100644 --- a/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c +++ b/src/overlays/actors/ovl_En_Okuta/z_en_okuta.c @@ -1,6 +1,12 @@ +/* + * File: z_en_okuta.c + * Overlay: ovl_En_Okuta + * Description: Octorok + */ + #include "z_en_okuta.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnOkuta*)thisx) 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 feddfb17a..c904cdd42 100644 --- a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c +++ b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c @@ -1,6 +1,12 @@ +/* + * File: z_en_onpuman.c + * Overlay: ovl_En_Onpuman + * Description: Monkey Instrument Prompt (unused) + */ + #include "z_en_onpuman.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnOnpuman*)thisx) diff --git a/src/overlays/actors/ovl_En_Osk/z_en_osk.c b/src/overlays/actors/ovl_En_Osk/z_en_osk.c index 3c88c3b0a..20c0dd19d 100644 --- a/src/overlays/actors/ovl_En_Osk/z_en_osk.c +++ b/src/overlays/actors/ovl_En_Osk/z_en_osk.c @@ -1,6 +1,14 @@ -#include "z_en_osk.h" +/* + * File: z_en_osk.c + * Overlay: ovl_En_Osk + * Description: Igos du Ikana's and his lackey's floating heads + */ -#define FLAGS 0x00000009 +#include "z_en_osk.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_ikn_demo/object_ikn_demo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnOsk*)thisx) @@ -14,7 +22,6 @@ void func_80BF61EC(EnOsk* this, GlobalContext* globalCtx); void func_80BF656C(EnOsk* this, GlobalContext* globalCtx); void func_80BF6A20(EnOsk* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Osk_InitVars = { ACTOR_EN_OSK, ACTORCAT_NPC, @@ -27,42 +34,533 @@ const ActorInit En_Osk_InitVars = { (ActorFunc)EnOsk_Draw, }; -#endif +AnimationHeader* D_80BF6FA0[] = { + &object_ikn_demo_Anim_003CAC, &object_ikn_demo_Anim_004208, &object_ikn_demo_Anim_004514, + &object_ikn_demo_Anim_004A58, &object_ikn_demo_Anim_0065D8, +}; -extern UNK_TYPE D_06006808; +AnimationHeader* D_80BF6FB4[] = { + &object_ikn_demo_Anim_0067B8, &object_ikn_demo_Anim_0083F4, &object_ikn_demo_Anim_0081A8, + &object_ikn_demo_Anim_008AF4, &object_ikn_demo_Anim_008724, &object_ikn_demo_Anim_008F1C, + &object_ikn_demo_Anim_008CEC, &object_ikn_demo_Anim_009254, &object_ikn_demo_Anim_009044, + &object_ikn_demo_Anim_0098E4, &object_ikn_demo_Anim_009CC8, &object_ikn_demo_Anim_009A44, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/EnOsk_Init.s") +AnimationHeader* D_80BF6FE4[] = { + &object_ikn_demo_Anim_009EA8, &object_ikn_demo_Anim_00B8C0, &object_ikn_demo_Anim_00B704, + &object_ikn_demo_Anim_00BDB4, &object_ikn_demo_Anim_00B9E4, &object_ikn_demo_Anim_00C154, + &object_ikn_demo_Anim_00BF04, &object_ikn_demo_Anim_00CA74, &object_ikn_demo_Anim_00C804, + &object_ikn_demo_Anim_00D044, &object_ikn_demo_Anim_00CD28, &object_ikn_demo_Anim_00C59C, + &object_ikn_demo_Anim_00C2C4, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/EnOsk_Destroy.s") +Vec3f D_80BF7018 = { 0.0f, 0.5f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF5E00.s") +Vec3f D_80BF7024 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF5E68.s") +void EnOsk_Init(Actor* thisx, GlobalContext* globalCtx) { + EnOsk* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF5EBC.s") + Actor_SetScale(&this->actor, 0.013f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF5F60.s") + this->actionFunc = func_80BF5F60; + this->unk_254 = -1; + this->unk_256 = -1; + this->actor.flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF5F70.s") + switch (ENOSK_GET_F(&this->actor)) { + case ENOSK_1: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ikn_demo_Skel_007B48, &object_ikn_demo_Anim_006808, + this->jointTable, this->morphTable, 7); + Animation_PlayLoop(&this->skelAnime, &object_ikn_demo_Anim_006808); + this->actionFunc = func_80BF656C; + this->unk_258 = 0x210; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF609C.s") + case ENOSK_2: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ikn_demo_Skel_00B490, &object_ikn_demo_Anim_009F00, + this->jointTable, this->morphTable, 7); + Animation_PlayLoop(&this->skelAnime, &object_ikn_demo_Anim_006808); + this->actionFunc = func_80BF6A20; + this->unk_258 = 0x211; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF61EC.s") + default: + Actor_SetScale(&this->actor, 0.017f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ikn_demo_Skel_0038F0, &object_ikn_demo_Anim_0000B8, + this->jointTable, this->morphTable, 17); + Animation_PlayLoop(&this->skelAnime, &object_ikn_demo_Anim_0000B8); + this->actionFunc = func_80BF61EC; + this->unk_258 = 0x212; + this->actor.home.rot.z = 0; + this->unk_25C = 0.0f; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF6314.s") +void EnOsk_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF6478.s") +void func_80BF5E00(EnOsk* this, AnimationHeader** animations, s16 index, f32 morphFrame) { + if (index == this->unk_254) { + return; + } + Animation_MorphToLoop(&this->skelAnime, animations[index], morphFrame); + this->unk_254 = index; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF656C.s") +void func_80BF5E68(EnOsk* this, AnimationHeader** animations, s16 index, f32 playSpeed) { + Animation_MorphToPlayOnce(&this->skelAnime, animations[index], playSpeed); + this->unk_254 = index; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF67A8.s") +void func_80BF5EBC(EnOsk* this, GlobalContext* globalCtx) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF68E0.s") + sp2C.x = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.x; + sp2C.z = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.z; + sp2C.y = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF6A20.s") + func_800B3030(globalCtx, &sp2C, &D_80BF7018, &D_80BF7018, 100, 0, 2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/EnOsk_Update.s") +void func_80BF5F60(EnOsk* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/func_80BF6C54.s") +void func_80BF5F70(EnOsk* this) { + if ((this->unk_256 != 1) && (this->unk_256 != 6)) { + this->actor.draw = EnOsk_Draw; + Actor_SetScale(&this->actor, 0.017f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osk/EnOsk_Draw.s") + switch (this->unk_256) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + func_80BF5E00(this, D_80BF6FA0, 3, -5.0f); + break; + + case 3: + func_80BF5E00(this, D_80BF6FA0, 2, -5.0f); + break; + + case 4: + func_80BF5E00(this, D_80BF6FA0, 1, -5.0f); + break; + + case 5: + func_80BF5E00(this, D_80BF6FA0, 0, -5.0f); + break; + + case 6: + func_80BF5E00(this, D_80BF6FA0, 1, -5.0f); + break; + + case 7: + func_80BF5E00(this, D_80BF6FA0, 4, -5.0f); + this->actor.home.rot.z = 1; + break; + } +} + +void func_80BF609C(EnOsk* this, GlobalContext* globalCtx) { + if (this->actor.draw != NULL) { + if (this->actor.home.rot.z != 0) { + if (globalCtx->msgCtx.currentTextId == 0x1531) { + this->actor.home.rot.z = 0; + } + } else { + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + this->unk_25C = Rand_ZeroFloat(3.0f); + } + + switch (this->unk_254) { + case 0: + if (Animation_OnFrame(&this->skelAnime, this->unk_25C) || + Animation_OnFrame(&this->skelAnime, this->unk_25C + 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOSU_TALK); + } + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->unk_25C)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOSU_TALK); + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->unk_25C) || + Animation_OnFrame(&this->skelAnime, this->unk_25C + 6.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOSU_TALK); + } + break; + } + } + } +} + +void func_80BF61EC(EnOsk* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Cutscene_CheckActorAction(globalCtx, this->unk_258)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, this->unk_258)); + if (this->unk_256 != + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action) { + this->unk_256 = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action; + func_80BF5F70(this); + } + func_80BF609C(this, globalCtx); + } else { + this->actor.draw = NULL; + } + + if (this->unk_256 == 6) { + if (this->actor.scale.x > 0.85f * 0.001f) { + this->actor.scale.x -= 0.85f * 0.001f; + Actor_SetScale(&this->actor, this->actor.scale.x); + func_80BF5EBC(this, globalCtx); + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } else { + this->actor.draw = NULL; + } + } +} + +void func_80BF6314(EnOsk* this) { + if ((this->unk_256 != 1) && (this->unk_256 != 9)) { + this->actor.draw = EnOsk_Draw; + Actor_SetScale(&this->actor, 0.013f); + } + + switch (this->unk_256) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + func_80BF5E00(this, D_80BF6FB4, 9, -5.0f); + Actor_SetScale(&this->actor, 0.0f); + break; + + case 3: + func_80BF5E68(this, D_80BF6FB4, 2, -5.0f); + break; + + case 4: + func_80BF5E68(this, D_80BF6FB4, 4, 0); + break; + + case 5: + func_80BF5E68(this, D_80BF6FB4, 8, -5.0f); + break; + + case 6: + func_80BF5E68(this, D_80BF6FB4, 11, -5.0f); + break; + + case 7: + func_80BF5E68(this, D_80BF6FB4, 6, -5.0f); + break; + + case 8: + func_80BF5E00(this, D_80BF6FB4, 0, -5.0f); + break; + + case 9: + func_80BF5E00(this, D_80BF6FB4, 0, -5.0f); + break; + } +} + +void func_80BF6478(EnOsk* this) { + if (this->actor.draw != NULL) { + switch (this->unk_254) { + case 1: + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 6.0f) || + Animation_OnFrame(&this->skelAnime, 11.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, 11.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 10: + case 11: + func_800B9010(&this->actor, NA_SE_EN_YASE_LAUGH_K - SFX_FLAG); + break; + } + } +} + +void func_80BF656C(EnOsk* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + switch (this->unk_254) { + case 2: + func_80BF5E00(this, D_80BF6FB4, 1, 0.0f); + break; + + case 4: + func_80BF5E00(this, D_80BF6FB4, 3, 0.0f); + break; + + case 8: + func_80BF5E00(this, D_80BF6FB4, 7, -5.0f); + break; + + case 11: + func_80BF5E00(this, D_80BF6FB4, 10, -5.0f); + break; + + case 6: + func_80BF5E00(this, D_80BF6FB4, 5, -5.0f); + break; + } + } + + if (Cutscene_CheckActorAction(globalCtx, this->unk_258)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, this->unk_258)); + if (this->unk_256 != + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action) { + this->unk_256 = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action; + func_80BF6314(this); + } + func_80BF6478(this); + } else { + this->actor.draw = NULL; + } + + if ((this->unk_256 == 2) && (this->actor.scale.x < 13.0f * 0.001f)) { + this->actor.scale.x += 0.65f * 0.001f; + Actor_SetScale(&this->actor, this->actor.scale.x); + } + + if (this->unk_256 == 9) { + if (this->actor.scale.x > 0.65f * 0.001f) { + this->actor.scale.x -= 0.65f * 0.001f; + Actor_SetScale(&this->actor, this->actor.scale.x); + func_80BF5EBC(this, globalCtx); + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } else { + this->actor.draw = NULL; + } + } +} + +void func_80BF67A8(EnOsk* this) { + if ((this->unk_256 != 1) && (this->unk_256 != 8)) { + this->actor.draw = EnOsk_Draw; + Actor_SetScale(&this->actor, 0.013f); + } + + switch (this->unk_256) { + case 1: + this->actor.draw = NULL; + break; + + case 2: + func_80BF5E68(this, D_80BF6FE4, 2, -5.0f); + break; + + case 3: + func_80BF5E68(this, D_80BF6FE4, 8, -5.0f); + break; + + case 4: + func_80BF5E68(this, D_80BF6FE4, 4, -5.0f); + break; + + case 5: + func_80BF5E68(this, D_80BF6FE4, 6, -5.0f); + break; + + case 6: + func_80BF5E68(this, D_80BF6FE4, 10, -5.0f); + break; + + case 7: + case 8: + func_80BF5E00(this, D_80BF6FE4, 0, -5.0f); + break; + + case 9: + func_80BF5E68(this, D_80BF6FE4, 12, -5.0f); + break; + } +} + +void func_80BF68E0(EnOsk* this) { + if (this->actor.draw != NULL) { + switch (this->unk_254) { + case 1: + case 7: + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 6.0f) || + Animation_OnFrame(&this->skelAnime, 11.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, 4.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, 5.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 5: + if ((Animation_OnFrame(&this->skelAnime, 6.0f)) || Animation_OnFrame(&this->skelAnime, 11.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + + case 8: + if (Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DEBU_HEAD_UP); + } + break; + } + } +} + +void func_80BF6A20(EnOsk* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + switch (this->unk_254) { + case 2: + func_80BF5E00(this, D_80BF6FE4, 1, -5.0f); + break; + + case 8: + func_80BF5E00(this, D_80BF6FE4, 7, -5.0f); + break; + + case 4: + func_80BF5E00(this, D_80BF6FE4, 3, -5.0f); + break; + + case 6: + func_80BF5E00(this, D_80BF6FE4, 5, -5.0f); + break; + + case 10: + func_80BF5E00(this, D_80BF6FE4, 9, -5.0f); + break; + + case 12: + func_80BF5E00(this, D_80BF6FE4, 11, -5.0f); + break; + } + } + + if (Cutscene_CheckActorAction(globalCtx, this->unk_258)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, this->unk_258)); + if (this->unk_256 != + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action) { + this->unk_256 = + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->unk_258)]->action; + func_80BF67A8(this); + } + func_80BF68E0(this); + } else { + this->actor.draw = NULL; + } + + if (this->unk_256 == 8) { + if (this->actor.scale.x > 0.65f * 0.001f) { + this->actor.scale.x -= 0.65f * 0.001f; + Actor_SetScale(&this->actor, this->actor.scale.x); + func_80BF5EBC(this, globalCtx); + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } else { + this->actor.draw = NULL; + } + } +} + +void EnOsk_Update(Actor* thisx, GlobalContext* globalCtx) { + EnOsk* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void func_80BF6C54(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnOsk* this = THIS; + + if (limbIndex == 1) { + Matrix_MultVec3f(&D_80BF7024, &this->actor.focus.pos); + } +} + +void EnOsk_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOsk* this = THIS; + Gfx* gfx; + Vec3f sp80; + s32 pad2[4]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_PrimColor(globalCtx->state.gfxCtx, 0x80, 255, 255, 255, 255)); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, func_80BF6C54, &this->actor); + + { + s16 sp62; + s16 sp60; + Vec3f sp54; + + sp54 = GET_ACTIVE_CAM(globalCtx)->eye; + + sp62 = Math_Vec3f_Yaw(&sp54, &this->actor.focus.pos); + sp60 = -Math_Vec3f_Pitch(&sp54, &this->actor.focus.pos); + + sp80.x = -(15.0f * (Math_SinS(sp62)) * Math_CosS(sp60)); + sp80.y = -(Math_SinS(sp60) * 15.0f); + sp80.z = -(15.0f * (Math_CosS(sp62)) * Math_CosS(sp60)); + + Matrix_Translate(this->actor.focus.pos.x + sp80.x, this->actor.focus.pos.y + sp80.y, + sp80.z = this->actor.focus.pos.z + sp80.z, MTXMODE_NEW); + + sp80.z = Math_SinS(globalCtx->gameplayFrames << 0xE); + sp80.z = ((sp80.z + 1.0f) * 0.1f) + 2.0f; + Matrix_Scale(this->actor.scale.x * sp80.z, this->actor.scale.y * sp80.z, this->actor.scale.z * sp80.z, + MTXMODE_APPLY); + } + + gfx = func_8012C868(POLY_XLU_DISP); + + gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); + if (1) {} + if (1) {} + if (1) {} + gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); + gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); + gDPSetPrimColor(gfx++, 0, 0, 130, 0, 255, 100); + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gameplay_keep_DL_029CF0); + + POLY_XLU_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Osk/z_en_osk.h b/src/overlays/actors/ovl_En_Osk/z_en_osk.h index f98437897..9515e9705 100644 --- a/src/overlays/actors/ovl_En_Osk/z_en_osk.h +++ b/src/overlays/actors/ovl_En_Osk/z_en_osk.h @@ -7,9 +7,20 @@ struct EnOsk; typedef void (*EnOskActionFunc)(struct EnOsk*, GlobalContext*); +#define ENOSK_GET_F(thisx) ((thisx)->params & 0xF) + +#define ENOSK_1 1 +#define ENOSK_2 2 + typedef struct EnOsk { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x11C]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[17]; + /* 0x01EE */ Vec3s morphTable[17]; + /* 0x0254 */ s16 unk_254; + /* 0x0256 */ s16 unk_256; + /* 0x0258 */ u16 unk_258; + /* 0x025C */ f32 unk_25C; /* 0x0260 */ EnOskActionFunc actionFunc; } EnOsk; // size = 0x264 diff --git a/src/overlays/actors/ovl_En_Osn/z_en_osn.c b/src/overlays/actors/ovl_En_Osn/z_en_osn.c index 8f301ace1..90cd6785f 100644 --- a/src/overlays/actors/ovl_En_Osn/z_en_osn.c +++ b/src/overlays/actors/ovl_En_Osn/z_en_osn.c @@ -1,6 +1,13 @@ -#include "z_en_osn.h" +/* + * File: z_en_osn.c + * Overlay: ovl_En_Osn + * Description: Happy Mask Salesman + */ -#define FLAGS 0x00000019 +#include "z_en_osn.h" +#include "objects/object_osn/object_osn.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnOsn*)thisx) @@ -9,7 +16,6 @@ void EnOsn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnOsn_Update(Actor* thisx, GlobalContext* globalCtx); void EnOsn_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Osn_InitVars = { ACTOR_EN_OSN, ACTORCAT_NPC, @@ -22,18 +28,45 @@ const ActorInit En_Osn_InitVars = { (ActorFunc)EnOsn_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AD2518 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, 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 AnimationInfo sAnimations[] = { + { &object_osn_Anim_0201BC, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_002F74, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_0037C4, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_004320, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_004C8C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_0094E4, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_009BB8, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_00AC60, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_001614, 1.0f, 1.0f, 39.0f, 0, 0.0f }, { &object_osn_Anim_001034, 1.0f, 1.0f, 70.0f, 0, 0.0f }, + { &object_osn_Anim_00AE9C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_003A1C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_0055F8, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_007220, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_00A444, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_0000C4, 0.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_osn_Anim_0000C4, 0.0f, 1.0f, 1.0f, 2, 0.0f }, { &object_osn_Anim_006D48, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_001D6C, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_osn_Anim_002634, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_008D80, 1.0f, 0.0f, 0.0f, 2, 0.0f }, { &object_osn_Anim_005D78, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_osn_Anim_006564, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_osn_Anim_00A444, 1.0f, 0.0f, 0.0f, 0, 0.0f }, + { &object_osn_Anim_008D80, 0.0f, 77.0f, 0.0f, 2, 0.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + 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 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80AD2544 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80AD2550 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -68,59 +101,827 @@ static DamageTable D_80AD2550 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AD2570[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 0, ICHAIN_STOP), }; -#endif +void func_80AD1634(EnOsn*, GlobalContext*); +void func_80AD16A8(EnOsn*, GlobalContext*); +void func_80AD14C8(EnOsn*, GlobalContext*); +void func_80AD19A0(EnOsn* this, GlobalContext* globalCtx); -extern ColliderCylinderInit D_80AD2518; -extern CollisionCheckInfoInit2 D_80AD2544; -extern DamageTable D_80AD2550; -extern InitChainEntry D_80AD2570[]; +void func_80AD0830(EnOsn* 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); +} -extern UNK_TYPE D_060192A0; -extern UNK_TYPE D_060201BC; +s32 func_80AD08B0(GlobalContext* globalCtx) { + switch (Player_GetMask(globalCtx)) { + case PLAYER_MASK_GREAT_FAIRY: + return 0x1FD6; + case PLAYER_MASK_GIBDO: + return 0x1FD8; + case PLAYER_MASK_TRUTH: + return 0x1FDA; + case PLAYER_MASK_GIANT: + return 0x1FDC; + case PLAYER_MASK_KAFEIS_MASK: + return 0x1FDE; + case PLAYER_MASK_DON_GERO: + return 0x1FE0; + case PLAYER_MASK_BLAST: + return 0x1FE2; + case PLAYER_MASK_COUPLE: + return 0x1FE4; + case PLAYER_MASK_SCENTS: + return 0x1FE6; + case PLAYER_MASK_KAMARO: + return 0x1FE8; + case PLAYER_MASK_STONE: + return 0x1FEA; + case PLAYER_MASK_POSTMAN: + return 0x1FEC; + case PLAYER_MASK_BUNNY: + return 0x1FEE; + case PLAYER_MASK_CAPTAIN: + return 0x1FF0; + case PLAYER_MASK_BREMEN: + return 0x1FF2; + case PLAYER_MASK_CIRCUS_LEADER: + return 0x1FF4; + case PLAYER_MASK_KEATON: + return 0x1FF6; + case PLAYER_MASK_GARO: + return 0x1FF8; + case PLAYER_MASK_ALL_NIGHT: + return 0x1FFA; + case PLAYER_MASK_ROMANI: + return 0x1FFC; + default: + return 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0830.s") +void func_80AD0998(EnOsn* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_1EC].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD08B0.s") + if (this->unk_1EC == 0x12 && curFrame == lastFrame) { + this->unk_1EC = 0x13; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0x13); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0998.s") +void func_80AD0A24(EnOsn* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_1EC].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0A24.s") + if (this->unk_1EC == 0x15 && curFrame == lastFrame) { + this->unk_1EC = 0x16; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0x16); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0AB0.s") +void func_80AD0AB0(EnOsn* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_1EC].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0B38.s") + if (curFrame == lastFrame) { + this->unk_1FA -= 8; + if (this->unk_1FA < 8) { + this->unk_1FA = 0; + Actor_MarkForDeath(&this->actor); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD0E10.s") +s32 func_80AD0B38(EnOsn* this, GlobalContext* globalCtx) { + switch (Player_GetMask(globalCtx)) { + case PLAYER_MASK_GREAT_FAIRY: + if (!(this->unk_1F6 & 1)) { + this->unk_1F6 |= 1; + return 0x1FD1; + } + break; + case PLAYER_MASK_GIBDO: + if (!(this->unk_1F6 & 2)) { + this->unk_1F6 |= 2; + return 0x1FD1; + } + break; + case PLAYER_MASK_TRUTH: + if (!(this->unk_1F6 & 4)) { + this->unk_1F6 |= 4; + return 0x1FD1; + } + break; + case PLAYER_MASK_GIANT: + if (!(this->unk_1F6 & 8)) { + this->unk_1F6 |= 8; + return 0x1FD1; + } + break; + case PLAYER_MASK_KAFEIS_MASK: + if (!(this->unk_1F6 & 0x10)) { + this->unk_1F6 |= 0x10; + return 0x1FD1; + } + break; + case PLAYER_MASK_DON_GERO: + if (!(this->unk_1F6 & 0x20)) { + this->unk_1F6 |= 0x20; + return 0x1FD1; + } + break; + case PLAYER_MASK_BLAST: + if (!(this->unk_1F6 & 0x40)) { + this->unk_1F6 |= 0x40; + return 0x1FD1; + } + break; + case PLAYER_MASK_COUPLE: + if (!(this->unk_1F6 & 0x80)) { + this->unk_1F6 |= 0x80; + return 0x1FD1; + } + break; + case PLAYER_MASK_SCENTS: + if (!(this->unk_1F6 & 0x100)) { + this->unk_1F6 |= 0x100; + return 0x1FD1; + } + break; + case PLAYER_MASK_KAMARO: + if (!(this->unk_1F6 & 0x200)) { + this->unk_1F6 |= 0x200; + return 0x1FD1; + } + break; + case PLAYER_MASK_STONE: + if (!(this->unk_1F6 & 0x400)) { + this->unk_1F6 |= 0x400; + return 0x1FD1; + } + break; + case PLAYER_MASK_POSTMAN: + if (!(this->unk_1F6 & 0x800)) { + this->unk_1F6 |= 0x800; + return 0x1FD2; + } + break; + case PLAYER_MASK_BUNNY: + if (!(this->unk_1F6 & 0x1000)) { + this->unk_1F6 |= 0x1000; + return 0x1FD2; + } + break; + case PLAYER_MASK_CAPTAIN: + if (!(this->unk_1F6 & 0x2000)) { + this->unk_1F6 |= 0x2000; + return 0x1FD1; + } + break; + case PLAYER_MASK_BREMEN: + if (!(this->unk_1F6 & 0x4000)) { + this->unk_1F6 |= 0x4000; + return 0x1FD1; + } + break; + case PLAYER_MASK_CIRCUS_LEADER: + if (!(this->unk_1F6 & 0x8000)) { + this->unk_1F6 |= 0x8000; + return 0x1FD1; + } + break; + case PLAYER_MASK_KEATON: + if (!(this->unk_1F6 & 0x10000)) { + this->unk_1F6 |= 0x10000; + return 0x1FD1; + } + break; + case PLAYER_MASK_GARO: + if (!(this->unk_1F6 & 0x20000)) { + this->unk_1F6 |= 0x20000; + return 0x1FD1; + } + break; + case PLAYER_MASK_ALL_NIGHT: + if (!(this->unk_1F6 & 0x40000)) { + this->unk_1F6 |= 0x40000; + return 0x1FD1; + } + break; + case PLAYER_MASK_ROMANI: + if (!(this->unk_1F6 & 0x80000)) { + this->unk_1F6 |= 0x80000; + return 0x1FD1; + } + break; + default: + break; + } + this->unk_1EA |= 0x20; + if (gSaveContext.save.day == 3 && gSaveContext.save.time >= CLOCK_TIME(5, 0) && + gSaveContext.save.time < CLOCK_TIME(6, 0)) { + return 0x2006; + } + return 0x1FCD; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD10FC.s") +s32 func_80AD0E10(EnOsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD1398.s") + if ((gSaveContext.save.inventory.items[SLOT_OCARINA] != ITEM_NONE) && CHECK_QUEST_ITEM(QUEST_SONG_HEALING)) { + if (this->unk_1EA & 1) { + this->unk_1EA |= 0x20; + if ((gSaveContext.save.inventory.items[SLOT_OCARINA] != ITEM_NONE) && + (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU)) { + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2006; + } + return 0x1FCD; + } + return 0x1FAF; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD144C.s") + if (player->transformation == PLAYER_FORM_DEKU) { + if (this->unk_1EA & 4) { + this->unk_1EA |= 0x20; + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2006; + } + return 0x1FCD; + } + this->unk_1EA |= 4; + return 0x1FC8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD14C8.s") + if (player->transformation == PLAYER_FORM_GORON) { + if (this->unk_1EA & 8) { + this->unk_1EA |= 0x20; + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2006; + } + return 0x1FCD; + } + this->unk_1EA |= 8; + if (gSaveContext.save.weekEventReg[76] & 0x20) { + return 0x1FC8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD1634.s") + gSaveContext.save.weekEventReg[76] |= 0x20; + return 0x1FCE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD16A8.s") + if (player->transformation == PLAYER_FORM_ZORA) { + if (this->unk_1EA & 0x10) { + this->unk_1EA |= 0x20; + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2006; + } + return 0x1FCD; + } + this->unk_1EA |= 0x10; + if (gSaveContext.save.weekEventReg[76] & 0x40) { + return 0x1FC8; + } + gSaveContext.save.weekEventReg[76] |= 0x40; + return 0x1FD0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD19A0.s") + if (Player_GetMask(globalCtx) == PLAYER_MASK_NONE) { + if (this->unk_1EA & 2) { + this->unk_1EA |= 0x20; + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2006; + } + return 0x1FCD; + } + this->unk_1EA |= 2; + return 0x1FC8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD1A4C.s") + return func_80AD0B38(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/EnOsn_Init.s") + this->unk_1EA |= 0x20; + if ((gSaveContext.save.day == 3) && (gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + return 0x2004; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/EnOsn_Destroy.s") + return 0x1FAE; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/EnOsn_Update.s") +void func_80AD10FC(EnOsn* this, GlobalContext* globalCtx) { + switch (this->unk_1F4) { + case 0x1FC8: + this->unk_1F4 = 0x1FC9; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD1DA8.s") + case 0x1FC9: + this->unk_1F4 = 0x1FCA; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/func_80AD1E28.s") + case 0x1FCA: + if ((gSaveContext.save.day == 3 && gSaveContext.save.time >= CLOCK_TIME(5, 0)) && + gSaveContext.save.time < CLOCK_TIME(6, 0)) { + this->unk_1F4 = 0x2007; + } else { + this->unk_1F4 = 0x1FCB; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Osn/EnOsn_Draw.s") + case 0x1FCB: + case 0x2007: + this->unk_1F4 = 0x1FCC; + this->unk_1EA |= 0x20; + break; + + case 0x1FCE: + case 0x1FD0: + this->unk_1F4 = 0x1FCF; + break; + + case 0x1FCF: + this->unk_1F4 = 0x1FCA; + break; + + case 0x1FD1: + case 0x1FD2: + this->unk_1F4 = func_80AD08B0(globalCtx); + break; + + case 0x1FD6: + this->unk_1F4 = 0x1FD7; + break; + + case 0x1FD8: + this->unk_1F4 = 0x1FD9; + break; + + case 0x1FDA: + this->unk_1F4 = 0x1FDB; + break; + + case 0x1FDC: + this->unk_1F4 = 0x1FDD; + break; + + case 0x1FDE: + this->unk_1F4 = 0x1FDF; + break; + + case 0x1FE0: + this->unk_1F4 = 0x1FE1; + break; + + case 0x1FE2: + this->unk_1F4 = 0x1FE3; + break; + + case 0x1FE4: + this->unk_1F4 = 0x1FE5; + break; + + case 0x1FE6: + this->unk_1F4 = 0x1FE7; + break; + + case 0x1FE8: + this->unk_1F4 = 0x1FE9; + break; + + case 0x1FEA: + this->unk_1F4 = 0x1FEB; + break; + + case 0x1FEC: + this->unk_1F4 = 0x1FED; + break; + + case 0x1FEE: + this->unk_1F4 = 0x1FEF; + break; + + case 0x1FF0: + this->unk_1F4 = 0x1FF1; + break; + + case 0x1FF2: + this->unk_1F4 = 0x1FF3; + break; + + case 0x1FF4: + this->unk_1F4 = 0x1FF5; + break; + + case 0x1FF6: + this->unk_1F4 = 0x1FF7; + break; + + case 0x1FF8: + this->unk_1F4 = 0x1FF9; + break; + + case 0x1FFA: + this->unk_1F4 = 0x1FFB; + break; + + case 0x1FFC: + this->unk_1F4 = 0x1FFD; + break; + + case 0x1FD7: + case 0x1FDB: + case 0x1FDD: + case 0x1FDF: + case 0x1FE1: + case 0x1FE7: + case 0x1FF1: + case 0x1FF3: + case 0x1FF7: + case 0x1FF9: + case 0x1FFB: + this->unk_1F4 = 0x1FD3; + break; + + case 0x1FD9: + case 0x1FE3: + case 0x1FE9: + case 0x1FEB: + case 0x1FED: + case 0x1FEF: + case 0x1FF5: + case 0x1FFD: + this->unk_1F4 = 0x1FD4; + break; + + case 0x1FE5: + this->unk_1F4 = 0x1FFE; + break; + + case 0x1FD3: + case 0x1FD4: + case 0x1FFE: + this->unk_1F4 = 0x1FD5; + this->unk_1EA |= 0x20; + } + + Message_StartTextbox(globalCtx, this->unk_1F4, &this->actor); +} + +void func_80AD1398(EnOsn* this) { + this->cutscene = this->actor.cutscene; + if ((gSaveContext.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) || + (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU)) { + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->cutscene); + + if ((gSaveContext.save.inventory.items[SLOT_OCARINA] != ITEM_NONE) || + (INV_CONTENT(ITEM_MASK_DEKU) == ITEM_MASK_DEKU)) { + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->cutscene); + } + } +} + +void func_80AD144C(EnOsn* this, GlobalContext* globalCtx) { + u32 sp1C = Flags_GetSwitch(globalCtx, 0); + this->cutscene = this->actor.cutscene; + + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + if (sp1C == 0) { + this->actionFunc = func_80AD16A8; + } else { + this->actionFunc = func_80AD14C8; + } +} + +void func_80AD14C8(EnOsn* this, GlobalContext* globalCtx) { + s16 temp_v1 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + if (gSaveContext.save.inventory.items[SLOT_OCARINA] != ITEM_NONE && !CHECK_QUEST_ITEM(QUEST_SONG_HEALING)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AD1634; + } else if ((((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) && (temp_v1 < 0x4000)) && + (temp_v1 > -0x4000)) { + func_800B863C(&this->actor, globalCtx); + this->actor.textId = 0xFFFF; + } + } else { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_1F4 = func_80AD0E10(this, globalCtx); + Message_StartTextbox(globalCtx, this->unk_1F4, &this->actor); + this->actionFunc = func_80AD19A0; + } else if ((((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) && (temp_v1 < 0x4000)) && + (temp_v1 > -0x4000)) { + func_800B863C(&this->actor, globalCtx); + } + } +} + +void func_80AD1634(EnOsn* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Start(this->cutscene, &this->actor); + this->actionFunc = func_80AD16A8; + return; + } + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->cutscene); +} + +void func_80AD16A8(EnOsn* this, GlobalContext* globalCtx) { + u8 pad; + s32 actionIndex; + + if (Cutscene_CheckActorAction(globalCtx, 130)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 130); + this->unk_1F0 = 0; + if (this->unk_1ED != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->unk_1ED = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { + case 1: + this->unk_1EC = 2; + break; + case 2: + this->unk_1EC = 1; + break; + case 3: + this->unk_1EC = 7; + break; + case 4: + this->unk_1EC = 3; + break; + case 5: + this->unk_1EC = 6; + break; + case 6: + this->unk_1EC = 5; + break; + case 7: + this->unk_1EC = 4; + break; + case 8: + this->unk_1EC = 0; + break; + case 10: + this->unk_1EC = 8; + break; + case 11: + this->unk_1EC = 9; + break; + case 13: + this->unk_1EC = 0xA; + break; + case 15: + this->unk_1EC = 0xB; + break; + case 16: + this->unk_1EC = 0xC; + break; + case 17: + this->unk_1EC = 0xD; + break; + case 18: + this->unk_1EC = 0xE; + break; + case 19: + this->unk_1EC = 0x11; + break; + case 20: + this->unk_1EC = 0x12; + break; + case 21: + this->unk_1EC = 0x14; + break; + case 22: + this->unk_1EC = 0x15; + break; + case 23: + this->unk_1EC = 0x17; + break; + case 24: + this->unk_1EC = 0x18; + break; + default: + this->unk_1EC = 0; + break; + } + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_1EC); + } + + if ((this->unk_1EC == 5) && (globalCtx->sceneNum == SCENE_SPOT00) && (gSaveContext.sceneSetupIndex == 0xB) && + (globalCtx->csCtx.frames == 400)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_OMVO00); + } + if (this->unk_1EC == 0x12) { + func_80AD0998(this); + } + if (this->unk_1EC == 0x15) { + func_80AD0A24(this); + } + if (this->unk_1EC == 0x18) { + func_80AD0AB0(this); + } + if ((this->unk_1EC == 0x14) && + (((Animation_OnFrame(&this->skelAnime, 17.0f))) || (Animation_OnFrame(&this->skelAnime, 27.0f)) || + (Animation_OnFrame(&this->skelAnime, 37.0f)) || (Animation_OnFrame(&this->skelAnime, 47.0f)) || + (Animation_OnFrame(&this->skelAnime, 57.0f)) || (Animation_OnFrame(&this->skelAnime, 67.0f)))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OMENYA_WALK); + } + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); + } else { + this->unk_1F0 = 1; + this->unk_1ED = 0x63; + func_80AD144C(this, globalCtx); + } +} + +void func_80AD19A0(EnOsn* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if ((temp_v0 == 6 || temp_v0 == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_1EA & 0x20) { + this->unk_1EA &= ~0x20; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80AD14C8; + } else { + func_80AD10FC(this, globalCtx); + } + } +} + +void EnOsn_Idle(EnOsn* this, GlobalContext* globalCtx) { +} + +void EnOsn_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOsn* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_osn_Skel_0202F0, &object_osn_Anim_0201BC, 0, 0, 0); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->unk_1FA = 255; + switch (ENOSN_GET_3(&this->actor)) { + case 0: + if (((gSaveContext.save.entranceIndex == 0xC020) || (gSaveContext.save.entranceIndex == 0xC030)) || + (gSaveContext.save.entranceIndex == 0xC060)) { + this->unk_1EA |= 1; + } + this->unk_1F0 = 1; + if (globalCtx->sceneNum == SCENE_INSIDETOWER) { + if ((gSaveContext.save.entranceIndex == 0xC020) || (gSaveContext.save.entranceIndex == 0xC060)) { + this->actionFunc = func_80AD16A8; + return; + } + if (gSaveContext.save.entranceIndex == 0xC030) { + func_80AD1398(this); + this->actionFunc = func_80AD1634; + return; + } + func_80AD144C(this, globalCtx); + return; + } + func_80AD144C(this, globalCtx); + break; + + case 1: + this->unk_1EC = 0xF; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_1EC); + this->actionFunc = EnOsn_Idle; + break; + + case 2: + this->unk_1EC = 0x10; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->unk_1EC); + this->actionFunc = EnOsn_Idle; + break; + + case 3: + this->actor.flags &= ~ACTOR_FLAG_1; + this->actionFunc = func_80AD16A8; + break; + + default: + Actor_MarkForDeath(&this->actor); + } +} + +void EnOsn_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnOsn* this = THIS; + + SkelAnime_Free(&this->skelAnime, globalCtx); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnOsn_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOsn* this = THIS; + u32 sp34; + + sp34 = Flags_GetSwitch(globalCtx, 0); + this->actionFunc(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + SkelAnime_Update(&this->skelAnime); + if (!(ENOSN_GET_3(&this->actor))) { + if (sp34 != 0) { + this->actor.flags |= ACTOR_FLAG_1; + func_80AD0830(this, globalCtx); + this->actor.draw = EnOsn_Draw; + } else { + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + } + } + func_800E9250(globalCtx, &this->actor, &this->unk_1D8, &this->unk_1DE, this->actor.focus.pos); +} + +s32 EnOsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnOsn* this = (EnOsn*)thisx; + + if (this->unk_1F0 && limbIndex == 11) { + Matrix_RotateXS(this->unk_1D8.y, MTXMODE_APPLY); + } + if ((this->unk_1EC == 9 || this->unk_1EC == 8) && limbIndex == 10) { + *dList = NULL; + } + return false; +} + +void EnOsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnOsn* this = (EnOsn*)thisx; + Vec3f sp30 = { 0.0f, 0.0f, 0.0f }; + Vec3s sp28 = { 0x9920, -0x384, -0x320 }; + + if (limbIndex == 11) { + Matrix_MultVec3f(&sp30, &thisx->focus.pos); + } + if (((this->unk_1EC == 17) || (this->unk_1EC == 21) || (this->unk_1EC == 22)) && (limbIndex == 6)) { + Matrix_Push(); + Matrix_Translate(-400.0f, 1100.0f, -200.0f, MTXMODE_APPLY); + Matrix_RotateXS(sp28.x, MTXMODE_APPLY); + Matrix_RotateYS(sp28.y, MTXMODE_APPLY); + Matrix_RotateZS(sp28.z, MTXMODE_APPLY); + + gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList((*gfx)++, &object_osn_DL_0192A0); + Matrix_Pop(); + } +} + +void EnOsn_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80AD2588 = object_osn_Tex_0166F8; + static TexturePtr D_80AD258C = object_osn_Tex_016EF8; + static TexturePtr D_80AD2590 = object_osn_Tex_0176F8; + static TexturePtr D_80AD2594 = object_osn_Tex_017EF8; + static TexturePtr D_80AD2598 = object_osn_Tex_0182F8; + s32 pad; + EnOsn* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_1FA == 0xFF) { + func_8012C28C(globalCtx->state.gfxCtx); + if ((this->unk_1EC == 0xB) || (this->unk_1EC == 0xC) || (this->unk_1EC == 0x17) || + (globalCtx->msgCtx.currentTextId == 0x1FCA)) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AD258C)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AD2594)); + } else if ((this->unk_1EC == 7) || (this->unk_1EC == 3) || (this->unk_1EC == 0xD)) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AD2590)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AD2598)); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AD2588)); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AD2594)); + } + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + Scene_SetRenderModeXlu(globalCtx, 0, 1); + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnOsn_OverrideLimbDraw, EnOsn_PostLimbDraw, + &this->actor, POLY_OPA_DISP); + } else { + func_8012C2DC(globalCtx->state.gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AD2588)); + gSPSegment(POLY_XLU_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AD2594)); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->unk_1FA); + Scene_SetRenderModeXlu(globalCtx, 1, 2); + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnOsn_OverrideLimbDraw, EnOsn_PostLimbDraw, + &this->actor, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Osn/z_en_osn.h b/src/overlays/actors/ovl_En_Osn/z_en_osn.h index 112a73e47..4cb99b925 100644 --- a/src/overlays/actors/ovl_En_Osn/z_en_osn.h +++ b/src/overlays/actors/ovl_En_Osn/z_en_osn.h @@ -9,11 +9,25 @@ typedef void (*EnOsnActionFunc)(struct EnOsn*, GlobalContext*); typedef struct EnOsn { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0X0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnOsnActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x28]; -} EnOsn; // size = 0x200 + /* 0x01D8 */ Vec3s unk_1D8; + /* 0x01DE */ Vec3s unk_1DE; + /* 0x01E4 */ UNK_TYPE1 unk_1E4[0x6]; + /* 0x01EA */ u16 unk_1EA; + /* 0x01EC */ u8 unk_1EC; + /* 0x01ED */ u8 unk_1ED; + /* 0x01EE */ s16 cutscene; + /* 0x01F0 */ u8 unk_1F0; + /* 0x01F1 */ UNK_TYPE1 unk_1F1[0x3]; + /* 0x01F4 */ u16 unk_1F4; + /* 0x01F6 */ s32 unk_1F6; + /* 0x01FA */ u8 unk_1FA; +} EnOsn; // size = 0x1FB extern const ActorInit En_Osn_InitVars; +#define ENOSN_GET_3(this) ((thisx)->params & 3) + #endif // Z_EN_OSN_H diff --git a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c index be2c4b570..ff85b7625 100644 --- a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c +++ b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.c @@ -5,8 +5,9 @@ */ #include "z_en_ossan.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnOssan*)thisx) @@ -17,17 +18,19 @@ void EnOssan_Init(Actor* thisx, GlobalContext* globalCtx); void EnOssan_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnOssan_Update(Actor* thisx, GlobalContext* globalCtx); -void EnOssan_DrawCuriosityShopMan(Actor* thisx, GlobalContext* globalCtx); -void EnOssan_DrawPartTimeWorker(Actor* thisx, GlobalContext* globalCtx); +void EnOssan_CuriosityShopMan_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnOssan_PartTimeWorker_Draw(Actor* thisx, GlobalContext* globalCtx); + +void EnOssan_CuriosityShopMan_Init(EnOssan* this, GlobalContext* globalCtx); +u16 EnOssan_CuriosityShopMan_GetWelcome(EnOssan* this, GlobalContext* globalCtx); + +void EnOssan_PartTimeWorker_Init(EnOssan* this, GlobalContext* globalCtx); +u16 EnOssan_PartTimerWorker_GetWelcome(EnOssan* this, GlobalContext* globalCtx); -void EnOssan_InitCuriosityShopMan(EnOssan* this, GlobalContext* globalCtx); -void EnOssan_InitPartTimeWorker(EnOssan* this, GlobalContext* globalCtx); -u16 EnOssan_GetWelcomeCuriosityShopMan(EnOssan* this, GlobalContext* globalCtx); void EnOssan_InitShop(EnOssan* this, GlobalContext* globalCtx); void EnOssan_Idle(EnOssan* this, GlobalContext* globalCtx); void EnOssan_BeginInteraction(EnOssan* this, GlobalContext* globalCtx); void EnOssan_Hello(EnOssan* this, GlobalContext* globalCtx); -u16 EnOssan_GetWelcomePartTimeWorker(EnOssan* this, GlobalContext* globalCtx); void EnOssan_SetHaveMet(EnOssan* this); void EnOssan_StartShopping(GlobalContext* globalCtx, EnOssan* this); void EnOssan_FaceShopkeeper(EnOssan* this, GlobalContext* globalCtx); @@ -50,28 +53,44 @@ void EnOssan_GetCutscenes(EnOssan* this, GlobalContext* globalCtx); s32 EnOssan_ReturnItemToShelf(EnOssan* this); s32 EnOssan_TakeItemOffShelf(EnOssan* this); -extern FlexSkeletonHeader D_060028A0; -extern TexturePtr D_06005BC0; -extern TexturePtr D_06006498; -extern TexturePtr D_06006B18; -extern TexturePtr D_06006D40; -extern TexturePtr D_06006F18; -extern TexturePtr D_06007140; -extern AnimationHeader D_06009D34; -extern AnimationHeader D_0600A460; -extern AnimationHeader D_0600CB3C; -extern AnimationHeader D_0600DE34; -extern AnimationHeader D_0600E3EC; -extern AnimationHeader D_0600C58C; -extern AnimationHeader D_0600F00C; -extern AnimationHeader D_0600B9D8; -extern AnimationHeader D_0600C26C; -extern AnimationHeader D_0600D354; -extern AnimationHeader D_06012C34; -extern AnimationHeader D_060131FC; -extern FlexSkeletonHeader D_06013320; -extern AnimationHeader D_060138B0; -extern AnimationHeader D_0601430C; +typedef enum { + /* 0 */ ENOSSAN_CUTSCENESTATE_STOPPED, + /* 1 */ ENOSSAN_CUTSCENESTATE_WAITING, + /* 2 */ ENOSSAN_CUTSCENESTATE_PLAYING +} EnOssanCutsceneState; + +typedef enum { + /* 00 */ FSN_ANIMATION_IDLE, + /* 01 */ FSN_ANIMATION_SCRATCH_BACK, + /* 02 */ FSN_ANIMATION_TURN_AROUND_FORWARD, + /* 03 */ FSN_ANIMATION_TURN_AROUND_REVERSE, + /* 04 */ FSN_ANIMATION_HANDS_ON_COUNTER_START, + /* 05 */ FSN_ANIMATION_HANDS_ON_COUNTER_LOOP, + /* 06 */ FSN_ANIMATION_HAND_ON_FACE_START, + /* 07 */ FSN_ANIMATION_HAND_ON_FACE_LOOP, + /* 08 */ FSN_ANIMATION_LEAN_FORWARD_START, + /* 09 */ FSN_ANIMATION_LEAN_FORWARD_LOOP, + /* 10 */ FSN_ANIMATION_SLAM_COUNTER_START, + /* 11 */ FSN_ANIMATION_SLAM_COUNTER_LOOP, + /* 12 */ FSN_ANIMATION_MAKE_OFFER, + /* 13 */ FSN_ANIMATION_MAX +} FsnAnimation; + +typedef enum { + /* 00 */ ANI_ANIMATION_STANDING_NORMAL_LOOP_1, + /* 01 */ ANI_ANIMATION_STANDING_NORMAL_LOOP_2, + /* 02 */ ANI_ANIMATION_STANDING_NORMAL_ONCE_FORWARD_1, + /* 03 */ ANI_ANIMATION_STANDING_NORMAL_ONCE_REVERSE, + /* 04 */ ANI_ANIMATION_STANDING_NORMAL_ONCE_FORWARD_2, + /* 05 */ ANI_ANIMATION_STANDING_NORMAL_LOOP_3, + /* 06 */ ANI_ANIMATION_STANDING_NORMAL_ONCE_FORWARD_3, + /* 07 */ ANI_ANIMATION_STANDING_NORMAL_LOOP_4, + /* 08 */ ANI_ANIMATION_APOLOGY_START, + /* 09 */ ANI_ANIMATION_APOLOGY_LOOP, + /* 10 */ ANI_ANIMATION_STANDING_NORMAL_ONCE_FORWARD_4, + /* 11 */ ANI_ANIMATION_STANDING_NORMAL_LOOP_5, + /* 12 */ ANI_ANIMATION_MAX +} AniAnimation; const ActorInit En_Ossan_InitVars = { ACTOR_EN_OSSAN, @@ -85,24 +104,40 @@ const ActorInit En_Ossan_InitVars = { (ActorFunc)NULL, }; -static ActorAnimationEntryS sAnimationsCuriosityShopMan[] = { - { &D_06012C34, 1.0f, 0, -1, 0, 0 }, { &D_060131FC, 1.0f, 0, -1, 0, 0 }, { &D_0600C58C, 1.0f, 0, -1, 2, 0 }, - { &D_0600C58C, -1.0f, 0, -1, 2, 0 }, { &D_0600E3EC, 1.0f, 0, -1, 2, 0 }, { &D_0600F00C, 1.0f, 0, -1, 0, 0 }, - { &D_0600CB3C, 1.0f, 0, -1, 2, 0 }, { &D_0600D354, 1.0f, 0, -1, 0, 0 }, { &D_060138B0, 1.0f, 0, -1, 2, 0 }, - { &D_0601430C, 1.0f, 0, -1, 0, 0 }, { &D_0600B9D8, 1.0f, 0, -1, 2, 0 }, { &D_0600C26C, 1.0f, 0, -1, 0, 0 }, - { &D_0600DE34, 1.0f, 0, -1, 2, 0 }, +static AnimationInfoS sAnimationsCuriosityShopMan[] = { + { &gFsnIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnScratchBackAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnTurnAroundAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnTurnAroundAnim, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandsOnCounterStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandsOnCounterLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnHandOnFaceStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnHandOnFaceLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnLeanForwardStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnLeanForwardLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnSlamCounterStartAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gFsnSlamCounterLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gFsnMakeOfferAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, }; -static ActorAnimationEntryS sAnimationsPartTimeWorker[] = { - { &D_06009D34, 1.0f, 0, -1, 0, -10 }, { &D_06009D34, 1.0f, 0, -1, 0, -10 }, { &D_06009D34, 1.0f, 0, -1, 2, 0 }, - { &D_06009D34, -1.0f, 0, -1, 2, 0 }, { &D_06009D34, 1.0f, 0, -1, 2, 0 }, { &D_06009D34, 1.0f, 0, -1, 0, 0 }, - { &D_06009D34, 1.0f, 0, -1, 2, 0 }, { &D_06009D34, 1.0f, 0, -1, 0, 0 }, { &D_0600A460, 1.0f, 0, -1, 2, -5 }, - { &D_0600A460, 1.0f, 0, -1, 0, -5 }, { &D_06009D34, 1.0f, 0, -1, 2, 0 }, { &D_06009D34, 1.0f, 0, -1, 0, 0 }, +static AnimationInfoS sAnimationsPartTimeWorker[] = { + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -10 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAniStandingNormalAnim, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gAniHandBehindHeadApologyAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -5 }, + { &gAniHandBehindHeadApologyAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -5 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gAniStandingNormalAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, }; static s16 sObjectIds[] = { OBJECT_FSN, OBJECT_ANI }; -static ActorAnimationEntryS* sAnimations[] = { sAnimationsCuriosityShopMan, sAnimationsPartTimeWorker }; +static AnimationInfoS* sAnimations[] = { sAnimationsCuriosityShopMan, sAnimationsPartTimeWorker }; static f32 sActorScales[] = { 0.01f, 0.01f }; @@ -172,10 +207,10 @@ s32 EnOssan_TestItemSelected(GlobalContext* globalCtx) { } void EnOssan_CheckValidSpawn(EnOssan* this) { - switch (gSaveContext.day) { + switch (gSaveContext.save.day) { case 1: case 2: - if (gSaveContext.time <= CLOCK_TIME(21, 30) && gSaveContext.time > CLOCK_TIME(6, 00)) { + if (gSaveContext.save.time <= CLOCK_TIME(21, 30) && gSaveContext.save.time > CLOCK_TIME(6, 00)) { if (this->actor.params != ENOSSAN_CURIOSITY_SHOP_MAN) { Actor_MarkForDeath(&this->actor); } @@ -187,7 +222,7 @@ void EnOssan_CheckValidSpawn(EnOssan* this) { if (this->actor.params == ENOSSAN_CURIOSITY_SHOP_MAN) { Actor_MarkForDeath(&this->actor); } - if (!(gSaveContext.time <= CLOCK_TIME(22, 00) && gSaveContext.time >= CLOCK_TIME(6, 00))) { + if (!(gSaveContext.save.time <= CLOCK_TIME(22, 00) && gSaveContext.save.time >= CLOCK_TIME(6, 00))) { if (this->actor.params != ENOSSAN_CURIOSITY_SHOP_MAN) { Actor_MarkForDeath(&this->actor); } @@ -256,7 +291,7 @@ void EnOssan_UpdateCursorPos(GlobalContext* globalCtx, EnOssan* this) { s16 x; s16 y; - func_800B8898(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); + Actor_GetScreenPos(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); this->cursorPos.x = x; this->cursorPos.y = y; } @@ -264,8 +299,8 @@ void EnOssan_UpdateCursorPos(GlobalContext* globalCtx, EnOssan* this) { void EnOssan_EndInteraction(GlobalContext* globalCtx, EnOssan* this) { Player* player = GET_PLAYER(globalCtx); - func_800B84D0(&this->actor, globalCtx); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; Interface_ChangeAlpha(50); this->drawCursor = 0; @@ -329,8 +364,8 @@ void EnOssan_SetupLookToShopkeeperFromShelf(GlobalContext* globalCtx, EnOssan* t void EnOssan_Idle(EnOssan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - func_8013D9C8(globalCtx, this->limbRotTableY, this->limbRotTableZ, 19); - if (func_800B84D0(&this->actor, globalCtx)) { + SubS_FillLimbRotTables(globalCtx, this->limbRotTableY, this->limbRotTableZ, ARRAY_COUNT(this->limbRotTableY)); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { player->stateFlags2 |= 0x20000000; EnOssan_SetupAction(this, EnOssan_BeginInteraction); if (this->cutsceneState == ENOSSAN_CUTSCENESTATE_STOPPED) { @@ -354,11 +389,11 @@ void EnOssan_Idle(EnOssan* this, GlobalContext* globalCtx) { } void EnOssan_BeginInteraction(EnOssan* this, GlobalContext* globalCtx) { - ActorAnimationEntryS* animations = sAnimations[this->actor.params]; + AnimationInfoS* animations = sAnimations[this->actor.params]; s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(animations[this->animationIdx].animationSeg); + s16 frameCount = Animation_GetLastFrame(animations[this->animationIndex].animation); - if (this->animationIdx == 3) { + if (this->animationIndex == FSN_ANIMATION_TURN_AROUND_REVERSE) { frameCount = 0; } if (this->cutsceneState == ENOSSAN_CUTSCENESTATE_WAITING) { @@ -371,48 +406,48 @@ void EnOssan_BeginInteraction(EnOssan* this, GlobalContext* globalCtx) { } if (this->actor.params == ENOSSAN_CURIOSITY_SHOP_MAN) { if (curFrame == frameCount) { - switch (this->animationIdx) { - case 1: - this->animationIdx = 2; - func_8013BC6C(&this->skelAnime, animations, 2); + switch (this->animationIndex) { + case FSN_ANIMATION_SCRATCH_BACK: + this->animationIndex = FSN_ANIMATION_TURN_AROUND_FORWARD; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, FSN_ANIMATION_TURN_AROUND_FORWARD); break; - case 2: + case FSN_ANIMATION_TURN_AROUND_FORWARD: EnOssan_SetHaveMet(this); - this->textId = EnOssan_GetWelcomeCuriosityShopMan(this, globalCtx); - func_8013BC6C(&this->skelAnime, animations, this->animationIdx); + this->textId = EnOssan_CuriosityShopMan_GetWelcome(this, globalCtx); + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, this->animationIndex); break; - case 4: - case 6: - case 8: - case 10: - this->animationIdx++; - func_8013BC6C(&this->skelAnime, animations, this->animationIdx); - func_801518B0(globalCtx, this->textId, &this->actor); + case FSN_ANIMATION_HANDS_ON_COUNTER_START: + case FSN_ANIMATION_HAND_ON_FACE_START: + case FSN_ANIMATION_LEAN_FORWARD_START: + case FSN_ANIMATION_SLAM_COUNTER_START: + this->animationIndex++; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, this->animationIndex); + Message_StartTextbox(globalCtx, this->textId, &this->actor); EnOssan_SetupStartShopping(globalCtx, this, false); break; - case 5: - case 7: - case 9: - case 11: - this->animationIdx = 3; - func_8013BC6C(&this->skelAnime, animations, 3); + case FSN_ANIMATION_HANDS_ON_COUNTER_LOOP: + case FSN_ANIMATION_HAND_ON_FACE_LOOP: + case FSN_ANIMATION_LEAN_FORWARD_LOOP: + case FSN_ANIMATION_SLAM_COUNTER_LOOP: + this->animationIndex = FSN_ANIMATION_TURN_AROUND_REVERSE; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, FSN_ANIMATION_TURN_AROUND_REVERSE); break; - case 3: - this->animationIdx = 1; - func_8013BC6C(&this->skelAnime, animations, 1); + case FSN_ANIMATION_TURN_AROUND_REVERSE: + this->animationIndex = FSN_ANIMATION_SCRATCH_BACK; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, FSN_ANIMATION_SCRATCH_BACK); EnOssan_SetupAction(this, EnOssan_Idle); break; default: - this->animationIdx = 1; - func_8013BC6C(&this->skelAnime, animations, 1); + this->animationIndex = FSN_ANIMATION_SCRATCH_BACK; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, FSN_ANIMATION_SCRATCH_BACK); EnOssan_SetupAction(this, EnOssan_Idle); break; } } } else { EnOssan_SetHaveMet(this); - this->textId = EnOssan_GetWelcomePartTimeWorker(this, globalCtx); - func_801518B0(globalCtx, this->textId, &this->actor); + this->textId = EnOssan_PartTimerWorker_GetWelcome(this, globalCtx); + Message_StartTextbox(globalCtx, this->textId, &this->actor); EnOssan_SetupStartShopping(globalCtx, this, false); } } @@ -522,16 +557,16 @@ u8 EnOssan_CursorLeft(EnOssan* this, u8 cursorIdx, u8 shelfSlotMax) { } void EnOssan_Hello(EnOssan* this, GlobalContext* globalCtx) { - ActorAnimationEntryS* animations = sAnimations[this->actor.params]; - u8 talkState = func_80152498(&globalCtx->msgCtx); + AnimationInfoS* animations = sAnimations[this->actor.params]; + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; Player* player = GET_PLAYER(globalCtx); EnOssan_RotateHead(this, globalCtx); - if (talkState == 5 && func_80147624(globalCtx)) { - if (this->animationIdx == 9 && this->actor.params == ENOSSAN_PART_TIME_WORKER) { - this->animationIdx = 1; - func_8013BC6C(&this->skelAnime, animations, 1); + if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { + if ((this->animationIndex == ANI_ANIMATION_APOLOGY_LOOP) && (this->actor.params == ENOSSAN_PART_TIME_WORKER)) { + this->animationIndex = ANI_ANIMATION_STANDING_NORMAL_LOOP_2; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, 1); } this->flags &= ~LOOKED_AT_PLAYER; if (player->transformation == PLAYER_FORM_DEKU) { @@ -545,26 +580,26 @@ void EnOssan_Hello(EnOssan* this, GlobalContext* globalCtx) { return; } } - if (talkState == 10 && this->actor.params == ENOSSAN_PART_TIME_WORKER && - player->transformation == PLAYER_FORM_ZORA && func_80147624(globalCtx)) { - this->animationIdx = 9; - func_8013BC6C(&this->skelAnime, animations, 9); + if ((talkState == 10) && (this->actor.params == ENOSSAN_PART_TIME_WORKER) && + (player->transformation == PLAYER_FORM_ZORA) && Message_ShouldAdvance(globalCtx)) { + this->animationIndex = ANI_ANIMATION_APOLOGY_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, ANI_ANIMATION_APOLOGY_LOOP); } - if (this->animationIdx == 11 && Animation_OnFrame(&this->skelAnime, 18.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_HANKO); + if ((this->animationIndex == FSN_ANIMATION_SLAM_COUNTER_LOOP) && Animation_OnFrame(&this->skelAnime, 18.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HANKO); } } s32 EnOssan_FacingShopkeeperDialogResult(EnOssan* this, GlobalContext* globalCtx) { - ActorAnimationEntryS* animations = sAnimations[this->actor.params]; + AnimationInfoS* animations = sAnimations[this->actor.params]; Player* player = GET_PLAYER(globalCtx); switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); - if (this->actor.params == ENOSSAN_PART_TIME_WORKER && player->transformation == PLAYER_FORM_ZORA) { - this->animationIdx = 9; - func_8013BC6C(&this->skelAnime, animations, 9); + if ((this->actor.params == ENOSSAN_PART_TIME_WORKER) && (player->transformation == PLAYER_FORM_ZORA)) { + this->animationIndex = ANI_ANIMATION_APOLOGY_LOOP; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, 9); } EnOssan_SetupAction(this, EnOssan_TalkToShopkeeper); func_80151938(globalCtx, sTalkOptionTextIds[this->actor.params]); @@ -581,7 +616,7 @@ s32 EnOssan_FacingShopkeeperDialogResult(EnOssan* this, GlobalContext* globalCtx } void EnOssan_FaceShopkeeper(EnOssan* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; Player* player = GET_PLAYER(globalCtx); u8 cursorIdx; @@ -597,7 +632,7 @@ void EnOssan_FaceShopkeeper(EnOssan* this, GlobalContext* globalCtx) { if (talkState == 4) { func_8011552C(globalCtx, 6); if (!EnOssan_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx)) && - (!func_80147624(globalCtx) || !EnOssan_FacingShopkeeperDialogResult(this, globalCtx))) { + (!Message_ShouldAdvance(globalCtx) || !EnOssan_FacingShopkeeperDialogResult(this, globalCtx))) { if (this->stickAccumX < 0) { cursorIdx = EnOssan_SetCursorIndexFromNeutral(this, 4); if (cursorIdx != CURSOR_INVALID) { @@ -628,12 +663,12 @@ void EnOssan_FaceShopkeeper(EnOssan* this, GlobalContext* globalCtx) { } void EnOssan_TalkToShopkeeper(EnOssan* this, GlobalContext* globalCtx) { - ActorAnimationEntryS* animations = sAnimations[this->actor.params]; + AnimationInfoS* animations = sAnimations[this->actor.params]; - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { - if (this->animationIdx == 9 && this->actor.params == ENOSSAN_PART_TIME_WORKER) { - this->animationIdx = 1; - func_8013BC6C(&this->skelAnime, animations, 1); + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { + if ((this->animationIndex == ANI_ANIMATION_APOLOGY_LOOP) && (this->actor.params == ENOSSAN_PART_TIME_WORKER)) { + this->animationIndex = ANI_ANIMATION_STANDING_NORMAL_LOOP_2; + SubS_ChangeAnimationByInfoS(&this->skelAnime, animations, 1); } EnOssan_StartShopping(globalCtx, this); } @@ -804,7 +839,7 @@ s32 EnOssan_HasPlayerSelectedItem(GlobalContext* globalCtx, EnOssan* this, Input } void EnOssan_BrowseLeftShelf(EnOssan* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; u8 prevCursorIndex = this->cursorIdx; u8 cursorIdx; @@ -862,7 +897,7 @@ void EnOssan_BrowseLeftShelf(EnOssan* this, GlobalContext* globalCtx) { } void EnOssan_BrowseRightShelf(EnOssan* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; u8 prevCursorIndex = this->cursorIdx; u8 cursorIdx; @@ -946,8 +981,8 @@ void EnOssan_LookToShopkeeperFromShelf(EnOssan* this, GlobalContext* globalCtx) void EnOssan_SetupBuyItemWithFanfare(GlobalContext* globalCtx, EnOssan* this) { Player* player = GET_PLAYER(globalCtx); - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->stateFlags2 &= ~0x20000000; Interface_ChangeAlpha(50); @@ -1014,11 +1049,11 @@ void EnOssan_HandleCanBuyItem(GlobalContext* globalCtx, EnOssan* this) { } void EnOssan_SelectItem(EnOssan* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (EnOssan_TakeItemOffShelf(this) && talkState == 4) { func_8011552C(globalCtx, 6); - if (!EnOssan_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && func_80147624(globalCtx)) { + if (!EnOssan_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: EnOssan_HandleCanBuyItem(globalCtx, this); @@ -1034,7 +1069,7 @@ void EnOssan_SelectItem(EnOssan* this, GlobalContext* globalCtx) { } void EnOssan_CannotBuy(EnOssan* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->actionFunc = this->tmpActionFunc; func_80151938(globalCtx, this->items[this->cursorIdx]->actor.textId); } @@ -1043,7 +1078,7 @@ void EnOssan_CannotBuy(EnOssan* this, GlobalContext* globalCtx) { void EnOssan_CanBuy(EnOssan* this, GlobalContext* globalCtx) { EnGirlA* item; - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->shopItemSelectedTween = 0.0f; EnOssan_ResetItemPosition(this); item = this->items[this->cursorIdx]; @@ -1058,13 +1093,13 @@ void EnOssan_BuyItemWithFanfare(EnOssan* this, GlobalContext* globalCtx) { this->actor.parent = NULL; EnOssan_SetupAction(this, EnOssan_SetupItemPurchased); } else { - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); } } void EnOssan_SetupItemPurchased(EnOssan* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; EnOssan_SetupAction(this, EnOssan_ItemPurchased); if (this->cutsceneState == ENOSSAN_CUTSCENESTATE_STOPPED) { @@ -1074,18 +1109,18 @@ void EnOssan_SetupItemPurchased(EnOssan* this, GlobalContext* globalCtx) { this->cutscene = this->lookToShopkeeperCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); } - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } void EnOssan_ContinueShopping(EnOssan* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); EnGirlA* item; if (talkState == 4) { func_8011552C(globalCtx, 6); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnOssan_ResetItemPosition(this); item = this->items[this->cursorIdx]; item->restockFunc(globalCtx, item); @@ -1095,9 +1130,9 @@ void EnOssan_ContinueShopping(EnOssan* this, GlobalContext* globalCtx) { func_8019F208(); player->actor.shape.rot.y = BINANG_ROT180(player->actor.shape.rot.y); player->stateFlags2 |= 0x20000000; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); EnOssan_SetupStartShopping(globalCtx, this, true); - func_800B85E0(&this->actor, globalCtx, 100.0f, -1); + func_800B85E0(&this->actor, globalCtx, 100.0f, EXCH_ITEM_MINUS1); break; case 1: default: @@ -1107,15 +1142,15 @@ void EnOssan_ContinueShopping(EnOssan* this, GlobalContext* globalCtx) { } } } - } else if (talkState == 5 && func_80147624(globalCtx)) { + } else if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { EnOssan_ResetItemPosition(this); item = this->items[this->cursorIdx]; item->restockFunc(globalCtx, item); player->actor.shape.rot.y = BINANG_ROT180(player->actor.shape.rot.y); player->stateFlags2 |= 0x20000000; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); EnOssan_SetupStartShopping(globalCtx, this, true); - func_800B85E0(&this->actor, globalCtx, 100.0f, -1); + func_800B85E0(&this->actor, globalCtx, 100.0f, EXCH_ITEM_MINUS1); } } @@ -1136,10 +1171,10 @@ void EnOssan_ItemPurchased(EnOssan* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80151938(globalCtx, 0x642); } else { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } @@ -1242,10 +1277,7 @@ void EnOssan_UpdateCursorAnim(EnOssan* this) { void EnOssan_UpdateStickDirectionPromptAnim(EnOssan* this) { f32 arrowAnimTween = this->arrowAnimTween; f32 stickAnimTween = this->stickAnimTween; - - // Possibly Fake - s32 maxColor = 255; - f32 tmp; + s32 maxColor = 255; //! FAKE: if (this->arrowAnimState == 0) { arrowAnimTween += 0.05f; @@ -1272,31 +1304,33 @@ void EnOssan_UpdateStickDirectionPromptAnim(EnOssan* this) { stickAnimTween = 0.0f; this->stickAnimState = 0; } - - tmp = 155.0f * arrowAnimTween; - this->stickAnimTween = stickAnimTween; this->stickLeftPrompt.arrowColor.r = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.g = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); - this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100, arrowAnimTween); + this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowColor.r = (maxColor - ((s32)tmp)) & 0xFF; - this->stickRightPrompt.arrowColor.g = (255 - ((s32)tmp)) & 0xFF; + this->stickRightPrompt.arrowTexX = 290.0f; + + this->stickRightPrompt.arrowColor.r = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); + this->stickRightPrompt.arrowColor.g = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowTexX = 290.0f; this->stickLeftPrompt.arrowTexX = 33.0f; this->stickRightPrompt.stickTexX = 274.0f; this->stickRightPrompt.stickTexX += 8.0f * stickAnimTween; + this->stickLeftPrompt.stickTexX = 49.0f; this->stickLeftPrompt.stickTexX -= 8.0f * stickAnimTween; - this->stickLeftPrompt.arrowTexY = this->stickRightPrompt.arrowTexY = 91.0f; - this->stickLeftPrompt.stickTexY = this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + + this->stickRightPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.stickTexY = 95.0f; } void EnOssan_WaitForBlink(EnOssan* this) { @@ -1328,50 +1362,52 @@ void EnOssan_Blink(EnOssan* this) { } } -void EnOssan_InitCuriosityShopMan(EnOssan* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013320, &D_06012C34, this->jointTable, this->morphTable, 19); - this->actor.draw = EnOssan_DrawCuriosityShopMan; +void EnOssan_CuriosityShopMan_Init(EnOssan* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFsnSkel, &gFsnIdleAnim, this->jointTable, this->morphTable, + ENOSSAN_LIMB_MAX); + this->actor.draw = EnOssan_CuriosityShopMan_Draw; } -void EnOssan_InitPartTimeWorker(EnOssan* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060028A0, &D_06009D34, this->jointTable, this->morphTable, 16); - this->actor.draw = EnOssan_DrawPartTimeWorker; +void EnOssan_PartTimeWorker_Init(EnOssan* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gAniSkeleton, &gAniStandingNormalAnim, this->jointTable, + this->morphTable, 16); + this->actor.draw = EnOssan_PartTimeWorker_Draw; } -u16 EnOssan_GetWelcomeCuriosityShopMan(EnOssan* this, GlobalContext* globalCtx) { +u16 EnOssan_CuriosityShopMan_GetWelcome(EnOssan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); u16 textId = Text_GetFaceReaction(globalCtx, 0x2F); if (textId != 0) { - this->animationIdx = 4; + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_START; this->flags |= END_INTERACTION; return textId; } switch (player->transformation) { case PLAYER_FORM_DEKU: - this->animationIdx = 10; - if (gSaveContext.weekEventReg[0x12] & 0x10) { + this->animationIndex = FSN_ANIMATION_SLAM_COUNTER_START; + if (gSaveContext.save.weekEventReg[18] & 0x10) { return sWelcomeDekuTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; } return sWelcomeDekuFirstTimeTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; case PLAYER_FORM_ZORA: - this->animationIdx = 8; - if (gSaveContext.weekEventReg[0x12] & 8) { + this->animationIndex = FSN_ANIMATION_LEAN_FORWARD_START; + if (gSaveContext.save.weekEventReg[18] & 8) { return sWelcomeZoraTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; } return sWelcomeZoraFirstTimeTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; case PLAYER_FORM_GORON: - this->animationIdx = 6; - if (gSaveContext.weekEventReg[0x12] & 4) { + this->animationIndex = FSN_ANIMATION_HAND_ON_FACE_START; + if (gSaveContext.save.weekEventReg[18] & 4) { return sWelcomeGoronTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; } return sWelcomeGoronFirstTimeTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; } - this->animationIdx = 4; + this->animationIndex = FSN_ANIMATION_HANDS_ON_COUNTER_START; return sWelcomeHumanTextIds[ENOSSAN_CURIOSITY_SHOP_MAN]; } -u16 EnOssan_GetWelcomePartTimeWorker(EnOssan* this, GlobalContext* globalCtx) { +u16 EnOssan_PartTimerWorker_GetWelcome(EnOssan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); u16 textId = Text_GetFaceReaction(globalCtx, 0x36); @@ -1381,17 +1417,17 @@ u16 EnOssan_GetWelcomePartTimeWorker(EnOssan* this, GlobalContext* globalCtx) { } switch (player->transformation) { case PLAYER_FORM_DEKU: - if (gSaveContext.weekEventReg[0x37] & 0x10) { + if (gSaveContext.save.weekEventReg[55] & 0x10) { return sWelcomeDekuTextIds[ENOSSAN_PART_TIME_WORKER]; } return sWelcomeDekuFirstTimeTextIds[ENOSSAN_PART_TIME_WORKER]; case PLAYER_FORM_ZORA: - if (gSaveContext.weekEventReg[0x37] & 8) { + if (gSaveContext.save.weekEventReg[55] & 8) { return sWelcomeZoraTextIds[ENOSSAN_PART_TIME_WORKER]; } return sWelcomeZoraFirstTimeTextIds[ENOSSAN_PART_TIME_WORKER]; case PLAYER_FORM_GORON: - if (gSaveContext.weekEventReg[0x37] & 4) { + if (gSaveContext.save.weekEventReg[55] & 4) { return sWelcomeGoronTextIds[ENOSSAN_PART_TIME_WORKER]; } return sWelcomeGoronFirstTimeTextIds[ENOSSAN_PART_TIME_WORKER]; @@ -1402,36 +1438,36 @@ u16 EnOssan_GetWelcomePartTimeWorker(EnOssan* this, GlobalContext* globalCtx) { void EnOssan_SetHaveMet(EnOssan* this) { switch (this->textId) { case 0x06A9: - gSaveContext.weekEventReg[0x12] |= 0x10; + gSaveContext.save.weekEventReg[18] |= 0x10; break; case 0x06C6: - gSaveContext.weekEventReg[0x37] |= 0x10; + gSaveContext.save.weekEventReg[55] |= 0x10; break; case 0x06A7: - gSaveContext.weekEventReg[0x12] |= 8; + gSaveContext.save.weekEventReg[18] |= 8; break; case 0x06C4: - gSaveContext.weekEventReg[0x37] |= 8; + gSaveContext.save.weekEventReg[55] |= 8; break; case 0x06A5: - gSaveContext.weekEventReg[0x12] |= 4; + gSaveContext.save.weekEventReg[18] |= 4; break; case 0x06C2: - gSaveContext.weekEventReg[0x37] |= 4; + gSaveContext.save.weekEventReg[55] |= 4; break; } } void EnOssan_InitShop(EnOssan* this, GlobalContext* globalCtx) { - static EnOssanActionFunc sInitFuncs[] = { EnOssan_InitCuriosityShopMan, EnOssan_InitPartTimeWorker }; + static EnOssanActionFunc sInitFuncs[] = { EnOssan_CuriosityShopMan_Init, EnOssan_PartTimeWorker_Init }; ShopItem* shopItems; if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { - this->actor.flags &= ~0x10; + this->actor.flags &= ~ACTOR_FLAG_10; this->actor.objBankIndex = this->objIndex; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); shopItems = sShops[this->actor.params]; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); sInitFuncs[this->actor.params](this, globalCtx); this->textId = sWelcomeHumanTextIds[this->actor.params]; EnOssan_GetCutscenes(this, globalCtx); @@ -1488,14 +1524,15 @@ void EnOssan_InitShop(EnOssan* this, GlobalContext* globalCtx) { this->arrowAnimTween = 0.0f; this->stickAnimTween = 0.0f; this->shopItemSelectedTween = 0.0f; + Actor_SetScale(&this->actor, sActorScales[this->actor.params]); - this->animationIdx = 1; - func_8013BC6C(&this->skelAnime, sAnimations[this->actor.params], 1); + this->animationIndex = 1; // FSN_ANIMATION_SCRATCH_BACK and ANI_ANIMATION_STANDING_NORMAL_LOOP_2 + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations[this->actor.params], 1); EnOssan_SpawnShopItems(this, globalCtx, shopItems); this->blinkTimer = 20; this->eyeTexIndex = 0; this->blinkFunc = EnOssan_WaitForBlink; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; EnOssan_SetupAction(this, EnOssan_Idle); } } @@ -1518,7 +1555,7 @@ void EnOssan_Update(Actor* thisx, GlobalContext* globalCtx) { EnOssan_UpdateCursorAnim(this); func_800E9250(globalCtx, &this->actor, &this->headRot, &this->unk2CC, this->actor.focus.pos); this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, 90.0f); + Actor_SetFocus(&this->actor, 90.0f); SkelAnime_Update(&this->skelAnime); } else { this->actionFunc(this, globalCtx); @@ -1526,18 +1563,21 @@ void EnOssan_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnOssan_DrawCursor(GlobalContext* globalCtx, EnOssan* this, f32 x, f32 y, f32 z, u8 drawCursor) { - s32 ulx, uly, lrx, lry; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; f32 w; s32 dsdx; - ((void)"../z_en_oB1.c"); // Unreferenced + (void)"../z_en_oB1.c"; OPEN_DISPS(globalCtx->state.gfxCtx); if (drawCursor != 0) { func_8012C654(globalCtx->state.gfxCtx); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, this->cursorColor.r, this->cursorColor.g, this->cursorColor.b, this->cursorColor.a); - gDPLoadTextureBlock_4b(OVERLAY_DISP++, &D_0401F740, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, + gDPLoadTextureBlock_4b(OVERLAY_DISP++, gSelectionCursorTex, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD); w = 16.0f * z; ulx = (x - w) * 4.0f; @@ -1553,11 +1593,16 @@ void EnOssan_DrawCursor(GlobalContext* globalCtx, EnOssan* this, f32 x, f32 y, f void EnOssan_DrawTextRec(GlobalContext* globalCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t, f32 dx, f32 dy) { f32 unk; - s32 ulx, uly, lrx, lry; - f32 w, h; - s32 dsdx, dtdy; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; + f32 w; + f32 h; + s32 dsdx; + s32 dtdy; - ((void)"../z_en_oB1.c"); // Unreferenced + (void)"../z_en_oB1.c"; OPEN_DISPS(globalCtx->state.gfxCtx); gDPPipeSync(OVERLAY_DISP++); @@ -1583,21 +1628,15 @@ void EnOssan_DrawStickDirectionPrompts(GlobalContext* globalCtx, EnOssan* this) s32 drawStickRightPrompt = this->stickLeftPrompt.isEnabled; s32 drawStickLeftPrompt = this->stickRightPrompt.isEnabled; - ((void)"../z_en_oB1.c"); // Unreferenced + (void)"../z_en_oB1.c"; OPEN_DISPS(globalCtx->state.gfxCtx); if (drawStickRightPrompt || drawStickLeftPrompt) { func_8012C654(globalCtx->state.gfxCtx); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F8C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 191, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 23 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnOssan_DrawTextRec(globalCtx, this->stickLeftPrompt.arrowColor.r, this->stickLeftPrompt.arrowColor.g, this->stickLeftPrompt.arrowColor.b, this->stickLeftPrompt.arrowColor.a, @@ -1610,15 +1649,9 @@ void EnOssan_DrawStickDirectionPrompts(GlobalContext* globalCtx, EnOssan* this) this->stickRightPrompt.arrowTexX, this->stickRightPrompt.arrowTexY, this->stickRightPrompt.texZ, 0, 0, 1.0f, 1.0f); } - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F7C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 127, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 15 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnOssan_DrawTextRec(globalCtx, this->stickLeftPrompt.stickColor.r, this->stickLeftPrompt.stickColor.g, this->stickLeftPrompt.stickColor.b, this->stickLeftPrompt.stickColor.a, @@ -1635,72 +1668,73 @@ void EnOssan_DrawStickDirectionPrompts(GlobalContext* globalCtx, EnOssan* this) CLOSE_DISPS(globalCtx->state.gfxCtx); } -s32 EnOssan_OverrideLimbDrawCuriosityShopMan(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, - Vec3s* rot, Actor* thisx) { +s32 EnOssan_CuriosityShopMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, + Vec3s* rot, Actor* thisx) { EnOssan* this = THIS; - if (limbIndex == 16) { - Matrix_InsertXRotation_s(this->headRot.y, MTXMODE_APPLY); + if (limbIndex == FSN_LIMB_HEAD) { + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); } return false; } -s32 EnOssan_OverrideLimbDrawPartTimeWorker(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, +s32 EnOssan_PartTimeWorker_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, + Vec3s* rot, Actor* thisx) { + EnOssan* this = THIS; + + if (limbIndex == ANI_LIMB_HEAD) { + Matrix_RotateXS(this->headRotPartTimeWorker.y, MTXMODE_APPLY); + Matrix_RotateZS(this->headRotPartTimeWorker.x, MTXMODE_APPLY); + } + return false; +} + +void EnOssan_CuriosityShopMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnOssan* this = THIS; - if (limbIndex == 15) { - Matrix_InsertXRotation_s(this->headRotPartTimeWorker.y, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->headRotPartTimeWorker.x, MTXMODE_APPLY); - } - return false; -} - -void EnOssan_PostLimbDrawCuriosityShopMan(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - Actor* thisx) { - EnOssan* this = THIS; - - if (limbIndex == 1 || limbIndex == 9 || limbIndex == 12) { + if (limbIndex == FSN_LIMB_PELVIS || limbIndex == FSN_LIMB_LEFT_UPPER_ARM || limbIndex == FSN_LIMB_RIGHT_UPPER_ARM) { rot->y += (s16)Math_SinS(this->limbRotTableY[limbIndex]) * 200; rot->z += (s16)Math_CosS(this->limbRotTableZ[limbIndex]) * 200; } } -void EnOssan_PostLimbDrawPartTimeWorker(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, - Actor* thisx) { +void EnOssan_PartTimeWorker_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + Actor* thisx) { static Vec3f sPartTimeWorkerFocusOffset = { 800.0f, 500.0f, 0.0f }; EnOssan* this = THIS; - if (limbIndex == 15) { - Matrix_MultiplyVector3fByState(&sPartTimeWorkerFocusOffset, &this->actor.focus.pos); + if (limbIndex == ANI_LIMB_HEAD) { + Matrix_MultVec3f(&sPartTimeWorkerFocusOffset, &this->actor.focus.pos); } } -void EnOssan_DrawCuriosityShopMan(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sEyeTextures[] = { &D_06005BC0, &D_06006D40, &D_06007140 }; - EnOssan* this = THIS; +void EnOssan_CuriosityShopMan_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sEyeTextures[] = { gFsnEyeOpenTex, gFsnEyeHalfTex, gFsnEyeClosedTex }; s32 pad; + EnOssan* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTexIndex])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnOssan_OverrideLimbDrawCuriosityShopMan, EnOssan_PostLimbDrawCuriosityShopMan, &this->actor); + EnOssan_CuriosityShopMan_OverrideLimbDraw, EnOssan_CuriosityShopMan_PostLimbDraw, + &this->actor); EnOssan_DrawCursor(globalCtx, this, this->cursorPos.x, this->cursorPos.y, this->cursorPos.z, this->drawCursor); EnOssan_DrawStickDirectionPrompts(globalCtx, this); CLOSE_DISPS(globalCtx->state.gfxCtx); } -void EnOssan_DrawPartTimeWorker(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sEyeTextures[] = { &D_06006498, &D_06006B18, &D_06006F18 }; - EnOssan* this = THIS; +void EnOssan_PartTimeWorker_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sEyeTextures[] = { gAniOpenEyeTex, gAniClosingEyeTex, gAniClosedEyeTex }; s32 pad; + EnOssan* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTexIndex])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnOssan_OverrideLimbDrawPartTimeWorker, EnOssan_PostLimbDrawPartTimeWorker, &this->actor); + EnOssan_PartTimeWorker_OverrideLimbDraw, EnOssan_PartTimeWorker_PostLimbDraw, &this->actor); EnOssan_DrawCursor(globalCtx, this, this->cursorPos.x, this->cursorPos.y, this->cursorPos.z, this->drawCursor); EnOssan_DrawStickDirectionPrompts(globalCtx, this); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h index 53f8b8f39..58c638d8e 100644 --- a/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h +++ b/src/overlays/actors/ovl_En_Ossan/z_en_ossan.h @@ -2,8 +2,11 @@ #define Z_EN_OSSAN_H #include "global.h" - #include "overlays/actors/ovl_En_GirlA/z_en_girla.h" +#include "objects/object_ani/object_ani.h" +#include "objects/object_fsn/object_fsn.h" + +#define ENOSSAN_LIMB_MAX MAX(FSN_LIMB_MAX + 1, ANI_LIMB_MAX) struct EnOssan; @@ -50,9 +53,9 @@ typedef struct EnOssan { /* 0x2CC */ Vec3s unk2CC; // Set but never used /* 0x2D2 */ s16 limbRotTableY[19]; /* 0x2F8 */ s16 limbRotTableZ[19]; - /* 0x31E */ Vec3s jointTable[19]; - /* 0x390 */ Vec3s morphTable[19]; - /* 0x402 */ s16 animationIdx; + /* 0x31E */ Vec3s jointTable[ENOSSAN_LIMB_MAX]; + /* 0x390 */ Vec3s morphTable[ENOSSAN_LIMB_MAX]; + /* 0x402 */ s16 animationIndex; /* 0x404 */ Vec3s headRotPartTimeWorker; /* 0x40A */ u16 flags; } EnOssan; // size = 0x40C @@ -68,12 +71,6 @@ typedef enum { /* 1 */ ENOSSAN_PART_TIME_WORKER } EnOssanWorker; -typedef enum { - /* 0 */ ENOSSAN_CUTSCENESTATE_STOPPED, - /* 1 */ ENOSSAN_CUTSCENESTATE_WAITING, - /* 2 */ ENOSSAN_CUTSCENESTATE_PLAYING -} EnOssanCutsceneState; - extern const ActorInit En_Ossan_InitVars; #endif // Z_EN_OSSAN_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 1744e5ddf..8ef3e1bfc 100644 --- a/src/overlays/actors/ovl_En_Ot/z_en_ot.c +++ b/src/overlays/actors/ovl_En_Ot/z_en_ot.c @@ -1,6 +1,15 @@ -#include "z_en_ot.h" +/* + * File: z_en_ot.c + * Overlay: ovl_En_Ot + * Description: Seahorse + */ -#define FLAGS 0x00000019 +#include "z_en_ot.h" +#include "prevent_bss_reordering.h" +#include "objects/object_ot/object_ot.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnOt*)thisx) @@ -9,26 +18,51 @@ void EnOt_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnOt_Update(Actor* thisx, GlobalContext* globalCtx); void EnOt_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B5BDA8(EnOt* this, GlobalContext* globalCtx); void func_80B5BE04(EnOt* this, GlobalContext* globalCtx); +void func_80B5BE88(EnOt* this, GlobalContext* globalCtx); void func_80B5BED4(EnOt* this, GlobalContext* globalCtx); +void func_80B5BF60(EnOt* this, GlobalContext* globalCtx); void func_80B5BFB8(EnOt* this, GlobalContext* globalCtx); void func_80B5C1CC(EnOt* this, GlobalContext* globalCtx); +void func_80B5C244(EnOt* this, GlobalContext* globalCtx); void func_80B5C25C(EnOt* this, GlobalContext* globalCtx); +void func_80B5C3B8(EnOt* this, GlobalContext* globalCtx); void func_80B5C3D8(EnOt* this, GlobalContext* globalCtx); +void func_80B5C634(EnOt* this, GlobalContext* globalCtx); void func_80B5C64C(EnOt* this, GlobalContext* globalCtx); +void func_80B5C684(EnOt* this, GlobalContext* globalCtx); void func_80B5C6DC(EnOt* this, GlobalContext* globalCtx); +void func_80B5C910(EnOt* this, GlobalContext* globalCtx); void func_80B5C950(EnOt* this, GlobalContext* globalCtx); +void func_80B5C9A8(EnOt* this, GlobalContext* globalCtx); void func_80B5C9C0(EnOt* this, GlobalContext* globalCtx); +void func_80B5C9D0(EnOt* this, GlobalContext* globalCtx); void func_80B5CA30(EnOt* this, GlobalContext* globalCtx); +void func_80B5CAD0(EnOt* this, GlobalContext* globalCtx); void func_80B5CB0C(EnOt* this, GlobalContext* globalCtx); void func_80B5CBEC(EnOt* this, GlobalContext* globalCtx); +void func_80B5CC88(EnOt* this, GlobalContext* globalCtx); void func_80B5CCA0(EnOt* this, GlobalContext* globalCtx); +void func_80B5CCF4(EnOt* this, GlobalContext* globalCtx); void func_80B5CD40(EnOt* this, GlobalContext* globalCtx); +void func_80B5CE6C(EnOt* this, GlobalContext* globalCtx); void func_80B5CEC8(EnOt* this, GlobalContext* globalCtx); +void func_80B5D114(EnOt* this, GlobalContext* globalCtx); void func_80B5D160(EnOt* this, GlobalContext* globalCtx); +void func_80B5D648(EnOt* this, GlobalContext* globalCtx); void func_80B5D750(EnOt* this, GlobalContext* globalCtx); +void func_80B5DAEC(Actor* thisx, GlobalContext* globalCtx); +void func_80B5DB6C(Actor* thisx, GlobalContext* globalCtx); +void EnOt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx); +EnOtUnkStruct* func_80B5DF58(EnOtUnkStruct* arg0, u8 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4); +void func_80B5E078(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2); +void func_80B5E1D8(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2); + +static EnOt* D_80B5E880; +static EnOt* D_80B5E884; +static EnOt* D_80B5E888; -#if 0 const ActorInit En_Ot_InitVars = { ACTOR_EN_OT, ACTORCAT_NPC, @@ -41,128 +75,1089 @@ const ActorInit En_Ot_InitVars = { (ActorFunc)EnOt_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B5E3A0 = { - { COLTYPE_HIT0, AT_NONE, AC_ON | 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_HIT0, + AT_NONE, + AC_ON | 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, + }, { 5, 33, -20, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B5E3FC[] = { +static AnimationSpeedInfo sAnimations[] = { + { &object_ot_Anim_004B30, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_ot_Anim_0008D8, 1.0f, ANIMMODE_LOOP, -5.0f }, + { &object_ot_Anim_000420, 1.0f, ANIMMODE_LOOP, 0.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 80, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 80, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_STOP), }; -#endif +void func_80B5B2E0(GlobalContext* globalCtx, Vec3f* pos, s16 params, Vec3f* vec, s32* index) { + s32 i; + Path* path = &globalCtx->setupPathList[params]; + f32 dist; + Vec3f sp58; + Vec3f sp4C; + f32 minDist = FLT_MAX; -extern ColliderCylinderInit D_80B5E3A0; -extern InitChainEntry D_80B5E3FC[]; + for (i = 0; i < path->count; i++) { + Math_Vec3s_ToVec3f(&sp58, &((Vec3s*)Lib_SegmentedToVirtual(path->points))[i]); + dist = Math_Vec3f_DistXYZ(pos, &sp58); + if (dist < minDist) { + minDist = dist; + Math_Vec3f_Copy(&sp4C, &sp58); + *index = i; + } + } -extern UNK_TYPE D_06000078; -extern UNK_TYPE D_060004A0; -extern UNK_TYPE D_060005F8; -extern UNK_TYPE D_060008D8; + Math_Vec3f_Copy(vec, &sp4C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5B2E0.s") +void EnOt_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOt* this = THIS; + s32 bgId; + s32 pad2; + Vec3f sp64; + Vec3f sp58; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/EnOt_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_388 = 0; + this->unk_33C = ENOT_GET_C000(&this->actor); + if (this->unk_33C == 0) { + D_80B5E880 = this; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.update = func_80B5DB6C; + this->actor.draw = NULL; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/EnOt_Destroy.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ot_Skel_004800, &object_ot_Anim_0008D8, this->jointTable, + this->morphTable, 19); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Animation_Change(&this->skelAnime, sAnimations[0].animation, 1.0f, + Animation_GetLastFrame(&sAnimations[0].animation->common) * Rand_ZeroOne(), + Animation_GetLastFrame(&sAnimations[0].animation->common), sAnimations[0].mode, + sAnimations[0].morphFrames); + this->unk_346 = ENOT_GET_7F(&this->actor); + this->unk_344 = this->actor.world.rot.z; + this->actor.world.rot.z = 0; + this->actor.shape.rot.z = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.gravity = 0.0f; + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->skelAnime.curFrame = Rand_ZeroOne() * this->skelAnime.endFrame; + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); + this->unk_744.r = 255; + this->unk_744.g = 200; + this->unk_744.b = 80; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BAAC.s") + switch (ENOT_GET_C000(&this->actor)) { + case 1: + D_80B5E884 = this; + Actor_SetScale(&this->actor, 0.012999999f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BB38.s") + switch (this->unk_344) { + case 0: + this->actor.world.pos.y = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &this->actor.floorPoly, + &bgId, &this->actor.world.pos) + + 50.0f; + if (gSaveContext.save.weekEventReg[84] & 0x10) { + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(52.519997f, &sp64); + Math_Vec3f_Sum(&this->actor.world.pos, &sp64, &sp64); + this->unk_360 = (EnOt*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_OT, sp64.x, sp64.y, + sp64.z, 0, BINANG_ROT180(this->actor.shape.rot.y), 1, + ENOT_GET_3FFF(&this->actor) | 0x8000); + if (this->unk_360 != NULL) { + this->unk_360->unk_360 = this; + this->unk_3A0 = 0; + this->unk_360->unk_3A0 = BINANG_ROT180(this->unk_3A0); + this->unk_394.x = (this->actor.world.pos.x + this->unk_360->actor.world.pos.x) * 0.5f; + this->unk_394.y = this->actor.world.pos.y; + this->unk_394.z = (this->actor.world.pos.z + this->unk_360->actor.world.pos.z) * 0.5f; + Math_Vec3f_Copy(&this->unk_360->unk_394, &this->unk_394); + if (gSaveContext.save.weekEventReg[32] & 1) { + func_80B5C244(this, globalCtx); + } else { + func_80B5C684(this, globalCtx); + } + } else { + Actor_MarkForDeath(&this->actor); + } + } else if ((D_80B5E888 != NULL) && (D_80B5E888->unk_32C & 1)) { + this->unk_360 = D_80B5E888; + this->unk_360->unk_360 = this; + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(800.0f, &sp58); + Math_Vec3f_Sum(&this->actor.world.pos, &sp58, &sp58); + Math_Vec3f_Copy(&this->unk_360->actor.world.pos, &sp58); + Math_Vec3f_Copy(&this->unk_360->actor.prevPos, &sp58); + func_80B5BDA8(this, globalCtx); + func_80B5BE88(this->unk_360, globalCtx); + } else { + func_80B5CE6C(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BDA8.s") + case 1: + Actor_MarkForDeath(&this->actor); + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BE04.s") + case 2: + D_80B5E888 = this; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BE88.s") + switch (this->unk_344) { + case 0: + Actor_SetScale(&this->actor, 0.0f); + if (!(gSaveContext.save.weekEventReg[13] & 1)) { + Actor_SetScale(&this->actor, 0.0f); + func_80B5C910(this, globalCtx); + } else { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BED4.s") + if (SurfaceType_IsHorseBlocked(&globalCtx->colCtx, player->actor.floorPoly, + player->actor.floorBgId)) { + Actor_SetScale(&this->actor, 0.0f); + func_80B5C910(this, globalCtx); + } else { + this->unk_360 = D_80B5E884; + this->unk_360->unk_360 = this; + func_80B5C9D0(this, globalCtx); + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BF60.s") + case 1: + Actor_SetScale(&this->actor, 0.012999999f); + if (gSaveContext.save.weekEventReg[84] & 0x10) { + if (gSaveContext.save.weekEventReg[32] & 1) { + func_80B5C244(this, globalCtx); + } else { + func_80B5C684(this, globalCtx); + } + } else { + func_80B5CE6C(this, globalCtx); + } + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5BFB8.s") + case 3: + if (!(gSaveContext.save.weekEventReg[26] & 8)) { + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + Actor_SetScale(&this->actor, 0.0064999997f); + this->collider.dim.radius *= 0.5f; + this->collider.dim.height *= 0.5f; + this->collider.dim.yShift *= 0.5f; + this->actor.update = func_80B5DAEC; + func_80B5C634(this, globalCtx); + } else { + Actor_MarkForDeath(&this->actor); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C154.s") +void EnOt_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnOt* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C1CC.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C244.s") +void func_80B5BAAC(LightInfo* lightInfo, Vec3f* arg1, Color_RGB8* arg2, s16 radius) { + Lights_PointNoGlowSetInfo(lightInfo, arg1->x, arg1->y, arg1->z, arg2->r, arg2->g, arg2->b, radius); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C25C.s") +void func_80B5BB38(Color_RGB8* arg0, Color_RGB8* arg1, f32 arg2) { + f32 rand = Rand_ZeroOne(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C3B8.s") + arg0->r = (arg1->r * arg2) + (arg1->r * (1.0f - arg2) * rand); + arg0->g = (arg1->g * arg2) + (arg1->g * (1.0f - arg2) * rand); + arg0->b = (arg1->b * arg2) + (arg1->b * (1.0f - arg2) * rand); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C3D8.s") +void func_80B5BDA8(EnOt* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 1, &this->animIdx); + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); + this->actionFunc = func_80B5BE04; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C634.s") +void func_80B5BE04(EnOt* this, GlobalContext* globalCtx) { + switch (this->unk_388) { + case 0: + if (SubS_StartActorCutscene(&this->actor, this->cutscenes[2], -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + func_80B5BF60(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C64C.s") + case 1: + if (SubS_StartActorCutscene(&this->actor, this->cutscenes[3], -1, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + func_80B5BF60(this, globalCtx); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C684.s") +void func_80B5BE88(EnOt* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 1, &this->animIdx); + this->actionFunc = func_80B5BED4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C6DC.s") +void func_80B5BED4(EnOt* this, GlobalContext* globalCtx) { + func_800BE33C(&this->actor.world.pos, &this->unk_360->actor.world.pos, &this->actor.world.rot, 0); + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, &this->unk_360->actor), 3, 0xE38, + 0x38E); + this->actor.speedXZ = 3.5f; + this->actor.world.pos.y = this->unk_360->actor.world.pos.y; + Actor_MoveWithoutGravityReverse(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C910.s") +void func_80B5BF60(EnOt* this, GlobalContext* globalCtx) { + this->unk_32C |= 0x40; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->actionFunc = func_80B5BFB8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C950.s") +void func_80B5BFB8(EnOt* this, GlobalContext* globalCtx) { + Vec3f sp34; + f32 temp_f0 = this->actor.floorHeight + 50.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C9A8.s") + if (temp_f0 <= this->actor.world.pos.y) { + Math_StepToF(&this->actor.world.pos.y, temp_f0, 2.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C9C0.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, &this->unk_360->actor), 3, 0xE38, + 0x38E); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5C9D0.s") + if (Actor_DistanceBetweenActors(&this->actor, &this->unk_360->actor) <= 52.519997f) { + this->unk_73C = 50; + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(52.519997f, &sp34); + this->unk_360->actor.world.pos.x = this->actor.world.pos.x + sp34.x; + this->unk_360->actor.world.pos.y = this->actor.world.pos.y + sp34.y; + this->unk_360->actor.world.pos.z = this->actor.world.pos.z + sp34.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CA30.s") + this->unk_394.x = (this->unk_360->actor.world.pos.x + this->actor.world.pos.x) * 0.5f; + this->unk_394.y = (this->unk_360->actor.world.pos.y + this->actor.world.pos.y) * 0.5f; + this->unk_394.z = (this->unk_360->actor.world.pos.z + this->actor.world.pos.z) * 0.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CAD0.s") + this->unk_360->unk_394.x = this->unk_394.x; + this->unk_360->unk_394.y = this->unk_394.y; + this->unk_360->unk_394.z = this->unk_394.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CB0C.s") + func_80B5C684(this->unk_360, globalCtx); + func_80B5C684(this, globalCtx); + } else { + Actor_MoveWithoutGravityReverse(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CBA0.s") +void func_80B5C154(EnOt* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[32] & 1) { + this->unk_38C = GI_RUPEE_RED; + } else { + this->unk_38C = GI_HEART_PIECE; + gSaveContext.save.weekEventReg[32] |= 1; + } + Actor_PickUp(&this->actor, globalCtx, this->unk_38C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_80B5C1CC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CBEC.s") +void func_80B5C1CC(EnOt* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_80B5C244(this, globalCtx); + func_80B5C244(this->unk_360, globalCtx); + } else { + Actor_PickUp(&this->actor, globalCtx, this->unk_38C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CC88.s") +void func_80B5C244(EnOt* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B5C25C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CCA0.s") +void func_80B5C25C(EnOt* this, GlobalContext* globalCtx) { + this->unk_390 = Actor_YawBetweenActors(&this->actor, &this->unk_360->actor); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_390, 3, 0xE38, 0x38E); + if (BINANG_SUB(BINANG_ROT180(this->unk_360->actor.shape.rot.y), this->actor.shape.rot.y) < 0x38E) { + this->unk_32C |= 0x80; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CCF4.s") + if ((this->unk_33C == 2) && (this->unk_32C & 0x80) && (this->unk_360->unk_32C & 0x80)) { + this->unk_32C |= 0x100; + this->unk_360->unk_32C |= 0x100; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 2, &this->animIdx); + SubS_ChangeAnimationBySpeedInfo(&this->unk_360->skelAnime, sAnimations, 2, &this->unk_360->animIdx); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->unk_360->actor.flags |= ACTOR_FLAG_8000000; + this->unk_360->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + func_80B5C9A8(this->unk_360, globalCtx); + func_80B5C3B8(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CD40.s") +void func_80B5C3B8(EnOt* this, GlobalContext* globalCtx) { + this->unk_740 = 0.0f; + this->actionFunc = func_80B5C3D8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CE6C.s") +void func_80B5C3D8(EnOt* this, GlobalContext* globalCtx) { + static Color_RGB8 D_80B5E408 = { 255, 200, 80 }; + static Color_RGB8 D_80B5E40C = { 255, 60, 200 }; + s16 temp; + s32 pad; + Vec3f sp5C; + Vec3f sp50; + Vec3f sp44; + Vec3f sp38; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5CEC8.s") + this->unk_3A0 += 0x2D8; + Matrix_RotateYS(this->unk_3A0, MTXMODE_NEW); + Matrix_MultVecZ(26.259998f, &sp5C); + Matrix_MultVecZ(-26.259998f, &sp50); + this->unk_348.x = this->unk_394.x + sp5C.x; + this->unk_348.y = this->unk_394.y; + this->unk_348.z = this->unk_394.z + sp5C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D114.s") + this->unk_360->unk_348.x = this->unk_394.x + sp50.x; + this->unk_360->unk_348.y = this->unk_394.y; + this->unk_360->unk_348.z = this->unk_394.z + sp50.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D160.s") + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_348); + Math_Vec3f_Copy(&this->unk_360->actor.world.pos, &this->unk_360->unk_348); + temp = Actor_YawBetweenActors(&this->actor, &this->unk_360->actor); + this->actor.shape.rot.y = temp; + this->unk_360->actor.shape.rot.y = BINANG_ROT180(temp); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D37C.s") + if (this->unk_740 < 1.0f) { + Lib_LerpRGB(&D_80B5E408, &D_80B5E40C, this->unk_740, &this->unk_744); + Lib_LerpRGB(&D_80B5E408, &D_80B5E40C, this->unk_740, &this->unk_360->unk_744); + Math_StepToF(&this->unk_740, 1.0f, 0.05f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D470.s") + if (Animation_OnFrame(&this->skelAnime, 12.0f)) { + Matrix_RotateYS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)), MTXMODE_NEW); + sp38.x = 1.0f; + sp38.y = 8.1f; + sp38.z = 0.0f; + Matrix_MultVec3f(&sp38, &sp44); + Math_Vec3f_Sum(&this->unk_74C, &sp44, &sp44); + func_80B5DF58(this->unk_3A4, 1, &sp44, &this->actor.shape.rot, 10); + sp38.x = -1.0f; + sp38.y = 8.1f; + sp38.z = 0.0f; + Matrix_MultVec3f(&sp38, &sp44); + Math_Vec3f_Sum(&this->unk_74C, &sp44, &sp44); + func_80B5DF58(this->unk_3A4, 2, &sp44, &this->actor.shape.rot, 10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D648.s") +void func_80B5C634(EnOt* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B5C64C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5D750.s") +void func_80B5C64C(EnOt* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[26] & 8) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/EnOt_Update.s") +void func_80B5C684(EnOt* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->actionFunc = func_80B5C6DC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5DAEC.s") +void func_80B5C6DC(EnOt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + s16 sp3E; + Vec3f sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5DB6C.s") + sp3E = Actor_YawToPoint(&player->actor, &this->unk_394); + Matrix_RotateYS(BINANG_ADD(sp3E, 0x4000), MTXMODE_NEW); + if (this->unk_33C == 2) { + Matrix_MultVecZ(26.259998f, &sp30); + } else { + if (this->unk_73C == 0) { + gSaveContext.save.weekEventReg[84] |= 0x10; + switch (this->unk_388) { + case 0: + ActorCutscene_Stop(this->cutscenes[2]); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/EnOt_Draw.s") + case 1: + ActorCutscene_Stop(this->cutscenes[3]); + break; + } + this->unk_73C = -1; + } else { + this->unk_73C--; + } + Matrix_MultVecZ(-26.259998f, &sp30); + } + this->unk_348.x = this->unk_394.x + sp30.x; + this->unk_348.y = this->unk_394.y; + this->unk_348.z = this->unk_394.z + sp30.z; + Math_SmoothStepToF(&this->actor.world.pos.x, this->unk_348.x, 1.0f, 2.0f, 0.01f); + Math_SmoothStepToF(&this->actor.world.pos.z, this->unk_348.z, 1.0f, 2.0f, 0.01f); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0xE38, 0x38E); + if ((gSaveContext.save.weekEventReg[84] & 0x10) && (this->unk_33C == 1)) { + this->actor.textId = 0; + this->unk_384 = 1; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_3A0 = BINANG_ADD(sp3E, 0x4000); + this->unk_360->unk_3A0 = this->unk_3A0; + func_80B5C9A8(this, globalCtx); + func_80B5D114(this, globalCtx); + } else if ((player->actor.bgCheckFlags & 1) && !func_801242B4(player) && + (this->actor.xzDistToPlayer < 130.0f)) { + func_800B8614(&this->actor, globalCtx, 130.0f); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5DECC.s") +void func_80B5C910(EnOt* this, GlobalContext* globalCtx) { + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + // This is weird + this->actor.world.rot.x = this->actor.world.rot.x; + this->actor.world.rot.y = this->actor.world.rot.y; + this->actor.world.rot.z = this->actor.world.rot.z; + this->actionFunc = func_80B5C950; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5DF58.s") +void func_80B5C950(EnOt* this, GlobalContext* globalCtx) { + if (this->unk_32C & 8) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SEAHORSE_OUT_BOTTLE); + gSaveContext.save.weekEventReg[25] |= 4; + func_80B5CAD0(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5E078.s") +void func_80B5C9A8(EnOt* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B5C9C0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ot/func_80B5E1D8.s") +void func_80B5C9C0(EnOt* this, GlobalContext* globalCtx) { +} + +void func_80B5C9D0(EnOt* this, GlobalContext* globalCtx) { + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + // This is weird + this->actor.world.rot.x = this->actor.world.rot.x; + this->actor.world.rot.y = this->actor.world.rot.y; + this->actor.world.rot.z = this->actor.world.rot.z; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SEAHORSE_OUT_BOTTLE); + this->actionFunc = func_80B5CA30; +} + +void func_80B5CA30(EnOt* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->actor.scale.x, 0.012999999f, 0.7f, 0.0001f, 0.01f); + Actor_SetScale(&this->actor, this->actor.scale.x); + if (this->actor.scale.x == 0.012999999f) { + this->unk_360->unk_32C |= 0x1000; + this->unk_360->unk_360 = this; + func_80B5C9A8(this, globalCtx); + } +} + +void func_80B5CAD0(EnOt* this, GlobalContext* globalCtx) { + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes) / 2); + this->actionFunc = func_80B5CB0C; +} + +void func_80B5CB0C(EnOt* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->actor.scale.x, 0.012999999f, 0.7f, 0.0001f, 0.01f); + Actor_SetScale(&this->actor, this->actor.scale.x); + if (this->actor.scale.x == 0.012999999f) { + this->unk_32C |= 0x800; + func_80B5CE6C(this, globalCtx); + } +} + +void func_80B5CBA0(EnOt* this, GlobalContext* globalCtx) { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = func_80B5CBEC; +} + +void func_80B5CBEC(EnOt* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + func_80B5CC88(this, globalCtx); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0xE38, 0x38E); + this->actor.world.rot.y = this->actor.shape.rot.y; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + } +} + +void func_80B5CC88(EnOt* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B5CCA0; +} + +void func_80B5CCA0(EnOt* this, GlobalContext* globalCtx) { + if (SubS_StartActorCutscene(&this->actor, this->cutscenes[0], 0x7C, SUBS_CUTSCENE_NORMAL)) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 |= 0x20000000; + func_80B5CCF4(this, globalCtx); + } +} + +void func_80B5CCF4(EnOt* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->actionFunc = func_80B5CD40; +} + +void func_80B5CD40(EnOt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 temp; + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + temp = Math_SmoothStepToS(&this->actor.shape.rot.y, + BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), 3, 0xE38, 0x38E); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (1) {} + if (!temp) { + gSaveContext.save.weekEventReg[23] |= 0x10; + Message_StartTextbox(globalCtx, 0x1069, NULL); + } + break; + + case 1: + case 2: + case 3: + break; + + case 4: + case 5: + case 6: + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.currentTextId == 0x1069)) { + this->unk_32C |= 4; + ActorCutscene_Stop(this->cutscenes[0]); + player->stateFlags2 &= ~0x20000000; + func_80B5CE6C(this, globalCtx); + } + break; + } +} + +void func_80B5CE6C(EnOt* this, GlobalContext* globalCtx) { + this->unk_384 = 0; + this->unk_32C |= 0x20; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->actionFunc = func_80B5CEC8; +} + +void func_80B5CEC8(EnOt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + + this->actor.textId = 0; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80B5D114(this, globalCtx); + return; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0xE38, 0x38E); + if (this->unk_32C & 0x800) { + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + } else { + this->actor.flags &= ~ACTOR_FLAG_10000; + if ((player->actor.bgCheckFlags & 1) && !func_801242B4(player) && (this->actor.xzDistToPlayer < 130.0f)) { + func_800B8614(&this->actor, globalCtx, 130.0f); + } + } + + if (!(gSaveContext.save.weekEventReg[84] & 0x10) && (ENOT_GET_C000(&this->actor) == 1)) { + if ((fabsf(this->actor.xzDistToPlayer) <= 130.0f) && (fabsf(this->actor.playerHeightRel) <= 130.0f)) { + player->unk_B2B = 29; + } + + if ((D_80B5E888 != NULL) && (D_80B5E888->unk_32C & 1)) { + Vec3f sp2C; + + this->unk_360 = D_80B5E888; + this->unk_360->unk_360 = this; + Matrix_RotateYS(this->actor.home.rot.y, MTXMODE_NEW); + Matrix_MultVecZ(800.0f, &sp2C); + Math_Vec3f_Sum(&this->actor.world.pos, &sp2C, &this->unk_360->actor.world.pos); + Math_Vec3f_Copy(&this->unk_360->actor.prevPos, &this->unk_360->actor.world.pos); + this->unk_32C &= ~0x800; + this->unk_360->unk_32C &= ~0x800; + func_80B5BDA8(this, globalCtx); + func_80B5BE88(this->unk_360, globalCtx); + return; + } + } + + if (this->unk_32C & 0x1000) { + this->unk_388 = 1; + func_80B5BDA8(this, globalCtx); + func_80B5BE88(this->unk_360, globalCtx); + } +} + +void func_80B5D114(EnOt* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 0, &this->animIdx); + this->actionFunc = func_80B5D160; +} + +void func_80B5D160(EnOt* this, GlobalContext* globalCtx) { + u16 phi_a1; + s32 temp; + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + temp = Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0xE38, 0x38E); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (!temp) { + switch (this->unk_384) { + case 0: + if ((this->unk_33C != 1) && (this->unk_33C == 2)) { + if (this->unk_32C & 1) { + if (this->unk_32C & 4) { + phi_a1 = 0x106A; + } else { + phi_a1 = 0x1069; + } + } else if (Flags_GetSwitch(globalCtx, ENOT_GET_3F80(&this->actor))) { + if (gSaveContext.save.weekEventReg[23] & 0x10) { + phi_a1 = 0x106C; + } else { + phi_a1 = 0x106B; + } + } else { + phi_a1 = 0x1068; + } + } else { + phi_a1 = 0x10A5; + } + Message_StartTextbox(globalCtx, phi_a1, &this->actor); + func_80B5D114(this, globalCtx); + break; + + case 1: + Message_StartTextbox(globalCtx, 0x106D, &this->actor); + func_80B5D114(this, globalCtx); + break; + } + break; + } + break; + + case 1: + case 2: + case 3: + break; + + case 4: + case 5: + case 6: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + default: + case 0x1068: + case 0x106B: + case 0x106C: + func_80B5D648(this, globalCtx); + break; + + case 0x1069: + this->unk_32C |= 4; + + case 0x106A: + func_80B5CE6C(this, globalCtx); + break; + + case 0x10A5: + func_801477B4(globalCtx); + func_80B5CE6C(this, globalCtx); + break; + + case 0x106D: + func_801477B4(globalCtx); + func_80B5C154(this, globalCtx); + break; + } + } + break; + } +} + +s32 EnOt_ActorPathing_Move(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor* thisx = actorPath->actor; + EnOt* this = (EnOt*)thisx; + f32 sp24 = Math_CosS(-thisx->world.rot.x) * thisx->speedXZ; + f32 sp20 = gFramerateDivisorHalf; + + thisx->velocity.x = Math_SinS(thisx->world.rot.y) * sp24; + thisx->velocity.y = Math_SinS(-thisx->world.rot.x) * thisx->speedXZ; + thisx->velocity.z = Math_CosS(thisx->world.rot.y) * sp24; + + this->unk_330.x += (thisx->velocity.x * sp20) + thisx->colChkInfo.displacement.x; + this->unk_330.y += (thisx->velocity.y * sp20) + thisx->colChkInfo.displacement.y; + this->unk_330.z += (thisx->velocity.z * sp20) + thisx->colChkInfo.displacement.z; + + return false; +} + +s32 EnOt_ActorPathing_UpdateActorInfo(GlobalContext* globalCtx, ActorPathing* actorPath) { + Actor* thisx = actorPath->actor; + s32 ret = false; + s32 pad; + Vec3f sp50; + Vec3f sp44; + f32 temp; + s32 sp2C; + s32 sp30; + s32 sp34; + + thisx->gravity = 0.0f; + Math_SmoothStepToF(&thisx->speedXZ, 10.0f, 0.8f, 2.0f, 0.0f); + + sp50.x = actorPath->curPoint.x - thisx->world.pos.x; + sp50.y = actorPath->curPoint.y - thisx->world.pos.y; + sp50.z = actorPath->curPoint.z - thisx->world.pos.z; + + sp44.x = actorPath->curPoint.x - actorPath->prevPoint.x; + sp44.y = actorPath->curPoint.y - actorPath->prevPoint.y; + sp44.z = actorPath->curPoint.z - actorPath->prevPoint.z; + + temp = Math3D_Parallel(&sp50, &sp44); + if ((actorPath->distSqToCurPointXZ < SQ(thisx->speedXZ)) || (temp <= 0.0f)) { + ret = true; + } else { + temp = SQ(thisx->speedXZ) / actorPath->distSqToCurPoint; + sp34 = ABS(actorPath->rotToCurPoint.x - thisx->world.rot.x); + sp2C = (s32)(sp34 * temp) + 0xAAA; + + sp34 = ABS(actorPath->rotToCurPoint.y - thisx->world.rot.y); + + Math_SmoothStepToS(&thisx->world.rot.x, actorPath->rotToCurPoint.x, 1, sp2C, 0); + sp2C = (s32)(sp34 * temp) + 0xAAA; + Math_SmoothStepToS(&thisx->world.rot.y, actorPath->rotToCurPoint.y, 1, sp2C, 0); + Math_SmoothStepToS(&thisx->shape.rot.y, thisx->world.rot.y, 2, sp2C, 0); + } + + return ret; +} + +void func_80B5D648(EnOt* this, GlobalContext* globalCtx) { + func_80B5B2E0(globalCtx, &this->actor.world.pos, this->unk_346, &this->unk_348, &this->unk_340); + Math_Vec3f_Copy(&this->unk_330, &this->actor.world.pos); + SubS_ActorPathing_Init(globalCtx, &this->unk_330, &this->actor, &this->actorPath, globalCtx->setupPathList, + this->unk_346, 0, 0, this->unk_340, 0); + this->unk_32C = 0; + this->actorPath.pointOffset.x = 0.0f; + this->actorPath.pointOffset.y = 0.0f; + this->actorPath.pointOffset.z = 0.0f; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, sAnimations, 1, &this->animIdx); + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + Flags_SetSwitch(globalCtx, ENOT_GET_3F80(&this->actor)); + this->actionFunc = func_80B5D750; +} + +void func_80B5D750(EnOt* this, GlobalContext* globalCtx) { + if (!(this->unk_32C & 1) && !(this->unk_32C & 2)) { + SubS_ActorPathing_Update(globalCtx, &this->actorPath, SubS_ActorPathing_ComputePointInfo, + EnOt_ActorPathing_UpdateActorInfo, EnOt_ActorPathing_Move, + SubS_ActorPathing_SetNextPoint); + } + + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_330); + + if (this->actorPath.flags & ACTOR_PATHING_REACHED_POINT_TEMPORARY) { + this->unk_32C |= 2; + } + + if (this->actorPath.flags & ACTOR_PATHING_REACHED_END_TEMPORARY) { + this->unk_32C |= 1; + } + + if ((this->unk_32C & 2) && (this->actor.xyzDistToPlayerSq <= SQ(120.0f))) { + this->unk_32C &= ~2; + } + + if ((this->unk_32C & 1) && (this->actor.xzDistToPlayer <= 180.0f)) { + this->actor.flags &= ~ACTOR_FLAG_8000000; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + if (D_80B5E884 != 0) { + func_80B5C9A8(this, globalCtx); + } else { + func_80B5CBA0(this, globalCtx); + } + } +} + +void EnOt_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOt* this = THIS; + + if ((this->animIdx == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SEAHORSE_SWIM); + } + + this->actionFunc(this, globalCtx); + if (this->actor.bgCheckFlags & 0x20) { + if (DECR(this->unk_354) == 0) { + if (this->actor.flags & ACTOR_FLAG_40) { + s32 i; + + for (i = 0; i < 2; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, 20.0f, 5.0f, 0.1f); + } + this->unk_354 = (Rand_ZeroOne() * 10.0f) + 10.0f; + } + } + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 10.0f, 0.0f, 4); + + if (this->actor.world.pos.y <= this->actor.floorHeight + 50.0f) { + this->actor.world.pos.y = this->actor.floorHeight + 50.0f; + this->actor.prevPos.y = this->actor.floorHeight + 50.0f; + } + + Actor_SetFocus(&this->actor, 12.0f); + SkelAnime_Update(&this->skelAnime); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + func_80B5BB38(&this->unk_747, &this->unk_744, 0.7f); + + if (this->unk_32C & 0x400) { + func_80B5BAAC(&this->lightInfo, &this->unk_378, &this->unk_747, 0xD2); + } + + func_80B5E078(globalCtx, this->unk_3A4, 10); +} + +void func_80B5DAEC(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOt* this = THIS; + + this->actionFunc(this, globalCtx); + Actor_SetFocus(&this->actor, 12.0f); + SkelAnime_Update(&this->skelAnime); + func_80B5BB38(&this->unk_747, &this->unk_744, 0.7f); + if (this->unk_32C & 0x400) { + func_80B5BAAC(&this->lightInfo, &this->unk_378, &this->unk_747, 210); + } +} + +void func_80B5DB6C(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnOt* this = THIS; + Player* player = GET_PLAYER(globalCtx); + + if (!(gSaveContext.save.weekEventReg[84] & 0x10) && !(this->unk_32C & 8)) { + if (gSaveContext.save.weekEventReg[25] & 4) { + Vec3f sp50; + + func_80B5B2E0(globalCtx, &this->actor.world.pos, ENOT_GET_7F(&this->actor), &sp50, &this->unk_340); + if (Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_OT, sp50.x, sp50.y, sp50.z, 0, + this->actor.shape.rot.y, 1, ENOT_GET_3FFF(&this->actor) | 0x8000, + this->actor.cutscene, this->actor.unk20, NULL) != NULL) { + this->unk_32C |= 8; + } + } else if (D_80B5E888 != NULL) { + s32 sp4C = false; + + if (gSaveContext.save.weekEventReg[13] & 1) { + if (!SurfaceType_IsHorseBlocked(&globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId)) { + sp4C = true; + } + } + + if (!sp4C) { + EnOt* temp = D_80B5E888; + + temp->unk_32C |= 8; + temp->unk_346 = ENOT_GET_7F(&this->actor); + temp->actor.params = this->actor.params; + temp->actor.cutscene = this->actor.cutscene; + this->unk_32C |= 8; + } + } else if (SurfaceType_IsHorseBlocked(&globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId)) { + player->unk_B2B = 29; + } + } +} + +void EnOt_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[2]; + EnOt* this = THIS; + Gfx* gfx; + + Matrix_Push(); + func_80B5E1D8(globalCtx, this->unk_3A4, 10); + Matrix_Pop(); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 25); + POLY_XLU_DISP = func_8012C2B4(POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_ot_Matanimheader_0005F8)); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, EnOt_PostLimbDraw, &this->actor); + Matrix_Translate(this->unk_378.x, this->unk_378.y, this->unk_378.z, MTXMODE_NEW); + Matrix_Scale(0.0882f, 0.0882f, 0.0882f, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = func_8012C7FC(POLY_XLU_DISP); + + gDPSetDither(&gfx[0], G_CD_NOISE); + gDPSetCombineLERP(&gfx[1], 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, + 0); + gSPDisplayList(&gfx[2], gameplay_keep_DL_029CB0); + gDPSetPrimColor(&gfx[3], 0, 0, this->unk_747.r, this->unk_747.g, this->unk_747.b, 50); + gSPMatrix(&gfx[4], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[5], gameplay_keep_DL_029CF0); + + POLY_XLU_DISP = &gfx[6]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnOt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80B5E410 = { 400.0f, 600.0f, 0.0f }; + EnOt* this = THIS; + + if (limbIndex == 4) { + OPEN_DISPS(globalCtx->state.gfxCtx); + Gfx* gfx = POLY_OPA_DISP; + + gSPDisplayList(&gfx[0], object_ot_DL_0004A0); + POLY_OPA_DISP = &gfx[1]; + Matrix_MultVec3f(&D_80B5E410, &this->unk_74C); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (limbIndex == 1) { + Matrix_MultZero(&this->unk_378); + this->unk_32C |= 0x400; + } +} + +EnOtUnkStruct* func_80B5DF58(EnOtUnkStruct* arg0, u8 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4) { + s32 i = 0; + + while (i < arg4 && arg0->unk_00) { + i++; + arg0++; + } + + if ((i < arg4) && ((arg1 == 1) || (arg1 == 2))) { + arg0->unk_00 = arg1; + Math_Vec3f_Copy(&arg0->unk_0C, arg2); + Math_Vec3f_Copy(&arg0->unk_50, arg2); + arg0->unk_04 = 0.009f; + arg0->unk_30 = 0.0f; + arg0->unk_34 = 0.0f; + arg0->unk_38 = 0.3f; + arg0->unk_3C = 1.4f; + arg0->unk_40 = -0.05f; + arg0->unk_4C = 40; + + if (arg0->unk_00 == 2) { + arg0->unk_30 = -arg0->unk_30; + arg0->unk_38 = -arg0->unk_38; + } + } + + return arg0; +} + +void func_80B5E078(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2) { + Vec3f sp54; + s32 i; + s16 temp = Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx)); + + for (i = 0; i < arg2; i++, arg1++) { + if ((arg1->unk_00 == 1) || (arg1->unk_00 == 2)) { + if (DECR(arg1->unk_4C) == 0) { + arg1->unk_00 = 0; + } + + arg1->unk_30 += arg1->unk_38; + arg1->unk_34 += arg1->unk_3C; + arg1->unk_3C += arg1->unk_40; + sp54.x = arg1->unk_30; + sp54.y = arg1->unk_34; + sp54.z = 0.0f; + Matrix_RotateYS(temp, MTXMODE_NEW); + Matrix_MultVec3f(&sp54, &arg1->unk_0C); + Math_Vec3f_Sum(&arg1->unk_0C, &arg1->unk_50, &arg1->unk_0C); + arg1->unk_4C--; + } + } +} + +void func_80B5E1D8(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2) { + s32 i; + s32 flag = 0; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP); + + for (i = 0; i < arg2; i++, arg1++) { + if (arg1->unk_00) { + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, object_ot_DL_000040); + flag = true; + if (globalCtx) {} + } + + Matrix_Translate(arg1->unk_0C.x, arg1->unk_0C.y, arg1->unk_0C.z, MTXMODE_NEW); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), MTXMODE_APPLY); + Matrix_Scale(arg1->unk_04, arg1->unk_04, arg1->unk_04, MTXMODE_APPLY); + + 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++, object_ot_DL_000078); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Ot/z_en_ot.h b/src/overlays/actors/ovl_En_Ot/z_en_ot.h index c9ab16c42..902cbecd7 100644 --- a/src/overlays/actors/ovl_En_Ot/z_en_ot.h +++ b/src/overlays/actors/ovl_En_Ot/z_en_ot.h @@ -7,10 +7,61 @@ struct EnOt; typedef void (*EnOtActionFunc)(struct EnOt*, GlobalContext*); +#define ENOT_GET_7F(thisx) ((thisx)->params & 0x7F) +#define ENOT_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F) +#define ENOT_GET_3FFF(thisx) ((thisx)->params & 0x3FFF) +#define ENOT_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ UNK_TYPE1 unk_08[0x4]; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ UNK_TYPE1 unk_18[0x18]; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; + /* 0x3C */ f32 unk_3C; + /* 0x40 */ f32 unk_40; + /* 0x44 */ UNK_TYPE1 unk_44[0x8]; + /* 0x4C */ u8 unk_4C; + /* 0x50 */ Vec3f unk_50; +} EnOtUnkStruct; // size = 0x5C + typedef struct EnOt { /* 0x0000 */ Actor actor; /* 0x0144 */ EnOtActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x610]; + /* 0x0148 */ SkelAnime skelAnime; + /* 0x018C */ ColliderCylinder collider; + /* 0x01D8 */ Vec3s jointTable[19]; + /* 0x024A */ Vec3s morphTable[19]; + /* 0x02BC */ s32 animIdx; + /* 0x02C0 */ ActorPathing actorPath; + /* 0x032C */ u16 unk_32C; + /* 0x0330 */ Vec3f unk_330; + /* 0x033C */ s32 unk_33C; + /* 0x0340 */ s32 unk_340; + /* 0x0344 */ s16 unk_344; + /* 0x0346 */ s16 unk_346; + /* 0x0348 */ Vec3f unk_348; + /* 0x0354 */ s16 unk_354; + /* 0x0356 */ s16 cutscenes[4]; + /* 0x0360 */ struct EnOt* unk_360; + /* 0x0364 */ LightNode* lightNode; + /* 0x0368 */ LightInfo lightInfo; + /* 0x0378 */ Vec3f unk_378; + /* 0x0384 */ u8 unk_384; + /* 0x0388 */ s32 unk_388; + /* 0x038C */ s32 unk_38C; + /* 0x0390 */ s16 unk_390; + /* 0x0394 */ Vec3f unk_394; + /* 0x03A0 */ s16 unk_3A0; + /* 0x03A4 */ EnOtUnkStruct unk_3A4[10]; + /* 0x073C */ s16 unk_73C; + /* 0x0740 */ f32 unk_740; + /* 0x0744 */ Color_RGB8 unk_744; + /* 0x0747 */ Color_RGB8 unk_747; + /* 0x074C */ Vec3f unk_74C; } EnOt; // size = 0x758 extern const ActorInit En_Ot_InitVars; 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 f0a2327fd..d324c8d92 100644 --- a/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -5,8 +5,9 @@ */ #include "z_en_owl.h" +#include "objects/object_owl/object_owl.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnOwl*)thisx) @@ -40,25 +41,13 @@ void func_8095C484(EnOwl* this); void func_8095CCF4(Actor* thisx, GlobalContext* globalCtx); void func_8095D074(Actor* thisx, GlobalContext* globalCtx); void EnOwl_ChangeMode(EnOwl* this, EnOwlActionFunc actionFunc, EnOwlFunc unkFunc, SkelAnime* skelAnime, - AnimationHeader* animationSeg, f32 transitionRate); + AnimationHeader* animation, f32 morphFrames); typedef enum { /* 0x00 */ OWL_REPEAT, /* 0x01 */ OWL_OK } EnOwlMessageChoice; -extern AnimationHeader D_06001168; -extern Gfx D_06001200[]; -extern AnimationHeader D_06001ADC; -extern TexturePtr D_06008EB8; -extern TexturePtr D_060092B8; -extern TexturePtr D_060096B8; -extern FlexSkeletonHeader D_0600C5F8; -extern AnimationHeader D_0600C6D4; -extern AnimationHeader D_0600CB94; -extern AnimationHeader D_0600CDB0; -extern FlexSkeletonHeader D_060105C0; - const ActorInit En_Owl_InitVars = { ACTOR_EN_OWL, ACTORCAT_NPC, @@ -131,23 +120,23 @@ void EnOwl_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_SetScale(&this->actor, 0.1f); this->actor.update = func_8095CCF4; this->actor.draw = func_8095D074; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_3D8 = 0; this->unk_3DA = 0x320; this->unk_3DC = 0x12C; return; } - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 36.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime1, &D_0600C5F8, &D_06001ADC, this->jointTable1, this->morphTable1, - 21); - SkelAnime_InitFlex(globalCtx, &this->skelAnime2, &D_060105C0, &D_0600CDB0, this->jointTable2, this->morphTable2, - 16); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime1, &object_owl_Skel_00C5F8, &object_owl_Anim_001ADC, + this->jointTable1, this->morphTable1, 21); + SkelAnime_InitFlex(globalCtx, &this->skelAnime2, &object_owl_Skel_0105C0, &object_owl_Anim_00CDB0, + this->jointTable2, this->morphTable2, 16); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->actor.minVelocityY = -10.0f; + this->actor.terminalVelocity = -10.0f; this->actor.targetArrowOffset = 500.0f; - EnOwl_ChangeMode(this, func_8095BF58, func_8095C484, &this->skelAnime2, &D_0600CDB0, 0.0f); + EnOwl_ChangeMode(this, func_8095BF58, func_8095C484, &this->skelAnime2, &object_owl_Anim_00CDB0, 0.0f); this->actionFlags = 0; this->unk_40D = 0; @@ -168,14 +157,14 @@ void EnOwl_Init(Actor* thisx, GlobalContext* globalCtx) { break; case ENOWL_GET_TYPE_2: - if (gSaveContext.inventory.items[14] == 14) { + if (gSaveContext.save.inventory.items[ITEM_LENS] == ITEM_LENS) { Actor_MarkForDeath(&this->actor); return; } break; case ENOWL_GET_TYPE_3: - if (CHECK_QUEST_ITEM(15)) { + if (CHECK_QUEST_ITEM(QUEST_SONG_SOARING)) { Actor_MarkForDeath(&this->actor); return; } @@ -194,7 +183,7 @@ void EnOwl_Init(Actor* thisx, GlobalContext* globalCtx) { case ENOWL_GET_TYPE_2: this->actionFunc = func_8095BE0C; - if (gSaveContext.weekEventReg[9] & 0x20) { + if (gSaveContext.save.weekEventReg[9] & 0x20) { this->actor.textId = 0xBF0; } else { this->actor.textId = 0xBEA; @@ -233,34 +222,34 @@ void func_8095A920(EnOwl* this, GlobalContext* globalCtx) { } s32 func_8095A978(EnOwl* this, GlobalContext* globalCtx, u16 textId, f32 targetDist, f32 arg4) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { return true; } this->actor.textId = textId; if (this->actor.xzDistToPlayer < targetDist) { - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, targetDist, arg4, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, targetDist, arg4, EXCH_ITEM_NONE); } return false; } s32 func_8095A9FC(EnOwl* this, GlobalContext* globalCtx, u16 textId) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { return true; } this->actor.textId = textId; if (this->actor.xzDistToPlayer < 120.0f) { - func_800B8500(&this->actor, globalCtx, 350.0f, 1000.0f, 0); + func_800B8500(&this->actor, globalCtx, 350.0f, 1000.0f, EXCH_ITEM_NONE); } return false; } void func_8095AA70(EnOwl* this) { - EnOwl_ChangeMode(this, func_8095C1C8, func_8095C484, &this->skelAnime1, &D_0600CB94, 0.0f); + EnOwl_ChangeMode(this, func_8095C1C8, func_8095C484, &this->skelAnime1, &object_owl_Anim_00CB94, 0.0f); this->eyeTexIndex = 0; this->blinkTimer = Rand_S16Offset(60, 60); } @@ -269,7 +258,7 @@ void func_8095AAD0(EnOwl* this, GlobalContext* globalCtx) { s32 switchFlag = ENOWL_GET_SWITCHFLAG(&this->actor); if (switchFlag < 0x7F) { - Actor_SetSwitchFlag(globalCtx, switchFlag); + Flags_SetSwitch(globalCtx, switchFlag); } func_8095AA70(this); @@ -302,16 +291,16 @@ void func_8095ABA8(EnOwl* this) { } void func_8095ABF0(EnOwl* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { Audio_QueueSeqCmd(0x110000FF); func_8095AAD0(this, globalCtx); - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } } // Unused? void func_8095AC50(EnOwl* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { Audio_QueueSeqCmd(0x110000FF); if ((this->unk_3DA % 64) == 0) { func_8095AAD0(this, globalCtx); @@ -320,7 +309,7 @@ void func_8095AC50(EnOwl* this, GlobalContext* globalCtx) { func_8095ABA8(this); this->actionFunc = func_8095AB1C; } - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } } @@ -335,7 +324,7 @@ void func_8095ACEC(EnOwl* this) { } void func_8095AD54(EnOwl* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case OWL_REPEAT: func_80151938(globalCtx, 0x7D1); @@ -351,14 +340,14 @@ void func_8095AD54(EnOwl* this, GlobalContext* globalCtx) { } void func_8095AE00(EnOwl* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x7D2); this->actionFunc = func_8095AD54; } } void func_8095AE60(EnOwl* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_80151938(globalCtx, 0x7D1); this->actionFunc = func_8095AE00; } @@ -367,21 +356,21 @@ void func_8095AE60(EnOwl* this, GlobalContext* globalCtx) { void func_8095AEC0(EnOwl* this, GlobalContext* globalCtx) { func_8095A920(this, globalCtx); if (func_8095A978(this, globalCtx, 0x7D0, 360.0f, 200.0f)) { - func_801A3098(0x45); + func_801A3098(NA_BGM_OWL); this->actionFunc = func_8095AE60; } } void func_8095AF2C(EnOwl* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 5: - if (func_80147624(globalCtx)) { - if (globalCtx->msgCtx.unk11F04 == 0xBFE) { + if (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.currentTextId == 0xBFE) { func_8095ACEC(this); func_801477B4(globalCtx); this->actionFunc = func_8095ABF0; } else { - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); } } break; @@ -396,7 +385,7 @@ void func_8095AF2C(EnOwl* this, GlobalContext* globalCtx) { void func_8095AFEC(EnOwl* this, GlobalContext* globalCtx) { func_8095A920(this, globalCtx); if (func_8095A978(this, globalCtx, 0xBF6, 200.0f, 100.0f)) { - func_801A3098(0x45); + func_801A3098(NA_BGM_OWL); this->actionFunc = func_8095AF2C; this->unk_406 = 0; this->actionFlags |= 0x40; @@ -419,7 +408,7 @@ s32 func_8095B06C(EnOwl* this) { void func_8095B0C8(EnOwl* this) { s32 pad; - Vec3s* points = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); + Vec3s* points = Lib_SegmentedToVirtual(this->path->points); points += this->unk_3F8; this->unk_3EC = Math_FAtan2F(points->z - this->actor.world.pos.z, points->x - this->actor.world.pos.x); @@ -430,7 +419,7 @@ void func_8095B158(EnOwl* this) { if (Animation_OnFrame(&this->skelAnime1, 2.0f) || Animation_OnFrame(&this->skelAnime1, 9.0f) || Animation_OnFrame(&this->skelAnime1, 23.0f) || Animation_OnFrame(&this->skelAnime1, 40.0f) || Animation_OnFrame(&this->skelAnime1, 58.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_OWL_FLUTTER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OWL_FLUTTER); } } @@ -450,9 +439,9 @@ void func_8095B254(EnOwl* this, GlobalContext* globalCtx) { } if (this->actionFlags & 1) { - EnOwl_ChangeMode(this, func_8095B1E4, func_8095C328, &this->skelAnime1, &D_06001ADC, 0.0f); + EnOwl_ChangeMode(this, func_8095B1E4, func_8095C328, &this->skelAnime1, &object_owl_Anim_001ADC, 0.0f); this->unk_3EA = 6; - this->actor.flags |= 0x20; + this->actor.flags |= ACTOR_FLAG_20; } func_8095B158(this); @@ -468,7 +457,7 @@ void func_8095B2F8(EnOwl* this, GlobalContext* globalCtx) { if ((this->actor.shape.rot.y == this->unk_3EC) && (this->actionFlags & 1)) { this->actionFunc = func_8095B254; Animation_Change(this->skelAnime3, this->skelAnime3->animation, 1.0f, 19.0f, - Animation_GetLastFrame(&D_06001168), 2, 0.0f); + Animation_GetLastFrame(&object_owl_Anim_001168), 2, 0.0f); this->unk_414 = func_8095C484; } @@ -478,7 +467,7 @@ void func_8095B2F8(EnOwl* this, GlobalContext* globalCtx) { void func_8095B3DC(EnOwl* this, GlobalContext* globalCtx) { if (this->actionFlags & 1) { this->actionFunc = func_8095B2F8; - Animation_Change(this->skelAnime3, &D_06001168, 1.0f, 0.0f, 35.0f, 2, 0.0f); + Animation_Change(this->skelAnime3, &object_owl_Anim_001168, 1.0f, 0.0f, 35.0f, 2, 0.0f); this->unk_414 = func_8095C408; this->unk_3EC = 0x5500; this->actor.world.pos.y += 100.0f; @@ -491,7 +480,7 @@ void func_8095B480(EnOwl* this, GlobalContext* globalCtx) { if (player->stateFlags3 & 0x10000000) { this->actor.textId = 0xBF1; - EnOwl_ChangeMode(this, func_8095BF58, func_8095C484, &this->skelAnime2, &D_0600CDB0, 0.0f); + EnOwl_ChangeMode(this, func_8095BF58, func_8095C484, &this->skelAnime2, &object_owl_Anim_00CDB0, 0.0f); this->eyeTexIndex = 0; this->actionFlags &= ~8; this->blinkTimer = Rand_S16Offset(60, 60); @@ -509,23 +498,23 @@ void func_8095B480(EnOwl* this, GlobalContext* globalCtx) { void func_8095B574(EnOwl* this, GlobalContext* globalCtx) { func_8095A920(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_8095BA84; - func_801A3098(0x45); + func_801A3098(NA_BGM_OWL); this->actionFlags |= 0x40; this->unk_406 = 2; } else if (this->actor.xzDistToPlayer < 200.0f) { - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 200.0f, 400.0f, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 200.0f, 400.0f, EXCH_ITEM_NONE); } else { - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } func_8095B480(this, globalCtx); } void func_8095B650(EnOwl* this, GlobalContext* globalCtx) { if (this->actionFlags & 1) { - EnOwl_ChangeMode(this, func_8095B574, func_8095C484, &this->skelAnime2, &D_0600CDB0, 0.0f); + EnOwl_ChangeMode(this, func_8095B574, func_8095C484, &this->skelAnime2, &object_owl_Anim_00CDB0, 0.0f); this->actor.textId = 0xBF5; this->actionFlags &= ~8; } @@ -534,7 +523,8 @@ void func_8095B650(EnOwl* this, GlobalContext* globalCtx) { void func_8095B6C8(EnOwl* this, GlobalContext* globalCtx) { if (this->actionFlags & 1) { - Animation_Change(this->skelAnime3, &D_0600CB94, -1.0f, Animation_GetLastFrame(&D_0600CB94), 0.0f, 2, 0.0f); + Animation_Change(this->skelAnime3, &object_owl_Anim_00CB94, -1.0f, + Animation_GetLastFrame(&object_owl_Anim_00CB94), 0.0f, 2, 0.0f); this->unk_414 = func_8095C484; this->actionFunc = func_8095B650; } @@ -545,14 +535,14 @@ void func_8095B6C8(EnOwl* this, GlobalContext* globalCtx) { void func_8095B76C(EnOwl* this, GlobalContext* globalCtx) { s32 pad; s16 sp4A; - f32 sp44 = func_80122524(&this->actor, this->path, this->unk_3F8, &sp4A); + f32 sp44 = Path_OrientAndGetDistSq(&this->actor, this->path, this->unk_3F8, &sp4A); Vec3s* points; Math_SmoothStepToS(&this->actor.world.rot.y, sp4A, 6, 0x800, 0x200); this->actor.shape.rot.y = this->actor.world.rot.y; if (sp44 < SQ(this->actor.speedXZ)) { this->actor.speedXZ = 0.0f; - points = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); + points = Lib_SegmentedToVirtual(this->path->points); points += this->unk_3F8; do { @@ -606,7 +596,7 @@ void func_8095B960(EnOwl* this, GlobalContext* globalCtx) { void func_8095B9FC(EnOwl* this, GlobalContext* globalCtx) { if (this->actionFlags & 1) { this->actionFunc = func_8095B960; - Animation_Change(this->skelAnime3, &D_06001168, 1.0f, 0.0f, 35.0f, 2, 0.0f); + Animation_Change(this->skelAnime3, &object_owl_Anim_001168, 1.0f, 0.0f, 35.0f, 2, 0.0f); this->unk_414 = func_8095C408; func_8095B0C8(this); } @@ -615,18 +605,18 @@ void func_8095B9FC(EnOwl* this, GlobalContext* globalCtx) { void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { func_8095A920(this, globalCtx); - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: - if (func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0xBEC: switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); - if (gSaveContext.weekEventReg[9] & 0x40) { + if (gSaveContext.save.weekEventReg[9] & 0x40) { func_80151938(globalCtx, 0xBF4); } else { - gSaveContext.weekEventReg[9] |= 0x40; + gSaveContext.save.weekEventReg[9] |= 0x40; func_80151938(globalCtx, 0xBED); } break; @@ -656,10 +646,10 @@ void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { break; case 5: - if (func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0xBEA: - gSaveContext.weekEventReg[9] |= 0x20; + gSaveContext.save.weekEventReg[9] |= 0x20; func_80151938(globalCtx, 0xBEB); break; @@ -676,11 +666,12 @@ void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { case 0xBEE: func_801477B4(globalCtx); Audio_QueueSeqCmd(0x110000FF); - EnOwl_ChangeMode(this, func_8095B9FC, func_8095C484, &this->skelAnime1, &D_0600CB94, 0.0f); + EnOwl_ChangeMode(this, func_8095B9FC, func_8095C484, &this->skelAnime1, &object_owl_Anim_00CB94, + 0.0f); this->eyeTexIndex = 0; this->blinkTimer = Rand_S16Offset(60, 60); this->actionFlags |= 8; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.home.rot.x = 0; func_8095ACEC(this); this->unk_406 = 0; @@ -692,7 +683,7 @@ void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { func_801477B4(globalCtx); Audio_QueueSeqCmd(0x110000FF); func_8095ACEC(this); - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.textId = 0xBF0; this->actionFunc = func_8095BE0C; break; @@ -704,8 +695,9 @@ void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { case 0xBF5: func_801477B4(globalCtx); Audio_QueueSeqCmd(0x110000FF); - this->actor.flags &= ~0x10000; - EnOwl_ChangeMode(this, func_8095B3DC, func_8095C484, &this->skelAnime1, &D_0600CB94, 0.0f); + this->actor.flags &= ~ACTOR_FLAG_10000; + EnOwl_ChangeMode(this, func_8095B3DC, func_8095C484, &this->skelAnime1, &object_owl_Anim_00CB94, + 0.0f); this->eyeTexIndex = 0; this->blinkTimer = Rand_S16Offset(60, 60); this->actionFlags |= 8; @@ -719,20 +711,20 @@ void func_8095BA84(EnOwl* this, GlobalContext* globalCtx) { void func_8095BE0C(EnOwl* this, GlobalContext* globalCtx) { func_8095A920(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_8095BA84; - func_801A3098(0x45); + func_801A3098(NA_BGM_OWL); this->unk_406 = 1; this->actionFlags |= 0x40; } else if (this->actor.textId == 0xBF0) { if (this->actor.isTargeted) { - func_800B8500(&this->actor, globalCtx, 200.0f, 200.0f, 0); + func_800B8500(&this->actor, globalCtx, 200.0f, 200.0f, EXCH_ITEM_NONE); } } else if (this->actor.xzDistToPlayer < 200.0f) { - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 200.0f, 200.0f, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 200.0f, 200.0f, EXCH_ITEM_NONE); } else { - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; } } @@ -746,7 +738,7 @@ void func_8095BF58(EnOwl* this, GlobalContext* globalCtx) { } void func_8095BF78(EnOwl* this, GlobalContext* globalCtx) { - this->actor.flags |= 0x20; + this->actor.flags |= ACTOR_FLAG_20; if (this->actor.xzDistToPlayer > 6000.0f) { Actor_MarkForDeath(&this->actor); } @@ -783,7 +775,7 @@ void func_8095C09C(EnOwl* this, GlobalContext* globalCtx) { } if (this->actionFlags & 1) { - EnOwl_ChangeMode(this, func_8095BF78, func_8095C328, &this->skelAnime1, &D_06001ADC, 0.0f); + EnOwl_ChangeMode(this, func_8095BF78, func_8095C328, &this->skelAnime1, &object_owl_Anim_001ADC, 0.0f); this->unk_3EA = 6; this->unk_3EC += 0x2000; } @@ -794,7 +786,7 @@ void func_8095C09C(EnOwl* this, GlobalContext* globalCtx) { void func_8095C1C8(EnOwl* this, GlobalContext* globalCtx) { if (this->actionFlags & 1) { this->unk_3EA = 3; - EnOwl_ChangeMode(this, func_8095C09C, func_8095C484, &this->skelAnime1, &D_06001168, 0.0f); + EnOwl_ChangeMode(this, func_8095C09C, func_8095C484, &this->skelAnime1, &object_owl_Anim_001168, 0.0f); this->unk_3EC = BINANG_ADD(this->actor.world.rot.y, 0x4000); this->unk_3E4 = this->actor.world.pos.y; this->actor.velocity.y = 2.0f; @@ -810,7 +802,8 @@ void func_8095C258(EnOwl* this) { } else { this->unk_414 = func_8095C328; this->unk_3EA = 6; - Animation_Change(this->skelAnime3, &D_06001ADC, 1.0f, 0.0f, Animation_GetLastFrame(&D_06001ADC), 2, 5.0f); + Animation_Change(this->skelAnime3, &object_owl_Anim_001ADC, 1.0f, 0.0f, + Animation_GetLastFrame(&object_owl_Anim_001ADC), 2, 5.0f); } } @@ -823,7 +816,8 @@ void func_8095C328(EnOwl* this) { } else { this->unk_3EA = 160; this->unk_414 = func_8095C258; - Animation_Change(this->skelAnime3, &D_0600C6D4, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600C6D4), 0, 5.0f); + Animation_Change(this->skelAnime3, &object_owl_Anim_00C6D4, 1.0f, 0.0f, + Animation_GetLastFrame(&object_owl_Anim_00C6D4), 0, 5.0f); } } } @@ -891,7 +885,7 @@ void EnOwl_Update(Actor* thisx, GlobalContext* globalCtx) { s16 sp36; if (this->actor.draw != NULL) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } if (this->unk_414 != NULL) { @@ -904,8 +898,8 @@ void EnOwl_Update(Actor* thisx, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); if (this->actor.update != NULL) { - if ((this->skelAnime1.animation == &D_06001ADC) && Animation_OnFrame(&this->skelAnime1, 4.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_OWL_FLUTTER); + if ((this->skelAnime1.animation == &object_owl_Anim_001ADC) && Animation_OnFrame(&this->skelAnime1, 4.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OWL_FLUTTER); } if (this->actionFlags & 2) { @@ -1142,15 +1136,15 @@ void EnOwl_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } if (limbIndex == 3) { - Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + Matrix_MultVec3f(&sp18, &this->actor.focus.pos); } } void EnOwl_Draw(Actor* thisx, GlobalContext* globalCtx) { static TexturePtr eyeTextures[] = { - &D_06008EB8, - &D_060092B8, - &D_060096B8, + object_owl_Tex_008EB8, + object_owl_Tex_0092B8, + object_owl_Tex_0096B8, }; s32 pad; EnOwl* this = THIS; @@ -1172,9 +1166,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_Translate(0.0f, 500.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_3D8 - 0x4000, MTXMODE_APPLY); + Matrix_Translate(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); @@ -1182,7 +1176,7 @@ void func_8095D074(Actor* thisx, GlobalContext* globalCtx) { gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_TEX_EDGE2); gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); - gSPDisplayList(POLY_OPA_DISP++, D_06001200); + gSPDisplayList(POLY_OPA_DISP++, object_owl_DL_001200); } else { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -1190,17 +1184,16 @@ void func_8095D074(Actor* thisx, GlobalContext* globalCtx) { gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_XLU_SURF2); gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, (u8)(this->unk_3DC * 8)); - gSPDisplayList(POLY_XLU_DISP++, D_06001200); + gSPDisplayList(POLY_XLU_DISP++, object_owl_DL_001200); } CLOSE_DISPS(globalCtx->state.gfxCtx); } void EnOwl_ChangeMode(EnOwl* this, EnOwlActionFunc actionFunc, EnOwlFunc unkFunc, SkelAnime* skelAnime, - AnimationHeader* animationSeg, f32 transitionRate) { + AnimationHeader* animation, f32 morphFrames) { this->skelAnime3 = skelAnime; - Animation_Change(this->skelAnime3, animationSeg, 1.0f, 0.0f, Animation_GetLastFrame(animationSeg), 2, - transitionRate); + Animation_Change(this->skelAnime3, animation, 1.0f, 0.0f, Animation_GetLastFrame(animation), 2, morphFrames); this->actionFunc = actionFunc; this->unk_414 = unkFunc; } diff --git a/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c b/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c index bb7a5ffbd..e17cba0e2 100644 --- a/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c +++ b/src/overlays/actors/ovl_En_Pamera/z_en_pamera.c @@ -1,14 +1,15 @@ /* * File: z_en_pamera.c - * Overlay: En_Pamera + * Overlay: ovl_En_Pamera * Description: Pamela */ #include "z_en_pamera.h" #include "../ovl_En_Bom/z_en_bom.h" #include "../ovl_En_Door/z_en_door.h" +#include "objects/object_pamera/object_pamera.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnPamera*)thisx) @@ -69,29 +70,6 @@ void func_80BDA288(EnPamera* this); void func_80BDA2E0(EnPamera* this, GlobalContext* globalCtx); void func_80BDA344(Actor* thisx, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_06008448; -extern AnimationHeader D_060005BC; -extern AnimationHeader D_06008AE0; // Pamela Walking -extern AnimationHeader D_06008E38; -extern AnimationHeader D_0600A844; // Pamela Looking down the well -extern AnimationHeader D_0600B0C4; -extern AnimationHeader D_06009870; -extern AnimationHeader D_06009F54; // HoldBack En_Hgo -extern AnimationHeader D_0600B5B0; // PushBack En_Hgo -extern AnimationHeader D_0600BCC4; // Defend En_Hgo -extern AnimationHeader D_0600D9DC; -extern AnimationHeader D_0600E16C; // Hugging En_Hg -extern AnimationHeader D_0600C9F4; -extern AnimationHeader D_0600D0F0; - -extern TexturePtr D_060074E8; -extern TexturePtr D_060078E8; -extern TexturePtr D_060066E8; -extern TexturePtr D_06006AE8; -extern TexturePtr D_06006EE8; -extern TexturePtr D_060072E8; -extern TexturePtr D_060073E8; - const ActorInit En_Pamera_InitVars = { ACTOR_EN_PAMERA, ACTORCAT_NPC, @@ -128,32 +106,38 @@ static CollisionCheckInfoInit2 sColChkInfoInit2 = { 0, 0, 0, 0, MASS_IMMOVABLE, }; -static ActorAnimationEntry sAnimations[] = { - { &D_060005BC, 1.0f, 0, 0.0f, 0, -4.0f }, { &D_06008AE0, 1.0f, 0, 0.0f, 0, -4.0f }, - { &D_06008E38, 1.0f, 0, 0.0f, 0, -4.0f }, { &D_0600A844, 1.0f, 0, 0.0f, 0, -4.0f }, - { &D_0600B0C4, 1.0f, 0, 0.0f, 0, -4.0f }, { &D_06009870, 1.0f, 0, 0.0f, 0, 0.0f }, - { &D_06009F54, 1.0f, 0, 0.0f, 0, 0.0f }, { &D_0600B5B0, 1.0f, 0, 0.0f, 0, 0.0f }, - { &D_0600BCC4, 1.0f, 0, 0.0f, 0, 0.0f }, { &D_0600D9DC, 1.0f, 0, 0.0f, 0, 0.0f }, - { &D_0600E16C, 1.0f, 0, 0.0f, 0, 0.0f }, { &D_0600C9F4, 1.0f, 0, 0.0f, 2, 0.0f }, - { &D_0600D0F0, 1.0f, 0, 0.0f, 0, 0.0f }, +static AnimationInfo sAnimations[] = { + { &object_pamera_Anim_0005BC, 1.0f, 0, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_pamera_Anim_008AE0, 1.0f, 0, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_pamera_Anim_008E38, 1.0f, 0, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_pamera_Anim_00A844, 1.0f, 0, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_pamera_Anim_00B0C4, 1.0f, 0, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_pamera_Anim_009870, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_009F54, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_00B5B0, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_00BCC4, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_00D9DC, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_00E16C, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_pamera_Anim_00C9F4, 1.0f, 0, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_pamera_Anim_00D0F0, 1.0f, 0, 0.0f, ANIMMODE_LOOP, 0.0f }, }; static Vec3f D_80BDA5F0 = { 1000.0f, 0.0f, 0.0f }; -static TexturePtr D_80BDA5FC[] = { &D_060074E8, &D_060078E8 }; +static TexturePtr D_80BDA5FC[] = { object_pamera_Tex_0074E8, object_pamera_Tex_0078E8 }; -static TexturePtr D_80BDA604[] = { &D_060066E8, &D_06006AE8, &D_06006EE8 }; +static TexturePtr D_80BDA604[] = { object_pamera_Tex_0066E8, object_pamera_Tex_006AE8, object_pamera_Tex_006EE8 }; -static TexturePtr D_80BDA610[] = { &D_060072E8, &D_060073E8 }; +static TexturePtr D_80BDA610[] = { object_pamera_Tex_0072E8, object_pamera_Tex_0073E8 }; void EnPamera_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnPamera* this = THIS; Vec3f sp44; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 15.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06008448, &D_060005BC, this->jointTable, this->morphTable, - PAMERA_LIMB_MAX); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 15.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_pamera_Skel_008448, &object_pamera_Anim_0005BC, + this->jointTable, this->morphTable, PAMERA_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, NULL, &sColChkInfoInit2); @@ -171,14 +155,14 @@ void EnPamera_Init(Actor* thisx, GlobalContext* globalCtx) { func_80BD8588(this, globalCtx); func_80BD8658(this); if (1) {} - if (!(gSaveContext.weekEventReg[14] & 4) || (gSaveContext.weekEventReg[52] & 0x20) || - (gSaveContext.weekEventReg[75] & 0x20) || (gSaveContext.entranceIndex == 0x2090)) { + if (!(gSaveContext.save.weekEventReg[14] & 4) || (gSaveContext.save.weekEventReg[52] & 0x20) || + (gSaveContext.save.weekEventReg[75] & 0x20) || (gSaveContext.save.entranceIndex == 0x2090)) { Actor_MarkForDeath(&this->actor); } - if (gSaveContext.weekEventReg[61] & 4) { - if (!(gSaveContext.weekEventReg[59] & 1) || (gSaveContext.entranceIndex != 0x2020)) { - if ((gSaveContext.entranceIndex != 0x2020) && (gSaveContext.weekEventReg[59] & 1)) { - gSaveContext.weekEventReg[59] &= (u8)~1; + if (gSaveContext.save.weekEventReg[61] & 4) { + if (!(gSaveContext.save.weekEventReg[59] & 1) || (gSaveContext.save.entranceIndex != 0x2020)) { + if ((gSaveContext.save.entranceIndex != 0x2020) && (gSaveContext.save.weekEventReg[59] & 1)) { + gSaveContext.save.weekEventReg[59] &= (u8)~1; } func_80BD8700(this); } else { @@ -189,14 +173,14 @@ void EnPamera_Init(Actor* thisx, GlobalContext* globalCtx) { func_80BD8CCC(this); } } else { - gSaveContext.weekEventReg[59] |= 1; + gSaveContext.save.weekEventReg[59] |= 1; func_80BD8FF0(this); } } } s32 func_80BD84F0(EnPamera* this, GlobalContext* globalCtx) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_DOOR].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_DOOR].first; while (actor != NULL) { if ((actor->id == ACTOR_EN_DOOR) && (Math_Vec3f_DistXZ(&this->actor.world.pos, &actor->world.pos) < 200.0f)) { @@ -216,7 +200,7 @@ void func_80BD8588(EnPamera* this, GlobalContext* globalCtx) { if (path == NULL) { Actor_MarkForDeath(&this->actor); } - if (gSaveContext.weekEventReg[61] & 4) { + if (gSaveContext.save.weekEventReg[61] & 4) { path = &globalCtx->setupPathList[path->unk1]; } this->pathPoints = Lib_SegmentedToVirtual(path->points); @@ -248,8 +232,8 @@ void EnPamera_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_80BD8700(EnPamera* this) { this->hideInisdeTimer = 0; - this->actor.flags &= ~1; - func_800BDC5C(&this->skelAnime, sAnimations, 0); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->actionFunc = func_80BD8758; } @@ -257,9 +241,10 @@ void func_80BD8758(EnPamera* this, GlobalContext* globalCtx) { if (this->hideInisdeTimer++ > 1800) { if (ActorCutscene_GetCanPlayNext(this->cutscenes[0]) && (this->cutscenes[0] != -1)) { ActorCutscene_StartAndSetUnkLinkFields(this->cutscenes[0], &this->actor); - func_800E02AC(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->cutscenes[0])), &this->actor); + Camera_SetToTrackActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->cutscenes[0])), + &this->actor); this->actor.speedXZ = 1.5f; - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actor.shape.rot.y = this->actor.home.rot.y; this->actor.world.rot.y = this->actor.home.rot.y; func_80BD9338(this, globalCtx); @@ -268,7 +253,7 @@ void func_80BD8758(EnPamera* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscenes[0]); } else { this->actor.speedXZ = 1.5f; - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actor.shape.rot.y = this->actor.home.rot.y; this->actor.world.rot.y = this->actor.home.rot.y; func_80BD9338(this, globalCtx); @@ -289,8 +274,8 @@ void func_80BD8758(EnPamera* this, GlobalContext* globalCtx) { void func_80BD8908(EnPamera* this) { this->actor.draw = EnPamera_Draw; - this->actor.flags |= 1; - func_800BDC5C(&this->skelAnime, sAnimations, 1); + this->actor.flags |= ACTOR_FLAG_1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actionFunc = func_80BD8964; } @@ -303,14 +288,14 @@ void func_80BD8964(EnPamera* this, GlobalContext* globalCtx) { if (Math_Vec3f_StepTo(&this->actor.world.pos, &vec, 1.0f) < 5.0f) { this->actor.speedXZ = 1.5f; - func_800BDC5C(&this->skelAnime, sAnimations, 1); - gSaveContext.weekEventReg[59] |= 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + gSaveContext.save.weekEventReg[59] |= 1; func_80BD8B50(this); } } void func_80BD8A38(EnPamera* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); this->actionFunc = func_80BD8A7C; } @@ -319,10 +304,10 @@ void func_80BD8A7C(EnPamera* this, GlobalContext* globalCtx) { 0x3000, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; if (Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.home.pos, 1.5f) < 10.0f) { - gSaveContext.weekEventReg[59] &= (u8)~1; - if (!(gSaveContext.weekEventReg[61] & 4)) { + gSaveContext.save.weekEventReg[59] &= (u8)~1; + if (!(gSaveContext.save.weekEventReg[61] & 4)) { func_80BD92D0(this, globalCtx); - gSaveContext.weekEventReg[61] |= 4; + gSaveContext.save.weekEventReg[61] |= 4; } func_80BD8700(this); } @@ -357,14 +342,14 @@ void func_80BD8B70(EnPamera* this, GlobalContext* globalCtx) { void func_80BD8CCC(EnPamera* this) { this->hideInisdeTimer = 0; this->actor.speedXZ = 0.0f; - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); this->actionFunc = func_80BD8D1C; } void func_80BD8D1C(EnPamera* this, GlobalContext* globalCtx) { if (this->hideInisdeTimer++ > 200) { this->actor.speedXZ = 1.5f; - func_800BDC5C(&this->skelAnime, sAnimations, 1); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); func_80BD8D80(this); } } @@ -400,14 +385,14 @@ void func_80BD8DB0(EnPamera* this, GlobalContext* globalCtx) { void EnPamera_LookDownWell(EnPamera* this) { func_80BD93CC(this, 1, 1); - func_800BDC5C(&this->skelAnime, sAnimations, 4); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); this->actionFunc = func_80BD8F60; } void func_80BD8F60(EnPamera* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x3000, 0x1000); if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - func_800BDC5C(&this->skelAnime, sAnimations, 2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); this->actor.speedXZ = 3.0f; func_80BD93CC(this, 0, 0); func_80BD8D80(this); @@ -424,7 +409,7 @@ void func_80BD8FF0(EnPamera* this) { pameraYaw = Math_Vec3f_Yaw(&pameraPos, &this->actor.world.pos); this->actor.shape.rot.y = pameraYaw; this->actor.world.rot.y = pameraYaw; - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); this->actionFunc = func_80BD909C; } @@ -434,7 +419,7 @@ void func_80BD909C(EnPamera* this, GlobalContext* globalCtx) { void func_80BD90AC(EnPamera* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK && (this->actionFunc != func_80BD8758) && + if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE && (this->actionFunc != func_80BD8758) && (this->actionFunc != func_80BD8964) && (this->actionFunc != func_80BD8A7C) && (this->actionFunc != func_80BD8F60) && ((this->actionFunc != func_80BD8B70) || (this->pathIndex != 0)) && ((this->actionFunc != func_80BD8DB0) || (this->actor.speedXZ != 3.0f)) && @@ -443,7 +428,8 @@ void func_80BD90AC(EnPamera* this, GlobalContext* globalCtx) { (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 200.0f)))) { if ((ActorCutscene_GetCanPlayNext(this->cutscenes[1])) && ((this->cutscenes[1] != -1))) { ActorCutscene_StartAndSetUnkLinkFields(this->cutscenes[1], &this->actor); - func_800E02AC(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->cutscenes[1])), &this->actor); + Camera_SetToTrackActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(this->cutscenes[1])), + &this->actor); EnPamera_LookDownWell(this); } else if (this->cutscenes[1] != -1) { ActorCutscene_SetIntentToPlay(this->cutscenes[1]); @@ -454,7 +440,7 @@ void func_80BD90AC(EnPamera* this, GlobalContext* globalCtx) { } s32 func_80BD9234(EnPamera* this, GlobalContext* globalCtx) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; while (actor != NULL) { if ((actor->id == ACTOR_EN_BOM) && (Math_Vec3f_DistXZ(&this->actor.world.pos, &actor->world.pos) < 500.0f) && @@ -486,7 +472,7 @@ void func_80BD9338(EnPamera* this, GlobalContext* globalCtx) { func_80BD84F0(this, globalCtx); actor = this->actor.child; if ((actor != NULL) && (actor->id == ACTOR_EN_DOOR)) { - ((EnDoor*)actor)->unk1A7 = -0x32; + ((EnDoor*)actor)->unk_1A7 = -0x32; } } @@ -510,13 +496,13 @@ void func_80BD93CC(EnPamera* this, s16 arg1, s16 arg2) { void func_80BD93F4(EnPamera* this, GlobalContext* globalCtx) { if ((this->actionFunc == func_80BD8B70) || (this->actionFunc == func_80BD8DB0) || (this->actionFunc == func_80BD8964) || (this->actionFunc == func_80BD8A7C)) { - if (this->skelAnime.animation == &D_06008AE0) { + if (this->skelAnime.animation == &object_pamera_Anim_008AE0) { if (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 18.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } - } else if ((this->skelAnime.animation == &D_06008E38) && + } else if ((this->skelAnime.animation == &object_pamera_Anim_008E38) && (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } } } @@ -553,14 +539,14 @@ s32 EnPamera_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi rot->x += this->limb9Rot.y; rot->z += this->limb9Rot.x; } - return 0; + return false; } void EnPamera_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnPamera* this = THIS; if (limbIndex == PAMERA_LIMB_HAIR) { - Matrix_MultiplyVector3fByState(&D_80BDA5F0, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80BDA5F0, &this->actor.focus.pos); } } @@ -579,9 +565,9 @@ void EnPamera_Draw(Actor* thisx, GlobalContext* globalCtx) { void func_80BD9840(EnPamera* this, GlobalContext* globalCtx) { this->actor.update = func_80BDA344; - this->actor.flags |= 0x2000000; - this->actor.flags |= 0x100000; - if ((gSaveContext.weekEventReg[75] & 0x20) || (gSaveContext.weekEventReg[52] & 0x20)) { + this->actor.flags |= ACTOR_FLAG_2000000; + this->actor.flags |= ACTOR_FLAG_100000; + if ((gSaveContext.save.weekEventReg[75] & 0x20) || (gSaveContext.save.weekEventReg[52] & 0x20)) { func_80BD9E60(this); func_80BD9938(this); } else { @@ -589,15 +575,15 @@ void func_80BD9840(EnPamera* this, GlobalContext* globalCtx) { func_80BD9E60(this); func_80BD9904(this); } - if (gSaveContext.weekEventReg[14] & 4) { - func_801A0204(0x27); + if (gSaveContext.save.weekEventReg[14] & 4) { + func_801A0204(NA_BGM_MUSIC_BOX_HOUSE); } else { - func_801A0204(0x1F); + func_801A0204(NA_BGM_INSIDE_A_HOUSE); } } void func_80BD9904(EnPamera* this) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = &func_80BD9928; } @@ -609,25 +595,25 @@ void func_80BD9938(EnPamera* this) { } void func_80BD994C(EnPamera* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx) != 0) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO_MASK) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { if (1) {} func_80BD93CC(this, 0, 1); - func_801518B0(globalCtx, 0x15A8, &this->actor); + Message_StartTextbox(globalCtx, 0x15A8, &this->actor); this->unk_324 = 0x15A8; - } else if ((gSaveContext.playerForm != PLAYER_FORM_HUMAN) || - ((gSaveContext.weekEventReg[52] & 0x20) && (!(gSaveContext.weekEventReg[75] & 0x20)))) { + } else if ((gSaveContext.save.playerForm != PLAYER_FORM_HUMAN) || + ((gSaveContext.save.weekEventReg[52] & 0x20) && (!(gSaveContext.save.weekEventReg[75] & 0x20)))) { func_80BD93CC(this, 1, 0); - func_801518B0(globalCtx, 0x158E, &this->actor); + Message_StartTextbox(globalCtx, 0x158E, &this->actor); this->unk_324 = 0x158E; } else { if (!(this->unk_322 & 1)) { this->unk_322 |= 1; - func_801518B0(globalCtx, 0x1587, &this->actor); + Message_StartTextbox(globalCtx, 0x1587, &this->actor); this->unk_324 = 0x1587; } else { - func_801518B0(globalCtx, 0x158C, &this->actor); + Message_StartTextbox(globalCtx, 0x158C, &this->actor); this->unk_324 = 0x158C; } } @@ -642,7 +628,7 @@ void func_80BD9A9C(EnPamera* this) { } void EnPamera_HandleDialogue(EnPamera* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: case 1: case 2: @@ -653,7 +639,7 @@ void EnPamera_HandleDialogue(EnPamera* this, GlobalContext* globalCtx) { func_80BD9B4C(this, globalCtx); break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80BD9938(this); } break; @@ -665,26 +651,26 @@ void EnPamera_HandleDialogue(EnPamera* this, GlobalContext* globalCtx) { } void func_80BD9B4C(EnPamera* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_324) { case 0x1587: - func_801518B0(globalCtx, 0x1588, &this->actor); + Message_StartTextbox(globalCtx, 0x1588, &this->actor); this->unk_324 = 0x1588; break; case 0x1588: - func_801518B0(globalCtx, 0x1589, &this->actor); + Message_StartTextbox(globalCtx, 0x1589, &this->actor); this->unk_324 = 0x1589; break; case 0x1589: - func_801518B0(globalCtx, 0x158A, &this->actor); + Message_StartTextbox(globalCtx, 0x158A, &this->actor); this->unk_324 = 0x158A; break; case 0x158A: - func_801518B0(globalCtx, 0x158B, &this->actor); + Message_StartTextbox(globalCtx, 0x158B, &this->actor); this->unk_324 = 0x158B; break; case 0x158C: - func_801518B0(globalCtx, 0x158D, &this->actor); + Message_StartTextbox(globalCtx, 0x158D, &this->actor); this->unk_324 = 0x158D; break; case 0x158E: @@ -704,21 +690,21 @@ void func_80BD9C70(EnPamera* this, GlobalContext* globalCtx) { } s32 func_80BD9CB8(EnPamera* this, GlobalContext* globalCtx) { - u32 actionIndex; + s32 actionIndex; - if (func_800EE29C(globalCtx, 0x1E5)) { - actionIndex = func_800EE200(globalCtx, 0x1E5); - if (this->unk_326 != globalCtx->csCtx.npcActions[actionIndex]->unk0) { - this->unk_326 = globalCtx->csCtx.npcActions[actionIndex]->unk0; + if (Cutscene_CheckActorAction(globalCtx, 0x1E5)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 0x1E5); + if (this->unk_326 != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->unk_326 = globalCtx->csCtx.actorActions[actionIndex]->action; - switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: func_80BD9E88(this); break; case 2: if (this->actor.draw == NULL) { this->actor.draw = EnPamera_Draw; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } func_80BD9EE0(this); break; @@ -736,11 +722,11 @@ s32 func_80BD9CB8(EnPamera* this, GlobalContext* globalCtx) { break; } } - func_800EDF24(&this->actor, globalCtx, actionIndex); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); this->setupFunc(this, globalCtx); return 1; } - if ((globalCtx->csCtx.state == 0) && (gSaveContext.weekEventReg[75] & 0x20)) { + if ((globalCtx->csCtx.state == 0) && (gSaveContext.save.weekEventReg[75] & 0x20)) { if ((this->actionFunc != func_80BD994C) && (this->actionFunc != EnPamera_HandleDialogue)) { this->actor.shape.rot.y = this->actor.world.rot.y; func_80BD9904(this); @@ -760,7 +746,7 @@ void func_80BD9E78(EnPamera* this, GlobalContext* globalCtx) { } void func_80BD9E88(EnPamera* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->unk_31E = 0; this->setupFunc = func_80BD9ED0; } @@ -769,7 +755,7 @@ void func_80BD9ED0(EnPamera* this, GlobalContext* globalCtx) { } void func_80BD9EE0(EnPamera* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 5); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); func_80BD93CC(this, 1, 0); this->unk_31E = 1; this->setupFunc = func_80BD9F3C; @@ -781,19 +767,19 @@ void func_80BD9F3C(EnPamera* this, GlobalContext* globalCtx) { Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 14.0f) || Animation_OnFrame(&this->skelAnime, 18.0f) || Animation_OnFrame(&this->skelAnime, 22.0f) || Animation_OnFrame(&this->skelAnime, 25.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_31E = 0; func_80BD93CC(this, 0, 0); - func_800BDC5C(&this->skelAnime, sAnimations, 6); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); } } } void func_80BDA038(EnPamera* this) { func_80BD93CC(this, 0, 1); - func_800BDC5C(&this->skelAnime, sAnimations, 7); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 7); this->unk_31E = 0; this->setupFunc = func_80BDA090; } @@ -803,7 +789,7 @@ void func_80BDA090(EnPamera* this, GlobalContext* globalCtx) { void func_80BDA0A0(EnPamera* this) { func_80BD93CC(this, 0, 1); - func_800BDC5C(&this->skelAnime, sAnimations, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); this->unk_31E = 1; this->setupFunc = func_80BDA0FC; } @@ -813,7 +799,7 @@ void func_80BDA0FC(EnPamera* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_31E = 0; func_80BD93CC(this, 0, 0); - func_800BDC5C(&this->skelAnime, sAnimations, 6); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); } } } @@ -821,7 +807,7 @@ void func_80BDA0FC(EnPamera* this, GlobalContext* globalCtx) { void func_80BDA170(EnPamera* this) { this->unk_31E = 1; func_80BD93CC(this, 0, 1); - func_800BDC5C(&this->skelAnime, sAnimations, 9); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 9); this->setupFunc = func_80BDA1C8; } @@ -829,12 +815,12 @@ void func_80BDA1C8(EnPamera* this, GlobalContext* globalCtx) { if (this->unk_31E == 1) { if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 14.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_31E = 0; func_80BD93CC(this, 0, 0); - func_800BDC5C(&this->skelAnime, sAnimations, 10); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 10); } } } @@ -842,7 +828,7 @@ void func_80BDA1C8(EnPamera* this, GlobalContext* globalCtx) { void func_80BDA288(EnPamera* this) { this->unk_31E = 1; func_80BD93CC(this, 0, 0); - func_800BDC5C(&this->skelAnime, sAnimations, 11); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 11); this->setupFunc = func_80BDA2E0; } @@ -850,7 +836,7 @@ void func_80BDA2E0(EnPamera* this, GlobalContext* globalCtx) { if (this->unk_31E == 1) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_31E = 0; - func_800BDC5C(&this->skelAnime, sAnimations, 12); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 12); } } } @@ -864,11 +850,11 @@ void func_80BDA344(Actor* thisx, GlobalContext* globalCtx) { func_80BD9384(this, globalCtx); if (func_80BD9CB8(this, globalCtx)) { // Pamela is outside - if (gSaveContext.weekEventReg[59] & 1) { - gSaveContext.weekEventReg[59] &= (u8)~1; + if (gSaveContext.save.weekEventReg[59] & 1) { + gSaveContext.save.weekEventReg[59] &= (u8)~1; } - if (!(gSaveContext.weekEventReg[61] & 4)) { - gSaveContext.weekEventReg[61] |= 4; + if (!(gSaveContext.save.weekEventReg[61] & 4)) { + gSaveContext.save.weekEventReg[61] |= 4; } func_800E8F08(&this->limb9Rot, &this->limb8Rot); } else { @@ -877,7 +863,7 @@ void func_80BDA344(Actor* thisx, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } - if (gSaveContext.weekEventReg[14] & 4) { + if (gSaveContext.save.weekEventReg[14] & 4) { globalCtx->roomCtx.unk7A[0]++; } } 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 2b8246f34..86b2eb671 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -1,14 +1,15 @@ /* * File: z_en_pametfrog.c - * Overlay: En_Pametfrog + * Overlay: ovl_En_Pametfrog * Description: Gekko & Snapper Miniboss: Gekko */ #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 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnPametfrog*)thisx) @@ -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, @@ -191,7 +170,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 10, ICHAIN_STOP), }; -// gSaveContext.weekEventReg[KEY] = VALUE +// gSaveContext.save.weekEventReg[KEY] = VALUE // KEY | VALUE static s32 isFrogReturnedFlags[] = { (32 << 8) | 0x40, // Woodfall Temple Frog Returned @@ -205,14 +184,15 @@ void EnPametfrog_Init(Actor* thisx, GlobalContext* globalCtx) { s32 i; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 55.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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)) { + if (Flags_GetClear(globalCtx, globalCtx->roomCtx.currRoom.num)) { Actor_MarkForDeath(&this->actor); - if (!(gSaveContext.weekEventReg[isFrogReturnedFlags[this->actor.params - 1] >> 8] & + if (!(gSaveContext.save.weekEventReg[isFrogReturnedFlags[this->actor.params - 1] >> 8] & (u8)isFrogReturnedFlags[this->actor.params - 1])) { Actor_Spawn(&globalCtx->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->params); @@ -250,33 +230,33 @@ u8 EnPametfrog_Vec3fNormalize(Vec3f* vec) { } } -void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) { - this->drawEffect = GEKKO_DRAW_EFFECT_FROZEN; +void EnPametfrog_Freeze(EnPametfrog* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; this->collider.base.colType = COLTYPE_HIT3; this->collider.elements->info.elemType = ELEMTYPE_UNK0; - this->unk_2C8 = 0.75f; - this->unk_2CC = 1.125f; - this->unk_2C4 = 1.0f; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffFrozenSteamScale = 1.125f; + this->drawDmgEffAlpha = 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; + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; 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); + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); } } void EnPametfrog_JumpWaterEffects(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f pos; - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { pos.x = this->actor.world.pos.x; pos.z = this->actor.world.pos.z; - pos.y = this->actor.world.pos.y + this->actor.yDistToWater; + pos.y = this->actor.world.pos.y + this->actor.depthInWater; EffectSsGRipple_Spawn(globalCtx, &pos, 150, 550, 0); pos.y += 8.0f; EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 0, 550); @@ -286,10 +266,10 @@ void EnPametfrog_JumpWaterEffects(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_IdleWaterEffects(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f pos; - if ((this->actor.yDistToWater > 0.0f) && ((globalCtx->gameplayFrames % 14) == 0)) { + if ((this->actor.depthInWater > 0.0f) && ((globalCtx->gameplayFrames % 14) == 0)) { pos.x = this->actor.world.pos.x; pos.z = this->actor.world.pos.z; - pos.y = this->actor.world.pos.y + this->actor.yDistToWater; + pos.y = this->actor.world.pos.y + this->actor.depthInWater; EffectSsGRipple_Spawn(globalCtx, &pos, 150, 550, 0); } } @@ -298,16 +278,16 @@ void func_8086A238(EnPametfrog* this) { MtxF unkMtx; unkMtx.xx = this->unk_2E8.x; - unkMtx.xy = this->unk_2E8.y; - unkMtx.xz = this->unk_2E8.z; - unkMtx.yx = this->unk_2DC.x; + unkMtx.yx = this->unk_2E8.y; + unkMtx.zx = this->unk_2E8.z; + unkMtx.xy = this->unk_2DC.x; unkMtx.yy = this->unk_2DC.y; - unkMtx.yz = this->unk_2DC.z; - unkMtx.zx = this->unk_2D0.x; - unkMtx.zy = this->unk_2D0.y; + unkMtx.zy = this->unk_2DC.z; + unkMtx.xz = this->unk_2D0.x; + unkMtx.yz = this->unk_2D0.y; unkMtx.zz = this->unk_2D0.z; - func_8018219C(&unkMtx, &this->actor.shape.rot, 0); + Matrix_MtxFToYXZRot(&unkMtx, &this->actor.shape.rot, false); this->actor.world.rot.x = -this->actor.shape.rot.x; this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.world.rot.z = this->actor.shape.rot.z; @@ -335,8 +315,8 @@ s32 func_8086A2CC(EnPametfrog* this, CollisionPoly* floorPoly) { Math3D_CrossProduct(&this->unk_2DC, &floorNorm, &vec2); EnPametfrog_Vec3fNormalize(&vec2); - Matrix_InsertRotationAroundUnitVector_f(rotation, &vec2, 0); - Matrix_MultiplyVector3fByState(&this->unk_2E8, &vec2); + Matrix_RotateAxisF(rotation, &vec2, MTXMODE_NEW); + Matrix_MultVec3f(&this->unk_2E8, &vec2); Math_Vec3f_Copy(&this->unk_2E8, &vec2); Math3D_CrossProduct(&this->unk_2E8, &floorNorm, &this->unk_2D0); EnPametfrog_Vec3fNormalize(&this->unk_2D0); @@ -345,24 +325,24 @@ s32 func_8086A2CC(EnPametfrog* this, CollisionPoly* floorPoly) { } void EnPametfrog_ShakeCamera(EnPametfrog* this, GlobalContext* globalCtx, f32 magShakeXZ, f32 magShakeY) { - Camera* camera = Play_GetCamera(globalCtx, this->camId); - s16 y; - Vec3f eye; + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + s16 subCamYaw; + Vec3f subCamEye; - y = BINANG_ROT180(func_800DFCDC(camera)); - eye.x = (Math_SinS(y) * magShakeXZ) + camera->at.x; - eye.y = camera->at.y + magShakeY; - eye.z = (Math_CosS(y) * magShakeXZ) + camera->at.z; - Play_CameraSetAtEye(globalCtx, this->camId, &camera->at, &eye); + subCamYaw = BINANG_ROT180(Camera_GetCamDirYaw(subCam)); + subCamEye.x = (Math_SinS(subCamYaw) * magShakeXZ) + subCam->at.x; + subCamEye.y = subCam->at.y + magShakeY; + subCamEye.z = (Math_CosS(subCamYaw) * magShakeXZ) + subCam->at.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); } void EnPametfrog_StopCutscene(EnPametfrog* this, GlobalContext* globalCtx) { - Camera* camera; + Camera* subCam; - if (this->camId != 0) { - camera = Play_GetCamera(globalCtx, this->camId); - Play_CameraSetAtEye(globalCtx, 0, &camera->at, &camera->eye); - this->camId = 0; + if (this->subCamId != CAM_ID_MAIN) { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Play_CameraSetAtEye(globalCtx, CAM_ID_MAIN, &subCam->at, &subCam->eye); + this->subCamId = CAM_ID_MAIN; ActorCutscene_Stop(this->cutscene); func_800B724C(globalCtx, &this->actor, 6); } @@ -370,7 +350,7 @@ void EnPametfrog_StopCutscene(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_PlaceSnapper(EnPametfrog* this, GlobalContext* globalCtx) { CollisionPoly* poly; - u32 bgId; + s32 bgId; Vec3f vec1; Vec3f vec2; Vec3f vec3; @@ -386,7 +366,7 @@ void EnPametfrog_PlaceSnapper(EnPametfrog* this, GlobalContext* globalCtx) { vec3.x = this->actor.child->world.pos.x; vec3.y = this->actor.child->world.pos.y - 150.0f; vec3.z = this->actor.child->world.pos.z; - if (func_800C55C4(&globalCtx->colCtx, &vec2, &vec3, &vec1, &poly, 0, 1, 0, 1, &bgId) != 0) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &vec2, &vec3, &vec1, &poly, false, true, false, true, &bgId)) { this->actor.child->floorHeight = vec1.y; } else { this->actor.child->floorHeight = this->actor.home.pos.y; @@ -398,55 +378,55 @@ void EnPametfrog_PlaceSnapper(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_JumpOnGround(EnPametfrog* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 1.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_JUMP); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_JUMP); } else if (Animation_OnFrame(&this->skelAnime, 11.0f)) { EnPametfrog_JumpWaterEffects(this, globalCtx); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_WALK_WATER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WALK_WATER); } } void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; - this->unk_2C4 = 3.0f; - this->unk_2C8 = 0.75f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 3.0f; + this->drawDmgEffScale = 0.75f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { - this->drawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; - this->unk_2C8 = 0.75f; - this->unk_2C4 = 3.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 3.0f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, 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); } } void EnPametfrog_ApplyElectricStun(EnPametfrog* this) { this->freezeTimer = 40; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); - func_800BCB70(&this->actor, 0, 255, 0, 40); - this->drawEffect = GEKKO_DRAW_EFFECT_ELECTRIC_STUN; - this->unk_2C8 = 0.75f; - this->unk_2C4 = 2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 2.0f; } void EnPametfrog_ApplyStun(EnPametfrog* this) { this->freezeTimer = 40; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); - func_800BCB70(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); } 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; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.params = GEKKO_ON_SNAPPER; this->actionFunc = EnPametfrog_RearOnSnapper; } @@ -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; @@ -514,24 +494,24 @@ void EnPametfrog_RearOnSnapperRise(EnPametfrog* this, GlobalContext* globalCtx) } void EnPametfrog_SetupFallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx) { - Vec3f eye; + Vec3f subCamEye; 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; this->actor.world.rot.y = BINANG_ROT180(this->actor.child->world.rot.y); this->actor.shape.rot.y = this->actor.world.rot.y; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->timer = 30; this->collider.base.ocFlags1 |= OC1_ON; yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); - eye.x = (Math_SinS(yaw) * 300.0f) + this->actor.focus.pos.x; - eye.y = this->actor.focus.pos.y + 100.0f; - eye.z = (Math_CosS(yaw) * 300.0f) + this->actor.focus.pos.z; - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.focus.pos, &eye); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE); + subCamEye.x = (Math_SinS(yaw) * 300.0f) + this->actor.focus.pos.x; + subCamEye.y = this->actor.focus.pos.y + 100.0f; + subCamEye.z = (Math_CosS(yaw) * 300.0f) + this->actor.focus.pos.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, &subCamEye); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_DAMAGE); this->actionFunc = EnPametfrog_FallOffSnapper; } @@ -554,11 +534,11 @@ 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; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_VOICE2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_VOICE2); this->actionFunc = EnPametfrog_JumpToWall; } @@ -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); @@ -601,7 +581,7 @@ void EnPametfrog_SetupWallCrawl(EnPametfrog* this) { this->skelAnime.playSpeed = 1.0f; } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_RUNAWAY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_RUNAWAY); this->actor.speedXZ = 8.0f; this->timer = Rand_S16Offset(35, 15); this->actionFunc = EnPametfrog_WallCrawl; @@ -615,8 +595,8 @@ void EnPametfrog_WallCrawl(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f worldPos1; Vec3f worldPos2; f32 doubleSpeedXZ; - u32 bgId1; - u32 bgId2; + s32 bgId1; + s32 bgId2; s32 isSuccess = false; if (this->freezeTimer > 0) { @@ -632,11 +612,13 @@ void EnPametfrog_WallCrawl(EnPametfrog* this, GlobalContext* globalCtx) { vec2.x = this->actor.world.pos.x - this->unk_2DC.x * 25.0f; vec2.y = this->actor.world.pos.y - this->unk_2DC.y * 25.0f; vec2.z = this->actor.world.pos.z - this->unk_2DC.z * 25.0f; - if (func_800C55C4(&globalCtx->colCtx, &vec1, &vec2, &worldPos2, &poly2, 1, 1, 1, 1, &bgId2) != 0) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &vec1, &vec2, &worldPos2, &poly2, true, true, true, true, + &bgId2)) { vec2.x = this->unk_2D0.x * doubleSpeedXZ + vec1.x; vec2.y = this->unk_2D0.y * doubleSpeedXZ + vec1.y; vec2.z = this->unk_2D0.z * doubleSpeedXZ + vec1.z; - if (func_800C55C4(&globalCtx->colCtx, &vec1, &vec2, &worldPos1, &poly1, 1, 1, 1, 1, &bgId1) != 0) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &vec1, &vec2, &worldPos1, &poly1, true, true, true, true, + &bgId1)) { isSuccess = func_8086A2CC(this, poly1); Math_Vec3f_Copy(&this->actor.world.pos, &worldPos1); this->actor.floorBgId = bgId1; @@ -657,11 +639,11 @@ void EnPametfrog_WallCrawl(EnPametfrog* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 15.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_BOMCHU_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BOMCHU_WALK); } if (((globalCtx->gameplayFrames % 60) == 0) && (Rand_ZeroOne() < 0.8f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_REAL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_REAL); } if ((this->timer == 0) || @@ -689,7 +671,7 @@ void EnPametfrog_SetupWallPause(EnPametfrog* this) { this->wallRotation = (Rand_ZeroOne() < 0.5f ? -1 : 1) * (0x1000 + randFloat) * (M_PI / (15 * 0x8000)); } this->timer = 15; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_RUNAWAY2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_RUNAWAY2); this->actionFunc = EnPametfrog_WallPause; } @@ -701,13 +683,13 @@ void EnPametfrog_WallPause(EnPametfrog* this, GlobalContext* globalCtx) { } else { SkelAnime_Update(&this->skelAnime); this->timer--; - Matrix_InsertRotationAroundUnitVector_f(this->wallRotation, &this->unk_2DC, 0); - Matrix_MultiplyVector3fByState(&this->unk_2D0, &vec); + Matrix_RotateAxisF(this->wallRotation, &this->unk_2DC, MTXMODE_NEW); + Matrix_MultVec3f(&this->unk_2D0, &vec); Math_Vec3f_Copy(&this->unk_2D0, &vec); Math3D_CrossProduct(&this->unk_2DC, &this->unk_2D0, &this->unk_2E8); func_8086A238(this); if (((globalCtx->gameplayFrames % 60) == 0) && (Rand_ZeroOne() < 0.8f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_REAL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_REAL); } if (this->timer == 0) { @@ -719,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; @@ -742,7 +725,7 @@ void EnPametfrog_ClimbDownWall(EnPametfrog* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 1) { EnPametfrog_SetupRunToSnapper(this); - } else if (this->actor.floorHeight == -32000.0f) { + } else if (this->actor.floorHeight == BGCHECK_Y_MIN) { yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); this->actor.world.pos.x += 5.0f * Math_SinS(yaw); this->actor.world.pos.z += 5.0f * Math_CosS(yaw); @@ -753,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; } @@ -776,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; @@ -785,7 +768,7 @@ void EnPametfrog_SetupJumpOnSnapper(EnPametfrog* this) { this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, this->actor.child); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.params = GEKKO_JUMP_ON_SNAPPER; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_GREET); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_GREET); this->actionFunc = EnPametfrog_JumpOnSnapper; } @@ -808,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; @@ -823,10 +806,10 @@ void EnPametfrog_LandOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { s16 yaw; - Vec3f eye; + Vec3f subCamEye; 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; } @@ -836,16 +819,16 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { this->collider.base.acFlags &= ~AC_ON; this->timer = 10; if (this->actor.colChkInfo.health == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_DEAD); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_DAMAGE); } - func_800BCB70(&this->actor, 0x4000, 255, 0, 16); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 16); yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); this->actor.world.pos.x += 30.0f * Math_SinS(yaw); this->actor.world.pos.z += 30.0f * Math_CosS(yaw); - if (this->camId != 0) { + if (this->subCamId != CAM_ID_MAIN) { xzDist = sqrtf(SQXZ(this->unk_2DC)); if (xzDist > 0.001f) { xzDist = 200.0f / xzDist; @@ -855,10 +838,10 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { this->unk_2DC.z = 0.0f; } - eye.x = this->actor.world.pos.x + (xzDist * this->unk_2DC.x); - eye.y = (this->actor.world.pos.y + this->actor.home.pos.y) * 0.5f; - eye.z = this->actor.world.pos.z + (xzDist * this->unk_2DC.z); - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, &eye); + subCamEye.x = this->actor.world.pos.x + (xzDist * this->unk_2DC.x); + subCamEye.y = (this->actor.world.pos.y + this->actor.home.pos.y) * 0.5f; + subCamEye.z = this->actor.world.pos.z + (xzDist * this->unk_2DC.z); + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.world.pos, &subCamEye); } this->actionFunc = EnPametfrog_FallInAir; @@ -875,9 +858,9 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) { } } else { this->spinYaw += 0xF00; - if (this->camId != 0) { - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, - &Play_GetCamera(globalCtx, this->camId)->eye); + if (this->subCamId != CAM_ID_MAIN) { + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.world.pos, + &Play_GetCamera(globalCtx, this->subCamId)->eye); } if (this->actor.bgCheckFlags & 1) { @@ -887,28 +870,28 @@ 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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WALK_WATER); this->actionFunc = EnPametfrog_FallOnGround; } 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); @@ -917,15 +900,15 @@ void EnPametfrog_FallOnGround(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupDefeatGekko(EnPametfrog* this, GlobalContext* globalCtx) { - Vec3f eye; + Vec3f subCamEye; s16 yaw = Actor_YawToPoint(this->actor.child, &this->actor.home.pos); s16 yawDiff = this->actor.yawTowardsPlayer - yaw; yaw = yawDiff > 0 ? yaw - 0x2000 : yaw + 0x2000; - eye.x = this->actor.child->focus.pos.x + 150.0f * Math_SinS(yaw); - eye.y = this->actor.child->focus.pos.y + 20.0f; - eye.z = this->actor.child->focus.pos.z + 150.0f * Math_CosS(yaw); - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.child->focus.pos, &eye); + subCamEye.x = this->actor.child->focus.pos.x + 150.0f * Math_SinS(yaw); + subCamEye.y = this->actor.child->focus.pos.y + 20.0f; + subCamEye.z = this->actor.child->focus.pos.z + 150.0f * Math_CosS(yaw); + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.child->focus.pos, &subCamEye); this->actor.params = GEKKO_DEFEAT; this->timer = 38; this->actionFunc = EnPametfrog_DefeatGekko; @@ -942,15 +925,15 @@ void EnPametfrog_DefeatGekko(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupDefeatSnapper(EnPametfrog* this, GlobalContext* globalCtx) { - Vec3f eye; + Vec3f subCamEye; s16 yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); s16 yawDiff = this->actor.yawTowardsPlayer - yaw; yaw = yawDiff > 0 ? yaw - 0x2000 : yaw + 0x2000; - eye.x = this->actor.world.pos.x + Math_SinS(yaw) * 150.0f; - eye.y = this->actor.world.pos.y + 20.0f; - eye.z = this->actor.world.pos.z + Math_CosS(yaw) * 150.0f; - Play_CameraSetAtEye(globalCtx, this->camId, &this->actor.world.pos, &eye); + subCamEye.x = this->actor.world.pos.x + Math_SinS(yaw) * 150.0f; + subCamEye.y = this->actor.world.pos.y + 20.0f; + subCamEye.z = this->actor.world.pos.z + Math_CosS(yaw) * 150.0f; + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.world.pos, &subCamEye); this->timer = 20; this->actionFunc = EnPametfrog_DefeatSnapper; } @@ -969,7 +952,7 @@ void EnPametfrog_SetupSpawnFrog(EnPametfrog* this, GlobalContext* globalCtx) { static Vec3f sAccel = { 0.0f, -0.5f, 0.0f }; static Color_RGBA8 primColor = { 250, 250, 250, 255 }; static Color_RGBA8 envColor = { 180, 180, 180, 255 }; - s16 yaw = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); + s16 yaw = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); Vec3f vec1; Vec3f vel; s32 i; @@ -980,9 +963,9 @@ 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); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); - Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); + func_800B0DE0(globalCtx, &vec1, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 800, 50); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); + Flags_SetClearTemp(globalCtx, globalCtx->roomCtx.currRoom.num); for (i = 0; i < 25; i++) { vel.x = randPlusMinusPoint5Scaled(5.0f); @@ -1024,7 +1007,7 @@ void EnPametfrog_SetupCutscene(EnPametfrog* this) { void EnPametfrog_PlayCutscene(EnPametfrog* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_Start(this->cutscene, &this->actor); - this->camId = ActorCutscene_GetCurrentCamera(this->cutscene); + this->subCamId = ActorCutscene_GetCurrentCamera(this->cutscene); func_800B724C(globalCtx, &this->actor, 7); if (this->actor.colChkInfo.health == 0) { if (this->actor.params == GEKKO_PRE_SNAPPER) { @@ -1041,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; @@ -1052,9 +1035,9 @@ void EnPametfrog_LookAround(EnPametfrog* this, GlobalContext* globalCtx) { EnPametfrog_IdleWaterEffects(this, globalCtx); Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 5, 0x400, 0x80); this->actor.shape.rot.y = this->actor.world.rot.y; - if (SkelAnime_Update(&this->skelAnime) && (func_801690CC(globalCtx) == 0)) { + if (SkelAnime_Update(&this->skelAnime) && !Play_InCsMode(globalCtx)) { if (!this->unk_2AE) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); this->unk_2AE = true; } EnPametfrog_SetupJumpToLink(this); @@ -1062,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; @@ -1080,24 +1063,24 @@ void EnPametfrog_JumpToLink(EnPametfrog* this, GlobalContext* globalCtx) { } if ((this->collider.base.ocFlags1 & OC1_HIT) && (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) && - Actor_IsActorFacingLink(&this->actor, 0x3000) && + Actor_IsFacingPlayer(&this->actor, 0x3000) && (this->skelAnime.curFrame <= 2.0f || this->skelAnime.curFrame >= 11.0f)) { EnPametfrog_SetupMeleeAttack(this); } } 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) { @@ -1107,21 +1090,21 @@ 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) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_KICK); + if (this->skelAnime.animation == &gGekkoKickAnim) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_KICK); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_PUNCH1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_PUNCH1); } } else { this->collider.base.atFlags &= ~AT_ON; @@ -1129,13 +1112,13 @@ 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; this->actor.speedXZ = 10.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_DAMAGE); - func_800BCB70(&this->actor, 0x4000, 255, 0, 20); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_DAMAGE); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); func_800BE5CC(&this->actor, &this->collider, 0); this->actor.shape.rot.y = BINANG_ROT180(this->actor.world.rot.y); this->actionFunc = EnPametfrog_Damage; @@ -1155,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); } @@ -1173,23 +1156,23 @@ 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); } } void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { - Vec3f eye; - Vec3f at; + Vec3f subCamEye; + Vec3f subCamAt; s16 yawDiff; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001B08, 3.0f); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_GREET); - this->actor.flags &= ~1; + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoCallAnim, 3.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FROG_GREET); + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.colChkInfo.health = 6; this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; @@ -1200,15 +1183,15 @@ void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } this->actor.shape.rot.y = this->actor.world.rot.y; - at.x = this->actor.world.pos.x; - at.z = this->actor.world.pos.z; - at.y = this->actor.world.pos.y + 45.0f; - eye.x = (Math_SinS(this->actor.shape.rot.y) * 90.0f) + at.x; - eye.z = (Math_CosS(this->actor.shape.rot.y) * 90.0f) + at.z; - eye.y = at.y + 4.0f; + subCamAt.x = this->actor.world.pos.x; + subCamAt.z = this->actor.world.pos.z; + subCamAt.y = this->actor.world.pos.y + 45.0f; + subCamEye.x = (Math_SinS(this->actor.shape.rot.y) * 90.0f) + subCamAt.x; + subCamEye.z = (Math_CosS(this->actor.shape.rot.y) * 90.0f) + subCamAt.z; + subCamEye.y = subCamAt.y + 4.0f; // Zooms in on Gekko - Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); this->timer = 0; this->actor.hintId = 0x5F; this->actionFunc = EnPametfrog_CallSnapper; @@ -1221,26 +1204,26 @@ void EnPametfrog_CallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupSnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx) { - Vec3f at; - Vec3f eye; + Vec3f subCamAt; + Vec3f subCamEye; s16 yaw; EnPametfrog_PlaceSnapper(this, globalCtx); - at.x = this->actor.child->world.pos.x; - at.z = this->actor.child->world.pos.z; - at.y = this->actor.child->floorHeight + 50.0f; + subCamAt.x = this->actor.child->world.pos.x; + subCamAt.z = this->actor.child->world.pos.z; + subCamAt.y = this->actor.child->floorHeight + 50.0f; if ((s16)(Actor_YawToPoint(&this->actor, &this->actor.home.pos) - this->actor.shape.rot.y) > 0) { yaw = this->actor.child->shape.rot.y - 0x1000; } else { yaw = this->actor.child->shape.rot.y + 0x1000; } - eye.x = (Math_SinS(yaw) * 500.0f) + at.x; - eye.y = at.y + 55.0f; - eye.z = (Math_CosS(yaw) * 500.0f) + at.z; + subCamEye.x = (Math_SinS(yaw) * 500.0f) + subCamAt.x; + subCamEye.y = subCamAt.y + 55.0f; + subCamEye.z = (Math_CosS(yaw) * 500.0f) + subCamAt.z; // Zooms in on Snapper spawn point - Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); this->quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 6); Quake_SetSpeed(this->quake, 18000); Quake_SetQuakeValues(this->quake, 2, 0, 0, 0); @@ -1274,7 +1257,7 @@ void EnPametfrog_SetupTransitionGekkoSnapper(EnPametfrog* this, GlobalContext* g void EnPametfrog_TransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx) { if (this->actor.params == GEKKO_INIT_SNAPPER) { - func_801A2E54(0x38); + func_801A2E54(NA_BGM_MINI_BOSS); EnPametfrog_SetupRunToSnapper(this); } } @@ -1282,7 +1265,7 @@ void EnPametfrog_TransitionGekkoSnapper(EnPametfrog* this, GlobalContext* global void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - if ((this->drawEffect != GEKKO_DRAW_EFFECT_FROZEN) || + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || !(this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { if (this->actor.params == GEKKO_PRE_SNAPPER) { if (Actor_ApplyDamage(&this->actor) == 0) { @@ -1296,20 +1279,20 @@ 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); + Actor_SetColorFilter(&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->unk_2C8 = 0.75f; - this->unk_2C4 = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { - this->drawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; - this->unk_2C8 = 0.75f; - this->unk_2C4 = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->collider.elements[0].info.bumper.hitPos.x, this->collider.elements[0].info.bumper.hitPos.y, @@ -1322,7 +1305,7 @@ void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) this->collider.base.acFlags &= ~AC_ON; EnPametfrog_ApplyMagicArrowEffects(this, globalCtx); Enemy_StartFinishingBlow(globalCtx, &this->actor); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; func_801A2ED8(); EnPametfrog_SetupCutscene(this); } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ZORA_BARRIER) { @@ -1353,11 +1336,11 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); if ((this->actionFunc != EnPametfrog_JumpOnSnapper) && (this->actionFunc != EnPametfrog_RearOnSnapperRise)) { if (this->actor.gravity < -0.1f) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); arg3 = this->actionFunc == EnPametfrog_FallInAir ? 3.0f : 15.0f; Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, arg3, 3.0f, 0x1F); } else if (this->freezeTimer == 0) { - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); this->actor.floorHeight = this->actor.world.pos.y; } } @@ -1374,46 +1357,47 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) { CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } - if (this->unk_2C4 > 0.0f) { - if ((this->drawEffect != GEKKO_DRAW_EFFECT_FROZEN) && (this->actionFunc != EnPametfrog_PlayCutscene)) { - Math_StepToF(&this->unk_2C4, 0.0f, 0.05f); - unk2C4 = ((this->unk_2C4 + 1.0f) * 0.375f); - this->unk_2C8 = unk2C4; - this->unk_2C8 = unk2C4 > 0.75f ? 0.75f : this->unk_2C8; - } else if (!Math_StepToF(&this->unk_2CC, 0.75f, (3.0f / 160.0f))) { + if (this->drawDmgEffAlpha > 0.0f) { + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->actionFunc != EnPametfrog_PlayCutscene)) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + unk2C4 = ((this->drawDmgEffAlpha + 1.0f) * 0.375f); + this->drawDmgEffScale = unk2C4; + this->drawDmgEffScale = unk2C4 > 0.75f ? 0.75f : this->drawDmgEffScale; + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, (3.0f / 160.0f))) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } } -/* 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, }; -void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnPametfrog* this = (EnPametfrog*)arg; +void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnPametfrog* this = THIS; Vec3f vec; Vec3s* center; s8 index; if (limbIndex == GEKKO_LIMB_HEAD) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); this->actor.focus.rot.y = this->actor.shape.rot.y; - Matrix_GetStateTranslationAndScaledY(2500.0f, &vec); + Matrix_MultVecY(2500.0f, &vec); center = &this->collider.elements[0].dim.worldSphere.center; center->x = vec.x; center->y = vec.y; @@ -1426,7 +1410,7 @@ void EnPametfrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi index = limbPosIndex[limbIndex]; if (index != -1) { - Matrix_GetStateTranslation(&this->limbPos[index]); + Matrix_MultZero(&this->limbPos[index]); } } @@ -1434,9 +1418,9 @@ void EnPametfrog_Draw(Actor* thisx, GlobalContext* globalCtx) { EnPametfrog* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - Matrix_RotateY(this->spinYaw, MTXMODE_APPLY); + Matrix_RotateYS(this->spinYaw, MTXMODE_APPLY); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, EnPametfrog_PostLimbDraw, &this->actor); - func_800BE680(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->unk_2C8, this->unk_2CC, - this->unk_2C4, this->drawEffect); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); } 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..1a10575cf 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h @@ -20,13 +20,6 @@ typedef enum { /* 0x9 */ GEKKO_DEFEAT, } EnPametfrogState; -typedef enum { - /* 00 */ GEKKO_DRAW_EFFECT_NONE, // May be GEKKO_DRAW_EFFECT_THAW - /* 10 */ GEKKO_DRAW_EFFECT_FROZEN = 10, - /* 20 */ GEKKO_DRAW_EFFECT_LIGHT_ORBS = 20, - /* 30 */ GEKKO_DRAW_EFFECT_ELECTRIC_STUN = 30, -} EnPametfrogDrawEffectType; - typedef enum { /* 0x00 */ GEKKO_LIMB_NONE, /* 0x01 */ GEKKO_LIMB_ROOT, @@ -61,7 +54,7 @@ typedef struct EnPametfrog { /* 0x188 */ Vec3s jointTable[GEKKO_LIMB_MAX]; /* 0x218 */ Vec3s morphTable[GEKKO_LIMB_MAX]; /* 0x2A8 */ EnPametfrogActionFunc actionFunc; - /* 0x2AC */ u8 drawEffect; + /* 0x2AC */ u8 drawDmgEffType; /* 0x2AD */ u8 wallPauseTimer; // Gekko stops 10 times along wall/ceiling after being blown off of Snapper /* 0x2AE */ u8 unk_2AE; // True/False /* 0x2B0 */ s16 cutscene; @@ -69,15 +62,15 @@ typedef struct EnPametfrog { /* 0x2B4 */ s16 quake; /* 0x2B6 */ s16 timer; /* 0x2B8 */ s16 spinYaw; - /* 0x2BA */ s16 camId; + /* 0x2BA */ s16 subCamId; /* 0x2BC */ s16 freezeTimer; /* 0x2C0 */ f32 wallRotation; - /* 0x2C4 */ f32 unk_2C4; - /* 0x2C8 */ f32 unk_2C8; - /* 0x2CC */ f32 unk_2CC; - /* 0x2D0 */ Vec3f unk_2D0; // MtxF zx/zy/zz - /* 0x2DC */ Vec3f unk_2DC; // MtxF yx/yy/yz: wallNorm/floorNorm/Base of Gekko walking??? - /* 0x2E8 */ Vec3f unk_2E8; // MtxF xx/xy/xz + /* 0x2C4 */ f32 drawDmgEffAlpha; + /* 0x2C8 */ f32 drawDmgEffScale; + /* 0x2CC */ f32 drawDmgEffFrozenSteamScale; + /* 0x2D0 */ Vec3f unk_2D0; // MtxF xz/yz/zz + /* 0x2DC */ Vec3f unk_2DC; // MtxF xy/yy/zy: wallNorm/floorNorm/Base of Gekko walking??? + /* 0x2E8 */ Vec3f unk_2E8; // MtxF xx/yx/zx /* 0x2F4 */ Vec3f limbPos[12]; /* 0x384 */ ColliderJntSph collider; /* 0x3A4 */ ColliderJntSphElement colElement[2]; diff --git a/src/overlays/actors/ovl_En_Paper/z_en_paper.c b/src/overlays/actors/ovl_En_Paper/z_en_paper.c index 037541cf4..50e364529 100644 --- a/src/overlays/actors/ovl_En_Paper/z_en_paper.c +++ b/src/overlays/actors/ovl_En_Paper/z_en_paper.c @@ -1,6 +1,12 @@ +/* + * File: z_en_paper.c + * Overlay: ovl_En_Paper + * Description: Tingle Confetti + */ + #include "z_en_paper.h" -#define FLAGS 0x02100010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((EnPaper*)thisx) 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 e574ee53a..bbf098c92 100644 --- a/src/overlays/actors/ovl_En_Part/z_en_part.c +++ b/src/overlays/actors/ovl_En_Part/z_en_part.c @@ -1,6 +1,12 @@ +/* + * File: z_en_part.c + * Overlay: ovl_En_Part + * Description: Enemy body parts (spawned when dying) + */ + #include "z_en_part.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnPart*)thisx) diff --git a/src/overlays/actors/ovl_En_Part/z_en_part.h b/src/overlays/actors/ovl_En_Part/z_en_part.h index be5c5b503..fa3dd410f 100644 --- a/src/overlays/actors/ovl_En_Part/z_en_part.h +++ b/src/overlays/actors/ovl_En_Part/z_en_part.h @@ -7,7 +7,8 @@ struct EnPart; typedef struct EnPart { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x10]; + /* 0x144 */ char unk_144[0xC]; + /* 0x150 */ Gfx* unk_150; } EnPart; // size = 0x154 extern const ActorInit En_Part_InitVars; 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 f56e49f05..708bae3ef 100644 --- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c +++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c @@ -1,6 +1,14 @@ -#include "z_en_peehat.h" +/* + * File: z_en_peehat.c + * Overlay: ovl_En_Peehat + * Description: Peahat + */ -#define FLAGS 0x00000015 +#include "z_en_peehat.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_ph/object_ph.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnPeehat*)thisx) @@ -9,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, @@ -22,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), @@ -90,98 +162,790 @@ 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, ActorShadow_DrawCircle, 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.save.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->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 1.1f; + this->drawDmgEffFrozenSteamScale = 1.6500001f; + this->drawDmgEffAlpha = 1.0f; + this->colliderSphere.base.colType = COLTYPE_HIT3; + this->unk_2B0 = 80; + Actor_SetColorFilter(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->colliderSphere.base.colType = COLTYPE_HIT6; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 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; + Actor_PlaySfxAtPos(&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.save.isNight) { + this->actor.flags |= ACTOR_FLAG_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 &= ~ACTOR_FLAG_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; + Actor_PlaySfxAtPos(&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.save.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); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + if (!(this->actor.bgCheckFlags & 1)) { + SoundSource_PlaySfxAtFixedWorldPos(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; + Actor_PlaySfxAtPos(&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.save.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.save.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); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_EXTINCT); + SoundSource_PlaySfxAtFixedWorldPos(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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIHAT_DAMAGE); + this->unk_2B2 = 4000; + this->unk_2B0 = 14; + this->actor.speedXZ = 10.0f; + Actor_SetColorFilter(&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->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(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); + Actor_SetDropFlag(&this->actor, &this->colliderSphere.info); + func_808971DC(this, globalCtx); + + if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_2B0 = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffScale = 1.1f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + func_80898414(this); + } else if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2B0 = 40; + Actor_SetColorFilter(&this->actor, 0, 200, 0, 40); + Actor_PlaySfxAtPos(&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->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 2.1f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 1.1f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (this->colliderCylinder.base.acFlags & AC_HIT) && + ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(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_MoveWithGravity(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_SetFocus(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, + true, true, false, true, &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->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) { + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 1.05f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 2.1f); + } else { + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.55f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 1.1f); + } + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 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_Push(); + Matrix_RotateXFApply(this->unk_2BC * 0.115f); + Matrix_RotateYF(this->unk_2BC * 0.13f, MTXMODE_APPLY); + Matrix_RotateZF(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_RotateZF(-(this->unk_2BC * 0.1f), MTXMODE_APPLY); + Matrix_RotateYF(-(this->unk_2BC * 0.13f), MTXMODE_APPLY); + Matrix_RotateXFApply(-(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_Pop(); + + 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_MultVecX(2000.0f, &this->limbPos[index]); + Matrix_MultVecX(4000.0f, &this->limbPos[index + 1]); + } + + if (limbIndex == 4) { + Matrix_MultVecZ(5500.0f, &this->unk_2D4[0]); + Matrix_MultVecZ(-5500.0f, &this->unk_2D4[1]); + } else if ((limbIndex == 3) && (thisx->params == 0)) { + Vec3f* vec = &D_80899570[0]; + Vec3f* vec2 = &this->limbPos[12]; + + for (i = 0; i < ARRAY_COUNT(D_80899570); i++, vec++, vec2++) { + Matrix_MultVec3f(vec, vec2); + } + + Matrix_MultVecX(3000.0f, vec2++); + Matrix_MultVecX(-400.0f, vec2); + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_OPA_DISP; + + Matrix_Translate(-1000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Collider_UpdateSphere(0, &this->colliderSphere); + Matrix_Translate(500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateYF(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_MultVecZ(4500.0f, &sp40); + Matrix_MultVecZ(-4500.0f, &sp4C); + Matrix_MultVecX(4500.0f, &sp58); + Collider_SetTrisVertices(&this->colliderTris, 0, &sp40, &sp4C, &sp58); + Matrix_MultVecX(-4500.0f, &sp58); + Collider_SetTrisVertices(&this->colliderTris, 1, &sp40, &sp58, &sp4C); + } + + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) { + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { + this->limbPos[i].y -= 50.0f; + } + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); +} 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..a7bda3577 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 drawDmgEffType; + /* 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 drawDmgEffAlpha; + /* 0x2CC */ f32 drawDmgEffScale; + /* 0x2D0 */ f32 drawDmgEffFrozenSteamScale; + /* 0x2D4 */ Vec3f unk_2D4[2]; + /* 0x2EC */ Vec3f limbPos[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 62620a035..bc41461d9 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -1,6 +1,14 @@ -#include "z_en_pm.h" +/* + * File: z_en_pm.c + * Overlay: ovl_En_Pm + * Description: Postman + */ -#define FLAGS 0x00000039 +#include "z_en_pm.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_mm/object_mm.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnPm*)thisx) @@ -12,7 +20,458 @@ void EnPm_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80AFA4D0(EnPm* this, GlobalContext* globalCtx); void func_80AFA5FC(EnPm* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80AFAD80[] = { + /* 0x000 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(1, 0x240 - 0x005), + /* 0x005 */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x00C), + /* 0x00C */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(12, 0, 13, 1, 0x10C - 0x013), + /* 0x013 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 15, 0, 0x02B - 0x019), + /* 0x019 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 0, 0, 5, 0x020 - 0x01F), + /* 0x01F */ SCHEDULE_CMD_RET_NONE(), + /* 0x020 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x02A - 0x024), + /* 0x024 */ SCHEDULE_CMD_RET_TIME(15, 0, 0, 5, 8), + /* 0x02A */ SCHEDULE_CMD_RET_NONE(), + /* 0x02B */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x060 - 0x02F), + /* 0x02F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 13, 4, 0x05A - 0x035), + /* 0x035 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 4, 13, 21, 0x054 - 0x03B), + /* 0x03B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 48, 14, 56, 0x04E - 0x041), + /* 0x041 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 56, 15, 0, 0x048 - 0x047), + /* 0x047 */ SCHEDULE_CMD_RET_NONE(), + /* 0x048 */ SCHEDULE_CMD_RET_TIME(14, 56, 15, 0, 2), + /* 0x04E */ SCHEDULE_CMD_RET_TIME(14, 48, 14, 56, 62), + /* 0x054 */ SCHEDULE_CMD_RET_TIME(13, 4, 13, 21, 53), + /* 0x05A */ SCHEDULE_CMD_RET_TIME(13, 1, 13, 4, 1), + /* 0x060 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x095 - 0x064), + /* 0x064 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 4, 13, 21, 0x08F - 0x06A), + /* 0x06A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 21, 13, 39, 0x089 - 0x070), + /* 0x070 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 38, 14, 48, 0x083 - 0x076), + /* 0x076 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 48, 14, 56, 0x07D - 0x07C), + /* 0x07C */ SCHEDULE_CMD_RET_NONE(), + /* 0x07D */ SCHEDULE_CMD_RET_TIME(14, 48, 14, 56, 61), + /* 0x083 */ SCHEDULE_CMD_RET_TIME(14, 38, 14, 48, 60), + /* 0x089 */ SCHEDULE_CMD_RET_TIME(13, 21, 13, 39, 55), + /* 0x08F */ SCHEDULE_CMD_RET_TIME(13, 4, 13, 21, 54), + /* 0x095 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x0CA - 0x099), + /* 0x099 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 39, 13, 56, 0x0C4 - 0x09F), + /* 0x09F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 56, 14, 0, 0x0BE - 0x0A5), + /* 0x0A5 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 26, 14, 30, 0x0B8 - 0x0AB), + /* 0x0AB */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 30, 14, 38, 0x0B2 - 0x0B1), + /* 0x0B1 */ SCHEDULE_CMD_RET_NONE(), + /* 0x0B2 */ SCHEDULE_CMD_RET_TIME(14, 30, 14, 38, 59), + /* 0x0B8 */ SCHEDULE_CMD_RET_TIME(14, 26, 14, 30, 11), + /* 0x0BE */ SCHEDULE_CMD_RET_TIME(13, 56, 14, 0, 10), + /* 0x0C4 */ SCHEDULE_CMD_RET_TIME(13, 39, 13, 56, 56), + /* 0x0CA */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_YADOYA, 0x10B - 0x0CE), + /* 0x0CE */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 56, 14, 0, 0x105 - 0x0D4), + /* 0x0D4 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 0, 14, 8, 0x0FF - 0x0DA), + /* 0x0DA */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 8, 14, 18, 0x0F9 - 0x0E0), + /* 0x0E0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 18, 14, 26, 0x0F3 - 0x0E6), + /* 0x0E6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 26, 14, 30, 0x0ED - 0x0EC), + /* 0x0EC */ SCHEDULE_CMD_RET_NONE(), + /* 0x0ED */ SCHEDULE_CMD_RET_TIME(14, 26, 14, 30, 13), + /* 0x0F3 */ SCHEDULE_CMD_RET_TIME(14, 18, 14, 26, 58), + /* 0x0F9 */ SCHEDULE_CMD_RET_TIME(14, 8, 14, 18, 16), + /* 0x0FF */ SCHEDULE_CMD_RET_TIME(14, 0, 14, 8, 57), + /* 0x105 */ SCHEDULE_CMD_RET_TIME(13, 56, 14, 0, 12), + /* 0x10B */ SCHEDULE_CMD_RET_NONE(), + /* 0x10C */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x116 - 0x110), + /* 0x110 */ SCHEDULE_CMD_RET_TIME(12, 0, 13, 1, 9), + /* 0x116 */ SCHEDULE_CMD_RET_NONE(), + /* 0x117 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x14C - 0x11B), + /* 0x11B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 0, 9, 3, 0x146 - 0x121), + /* 0x121 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 3, 9, 17, 0x140 - 0x127), + /* 0x127 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 43, 11, 57, 0x13A - 0x12D), + /* 0x12D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 57, 12, 0, 0x134 - 0x133), + /* 0x133 */ SCHEDULE_CMD_RET_NONE(), + /* 0x134 */ SCHEDULE_CMD_RET_TIME(11, 57, 12, 0, 2), + /* 0x13A */ SCHEDULE_CMD_RET_TIME(11, 43, 11, 57, 52), + /* 0x140 */ SCHEDULE_CMD_RET_TIME(9, 3, 9, 17, 38), + /* 0x146 */ SCHEDULE_CMD_RET_TIME(9, 0, 9, 3, 1), + /* 0x14C */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x1B1 - 0x150), + /* 0x150 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 3, 9, 17, 0x1AB - 0x156), + /* 0x156 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 17, 9, 31, 0x1A5 - 0x15C), + /* 0x15C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 31, 9, 35, 0x19F - 0x162), + /* 0x162 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 35, 9, 49, 0x199 - 0x168), + /* 0x168 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 57, 11, 11, 0x193 - 0x16E), + /* 0x16E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 11, 11, 25, 0x18D - 0x174), + /* 0x174 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 25, 11, 29, 0x187 - 0x17A), + /* 0x17A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 29, 11, 43, 0x181 - 0x180), + /* 0x180 */ SCHEDULE_CMD_RET_NONE(), + /* 0x181 */ SCHEDULE_CMD_RET_TIME(11, 29, 11, 43, 50), + /* 0x187 */ SCHEDULE_CMD_RET_TIME(11, 25, 11, 29, 7), + /* 0x18D */ SCHEDULE_CMD_RET_TIME(11, 11, 11, 25, 48), + /* 0x193 */ SCHEDULE_CMD_RET_TIME(10, 57, 11, 11, 47), + /* 0x199 */ SCHEDULE_CMD_RET_TIME(9, 35, 9, 49, 41), + /* 0x19F */ SCHEDULE_CMD_RET_TIME(9, 31, 9, 35, 3), + /* 0x1A5 */ SCHEDULE_CMD_RET_TIME(9, 17, 9, 31, 40), + /* 0x1AB */ SCHEDULE_CMD_RET_TIME(9, 3, 9, 17, 39), + /* 0x1B1 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_BACKTOWN, 0x1DA - 0x1B5), + /* 0x1B5 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 49, 10, 3, 0x1D4 - 0x1BB), + /* 0x1BB */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 3, 10, 7, 0x1CE - 0x1C1), + /* 0x1C1 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 7, 10, 21, 0x1C8 - 0x1C7), + /* 0x1C7 */ SCHEDULE_CMD_RET_NONE(), + /* 0x1C8 */ SCHEDULE_CMD_RET_TIME(10, 7, 10, 21, 43), + /* 0x1CE */ SCHEDULE_CMD_RET_TIME(10, 3, 10, 7, 4), + /* 0x1D4 */ SCHEDULE_CMD_RET_TIME(9, 49, 10, 3, 42), + /* 0x1DA */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x23F - 0x1DE), + /* 0x1DE */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 21, 10, 35, 0x239 - 0x1E4), + /* 0x1E4 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 35, 10, 39, 0x233 - 0x1EA), + /* 0x1EA */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 39, 10, 53, 0x22D - 0x1F0), + /* 0x1F0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 53, 10, 57, 0x227 - 0x1F6), + /* 0x1F6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(10, 57, 11, 11, 0x221 - 0x1FC), + /* 0x1FC */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 11, 11, 25, 0x21B - 0x202), + /* 0x202 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 25, 11, 29, 0x215 - 0x208), + /* 0x208 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(11, 29, 11, 43, 0x20F - 0x20E), + /* 0x20E */ SCHEDULE_CMD_RET_NONE(), + /* 0x20F */ SCHEDULE_CMD_RET_TIME(11, 29, 11, 43, 51), + /* 0x215 */ SCHEDULE_CMD_RET_TIME(11, 25, 11, 29, 7), + /* 0x21B */ SCHEDULE_CMD_RET_TIME(11, 11, 11, 25, 49), + /* 0x221 */ SCHEDULE_CMD_RET_TIME(10, 57, 11, 11, 46), + /* 0x227 */ SCHEDULE_CMD_RET_TIME(10, 53, 10, 57, 6), + /* 0x22D */ SCHEDULE_CMD_RET_TIME(10, 39, 10, 53, 45), + /* 0x233 */ SCHEDULE_CMD_RET_TIME(10, 35, 10, 39, 5), + /* 0x239 */ SCHEDULE_CMD_RET_TIME(10, 21, 10, 35, 44), + /* 0x23F */ SCHEDULE_CMD_RET_NONE(), + /* 0x240 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(2, 0x414 - 0x245), + /* 0x245 */ SCHEDULE_CMD_CHECK_FLAG_L(0x1C, 0x08, 0x2EF - 0x24A), + /* 0x24A */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x251), + /* 0x251 */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(12, 0, 13, 1, 0x2E4 - 0x258), + /* 0x258 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 15, 0, 0x2DC - 0x25E), + /* 0x25E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 2, 0, 0x265 - 0x264), + /* 0x264 */ SCHEDULE_CMD_RET_NONE(), + /* 0x265 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x29A - 0x269), + /* 0x269 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 4, 0x294 - 0x26F), + /* 0x26F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 4, 0, 31, 0x28E - 0x275), + /* 0x275 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 29, 1, 56, 0x288 - 0x27B), + /* 0x27B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 56, 2, 0, 0x282 - 0x281), + /* 0x281 */ SCHEDULE_CMD_RET_NONE(), + /* 0x282 */ SCHEDULE_CMD_RET_TIME(1, 56, 2, 0, 2), + /* 0x288 */ SCHEDULE_CMD_RET_TIME(1, 29, 1, 56, 79), + /* 0x28E */ SCHEDULE_CMD_RET_TIME(0, 4, 0, 31, 74), + /* 0x294 */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 4, 1), + /* 0x29A */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x2DB - 0x29E), + /* 0x29E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 4, 0, 31, 0x2D5 - 0x2A4), + /* 0x2A4 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 31, 0, 58, 0x2CF - 0x2AA), + /* 0x2AA */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 58, 1, 2, 0x2C9 - 0x2B0), + /* 0x2B0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 2, 1, 29, 0x2C3 - 0x2B6), + /* 0x2B6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 29, 1, 56, 0x2BD - 0x2BC), + /* 0x2BC */ SCHEDULE_CMD_RET_NONE(), + /* 0x2BD */ SCHEDULE_CMD_RET_TIME(1, 29, 1, 56, 78), + /* 0x2C3 */ SCHEDULE_CMD_RET_TIME(1, 2, 1, 29, 77), + /* 0x2C9 */ SCHEDULE_CMD_RET_TIME(0, 58, 1, 2, 18), + /* 0x2CF */ SCHEDULE_CMD_RET_TIME(0, 31, 0, 58, 76), + /* 0x2D5 */ SCHEDULE_CMD_RET_TIME(0, 4, 0, 31, 75), + /* 0x2DB */ SCHEDULE_CMD_RET_NONE(), + /* 0x2DC */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x2E3 - 0x2E0), + /* 0x2E0 */ SCHEDULE_CMD_RET_VAL_L(14), + /* 0x2E3 */ SCHEDULE_CMD_RET_NONE(), + /* 0x2E4 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x2EE - 0x2E8), + /* 0x2E8 */ SCHEDULE_CMD_RET_TIME(12, 0, 13, 1, 20), + /* 0x2EE */ SCHEDULE_CMD_RET_NONE(), + /* 0x2EF */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x2F6), + /* 0x2F6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(12, 0, 13, 1, 0x409 - 0x2FD), + /* 0x2FD */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 17, 0, 0x315 - 0x303), + /* 0x303 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(17, 0, 0, 5, 0x30A - 0x309), + /* 0x309 */ SCHEDULE_CMD_RET_NONE(), + /* 0x30A */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x314 - 0x30E), + /* 0x30E */ SCHEDULE_CMD_RET_TIME(17, 0, 0, 5, 8), + /* 0x314 */ SCHEDULE_CMD_RET_NONE(), + /* 0x315 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x34A - 0x319), + /* 0x319 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 13, 4, 0x344 - 0x31F), + /* 0x31F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 4, 13, 15, 0x33E - 0x325), + /* 0x325 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 35, 16, 57, 0x338 - 0x32B), + /* 0x32B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 57, 17, 0, 0x332 - 0x331), + /* 0x331 */ SCHEDULE_CMD_RET_NONE(), + /* 0x332 */ SCHEDULE_CMD_RET_TIME(16, 57, 17, 0, 2), + /* 0x338 */ SCHEDULE_CMD_RET_TIME(16, 35, 16, 57, 73), + /* 0x33E */ SCHEDULE_CMD_RET_TIME(13, 4, 13, 15, 63), + /* 0x344 */ SCHEDULE_CMD_RET_TIME(13, 1, 13, 4, 1), + /* 0x34A */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x37F - 0x34E), + /* 0x34E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 4, 13, 15, 0x379 - 0x354), + /* 0x354 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 15, 13, 30, 0x373 - 0x35A), + /* 0x35A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 52, 14, 45, 0x36D - 0x360), + /* 0x360 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(16, 15, 16, 35, 0x367 - 0x366), + /* 0x366 */ SCHEDULE_CMD_RET_NONE(), + /* 0x367 */ SCHEDULE_CMD_RET_TIME(16, 15, 16, 35, 72), + /* 0x36D */ SCHEDULE_CMD_RET_TIME(13, 52, 14, 45, 67), + /* 0x373 */ SCHEDULE_CMD_RET_TIME(13, 15, 13, 30, 65), + /* 0x379 */ SCHEDULE_CMD_RET_TIME(13, 4, 13, 15, 64), + /* 0x37F */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x39C - 0x383), + /* 0x383 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 30, 13, 52, 0x396 - 0x389), + /* 0x389 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 52, 14, 50, 0x390 - 0x38F), + /* 0x38F */ SCHEDULE_CMD_RET_NONE(), + /* 0x390 */ SCHEDULE_CMD_RET_TIME(13, 52, 14, 50, 68), + /* 0x396 */ SCHEDULE_CMD_RET_TIME(13, 30, 13, 52, 66), + /* 0x39C */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ALLEY, 0x408 - 0x3A0), + /* 0x3A0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 45, 15, 5, 0x402 - 0x3A6), + /* 0x3A6 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x3DB - 0x3AA), + /* 0x3AA */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 5, 15, 20, 0x3D5 - 0x3B0), + /* 0x3B0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 20, 15, 25, 0x3CF - 0x3B6), + /* 0x3B6 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 25, 15, 40, 0x3C9 - 0x3BC), + /* 0x3BC */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 40, 16, 15, 0x3C3 - 0x3C2), + /* 0x3C2 */ SCHEDULE_CMD_RET_NONE(), + /* 0x3C3 */ SCHEDULE_CMD_RET_TIME(15, 40, 16, 15, 81), + /* 0x3C9 */ SCHEDULE_CMD_RET_TIME(15, 25, 15, 40, 17), + /* 0x3CF */ SCHEDULE_CMD_RET_TIME(15, 20, 15, 25, 80), + /* 0x3D5 */ SCHEDULE_CMD_RET_TIME(15, 5, 15, 20, 23), + /* 0x3DB */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 5, 15, 20, 0x3FC - 0x3E1), + /* 0x3E1 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 20, 15, 50, 0x3F6 - 0x3E7), + /* 0x3E7 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(15, 50, 16, 15, 0x3F0 - 0x3ED), + /* 0x3ED */ SCHEDULE_CMD_RET_VAL_L(0), + /* 0x3F0 */ SCHEDULE_CMD_RET_TIME(15, 50, 16, 15, 71), + /* 0x3F6 */ SCHEDULE_CMD_RET_TIME(15, 20, 15, 50, 25), + /* 0x3FC */ SCHEDULE_CMD_RET_TIME(15, 5, 15, 20, 23), + /* 0x402 */ SCHEDULE_CMD_RET_TIME(14, 45, 15, 5, 70), + /* 0x408 */ SCHEDULE_CMD_RET_NONE(), + /* 0x409 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x413 - 0x40D), + /* 0x40D */ SCHEDULE_CMD_RET_TIME(12, 0, 13, 1, 21), + /* 0x413 */ SCHEDULE_CMD_RET_NONE(), + /* 0x414 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_L(3, 0x588 - 0x419), + /* 0x419 */ SCHEDULE_CMD_CHECK_FLAG_L(0x1C, 0x08, 0x55D - 0x41E), + /* 0x41E */ SCHEDULE_CMD_CHECK_FLAG_L(0x1C, 0x10, 0x52F - 0x423), + /* 0x423 */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x42A), + /* 0x42A */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(12, 0, 13, 1, 0x527 - 0x431), + /* 0x431 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 1, 15, 0, 0x446 - 0x437), + /* 0x437 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x43E - 0x43D), + /* 0x43D */ SCHEDULE_CMD_RET_NONE(), + /* 0x43E */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x445 - 0x442), + /* 0x442 */ SCHEDULE_CMD_RET_VAL_L(24), + /* 0x445 */ SCHEDULE_CMD_RET_NONE(), + /* 0x446 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x47B - 0x44A), + /* 0x44A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 0, 13, 1, 0x475 - 0x450), + /* 0x450 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 5, 13, 15, 0x46F - 0x456), + /* 0x456 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 45, 14, 55, 0x469 - 0x45C), + /* 0x45C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 55, 15, 0, 0x463 - 0x462), + /* 0x462 */ SCHEDULE_CMD_RET_NONE(), + /* 0x463 */ SCHEDULE_CMD_RET_TIME(14, 55, 15, 0, 2), + /* 0x469 */ SCHEDULE_CMD_RET_TIME(14, 45, 14, 55, 52), + /* 0x46F */ SCHEDULE_CMD_RET_TIME(13, 5, 13, 15, 38), + /* 0x475 */ SCHEDULE_CMD_RET_TIME(13, 0, 13, 1, 1), + /* 0x47B */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x4C8 - 0x47F), + /* 0x47F */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 5, 13, 15, 0x4C2 - 0x485), + /* 0x485 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 15, 13, 25, 0x4BC - 0x48B), + /* 0x48B */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 25, 13, 35, 0x4B6 - 0x491), + /* 0x491 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 15, 14, 25, 0x4B0 - 0x497), + /* 0x497 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 25, 14, 35, 0x4AA - 0x49D), + /* 0x49D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 35, 14, 45, 0x4A4 - 0x4A3), + /* 0x4A3 */ SCHEDULE_CMD_RET_NONE(), + /* 0x4A4 */ SCHEDULE_CMD_RET_TIME(14, 35, 14, 45, 50), + /* 0x4AA */ SCHEDULE_CMD_RET_TIME(14, 25, 14, 35, 48), + /* 0x4B0 */ SCHEDULE_CMD_RET_TIME(14, 15, 14, 25, 47), + /* 0x4B6 */ SCHEDULE_CMD_RET_TIME(13, 25, 13, 35, 41), + /* 0x4BC */ SCHEDULE_CMD_RET_TIME(13, 15, 13, 25, 40), + /* 0x4C2 */ SCHEDULE_CMD_RET_TIME(13, 5, 13, 15, 39), + /* 0x4C8 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_BACKTOWN, 0x4E5 - 0x4CC), + /* 0x4CC */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 35, 13, 45, 0x4DF - 0x4D2), + /* 0x4D2 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 45, 13, 55, 0x4D9 - 0x4D8), + /* 0x4D8 */ SCHEDULE_CMD_RET_NONE(), + /* 0x4D9 */ SCHEDULE_CMD_RET_TIME(13, 45, 13, 55, 43), + /* 0x4DF */ SCHEDULE_CMD_RET_TIME(13, 35, 13, 45, 42), + /* 0x4E5 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x526 - 0x4E9), + /* 0x4E9 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(13, 55, 14, 5, 0x520 - 0x4EF), + /* 0x4EF */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 5, 14, 15, 0x51A - 0x4F5), + /* 0x4F5 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 15, 14, 25, 0x514 - 0x4FB), + /* 0x4FB */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 25, 14, 35, 0x50E - 0x501), + /* 0x501 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(14, 35, 14, 45, 0x508 - 0x507), + /* 0x507 */ SCHEDULE_CMD_RET_NONE(), + /* 0x508 */ SCHEDULE_CMD_RET_TIME(14, 35, 14, 45, 51), + /* 0x50E */ SCHEDULE_CMD_RET_TIME(14, 25, 14, 35, 49), + /* 0x514 */ SCHEDULE_CMD_RET_TIME(14, 15, 14, 25, 46), + /* 0x51A */ SCHEDULE_CMD_RET_TIME(14, 5, 14, 15, 45), + /* 0x520 */ SCHEDULE_CMD_RET_TIME(13, 55, 14, 5, 44), + /* 0x526 */ SCHEDULE_CMD_RET_NONE(), + /* 0x527 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x52E - 0x52B), + /* 0x52B */ SCHEDULE_CMD_RET_VAL_L(22), + /* 0x52E */ SCHEDULE_CMD_RET_NONE(), + /* 0x52F */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x536), + /* 0x536 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 0, 13, 1, 0x552 - 0x53C), + /* 0x53C */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(13, 1, 17, 0, 0x315 - 0x543), + /* 0x543 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x54A - 0x549), + /* 0x549 */ SCHEDULE_CMD_RET_NONE(), + /* 0x54A */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x551 - 0x54E), + /* 0x54E */ SCHEDULE_CMD_RET_VAL_L(24), + /* 0x551 */ SCHEDULE_CMD_RET_NONE(), + /* 0x552 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x55C - 0x556), + /* 0x556 */ SCHEDULE_CMD_RET_TIME(12, 0, 13, 1, 21), + /* 0x55C */ SCHEDULE_CMD_RET_NONE(), + /* 0x55D */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(9, 0, 12, 0, 0x117 - 0x564), + /* 0x564 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(12, 0, 13, 1, 0x580 - 0x56A), + /* 0x56A */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(13, 1, 15, 0, 0x446 - 0x571), + /* 0x571 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x578 - 0x577), + /* 0x577 */ SCHEDULE_CMD_RET_NONE(), + /* 0x578 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x57F - 0x57C), + /* 0x57C */ SCHEDULE_CMD_RET_VAL_L(24), + /* 0x57F */ SCHEDULE_CMD_RET_NONE(), + /* 0x580 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x587 - 0x584), + /* 0x584 */ SCHEDULE_CMD_RET_VAL_L(20), + /* 0x587 */ SCHEDULE_CMD_RET_NONE(), + /* 0x588 */ SCHEDULE_CMD_RET_NONE(), +}; + +static u8 D_80AFB30C[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_POSTHOUSE, 0x32 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 10, 0x2C - 0x0A), + /* 0x0A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 10, 0, 13, 0x29 - 0x10), + /* 0x10 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 13, 0, 23, 0x23 - 0x16), + /* 0x16 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 23, 0, 26, 0x1D - 0x1C), + /* 0x1C */ SCHEDULE_CMD_RET_NONE(), + /* 0x1D */ SCHEDULE_CMD_RET_TIME(0, 23, 0, 26, 32), + /* 0x23 */ SCHEDULE_CMD_RET_TIME(0, 13, 0, 23, 83), + /* 0x29 */ SCHEDULE_CMD_RET_VAL_L(27), + /* 0x2C */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 10, 82), + /* 0x32 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x4F - 0x36), + /* 0x36 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 23, 0, 26, 0x49 - 0x3C), + /* 0x3C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 26, 0, 36, 0x43 - 0x42), + /* 0x42 */ SCHEDULE_CMD_RET_NONE(), + /* 0x43 */ SCHEDULE_CMD_RET_TIME(0, 26, 0, 36, 84), + /* 0x49 */ SCHEDULE_CMD_RET_TIME(0, 23, 0, 26, 33), + /* 0x4F */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_CLOCKTOWER, 0x6C - 0x53), + /* 0x53 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 26, 0, 36, 0x66 - 0x59), + /* 0x59 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 36, 0, 46, 0x60 - 0x5F), + /* 0x5F */ SCHEDULE_CMD_RET_NONE(), + /* 0x60 */ SCHEDULE_CMD_RET_TIME(0, 36, 0, 46, 86), + /* 0x66 */ SCHEDULE_CMD_RET_TIME(0, 26, 0, 36, 85), + /* 0x6C */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x89 - 0x70), + /* 0x70 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 46, 0, 56, 0x83 - 0x76), + /* 0x76 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 56, 0, 59, 0x7D - 0x7C), + /* 0x7C */ SCHEDULE_CMD_RET_NONE(), + /* 0x7D */ SCHEDULE_CMD_RET_TIME(0, 56, 0, 59, 34), + /* 0x83 */ SCHEDULE_CMD_RET_TIME(0, 46, 0, 56, 87), + /* 0x89 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0xB2 - 0x8D), + /* 0x8D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 56, 0, 59, 0xAC - 0x93), + /* 0x93 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 59, 1, 9, 0xA6 - 0x99), + /* 0x99 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 9, 1, 40, 0xA0 - 0x9F), + /* 0x9F */ SCHEDULE_CMD_RET_NONE(), + /* 0xA0 */ SCHEDULE_CMD_RET_TIME(1, 9, 1, 40, 28), + /* 0xA6 */ SCHEDULE_CMD_RET_TIME(0, 59, 1, 9, 88), + /* 0xAC */ SCHEDULE_CMD_RET_TIME(0, 56, 0, 59, 36), + /* 0xB2 */ SCHEDULE_CMD_RET_NONE(), +}; + +static u8 D_80AFB3C0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x1D - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 10, 0, 13, 0x17 - 0x0A), + /* 0x0A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 13, 0, 23, 0x11 - 0x10), + /* 0x10 */ SCHEDULE_CMD_RET_NONE(), + /* 0x11 */ SCHEDULE_CMD_RET_TIME(0, 13, 0, 23, 90), + /* 0x17 */ SCHEDULE_CMD_RET_TIME(0, 10, 0, 13, 35), + /* 0x1D */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0x3A - 0x21), + /* 0x21 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 10, 0x34 - 0x27), + /* 0x27 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 10, 0, 13, 0x2E - 0x2D), + /* 0x2D */ SCHEDULE_CMD_RET_NONE(), + /* 0x2E */ SCHEDULE_CMD_RET_TIME(0, 10, 0, 13, 37), + /* 0x34 */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 10, 89), + /* 0x3A */ SCHEDULE_CMD_RET_NONE(), +}; + +static u8 D_80AFB3FC[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x1D - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x17 - 0x0A), + /* 0x0A */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(5, 0, 5, 10, 0x11 - 0x10), + /* 0x10 */ SCHEDULE_CMD_RET_NONE(), + /* 0x11 */ SCHEDULE_CMD_RET_TIME(5, 0, 5, 10, 91), + /* 0x17 */ SCHEDULE_CMD_RET_TIME(18, 0, 6, 0, 29), + /* 0x1D */ SCHEDULE_CMD_RET_NONE(), +}; + +static u8 D_80AFB41C[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_TOWN, 0x11 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 10, 0x0B - 0x0A), + /* 0x0A */ SCHEDULE_CMD_RET_NONE(), + /* 0x0B */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 10, 91), + /* 0x11 */ SCHEDULE_CMD_RET_NONE(), +}; + +static s32 D_80AFB430[] = { + -1, 0, 4, 1, 0, 0, 1, 4, -1, -1, 15, 5, 0, 3, -1, -1, 1, 2, 11, 3, -1, -1, -1, 0, 0, 0, 0, 0, 1, 12, -1, + -1, 2, 0, 10, 11, 0, 3, 1, 0, 1, 2, 0, 1, 0, 1, 2, 3, 4, 3, 5, 14, 3, 1, 0, 6, 4, 1, 2, 6, 7, 8, + 2, 1, 0, 6, 7, 9, 8, -1, 0, 1, 10, 3, 1, 0, 11, 12, 8, 2, 2, 3, 0, 1, 1, 0, 6, 9, 1, 2, 12, 13, +}; + +// Game scripts +static UNK_TYPE D_80AFB5A0[] = { + 0x00560800, 0x45090000, 0x170E28BA, 0x0C090000, 0x180E28BB, 0x0C090000, 0x170E28BC, 0x0C090000, 0x180E28BD, + 0x0C090000, 0x170E28BE, 0x0C090000, 0x180E28BF, 0x0C090000, 0x170E28C0, 0x2D00012D, 0x000B0C09, 0x00001156, + 0x08100900, 0x00170E29, 0x5C0C0900, 0x00180E29, 0x5D0C0900, 0x00170E29, 0x5E2D0001, 0x2D000B0C, 0x09000010, +}; + +static UNK_TYPE D_80AFB60C[] = { + 0x0E27742D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB614[] = { + 0x0E27752D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB61C[] = { + 0x0E27772D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB624[] = { + 0x0E27782D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB62C[] = { + 0x0E27792D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB634[] = { + 0x0E27812D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB63C[] = { + 0x0E277A2D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB644[] = { + 0x0E27822D, + 0x000B0C11, + 0x58021000, +}; + +static UNK_TYPE D_80AFB650[] = { + 0x0E27832D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB658[] = { + 0x25002E00, 0x1A005280, 0x000C0E27, 0x7C2D000B, 0x0C115280, 0x12100E27, 0x7D2D000B, 0x0C12100E, 0x277C0C0E, + 0x00FF1E00, 0x33000000, 0x1800282C, 0xFFFF0900, 0x000E277E, 0x2D000B0C, 0x11528011, 0x56012A00, 0x2E12102C, + 0x277D0C2F, 0x00002D00, 0x0B0C1152, 0x8012100E, 0x277D2D00, 0x0B0C1152, 0x80121000, +}; + +static UNK_TYPE D_80AFB6BC[] = { + 0x0900000E, 0x27A50C09, 0x0000170E, 0x27A60C09, 0x0000180E, 0x27A70C09, 0x0000170E, + 0x27A80C09, 0x0000180E, 0x27A90C09, 0x0000170E, 0x27AA0C09, 0x0000180E, 0x27AB0C09, + 0x0000170E, 0x27AC0C09, 0x0000180E, 0x27AD2D00, 0x0B2D0008, 0x0C115908, 0x09000010, +}; + +static UNK_TYPE D_80AFB710[] = { + 0x25003E00, 0x230E2780, 0x0C0F27AE, 0x0C120600, 0x84000013, 0x0084115A, 0x042F0000, + 0x2E2D000B, 0x2D00310C, 0x115A0110, 0x0E27802D, 0x000B0C11, 0x5A011210, +}; + +static UNK_TYPE D_80AFB744[] = { + 0x0E23692D, + 0x000B0C10, +}; + +static UNK_TYPE D_80AFB74C[] = { + 0x2CFFFF09, 0x00000E27, 0x7E2D000B, 0x0C115280, 0x1156012A, 0x002E1210, +}; + +static UNK_TYPE D_80AFB764[] = { + 0x2C277D2D, + 0x000B0C11, + 0x52801210, +}; + const ActorInit En_Pm_InitVars = { ACTOR_EN_PM, ACTORCAT_NPC, @@ -25,128 +484,1716 @@ const ActorInit En_Pm_InitVars = { (ActorFunc)EnPm_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AFB790 = { - { 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_80AFB7BC = { - { 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 }, 26 }, 100 }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80AFB7E8 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_mm_Anim_002238, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_002238, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_mm_Anim_00A4E0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_mm_Anim_00B09C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_00B09C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_mm_Anim_00BA78, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_mm_Anim_00C32C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_mm_Anim_0099B4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_000FC4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_00A8D8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_00099C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_001F84, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_mm_Anim_000468, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_mm_Anim_00C640, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern ColliderCylinderInit D_80AFB790; -extern ColliderSphereInit D_80AFB7BC; -extern CollisionCheckInfoInit2 D_80AFB7E8; +s32 func_80AF7B40(void) { + if (gSaveContext.save.weekEventReg[90] & 1) { + return 4; + } -extern UNK_TYPE D_06008348; -extern UNK_TYPE D_060096E8; + if (gSaveContext.save.weekEventReg[89] & 0x40) { + return 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7B40.s") + if (gSaveContext.save.weekEventReg[89] & 8) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7BAC.s") + if (gSaveContext.save.weekEventReg[86] & 1) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7CB0.s") + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7D60.s") +s32 func_80AF7BAC(EnPm* this) { + switch (this->unk_38C) { + case 0: + if (gSaveContext.save.weekEventReg[86] & 1) { + D_801F4E78 = gSaveContext.save.time; + this->unk_38C++; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7DC4.s") + case 1: + if (gSaveContext.save.weekEventReg[89] & 8) { + D_801F4E78 = gSaveContext.save.time; + this->unk_38C++; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7E6C.s") + case 2: + if (gSaveContext.save.weekEventReg[89] & 0x40) { + D_801F4E78 = 0; + this->unk_38C++; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7E98.s") + case 3: + if (gSaveContext.save.weekEventReg[90] & 1) { + D_801F4E78 = gSaveContext.save.time; + this->unk_38C++; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF7F68.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8040.s") +Actor* func_80AF7CB0(EnPm* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* phi_s0 = NULL; + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF80F4.s") + while (true) { + actor = SubS_FindActor(globalCtx, phi_s0, actorCat, actorId); + phi_s0 = actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8170.s") + if (actor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF81E8.s") + if (((EnPm*)phi_s0 != this) && (actor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8348.s") + actor = actor->next; + if (actor == NULL) { + phi_s0 = NULL; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8478.s") + phi_s0 = actor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8540.s") + return phi_s0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF86F0.s") +EnDoor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) { + s32 phi_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF87C4.s") + switch (arg1) { + case 1: + case 2: + case 32: + case 33: + phi_a1 = 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8890.s") + case 34: + case 35: + case 36: + case 37: + phi_a1 = 10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF898C.s") + case 10: + case 11: + case 12: + case 13: + phi_a1 = 11; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8AC8.s") + default: + return NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8BA8.s") + return SubS_FindDoor(globalCtx, phi_a1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8C68.s") +Actor* func_80AF7DC4(EnPm* this, GlobalContext* globalCtx, s32 arg2) { + Actor* phi_s0 = NULL; + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8D84.s") + while (true) { + actor = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_PROP, ACTOR_EN_PST); + phi_s0 = actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8DD4.s") + if (actor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF8ED4.s") + if (((EnPm*)actor != this) && (actor->update != NULL) && (actor->params == (s16)arg2)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9008.s") + actor = actor->next; + if (actor == NULL) { + phi_s0 = NULL; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF91E8.s") + phi_s0 = actor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF94AC.s") + return phi_s0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF95E8.s") +void func_80AF7E6C(EnPm* this) { + this->skelAnime.playSpeed = this->unk_35C; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF98A0.s") +s32 func_80AF7E98(EnPm* this, s32 arg1) { + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF992C.s") + switch (arg1) { + case 0: + case 1: + if ((this->unk_384 != 0) && (this->unk_384 != 1)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9A0C.s") + case 3: + case 4: + if ((this->unk_384 != 3) && (this->unk_384 != 4)) { + phi_v1 = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9AB0.s") + default: + if (arg1 != this->unk_384) { + phi_v1 = true; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9B54.s") + if (phi_v1) { + this->unk_384 = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->unk_35C = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9BF8.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9D04.s") +void func_80AF7F68(EnPm* this, GlobalContext* globalCtx) { + f32 temp; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AF9E7C.s") + switch (this->unk_258) { + case 9: + case 20: + case 21: + case 22: + case 24: + temp = this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; + this->colliderSphere.dim.worldSphere.radius = temp; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA170.s") + default: + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + temp = this->actor.focus.pos.y - this->actor.world.pos.y; + this->colliderCylinder.dim.height = temp; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA334.s") +Actor* func_80AF8040(EnPm* this, GlobalContext* globalCtx) { + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA438.s") + switch (this->unk_258) { + case 16: + actor = func_80AF7CB0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AN); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA4D0.s") + case 17: + actor = func_80AF7CB0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TEST3); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA5FC.s") + case 28: + actor = func_80AF7CB0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFA724.s") + case 3: + case 4: + case 5: + case 6: + case 7: + actor = func_80AF7DC4(this, globalCtx, this->unk_258 - 3); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/EnPm_Init.s") + case 19: + actor = func_80AF7DC4(this, globalCtx, 4); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/EnPm_Destroy.s") + case 18: + actor = func_80AF7DC4(this, globalCtx, 4); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/EnPm_Update.s") + default: + actor = &GET_PLAYER(globalCtx)->actor; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFAA04.s") + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFAA44.s") +s32 func_80AF80F4(EnPm* this, s16 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pm/func_80AFABAC.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_Pm/EnPm_Draw.s") +s16 func_80AF8170(EnPm* this, s32 arg1) { + s32 i; + s16 cs = -1; + + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + cs = this->actor.child->cutscene; + + for (i = 0; i < arg1; i++) { + cs = ActorCutscene_GetAdditionalCutscene(cs); + } + } + return cs; +} + +s32 func_80AF81E8(EnPm* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A = func_80AF8170(this, 0); + s32 ret = false; + + switch (this->unk_378) { + case 0: + if (!func_80AF80F4(this, sp2A)) { + break; + } + + case 2: + case 4: + case 6: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), + this->actor.child); + } + this->unk_378++; + ret = true; + break; + + case 1: + case 3: + case 5: + if ((gSaveContext.save.weekEventReg[86] & 8) && (this->unk_378 == 3)) { + ActorCutscene_Stop(sp2A); + } else { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + } + this->unk_378++; + ret = true; + break; + + case 7: + ActorCutscene_Stop(sp2A); + this->unk_378++; + ret = true; + break; + } + return ret; +} + +s32 func_80AF8348(EnPm* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A = func_80AF8170(this, 0); + s32 ret = false; + + switch (this->unk_378) { + case 0: + if (!func_80AF80F4(this, sp2A)) { + break; + } + + case 2: + case 4: + case 6: + case 8: + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + this->unk_378++; + ret = true; + break; + + case 1: + case 3: + case 5: + case 7: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + Camera_SetTargetActor(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), + this->actor.child); + } + this->unk_378++; + ret = true; + break; + + case 9: + ActorCutscene_Stop(sp2A); + this->unk_378++; + ret = true; + break; + } + + return ret; +} + +s32 func_80AF8478(EnPm* this, GlobalContext* globalCtx) { + s32 pad; + s32 ret = false; + + switch (this->unk_378) { + case 0: + func_80AF7E98(this, 2); + this->unk_356 &= ~0x20; + this->unk_356 |= 0x200; + this->unk_378++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80AF7E98(this, 4); + this->unk_356 &= ~0x200; + this->unk_356 |= 0x20; + this->unk_378++; + ret = true; + } + break; + } + return ret; +} + +UNK_TYPE* func_80AF8540(EnPm* this, GlobalContext* globalCtx) { + switch (this->unk_258) { + case 28: + this->unk_37C = func_80AF8348; + return D_80AFB6BC; + + case 29: + return D_80AFB710; + + case 16: + this->unk_37C = func_80AF81E8; + return D_80AFB5A0; + + case 17: + return D_80AFB644; + + case 24: + if (this->unk_356 & 0x2000) { + this->unk_37C = func_80AF8478; + return D_80AFB74C; + } else if (this->unk_356 & 0x4000) { + return D_80AFB764; + } else { + this->unk_37C = func_80AF8478; + return D_80AFB658; + } + break; + + case 25: + return D_80AFB650; + + default: + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + return D_80AFB744; + } + + switch (this->unk_258) { + case 9: + return D_80AFB614; + + case 14: + return D_80AFB624; + + case 20: + return D_80AFB61C; + + case 21: + return D_80AFB634; + + case 22: + return D_80AFB63C; + + case 18: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + return D_80AFB62C; + + default: + return D_80AFB60C; + } + break; + } +} + +s32 func_80AF86F0(EnPm* this, GlobalContext* globalCtx) { + s32 ret = false; + + if ((this->unk_356 & 7) && Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_356, 0, 7); + this->unk_398 = 0; + this->unk_378 = 0; + this->unk_37C = NULL; + this->actor.child = this->unk_268; + this->unk_25C = func_80AF8540(this, globalCtx); + if ((this->unk_258 != 24) && (this->unk_258 != 9) && (this->unk_258 != 20) && (this->unk_258 != 21) && + (this->unk_258 != 22)) { + this->unk_356 |= 0x20; + } + this->actionFunc = func_80AFA5FC; + ret = true; + } + return ret; +} + +s32 func_80AF87C4(EnPm* this, GlobalContext* globalCtx) { + s32 ret = false; + + if ((globalCtx->csCtx.state != 0) && (globalCtx->sceneNum == SCENE_00KEIKOKU) && + (gSaveContext.sceneSetupIndex == 9) && (globalCtx->curSpawn == 1)) { + if (!this->unk_380) { + func_80AF7E98(this, 0); + this->unk_258 = 255; + this->unk_380 = true; + this->actor.speedXZ = 4.0f; + this->actor.gravity = -1.0f; + } + ret = true; + } else if (this->unk_380) { + this->unk_258 = 0; + this->unk_380 = false; + this->actor.speedXZ = 0.0f; + } + return ret; +} + +void func_80AF8890(EnPm* this, Gfx** gfx, s32 arg2) { + Matrix_Push(); + + switch (arg2) { + case 0: + if (this->unk_356 & 0x800) { + gSPDisplayList((*gfx)++, object_mm_DL_008348); + } + break; + + case 1: + if (this->unk_356 & 0x1000) { + gSPDisplayList((*gfx)++, object_mm_DL_0085C8); + } + break; + + case 2: + if (this->unk_356 & 0x1000) { + gSPDisplayList((*gfx)++, object_mm_DL_0083E0); + } + break; + } + + Matrix_Pop(); +} + +void func_80AF898C(EnPm* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s32 pad2; + + Math_Vec3f_Copy(&sp40, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->unk_372, Math_Vec3f_Yaw(&sp34, &sp40) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_372 = CLAMP(this->unk_372, -0x1FFE, 0x1FFE); + 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_370, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x2AA8); + this->unk_370 = CLAMP(this->unk_370, -0x1554, 0x1554); +} + +void func_80AF8AC8(EnPm* this) { + if ((this->unk_356 & 0x20) && (this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + if (DECR(this->unk_376) == 0) { + func_80AF898C(this); + this->unk_356 &= ~0x200; + this->unk_356 |= 0x80; + return; + } + } + + if (this->unk_356 & 0x80) { + this->unk_356 &= ~0x80; + this->unk_370 = 0; + this->unk_372 = 0; + this->unk_376 = 20; + } else if (DECR(this->unk_376) == 0) { + this->unk_356 |= 0x200; + } +} + +void func_80AF8BA8(s32 arg0) { + static u16 D_80AFB8D4[] = { + 0x1B02, 0x1B04, 0x1B08, 0x1B10, 0x1B20, + }; + static u16 D_80AFB8E0[] = { + 0x1B40, 0x1B80, 0x1C01, 0x1C02, 0x1C04, + }; + + if (!(gSaveContext.save.weekEventReg[88] & 2)) { + if (gSaveContext.save.weekEventReg[D_80AFB8D4[arg0] >> 8] & + (D_80AFB8D4[arg0] & (1 | 2 | 4 | 0x38 | 0x40 | 0x80))) { + switch (gSaveContext.save.day) { + case 2: + gSaveContext.save.weekEventReg[28] |= 8; + break; + + case 3: + gSaveContext.save.weekEventReg[28] |= 0x10; + break; + } + gSaveContext.save.weekEventReg[51] |= 2; + gSaveContext.save.weekEventReg[90] |= 8; + } + } + + gSaveContext.save.weekEventReg[D_80AFB8E0[arg0] >> 8] = + ((void)0, gSaveContext.save.weekEventReg[D_80AFB8E0[arg0] >> 8]) | (u8)D_80AFB8E0[arg0]; +} + +void func_80AF8C68(EnPm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp28 = Message_GetState(&globalCtx->msgCtx); + u16 temp_a0 = globalCtx->msgCtx.currentTextId; + + if ((player->targetActor == &this->actor) && ((temp_a0 < 255) || (temp_a0 > 512)) && (sp28 == 3) && + (this->unk_388 == 3)) { + if ((globalCtx->state.frames % 3) == 0) { + if (this->unk_360 == 120.0f) { + this->unk_360 = 0.0f; + } else { + this->unk_360 = 120.0f; + } + } + } else { + this->unk_360 = 0.0f; + } + Math_SmoothStepToF(&this->unk_364, this->unk_360, 0.8f, 40.0f, 10.0f); + Matrix_Translate(this->unk_364, 0.0f, 0.0f, MTXMODE_APPLY); + this->unk_388 = sp28; +} + +s32 func_80AF8D84(EnPm* this, GlobalContext* globalCtx) { + switch (this->unk_384) { + case 10: + func_80AF7E98(this, 9); + break; + + case 7: + func_80AF7E98(this, 0); + break; + } + return true; +} + +s32 func_80AF8DD4(EnPm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 temp = globalCtx->msgCtx.currentTextId; + s32 pad; + + if (player->stateFlags1 & (0x400 | 0x40)) { + this->unk_356 |= 0x400; + if (this->unk_358 != temp) { + if ((this->unk_384 == 0) || (this->unk_384 == 1)) { + func_80AF7E98(this, 7); + } + if ((temp == 0x277C) || (temp == 0x277D)) { + func_80AF7E98(this, 10); + } + } + this->unk_358 = temp; + } else { + if (this->unk_356 & 0x400) { + this->unk_358 = 0; + this->unk_356 &= ~0x400; + func_80AF8D84(this, globalCtx); + } + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + return 0; +} + +s32 func_80AF8ED4(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2, u8 actorCat, s16 actorId) { + u8 sp4F = this->actor.params & 0xFF; + Vec3s* sp48; + Vec3f sp3C; + Vec3f sp30; + Actor* sp2C; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + sp2C = func_80AF7CB0(this, globalCtx, actorCat, actorId); + if (D_80AFB430[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80AFB430[arg2->result]); + } + + if ((sp2C != NULL) && (sp2C->update != NULL)) { + if (this->unk_234 != NULL) { + sp48 = 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_80AF9008(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp56 = SCHEDULE_TIME_NOW; + u8 sp55 = this->actor.params & 0xFF; + EnDoor* door; + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s16 temp; + s32 ret = false; + + this->unk_234 = NULL; + door = func_80AF7D60(globalCtx, arg2->result); + if (D_80AFB430[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp55, D_80AFB430[arg2->result]); + } + + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if (this->unk_234 != 0) { + sp4C = Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp40, &sp4C[0]); + Math_Vec3s_ToVec3f(&sp34, &sp4C[1]); + Math_Vec3f_Copy(&this->unk_26C, &sp40); + 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 - door->dyna.actor.shape.rot.y; + if (ABS_ALT(temp) <= 0x4000) { + this->unk_260 = -0x4B; + } else { + this->unk_260 = 0x4B; + } + + this->unk_36C = arg2->time1 - arg2->time0; + this->unk_36E = sp56 - arg2->time0; + this->actor.flags &= ~ACTOR_FLAG_1; + if (gSaveContext.save.weekEventReg[90] & 8) { + this->unk_356 |= 0x800; + } + this->unk_356 |= 0x9000; + this->unk_356 |= 0x200; + func_80AF7E98(this, 0); + this->actor.gravity = 0.0f; + ret = true; + } + } + return ret; +} + +s32 func_80AF91E8(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp2E = SCHEDULE_TIME_NOW; + u16 phi_v1; + u8 sp2B = this->actor.params & 0xFF; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + + if (D_80AFB430[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp2B, D_80AFB430[arg2->result]); + } + + if ((this->unk_234 != NULL) && (this->unk_234->count < 3)) { + this->unk_234 = NULL; + } + + if (this->unk_234 != 0) { + if ((this->unk_258 < 38) && (this->unk_258 != 0) && (this->unk_374 >= 0)) { + phi_v1 = sp2E; + } else { + phi_v1 = arg2->time0; + } + + if (arg2->time1 < phi_v1) { + this->unk_248 = (phi_v1 - arg2->time1) + 0xFFFF; + } else { + this->unk_248 = arg2->time1 - 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_356 &= ~8; + this->unk_356 &= ~0x10; + if (this->unk_258 == 27) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROOM_CARTAIN); + Flags_UnsetSwitch(globalCtx, 0); + } + + switch (arg2->result) { + case 83: + case 84: + case 85: + case 86: + case 87: + case 88: + case 89: + case 90: + this->unk_356 |= 0x9000; + this->unk_356 |= 0x200; + + case 82: + func_80AF7E98(this, 0); + break; + + case 91: + this->unk_356 |= 0x9000; + func_80AF7E98(this, 12); + break; + + default: + SubS_UpdateFlags(&this->unk_356, 3, 7); + func_80AF7E98(this, 0); + if (gSaveContext.save.weekEventReg[90] & 8) { + this->unk_356 |= 0x800; + } + this->unk_356 |= 0x9000; + this->unk_356 |= 0x200; + break; + } + + this->actor.gravity = -1.0f; + ret = true; + } + + return ret; +} + +s32 func_80AF94AC(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u8 sp4F = this->actor.params & 0xFF; + Vec3f sp40; + Vec3f sp34; + Vec3s* sp30; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + if (D_80AFB430[arg2->result] >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp4F, D_80AFB430[arg2->result]); + } + + if ((this->unk_234 != 0) && (this->unk_234->count >= 2)) { + sp30 = Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp40, &sp30[0]); + Math_Vec3s_ToVec3f(&sp34, &sp30[1]); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp40, &sp34); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + Math_Vec3f_Copy(&this->actor.prevPos, &sp40); + if (arg2->result == 24) { + Flags_UnsetSwitch(globalCtx, 0); + Flags_UnsetSwitch(globalCtx, 1); + this->unk_394 = EXCH_ITEM_NONE; + this->unk_368 = 60.0f; + func_80AF7E98(this, 9); + } + ret = true; + } + return ret; +} + +s32 func_80AF95E8(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u8 sp4F = this->actor.params & 0xFF; + Vec3f sp40; + Vec3f sp34; + Vec3s* sp30; + s32 pad; + s32 ret = false; + s32 phi_a3 = -1; + + switch (arg2->result) { + case 3: + case 4: + case 5: + case 6: + case 7: + phi_a3 = arg2->result - 3; + break; + + case 19: + phi_a3 = 4; + break; + } + + if ((phi_a3 >= 0) && !func_80AF7DC4(this, globalCtx, phi_a3)) { + return ret; + } + + this->unk_234 = NULL; + phi_a3 = D_80AFB430[arg2->result]; + if (phi_a3 >= 0) { + this->unk_234 = SubS_GetAdditionalPath(globalCtx, sp4F, phi_a3); + } + + if ((this->unk_234 != 0) && (this->unk_234->count >= 2)) { + sp30 = Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp40, &sp30[this->unk_234->count - 1]); + Math_Vec3s_ToVec3f(&sp34, &sp30[this->unk_234->count - 2]); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp34, &sp40); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + Math_Vec3f_Copy(&this->actor.prevPos, &sp40); + + switch (arg2->result) { + case 27: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ROOM_CARTAIN); + Flags_SetSwitch(globalCtx, 0); + this->unk_36C = 20; + SubS_UpdateFlags(&this->unk_356, 3, 7); + func_80AF7E98(this, 3); + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + case 19: + this->unk_356 |= 0x9000; + func_80AF7E98(this, 11); + break; + + case 18: + this->unk_356 |= 0x9000; + this->unk_356 |= 0x800; + func_80AF7E98(this, 5); + break; + + case 23: + if (gSaveContext.save.weekEventReg[90] & 8) { + this->unk_356 |= 0x800; + } + gSaveContext.save.weekEventReg[60] |= 4; + + default: + if (arg2->result == 0x1D) { + this->actor.world.rot.y = BINANG_ROT180(this->actor.world.rot.y); + } + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->unk_356 |= 0x9000; + func_80AF7E98(this, 3); + break; + } + ret = true; + } + return ret; +} + +s32 func_80AF98A0(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + if (Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_MM3, 116.0f, 26.0f, -219.0f, 0, + -0x3F46, 0, 0) != NULL) { + Actor_MarkForDeath(&this->actor); + ret = true; + } + return ret; +} + +s32 func_80AF992C(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + static Vec3f D_80AFB8EC = { 116.0f, 26.0f, -219.0f }; + static Vec3s D_80AFB8F8 = { 0x0000, 0xC0BA, 0x0000 }; + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80AFB8EC); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80AFB8F8); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->actor.targetMode = 6; + this->actor.gravity = -1.0f; + this->unk_368 = 80.0f; + if (arg2->result == 14) { + this->unk_356 &= ~0x200; + func_80AF7E98(this, 13); + } else { + this->unk_356 &= ~0x200; + func_80AF7E98(this, 8); + } + return true; +} + +s32 func_80AF9A0C(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + if (func_80AF8ED4(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_AN)) { + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->unk_356 |= 0x20; + this->unk_356 |= 0x9000; + if (this->unk_258 != 0) { + this->unk_356 |= 0x800; + func_80AF7E98(this, 5); + } else { + func_80AF7E98(this, 3); + } + ret = true; + } + return ret; +} + +s32 func_80AF9AB0(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + if (func_80AF8ED4(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_TEST3)) { + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->unk_356 |= 0x20; + this->unk_356 |= 0x9000; + if (this->unk_258 != 0) { + this->unk_356 |= 0x800; + func_80AF7E98(this, 5); + } else { + func_80AF7E98(this, 3); + } + ret = true; + } + return ret; +} + +s32 func_80AF9B54(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + + if (func_80AF8ED4(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_AL)) { + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->unk_356 |= 0x9000; + this->unk_356 |= 0x20; + if (this->unk_258 != 0) { + this->unk_356 |= 0x800; + func_80AF7E98(this, 5); + } else { + func_80AF7E98(this, 3); + } + ret = true; + } + return ret; +} + +s32 func_80AF9BF8(EnPm* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret; + + this->actor.flags |= ACTOR_FLAG_1; + this->actor.targetMode = 0; + this->unk_394 = EXCH_ITEM_NONE; + this->unk_356 = 0; + this->unk_368 = 40.0f; + + switch (arg2->result) { + case 16: + ret = func_80AF9A0C(this, globalCtx, arg2); + break; + + case 17: + ret = func_80AF9AB0(this, globalCtx, arg2); + break; + + case 28: + ret = func_80AF9B54(this, globalCtx, arg2); + break; + + case 24: + ret = func_80AF94AC(this, globalCtx, arg2); + break; + + case 29: + ret = func_80AF95E8(this, globalCtx, arg2); + break; + + case 1: + case 2: + case 10: + case 11: + case 12: + case 13: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + ret = func_80AF9008(this, globalCtx, arg2); + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + case 18: + case 19: + case 23: + case 25: + case 27: + ret = func_80AF95E8(this, globalCtx, arg2); + break; + + case 8: + ret = func_80AF98A0(this, globalCtx, arg2); + break; + + case 9: + case 14: + case 20: + case 21: + case 22: + ret = func_80AF992C(this, globalCtx, arg2); + break; + + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 84: + case 85: + case 86: + case 87: + case 88: + case 89: + case 90: + case 91: + ret = func_80AF91E8(this, globalCtx, arg2); + break; + + default: + ret = false; + break; + } + return ret; +} + +s32 func_80AF9D04(EnPm* this, GlobalContext* globalCtx) { + EnDoor* door = (EnDoor*)func_80AF7D60(globalCtx, this->unk_258); + Vec3f sp38; + Vec3f* sp28; + f32 temp; + + if (!SubS_InCsMode(globalCtx) && (this->unk_374 != 0)) { + if ((door != NULL) && (door->dyna.actor.update != NULL)) { + if (((f32)this->unk_36E / this->unk_36C) <= 0.9f) { + door->unk_1A7 = this->unk_260; + } else { + door->unk_1A7 = 0; + } + } + this->unk_36E = CLAMP(this->unk_36E, 0, this->unk_36C); + temp = Math_Vec3f_DistXZ(&this->unk_26C, &this->unk_278) / this->unk_36C; + sp38.x = 0.0f; + sp38.y = 0.0f; + sp38.z = this->unk_36E * temp; + Lib_Vec3f_TranslateAndRotateY(&this->unk_26C, this->actor.world.rot.y, &sp38, &this->actor.world.pos); + this->unk_36E += this->unk_374; + if (Animation_OnFrame(&this->skelAnime, 3.0f) || Animation_OnFrame(&this->skelAnime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_POSTMAN_WALK); + } + } + return false; +} + +s32 func_80AF9E7C(EnPm* this, GlobalContext* globalCtx) { + f32 sp7C[265]; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + s32 sp54; + s32 sp50; + + sp50 = 0; + sp54 = 0; + + func_8013AF00(sp7C, 3, this->unk_234->count + 3); + if (!(this->unk_356 & 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_374); + func_8013B878(globalCtx, this->unk_234, this->unk_250, &sp58); + this->actor.world.pos.y = sp58.y; + this->unk_356 |= 8; + } else { + sp58 = this->unk_238; + } + + this->actor.world.pos.x = sp58.x; + this->actor.world.pos.z = sp58.z; + + if (SubS_InCsMode(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_374)) { + this->unk_356 |= 0x10; + } else { + sp70 = this->actor.world.pos; + sp64 = this->unk_238; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); + } + + if (SubS_InCsMode(globalCtx)) { + this->unk_254 = sp54; + this->unk_250 = sp50; + this->unk_238 = sp58; + } else if ((this->unk_258 != 91) && + (Animation_OnFrame(&this->skelAnime, 3.0f) || Animation_OnFrame(&this->skelAnime, 8.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_POSTMAN_WALK); + } + + if ((this->unk_356 & 0x10) && (this->unk_258 == 90)) { + u8 val = gSaveContext.save.weekEventReg[89] | 0x40; + + gSaveContext.save.weekEventReg[89] = val; + if (val == 0) { + gSaveContext.save.weekEventReg[89] |= 0x40; + } + } + + return false; +} + +s32 func_80AFA170(EnPm* this, GlobalContext* globalCtx) { + Vec3f sp34; + Vec3f sp28; + + switch (this->unk_258) { + case 28: + if (gSaveContext.save.time >= CLOCK_TIME(1, 39)) { + gSaveContext.save.weekEventReg[89] |= 8; + } + + case 16: + case 17: + case 18: + if ((this->unk_384 == 5) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80AF7E98(this, 6); + this->unk_36C = 40; + } else if ((this->unk_384 == 6) && (DECR(this->unk_36C) == 0)) { + this->unk_356 &= ~0x800; + func_80AF7E98(this, 4); + } + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + case 19: + if ((this->unk_384 == 11) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80AF7E98(this, 4); + } + + if ((this->unk_384 == 11) && Animation_OnFrame(&this->skelAnime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_POSTMACHINE_HIT_OPEN); + } + + if (this->unk_258 == 19) { + func_80AF8BA8(4); + } else { + func_80AF8BA8(this->unk_258 - 3); + } + break; + } + + if ((this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + Math_Vec3f_Copy(&sp34, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp28, &this->actor.world.pos); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp28, &sp34); + } + + return true; +} + +s32 func_80AFA334(EnPm* this, GlobalContext* globalCtx) { + s16 temp_v0; + + switch (this->unk_258) { + case 14: + case 24: + temp_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0) < 0x4000) { + SubS_UpdateFlags(&this->unk_356, 3, 7); + } else { + SubS_UpdateFlags(&this->unk_356, 0, 7); + } + break; + + case 27: + if (DECR(this->unk_36C) == 0) { + Flags_SetSwitch(globalCtx, 1); + } + break; + + case 9: + case 20: + case 21: + case 22: + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_VO_NP_SLEEP_OUT); + } + break; + + case 29: + break; + } + + return false; +} + +void func_80AFA438(EnPm* this, GlobalContext* globalCtx) { + switch (this->unk_258) { + case 3: + case 4: + case 5: + case 6: + case 7: + case 16: + case 17: + case 18: + case 28: + func_80AFA170(this, globalCtx); + break; + + case 1: + case 2: + case 10: + case 11: + case 12: + case 13: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + func_80AF9D04(this, globalCtx); + break; + + case 9: + case 14: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 27: + case 29: + func_80AFA334(this, globalCtx); + break; + + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: + case 50: + case 51: + case 52: + case 53: + case 54: + case 55: + case 56: + case 57: + case 58: + case 59: + case 60: + case 61: + case 62: + case 63: + case 64: + case 65: + case 66: + case 67: + case 68: + case 69: + case 70: + case 71: + case 72: + case 73: + case 74: + case 75: + case 76: + case 77: + case 78: + case 79: + case 80: + case 81: + case 82: + case 83: + case 84: + case 85: + case 86: + case 87: + case 88: + case 89: + case 90: + case 91: + func_80AF9E7C(this, globalCtx); + break; + } + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80AFA4D0(EnPm* this, GlobalContext* globalCtx) { + static u8* D_80AFB900[] = { + D_80AFAD80, D_80AFB30C, D_80AFB3C0, D_80AFB3FC, D_80AFB41C, + }; + u16 time = gSaveContext.save.time; + u16 sp3C = 0; + ScheduleResult sp2C; + + this->unk_374 = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (this->unk_38C != 0) { + time = gSaveContext.save.time - D_801F4E78; + sp3C = gSaveContext.save.time; + gSaveContext.save.time = time; + } + + if (!Schedule_RunScript(globalCtx, D_80AFB900[this->unk_38C], &sp2C) || + ((this->unk_258 != sp2C.result) && !func_80AF9BF8(this, globalCtx, &sp2C))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp2C.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + + this->unk_258 = sp2C.result; + this->unk_268 = func_80AF8040(this, globalCtx); + func_80AFA438(this, globalCtx); + if (this->unk_38C != 0) { + gSaveContext.save.time = sp3C; + } +} + +void func_80AFA5FC(EnPm* this, GlobalContext* globalCtx) { + s16 yaw; + Vec3f sp38; + Vec3f sp2C; + + if (func_8010BF58(&this->actor, globalCtx, this->unk_25C, this->unk_37C, &this->unk_264)) { + SubS_UpdateFlags(&this->unk_356, 3, 7); + this->unk_356 &= ~0x20; + this->unk_356 |= 0x200; + this->actor.child = NULL; + this->unk_376 = 20; + this->unk_264 = 0; + this->actionFunc = func_80AFA4D0; + return; + } + + if ((this->unk_258 != 9) && (this->unk_258 != 14) && (this->unk_258 != 16) && (this->unk_258 != 17) && + (this->unk_258 != 20) && (this->unk_258 != 21) && (this->unk_258 != 22) && (this->unk_258 != 24) && + (this->unk_258 != 25)) { + if ((this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + Math_Vec3f_Copy(&sp38, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + yaw = Math_Vec3f_Yaw(&sp2C, &sp38); + Math_ApproachS(&this->actor.shape.rot.y, yaw, 4, 0x2AA8); + } + } +} + +void func_80AFA724(EnPm* this, GlobalContext* globalCtx) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + if (Animation_OnFrame(&this->skelAnime, 3.0f) || Animation_OnFrame(&this->skelAnime, 8.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_POSTMAN_WALK); + } +} + +void EnPm_Init(Actor* thisx, GlobalContext* globalCtx) { + EnPm* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 14.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_mm_Skel_0096E8, NULL, this->jointTable, this->morphTable, + 16); + this->unk_384 = -1; + func_80AF7E98(this, 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->unk_38C = func_80AF7B40(); + this->unk_258 = 0; + this->unk_356 = 0; + this->actionFunc = func_80AFA4D0; + this->actionFunc(this, globalCtx); +} + +void EnPm_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnPm* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroySphere(globalCtx, &this->colliderSphere); +} + +void EnPm_Update(Actor* thisx, GlobalContext* globalCtx) { + EnPm* this = THIS; + + if (!func_80AF86F0(this, globalCtx) && func_80AF87C4(this, globalCtx)) { + func_80AFA724(this, globalCtx); + func_80AF7E6C(this); + func_80AF8AC8(this); + } else { + this->actionFunc(this, globalCtx); + func_80AF7BAC(this); + if (this->unk_258 != 0) { + func_80AF8DD4(this, globalCtx); + func_80AF7E6C(this); + func_80AF8AC8(this); + func_8013C964(&this->actor, globalCtx, this->unk_368, 30.0f, this->unk_394, this->unk_356 & 7); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + func_80AF7F68(this, globalCtx); + } + } +} + +s32 EnPm_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnPm* this = THIS; + + if (limbIndex == 15) { + func_80AF8C68(this, globalCtx); + } + return false; +} + +void EnPm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnPm* this = THIS; + s32 pad; + Vec3f sp2C; + + switch (limbIndex) { + case 15: + if (ActorCutscene_GetCurrentIndex() == -1) { + Matrix_MultVec3f(&gZeroVec3f, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } + if ((this->unk_356 & 0x8000) && !(gSaveContext.save.weekEventReg[90] & 4)) { + func_80AF8890(this, gfx, 1); + } + break; + + case 11: + if (this->unk_356 & 0x800) { + func_80AF8890(this, gfx, 0); + } + break; + + case 8: + if ((this->unk_258 == 9) || (this->unk_258 == 20) || (this->unk_258 == 21) || (this->unk_258 == 22)) { + Matrix_MultVec3f(&gZeroVec3f, &sp2C); + Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); + } else if (this->unk_258 == 24) { + Matrix_MultVec3f(&gZeroVec3f, &sp2C); + Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); + } + func_80AF8890(this, gfx, 2); + break; + } +} + +void EnPm_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx, Gfx** gfx) { + EnPm* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->unk_356 & 0x200)) { + if (this->unk_356 & 0x80) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + overrideRot = false; + stepRot = false; + } + + if (limbIndex == 15) { + SubS_UpdateLimb(this->unk_370 + 0x4000, this->unk_372 + this->actor.shape.rot.y + 0x4000, &this->unk_284, + &this->unk_290, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_284.x, this->unk_284.y, this->unk_284.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_290.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_290.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_290.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnPm_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80AFB914[] = { + object_mm_Tex_002950, + object_mm_Tex_002750, + }; + EnPm* this = THIS; + s32 pad; + + if (this->unk_258 != 0) { + func_8012C28C(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AFB914[0])); + + POLY_OPA_DISP = SubS_DrawTransformFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnPm_OverrideLimbDraw, EnPm_PostLimbDraw, + EnPm_TransformLimbDraw, &this->actor, POLY_OPA_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} 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 6e3024bf1..6d545373b 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.h +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.h @@ -6,12 +6,56 @@ struct EnPm; typedef void (*EnPmActionFunc)(struct EnPm*, GlobalContext*); +typedef s32 (*EnPmFunc)(struct EnPm*, GlobalContext*); +typedef s32 (*EnPmFunc2)(struct EnPm*, GlobalContext*); typedef struct EnPm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnPmActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x214]; + /* 0x018C */ EnPmFunc2 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; + /* 0x025C */ UNK_TYPE* unk_25C; + /* 0x0260 */ s8 unk_260; + /* 0x0264 */ s32 unk_264; + /* 0x0268 */ Actor* unk_268; + /* 0x026C */ Vec3f unk_26C; + /* 0x0278 */ Vec3f unk_278; + /* 0x0284 */ Vec3f unk_284; + /* 0x0290 */ Vec3s unk_290; + /* 0x0296 */ Vec3s jointTable[16]; + /* 0x02F6 */ Vec3s morphTable[16]; + /* 0x0356 */ u16 unk_356; + /* 0x0358 */ u16 unk_358; + /* 0x035C */ f32 unk_35C; + /* 0x0360 */ f32 unk_360; + /* 0x0364 */ f32 unk_364; + /* 0x0368 */ f32 unk_368; + /* 0x036C */ s16 unk_36C; + /* 0x036E */ s16 unk_36E; + /* 0x0370 */ s16 unk_370; + /* 0x0372 */ s16 unk_372; + /* 0x0374 */ s16 unk_374; + /* 0x0376 */ s16 unk_376; + /* 0x0378 */ s16 unk_378; + /* 0x037C */ EnPmFunc unk_37C; + /* 0x0380 */ s32 unk_380; + /* 0x0384 */ s32 unk_384; + /* 0x0388 */ s32 unk_388; + /* 0x038C */ s32 unk_38C; + /* 0x0390 */ UNK_TYPE1 unk390[0x4]; + /* 0x0394 */ s32 unk_394; + /* 0x0398 */ s32 unk_398; + /* 0x039C */ UNK_TYPE1 unk39C[0x4]; } EnPm; // size = 0x3A0 extern const ActorInit En_Pm_InitVars; diff --git a/src/overlays/actors/ovl_En_Po_Composer/z_en_po_composer.c b/src/overlays/actors/ovl_En_Po_Composer/z_en_po_composer.c index 9c2741808..744644e58 100644 --- a/src/overlays/actors/ovl_En_Po_Composer/z_en_po_composer.c +++ b/src/overlays/actors/ovl_En_Po_Composer/z_en_po_composer.c @@ -1,6 +1,12 @@ +/* + * File: z_en_po_composer.c + * Overlay: ovl_En_Po_Composer + * Description: Poe Composers + */ + #include "z_en_po_composer.h" -#define FLAGS 0x02100019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((EnPoComposer*)thisx) diff --git a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c index c578e3d37..42fd2b418 100644 --- a/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c +++ b/src/overlays/actors/ovl_En_Po_Fusen/z_en_po_fusen.c @@ -6,8 +6,9 @@ #include "z_en_po_fusen.h" #include "overlays/actors/ovl_En_Ma4/z_en_ma4.h" +#include "objects/object_po_fusen/object_po_fusen.h" -#define FLAGS 0x80100030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_100000 | ACTOR_FLAG_80000000) #define THIS ((EnPoFusen*)thisx) @@ -26,10 +27,7 @@ void EnPoFusen_Pop(EnPoFusen* this, GlobalContext* globalCtx); void EnPoFusen_Idle(EnPoFusen* this, GlobalContext* globalCtx); void EnPoFusen_IdleFuse(EnPoFusen* this, GlobalContext* globalCtx); s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg); - -extern AnimationHeader D_06000040; -extern FlexSkeletonHeader D_060024F0; + Actor* thisx); const ActorInit En_Po_Fusen_InitVars = { ACTOR_EN_PO_FUSEN, @@ -111,8 +109,9 @@ void EnPoFusen_Init(Actor* thisx, GlobalContext* globalCtx) { if (0) {} this->collider.dim.worldSphere.radius = 40; - SkelAnime_InitFlex(globalCtx, &this->anime, &D_060024F0, &D_06000040, this->jointTable, this->morphTable, 10); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 25.0f); + SkelAnime_InitFlex(globalCtx, &this->anime, &object_po_fusen_Skel_0024F0, &object_po_fusen_Anim_000040, + this->jointTable, this->morphTable, 10); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 25.0f); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 0x4); if (EnPoFusen_CheckParent(this, globalCtx) == 0) { @@ -148,9 +147,9 @@ void EnPoFusen_Destroy(Actor* thisx, GlobalContext* globalCtx) { } u16 EnPoFusen_CheckParent(EnPoFusen* this, GlobalContext* globalCtx) { - struct Actor* actorPtr; + Actor* actorPtr; - actorPtr = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + actorPtr = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; if (GET_IS_FUSE_TYPE_PARAM(this)) { return 1; } @@ -243,7 +242,7 @@ void EnPoFusen_IncrementRomaniPop(EnPoFusen* this) { void EnPoFusen_Pop(EnPoFusen* this, GlobalContext* globalCtx) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, this->actor.world.pos.y + 20.0f, this->actor.world.pos.z, 255, 255, 200, CLEAR_TAG_POP); - Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_EXPLOSION); Actor_MarkForDeath(&this->actor); } @@ -271,8 +270,8 @@ void EnPoFusen_Update(Actor* thisx, GlobalContext* globalCtx) { } s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* arg) { - EnPoFusen* this = (EnPoFusen*)arg; + Actor* thisx) { + EnPoFusen* this = THIS; f32 zScale; f32 yScale; f32 xScale; @@ -289,10 +288,10 @@ s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL yScale = yScale * yScale; xRot = ((Math_SinS(this->randXZRotChange) * 2730.0f)); zRot = ((Math_CosS(this->randXZRotChange) * 2730.0f)); - Matrix_InsertRotation(xRot, 0, zRot, MTXMODE_APPLY); + Matrix_RotateZYX(xRot, 0, zRot, MTXMODE_APPLY); Matrix_Scale(xScale, yScale, zScale, MTXMODE_APPLY); - Matrix_InsertZRotation_s(-zRot, MTXMODE_APPLY); - Matrix_InsertXRotation_s(-xRot, MTXMODE_APPLY); + Matrix_RotateZS(-zRot, MTXMODE_APPLY); + Matrix_RotateXS(-xRot, MTXMODE_APPLY); } else if (limbIndex == 3) { rot->y += this->limb3Rot; } else if (limbIndex == 6) { @@ -307,18 +306,19 @@ s32 EnPoFusen_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL rot->y += (s16)(this->limb9Rot * Math_SinS(this->randBaseRotChange)); rot->z += (s16)(this->limb9Rot * Math_CosS(this->randBaseRotChange)); } - return 0; + return false; } -void EnPoFusen_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { +void EnPoFusen_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void EnPoFusen_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnPoFusen_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void EnPoFusen_Draw(Actor* thisx, GlobalContext* globalCtx) { EnPoFusen* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->anime.skeleton, this->anime.jointTable, this->anime.dListCount, - EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->anime.skeleton, this->anime.jointTable, this->anime.dListCount, + EnPoFusen_OverrideLimbDraw, EnPoFusen_PostLimbDraw, EnPoFusen_TransformLimbDraw, + &this->actor); } 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 50aba0d7b..bb128935d 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 @@ -1,6 +1,14 @@ -#include "z_en_po_sisters.h" +/* + * File: z_en_po_sisters.c + * Overlay: ovl_En_Po_Sisters + * Description: Poe Sisters + */ -#define FLAGS 0x00005015 +#include "z_en_po_sisters.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_po_sisters/object_po_sisters.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_1000 | ACTOR_FLAG_4000) #define THIS ((EnPoSisters*)thisx) @@ -9,24 +17,51 @@ void EnPoSisters_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPoSisters_Update(Actor* thisx, GlobalContext* globalCtx); void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B1AA88(EnPoSisters* this); void func_80B1AAE8(EnPoSisters* this, GlobalContext* globalCtx); void func_80B1ABB8(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1AC40(EnPoSisters* this); void func_80B1ACB8(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1AE28(EnPoSisters* this); void func_80B1AE3C(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1AF8C(EnPoSisters* this); void func_80B1B020(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1B0E0(EnPoSisters* this); void func_80B1B168(EnPoSisters* this, GlobalContext* globalCtx); void func_80B1B2F0(EnPoSisters* this, GlobalContext* globalCtx); void func_80B1B444(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1B5B4(EnPoSisters* this); void func_80B1B628(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1B70C(EnPoSisters* this); void func_80B1B7BC(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1B860(EnPoSisters* this, GlobalContext* globalCtx); void func_80B1B940(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1BA3C(EnPoSisters* this); void func_80B1BA90(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1BC4C(EnPoSisters* this, GlobalContext* globalCtx); void func_80B1BCA0(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1BCF0(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1BE4C(EnPoSisters* this, s32 arg1); void func_80B1BF2C(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1C030(EnPoSisters* this); void func_80B1C0A4(EnPoSisters* this, GlobalContext* globalCtx); +void func_80B1C2E8(EnPoSisters* this); void func_80B1C340(EnPoSisters* this, GlobalContext* globalCtx); -#if 0 +static Color_RGBA8 D_80B1DA30[] = { + { 255, 170, 255, 255 }, + { 255, 200, 0, 255 }, + { 0, 170, 255, 255 }, + { 170, 255, 0, 255 }, +}; + +static Color_RGBA8 D_80B1DA40[] = { + { 100, 0, 255, 255 }, + { 255, 0, 0, 255 }, + { 0, 0, 255, 255 }, + { 0, 150, 0, 255 }, +}; + const ActorInit En_Po_Sisters_InitVars = { ACTOR_EN_PO_SISTERS, ACTORCAT_ENEMY, @@ -39,18 +74,29 @@ const ActorInit En_Po_Sisters_InitVars = { (ActorFunc)EnPoSisters_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B1DA70 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CBFFFE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, 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_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CBFFFE, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 18, 60, 15, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80B1DA9C = { 6, 25, 60, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 6, 25, 60, 50 }; -// static DamageTable sDamageTable = { -static DamageTable D_80B1DAA4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xF), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -85,114 +131,1057 @@ static DamageTable D_80B1DAA4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B1DAC4[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 7, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 6000, ICHAIN_STOP), }; -#endif +void EnPoSisters_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnPoSisters* this = THIS; -extern ColliderCylinderInit D_80B1DA70; -extern CollisionCheckInfoInit D_80B1DA9C; -extern DamageTable D_80B1DAA4; -extern InitChainEntry D_80B1DAC4[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 50.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_po_sisters_Skel_0065C8, &object_po_sisters_Anim_0014CC, + this->jointTable, this->morphTable, 12); + this->unk_226 = 255; + this->unk_227 = 255; + this->unk_228 = 210; + this->unk_229 = 255; + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); + Lights_PointGlowSetInfo(&this->lightInfo, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, 0, + 0, 0, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->unk_18C = ENPOSISTERS_GET_300(thisx); + this->actor.hintId = this->unk_18C + 80; + this->unk_18D = ENPOSISTERS_GET_C00(thisx); + this->unk_18E = 32; + this->unk_18F = 20; + this->unk_190 = 1; + this->unk_191 = 0x20; + this->unk_2EC = 110.0f; + thisx->flags &= ~1; -extern UNK_TYPE D_06000114; -extern UNK_TYPE D_060008C0; -extern UNK_TYPE D_06000A54; -extern UNK_TYPE D_06000D40; -extern UNK_TYPE D_0600119C; -extern UNK_TYPE D_060014CC; -extern UNK_TYPE D_060027B0; -extern UNK_TYPE D_060046E0; + if (ENPOSISTERS_GET_1000(&this->actor)) { + func_80B1AA88(this); + } else if (this->unk_18C == 0) { + if (this->unk_18D == 0) { + this->actor.colChkInfo.health = 8; + this->collider.info.toucher.damage = 16; + this->collider.base.ocFlags1 = (OC1_TYPE_PLAYER | OC1_ON); + func_80B1BCF0(this, globalCtx); + func_80B1C2E8(this); + } else { + this->actor.flags &= ~(ACTOR_FLAG_200 | ACTOR_FLAG_4000); + this->collider.info.elemType = ELEMTYPE_UNK4; + this->collider.info.bumper.dmgFlags |= (0x40000 | 0x1); + this->collider.base.ocFlags1 = OC1_NONE; + func_80B1BE4C(this, false); + } + } else { + func_80B1C2E8(this); + } + this->actor.params &= 0xFF; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/EnPoSisters_Init.s") +void EnPoSisters_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnPoSisters* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/EnPoSisters_Destroy.s") + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1A648.s") +void func_80B1A648(EnPoSisters* this, s32 arg1, Vec3f* pos) { + s32 i; + Vec3f* ptr; + f32 temp_f20 = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1A768.s") + for (i = 0; i < this->unk_190; i++) { + ptr = &this->unk_22C[i]; + ptr->x = Math_SinS(this->actor.shape.rot.y + (this->unk_192 * 0x800) + (i * 0x2000)) * (SQ(temp_f20) * 0.1f) + + pos->x; + ptr->z = Math_CosS(this->actor.shape.rot.y + (this->unk_192 * 0x800) + (i * 0x2000)) * (SQ(temp_f20) * 0.1f) + + pos->z; + ptr->y = pos->y + temp_f20; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1A894.s") +void func_80B1A768(EnPoSisters* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1A9B0.s") + if ((this->unk_18D == 0) || (this->actionFunc != func_80B1B444)) { + if (((player->swordState == 0) || (player->swordAnimation >= 30)) && + ((player->actor.world.pos.y - player->actor.floorHeight) < 1.0f)) { + Math_StepToF(&this->unk_2EC, 110.0f, 3.0f); + } else { + Math_StepToF(&this->unk_2EC, 170.0f, 10.0f); + } + sp20 = this->unk_2EC; + } else if (this->unk_18D != 0) { // An else would be sufficient + sp20 = this->actor.parent->xzDistToPlayer; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AA88.s") + this->actor.world.pos.x = (Math_SinS(BINANG_ROT180(this->actor.shape.rot.y)) * sp20) + player->actor.world.pos.x; + this->actor.world.pos.z = (Math_CosS(BINANG_ROT180(this->actor.shape.rot.y)) * sp20) + player->actor.world.pos.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AAE8.s") +void func_80B1A894(EnPoSisters* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AB5C.s") + Math_ApproachF(&this->actor.world.pos.y, player->actor.world.pos.y + 5.0f, 0.5f, 3.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1ABB8.s") + if (this->unk_18E == 0) { + this->unk_18E = 32; + if (this->unk_18E) {} + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AC40.s") + if (this->unk_18E != 0) { + this->unk_18E--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1ACB8.s") + this->actor.world.pos.y += (2.0f + (0.5f * Rand_ZeroOne())) * Math_SinS(this->unk_18E * 0x800); + if ((this->unk_229 == 255) && (this->actionFunc != func_80B1B168) && (this->actionFunc != func_80B1B020)) { + if (this->actionFunc == func_80B1B628) { + func_800B9010(&this->actor, NA_SE_EN_PO_AWAY - SFX_FLAG); + } else { + func_800B9010(&this->actor, NA_SE_EN_PO_FLY - SFX_FLAG); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AE28.s") +void func_80B1A9B0(EnPoSisters* this, GlobalContext* globalCtx) { + if (this->actor.isTargeted && (this->unk_229 == 255)) { + if (this->unk_18F != 0) { + this->unk_18F--; + } + } else { + this->unk_18F = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AE3C.s") + if (this->unk_229 == 0) { + if (this->unk_194 != 0) { + this->unk_194--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1AF8C.s") + if ((this->actionFunc != func_80B1B020) && (this->actionFunc != func_80B1B168) && + (this->actionFunc != func_80B1B444)) { + if (this->unk_18F == 0) { + func_80B1B70C(this); + } else if ((this->unk_194 == 0) && (this->unk_229 == 0)) { + func_80B1B860(this, globalCtx); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B020.s") +void func_80B1AA88(EnPoSisters* this) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_0014CC, -3.0f); + this->actor.speedXZ = 0.0f; + this->unk_192 = Rand_S16Offset(100, 50); + this->actionFunc = func_80B1AAE8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B0E0.s") +void func_80B1AAE8(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (DECR(this->unk_192) == 0) { + this->unk_192 = Rand_S16Offset(100, 50); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B168.s") +void func_80B1AB5C(EnPoSisters* this) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_0014CC, -3.0f); + this->unk_192 = Rand_S16Offset(2, 3); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80B1ABB8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B280.s") +void func_80B1ABB8(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + if (this->unk_192 != 0) { + this->unk_192--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B2F0.s") + if ((this->unk_192 == 0) || (this->actor.xzDistToPlayer < 600.0f)) { + func_80B1AC40(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B3A8.s") +void func_80B1AC40(EnPoSisters* this) { + if (this->actionFunc != func_80B1AE3C) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000D40, -3.0f); + } + this->unk_192 = Rand_S16Offset(15, 3); + this->unk_191 |= (0x6 | 0x1); + this->actionFunc = func_80B1ACB8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B444.s") +void func_80B1ACB8(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_StepToF(&this->actor.speedXZ, 1.0f, 0.2f); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + if (this->unk_192 != 0) { + this->unk_192--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B5B4.s") + if ((this->actor.xzDistToPlayer < 600.0f) && (fabsf(this->actor.playerHeightRel + 5.0f) < 30.0f)) { + func_80B1AE28(this); + } else if ((this->unk_192 == 0) && Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f)) { + func_80B1AB5C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B628.s") + if (this->actor.bgCheckFlags & 8) { + Math_ScaledStepToS(&this->actor.world.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 0x71C); + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 600.0f) { + Math_ScaledStepToS(&this->actor.world.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 0x71C); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B70C.s") +void func_80B1AE28(EnPoSisters* this) { + this->actionFunc = func_80B1AE3C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B7BC.s") +void func_80B1AE3C(EnPoSisters* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp22; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B860.s") + SkelAnime_Update(&this->skelAnime); + sp22 = this->actor.yawTowardsPlayer - player->actor.shape.rot.y; + Math_StepToF(&this->actor.speedXZ, 2.0f, 0.2f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1B940.s") + if (sp22 > 0x3000) { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer + 0x3000, 0x71C); + } else if (sp22 < -0x3000) { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer - 0x3000, 0x71C); + } else { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x71C); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BA3C.s") + if ((this->actor.xzDistToPlayer < 320.0f) && (fabsf(this->actor.playerHeightRel + 5.0f) < 30.0f)) { + func_80B1AF8C(this); + } else if (this->actor.xzDistToPlayer > 720.0f) { + func_80B1AC40(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BA90.s") +void func_80B1AF8C(EnPoSisters* this) { + if (this->unk_229 != 0) { + this->collider.base.colType = COLTYPE_METAL; + this->collider.base.acFlags |= AC_HARD; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BC4C.s") + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000114, -5.0f); + this->actor.speedXZ = 0.0f; + this->unk_192 = Animation_GetLastFrame(&object_po_sisters_Anim_000114.common) * 3 + 3; + this->unk_191 &= ~2; + this->actionFunc = func_80B1B020; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BCA0.s") +void func_80B1B020(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->unk_192 != 0) { + this->unk_192--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BCF0.s") + this->actor.shape.rot.y += ((s32)((this->skelAnime.endFrame + 1.0f) * 3.0f) - this->unk_192) * 0x180; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BE4C.s") + if ((this->unk_192 == 18) || (this->unk_192 == 7)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_ROLL); + } else if (this->unk_192 == 0) { + func_80B1B0E0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1BF2C.s") +void func_80B1B0E0(EnPoSisters* this) { + this->actor.speedXZ = 5.0f; + if (this->unk_18C == 0) { + this->collider.base.colType = COLTYPE_METAL; + this->collider.base.acFlags |= AC_HARD; + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000114, -5.0f); + } + this->unk_192 = 5; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->unk_191 |= 8; + this->actionFunc = func_80B1B168; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C030.s") +void func_80B1B168(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + if (this->unk_192 != 0) { + this->unk_192--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C0A4.s") + this->actor.shape.rot.y += (s32)(1152.0f * this->skelAnime.endFrame); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C2E8.s") + if (this->unk_192 == 0) { + s16 rotY = this->actor.shape.rot.y - this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C340.s") + if (ABS_ALT(rotY) < 0x1000) { + if (this->unk_18C != 0) { + this->collider.base.colType = COLTYPE_HIT3; + this->collider.base.acFlags &= ~AC_HARD; + func_80B1AC40(this); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2); + func_80B1BE4C(this, globalCtx); + } + } + } + if (Animation_OnFrame(&this->skelAnime, 1.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_ROLL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C408.s") +void func_80B1B280(EnPoSisters* this) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000D40, -3.0f); + this->actor.world.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); + if (this->unk_18C != 0) { + this->collider.base.colType = COLTYPE_HIT3; + this->collider.base.acFlags &= ~AC_HARD; + } + this->actionFunc = func_80B1B2F0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/EnPoSisters_Update.s") +void func_80B1B2F0(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y -= (s16)(this->actor.speedXZ * 10.0f * 128.0f); + if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->unk_18C != 0) { + func_80B1AC40(this); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2); + func_80B1BE4C(this, globalCtx); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1C974.s") +void func_80B1B3A8(EnPoSisters* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_po_sisters_Anim_0008C0, -3.0f); + if (this->collider.base.ac != NULL) { + func_800BE504(&this->actor, &this->collider); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1CB44.s") + if (this->unk_18C != 0) { + this->actor.speedXZ = 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/func_80B1CD34.s") + this->unk_191 &= ~(0x8 | 0x2 | 0x1); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 16); + this->actionFunc = func_80B1B444; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Po_Sisters/EnPoSisters_Draw.s") +void func_80B1B444(EnPoSisters* this, GlobalContext* globalCtx) { + s32 temp_f18; + + if (SkelAnime_Update(&this->skelAnime) && !(this->actor.flags & ACTOR_FLAG_8000)) { + if (this->actor.colChkInfo.health != 0) { + if (this->unk_18C != 0) { + func_80B1B5B4(this); + } else if (this->unk_18D != 0) { + func_80B1BE4C(this, 0); + } else { + func_80B1BE4C(this, globalCtx); + } + } else { + func_80B1BA3C(this); + } + } + + if (this->unk_18D != 0) { + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.parent->shape.rot.y, + (this->unk_18D == 2) ? 0x800 : 0x400); + temp_f18 = ((this->skelAnime.endFrame - this->skelAnime.curFrame) * 255.0f) / this->skelAnime.endFrame; + this->unk_229 = CLAMP(temp_f18, 0, 255); + this->actor.world.pos.y = this->actor.parent->world.pos.y; + func_80B1A768(this, globalCtx); + } else if (this->unk_18C != 0) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + } +} + +void func_80B1B5B4(EnPoSisters* this) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000A54, -3.0f); + this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); + this->unk_192 = 5; + this->unk_191 |= (0x8 | 0x2 | 0x1); + this->actor.speedXZ = 5.0f; + this->actionFunc = func_80B1B628; +} + +void func_80B1B628(EnPoSisters* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_ScaledStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 0x71C); + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + if (this->unk_192 != 0) { + this->unk_192--; + } + } + + if (this->actor.bgCheckFlags & 8) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_191 |= 2; + func_80B1B70C(this); + } else if ((this->unk_192 == 0) && (this->actor.xzDistToPlayer > 480.0f)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80B1AC40(this); + } +} + +void func_80B1B70C(EnPoSisters* this) { + Animation_Change(&this->skelAnime, &object_po_sisters_Anim_00119C, 1.5f, 0.0f, + Animation_GetLastFrame(&object_po_sisters_Anim_00119C.common), 2, -3.0f); + this->unk_194 = 100; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_191 &= ~(0x4 | 0x1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DISAPPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2); + this->actionFunc = func_80B1B7BC; +} + +void func_80B1B7BC(EnPoSisters* this, GlobalContext* globalCtx) { + s32 temp_f18; + + if (SkelAnime_Update(&this->skelAnime)) { + this->unk_229 = 0; + this->collider.info.bumper.dmgFlags = (0x40000 | 0x1); + func_80B1AC40(this); + } else { + temp_f18 = ((this->skelAnime.endFrame - this->skelAnime.curFrame) * 255.0f) / this->skelAnime.endFrame; + this->unk_229 = CLAMP(temp_f18, 0, 255); + } +} + +void func_80B1B860(EnPoSisters* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &object_po_sisters_Anim_00119C, 1.5f, 0.0f, + Animation_GetLastFrame(&object_po_sisters_Anim_00119C.common), 2, -3.0f); + if (this->unk_18C == 0) { + this->unk_2EC = 110.0f; + func_80B1A768(this, globalCtx); + this->unk_229 = 0; + this->actor.draw = EnPoSisters_Draw; + } else { + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + this->unk_192 = 15; + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + this->unk_191 &= ~0x1; + this->actionFunc = func_80B1B940; +} + +void func_80B1B940(EnPoSisters* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + this->unk_229 = 255; + if (this->unk_18C != 0) { + this->unk_191 |= 1; + this->collider.info.bumper.dmgFlags = ~(0x8000000 | 0x200000 | 0x100000 | 0x40000 | 0x1); + if (this->unk_192 != 0) { + this->unk_192--; + } + + if (this->unk_192 == 0) { + this->unk_18F = 20; + func_80B1AC40(this); + } + } else { + func_80B1C030(this); + } + } else { + s32 temp_f18 = (this->skelAnime.curFrame * 255.0f) / this->skelAnime.endFrame; + + this->unk_229 = CLAMP(temp_f18, 0, 255); + if (this->unk_18C == 0) { + func_80B1A768(this, globalCtx); + } + } +} + +void func_80B1BA3C(EnPoSisters* this) { + this->unk_192 = 0; + this->actor.speedXZ = 0.0f; + this->actor.world.pos.y += 42.0f; + this->actor.shape.yOffset = -6000.0f; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_191 = 0; + this->actionFunc = func_80B1BA90; +} + +void func_80B1BA90(EnPoSisters* this, GlobalContext* globalCtx) { + s32 i; + s32 end = this->unk_190; + + this->unk_192++; + end++; + if (end > ARRAY_COUNT(this->unk_22C)) { + this->unk_190 = 8; + } else { + this->unk_190 = end; + } + + for (end = this->unk_190 - 1; end > 0; end--) { + this->unk_22C[end] = this->unk_22C[end - 1]; + } + + this->unk_22C[0].x = + (Math_SinS((this->actor.shape.rot.y + (this->unk_192 * 0x3000)) - 0x4000) * (3000.0f * this->actor.scale.x)) + + this->actor.world.pos.x; + this->unk_22C[0].z = + (Math_CosS((this->actor.shape.rot.y + (this->unk_192 * 0x3000)) - 0x4000) * (3000.0f * this->actor.scale.x)) + + this->actor.world.pos.z; + if (this->unk_192 < 8) { + this->unk_22C[0].y = this->unk_22C[1].y - 9.0f; + } else { + this->unk_22C[0].y = this->unk_22C[1].y + 2.0f; + if (this->unk_192 >= 16) { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.001f)) { + func_80B1BC4C(this, globalCtx); + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.x; + } + } + + if (this->unk_192 == 16) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); + } +} + +void func_80B1BC4C(EnPoSisters* this, GlobalContext* globalCtx) { + this->unk_192 = 0; + this->actor.world.pos.y = this->unk_22C[0].y; + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x80); + this->actionFunc = func_80B1BCA0; +} + +void func_80B1BCA0(EnPoSisters* this, GlobalContext* globalCtx) { + this->unk_192++; + if (this->unk_192 == 32) { + Actor_MarkForDeath(&this->actor); + } else { + func_80B1A648(this, this->unk_192, &this->actor.world.pos); + } +} + +void func_80B1BCF0(EnPoSisters* this, GlobalContext* globalCtx) { + Actor* sp4C = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0x400); + Actor* sp48 = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0x800); + Actor* sp44 = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0xC00); + + if ((sp4C == NULL) || (sp48 == NULL) || (sp44 == NULL)) { + if (sp4C != NULL) { + Actor_MarkForDeath(sp4C); + } + + if (sp48 != NULL) { + Actor_MarkForDeath(sp48); + } + + if (sp44 != NULL) { + Actor_MarkForDeath(sp44); + } + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B1BE4C(EnPoSisters* this, s32 arg1) { + Vec3f sp34; + + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_194 = 100; + this->unk_191 = 0x20; + this->collider.base.colType = COLTYPE_HIT3; + this->collider.base.acFlags &= ~AC_HARD; + if (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, &gZeroVec3f, &gZeroVec3f, 150, 0, 3); + } + Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); + this->actionFunc = func_80B1BF2C; +} + +void func_80B1BF2C(EnPoSisters* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnPoSisters* parent = (EnPoSisters*)this->actor.parent; + + if (this->unk_18D == 0) { + if (this->unk_194 != 0) { + this->unk_194--; + } + + if (this->unk_194 == 0) { + s32 rand = Rand_ZeroFloat(4.0f); + + this->actor.shape.rot.y = (rand * 0x4000) + this->actor.yawTowardsPlayer; + this->actor.world.pos.y = player->actor.world.pos.y + 5.0f; + func_80B1B860(this, globalCtx); + } + } else if (parent->actionFunc == func_80B1B940) { + this->actor.shape.rot.y = this->actor.parent->shape.rot.y + (this->unk_18D * 0x4000); + this->actor.world.pos.y = player->actor.world.pos.y + 5.0f; + func_80B1B860(this, globalCtx); + } else if (parent->actionFunc == func_80B1BA90) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B1C030(EnPoSisters* this) { + Animation_MorphToLoop(&this->skelAnime, &object_po_sisters_Anim_000D40, -3.0f); + this->unk_229 = 255; + this->unk_192 = 300; + this->unk_194 = 3; + this->unk_191 |= (0x8 | 0x1); + this->actor.flags |= ACTOR_FLAG_1; + this->actionFunc = func_80B1C0A4; +} + +void func_80B1C0A4(EnPoSisters* this, GlobalContext* globalCtx) { + EnPoSisters* parent; + + if (this->unk_192 != 0) { + this->unk_192--; + } + + if (this->unk_194 > 0) { + if (this->unk_192 >= 16) { + SkelAnime_Update(&this->skelAnime); + if (this->unk_18D == 0) { + if (ABS_ALT(16 - this->unk_18E) < 14) { + this->actor.shape.rot.y += + (s16)((0x580 - (this->unk_194 * 0x180)) * fabsf(Math_SinS(this->unk_18E * 0x800))); + } + + if ((this->unk_192 >= 284) || (this->unk_192 < 31)) { + this->unk_191 |= 0x40; + } else { + this->unk_191 &= ~0x40; + } + } else { + this->actor.shape.rot.y = this->actor.parent->shape.rot.y + (this->unk_18D * 0x4000); + } + } + } + + if (this->unk_18D == 0) { + if ((this->unk_192 >= 284) || ((this->unk_192 < 31) && (this->unk_192 >= 16))) { + this->unk_191 |= 0x40; + } else { + this->unk_191 &= ~0x40; + } + } + + if (this->unk_192 == 0) { + if (this->unk_18D == 0) { + func_80B1B0E0(this); + } else { + func_80B1BE4C(this, globalCtx); + } + } else if (this->unk_18D != 0) { + parent = (EnPoSisters*)this->actor.parent; + if (parent->actionFunc == func_80B1B444) { + func_80B1B3A8(this); + } + } else if (this->unk_194 == 0) { + this->unk_194 = -15; + } else if (this->unk_194 < 0) { + this->unk_194++; + if (this->unk_194 == 0) { + func_80B1B0E0(this); + } + } + func_80B1A768(this, globalCtx); +} + +void func_80B1C2E8(EnPoSisters* this) { + Animation_PlayOnce(&this->skelAnime, &object_po_sisters_Anim_00119C); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + this->unk_229 = 0; + this->unk_191 = 0x20; + this->actionFunc = func_80B1C340; +} + +void func_80B1C340(EnPoSisters* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + this->unk_229 = 255; + this->actor.flags |= ACTOR_FLAG_1; + this->unk_191 |= (0x10 | 0x8); + if (this->unk_18C == 0) { + func_80B1BE4C(this, globalCtx); + } else { + func_80B1AC40(this); + } + } else { + f32 temp = this->skelAnime.curFrame / this->skelAnime.endFrame; + s32 temp_f16 = 255.0f * temp; + + this->unk_229 = CLAMP(temp_f16, 0, 255); + } +} + +void func_80B1C408(EnPoSisters* this, GlobalContext* globalCtx) { + Vec3f sp3C; + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.info); + + if (this->unk_18D != 0) { + ((EnPoSisters*)this->actor.parent)->unk_194--; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH2); + func_80B1BE4C(this, globalCtx); + if (Rand_ZeroOne() < 0.2f) { + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y; + sp3C.z = this->actor.world.pos.z; + Item_DropCollectible(globalCtx, &sp3C, ITEM00_ARROWS_10); + } + } else if (this->collider.base.colType != 9) { + if (this->actor.colChkInfo.damageEffect == 0xF) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_191 |= 2; + func_80B1B860(this, globalCtx); + } else if ((this->unk_18C == 0) && (this->actor.colChkInfo.damageEffect == 0xE) && + (this->actionFunc == func_80B1C0A4)) { + if (this->unk_194 == 0) { + this->unk_194 = -45; + } + } else { + if (Actor_ApplyDamage(&this->actor)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DAMAGE); + } else { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_SISTER_DEAD); + } + + if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.5f; + 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); + } + func_80B1B3A8(this); + } + } + } +} + +void EnPoSisters_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnPoSisters* this = THIS; + f32 temp_f2; + Vec3f checkPos; + s32 bgId; + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + func_80B1B280(this); + } + + func_80B1C408(this, globalCtx); + if (this->unk_191 & 0x4) { + func_80B1A9B0(this, globalCtx); + } + + this->actionFunc(this, globalCtx); + + if (this->unk_191 & 0x8) { + func_80B1A894(this, globalCtx); + } + + Actor_MoveWithGravity(&this->actor); + + if (this->unk_191 & 0x10) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 0.0f, 5); + } else { + checkPos.x = this->actor.world.pos.x; + checkPos.y = this->actor.world.pos.y + 10.0f; + checkPos.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, &this->actor, &checkPos); + } + + this->actor.shape.shadowAlpha = this->unk_229; + Actor_SetFocus(&this->actor, 40.0f); + + if (this->drawDmgEffAlpha > 0.0f) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + if (this->unk_229 != 255) { + temp_f2 = this->unk_229 * (1.0f / 255); + if (temp_f2 < this->unk_229) { + this->drawDmgEffAlpha = temp_f2; + } + } + + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.25f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.5f); + } + + if (this->unk_191 & (0x10 | 0x8 | 0x4 | 0x2 | 0x1)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + if ((this->actionFunc == func_80B1B168) || (this->actionFunc == func_80B1B020)) { + this->unk_190++; + this->unk_190 = CLAMP_MAX(this->unk_190, ARRAY_COUNT(this->unk_22C)); + } else if (this->actionFunc != func_80B1BA90) { + this->unk_190 = CLAMP_MIN(this->unk_190 - 1, 1); + } + + if (this->actionFunc == func_80B1B168) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->unk_191 & 0x1) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actionFunc != func_80B1BF2C) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actionFunc == func_80B1B628) { + this->actor.shape.rot.y = BINANG_ROT180(this->actor.world.rot.y); + } else if (this->unk_191 & 0x2) { + this->actor.shape.rot.y = this->actor.world.rot.y; + } + } +} + +void func_80B1C974(EnPoSisters* this) { + if (this->skelAnime.animation == &object_po_sisters_Anim_000114) { + this->unk_226 = CLAMP_MAX(this->unk_226 + 5, 255); + this->unk_227 = CLAMP_MIN(this->unk_227 - 5, 50); + this->unk_228 = CLAMP_MIN(this->unk_228 - 5, 0); + } else if (this->skelAnime.animation == &object_po_sisters_Anim_000A54) { + this->unk_226 = CLAMP_MAX(this->unk_226 + 5, 80); + this->unk_227 = CLAMP_MAX(this->unk_227 + 5, 255); + this->unk_228 = CLAMP_MAX(this->unk_228 + 5, 225); + } else if (this->skelAnime.animation == &object_po_sisters_Anim_0008C0) { + if (this->actor.colorFilterTimer & 0x2) { + this->unk_226 = 0; + this->unk_227 = 0; + this->unk_228 = 0; + } else { + this->unk_226 = 80; + this->unk_227 = 255; + this->unk_228 = 225; + } + } else { + this->unk_226 = CLAMP_MAX(this->unk_226 + 5, 255); + this->unk_227 = CLAMP_MAX(this->unk_227 + 5, 255); + + if (this->unk_228 > 210) { + if (this->unk_228 && this->unk_228 && this->unk_228) {} + this->unk_228 = CLAMP_MIN(this->unk_228 - 5, 210); + } else { + this->unk_228 = CLAMP_MAX(this->unk_228 + 5, 210); + } + } +} + +s32 EnPoSisters_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + static Gfx* D_80B1DACC[] = { + object_po_sisters_DL_001DE0, + object_po_sisters_DL_002F88, + object_po_sisters_DL_003628, + object_po_sisters_DL_003DC8, + }; + static Gfx* D_80B1DADC[] = { + object_po_sisters_DL_001CB0, + object_po_sisters_DL_002EB8, + object_po_sisters_DL_003880, + object_po_sisters_DL_004020, + }; + static Color_RGBA8 D_80B1DAEC[] = { + { 80, 0, 100, 0 }, + { 80, 15, 0, 0 }, + { 0, 70, 50, 0 }, + { 70, 70, 0, 0 }, + }; + EnPoSisters* this = THIS; + + if ((limbIndex == 1) && (this->unk_191 & 0x40)) { + if (this->unk_192 >= 284) { + rot->x += (this->unk_192 - 284) * 0x1000; + } else { + rot->x += (this->unk_192 - 15) * 0x1000; + } + } + + if ((this->unk_229 == 0) || (limbIndex == 8) || ((this->actionFunc == func_80B1BA90) && (this->unk_192 >= 8))) { + *dList = NULL; + } else if (limbIndex == 9) { + *dList = D_80B1DACC[this->unk_18C]; + } else if (limbIndex == 10) { + *dList = D_80B1DADC[this->unk_18C]; + + gDPPipeSync((*gfx)++); + gDPSetEnvColor((*gfx)++, this->unk_226, this->unk_227, this->unk_228, this->unk_229); + } else if (limbIndex == 11) { + Color_RGBA8* colour = &D_80B1DAEC[this->unk_18C]; + + gDPPipeSync((*gfx)++); + gDPSetEnvColor((*gfx)++, colour->r, colour->g, colour->b, this->unk_229); + } + + return false; +} + +void EnPoSisters_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + static Vec3f D_80B1DAFC = { 1000.0f, -1700.0f, 0.0f }; + static s8 D_80B1DB08[] = { + -1, -1, 0, 1, 2, -1, 3, -1, -1, -1, -1, -1, + }; + EnPoSisters* this = THIS; + s32 end; + f32 temp_f2; + + if (D_80B1DB08[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[D_80B1DB08[limbIndex]]); + } else if (limbIndex == 9) { + Matrix_MultVecY(-2500.0f, &this->limbPos[4]); + Matrix_MultVecY(3000.0f, &this->limbPos[5]); + } else if (limbIndex == 10) { + Matrix_MultVecY(-4000.0f, &this->limbPos[6]); + } else if (limbIndex == 11) { + Matrix_MultVecX(3000.0f, &this->limbPos[7]); + } + + if ((this->actionFunc == func_80B1BA90) && (this->unk_192 >= 8) && (limbIndex == 9)) { + gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList((*gfx)++, object_po_sisters_DL_0046E0); + } + + if (limbIndex == 8) { + if (this->unk_191 & 0x20) { + for (end = this->unk_190 - 1; end > 0; end--) { + this->unk_22C[end] = this->unk_22C[end - 1]; + } + + Matrix_MultVec3f(&D_80B1DAFC, this->unk_22C); + } + + if (this->unk_190 > 0) { + Color_RGBA8* sp38 = &D_80B1DA30[this->unk_18C]; + + temp_f2 = Rand_ZeroFloat(0.3f) + 0.7f; + + if (this->actionFunc == func_80B1BCA0) { + Lights_PointNoGlowSetInfo(&this->lightInfo, this->unk_22C[0].x, this->unk_22C[0].y + 15.0f, + this->unk_22C[0].z, sp38->r * temp_f2, sp38->g * temp_f2, sp38->b * temp_f2, + 200); + } else { + Lights_PointGlowSetInfo(&this->lightInfo, this->unk_22C[0].x, this->unk_22C[0].y + 15.0f, + this->unk_22C[0].z, sp38->r * temp_f2, sp38->g * temp_f2, sp38->b * temp_f2, + 200); + } + } else { + Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); + } + + if (!(this->unk_191 & 0x80)) { + Matrix_Get(&this->unk_358); + } + } +} + +void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnPoSisters* this = THIS; + Color_RGBA8* temp_s1 = &D_80B1DA40[this->unk_18C]; + Color_RGBA8* temp_s7 = &D_80B1DA30[this->unk_18C]; + s32 pad; + s32 i; + s32 phi_s5; + f32 phi_f20; + s32 pad2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_80B1C974(this); + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + if ((this->unk_229 == 255) || (this->unk_229 == 0)) { + gDPSetEnvColor(POLY_OPA_DISP++, this->unk_226, this->unk_227, this->unk_228, this->unk_229); + gSPSegment(POLY_OPA_DISP++, 0x09, D_801AEFA0); + POLY_OPA_DISP = + SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_OPA_DISP); + } else { + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->unk_229); + gSPSegment(POLY_XLU_DISP++, 0x09, D_801AEF88); + POLY_XLU_DISP = + SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnPoSisters_OverrideLimbDraw, EnPoSisters_PostLimbDraw, &this->actor, POLY_XLU_DISP); + } + + if (!(this->unk_191 & 0x80)) { + Matrix_Put(&this->unk_358); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_po_sisters_DL_0027B0); + } + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0, (globalCtx->gameplayFrames * -20) % 512, + 32, 128)); + gDPSetEnvColor(POLY_XLU_DISP++, temp_s1->r, temp_s1->g, temp_s1->b, temp_s1->a); + + if (this->actionFunc == func_80B1BCA0) { + phi_s5 = (((-this->unk_192 * 255) + 0x1FE0) / 32) & 0xFF; + phi_f20 = 0.0056000003f; + } else { + phi_s5 = 0; + phi_f20 = this->actor.scale.x * 0.5f; + } + + for (i = 0; i < this->unk_190; i++) { + if (this->actionFunc != func_80B1BCA0) { + phi_s5 = ((-i * 31) + 248) & 0xFF; + } + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, temp_s7->r, temp_s7->g, temp_s7->b, phi_s5); + + Matrix_Translate(this->unk_22C[i].x, this->unk_22C[i].y, this->unk_22C[i].z, MTXMODE_NEW); + Matrix_RotateZYX(0, BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), 0, MTXMODE_APPLY); + + if (this->actionFunc == func_80B1BA90) { + f32 phi_f0; + + phi_f20 = ((this->unk_192 - i) * 0.025f) + 0.5f; + phi_f0 = CLAMP(phi_f20, 0.5f, 0.8f); + phi_f20 = phi_f0 * 0.007f; + } + 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++, gGameplayKeepDrawFlameDL); + } + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->actor.scale.x * 142.857131958f * this->drawDmgEffScale, 0.0f, this->drawDmgEffAlpha, + ACTOR_DRAW_DMGEFF_LIGHT_ORBS); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h index 75ad55a00..3350f8f03 100644 --- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h +++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.h @@ -7,11 +7,37 @@ struct EnPoSisters; typedef void (*EnPoSistersActionFunc)(struct EnPoSisters*, GlobalContext*); +#define ENPOSISTERS_GET_300(thisx) (((thisx)->params >> 8) & 3) +#define ENPOSISTERS_GET_C00(thisx) (((thisx)->params >> 0xA) & 3) +#define ENPOSISTERS_GET_1000(thisx) ((thisx)->params & 0x1000) + typedef struct EnPoSisters { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnPoSistersActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x20C]; + /* 0x018C */ u8 unk_18C; + /* 0x018D */ u8 unk_18D; + /* 0x018E */ u8 unk_18E; + /* 0x018F */ u8 unk_18F; + /* 0x0190 */ u8 unk_190; + /* 0x0191 */ u8 unk_191; + /* 0x0192 */ s16 unk_192; + /* 0x0194 */ s16 unk_194; + /* 0x0196 */ Vec3s jointTable[12]; + /* 0x01DE */ Vec3s morphTable[12]; + /* 0x0226 */ u8 unk_226; + /* 0x0227 */ u8 unk_227; + /* 0x0228 */ u8 unk_228; + /* 0x0229 */ u8 unk_229; + /* 0x022C */ Vec3f unk_22C[8]; + /* 0x028C */ Vec3f limbPos[8]; + /* 0x02EC */ f32 unk_2EC; + /* 0x02F0 */ f32 drawDmgEffAlpha; + /* 0x02F4 */ f32 drawDmgEffScale; + /* 0x02F8 */ LightNode* lightNode; + /* 0x02FC */ LightInfo lightInfo; + /* 0x030C */ ColliderCylinder collider; + /* 0x0358 */ MtxF unk_358; } EnPoSisters; // size = 0x398 extern const ActorInit En_Po_Sisters_InitVars; 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 bddd970b9..478c306b0 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -5,8 +5,9 @@ */ #include "z_en_poh.h" +#include "objects/object_po/object_po.h" -#define FLAGS 0x00001205 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200 | ACTOR_FLAG_1000) #define THIS ((EnPoh*)thisx) @@ -45,17 +46,6 @@ void func_80B2E3F8(EnPoh* this, GlobalContext* globalCtx); void func_80B2F328(Actor* thisx, GlobalContext* globalCtx); void func_80B2F37C(Actor* thisx, GlobalContext* globalCtx); -extern AnimationHeader D_060001A8; -extern AnimationHeader D_060004EC; -extern AnimationHeader D_060006E0; -extern AnimationHeader D_06000A60; -extern AnimationHeader D_060011C4; -extern AnimationHeader D_060015B0; -extern Gfx D_06002608[]; -extern Gfx D_06002D28[]; -extern Gfx D_06003850[]; -extern SkeletonHeader D_060050D0; - const ActorInit En_Poh_InitVars = { ACTOR_EN_POH, ACTORCAT_ENEMY, @@ -162,7 +152,7 @@ void EnPoh_Init(Actor* thisx, GlobalContext* globalCtx) { s32 pad; Actor_ProcessInitChain(&this->actor, sInitChain); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); Collider_InitAndSetJntSph(globalCtx, &this->colliderSph, &this->actor, &sJntSphInit, this->colliderSphElements); this->colliderSph.elements[0].dim.worldSphere.radius = 0; this->colliderSph.elements[0].dim.worldSphere.center.x = this->actor.world.pos.x; @@ -175,7 +165,8 @@ void EnPoh_Init(Actor* thisx, GlobalContext* globalCtx) { this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); Lights_PointGlowSetInfo(&this->lightInfo, this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, 255, 255, 255, 0); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_060050D0, &D_06000A60, this->jointTable, this->morphTable, 21); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_po_Skel_0050D0, &object_po_Anim_000A60, this->jointTable, + this->morphTable, 21); this->actor.bgCheckFlags |= 0x400; func_80B2D0E8(this); } @@ -203,7 +194,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); } } @@ -222,7 +213,7 @@ void func_80B2C9B8(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2CA4C(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &D_060015B0); + Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0); this->unk_18E = Rand_S16Offset(2, 3); this->actionFunc = func_80B2CAA4; this->actor.speedXZ = 0.0f; @@ -248,7 +239,7 @@ void func_80B2CAA4(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2CB60(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &D_06000A60); + Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60); this->unk_18E = Rand_S16Offset(15, 3); this->colliderCylinder.base.acFlags |= AC_ON; this->actionFunc = func_80B2CBBC; @@ -283,7 +274,7 @@ void func_80B2CBBC(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2CD14(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &D_06000A60); + Animation_PlayLoop(&this->skelAnime, &object_po_Anim_000A60); this->actionFunc = func_80B2CD64; this->unk_18E = 0; this->actor.speedXZ = 2.0f; @@ -312,7 +303,7 @@ void func_80B2CD64(EnPoh* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer > 280.0f) { func_80B2CB60(this); } else if ((this->unk_18E == 0) && (this->actor.xzDistToPlayer < 140.0f) && - !Actor_IsLinkFacingActor(&this->actor, 0x2AAA, globalCtx)) { + !Player_IsFacingActor(&this->actor, 0x2AAA, globalCtx)) { func_80B2CEC8(this); } @@ -322,17 +313,17 @@ void func_80B2CD64(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2CEC8(EnPoh* this) { - Animation_MorphToLoop(&this->skelAnime, &D_060001A8, -6.0f); + Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0001A8, -6.0f); this->unk_18E = 12; this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); this->actionFunc = func_80B2CF28; } void func_80B2CF28(EnPoh* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_KANTERA); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_KANTERA); if (this->unk_18E != 0) { this->unk_18E--; } @@ -351,11 +342,11 @@ void func_80B2CF28(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2CFF8(EnPoh* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_060004EC, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_po_Anim_0004EC, -6.0f); func_800BE504(&this->actor, &this->colliderCylinder); this->colliderCylinder.base.acFlags &= ~AC_ON; this->actor.speedXZ = 5.0f; - func_800BCB70(&this->actor, 0x4000, 255, 0, 16); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 16); this->actionFunc = func_80B2D07C; } @@ -372,8 +363,8 @@ void func_80B2D07C(EnPoh* this, GlobalContext* globalCtx) { void func_80B2D0E8(EnPoh* this) { this->unk_197 = 0; - this->actor.flags &= ~1; - Animation_PlayOnceSetSpeed(&this->skelAnime, &D_060011C4, 0.0f); + this->actor.flags &= ~ACTOR_FLAG_1; + Animation_PlayOnceSetSpeed(&this->skelAnime, &object_po_Anim_0011C4, 0.0f); this->actionFunc = func_80B2D140; } @@ -381,14 +372,14 @@ void func_80B2D140(EnPoh* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { this->unk_197 = 255; this->unk_190 = Rand_S16Offset(700, 300); - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; func_80B2CB60(this); } else if (this->skelAnime.curFrame > 10.0f) { this->unk_197 = (this->skelAnime.curFrame - 10.0f) * 0.05f * 255.0f; } if ((this->skelAnime.playSpeed < 0.5f) && (this->actor.xzDistToPlayer < 280.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); this->skelAnime.playSpeed = 1.0f; } } @@ -398,7 +389,7 @@ void func_80B2D2C0(EnPoh* this) { this->actor.world.rot.y = this->actor.shape.rot.y; this->unk_18E = 0; this->actor.hintId = 0xFF; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = func_80B2D300; } @@ -413,7 +404,7 @@ void func_80B2D300(EnPoh* this, GlobalContext* globalCtx) { this->unk_18E++; if (this->unk_18E < 8) { - sp38 = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) + 0x4800; + sp38 = Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x4800; if (this->unk_18E < 5) { sp3A = (this->unk_18E * 0x1000) - 0x4000; sp44.y = (Math_SinS(sp3A) * 23.0f) + (this->actor.world.pos.y + 40.0f); @@ -426,13 +417,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) { @@ -447,12 +438,12 @@ void func_80B2D300(EnPoh* this, GlobalContext* globalCtx) { } if (this->unk_18E == 18) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WIZ_DISAPPEAR); } } void func_80B2D5DC(EnPoh* this) { - Animation_PlayOnce(&this->skelAnime, &D_06000A60); + Animation_PlayOnce(&this->skelAnime, &object_po_Anim_000A60); this->actionFunc = func_80B2D628; this->actor.speedXZ = -5.0f; } @@ -469,7 +460,7 @@ void func_80B2D628(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2D694(EnPoh* this) { - Animation_PlayLoop(&this->skelAnime, &D_060015B0); + Animation_PlayLoop(&this->skelAnime, &object_po_Anim_0015B0); this->unk_192 = BINANG_ROT180(this->actor.world.rot.y); this->actionFunc = func_80B2D6EC; this->actor.speedXZ = 0.0f; @@ -493,8 +484,8 @@ void func_80B2D76C(EnPoh* this) { this->unk_192 = 0x2000; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DISAPPEAR); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DISAPPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); this->colliderCylinder.base.acFlags &= ~AC_ON; this->actionFunc = func_80B2D7D4; } @@ -523,8 +514,8 @@ void func_80B2D924(EnPoh* this) { this->unk_18C = 0; this->unk_192 = 0x2000; this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); this->colliderCylinder.base.acFlags &= ~AC_ON; this->actionFunc = func_80B2D980; } @@ -547,7 +538,7 @@ void func_80B2D980(EnPoh* this, GlobalContext* globalCtx) { } void func_80B2DAD0(EnPoh* this) { - Animation_MorphToLoop(&this->skelAnime, &D_060006E0, -5.0f); + Animation_MorphToLoop(&this->skelAnime, &object_po_Anim_0006E0, -5.0f); this->actor.speedXZ = 5.0f; this->actor.world.rot.y = BINANG_ROT180(this->actor.shape.rot.y); this->colliderCylinder.base.acFlags |= AC_ON; @@ -576,27 +567,28 @@ void func_80B2DC50(EnPoh* this, GlobalContext* globalCtx) { this->actor.update = func_80B2F328; this->actor.draw = func_80B2F37C; this->actor.shape.shadowDraw = NULL; - this->actor.world.pos.x = this->unk_3D8.wx; - this->actor.world.pos.y = this->unk_3D8.wy; - this->actor.world.pos.z = this->unk_3D8.wz; + this->actor.world.pos.x = this->unk_3D8.xw; + this->actor.world.pos.y = this->unk_3D8.yw; + this->actor.world.pos.z = this->unk_3D8.zw; Actor_SetScale(&this->actor, 0.01f); - this->actor.flags |= 0x10; + this->actor.flags |= ACTOR_FLAG_10; this->actor.gravity = -1.0f; this->actor.shape.yOffset = 1500.0f; this->actor.world.pos.y -= 15.0f; this->actor.shape.rot.x = -0x8000; func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 8); - this->actor.flags &= ~(0x4 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); this->actionFunc = func_80B2DD2C; } void func_80B2DD2C(EnPoh* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight <= BGCHECK_Y_MIN)) { - EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, D_06002D28); + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_PO, 10, + object_po_DL_002D28); func_80B2E0B0(this); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 4); } @@ -638,7 +630,7 @@ void func_80B2E0B0(EnPoh* this) { this->actor.home.pos.y = this->actor.world.pos.y; this->actor.scale.x = 0.0f; this->actor.scale.y = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_METAL_BOX_BOUND); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_METAL_BOX_BOUND); this->actionFunc = func_80B2E180; } @@ -652,10 +644,10 @@ void func_80B2E180(EnPoh* this, GlobalContext* globalCtx) { void func_80B2E1D8(EnPoh* this) { this->actor.home.pos.y = this->actor.world.pos.y; - Actor_SetHeight(&this->actor, -10.0f); + Actor_SetFocus(&this->actor, -10.0f); this->unk_18E = 200; this->unk_18D = 32; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->actionFunc = func_80B2E230; } @@ -672,7 +664,7 @@ void func_80B2E230(EnPoh* this, GlobalContext* globalCtx) { return; } - func_800B8A1C(&this->actor, globalCtx, 0xBA, 35.0f, 60.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 35.0f, 60.0f); this->actor.world.pos.y = (Math_SinS(this->unk_18D * 0x800) * 5.0f) + this->actor.home.pos.y; if (this->unk_18D) { this->unk_18D--; @@ -682,14 +674,14 @@ void func_80B2E230(EnPoh* this, GlobalContext* globalCtx) { this->unk_18D = 32; } - Actor_SetHeight(&this->actor, -10.0f); + Actor_SetFocus(&this->actor, -10.0f); Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 100, 0, 150, this->unk_197 * (40.0f / 51.0f)); } void func_80B2E3B0(EnPoh* this) { func_801A7328(&this->actor.projectedPos, NA_SE_EN_PO_BIG_CRY - SFX_FLAG); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_LAUGH); this->actionFunc = func_80B2E3F8; } @@ -705,9 +697,9 @@ void func_80B2E438(EnPoh* this, GlobalContext* globalCtx) { this->colliderCylinder.base.acFlags &= ~AC_HIT; if (!Actor_ApplyDamage(&this->actor)) { Enemy_StartFinishingBlow(globalCtx, &this->actor); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DEAD); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DEAD); } else if (this->actor.colChkInfo.damage != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PO_DAMAGE); } if (this->actor.colChkInfo.damageEffect != 14) { @@ -715,8 +707,8 @@ void func_80B2E438(EnPoh* this, GlobalContext* globalCtx) { func_80B2D924(this); } else { if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_298 = 4.0f; - this->unk_29C = 0.45f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.45f; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->colliderCylinder.info.bumper.hitPos.x, this->colliderCylinder.info.bumper.hitPos.y, @@ -805,8 +797,8 @@ void func_80B2E8E0(EnPoh* this) { } void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx2) { - EnPoh* this = THIS; GlobalContext* globalCtx = globalCtx2; + EnPoh* this = THIS; s32 pad; if (this->colliderSph.base.atFlags & AT_HIT) { @@ -817,9 +809,9 @@ void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx2) { func_80B2E438(this, globalCtx); func_80B2E55C(this); this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if ((this->actionFunc == func_80B2CF28) && (this->unk_18E < 10)) { - this->actor.flags |= 0x1000000; + this->actor.flags |= ACTOR_FLAG_1000000; CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSph.base); } @@ -830,7 +822,7 @@ void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx2) { CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSph.base); - Actor_SetHeight(&this->actor, 42.0f); + Actor_SetFocus(&this->actor, 42.0f); if ((this->actionFunc != func_80B2D07C) && (this->actionFunc != func_80B2D628)) { if (this->actionFunc == func_80B2DB44) { @@ -842,16 +834,16 @@ void EnPoh_Update(Actor* thisx, GlobalContext* globalCtx2) { func_80B2E8E0(this); this->actor.shape.shadowAlpha = this->unk_197; - if (this->unk_298 > 0.0f) { - Math_StepToF(&this->unk_298, 0.0f, 0.05f); + if (this->drawDmgEffAlpha > 0.0f) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); if (this->unk_197 != 255) { if (this->unk_197 * (1.0f / 255.0f) < this->unk_197) { - this->unk_298 = this->unk_197 * (1.0f / 255.0f); + this->drawDmgEffAlpha = this->unk_197 * (1.0f / 255.0f); } } - this->unk_29C = (this->unk_298 + 1.0f) * (9.0f / 40.0f); - this->unk_29C = CLAMP_MAX(this->unk_29C, 0.45f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * (9.0f / 40.0f); + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.45f); } } @@ -888,14 +880,15 @@ void EnPoh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve Collider_UpdateSpheres(limbIndex, &this->colliderSph); if ((this->actionFunc == func_80B2D300) && (this->unk_18E >= 2) && (limbIndex == 5)) { gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList((*gfx)++, D_06002608); + gSPDisplayList((*gfx)++, object_po_DL_002608); } 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); + Matrix_Get(&this->unk_3D8); func_80B2C910(&sp60, globalCtx); Lights_PointGlowSetInfo(&this->lightInfo, this->colliderSph.elements[0].dim.worldSphere.center.x + (s32)sp60.x, this->colliderSph.elements[0].dim.worldSphere.center.y + (s32)sp60.y, @@ -906,19 +899,19 @@ void EnPoh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve temp_s3 = D_80B2F71C[limbIndex]; if (temp_s3 != -1) { if (temp_s3 < 4) { - Matrix_GetStateTranslation(&this->unk_2A0[temp_s3]); + Matrix_MultZero(&this->limbPos[temp_s3]); } else if (temp_s3 == 4) { - Matrix_GetStateTranslationAndScaledX(2000.0f, &this->unk_2A0[temp_s3]); + Matrix_MultVecX(2000.0f, &this->limbPos[temp_s3]); } else { s32 i; - Vec3f* vec = &this->unk_2A0[temp_s3 + 2]; + Vec3f* vec = &this->limbPos[temp_s3 + 2]; Vec3f* vec2 = &D_80B2F734[0]; - Matrix_GetStateTranslationAndScaledX(-2000.0f, &this->unk_2A0[temp_s3]); - Matrix_GetStateTranslationAndScaledY(-2000.0f, &this->unk_2A0[temp_s3 + 1]); + Matrix_MultVecX(-2000.0f, &this->limbPos[temp_s3]); + Matrix_MultVecY(-2000.0f, &this->limbPos[temp_s3 + 1]); - for (i = temp_s3 + 2; i < ARRAY_COUNT(this->unk_2A0); i++, vec++, vec2++) { - Matrix_MultiplyVector3fByState(vec2, vec); + for (i = temp_s3 + 2; i < ARRAY_COUNT(this->limbPos); i++, vec++, vec2++) { + Matrix_MultVec3f(vec2, vec); } } } @@ -959,14 +952,15 @@ void EnPoh_Draw(Actor* thisx, GlobalContext* globalCtx) { gDPPipeSync(&gfx[0]); gDPSetEnvColor(&gfx[1], this->unk_198, this->unk_199, this->unk_19A, 255); - Matrix_SetCurrentState(&this->unk_3D8); + Matrix_Put(&this->unk_3D8); gSPMatrix(&gfx[2], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&gfx[3], D_06002D28); + gSPDisplayList(&gfx[3], object_po_DL_002D28); POLY_OPA_DISP = &gfx[4]; - func_800BE680(globalCtx, &this->actor, this->unk_2A0, 10, this->actor.scale.x * 100.0f * this->unk_29C, 0.0f, - this->unk_298, 20); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->actor.scale.x * 100.0f * this->drawDmgEffScale, 0.0f, this->drawDmgEffAlpha, + ACTOR_DRAW_DMGEFF_LIGHT_ORBS); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -1001,7 +995,7 @@ void func_80B2F37C(Actor* thisx, GlobalContext* globalCtx) { this->actor.world.pos.z + sp7C.z, this->unk_198, this->unk_199, this->unk_19A, 200); gSPMatrix(&gfx[2], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&gfx[3], D_06002D28); + gSPDisplayList(&gfx[3], object_po_DL_002D28); POLY_OPA_DISP = &gfx[4]; } else { @@ -1013,10 +1007,10 @@ void func_80B2F37C(Actor* thisx, GlobalContext* globalCtx) { gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 170, 255, this->unk_197); gDPSetEnvColor(POLY_XLU_DISP++, this->unk_194, this->unk_195, this->unk_196, 255); - Matrix_InsertYRotation_f((func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) + 0x8000) * (M_PI / 32768), MTXMODE_APPLY); + Matrix_RotateYF((Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) + 0x8000) * (M_PI / 32768), 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_06003850); + gSPDisplayList(POLY_XLU_DISP++, object_po_DL_003850); } CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.h b/src/overlays/actors/ovl_En_Poh/z_en_poh.h index fe579e027..f4787b357 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.h +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.h @@ -26,9 +26,9 @@ typedef struct EnPoh { /* 0x019B */ u8 unk_19B; /* 0x019C */ Vec3s jointTable[21]; /* 0x021A */ Vec3s morphTable[21]; - /* 0x0298 */ f32 unk_298; - /* 0x029C */ f32 unk_29C; - /* 0x02A0 */ Vec3f unk_2A0[10]; + /* 0x0298 */ f32 drawDmgEffAlpha; + /* 0x029C */ f32 drawDmgEffScale; + /* 0x02A0 */ Vec3f limbPos[10]; /* 0x0318 */ LightNode* lightNode; /* 0x031C */ LightInfo lightInfo; /* 0x032C */ ColliderCylinder colliderCylinder; diff --git a/src/overlays/actors/ovl_En_Pp/z_en_pp.c b/src/overlays/actors/ovl_En_Pp/z_en_pp.c index 2ae03a166..67f951299 100644 --- a/src/overlays/actors/ovl_En_Pp/z_en_pp.c +++ b/src/overlays/actors/ovl_En_Pp/z_en_pp.c @@ -1,6 +1,12 @@ +/* + * File: z_en_pp.c + * Overlay: ovl_En_Pp + * Description: Hiploop + */ + #include "z_en_pp.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnPp*)thisx) diff --git a/src/overlays/actors/ovl_En_Pr/z_en_pr.c b/src/overlays/actors/ovl_En_Pr/z_en_pr.c index 91c8407a3..8f3a30d75 100644 --- a/src/overlays/actors/ovl_En_Pr/z_en_pr.c +++ b/src/overlays/actors/ovl_En_Pr/z_en_pr.c @@ -1,6 +1,14 @@ -#include "z_en_pr.h" +/* + * File: z_en_pr.c + * Overlay: ovl_En_Pr + * Description: Desbreko + */ -#define FLAGS 0x00000015 +#include "z_en_pr.h" +#include "overlays/actors/ovl_En_Prz/z_en_prz.h" +#include "objects/object_pr/object_pr.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnPr*)thisx) @@ -9,18 +17,21 @@ void EnPr_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPr_Update(Actor* thisx, GlobalContext* globalCtx); void EnPr_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A326F0(EnPr* this); void func_80A32740(EnPr* this, GlobalContext* globalCtx); +void func_80A32854(EnPr* this); void func_80A3289C(EnPr* this, GlobalContext* globalCtx); +void func_80A3295C(EnPr* this); void func_80A32984(EnPr* this, GlobalContext* globalCtx); void func_80A32A40(EnPr* this, GlobalContext* globalCtx); +void func_80A32AF8(EnPr* this); void func_80A32B20(EnPr* this, GlobalContext* globalCtx); +void func_80A32CDC(EnPr* this); void func_80A32D28(EnPr* this, GlobalContext* globalCtx); void func_80A32EA4(EnPr* this, GlobalContext* globalCtx); void func_80A32F48(EnPr* this, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_80A338A0 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -55,6 +66,8 @@ static DamageTable D_80A338A0 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; +f32 D_80A338C0[PLAYER_FORM_MAX] = { 30.0f, 30.0f, 30.0f, 15.0f, 15.0f }; + const ActorInit En_Pr_InitVars = { ACTOR_EN_PR, ACTORCAT_ENEMY, @@ -67,64 +80,547 @@ const ActorInit En_Pr_InitVars = { (ActorFunc)EnPr_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A338F4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK4, { 0x20000000, 0x00, 0x04 }, { 0xF7CFFFFF, 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_UNK4, + { 0x20000000, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 18, 20, 5, { 0, 0, 0 } }, }; -#endif +static AnimationHeader* sAnimations[] = { + &object_pr_Anim_0021E8, &object_pr_Anim_001E10, &object_pr_Anim_0021E8, + &object_pr_Anim_000740, &object_pr_Anim_000268, +}; -extern DamageTable D_80A338A0; -extern ColliderCylinderInit D_80A338F4; +u8 D_80A33934[] = { + 0, 2, 0, 0, 2, +}; -extern UNK_TYPE D_060021E8; +void EnPr_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnPr* this = THIS; + EnPrz* prz; + s32 i; + s32 temp_s4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/EnPr_Init.s") + this->actor.colChkInfo.health = 3; + this->actor.colChkInfo.mass = 50; + this->actor.hintId = 0x5C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/EnPr_Destroy.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A3242C.s") + this->unk_208 = 255; + this->unk_2CC = 0.01f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A324E0.s") + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A325E4.s") + this->actor.targetMode = 3; + this->unk_2B8 = this->actor.world.pos.y; + this->actor.shape.yOffset = 1500.0f; + this->actor.colChkInfo.damageTable = &sDamageTable; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A326F0.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_pr_Skel_0038B8, &object_pr_Anim_0021E8, this->jointTable, + this->morphTable, 10); + this->unk_2C8 = this->actor.world.rot.z * 20.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32740.s") + if (this->unk_2C8 < 80.0f) { + this->unk_2C8 = 80.0f; + } + this->actor.world.rot.z = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32854.s") + temp_s4 = ENPR_GET_FF00(&this->actor); + if (temp_s4 > ENPR_FF00_MAX) { + temp_s4 = ENPR_FF00_MAX; + } else if (temp_s4 < ENPR_FF00_MIN) { + temp_s4 = ENPR_FF00_MIN; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A3289C.s") + this->unk_2F8 = &this->actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A3295C.s") + for (i = 0; i < temp_s4; i++) { + prz = (EnPrz*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PRZ, + this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, + this->actor.world.rot.y, 0, i + 1); + if (prz != NULL) { + prz->unk_220 = this->unk_2F8; + this->unk_2F8 = &prz->actor; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32984.s") + this->unk_2D0 = 255; + this->unk_20E = 30; + this->unk_216 = this->actor.world.rot.y; + this->unk_214 = this->actor.world.rot.y; + this->unk_2B4 = this->actor.world.pos.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32A40.s") + func_80A326F0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32AF8.s") +void EnPr_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnPr* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32B20.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32CDC.s") +void func_80A3242C(EnPr* this, s32 arg0) { + f32 sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32D28.s") + this->unk_21C = arg0; + sp34 = 1.0f; + this->unk_2BC = Animation_GetLastFrame(sAnimations[arg0]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32E60.s") + if (this->unk_21C == 2) { + sp34 = 2.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32EA4.s") + Animation_Change(&this->skelAnime, sAnimations[this->unk_21C], sp34, 0.0f, this->unk_2BC, D_80A33934[this->unk_21C], + -2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A32F48.s") +s32 func_80A324E0(EnPr* this, GlobalContext* globalCtx) { + CollisionPoly* sp54; + Vec3f sp48; + s32 sp44; + WaterBox* sp40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A33098.s") + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &this->unk_2E0, &sp48, &sp54, 1, 0, 0, 1, + &sp44)) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/EnPr_Update.s") + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_2B4, &sp40)) { + if ((this->unk_2B4 - 30.0f) < this->actor.world.pos.y) { + this->unk_2B8 = this->unk_2B4 - 30.0f; + return 2; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A3357C.s") + if (this->actor.world.pos.y < (this->actor.floorHeight + 20.0f)) { + this->unk_2B8 = this->actor.floorHeight + 20.0f; + return 2; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/func_80A335B4.s") +s32 func_80A325E4(EnPr* this) { + s16 temp = this->unk_214 * 0.2f; + s32 abs = ABS_ALT(temp) & 0xFFFF; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr/EnPr_Draw.s") + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_22C, 1, abs + 1, 0); + this->unk_216 = this->actor.world.rot.y - this->unk_22C; + + if (this->unk_216 > 10000) { + this->unk_216 = 10000; + } else if (this->unk_216 < -10000) { + this->unk_216 = -10000; + } + + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->unk_22C)) > 0x100) { + return true; + } + this->unk_216 = 0; + return false; +} + +void func_80A326F0(EnPr* this) { + if (this->unk_21C != 0) { + func_80A3242C(this, 0); + } + this->unk_206 = 0; + this->actor.speedXZ = 1.0f; + this->actionFunc = func_80A32740; +} + +void func_80A32740(EnPr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (func_80A324E0(this, globalCtx)) { + case 1: + func_80A3295C(this); + return; + + case 2: + this->unk_206 = 3; + this->actionFunc = func_80A32A40; + break; + } + + if (this->unk_2C8 < sqrtf(SQ(this->actor.world.pos.x - this->actor.home.pos.x) + + SQ(this->actor.world.pos.z - this->actor.home.pos.z))) { + func_80A32854(this); + } else if ((this->unk_20E == 0) && (player->stateFlags1 & 0x8000000)) { + if (sqrtf(SQ(player->actor.world.pos.x - this->actor.home.pos.x) + + SQ(player->actor.world.pos.z - this->actor.home.pos.z)) < this->unk_2C8) { + func_80A32AF8(this); + } + } +} + +void func_80A32854(EnPr* this) { + if (this->unk_21C != 0) { + func_80A3242C(this, 0); + } + this->unk_206 = 1; + this->actionFunc = func_80A3289C; +} + +void func_80A3289C(EnPr* this, GlobalContext* globalCtx) { + this->unk_22C = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + func_80A325E4(this); + + if (sqrtf(SQ(this->actor.world.pos.x - this->actor.home.pos.x) + + SQ(this->actor.world.pos.z - this->actor.home.pos.z)) < (((BREG(53) * 0.1f) + 0.5f) * this->unk_2C8)) { + this->unk_206 = 3; + this->actionFunc = func_80A32A40; + } +} + +void func_80A3295C(EnPr* this) { + this->unk_22C = BINANG_ADD(this->actor.world.rot.y, 0x4000); + this->unk_206 = 2; + this->actionFunc = func_80A32984; +} + +void func_80A32984(EnPr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((player->stateFlags1 & 0x8000000) && (this->unk_20E == 0)) { + this->unk_22C = this->actor.world.rot.y; + func_80A32AF8(this); + } else if (!func_80A325E4(this)) { + if (func_80A324E0(this, globalCtx)) { + this->unk_22C += 0x1000; + } else { + if (this->unk_21C != 0) { + func_80A3242C(this, 0); + } + this->unk_206 = 3; + this->actionFunc = func_80A32A40; + } + } +} + +void func_80A32A40(EnPr* this, GlobalContext* globalCtx) { + Vec3f sp34; + WaterBox* sp30; + + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp34.y = randPlusMinusPoint5Scaled(50.0f) + this->actor.home.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_2B4, &sp30)) { + if (sp34.y < (this->unk_2B4 - 30.0f)) { + this->unk_2B8 = sp34.y; + } else { + this->unk_2B8 = this->unk_2B4 - 30.0f; + } + } + + this->unk_206 = 0; + this->actionFunc = func_80A32740; +} + +void func_80A32AF8(EnPr* this) { + this->unk_206 = 4; + this->skelAnime.playSpeed = 2.0f; + this->actionFunc = func_80A32B20; +} + +void func_80A32B20(EnPr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->actor.speedXZ = BREG(57) + 3.0f; + Math_SmoothStepToS(&this->unk_22C, this->actor.yawTowardsPlayer, BREG(49) + 1, BREG(50) + 1000, BREG(51)); + this->unk_2B8 = D_80A338C0[(void)0, gSaveContext.save.playerForm] + player->actor.world.pos.y; + func_80A324E0(this, globalCtx); + + if (!(player->stateFlags1 & 0x8000000)) { + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 1.0f; + func_80A32854(this); + } else if (this->unk_2C8 < sqrtf(SQ(player->actor.world.pos.x - this->actor.home.pos.x) + + SQ(player->actor.world.pos.z - this->actor.home.pos.z))) { + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 1.0f; + func_80A32854(this); + } else if (!func_80A325E4(this) && (this->actor.xzDistToPlayer < 200.0f) && + (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 80.0f)) { + this->skelAnime.playSpeed = 1.0f; + func_80A32CDC(this); + } +} + +void func_80A32CDC(EnPr* this) { + func_80A3242C(this, 3); + this->unk_206 = 5; + this->unk_20A = 400; + this->unk_2C0 = 0.0f; + this->actionFunc = func_80A32D28; +} + +void func_80A32D28(EnPr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags1 & 0x8000000)) { + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 1.0f; + func_80A32854(this); + } else { + Math_SmoothStepToS(&this->unk_22C, this->actor.yawTowardsPlayer, BREG(49) + 1, BREG(50) + 1000, BREG(51)); + func_80A325E4(this); + this->unk_2B8 = D_80A338C0[(void)0, gSaveContext.save.playerForm] + player->actor.world.pos.y; + func_80A324E0(this, globalCtx); + if (this->unk_2C8 < sqrtf(SQ(player->actor.world.pos.x - this->actor.home.pos.x) + + SQ(player->actor.world.pos.z - this->actor.home.pos.z))) { + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 1.0f; + func_80A32854(this); + } + } +} + +void func_80A32E60(EnPr* this) { + func_80A3242C(this, 4); + this->unk_206 = 6; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80A32EA4; +} + +void func_80A32EA4(EnPr* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_2BC <= curFrame) { + if (this->actor.colChkInfo.health <= 0) { + this->unk_206 = 7; + this->unk_20A = 50; + this->actor.flags |= ACTOR_FLAG_8000000; + this->unk_2C4 = 0.0f; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLEWALK_DEAD); + this->unk_216 = 0; + this->actionFunc = func_80A32F48; + } else { + func_80A326F0(this); + } + } +} + +void func_80A32F48(EnPr* this, GlobalContext* globalCtx) { + WaterBox* sp2C; + + if (this->unk_208 > 0) { + this->unk_208 -= 2; + } else { + this->unk_208 = 0; + } + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_2B4, &sp2C)) { + if ((this->unk_2B4 - 100.0f) < this->actor.world.pos.y) { + this->unk_212 += 0xBB8; + this->unk_2C4 = 2.0f * Math_SinS(this->unk_212); + } + Math_ApproachF(&this->actor.world.pos.y, (this->unk_2B4 - 16.0f) + this->unk_2C4, 0.5f, 2.0f); + Math_SmoothStepToS(&this->actor.world.rot.z, 0x7700, 0x12C, 0x3E8, 0x3E8); + } + + if ((this->unk_20A == 0) && (this->unk_208 == 0)) { + this->unk_2D2 = 1; + } + + if (this->unk_2D2 != 0) { + Math_SmoothStepToS(&this->unk_2D0, 0, 1, 15, 50); + if (this->unk_2D0 < 2) { + Actor_MarkForDeath(&this->actor); + } + } +} + +void func_80A33098(EnPr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((this->unk_206 != 7) && (this->unk_206 != 6)) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffAlpha = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.focus.pos.x, + this->actor.focus.pos.y, this->actor.focus.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + + if ((player->stateFlags1 & 0x8000000) && (this->actor.colChkInfo.damageEffect == 5)) { + this->drawDmgEffAlpha = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + } + + if ((this->unk_206 != 6) && (this->unk_206 != 7)) { + Actor_ApplyDamage(&this->actor); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLEWALK_DAMAGE); + func_80A32E60(this); + } + } + } +} + +void EnPr_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnPr* this = THIS; + s32 i; + + SkelAnime_Update(&this->skelAnime); + + if (this->unk_20A != 0) { + this->unk_20A--; + } + + if (this->unk_20E != 0) { + this->unk_20E--; + } + + if (this->unk_20C != 0) { + this->unk_20C--; + } + + if (this->unk_210 != 0) { + this->unk_210--; + } + + this->actionFunc(this, globalCtx); + + Actor_SetFocus(&this->actor, 20.0f); + func_80A33098(this, globalCtx); + Math_Vec3f_Copy(&this->unk_2E0, &this->actor.world.pos); + + this->unk_2E0.x += (Math_SinS(this->actor.world.rot.y) * 70.0f); + this->unk_2E0.y = this->unk_2D4.y - 10.0f; + this->unk_2E0.z += Math_CosS(this->actor.world.rot.y) * 70.0f; + + Math_SmoothStepToS(&this->unk_214, this->unk_216, 1, 0x7D0, 0); + + if (this->unk_210 == 0) { + this->unk_210 = Rand_S16Offset(10, 30); + this->unk_204 = 1; + } + + Actor_MoveWithGravity(&this->actor); + + if (this->unk_206 != 7) { + Vec3f sp50; + s16 pitch; + + Math_ApproachF(&this->actor.world.pos.y, this->unk_2B8, 0.3f, BREG(11) + 1.0f); + Math_Vec3f_Copy(&sp50, &this->actor.world.pos); + sp50.y = this->unk_2B8; + pitch = Math_Vec3f_Pitch(&this->actor.world.pos, &sp50) * 0.3f; + + if (fabsf(this->actor.world.pos.y - this->unk_2B8) > 8.0f) { + Math_SmoothStepToS(&this->actor.world.rot.x, pitch, 1, BREG(48) + 500, 0); + } else { + Math_SmoothStepToS(&this->actor.world.rot.x, 0, 1, BREG(52) + 500, 0); + } + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 30.0f, 20.0f, 0x1D); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + + if (this->unk_206 != 7) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->unk_204 != 0) { + Vec3f sp40; + + Math_Vec3f_Copy(&sp40, &this->unk_2D4); + this->unk_204 = 0; + sp40.x += randPlusMinusPoint5Scaled(20.0f); + sp40.y += randPlusMinusPoint5Scaled(5.0f); + sp40.z += randPlusMinusPoint5Scaled(20.0f); + + for (i = 0; i < (s32)Rand_ZeroFloat(5.0f) + 5; i++) { + EffectSsBubble_Spawn(globalCtx, &sp40, 0.0f, 5.0f, 5.0f, Rand_ZeroFloat(0.03f) + 0.07f); + } + } + } +} + +s32 EnPr_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnPr* this = THIS; + + if (limbIndex == 2) { + rot->y += this->unk_214; + } + return false; +} + +void EnPr_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Vec3f sp24 = { 0.0f, 0.0f, 0.0f }; + EnPr* this = THIS; + + if (limbIndex == 2) { + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_MultVec3f(&sp24, &this->unk_2D4); + } + + if ((limbIndex == 0) || (limbIndex == 1) || (limbIndex == 2) || (limbIndex == 3) || (limbIndex == 4) || + (limbIndex == 5) || (limbIndex == 6) || (limbIndex == 7) || (limbIndex == 8) || (limbIndex == 9)) { + Matrix_MultZero(&this->limbPos[this->unk_228]); + this->unk_228++; + if (this->unk_228 >= ARRAY_COUNT(this->limbPos)) { + this->unk_228 = 0; + } + } +} + +void EnPr_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnPr* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + if (this->unk_2D2 == 0) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_208, this->unk_208, this->unk_208, this->unk_2D0); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_2D0); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnPr_OverrideLimbDraw, EnPr_PostLimbDraw, &this->actor); + } else { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_2D0); + + Scene_SetRenderModeXlu(globalCtx, 1, 2); + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, &this->actor, POLY_XLU_DISP); + } + + if (this->drawDmgEffAlpha != 0) { + f32 drawDmgEffAlpha = this->drawDmgEffAlpha * 0.05f; + + this->unk_238 = 0.8f; + this->unk_234 = 0.8f; + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 0.8f, 0.8f, + drawDmgEffAlpha, this->drawDmgEffType); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Pr/z_en_pr.h b/src/overlays/actors/ovl_En_Pr/z_en_pr.h index fb2a1c8a2..18123e119 100644 --- a/src/overlays/actors/ovl_En_Pr/z_en_pr.h +++ b/src/overlays/actors/ovl_En_Pr/z_en_pr.h @@ -7,11 +7,51 @@ struct EnPr; typedef void (*EnPrActionFunc)(struct EnPr*, GlobalContext*); +#define ENPR_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +#define ENPR_FF00_MAX 20 +#define ENPR_FF00_MIN 0 + typedef struct EnPr { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xBC]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[10]; + /* 0x01C4 */ Vec3s morphTable[10]; /* 0x0200 */ EnPrActionFunc actionFunc; - /* 0x0204 */ char unk_204[0x144]; + /* 0x0204 */ u8 unk_204; + /* 0x0206 */ s16 unk_206; + /* 0x0208 */ s16 unk_208; + /* 0x020A */ s16 unk_20A; + /* 0x020C */ s16 unk_20C; + /* 0x020E */ s16 unk_20E; + /* 0x0210 */ s16 unk_210; + /* 0x0212 */ s16 unk_212; + /* 0x0214 */ s16 unk_214; + /* 0x0216 */ s16 unk_216; + /* 0x0218 */ UNK_TYPE1 unk218[4]; + /* 0x021C */ s32 unk_21C; + /* 0x0220 */ UNK_TYPE1 unk220[0x8]; + /* 0x0228 */ s32 unk_228; + /* 0x022C */ s16 unk_22C; + /* 0x022E */ s16 drawDmgEffAlpha; + /* 0x0230 */ s16 drawDmgEffType; + /* 0x0234 */ f32 unk_234; + /* 0x0238 */ f32 unk_238; + /* 0x023C */ Vec3f limbPos[10]; + /* 0x02B4 */ f32 unk_2B4; + /* 0x02B8 */ f32 unk_2B8; + /* 0x02BC */ f32 unk_2BC; + /* 0x02C0 */ f32 unk_2C0; + /* 0x02C4 */ f32 unk_2C4; + /* 0x02C8 */ f32 unk_2C8; + /* 0x02CC */ f32 unk_2CC; + /* 0x02D0 */ s16 unk_2D0; + /* 0x02D2 */ s16 unk_2D2; + /* 0x02D4 */ Vec3f unk_2D4; + /* 0x02E0 */ Vec3f unk_2E0; + /* 0x02EC */ UNK_TYPE1 unk2EC[0xC]; + /* 0x02F8 */ Actor* unk_2F8; + /* 0x02FC */ ColliderCylinder collider; } EnPr; // size = 0x348 extern const ActorInit En_Pr_InitVars; diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c index b2d70518d..797433892 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.c @@ -1,6 +1,14 @@ -#include "z_en_pr2.h" +/* + * File: z_en_pr2.c + * Overlay: ovl_En_Pr2 + * Description: Skullfish + */ -#define FLAGS 0x00000015 +#include "z_en_pr2.h" +#include "objects/object_pr/object_pr.h" +#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnPr2*)thisx) @@ -9,9 +17,16 @@ void EnPr2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPr2_Update(Actor* thisx, GlobalContext* globalCtx); void EnPr2_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_80A75BC0 = { +void func_80A745C4(EnPr2* this); +void func_80A745FC(EnPr2* this, GlobalContext* globalCtx); +void func_80A74888(EnPr2* this); +void func_80A748E8(EnPr2* this, GlobalContext* globalCtx); +void func_80A74DEC(EnPr2* this, GlobalContext* globalCtx); +void func_80A74E90(EnPr2* this, GlobalContext* globalCtx); +void func_80A751B4(EnPr2* this); +void func_80A75310(EnPr2* this, GlobalContext* globalCtx); + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -46,10 +61,23 @@ static DamageTable D_80A75BC0 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A75BE0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_1, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x08, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_1, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x08, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 17, 32, -10, { 0, 0, 0 } }, }; @@ -65,48 +93,668 @@ const ActorInit En_Pr2_InitVars = { (ActorFunc)EnPr2_Draw, }; -#endif +static AnimationHeader* sAnimations[] = { + &object_pr_Anim_004340, + &object_pr_Anim_004274, + &object_pr_Anim_003904, +}; -extern DamageTable D_80A75BC0; -extern ColliderCylinderInit D_80A75BE0; +u8 D_80A75C38[] = { 0, 0, 2, 0 }; -extern UNK_TYPE D_06003904; -extern UNK_TYPE D_06004340; +s16 D_80A75C3C[] = { + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Init.s") +void EnPr2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnPr2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Destroy.s") + this->actor.targetMode = 3; + this->actor.hintId = 0x5B; + this->unk_1EC = 255; + this->actor.colChkInfo.health = 1; + this->actor.colChkInfo.damageTable = &sDamageTable; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A7429C.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_pr_Skel_004188, &object_pr_Anim_004340, this->jointTable, + this->morphtable, 5); + this->unk_1E0 = ENPR2_GET_F(&this->actor); + this->actor.colChkInfo.mass = 10; + Math_Vec3f_Copy(&this->unk_228, &this->actor.home.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A7436C.s") + if (this->unk_1E0 == 2) { + this->unk_208 = ENPR2_GET_FF0(&this->actor) * 20.0f; + } + this->unk_1F4 = 255; + this->actor.shape.yOffset = 500.0f; + this->actor.shape.shadowScale = 12.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74510.s") + if (this->unk_1E0 < 10) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 19.0f); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_218 = -1; + this->unk_204 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A745C4.s") + if (this->actor.parent != NULL) { + Actor* parent = this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A745FC.s") + if (parent->update != NULL) { + if (parent->world.rot.y != 0) { + this->unk_218 = parent->world.rot.y - 1; + } + } + } else if (this->actor.world.rot.z != 0) { + this->unk_218 = this->actor.world.rot.z - 1; + this->actor.world.rot.z = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74888.s") + if (this->unk_1E0 == 3) { + if (this->actor.parent != NULL) { + Actor* parent = this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A748E8.s") + if (parent->update != NULL) { + this->unk_1C8 = ((EnEncount1*)parent)->unk_15A; + this->path = SubS_GetPathByIndex(globalCtx, this->unk_1C8, 0x3F); + this->unk_208 = parent->world.rot.z * 20.0f; + if (this->unk_208 < 20.0f) { + this->unk_208 = 20.0f; + } + } + func_80A745C4(this); + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } else { + func_80A74888(this); + } + } else { + this->unk_204 = 0.02f; + func_80A751B4(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74DEC.s") + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 20.0f, 20.0f, 0x1D); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A74E90.s") + if (!(this->actor.bgCheckFlags & 0x60)) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A751B4.s") +void EnPr2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnPr2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A75310.s") + if (this->unk_1E0 < 10) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A755D8.s") + if (this->actor.parent != NULL) { + EnEncount1* encount1 = (EnEncount1*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Update.s") + if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) { + encount1->unk_14E--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A758E8.s") +s32 func_80A7429C(EnPr2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp1A; + s16 sp18; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A75950.s") + Actor_GetScreenPos(globalCtx, &this->actor, &sp1A, &sp18); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/func_80A759D8.s") + if ((fabsf(player->actor.world.pos.y - this->actor.world.pos.y) > 160.0f) || + (this->actor.projectedPos.z < -40.0f) || (sp1A < 0) || (sp1A > 320) || (sp18 < 0) || (sp18 > 240)) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Pr2/EnPr2_Draw.s") + if (!(player->stateFlags1 & 0x8000000)) { + return false; + } else { + return true; + } +} + +void func_80A7436C(EnPr2* this, s16 arg1) { + s16 sp2E = arg1 - this->actor.world.rot.y; + + if (sp2E > 10000) { + sp2E = 10000; + } else if (sp2E < -10000) { + sp2E = -10000; + } + + Math_ApproachF(&this->actor.world.pos.y, this->unk_21C.y, 0.3f, 5.0f); + + if (fabsf(this->actor.world.pos.y - this->unk_21C.y) > 10.0f) { + Math_SmoothStepToS(&this->actor.world.rot.x, Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_21C) * 0.3f, + 20, 5000, 500); + } else { + Math_SmoothStepToS(&this->actor.world.rot.x, 0, 20, 5000, 500); + } + + if (fabsf(this->actor.world.rot.y - arg1) < 30.0f) { + Math_ApproachZeroF(&this->unk_1FC, 0.5f, 20.0f); + } else { + Math_ApproachF(&this->unk_1FC, sp2E, 0.5f, 3000.0f); + } + + Math_SmoothStepToS(&this->actor.world.rot.y, arg1, 1, 2000, 300); +} + +void func_80A74510(EnPr2* this, s32 arg0) { + f32 sp34 = 1.0f; + + this->unk_210 = arg0; + this->unk_1F8 = Animation_GetLastFrame(sAnimations[arg0]); + if (this->unk_210 == 3) { + sp34 = 0.0f; + } + Animation_Change(&this->skelAnime, sAnimations[arg0], sp34, 0.0f, this->unk_1F8, D_80A75C38[arg0], 0.0f); +} + +void func_80A745C4(EnPr2* this) { + func_80A74510(this, 0); + this->unk_1D4 = 0; + this->actionFunc = func_80A745FC; +} + +void func_80A745FC(EnPr2* this, GlobalContext* globalCtx) { + f32 x; + f32 y; + f32 z; + f32 sqrtXYZ; + + if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f) { + SkelAnime_Update(&this->skelAnime); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_EXIST - SFX_FLAG); + Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f); + + if (this->path->unk2 < this->unk_1D0) { + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 1.0f); + } else { + Math_ApproachF(&this->actor.speedXZ, 10.0f, 0.3f, 1.0f); + } + + if ((this->path != NULL) && !SubS_CopyPointFromPath(this->path, this->unk_1D0, &this->unk_21C)) { + Actor_MarkForDeath(&this->actor); + } + + Math_ApproachF(&this->actor.world.pos.y, this->unk_21C.y, 0.3f, 5.0f); + + if (fabsf(this->actor.world.pos.y - this->unk_21C.y) > 10.0f) { + Math_SmoothStepToS(&this->actor.world.rot.x, Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_21C) * 0.3f, + 20, 5000, 500); + } else { + Math_SmoothStepToS(&this->actor.world.rot.x, 0, 20, 5000, 500); + } + + x = this->actor.world.pos.x - this->unk_21C.x; + y = this->actor.world.pos.y - this->unk_21C.y; + z = this->actor.world.pos.z - this->unk_21C.z; + sqrtXYZ = sqrtf(SQ(x) + SQ(y) + SQ(z)); + + if (sqrtXYZ < (Rand_ZeroFloat(20.0f) + 15.0f)) { + this->unk_1D0++; + Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos); + if (this->unk_1D0 >= this->path->count) { + this->unk_1E0 = 2; + func_80A74888(this); + } + } + + this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C); + func_80A7436C(this, this->unk_1EE); +} + +void func_80A74888(EnPr2* this) { + func_80A74510(this, 0); + this->unk_1DA = 2; + this->unk_1D8 = 0; + Math_Vec3f_Copy(&this->unk_21C, &this->unk_228); + this->unk_1D4 = 1; + this->actionFunc = func_80A748E8; +} + +void func_80A748E8(EnPr2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 temp_f12; + f32 temp_f2; + f32 sqrtXZ; + s32 sp4C = false; + s32 sp48 = false; + Vec3f sp3C; + + Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_EXIST - SFX_FLAG); + + if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f) { + sp48 = true; + SkelAnime_Update(&this->skelAnime); + } + + if (this->unk_1F4 != 255) { + this->actor.speedXZ = 0.0f; + Math_SmoothStepToS(&this->unk_1F4, 0, 1, 30, 100); + if (this->unk_1F4 < 2) { + Actor_MarkForDeath(&this->actor); + } + } else { + switch (this->unk_1E0) { + case 1: + if (this->unk_1DC == 0) { + sp4C = true; + func_80A74DEC(this, globalCtx); + } else if (!func_80A7429C(this, globalCtx) && (this->unk_1F4 == 255)) { + this->unk_1F4 = 254; + } + break; + + case 2: + if (this->unk_1DE == 0) { + temp_f2 = player->actor.world.pos.x - this->unk_228.x; + temp_f12 = player->actor.world.pos.z - this->unk_228.z; + sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12)); + + if (sp48 && (player->stateFlags1 & 0x8000000) && (sqrtXZ < this->unk_208)) { + sp4C = true; + func_80A74DEC(this, globalCtx); + } + } else { + temp_f2 = this->actor.world.pos.x - this->unk_228.x; + temp_f12 = this->actor.world.pos.z - this->unk_228.z; + sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12)); + + if (sqrtXZ > 20.0f) { + this->unk_1DE = 5; + sp4C = true; + this->unk_1DC = 0; + Math_Vec3f_Copy(&this->unk_21C, &this->unk_228); + Math_ApproachF(&this->actor.speedXZ, 3.0f, 0.3f, 0.2f); + } + } + break; + } + + if (!sp4C) { + this->unk_21C.y = this->actor.world.pos.y; + if (this->unk_1DA != 0) { + if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) { + this->unk_1D6 = true; + } + + Math_ApproachZeroF(&this->actor.speedXZ, 0.1f, 0.2f); + + if (this->unk_1DA == 1) { + this->unk_1D8 = Rand_S16Offset(100, 100); + Math_Vec3f_Copy(&sp3C, &this->unk_228); + sp3C.x += randPlusMinusPoint5Scaled(300.0f); + sp3C.z += randPlusMinusPoint5Scaled(300.0f); + Math_Vec3f_Copy(&this->unk_21C, &sp3C); + } + } else { + Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.3f, 0.2f); + Math_Vec3f_Copy(&sp3C, &this->actor.world.pos); + sp3C.x += Math_SinS(this->actor.world.rot.y) * 20.0f; + sp3C.z += Math_CosS(this->actor.world.rot.y) * 20.0f; + if (fabsf(this->actor.world.rot.y - this->unk_1EE) < 100.0f) { + if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &sp3C, 20.0f) || (this->actor.bgCheckFlags & 8)) { + this->unk_1DC = 0; + this->unk_1F2++; + Math_Vec3f_Copy(&this->unk_21C, &this->unk_228); + if (this->unk_1F2 > 10) { + this->unk_1F0 += 0x2000; + } + } else { + Math_SmoothStepToS(&this->unk_1F0, 0, 1, 1000, 100); + this->unk_1F2 = 0; + } + } + + if ((this->unk_1D8 == 0) || ((fabsf(this->unk_21C.x - this->actor.world.pos.x) < 10.0f) && + (fabsf(this->unk_21C.z - this->actor.world.pos.z) < 10.0f))) { + this->unk_1DA = Rand_S16Offset(20, 30); + } + } + } + + if (this->unk_1DA == 0) { + this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C) + this->unk_1F0; + func_80A7436C(this, this->unk_1EE); + } + } +} + +void func_80A74DEC(EnPr2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_1F0 = 0; + func_80A74510(this, 1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_ATTACK); + Math_Vec3f_Copy(&this->unk_21C, &player->actor.world.pos); + + this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C); + this->unk_20C = Rand_ZeroFloat(30.0f); + this->unk_1DC = 0; + this->unk_1D8 = 70; + this->unk_1D4 = 2; + this->actionFunc = func_80A74E90; +} + +void func_80A74E90(EnPr2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + WaterBox* sp40; + + Math_ApproachF(&this->unk_204, 0.02f, 0.1f, 0.005f); + if ((this->unk_1D8 == 0) || !(player->stateFlags1 & 0x8000000) || (this->unk_1E0 == 0)) { + func_80A74888(this); + return; + } + + if (this->unk_1F4 != 255) { + this->actor.speedXZ = 0.0f; + Math_SmoothStepToS(&this->unk_1F4, 0, 1, 30, 100); + if (this->unk_1F4 < 2) { + Actor_MarkForDeath(&this->actor); + } + } else { + SkelAnime_Update(&this->skelAnime); + + if ((this->unk_1DC == 0) && (fabsf(this->actor.world.rot.y - this->unk_1EE) < 200.0f)) { + Math_Vec3f_Copy(&this->unk_21C, &player->actor.world.pos); + } + + if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) { + this->unk_1D6 = true; + this->unk_20C = Rand_ZeroFloat(30.0f); + } + + this->unk_21C.y = player->actor.world.pos.y + 30.0f + this->unk_20C; + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.3f, 1.0f); + this->unk_1F0 = 0; + + if (this->unk_1E0 == 2) { + f32 temp_f2 = this->actor.world.pos.x - this->unk_228.x; + f32 temp_f12 = this->actor.world.pos.z - this->unk_228.z; + f32 sqrtXZ = sqrtf(SQ(temp_f2) + SQ(temp_f12)); + + if (this->unk_208 < sqrtXZ) { + this->unk_1DE = 20; + func_80A74888(this); + return; + } + } else { + Math_Vec3f_Copy(&this->unk_228, &this->actor.world.pos); + } + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_200, &sp40)) { + if ((this->unk_200 - 40.0f) < this->unk_21C.y) { + this->unk_21C.y = this->unk_200 - 40.0f; + } + } + + if ((this->unk_1E0 == 1) && !func_80A7429C(this, globalCtx)) { + if (this->unk_1F4 == 255) { + this->unk_1F4 = 254; + } + } else { + if (this->collider.base.atFlags & AT_HIT) { + this->unk_1DC = Rand_S16Offset(30, 30); + this->unk_1D8 = 100; + if (this->unk_1E0 != 2) { + func_80A74888(this); + } + } + this->unk_1EE = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_21C); + func_80A7436C(this, this->unk_1EE); + } + } +} + +void func_80A751B4(EnPr2* this) { + this->unk_1EC = 0; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + if (this->unk_1E0 < 10) { + func_80A74510(this, 2); + } else { + this->unk_1F8 = Animation_GetLastFrame(&object_pr_Anim_003904); + Animation_Change(&this->skelAnime, &object_pr_Anim_003904, 1.0f, this->unk_1F8, this->unk_1F8, 2, 0.0f); + this->unk_1D8 = Rand_S16Offset(20, 30); + this->unk_1E4 = 0x4000; + if (Rand_ZeroOne() < 0.5f) { + this->unk_1E4 = -0x4000; + } + this->unk_1E6 = this->actor.world.rot.y; + this->actor.shape.rot.x = this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + this->unk_1D8 = 30; + this->actor.speedXZ = Rand_ZeroFloat(0.5f); + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x8000); + } + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 10); + this->unk_1D4 = 3; + this->actionFunc = func_80A75310; +} + +void func_80A75310(EnPr2* this, GlobalContext* globalCtx) { + s32 temp; + f32 frame; + WaterBox* sp74; + + SkelAnime_Update(&this->skelAnime); + if (this->unk_1E0 < 10) { + s32 i; + + frame = this->skelAnime.curFrame; + + if (this->unk_1F8 <= frame) { + for (i = 0; i < ARRAY_COUNT(this->unk_234); i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_PR2, this->unk_234[i].x, this->unk_234[i].y, + this->unk_234[i].z, this->actor.world.rot.x, this->actor.world.rot.y, + this->actor.world.rot.z, i + 10); + } + + Actor_MarkForDeath(&this->actor); + return; + } + } else { + Vec3f sp64; + + temp = false; + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 5, 10000, 1000); + Math_SmoothStepToS(&this->actor.shape.rot.z, this->unk_1E4, 5, 10000, 1000); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_1E6, 5, 10000, 1000); + + if ((Rand_ZeroOne() < 0.3f) && !this->unk_1D6) { + this->unk_1D6 = true; + } + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_200, &sp74)) { + frame = this->unk_200 - 15.0f; + + if (frame <= this->actor.world.pos.y) { + temp = true; + } else { + Math_ApproachF(&this->actor.world.pos.y, frame, 0.3f, 1.0f); + } + } + + if ((this->unk_1D8 == 0) || temp) { + s32 i; + + Math_SmoothStepToS(&this->unk_1F4, 0, 1, 15, 50); + + if (this->unk_1F4 < 2) { + for (i = 0; i < 10; i++) { + Math_Vec3f_Copy(&sp64, &this->actor.world.pos); + + sp64.x += randPlusMinusPoint5Scaled(20.0f); + sp64.y += randPlusMinusPoint5Scaled(5.0f); + sp64.z += randPlusMinusPoint5Scaled(20.0f); + frame = Rand_ZeroFloat(0.03f) + 0.07f; + + EffectSsBubble_Spawn(globalCtx, &sp64, 0.0f, 5.0f, 5.0f, frame); + } + + Actor_MarkForDeath(&this->actor); + } + } + } +} + +void func_80A755D8(EnPr2* this, GlobalContext* globalCtx) { + s32 temp_v0; + + if (this->collider.base.acFlags & AC_HIT) { + Actor_ApplyDamage(&this->actor); + if ((this->actor.colChkInfo.health <= 0) && (this->unk_1D4 != 3)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_DEAD); + + if (this->unk_218 >= 0) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, D_80A75C3C[this->unk_218]); + } + + this->actor.colChkInfo.health = 0; + func_80A751B4(this); + } + } + + if (this->collider.base.atFlags & AT_BOUNCED) { + this->actor.speedXZ = -10.0f; + } +} + +void EnPr2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnPr2* this = THIS; + f32 rand; + + if (thisx) {} + + Actor_SetScale(&this->actor, this->unk_204); + + this->actionFunc(this, globalCtx); + + if (this->unk_1DA != 0) { + this->unk_1DA--; + } + + if (this->unk_1D8 != 0) { + this->unk_1D8--; + } + + if (this->unk_1DC != 0) { + this->unk_1DC--; + } + + if (this->unk_1DE != 0) { + this->unk_1DE--; + } + + Actor_SetFocus(&this->actor, 10.0f); + func_80A755D8(this, globalCtx); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0, 10.0f, 20.0f, 0x1F); + + if (this->unk_1D6) { + s32 i; + Vec3f sp58; + f32 rand; + + Math_Vec3f_Copy(&sp58, &this->unk_270); + this->unk_1D6 = false; + + sp58.x += randPlusMinusPoint5Scaled(20.0f); + sp58.y += randPlusMinusPoint5Scaled(5.0f); + sp58.z += randPlusMinusPoint5Scaled(20.0f); + + for (i = 0; i < 2; i++) { + rand = Rand_ZeroFloat(0.03f) + 0.07f; + EffectSsBubble_Spawn(globalCtx, &sp58, 0, 5.0f, 5.0f, rand); + } + } + + if ((this->unk_1F4 == 255) && (this->unk_1E0 < 10)) { + this->actor.shape.rot.x = this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + if (this->unk_1D4 != 3) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +s32 func_80A758E8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnPr2* this = THIS; + + if (this->unk_1E0 < 10) { + if (limbIndex == 2) { + rot->y += (s16)this->unk_1FC * -1; + } + } else if ((limbIndex + 10) != this->unk_1E0) { + *dList = NULL; + } + return false; +} + +void func_80A75950(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnPr2* this = THIS; + + if (this->unk_1E0 < 10) { + if (limbIndex == 2) { + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_MultZero(&this->unk_270); + } + Matrix_MultZero(&this->unk_234[limbIndex]); + } +} + +s32 func_80A759D8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnPr2* this = THIS; + + if (this->unk_1E0 < 10) { + if (limbIndex == 2) { + rot->y += (s16)this->unk_1FC * -1; + } + } else if ((limbIndex + 10) != this->unk_1E0) { + *dList = NULL; + } + return false; +} + +void EnPr2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnPr2* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_1F4 == 255) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1EC, this->unk_1EC, this->unk_1EC, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_1F4); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, func_80A758E8, func_80A75950, &this->actor); + } else { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1F4); + + Scene_SetRenderModeXlu(globalCtx, 1, 2); + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, func_80A759D8, NULL, &this->actor, POLY_XLU_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h index 68fb09b82..4ae14db77 100644 --- a/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h +++ b/src/overlays/actors/ovl_En_Pr2/z_en_pr2.h @@ -7,11 +7,48 @@ struct EnPr2; typedef void (*EnPr2ActionFunc)(struct EnPr2*, GlobalContext*); +#define ENPR2_GET_F(thisx) ((thisx)->params & 0xF) +#define ENPR2_GET_FF0(thisx) (((thisx)->params >> 4) & 0xFF) + typedef struct EnPr2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x80]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[5]; + /* 0x01A6 */ Vec3s morphtable[5]; /* 0x01C4 */ EnPr2ActionFunc actionFunc; - /* 0x01C8 */ char unk_1C8[0x100]; + /* 0x01C8 */ s16 unk_1C8; + /* 0x01CC */ Path* path; + /* 0x01D0 */ s32 unk_1D0; + /* 0x01D4 */ s16 unk_1D4; + /* 0x01D6 */ s16 unk_1D6; + /* 0x01D8 */ s16 unk_1D8; + /* 0x01DA */ s16 unk_1DA; + /* 0x01DC */ s16 unk_1DC; + /* 0x01DE */ s16 unk_1DE; + /* 0x01E0 */ s16 unk_1E0; + /* 0x01E2 */ UNK_TYPE1 unk1E2[2]; + /* 0x01E4 */ s16 unk_1E4; + /* 0x01E6 */ s16 unk_1E6; + /* 0x01E8 */ UNK_TYPE1 unk1E8[4]; + /* 0x01EC */ s16 unk_1EC; + /* 0x01EE */ s16 unk_1EE; + /* 0x01F0 */ s16 unk_1F0; + /* 0x01F2 */ s16 unk_1F2; + /* 0x01F4 */ s16 unk_1F4; + /* 0x01F8 */ f32 unk_1F8; + /* 0x01FC */ f32 unk_1FC; + /* 0x0200 */ f32 unk_200; + /* 0x0204 */ f32 unk_204; + /* 0x0208 */ f32 unk_208; + /* 0x020C */ f32 unk_20C; + /* 0x0210 */ s32 unk_210; + /* 0x0214 */ UNK_TYPE1 unk214[4]; + /* 0x0218 */ s32 unk_218; + /* 0x021C */ Vec3f unk_21C; + /* 0x0228 */ Vec3f unk_228; + /* 0x0234 */ Vec3f unk_234[5]; + /* 0x0270 */ Vec3f unk_270; + /* 0x027C */ ColliderCylinder collider; } EnPr2; // size = 0x2C8 extern const ActorInit En_Pr2_InitVars; diff --git a/src/overlays/actors/ovl_En_Prz/z_en_prz.c b/src/overlays/actors/ovl_En_Prz/z_en_prz.c index d966b00d1..99cc24158 100644 --- a/src/overlays/actors/ovl_En_Prz/z_en_prz.c +++ b/src/overlays/actors/ovl_En_Prz/z_en_prz.c @@ -1,6 +1,14 @@ -#include "z_en_prz.h" +/* + * File: z_en_prz.c + * Overlay: ovl_En_Prz + * Description: Skullfish - Defeated + */ -#define FLAGS 0x00000015 +#include "z_en_prz.h" +#include "objects/object_pr/object_pr.h" +#include "overlays/actors/ovl_En_Pr/z_en_pr.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnPrz*)thisx) @@ -9,9 +17,15 @@ void EnPrz_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPrz_Update(Actor* thisx, GlobalContext* globalCtx); void EnPrz_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_80A771C0 = { +void func_80A76388(EnPrz* this); +void func_80A763E8(EnPrz* this, GlobalContext* globalCtx); +void func_80A76604(EnPrz* this, GlobalContext* globalCtx); +void func_80A76634(EnPrz* this, GlobalContext* globalCtx); +void func_80A76748(EnPrz* this); +void func_80A767A8(EnPrz* this, GlobalContext* globalCtx); +void func_80A76B14(EnPrz* this, GlobalContext* globalCtx); + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -46,10 +60,25 @@ static DamageTable D_80A771C0 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A771F4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK4, { 0x20000000, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +f32 D_80A771E0[] = { 40.0f, 40.0f, 40.0f, 30.0f, 30.0f }; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK4, + { 0x20000000, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 10, 10, 0, { 0, 0, 0 } }, }; @@ -65,45 +94,434 @@ const ActorInit En_Prz_InitVars = { (ActorFunc)EnPrz_Draw, }; -#endif +AnimationHeader* D_80A77240[] = { &object_pr_Anim_004340, &object_pr_Anim_004274 }; -extern DamageTable D_80A771C0; -extern ColliderCylinderInit D_80A771F4; +u8 D_80A77248[] = { 0, 0 }; -extern UNK_TYPE D_06004340; +Vec3f D_80A7724C = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/EnPrz_Init.s") +void EnPrz_Init(Actor* thisx, GlobalContext* globalCtx) { + EnPrz* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/EnPrz_Destroy.s") + this->unk_20C = 0.01f; + this->unk_1E4 = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A75F18.s") + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A75FA4.s") + this->actor.targetMode = 3; + this->unk_1E8 = 255; + this->actor.hintId = 0x5B; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.colChkInfo.health = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76070.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_pr_Skel_004188, &object_pr_Anim_004340, this->jointTable, + this->morphTable, 5); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A762C0.s") + this->unk_1E6 = ENPRZ_GET(&this->actor); + this->actor.shape.yOffset = 500.0f; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76388.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Math_Vec3f_Copy(&this->unk_1D8, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A763E8.s") + this->unk_220 = &this->actor; + this->unk_1EC = 255; + this->unk_202 = randPlusMinusPoint5Scaled((this->unk_1E6 * 100.0f) + 1000.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76604.s") + func_80A76388(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76634.s") +void EnPrz_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76748.s") +void func_80A75F18(EnPrz* this, s32 arg1) { + this->unk_204 = arg1; + Animation_Change(&this->skelAnime, D_80A77240[arg1], 1.0f, 0.0f, Animation_GetLastFrame(D_80A77240[arg1]), + D_80A77248[arg1], -2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A767A8.s") +s32 func_80A75FA4(EnPrz* this, GlobalContext* globalCtx) { + WaterBox* sp2C; + f32 temp_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76A1C.s") + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_210, &sp2C)) { + temp_f0 = BREG(10) + (this->unk_210 - 10.0f); + if (temp_f0 < this->actor.world.pos.y) { + this->unk_1D8.y = temp_f0; + return 1; + } + } else { + temp_f0 = this->actor.floorHeight + 35.0f; + if (this->actor.world.pos.y < temp_f0) { + this->unk_1D8.y = temp_f0; + return 2; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76B14.s") + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/EnPrz_Update.s") +void func_80A76070(EnPrz* this, s16 arg1, GlobalContext* globalCtx) { + s16 temp_s0 = arg1 - this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76F70.s") + temp_s0 *= 0.01f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/func_80A76FCC.s") + if (temp_s0 > 100) { + temp_s0 = 100; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Prz/EnPrz_Draw.s") + if (temp_s0 < -100) { + temp_s0 = -100; + } + + if (fabsf(this->actor.world.rot.y - (f32)arg1) < (randPlusMinusPoint5Scaled(20.0f) + 100.0f)) { + Math_ApproachZeroF(&this->unk_218, 0.5f, 20.0f); + } else { + Math_ApproachF(&this->unk_218, temp_s0, 0.5f, 5.0f); + } + + temp_s0 = fabsf(this->unk_218) * 0.1f; + if (temp_s0 < 2) { + temp_s0 = 2; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, arg1, temp_s0, this->unk_202 + 0x1388, 0); + func_80A75FA4(this, globalCtx); + Math_ApproachF(&this->actor.world.pos.y, this->unk_1D8.y, 0.5f, 1.0f); + temp_s0 = Math_Vec3f_Pitch(&this->actor.world.pos, &this->unk_1D8) * 0.5f; + + if (fabsf(this->actor.world.pos.y - this->unk_208) > 4.0f) { + Math_SmoothStepToS(&this->actor.world.rot.x, temp_s0, 1, BREG(48) + 0x1F4, 0); + } else { + Math_SmoothStepToS(&this->actor.world.rot.x, 0, 1, BREG(52) + 0xBB8, 0); + } +} + +s32 func_80A762C0(EnPrz* this, GlobalContext* globalCtx) { + CollisionPoly* sp54; + Vec3f sp48; + s32 sp44; + Vec3f sp38; + + Math_Vec3f_Copy(&sp38, &this->actor.world.pos); + + sp38.x += Math_SinS(this->actor.world.rot.y) * 40.0f; + sp38.z += Math_CosS(this->actor.world.rot.y) * 40.0f; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp38, &sp48, &sp54, true, false, false, + true, &sp44)) { + return true; + } + return false; +} + +void func_80A76388(EnPrz* this) { + this->actor.speedXZ = randPlusMinusPoint5Scaled(1.0f) + 4.0f; + func_80A75F18(this, 0); + this->unk_1EA = 1; + this->actionFunc = func_80A763E8; +} + +void func_80A763E8(EnPrz* this, GlobalContext* globalCtx) { + Actor* sp3C = this->actor.parent; + Player* player = GET_PLAYER(globalCtx); + s16 yaw; + s32 pad; + + if (&this->actor == this->unk_220) { + return; + } + + if ((player->stateFlags1 & 0x8000000) && (this->unk_1F2 == 0)) { + func_80A76748(this); + return; + } + + if (func_80A762C0(this, globalCtx)) { + func_80A76604(this, globalCtx); + return; + } + + if ((this->unk_220 != NULL) && (this->unk_220->update == NULL)) { + this->unk_220 = this->actor.parent; + } + + if ((this->unk_1EE == 0) && (this->unk_1F2 == 0)) { + s16 rot; + + this->unk_214 = randPlusMinusPoint5Scaled(40.0f); + + rot = BINANG_ROT180(this->unk_220->world.rot.y); + this->unk_1D8.x += Math_SinS(rot) * this->unk_214; + this->unk_1D8.y = randPlusMinusPoint5Scaled(40.0f) + (this->unk_220->world.pos.y + 40.0f); + rot = BINANG_ROT180(this->unk_220->world.rot.y); + this->unk_1D8.z += Math_CosS(rot) * this->unk_214; + + this->unk_1EE = Rand_S16Offset(20, 30); + } else if (sqrtf(SQ(this->actor.world.pos.x - sp3C->world.pos.x) + + SQ(this->actor.world.pos.z - sp3C->world.pos.z)) > 100.0f) { + Math_Vec3f_Copy(&this->unk_1D8, &sp3C->world.pos); + } + + if (1) {} + + if ((Rand_ZeroOne() < 0.1f) && (this->unk_1C8 == 0)) { + this->unk_1C8 = 1; + } + + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_1D8); + func_80A76070(this, yaw, globalCtx); +} + +void func_80A76604(EnPrz* this, GlobalContext* globalCtx) { + this->unk_1EE = 0; + this->unk_1E4 = BINANG_ADD(this->actor.world.rot.y, 0x4000); + this->unk_1EA = 2; + this->actionFunc = func_80A76634; +} + +void func_80A76634(EnPrz* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_80A76070(this, this->unk_1E4, globalCtx); + + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->unk_1E4)) < 0x100) { + if (func_80A762C0(this, globalCtx) != 0) { + this->unk_1E4 += 0x1500; + this->unk_1E4 += (s16)Rand_ZeroFloat(5000.0f); + } else if ((player->stateFlags1 & 0x8000000) && (player->actor.floorHeight < 30.0f)) { + this->actionFunc = func_80A763E8; + } else { + this->unk_1EE = 10; + this->unk_1EA = 1; + this->actionFunc = func_80A763E8; + } + } +} + +void func_80A76748(EnPrz* this) { + this->actor.speedXZ = randPlusMinusPoint5Scaled(1.0f) + 3.0f; + this->unk_1EE = 0; + this->unk_1EA = 3; + this->skelAnime.playSpeed = 2.0f; + this->actionFunc = func_80A767A8; +} + +void func_80A767A8(EnPrz* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnPr* pr = (EnPr*)this->actor.parent; + f32 distXZ; + s32 pad[2]; + + if (func_80A762C0(this, globalCtx)) { + func_80A75F18(this, 0); + this->actor.speedXZ = randPlusMinusPoint5Scaled(1.0f) + 4.0f; + func_80A76604(this, globalCtx); + return; + } + + distXZ = sqrtf(SQ(player->actor.world.pos.x - this->actor.parent->home.pos.x) + + SQ(player->actor.world.pos.z - this->actor.parent->home.pos.z)); + + if (!(player->stateFlags1 & 0x8000000) || (pr->unk_2C8 < distXZ)) { + this->unk_1F2 = 100; + this->skelAnime.playSpeed = 1.0f; + func_80A76388(this); + return; + } + + if ((this->actor.xzDistToPlayer < 200.0f) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 80.0f)) { + if (this->unk_204 != 1) { + func_80A75F18(this, 1); + } + this->skelAnime.playSpeed = 1.0f; + } else { + if (this->unk_204 != 0) { + func_80A75F18(this, 0); + } + this->skelAnime.playSpeed = 2.0f; + } + + if (this->unk_1EE == 0) { + this->unk_1EE = Rand_S16Offset(2, 3); + Math_Vec3f_Copy(&this->unk_1D8, &player->actor.world.pos); + } + + if ((Rand_ZeroOne() < 0.1f) && (this->unk_1C8 == 0)) { + this->unk_1C8 = 1; + } + + this->unk_1D8.y = (player->actor.world.pos.y + D_80A771E0[((void)0, gSaveContext.save.playerForm)]) + + randPlusMinusPoint5Scaled((2.0f * this->unk_1E6) + 1.0f); + func_80A76070(this, Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_1D8), globalCtx); +} + +void func_80A76A1C(EnPrz* this) { + this->unk_1E8 = 0; + this->actor.flags |= ACTOR_FLAG_8000000; + this->actor.flags &= ~ACTOR_FLAG_1; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BUBLEWALK_DEAD); + + this->unk_1EE = Rand_S16Offset(100, 30); + this->unk_1FC = 0x4000; + + if (Rand_ZeroOne() < 0.5f) { + this->unk_1FC = -0x4000; + } + + this->unk_1FE = this->actor.world.rot.y; + this->actor.speedXZ = Rand_ZeroFloat(0.5f); + this->actor.world.rot.y = randPlusMinusPoint5Scaled(0x8000); + + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 30); + this->unk_1EE = 50; + func_80A75F18(this, 0); + this->unk_1EA = 7; + this->actionFunc = func_80A76B14; +} + +void func_80A76B14(EnPrz* this, GlobalContext* globalCtx) { + WaterBox* sp7C; + s32 i; + Vec3f sp6C; + s32 phi_s0 = false; + + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 5, 0x2710, 0x3E8); + Math_SmoothStepToS(&this->actor.shape.rot.z, this->unk_1FC, 5, 0x2710, 0x3E8); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_1FE, 5, 0x2710, 0x3E8); + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &this->unk_210, &sp7C)) { + if ((this->unk_210 - 15.0f) <= this->actor.world.pos.y) { + phi_s0 = true; + } else { + Math_ApproachF(&this->actor.world.pos.y, this->unk_210 - 14.0f, 0.3f, 1.0f); + } + } + + if ((this->unk_1EE == 0) || phi_s0) { + Math_SmoothStepToS(&this->unk_1EC, 0, 1, 15, 50); + + if (this->unk_1EC < 2) { + for (i = 0; i < 10; i++) { + Math_Vec3f_Copy(&sp6C, &this->actor.world.pos); + + sp6C.x += randPlusMinusPoint5Scaled(20.0f); + sp6C.y += randPlusMinusPoint5Scaled(5.0f); + sp6C.z += randPlusMinusPoint5Scaled(20.0f); + + EffectSsBubble_Spawn(globalCtx, &sp6C, 0.0f, 5.0f, 5.0f, Rand_ZeroFloat(0.03f) + 0.07f); + } + Actor_MarkForDeath(&this->actor); + } + } +} + +void EnPrz_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnPrz* this = THIS; + s32 sp44 = false; + Vec3f sp38; + + if (this->unk_1EA != 7) { + SkelAnime_Update(&this->skelAnime); + } + + this->actionFunc(this, globalCtx); + + if (this->unk_1EE != 0) { + this->unk_1EE--; + } + + if (this->unk_1F2 != 0) { + this->unk_1F2--; + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 10.0f, 10.0f, 0x1D); + + if (this->unk_1EA != 7) { + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + } + + if (this->unk_1EA != 7) { + if (this->collider.base.acFlags & AC_HIT) { + Actor_ApplyDamage(&this->actor); + if (this->actor.colChkInfo.health <= 0) { + sp44 = true; + } + } + + if (sp44 || (this->actor.parent == NULL) || (this->actor.parent->colChkInfo.health <= 0)) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_1EA != 7) { + func_80A76A1C(this); + return; + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->unk_1C8 != 0) { + Math_Vec3f_Copy(&sp38, &this->unk_1CC); + this->unk_1C8 = 0; + + sp38.x += randPlusMinusPoint5Scaled(20.0f); + sp38.y += randPlusMinusPoint5Scaled(5.0f); + sp38.z += randPlusMinusPoint5Scaled(20.0f); + + EffectSsBubble_Spawn(globalCtx, &sp38, 0.0f, 5.0f, 5.0f, Rand_ZeroFloat(0.03f) + 0.07f); + } + } +} + +s32 func_80A76F70(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnPrz* this = THIS; + + if (limbIndex == 2) { + rot->y += (s16)this->unk_218 * -100; + } + return false; +} + +void func_80A76FCC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + Vec3f sp1C = D_80A7724C; + EnPrz* this = THIS; + + if (limbIndex == 2) { + Matrix_Translate(0.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_MultVec3f(&sp1C, &this->unk_1CC); + } +} + +void EnPrz_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnPrz* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_1EC == 255) { + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1E8, this->unk_1E8, this->unk_1E8, this->unk_1EC); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_1EC); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, func_80A76F70, func_80A76FCC, &this->actor); + } else { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1EC); + + Scene_SetRenderModeXlu(globalCtx, 1, 2); + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, &this->actor, POLY_XLU_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Prz/z_en_prz.h b/src/overlays/actors/ovl_En_Prz/z_en_prz.h index 396ed84aa..28f8152a8 100644 --- a/src/overlays/actors/ovl_En_Prz/z_en_prz.h +++ b/src/overlays/actors/ovl_En_Prz/z_en_prz.h @@ -7,11 +7,39 @@ struct EnPrz; typedef void (*EnPrzActionFunc)(struct EnPrz*, GlobalContext*); +#define ENPRZ_GET(thisx) ((thisx)->params & 0xFF) + typedef struct EnPrz { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x80]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[5]; + /* 0x01A6 */ Vec3s morphTable[5]; /* 0x01C4 */ EnPrzActionFunc actionFunc; - /* 0x01C8 */ char unk_1C8[0xA8]; + /* 0x01C8 */ u8 unk_1C8; + /* 0x01CC */ Vec3f unk_1CC; + /* 0x01D8 */ Vec3f unk_1D8; + /* 0x01E4 */ s16 unk_1E4; + /* 0x01E6 */ s16 unk_1E6; + /* 0x01E8 */ s16 unk_1E8; + /* 0x01EA */ s16 unk_1EA; + /* 0x01EC */ s16 unk_1EC; + /* 0x01EE */ s16 unk_1EE; + /* 0x01F0 */ UNK_TYPE1 unk1F0[2]; + /* 0x01F2 */ s16 unk_1F2; + /* 0x01F4 */ UNK_TYPE1 unk1F4[8]; + /* 0x01FC */ s16 unk_1FC; + /* 0x01FE */ s16 unk_1FE; + /* 0x0200 */ UNK_TYPE1 unk200[2]; + /* 0x0202 */ s16 unk_202; + /* 0x0204 */ s32 unk_204; + /* 0x0208 */ f32 unk_208; + /* 0x020C */ f32 unk_20C; + /* 0x0210 */ f32 unk_210; + /* 0x0214 */ f32 unk_214; + /* 0x0218 */ f32 unk_218; + /* 0x021C */ UNK_TYPE1 unk21C[4]; + /* 0x0220 */ Actor* unk_220; + /* 0x0224 */ ColliderCylinder collider; } EnPrz; // size = 0x270 extern const ActorInit En_Prz_InitVars; diff --git a/src/overlays/actors/ovl_En_Pst/z_en_pst.c b/src/overlays/actors/ovl_En_Pst/z_en_pst.c index 30ffa979b..02a9ea743 100644 --- a/src/overlays/actors/ovl_En_Pst/z_en_pst.c +++ b/src/overlays/actors/ovl_En_Pst/z_en_pst.c @@ -1,6 +1,12 @@ +/* + * File: z_en_pst.c + * Overlay: ovl_En_Pst + * Description: Postbox + */ + #include "z_en_pst.h" -#define FLAGS 0x00000001 +#define FLAGS (ACTOR_FLAG_1) #define THIS ((EnPst*)thisx) diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c index 1170827cc..cf6b1d63f 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.c @@ -1,6 +1,17 @@ -#include "z_en_racedog.h" +/* + * File: z_en_racedog.c + * Overlay: ovl_En_Racedog + * Description: The dogs that run around the racetrack during the dog race. + * + * Note that the dogs milling about the Doggy Racetrack prior to and after the + * race are actually En_Dg. This actor is solely concerned with the dogs that + * actually perform the race by running around the track. + */ -#define FLAGS 0x80000010 +#include "z_en_racedog.h" +#include "overlays/actors/ovl_En_Dg/z_en_dg.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnRacedog*)thisx) @@ -9,10 +20,64 @@ void EnRacedog_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRacedog_Update(Actor* thisx, GlobalContext* globalCtx); void EnRacedog_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80B24C14(EnRacedog* this, GlobalContext* globalCtx); -void func_80B24CB4(EnRacedog* this, GlobalContext* globalCtx); +void EnRacedog_RaceStart(EnRacedog* this, GlobalContext* globalCtx); +void EnRacedog_Race(EnRacedog* this, GlobalContext* globalCtx); +void EnRacedog_UpdateTextId(EnRacedog* this); +void EnRacedog_UpdateSpeed(EnRacedog* this); +void EnRacedog_CalculateFinalStretchTargetSpeed(EnRacedog* this); +void EnRacedog_UpdateRaceVariables(EnRacedog* this); +void EnRacedog_CheckForFinish(EnRacedog* this); +void EnRacedog_UpdateRunAnimationPlaySpeed(EnRacedog* this); +s32 EnRacedog_IsOverFinishLine(EnRacedog* this, Vec2f* arg1); +void EnRacedog_SpawnFloorDustRing(EnRacedog* this, GlobalContext* globalCtx); +void EnRacedog_PlayWalkSfx(EnRacedog* this); + +/** + * Dogs can be in three conditions, which is indicated by the message it says when + * you pick it up prior to entering the race. + * If it starts with "Ruff!", it's in good condition. + * If it starts with "Rrr-Ruff!", it's in normal condition. + * If it starts with "Hoo-whine", it's in bad condition. + * These text boxes are grouped up like so: + * - 0x3538 - 0x353D: Good condition + * - 0x353E - 0x3541: Normal condition + * - 0x3542 - 0x3546: Bad condition + */ +#define DOG_IS_IN_GOOD_CONDITION(this) (sDogInfo[this->index].textId < 0x353E) +#define DOG_IS_IN_BAD_CONDITION(this) (sDogInfo[this->index].textId >= 0x3542) + +typedef enum { + /* 0 */ RACEDOG_ANIMATION_IDLE, + /* 1 */ RACEDOG_ANIMATION_WALK_1, + /* 2 */ RACEDOG_ANIMATION_RUN, + /* 3 */ RACEDOG_ANIMATION_BARK, + /* 4 */ RACEDOG_ANIMATION_SIT_DOWN_1, + /* 5 */ RACEDOG_ANIMATION_SIT_DOWN_2, + /* 6 */ RACEDOG_ANIMATION_LYING_DOWN_START_1, + /* 7 */ RACEDOG_ANIMATION_LYING_DOWN_LOOP, + /* 8 */ RACEDOG_ANIMATION_LYING_DOWN_START_2, + /* 9 */ RACEDOG_ANIMATION_LYING_DOWN_START_3, + /* 10 */ RACEDOG_ANIMATION_LYING_DOWN_START_4, + /* 11 */ RACEDOG_ANIMATION_WALK_2, + /* 12 */ RACEDOG_ANIMATION_JUMP, + /* 13 */ RACEDOG_ANIMATION_LONG_JUMP, + /* 14 */ RACEDOG_ANIMATION_JUMP_2, + /* 15 */ RACEDOG_ANIMATION_WALK_3, + /* 16 */ RACEDOG_ANIMATION_MAX +} RacedogAnimationIndex; + +/** + * Stores various information for each dog in the race, mostly related to speed. + */ +typedef struct { + f32 sprintSpeedMultiplier; // Target speed is multiplied by this when the dog is in the last 1/4 of the race + f32 goodConditionSpeedMultiplier; // Target speed is multiplied by this if the dog is in good condition + s16 color; // The dog's color, which is used as an index into sBaseSpeeds + s16 index; // The dog's index within sDogInfo + s16 pointToUseSecondBaseSpeed; // When the dog is at or after this point, the second value in sBaseSpeeds is used + s16 textId; // Used to determine the dog's condition +} RaceDogInfo; -#if 0 const ActorInit En_Racedog_InitVars = { ACTOR_EN_RACEDOG, ACTORCAT_NPC, @@ -25,18 +90,94 @@ const ActorInit En_Racedog_InitVars = { (ActorFunc)EnRacedog_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B25E98 = { - { 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 s16 sNumberOfDogsFinished = 0; + +/** + * The furthest point along the race track path that any dog has reached. + */ +static s16 sFurthestPoint = -1; + +/** + * Starts counting up as soon as the first-place dog gets 3/4ths of the way through the race track, + * and stops counting up as soon as the first-place dog finishes. Used to scale up the sprint + * multiplier in EnRacedog_CalculateFinalStretchTargetSpeed. + */ +static s16 sSprintTimer = 0; + +/** + * The index of the dog currently in first place. It's determined by checking, for each dog on the track, + * if its current point along the race track path is greater than or equal to sFurthestPoint. + */ +static s16 sFirstPlaceIndex = -1; + +/** + * The base speeds for each dog indexed by its color. The two values are used during different parts of the race. + * - At the very start of the race, all dogs will use the first value for their color, but only for a single point + * along the race track's path. After that, they will have a base speed of 5.0, regardless of what's in the table + * for their color. The sole exception to this is the blue dog, who will use its first value for the entire + * first 1/4th of the race. + * - For the last 3/4ths of the race, all dogs will check to see if their current point along the race track path is + * greater than or equal to the pointToUseSecondBaseSpeed for their RaceDogInfo. If it is, then they will use the + * second value for their color as their base speed; otherwise, they will use 5.0. + */ +static f32 sBaseSpeeds[][2] = { + { 0.0f, 0.0f }, { 5.0f, 5.5f }, { 5.0f, 5.0f }, { 5.5f, 5.0f }, { 4.5f, 5.5f }, { 6.0f, 4.0f }, { 4.0f, 6.0f }, +}; + +/** + * A table of RaceDogInfo for every dog in the race. Note that the sprintSpeedMultiplier and + * textId values in this table are updated by functions within this actor. + */ +static RaceDogInfo sDogInfo[] = { + { -1.0f, 1.2f, DOG_COLOR_BEIGE, 0, 9, 0x3539 }, { -1.0f, 1.2f, DOG_COLOR_WHITE, 1, 9, 0x353A }, + { -1.0f, 1.2f, DOG_COLOR_BLUE, 2, 10, 0x353B }, { -1.0f, 1.2f, DOG_COLOR_GRAY, 3, 9, 0x353C }, + { -1.0f, 1.2f, DOG_COLOR_BROWN, 4, 8, 0x353D }, { -1.0f, 1.2f, DOG_COLOR_GRAY, 5, 9, 0x353E }, + { -1.0f, 1.2f, DOG_COLOR_BEIGE, 6, 9, 0x353F }, { -1.0f, 1.2f, DOG_COLOR_WHITE, 7, 9, 0x3540 }, + { -1.0f, 1.2f, DOG_COLOR_WHITE, 8, 9, 0x3541 }, { -1.0f, 1.2f, DOG_COLOR_GOLD, 9, 8, 0x3542 }, + { -1.0f, 1.2f, DOG_COLOR_GRAY, 10, 9, 0x3543 }, { -1.0f, 1.2f, DOG_COLOR_BEIGE, 11, 9, 0x3544 }, + { -1.0f, 1.2f, DOG_COLOR_WHITE, 12, 9, 0x3545 }, { -1.0f, 1.2f, DOG_COLOR_BROWN, 13, 8, 0x3546 }, +}; + +/** + * Stores the RacedogInfo for the dog that is selected by the player. These values are just + * placeholders, and the actual value gets grabbed from sDogInfo in EnRacedog_Init. + */ +static RaceDogInfo sSelectedDogInfo = { -1.0f, 1.0, DOG_COLOR_DEFAULT, -1, 0, 0x353E }; + +/** + * The XZ-coordinates used to determine if the dog is inside the finish line. + * They're a little bit bigger than the in-game visual. + */ +static Vec2f sFinishLineCoordinates[] = { + { -3914.0f, 1283.0f }, + { -3747.0f, 1104.0f }, + { -3717.0f, 1169.0f }, + { -3897.0f, 1308.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, + }, { 13, 19, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B25EC4 = { 0, 0, 0, 0, 1 }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, 1 }; -// static DamageTable sDamageTable = { -static DamageTable D_80B25ED0 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -71,63 +212,588 @@ static DamageTable D_80B25ED0 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B25FF0[] = { +static AnimationInfoS sAnimations[] = { + { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogRunAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, { &gDogBarkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogSitAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -6 }, { &gDogSitAnim, 1.0f, 0, -1, ANIMMODE_LOOP_PARTIAL, -6 }, + { &gDogLyingDownAnim, 1.0f, 0, -1, ANIMMODE_ONCE, -6 }, { &gDogLyingDownLoopAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -6 }, + { &gDogLyingDownAnim, 1.0f, 0, 27, ANIMMODE_ONCE, -6 }, { &gDogLyingDownAnim, 1.0f, 28, -1, ANIMMODE_ONCE, -6 }, + { &gDogLyingDownAnim, 1.0f, 54, 54, ANIMMODE_ONCE, -6 }, { &gDogWalkAnim, -1.5f, -1, 0, ANIMMODE_LOOP, -6 }, + { &gDogJumpAnim, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogLongJumpAnim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, + { &gDogJump2Anim, 1.2f, 0, -1, ANIMMODE_ONCE, 0 }, { &gDogWalkAnim, 0.5f, 0, -1, ANIMMODE_LOOP, 0 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 1000, ICHAIN_STOP), }; -#endif +void EnRacedog_ChangeAnimation(SkelAnime* skelAnime, AnimationInfoS* animationInfo, s32 index) { + f32 frameCount; -extern ColliderCylinderInit D_80B25E98; -extern CollisionCheckInfoInit2 D_80B25EC4; -extern DamageTable D_80B25ED0; -extern InitChainEntry D_80B25FF0[]; + animationInfo += index; + if (animationInfo->frameCount < 0) { + frameCount = Animation_GetLastFrame(animationInfo->animation); + } else { + frameCount = animationInfo->frameCount; + } -extern UNK_TYPE D_06000618; -extern UNK_TYPE D_060080F0; + Animation_Change(skelAnime, animationInfo->animation, animationInfo->playSpeed + (BREG(88) * 0.1f), + animationInfo->startFrame, frameCount, animationInfo->mode, animationInfo->morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B24630.s") +void EnRacedog_UpdateCollision(EnRacedog* 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_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 26.0f, 10.0f, 0.0f, 5); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B246F4.s") +/** + * Returns the Y-rotation the dog should have to move to the next point along the race track path. + * There is a small degree of randomness incorporated into this angle. + */ +s16 EnRacedog_GetYRotation(Path* path, s32 pointIndex, Vec3f* pos, f32* distSQ) { + Vec3s* point; + f32 xDiffRand; + f32 zDiffRand; + f32 xDiff; + f32 zDiff; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B2478C.s") + if (path != NULL) { + point = Lib_SegmentedToVirtual(path->points); + point = &point[pointIndex]; + xDiffRand = (randPlusMinusPoint5Scaled(100.0f) + point->x) - pos->x; + zDiffRand = (randPlusMinusPoint5Scaled(100.0f) + point->z) - pos->z; + xDiff = point->x - pos->x; + zDiff = point->z - pos->z; + } else { + xDiffRand = 0.0f; + zDiffRand = 0.0f; + xDiff = 0.0f; + zDiff = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B248B8.s") + *distSQ = SQ(xDiff) + SQ(zDiff); + return RADF_TO_BINANG(Math_Acot2F(zDiffRand, xDiffRand)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/EnRacedog_Init.s") +void EnRacedog_GetFloorRot(EnRacedog* this, Vec3f* floorRot) { + f32 ny; + f32 nz; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/EnRacedog_Destroy.s") + if (this->actor.floorPoly != NULL) { + ny = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.y); + nz = COLPOLY_GET_NORMAL(this->actor.floorPoly->normal.z); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B24C14.s") + floorRot->x = -Math_Acot2F(1.0f, -nz * ny); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B24CB4.s") +void EnRacedog_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRacedog* this = THIS; + ColliderCylinder* collider = &this->collider; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B24E14.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gDogSkel, NULL, this->jointTable, this->morphTable, DOG_LIMB_MAX); + Collider_InitCylinder(globalCtx, collider); + Collider_SetCylinder(globalCtx, collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B24F08.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->path = SubS_GetPathByIndex(globalCtx, ENRACEDOG_GET_PATH(&this->actor), 0x3F); + Actor_SetScale(&this->actor, 0.0075f); + this->actor.gravity = -3.0f; + if (ENRACEDOG_GET_INDEX(&this->actor) < 14) { + this->index = ENRACEDOG_GET_INDEX(&this->actor); + } else { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B251EC.s") + this->selectionArrowGreenPrimColor = 255; + this->selectionArrowGreenEnvColor = 50; + this->selectionArrowTimer = 12; + this->prevRot.x = 0.0f; + this->prevRot.y = 0.0f; + this->prevRot.z = 0.0f; + this->selectionArrowScale = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B252F8.s") + // The first part of this check is a bit strange. If they intended to check for dogs that were + // in good condition, they should've stopped at 0x353D instead of 0x353E. Additionally, this + // runs before EnRacedog_UpdateTextId is called to set the text IDs to their "correct" values, + // meaning that the IDs are just whatever their default values in sDogInfo are. As a result, + // the blue dog, one beige dog, one white dog, one brown dog, and two gray dogs never bother + // to do the random 1/20 check here, regardless of anything else. + if ((sDogInfo[this->index].textId > 0x353E) && (this->index == (s16)Rand_ZeroFloat(20.0f))) { + this->extraTimeBeforeRaceStart = 5; + } else { + this->extraTimeBeforeRaceStart = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B2538C.s") + this->raceStartTimer = 60; + this->raceStartTimer += this->extraTimeBeforeRaceStart; + this->targetSpeed = sBaseSpeeds[sDogInfo[this->index].color][0]; + this->raceStatus = RACEDOG_RACE_STATUS_BEFORE_POINT_9; + this->pointForCurrentTargetSpeed = -1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B25448.s") + EnRacedog_UpdateTextId(this); + this->actor.flags |= ACTOR_FLAG_10; + this->actor.flags |= ACTOR_FLAG_20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B25490.s") + sSelectedDogInfo = sDogInfo[(s16)((gSaveContext.eventInf[0] & 0xF8) >> 3)]; + this->selectedDogIndex = sSelectedDogInfo.index; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B255AC.s") + EnRacedog_ChangeAnimation(&this->skelAnime, sAnimations, RACEDOG_ANIMATION_IDLE); + sAnimations[RACEDOG_ANIMATION_IDLE].playSpeed = Rand_ZeroFloat(0.5f) + 1.0f; + this->actionFunc = EnRacedog_RaceStart; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B256BC.s") +void EnRacedog_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRacedog* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/EnRacedog_Update.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B2583C.s") +/** + * This function makes the dog wait at the starting line until the race actually begins. + * It's also responsible for playing the starting shot sound once the race begins. + */ +void EnRacedog_RaceStart(EnRacedog* this, GlobalContext* globalCtx) { + if (DECR(this->raceStartTimer) == 0) { + this->raceStartTimer = Rand_S16Offset(50, 50); + if (this->extraTimeBeforeRaceStart == 0) { + play_sound(NA_SE_SY_START_SHOT); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B258D8.s") + EnRacedog_ChangeAnimation(&this->skelAnime, sAnimations, RACEDOG_ANIMATION_RUN); + this->actionFunc = EnRacedog_Race; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B25A74.s") +/** + * This function handles the dog's behavior and state for the entire time the race is going. + */ +void EnRacedog_Race(EnRacedog* this, GlobalContext* globalCtx) { + s16 yRotation; + f32 distSq; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/func_80B25A90.s") + this->collider.dim.radius = 15; + if (this->path != NULL) { + yRotation = EnRacedog_GetYRotation(this->path, this->currentPoint, &this->actor.world.pos, &distSq); + if (this->actor.bgCheckFlags & 8) { + yRotation = this->actor.wallYaw; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Racedog/EnRacedog_Draw.s") + Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (distSq <= SQ(50.0f)) { + this->currentPoint++; + if (this->currentPoint >= (this->path->count - 1)) { + this->currentPoint = 0; + } + } + + EnRacedog_UpdateSpeed(this); + + // Putting this after EnRacedog_UpdateSpeed will ensure that when EnRacedog_CalculateFinalStretchTargetSpeed + // is called for the first-place dog, the sprint timer will be 0, so the first-place dog will be guaranteed + // to have a sprint speed multiplier of 1. + if ((this->currentPoint >= ((this->path->count / 4) * 3)) && (this->index == sFirstPlaceIndex)) { + sSprintTimer++; + } + + EnRacedog_UpdateRaceVariables(this); + EnRacedog_CheckForFinish(this); + Actor_MoveWithGravity(&this->actor); + } + + EnRacedog_UpdateRunAnimationPlaySpeed(this); + EnRacedog_PlayWalkSfx(this); + EnRacedog_SpawnFloorDustRing(this, globalCtx); +} + +/** + * Updates the text ID in sDogInfo based on what was set in the weekEventRegs by + * En_Aob_01. This makes it so sDogInfo can be used in other functions to determine + * the condition of the dog. + */ +void EnRacedog_UpdateTextId(EnRacedog* this) { + if (this->index % 2) { + sDogInfo[this->index].textId = + (((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & (0x10 | 0x20 | 0x40 | 0x80)) >> 4) + 0x3539; + } else { + sDogInfo[this->index].textId = + ((gSaveContext.save.weekEventReg[42 + (this->index / 2)]) & (1 | 2 | 4 | 8)) + 0x3539; + } + + // This makes sure the text ID is something in the range of 0x3539 to 0x3547. + if ((sDogInfo[this->index].textId >= 0x3547) || (sDogInfo[this->index].textId < 0x3539)) { + sDogInfo[this->index].textId = 0x353E; + } + + // Actual valid text IDs for the race dogs range between 0x3538 and 0x3546, so this + // code makes the two ranges match up. Perhaps the text got shifted? + if (sDogInfo[this->index].textId == 0x3547) { + sDogInfo[this->index].textId = 0x3538; + } +} + +/** + * Responsible for calculating the dog's target speed and for making its actual speed + * approach the target speed. + */ +void EnRacedog_UpdateSpeed(EnRacedog* this) { + s32 quarterPathCount; + s32 pathCount = this->path->count; + + // Only update the target speed if the dog is at a further point along the path + // than it was when the target speed was last updated. + if (this->pointForCurrentTargetSpeed < this->currentPoint) { + this->pointForCurrentTargetSpeed = this->currentPoint; + if (this->currentPoint == 0) { + // The dog is at the very start of the race track. + this->targetSpeed = sBaseSpeeds[sDogInfo[this->index].color][0]; + } else { + quarterPathCount = pathCount / 4; + if (this->currentPoint < quarterPathCount) { + // The dog is past the very start, but is still less than 1/4th of the way through the race track. + // This code will give the blue dog a higher base speed than any other dog (6.0 instead of 5.0). + if (sDogInfo[this->index].color == DOG_COLOR_BLUE) { + this->targetSpeed = sBaseSpeeds[sDogInfo[this->index].color][0] + randPlusMinusPoint5Scaled(1.0f); + } else { + this->targetSpeed = 5.0f + randPlusMinusPoint5Scaled(1.0f); + } + + if (DOG_IS_IN_GOOD_CONDITION(this) && (this->index != sFirstPlaceIndex)) { + this->targetSpeed *= sDogInfo[this->index].goodConditionSpeedMultiplier; + } + } else if (this->currentPoint < (quarterPathCount * 3)) { + // The dog is between 1/4th and 3/4ths of the way through the race track. + if (this->currentPoint < sDogInfo[this->index].pointToUseSecondBaseSpeed) { + this->targetSpeed = 5.0f + randPlusMinusPoint5Scaled(1.0f); + } else { + this->targetSpeed = sBaseSpeeds[sDogInfo[this->index].color][1] + randPlusMinusPoint5Scaled(1.0f); + + if (DOG_IS_IN_GOOD_CONDITION(this) && (this->index != sFirstPlaceIndex)) { + this->targetSpeed *= sDogInfo[this->index].goodConditionSpeedMultiplier; + } + } + } else if (this->currentPoint < pathCount) { + // The dog is more than 3/4ths of the way through the race track. + EnRacedog_CalculateFinalStretchTargetSpeed(this); + } else { + this->targetSpeed = randPlusMinusPoint5Scaled(1.0f) + 5.0f; + } + } + } + + // Seemingly the only point of this raceStatus check is to ensure this code still runs when + // the dog has finished the race and is at point 0 along their second lap. + if ((this->currentPoint != 0) || (this->raceStatus != RACEDOG_RACE_STATUS_BEFORE_POINT_9)) { + this->actor.shape.rot.y = this->actor.world.rot.y; + } + + Math_ApproachF(&this->actor.speedXZ, this->targetSpeed, 0.5f, 3.0f); + + // The dog that the player has selected has a slightly higher max speed than the other dogs. + if (this->index == this->selectedDogIndex) { + if (this->actor.speedXZ > 7.5f) { + this->actor.speedXZ = 7.5f; + } + } else { + if (this->actor.speedXZ > 7.0f) { + this->actor.speedXZ = 7.0f; + } + } +} + +/** + * This function handles updating targetSpeed for the final stretch of the race, + * where the dog starts sprinting towards the finish line. + */ +void EnRacedog_CalculateFinalStretchTargetSpeed(EnRacedog* this) { + f32 sprintSpeedMultiplier; + + // Dogs are only allowed to update their sprintSpeedMultiplier once, so its value will + // depend on the value of sSprintTimer when they first hit the 3/4th mark on the track. + if (sDogInfo[this->index].sprintSpeedMultiplier == -1.0f) { + if (sSprintTimer < 100.0f) { + sDogInfo[this->index].sprintSpeedMultiplier = 200.0f / (200.0f - sSprintTimer); + } else { + sDogInfo[this->index].sprintSpeedMultiplier = 2.0f; + } + } + + if (!DOG_IS_IN_BAD_CONDITION(this)) { + sprintSpeedMultiplier = sDogInfo[this->index].sprintSpeedMultiplier; + this->targetSpeed = sprintSpeedMultiplier * sBaseSpeeds[sDogInfo[this->index].color][1]; + } + + if (DOG_IS_IN_GOOD_CONDITION(this) && (this->index != sFirstPlaceIndex)) { + this->targetSpeed *= sDogInfo[this->index].goodConditionSpeedMultiplier; + } +} + +/** + * Responsible for updating the raceStatus variable for this dog, as well as updating the + * sFurthestPoint and sFirstPlaceIndex variables. + */ +void EnRacedog_UpdateRaceVariables(EnRacedog* this) { + if ((this->currentPoint >= 9) && (this->raceStatus == RACEDOG_RACE_STATUS_BEFORE_POINT_9)) { + this->raceStatus = RACEDOG_RACE_STATUS_BETWEEN_POINTS_9_AND_11; + } + + if ((this->currentPoint >= 11) && (this->raceStatus == RACEDOG_RACE_STATUS_BETWEEN_POINTS_9_AND_11)) { + this->raceStatus = RACEDOG_RACE_STATUS_AFTER_POINT_11; + } + + if (((this->currentPoint >= sFurthestPoint) || (this->raceStatus <= RACEDOG_RACE_STATUS_BEFORE_POINT_9)) && + (this->currentPoint > sFurthestPoint)) { + sFurthestPoint = this->currentPoint; + sFirstPlaceIndex = this->index; + } +} + +/** + * Checks to see if this dog has finished the race. This function is responsible for changing the + * music when the first dog finishes the race, and it is also responsible for updating the event + * flags with what position the player's selected dog finished in. + */ +void EnRacedog_CheckForFinish(EnRacedog* this) { + if (EnRacedog_IsOverFinishLine(this, sFinishLineCoordinates) && + this->raceStatus == RACEDOG_RACE_STATUS_AFTER_POINT_11) { + sNumberOfDogsFinished++; + if (sNumberOfDogsFinished == 1) { + Audio_QueueSeqCmd(NA_BGM_HORSE_GOAL | 0x8000); + play_sound(NA_SE_SY_START_SHOT); + } + + this->raceStatus = RACEDOG_RACE_STATUS_FINISHED; + if (this->index == this->selectedDogIndex) { + gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 7) | (sNumberOfDogsFinished * 8); + } + } +} + +/** + * Slows the dog's running speed animation if its speed is less than 3.0, and sets it + * to normal speed otherwise. + */ +void EnRacedog_UpdateRunAnimationPlaySpeed(EnRacedog* this) { + if (this->actor.speedXZ < 3.0f) { + sAnimations[RACEDOG_ANIMATION_RUN].playSpeed = 0.9f; + } else { + sAnimations[RACEDOG_ANIMATION_RUN].playSpeed = 1.0f; + } +} + +/** + * Returns true if the dog's current position is in the finish line. + */ +s32 EnRacedog_IsOverFinishLine(EnRacedog* this, Vec2f* finishLineCoordinates) { + f32 xDistToTopFront; + f32 zDistToTopFront; + f32 xDistToBottomFront; + f32 xDistToBottomBack; + f32 zDistToBottomBack; + f32 zDistToBottomFront; + f32 zDistToTopBack; + f32 xDistToTopBack; + f32 frontPointsCrossProduct; + f32 crossProductTemp; + + xDistToTopFront = this->actor.world.pos.x - finishLineCoordinates[0].x; + zDistToTopFront = this->actor.world.pos.z - finishLineCoordinates[0].z; + xDistToBottomFront = this->actor.world.pos.x - finishLineCoordinates[1].x; + zDistToBottomFront = this->actor.world.pos.z - finishLineCoordinates[1].z; + xDistToBottomBack = this->actor.world.pos.x - finishLineCoordinates[2].x; + zDistToBottomBack = this->actor.world.pos.z - finishLineCoordinates[2].z; + xDistToTopBack = this->actor.world.pos.x - finishLineCoordinates[3].x; + zDistToTopBack = this->actor.world.pos.z - finishLineCoordinates[3].z; + + // frontPointsCrossProduct is positive if the dog is to the left of the line formed by the front points + // crossProductTemp is positive if the dog is above the line formed by the bottom points + frontPointsCrossProduct = ((xDistToTopFront * zDistToBottomFront) - (xDistToBottomFront * zDistToTopFront)); + crossProductTemp = (((xDistToBottomFront * zDistToBottomBack) - (xDistToBottomBack * zDistToBottomFront))); + if (frontPointsCrossProduct * crossProductTemp < 0.0f) { + return false; + } + + // crossProductTemp is positive if the dog is to the right of the line formed by the back points + frontPointsCrossProduct = ((xDistToTopFront * zDistToBottomFront) - (xDistToBottomFront * zDistToTopFront)); + crossProductTemp = ((xDistToBottomBack * zDistToTopBack) - (xDistToTopBack * zDistToBottomBack)); + if (frontPointsCrossProduct * crossProductTemp < 0.0f) { + return false; + } + + // crossProductTemp is positive if the dog is below the line formed by the top points + frontPointsCrossProduct = ((xDistToTopFront * zDistToBottomFront) - (xDistToBottomFront * zDistToTopFront)); + crossProductTemp = ((xDistToTopBack * zDistToTopFront) - (xDistToTopFront * zDistToTopBack)); + if (frontPointsCrossProduct * crossProductTemp < 0.0f) { + return false; + } + + return true; +} + +void EnRacedog_SpawnFloorDustRing(EnRacedog* this, GlobalContext* globalCtx) { + s16 curFrame = this->skelAnime.curFrame; + s16 mod = (this->actor.speedXZ > 6.0f) ? 2 : 3; + Vec3f pos; + + if (((this->index + curFrame) % mod) == 0) { + pos.x = this->actor.world.pos.x + randPlusMinusPoint5Scaled(15.0f); + pos.y = this->actor.world.pos.y; + pos.z = this->actor.world.pos.z + randPlusMinusPoint5Scaled(15.0f); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &pos, 10.0f, 0, 2.0f, 300, 0, true); + } +} + +void EnRacedog_PlayWalkSfx(EnRacedog* this) { + s16 curFrame = this->skelAnime.curFrame; + + if ((curFrame == 1) || (curFrame == 7)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_MONKEY_WALK); + } +} + +void EnRacedog_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRacedog* this = THIS; + Vec3f floorRot = { 0.0f, 0.0f, 0.0f }; + + this->selectedDogIndex = sSelectedDogInfo.index; + + this->actionFunc(this, globalCtx); + + EnRacedog_UpdateCollision(this, globalCtx); + EnRacedog_GetFloorRot(this, &floorRot); + Math_ApproachF(&this->curRot.x, floorRot.x, 0.2f, 0.1f); + + if (this->prevRot.x > 0.0f) { + if ((this->curRot.x < 0.0f) && (this->curRot.x > -0.1f)) { + // Moves to the part of the running animation where the dog has four feet + // on the ground and is about to lift its feet off the ground. + this->skelAnime.curFrame = 4.0f; + this->actor.velocity.y = 5.5f; + } + } + + if (!(this->actor.bgCheckFlags & 1)) { + this->skelAnime.curFrame = 0.0f; + } + + this->prevRot = this->curRot; + SkelAnime_Update(&this->skelAnime); +} + +void EnRacedog_UpdateSelectionArrow(EnRacedog* this) { + if (this->selectionArrowTimer > 6) { + this->selectionArrowGreenPrimColor -= 16; + this->selectionArrowGreenEnvColor += 8; + this->selectionArrowScale += 0.05f; + } else { + this->selectionArrowGreenPrimColor += 16; + this->selectionArrowGreenEnvColor -= 8; + this->selectionArrowScale -= 0.05f; + } + + if (DECR(this->selectionArrowTimer) == 0) { + this->selectionArrowTimer = 12; + } +} + +void EnRacedog_DrawSelectionArrow(EnRacedog* this, GlobalContext* globalCtx) { + Vec3s rotation = gZeroVec3s; + s32 shouldDrawSelectionArrow = (this->index == this->selectedDogIndex) ? true : false; + + if (shouldDrawSelectionArrow) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + EnRacedog_UpdateSelectionArrow(this); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, + &rotation); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 255, 255, this->selectionArrowGreenPrimColor, 0, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255, this->selectionArrowGreenEnvColor, 0, 255); + Matrix_Scale(this->selectionArrowScale * 2.0f, this->selectionArrowScale * 2.0f, + this->selectionArrowScale * 2.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++, gDogSelectionArrowEmptyDL); + gSPDisplayList(POLY_OPA_DISP++, gDogSelectionArrowDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +s32 EnRacedog_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + return false; +} + +void EnRacedog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnRacedog* this = THIS; + Vec3f focusOffset = { 0.0f, 20.0f, 0.0f }; + + if (limbIndex == DOG_LIMB_HEAD) { + Matrix_MultVec3f(&focusOffset, &this->actor.focus.pos); + } + + if (limbIndex == DOG_LIMB_TAIL) { + EnRacedog_DrawSelectionArrow(this, globalCtx); + } +} + +void EnRacedog_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRacedog* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + + switch (sDogInfo[this->index].color) { + case DOG_COLOR_BEIGE: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 200, 0); + break; + + case DOG_COLOR_WHITE: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 0); + break; + + case DOG_COLOR_BLUE: + gDPSetEnvColor(POLY_OPA_DISP++, 79, 79, 143, 0); + break; + + case DOG_COLOR_GOLD: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 207, 47, 0); + break; + + case DOG_COLOR_BROWN: + gDPSetEnvColor(POLY_OPA_DISP++, 143, 79, 47, 0); + break; + + case DOG_COLOR_GRAY: + gDPSetEnvColor(POLY_OPA_DISP++, 143, 143, 143, 0); + break; + + default: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 200, 0); + break; + } + + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateXFApply(this->curRot.x); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnRacedog_OverrideLimbDraw, EnRacedog_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..a4406b04c 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h @@ -2,15 +2,53 @@ #define Z_EN_RACEDOG_H #include "global.h" +#include "objects/object_dog/object_dog.h" + +#define ENRACEDOG_GET_INDEX(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENRACEDOG_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 10) + +/** + * The main point of this seems to be some very light anti-cheat detection. The dog + * must progress through these statuses in a linear order to finish the race. + */ +typedef enum { + /* 0 */ RACEDOG_RACE_STATUS_BEFORE_POINT_9, + /* 1 */ RACEDOG_RACE_STATUS_BETWEEN_POINTS_9_AND_11, + /* 2 */ RACEDOG_RACE_STATUS_AFTER_POINT_11, + /* 3 */ RACEDOG_RACE_STATUS_FINISHED +} RacedogRaceStatus; struct EnRacedog; typedef void (*EnRacedogActionFunc)(struct EnRacedog*, GlobalContext*); typedef struct EnRacedog { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnRacedogActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x180]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnRacedogActionFunc actionFunc; + /* 0x148 */ UNK_TYPE1 unk_148[0x4]; + /* 0x14C */ SkelAnime skelAnime; + /* 0x190 */ ColliderCylinder collider; + /* 0x1DC */ UNK_TYPE1 unk_1DC[0x4]; + /* 0x1E0 */ Path* path; + /* 0x1E4 */ UNK_TYPE1 unk_1E4[0x4]; + /* 0x1E8 */ s32 currentPoint; + /* 0x1EC */ Vec3s jointTable[DOG_LIMB_MAX]; + /* 0x23A */ Vec3s morphTable[DOG_LIMB_MAX]; + /* 0x288 */ s16 selectionArrowTimer; + /* 0x28A */ s16 raceStartTimer; + /* 0x28C */ s16 extraTimeBeforeRaceStart; + /* 0x28A */ UNK_TYPE1 unk_28E[0x2]; + /* 0x290 */ s16 index; + /* 0x292 */ s16 selectedDogIndex; + /* 0x294 */ UNK_TYPE1 unk_294[0x4]; + /* 0x298 */ f32 targetSpeed; + /* 0x29C */ s16 raceStatus; + /* 0x2A0 */ Vec3f prevRot; + /* 0x2AC */ Vec3f curRot; + /* 0x2B8 */ s32 pointForCurrentTargetSpeed; + /* 0x2BC */ s32 selectionArrowGreenPrimColor; + /* 0x2C0 */ s32 selectionArrowGreenEnvColor; + /* 0x2C4 */ f32 selectionArrowScale; } EnRacedog; // size = 0x2C8 extern const ActorInit En_Racedog_InitVars; diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.c b/src/overlays/actors/ovl_En_Raf/z_en_raf.c index ee2cbd79e..fb3b1070e 100644 --- a/src/overlays/actors/ovl_En_Raf/z_en_raf.c +++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.c @@ -1,6 +1,12 @@ +/* + * File: z_en_raf.c + * Overlay: ovl_En_Raf + * Description: Carnivorous Lily Pad + */ + #include "z_en_raf.h" -#define FLAGS 0x08000000 +#define FLAGS (ACTOR_FLAG_8000000) #define THIS ((EnRaf*)thisx) @@ -9,16 +15,58 @@ void EnRaf_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRaf_Update(Actor* thisx, GlobalContext* globalCtx); void EnRaf_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80A171D8(EnRaf* this, GlobalContext* globalCtx); -void func_80A17464(EnRaf* this, GlobalContext* globalCtx); -void func_80A175E4(EnRaf* this, GlobalContext* globalCtx); -void func_80A178A0(EnRaf* this, GlobalContext* globalCtx); -void func_80A17C6C(EnRaf* this, GlobalContext* globalCtx); -void func_80A17D54(EnRaf* this, GlobalContext* globalCtx); -void func_80A17E1C(EnRaf* this, GlobalContext* globalCtx); -void func_80A180B4(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupIdle(EnRaf* this); +void EnRaf_Idle(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupGrab(EnRaf* this); +void EnRaf_Grab(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupChew(EnRaf* this); +void EnRaf_Chew(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupThrow(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_Throw(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_Explode(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_PostDetonation(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_Convulse(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupDissolve(EnRaf* this); +void EnRaf_Dissolve(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_SetupDormant(EnRaf* this); +void EnRaf_Dormant(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_InitializeParticle(EnRaf* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, s16 timer); +void EnRaf_UpdateParticles(EnRaf* this, GlobalContext* globalCtx); +void EnRaf_DrawParticles(EnRaf* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ EN_RAF_ANIMATION_IDLE, + /* 1 */ EN_RAF_ANIMATION_CLOSE, + /* 2 */ EN_RAF_ANIMATION_CHEW, + /* 3 */ EN_RAF_ANIMATION_SPIT, + /* 4 */ EN_RAF_ANIMATION_CONVULSE, + /* 5 */ EN_RAF_ANIMATION_DEATH, +} EnRafAnimationIndex; + +typedef enum { + /* 0 */ EN_RAF_ACTION_IDLE, + /* 1 */ EN_RAF_ACTION_GRAB, + /* 2 */ EN_RAF_ACTION_CHEW, + /* 3 */ EN_RAF_ACTION_THROW, + /* 4 */ EN_RAF_ACTION_EXPLODE, + /* 5 */ EN_RAF_ACTION_CONVULSE, + /* 6 */ EN_RAF_ACTION_DISSOLVE, + /* 7 */ EN_RAF_ACTION_DORMANT, +} EnRafAction; + +typedef enum { + /* 0 */ EN_RAF_GRAB_TARGET_PLAYER, + /* 1 */ EN_RAF_GRAB_TARGET_EXPLOSIVE, + /* 2 */ EN_RAF_GRAB_TARGET_GORON_PLAYER +} EnRafGrabTarget; + +typedef enum { + /* 0 */ EN_RAF_PETAL_SCALE_TYPE_DEAD, + /* 1 */ EN_RAF_PETAL_SCALE_TYPE_GRAB, + /* 2 */ EN_RAF_PETAL_SCALE_TYPE_CHEW, + /* 3 */ EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW +} EnRafPetalScaleType; -#if 0 const ActorInit En_Raf_InitVars = { ACTOR_EN_RAF, ACTORCAT_PROP, @@ -31,15 +79,71 @@ const ActorInit En_Raf_InitVars = { (ActorFunc)EnRaf_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A18EE0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 50, 10, -10, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80A1939C = { +static u8 sTeethClearPixelTableFirstPass[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, +}; + +static u8 sTeethClearPixelTableSecondPass[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static u8 sPetalClearPixelTableFirstPass[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, + 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, + 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, +}; + +static u8 sPetalClearPixelTableSecondPass[] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +}; + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xF), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -74,65 +178,786 @@ static DamageTable D_80A1939C = { /* Powder Keg */ DMG_ENTRY(0, 0xF), }; -#endif +/** + * Sets the `index`th pixel of the trap teeth texture to 0 (transparent black) + * according to the `clearPixelTable`. Only works if the texture uses 16-bit pixels. + */ +void EnRaf_ClearPixelTeeth(u16* texture, u8* clearPixelTable, s32 index) { + if ((index < (8 * 8)) && (clearPixelTable[index] != 0)) { + texture[index] = 0; + } +} -extern ColliderCylinderInit D_80A18EE0; -extern DamageTable D_80A1939C; +/** + * Sets the `index`th pixel of the trap petal texture to 0 (transparent black) + * according to the `clearPixelTable`. Only works if the texture uses 16-bit pixels. + */ +void EnRaf_ClearPixelPetal(u16* texture, u8* clearPixelTable, s32 index) { + if (clearPixelTable[index] != 0) { + texture[index] = 0; + } +} -extern UNK_TYPE D_06000108; -extern UNK_TYPE D_060024E0; -extern UNK_TYPE D_060032F8; +void EnRaf_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRaf* this = THIS; + Vec3f limbScale = { 1.0f, 1.0f, 1.0f }; + s32 pad; + s32 i; + CollisionHeader* colHeader = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A16D40.s") + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&gCarnivorousLilyPadCol, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + this->dyna.actor.targetMode = 3; + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gCarnivorousLilyPadSkel, &gCarnivorousLilyPadSpitAnim, + this->jointTable, this->morphTable, CARNIVOROUS_LILY_PAD_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A16D6C.s") + for (i = 0; i < ARRAY_COUNT(this->limbScale); i++) { + Math_Vec3f_Copy(&this->targetLimbScale[i], &limbScale); + Math_Vec3f_Copy(&this->limbScale[i], &limbScale); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/EnRaf_Init.s") + this->dyna.actor.colChkInfo.damageTable = &sDamageTable; + this->dyna.actor.colChkInfo.health = BREG(1) + 2; + this->mainType = EN_RAF_GET_TYPE(&this->dyna.actor); + this->reviveTimer = EN_RAF_GET_REVIVE_TIMER(&this->dyna.actor); + this->switchFlag = EN_RAF_GET_SWITCH_FLAG(&this->dyna.actor); + if (this->switchFlag == 0x7F) { + this->switchFlag = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/EnRaf_Destroy.s") + if (this->reviveTimer == 31) { + this->reviveTimer = -1; + } else { + this->reviveTimer = 30; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17060.s") + if (((this->switchFlag >= 0) || (this->mainType == EN_RAF_TYPE_DORMANT) || + (gSaveContext.save.weekEventReg[12] & 1)) && + ((Flags_GetSwitch(globalCtx, this->switchFlag)) || (this->mainType == EN_RAF_TYPE_DORMANT))) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A1712C.s") + for (i = CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_LOWER_SEGMENT; i <= CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT; + i++) { + Math_Vec3f_Copy(&this->limbScale[i], &gZeroVec3f); + Math_Vec3f_Copy(&this->targetLimbScale[i], &gZeroVec3f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A171D8.s") + EnRaf_SetupDormant(this); + } else { + this->bobPhase = Rand_ZeroFloat(1.0f) * 20000.0f; + Actor_SetScale(&this->dyna.actor, 0.01f); + EnRaf_SetupIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17414.s") +void EnRaf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRaf* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17464.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17530.s") +void EnRaf_ChangeAnimation(EnRaf* this, s32 index) { + static AnimationHeader* sAnimations[] = { + &gCarnivorousLilyPadSpitAnim, &gCarnivorousLilyPadCloseAnim, &gCarnivorousLilyPadChewAnim, + &gCarnivorousLilyPadSpitAnim, &gCarnivorousLilyPadConvulseAnim, &gCarnivorousLilyPadDeathAnim, + }; + static u8 sAnimationModes[] = { + ANIMMODE_ONCE, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_ONCE, ANIMMODE_LOOP, ANIMMODE_ONCE, + }; + f32 startFrame = 0.0f; + f32 playSpeed = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A175E4.s") + this->endFrame = Animation_GetLastFrame(sAnimations[index]); + if (index == EN_RAF_ANIMATION_IDLE) { + startFrame = this->endFrame; + } else if (index == EN_RAF_ANIMATION_CLOSE) { + playSpeed = 2.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17848.s") + Animation_Change(&this->skelAnime, sAnimations[index], playSpeed, startFrame, this->endFrame, + sAnimationModes[index], -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A178A0.s") +void EnRaf_SetupIdle(EnRaf* this) { + Vec3f targetLimbScale = { 1.0f, 1.0f, 1.0f }; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A179C8.s") + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_IDLE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17C6C.s") + for (i = CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_LOWER_SEGMENT; i <= CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT; i++) { + Math_Vec3f_Copy(&this->targetLimbScale[i], &targetLimbScale); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17D14.s") + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW; + this->action = EN_RAF_ACTION_IDLE; + this->actionFunc = EnRaf_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17D54.s") +/** + * Sits around waiting for the player or an explosive to get near in order to grab them. + */ +void EnRaf_Idle(EnRaf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Actor* explosive; + f32 xDiff; + f32 yDiff; + f32 zDiff; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17DDC.s") + if (this->timer == 0) { + if ((player->transformation != PLAYER_FORM_DEKU) && + (this->dyna.actor.xzDistToPlayer < (BREG(48) + 80.0f) && (player->invincibilityTimer == 0) && + DynaPolyActor_IsInRidingMovingState(&this->dyna) && !(player->stateFlags1 & 0x8000000) && + globalCtx->grabPlayer(globalCtx, player))) { + player->actor.parent = &this->dyna.actor; + this->grabTarget = EN_RAF_GRAB_TARGET_PLAYER; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A17E1C.s") + if (player->transformation == PLAYER_FORM_GORON) { + this->grabTarget = EN_RAF_GRAB_TARGET_GORON_PLAYER; + } else { + player->unk_AE8 = 50; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A18080.s") + this->playerRotYWhenGrabbed = player->actor.world.rot.y; + EnRaf_SetupGrab(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A180B4.s") + if ((globalCtx->gameplayFrames % 2) == 0) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/EnRaf_Update.s") + explosive = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + while (explosive != NULL) { + // This check is pointless, since EnRaf is never in the explosive category. + if ((EnRaf*)explosive == this) { + explosive = explosive->next; + continue; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A1859C.s") + xDiff = explosive->world.pos.x - this->dyna.actor.world.pos.x; + yDiff = explosive->world.pos.y - this->dyna.actor.world.pos.y; + zDiff = explosive->world.pos.z - this->dyna.actor.world.pos.z; + if ((fabsf(xDiff) < 80.0f) && (fabsf(yDiff) < 30.0f) && (fabsf(zDiff) < 80.0f) && + (explosive->update != NULL) && (explosive->velocity.y != 0.0f)) { + Actor_MarkForDeath(explosive); + this->grabTarget = EN_RAF_GRAB_TARGET_EXPLOSIVE; + this->collider.dim.radius = 30; + this->collider.dim.height = 90; + this->collider.dim.yShift = -10; + EnRaf_SetupGrab(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/EnRaf_Draw.s") + explosive = explosive->next; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A18A90.s") +void EnRaf_SetupGrab(EnRaf* this) { + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_CLOSE); + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_GRAB; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_SUISEN_DRINK); + this->action = EN_RAF_ACTION_GRAB; + this->actionFunc = EnRaf_Grab; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A18B8C.s") +/** + * Grabs the player or explosive that entered its range. + */ +void EnRaf_Grab(EnRaf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 curFrame = this->skelAnime.curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Raf/func_80A18DA0.s") + if ((this->grabTarget != EN_RAF_GRAB_TARGET_EXPLOSIVE) && (player->stateFlags2 & 0x80) && + (&this->dyna.actor == player->actor.parent)) { + Math_ApproachF(&player->actor.world.pos.x, this->dyna.actor.world.pos.x, 0.3f, 10.0f); + Math_ApproachF(&player->actor.world.pos.y, this->dyna.actor.world.pos.y, 0.3f, 10.0f); + Math_ApproachF(&player->actor.world.pos.z, this->dyna.actor.world.pos.z, 0.3f, 10.0f); + } + + if (this->endFrame <= curFrame) { + EnRaf_SetupChew(this); + } +} + +void EnRaf_SetupChew(EnRaf* this) { + s32 i; + + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_CHEW); + this->chewCount = 0; + for (i = 0; i < ARRAY_COUNT(this->chewLimbRot); i++) { + this->chewLimbRot[i].x = Rand_S16Offset(8, 8) << 8; + this->chewLimbRot[i].y = Rand_S16Offset(8, 8) << 8; + this->chewLimbRot[i].z = Rand_S16Offset(8, 8) << 8; + } + + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_CHEW; + this->action = EN_RAF_ACTION_CHEW; + this->actionFunc = EnRaf_Chew; +} + +/** + * Chews the player or explosive that was grabbed. If it grabbed a non-Goron player, it will deal + * damage to them and eventually throw them. If it grabbed a Goron player or explosive, it will + * instead explode after chewing them a bit. + */ +void EnRaf_Chew(EnRaf* this, GlobalContext* globalCtx) { + f32 targetChewScale; + f32 curFrame; + Player* player = GET_PLAYER(globalCtx); + + curFrame = this->skelAnime.curFrame; + targetChewScale = (BREG(51) / 100.0f) + 0.2f; + Math_ApproachF(&this->chewScale, targetChewScale, 0.2f, 0.03f); + + if ((player->stateFlags2 & 0x80) && (this->grabTarget != EN_RAF_GRAB_TARGET_EXPLOSIVE) && + (&this->dyna.actor == player->actor.parent)) { + Math_ApproachF(&player->actor.world.pos.x, this->dyna.actor.world.pos.x, 0.3f, 10.0f); + Math_ApproachF(&player->actor.world.pos.y, this->dyna.actor.world.pos.y, 0.3f, 10.0f); + Math_ApproachF(&player->actor.world.pos.z, this->dyna.actor.world.pos.z, 0.3f, 10.0f); + } + + if (this->endFrame <= curFrame) { + if (BREG(52) == 0) { + this->chewCount++; + } + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_SUISEN_EAT); + switch (this->grabTarget) { + case EN_RAF_GRAB_TARGET_PLAYER: + globalCtx->damagePlayer(globalCtx, -2); + func_800B8E58((Player*)this, player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S); + CollisionCheck_GreenBlood(globalCtx, NULL, &player->actor.world.pos); + if ((this->chewCount > (BREG(53) + 5)) || !(player->stateFlags2 & 0x80)) { + player->actor.freezeTimer = 10; + EnRaf_SetupThrow(this, globalCtx); + return; + } + break; + + case EN_RAF_GRAB_TARGET_EXPLOSIVE: + Actor_ApplyDamage(&this->dyna.actor); + if (this->chewCount > (BREG(54) + 4)) { + EnRaf_Explode(this, globalCtx); + return; + } + break; + + case EN_RAF_GRAB_TARGET_GORON_PLAYER: + if (this->chewCount > (BREG(54) + 4)) { + player->actor.parent = NULL; + player->unk_AE8 = 1000; + EnRaf_Explode(this, globalCtx); + } + break; + } + } +} + +void EnRaf_SetupThrow(EnRaf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_SPIT); + player->actor.freezeTimer = 10; + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW; + this->action = EN_RAF_ACTION_THROW; + this->actionFunc = EnRaf_Throw; +} + +/** + * Spits out the grabbed player. + */ +void EnRaf_Throw(EnRaf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 curFrame = this->skelAnime.curFrame; + + if (Animation_OnFrame(&this->skelAnime, 10.0f)) { + player->actor.freezeTimer = 0; + player->actor.parent = NULL; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_SUISEN_THROW); + func_800B8D50(globalCtx, &this->dyna.actor, BREG(55) + 3.0f, this->playerRotYWhenGrabbed + 0x8000, + BREG(56) + 10.0f, 0); + } else if (curFrame < 10.0f) { + player->actor.freezeTimer = 10; + } + + if (this->endFrame <= curFrame) { + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW; + this->action = EN_RAF_ACTION_IDLE; + this->timer = 20; + this->actionFunc = EnRaf_Idle; + } +} + +/** + * Creates an explosion effect/sound and spawns particles. + */ +void EnRaf_Explode(EnRaf* this, GlobalContext* globalCtx) { + Vec3f velocity = { 0.0f, 0.0f, 0.0f }; + Vec3f acceleration = { 0.0f, 0.0f, 0.0f }; + Vec3f explosionPos; + s32 i; + s32 pad; + + this->action = EN_RAF_ACTION_EXPLODE; + Math_Vec3f_Copy(&explosionPos, &this->dyna.actor.world.pos); + explosionPos.y += 10.0f; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, explosionPos.x, explosionPos.y, explosionPos.z, 0, + 0, 0, CLEAR_TAG_SMALL_EXPLOSION); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_IT_BOMB_EXPLOSION); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_SUISEN_DEAD); + if (this->switchFlag >= 0) { + Flags_SetSwitch(globalCtx, this->switchFlag); + } + + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_DEAD; + for (i = 0; i < BREG(57) + 30; i++) { + acceleration.x = (Rand_ZeroOne() - 0.5f) * 0.5f; + acceleration.y = -0.3f; + acceleration.z = (Rand_ZeroOne() - 0.5f) * 0.5f; + velocity.x = Rand_ZeroOne() - 0.5f; + velocity.y = Rand_ZeroOne() * 10.0f; + velocity.z = Rand_ZeroOne() - 0.5f; + EnRaf_InitializeParticle(this, &this->dyna.actor.world.pos, &velocity, &acceleration, + (Rand_ZeroFloat(1.0f) / 500.0f) + 0.002f, 90); + } + + for (i = CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_LOWER_SEGMENT; i <= CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT; i++) { + Math_Vec3f_Copy(&this->targetLimbScale[i], &gZeroVec3f); + } + + this->timer = 5; + if (this->grabTarget == EN_RAF_GRAB_TARGET_EXPLOSIVE) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->dyna.actor, 5); + this->dyna.actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); + } + + this->actionFunc = EnRaf_PostDetonation; +} + +/** + * Switches the lily pad to the "dead" state once the timer reaches 0. + */ +void EnRaf_PostDetonation(EnRaf* this, GlobalContext* globalCtx) { + if (this->timer == 0) { + this->collider.dim.radius = 50; + this->collider.dim.height = 10; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->dyna.actor, 6); + this->dyna.actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + EnRaf_SetupDormant(this); + } else if (this->grabTarget == EN_RAF_GRAB_TARGET_EXPLOSIVE) { + this->collider.dim.radius = 80; + this->collider.dim.height = 50; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnRaf_SetupConvulse(EnRaf* this) { + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_CONVULSE); + this->chewCount = 0; + this->action = EN_RAF_ACTION_CONVULSE; + this->actionFunc = EnRaf_Convulse; +} + +/** + * Plays the convulsing animation and sets the lily pad's switch flag to prevent it from + * ever coming back to life. When the water in Woodfall Temple is purified, this function + * and EnRaf_Dissolve are jointly responsible for controlling the lily pad's death. + */ +void EnRaf_Convulse(EnRaf* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->endFrame <= curFrame) { + this->chewCount++; + if (this->chewCount > (BREG(2) + 2)) { + if (this->switchFlag >= 0) { + Flags_SetSwitch(globalCtx, this->switchFlag); + } + + EnRaf_SetupDissolve(this); + } + } +} + +void EnRaf_SetupDissolve(EnRaf* this) { + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_DEATH); + this->action = EN_RAF_ACTION_DISSOLVE; + this->dissolveTimer = 0; + this->actionFunc = EnRaf_Dissolve; +} + +/** + * Makes the trap petals on the lily pad dissolve and switches the lily pad to the "dead" state. + * When the water in Woodfall Temple is purified, this function and EnRaf_Convulse are jointly + * responsible for controlling the lily pad's death. + */ +void EnRaf_Dissolve(EnRaf* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + s32 i; + + if (this->endFrame <= curFrame) { + this->dissolveTimer++; + if (this->dissolveTimer < (BREG(3) + 105)) { + for (i = 0; i < (BREG(4) + 5); i++) { + EnRaf_ClearPixelPetal(Lib_SegmentedToVirtual(&gCarnivorousLilyPadTrapPetalTex), + sPetalClearPixelTableFirstPass, this->petalClearPixelFirstPassIndex); + EnRaf_ClearPixelTeeth(Lib_SegmentedToVirtual(&gCarnivorousLilyPadTrapTeethTex), + sTeethClearPixelTableFirstPass, this->teethClearPixelFirstPassIndex); + if (this->petalClearPixelFirstPassIndex < (16 * 32)) { + this->petalClearPixelFirstPassIndex++; + } + + if (this->teethClearPixelFirstPassIndex < (8 * 8)) { + this->teethClearPixelFirstPassIndex++; + } + } + } + } + + if (this->dissolveTimer > (BREG(5) + 50)) { + for (i = 0; i < (BREG(6) + 5); i++) { + EnRaf_ClearPixelPetal(Lib_SegmentedToVirtual(&gCarnivorousLilyPadTrapPetalTex), + sPetalClearPixelTableSecondPass, this->petalClearPixelSecondPassIndex); + EnRaf_ClearPixelTeeth(Lib_SegmentedToVirtual(&gCarnivorousLilyPadTrapTeethTex), + sTeethClearPixelTableSecondPass, this->teethClearPixelSecondPassIndex); + if (this->petalClearPixelSecondPassIndex < (16 * 32)) { + this->petalClearPixelSecondPassIndex++; + } + + if (this->teethClearPixelSecondPassIndex < (8 * 8)) { + this->teethClearPixelSecondPassIndex++; + } + } + } + + if (this->dissolveTimer > (BREG(7) + 160)) { + for (i = CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_LOWER_SEGMENT; i <= CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT; + i++) { + Math_Vec3f_Copy(&this->limbScale[i], &gZeroVec3f); + Math_Vec3f_Copy(&this->targetLimbScale[i], &gZeroVec3f); + } + + EnRaf_SetupDormant(this); + } +} + +void EnRaf_SetupDormant(EnRaf* this) { + if (this->action == EN_RAF_ACTION_EXPLODE) { + this->timer = 90; + } else { + this->action = EN_RAF_ACTION_DORMANT; + } + + this->actionFunc = EnRaf_Dormant; +} + +/** + * Simply sits around doing nothing. If the revive timer is non-zero, then this function + * will decrement the revive timer and revive the trap petals once it reaches 0. + */ +void EnRaf_Dormant(EnRaf* this, GlobalContext* globalCtx) { + Vec3f targetLimbScale = { 1.0f, 1.0f, 1.0f }; + s32 i; + + if (this->timer == 0) { + this->action = EN_RAF_ACTION_DORMANT; + } + + if (this->reviveTimer >= 0) { + DECR(this->reviveTimer); + + if (this->reviveTimer == 0) { + EnRaf_ChangeAnimation(this, EN_RAF_ANIMATION_SPIT); + + for (i = CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_LOWER_SEGMENT; + i <= CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT; i++) { + Math_Vec3f_Copy(&this->targetLimbScale[i], &targetLimbScale); + } + + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW; + this->action = EN_RAF_ACTION_IDLE; + this->reviveTimer = EN_RAF_GET_REVIVE_TIMER(&this->dyna.actor); + this->reviveTimer += 30; + this->actionFunc = EnRaf_Idle; + } + } +} + +void EnRaf_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRaf* this = THIS; + WaterBox* waterBox; + f32 ySurface; + Vec3f ripplePos; + s32 i; + + SkelAnime_Update(&this->skelAnime); + DECR(this->rippleTimer); + DECR(this->timer); + this->actionFunc(this, globalCtx); + + if ((this->action == EN_RAF_ACTION_IDLE) && (gSaveContext.save.weekEventReg[12] & 1)) { + this->petalScaleType = EN_RAF_PETAL_SCALE_TYPE_DEAD; + EnRaf_SetupConvulse(this); + return; + } + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + if ((this->heightDiffFromPlayer > -0.1f) && !this->isCurrentlyInRidingMovingState) { + this->heightDiffFromPlayer = -20.0f; + this->isCurrentlyInRidingMovingState = true; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_COMMON_WATER_MID); + } + } else { + this->isCurrentlyInRidingMovingState = false; + } + + this->bobPhase += 3000.0f; + this->bobOffset = 2.0f * Math_SinS(this->bobPhase); + if (this->mainType != EN_RAF_TYPE_NO_WATER_INTERACTIONS) { + ySurface = BREG(60) + (this->dyna.actor.world.pos.y - 60.0f); + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.z, &ySurface, &waterBox)) { + ySurface -= this->bobOffset + BREG(59); + Math_ApproachF(&this->dyna.actor.world.pos.y, this->heightDiffFromPlayer + ySurface, 0.5f, 40.0f); + if (this->rippleTimer == 0) { + this->rippleTimer = 30; + if (this->petalScaleType == EN_RAF_PETAL_SCALE_TYPE_CHEW) { + this->rippleTimer = 10; + } + + Math_Vec3f_Copy(&ripplePos, &this->dyna.actor.world.pos); + ripplePos.y = ySurface; + EffectSsGRipple_Spawn(globalCtx, &ripplePos, 650, 3150, 0); + } + } + } else { + Math_ApproachF(&this->dyna.actor.world.pos.y, + (this->dyna.actor.home.pos.y + this->heightDiffFromPlayer) - this->bobOffset, 0.5f, 40.0f); + } + + Math_ApproachZeroF(&this->heightDiffFromPlayer, 0.3f, 2.0f); + if (this->action == EN_RAF_ACTION_EXPLODE) { + EnRaf_UpdateParticles(this, globalCtx); + } + + for (i = 0; i < ARRAY_COUNT(this->limbScale); i++) { + if (this->action < EN_RAF_ACTION_EXPLODE) { + Math_ApproachF(&this->limbScale[i].x, this->targetLimbScale[i].x, 0.4f, 0.5f); + Math_ApproachF(&this->limbScale[i].y, this->targetLimbScale[i].y, 0.4f, 0.5f); + Math_ApproachF(&this->limbScale[i].z, this->targetLimbScale[i].z, 0.4f, 0.5f); + } else { + Math_ApproachF(&this->limbScale[i].x, this->targetLimbScale[i].x, 1.0f, 1.0f); + Math_ApproachF(&this->limbScale[i].y, this->targetLimbScale[i].y, 1.0f, 1.0f); + Math_ApproachF(&this->limbScale[i].z, this->targetLimbScale[i].z, 1.0f, 1.0f); + } + } + + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + if (this->action < EN_RAF_ACTION_EXPLODE) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +static s16 sGrabAnimationCheckFrames[] = { 0, 4, 6 }; + +static Vec3f sMiddleSegmentTargetScaleDuringGrab[] = { + { 1.0f, 1.0f, 1.0f }, + { 1.0f, 2.0f, 1.0f }, + { 0.0f, 1.5f, 0.7f }, +}; + +static Vec3f sUpperSegmentTargetScaleDuringGrab[] = { + { 1.0f, 1.0f, 1.0f }, + { 3.0f, 2.0f, 1.5f }, + { 1.5f, 1.2f, 0.8f }, +}; + +static s16 sSpitAnimationCheckFrames[] = { 0, 7, 9, 13, 19 }; + +static Vec3f sMiddleSegmentTargetScaleDuringSpit[] = { + { 1.0f, 1.5f, 0.7f }, { 1.0f, 2.0f, 1.5f }, { 1.0f, 2.0f, 0.5f }, { 1.0f, 2.0f, 0.5f }, { 1.0f, 1.0f, 1.0f }, +}; + +static Vec3f sUpperSegmentTargetScaleDuringSpit[] = { + { 1.5f, 1.5f, 1.7f }, { 1.5f, 1.5f, 1.3f }, { 3.0f, 1.0f, 0.5f }, { 1.0f, 1.0f, 0.5f }, { 1.0f, 1.0f, 1.0f }, +}; + +void EnRaf_TransformLimbDraw(GlobalContext* globalCtx2, s32 limbIndex, Actor* thisx) { + GlobalContext* globalCtx = globalCtx2; + EnRaf* this = THIS; + s32 i; + + switch (this->petalScaleType) { + case EN_RAF_PETAL_SCALE_TYPE_GRAB: + if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_MIDDLE_SEGMENT)) { + for (i = 0; i < ARRAY_COUNT(sGrabAnimationCheckFrames); i++) { + if ((s16)this->skelAnime.curFrame == sGrabAnimationCheckFrames[i]) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sMiddleSegmentTargetScaleDuringGrab[i]); + } + } + } + + if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_UPPER_SEGMENT)) { + for (i = 0; i < ARRAY_COUNT(sGrabAnimationCheckFrames); i++) { + if ((s16)this->skelAnime.curFrame == sGrabAnimationCheckFrames[i]) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sUpperSegmentTargetScaleDuringGrab[i]); + } + } + } + break; + + case EN_RAF_PETAL_SCALE_TYPE_CHEW: + if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_MIDDLE_SEGMENT)) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sMiddleSegmentTargetScaleDuringGrab[2]); + } else if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_UPPER_SEGMENT)) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sUpperSegmentTargetScaleDuringGrab[2]); + } + + // These matrix operations make the trap petals look a bit more "wobbly" as it chews + // by stretching the limbs in various random directions. + if ((limbIndex > CARNIVOROUS_LILY_PAD_LIMB_FLOWER) && (limbIndex < CARNIVOROUS_LILY_PAD_LIMB_ROOTS)) { + Matrix_RotateYS((this->chewLimbRot[limbIndex].y * globalCtx->gameplayFrames), MTXMODE_APPLY); + Matrix_RotateXS((this->chewLimbRot[limbIndex].x * globalCtx->gameplayFrames), MTXMODE_APPLY); + Matrix_RotateZS((this->chewLimbRot[limbIndex].z * globalCtx->gameplayFrames), MTXMODE_APPLY); + Matrix_Scale(this->chewScale + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZS(-(this->chewLimbRot[limbIndex].z * globalCtx->gameplayFrames), MTXMODE_APPLY); + Matrix_RotateXS(-(this->chewLimbRot[limbIndex].x * globalCtx->gameplayFrames), MTXMODE_APPLY); + Matrix_RotateYS(-(this->chewLimbRot[limbIndex].y * globalCtx->gameplayFrames), MTXMODE_APPLY); + } + break; + + case EN_RAF_PETAL_SCALE_TYPE_IDLE_OR_THROW: + if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_MIDDLE_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_MIDDLE_SEGMENT)) { + for (i = 0; i < ARRAY_COUNT(sSpitAnimationCheckFrames); i++) { + if ((s16)this->skelAnime.curFrame == sSpitAnimationCheckFrames[i]) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sMiddleSegmentTargetScaleDuringSpit[i]); + } + } + } + + if ((limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_1_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_3_UPPER_SEGMENT) || + (limbIndex == CARNIVOROUS_LILY_PAD_LIMB_TRAP_2_UPPER_SEGMENT)) { + for (i = 0; i < 4; i++) { + if ((s16)this->skelAnime.curFrame == sSpitAnimationCheckFrames[i]) { + Math_Vec3f_Copy(&this->targetLimbScale[limbIndex], &sUpperSegmentTargetScaleDuringSpit[i]); + } + } + } + break; + } + + Matrix_Scale(this->limbScale[limbIndex].x, this->limbScale[limbIndex].y, this->limbScale[limbIndex].z, + MTXMODE_APPLY); +} + +void EnRaf_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRaf* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, EnRaf_TransformLimbDraw, &this->dyna.actor); + + if (this->action == EN_RAF_ACTION_EXPLODE) { + EnRaf_DrawParticles(this, globalCtx); + } +} + +void EnRaf_InitializeParticle(EnRaf* this, Vec3f* position, Vec3f* velocity, Vec3f* acceleration, f32 scale, + s16 timer) { + s16 i; + EnRafParticle* particle = this->particles; + + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (!particle->isVisible) { + particle->isVisible = true; + particle->position = *position; + particle->velocity = *velocity; + particle->acceleration = *acceleration; + particle->scale = scale; + particle->timer = timer; + particle->rotation.x = randPlusMinusPoint5Scaled(30000.0f); + particle->rotation.y = randPlusMinusPoint5Scaled(30000.0f); + particle->rotation.z = randPlusMinusPoint5Scaled(30000.0f); + return; + } + } +} + +void EnRaf_UpdateParticles(EnRaf* this, GlobalContext* globalCtx) { + s32 i; + EnRafParticle* particle = this->particles; + + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (particle->isVisible) { + particle->position.x += particle->velocity.x; + particle->position.y += particle->velocity.y; + particle->position.z += particle->velocity.z; + particle->rotation.x += 0xBB8; + particle->rotation.y += 0xBB8; + particle->rotation.z += 0xBB8; + particle->velocity.x += particle->acceleration.x; + particle->velocity.y += particle->acceleration.y; + particle->velocity.z += particle->acceleration.z; + + if (this->mainType != EN_RAF_TYPE_NO_WATER_INTERACTIONS) { + if (particle->position.y < (this->dyna.actor.world.pos.y - 10.0f)) { + EffectSsGSplash_Spawn(globalCtx, &particle->position, NULL, NULL, 0, particle->scale * 200000.0f); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &particle->position, 50, NA_SE_EV_BOMB_DROP_WATER); + particle->isVisible = false; + } + } else if (particle->position.y < (this->dyna.actor.world.pos.y - 10.0f)) { + Math_ApproachZeroF(&particle->scale, 0.2f, 0.001f); + if (particle->scale <= 0.0001f) { + particle->timer = 0; + } + } + + if (particle->timer != 0) { + particle->timer--; + } else { + particle->isVisible = false; + } + } + } +} + +void EnRaf_DrawParticles(EnRaf* this, GlobalContext* globalCtx) { + s16 i; + EnRafParticle* particle = this->particles; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + for (i = 0; i < ARRAY_COUNT(this->particles); i++, particle++) { + if (particle->isVisible) { + Matrix_Translate(particle->position.x, particle->position.y, particle->position.z, MTXMODE_NEW); + Matrix_Scale(particle->scale, particle->scale, particle->scale, MTXMODE_APPLY); + Matrix_RotateXS(particle->rotation.x, MTXMODE_APPLY); + Matrix_RotateYS(particle->rotation.y, MTXMODE_APPLY); + Matrix_RotateZS(particle->rotation.z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gCarnivorousLilyPadParticleDL); + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Raf/z_en_raf.h b/src/overlays/actors/ovl_En_Raf/z_en_raf.h index 95ddfc54d..f63924402 100644 --- a/src/overlays/actors/ovl_En_Raf/z_en_raf.h +++ b/src/overlays/actors/ovl_En_Raf/z_en_raf.h @@ -2,16 +2,64 @@ #define Z_EN_RAF_H #include "global.h" +#include "objects/object_raf/object_raf.h" + +#define EN_RAF_GET_TYPE(thisx) (((thisx)->params >> 12) & 0xF) +#define EN_RAF_GET_REVIVE_TIMER(thisx) (((thisx)->params >> 7) & 0x1F) +#define EN_RAF_GET_SWITCH_FLAG(thisx) ((thisx)->params & 0x7F) + +typedef enum { + /* 0 */ EN_RAF_TYPE_NORMAL, + /* 1 */ EN_RAF_TYPE_DORMANT, // Spawns without trap, so it can't eat bombs/player + /* 2 */ EN_RAF_TYPE_NO_WATER_INTERACTIONS // Won't produce ripples, and particles won't produce splashes +} EnRafType; struct EnRaf; typedef void (*EnRafActionFunc)(struct EnRaf*, GlobalContext*); +typedef struct { + /* 0x00 */ u8 isVisible; + /* 0x04 */ Vec3f position; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f acceleration; + /* 0x28 */ Vec3s rotation; + /* 0x30 */ f32 scale; + /* 0x34 */ s16 timer; +} EnRafParticle; // size = 0x38 + typedef struct EnRaf { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xEC]; - /* 0x0230 */ EnRafActionFunc actionFunc; - /* 0x0234 */ char unk_234[0x8B0]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ SkelAnime skelAnime; + /* 0x1A0 */ Vec3s jointTable[CARNIVOROUS_LILY_PAD_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[CARNIVOROUS_LILY_PAD_LIMB_MAX]; + /* 0x230 */ EnRafActionFunc actionFunc; + /* 0x234 */ Vec3f limbScale[CARNIVOROUS_LILY_PAD_LIMB_MAX]; + /* 0x2C4 */ Vec3f targetLimbScale[CARNIVOROUS_LILY_PAD_LIMB_MAX]; + /* 0x354 */ Vec3s chewLimbRot[CARNIVOROUS_LILY_PAD_LIMB_MAX]; + /* 0x39C */ s16 grabTarget; + /* 0x39E */ u8 isCurrentlyInRidingMovingState; + /* 0x3A0 */ f32 endFrame; + /* 0x3A4 */ f32 chewScale; + /* 0x3A8 */ f32 bobOffset; + /* 0x3AC */ f32 heightDiffFromPlayer; + /* 0x3B0 */ f32 bobPhase; + /* 0x3B4 */ s16 timer; + /* 0x3B6 */ s16 dissolveTimer; + /* 0x3B8 */ s16 rippleTimer; + /* 0x3BA */ s16 reviveTimer; + /* 0x3BC */ s16 playerRotYWhenGrabbed; + /* 0x3BE */ s16 mainType; + /* 0x3C0 */ s16 switchFlag; + /* 0x3C2 */ s16 petalScaleType; + /* 0x3C4 */ s16 chewCount; + /* 0x3C6 */ s16 action; + /* 0x3C8 */ s16 petalClearPixelFirstPassIndex; + /* 0x3CA */ s16 teethClearPixelFirstPassIndex; + /* 0x3CC */ s16 petalClearPixelSecondPassIndex; + /* 0x3CE */ s16 teethClearPixelSecondPassIndex; + /* 0x3D0 */ ColliderCylinder collider; + /* 0x41C */ EnRafParticle particles[31]; } EnRaf; // size = 0xAE4 extern const ActorInit En_Raf_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 38579f83a..99d30f14c 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 @@ -1,6 +1,14 @@ -#include "z_en_rail_skb.h" +/* + * File: z_en_rail_skb.c + * Overlay: ovl_En_Rail_Skb + * Description: Ikana Graveyard - Circle of Stalchildren + */ -#define FLAGS 0x00000015 +#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 (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10) #define THIS ((EnRailSkb*)thisx) @@ -9,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, @@ -38,29 +62,63 @@ const ActorInit En_Rail_Skb_InitVars = { (ActorFunc)EnRailSkb_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80B73408[2] = { +static AnimationInfo sAnimations[] = { + { &object_skb_Anim_0064E0, 0.96f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &object_skb_Anim_002190, 0.6f, 0.0f, 0.0f, ANIMMODE_ONCE_INTERP, 4.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0f }, + { &object_skb_Anim_00270C, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0f }, + { &object_skb_Anim_00697C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_006D90, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_001D1C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -16.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_0015EC, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_0009E4, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -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), @@ -95,122 +153,1005 @@ 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.z) < (arg0.x * arg1.z)) { + 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.z = this->unk_230[0].x - pos.x; + sp58.x = this->unk_230[1].z - pos.z; + sp58.z = 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.z = this->unk_230[i].x - pos.x; + sp58.x = this->unk_230[j].z - pos.z; + sp58.z = 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.actorLists[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, ActorShadow_DrawCircle, 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->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + 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.currentCsIndex == 0)) { + this->actor.flags |= ACTOR_FLAG_100000; + } -#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) { + Actor_ChangeAnimationByInfo(&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) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&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->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; + if (this->actor.colChkInfo.health != 0) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_402 |= 1; + func_80B712FC(this); + } else { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80B71488(this); + } + } else if (this->drawDmgEffTimer == 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->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; + if (this->actor.colChkInfo.health != 0) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_402 |= 1; + func_80B712FC(this); + } else { + SoundSource_PlaySfxAtFixedWorldPos(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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_ChangeAnimationByInfo(&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 { + Actor_ChangeAnimationByInfo(&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 &= ~ACTOR_FLAG_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 |= ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&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; + Actor_ChangeAnimationByInfo(&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) { + Actor_ChangeAnimationByInfo(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_3FE = 1; + func_80B71D8C(this, globalCtx, func_80B723F8); + if (!func_80B7285C(this)) { + Message_StartTextbox(globalCtx, 0x13EC, &this->actor); + this->unk_400 = 0x13EC; + func_80B72830(this, 1); + } else { + Message_StartTextbox(globalCtx, 0x13F5, &this->actor); + this->unk_400 = 0x13F5; + } + Actor_ChangeAnimationByInfo(&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 (Message_GetState(&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 (Message_ShouldAdvance(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) { + Actor_ChangeAnimationByInfo(&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->dyna.actor.world.pos); + f32 sp30 = Math_Vec3f_DistXZ(&this->actor.world.pos, &this->unk_22C->dyna.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_MoveWithGravity(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B726B4.s") +void func_80B71A08(EnRailSkb* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_ChangeAnimationByInfo(&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->dyna.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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + if (this->unk_2E8 < this->unk_22C->dyna.actor.colChkInfo.health) { + this->unk_22C->dyna.actor.colChkInfo.health--; + } else { + this->unk_22C->dyna.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->dyna.actor.colChkInfo.health) { + this->unk_22C->dyna.actor.colChkInfo.health--; + } else { + this->unk_22C->dyna.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; + Actor_ChangeAnimationByInfo(&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->dyna.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->dyna.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->dyna.actor.colChkInfo.health == 0)) { + Actor_MoveWithGravity(&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->dyna.actor.world.pos.x, 0.6f, 1.6f, 0.1f); + Math_SmoothStepToF(&this->actor.world.pos.z, this->unk_22C->dyna.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)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_ChangeAnimationByInfo(&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.actorLists[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 |= ACTOR_FLAG_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->drawDmgEffTimer > 1)) { + this->drawDmgEffTimer = 0; + } + + Actor_ChangeAnimationByInfo(&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 (Message_ShouldAdvance(globalCtx)) { + switch (this->unk_400) { + case 0x13EC: + Message_StartTextbox(globalCtx, 0x13ED, &this->actor); + this->unk_400 = 0x13ED; + break; + + case 0x13ED: + Message_StartTextbox(globalCtx, 0x13EE, &this->actor); + this->unk_400 = 0x13EE; + break; + + case 0x13EE: + Message_StartTextbox(globalCtx, 0x13EF, &this->actor); + this->unk_400 = 0x13EF; + break; + + case 0x13EF: + case 0x13F5: + Message_StartTextbox(globalCtx, 0x13F0, &this->actor); + this->unk_400 = 0x13F0; + break; + + case 0x13F1: + Message_StartTextbox(globalCtx, 0x13F2, &this->actor); + this->unk_400 = 0x13F2; + break; + + case 0x13F2: + if (this->unk_3FC == 1) { + Message_StartTextbox(globalCtx, 0x13F4, &this->actor); + this->unk_400 = 0x13F4; + } else { + func_801477B4(globalCtx); + func_80B71D8C(this, globalCtx, func_80B71650); + } + break; + + case 0x13F3: + Message_StartTextbox(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 (Message_ShouldAdvance(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + Message_StartTextbox(globalCtx, 0x13F1, &this->actor); + this->unk_400 = 0x13F1; + } else { + func_8019F208(); + Message_StartTextbox(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))) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&this->actor); + } +} + +void func_80B723F8(EnRailSkb* this) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.flags |= ACTOR_FLAG_100000; + 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->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; + } + + if (this->actionFunc != func_80B7114C) { + if (this->drawDmgEffTimer < 20) { + if (this->actionFunc == func_80B7123C) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.01f, 0.0f); + } + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 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->limbPos) - 1; + } else { + end = ARRAY_COUNT(this->limbPos); + } + + SoundSource_PlaySfxAtFixedWorldPos(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->limbPos[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->limbPos[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 &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.flags |= ACTOR_FLAG_100000; + this->actor.hintId = 0xFF; + this->actor.textId = 0; + func_80B71650(this); + } + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.flags &= ~ACTOR_FLAG_100000; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); + 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->drawDmgEffTimer >= 2) { + func_80B726B4(this, globalCtx); + } + this->drawDmgEffTimer = 0; + break; + } + } + + if ((Actor_ApplyDamage(&this->actor) == 0) && (this->actor.colChkInfo.damageEffect != 3) && + (this->actor.colChkInfo.damageEffect != 4)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80B71488(this); + return; + } + + switch (this->actor.colChkInfo.damageEffect) { + case 11: + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0, 120, 0, 40); + func_80B710AC(this); + break; + + case 1: + Actor_SetColorFilter(&this->actor, 0, 120, 0, 40); + func_80B710AC(this); + break; + + case 2: + this->drawDmgEffTimer = 80; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + this->unk_402 |= 1; + func_80B712FC(this); + break; + + case 3: + if (this->actor.colChkInfo.health != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->drawDmgEffTimer = 80; + } else { + this->drawDmgEffTimer = 3; + } + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + func_80B71114(this); + break; + + case 4: + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&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: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&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_MultVec3f(&sp24, &this->actor.focus.pos); + } else if ((limbIndex == 12) && (this->unk_3FA == 1)) { + Matrix_RotateZS(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)) { + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); + this->unk_402 |= 2; + } else if ((this->unk_402 & 0x40) && ((limbIndex != 11) || !(this->unk_402 & 1)) && (limbIndex != 12)) { + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); + } + + if (this->drawDmgEffTimer != 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_MultZero(&this->limbPos[this->limbCount]); + this->limbCount++; + } else if ((limbIndex == 11) && !(this->unk_402 & 2)) { + Matrix_MultVec3f(&D_80B734D0, &this->limbPos[this->limbCount]); + this->limbCount++; + } + } + } +} + +void EnRailSkb_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRailSkb* this = THIS; + + this->limbCount = 0; + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnRailSkb_OverrideLimbDraw, + EnRailSkb_PostLimbDraw, &this->actor); + if (this->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, this->limbCount, this->drawDmgEffScale, 0.5f, + this->drawDmgEffAlpha, this->drawDmgEffType); + } + + 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..6346eebe2 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 limbPos[14]; + /* 0x2DC */ s32 limbCount; + /* 0x2E0 */ s32 unk_2E0; + /* 0x2E4 */ s32 unk_2E4; + /* 0x2E8 */ s32 unk_2E8; + /* 0x2EC */ f32 drawDmgEffAlpha; + /* 0x2F0 */ f32 drawDmgEffScale; + /* 0x2F4 */ Vec3s jointTable[20]; + /* 0x36C */ Vec3s morphTable[20]; + /* 0x3E4 */ UNK_TYPE1 unk3E4[0xC]; + /* 0x3F0 */ s16 drawDmgEffTimer; + /* 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 drawDmgEffType; } 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 5f9fe203a..ba6043f52 100644 --- a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c +++ b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c @@ -5,8 +5,9 @@ */ #include "z_en_railgibud.h" +#include "objects/object_rd/object_rd.h" -#define FLAGS 0x00000415 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((EnRailgibud*)thisx) @@ -15,59 +16,71 @@ void EnRailgibud_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRailgibud_Update(Actor* thisx, GlobalContext* globalCtx); void EnRailgibud_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BA57A8(EnRailgibud* this); -void func_80BA57F8(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA59F0(EnRailgibud* this); -void func_80BA5A34(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA5AF0(EnRailgibud* this); -void func_80BA5B64(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA5DBC(EnRailgibud* this); -void func_80BA5E18(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6054(EnRailgibud* this); -void func_80BA60B0(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6158(EnRailgibud* this); -void func_80BA61A0(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6284(EnRailgibud* this); -void func_80BA62D4(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA64AC(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6604(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6664(EnRailgibud* this); -void func_80BA66C8(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA6974(GlobalContext* globalCtx, Vec3f* vec, f32 arg2, s32 arg3, s16 arg4, s16 arg5); -void func_80BA6B9C(EnRailgibud* this, GlobalContext* globalCtx); -s32 func_80BA6D10(EnRailgibud* this, GlobalContext* globalCtx); -s32 func_80BA6DAC(EnRailgibud* this, GlobalContext* globalCtx); -s32 func_80BA7088(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA7578(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA7878(Actor* thisx, GlobalContext* globalCtx); -void func_80BA7B6C(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA7C78(EnRailgibud* this); -void func_80BA7CF0(EnRailgibud* this); -void func_80BA7D04(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA7D30(EnRailgibud* this, GlobalContext* globalCtx); -void func_80BA8050(Actor* thisx, GlobalContext* globalCtx); +void EnRailgibud_SetupWalkInCircles(EnRailgibud* this); +void EnRailgibud_WalkInCircles(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupAttemptPlayerFreeze(EnRailgibud* this); +void EnRailgibud_AttemptPlayerFreeze(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupWalkToPlayer(EnRailgibud* this); +void EnRailgibud_WalkToPlayer(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupGrab(EnRailgibud* this); +void EnRailgibud_Grab(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupGrabFail(EnRailgibud* this); +void EnRailgibud_GrabFail(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupTurnAwayAndShakeHead(EnRailgibud* this); +void EnRailgibud_TurnAwayAndShakeHead(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupWalkToHome(EnRailgibud* this); +void EnRailgibud_WalkToHome(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_Damage(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_Stunned(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SetupDead(EnRailgibud* this); +void EnRailgibud_Dead(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SpawnDust(GlobalContext* globalCtx, Vec3f* vec, f32 arg2, s32 arg3, s16 arg4, s16 arg5); +void EnRailgibud_TurnTowardsPlayer(EnRailgibud* this, GlobalContext* globalCtx); +s32 EnRailgibud_PlayerInRangeWithCorrectState(EnRailgibud* this, GlobalContext* globalCtx); +s32 EnRailgibud_PlayerOutOfRange(EnRailgibud* this, GlobalContext* globalCtx); +s32 EnRailgibud_MoveToIdealGrabPositionAndRotation(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_CheckIfTalkingToPlayer(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_MainGibdo_DeadUpdate(Actor* thisx, GlobalContext* globalCtx); +void EnRailgibud_InitCutsceneGibdo(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_InitActorActionCommand(EnRailgibud* this); +void EnRailgibud_SetupDoNothing(EnRailgibud* this); +void EnRailgibud_DoNothing(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_SinkIntoGround(EnRailgibud* this, GlobalContext* globalCtx); +void EnRailgibud_Cutscene_Update(Actor* thisx, GlobalContext* globalCtx); -extern AnimationHeader D_060009C4; -extern AnimationHeader D_06000F1C; -extern AnimationHeader D_06001600; -extern FlexSkeletonHeader D_060053E8; -extern AnimationHeader D_06005DF4; -extern AnimationHeader D_060061E4; -extern AnimationHeader D_06006678; -extern AnimationHeader D_06006B08; -extern AnimationHeader D_06006EEC; -extern AnimationHeader D_060073A4; -extern AnimationHeader D_06007BBC; -extern AnimationHeader D_060081A8; -extern AnimationHeader D_06009298; -extern AnimationHeader D_06009900; -extern AnimationHeader D_0600A450; -extern AnimationHeader D_0600ABE0; -extern FlexSkeletonHeader D_06010B88; -extern AnimationHeader D_060113EC; -extern AnimationHeader D_060118D8; -extern AnimationHeader D_06011DB8; -extern AnimationHeader D_0601216C; +typedef enum { + /* 0 */ EN_RAILGIBUD_ANIMATION_GRAB_ATTACK, + /* 1 */ EN_RAILGIBUD_ANIMATION_GRAB_END, + /* 2 */ EN_RAILGIBUD_ANIMATION_GRAB_START, + /* 3 */ EN_RAILGIBUD_ANIMATION_LOOK_BACK, + /* 4 */ EN_RAILGIBUD_ANIMATION_CROUCH_WIPING_TEARS, + /* 5 */ EN_RAILGIBUD_ANIMATION_CROUCH_CRYING, + /* 6 */ EN_RAILGIBUD_ANIMATION_DEATH, + /* 7 */ EN_RAILGIBUD_ANIMATION_DAMAGE, + /* 8 */ EN_RAILGIBUD_ANIMATION_CROUCH_END, + /* 9 */ EN_RAILGIBUD_ANIMATION_IDLE, + /* 10 */ EN_RAILGIBUD_ANIMATION_WALK, + /* 11 */ EN_RAILGIBUD_ANIMATION_DANCE_SQUAT, + /* 12 */ EN_RAILGIBUD_ANIMATION_DANCE_PIROUETTE, + /* 13 */ EN_RAILGIBUD_ANIMATION_DANCE_CLAP, + /* 14 */ EN_RAILGIBUD_ANIMATION_CROUCH_END_2, + /* 15 */ EN_RAILGIBUD_ANIMATION_SLUMP_START, + /* 16 */ EN_RAILGIBUD_ANIMATION_SLUMP_LOOP, + /* 17 */ EN_RAILGIBUD_ANIMATION_CONVULSION, + /* 18 */ EN_RAILGIBUD_ANIMATION_ARMS_UP_START, + /* 19 */ EN_RAILGIBUD_ANIMATION_ARMS_UP_LOOP, +} EnRailgibudAnimations; + +typedef enum { + /* 0 */ EN_RAILGIBUD_TYPE_GIBDO, + /* 1 */ EN_RAILGIBUD_TYPE_REDEAD, +} EnRailgibudType; + +typedef enum { + /* 0 */ EN_RAILGIBUD_GRAB_START, + /* 1 */ EN_RAILGIBUD_GRAB_ATTACK, + /* 2 */ EN_RAILGIBUD_GRAB_RELEASE, +} EnRailgibudGrabState; const ActorInit En_Railgibud_InitVars = { ACTOR_EN_RAILGIBUD, @@ -81,17 +94,27 @@ const ActorInit En_Railgibud_InitVars = { (ActorFunc)EnRailgibud_Draw, }; -static ActorAnimationEntry sAnimations[] = { - { &D_06006678, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &D_06006B08, 0.5f, 0.0f, 0.0f, 3, 0.0f }, - { &D_06006EEC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_060073A4, 0.0f, 0.0f, 0.0f, 2, -8.0f }, - { &D_06007BBC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_060081A8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_06009298, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_06009900, 1.0f, 0.0f, 0.0f, 2, -8.0f }, - { &D_0600A450, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_0600ABE0, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_060113EC, 0.4f, 0.0f, 0.0f, 1, -8.0f }, { &D_0601216C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_060118D8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &D_06011DB8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_0600A450, 3.0f, 0.0f, 0.0f, 2, -6.0f }, { &D_06005DF4, 1.0f, 0.0f, 0.0f, 2, -8.0f }, - { &D_060061E4, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &D_06001600, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_060009C4, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_06000F1C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, +static AnimationInfo sAnimations[] = { + { &gGibdoRedeadGrabAttackAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadGrabEndAnim, 0.5f, 0.0f, 0.0f, ANIMMODE_ONCE_INTERP, 0.0f }, + { &gGibdoRedeadGrabStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadWipingTearsAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadSobbingAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadDeathAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadDamageAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadStandUpAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadWalkAnim, 0.4f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -8.0f }, + { &gGibdoRedeadSquattingDanceAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadPirouetteAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadClappingDanceAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadStandUpAnim, 3.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -6.0f }, + { &gGibdoRedeadSlumpStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadSlumpLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadConvulsionAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadArmsUpStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadArmsUpLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, }; static ColliderCylinderInit sCylinderInit = { @@ -114,76 +137,98 @@ static ColliderCylinderInit sCylinderInit = { { 20, 70, 0, { 0, 0, 0 } }, }; +typedef enum { + /* 0x0 */ EN_RAILGIBUD_DMGEFF_NONE, // Does not interact with the Gibdo/Redead at all + /* 0x1 */ EN_RAILGIBUD_DMGEFF_STUN, // Stuns without applying any effect + /* 0x2 */ EN_RAILGIBUD_DMGEFF_FIRE_ARROW, // Damages, applies a fire effect, and changes a Gibdo into a Redead + /* 0x4 */ EN_RAILGIBUD_DMGEFF_LIGHT_ARROW = 0x4, // Damages and applies a light effect + /* 0xC */ EN_RAILGIBUD_DMGEFF_ZORA_MAGIC = 0xC, // Stuns and applies an electric effect + /* 0xD */ EN_RAILGIBUD_DMGEFF_RECOIL, // Deals no damage, but displays hit mark and recoil animation + /* 0xE */ EN_RAILGIBUD_DMGEFF_LIGHT_RAY, // Instantly kills a Redead on contact + /* 0xF */ EN_RAILGIBUD_DMGEFF_DAMAGE, // Deals damage and plays the damage animation +} EnRailgibudDamageEffect; + static DamageTable sDamageTable = { - /* 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), + /* Deku Nut */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(2, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Horse trample */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Zora boomerang */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_RECOIL), + /* Normal arrow */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_RECOIL), + /* UNK_DMG_0x06 */ DMG_ENTRY(2, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Hookshot */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_RECOIL), + /* Goron punch */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Sword */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Goron pound */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Fire arrow */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_RECOIL), + /* Light arrow */ DMG_ENTRY(2, EN_RAILGIBUD_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Deku spin */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_RECOIL), + /* Deku launch */ DMG_ENTRY(2, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_LIGHT_RAY), + /* Thrown object */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Zora punch */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Spin attack */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), + /* Sword beam */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_RAILGIBUD_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_RAILGIBUD_DMGEFF_DAMAGE), }; static CollisionCheckInfoInit2 sColChkInfoInit = { 8, 0, 0, 0, MASS_IMMOVABLE }; -void func_80BA5400(EnRailgibud* this, GlobalContext* globalCtx) { - static s32 D_80BA82F8 = 0; - s32 phi_a3; - Vec3f sp70; - Path* path = &globalCtx->setupPathList[ENRAILGIBUD_GET_FF00(&this->actor)]; +/** + * The design behind this actor is that scene files should only spawn a single "main" Gibdo + * who then spawns all the other Gibdos. It spawns enough Gibdos for one to exist on every + * point along the path up to a maximum of nine additional Gibdos (not counting itself). + */ +void EnRailgibud_SpawnOtherGibdosAndSetPositionAndRotation(EnRailgibud* this, GlobalContext* globalCtx) { + static s32 currentGibdoIndex = 0; + s32 nextPoint; + Vec3f targetPos; + Path* path = &globalCtx->setupPathList[ENRAILGIBUD_GET_PATH(&this->actor)]; - this->unk_294 = Lib_SegmentedToVirtual(path->points); - this->unk_298 = D_80BA82F8; - this->unk_29C = path->count; - if (D_80BA82F8 == 0) { + this->points = Lib_SegmentedToVirtual(path->points); + this->currentPoint = currentGibdoIndex; + this->pathCount = path->count; + + // This branch will only be taken for the first, "main" Gibdo. The subsequent + // Gibdos created by Actor_SpawnAsChild will go through this function to set + // their position and rotation, but they will not be able to spawn any more + // Gibdos themselves because currentGibdoIndex will be non-zero. + if (currentGibdoIndex == 0) { s32 i; - for (i = 1; i < this->unk_29C && i < 10; i++) { - D_80BA82F8++; + for (i = 1; i < this->pathCount && i < 10; i++) { + currentGibdoIndex++; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_RAILGIBUD, 0.0f, 0.0f, 0.0f, 0, 0, 0, this->actor.params); } - D_80BA82F8 = 0; + + currentGibdoIndex = 0; } - this->actor.world.pos.x = this->unk_294[this->unk_298].x; - this->actor.world.pos.y = this->unk_294[this->unk_298].y; - this->actor.world.pos.z = this->unk_294[this->unk_298].z; - if (this->unk_298 < (this->unk_29C - 1)) { - phi_a3 = this->unk_298 + 1; + this->actor.world.pos.x = this->points[this->currentPoint].x; + this->actor.world.pos.y = this->points[this->currentPoint].y; + this->actor.world.pos.z = this->points[this->currentPoint].z; + if (this->currentPoint < (this->pathCount - 1)) { + nextPoint = this->currentPoint + 1; } else { - phi_a3 = 0; + nextPoint = 0; } - sp70.x = this->unk_294[phi_a3].x; - sp70.y = this->unk_294[phi_a3].y; - sp70.z = this->unk_294[phi_a3].z; - this->actor.world.rot.y = this->actor.shape.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp70); + targetPos.x = this->points[nextPoint].x; + targetPos.y = this->points[nextPoint].y; + targetPos.z = this->points[nextPoint].z; + this->actor.world.rot.y = this->actor.shape.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &targetPos); this->actor.home = this->actor.world; } @@ -202,33 +247,34 @@ void EnRailgibud_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.targetMode = 0; this->actor.hintId = 0x2D; this->actor.textId = 0; - if (ENRAILGIBUD_GET_80(&this->actor)) { - func_80BA7B6C(this, globalCtx); + if (ENRAILGIBUD_IS_CUTSCENE_TYPE(&this->actor)) { + EnRailgibud_InitCutsceneGibdo(this, globalCtx); return; } - func_80BA5400(this, globalCtx); - this->unk_3F2 = 0; - this->unk_402 = gSaveContext.time; - this->unk_404 = 0; - this->unk_3F8 = 0; - this->unk_400 = 0; - this->unk_3FA = 0; + EnRailgibud_SpawnOtherGibdosAndSetPositionAndRotation(this, globalCtx); + this->playerStunWaitTimer = 0; + this->timeInitialized = gSaveContext.save.time; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->type = EN_RAILGIBUD_TYPE_GIBDO; + this->textId = 0; + this->isInvincible = false; if (this->actor.parent == NULL) { - this->unk_3EC = 1; - this->unk_3EE = 1; + this->shouldWalkForward = true; + this->shouldWalkForwardNextFrame = true; } - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 28.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060053E8, &D_0600ABE0, this->jointTable, this->morphTable, 26); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGibdoSkel, &gGibdoRedeadIdleAnim, this->jointTable, + this->morphTable, GIBDO_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - if (gSaveContext.weekEventReg[14] & 4) { + if (gSaveContext.save.weekEventReg[14] & 4) { Actor_MarkForDeath(&this->actor); } - func_80BA57A8(this); + EnRailgibud_SetupWalkInCircles(this); } void EnRailgibud_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -237,173 +283,183 @@ void EnRailgibud_Destroy(Actor* thisx, GlobalContext* globalCtx) { Collider_DestroyCylinder(globalCtx, &this->collider); } -void func_80BA57A8(EnRailgibud* this) { +void EnRailgibud_SetupWalkInCircles(EnRailgibud* this) { this->actor.speedXZ = 0.6f; - func_800BDC5C(&this->skelAnime, sAnimations, 10); - this->actionFunc = func_80BA57F8; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_WALK); + this->actionFunc = EnRailgibud_WalkInCircles; } -void func_80BA57F8(EnRailgibud* this, GlobalContext* globalCtx) { - Vec3f sp3C; +void EnRailgibud_WalkInCircles(EnRailgibud* this, GlobalContext* globalCtx) { + Vec3f targetPos; s32 pad; - s16 sp36; + s16 yRotation; - sp3C.x = this->unk_294[this->unk_298].x; - sp3C.y = this->unk_294[this->unk_298].y; - sp3C.z = this->unk_294[this->unk_298].z; + targetPos.x = this->points[this->currentPoint].x; + targetPos.y = this->points[this->currentPoint].y; + targetPos.z = this->points[this->currentPoint].z; if ((this->actor.xzDistToPlayer <= 100.0f) && func_800B715C(globalCtx) && - (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO_MASK)) { + (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO)) { this->actor.home = this->actor.world; - func_80BA59F0(this); + EnRailgibud_SetupAttemptPlayerFreeze(this); } - Math_SmoothStepToS(&this->unk_3E2, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_3E8, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 0x64, 0); + // If we're not supposed to walk forward, then stop here; + // don't rotate the Gibdo or move it around. if (this->actor.parent == NULL) { - if (this->unk_3EC != 0) { + if (this->shouldWalkForward) { } else { return; } } else { EnRailgibud* parent = (EnRailgibud*)this->actor.parent; - if (parent->unk_3EC == 0) { + if (!parent->shouldWalkForward) { return; } } - sp36 = Math_Vec3f_Yaw(&this->actor.world.pos, &sp3C); - if (Math_Vec3f_DistXZ(&this->actor.world.pos, &sp3C) > 60.0f) { - Math_SmoothStepToS(&this->actor.world.rot.y, sp36, 1, 0x190, 0xA); + yRotation = Math_Vec3f_Yaw(&this->actor.world.pos, &targetPos); + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &targetPos) > 60.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, yRotation, 1, 0x190, 0xA); this->actor.shape.rot.y = this->actor.world.rot.y; - } else if (this->unk_298 < (this->unk_29C - 1)) { - this->unk_298++; + } else if (this->currentPoint < (this->pathCount - 1)) { + this->currentPoint++; } else { - this->unk_298 = 0; + this->currentPoint = 0; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + Actor_MoveWithGravity(&this->actor); } -void func_80BA59F0(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 9); - this->actionFunc = func_80BA5A34; +void EnRailgibud_SetupAttemptPlayerFreeze(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_IDLE); + this->actionFunc = EnRailgibud_AttemptPlayerFreeze; } -void func_80BA5A34(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_AttemptPlayerFreeze(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - s16 rot = this->actor.shape.rot.y + this->unk_3E2 + this->unk_3E8; + s16 rot = this->actor.shape.rot.y + this->headRotation.y + this->upperBodyRotation.y; s16 yaw = BINANG_SUB(this->actor.yawTowardsPlayer, rot); 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); - func_80BA5AF0(this); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); + EnRailgibud_SetupWalkToPlayer(this); } - func_80BA6B9C(this, globalCtx); + + EnRailgibud_TurnTowardsPlayer(this, globalCtx); } -void func_80BA5AF0(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 10); +void EnRailgibud_SetupWalkToPlayer(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_WALK); this->actor.speedXZ = 0.4f; - if (this->actionFunc == func_80BA5A34) { - this->unk_3F2 = 80; + + if (this->actionFunc == EnRailgibud_AttemptPlayerFreeze) { + this->playerStunWaitTimer = 80; } else { - this->unk_3F2 = 20; + this->playerStunWaitTimer = 20; } - this->actionFunc = func_80BA5B64; + + this->actionFunc = EnRailgibud_WalkToPlayer; } -void func_80BA5B64(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_WalkToPlayer(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 pad; Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xFA); this->actor.world.rot = this->actor.shape.rot; - Math_SmoothStepToS(&this->unk_3E2, 0, 1, 0x64, 0); - Math_SmoothStepToS(&this->unk_3E8, 0, 1, 0x64, 0); - if (func_80BA6D10(this, globalCtx) && Actor_IsActorFacingLink(&this->actor, 0x38E3)) { - if ((this->unk_3F4 == 0) && (this->actor.xzDistToPlayer <= 45.0f)) { + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 0x64, 0); + + if (EnRailgibud_PlayerInRangeWithCorrectState(this, globalCtx) && Actor_IsFacingPlayer(&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)) { - func_80BA6054(this); + if ((gSaveContext.save.playerForm == PLAYER_FORM_GORON) || + (gSaveContext.save.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. + EnRailgibud_SetupGrabFail(this); } else if (globalCtx->grabPlayer(globalCtx, player)) { - func_80BA5DBC(this); + EnRailgibud_SetupGrab(this); } } else { - if (this->unk_3F2 == 0) { + if (this->playerStunWaitTimer == 0) { player->actor.freezeTimer = 40; - this->unk_3F2 = 60; + 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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); } else { - this->unk_3F2--; + this->playerStunWaitTimer--; } } - } else if ((this->unk_3F4 == 0) && (this->actor.xzDistToPlayer <= 45.0f)) { - func_80BA6284(this); - } else if (func_80BA6DAC(this, globalCtx)) { - func_80BA6284(this); + } else if ((this->grabWaitTimer == 0) && (this->actor.xzDistToPlayer <= 45.0f)) { + EnRailgibud_SetupWalkToHome(this); + } else if (EnRailgibud_PlayerOutOfRange(this, globalCtx)) { + EnRailgibud_SetupWalkToHome(this); } - if (this->unk_3F4 > 0) { - this->unk_3F4--; + if (this->grabWaitTimer > 0) { + this->grabWaitTimer--; } 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 & 95) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); + } else if (!(globalCtx->gameplayFrames & 95)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_80BA5DBC(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 2); - this->actor.flags &= ~1; - this->unk_3F2 = 0; - this->unk_3F0 = 0; - this->actionFunc = func_80BA5E18; +void EnRailgibud_SetupGrab(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_GRAB_START); + this->grabDamageTimer = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->grabState = EN_RAILGIBUD_GRAB_START; + this->actionFunc = EnRailgibud_Grab; } -void func_80BA5E18(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_Grab(EnRailgibud* this, GlobalContext* globalCtx) { Player* player2 = GET_PLAYER(globalCtx); Player* player = player2; - s32 sp34; - u16 sp32; + s32 inPositionToAttack; + u16 damageSfxId; - switch (this->unk_3F0) { - case 0: - sp34 = func_80BA7088(this, globalCtx); - if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (sp34 == 1)) { - this->unk_3F0 = 1; - func_800BDC5C(&this->skelAnime, sAnimations, 0); + switch (this->grabState) { + case EN_RAILGIBUD_GRAB_START: + inPositionToAttack = EnRailgibud_MoveToIdealGrabPositionAndRotation(this, globalCtx); + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (inPositionToAttack == true)) { + this->grabState = EN_RAILGIBUD_GRAB_ATTACK; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_GRAB_ATTACK); } else if (!(player->stateFlags2 & 0x80)) { - func_800BDC5C(&this->skelAnime, sAnimations, 1); - this->actor.flags |= 1; - this->unk_3F0 = 2; - this->unk_3F2 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_GRAB_END); + this->actor.flags |= ACTOR_FLAG_1; + this->grabState = EN_RAILGIBUD_GRAB_RELEASE; + this->grabDamageTimer = 0; } break; - case 1: - if (this->unk_3F2 == 20) { + case EN_RAILGIBUD_GRAB_ATTACK: + if (this->grabDamageTimer == 20) { s16 requiredScopeTemp; - sp32 = player->ageProperties->unk_92 + 0x6805; + damageSfxId = player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S; globalCtx->damagePlayer(globalCtx, -8); - func_800B8E58(&player->actor, sp32); + func_800B8E58(player, damageSfxId); func_8013ECE0(this->actor.xzDistToPlayer, 240, 1, 12); - this->unk_3F2 = 0; + this->grabDamageTimer = 0; } else { - this->unk_3F2++; + this->grabDamageTimer++; } if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_ATTACK); } if (!(player->stateFlags2 & 0x80) || (player->unk_B62 != 0)) { @@ -411,18 +467,19 @@ void func_80BA5E18(EnRailgibud* this, GlobalContext* globalCtx) { player->stateFlags2 &= ~0x80; player->unk_AE8 = 100; } - func_800BDC5C(&this->skelAnime, sAnimations, 1); - this->actor.flags |= 1; - this->unk_3F0 = 2; - this->unk_3F2 = 0; + + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_GRAB_END); + this->actor.flags |= ACTOR_FLAG_1; + this->grabState = EN_RAILGIBUD_GRAB_RELEASE; + this->grabDamageTimer = 0; } break; - case 2: + case EN_RAILGIBUD_GRAB_RELEASE: if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - this->unk_3F4 = 40; + this->grabWaitTimer = 40; this->actor.shape.yOffset = 0.0f; - func_80BA5AF0(this); + EnRailgibud_SetupWalkToPlayer(this); } else { Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); } @@ -430,88 +487,90 @@ void func_80BA5E18(EnRailgibud* this, GlobalContext* globalCtx) { } } -void func_80BA6054(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 7); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); +void EnRailgibud_SetupGrabFail(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); this->actor.speedXZ = -2.0f; - this->actionFunc = func_80BA60B0; + this->actionFunc = EnRailgibud_GrabFail; } -void func_80BA60B0(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_GrabFail(EnRailgibud* 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->unk_3E2, 0, 1, 0x12C, 0); - Math_SmoothStepToS(&this->unk_3E8, 0, 1, 0x12C, 0); + 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; - func_80BA6158(this); + EnRailgibud_SetupTurnAwayAndShakeHead(this); } } -void func_80BA6158(EnRailgibud* this) { - this->unk_3F2 = 0; - func_800BDC5C(&this->skelAnime, sAnimations, 10); - this->actionFunc = func_80BA61A0; +void EnRailgibud_SetupTurnAwayAndShakeHead(EnRailgibud* this) { + this->headShakeTimer = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_WALK); + this->actionFunc = EnRailgibud_TurnAwayAndShakeHead; } -void func_80BA61A0(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_TurnAwayAndShakeHead(EnRailgibud* 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->unk_3F2 > 60) { - func_80BA6284(this); - this->unk_3F2 = 0; + if (this->headShakeTimer > 60) { + EnRailgibud_SetupWalkToHome(this); + this->playerStunWaitTimer = 0; } else { - this->unk_3E2 = Math_SinS(this->unk_3F2 * 0xFA0) * (0x256F * ((60 - this->unk_3F2) / 60.0f)); - this->unk_3F2++; + this->headRotation.y = + Math_SinS(this->headShakeTimer * 4000) * (0x256F * ((60 - this->headShakeTimer) / 60.0f)); + this->headShakeTimer++; } } -void func_80BA6284(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 10); +void EnRailgibud_SetupWalkToHome(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_WALK); this->actor.speedXZ = 0.4f; - this->actionFunc = func_80BA62D4; + this->actionFunc = EnRailgibud_WalkToHome; } -void func_80BA62D4(EnRailgibud* this, GlobalContext* globalCtx) { - Math_SmoothStepToS(&this->unk_3E2, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3E8, 0, 1, 100, 0); +void EnRailgibud_WalkToHome(EnRailgibud* 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) { - func_80BA57A8(this); + EnRailgibud_SetupWalkInCircles(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 (func_80BA6D10(this, globalCtx)) { - if ((gSaveContext.playerForm != PLAYER_FORM_GORON) && (gSaveContext.playerForm != PLAYER_FORM_DEKU) && - Actor_IsActorFacingLink(&this->actor, 0x38E3)) { - func_80BA5AF0(this); + if (EnRailgibud_PlayerInRangeWithCorrectState(this, globalCtx)) { + if ((gSaveContext.save.playerForm != PLAYER_FORM_GORON) && (gSaveContext.save.playerForm != PLAYER_FORM_DEKU) && + Actor_IsFacingPlayer(&this->actor, 0x38E3)) { + EnRailgibud_SetupWalkToPlayer(this); } } } -void func_80BA6440(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 7); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); - this->unk_3F2 = 0; - this->unk_3F4 = 0; +void EnRailgibud_SetupDamage(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->stunTimer = 0; + this->grabWaitTimer = 0; this->actor.world.rot.y = this->actor.yawTowardsPlayer; this->actor.speedXZ = -2.0f; - this->actionFunc = func_80BA64AC; + this->actionFunc = EnRailgibud_Damage; } -void func_80BA64AC(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_Damage(EnRailgibud* this, GlobalContext* globalCtx) { if (this->actor.speedXZ < 0.0f) { this->actor.speedXZ += 0.15f; } @@ -519,57 +578,66 @@ void func_80BA64AC(EnRailgibud* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { this->unk_405 = -1; this->actor.world.rot.y = this->actor.shape.rot.y; - if ((this->unk_3F6 > 0) && (this->unk_404 == 0) && (this->unk_3F8 == 0)) { + if ((this->drawDmgEffTimer > 0) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) && + (this->type == EN_RAILGIBUD_TYPE_GIBDO)) { this->actor.hintId = 0x2A; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06010B88, NULL, this->jointTable, this->morphTable, 26); - this->unk_3F8 = 1; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gRedeadSkel, NULL, this->jointTable, this->morphTable, + GIBDO_LIMB_MAX); + this->type = EN_RAILGIBUD_TYPE_REDEAD; } - func_80BA6284(this); + + EnRailgibud_SetupWalkToHome(this); } } -void func_80BA6584(EnRailgibud* this) { +void EnRailgibud_SetupStunned(EnRailgibud* this) { this->actor.world.rot.y = this->actor.shape.rot.y; - this->unk_3F2 = 10; - if (this->unk_3F6 != 0) { - func_800BCB70(&this->actor, 0, 0xC8, 0, 0x28); + this->stunTimer = 10; + + if (this->drawDmgEffTimer != 0) { + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x28); } else { - func_800BCB70(&this->actor, 0, 0xC8, 0, 0x28); + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x28); } - this->actionFunc = func_80BA6604; + + this->actionFunc = EnRailgibud_Stunned; } -void func_80BA6604(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_Stunned(EnRailgibud* this, GlobalContext* globalCtx) { if (this->actor.colorFilterTimer == 0) { if (this->actor.colChkInfo.health == 0) { - func_80BA6664(this); + EnRailgibud_SetupDead(this); } else { - func_80BA6440(this); + EnRailgibud_SetupDamage(this); } } - if (this->unk_3F2 != 0) { - this->unk_3F2--; + if (this->stunTimer != 0) { + this->stunTimer--; } } -void func_80BA6664(EnRailgibud* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 6); - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DEAD); - this->unk_3F2 = 0; - this->actionFunc = func_80BA66C8; +void EnRailgibud_SetupDead(EnRailgibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_DEATH); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DEAD); + this->deathTimer = 0; + this->actionFunc = EnRailgibud_Dead; } -void func_80BA66C8(EnRailgibud* this, GlobalContext* globalCtx) { - if (this->unk_3F2 > 300) { +void EnRailgibud_Dead(EnRailgibud* this, GlobalContext* globalCtx) { + if (this->deathTimer > 300) { if (this->actor.shape.shadowAlpha == 0) { if (this->actor.parent != NULL) { Actor_MarkForDeath(&this->actor); } else { + // Don't delete the "main" Gibdo, since that will break the surviving + // Gibdos' ability to start and stop walking forward. Instead, just + // stop drawing it, and make its Update function only check to see if + // the Gibdos should move forward. this->actor.draw = NULL; - this->actor.flags &= ~1; - this->actor.update = func_80BA7878; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.update = EnRailgibud_MainGibdo_DeadUpdate; } } else { this->actor.shape.shadowAlpha -= 5; @@ -578,106 +646,124 @@ void func_80BA66C8(EnRailgibud* this, GlobalContext* globalCtx) { } } } else { - Math_SmoothStepToS(&this->unk_3E2, 0, 1, 250, 0); - Math_SmoothStepToS(&this->unk_3E8, 0, 1, 250, 0); - this->unk_3F2++; + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 250, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 250, 0); + this->deathTimer++; } - if ((this->unk_3F2 == 20) && (this->unk_3F6 > 0) && (this->unk_404 == 0) && (this->unk_3F8 == 0)) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06010B88, NULL, this->jointTable, this->morphTable, 26); - this->unk_3F8 = 1; + if ((this->deathTimer == 20) && (this->drawDmgEffTimer > 0) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) && + (this->type == EN_RAILGIBUD_TYPE_GIBDO)) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gRedeadSkel, NULL, this->jointTable, this->morphTable, + GIBDO_LIMB_MAX); + this->type = EN_RAILGIBUD_TYPE_REDEAD; } } -void func_80BA6800(EnRailgibud* 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 }; +void EnRailgibud_SpawnEffectsForSinkingIntoTheGround(EnRailgibud* this, GlobalContext* globalCtx, s32 arg2) { + Vec3f rockFragmentPos = this->actor.world.pos; + Vec3f rockFragmentVelocity = { 0.0f, 8.0f, 0.0f }; + Vec3f rockFragmentAccel = { 0.0f, -1.5f, 0.0f }; s16 rand; s32 pad; if ((globalCtx->gameplayFrames & arg2) == 0) { rand = Rand_Next(); - sp5C.x += 15.0f * Math_SinS(rand); - sp5C.z += 15.0f * Math_CosS(rand); - 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_80BA6974(globalCtx, &sp5C, 10.0f, 10, 150, 0); + rockFragmentPos.x += 15.0f * Math_SinS(rand); + rockFragmentPos.z += 15.0f * Math_CosS(rand); + rockFragmentAccel.x = Rand_Centered(); + rockFragmentAccel.z = Rand_Centered(); + rockFragmentVelocity.y += Rand_Centered() * 4.0f; + EffectSsHahen_Spawn(globalCtx, &rockFragmentPos, &rockFragmentVelocity, &rockFragmentAccel, 0, + (Rand_Next() & 7) + 10, -1, 10, NULL); + EnRailgibud_SpawnDust(globalCtx, &rockFragmentPos, 10.0f, 10, 150, 0); } } -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; +void EnRailgibud_SpawnDust(GlobalContext* globalCtx, Vec3f* basePos, f32 randomnessScale, s32 dustCount, s16 dustScale, + s16 scaleStep) { + Vec3f dustPos; + Vec3f dustAccel = { 0.0f, 0.3f, 0.0f }; + Vec3f dustVelocity = gZeroVec3f; s32 i; s32 pad; - sp74.y = 2.5f; + dustVelocity.y = 2.5f; - for (i = arg3; i >= 0; i--) { - sp74.x = (Rand_ZeroOne() - 0.5f) * arg2; - sp74.z = (Rand_ZeroOne() - 0.5f) * arg2; + for (i = dustCount; i >= 0; i--) { + dustVelocity.x = (Rand_ZeroOne() - 0.5f) * randomnessScale; + dustVelocity.z = (Rand_ZeroOne() - 0.5f) * randomnessScale; - sp8C.x = vec->x + sp74.x; - sp8C.y = ((Rand_ZeroOne() - 0.5f) * arg2) + vec->y; - sp8C.z = vec->z + sp74.z; + dustPos.x = basePos->x + dustVelocity.x; + dustPos.y = ((Rand_ZeroOne() - 0.5f) * randomnessScale) + basePos->y; + dustPos.z = basePos->z + dustVelocity.z; - sp74.x *= 0.5f; - sp74.z *= 0.5f; - func_800B1210(globalCtx, &sp8C, &sp74, &sp80, (s16)(Rand_ZeroOne() * arg4 * 0.2f) + arg4, arg5); + dustVelocity.x *= 0.5f; + dustVelocity.z *= 0.5f; + func_800B1210(globalCtx, &dustPos, &dustVelocity, &dustAccel, + (s16)(Rand_ZeroOne() * dustScale * 0.2f) + dustScale, scaleStep); } } -void func_80BA6B30(EnRailgibud* this) { +/** + * If any Gibdo in the ring of Gibdos is doing any other action besides walking in + * circles or being dead, then this function will update the "main" Gibdo's + * walking forward variables such that all Gibdos in the ring will stop moving. + * Similarly, this will make all Gibdos in the ring start walking forward again + * if the Gibdos are all performing the appropriate action. + */ +void EnRailgibud_UpdateWalkForwardState(EnRailgibud* this) { if (this->actor.parent == NULL) { - this->unk_3EC = this->unk_3EE; - this->unk_3EE = 1; - if ((this->actionFunc != func_80BA57F8) && (this->actionFunc != func_80BA66C8)) { - this->unk_3EE = 0; + this->shouldWalkForward = this->shouldWalkForwardNextFrame; + this->shouldWalkForwardNextFrame = true; + if ((this->actionFunc != EnRailgibud_WalkInCircles) && (this->actionFunc != EnRailgibud_Dead)) { + this->shouldWalkForwardNextFrame = false; } - } else if ((this->actionFunc != func_80BA57F8) && (this->actionFunc != func_80BA66C8)) { - ((EnRailgibud*)this->actor.parent)->unk_3EE = 0; + } else if ((this->actionFunc != EnRailgibud_WalkInCircles) && (this->actionFunc != EnRailgibud_Dead)) { + ((EnRailgibud*)this->actor.parent)->shouldWalkForwardNextFrame = false; } } -void func_80BA6B9C(EnRailgibud* this, GlobalContext* globalCtx) { - s16 temp_v0 = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3E8; - s16 phi_a2 = CLAMP(temp_v0, -500, 500); +void EnRailgibud_TurnTowardsPlayer(EnRailgibud* this, GlobalContext* globalCtx) { + s16 headAngle = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->upperBodyRotation.y; + s16 upperBodyAngle = CLAMP(headAngle, -500, 500); - temp_v0 -= this->unk_3E2; - temp_v0 = CLAMP(temp_v0, -500, 500); + headAngle -= this->headRotation.y; + headAngle = CLAMP(headAngle, -500, 500); if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y) >= 0) { - this->unk_3E8 += ABS_ALT(phi_a2); - this->unk_3E2 += ABS_ALT(temp_v0); + this->upperBodyRotation.y += ABS_ALT(upperBodyAngle); + this->headRotation.y += ABS_ALT(headAngle); } else { - this->unk_3E8 -= ABS_ALT(phi_a2); - this->unk_3E2 -= ABS_ALT(temp_v0); + this->upperBodyRotation.y -= ABS_ALT(upperBodyAngle); + this->headRotation.y -= ABS_ALT(headAngle); } - this->unk_3E8 = CLAMP(this->unk_3E8, -0x495F, 0x495F); - this->unk_3E2 = CLAMP(this->unk_3E2, -0x256F, 0x256F); + this->upperBodyRotation.y = CLAMP(this->upperBodyRotation.y, -0x495F, 0x495F); + this->headRotation.y = CLAMP(this->headRotation.y, -0x256F, 0x256F); } -s32 func_80BA6D10(EnRailgibud* this, GlobalContext* globalCtx) { +s32 EnRailgibud_PlayerInRangeWithCorrectState(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO_MASK) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { return false; } - if ((Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) < 100.0f) && !(player->stateFlags1 & 0x2C6080) && - !(player->stateFlags2 & 0x4080)) { + if ((Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) < 100.0f) && + !(player->stateFlags1 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && + !(player->stateFlags2 & (0x4000 | 0x80))) { return true; } return false; } -s32 func_80BA6DAC(EnRailgibud* this, GlobalContext* globalCtx) { +/** + * 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 EnRailgibud_PlayerOutOfRange(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 100.0f) { @@ -687,196 +773,212 @@ s32 func_80BA6DAC(EnRailgibud* this, GlobalContext* globalCtx) { return false; } -void func_80BA6DF8(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_UpdateDamage(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((this->unk_3FA != 1) && (this->collider.base.acFlags & AC_HIT)) { - if (this->actionFunc == func_80BA57F8) { + if ((this->isInvincible != true) && (this->collider.base.acFlags & AC_HIT)) { + if (this->actionFunc == EnRailgibud_WalkInCircles) { this->actor.home = this->actor.world; } this->collider.base.acFlags &= ~AC_HIT; Actor_ApplyDamage(&this->actor); switch (this->actor.colChkInfo.damageEffect) { - case 15: - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + case EN_RAILGIBUD_DMGEFF_DAMAGE: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); if (player->unk_ADC != 0) { this->unk_405 = player->unk_ADD; } this->actor.shape.yOffset = 0.0f; if (this->actor.colChkInfo.health == 0) { - func_80BA6664(this); + EnRailgibud_SetupDead(this); } else { - func_80BA6440(this); + EnRailgibud_SetupDamage(this); } break; - case 14: - if (this->unk_3F8 == 1) { + case EN_RAILGIBUD_DMGEFF_LIGHT_RAY: + if (this->type == EN_RAILGIBUD_TYPE_REDEAD) { this->actor.colChkInfo.health = 0; this->actor.shape.yOffset = 0.0f; - func_80BA6664(this); + EnRailgibud_SetupDead(this); } break; - case 2: - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + case EN_RAILGIBUD_DMGEFF_FIRE_ARROW: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); if (this->actor.colChkInfo.health == 0) { - func_80BA6664(this); + EnRailgibud_SetupDead(this); } else { - func_80BA6440(this); + EnRailgibud_SetupDamage(this); } - this->unk_404 = 0; - this->unk_3F6 = 180; - this->unk_2A0 = 1.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffTimer = 180; + this->drawDmgEffAlpha = 1.0f; break; - case 4: - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + case EN_RAILGIBUD_DMGEFF_LIGHT_ARROW: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); if (this->actor.colChkInfo.health == 0) { - func_80BA6664(this); + EnRailgibud_SetupDead(this); } else { - func_80BA6440(this); + EnRailgibud_SetupDamage(this); } - this->unk_404 = 20; - this->unk_3F6 = 60; - this->unk_2A0 = 1.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffTimer = 60; + this->drawDmgEffAlpha = 1.0f; break; - case 12: - if ((this->actionFunc != func_80BA5E18) && - ((this->actionFunc != func_80BA6604) || (this->unk_3F2 == 0))) { - this->unk_404 = 30; - this->unk_3F6 = 40; - this->unk_2A0 = 1.0f; - func_80BA6584(this); + case EN_RAILGIBUD_DMGEFF_ZORA_MAGIC: + if ((this->actionFunc != EnRailgibud_Grab) && + ((this->actionFunc != EnRailgibud_Stunned) || (this->stunTimer == 0))) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffTimer = 40; + this->drawDmgEffAlpha = 1.0f; + EnRailgibud_SetupStunned(this); } break; - case 1: - if ((this->actionFunc != func_80BA6604) || (this->unk_3F2 == 0)) { - func_80BA6584(this); + case EN_RAILGIBUD_DMGEFF_STUN: + if ((this->actionFunc != EnRailgibud_Stunned) || (this->stunTimer == 0)) { + EnRailgibud_SetupStunned(this); } break; } } } -s32 func_80BA7088(EnRailgibud* this, GlobalContext* globalCtx) { +/** + * 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 EnRailgibud_MoveToIdealGrabPositionAndRotation(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp40; - f32 sp3C; - f32 sp38 = 0.0f; - s16 temp_s0_2; + Vec3f targetPos; + f32 distanceFromTargetPos; + f32 distanceFromTargetYOffset = 0.0f; + s16 distanceFromTargetAngle; - sp40 = player->actor.world.pos; - - sp40.x -= 25.0f * Math_SinS(player->actor.shape.rot.y); - sp40.z -= 25.0f * Math_CosS(player->actor.shape.rot.y); - sp3C = Math_Vec3f_StepTo(&this->actor.world.pos, &sp40, 10.0f); - temp_s0_2 = Math_SmoothStepToS(&this->actor.shape.rot.y, player->actor.shape.rot.y, 1, 0x1770, 0x64); + 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) { - sp38 = Math_SmoothStepToF(&this->actor.shape.yOffset, -1500.0f, 1.0f, 150.0f, 0.0f); + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + distanceFromTargetYOffset = Math_SmoothStepToF(&this->actor.shape.yOffset, -1500.0f, 1.0f, 150.0f, 0.0f); } - if ((sp3C == 0.0f) && (ABS_ALT(temp_s0_2) < 100) && (sp38 == 0.0f)) { + if ((distanceFromTargetPos == 0.0f) && (ABS_ALT(distanceFromTargetAngle) < 100) && + (distanceFromTargetYOffset == 0.0f)) { return true; } return false; } -void func_80BA71E4(EnRailgibud* this, GlobalContext* globalCtx) { - if ((this->actionFunc == func_80BA5B64) || (this->actionFunc == func_80BA62D4) || - (this->actionFunc == func_80BA64AC)) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); +void EnRailgibud_MoveWithGravity(EnRailgibud* this, GlobalContext* globalCtx) { + if ((this->actionFunc == EnRailgibud_WalkToPlayer) || (this->actionFunc == EnRailgibud_WalkToHome) || + (this->actionFunc == EnRailgibud_Damage)) { + Actor_MoveWithGravity(&this->actor); } } -void func_80BA7234(EnRailgibud* this, GlobalContext* globalCtx) { +/** + * 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 EnRailgibud_MoveGrabbedPlayerAwayFromWall(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp30; + Vec3f targetPos; - if ((this->actionFunc == func_80BA5E18) && (this->unk_3F0 != 2)) { + if ((this->actionFunc == EnRailgibud_Grab) && (this->grabState != EN_RAILGIBUD_GRAB_RELEASE)) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 35.0f, 1); } else { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 35.0f, 0x1D); } - if ((this->actionFunc == func_80BA5E18) && (this->unk_3F0 == 0) && (this->actor.bgCheckFlags & 8)) { - sp30 = player->actor.world.pos; - sp30.x += 10.0f * Math_SinS(this->actor.wallYaw); - sp30.z += 10.0f * Math_CosS(this->actor.wallYaw); - Math_Vec3f_StepTo(&player->actor.world.pos, &sp30, 5.0f); + if ((this->actionFunc == EnRailgibud_Grab) && (this->grabState == EN_RAILGIBUD_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 func_80BA7388(EnRailgibud* this, GlobalContext* globalCtx) { - if (this->unk_3F6 > 0) { - this->unk_3F6--; +void EnRailgibud_UpdateEffect(EnRailgibud* this, GlobalContext* globalCtx) { + if (this->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; } - if (this->unk_3F6 < 20) { - Math_SmoothStepToF(&this->unk_2A4, 0.0f, 0.5f, 0.03f, 0.0f); - this->unk_2A0 = this->unk_3F6 * 0.05f; + if (this->drawDmgEffTimer < 20) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; } else { - Math_SmoothStepToF(&this->unk_2A4, 0.5f, 0.1f, 0.02f, 0.0f); + Math_SmoothStepToF(&this->drawDmgEffScale, 0.5f, 0.1f, 0.02f, 0.0f); } } -void func_80BA7434(EnRailgibud* this, GlobalContext* globalCtx) { - if ((this->actionFunc != func_80BA5E18) && (this->actionFunc != func_80BA64AC) && - (this->actionFunc != func_80BA60B0) && (this->actionFunc != func_80BA61A0) && - (this->actionFunc != func_80BA66C8)) { - if ((this->actor.flags & 5) == 5) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO_MASK) { - this->actor.flags &= ~5; - this->actor.flags |= 9; +void EnRailgibud_CheckForGibdoMask(EnRailgibud* this, GlobalContext* globalCtx) { + if ((this->actionFunc != EnRailgibud_Grab) && (this->actionFunc != EnRailgibud_Damage) && + (this->actionFunc != EnRailgibud_GrabFail) && (this->actionFunc != EnRailgibud_TurnAwayAndShakeHead) && + (this->actionFunc != EnRailgibud_Dead)) { + if (CHECK_FLAG_ALL(this->actor.flags, (ACTOR_FLAG_1 | ACTOR_FLAG_4))) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { + this->actor.flags &= ~(ACTOR_FLAG_4 | ACTOR_FLAG_1); + this->actor.flags |= (ACTOR_FLAG_8 | ACTOR_FLAG_1); this->actor.hintId = 0xFF; this->actor.textId = 0; - if ((this->actionFunc != func_80BA57F8) && (this->actionFunc != func_80BA62D4)) { - func_80BA6284(this); + if ((this->actionFunc != EnRailgibud_WalkInCircles) && (this->actionFunc != EnRailgibud_WalkToHome)) { + EnRailgibud_SetupWalkToHome(this); } } - } else if (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO_MASK) { - this->actor.flags &= ~(0x8 | 0x1); - this->actor.flags |= (0x4 | 0x1); - if (this->unk_3F8 == 1) { + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO) { + this->actor.flags &= ~(ACTOR_FLAG_8 | ACTOR_FLAG_1); + this->actor.flags |= (ACTOR_FLAG_4 | ACTOR_FLAG_1); + if (this->type == EN_RAILGIBUD_TYPE_REDEAD) { this->actor.hintId = 0x2A; } else { this->actor.hintId = 0x2D; } this->actor.textId = 0; } - func_80BA7578(this, globalCtx); + + EnRailgibud_CheckIfTalkingToPlayer(this, globalCtx); } } -void func_80BA7578(EnRailgibud* this, GlobalContext* globalCtx) { - if ((this->unk_400 == 0) && (this->unk_3F8 == 0)) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->unk_3FA = 1; - func_801518B0(globalCtx, 0x13B2, &this->actor); - this->unk_400 = 0x13B2; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); +void EnRailgibud_CheckIfTalkingToPlayer(EnRailgibud* this, GlobalContext* globalCtx) { + if ((this->textId == 0) && (this->type == EN_RAILGIBUD_TYPE_GIBDO)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->isInvincible = true; + Message_StartTextbox(globalCtx, 0x13B2, &this->actor); + this->textId = 0x13B2; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); this->actor.speedXZ = 0.0f; - } else if (((this->actor.flags & 9) == 9) && !(this->collider.base.acFlags & AC_HIT)) { + } else if (CHECK_FLAG_ALL(this->actor.flags, (ACTOR_FLAG_1 | ACTOR_FLAG_8)) && + !(this->collider.base.acFlags & AC_HIT)) { func_800B8614(&this->actor, globalCtx, 100.0f); } } else { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 5: - if (func_80147624(globalCtx)) { - func_801518B0(globalCtx, 0x13B3, &this->actor); - this->unk_400 = 0x13B3; + if (Message_ShouldAdvance(globalCtx)) { + Message_StartTextbox(globalCtx, 0x13B3, &this->actor); + this->textId = 0x13B3; } break; case 6: - if (func_80147624(globalCtx)) { - this->unk_400 = 0; - this->unk_3FA = 0; + if (Message_ShouldAdvance(globalCtx)) { + this->textId = 0; + this->isInvincible = false; this->actor.speedXZ = 0.6f; } break; @@ -891,14 +993,16 @@ void func_80BA7578(EnRailgibud* this, GlobalContext* globalCtx) { } } -void func_80BA76C4(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_UpdateCollision(EnRailgibud* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((this->actionFunc != func_80BA66C8) && ((this->actionFunc != func_80BA5E18) || (this->unk_3F0 == 2))) { + if ((this->actionFunc != EnRailgibud_Dead) && + ((this->actionFunc != EnRailgibud_Grab) || (this->grabState == EN_RAILGIBUD_GRAB_RELEASE))) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (((this->actionFunc != func_80BA64AC) || ((player->unk_ADC != 0) && (player->unk_ADD != this->unk_405))) && - ((this->actionFunc != func_80BA6604) || (this->unk_3F2 == 0))) { + if (((this->actionFunc != EnRailgibud_Damage) || + ((player->unk_ADC != 0) && (player->unk_ADD != this->unk_405))) && + ((this->actionFunc != EnRailgibud_Stunned) || (this->stunTimer == 0))) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } @@ -907,35 +1011,38 @@ void func_80BA76C4(EnRailgibud* this, GlobalContext* globalCtx) { void EnRailgibud_Update(Actor* thisx, GlobalContext* globalCtx) { EnRailgibud* this = THIS; - func_80BA6B30(this); - func_80BA7434(this, globalCtx); - func_80BA6DF8(this, globalCtx); + EnRailgibud_UpdateWalkForwardState(this); + EnRailgibud_CheckForGibdoMask(this, globalCtx); + EnRailgibud_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); - if (this->actionFunc != func_80BA6604) { + if (this->actionFunc != EnRailgibud_Stunned) { SkelAnime_Update(&this->skelAnime); } - func_80BA71E4(this, globalCtx); - func_80BA76C4(this, globalCtx); - func_80BA7234(this, globalCtx); - func_80BA7388(this, globalCtx); + + EnRailgibud_MoveWithGravity(this, globalCtx); + EnRailgibud_UpdateCollision(this, globalCtx); + EnRailgibud_MoveGrabbedPlayerAwayFromWall(this, globalCtx); + EnRailgibud_UpdateEffect(this, globalCtx); + this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 50.0f; } -void func_80BA7878(Actor* thisx, GlobalContext* globalCtx) { +void EnRailgibud_MainGibdo_DeadUpdate(Actor* thisx, GlobalContext* globalCtx) { EnRailgibud* this = THIS; - func_80BA6B30(this); + EnRailgibud_UpdateWalkForwardState(this); } s32 EnRailgibud_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { EnRailgibud* this = THIS; - if (limbIndex == 12) { - rot->y += this->unk_3E8; - } else if (limbIndex == 23) { - rot->y += this->unk_3E2; + if (limbIndex == GIBDO_LIMB_UPPER_BODY_ROOT) { + rot->y += this->upperBodyRotation.y; + } else if (limbIndex == GIBDO_LIMB_HEAD_ROOT) { + rot->y += this->headRotation.y; } return false; @@ -945,12 +1052,16 @@ void EnRailgibud_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi Gfx** gfx) { EnRailgibud* this = THIS; - if ((this->unk_3F6 != 0) && - ((limbIndex == 3) || (limbIndex == 4) || (limbIndex == 6) || (limbIndex == 8) || (limbIndex == 9) || - (limbIndex == 11) || (limbIndex == 14) || (limbIndex == 16) || (limbIndex == 17) || (limbIndex == 18) || - (limbIndex == 20) || (limbIndex == 21) || (limbIndex == 22) || (limbIndex == 24) || (limbIndex == 25))) { - Matrix_GetStateTranslation(&this->unk_1D8[this->unk_28C]); - this->unk_28C++; + if ((this->drawDmgEffTimer != 0) && + ((limbIndex == GIBDO_LIMB_LEFT_THIGH) || (limbIndex == GIBDO_LIMB_LEFT_SHIN) || + (limbIndex == GIBDO_LIMB_LEFT_FOOT) || (limbIndex == GIBDO_LIMB_RIGHT_THIGH) || + (limbIndex == GIBDO_LIMB_RIGHT_SHIN) || (limbIndex == GIBDO_LIMB_RIGHT_FOOT) || + (limbIndex == GIBDO_LIMB_TORSO) || (limbIndex == GIBDO_LIMB_LEFT_SHOULDER_AND_UPPER_ARM) || + (limbIndex == GIBDO_LIMB_LEFT_FOREARM) || (limbIndex == GIBDO_LIMB_LEFT_HAND) || + (limbIndex == GIBDO_LIMB_RIGHT_SHOULDER_AND_UPPER_ARM) || (limbIndex == GIBDO_LIMB_RIGHT_FOREARM) || + (limbIndex == GIBDO_LIMB_RIGHT_HAND) || (limbIndex == GIBDO_LIMB_HEAD) || (limbIndex == GIBDO_LIMB_PELVIS))) { + Matrix_MultZero(&this->limbPos[this->limbIndex]); + this->limbIndex++; } } @@ -959,7 +1070,7 @@ void EnRailgibud_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - this->unk_28C = 0; + this->limbIndex = 0; if (this->actor.shape.shadowAlpha == 255) { func_8012C28C(globalCtx->state.gfxCtx); @@ -980,132 +1091,135 @@ void EnRailgibud_Draw(Actor* thisx, GlobalContext* globalCtx) { EnRailgibud_PostLimbDraw, &this->actor, POLY_XLU_DISP); } - if (this->unk_3F6 > 0) { - func_800BE680(globalCtx, &this->actor, this->unk_1D8, ARRAY_COUNT(this->unk_1D8), this->unk_2A4, 0.5f, - this->unk_2A0, this->unk_404); + if (this->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, 0.5f, this->drawDmgEffAlpha, this->drawDmgEffType); } CLOSE_DISPS(globalCtx->state.gfxCtx); } -void func_80BA7B6C(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_InitCutsceneGibdo(EnRailgibud* this, GlobalContext* globalCtx) { s32 pad[2]; - func_80BA7C78(this); - this->unk_3FE = 99; - this->actor.flags |= 0x100000; - this->actor.flags |= 0x10; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 28.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060053E8, &D_0600ABE0, this->jointTable, this->morphTable, 26); + EnRailgibud_InitActorActionCommand(this); + this->csAction = 99; + this->actor.flags |= ACTOR_FLAG_100000; + this->actor.flags |= ACTOR_FLAG_10; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGibdoSkel, &gGibdoRedeadIdleAnim, this->jointTable, + this->morphTable, GIBDO_LIMB_MAX); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - if (gSaveContext.entranceIndex != 0x2090) { // NOT Cutscene: Music Box House Opens + if (gSaveContext.save.entranceIndex != 0x2090) { // NOT Cutscene: Music Box House Opens Actor_MarkForDeath(&this->actor); } - func_80BA7CF0(this); - this->actor.update = func_80BA8050; + + EnRailgibud_SetupDoNothing(this); + this->actor.update = EnRailgibud_Cutscene_Update; } -void func_80BA7C78(EnRailgibud* this) { - switch (ENRAILGIBUD_GET_7F(&this->actor)) { +void EnRailgibud_InitActorActionCommand(EnRailgibud* this) { + switch (ENRAILGIBUD_GET_CUTSCENE_TYPE(&this->actor)) { case 1: - this->unk_3FC = 0x207; + this->actorActionCommand = 519; break; case 2: - this->unk_3FC = 0x208; + this->actorActionCommand = 520; break; case 3: - this->unk_3FC = 0x209; + this->actorActionCommand = 521; break; case 4: - this->unk_3FC = 0x20A; + this->actorActionCommand = 522; break; case 5: - this->unk_3FC = 0x20B; + this->actorActionCommand = 523; break; default: - this->unk_3FC = 0x207; + this->actorActionCommand = 519; break; } } -void func_80BA7CF0(EnRailgibud* this) { - this->actionFunc = func_80BA7D04; +void EnRailgibud_SetupDoNothing(EnRailgibud* this) { + this->actionFunc = EnRailgibud_DoNothing; } -void func_80BA7D04(EnRailgibud* this, GlobalContext* globalCtx) { +void EnRailgibud_DoNothing(EnRailgibud* this, GlobalContext* globalCtx) { } -void func_80BA7D14(EnRailgibud* this) { - this->unk_3F2 = 30; - this->actionFunc = func_80BA7D30; +void EnRailgibud_SetupSinkIntoGround(EnRailgibud* this) { + this->sinkTimer = 30; + this->actionFunc = EnRailgibud_SinkIntoGround; } -void func_80BA7D30(EnRailgibud* this, GlobalContext* globalCtx) { - if (this->unk_3F2 != 0) { - this->unk_3F2--; +void EnRailgibud_SinkIntoGround(EnRailgibud* this, GlobalContext* globalCtx) { + if (this->sinkTimer != 0) { + this->sinkTimer--; } else if (Math_SmoothStepToF(&this->actor.shape.yOffset, -9500.0f, 0.5f, 200.0f, 10.0f) < 10.0f) { Actor_MarkForDeath(&this->actor); } else { - func_80BA6800(this, globalCtx, 0); + EnRailgibud_SpawnEffectsForSinkingIntoTheGround(this, globalCtx, 0); } } -s32 func_80BA7DC8(EnRailgibud* this, GlobalContext* globalCtx) { - u32 sp2C; +s32 EnRailgibud_PerformCutsceneActions(EnRailgibud* this, GlobalContext* globalCtx) { + s32 actionIndex; - if (func_800EE29C(globalCtx, this->unk_3FC)) { - sp2C = func_800EE200(globalCtx, this->unk_3FC); - if (this->unk_3FE != globalCtx->csCtx.npcActions[sp2C]->unk0) { - this->unk_3FE = globalCtx->csCtx.npcActions[sp2C]->unk0; - switch (globalCtx->csCtx.npcActions[sp2C]->unk0) { + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCommand)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, this->actorActionCommand); + if (this->csAction != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->csAction = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: - this->unk_3F0 = 9; - func_800BDC5C(&this->skelAnime, sAnimations, 9); + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_IDLE; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_IDLE); break; case 2: - this->unk_3F0 = 15; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_WEAKENED2); - func_800BDC5C(&this->skelAnime, sAnimations, 15); + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_SLUMP_START; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_WEAKENED2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_SLUMP_START); break; case 3: - this->unk_3F0 = 17; - func_800BDC5C(&this->skelAnime, sAnimations, 17); + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_CONVULSION; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_CONVULSION); break; case 4: - this->unk_3F0 = 18; - func_800BDC5C(&this->skelAnime, sAnimations, 18); + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_ARMS_UP_START; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_ARMS_UP_START); break; case 5: - this->unk_3F0 = 10; - func_800BDC5C(&this->skelAnime, sAnimations, 10); + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_WALK; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_WALK); break; } } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - if (this->unk_3F0 == 15) { - this->unk_3F0 = 16; - func_800BDC5C(&this->skelAnime, sAnimations, 16); - } else if (this->unk_3F0 == 18) { - this->unk_3F0 = 19; - func_800BDC5C(&this->skelAnime, sAnimations, 19); - func_80BA7D14(this); + if (this->cutsceneAnimationIndex == EN_RAILGIBUD_ANIMATION_SLUMP_START) { + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_SLUMP_LOOP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_SLUMP_LOOP); + } else if (this->cutsceneAnimationIndex == EN_RAILGIBUD_ANIMATION_ARMS_UP_START) { + this->cutsceneAnimationIndex = EN_RAILGIBUD_ANIMATION_ARMS_UP_LOOP; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_RAILGIBUD_ANIMATION_ARMS_UP_LOOP); + EnRailgibud_SetupSinkIntoGround(this); } } - switch (this->unk_3FE) { + switch (this->csAction) { case 3: case 4: - if (this->actionFunc == func_80BA7D30) { + if (this->actionFunc == EnRailgibud_SinkIntoGround) { func_800B9010(&this->actor, NA_SE_EN_REDEAD_WEAKENED_L2 - SFX_FLAG); } else { func_800B9010(&this->actor, NA_SE_EN_REDEAD_WEAKENED_L1 - SFX_FLAG); @@ -1115,26 +1229,26 @@ s32 func_80BA7DC8(EnRailgibud* this, GlobalContext* globalCtx) { case 5: if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { if (globalCtx->csCtx.frames < 280) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_WEAKENED1); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_WEAKENED1); } } break; } - func_800EDF24(&this->actor, globalCtx, sp2C); + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, actionIndex); return true; } - this->unk_3FE = 99; + this->csAction = 99; return false; } -void func_80BA8050(Actor* thisx, GlobalContext* globalCtx) { +void EnRailgibud_Cutscene_Update(Actor* thisx, GlobalContext* globalCtx) { EnRailgibud* this = THIS; this->actionFunc(this, globalCtx); - func_80BA7DC8(this, globalCtx); + EnRailgibud_PerformCutsceneActions(this, globalCtx); SkelAnime_Update(&this->skelAnime); } diff --git a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.h b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.h index 35cb83cd2..a51fd37d4 100644 --- a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.h +++ b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.h @@ -2,49 +2,57 @@ #define Z_EN_RAILGIBUD_H #include "global.h" +#include "objects/object_rd/object_rd.h" struct EnRailgibud; typedef void (*EnRailgibudActionFunc)(struct EnRailgibud*, GlobalContext*); -#define ENRAILGIBUD_GET_7F(thisx) ((thisx)->params & 0x7F) -#define ENRAILGIBUD_GET_80(thisx) ((thisx)->params & 0x80) -#define ENRAILGIBUD_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define ENRAILGIBUD_GET_CUTSCENE_TYPE(thisx) ((thisx)->params & 0x7F) +#define ENRAILGIBUD_IS_CUTSCENE_TYPE(thisx) ((thisx)->params & 0x80) +#define ENRAILGIBUD_GET_PATH(thisx) (((thisx)->params & 0xFF00) >> 8) typedef struct EnRailgibud { /* 0x0000 */ Actor actor; /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnRailgibudActionFunc actionFunc; - /* 0x01D8 */ Vec3f unk_1D8[15]; - /* 0x028C */ s32 unk_28C; + /* 0x01D8 */ Vec3f limbPos[15]; + /* 0x028C */ s32 limbIndex; /* 0x0290 */ UNK_TYPE1 unk290[0x4]; - /* 0x0294 */ Vec3s* unk_294; - /* 0x0298 */ s32 unk_298; - /* 0x029C */ s32 unk_29C; - /* 0x02A0 */ f32 unk_2A0; - /* 0x02A4 */ f32 unk_2A4; - /* 0x02A8 */ Vec3s jointTable[26]; - /* 0x0344 */ Vec3s morphTable[26]; - /* 0x03E0 */ UNK_TYPE1 unk3E0[0x2]; - /* 0x03E2 */ s16 unk_3E2; - /* 0x03E4 */ UNK_TYPE1 unk3E4[0x4]; - /* 0x03E8 */ s16 unk_3E8; - /* 0x03EA */ UNK_TYPE1 unk3EA[0x2]; - /* 0x03EC */ s16 unk_3EC; - /* 0x03EE */ s16 unk_3EE; - /* 0x03F0 */ s16 unk_3F0; - /* 0x03F2 */ s16 unk_3F2; - /* 0x03F4 */ s16 unk_3F4; - /* 0x03F6 */ s16 unk_3F6; - /* 0x03F8 */ s16 unk_3F8; - /* 0x03FA */ s16 unk_3FA; - /* 0x03FC */ u16 unk_3FC; - /* 0x03FE */ u16 unk_3FE; - /* 0x0400 */ u16 unk_400; - /* 0x0402 */ s16 unk_402; - /* 0x0404 */ u8 unk_404; - /* 0x0405 */ s8 unk_405; + /* 0x0294 */ Vec3s* points; + /* 0x0298 */ s32 currentPoint; + /* 0x029C */ s32 pathCount; + /* 0x02A0 */ f32 drawDmgEffAlpha; + /* 0x02A4 */ f32 drawDmgEffScale; + /* 0x02A8 */ Vec3s jointTable[GIBDO_LIMB_MAX]; + /* 0x0344 */ Vec3s morphTable[GIBDO_LIMB_MAX]; + /* 0x03E0 */ Vec3s headRotation; + /* 0x03E6 */ Vec3s upperBodyRotation; + /* 0x03EC */ s16 shouldWalkForward; // Only used by the "main" Gibdo + /* 0x03EE */ s16 shouldWalkForwardNextFrame; // Only used by the "main" Gibdo + /* 0x03F0 */ union { + s16 grabState; + s16 cutsceneAnimationIndex; + }; + /* 0x03F2 */ union { + s16 playerStunWaitTimer; // Cannot stun the player if this is non-zero + s16 grabDamageTimer; + s16 headShakeTimer; + s16 stunTimer; + s16 deathTimer; + s16 sinkTimer; + }; + /* 0x03F4 */ s16 grabWaitTimer; // Cannot grab the player if this is non-zero + /* 0x03F6 */ s16 drawDmgEffTimer; + /* 0x03F8 */ s16 type; + /* 0x03FA */ s16 isInvincible; + /* 0x03FC */ u16 actorActionCommand; + /* 0x03FE */ u16 csAction; + /* 0x0400 */ u16 textId; + /* 0x0402 */ s16 timeInitialized; // unused other than setting it + /* 0x0404 */ u8 drawDmgEffType; + /* 0x0405 */ s8 unk_405; // related to player->unk_ADD } EnRailgibud; // size = 0x408 extern const ActorInit En_Railgibud_InitVars; diff --git a/src/overlays/actors/ovl_En_Rat/z_en_rat.c b/src/overlays/actors/ovl_En_Rat/z_en_rat.c index ef302a688..583d3637c 100644 --- a/src/overlays/actors/ovl_En_Rat/z_en_rat.c +++ b/src/overlays/actors/ovl_En_Rat/z_en_rat.c @@ -1,6 +1,12 @@ +/* + * File: z_en_rat.c + * Overlay: ovl_En_Rat + * Description: Real Bombchu + */ + #include "z_en_rat.h" -#define FLAGS 0x00000205 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200) #define THIS ((EnRat*)thisx) 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 c6359ba89..c24a5e5a9 100644 --- a/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -1,12 +1,31 @@ /* * File: z_en_rd.c * Overlay: ovl_En_Rd - * Description: Redead / Gibdo + * Description: Redead/Gibdo that cannot talk to the player. + * + * A variety of different Redeads/Gibdos are represented by this actor; + * one of the few things they all have in common is that none of them + * can talk with the player, which separates them from Talk_Gibud and + * Railgibud. Some of the different kinds of Redeads/Gibdos that this + * actor controls are: + * - Three different types of dancing Redeads. These are the only + * Redead/Gidbo variations that are actually used in the final game. + * - A Redead frozen in a block of ice. + * - An invisible Redead. + * - A crying Redead. + * - A Gidbo that rises out of a "coffin"; this is leftover from OoT. + * + * Another thing that separates this actor from Talk_Gibud and Railgibud + * is that most Redead variations will "mourn" other fallen Redeads in + * the same area by walking over to their corpse. Note that some Redeads, + * depending on their params, will refuse to mourn under certain + * circumstances, and all Gibdo variations will refuse to mourn as well. */ #include "z_en_rd.h" +#include "objects/object_rd/object_rd.h" -#define FLAGS 0x00000415 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((EnRd*)thisx) @@ -15,56 +34,67 @@ void EnRd_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRd_Update(Actor* thisx, GlobalContext* globalCtx); void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx); -s32 func_808D41FC(GlobalContext* globalCtx); -void func_808D4308(EnRd* this); -void func_808D43AC(EnRd* this, GlobalContext* globalCtx); -void func_808D45D4(EnRd* this); -void func_808D4660(EnRd* this, GlobalContext* globalCtx); -void func_808D47DC(EnRd* this); -void func_808D4868(EnRd* this, GlobalContext* globalCtx); -void func_808D49E4(EnRd* this, GlobalContext* globalCtx); -void func_808D4A90(EnRd* this); -void func_808D4B20(EnRd* this, GlobalContext* globalCtx); -void func_808D4CA8(EnRd* this, GlobalContext* globalCtx); -void func_808D4DC4(EnRd* this); -void func_808D4E60(EnRd* this, GlobalContext* globalCtx); -void func_808D506C(EnRd* this, GlobalContext* globalCtx); -void func_808D53C0(EnRd* this, GlobalContext* globalCtx); -void func_808D5440(EnRd* this, GlobalContext* globalCtx); -void func_808D5660(EnRd* this); -void func_808D56E4(EnRd* this, GlobalContext* globalCtx); -void func_808D586C(EnRd* this); -void func_808D58CC(EnRd* this, GlobalContext* globalCtx); -void func_808D5C54(EnRd* this); -void func_808D5CCC(EnRd* this, GlobalContext* globalCtx); -void func_808D5D88(EnRd* this); -void func_808D5DF4(EnRd* this, GlobalContext* globalCtx); -void func_808D5E98(EnRd* this); -void func_808D5F18(EnRd* this, GlobalContext* globalCtx); -void func_808D6008(EnRd* this); -void func_808D6054(EnRd* this, GlobalContext* globalCtx); -void func_808D60B0(EnRd* this); -void func_808D6130(EnRd* this, GlobalContext* globalCtx); -void func_808D6200(EnRd* this, GlobalContext* globalCtx); -void func_808D6388(EnRd* this, GlobalContext* globalCtx); -void func_808D65BC(EnRd* this, GlobalContext* globalCtx); +s32 EnRd_ShouldNotDance(GlobalContext* globalCtx); +void EnRd_SetupIdle(EnRd* this); +void EnRd_Idle(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupSquattingDance(EnRd* this); +void EnRd_SquattingDance(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupClappingDance(EnRd* this); +void EnRd_ClappingDance(EnRd* this, GlobalContext* globalCtx); +void EnRd_EndClappingOrSquattingDanceWhenPlayerIsClose(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupPirouette(EnRd* this); +void EnRd_Pirouette(EnRd* this, GlobalContext* globalCtx); +void EnRd_EndPirouetteWhenPlayerIsClose(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupRiseFromCoffin(EnRd* this); +void EnRd_RiseFromCoffin(EnRd* this, GlobalContext* globalCtx); +void EnRd_WalkToPlayer(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupWalkToHome(EnRd* this, GlobalContext* globalCtx); +void EnRd_WalkToHome(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupWalkToParent(EnRd* this); +void EnRd_WalkToParent(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupGrab(EnRd* this); +void EnRd_Grab(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupAttemptPlayerFreeze(EnRd* this); +void EnRd_AttemptPlayerFreeze(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupGrabFail(EnRd* this); +void EnRd_GrabFail(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupTurnAwayAndShakeHead(EnRd* this); +void EnRd_TurnAwayAndShakeHead(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupStandUp(EnRd* this); +void EnRd_StandUp(EnRd* this, GlobalContext* globalCtx); +void EnRd_SetupCrouch(EnRd* this); +void EnRd_Crouch(EnRd* this, GlobalContext* globalCtx); +void EnRd_Damage(EnRd* this, GlobalContext* globalCtx); +void EnRd_Dead(EnRd* this, GlobalContext* globalCtx); +void EnRd_Stunned(EnRd* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_060053E8; -extern AnimationHeader D_06006678; -extern AnimationHeader D_06006B08; -extern AnimationHeader D_06006EEC; -extern AnimationHeader D_060073A4; -extern AnimationHeader D_06007BBC; -extern AnimationHeader D_060081A8; -extern AnimationHeader D_06009298; -extern AnimationHeader D_06009900; -extern AnimationHeader D_0600A450; -extern AnimationHeader D_0600ABE0; -extern FlexSkeletonHeader D_06010B88; -extern AnimationHeader D_060113EC; -extern AnimationHeader D_060118D8; -extern AnimationHeader D_06011DB8; -extern AnimationHeader D_0601216C; +typedef enum { + /* 0 */ EN_RD_ACTION_IDLE, + /* 1 */ EN_RD_ACTION_STUNNED, + /* 2 */ EN_RD_ACTION_WALKING_TO_HOME, + /* 3 */ EN_RD_ACTION_WALKING_TO_PARENT, + /* 4 */ EN_RD_ACTION_WALKING_TO_PLAYER_OR_RELEASING_GRAB, + /* 5 */ EN_RD_ACTION_STANDING_UP, + /* 6 */ EN_RD_ACTION_CROUCHING, + /* 7 */ EN_RD_ACTION_ATTEMPTING_PLAYER_STUN, + /* 8 */ EN_RD_ACTION_FAILING_GRAB, + /* 9 */ EN_RD_ACTION_TURNING_AWAY_AND_SHAKING_HEAD, + /* 10 */ EN_RD_ACTION_GRABBING, + /* 11 */ EN_RD_ACTION_DAMAGE, + /* 12 */ EN_RD_ACTION_DEAD, + /* 13 */ EN_RD_ACTION_RISING_FROM_COFFIN, + /* 14 */ EN_RD_ACTION_SQUATTING_DANCE, + /* 15 */ EN_RD_ACTION_CLAPPING_DANCE, + /* 16 */ EN_RD_ACTION_PIROUETTE +} EnRdAction; + +typedef enum { + /* 0 */ EN_RD_GRAB_START, + /* 1 */ EN_RD_GRAB_INITIAL_DAMAGE, + /* 2 */ EN_RD_GRAB_ATTACK, + /* 3 */ EN_RD_GRAB_RELEASE, + /* 4 */ EN_RD_GRAB_END, +} EnRdGrabState; const ActorInit En_Rd_InitVars = { ACTOR_EN_RD, @@ -98,39 +128,52 @@ static ColliderCylinderInit sCylinderInit = { { 20, 70, 0, { 0, 0, 0 } }, }; +typedef enum { + /* 0x0 */ EN_RD_DMGEFF_NONE, // Does not interact with the Gibdo/Redead at all + /* 0x1 */ EN_RD_DMGEFF_STUN, // Stuns without applying any effect + /* 0x2 */ EN_RD_DMGEFF_FIRE_ARROW, // Damages and applies a fire effect + /* 0x4 */ EN_RD_DMGEFF_LIGHT_ARROW = 0x4, // Damages and applies a light effect + /* 0x6 */ EN_RD_DMGEFF_UNUSED_6 = 0x6, // Referenced in EnRd_Update, but no attack uses this damage effect. + // Likely to have originally been used for Ice Arrows like OoT. + /* 0xC */ EN_RD_DMGEFF_ZORA_MAGIC = 0xC, // Stuns and applies an electric effect + /* 0xD */ EN_RD_DMGEFF_RECOIL, // Deals no damage, but displays hit mark and recoil animation + /* 0xE */ EN_RD_DMGEFF_LIGHT_RAY, // Instantly kills on contact + /* 0xF */ EN_RD_DMGEFF_DAMAGE, // Deals damage and plays the damage animation +} EnRdDamageEffect; + static DamageTable sDamageTable = { - /* 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), + /* Deku Nut */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(2, EN_RD_DMGEFF_DAMAGE), + /* Horse trample */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Zora boomerang */ DMG_ENTRY(0, EN_RD_DMGEFF_RECOIL), + /* Normal arrow */ DMG_ENTRY(0, EN_RD_DMGEFF_RECOIL), + /* UNK_DMG_0x06 */ DMG_ENTRY(2, EN_RD_DMGEFF_DAMAGE), + /* Hookshot */ DMG_ENTRY(0, EN_RD_DMGEFF_RECOIL), + /* Goron punch */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Sword */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Goron pound */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Fire arrow */ DMG_ENTRY(1, EN_RD_DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(0, EN_RD_DMGEFF_RECOIL), + /* Light arrow */ DMG_ENTRY(2, EN_RD_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Deku spin */ DMG_ENTRY(0, EN_RD_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(0, EN_RD_DMGEFF_RECOIL), + /* Deku launch */ DMG_ENTRY(2, EN_RD_DMGEFF_DAMAGE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, EN_RD_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_RD_DMGEFF_LIGHT_RAY), + /* Thrown object */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Zora punch */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Spin attack */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), + /* Sword beam */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_RD_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_RD_DMGEFF_DAMAGE), }; static InitChainEntry sInitChain[] = { @@ -147,86 +190,86 @@ void EnRd_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.targetMode = 0; this->actor.colChkInfo.damageTable = &sDamageTable; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - this->unk_3DA = this->unk_3D8 = 0; + this->upperBodyYRotation = this->headYRotation = 0; this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 50.0f; this->actor.colChkInfo.mass = MASS_HEAVY; this->actor.colChkInfo.health = 8; - this->unk_3DE = 255; + this->alpha = 255; this->unk_3F1 = -1; - this->unk_3DC = ENRD_GET_FF00(thisx); + this->flags = EN_RD_GET_FLAGS(thisx); - if (ENRD_GET_80(&this->actor)) { + if (EN_RD_GET_80(&this->actor)) { this->actor.params |= 0xFF00; } else { this->actor.params &= 0xFF; } - if (this->actor.params >= ENRD_GET_MINUS_1) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06010B88, &D_0600ABE0, this->jointTable, this->morphTable, - 26); + if (EN_RD_GET_TYPE(&this->actor) > EN_RD_TYPE_GIBDO) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gRedeadSkel, &gGibdoRedeadIdleAnim, this->jointTable, + this->morphTable, REDEAD_LIMB_MAX); } else { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060053E8, &D_0600ABE0, this->jointTable, this->morphTable, - 26); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGibdoSkel, &gGibdoRedeadIdleAnim, this->jointTable, + this->morphTable, REDEAD_LIMB_MAX); } Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); - if (this->actor.params >= ENRD_GET_MINUS_2) { - switch (this->actor.params) { - case 5: - if (!func_808D41FC(globalCtx)) { - func_808D45D4(this); + if (EN_RD_GET_TYPE(&this->actor) >= EN_RD_TYPE_GIBDO) { + switch (EN_RD_GET_TYPE(&this->actor)) { + case EN_RD_TYPE_SQUATTING_DANCE: + if (!EnRd_ShouldNotDance(globalCtx)) { + EnRd_SetupSquattingDance(this); } else { this->actor.hintId = 0x2A; - func_808D4308(this); + EnRd_SetupIdle(this); } - this->unkFunc = func_808D45D4; + this->setupDanceFunc = EnRd_SetupSquattingDance; break; - case 6: - if (!func_808D41FC(globalCtx)) { - func_808D47DC(this); + case EN_RD_TYPE_CLAPPING_DANCE: + if (!EnRd_ShouldNotDance(globalCtx)) { + EnRd_SetupClappingDance(this); } else { this->actor.hintId = 0x2A; - func_808D4308(this); + EnRd_SetupIdle(this); } - this->unkFunc = func_808D47DC; + this->setupDanceFunc = EnRd_SetupClappingDance; break; - case 7: - if (!func_808D41FC(globalCtx)) { - func_808D4A90(this); + case EN_RD_TYPE_PIROUETTE: + if (!EnRd_ShouldNotDance(globalCtx)) { + EnRd_SetupPirouette(this); } else { this->actor.hintId = 0x2A; - func_808D4308(this); + EnRd_SetupIdle(this); } - this->unkFunc = func_808D4A90; + this->setupDanceFunc = EnRd_SetupPirouette; break; default: - if (this->actor.params == ENRD_GET_MINUS_2) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - func_808D4308(this); - this->unkFunc = func_808D4308; + EnRd_SetupIdle(this); + this->setupDanceFunc = EnRd_SetupIdle; break; } } else { - func_808D4DC4(this); + EnRd_SetupRiseFromCoffin(this); } SkelAnime_Update(&this->skelAnime); - if (this->actor.params == ENRD_GET_3) { - this->actor.flags |= 0x80; + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_INVISIBLE) { + this->actor.flags |= ACTOR_FLAG_80; } - if (this->actor.params == ENRD_GET_4) { - s32 pad2; + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_FROZEN) { + s32 requiredScopeTemp; Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, this->actor.world.rot.x, @@ -237,313 +280,344 @@ void EnRd_Init(Actor* thisx, GlobalContext* globalCtx) { void EnRd_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnRd* this = THIS; - if (gSaveContext.unk_3F58 != 0) { - gSaveContext.unk_3F58 = 0; + if (gSaveContext.sunsSongState != SUNSSONG_INACTIVE) { + gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } Collider_DestroyCylinder(globalCtx, &this->collider); } -void func_808D4190(GlobalContext* globalCtx, EnRd* this, s32 arg2) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first; +/** + * This function does two things depending on whether setParent is true or false. + * - If setParent is true, this function sets thisx to be the parent for all Redeads + * in the area that are capable of mourning. This is used right when thisx first + * dies to make the other Redeads mourn it. + * - If setParent is false, this function nulls out the parent for all Redeads in the + * are whose parents is thisx. This is used when thisx is fading away to make the + * other Redeads stop mourning over it. + */ +void EnRd_UpdateParentForOtherRedeads(GlobalContext* globalCtx, Actor* thisx, s32 setParent) { + Actor* enemyIterator = globalCtx->actorCtx.actorLists[ACTORCAT_ENEMY].first; - while (actor != NULL) { - if ((actor->id != ACTOR_EN_RD) || (this == (EnRd*)actor) || (actor->params < ENRD_GET_0)) { - actor = actor->next; + while (enemyIterator != NULL) { + if ((enemyIterator->id != ACTOR_EN_RD) || (enemyIterator == thisx) || + (EN_RD_GET_TYPE(enemyIterator) < EN_RD_TYPE_DOES_NOT_MOURN_IF_WALKING)) { + enemyIterator = enemyIterator->next; continue; - } else if (arg2 != 0) { - actor->parent = &this->actor; - } else if (this == (EnRd*)actor->parent) { - actor->parent = NULL; } - actor = actor->next; + + if (setParent) { + enemyIterator->parent = thisx; + } else if (thisx == enemyIterator->parent) { + enemyIterator->parent = NULL; + } + + enemyIterator = enemyIterator->next; } } -s32 func_808D41FC(GlobalContext* globalCtx) { - if ((Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO_MASK) || - (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) || - (Player_GetMask(globalCtx) == PLAYER_MASK_GAROS_MASK)) { +/** + * Returns true if the various dancing Redead types *should not* be dancing + * and returns false if they *should* be dancing. The non-dancing Redeads + * do not call this function in the final game and thus don't care about + * what mask the player has equipped. + */ +s32 EnRd_ShouldNotDance(GlobalContext* globalCtx) { + if ((Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) || (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) || + (Player_GetMask(globalCtx) == PLAYER_MASK_GARO)) { return false; } + return true; } -void func_808D4260(EnRd* this, GlobalContext* globalCtx) { - if ((this->actor.params >= ENRD_GET_5) && (this->actionFunc != func_808D4660) && - (this->actionFunc != func_808D4868) && (this->actionFunc != func_808D4B20) && - (this->actionFunc != func_808D65BC) && (this->actionFunc != func_808D58CC) && - (this->actionFunc != func_808D6200) && (this->actionFunc != func_808D6388)) { - if (!func_808D41FC(globalCtx)) { - this->unkFunc(this); +/** + * If the Redead/Gibdo is a dancing Redead; if it isn't already dancing; if it isn't stunned, + * taking damage, dead, or currently grabbing the player; and if the player is wearing the + * appropriate mask, this function will make the Redead start dancing. + */ +void EnRd_SetupDanceIfConditionsMet(EnRd* this, GlobalContext* globalCtx) { + if ((EN_RD_GET_TYPE(&this->actor) >= EN_RD_TYPE_SQUATTING_DANCE) && (this->actionFunc != EnRd_SquattingDance) && + (this->actionFunc != EnRd_ClappingDance) && (this->actionFunc != EnRd_Pirouette) && + (this->actionFunc != EnRd_Stunned) && (this->actionFunc != EnRd_Grab) && (this->actionFunc != EnRd_Damage) && + (this->actionFunc != EnRd_Dead)) { + if (!EnRd_ShouldNotDance(globalCtx)) { + this->setupDanceFunc(this); } } } -void func_808D4308(EnRd* this) { - if (this->actor.params != ENRD_GET_2) { - Animation_MorphToLoop(&this->skelAnime, &D_0600ABE0, -6.0f); +void EnRd_SetupIdle(EnRd* this) { + if (EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) { + Animation_MorphToLoop(&this->skelAnime, &gGibdoRedeadIdleAnim, -6.0f); } else { - Animation_PlayLoop(&this->skelAnime, &D_060081A8); + Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadSobbingAnim); } - this->unk_3EF = 0; - this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->action = EN_RD_ACTION_IDLE; + this->animationJudderTimer = (Rand_ZeroOne() * 10.0f) + 5.0f; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - this->actionFunc = func_808D43AC; + this->actionFunc = EnRd_Idle; } -void func_808D43AC(EnRd* this, GlobalContext* globalCtx) { +void EnRd_Idle(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); - if ((this->actor.params == ENRD_GET_2) && Animation_OnFrame(&this->skelAnime, 0.0f)) { + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); + + if ((EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_CRYING) && Animation_OnFrame(&this->skelAnime, 0.0f)) { if (Rand_ZeroOne() >= 0.5f) { - Animation_PlayLoop(&this->skelAnime, &D_060081A8); + Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadSobbingAnim); } else { - Animation_PlayLoop(&this->skelAnime, &D_06007BBC); + Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadWipingTearsAnim); } } else { - this->unk_3D6--; - if (this->unk_3D6 == 0) { - this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 10.0f; + this->animationJudderTimer--; + if (this->animationJudderTimer == 0) { + // This resets the idle animation back to its first frame, making the + // Redead/Gibdo appear to "judder" in place. + this->animationJudderTimer = (Rand_ZeroOne() * 10.0f) + 10.0f; this->skelAnime.curFrame = 0.0f; } } if (this->actor.parent != NULL) { - if (this->unk_3EC == 0) { - if (this->actor.params != ENRD_GET_2) { - func_808D5660(this); + if (!this->isMourning) { + if (EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) { + EnRd_SetupWalkToParent(this); } else { - func_808D6008(this); + EnRd_SetupStandUp(this); } } } else { - if (this->unk_3EC != 0) { - if (this->actor.params != ENRD_GET_2) { - func_808D5C54(this); + if (this->isMourning) { + if (EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) { + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_808D6008(this); + EnRd_SetupStandUp(this); } } - this->unk_3EC = 0; + this->isMourning = false; if ((this->actor.xzDistToPlayer <= 150.0f) && func_800B715C(globalCtx)) { - if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { - func_808D5C54(this); + if ((EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) && (!this->isMourning)) { + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_808D6008(this); + EnRd_SetupStandUp(this); } } } if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D45D4(EnRd* this) { - Animation_MorphToLoop(&this->skelAnime, &D_0601216C, -6.0f); - this->unk_3EF = 14; - this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; - this->unk_3E4 = 0; +void EnRd_SetupSquattingDance(EnRd* this) { + Animation_MorphToLoop(&this->skelAnime, &gGibdoRedeadSquattingDanceAnim, -6.0f); + this->action = EN_RD_ACTION_SQUATTING_DANCE; + this->animationJudderTimer = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->danceEndTimer = 0; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - this->actionFunc = func_808D4660; + this->actionFunc = EnRd_SquattingDance; } -void func_808D4660(EnRd* this, GlobalContext* globalCtx) { +void EnRd_SquattingDance(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); - if (this->unk_3EC != 0) { - func_808D5C54(this); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); + + if (this->isMourning) { + EnRd_SetupAttemptPlayerFreeze(this); } - this->unk_3EC = 0; - if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + this->isMourning = false; + if ((this->actor.xzDistToPlayer <= 150.0f) && EnRd_ShouldNotDance(globalCtx) && func_800B715C(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - Animation_Change(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); - this->actionFunc = func_808D49E4; + Animation_Change(&this->skelAnime, &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, 19.0f, 2, -10.0f); + this->actionFunc = EnRd_EndClappingOrSquattingDanceWhenPlayerIsClose; } - if (func_808D41FC(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + if (EnRd_ShouldNotDance(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - func_808D4308(this); + EnRd_SetupIdle(this); } if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D47DC(EnRd* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06011DB8, -6.0f); - this->unk_3EF = 15; - this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; - this->unk_3E4 = 0; +void EnRd_SetupClappingDance(EnRd* this) { + Animation_MorphToLoop(&this->skelAnime, &gGibdoRedeadClappingDanceAnim, -6.0f); + this->action = EN_RD_ACTION_CLAPPING_DANCE; + this->animationJudderTimer = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->danceEndTimer = 0; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - this->actionFunc = func_808D4868; + this->actionFunc = EnRd_ClappingDance; } -void func_808D4868(EnRd* this, GlobalContext* globalCtx) { +void EnRd_ClappingDance(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); - if (this->unk_3EC != 0) { - func_808D5C54(this); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); + + if (this->isMourning) { + EnRd_SetupAttemptPlayerFreeze(this); } - this->unk_3EC = 0; - if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + this->isMourning = false; + if ((this->actor.xzDistToPlayer <= 150.0f) && EnRd_ShouldNotDance(globalCtx) && func_800B715C(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - Animation_Change(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); - this->actionFunc = func_808D49E4; + Animation_Change(&this->skelAnime, &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, 19.0f, 2, -10.0f); + this->actionFunc = EnRd_EndClappingOrSquattingDanceWhenPlayerIsClose; } - if (func_808D41FC(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + if (EnRd_ShouldNotDance(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - func_808D4308(this); + EnRd_SetupIdle(this); } if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D49E4(EnRd* this, GlobalContext* globalCtx) { +void EnRd_EndClappingOrSquattingDanceWhenPlayerIsClose(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } - this->unk_3E4++; - if (this->unk_3E4 > 10) { - if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { - func_808D5C54(this); + this->danceEndTimer++; + if (this->danceEndTimer > 10) { + if ((EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) && (!this->isMourning)) { + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_808D6008(this); + EnRd_SetupStandUp(this); } - this->unk_3E4 = 0; + this->danceEndTimer = 0; } } -void func_808D4A90(EnRd* this) { - Animation_MorphToLoop(&this->skelAnime, &D_060118D8, -6.0f); - this->unk_3EF = 16; - this->unk_3D6 = (Rand_ZeroOne() * 10.0f) + 5.0f; - this->unk_3E4 = 4370; +void EnRd_SetupPirouette(EnRd* this) { + Animation_MorphToLoop(&this->skelAnime, &gGibdoRedeadPirouetteAnim, -6.0f); + this->action = EN_RD_ACTION_PIROUETTE; + this->animationJudderTimer = (Rand_ZeroOne() * 10.0f) + 5.0f; + this->pirouetteRotationalVelocity = 0x1112; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - this->actionFunc = func_808D4B20; + this->actionFunc = EnRd_Pirouette; } -void func_808D4B20(EnRd* this, GlobalContext* globalCtx) { +void EnRd_Pirouette(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); - if (this->unk_3EC != 0) { - func_808D5C54(this); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); + + if (this->isMourning) { + EnRd_SetupAttemptPlayerFreeze(this); } - this->unk_3EC = 0; - if ((this->actor.xzDistToPlayer <= 150.0f) && func_808D41FC(globalCtx) && func_800B715C(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + this->isMourning = false; + if ((this->actor.xzDistToPlayer <= 150.0f) && EnRd_ShouldNotDance(globalCtx) && func_800B715C(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - this->actionFunc = func_808D4CA8; + this->actionFunc = EnRd_EndPirouetteWhenPlayerIsClose; } - if (func_808D41FC(globalCtx)) { - if (this->actor.params == ENRD_GET_MINUS_2) { + if (EnRd_ShouldNotDance(globalCtx)) { + if (EN_RD_GET_TYPE(&this->actor) == EN_RD_TYPE_GIBDO) { this->actor.hintId = 0x2D; } else { this->actor.hintId = 0x2A; } - func_808D4308(this); + EnRd_SetupIdle(this); } if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - this->unk_3E4 = 4370; + this->pirouetteRotationalVelocity = 0x1112; } else if (Animation_OnFrame(&this->skelAnime, 15.0f)) { - this->unk_3E4 = 6554; + this->pirouetteRotationalVelocity = 0x199A; } - this->actor.world.rot.y -= this->unk_3E4; + this->actor.world.rot.y -= this->pirouetteRotationalVelocity; this->actor.shape.rot.y = this->actor.world.rot.y; } -void func_808D4CA8(EnRd* this, GlobalContext* globalCtx) { +void EnRd_EndPirouetteWhenPlayerIsClose(EnRd* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } - this->actor.world.rot.y -= this->unk_3E4; + this->actor.world.rot.y -= this->pirouetteRotationalVelocity; this->actor.shape.rot.y = this->actor.world.rot.y; - this->unk_3E4 -= 100; - if ((this->unk_3E4 < 2100) && (this->unk_3E4 >= 2000)) { - Animation_Change(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, 19.0f, 2, -10.0f); - } else if (this->unk_3E4 < 1000) { - if ((this->actor.params != ENRD_GET_2) && (this->unk_3EC == 0)) { - func_808D5C54(this); + this->pirouetteRotationalVelocity -= 0x64; + if ((this->pirouetteRotationalVelocity < 0x834) && (this->pirouetteRotationalVelocity >= 0x7D0)) { + Animation_Change(&this->skelAnime, &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, 19.0f, 2, -10.0f); + } else if (this->pirouetteRotationalVelocity < 0x3E8) { + if ((EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) && (!this->isMourning)) { + EnRd_SetupAttemptPlayerFreeze(this); } else { - func_808D6008(this); + EnRd_SetupStandUp(this); } } } -void func_808D4DC4(EnRd* this) { - Animation_Change(&this->skelAnime, &D_0600ABE0, 0.0f, 0.0f, Animation_GetLastFrame(&D_0600ABE0), 0, -6.0f); - this->unk_3EF = 13; - this->unk_3D6 = 6; +void EnRd_SetupRiseFromCoffin(EnRd* this) { + Animation_Change(&this->skelAnime, &gGibdoRedeadIdleAnim, 0.0f, 0.0f, Animation_GetLastFrame(&gGibdoRedeadIdleAnim), + 0, -6.0f); + this->action = EN_RD_ACTION_RISING_FROM_COFFIN; + this->coffinRiseForwardAccelTimer = 6; this->actor.shape.rot.x = -0x4000; this->actor.gravity = 0.0f; this->actor.shape.yOffset = 0.0f; this->actor.speedXZ = 0.0f; - this->actionFunc = func_808D4E60; + this->actionFunc = EnRd_RiseFromCoffin; } -void func_808D4E60(EnRd* this, GlobalContext* globalCtx) { +void EnRd_RiseFromCoffin(EnRd* this, GlobalContext* globalCtx) { if (this->actor.shape.rot.x != -0x4000) { Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 0.3f, 2.0f, 0.3f) == 0.0f) { this->actor.gravity = -3.5f; - func_808D4308(this); + EnRd_SetupIdle(this); } } else { if (this->actor.world.pos.y == this->actor.home.pos.y) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } if (Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.home.pos.y + 50.0f, 0.3f, 2.0f, 0.3f) == 0.0f) { - if (this->unk_3D6 != 0) { - this->unk_3D6--; + if (this->coffinRiseForwardAccelTimer != 0) { + this->coffinRiseForwardAccelTimer--; Math_SmoothStepToF(&this->actor.speedXZ, 6.0f, 0.3f, 1.0f, 0.3f); } else if (Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.3f, 1.0f, 0.3f) == 0.0f) { Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x7D0, 0); @@ -552,88 +626,92 @@ void func_808D4E60(EnRd* this, GlobalContext* globalCtx) { } } -void func_808D4FE0(EnRd* this, GlobalContext* globalCtx) { - f32 frameCount = Animation_GetLastFrame(&D_060113EC); +void EnRd_SetupWalkToPlayer(EnRd* this, GlobalContext* globalCtx) { + f32 frameCount = Animation_GetLastFrame(&gGibdoRedeadWalkAnim); - Animation_Change(&this->skelAnime, &D_060113EC, 1.0f, 4.0f, frameCount, 1, -4.0f); + Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 1.0f, 4.0f, frameCount, 1, -4.0f); this->actor.speedXZ = 0.4f; - this->unk_3EF = 4; - this->actionFunc = func_808D506C; + this->action = EN_RD_ACTION_WALKING_TO_PLAYER_OR_RELEASING_GRAB; + this->actionFunc = EnRd_WalkToPlayer; } -void func_808D506C(EnRd* this, GlobalContext* globalCtx) { +void EnRd_WalkToPlayer(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 pad; - s16 sp36 = ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3D8) - this->unk_3DA; + s16 yaw = + ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->headYRotation) - this->upperBodyYRotation; this->skelAnime.playSpeed = this->actor.speedXZ; Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 250, 0); - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); this->actor.world.rot.y = this->actor.shape.rot.y; SkelAnime_Update(&this->skelAnime); if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { - func_808D53C0(this, globalCtx); + EnRd_SetupWalkToHome(this, globalCtx); } - if ((ABS_ALT(sp36) < 0x1554) && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 150.0f)) { + if ((ABS_ALT(yaw) < 0x1554) && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 150.0f)) { if (!(player->stateFlags1 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && - !(player->stateFlags2 & 0x4080)) { - if (this->unk_3ED == 0) { - if (!(this->unk_3DC & 0x80)) { + !(player->stateFlags2 & (0x4000 | 0x80))) { + if (this->playerStunWaitTimer == 0) { + if (!(this->flags & EN_RD_FLAG_CANNOT_FREEZE_PLAYER)) { player->actor.freezeTimer = 40; func_80123E90(globalCtx, &this->actor); GET_PLAYER(globalCtx)->unk_A78 = &this->actor; func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); } - this->unk_3ED = 60; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + this->playerStunWaitTimer = 60; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); } } else { - func_808D53C0(this, globalCtx); + EnRd_SetupWalkToHome(this, globalCtx); } } - if (this->unk_3EE != 0) { - this->unk_3EE--; + if (this->grabWaitTimer != 0) { + this->grabWaitTimer--; } - if (!this->unk_3EE && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 45.0f) && - Actor_IsActorFacingLink(&this->actor, 0x38E3)) { + if (!this->grabWaitTimer && (Actor_DistanceBetweenActors(&this->actor, &player->actor) <= 45.0f) && + Actor_IsFacingPlayer(&this->actor, 0x38E3)) { player->actor.freezeTimer = 0; if ((player->transformation == PLAYER_FORM_GORON) || (player->transformation == PLAYER_FORM_DEKU)) { if (Actor_DistanceToPoint(&this->actor, &this->actor.home.pos) < 150.0f) { - func_808D5D88(this); + // 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. + EnRd_SetupGrabFail(this); } else { - func_808D53C0(this, globalCtx); + EnRd_SetupWalkToHome(this, globalCtx); } } else if (globalCtx->grabPlayer(globalCtx, player)) { - this->actor.flags &= ~1; - func_808D586C(this); + this->actor.flags &= ~ACTOR_FLAG_1; + EnRd_SetupGrab(this); } - } else if (this->actor.params > ENRD_GET_0) { + } else if (EN_RD_GET_TYPE(&this->actor) > EN_RD_TYPE_DOES_NOT_MOURN_IF_WALKING) { if (this->actor.parent != NULL) { - func_808D5660(this); + EnRd_SetupWalkToParent(this); } else { - this->unk_3EC = 0; + this->isMourning = false; } } if (Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 22.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D53C0(EnRd* this, GlobalContext* globalCtx) { - Animation_Change(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, Animation_GetLastFrame(&D_060113EC), 1, -4.0f); - this->unk_3EF = 2; - this->actionFunc = func_808D5440; +void EnRd_SetupWalkToHome(EnRd* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 0.5f, 0.0f, Animation_GetLastFrame(&gGibdoRedeadWalkAnim), + 1, -4.0f); + this->action = EN_RD_ACTION_WALKING_TO_HOME; + this->actionFunc = EnRd_WalkToHome; } -void func_808D5440(EnRd* this, GlobalContext* globalCtx) { +void EnRd_WalkToHome(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 pad; s16 sp36 = Actor_YawToPoint(&this->actor, &this->actor.home.pos); @@ -643,136 +721,142 @@ void func_808D5440(EnRd* this, GlobalContext* globalCtx) { } else { this->actor.speedXZ = 0.0f; if (!Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 450, 0)) { - if (this->actor.params != ENRD_GET_2) { - func_808D4308(this); + if (EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) { + EnRd_SetupIdle(this); } else { - func_808D60B0(this); + EnRd_SetupCrouch(this); } } } - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); this->actor.world.rot.y = this->actor.shape.rot.y; SkelAnime_Update(&this->skelAnime); if (!(player->stateFlags1 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && - !(player->stateFlags2 & 0x4080) && (player->transformation != PLAYER_FORM_GORON) && + !(player->stateFlags2 & (0x4000 | 0x80)) && (player->transformation != PLAYER_FORM_GORON) && (player->transformation != PLAYER_FORM_DEKU) && (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) < 150.0f)) { this->actor.targetMode = 0; - func_808D4FE0(this, globalCtx); - } else if (this->actor.params > ENRD_GET_0) { + EnRd_SetupWalkToPlayer(this, globalCtx); + } else if (EN_RD_GET_TYPE(&this->actor) > EN_RD_TYPE_DOES_NOT_MOURN_IF_WALKING) { if (this->actor.parent != NULL) { - func_808D5660(this); + EnRd_SetupWalkToParent(this); } else { - this->unk_3EC = 0; + this->isMourning = false; } } if (Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 22.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D5660(EnRd* this) { - f32 frameCount = Animation_GetLastFrame(&D_060113EC); +void EnRd_SetupWalkToParent(EnRd* this) { + f32 frameCount = Animation_GetLastFrame(&gGibdoRedeadWalkAnim); - Animation_Change(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, frameCount, 1, -4.0f); - this->unk_3EF = 3; - this->unk_3EC = 1; - this->actionFunc = func_808D56E4; + Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 0.5f, 0.0f, frameCount, 1, -4.0f); + this->action = EN_RD_ACTION_WALKING_TO_PARENT; + this->isMourning = true; + this->actionFunc = EnRd_WalkToParent; } -void func_808D56E4(EnRd* this, GlobalContext* globalCtx) { +/** + * When a Redead or Gibdo dies, it sets itself to be the parent for all other + * Redeads in the area that are capable of mourning. This function will make + * these Redeads walk over to the corpse and stand near until it begins to + * fade away. + */ +void EnRd_WalkToParent(EnRd* this, GlobalContext* globalCtx) { s32 pad; s16 yaw; - Vec3f sp2C; + Vec3f parentPos; if (this->actor.parent != NULL) { - sp2C = this->actor.parent->world.pos; - yaw = Actor_YawToPoint(&this->actor, &sp2C); + parentPos = this->actor.parent->world.pos; + yaw = Actor_YawToPoint(&this->actor, &parentPos); Math_SmoothStepToS(&this->actor.shape.rot.y, yaw, 1, 250, 0); - if (Actor_DistanceToPoint(&this->actor, &sp2C) >= 45.0f) { + if (Actor_DistanceToPoint(&this->actor, &parentPos) >= 45.0f) { this->actor.speedXZ = 0.4f; } else { this->actor.speedXZ = 0.0f; - if (this->actor.params != ENRD_GET_2) { - func_808D4308(this); + if (EN_RD_GET_TYPE(&this->actor) != EN_RD_TYPE_CRYING) { + EnRd_SetupIdle(this); } else { - func_808D60B0(this); + EnRd_SetupCrouch(this); } } - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 100, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 100, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 100, 0); } else { - func_808D4FE0(this, globalCtx); + EnRd_SetupWalkToPlayer(this, globalCtx); } this->actor.world.rot.y = this->actor.shape.rot.y; SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 22.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); } else if ((globalCtx->gameplayFrames & 0x5F) == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); } } -void func_808D586C(EnRd* this) { - Animation_PlayOnce(&this->skelAnime, &D_06006EEC); - this->unk_3D6 = 0; - this->unk_3EB = 0; - this->unk_3EA = 200; - this->unk_3EF = 10; +void EnRd_SetupGrab(EnRd* this) { + Animation_PlayOnce(&this->skelAnime, &gGibdoRedeadGrabStartAnim); + this->animationJudderTimer = 0; + this->grabState = 0; + this->grabDamageTimer = 200; + this->action = EN_RD_ACTION_GRABBING; this->actor.speedXZ = 0.0f; - this->actionFunc = func_808D58CC; + this->actionFunc = EnRd_Grab; } -void func_808D58CC(EnRd* this, GlobalContext* globalCtx) { +void EnRd_Grab(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 pad; if (SkelAnime_Update(&this->skelAnime)) { - this->unk_3EB++; + this->grabState++; } - switch (this->unk_3EB) { - case 1: - Animation_PlayLoop(&this->skelAnime, &D_06006678); - this->unk_3EB++; + switch (this->grabState) { + case EN_RD_GRAB_INITIAL_DAMAGE: + Animation_PlayLoop(&this->skelAnime, &gGibdoRedeadGrabAttackAnim); + this->grabState++; globalCtx->damagePlayer(globalCtx, -8); func_8013ECE0(this->actor.xzDistToPlayer, 255, 1, 12); - this->unk_3EA = 20; + this->grabDamageTimer = 20; - case 0: - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 1500, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 1500, 0); + case EN_RD_GRAB_START: + Math_SmoothStepToS(&this->headYRotation, 0, 1, 1500, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 1500, 0); - case 2: + case EN_RD_GRAB_ATTACK: if (!(player->stateFlags2 & 0x80) || (player->unk_B62 != 0)) { if ((player->unk_B62 != 0) && (player->stateFlags2 & 0x80)) { player->stateFlags2 &= ~0x80; player->unk_AE8 = 100; } - Animation_Change(&this->skelAnime, &D_06006B08, 0.5f, 0.0f, Animation_GetLastFrame(&D_06006B08), 3, - 0.0f); - this->unk_3EB++; - this->unk_3EF = 4; + Animation_Change(&this->skelAnime, &gGibdoRedeadGrabEndAnim, 0.5f, 0.0f, + Animation_GetLastFrame(&gGibdoRedeadGrabEndAnim), 3, 0.0f); + this->grabState++; + this->action = EN_RD_ACTION_WALKING_TO_PLAYER_OR_RELEASING_GRAB; break; } switch (player->transformation) { - case 0: - case 1: - case 2: - case 3: + case PLAYER_FORM_FIERCE_DEITY: + case PLAYER_FORM_GORON: + case PLAYER_FORM_ZORA: + case PLAYER_FORM_DEKU: break; - case 4: + case PLAYER_FORM_HUMAN: Math_SmoothStepToF(&this->actor.shape.yOffset, -1500.0f, 1.0f, 150.0f, 0.0f); break; } @@ -787,145 +871,148 @@ void func_808D58CC(EnRd* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, player->actor.shape.rot.y, 1, 6000, 0); if (Animation_OnFrame(&this->skelAnime, 0.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_ATTACK); } - this->unk_3EA--; - if (this->unk_3EA == 0) { + this->grabDamageTimer--; + if (this->grabDamageTimer == 0) { globalCtx->damagePlayer(globalCtx, -8); func_8013ECE0(this->actor.xzDistToPlayer, 240, 1, 12); - this->unk_3EA = 20; - func_800B8E58(&player->actor, player->ageProperties->unk_92 + 0x6805); + this->grabDamageTimer = 20; + func_800B8E58(player, player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S); } break; - case 3: + case EN_RD_GRAB_RELEASE: if (player->transformation != PLAYER_FORM_FIERCE_DEITY) { Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); } break; - case 4: + case EN_RD_GRAB_END: if (player->transformation != PLAYER_FORM_FIERCE_DEITY) { Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); } this->actor.targetMode = 0; - this->actor.flags |= 1; - this->unk_3ED = 10; - this->unk_3EE = 15; - func_808D4FE0(this, globalCtx); + this->actor.flags |= ACTOR_FLAG_1; + this->playerStunWaitTimer = 10; + this->grabWaitTimer = 15; + EnRd_SetupWalkToPlayer(this, globalCtx); break; } } -void func_808D5C54(EnRd* this) { - Animation_Change(&this->skelAnime, &D_060073A4, 0.0f, 0.0f, Animation_GetLastFrame(&D_060073A4), 2, 0.0f); - this->unk_3EF = 7; - this->actionFunc = func_808D5CCC; +void EnRd_SetupAttemptPlayerFreeze(EnRd* this) { + Animation_Change(&this->skelAnime, &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, + Animation_GetLastFrame(&gGibdoRedeadLookBackAnim), 2, 0.0f); + this->action = EN_RD_ACTION_ATTEMPTING_PLAYER_STUN; + this->actionFunc = EnRd_AttemptPlayerFreeze; } -void func_808D5CCC(EnRd* this, GlobalContext* globalCtx) { +void EnRd_AttemptPlayerFreeze(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - s16 temp_v0 = ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3D8) - this->unk_3DA; + s16 yaw = + ((this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->headYRotation) - this->upperBodyYRotation; - if (ABS_ALT(temp_v0) < 0x2008) { - if (!(this->unk_3DC & 0x80)) { + if (ABS_ALT(yaw) < 0x2008) { + if (!(this->flags & EN_RD_FLAG_CANNOT_FREEZE_PLAYER)) { 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); - func_808D4FE0(this, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); + EnRd_SetupWalkToPlayer(this, globalCtx); } } -void func_808D5D88(EnRd* this) { - this->unk_3EF = 8; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06009900, -6.0f); +void EnRd_SetupGrabFail(EnRd* this) { + this->action = EN_RD_ACTION_FAILING_GRAB; + Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadDamageAnim, -6.0f); this->actor.speedXZ = -2.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); - this->unk_3EF = 8; - this->actionFunc = func_808D5DF4; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->action = EN_RD_ACTION_FAILING_GRAB; + this->actionFunc = EnRd_GrabFail; } -void func_808D5DF4(EnRd* this, GlobalContext* globalCtx) { +void EnRd_GrabFail(EnRd* 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->unk_3D8, 0, 1, 300, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 300, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 300, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 300, 0); if (SkelAnime_Update(&this->skelAnime)) { this->actor.world.rot.y = this->actor.shape.rot.y; - func_808D5E98(this); + EnRd_SetupTurnAwayAndShakeHead(this); } } -void func_808D5E98(EnRd* this) { - f32 frameCount = Animation_GetLastFrame(&D_060113EC); +void EnRd_SetupTurnAwayAndShakeHead(EnRd* this) { + f32 frameCount = Animation_GetLastFrame(&gGibdoRedeadWalkAnim); - Animation_Change(&this->skelAnime, &D_060113EC, 0.5f, 0.0f, frameCount, 1, -4.0f); - this->unk_3EF = 9; - this->unk_3D4 = 0; - this->actionFunc = func_808D5F18; + Animation_Change(&this->skelAnime, &gGibdoRedeadWalkAnim, 0.5f, 0.0f, frameCount, 1, -4.0f); + this->action = EN_RD_ACTION_TURNING_AWAY_AND_SHAKING_HEAD; + this->headShakeTimer = 0; + this->actionFunc = EnRd_TurnAwayAndShakeHead; } -void func_808D5F18(EnRd* this, GlobalContext* globalCtx) { +void EnRd_TurnAwayAndShakeHead(EnRd* 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->unk_3D4 > 60) { - func_808D53C0(this, globalCtx); - this->unk_3D4 = 0; + if (this->headShakeTimer > 60) { + EnRd_SetupWalkToHome(this, globalCtx); + this->headShakeTimer = 0; } else { - this->unk_3D8 = Math_SinS(this->unk_3D4 * 4000) * (9583.0f * ((60 - this->unk_3D4) / 60.0f)); + this->headYRotation = Math_SinS(this->headShakeTimer * 4000) * (0x256F * ((60 - this->headShakeTimer) / 60.0f)); SkelAnime_Update(&this->skelAnime); - this->unk_3D4++; + this->headShakeTimer++; } } -void func_808D6008(EnRd* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A450, -4.0f); - this->unk_3EF = 5; - this->actionFunc = func_808D6054; +void EnRd_SetupStandUp(EnRd* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadStandUpAnim, -4.0f); + this->action = EN_RD_ACTION_STANDING_UP; + this->actionFunc = EnRd_StandUp; } -void func_808D6054(EnRd* this, GlobalContext* globalCtx) { +void EnRd_StandUp(EnRd* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { if (this->actor.parent != NULL) { - func_808D5660(this); + EnRd_SetupWalkToParent(this); } else { - func_808D5C54(this); + EnRd_SetupAttemptPlayerFreeze(this); } } } -void func_808D60B0(EnRd* this) { - Animation_Change(&this->skelAnime, &D_0600A450, -1.0f, Animation_GetLastFrame(&D_0600A450), 0.0f, 2, -4.0f); - this->unk_3EF = 6; - this->actionFunc = func_808D6130; +void EnRd_SetupCrouch(EnRd* this) { + Animation_Change(&this->skelAnime, &gGibdoRedeadStandUpAnim, -1.0f, + Animation_GetLastFrame(&gGibdoRedeadStandUpAnim), 0.0f, 2, -4.0f); + this->action = EN_RD_ACTION_CROUCHING; + this->actionFunc = EnRd_Crouch; } -void func_808D6130(EnRd* this, GlobalContext* globalCtx) { +void EnRd_Crouch(EnRd* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { - func_808D4308(this); + EnRd_SetupIdle(this); } } -void func_808D616C(EnRd* this) { +void EnRd_SetupDamage(EnRd* this) { this->actor.shape.yOffset = 0.0f; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06009900, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadDamageAnim, -6.0f); if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = -2.0f; } - this->actor.flags |= 1; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); - this->unk_3EF = 11; - this->actionFunc = func_808D6200; + this->actor.flags |= ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->action = EN_RD_ACTION_DAMAGE; + this->actionFunc = EnRd_Damage; } -void func_808D6200(EnRd* this, GlobalContext* globalCtx) { +void EnRd_Damage(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (this->actor.speedXZ < 0.0f) { @@ -933,197 +1020,197 @@ void func_808D6200(EnRd* this, GlobalContext* globalCtx) { } this->actor.world.rot.y = this->actor.yawTowardsPlayer; - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 300, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 300, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 300, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 300, 0); if (SkelAnime_Update(&this->skelAnime)) { this->actor.world.rot.y = this->actor.shape.rot.y; if (this->actor.parent != NULL) { - func_808D5660(this); + EnRd_SetupWalkToParent(this); } else if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { - func_808D53C0(this, globalCtx); + EnRd_SetupWalkToHome(this, globalCtx); } else { - func_808D4FE0(this, globalCtx); + EnRd_SetupWalkToPlayer(this, globalCtx); } this->unk_3F1 = -1; } } -void func_808D6310(EnRd* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06009298, -1.0f); - this->unk_3EF = 12; - this->unk_3D6 = 300; - this->actor.flags &= ~1; +void EnRd_SetupDead(EnRd* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGibdoRedeadDeathAnim, -1.0f); + this->action = EN_RD_ACTION_DEAD; + this->deathTimer = 300; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DEAD); - this->actionFunc = func_808D6388; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DEAD); + this->actionFunc = EnRd_Dead; } -void func_808D6388(EnRd* this, GlobalContext* globalCtx) { - if (this->actor.category != 6) { - func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 6); +void EnRd_Dead(EnRd* this, GlobalContext* globalCtx) { + if (this->actor.category != ACTORCAT_PROP) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_PROP); } - Math_SmoothStepToS(&this->unk_3D8, 0, 1, 2000, 0); - Math_SmoothStepToS(&this->unk_3DA, 0, 1, 2000, 0); + Math_SmoothStepToS(&this->headYRotation, 0, 1, 2000, 0); + Math_SmoothStepToS(&this->upperBodyYRotation, 0, 1, 2000, 0); if (SkelAnime_Update(&this->skelAnime)) { - if (this->unk_3D6 == 0) { - if (!Flags_GetSwitch(globalCtx, this->unk_3DC & 0x7F)) { - Actor_SetSwitchFlag(globalCtx, this->unk_3DC & 0x7F); + if (this->deathTimer == 0) { + if (!Flags_GetSwitch(globalCtx, EN_RD_GET_SWITCH_FLAG(this))) { + Flags_SetSwitch(globalCtx, EN_RD_GET_SWITCH_FLAG(this)); } - if (this->unk_3DE != 0) { - if (this->unk_3DE == 180) { - func_808D4190(globalCtx, this, 0); + if (this->alpha != 0) { + if (this->alpha == 180) { + EnRd_UpdateParentForOtherRedeads(globalCtx, &this->actor, false); } this->actor.scale.y -= (75.0f / 1000000.0f); - this->unk_3DE -= 5; + this->alpha -= 5; } else { Actor_MarkForDeath(&this->actor); } } else { - this->unk_3D6--; + this->deathTimer--; } } else if (Animation_OnFrame(&this->skelAnime, 33.0f) || Animation_OnFrame(&this->skelAnime, 40.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_GERUDOFT_DOWN); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GERUDOFT_DOWN); } } -void func_808D64D0(EnRd* this) { - this->unk_3EF = 1; - this->unk_3D6 = 0xA; +void EnRd_SetupStunned(EnRd* this) { + this->action = EN_RD_ACTION_STUNNED; + this->stunTimer = 10; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; - if (gSaveContext.unk_3F58 != 0) { - this->unk_3E9 = 1; - this->unk_3E0 = 600; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIGHT_ARROW_HIT); - func_800BCB70(&this->actor, 0x8000, 0x80C8, 0, 255); - } else if (this->unk_3F0 == 1) { - func_800BCB70(&this->actor, 0, 0xC8, 0, 40); - } else if (this->unk_3F0 == 12) { - func_800BCB70(&this->actor, 0, 0xC8, 0, 40); + if (gSaveContext.sunsSongState != SUNSSONG_INACTIVE) { + this->stunnedBySunsSong = true; + this->sunsSongStunTimer = 600; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LIGHT_ARROW_HIT); + Actor_SetColorFilter(&this->actor, 0x8000, 0x80C8, 0, 255); + } else if (this->damageEffect == EN_RD_DMGEFF_STUN) { + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 40); + } else if (this->damageEffect == EN_RD_DMGEFF_ZORA_MAGIC) { + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 40); } - this->actionFunc = func_808D65BC; + this->actionFunc = EnRd_Stunned; } -void func_808D65BC(EnRd* this, GlobalContext* globalCtx) { - if (this->unk_3D6 > 0) { - this->unk_3D6--; +void EnRd_Stunned(EnRd* this, GlobalContext* globalCtx) { + if (this->stunTimer > 0) { + this->stunTimer--; } - if (this->unk_3E9 != 0) { - if (this->unk_3E0 != 0) { - this->unk_3E0--; - if (this->unk_3E0 >= 255) { - func_800BCB70(&this->actor, 0x8000, 0x80C8, 0, 255); + if (this->stunnedBySunsSong) { + if (this->sunsSongStunTimer != 0) { + this->sunsSongStunTimer--; + if (this->sunsSongStunTimer >= 255) { + Actor_SetColorFilter(&this->actor, 0x8000, 0x80C8, 0, 255); } - if (this->unk_3E0 == 0) { - this->unk_3E9 = 0; - gSaveContext.unk_3F58 = 0; + if (this->sunsSongStunTimer == 0) { + this->stunnedBySunsSong = false; + gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } } } if (this->actor.colorFilterTimer == 0) { if (this->actor.colChkInfo.health == 0) { - func_808D4190(globalCtx, this, 1); - func_808D6310(this); + EnRd_UpdateParentForOtherRedeads(globalCtx, &this->actor, true); + EnRd_SetupDead(this); Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); } else { - func_808D616C(this); + EnRd_SetupDamage(this); } } } -void func_808D66A0(EnRd* this, GlobalContext* globalCtx) { - s16 phi_v0 = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_3DA; - s16 temp_v0 = CLAMP(phi_v0, -0x1F4, 0x1F4); +void EnRd_TurnTowardsPlayer(EnRd* this, GlobalContext* globalCtx) { + s16 headAngle = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->upperBodyYRotation; + s16 upperBodyAngle = CLAMP(headAngle, -500, 500); - phi_v0 -= this->unk_3D8; - phi_v0 = CLAMP(phi_v0, -0x1F4, 0x1F4); + headAngle -= this->headYRotation; + headAngle = CLAMP(headAngle, -500, 500); if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y) >= 0) { - this->unk_3DA += ABS_ALT(temp_v0); - this->unk_3D8 += ABS_ALT(phi_v0); + this->upperBodyYRotation += ABS_ALT(upperBodyAngle); + this->headYRotation += ABS_ALT(headAngle); } else { - this->unk_3DA -= ABS_ALT(temp_v0); - this->unk_3D8 -= ABS_ALT(phi_v0); + this->upperBodyYRotation -= ABS_ALT(upperBodyAngle); + this->headYRotation -= ABS_ALT(headAngle); } - this->unk_3DA = CLAMP(this->unk_3DA, -0x495F, 0x495F); - this->unk_3D8 = CLAMP(this->unk_3D8, -0x256F, 0x256F); + this->upperBodyYRotation = CLAMP(this->upperBodyYRotation, -0x495F, 0x495F); + this->headYRotation = CLAMP(this->headYRotation, -0x256F, 0x256F); } -void func_808D6814(EnRd* this, GlobalContext* globalCtx) { +void EnRd_UpdateDamage(EnRd* this, GlobalContext* globalCtx) { s32 pad; Player* player = GET_PLAYER(globalCtx); - if ((gSaveContext.unk_3F58 != 0) && (this->actor.shape.rot.x == 0) && (this->unk_3E9 == 0) && - (this->unk_3EF != 11) && (this->unk_3EF != 12) && (this->unk_3EF != 1)) { - func_808D64D0(this); + if ((gSaveContext.sunsSongState != SUNSSONG_INACTIVE) && (this->actor.shape.rot.x == 0) && + (!this->stunnedBySunsSong) && (this->action != EN_RD_ACTION_DAMAGE) && (this->action != EN_RD_ACTION_DEAD) && + (this->action != EN_RD_ACTION_STUNNED)) { + EnRd_SetupStunned(this); return; } if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; - this->unk_3F0 = this->actor.colChkInfo.damageEffect; + this->damageEffect = this->actor.colChkInfo.damageEffect; - if (this->unk_3EF == 13) { + if (this->action == EN_RD_ACTION_RISING_FROM_COFFIN) { return; } - func_800BE258(&this->actor, &this->collider.info); + Actor_SetDropFlag(&this->actor, &this->collider.info); if (player->unk_ADC != 0) { this->unk_3F1 = player->unk_ADD; } - switch (this->unk_3F0) { - case 12: - if ((this->actionFunc != func_808D58CC) && - ((this->actionFunc != func_808D65BC) || (this->unk_3D6 == 0))) { - this->unk_3E6 = 40; - this->unk_3E8 = 30; - this->unk_294 = 1.0f; - func_808D64D0(this); + switch (this->damageEffect) { + case EN_RD_DMGEFF_ZORA_MAGIC: + if ((this->actionFunc != EnRd_Grab) && ((this->actionFunc != EnRd_Stunned) || (this->stunTimer == 0))) { + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffAlpha = 1.0f; + EnRd_SetupStunned(this); } return; - case 1: - func_808D64D0(this); + case EN_RD_DMGEFF_STUN: + EnRd_SetupStunned(this); return; - case 2: - func_800BCB70(&this->actor, 0x4000, 255, 0, 40); - this->unk_3E6 = 180; - this->unk_3E8 = 0; - this->unk_3E9 = 0; - this->unk_3E0 = 0; - this->unk_294 = 1.0f; + case EN_RD_DMGEFF_FIRE_ARROW: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + this->drawDmgEffTimer = 180; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->stunnedBySunsSong = false; + this->sunsSongStunTimer = 0; + this->drawDmgEffAlpha = 1.0f; break; - case 4: - func_800BCB70(&this->actor, 0x4000, 255, 0, 40); - this->unk_3E6 = 60; - this->unk_3E8 = 20; - this->unk_3E9 = 0; - this->unk_3E0 = 0; - this->unk_294 = 1.0f; + case EN_RD_DMGEFF_LIGHT_ARROW: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + this->drawDmgEffTimer = 60; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->stunnedBySunsSong = false; + this->sunsSongStunTimer = 0; + this->drawDmgEffAlpha = 1.0f; break; - case 15: - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); - this->unk_3E9 = 0; - this->unk_3E0 = 0; + case EN_RD_DMGEFF_DAMAGE: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + this->stunnedBySunsSong = false; + this->sunsSongStunTimer = 0; break; - case 14: - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); - this->unk_3E9 = 0; - this->unk_3E0 = 0; + case EN_RD_DMGEFF_LIGHT_RAY: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + this->stunnedBySunsSong = false; + this->sunsSongStunTimer = 0; this->actor.colChkInfo.health = 0; break; @@ -1133,84 +1220,87 @@ void func_808D6814(EnRd* this, GlobalContext* globalCtx) { Actor_ApplyDamage(&this->actor); if (this->actor.colChkInfo.health == 0) { - func_808D4190(globalCtx, this, 1); - func_808D6310(this); + EnRd_UpdateParentForOtherRedeads(globalCtx, &this->actor, true); + EnRd_SetupDead(this); Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0x90); } else { - func_808D616C(this); + EnRd_SetupDamage(this); } } } -void func_808D6A94(EnRd* this, GlobalContext* globalCtx) { +void EnRd_UpdateCollision(EnRd* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((this->actor.colChkInfo.health > 0) && (this->unk_3EF != 10)) { + if ((this->actor.colChkInfo.health > 0) && (this->action != EN_RD_ACTION_GRABBING)) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (((this->unk_3EF != 11) || ((player->unk_ADC != 0) && (player->unk_ADD != this->unk_3F1))) && - ((this->actionFunc != func_808D65BC) || (this->unk_3D6 == 0))) { + if (((this->action != EN_RD_ACTION_DAMAGE) || ((player->unk_ADC != 0) && (player->unk_ADD != this->unk_3F1))) && + ((this->actionFunc != EnRd_Stunned) || (this->stunTimer == 0))) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } } } -void func_808D6B64(EnRd* this, GlobalContext* globalCtx) { - if (this->unk_3E6 > 0) { - this->unk_3E6--; +void EnRd_UpdateEffect(EnRd* this, GlobalContext* globalCtx) { + if (this->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; } - if (this->unk_3E6 < 20) { - Math_SmoothStepToF(&this->unk_298, 0.0f, 0.5f, 0.03f, 0.0f); - this->unk_294 = this->unk_3E6 * 0.05f; + if (this->drawDmgEffTimer < 20) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; } else { - Math_SmoothStepToF(&this->unk_298, 0.5f, 0.1f, 0.02f, 0.0f); + Math_SmoothStepToF(&this->drawDmgEffScale, 0.5f, 0.1f, 0.02f, 0.0f); } } void EnRd_Update(Actor* thisx, GlobalContext* globalCtx) { EnRd* this = THIS; - func_808D6814(this, globalCtx); - if ((gSaveContext.unk_3F58 != 0) && (this->unk_3E9 == 0)) { - gSaveContext.unk_3F58 = 0; + EnRd_UpdateDamage(this, globalCtx); + if ((gSaveContext.sunsSongState != SUNSSONG_INACTIVE) && (!this->stunnedBySunsSong)) { + gSaveContext.sunsSongState = SUNSSONG_INACTIVE; } - if ((this->unk_3F0 != 6) && ((this->unk_3EF != 13) || (this->unk_3F0 != 2))) { - if (this->unk_3ED != 0) { - this->unk_3ED--; + if ((this->damageEffect != EN_RD_DMGEFF_UNUSED_6) && + ((this->action != EN_RD_ACTION_RISING_FROM_COFFIN) || (this->damageEffect != EN_RD_DMGEFF_FIRE_ARROW))) { + if (this->playerStunWaitTimer != 0) { + this->playerStunWaitTimer--; } this->actionFunc(this, globalCtx); - if ((this->unk_3EF != 10) && (this->actor.speedXZ != 0.0f)) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if ((this->action != EN_RD_ACTION_GRABBING) && (this->actor.speedXZ != 0.0f)) { + Actor_MoveWithGravity(&this->actor); } - if ((this->actor.shape.rot.x == 0) && (this->unk_3EF != 10) && (this->actor.speedXZ != 0.0f)) { + if ((this->actor.shape.rot.x == 0) && (this->action != EN_RD_ACTION_GRABBING) && + (this->actor.speedXZ != 0.0f)) { Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 35.0f, 0x1D); } - if (this->unk_3EF == 7) { - func_808D66A0(this, globalCtx); + if (this->action == EN_RD_ACTION_ATTEMPTING_PLAYER_STUN) { + EnRd_TurnTowardsPlayer(this, globalCtx); } } this->actor.focus.pos = this->actor.world.pos; this->actor.focus.pos.y += 50.0f; - func_808D6A94(this, globalCtx); - func_808D4260(this, globalCtx); - func_808D6B64(this, globalCtx); + + EnRd_UpdateCollision(this, globalCtx); + EnRd_SetupDanceIfConditionsMet(this, globalCtx); + EnRd_UpdateEffect(this, globalCtx); } s32 EnRd_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, Gfx** gfx) { EnRd* this = THIS; - if (limbIndex == 23) { - rot->y += this->unk_3D8; - } else if (limbIndex == 12) { - rot->y += this->unk_3DA; + if (limbIndex == REDEAD_LIMB_HEAD_ROOT) { + rot->y += this->headYRotation; + } else if (limbIndex == REDEAD_LIMB_UPPER_BODY_ROOT) { + rot->y += this->upperBodyYRotation; } return false; } @@ -1218,12 +1308,17 @@ s32 EnRd_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, void EnRd_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { EnRd* this = THIS; - if ((this->unk_3E6 != 0) && - ((limbIndex == 3) || (limbIndex == 4) || (limbIndex == 6) || (limbIndex == 8) || (limbIndex == 9) || - (limbIndex == 11) || (limbIndex == 14) || (limbIndex == 16) || (limbIndex == 17) || (limbIndex == 18) || - (limbIndex == 20) || (limbIndex == 21) || (limbIndex == 22) || (limbIndex == 24) || (limbIndex == 25))) { - Matrix_GetStateTranslation(&this->unk_1DC[this->unk_290]); - this->unk_290++; + if ((this->drawDmgEffTimer != 0) && + ((limbIndex == REDEAD_LIMB_LEFT_THIGH) || (limbIndex == REDEAD_LIMB_LEFT_SHIN) || + (limbIndex == REDEAD_LIMB_LEFT_FOOT) || (limbIndex == REDEAD_LIMB_RIGHT_THIGH) || + (limbIndex == REDEAD_LIMB_RIGHT_SHIN) || (limbIndex == REDEAD_LIMB_RIGHT_FOOT) || + (limbIndex == REDEAD_LIMB_TORSO) || (limbIndex == REDEAD_LIMB_LEFT_SHOULDER_AND_UPPER_ARM) || + (limbIndex == REDEAD_LIMB_LEFT_FOREARM) || (limbIndex == REDEAD_LIMB_LEFT_HAND) || + (limbIndex == REDEAD_LIMB_RIGHT_SHOULDER_AND_UPPER_ARM) || (limbIndex == REDEAD_LIMB_RIGHT_FOREARM) || + (limbIndex == REDEAD_LIMB_RIGHT_HAND) || (limbIndex == REDEAD_LIMB_HEAD) || + (limbIndex == REDEAD_LIMB_PELVIS))) { + Matrix_MultZero(&this->limbPos[this->limbIndex]); + this->limbIndex++; } } @@ -1235,12 +1330,12 @@ void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - this->unk_290 = 0; + this->limbIndex = 0; - if (this->unk_3DE == 255) { + if (this->alpha == 255) { func_8012C28C(globalCtx->state.gfxCtx); - gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->unk_3DE); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->alpha); gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, @@ -1251,19 +1346,19 @@ void EnRd_Draw(Actor* thisx, GlobalContext* globalCtx) { } else { func_8012C2DC(globalCtx->state.gfxCtx); - gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_3DE); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha); gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnRd_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); - func_800BC620(&sp54, &D_808D7138, this->unk_3DE, globalCtx); + func_800BC620(&sp54, &D_808D7138, this->alpha, globalCtx); } CLOSE_DISPS(globalCtx->state.gfxCtx); - if (this->unk_3E6 > 0) { - func_800BE680(globalCtx, &this->actor, this->unk_1DC, ARRAY_COUNT(this->unk_1DC), this->unk_298, 0.5f, - this->unk_294, this->unk_3E8); + if (this->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, 0.5f, this->drawDmgEffAlpha, this->drawDmgEffType); } } diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.h b/src/overlays/actors/ovl_En_Rd/z_en_rd.h index 2c6637d76..7bf5a6ddc 100644 --- a/src/overlays/actors/ovl_En_Rd/z_en_rd.h +++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.h @@ -2,58 +2,74 @@ #define Z_EN_RD_H #include "global.h" +#include "objects/object_rd/object_rd.h" struct EnRd; typedef void (*EnRdActionFunc)(struct EnRd*, GlobalContext*); -typedef void (*EnRdFunc)(struct EnRd*); +typedef void (*EnRdSetupDanceFunc)(struct EnRd*); -#define ENRD_GET_80(thisx) ((thisx)->params & 0x80) -#define ENRD_GET_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_RD_GET_80(thisx) ((thisx)->params & 0x80) +#define EN_RD_GET_FLAGS(thisx) (((thisx)->params & 0xFF00) >> 8) +#define EN_RD_GET_TYPE(thisx) ((thisx)->params) +#define EN_RD_GET_SWITCH_FLAG(this) ((this)->flags & 0x7F) -enum { - /* -2 */ ENRD_GET_MINUS_2 = -2, - /* -1 */ ENRD_GET_MINUS_1 = -1, - /* 0x00 */ ENRD_GET_0 = 0, - /* 0x01 */ ENRD_GET_1, - /* 0x02 */ ENRD_GET_2, - /* 0x03 */ ENRD_GET_3, - /* 0x04 */ ENRD_GET_4, - /* 0x05 */ ENRD_GET_5, -}; +#define EN_RD_FLAG_CANNOT_FREEZE_PLAYER (1 << 7) + +typedef enum { + /* -3 */ EN_RD_TYPE_GIBDO_RISING_OUT_OF_COFFIN = -3, // Unused OoT leftover + /* -2 */ EN_RD_TYPE_GIBDO = -2, // Unused OoT leftover + /* -1 */ EN_RD_TYPE_DOES_NOT_MOURN = -1, // Unused OoT leftover + /* 0 */ EN_RD_TYPE_DOES_NOT_MOURN_IF_WALKING = 0, // Unused OoT leftover. Still mourns, but it must come to a complete stop first + /* 1 */ EN_RD_TYPE_REGULAR, // Unused OoT leftover + /* 2 */ EN_RD_TYPE_CRYING, // Unused in the final game + /* 3 */ EN_RD_TYPE_INVISIBLE, // Unused OoT leftover + /* 4 */ EN_RD_TYPE_FROZEN, // Unused in the final game + /* 5 */ EN_RD_TYPE_SQUATTING_DANCE, + /* 6 */ EN_RD_TYPE_CLAPPING_DANCE, + /* 7 */ EN_RD_TYPE_PIROUETTE, +} EnRdType; typedef struct EnRd { /* 0x0000 */ Actor actor; /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnRdActionFunc actionFunc; - /* 0x018C */ EnRdFunc unkFunc; + /* 0x018C */ EnRdSetupDanceFunc setupDanceFunc; /* 0x0190 */ ColliderCylinder collider; - /* 0x01DC */ Vec3f unk_1DC[15]; - /* 0x0290 */ s32 unk_290; - /* 0x0294 */ f32 unk_294; - /* 0x0298 */ f32 unk_298; - /* 0x029C */ Vec3s jointTable[26]; - /* 0x0338 */ Vec3s morphTable[26]; - /* 0x03D4 */ s16 unk_3D4; - /* 0x03D6 */ s16 unk_3D6; - /* 0x03D8 */ s16 unk_3D8; - /* 0x03DA */ s16 unk_3DA; - /* 0x03DC */ s16 unk_3DC; - /* 0x03DE */ s16 unk_3DE; - /* 0x03E0 */ s16 unk_3E0; - /* 0x03E2 */ s16 unk_3E2; - /* 0x03E4 */ s16 unk_3E4; - /* 0x03E6 */ s16 unk_3E6; - /* 0x03E8 */ u8 unk_3E8; - /* 0x03E9 */ u8 unk_3E9; - /* 0x03EA */ u8 unk_3EA; - /* 0x03EB */ u8 unk_3EB; - /* 0x03EC */ u8 unk_3EC; - /* 0x03ED */ u8 unk_3ED; - /* 0x03EE */ u8 unk_3EE; - /* 0x03EF */ u8 unk_3EF; - /* 0x03F0 */ u8 unk_3F0; - /* 0x03F1 */ s8 unk_3F1; + /* 0x01DC */ Vec3f limbPos[15]; + /* 0x0290 */ s32 limbIndex; + /* 0x0294 */ f32 drawDmgEffAlpha; + /* 0x0298 */ f32 drawDmgEffScale; + /* 0x029C */ Vec3s jointTable[REDEAD_LIMB_MAX]; + /* 0x0338 */ Vec3s morphTable[REDEAD_LIMB_MAX]; + /* 0x03D4 */ s16 headShakeTimer; + /* 0x03D6 */ union { + s16 animationJudderTimer; + s16 stunTimer; + s16 deathTimer; + s16 coffinRiseForwardAccelTimer; + }; + /* 0x03D8 */ s16 headYRotation; + /* 0x03DA */ s16 upperBodyYRotation; + /* 0x03DC */ s16 flags; + /* 0x03DE */ s16 alpha; + /* 0x03E0 */ s16 sunsSongStunTimer; + /* 0x03E2 */ UNK_TYPE1 unk3E2[0x2]; + /* 0x03E4 */ union { + s16 danceEndTimer; + s16 pirouetteRotationalVelocity; + }; + /* 0x03E6 */ s16 drawDmgEffTimer; + /* 0x03E8 */ u8 drawDmgEffType; + /* 0x03E9 */ u8 stunnedBySunsSong; + /* 0x03EA */ u8 grabDamageTimer; + /* 0x03EB */ u8 grabState; + /* 0x03EC */ u8 isMourning; + /* 0x03ED */ u8 playerStunWaitTimer; // Cannot stun the player if this is non-zero + /* 0x03EE */ u8 grabWaitTimer; // Cannot grab the player if this is non-zero + /* 0x03EF */ u8 action; + /* 0x03F0 */ u8 damageEffect; + /* 0x03F1 */ s8 unk_3F1; // related to player->unk_ADD } EnRd; // size = 0x3F4 extern const ActorInit En_Rd_InitVars; 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 516dae5cc..13ab86f52 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c @@ -1,6 +1,13 @@ -#include "z_en_recepgirl.h" +/* + * File: z_en_recepgirl.c + * Overlay: ovl_En_Recepgirl + * Description: Mayor's receptionist + */ -#define FLAGS 0x00000009 +#include "z_en_recepgirl.h" +#include "objects/object_bg/object_bg.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnRecepgirl*)thisx) @@ -9,7 +16,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, @@ -22,38 +33,185 @@ const ActorInit En_Recepgirl_InitVars = { (ActorFunc)EnRecepgirl_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C106C0[] = { +static TexturePtr sEyeTextures[] = { object_bg_Tex_00F8F0, object_bg_Tex_00FCF0, object_bg_Tex_0100F0, + object_bg_Tex_00FCF0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), }; -#endif +static s32 texturesDesegmented = false; -extern InitChainEntry D_80C106C0[]; +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + s32 i; -extern UNK_TYPE D_06001384; -extern UNK_TYPE D_06009890; -extern UNK_TYPE D_0600A280; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_bg_Skel_011B60, &object_bg_Anim_009890, this->jointTable, + this->morphTable, 24); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.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/EnRecepgirl_Destroy.s") + this->eyeTexIndex = 2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.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_80C10148.s") + EnRecepgirl_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.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/func_80C102D4.s") +void EnRecepgirl_SetupWait(EnRecepgirl* this) { + if (this->skelAnime.animation == &object_bg_Anim_001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f); + } + this->actionFunc = EnRecepgirl_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") +void EnRecepgirl_Wait(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &object_bg_Anim_00A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &object_bg_Anim_009890, -4.0f); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + EnRecepgirl_SetupTalk(this); + } else if (Actor_IsFacingPlayer(&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/func_80C10590.s") +void EnRecepgirl_SetupTalk(EnRecepgirl* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00A280, -4.0f); + this->actionFunc = EnRecepgirl_Talk; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_Talk(EnRecepgirl* this, GlobalContext* globalCtx) { + u8 talkState; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &object_bg_Anim_00A280) { + Animation_PlayLoop(&this->skelAnime, &object_bg_Anim_001384); + } else if (this->skelAnime.animation == &object_bg_Anim_00AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 10.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } + } else { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToLoop(&this->skelAnime, &object_bg_Anim_009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00A280, -4.0f); + } + } + } + + talkState = Message_GetState(&globalCtx->msgCtx); + if (talkState == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + EnRecepgirl_SetupWait(this); + } else if ((talkState == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Flags_SetSwitch(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f); + + if (gSaveContext.save.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, &object_bg_Anim_00AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_000968, 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_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateYS(0x400 - this->headRot.x, MTXMODE_APPLY); + Matrix_MultVecX(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]); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnRecepgirl_OverrideLimbDraw, NULL, + EnRecepgirl_TransformLimbDraw, &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 67d08ed98..c5f2954f9 100644 --- a/src/overlays/actors/ovl_En_Rg/z_en_rg.c +++ b/src/overlays/actors/ovl_En_Rg/z_en_rg.c @@ -1,6 +1,14 @@ -#include "z_en_rg.h" +/* + * File: z_en_rg.c + * Overlay: ovl_En_Rg + * Description: Racing Goron + */ -#define FLAGS 0x80000010 +#include "z_en_rg.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_oF1d_map/object_oF1d_map.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80000000) #define THIS ((EnRg*)thisx) @@ -12,7 +20,8 @@ void EnRg_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BF4EBC(EnRg* this, GlobalContext* globalCtx); void func_80BF4FC4(EnRg* this, GlobalContext* globalCtx); -#if 0 +s32 D_80BF5C10; + const ActorInit En_Rg_InitVars = { ACTOR_EN_RG, ACTORCAT_NPC, @@ -25,25 +34,49 @@ const ActorInit En_Rg_InitVars = { (ActorFunc)EnRg_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80BF5760 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_PLAYER | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_PLAYER | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BF578C = { - { 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, + }, { 20, 62, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BF57B8 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80BF57C4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -78,75 +111,760 @@ static DamageTable D_80BF57C4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +s32 D_80BF57E4[][4] = { + { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, + { 11, 11, 8, 10 }, { 16, 12, 12, 14 }, { 19, 15, 15, 18 }, { 25, 17, 18, 22 }, { 29, 20, 23, 28 }, + { 39, 24, 28, 33 }, { 43, 27, 33, 37 }, { 46, 28, 36, 37 }, { 51, 30, 38, 39 }, { 54, 33, 42, 40 }, + { 56, 34, 44, 41 }, { 60, 38, 50, 45 }, { 67, 42, 55, 49 }, { 74, 47, 61, 54 }, +}; -extern ColliderSphereInit D_80BF5760; -extern ColliderCylinderInit D_80BF578C; -extern CollisionCheckInfoInit2 D_80BF57B8; -extern DamageTable D_80BF57C4; +AnimationInfoS D_80BF5914[] = { + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, ANIMMODE_ONCE, 0 }, +}; -extern UNK_TYPE D_060091A8; -extern UNK_TYPE D_06011AC8; -extern UNK_TYPE D_06014D00; +TexturePtr D_80BF5934[] = { + gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3920.s") +Color_RGBA8 D_80BF5954[] = { + { 255, 255, 255, 0 }, + { 170, 130, 90, 0 }, + { 0, 0, 0, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3C64.s") +Color_RGBA8 D_80BF5960[] = { + { 255, 255, 255, 0 }, + { 100, 60, 20, 0 }, + { 0, 0, 0, 0 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3DA0.s") +Vec3f D_80BF596C[] = { + { -2473.0f, 39.0f, 7318.0f }, { -2223.0f, 142.0f, 7184.0f }, { -2281.0f, 41.0f, 7718.0f }, + { -2136.0f, 96.0f, 7840.0f }, { -2432.0f, 6.0f, 7857.0f }, { -2412.0f, 139.0f, 6872.0f }, + { -2719.0f, 39.0f, 7110.0f }, { -2289.0f, 67.0f, 7463.0f }, { -2820.0f, 85.0f, 6605.0f }, + { -2088.0f, 160.0f, 7584.0f }, { -2503.0f, 1.0f, 7643.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3DC4.s") +EffectTireMarkInit D_80BF59F0 = { + 0, + 62, + { 0, 0, 15, 100 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3E88.s") +TexturePtr D_80BF59F8[] = { + 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, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3ED4.s") +void func_80BF3920(EnRgStruct* ptr, GlobalContext* globalCtx) { + f32 temp_f20; + u8 phi_fp = false; + s32 i; + s32 idx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3F14.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF3FF8.s") + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4024.s") + for (i = 0; i < 32; i++, ptr++) { + if ((ptr->unk_00 >= 4) && (ptr->unk_00 < 7)) { + if (!phi_fp) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, sizeof(Gfx) * 0); + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014CF0); + phi_fp = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF409C.s") + Matrix_Push(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF40F4.s") + if (globalCtx) {} + temp_f20 = (f32)ptr->unk_02 / ptr->unk_01; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF416C.s") + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80BF5954[ptr->unk_00 - 4].r, D_80BF5954[ptr->unk_00 - 4].g, + D_80BF5954[ptr->unk_00 - 4].b, (u8)(temp_f20 * 255.0f)); + gDPSetEnvColor(POLY_XLU_DISP++, D_80BF5960[ptr->unk_00 - 4].r, D_80BF5960[ptr->unk_00 - 4].g, + D_80BF5960[ptr->unk_00 - 4].b, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4220.s") + Matrix_Translate(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_ReplaceRotation(&globalCtx->billboardMtxF); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF42BC.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + idx = temp_f20 * 7.0f; + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BF5934[idx])); + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014D00); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF43FC.s") + Matrix_Pop(); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4560.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF45B4.s") +void func_80BF3C64(EnRg* this) { + EnRgStruct* ptr = this->unk_34C; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF47AC.s") + for (i = 0; i < ARRAY_COUNT(this->unk_34C); i++, ptr++) { + if (ptr->unk_00) { + if (!ptr->unk_02) { + ptr->unk_00 = 0; + } 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; + ptr->unk_28.x += ptr->unk_1C.x; + ptr->unk_28.y += ptr->unk_1C.y; + ptr->unk_28.z += ptr->unk_1C.z; + ptr->unk_34 += ptr->unk_38; + ptr->unk_02--; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4934.s") +void func_80BF3DA0(EnRg* this, GlobalContext* globalCtx) { + func_80BF3920(this->unk_34C, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4964.s") +void func_80BF3DC4(EnRg* this, GlobalContext* globalCtx) { + this->collider2.dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider2.dim.worldSphere.center.y = this->actor.world.pos.y + this->actor.shape.yOffset; + this->collider2.dim.worldSphere.center.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4AB8.s") + if (this->actor.speedXZ >= 10.0f) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4D64.s") +void func_80BF3E88(EnRg* this, GlobalContext* globalCtx) { + Math_Vec3f_ToVec3s(&this->collider1.dim.pos, &this->actor.world.pos); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4DA8.s") +void func_80BF3ED4(EnRg* this, GlobalContext* globalCtx) { + if (this->unk_310 & 0x10) { + func_80BF3DC4(this, globalCtx); + } else { + func_80BF3E88(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4EBC.s") +s32 func_80BF3F14(EnRg* this, GlobalContext* globalCtx) { + this->unk_310 &= ~0x20; + this->unk_310 &= ~0x40; + this->unk_310 &= ~0x80; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF4FC4.s") + if ((this->collider1.base.atFlags & AT_HIT) || (this->collider2.base.atFlags & AT_HIT)) { + this->collider1.base.atFlags &= ~AT_HIT; + this->collider2.base.atFlags &= ~AT_HIT; + this->unk_310 |= 0x20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/EnRg_Init.s") + if ((this->collider1.base.acFlags & AC_HIT) || (this->collider2.base.acFlags & AC_HIT)) { + this->collider1.base.acFlags &= ~AC_HIT; + this->collider2.base.acFlags &= ~AC_HIT; + this->unk_310 |= 0x40; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/EnRg_Destroy.s") + if ((this->collider1.base.ocFlags1 & OC1_HIT) || (this->collider2.base.ocFlags1 & OC1_HIT)) { + this->collider1.base.ocFlags1 &= ~OC1_HIT; + this->collider2.base.ocFlags1 &= ~OC1_HIT; + this->unk_310 |= 0x80; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/EnRg_Update.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF547C.s") +void func_80BF3FF8(EnRg* this) { + this->skelAnime.playSpeed = this->unk_314; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/func_80BF5588.s") +s32 func_80BF4024(EnRg* this, GlobalContext* globalCtx) { + if ((globalCtx->csCtx.state == 0) && (this->unk_334 == 1)) { + if (Animation_OnFrame(&this->skelAnime, 2.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_CIRCLE); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rg/EnRg_Draw.s") + if (Animation_OnFrame(&this->skelAnime, 22.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_SIT_IMT); + } + } + + return false; +} + +s32 func_80BF409C(EnRg* this, s32 arg1) { + s32 ret = false; + + if (arg1 != this->unk_334) { + this->unk_334 = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80BF5914, arg1); + this->unk_314 = this->skelAnime.playSpeed; + } + return ret; +} + +void func_80BF40F4(EnRg* this) { + if (DECR(this->unk_31C) == 0) { + this->unk_31E++; + if (this->unk_31E >= 4) { + this->unk_31C = Rand_S16Offset(30, 30); + this->unk_31E = 0; + } + } +} + +s32 func_80BF416C(EnRg* this, GlobalContext* globalCtx) { + if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ >= 0.01f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_ROLLING - SFX_FLAG); + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->unk_340), &this->actor.world.pos, 18.0f, + this->actor.shape.rot.y, this->actor.floorPoly, this->actor.floorBgId); + } else { + func_800AEF44(Effect_GetByIndex(this->unk_340)); + } + return false; +} + +s32 func_80BF4220(EnRg* this, GlobalContext* globalCtx, Actor* arg2) { + CollisionPoly* sp44 = NULL; + s32 sp40; + Vec3f sp34; + + if (Actor_ActorAIsFacingAndNearActorB(&this->actor, arg2, 400.0f, 0x2000) && + !BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &arg2->world.pos, &sp34, &sp44, true, + false, false, true, &sp40)) { + return true; + } + return false; +} + +s32 func_80BF42BC(EnRg* this, f32 arg1) { + f32 sp2C; + s32 sp24; + + Math_ApproachF(&this->actor.speedXZ, arg1, 0.3f, 0.5f); + + sp2C = this->actor.speedXZ * (1.0f / 26); + if (sp2C > 1.0f) { + sp2C = 1.0f; + } + sp24 = 5460.0f * sp2C; + + this->actor.scale.x = 0.01f - (Math_SinS(sp24) * 0.01f); + this->actor.scale.y = (Math_SinS(sp24) * 0.01f) + 0.01f; + this->actor.scale.z = (Math_SinS(sp24) * 0.01f) + 0.01f; + + this->actor.shape.yOffset = this->actor.scale.y * 100.0f * 14.0f; + if (!(this->unk_310 & 0x1000)) { + this->actor.shape.rot.x += (s16)(13650.0f * sp2C); + } + + this->actor.world.rot.x = this->actor.shape.rot.x; + return false; +} + +s32 func_80BF43FC(EnRg* this) { + Vec3f sp9C; + Vec3f sp90; + f32 sp8C; + f32 sp88; + f32 sp84; + f32 phi_f20 = 0.0f; + s32 temp_s7 = ENRG_GET_7F80(&this->actor); + s32 phi_s4 = -1; + s32 temp_s5 = this->unk_344; + s16 phi_s6 = 0; + s32 phi_s0 = D_80BF57E4[this->unk_344][temp_s7]; + + do { + SubS_CopyPointFromPathCheckBounds(this->path, phi_s0 - 1, &sp9C); + SubS_CopyPointFromPathCheckBounds(this->path, phi_s0 + 1, &sp90); + if (Math3D_PointDistToLine2D(this->actor.world.pos.x, this->actor.world.pos.z, sp9C.x, sp9C.z, sp90.x, sp90.z, + &sp8C, &sp88, &sp84) && + (!phi_s6 || ((phi_s4 + 1) == phi_s0) || (sp84 < phi_f20))) { + phi_s6 = 1; + phi_f20 = sp84; + phi_s4 = phi_s0; + } + phi_s0++; + } while ((temp_s5 != 18) && (phi_s0 < D_80BF57E4[temp_s5 + 1][temp_s7])); + + return phi_s4; +} + +s32 func_80BF4560(EnRg* this, GlobalContext* globalCtx) { + s32 temp_v0 = SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + + if ((temp_v0 < 4) || (temp_v0 >= 19)) { + temp_v0 = -1; + } + return temp_v0; +} + +s32 func_80BF45B4(EnRg* this) { + s32 sp24 = 0; + s32 ret = false; + s16 temp_v0; + s16 temp_v1; + + if ((this->actor.bgCheckFlags & 8) && (this->actor.speedXZ >= 5.0f)) { + temp_v1 = this->actor.world.rot.y; + temp_v0 = temp_v1 - BINANG_ROT180(this->actor.wallYaw); + + if (ABS_ALT(temp_v0) >= 0x3400) { + this->actor.world.rot.y = BINANG_ROT180(BINANG_ROT180(this->actor.wallYaw) - temp_v0); + this->unk_322 = 0xA; + } else if (ABS_ALT(temp_v0) >= 0x1000) { + this->actor.world.rot.y = BINANG_ROT180(BINANG_ROT180(this->actor.wallYaw) - temp_v0); + this->actor.speedXZ *= 0.75f; + this->unk_322 = 0xA; + } else { + this->actor.world.rot.y = BINANG_ROT180(temp_v1); + ret = 1; + this->actor.speedXZ *= 0.25f; + } + sp24 = 1; + } else if (this->unk_310 & 0x40) { + s16 yaw = Actor_YawBetweenActors(&this->actor, ((void)0, this->collider2.base.ac)); + + sp24 = 2; + if (this->actor.colorFilterTimer == 0) { + this->actor.speedXZ *= 0.5f; + if ((s16)(yaw - this->actor.world.rot.y) > 0) { + this->actor.world.rot.y -= 0x2000; + } else { + this->actor.world.rot.y += 0x2000; + } + } + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + this->unk_322 = 0xA; + } + + if (sp24) { + this->unk_310 &= ~0x800; + this->unk_310 &= ~0x40; + if ((this->unk_18C != NULL) && (this->unk_18C->id == ACTOR_PLAYER)) { + D_80BF5C10 = 0; + } + this->unk_18C = NULL; + this->unk_324 = 0; + } + return ret; +} + +s32 func_80BF47AC(EnRg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 phi_f0; + f32 phi_f2; + + if (player->linearVelocity < 20.0f) { + phi_f2 = 20.0f; + } else { + phi_f2 = player->linearVelocity; + } + + if ((this->unk_310 & 0x400) || (this->unk_310 & 0x1000)) { + phi_f0 = 0.0f; + } else if (this->numCheckpointsAheadOfPlayer >= 2) { + phi_f0 = phi_f2 * 0.5f; + } else if (this->numCheckpointsAheadOfPlayer == 1) { + phi_f0 = phi_f2 * 0.75f; + } else if (this->numCheckpointsAheadOfPlayer == 0) { + s16 temp_v0_3 = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + + if ((ABS_ALT(temp_v0_3) > 0x4000) || (this->unk_326 > 0)) { + phi_f0 = phi_f2 * 0.72f; + } else { + phi_f0 = phi_f2 * 0.94f; + } + } else if (this->numCheckpointsAheadOfPlayer == -1) { + phi_f0 = phi_f2 * 1.6f; + } else { + phi_f0 = 2.0f * phi_f2; + } + + if (phi_f0 > 0.0f) { + if (this->unk_320 != 0) { + this->unk_320--; + } + phi_f2 = this->unk_320 * 0.01f; + phi_f0 += phi_f2; + } + + func_80BF42BC(this, phi_f0); + + return false; +} + +void func_80BF4934(EnRg* this) { + if (this->unk_318 == 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_DASH); + } +} + +void func_80BF4964(EnRg* this) { + Vec3s* sp3C; + Vec3f sp30; + + if (this->path != NULL) { + sp3C = Lib_SegmentedToVirtual(this->path->points); + + if (SubS_HasReachedPoint(&this->actor, this->path, this->unk_33C)) { + if ((this->path->count - 1) < (this->unk_33C + 1)) { + this->unk_33C = this->path->count - 1; + } else { + this->unk_33C++; + } + } + + if (this->unk_322 != 0) { + this->unk_322--; + } + + if (this->unk_324 != 0) { + this->unk_324--; + } + + if (this->unk_326 != 0) { + this->unk_326--; + } + + if (!(this->unk_310 & 0x400) && !(this->unk_310 & 0x1000) && (this->unk_322 == 0) && (this->unk_324 == 0) && + (this->actor.bgCheckFlags & 1)) { + if (this->unk_18C == NULL) { + Math_Vec3s_ToVec3f(&sp30, &sp3C[this->unk_33C]); + } else { + Math_Vec3f_Copy(&sp30, &this->unk_18C->world.pos); + } + Math_ApproachS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp30), 10, 0x71C); + } + } +} + +void func_80BF4AB8(EnRg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Actor* phi_s0; + + phi_s0 = NULL; + if (!(this->unk_310 & 0x800)) { + if (this->unk_320 == 0) { + do { + phi_s0 = SubS_FindActor(globalCtx, phi_s0, 6, ACTOR_OBJ_TSUBO); + if (phi_s0 != NULL) { + if (func_80BF4220(this, globalCtx, phi_s0) && (phi_s0->update != NULL)) { + this->unk_18C = phi_s0; + this->unk_310 |= 0x800; + break; + } + phi_s0 = phi_s0->next; + } + } while (phi_s0 != NULL); + } + + if ((phi_s0 == NULL) && (D_80BF5C10 == 0) && (this->unk_326 == 0) && (player->stateFlags3 & 0x80000) && + (player->invincibilityTimer == 0) && func_80BF4220(this, globalCtx, &player->actor)) { + this->unk_18C = &player->actor; + this->unk_310 |= 0x800; + D_80BF5C10 = 1; + } + } else if ((this->unk_18C != NULL) && !func_80BF4220(this, globalCtx, this->unk_18C)) { + if (this->unk_18C->id == ACTOR_PLAYER) { + D_80BF5C10 = 0; + } + this->unk_18C = NULL; + this->unk_310 &= ~0x800; + } + + if (this->unk_310 & 0x20) { + if (this->collider2.base.at != NULL) { + if (this->collider2.base.at->id == ACTOR_OBJ_TSUBO) { + this->collider2.base.at->params |= 0x3F; + this->unk_320 += 0x190; + this->unk_320 = CLAMP_MAX(this->unk_320, 0x190); + } else if (this->collider2.base.at->id == ACTOR_PLAYER) { + this->unk_326 = 0x28; + if (player->stateFlags3 & 0x1000) { + player->linearVelocity *= 0.5f; + player->unk_B08[0] = player->linearVelocity; + player->unk_B08[1] += player->linearVelocity * 0.05f; + if (BINANG_SUB(this->actor.yawTowardsPlayer, player->currentYaw) > 0) { + player->currentYaw += 0x2000; + } else { + player->currentYaw -= 0x2000; + } + player->unk_B8C = 4; + player->invincibilityTimer = 20; + player->actor.home.rot.y = player->actor.world.rot.y; + player->actor.shape.rot.y = player->actor.world.rot.y; + } + + if ((this->unk_18C != NULL) && (this->unk_18C->id == ACTOR_PLAYER)) { + D_80BF5C10 = 0; + } + } + } + this->unk_18C = NULL; + this->unk_310 &= ~0x800; + this->unk_310 &= ~0x20; + } +} + +s32 func_80BF4D64(Vec3f* arg0) { + return Math3D_XZBoundCheck(-1261.0f, -901.0f, -1600.0f, -1520.0f, arg0->x, arg0->z); +} + +s32 func_80BF4DA8(EnRg* this) { + s32 pad[4]; + s32 ret = false; + f32 temp_f20; + s16 temp_v1; + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_80BF596C); i++) { + temp_f20 = Actor_XZDistanceToPoint(&this->actor, &D_80BF596C[i]); + temp_v1 = Actor_YawToPoint(&this->actor, &D_80BF596C[i]) - this->actor.world.rot.y; + + if ((temp_f20 < 100.0f) && (ABS_ALT(temp_v1) < 0xC00)) { + if (temp_v1 > 0) { + this->actor.world.rot.y -= 0x1600; + } else { + this->actor.world.rot.y += 0x1600; + } + + this->unk_324 = 20; + this->unk_310 &= ~0x800; + + if ((this->unk_18C != NULL) && (this->unk_18C->id == ACTOR_PLAYER)) { + D_80BF5C10 = 0; + } + + this->unk_18C = NULL; + ret = true; + break; + } + } + return ret; +} + +void func_80BF4EBC(EnRg* this, GlobalContext* globalCtx) { + if (this->unk_310 & 0x100) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_310 &= ~0x100; + this->unk_310 |= 0x10; + this->unk_320 = 0; + this->actor.shape.yOffset = 14.0f; + this->actionFunc = func_80BF4FC4; + } + } else if (gSaveContext.save.weekEventReg[12] & 2) { + if (DECR(this->unk_318) == 0) { + func_80BF409C(this, 1); + this->unk_310 &= ~8; + this->unk_310 &= ~0x10; + this->unk_310 |= 0x100; + this->actor.shape.yOffset = 0.0f; + this->unk_318 = Rand_S16Offset(0, 20); + } + } + SubS_FillLimbRotTables(globalCtx, this->unk_32E, this->unk_328, ARRAY_COUNT(this->unk_328)); +} + +void func_80BF4FC4(EnRg* this, GlobalContext* globalCtx) { + this->unk_344 = func_80BF4560(this, globalCtx); + + if (!Play_InCsMode(globalCtx)) { + if (this->actor.bgCheckFlags & 2) { + if (this->unk_310 & 0x400) { + this->unk_310 &= ~0x400; + this->actor.speedXZ = 0.0f; + } + + if (this->unk_344 != -1) { + this->unk_33C = func_80BF43FC(this); + if (this->unk_33C >= 0) { + this->unk_33C++; + } + } + } else if ((this->actor.bgCheckFlags & 1) && !(this->unk_310 & 0x1000) && + func_80BF4D64(&this->actor.world.pos)) { + this->unk_310 |= 0x1000; + } + + if ((this->unk_18C != NULL) && (this->unk_18C->update == NULL)) { + this->unk_18C = NULL; + this->unk_310 &= ~0x800; + } + + if (gSaveContext.eventInf[1] & 1) { + if (DECR(this->unk_318) == 0) { + func_80BF47AC(this, globalCtx); + + if ((this->unk_324 == 0) && !func_80BF4DA8(this)) { + func_80BF4AB8(this, globalCtx); + } + + if (func_80BF45B4(this)) { + this->unk_310 |= 0x400; + this->actor.velocity.y = 7.0f; + } + + func_80BF4964(this); + Actor_UpdateVelocityWithGravity(&this->actor); + Actor_UpdatePos(&this->actor); + func_80BF416C(this, globalCtx); + return; + } + } + func_80BF4934(this); + } +} + +void EnRg_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRg* this = THIS; + + if (gSaveContext.save.entranceIndex == 0xD010) { + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_oF1d_map_Skel_011AC8, NULL, this->jointTable, + this->morphTable, 18); + + this->unk_334 = -1; + func_80BF409C(this, 0); + this->skelAnime.curFrame = this->skelAnime.endFrame; + + Collider_InitAndSetSphere(globalCtx, &this->collider2, &this->actor, &sSphereInit); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit); + this->collider2.dim.worldSphere.radius = this->collider2.dim.modelSphere.radius; + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + Effect_Add(globalCtx, &this->unk_340, EFFECT_TIRE_MARK, 0, 0, &D_80BF59F0); + + this->path = SubS_GetDayDependentPath(globalCtx, ENRG_GET_7F80(&this->actor), 255, &this->unk_33C); + if (this->path != NULL) { + this->unk_33C = 1; + } + + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_310 = 8; + this->actor.gravity = -1.0f; + SubS_UpdateFlags(&this->unk_310, 3, 7); + + if (!(gSaveContext.save.weekEventReg[12] & 2)) { + this->unk_318 = Rand_S16Offset(30, 30); + } + + this->unk_31C = 0; + this->unk_31E = 0; + this->actionFunc = func_80BF4EBC; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnRg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroySphere(globalCtx, &this->collider2); + Effect_Destroy(globalCtx, this->unk_340); +} + +void EnRg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRg* this = THIS; + + func_80BF3F14(this, globalCtx); + + this->actionFunc(this, globalCtx); + + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (!(this->unk_310 & 0x10)) { + func_80BF40F4(this); + func_80BF3FF8(this); + func_80BF4024(this, globalCtx); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 0.0f, 0x1D); + + if (this->actor.floorHeight <= BGCHECK_Y_MIN) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + } + + func_80BF3ED4(this, globalCtx); + + if (!Play_InCsMode(globalCtx)) { + func_80BF3C64(this); + } +} + +void func_80BF547C(EnRg* this, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset, + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Translate(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_RotateXS(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++, object_oF1d_map_DL_0091A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 func_80BF5588(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnRg* this = THIS; + s32 phi_v0; + + switch (limbIndex) { + case 10: + phi_v0 = 0; + break; + + case 11: + phi_v0 = 1; + break; + + case 14: + phi_v0 = 2; + break; + + default: + phi_v0 = 9; + break; + } + + if (((this->unk_310 & 8) != 0) && (phi_v0 < 9)) { + rot->y += (s16)(Math_SinS(this->unk_32E[phi_v0]) * 200.0f); + rot->z += (s16)(Math_CosS(this->unk_328[phi_v0]) * 200.0f); + } + + return false; +} + +void EnRg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRg* this = THIS; + + if (!(this->unk_310 & 0x10)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BF59F8[this->unk_31E])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, func_80BF5588, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + func_80BF547C(this, globalCtx); + } + func_80BF3DA0(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Rg/z_en_rg.h b/src/overlays/actors/ovl_En_Rg/z_en_rg.h index 2a34ecf8e..9f7e60ba4 100644 --- a/src/overlays/actors/ovl_En_Rg/z_en_rg.h +++ b/src/overlays/actors/ovl_En_Rg/z_en_rg.h @@ -7,11 +7,49 @@ struct EnRg; typedef void (*EnRgActionFunc)(struct EnRg*, GlobalContext*); +#define ENRG_GET_7F80(thisx) ((((thisx)->params & 0x7F80) >> 7) & 0xFF) + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; + /* 0x03 */ UNK_TYPE1 unk_03[0xD]; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ Vec3f unk_28; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; +} EnRgStruct; // size = 0x3C + typedef struct EnRg { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnRgActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x940]; + /* 0x018C */ Actor* unk_18C; + /* 0x0190 */ ColliderCylinder collider1; + /* 0x01DC */ ColliderSphere collider2; + /* 0x0234 */ Path* path; + /* 0x0238 */ Vec3s jointTable[18]; + /* 0x02A4 */ Vec3s morphTable[18]; + /* 0x0310 */ u16 unk_310; + /* 0x0314 */ f32 unk_314; + /* 0x0318 */ s16 unk_318; + /* 0x031A */ UNK_TYPE1 unk31A[2]; + /* 0x031C */ s16 unk_31C; + /* 0x031E */ s16 unk_31E; + /* 0x0320 */ s16 unk_320; + /* 0x0322 */ s16 unk_322; + /* 0x0324 */ s16 unk_324; + /* 0x0326 */ s16 unk_326; + /* 0x0328 */ s16 unk_328[3]; + /* 0x032E */ s16 unk_32E[3]; + /* 0x0334 */ s32 unk_334; + /* 0x0338 */ UNK_TYPE1 unk338[4]; + /* 0x033C */ s32 unk_33C; + /* 0x0340 */ s32 unk_340; + /* 0x0344 */ s32 unk_344; + /* 0x0348 */ s32 numCheckpointsAheadOfPlayer; + /* 0x034C */ EnRgStruct unk_34C[32]; } EnRg; // size = 0xACC extern const ActorInit En_Rg_InitVars; 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 ef39aafb1..2084130ce 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,6 +1,12 @@ +/* + * File: z_en_river_sound.c + * Overlay: ovl_En_River_Sound + * Description: Various environment Sfx along a path (e.g., ocean waves, gulls, waterfall, lava, etc) + */ + #include "z_en_river_sound.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnRiverSound*)thisx) @@ -8,7 +14,6 @@ void EnRiverSound_Init(Actor* thisx, GlobalContext* globalCtx); void EnRiverSound_Update(Actor* thisx, GlobalContext* globalCtx); void EnRiverSound_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_River_Sound_InitVars = { ACTOR_EN_RIVER_SOUND, ACTORCAT_ITEMACTION, @@ -21,10 +26,68 @@ const ActorInit En_River_Sound_InitVars = { (ActorFunc)EnRiverSound_Draw, }; -#endif +void EnRiverSound_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRiverSound* this = THIS; + Path* path; + s32 pathIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_River_Sound/EnRiverSound_Init.s") + this->playSound = false; + pathIndex = RS_GET_PATH_INDEX(&this->actor); + this->actor.params = RS_GET_TYPE(&this->actor); + if (pathIndex == 0xFF) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_River_Sound/EnRiverSound_Update.s") + path = &globalCtx->setupPathList[pathIndex]; + this->pathPoints = Lib_SegmentedToVirtual(path->points); + this->numPoints = path->count; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_River_Sound/EnRiverSound_Draw.s") +void EnRiverSound_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRiverSound* this = THIS; + Vec3f* worldPos = &this->actor.world.pos; + Vec3f eye; + s32 bgId; + + Math_Vec3f_Copy(&eye, &globalCtx->view.eye); + + if (this->actor.params < RS_RIVER_DEFAULT_LOW_FREQ) { + // All sfx from river_sound that accesses gAudioEnvironmentalSfx is associated with a closed-loop + // path that is used to play a regional sfx + Actor_GetClosestPosOnPath(this->pathPoints, this->numPoints, &eye, worldPos, true); + } else { + Actor_GetClosestPosOnPath(this->pathPoints, this->numPoints, &eye, worldPos, false); + if (BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, &this->actor, worldPos) != + BGCHECK_Y_MIN) { + this->soundFreqIndex = SurfaceType_GetConveyorSpeed(&globalCtx->colCtx, this->actor.floorPoly, bgId); + } else { + this->soundFreqIndex = 0; + } + + if (this->soundFreqIndex == 0) { + this->soundFreqIndex = this->actor.params - RS_RIVER_DEFAULT_LOW_FREQ; + } else { + this->soundFreqIndex--; + } + + this->soundFreqIndex = CLAMP_MAX(this->soundFreqIndex, 2); + } +} + +void EnRiverSound_Draw(Actor* thisx, GlobalContext* globalCtx) { + static f32 freqScale[] = { + 0.7f, // 1 / sqrt(2) + 1.0f, // 1 + 1.4f, // sqrt(2) + }; + EnRiverSound* this = THIS; + s16 params = this->actor.params; + + if (params < RS_RIVER_DEFAULT_LOW_FREQ) { + Actor_PlaySfxAtPos(&this->actor, gAudioEnvironmentalSfx[params]); + } else { + Audio_PlaySfxForRiver(&this->actor.projectedPos, freqScale[this->soundFreqIndex]); + } +} diff --git a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h index dc02f58fa..b8dbcc513 100644 --- a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h +++ b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.h @@ -5,9 +5,44 @@ struct EnRiverSound; +#define RS_GET_TYPE(thisx) ((thisx)->params & 0xFF); +#define RS_GET_PATH_INDEX(thisx) (((thisx)->params >> 8) & 0xFF); + +// Any param not as one of these values will result in UB +typedef enum { + /* 0x00 */ RS_RIVER_STREAM, + /* 0x01 */ RS_WAVE, + /* 0x02 */ RS_WATER_WALL_BIG, + /* 0x03 */ RS_WATER_WALL, + /* 0x04 */ RS_MAGMA_LEVEL, + /* 0x05 */ RS_MAGMA_LEVEL_M, + /* 0x06 */ RS_MAGMA_LEVEL_L, + /* 0x07 */ RS_TORCH, + /* 0x08 */ RS_FOUNTAIN, + /* 0x09 */ RS_DRAIN, + /* 0x0A */ RS_CROWD, + /* 0x0B */ RS_WATER_CONVECTION, + /* 0x0C */ RS_GORON_CHEER, + /* 0x0D */ RS_WATER_WALL_BIG_SILENT, + /* 0x0E */ RS_WATER_BUBBLE, + /* 0x0F */ RS_COW_CRY_LV, + /* 0x10 */ RS_MAKE_TURRET, + /* 0x11 */ RS_BOILED_WATER_S, + /* 0x12 */ RS_BOILED_WATER_L, + /* 0x13 */ RS_WAVE_0, + /* 0x14 */ RS_WAVE_1, + /* 0x15 */ RS_WAVE_2, + /* 0xFD */ RS_RIVER_DEFAULT_LOW_FREQ = 0xFD, + /* 0xFE */ RS_RIVER_DEFAULT_MEDIUM_FREQ, + /* 0xFF */ RS_RIVER_DEFAULT_HIGH_FREQ +} RiverSoundType; + typedef struct EnRiverSound { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x8]; + /* 0x144 */ u8 playSound; // Unused remnant of OoT + /* 0x145 */ u8 soundFreqIndex; + /* 0x146 */ u8 numPoints; + /* 0x148 */ Vec3s* pathPoints; } EnRiverSound; // size = 0x14C extern const ActorInit En_River_Sound_InitVars; 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 f1094a154..2ad27aab5 100644 --- a/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -1,6 +1,13 @@ -#include "z_en_rr.h" +/* + * File: z_en_rr.c + * Overlay: ovl_En_Rr + * Description: Like Like + */ -#define FLAGS 0x00000405 +#include "z_en_rr.h" +#include "objects/object_rr/object_rr.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnRr*)thisx) @@ -17,7 +24,9 @@ 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); + const ActorInit En_Rr_InitVars = { ACTOR_EN_RR, ACTORCAT_ENEMY, @@ -30,22 +39,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), @@ -80,11 +114,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), @@ -92,72 +124,818 @@ 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_SetFocus(&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->drawDmgEffScale = 0.85f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffScale = 0.85f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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->drawDmgEffScale = 0.85f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA238.s") +void func_808FA11C(EnRr* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->collider1.base.colType = COLTYPE_HIT3; + this->collider1.info.elemType = ELEMTYPE_UNK0; + this->unk_1EE = 80; + this->drawDmgEffScale = 0.85f; + this->drawDmgEffFrozenSteamScale = 1.2750001f; + this->drawDmgEffAlpha = 1.0f; + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider1.base.colType = COLTYPE_HIT0; + this->collider1.info.elemType = ELEMTYPE_UNK1; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 20, 2, this->actor.scale.y * 23.333334f, + this->actor.scale.y * 20.000002f); + this->actor.flags |= ACTOR_FLAG_400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA344.s") +void func_808FA238(EnRr* this, f32 arg1) { + this->actor.speedXZ = arg1; + Actor_PlaySfxAtPos(&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") + Actor_PlaySfxAtPos(&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 &= ~ACTOR_FLAG_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; + Actor_PlaySfxAtPos(&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 |= ACTOR_FLAG_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.save.playerForm == PLAYER_FORM_HUMAN)) && + (GET_CUR_EQUIP_VALUE(EQUIP_SHIELD) == 1)) { + sp34 = true; + this->unk_1E2 = Inventory_DeleteEquipment(globalCtx, 1); + } else { + sp34 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB42C.s") + if (sp34 && (Message_GetState(&globalCtx->msgCtx) == 0)) { + Message_StartTextbox(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); + Actor_PlaySfxAtPos(&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; + } + Actor_SetColorFilter(&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; + Actor_PlaySfxAtPos(&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; + Actor_SetColorFilter(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LIKE_DEAD); + this->actor.flags &= ~ACTOR_FLAG_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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) && + (sp2C->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + return false; + } + + if (this->actor.colChkInfo.damageEffect == 14) { + return false; + } + + Actor_SetDropFlag(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&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)) { + Actor_PlaySfxAtPos(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL) { + 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); + SoundSource_PlaySfxAtFixedWorldPos(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_SetFocus(&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_MoveWithGravity(&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->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.425f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.85f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 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, sizeof(Mtx) * 4); + + 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_Push(); + 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->limbPos[0]; + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + Matrix_MultVecZ(1842.1053f, vecPtr++); + Matrix_MultVecZ(-1842.1053f, vecPtr++); + Matrix_MultVecX(1842.1053f, vecPtr++); + Matrix_MultVecX(-1842.1053f, vecPtr++); + Matrix_Pop(); + + 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_Translate(0.0f, ptr->unk_00 + 1000.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZYX(ptr->unk_1A.x, ptr->unk_1A.y, ptr->unk_1A.z, MTXMODE_APPLY); + Matrix_Push(); + Matrix_Scale(temp_f20, 1.0f, temp_f20, MTXMODE_APPLY); + Matrix_ToMtx(matrix); + + if ((i & 1) != 0) { + Matrix_RotateYS(0x2000, MTXMODE_APPLY); + } + + Matrix_MultVecZ(1842.1053f, vecPtr++); + Matrix_MultVecZ(-1842.1053f, vecPtr++); + Matrix_MultVecX(1842.1053f, vecPtr++); + Matrix_MultVecX(-1842.1053f, vecPtr++); + Matrix_Pop(); + matrix++; + if (i == 3) { + Matrix_MultZero(&spA4); + } + } + + Matrix_MultZero(&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++, object_rr_DL_000470); + + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->actor.scale.y * 66.66667f * this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, + this->drawDmgEffAlpha, this->drawDmgEffType); + + 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..e2c935b47 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 drawDmgEffType; + /* 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 drawDmgEffAlpha; + /* 0x220 */ f32 drawDmgEffScale; + /* 0x224 */ f32 drawDmgEffFrozenSteamScale; + /* 0x228 */ Vec3f unk_228; + /* 0x234 */ Vec3f limbPos[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 a5e91243b..3a29b5081 100644 --- a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c +++ b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c @@ -1,6 +1,13 @@ -#include "z_en_rsn.h" +/* + * File: z_en_rsn.c + * Overlay: ovl_En_Rsn + * Description: Bomb Shop Man in the credits + */ -#define FLAGS 0x02000019 +#include "z_en_rsn.h" +#include "objects/object_rs/object_rs.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnRsn*)thisx) @@ -23,15 +30,10 @@ const ActorInit En_Rsn_InitVars = { (ActorFunc)EnRsn_Draw, }; -extern FlexSkeletonHeader D_06009220; -extern AnimationHeader D_06009120; -extern AnimationHeader D_0600788C; -extern Gfx D_06005458[]; - -static ActorAnimationEntry animations[] = { { &D_0600788C, 1.0f, 0.0f, 0.0f, 0x00, 0.0f } }; +static AnimationInfo sAnimations[] = { { &object_rs_Anim_00788C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f } }; void func_80C25D40(EnRsn* this) { - func_800BDC5C(&this->skelAnime, animations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->actionFunc = func_80C25D84; } @@ -41,9 +43,9 @@ void func_80C25D84(EnRsn* this, GlobalContext* globalCtx) { void EnRsn_Init(Actor* thisx, GlobalContext* globalCtx) { EnRsn* this = THIS; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06009220, &D_06009120, NULL, NULL, 0); - this->actor.flags &= ~1; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_rs_Skel_009220, &object_rs_Anim_009120, NULL, NULL, 0); + this->actor.flags &= ~ACTOR_FLAG_1; func_80C25D40(this); } @@ -57,28 +59,28 @@ void EnRsn_Update(Actor* thisx, GlobalContext* globalCtx) { EnRsn* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); SkelAnime_Update(&this->skelAnime); func_800E9250(globalCtx, &this->actor, &this->unk1D8, &this->unk1DE, this->actor.focus.pos); } -s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* arg) { - EnRsn* this = (EnRsn*)arg; +s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnRsn* this = THIS; if (limbIndex == 14) { - Matrix_InsertXRotation_s(this->unk1D8.y, 1); + Matrix_RotateXS(this->unk1D8.y, MTXMODE_APPLY); } - return 0; + return false; } static Vec3f D_80C26028 = { 0.0f, 0.0f, 0.0f }; -void EnRsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* arg) { - EnRsn* this = (EnRsn*)arg; +void EnRsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnRsn* this = THIS; Vec3f sp18 = D_80C26028; if (limbIndex == 14) { - Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + Matrix_MultVec3f(&sp18, &this->actor.focus.pos); } } @@ -87,7 +89,7 @@ void EnRsn_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C5B0(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_06005458)); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(object_rs_Tex_005458)); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, EnRsn_OverrideLimbDraw, EnRsn_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); 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 90f4b3eb1..3e9538f61 100644 --- a/src/overlays/actors/ovl_En_Ru/z_en_ru.c +++ b/src/overlays/actors/ovl_En_Ru/z_en_ru.c @@ -1,6 +1,12 @@ +/* + * File: z_en_ru.c + * Overlay: ovl_En_Ru + * Description: OoT's Adult Ruto (unused) + */ + #include "z_en_ru.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnRu*)thisx) 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 2b19b33a7..2b4026858 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c @@ -1,15 +1,45 @@ -#include "z_en_ruppecrow.h" +/* + * File: z_en_ruppecrow.c + * Overlay: ovl_En_Ruppecrow + * Description: Guay Circling Clock Town + */ -#define FLAGS 0x00004030 +#include "z_en_ruppecrow.h" +#include "objects/object_crow/object_crow.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_4000) #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, @@ -22,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), @@ -75,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; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= ACTOR_FLAG_10; + } 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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= ACTOR_FLAG_10; + } + } 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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= ACTOR_FLAG_10; + } 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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= ACTOR_FLAG_10; + } + + 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.ocarinaMode == 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, &gGuayFlyAnim, 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; + + Actor_PlaySfxAtPos(&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; + } + + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0x0, 0x28); + if (this->actor.flags & ACTOR_FLAG_8000) { + this->actor.speedXZ = 0.0f; + } + + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= ACTOR_FLAG_10; + this->actionFunc = EnRuppecrow_FallToDespawn; +} + +void EnRuppecrow_UpdateDamage(EnRuppecrow* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.elements->info); + + if (this->actor.colChkInfo.damageEffect != 0x1) { + this->actor.colChkInfo.health = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + 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_IsFacingPlayer(&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_MoveWithoutGravity(&this->actor); + this->yOffset += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f; + + if ((globalCtx->state.frames % 43) == 0) { + Actor_PlaySfxAtPos(&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_MoveWithoutGravity(&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_MoveWithGravity(&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_MoveWithoutGravity(&this->actor); + this->yOffset += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f; + + if ((globalCtx->state.frames % 43) == 0) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&this->actor); + + if ((globalCtx->state.frames % 43) == 0) { + Actor_PlaySfxAtPos(&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 & ACTOR_FLAG_8000)) { + 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); + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 0xB, NA_SE_EN_EXTINCT); + Actor_MarkForDeath(&this->actor); + return; + } + } + + Actor_MoveWithGravity(&this->actor); +} + +void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnRuppecrow* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->joinTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 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 |= ACTOR_FLAG_2000000; + + this->path = SubS_GetPathByIndex(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..de9fceac9 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h @@ -2,16 +2,39 @@ #define Z_EN_RUPPECROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" + +#define ENRUPPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) + +#define ENRUPPECROW_RUPEE_COUNT 20 +#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[OBJECT_CROW_LIMB_MAX]; + /* 0x216 */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; + /* 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 e812c284b..57f679803 100644 --- a/src/overlays/actors/ovl_En_Rz/z_en_rz.c +++ b/src/overlays/actors/ovl_En_Rz/z_en_rz.c @@ -1,6 +1,12 @@ +/* + * File: z_en_rz.c + * Overlay: ovl_En_Rz + * Description: Rosa Sisters, Judo (red) and Marilla (blue) + */ + #include "z_en_rz.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnRz*)thisx) diff --git a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c index bc1b6c91d..99e92b017 100644 --- a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c +++ b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.c @@ -1,6 +1,12 @@ +/* + * File: z_en_s_goro.c + * Overlay: ovl_En_S_Goro + * Description: Goron in Goron Shrine / Bomb Shop Goron + */ + #include "z_en_s_goro.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnSGoro*)thisx) diff --git a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.h b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.h index 489499b33..99c35127a 100644 --- a/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.h +++ b/src/overlays/actors/ovl_En_S_Goro/z_en_s_goro.h @@ -3,6 +3,8 @@ #include "global.h" +#define EN_S_GORO_GET_PARAM_F(thisx) ((thisx)->params & 0xF) + struct EnSGoro; typedef void (*EnSGoroActionFunc)(struct EnSGoro*, GlobalContext*); diff --git a/src/overlays/actors/ovl_En_Sb/z_en_sb.c b/src/overlays/actors/ovl_En_Sb/z_en_sb.c index a860e49fb..7ffeb543b 100644 --- a/src/overlays/actors/ovl_En_Sb/z_en_sb.c +++ b/src/overlays/actors/ovl_En_Sb/z_en_sb.c @@ -5,8 +5,9 @@ */ #include "z_en_sb.h" +#include "objects/object_sb/object_sb.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnSb*)thisx) @@ -103,25 +104,19 @@ static Vec3f sFlamePosOffsets[] = { { 0.0f, 0.0f, -5.0f }, }; -extern FlexSkeletonHeader D_06002BF0; -extern AnimationHeader D_06000194; -extern AnimationHeader D_0600004C; -extern AnimationHeader D_06000124; -extern AnimationHeader D_06002C8C; -extern AnimationHeader D_060000B4; - void EnSb_Init(Actor* thisx, GlobalContext* globalCtx) { EnSb* this = THIS; Actor_ProcessInitChain(&this->actor, sInitChain); this->actor.colChkInfo.damageTable = &sDamageTable; - this->actor.colChkInfo.mass = 0xA; + this->actor.colChkInfo.mass = 10; this->actor.colChkInfo.health = 2; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06002BF0, &D_06000194, this->jointTable, this->morphTable, 9); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_sb_Skel_002BF0, &object_sb_Anim_000194, this->jointTable, + this->morphTable, 9); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->isDead = false; - this->actor.colChkInfo.mass = 0x5A; + this->actor.colChkInfo.mass = 90; this->actor.shape.rot.y = 0; this->actor.speedXZ = 0.0f; this->actor.gravity = -0.35f; @@ -141,7 +136,7 @@ void EnSb_Destroy(Actor* thisx, GlobalContext* globalCtx) { void EnSb_SpawnBubbles(GlobalContext* globalCtx, EnSb* this) { s32 bubbleCount; - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { for (bubbleCount = 0; bubbleCount < 10; bubbleCount++) { EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 10.0f, 10.0f, 30.0f, 0.25f); } @@ -149,49 +144,53 @@ void EnSb_SpawnBubbles(GlobalContext* globalCtx, EnSb* this) { } void EnSb_SetupWaitClosed(EnSb* this) { - Animation_Change(&this->skelAnime, &D_0600004C, 1.0f, 0, Animation_GetLastFrame(&D_0600004C), 2, 0.0f); + Animation_Change(&this->skelAnime, &object_sb_Anim_00004C, 1.0f, 0, Animation_GetLastFrame(&object_sb_Anim_00004C), + 2, 0.0f); this->state = SHELLBLADE_WAIT_CLOSED; this->actionFunc = EnSb_Idle; } void EnSb_SetupOpen(EnSb* this) { - Animation_Change(&this->skelAnime, &D_06000194, 1.0f, 0, Animation_GetLastFrame(&D_06000194), 2, 0.0f); + Animation_Change(&this->skelAnime, &object_sb_Anim_000194, 1.0f, 0, Animation_GetLastFrame(&object_sb_Anim_000194), + 2, 0.0f); this->state = SHELLBLADE_OPEN; this->actionFunc = EnSb_Open; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); } void EnSb_SetupWaitOpen(EnSb* this) { - Animation_Change(&this->skelAnime, &D_06002C8C, 1.0f, 0, Animation_GetLastFrame(&D_06002C8C), 0, 0.0f); + Animation_Change(&this->skelAnime, &object_sb_Anim_002C8C, 1.0f, 0, Animation_GetLastFrame(&object_sb_Anim_002C8C), + 0, 0.0f); this->state = SHELLBLADE_WAIT_OPEN; this->actionFunc = EnSb_WaitOpen; } void EnSb_SetupLunge(EnSb* this) { - f32 frameCount = Animation_GetLastFrame(&D_06000124); - f32 playbackSpeed = this->actor.yDistToWater > 0.0f ? 1.0f : 0.0f; + f32 frameCount = Animation_GetLastFrame(&object_sb_Anim_000124); + f32 playbackSpeed = this->actor.depthInWater > 0.0f ? 1.0f : 0.0f; - Animation_Change(&this->skelAnime, &D_06000124, playbackSpeed, 0.0f, frameCount, 2, 0); + Animation_Change(&this->skelAnime, &object_sb_Anim_000124, playbackSpeed, 0.0f, frameCount, 2, 0); this->state = SHELLBLADE_LUNGE; this->actionFunc = EnSb_Lunge; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); } void EnSb_SetupBounce(EnSb* this) { - Animation_Change(&this->skelAnime, &D_060000B4, 1.0f, 0, Animation_GetLastFrame(&D_060000B4), 2, 0.0f); + Animation_Change(&this->skelAnime, &object_sb_Anim_0000B4, 1.0f, 0, Animation_GetLastFrame(&object_sb_Anim_0000B4), + 2, 0.0f); this->state = SHELLBLADE_BOUNCE; this->actionFunc = EnSb_Bounce; } void EnSb_SetupIdle(EnSb* this, s32 changeSpeed) { - f32 frameCount = Animation_GetLastFrame(&D_0600004C); + f32 frameCount = Animation_GetLastFrame(&object_sb_Anim_00004C); if (this->state != SHELLBLADE_WAIT_CLOSED) { - Animation_Change(&this->skelAnime, &D_0600004C, 1.0f, 0, frameCount, 2, 0.0f); + Animation_Change(&this->skelAnime, &object_sb_Anim_00004C, 1.0f, 0, frameCount, 2, 0.0f); } this->state = SHELLBLADE_WAIT_CLOSED; if (changeSpeed) { - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { this->actor.speedXZ = -5.0f; if (this->actor.velocity.y < 0.0f) { this->actor.velocity.y = 2.1f; @@ -217,7 +216,7 @@ void EnSb_Idle(EnSb* this, GlobalContext* globalCtx) { void EnSb_Open(EnSb* this, GlobalContext* globalCtx) { f32 currentFrame = this->skelAnime.curFrame; - if (Animation_GetLastFrame(&D_06000194) <= currentFrame) { + if (Animation_GetLastFrame(&object_sb_Anim_000194) <= currentFrame) { this->vulnerableTimer = 20; EnSb_SetupWaitOpen(this); } else { @@ -252,7 +251,7 @@ void EnSb_TurnAround(EnSb* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, invertedYaw, 1, 0x1F40, 0xA); if (this->actor.shape.rot.y == invertedYaw) { this->actor.world.rot.y = this->yawAngle; - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { this->actor.velocity.y = 3.0f; this->actor.speedXZ = 5.0f; this->actor.gravity = -0.35f; @@ -270,8 +269,8 @@ void EnSb_TurnAround(EnSb* this, GlobalContext* globalCtx) { void EnSb_Lunge(EnSb* this, GlobalContext* globalCtx) { Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); if (this->actor.velocity.y <= -0.1f || this->actor.bgCheckFlags & 2) { - if (!(this->actor.yDistToWater > 0.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + if (!(this->actor.depthInWater > 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); } this->actor.bgCheckFlags &= ~2; EnSb_SetupBounce(this); @@ -281,14 +280,14 @@ void EnSb_Lunge(EnSb* this, GlobalContext* globalCtx) { void EnSb_Bounce(EnSb* this, GlobalContext* globalCtx) { s32 pad; f32 currentFrame = currentFrame = this->skelAnime.curFrame; - f32 frameCount = frameCount = Animation_GetLastFrame(&D_060000B4); + f32 frameCount = frameCount = Animation_GetLastFrame(&object_sb_Anim_0000B4); Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); if (currentFrame == frameCount) { if (this->bounceCounter != 0) { this->bounceCounter--; this->attackTimer = 1; - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { this->actor.velocity.y = 3.0f; this->actor.speedXZ = 5.0f; this->actor.gravity = -0.35f; @@ -332,7 +331,7 @@ void EnSb_UpdateDamage(EnSb* this, GlobalContext* globalCtx) { hitPlayer = 0; if (this->vulnerableTimer != 0) { Actor_ApplyDamage(&this->actor); - func_800BCB70(&this->actor, 0x4000, 0xFF, 0x2000, 80); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0x2000, 80); hitPlayer = 1; } } @@ -343,7 +342,7 @@ void EnSb_UpdateDamage(EnSb* this, GlobalContext* globalCtx) { } this->isDead = true; Enemy_StartFinishingBlow(globalCtx, &this->actor); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EN_BEE_FLY); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EN_BEE_FLY); return; } hitPoint.x = this->collider.info.bumper.hitPos.x; @@ -363,7 +362,7 @@ void EnSb_Update(Actor* thisx, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (this->isDead) { - if (this->actor.yDistToWater > 0.0f) { + if (this->actor.depthInWater > 0.0f) { this->actor.params = 4; } else { this->actor.params = 1; @@ -371,8 +370,8 @@ void EnSb_Update(Actor* thisx, GlobalContext* globalCtx) { Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x80); Actor_MarkForDeath(&this->actor); } else { - Actor_SetHeight(&this->actor, 20.0f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_SetFocus(&this->actor, 20.0f); + Actor_MoveWithGravity(&this->actor); this->actionFunc(this, globalCtx); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 25.0f, 20.0f, 5); EnSb_UpdateDamage(this, globalCtx); @@ -393,8 +392,8 @@ void EnSb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec if (this->isDrawn != false) { if (limbIndex < 7) { - phi_a2 = (this->actor.yDistToWater > 0) ? 4 : 1; - func_800BBCEC(thisx, globalCtx, phi_a2, dList); + phi_a2 = (this->actor.depthInWater > 0) ? 4 : 1; + Actor_SpawnBodyParts(thisx, globalCtx, phi_a2, dList); } if (limbIndex == 6) { this->isDrawn = false; diff --git a/src/overlays/actors/ovl_En_Sc_Ruppe/z_en_sc_ruppe.c b/src/overlays/actors/ovl_En_Sc_Ruppe/z_en_sc_ruppe.c index 752ade75e..357d41ba7 100644 --- a/src/overlays/actors/ovl_En_Sc_Ruppe/z_en_sc_ruppe.c +++ b/src/overlays/actors/ovl_En_Sc_Ruppe/z_en_sc_ruppe.c @@ -1,6 +1,12 @@ +/* + * File: z_en_sc_ruppe.c + * Overlay: ovl_En_Sc_Ruppe + * Description: Giant Rupee + */ + #include "z_en_sc_ruppe.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnScRuppe*)thisx) 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 f14dabc20..dd6453773 100644 --- a/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c +++ b/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c @@ -1,6 +1,13 @@ -#include "z_en_scopecoin.h" +/* + * File: z_en_scopecoin.c + * Overlay: ovl_En_Scopecoin + * Description: Termina Field rupees visible from the telescope + */ -#define FLAGS 0x00000030 +#include "z_en_scopecoin.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnScopecoin*)thisx) @@ -29,8 +36,8 @@ void func_80BFCFA0(EnScopecoin* this, GlobalContext* globalCtx) { } void func_80BFCFB8(EnScopecoin* this, GlobalContext* globalCtx) { - if (Actor_GetCollectibleFlag(globalCtx, (this->actor.params & 0x7F0) >> 4)) { - Item_DropCollectible(globalCtx, &this->actor.world.pos, 2); + if (Flags_GetCollectible(globalCtx, (this->actor.params & 0x7F0) >> 4)) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_RUPEE_RED); Actor_MarkForDeath(&this->actor); } } @@ -39,7 +46,7 @@ void EnScopecoin_Init(Actor* thisx, GlobalContext* globalCtx) { EnScopecoin* this = THIS; Actor_SetScale(&this->actor, 0.01f); - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 10.0f); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 10.0f); this->unk148 = (this->actor.params & 0xF); if (this->unk148 < 0 || this->unk148 >= 8) { this->unk148 = 0; @@ -47,7 +54,7 @@ void EnScopecoin_Init(Actor* thisx, GlobalContext* globalCtx) { if (globalCtx->actorCtx.unk5 & 2) { if (this->unk148 == 2 || this->unk148 == 6) { - if (Actor_GetCollectibleFlag(globalCtx, (this->actor.params & 0x7F0) >> 4)) { + if (Flags_GetCollectible(globalCtx, (this->actor.params & 0x7F0) >> 4)) { Actor_MarkForDeath(&this->actor); return; } @@ -57,7 +64,7 @@ void EnScopecoin_Init(Actor* thisx, GlobalContext* globalCtx) { return; } if (this->unk148 == 2 || this->unk148 == 6) { - if (Actor_GetCollectibleFlag(globalCtx, (this->actor.params & 0x7F0) >> 4)) { + if (Flags_GetCollectible(globalCtx, (this->actor.params & 0x7F0) >> 4)) { Actor_MarkForDeath(&this->actor); } else { this->actor.draw = NULL; @@ -77,8 +84,10 @@ void EnScopecoin_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } -static UNK_PTR D_80BFD280[] = { &D_04061FC0, &D_04061FE0, &D_04062000, &D_04062040, - &D_04062020, &D_04062060, &D_04062000 }; +static TexturePtr D_80BFD280[] = { + gameplay_keep_Tex_061FC0, gameplay_keep_Tex_061FE0, gameplay_keep_Tex_062000, gameplay_keep_Tex_062040, + gameplay_keep_Tex_062020, gameplay_keep_Tex_062060, gameplay_keep_Tex_062000, +}; void EnScopecoin_Draw(Actor* thisx, GlobalContext* globalCtx) { EnScopecoin* this = THIS; @@ -90,7 +99,7 @@ void EnScopecoin_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BFD280[this->unk148])); - gSPDisplayList(POLY_OPA_DISP++, D_040622C0); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0622C0); CLOSE_DISPS(gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c index 8351aa961..5743f4a48 100644 --- a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c +++ b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.c @@ -1,6 +1,12 @@ +/* + * File: z_en_scopecrow.c + * Overlay: ovl_En_Scopecrow + * Description: Astral Observatory - Guay in Telescope + */ + #include "z_en_scopecrow.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnScopecrow*)thisx) @@ -12,7 +18,6 @@ void EnScopecrow_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BCD590(EnScopecrow* this, GlobalContext* globalCtx); void func_80BCD640(EnScopecrow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Scopecrow_InitVars = { ACTOR_EN_SCOPECROW, ACTORCAT_NPC, @@ -25,47 +30,324 @@ const ActorInit En_Scopecrow_InitVars = { (ActorFunc)EnScopecrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80BCDB70[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 60, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80BCDB94 = { - { COLTYPE_HIT3, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80BCDB70, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -#endif +void func_80BCD000(EnScopecrow* this, GlobalContext* globalCtx) { + this->collider.elements->dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.elements->dim.worldSphere.center.y = + sJntSphInit.elements[0].dim.modelSphere.center.y + this->actor.world.pos.y; + this->collider.elements->dim.worldSphere.center.z = this->actor.world.pos.z; -extern ColliderJntSphElementInit D_80BCDB70[1]; -extern ColliderJntSphInit D_80BCDB94; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -extern UNK_TYPE D_060010C0; +s32 func_80BCD09C(s16 arg0) { + switch (arg0) { + case 0: + if (gSaveContext.save.weekEventReg[53] & 4) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD000.s") + case 1: + if (gSaveContext.save.weekEventReg[53] & 0x80) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD09C.s") + case 2: + if (gSaveContext.save.weekEventReg[54] & 1) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD1AC.s") + case 3: + if (gSaveContext.save.weekEventReg[54] & 2) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD2BC.s") + case 4: + if (gSaveContext.save.weekEventReg[54] & 4) { + return true; + } + return false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD334.s") + case 5: + if (gSaveContext.save.weekEventReg[54] & 8) { + return true; + } + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD4D0.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD590.s") +s32 func_80BCD1AC(s16 arg0) { + switch (arg0) { + case 0: + if (!(gSaveContext.save.weekEventReg[53] & 4)) { + gSaveContext.save.weekEventReg[53] |= 4; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/func_80BCD640.s") + case 1: + if (!(gSaveContext.save.weekEventReg[53] & 0x80)) { + gSaveContext.save.weekEventReg[53] |= 0x80; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Init.s") + case 2: + if (!(gSaveContext.save.weekEventReg[54] & 1)) { + gSaveContext.save.weekEventReg[54] |= 1; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Destroy.s") + case 3: + if (!(gSaveContext.save.weekEventReg[54] & 2)) { + gSaveContext.save.weekEventReg[54] |= 2; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Update.s") + case 4: + if (!(gSaveContext.save.weekEventReg[54] & 4)) { + gSaveContext.save.weekEventReg[54] |= 4; + return true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopecrow/EnScopecrow_Draw.s") + case 5: + if (!(gSaveContext.save.weekEventReg[54] & 8)) { + gSaveContext.save.weekEventReg[54] |= 8; + return true; + } + break; + } + + return false; +} + +void func_80BCD2BC(EnScopecrow* this, GlobalContext* globalCtx) { + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SC_RUPPE, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, this->actor.shape.rot.x, + this->actor.shape.rot.y, this->actor.shape.rot.z, this->actor.params, + this->actor.cutscene, this->actor.unk20, NULL); +} + +s32 func_80BCD334(EnScopecrow* this, Path* path, s32 pointIndex) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 index = pointIndex; + s32 ret = false; + f32 phi_fa0; + f32 phi_fa1; + Vec3f sp3C; + Vec3f sp30; + + Math_Vec3s_ToVec3f(&sp30, &points[index]); + + if (index == 0) { + phi_fa0 = points[1].x - points[0].x; + phi_fa1 = points[1].z - points[0].z; + } else if ((sp58 - 1) == index) { + phi_fa0 = points[sp58 - 1].x - points[sp58 - 2].x; + phi_fa1 = points[sp58 - 1].z - points[sp58 - 2].z; + } else { + phi_fa0 = points[index + 1].x - points[index - 1].x; + phi_fa1 = points[index + 1].z - points[index - 1].z; + } + + func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(phi_fa0, phi_fa1)), &sp3C.z, &sp3C.y, &sp3C.x); + + if (((this->actor.world.pos.x * sp3C.z) + (sp3C.y * this->actor.world.pos.z) + sp3C.x) > 0.0f) { + ret = true; + } + return ret; +} + +f32 func_80BCD4D0(Path* path, s32 count, Vec3f* arg2, Vec3s* arg3) { + Vec3s* temp; + Vec3f sp20; + Vec3s* points; + + if (path != NULL) { + temp = Lib_SegmentedToVirtual(path->points); + points = temp + count; + + sp20.x = points->x; + sp20.y = points->y; + sp20.z = points->z; + } + + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + return sp20.y - arg2->y; +} + +void func_80BCD590(EnScopecrow* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + func_80169474(globalCtx, &this->actor.world.pos, &sp1C); + + if ((sp1C.x >= 130.0f) && (sp1C.x < 190.0f) && (sp1C.y >= 90.0f) && (sp1C.y < 150.0f)) { + this->actor.draw = EnScopecrow_Draw; + this->actionFunc = func_80BCD640; + } +} + +void func_80BCD640(EnScopecrow* this, GlobalContext* globalCtx) { + Vec3s sp30; + + if (this->path != NULL) { + func_80BCD4D0(this->path, this->unk_1FC, &this->actor.world.pos, &sp30); + if (this->actor.bgCheckFlags & 8) { + sp30.y = this->actor.wallYaw; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.world.rot.x, -sp30.x, 4, 0x3E8, 1); + + if (func_80BCD334(this, this->path, this->unk_1FC)) { + if ((this->unk_1FC == this->unk_262) && func_80BCD1AC(this->unk_260)) { + func_80BCD2BC(this, globalCtx); + } + + if (this->unk_1FC >= (this->path->count - 1)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_1FC++; + } + } + } + + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 1.0f); + Actor_MoveWithoutGravity(&this->actor); + this->unk_264 += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->unk_264) * 500.0f; +} + +void EnScopecrow_Init(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + Vec3s* temp; + CollisionPoly* sp4C; + Vec3s* points; + Vec3f sp3C; + + this->unk_260 = ENSCOPECROW_GET_1F(&this->actor); + if ((this->unk_260 < 0) || (this->unk_260 >= 6)) { + this->unk_260 = 0; + } + + if (func_80BCD09C(this->unk_260)) { + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPECROW_GET_PATH(&this->actor), 0x3F); + this->unk_262 = ENSCOPECROW_GET_3E0(&this->actor); + + if (this->path != NULL) { + if ((this->unk_262 <= 0) || ((this->path->count - 1) < this->unk_262)) { + this->unk_262 = this->path->count - 1; + } + + temp = Lib_SegmentedToVirtual(this->path->points); + points = temp + this->unk_262; + + sp3C.x = points->x; + sp3C.y = points->y; + sp3C.z = points->z; + + this->actor.world.pos = sp3C; + this->actor.world.pos.y = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp4C, &sp3C); + if (this->actor.world.pos.y == BGCHECK_Y_MIN) { + Actor_MarkForDeath(&this->actor); + } + + func_80BCD2BC(this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_MarkForDeath(&this->actor); + return; + } + + if (globalCtx->actorCtx.unk5 & 2) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); + + Collider_InitJntSph(globalCtx, &this->collider); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; + + Actor_SetScale(&this->actor, 0.03f); + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPECROW_GET_PATH(&this->actor), 0x3F); + this->unk_262 = ENSCOPECROW_GET_3E0(&this->actor); + + if (this->path != NULL) { + if ((this->unk_262 <= 0) || ((this->path->count - 1) < this->unk_262)) { + this->unk_262 = this->path->count - 1; + } + this->actor.draw = NULL; + this->actor.gravity = 0.0f; + this->actionFunc = func_80BCD590; + return; + } + + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_MarkForDeath(&this->actor); +} + +void EnScopecrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void EnScopecrow_Update(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* this = THIS; + + this->actionFunc(this, globalCtx); + + SkelAnime_Update(&this->skelAnime); + func_80BCD000(this, globalCtx); +} + +void EnScopecrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnScopecrow* 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_Scopecrow/z_en_scopecrow.h b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h index 2b5b38eae..72469bd75 100644 --- a/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h +++ b/src/overlays/actors/ovl_En_Scopecrow/z_en_scopecrow.h @@ -2,16 +2,29 @@ #define Z_EN_SCOPECROW_H #include "global.h" +#include "objects/object_crow/object_crow.h" struct EnScopecrow; typedef void (*EnScopecrowActionFunc)(struct EnScopecrow*, GlobalContext*); +#define ENSCOPECROW_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENSCOPECROW_GET_3E0(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENSCOPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) + typedef struct EnScopecrow { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnScopecrowActionFunc actionFunc; - /* 0x018C */ char unk_18C[0xDC]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnScopecrowActionFunc actionFunc; + /* 0x18C */ Vec3s jointTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1C2 */ Vec3s morphTable[OBJECT_CROW_LIMB_MAX]; + /* 0x1F8 */ Path* path; + /* 0x1FC */ s32 unk_1FC; + /* 0x200 */ ColliderJntSph collider; + /* 0x220 */ ColliderJntSphElement colliderElements[1]; + /* 0x260 */ s16 unk_260; + /* 0x262 */ s16 unk_262; + /* 0x264 */ s16 unk_264; } EnScopecrow; // size = 0x268 extern const ActorInit En_Scopecrow_InitVars; 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 ee45a01db..3f0ae6154 100644 --- a/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c +++ b/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c @@ -1,6 +1,14 @@ -#include "z_en_scopenuts.h" +/* + * File: z_en_scopenuts.c + * Overlay: ovl_En_Scopenuts + * Description: Business Scrub that sells you a Heart Piece + */ -#define FLAGS 0x00000039 +#include "z_en_scopenuts.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_dnt/object_dnt.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnScopenuts*)thisx) @@ -9,7 +17,22 @@ void EnScopenuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnScopenuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnScopenuts_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BCB078(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB1C8(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB4DC(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB52C(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB6D0(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB90C(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCB980(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCBA00(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCBC60(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCBD28(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCBF0C(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCBFFC(EnScopenuts* this, GlobalContext* globalCtx); +void func_80BCC288(EnScopenuts* this, GlobalContext* globalCtx); +s32 func_80BCC2AC(EnScopenuts* this, Path* path, s32 arg2_); +f32 func_80BCC448(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3); + const ActorInit En_Scopenuts_InitVars = { ACTOR_EN_SCOPENUTS, ACTORCAT_NPC, @@ -22,81 +45,787 @@ const ActorInit En_Scopenuts_InitVars = { (ActorFunc)EnScopenuts_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80BCCB40 = { - { 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_80BCCCF0[] = { +static AnimationInfoS sAnimations[] = { + { &object_dnt_Anim_005488, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00B0B4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_004AA0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004E38, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_005CA8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0038CC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003CC0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004700, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003438, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001E2C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_000994, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_002268, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002F08, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00577C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 8, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 4, -1, ANIMMODE_ONCE, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002670, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, +}; + +Gfx* D_80BCCCDC[] = { gKakeraLeafMiddle, gKakeraLeafTip }; + +Vec3f D_80BCCCE4 = { 0.0f, -0.5f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 0, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), }; -#endif +s16 func_80BCABF0(Path* path) { + Vec3s* sp34 = Lib_SegmentedToVirtual(path->points); + Vec3f sp28; + Vec3f sp1C; -extern ColliderCylinderInit D_80BCCB40; -extern InitChainEntry D_80BCCCF0[]; + Math_Vec3s_ToVec3f(&sp28, &sp34[0]); + Math_Vec3s_ToVec3f(&sp1C, &sp34[1]); + return Math_Vec3f_Yaw(&sp28, &sp1C); +} -extern UNK_TYPE D_06001420; -extern UNK_TYPE D_06005488; +void func_80BCAC40(EnScopenuts* this, GlobalContext* globalCtx) { + s16 i; + Vec3f sp60; + Vec3f sp54; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCABF0.s") + sp60 = this->actor.world.pos; + sp60.y += 100.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCAC40.s") + for (i = 0; i < 36; i++) { + sp54.x = Rand_Centered() * 10.0f; + sp54.y = 2.0f * Rand_Centered(); + sp54.z = Rand_Centered() * 10.0f; + EffectSsHahen_Spawn(globalCtx, &sp60, &sp54, &D_80BCCCE4, 0, 0x96, 1, 0x10, D_80BCCCDC[i & 1]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCAD64.s") +void func_80BCAD64(EnScopenuts* this, s16 arg1) { + f32 sp24 = Math_CosS(this->actor.world.rot.x) * this->actor.speedXZ; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCAE78.s") + switch (arg1) { + case 1: + this->actor.velocity.y = this->actor.speedXZ; + this->actor.velocity.x = 0.0f; + this->actor.velocity.z = 0.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCAF0C.s") + case 2: + this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; + this->actor.velocity.y = 0.0f; + this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCAFA8.s") + case 3: + this->actor.velocity.x = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.velocity.z = 0.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB078.s") + default: + 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; + break; + } + Actor_UpdatePos(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB1C8.s") +void func_80BCAE78(EnScopenuts* this, GlobalContext* globalCtx) { + if (this->unk_328 & 4) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB230.s") + if (this->unk_328 & 2) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 20.0f, 5); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB4DC.s") +s16 func_80BCAF0C(EnScopenuts* this) { + switch (this->unk_33C) { + case 0x0: + if (gSaveContext.save.weekEventReg[53] & 2) { + this->unk_328 |= 1; + return 0x1638; + } + return 0x162F; + case 0x162F: + return 0x1630; + case 0x1630: + return 0x1631; + case 0x1631: + this->unk_358 = 150; + return 0x1632; + case 0x1633: + this->unk_358 = 100; + return 0x1634; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB52C.s") +void func_80BCAFA8(EnScopenuts* this, GlobalContext* globalCtx) { + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB6D0.s") + func_80169474(globalCtx, &this->actor.world.pos, &sp1C); + if ((sp1C.x >= 130.0f) && (sp1C.x < 190.0f) && (sp1C.y >= 90.0f)) { + if (sp1C.y < 150.0f) { + this->actor.draw = EnScopenuts_Draw; + this->unk_348 = 10; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 10); + this->actionFunc = func_80BCB078; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB90C.s") +void func_80BCB078(EnScopenuts* this, GlobalContext* globalCtx) { + Vec3s sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCB980.s") + if (this->path != NULL) { + func_80BCC448(this->path, this->unk_334, &this->actor.world.pos, &sp30); + if (this->actor.bgCheckFlags & 8) { + sp30.y = this->actor.wallYaw; + } + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 10, 300, 0); + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_33E = 0x1000; + this->unk_340 += 0x1C71; + this->actor.world.rot.x = -sp30.x; + if (func_80BCC2AC(this, this->path, this->unk_334)) { + if (this->unk_334 >= (this->path->count - 1)) { + this->actionFunc = func_80BCB1C8; + this->actor.speedXZ = 0.0f; + this->actor.gravity = -1.0f; + return; + } + this->unk_334++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCBA00.s") + if (this->unk_334 >= (this->path->count - 2)) { + Math_ApproachF(&this->actor.speedXZ, 1.5f, 0.2f, 1.0f); + } else { + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 1.0f); + } + Actor_MoveWithoutGravity(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCBC60.s") +void func_80BCB1C8(EnScopenuts* this, GlobalContext* globalCtx) { + this->unk_350 *= 0.92f; + Actor_SetScale(&this->actor, this->unk_350); + if (this->actor.bgCheckFlags & 1) { + gSaveContext.save.weekEventReg[52] |= 0x40; + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCBD28.s") +void func_80BCB230(EnScopenuts* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 sp24 = Animation_GetLastFrame(sAnimations[this->unk_348].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCBF0C.s") + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCBFFC.s") + if ((((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) ? true : false) && + ((this->actor.xzDistToPlayer < 200.0f) ? true : false)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actionFunc = func_80BCB4DC; + this->unk_348 = 3; + this->collider.dim.height = 64; + func_80BCAC40(this, globalCtx); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 3); + } else if (sp26 == sp24) { + if ((this->unk_348 == 4) || (this->unk_348 == 18)) { + this->unk_348 = 17; + this->collider.dim.height = 0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 17); + } else if (this->unk_348 == 2) { + this->unk_348 = 16; + this->collider.dim.height = 32; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 16); + } else if (this->unk_348 == 17) { + if (DECR(this->unk_34E) == 0) { + this->unk_34E = Rand_ZeroOne() * 10.0f; + this->unk_348 = 2; + this->collider.dim.height = 32; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 2); + } + } else if ((this->unk_348 == 16) && (DECR(this->unk_34E) == 0)) { + this->unk_34E = Rand_S16Offset(40, 40); + this->unk_348 = 18; + this->collider.dim.height = 32; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 18); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC288.s") +void func_80BCB4DC(EnScopenuts* this, GlobalContext* globalCtx) { + if (this->skelAnime.curFrame == this->skelAnime.endFrame) { + this->actionFunc = func_80BCB52C; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC2AC.s") +void func_80BCB52C(EnScopenuts* 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_33C = func_80BCAF0C(this); + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); + this->actionFunc = func_80BCB6D0; + } 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_348 = 4; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 4); + this->actionFunc = func_80BCB230; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC448.s") +void func_80BCB6D0(EnScopenuts* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/EnScopenuts_Init.s") + if (temp_v0 == 5) { + if (Message_ShouldAdvance(globalCtx)) { + if (this->unk_328 & 1) { + this->unk_328 &= ~1; + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_328 &= ~4; + this->unk_348 = 8; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 8); + this->actionFunc = func_80BCBA00; + } else { + this->unk_33C = func_80BCAF0C(this); + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); + } + } + } else if (temp_v0 == 4) { + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.save.playerData.rupees < this->unk_358) { + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1636; + this->unk_328 |= 1; + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); + } else { + func_8019F208(); + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + func_801159EC(this->unk_358 * -1); + this->actionFunc = func_80BCB90C; + } + break; + case 1: + func_8019F230(); + if (this->unk_358 == 150) { + this->unk_33C = 0x1633; + } else { + this->unk_33C = 0x1635; + this->unk_328 |= 1; + } + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); + break; + } + } + } else if (temp_v0 == 6) { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + this->actionFunc = func_80BCB980; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/EnScopenuts_Destroy.s") +void func_80BCB90C(EnScopenuts* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + gSaveContext.save.weekEventReg[53] |= 2; + this->actionFunc = func_80BCB6D0; + } else { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 300.0f, 300.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/EnScopenuts_Update.s") +void func_80BCB980(EnScopenuts* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_33C = 0x1637; + this->unk_328 |= 1; + Message_StartTextbox(globalCtx, this->unk_33C, &this->actor); + this->actionFunc = func_80BCB6D0; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC828.s") +void func_80BCBA00(EnScopenuts* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 sp24 = Animation_GetLastFrame(sAnimations[this->unk_348].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC9CC.s") + switch (sp26) { + case 10: + this->unk_35A = 1; + this->unk_35C = 0.1f; + this->unk_360 = 0.1f; + this->unk_364 = 0.1f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/func_80BCC9E4.s") + case 11: + case 12: + this->unk_35C += 0.15f; + this->unk_360 += 0.32f; + this->unk_364 += 0.15f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Scopenuts/EnScopenuts_Draw.s") + case 13: + this->unk_35C = 0.55f; + this->unk_360 = 1.05f; + this->unk_364 = 0.55f; + break; + + case 14: + this->unk_35C = 1.0f; + this->unk_360 = 2.0f; + this->unk_364 = 1.0f; + break; + + case 15: + case 16: + this->unk_360 -= 0.33f; + break; + + case 17: + this->unk_360 = 1.0f; + break; + + case 18: + case 19: + this->unk_360 += 0.27f; + break; + + case 20: + this->unk_35A = 2; + this->unk_360 = 1.8f; + break; + + case 21: + case 22: + case 23: + this->unk_360 -= 0.2f; + break; + + case 24: + this->unk_360 = 1.0f; + break; + } + + if (this->unk_36C == 0) { + if (ActorCutscene_GetCanPlayNext(this->unk_338)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_338, &this->actor); + this->unk_36C = 1; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_338); + return; + } + } + + if (sp26 == sp24) { + this->unk_35A = 3; + this->unk_348 = 19; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 19); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + this->unk_328 &= ~2; + this->unk_34E = 50; + this->unk_328 |= 8; + this->unk_32C = this->actor.world.pos.y; + this->actionFunc = func_80BCBC60; + } +} + +void func_80BCBC60(EnScopenuts* this, GlobalContext* globalCtx) { + f32 sp24; + Vec3f sp18; + + this->unk_340 += this->unk_34C; + sp24 = this->unk_32C - this->actor.world.pos.y; + + if (!(this->unk_370 & 3)) { + sp18.x = this->actor.world.pos.x; + sp18.y = this->unk_32C; + sp18.z = this->actor.world.pos.z; + func_800B14D4(globalCtx, 20.0f, &sp18); + } + + if (sp24 > 5.0f) { + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + this->unk_372 = func_80BCABF0(this->path); + this->actionFunc = func_80BCBD28; + } +} + +void func_80BCBD28(EnScopenuts* this, GlobalContext* globalCtx) { + Vec3f sp44; + s16 sp42 = this->skelAnime.curFrame; + s16 sp40 = Animation_GetLastFrame(sAnimations[this->unk_348].animation); + Vec3s sp38; + + func_80BCC448(this->path, this->unk_334, &this->actor.world.pos, &sp38); + if (sp42 == sp40) { + Math_SmoothStepToS(&this->unk_34C, 0x1C71, 3, 0x100, 0); + this->unk_340 += this->unk_34C; + this->actor.shape.yOffset = 1500.0f; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_372, 3, 2000, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (DECR(this->unk_34E) == 0) { + if (!(this->unk_370 & 3)) { + sp44 = this->actor.world.pos; + func_800B14D4(globalCtx, 20.0f, &sp44); + } + this->actor.velocity.y = 5.0f; + } else if (!(this->unk_370 & 3)) { + sp44.x = this->actor.world.pos.x; + sp44.y = this->unk_32C; + sp44.z = this->actor.world.pos.z; + func_800B14D4(globalCtx, 20.0f, &sp44); + } + + if ((this->actor.home.pos.y + 22.5f) < this->actor.world.pos.y) { + this->unk_368 = 0.3f; + this->unk_348 = 9; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 9); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + func_80BCAC40(this, globalCtx); + this->actionFunc = func_80BCBF0C; + } +} + +void func_80BCBF0C(EnScopenuts* this, GlobalContext* globalCtx) { + this->unk_340 += this->unk_34C; + if (this->unk_368 >= 1.0f) { + this->unk_368 = 1.0f; + this->actor.velocity.y = 5.0f; + } else { + this->actor.velocity.y = 5.0f; + this->unk_368 += 0.1f; + } + + if ((this->actor.home.pos.y + 50.0f) < this->actor.world.pos.y) { + Math_ApproachF(&this->actor.velocity.y, 0.0f, 0.2f, 1.0f); + this->unk_348 = 10; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 10); + this->unk_328 |= 2; + this->unk_36E = 0; + this->actionFunc = func_80BCBFFC; + } +} + +void func_80BCBFFC(EnScopenuts* this, GlobalContext* globalCtx) { + Vec3s sp38; + f32 sp34; + s16 sp32 = 0; + + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + + if (this->path != NULL) { + sp34 = func_80BCC448(this->path, this->unk_334, &this->actor.world.pos, &sp38); + if (this->actor.bgCheckFlags & 8) { + sp38.y = this->actor.wallYaw; + } + + if (this->unk_334 < 6) { + Math_SmoothStepToS(&this->actor.world.rot.y, sp38.y, 10, 300, 0); + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, sp38.y, 10, 1500, 0); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_33E = 0x1000; + this->unk_340 += this->unk_34C; + this->actor.world.rot.x = -sp38.x; + + if (func_80BCC2AC(this, this->path, this->unk_334)) { + sp32 = 1; + } + + if (sp34 < 10.0f) { + if (sp32 == 1) { + sp32 = 3; + } else { + sp32 = 2; + } + } + + if (sp32 == 3) { + if (this->unk_334 >= (this->path->count - 1)) { + ActorCutscene_Stop(this->unk_338); + gSaveContext.save.weekEventReg[52] &= (u8)~0x40; + this->actionFunc = func_80BCC288; + } else { + this->unk_334++; + } + } + } else if (this->actor.playerHeightRel > 500.0f) { + ActorCutscene_Stop(this->unk_338); + this->actionFunc = func_80BCC288; + } + + Math_ApproachF(&this->actor.speedXZ, 1.0f, 0.2f, 1.0f); + func_80BCAD64(this, sp32); + + if (this->unk_36C == 2) { + if (ActorCutscene_GetCanPlayNext(this->unk_338)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_338, &this->actor); + this->unk_36C = 3; + } else { + ActorCutscene_SetIntentToPlay(this->unk_338); + return; + } + } else if ((this->unk_36C == 1) && (this->unk_36E == 20)) { + ActorCutscene_Stop(this->unk_338); + this->unk_338 = ActorCutscene_GetAdditionalCutscene(this->unk_338); + ActorCutscene_SetIntentToPlay(this->unk_338); + this->unk_36C = 2; + } + this->unk_36E++; +} + +void func_80BCC288(EnScopenuts* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} + +s32 func_80BCC2AC(EnScopenuts* this, Path* path, s32 arg2_) { + Vec3s* sp5C = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 arg2 = arg2_; + s32 sp50 = false; + f32 phi_f12; + f32 phi_f14; + f32 sp44; + f32 sp40; + f32 sp3C; + Vec3f sp30; + + Math_Vec3s_ToVec3f(&sp30, &sp5C[arg2]); + + if (arg2 == 0) { + phi_f12 = sp5C[1].x - sp5C[0].x; + phi_f14 = sp5C[1].z - sp5C[0].z; + } else if ((sp58 - 1) == arg2) { + phi_f12 = sp5C[sp58 - 1].x - sp5C[sp58 - 2].x; + phi_f14 = sp5C[sp58 - 1].z - sp5C[sp58 - 2].z; + } else { + phi_f12 = sp5C[arg2 + 1].x - sp5C[arg2 - 1].x; + phi_f14 = sp5C[arg2 + 1].z - sp5C[arg2 - 1].z; + } + + 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; + } + return sp50; +} + +f32 func_80BCC448(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3) { + Vec3s* temp_v1; + Vec3f sp20; + + if (path != NULL) { + temp_v1 = Lib_SegmentedToVirtual(path->points); + temp_v1 = &temp_v1[arg1]; + sp20.x = temp_v1[0].x; + sp20.y = temp_v1[0].y; + sp20.z = temp_v1[0].z; + } + + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + + return sp20.y - arg2->y; +} + +void EnScopenuts_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnScopenuts* this = THIS; + + if (!(gSaveContext.save.weekEventReg[74] & 0x40) && + (gSaveContext.save.inventory.items[ITEM_OCARINA] == ITEM_NONE)) { + Actor_MarkForDeath(&this->actor); + return; + } + + 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, ActorShadow_DrawCircle, 35.0f); + this->unk_350 = 0.01f; + Actor_SetScale(&this->actor, 0.01f); + this->actor.colChkInfo.cylRadius = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_328 |= 2; + this->unk_328 |= 4; + this->actor.speedXZ = 0.0f; + + if (ENSCOPENUTS_GET_3E0(&this->actor) == ENSCOPENUTS_3E0_0) { + if (gSaveContext.save.weekEventReg[52] & 0x40) { + Actor_MarkForDeath(&this->actor); + } else if (globalCtx->actorCtx.unk5 & 2) { + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPENUTS_GET_FC00(&this->actor), 0x3F); + this->actor.draw = NULL; + this->actionFunc = func_80BCAFA8; + this->actor.gravity = 0.0f; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENSCOPENUTS_GET_3E0(&this->actor) == ENSCOPENUTS_3E0_1) { + if (gSaveContext.save.weekEventReg[52] & 0x40) { + this->path = SubS_GetPathByIndex(globalCtx, ENSCOPENUTS_GET_FC00(&this->actor), 0x3F); + if (this->path == NULL) { + Actor_MarkForDeath(&this->actor); + } else { + this->actor.gravity = -1.0f; + this->actor.draw = EnScopenuts_Draw; + this->unk_338 = this->actor.cutscene; + this->unk_33C = 0; + this->unk_358 = 150; + this->unk_348 = 4; + this->unk_35A = 0; + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 4); + this->actionFunc = func_80BCB230; + } + } else { + Actor_MarkForDeath(&this->actor); + } + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnScopenuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnScopenuts* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnScopenuts_Update(Actor* thisx, GlobalContext* globalCtx) { + EnScopenuts* this = THIS; + + Actor_SetFocus(&this->actor, 60.0f); + SkelAnime_Update(&this->skelAnime); + Actor_MoveWithGravity(&this->actor); + + this->actionFunc(this, globalCtx); + + if (this->unk_328 & 8) { + func_800B9010(&this->actor, NA_SE_EN_AKINDO_FLY - SFX_FLAG); + } + func_80BCAE78(this, globalCtx); +} + +s32 EnScopenuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnScopenuts* this = THIS; + + if (((this->unk_348 == 4) && (this->unk_35A == 0)) || ((this->unk_348 == 8) && (this->unk_35A == 0)) || + (this->unk_348 == 18) || (this->unk_348 == 2) || (this->unk_348 == 3) || (this->unk_348 == 17) || + (this->unk_348 == 16)) { + if ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27) || (limbIndex == 23) || (limbIndex == 24) || + (limbIndex == 15)) { + *dList = NULL; + } + } else if ((this->unk_348 == 8) || (this->unk_348 == 19)) { + switch (this->unk_35A) { + 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_348 == 9) || (this->unk_348 == 10)) && ((limbIndex == 15) || (limbIndex == 25))) { + *dList = NULL; + } + + if (limbIndex == 26) { + if ((this->unk_33C == 0x162F) || (this->unk_33C == 0x1630)) { + *dList = object_dnt_DL_001420; + } else { + *dList = object_dnt_DL_008290; + } + } + + return false; +} + +void EnScopenuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +} + +void EnScopenuts_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnScopenuts* this = THIS; + + if (((this->unk_35A == 1) || (this->unk_35A == 2)) && ((limbIndex == 23) || (limbIndex == 24))) { + Matrix_Scale(this->unk_35C, this->unk_360, this->unk_364, MTXMODE_APPLY); + } + + if ((this->unk_348 == 9) && ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27))) { + Matrix_Scale(this->unk_368, this->unk_368, this->unk_368, MTXMODE_APPLY); + } + + if (limbIndex == 24) { + Matrix_RotateYS(this->unk_340, MTXMODE_APPLY); + } +} + +void EnScopenuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnScopenuts* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnScopenuts_OverrideLimbDraw, EnScopenuts_PostLimbDraw, + EnScopenuts_TransformLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.h b/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.h index 2eed1584f..c4a00f84a 100644 --- a/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.h +++ b/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.h @@ -7,11 +7,44 @@ struct EnScopenuts; typedef void (*EnScopenutsActionFunc)(struct EnScopenuts*, GlobalContext*); +#define ENSCOPENUTS_GET_3E0(thisx) (((thisx)->params & 0x3E0) >> 5) +#define ENSCOPENUTS_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + +#define ENSCOPENUTS_3E0_0 0 +#define ENSCOPENUTS_3E0_1 1 + typedef struct EnScopenuts { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x194]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[28]; + /* 0x0230 */ Vec3s morphTable[28]; /* 0x02D8 */ EnScopenutsActionFunc actionFunc; - /* 0x02DC */ char unk_2DC[0x98]; + /* 0x02DC */ ColliderCylinder collider; + /* 0x0328 */ u16 unk_328; + /* 0x032C */ f32 unk_32C; + /* 0x0330 */ Path* path; + /* 0x0334 */ s32 unk_334; + /* 0x0338 */ s16 unk_338; + /* 0x033A */ UNK_TYPE1 unk33A[2]; + /* 0x033C */ u16 unk_33C; + /* 0x033E */ s16 unk_33E; + /* 0x0340 */ s16 unk_340; + /* 0x0342 */ UNK_TYPE1 unk342[0x6]; + /* 0x0348 */ s32 unk_348; + /* 0x034C */ s16 unk_34C; + /* 0x034E */ s16 unk_34E; + /* 0x0350 */ f32 unk_350; + /* 0x0354 */ UNK_TYPE1 unk354[4]; + /* 0x0358 */ s16 unk_358; + /* 0x035A */ s16 unk_35A; + /* 0x035C */ f32 unk_35C; + /* 0x0360 */ f32 unk_360; + /* 0x0364 */ f32 unk_364; + /* 0x0368 */ f32 unk_368; + /* 0x036C */ s16 unk_36C; + /* 0x036E */ s16 unk_36E; + /* 0x0370 */ s16 unk_370; + /* 0x0372 */ s16 unk_372; } EnScopenuts; // size = 0x374 extern const ActorInit En_Scopenuts_InitVars; 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 62a36b618..fc4f91308 100644 --- a/src/overlays/actors/ovl_En_Sda/z_en_sda.c +++ b/src/overlays/actors/ovl_En_Sda/z_en_sda.c @@ -1,6 +1,12 @@ +/* + * File: z_en_sda.c + * Overlay: ovl_En_Sda + * Description: Dynamic Shadow for Player + */ + #include "z_en_sda.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnSda*)thisx) @@ -9,7 +15,11 @@ void EnSda_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSda_Update(Actor* thisx, GlobalContext* globalCtx); void EnSda_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_8094702C(EnSda* this, u8* shadowTexture, Player* player, GlobalContext* globalCtx); +void func_80947668(u8* shadowTexture, Player* player, GlobalContext* globalCtx); + +Vec3f D_80947EA0[16]; + const ActorInit En_Sda_InitVars = { ACTOR_EN_SDA, ACTORCAT_BOSS, @@ -22,18 +32,326 @@ const ActorInit En_Sda_InitVars = { (ActorFunc)EnSda_Draw, }; -#endif +Vec3f D_80947A60 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/EnSda_Init.s") +s16 D_80947A6C[] = { 1, 2, 3, 3, 2, 1 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/EnSda_Destroy.s") +s16 D_80947A78[] = { 2, 3, 4, 4, 4, 3, 2, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/EnSda_Update.s") +s16 D_80947A88[] = { 2, 3, 4, 4, 4, 4, 3, 2 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/EnSda_Draw.s") +s16 D_80947A98[] = { 2, 4, 5, 5, 6, 6, 6, 6, 5, 5, 4, 2 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/func_809469C0.s") +s16 D_80947AB0[] = { 2, 4, 5, 6, 7, 8, 8, 8, 8, 7, 6, 5, 4, 2 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/func_8094702C.s") +s16 D_80947ACC[] = { 1, -1, 1, 1, 3, 4, 1, 6, 7, 2, 9, 0xA, 2, 0xC, 0xD, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sda/func_80947668.s") +u8 D_80947AEC[] = { + 2, 2, 2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 3, +}; + +s8 D_80947AFC[] = { + 2, 9, 10, 11, 12, 13, 14, 0, 15, -1, 3, 4, 5, 6, 7, 8, -1, 1, 0, 0, +}; + +Vec3f D_80947B10[] = { + { -1.0f, 2.0f, -0.2f }, { 0.0f, 2.0f, -0.5f }, { 1.0f, 2.0f, -0.2f }, { -2.0f, 1.0f, -0.5f }, + { -1.0f, 1.0f, -0.2f }, { 0.0f, 1.0f, -0.2f }, { 1.0f, 1.0f, -0.2f }, { 2.0f, 1.0f, -0.5f }, + { -2.0f, 0.0f, -0.5f }, { -1.0f, 0.0f, -0.2f }, { 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, -0.2f }, + { 2.0f, 0.0f, -0.5f }, { -2.0f, -1.0f, -0.5f }, { -1.0f, -1.0f, -0.2f }, { 0.0f, -1.0f, -0.1f }, + { 1.0f, -1.0f, -0.2f }, { 2.0f, -1.0f, -0.5f }, { -1.0f, -2.0f, -0.2f }, { 0.0f, -2.0f, -0.2f }, + { 1.0f, -2.0f, -0.2f }, { 0.0f, -3.0f, -0.5f }, { -1.0f, 2.0f, -0.2f }, { 0.0f, 2.0f, -0.5f }, + { 1.0f, 2.0f, -0.2f }, { -2.0f, 1.0f, -0.5f }, { -1.0f, 1.0f, -0.2f }, { 0.0f, 1.0f, -0.2f }, + { 1.0f, 1.0f, -0.2f }, { 2.0f, 1.0f, -0.5f }, { -2.0f, 0.0f, -0.5f }, { -1.0f, 0.0f, -0.2f }, + { 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, -0.2f }, { 2.0f, 0.0f, -0.5f }, { -2.0f, -1.0f, -0.5f }, + { -1.0f, -1.0f, -0.2f }, { 0.0f, -1.0f, -0.1f }, { 1.0f, -1.0f, -0.2f }, { 2.0f, -1.0f, -0.5f }, + { -1.0f, -2.0f, -0.2f }, { 0.0f, -2.0f, -0.2f }, { 1.0f, -2.0f, -0.2f }, { 0.0f, -3.0f, -0.5f }, +}; + +static s32 sPad[2] = { 0, 0 }; + +#include "overlays/ovl_En_Sda/ovl_En_Sda.c" + +void EnSda_Init(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnSda_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnSda_Update(Actor* thisx, GlobalContext* globalCtx) { + EnSda* this = THIS; + Player* player; + + if (this->actor.params == ENSDA_1) { + player = (Player*)this->actor.parent; + } else { + player = GET_PLAYER(globalCtx); + } + this->actor.world.pos = player->actor.world.pos; +} + +void EnSda_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSda* this = THIS; + Player* player; + u8* shadowTexture = GRAPH_ALLOC(globalCtx->state.gfxCtx, 64 * 64); + + if (this->actor.params == ENSDA_1) { + player = (Player*)this->actor.parent; + } else { + player = GET_PLAYER(globalCtx); + } + + player->actor.shape.shadowAlpha = 0; + func_8094702C(this, shadowTexture, player, globalCtx); + + if (KREG(0) < 5) { + func_80947668(shadowTexture, player, globalCtx); + } +} + +void func_809469C0(Player* player, u8* shadowTexture, f32 arg2) { + s16 temp_t0; + s16 temp_t1; + s16 temp_v1; + s16 temp_v0; + s16 phi_a0; + s16 phi_a3; + s16 i; + s16 j; + Vec3f lerp; + Vec3f sp88; + Vec3f sp7C; + + for (i = 0; i < 16; i++) { + if ((arg2 == 0.0f) || ((j = D_80947ACC[i]) >= 0)) { + if (arg2 > 0.0f) { + lerp.x = D_80947EA0[i].x + (D_80947EA0[j].x - D_80947EA0[i].x) * arg2; + lerp.y = D_80947EA0[i].y + (D_80947EA0[j].y - D_80947EA0[i].y) * arg2; + lerp.z = D_80947EA0[i].z + (D_80947EA0[j].z - D_80947EA0[i].z) * arg2; + + sp88.x = lerp.x - player->actor.world.pos.x; + sp88.y = lerp.y - player->actor.world.pos.y + BREG(48) + 76.0f + 30.0f - 105.0f + 15.0f; + sp88.z = lerp.z - player->actor.world.pos.z; + } else { + sp88.x = D_80947EA0[i].x - player->actor.world.pos.x; + sp88.y = D_80947EA0[i].y - player->actor.world.pos.y + BREG(48) + 76.0f + 30.0f - 105.0f + 15.0f; + sp88.z = D_80947EA0[i].z - player->actor.world.pos.z; + } + + Matrix_MultVec3f(&sp88, &sp7C); + sp7C.x *= (1.0f + (BREG(49) / 100.0f)); + sp7C.y *= (1.0f + (BREG(49) / 100.0f)); + temp_t0 = sp7C.x + 32.0f; + temp_t1 = sp7C.y * 64.0f; + + if (D_80947AEC[i] == 2) { + for (j = 0, phi_a3 = -0x180; j < 12; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947A98[j]; phi_a0 < D_80947A98[j]; phi_a0++) { + temp_v1 = temp_t0 + phi_a0; + if ((temp_v1 >= 0) && (temp_v1 < 0x40)) { + temp_v0 = temp_t1 + phi_a3; + if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { + shadowTexture[temp_v1 + temp_v0] = 255; + } + } + } + } + } else if (D_80947AEC[i] == 1) { + for (j = 0, phi_a3 = -0x100; j < 8; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947A88[j]; phi_a0 < D_80947A88[j]; phi_a0++) { + temp_v1 = temp_t0 + phi_a0; + if ((temp_v1 >= 0) && (temp_v1 < 0x40)) { + temp_v0 = temp_t1 + phi_a3; + if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { + shadowTexture[temp_v1 + temp_v0] = 255; + } + } + } + } + } else if (D_80947AEC[i] == 0) { + for (j = 0, phi_a3 = -0xC0; j < 7; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947A78[j]; phi_a0 < D_80947A78[j] - 1; phi_a0++) { + temp_v1 = temp_t0 + phi_a0; + if ((temp_v1 >= 0) && (temp_v1 < 0x40)) { + temp_v0 = temp_t1 + phi_a3; + if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { + shadowTexture[temp_v1 + temp_v0] = 255; + } + } + } + } + } else if (D_80947AEC[i] == 4) { + for (j = 0, phi_a3 = -0x1C0; j < 14; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947AB0[j]; phi_a0 < D_80947AB0[j]; phi_a0++) { + temp_v1 = temp_t0 + phi_a0; + if ((temp_v1 >= 0) && (temp_v1 < 0x40)) { + temp_v0 = temp_t1 + phi_a3; + if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { + shadowTexture[temp_v1 + temp_v0] = 255; + } + } + } + } + } else { + for (j = 0, phi_a3 = -0x80; j < 6; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947A6C[j]; phi_a0 < D_80947A6C[j] - 1; phi_a0++) { + temp_v1 = temp_t0 + phi_a0; + if ((temp_v1 >= 0) && (temp_v1 < 0x40)) { + temp_v0 = temp_t1 + phi_a3; + if ((temp_v0 >= 0) && (temp_v0 < 0x1000)) { + shadowTexture[temp_v1 + temp_v0] = 255; + } + } + } + } + } + } + } +} + +void func_8094702C(EnSda* this, u8* shadowTexture, Player* player, GlobalContext* globalCtx) { + s16 temp_t0; + s16 temp_t1; + s16 temp_v0; + s16 temp_v1; + s16 phi_a0; + s16 phi_a3; + s16 i; + s16 j; + Vec3f sp194; + Vec3f sp188; + s32* shadowTextureTemp32; + u8* shadowTextureTemp; + Vec3s sp178; + Vec3f sp16C; + Vec3f sp64[22]; + + if (BREG(57) != 0) { + for (shadowTextureTemp = shadowTexture, i = 0; i < 0x1000; i++, shadowTextureTemp++) { + if ((i >= 0 && i < 0x40) || (i >= 0xFC0 && i < 0x1000) || ((i & 0x3F) == 0) || ((i & 0x3F) == 0x3F)) { + *shadowTextureTemp = 255; + } else { + *shadowTextureTemp = 0; + } + } + } else { + for (shadowTextureTemp32 = (s32*)shadowTexture, i = 0; i < 0x400; i++, shadowTextureTemp32++) { + *shadowTextureTemp32 = 0; + } + } + + Matrix_RotateXFNew((BREG(50) + 70) / 100.0f); + + for (i = 0; i < 18; i++) { + if (D_80947AFC[i] >= 0) { + D_80947EA0[D_80947AFC[i]] = player->bodyPartsPos[i]; + } + } + + D_80947EA0[0].y += 3.0f; + D_80947EA0[15].x = D_80947EA0[0].x + ((D_80947EA0[15].x - D_80947EA0[0].x) * 1.2f); + D_80947EA0[15].y = D_80947EA0[0].y + ((D_80947EA0[15].y - D_80947EA0[0].y) * -1.2f); + D_80947EA0[15].z = D_80947EA0[0].z + ((D_80947EA0[15].z - D_80947EA0[0].z) * 1.2f); + + for (i = 0; i < 6; i++) { + func_809469C0(player, shadowTexture, i / 5.0f); + } + + if (this->actor.params != ENSDA_1) { + Matrix_MtxFToYXZRot(&player->shieldMf, &sp178, false); + + sp178.y += (KREG(87) * 0x8000) + 0x8000; + sp178.x *= (KREG(88) - 1); + + Matrix_Mult(&player->shieldMf, MTXMODE_NEW); + Matrix_MultVec3f(&D_80947A60, &sp16C); + Matrix_RotateYS(sp178.y, MTXMODE_NEW); + Matrix_RotateXS(sp178.x, MTXMODE_APPLY); + + for (i = 0; i < 22; i++) { + Matrix_MultVec3f(&D_80947B10[i], &sp188); + sp64[i].x = (((KREG(82) / 100.0f) + 4.0f) * sp188.x) + sp16C.x; + sp64[i].y = (((KREG(82) / 100.0f) + 4.0f) * sp188.y) + sp16C.y; + sp64[i].z = (((KREG(82) / 100.0f) + 4.0f) * sp188.z) + sp16C.z; + } + + Matrix_RotateXFNew((BREG(50) + 70) / 100.0f); + + for (i = 0; i < 22; i++) { + sp194.x = sp64[i].x - player->actor.world.pos.x; + sp194.y = sp64[i].y - player->actor.world.pos.y + KREG(80) + 16.0f; + sp194.z = sp64[i].z - player->actor.world.pos.z; + + Matrix_MultVec3f(&sp194, &sp188); + + sp188.x *= (1.0f + (KREG(90) / 100.0f)); + sp188.y *= (1.0f + (KREG(90) / 100.0f)); + temp_t0 = sp188.x + 32.0f; + temp_t1 = sp188.y * 64.0f; + + do { + for (j = 0, phi_a3 = -0xC0; j < 7; j++, phi_a3 += 0x40) { + for (phi_a0 = -D_80947A78[j]; phi_a0 < D_80947A78[j] - 1; phi_a0++) { + temp_v0 = temp_t0 + phi_a0; + if ((temp_v0 >= 0) && (temp_v0 < 0x40)) { + temp_v1 = temp_t1 + phi_a3; + if ((temp_v1 >= 0) && (temp_v1 < 0x1000)) { + shadowTexture[temp_v0 + temp_v1] = 255; + } + } + } + } + j++; + } while (j < 6); + } + } + + if (BREG(61) == 1) { + for (shadowTextureTemp = shadowTexture, i = 0; i < 0x1000; i++, shadowTextureTemp++) { + if (*shadowTextureTemp != 0) { + *shadowTextureTemp = -((i >> 6) * (BREG(60) + 4)) + (255 - BREG(61)); + } + } + } +} + +void func_80947668(u8* shadowTexture, Player* player, GlobalContext* globalCtx) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + f32 tempx; + f32 tempz; + s16 i; + + OPEN_DISPS(gfxCtx); + + func_8012C448(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x00, 0, 0, 0, (BREG(52) + 50)); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 0); + + Matrix_Translate(player->actor.world.pos.x, player->actor.floorHeight, player->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYF(BREG(51) / 100.0f, MTXMODE_APPLY); + Matrix_Scale(1.0f, 1.0f, (BREG(63) / 10.0f) + 1.0f, MTXMODE_APPLY); + + tempx = (BREG(62) / 10.0f) + 2.0f; + tempz = ((player->actor.world.pos.y - player->actor.floorHeight + BREG(54)) * (BREG(55) - 5) / 10.0f) + BREG(58) - + 20.0f; + + Matrix_Translate(tempx, 0.0f, tempz, MTXMODE_APPLY); + Matrix_Scale(((BREG(56) - 250) / 1000.0f) + 0.6f, 1.0f, ((BREG(59) - 250) / 1000.0f) + 0.6f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, ovl_En_Sda_DL_1498); + gDPLoadTextureBlock(POLY_XLU_DISP++, shadowTexture, G_IM_FMT_I, G_IM_SIZ_8b, 64, 64, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, 6, 6, G_TX_NOLOD, G_TX_NOLOD); + gSPDisplayList(POLY_XLU_DISP++, ovl_En_Sda_DL_14B8); + + for (i = 0; i < KREG(78); i++) { + Matrix_Scale((KREG(79) / 100.0f) + 1.0f, 1.0f, (KREG(79) / 100.0f) + 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++, ovl_En_Sda_DL_14B8); + } + + CLOSE_DISPS(gfxCtx); + + if (1) {} +} diff --git a/src/overlays/actors/ovl_En_Sda/z_en_sda.h b/src/overlays/actors/ovl_En_Sda/z_en_sda.h index fff04d601..ff17a2538 100644 --- a/src/overlays/actors/ovl_En_Sda/z_en_sda.h +++ b/src/overlays/actors/ovl_En_Sda/z_en_sda.h @@ -5,6 +5,8 @@ struct EnSda; +#define ENSDA_1 1 + typedef struct EnSda { /* 0x000 */ Actor actor; } EnSda; // size = 0x144 diff --git a/src/overlays/actors/ovl_En_Sekihi/z_en_sekihi.c b/src/overlays/actors/ovl_En_Sekihi/z_en_sekihi.c index 58152281d..5ce4184a6 100644 --- a/src/overlays/actors/ovl_En_Sekihi/z_en_sekihi.c +++ b/src/overlays/actors/ovl_En_Sekihi/z_en_sekihi.c @@ -1,6 +1,12 @@ +/* + * File: z_en_sekihi.c + * Overlay: ovl_En_Sekihi + * Description: Mikau's Grave & Song Pedestals + */ + #include "z_en_sekihi.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnSekihi*)thisx) diff --git a/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c b/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c index badcc5501..0d53b127e 100644 --- a/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c +++ b/src/overlays/actors/ovl_En_Sellnuts/z_en_sellnuts.c @@ -5,8 +5,9 @@ */ #include "z_en_sellnuts.h" +#include "objects/object_dnt/object_dnt.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnSellnuts*)thisx) @@ -34,33 +35,7 @@ void func_80ADCA64(EnSellnuts* this, GlobalContext* globalCtx); s32 func_80ADCE4C(EnSellnuts* this, Path* path, s32 arg2); f32 func_80ADCFE8(Path* path, s32 arg1, Vec3f* pos, Vec3s* arg3); -extern AnimationHeader D_06000994; -extern AnimationHeader D_060012F4; -extern Gfx D_06001350[]; -extern AnimationHeader D_06001BC8; -extern AnimationHeader D_06001E2C; -extern AnimationHeader D_06002268; -extern AnimationHeader D_06002670; -extern AnimationHeader D_060029E8; -extern AnimationHeader D_06002F08; -extern AnimationHeader D_06003438; -extern AnimationHeader D_060038CC; -extern AnimationHeader D_06003CC0; -extern AnimationHeader D_06004700; -extern AnimationHeader D_06004AA0; -extern AnimationHeader D_06004E38; -extern AnimationHeader D_06005488; -extern AnimationHeader D_0600577C; -extern AnimationHeader D_06005CA8; -extern Gfx D_06008290[]; -extern FlexSkeletonHeader D_0600AC70; -extern AnimationHeader D_0600B0B4; - -static u16 D_80ADD910[] = { - 0x0614, - 0x060E, - 0x0628, -}; +static u16 D_80ADD910[] = { 0x0614, 0x060E, 0x0628 }; static u16 D_80ADD918[] = { 0x0616, 0x0610, 0x0629 }; @@ -105,15 +80,30 @@ static ColliderCylinderInitType1 sCylinderInit = { { 27, 32, 0, { 0, 0, 0 } }, }; -static ActorAnimationEntryS D_80ADD990[] = { - { &D_06005488, 1.0f, 0, -1, 0, 0 }, { &D_0600B0B4, 1.0f, 0, -1, 0, 0 }, { &D_06004AA0, 1.0f, 0, -1, 2, 0 }, - { &D_06004E38, 1.0f, 0, -1, 2, 0 }, { &D_060029E8, 1.0f, 0, -1, 2, 0 }, { &D_06005CA8, 1.0f, 0, -1, 2, 0 }, - { &D_060038CC, 1.0f, 0, -1, 0, 0 }, { &D_06003CC0, 1.0f, 0, -1, 0, 0 }, { &D_060012F4, 1.0f, 0, -1, 2, 0 }, - { &D_06004700, 1.0f, 0, -1, 2, 0 }, { &D_06001BC8, 1.0f, 0, -1, 0, 0 }, { &D_06003438, 1.0f, 0, -1, 2, 0 }, - { &D_06001E2C, 1.0f, 0, -1, 0, 0 }, { &D_06000994, 1.0f, 0, -1, 0, 0 }, { &D_06002268, 1.0f, 0, -1, 2, 0 }, - { &D_06002F08, 1.0f, 0, -1, 0, 0 }, { &D_0600577C, 1.0f, 0, -1, 0, -4 }, { &D_060029E8, 1.0f, 8, -1, 2, 0 }, - { &D_060029E8, 1.0f, 4, -1, 2, -4 }, { &D_060029E8, 1.0f, 0, -1, 2, 0 }, { &D_06001BC8, 1.0f, 0, -1, 0, 0 }, - { &D_060012F4, -1.0f, 0, -1, 2, 0 }, { &D_06002670, 1.0f, 0, -1, 2, 0 }, +static AnimationInfoS D_80ADD990[] = { + { &object_dnt_Anim_005488, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00B0B4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_004AA0, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004E38, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_005CA8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0038CC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003CC0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_004700, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_003438, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001E2C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_000994, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_002268, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002F08, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_00577C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 8, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 4, -1, ANIMMODE_ONCE, -4 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_dnt_Anim_0012F4, -1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_dnt_Anim_002670, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, }; static InitChainEntry sInitChain[] = { @@ -219,7 +209,7 @@ void func_80ADAFC0(EnSellnuts* this) { } Actor* func_80ADB040(GlobalContext* globalCtx) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (actor != NULL) { if ((actor->id == ACTOR_EN_SELLNUTS) && !ENSELLNUTS_GET_1(actor)) { @@ -245,25 +235,25 @@ f32 func_80ADB08C(GlobalContext* globalCtx) { void func_80ADB0D8(EnSellnuts* this, GlobalContext* globalCtx) { s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if (currentFrame == frameCount) { switch (this->unk_340) { case 0x611: case 0x62A: this->unk_34C = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, 0); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 0); this->actionFunc = func_80ADBFA0; break; case 0x618: if (this->unk_34C == 1) { this->unk_34C = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, 0); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 0); this->actionFunc = func_80ADB544; } else { this->unk_34C = 1; - func_8013BC6C(&this->skelAnime, D_80ADD990, 1); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 1); this->actionFunc = func_80ADBFA0; } break; @@ -274,7 +264,7 @@ void func_80ADB0D8(EnSellnuts* this, GlobalContext* globalCtx) { case 0x614: case 0x628: this->unk_34C = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, 0); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 0); this->actionFunc = func_80ADB924; break; @@ -283,14 +273,14 @@ void func_80ADB0D8(EnSellnuts* this, GlobalContext* globalCtx) { case 0x616: case 0x629: this->unk_34C = 1; - func_8013BC6C(&this->skelAnime, D_80ADD990, 1); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 1); this->actionFunc = func_80ADB924; break; case 0x613: case 0x619: this->unk_34C = 7; - func_8013BC6C(&this->skelAnime, D_80ADD990, 7); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 7); this->actionFunc = func_80ADBD64; break; } @@ -299,40 +289,40 @@ void func_80ADB0D8(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADB254(EnSellnuts* this, GlobalContext* globalCtx) { s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); - if (((this->actor.yDistToPlayer < 50.0f) && (this->actor.yDistToPlayer > -50.0f) ? true : false) && + if (((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f) ? true : false) && ((this->actor.xzDistToPlayer < 200.0f) ? true : false)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); this->actionFunc = func_80ADB4F4; this->unk_34C = 3; this->collider.dim.height = 64; - func_8013BC6C(&this->skelAnime, D_80ADD990, 3); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 3); } else if (currentFrame == frameCount) { if ((this->unk_34C == 4) || (this->unk_34C == 18)) { this->unk_34C = 17; this->collider.dim.height = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); - func_8013BC6C(&this->skelAnime, D_80ADD990, 17); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 17); } else if (this->unk_34C == 2) { this->unk_34C = 16; this->collider.dim.height = 32; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_UP); - func_8013BC6C(&this->skelAnime, D_80ADD990, 16); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 16); } else if (this->unk_34C == 17) { if (DECR(this->unk_34E) == 0) { this->unk_34E = Rand_ZeroOne() * 10.0f; this->unk_34C = 2; this->collider.dim.height = 32; - func_8013BC6C(&this->skelAnime, D_80ADD990, 2); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 2); } } else if (this->unk_34C == 16) { if (DECR(this->unk_34E) == 0) { this->unk_34E = Rand_S16Offset(40, 40); this->unk_34C = 18; this->collider.dim.height = 32; - func_8013BC6C(&this->skelAnime, D_80ADD990, 18); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 18); } } } @@ -341,7 +331,7 @@ void func_80ADB254(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADB4F4(EnSellnuts* this, GlobalContext* globalCtx) { if (this->skelAnime.curFrame == this->skelAnime.endFrame) { this->actionFunc = func_80ADB544; - func_8013BC6C(&this->skelAnime, D_80ADD990, 0); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 0); } } @@ -350,37 +340,37 @@ void func_80ADB544(EnSellnuts* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 0x7D0, 0); this->actor.world.rot.y = this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { - if (func_800B8708(globalCtx) == 0x2A) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (Player_GetExchangeItemId(globalCtx) == EXCH_ITEM_2A) { player->actor.textId = D_80ADD928[this->unk_33A]; this->unk_340 = player->actor.textId; this->actionFunc = func_80ADBAB8; } else { switch (this->unk_340) { case 0x60E: - gSaveContext.weekEventReg[17] |= 0x20; - gSaveContext.weekEventReg[86] |= 4; - func_801518B0(globalCtx, this->unk_340, &this->actor); + gSaveContext.save.weekEventReg[17] |= 0x20; + gSaveContext.save.weekEventReg[86] |= 4; + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); this->actionFunc = func_80ADB0D8; break; case 0x628: - gSaveContext.weekEventReg[77] |= 0x40; - gSaveContext.weekEventReg[86] |= 4; - func_801518B0(globalCtx, this->unk_340, &this->actor); + gSaveContext.save.weekEventReg[77] |= 0x40; + gSaveContext.save.weekEventReg[86] |= 4; + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); this->actionFunc = func_80ADB0D8; break; case 0x614: - gSaveContext.weekEventReg[17] |= 0x40; - func_801518B0(globalCtx, this->unk_340, &this->actor); + gSaveContext.save.weekEventReg[17] |= 0x40; + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); this->actionFunc = func_80ADB0D8; break; case 0x610: case 0x616: case 0x629: - func_801518B0(globalCtx, this->unk_340, &this->actor); + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); this->actionFunc = func_80ADB0D8; break; @@ -390,52 +380,52 @@ void func_80ADB544(EnSellnuts* this, GlobalContext* globalCtx) { } } } else if (((this->actor.xzDistToPlayer < 80.0f) && - (((this->actor.yDistToPlayer < 50.0f) && (this->actor.yDistToPlayer > -50.0f)) ? true : false)) || + (((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) ? true : false)) || this->actor.isTargeted) { - func_800B85E0(&this->actor, globalCtx, 80.0f, 0x2A); + func_800B85E0(&this->actor, globalCtx, 80.0f, EXCH_ITEM_2A); if (player->transformation == PLAYER_FORM_DEKU) { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { this->unk_33A = 2; - if (gSaveContext.weekEventReg[77] & 0x40) { + if (gSaveContext.save.weekEventReg[77] & 0x40) { this->unk_340 = D_80ADD918[this->unk_33A]; } else { this->unk_340 = D_80ADD910[this->unk_33A]; } } else { this->unk_33A = 1; - if (gSaveContext.weekEventReg[17] & 0x20) { + if (gSaveContext.save.weekEventReg[17] & 0x20) { this->unk_340 = D_80ADD918[this->unk_33A]; } else { this->unk_340 = D_80ADD910[this->unk_33A]; } } - } else if (gSaveContext.weekEventReg[17] & 0x40) { + } else if (gSaveContext.save.weekEventReg[17] & 0x40) { this->unk_340 = D_80ADD918[this->unk_33A]; } else { this->unk_340 = D_80ADD910[this->unk_33A]; } } - if (!(((this->actor.yDistToPlayer < 50.0f) && (this->actor.yDistToPlayer > -50.0f)) ? true : false) || + if (!(((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) ? true : false) || !((this->actor.xzDistToPlayer < 200.0f) ? true : false)) { this->unk_34C = 4; - func_8013BC6C(&this->skelAnime, D_80ADD990, 4); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 4); this->actionFunc = func_80ADB254; } } void func_80ADB924(EnSellnuts* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - u8 temp_v0 = func_80152498(&globalCtx->msgCtx); - s32 temp_v0_2; + u8 msgState = Message_GetState(&globalCtx->msgCtx); + s32 item; - if (temp_v0 == 0x10) { - temp_v0_2 = func_80123810(globalCtx); - if (temp_v0_2 > 0) { - if (temp_v0_2 == 0x2A) { + if (msgState == 0x10) { + item = func_80123810(globalCtx); + if (item > EXCH_ITEM_NONE) { + if (item == EXCH_ITEM_2A) { player->actor.textId = D_80ADD928[this->unk_33A]; this->unk_340 = player->actor.textId; - player->unk_A87 = temp_v0_2; + player->exchangeItemId = item; this->actionFunc = func_80ADBAB8; } else { player->actor.textId = D_80ADD920[this->unk_33A]; @@ -443,12 +433,12 @@ void func_80ADB924(EnSellnuts* this, GlobalContext* globalCtx) { this->actionFunc = func_80ADB0D8; } func_801477B4(globalCtx); - } else if (temp_v0_2 < 0) { + } else if (item < EXCH_ITEM_NONE) { this->unk_340 = D_80ADD920[this->unk_33A]; func_80151938(globalCtx, this->unk_340); this->actionFunc = func_80ADB0D8; } - } else if ((temp_v0 == 5) && func_80147624(globalCtx)) { + } else if ((msgState == 5) && Message_ShouldAdvance(globalCtx)) { if (this->unk_340 == D_80ADD910[this->unk_33A]) { this->unk_340 = D_80ADD938[this->unk_33A]; func_80151938(globalCtx, this->unk_340); @@ -462,24 +452,24 @@ void func_80ADB924(EnSellnuts* this, GlobalContext* globalCtx) { } void func_80ADBAB8(EnSellnuts* this, GlobalContext* globalCtx) { - u8 sp27 = func_80152498(&globalCtx->msgCtx); + u8 sp27 = Message_GetState(&globalCtx->msgCtx); s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if (this->unk_368 == 0x28) { this->unk_34C = 5; - func_8013BC6C(&this->skelAnime, D_80ADD990, 5); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 5); } this->unk_368++; if ((currentFrame == frameCount) && (this->unk_34C == 5)) { this->unk_34C = 6; - func_8013BC6C(&this->skelAnime, D_80ADD990, 6); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 6); } - if ((sp27 == 5) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if ((sp27 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = func_80ADBBEC; func_800B7298(globalCtx, NULL, 0x13); @@ -489,55 +479,55 @@ void func_80ADBAB8(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADBBEC(EnSellnuts* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - gSaveContext.weekEventReg[17] |= 0x80; + gSaveContext.save.weekEventReg[17] |= 0x80; this->actionFunc = func_80ADBCE4; } else { - func_800B8A1C(&this->actor, globalCtx, 0x97, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, GI_DEED_LAND, 300.0f, 300.0f); } } void func_80ADBC60(EnSellnuts* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, this->unk_340, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); this->actionFunc = func_80ADB0D8; } else { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); this->unk_340 = D_80ADD930[this->unk_33A]; } } void func_80ADBCE4(EnSellnuts* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); this->unk_340 = D_80ADD930[this->unk_33A]; this->actionFunc = func_80ADBC60; } } void func_80ADBD64(EnSellnuts* this, GlobalContext* globalCtx) { - u8 sp27 = func_80152498(&globalCtx->msgCtx); + u8 sp27 = Message_GetState(&globalCtx->msgCtx); s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if ((currentFrame == frameCount) && (this->unk_34C == 7)) { this->unk_34C = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, 0); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 0); } - if ((sp27 == 5) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if ((sp27 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->unk_338 &= ~2; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_34C = 8; - func_8013BC6C(&this->skelAnime, D_80ADD990, 8); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 8); this->actionFunc = func_80ADBE80; } } void func_80ADBE80(EnSellnuts* this, GlobalContext* globalCtx) { s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); func_80ADAE64(this); if (this->unk_366 == 0) { @@ -556,8 +546,8 @@ void func_80ADBE80(EnSellnuts* this, GlobalContext* globalCtx) { if (currentFrame == frameCount) { this->unk_350 = 4; this->unk_34C = 19; - func_8013BC6C(&this->skelAnime, D_80ADD990, 19); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 19); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); this->unk_338 &= ~1; this->unk_338 |= 8; this->unk_32C = this->actor.world.pos.y; @@ -566,8 +556,8 @@ void func_80ADBE80(EnSellnuts* this, GlobalContext* globalCtx) { } void func_80ADBFA0(EnSellnuts* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; if (this->unk_34C == 0) { this->actionFunc = func_80ADB544; @@ -590,7 +580,7 @@ void func_80ADC034(EnSellnuts* this, GlobalContext* globalCtx) { 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_34C = 10; - func_8013BC6C(&this->skelAnime, D_80ADD990, 10); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 10); this->unk_368 = 0; this->actionFunc = func_80ADC37C; } @@ -599,7 +589,7 @@ void func_80ADC034(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADC118(EnSellnuts* this, GlobalContext* globalCtx) { Vec3f sp34; s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if (currentFrame == frameCount) { Math_SmoothStepToS(&this->unk_364, 0x1C71, 3, 0x100, 0); @@ -625,8 +615,8 @@ void func_80ADC118(EnSellnuts* this, GlobalContext* globalCtx) { if ((this->actor.home.pos.y + 22.5f) < this->actor.world.pos.y) { this->unk_34C = 9; this->unk_360 = 0.3f; - func_8013BC6C(&this->skelAnime, D_80ADD990, 9); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 9); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); this->actionFunc = func_80ADC034; } } @@ -674,13 +664,13 @@ void func_80ADC37C(EnSellnuts* this, GlobalContext* globalCtx) { this->unk_334++; } } - } else if (this->actor.yDistToPlayer > 500.0f) { + } else if (this->actor.playerHeightRel > 500.0f) { ActorCutscene_Stop(this->cutscene); this->actionFunc = func_80ADC580; } Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); if (this->unk_366 == 2) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->cutscene, &this->actor); @@ -706,10 +696,10 @@ void func_80ADC580(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADC5A4(EnSellnuts* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { player->linearVelocity = 0.0f; - this->actor.flags &= ~0x10000; - func_801518B0(globalCtx, this->unk_340, &this->actor); + this->actor.flags &= ~ACTOR_FLAG_10000; + Message_StartTextbox(globalCtx, this->unk_340, &this->actor); if (this->unk_340 == 0x625) { this->unk_338 |= 1; this->actor.draw = EnSellnuts_Draw; @@ -721,7 +711,7 @@ void func_80ADC5A4(EnSellnuts* this, GlobalContext* globalCtx) { this->actionFunc = func_80ADC6D0; } } else if (func_80ADB08C(globalCtx) < 80.0f) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, this->actor.xzDistToPlayer); } } @@ -729,11 +719,11 @@ void func_80ADC5A4(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADC6D0(EnSellnuts* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; if (player->transformation == PLAYER_FORM_DEKU) { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { this->unk_33A = 2; } else { this->unk_33A = 1; @@ -747,7 +737,7 @@ void func_80ADC6D0(EnSellnuts* this, GlobalContext* globalCtx) { } void func_80ADC7B4(EnSellnuts* this, GlobalContext* globalCtx) { - s32 temp = func_80152498(&globalCtx->msgCtx); + s32 temp = Message_GetState(&globalCtx->msgCtx); if (this->unk_366 == 0) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { @@ -759,8 +749,8 @@ void func_80ADC7B4(EnSellnuts* this, GlobalContext* globalCtx) { } ActorCutscene_SetIntentToPlay(this->cutscene); } - } else if ((this->unk_366 == 1) && (temp == 5) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + } else if ((this->unk_366 == 1) && (temp == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->unk_366 = 0; ActorCutscene_Stop(this->cutscene); @@ -803,7 +793,7 @@ void func_80ADC8C4(EnSellnuts* this, GlobalContext* globalCtx) { this->actor.gravity = -1.0f; this->actor.velocity.y = -1.0f; this->actor.speedXZ = 0.0f; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->unk_338 &= ~1; this->unk_338 &= ~2; this->actionFunc = func_80ADCA64; @@ -812,13 +802,13 @@ void func_80ADC8C4(EnSellnuts* this, GlobalContext* globalCtx) { this->unk_334++; } Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.2f, 1.0f); - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); } } void func_80ADCA64(EnSellnuts* this, GlobalContext* globalCtx) { s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if (this->unk_34C == 22) { Math_SmoothStepToS(&this->unk_364, 0, 3, 0x100, 0); @@ -831,8 +821,8 @@ void func_80ADCA64(EnSellnuts* this, GlobalContext* globalCtx) { this->unk_350 = 4; this->unk_34C = 19; this->actor.velocity.y = 0.0f; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DOWN); } return; } @@ -842,10 +832,10 @@ void func_80ADCA64(EnSellnuts* this, GlobalContext* globalCtx) { if (this->unk_34C == 19) { this->unk_34C = 17; this->collider.dim.height = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, 17); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, 17); } else if (this->unk_34C == 17) { ActorCutscene_Stop(this->cutscene); - gSaveContext.weekEventReg[73] |= 4; + gSaveContext.save.weekEventReg[73] |= 4; Actor_MarkForDeath(&this->actor); } } @@ -853,7 +843,7 @@ void func_80ADCA64(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADCC04(EnSellnuts* this, GlobalContext* globalCtx) { s16 currentFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animationSeg); + s16 frameCount = Animation_GetLastFrame(D_80ADD990[this->unk_34C].animation); if (this->unk_34C == 3) { if (currentFrame == frameCount) { @@ -862,18 +852,18 @@ void func_80ADCC04(EnSellnuts* this, GlobalContext* globalCtx) { this->unk_354 = 1.0f; this->unk_358 = 1.0f; this->unk_35C = 1.0f; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); } } else if (this->unk_34C == 21) { func_80ADAFC0(this); if (currentFrame == 0) { if (func_80ADB08C(globalCtx) < 9999.0f) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 9999.0f); } this->unk_340 = 0x626; this->unk_34C = 0; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->actionFunc = func_80ADC5A4; } } @@ -881,11 +871,11 @@ void func_80ADCC04(EnSellnuts* this, GlobalContext* globalCtx) { void func_80ADCD3C(EnSellnuts* this, GlobalContext* globalCtx) { Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); - if (gSaveContext.weekEventReg[73] & 4) { + if (gSaveContext.save.weekEventReg[73] & 4) { this->unk_338 |= 2; this->unk_338 |= 1; this->unk_340 = 0x626; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; this->actor.gravity = -1.0f; this->actor.draw = EnSellnuts_Draw; this->unk_34A = 50; @@ -893,8 +883,8 @@ void func_80ADCD3C(EnSellnuts* this, GlobalContext* globalCtx) { this->collider.dim.height = 64; this->unk_34C = 3; this->unk_350 = 4; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->actionFunc = func_80ADCC04; } else if (D_80ADD940 != 0) { this->collider.dim.height = 64; @@ -902,7 +892,7 @@ void func_80ADCD3C(EnSellnuts* this, GlobalContext* globalCtx) { } s32 func_80ADCE4C(EnSellnuts* this, Path* path, s32 arg2) { - Vec3s* points = (Vec3s*)Lib_SegmentedToVirtual(path->points); + Vec3s* points = Lib_SegmentedToVirtual(path->points); s32 count = path->count; s32 var = arg2; s32 ret = false; @@ -925,7 +915,7 @@ s32 func_80ADCE4C(EnSellnuts* this, Path* path, s32 arg2) { pointY = points[var + 1].z - points[var - 1].z; } - func_8017B7F8(&sp30, func_80086B30(pointX, pointY) * 10430.378f, &sp44, &sp40, &sp3C); + func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(pointX, pointY)), &sp44, &sp40, &sp3C); if (((this->actor.world.pos.x * sp44) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) { ret = true; } @@ -939,7 +929,7 @@ f32 func_80ADCFE8(Path* path, s32 arg1, Vec3f* pos, Vec3s* arg3) { Vec3s* points; if (path != NULL) { - points = (Vec3s*)Lib_SegmentedToVirtual(path->points); + points = Lib_SegmentedToVirtual(path->points); points = &points[arg1]; sp20.x = points->x; sp20.y = points->y; @@ -957,16 +947,17 @@ void EnSellnuts_Init(Actor* thisx, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s32 pad2; - if ((gSaveContext.weekEventReg[17] & 0x80) || (gSaveContext.weekEventReg[61] & 0x10)) { + if ((gSaveContext.save.weekEventReg[17] & 0x80) || (gSaveContext.save.weekEventReg[61] & 0x10)) { Actor_MarkForDeath(&this->actor); } Actor_ProcessInitChain(&this->actor, sInitChain); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600AC70, &D_06005488, this->jointTable, this->morphTable, 28); + 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); - this->path = func_8013D648(globalCtx, ENSELLNUTS_GET_FC00(&this->actor), 0x3F); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 35.0f); + this->path = SubS_GetPathByIndex(globalCtx, ENSELLNUTS_GET_FC00(&this->actor), 0x3F); this->cutscene = this->actor.cutscene; Actor_SetScale(&this->actor, 0.01f); this->actor.colChkInfo.cylRadius = 0; @@ -978,7 +969,7 @@ void EnSellnuts_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_36C = 0.01f; this->actor.speedXZ = 0.0f; this->actor.velocity.y = 0.0f; - if (gSaveContext.weekEventReg[73] & 4) { + if (gSaveContext.save.weekEventReg[73] & 4) { if (ENSELLNUTS_GET_1(&this->actor)) { Actor_MarkForDeath(&this->actor); return; @@ -986,7 +977,7 @@ void EnSellnuts_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_338 |= 2; this->unk_338 |= 1; if (player->transformation == PLAYER_FORM_DEKU) { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { this->unk_33A = 2; } else { this->unk_33A = 1; @@ -998,7 +989,7 @@ void EnSellnuts_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.gravity = -1.0f; this->unk_34A = 50; this->unk_34C = 4; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->actionFunc = func_80ADB254; return; } @@ -1011,23 +1002,23 @@ void EnSellnuts_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.gravity = 0.0f; this->actor.draw = NULL; this->unk_34C = 20; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->unk_35C = 1.0f; this->unk_358 = 1.0f; this->unk_354 = 1.0f; this->unk_360 = 1.0f; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->actionFunc = func_80ADC5A4; } else { this->unk_338 |= 2; this->unk_338 &= ~1; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.gravity = 0.0f; this->actor.draw = NULL; this->unk_34C = 4; this->unk_34E = 20; this->collider.dim.height = 64; - func_8013BC6C(&this->skelAnime, D_80ADD990, this->unk_34C); + SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80ADD990, this->unk_34C); this->actionFunc = func_80ADCD3C; } } @@ -1044,7 +1035,7 @@ void EnSellnuts_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk_328++; if (player->transformation == PLAYER_FORM_DEKU) { - if (gSaveContext.day == 3) { + if (gSaveContext.save.day == 3) { this->unk_33A = 2; } else { this->unk_33A = 1; @@ -1053,10 +1044,10 @@ void EnSellnuts_Update(Actor* thisx, GlobalContext* globalCtx) { this->unk_33A = 0; } - Actor_SetHeight(&this->actor, 60.0f); + Actor_SetFocus(&this->actor, 60.0f); Actor_SetScale(&this->actor, 0.01f); SkelAnime_Update(&this->skelAnime); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); this->actionFunc(this, globalCtx); if (this->unk_338 & 8) { func_800B9010(&this->actor, NA_SE_EN_AKINDO_FLY - SFX_FLAG); @@ -1110,14 +1101,14 @@ s32 EnSellnuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d } if (limbIndex == 24) { - Matrix_InsertXRotation_s(this->unk_342, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_342, MTXMODE_APPLY); } if (limbIndex == 26) { if ((this->unk_34C == 6) || (this->unk_34C == 5) || (this->unk_34C == 7)) { - *dList = D_06001350; + *dList = object_dnt_DL_001350; } else { - *dList = D_06008290; + *dList = object_dnt_DL_008290; } } @@ -1127,7 +1118,7 @@ s32 EnSellnuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d void EnSellnuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { } -void func_80ADD7CC(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnSellnuts_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnSellnuts* this = THIS; if (((this->unk_350 == 1) || (this->unk_350 == 3)) && ((limbIndex == 23) || (limbIndex == 24))) { @@ -1140,7 +1131,7 @@ void func_80ADD7CC(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } if (limbIndex == 24) { - Matrix_RotateY(this->unk_344, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_344, MTXMODE_APPLY); } } @@ -1148,6 +1139,7 @@ void EnSellnuts_Draw(Actor* thisx, GlobalContext* globalCtx) { EnSellnuts* this = THIS; func_8012C28C(globalCtx->state.gfxCtx); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSellnuts_OverrideLimbDraw, EnSellnuts_PostLimbDraw, func_80ADD7CC, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnSellnuts_OverrideLimbDraw, EnSellnuts_PostLimbDraw, + EnSellnuts_TransformLimbDraw, &this->actor); } diff --git a/src/overlays/actors/ovl_En_Shn/z_en_shn.c b/src/overlays/actors/ovl_En_Shn/z_en_shn.c index 447f7cea4..0b9905ba5 100644 --- a/src/overlays/actors/ovl_En_Shn/z_en_shn.c +++ b/src/overlays/actors/ovl_En_Shn/z_en_shn.c @@ -1,6 +1,13 @@ +/* + * File: z_en_shn.c + * Overlay: ovl_En_Shn + * Description: Swamp Tourist Center Guide + * Shashin(Shn) ~ Photo + */ + #include "z_en_shn.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnShn*)thisx) @@ -8,11 +15,42 @@ void EnShn_Init(Actor* thisx, GlobalContext* globalCtx); void EnShn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnShn_Update(Actor* thisx, GlobalContext* globalCtx); void EnShn_Draw(Actor* thisx, GlobalContext* globalCtx); - void func_80AE69E8(EnShn* this, GlobalContext* globalCtx); void func_80AE6A64(EnShn* this, GlobalContext* globalCtx); +s32 func_80AE6704(EnShn* this, GlobalContext* globalCtx); + +// Could be something related to text/dialogue? +static UNK_TYPE D_80AE6F00[] = { + 0x00170800, 0x0B0E09C4, 0x0C0F09C5, 0x0C111708, 0x03018C04, 0x018E1901, 0x860F00FF, 0x1E001300, 0x00011501, + 0x47280012, 0x28001928, 0x002D2800, 0x5D280093, 0x28003319, 0x00472C09, 0xE70C2F00, 0x000C1210, 0x2C09CB0C, + 0x2F00000C, 0x0F09CC0C, 0x0F09CD0C, 0x0500A500, 0xCB00CB2C, 0x09D10C2F, 0x00000C0F, 0x09D20C19, 0xFFE62C09, + 0xD30C2F00, 0x000C0F09, 0xD40C0F09, 0xD50C0500, 0x9200B200, 0xB22C09D9, 0x0C2F0000, 0x0C0F09DA, 0x0C102C09, + 0xE80C2F00, 0x000C0F09, 0xE90C0F09, 0xEA0C0057, 0x04001712, 0x06000C00, 0x0013000C, 0x0C115704, 0x0700000E, + 0x09EB0C12, 0x16101206, 0x00060000, 0x1300060C, 0x07FFEC2C, 0x09EC0C2F, 0x00000C0F, 0x09ED0C0F, 0x09EE0C00, + 0x57040017, 0x1206000C, 0x00001300, 0x0C0C1157, 0x04070000, 0x0E09EF0C, 0x12161012, 0x06000600, 0x00130006, + 0x0C07FFEC, 0x12060004, 0x00001300, 0x040C0700, 0x000E09CE, 0x0C161012, 0x06000200, 0x00130002, 0x0C070000, + 0x0E09D80C, 0x16100C0F, 0x09CF0C1C, 0x05011509, 0x0000100E, 0x09D60C19, 0xFFF10037, 0x40001C2C, 0x09DB0C2F, + 0x00000C0F, 0x09DC0C0F, 0x09DD0C0F, 0x09DE0C0F, 0x09DF0C11, 0x3740102C, 0x09E00C2F, 0x00000C0F, 0x09E10C0F, + 0x09E20C10, 0x00374000, 0x180E09DB, 0x0C0F09DC, 0x0C0F09DD, 0x0C0F09DE, 0x0C0F09DF, 0x0C113740, 0x100E09E0, + 0x0C0F09E1, 0x0C0F09E2, 0x0C100E09, 0xC90C0F09, 0xCA0C100E, 0x09C60C10, 0x001402FF, 0xED0E09C8, 0x0C19FE69 +}; + +static UNK_TYPE D_80AE70B0[] = { 0x0E09D00C, 0x16100000 }; + +static UNK_TYPE D_80AE70B8[] = { + 0x28001228, 0x00152800, 0x28280055, 0x28008A28, 0x002D1900, 0x402C09E7, 0x0C12102C, 0x09CB2F00, 0x000C0F09, + 0xCC0C0F09, 0xCD0C0500, 0xA000C600, 0xC62C09D1, 0x2F00000C, 0x0F09D20C, 0x19FFE72C, 0x09D32F00, 0x000C0F09, + 0xD40C0F09, 0xD50C0500, 0x8F00AF00, 0xAF2C09D9, 0x2F00000C, 0x0F09DA0C, 0x102C09E8, 0x2F00000C, 0x0F09E90C, + 0x0F09EA0C, 0x00570400, 0x17120600, 0x0C000013, 0x000C0C11, 0x57040700, 0x000E09EB, 0x0C121610, 0x12060006, + 0x00001300, 0x060C07FF, 0xEC2C09EC, 0x2F00000C, 0x0F09ED0C, 0x0F09EE0C, 0x00570800, 0x17120600, 0x0C000013, + 0x000C0C11, 0x57080700, 0x000E09EF, 0x0C121610, 0x12060006, 0x00001300, 0x060C07FF, 0xEC120600, 0x04000013, + 0x00040C07, 0x00000E09, 0xCE0C1610, 0x12060002, 0x00001300, 0x020C0700, 0x000E09D8, 0x0C16100C, 0x0F09CF0C, + 0x1C050115, 0x09000010, 0x0E09D60C, 0x19FFF100, +}; + +static UNK_TYPE D_80AE71C4[] = { 0x00374000, 0x1C2C09DB, 0x0C2F0000, 0x0C0F09DC, 0x0C0F09DD, 0x0C0F09DE, 0x0C0F09DF, + 0x0C113740, 0x102C09E0, 0x0C2F0000, 0x0C0F09E1, 0x0C0F09E2, 0x0C100000 }; -#if 0 const ActorInit En_Shn_InitVars = { ACTOR_EN_SHN, ACTORCAT_NPC, @@ -25,47 +63,379 @@ const ActorInit En_Shn_InitVars = { (ActorFunc)EnShn_Draw, }; -#endif +static AnimationInfoS sAnimations[] = { + { &gBurlyGuyHandsOnTableAnim, 1.0f, 0, -1, 0, 0 }, + { &gBurlyGuyHandsOnTableAnim, 1.0f, 0, -1, 0, -4 }, + { &gSwampGuideChinScratchAnim, 1.0f, 0, -1, 0, 0 }, + { &gSwampGuideChinScratchAnim, 1.0f, 0, -1, 0, -4 }, +}; -extern UNK_TYPE D_0600B738; -extern UNK_TYPE D_0600E7D0; +static s32 D_80AE7258[] = { 0, 2, 3, 8, 10, 1 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6130.s") +void func_80AE6130(EnShn* this) { + this->skelAnime.playSpeed = this->playSpeed; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE615C.s") +s32 func_80AE615C(EnShn* this, s32 arg1) { + s32 phi_v0 = 0; + s32 phi_v1 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE61C0.s") + if (arg1 != this->unk_2E8) { + phi_v0 = 1; + } + if (phi_v0 != 0) { + this->unk_2E8 = arg1; + phi_v1 = SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, arg1); + this->playSpeed = this->skelAnime.playSpeed; + } + return phi_v1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE625C.s") +s32 EnShn_IsFacingPlayer(EnShn* this) { + s16 phi_v1; + f32 range; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE626C.s") + if (this->unk_2C8 == 0) { + phi_v1 = 0; + } else { + this->unk_2C8--; + phi_v1 = this->unk_2C8; + } + if (phi_v1 == 0) { + this->unk_2EC ^= 1; + this->unk_2C8 = Rand_S16Offset(0x1E, 0x1E); + } + if (this->unk_2EC != 0) { + range = 120.0f; + } else { + range = 80.0f; + } + return Actor_IsFacingAndNearPlayer(&this->actor, range, 0x238C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE63A8.s") +Player* EnShn_GetPlayer(EnShn* this, GlobalContext* globalCtx) { + return GET_PLAYER(globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6488.s") +void func_80AE626C(EnShn* this) { + s32 topPad; + Vec3f playerPos; + Vec3f shnPos; + s32 bottomPad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE65F4.s") + Math_Vec3f_Copy(&playerPos, &this->shnPlayerRef->actor.world.pos); + Math_Vec3f_Copy(&shnPos, &this->actor.world.pos); + Math_ApproachS(&this->unk_2BC, (Math_Vec3f_Yaw(&shnPos, &playerPos) - this->actor.shape.rot.y), 4, 0x2AA8); + this->unk_2BC = CLAMP(this->unk_2BC, -0x1FFE, 0x1FFE); + Math_Vec3f_Copy(&shnPos, &this->actor.focus.pos); + if (this->shnPlayerRef->actor.id == ACTOR_PLAYER) { + playerPos.y = this->shnPlayerRef->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&playerPos, &this->shnPlayerRef->actor.focus.pos); + } + Math_ApproachS(&this->unk_2BA, Math_Vec3f_Pitch(&shnPos, &playerPos), 4, 0x2AA8); + this->unk_2BA = CLAMP(this->unk_2BA, -0x1554, 0x1554); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6704.s") +void func_80AE63A8(EnShn* this, GlobalContext* globalCtx) { + s16 phi_v1; + s16 phi_v1_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6880.s") + this->shnPlayerRef = EnShn_GetPlayer(this, globalCtx); + if ((this->unk_1D8 & 8) && (this->shnPlayerRef != NULL)) { + if (this->unk_2CA == 0) { + phi_v1 = 0; + } else { + this->unk_2CA--; + phi_v1 = this->unk_2CA; + } + if (phi_v1 == 0) { + func_80AE626C(this); + this->unk_1D8 &= ~0x20; + this->unk_1D8 |= 0x10; + return; + } + } + if (this->unk_1D8 & 0x10) { + this->unk_1D8 &= ~0x10; + this->unk_2BA = 0; + this->unk_2BC = 0; + this->unk_2CA = 20; + return; + } + if (this->unk_2CA == 0) { + phi_v1_2 = 0; + } else { + this->unk_2CA--; + phi_v1_2 = this->unk_2CA; + } + if (phi_v1_2 == 0) { + this->unk_1D8 |= 0x20; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE68F0.s") +void func_80AE6488(EnShn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 tempMsgState; + f32 phi_f0_2; + f32 phi_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE69E8.s") + tempMsgState = Message_GetState(&globalCtx->msgCtx); + this->unk_2D4 += (this->unk_2D0 != 0.0f) ? 40.0f : -40.0f; + this->unk_2D4 = CLAMP(this->unk_2D4, 0.0f, 80.0f); + Matrix_Translate(this->unk_2D4, 0.0f, 0.0f, MTXMODE_APPLY); + if ((&this->actor == player->targetActor) && + ((globalCtx->msgCtx.currentTextId < 0xFF) || (globalCtx->msgCtx.currentTextId >= 0x201)) && + (tempMsgState == 3) && (this->msgState == 3)) { + if (globalCtx->state.frames % 2 == 0) { + if (this->unk_2D0 != 0.0f) { + this->unk_2D0 = 0.0f; + } else { + this->unk_2D0 = 1.0f; + } + } + } else { + this->unk_2D0 = 0.0f; + } + this->msgState = tempMsgState; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6A64.s") +s32 func_80AE65F4(EnShn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 temp = globalCtx->msgCtx.currentTextId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/EnShn_Init.s") + if (player->stateFlags1 & 0x40) { + if (this->unk_1DA != temp) { + if ((this->unk_1D8 & 0x80) || (this->unk_1D8 & 0x100)) { + this->unk_1D8 |= 8; + func_80AE615C(this, 1); + } + if (temp == 0x9C5) { + if (1) {} + this->unk_1D8 |= 8; + func_80AE615C(this, 1); + } + } + this->unk_1DA = temp; + this->unk_1D8 |= 0x40; + } else if (this->unk_1D8 & 0x40) { + if (!(gSaveContext.save.weekEventReg[23] & 8)) { + func_80AE615C(this, 3); + } + this->unk_1DA = 0; + this->unk_1D8 &= ~0x40; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/EnShn_Destroy.s") +s32 func_80AE6704(EnShn* thisx, GlobalContext* globalCtx) { + EnShn* this = THIS; + s32 ret = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/EnShn_Update.s") + switch (this->unk_2C6) { + case 0: + if (!CHECK_QUEST_ITEM(QUEST_UNK_19)) { + this->unk_2C6 = 6; + ret = 1; + } else { + this->unk_2C6++; + } + break; + case 1: + case 2: + case 3: + case 4: + case 5: + if (func_8013A4C4(D_80AE7258[this->unk_2C6])) { + this->unk_2C6 = 6; + ret = 1; + REMOVE_QUEST_ITEM(QUEST_UNK_19); + } else { + this->unk_2C6++; + } + break; + case 6: + gSaveContext.save.weekEventReg[90] &= (u8)~0x40; + func_800B7298(globalCtx, &this->actor, 7); + globalCtx->nextEntranceIndex = 0x8460; + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 7; + this->unk_2C6++; + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6CF0.s") +UNK_TYPE* func_80AE6880(EnShn* this, GlobalContext* globalCtx) { + if (this->unk_2BE != 0) { + return D_80AE70B0; + } + if (this->unk_1D8 & 0x80) { + this->unk_2D8 = func_80AE6704; + return D_80AE70B8; + } + if (this->unk_1D8 & 0x100) { + return D_80AE71C4; + } + this->unk_2D8 = func_80AE6704; + return D_80AE6F00; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6D40.s") +s32 func_80AE68F0(EnShn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/func_80AE6D90.s") + if (this->unk_1D8 & 7) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_1D8 &= ~0x180; + if (player->exchangeItemId == EXCH_ITEM_13) { + this->unk_1D8 |= 0x80; + this->unk_2E4 = player->exchangeItemId; + } else if (player->exchangeItemId != EXCH_ITEM_NONE) { + this->unk_1D8 |= 0x100; + this->unk_2E4 = player->exchangeItemId; + } + SubS_UpdateFlags(&this->unk_1D8, 0, 7); + this->unk_1DC = func_80AE6880(this, globalCtx); + this->unk_2C6 = 0; + if (gSaveContext.save.weekEventReg[23] & 8) { + this->unk_1D8 |= 8; + } + this->actionFunc = func_80AE6A64; + ret = 1; + } + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Shn/EnShn_Draw.s") +void func_80AE69E8(EnShn* this, GlobalContext* globalCtx) { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); + if ((gSaveContext.save.weekEventReg[23] & 8) && EnShn_IsFacingPlayer(this)) { + this->unk_1D8 |= 8; + } else { + this->unk_1D8 &= ~0x8; + } +} + +void func_80AE6A64(EnShn* this, GlobalContext* globalCtx) { + s16 yawBetweenActors; + Vec3f playerPos; + Vec3f shnPos; + + if (func_8010BF58(&this->actor, globalCtx, this->unk_1DC, this->unk_2D8, &this->unk_1E0)) { + SubS_UpdateFlags(&this->unk_1D8, 3, 7); + this->unk_1D8 &= ~8; + this->unk_1D8 |= 0x20; + this->unk_2CA = 20; + this->unk_1E0 = 0; + this->unk_2BE = 0; + this->actionFunc = func_80AE69E8; + } else if (this->shnPlayerRef != 0) { + Math_Vec3f_Copy(&playerPos, &this->shnPlayerRef->actor.world.pos); + Math_Vec3f_Copy(&shnPos, &this->actor.world.pos); + yawBetweenActors = Math_Vec3f_Yaw(&shnPos, &playerPos); + Math_ApproachS(&this->actor.shape.rot.y, yawBetweenActors, 4, 0x2AA8); + } +} + +void EnShn_Init(Actor* thisx, GlobalContext* globalCtx) { + EnShn* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gBurlyGuySkel, NULL, this->jointTable, this->morphTable, + BURLY_GUY_LIMB_MAX); + this->unk_2E8 = -1; + if (gSaveContext.save.weekEventReg[23] & 8) { + func_80AE615C(this, 0); + } else { + func_80AE615C(this, 2); + } + this->actor.targetMode = 6; + Actor_SetScale(&this->actor, 0.01f); + this->unk_2E0 = 0; + this->unk_2D8 = 0; + this->unk_1D8 = 0; + if (gSaveContext.save.entranceIndex != 0xA820) { + SubS_UpdateFlags(&this->unk_1D8, 3, 7); + this->unk_2BE = 0; + } else { + SubS_UpdateFlags(&this->unk_1D8, 4, 7); + this->unk_2BE = 1; + } + this->actionFunc = func_80AE69E8; +} + +void EnShn_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnShn_Update(Actor* thisx, GlobalContext* globalCtx) { + EnShn* this = THIS; + + func_80AE68F0(this, globalCtx); + this->actionFunc(this, globalCtx); + func_80AE65F4(this, globalCtx); + func_80AE6130(this); + func_80AE63A8(this, globalCtx); + this->unk_2E0 = 0; + func_8013C964(&this->actor, globalCtx, 120.0f, 40.0f, EXCH_ITEM_NONE, this->unk_1D8 & 7); +} + +s32 EnShn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnShn* this = THIS; + + if (limbIndex == BURLY_GUY_LIMB_HEAD) { + func_80AE6488(this, globalCtx); + *dList = gSwampGuideHeadDL; + } + return false; +} + +Vec3f D_80AE7270 = { 1200.0f, 0.0f, 0.0f }; +void EnShn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + if (limbIndex == BURLY_GUY_LIMB_HEAD) { + Matrix_MultVec3f(&D_80AE7270, &thisx->focus.pos); + Math_Vec3s_Copy(&thisx->focus.rot, &thisx->world.rot); + } +} + +void EnShn_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnShn* this = THIS; + s32 stepRot; + s32 overrideRot; + + if (!(this->unk_1D8 & 0x20)) { + if (this->unk_1D8 & 0x10) { + overrideRot = true; + } else { + overrideRot = false; + } + stepRot = true; + } else { + overrideRot = false; + stepRot = false; + } + + if (limbIndex == BURLY_GUY_LIMB_HEAD) { + SubS_UpdateLimb(this->unk_2BA + 0x4000, this->unk_2BC + this->actor.shape.rot.y + 0x4000, &this->unk_1E8, + &this->unk_1F4, stepRot, overrideRot); + Matrix_Pop(); + Matrix_Translate(this->unk_1E8.x, this->unk_1E8.y, this->unk_1E8.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_1F4.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_1F4.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_1F4.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnShn_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnShn* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnShn_OverrideLimbDraw, EnShn_PostLimbDraw, + EnShn_TransformLimbDraw, &this->actor); +} 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..22e10ca32 100644 --- a/src/overlays/actors/ovl_En_Shn/z_en_shn.h +++ b/src/overlays/actors/ovl_En_Shn/z_en_shn.h @@ -2,15 +2,44 @@ #define Z_EN_SHN_H #include "global.h" +#include "objects/object_shn/object_shn.h" struct EnShn; typedef void (*EnShnActionFunc)(struct EnShn*, GlobalContext*); typedef struct EnShn { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnShnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1A8]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnShnActionFunc actionFunc; + /* 0x148 */ SkelAnime skelAnime; + /* 0x18C */ UNK_TYPE1 pad_18C[0x4C]; + /* 0x1D8 */ u16 unk_1D8; + /* 0x1DA */ u16 unk_1DA; + /* 0x1DC */ UNK_TYPE* unk_1DC; + /* 0x1E0 */ s32 unk_1E0; + /* 0x1E4 */ Player* shnPlayerRef; + /* 0x1E8 */ Vec3f unk_1E8; + /* 0x1F4 */ Vec3s unk_1F4; + /* 0x1FA */ Vec3s jointTable[BURLY_GUY_LIMB_MAX]; + /* 0x25A */ Vec3s morphTable[BURLY_GUY_LIMB_MAX]; + /* 0x2BA */ s16 unk_2BA; + /* 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 playSpeed; + /* 0x2D0 */ f32 unk_2D0; + /* 0x2D4 */ f32 unk_2D4; + /* 0x2D8 */ s32 unk_2D8; + /* 0x2DC */ s32 msgState; + /* 0x2E0 */ s32 unk_2E0; + /* 0x2E4 */ s32 unk_2E4; + /* 0x2E8 */ s32 unk_2E8; + /* 0x2EC */ s32 unk_2EC; } EnShn; // size = 0x2F0 extern const ActorInit En_Shn_InitVars; diff --git a/src/overlays/actors/ovl_En_Si/z_en_si.c b/src/overlays/actors/ovl_En_Si/z_en_si.c index e47fbb11b..8933d5305 100644 --- a/src/overlays/actors/ovl_En_Si/z_en_si.c +++ b/src/overlays/actors/ovl_En_Si/z_en_si.c @@ -1,6 +1,12 @@ +/* + * File: z_en_si.c + * Overlay: ovl_En_Si + * Description: Golden Skulltula Token + */ + #include "z_en_si.h" -#define FLAGS 0x00000201 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_200) #define THIS ((EnSi*)thisx) 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_Skb/z_en_skb.c b/src/overlays/actors/ovl_En_Skb/z_en_skb.c index 3fd19ef91..6d3a118f4 100644 --- a/src/overlays/actors/ovl_En_Skb/z_en_skb.c +++ b/src/overlays/actors/ovl_En_Skb/z_en_skb.c @@ -7,8 +7,9 @@ #include "z_en_skb.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" #include "overlays/actors/ovl_En_Encount4/z_en_encount4.h" +#include "objects/object_skb/object_skb.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnSkb*)thisx) @@ -48,26 +49,20 @@ void func_809964A0(EnSkb* this, GlobalContext* globalCtx); s32 func_80996594(EnSkb* this, GlobalContext* globalCtx); void func_80996BEC(EnSkb* this, GlobalContext* globalCtx); -extern AnimationHeader D_060009E4; -extern AnimationHeader D_060015EC; -extern AnimationHeader D_06001D1C; -extern AnimationHeader D_06002190; -extern AnimationHeader D_0600270C; -extern AnimationHeader D_06002AC8; -extern AnimationHeader D_06003584; -extern SkeletonHeader D_06005EF8; -extern AnimationHeader D_060064E0; -extern AnimationHeader D_0600697C; -extern AnimationHeader D_06006D90; - -static ActorAnimationEntry sAnimations[] = { - { &D_060064E0, 1.0f, 0.0f, 0.0f, 0, -4.0 }, { &D_06003584, 1.0f, 0.0f, 0.0f, 2, -1.0f }, - { &D_06002190, 0.6f, 0.0f, 0.0f, 3, 4.0f }, { &D_06002AC8, 1.0f, 0.0f, 0.0f, 2, -4.0 }, - { &D_0600270C, 1.0f, 0.0f, 0.0f, 2, -4.0 }, { &D_0600697C, 1.0f, 0.0f, 0.0f, 0, -4.0 }, - { &D_06006D90, 1.0f, 0.0f, 0.0f, 0, -4.0 }, { &D_06001D1C, 1.0f, 0.0f, 0.0f, 0, -4.0 }, - { &D_06003584, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_06003584, 1.0f, 0.0f, 0.0f, 2, -16.0f }, - { &D_06002AC8, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &D_060015EC, 1.0f, 0.0f, 0.0f, 2, -4.0 }, - { &D_060009E4, 1.0f, 0.0f, 0.0f, 0, -4.0 }, +static AnimationInfo sAnimations[] = { + { &object_skb_Anim_0064E0, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0 }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &object_skb_Anim_002190, 0.6f, 0.0f, 0.0f, ANIMMODE_ONCE_INTERP, 4.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0 }, + { &object_skb_Anim_00270C, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0 }, + { &object_skb_Anim_00697C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0 }, + { &object_skb_Anim_006D90, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0 }, + { &object_skb_Anim_001D1C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0 }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -16.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &object_skb_Anim_0015EC, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -4.0 }, + { &object_skb_Anim_0009E4, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -4.0 }, }; static Vec3f D_80997468[] = { @@ -181,25 +176,29 @@ void func_809947B0(GlobalContext* globalCtx, EnSkb* this, Vec3f* inPos) { } void func_8099495C(EnSkb* this, GlobalContext* globalCtx) { - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005EF8, &D_06003584, this->jointTable, this->morphTable, 20); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_003584, this->jointTable, + this->morphTable, 20); this->unk_3DC = 0; func_80994E2C(this); } void func_809949C4(EnSkb* this, GlobalContext* globalCtx) { - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005EF8, &D_0600697C, this->jointTable, this->morphTable, 20); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_00697C, this->jointTable, + this->morphTable, 20); this->unk_3DC = 1; func_809952D8(this); } void func_80994A30(EnSkb* this, GlobalContext* globalCtx) { - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005EF8, &D_06006D90, this->jointTable, this->morphTable, 20); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_006D90, this->jointTable, + this->morphTable, 20); this->unk_3DC = 1; func_809953E8(this); } void func_80994A9C(EnSkb* this, GlobalContext* globalCtx) { - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005EF8, &D_06001D1C, this->jointTable, this->morphTable, 20); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_001D1C, this->jointTable, + this->morphTable, 20); this->unk_3DC = 1; func_809954F8(this); } @@ -215,7 +214,7 @@ void EnSkb_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); this->actor.colChkInfo.damageTable = &sDamageTable; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 0.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); this->unk_3E0 = 0; this->unk_3E2 = 0; Actor_SetScale(&this->actor, 0.01f); @@ -231,8 +230,9 @@ void EnSkb_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_3D6 = ENSKB_GET_F0(&this->actor); this->actor.floorHeight = this->actor.world.pos.y; - if ((globalCtx->sceneNum == SCENE_BOTI) && (gSaveContext.sceneSetupIndex == 1) && (globalCtx->csCtx.unk_12 == 0)) { - this->actor.flags |= 0x100000; + if ((globalCtx->sceneNum == SCENE_BOTI) && (gSaveContext.sceneSetupIndex == 1) && + (globalCtx->csCtx.currentCsIndex == 0)) { + this->actor.flags |= ACTOR_FLAG_100000; } switch (this->unk_3D6) { @@ -249,7 +249,7 @@ void EnSkb_Init(Actor* thisx, GlobalContext* globalCtx) { break; default: - this->actor.flags &= ~0x100000; + this->actor.flags &= ~ACTOR_FLAG_100000; this->actor.hintId = 0x55; func_8099495C(this, globalCtx); break; @@ -279,8 +279,8 @@ void EnSkb_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void func_80994DA8(EnSkb* this, GlobalContext* globalCtx) { - if (Actor_IsActorFacingLink(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f) && - (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAINS_HAT)) { + if (Actor_IsFacingPlayer(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f) && + (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN)) { func_80995C24(this); } else { func_80995A30(this); @@ -288,9 +288,9 @@ void func_80994DA8(EnSkb* this, GlobalContext* globalCtx) { } void func_80994E2C(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 1); - this->actor.flags &= ~1; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_APPEAR); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_APPEAR); this->unk_3D0 = 0; this->unk_3DE = 0; this->actionFunc = func_80994E94; @@ -301,7 +301,7 @@ void func_80994E94(EnSkb* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.yawTowardsPlayer; this->actor.shape.rot.y = this->actor.yawTowardsPlayer; } else { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } Math_ApproachZeroF(&this->actor.shape.yOffset, 1.0f, 800.0f); @@ -317,17 +317,17 @@ void func_80994E94(EnSkb* this, GlobalContext* globalCtx) { } void func_80994F7C(EnSkb* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->unk_3E2 = 1; if (this->unk_3E0 == 1) { - func_801518B0(globalCtx, 0x13F8, &this->actor); + Message_StartTextbox(globalCtx, 0x13F8, &this->actor); } else { - func_801518B0(globalCtx, 0x13F6, &this->actor); + Message_StartTextbox(globalCtx, 0x13F6, &this->actor); this->unk_3E0 = 1; } this->actionFunc = func_80995190; this->actor.speedXZ = 0.0f; - } else if (Actor_IsActorFacingLink(&this->actor, 0x2AAA) && !(this->collider.base.acFlags & AC_HIT)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x2AAA) && !(this->collider.base.acFlags & AC_HIT)) { func_800B8614(&this->actor, globalCtx, 100.0f); } } @@ -338,22 +338,22 @@ void func_8099504C(EnSkb* this) { } void func_80995068(EnSkb* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->unk_3E2 = 1; if (this->unk_3E0 == 1) { - func_801518B0(globalCtx, 0x13F8, &this->actor); + Message_StartTextbox(globalCtx, 0x13F8, &this->actor); if (this->unk_3DE == 2) { - func_800BDC5C(&this->skelAnime, sAnimations, 11); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 11); } } else { - func_801518B0(globalCtx, 0x13F6, &this->actor); + Message_StartTextbox(globalCtx, 0x13F6, &this->actor); this->unk_3E0 = 1; } this->actionFunc = func_80995190; this->actor.speedXZ = 0.0f; - } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAINS_HAT) { - this->actor.flags |= (0x4 | 0x1); - this->actor.flags &= ~(0x8 | 0x1); + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN) { + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); this->actor.hintId = 0x55; this->actor.colChkInfo.mass = MASS_HEAVY; func_80995A30(this); @@ -363,7 +363,7 @@ void func_80995068(EnSkb* this, GlobalContext* globalCtx) { } void func_80995190(EnSkb* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: case 1: case 2: @@ -372,16 +372,16 @@ void func_80995190(EnSkb* this, GlobalContext* globalCtx) { break; case 5: - if (func_80147624(globalCtx)) { - func_801518B0(globalCtx, 0x13F7, &this->actor); + if (Message_ShouldAdvance(globalCtx)) { + Message_StartTextbox(globalCtx, 0x13F7, &this->actor); if (this->unk_3DE == 2) { - func_800BDC5C(&this->skelAnime, sAnimations, 11); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 11); } } break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { this->actionFunc = func_80995244; } break; @@ -389,8 +389,8 @@ void func_80995190(EnSkb* this, GlobalContext* globalCtx) { } void func_80995244(EnSkb* this, GlobalContext* globalCtx) { - this->actor.flags &= ~(0x8 | 0x1); - this->actor.flags |= (0x4 | 0x1); + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_4); this->unk_3E2 = 0; switch (this->unk_3DE) { @@ -413,7 +413,7 @@ void func_80995244(EnSkb* this, GlobalContext* globalCtx) { } void func_809952D8(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 5); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->unk_3DE = 9; this->actionFunc = func_8099533C; @@ -423,11 +423,11 @@ void func_809952D8(EnSkb* this) { } void func_8099533C(EnSkb* this, GlobalContext* globalCtx) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) { - this->actor.flags &= ~(0x4 | 0x1); - this->actor.flags |= (0x8 | 0x1); + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); func_80994F7C(this, globalCtx); - } else if (Actor_IsActorFacingLink(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f)) { this->actor.hintId = 0x55; this->actor.colChkInfo.mass = MASS_HEAVY; func_8099571C(this); @@ -435,7 +435,7 @@ void func_8099533C(EnSkb* this, GlobalContext* globalCtx) { } void func_809953E8(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 6); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->unk_3DE = 10; this->actionFunc = func_8099544C; @@ -445,11 +445,11 @@ void func_809953E8(EnSkb* this) { } void func_8099544C(EnSkb* this, GlobalContext* globalCtx) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) { - this->actor.flags &= ~(0x4 | 0x1); - this->actor.flags |= (0x8 | 0x1); + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); func_80994F7C(this, globalCtx); - } else if (Actor_IsActorFacingLink(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f)) { this->actor.hintId = 0x55; this->actor.colChkInfo.mass = MASS_HEAVY; func_8099571C(this); @@ -457,7 +457,7 @@ void func_8099544C(EnSkb* this, GlobalContext* globalCtx) { } void func_809954F8(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 7); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 7); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->unk_3DE = 11; this->actionFunc = func_8099556C; @@ -482,11 +482,11 @@ void func_8099556C(EnSkb* this, GlobalContext* globalCtx) { } this->actor.shape.rot.x = Math_SinS(this->unk_3D4 * sp26) * 20000.0f; - if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) { - this->actor.flags &= ~(0x4 | 0x1); - this->actor.flags |= (0x8 | 0x1); + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); func_80994F7C(this, globalCtx); - } else if (Actor_IsActorFacingLink(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f) && + } else if (Actor_IsFacingPlayer(&this->actor, 0x2AAA) && (this->actor.xzDistToPlayer < 200.0f) && (this->skelAnime.curFrame > 24.0f) && (this->skelAnime.curFrame < 28.0f)) { this->actor.hintId = 0x55; this->actor.colChkInfo.mass = MASS_HEAVY; @@ -496,18 +496,18 @@ void func_8099556C(EnSkb* this, GlobalContext* globalCtx) { } void func_8099571C(EnSkb* this) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); this->unk_3DC = 0; this->actor.shape.shadowScale = 0.0f; if (this->unk_3DE == 9) { - func_800BDC5C(&this->skelAnime, sAnimations, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); this->actor.speedXZ = 2.4f; this->actor.gravity = -1.0f; this->actor.velocity.y = 3.0f; } else if (this->unk_3DE == 0xA) { - func_800BDC5C(&this->skelAnime, sAnimations, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); } else if (this->unk_3DE == 0xB) { - func_800BDC5C(&this->skelAnime, sAnimations, 9); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 9); this->actor.speedXZ = 3.2f; this->actor.gravity = -1.0f; this->actor.velocity.y = 2.0f; @@ -536,11 +536,12 @@ void func_80995818(EnSkb* this, GlobalContext* globalCtx) { } void func_809958F4(EnSkb* this) { - Animation_Change(&this->skelAnime, &D_06003584, -1.0f, Animation_GetLastFrame(&D_06003584), 0.0f, 2, -4.0f); + Animation_Change(&this->skelAnime, &object_skb_Anim_003584, -1.0f, Animation_GetLastFrame(&object_skb_Anim_003584), + 0.0f, 2, -4.0f); this->unk_3E4 = 0; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actor.speedXZ = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); this->unk_3DE = 1; this->actionFunc = func_8099599C; } @@ -560,7 +561,7 @@ void func_8099599C(EnSkb* this, GlobalContext* globalCtx) { } void func_80995A30(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); this->actor.speedXZ = 1.6f; this->unk_3DA = 0; this->unk_3DE = 2; @@ -568,12 +569,12 @@ void func_80995A30(EnSkb* this) { } void func_80995A8C(EnSkb* this, GlobalContext* globalCtx) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAINS_HAT) { - this->actor.flags &= ~(0x4 | 0x1); - this->actor.flags |= (0x8 | 0x1); + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_4); + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); this->actor.hintId = 0xFF; this->actor.colChkInfo.mass = MASS_HEAVY; - func_800BDC5C(&this->skelAnime, sAnimations, 12); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 12); func_8099504C(this); return; } @@ -585,18 +586,18 @@ void func_80995A8C(EnSkb* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + this->unk_3DA, 1, 0x2EE, 0); this->actor.world.rot.y = this->actor.shape.rot.y; if (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 15.0f)) { - Audio_PlayActorSound2(&this->actor, 0x3830); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_WALK); } if ((this->actor.xzDistToPlayer > 800.0f) || func_80996594(this, globalCtx)) { func_809958F4(this); - } else if (Actor_IsActorFacingLink(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x11C7) && (this->actor.xzDistToPlayer < 60.0f)) { func_80995C24(this); } } void func_80995C24(EnSkb* this) { - func_800BDC5C(&this->skelAnime, sAnimations, 2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); this->collider.base.atFlags &= ~AT_BOUNCED; this->actor.speedXZ = 0.0f; this->unk_3DE = 3; @@ -605,7 +606,7 @@ void func_80995C24(EnSkb* this) { void func_80995C84(EnSkb* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 3.0f) && (this->unk_3E4 == 0)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_ATTACK); this->unk_3E4 = 1; } else if (Animation_OnFrame(&this->skelAnime, 6.0f)) { this->unk_3E4 = 0; @@ -620,7 +621,7 @@ void func_80995C84(EnSkb* this, GlobalContext* globalCtx) { } void func_80995D3C(EnSkb* this) { - Animation_Change(&this->skelAnime, &D_06002190, -0.4f, this->skelAnime.curFrame - 1.0f, 0.0f, 3, 0.0f); + Animation_Change(&this->skelAnime, &object_skb_Anim_002190, -0.4f, this->skelAnime.curFrame - 1.0f, 0.0f, 3, 0.0f); this->collider.base.atFlags &= ~AT_BOUNCED; this->unk_3DE = 4; this->unk_3E4 = 0; @@ -637,7 +638,7 @@ void func_80995E08(EnSkb* this) { if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = 0.0f; } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); this->unk_3E4 = 0; this->unk_3DE = 5; this->actionFunc = func_80995E64; @@ -681,22 +682,22 @@ void func_80995E64(EnSkb* this, GlobalContext* globalCtx) { void func_80995F98(EnSkb* this) { if ((this->unk_3DE == 9) || (this->unk_3DE == 0xA)) { this->actor.world.rot.y = this->actor.yawTowardsPlayer; - func_800BDC5C(&this->skelAnime, sAnimations, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 8); this->actor.gravity = -1.0f; this->actor.speedXZ = 1.0f; } else if (this->unk_3DE == 0xB) { - func_800BDC5C(&this->skelAnime, sAnimations, 9); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 9); this->actor.speedXZ = 3.2f; this->actor.velocity.y = 2.0f; this->actor.gravity = -1.0f; } else { this->actor.world.rot.y = this->actor.yawTowardsPlayer; - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = -4.0f; } } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); this->unk_3DE = 6; this->actionFunc = func_809960AC; } @@ -727,14 +728,14 @@ void func_809960AC(EnSkb* this, GlobalContext* globalCtx) { } void func_809961E4(EnSkb* this, GlobalContext* globalCtx) { - func_800BDC5C(&this->skelAnime, sAnimations, 4); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); this->unk_3D8 |= 0x40; if (this->actor.bgCheckFlags & 1) { this->actor.speedXZ = -6.0f; } this->unk_3E4 = 0; - this->actor.flags &= ~1; - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + this->actor.flags &= ~ACTOR_FLAG_1; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); this->unk_3DE = 7; this->actionFunc = func_80996284; } @@ -748,24 +749,24 @@ void func_80996284(EnSkb* this, GlobalContext* globalCtx) { } void func_809962D4(EnSkb* this) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); this->actionFunc = func_8099630C; } void func_8099630C(EnSkb* this, GlobalContext* globalCtx) { - if (this->unk_3D2 == 0) { - this->unk_3D2 = 0; - this->unk_230 = 0.0f; - this->unk_22C = 0.0f; + if (this->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; if (this->actor.colChkInfo.health != 0) { - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); this->unk_3D8 |= 1; func_80995F98(this); } else { func_809961E4(this, globalCtx); } - } else if (this->unk_3D2 == 1) { + } else if (this->drawDmgEffTimer == 1) { func_80996BEC(this, globalCtx); } } @@ -775,13 +776,13 @@ void func_809963C4(EnSkb* this) { } void func_809963D8(EnSkb* this, GlobalContext* globalCtx) { - if (this->unk_3D2 == 0) { - this->unk_3D2 = 0; - this->unk_230 = 0.0f; - this->unk_22C = 0.0f; + if (this->drawDmgEffTimer == 0) { + this->drawDmgEffTimer = 0; + this->drawDmgEffScale = 0.0f; + this->drawDmgEffAlpha = 0.0f; if (this->actor.colChkInfo.health != 0) { - func_800BCB70(&this->actor, 0x4000, 255, 0, 8); - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); this->unk_3D8 |= 1; func_80995F98(this); } else { @@ -793,7 +794,7 @@ void func_809963D8(EnSkb* this, GlobalContext* globalCtx) { void func_80996474(EnSkb* this) { this->unk_3D0 = 0; this->actor.draw = NULL; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = func_809964A0; } @@ -806,14 +807,14 @@ void func_809964A0(EnSkb* this, GlobalContext* globalCtx) { void func_809964DC(EnSkb* this, GlobalContext* globalCtx) { if (this->unk_3D6 == 0) { if ((this->actionFunc != func_80994E94) && (this->actionFunc != func_80996284) && - (this->actionFunc != func_809964A0) && (gSaveContext.weekEventReg[85] & 0x40)) { + (this->actionFunc != func_809964A0) && (gSaveContext.save.weekEventReg[85] & 0x40)) { this->actor.colChkInfo.health = 0; func_809961E4(this, globalCtx); } } } -s32 func_80996544(EnSkbVec2f arg0, EnSkbVec2f arg1) { +s32 func_80996544(Vec2f arg0, Vec2f arg1) { s32 ret; if ((arg1.x * arg0.z) < (arg0.x * arg1.z)) { @@ -828,8 +829,8 @@ s32 func_80996544(EnSkbVec2f arg0, EnSkbVec2f arg1) { s32 func_80996594(EnSkb* this, GlobalContext* globalCtx) { s32 temp_s2; s32 j; - EnSkbVec2f sp60; - EnSkbVec2f sp58; + Vec2f sp60; + Vec2f sp58; s32 sp54 = true; f32 worldZ; s32 i = 0; @@ -872,7 +873,7 @@ void func_8099672C(EnSkb* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if ((this->unk_3DE != 6) && (this->unk_3DE != 7)) { - if ((this->actor.bgCheckFlags & 0x60) && (this->actor.yDistToWater >= 40.0f)) { + if ((this->actor.bgCheckFlags & 0x60) && (this->actor.depthInWater >= 40.0f)) { this->actor.colChkInfo.health = 0; this->unk_3E4 = 0; func_809961E4(this, globalCtx); @@ -884,10 +885,10 @@ void func_8099672C(EnSkb* this, GlobalContext* globalCtx) { if (this->actionFunc == func_8099630C) { switch (this->actor.colChkInfo.damageEffect) { default: - if (this->unk_3D2 >= 2) { + if (this->drawDmgEffTimer > 1) { func_80996BEC(this, globalCtx); } - this->unk_3D2 = 0; + this->drawDmgEffTimer = 0; break; case 1: @@ -908,51 +909,51 @@ void func_8099672C(EnSkb* this, GlobalContext* globalCtx) { switch (this->actor.colChkInfo.damageEffect) { case 11: - this->unk_3E6 = 30; - this->unk_3D2 = 40; - this->unk_22C = 1.0f; - this->unk_230 = 0.0f; - func_800BCB70(&this->actor, 0, 0x78, 0, 40); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffTimer = 40; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 40); func_80995E08(this); break; case 1: - func_800BCB70(&this->actor, 0, 0x78, 0, 40); + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 40); func_80995E08(this); break; case 2: - this->unk_3D2 = 0x50; - this->unk_3E6 = 0; - this->unk_22C = 1.0f; - this->unk_230 = 0.0f; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); + this->drawDmgEffTimer = 80; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); this->unk_3D8 |= 1; func_80995F98(this); break; case 3: if (this->actor.colChkInfo.health != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); - this->unk_3D2 = 0x50; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->drawDmgEffTimer = 80; } else { - this->unk_3D2 = 3; + this->drawDmgEffTimer = 3; } - this->unk_3E6 = 0xB; - this->unk_22C = 1.0f; - this->unk_230 = 0.5f; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); func_809962D4(this); break; case 4: - this->unk_3D2 = 0x28; - this->unk_3E6 = 0x14; - this->unk_22C = 1.0f; - this->unk_230 = 0.5f; - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); - func_800BDC5C(&this->skelAnime, sAnimations, 3); + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffScale = 0.5f; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALKID_DAMAGE); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); func_809963C4(this); break; @@ -967,8 +968,8 @@ void func_8099672C(EnSkb* this, GlobalContext* globalCtx) { } case 13: - func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 8); - func_800BDC5C(&this->skelAnime, sAnimations, 3); + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); func_80995F98(this); break; } @@ -1011,32 +1012,32 @@ void func_80996BEC(EnSkb* this, GlobalContext* globalCtx) { end = 14; } - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(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]); + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->limbPos[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_80997558, &D_80997550, &D_80997554, 30); + EffectSsEnIce_Spawn(globalCtx, &this->limbPos[i], 0.6f, &sp84, &D_80997558, &D_80997550, &D_80997554, 30); } } void func_80996D68(EnSkb* this, GlobalContext* globalCtx) { - if (this->unk_3D2 > 0) { - this->unk_3D2--; + if (this->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; } if (this->actionFunc != func_8099630C) { - if (this->unk_3D2 < 20) { + if (this->drawDmgEffTimer < 20) { if (this->actionFunc == func_809963D8) { - Math_SmoothStepToF(&this->unk_230, 0.0f, 0.5f, 0.03f, 0.0f); + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); } else { - Math_SmoothStepToF(&this->unk_230, 0.0f, 0.5f, 0.01f, 0.0f); + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.01f, 0.0f); } - this->unk_22C = this->unk_3D2 * 0.05f; + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; } else { - Math_SmoothStepToF(&this->unk_230, 0.5f, 0.1f, 0.02f, 0.0f); + Math_SmoothStepToF(&this->drawDmgEffScale, 0.5f, 0.1f, 0.02f, 0.0f); } } } @@ -1054,7 +1055,7 @@ void EnSkb_Update(Actor* thisx, GlobalContext* globalCtx) { func_8099672C(this, globalCtx); if ((this->actionFunc != func_8099630C) && (this->actionFunc != func_809963D8) && (this->actionFunc != func_80995E64)) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 60.0f, 0x1D); @@ -1086,7 +1087,7 @@ s32 EnSkb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } if (limbIndex == 10) { - Matrix_GetStateTranslation(&this->actor.focus.pos); + Matrix_MultZero(&this->actor.focus.pos); } return false; @@ -1099,23 +1100,23 @@ void EnSkb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve Collider_UpdateSpheres(limbIndex, &this->collider); if ((this->unk_3D8 & 1) && !(this->unk_3D8 & 2)) { if (limbIndex == 11) { - func_800BBCEC(&this->actor, globalCtx, 1, dList); + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); this->unk_3D8 |= 2; } } else if ((this->unk_3D8 & 0x40) && !(this->unk_3D8 & 0x80) && ((limbIndex != 11) || !(this->unk_3D8 & 1)) && (limbIndex != 12)) { - func_800BBCEC(&this->actor, globalCtx, 1, dList); + Actor_SpawnBodyParts(&this->actor, globalCtx, 1, dList); } - if (this->unk_3D2 != 0) { + if (this->drawDmgEffTimer != 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++; + Matrix_MultZero(&this->limbPos[this->limbCount]); + this->limbCount++; } else if ((limbIndex == 11) && !(this->unk_3D8 & 2)) { - Matrix_MultiplyVector3fByState(&D_80997564, &this->unk_234[this->unk_2DC]); - this->unk_2DC++; + Matrix_MultVec3f(&D_80997564, &this->limbPos[this->limbCount]); + this->limbCount++; } } } @@ -1123,13 +1124,13 @@ void EnSkb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve void EnSkb_Draw(Actor* thisx, GlobalContext* globalCtx) { EnSkb* this = THIS; - this->unk_2DC = 0; + this->limbCount = 0; func_8012C28C(globalCtx->state.gfxCtx); SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnSkb_OverrideLimbDraw, EnSkb_PostLimbDraw, &this->actor); - if (this->unk_3D2 > 0) { - func_800BE680(globalCtx, &this->actor, this->unk_234, this->unk_2DC, this->unk_230, 0.5f, this->unk_22C, - this->unk_3E6); + if (this->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, this->limbCount, this->drawDmgEffScale, 0.5f, + this->drawDmgEffAlpha, this->drawDmgEffType); } if (this->unk_3D8 & 0x40) { diff --git a/src/overlays/actors/ovl_En_Skb/z_en_skb.h b/src/overlays/actors/ovl_En_Skb/z_en_skb.h index 59186808d..fe5722e53 100644 --- a/src/overlays/actors/ovl_En_Skb/z_en_skb.h +++ b/src/overlays/actors/ovl_En_Skb/z_en_skb.h @@ -9,25 +9,20 @@ typedef void (*EnSkbActionFunc)(struct EnSkb*, GlobalContext*); #define ENSKB_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) -typedef struct { - f32 x; - f32 z; -} EnSkbVec2f; - typedef struct EnSkb { /* 0x0000 */ Actor actor; /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ ColliderJntSph collider; /* 0x01A8 */ ColliderJntSphElement colliderElements[2]; /* 0x0228 */ EnSkbActionFunc actionFunc; - /* 0x022C */ f32 unk_22C; - /* 0x0230 */ f32 unk_230; - /* 0x0234 */ Vec3f unk_234[14]; - /* 0x02DC */ s32 unk_2DC; + /* 0x022C */ f32 drawDmgEffAlpha; + /* 0x0230 */ f32 drawDmgEffScale; + /* 0x0234 */ Vec3f limbPos[14]; + /* 0x02DC */ s32 limbCount; /* 0x02E0 */ Vec3s jointTable[20]; /* 0x0358 */ Vec3s morphTable[20]; /* 0x03D0 */ s16 unk_3D0; - /* 0x03D2 */ s16 unk_3D2; + /* 0x03D2 */ s16 drawDmgEffTimer; /* 0x03D4 */ s16 unk_3D4; /* 0x03D6 */ s16 unk_3D6; /* 0x03D8 */ s16 unk_3D8; @@ -38,7 +33,7 @@ typedef struct EnSkb { /* 0x03E2 */ s16 unk_3E2; /* 0x03E4 */ u8 unk_3E4; /* 0x03E5 */ u8 unk_3E5; - /* 0x03E6 */ u8 unk_3E6; + /* 0x03E6 */ u8 drawDmgEffType; } EnSkb; // size = 0x3E8 extern const ActorInit En_Skb_InitVars; diff --git a/src/overlays/actors/ovl_En_Slime/z_en_slime.c b/src/overlays/actors/ovl_En_Slime/z_en_slime.c index ba48df119..539d458ad 100644 --- a/src/overlays/actors/ovl_En_Slime/z_en_slime.c +++ b/src/overlays/actors/ovl_En_Slime/z_en_slime.c @@ -1,6 +1,12 @@ +/* + * File: z_en_slime.c + * Overlay: ovl_En_Slime + * Description: Chuchu + */ + #include "z_en_slime.h" -#define FLAGS 0x00000215 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_200) #define THIS ((EnSlime*)thisx) 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_Snowman/z_en_snowman.c b/src/overlays/actors/ovl_En_Snowman/z_en_snowman.c index 5fcfe3645..ef0ad1b57 100644 --- a/src/overlays/actors/ovl_En_Snowman/z_en_snowman.c +++ b/src/overlays/actors/ovl_En_Snowman/z_en_snowman.c @@ -1,6 +1,12 @@ +/* + * File: z_en_snowman.c + * Overlay: ovl_En_Snowman + * Description: Eeno + */ + #include "z_en_snowman.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnSnowman*)thisx) @@ -9,21 +15,52 @@ void EnSnowman_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSnowman_Update(Actor* thisx, GlobalContext* globalCtx); void EnSnowman_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80B1746C(EnSnowman* this, GlobalContext* globalCtx); -void func_80B178B8(EnSnowman* this, GlobalContext* globalCtx); -void func_80B17A58(EnSnowman* this, GlobalContext* globalCtx); -void func_80B17D78(EnSnowman* this, GlobalContext* globalCtx); -void func_80B17EFC(EnSnowman* this, GlobalContext* globalCtx); -void func_80B17FE0(EnSnowman* this, GlobalContext* globalCtx); -void func_80B18124(EnSnowman* this, GlobalContext* globalCtx); -void func_80B183A4(EnSnowman* this, GlobalContext* globalCtx); -void func_80B1848C(EnSnowman* this, GlobalContext* globalCtx); -void func_80B1861C(EnSnowman* this, GlobalContext* globalCtx); -void func_80B189C4(EnSnowman* this, GlobalContext* globalCtx); -void func_80B18A04(EnSnowman* this, GlobalContext* globalCtx); -void func_80B18C7C(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupMoveSnowPile(EnSnowman* this); +void EnSnowman_MoveSnowPile(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupEmerge(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_Emerge(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupReadySnowball(EnSnowman* this); +void EnSnowman_ReadySnowball(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupThrowSnowball(EnSnowman* this); +void EnSnowman_ThrowSnowball(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupIdle(EnSnowman* this); +void EnSnowman_Idle(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupSubmerge(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_Submerge(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_Melt(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_Stun(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_Damaged(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupDead(EnSnowman* this); +void EnSnowman_Dead(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupSplitDoNothing(EnSnowman* this); +void EnSnowman_SplitDoNothing(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_SetupMarkForDeath(EnSnowman* this); +void EnSnowman_MarkForDeath(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_CreateSplitEeno(EnSnowman* this, Vec3f* basePos, s32 yRot); +void EnSnowman_SetupCombine(EnSnowman* this, GlobalContext* globalCtx, Vec3f* combinePos); +void EnSnowman_Combine(EnSnowman* this, GlobalContext* globalCtx); +void EnSnowman_UpdateSnowball(Actor* thisx, GlobalContext* globalCtx); +void EnSnowman_DrawSnowPile(Actor* thisx, GlobalContext* globalCtx); +void EnSnowman_DrawSnowball(Actor* thisx, GlobalContext* globalCtx); + +typedef enum { + // Indicates that this split Eeno is not currently trying to combine into a large Eeno. + /* 0 */ EN_SNOWMAN_COMBINE_STATE_NONE, + + // Indicates that this split Eeno is actively trying to combine into a large Eeno again. + // Eenos in this state can both absorb other Eenos and start being absorbed themselves. + /* 1 */ EN_SNOWMAN_COMBINE_STATE_ACTIVE, + + // Indicates that this Eeno cannot absorb other Eenos to combine into a large Eeno. + // It can still be absorbed by Eenos in the EN_SNOWMAN_COMBINE_STATE_ACTIVE state. + /* 2 */ EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION, + + // Indicates that either this Eeno is shrinking having been absorbed by another Eeno, or that + // this Eeno is a fully-combined large Eeno and is done trying to combine with other split + // Eenos. In both cases, this Eeno cannot be absorbed by any other Eeno. + /* 3 */ EN_SNOWMAN_COMBINE_STATE_BEING_ABSORBED_OR_DONE, +} EnSnowmanCombineState; -#if 0 const ActorInit En_Snowman_InitVars = { ACTOR_EN_SNOWMAN, ACTORCAT_ENEMY, @@ -36,155 +73,1125 @@ const ActorInit En_Snowman_InitVars = { (ActorFunc)EnSnowman_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B19A00 = { - { COLTYPE_HIT4, 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 sEenoCylinderInit = { + { + COLTYPE_HIT4, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0.0f, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 60, 80, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B19A2C = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sSnowballCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 60, 80, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B19A58 = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(1, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(1, 0xF), - /* Goron punch */ DMG_ENTRY(2, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0x0), - /* Fire arrow */ DMG_ENTRY(2, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x0), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x1), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 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, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), +typedef enum { + /* 0x0 */ EN_SNOWMAN_DMGEFF_NONE, + /* 0x1 */ EN_SNOWMAN_DMGEFF_STUN, + /* 0x2 */ EN_SNOWMAN_DMGEFF_MELT, + /* 0x4 */ EN_SNOWMAN_DMGEFF_LIGHT_ORB = 0x4, + /* 0x5 */ EN_SNOWMAN_DMGEFF_ELECTRIC_STUN, + /* 0xF */ EN_SNOWMAN_DMGEFF_HOOKSHOT = 0xF, // Damages small Eenos, pulls the player towards large Eenos +} EnTalkGibudDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(2, EN_SNOWMAN_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(2, EN_SNOWMAN_DMGEFF_MELT), + /* Ice arrow */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Light arrow */ DMG_ENTRY(2, EN_SNOWMAN_DMGEFF_LIGHT_ORB), + /* Goron spikes */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, EN_SNOWMAN_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_ELECTRIC_STUN), + /* Normal shield */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_SNOWMAN_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_SNOWMAN_DMGEFF_NONE), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80B19A78 = { 2, 60, 80, 150 }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 60, 80, 150 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B19AAC[] = { +static Color_RGBA8 sDustPrimColor = { 250, 250, 250, 255 }; + +static Color_RGBA8 sDustEnvColor = { 180, 180, 180, 255 }; + +static Vec3f sDustVelocity = { 0.0f, 1.5f, 0.0f }; + +static Gfx* sSnowballDLs[] = { + gEenoSmallSnowballDL, + gEenoLargeSnowballDL, + gEenoSmallSnowballDL, +}; + +static Gfx* sSnowballFragmentDLs[] = { + gEenoSnowballFragment1DL, + gEenoSnowballFragment2DL, + gEenoSnowballFragment3DL, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 20, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 3000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -1000, ICHAIN_STOP), }; -#endif +void EnSnowman_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSnowman* this = THIS; + s32 attackRange; -extern ColliderCylinderInit D_80B19A00; -extern ColliderCylinderInit D_80B19A2C; -extern DamageTable D_80B19A58; -extern CollisionCheckInfoInit D_80B19A78; -extern InitChainEntry D_80B19AAC[]; + Actor_ProcessInitChain(thisx, sInitChain); + attackRange = EN_SNOWMAN_GET_ATTACK_RANGE(thisx); + if (attackRange == 0xFF) { + attackRange = 0; + } -extern UNK_TYPE D_06000404; -extern UNK_TYPE D_06004628; -extern UNK_TYPE D_060046D8; -extern UNK_TYPE D_06004F14; -extern UNK_TYPE D_0600554C; -extern UNK_TYPE D_060058CC; + thisx->params &= 7; + if (EN_SNOWMAN_GET_TYPE(thisx) < EN_SNOWMAN_TYPE_SMALL_SNOWBALL) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gEenoSkel, &gEenoEmergeAnim, this->jointTable, + this->morphTable, EENO_LIMB_MAX); + SkelAnime_InitFlex(globalCtx, &this->snowPileSkelAnime, &gEenoSnowPileSkel, &gEenoSnowPileMoveAnim, + this->snowPileJointTable, this->snowPileMorphTable, EENO_SNOW_PILE_LIMB_MAX); + CollisionCheck_SetInfo(&thisx->colChkInfo, &sDamageTable, &sColChkInfoInit); + Collider_InitAndSetCylinder(globalCtx, &this->collider, thisx, &sEenoCylinderInit); + if (EN_SNOWMAN_GET_TYPE(thisx) == EN_SNOWMAN_TYPE_LARGE) { + thisx->flags |= ACTOR_FLAG_400; + Actor_SpawnAsChild(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_EN_SNOWMAN, thisx->world.pos.x, + thisx->world.pos.y, thisx->world.pos.z, 0, 0, 0, EN_SNOWMAN_TYPE_SPLIT); + thisx->parent = Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SNOWMAN, + thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 0, + 0, 0, EN_SNOWMAN_TYPE_SPLIT, -1, thisx->unk20, NULL); + if ((thisx->child == NULL) || (thisx->parent == NULL)) { + if (thisx->child != NULL) { + Actor_MarkForDeath(thisx->child); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/EnSnowman_Init.s") + if (thisx->parent != NULL) { + Actor_MarkForDeath(thisx->parent); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/EnSnowman_Destroy.s") + Actor_MarkForDeath(thisx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B16FC0.s") + // Makes each split Eeno the parent or child of other split Eenos + thisx->parent->child = thisx; + thisx->child->child = thisx->parent; + thisx->parent->parent = thisx->child; + if (1) {} + Actor_SetScale(thisx, 0.02f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17144.s") + this->eenoScale = thisx->scale.x * 100.0f; + this->attackRange = (240.0f * this->eenoScale) + (attackRange * 0.1f * 40.0f); + if (EN_SNOWMAN_GET_TYPE(thisx) == EN_SNOWMAN_TYPE_SPLIT) { + EnSnowman_SetupSplitDoNothing(this); + } else { + EnSnowman_SetupMoveSnowPile(this); + } + } else { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B173D0.s") + thisx->flags &= ~ACTOR_FLAG_1; + Collider_InitAndSetCylinder(globalCtx, &this->collider, thisx, &sSnowballCylinderInit); + thisx->world.rot.y = Actor_YawBetweenActors(thisx, &player->actor); + thisx->velocity.y = (Actor_XZDistanceBetweenActors(thisx, &player->actor) * 0.035f) + -5.0f; + thisx->velocity.y = CLAMP_MAX(thisx->velocity.y, 3.5f); + if (EN_SNOWMAN_GET_TYPE(thisx) == EN_SNOWMAN_TYPE_SMALL_SNOWBALL) { + thisx->speedXZ = 15.0f; + } else { + thisx->speedXZ = 22.5f; + thisx->velocity.y *= 1.5f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B1746C.s") + thisx->world.pos.x += thisx->speedXZ * Math_SinS(thisx->world.rot.y); + thisx->world.pos.y += thisx->velocity.y; + thisx->world.pos.z += thisx->speedXZ * Math_CosS(thisx->world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B177EC.s") + if (EN_SNOWMAN_GET_TYPE(thisx) == EN_SNOWMAN_TYPE_SMALL_SNOWBALL) { + this->collider.dim.radius = 8; + this->collider.dim.height = 12; + this->collider.dim.yShift = -6; + ActorShape_Init(&thisx->shape, 0.0f, ActorShadow_DrawCircle, 10.0f); + } else { + this->collider.dim.radius = 50; + this->collider.dim.height = 122; + this->collider.dim.yShift = -8; + this->collider.info.toucher.damage = 16; + thisx->world.pos.y -= 32.0f; + Actor_SetScale(thisx, 0.006f); + ActorShape_Init(&thisx->shape, 16000.0f / 3.0f, ActorShadow_DrawCircle, 170.0f); + thisx->gravity = -1.5f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B178B8.s") + thisx->flags |= ACTOR_FLAG_10; + thisx->update = EnSnowman_UpdateSnowball; + thisx->draw = EnSnowman_DrawSnowball; + this->work.timer = 5; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B179D0.s") +void EnSnowman_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSnowman* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17A58.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17CE8.s") +/** + * Spawns a circle of snow-colored dust around the actor. + */ +void EnSnowman_SpawnCircularDustEffect(EnSnowman* this, GlobalContext* globalCtx) { + s16 angle = 0; + Vec3f pos; + f32 offset; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17D78.s") + pos.y = (Rand_ZeroFloat(10.0f) * this->eenoScale) + this->actor.world.pos.y; + for (i = 0; i < 16; i++) { + offset = (Rand_ZeroFloat(10.0f) + 20.0f) * this->eenoScale; + pos.x = (Math_SinS(angle) * offset) + this->actor.world.pos.x; + pos.z = (Math_CosS(angle) * offset) + this->actor.world.pos.z; + func_800B0DE0(globalCtx, &pos, &sDustVelocity, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, + this->eenoScale * 400.0f, 10); + angle += 0x1000; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17EB4.s") +/** + * Spawns a batch of large snowball fragments and some snow-colored dust at snowballPos. + */ +void EnSnowman_SpawnBigSnowballFragmentEffects(EnSnowman* this, GlobalContext* globalCtx) { + static Vec3f sAccel = { 0.0f, -1.0f, 0.0f }; + s16 altitude; + s16 azimuth; + Vec3f pos; + Vec3f velocity; + f32 speed; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17EFC.s") + for (i = 0; i < 15; i++) { + altitude = Rand_S16Offset(0x1800, 0x2800); + azimuth = ((u32)Rand_Next() >> 0x10); + speed = Rand_ZeroFloat(3.0f) + 8.0f; + velocity.x = (speed * Math_CosS(altitude)) * Math_SinS(azimuth); + velocity.y = speed * Math_SinS(altitude); + velocity.z = (speed * Math_CosS(altitude)) * Math_CosS(azimuth); + pos.x = (Rand_ZeroFloat(10.0f) * velocity.x) + this->snowballPos.x; + pos.y = (Rand_ZeroFloat(8.0f) * velocity.y) + this->snowballPos.y; + pos.z = (Rand_ZeroFloat(10.0f) * velocity.z) + this->snowballPos.z; + EffectSsHahen_Spawn(globalCtx, &pos, &velocity, &sAccel, 0, + Rand_S16Offset((((i % 3) * 50) + 50), (((i % 3) * 25) + 25)), 452, 20, + sSnowballFragmentDLs[i % 3]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17F4C.s") + func_800B0DE0(globalCtx, &this->snowballPos, &gZeroVec3f, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, 1000, 150); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B17FE0.s") +void EnSnowman_SetupMoveSnowPile(EnSnowman* this) { + Animation_PlayLoop(&this->snowPileSkelAnime, &gEenoSnowPileMoveAnim); + this->actor.scale.y = this->actor.scale.x; + this->actor.speedXZ = 2.0f; + this->actor.draw = EnSnowman_DrawSnowPile; + this->work.timer = 40; + this->turningOnSteepSlope = false; + this->collider.dim.radius = this->eenoScale * 30.0f; + this->collider.dim.height = this->eenoScale * 10.0f; + this->actionFunc = EnSnowman_MoveSnowPile; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B180A4.s") +/** + * Moves around beneath the snow as a snow pile. + */ +void EnSnowman_MoveSnowPile(EnSnowman* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f combinePos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18124.s") + SkelAnime_Update(&this->snowPileSkelAnime); + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + func_800B9010(&this->actor, NA_SE_EN_YMAJIN_MOVE - SFX_FLAG); + } else { + func_800B9010(&this->actor, NA_SE_EN_YMAJIN_MINI_MOVE - SFX_FLAG); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18380.s") + if (this->work.timer > 0) { + this->work.timer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B183A4.s") + if (this->work.timer == 0) { + this->collider.base.acFlags |= AC_ON; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B183C4.s") + if ((this->combineTimer == 0) && (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_SPLIT)) { + // Sets the combinePos to be the average position of all living split Eenos. + if ((this->actor.parent->colChkInfo.health != 0) && (this->actor.child->colChkInfo.health != 0)) { + combinePos.x = + (this->actor.parent->world.pos.x + this->actor.child->world.pos.x + this->actor.world.pos.x) * + (1.0f / 3.0f); + combinePos.z = + (this->actor.parent->world.pos.z + this->actor.child->world.pos.z + this->actor.world.pos.z) * + (1.0f / 3.0f); + } else if (this->actor.parent->colChkInfo.health != 0) { + combinePos.x = (this->actor.parent->world.pos.x + this->actor.world.pos.x) / 2.0f; + combinePos.z = (this->actor.parent->world.pos.z + this->actor.world.pos.z) / 2.0f; + } else if (this->actor.child->colChkInfo.health != 0) { + combinePos.x = (this->actor.child->world.pos.x + this->actor.world.pos.x) / 2.0f; + combinePos.z = (this->actor.child->world.pos.z + this->actor.world.pos.z) / 2.0f; + } else { + combinePos.x = this->actor.world.pos.x; + combinePos.z = this->actor.world.pos.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B1848C.s") + combinePos.y = this->actor.world.pos.y; + EnSnowman_SetupCombine((EnSnowman*)this->actor.parent, globalCtx, &combinePos); + EnSnowman_SetupCombine((EnSnowman*)this->actor.child, globalCtx, &combinePos); + EnSnowman_SetupCombine(this, globalCtx, &combinePos); + } else if ((this->work.timer == 0) && (fabsf(this->actor.playerHeightRel) < 60.0f) && + (this->actor.xzDistToPlayer < this->attackRange) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && + !(player->stateFlags1 & 0x800000)) { + EnSnowman_SetupEmerge(this, globalCtx); + } else if (this->snowPileTargetRotY != this->actor.shape.rot.y) { + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->snowPileTargetRotY, 0x100)) { + this->turningOnSteepSlope = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18600.s") + this->actor.world.rot.y = this->actor.shape.rot.y; + } else if (this->actor.bgCheckFlags & 8) { + this->snowPileTargetRotY = this->actor.wallYaw; + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 200.0f) { + this->snowPileTargetRotY = Actor_YawToPoint(&this->actor, &this->actor.home.pos) + (Rand_Next() >> 0x14); + } else if (Rand_ZeroOne() < 0.02f) { + this->snowPileTargetRotY += (s16)((((u32)Rand_Next() >> 0x13) + 0x1000) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B1861C.s") +void EnSnowman_SetupEmerge(EnSnowman* this, GlobalContext* globalCtx) { + Animation_PlayOnce(&this->skelAnime, &gEenoEmergeAnim); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_SURFACE); + this->collider.dim.radius = this->eenoScale * 40.0f; + this->collider.dim.height = this->eenoScale * 25.0f; + this->actor.draw = EnSnowman_Draw; + this->actor.scale.y = this->actor.scale.x * 0.4f; + this->actor.speedXZ = 0.0f; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + EnSnowman_SpawnCircularDustEffect(this, globalCtx); + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = EnSnowman_Emerge; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18908.s") +/** + * Emerge from beneath the snow and face the player. + */ +void EnSnowman_Emerge(EnSnowman* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B189C4.s") + Math_StepToF(&this->actor.scale.y, this->actor.scale.x, + (this->actor.scale.x * 0.6f) / Animation_GetLastFrame(&gEenoEmergeAnim)); + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B189D4.s") + if (SkelAnime_Update(&this->skelAnime)) { + if (this->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE) { + EnSnowman_SetupSubmerge(this, globalCtx); + } else if (!(player->stateFlags1 & 0x800000) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + this->collider.base.acFlags |= AC_ON; + this->work.snowballsToThrowBeforeIdling = 3; + EnSnowman_SetupReadySnowball(this); + } else { + this->collider.base.acFlags |= AC_ON; + this->actor.scale.y = this->actor.scale.x; + EnSnowman_SetupIdle(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18A04.s") +void EnSnowman_SetupReadySnowball(EnSnowman* this) { + this->actor.scale.y = this->actor.scale.x; + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + this->fwork.frameToStartHoldingSnowball = 15.0f; + Animation_PlayOnce(&this->skelAnime, &gEenoLargeSnowballCreateAnim); + } else { + this->fwork.frameToStartHoldingSnowball = 6.0f; + Animation_PlayOnce(&this->skelAnime, &gEenoSmallSnowballCreateAnim); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18A28.s") + this->actionFunc = EnSnowman_ReadySnowball; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18B30.s") +/** + * Plays the animation of the Eeno creating a snowball and spawns some snow-colored dust + * near the snowball at the appropriate part of their animation. + */ +void EnSnowman_ReadySnowball(EnSnowman* this, GlobalContext* globalCtx) { + Vec3f pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18BB4.s") + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); + if ((EN_SNOWMAN_GET_TYPE(&this->actor) != EN_SNOWMAN_TYPE_LARGE) && this->isHoldingSnowball && + ((globalCtx->gameplayFrames % 2) != 0)) { + pos.x = randPlusMinusPoint5Scaled(10.0f) + this->snowballPos.x; + pos.y = randPlusMinusPoint5Scaled(10.0f) + this->snowballPos.y; + pos.z = randPlusMinusPoint5Scaled(10.0f) + this->snowballPos.z; + func_800B0DE0(globalCtx, &pos, &sDustVelocity, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, 500, 30); + } else if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + if ((this->skelAnime.curFrame > 3.0f) && (this->skelAnime.curFrame < 14.0f) && + ((globalCtx->gameplayFrames % 2) != 0)) { + pos.x = (this->actor.world.pos.x + (70.0f * Math_SinS(this->actor.shape.rot.y))) + + randPlusMinusPoint5Scaled(40.0f); + pos.y = this->actor.world.pos.y + randPlusMinusPoint5Scaled(20.0f); + pos.z = (this->actor.world.pos.z + (70.0f * Math_CosS(this->actor.shape.rot.y))) + + randPlusMinusPoint5Scaled(40.0f); + func_800B0DE0(globalCtx, &pos, &sDustVelocity, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, 1000, 150); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18C7C.s") + if (SkelAnime_Update(&this->skelAnime)) { + EnSnowman_SetupThrowSnowball(this); + } else if (Animation_OnFrame(&this->skelAnime, this->fwork.frameToStartHoldingSnowball)) { + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_HOLD_SNOW); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_MINI_HOLD); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B18F50.s") + this->isHoldingSnowball = true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/EnSnowman_Update.s") +void EnSnowman_SetupThrowSnowball(EnSnowman* this) { + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Animation_PlayOnce(&this->skelAnime, &gEenoLargeSnowballThrowAnim); + this->fwork.frameToThrowSnowball = 17.0f; + } else { + Animation_PlayOnce(&this->skelAnime, &gEenoSmallSnowballThrowAnim); + this->fwork.frameToThrowSnowball = 15.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B19474.s") + this->work.snowballsToThrowBeforeIdling--; + this->actionFunc = EnSnowman_ThrowSnowball; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B19718.s") +/** + * Throws the snowball the Eeno is holding at the player. If there are still more snowballs + * to throw before idling, this function is responsible for calling EnSnowman_SetupReadySnowball + * so it can eventually throw another one. Otherwise, this function will call EnSnowman_SetupIdle + * to transition the Eeno into an idle state. + */ +void EnSnowman_ThrowSnowball(EnSnowman* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/EnSnowman_Draw.s") + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xA, 0x1000); + if (SkelAnime_Update(&this->skelAnime)) { + if ((this->work.snowballsToThrowBeforeIdling != 0) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && + !(player->stateFlags1 & 0x800000)) { + EnSnowman_SetupReadySnowball(this); + } else { + this->work.snowballsToThrowBeforeIdling = 0; + EnSnowman_SetupIdle(this); + } + } else if (Animation_OnFrame(&this->skelAnime, this->fwork.frameToThrowSnowball)) { + this->isHoldingSnowball = false; + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + params = EN_SNOWMAN_TYPE_LARGE_SNOWBALL; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_THROW); + } else { + params = EN_SNOWMAN_TYPE_SMALL_SNOWBALL; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_MINI_THROW); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B19948.s") + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SNOWMAN, this->snowballPos.x, this->snowballPos.y, + this->snowballPos.z, 0, this->actor.yawTowardsPlayer, 0, params); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Snowman/func_80B19998.s") +void EnSnowman_SetupIdle(EnSnowman* this) { + Animation_PlayLoop(&this->skelAnime, &gEenoIdleAnim); + this->work.timer = 60; + this->actionFunc = EnSnowman_Idle; +} + +/** + * Simply makes the Eeno wait around for a bit before submerging back into the snow. + */ +void EnSnowman_Idle(EnSnowman* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (this->work.timer > 0) { + this->work.timer--; + } else { + EnSnowman_SetupSubmerge(this, globalCtx); + } +} + +void EnSnowman_SetupSubmerge(EnSnowman* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gEenoEmergeAnim, -1.0f, Animation_GetLastFrame(&gEenoEmergeAnim), 0.0f, + ANIMMODE_ONCE, -3.0f); + EnSnowman_SpawnCircularDustEffect(this, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_HIDE); + this->actionFunc = EnSnowman_Submerge; +} + +/** + * Submerge beneath the snow and become a snow pile. + */ +void EnSnowman_Submerge(EnSnowman* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.scale.y, this->actor.scale.x * 0.4f, + (this->actor.scale.x * 0.6f) / Animation_GetLastFrame(&gEenoEmergeAnim)); + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE) { + this->actor.draw = EnSnowman_DrawSnowPile; + this->collider.base.acFlags |= AC_ON; + + // Calling EnSnowman_SetupCombine while EnSnowman_Submerge is our actionFunc will result + // in the broken target scale bug described in EnSnowman_SetupCombine. + EnSnowman_SetupCombine(this, globalCtx, &this->combinePos); + } else { + EnSnowman_SetupMoveSnowPile(this); + } + } +} + +void EnSnowman_SetupMelt(EnSnowman* this) { + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 50); + this->collider.base.acFlags &= ~AC_ON; + this->work.timer = 50; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.scale.y = this->actor.scale.x; + this->actor.speedXZ = 0.0f; + this->actionFunc = EnSnowman_Melt; +} + +/** + * Spawns smoke and shrinks the Eeno down until the timer runs out, then kills the Eeno. + */ +void EnSnowman_Melt(EnSnowman* this, GlobalContext* globalCtx) { + Vec3f smokeVelocity; + Vec3f smokePos; + + this->work.timer--; + if ((this->work.timer >= 38) && (!(this->work.timer & 1))) { + smokeVelocity.y = (this->work.timer - 38) * (1.0f / 12.0f); + smokeVelocity.x = randPlusMinusPoint5Scaled(1.5f) * smokeVelocity.y; + smokeVelocity.z = randPlusMinusPoint5Scaled(1.5f) * smokeVelocity.y; + smokeVelocity.y += 0.8f; + smokePos.x = ((smokeVelocity.x >= 0.0f ? 1.0f : -1.0f) * Rand_ZeroFloat(20.0f) * this->eenoScale) + + this->actor.world.pos.x; + smokePos.z = ((smokeVelocity.z >= 0.0f ? 1.0f : -1.0f) * Rand_ZeroFloat(20.0f) * this->eenoScale) + + this->actor.world.pos.z; + smokePos.y = this->actor.world.pos.y + 3.0f; + EffectSsIceSmoke_Spawn(globalCtx, &smokePos, &smokeVelocity, &gZeroVec3f, this->eenoScale * 300.0f); + } + + if (this->work.timer == 0) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60); + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_SPLIT) { + EnSnowman_SetupSplitDoNothing(this); + } else if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Actor_MarkForDeath(this->actor.parent); + Actor_MarkForDeath(this->actor.child); + Actor_MarkForDeath(&this->actor); + } else { + Actor_MarkForDeath(&this->actor); + } + } + + this->actor.scale.y = this->work.timer * 0.0002f * this->eenoScale; + this->actor.scale.x = (this->eenoScale * (1.4f * 0.01f)) - (0.4f * this->actor.scale.y); + this->actor.scale.z = (this->eenoScale * (1.4f * 0.01f)) - (0.4f * this->actor.scale.y); +} + +void EnSnowman_SetupStun(EnSnowman* this) { + if (this->actionFunc != EnSnowman_Stun) { + this->prevActionFunc = this->actionFunc; + } + + this->actionFunc = EnSnowman_Stun; +} + +/** + * Simply makes the Eeno do absolutely nothing until the stun is over. + * Once the stun is over, this swaps the actionFunc back to what it was before the stun. + */ +void EnSnowman_Stun(EnSnowman* this, GlobalContext* globalCtx) { + if (this->actor.colorFilterTimer == 0) { + this->actionFunc = this->prevActionFunc; + } +} + +void EnSnowman_SetupDamaged(EnSnowman* this) { + Animation_PlayLoop(&this->skelAnime, &gEenoDamageAnim); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->collider.base.acFlags &= ~AC_ON; + this->work.timer = 20; + this->actor.draw = EnSnowman_Draw; + this->actor.scale.y = this->actor.scale.x; + this->actor.speedXZ = 10.0f; + func_800BE504(&this->actor, &this->collider); + + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_DAMAGE); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_MINI_DAMAGE); + } + + this->actionFunc = EnSnowman_Damaged; +} + +/** + * Plays the damage animation and spins the Eeno around. + * Once it's done spinning, it will spawn three small split-off Eenos if the Eeno is a large one. + * Otherwise, it will either submerge underground (if it has health remaining) or die. + */ +void EnSnowman_Damaged(EnSnowman* this, GlobalContext* globalCtx) { + s32 rotationalVelocityScale; + + SkelAnime_Update(&this->skelAnime); + rotationalVelocityScale = CLAMP_MAX(this->work.timer, 10); + this->actor.shape.rot.y += rotationalVelocityScale * 0x300; + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Math_StepToF(&this->actor.scale.y, 1.3f * 0.01f, 0.7f * 0.001f); + this->actor.scale.x = this->actor.scale.y; + this->actor.scale.z = this->actor.scale.y; + } + + if (this->work.timer > 0) { + this->work.timer--; + } else if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_YMAJIN_SPLIT); + EnSnowman_SpawnCircularDustEffect(this, globalCtx); + this->drawDmgEffAlpha = 0.0f; + EnSnowman_CreateSplitEeno((EnSnowman*)this->actor.parent, &this->actor.world.pos, + this->actor.shape.rot.y + 0x10000 / 3); + EnSnowman_CreateSplitEeno((EnSnowman*)this->actor.child, &this->actor.world.pos, + this->actor.shape.rot.y - 0x10000 / 3); + EnSnowman_CreateSplitEeno(this, &this->actor.world.pos, this->actor.shape.rot.y); + + // This is a hack to reuse EnSnowman_SpawnBigSnowballFragmentEffects, since it + // draws the fragments at snowballPos. + Math_Vec3f_Copy(&this->snowballPos, &this->actor.world.pos); + EnSnowman_SpawnBigSnowballFragmentEffects(this, globalCtx); + } else if (this->actor.colChkInfo.health != 0) { + this->collider.base.acFlags |= AC_ON; + EnSnowman_SetupSubmerge(this, globalCtx); + } else { + EnSnowman_SetupDead(this); + } +} + +void EnSnowman_SetupDead(EnSnowman* this) { + this->drawDmgEffAlpha = 0.0f; + this->actionFunc = EnSnowman_Dead; +} + +/** + * Spawns snow-colored dust and snowball fragments and kills the Eeno. + */ +void EnSnowman_Dead(EnSnowman* this, GlobalContext* globalCtx) { + static Vec3f sAccel = { 0.0f, -0.5f, 0.0f }; + Vec3f velocity; + Vec3f pos; + s16 altitude; + s16 azimuth; + f32 speed; + s32 i; + + for (i = 0; i < 15; i++) { + altitude = Rand_S16Offset(0x1000, 0x3000); + azimuth = ((u32)Rand_Next() >> 0x10); + speed = Rand_ZeroFloat(2.0f) + 4.0f; + velocity.x = (speed * Math_CosS(altitude)) * Math_SinS(azimuth); + velocity.y = speed * Math_SinS(altitude); + velocity.z = (speed * Math_CosS(altitude)) * Math_CosS(azimuth); + pos.x = (Rand_ZeroFloat(6.0f) * velocity.x) + this->actor.world.pos.x; + pos.y = (Rand_ZeroFloat(3.0f) * velocity.y) + this->actor.world.pos.y; + pos.z = (Rand_ZeroFloat(6.0f) * velocity.z) + this->actor.world.pos.z; + EffectSsHahen_Spawn(globalCtx, &pos, &velocity, &sAccel, 0, + Rand_S16Offset((((i % 3) * 20) + 20), (((i % 3) * 10) + 10)), 452, 20, + sSnowballFragmentDLs[i % 3]); + } + + func_800B0DE0(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, 500, + 30); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_YMAJIN_DEAD_BREAK); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60); + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_SPLIT) { + EnSnowman_SetupSplitDoNothing(this); + } else { + Actor_MarkForDeath(&this->actor); + } +} + +/** + * There are some cases where a split Eeno shouldn't do anything, but we don't want to mark it for death. + * This is because we want to keep it around until *all* split Eenos are killed. + * + * This function is called whenever we want to put a split Eeno into this "do nothing" state. It disables + * collision and turns off drawing for the Eeno. If all three split Eenos are killed, this function is + * responsible for marking all of them for death. + */ +void EnSnowman_SetupSplitDoNothing(EnSnowman* this) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.acFlags &= ~AC_HIT; + this->actor.draw = NULL; + if (this->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE) { + this->combineState = EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION; + } + + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_10); + if ((this->actor.parent != NULL) && (((EnSnowman*)this->actor.parent)->actionFunc == EnSnowman_SplitDoNothing)) { + if ((this->actor.child != NULL) && (((EnSnowman*)this->actor.child)->actionFunc == EnSnowman_SplitDoNothing)) { + EnSnowman_SetupMarkForDeath((EnSnowman*)this->actor.parent); + EnSnowman_SetupMarkForDeath((EnSnowman*)this->actor.child); + Actor_MarkForDeath(&this->actor); + } + } + + this->actionFunc = EnSnowman_SplitDoNothing; +} + +void EnSnowman_SplitDoNothing(EnSnowman* this, GlobalContext* globalCtx) { +} + +/** + * Turns off collision on the Eeno before calling Actor_MarkForDeath on it. + */ +void EnSnowman_SetupMarkForDeath(EnSnowman* this) { + this->collider.base.acFlags &= ~(AC_ON | AC_HIT); + this->collider.base.ocFlags1 &= ~(OC1_ON | OC1_HIT); + this->actionFunc = EnSnowman_MarkForDeath; +} + +/** + * Simply calls Actor_MarkForDeath on the Eeno. + */ +void EnSnowman_MarkForDeath(EnSnowman* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} + +/** + * Creates a small split Eeno with a certain Y-rotation and at a certain offset from basePos. + */ +void EnSnowman_CreateSplitEeno(EnSnowman* this, Vec3f* basePos, s32 yRot) { + this->actor.flags |= ACTOR_FLAG_1; + Actor_SetScale(&this->actor, 0.01f); + this->actor.shape.rot.y = yRot; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->combineState = EN_SNOWMAN_COMBINE_STATE_NONE; + this->actor.colChkInfo.health = 2; + this->eenoScale = 1.0f; + this->actor.world.pos.x = (Math_SinS(yRot) * 40.0f) + basePos->x; + this->actor.world.pos.y = basePos->y; + this->actor.world.pos.z = (Math_CosS(yRot) * 40.0f) + basePos->z; + this->combineTimer = 600; + this->actor.params = EN_SNOWMAN_TYPE_SPLIT; + this->actor.flags &= ~ACTOR_FLAG_400; + this->collider.base.ocFlags1 |= OC1_ON; + this->collider.base.acFlags &= ~AC_ON; + EnSnowman_SetupMoveSnowPile(this); +} + +/** + * Absorbs the smaller Eeno into the larger one. The smaller Eeno's target scale is set to + * zero so it gradually disappears, and its collision is disabled, while the larger Eeno's + * target scale increases. + */ +void EnSnowman_AbsorbEeno(EnSnowman* smallerEeno, EnSnowman* largerEeno) { + Actor_PlaySfxAtPos(&largerEeno->actor, NA_SE_EN_YMAJIN_UNITE); + largerEeno->fwork.targetScaleDuringCombine += 0.005f; + smallerEeno->combineState = EN_SNOWMAN_COMBINE_STATE_BEING_ABSORBED_OR_DONE; + smallerEeno->collider.base.ocFlags1 &= ~OC1_HIT; + smallerEeno->collider.base.acFlags &= ~AC_HIT; + smallerEeno->collider.base.ocFlags1 &= ~OC1_ON; + smallerEeno->collider.base.acFlags &= ~AC_ON; + smallerEeno->fwork.targetScaleDuringCombine = 0.0f; +} + +void EnSnowman_SetupCombine(EnSnowman* this, GlobalContext* globalCtx, Vec3f* combinePos) { + if (this->actor.colChkInfo.health == 0) { + this->combineState = EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION; + } else { + this->actor.flags |= ACTOR_FLAG_10; + Math_Vec3f_Copy(&this->combinePos, combinePos); + this->combineState = EN_SNOWMAN_COMBINE_STATE_ACTIVE; + + if (this->actionFunc != EnSnowman_Submerge) { + this->combineTimer = 400; + + //! @bug: Skipping this based the current actionFunc results in whatever is currently in fwork + //! being treated as the target scale when this function is called from EnSnowman_Submerge. + //! Since the only other things that get put in fwork are animation frame numbers, this results + //! in an enormous target scale, potentially creating the so-called "Mega Eeno" glitch. + //! It can still fail to become a Mega Eeno if it gets absorbed before it gets a chance to call + //! EnSnowman_Combine, though. + this->fwork.targetScaleDuringCombine = 0.01f; + } + + //! @bug: If an Eeno is in the middle of submerging, its draw function will still be EnSnowman_Draw. + //! It will call EnSnowman_SetupSubmerge again, resulting in the submerge animation playing twice. + if (this->actor.draw == EnSnowman_DrawSnowPile) { + this->actor.speedXZ = 3.0f; + this->actionFunc = EnSnowman_Combine; + } else { + this->isHoldingSnowball = false; + this->actor.speedXZ = 0.0f; + + // At this point, the combineState is EN_SNOWMAN_COMBINE_STATE_ACTIVE, and the actionFunc + // will be set to EnSnowman_Submerge. When the submerging animation is complete with this + // combineState, EnSnowman_Submerge will call EnSnowman_SetupCombine, causing the broken + // target scale bug described above. + EnSnowman_SetupSubmerge(this, globalCtx); + } + } +} + +/** + * Makes the small, split-off Eenos try to combine into a large Eeno by absorbing each other. + */ +void EnSnowman_Combine(EnSnowman* this, GlobalContext* globalCtx) { + EnSnowman* parent; + EnSnowman* child; + + SkelAnime_Update(&this->snowPileSkelAnime); + parent = (EnSnowman*)this->actor.parent; + child = (EnSnowman*)this->actor.child; + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->combinePos), 0x1000); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (this->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE) { + if (this->collider.base.ocFlags1 & OC1_HIT) { + if ((this->collider.base.oc == this->actor.parent) && + (parent->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE)) { + if (this->actor.scale.x < this->actor.parent->scale.x) { + EnSnowman_AbsorbEeno(this, parent); + } else { + EnSnowman_AbsorbEeno(parent, this); + } + } else if ((this->collider.base.oc == this->actor.child) && + (child->combineState == EN_SNOWMAN_COMBINE_STATE_ACTIVE)) { + if (this->actor.scale.x < this->actor.child->scale.x) { + EnSnowman_AbsorbEeno(this, child); + } else { + EnSnowman_AbsorbEeno(child, this); + } + } + } + + if (parent->combineState == EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION) { + EnSnowman_AbsorbEeno(parent, this); + } + + if (child->combineState == EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION) { + EnSnowman_AbsorbEeno(child, this); + } + } + + if ((this->combineTimer == 0) && (parent->fwork.targetScaleDuringCombine > 0.0f) && + (child->fwork.targetScaleDuringCombine > 0.0f) && (this->fwork.targetScaleDuringCombine < 0.011f) && + (this->combineState != EN_SNOWMAN_COMBINE_STATE_BEING_ABSORBED_OR_DONE)) { + this->combineState = EN_SNOWMAN_COMBINE_STATE_NO_ABSORPTION; + this->fwork.targetScaleDuringCombine = 0.0f; + } + + if (Actor_XZDistanceToPoint(&this->actor, &this->combinePos) < 20.0f) { + this->actor.speedXZ = 0.0f; + } + + if (Math_StepToF(&this->actor.scale.x, this->fwork.targetScaleDuringCombine, 0.0005f)) { + if (this->fwork.targetScaleDuringCombine < 0.01f) { + EnSnowman_SetupSplitDoNothing(this); + } else if (this->fwork.targetScaleDuringCombine > 0.018f) { + Actor_SetScale(&this->actor, 0.02f); + this->actor.params = EN_SNOWMAN_TYPE_LARGE; + this->actor.flags |= ACTOR_FLAG_400; + this->collider.base.ocFlags1 |= OC1_ON; + this->combineState = EN_SNOWMAN_COMBINE_STATE_BEING_ABSORBED_OR_DONE; + this->eenoScale = 2.0f; + EnSnowman_SetupMoveSnowPile(this); + } + } + + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; +} + +void EnSnowman_UpdateDamage(EnSnowman* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.info); + if ((this->actor.colChkInfo.damageEffect != EN_SNOWMAN_DMGEFF_HOOKSHOT) || + (EN_SNOWMAN_GET_TYPE(&this->actor) != EN_SNOWMAN_TYPE_LARGE)) { + if (this->actor.colChkInfo.damageEffect == EN_SNOWMAN_DMGEFF_MELT) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_ApplyDamage(&this->actor); + EnSnowman_SetupMelt(this); + } else { + if ((this->actionFunc == EnSnowman_MoveSnowPile) || (this->actionFunc == EnSnowman_Combine)) { + EnSnowman_SetupEmerge(this, globalCtx); + } else if (this->actor.colChkInfo.damageEffect == EN_SNOWMAN_DMGEFF_STUN) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + EnSnowman_SetupStun(this); + } else if (this->actor.colChkInfo.damageEffect == EN_SNOWMAN_DMGEFF_ELECTRIC_STUN) { + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + this->drawDmgEffScale = 0.55f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + EnSnowman_SetupStun(this); + } else if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) { + if (this->isHoldingSnowball == true) { + this->isHoldingSnowball = false; + EnSnowman_SpawnBigSnowballFragmentEffects(this, globalCtx); + } + + EnSnowman_SetupDamaged(this); + } else { + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + EnSnowman_SetupDamaged(this); + } + } + + if (this->actor.colChkInfo.damageEffect == EN_SNOWMAN_DMGEFF_LIGHT_ORB) { + this->drawDmgEffScale = 0.55f; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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); + } + } + } +} + +void EnSnowman_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSnowman* this = THIS; + f32 wallCheckRadius; + + if (this->actionFunc != EnSnowman_SplitDoNothing) { + DECR(this->combineTimer); + + EnSnowman_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + + if (this->actionFunc != EnSnowman_MarkForDeath) { + Actor_MoveWithGravity(&this->actor); + if ((EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_LARGE) && + (this->actionFunc == EnSnowman_ReadySnowball)) { + wallCheckRadius = (this->skelAnime.curFrame * (1.0f / 60.0f)) + 1.0f; + wallCheckRadius = CLAMP_MAX(wallCheckRadius, 1.3f); + wallCheckRadius *= this->collider.dim.radius; + } else { + wallCheckRadius = this->collider.dim.radius; + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, wallCheckRadius, 0.0f, 0x1D); + if ((this->actor.floorPoly != NULL) && ((this->actor.floorPoly->normal.y * SHT_MINV) < 0.7f)) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + if (!this->turningOnSteepSlope) { + this->snowPileTargetRotY = Math_FAtan2F(this->actor.floorPoly->normal.z * SHT_MINV, + this->actor.floorPoly->normal.x * SHT_MINV); + this->turningOnSteepSlope = true; + } + } else { + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &this->actor.shape.rot); + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + 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->actor.draw == EnSnowman_Draw) { + Actor_SetFocus(&this->actor, this->actor.scale.y * 1800.0f); + } else { + Actor_SetFocus(&this->actor, this->actor.scale.y * 720.0f); + } + + if (this->drawDmgEffAlpha > 0.0f) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } + } + } +} + +void EnSnowman_UpdateSnowball(Actor* thisx, GlobalContext* globalCtx) { + EnSnowman* this = THIS; + s16 scale; + s32 i; + + if (this->work.timer > 0) { + this->work.timer--; + } else { + this->collider.base.ocFlags1 |= OC1_ON; + } + + if ((this->actor.bgCheckFlags & 8) || (this->actor.bgCheckFlags & 1) || (this->actor.bgCheckFlags & 0x10) || + (this->collider.base.atFlags & AT_HIT) || (this->collider.base.acFlags & AC_HIT) || + (this->collider.base.ocFlags1 & OC1_HIT)) { + if (EN_SNOWMAN_GET_TYPE(&this->actor) == EN_SNOWMAN_TYPE_SMALL_SNOWBALL) { + scale = 10; + for (i = 0; i < 3; i++) { + EffectSsHahen_SpawnBurst(globalCtx, &thisx->world.pos, 5.0f, 0, scale, scale >> 1, 3, 452, 20, + sSnowballFragmentDLs[i]); + scale *= 2; + } + + func_800B0DE0(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, &sDustPrimColor, &sDustEnvColor, + 500, 30); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_SMALL_SNOWBALL_BROKEN); + } else { + // EnSnowman_SpawnBigSnowballFragmentEffects only fworks with snowballPos, so we need + // to copy the snowball actor's current position into snowballPos to make this fwork. + Math_Vec3f_Copy(&this->snowballPos, &this->actor.world.pos); + EnSnowman_SpawnBigSnowballFragmentEffects(this, globalCtx); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_SNOWBALL_BROKEN); + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_IT_REFLECTION_WOOD); + Actor_MarkForDeath(&this->actor); + } else { + this->actor.shape.rot.x += 0xF00; + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, this->collider.dim.radius * 0.6f, + this->collider.dim.height - this->collider.dim.yShift, 0x1F); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +/** + * This maps a given limb based on its limbIndex to its appropriate index + * in the bodyPartsPos array. An index of -1 indicates that the limb is + * not part of the bodyPartsPos array. + */ +static s8 sLimbIndexToBodyPartsPosIndex[] = { + -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, +}; + +/** + * The last five elements of the bodyPartsPos array are duplicates of the body + * bottom limb, each offset by a certain certain amount. + */ +static Vec3f sBodyBottomBodyPartOffsets[] = { + { 2000.0f, 3000.0f, 0.0f }, { 2000.0f, -2000.0f, 0.0f }, { 3000.0f, 0.0f, 0.0f }, + { 1000.0f, 0.0f, 3000.0f }, { 1000.0f, 0.0f, -3000.0f }, +}; + +void EnSnowman_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnSnowman* this = THIS; + Gfx* gfx; + s32 i; + + if (sLimbIndexToBodyPartsPosIndex[limbIndex] != -1) { + if (sLimbIndexToBodyPartsPosIndex[limbIndex] == 4) { + for (i = 0; i < 5; i++) { + Matrix_MultVec3f(&sBodyBottomBodyPartOffsets[i], &this->bodyPartsPos[i + 4]); + } + } else { + Matrix_MultZero(&this->bodyPartsPos[sLimbIndexToBodyPartsPosIndex[limbIndex]]); + } + } + + if ((limbIndex == EENO_LIMB_RIGHT_HAND) && (this->isHoldingSnowball == true)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + if (EN_SNOWMAN_GET_TYPE(thisx) != EN_SNOWMAN_TYPE_LARGE) { + Matrix_Translate(800.0f, -600.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_Translate(300.0f, -2300.0f, -1900.0f, MTXMODE_APPLY); + Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); + } + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], sSnowballDLs[EN_SNOWMAN_GET_TYPE(&this->actor)]); + + POLY_OPA_DISP = &gfx[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Matrix_MultZero(&this->snowballPos); + } +} + +void EnSnowman_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSnowman* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, EnSnowman_PostLimbDraw, &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->bodyPartsPos, ARRAY_COUNT(this->bodyPartsPos), + this->drawDmgEffScale * this->eenoScale, 0.0f, this->drawDmgEffAlpha, this->drawDmgEffType); +} + +void EnSnowman_DrawSnowPile(Actor* thisx, GlobalContext* globalCtx) { + EnSnowman* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->snowPileSkelAnime.skeleton, this->snowPileSkelAnime.jointTable, + this->snowPileSkelAnime.dListCount, NULL, NULL, &this->actor); +} + +void EnSnowman_DrawSnowball(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, sSnowballDLs[EN_SNOWMAN_GET_TYPE(thisx) - EN_SNOWMAN_TYPE_SMALL_SNOWBALL]); +} diff --git a/src/overlays/actors/ovl_En_Snowman/z_en_snowman.h b/src/overlays/actors/ovl_En_Snowman/z_en_snowman.h index ceb711202..07d7f98c3 100644 --- a/src/overlays/actors/ovl_En_Snowman/z_en_snowman.h +++ b/src/overlays/actors/ovl_En_Snowman/z_en_snowman.h @@ -2,16 +2,56 @@ #define Z_EN_SNOWMAN_H #include "global.h" +#include "objects/object_snowman/object_snowman.h" + +#define EN_SNOWMAN_GET_TYPE(thisx) ((thisx)->params) +#define EN_SNOWMAN_GET_ATTACK_RANGE(thisx) (((thisx)->params >> 8) & 0xFF) + +typedef enum { + /* 0 */ EN_SNOWMAN_TYPE_SMALL, + /* 1 */ EN_SNOWMAN_TYPE_LARGE, + /* 2 */ EN_SNOWMAN_TYPE_SPLIT, + /* 3 */ EN_SNOWMAN_TYPE_SMALL_SNOWBALL, + /* 4 */ EN_SNOWMAN_TYPE_LARGE_SNOWBALL, +} EnSnowmanType; struct EnSnowman; typedef void (*EnSnowmanActionFunc)(struct EnSnowman*, GlobalContext*); typedef struct EnSnowman { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x13C]; - /* 0x0280 */ EnSnowmanActionFunc actionFunc; - /* 0x0284 */ char unk_284[0xF4]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ SkelAnime snowPileSkelAnime; + /* 0x1CC */ Vec3s jointTable[EENO_LIMB_MAX]; + /* 0x214 */ Vec3s morphTable[EENO_LIMB_MAX]; + /* 0x25C */ Vec3s snowPileJointTable[EENO_SNOW_PILE_LIMB_MAX]; + /* 0x26E */ Vec3s snowPileMorphTable[EENO_SNOW_PILE_LIMB_MAX]; + /* 0x280 */ EnSnowmanActionFunc actionFunc; + /* 0x284 */ EnSnowmanActionFunc prevActionFunc; + /* 0x288 */ u8 isHoldingSnowball; + /* 0x289 */ u8 combineState; + /* 0x28A */ u8 turningOnSteepSlope; + /* 0x28B */ u8 drawDmgEffType; + /* 0x28C */ union { + s16 timer; + s16 snowballsToThrowBeforeIdling; + } work; + /* 0x28E */ s16 snowPileTargetRotY; + /* 0x290 */ s16 combineTimer; + /* 0x294 */ f32 eenoScale; + /* 0x298 */ union { + f32 frameToStartHoldingSnowball; + f32 frameToThrowSnowball; + f32 targetScaleDuringCombine; + } fwork; + /* 0x29C */ f32 attackRange; + /* 0x2A0 */ f32 drawDmgEffAlpha; + /* 0x2A4 */ f32 drawDmgEffScale; + /* 0x2A8 */ Vec3f combinePos; + /* 0x2B4 */ Vec3f snowballPos; + /* 0x2C0 */ Vec3f bodyPartsPos[9]; + /* 0x32C */ ColliderCylinder collider; } EnSnowman; // size = 0x378 extern const ActorInit En_Snowman_InitVars; diff --git a/src/overlays/actors/ovl_En_Snowwd/z_en_snowwd.c b/src/overlays/actors/ovl_En_Snowwd/z_en_snowwd.c index ef7899fd4..03038d058 100644 --- a/src/overlays/actors/ovl_En_Snowwd/z_en_snowwd.c +++ b/src/overlays/actors/ovl_En_Snowwd/z_en_snowwd.c @@ -1,3 +1,9 @@ +/* + * File: z_en_snowwd.c + * Overlay: ovl_En_Snowwd + * Description: Snow-Covered Tree + */ + #include "z_en_snowwd.h" #define FLAGS 0x00000000 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 8f79570b6..08c1a8aaf 100644 --- a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c +++ b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c @@ -5,8 +5,14 @@ */ #include "z_en_sob1.h" +#include "objects/object_rs/object_rs.h" +#include "objects/object_zo/object_zo.h" +#include "objects/object_mastergolon/object_mastergolon.h" +#include "objects/object_masterzoora/object_masterzoora.h" +#include "objects/object_oF1d_map/object_oF1d_map.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnSob1*)thisx) @@ -14,13 +20,14 @@ void EnSob1_Init(Actor* thisx, GlobalContext* globalCtx); void EnSob1_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSob1_Update(Actor* thisx, GlobalContext* globalCtx); -void EnSob1_DrawZoraShopkeeper(Actor* thisx, GlobalContext* globalCtx); -void EnSob1_DrawGoronShopkeeper(Actor* thisx, GlobalContext* globalCtx); -void EnSob1_DrawBombShopkeeper(Actor* thisx, GlobalContext* globalCtx); +void EnSob1_ZoraShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnSob1_GoronShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnSob1_BombShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx); + +void EnSob1_ZoraShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx); +void EnSob1_GoronShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx); +void EnSob1_BombShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx); -void EnSob1_InitZoraShopkeeper(EnSob1* this, GlobalContext* globalCtx); -void EnSob1_InitGoronShopkeeper(EnSob1* this, GlobalContext* globalCtx); -void EnSob1_InitBombShopkeeper(EnSob1* this, GlobalContext* globalCtx); void EnSob1_InitShop(EnSob1* this, GlobalContext* globalCtx); void EnSob1_Idle(EnSob1* this, GlobalContext* globalCtx); void EnSob1_Walk(EnSob1* this, GlobalContext* globalCtx); @@ -46,32 +53,12 @@ void EnSob1_Blink(EnSob1* this); s32 EnSob1_TakeItemOffShelf(EnSob1* this); s32 EnSob1_ReturnItemToShelf(EnSob1* this); -s16 EnSob1_GetXZAngleAndDistanceSqToPoint(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq); +s16 EnSob1_GetDistSqAndOrient(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq); -extern UNK_TYPE D_0401F740; -extern UNK_TYPE D_0401F8C0; -extern UNK_TYPE D_0401F7C0; -extern AnimationHeader D_06009120; -extern AnimationHeader D_06008268; -extern FlexSkeletonHeader D_0600D208; -extern AnimationHeader D_0600078C; -extern AnimationHeader D_060087BC; -extern FlexSkeletonHeader D_06011AC8; -extern AnimationHeader D_060000FC; -extern FlexSkeletonHeader D_06009220; -extern Gfx D_06000970[]; -extern UNK_TYPE D_06005458; -extern TexturePtr D_060050A0; -extern TexturePtr D_060058A0; -extern TexturePtr D_060060A0; -extern TexturePtr D_06010438; -extern TexturePtr D_06010C38; -extern TexturePtr D_06011038; - -static ActorAnimationEntryS sAnimationsBombShopkeeper[] = { - { &D_06009120, 2.0f, 0, -1, 0, 20 }, - { &D_06008268, 1.0f, 0, -1, 2, 0 }, - { &D_060087BC, 1.0f, 0, -1, 0, 0 }, +static AnimationInfoS sAnimationsBombShopkeeper[] = { + { &object_rs_Anim_009120, 2.0f, 0, -1, ANIMMODE_LOOP, 20 }, + { &object_rs_Anim_008268, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_rs_Anim_0087BC, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, }; const ActorInit En_Sob1_InitVars = { @@ -153,10 +140,10 @@ static InitChainEntry sInitChain[] = { }; static EnSob1ActionFunc sInitFuncs[] = { - EnSob1_InitZoraShopkeeper, - EnSob1_InitGoronShopkeeper, - EnSob1_InitBombShopkeeper, - EnSob1_InitGoronShopkeeper, + EnSob1_ZoraShopkeeper_Init, + EnSob1_GoronShopkeeper_Init, + EnSob1_BombShopkeeper_Init, + EnSob1_GoronShopkeeper_Init, }; static Vec3f sPosOffset[] = { @@ -166,17 +153,17 @@ static Vec3f sPosOffset[] = { { 0.0f, -4.0f, 0.0f }, }; -void EnSob1_ChangeAnim(SkelAnime* skelAnime, ActorAnimationEntryS* animations, s32 idx) { +void EnSob1_ChangeAnim(SkelAnime* skelAnime, AnimationInfoS* animations, s32 idx) { f32 frameCount; animations += idx; if (animations->frameCount < 0) { - frameCount = Animation_GetLastFrame(animations->animationSeg); + frameCount = Animation_GetLastFrame(animations->animation); } else { frameCount = animations->frameCount; } - Animation_Change(skelAnime, animations->animationSeg, animations->playbackSpeed, animations->frame, frameCount, - animations->mode, animations->transitionRate); + Animation_Change(skelAnime, animations->animation, animations->playSpeed, animations->startFrame, frameCount, + animations->mode, animations->morphFrames); } void EnSob1_SetupAction(EnSob1* this, EnSob1ActionFunc action) { @@ -198,9 +185,9 @@ u16 EnSob1_GetTalkOption(EnSob1* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (this->shopType == BOMB_SHOP) { - if (gSaveContext.day == 1 && gSaveContext.time >= CLOCK_TIME(6, 00)) { + if (gSaveContext.save.day == 1 && gSaveContext.save.time >= CLOCK_TIME(6, 00)) { return 0x648; - } else if (gSaveContext.weekEventReg[0x21] & 8) { + } else if (gSaveContext.save.weekEventReg[33] & 8) { return 0x649; } else { return 0x64A; @@ -236,33 +223,33 @@ u16 EnSob1_GetWelcome(EnSob1* this, GlobalContext* globalCtx) { if (this->shopType == BOMB_SHOP) { switch (Player_GetMask(globalCtx)) { case PLAYER_MASK_NONE: - case PLAYER_MASK_BUNNY_HOOD: - case PLAYER_MASK_POSTMANS_HAT: + case PLAYER_MASK_BUNNY: + case PLAYER_MASK_POSTMAN: return 0x644; - case PLAYER_MASK_GORON_MASK: - case PLAYER_MASK_ZORA_MASK: - case PLAYER_MASK_DEKU_MASK: + case PLAYER_MASK_GORON: + case PLAYER_MASK_ZORA: + case PLAYER_MASK_DEKU: return 0x64B; - case PLAYER_MASK_MASK_OF_TRUTH: - case PLAYER_MASK_ALL_NIGHT_MASK: - case PLAYER_MASK_KEATON_MASK: - case PLAYER_MASK_ROMANIS_MASK: - case PLAYER_MASK_GREAT_FAIRYS_MASK: - case PLAYER_MASK_DON_GEROS_MASK: - case PLAYER_MASK_KAMAROS_MASK: - case PLAYER_MASK_BREMEN_MASK: - case PLAYER_MASK_MASK_OF_SCENTS: + case PLAYER_MASK_TRUTH: + case PLAYER_MASK_ALL_NIGHT: + case PLAYER_MASK_KEATON: + case PLAYER_MASK_ROMANI: + case PLAYER_MASK_GREAT_FAIRY: + case PLAYER_MASK_DON_GERO: + case PLAYER_MASK_KAMARO: + case PLAYER_MASK_BREMEN: + case PLAYER_MASK_SCENTS: return 0x685; - case PLAYER_MASK_GAROS_MASK: - case PLAYER_MASK_CIRCUS_LEADERS_MASK: - case PLAYER_MASK_GIBDO_MASK: - case PLAYER_MASK_CAPTAINS_HAT: + case PLAYER_MASK_GARO: + case PLAYER_MASK_CIRCUS_LEADER: + case PLAYER_MASK_GIBDO: + case PLAYER_MASK_CAPTAIN: return 0x686; - case PLAYER_MASK_COUPLES_MASK: + case PLAYER_MASK_COUPLE: return 0x687; - case PLAYER_MASK_STONE_MASK: + case PLAYER_MASK_STONE: return 0x688; - case PLAYER_MASK_BLAST_MASK: + case PLAYER_MASK_BLAST: return 0x689; case PLAYER_MASK_KAFEIS_MASK: return 0x68A; @@ -270,58 +257,58 @@ u16 EnSob1_GetWelcome(EnSob1* this, GlobalContext* globalCtx) { } else if (this->shopType == ZORA_SHOP) { switch (player->transformation) { case PLAYER_FORM_HUMAN: - if (gSaveContext.weekEventReg[0x39] & 0x10) { + if (gSaveContext.save.weekEventReg[57] & 0x10) { return 0x12CF; } - gSaveContext.weekEventReg[0x39] |= 0x10; + gSaveContext.save.weekEventReg[57] |= 0x10; return 0x12CE; case PLAYER_FORM_DEKU: - if (gSaveContext.weekEventReg[0x39] & 0x20) { + if (gSaveContext.save.weekEventReg[57] & 0x20) { return 0x12D1; } - gSaveContext.weekEventReg[0x39] |= 0x20; + gSaveContext.save.weekEventReg[57] |= 0x20; return 0x12D0; case PLAYER_FORM_GORON: - if (gSaveContext.weekEventReg[0x39] & 0x40) { + if (gSaveContext.save.weekEventReg[57] & 0x40) { return 0x12D3; } - gSaveContext.weekEventReg[0x39] |= 0x40; + gSaveContext.save.weekEventReg[57] |= 0x40; return 0x12D2; case PLAYER_FORM_ZORA: - if (gSaveContext.weekEventReg[0x39] & 0x80) { + if (gSaveContext.save.weekEventReg[57] & 0x80) { return 0x12D5; } - gSaveContext.weekEventReg[0x39] |= 0x80; + gSaveContext.save.weekEventReg[57] |= 0x80; return 0x12D4; default: return 0x12CE; } } else if (this->shopType == GORON_SHOP) { if (player->transformation != PLAYER_FORM_GORON) { - if (gSaveContext.weekEventReg[0x3A] & 4) { + if (gSaveContext.save.weekEventReg[58] & 4) { return 0xBB9; } - gSaveContext.weekEventReg[0x3A] |= 4; + gSaveContext.save.weekEventReg[58] |= 4; return 0xBB8; } else { - if (gSaveContext.weekEventReg[0x3A] & 8) { + if (gSaveContext.save.weekEventReg[58] & 8) { return 0xBBB; } - gSaveContext.weekEventReg[0x3A] |= 8; + gSaveContext.save.weekEventReg[58] |= 8; return 0xBBA; } } else if (this->shopType == GORON_SHOP_SPRING) { if (player->transformation != PLAYER_FORM_GORON) { - if (gSaveContext.weekEventReg[0x3A] & 0x10) { + if (gSaveContext.save.weekEventReg[58] & 0x10) { return 0xBBD; } - gSaveContext.weekEventReg[0x3A] |= 0x10; + gSaveContext.save.weekEventReg[58] |= 0x10; return 0xBBC; } else { - if (gSaveContext.weekEventReg[0x3A] & 0x20) { + if (gSaveContext.save.weekEventReg[58] & 0x20) { return 0xBBF; } - gSaveContext.weekEventReg[0x3A] |= 0x20; + gSaveContext.save.weekEventReg[58] |= 0x20; return 0xBBE; } } @@ -330,11 +317,11 @@ u16 EnSob1_GetWelcome(EnSob1* this, GlobalContext* globalCtx) { u16 EnSob1_GetGoodbye(EnSob1* this) { if (this->shopType == BOMB_SHOP) { - if (gSaveContext.day == 1) { + if (gSaveContext.save.day == 1) { return 0x64C; - } else if (gSaveContext.day == 2) { + } else if (gSaveContext.save.day == 2) { return 0x64D; - } else if (!gSaveContext.isNight) { + } else if (!gSaveContext.save.isNight) { return 0x64E; } else { return 0x64F; @@ -343,12 +330,12 @@ u16 EnSob1_GetGoodbye(EnSob1* this) { return 0x64C; } -void EnSob1_EndInteractionBombShop(EnSob1* this, GlobalContext* globalCtx) { +void EnSob1_BombShopkeeper_EndInteraction(EnSob1* this, GlobalContext* globalCtx) { this->drawCursor = 0; this->stickLeftPrompt.isEnabled = false; this->stickRightPrompt.isEnabled = false; this->goodbyeTextId = EnSob1_GetGoodbye(this); - func_801518B0(globalCtx, this->goodbyeTextId, &this->actor); + Message_StartTextbox(globalCtx, this->goodbyeTextId, &this->actor); EnSob1_SetupAction(this, EnSob1_EndingInteraction); } @@ -396,7 +383,7 @@ void EnSob1_Init(Actor* thisx, GlobalContext* globalCtx) { this->shopType = ZORA_SHOP; break; case GORON_SHOP: - if (gSaveContext.weekEventReg[0x21] & 0x80) { + if (gSaveContext.save.weekEventReg[33] & 0x80) { this->shopType = GORON_SHOP_SPRING; } else { this->shopType = GORON_SHOP; @@ -436,7 +423,7 @@ void EnSob1_UpdateCursorPos(GlobalContext* globalCtx, EnSob1* this) { f32 xOffset = 0.0f; f32 yOffset = 17.0f; - func_800B8898(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); + Actor_GetScreenPos(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); this->cursorPos.x = x + xOffset; this->cursorPos.y = y + yOffset; this->cursorPos.z = 1.2f; @@ -449,8 +436,8 @@ void EnSob1_EndInteraction(GlobalContext* globalCtx, EnSob1* this) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENSOB1_CUTSCENESTATE_STOPPED; } - func_800B84D0(&this->actor, globalCtx); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; Interface_ChangeAlpha(50); this->drawCursor = 0; @@ -465,7 +452,7 @@ void EnSob1_EndInteraction(GlobalContext* globalCtx, EnSob1* this) { s32 EnSob1_TestEndInteraction(EnSob1* this, GlobalContext* globalCtx, Input* input) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { if (this->shopType == BOMB_SHOP) { - EnSob1_EndInteractionBombShop(this, globalCtx); + EnSob1_BombShopkeeper_EndInteraction(this, globalCtx); } else { EnSob1_EndInteraction(globalCtx, this); } @@ -516,7 +503,7 @@ void EnSob1_SetupLookToShopkeeperFromShelf(GlobalContext* globalCtx, EnSob1* thi } void EnSob1_EndingInteraction(EnSob1* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { EnSob1_EndInteraction(globalCtx, this); } } @@ -534,7 +521,7 @@ void EnSob1_Idle(EnSob1* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); this->headRotTarget = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->cutsceneState == ENSOB1_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -545,7 +532,7 @@ void EnSob1_Idle(EnSob1* this, GlobalContext* globalCtx) { } player->stateFlags2 |= 0x20000000; this->welcomeTextId = EnSob1_GetWelcome(this, globalCtx); - func_801518B0(globalCtx, this->welcomeTextId, &this->actor); + Message_StartTextbox(globalCtx, this->welcomeTextId, &this->actor); if (ENSOB1_GET_SHOPTYPE(&this->actor) == BOMB_SHOP) { this->headRotTarget = -0x2000; } @@ -610,7 +597,7 @@ u8 EnSob1_SetCursorIndexFromNeutral(EnSob1* this, u8 shelfOffset) { } void EnSob1_Hello(EnSob1* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (this->cutsceneState == ENSOB1_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { @@ -620,8 +607,8 @@ void EnSob1_Hello(EnSob1* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if ((talkState == 5) && (func_80147624(globalCtx)) && - (!EnSob1_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx)))) { + if ((talkState == 5) && Message_ShouldAdvance(globalCtx) && + !EnSob1_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx))) { if (this->welcomeTextId == 0x68A) { // Welcome text when wearing Kafei's mask EnSob1_EndInteraction(globalCtx, this); } else { @@ -639,7 +626,7 @@ s32 EnSob1_FacingShopkeeperDialogResult(EnSob1* this, GlobalContext* globalCtx) case 1: func_8019F230(); if (this->shopType == BOMB_SHOP) { - EnSob1_EndInteractionBombShop(this, globalCtx); + EnSob1_BombShopkeeper_EndInteraction(this, globalCtx); } else { EnSob1_EndInteraction(globalCtx, this); } @@ -650,7 +637,7 @@ s32 EnSob1_FacingShopkeeperDialogResult(EnSob1* this, GlobalContext* globalCtx) void EnSob1_FaceShopkeeper(EnSob1* this, GlobalContext* globalCtx) { s32 pad[2]; - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); u8 cursorIdx; if (this->cutsceneState == ENSOB1_CUTSCENESTATE_WAITING) { @@ -672,7 +659,7 @@ void EnSob1_FaceShopkeeper(EnSob1* this, GlobalContext* globalCtx) { if (talkState == 4) { func_8011552C(globalCtx, 6); if (!EnSob1_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx))) { - if (!func_80147624(globalCtx) || !EnSob1_FacingShopkeeperDialogResult(this, globalCtx)) { + if (!Message_ShouldAdvance(globalCtx) || !EnSob1_FacingShopkeeperDialogResult(this, globalCtx)) { if (this->stickAccumX > 0) { cursorIdx = EnSob1_SetCursorIndexFromNeutral(this, 2); if (cursorIdx != CURSOR_INVALID) { @@ -690,7 +677,7 @@ void EnSob1_FaceShopkeeper(EnSob1* this, GlobalContext* globalCtx) { } void EnSob1_TalkingToShopkeeper(EnSob1* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { EnSob1_StartShopping(globalCtx, this); } } @@ -722,12 +709,11 @@ void EnSob1_EndWalk(EnSob1* this, GlobalContext* globalCtx) { s32 pad; f32 distSq; s16 curFrame = this->skelAnime.curFrame / this->skelAnime.playSpeed; - s16 animLastFrame = Animation_GetLastFrame(&D_06009120) / (s16)this->skelAnime.playSpeed; + s16 animLastFrame = Animation_GetLastFrame(&object_rs_Anim_009120) / (s16)this->skelAnime.playSpeed; - Math_SmoothStepToS( - &this->actor.world.rot.y, - EnSob1_GetXZAngleAndDistanceSqToPoint(this->path, this->pathPointsIdx - 1, &this->actor.world.pos, &distSq), 4, - 1000, 1); + Math_SmoothStepToS(&this->actor.world.rot.y, + EnSob1_GetDistSqAndOrient(this->path, this->pathPointsIdx - 1, &this->actor.world.pos, &distSq), + 4, 1000, 1); this->actor.shape.rot.y = this->actor.world.rot.y; Math_ApproachF(&this->actor.speedXZ, 0.5f, 0.2f, 1.0f); if (distSq < 12.0f) { @@ -737,13 +723,13 @@ void EnSob1_EndWalk(EnSob1* this, GlobalContext* globalCtx) { EnSob1_SetupAction(this, EnSob1_SetupIdle); } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void EnSob1_SetupIdle(EnSob1* this, GlobalContext* globalCtx) { s16 curFrame = this->skelAnime.curFrame; - if (Animation_GetLastFrame(&D_06008268) == curFrame) { + if (Animation_GetLastFrame(&object_rs_Anim_008268) == curFrame) { EnSob1_ChangeAnim(&this->skelAnime, sAnimationsBombShopkeeper, 2); EnSob1_SetupAction(this, EnSob1_Idle); } @@ -763,10 +749,9 @@ void EnSob1_Walk(EnSob1* this, GlobalContext* globalCtx) { } } if (this->path != NULL) { - Math_SmoothStepToS( - &this->actor.world.rot.y, - EnSob1_GetXZAngleAndDistanceSqToPoint(this->path, this->pathPointsIdx, &this->actor.world.pos, &distSq), 4, - 1000, 1); + Math_SmoothStepToS(&this->actor.world.rot.y, + EnSob1_GetDistSqAndOrient(this->path, this->pathPointsIdx, &this->actor.world.pos, &distSq), + 4, 1000, 1); this->actor.shape.rot.y = this->actor.world.rot.y; this->actor.speedXZ = 2.0f; if (distSq < SQ(5.0f)) { @@ -777,7 +762,7 @@ void EnSob1_Walk(EnSob1* this, GlobalContext* globalCtx) { } } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); EnSob1_Walking(this, globalCtx); } @@ -792,7 +777,7 @@ void EnSob1_Walking(EnSob1* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->cutsceneState == ENSOB1_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -803,7 +788,7 @@ void EnSob1_Walking(EnSob1* this, GlobalContext* globalCtx) { } player->stateFlags2 |= 0x20000000; this->welcomeTextId = EnSob1_GetWelcome(this, globalCtx); - func_801518B0(globalCtx, this->welcomeTextId, &this->actor); + Message_StartTextbox(globalCtx, this->welcomeTextId, &this->actor); this->wasTalkedToWhileWalking = true; } else { if ((player->actor.world.pos.x >= this->posXZRange.xMin && @@ -832,10 +817,10 @@ void EnSob1_ItemPurchased(EnSob1* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80151938(globalCtx, 0x647); } else { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } @@ -910,7 +895,7 @@ s32 EnSob1_HasPlayerSelectedItem(GlobalContext* globalCtx, EnSob1* this, Input* } void EnSob1_BrowseShelf(EnSob1* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; u8 prevCursorIdx = this->cursorIdx; u8 cursorIdx; @@ -940,8 +925,8 @@ void EnSob1_BrowseShelf(EnSob1* this, GlobalContext* globalCtx) { void EnSob1_SetupBuyItemWithFanfare(GlobalContext* globalCtx, EnSob1* this) { Player* player = GET_PLAYER(globalCtx); - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->stateFlags2 &= ~0x20000000; Interface_ChangeAlpha(50); @@ -1029,11 +1014,11 @@ void EnSob1_HandleCanBuyItem(GlobalContext* globalCtx, EnSob1* this) { } void EnSob1_SelectItem(EnSob1* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (EnSob1_TakeItemOffShelf(this) && talkState == 4) { func_8011552C(globalCtx, 6); - if (!EnSob1_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && func_80147624(globalCtx)) { + if (!EnSob1_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: EnSob1_HandleCanBuyItem(globalCtx, this); @@ -1049,8 +1034,8 @@ void EnSob1_SelectItem(EnSob1* this, GlobalContext* globalCtx) { } void EnSob1_CannotBuy(EnSob1* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5) { - if (func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5) { + if (Message_ShouldAdvance(globalCtx)) { this->actionFunc = this->tmpActionFunc; func_80151938(globalCtx, this->items[this->cursorIdx]->actor.textId); } @@ -1060,7 +1045,7 @@ void EnSob1_CannotBuy(EnSob1* this, GlobalContext* globalCtx) { void EnSob1_CanBuy(EnSob1* this, GlobalContext* globalCtx) { EnGirlA* item; - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->shopItemSelectedTween = 0.0f; EnSob1_ResetItemPosition(this); item = this->items[this->cursorIdx]; @@ -1075,13 +1060,13 @@ void EnSob1_BuyItemWithFanfare(EnSob1* this, GlobalContext* globalCtx) { this->actor.parent = NULL; EnSob1_SetupAction(this, EnSob1_SetupItemPurchased); } else { - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); } } void EnSob1_SetupItemPurchased(EnSob1* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; EnSob1_SetupAction(this, EnSob1_ItemPurchased); if (this->cutsceneState == ENSOB1_CUTSCENESTATE_STOPPED) { @@ -1091,7 +1076,7 @@ void EnSob1_SetupItemPurchased(EnSob1* this, GlobalContext* globalCtx) { this->cutscene = this->lookToShopkeeperCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); } - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } @@ -1099,15 +1084,15 @@ void EnSob1_ContinueShopping(EnSob1* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); EnGirlA* item; - if ((func_80152498(&globalCtx->msgCtx) == 5) && (func_80147624(globalCtx))) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { EnSob1_ResetItemPosition(this); item = this->items[this->cursorIdx]; item->restockFunc(globalCtx, item); player->actor.shape.rot.y += 0x8000; player->stateFlags2 |= 0x20000000; - func_801518B0(globalCtx, this->welcomeTextId, &this->actor); + Message_StartTextbox(globalCtx, this->welcomeTextId, &this->actor); EnSob1_SetupStartShopping(globalCtx, this, true); - func_800B85E0(&this->actor, globalCtx, 200.0f, -1); + func_800B85E0(&this->actor, globalCtx, 200.0f, EXCH_ITEM_MINUS1); } } @@ -1206,10 +1191,7 @@ void EnSob1_UpdateCursorAnim(EnSob1* this) { void EnSob1_UpdateStickDirectionPromptAnim(EnSob1* this) { f32 arrowAnimTween = this->arrowAnimTween; f32 stickAnimTween = this->stickAnimTween; - - // Possbily fake temps - s32 maxColor = 255; - f32 tmp; + s32 maxColor = 255; //! FAKE: if (this->arrowAnimState == 0) { arrowAnimTween += 0.05f; @@ -1236,40 +1218,42 @@ void EnSob1_UpdateStickDirectionPromptAnim(EnSob1* this) { stickAnimTween = 0.0f; this->stickAnimState = 0; } - - tmp = 155.0f * arrowAnimTween; - this->stickAnimTween = stickAnimTween; this->stickLeftPrompt.arrowColor.r = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.g = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); - this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100, arrowAnimTween); + this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowColor.r = (maxColor - ((s32)tmp)) & 0xFF; - this->stickRightPrompt.arrowColor.g = (255 - ((s32)tmp)) & 0xFF; + this->stickRightPrompt.arrowTexX = 290.0f; + + this->stickRightPrompt.arrowColor.r = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); + this->stickRightPrompt.arrowColor.g = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowTexX = 290.0f; this->stickLeftPrompt.arrowTexX = 33.0f; this->stickRightPrompt.stickTexX = 274.0f; this->stickRightPrompt.stickTexX += 8.0f * stickAnimTween; + this->stickLeftPrompt.stickTexX = 49.0f; this->stickLeftPrompt.stickTexX -= 8.0f * stickAnimTween; - this->stickLeftPrompt.arrowTexY = this->stickRightPrompt.arrowTexY = 91.0f; - this->stickLeftPrompt.stickTexY = this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + + this->stickRightPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.stickTexY = 95.0f; } -s16 EnSob1_GetXZAngleAndDistanceSqToPoint(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq) { +s16 EnSob1_GetDistSqAndOrient(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq) { Vec3s* points; f32 diffX; f32 diffZ; if (path != NULL) { - points = (Vec3s*)Lib_SegmentedToVirtual(path->points); + points = Lib_SegmentedToVirtual(path->points); points = &points[pointIdx]; diffX = points->x - pos->x; diffZ = points->z - pos->z; @@ -1317,7 +1301,7 @@ void EnSob1_Blink(EnSob1* this) { } void EnSob1_ChangeObject(EnSob1* this, GlobalContext* globalCtx) { - gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->objIndices[2]].segment); + gSegments[0x06] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->objIndices[2]].segment); } s32 EnSob1_AreObjectsLoaded(EnSob1* this, GlobalContext* globalCtx) { @@ -1333,55 +1317,55 @@ s32 EnSob1_AreObjectsLoaded(EnSob1* this, GlobalContext* globalCtx) { return false; } -void EnSob1_InitZoraShopkeeper(EnSob1* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600D208, NULL, this->jointTable, this->morphTable, 20); +void EnSob1_ZoraShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gZoraSkel, NULL, this->jointTable, this->morphTable, 20); gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->objIndices[2]].segment); - Animation_Change(&this->skelAnime, &D_0600078C, 1.0f, 0.0f, Animation_GetLastFrame(&D_0600078C), 0, 0.0f); - this->actor.draw = EnSob1_DrawZoraShopkeeper; + Animation_Change(&this->skelAnime, &object_masterzoora_Anim_00078C, 1.0f, 0.0f, + Animation_GetLastFrame(&object_masterzoora_Anim_00078C), 0, 0.0f); + this->actor.draw = EnSob1_ZoraShopkeeper_Draw; this->changeObjectFunc = EnSob1_ChangeObject; } -void EnSob1_InitGoronShopkeeper(EnSob1* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011AC8, NULL, this->jointTable, this->morphTable, 18); +void EnSob1_GoronShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_oF1d_map_Skel_011AC8, NULL, this->jointTable, + this->morphTable, 18); gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->objIndices[2]].segment); - Animation_Change(&this->skelAnime, &D_060000FC, 1.0f, 0.0f, Animation_GetLastFrame(&D_060000FC), 0, 0.0f); - this->actor.draw = EnSob1_DrawGoronShopkeeper; + Animation_Change(&this->skelAnime, &object_mastergolon_Anim_0000FC, 1.0f, 0.0f, + Animation_GetLastFrame(&object_mastergolon_Anim_0000FC), 0, 0.0f); + this->actor.draw = EnSob1_GoronShopkeeper_Draw; this->changeObjectFunc = EnSob1_ChangeObject; } -void EnSob1_InitBombShopkeeper(EnSob1* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06009220, &D_06009120, this->jointTable, this->morphTable, 16); - this->actor.draw = EnSob1_DrawBombShopkeeper; +void EnSob1_BombShopkeeper_Init(EnSob1* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_rs_Skel_009220, &object_rs_Anim_009120, this->jointTable, + this->morphTable, 16); + this->actor.draw = EnSob1_BombShopkeeper_Draw; this->changeObjectFunc = NULL; this->skelAnime.playSpeed = 2.0f; } void EnSob1_InitShop(EnSob1* this, GlobalContext* globalCtx) { ShopItem* shopItems; - EnSob1XZRange* unkStruct; + EnSob1XZRange* xzRange; Vec3f* posOffset; - // Possibly fake temps - EnSob1* this2; - u32 maxColor = 255; - if (EnSob1_AreObjectsLoaded(this, globalCtx)) { - this->actor.flags &= ~0x10; + this->actor.flags &= ~ACTOR_FLAG_10; this->actor.objBankIndex = this->objIndices[0]; - Actor_SetObjectSegment(globalCtx, &this->actor); + Actor_SetObjectDependency(globalCtx, &this->actor); posOffset = &sPosOffset[this->shopType]; this->actor.world.pos.x += posOffset->x; this->actor.world.pos.y += posOffset->y; this->actor.world.pos.z += posOffset->z; shopItems = sShops[this->shopType]; - if ((this->shopType == BOMB_SHOP) && (gSaveContext.weekEventReg[0x21] & 8)) { + if ((this->shopType == BOMB_SHOP) && (gSaveContext.save.weekEventReg[33] & 8)) { sShops[this->shopType][0].shopItemId = SI_BOMB_BAG_30_2; } this->cutsceneState = ENSOB1_CUTSCENESTATE_STOPPED; EnSob1_GetCutscenes(this); this->cutscene = this->lookFowardCutscene; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); sInitFuncs[this->shopType](this, globalCtx); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->actor.colChkInfo.cylRadius = 50; @@ -1389,7 +1373,7 @@ void EnSob1_InitShop(EnSob1* this, GlobalContext* globalCtx) { this->pathPointsIdx = 0; if (this->shopType == BOMB_SHOP) { - this->path = func_8013D648(globalCtx, ENSOB1_GET_PATH(&this->actor), 0x1F); + this->path = SubS_GetPathByIndex(globalCtx, ENSOB1_GET_PATH(&this->actor), 0x1F); } if (this->shopType == BOMB_SHOP) { EnSob1_SetupAction(this, EnSob1_SetupWalk); @@ -1397,67 +1381,65 @@ void EnSob1_InitShop(EnSob1* this, GlobalContext* globalCtx) { EnSob1_SetupAction(this, EnSob1_Idle); } - this->cursorPos.y = (this->cursorPos.x = 100.0f); - this->stickAccumX = (this->stickAccumY = 0); + this->cursorPos.y = this->cursorPos.x = 100.0f; + this->stickAccumY = 0; + this->stickAccumX = 0; + this->cursorIdx = 0; this->cursorPos.z = 1.2f; this->cursorColor.r = 0; this->cursorColor.g = 80; - this->cursorColor.b = maxColor; - this->cursorColor.a = maxColor; + this->cursorColor.b = 255; + this->cursorColor.a = 255; this->cursorAnimTween = 0.0f; this->cursorAnimState = 0; this->drawCursor = 0; - this2 = this; + this->stickLeftPrompt.stickColor.r = 200; + this->stickLeftPrompt.stickColor.g = 200; + this->stickLeftPrompt.stickColor.b = 200; + this->stickLeftPrompt.stickColor.a = 180; + this->stickLeftPrompt.stickTexX = 49.0f; + this->stickLeftPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.arrowColor.r = 255; + this->stickLeftPrompt.arrowColor.g = 255; + this->stickLeftPrompt.arrowColor.b = 0; + this->stickLeftPrompt.arrowColor.a = 200; + this->stickLeftPrompt.arrowTexX = 33.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.texZ = 1.0f; + this->stickLeftPrompt.isEnabled = false; - this2->stickLeftPrompt.stickColor.r = 200; - this2->stickLeftPrompt.stickColor.g = 200; - this2->stickLeftPrompt.stickColor.b = 200; - this2->stickLeftPrompt.stickColor.a = 180; - this2->stickLeftPrompt.stickTexX = 49.0f; - this2->stickLeftPrompt.stickTexY = 95.0f; - this2->stickLeftPrompt.arrowColor.r = maxColor; - this2->stickLeftPrompt.arrowColor.g = maxColor; - this2->stickLeftPrompt.arrowColor.b = 0; - this2->stickLeftPrompt.arrowColor.a = 200; - this2->stickLeftPrompt.arrowTexX = 33.0f; - this2->stickLeftPrompt.arrowTexY = 91.0f; - this2->stickLeftPrompt.texZ = 1.0f; - this2->stickLeftPrompt.isEnabled = 0; + this->stickRightPrompt.stickColor.r = 200; + this->stickRightPrompt.stickColor.g = 200; + this->stickRightPrompt.stickColor.b = 200; + this->stickRightPrompt.stickColor.a = 180; + this->stickRightPrompt.stickTexX = 274.0f; + this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowColor.r = 255; + this->stickRightPrompt.arrowColor.g = 0; + this->stickRightPrompt.arrowColor.b = 0; + this->stickRightPrompt.arrowColor.a = 200; + this->stickRightPrompt.arrowTexX = 290.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickRightPrompt.texZ = 1.0f; + this->stickRightPrompt.isEnabled = false; - if (1) {} + this->arrowAnimState = 0; + this->stickAnimState = 0; + this->arrowAnimTween = 0.0f; + this->stickAnimTween = 0.0f; + this->shopItemSelectedTween = 0.0f; - this2->stickRightPrompt.stickColor.r = 200; - this2->stickRightPrompt.stickColor.g = 200; - this2->stickRightPrompt.stickColor.b = 200; - this2->stickRightPrompt.stickColor.a = 180; - this2->stickRightPrompt.stickTexX = 274.0f; - this2->stickRightPrompt.stickTexY = 95.0f; - this2->stickRightPrompt.arrowColor.r = maxColor; - this2->stickRightPrompt.arrowColor.g = 0; - this2->stickRightPrompt.arrowColor.b = 0; - this2->stickRightPrompt.arrowColor.a = 200; - this2->stickRightPrompt.arrowTexX = 290.0f; - this2->stickRightPrompt.arrowTexY = 91.0f; - this2->stickRightPrompt.texZ = 1.0f; - this2->stickRightPrompt.isEnabled = 0; - - this2->arrowAnimState = 0; - this2->stickAnimState = 0; - this2->arrowAnimTween = 0.0f; - this2->stickAnimTween = 0.0f; - this2->shopItemSelectedTween = 0.0f; - - this2->actor.gravity = 0.0f; - this2->posXZRange = sPosXZRanges[this2->shopType]; - Actor_SetScale(&this2->actor, sActorScales[this2->shopType]); - EnSob1_SpawnShopItems(this2, globalCtx, shopItems); + this->actor.gravity = 0.0f; + this->posXZRange = sPosXZRanges[this->shopType]; + Actor_SetScale(&this->actor, sActorScales[this->shopType]); + EnSob1_SpawnShopItems(this, globalCtx, shopItems); this->headRot = this->headRotTarget = 0; - this2->blinkTimer = 20; - this2->eyeTexIndex = 0; + this->blinkTimer = 20; + this->eyeTexIndex = 0; this->blinkFunc = EnSob1_WaitForBlink; - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; } } @@ -1473,7 +1455,7 @@ void EnSob1_Update(Actor* thisx, GlobalContext* globalCtx) { EnSob1_UpdateCursorAnim(this); Math_StepToS(&this->headRot, this->headRotTarget, 0x190); this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, 90.0f); + Actor_SetFocus(&this->actor, 90.0f); changeObjectFunc = this->changeObjectFunc; if (changeObjectFunc != NULL) { changeObjectFunc(this, globalCtx); @@ -1485,7 +1467,10 @@ void EnSob1_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnSob1_DrawCursor(GlobalContext* globalCtx, EnSob1* this, f32 x, f32 y, f32 z, u8 drawCursor) { - s32 ulx, uly, lrx, lry; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; f32 w; s32 dsdx; s32 pad; @@ -1495,7 +1480,7 @@ void EnSob1_DrawCursor(GlobalContext* globalCtx, EnSob1* this, f32 x, f32 y, f32 func_8012C654(globalCtx->state.gfxCtx); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, this->cursorColor.r, this->cursorColor.g, this->cursorColor.b, this->cursorColor.a); - gDPLoadTextureBlock_4b(OVERLAY_DISP++, &D_0401F740, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, + gDPLoadTextureBlock_4b(OVERLAY_DISP++, gSelectionCursorTex, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD); w = 16.0f * z; ulx = (x - w) * 4.0f; @@ -1511,11 +1496,16 @@ void EnSob1_DrawCursor(GlobalContext* globalCtx, EnSob1* this, f32 x, f32 y, f32 void EnSob1_DrawTextRec(GlobalContext* globalCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t, f32 dx, f32 dy) { f32 unk; - s32 ulx, uly, lrx, lry; - f32 w, h; - s32 dsdx, dtdy; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; + f32 w; + f32 h; + s32 dsdx; + s32 dtdy; - ((void)"../z_en_soB1.c"); // Unreferenced + (void)"../z_en_soB1.c"; OPEN_DISPS(globalCtx->state.gfxCtx); gDPPipeSync(OVERLAY_DISP++); @@ -1541,21 +1531,15 @@ void EnSob1_DrawStickDirectionPrompt(GlobalContext* globalCtx, EnSob1* this) { s32 drawStickRightPrompt = this->stickLeftPrompt.isEnabled; s32 drawStickLeftPrompt = this->stickRightPrompt.isEnabled; - ((void)"../z_en_soB1.c"); // Unreferenced + (void)"../z_en_soB1.c"; OPEN_DISPS(globalCtx->state.gfxCtx); if (drawStickRightPrompt || drawStickLeftPrompt) { func_8012C654(globalCtx->state.gfxCtx); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F8C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 191, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 23 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnSob1_DrawTextRec(globalCtx, this->stickLeftPrompt.arrowColor.r, this->stickLeftPrompt.arrowColor.g, this->stickLeftPrompt.arrowColor.b, this->stickLeftPrompt.arrowColor.a, @@ -1568,15 +1552,9 @@ void EnSob1_DrawStickDirectionPrompt(GlobalContext* globalCtx, EnSob1* this) { this->stickRightPrompt.arrowTexX, this->stickRightPrompt.arrowTexY, this->stickRightPrompt.texZ, 0, 0, 1.0f, 1.0f); } - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F7C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 127, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 15 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnSob1_DrawTextRec(globalCtx, this->stickLeftPrompt.stickColor.r, this->stickLeftPrompt.stickColor.g, this->stickLeftPrompt.stickColor.b, this->stickLeftPrompt.stickColor.a, @@ -1593,8 +1571,8 @@ void EnSob1_DrawStickDirectionPrompt(GlobalContext* globalCtx, EnSob1* this) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -s32 EnSob1_OverrideLimbDrawZoraShopkeeper(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* thisx) { +s32 EnSob1_ZoraShopkeeper_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnSob1* this = THIS; if (limbIndex == 15) { @@ -1603,20 +1581,21 @@ s32 EnSob1_OverrideLimbDrawZoraShopkeeper(GlobalContext* globalCtx, s32 limbInde return false; } -s32 EnSob1_OverrideLimbDrawBombShopkeeper(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, - Actor* thisx) { +s32 EnSob1_BombShopkeeper_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { EnSob1* this = THIS; if (limbIndex == 15) { - Matrix_InsertXRotation_s(this->headRot, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot, MTXMODE_APPLY); } return false; } -void EnSob1_PostLimbDrawBombShopkeeper(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +void EnSob1_BombShopkeeper_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + Actor* thisx) { OPEN_DISPS(globalCtx->state.gfxCtx); if (limbIndex == 11) { - gSPDisplayList(POLY_OPA_DISP++, D_06000970); + gSPDisplayList(POLY_OPA_DISP++, object_rs_DL_000970); } CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -1631,8 +1610,8 @@ Gfx* EnSob1_EndDList(GraphicsContext* gfxCtx) { return dList; } -void EnSob1_DrawZoraShopkeeper(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sZoraShopkeeperEyeTextures[] = { &D_060050A0, &D_060058A0, &D_060060A0 }; +void EnSob1_ZoraShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sZoraShopkeeperEyeTextures[] = { gZoraEyeOpenTex, gZoraEyeHalfTex, gZoraEyeClosedTex }; EnSob1* this = THIS; s32 pad; s32 i; @@ -1643,7 +1622,7 @@ void EnSob1_DrawZoraShopkeeper(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x0C, EnSob1_EndDList(globalCtx->state.gfxCtx)); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sZoraShopkeeperEyeTextures[this->eyeTexIndex])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSob1_OverrideLimbDrawZoraShopkeeper, NULL, &this->actor); + EnSob1_ZoraShopkeeper_OverrideLimbDraw, NULL, &this->actor); for (i = 0; i < ARRAY_COUNT(this->items); i++) { this->items[i]->actor.scale.x = 0.2f; this->items[i]->actor.scale.y = 0.2f; @@ -1654,8 +1633,9 @@ void EnSob1_DrawZoraShopkeeper(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -void EnSob1_DrawGoronShopkeeper(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sGoronShopkeeperEyeTextures[] = { &D_06010438, &D_06010C38, &D_06011038 }; +void EnSob1_GoronShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr sGoronShopkeeperEyeTextures[] = { object_oF1d_map_Tex_010438, object_oF1d_map_Tex_010C38, + object_oF1d_map_Tex_011038 }; EnSob1* this = THIS; s32 pad; s32 i; @@ -1675,7 +1655,7 @@ void EnSob1_DrawGoronShopkeeper(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } -void EnSob1_DrawBombShopkeeper(Actor* thisx, GlobalContext* globalCtx) { +void EnSob1_BombShopkeeper_Draw(Actor* thisx, GlobalContext* globalCtx) { EnSob1* this = THIS; s32 pad; u32 frames; @@ -1683,9 +1663,9 @@ void EnSob1_DrawBombShopkeeper(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_06005458)); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(object_rs_Tex_005458)); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSob1_OverrideLimbDrawBombShopkeeper, EnSob1_PostLimbDrawBombShopkeeper, &this->actor); + EnSob1_BombShopkeeper_OverrideLimbDraw, EnSob1_BombShopkeeper_PostLimbDraw, &this->actor); for (i = 0; i < ARRAY_COUNT(this->items); i++) { this->items[i]->actor.scale.x = 0.2f; this->items[i]->actor.scale.y = 0.2f; @@ -1695,7 +1675,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_ReplaceRotation(&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 1ac84901e..b9ccdb579 100644 --- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c +++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c @@ -1,6 +1,13 @@ -#include "z_en_ssh.h" +/* + * File: z_en_ssh.c + * Overlay: ovl_En_Ssh + * Description: Cursed Man (Swamp Spider House) + */ -#define FLAGS 0x00000035 +#include "z_en_ssh.h" +#include "objects/object_ssh/object_ssh.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnSsh*)thisx) @@ -9,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, @@ -31,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, false, + false, true, true, &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_Push(); + Matrix_MultVec3f(&p1Base, &p1); + Matrix_MultVec3f(&p2Base, &p2); + Matrix_Pop(); + 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) { + Actor_PlaySfxAtPos(&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)) { + Actor_SetColorFilter(&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") + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTU_ROLL); + Actor_PlaySfxAtPos(&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_Push(); + Matrix_Translate(this->ceilingPos.x, this->ceilingPos.y, this->ceilingPos.z, MTXMODE_NEW); + Matrix_RotateYF(this->actor.world.rot.y * (M_PI / 0x8000), MTXMODE_APPLY); + Matrix_MultVec3f(&swayVecBase, &swayVec); + Matrix_Pop(); + + 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; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTU_ROLL); + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&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_Push(); + Matrix_Translate(colliderPos.x, colliderPos.y, colliderPos.z, MTXMODE_NEW); + Matrix_RotateYF(BINANG_TO_RAD(this->initialYaw), MTXMODE_APPLY); + Matrix_MultVec3f(&colliderOffsets[i], &colliderPos); + Matrix_Pop(); + + 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, ActorShadow_DrawCircle, 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 (Inventory_GetSkullTokenCount(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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x904: + case 0x905: + case 0x906: + case 0x908: + case 0x910: + case 0x911: + case 0x912: + case 0x914: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = EnSsh_Idle; + break; + } + } +} + +void func_809756D0(EnSsh* this, GlobalContext* globalCtx) { + u16 phi_a1; + + if (gSaveContext.save.weekEventReg[34] & 8) { + phi_a1 = 0x914; + } else { + phi_a1 = 0x910; + gSaveContext.save.weekEventReg[34] |= 8; + } + Message_StartTextbox(globalCtx, phi_a1, &this->actor); +} + +void EnSsh_Idle(EnSsh* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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) { + Actor_PlaySfxAtPos(&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) && + Player_IsFacingActor(&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) { + Actor_PlaySfxAtPos(&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_UpdatePos(&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_SetFocus(&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 a0d2cacf9..e2915a614 100644 --- a/src/overlays/actors/ovl_En_St/z_en_st.c +++ b/src/overlays/actors/ovl_En_St/z_en_st.c @@ -1,6 +1,14 @@ -#include "z_en_st.h" +/* + * File: z_en_st.c + * Overlay: ovl_En_St + * Description: Skulltula (large suspended one) + */ -#define FLAGS 0x01004035 +#include "z_en_st.h" +#include "objects/object_st/object_st.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_4000 | ACTOR_FLAG_1000000) #define THIS ((EnSt*)thisx) @@ -13,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, @@ -27,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), @@ -94,73 +152,795 @@ static DamageTable D_808A766C = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static AnimationInfoS sAnimations[] = { + { &object_st_Anim_000304, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_st_Anim_005B98, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_st_Anim_000304, 4.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_st_Anim_000304, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_st_Anim_0055A8, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_st_Anim_000304, 8.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_st_Anim_000304, 6.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_st_Anim_005B98, 2.0f, 0, -1, ANIMMODE_LOOP, -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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(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->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + 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->drawDmgEffFrozenSteamScales[i] = 0.90000004f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A701C.s") + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) || (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_BLUE_FIRE)) { + 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 drawDmgEffType; + Vec3f limbPos[1]; + f32 drawDmgEffAlpha; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A73E8.s") + if (arg2 < this->unk_31A) { + if (this->unk_31C[arg2] != 0) { + drawDmgEffAlpha = (f32)this->unk_31C[arg2] / this->unk_334[arg2]; + drawDmgEffType = this->drawDmgEffType; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A7478.s") + Math_ApproachF(&this->drawDmgEffFrozenSteamScales[arg2], 0.6f, 0.3f, 0.5f); + Math_Vec3f_Copy(&limbPos[0], &this->actor.world.pos); + + limbPos[0].x += this->unk_358[arg2].x; + limbPos[0].y += this->unk_358[arg2].y; + limbPos[0].z += this->unk_358[arg2].z; + + if (drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + if ((this->unk_334[arg2] - this->unk_31C[arg2]) < 20) { + drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; + } + drawDmgEffAlpha = 1.0f; + } + Actor_DrawDamageEffects(globalCtx, &this->actor, limbPos, ARRAY_COUNT(limbPos), 0.6f, + this->drawDmgEffFrozenSteamScales[arg2], drawDmgEffAlpha, drawDmgEffType); + 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); + } + Actor_SpawnIceEffects(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) { + Actor_PlaySfxAtPos(&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) { + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, idx); + Actor_PlaySfxAtPos(&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) { + SubS_ChangeAnimationByInfoS(&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); + SubS_ChangeAnimationByInfoS(&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; + + SubS_ChangeAnimationByInfoS(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + // 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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + // 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: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->unk_312 = 40; + Actor_SetColorFilter(&this->actor, 0, 200, 0, this->unk_312); + break; + + case 5: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->unk_312 = 40; + func_808A576C(this); + Actor_SetColorFilter(&this->actor, 0, 200, 0, this->unk_312); + break; + + default: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTU_DAMAGE); + this->unk_314 = 20; + this->unk_312 = 0; + Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, this->unk_314); + SubS_ChangeAnimationByInfoS(&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) { + Flags_SetSwitch(globalCtx, ENST_GET_3F(&this->actor)); + } + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALTU_DEAD); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + + this->actor.flags &= ~ACTOR_FLAG_1; + + switch (this->actor.colChkInfo.damageEffect) { + case 4: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->unk_318 = 20; + func_808A576C(this); + break; + + case 3: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->unk_318 = 0; + func_808A576C(this); + break; + + case 2: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->unk_318 = 20; + func_808A576C(this); + break; + + default: + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_BLUE_FIRE; + this->unk_318 = 0; + break; + } + + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + SubS_ChangeAnimationByInfoS(&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; + Actor_SetColorFilter(&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); + Actor_PlaySfxAtPos(&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, ActorShadow_DrawCircle, 8.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_st_Skel_005298, NULL, this->jointTable, this->morphTable, + 30); + SubS_ChangeAnimationByInfoS(&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 |= ACTOR_FLAG_80; + } + + 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_MoveWithGravity(&this->actor); + + if ((this->unk_18C & 8) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_ChangeAnimationByInfoS(&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_MoveWithGravity(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + 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)) { + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 7); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_BLUE_FIRE; + 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) { + Actor_PlaySfxAtPos(&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_MoveWithGravity(&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->drawDmgEffType == ACTOR_DRAW_DMGEFF_BLUE_FIRE) { + 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 & ACTOR_FLAG_8000) { + SkelAnime_Update(&this->skelAnime); + this->unk_18C |= 0x80; + return; + } + + if (!(this->actor.flags & ACTOR_FLAG_80) && func_808A6A3C(this)) { + this->actor.flags |= ACTOR_FLAG_80; + } + + if (func_808A6580(this, globalCtx)) { + this->actionFunc = func_808A6E24; + } else if (DECR(this->unk_312) == 0) { + this->actionFunc(this, globalCtx); + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + 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->drawDmgEffType == ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL) { + 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_SetFocus(&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..f3a827515 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 drawDmgEffType; + /* 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 drawDmgEffFrozenSteamScales[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_Sth/z_en_sth.c b/src/overlays/actors/ovl_En_Sth/z_en_sth.c index 9b7965946..23b1b6223 100644 --- a/src/overlays/actors/ovl_En_Sth/z_en_sth.c +++ b/src/overlays/actors/ovl_En_Sth/z_en_sth.c @@ -1,6 +1,15 @@ -#include "z_en_sth.h" +/* + * File: z_en_sth.c + * Overlay: ovl_En_Sth + * Description: Guy looking at moon in South Clock Town + */ -#define FLAGS 0x00000009 +#include "z_en_sth.h" +#include "objects/object_sth/object_sth.h" +#include "objects/object_ahg/object_ahg.h" +#include "objects/object_mask_truth/object_mask_truth.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnSth*)thisx) @@ -8,7 +17,16 @@ void EnSth_Init(Actor* thisx, GlobalContext* globalCtx); void EnSth_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSth_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B67208(EnSth* this, GlobalContext* globalCtx); +void func_80B67540(EnSth* this, GlobalContext* globalCtx); +void func_80B677BC(EnSth* this, GlobalContext* globalCtx); +void func_80B678A8(EnSth* this, GlobalContext* globalCtx); +void func_80B67958(EnSth* this, GlobalContext* globalCtx); +void func_80B67C1C(EnSth* this, GlobalContext* globalCtx); +void func_80B67DA0(EnSth* this, GlobalContext* globalCtx); +void func_80B680A8(Actor* thisx, GlobalContext* globalCtx); +void func_80B6849C(Actor* thisx, GlobalContext* globalCtx); + const ActorInit En_Sth_InitVars = { ACTOR_EN_STH, ACTORCAT_NPC, @@ -21,68 +39,677 @@ const ActorInit En_Sth_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B6D19C = { - { 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, }, +#include "overlays/ovl_En_Sth/ovl_En_Sth.c" + +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 +AnimationHeader* D_80B6D1C8[] = { + &ovl_En_Sth_Anim_003F50, &ovl_En_Sth_Anim_0045B4, &ovl_En_Sth_Anim_004CC0, &ovl_En_Sth_Anim_00533C, + &ovl_En_Sth_Anim_0059B8, &ovl_En_Sth_Anim_005E40, &ovl_En_Sth_Anim_006354, &ovl_En_Sth_Anim_00645C, +}; -extern ColliderCylinderInit D_80B6D19C; +u16 D_80B6D1E8[] = { 0x1144, 0x1145, 0x1146 }; -extern UNK_TYPE D_06005998; -extern UNK_TYPE D_0A0001A0; +u16 D_80B6D1F0[] = { 0x1139, 0x113E, 0x1143 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/EnSth_Init.s") +u16 D_80B6D1F8[] = { 0x1132, 0x113A, 0x113F }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/EnSth_Destroy.s") +Vec3f D_80B6D200 = { 700.0f, 400.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B6703C.s") +Color_RGB8 D_80B6D20C[] = { + { 190, 110, 0 }, { 0, 180, 110 }, { 0, 255, 0x50 }, { 255, 160, 60 }, { 190, 230, 250 }, { 240, 230, 120 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B670A4.s") +void EnSth_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSth* this = THIS; + s32 objectId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67148.s") + if (ENSTH_GET_100(&this->actor)) { + objectId = Object_GetIndex(&globalCtx->objectCtx, OBJECT_AHG); + } else { + objectId = Object_GetIndex(&globalCtx->objectCtx, OBJECT_STH); + } + this->unk_29E = objectId; + this->unk_29F = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MASK_TRUTH); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B671A0.s") + Actor_SetScale(&this->actor, 0.01f); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 36.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67208.s") + this->unk_29C = 0; + this->unk_29A = 8; + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B672A4.s") + switch (ENSTH_GET_F(&this->actor)) { + case ENSTH_F_1: + if (globalCtx->actorCtx.unk5 & 2) { + this->actor.flags |= (ACTOR_FLAG_10 | ACTOR_FLAG_20); + this->actionFunc = func_80B67958; + } else { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67348.s") + case ENSTH_F_2: + if (Inventory_GetSkullTokenCount(globalCtx->sceneNum) >= 30) { + this->actionFunc = func_80B67DA0; + } else { + Actor_MarkForDeath(&this->actor); + } + this->actor.textId = 0; + if (!(gSaveContext.save.weekEventReg[34] & 0x40) || !(gSaveContext.save.weekEventReg[34] & 8)) { + this->unk_29C |= 1; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67458.s") + case ENSTH_F_3: + if ((gSaveContext.save.skullTokenCount & 0xFFFF) >= 30) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc = func_80B678A8; + this->unk_29C |= 8; + this->actor.targetMode = 3; + this->actor.uncullZoneForward = 800.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67540.s") + case ENSTH_F_4: + if (gSaveContext.save.weekEventReg[13] & 0x20) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.textId = 0; + this->actionFunc = func_80B677BC; + if (gSaveContext.save.weekEventReg[13] & 0x80) { + this->unk_29C |= 2; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B677BC.s") + case ENSTH_F_5: + if (!(gSaveContext.save.weekEventReg[13] & 0x20) || + (Inventory_GetSkullTokenCount(globalCtx->sceneNum) < 30)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc = func_80B67208; + this->actor.textId = 0; + this->unk_29C |= 8; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67838.s") + default: + this->actionFunc = func_80B67958; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B678A8.s") +void EnSth_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSth* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67958.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67984.s") +s32 func_80B6703C(EnSth* this, GlobalContext* globalCtx) { + if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x2000)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67AB4.s") +void func_80B670A4(EnSth* this, s16 arg1) { + if ((arg1 >= 0) && (arg1 < ARRAY_COUNT(D_80B6D1C8)) && (arg1 != this->unk_29A)) { + Animation_Change(&this->skelAnime, D_80B6D1C8[arg1], 1.0f, 0.0f, Animation_GetLastFrame(D_80B6D1C8[arg1]), 0, + -5.0f); + this->unk_29A = arg1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67B50.s") +void func_80B67148(EnSth* this, GlobalContext* globalCtx) { + s32 day = CURRENT_DAY - 1; + u16 val; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67C1C.s") + if (day < 0) { + day = 0; + } + val = D_80B6D1E8[day]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67DA0.s") + Message_StartTextbox(globalCtx, val, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B67E20.s") +void func_80B671A0(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/EnSth_Update.s") + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + this->actionFunc = func_80B67208; + func_801477B4(globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B680A8.s") +void func_80B67208(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B681E8.s") + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80B67148(this, globalCtx); + this->actionFunc = func_80B671A0; + } else if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 110.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B68310.s") +void func_80B672A4(EnSth* this, GlobalContext* globalCtx) { + u16 sp1E; + s32 day = CURRENT_DAY - 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sth/func_80B6849C.s") + if (day < 0) { + day = 0; + } + + if (this->unk_29C & 2) { + s32 pad; + + sp1E = D_80B6D1F0[day]; + if (day == 2) { + func_80B670A4(this, 5); + } + } else { + sp1E = D_80B6D1F8[day]; + } + Message_StartTextbox(globalCtx, sp1E, &this->actor); +} + +void func_80B67348(EnSth* this, GlobalContext* globalCtx) { + u16 phi_a1; + + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + this->actionFunc = func_80B67540; + + switch (this->actor.home.rot.z) { + case 8: + case 9: + phi_a1 = 0x1137; + break; + + case 6: + phi_a1 = 0x1138; + break; + + case 5: + if (gSaveContext.save.weekEventReg[13] & 0x40) { + phi_a1 = 0x113D; + } else { + phi_a1 = 0x113C; + } + break; + + default: + if (gSaveContext.save.weekEventReg[13] & 0x40) { + phi_a1 = 0x1142; + } else { + phi_a1 = 0x1141; + } + break; + } + Message_StartTextbox(globalCtx, phi_a1, &this->actor); + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} + +void func_80B67458(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80B67348; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + if (CURRENT_DAY == 3) { + func_80B670A4(this, 6); + } else { + func_80B670A4(this, 3); + } + } else { + Actor_PickUp(&this->actor, globalCtx, this->actor.home.rot.z, 10000.0f, 500.0f); + } +} + +void func_80B67540(EnSth* this, GlobalContext* globalCtx) { + s32 sp2C = CURRENT_DAY - 1; + + if (sp2C < 0) { + sp2C = 0; + } + + if (this->unk_29A == 6) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + SkelAnime_Update(&this->skelAnime); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1134: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1132: + case 0x113A: + case 0x113F: + func_80151938(globalCtx, 0x1133); + break; + + case 0x1133: + func_80151938(globalCtx, 0x1136); + func_80B670A4(this, 6); + break; + + case 0x1136: + gSaveContext.save.weekEventReg[13] |= 0x80; + + switch (sp2C) { + case 0: + if (gSaveContext.save.weekEventReg[13] & 0x40) { + this->actor.home.rot.z = 6; + } else { + gSaveContext.save.weekEventReg[13] |= 0x40; + switch (CUR_UPG_VALUE(UPG_WALLET)) { + case 0: + this->actor.home.rot.z = 8; + break; + + case 1: + this->actor.home.rot.z = 9; + break; + } + } + break; + + case 1: + this->actor.home.rot.z = 5; + break; + + default: + this->actor.home.rot.z = 4; + break; + } + func_801477B4(globalCtx); + this->actionFunc = func_80B67458; + func_80B67458(this, globalCtx); + break; + + case 0x113C: + func_80151938(globalCtx, 0x113B); + break; + + case 0x1141: + func_80151938(globalCtx, 0x1140); + func_80B670A4(this, 3); + break; + + default: + this->actionFunc = func_80B677BC; + func_801477B4(globalCtx); + this->unk_29C |= 2; + break; + } + } + break; + + case 2: + this->actionFunc = func_80B677BC; + this->unk_29C |= 2; + break; + } +} + +void func_80B677BC(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80B672A4(this, globalCtx); + this->actionFunc = func_80B67540; + } else if (func_80B6703C(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 110.0f); + } +} + +void func_80B67838(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + this->actionFunc = func_80B678A8; + func_801477B4(globalCtx); + } + this->unk_294.x = -0x1388; +} + +void func_80B678A8(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80B67838; + } else if (func_80B6703C(this, globalCtx) || this->actor.isTargeted) { + if ((gSaveContext.save.time >= CLOCK_TIME(6, 0)) && (gSaveContext.save.time <= CLOCK_TIME(18, 0))) { + this->actor.textId = 0x1130; + } else { + this->actor.textId = 0x1131; + } + func_800B8614(&this->actor, globalCtx, 110.0f); + } + this->unk_294.x = -0x1388; +} + +void func_80B67958(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); +} + +void func_80B67984(EnSth* this, GlobalContext* globalCtx) { + u16 sp1E; + + if (gSaveContext.save.weekEventReg[34] & 0x10) { + sp1E = 0x903; + func_80B670A4(this, 2); + } else if (gSaveContext.save.weekEventReg[34] & 0x20) { + sp1E = 0x90F; + func_80B670A4(this, 2); + } else if (gSaveContext.save.weekEventReg[34] & 0x40) { + if (!(gSaveContext.save.weekEventReg[34] & 8)) { + sp1E = 0x91B; + } else { + sp1E = 0x918; + } + func_80B670A4(this, 2); + } else if (Inventory_GetSkullTokenCount(globalCtx->sceneNum) >= 30) { + if (INV_CONTENT(ITEM_MASK_TRUTH) == ITEM_MASK_TRUTH) { + this->unk_29C |= 4; + sp1E = 0x919; + } else { + sp1E = 0x916; + } + } else if (gSaveContext.save.weekEventReg[34] & 2) { + sp1E = 0x8FF; + } else { + sp1E = 0x8FC; + gSaveContext.save.weekEventReg[34] |= 2; + } + Message_StartTextbox(globalCtx, sp1E, &this->actor); +} + +void func_80B67AB4(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80B67C1C; + gSaveContext.save.weekEventReg[34] |= 0x40; + Message_StartTextbox(globalCtx, 0x918, &this->actor); + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} + +void func_80B67B50(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80B67AB4; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } else { + this->unk_29C &= ~1; + gSaveContext.save.weekEventReg[34] |= 8; + Actor_PickUp(&this->actor, globalCtx, GI_MASK_CAPTAIN, 10000.0f, 50.0f); + } +} + +void func_80B67C1C(EnSth* this, GlobalContext* globalCtx) { + s32 pad; + + SkelAnime_Update(&this->skelAnime); + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x90C: + func_80B670A4(this, 2); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x916: + case 0x919: + func_80B670A4(this, 3); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x8FC: + case 0x8FD: + case 0x900: + case 0x90A: + case 0x90D: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x901: + case 0x90B: + case 0x917: + func_801477B4(globalCtx); + this->actionFunc = func_80B67B50; + func_80B67B50(this, globalCtx); + break; + + case 0x91A: + gSaveContext.save.weekEventReg[34] |= 0x40; + gSaveContext.save.weekEventReg[34] &= (u8)~8; + + case 0x902: + case 0x903: + case 0x90E: + case 0x90F: + case 0x918: + case 0x91B: + func_80B670A4(this, 3); + + default: + this->actor.flags &= ~ACTOR_FLAG_10000; + func_801477B4(globalCtx); + this->actionFunc = func_80B67DA0; + break; + } + } +} + +void func_80B67DA0(EnSth* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80B67984(this, globalCtx); + this->actionFunc = func_80B67C1C; + } else if (func_80B6703C(this, globalCtx)) { + this->actor.textId = 0; + func_800B8614(&this->actor, globalCtx, 110.0f); + } +} + +void func_80B67E20(Actor* thisx, GlobalContext* globalCtx) { + EnSth* this = THIS; + + if (Inventory_GetSkullTokenCount(globalCtx->sceneNum) >= 30) { + this->actor.update = func_80B680A8; + this->actor.draw = func_80B6849C; + this->actor.flags |= ACTOR_FLAG_1; + } +} + +void EnSth_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSth* this = THIS; + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_29E)) { + this->actor.objBankIndex = this->unk_29E; + Actor_SetObjectDependency(globalCtx, &this->actor); + + if (ENSTH_GET_100(&this->actor)) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ahg_Skel_005998, &ovl_En_Sth_Anim_0045B4, + this->jointTable, this->morphTable, 16); + Animation_PlayLoop(&this->skelAnime, &ovl_En_Sth_Anim_0045B4); + this->unk_29A = 1; + if ((gSaveContext.save.weekEventReg[34] & 0x10) || (gSaveContext.save.weekEventReg[34] & 0x20) || + (gSaveContext.save.weekEventReg[34] & 0x40) || + (Inventory_GetSkullTokenCount(globalCtx->sceneNum) >= 30)) { + func_80B670A4(this, 3); + } + } else { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_sth_Skel_0031F8, &ovl_En_Sth_Anim_003F50, + this->jointTable, this->morphTable, 16); + Animation_PlayLoop(&this->skelAnime, &ovl_En_Sth_Anim_003F50); + } + + this->actor.update = func_80B680A8; + this->actor.draw = func_80B6849C; + + switch (ENSTH_GET_F(&this->actor)) { + case ENSTH_F_3: + func_80B670A4(this, 4); + break; + + case ENSTH_F_4: + if (gSaveContext.save.weekEventReg[13] & 0x80) { + func_80B670A4(this, 5); + } else { + func_80B670A4(this, 5); + } + break; + + case ENSTH_F_5: + func_80B670A4(this, 7); + break; + } + + if ((ENSTH_GET_F(&this->actor) == ENSTH_F_4) && (Inventory_GetSkullTokenCount(globalCtx->sceneNum) < 30)) { + this->actor.update = func_80B67E20; + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + } + } +} + +void func_80B680A8(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSth* this = THIS; + Vec3s sp38; + + Actor_MoveWithGravity(&this->actor); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + this->actionFunc(this, globalCtx); + + if (func_80B6703C(this, globalCtx) && !(this->unk_29C & 8) && (this->unk_29A != 5)) { + sp38.x = sp38.y = sp38.z = 0; + + func_800E9250(globalCtx, &this->actor, &this->unk_294, &sp38, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_294.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_294.y, 0, 6, 6200, 100); + } +} + +s32 func_80B681E8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + s32 pad; + EnSth* this = THIS; + + if (limbIndex == 15) { + rot->x += this->unk_294.y; + rot->z += this->unk_294.x; + *dList = ovl_En_Sth_DL_0034A0; + } + + if ((limbIndex == 8) || (limbIndex == 10) || (limbIndex == 13)) { + rot->y += (s16)(Math_SinS(globalCtx->state.frames * ((limbIndex * 50) + 0x814)) * 200.0f); + rot->z += (s16)(Math_CosS(globalCtx->state.frames * ((limbIndex * 50) + 0x940)) * 200.0f); + } + return false; +} + +void func_80B68310(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnSth* this = THIS; + + if (limbIndex == 15) { + s32 pad; + + Matrix_MultVec3f(&D_80B6D200, &this->actor.focus.pos); + + if (!ENSTH_GET_100(&this->actor)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Sth_DL_0037C0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_29C & 1) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_29F)) { + Matrix_Push(); + Matrix_RotateZS(0x3A98, MTXMODE_APPLY); + Matrix_Translate(0.0f, 190.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_OPA_DISP++, 0x0A, globalCtx->objectCtx.status[this->unk_29F].segment); + gSPDisplayList(POLY_OPA_DISP++, object_mask_truth_DL_0001A0); + + Matrix_Pop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} + +void func_80B6849C(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSth* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, + Gfx_EnvColor(globalCtx->state.gfxCtx, D_80B6D20C[1].r, D_80B6D20C[1].g, D_80B6D20C[1].b, 255)); + gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 90, 110, 130, 255)); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80B681E8, func_80B68310, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Sth/z_en_sth.h b/src/overlays/actors/ovl_En_Sth/z_en_sth.h index fcd6042aa..422a92c34 100644 --- a/src/overlays/actors/ovl_En_Sth/z_en_sth.h +++ b/src/overlays/actors/ovl_En_Sth/z_en_sth.h @@ -5,9 +5,31 @@ struct EnSth; +typedef void (*EnSthActionFunc)(struct EnSth*, GlobalContext*); + +#define ENSTH_GET_F(thisx) ((thisx)->params & 0xF) +#define ENSTH_GET_100(thisx) ((thisx)->params & 0x100) + +enum { + /* 1 */ ENSTH_F_1 = 1, + /* 2 */ ENSTH_F_2, + /* 3 */ ENSTH_F_3, + /* 4 */ ENSTH_F_4, + /* 5 */ ENSTH_F_5, +}; + typedef struct EnSth { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x160]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ Vec3s jointTable[16]; + /* 0x234 */ Vec3s morphTable[16]; + /* 0x294 */ Vec3s unk_294; + /* 0x29A */ s16 unk_29A; + /* 0x29C */ u16 unk_29C; + /* 0x29E */ u8 unk_29E; + /* 0x29F */ u8 unk_29F; + /* 0x2A0 */ EnSthActionFunc actionFunc; } EnSth; // size = 0x2A4 extern const ActorInit En_Sth_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 d0141f546..0bf0ae73c 100644 --- a/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c +++ b/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_sth2.c + * Overlay: ovl_En_Sth2 + * Description: Guy waving at the telescope in Termina Field + */ + #include "z_en_sth2.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnSth2*)thisx) diff --git a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c index 3ae886dc1..54a1f84a8 100644 --- a/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c +++ b/src/overlays/actors/ovl_En_Stone_heishi/z_en_stone_heishi.c @@ -1,6 +1,12 @@ +/* + * File: z_en_stone_heishi.c + * Overlay: ovl_En_Stone_heishi + * Description: Shiro + */ + #include "z_en_stone_heishi.h" -#define FLAGS 0x00000089 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_80) #define THIS ((EnStoneheishi*)thisx) diff --git a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c index 96e593392..3ca829630 100644 --- a/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c +++ b/src/overlays/actors/ovl_En_Stop_heishi/z_en_stop_heishi.c @@ -1,6 +1,12 @@ +/* + * File: z_en_stop_heishi.c + * Overlay: ovl_En_Stop_heishi + * Description: Clock Town - Gate-Blocking Soldier + */ + #include "z_en_stop_heishi.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnStopheishi*)thisx) 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 ad7228b1b..abf58da86 100644 --- a/src/overlays/actors/ovl_En_Stream/z_en_stream.c +++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.c @@ -1,6 +1,13 @@ -#include "z_en_stream.h" +/* + * File: z_en_stream.c + * Overlay: ovl_En_Stream + * Description: Unused water vortex from OoT + */ -#define FLAGS 0x00000010 +#include "z_en_stream.h" +#include "objects/object_stream/object_stream.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnStream*)thisx) @@ -9,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, @@ -24,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 7449b0f5d..4a7e56682 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -7,8 +7,9 @@ #include "z_en_suttari.h" #include "overlays/actors/ovl_En_Elf/z_en_elf.h" #include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_boj/object_boj.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnSuttari*)thisx) @@ -36,17 +37,6 @@ void func_80BADE14(EnSuttari* this, GlobalContext* globalCtx); void func_80BADE8C(EnSuttari* this, GlobalContext* globalCtx); void func_80BADF3C(EnSuttari* this, GlobalContext* globalCtx); -extern FlexSkeletonHeader D_0600C240; -extern AnimationHeader D_0600071C; -extern AnimationHeader D_06010BDC; -extern AnimationHeader D_0601139C; -extern AnimationHeader D_06011F84; -extern AnimationHeader D_06011C38; -extern AnimationHeader D_060128F4; -extern AnimationHeader D_06012E84; -extern Gfx D_0600AF90[]; -extern Gfx D_06013380[]; - const ActorInit En_Suttari_InitVars = { ACTOR_EN_SUTTARI, ACTORCAT_NPC, @@ -59,12 +49,16 @@ const ActorInit En_Suttari_InitVars = { (ActorFunc)EnSuttari_Draw, }; -static ActorAnimationEntry sAnimations[] = { - { &D_0600071C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_060128F4, 1.0f, 0.0f, 0.0f, 0, 0.0f }, - { &D_06011F84, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_06012E84, 1.0f, 0.0f, 0.0f, 0, -6.0f }, - { &D_0601139C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_0600071C, 2.0f, 0.0f, 0.0f, 0, 0.0f }, - { &D_06011F84, 2.0f, 0.0f, 0.0f, 0, 0.0f }, { &D_06011C38, 1.0f, 0.0f, 0.0f, 2, 0.0f }, - { &D_06010BDC, 1.0f, 0.0f, 0.0f, 0, 0.0f }, +static AnimationInfo sAnimations[] = { + { &object_boj_Anim_00071C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_0128F4, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_011F84, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_012E84, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -6.0f }, + { &object_boj_Anim_01139C, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_00071C, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_011F84, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, + { &object_boj_Anim_011C38, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 0.0f }, + { &object_boj_Anim_010BDC, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, 0.0f }, }; static ColliderCylinderInit sCylinderInit = { @@ -126,17 +120,61 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(1, 0xE), }; -static s16 D_80BAE800[] = { - 4000, 4, 1, 3, 6000, 4, 1, 6, 4000, 4, 1, 3, 6000, 4, 1, 6, +static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, }; -static UNK_TYPE D_80BAE820[] = { - 0xC00027C, 0x210877, 0xA006D31, 0x2000000, 0x19250200, 0x19001E19, 0x2010F01, 0x140D0201, 0x14012D01, - 0x50E0114, 0x12D0E0E, 0x10F0114, 0x70E0019, 0x1E060E, 0x19, 0xD0A000D, 0x3D020019, 0x1E3102, - 0x1E002D, 0x2502002D, 0x1001902, 0x100010F, 0xD02010F, 0x1140105, 0xE010F01, 0x14090E01, 0x10F0B, - 0xE002D01, 0x20E00, 0x1E002D0A, 0xE001900, 0x1E080505, 0xC000125, 0xA006E20, 0x2120000, 0x14140200, - 0x14001E08, 0xF001E03, 0x4000405, 0xE001400, 0x1E0F0E12, 0x1403, 0x50C0003, 0x270A0013, 0x22021200, - 0x13001602, 0x13001319, 0xD021319, 0x105, 0xE131900, 0x10400, 0x50E1200, 0x13000C05, 0x5000000, +static u8 D_80BAE820[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(2, 0x80 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_FLAG_S(0x21, 0x08, 0x7F - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_ICHIBA, 0x3D - 0x0C), + /* 0x0C */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 0, 0, 25, 0x37 - 0x12), + /* 0x12 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 25, 0, 30, 0x31 - 0x18), + /* 0x18 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 15, 1, 20, 0x2B - 0x1E), + /* 0x1E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 20, 1, 45, 0x25 - 0x24), + /* 0x24 */ SCHEDULE_CMD_RET_NONE(), + /* 0x25 */ SCHEDULE_CMD_RET_TIME(1, 20, 1, 45, 14), + /* 0x2B */ SCHEDULE_CMD_RET_TIME(1, 15, 1, 20, 7), + /* 0x31 */ SCHEDULE_CMD_RET_TIME(0, 25, 0, 30, 6), + /* 0x37 */ SCHEDULE_CMD_RET_TIME(0, 0, 0, 25, 13), + /* 0x3D */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_AYASHIISHOP, 0x7E - 0x41), + /* 0x41 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 25, 0, 30, 0x78 - 0x47), + /* 0x47 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 30, 0, 45, 0x72 - 0x4D), + /* 0x4D */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 45, 1, 0, 0x6C - 0x53), + /* 0x53 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 0, 1, 15, 0x66 - 0x59), + /* 0x59 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(1, 15, 1, 20, 0x60 - 0x5F), + /* 0x5F */ SCHEDULE_CMD_RET_NONE(), + /* 0x60 */ SCHEDULE_CMD_RET_TIME(1, 15, 1, 20, 9), + /* 0x66 */ SCHEDULE_CMD_RET_TIME(1, 0, 1, 15, 11), + /* 0x6C */ SCHEDULE_CMD_RET_TIME(0, 45, 1, 0, 2), + /* 0x72 */ SCHEDULE_CMD_RET_TIME(0, 30, 0, 45, 10), + /* 0x78 */ SCHEDULE_CMD_RET_TIME(0, 25, 0, 30, 8), + /* 0x7E */ SCHEDULE_CMD_RET_NONE(), + /* 0x7F */ SCHEDULE_CMD_RET_NONE(), + /* 0x80 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(1, 0xA9 - 0x84), + /* 0x84 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_BACKTOWN, 0xA8 - 0x88), + /* 0x88 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 0, 20, 0xA2 - 0x8E), + /* 0x8E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(0, 20, 0, 30, 0x9C - 0x94), + /* 0x94 */ SCHEDULE_CMD_CHECK_BEFORE_TIME_S(0, 30, 0x9B - 0x98), + /* 0x98 */ SCHEDULE_CMD_RET_VAL_L(4), + /* 0x9B */ SCHEDULE_CMD_RET_NONE(), + /* 0x9C */ SCHEDULE_CMD_RET_TIME(0, 20, 0, 30, 15), + /* 0xA2 */ SCHEDULE_CMD_RET_TIME(18, 0, 0, 20, 3), + /* 0xA8 */ SCHEDULE_CMD_RET_NONE(), + /* 0xA9 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0xD4 - 0xAD), + /* 0xAD */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_IKANA, 0xD3 - 0xB1), + /* 0xB1 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 19, 0, 0xCD - 0xB7), + /* 0xB7 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(19, 0, 19, 25, 0xCA - 0xBD), + /* 0xBD */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(19, 25, 0, 0, 0xC4 - 0xC3), + /* 0xC3 */ SCHEDULE_CMD_RET_NONE(), + /* 0xC4 */ SCHEDULE_CMD_RET_TIME(19, 25, 0, 0, 1), + /* 0xCA */ SCHEDULE_CMD_RET_VAL_L(5), + /* 0xCD */ SCHEDULE_CMD_RET_TIME(18, 0, 19, 0, 12), + /* 0xD3 */ SCHEDULE_CMD_RET_NONE(), + /* 0xD4 */ SCHEDULE_CMD_RET_NONE(), }; static s32 D_80BAE8F8[] = { @@ -173,7 +211,7 @@ void EnSuttari_UpdateCollider(EnSuttari* this, GlobalContext* globalCtx) { } Actor* EnSuttari_GetActorById(GlobalContext* globalCtx, s16 actorId) { - Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (actor != NULL) { if (actor->id == actorId) { @@ -192,23 +230,19 @@ void EnSuttari_SetNextEntrance(GlobalContext* globalCtx, u16 nextEntranceIndex) } void EnSuttari_UpdateTime(void) { - u32* unk_14 = &gSaveContext.unk_14; - u16 time = gSaveContext.time; - - gSaveContext.time = (u16)REG(15) + time; - time = gSaveContext.time; - gSaveContext.time = (u16)*unk_14 + time; + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)REG(15); + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.daySpeed); } s32 func_80BAA904(EnSuttari* this, GlobalContext* globalCtx) { - Vec3f sp2C; + Vec3f pos; s32 pad; - s32 sp24; + CollisionPoly* poly; - sp2C.x = (Math_SinS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.x; - sp2C.y = this->actor.world.pos.y + 100.0f; - sp2C.z = (Math_CosS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.z; - if (func_800C4000(globalCtx, &globalCtx->colCtx, &sp24, &sp2C) > -500.0f) { + pos.x = (Math_SinS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.x; + pos.y = this->actor.world.pos.y + 100.0f; + pos.z = (Math_CosS(this->actor.world.rot.y) * 50.0f) + this->actor.world.pos.z; + if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos) > -500.0f) { return false; } return true; @@ -216,7 +250,7 @@ s32 func_80BAA904(EnSuttari* this, GlobalContext* globalCtx) { void func_80BAA9B4(EnSuttari* this) { s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); switch (this->textId) { case 0x1454: @@ -227,15 +261,15 @@ void func_80BAA9B4(EnSuttari* this) { case 0x1459: case 0x145A: case 0x145B: - if ((this->animationIdx != 8) && (curFrame == frameCount)) { - this->animationIdx = 8; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if ((this->animationIndex != 8) && (curFrame == frameCount)) { + this->animationIndex = 8; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } break; default: - if ((this->animationIdx != 1) && (curFrame == frameCount)) { - this->animationIdx = 1; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if ((this->animationIndex != 1) && (curFrame == frameCount)) { + this->animationIndex = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } } } @@ -243,8 +277,8 @@ void func_80BAA9B4(EnSuttari* this) { void func_80BAAA94(EnSuttari* this) { switch (this->textId) { case 0x29E5: - this->animationIdx = 1; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); break; case 0x29E9: this->enFsn->flags |= ENFSN_ANGRY; @@ -256,12 +290,12 @@ void func_80BAAA94(EnSuttari* this) { this->enFsn->flags |= ENFSN_OFFER_FINAL_PRICE; break; case 0x29EC: - this->animationIdx = 7; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 7; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); break; case 0x29ED: - this->animationIdx = 1; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); break; } } @@ -329,9 +363,9 @@ void func_80BAAB78(EnSuttari* this, GlobalContext* globalCtx) { } else if (this->flags1 & 1) { switch (this->textId) { case 0: - if (gSaveContext.weekEventReg[0x51] & 1) { + if (gSaveContext.save.weekEventReg[81] & 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; @@ -347,13 +381,13 @@ void func_80BAAB78(EnSuttari* this, GlobalContext* globalCtx) { } else { this->flags1 |= 0x400; this->textId = 0x1452; - gSaveContext.weekEventReg[0x51] |= 1; + gSaveContext.save.weekEventReg[81] |= 1; } break; case 0x1453: this->flags1 |= 0x400; - gSaveContext.weekEventReg[0x51] |= 1; - ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk264 |= 8; + gSaveContext.save.weekEventReg[81] |= 1; + ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk_264 |= 8; this->flags2 |= 1; this->textId = 0x1454; break; @@ -378,25 +412,25 @@ void func_80BAAB78(EnSuttari* this, GlobalContext* globalCtx) { break; } } - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); } void func_80BAAF1C(EnSuttari* this) { s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); - if (this->animationIdx == 5) { - this->animationIdx = 3; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); - } else if ((this->animationIdx == 3) && (curFrame == frameCount)) { - this->animationIdx = 6; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if (this->animationIndex == 5) { + this->animationIndex = 3; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); + } else if ((this->animationIndex == 3) && (curFrame == frameCount)) { + this->animationIndex = 6; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->flags1 &= ~0x100; } } void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { - if ((this->actor.xzDistToPlayer < 500.0f) && (this->actor.yDistToPlayer < 100.0f)) { + if ((this->actor.xzDistToPlayer < 500.0f) && (this->actor.playerHeightRel < 100.0f)) { Vec3f effectVelOffset = { 0.0f, 0.0f, 0.0f }; Vec3f effectPos; Vec3f effectVel; @@ -405,13 +439,13 @@ void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { effectPos.x += Math_SinS(this->actor.world.rot.y + this->unk3F4) * 10.0f; effectPos.y += 60.0f; effectPos.z += Math_CosS(this->actor.world.rot.y + this->unk3F4) * 10.0f; - Matrix_StatePush(); - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); effectVelOffset.z = 20.0f; - Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); - Matrix_StatePop(); + Matrix_MultVec3f(&effectVelOffset, &effectVel); + Matrix_Pop(); 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); @@ -420,7 +454,7 @@ void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { if (this->unk1F4[0] != 0) { this->unk1F4[0]--; } - gSaveContext.weekEventReg[0x3D] |= 8; + gSaveContext.save.weekEventReg[61] |= 8; this->unk3F6 = 20; this->actionFunc = func_80BADE8C; } @@ -428,7 +462,7 @@ void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { } void func_80BAB1A0(EnSuttari* this, GlobalContext* globalCtx) { - if ((this->actor.xzDistToPlayer < 500.0f) && (this->actor.yDistToPlayer < 100.0f)) { + if ((this->actor.xzDistToPlayer < 500.0f) && (this->actor.playerHeightRel < 100.0f)) { Vec3f effectVelOffset = { 0.0f, 0.0f, 0.0f }; Vec3f effectPos; Vec3f effectVel; @@ -437,13 +471,13 @@ void func_80BAB1A0(EnSuttari* this, GlobalContext* globalCtx) { effectPos.x += Math_SinS(this->actor.world.rot.y + this->unk3F4) * 350.0f; effectPos.y += 60.0f; effectPos.z += Math_CosS(this->actor.world.rot.y + this->unk3F4) * 350.0f; - Matrix_StatePush(); - Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); effectVelOffset.z = 20.0f; - Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); - Matrix_StatePop(); + Matrix_MultVec3f(&effectVelOffset, &effectVel); + Matrix_Pop(); 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); @@ -452,7 +486,7 @@ void func_80BAB1A0(EnSuttari* this, GlobalContext* globalCtx) { if (this->unk1F4[0] != 0) { this->unk1F4[0]--; } - gSaveContext.weekEventReg[0x3D] |= 8; + gSaveContext.save.weekEventReg[61] |= 8; this->unk3F6 = 20; this->actionFunc = func_80BADE8C; } else { @@ -469,7 +503,7 @@ void func_80BAB374(EnSuttari* this, GlobalContext* globalCtx) { sp38.x = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.x; sp38.y = this->actor.world.pos.y; sp38.z = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.z; - func_800BBDAC(globalCtx, &this->actor, &sp38, 10.0f, 0, 2.0f, 0, 0, 0); + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &sp38, 10.0f, 0, 2.0f, 0, 0, 0); } } @@ -479,80 +513,78 @@ void func_80BAB434(EnSuttari* this) { } void EnSuttari_GetPaths(EnSuttari* this, GlobalContext* globalCtx) { - this->paths[0] = func_8013D648(globalCtx, ENSUTTARI_GET_PATH(&this->actor), 0x3F); - this->paths[1] = func_8013D648(globalCtx, this->paths[0]->unk1, 0x3F); + this->paths[0] = SubS_GetPathByIndex(globalCtx, ENSUTTARI_GET_PATH(&this->actor), 0x3F); + this->paths[1] = SubS_GetPathByIndex(globalCtx, this->paths[0]->unk1, 0x3F); } void func_80BAB4F0(EnSuttari* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - Vec3f sp30; + Vec3f point; if (this->flags1 & 0x80) { EnSuttari_UpdateCollider(this, globalCtx); } SkelAnime_Update(&this->skelAnime); - if (!(this->flags1 & 4) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK)) { - if (func_8013D5E8(this->actor.shape.rot.y, 0x36B0, this->actor.yawTowardsPlayer) != 0) { - 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, &this->actor.shape, &this->unk2D6, &this->unk2DC, &this->unk2E2, - D_80BAE800); + if (!(this->flags1 & 4) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x36B0, this->actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->actor.focus.pos, &this->actor.shape.rot, &this->turnTarget, &this->headRot, + &this->torsoRot, &sTurnOptions); } else { - Math_SmoothStepToS(&this->unk2D6, 0, 4, 0x3E8, 1); - Math_SmoothStepToS(&this->unk2D8, 0, 4, 0x3E8, 1); - Math_SmoothStepToS(&this->unk2DC, 0, 4, 0x3E8, 1); - Math_SmoothStepToS(&this->unk2DE, 0, 4, 0x3E8, 1); - Math_SmoothStepToS(&this->unk2E2, 0, 4, 0x3E8, 1); - Math_SmoothStepToS(&this->unk2E4, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->turnTarget.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->turnTarget.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->headRot.y, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.x, 0, 4, 0x3E8, 1); + Math_SmoothStepToS(&this->torsoRot.y, 0, 4, 0x3E8, 1); } } - func_8013D9C8(globalCtx, this->unk2FA, this->unk31A, 16); + SubS_FillLimbRotTables(globalCtx, this->unk2FA, this->unk31A, ARRAY_COUNT(this->unk2FA)); } -s16 func_80BAB698(Path* path, s32 idx, Vec3f* pos, f32* distSQ) { +s16 EnSuttari_GetDistSqAndOrient(Path* path, s32 index, Vec3f* pos, f32* distSq) { Vec3s* points; f32 diffX; f32 diffZ; if (path != NULL) { - points = (Vec3s*)Lib_SegmentedToVirtual(path->points); - points = &points[idx]; + points = Lib_SegmentedToVirtual(path->points); + points = &points[index]; diffX = points->x - pos->x; diffZ = points->z - pos->z; } else { diffX = 0.0f; diffZ = 0.0f; } - *distSQ = SQ(diffX) + SQ(diffZ); - return Math_Acot2F(diffZ, diffX) * (0x8000 / M_PI); + + *distSq = SQ(diffX) + SQ(diffZ); + return RADF_TO_BINANG(Math_Acot2F(diffZ, diffX)); } s32 func_80BAB758(EnSuttari* this, Path* path, s32 arg2) { Vec3s* sp5C = Lib_SegmentedToVirtual(path->points); - s32 sp58; + s32 sp58 = path->count; + s32 index = arg2; + s32 ret = false; f32 sp54; - s32 ret; - s32 pad4C; f32 sp48; f32 sp44; f32 sp40; f32 sp3C; Vec3f sp30; - if (sp5C[arg2].x) {} - sp58 = path->count; - ret = false; - Math_Vec3s_ToVec3f(&sp30, &sp5C[arg2]); - if (arg2 == 0) { + Math_Vec3s_ToVec3f(&sp30, &sp5C[index]); + if (index == 0) { sp54 = sp5C[1].x - sp5C[0].x; sp48 = sp5C[1].z - sp5C[0].z; - } else if (arg2 == sp58 - 1) { + } else if (index == sp58 - 1) { sp54 = sp5C[sp58 - 1].x - sp5C[sp58 - 2].x; sp48 = sp5C[sp58 - 1].z - sp5C[sp58 - 2].z; } else { - sp54 = sp5C[arg2 + 1].x - sp5C[arg2 - 1].x; - sp48 = sp5C[arg2 + 1].z - sp5C[arg2 - 1].z; + sp54 = sp5C[index + 1].x - sp5C[index - 1].x; + sp48 = sp5C[index + 1].z - sp5C[index - 1].z; } func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(sp54, sp48)), &sp44, &sp40, &sp3C); if (((sp44 * this->actor.world.pos.x) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) { @@ -563,29 +595,26 @@ s32 func_80BAB758(EnSuttari* this, Path* path, s32 arg2) { s32 func_80BAB8F4(EnSuttari* this, Path* path, s32 arg2) { Vec3s* sp5C = Lib_SegmentedToVirtual(path->points); - s32 sp58; + s32 sp58 = path->count; + s32 index = arg2; + s32 ret = false; f32 sp54; - s32 ret; - s32 pad4C; f32 sp48; f32 sp44; f32 sp40; f32 sp3C; Vec3f sp30; - if (sp5C[arg2 - 1].x) {} - sp58 = path->count; - ret = false; - Math_Vec3s_ToVec3f(&sp30, &sp5C[arg2]); - if (arg2 == 0) { + Math_Vec3s_ToVec3f(&sp30, &sp5C[index]); + if (index == 0) { sp54 = sp5C[0].x - sp5C[1].x; sp48 = sp5C[0].z - sp5C[1].z; - } else if (arg2 == sp58 - 1) { + } else if (index == sp58 - 1) { sp54 = sp5C[sp58 - 2].x - sp5C[sp58 - 1].x; sp48 = sp5C[sp58 - 2].z - sp5C[sp58 - 1].z; } else { - sp54 = sp5C[arg2 - 1].x - sp5C[arg2 + 1].x; - sp48 = sp5C[arg2 - 1].z - sp5C[arg2 + 1].z; + sp54 = sp5C[index - 1].x - sp5C[index + 1].x; + sp48 = sp5C[index - 1].z - sp5C[index + 1].z; } func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(sp54, sp48)), &sp44, &sp40, &sp3C); if (((sp44 * this->actor.world.pos.x) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) { @@ -599,7 +628,7 @@ void func_80BABA90(EnSuttari* this, s32 arg1, u8 arg2) { f32 dist; if (this->paths[arg1] != NULL) { - target = func_80BAB698(this->paths[arg1], this->unk1F4[arg1], &this->actor.world.pos, &dist); + target = EnSuttari_GetDistSqAndOrient(this->paths[arg1], this->unk1F4[arg1], &this->actor.world.pos, &dist); if (this->actor.bgCheckFlags & 8) { if (arg2 == 2) { this->unk1F4[arg1] = -0x63; @@ -628,7 +657,7 @@ void func_80BABB90(EnSuttari* this, s32 arg1) { f32 sp30; if (this->paths[arg1] != NULL) { - target = func_80BAB698(this->paths[arg1], this->unk1F4[arg1], &this->actor.world.pos, &sp30); + target = EnSuttari_GetDistSqAndOrient(this->paths[arg1], this->unk1F4[arg1], &this->actor.world.pos, &sp30); if (this->actor.bgCheckFlags & 8) { target = this->actor.wallYaw; } @@ -644,16 +673,16 @@ void func_80BABB90(EnSuttari* this, s32 arg1) { } } -s32 func_80BABC48(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg2* unkStruct) { - u16 sp26 = gSaveContext.time - 0x3FFC; +s32 func_80BABC48(EnSuttari* this, GlobalContext* globalCtx, ScheduleResult* unkStruct) { + u16 sp26 = SCHEDULE_TIME_NOW; u16 pad1; u8 sp23 = ENSUTTARI_GET_PATH(&this->actor); u16 pad2; - UNK_TYPE sp1C = D_80BAE8F8[unkStruct->unk0]; + UNK_TYPE sp1C = D_80BAE8F8[unkStruct->result]; u16 phi_a0; if (sp1C >= 0) { - this->unk404 = func_8013BB34(globalCtx, sp23, sp1C); + this->unk404 = SubS_GetAdditionalPath(globalCtx, sp23, sp1C); } if (this->unk404 == NULL) { return 0; @@ -661,12 +690,12 @@ s32 func_80BABC48(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg if ((this->unk428 != 0 && this->unk428 < 0xC) && (this->unk42A >= 0)) { phi_a0 = sp26; } else { - phi_a0 = unkStruct->unk4; + phi_a0 = unkStruct->time0; } - if (unkStruct->unk8 < phi_a0) { - this->unk418 = (phi_a0 - unkStruct->unk8) + 0xFFFF; + if (unkStruct->time1 < phi_a0) { + this->unk418 = (phi_a0 - unkStruct->time1) + 0xFFFF; } else { - this->unk418 = unkStruct->unk8 - phi_a0; + this->unk418 = unkStruct->time1 - phi_a0; } this->unk424 = sp26 - phi_a0; phi_a0 = this->unk404->count - 2; @@ -677,7 +706,7 @@ s32 func_80BABC48(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg return 1; } -s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg2* unkStruct) { +s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, ScheduleResult* unkStruct) { s32 pad; EnDoor* sp48; u8 sp47; @@ -688,25 +717,25 @@ s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg UNK_TYPE sp24; sp47 = ENSUTTARI_GET_PATH(&this->actor); - sp44 = gSaveContext.time - 0x3FFC; + sp44 = SCHEDULE_TIME_NOW; if (this->unk428 == 10 || this->unk428 == 11 || this->unk428 == 2) { return 0; } - sp48 = (EnDoor*)func_8013BB7C(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR); - sp24 = D_80BAE8F8[unkStruct->unk0]; + sp48 = (EnDoor*)SubS_FindNearestActor(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR); + sp24 = D_80BAE8F8[unkStruct->result]; if ((sp48 != NULL) && (sp24 >= 0)) { - this->unk404 = func_8013BB34(globalCtx, sp47, sp24); + this->unk404 = SubS_GetAdditionalPath(globalCtx, sp47, sp24); } if ((sp48 == NULL) || (this->unk404 == NULL)) { return 0; } - sp28 = (Vec3s*)Lib_SegmentedToVirtual(this->unk404->points); + sp28 = Lib_SegmentedToVirtual(this->unk404->points); Math_Vec3s_ToVec3f(&sp38, &sp28[0]); Math_Vec3s_ToVec3f(&sp2C, &sp28[1]); - this->unk434 = sp44 - unkStruct->unk4; - this->unk436 = unkStruct->unk8 - unkStruct->unk4; - if (unkStruct->unk0 != 10 && unkStruct->unk0 != 11) { - sp48->unk1A7 = 0x4B; + this->unk434 = sp44 - unkStruct->time0; + this->unk436 = unkStruct->time1 - unkStruct->time0; + if (unkStruct->result != 10 && unkStruct->result != 11) { + sp48->unk_1A7 = 0x4B; } Math_Vec3f_Copy(&this->unk438, &sp38); Math_Vec3f_Copy(&this->unk444, &sp2C); @@ -715,10 +744,10 @@ s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg return 1; } -s32 func_80BABF64(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg2* unkStruct) { +s32 func_80BABF64(EnSuttari* this, GlobalContext* globalCtx, ScheduleResult* unkStruct) { s32 ret; - switch (unkStruct->unk0) { + switch (unkStruct->result) { case 15: case 14: case 13: @@ -748,20 +777,18 @@ s32 func_80BABF64(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg } s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { - UNK_TYPE1 sp7C[0x424]; + f32 sp7C[265]; Vec3f sp70; Vec3f sp64; Vec3f sp58; - s32 sp54; - s32 sp50; + s32 sp54 = 0; + s32 sp50 = 0; s32 pad; - sp54 = 0; - sp50 = 0; - func_8013AF00(&sp7C, 3, this->unk404->count + 3); + func_8013AF00(sp7C, 3, this->unk404->count + 3); if (this->unk42C == 0) { - sp58 = D_801D15B0; - func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, &sp7C, + 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); this->actor.world.pos.y = sp58.y; @@ -771,13 +798,13 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { } this->actor.world.pos.x = sp58.x; this->actor.world.pos.z = sp58.z; - if (func_8013AD6C(globalCtx)) { + if (SubS_InCsMode(globalCtx)) { sp54 = this->unk424; sp50 = this->unk420; sp58 = this->actor.world.pos; } - this->unk408 = D_801D15B0; - if (func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, &sp7C, + 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; } else { @@ -785,7 +812,7 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { sp64 = this->unk408; this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); } - if (func_8013AD6C(globalCtx)) { + if (SubS_InCsMode(globalCtx)) { this->unk424 = sp54; this->unk420 = sp50; this->unk408 = sp58; @@ -817,7 +844,7 @@ s32 func_80BAC220(EnSuttari* this, GlobalContext* globalCtx) { void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); switch (this->unk428) { case 12: @@ -826,11 +853,11 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { func_80BABFD4(this, globalCtx); break; case 15: - if ((this->animationIdx == 1) && (curFrame == frameCount)) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if ((this->animationIndex == 1) && (curFrame == frameCount)) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } - if (!(gSaveContext.weekEventReg[0x53] & 4) && !(this->flags1 & 0x1000)) { + if (!(gSaveContext.save.weekEventReg[83] & 4) && !(this->flags1 & 0x1000)) { if (ActorCutscene_GetCanPlayNext(this->cutscenes[0])) { ActorCutscene_Start(this->cutscenes[0], &this->actor); if (!(player->stateFlags1 & 0x10000000)) { @@ -859,9 +886,9 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { this->flags1 |= 0x80; this->flags1 |= 0x20; this->enFsn->flags &= ~ENFSN_HAGGLE; - if (this->animationIdx != 2) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if (this->animationIndex != 2) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } func_80BAC220(this, globalCtx); break; @@ -879,7 +906,7 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); break; case 2: - if (!(gSaveContext.weekEventReg[0x51] & 4)) { + if (!(gSaveContext.save.weekEventReg[81] & 4)) { this->flags1 |= 0x80; this->actor.world.pos.x = -16.0f; this->actor.world.pos.z = -16.0f; @@ -889,10 +916,10 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { } break; case 4: - if (!(gSaveContext.weekEventReg[0x21] & 8)) { - if (this->animationIdx == 2 || this->animationIdx == 1) { - this->animationIdx = 5; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if (!(gSaveContext.save.weekEventReg[33] & 8)) { + if (this->animationIndex == 2 || this->animationIndex == 1) { + this->animationIndex = 5; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } this->flags1 |= 0x10; if (this->flags2 & 2) { @@ -903,7 +930,7 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { player->stateFlags1 |= 0x10000000; } this->textId = 0x2A30; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->actionFunc = func_80BAD2B4; } break; @@ -913,57 +940,58 @@ void func_80BAC2FC(EnSuttari* this, GlobalContext* globalCtx) { void func_80BAC6E8(EnSuttari* this, GlobalContext* globalCtx) { ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600C240, &D_0600071C, this->jointTable, this->morphTable, 16); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_boj_Skel_00C240, &object_boj_Anim_00071C, this->jointTable, + this->morphTable, 16); this->actor.draw = EnSuttari_Draw; - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; if (globalCtx->sceneNum == SCENE_IKANA) { this->flags1 |= 1; - if (gSaveContext.day == 1 || gSaveContext.day == 2) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if (gSaveContext.save.day == 1 || gSaveContext.save.day == 2) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->flags1 |= 0x80; this->actionFunc = func_80BACA14; return; - } else if ((gSaveContext.day == 3) && (gSaveContext.time <= CLOCK_TIME(19, 00)) && - !(gSaveContext.weekEventReg[0x3D] & 8) && !(gSaveContext.weekEventReg[0x21] & 8) && - (gSaveContext.weekEventReg[0x33] & 8)) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + } else if ((gSaveContext.save.day == 3) && (gSaveContext.save.time <= CLOCK_TIME(19, 0)) && + !(gSaveContext.save.weekEventReg[61] & 8) && !(gSaveContext.save.weekEventReg[33] & 8) && + (gSaveContext.save.weekEventReg[51] & 8)) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->actionFunc = func_80BACEE0; return; } } else if (globalCtx->sceneNum == SCENE_BACKTOWN) { - if (gSaveContext.time >= CLOCK_TIME(0, 20) && gSaveContext.time < CLOCK_TIME(6, 00)) { + if (gSaveContext.save.time >= CLOCK_TIME(0, 20) && gSaveContext.save.time < CLOCK_TIME(6, 00)) { Actor_MarkForDeath(&this->actor); } - if ((gSaveContext.entranceIndex == 0xD670) || (gSaveContext.weekEventReg[0x3A] & 0x40)) { + if ((gSaveContext.save.entranceIndex == 0xD670) || (gSaveContext.save.weekEventReg[58] & 0x40)) { Actor_MarkForDeath(&this->actor); } this->cutscenes[0] = this->actor.cutscene; this->cutscenes[1] = ActorCutscene_GetAdditionalCutscene(this->cutscenes[0]); this->flags1 |= 0x80; this->flags1 |= 8; - this->animationIdx = 1; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->actionFunc = func_80BAD004; return; } else if (globalCtx->sceneNum == SCENE_ICHIBA) { - if (gSaveContext.weekEventReg[0x21] & 8) { + if (gSaveContext.save.weekEventReg[33] & 8) { Actor_MarkForDeath(&this->actor); return; } - this->animationIdx = 0; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->flags1 |= 2; this->actionFunc = func_80BAD5F8; return; } else if (globalCtx->sceneNum == SCENE_AYASHIISHOP) { - if (gSaveContext.weekEventReg[0x21] & 8) { + if (gSaveContext.save.weekEventReg[33] & 8) { Actor_MarkForDeath(&this->actor); return; } - this->animationIdx = 0; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + this->animationIndex = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); this->cutscenes[0] = this->actor.cutscene; this->cutscenes[1] = ActorCutscene_GetAdditionalCutscene(this->cutscenes[0]); this->flags1 |= 4; @@ -981,20 +1009,20 @@ void func_80BAC6E8(EnSuttari* this, GlobalContext* globalCtx) { void func_80BACA14(EnSuttari* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (this->animationIdx == 1 || this->animationIdx == 8) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if (this->animationIndex == 1 || this->animationIndex == 8) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } func_80BABA90(this, 0, 0); func_80BAB434(this); if (player->transformation == PLAYER_FORM_GORON || player->transformation == PLAYER_FORM_ZORA) { - if (this->actor.yDistToPlayer < 60.0f && this->actor.xzDistToPlayer < 500.0f) { - this->unk3F2 = this->unk2DE; + if (this->actor.playerHeightRel < 60.0f && this->actor.xzDistToPlayer < 500.0f) { + this->unk3F2 = this->headRot.y; this->actionFunc = func_80BACBB0; } - } else if ((player->transformation == PLAYER_FORM_HUMAN) && CUR_EQUIP_VALUE_VOID(EQUIP_SWORD) != 0) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->unk3F2 = this->unk2DE; + } else if ((player->transformation == PLAYER_FORM_HUMAN) && GET_CUR_EQUIP_VALUE(EQUIP_SWORD) != 0) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk3F2 = this->headRot.y; func_80BAAB78(this, globalCtx); this->actionFunc = func_80BADA9C; } else if (this->actor.xzDistToPlayer < 200.0f) { @@ -1002,18 +1030,18 @@ void func_80BACA14(EnSuttari* this, GlobalContext* globalCtx) { } } Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 0.1f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BACBB0(EnSuttari* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 target; - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; if (player->transformation == PLAYER_FORM_HUMAN || player->transformation == PLAYER_FORM_DEKU) { this->actionFunc = func_80BACA14; } - if ((this->actor.yDistToPlayer < 60.0f) && (this->actor.xzDistToPlayer < 500.0f)) { + if ((this->actor.playerHeightRel < 60.0f) && (this->actor.xzDistToPlayer < 500.0f)) { if (this->actor.bgCheckFlags & 8) { target = this->actor.wallYaw; } else if (func_80BAA904(this, globalCtx)) { @@ -1028,7 +1056,7 @@ void func_80BACBB0(EnSuttari* this, GlobalContext* globalCtx) { this->actionFunc = func_80BACD2C; this->actor.speedXZ = 0.0f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (!(this->actor.bgCheckFlags & 1)) { this->actor.world.pos = this->actor.prevPos; this->actor.world.rot.y = -this->actor.world.rot.y; @@ -1039,18 +1067,18 @@ void func_80BACBB0(EnSuttari* this, GlobalContext* globalCtx) { void func_80BACD2C(EnSuttari* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; if (player->transformation == PLAYER_FORM_HUMAN || player->transformation == PLAYER_FORM_DEKU) { this->actionFunc = func_80BACA14; } - if ((this->actor.yDistToPlayer < 60.0f) && (this->actor.xzDistToPlayer < 500.0f)) { + if ((this->actor.playerHeightRel < 60.0f) && (this->actor.xzDistToPlayer < 500.0f)) { this->actionFunc = func_80BACBB0; Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 0.1f); } else { Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 4, 0x3E8, 1); this->actor.shape.rot.y = this->actor.world.rot.y; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (!(this->actor.bgCheckFlags & 1)) { this->actor.world.pos = this->actor.prevPos; this->actor.world.rot.y = -this->actor.world.rot.y; @@ -1062,7 +1090,7 @@ void func_80BACE4C(EnSuttari* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer > 100.0f) { this->actionFunc = func_80BACBB0; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); if (this->actor.world.pos.y != this->actor.floorHeight) { this->actor.world.pos = this->actor.prevPos; this->actor.world.rot.y = -this->actor.world.rot.y; @@ -1071,58 +1099,56 @@ void func_80BACE4C(EnSuttari* this, GlobalContext* globalCtx) { } void func_80BACEE0(EnSuttari* this, GlobalContext* globalCtx) { - u32* unk_14 = &gSaveContext.unk_14; - struct_80133038_arg2 unkStruct; + ScheduleResult unkStruct; - this->unk42A = REG(15) + *unk_14; - if (!func_80133038(globalCtx, D_80BAE820, &unkStruct) || - ((this->unk428 != unkStruct.unk0) && !func_80BABF64(this, globalCtx, &unkStruct))) { - this->actor.flags &= ~1; - unkStruct.unk0 = 0; + this->unk42A = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BAE820, &unkStruct) || + ((this->unk428 != unkStruct.result) && !func_80BABF64(this, globalCtx, &unkStruct))) { + this->actor.flags &= ~ACTOR_FLAG_1; + unkStruct.result = 0; } else { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } - this->unk428 = unkStruct.unk0; + this->unk428 = unkStruct.result; func_80BAC2FC(this, globalCtx); func_80BAB434(this); if (this->unk428 == 5) { - gSaveContext.weekEventReg[0x3A] |= 0x80; + gSaveContext.save.weekEventReg[58] |= 0x80; this->actionFunc = func_80BADDB4; this->actor.speedXZ = 0.0f; - } else if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) { + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) { func_80BAB1A0(this, globalCtx); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BAD004(EnSuttari* this, GlobalContext* globalCtx) { - u32* unk_14 = &gSaveContext.unk_14; - struct_80133038_arg2 unkStruct; + ScheduleResult unkStruct; - this->unk42A = REG(15) + *unk_14; - if (!func_80133038(globalCtx, D_80BAE820, &unkStruct) || - ((this->unk428 != unkStruct.unk0) && !func_80BABF64(this, globalCtx, &unkStruct))) { - this->actor.flags &= ~1; - unkStruct.unk0 = 0; + this->unk42A = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BAE820, &unkStruct) || + ((this->unk428 != unkStruct.result) && !func_80BABF64(this, globalCtx, &unkStruct))) { + this->actor.flags &= ~ACTOR_FLAG_1; + unkStruct.result = 0; } else { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } - this->unk428 = unkStruct.unk0; + this->unk428 = unkStruct.result; func_80BAC2FC(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x2A3A, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x2A3A, &this->actor); this->actionFunc = func_80BAD130; } else if ((this->actor.xzDistToPlayer < 200.0f) || this->actor.isTargeted) { func_800B863C(&this->actor, globalCtx); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BAD130(EnSuttari* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); - if ((talkState == 5 || talkState == 6) && func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if ((talkState == 5 || talkState == 6) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; if (this->flags1 & 8) { this->actionFunc = func_80BAD004; @@ -1142,9 +1168,9 @@ void func_80BAD230(EnSuttari* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->cutscenes[1])) { ActorCutscene_Start(this->cutscenes[1], &this->actor); this->textId = 0x2A31; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->flags1 |= 0x4000; - Audio_QueueSeqCmd(0x8003); + Audio_QueueSeqCmd(NA_BGM_CHASE | 0x8000); this->actionFunc = func_80BAD380; } else { ActorCutscene_SetIntentToPlay(this->cutscenes[1]); @@ -1152,14 +1178,14 @@ void func_80BAD230(EnSuttari* this, GlobalContext* globalCtx) { } void func_80BAD2B4(EnSuttari* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { if (this->textId == 0x2A30) { ActorCutscene_Stop(this->cutscenes[0]); ActorCutscene_SetIntentToPlay(this->cutscenes[1]); this->actionFunc = func_80BAD230; } else { ActorCutscene_Stop(this->cutscenes[1]); - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->flags1 |= 0x40; this->actionFunc = func_80BAD380; @@ -1169,21 +1195,21 @@ void func_80BAD2B4(EnSuttari* this, GlobalContext* globalCtx) { } void func_80BAD380(EnSuttari* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); - if ((player->stateFlags1 & 0x40) && (globalCtx->msgCtx.unk11F04 != 0x2A31)) { + if ((player->stateFlags1 & 0x40) && (globalCtx->msgCtx.currentTextId != 0x2A31)) { this->flags1 |= 0x8000; this->actor.speedXZ = 0.0f; } else { this->flags1 &= ~0x8000; func_80BABA90(this, 1, 1); - if ((this->flags1 & 0x4000) && (talkState == 5) && func_80147624(globalCtx)) { + if ((this->flags1 & 0x4000) && (talkState == 5) && Message_ShouldAdvance(globalCtx)) { this->flags2 &= ~0x10; player->stateFlags1 &= ~0x10000000; this->flags1 &= ~0x4000; ActorCutscene_Stop(this->cutscenes[1]); - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->flags1 |= 0x40; } @@ -1191,142 +1217,140 @@ void func_80BAD380(EnSuttari* this, GlobalContext* globalCtx) { this->flags2 |= 8; func_80BAAF1C(this); } else if (this->flags1 & 0x200) { - gSaveContext.weekEventReg[0x4F] |= 0x40; + gSaveContext.save.weekEventReg[79] |= 0x40; this->flags2 |= 4; this->actor.speedXZ = 0.0f; 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_SMALL_EXPLOSION); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_IT_BOMB_EXPLOSION); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_IT_BOMB_EXPLOSION); Actor_MarkForDeath(&this->actor); return; } if (this->unk1F4[1] == -0x63) { if (this->flags2 & 8) { - gSaveContext.weekEventReg[0x21] |= 8; + gSaveContext.save.weekEventReg[33] |= 8; } this->actor.speedXZ = 0.0f; Audio_QueueSeqCmd(0x101400FF); this->flags2 |= 4; EnSuttari_SetNextEntrance(globalCtx, 0xD670); } else { - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; Math_ApproachF(&this->actor.speedXZ, 4.0f, 0.2f, 0.5f); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_80BAB374(this, globalCtx); } } } void func_80BAD5F8(EnSuttari* this, GlobalContext* globalCtx) { - u32* unk_14 = &gSaveContext.unk_14; - struct_80133038_arg2 unkStruct; + ScheduleResult unkStruct; s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); - if ((curFrame == frameCount) && (this->animationIdx == 0) && (this->flags1 & 0x20)) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if ((curFrame == frameCount) && (this->animationIndex == 0) && (this->flags1 & 0x20)) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } - this->unk42A = REG(15) + *unk_14; - if (!func_80133038(globalCtx, D_80BAE820, &unkStruct) || - ((this->unk428 != unkStruct.unk0) && !func_80BABF64(this, globalCtx, &unkStruct))) { - this->actor.flags &= ~1; - unkStruct.unk0 = 0; + this->unk42A = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BAE820, &unkStruct) || + ((this->unk428 != unkStruct.result) && !func_80BABF64(this, globalCtx, &unkStruct))) { + this->actor.flags &= ~ACTOR_FLAG_1; + unkStruct.result = 0; } else { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } - this->unk428 = unkStruct.unk0; + this->unk428 = unkStruct.result; func_80BAC2FC(this, globalCtx); if ((this->unk430 == 1) && (this->unk404->unk1 == 0xFF)) { Actor_MarkForDeath(&this->actor); return; } func_80BAB434(this); - if ((this->flags1 & 0x20) && (this->unk430 == 0) && (unkStruct.unk0 != 7)) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x2A02, &this->actor); + if ((this->flags1 & 0x20) && (this->unk430 == 0) && (unkStruct.result != 7)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x2A02, &this->actor); this->actionFunc = func_80BAD130; } else if ((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) { func_800B863C(&this->actor, globalCtx); } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BAD7F8(EnSuttari* this, GlobalContext* globalCtx) { - u32* unk_14 = &gSaveContext.unk_14; - struct_80133038_arg2 unkStruct; + ScheduleResult unkStruct; s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); if (this->enFsn == NULL) { this->enFsn = (EnFsn*)EnSuttari_GetActorById(globalCtx, ACTOR_EN_FSN); } else { - if ((this->flags1 & 0x2000) && (this->animationIdx == 1) && (curFrame == frameCount)) { - this->animationIdx = 2; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + if ((this->flags1 & 0x2000) && (this->animationIndex == 1) && (curFrame == frameCount)) { + this->animationIndex = 2; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } - this->unk42A = REG(15) + *unk_14; - if (!func_80133038(globalCtx, D_80BAE820, &unkStruct) || - ((this->unk428 != unkStruct.unk0) && !func_80BABF64(this, globalCtx, &unkStruct))) { - this->actor.flags &= ~1; - unkStruct.unk0 = 0; + this->unk42A = REG(15) + ((void)0, gSaveContext.save.daySpeed); + if (!Schedule_RunScript(globalCtx, D_80BAE820, &unkStruct) || + ((this->unk428 != unkStruct.result) && !func_80BABF64(this, globalCtx, &unkStruct))) { + this->actor.flags &= ~ACTOR_FLAG_1; + unkStruct.result = 0; } else { - this->actor.flags |= 1; + this->actor.flags |= ACTOR_FLAG_1; } - this->unk428 = unkStruct.unk0; + this->unk428 = unkStruct.result; func_80BAC2FC(this, globalCtx); if ((this->unk430 == 1) && (this->unk404->unk1 == 0xFF)) { Actor_MarkForDeath(&this->actor); return; } - if ((this->flags1 & 0x20) && (unkStruct.unk0 != 9)) { - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x2A02, &this->actor); + if ((this->flags1 & 0x20) && (unkStruct.result != 9)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x2A02, &this->actor); this->actionFunc = func_80BAD130; } else if ((this->actor.xzDistToPlayer < 100.0f) || this->actor.isTargeted) { func_800B863C(&this->actor, globalCtx); } } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } } void func_80BADA08(EnSuttari* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; func_80BAAB78(this, globalCtx); - gSaveContext.weekEventReg[0x51] |= 4; + gSaveContext.save.weekEventReg[81] |= 4; } else if (this->actor.xzDistToPlayer < 500.0f) { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 500.0f); } } void func_80BADA9C(EnSuttari* this, GlobalContext* globalCtx) { - u8 talkstate = func_80152498(&globalCtx->msgCtx); + u8 talkstate = Message_GetState(&globalCtx->msgCtx); s16 curFrame = this->skelAnime.curFrame; - s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIdx].animation); + s16 frameCount = Animation_GetLastFrame(sAnimations[this->animationIndex].animation); if (this->flags1 & 1) { - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; func_80BAA9B4(this); - } else if ((this->animationIdx == 7) && (curFrame == frameCount)) { - this->animationIdx = 1; - func_800BDC5C(&this->skelAnime, sAnimations, this->animationIdx); + } else if ((this->animationIndex == 7) && (curFrame == frameCount)) { + this->animationIndex = 1; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, this->animationIndex); } if (talkstate == 5) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (this->flags1 & 0x400) { if (this->textId == 0x29EE) { ActorCutscene_Stop(this->cutscenes[this->cutsceneIdx]); } 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; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->textId = 0; if (this->flags1 & 1) { @@ -1338,7 +1362,7 @@ void func_80BADA9C(EnSuttari* this, GlobalContext* globalCtx) { } func_80BAAB78(this, globalCtx); } - } else if ((talkstate == 4) && func_80147624(globalCtx)) { + } else if ((talkstate == 4) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); @@ -1374,10 +1398,10 @@ void func_80BADD0C(EnSuttari* this, GlobalContext* globalCtx) { void func_80BADDB4(EnSuttari* this, GlobalContext* globalCtx) { func_80BABA90(this, 1, 1); func_80BAB434(this); - if (gSaveContext.weekEventReg[0x33] & 0x10) { + if (gSaveContext.save.weekEventReg[51] & 0x10) { this->actionFunc = func_80BADE14; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BADE14(EnSuttari* this, GlobalContext* globalCtx) { @@ -1385,21 +1409,21 @@ void func_80BADE14(EnSuttari* this, GlobalContext* globalCtx) { if (this->unk1F4[1] == -0x63) { this->actor.speedXZ = 0.0f; } else { - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 0.5f); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void func_80BADE8C(EnSuttari* this, GlobalContext* globalCtx) { - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0xBB8, 0); - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; - func_801518B0(globalCtx, 0x2A3A, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + Message_StartTextbox(globalCtx, 0x2A3A, &this->actor); this->actionFunc = func_80BAD130; } else { - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 500.0f); } } @@ -1409,25 +1433,25 @@ void func_80BADF3C(EnSuttari* this, GlobalContext* globalCtx) { if (this->unk1F4[0] == -0x63) { Actor_MarkForDeath(&this->actor); } - this->unk3F2 = this->unk2DE; + this->unk3F2 = this->headRot.y; if (DECR(this->unk3F6) == 0) { Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 0.5f); } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } void EnSuttari_Init(Actor* thisx, GlobalContext* globalCtx) { EnSuttari* this = THIS; s32 pad; - if (gSaveContext.weekEventReg[0x4F] & 0x40) { + if (gSaveContext.save.weekEventReg[79] & 0x40) { Actor_MarkForDeath(&this->actor); return; } Collider_InitCylinder(globalCtx, &this->collider); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; EnSuttari_GetPaths(this, globalCtx); Actor_SetScale(&this->actor, 0.01f); this->actionFunc = func_80BAC6E8; @@ -1459,13 +1483,13 @@ void EnSuttari_Update(Actor* thisx, GlobalContext* globalCtx) { EnSuttari_UpdateTime(); } if (this->unk428 != 0) { - if (this->animationIdx == 2 || this->animationIdx == 6) { + if (this->animationIndex == 2 || this->animationIndex == 6) { if (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 16.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } - } else if (this->animationIdx == 0 || this->animationIdx == 5) { + } else if (this->animationIndex == 0 || this->animationIndex == 5) { if (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 17.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PAMERA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PAMERA_WALK); } } } @@ -1476,17 +1500,17 @@ s32 EnSuttari_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL EnSuttari* this = THIS; if (limbIndex == 15) { - *dList = D_0600AF90; + *dList = object_boj_DL_00AF90; if (!(this->flags1 & 4)) { - Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk3F2, MTXMODE_APPLY); - Matrix_InsertZRotation_s(-this->unk2DC, MTXMODE_APPLY); - Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk3F2, MTXMODE_APPLY); + Matrix_RotateZS(-this->headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); } } if (limbIndex == 8) { - Matrix_InsertXRotation_s(-this->unk2E4, MTXMODE_APPLY); - Matrix_InsertZRotation_s(-this->unk2E2, MTXMODE_APPLY); + Matrix_RotateXS(-this->torsoRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->torsoRot.x, MTXMODE_APPLY); } if (limbIndex == 8 || limbIndex == 9 || limbIndex == 0xC) { rot->y += (s16)(Math_SinS(this->unk2FA[limbIndex]) * 200.0f); @@ -1506,31 +1530,31 @@ void EnSuttari_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList if (((this->flags1 & 8) && (this->flags1 & 0x10)) || ((this->flags1 & 2) && !(this->flags1 & 0x20)) || ((this->flags1 & 4) && !(this->flags1 & 0x20))) { if (limbIndex == 8) { - curState = Matrix_GetCurrentState(); - Matrix_MultiplyVector3fByState(&D_80BAE95C, &this->unk3F8); + curState = Matrix_GetCurrent(); + Matrix_MultVec3f(&D_80BAE95C, &this->unk3F8); if (this->actor.child == NULL) { if (this->flags1 & 0x100) { bombBag = Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_NIMOTSU, curState->mf[3][0], curState->mf[3][1], curState->mf[3][2], 0, 0, 0, -1); if (bombBag != NULL) { - func_8018219C(curState, &bombBag->shape.rot, 0); + Matrix_MtxFToYXZRot(curState, &bombBag->shape.rot, false); } } else { func_8012C28C(globalCtx->state.gfxCtx); OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_06013380); + gSPDisplayList(POLY_OPA_DISP++, object_boj_DL_013380); CLOSE_DISPS(globalCtx->state.gfxCtx); } } } } if (limbIndex == 15) { - Matrix_MultiplyVector3fByState(&D_80BAE950, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80BAE950, &this->actor.focus.pos); } } -void EnSuttari_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnSuttari_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { } void EnSuttari_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -1545,8 +1569,9 @@ void EnSuttari_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, 255, 255, 255, 0)); gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 55, 55, 255, 0)); gDPPipeSync(POLY_OPA_DISP++); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSuttari_OverrideLimbDraw, EnSuttari_PostLimbDraw, EnSuttari_UnkDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnSuttari_OverrideLimbDraw, EnSuttari_PostLimbDraw, + EnSuttari_TransformLimbDraw, &this->actor); if (this->flags1 & 0x80) { func_8012C2DC(globalCtx->state.gfxCtx); sp5C = this->actor.world.pos; diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h index 93423fe77..2fbdff53b 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.h @@ -27,15 +27,10 @@ typedef struct EnSuttari { /* 0x1FC */ UNK_TYPE1 unk_1FC[0x1A]; /* 0x216 */ Vec3s jointTable[16]; /* 0x276 */ Vec3s morphTable[16]; - /* 0x2D6 */ s16 unk2D6; - /* 0x2D8 */ s16 unk2D8; - /* 0x2DA */ UNK_TYPE1 unk_2DA[0x2]; - /* 0x2DC */ s16 unk2DC; - /* 0x2DE */ s16 unk2DE; - /* 0x2E0 */ UNK_TYPE1 unk_2E0[0x2]; - /* 0x2E2 */ s16 unk2E2; - /* 0x2E4 */ s16 unk2E4; - /* 0x2E6 */ UNK_TYPE1 unk_2E6[0x14]; + /* 0x2D6 */ Vec3s turnTarget; + /* 0x2DC */ Vec3s headRot; + /* 0x2E2 */ Vec3s torsoRot; + /* 0x2E8 */ UNK_TYPE1 unk_2E8[0x12]; /* 0x2FA */ s16 unk2FA[16]; /* 0x31A */ s16 unk31A[16]; /* 0x33A */ UNK_TYPE1 unk_33A[0xB6]; @@ -46,7 +41,7 @@ typedef struct EnSuttari { /* 0x3F8 */ Vec3f unk3F8; /* 0x404 */ Path* unk404; /* 0x408 */ Vec3f unk408; - /* 0x414 */ s32 unk414; + /* 0x414 */ f32 unk414; /* 0x418 */ s32 unk418; /* 0x41C */ s32 unk41C; /* 0x420 */ s32 unk420; @@ -60,7 +55,7 @@ typedef struct EnSuttari { /* 0x436 */ s16 unk436; /* 0x438 */ Vec3f unk438; /* 0x444 */ Vec3f unk444; - /* 0x450 */ s32 animationIdx; + /* 0x450 */ s32 animationIndex; /* 0x454 */ UNK_TYPE1 unk_454[0x2]; /* 0x456 */ s16 cutscenes[2]; /* 0x45A */ s16 cutsceneIdx; 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 9cc79183e..0188b323c 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -5,8 +5,9 @@ */ #include "z_en_sw.h" +#include "objects/object_st/object_st.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnSw*)thisx) @@ -27,21 +28,6 @@ void func_808DB100(EnSw* this, GlobalContext* globalCtx); void func_808DB25C(EnSw* this, GlobalContext* globalCtx); void func_808DB2E0(EnSw* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000304; -extern Gfx D_06003FB0[]; -extern Gfx D_060043D8[]; -extern Gfx D_060045C0[]; -extern Gfx D_06004658[]; -extern Gfx D_060046F0[]; -extern Gfx D_06004788[]; -extern Gfx D_06004820[]; -extern Gfx D_060048B8[]; -extern Gfx D_06004950[]; -extern Gfx D_060049E8[]; -extern SkeletonHeader D_06005298; -extern AnimationHeader D_060055A8; -extern AnimationHeader D_06005B98; - const ActorInit En_Sw_InitVars = { ACTOR_EN_SW, ACTORCAT_NPC, @@ -148,11 +134,11 @@ static DamageTable sDamageTable2 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -static ActorAnimationEntryS sAnimations[] = { - { &D_06000304, 1.0f, 0, -1, 3, 0 }, - { &D_06000304, 1.0f, 0, -1, 3, -4 }, - { &D_060055A8, 1.0f, 0, -1, 1, -4 }, - { &D_06005B98, 1.0f, 0, -1, 1, -4 }, +static AnimationInfoS sAnimations[] = { + { &object_st_Anim_000304, 1.0f, 0, -1, ANIMMODE_ONCE_INTERP, 0 }, + { &object_st_Anim_000304, 1.0f, 0, -1, ANIMMODE_ONCE_INTERP, -4 }, + { &object_st_Anim_0055A8, 1.0f, 0, -1, ANIMMODE_LOOP_INTERP, -4 }, + { &object_st_Anim_005B98, 1.0f, 0, -1, ANIMMODE_LOOP_INTERP, -4 }, }; void func_808D8940(EnSw* this, GlobalContext* globalCtx) { @@ -174,11 +160,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); @@ -190,14 +176,15 @@ s32 func_808D8B58(EnSw* this) { s32 i; for (i = 0; i < ARRAY_COUNT(this->unk_464); i++, phi_s2 += 0x1555) { - if (this->unk_412 != 10) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { this->unk_464[i] = (Rand_ZeroOne() * 16.0f) + 8.0f; } else { this->unk_464[i] = 80; } this->unk_47C[i] = this->unk_464[i]; - this->unk_418[i] = 0.45000002f; - if ((this->unk_412 == 0) || (this->unk_412 == 1) || (this->unk_412 == 10)) { + this->drawDmgEffFrozenSteamScales[i] = 0.45000002f; + if ((this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) || (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_BLUE_FIRE) || + (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) { this->unk_380[i].y = (Rand_ZeroOne() - 0.5f) * 20.0f; } else { this->unk_380[i].y = ((Rand_ZeroOne() - 0.5f) * 20.0f) + 10.0f; @@ -211,26 +198,27 @@ s32 func_808D8B58(EnSw* this) { s32 func_808D8D60(EnSw* this, GlobalContext* globalCtx, s32 arg2) { s32 ret = false; - u8 sp53; - Vec3f sp44; - f32 sp40; + u8 drawDmgEffType; + Vec3f limbPos[1]; + f32 drawDmgEffAlpha; if (arg2 < this->unk_462) { if (this->unk_464[arg2] != 0) { - sp40 = (f32)this->unk_464[arg2] / this->unk_47C[arg2]; - sp53 = this->unk_412; - Math_ApproachF(&this->unk_418[arg2], 0.3f, 0.3f, 0.5f); - Math_Vec3f_Copy(&sp44, &this->actor.world.pos); - sp44.x += this->unk_380[arg2].x; - sp44.y += this->unk_380[arg2].y; - sp44.z += this->unk_380[arg2].z; - if (sp53 == 10) { + drawDmgEffAlpha = (f32)this->unk_464[arg2] / this->unk_47C[arg2]; + drawDmgEffType = this->drawDmgEffType; + Math_ApproachF(&this->drawDmgEffFrozenSteamScales[arg2], 0.3f, 0.3f, 0.5f); + Math_Vec3f_Copy(&limbPos[0], &this->actor.world.pos); + limbPos[0].x += this->unk_380[arg2].x; + limbPos[0].y += this->unk_380[arg2].y; + limbPos[0].z += this->unk_380[arg2].z; + if (drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { if ((this->unk_47C[arg2] - this->unk_464[arg2]) < 20) { - sp53 = 11; + drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_SFX; } - sp40 = 1.0f; + drawDmgEffAlpha = 1.0f; } - func_800BE680(globalCtx, &this->actor, &sp44, 1, 0.3f, this->unk_418[arg2], sp40, sp53); + Actor_DrawDamageEffects(globalCtx, &this->actor, limbPos, ARRAY_COUNT(limbPos), 0.3f, + this->drawDmgEffFrozenSteamScales[arg2], drawDmgEffAlpha, drawDmgEffType); ret = true; } } @@ -248,7 +236,7 @@ void func_808D8ED0(EnSw* this, GlobalContext* globalCtx) { sp54.z += this->unk_380[i].z; Math_Vec3f_Copy(&this->unk_380[i], &sp54); } - func_800BF7CC(globalCtx, &this->actor, this->unk_380, ARRAY_COUNT(this->unk_380), 3, 0.1f, 0.3f); + Actor_SpawnIceEffects(globalCtx, &this->actor, this->unk_380, ARRAY_COUNT(this->unk_380), 3, 0.1f, 0.3f); } void func_808D8FC4(EnSw* this, GlobalContext* globalCtx) { @@ -289,8 +277,8 @@ void func_808D90F0(EnSw* this, s32 arg1, s16 arg2) { temp = arg2; } - Matrix_InsertRotationAroundUnitVector_f(BINANG_TO_RAD(temp), &this->unk_368, 0); - Matrix_MultiplyVector3fByState(&this->unk_350, &sp2C); + Matrix_RotateAxisF(BINANG_TO_RAD(temp), &this->unk_368, MTXMODE_NEW); + Matrix_MultVec3f(&this->unk_350, &sp2C); Math_Vec3f_Copy(&this->unk_350, &sp2C); Math3D_CrossProduct(&this->unk_368, &this->unk_350, &this->unk_35C); } @@ -328,8 +316,8 @@ s32 func_808D91C4(EnSw* this, CollisionPoly* arg1) { } Math_Vec3f_Scale(&sp2C, 1.0f / temp_f0); - Matrix_InsertRotationAroundUnitVector_f(sp4C, &sp2C, MTXMODE_NEW); - Matrix_MultiplyVector3fByState(&this->unk_35C, &sp2C); + Matrix_RotateAxisF(sp4C, &sp2C, MTXMODE_NEW); + Matrix_MultVec3f(&this->unk_35C, &sp2C); Math_Vec3f_Copy(&this->unk_35C, &sp2C); Math3D_CrossProduct(&this->unk_35C, &sp38, &this->unk_350); @@ -348,23 +336,24 @@ void func_808D93BC(EnSw* this) { MtxF sp18; sp18.xx = this->unk_35C.x; - sp18.xy = this->unk_35C.y; - sp18.xz = this->unk_35C.z; - sp18.yx = this->unk_368.x; + sp18.yx = this->unk_35C.y; + sp18.zx = this->unk_35C.z; + sp18.xy = this->unk_368.x; sp18.yy = this->unk_368.y; - sp18.yz = this->unk_368.z; - sp18.zx = this->unk_350.x; - sp18.zy = this->unk_350.y; + sp18.zy = this->unk_368.z; + sp18.xz = this->unk_350.x; + sp18.yz = this->unk_350.y; sp18.zz = this->unk_350.z; - func_8018219C(&sp18, &this->actor.world.rot, 0); + Matrix_MtxFToYXZRot(&sp18, &this->actor.world.rot, false); this->actor.world.rot.x = -this->actor.world.rot.x; } -s32 func_808D9440(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, CollisionPoly** arg4, u32* arg5) { +s32 func_808D9440(GlobalContext* globalCtx, Vec3f* posA, Vec3f* posB, Vec3f* posResult, CollisionPoly** outPoly, + s32* bgId) { s32 ret = false; - if (func_800C55C4(&globalCtx->colCtx, arg1, arg2, arg3, arg4, 1, 1, 1, 1, arg5) && - !(func_800C9A4C(&globalCtx->colCtx, *arg4, *arg5) & 0x30)) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, posA, posB, posResult, outPoly, true, true, true, true, bgId) && + !(func_800C9A4C(&globalCtx->colCtx, *outPoly, *bgId) & 0x30)) { ret = true; } return ret; @@ -379,16 +368,16 @@ void func_808D94D0(EnSw* this, GlobalContext* globalCtx, s32 arg2, s32 arg3, s16 Vec3f sp84; Vec3f sp78; Vec3f sp6C; - u32 sp68; - u32 sp64; + s32 sp68; + s32 sp64; Actor* thisx = &this->actor; f32 temp_f20; s32 i; spA4 = NULL; spA0 = NULL; - sp68 = 50; - sp64 = 50; + sp68 = BGCHECK_SCENE; + sp64 = BGCHECK_SCENE; func_808D90F0(this, arg3, arg4); this->actor.speedXZ = this->unk_44C; temp_f20 = thisx->speedXZ * 2.0f; @@ -457,10 +446,11 @@ void func_808D94D0(EnSw* this, GlobalContext* globalCtx, s32 arg2, s32 arg3, s16 } if (arg2 == 1) { - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); } } #else +void func_808D94D0(EnSw* this, GlobalContext* globalCtx, s32 arg2, s32 arg3, s16 arg4); #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sw/func_808D94D0.s") #endif @@ -469,38 +459,38 @@ void func_808D9894(EnSw* this, Vec3f* vec) { MtxF sp1C; sp1C.xx = this->unk_35C.x; - sp1C.yx = this->unk_35C.y; - sp1C.zx = this->unk_35C.z; - sp1C.wx = 0.0f; - - sp1C.xy = this->unk_368.x; - sp1C.yy = this->unk_368.y; - sp1C.zy = this->unk_368.z; - sp1C.wy = 0.0f; - - sp1C.xz = this->unk_350.x; - sp1C.yz = this->unk_350.y; - sp1C.zz = this->unk_350.z; - sp1C.wz = 0.0f; - + sp1C.xy = this->unk_35C.y; + sp1C.xz = this->unk_35C.z; sp1C.xw = 0.0f; + + sp1C.yx = this->unk_368.x; + sp1C.yy = this->unk_368.y; + sp1C.yz = this->unk_368.z; sp1C.yw = 0.0f; + + sp1C.zx = this->unk_350.x; + sp1C.zy = this->unk_350.y; + sp1C.zz = this->unk_350.z; sp1C.zw = 0.0f; + + sp1C.wx = 0.0f; + sp1C.wy = 0.0f; + sp1C.wz = 0.0f; sp1C.ww = 0.0f; - Matrix_SetCurrentState(&sp1C); + Matrix_Put(&sp1C); sp5C.x = vec->x - this->actor.world.pos.x; sp5C.y = vec->y - this->actor.world.pos.y; sp5C.z = vec->z - this->actor.world.pos.z; - Matrix_MultiplyVector3fByState(&sp5C, vec); + Matrix_MultVec3f(&sp5C, vec); } s32 func_808D9968(EnSw* this, GlobalContext* globalCtx) { s32 ret = false; - u8 param = ENSW_GET_3FC(&this->actor); + s32 param = ENSW_GET_3FC(&this->actor) & 0xFF; if (ENSW_GET_3(&this->actor)) { - if ((param != 0x3F) && Actor_GetChestFlag(globalCtx, param)) { + if ((param != 0x3F) && Flags_GetTreasure(globalCtx, param)) { ret = true; } } @@ -535,9 +525,9 @@ s32 func_808D9A70(EnSw* this, GlobalContext* globalCtx) { } else { if (this->unk_456 != 0) { if (!ENSW_GET_3(&this->actor)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_ROLL); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALGOLD_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALGOLD_ROLL); } this->unk_456--; this->skelAnime.curFrame = 0.0f; @@ -586,7 +576,7 @@ s32 func_808D9C18(EnSw* this) { this->actor.world.rot.y = Math_Vec3f_Yaw(&sp3C, &sp30); } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTURA_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTURA_APPEAR); if (ENSW_GET_3(&this->actor) == 1) { Actor_SetScale(&this->actor, 0.0f); @@ -678,69 +668,69 @@ s32 func_808DA08C(EnSw* this, GlobalContext* globalCtx) { this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); } - if (this->unk_412 == 10) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { // clang-format off for (i = 0; i < ARRAY_COUNT(this->unk_464); i++) { this->unk_464[i] = 0; } // clang-format on this->unk_45C = 0; } else if (!func_808D90C4(this)) { - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALTU_DEAD); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALTU_DEAD); Enemy_StartFinishingBlow(globalCtx, &this->actor); - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; if (!ENSW_GET_3(&this->actor)) { - func_8013BC6C(&this->skelAnime, sAnimations, 3); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 3); } switch (this->actor.colChkInfo.damageEffect) { case 4: - this->unk_412 = 20; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; this->unk_45C = 20; func_808D8B58(this); break; case 3: - this->unk_412 = 10; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; this->unk_45C = 0; func_808D8B58(this); break; case 2: - this->unk_412 = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; this->unk_45C = 20; func_808D8B58(this); break; case 5: - this->unk_412 = 30; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; this->unk_45C = 20; func_808D8B58(this); break; default: - this->unk_412 = 1; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_BLUE_FIRE; this->unk_45C = 0; break; } - if (!ENSW_GET_3(&this->actor) && (this->unk_412 != 10)) { + if (!ENSW_GET_3(&this->actor) && (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX)) { func_808D9E44(this); } this->unk_458 = 20; this->unk_45A = 0; - func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_458); + Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, this->unk_458); ret = true; } else if (this->actor.colChkInfo.damageEffect == 1) { if (this->unk_45A == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); this->unk_45A = 40; - func_800BCB70(&this->actor, 0, 200, 0, this->unk_45A); + Actor_SetColorFilter(&this->actor, 0, 200, 0, this->unk_45A); } } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTU_DAMAGE); this->unk_458 = 20; this->unk_45A = 0; - func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_458); + Actor_SetColorFilter(&this->actor, 0x4000, 200, 0, this->unk_458); } } return ret; @@ -750,7 +740,7 @@ void func_808DA350(EnSw* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if ((player->stateFlags1 & 0x200000) && (this->actor.xyzDistToPlayerSq < 8000.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_LAUGH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_LAUGH); Math_Vec3f_Copy(&this->unk_374, &player->actor.world.pos); this->unk_410 &= ~0x20; this->unk_414 = 0.0f; @@ -775,7 +765,7 @@ void func_808DA3F4(EnSw* this, GlobalContext* globalCtx) { temp_v0 = Math_FAtan2F(sp38.z, sp38.x); if (ABS_ALT(temp_v0) < temp_s1) { this->skelAnime.curFrame = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_DASH); this->unk_414 = 0.0f; if (this->unk_410 & 0x20) { this->actionFunc = func_808DA6FC; @@ -786,7 +776,7 @@ void func_808DA3F4(EnSw* this, GlobalContext* globalCtx) { } temp_s1 *= (temp_v0 < 0) ? -1 : 1; } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_ROLL); this->skelAnime.curFrame = 0.0f; } func_808D94D0(this, globalCtx, 0, 0, temp_s1); @@ -812,7 +802,7 @@ void func_808DA578(EnSw* this, GlobalContext* globalCtx) { Math_Vec3f_Copy(&this->unk_374, &this->actor.home.pos); this->actionFunc = func_808DA3F4; } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_DASH); this->skelAnime.curFrame = 0.0f; } @@ -827,6 +817,7 @@ void func_808DA578(EnSw* this, GlobalContext* globalCtx) { this->unk_414 = temp_f0; } #else +void func_808DA578(EnSw* this, GlobalContext* globalCtx); #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sw/func_808DA578.s") #endif @@ -848,7 +839,7 @@ void func_808DA6FC(EnSw* this, GlobalContext* globalCtx) { func_808D94D0(this, globalCtx, 0, 0, Math_FAtan2F(sp38.z, sp38.x)); } } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_DASH); this->skelAnime.curFrame = 0.0f; } @@ -865,11 +856,12 @@ void func_808DA6FC(EnSw* this, GlobalContext* globalCtx) { this->unk_414 = sp4C; } #else +void func_808DA6FC(EnSw* this, GlobalContext* globalCtx); #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sw/func_808DA6FC.s") #endif void func_808DA89C(EnSw* this, GlobalContext* globalCtx) { - if (this->unk_412 == 10) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { s32 i; s32 count; s16 phi_a0; @@ -890,41 +882,36 @@ void func_808DA89C(EnSw* this, GlobalContext* globalCtx) { if (!ENSW_GET_3(&this->actor)) { func_808D9E44(this); } - this->unk_412 = 1; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_BLUE_FIRE; func_808D8ED0(this, globalCtx); } - return; - if (1) {} - } - - if (ENSW_GET_3(&this->actor)) { + } else if (ENSW_GET_3(&this->actor)) { this->actionFunc = func_808DAEB4; - return; - } - - if (this->actor.bgCheckFlags & 1) { - f32 temp_f2; - - this->actor.shape.yOffset = 400.0f; - temp_f2 = fabsf(this->actor.velocity.y) * 0.6f; - this->actor.velocity.y = temp_f2; - this->unk_448 = temp_f2; - this->actor.speedXZ = 0.0f; - if ((s32)temp_f2 != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTURA_BOUND); - } else { - this->actionFunc = func_808DAEB4; - this->actor.velocity.y = 0.0f; - } - if ((s32)this->actor.velocity.y >= 2) { - func_808D8940(this, globalCtx); - } } else { - Math_ApproachF(&this->actor.shape.yOffset, 400.0f, 0.3f, 1000.0f); - } + if (this->actor.bgCheckFlags & 1) { + f32 temp_f2; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); - Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + this->actor.shape.yOffset = 400.0f; + temp_f2 = fabsf(this->actor.velocity.y) * 0.6f; + this->actor.velocity.y = temp_f2; + this->unk_448 = temp_f2; + this->actor.speedXZ = 0.0f; + if ((s32)temp_f2 != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALTURA_BOUND); + } else { + this->actionFunc = func_808DAEB4; + this->actor.velocity.y = 0.0f; + } + if ((s32)this->actor.velocity.y >= 2) { + func_808D8940(this, globalCtx); + } + } else { + Math_ApproachF(&this->actor.shape.yOffset, 400.0f, 0.3f, 1000.0f); + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } } void func_808DAA60(EnSw* this, GlobalContext* globalCtx) { @@ -934,7 +921,7 @@ void func_808DAA60(EnSw* this, GlobalContext* globalCtx) { Vec3f sp34; f32 temp_f16; - sp44 = (Vec3s*)Lib_SegmentedToVirtual(this->unk_1E4->unk_04); + sp44 = Lib_SegmentedToVirtual(this->unk_1E4->points); sp40 = 0; if (DECR(this->unk_454) == 0) { @@ -947,7 +934,7 @@ void func_808DAA60(EnSw* this, GlobalContext* globalCtx) { temp_v0 = Math_FAtan2F(sp34.z, sp34.x); if (ABS_ALT(temp_v0) < sp40) { this->skelAnime.curFrame = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_DASH); Math_Vec3s_ToVec3f(&this->unk_374, &sp44[this->unk_4A0]); this->actionFunc = func_808DACF4; this->unk_414 = 0.0f; @@ -957,7 +944,7 @@ void func_808DAA60(EnSw* this, GlobalContext* globalCtx) { } } else { if (this->unk_456 != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALGOLD_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALGOLD_ROLL); this->unk_456--; this->skelAnime.curFrame = 0.0f; } else { @@ -1000,7 +987,7 @@ void func_808DACF4(EnSw* this, GlobalContext* globalCtx) { func_808D94D0(this, globalCtx, 0, 0, Math_FAtan2F(sp38.z, sp38.x)); } } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_DASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_DASH); this->skelAnime.curFrame = 0.0f; } @@ -1009,7 +996,7 @@ void func_808DACF4(EnSw* this, GlobalContext* globalCtx) { if ((temp_f6 != 0) && (temp_f6 < (s32)sp4C)) { Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_374); this->unk_4A0 += this->unk_49C; - if ((this->unk_4A0 >= this->unk_1E4->unk_00) || (this->unk_4A0 < 0)) { + if ((this->unk_4A0 >= this->unk_1E4->count) || (this->unk_4A0 < 0)) { this->unk_49C = -this->unk_49C; this->unk_4A0 += this->unk_49C * 2; } @@ -1024,6 +1011,7 @@ void func_808DACF4(EnSw* this, GlobalContext* globalCtx) { this->unk_414 = sp4C; } #else +void func_808DACF4(EnSw* this, GlobalContext* globalCtx); #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Sw/func_808DACF4.s") #endif @@ -1078,7 +1066,7 @@ void func_808DAEB4(EnSw* this, GlobalContext* globalCtx) { phi_a0 = DECR(this->unk_45C); if (phi_a0 == 0) { this->unk_410 |= 2; - if (!ENSW_GET_3(&this->actor) && (this->unk_412 == 1)) { + if (!ENSW_GET_3(&this->actor) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_BLUE_FIRE)) { func_808D8B58(this); this->unk_45C = 10; } else { @@ -1107,9 +1095,9 @@ void func_808DB100(EnSw* this, GlobalContext* globalCtx) { if ((DECR(this->unk_454) == 0) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { if (this->unk_456 != 0) { if (!ENSW_GET_3(&this->actor)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALWALL_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALWALL_ROLL); } else { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALGOLD_ROLL); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALGOLD_ROLL); } this->unk_456--; this->skelAnime.curFrame = 0.0f; @@ -1144,10 +1132,10 @@ void func_808DB2E0(EnSw* this, GlobalContext* globalCtx) { this->actor.velocity.z *= 0.5f; if ((s32)temp_f2 != 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTURA_BOUND); + Actor_PlaySfxAtPos(&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; } @@ -1160,7 +1148,7 @@ void func_808DB2E0(EnSw* this, GlobalContext* globalCtx) { Math_ApproachF(&this->actor.scale.x, 0.02f, 0.4f, 1.0f); Actor_SetScale(&this->actor, this->actor.scale.x); this->actor.velocity.y += this->actor.gravity; - Actor_ApplyMovement(&this->actor); + Actor_UpdatePos(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); } @@ -1170,8 +1158,9 @@ void EnSw_Init(Actor* thisx, GlobalContext* globalCtx) { if (!func_808D9968(this, globalCtx)) { ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005298, NULL, this->jointTable, this->morphTable, 30); - func_8013BC6C(&this->skelAnime, sAnimations, 0); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_st_Skel_005298, NULL, this->jointTable, this->morphTable, + 30); + SubS_ChangeAnimationByInfoS(&this->skelAnime, sAnimations, 0); this->skelAnime.playSpeed = 4.0f; Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); @@ -1185,7 +1174,7 @@ void EnSw_Init(Actor* thisx, GlobalContext* globalCtx) { this->collider.info.toucher.damage = 16; } - this->unk_1E4 = func_8013BEDC(globalCtx, ENSW_GET_FF00(&this->actor), 255, &this->unk_4A0); + this->unk_1E4 = SubS_GetDayDependentPath(globalCtx, ENSW_GET_FF00(&this->actor), 255, &this->unk_4A0); if (this->unk_1E4 != NULL) { this->unk_4A0 = 1; } @@ -1197,8 +1186,8 @@ void EnSw_Init(Actor* thisx, GlobalContext* globalCtx) { break; case 1: - this->actor.flags &= ~1; - this->actor.flags |= 0x10; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; if (this->actor.world.rot.z < 0) { this->unk_460 = -thisx->world.rot.z; @@ -1218,8 +1207,8 @@ void EnSw_Init(Actor* thisx, GlobalContext* globalCtx) { case 2: case 3: - this->actor.flags &= ~1; - this->actor.flags |= 0x10; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; if (this->actor.world.rot.z < 0) { this->unk_460 = -thisx->world.rot.z; @@ -1261,11 +1250,11 @@ void EnSw_Update(Actor* thisx, GlobalContext* globalCtx) { this->actionFunc(this, globalCtx); } - if ((this->unk_412 != 10) || (this->unk_45A != 0)) { + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || (this->unk_45A != 0)) { SkelAnime_Update(&this->skelAnime); } - Actor_SetHeight(&this->actor, 0.0f); + Actor_SetFocus(&this->actor, 0.0f); func_808D8FC4(this, globalCtx); } @@ -1275,43 +1264,43 @@ s32 EnSw_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if (ENSW_GET_3(&this->actor)) { switch (limbIndex) { case 23: - *dList = D_06004788; + *dList = object_st_DL_004788; break; case 8: - *dList = D_060046F0; + *dList = object_st_DL_0046F0; break; case 14: - *dList = D_06004658; + *dList = object_st_DL_004658; break; case 11: - *dList = D_060045C0; + *dList = object_st_DL_0045C0; break; case 26: - *dList = D_06004820; + *dList = object_st_DL_004820; break; case 20: - *dList = D_060048B8; + *dList = object_st_DL_0048B8; break; case 17: - *dList = D_06004950; + *dList = object_st_DL_004950; break; case 29: - *dList = D_060049E8; + *dList = object_st_DL_0049E8; break; case 5: - *dList = D_06003FB0; + *dList = object_st_DL_003FB0; break; case 4: - *dList = D_060043D8; + *dList = object_st_DL_0043D8; break; } } @@ -1328,7 +1317,7 @@ void EnSw_Draw(Actor* thisx, GlobalContext* globalCtx) { func_800B8050(&this->actor, globalCtx, MTXMODE_NEW); } func_8012C28C(globalCtx->state.gfxCtx); - Matrix_InsertXRotation_s(-0x3C72, MTXMODE_APPLY); + Matrix_RotateXS(-0x3C72, MTXMODE_APPLY); SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnSw_OverrideLimbDraw, NULL, &this->actor); } 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 b64b6d02a..b74062705 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.h +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.h @@ -11,17 +11,12 @@ typedef void (*EnSwActionFunc)(struct EnSw*, GlobalContext*); #define ENSW_GET_3FC(thisx) (((thisx)->params & 0x3FC) >> 2) #define ENSW_GET_FF00(thisx) ((((thisx)->params & 0xFF00) >> 8) & 0xFF) -typedef struct { - u8 unk_00; - s32 unk_04; -} EnSwUnkStruct; - typedef struct EnSw { /* 0x0000 */ Actor actor; /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnSwActionFunc actionFunc; /* 0x018C */ ColliderSphere collider; - /* 0x01E4 */ EnSwUnkStruct* unk_1E4; + /* 0x01E4 */ Path* unk_1E4; /* 0x01E8 */ Vec3s jointTable[30]; /* 0x029C */ Vec3s morphTable[30]; /* 0x0350 */ Vec3f unk_350; @@ -30,9 +25,9 @@ typedef struct EnSw { /* 0x0374 */ Vec3f unk_374; /* 0x0380 */ Vec3f unk_380[12]; /* 0x0410 */ u16 unk_410; - /* 0x0412 */ u8 unk_412; + /* 0x0412 */ u8 drawDmgEffType; /* 0x0414 */ f32 unk_414; - /* 0x0418 */ f32 unk_418[12]; + /* 0x0418 */ f32 drawDmgEffFrozenSteamScales[12]; /* 0x0448 */ f32 unk_448; /* 0x044C */ f32 unk_44C; /* 0x0450 */ f32 unk_450; @@ -48,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_Syateki_Crow/z_en_syateki_crow.c b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c index f14c5b3c5..b45da318d 100644 --- a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c +++ b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.c @@ -1,6 +1,14 @@ -#include "z_en_syateki_crow.h" +/* + * File: z_en_syateki_crow.c + * Overlay: ovl_En_Syateki_Crow + * Description: Shooting Gallery Guay + */ -#define FLAGS 0x08000030 +#include "z_en_syateki_crow.h" +#include "overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" +#include "objects/object_crow/object_crow.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_8000000) #define THIS ((EnSyatekiCrow*)thisx) @@ -9,7 +17,15 @@ void EnSyatekiCrow_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiCrow_Update(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiCrow_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809CA5D4(EnSyatekiCrow* this); +void func_809CA67C(EnSyatekiCrow* this, GlobalContext* globalCtx); +void func_809CA71C(EnSyatekiCrow* this); +void func_809CA840(EnSyatekiCrow* this, GlobalContext* globalCtx); +void func_809CA8E4(EnSyatekiCrow* this, GlobalContext* globalCtx); +void func_809CABC0(EnSyatekiCrow* this, GlobalContext* globalCtx); + +static Vec3f D_809CB050 = { 0.0f, 0.0f, 0.0f }; + const ActorInit En_Syateki_Crow_InitVars = { ACTOR_EN_SYATEKI_CROW, ACTORCAT_ENEMY, @@ -22,60 +38,286 @@ const ActorInit En_Syateki_Crow_InitVars = { (ActorFunc)EnSyatekiCrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809CB07C[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, 60, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809CB0A0 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_809CB07C, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809CB0B0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneScale, 3000, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 88, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP), }; -#endif +static Vec3f D_809CB0C0 = { 0.0f, 20.0f, 0.0f }; -extern ColliderJntSphElementInit D_809CB07C[1]; -extern ColliderJntSphInit D_809CB0A0; -extern InitChainEntry D_809CB0B0[]; +static Vec3f D_809CB0CC = { 0.0f, 0.0f, 0.0f }; -extern UNK_TYPE D_060000F0; +static Vec3f D_809CB0D8 = { 2500.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/EnSyatekiCrow_Init.s") +void EnSyatekiCrow_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnSyatekiCrow* this = THIS; + Path* path; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/EnSyatekiCrow_Destroy.s") + path = syatekiMan->path; + while (path->unk2 != 0) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CA5D4.s") + for (i = 0; i < EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor); i++) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CA67C.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGuaySkel, &gGuayFlyAnim, this->jointTable, this->morphTable, + OBJECT_CROW_LIMB_MAX); + Collider_InitJntSph(globalCtx, &this->unk_23C); + Collider_SetJntSph(globalCtx, &this->unk_23C, &this->actor, &sJntSphInit, &this->unk_25C); + this->unk_23C.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; + ActorShape_Init(&this->actor.shape, 2000.0f, ActorShadow_DrawCircle, 20.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CA71C.s") + if ((path == NULL) || (EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor) >= 0x80)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CA840.s") + this->unk_1C8 = Lib_SegmentedToVirtual(path->points); + this->unk_1CC = 1; + this->unk_1CE = path->count; + this->unk_1C4 = 0x14; + this->unk_1BC = 0; + func_809CA5D4(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CA8E4.s") +void EnSyatekiCrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiCrow* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CAAF8.s") + Collider_DestroyJntSph(globalCtx, &this->unk_23C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CABC0.s") +void func_809CA5D4(EnSyatekiCrow* this) { + Actor_SetScale(&this->actor, 0.03f); + this->actor.speedXZ = 0.0f; + this->actor.gravity = 0.0f; + this->actor.world = this->actor.home; + this->actor.prevPos = this->actor.home.pos; + this->actor.shape.rot = this->actor.world.rot; + this->unk_1CC = 1; + this->actor.draw = NULL; + this->actionFunc = func_809CA67C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CACD0.s") +void func_809CA67C(EnSyatekiCrow* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/EnSyatekiCrow_Update.s") + if ((syatekiMan->unk_26A == 1) && (this->unk_1C2 == 1) && + (syatekiMan->unk_274 & (1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)))) { + func_809CA71C(this); + } else if (syatekiMan->unk_26A != 1) { + this->unk_1C2 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CAE5C.s") + if ((syatekiMan->unk_274 == 0) && (syatekiMan->unk_274 == 0)) { + this->unk_1C2 = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/func_809CAF2C.s") +void func_809CA71C(EnSyatekiCrow* this) { + Vec3f sp24; + s16 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Crow/EnSyatekiCrow_Draw.s") + this->actor.world.pos.x = this->unk_1C8[0].x; + this->actor.world.pos.y = this->unk_1C8[0].y; + this->actor.world.pos.z = this->unk_1C8[0].z; + sp24.x = this->unk_1C8[this->unk_1CC].x; + sp24.y = this->unk_1C8[this->unk_1CC].y; + sp24.z = this->unk_1C8[this->unk_1CC].z; + temp = Math_Vec3f_Yaw(&this->actor.world.pos, &sp24); + this->actor.world.rot.y = temp; + this->actor.shape.rot.y = temp; + temp = Math_Vec3f_Pitch(&this->actor.world.pos, &sp24); + this->actor.shape.rot.x = temp; + this->actor.world.rot.x = temp; + this->actor.draw = EnSyatekiCrow_Draw; + this->actionFunc = func_809CA840; +} + +void func_809CA840(EnSyatekiCrow* this, GlobalContext* globalCtx) { + if (((EN_SYATEKI_CROW_GET_PARAM_F(&this->actor) * 20) + 20) < this->unk_1BC) { + Actor_PlaySfxAtPos(this->actor.parent, NA_SE_EN_KAICHO_CRY); + this->unk_1BC = 0; + this->actor.speedXZ = EN_SYATEKI_CROW_GET_PARAM_F0(&this->actor) + 6.0f; + this->actor.gravity = -0.5f; + this->actionFunc = func_809CA8E4; + } else { + this->unk_1BC++; + } +} + +void func_809CA8E4(EnSyatekiCrow* this, GlobalContext* globalCtx) { + Vec3f sp34; + f32 sp30; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (syatekiMan->unk_26A != 1) { + func_809CA5D4(this); + return; + } + + sp34.x = this->unk_1C8[this->unk_1CC].x; + sp34.y = this->unk_1C8[this->unk_1CC].y; + sp34.z = this->unk_1C8[this->unk_1CC].z; + + sp30 = Math_Vec3f_DistXZ(&this->actor.world.pos, &sp34); + this->unk_1C0 = Math_Vec3f_Yaw(&this->actor.world.pos, &sp34); + this->unk_1BE = Math_Vec3f_Pitch(&this->actor.world.pos, &sp34); + + if (sp30 > 100.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_1C0, 5, 0x3000, 0x100); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.shape.rot.x, this->unk_1BE, 5, 0x3000, 0x100); + this->actor.world.rot.x = -this->actor.shape.rot.x; + } else if (this->unk_1CC < (this->unk_1CE - 1)) { + this->unk_1CC++; + } else { + this->unk_1C2 = 0; + syatekiMan->unk_274 &= ~(1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)); + func_809CA5D4(this); + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.yOffset = (fabsf(this->skelAnime.curFrame - 3.0f) * 150.0f) + 1700.0f; + if ((syatekiMan->unk_26C % 90) == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_CRY); + } +} + +void func_809CAAF8(EnSyatekiCrow* this) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + syatekiMan->unk_280 += 60; + this->unk_1C2 = 0; + this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); + this->actor.velocity.y = 0.0f; + Animation_Change(&this->skelAnime, &gGuayFlyAnim, 0.4f, 0.0f, 0.0f, 1, -3.0f); + this->actor.bgCheckFlags &= ~1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_DEAD); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + this->actionFunc = func_809CABC0; +} + +void func_809CABC0(EnSyatekiCrow* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + this->actor.colorFilterTimer = 40; + + if (this->actor.colorFilterParams & 0x4000) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200); + this->actor.shape.rot.z += 0x1780; + } + + if (this->unk_1C4 > 20) { + func_800B3030(globalCtx, &this->actor.world.pos, &D_809CB050, &D_809CB050, this->actor.scale.x * 10000.0f, 0, + 0); + syatekiMan->unk_27A++; + syatekiMan->unk_274 &= ~(1 << EN_SYATEKI_CROW_GET_PARAM_FF00(&this->actor)); + func_809CA5D4(this); + } + + this->unk_1C4++; +} + +void func_809CACD0(EnSyatekiCrow* this, GlobalContext* globalCtx) { + if (this->actionFunc == func_809CA8E4) { + if (this->unk_23C.base.acFlags & AC_HIT) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + this->unk_1C4 = 0; + this->unk_23C.base.acFlags &= ~AC_HIT; + EffectSsExtra_Spawn(globalCtx, &this->actor.world.pos, &D_809CB0C0, &D_809CB0CC, 5, 1); + func_809CAAF8(this); + } else { + this->unk_23C.elements->dim.worldSphere.center.x = this->actor.world.pos.x; + this->unk_23C.elements->dim.worldSphere.center.y = + sJntSphInit.elements[0].dim.modelSphere.center.y + this->actor.world.pos.y; + this->unk_23C.elements->dim.worldSphere.center.z = this->actor.world.pos.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_23C.base); + } + } +} + +void EnSyatekiCrow_Update(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiCrow* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != func_809CABC0) { + Actor_MoveWithoutGravity(&this->actor); + } else { + Actor_MoveWithGravity(&this->actor); + } + + func_809CACD0(this, globalCtx); +} + +s32 EnSyatekiCrow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnSyatekiCrow* this = THIS; + + if (limbIndex == OBJECT_CROW_LIMB_UPPER_TAIL) { + rot->y += (s16)(3072.0f * sin_rad(this->skelAnime.curFrame * (M_PI / 4))); + } else if (limbIndex == OBJECT_CROW_LIMB_TAIL) { + rot->y += (s16)(5120.0f * sin_rad((this->skelAnime.curFrame + 2.5f) * (M_PI / 4))); + } + + return false; +} + +void EnSyatekiCrow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnSyatekiCrow* this = THIS; + Vec3f* sp1C; + + if (limbIndex == OBJECT_CROW_LIMB_BODY) { + Matrix_MultVec3f(&D_809CB0D8, &this->unk_144[0]); + this->unk_144[0].y -= 20.0f; + } else if ((limbIndex == OBJECT_CROW_LIMB_RIGHT_WING_TIP) || (limbIndex == OBJECT_CROW_LIMB_LEFT_WING_TIP) || + (limbIndex == OBJECT_CROW_LIMB_TAIL)) { + sp1C = &this->unk_144[(limbIndex >> 1) - 1]; + Matrix_MultVec3f(&D_809CB050, sp1C); + sp1C->y -= 20.0f; + } +} + +void EnSyatekiCrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiCrow* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnSyatekiCrow_OverrideLimbDraw, EnSyatekiCrow_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h index 48c9305dd..8946e213f 100644 --- a/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h +++ b/src/overlays/actors/ovl_En_Syateki_Crow/z_en_syateki_crow.h @@ -3,15 +3,31 @@ #include "global.h" +#define EN_SYATEKI_CROW_GET_PARAM_F(thisx) ((thisx)->params & 0xF) +#define EN_SYATEKI_CROW_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define EN_SYATEKI_CROW_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) + struct EnSyatekiCrow; typedef void (*EnSyatekiCrowActionFunc)(struct EnSyatekiCrow*, GlobalContext*); typedef struct EnSyatekiCrow { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x74]; - /* 0x01B8 */ EnSyatekiCrowActionFunc actionFunc; - /* 0x01BC */ char unk_1BC[0xE0]; + /* 0x000 */ Actor actor; + /* 0x144 */ Vec3f unk_144[4]; + /* 0x174 */ SkelAnime skelAnime; + /* 0x1B8 */ EnSyatekiCrowActionFunc actionFunc; + /* 0x1BC */ s16 unk_1BC; + /* 0x1BE */ s16 unk_1BE; + /* 0x1C0 */ s16 unk_1C0; + /* 0x1C2 */ s16 unk_1C2; + /* 0x1C4 */ s16 unk_1C4; + /* 0x1C8 */ Vec3s* unk_1C8; + /* 0x1CC */ s16 unk_1CC; + /* 0x1CE */ s16 unk_1CE; + /* 0x1D0 */ Vec3s jointTable[9]; + /* 0x206 */ Vec3s morphTable[9]; + /* 0x23C */ ColliderJntSph unk_23C; + /* 0x25C */ ColliderJntSphElement unk_25C; } EnSyatekiCrow; // size = 0x29C extern const ActorInit En_Syateki_Crow_InitVars; diff --git a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c index ec86ce081..bd5dece41 100644 --- a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c +++ b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.c @@ -1,6 +1,14 @@ -#include "z_en_syateki_dekunuts.h" +/* + * File: z_en_syateki_dekunuts.c + * Overlay: ovl_En_Syateki_Dekunuts + * Description: Shooting Gallery Deku Scrub + */ -#define FLAGS 0x08000030 +#include "z_en_syateki_dekunuts.h" +#include "overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_8000000) #define THIS ((EnSyatekiDekunuts*)thisx) @@ -9,16 +17,23 @@ void EnSyatekiDekunuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiDekunuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiDekunuts_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A2BE54(EnSyatekiDekunuts* this); void func_80A2BF18(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2BFC4(EnSyatekiDekunuts* this); void func_80A2C0F8(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C150(EnSyatekiDekunuts* this); void func_80A2C168(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C1AC(EnSyatekiDekunuts* this); void func_80A2C208(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C27C(EnSyatekiDekunuts* this); void func_80A2C2E0(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C33C(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C3AC(EnSyatekiDekunuts* this); void func_80A2C3F0(EnSyatekiDekunuts* this, GlobalContext* globalCtx); +void func_80A2C478(EnSyatekiDekunuts* this); void func_80A2C48C(EnSyatekiDekunuts* this, GlobalContext* globalCtx); void func_80A2C5DC(EnSyatekiDekunuts* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Syateki_Dekunuts_InitVars = { ACTOR_EN_SYATEKI_DEKUNUTS, ACTORCAT_ENEMY, @@ -31,69 +46,390 @@ const ActorInit En_Syateki_Dekunuts_InitVars = { (ActorFunc)EnSyatekiDekunuts_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A2CAB0 = { - { COLTYPE_HIT6, 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, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT6, + 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, + OCELEM_NONE, + }, { 48, 80, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A2CB90[] = { +static Cylinder16 D_80A2CADC[] = { { 24, 40, 0, { 0, 0, 0 } } }; + +static AnimationInfo sAnimations[] = { + { &gDekuScrubUpAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gDekuScrubBurrowAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gDekuScrubIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -1.0f }, + { &gDekuScrubLookAroundAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -1.0f }, + { &gDekuScrubDamageAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gDekuScrubDieAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gDekuScrubUnburrowAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 77, ICHAIN_CONTINUE), ICHAIN_F32(gravity, 0, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2600, ICHAIN_STOP), }; -#endif +void EnSyatekiDekunuts_Init(Actor* thisx, GlobalContext* globalCtx2) { + static s32 D_80A2CB9C = 1; + EnSyatekiDekunuts* this = THIS; + GlobalContext* globalCtx = globalCtx2; + s32 phi_v0; + Path* path; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + s32 i; -extern ColliderCylinderInit D_80A2CAB0; -extern InitChainEntry D_80A2CB90[]; + path = syatekiMan->path; + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -extern UNK_TYPE D_06001E50; -extern UNK_TYPE D_06002A5C; -extern UNK_TYPE D_06003180; + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) == 1) { + Actor_SetScale(&this->actor, 0.01f); + this->collider.dim = D_80A2CADC[0]; + phi_v0 = 3; + } else { + Actor_SetScale(&this->actor, 0.02f); + phi_v0 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/EnSyatekiDekunuts_Init.s") + while (path->unk2 != phi_v0) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/EnSyatekiDekunuts_Destroy.s") + for (i = 0; i < EN_SYATEKI_DEKUNUTS_GET_PARAM_FF00(&this->actor); i++) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2BE54.s") + if (D_80A2CB9C == 1) { + this->unk_1EC = 1; + D_80A2CB9C = 0; + } else { + this->unk_1EC = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2BF18.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 35.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gDekuScrubSkel, &gDekuScrubBurrowAnim, this->jointTable, + this->morphTable, DEKU_SCRUB_LIMB_MAX); + if (path == NULL) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2BFC4.s") + this->unk_1E4 = Lib_SegmentedToVirtual(path->points); + this->unk_1E8 = EN_SYATEKI_DEKUNUTS_GET_PARAM_F0(&this->actor); + this->unk_1EA = path->count; + this->unk_1D8 = 0; + this->unk_1DC = 0; + this->unk_1DA = 0; + func_80A2BE54(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C0F8.s") +void EnSyatekiDekunuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiDekunuts* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C150.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C168.s") +void func_80A2BE54(EnSyatekiDekunuts* this) { + Animation_PlayOnceSetSpeed(&this->skelAnime, &gDekuScrubUpAnim, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C1AC.s") + this->actor.speedXZ = 0.0f; + this->actor.world = this->actor.home; + this->actor.prevPos = this->actor.home.pos; + this->actor.shape.rot = this->actor.world.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C208.s") + this->unk_1D8 = 0; + this->unk_1DC = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C27C.s") + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1) { + this->unk_1E2 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C2E0.s") + this->actionFunc = func_80A2BF18; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C33C.s") +void func_80A2BF18(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C3AC.s") + if ((syatekiMan->unk_26A == 1) && (this->unk_1E2 == 1) && ((syatekiMan->unk_272 & (1 << this->unk_1E8)) != 0)) { + func_80A2BFC4(this); + } else if (syatekiMan->unk_26A != 1) { + this->unk_1E2 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C3F0.s") + if ((syatekiMan->unk_272 == 0) && (syatekiMan->unk_274 == 0) && + (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1)) { + this->unk_1E2 = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C478.s") +void func_80A2BFC4(EnSyatekiDekunuts* this) { + Vec3f sp14; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C48C.s") + this->unk_1D8 = 0; + sp14.x = this->unk_1E4[this->unk_1E8].x; + sp14.y = this->unk_1E4[this->unk_1E8].y; + sp14.z = this->unk_1E4[this->unk_1E8].z; + this->actor.world.pos = this->actor.prevPos = sp14; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->unk_1EE = 140 - (syatekiMan->unk_27C * 20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C4D0.s") + if ((syatekiMan->unk_27C & 1) != 0) { + this->unk_1F0 = 1; + this->unk_1F2 = 0; + } else { + this->unk_1F0 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C5DC.s") + this->actionFunc = func_80A2C0F8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/EnSyatekiDekunuts_Update.s") +void func_80A2C0F8(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/func_80A2C8A0.s") + if (this->unk_1DA > 20) { + syatekiMan = (EnSyatekiMan*)this->actor.parent; + Actor_PlaySfxAtPos(&syatekiMan->actor, NA_SE_EN_NUTS_DAMAGE); + this->unk_1DA = 0; + func_80A2C150(this); + } else { + this->unk_1DA++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Dekunuts/EnSyatekiDekunuts_Draw.s") +void func_80A2C150(EnSyatekiDekunuts* this) { + this->unk_1D8 = 0; + this->actionFunc = func_80A2C168; +} + +void func_80A2C168(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + if (this->unk_1DA > 20) { + func_80A2C1AC(this); + this->unk_1DA = 0; + } else { + this->unk_1DA++; + } +} + +void func_80A2C1AC(EnSyatekiDekunuts* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_UP); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actionFunc = func_80A2C208; +} + +void func_80A2C208(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A2C27C(this); + } + + if (this->unk_1F0 == 1) { + Math_SmoothStepToS(&this->unk_1F2, -0x8000, 5, 0x1000, 0x100); + } + + this->unk_1D8++; +} + +void func_80A2C27C(EnSyatekiDekunuts* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1) { + this->actionFunc = func_80A2C2E0; + } else { + this->actionFunc = func_80A2C33C; + } +} + +void func_80A2C2E0(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if ((this->unk_1EE < this->unk_1D8) || (syatekiMan->unk_26A != 1)) { + func_80A2C3AC(this); + } + + this->unk_1D8++; +} + +void func_80A2C33C(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if ((gSaveContext.unk_3DE0[1] <= 0) || (syatekiMan->unk_26A != 1)) { + func_80A2C3AC(this); + } + + if (this->unk_1D8 < 11) { + this->unk_1D8++; + } +} + +void func_80A2C3AC(EnSyatekiDekunuts* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actionFunc = func_80A2C3F0; +} + +void func_80A2C3F0(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (syatekiMan->unk_26A == 1) { + if (this->unk_1D8 > 160 && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_1D8 = 0; + func_80A2C150(this); + } else { + this->unk_1D8++; + } + } else { + func_80A2C478(this); + } +} + +void func_80A2C478(EnSyatekiDekunuts* this) { + this->actionFunc = func_80A2C48C; +} + +void func_80A2C48C(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + if (this->unk_1DA > 20) { + func_80A2BE54(this); + this->unk_1DA = 0; + } else { + this->unk_1DA++; + } +} + +void func_80A2C4D0(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + static Vec3f D_80A2CBA0 = { 0.0f, 20.0f, 0.0f }; + static Vec3f D_80A2CBAC = { 0.0f, 0.0f, 0.0f }; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) == 1) { + EffectSsExtra_Spawn(globalCtx, &this->actor.world.pos, &D_80A2CBA0, &D_80A2CBAC, 5, 2); + syatekiMan->unk_280 += 100; + syatekiMan->unk_26E++; + } else { + EffectSsExtra_Spawn(globalCtx, &this->actor.world.pos, &D_80A2CBA0, &D_80A2CBAC, 5, 0); + syatekiMan->unk_280 += 30; + syatekiMan->unk_278++; + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DAMAGE); + this->unk_1E2 = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + this->unk_1D8 = 160; + this->actionFunc = func_80A2C5DC; +} + +void func_80A2C5DC(EnSyatekiDekunuts* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_80A2CBB8 = { 255, 255, 255, 255 }; + static Color_RGBA8 D_80A2CBBC = { 150, 150, 150, 0 }; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_1D8 == 160) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_NUTS_DEAD); + this->unk_1D8--; + } else if (this->unk_1D8 < 160) { + Vec3f sp40; + + 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, &gZeroVec3f, &gZeroVec3f, &D_80A2CBB8, &D_80A2CBBC, 200, 0, 13); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, 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); + + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) != 1) { + syatekiMan->unk_272 &= ~(1 << this->unk_1E8); + } + + func_80A2BE54(this); + } + } else if (this->unk_1D8 < 160) { + this->unk_1D8--; + } +} + +void EnSyatekiDekunuts_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSyatekiDekunuts* this = THIS; + + this->actionFunc(this, globalCtx); + + if ((this->actionFunc != func_80A2BF18) && (this->unk_1D8 < this->unk_1EE) && (this->unk_1D8 > 10)) { + if ((this->collider.base.acFlags & AC_HIT) && (this->unk_1E2 == 1)) { + if (EN_SYATEKI_DEKUNUTS_GET_PARAM_F(&this->actor) == 1) { + func_801A3098(NA_BGM_GET_ITEM | 0x900); + } else { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + + this->collider.base.acFlags &= ~AC_HIT; + func_80A2C4D0(this, globalCtx); + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.acFlags &= ~AC_HIT; + } + + SkelAnime_Update(&this->skelAnime); +} + +s32 EnSyatekiDekunuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnSyatekiDekunuts* this = THIS; + + if ((limbIndex == DEKU_SCRUB_LIMB_HEADDRESS) && (this->unk_1F0 == 1)) { + rot->z += this->unk_1F2; + } + + return false; +} + +void EnSyatekiDekunuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiDekunuts* this = THIS; + Vec3f temp_f20; + s32 i; + + if (this->actionFunc != func_80A2BF18) { + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnSyatekiDekunuts_OverrideLimbDraw, NULL, &this->actor); + } + + if (this->unk_1EC == 1) { + for (i = 0; i < this->unk_1EA; i++) { + temp_f20.x = this->unk_1E4[i].x; + temp_f20.y = this->unk_1E4[i].y; + temp_f20.z = this->unk_1E4[i].z; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(temp_f20.x, temp_f20.y, temp_f20.z, MTXMODE_NEW); + Matrix_Scale(0.02f, 0.02f, 0.02f, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gDekuScrubFlowerDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} diff --git a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h index 30712d917..50361894b 100644 --- a/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h +++ b/src/overlays/actors/ovl_En_Syateki_Dekunuts/z_en_syateki_dekunuts.h @@ -2,16 +2,36 @@ #define Z_EN_SYATEKI_DEKUNUTS_H #include "global.h" +#include "objects/object_dekunuts/object_dekunuts.h" + +#define EN_SYATEKI_DEKUNUTS_GET_PARAM_F(thisx) ((thisx)->params & 0xF) +#define EN_SYATEKI_DEKUNUTS_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define EN_SYATEKI_DEKUNUTS_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) struct EnSyatekiDekunuts; typedef void (*EnSyatekiDekunutsActionFunc)(struct EnSyatekiDekunuts*, GlobalContext*); typedef struct EnSyatekiDekunuts { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnSyatekiDekunutsActionFunc actionFunc; - /* 0x018C */ char unk_18C[0xE4]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnSyatekiDekunutsActionFunc actionFunc; + /* 0x18C */ ColliderCylinder collider; + /* 0x1D8 */ s16 unk_1D8; + /* 0x1DA */ s16 unk_1DA; + /* 0x1CD */ s16 unk_1DC; + /* 0x1DE */ UNK_TYPE1 unk_1DE[0x4]; + /* 0x1E2 */ s16 unk_1E2; + /* 0x1E4 */ Vec3s* unk_1E4; + /* 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 */ Vec3s jointTable[DEKU_SCRUB_LIMB_MAX]; + /* 0x230 */ Vec3s morphTable[DEKU_SCRUB_LIMB_MAX]; + /* 0x26C */ UNK_TYPE1 unk_26C[0x4]; } EnSyatekiDekunuts; // size = 0x270 extern const ActorInit En_Syateki_Dekunuts_InitVars; diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c index 7e641a4ed..6ea613a6b 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.c @@ -6,7 +6,7 @@ #include "z_en_syateki_man.h" -#define FLAGS 0x08000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_8000000) #define THIS ((EnSyatekiMan*)thisx) @@ -34,16 +34,6 @@ void func_809C8808(EnSyatekiMan* this, GlobalContext* globalCtx); void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx); void func_809C8BF0(EnSyatekiMan* this, GlobalContext* globalCtx); -extern UNK_PTR D_06005AC8; -extern UNK_PTR D_060062C8; -extern AnimationHeader D_0600D2F8; -extern AnimationHeader D_0600D9D0; -extern AnimationHeader D_0600DFEC; -extern FlexSkeletonHeader D_0600E7D0; -extern Gfx D_0600F2D0[]; -extern UNK_PTR D_0600FB90; -extern UNK_PTR D_06010390; - const ActorInit En_Syateki_Man_InitVars = { ACTOR_EN_SYATEKI_MAN, ACTORCAT_NPC, @@ -56,10 +46,10 @@ const ActorInit En_Syateki_Man_InitVars = { (ActorFunc)EnSyatekiMan_Draw, }; -static ActorAnimationEntry sAnimations[] = { - { &D_0600D9D0, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_0600DFEC, 1.0f, 0.0f, 0.0f, 0, -8.0f }, - { &D_0600D2F8, 1.0f, 0.0f, 0.0f, 2, -8.0f }, +static AnimationInfo sAnimations[] = { + { &gBurlyGuyHandsOnTableAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gSwampShootingGalleryManHeadScratchLoopAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gSwampShootingGalleryManHeadScratchEndAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, }; static s16 D_809C91C8[] = { @@ -141,11 +131,11 @@ void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.targetMode = 1; Actor_SetScale(&this->actor, 0.01f); if (globalCtx->sceneNum == SCENE_SYATEKI_MORI) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600E7D0, &D_0600DFEC, this->jointTable, this->morphTable, - 16); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gBurlyGuySkel, &gSwampShootingGalleryManHeadScratchLoopAnim, + this->jointTable, this->morphTable, BURLY_GUY_LIMB_MAX); } else { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600E7D0, &D_0600D9D0, this->jointTable, this->morphTable, - 16); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gBurlyGuySkel, &gBurlyGuyHandsOnTableAnim, this->jointTable, + this->morphTable, BURLY_GUY_LIMB_MAX); } this->actor.colChkInfo.cylRadius = 100; @@ -163,8 +153,8 @@ void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) { this->unk_284 = 0; this->unk_194 = 0; this->unk_282 = 0; - this->unk_264 = 0; - this->unk_266 = 0; + this->eyeIndex = 0; + this->blinkTimer = 0; if (globalCtx->sceneNum == SCENE_SYATEKI_MORI) { this->path = sp34; @@ -173,7 +163,7 @@ void EnSyatekiMan_Init(Actor* thisx, GlobalContext* globalCtx) { } void EnSyatekiMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { - gSaveContext.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~1; } s32 func_809C6720(GlobalContext* globalCtx, Vec3f arg1) { @@ -193,7 +183,7 @@ s32 func_809C6720(GlobalContext* globalCtx, Vec3f arg1) { } globalCtx->actorCtx.unk268 = 1; - func_800B6F20(globalCtx, globalCtx->actorCtx.pad26C, phi_f0, sp22); + func_800B6F20(globalCtx, &globalCtx->actorCtx.unk_26C, phi_f0, sp22); if (sp28 < 5.0f) { return true; @@ -213,37 +203,37 @@ void func_809C6810(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C6848(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { u16 sp22; - func_800BDC5C(&this->skelAnime, sAnimations, 2); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); sp22 = Text_GetFaceReaction(globalCtx, 0x31); if (sp22 != 0) { - func_801518B0(globalCtx, sp22, &this->actor); + Message_StartTextbox(globalCtx, sp22, &this->actor); this->unk_284 = sp22; } else if (player->transformation == PLAYER_FORM_HUMAN) { if (this->unk_282 == 0) { this->unk_282 = 1; - func_801518B0(globalCtx, 0xA28, &this->actor); + Message_StartTextbox(globalCtx, 0xA28, &this->actor); this->unk_284 = 0xA28; } else { - func_801518B0(globalCtx, 0xA29, &this->actor); + Message_StartTextbox(globalCtx, 0xA29, &this->actor); this->unk_284 = 0xA29; } } else { switch (CURRENT_DAY) { case 1: - func_801518B0(globalCtx, 0xA38, &this->actor); + Message_StartTextbox(globalCtx, 0xA38, &this->actor); this->unk_284 = 0xA38; break; case 2: - func_801518B0(globalCtx, 0xA39, &this->actor); + Message_StartTextbox(globalCtx, 0xA39, &this->actor); this->unk_284 = 0xA39; break; case 3: - func_801518B0(globalCtx, 0xA3A, &this->actor); + Message_StartTextbox(globalCtx, 0xA3A, &this->actor); this->unk_284 = 0xA3A; break; } @@ -261,15 +251,15 @@ void func_809C6848(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C6A04(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex == 0) { if (!CUR_UPG_VALUE(UPG_QUIVER)) { play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0xA30, &this->actor); + Message_StartTextbox(globalCtx, 0xA30, &this->actor); this->unk_284 = 0xA30; - } else if (gSaveContext.rupees < 20) { + } else if (gSaveContext.save.playerData.rupees < 20) { play_sound(NA_SE_SY_ERROR); - func_801518B0(globalCtx, 0xA31, &this->actor); + Message_StartTextbox(globalCtx, 0xA31, &this->actor); this->unk_284 = 0xA31; if (this->unk_26A == 4) { gSaveContext.minigameState = 3; @@ -278,9 +268,9 @@ void func_809C6A04(EnSyatekiMan* this, GlobalContext* globalCtx) { } else { func_8019F208(); func_801159EC(-20); - gSaveContext.weekEventReg[63] |= 1; - gSaveContext.weekEventReg[63] &= (u8)~2; - globalCtx->msgCtx.unk11F22 = 0x43; + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->unk_26A = 7; player->stateFlags1 |= 0x20; @@ -291,17 +281,17 @@ void func_809C6A04(EnSyatekiMan* this, GlobalContext* globalCtx) { switch (CURRENT_DAY) { case 1: - func_801518B0(globalCtx, 0xA2D, &this->actor); + Message_StartTextbox(globalCtx, 0xA2D, &this->actor); this->unk_284 = 0xA2D; break; case 2: - func_801518B0(globalCtx, 0xA2E, &this->actor); + Message_StartTextbox(globalCtx, 0xA2E, &this->actor); this->unk_284 = 0xA2E; break; case 3: - func_801518B0(globalCtx, 0xA2F, &this->actor); + Message_StartTextbox(globalCtx, 0xA2F, &this->actor); this->unk_284 = 0xA2F; break; } @@ -318,18 +308,18 @@ void func_809C6A04(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C6C2C(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_284) { case 0xA28: case 0xA29: - func_801518B0(globalCtx, 0xA2A, &this->actor); + Message_StartTextbox(globalCtx, 0xA2A, &this->actor); this->unk_284 = 0xA2A; break; case 0xA2B: case 0xA2C: case 0xA35: - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->actor.freezeTimer = 0; func_80112AFC(globalCtx); @@ -337,32 +327,32 @@ void func_809C6C2C(EnSyatekiMan* this, GlobalContext* globalCtx) { func_80123F2C(globalCtx, 80); this->unk_26A = 1; this->actionFunc = func_809C80C0; - func_801A2BB8(0x25); + func_801A2BB8(NA_BGM_MINI_GAME_2); break; case 0xA32: - if (gSaveContext.weekEventReg[63] & 2) { + if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(globalCtx); player->stateFlags1 &= ~0x20; - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->actionFunc = func_809C6848; gSaveContext.minigameState = 3; this->unk_26A = 0; } else { - func_801518B0(globalCtx, 0xA33, &this->actor); + Message_StartTextbox(globalCtx, 0xA33, &this->actor); this->unk_284 = 0xA33; } break; case 0xA33: - func_801518B0(globalCtx, 0xA2A, &this->actor); + Message_StartTextbox(globalCtx, 0xA2A, &this->actor); this->unk_284 = 0xA2A; this->unk_26A = 4; break; case 0xA34: - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->actor.freezeTimer = 0; gSaveContext.minigameState = 3; @@ -381,7 +371,7 @@ void func_809C6E30(EnSyatekiMan* this, GlobalContext* globalCtx) { player->stateFlags1 |= 0x20; } - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 2: this->actionFunc = func_809C6848; this->unk_26A = 0; @@ -396,12 +386,12 @@ void func_809C6E30(EnSyatekiMan* this, GlobalContext* globalCtx) { break; case 6: - if (func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if (Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->stateFlags1 &= ~0x20; - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->actionFunc = func_809C6848; this->unk_26A = 0; } @@ -417,32 +407,32 @@ void func_809C6E30(EnSyatekiMan* this, GlobalContext* globalCtx) { break; } - if (this->skelAnime.animation == &D_0600D2F8) { + if (this->skelAnime.animation == &gSwampShootingGalleryManHeadScratchEndAnim) { if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { - func_800BDC5C(&this->skelAnime, sAnimations, 0); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 0); } } } void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { - switch (gSaveContext.playerForm) { + switch (gSaveContext.save.playerForm) { case PLAYER_FORM_HUMAN: - Actor_SetAllChestFlag(globalCtx, Actor_GetAllChestFlag(globalCtx) + 1); + Flags_SetAllTreasure(globalCtx, Flags_GetAllTreasure(globalCtx) + 1); if (CURRENT_DAY != 3) { if (!(this->unk_282 & 1)) { this->unk_282 |= 1; - func_801518B0(globalCtx, 0x3E8, &this->actor); + Message_StartTextbox(globalCtx, 0x3E8, &this->actor); this->unk_284 = 0x3E8; } else { - func_801518B0(globalCtx, 0x3E9, &this->actor); + Message_StartTextbox(globalCtx, 0x3E9, &this->actor); this->unk_284 = 0x3E9; } } else if (!(this->unk_282 & 1)) { this->unk_282 |= 1; - func_801518B0(globalCtx, 0x3EA, &this->actor); + Message_StartTextbox(globalCtx, 0x3EA, &this->actor); this->unk_284 = 0x3EA; } else { - func_801518B0(globalCtx, 0x3EB, &this->actor); + Message_StartTextbox(globalCtx, 0x3EB, &this->actor); this->unk_284 = 0x3EB; } break; @@ -451,18 +441,18 @@ void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { if (CURRENT_DAY != 3) { if (!(this->unk_282 & 2)) { this->unk_282 |= 2; - func_801518B0(globalCtx, 0x3EC, &this->actor); + Message_StartTextbox(globalCtx, 0x3EC, &this->actor); this->unk_284 = 0x3EC; } else { - func_801518B0(globalCtx, 0x3ED, &this->actor); + Message_StartTextbox(globalCtx, 0x3ED, &this->actor); this->unk_284 = 0x3ED; } } else if (!(this->unk_282 & 2)) { this->unk_282 |= 2; - func_801518B0(globalCtx, 0x3EE, &this->actor); + Message_StartTextbox(globalCtx, 0x3EE, &this->actor); this->unk_284 = 0x3EE; } else { - func_801518B0(globalCtx, 0x3EF, &this->actor); + Message_StartTextbox(globalCtx, 0x3EF, &this->actor); this->unk_284 = 0x3EF; } break; @@ -471,18 +461,18 @@ void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { if (CURRENT_DAY != 3) { if (!(this->unk_282 & 8)) { this->unk_282 |= 8; - func_801518B0(globalCtx, 0x3F0, &this->actor); + Message_StartTextbox(globalCtx, 0x3F0, &this->actor); this->unk_284 = 0x3F0; } else { - func_801518B0(globalCtx, 0x3F1, &this->actor); + Message_StartTextbox(globalCtx, 0x3F1, &this->actor); this->unk_284 = 0x3F1; } } else if (!(this->unk_282 & 8)) { this->unk_282 |= 8; - func_801518B0(globalCtx, 0x3F4, &this->actor); + Message_StartTextbox(globalCtx, 0x3F4, &this->actor); this->unk_284 = 0x3F4; } else { - func_801518B0(globalCtx, 0x3F5, &this->actor); + Message_StartTextbox(globalCtx, 0x3F5, &this->actor); this->unk_284 = 0x3F5; } break; @@ -491,18 +481,18 @@ void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { if (CURRENT_DAY != 3) { if (!(this->unk_282 & 4)) { this->unk_282 |= 4; - func_801518B0(globalCtx, 0x3F2, &this->actor); + Message_StartTextbox(globalCtx, 0x3F2, &this->actor); this->unk_284 = 0x3F2; } else { - func_801518B0(globalCtx, 0x3F3, &this->actor); + Message_StartTextbox(globalCtx, 0x3F3, &this->actor); this->unk_284 = 0x3F3; } } else if (!(this->unk_282 & 4)) { this->unk_282 |= 4; - func_801518B0(globalCtx, 0x3F4, &this->actor); + Message_StartTextbox(globalCtx, 0x3F4, &this->actor); this->unk_284 = 0x3F4; } else { - func_801518B0(globalCtx, 0x3F5, &this->actor); + Message_StartTextbox(globalCtx, 0x3F5, &this->actor); this->unk_284 = 0x3F5; } break; @@ -510,11 +500,11 @@ void func_809C6F98(EnSyatekiMan* this, GlobalContext* globalCtx) { } void func_809C72D8(EnSyatekiMan* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { u16 sp26 = Text_GetFaceReaction(globalCtx, 0x30); if (sp26 != 0) { - func_801518B0(globalCtx, sp26, &this->actor); + Message_StartTextbox(globalCtx, sp26, &this->actor); this->unk_284 = sp26; } else { func_809C6F98(this, globalCtx); @@ -528,24 +518,24 @@ void func_809C72D8(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C7380(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex == 0) { if (!CUR_UPG_VALUE(UPG_QUIVER)) { play_sound(NA_SE_SY_ERROR); if (CURRENT_DAY != 3) { - func_801518B0(globalCtx, 0x3F9, &this->actor); + Message_StartTextbox(globalCtx, 0x3F9, &this->actor); this->unk_284 = 0x3F9; } else { - func_801518B0(globalCtx, 0x3FA, &this->actor); + Message_StartTextbox(globalCtx, 0x3FA, &this->actor); this->unk_284 = 0x3FA; } - } else if (gSaveContext.rupees < 20) { + } else if (gSaveContext.save.playerData.rupees < 20) { play_sound(NA_SE_SY_ERROR); if (CURRENT_DAY != 3) { - func_801518B0(globalCtx, 0x3FB, &this->actor); + Message_StartTextbox(globalCtx, 0x3FB, &this->actor); this->unk_284 = 0x3FB; } else { - func_801518B0(globalCtx, 0x3FC, &this->actor); + Message_StartTextbox(globalCtx, 0x3FC, &this->actor); this->unk_284 = 0x3FC; } @@ -560,22 +550,22 @@ void func_809C7380(EnSyatekiMan* this, GlobalContext* globalCtx) { this->unk_26A = 2; if (!(this->unk_282 & 0x10)) { this->unk_282 |= 0x10; - func_801518B0(globalCtx, 0x3FD, &this->actor); + Message_StartTextbox(globalCtx, 0x3FD, &this->actor); this->unk_284 = 0x3FD; } else { - func_801518B0(globalCtx, 0x3FF, &this->actor); + Message_StartTextbox(globalCtx, 0x3FF, &this->actor); this->unk_284 = 0x3FF; } - gSaveContext.weekEventReg[63] |= 1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; } } else { func_8019F230(); if (CURRENT_DAY != 3) { - func_801518B0(globalCtx, 0x3F7, &this->actor); + Message_StartTextbox(globalCtx, 0x3F7, &this->actor); this->unk_284 = 0x3F7; } else { - func_801518B0(globalCtx, 0x3F8, &this->actor); + Message_StartTextbox(globalCtx, 0x3F8, &this->actor); this->unk_284 = 0x3F8; } @@ -591,38 +581,38 @@ void func_809C7380(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C7620(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->unk_284) { case 0x3E8: case 0x3E9: case 0x3EA: case 0x3EB: - func_801518B0(globalCtx, 0x3F6, &this->actor); + Message_StartTextbox(globalCtx, 0x3F6, &this->actor); this->unk_284 = 0x3F6; break; case 0x3EC: - func_801518B0(globalCtx, 0x3ED, &this->actor); + Message_StartTextbox(globalCtx, 0x3ED, &this->actor); this->unk_284 = 0x3ED; break; case 0x3EE: - func_801518B0(globalCtx, 0x3EF, &this->actor); + Message_StartTextbox(globalCtx, 0x3EF, &this->actor); this->unk_284 = 0x3EF; break; case 0x3F0: - func_801518B0(globalCtx, 0x3F1, &this->actor); + Message_StartTextbox(globalCtx, 0x3F1, &this->actor); this->unk_284 = 0x3F1; break; case 0x3F2: - func_801518B0(globalCtx, 0x3F3, &this->actor); + Message_StartTextbox(globalCtx, 0x3F3, &this->actor); this->unk_284 = 0x3F3; break; case 0x3F4: - func_801518B0(globalCtx, 0x3F5, &this->actor); + Message_StartTextbox(globalCtx, 0x3F5, &this->actor); this->unk_284 = 0x3F5; break; @@ -630,66 +620,66 @@ void func_809C7620(EnSyatekiMan* this, GlobalContext* globalCtx) { case 0x3FF: if (this->unk_26A == 4) { if (this->unk_284 == 0x3FD) { - func_801518B0(globalCtx, 0x3FE, &this->actor); + Message_StartTextbox(globalCtx, 0x3FE, &this->actor); this->unk_284 = 0x3FE; } else { - func_801518B0(globalCtx, 0x400, &this->actor); + Message_StartTextbox(globalCtx, 0x400, &this->actor); this->unk_284 = 0x400; } } else { - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->actor.freezeTimer = 0; this->unk_26A = 7; player->stateFlags1 |= 0x20; - gSaveContext.weekEventReg[63] |= 1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] |= 1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->actionFunc = func_809C8710; } break; case 0x3FE: case 0x400: - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->actor.freezeTimer = 0; this->unk_27E = 0; func_80112AFC(globalCtx); func_80123F2C(globalCtx, 0x63); this->unk_26A = 1; - func_801A2BB8(0x25); + func_801A2BB8(NA_BGM_MINI_GAME_2); this->actionFunc = func_809C8808; break; case 0x401: - if (gSaveContext.weekEventReg[63] & 2) { + if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(globalCtx); - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->unk_26A = 0; this->actionFunc = func_809C72D8; } else { - func_801518B0(globalCtx, 0x402, &this->actor); + Message_StartTextbox(globalCtx, 0x402, &this->actor); this->unk_284 = 0x402; } break; case 0x403: - if (gSaveContext.weekEventReg[63] & 2) { + if (gSaveContext.save.weekEventReg[63] & 2) { func_801477B4(globalCtx); - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->unk_26A = 0; this->actionFunc = func_809C72D8; } else { - func_801518B0(globalCtx, 0x404, &this->actor); + Message_StartTextbox(globalCtx, 0x404, &this->actor); this->unk_284 = 0x404; } break; case 0x402: case 0x404: - func_801518B0(globalCtx, 0x3F6, &this->actor); + Message_StartTextbox(globalCtx, 0x3F6, &this->actor); this->unk_284 = 0x3F6; this->unk_26A = 4; break; @@ -697,7 +687,7 @@ void func_809C7620(EnSyatekiMan* this, GlobalContext* globalCtx) { case 0x405: case 0x406: case 0x407: - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->actor.freezeTimer = 0; gSaveContext.minigameState = 3; @@ -715,7 +705,7 @@ void func_809C7990(EnSyatekiMan* this, GlobalContext* globalCtx) { player->stateFlags1 |= 0x20; } - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 2: this->actionFunc = func_809C72D8; this->unk_26A = 0; @@ -730,9 +720,9 @@ void func_809C7990(EnSyatekiMan* this, GlobalContext* globalCtx) { break; case 6: - if (func_80147624(globalCtx)) { - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + if (Message_ShouldAdvance(globalCtx)) { + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; player->stateFlags1 &= ~0x20; this->actionFunc = func_809C72D8; this->unk_26A = 0; @@ -754,22 +744,22 @@ void func_809C7A90(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (Actor_HasParent(&this->actor, globalCtx)) { - if (!(gSaveContext.weekEventReg[59] & 0x10)) { - gSaveContext.weekEventReg[59] |= 0x10; - } else if (!(gSaveContext.weekEventReg[32] & 2) && (this->unk_280 >= 0x884)) { - gSaveContext.weekEventReg[32] |= 2; + if (!(gSaveContext.save.weekEventReg[59] & 0x10)) { + gSaveContext.save.weekEventReg[59] |= 0x10; + } else if (!(gSaveContext.save.weekEventReg[32] & 2) && (this->unk_280 >= 0x884)) { + gSaveContext.save.weekEventReg[32] |= 2; } this->actor.parent = NULL; this->actionFunc = func_809C7C14; } else { - if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.weekEventReg[59] & 0x10)) { - func_800B8A1C(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); + if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.save.weekEventReg[59] & 0x10)) { + Actor_PickUp(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); } else if (this->unk_280 < 0x884) { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_RED, 500.0f, 100.0f); - } else if (!(gSaveContext.weekEventReg[32] & 2)) { - func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 500.0f, 100.0f); + } else if (!(gSaveContext.save.weekEventReg[32] & 2)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); } player->actor.shape.rot.y = -0x8000; @@ -782,21 +772,21 @@ void func_809C7A90(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C7C14(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { - if ((CURRENT_DAY == 3) && (gSaveContext.time > CLOCK_TIME(12, 00))) { - func_801518B0(globalCtx, 0xA36, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if ((CURRENT_DAY == 3) && (gSaveContext.save.time > CLOCK_TIME(12, 0))) { + Message_StartTextbox(globalCtx, 0xA36, &this->actor); this->unk_284 = 0xA36; } else { - func_801518B0(globalCtx, 0xA37, &this->actor); + Message_StartTextbox(globalCtx, 0xA37, &this->actor); this->unk_284 = 0xA37; } player->stateFlags1 &= ~0x20; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->unk_280 = 0; this->unk_26A = 0; this->actionFunc = func_809C6E30; } else { - func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + func_800B85E0(&this->actor, globalCtx, 500.0f, EXCH_ITEM_MINUS1); } } @@ -805,29 +795,29 @@ void func_809C7D14(EnSyatekiMan* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { if (this->unk_284 == 0x407) { - if (!(gSaveContext.weekEventReg[59] & 0x20)) { - gSaveContext.weekEventReg[59] |= 0x20; + if (!(gSaveContext.save.weekEventReg[59] & 0x20)) { + gSaveContext.save.weekEventReg[59] |= 0x20; } } if ((this->unk_284 == 0x405) || (this->unk_284 == 0x406)) { - if (!(gSaveContext.weekEventReg[32] & 4)) { - gSaveContext.weekEventReg[32] |= 4; + if (!(gSaveContext.save.weekEventReg[32] & 4)) { + gSaveContext.save.weekEventReg[32] |= 4; } } this->actor.parent = NULL; this->actionFunc = func_809C7EB4; } else { if (this->unk_284 == 0x407) { - if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.weekEventReg[59] & 0x20)) { - func_800B8A1C(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); + if ((CUR_UPG_VALUE(UPG_QUIVER) < 3) && !(gSaveContext.save.weekEventReg[59] & 0x20)) { + Actor_PickUp(&this->actor, globalCtx, GI_QUIVER_30 + CUR_UPG_VALUE(UPG_QUIVER), 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_PURPLE, 500.0f, 100.0f); } - } else if (!(gSaveContext.weekEventReg[32] & 4)) { - func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); + } else if (!(gSaveContext.save.weekEventReg[32] & 4)) { + Actor_PickUp(&this->actor, globalCtx, GI_HEART_PIECE, 500.0f, 100.0f); } else { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_GOLD, 500.0f, 100.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_HUGE, 500.0f, 100.0f); } player->actor.shape.rot.y = -0x8000; @@ -841,24 +831,24 @@ void func_809C7EB4(EnSyatekiMan* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); if (CURRENT_DAY != 3) { - if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { player->stateFlags1 &= ~0x20; this->unk_280 = 0; this->unk_26A = 0; - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->actionFunc = func_809C6810; } - } else if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, 0x408, &this->actor); + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x408, &this->actor); this->unk_284 = 0x408; player->stateFlags1 &= ~0x20; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->unk_280 = 0; this->unk_26A = 0; this->actionFunc = func_809C7990; } else { - func_800B85E0(&this->actor, globalCtx, 500.0f, -1); + func_800B85E0(&this->actor, globalCtx, 500.0f, EXCH_ITEM_MINUS1); } } @@ -870,10 +860,10 @@ void func_809C7FFC(EnSyatekiMan* this, GlobalContext* globalCtx) { this->unk_26A = 2; if (this->unk_282 != 2) { this->unk_282 = 2; - func_801518B0(globalCtx, 0xA2B, &this->actor); + Message_StartTextbox(globalCtx, 0xA2B, &this->actor); this->unk_284 = 0xA2B; } else { - func_801518B0(globalCtx, 0xA2C, &this->actor); + Message_StartTextbox(globalCtx, 0xA2C, &this->actor); this->unk_284 = 0xA2C; } this->actionFunc = func_809C6E30; @@ -895,7 +885,7 @@ void func_809C80C0(EnSyatekiMan* this, GlobalContext* globalCtx) { this->unk_27E = 0; this->unk_280 = 0; player->stateFlags1 &= ~0x20; - Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); this->unk_272 = 0x1F; this->unk_274 = 0; this->unk_276 = 0; @@ -917,7 +907,7 @@ void func_809C81D0(EnSyatekiMan* this, GlobalContext* globalCtx) { if (((this->unk_272 == 0) || (this->unk_26C > 140)) && (D_809C949C == 0) && (this->unk_27C < 4)) { D_809C949C = 1; this->unk_26C = 0; - Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); this->unk_274 = D_809C91C8[this->unk_27E]; if (this->unk_27E == 3) { this->unk_27E = 0; @@ -983,29 +973,29 @@ void func_809C8488(EnSyatekiMan* this, GlobalContext* globalCtx) { this->unk_274 = 0; this->unk_276 = 0; if (this->unk_270 <= 0) { - if ((s32)((gSaveContext.roomInf[127][6] & 0xFFFF0000) >> 0x10) < this->unk_280) { - gSaveContext.roomInf[127][6] = ((gSaveContext.roomInf[127][6]) & 0xFFFF) | ((u16)this->unk_280 << 0x10); + if ((s32)((gSaveContext.save.unk_EF4 & 0xFFFF0000) >> 0x10) < this->unk_280) { + gSaveContext.save.unk_EF4 = ((gSaveContext.save.unk_EF4) & 0xFFFF) | ((u16)this->unk_280 << 0x10); } this->unk_270 = 15; if (this->unk_280 >= 0x848) { - func_801518B0(globalCtx, 0xA34, &this->actor); + Message_StartTextbox(globalCtx, 0xA34, &this->actor); this->unk_284 = 0xA34; this->unk_26A = 6; } else if (this->unk_280 >= 0x7D0) { - if (gSaveContext.weekEventReg[63] & 2) { - gSaveContext.weekEventReg[63] &= (u8)~1; - gSaveContext.weekEventReg[63] &= (u8)~2; + if (gSaveContext.save.weekEventReg[63] & 2) { + gSaveContext.save.weekEventReg[63] &= (u8)~1; + gSaveContext.save.weekEventReg[63] &= (u8)~2; this->unk_26A = 0; gSaveContext.minigameState = 3; this->actionFunc = func_809C6848; return; } - func_801518B0(globalCtx, 0xA35, &this->actor); + Message_StartTextbox(globalCtx, 0xA35, &this->actor); this->unk_284 = 0xA35; this->unk_26A = 4; this->unk_280 = 0; } else { - func_801518B0(globalCtx, 0xA32, &this->actor); + Message_StartTextbox(globalCtx, 0xA32, &this->actor); this->unk_284 = 0xA32; this->unk_26A = 6; } @@ -1037,7 +1027,7 @@ void func_809C8610(EnSyatekiMan* this, GlobalContext* globalCtx) { gSaveContext.unk_3E88[1] += 100; globalCtx->interfaceCtx.unk_25C += 10; this->unk_280 += 10; - Audio_PlayActorSound2(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); D_809C94A0 = 0; } else { D_809C94A0++; @@ -1048,7 +1038,7 @@ void func_809C8610(EnSyatekiMan* this, GlobalContext* globalCtx) { void func_809C8710(EnSyatekiMan* this, GlobalContext* globalCtx) { Vec3f sp24; - if (gSaveContext.playerForm == PLAYER_FORM_FIERCE_DEITY) { + if (gSaveContext.save.playerForm == PLAYER_FORM_FIERCE_DEITY) { sp24 = D_809C9480; } else { sp24 = D_809C948C; @@ -1056,10 +1046,10 @@ void func_809C8710(EnSyatekiMan* this, GlobalContext* globalCtx) { if (func_809C6720(globalCtx, sp24)) { if (this->unk_284 == 0x3FD) { - func_801518B0(globalCtx, 0x3FE, &this->actor); + Message_StartTextbox(globalCtx, 0x3FE, &this->actor); this->unk_284 = 0x3FE; } else { - func_801518B0(globalCtx, 0x400, &this->actor); + Message_StartTextbox(globalCtx, 0x400, &this->actor); this->unk_284 = 0x400; } this->unk_26A = 2; @@ -1107,26 +1097,19 @@ void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx) { }; static s32 D_809C94A8 = 0; Player* player = GET_PLAYER(globalCtx); - s32 sp30; - s32 pad; - u64 sp20; - - sp20 = gSaveContext.unk_3DE0[1]; - sp30 = (sp20 * 0.1f) + 1.0f; + s32 sp30 = (((void)0, gSaveContext.unk_3DE0[1]) * 0.1f) + 1.0f; if (sp30 < 0x2EF) { s32 temp; - // clang-format off if (D_809C94A8 == 0) { - sp20 = gSaveContext.unk_3DE0[1]; temp = sp20 % 0x1F4; + temp = ((void)0, gSaveContext.unk_3DE0[1]) % 500; } else { - sp20 = gSaveContext.unk_3DE0[1]; temp = (sp20 + 250) % 0x1F4; + temp = (((void)0, gSaveContext.unk_3DE0[1]) + 250) % 500; } - //clang-format on if (temp < 100) { - this->unk_26C = 0x50; + this->unk_26C = 80; } if (this->unk_26E != 0) { @@ -1144,7 +1127,7 @@ void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx) { if ((D_809C94A8 == (sp30 % 50)) && (this->unk_26C >= 70)) { if (this->unk_27E < 15) { this->unk_190 = D_809C94D0[this->unk_27E++]; - Audio_PlayActorSound2(&this->actor, NA_SE_SY_FOUND); + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_FOUND); this->unk_26C = 0; } } @@ -1160,7 +1143,7 @@ void func_809C898C(EnSyatekiMan* this, GlobalContext* globalCtx) { func_801A2C20(); this->actionFunc = func_809C8BF0; if (this->unk_280 == 50) { - func_801A3098(0x922); + func_801A3098(NA_BGM_GET_ITEM | 0x900); func_8011B4E0(globalCtx, 1); } } @@ -1171,32 +1154,32 @@ void func_809C8BF0(EnSyatekiMan* this, GlobalContext* globalCtx) { if (this->unk_26A == 1) { this->unk_190 = 0; if ((this->unk_270 <= 0) && (globalCtx->interfaceCtx.unk_286 == 0)) { - Actor_SetAllChestFlag(globalCtx, this->unk_280); + Flags_SetAllTreasure(globalCtx, this->unk_280); this->unk_270 = 15; - if (((s32)(gSaveContext.roomInf[127][6] & 0xFFFF) < this->unk_280) || (this->unk_280 == 50)) { - if ((s32)(gSaveContext.roomInf[127][6] & 0xFFFF) < this->unk_280) { - if (!(gSaveContext.weekEventReg[59] & 0x20)) { - func_801518B0(globalCtx, 0x407, &this->actor); + if (((s32)(gSaveContext.save.unk_EF4 & 0xFFFF) < this->unk_280) || (this->unk_280 == 50)) { + if ((s32)(gSaveContext.save.unk_EF4 & 0xFFFF) < this->unk_280) { + if (!(gSaveContext.save.weekEventReg[59] & 0x20)) { + Message_StartTextbox(globalCtx, 0x407, &this->actor); this->unk_284 = 0x407; } else if (this->unk_280 == 50) { - func_801518B0(globalCtx, 0x405, &this->actor); + Message_StartTextbox(globalCtx, 0x405, &this->actor); this->unk_284 = 0x405; } else { - func_801518B0(globalCtx, 0x407, &this->actor); + Message_StartTextbox(globalCtx, 0x407, &this->actor); this->unk_284 = 0x407; } } else if (this->unk_280 == 50) { - func_801518B0(globalCtx, 0x406, &this->actor); + Message_StartTextbox(globalCtx, 0x406, &this->actor); this->unk_284 = 0x406; } - gSaveContext.roomInf[127][6] = (gSaveContext.roomInf[127][6] & 0xFFFF0000) | (this->unk_280 & 0xFFFF); + gSaveContext.save.unk_EF4 = (gSaveContext.save.unk_EF4 & 0xFFFF0000) | (this->unk_280 & 0xFFFF); this->unk_26A = 6; } else { if (CURRENT_DAY != 3) { - func_801518B0(globalCtx, 0x401, &this->actor); + Message_StartTextbox(globalCtx, 0x401, &this->actor); this->unk_284 = 0x401; } else { - func_801518B0(globalCtx, 0x403, &this->actor); + Message_StartTextbox(globalCtx, 0x403, &this->actor); this->unk_284 = 0x403; } this->unk_26A = 4; @@ -1212,34 +1195,34 @@ void func_809C8BF0(EnSyatekiMan* this, GlobalContext* globalCtx) { } } -void func_809C8DE8(EnSyatekiMan* this) { - switch (this->unk_266) { +void EnSyatekiMan_Blink(EnSyatekiMan* this) { + switch (this->blinkTimer) { case 1: - this->unk_264 = 2; + this->eyeIndex = 2; break; case 2: - this->unk_264 = 1; + this->eyeIndex = 1; break; case 40: - this->unk_266 = 0; + this->blinkTimer = 0; default: - this->unk_264 = 0; + this->eyeIndex = 0; break; } - this->unk_266++; + this->blinkTimer++; } void EnSyatekiMan_Update(Actor* thisx, GlobalContext* globalCtx) { EnSyatekiMan* this = THIS; this->actionFunc(this, globalCtx); - func_809C8DE8(this); + EnSyatekiMan_Blink(this); this->actor.focus.pos.y = 70.0f; - Actor_SetHeight(&this->actor, 70.0f); + Actor_SetFocus(&this->actor, 70.0f); if (this->unk_26A != 1) { SkelAnime_Update(&this->skelAnime); func_800E9250(globalCtx, &this->actor, &this->unk_258, &this->unk_25E, this->actor.focus.pos); @@ -1250,17 +1233,17 @@ s32 EnSyatekiMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** Actor* thisx) { EnSyatekiMan* this = THIS; - if ((globalCtx->sceneNum == SCENE_SYATEKI_MIZU) && (limbIndex == 15)) { - *dList = D_0600F2D0; + if ((globalCtx->sceneNum == SCENE_SYATEKI_MIZU) && (limbIndex == BURLY_GUY_LIMB_HEAD)) { + *dList = gTownShootingGalleryManHeadDL; } - if (limbIndex == 15) { - Matrix_InsertTranslation(3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_258.x, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_258.y, MTXMODE_APPLY); - Matrix_InsertTranslation(-3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); - } else if (limbIndex == 8) { - Matrix_InsertXRotation_s(-this->unk_25E.y, MTXMODE_APPLY); + if (limbIndex == BURLY_GUY_LIMB_HEAD) { + Matrix_Translate(3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_258.x, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_258.y, MTXMODE_APPLY); + Matrix_Translate(-3000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } else if (limbIndex == BURLY_GUY_LIMB_TORSO) { + Matrix_RotateXS(-this->unk_25E.y, MTXMODE_APPLY); } return false; @@ -1270,39 +1253,39 @@ void EnSyatekiMan_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dL EnSyatekiMan* this = THIS; Vec3f sp18 = { 1600.0f, 0.0f, 0.0f }; - if (limbIndex == 15) { - Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + if (limbIndex == BURLY_GUY_LIMB_HEAD) { + Matrix_MultVec3f(&sp18, &this->actor.focus.pos); } } void EnSyatekiMan_Draw(Actor* thisx, GlobalContext* globalCtx) { - static UNK_PTR D_809C94B8[] = { - &D_06005AC8, - &D_060062C8, - &D_060062C8, + static TexturePtr sEyeTextures[] = { + gSwampShootingGalleryManEyeOpenTex, + gSwampShootingGalleryManEyeHalfTex, + gSwampShootingGalleryManEyeHalfTex, }; EnSyatekiMan* this = THIS; s32 pad; if (globalCtx->sceneNum == SCENE_SYATEKI_MIZU) { - D_809C94B8[0] = &D_0600FB90; - D_809C94B8[1] = &D_06010390; - D_809C94B8[2] = &D_06010390; + sEyeTextures[0] = gTownShootingGalleryManEyeOpenTex; + sEyeTextures[1] = gTownShootingGalleryManEyeClosedTex; + sEyeTextures[2] = gTownShootingGalleryManEyeClosedTex; } else { - D_809C94B8[0] = &D_06005AC8; - D_809C94B8[1] = &D_060062C8; - D_809C94B8[2] = &D_060062C8; + sEyeTextures[0] = gSwampShootingGalleryManEyeOpenTex; + sEyeTextures[1] = gSwampShootingGalleryManEyeHalfTex; + sEyeTextures[2] = gSwampShootingGalleryManEyeHalfTex; } OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C5B0(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_809C94B8[this->unk_264])); - gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_809C94B8[this->unk_264])); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnSyatekiMan_OverrideLimbDraw, EnSyatekiMan_PostLimbDraw, &this->actor); + EnSyatekiMan_OverrideLimbDraw, EnSyatekiMan_PostLimbDraw, &this->actor); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h index 80f2a1068..16585ac84 100644 --- a/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h +++ b/src/overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h @@ -2,6 +2,8 @@ #define Z_EN_SYATEKI_MAN_H #include "global.h" +#include "objects/object_shn/object_shn.h" + struct EnSyatekiMan; @@ -24,12 +26,12 @@ typedef struct EnSyatekiMan { /* 0x018C */ Path* path; /* 0x0190 */ s32 unk_190; /* 0x0194 */ s32 unk_194; - /* 0x0198 */ Vec3s jointTable[16]; - /* 0x01F8 */ Vec3s morphTable[16]; + /* 0x0198 */ Vec3s jointTable[BURLY_GUY_LIMB_MAX]; + /* 0x01F8 */ Vec3s morphTable[BURLY_GUY_LIMB_MAX]; /* 0x0258 */ Vec3s unk_258; /* 0x025E */ Vec3s unk_25E; - /* 0x0264 */ s16 unk_264; - /* 0x0266 */ s16 unk_266; + /* 0x0264 */ s16 eyeIndex; + /* 0x0266 */ s16 blinkTimer; /* 0x0268 */ UNK_TYPE1 unk268[0x2]; /* 0x026A */ s16 unk_26A; /* 0x026C */ s16 unk_26C; diff --git a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c index 480c0badb..34afad373 100644 --- a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c +++ b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.c @@ -1,6 +1,13 @@ -#include "z_en_syateki_okuta.h" +/* + * File: z_en_syateki_okuta.c + * Overlay: ovl_En_Syateki_Okuta + * Description: Shooting Gallery Octorok + */ -#define FLAGS 0x08000030 +#include "z_en_syateki_okuta.h" +#include "overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_8000000) #define THIS ((EnSyatekiOkuta*)thisx) @@ -9,14 +16,18 @@ void EnSyatekiOkuta_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiOkuta_Update(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiOkuta_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A36260(EnSyatekiOkuta* this); void func_80A362A8(EnSyatekiOkuta* this, GlobalContext* globalCtx); +void func_80A362F8(EnSyatekiOkuta* this); void func_80A36350(EnSyatekiOkuta* this, GlobalContext* globalCtx); void func_80A363B4(EnSyatekiOkuta* this, GlobalContext* globalCtx); +void func_80A36444(EnSyatekiOkuta* this); void func_80A36488(EnSyatekiOkuta* this, GlobalContext* globalCtx); +void func_80A364C0(EnSyatekiOkuta* this); void func_80A36504(EnSyatekiOkuta* this, GlobalContext* globalCtx); void func_80A365EC(EnSyatekiOkuta* this, GlobalContext* globalCtx); +void func_80A36CB0(EnSyatekiOkuta* this); -#if 0 const ActorInit En_Syateki_Okuta_InitVars = { ACTOR_EN_SYATEKI_OKUTA, ACTORCAT_ENEMY, @@ -29,72 +40,483 @@ const ActorInit En_Syateki_Okuta_InitVars = { (ActorFunc)EnSyatekiOkuta_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A37570 = { - { COLTYPE_HIT3, 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 ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT3, + 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, + }, { 20, 40, -30, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A37B88[] = { +static AnimationInfo sAnimations[] = { + { &gOctorokShootAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gOctorokDieAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gOctorokHideAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gOctorokFloatAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -1.0f }, + { &gOctorokAppearAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gOctorokHitAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, +}; + +#include "assets/overlays/ovl_En_Syateki_Okuta/ovl_En_Syateki_Okuta.c" + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 66, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 6500, ICHAIN_STOP), }; -#endif +Color_RGBA8 D_80A37B90 = { 255, 255, 255, 255 }; -extern ColliderCylinderInit D_80A37570; -extern InitChainEntry D_80A37B88[]; +Color_RGBA8 D_80A37B94 = { 150, 150, 150, 255 }; -extern UNK_TYPE D_0600466C; +Vec3f D_80A37B98 = { 0.0f, -0.5, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/EnSyatekiOkuta_Init.s") +Color_RGBA8 D_80A37BA4 = { 255, 255, 255, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/EnSyatekiOkuta_Destroy.s") +Color_RGBA8 D_80A37BA8 = { 150, 150, 150, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36148.s") +void EnSyatekiOkuta_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSyatekiOkuta* this = THIS; + WaterBox* waterbox; + f32 ySurface; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A361B0.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &gOctorokSkel, &gOctorokAppearAnim, this->jointTable, this->morphTable, + OCTOROK_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A361F4.s") + this->actor.floorHeight = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, + &this->actor, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36260.s") + if (!(WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &ySurface, &waterbox)) || + (ySurface <= this->actor.floorHeight)) { + Actor_MarkForDeath(&this->actor); + } else { + this->actor.world.pos.y = this->actor.home.pos.y = ySurface; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A362A8.s") + this->unk_2A4 = 0; + this->unk_2AA = 0; + func_80A36260(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A362F8.s") +void EnSyatekiOkuta_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiOkuta* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36350.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36360.s") +void func_80A36148(Vec3f* pos, Vec3f* velocity, s16 scaleStep, GlobalContext* globalCtx) { + func_800B0DE0(globalCtx, pos, velocity, &gZeroVec3f, &D_80A37B90, &D_80A37B94, 400, scaleStep); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A363B4.s") +void func_80A361B0(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + EffectSsGSplash_Spawn(globalCtx, &this->actor.home.pos, NULL, NULL, 0, 800); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36444.s") +s32 func_80A361F4(EnSyatekiOkuta* this) { + s32 temp_a0; + s32 temp_a1; + s32 temp_v1; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36488.s") + temp_v1 = EN_SYATEKI_OKUTA_GET_F(&this->actor); + if ((temp_v1 == 1) || (temp_v1 == 4)) { + temp_a0 = syatekiMan->unk_190; + temp_a1 = (temp_v1 * 2) + 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A364C0.s") + if ((temp_a0 >> temp_a1) & 3) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36504.s") + if ((temp_a1 == 8) && ((temp_a0 >> 0xE) & 3)) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A3657C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A365EC.s") +void func_80A36260(EnSyatekiOkuta* this) { + Animation_PlayOnceSetSpeed(&this->skelAnime, &gOctorokAppearAnim, 0.0f); + this->actor.draw = NULL; + this->actionFunc = func_80A362A8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A368E0.s") +void func_80A362A8(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + Actor* actorIt = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36A90.s") + while (actorIt != NULL) { + if (actorIt->id == ACTOR_EN_SYATEKI_MAN) { + this->actor.parent = actorIt; + func_80A362F8(this); + break; + } else { + actorIt = actorIt->next; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36AF8.s") +void func_80A362F8(EnSyatekiOkuta* this) { + Animation_PlayOnceSetSpeed(&this->skelAnime, &gOctorokAppearAnim, 0.0f); + this->actor.draw = NULL; + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = func_80A36350; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/EnSyatekiOkuta_Update.s") +void func_80A36350(EnSyatekiOkuta* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A36CB0.s") +void func_80A36360(EnSyatekiOkuta* this) { + this->actor.draw = EnSyatekiOkuta_Draw; + this->unk_2AA = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 4); + this->actionFunc = func_80A363B4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A370EC.s") +void func_80A363B4(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + if ((Animation_OnFrame(&this->skelAnime, 2.0f)) || (Animation_OnFrame(&this->skelAnime, 15.0f))) { + if (func_80A361F4(this)) { + return; + } else { + func_80A361B0(this, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OCTAROCK_JUMP); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/func_80A37294.s") + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A36444(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Okuta/EnSyatekiOkuta_Draw.s") +void func_80A36444(EnSyatekiOkuta* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + this->actionFunc = func_80A36488; +} + +void func_80A36488(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (syatekiMan->unk_26C >= 0x46) { + func_80A364C0(this); + } +} + +void func_80A364C0(EnSyatekiOkuta* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80A36504; +} + +void func_80A36504(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, 4.0f)) { + func_80A361B0(this, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_LAND); + } else if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A362F8(this); + } +} + +void func_80A3657C(EnSyatekiOkuta* this) { + this->unk_2A4 = 0; + this->unk_2AA = 300; + if (this->unk_2A6 == 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OCTAROCK_DEAD1); + } + + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actionFunc = func_80A365EC; +} + +void func_80A365EC(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + Vec3f sp84; + Vec3f sp78; + s32 pad; + s32 i; + + if (this->unk_2AA > 0) { + this->unk_2AA -= 15; + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if (this->unk_2A4 == 0) { + sp78.x = this->actor.world.pos.x; + sp78.y = this->actor.world.pos.y + 40.0f; + sp78.z = this->actor.world.pos.z; + sp84.x = 0.0f; + sp84.y = -0.5f; + sp84.z = 0.0f; + func_80A36148(&sp78, &sp84, -20, globalCtx); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_OCTAROCK_DEAD2); + } + + this->unk_2A4++; + } + + if (Animation_OnFrame(&this->skelAnime, 15.0f)) { + func_80A361B0(this, globalCtx); + } + + if (this->unk_2A4 < 3) { + Actor_SetScale(&this->actor, ((this->unk_2A4 * 0.25f) + 1.0f) * 0.01f); + } else if (this->unk_2A4 < 6) { + Actor_SetScale(&this->actor, (1.5f - ((this->unk_2A4 - 2) * 0.2333f)) * 0.01f); + } else if (this->unk_2A4 < 11) { + Actor_SetScale(&this->actor, (((this->unk_2A4 - 5) * 0.04f) + 0.8f) * 0.01f); + } else { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.002f)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_COMMON_WATER_MID); + for (i = 0; i < 10; i++) { + sp84.x = (Rand_ZeroOne() - 0.5f) * 7.0f; + sp84.y = Rand_ZeroOne() * 7.0f; + sp84.z = (Rand_ZeroOne() - 0.5f) * 7.0f; + EffectSsDtBubble_SpawnCustomColor(globalCtx, &this->actor.world.pos, &sp84, &D_80A37B98, &D_80A37BA4, + &D_80A37BA8, Rand_S16Offset(100, 50), 25, 0); + } + + func_80A362F8(this); + } + + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + } +} + +void func_80A368E0(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + this->collider.dim.height = + (sCylinderInit.dim.height - this->collider.dim.yShift) * this->unk_1D8.y * this->actor.scale.y * 100.0f; + this->collider.dim.radius = sCylinderInit.dim.radius * this->actor.scale.x * 100.0f; + + if (this->actionFunc == func_80A363B4) { + if ((this->unk_2A6 == 2) && func_80A361F4(this)) { + return; + } + + if (this->skelAnime.curFrame < (this->skelAnime.endFrame - 5.0f)) { + this->collider.dim.height *= 1.35f; + } + } + + if (this->unk_2A6 == 1) { + this->collider.dim.radius += 10; + this->collider.dim.height += 15; + } + + this->collider.dim.pos.x = this->actor.world.pos.x; + // jointTable->y is the y-translation of the skeleton root + this->collider.dim.pos.y = this->actor.world.pos.y + (this->skelAnime.jointTable->y * this->actor.scale.y); + this->collider.dim.pos.z = this->actor.world.pos.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +s32 func_80A36A90(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + if ((this->actionFunc == func_80A365EC) || (this->actionFunc == func_80A36350)) { + return false; + } + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + return true; + } + + func_80A368E0(this, globalCtx); + return false; +} + +void func_80A36AF8(EnSyatekiOkuta* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + s16 temp_v1_2; + + if ((this->actionFunc != func_80A36488) && (this->actionFunc != func_80A363B4) && (syatekiMan->unk_26A == 1) && + (syatekiMan->unk_26C == 0)) { + temp_v1_2 = (syatekiMan->unk_190 >> (EN_SYATEKI_OKUTA_GET_F(&this->actor) * 2)) & 3; + if (temp_v1_2 > 0) { + Actor_SetScale(&this->actor, 0.01f); + this->unk_2A6 = temp_v1_2; + func_80A36360(this); + } + } +} + +void EnSyatekiOkuta_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSyatekiOkuta* this = THIS; + EnSyatekiMan* syatekiMan; + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != func_80A36350) { + SkelAnime_Update(&this->skelAnime); + } + + func_80A36AF8(this, globalCtx); + + if (func_80A36A90(this, globalCtx)) { + syatekiMan = (EnSyatekiMan*)this->actor.parent; + if (this->unk_2A6 == 1) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + globalCtx->interfaceCtx.unk_25C++; + syatekiMan->unk_280++; + syatekiMan->unk_26E = 1; + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_ERROR); + syatekiMan->unk_26E = 2; + } + + func_80A3657C(this); + } else { + this->collider.base.acFlags &= ~AC_HIT; + } + + func_80A36CB0(this); +} + +void func_80A36CB0(EnSyatekiOkuta* this) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->actionFunc == func_80A363B4) { + if (curFrame < 8.0f) { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = 1.0f; + } else if (curFrame < 10.0f) { + this->unk_1D8.x = this->unk_1D8.z = 1.0f; + this->unk_1D8.y = ((curFrame - 7.0f) * 0.4f) + 1.0f; + } else if (curFrame < 14.0f) { + this->unk_1D8.x = this->unk_1D8.z = ((curFrame - 9.0f) * 0.075f) + 1.0f; + this->unk_1D8.y = 1.8f - ((curFrame - 9.0f) * 0.25f); + } else { + this->unk_1D8.x = this->unk_1D8.z = 1.3f - ((curFrame - 13.0f) * 0.05f); + this->unk_1D8.y = ((curFrame - 13.0f) * 0.0333f) + 0.8f; + } + } else if (this->actionFunc == func_80A36488) { + this->unk_1D8.x = this->unk_1D8.z = 1.0f; + this->unk_1D8.y = (sin_rad((M_PI / 16) * curFrame) * 0.2f) + 1.0f; + } else if (this->actionFunc == func_80A36504) { + if (curFrame < 3.0f) { + this->unk_1D8.y = 1.0f; + } else if (curFrame < 4.0f) { + this->unk_1D8.y = (curFrame - 2.0f) + 1.0f; + } else { + this->unk_1D8.y = 2.0f - ((curFrame - 3.0f) * 0.333f); + } + this->unk_1D8.x = this->unk_1D8.z = 1.0f; + } else if (this->actionFunc == func_80A365EC) { + curFrame += this->unk_2A4; + if (curFrame >= 35.0f) { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = 1.0f; + } else if (curFrame < 4.0f) { + this->unk_1D8.x = this->unk_1D8.z = 1.0f - (curFrame * 0.0666f); + this->unk_1D8.y = (curFrame * 0.1666f) + 1.0f; + } else if (curFrame < 25.0f) { + this->unk_1D8.x = this->unk_1D8.z = ((curFrame - 4.0f) * 0.01f) + 0.8f; + this->unk_1D8.y = 1.5f - ((curFrame - 4.0f) * 0.025f); + } else if (curFrame < 27.0f) { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = ((curFrame - 24.0f) * 0.25f) + 1.0f; + } else if (curFrame < 30.0f) { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = 1.5f - ((curFrame - 26.0f) * 0.233f); + } else { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = ((curFrame - 29.0f) * 0.04f) + 0.8f; + } + } else { + this->unk_1D8.x = this->unk_1D8.y = this->unk_1D8.z = 1.0f; + } +} + +s32 func_80A370EC(EnSyatekiOkuta* this, f32 arg1, Vec3f* arg2) { + if (this->actionFunc == func_80A363B4) { + arg2->y = 1.0f; + arg2->z = 1.0f; + arg2->x = (sin_rad((M_PI / 16) * arg1) * 0.4f) + 1.0f; + } else if (this->actionFunc == func_80A365EC) { + if ((arg1 >= 35.0f) || (arg1 < 25.0f)) { + return false; + } + + if (arg1 < 27.0f) { + arg2->z = 1.0f; + arg2->x = arg2->y = ((arg1 - 24.0f) * 0.5f) + 1.0f; + } else if (arg1 < 30.0f) { + arg2->z = (arg1 - 26.0f) * 0.333f + 1.0f; + arg2->x = arg2->y = 2.0f - (arg1 - 26.0f) * 0.333f; + } else { + arg2->z = 2.0f - ((arg1 - 29.0f) * 0.2f); + arg2->x = arg2->y = 1.0f; + } + } else { + return false; + } + + return true; +} + +s32 EnSyatekiOkuta_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + s32 pad; + Vec3f sp20; + f32 curFrame; + EnSyatekiOkuta* this = THIS; + + curFrame = this->skelAnime.curFrame; + if (this->actionFunc == func_80A365EC) { + curFrame += this->unk_2A4; + } + + if (limbIndex == OCTOROK_LIMB_HEAD) { + sp20 = this->unk_1D8; + Matrix_Scale(sp20.x, sp20.y, sp20.z, MTXMODE_APPLY); + } else if ((limbIndex == OCTOROK_LIMB_SNOUT) && (func_80A370EC(this, curFrame, &sp20))) { + Matrix_Scale(sp20.x, sp20.y, sp20.z, MTXMODE_APPLY); + } + + return false; +} + +void EnSyatekiOkuta_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiOkuta* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->unk_2A6 == 1) { + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, gShootingGalleryOctorokBlueMaterialDL); + } + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnSyatekiOkuta_OverrideLimbDraw, + NULL, &this->actor); + func_8012C2DC(globalCtx->state.gfxCtx); + if (this->actionFunc == func_80A365EC) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + 30.0f, this->actor.world.pos.z + 20.0f, + MTXMODE_NEW); + + if (this->unk_2AA >= 256) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 210, 64, 32, 255); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 210, 64, 32, this->unk_2AA); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->unk_2A6 == 2) { + gSPDisplayList(POLY_XLU_DISP++, gShootingGalleryOctorokCrossDL); + } else { + gSPDisplayList(POLY_XLU_DISP++, gShootingGalleryOctorokCircleDL); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.h b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.h index f3f569eda..17fafe94d 100644 --- a/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.h +++ b/src/overlays/actors/ovl_En_Syateki_Okuta/z_en_syateki_okuta.h @@ -2,16 +2,26 @@ #define Z_EN_SYATEKI_OKUTA_H #include "global.h" +#include "objects/object_okuta/object_okuta.h" + +#define EN_SYATEKI_OKUTA_GET_F(thisx) ((thisx)->params & 0xF) struct EnSyatekiOkuta; typedef void (*EnSyatekiOkutaActionFunc)(struct EnSyatekiOkuta*, GlobalContext*); typedef struct EnSyatekiOkuta { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnSyatekiOkutaActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x120]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnSyatekiOkutaActionFunc actionFunc; + /* 0x18C */ ColliderCylinder collider; + /* 0x1DC */ Vec3f unk_1D8; + /* 0x1E4 */ Vec3s jointTable[OCTOROK_LIMB_MAX]; + /* 0x244 */ Vec3s morphTable[OCTOROK_LIMB_MAX]; + /* 0x2A4 */ s16 unk_2A4; + /* 0x2A6 */ s16 unk_2A6; + /* 0x2A8 */ UNK_TYPE1 unk_2A8[0x2]; + /* 0x2AA */ s16 unk_2AA; } EnSyatekiOkuta; // size = 0x2AC extern const ActorInit En_Syateki_Okuta_InitVars; diff --git a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c index 9323517fd..0a0b3f66c 100644 --- a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c +++ b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.c @@ -1,6 +1,13 @@ -#include "z_en_syateki_wf.h" +/* + * File: z_en_syateki_wf.c + * Overlay: ovl_En_Syateki_Wf + * Description: Shooting Gallery Wolfos + */ -#define FLAGS 0x08000030 +#include "z_en_syateki_wf.h" +#include "overlays/actors/ovl_En_Syateki_Man/z_en_syateki_man.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_8000000) #define THIS ((EnSyatekiWf*)thisx) @@ -9,43 +16,91 @@ void EnSyatekiWf_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiWf_Update(Actor* thisx, GlobalContext* globalCtx); void EnSyatekiWf_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A201CC(EnSyatekiWf* this); void func_80A20284(EnSyatekiWf* this, GlobalContext* globalCtx); +void func_80A2030C(EnSyatekiWf* this); void func_80A20320(EnSyatekiWf* this, GlobalContext* globalCtx); +void func_80A20378(EnSyatekiWf* this); void func_80A203DC(EnSyatekiWf* this, GlobalContext* globalCtx); +void func_80A20670(EnSyatekiWf* this); void func_80A206DC(EnSyatekiWf* this, GlobalContext* globalCtx); +void func_80A20710(EnSyatekiWf* this); void func_80A2075C(EnSyatekiWf* this, GlobalContext* globalCtx); +void func_80A2079C(EnSyatekiWf* this); void func_80A20800(EnSyatekiWf* this, GlobalContext* globalCtx); void func_80A208F8(EnSyatekiWf* this, GlobalContext* globalCtx); -#if 0 -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A20E74 = { - { COLTYPE_HIT5, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { 40, 60, 0, { 0, 0, 0 } }, -}; - -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80A20E50[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, + }, { 17, { { 800, 0, 0 }, 25 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80A20EA0 = { - { COLTYPE_HIT5, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80A20E50, // sJntSphElementsInit, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HIT5, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { 40, 60, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A20EB0 = { - { COLTYPE_HIT5, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT5, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, +}; + +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT5, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 15, 20, -15, { 0, 0, 0 } }, }; +static Vec3f D_80A20EDC = { 0.0f, 20.0f, 0.0f }; + +static Vec3f D_80A20EE8 = { 0.0f, 0.0f, 0.0f }; + const ActorInit En_Syateki_Wf_InitVars = { ACTOR_EN_SYATEKI_WF, ACTORCAT_ENEMY, @@ -58,60 +113,370 @@ const ActorInit En_Syateki_Wf_InitVars = { (ActorFunc)EnSyatekiWf_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A20FBC[] = { +static AnimationInfo sAnimations[] = { + { &gWolfosWaitingAnim, 2.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -1.0f }, + { &gWolfosRunningAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gWolfosRunningAnim, 1.0f, 0.0f, 4.0f, ANIMMODE_ONCE, 1.0f }, + { &gWolfosRunningAnim, 1.0f, 4.0f, 8.0f, ANIMMODE_ONCE, 1.0f }, + { &gWolfosBackflippingAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, + { &gWolfosDamagedAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, 8.0f }, + { &gWolfosRearingUpFallingOverAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -1.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), }; -#endif +static Vec3f D_80A20FC4 = { 0.0f, 0.5f, 0.0f }; -extern ColliderCylinderInit D_80A20E74; -extern ColliderJntSphElementInit D_80A20E50[1]; -extern ColliderJntSphInit D_80A20EA0; -extern ColliderCylinderInit D_80A20EB0; -extern InitChainEntry D_80A20FBC[]; +static Vec3f D_80A20FD0 = { 1200.0f, 0.0f, 0.0f }; -extern UNK_TYPE D_0600A3CC; +static TexturePtr sEyeTextures[] = { + gWolfosNormalEyeOpenTex, + gWolfosNormalEyeHalfTex, + gWolfosNormalEyeNarrowTex, + gWolfosNormalEyeHalfTex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/EnSyatekiWf_Init.s") +void EnSyatekiWf_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnSyatekiWf* this = THIS; + Path* path; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/EnSyatekiWf_Destroy.s") + path = syatekiMan->path; + while (path->unk2 != 2) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A200E0.s") + for (i = 0; i < EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor); i++) { + path = &globalCtx->setupPathList[path->unk1]; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A201CC.s") + if (path == NULL) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20284.s") + this->unk_2A0 = Lib_SegmentedToVirtual(path->points); + this->unk_2A4 = 1; + this->unk_2A6 = path->count; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A2030C.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_29C = 0; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 0.0f); + this->actor.focus.pos = this->actor.world.pos; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.colChkInfo.health = 2; + this->actor.colChkInfo.cylRadius = 50; + this->actor.colChkInfo.cylHeight = 100; + this->eyeIndex = 0; + this->unk_2AC = 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20320.s") + Collider_InitCylinder(globalCtx, &this->unk_2B4); + Collider_SetCylinder(globalCtx, &this->unk_2B4, &this->actor, &sCylinderInit1); + Collider_InitCylinder(globalCtx, &this->unk_300); + Collider_SetCylinder(globalCtx, &this->unk_300, &this->actor, &sCylinderInit2); + Collider_InitJntSph(globalCtx, &this->unk_34C); + Collider_SetJntSph(globalCtx, &this->unk_34C, &this->actor, &sJntSphInit, this->unk_36C); + this->unk_34C.elements->dim.worldSphere.radius = sJntSphInit.elements[0].dim.modelSphere.radius; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20378.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWolfosNormalSkel, &gWolfosWaitingAnim, this->jointTable, + this->morphTable, WOLFOS_NORMAL_LIMB_MAX); + Actor_SetScale(&this->actor, 0.01f); + this->actor.hintId = 0x4C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A203DC.s") + func_80A201CC(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20670.s") +void EnSyatekiWf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiWf* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A206DC.s") + Collider_DestroyCylinder(globalCtx, &this->unk_2B4); + Collider_DestroyCylinder(globalCtx, &this->unk_300); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20710.s") +void func_80A200E0(EnSyatekiWf* this) { + Vec3f sp24; + s16 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A2075C.s") + this->actor.world.pos.x = this->unk_2A0[0].x; + this->actor.world.pos.y = this->unk_2A0[0].y; + this->actor.world.pos.z = this->unk_2A0[0].z; + sp24.x = this->unk_2A0[this->unk_2A4].x; + sp24.y = this->unk_2A0[this->unk_2A4].y; + sp24.z = this->unk_2A0[this->unk_2A4].z; + temp = Math_Vec3f_Yaw(&this->actor.world.pos, &sp24); + this->actor.shape.rot.y = temp; + this->actor.world.rot.y = temp; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A2079C.s") +void func_80A201CC(EnSyatekiWf* this) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20800.s") + this->actor.speedXZ = 0.0f; + this->actor.world = this->actor.home; + this->actor.prevPos = this->actor.home.pos; + this->actor.shape.rot = this->actor.world.rot; + this->actor.colChkInfo.health = 2; + this->actor.draw = NULL; + this->unk_2A4 = 1; + this->unk_298 = 0; + syatekiMan->unk_276 &= ~(1 << EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor)); + this->actionFunc = func_80A20284; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20858.s") +void func_80A20284(EnSyatekiWf* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A208F8.s") + if (this->actor.parent != NULL) { + syatekiMan = (EnSyatekiMan*)this->actor.parent; + if ((syatekiMan->unk_26A == 1) && (this->unk_298 == 1)) { + func_80A200E0(this); + func_80A2030C(this); + } else if (syatekiMan->unk_276 & (1 << EN_SYATEKI_WF_GET_PARAM_FF00(&this->actor))) { + this->unk_298 = 1; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/EnSyatekiWf_Update.s") +void func_80A2030C(EnSyatekiWf* this) { + this->actionFunc = func_80A20320; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20CF4.s") +void func_80A20320(EnSyatekiWf* this, GlobalContext* globalCtx) { + if (this->unk_29C >= 11) { + Actor_PlaySfxAtPos(this->actor.parent, NA_SE_EN_WOLFOS_APPEAR); + this->unk_29C = 0; + func_80A20378(this); + } else { + this->unk_29C++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/func_80A20D10.s") +void func_80A20378(EnSyatekiWf* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 1); + this->actor.speedXZ = 10.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.draw = EnSyatekiWf_Draw; + this->actionFunc = func_80A203DC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Syateki_Wf/EnSyatekiWf_Draw.s") +void func_80A203DC(EnSyatekiWf* this, GlobalContext* globalCtx) { + Vec3f sp54; + f32 sp50; + s16 temp_v0; + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + if (syatekiMan->unk_26A != 1) { + func_80A201CC(this); + } + + sp54.x = this->unk_2A0[this->unk_2A4].x; + sp54.y = this->unk_2A0[this->unk_2A4].y; + sp54.z = this->unk_2A0[this->unk_2A4].z; + temp_v0 = (this->actor.wallYaw - this->actor.world.rot.y) + 0x8000; + + if (this->actor.bgCheckFlags & 1) { + if (this->actor.bgCheckFlags & 8) { + if ((ABS(temp_v0) < 0x1555) && (this->actor.wallPoly != this->actor.floorPoly)) { + func_80A20670(this); + return; + } + } + + if (this->actor.bgCheckFlags & 4) { + this->actor.velocity.y = 2.0f; + } + + sp50 = Math_Vec3f_DistXZ(&this->actor.world.pos, &sp54); + this->unk_2A8 = Math_Vec3f_Yaw(&this->actor.world.pos, &sp54); + + if (sp50 > 15.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2A8, 5, 0x3000, 0x100); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (sp50 < 50.0f) { + if (this->actor.speedXZ > 3.0f) { + this->actor.speedXZ = this->actor.speedXZ - 0.5f; + } else { + this->actor.speedXZ = this->actor.speedXZ; + } + } + } else { + if (this->unk_2A4 < (this->unk_2A6 - 1)) { + if (this->unk_2A4 == EN_SYATEKI_WF_GET_PARAM_F0(&this->actor)) { + func_80A2079C(this); + } + + this->unk_2A4++; + } else { + this->unk_298 = 0; + this->unk_2A4 = 1; + func_80A201CC(this); + } + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 10.0f, 3, 2.0f, 0, 0, 0); + } + } +} + +void func_80A20670(EnSyatekiWf* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP); + this->actor.velocity.y = 20.0f; + this->actor.speedXZ = 5.0f; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80A206DC; +} + +void func_80A206DC(EnSyatekiWf* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 2) { + func_80A20710(this); + } +} + +void func_80A20710(EnSyatekiWf* this) { + this->actor.speedXZ = 0.0f; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 3); + this->actionFunc = func_80A2075C; +} + +void func_80A2075C(EnSyatekiWf* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A20378(this); + } +} + +void func_80A2079C(EnSyatekiWf* this) { + this->unk_29A = 40; + this->actor.speedXZ = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_APPEAR); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 5); + this->actionFunc = func_80A20800; +} + +void func_80A20800(EnSyatekiWf* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_29A--; + if (this->unk_29A == 0) { + func_80A20378(this); + } + } +} + +void func_80A20858(EnSyatekiWf* this, GlobalContext* globalCtx) { + EnSyatekiMan* syatekiMan = (EnSyatekiMan*)this->actor.parent; + + this->unk_298 = 0; + this->actor.speedXZ = 0.0f; + EffectSsExtra_Spawn(globalCtx, &this->actor.world.pos, &D_80A20EDC, &D_80A20EE8, 5, 2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_DEAD); + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, 6); + syatekiMan->unk_280 += 100; + this->actionFunc = func_80A208F8; +} + +void func_80A208F8(EnSyatekiWf* this, GlobalContext* globalCtx) { + s32 pad; + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A201CC(this); + } else { + Vec3f sp68; + Vec3f sp5C = D_80A20FC4; + s32 i; + + for (i = (s32)this->skelAnime.animLength - (s32)this->skelAnime.curFrame; i >= 0; i--) { + sp68.x = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.x; + sp68.z = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.z; + sp68.y = randPlusMinusPoint5Scaled(50.0f) + (this->actor.world.pos.y + 20.0f); + func_800B3030(globalCtx, &sp68, &sp5C, &sp5C, 0x64, 0, 2); + } + } +} + +void EnSyatekiWf_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnSyatekiWf* this = THIS; + + if (this->actionFunc != func_80A20284) { + SkelAnime_Update(&this->skelAnime); + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 32.0f, 30.0f, 60.0f, 5); + this->actionFunc(this, globalCtx); + + if (this->actor.bgCheckFlags & 3) { + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &this->actor.shape.rot); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.x, 0, 1, 0x3E8, 0); + Math_SmoothStepToS(&this->actor.shape.rot.z, 0, 1, 0x3E8, 0); + } + + if ((this->unk_2B4.base.acFlags & AC_HIT) || (this->unk_300.base.acFlags & AC_HIT) || + (this->unk_34C.base.acFlags & AC_HIT)) { + this->unk_2B4.base.acFlags &= ~AC_HIT; + this->unk_300.base.acFlags &= ~AC_HIT; + this->unk_34C.base.acFlags &= ~AC_HIT; + this->actor.colChkInfo.health -= 2; + if (this->actor.colChkInfo.health == 0) { + func_801A3098(NA_BGM_GET_ITEM | 0x900); + func_80A20858(this, globalCtx); + } else { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + EffectSsExtra_Spawn(globalCtx, &this->actor.world.pos, &D_80A20EDC, &D_80A20EE8, 3, 0); + } + } + + Collider_UpdateCylinder(&this->actor, &this->unk_2B4); + if ((this->actionFunc != func_80A20284) && (this->actionFunc != func_80A208F8) && (this->actor.draw != NULL)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_300.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_2B4.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->unk_34C.base); + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 25.0f; + } + + if (this->eyeIndex == 0) { + if ((Rand_ZeroOne() < 0.2f) && ((globalCtx->gameplayFrames & 3) == 0) && (this->actor.colorFilterTimer == 0)) { + this->eyeIndex++; + } + } else { + this->eyeIndex = (this->eyeIndex + 1) & 3; + } +} + +s32 EnSyatekiWf_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + return false; +} + +void EnSyatekiWf_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnSyatekiWf* this = THIS; + Vec3f sp18; + + Collider_UpdateSpheres(limbIndex, &this->unk_34C); + if (limbIndex == WOLFOS_NORMAL_LIMB_TAIL) { + Matrix_MultVec3f(&D_80A20FD0, &sp18); + this->unk_300.dim.pos.x = sp18.x; + this->unk_300.dim.pos.y = sp18.y; + this->unk_300.dim.pos.z = sp18.z; + } +} + +void EnSyatekiWf_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnSyatekiWf* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeIndex])); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnSyatekiWf_OverrideLimbDraw, EnSyatekiWf_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h index ff552ed19..a43c76f77 100644 --- a/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h +++ b/src/overlays/actors/ovl_En_Syateki_Wf/z_en_syateki_wf.h @@ -2,16 +2,36 @@ #define Z_EN_SYATEKI_WF_H #include "global.h" +#include "objects/object_wf/object_wf.h" + +#define EN_SYATEKI_WF_GET_PARAM_F0(thisx) (((thisx)->params & 0xF0) >> 4) +#define EN_SYATEKI_WF_GET_PARAM_FF00(thisx) (((thisx)->params & 0xFF00) >> 8) struct EnSyatekiWf; typedef void (*EnSyatekiWfActionFunc)(struct EnSyatekiWf*, GlobalContext*); typedef struct EnSyatekiWf { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x150]; - /* 0x0294 */ EnSyatekiWfActionFunc actionFunc; - /* 0x0298 */ char unk_298[0x134]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[WOLFOS_NORMAL_LIMB_MAX]; + /* 0x20C */ Vec3s morphTable[WOLFOS_NORMAL_LIMB_MAX]; + /* 0x290 */ UNK_TYPE1 unk_290[0x4]; + /* 0x294 */ EnSyatekiWfActionFunc actionFunc; + /* 0x298 */ s16 unk_298; + /* 0x29A */ s16 unk_29A; + /* 0x29C */ s16 unk_29C; + /* 0x2A0 */ Vec3s* unk_2A0; + /* 0x2A4 */ s16 unk_2A4; + /* 0x2A6 */ s16 unk_2A6; + /* 0x2A8 */ s16 unk_2A8; + /* 0x2AC */ f32 unk_2AC; + /* 0x2B0 */ u8 eyeIndex; + /* 0x2B4 */ ColliderCylinder unk_2B4; + /* 0x300 */ ColliderCylinder unk_300; + /* 0x34C */ ColliderJntSph unk_34C; + /* 0x36C */ ColliderJntSphElement unk_36C[1]; + /* 0x3AC */ UNK_TYPE1 unk_3AC[0x20]; } EnSyatekiWf; // size = 0x3CC extern const ActorInit En_Syateki_Wf_InitVars; diff --git a/src/overlays/actors/ovl_En_Tab/z_en_tab.c b/src/overlays/actors/ovl_En_Tab/z_en_tab.c index 451c762d7..5745da0fd 100644 --- a/src/overlays/actors/ovl_En_Tab/z_en_tab.c +++ b/src/overlays/actors/ovl_En_Tab/z_en_tab.c @@ -1,6 +1,14 @@ -#include "z_en_tab.h" +/* + * File: z_en_tab.c + * Overlay: ovl_En_Tab + * Description: Talon B - Mr. Barten + */ -#define FLAGS 0x00000039 +#include "z_en_tab.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_tab/object_tab.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTab*)thisx) @@ -12,7 +20,52 @@ void EnTab_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BE127C(EnTab* this, GlobalContext* globalCtx); void func_80BE1348(EnTab* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80BE18D0[] = { + /* 0x00 */ SCHEDULE_CMD_CHECK_NOT_IN_DAY_S(3, 0x24 - 0x04), + /* 0x04 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0x23 - 0x08), + /* 0x08 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 50, 18, 1, 0x1D - 0x0E), + /* 0x0E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(18, 0, 6, 0, 0x17 - 0x14), + /* 0x14 */ SCHEDULE_CMD_RET_VAL_L(0), + /* 0x17 */ SCHEDULE_CMD_RET_TIME(18, 0, 6, 0, 2), + /* 0x1D */ SCHEDULE_CMD_RET_TIME(9, 50, 18, 1, 1), + /* 0x23 */ SCHEDULE_CMD_RET_NONE(), + /* 0x24 */ SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S(SCENE_MILK_BAR, 0x41 - 0x28), + /* 0x28 */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(9, 50, 21, 5, 0x3B - 0x2E), + /* 0x2E */ SCHEDULE_CMD_CHECK_TIME_RANGE_S(21, 55, 5, 5, 0x35 - 0x34), + /* 0x34 */ SCHEDULE_CMD_RET_NONE(), + /* 0x35 */ SCHEDULE_CMD_RET_TIME(21, 55, 5, 5, 2), + /* 0x3B */ SCHEDULE_CMD_RET_TIME(9, 50, 21, 5, 1), + /* 0x41 */ SCHEDULE_CMD_RET_NONE(), +}; + +s32 D_80BE1914[] = { + 0x003A0200, 0x080E2AF9, 0x0C113A02, 0x100E2AFA, 0x0C150900, 0x000E2AFB, + 0x0C003401, 0x00090F2A, 0xFD0C0F2A, 0xFE0C100F, 0x2AFC0C10, +}; + +s32 D_80BE1940[] = { + 0x003F0400, 0x080E2B3D, 0x0C113F04, 0x100E2B3E, 0x0C0F2AFA, 0x0C150900, + 0x000E2AFB, 0x0C003401, 0x00090F2A, 0xFD0C0F2A, 0xFE0C100F, 0x2AFC0C10, +}; + +s32 D_80BE1970[] = { 0x003A0100, 0x080E2AFF, 0x0C113A01, 0x100E2B00, 0x0C100000 }; + +s32 D_80BE1984[] = { 0x00500100, 0x080E2B3F, 0x0C115001, 0x100E2B40, 0x0C100000 }; + +s32 D_80BE1998[] = { 0x0E2B090C, 0x10000000 }; + +s32 D_80BE19A0[] = { + 0x0E2B0A0C, 0x05004E00, 0x00004E30, 0x2800050E, 0x2B0E0C10, 0x0E2B0B0C, 0x05000000, 0x08001008, 0x00140026, + 0x19000E08, 0x00C8000F, 0x19000631, 0x0E2B0D0C, 0x10320E2B, 0x0C0C1030, 0x1214FF38, 0x06009100, 0x00130091, + 0x0C103012, 0x14FFEC06, 0x00920000, 0x1300920C, 0x10300034, 0x0100050E, 0x2B0F0C10, 0x0E2B110C, 0x10000000, +}; + +s32 D_80BE1A0C[] = { + 0x0E2B0A0C, 0x05004E00, 0x00004E30, 0x2800050E, 0x2B0E0C10, 0x0E2B0B0C, 0x05000000, 0x08001008, 0x00140026, + 0x19000E08, 0x00C8000F, 0x19000631, 0x0E2B0D0C, 0x10320E2B, 0x0C0C1030, 0x1214FF38, 0x06009100, 0x00130091, + 0x0C103012, 0x14FFEC06, 0x00920000, 0x1300920C, 0x10300034, 0x0100050E, 0x2B100C10, 0x0E2B110C, 0x10000000, +}; + const ActorInit En_Tab_InitVars = { ACTOR_EN_TAB, ACTORCAT_NPC, @@ -25,75 +78,555 @@ const ActorInit En_Tab_InitVars = { (ActorFunc)EnTab_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BE1A98 = { - { 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 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BE1AC4 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +AnimationInfoS D_80BE1AD0[] = { + { &object_tab_Anim_000758, 1.0f, 0, -1, 0, 0 }, + { &object_tab_Anim_0086AC, 1.0f, 0, -1, 0, 0 }, +}; -extern ColliderCylinderInit D_80BE1A98; -extern CollisionCheckInfoInit2 D_80BE1AC4; +Vec3f D_80BE1AF0 = { -28.0f, -8.0f, -195.0f }; -extern UNK_TYPE D_06007F78; +Vec3s D_80BE1AFC = { 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE04E0.s") +Vec3f D_80BE1B04 = { 161.0f, 0.0f, -10.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0590.s") +Vec3s D_80BE1B10 = { 0, 0xC000, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE05BC.s") +Vec3f D_80BE1B18 = { 800.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0620.s") +TexturePtr D_80BE1B24[] = { + object_tab_Tex_006428, + object_tab_Tex_006928, + object_tab_Tex_006D28, + object_tab_Tex_006928, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0664.s") +EnGm* func_80BE04E0(EnTab* this, GlobalContext* globalCtx, u8 actorCat, s16 actorId) { + Actor* foundActor = NULL; + Actor* tempActor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE06DC.s") + while (true) { + foundActor = SubS_FindActor(globalCtx, foundActor, actorCat, actorId); + if ((foundActor == NULL) || (((EnTab*)foundActor != this) && (foundActor->update != NULL))) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0778.s") + tempActor = foundActor->next; + if (tempActor == NULL) { + foundActor = NULL; + break; + } + foundActor = tempActor; + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE07A0.s") + return (EnGm*)foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE09A8.s") +void func_80BE0590(EnTab* this) { + this->skelAnime.playSpeed = this->unk_300; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0A98.s") +s32 func_80BE05BC(EnTab* this, s32 arg1) { + s32 phi_v0 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0C04.s") + if (arg1 != this->unk_32C) { + phi_v0 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0D38.s") + if (phi_v0) { + this->unk_32C = arg1; + ret = SubS_ChangeAnimationByInfoS(&this->skelAnime, D_80BE1AD0, arg1); + this->unk_300 = this->skelAnime.playSpeed; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0D60.s") +void func_80BE0620(EnTab* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0E04.s") + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0F04.s") +void func_80BE0664(EnTab* this) { + if (DECR(this->unk_31C) == 0) { + this->unk_31E++; + if (this->unk_31E > 3) { + this->unk_31C = Rand_S16Offset(30, 30); + this->unk_31E = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE0FC4.s") +s32 func_80BE06DC(EnTab* this, GlobalContext* globalCtx) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE1060.s") + if (this->unk_2FC & 7) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + SubS_UpdateFlags(&this->unk_2FC, 0, 7); + ret = true; + this->unk_320 = 0; + this->unk_328 = NULL; + this->actor.child = &GET_PLAYER(globalCtx)->actor; + this->unk_2FC |= 8; + this->actionFunc = func_80BE1348; + } + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE10BC.s") +Actor* func_80BE0778(EnTab* this, GlobalContext* globalCtx) { + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE1224.s") + if (this->unk_1D8 == 1) { + actor = this->actor.child; + } else { + actor = &GET_PLAYER(globalCtx)->actor; + } + return actor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE127C.s") +void func_80BE07A0(EnTab* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE1348.s") + Math_Vec3f_Copy(&sp40, &this->unk_1E0->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/EnTab_Init.s") + Math_ApproachS(&this->unk_314, (sp32 - this->unk_318) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_314 = CLAMP(this->unk_314, -0x1FFE, 0x1FFE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/EnTab_Destroy.s") + Math_ApproachS(&this->unk_318, (sp32 - this->unk_314) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_318 = CLAMP(this->unk_318, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/EnTab_Update.s") + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + if (this->unk_1E0->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_1E0)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_1E0->focus.pos); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE1648.s") + Math_ApproachS(&this->unk_312, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_316, 4, 0x2AA8); + this->unk_312 = CLAMP(this->unk_312, -0x1554, 0x1554); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE16B4.s") + Math_ApproachS(&this->unk_316, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_312, 4, 0x2AA8); + this->unk_316 = CLAMP(this->unk_316, -0xE38, 0xE38); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/func_80BE1704.s") +void func_80BE09A8(EnTab* this, GlobalContext* globalCtx) { + this->unk_1E0 = func_80BE0778(this, globalCtx); + if ((this->unk_2FC & 8) && (this->unk_1E0 != 0) && (DECR(this->unk_324) == 0)) { + func_80BE07A0(this); + this->unk_316 = 0; + this->unk_318 = 0; + this->unk_2FC &= ~0x40; + this->unk_2FC |= 0x10; + } else if (this->unk_2FC & 0x10) { + this->unk_2FC &= ~0x10; + this->unk_312 = 0; + this->unk_314 = 0; + this->unk_316 = 0; + this->unk_318 = 0; + this->unk_324 = 20; + } else if (DECR(this->unk_324) == 0) { + this->unk_2FC |= 0x40; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tab/EnTab_Draw.s") +void func_80BE0A98(EnTab* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp20 = Message_GetState(&globalCtx->msgCtx); + + this->unk_308 += (this->unk_304 != 0.0f) ? 40.0f : -40.0f; + this->unk_308 = CLAMP(this->unk_308, 0.0f, 80.0f); + + Matrix_Translate(this->unk_308, 0.0f, 0.0f, MTXMODE_APPLY); + + if ((&this->actor == player->targetActor) && + ((globalCtx->msgCtx.currentTextId < 0xFF) || (globalCtx->msgCtx.currentTextId > 0x200)) && (sp20 == 3) && + (this->unk_334 == 3)) { + if ((globalCtx->state.frames % 2) == 0) { + if (this->unk_304 != 0.0f) { + this->unk_304 = 0.0f; + } else { + this->unk_304 = 1.0f; + } + } + } else { + this->unk_304 = 0.0f; + } + this->unk_334 = sp20; +} + +s32 func_80BE0C04(EnTab* this, Actor* actor, f32 arg2) { + Vec3f sp44; + Vec3f sp38; + s32 ret = false; + f32 sp30; + s16 sp2E; + + if (actor != NULL) { + Math_Vec3f_Copy(&sp38, &this->actor.world.pos); + Math_Vec3f_Copy(&sp44, &actor->world.pos); + sp2E = Math_Vec3f_Yaw(&sp38, &sp44); + + if (this->unk_338) { + sp30 = arg2; + } else { + sp30 = arg2 * 0.5f; + } + if ((Math_Vec3f_DistXZ(&sp44, &sp38) < sp30) && (ABS_ALT(BINANG_SUB(sp2E, this->actor.shape.rot.y)) < 0x38E0)) { + ret = true; + } + + if (DECR(this->unk_322) == 0) { + this->unk_338 ^= true; + this->unk_322 = Rand_S16Offset(60, 60); + } + } + return ret; +} + +s32 func_80BE0D38(EnTab* this, GlobalContext* globalCtx) { + return Interface_HasEmptyBottle(); +} + +s32 func_80BE0D60(EnTab* this, GlobalContext* globalCtx) { + s32 pad; + s32 ret = false; + + this->unk_320++; + if (this->unk_320 == 1) { + globalCtx->setPlayerTalkAnim(globalCtx, &gameplay_keep_Linkanim_00D568, 2); + } else if (this->unk_320 > 20) { + globalCtx->setPlayerTalkAnim(globalCtx, NULL, 0); + this->unk_320 = 0; + ret = true; + } + return ret; +} + +s32* func_80BE0E04(EnTab* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->transformation == PLAYER_FORM_DEKU) { + return D_80BE1984; + } + + switch (this->unk_1D8) { + case 2: + this->unk_328 = func_80BE0D38; + if (Player_GetMask(globalCtx) != PLAYER_MASK_ROMANI) { + return D_80BE1998; + } + + if (gSaveContext.save.day == 3) { + return D_80BE1A0C; + } + return D_80BE19A0; + + case 1: + this->unk_328 = func_80BE0D60; + if (Player_GetMask(globalCtx) == PLAYER_MASK_ROMANI) { + return D_80BE1940; + } + + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + return D_80BE1970; + } + return D_80BE1914; + } + + return NULL; +} + +s32 func_80BE0F04(EnTab* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret = false; + EnGm* sp28 = func_80BE04E0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_GM); + + if (sp28) { + Math_Vec3f_Copy(&this->actor.world.pos, &D_80BE1AF0); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80BE1AFC); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + this->actor.targetMode = 0; + SubS_UpdateFlags(&this->unk_2FC, 3, 7); + this->unk_2FC |= (0x40 | 0x20); + this->unk_30C = 30; + this->unk_1E4 = sp28; + func_80BE05BC(this, 0); + ret = true; + } + return ret; +} + +s32 func_80BE0FC4(EnTab* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80BE1B04); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80BE1B10); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + this->actor.targetMode = 6; + SubS_UpdateFlags(&this->unk_2FC, 3, 7); + this->unk_2FC |= (0x40 | 0x20); + this->unk_30C = 0x50; + func_80BE05BC(this, 1); + return true; +} + +s32 func_80BE1060(EnTab* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 ret; + + this->unk_2FC = 0; + + switch (arg2->result) { + case 1: + ret = func_80BE0F04(this, globalCtx, arg2); + break; + + case 2: + ret = func_80BE0FC4(this, globalCtx, arg2); + break; + + default: + ret = false; + break; + } + return ret; +} + +s32 func_80BE10BC(EnTab* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + f32 dist; + Actor* tempActor; + + switch (this->unk_1D8) { + case 1: + if ((player->stateFlags1 & 0x40) && !(globalCtx->msgCtx.currentTextId <= 0x2B00) && + (globalCtx->msgCtx.currentTextId < 0x2B08)) { + this->actor.child = &this->unk_1E4->actor; + this->unk_2FC |= 8; + } else { + dist = Math_Vec3f_DistXYZ(&this->actor.world.pos, &this->unk_1E4->actor.world.pos); + + if ((gSaveContext.save.weekEventReg[75] & 1) || (this->unk_1E4->actor.draw == NULL) || + !(dist < 160.0f)) { + tempActor = &GET_PLAYER(globalCtx)->actor; + this->actor.child = tempActor; + } else { + tempActor = &this->unk_1E4->actor; + this->actor.child = tempActor; + } + + if (func_80BE0C04(this, tempActor, 160.0f)) { + this->unk_2FC |= 8; + } else { + this->unk_2FC &= ~8; + } + } + break; + + case 2: + if (func_80BE0C04(this, &GET_PLAYER(globalCtx)->actor, 200.0f)) { + this->unk_2FC |= 8; + } else { + this->unk_2FC &= ~8; + } + break; + } + + return false; +} + +void func_80BE1224(EnTab* this, GlobalContext* globalCtx) { + if ((this->unk_1D8 == 1) || (this->unk_1D8 == 2)) { + func_80BE10BC(this, globalCtx); + } + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80BE127C(EnTab* this, GlobalContext* globalCtx) { + ScheduleResult sp18; + + this->unk_31A = REG(15) + ((void)0, gSaveContext.save.daySpeed); + + if (!Schedule_RunScript(globalCtx, D_80BE18D0, &sp18) || + ((this->unk_1D8 != sp18.result) && !func_80BE1060(this, globalCtx, &sp18))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + sp18.result = 0; + } else { + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + } + this->unk_1D8 = sp18.result; + func_80BE1224(this, globalCtx); +} + +void func_80BE1348(EnTab* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + + if (func_8010BF58(&this->actor, globalCtx, func_80BE0E04(this, globalCtx), this->unk_328, &this->unk_1DC)) { + SubS_UpdateFlags(&this->unk_2FC, 3, 7); + this->unk_2FC &= ~8; + this->unk_2FC |= 0x40; + this->unk_324 = 20; + this->unk_1DC = 0; + this->actionFunc = func_80BE127C; + } else if (this->unk_1E0 != 0) { + Math_Vec3f_Copy(&sp40, &this->unk_1E0->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&sp34, &sp40), 4, 0x2AA8); + } +} + +void EnTab_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTab* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 14.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tab_Skel_007F78, NULL, this->jointTable, this->morphTable, + 20); + this->unk_32C = -1; + func_80BE05BC(this, 0); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + + this->unk_1D8 = 0; + this->unk_328 = NULL; + this->unk_2FC = 0; + this->unk_2FC |= 0x40; + this->actor.gravity = -1.0f; + + this->actionFunc = func_80BE127C; + this->actionFunc(this, globalCtx); +} + +void EnTab_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTab* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnTab_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTab* this = THIS; + f32 radius; + f32 height; + + func_80BE06DC(this, globalCtx); + + this->actionFunc(this, globalCtx); + + if (this->unk_1D8 != 0) { + func_80BE0590(this); + func_80BE0664(this); + func_80BE09A8(this, globalCtx); + + radius = this->collider.dim.radius + this->unk_30C; + height = this->collider.dim.height + 10; + + func_8013C964(&this->actor, globalCtx, radius, height, EXCH_ITEM_NONE, this->unk_2FC & 7); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + func_80BE0620(this, globalCtx); + } +} + +s32 EnTab_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnTab* this = THIS; + + if (limbIndex == 9) { + func_80BE0A98(this, globalCtx); + } + + if ((this->unk_32C == 1) && (limbIndex == 18)) { + *dList = NULL; + } + return false; +} + +void EnTab_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTab* this = THIS; + + if (limbIndex == 9) { + Matrix_MultVec3f(&D_80BE1B18, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } +} + +void EnTab_TransformDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTab* this = THIS; + s32 rotStep; + s32 overrideStep; + + if (!(this->unk_2FC & 0x40)) { + if (this->unk_2FC & 0x10) { + overrideStep = true; + } else { + overrideStep = false; + } + rotStep = true; + } else { + overrideStep = false; + rotStep = false; + } + + if (limbIndex == 9) { + SubS_UpdateLimb(BINANG_ADD(this->unk_312 + this->unk_316, 0x4000), + BINANG_ADD(this->unk_314 + this->unk_318 + this->actor.shape.rot.y, 0x4000), this->unk_1E8, + this->unk_200, rotStep, overrideStep); + Matrix_Pop(); + Matrix_Translate(this->unk_1E8[0].x, this->unk_1E8[0].y, this->unk_1E8[0].z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_200[0].y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_200[0].x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_200[0].z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +void EnTab_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTab* this = THIS; + + if (this->unk_1D8 != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BE1B24[this->unk_31E])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTab_OverrideLimbDraw, EnTab_PostLimbDraw, + EnTab_TransformDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Tab/z_en_tab.h b/src/overlays/actors/ovl_En_Tab/z_en_tab.h index 45f6a057d..266949fe8 100644 --- a/src/overlays/actors/ovl_En_Tab/z_en_tab.h +++ b/src/overlays/actors/ovl_En_Tab/z_en_tab.h @@ -2,16 +2,47 @@ #define Z_EN_TAB_H #include "global.h" +#include "overlays/actors/ovl_En_Gm/z_en_gm.h" struct EnTab; typedef void (*EnTabActionFunc)(struct EnTab*, GlobalContext*); +typedef s32 (*EnTabUnkFunc)(struct EnTab*, GlobalContext*); typedef struct EnTab { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnTabActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x1B0]; + /* 0x018C */ ColliderCylinder collider; + /* 0x01D8 */ u8 unk_1D8; + /* 0x01DC */ s32 unk_1DC; + /* 0x01E0 */ Actor* unk_1E0; + /* 0x01E4 */ EnGm* unk_1E4; + /* 0x01E8 */ Vec3f unk_1E8[2]; + /* 0x0200 */ Vec3s unk_200[2]; + /* 0x020C */ Vec3s jointTable[20]; + /* 0x0284 */ Vec3s morphTable[20]; + /* 0x02FC */ u16 unk_2FC; + /* 0x0300 */ f32 unk_300; + /* 0x0304 */ f32 unk_304; + /* 0x0308 */ f32 unk_308; + /* 0x030C */ s16 unk_30C; + /* 0x030E */ UNK_TYPE1 unk30E[4]; + /* 0x0312 */ s16 unk_312; + /* 0x0314 */ s16 unk_314; + /* 0x0316 */ s16 unk_316; + /* 0x0318 */ s16 unk_318; + /* 0x031A */ s16 unk_31A; + /* 0x031C */ s16 unk_31C; + /* 0x031E */ s16 unk_31E; + /* 0x0320 */ s16 unk_320; + /* 0x0322 */ s16 unk_322; + /* 0x0324 */ s16 unk_324; + /* 0x0328 */ EnTabUnkFunc unk_328; + /* 0x032C */ s32 unk_32C; + /* 0x0330 */ UNK_TYPE1 unk330[4]; + /* 0x0334 */ s32 unk_334; + /* 0x0338 */ s32 unk_338; } EnTab; // size = 0x33C extern const ActorInit En_Tab_InitVars; diff --git a/src/overlays/actors/ovl_En_Tag_Obj/z_en_tag_obj.c b/src/overlays/actors/ovl_En_Tag_Obj/z_en_tag_obj.c index dec8347bc..5504dabdb 100644 --- a/src/overlays/actors/ovl_En_Tag_Obj/z_en_tag_obj.c +++ b/src/overlays/actors/ovl_En_Tag_Obj/z_en_tag_obj.c @@ -1,3 +1,9 @@ +/* + * File: z_en_tag_obj.c + * Overlay: ovl_En_Tag_Obj + * Description: + */ + #include "z_en_tag_obj.h" #define FLAGS 0x00000000 @@ -41,7 +47,7 @@ const ActorInit En_Tag_Obj_InitVars = { }; void EnTagObj_Init(Actor* thisx, GlobalContext* globalCtx) { - EnTagObj* this = (EnTagObj*)thisx; + EnTagObj* this = THIS; this->hasSpawnedSeahorse = 0; } @@ -50,7 +56,7 @@ void EnTagObj_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void EnTagObj_Update(Actor* thisx, GlobalContext* globalCtx) { - EnTagObj* this = (EnTagObj*)thisx; + EnTagObj* this = THIS; if (!this->hasSpawnedSeahorse) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_OT, this->actor.world.pos.x, this->actor.world.pos.y, diff --git a/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c b/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c index b7715b6ab..35dc1ba30 100644 --- a/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c +++ b/src/overlays/actors/ovl_En_Takaraya/z_en_takaraya.c @@ -1,6 +1,12 @@ +/* + * File: z_en_takaraya.c + * Overlay: ovl_En_Takaraya + * Description: Treasure Chest Shop Gal + */ + #include "z_en_takaraya.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTakaraya*)thisx) 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 960bdbb05..4cf4ca407 100644 --- a/src/overlays/actors/ovl_En_Talk/z_en_talk.c +++ b/src/overlays/actors/ovl_En_Talk/z_en_talk.c @@ -1,17 +1,21 @@ +/* + * File: z_en_talk.c + * Overlay: ovl_En_Talk + * Description: Green Target Spot (e.g., Indigo-Go's Poster) + */ + #include "z_en_talk.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnTalk*)thisx) 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, @@ -24,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 (Actor_TextboxIsClosing(&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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BDE058; + return; + } + + if ((this->actor.xzDistToPlayer < 40.0f && Player_IsFacingActor(&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 ab563ab23..a52c9391d 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 @@ -1,6 +1,12 @@ +/* + * File: z_en_talk_gibud.c + * Overlay: ovl_En_Talk_Gibud + * Description: Gibdos requesting items Beneath the Well + */ + #include "z_en_talk_gibud.h" -#define FLAGS 0x00000415 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((EnTalkGibud*)thisx) @@ -9,7 +15,92 @@ 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_SetupAttemptPlayerFreeze(EnTalkGibud* this); +void EnTalkGibud_AttemptPlayerFreeze(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_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; + +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_BACK, + /* 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_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; + const ActorInit En_Talk_Gibud_InitVars = { ACTOR_EN_TALK_GIBUD, ACTORCAT_ENEMY, @@ -22,166 +113,1101 @@ 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 AnimationInfo sAnimations[] = { + { &gGibdoRedeadGrabAttackAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadGrabEndAnim, 0.5f, 0.0f, 0.0f, ANIMMODE_ONCE_INTERP, 0.0f }, + { &gGibdoRedeadGrabStartAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadLookBackAnim, 0.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadWipingTearsAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadSobbingAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadDeathAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadDamageAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadStandUpAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_ONCE, -8.0f }, + { &gGibdoRedeadIdleAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadWalkAnim, 0.4f, 0.0f, 0.0f, ANIMMODE_LOOP_INTERP, -8.0f }, + { &gGibdoRedeadSquattingDanceAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadPirouetteAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -8.0f }, + { &gGibdoRedeadClappingDanceAnim, 1.0f, 0.0f, 0.0f, ANIMMODE_LOOP, -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, applies a fire effect, 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Destroy.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGibdoSkel, &gGibdoRedeadIdleAnim, this->jointTable, + this->morphTable, GIBDO_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEB38.s") + this->playerStunWaitTimer = 0; + this->grabState = EN_TALK_GIBUD_GRAB_START; + this->grabWaitTimer = 0; + this->itemActionParam = PLAYER_AP_NONE; + this->drawDmgEffTimer = 0; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + 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->drawDmgEffAlpha = 0.0f; + this->drawDmgEffScale = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEB7C.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_80AFEC08.s") + if (this->requestedItemIndex < EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION) { + this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEC4C.s") + 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_80AFED08.s") + if (this->switchFlag == 0xFF) { + this->switchFlag = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFED7C.s") + 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_80AFEFD4.s") + EnTalkGibud_SetupIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF030.s") +void EnTalkGibud_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTalkGibud* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF22C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF288.s") +void EnTalkGibud_SetupIdle(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actionFunc = EnTalkGibud_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF330.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_SetupAttemptPlayerFreeze(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF378.s") + 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_80AFF45C.s") +void EnTalkGibud_SetupAttemptPlayerFreeze(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actionFunc = EnTalkGibud_AttemptPlayerFreeze; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF4AC.s") +void EnTalkGibud_AttemptPlayerFreeze(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_80AFF618.s") + if (ABS_ALT(yaw) < 0x2008) { + player->actor.freezeTimer = 60; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + func_80123E90(globalCtx, &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_AIM); + EnTalkGibud_SetupWalkToPlayer(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF6A0.s") + EnTalkGibud_TurnTowardsPlayer(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF700.s") +void EnTalkGibud_SetupWalkToPlayer(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_WALK); + this->actor.speedXZ = 0.4f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF76C.s") + if (this->actionFunc == EnTalkGibud_AttemptPlayerFreeze) { + this->playerStunWaitTimer = 80; + } else { + this->playerStunWaitTimer = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF880.s") + this->actionFunc = EnTalkGibud_WalkToPlayer; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF8E4.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_80AFF9CC.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, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 0x64, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFA68.s") + if (EnTalkGibud_PlayerInRangeWithCorrectState(this, globalCtx) && Actor_IsFacingPlayer(&this->actor, 0x38E3)) { + if ((this->grabWaitTimer == 0) && (this->actor.xzDistToPlayer <= 45.0f)) { + player->actor.freezeTimer = 0; + if (gSaveContext.save.playerForm == PLAYER_FORM_GORON || gSaveContext.save.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); + Actor_PlaySfxAtPos(&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); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFAB0.s") + if (this->grabWaitTimer > 0) { + this->grabWaitTimer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFC10.s") + if (Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 22.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_RIZA_WALK); + } else if (!(globalCtx->gameplayFrames & 95)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFC9C.s") +void EnTalkGibud_SetupGrab(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_START); + this->grabDamageTimer = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->grabState = EN_TALK_GIBUD_GRAB_START; + this->actionFunc = EnTalkGibud_Grab; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFD3C.s") +void EnTalkGibud_Grab(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player2 = GET_PLAYER(globalCtx); + Player* player = player2; + s32 inPositionToAttack; + u16 damageSfxId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFE3C.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; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_ATTACK); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFE94.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_80AFFFA4.s") + damageSfxId = player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S; + globalCtx->damagePlayer(globalCtx, -8); + func_800B8E58(player, 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_80AFFFBC.s") + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_ATTACK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B000FC.s") + if (!(player->stateFlags2 & 0x80) || (player->unk_B62 != 0)) { + if ((player->unk_B62 != 0) && (player->stateFlags2 & 0x80)) { + player->stateFlags2 &= ~0x80; + player->unk_AE8 = 100; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00158.s") + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_END); + this->actor.flags |= ACTOR_FLAG_1; + this->grabState = EN_TALK_GIBUD_GRAB_RELEASE; + this->grabDamageTimer = 0; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00384.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_80B0040C.s") +void EnTalkGibud_SetupGrabFail(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->actor.speedXZ = -2.0f; + this->actionFunc = EnTalkGibud_GrabFail; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00484.s") +void EnTalkGibud_GrabFail(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.15f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B004D0.s") + 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_80B005EC.s") +void EnTalkGibud_SetupTurnAwayAndShakeHead(EnTalkGibud* this) { + this->headShakeTimer = 0; + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_WALK); + this->actionFunc = EnTalkGibud_TurnAwayAndShakeHead; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00760.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_80B008BC.s") +void EnTalkGibud_SetupWalkToHome(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&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_80B008FC.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; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B0094C.s") + 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.save.playerForm != PLAYER_FORM_GORON && gSaveContext.save.playerForm != PLAYER_FORM_DEKU && + Actor_IsFacingPlayer(&this->actor, 0x38E3)) { + EnTalkGibud_SetupWalkToPlayer(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00B8C.s") +void EnTalkGibud_SetupStunned(EnTalkGibud* this) { + this->stunTimer = 10; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00C94.s") + if (this->drawDmgEffTimer != 0) { + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x28); + } else { + Actor_SetColorFilter(&this->actor, 0, 0xC8, 0, 0x28); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00D9C.s") + this->actionFunc = EnTalkGibud_Stunned; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Update.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); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00F08.s") + if (this->stunTimer != 0) { + this->stunTimer--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00F64.s") +void EnTalkGibud_SetupDamage(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DAMAGE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->stunTimer = 0; + this->grabWaitTimer = 0; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.speedXZ = -2.0f; + this->actionFunc = EnTalkGibud_Damage; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Draw.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->drawDmgEffTimer > 0) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) && + (this->type == EN_TALK_GIBUD_TYPE_GIBDO)) { + this->actor.hintId = 0x2A; + this->actor.flags &= ~(ACTOR_FLAG_8 | ACTOR_FLAG_1); + this->actor.flags |= (ACTOR_FLAG_4 | ACTOR_FLAG_1); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gRedeadSkel, NULL, this->jointTable, this->morphTable, + GIBDO_LIMB_MAX); + this->type = EN_TALK_GIBUD_TYPE_REDEAD; + } + + if (EnTalkGibud_PlayerOutOfRange(this, globalCtx)) { + EnTalkGibud_SetupWalkToHome(this); + } else { + EnTalkGibud_SetupWalkToPlayer(this); + } + } +} + +void EnTalkGibud_SetupDead(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DEATH); + this->actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_DEAD); + this->deathTimer = 0; + this->actionFunc = EnTalkGibud_Dead; +} + +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->drawDmgEffTimer > 0) && (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FIRE) && + (this->type == EN_TALK_GIBUD_TYPE_GIBDO)) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gRedeadSkel, NULL, this->jointTable, this->morphTable, + GIBDO_LIMB_MAX); + this->type = EN_TALK_GIBUD_TYPE_REDEAD; + } +} + +void EnTalkGibud_SetupRevive(EnTalkGibud* this) { + Animation_Change(&this->skelAnime, &gGibdoRedeadDeathAnim, -1.0f, Animation_GetLastFrame(&gGibdoRedeadDeathAnim), + 0.0f, 2, -8.0f); + this->actor.flags |= ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_REDEAD_REVERSE); + this->deathTimer = 0; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnTalkGibud_Revive; +} + +void EnTalkGibud_Revive(EnTalkGibud* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->actor.colChkInfo.health = 8; + EnTalkGibud_SetupIdle(this); + } +} + +void EnTalkGibud_GetTextIdForRequestedItem(EnTalkGibud* this, GlobalContext* globalCtx) { + switch (this->requestedItemIndex) { + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION: + Message_StartTextbox(globalCtx, 0x138C, &this->actor); + this->textId = 0x138C; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BEANS: + Message_StartTextbox(globalCtx, 0x138D, &this->actor); + this->textId = 0x138D; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_SPRING_WATER: + Message_StartTextbox(globalCtx, 0x138E, &this->actor); + this->textId = 0x138E; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_FISH: + Message_StartTextbox(globalCtx, 0x138F, &this->actor); + this->textId = 0x138F; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BUGS: + Message_StartTextbox(globalCtx, 0x1390, &this->actor); + this->textId = 0x1390; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_DEKU_NUTS: + Message_StartTextbox(globalCtx, 0x1391, &this->actor); + this->textId = 0x1391; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BOMBS: + Message_StartTextbox(globalCtx, 0x1392, &this->actor); + this->textId = 0x1392; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_HOT_SPRING_WATER: + Message_StartTextbox(globalCtx, 0x1393, &this->actor); + this->textId = 0x1393; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BIG_POE: + Message_StartTextbox(globalCtx, 0x1394, &this->actor); + this->textId = 0x1394; + break; + + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK: + Message_StartTextbox(globalCtx, 0x1395, &this->actor); + this->textId = 0x1395; + break; + } +} + +void EnTalkGibud_GetNextTextBoxId(EnTalkGibud* this, GlobalContext* globalCtx) { + if (Message_ShouldAdvance(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 + Message_StartTextbox(globalCtx, 0xFF, &this->actor); + this->textId = 0xFF; + break; + } + } +} + +s32 EnTalkGibud_PresentedItemMatchesRequest(EnTalkGibud* this, GlobalContext* globalCtx, s32 presentedItemActionParam) { + EnTalkGibudRequestedItem* requestedItem = &sRequestedItemTable[this->requestedItemIndex]; + + 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 (Interface_HasItemInBottle(requestedItem->item)) { + return EN_TALK_GIBUD_REQUESTED_ITEM_MET; + } + } + return EN_TALK_GIBUD_REQUESTED_ITEM_NOT_MET; +} + +void EnTalkGibud_CheckPresentedItem(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 itemActionParam; + + 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) { + Message_StartTextbox(globalCtx, 0x1389, &this->actor); + this->textId = 0x1389; + } + } +} + +void EnTalkGibud_SetupPassiveIdle(EnTalkGibud* this) { + this->isTalking = false; + if (this->actionFunc != EnTalkGibud_Talk) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + } + this->actionFunc = EnTalkGibud_PassiveIdle; +} + +/** + * 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->isTalking = true; + Message_StartTextbox(globalCtx, 0x1388, &this->actor); + this->textId = 0x1388; + Actor_PlaySfxAtPos(&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); + } +} + +void EnTalkGibud_SetupTalk(EnTalkGibud* this) { + this->itemActionParam = PLAYER_AP_NONE; + this->actionFunc = EnTalkGibud_Talk; +} + +void EnTalkGibud_Talk(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnTalkGibudRequestedItem* requestedItem; + + switch (Message_GetState(&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 (Message_ShouldAdvance(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 |= ACTOR_FLAG_100000; + EnTalkGibud_SetupDisappear(this); + } else { + EnTalkGibud_SetupPassiveIdle(this); + } + } + break; + + case 16: + EnTalkGibud_CheckPresentedItem(this, globalCtx); + break; + } + EnTalkGibud_FacePlayerWhenTalking(this, globalCtx); +} + +void EnTalkGibud_SetupDisappear(EnTalkGibud* this) { + Actor_ChangeAnimationByInfo(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actor.flags &= ~ACTOR_FLAG_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) { + Flags_SetSwitch(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 & (0x200000 | 0x80000 | 0x40000 | 0x4000 | 0x2000 | 0x80)) && + !(player->stateFlags2 & (0x4000 | 0x80))) { + 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 &= ~(ACTOR_FLAG_4 | ACTOR_FLAG_1); + this->actor.flags |= (ACTOR_FLAG_8 | ACTOR_FLAG_1); + this->actor.hintId = 0xFF; + this->actor.textId = 0; + EnTalkGibud_SetupPassiveIdle(this); + } + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO) { + this->actor.flags &= ~(ACTOR_FLAG_8 | ACTOR_FLAG_1); + this->actor.flags |= (ACTOR_FLAG_4 | ACTOR_FLAG_1); + 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.save.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_MoveWithGravity(&this->actor); + } +} + +void EnTalkGibud_UpdateDamage(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: + Actor_SetColorFilter(&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: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + this->drawDmgEffTimer = 180; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 1.0f; + break; + + case EN_TALK_GIBUD_DMGEFF_LIGHT_ARROW: + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + this->drawDmgEffTimer = 60; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 1.0f; + break; + + case EN_TALK_GIBUD_DMGEFF_ZORA_MAGIC: + if (this->actionFunc != EnTalkGibud_Grab && + (this->actionFunc != EnTalkGibud_Stunned || this->stunTimer == 0)) { + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffTimer = 40; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + EnTalkGibud_SetupStunned(this); + } + break; + + case EN_TALK_GIBUD_DMGEFF_STUN: + if ((this->actionFunc != EnTalkGibud_Stunned) || this->stunTimer == 0) { + EnTalkGibud_SetupStunned(this); + } + break; + } + } +} + +void EnTalkGibud_UpdateCollision(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->drawDmgEffTimer > 0) { + this->drawDmgEffTimer--; + } + + if (this->drawDmgEffTimer < 20) { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.0f, 0.5f, 0.03f, 0.0f); + this->drawDmgEffAlpha = this->drawDmgEffTimer * 0.05f; + } else { + Math_SmoothStepToF(&this->drawDmgEffScale, 0.5f, 0.1f, 0.02f, 0.0f); + } +} + +void EnTalkGibud_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTalkGibud* this = THIS; + + EnTalkGibud_CheckForGibdoMask(this, globalCtx); + EnTalkGibud_UpdateDamage(this, globalCtx); + + this->actionFunc(this, globalCtx); + + EnTalkGibud_PlayAnimation(this, globalCtx); + EnTalkGibud_MoveWithGravity(this, globalCtx); + EnTalkGibud_UpdateCollision(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 == GIBDO_LIMB_UPPER_BODY_ROOT) { + rot->y += this->upperBodyRotation.y; + } else if (limbIndex == GIBDO_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->drawDmgEffTimer != 0) && + ((limbIndex == GIBDO_LIMB_LEFT_THIGH) || (limbIndex == GIBDO_LIMB_LEFT_SHIN) || + (limbIndex == GIBDO_LIMB_LEFT_FOOT) || (limbIndex == GIBDO_LIMB_RIGHT_THIGH) || + (limbIndex == GIBDO_LIMB_RIGHT_SHIN) || (limbIndex == GIBDO_LIMB_RIGHT_FOOT) || + (limbIndex == GIBDO_LIMB_TORSO) || (limbIndex == GIBDO_LIMB_LEFT_SHOULDER_AND_UPPER_ARM) || + (limbIndex == GIBDO_LIMB_LEFT_FOREARM) || (limbIndex == GIBDO_LIMB_LEFT_HAND) || + (limbIndex == GIBDO_LIMB_RIGHT_SHOULDER_AND_UPPER_ARM) || (limbIndex == GIBDO_LIMB_RIGHT_FOREARM) || + (limbIndex == GIBDO_LIMB_RIGHT_HAND) || (limbIndex == GIBDO_LIMB_HEAD) || (limbIndex == GIBDO_LIMB_PELVIS))) { + Matrix_MultZero(&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->drawDmgEffTimer > 0) { + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, 0.5f, this->drawDmgEffAlpha, this->drawDmgEffType); + } + + 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..b2d5b06b8 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 @@ -2,16 +2,47 @@ #define Z_EN_TALK_GIBUD_H #include "global.h" +#include "objects/object_rd/object_rd.h" + +#define EN_TALK_GIBUD_REQUESTED_ITEM_INDEX(thisx) ((thisx)->params & 0xF) +#define EN_TALK_GIBUD_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF0) >> 4) 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 drawDmgEffAlpha; + /* 0x2A0 */ f32 drawDmgEffScale; + /* 0x2A4 */ Vec3s jointTable[GIBDO_LIMB_MAX]; + /* 0x340 */ Vec3s morphTable[GIBDO_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 drawDmgEffTimer; + /* 0x3F2 */ s16 type; + /* 0x3F4 */ s16 isTalking; + /* 0x3F6 */ u8 drawDmgEffType; + /* 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_Tanron1/z_en_tanron1.c b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c index 1781ab829..0f8b56068 100644 --- a/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c +++ b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.c @@ -1,6 +1,12 @@ +/* + * File: z_en_tanron1.c + * Overlay: ovl_En_Tanron1 + * Description: Swarm of Moths in Woodfall Temple + */ + #include "z_en_tanron1.h" -#define FLAGS 0x00000035 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTanron1*)thisx) @@ -9,7 +15,9 @@ void EnTanron1_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron1_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron1_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BB5318(EnTanron1* this, GlobalContext* globalCtx); +void func_80BB5AAC(EnTanron1* this, GlobalContext* globalCtx); + const ActorInit En_Tanron1_InitVars = { ACTOR_EN_TANRON1, ACTORCAT_ENEMY, @@ -22,18 +30,387 @@ const ActorInit En_Tanron1_InitVars = { (ActorFunc)EnTanron1_Draw, }; -#endif +static u64 sPad = { 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/EnTanron1_Init.s") +#include "overlays/ovl_En_Tanron1/ovl_En_Tanron1.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/EnTanron1_Destroy.s") +void EnTanron1_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron1* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/func_80BB4E50.s") + this->actor.flags &= ~ACTOR_FLAG_1; + if (!ENTANRON1_GET_100(&this->actor)) { + this->unk_144 = 0; + } else { + this->actor.params = 200; + this->unk_144 = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/EnTanron1_Update.s") +void EnTanron1_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/EnTanron1_Draw.s") +void func_80BB4E50(EnTanron1Struct* arg0, Vec3f* arg1, s16 arg2) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/func_80BB5318.s") + for (i = 0; i < 200; i++, arg0++) { + if (arg0->unk_24 == 0) { + arg0->unk_24 = 1; + arg0->unk_2C = 0.0f; + arg0->unk_00 = *arg1; + arg0->unk_18 = arg0->unk_1C = 0; + arg0->unk_1A = arg2; + arg0->unk_26 = Rand_ZeroFloat(100.0f); + arg0->unk_28 = 0; + if (Rand_ZeroOne() < 0.5f) { + arg0->unk_2A = 0xC00; + } else { + arg0->unk_2A = -0xC00; + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron1/func_80BB5AAC.s") +void EnTanron1_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTanron1* this = THIS; + Actor* temp_a0; + Player* player = GET_PLAYER(globalCtx); + s16 i; + EnTanron1Struct* ptr = &this->unk_160[0]; + Vec3f temp; + f32 phi_f18; + s32 pad; + + if (this->unk_148 != 0) { + this->unk_148--; + } + + switch (this->unk_144) { + case 0: + for (i = 0; i < this->actor.params; i++) { + func_80BB4E50(this->unk_160, &this->actor.world.pos, Rand_ZeroFloat(0x10000)); + } + this->unk_144 = 200; + break; + + case 1: + this->unk_14C.x = player->actor.world.pos.x; + this->unk_14C.y = player->actor.world.pos.y + 60.0f; + this->unk_14C.z = player->actor.world.pos.z; + if (this->unk_148 != 0) { + func_80BB4E50(this->unk_160, &this->actor.world.pos, this->actor.world.rot.y); + } + this->unk_158 = 0x1000; + this->unk_15C = 150.0f; + break; + + case 100: + phi_f18 = 10.0f; + + while (phi_f18 < 1000.0f) { + temp_a0 = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; + while (temp_a0 != NULL) { + if (temp_a0->id != ACTOR_OBJ_SYOKUDAI) { + temp_a0 = temp_a0->next; + continue; + } + + temp.x = this->unk_14C.x - temp_a0->world.pos.x; + temp.y = (this->unk_14C.y - temp_a0->world.pos.y) + 70.0f; + temp.z = this->unk_14C.z - temp_a0->world.pos.z; + + if (sqrtf(SQXYZ(temp)) < phi_f18) { + this->unk_14C.x = temp_a0->world.pos.x; + this->unk_14C.y = temp_a0->world.pos.y + 70.0f; + this->unk_14C.z = temp_a0->world.pos.z; + goto end; + } + temp_a0 = temp_a0->next; + } + phi_f18 += 20.0f; + } + end: + break; + + case 200: + this->unk_14C = this->actor.world.pos; + this->unk_158 = 0x5000; + this->unk_15C = 50.0f; + break; + + case 250: + for (i = 0; i < ARRAY_COUNT(this->unk_160); i++, ptr++) { + if ((ptr->unk_24 != 0) && (ptr->unk_28 < 8)) { + ptr->unk_28 = 8; + ptr->unk_24 = 2; + } + } + this->unk_144 = 1; + break; + } + + if ((player->itemActionParam == 7) && (player->unk_B28 != 0)) { + this->unk_14C.x = player->swordInfo[0].tip.x; + this->unk_14C.y = player->swordInfo[0].tip.y; + this->unk_14C.z = player->swordInfo[0].tip.z; + + this->unk_158 = 0x5000; + this->unk_15C = 50.0f; + if (this->unk_144 != 1) { + this->unk_144 = 100; + } + } else { + temp_a0 = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + while (temp_a0 != NULL) { + if (temp_a0->params == 1) { + temp_a0 = temp_a0->next; + continue; + } + + this->unk_14C.x = temp_a0->world.pos.x; + this->unk_14C.y = temp_a0->world.pos.y + 50.0f; + this->unk_14C.z = temp_a0->world.pos.z; + + this->unk_15C = 150.0f; + this->unk_158 = 0x1000; + if (this->unk_144 != 1) { + this->unk_144 = 100; + } + break; + } + } + func_80BB5318(this, globalCtx); +} + +void EnTanron1_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTanron1* this = THIS; + + func_80BB5AAC(this, globalCtx); +} + +void func_80BB5318(EnTanron1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnTanron1Struct* ptr = NULL; + f32 phi_f28 = 0.0f; + Vec3f* phi_s2 = NULL; + Vec3f temp; + s16 spBA = 0; + s16 spB8 = 0; + Vec3f* spB4 = NULL; + f32 spB0; + Vec3f spA4; + WaterBox* spA0; + f32 sp9C; + CollisionPoly* sp98; + Actor* temp_v0; + s16 i; + f32 temp_f30 = this->unk_15C; + + if (player->unk_ADC != 0) { + phi_s2 = &player->swordInfo[0].tip; + if (player->swordAnimation >= 30) { + phi_f28 = 2500.0f; + } else { + phi_f28 = 400.0f; + } + } + + temp_v0 = globalCtx->actorCtx.actorLists[ACTORCAT_EXPLOSIVES].first; + while (temp_v0 != NULL) { + if (temp_v0->params != 1) { + temp_v0 = temp_v0->next; + continue; + } + phi_s2 = &temp_v0->world.pos; + phi_f28 = 40000.0f; + break; + } + + ptr = &this->unk_160[0]; + for (i = 0; i < this->actor.params; i++, ptr++) { + if (ptr->unk_24 != 0) { + ptr->unk_26++; + ptr->unk_00.x += ptr->unk_0C.x; + ptr->unk_00.y += ptr->unk_0C.y; + ptr->unk_00.z += ptr->unk_0C.z; + + if (ptr->unk_24 == 0) { + } else { + spB4 = &ptr->unk_00; + if (ptr->unk_28 == 0) { + spBA++; + ptr->unk_2C = Math_SinS(ptr->unk_26 * 0x5000) * 1.2f; + if ((ptr->unk_26 & 3) == 0) { + temp.x = ptr->unk_30 + (this->unk_14C.x - ptr->unk_00.x); + temp.y = ptr->unk_34 + (this->unk_14C.y - ptr->unk_00.y); + temp.z = ptr->unk_38 + (this->unk_14C.z - ptr->unk_00.z); + + ptr->unk_20 = Math_Atan2S(temp.x, temp.z); + ptr->unk_1E = Math_Atan2S(temp.y, sqrtf(SQXZ(temp))); + if ((ptr->unk_26 & 0xF) == 0) { + ptr->unk_30 = randPlusMinusPoint5Scaled(temp_f30); + ptr->unk_34 = randPlusMinusPoint5Scaled(temp_f30 * 0.5f); + ptr->unk_38 = randPlusMinusPoint5Scaled(temp_f30); + } + + temp.x = player->actor.world.pos.x - ptr->unk_00.x; + temp.y = (player->actor.world.pos.y + 40.0f) - ptr->unk_00.y; + temp.z = player->actor.world.pos.z - ptr->unk_00.z; + + if ((SQXYZ(temp) < 400.0f) && (player->transformation != PLAYER_FORM_DEKU)) { + func_800B8D10(globalCtx, &this->actor, 0.0f, 0, 0.0f, 1, 1); + } + } + + Math_ApproachS(&ptr->unk_1A, ptr->unk_20, 2, this->unk_158); + Math_ApproachS(&ptr->unk_18, ptr->unk_1E, 2, this->unk_158); + Matrix_RotateYS(ptr->unk_1A, MTXMODE_NEW); + Matrix_RotateXS(-ptr->unk_18, MTXMODE_APPLY); + Matrix_MultVecZ(6.0f, &ptr->unk_0C); + + if (phi_s2 != NULL) { + temp.x = phi_s2->x - ptr->unk_00.x; + temp.y = phi_s2->y - ptr->unk_00.y; + temp.z = phi_s2->z - ptr->unk_00.z; + + if (SQXYZ(temp) < phi_f28) { + ptr->unk_20 = Math_Atan2S(temp.x, temp.z); + ptr->unk_1E = Math_Atan2S(temp.y, sqrtf(SQXZ(temp))); + + Matrix_RotateYS(ptr->unk_20, MTXMODE_NEW); + Matrix_RotateXS(-ptr->unk_1E, MTXMODE_APPLY); + Matrix_MultVecZ(-20.0f, &ptr->unk_0C); + + if (phi_f28 >= 100000.0f) { + ptr->unk_28 = 1; + } else { + ptr->unk_28 = 6; + } + ptr->unk_24 = 2; + spB8++; + } + } + } else if (ptr->unk_28 < 9) { + ptr->unk_18 += 0x3000; + ptr->unk_1A += 0x5000; + ptr->unk_30 = 0.0f; + ptr->unk_34 = 0.0f; + ptr->unk_28++; + } else { + ptr->unk_1A += ptr->unk_2A; + Math_ApproachS(&ptr->unk_18, 0, 0xA, 0x1000); + Matrix_RotateYS(ptr->unk_1A, MTXMODE_NEW); + Matrix_MultVecZ(ptr->unk_30, &spA4); + + ptr->unk_0C.x = spA4.x; + ptr->unk_0C.z = spA4.z; + ptr->unk_0C.y = -2.0f; + + if (phi_s2 != NULL) { + temp.x = phi_s2->x - ptr->unk_00.x; + temp.y = phi_s2->y - ptr->unk_00.y; + temp.z = phi_s2->z - ptr->unk_00.z; + + if (SQXYZ(temp) < phi_f28) { + ptr->unk_20 = Math_Atan2S(temp.x, temp.z); + ptr->unk_1E = Math_Atan2S(temp.y, sqrtf(SQXZ(temp))); + + Matrix_RotateYS(ptr->unk_20, MTXMODE_NEW); + Matrix_RotateXS(-ptr->unk_1E, MTXMODE_APPLY); + Matrix_MultVecZ(-20.0f, &ptr->unk_0C); + + ptr->unk_3C = ptr->unk_00.y - 1000.0f; + ptr->unk_30 = 5.0f; + } + } + + if (ptr->unk_00.y <= (ptr->unk_3C + 5.0f)) { + ptr->unk_00.y = (ptr->unk_3C + 5.0f); + Math_ApproachZeroF(&ptr->unk_30, 1.0f, 0.3f); + Math_ApproachS(&ptr->unk_2A, 0, 1, 0x100); + ptr->unk_28++; + if (ptr->unk_28 > 50) { + ptr->unk_24 = 0; + } + } else { + Math_ApproachF(&ptr->unk_30, ptr->unk_34, 1.0f, 0.5f); + if ((ptr->unk_26 & 0xF) == 0) { + if (Rand_ZeroOne() < 0.5f) { + ptr->unk_34 = randPlusMinusPoint5Scaled(12.0f); + } + ptr->unk_3C = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp98, &ptr->unk_00); + sp9C = ptr->unk_00.y; + WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, ptr->unk_00.x, ptr->unk_00.z, &sp9C, + &spA0); + if ((sp9C < ptr->unk_00.y) && (ptr->unk_3C < sp9C)) { + ptr->unk_3C = sp9C; + } + } + } + } + } + } + } + + if (spB4 != NULL) { + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, spB4, &this->unk_3360, &spB0); + if (spB8 >= (s16)(KREG(39) + 20)) { + Audio_PlaySfxAtPos(&this->unk_3360, NA_SE_EN_MB_MOTH_DEAD); + } else if (spBA >= 20) { + Audio_PlaySfxAtPos(&this->unk_3360, NA_SE_EN_MB_MOTH_FLY - SFX_FLAG); + } + } +} + +void func_80BB5AAC(EnTanron1* this, GlobalContext* globalCtx) { + EnTanron1Struct* ptrBase = &this->unk_160[0]; + s16 i; + u8 flag = 0; + EnTanron1Struct* ptr = ptrBase; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < this->actor.params; i++, ptr++) { + if (ptr->unk_24 == 1) { + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001888); + flag++; + } + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_RotateYS(ptr->unk_1A, MTXMODE_APPLY); + Matrix_RotateXS(ptr->unk_18 * -1, MTXMODE_APPLY); + Matrix_Scale(1.2f, ptr->unk_2C, 1.2f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001900); + } + } + + flag = 0; + ptr = ptrBase; + for (i = 0; i < this->actor.params; i++, ptr++) { + if (ptr->unk_24 != 2) { + continue; + } + + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001888); + gDPLoadTextureBlock(POLY_OPA_DISP++, ovl_En_Tanron1_DL_001428, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 32, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 4, 5, G_TX_NOLOD, G_TX_NOLOD); + flag++; + } + + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_RotateYS(ptr->unk_1A, MTXMODE_APPLY); + Matrix_RotateXS(ptr->unk_18 * -1, MTXMODE_APPLY); + Matrix_Scale(1.0f, ptr->unk_2C, 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++, ovl_En_Tanron1_DL_001900); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.h b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.h index b32810084..d8e96537f 100644 --- a/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.h +++ b/src/overlays/actors/ovl_En_Tanron1/z_en_tanron1.h @@ -5,9 +5,38 @@ struct EnTanron1; +#define ENTANRON1_GET_100(thisx) ((thisx)->params & 0x100) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ s16 unk_18; + /* 0x1A */ s16 unk_1A; + /* 0x1C */ s16 unk_1C; + /* 0x1E */ s16 unk_1E; + /* 0x20 */ s16 unk_20; + /* 0x22 */ UNK_TYPE1 unk_22[0x2]; + /* 0x24 */ u8 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ s16 unk_28; + /* 0x2A */ s16 unk_2A; + /* 0x2C */ f32 unk_2C; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; + /* 0x3C */ f32 unk_3C; +} EnTanron1Struct; // size = 0x40 + typedef struct EnTanron1 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_0144[0x3228]; + /* 0x0144 */ u8 unk_144; + /* 0x0145 */ UNK_TYPE1 pad145[3]; + /* 0x0148 */ s16 unk_148; + /* 0x014C */ Vec3f unk_14C; + /* 0x0158 */ s16 unk_158; + /* 0x015C */ f32 unk_15C; + /* 0x0160 */ EnTanron1Struct unk_160[200]; + /* 0x3360 */ Vec3f unk_3360; } EnTanron1; // size = 0x336C extern const ActorInit En_Tanron1_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.c b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.c index 640d24f8c..66ee6080e 100644 --- a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.c +++ b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.c @@ -1,6 +1,15 @@ -#include "z_en_tanron2.h" +/* + * File: z_en_tanron2.c + * Overlay: ovl_En_Tanron2 + * Description: Wart's Bubbles + */ -#define FLAGS 0x00000035 +#include "z_en_tanron2.h" +#include "overlays/actors/ovl_Boss_04/z_boss_04.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_boss04/object_boss04.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTanron2*)thisx) @@ -9,12 +18,18 @@ void EnTanron2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron2_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron2_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80BB69C0(EnTanron2* this); void func_80BB69FC(EnTanron2* this, GlobalContext* globalCtx); void func_80BB6BD8(EnTanron2* this, GlobalContext* globalCtx); +void func_80BB6F64(EnTanron2* this); void func_80BB6F78(EnTanron2* this, GlobalContext* globalCtx); void func_80BB7408(EnTanron2* this, GlobalContext* globalCtx); +void func_80BB7B90(Actor* thisx, GlobalContext* globalCtx); + +Boss04* D_80BB8450; +f32 D_80BB8454; +EnTanron2* D_80BB8458[82]; -#if 0 const ActorInit En_Tanron2_InitVars = { ACTOR_EN_TANRON2, ACTORCAT_BOSS, @@ -27,8 +42,7 @@ const ActorInit En_Tanron2_InitVars = { (ActorFunc)EnTanron2_Draw, }; -// static DamageTable sDamageTable = { -static DamageTable D_80BB8170 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0xF), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -63,54 +77,606 @@ static DamageTable D_80BB8170 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BB8190 = { - { 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, 0x04 }, { 0xFFFFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + 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, 0x04 }, + { 0xFFFFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 30, 50, -25, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BB81BC = { - { 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, 0x04 }, { 0xF7FFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + 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, 0x04 }, + { 0xF7FFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 22, 42, -21, { 0, 0, 0 } }, }; -#endif +Color_RGBA8 D_80BB81E8 = { 255, 255, 255, 255 }; +Color_RGBA8 D_80BB81EC = { 255, 100, 100, 255 }; -extern DamageTable D_80BB8170; -extern ColliderCylinderInit D_80BB8190; -extern ColliderCylinderInit D_80BB81BC; +void EnTanron2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron2* this = THIS; -extern UNK_TYPE D_06003450; + D_80BB8450 = (Boss04*)this->actor.parent; + this->actor.flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/EnTanron2_Init.s") + if (this->actor.params == 100) { + this->actor.update = func_80BB7B90; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 5); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/EnTanron2_Destroy.s") + this->actor.flags |= ACTOR_FLAG_200; + Actor_SetScale(&this->actor, 1.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB69C0.s") + this->actor.draw = NULL; + this->actor.colChkInfo.health = 1; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.targetMode = 5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB69FC.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB6B80.s") + if ((KREG(64) != 0) || (gSaveContext.eventInf[6] & 1)) { + func_80BB69C0(this); + } else { + func_80BB6F64(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB6BD8.s") + this->unk_14A = Rand_ZeroFloat(0x10000); + this->unk_14C = Rand_ZeroFloat(800.0f) + 1400.0f; + if (Rand_ZeroOne() < 0.5f) { + this->unk_14C = -this->unk_14C; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB6F64.s") + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 35.0f, 60.0f, 60.0f, 4); + this->actor.floorHeight += 20.0f; + this->unk_148 = Rand_ZeroFloat(32.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB6F78.s") +void EnTanron2_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB71C8.s") +void func_80BB69C0(EnTanron2* this) { + this->actionFunc = func_80BB69FC; + this->unk_160 = 0.0f; + this->unk_15C = 0.0f; + this->collider1.dim.radius = 25; + this->collider1.dim.height = 46; + this->collider1.dim.yShift = -23; + this->unk_158 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB7398.s") +void func_80BB69FC(EnTanron2* this, GlobalContext* globalCtx) { + f32 sp34; + f32 sp30; + f32 sp2C; + Vec3f* temp_s1 = &D_80BB8450->unk_2E4[this->actor.params]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB7408.s") + if (this->unk_15C == 1.0f) { + Math_Vec3f_Copy(&this->actor.world.pos, temp_s1); + } else { + sp34 = Math_SmoothStepToF(&this->actor.world.pos.x, temp_s1->x, this->unk_15C, this->unk_160, 0.0f); + sp30 = Math_SmoothStepToF(&this->actor.world.pos.y, temp_s1->y, this->unk_15C, this->unk_160, 0.0f); + sp2C = Math_SmoothStepToF(&this->actor.world.pos.z, temp_s1->z, this->unk_15C, this->unk_160, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB7578.s") + if ((this->unk_158 == 0) && ((sp34 + sp30 + sp2C) < 2.0f)) { + this->unk_158 = 1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_B_SLIME_EAT); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/EnTanron2_Update.s") + Math_ApproachF(&this->unk_15C, 1.0f, 1.0f, 0.02f); + Math_ApproachF(&this->unk_160, 20.0f, 1.0f, 1.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/func_80BB7B90.s") + Math_ApproachF(&this->actor.scale.x, 1.0f, 0.1f, 0.2f); + Math_ApproachF(&this->actor.scale.y, 1.0f, 0.1f, 0.2f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron2/EnTanron2_Draw.s") +void func_80BB6B80(EnTanron2* this) { + this->actionFunc = func_80BB6BD8; + this->actor.speedXZ = 0.0f; + this->actor.velocity.z = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.velocity.x = 0.0f; + this->unk_158 = 0; + this->unk_159 = 1; + this->actor.flags |= ACTOR_FLAG_1; + this->collider1.dim.radius = 30; + this->collider1.dim.height = 50; + this->collider1.dim.yShift = -25; +} + +void func_80BB6BD8(EnTanron2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp32; + f32 sp2C; + f32 sp28; + + if (this->unk_14E == 0) { + this->actor.world.pos.x += this->actor.velocity.x; + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.z += this->actor.velocity.z; + this->actor.velocity.y = this->actor.velocity.y - 2.0f; + + if (this->actor.world.pos.y <= this->actor.floorHeight) { + this->actor.world.pos.y = this->actor.floorHeight; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_JUMP2); + + sp2C = D_80BB8450->unk_6BC.x - this->actor.world.pos.x; + sp28 = D_80BB8450->unk_6BC.z - this->actor.world.pos.z; + + switch (this->unk_158) { + case 0: + if (Rand_ZeroOne() > 0.2f) { + sp32 = Rand_ZeroFloat(65536.0f); + } else { + sp32 = Math_Atan2S(sp2C, sp28); + } + this->actor.speedXZ = Rand_ZeroFloat(5.0f) + 5.0f; + break; + + case 1: + sp32 = Math_Atan2S(sp2C, sp28); + this->actor.speedXZ += 2.0f; + if (this->actor.speedXZ > 10.0f) { + this->actor.speedXZ = 10.0f; + } + break; + + case 2: + sp32 = Math_Atan2S(player->actor.world.pos.x - this->actor.world.pos.x, + player->actor.world.pos.z - this->actor.world.pos.z) + + (s16)Rand_ZeroFloat(20000.0f); + this->actor.speedXZ = Rand_ZeroFloat(7.0f) + 7.0f; + if ((this->unk_152 == 0) && (D_80BB8450->unk_1F6 == 0)) { + this->unk_158 = 1; + } + break; + } + Matrix_RotateYS(sp32, MTXMODE_NEW); + Matrix_MultVecZ(this->actor.speedXZ, &this->actor.velocity); + this->actor.velocity.y = Rand_ZeroFloat(5.0f) + 12.0f; + this->unk_14E = 5; + } + + if (this->unk_150 != 0) { + Math_ApproachF(&this->actor.scale.x, 0.75f, 0.5f, 1.0f); + Math_ApproachF(&this->actor.scale.y, 1.2f, 0.5f, 1.0f); + } else { + Math_ApproachF(&this->actor.scale.x, 1.0f, 0.1f, 0.2f); + Math_ApproachF(&this->actor.scale.y, 1.0f, 0.1f, 0.2f); + } + } else { + Math_ApproachF(&this->actor.scale.x, 1.2f, 0.75f, 1.5f); + Math_ApproachF(&this->actor.scale.y, 0.75f, 0.75f, 1.5f); + if (this->unk_14E == 1) { + sp2C = D_80BB8450->unk_6BC.x - this->actor.world.pos.x; + sp28 = D_80BB8450->unk_6BC.z - this->actor.world.pos.z; + + if ((this->unk_158 != 0) && ((SQ(sp2C) + SQ(sp28)) < 14400.0f)) { + func_80BB69C0(this); + } else { + this->unk_150 = 10; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_JUMP1); + } + } + } +} + +void func_80BB6F64(EnTanron2* this) { + this->actionFunc = func_80BB6F78; +} + +void func_80BB6F78(EnTanron2* this, GlobalContext* globalCtx) { + switch (this->unk_158) { + case 0: + if (D_80BB8450->unk_708 == 13) { + this->unk_158 = 10; + this->unk_14E = Rand_ZeroFloat(50.0f); + } + break; + + case 10: + if (this->unk_14E == 0) { + this->unk_150 = 10; + this->unk_158 = 1; + } + break; + + case 1: + if (this->unk_14E == 0) { + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.velocity.y = this->actor.velocity.y - 2.0f; + + if (this->actor.world.pos.y <= this->actor.floorHeight) { + this->actor.world.pos.y = this->actor.floorHeight; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_JUMP2); + if (D_80BB8450->unk_6F8 > 0.1f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER_L); + } + this->actor.velocity.y = Rand_ZeroFloat(5.0f) + 12.0f; + this->unk_14E = 5; + } + + if (this->unk_150 != 0) { + Math_ApproachF(&this->actor.scale.x, 0.75f, 0.5f, 1.0f); + Math_ApproachF(&this->actor.scale.y, 1.2f, 0.5f, 1.0f); + } else { + Math_ApproachF(&this->actor.scale.x, 1.0f, 0.1f, 0.2f); + Math_ApproachF(&this->actor.scale.y, 1.0f, 0.1f, 0.2f); + } + } else { + Math_ApproachF(&this->actor.scale.x, 1.2f, 0.75f, 1.5f); + Math_ApproachF(&this->actor.scale.y, 0.75f, 0.75f, 1.5f); + + if (this->unk_14E == 1) { + if (D_80BB8450->unk_708 == 3) { + func_80BB6B80(this); + this->unk_158 = 1; + this->unk_159 = 0; + } else { + this->unk_150 = 0xA; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_JUMP1); + } + } + } + break; + } +} + +void func_80BB71C8(EnTanron2* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spA8; + Vec3f sp9C; + Vec3f sp90; + + for (i = 0; i < 15; i++) { + Matrix_RotateYF(Rand_ZeroFloat(6.2831855f), MTXMODE_NEW); + Matrix_RotateXFApply(Rand_ZeroFloat(6.2831855f)); + Matrix_MultVecZ(Rand_ZeroFloat(10.0f) + 5.0f, &spA8); + sp90.x = this->actor.world.pos.x + spA8.x; + sp90.y = this->actor.world.pos.y + spA8.y; + sp90.z = this->actor.world.pos.z + spA8.z; + + sp9C.x = spA8.x * -0.03f; + sp9C.y = spA8.y * -0.03f; + sp9C.z = spA8.z * -0.03f; + + EffectSsDtBubble_SpawnCustomColor(globalCtx, &sp90, &spA8, &sp9C, &D_80BB81E8, &D_80BB81EC, + Rand_ZeroFloat(100.0f) + 200.0f, Rand_ZeroFloat(5.0f) + 15.0f, 0); + } +} + +void func_80BB7398(EnTanron2* this, GlobalContext* globalCtx) { + this->actionFunc = func_80BB7408; + if ((s8)this->actor.colChkInfo.health <= 0) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_IKURA_DEAD); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_DAMAGE); + } +} + +void func_80BB7408(EnTanron2* this, GlobalContext* globalCtx) { + this->actor.world.pos.x += this->actor.velocity.x; + this->actor.world.pos.y += this->actor.velocity.y; + this->actor.world.pos.z += this->actor.velocity.z; + this->actor.velocity.y -= 2.0f; + + if (this->actor.world.pos.y <= this->actor.floorHeight) { + this->actor.world.pos.y = this->actor.floorHeight; + if ((s8)this->actor.colChkInfo.health <= 0) { + Actor_MarkForDeath(&this->actor); + func_80BB71C8(this, globalCtx); + D_80BB8450->unk_6F6--; + D_80BB8450->unk_2E2 += 4; + D_80BB8450->unk_2E0 += 4; + } else { + this->actor.velocity.x *= 0.5f; + this->actor.velocity.z *= 0.5f; + Math_ApproachF(&this->actor.scale.x, 1.2f, 0.75f, 1.5f); + Math_ApproachF(&this->actor.scale.y, 0.75f, 0.75f, 1.5f); + if ((this->actor.velocity.x < 0.1f) && (this->actor.velocity.z < 0.1f)) { + func_80BB6B80(this); + this->unk_158 = 1; + } + } + } +} + +void func_80BB7578(EnTanron2* this, GlobalContext* globalCtx) { + ColliderInfo* acHitInfo; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + s32 pad2; + s32 pad3; + u8 damage; + + if (this->unk_154 == 0) { + if (this->collider1.base.acFlags & AC_HIT) { + this->collider1.base.acFlags &= ~AC_HIT; + acHitInfo = this->collider1.info.acHitInfo; + if (acHitInfo->toucher.dmgFlags & 0x80) { + func_80BB6B80(this); + this->unk_158 = 1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_DAMAGE); + if ((player->unk_730 != 0) && (&this->actor != player->unk_730)) { + player->unk_730 = &this->actor; + globalCtx->actorCtx.targetContext.arrowPointedActor = &this->actor; + globalCtx->actorCtx.targetContext.targetedActor = &this->actor; + } + } else { + this->unk_154 = 15; + if (this->actionFunc != func_80BB69FC) { + Matrix_RotateYS(this->actor.yawTowardsPlayer, MTXMODE_NEW); + if ((acHitInfo->toucher.dmgFlags & 0x300000) != 0) { + this->unk_154 = 10; + Matrix_MultVecZ(-10.0f, &this->actor.velocity); + } else { + this->unk_156 = 15; + Matrix_MultVecZ(-20.0f, &this->actor.velocity); + damage = this->actor.colChkInfo.damage; + this->actor.colChkInfo.health -= damage; + func_80BB7398(this, globalCtx); + } + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_IKURA_DAMAGE); + goto block_18; + } + } + } + } + + if ((this->actionFunc == func_80BB69FC) && + ((D_80BB8450->unk_1F6 == 1) || ((D_80BB8450->unk_1F7 != 0) && (Rand_ZeroOne() < 0.1f)))) { + if (D_80BB8450->unk_1F7 != 0) { + D_80BB8450->unk_1F7--; + } + + block_18: + func_80BB6B80(this); + this->unk_158 = 2; + Matrix_RotateYS(Math_Atan2S(this->actor.world.pos.x - D_80BB8450->unk_6BC.x, + this->actor.world.pos.z - D_80BB8450->unk_6BC.z), + MTXMODE_NEW); + Matrix_MultVecZ(10.0f, &this->actor.velocity); + this->unk_152 = Rand_ZeroFloat(100.0f) + 200.0f; + } else if (D_80BB8450->unk_1F6 == 10) { + Actor_MarkForDeath(&this->actor); + func_80BB71C8(this, globalCtx); + } +} + +void EnTanron2_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTanron2* this = THIS; + s32 pad2[2]; + Input* input; + + this->unk_148++; + Actor_SetFocus(&this->actor, 0.0f); + + if (this->unk_14E != 0) { + this->unk_14E--; + } + + if (this->unk_150 != 0) { + this->unk_150--; + } + + if (this->unk_152 != 0) { + this->unk_152--; + } + + if (this->unk_154 != 0) { + this->unk_154--; + } + + if (this->unk_156 != 0) { + this->unk_156--; + } + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != func_80BB69FC) { + if ((this->actor.world.pos.x < (D_80BB8450->unk_6D8 + 20.0f)) || + ((D_80BB8450->unk_6DC - 20.0f) < this->actor.world.pos.x)) { + this->actor.world.pos.x = this->actor.prevPos.x; + this->actor.velocity.x *= -1.0f; + } + + if ((this->actor.world.pos.z < (D_80BB8450->unk_6E0 + 20.0f)) || + ((D_80BB8450->unk_6E4 - 20.0f) < this->actor.world.pos.z)) { + this->actor.world.pos.z = this->actor.prevPos.z; + this->actor.velocity.z *= -1.0f; + } + } + + this->unk_14A += this->unk_14C; + func_80BB7578(this, globalCtx); + + if (this->unk_159 != 0) { + if (this->actor.xzDistToPlayer < 100.0f) { + if (this->unk_15A == 0) { + Collider_UpdateCylinder(&this->actor, &this->collider2); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } else { + this->unk_15A--; + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider1); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + if (!(this->unk_148 & 0x1F)) { + if ((this->actionFunc != func_80BB69FC) && (this->actor.xyzDistToPlayerSq < SQ(200.0f))) { + this->unk_15B = 1; + } else { + this->unk_15B = 0; + } + + if (this->actionFunc == func_80BB69FC) { + s16 atan = Math_Atan2S(this->actor.world.pos.x - D_80BB8450->unk_6BC.x, + this->actor.world.pos.z - D_80BB8450->unk_6BC.z); + + if (ABS_ALT(BINANG_SUB(D_80BB8450->actor.yawTowardsPlayer, atan)) > 0x3000) { + this->unk_159 = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + } else { + this->unk_159 = 1; + this->actor.flags |= ACTOR_FLAG_1; + } + } + } + + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_2000) && (this->actor.xzDistToPlayer < 80.0f)) { + this->actor.flags &= ~ACTOR_FLAG_2000; + this->unk_15A = 25; + this->unk_159 = 1; + } + + input = CONTROLLER3(globalCtx); + if (CHECK_BTN_ALL(input->press.button, BTN_L)) { + this->unk_158 = 1; + } + + if (CHECK_BTN_ALL(input->press.button, BTN_R)) { + func_80BB6B80(this); + } +} + +void func_80BB7B90(Actor* thisx, GlobalContext* globalCtx) { + EnTanron2* this = THIS; + + D_80BB8454 = (Math_SinS(globalCtx->gameplayFrames * 0x3000) * 0.1f) + 1.0f; + if (D_80BB8450->unk_1F6 == 11) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnTanron2_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 i; + s32 j; + s32 found; + Actor* tanron2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_003450); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 150); + + tanron2 = globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; + + for (i = 0; i < ARRAY_COUNT(D_80BB8458); i++) { + D_80BB8458[i] = NULL; + } + + found = 0; + while (tanron2 != NULL) { + if (tanron2->params < 100) { + D_80BB8458[found] = (EnTanron2*)tanron2; + found++; + } + tanron2 = tanron2->next; + } + + for (j = 0; j < found - 1; j++) { + for (i = 0; i < found - 1; i++) { + if (D_80BB8458[i + 1] != NULL) { + if (D_80BB8458[i]->actor.projectedPos.z < D_80BB8458[i + 1]->actor.projectedPos.z) { + SWAP(EnTanron2*, D_80BB8458[i], D_80BB8458[i + 1]); + } + } + } + } + + for (i = 0; i < ARRAY_COUNT(D_80BB8458); i++) { + if (D_80BB8458[i] != NULL) { + Matrix_Translate(D_80BB8458[i]->actor.world.pos.x, D_80BB8458[i]->actor.world.pos.y, + D_80BB8458[i]->actor.world.pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(D_80BB8458[i]->actor.scale.x, D_80BB8458[i]->actor.scale.y, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(D_80BB8458[i]->unk_14A, MTXMODE_APPLY); + Matrix_Scale(0.13f, 0.14299999f, 0.13f, MTXMODE_APPLY); + Matrix_RotateZS(-D_80BB8458[i]->unk_14A, 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_0034C8); + } + } + + func_8012C448(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 150); + gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_004510); + + tanron2 = globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; + while (tanron2 != NULL) { + if ((tanron2->params < 100) && (((EnTanron2*)tanron2)->unk_15B != 0)) { + Matrix_Translate(tanron2->world.pos.x, D_80BB8450->actor.floorHeight, tanron2->world.pos.z, MTXMODE_NEW); + Matrix_Scale(0.6f, 0.0f, 0.6f, 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); + } + tanron2 = tanron2->next; + } + + func_8012C974(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE); + + tanron2 = globalCtx->actorCtx.actorLists[ACTORCAT_BOSS].first; + while (tanron2 != NULL) { + if ((tanron2->params < 100) && (((EnTanron2*)tanron2)->unk_15B != 0) && + (tanron2->world.pos.y <= tanron2->floorHeight)) { + Matrix_Translate(tanron2->world.pos.x, D_80BB8450->actor.floorHeight + 2.0f, tanron2->world.pos.z, + MTXMODE_NEW); + Matrix_Scale(D_80BB8454, 0.0f, D_80BB8454, 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_0377B0); + } + tanron2 = tanron2->next; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..755bb4ff4 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,22 @@ typedef void (*EnTanron2ActionFunc)(struct EnTanron2*, GlobalContext*); typedef struct EnTanron2 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTanron2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xB4]; + /* 0x0148 */ s16 unk_148; + /* 0x014A */ s16 unk_14A; + /* 0x014C */ s16 unk_14C; + /* 0x014E */ s16 unk_14E; + /* 0x0150 */ s16 unk_150; + /* 0x0152 */ s16 unk_152; + /* 0x0154 */ s16 unk_154; + /* 0x0156 */ s16 unk_156; + /* 0x0158 */ u8 unk_158; + /* 0x0159 */ u8 unk_159; + /* 0x015A */ u8 unk_15A; + /* 0x015B */ u8 unk_15B; + /* 0x015C */ f32 unk_15C; + /* 0x0160 */ f32 unk_160; + /* 0x0164 */ ColliderCylinder collider1; + /* 0x01B0 */ ColliderCylinder collider2; } 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 126dd987c..5e6bd32ee 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c @@ -1,15 +1,36 @@ -#include "z_en_tanron3.h" +/* + * File: z_en_tanron3.c + * Overlay: ovl_En_Tanron3 + * Description: Small fish summoned by Gyorg + */ -#define FLAGS 0x00000035 +#include "z_en_tanron3.h" +#include "overlays/actors/ovl_Boss_03/z_boss_03.h" +#include "objects/object_boss03/object_boss03.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTanron3*)thisx) +#define WORK_TIMER_PICK_NEW_DEVIATION 0 +#define WORK_TIMER_DIE 0 +#define WORK_TIMER_OUT_OF_WATER 1 +#define WORK_TIMER_ATTACK 2 +#define WORK_TIMER_WAIT 2 + void EnTanron3_Init(Actor* thisx, GlobalContext* globalCtx); 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, @@ -22,39 +43,422 @@ 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; +void EnTanron3_CreateEffect(GlobalContext* globalCtx, Vec3f* effectPos) { + GyorgEffect* effectPtr = globalCtx->specialEffects; + s16 i; -extern UNK_TYPE D_0600DAAC; + for (i = 0; i < GYORG_EFFECT_COUNT; i++, effectPtr++) { + if ((effectPtr->type == GYORG_EFFECT_NONE) || (effectPtr->type == GYORG_EFFECT_BUBBLE)) { + effectPtr->type = GYORG_EFFECT_DROPLET; + 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/func_80BB85A0.s") +void EnTanron3_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Init.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, &gGyorgSmallFishSkel, &gGyorgSmallFishSwimAnim, this->jointTable, + this->morphTable, GYORG_SMALL_FISH_LIMB_MAX); + Actor_SetScale(&this->actor, 0.02f); + EnTanron3_SetupLive(this, globalCtx); + this->actor.flags &= ~ACTOR_FLAG_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/EnTanron3_Destroy.s") +void EnTanron3_Destroy(Actor* thisx, GlobalContext* globalCtx) { + sGyorg->numSpawnedSmallFish--; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB87D4.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_80BB897C.s") + for (i = 0; i < 20; i++) { + Matrix_RotateYF(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); + Matrix_RotateXFApply(Rand_ZeroFloat(2 * M_PI)); + Matrix_MultVecZ(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_80BB8A48.s") +void EnTanron3_SetupLive(EnTanron3* this, GlobalContext* globalCtx) { + this->actionFunc = EnTanron3_Live; + Animation_MorphToLoop(&this->skelAnime, &gGyorgSmallFishSwimAnim, -10.0f); + this->rotationStep = 0; + this->rotationScale = 5; + this->workTimer[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_80BB91D4.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_80BB9288.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[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[WORK_TIMER_ATTACK] = 150; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB9308.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/EnTanron3_Update.s") + Math_Vec3f_Copy(&this->targetPos, &player->actor.world.pos); + if (!(this->timer & 0xF)) { + if (Rand_ZeroOne() < 0.5f && this->actor.xzDistToPlayer <= 200.0f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_PIRANHA_ATTACK); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB95FC.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[WORK_TIMER_ATTACK] == 0 || (player->stateFlags2 & 0x80)) { + this->workTimer[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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Draw.s") + // 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_RotateYS(atanTemp, MTXMODE_NEW); + Matrix_MultVecZ(700.0f, &this->targetPos); + this->targetPos.y = 250.0f; + + extraScaleY = 150.0f; + break; + } + + if (this->workTimer[WORK_TIMER_OUT_OF_WATER] == 0) { + if (this->workTimer[WORK_TIMER_PICK_NEW_DEVIATION] == 0 && this->actor.speedXZ > 1.0f) { + this->workTimer[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_MoveWithoutGravityReverse(&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[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_MoveWithGravity(&this->actor); + } + + this->currentRotationAngle += this->nextRotationAngle; + this->tailRotation = Math_SinS(this->currentRotationAngle) * 5000.0f; + this->bodyRotation = Math_SinS(this->currentRotationAngle + 0x6978) * 5000.0f; + this->trunkRotation = 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[WORK_TIMER_DIE] = 6; + this->actor.speedXZ = 10.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KONB_MINI_DEAD); +} + +void EnTanron3_Die(EnTanron3* this, GlobalContext* globalCtx) { + Actor_MoveWithoutGravityReverse(&this->actor); + if (this->workTimer[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); + Actor_PlaySfxAtPos(&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[WORK_TIMER_DIE] = 0; + } +} + +s32 EnTanron3_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTanron3* this = THIS; + + if (limbIndex == GYORG_SMALL_FISH_LIMB_ROOT) { + rot->y += this->bodyRotation; + } + + if (limbIndex == GYORG_SMALL_FISH_LIMB_TRUNK_ROOT) { + rot->y += this->trunkRotation; + } + + if (limbIndex == GYORG_SMALL_FISH_LIMB_TAIL_FIN) { + rot->y += this->tailRotation; + } + + 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..5f984e2ef 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h @@ -2,15 +2,43 @@ #define Z_EN_TANRON3_H #include "global.h" +#include "objects/object_boss03/object_boss03.h" struct EnTanron3; typedef void (*EnTanron3ActionFunc)(struct EnTanron3*, GlobalContext*); +#define TANRON3_WORK_TIMER_MAX 3 + typedef struct EnTanron3 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1B4]; - /* 0x02F8 */ EnTanron3ActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[GYORG_SMALL_FISH_LIMB_MAX]; + /* 0x1C4 */ Vec3s morphTable[GYORG_SMALL_FISH_LIMB_MAX]; + /* 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 trunkRotation; + /* 0x25A */ s16 tailRotation; + /* 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_Tanron4/z_en_tanron4.c b/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.c index df10d0042..48eea6828 100644 --- a/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.c +++ b/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.c @@ -1,6 +1,12 @@ +/* + * File: z_en_tanron4.c + * Overlay: ovl_En_Tanron4 + * Description: Seagull + */ + #include "z_en_tanron4.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnTanron4*)thisx) @@ -9,7 +15,22 @@ void EnTanron4_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron4_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron4_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnTanron4_SetupFlyNearHome(EnTanron4* this); +void EnTanron4_SetupFlyNearActor(EnTanron4* this); + +void EnTanron4_FlyNearHome(EnTanron4* this, GlobalContext* globalCtx); +void EnTanron4_FlyNearActor(EnTanron4* this, GlobalContext* globalCtx); + +typedef enum { + /* 0 */ SEAGULL_FLY_FLAP, + /* 1 */ SEAGULL_FLY_GLIDE, +} SeagullFlyState; + +typedef enum { + /* 0 */ SEAGULL_TIMER_FLY_STATE, + /* 1 */ SEAGULL_TIMER_CHOOSE_TARGET, +} SeagullTimers; + const ActorInit En_Tanron4_InitVars = { ACTOR_EN_TANRON4, ACTORCAT_ITEMACTION, @@ -22,22 +43,241 @@ const ActorInit En_Tanron4_InitVars = { (ActorFunc)EnTanron4_Draw, }; -#endif +void EnTanron4_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTanron4* this = THIS; -extern UNK_TYPE D_06000168; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gSeagullSkel, &gSeagullFlapAnim, this->jointTable, + this->morphTable, OBJECT_TANRON4_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/EnTanron4_Init.s") + thisx->flags &= ~ACTOR_FLAG_1; + thisx->speedXZ = 3.0f + KREG(48); + thisx->uncullZoneForward = 10000.0f + KREG(70); + this->randRollTimer = Rand_ZeroFloat(10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/EnTanron4_Destroy.s") + if (thisx->params == SEAGULL_FOLLOW_ACTOR) { + EnTanron4_SetupFlyNearActor(this); + } else { + EnTanron4_SetupFlyNearHome(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/func_80BE3DC0.s") + // spawn number of seagulls specified by params + if (thisx->params >= 0) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/func_80BE3DFC.s") + for (i = 0; i < thisx->params; i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TANRON4, + thisx->world.pos.x + randPlusMinusPoint5Scaled(500.0f), + thisx->world.pos.y + randPlusMinusPoint5Scaled(100.0f), + thisx->world.pos.z + randPlusMinusPoint5Scaled(500.0f), 0, Rand_ZeroFloat(65536.0f), 0, + SEAGULL_CLONE); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/func_80BE4268.s") + if ((gSaveContext.save.time > CLOCK_TIME(20, 0)) || (gSaveContext.save.time < CLOCK_TIME(4, 0))) { + this->timeInfluence = 1500.0f; + thisx->world.pos.y += 1500.0f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/func_80BE42A4.s") +void EnTanron4_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/EnTanron4_Update.s") +void EnTanron4_SetupFlyNearHome(EnTanron4* this) { + this->actionFunc = EnTanron4_FlyNearHome; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron4/EnTanron4_Draw.s") +void EnTanron4_FlyNearHome(EnTanron4* this, GlobalContext* globalCtx) { + f32 xDiff; + f32 yDiff; + f32 zDiff; + f32 distToTarget; + s16 xRot; + s16 yRot; + s16 zRot; + + // `timeInfluence` controls both the height of the seagulls and when they are visible. + // They fly higher in the sky as the night goes on, and they disapear as dawn approaches. + if ((gSaveContext.save.time > CLOCK_TIME(20, 0)) || (gSaveContext.save.time < CLOCK_TIME(4, 0))) { + Math_ApproachF(&this->timeInfluence, 1500.0f, 1.0f, 1.0f); + } else { + Math_ApproachZeroF(&this->timeInfluence, 1.0f, 1.0f); + } + + xDiff = this->targetPos.x - this->actor.world.pos.x; + yDiff = (this->targetPos.y + this->timeInfluence) - this->actor.world.pos.y; + zDiff = this->targetPos.z - this->actor.world.pos.z; + + distToTarget = sqrtf(SQ(xDiff) + SQ(zDiff)); + + if ((this->timers[SEAGULL_TIMER_CHOOSE_TARGET] == 0) || (distToTarget < 100.0f)) { + this->targetPos.x = this->actor.home.pos.x + randPlusMinusPoint5Scaled(500.0f); + this->targetPos.y = this->actor.home.pos.y + randPlusMinusPoint5Scaled(100.0f); + this->targetPos.z = this->actor.home.pos.z + randPlusMinusPoint5Scaled(500.0f); + + this->timers[SEAGULL_TIMER_CHOOSE_TARGET] = Rand_ZeroFloat(100.0f) + 60.0f; + this->step = 0; + } + + yRot = Math_Atan2S(xDiff, zDiff); + xRot = Math_Atan2S(yDiff, distToTarget); + zRot = Math_SmoothStepToS(&this->actor.world.rot.y, yRot, 0xA, this->step, 0); + + if (zRot > 0x1000) { + zRot = 0x1000; + } else if (zRot < -0x1000) { + zRot = -0x1000; + } + + Math_ApproachS(&this->actor.world.rot.x, xRot, 0xA, this->step); + Math_ApproachS(&this->actor.world.rot.z, -zRot, 0xA, this->step); + + Math_ApproachS(&this->step, 0x200, 1, 0x10); + + SkelAnime_Update(&this->skelAnime); + + switch (this->flyState) { + case SEAGULL_FLY_FLAP: + if ((this->timers[SEAGULL_TIMER_FLY_STATE] == 0) && + (Animation_OnFrame(&this->skelAnime, 2.0f + KREG(42)))) { + this->flyState = SEAGULL_FLY_GLIDE; + this->timers[SEAGULL_TIMER_FLY_STATE] = Rand_ZeroFloat(50.0f) + 50.0f; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, -15.0f + KREG(43)); + this->skelAnime.curFrame = 2.0f + KREG(42); + this->skelAnime.playSpeed = 0.0f; + } + break; + + case SEAGULL_FLY_GLIDE: + if (((this->randRollTimer % 8) == 0) && (Rand_ZeroOne() < 0.5f)) { + this->rollTarget = randPlusMinusPoint5Scaled(3000.0f + KREG(44)); + } + + if (this->timers[SEAGULL_TIMER_FLY_STATE] == 0) { + this->flyState = SEAGULL_FLY_FLAP; + this->timers[SEAGULL_TIMER_FLY_STATE] = Rand_ZeroFloat(50.0f) + 70.0f; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, -10.0f + KREG(43)); + this->skelAnime.curFrame = 2.0f + KREG(42); + } + break; + } + + this->actor.shape.rot.x = -this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + + Math_ApproachS(&this->roll, this->rollTarget, 3, 0x3E8 + KREG(45)); +} + +void EnTanron4_SetupFlyNearActor(EnTanron4* this) { + this->actionFunc = EnTanron4_FlyNearActor; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, 0.0f); +} + +void EnTanron4_FlyNearActor(EnTanron4* this, GlobalContext* globalCtx) { + f32 xDiff; + f32 yDiff; + f32 zDiff; + f32 distToTarget; + s16 xRot; + s16 yRot; + s16 zRot; + Actor* targetActor = this->actor.parent; + + xDiff = this->targetPos.x - this->actor.world.pos.x; + yDiff = this->targetPos.y - this->actor.world.pos.y; + zDiff = this->targetPos.z - this->actor.world.pos.z; + + distToTarget = sqrtf(SQ(xDiff) + SQ(zDiff)); + + if ((this->timers[SEAGULL_TIMER_CHOOSE_TARGET] == 0) || (distToTarget < 100.0f)) { + this->targetPos.x = targetActor->world.pos.x + randPlusMinusPoint5Scaled(200.0f + KREG(82)); + this->targetPos.y = targetActor->world.pos.y + KREG(80) + 100.0f + randPlusMinusPoint5Scaled(100.0f + KREG(81)); + this->targetPos.z = targetActor->world.pos.z + randPlusMinusPoint5Scaled(200.0f + KREG(82)); + + this->timers[SEAGULL_TIMER_CHOOSE_TARGET] = Rand_ZeroFloat(100.0f) + 60.0f; + this->step = 0; + } + + yRot = Math_Atan2S(xDiff, zDiff); + xRot = Math_Atan2S(yDiff, distToTarget); + zRot = Math_SmoothStepToS(&this->actor.world.rot.y, yRot, 0xA, this->step, 0); + + if (zRot > 0x1000) { + zRot = 0x1000; + } else if (zRot < -0x1000) { + zRot = -0x1000; + } + + Math_ApproachS(&this->actor.world.rot.x, xRot, 0xA, this->step); + Math_ApproachS(&this->actor.world.rot.z, -zRot, 0xA, this->step); + Math_ApproachS(&this->step, 0x200, 1, 0x10); + + SkelAnime_Update(&this->skelAnime); + + switch (this->flyState) { + case SEAGULL_FLY_FLAP: + if ((this->timers[SEAGULL_TIMER_FLY_STATE] == 0) && + (Animation_OnFrame(&this->skelAnime, 2.0f + KREG(42)))) { + this->flyState = SEAGULL_FLY_GLIDE; + this->timers[SEAGULL_TIMER_FLY_STATE] = Rand_ZeroFloat(50.0f) + 50.0f; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, -15.0f + KREG(43)); + this->skelAnime.curFrame = 2.0f + KREG(42); + this->skelAnime.playSpeed = 0.0f; + } + break; + + case SEAGULL_FLY_GLIDE: + if (((this->randRollTimer % 8) == 0) && (Rand_ZeroOne() < 0.5f)) { + this->rollTarget = randPlusMinusPoint5Scaled(3000.0f + KREG(44)); + } + + if (this->timers[SEAGULL_TIMER_FLY_STATE] == 0) { + this->flyState = SEAGULL_FLY_FLAP; + this->timers[SEAGULL_TIMER_FLY_STATE] = Rand_ZeroFloat(50.0f) + 70.0f; + Animation_MorphToLoop(&this->skelAnime, &gSeagullFlapAnim, -10.0f + KREG(43)); + this->skelAnime.curFrame = 2.0f + KREG(42); + } + break; + } + + this->actor.shape.rot.x = -this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.z = this->actor.world.rot.z; + + Math_ApproachS(&this->roll, this->rollTarget, 3, 0x3E8 + KREG(45)); +} + +void EnTanron4_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTanron4* this = THIS; + + Actor_SetScale(&this->actor, 0.001f * KREG(16) + 0.01f); + + if (KREG(63) == 0) { + s32 i; + + this->randRollTimer++; + + for (i = 0; i < ARRAY_COUNT(this->timers); i++) { + if (this->timers[i] != 0) { + this->timers[i]--; + } + } + + this->actionFunc(this, globalCtx); + + Actor_UpdateVelocityWithoutGravity(&this->actor); + Actor_UpdatePos(&this->actor); + } +} + +void EnTanron4_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTanron4* this = THIS; + + if (this->timeInfluence < 1400.0f) { + Matrix_RotateZS(this->roll, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, NULL, &this->actor); + } +} diff --git a/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.h b/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.h index abbcc6633..250a62cf1 100644 --- a/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.h +++ b/src/overlays/actors/ovl_En_Tanron4/z_en_tanron4.h @@ -2,17 +2,32 @@ #define Z_EN_TANRON4_H #include "global.h" +#include "assets/objects/object_tanron4/object_tanron4.h" struct EnTanron4; typedef void (*EnTanron4ActionFunc)(struct EnTanron4*, GlobalContext*); typedef struct EnTanron4 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xE8]; + /* 0x000 */ Actor actor; + /* 0x144 */ s16 randRollTimer; + /* 0x146 */ s16 timers[2]; + /* 0x14A */ u8 flyState; + /* 0x14C */ Vec3f targetPos; + /* 0x158 */ s16 step; + /* 0x15A */ s16 roll; + /* 0x15C */ s16 rollTarget; + /* 0x160 */ f32 timeInfluence; + /* 0x164 */ SkelAnime skelAnime; + /* 0x1A8 */ Vec3s jointTable[OBJECT_TANRON4_LIMB_MAX]; + /* 0x1EA */ Vec3s morphTable[OBJECT_TANRON4_LIMB_MAX]; /* 0x022C */ EnTanron4ActionFunc actionFunc; } EnTanron4; // size = 0x230 +// other than these magic values, params is the number of desired seagulls in the flock +#define SEAGULL_CLONE -1 +#define SEAGULL_FOLLOW_ACTOR 100 + extern const ActorInit En_Tanron4_InitVars; #endif // Z_EN_TANRON4_H diff --git a/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c b/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c index 9d3a8bbb2..09da81cee 100644 --- a/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c +++ b/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.c @@ -1,6 +1,15 @@ -#include "z_en_tanron5.h" +/* + * File: z_en_tanron5.c + * Overlay: ovl_En_Tanron5 + * Description: Destructible props in Twinmold's arena + */ -#define FLAGS 0x00000030 +#include "z_en_tanron5.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_boss02/object_boss02.h" +#include "overlays/actors/ovl_Boss_02/z_boss_02.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTanron5*)thisx) @@ -9,7 +18,11 @@ void EnTanron5_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron5_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron5_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BE5818(Actor* thisx, GlobalContext* globalCtx); +void func_80BE5C10(Actor* thisx, GlobalContext* globalCtx); + +s32 D_80BE5D80 = 0; + const ActorInit En_Tanron5_InitVars = { ACTOR_EN_TANRON5, ACTORCAT_BOSS, @@ -22,32 +35,494 @@ const ActorInit En_Tanron5_InitVars = { (ActorFunc)EnTanron5_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BE5DA4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ALL, AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ALL, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_ENEMY | AC_TYPE_OTHER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 70, 450, 0, { 0, 0, 0 } }, }; -#endif +f32 D_80BE5DD0 = 1.0f; -extern ColliderCylinderInit D_80BE5DA4; +Vec2s D_80BE5DD4[] = { + { 0x4B0, 0x9C4 }, { -0x4B0, 0x9C4 }, { 0x4B0, -0x9C4 }, { -0x4B0, -0x9C4 }, { 0x9C4, 0x4B0 }, + { -0x9C4, 0x4B0 }, { 0x9C4, -0x4B0 }, { -0x9C4, -0x4B0 }, { 0x3E8, 0x3E8 }, { -0x3E8, 0x3E8 }, + { 0x3E8, -0x3E8 }, { -0x3E8, -0x3E8 }, { 0x000, -0x3E8 }, { 0x000, 0x3E8 }, { 0x3E8, 0x000 }, + { -0x3E8, 0x000 }, { 0x000, -0x7D0 }, { 0x000, 0x7D0 }, { 0x7D0, 0x000 }, { -0x7D0, 0x000 }, +}; -extern UNK_TYPE D_06007A88; -extern UNK_TYPE D_06007D18; +Gfx* D_80BE5E24[] = { + gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, + gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, + gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, gTwinmoldMajoraPillarDL, + gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, + gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, gTwinmoldPyramidRuinDL, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/func_80BE4930.s") +f32 D_80BE5E74[] = { + 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, + 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, 0.09f, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/func_80BE4A2C.s") +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ Vec3f unk_18; + /* 0x24 */ u8 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ UNK_TYPE1 unk28[0x4]; + /* 0x2C */ s16 unk_2C; + /* 0x2E */ UNK_TYPE1 unk2E[0x6]; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; +} EnTanron5Effect; // size = 0x3C -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/EnTanron5_Init.s") +void func_80BE4930(EnTanron5Effect* effect, Vec3f* arg1, f32 arg2) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/EnTanron5_Destroy.s") + for (i = 0; i < 150; i++, effect++) { + if (effect->unk_24 == 0) { + effect->unk_24 = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/EnTanron5_Update.s") + effect->unk_00 = *arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/func_80BE5818.s") + effect->unk_0C = randPlusMinusPoint5Scaled(10.0f); + effect->unk_10 = Rand_ZeroFloat(2.0f) + 3.0f; + effect->unk_14 = randPlusMinusPoint5Scaled(10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/EnTanron5_Draw.s") + effect->unk_18.y = -0.15f; + effect->unk_18.x = 0.0f; + effect->unk_18.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron5/func_80BE5C10.s") + effect->unk_2C = Rand_ZeroFloat(100.0f) + 200.0f; + effect->unk_26 = 0; + effect->unk_34 = arg2; + effect->unk_38 = 2.0f * arg2; + break; + } + } +} + +void func_80BE4A2C(EnTanron5Effect* effect, Vec3f* arg1, f32 arg2) { + s16 i; + + for (i = 0; i < 150; i++, effect++) { + if (effect->unk_24 == 0) { + effect->unk_24 = 2; + + effect->unk_00 = *arg1; + + effect->unk_0C = randPlusMinusPoint5Scaled(30.0f); + effect->unk_10 = Rand_ZeroFloat(7.0f); + effect->unk_14 = randPlusMinusPoint5Scaled(30.0f); + + effect->unk_18.y = -0.3f; + effect->unk_18.x = 0.0f; + effect->unk_18.z = 0.0f; + + effect->unk_2C = Rand_ZeroFloat(70.0f) + 150.0f; + effect->unk_26 = 0; + effect->unk_34 = arg2; + effect->unk_38 = 2.0f * arg2; + break; + } + } +} + +void EnTanron5_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron5* this = THIS; + + if (ENTANRON5_GET(&this->actor) >= ENTANRON5_100) { + D_80BE5D80++; + if (D_80BE5D80 > 60) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->unk_198 = randPlusMinusPoint5Scaled(0x2000); + this->unk_19A = randPlusMinusPoint5Scaled(0x2000); + + if (ENTANRON5_GET(&this->actor) < ENTANRON5_107) { + Actor_SetScale(&this->actor, (Rand_ZeroFloat(0.025f) + 0.085f) * D_80BE5DD0); + } else { + Actor_SetScale(&this->actor, (Rand_ZeroFloat(0.015f) + 0.01f) * D_80BE5DD0); + } + + this->actor.speedXZ = (Rand_ZeroFloat(10.0f) + 10.0f) * D_80BE5DD0; + this->actor.velocity.y = (Rand_ZeroFloat(10.0f) + 15.0f) * D_80BE5DD0; + this->actor.gravity = -2.5f * D_80BE5DD0; + this->actor.terminalVelocity = -1000.0f * D_80BE5DD0; + this->actor.update = func_80BE5818; + + if (ENTANRON5_GET(&this->actor) >= ENTANRON5_110) { + this->actor.draw = func_80BE5C10; + this->unk_1A0 = Rand_ZeroFloat(1.999f); + Actor_SetScale(&this->actor, D_80BE5DD0 * 0.03f); + this->unk_144 = 250; + this->actor.shape.rot.x = this->actor.shape.rot.y = this->actor.shape.rot.z = 0; + } else { + this->unk_148 = gRuinFragmentDL; + this->unk_144 = 150; + } + } else if (ENTANRON5_GET(&this->actor) == ENTANRON5_0) { + EnTanron5* child; + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_80BE5E74); i++) { + child = + (EnTanron5*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TANRON5, D_80BE5DD4[i].x, + this->actor.world.pos.y, D_80BE5DD4[i].z, 0, Rand_ZeroFloat(0x10000), 0, i + 1); + + child->actor.parent = this->actor.parent; + child->unk_19C = D_80BE5E74[i]; + + Actor_SetScale(&child->actor, child->unk_19C); + + child->unk_148 = D_80BE5E24[i]; + if (child->unk_148 == gTwinmoldPyramidRuinDL) { + child->actor.shape.rot.y = 0; + } + + Collider_InitAndSetCylinder(globalCtx, &child->collider, &child->actor, &sCylinderInit); + } + + Actor_MarkForDeath(&this->actor); + } else { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 150.0f, 100.0f, 4); + this->actor.world.pos.y = this->actor.floorHeight + -20.0f; + } +} + +void EnTanron5_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTanron5* this = THIS; + + if (ENTANRON5_GET(&this->actor) >= ENTANRON5_100) { + D_80BE5D80--; + } +} + +void EnTanron5_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTanron5* this = THIS; + Boss02* boss02 = (Boss02*)this->actor.parent; + Player* player = GET_PLAYER(globalCtx2); + s32 i; + s32 phi_v0; + s32 spC4; + Vec3f spB8; + + if (this->unk_1A0 >= 3) { + this->unk_1A0++; + Actor_SetScale(&this->actor, 0.0f); + if (this->unk_1A0 >= 40) { + Actor_MarkForDeath(&this->actor); + } + return; + } else { + // required + } + + if (this->unk_144 != 0) { + this->unk_144--; + } + + if (boss02->actor.update != NULL) { + D_80BE5DD0 = boss02->unk_01AC; + } else { + D_80BE5DD0 = 1.0f; + } + + Actor_SetScale(&this->actor, this->unk_19C * D_80BE5DD0); + + if (this->unk_148 == gTwinmoldMajoraPillarDL) { + this->collider.dim.radius = 65.0f * D_80BE5DD0; + this->collider.dim.height = 380.0f * D_80BE5DD0; + } else if (this->unk_1A0 == 0) { + this->collider.dim.radius = 85.0f * D_80BE5DD0; + this->collider.dim.height = 200.0f * D_80BE5DD0; + } else if (this->unk_1A0 == 1) { + this->collider.dim.radius = 95.0f * D_80BE5DD0; + this->collider.dim.height = 100.0f * D_80BE5DD0; + } else if (this->unk_1A0 == 2) { + this->collider.dim.radius = 95.0f * D_80BE5DD0; + this->collider.dim.height = 30.0f * D_80BE5DD0; + } + + if (this->unk_144 == 0) { + if (this->collider.base.acFlags & AC_HIT) { + ColliderInfo* acHitInfo = this->collider.info.acHitInfo; + Actor* ac = this->collider.base.ac; + + this->collider.base.acFlags &= ~AC_HIT; + spC4 = 10; + + if (Play_InCsMode(globalCtx)) { + this->unk_144 = 1; + } else { + this->unk_144 = 5; + spC4 = (s32)Rand_ZeroFloat(2.99f) + 10; + } + + if ((KREG(19) != 0) || ((acHitInfo->toucher.dmgFlags & 0x05000202) && (D_80BE5DD0 < 0.5f)) || + (ac->id == ACTOR_BOSS_02)) { + if (this->unk_148 == gTwinmoldMajoraPillarDL) { + Math_Vec3f_Copy(&spB8, &this->actor.world.pos); + spB8.y += D_80BE5DD0 * 300.0f; + + for (i = 3; i < spC4; i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TANRON5, spB8.x, spB8.y, spB8.z, + Rand_ZeroFloat(0x10000), Rand_ZeroFloat(0x10000), 0, i + 100); + } + + for (i = 0; i < 6; i++) { + func_80BE4A2C(globalCtx->specialEffects, &spB8, Rand_ZeroFloat(3.0f) + 6.0f); + } + + this->actor.world.pos.y -= D_80BE5DD0 * 130.0f; + } else { + f32 spAC; + f32 spA8; + Vec3f sp9C; + + if (this->unk_1A0 == 0) { + spAC = 180.0f; + this->unk_19C *= 1.4f; + } else if (this->unk_1A0 == 1) { + spAC = 230.0f; + this->unk_19C *= 1.37f; + } else if (this->unk_1A0 == 2) { + spAC = 780.0f; + this->unk_19C *= 1.5f; + } + // TODO: determine if unk_1A0 ever has a different value from these 3, which will cause UB from spAC + // being uninitialised + this->actor.world.pos.y -= D_80BE5DD0 * spAC; + Actor_SetScale(&this->actor, this->unk_19C * D_80BE5DD0); + Math_Vec3f_Copy(&spB8, &this->actor.world.pos); + + for (i = 0; i < spC4; i++) { + if (this->unk_1A0 == 0) { + spA8 = 100.0f; + spAC = 180.0f; + } else if (this->unk_1A0 == 1) { + spA8 = 200.0f; + spAC = 100.0f; + } else if (this->unk_1A0 == 2) { + spA8 = 250.0f; + spAC = 50.0f; + } + + sp9C.x = (randPlusMinusPoint5Scaled(spA8) * D_80BE5DD0) + spB8.x; + sp9C.z = (randPlusMinusPoint5Scaled(spA8) * D_80BE5DD0) + spB8.z; + sp9C.y = this->actor.floorHeight + (spAC * D_80BE5DD0); + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TANRON5, sp9C.x, sp9C.y, sp9C.z, + Rand_ZeroFloat(0x10000), Rand_ZeroFloat(0x10000), 0, i + 100); + + if (i < 8) { + func_80BE4A2C(globalCtx->specialEffects, &sp9C, Rand_ZeroFloat(3.0f) + 6.0f); + } + } + } + + if (Rand_ZeroOne() < 0.333f) { + phi_v0 = 0x4000; + } else if (Rand_ZeroOne() < 0.5f) { + phi_v0 = -0x8000; + } else { + phi_v0 = -0x4000; + } + + this->actor.shape.rot.y += phi_v0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BIG_BOMB_EXPLOSION); + func_800BC848(&this->actor, globalCtx, 4, 4); + this->unk_1A0++; + } else { + Vec3f sp90; + ColliderInfo* info = this->collider.info.acHitInfo; + + sp90.x = info->bumper.hitPos.x; + sp90.y = info->bumper.hitPos.y; + sp90.z = info->bumper.hitPos.z; + + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_SHIELD_REFLECT_SW); + CollisionCheck_SpawnShieldParticlesMetal(globalCtx, &sp90); + } + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + if (this->unk_148 == gTwinmoldPyramidRuinDL) { + this->collider.dim.pos.y = this->actor.floorHeight; + } + + if ((this->unk_148 == gTwinmoldMajoraPillarDL) || (D_80BE5DD0 < 0.5f)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + f32 xDiff = player->actor.world.pos.x - this->actor.world.pos.x; + f32 yDiff = player->actor.world.pos.z - this->actor.world.pos.z; + + if ((fabsf(xDiff) < 120.0f) && (fabsf(yDiff) < 120.0f)) { + if (fabsf(yDiff) < fabsf(xDiff)) { + if (xDiff > 0.0f) { + player->actor.prevPos.x = player->actor.world.pos.x = this->actor.world.pos.x + 120.0f; + } else { + player->actor.prevPos.x = player->actor.world.pos.x = this->actor.world.pos.x - 120.0f; + } + } else if (yDiff > 0.0f) { + player->actor.prevPos.z = player->actor.world.pos.z = this->actor.world.pos.z + 120.0f; + } else { + player->actor.prevPos.z = player->actor.world.pos.z = this->actor.world.pos.z - 120.0f; + } + } + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80BE5818(Actor* thisx, GlobalContext* globalCtx2) { + f32 sp6C; + s32 i; + Vec3f sp5C; + EnTanron5* this = THIS; + GlobalContext* globalCtx = globalCtx2; + + if ((ENTANRON5_GET(&this->actor) < ENTANRON5_110) && (this->unk_1A0 != 0)) { + this->unk_1A0++; + this->actor.world.pos.y -= 2.0f * D_80BE5DD0; + if (this->unk_1A0 == 40) { + Actor_MarkForDeath(&this->actor); + } + return; + } + + if (DECR(this->unk_144) == 0) { + Actor_MarkForDeath(&this->actor); + } + + if (this->actor.speedXZ > 0.02f) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 50.0f, 150.0f, 100.0f, 4); + } + + if (ENTANRON5_GET(&this->actor) < ENTANRON5_110) { + this->actor.shape.rot.x += this->unk_198; + this->actor.shape.rot.y += this->unk_19A; + sp6C = 1225.0f; + + if (this->actor.bgCheckFlags & 1) { + if (ENTANRON5_GET(&this->actor) < ENTANRON5_108) { + Math_Vec3f_Copy(&sp5C, &this->actor.world.pos); + sp5C.y = this->actor.floorHeight; + + for (i = 0; i < 4; i++) { + func_80BE4930(globalCtx->specialEffects, &sp5C, Rand_ZeroFloat(1.0f) + 2.0f); + } + this->unk_1A0++; + } else { + Actor_MarkForDeath(&this->actor); + } + } + } else { + sp6C = 400.0f; + this->unk_198 += 0x2000; + if (this->actor.bgCheckFlags & 1) { + this->unk_198 = 0; + this->actor.speedXZ = 0.0f; + } + } + + if (this->unk_1A1 == 0) { + if ((D_80BE5DD0 > 0.5f) && + ((ENTANRON5_GET(&this->actor) < ENTANRON5_108) || (ENTANRON5_GET(&this->actor) >= ENTANRON5_110))) { + Player* player = GET_PLAYER(globalCtx); + Vec3f temp; + + temp.x = player->actor.world.pos.x - this->actor.world.pos.x; + temp.y = (player->actor.world.pos.y + 10.0f) - this->actor.world.pos.y; + temp.z = player->actor.world.pos.z - this->actor.world.pos.z; + + if (SQXYZ(temp) < sp6C) { + if (ENTANRON5_GET(&this->actor) >= ENTANRON5_110) { + if (this->unk_1A0 == 0) { + Item_Give(globalCtx, ITEM_ARROWS_10); + } else { + Item_Give(globalCtx, ITEM_MAGIC_LARGE); + } + Actor_MarkForDeath(&this->actor); + play_sound(NA_SE_SY_GET_ITEM); + } else { + this->unk_1A1 = 20; + func_800B8D50(globalCtx, NULL, 5.0f, this->actor.world.rot.y, 0.0f, 8); + } + } + } + } else { + this->unk_1A1--; + } +} + +void EnTanron5_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTanron5* this = THIS; + + if ((-500.0f * D_80BE5DD0) < this->actor.projectedPos.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++, this->unk_148); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_80BE5C10(Actor* thisx, GlobalContext* globalCtx) { + EnTanron5* this = THIS; + TexturePtr texture; + s32 phi_v0; + + if ((this->unk_144 > 50) || (this->unk_144 & 1)) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (((-500.0f * D_80BE5DD0) < this->actor.projectedPos.z) && phi_v0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->unk_1A0 == 0) { + texture = gameplay_keep_Tex_05BEF0; + } else { + texture = gameplay_keep_Tex_0617C0; + } + + POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(texture)); + + Matrix_Translate(0.0f, 200.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_198, 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_05F6F0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.h b/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.h index c19bb1ded..576309694 100644 --- a/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.h +++ b/src/overlays/actors/ovl_En_Tanron5/z_en_tanron5.h @@ -5,9 +5,24 @@ struct EnTanron5; +#define ENTANRON5_GET(thisx) ((thisx)->params) + +#define ENTANRON5_0 0 +#define ENTANRON5_100 100 +#define ENTANRON5_107 107 +#define ENTANRON5_108 108 +#define ENTANRON5_110 110 + typedef struct EnTanron5 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x60]; + /* 0x0144 */ s16 unk_144; + /* 0x0148 */ Gfx* unk_148; + /* 0x014C */ ColliderCylinder collider; + /* 0x0198 */ s16 unk_198; + /* 0x019A */ s16 unk_19A; + /* 0x019C */ f32 unk_19C; + /* 0x01A0 */ u8 unk_1A0; + /* 0x01A1 */ u8 unk_1A1; } EnTanron5; // size = 0x1A4 extern const ActorInit En_Tanron5_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron6/z_en_tanron6.c b/src/overlays/actors/ovl_En_Tanron6/z_en_tanron6.c index 7e184a710..bb57ff92f 100644 --- a/src/overlays/actors/ovl_En_Tanron6/z_en_tanron6.c +++ b/src/overlays/actors/ovl_En_Tanron6/z_en_tanron6.c @@ -1,6 +1,12 @@ +/* + * File: z_en_tanron6.c + * Overlay: ovl_En_Tanron6 + * Description: Swarm of Giant Bees + */ + #include "z_en_tanron6.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnTanron6*)thisx) @@ -63,7 +69,7 @@ void EnTanron6_Init(Actor* thisx, GlobalContext* globalCtx) { EnTanron6* this = THIS; this->actor.colChkInfo.mass = 10; - ActorShape_Init(&this->actor.shape, 0, func_800B3FC0, 19.0f); + ActorShape_Init(&this->actor.shape, 0, ActorShadow_DrawCircle, 19.0f); this->actor.colChkInfo.health = 1; this->actor.colChkInfo.damageTable = &sDamageTable; this->actor.targetMode = 6; @@ -84,7 +90,7 @@ void EnTanron6_Update(Actor* thisx, GlobalContext* globalCtx) { EnTanron6* this = THIS; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 40.0f, 40.0f, 0x1D); } 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 12086b398..e3e22939f 100644 --- a/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -1,6 +1,13 @@ -#include "z_en_test.h" +/* + * File: z_en_test.c + * Overlay: ovl_En_Test + * Description: Various crater marks (e.g., Goron Link punch/pound, Moon's Tear crash, etc.) + */ -#define FLAGS 0x00000010 +#include "z_en_test.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnTest*)thisx) @@ -9,7 +16,6 @@ void EnTest_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTest_Update(Actor* thisx, GlobalContext* globalCtx); void EnTest_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Test_InitVars = { ACTOR_EN_TEST, ACTORCAT_ITEMACTION, @@ -22,22 +28,247 @@ const ActorInit En_Test_InitVars = { (ActorFunc)EnTest_Draw, }; -#endif +void func_80862B70(EnTestStruct* arg0) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/func_80862B70.s") + for (i = 0; i < 20; i++) { + EnTestStruct* ptr = &arg0[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/func_80862CBC.s") + ptr->unk_00 = false; + ptr->unk_04 = 0; + ptr->unk_08.x = 0.0f; + ptr->unk_08.y = 0.0f; + ptr->unk_08.z = 0.0f; + ptr->unk_14.x = 0.0f; + ptr->unk_14.y = 0.0f; + ptr->unk_14.z = 0.0f; + ptr->unk_20.x = 0.0f; + ptr->unk_20.y = 0.0f; + ptr->unk_20.z = 0.0f; + ptr->unk_2C = 0.001f; + ptr->unk_30.x = 0; + ptr->unk_30.y = 0; + ptr->unk_30.z = 0; + ptr->unk_36.x = 0; + ptr->unk_36.y = 0; + ptr->unk_36.z = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/func_80862EDC.s") +void func_80862CBC(EnTestStruct* arg0, Vec3f* arg1) { + EnTestStruct* ptr; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/func_80863048.s") + for (i = 0; i < 20; i++) { + ptr = &arg0[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/EnTest_Init.s") + if (!ptr->unk_00) { + s16 sp26 = Rand_ZeroOne() * 0xFFFF; + f32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/EnTest_Destroy.s") + ptr->unk_00 = true; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/EnTest_Update.s") + ptr->unk_08.x = (Math_CosS(sp26) * 20.0f) + arg1->x; + ptr->unk_08.y = arg1->y; + ptr->unk_08.z = (Math_SinS(sp26) * 20.0f) + arg1->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/func_808634B8.s") + sp20 = Rand_ZeroOne(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test/EnTest_Draw.s") + ptr->unk_14.x = Math_CosS(sp26) * 13.0f * sp20; + ptr->unk_14.y = (Rand_ZeroOne() * 5.0f) + 8.0f; + ptr->unk_14.z = (Math_SinS(sp26) * 13.0f) * sp20; + + ptr->unk_20.x = 0.0f; + ptr->unk_20.z = 0.0f; + ptr->unk_20.y = -2.0f; + + ptr->unk_2C = (Rand_ZeroOne() * 0.0004f) + 0.0004f; + + ptr->unk_30.x = Rand_ZeroOne() * 0x7FFE; + ptr->unk_30.y = Rand_ZeroOne() * 0x7FFE; + ptr->unk_30.z = Rand_ZeroOne() * 0x7FFE; + + ptr->unk_36.x = Rand_ZeroOne() * 0x2000; + ptr->unk_36.y = Rand_ZeroOne() * 0x2000; + ptr->unk_36.z = Rand_ZeroOne() * 0x2000; + + ptr->unk_04 = 10; + break; + } + } +} + +void func_80862EDC(EnTestStruct* arg0) { + s32 i; + EnTestStruct* ptr; + + for (i = 0; i < 20; i++) { + ptr = &arg0[i]; + + if (ptr->unk_00) { + ptr->unk_04--; + if (ptr->unk_04 < 0) { + ptr->unk_00 = false; + } + + ptr->unk_08.x += ptr->unk_14.x; + ptr->unk_08.y += ptr->unk_14.y; + ptr->unk_08.z += ptr->unk_14.z; + + ptr->unk_14.x += ptr->unk_20.x; + ptr->unk_14.y += ptr->unk_20.y; + ptr->unk_14.z += ptr->unk_20.z; + + ptr->unk_30.x += ptr->unk_36.x; + ptr->unk_30.y += ptr->unk_36.y; + ptr->unk_30.z += ptr->unk_36.z; + } + } +} + +void func_80863048(GlobalContext* globalCtx, EnTestStruct* arg1) { + EnTestStruct* ptr; + s32 i; + Mtx* mtx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + + for (i = 0; i < 20; i++) { + ptr = &arg1[i]; + + if (!ptr->unk_00) { + continue; + } + + Matrix_Translate(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); + Matrix_RotateZYX(ptr->unk_30.x, ptr->unk_30.y, ptr->unk_30.z, MTXMODE_APPLY); + Matrix_Scale(ptr->unk_2C, ptr->unk_2C, ptr->unk_2C, MTXMODE_APPLY); + + mtx = Matrix_NewMtx(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnTest_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTest* this = THIS; + MtxF sp38; + s32 sp34; + + this->unk_209 = 0; + this->unk_174 = 0; + + if (thisx->params > 0) { + Actor_SetScale(thisx, thisx->params / 100000.0f); + this->unk_20A = 0; + } else { + thisx->floorPoly = NULL; + thisx->world.pos.y += 10.0f; + thisx->floorHeight = + BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &thisx->floorPoly, &sp34, &thisx->world.pos); + + if ((thisx->floorPoly == NULL) || (thisx->floorHeight == BGCHECK_Y_MIN)) { + Actor_MarkForDeath(thisx); + return; + } + + thisx->world.pos.y = thisx->floorHeight; + func_800C0094(thisx->floorPoly, thisx->world.pos.x, thisx->floorHeight, thisx->world.pos.z, &sp38); + Matrix_MtxFToYXZRot(&sp38, &thisx->shape.rot, true); + thisx->world.rot = thisx->shape.rot; + this->unk_20A = func_800C9BB8(&globalCtx->colCtx, thisx->floorPoly, sp34); + } + + func_80183430(&this->skeletonInfo, &gameplay_keep_Blob_06EB70, &gameplay_keep_Blob_06BB0C, this->unk_178, + this->unk_1C0, NULL); + func_801834A8(&this->skeletonInfo, &gameplay_keep_Blob_06BB0C); + this->skeletonInfo.frameCtrl.unk_10 = 9.0f; + func_80862B70(this->unk_20C); +} + +void EnTest_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTest* this = THIS; + + func_8018349C(&this->skeletonInfo); +} + +void EnTest_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTest* this = THIS; + s32 i; + + this->unk_208 = this->skeletonInfo.frameCtrl.unk_10; + + if (func_80183DE0(&this->skeletonInfo) && (this->actor.parent == NULL) && (this->actor.params != -1)) { + this->unk_209++; + if (this->unk_209 > 20) { + Actor_MarkForDeath(&this->actor); + } + } + + if ((this->actor.params != -1) && (this->unk_208 >= 2)) { + if (!(this->unk_174 & 1)) { + this->unk_174 |= 1; + + for (i = 0; i < ARRAY_COUNT(this->unk_20C); i++) { + func_80862CBC(this->unk_20C, &this->actor.world.pos); + } + } + } + func_80862EDC(this->unk_20C); +} + +s32 EnTest_OverrideKeyframeDraw(GlobalContext* globalCtx, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, + u8* flags, Actor* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { + EnTest* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->actor.params == -1) && ((limbIndex == 1) || (limbIndex == 2))) { + *dList = NULL; + } + + if ((this->actor.params == -2) && (limbIndex == 3)) { + *dList = NULL; + } + + if (limbIndex == 3) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 0, 0, 0, ((20 - this->unk_209) * 255.0f) / 20.0f); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, ((20 - this->unk_209) * 255.0f) / 20.0f); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + return true; +} + +void EnTest_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTest* this = THIS; + Mtx* sp28; + s32 sp2C = this->unk_208 - 1; + + if (sp2C >= 29) { + sp2C = 29; + } + + if ((this->unk_20A == 15) || (this->unk_20A == 14)) { + AnimatedMat_DrawStep(globalCtx, Lib_SegmentedToVirtual(gameplay_keep_Matanimheader_06B730), sp2C); + } else { + AnimatedMat_DrawStep(globalCtx, Lib_SegmentedToVirtual(gameplay_keep_Matanimheader_06B6A0), sp2C); + } + + sp28 = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(this->skeletonInfo.unk_18->unk_1 * sizeof(Mtx))); + + if (sp28 != NULL) { + func_8012C2DC(globalCtx->state.gfxCtx); + func_8018450C(globalCtx, &this->skeletonInfo, sp28, EnTest_OverrideKeyframeDraw, NULL, thisx); + func_80863048(globalCtx, this->unk_20C); + } +} diff --git a/src/overlays/actors/ovl_En_Test/z_en_test.h b/src/overlays/actors/ovl_En_Test/z_en_test.h index 32015ecb1..bcb0c4a1e 100644 --- a/src/overlays/actors/ovl_En_Test/z_en_test.h +++ b/src/overlays/actors/ovl_En_Test/z_en_test.h @@ -5,9 +5,27 @@ struct EnTest; +typedef struct { + /* 0x00 */ s32 unk_00; + /* 0x04 */ s32 unk_04; + /* 0x08 */ Vec3f unk_08; + /* 0x14 */ Vec3f unk_14; + /* 0x20 */ Vec3f unk_20; + /* 0x2C */ f32 unk_2C; + /* 0x30 */ Vec3s unk_30; + /* 0x36 */ Vec3s unk_36; +} EnTestStruct; // size = 0x3C + typedef struct EnTest { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x578]; + /* 0x144 */ SkeletonInfo skeletonInfo; + /* 0x174 */ s32 unk_174; + /* 0x178 */ Vec3s unk_178[12]; + /* 0x1C0 */ s16 unk_1C0[36]; + /* 0x208 */ u8 unk_208; + /* 0x209 */ u8 unk_209; + /* 0x20A */ u8 unk_20A; + /* 0x20C */ EnTestStruct unk_20C[20]; } EnTest; // size = 0x6BC extern const ActorInit En_Test_InitVars; diff --git a/src/overlays/actors/ovl_En_Test2/z_en_test2.c b/src/overlays/actors/ovl_En_Test2/z_en_test2.c index 8a78ce1bd..c16a4133d 100644 --- a/src/overlays/actors/ovl_En_Test2/z_en_test2.c +++ b/src/overlays/actors/ovl_En_Test2/z_en_test2.c @@ -1,6 +1,12 @@ +/* + * File: z_en_test2.c + * Overlay: ovl_En_Test2 + * Description: Objects affected by the Lens of Truth + */ + #include "z_en_test2.h" -#define FLAGS 0x00000090 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_80) #define THIS ((EnTest2*)thisx) diff --git a/src/overlays/actors/ovl_En_Test3/z_en_test3.c b/src/overlays/actors/ovl_En_Test3/z_en_test3.c index c5f54d31a..ce9a8f3c9 100644 --- a/src/overlays/actors/ovl_En_Test3/z_en_test3.c +++ b/src/overlays/actors/ovl_En_Test3/z_en_test3.c @@ -1,6 +1,12 @@ +/* + * File: z_en_test3.c + * Overlay: ovl_En_Test3 + * Description: Kafei + */ + #include "z_en_test3.h" -#define FLAGS 0x04000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_4000000) #define THIS ((EnTest3*)thisx) 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 f5f460141..729a82a70 100644 --- a/src/overlays/actors/ovl_En_Test4/z_en_test4.c +++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.c @@ -1,14 +1,14 @@ /* * File: z_en_test4.c * Overlay: ovl_En_Test4 - * Description: Day transition effects + * Description: Three-Day Timer */ #include "z_en_test4.h" #include "overlays/gamestates/ovl_daytelop/z_daytelop.h" #include "overlays/actors/ovl_En_Horse/z_en_horse.h" -#define FLAGS 0x00100030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_100000) #define THIS ((EnTest4*)thisx) @@ -51,11 +51,11 @@ void func_80A41D70(EnTest4* this, GlobalContext* globalCtx) { } else if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0)) { if (globalCtx->actorCtx.unk5 & 2) { Sram_IncrementDay(); - gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.save.time = CLOCK_TIME(6, 0); func_80151A68(globalCtx, sDayMessages1[CURRENT_DAY - 1]); } else { this->unk_144 = 0; - this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.save.time += CLOCK_TIME_MINUTE; } func_8010EE74(globalCtx, CURRENT_DAY); @@ -84,7 +84,7 @@ void func_80A41D70(EnTest4* this, GlobalContext* globalCtx) { this->unk_144 = 0; } - this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.save.time += CLOCK_TIME_MINUTE; } } @@ -93,7 +93,7 @@ void func_80A41FA4(EnTest4* this, GlobalContext* globalCtx) { func_80151A68(globalCtx, sNightMessages2[CURRENT_DAY - 1]); } else if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0)) { Sram_IncrementDay(); - gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.save.time = CLOCK_TIME(6, 0); func_8010EE74(globalCtx, CURRENT_DAY); func_80151A68(globalCtx, sDayMessages2[CURRENT_DAY - 1]); D_801BDBC8 = 0xFE; @@ -121,174 +121,172 @@ void func_80A41FA4(EnTest4* this, GlobalContext* globalCtx) { this->unk_144 = 0; } - this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.save.time += CLOCK_TIME_MINUTE; } } // Bells on last day void func_80A42198(EnTest4* this) { - if ((gSaveContext.time >= CLOCK_TIME(6, 0)) && (gSaveContext.time <= CLOCK_TIME(18, 0))) { - if (gSaveContext.time < CLOCK_TIME(17, 30)) { + if ((gSaveContext.save.time >= CLOCK_TIME(6, 0)) && (gSaveContext.save.time <= CLOCK_TIME(18, 0))) { + if (gSaveContext.save.time < CLOCK_TIME(17, 30)) { this->nextBellTime = CLOCK_TIME(17, 30); - } else if (gSaveContext.time < CLOCK_TIME(17, 36)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 36)) { this->nextBellTime = CLOCK_TIME(17, 36); - } else if (gSaveContext.time < CLOCK_TIME(17, 42)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 42)) { this->nextBellTime = CLOCK_TIME(17, 42); - } else if (gSaveContext.time < CLOCK_TIME(17, 48)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 48)) { this->nextBellTime = CLOCK_TIME(17, 48); - } else if (gSaveContext.time < CLOCK_TIME(17, 54)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 54)) { this->nextBellTime = CLOCK_TIME(17, 54); } else { this->nextBellTime = CLOCK_TIME(0, 0); } - } else if (gSaveContext.time > CLOCK_TIME(6, 0)) { + } else if (gSaveContext.save.time > CLOCK_TIME(6, 0)) { this->nextBellTime = CLOCK_TIME(0, 0); - } else if (gSaveContext.time < CLOCK_TIME(0, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(0, 10)) { this->nextBellTime = CLOCK_TIME(0, 10); - } else if (gSaveContext.time < CLOCK_TIME(0, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(0, 20)) { this->nextBellTime = CLOCK_TIME(0, 20); - } else if (gSaveContext.time < CLOCK_TIME(0, 30)) { + } else if (gSaveContext.save.time < CLOCK_TIME(0, 30)) { this->nextBellTime = CLOCK_TIME(0, 30); - } else if (gSaveContext.time < CLOCK_TIME(0, 40)) { + } else if (gSaveContext.save.time < CLOCK_TIME(0, 40)) { this->nextBellTime = CLOCK_TIME(0, 40); - } else if (gSaveContext.time < CLOCK_TIME(0, 50)) { + } else if (gSaveContext.save.time < CLOCK_TIME(0, 50)) { this->nextBellTime = CLOCK_TIME(0, 50); - } else if (gSaveContext.time < CLOCK_TIME(1, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 0)) { this->nextBellTime = CLOCK_TIME(1, 0); - } else if (gSaveContext.time < CLOCK_TIME(1, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 10)) { this->nextBellTime = CLOCK_TIME(1, 10); - } else if (gSaveContext.time < CLOCK_TIME(1, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 20)) { this->nextBellTime = CLOCK_TIME(1, 20); - } else if (gSaveContext.time < CLOCK_TIME(1, 30) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 30) - 1) { this->nextBellTime = CLOCK_TIME(1, 30) - 1; - } else if (gSaveContext.time < CLOCK_TIME(1, 40) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 40) - 1) { this->nextBellTime = CLOCK_TIME(1, 40) - 1; - } else if (gSaveContext.time < CLOCK_TIME(1, 50) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(1, 50) - 1) { this->nextBellTime = CLOCK_TIME(1, 50) - 1; - } else if (gSaveContext.time < CLOCK_TIME(2, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 0)) { this->nextBellTime = CLOCK_TIME(2, 0); - } else if (gSaveContext.time < CLOCK_TIME(2, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 10)) { this->nextBellTime = CLOCK_TIME(2, 10); - } else if (gSaveContext.time < CLOCK_TIME(2, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 20)) { this->nextBellTime = CLOCK_TIME(2, 20); - } else if (gSaveContext.time < CLOCK_TIME(2, 30)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 30)) { this->nextBellTime = CLOCK_TIME(2, 30); - } else if (gSaveContext.time < CLOCK_TIME(2, 40)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 40)) { this->nextBellTime = CLOCK_TIME(2, 40); - } else if (gSaveContext.time < CLOCK_TIME(2, 50)) { + } else if (gSaveContext.save.time < CLOCK_TIME(2, 50)) { this->nextBellTime = CLOCK_TIME(2, 50); - } else if (gSaveContext.time < CLOCK_TIME(3, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 0)) { this->nextBellTime = CLOCK_TIME(3, 0); - } else if (gSaveContext.time < CLOCK_TIME(3, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 10)) { this->nextBellTime = CLOCK_TIME(3, 10); - } else if (gSaveContext.time < CLOCK_TIME(3, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 20)) { this->nextBellTime = CLOCK_TIME(3, 20); - } else if (gSaveContext.time < CLOCK_TIME(3, 30)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 30)) { this->nextBellTime = CLOCK_TIME(3, 30); - } else if (gSaveContext.time < CLOCK_TIME(3, 40)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 40)) { this->nextBellTime = CLOCK_TIME(3, 40); - } else if (gSaveContext.time < CLOCK_TIME(3, 50)) { + } else if (gSaveContext.save.time < CLOCK_TIME(3, 50)) { this->nextBellTime = CLOCK_TIME(3, 50); - } else if (gSaveContext.time < CLOCK_TIME(4, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 0)) { this->nextBellTime = CLOCK_TIME(4, 0); - } else if (gSaveContext.time < CLOCK_TIME(4, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 10)) { this->nextBellTime = CLOCK_TIME(4, 10); - } else if (gSaveContext.time < CLOCK_TIME(4, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 20)) { this->nextBellTime = CLOCK_TIME(4, 20); - } else if (gSaveContext.time < CLOCK_TIME(4, 30) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 30) - 1) { this->nextBellTime = CLOCK_TIME(4, 30) - 1; - } else if (gSaveContext.time < CLOCK_TIME(4, 40) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 40) - 1) { this->nextBellTime = CLOCK_TIME(4, 40) - 1; - } else if (gSaveContext.time < CLOCK_TIME(4, 50) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(4, 50) - 1) { this->nextBellTime = CLOCK_TIME(4, 50) - 1; - } else if (gSaveContext.time < CLOCK_TIME(5, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 0)) { this->nextBellTime = CLOCK_TIME(5, 0); - } else if (gSaveContext.time < CLOCK_TIME(5, 5)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 5)) { this->nextBellTime = CLOCK_TIME(5, 5); - } else if (gSaveContext.time < CLOCK_TIME(5, 10)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 10)) { this->nextBellTime = CLOCK_TIME(5, 10); - } else if (gSaveContext.time < CLOCK_TIME(5, 15) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 15) - 1) { this->nextBellTime = CLOCK_TIME(5, 15) - 1; - } else if (gSaveContext.time < CLOCK_TIME(5, 20)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 20)) { this->nextBellTime = CLOCK_TIME(5, 20); - } else if (gSaveContext.time < CLOCK_TIME(5, 25) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 25) - 1) { this->nextBellTime = CLOCK_TIME(5, 25) - 1; - } else if (gSaveContext.time < CLOCK_TIME(5, 30)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 30)) { this->nextBellTime = CLOCK_TIME(5, 30); - } else if (gSaveContext.time < CLOCK_TIME(5, 33) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 33) - 1) { this->nextBellTime = CLOCK_TIME(5, 33) - 1; - } else if (gSaveContext.time < CLOCK_TIME(5, 36)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 36)) { this->nextBellTime = CLOCK_TIME(5, 36); - } else if (gSaveContext.time < CLOCK_TIME(5, 39) - 1) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 39) - 1) { this->nextBellTime = CLOCK_TIME(5, 39) - 1; - } else if (gSaveContext.time < CLOCK_TIME(5, 42)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 42)) { this->nextBellTime = CLOCK_TIME(5, 42); - } else if (gSaveContext.time < CLOCK_TIME(5, 45)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 45)) { this->nextBellTime = CLOCK_TIME(5, 45); - } else if (gSaveContext.time < CLOCK_TIME(5, 48)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 48)) { this->nextBellTime = CLOCK_TIME(5, 48); - } else if (gSaveContext.time < CLOCK_TIME(5, 51)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 51)) { this->nextBellTime = CLOCK_TIME(5, 51); - } else if (gSaveContext.time < CLOCK_TIME(5, 54)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 54)) { this->nextBellTime = CLOCK_TIME(5, 54); - } else if (gSaveContext.time < CLOCK_TIME(5, 57)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 57)) { this->nextBellTime = CLOCK_TIME(5, 57); - } else if (gSaveContext.time < CLOCK_TIME(6, 0)) { + } else if (gSaveContext.save.time < CLOCK_TIME(6, 0)) { this->nextBellTime = CLOCK_TIME(6, 0); } } // Bells on first and second day void func_80A425E4(EnTest4* this, GlobalContext* globalCtx) { - gSaveContext.unk_3F64 = 1000.0f; + gSaveContext.screenScale = 1000.0f; - if ((gSaveContext.time >= CLOCK_TIME(6, 0)) && (gSaveContext.time < CLOCK_TIME(18, 0))) { - if (gSaveContext.time < CLOCK_TIME(17, 30)) { + if ((gSaveContext.save.time >= CLOCK_TIME(6, 0)) && (gSaveContext.save.time < CLOCK_TIME(18, 0))) { + if (gSaveContext.save.time < CLOCK_TIME(17, 30)) { this->nextBellTime = CLOCK_TIME(17, 30); - } else if (gSaveContext.time < CLOCK_TIME(17, 36)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 36)) { this->nextBellTime = CLOCK_TIME(17, 36); - } else if (gSaveContext.time < CLOCK_TIME(17, 42)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 42)) { this->nextBellTime = CLOCK_TIME(17, 42); - } else if (gSaveContext.time < CLOCK_TIME(17, 48)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 48)) { this->nextBellTime = CLOCK_TIME(17, 48); - } else if (gSaveContext.time < CLOCK_TIME(17, 54)) { + } else if (gSaveContext.save.time < CLOCK_TIME(17, 54)) { this->nextBellTime = CLOCK_TIME(17, 54); } else { this->nextBellTime = CLOCK_TIME(5, 30); } } else { - if (gSaveContext.time < CLOCK_TIME(5, 30)) { + if (gSaveContext.save.time < CLOCK_TIME(5, 30)) { this->nextBellTime = CLOCK_TIME(5, 30); - } else if (gSaveContext.time < CLOCK_TIME(5, 36)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 36)) { this->nextBellTime = CLOCK_TIME(5, 36); - } else if (gSaveContext.time < CLOCK_TIME(5, 42)) { + } else if (gSaveContext.save.time < CLOCK_TIME(5, 42)) { this->nextBellTime = CLOCK_TIME(5, 42); - gSaveContext.unk_3F64 -= 50.0f; - } else if (gSaveContext.time < CLOCK_TIME(5, 48)) { + gSaveContext.screenScale -= 50.0f; + } else if (gSaveContext.save.time < CLOCK_TIME(5, 48)) { this->nextBellTime = CLOCK_TIME(5, 48); - gSaveContext.unk_3F64 -= 100.0f; - } else if (gSaveContext.time < CLOCK_TIME(5, 54)) { + gSaveContext.screenScale -= 100.0f; + } else if (gSaveContext.save.time < CLOCK_TIME(5, 54)) { this->nextBellTime = CLOCK_TIME(5, 54); - gSaveContext.unk_3F64 -= 150.0f; - } else if (gSaveContext.time < CLOCK_TIME(6, 0)) { + gSaveContext.screenScale -= 150.0f; + } else if (gSaveContext.save.time < CLOCK_TIME(6, 0)) { this->nextBellTime = CLOCK_TIME(17, 30); - gSaveContext.unk_3F64 -= 200.0f; + gSaveContext.screenScale -= 200.0f; } else { this->nextBellTime = CLOCK_TIME(17, 30); } if ((sCutscenes[this->unk_144] < 0) || ((globalCtx->actorCtx.unk5 & 2) != 0) || (CURRENT_DAY == 3) || - (gSaveContext.time >= CLOCK_TIME(17, 0))) { - gSaveContext.unk_3F64 = 1000.0f; + (gSaveContext.save.time >= CLOCK_TIME(17, 0))) { + gSaveContext.screenScale = 1000.0f; } - if (gSaveContext.unk_3F64 != 1000.0f) { - gSaveContext.unk_3F60 = 1; + if (gSaveContext.screenScale != 1000.0f) { + gSaveContext.screenScaleFlag = 1; } } } -#ifdef NON_MATCHING -// 1 instruction in the wrong place void EnTest4_Init(Actor* thisx, GlobalContext* globalCtx) { s32 dayTemp; EnTest4* this = THIS; @@ -311,29 +309,30 @@ void EnTest4_Init(Actor* thisx, GlobalContext* globalCtx) { } else { sIsLoaded = true; this->actor.room = -1; - gSaveContext.unk_3F60 = 0; - gSaveContext.unk_3F64 = 1000.0f; + gSaveContext.screenScaleFlag = 0; + gSaveContext.screenScale = 1000.0f; if (CURRENT_DAY == 0) { - if (gSaveContext.time < CLOCK_TIME(6, 1)) { - gSaveContext.time = CLOCK_TIME(6, 0); + if (gSaveContext.save.time < CLOCK_TIME(6, 1)) { + gSaveContext.save.time = CLOCK_TIME(6, 0); gSaveContext.gameMode = 0; - do { + { GameState* state = &globalCtx->state; state->running = false; - } while (0); + } SET_NEXT_GAMESTATE(&globalCtx->state, Daytelop_Init, DaytelopContext); + if (this && this && this) {} this->unk_144 = 1; - gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.save.time = CLOCK_TIME(6, 0); Actor_MarkForDeath(&this->actor); } else { - gSaveContext.day = 1; - dayTemp = gSaveContext.day; - gSaveContext.daysElapsed = dayTemp; + gSaveContext.save.day = 1; + dayTemp = gSaveContext.save.day; + gSaveContext.save.daysElapsed = dayTemp; this->unk_144 = 1; - this->unk_146 = gSaveContext.time; + this->unk_146 = gSaveContext.save.time; this->actionFunc = func_80A42AB8; } - } else if (gSaveContext.time == CLOCK_TIME(6, 0)) { + } else if (gSaveContext.save.time == CLOCK_TIME(6, 0)) { this->unk_144 = 0; func_80A41D70(this, globalCtx); if ((gSaveContext.cutsceneTrigger == 0) && (sCutscenes[this->unk_144] >= 0) && @@ -341,12 +340,12 @@ void EnTest4_Init(Actor* thisx, GlobalContext* globalCtx) { player->stateFlags1 |= 0x200; } } else { - if ((gSaveContext.time > CLOCK_TIME(18, 0)) || (gSaveContext.time < CLOCK_TIME(6, 0))) { + if ((gSaveContext.save.time > CLOCK_TIME(18, 0)) || (gSaveContext.save.time < CLOCK_TIME(6, 0))) { this->unk_144 = 0; } else { this->unk_144 = 1; } - this->unk_146 = gSaveContext.time; + this->unk_146 = gSaveContext.save.time; this->actionFunc = func_80A42AB8; } } @@ -357,15 +356,12 @@ void EnTest4_Init(Actor* thisx, GlobalContext* globalCtx) { func_80A425E4(this, globalCtx); } - this->lastBellTime = gSaveContext.time; + this->lastBellTime = gSaveContext.save.time; if ((sCutscenes[this->unk_144] < 0) || (globalCtx->actorCtx.unk5 & 2)) { - gSaveContext.unk_3F60 = 0; - gSaveContext.unk_3F64 = 1000.0f; + gSaveContext.screenScaleFlag = 0; + gSaveContext.screenScale = 1000.0f; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test4/EnTest4_Init.s") -#endif void EnTest4_Destroy(Actor* thisx, GlobalContext* globalCtx) { } @@ -373,7 +369,7 @@ void EnTest4_Destroy(Actor* thisx, GlobalContext* globalCtx) { void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((globalCtx->unk_18B4A == 0) && (func_801690CC(globalCtx) == 0) && (globalCtx->numSetupActors <= 0) && + if ((globalCtx->unk_18B4A == 0) && !Play_InCsMode(globalCtx) && (globalCtx->numSetupActors <= 0) && (globalCtx->roomCtx.unk31 == 0) && (func_8016A168() == 0)) { s16 temp_a2; u16 temp_a0 = D_80A43364[this->unk_144]; @@ -381,10 +377,10 @@ void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { s16 bellDiff; s16 new_var; - temp_a3 = gSaveContext.time - temp_a0; + temp_a3 = gSaveContext.save.time - temp_a0; temp_a2 = this->unk_146 - temp_a0; bellDiff = this->lastBellTime - this->nextBellTime; - new_var = gSaveContext.time - this->nextBellTime; + new_var = gSaveContext.save.time - this->nextBellTime; if ((temp_a3 * temp_a2) <= 0) { gSaveContext.unk_3CA7 = 1; @@ -402,14 +398,14 @@ void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { } else if (((sCutscenes[this->unk_144] < 0) || (globalCtx->actorCtx.unk5 & 2)) && CURRENT_DAY != 3) { func_80A41FA4(this, globalCtx); } else { - gSaveContext.unk_3F64 = 0.0f; - func_80169DCC(globalCtx, 0, Entrance_CreateIndexFromSpawn(0), player->unk_3CE, 0xBFF, - &player->unk_3C0, player->unk_3CC); - func_80169EFC(globalCtx); + gSaveContext.screenScale = 0.0f; + Play_SetRespawnData(&globalCtx->state, RESTART_MODE_DOWN, Entrance_CreateIndexFromSpawn(0), + player->unk_3CE, 0xBFF, &player->unk_3C0, player->unk_3CC); + func_80169EFC(&globalCtx->state); if (player->stateFlags1 & 0x800000) { EnHorse* rideActor = (EnHorse*)player->rideActor; - if ((rideActor->unk_150 == 0) || (rideActor->unk_150 == 2)) { + if ((rideActor->type == HORSE_EPONA) || (rideActor->type == HORSE_2)) { if (CURRENT_DAY < 3) { D_801BDA9C = 1; } else { @@ -426,7 +422,7 @@ void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { if ((sCutscenes[this->unk_144] >= 0) && ((globalCtx->actorCtx.unk5 & 2) == 0)) { player->stateFlags1 |= 0x200; - this->unk_146 = gSaveContext.time; + this->unk_146 = gSaveContext.save.time; } else { if (this->unk_144 == 0) { this->unk_144 = 1; @@ -434,26 +430,26 @@ void func_80A42AB8(EnTest4* this, GlobalContext* globalCtx) { this->unk_144 = 0; } - this->unk_146 = gSaveContext.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.save.time += CLOCK_TIME_MINUTE; } } else if ((new_var * bellDiff) <= 0) { func_801A0124(&this->actor.projectedPos, (this->actor.params >> 5) & 0xF); - this->lastBellTime = gSaveContext.time; + this->lastBellTime = gSaveContext.save.time; if (CURRENT_DAY == 3) { if ((this->nextBellTime == CLOCK_TIME(0, 0)) && - ((gSaveContext.inventory.items[ITEM_OCARINA] == ITEM_NONE) || + ((gSaveContext.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) || (globalCtx->sceneNum == SCENE_CLOCKTOWER))) { - s32 phi_v0; - u32 entranceIndex = gSaveContext.entranceIndex; + s32 playerParams; + u32 entranceIndex = gSaveContext.save.entranceIndex; if ((globalCtx->actorCtx.unk5 & 2)) { - phi_v0 = 0xCFF; + playerParams = 0xCFF; } else { - phi_v0 = 0xBFF; + playerParams = 0xBFF; } - func_80169DCC(globalCtx, 1, entranceIndex, player->unk_3CE, phi_v0, &player->unk_3C0, - player->unk_3CC); + Play_SetRespawnData(&globalCtx->state, RESTART_MODE_RETURN, entranceIndex, player->unk_3CE, + playerParams, &player->unk_3C0, player->unk_3CC); if ((globalCtx->sceneNum == SCENE_TENMON_DAI) || (globalCtx->sceneNum == SCENE_00KEIKOKU)) { globalCtx->nextEntranceIndex = 0x5400; @@ -498,8 +494,8 @@ void func_80A42F20(EnTest4* this, GlobalContext* globalCtx) { if (this->transitionCsTimer == 60) { Player* player = GET_PLAYER(globalCtx); - gSaveContext.time += CLOCK_TIME_MINUTE; - this->unk_146 = gSaveContext.time; + gSaveContext.save.time += CLOCK_TIME_MINUTE; + this->unk_146 = gSaveContext.save.time; globalCtx->numSetupActors = -globalCtx->numSetupActors; player->stateFlags1 &= ~0x200; } @@ -521,8 +517,8 @@ void func_80A42F20(EnTest4* this, GlobalContext* globalCtx) { } void func_80A430C8(EnTest4* this, GlobalContext* globalCtx) { - if ((CURRENT_DAY == 2) && (gSaveContext.time >= CLOCK_TIME(7, 0)) && (gSaveContext.time < CLOCK_TIME(17, 30)) && - (globalCtx->envCtx.unk_F2[2] == 0)) { + if ((CURRENT_DAY == 2) && (gSaveContext.save.time >= CLOCK_TIME(7, 0)) && + (gSaveContext.save.time < CLOCK_TIME(17, 30)) && (globalCtx->envCtx.unk_F2[2] == 0)) { // rain? D_801BDBB0 = 1; @@ -546,7 +542,7 @@ void func_80A430C8(EnTest4* this, GlobalContext* globalCtx) { } void func_80A431C8(EnTest4* this, GlobalContext* globalCtx) { - if (((gSaveContext.time >= CLOCK_TIME(17, 30)) && (gSaveContext.time < CLOCK_TIME(23, 0)) && + if (((gSaveContext.save.time >= CLOCK_TIME(17, 30)) && (gSaveContext.save.time < CLOCK_TIME(23, 0)) && (globalCtx->envCtx.unk_F2[0] != 0)) || (globalCtx->envCtx.unk_F2[2] != 0)) { D_801BDBB0 = 0; 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 76097f09a..4a93cf5e8 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.c +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.c @@ -1,18 +1,21 @@ +/* + * File: z_en_test5.c + * Overlay: ovl_En_Test5 + * Description: Spring Water Modifier + */ + #include "z_en_test5.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnTest5*)thisx) 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, @@ -25,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) { + GlobalContext* globalCtx = globalCtx2; + EnTest5* this = THIS; + WaterBox* water; + f32 ySurface; -#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->interactRangeActor == NULL || player->getItemId != 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) { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, this->actor.xzDistToPlayer, + fabsf(this->actor.playerHeightRel)); + } + } +} + +void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTest5* this = THIS; + Vec3f steamPos; + CollisionPoly* poly; + s32 pad; + + 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 6fa9bf8b9..2efb3eb6b 100644 --- a/src/overlays/actors/ovl_En_Test6/z_en_test6.c +++ b/src/overlays/actors/ovl_En_Test6/z_en_test6.c @@ -1,6 +1,13 @@ -#include "z_en_test6.h" +/* + * File: z_en_test6.c + * Overlay: ovl_En_Test6 + * Description: Song of Time effects (Return to DotFD, invert, skip forward) + */ -#define FLAGS 0x02200030 +#include "z_en_test6.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_200000 | ACTOR_FLAG_2000000) #define THIS ((EnTest6*)thisx) @@ -9,14 +16,31 @@ void EnTest6_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTest6_Update(Actor* thisx, GlobalContext* globalCtx); void EnTest6_Draw(Actor* thisx, GlobalContext* globalCtx); +struct EnTest6Struct; + +typedef void (*EnTest6StructFunc)(EnTest6*, GlobalContext*, struct EnTest6Struct*); + +typedef struct EnTest6Struct { + /* 0x00 */ s32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ EnTest6StructFunc unk_14; +} EnTest6Struct; // size = 0x18 + +void func_80A90D34(EnTest6* this, GlobalContext* globalCtx, EnTest6Struct* ptr); +void func_80A90FC0(EnTest6* this, GlobalContext* globalCtx, EnTest6Struct* ptr); +void EnTest6_SetupAction(EnTest6* this, EnTest6ActionFunc actionFunc); void func_80A9156C(EnTest6* this, GlobalContext* globalCtx); +void func_80A91690(EnTest6* this, GlobalContext* globalCtx); void func_80A91760(EnTest6* this, GlobalContext* globalCtx); +void func_80A920C8(EnTest6* this, GlobalContext* globalCtx); void func_80A92188(EnTest6* this, GlobalContext* globalCtx); void func_80A92950(EnTest6* this, GlobalContext* globalCtx); -void EnTest6_SetupAction(EnTest6* this, EnTest6ActionFunc actionFunc); +EnTest6Struct D_80A94910[12]; -#if 0 const ActorInit En_Test6_InitVars = { ACTOR_EN_TEST6, ACTORCAT_ITEMACTION, @@ -29,50 +53,1267 @@ const ActorInit En_Test6_InitVars = { (ActorFunc)EnTest6_Draw, }; -#endif +u8 D_80A93E80[] = { + 0x00, 0x0D, 0x01, 0xA8, 0x00, 0x00, 0x00, 0x64, 0x04, 0x64, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xED, 0x00, + 0x00, 0x04, 0x64, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0xFF, 0xED, 0x00, 0x00, 0x04, 0x64, 0x00, 0x10, 0x00, 0x00, + 0x00, 0x15, 0xFF, 0xED, 0x00, 0x00, 0x04, 0x64, 0x00, 0x11, 0xFF, 0xE6, 0xFF, 0xFB, 0xFF, 0xE0, 0x00, 0x00, 0x04, + 0x64, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x12, 0xFF, 0xE0, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0E, 0x00, 0x01, 0x00, 0x16, + 0xFF, 0xE5, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFB, 0x00, 0x00, 0x04, 0x64, 0x00, + 0x07, 0x00, 0x10, 0x00, 0x1D, 0xFF, 0xB3, 0x00, 0x00, 0x04, 0x64, 0x00, 0x03, 0x00, 0x01, 0x00, 0x13, 0x00, 0x6F, + 0x00, 0x00, 0x04, 0x64, 0x00, 0x03, 0xFF, 0xC5, 0x00, 0x15, 0x00, 0x5B, 0x00, 0x00, 0x04, 0x64, 0x00, 0x03, 0xFF, + 0xED, 0x00, 0x3B, 0x00, 0x54, 0x00, 0x00, 0x04, 0x64, 0x00, 0x88, 0xFF, 0xED, 0x00, 0x3B, 0x00, 0x54, 0x00, 0x00, + 0x04, 0x64, 0x00, 0x6C, 0xFF, 0xEF, 0x00, 0x39, 0x00, 0x52, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0D, 0x00, 0x00, 0x00, + 0x32, 0x02, 0xA9, 0x00, 0x00, 0x04, 0x64, 0x00, 0x12, 0x00, 0x00, 0x00, 0x32, 0x02, 0xA9, 0x00, 0x00, 0x04, 0x64, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x02, 0xA9, 0x00, 0x00, 0x04, 0x64, 0x00, 0x11, 0xFF, 0x98, 0x01, 0x77, 0x01, + 0x59, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0F, 0x00, 0x00, 0xFF, 0xC2, 0x01, 0x21, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0E, + 0xFF, 0xD1, 0x00, 0x7D, 0x00, 0xCD, 0x00, 0x00, 0x04, 0x64, 0x00, 0x0C, 0xFF, 0xC6, 0xFF, 0xEF, 0x00, 0xC7, 0x00, + 0x00, 0x04, 0x64, 0x00, 0x07, 0x00, 0x10, 0x00, 0x35, 0x00, 0xD3, 0x00, 0x00, 0x04, 0x64, 0x00, 0x03, 0xFF, 0xE1, + 0x00, 0x3F, 0x02, 0x6F, 0x00, 0x00, 0x04, 0x64, 0x00, 0x03, 0xFE, 0xAB, 0x01, 0xD0, 0x02, 0x1E, 0x00, 0x00, 0x04, + 0x64, 0x00, 0x03, 0xFE, 0xAB, 0x01, 0xD0, 0x02, 0x1E, 0x00, 0x00, 0x04, 0x64, 0x00, 0x88, 0xFE, 0xAB, 0x01, 0xD0, + 0x02, 0x1E, 0x00, 0x00, 0x04, 0x64, 0x00, 0x6C, 0xFE, 0xAD, 0x01, 0xCE, 0x02, 0x1C, 0x00, 0x00, 0x00, 0x0F, 0x00, + 0x0A, 0x00, 0x46, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0A, 0x00, 0x46, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0A, 0x00, 0x46, + 0x00, 0x00, 0x00, 0x0A, 0x00, 0x02, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x0A, 0xFF, 0xEC, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x06, 0x00, 0x2F, 0x00, 0x00, 0x00, 0x05, 0xFF, 0xFB, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xDC, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xD8, 0x00, 0x78, 0x00, + 0x00, 0x00, 0x02, 0xFF, 0xC4, 0x00, 0x78, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xBA, 0x00, 0x82, 0x00, 0x00, 0x00, 0x02, + 0xFF, 0xB0, 0x00, 0x8C, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x04, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90730.s") +TexturePtr D_80A9402C[] = { + NULL, + gameplay_keep_Tex_05B6F0, + gameplay_keep_Tex_05CEF0, + gameplay_keep_Tex_0607C0, + gameplay_keep_Tex_060FC0, + gameplay_keep_Tex_061FC0, + gameplay_keep_Tex_061FE0, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90C08.s") +Color_RGB8 D_80A94048 = { 230, 230, 220 }; +Color_RGB8 D_80A9404C = { 120, 120, 100 }; +Color_RGB8 D_80A94050 = { 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90C34.s") +s16 D_80A94054 = 500; +s16 D_80A94058 = 1500; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90C54.s") +Vec3f D_80A9405C = { 0.0f, 1.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90D20.s") +Color_RGB8 D_80A94068 = { 225, 230, 225 }; +Color_RGB8 D_80A9406C = { 120, 120, 100 }; +Color_RGB8 D_80A94070 = { 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90D34.s") +s16 D_80A94074 = 940; +s16 D_80A94078 = 2000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A90FC0.s") +void func_80A90730(EnTest6* this, GlobalContext* globalCtx) { + s32 i; + Player* player = GET_PLAYER(globalCtx); + s32 phi_s0; + f32 phi_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/EnTest6_SetupAction.s") + this->actor.home.pos = player->actor.world.pos; + this->actor.home.rot = player->actor.shape.rot; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/EnTest6_Init.s") + switch (ENTEST6_GET(&this->actor)) { + case ENTEST6_24: + case ENTEST6_25: + func_80A91690(this, globalCtx); + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + return; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/EnTest6_Destroy.s") + case ENTEST6_26: + func_80A920C8(this, globalCtx); + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A9156C.s") + phi_s0 = 0; + phi_f24 = -900.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A91690.s") + if (gSaveContext.eventInf[7] & 1) { + for (i = 0; i < 6; i++) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 5; + } + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 5; + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 6; + phi_s0 |= 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A916F0.s") + if (gSaveContext.eventInf[7] & 0x10) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 1; + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 1; + if (!(phi_s0 & 1)) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 1; + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 1; + } + phi_s0 |= 0x10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A91760.s") + if (gSaveContext.eventInf[7] & 2) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 2; + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 2; + if (!(phi_s0 & 1)) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 2; + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 2; + } + phi_s0 |= 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A920C8.s") + if (gSaveContext.eventInf[7] & 4) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 3; + if (!(phi_s0 & (0x10 | 0x2 | 0x1))) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 3; + } + phi_s0 |= 4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A92118.s") + if (gSaveContext.eventInf[7] & 8) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 4; + if (!(phi_s0 & (0x10 | 0x2 | 0x1))) { + D_80A94910[(s32)(Rand_ZeroOne() * ARRAY_COUNT(D_80A94910))].unk_00 = 4; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A92188.s") + for (i = 0; i < ARRAY_COUNT(D_80A94910); i++) { + D_80A94910[i].unk_08 = ((2.0f * Rand_ZeroOne()) - 1.0f) * 80.0f; + D_80A94910[i].unk_10 = ((2.0f * Rand_ZeroOne()) - 1.0f) * 80.0f; + D_80A94910[i].unk_0C = (((2.0f * Rand_ZeroOne()) - 1.0f) * 40.0f) + phi_f24; + D_80A94910[i].unk_04 = -10.0f; + if (D_80A94910[i].unk_00 < 5) { + D_80A94910[i].unk_14 = func_80A90D34; + } else { + D_80A94910[i].unk_14 = func_80A90FC0; + } + phi_f24 += 50.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/EnTest6_Update.s") +void func_80A90C08(s16 arg0) { + func_8016566C(arg0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A92950.s") +void func_80A90C34(void) { + func_80165690(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A93298.s") +void func_80A90C54(GlobalContext* globalCtx, f32 arg1) { + globalCtx->envCtx.fillScreen = 1; + globalCtx->envCtx.screenFillColor[0] = 250; + globalCtx->envCtx.screenFillColor[1] = 250; + globalCtx->envCtx.screenFillColor[2] = 250; + globalCtx->envCtx.screenFillColor[3] = 255.0f * arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A9369C.s") +void func_80A90D20(GlobalContext* globalCtx) { + globalCtx->envCtx.fillScreen = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/func_80A939E8.s") +void func_80A90D34(EnTest6* this, GlobalContext* globalCtx, EnTest6Struct* ptr) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test6/EnTest6_Draw.s") + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (ptr->unk_00 != 0) { + Matrix_Translate(ptr->unk_08 * ptr->unk_04, ptr->unk_0C, ptr->unk_10 * ptr->unk_04, MTXMODE_NEW); + Matrix_Scale(ptr->unk_04 * 0.02f, ptr->unk_04 * 0.02f, ptr->unk_04 * 0.02f, MTXMODE_APPLY); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A9402C[ptr->unk_00])); + 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); + } + + Matrix_Translate(ptr->unk_08 * ptr->unk_04, ptr->unk_0C, ptr->unk_10 * ptr->unk_04, MTXMODE_NEW); + Matrix_Scale(2.0f * ptr->unk_04, 2.0f * ptr->unk_04, 2.0f * ptr->unk_04, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(globalCtx->state.frames * 512, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 2.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); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 210, 210, 230, 128); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 0); + gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A90FC0(EnTest6* this, GlobalContext* globalCtx, EnTest6Struct* ptr) { + s32 pad; + Gfx* gfx = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 2); + Gfx* gfx2 = gfx; + Hilite* sp70; + Vec3f sp64; + + sp64.x = ptr->unk_08 * ptr->unk_04; + sp64.y = ptr->unk_0C; + sp64.z = ptr->unk_10 * ptr->unk_04; + + sp70 = func_800BCBF4(&sp64, globalCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (gfx != NULL) { + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetTileSize(gfx++, 1, sp70->h.x1 & 0xFFFF, sp70->h.y1 & 0xFFFF, (sp70->h.x1 + 60) & 0xFFFF, + (sp70->h.y1 + 60) & 0xFFFF); + gSPEndDisplayList(gfx); + + gSPSegment(POLY_OPA_DISP++, 0x07, gfx2); + + Matrix_Translate(sp64.x, sp64.y, sp64.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_04 * 0.018f, ptr->unk_04 * 0.018f, ptr->unk_04 * 0.018f, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A9402C[ptr->unk_00])); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0622C0); + } + + Matrix_Translate(ptr->unk_08 * ptr->unk_04, ptr->unk_0C, ptr->unk_10 * ptr->unk_04, MTXMODE_NEW); + Matrix_Scale(ptr->unk_04 * 2.5f, ptr->unk_04 * 2.5f, ptr->unk_04 * 2.5f, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(globalCtx->state.frames * 256, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 4.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); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 220, 220, 230, 192); + gDPSetEnvColor(POLY_XLU_DISP++, 128, 128, 128, 0); + gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + gSPDisplayList(POLY_XLU_DISP++, gEffSparklesDL); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnTest6_SetupAction(EnTest6* this, EnTest6ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} + +void EnTest6_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTest6* this = THIS; + s32 i; + + if (((ENTEST6_GET(&this->actor) == ENTEST6_24) || (ENTEST6_GET(&this->actor) == ENTEST6_25) || + (ENTEST6_GET(&this->actor) == ENTEST6_26)) && + (globalCtx->playerActorCsIds[8] == -1)) { + Actor_MarkForDeath(&this->actor); + return; + } + + for (i = 0; i < ARRAY_COUNT(this->lights); i++) { + Lights_PointNoGlowSetInfo(&this->lights[i].info, this->actor.world.pos.x, (s32)this->actor.world.pos.y - 20, + this->actor.world.pos.z, 255, 255, 180, -1); + this->lights[i].node = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lights[i].info); + } + + this->unk_286 = 0; + this->unk_274 = 0; + this->unk_278 = 0; + this->unk_276 = 99; + func_80A90730(this, globalCtx); + EnTest6_SetupAction(this, func_80A9156C); +} + +void EnTest6_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTest6* this = THIS; + s32 i; + + globalCtx->envCtx.lightSettings.ambientColor[0] = 0; + globalCtx->envCtx.lightSettings.ambientColor[1] = 0; + globalCtx->envCtx.lightSettings.ambientColor[2] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[0] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[1] = 0; + globalCtx->envCtx.lightSettings.diffuseColor1[2] = 0; + globalCtx->envCtx.lightSettings.diffuseColor2[0] = 0; + globalCtx->envCtx.lightSettings.diffuseColor2[1] = 0; + globalCtx->envCtx.lightSettings.diffuseColor2[2] = 0; + globalCtx->envCtx.lightSettings.fogColor[0] = 0; + globalCtx->envCtx.lightSettings.fogColor[1] = 0; + globalCtx->envCtx.lightSettings.fogColor[2] = 0; + globalCtx->envCtx.lightSettings.fogNear = 0; + globalCtx->envCtx.lightSettings.fogFar = 0; + globalCtx->envCtx.fillScreen = 0; + + for (i = 0; i < ARRAY_COUNT(this->lights); i++) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lights[i].node); + } +} + +void func_80A9156C(EnTest6* this, GlobalContext* globalCtx) { + switch (ENTEST6_GET(&this->actor)) { + case ENTEST6_24: + case ENTEST6_25: + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[8])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[8], NULL); + this->unk_284 = ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8]); + EnTest6_SetupAction(this, func_80A91760); + } + break; + + case ENTEST6_26: + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[8])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[8], NULL); + this->unk_284 = ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8]); + EnTest6_SetupAction(this, func_80A92188); + } + break; + + default: + gSaveContext.save.daysElapsed = 0; + gSaveContext.save.day = false; + gSaveContext.save.time = CLOCK_TIME(6, 0) - 1; + EnTest6_SetupAction(this, func_80A92950); + break; + } +} + +void func_80A91690(EnTest6* this, GlobalContext* globalCtx) { + this->unk_274 = 90; + this->unk_27A = 100; + this->unk_286 = 0; + if (ENTEST6_GET(&this->actor) == ENTEST6_25) { + play_sound(NA_SE_SY_TIME_CONTROL_SLOW); + } else if (ENTEST6_GET(&this->actor) == ENTEST6_24) { + play_sound(NA_SE_SY_TIME_CONTROL_NORMAL); + } +} + +void func_80A916F0(EnTest6* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.freezeTimer = 0; + globalCtx->unk_18844 = 0; + ActorCutscene_Stop(globalCtx->playerActorCsIds[8]); + func_800B7298(globalCtx, NULL, 6); + func_80A90C34(); + Distortion_ClearType(0x20); + Actor_MarkForDeath(&this->actor); +} + +void func_80A91760(EnTest6* this, GlobalContext* globalCtx) { + Input* input = CONTROLLER1(globalCtx); + s16 temp_s0; + Player* player = GET_PLAYER(globalCtx); + Camera* sp78; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + s32 i; + f32 sp4C; + Camera* temp_s3 = Play_GetCamera(globalCtx, this->unk_284); + + sp78 = Play_GetCamera(globalCtx, CAM_ID_MAIN); + + switch (this->unk_274) { + case 90: + this->unk_276 = 2; + this->unk_15C = 0.0f; + this->unk_14C = 0.1f; + this->unk_282 = 0; + this->unk_278 = 0; + this->unk_274 = 91; + break; + + case 91: + this->unk_15C += this->unk_14C; + func_800FD59C(globalCtx, &D_80A9404C, this->unk_15C); + func_800FD5E0(globalCtx, &D_80A94050, this->unk_15C); + func_800FD654(globalCtx, &D_80A94048, this->unk_15C); + func_800FD698(globalCtx, D_80A94054, D_80A94058, this->unk_15C); + + if (this->unk_27A == 90) { + this->unk_282 = 0; + if (ENTEST6_GET(&this->actor) == ENTEST6_24) { + this->unk_27C = 0x200; + this->unk_150 = 0.0f; + sp4C = -100.0f; + } else { + this->unk_27C = 0x570; + this->unk_150 = 110.0f; + sp4C = 100.0f; + } + this->unk_14C = 1.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_20C); i++) { + this->unk_20C[i].x = player->actor.world.pos.x; + this->unk_20C[i].y = player->actor.world.pos.y; + this->unk_20C[i].z = player->actor.world.pos.z; + } + + this->unk_254 = ZeldaArena_Malloc(sizeof(Vec3f) * 64); + if (this->unk_254 != NULL) { + for (i = 0; i < ARRAY_COUNT(this->unk_254[0]); i++) { + (*this->unk_254)[i].x = (((2.0f * Rand_ZeroOne()) - 1.0f) * 40.0f) + temp_s3->eye.x + + ((temp_s3->at.x - temp_s3->eye.x) * 0.2f); + (*this->unk_254)[i].y = (((2.0f * Rand_ZeroOne()) - 1.0f) * 120.0f) + temp_s3->eye.y + + ((temp_s3->at.y - temp_s3->eye.y) * 0.2f) + sp4C; + (*this->unk_254)[i].z = (((2.0f * Rand_ZeroOne()) - 1.0f) * 40.0f) + temp_s3->eye.z + + ((temp_s3->at.z - temp_s3->eye.z) * 0.2f); + } + } + func_80A90C08(0x78); + Distortion_SetType(0x20); + Distortion_SetCountdown(80); + globalCtx->unk_18844 = 1; + this->unk_274 = 95; + } + break; + + case 95: + if (this->unk_27A > 80) { + this->unk_282 += 25; + } + + if (this->unk_27A < 20) { + this->unk_282 -= 25; + } + + func_800FD59C(globalCtx, &D_80A9404C, this->unk_15C); + func_800FD5E0(globalCtx, &D_80A94050, this->unk_15C); + func_800FD654(globalCtx, &D_80A94048, this->unk_15C); + func_800FD698(globalCtx, D_80A94054 + this->unk_282, D_80A94058 + this->unk_282, this->unk_15C); + + this->unk_278 -= this->unk_27C; + temp_s0 = this->unk_278; + if (ENTEST6_GET(&this->actor) == ENTEST6_24) { + this->unk_27C += 8; + this->unk_150 += this->unk_14C; + } else { + this->unk_27C -= 8; + this->unk_150 -= this->unk_14C; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_20C); i++) { + temp_s0 += 0x10000 / ARRAY_COUNT(this->unk_20C); + if (player) {} + this->unk_20C[i].x = (Math_SinS(temp_s0) * this->unk_150) + player->actor.world.pos.x; + this->unk_20C[i].y = player->actor.world.pos.y; + this->unk_20C[i].z = (Math_CosS(temp_s0) * this->unk_150) + player->actor.world.pos.z; + } + + if (this->unk_254 != NULL) { + for (i = 0; i < ARRAY_COUNT(this->unk_254[0]); i++) { + (*this->unk_254)[i].x += 2.0f * ((2.0f * Rand_ZeroOne()) - 1.0f); + if (ENTEST6_GET(&this->actor) == ENTEST6_24) { + (*this->unk_254)[i].y += 1.0f; + } else { + if (1) {} + (*this->unk_254)[i].y -= 1.0f; + } + (*this->unk_254)[i].z += 2.0f * ((2.0f * Rand_ZeroOne()) - 1.0f); + } + } + + if (this->unk_27A == 10) { + this->unk_14C = 0.1f; + func_80A90C34(); + Distortion_ClearType(0x20); + globalCtx->unk_18844 = 0; + if (this->unk_254 != NULL) { + ZeldaArena_Free(this->unk_254); + } + this->unk_274 = 99; + } + break; + + case 99: + this->unk_15C -= this->unk_14C; + func_800FD59C(globalCtx, &D_80A9404C, this->unk_15C); + func_800FD5E0(globalCtx, &D_80A94050, this->unk_15C); + func_800FD654(globalCtx, &D_80A94048, this->unk_15C); + func_800FD698(globalCtx, D_80A94054, D_80A94058, this->unk_15C); + break; + } + + if (this->unk_286 != 0) { + func_800B7298(globalCtx, NULL, 7); + } else { + if (this->unk_27A == 90) { + func_800B7298(globalCtx, NULL, 0x42); + } + + if (this->unk_27A == 70) { + func_800B7298(globalCtx, NULL, 0x52); + } + + if (this->unk_27A == 30) { + func_800B7298(globalCtx, NULL, 0x51); + } + + if (this->unk_27A == 5) { + func_800B7298(globalCtx, NULL, 0x4A); + } + } + + if (this->unk_27A > 80) { + temp_s3->fov += (90.0f - temp_s3->fov) / (this->unk_27A - 80); + } else if (this->unk_27A > 60) { + sp4C = 1.0f / (this->unk_27A - 60); + + sp6C.x = temp_s3->at.x + ((player->actor.world.pos.x - temp_s3->at.x) * sp4C); + sp6C.y = temp_s3->at.y + (((player->actor.focus.pos.y - temp_s3->at.y) - 20.0f) * sp4C); + sp6C.z = temp_s3->at.z + ((player->actor.world.pos.z - temp_s3->at.z) * sp4C); + + sp54.x = (Math_SinS(player->actor.world.rot.y) * 80.0f) + sp6C.x; + sp54.y = sp6C.y + 20.0f; + sp54.z = (Math_CosS(player->actor.world.rot.y) * 80.0f) + sp6C.z; + sp4C *= 0.75f; + + VEC3F_LERPIMPDST(&sp60, &temp_s3->eye, &sp54, sp4C); + + Play_CameraSetAtEye(globalCtx, this->unk_284, &sp6C, &sp60); + } else if ((this->unk_27A < 11) && (this->unk_27A > 0)) { + temp_s3->fov += (sp78->fov - temp_s3->fov) / this->unk_27A; + } + + if (this->unk_286 != 0) { + func_80A90C54(globalCtx, this->unk_286 * 0.05f); + temp_s3->fov += (sp78->fov - temp_s3->fov) * 0.05f; + this->unk_286++; + if (this->unk_286 >= 20) { + this->unk_27A = 1; + } + } else if ((this->unk_27A <= 60) && (this->unk_27A > 40) && + (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_B))) { + this->unk_286 = 1; + if (ENTEST6_GET(&this->actor) == ENTEST6_25) { + func_801A75E8(NA_SE_SY_TIME_CONTROL_SLOW); + } else if (ENTEST6_GET(&this->actor) == ENTEST6_24) { + func_801A75E8(NA_SE_SY_TIME_CONTROL_NORMAL); + } + } + + if (DECR(this->unk_27A) == 0) { + func_80A916F0(this, globalCtx); + globalCtx->msgCtx.ocarinaMode = 4; + } +} + +void func_80A920C8(EnTest6* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_27A = 120; + this->unk_286 = 0; + this->unk_160 = 0.0f; + this->actor.home.pos = player->actor.world.pos; + this->actor.home.rot = player->actor.shape.rot; +} + +void func_80A92118(EnTest6* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.freezeTimer = 0; + globalCtx->unk_18844 = 0; + ActorCutscene_Stop(globalCtx->playerActorCsIds[8]); + func_800B7298(globalCtx, NULL, 6); + func_80A90C34(); + Distortion_ClearType(0x20); + Actor_MarkForDeath(&this->actor); +} + +void func_80A92188(EnTest6* this, GlobalContext* globalCtx) { + Input* input = CONTROLLER1(globalCtx); + Player* player = GET_PLAYER(globalCtx); + Camera* camera; + s32 pad; + s16 sp46; + s16 sp44; + + if (this->unk_27A > 115) { + this->unk_160 += 0.2f; + func_80A90C54(globalCtx, this->unk_160); + } else if (this->unk_27A > 90) { + this->unk_160 -= 0.05f; + func_80A90C54(globalCtx, this->unk_160); + } else if (this->unk_27A == 90) { + this->unk_160 = 0.0f; + func_80A90D20(globalCtx); + } + + if (this->unk_27A == 1) { + this->unk_160 = 0.0f; + func_80A90D20(globalCtx); + } else if (this->unk_27A < 17) { + this->unk_160 -= 0.06666666f; + func_80A90C54(globalCtx, this->unk_160); + } else if (this->unk_27A < 22) { + this->unk_160 += 0.2f; + func_80A90C54(globalCtx, this->unk_160); + } + + if (this->unk_27A == 115) { + func_800FD59C(globalCtx, &D_80A9406C, 1.0f); + func_800FD5E0(globalCtx, &D_80A94070, 1.0f); + func_800FD654(globalCtx, &D_80A94068, 1.0f); + func_800FD698(globalCtx, D_80A94074, D_80A94078, 1.0f); + globalCtx->unk_18844 = 1; + } + + if (this->unk_27A == 15) { + func_800FD59C(globalCtx, &D_80A9406C, 0.0f); + func_800FD5E0(globalCtx, &D_80A94070, 0.0f); + func_800FD654(globalCtx, &D_80A94068, 0.0f); + func_800FD698(globalCtx, D_80A94074, D_80A94078, 0.0f); + globalCtx->unk_18844 = 0; + } + + if (this->unk_286 >= 20) { + func_800FD59C(globalCtx, &D_80A9406C, this->unk_160); + func_800FD5E0(globalCtx, &D_80A94070, this->unk_160); + func_800FD654(globalCtx, &D_80A94068, this->unk_160); + func_800FD698(globalCtx, D_80A94074, D_80A94078, this->unk_160); + globalCtx->unk_18844 = 0; + } + + func_800B8F98(&player->actor, NA_SE_PL_FLYING_AIR - SFX_FLAG); + + switch (this->unk_27A) { + case 119: + func_80A90C08(0x32); + break; + + case 115: + func_80A90C08(0x14); + Distortion_SetType(0x20); + Distortion_SetCountdown(90); + this->unk_274 = 2; + break; + + case 110: + func_801A3098(0x4A); + break; + + case 38: + case 114: + this->unk_274 = 1; + break; + + case 76: + this->unk_274 = 3; + break; + + case 61: + func_80A90C08(0x96); + this->unk_274 = 4; + break; + + case 51: + func_80A90C08(0xB4); + this->unk_274 = 5; + break; + + case 14: + case 15: + func_80A90C08(0x32); + Distortion_ClearType(0x20); + this->unk_274 = 0; + break; + + case 1: + func_80A90C34(); + if (gSaveContext.eventInf[5] & 4) { + this->unk_274 = 9; + } + break; + } + + func_80A92950(this, globalCtx); + + if (this->unk_27A == 115) { + sp44 = ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8]); + camera = Play_GetCamera(globalCtx, sp44); + + this->unk_258 = camera->at; + this->unk_264 = camera->eye; + this->unk_270 = camera->fov; + func_8016119C(camera, &this->unk_18C); + } + + if ((this->unk_27A <= 115) && (this->unk_27A >= 16)) { + func_80161998(D_80A93E80, &this->unk_18C); + } else if (this->unk_27A < 16) { + sp46 = ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8]); + + Play_CameraSetAtEyeUp(globalCtx, sp46, &this->unk_258, &this->unk_264, &D_80A9405C); + Play_CameraSetFov(globalCtx, sp46, this->unk_270); + Play_CameraSetRoll(globalCtx, sp46, 0); + } + + switch (this->unk_27A) { + case 116: + player->actor.freezeTimer = 2; + player->actor.shape.rot.x = 0; + player->actor.shape.rot.y = 0; + player->actor.world.pos.x = 0.0f; + player->actor.world.pos.y = 0.0f; + player->actor.world.pos.z = 0.0f; + player->actor.home.pos.x = 0.0f; + player->actor.home.pos.y = 0.0f; + player->actor.home.pos.z = 0.0f; + break; + + case 98: + func_800B7298(globalCtx, NULL, 0x40); + break; + + case 68: + func_800B7298(globalCtx, NULL, 0x41); + break; + + case 52: + func_800B7298(globalCtx, NULL, 0x58); + break; + + case 43: + func_800B7298(globalCtx, NULL, 0x72); + break; + + case 38: + func_800B7298(globalCtx, NULL, 7); + break; + + case 14: + player->actor.freezeTimer = 5; + player->actor.world.pos = player->actor.home.pos = this->actor.home.pos; + player->actor.shape.rot = this->actor.home.rot; + player->actor.focus.rot.y = player->actor.shape.rot.y; + player->currentYaw = player->actor.shape.rot.y; + player->unk_ABC = 0.0f; + player->unk_AC0 = 0.0f; + player->actor.shape.yOffset = 0.0f; + break; + } + + if ((this->unk_286 > 0) && (this->unk_286 < 20)) { + func_80A90C54(globalCtx, this->unk_286 * 0.05f); + this->unk_286++; + if (this->unk_286 >= 20) { + this->unk_27A = 15; + this->unk_160 = 0.9333333f; + } + } else if ((this->unk_27A < 96) && (this->unk_27A > 50) && + (CHECK_BTN_ALL(input->press.button, BTN_A) || CHECK_BTN_ALL(input->press.button, BTN_B))) { + this->unk_286 = 1; + this->unk_27A = 39; + Audio_QueueSeqCmd(0x111400FF); + } + + if (DECR(this->unk_27A) == 0) { + func_80A92118(this, globalCtx); + } +} + +void EnTest6_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTest6* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void func_80A92950(EnTest6* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player = GET_PLAYER(globalCtx); + f32 temp_f0; + s32 i; + s32 temp_v0; + + if (Cutscene_CheckActorAction(globalCtx, 0x1F9)) { + temp_v0 = Cutscene_GetActorActionIndex(globalCtx, 0x1F9); + this->unk_274 = globalCtx->csCtx.actorActions[temp_v0]->action; + + switch (this->unk_274) { + case 1: + break; + + case 2: + this->unk_276 = 0; + this->unk_278 = 0; + this->unk_27C = 0; + player->actor.shape.shadowDraw = NULL; + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_154 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } else { + this->unk_154 = 150.0f; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.y != 0) { + this->unk_280 = globalCtx->csCtx.actorActions[temp_v0]->startPos.y; + } else { + this->unk_280 = 38; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.z != 0) { + this->unk_150 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.z; + } else { + this->unk_150 = 480.0f; + } + break; + + case 3: + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_154 += (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.y != 0) { + this->unk_280 += (s16)globalCtx->csCtx.actorActions[temp_v0]->startPos.y; + + } else { + this->unk_280 += 6; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.z != 0) { + this->unk_158 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.z; + } else { + this->unk_158 = -32.0f; + } + this->unk_150 += this->unk_158; + break; + + case 4: + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_154 += (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.y != 0) { + this->unk_280 += (s16)globalCtx->csCtx.actorActions[temp_v0]->startPos.y; + } else { + this->unk_280 -= 4; + } + break; + + case 5: + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_154 += (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.y != 0) { + this->unk_280 += (s16)globalCtx->csCtx.actorActions[temp_v0]->startPos.y; + } else { + this->unk_280 -= 8; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.z != 0) { + this->unk_158 += (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.z; + } else { + this->unk_158 += 20.0f; + } + + this->unk_150 += this->unk_158; + if (this->unk_150 > 3500.0f) { + this->unk_150 = 3500.0f; + this->unk_274 = 0; + } + break; + + case 6: + this->unk_276 = 1; + this->unk_278 = 0; + this->unk_27C = 0; + player->actor.shape.shadowDraw = NULL; + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_154 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } else { + this->unk_154 = 100.0f; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.y != 0) { + this->unk_14C = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.y; + } else { + this->unk_14C = 20.0f; + } + + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.z != 0) { + this->unk_150 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.z; + } else { + this->unk_150 = 300.0f; + } + this->unk_158 = 0.0f; + break; + + case 7: + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_158 = (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } else { + this->unk_158 = -5.0f; + } + this->unk_154 += this->unk_158; + break; + + case 8: + if (globalCtx->csCtx.actorActions[temp_v0]->startPos.x != 0) { + this->unk_158 += (u32)globalCtx->csCtx.actorActions[temp_v0]->startPos.x; + } else { + this->unk_158 += 2.0f; + } + + this->unk_154 += this->unk_158; + if (this->unk_154 > 10000.0f) { + this->unk_154 = 10000.0f; + this->unk_274 = 0; + } + break; + + case 0: + default: + this->unk_276 = 99; + return; + + case 9: + Play_SetRespawnData(&globalCtx->state, 1, ((void)0, gSaveContext.save.entranceIndex & 0xFFFF), + player->unk_3CE, 0xBFF, &player->unk_3C0, player->unk_3CC); + this->unk_276 = 99; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->nextEntranceIndex = gSaveContext.respawn[RESTART_MODE_RETURN].entranceIndex; + globalCtx->unk_1887F = 2; + if ((gSaveContext.save.time > CLOCK_TIME(18, 0)) || (gSaveContext.save.time < CLOCK_TIME(6, 0))) { + gSaveContext.respawnFlag = -0x63; + gSaveContext.eventInf[2] |= 0x80; + } else { + gSaveContext.respawnFlag = 2; + } + globalCtx->msgCtx.ocarinaMode = 4; + return; + } + } else { + switch (this->unk_274) { + case 2: + this->unk_276 = 0; + this->unk_278 = 0; + this->unk_27C = 0; + player->actor.shape.shadowDraw = NULL; + this->unk_280 = 38; + this->unk_154 = 150.0f; + this->unk_150 = 480.0f; + + case 1: + break; + + case 3: + this->unk_158 = -32.0f; + this->unk_280 += 6; + this->unk_150 += -32.0f; + break; + + case 4: + this->unk_280 -= 4; + break; + + case 5: + this->unk_280 -= 8; + this->unk_158 += 20.0f; + this->unk_150 += this->unk_158; + if (this->unk_150 > 3500.0f) { + this->unk_150 = 3500.0f; + this->unk_274 = 0; + } + break; + + case 6: + this->unk_276 = 1; + this->unk_278 = 0; + this->unk_27C = 0; + player->actor.shape.shadowDraw = NULL; + this->unk_154 = 100.0f; + this->unk_14C = 20.0f; + this->unk_150 = 300.0f; + this->unk_158 = 0.0f; + break; + + case 7: + this->unk_158 = -5.0f; + this->unk_154 += -5.0f; + break; + + case 8: + this->unk_158 += 2.0f; + this->unk_154 += this->unk_158; + if (this->unk_154 > 10000.0f) { + this->unk_154 = 10000.0f; + this->unk_274 = 0; + } + break; + + case 0: + default: + this->unk_276 = 99; + return; + + case 9: + if (gSaveContext.save.time > CLOCK_TIME(12, 0)) { + Play_SetRespawnData(&globalCtx->state, 1, ((void)0, gSaveContext.save.entranceIndex & 0xFFFF), + player->unk_3CE, 0xBFF, &player->unk_3C0, player->unk_3CC); + this->unk_276 = 99; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->nextEntranceIndex = gSaveContext.respawn[RESTART_MODE_RETURN].entranceIndex; + globalCtx->unk_1887F = 2; + gSaveContext.respawnFlag = 2; + globalCtx->msgCtx.ocarinaMode = 4; + } + return; + } + } + + if (this->unk_276 == 1) { + for (i = 0; i < ARRAY_COUNT(D_80A94910); i++) { + D_80A94910[i].unk_08 += 2.0f * ((2.0f * Rand_ZeroOne()) - 1.0f); + D_80A94910[i].unk_10 += 2.0f * ((2.0f * Rand_ZeroOne()) - 1.0f); + D_80A94910[i].unk_0C += 3.0f; + + if (player->actor.world.pos.y < D_80A94910[i].unk_0C) { + temp_f0 = D_80A94910[i].unk_0C - player->actor.world.pos.y; + if (temp_f0 > 550.0f) { + temp_f0 = 1.0f; + } else { + temp_f0 = temp_f0 / 550.0f; + } + D_80A94910[i].unk_04 = SQ(temp_f0); + } else { + D_80A94910[i].unk_04 = -10.0f; + } + } + } + this->unk_278++; +} + +void func_80A93298(EnTest6* this, GlobalContext* globalCtx) { + s16 temp_s3; + s16 temp_s4; + f32 phi_f24; + s16 phi_s2; + s32 i; + f32 cos; + f32 sin; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + this->unk_148 = POLY_OPA_DISP; + phi_f24 = 0.0f; + + temp_s3 = this->unk_27C; + temp_s4 = (s32)(Math_SinS(globalCtx->state.frames) * 12000.0f) + temp_s3 + 0x4E20; + phi_s2 = (globalCtx->state.frames & 0x3C) * 1024; + phi_s2 *= (this->unk_154 / 200.0f); + this->unk_27C += (s16)this->unk_154; + this->unk_27E = (s16)((this->unk_154 / 200.0f) * 256.0f); + + for (i = 0; i < ARRAY_COUNT(this->unk_254[0]); i++) { + temp_s3 += 0x1000; + cos = Math_CosS(temp_s3) * this->unk_150; + sin = Math_SinS(temp_s3) * this->unk_150; + Matrix_Translate(cos, phi_f24, sin, MTXMODE_NEW); + Matrix_RotateXS(0x4000, MTXMODE_APPLY); + Matrix_Scale(0.8f, 0.8f, 0.8f, MTXMODE_APPLY); + Matrix_RotateZS(phi_s2, MTXMODE_APPLY); + + gSPMatrix(this->unk_148++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(this->unk_148++, 0, 0xFF, 28, 28, 28, 255); + gDPSetEnvColor(this->unk_148++, 255, 255, 255, 255); + gDPSetRenderMode(this->unk_148++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPDisplayList(this->unk_148++, gameplay_keep_DL_07AFB0); + + temp_s4 += 0x1000; + cos = Math_CosS(temp_s4) * this->unk_150; + sin = Math_SinS(temp_s4) * this->unk_150; + Matrix_Translate(cos, phi_f24, sin, MTXMODE_NEW); + Matrix_RotateXS(0x4000, MTXMODE_APPLY); + Matrix_Scale(0.8f, 0.8f, 0.8f, MTXMODE_APPLY); + Matrix_RotateZS(-phi_s2, MTXMODE_APPLY); + + gSPMatrix(this->unk_148++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(this->unk_148++, 0, 0xFF, 28, 28, 28, 255); + gDPSetEnvColor(this->unk_148++, 255, 255, 255, 255); + gDPSetRenderMode(this->unk_148++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPDisplayList(this->unk_148++, gameplay_keep_DL_07AFB0); + + phi_f24 -= this->unk_14C; + phi_s2 += this->unk_27E; + } + + POLY_OPA_DISP = this->unk_148; + + for (i = 0; i < ARRAY_COUNT(D_80A94910); i++) { + if (D_80A94910[i].unk_04 > 0.0f) { + D_80A94910[i].unk_14(this, globalCtx, &D_80A94910[i]); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A9369C(Actor* thisx, GlobalContext* globalCtx2) { + EnTest6* this = THIS; + GlobalContext* globalCtx = globalCtx2; + f32 temp_f20; + f32 temp_f22; + f32 phi_f26; + s16 phi_s2; + s16 sp78; + s32 i; + Player* player = GET_PLAYER(globalCtx); + s32 pad; + + if (this) {} + OPEN_DISPS(globalCtx->state.gfxCtx); + + this->unk_148 = POLY_OPA_DISP; + this->unk_27C += (s16)this->unk_154; + this->unk_27E = this->unk_27C * 2; + sp78 = (globalCtx->state.frames & 0x3C) * 1024; + phi_s2 = this->unk_27C + 0x4000; + + switch (player->transformation) { + default: + phi_f26 = player->actor.world.pos.y + 40.0f; + break; + + case PLAYER_FORM_DEKU: + phi_f26 = player->actor.world.pos.y + 40.0f; + break; + + case PLAYER_FORM_GORON: + phi_f26 = player->actor.world.pos.y + 40.0f; + break; + + case PLAYER_FORM_ZORA: + phi_f26 = player->actor.world.pos.y + 40.0f; + break; + + case PLAYER_FORM_FIERCE_DEITY: + phi_f26 = player->actor.world.pos.y + 40.0f; + break; + } + + for (i = 0; i < 51; i++) { + temp_f20 = Math_CosS(phi_s2) * this->unk_150; + temp_f22 = Math_SinS(phi_s2) * this->unk_150; + Matrix_RotateZS(this->unk_27E, MTXMODE_NEW); + Matrix_Translate(phi_f26, temp_f20, temp_f22, MTXMODE_APPLY); + Matrix_Scale(0.85f, 0.85f, 0.85f, MTXMODE_APPLY); + Matrix_RotateXS(phi_s2, MTXMODE_APPLY); + Matrix_RotateZS(sp78, MTXMODE_APPLY); + + gSPMatrix(this->unk_148++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(this->unk_148++, 0, 0xFF, this->unk_280, this->unk_280, this->unk_280, 255); + gDPSetEnvColor(this->unk_148++, 235, 238, 235, 255); + gDPSetRenderMode(this->unk_148++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPDisplayList(this->unk_148++, gameplay_keep_DL_07AFB0); + + phi_s2 += 0x505; + } + + Lights_PointSetPosition(&this->lights[0].info, player->actor.world.pos.x, player->actor.world.pos.y - 10.0f, + player->actor.world.pos.z); + Lights_PointSetColorAndRadius(&this->lights[0].info, 100, 250, 100, 200); + + POLY_OPA_DISP = this->unk_148; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A939E8(EnTest6* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + Player* player = GET_PLAYER(globalCtx); + f32 temp_f20; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + switch (this->unk_274) { + case 91: + case 93: + Lights_PointSetPosition(&this->lights[0].info, player->actor.world.pos.x, player->actor.world.pos.y - 10.0f, + player->actor.world.pos.z); + Lights_PointSetColorAndRadius(&this->lights[0].info, 245, 245, 200, this->unk_282); + break; + + case 95: + this->unk_148 = POLY_XLU_DISP; + + for (i = 0; i < ARRAY_COUNT(this->unk_20C); i++) { + Matrix_Translate(this->unk_20C[i].x, this->unk_20C[i].y, this->unk_20C[i].z, MTXMODE_NEW); + Matrix_Scale(0.3f, 0.3f, 0.3f, MTXMODE_APPLY); + Matrix_RotateXS(-0x4000, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_278, MTXMODE_APPLY); + + gSPMatrix(this->unk_148++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(this->unk_148++, 0, 0xFF, 28, 28, 28, 255); + gDPSetEnvColor(this->unk_148++, 245, 245, 200, this->unk_282); + gDPSetRenderMode(this->unk_148++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gSPDisplayList(this->unk_148++, gameplay_keep_DL_07AFB0); + + POLY_XLU_DISP = this->unk_148; + } + + if (this->unk_254 != NULL) { + for (i = 0; i < ARRAY_COUNT(this->unk_254[0]); i++) { + temp_f20 = Rand_ZeroOne() * 0.0025f; + Matrix_Translate((*this->unk_254)[i].x, (*this->unk_254)[i].y, (*this->unk_254)[i].z, MTXMODE_NEW); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 128, 128, 128, this->unk_282 >> 1); + gDPSetEnvColor(POLY_XLU_DISP++, 230, 230, 180, this->unk_282); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_278 + (i << 2), MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gOwlStatueWhiteFlashDL); + } + } + Lights_PointSetPosition(&this->lights[0].info, player->actor.world.pos.x, player->actor.world.pos.y - 10.0f, + player->actor.world.pos.z); + Lights_PointSetColorAndRadius(&this->lights[0].info, 250, 250, 100, this->unk_282); + break; + + case 90: + case 92: + case 94: + case 96: + case 97: + case 98: + case 99: + break; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnTest6_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTest6* this = THIS; + + if (this->unk_274 != 0) { + switch (this->unk_276) { + case 1: + func_80A93298(this, globalCtx); + break; + + case 0: + func_80A9369C(thisx, globalCtx); + break; + + case 2: + func_80A939E8(this, globalCtx); + break; + } + } +} 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..0c1aab3b0 100644 --- a/src/overlays/actors/ovl_En_Test6/z_en_test6.h +++ b/src/overlays/actors/ovl_En_Test6/z_en_test6.h @@ -7,10 +7,46 @@ struct EnTest6; typedef void (*EnTest6ActionFunc)(struct EnTest6*, GlobalContext*); +#define ENTEST6_GET(thisx) ((thisx)->params) + +enum { + /* 24 */ ENTEST6_24 = 24, + /* 25 */ ENTEST6_25, + /* 26 */ ENTEST6_26, +}; + +typedef struct { + /* 0x00 */ LightNode* node; + /* 0x04 */ LightInfo info; +} EnTest6Light; + typedef struct EnTest6 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTest6ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x140]; + /* 0x0148 */ Gfx* unk_148; + /* 0x014C */ f32 unk_14C; + /* 0x0150 */ f32 unk_150; + /* 0x0154 */ f32 unk_154; + /* 0x0158 */ f32 unk_158; + /* 0x015C */ f32 unk_15C; + /* 0x0160 */ f32 unk_160; + /* 0x0164 */ EnTest6Light lights[2]; + /* 0x018C */ DbCameraUnkStruct unk_18C; + /* 0x020C */ Vec3f unk_20C[6]; + /* 0x0254 */ Vec3f (*unk_254)[64]; + /* 0x0258 */ Vec3f unk_258; + /* 0x0264 */ Vec3f unk_264; + /* 0x0270 */ f32 unk_270; + /* 0x0274 */ s16 unk_274; + /* 0x0276 */ s16 unk_276; + /* 0x0278 */ s16 unk_278; + /* 0x027A */ s16 unk_27A; + /* 0x027C */ s16 unk_27C; + /* 0x027E */ s16 unk_27E; + /* 0x0280 */ s16 unk_280; + /* 0x0282 */ s16 unk_282; + /* 0x0284 */ s16 unk_284; + /* 0x0286 */ s16 unk_286; } 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 0e318e246..8aacf408d 100644 --- a/src/overlays/actors/ovl_En_Test7/z_en_test7.c +++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.c @@ -1,6 +1,13 @@ -#include "z_en_test7.h" +/* + * File: z_en_test7.c + * Overlay: ovl_En_Test7 + * Description: Soaring effects (wings, sphere, etc) + */ -#define FLAGS 0x02300030 +#include "z_en_test7.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_100000 | ACTOR_FLAG_200000 | ACTOR_FLAG_2000000) #define THIS ((EnTest7*)thisx) @@ -9,11 +16,24 @@ void EnTest7_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTest7_Update(Actor* thisx, GlobalContext* globalCtx); void EnTest7_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80AF2854(EnTest7* this, GlobalContext* globalCtx); - void EnTest7_SetupAction(EnTest7* this, EnTest7ActionFunc actionFunc); +void func_80AF19A8(EnTest7* this, GlobalContext* globalCtx); +void func_80AF1A2C(EnTest7* this, GlobalContext* globalCtx); +void func_80AF1CA0(EnTest7* this, GlobalContext* globalCtx); +void func_80AF1E44(EnTest7* this, GlobalContext* globalCtx); +void func_80AF1F48(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2030(EnTest7* this, GlobalContext* globalCtx); +void func_80AF21E8(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2318(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2350(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2854(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2938(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2AE8(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2C48(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2EC8(EnTest7* this, GlobalContext* globalCtx); +void func_80AF2F98(EnTest7* this, GlobalContext* globalCtx); +void func_80AF30F4(EnTest7* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Test7_InitVars = { ACTOR_EN_TEST7, ACTORCAT_ITEMACTION, @@ -26,80 +46,936 @@ const ActorInit En_Test7_InitVars = { (ActorFunc)EnTest7_Draw, }; -#endif +void EnTest7_SetupAction(EnTest7* this, EnTest7ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/EnTest7_SetupAction.s") +void func_80AF082C(EnTest7* this, EnTest7UnkFunc func) { + this->unk_1E58 = func; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF082C.s") +void func_80AF0838(EnTest7Struct2* arg0) { + EnTest7Struct2* ptr = arg0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF0838.s") + for (i = 0, ptr = arg0; i < 100; i++, ptr++) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF0984.s") + ptr->unk_00 = 0; + ptr->unk_04 = 0; + ptr->unk_08.x = 0.0f; + ptr->unk_08.y = 0.0f; + ptr->unk_08.z = 0.0f; + ptr->unk_14 = 0.0f; + ptr->unk_18 = 0.0f; + ptr->unk_1C = 0.0f; + ptr->unk_20 = 0.0f; + ptr->unk_24 = 0.0f; + ptr->unk_28 = 0.0f; + ptr->unk_2C = 0.00001f; + ptr->unk_30.x = 0; + ptr->unk_30.y = 0; + ptr->unk_30.z = 0; + ptr->unk_36 = 0; + ptr->unk_38 = 0; + ptr->unk_3A = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF0C30.s") +void func_80AF0984(EnTest7Struct2* arg0, Vec3f* arg1, s32 arg2) { + s16 sp26 = Rand_ZeroOne() * 0xFFFF; + f32 sp20; + f32 temp_f0; + f32 temp_f0_2; + f32 temp_f0_3; + f32 temp_f4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF0CDC.s") + arg0->unk_08 = *arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF10D8.s") + if (arg2 != 0) { + Math_CosS(sp26); + arg0->unk_08.x = arg0->unk_08.x; + arg0->unk_08.y += (Rand_ZeroOne() * 100.0f) - 20.0f; + Math_SinS(sp26); + arg0->unk_08.z = arg0->unk_08.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF118C.s") + sp20 = (Rand_ZeroOne() * 4.0f) + 2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF14FC.s") + arg0->unk_14 = Math_CosS(sp26) * sp20; + arg0->unk_18 = Rand_ZeroOne(); + arg0->unk_1C = Math_SinS(sp26) * sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1730.s") + arg0->unk_20 = 0.0f; + arg0->unk_24 = 0.0f; + arg0->unk_28 = 0.0f; + arg0->unk_2C = 0.25f; + arg0->unk_30.x = Rand_ZeroOne() * 0x10000; + arg0->unk_30.y = Rand_ZeroOne() * 0x10000; + arg0->unk_30.z = Rand_ZeroOne() * 0x10000; + arg0->unk_04 = 60; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/EnTest7_Init.s") + if (Rand_ZeroOne() < 0.9f) { + arg0->unk_00 = 1; + arg0->unk_30.x = Rand_ZeroOne() * 0x10000; + arg0->unk_30.y = Rand_ZeroOne() * 0x10000; + arg0->unk_30.z = Rand_ZeroOne() * 0x10000; + arg0->unk_36 = 0; + arg0->unk_38 = 0; + arg0->unk_3A = 0; + } else { + arg0->unk_00 = 2; + arg0->unk_30.x = 0; + arg0->unk_30.y = 0; + arg0->unk_30.z = Rand_ZeroOne() * 5000.0f; + arg0->unk_36 = 0; + arg0->unk_38 = (Rand_ZeroOne() * 8000.0f) + 2000.0f; + if (Rand_ZeroOne() > 0.5f) { + arg0->unk_38 = -arg0->unk_38; + } + arg0->unk_3A = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/EnTest7_Destroy.s") +void func_80AF0C30(EnTest7Struct2* arg0, Vec3f* arg1, s32 arg2) { + static s32 D_80AF3410 = 0; + s32 i; + s32 phi_t0 = false; + EnTest7Struct2* ptr; + s32 idx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF19A8.s") + for (i = 0, ptr = arg0; i < 100; i++, ptr++) { + if (ptr->unk_00 == 0) { + func_80AF0984(ptr, arg1, arg2); + D_80AF3410 = i; + phi_t0 = true; + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1A2C.s") + if (!phi_t0) { + idx = D_80AF3410 + 1; + if (idx >= 100) { + idx = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1B68.s") + func_80AF0984(&arg0[idx], arg1, arg2); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1CA0.s") +Vec3f D_80AF3414 = { 0.0f, 1.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1E44.s") +Vec3f D_80AF3420 = { 0.0f, 0.0f, 1.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF1F48.s") +void func_80AF0CDC(GlobalContext* globalCtx, EnTest7Struct2* arg1) { + static MtxF D_80AF38B0; + static Vec3f D_80AF38F0; + static f32 D_80AF38FC; + static Vec3f D_80AF3900; + s32 sp2C; + s32 sp28; + s32 sp24; + s16 temp_v0_2; + s16 temp_v0_3; + s32 temp_v0; + f32 phi_f8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2030.s") + sp2C = arg1->unk_04 % 41; + sp24 = 0; + sp28 = (arg1->unk_04 + 0x1B58) % 41; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF21E8.s") + SkinMatrix_SetRotateRPY(&D_80AF38B0, arg1->unk_30.x, arg1->unk_30.y, arg1->unk_30.z); + SkinMatrix_Vec3fMtxFMultXYZ(&D_80AF38B0, &D_80AF3414, &D_80AF38F0); + SkinMatrix_Vec3fMtxFMultXYZ(&D_80AF38B0, &D_80AF3420, &D_80AF3900); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2318.s") + if (arg1->unk_30.x < 0x3448) { + arg1->unk_30.x += 0x384; + } else if (arg1->unk_30.x >= 0x4BB9) { + arg1->unk_30.x -= 0x384; + } else { + arg1->unk_30.x = (Math_SinS((sp2C * 65535.0f) / 41.0f) * 2000.0f) + 16384.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2350.s") + if (arg1->unk_30.y < -0xBB8) { + arg1->unk_30.y += 0x384; + } else if (arg1->unk_30.y > 0xBB8) { + arg1->unk_30.y -= 0x384; + } else { + sp24 = 1; + arg1->unk_30.y = Math_SinS((sp28 * 65535.0f) / 41.0f) * 2000.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF24D8.s") + if (sp24 == 1) { + if (D_80AF38F0.y < 0.0f) { + arg1->unk_14 += D_80AF38F0.x * 0.5f; + arg1->unk_18 += (D_80AF38F0.y * 0.5f) + 0.08f; + arg1->unk_1C += (D_80AF38F0.z * 0.5f); + } else { + arg1->unk_14 += -D_80AF38F0.x * 0.5f; + arg1->unk_18 += (-D_80AF38F0.y * 0.5f) + 0.08f; + arg1->unk_1C += -D_80AF38F0.z * 0.5f; + } + } else if (D_80AF38F0.y < 0.0f) { + arg1->unk_14 += D_80AF38F0.x * 0.2f; + arg1->unk_18 += (D_80AF38F0.y * 0.2f) + 0.08f; + arg1->unk_1C += D_80AF38F0.z * 0.2f; + } else { + arg1->unk_14 += -D_80AF38F0.x * 0.2f; + arg1->unk_18 += (-D_80AF38F0.y * 0.2f) + 0.08f; + arg1->unk_1C += (-D_80AF38F0.z * 0.2f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2654.s") + arg1->unk_08.x += arg1->unk_14; + arg1->unk_08.y += arg1->unk_18; + arg1->unk_08.z += arg1->unk_1C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2808.s") +void func_80AF10D8(GlobalContext* globalCtx, EnTest7Struct2* arg1) { + arg1->unk_30.y += arg1->unk_38; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2854.s") + arg1->unk_20 = Rand_Centered(); + arg1->unk_24 = Rand_Centered() + -0.01f; + arg1->unk_28 = Rand_Centered(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2938.s") + arg1->unk_14 += arg1->unk_20; + arg1->unk_18 += arg1->unk_24; + arg1->unk_1C += arg1->unk_28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF29C0.s") + arg1->unk_08.x += arg1->unk_14; + arg1->unk_08.y += arg1->unk_18; + arg1->unk_08.z += arg1->unk_1C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2AE8.s") +void func_80AF118C(GlobalContext* globalCtx, EnTest7Struct2* arg1, EnTest7* this, s32 arg3, s32 arg4) { + s32 pad[4]; + EnTest7Struct2* ptr; + s16 phi_s1; + s32 i; + f32 temp_f28; + Vec3f sp8C; + f32 temp_f0; + f32 temp_f22; + f32 temp_f24; + f32 temp_f26; + f32 temp_f2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2BAC.s") + for (i = 0, ptr = arg1; i < (s32)(ARRAY_COUNT(this->unk_15C) * sizeof(this->unk_15C[0])); + i += sizeof(this->unk_15C[0]), ptr++) { + arg1 = ptr; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2C48.s") + if (arg1->unk_00 == 0) { + continue; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2DB4.s") + if (arg1->unk_00 == 1) { + func_80AF0CDC(globalCtx, arg1); + } else { + func_80AF10D8(globalCtx, arg1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2EC8.s") + if (arg3) { + temp_f22 = arg1->unk_08.x - this->actor.world.pos.x; + temp_f24 = arg1->unk_08.z - this->actor.world.pos.z; + temp_f0 = SQ(temp_f22) + SQ(temp_f24); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF2F98.s") + phi_s1 = -10000; + if (temp_f0 > SQ(20.0f)) { + phi_s1 /= ((temp_f0 - SQ(20.0f)) * 0.00125f) + 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF30F4.s") + temp_f26 = (temp_f22 * Math_CosS(phi_s1)) - (Math_SinS(phi_s1) * temp_f24); + temp_f28 = (temp_f22 * Math_SinS(phi_s1)) + (Math_CosS(phi_s1) * temp_f24); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/EnTest7_Update.s") + arg1->unk_08.x = this->actor.world.pos.x + temp_f26; + arg1->unk_08.z = this->actor.world.pos.z + temp_f28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/func_80AF31D0.s") + temp_f22 = arg1->unk_14; + temp_f24 = arg1->unk_1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test7/EnTest7_Draw.s") + arg1->unk_14 = (temp_f22 * Math_CosS(phi_s1)) - (Math_SinS(phi_s1) * temp_f24); + arg1->unk_1C = (temp_f22 * Math_SinS(phi_s1)) + (Math_CosS(phi_s1) * temp_f24); + + temp_f22 = arg1->unk_20; + temp_f24 = arg1->unk_28; + + arg1->unk_20 = (temp_f22 * Math_CosS(phi_s1)) - (Math_SinS(phi_s1) * temp_f24); + arg1->unk_28 = (temp_f22 * Math_SinS(phi_s1)) + (Math_CosS(phi_s1) * temp_f24); + } + + if (arg4) { + sp8C.x = arg1->unk_08.x - this->actor.world.pos.x; + sp8C.y = arg1->unk_08.y - (this->actor.world.pos.y + 40.0f); + sp8C.z = arg1->unk_08.z - this->actor.world.pos.z; + + temp_f2 = 1.0f - (0.5f / ((Math3D_Vec3fMagnitude(&sp8C) / 500.0f) + 1.0f)); + + sp8C.x *= temp_f2; + sp8C.y *= temp_f2; + sp8C.z *= temp_f2; + + arg1->unk_08.x = this->actor.world.pos.x + sp8C.x; + arg1->unk_08.y = this->actor.world.pos.y + sp8C.y + 40.0f; + arg1->unk_08.z = this->actor.world.pos.z + sp8C.z; + } + } +} + +void func_80AF14FC(GlobalContext* globalCtx2, EnTest7Struct2* arg1) { + s32 pad[3]; + GlobalContext* globalCtx = globalCtx2; + Mtx* temp_v0; + EnTest7Struct2* ptr; + s32 i; + MtxF sp6C; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C1C0(globalCtx->state.gfxCtx); + + Matrix_Push(); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + + for (i = 0, ptr = arg1; i < 0x1770; i += 0x3C, ptr++) { + if (ptr->unk_00 == 0) { + continue; + } + + if ((ptr->unk_08.x > 30000.0f) || (ptr->unk_08.x < -30000.0f) || (ptr->unk_08.y > 30000.0f) || + (ptr->unk_08.y < -30000.0f) || (ptr->unk_08.z > 30000.0f) || (ptr->unk_08.z < -30000.0f)) { + ptr->unk_00 = 0; + continue; + } + + Matrix_Translate(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); + + if (ptr->unk_00 == 1) { + Matrix_RotateZYX(ptr->unk_30.x, ptr->unk_30.y, ptr->unk_30.z, MTXMODE_APPLY); + } else { + SkinMatrix_SetRotateYRP(&sp6C, ptr->unk_30.x, ptr->unk_30.y, ptr->unk_30.z); + Matrix_Mult(&sp6C, MTXMODE_APPLY); + } + + Matrix_Scale(ptr->unk_2C, ptr->unk_2C, ptr->unk_2C, MTXMODE_APPLY); + if (ptr->unk_00 == 2) { + Matrix_Translate(0.0f, 30.0f, 0.0f, MTXMODE_APPLY); + } + + temp_v0 = Matrix_NewMtx(globalCtx->state.gfxCtx); + if (temp_v0 != NULL) { + gSPMatrix(POLY_OPA_DISP++, temp_v0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_081628); + } + } + + if (ptr) {} + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80AF1730(EnTest7Struct* arg0) { + arg0->unk_00 = 0.0f; + arg0->unk_04 = 0.0f; + arg0->unk_08 = 1.0f; + arg0->unk_0C = 1.0f; + arg0->unk_10 = 0; +} + +void EnTest7_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnTest7* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Player* player2 = GET_PLAYER(globalCtx); + + this->actor.world.rot.y = this->actor.shape.rot.y = player->actor.shape.rot.y; + this->unk_144 = 0; + this->unk_1E54 = 0; + this->unk_1E8E = player->actor.shape.rot.y; + this->unk_1E90 = player->actor.scale.x; + this->unk_1E94 = player->actor.scale.z; + + func_80183430(&this->unk_18CC, &gameplay_keep_Blob_085640, &gameplay_keep_Blob_083534, this->unk_18FC, + this->unk_1BA8, 0); + func_801834A8(&this->unk_18CC, &gameplay_keep_Blob_083534); + func_80AF0838(this->unk_15C); + func_80AF1730(&this->unk_148); + + if (ENTEST7_GET(&this->actor) == ENTEST7_MINUS1) { + func_80AF082C(this, func_80AF2938); + EnTest7_SetupAction(this, NULL); + } else { + func_80AF082C(this, func_80AF19A8); + EnTest7_SetupAction(this, func_80AF2854); + func_801A2E54(NA_BGM_SONG_OF_SOARING); + } + + if (globalCtx->playerActorCsIds[8] == -1) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + player2->stateFlags1 |= 0x20; + Lights_PointNoGlowSetInfo(&this->lightInfo, (Math_SinS(this->unk_1E8E) * 90.0f) + player->actor.world.pos.x, + player->actor.world.pos.y + 10.0f, + (Math_CosS(this->unk_1E8E) * 90.0f) + player->actor.world.pos.z, 255, 255, 255, 255); + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); +} + +void EnTest7_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTest7* this = THIS; + + ActorCutscene_Stop(globalCtx->playerActorCsIds[8]); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); +} + +void func_80AF19A8(EnTest7* this, GlobalContext* globalCtx) { + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[8])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[8], NULL); + func_80AF082C(this, func_80AF1A2C); + globalCtx->unk_18844 = 1; + } +} + +void func_80AF1A2C(EnTest7* this, GlobalContext* globalCtx) { + Color_RGB8 sp34 = { 64, 0, 0 }; + Color_RGB8 sp30 = { 220, 220, 255 }; + f32 sp2C = this->unk_1E54 / 10.0f; + + func_800FD59C(globalCtx, &sp30, sp2C); + func_800FD654(globalCtx, &sp34, sp2C); + func_800FD698(globalCtx, 2000, 4000, sp2C); + + if (this->unk_1E54 >= 10) { + Camera* camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + + this->unk_1E60 = camera->eye; + this->unk_1E6C = camera->at; + this->unk_1E78 = camera->fov; + + func_80AF082C(this, func_80AF1CA0); + this->unk_144 |= 0x20; + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_OPEN); + func_8016566C(0x78); + } +} + +void func_80AF1B68(EnTest7* this, GlobalContext* globalCtx) { + this->unk_144 |= 2; + + if (this->unk_148.unk_04 < 11.0f) { + this->unk_148.unk_04 = this->unk_148.unk_04 + 0.3f; + this->unk_148.unk_08 = ((this->unk_148.unk_00 * -0.45f) / 11.0f) + 0.7f; + this->unk_148.unk_0C = ((this->unk_148.unk_00 * -0.29999998f) / 11.0f) + 0.7f; + } + + if (this->unk_148.unk_00 < 11.0f) { + this->unk_148.unk_00 += 1.0f; + if (this->unk_148.unk_00 > 6.0f) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_144 &= ~1; + player->actor.draw = NULL; + } + } else if (this->unk_1E54 >= 87) { + func_80AF082C(this, func_80AF1F48); + this->unk_144 &= -9; + this->unk_148.unk_10 -= 0x2EE0; + } else { + this->unk_148.unk_10 -= 0x2EE0; + } +} + +void func_80AF1CA0(EnTest7* this, GlobalContext* globalCtx) { + Vec3f sp34; + + if (func_80183DE0(&this->unk_18CC)) { + func_80AF082C(this, func_80AF1E44); + } + + if (this->unk_18CC.frameCtrl.unk_10 > 60.0f) { + func_80AF1B68(this, globalCtx); + } + + if ((this->unk_18CC.frameCtrl.unk_10 > 20.0f) && !(this->unk_144 & 0x40)) { + this->unk_144 |= 0x40; + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_CLOSE); + } + + if (this->unk_18CC.frameCtrl.unk_10 > 42.0f) { + if (!(this->unk_144 & 0x80)) { + this->unk_144 |= 0x80; + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_ROLL); + } + + if (Rand_ZeroOne() < 0.3f) { + Camera* camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + f32 rand = Rand_ZeroOne(); + + sp34.x = ((camera->eye.x - this->actor.world.pos.x) * rand) + this->actor.world.pos.x; + sp34.y = ((camera->eye.y - this->actor.world.pos.y) * rand) + this->actor.world.pos.y; + sp34.z = ((camera->eye.z - this->actor.world.pos.z) * rand) + this->actor.world.pos.z; + + func_80AF0C30(this->unk_15C, &sp34, 1); + this->unk_144 |= 8; + } + } else { + this->unk_144 |= 1; + } +} + +void func_80AF1E44(EnTest7* this, GlobalContext* globalCtx) { + Vec3f sp34; + Camera* camera; + f32 rand; + + func_80AF1B68(this, globalCtx); + + if (Rand_ZeroOne() < 0.3f) { + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + rand = Rand_ZeroOne(); + sp34.x = ((camera->eye.x - this->actor.world.pos.x) * rand) + this->actor.world.pos.x; + sp34.y = ((camera->eye.y - this->actor.world.pos.y) * rand) + this->actor.world.pos.y; + sp34.z = ((camera->eye.z - this->actor.world.pos.z) * rand) + this->actor.world.pos.z; + func_80AF0C30(this->unk_15C, &sp34, 1); + } + + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + func_80AF0C30(this->unk_15C, &sp34, 1); + this->unk_18FC[1].y += 0x2EE0; +} + +void func_80AF1F48(EnTest7* this, GlobalContext* globalCtx) { + s32 pad; + s32 temp = this->unk_1E54 - 86; + f32 temp_f0 = temp / 10.0f; + Vec3f sp20; + + this->unk_144 |= 0x10; + + this->unk_148.unk_08 = (-0.15f * temp_f0) + 0.25f; + this->unk_148.unk_0C = (-0.3f * temp_f0) + 0.4f; + this->unk_148.unk_10 -= 0x2EE0; + + this->unk_144 |= 4; + + if (this->unk_1E54 >= 96) { + func_80AF082C(this, func_80AF2030); + this->unk_144 &= ~0x10; + } + Math_Vec3f_Copy(&sp20, &this->actor.world.pos); + func_80AF0C30(this->unk_15C, &sp20, 1); +} + +void func_80AF2030(EnTest7* this, GlobalContext* globalCtx) { + s32 temp = this->unk_1E54 - 96; + f32 four = 4; + f32 sp1C = 1.0f - (temp / four); + Camera* camera; + f32 temp_f2; + f32 temp_f4; + + this->unk_148.unk_08 = ((temp * -0.1f) / four) + 0.1f; + this->unk_148.unk_0C = ((temp * 5.9f) / four) + 0.1f; + this->unk_148.unk_10 -= 0x2EE0; + this->actor.world.pos.y += 100.0f; + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + camera->player = NULL; + + camera->eye.x = ((camera->eye.x - this->unk_1E60.x) * sp1C) + this->unk_1E60.x; + camera->eye.y = ((camera->eye.y - this->unk_1E60.y) * sp1C) + this->unk_1E60.y; + camera->eye.z = ((camera->eye.z - this->unk_1E60.z) * sp1C) + this->unk_1E60.z; + camera->fov = ((camera->fov - this->unk_1E78) * sp1C) + this->unk_1E78; + + if (this->unk_1E54 >= 100) { + MREG(64) = 1; + MREG(65) = 255; + MREG(66) = 255; + MREG(67) = 255; + MREG(68) = 255; + globalCtx->unk_18844 = 0; + this->unk_144 &= ~4; + func_80AF082C(this, func_80AF21E8); + func_80165690(); + } +} + +void func_80AF21E8(EnTest7* this, GlobalContext* globalCtx) { + s32 sp2C = this->unk_1E54 - 100; + f32 sp1C; + Color_RGB8 sp24 = { 64, 0, 0 }; + Color_RGB8 sp20 = { 220, 220, 255 }; + + if (MREG(64) != 0) { + Audio_PlaySfxAtPos(&this->actor.projectedPos, NA_SE_PL_WARP_WING_VANISH); + MREG(64) = 0; + MREG(65) = 0; + MREG(66) = 0; + MREG(67) = 0; + MREG(68) = 0; + } + + sp1C = 1.0f - (sp2C / 10.0f); + func_800FD59C(globalCtx, &sp20, sp1C); + func_800FD654(globalCtx, &sp24, sp1C); + func_800FD698(globalCtx, 2000, 4000, sp1C); + + if (this->unk_1E54 >= 110) { + func_80AF082C(this, func_80AF2318); + } +} + +void func_80AF2318(EnTest7* this, GlobalContext* globalCtx) { + if (this->unk_1E54 >= 130) { + func_80AF082C(this, func_80AF2350); + } +} + +u16 D_80AF343C[] = { + 0x68B0, 0x6A60, 0xB230, 0x9A80, 0xD890, 0x3E40, 0x8640, 0x84A0, 0x2040, 0xAA30, +}; + +void func_80AF2350(EnTest7* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + if (this) {} + + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + + if (Rand_ZeroOne() < 0.1f) { + func_80AF0C30(this->unk_15C, &sp2C, 1); + } + + this->unk_148.unk_10 -= 0x2EE0; + + if (globalCtx->sceneNum == SCENE_SECOM) { + globalCtx->nextEntranceIndex = 0x2060; + } else if (ENTEST7_GET(&this->actor) == ENTEST7_26) { + func_80169F78(&globalCtx->state); + gSaveContext.respawn[2].playerParams = (gSaveContext.respawn[2].playerParams & 0xFF) | 0x600; + gSaveContext.respawnFlag = -6; + } else { + globalCtx->nextEntranceIndex = D_80AF343C[ENTEST7_GET(&this->actor) - ENTEST7_1C]; + if ((globalCtx->nextEntranceIndex == 0x84A0) && (gSaveContext.save.weekEventReg[20] & 2)) { + globalCtx->nextEntranceIndex = 0xCA0; + } else if ((globalCtx->nextEntranceIndex == 0x9A80) && (gSaveContext.save.weekEventReg[33] & 0x80)) { + globalCtx->nextEntranceIndex = 0xAE80; + } + } + + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + gSaveContext.seqIndex = 0xFF; + gSaveContext.nightSeqIndex = 0xFF; +} + +void func_80AF24D8(EnTest7* this, GlobalContext* globalCtx, f32 arg2) { + Vec3f sp3C; + Vec3f* pos; + Player* player = GET_PLAYER(globalCtx); + Camera* camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + + pos = &player->actor.world.pos; + camera->player = NULL; + + sp3C.x = ((180.0f * Math_SinS(this->unk_1E8E)) * Math_CosS(0xFA0)) + pos->x; + sp3C.y = (Math_SinS(0xFA0) * 180.0f) + pos->y; + sp3C.z = ((180.0f * Math_CosS(this->unk_1E8E)) * Math_CosS(0xFA0)) + pos->z; + + camera->eye.x = ((sp3C.x - camera->eye.x) * arg2) + camera->eye.x; + camera->eye.y = ((sp3C.y - camera->eye.y) * arg2) + camera->eye.y; + camera->eye.z = ((sp3C.z - camera->eye.z) * arg2) + camera->eye.z; + + camera->fov = ((this->unk_1E78 - camera->fov) * arg2) + camera->fov; + camera->at.y += 1.4444444f; +} + +void func_80AF2654(EnTest7* this, GlobalContext* globalCtx, f32 arg2) { + Vec3f* pos; + Player* player = GET_PLAYER(globalCtx); + Camera* camera; + Vec3f sp30; + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + camera->player = NULL; + + pos = &player->actor.world.pos; + + sp30.x = ((80.0f * Math_SinS(this->unk_1E8E)) * Math_CosS(0xBB8)) + pos->x; + sp30.y = (Math_SinS(0xBB8) * 80.0f) + pos->y; + sp30.z = ((80.0f * Math_CosS(this->unk_1E8E)) * Math_CosS(0xBB8)) + pos->z; + + camera->eye.x = ((sp30.x - camera->eye.x) * arg2) + camera->eye.x; + camera->eye.y = ((sp30.y - camera->eye.y) * arg2) + camera->eye.y; + camera->eye.z = ((sp30.z - camera->eye.z) * arg2) + camera->eye.z; + + camera->at.x = ((pos->x - camera->at.x) * arg2) + camera->at.x; + camera->at.y = (((pos->y + 40.0f) - camera->at.y) * arg2) + camera->at.y; + camera->at.z = ((pos->z - camera->at.z) * arg2) + camera->at.z; + + camera->fov = ((this->unk_1E78 - camera->fov) * arg2) + camera->fov; +} + +void func_80AF2808(EnTest7* this, GlobalContext* globalCtx, f32 arg2) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.shape.rot.y += 0x2EE0; + player->actor.scale.x = ((0.0f - this->unk_1E90) * arg2) + this->unk_1E90; + player->actor.scale.z = ((0.0f - this->unk_1E94) * arg2) + this->unk_1E94; +} + +void func_80AF2854(EnTest7* this, GlobalContext* globalCtx) { + f32 temp; + f32 sixteen = 16.0f; + + if ((this->unk_1E54 >= 12) && (this->unk_1E54 < 31)) { + temp = (this->unk_1E54 - 12) / 18.0f; + func_80AF24D8(this, globalCtx, temp); + } else if ((this->unk_1E54 >= 79) && (this->unk_1E54 < 96)) { + temp = (this->unk_1E54 - 79) / sixteen; + func_80AF2654(this, globalCtx, temp); + } + + if ((this->unk_1E54 >= 42) && (this->unk_1E54 < 69)) { + temp = (this->unk_1E54 - 42) / 26.0f; + func_80AF2808(this, globalCtx, temp); + } +} + +void func_80AF2938(EnTest7* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_1E98 = player->actor.draw; + player->actor.draw = NULL; + player->stateFlags2 |= 0x20000000; + this->unk_144 |= 2; + this->unk_148.unk_04 = 30.0f; + if (globalCtx->roomCtx.currRoom.unk3 != 1) { + func_80AF082C(this, func_80AF2AE8); + } else { + func_80AF082C(this, func_80AF2EC8); + } +} + +s16 D_80AF3450[] = { 0, 0x31C7 }; + +f32 D_80AF3454 = 3500.0f; + +void func_80AF29C0(EnTest7* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Vec3f* pos = &player->actor.world.pos; + Camera* temp_s0 = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + + temp_s0->at.x = ((D_80AF3454 * Math_SinS(D_80AF3450[0]) * Math_CosS(D_80AF3450[1]))) + pos->x; + temp_s0->at.y = (Math_SinS(D_80AF3450[1]) * D_80AF3454) + pos->y; + temp_s0->at.z = ((D_80AF3454 * Math_CosS(D_80AF3450[0])) * Math_CosS(D_80AF3450[1])) + pos->z; + + this->actor.world.pos.x = temp_s0->at.x; + this->actor.world.pos.y = temp_s0->at.y - 40.0f; + this->actor.world.pos.z = temp_s0->at.z; +} + +void func_80AF2AE8(EnTest7* this, GlobalContext* globalCtx) { + Camera* camera; + + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[8])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + return; + } + + ActorCutscene_Start(globalCtx->playerActorCsIds[8], NULL); + func_80AF082C(this, func_80AF2C48); + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + this->unk_1E60 = camera->eye; + this->unk_1E6C = camera->at; + + func_80AF29C0(this, globalCtx); +} + +void func_80AF2BAC(EnTest7* this, GlobalContext* globalCtx, Vec3f* arg2, f32 arg3) { + f32 x; + f32 y; + f32 z; + Camera* camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + + camera->player = NULL; + x = ((camera->at.x - arg2->x) * arg3) + arg2->x; + y = ((camera->at.y - arg2->y) * arg3) + arg2->y; + z = ((camera->at.z - arg2->z) * arg3) + arg2->z; + + camera->at.x = x; + camera->at.y = y; + camera->at.z = z; +} + +void func_80AF2C48(EnTest7* this, GlobalContext* globalCtx) { + f32 sp24 = (40 - this->unk_1E54) / 40.0f; + Camera* camera; + + this->unk_148.unk_00 = 11.0f; + this->unk_144 |= 4; + this->unk_148.unk_08 = 0.05f; + this->unk_148.unk_0C = 0.05f; + this->unk_148.unk_10 += 0x2EE0; + + this->actor.world.pos.x = ((this->actor.world.pos.x - this->actor.home.pos.x) * sp24) + this->actor.home.pos.x; + this->actor.world.pos.y = ((this->actor.world.pos.y - this->actor.home.pos.y) * sp24) + this->actor.home.pos.y; + this->actor.world.pos.z = ((this->actor.world.pos.z - this->actor.home.pos.z) * sp24) + this->actor.home.pos.z; + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + func_80AF2BAC(this, globalCtx, &this->actor.home.pos, sp24); + + camera->at.x = this->actor.world.pos.x; + camera->at.y = this->actor.world.pos.y + 40.0f; + camera->at.z = this->actor.world.pos.z; + + func_800B9010(&this->actor, NA_SE_PL_WARP_WING_ROLL_2 - SFX_FLAG); + if (this->unk_1E54 >= 40) { + this->unk_144 &= ~4; + func_80AF082C(this, func_80AF2F98); + } +} + +void func_80AF2DB4(EnTest7* this, GlobalContext* globalCtx) { + Camera* camera; + Player* player = GET_PLAYER(globalCtx); + Vec3f* pos = &player->actor.world.pos; + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + + camera->eye.x = (Math_SinS(-player->actor.shape.rot.y) * 200.0f * -0.83907f) + pos->x; + camera->eye.y = pos->y + 108.8042f; + camera->eye.z = (Math_CosS(-player->actor.shape.rot.y) * 200.0f * -0.83907f) + pos->z; + + camera->at.x = pos->x; + camera->at.y = pos->y + 40.0f; + camera->at.z = pos->z; +} + +void func_80AF2EC8(EnTest7* this, GlobalContext* globalCtx) { + Camera* camera; + + if (!ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[8])) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[8]); + } else { + ActorCutscene_Start(globalCtx->playerActorCsIds[8], NULL); + func_80AF082C(this, func_80AF2F98); + + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(globalCtx->playerActorCsIds[8])); + this->unk_1E60 = camera->eye; + this->unk_1E6C = camera->at; + this->unk_1E54 = 40; + + func_80AF2DB4(this, globalCtx); + } +} + +void func_80AF2F98(EnTest7* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Player* player2 = GET_PLAYER(globalCtx); + Vec3f sp2C; + + func_800B9010(&this->actor, NA_SE_PL_WARP_WING_ROLL_2 - SFX_FLAG); + + sp2C = this->actor.world.pos; + + func_80AF0C30(this->unk_15C, &sp2C, 1); + func_80AF0C30(this->unk_15C, &sp2C, 1); + this->unk_148.unk_04 = 70 - this->unk_1E54; + if (this->unk_1E54 > 70) { + func_80AF082C(this, func_80AF30F4); + } + + if (this->unk_148.unk_04 > 11.0f) { + f32 temp = this->unk_148.unk_04 - 11.0f; + + this->unk_148.unk_08 = ((-0.35f * temp) / 19.0f) + 0.4f; + this->unk_148.unk_0C = ((-0.35f * temp) / 19.0f) + 0.4f; + this->unk_148.unk_10 += 0x2EE0; + } else { + player2->actor.draw = this->unk_1E98; + this->unk_148.unk_00 = this->unk_148.unk_04; + this->unk_148.unk_08 = ((this->unk_148.unk_04 * -0.29999998f) / 11.0f) + 0.7f; + this->unk_148.unk_0C = ((this->unk_148.unk_04 * -0.29999998f) / 11.0f) + 0.7f; + player->stateFlags2 &= ~0x20000000; + } +} + +void func_80AF30F4(EnTest7* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_1E54 > 90) { + player->stateFlags1 &= ~0x20; + player->stateFlags1 &= ~0x20000000; + Actor_MarkForDeath(&this->actor); + } +} + +void EnTest7_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTest7* this = THIS; + + this->unk_1E58(this, globalCtx); + + if (this->actionFunc != NULL) { + this->actionFunc(this, globalCtx); + } + + this->unk_1E54++; + + func_80AF118C(globalCtx, this->unk_15C, this, (this->unk_144 & 8) != 0, (this->unk_144 & 0x10) != 0); +} + +s32 func_80AF31D0(GlobalContext* globalCtx, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList, u8* flags, + Actor* thisx, Vec3f* scale, Vec3s* rot, Vec3f* pos) { + EnTest7* this = THIS; + Vec3f sp18; + + if ((*dList != NULL) && (Rand_ZeroOne() < 0.03f)) { + Matrix_MultVec3f(&gZeroVec3f, &sp18); + func_80AF0C30(this->unk_15C, &sp18, 0); + } + return true; +} + +void EnTest7_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[2]; + EnTest7* this = THIS; + s32 sp40; + + if (this->unk_144 & 1) { + Mtx* mtx = GRAPH_ALLOC(globalCtx->state.gfxCtx, ALIGN16(sizeof(Mtx) * this->unk_18CC.unk_18->unk_1)); + + if (mtx != NULL) { + func_8018450C(globalCtx, &this->unk_18CC, mtx, func_80AF31D0, NULL, &this->actor); + } else { + return; + } + } + + if (this->unk_144 & 2) { + Matrix_Push(); + Matrix_Translate(0.0f, 4000.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateZYX(0, this->unk_148.unk_10, 0, MTXMODE_APPLY); + Matrix_Scale(this->unk_148.unk_08 * 100.0f, this->unk_148.unk_0C * 100.0f, this->unk_148.unk_08 * 100.0f, + MTXMODE_APPLY); + sp40 = this->unk_148.unk_00; + AnimatedMat_DrawStep(globalCtx, Lib_SegmentedToVirtual(&gameplay_keep_Matanimheader_0815D0), sp40); + Gfx_DrawDListXlu(globalCtx, gameplay_keep_DL_080FC8); + Matrix_Pop(); + } + + func_80AF14FC(globalCtx, this->unk_15C); + + if (this->unk_144 & 4) { + func_800F9824(globalCtx, &globalCtx->envCtx, &globalCtx->view, globalCtx->state.gfxCtx, this->actor.world.pos, + 70.0f, 5.0f, 0, 0); + } +} diff --git a/src/overlays/actors/ovl_En_Test7/z_en_test7.h b/src/overlays/actors/ovl_En_Test7/z_en_test7.h index 0973b4245..a074c7875 100644 --- a/src/overlays/actors/ovl_En_Test7/z_en_test7.h +++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.h @@ -6,12 +6,60 @@ struct EnTest7; typedef void (*EnTest7ActionFunc)(struct EnTest7*, GlobalContext*); +typedef void (*EnTest7UnkFunc)(struct EnTest7*, GlobalContext*); +typedef void (*EnTest7UnkDrawFunc)(Actor*, GlobalContext*); + +#define ENTEST7_GET(thisx) ((thisx)->params) + +#define ENTEST7_MINUS1 -1 +#define ENTEST7_26 0x26 +#define ENTEST7_1C 0x1C + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ s16 unk_10; +} EnTest7Struct; // size >= 0x14 + +typedef struct { + /* 0x00 */ s32 unk_00; + /* 0x04 */ s32 unk_04; + /* 0x08 */ Vec3f unk_08; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ f32 unk_20; + /* 0x24 */ f32 unk_24; + /* 0x28 */ f32 unk_28; + /* 0x2C */ f32 unk_2C; + /* 0x30 */ Vec3s unk_30; + /* 0x36 */ s16 unk_36; + /* 0x38 */ s16 unk_38; + /* 0x3A */ s16 unk_3A; +} EnTest7Struct2; // size = 0x3C typedef struct EnTest7 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1D18]; + /* 0x0144 */ s32 unk_144; + /* 0x0148 */ EnTest7Struct unk_148; + /* 0x015C */ EnTest7Struct2 unk_15C[100]; + /* 0x18CC */ SkeletonInfo unk_18CC; + /* 0x18FC */ Vec3s unk_18FC[114]; + /* 0x1BA8 */ s16 unk_1BA8[342]; + /* 0x1E54 */ s32 unk_1E54; + /* 0x1E58 */ EnTest7UnkFunc unk_1E58; /* 0x1E5C */ EnTest7ActionFunc actionFunc; - /* 0x1E60 */ char unk_1E60[0x3C]; + /* 0x1E60 */ Vec3f unk_1E60; + /* 0x1E6C */ Vec3f unk_1E6C; + /* 0x1E78 */ f32 unk_1E78; + /* 0x1E7C */ LightNode* lightNode; + /* 0x1E80 */ LightInfo lightInfo; + /* 0x1E8E */ s16 unk_1E8E; + /* 0x1E90 */ f32 unk_1E90; + /* 0x1E94 */ f32 unk_1E94; + /* 0x1E98 */ EnTest7UnkDrawFunc unk_1E98; } EnTest7; // size = 0x1E9C extern const ActorInit En_Test7_InitVars; diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.c b/src/overlays/actors/ovl_En_Tg/z_en_tg.c index 95801e7b4..fe3aadc7b 100644 --- a/src/overlays/actors/ovl_En_Tg/z_en_tg.c +++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.c @@ -1,6 +1,12 @@ +/* + * File: z_en_tg.c + * Overlay: ovl_En_Tg + * Description: Target Game (Honey & Darling) + */ + #include "z_en_tg.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnTg*)thisx) 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 b303ed877..faeb3163e 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c @@ -5,8 +5,9 @@ */ #include "z_en_thiefbird.h" +#include "objects/object_thiefbird/object_thiefbird.h" -#define FLAGS 0x80001205 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200 | ACTOR_FLAG_1000 | ACTOR_FLAG_80000000) #define THIS ((EnThiefbird*)thisx) @@ -32,19 +33,6 @@ void func_80C126D8(EnThiefbird* this, GlobalContext* globalCtx); void func_80C12744(EnThiefbird* this); void func_80C127F4(EnThiefbird* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000088; -extern AnimationHeader D_06000278; -extern AnimationHeader D_06000604; -extern Gfx D_06003060[]; -extern Gfx D_060030D8[]; -extern Gfx D_060033B0[]; -extern Gfx D_06003D58[]; -extern Gfx D_06004348[]; -extern Gfx D_06004B88[]; -extern Gfx D_060055E0[]; -extern FlexSkeletonHeader D_060061A0; -extern AnimationHeader D_060063C4; - const ActorInit En_Thiefbird_InitVars = { ACTOR_EN_THIEFBIRD, ACTORCAT_ENEMY, @@ -162,7 +150,8 @@ void EnThiefbird_Init(Actor* thisx, GlobalContext* globalCtx) { ColliderJntSphElementDim* dim; Actor_ProcessInitChain(&this->actor, sInitChain); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060061A0, &D_06000604, this->jointTable, this->morphTable, 17); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_thiefbird_Skel_0061A0, &object_thiefbird_Anim_000604, + this->jointTable, this->morphTable, 17); Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { @@ -174,12 +163,12 @@ void EnThiefbird_Init(Actor* thisx, GlobalContext* globalCtx) { } CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); - ActorShape_Init(&this->actor.shape, 1500.0f, func_800B3FC0, 35.0f); + ActorShape_Init(&this->actor.shape, 1500.0f, ActorShadow_DrawCircle, 35.0f); if (this->actor.params == 1) { D_80C1392C = 1; Math_Vec3f_Copy(&D_80C13920, &this->actor.world.pos); Actor_MarkForDeath(&this->actor); - } else if ((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) { + } else if (STOLEN_ITEM_1 != STOLEN_ITEM_NONE) { Actor_MarkForDeath(&this->actor); } else { func_80C11538(this); @@ -217,24 +206,25 @@ void func_80C10984(EnThiefbird* this, s32 arg1) { } s32 func_80C10B0C(EnThiefbird* this, GlobalContext* globalCtx) { - static Gfx* D_80C13680[] = { D_06004348, D_06004B88, D_060055E0 }; + static Gfx* D_80C13680[] = { object_thiefbird_DL_004348, object_thiefbird_DL_004B88, object_thiefbird_DL_0055E0 }; s32 isItemFound = false; s32 phi_a3 = 0; - s32 i = 18; - s32 phi_t0_3; - s16 sp1E = 0; + s32 slotId = SLOT_BOTTLE_1; + s32 itemId1; + s16 itemId2 = 0; - for (; i < ARRAY_COUNT(gSaveContext.inventory.items); i++) { - if ((gSaveContext.inventory.items[i] >= ITEM_BOTTLE) && (gSaveContext.inventory.items[i] <= ITEM_POTION_BLUE)) { + for (; slotId < 24; slotId++) { + if ((gSaveContext.save.inventory.items[slotId] >= ITEM_BOTTLE) && + (gSaveContext.save.inventory.items[slotId] <= ITEM_POTION_BLUE)) { isItemFound = true; - sp1E = gSaveContext.inventory.items[i]; + itemId2 = gSaveContext.save.inventory.items[slotId]; break; } } - if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { - phi_a3 = CUR_EQUIP_VALUE_VOID(EQUIP_SWORD); - if (gSaveContext.inventory.items[gItemSlots[16]] == ITEM_SWORD_GREAT_FAIRY) { + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + phi_a3 = GET_CUR_EQUIP_VALUE(EQUIP_SWORD); + if (INV_CONTENT(ITEM_SWORD_GREAT_FAIRY) == ITEM_SWORD_GREAT_FAIRY) { phi_a3 += 4; } } @@ -248,12 +238,12 @@ s32 func_80C10B0C(EnThiefbird* this, GlobalContext* globalCtx) { } if (isItemFound) { - func_801149A0(sp1E, i); - this->unk_3E8 = D_060033B0; - if (!func_80152498(&globalCtx->msgCtx)) { - func_801518B0(globalCtx, 0xF4, NULL); + func_801149A0(itemId2, slotId); + this->unk_3E8 = object_thiefbird_DL_0033B0; + if (Message_GetState(&globalCtx->msgCtx) == 0) { + Message_StartTextbox(globalCtx, 0xF4, NULL); } - phi_t0_3 = 0x12; + itemId1 = ITEM_BOTTLE; } else if (phi_a3 != 0) { if (phi_a3 >= 5) { if (Rand_ZeroOne() < 0.5f) { @@ -263,28 +253,28 @@ s32 func_80C10B0C(EnThiefbird* this, GlobalContext* globalCtx) { } } - phi_t0_3 = phi_a3 + 0x4C; + itemId1 = phi_a3 + (ITEM_SWORD_KOKIRI - 1); if (phi_a3 == 4) { - func_801149A0(16, 16); - this->unk_3E8 = D_06003D58; - phi_t0_3 = 0x10; + func_801149A0(ITEM_SWORD_GREAT_FAIRY, SLOT_SWORD_GREAT_FAIRY); + this->unk_3E8 = object_thiefbird_DL_003D58; + itemId1 = ITEM_SWORD_GREAT_FAIRY; } else { CUR_FORM_EQUIP(EQUIP_SLOT_B) = ITEM_NONE; - TAKE_EQUIPPED_ITEM(EQUIP_SWORD); + SET_EQUIP_VALUE(EQUIP_SWORD, 0); this->unk_3E8 = D_80C13680[phi_a3 - 1]; } - if (!func_80152498(&globalCtx->msgCtx)) { - func_801518B0(globalCtx, 0xF5, NULL); + if (Message_GetState(&globalCtx->msgCtx) == 0) { + Message_StartTextbox(globalCtx, 0xF5, NULL); } } else { return false; } - if (!((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18)) { - gSaveContext.roomInf[126][5] = (gSaveContext.roomInf[126][5] & 0xFFFFFF) | ((phi_t0_3 & 0xFF) << 0x18); + if (STOLEN_ITEM_1 == STOLEN_ITEM_NONE) { + SET_STOLEN_ITEM_1(itemId1); } else { - gSaveContext.roomInf[126][5] = (gSaveContext.roomInf[126][5] & 0xFF00FFFF) | ((phi_t0_3 & 0xFF) << 0x10); + SET_STOLEN_ITEM_2(itemId1); } return true; @@ -322,16 +312,16 @@ s32 func_80C10E98(GlobalContext* globalCtx) { s32 pad2; s32 sp98; s32 i; - s32 sp74[8]; + s32 dropItem00Ids[8]; s32 sp5C; - for (i = 0; i < ARRAY_COUNT(sp74); i++) { - sp74[i] = ITEM00_NO_DROP; + for (i = 0; i < ARRAY_COUNT(dropItem00Ids); i++) { + dropItem00Ids[i] = ITEM00_NO_DROP; } if (AMMO(ITEM_BOMB) >= 5) { spB0 = 1; - sp74[1] = ITEM00_BOMBS_B; + dropItem00Ids[1] = ITEM00_BOMBS_B; if (1) {} } else { spB0 = 0; @@ -339,12 +329,12 @@ s32 func_80C10E98(GlobalContext* globalCtx) { if (AMMO(ITEM_BOW) >= 10) { spAC = 1; - sp74[5] = ITEM00_ARROWS_10; + dropItem00Ids[5] = ITEM00_ARROWS_10; } else { spAC = 0; } - sp98 = (gSaveContext.rupees / 4) * 3; + sp98 = (gSaveContext.save.playerData.rupees / 4) * 3; phi_s0_2 = sp98 / 50; sp5C = (-spB0 - spAC); sp5C += 8; @@ -364,7 +354,7 @@ s32 func_80C10E98(GlobalContext* globalCtx) { sp5C = phi_s0_2 * 50; sp98 -= sp5C; - func_80C10DE8(sp74, phi_s0_2, ITEM00_RUPEE_PURPLE); + func_80C10DE8(dropItem00Ids, phi_s0_2, ITEM00_RUPEE_PURPLE); spA0 = sp98 / 20; if (i < spA0) { spA0 = i; @@ -372,7 +362,7 @@ s32 func_80C10E98(GlobalContext* globalCtx) { i -= spA0; sp98 -= spA0 * 20; - func_80C10DE8(sp74, spA0, ITEM00_RUPEE_RED); + func_80C10DE8(dropItem00Ids, spA0, ITEM00_RUPEE_RED); phi_s2 = sp98 / 5; if (i < phi_s2) { phi_s2 = i; @@ -380,14 +370,14 @@ s32 func_80C10E98(GlobalContext* globalCtx) { i -= phi_s2; sp98 -= phi_s2 * 5; - func_80C10DE8(sp74, phi_s2, ITEM00_RUPEE_BLUE); + func_80C10DE8(dropItem00Ids, phi_s2, ITEM00_RUPEE_BLUE); if (i < sp98) { spA8 = i; } else { spA8 = sp98; } - func_80C10DE8(sp74, spA8, ITEM00_RUPEE_GREEN); + func_80C10DE8(dropItem00Ids, spA8, ITEM00_RUPEE_GREEN); if ((spB0 + spAC + phi_s0_2 + spA0 + phi_s2 + spA8) == 0) { return false; } @@ -395,17 +385,17 @@ s32 func_80C10E98(GlobalContext* globalCtx) { { Vec3f sp64; - for (i = 0; i < ARRAY_COUNT(sp74); i++) { + for (i = 0; i < ARRAY_COUNT(dropItem00Ids); i++) { sp64.x = (Math_SinS(phi_s3) * 40.0f) + player->actor.world.pos.x; sp64.y = player->actor.world.pos.y + 20.0f; sp64.z = (Math_CosS(phi_s3) * 40.0f) + player->actor.world.pos.z; - if (sp74[i] != ITEM00_NO_DROP) { - EnItem00* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, sp74[i]); + if (dropItem00Ids[i] != ITEM00_NO_DROP) { + 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)); } @@ -428,7 +418,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) { @@ -453,25 +443,25 @@ void func_80C11338(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C11454(EnThiefbird* this) { - this->unk_18C = 10; - this->unk_3D8 = 0.5f; - this->unk_3DC = 0.75f; - this->unk_3D4 = 1.0f; - this->actor.flags &= ~0x200; - func_800BCB70(&this->actor, 0x4000, 255, 0, 80); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffFrozenSteamScale = 0.75f; + this->drawDmgEffAlpha = 1.0f; + this->actor.flags &= ~ACTOR_FLAG_200; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); } void func_80C114C0(EnThiefbird* this, GlobalContext* globalCtx) { - if (this->unk_18C == 10) { - this->unk_18C = 0; - this->unk_3D4 = 0.0f; - func_800BF7CC(globalCtx, &this->actor, this->unk_350, 11, 2, 0.2f, 0.2f); - this->actor.flags |= 0x200; + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 11, 2, 0.2f, 0.2f); + this->actor.flags |= ACTOR_FLAG_200; } } void func_80C11538(EnThiefbird* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06000604, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_thiefbird_Anim_000604, -4.0f); this->unk_18E = 60; this->collider.base.acFlags |= AC_ON; this->actionFunc = func_80C11590; @@ -502,10 +492,10 @@ void func_80C11590(EnThiefbird* this, GlobalContext* globalCtx) { } else { this->unk_192 -= Rand_S16Offset(4096, 4096); } - Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); } - if ((this->actor.yDistToWater > -40.0f) || (this->actor.bgCheckFlags & 1)) { + if ((this->actor.depthInWater > -40.0f) || (this->actor.bgCheckFlags & 1)) { this->unk_190 = -4096; } else if (this->actor.world.pos.y < (this->actor.home.pos.y - 75.0f)) { this->unk_190 = -Rand_S16Offset(2048, 2048); @@ -529,13 +519,13 @@ void func_80C11590(EnThiefbird* this, GlobalContext* globalCtx) { } if ((this->unk_18E == 0) && (this->actor.xzDistToPlayer < 300.0f) && !(player->stateFlags1 & 0x800000) && - (Player_GetMask(globalCtx) != PLAYER_MASK_STONE_MASK) && (this->actor.yDistToWater < -40.0f)) { + (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && (this->actor.depthInWater < -40.0f)) { func_80C118E4(this); } } void func_80C118E4(EnThiefbird* this) { - Animation_MorphToLoop(&this->skelAnime, &D_060063C4, -10.0f); + Animation_MorphToLoop(&this->skelAnime, &object_thiefbird_Anim_0063C4, -10.0f); this->unk_18E = 300; this->actionFunc = func_80C1193C; this->actor.speedXZ = 5.0f; @@ -547,7 +537,7 @@ void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); if (Animation_OnFrame(&this->skelAnime, 1.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_FLUTTER); } if (this->unk_18E != 0) { @@ -559,7 +549,7 @@ void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.x, pitch, 4, 0x800, 0x80); if (this->actor.bgCheckFlags & 8) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.wallYaw, 6, 0x1000, 0x100); - } else if (Actor_IsActorFacingLink(&this->actor, 0x3C00) || (this->actor.xzDistToPlayer > 120.0f)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x3C00) || (this->actor.xzDistToPlayer > 120.0f)) { s16 rot = BINANG_ROT180(this->actor.yawTowardsPlayer - player->actor.shape.rot.y); if (rot > 0x4000) { @@ -572,16 +562,15 @@ void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, rot, 4, 0x1000, 0x100); } - if ((this->unk_18E == 0) || (player->stateFlags1 & 0x800000) || - (Player_GetMask(globalCtx) == PLAYER_MASK_STONE_MASK) || (this->collider.base.atFlags & AT_HIT) || - (this->actor.bgCheckFlags & 1) || (this->actor.yDistToWater > -40.0f)) { + if ((this->unk_18E == 0) || (player->stateFlags1 & 0x800000) || (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || + (this->collider.base.atFlags & AT_HIT) || (this->actor.bgCheckFlags & 1) || + (this->actor.depthInWater > -40.0f)) { if (this->collider.base.atFlags & AT_HIT) { this->collider.base.atFlags &= ~AT_HIT; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_THIEFBIRD_VOICE); if (!(this->collider.base.atFlags & AT_BOUNCED)) { if ((D_80C1392C != 0) && CUR_UPG_VALUE(UPG_QUIVER) && - (!((gSaveContext.roomInf[126][5] & 0xFF000000) >> 0x18) || - !((gSaveContext.roomInf[126][5] & 0xFF0000) >> 0x10)) && + ((STOLEN_ITEM_1 == STOLEN_ITEM_NONE) || (STOLEN_ITEM_2 == STOLEN_ITEM_NONE)) && (Rand_ZeroOne() < 0.5f) && func_80C10B0C(this, globalCtx)) { func_80C1242C(this); } else if (func_80C10E98(globalCtx)) { @@ -602,15 +591,15 @@ void func_80C1193C(EnThiefbird* this, GlobalContext* globalCtx) { void func_80C11C60(EnThiefbird* this) { this->actor.speedXZ = 0.0f; this->actor.velocity.y = 0.0f; - Animation_PlayOnce(&this->skelAnime, &D_06000088); + Animation_PlayOnce(&this->skelAnime, &object_thiefbird_Anim_000088); this->actor.bgCheckFlags &= ~1; this->actor.shape.rot.x = 0; this->unk_18E = 40; this->actor.velocity.y = 0.0f; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_DEAD); - func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_THIEFBIRD_DEAD); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); this->collider.base.acFlags &= ~AC_ON; - this->actor.flags |= 0x10; + this->actor.flags |= ACTOR_FLAG_10; this->unk_192 = 0x1C00; this->actionFunc = func_80C11D14; } @@ -621,7 +610,7 @@ void func_80C11D14(EnThiefbird* this, GlobalContext* globalCtx) { this->unk_18E--; } - if (this->unk_18C == 10) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { if (this->unk_18E < 38) { func_80C114C0(this, globalCtx); this->actor.speedXZ = 4.0f; @@ -641,7 +630,7 @@ void func_80C11D14(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C11DC0(EnThiefbird* this) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->actionFunc = func_80C11DF0; this->actor.gravity = -0.5f; } @@ -656,12 +645,12 @@ 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); + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { + func_800B3030(globalCtx, &this->limbPos[i], &gZeroVec3f, &gZeroVec3f, 0x8C, 0, 0); } - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); - Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_RUPEE_ORANGE); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_RUPEE_HUGE); for (i = 0; i < ARRAY_COUNT(D_80C13664); i++) { for (j = 0; j < this->unk_196[i]; j++) { @@ -674,7 +663,7 @@ void func_80C11DF0(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C11F6C(EnThiefbird* this, GlobalContext* globalCtx) { - Animation_MorphToLoop(&this->skelAnime, &D_06000278, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_thiefbird_Anim_000278, -4.0f); func_80C10984(this, 15); if (this->actor.colChkInfo.damageEffect != 3) { this->actor.speedXZ = 4.0f; @@ -683,14 +672,14 @@ void func_80C11F6C(EnThiefbird* this, GlobalContext* globalCtx) { } if (this->actor.colChkInfo.damageEffect == 5) { - func_800BCB70(&this->actor, 0, 255, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); } else if (this->actor.colChkInfo.damageEffect == 1) { - func_800BCB70(&this->actor, 0, 255, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); } else { - func_800BCB70(&this->actor, 0x4000, 255, 0, 40); - Audio_PlayActorSound2(&this->actor, NA_SE_EN_THIEFBIRD_DAMAGE); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_THIEFBIRD_DAMAGE); } this->collider.base.acFlags &= ~AC_ON; @@ -723,7 +712,7 @@ void func_80C1215C(EnThiefbird* this, GlobalContext* globalCtx) { this->unk_18E--; } - if (this->unk_18C == 10) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { if (this->unk_18E < 38) { func_80C114C0(this, globalCtx); this->actor.speedXZ = 4.0f; @@ -758,7 +747,7 @@ void func_80C1215C(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C12308(EnThiefbird* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06000278, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_thiefbird_Anim_000278, -4.0f); func_80C10984(this, 15); this->unk_190 = -0x1000; this->unk_192 = BINANG_ROT180(this->actor.yawTowardsPlayer); @@ -787,8 +776,8 @@ void func_80C12378(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C1242C(EnThiefbird* this) { - Animation_Change(&this->skelAnime, &D_06000278, 2.0f, 0.0f, 0.0f, 0, -4.0f); - this->actor.flags |= 0x10; + Animation_Change(&this->skelAnime, &object_thiefbird_Anim_000278, 2.0f, 0.0f, 0.0f, 0, -4.0f); + this->actor.flags |= ACTOR_FLAG_10; this->collider.base.acFlags |= AC_ON; this->actionFunc = func_80C124B0; this->actor.speedXZ = 12.0f; @@ -833,7 +822,7 @@ void func_80C124B0(EnThiefbird* this, GlobalContext* globalCtx) { } void func_80C126A8(EnThiefbird* this) { - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; this->collider.base.acFlags &= ~AC_ON; this->actionFunc = func_80C126D8; } @@ -841,17 +830,17 @@ void func_80C126A8(EnThiefbird* this) { void func_80C126D8(EnThiefbird* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); Math_ApproachS(&this->actor.shape.rot.x, 0x3000, 6, 0x1000); - if (this->actor.yDistToPlayer > 100.0f) { + if (this->actor.playerHeightRel > 100.0f) { Actor_MarkForDeath(&this->actor); } } void func_80C12744(EnThiefbird* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06000604, -4.0f); - Animation_Change(&this->skelAnime, &D_06000604, 1.0f, 0.0f, 0.0f, 1, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_thiefbird_Anim_000604, -4.0f); + Animation_Change(&this->skelAnime, &object_thiefbird_Anim_000604, 1.0f, 0.0f, 0.0f, 1, -4.0f); this->unk_190 = 0; this->collider.base.acFlags |= AC_ON; - this->actor.flags |= 0x10; + this->actor.flags |= ACTOR_FLAG_10; this->actionFunc = func_80C127F4; this->actor.speedXZ = 4.0f; this->skelAnime.playSpeed = 3.0f; @@ -887,10 +876,10 @@ void func_80C127F4(EnThiefbird* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawBetweenActors(&this->actor, &this->unk_3EC->actor), 3, 0x2000, 0x100); } - temp_v0 = Math_Vec3f_Pitch(&this->unk_350[9], &this->unk_3EC->actor.world.pos); + temp_v0 = Math_Vec3f_Pitch(&this->limbPos[9], &this->unk_3EC->actor.world.pos); temp_v0 = CLAMP(temp_v0, -0x3000, 0x3000); Math_SmoothStepToS(&this->actor.shape.rot.x, temp_v0, 4, 0x800, 0x80); - temp_f0 = Actor_DistanceToPoint(&this->unk_3EC->actor, &this->unk_350[9]); + temp_f0 = Actor_DistanceToPoint(&this->unk_3EC->actor, &this->limbPos[9]); this->actor.speedXZ = (0.02f * temp_f0) + 2.0f; this->actor.speedXZ = CLAMP_MAX(this->actor.speedXZ, 4.0f); if ((this->unk_3EC->actor.speedXZ <= 0.0f) && (temp_f0 < 40.0f)) { @@ -917,7 +906,7 @@ void func_80C127F4(EnThiefbird* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.x, -0x800, 4, 0x800, 0x80); if (this->unk_194 == 0) { - this->actor.flags &= ~0x10; + this->actor.flags &= ~ACTOR_FLAG_10; func_80C11538(this); } } @@ -930,12 +919,12 @@ void func_80C12B1C(EnThiefbird* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; this->collider.base.atFlags &= ~AT_HIT; - func_800BE258(&this->actor, this->collider.elements); + Actor_SetDropFlag(&this->actor, &this->collider.elements->info); func_80C114C0(this, globalCtx); this->unk_194 = 0; for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { - if (this->collider.elements[i].info.bumperFlags & 2) { + if (this->collider.elements[i].info.bumperFlags & BUMP_HIT) { break; } } @@ -943,22 +932,22 @@ void func_80C12B1C(EnThiefbird* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == 3) { func_80C11454(this); } else if (this->actor.colChkInfo.damageEffect == 4) { - this->unk_18C = 20; - this->unk_3D8 = 0.5f; - this->unk_3D4 = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffAlpha = 4.0f; if (i != ARRAY_COUNT(this->colliderElements)) { sph = &this->collider.elements[i]; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, sph->info.bumper.hitPos.x, sph->info.bumper.hitPos.y, sph->info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); } } else if (this->actor.colChkInfo.damageEffect == 2) { - this->unk_18C = 0; - this->unk_3D8 = 0.5f; - this->unk_3D4 = 4.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffAlpha = 4.0f; } else if (this->actor.colChkInfo.damageEffect == 5) { - this->unk_18C = 0x1E; - this->unk_3D8 = 0.5f; - this->unk_3D4 = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffAlpha = 2.0f; } if (this->unk_3E8 != 0) { @@ -1007,17 +996,17 @@ void func_80C12D00(EnThiefbird* this) { } void EnThiefbird_Update(Actor* thisx, GlobalContext* globalCtx2) { - EnThiefbird* this = THIS; GlobalContext* globalCtx = globalCtx2; + EnThiefbird* this = THIS; func_80C12B1C(this, globalCtx); this->actionFunc(this, globalCtx); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.world.rot.x = -this->actor.shape.rot.x; if (this->actor.colChkInfo.health != 0) { - Actor_SetVelocityAndMoveXYRotation(&this->actor); + Actor_MoveWithoutGravity(&this->actor); } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, 25.0f, 50.0f, 7); @@ -1030,20 +1019,20 @@ void EnThiefbird_Update(Actor* thisx, GlobalContext* globalCtx2) { } CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - if (this->unk_3D4 > 0.0f) { - if (this->unk_18C != 10) { - Math_StepToF(&this->unk_3D4, 0.0f, 0.05f); - this->unk_3D8 = (this->unk_3D4 + 1.0f) * 0.25f; - this->unk_3D8 = CLAMP_MAX(this->unk_3D8, 0.5f); - } else if (!Math_StepToF(&this->unk_3DC, 0.5f, 0.0125f)) { + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.25f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.5f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.5f, 0.0125f)) { func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); } } func_80C12D00(this); - if (((this->skelAnime.animation == &D_06000604) && Animation_OnFrame(&this->skelAnime, 13.0f)) || - ((this->skelAnime.animation == &D_06000278) && Animation_OnFrame(&this->skelAnime, 1.0f))) { - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_FLUTTER); + if (((this->skelAnime.animation == &object_thiefbird_Anim_000604) && Animation_OnFrame(&this->skelAnime, 13.0f)) || + ((this->skelAnime.animation == &object_thiefbird_Anim_000278) && Animation_OnFrame(&this->skelAnime, 1.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KAICHO_FLUTTER); } } @@ -1077,7 +1066,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_ReplaceRotation(&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]; @@ -1087,7 +1076,7 @@ void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi if (this->unk_3E8 != NULL) { OPEN_DISPS(globalCtx->state.gfxCtx); - if (this->unk_3E8 == D_060033B0) { + if (this->unk_3E8 == object_thiefbird_DL_0033B0) { gfx = POLY_XLU_DISP; } else { gfx = POLY_OPA_DISP; @@ -1096,7 +1085,7 @@ void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(&gfx[1], this->unk_3E8); - if (this->unk_3E8 == D_060033B0) { + if (this->unk_3E8 == object_thiefbird_DL_0033B0) { POLY_XLU_DISP = &gfx[2]; } else { POLY_OPA_DISP = &gfx[2]; @@ -1109,11 +1098,11 @@ void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi idx = D_80C13698[limbIndex]; if (idx != -1) { if (idx == 9) { - Matrix_GetStateTranslationAndScaledX(1000.0f, &this->unk_350[idx]); + Matrix_MultVecX(1000.0f, &this->limbPos[idx]); } else { - Matrix_GetStateTranslation(&this->unk_350[idx]); + Matrix_MultZero(&this->limbPos[idx]); if ((idx == 3) || (idx == 5)) { - Matrix_GetStateTranslationAndScaledX(2000.0f, &this->unk_350[idx + 1]); + Matrix_MultVecX(2000.0f, &this->limbPos[idx + 1]); } } } @@ -1129,20 +1118,20 @@ void func_80C13354(EnThiefbird* this, GlobalContext* globalCtx2) { gfx = POLY_OPA_DISP; gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); - gSPDisplayList(&gfx[1], D_06003060); + gSPDisplayList(&gfx[1], object_thiefbird_DL_003060); gfx = &gfx[2]; 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_RotateY(ptr->unk_1E, MTXMODE_APPLY); - Matrix_InsertZRotation_s(ptr->unk_20, MTXMODE_APPLY); - Matrix_InsertTranslation(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateYS(ptr->unk_1E, MTXMODE_APPLY); + Matrix_RotateZS(ptr->unk_20, MTXMODE_APPLY); + Matrix_Translate(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); Matrix_Scale(ptr->unk_18, ptr->unk_18, 1.0f, MTXMODE_APPLY); gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&gfx[1], D_060030D8); + gSPDisplayList(&gfx[1], object_thiefbird_DL_0030D8); gfx = &gfx[2]; } } @@ -1161,7 +1150,7 @@ void EnThiefbird_Draw(Actor* thisx, GlobalContext* globalCtx) { func_800AE5A0(globalCtx); } func_80C13354(this, globalCtx); - func_800BE680(globalCtx, &this->actor, this->unk_350, 11, this->unk_3D8, this->unk_3DC, this->unk_3D4, - this->unk_18C); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->collider.elements[1].dim.worldSphere.center); } diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h index 5581f1155..990b4b2c5 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.h @@ -21,7 +21,7 @@ typedef struct EnThiefbird { /* 0x0000 */ Actor actor; /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnThiefbirdActionFunc actionFunc; - /* 0x018C */ u8 unk_18C; + /* 0x018C */ u8 drawDmgEffType; /* 0x018E */ s16 unk_18E; /* 0x0190 */ s16 unk_190; /* 0x0192 */ s16 unk_192; @@ -31,10 +31,10 @@ typedef struct EnThiefbird { /* 0x0208 */ Vec3s morphTable[17]; /* 0x0270 */ ColliderJntSph collider; /* 0x0290 */ ColliderJntSphElement colliderElements[3]; - /* 0x0350 */ Vec3f unk_350[11]; - /* 0x03D4 */ f32 unk_3D4; - /* 0x03D8 */ f32 unk_3D8; - /* 0x03DC */ f32 unk_3DC; + /* 0x0350 */ Vec3f limbPos[11]; + /* 0x03D4 */ f32 drawDmgEffAlpha; + /* 0x03D8 */ f32 drawDmgEffScale; + /* 0x03DC */ f32 drawDmgEffFrozenSteamScale; /* 0x03E0 */ f32 unk_3E0; /* 0x03E4 */ Gfx* unk_3E4; /* 0x03E8 */ Gfx* unk_3E8; diff --git a/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c b/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c index b9a48e7c3..cd0403c71 100644 --- a/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c +++ b/src/overlays/actors/ovl_En_Time_Tag/z_en_time_tag.c @@ -1,6 +1,12 @@ +/* + * File: z_en_time_tag.c + * Overlay: ovl_En_Time_Tag + * Description: + */ + #include "z_en_time_tag.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnTimeTag*)thisx) 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 2108a5a8f..153bb8722 100644 --- a/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -1,6 +1,13 @@ -#include "z_en_tite.h" +/* + * File: z_en_tite.c + * Overlay: ovl_En_Tite + * Description: Tektites + */ -#define FLAGS 0x00000205 +#include "z_en_tite.h" +#include "objects/object_tite/object_tite.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_200) #define THIS ((EnTite*)thisx) @@ -9,7 +16,36 @@ void EnTite_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTite_Update(Actor* thisx, GlobalContext* globalCtx); void EnTite_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80893ED4(EnTite* this); +void func_80893F30(EnTite* this, GlobalContext* globalCtx); +void func_80893FD0(EnTite* this); +void func_80894024(EnTite* this, GlobalContext* globalCtx); +void func_8089408C(EnTite* this, GlobalContext* globalCtx); +void func_808942B4(EnTite* this, GlobalContext* globalCtx); +void func_80894414(EnTite* this); +void func_80894454(EnTite* this, GlobalContext* globalCtx); +void func_8089452C(EnTite* this, GlobalContext* globalCtx); +void func_808945B4(EnTite* this, GlobalContext* globalCtx); +void func_808945EC(EnTite* this); +void func_80894638(EnTite* this, GlobalContext* globalCtx); +void func_8089484C(EnTite* this); +void func_80894910(EnTite* this, GlobalContext* globalCtx); +void func_80894B2C(EnTite* this); +void func_80894BC8(EnTite* this, GlobalContext* globalCtx); +void func_80894E0C(EnTite* this, GlobalContext* globalCtx); +void func_80895020(EnTite* this, GlobalContext* globalCtx); +void func_808951B8(EnTite* this, GlobalContext* globalCtx); +void func_80895424(EnTite* this, GlobalContext* globalCtx); +void func_808955E4(EnTite* this); +void func_80895640(EnTite* this, GlobalContext* globalCtx); +void func_808956B8(EnTite* this); +void func_80895738(EnTite* this, GlobalContext* globalCtx); +void func_80895A10(EnTite* this); +void func_80895AC0(EnTite* this, GlobalContext* globalCtx); +void func_80895CB0(EnTite* this); +void func_80895D08(EnTite* this, GlobalContext* globalCtx); +void func_80895E28(EnTite* this, GlobalContext* globalCtx); + const ActorInit En_Tite_InitVars = { ACTOR_EN_TITE, ACTORCAT_ENEMY, @@ -22,15 +58,27 @@ const ActorInit En_Tite_InitVars = { (ActorFunc)EnTite_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80896AD0 = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_HARD, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_HIT6, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_HARD, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 0, { { 0, 1500, 0 }, 20 }, 100 }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80896AFC = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -65,129 +113,1068 @@ static DamageTable D_80896AFC = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80896B1C = { 2, 40, 40, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 40, 40, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80896B50[] = { +static TexturePtr D_80896B24[2][3] = { + { object_tite_Tex_001300, object_tite_Tex_001700, object_tite_Tex_001900 }, + { object_tite_Tex_001B00, object_tite_Tex_001F00, object_tite_Tex_002100 }, +}; + +static Color_RGBA8 D_80896B3C = { 250, 250, 250, 255 }; +static Color_RGBA8 D_80896B40 = { 180, 180, 180, 255 }; +static Vec3f D_80896B44 = { 0.0f, 0.45f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 70, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), - ICHAIN_F32(minVelocityY, -40, ICHAIN_CONTINUE), + ICHAIN_F32(terminalVelocity, -40, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -1000, ICHAIN_STOP), }; -#endif +static s32 D_80896B60 = 0; +static Vec3f D_80896B64 = { 0.0f, 0.3f, 0.0f }; -extern ColliderSphereInit D_80896AD0; -extern DamageTable D_80896AFC; -extern CollisionCheckInfoInit D_80896B1C; -extern InitChainEntry D_80896B50[]; +void EnTite_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTite* this = THIS; + s32 i; + s32 j; -extern UNK_TYPE D_060004F8; -extern UNK_TYPE D_0600069C; -extern UNK_TYPE D_0600083C; -extern UNK_TYPE D_06000A14; -extern UNK_TYPE D_06000C70; -extern UNK_TYPE D_060012E4; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_tite_Skel_003A20, &object_tite_Anim_0012E4, this->jointTable, + this->morphTable, 25); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 60.0f); + Actor_SetFocus(&this->actor, 20.0f); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + this->collider.dim.worldSphere.radius = sSphereInit.dim.modelSphere.radius; + this->unk_2C0 = 0x1D; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/EnTite_Init.s") + if (!D_80896B60) { + for (i = 0; i < ARRAY_COUNT(D_80896B24); i++) { + for (j = 0; j < ARRAY_COUNT(D_80896B24[0]); j++) { + D_80896B24[i][j] = Lib_SegmentedToVirtual(D_80896B24[i][j]); + } + } + D_80896B60 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/EnTite_Destroy.s") + if (this->actor.params == ENTITE_MINUS_3) { + this->actor.params = ENTITE_MINUS_2; + this->unk_2BE = 240; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.shape.yOffset = -3000.0f; + this->actor.shape.shadowDraw = NULL; + func_80895A10(this); + } else { + if (this->actor.params == ENTITE_MINUS_4) { + this->actor.params = ENTITE_MINUS_2; + this->unk_2BE = 240; + } else if (this->actor.params == ENTITE_MINUS_2) { + this->unk_2BE = 128; + } else { + this->unk_2BE = 64; + } + func_80893ED4(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893A18.s") + if (this->actor.params == ENTITE_MINUS_2) { + this->unk_2C0 |= 0x40; + this->actor.colChkInfo.health = 3; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893A34.s") +void EnTite_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTite* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893A9C.s") + Collider_DestroySphere(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893ADC.s") +void func_80893A18(EnTite* this) { + this->collider.base.colType = COLTYPE_HIT6; + this->collider.base.acFlags &= ~AC_HARD; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893B10.s") +s32 func_80893A34(EnTite* this, GlobalContext* globalCtx) { + if ((this->actor.params == ENTITE_MINUS_2) && (this->actor.bgCheckFlags & 1) && + (func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 5)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893B70.s") +void func_80893A9C(EnTite* this, GlobalContext* globalCtx) { + if (func_80893A34(this, globalCtx)) { + func_808956B8(this); + } else { + func_80893FD0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893BCC.s") +s32 func_80893ADC(EnTite* this) { + if ((this->actor.params == ENTITE_MINUS_2) && (this->actor.bgCheckFlags & 0x20)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893DD4.s") +s32 func_80893B10(EnTite* this) { + Math_StepToF(&this->actor.velocity.y, 0.0f, 2.0f); + return Math_StepToF(&this->actor.world.pos.y, (this->actor.world.pos.y + this->actor.depthInWater) - 1.0f, 2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893E54.s") +void func_80893B70(EnTite* this) { + if (this->actor.params == ENTITE_MINUS_2) { + if (this->actor.bgCheckFlags & 0x20) { + this->actor.gravity = 0.0f; + func_80893B10(this); + } else { + this->actor.gravity = -1.0f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893ED4.s") +void func_80893BCC(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp7C; + s32 i; + s32 j; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893F30.s") + if (this->actor.bgCheckFlags & 2) { + u32 surface = func_800C9BB8(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80893FD0.s") + if ((surface == COLPOLY_SURFACE_GROUND) || (surface == COLPOLY_SURFACE_SAND)) { + for (i = 5; i < ARRAY_COUNT(this->limbPos); i++) { + func_800BBFB0(globalCtx, &this->limbPos[i], 1.0f, 2, 80, 15, 1); + } + } else if (surface == COLPOLY_SURFACE_SNOW) { + Vec3f* ptr; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894024.s") + for (i = 5; i < ARRAY_COUNT(this->limbPos); i++) { + for (j = 0; j < 2; j++) { + ptr = &this->limbPos[i]; + 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, &gZeroVec3f, &D_80896B64, &D_80896B3C, &D_80896B40, + (s32)Rand_ZeroFloat(16.0f) + 80, 15); + } + } + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_8089408C.s") +void func_80893DD4(EnTite* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->collider.base.colType = COLTYPE_HIT3; + this->unk_2BC = 80; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffFrozenSteamScale = 0.75f; + this->drawDmgEffAlpha = 1.0f; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); + this->actor.flags &= ~ACTOR_FLAG_200; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808942B4.s") +void func_80893E54(EnTite* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider.base.colType = COLTYPE_HIT6; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 9, 2, 0.2f, 0.2f); + this->actor.flags |= ACTOR_FLAG_200; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894414.s") +void func_80893ED4(EnTite* this) { + Animation_MorphToLoop(&this->skelAnime, &object_tite_Anim_0012E4, 4.0f); + this->unk_2BC = Rand_S16Offset(15, 30); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80893F30; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894454.s") +void func_80893F30(EnTite* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + func_80893B70(this); + if (this->unk_2BC > 0) { + this->unk_2BC--; + } else if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && (this->actor.xzDistToPlayer < 300.0f) && + (this->actor.playerHeightRel < 80.0f)) { + func_808945EC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_8089452C.s") +void func_80893FD0(EnTite* this) { + Animation_PlayOnce(&this->skelAnime, &object_tite_Anim_00083C); + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_80894024; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808945B4.s") +void func_80894024(EnTite* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + func_8089408C(this, globalCtx); + } else { + func_80893B70(this); + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1000); + this->actor.world.rot.y = this->actor.shape.rot.y; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808945EC.s") +void func_8089408C(EnTite* this, GlobalContext* globalCtx) { + Animation_PlayOnce(&this->skelAnime, &object_tite_Anim_0004F8); + if (!func_80893ADC(this)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP); + } else { + this->actor.world.pos.y += this->actor.depthInWater; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP_WATER); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894638.s") + if (this->actor.shape.yOffset < 0.0f) { + s32 i; + Vec3f sp70; + Vec3f sp64; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_8089484C.s") + sp64.y = 3.0f; + this->actor.shape.yOffset = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894910.s") + for (i = 0; i < 4; i++) { + sp64.x = 2.0f * Math_SinS(this->actor.shape.rot.y); + sp64.z = 2.0f * Math_CosS(this->actor.shape.rot.y); + sp70.x = this->actor.world.pos.x + (12.5f * sp64.x); + sp70.y = this->actor.world.pos.y + 15.0f; + sp70.z = this->actor.world.pos.z + (12.5f * sp64.z); + func_800B0DE0(globalCtx, &sp70, &sp64, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); + this->actor.shape.rot.y += 0x4000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894B2C.s") + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.flags |= ACTOR_FLAG_1; + this->actor.velocity.y = 10.0f; + } else { + this->actor.velocity.y = 8.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894BC8.s") + this->actor.bgCheckFlags &= ~(0x40 | 0x20 | 0x2 | 0x1); + this->actor.gravity = -1.0f; + this->actor.speedXZ = 4.0f; + this->actionFunc = func_808942B4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894DD0.s") +void func_808942B4(EnTite* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (((this->actor.bgCheckFlags & 1) || (func_80893ADC(this) && (this->actor.depthInWater > 0.0f))) && + (this->actor.velocity.y <= 0.0f)) { + this->actor.speedXZ = 0.0f; + this->collider.base.atFlags &= ~AT_HIT; + if (!func_80893ADC(this)) { + func_80893BCC(this, globalCtx); + func_80894414(this); + } else { + this->actor.gravity = 0.0f; + if (this->actor.velocity.y < -8.0f) { + func_8089452C(this, globalCtx); + } else { + this->actor.velocity.y = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_LAND_WATER2); + func_80894414(this); + } + } + } else if (!(this->collider.base.atFlags & AT_HIT)) { + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.atFlags &= ~AT_HIT; + func_80894B2C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80894E0C.s") +void func_80894414(EnTite* this) { + Animation_PlayOnce(&this->skelAnime, &object_tite_Anim_00069C); + this->actionFunc = func_80894454; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895020.s") +void func_80894454(EnTite* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (this->actor.xzDistToPlayer > 450.0f) || + (this->actor.playerHeightRel > 80.0f)) { + func_80893ED4(this); + } else if (!Actor_IsFacingPlayer(&this->actor, 0x2328)) { + func_808945EC(this); + } else { + func_80893A9C(this, globalCtx); + } + } else { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1500); + func_80893B70(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808951B8.s") +void func_8089452C(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808952EC.s") + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + sp2C.y += this->actor.depthInWater; + this->actor.velocity.y *= 0.75f; + EffectSsGRipple_Spawn(globalCtx, &sp2C, 0, 500, 0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_LAND_WATER); + this->actionFunc = func_808945B4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895424.s") +void func_808945B4(EnTite* this, GlobalContext* globalCtx) { + if (func_80893B10(this)) { + func_80894414(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808955E4.s") +void func_808945EC(EnTite* this) { + Animation_PlayLoop(&this->skelAnime, &object_tite_Anim_000A14); + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actionFunc = func_80894638; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895640.s") +void func_80894638(EnTite* this, GlobalContext* globalCtx) { + s16 temp_v0; + s16 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808956B8.s") + func_80893B70(this); + temp_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (temp_v0 > 0) { + temp_v1 = (s32)(temp_v0 * (1.0f / 42.0f)) + 10; + } else { + temp_v1 = (s32)(temp_v0 * (1.0f / 42.0f)) - 10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808956FC.s") + this->actor.shape.rot.y = this->actor.shape.rot.y + (temp_v1 * 2); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->skelAnime.playSpeed = temp_v1 * 0.01f; + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895738.s") + if (Animation_OnFrame(&this->skelAnime, 7.0f)) { + if (func_80893ADC(this)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_WALK_WATER); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_WALK); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_8089595C.s") + if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (this->actor.xzDistToPlayer > 450.0f) || + (this->actor.playerHeightRel > 80.0f)) { + func_80893ED4(this); + } else if (((this->actor.bgCheckFlags & 1) || (func_80893ADC(this) && (this->actor.depthInWater < 10.0f))) && + Actor_IsFacingPlayer(&this->actor, 0xE38)) { + if ((this->actor.xzDistToPlayer <= 180.0f) && (this->actor.playerHeightRel <= 80.0f)) { + func_80893A9C(this, globalCtx); + } else { + func_8089484C(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895A10.s") +void func_8089484C(EnTite* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_tite_Anim_000C70, -3.0f); + if (this->actionFunc != func_80894910) { + this->unk_2B8 = Rand_S16Offset(1, 3); + } + this->actor.velocity.y = 9.5f; + this->actor.gravity = -1.0f; + this->actor.speedXZ = 4.0f; + if (func_80893ADC(this)) { + this->actor.world.pos.y += this->actor.depthInWater; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP_WATER); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP); + } + this->actionFunc = func_80894910; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895AC0.s") +void func_80894910(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895CB0.s") + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 1.0f, 0.0f); + SkelAnime_Update(&this->skelAnime); + if (this->actor.bgCheckFlags & 0x40) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_LAND_WATER); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895D08.s") + if (func_80893ADC(this)) { + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp34.y += this->actor.depthInWater; + this->actor.velocity.y *= 0.75f; + EffectSsGRipple_Spawn(globalCtx, &sp34, 0, 500, 0); + } + } else { + func_80893BCC(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895DE8.s") + if (((this->actor.bgCheckFlags & 1) || (func_80893ADC(this) && (this->actor.depthInWater > 0.0f))) && + (this->actor.velocity.y <= 0.0f)) { + this->actor.speedXZ = 0.0f; + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4000); + this->actor.world.rot.y = this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895E28.s") + if (func_80893ADC(this)) { + this->actor.gravity = 0.0f; + if (!func_80893B10(this)) { + return; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80895FF8.s") + if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (this->actor.xzDistToPlayer > 450.0f) || + (this->actor.playerHeightRel > 80.0f)) { + func_80893ED4(this); + } else if ((this->actor.xzDistToPlayer <= 180.0f) && (this->actor.playerHeightRel <= 80.0f)) { + func_808945EC(this); + } else { + func_8089484C(this); + } + } else { + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1000); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_808963B4.s") +void func_80894B2C(EnTite* this) { + Animation_MorphToLoop(&this->skelAnime, &object_tite_Anim_0012E4, 4.0f); + this->actor.speedXZ = -6.0f; + this->actor.gravity = -1.0f; + if (this->collider.base.ac != NULL) { + func_800BE568(&this->actor, &this->collider); + } else { + this->actor.world.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); + } + this->actor.world.rot.y += 0x8000; + this->actionFunc = func_80894BC8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/EnTite_Update.s") +void func_80894BC8(EnTite* this, GlobalContext* globalCtx) { + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 1.0f, 0.5f, 0.0f); + SkelAnime_Update(&this->skelAnime); + if (func_80893ADC(this) && (this->actor.velocity.y <= 0.0f)) { + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y += this->actor.depthInWater - 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80896750.s") + if (this->actor.bgCheckFlags & 0x40) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_LAND_WATER2); + } else { + func_80893BCC(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/func_80896788.s") + if ((this->actor.speedXZ == 0.0f) && ((this->actor.bgCheckFlags & 1) || func_80893ADC(this))) { + this->actor.world.rot.y = this->actor.shape.rot.y; + this->collider.base.acFlags |= AC_ON; + if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || + (((this->actor.xzDistToPlayer > 450.0f) || (this->actor.playerHeightRel > 80.0f)) && + (ABS_ALT(this->actor.shape.rot.x) < 4000) && (ABS_ALT(this->actor.shape.rot.z) < 4000))) { + func_80893ED4(this); + } else if ((this->actor.xzDistToPlayer < 180.0f) && (this->actor.playerHeightRel <= 80.0f) && + Actor_IsFacingPlayer(&this->actor, 0x1770)) { + func_80893A9C(this, globalCtx); + } else { + func_8089484C(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tite/EnTite_Draw.s") +void func_80894DD0(EnTite* this) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = 0.0f; + } + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_80894E0C; +} + +void func_80894E0C(EnTite* this, GlobalContext* globalCtx) { + if (this->unk_2BC != 0) { + this->unk_2BC--; + } + + if ((func_80893ADC(this) != 0) && (this->actor.velocity.y <= 0.0f)) { + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y += this->actor.depthInWater; + } + + if (this->actor.bgCheckFlags & 0x40) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_LAND_WATER2); + } else { + func_80893BCC(this, globalCtx); + } + + if (this->unk_2BC == 0) { + func_80893E54(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + func_80895020(this, globalCtx); + } else if (this->unk_2B9 != 0) { + func_808955E4(this); + } else if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || + (((this->actor.xzDistToPlayer > 450.0f) || (this->actor.playerHeightRel > 80.0f)) && + (ABS_ALT(this->actor.shape.rot.x) < 4000) && (ABS_ALT(this->actor.shape.rot.z) < 4000))) { + func_80893ED4(this); + } else if ((this->actor.xzDistToPlayer < 180.0f) && (this->actor.playerHeightRel <= 80.0f) && + Actor_IsFacingPlayer(&this->actor, 0x1770)) { + func_80893A9C(this, globalCtx); + } else { + func_8089484C(this); + } + } +} + +void func_80895020(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp74; + s32 i; + f32 temp_f0; + Vec3f* ptr; + + this->actor.speedXZ = 0.0f; + this->collider.base.acFlags &= ~AC_ON; + this->actor.colorFilterTimer = 0; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_TEKU_DEAD); + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; + this->unk_2BA = 1; + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, this->unk_2BE); + this->unk_2BC = 25; + this->actor.gravity = -0.58f; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + + ptr = &this->unk_33C[0]; + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++, ptr++) { + Math_Vec3f_Diff(&this->limbPos[i], &this->actor.world.pos, &sp74); + temp_f0 = Math3D_Vec3fMagnitude(&sp74); + if (temp_f0 > 1.0f) { + temp_f0 = 1.2f / temp_f0; + } + + ptr->x = sp74.x * temp_f0; + ptr->z = sp74.z * temp_f0; + ptr->y = Rand_ZeroFloat(3.5f) + 5.5f; + } + this->actionFunc = func_808951B8; +} + +void func_808951B8(EnTite* this, GlobalContext* globalCtx) { + s32 i; + + this->unk_2BC--; + Math_SmoothStepToS(&this->actor.world.rot.z, 0x4000, 4, 0x1000, 0x400); + + if (this->unk_2BC == 0) { + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { + func_800B3030(globalCtx, &this->limbPos[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 1); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->limbPos[i], 11, NA_SE_EN_EXTINCT); + } + Actor_MarkForDeath(&this->actor); + } else { + for (i = 0; i < ARRAY_COUNT(this->unk_33C); i++) { + Math_Vec3f_Sum(&this->limbPos[i], &this->unk_33C[i], &this->limbPos[i]); + this->unk_33C[i].y += this->actor.gravity; + } + } +} + +void func_808952EC(EnTite* this) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &object_tite_Anim_000A14, 1.5f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_GROW_HEAD); + this->collider.base.acFlags &= ~AC_ON; + func_80893A18(this); + this->unk_2B9 = 1; + this->unk_2BC = 400; + this->actor.speedXZ = 0.0f; + this->actor.gravity = -1.0f; + this->unk_2B8 = Rand_ZeroOne() * 50.0f; + this->actor.bgCheckFlags &= ~1; + this->actor.velocity.y = 11.0f; + this->actionFunc = func_80895424; +} + +void func_80895424(EnTite* this, GlobalContext* globalCtx) { + Math_ScaledStepToS(&this->actor.shape.rot.z, -0x8000, 4000); + if (this->unk_2B8 != 0) { + this->unk_2B8--; + } else { + this->unk_2B8 = Rand_ZeroOne() * 30.0f; + this->skelAnime.curFrame = Rand_ZeroOne() * 5.0f; + } + + SkelAnime_Update(&this->skelAnime); + + if (this->actor.bgCheckFlags & 1) { + this->collider.base.acFlags |= AC_ON; + if (this->actor.bgCheckFlags & 2) { + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 20.0f, 11, 4.0f, 0, 0, 0); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + + if (this->unk_2BC == 0) { + func_808955E4(this); + } else { + this->unk_2BC--; + } + } else if (this->actor.shape.yOffset < 2800.0f) { + this->actor.shape.yOffset += 400.0f; + } +} + +void func_808955E4(EnTite* this) { + this->unk_2B9 = 0; + this->actor.velocity.y = 13.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_LAST1_GROW_HEAD); + this->actor.bgCheckFlags &= ~1; + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = func_80895640; +} + +void func_80895640(EnTite* this, GlobalContext* globalCtx) { + Math_ScaledStepToS(&this->actor.shape.rot.z, 0, 4000); + SkelAnime_Update(&this->skelAnime); + if (this->actor.bgCheckFlags & 1) { + this->collider.base.acFlags |= AC_ON; + this->actor.shape.yOffset = 0.0f; + func_80893BCC(this, globalCtx); + func_80893ED4(this); + } +} + +void func_808956B8(EnTite* this) { + this->unk_2BC = 400; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->collider.base.colType = COLTYPE_HARD; + this->collider.base.acFlags |= AC_HARD; + this->actor.gravity = -1.0f; + this->actionFunc = func_80895738; +} + +void func_808956FC(EnTite* this) { + this->unk_2BC = -1; + this->actor.bgCheckFlags &= ~1; + this->actor.velocity.y = 7.5f; + func_80893A18(this); +} + +void func_80895738(EnTite* this, GlobalContext* globalCtx) { + func_80893BCC(this, globalCtx); + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + this->actor.world.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); + if (this->collider.base.atFlags & AT_BOUNCED) { + func_808956FC(this); + } + } else if (this->actor.bgCheckFlags & 8) { + this->actor.world.rot.y = BINANG_SUB((this->actor.wallYaw * 2) - this->actor.world.rot.y, 0x8000); + } + + if (this->unk_2BC == -1) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.3f); + if (this->actor.bgCheckFlags & 1) { + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80893ED4(this); + this->unk_2BC = 100; + } + } else if (this->unk_2BC > 0) { + this->unk_2BC--; + Math_StepToF(&this->actor.speedXZ, 10.0f, 0.3f); + this->actor.flags |= ACTOR_FLAG_1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (!func_80893A34(this, globalCtx)) { + this->unk_2BC = 0; + } + } else if ((this->unk_2BC == 0) && Math_StepToF(&this->actor.speedXZ, 0.0f, 0.3f)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80893A18(this); + if ((Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (this->actor.xzDistToPlayer > 450.0f) || + (this->actor.playerHeightRel > 80.0f)) { + func_80893ED4(this); + } else if (!Actor_IsFacingPlayer(&this->actor, 0x2328)) { + func_808945EC(this); + } else { + func_80893A9C(this, globalCtx); + } + } + this->actor.shape.rot.y += (s16)(this->actor.speedXZ * 768.0f); +} + +void func_8089595C(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + 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, &gZeroVec3f, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); +} + +void func_80895A10(EnTite* this) { + s32 pad; + s16 rand; + + Animation_Change(&this->skelAnime, &object_tite_Anim_000A14, 2.0f, 0.0f, 0.0f, 0, 4.0f); + this->actor.speedXZ = 0.0f; + rand = Rand_S16Offset(20, 20); + this->unk_2BC = ((Rand_ZeroOne() < 0.5f) ? -1 : 1) * rand; + this->actionFunc = func_80895AC0; +} + +void func_80895AC0(EnTite* this, GlobalContext* globalCtx) { + s16 temp_v1; + s32 temp_v0; + + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 7.0f)) { + if (Rand_ZeroOne() < 0.25f) { + func_8089595C(this, globalCtx); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_WALK); + } + + if ((this->unk_2BC == 1) || (this->unk_2BC == -1)) { + if (this->actor.bgCheckFlags & 8) { + temp_v1 = this->actor.shape.rot.y - this->actor.wallYaw; + temp_v0 = ABS_ALT(temp_v1); + if (temp_v0 > 0x3000) { + this->unk_2BC = (temp_v0 >> 9) * this->unk_2BC; + } + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 200.0f) { + temp_v1 = this->actor.shape.rot.y - Actor_YawToPoint(&this->actor, &this->actor.home.pos); + temp_v0 = ABS_ALT(temp_v1); + if (temp_v0 > 0x2000) { + this->unk_2BC = (temp_v0 >> 9) * this->unk_2BC; + } + } + } + + if ((this->actor.xzDistToPlayer < 240.0f) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + func_8089408C(this, globalCtx); + } else if (this->unk_2BC > 0) { + this->unk_2BC--; + this->actor.shape.rot.y += 0x100; + } else if (this->unk_2BC < 0) { + this->unk_2BC++; + this->actor.shape.rot.y -= 0x100; + } else { + func_80895CB0(this); + } +} + +void func_80895CB0(EnTite* this) { + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 1.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_2BC = Rand_S16Offset(20, 20); + this->actionFunc = func_80895D08; +} + +void func_80895D08(EnTite* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if (Animation_OnFrame(&this->skelAnime, 7.0f)) { + if (Rand_ZeroOne() < 0.5f) { + func_8089595C(this, globalCtx); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_WALK); + } + if ((this->actor.xzDistToPlayer < 240.0f) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + func_8089408C(this, globalCtx); + } else { + this->unk_2BC--; + if (this->unk_2BC == 0) { + func_80895A10(this); + } + } +} + +void func_80895DE8(EnTite* this) { + this->collider.base.acFlags &= ~AC_ON; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->skelAnime.playSpeed = 1.0f; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80895E28; +} + +void func_80895E28(EnTite* this, GlobalContext* globalCtx) { + Vec3f sp44; + Vec3f sp38; + s16 sp36; + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y += 0x1E00; + + sp44.x = (Math_SinS(this->actor.shape.rot.y) * 25.0f) + this->actor.world.pos.x; + sp44.y = this->actor.world.pos.y + 15.0f; + sp44.z = (Math_CosS(this->actor.shape.rot.y) * 25.0f) + this->actor.world.pos.z; + + sp36 = BINANG_SUB(this->actor.shape.rot.y, 0x4000); + + sp38.x = 2.0f * Math_SinS(sp36); + sp38.y = 3.0f; + sp38.z = 2.0f * Math_CosS(sp36); + + func_800B0DE0(globalCtx, &sp44, &sp38, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); + + sp44.x = (2.0f * this->actor.world.pos.x) - sp44.x; + sp44.z = (2.0f * this->actor.world.pos.z) - sp44.z; + sp38.x *= -1.0f; + sp38.z *= -1.0f; + + func_800B0DE0(globalCtx, &sp44, &sp38, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); + + if (Math_StepToF(&this->actor.shape.yOffset, 0.0f, 200.0f)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->collider.base.acFlags |= AC_ON; + func_808945EC(this); + } +} + +void func_80895FF8(EnTite* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + this->collider.base.atFlags &= ~AT_HIT; + if (this->collider.base.colType == COLTYPE_HARD) { + func_808956FC(this); + func_800BE568(&this->actor, &this->collider); + return; + } + + Actor_SetDropFlag(&this->actor, &this->collider.info); + + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + func_80893E54(this, globalCtx); + if (this->actor.shape.yOffset < 0.0f) { + func_80895DE8(this); + return; + } + + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + if (this->actor.colChkInfo.damageEffect != 0xF) { + if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_2BC = 40; + Actor_SetColorFilter(&this->actor, 0, 200, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_LARGE; + this->drawDmgEffScale = 0.5f; + this->drawDmgEffAlpha = 2.0f; + func_80894DD0(this); + return; + } + + if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2BC = 40; + Actor_SetColorFilter(&this->actor, 0, 200, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_80894DD0(this); + return; + } + + if (this->actor.colChkInfo.damageEffect == 3) { + func_80893DD4(this); + if (this->actor.colChkInfo.health == 0) { + this->unk_2BC = 3; + this->collider.base.acFlags &= ~AC_ON; + } + func_80894DD0(this); + return; + } + + if (this->actor.colChkInfo.damageEffect == 2) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.5f; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.5f; + 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); + } + + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 8); + + if (this->actor.colChkInfo.health == 0) { + func_80895020(this, globalCtx); + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_DAMAGE); + + if (this->unk_2B9 == 0) { + func_80894B2C(this); + this->collider.base.acFlags &= ~AC_ON; + } else { + func_808955E4(this); + } + } + } + } + } else if ((this->actor.bgCheckFlags & 1) && (this->collider.base.acFlags & AC_ON) && + (this->actor.colChkInfo.health != 0) && (globalCtx->actorCtx.unk2 != 0) && + (this->actor.xyzDistToPlayerSq < SQ(200.0f))) { + this->actor.flags |= ACTOR_FLAG_1; + if (this->actor.shape.yOffset < 0.0f) { + this->actor.shape.yOffset = 0.0f; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + } + if (this->unk_2B9 != 0) { + func_808955E4(this); + } else { + func_808952EC(this); + } + } +} + +void func_808963B4(EnTite* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp48; + + if (this->actor.bgCheckFlags & 0x40) { + for (i = 5; i < ARRAY_COUNT(this->limbPos); i++) { + Math_Vec3f_Copy(&sp48, &this->limbPos[i]); + sp48.y = this->actor.world.pos.y + this->actor.depthInWater; + EffectSsGRipple_Spawn(globalCtx, &sp48, 0, 220, 0); + } + } else if (this->actor.bgCheckFlags & 0x20) { + s32 temp = globalCtx->gameplayFrames & 7; + + if (!(temp & 1) && (this->actor.depthInWater < 10.0f)) { + Math_Vec3f_Copy(&sp48, &this->limbPos[5 + (temp >> 1)]); + sp48.y = this->actor.world.pos.y + this->actor.depthInWater; + EffectSsGRipple_Spawn(globalCtx, &sp48, 0, 220, 0); + } + } +} + +void EnTite_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTite* this = THIS; + + func_80895FF8(this, globalCtx); + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != func_808951B8) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 25.0f, 40.0f, 20.0f, this->unk_2C0); + func_808963B4(this, globalCtx); + if (this->actor.bgCheckFlags & 1) { + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &this->actor.shape.rot); + if (this->unk_2B9 != 0) { + this->actor.shape.rot.z = BINANG_ROT180(this->actor.shape.rot.z); + } + } else { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 1000); + if (this->unk_2B9 == 0) { + Math_ScaledStepToS(&this->actor.shape.rot.z, 0, 1000); + if (this->actor.shape.yOffset > 0.0f) { + this->actor.shape.yOffset -= 400.0f; + } + } + } + + Actor_SetFocus(&this->actor, this->actor.scale.y * 2000.0f); + this->collider.dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.dim.worldSphere.center.y = (s32)this->actor.world.pos.y + 15; + this->collider.dim.worldSphere.center.z = this->actor.world.pos.z; + + 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->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.25f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.5f); + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.5f, 0.0125f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + } +} + +s32 EnTite_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTite* this = THIS; + + if (this->unk_2BA == -1) { + this->unk_3A8 = *dList; + *dList = NULL; + } + return false; +} + +void EnTite_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static s8 D_80896B70[] = { + -1, -1, -1, -1, 0, -1, -1, -1, 1, -1, -1, -1, -1, 2, -1, -1, -1, -1, 3, -1, -1, -1, -1, 4, -1, + }; + static s8 D_80896B8C[] = { + -1, -1, -1, -1, 0, -1, -1, -1, 1, 5, -1, -1, -1, 2, 6, -1, -1, -1, 3, 7, -1, -1, -1, 4, 8, + }; + EnTite* this = THIS; + MtxF* matrix; + s8 idx; + + if (this->unk_2BA == 0) { + idx = D_80896B70[limbIndex]; + if (idx != -1) { + Matrix_MultZero(&this->limbPos[idx]); + if (idx >= 1) { + Matrix_MultVecX(2500.0f, &this->limbPos[idx + 4]); + } + } + } else if (this->unk_2BA > 0) { + if (D_80896B8C[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[D_80896B8C[limbIndex]]); + } + + if (limbIndex == 24) { + this->unk_2BA = -1; + } + } else if (D_80896B8C[limbIndex] != -1) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + matrix = Matrix_GetCurrent(); + matrix->xw = this->limbPos[D_80896B8C[limbIndex]].x; + matrix->yw = this->limbPos[D_80896B8C[limbIndex]].y; + matrix->zw = this->limbPos[D_80896B8C[limbIndex]].z; + Matrix_RotateZS(this->actor.world.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++, this->unk_3A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnTite_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTite* this = THIS; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_OPA_DISP; + + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + + if (this->actor.params == ENTITE_MINUS_2) { + gSPSegment(&gfx[1], 0x08, D_80896B24[0][0]); + gSPSegment(&gfx[2], 0x09, D_80896B24[0][1]); + gSPSegment(&gfx[3], 0x0A, D_80896B24[0][2]); + } else { + gSPSegment(&gfx[1], 0x08, D_80896B24[1][0]); + gSPSegment(&gfx[2], 0x09, D_80896B24[1][1]); + gSPSegment(&gfx[3], 0x0A, D_80896B24[1][2]); + } + + POLY_OPA_DISP = &gfx[4]; + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnTite_OverrideLimbDraw, + EnTite_PostLimbDraw, &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->drawDmgEffScale, + this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, this->drawDmgEffType); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.h b/src/overlays/actors/ovl_En_Tite/z_en_tite.h index cf6939425..24f3bd630 100644 --- a/src/overlays/actors/ovl_En_Tite/z_en_tite.h +++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.h @@ -7,11 +7,34 @@ struct EnTite; typedef void (*EnTiteActionFunc)(struct EnTite*, GlobalContext*); +enum { + /* -4 */ ENTITE_MINUS_4 = -4, + /* -3 */ ENTITE_MINUS_3, + /* -2 */ ENTITE_MINUS_2, + /* -1 */ ENTITE_MINUS_1, + /* 0 */ ENTITE_MINUS_0, +}; + typedef struct EnTite { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x170]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[25]; + /* 0x021E */ Vec3s morphTable[25]; /* 0x02B4 */ EnTiteActionFunc actionFunc; - /* 0x02B8 */ char unk_2B8[0x14C]; + /* 0x02B8 */ u8 unk_2B8; + /* 0x02B9 */ u8 unk_2B9; + /* 0x02BA */ s8 unk_2BA; + /* 0x02BB */ u8 drawDmgEffType; + /* 0x02BC */ s16 unk_2BC; + /* 0x02BE */ s16 unk_2BE; + /* 0x02C0 */ s32 unk_2C0; + /* 0x02C4 */ f32 drawDmgEffAlpha; + /* 0x02C8 */ f32 drawDmgEffScale; + /* 0x02CC */ f32 drawDmgEffFrozenSteamScale; + /* 0x02D0 */ Vec3f limbPos[9]; + /* 0x033C */ Vec3f unk_33C[9]; + /* 0x03A8 */ Gfx* unk_3A8; + /* 0x03AC */ ColliderSphere collider; } EnTite; // size = 0x404 extern const ActorInit En_Tite_InitVars; 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 de2c1fe1e..4f61ac43f 100644 --- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -1,6 +1,15 @@ -#include "z_en_tk.h" +/* + * File: z_en_tk.c + * Overlay: ovl_En_Tk + * Description: Dampé + */ -#define FLAGS 0x00000009 +#include "z_en_tk.h" +#include "overlays/actors/ovl_Bg_Danpei_Movebg/z_bg_danpei_movebg.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" +#include "objects/object_tk/object_tk.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnTk*)thisx) @@ -9,20 +18,57 @@ void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTk_Update(Actor* thisx, GlobalContext* globalCtx); void EnTk_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80AECA3C(EnTk* this, GlobalContext* globalCtx); void func_80AECA90(EnTk* this, GlobalContext* globalCtx); +void func_80AECB0C(EnTk* this, GlobalContext* globalCtx); void func_80AECB6C(EnTk* this, GlobalContext* globalCtx); +void func_80AECE0C(EnTk* this, GlobalContext* globalCtx); +s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx); +s32 func_80AED354(EnTk* this, GlobalContext* globalCtx, ScheduleResult* arg2); +s32 func_80AED38C(EnTk* this, GlobalContext* globalCtx, ScheduleResult* arg2); +void func_80AED4F8(EnTk* this, GlobalContext* globalCtx); void func_80AED610(EnTk* this, GlobalContext* globalCtx); +void func_80AED898(EnTk* this, GlobalContext* globalCtx); void func_80AED940(EnTk* this, GlobalContext* globalCtx); void func_80AEDC4C(EnTk* this, GlobalContext* globalCtx); +void func_80AEDCBC(EnTk* this, GlobalContext* globalCtx); void func_80AEDD4C(EnTk* this, GlobalContext* globalCtx); +void func_80AEDE10(EnTk* this, GlobalContext* globalCtx); void func_80AEDF5C(EnTk* this, GlobalContext* globalCtx); +void func_80AEE2A8(EnTk* this, GlobalContext* globalCtx); void func_80AEE2C0(EnTk* this, GlobalContext* globalCtx); +void func_80AEE374(EnTk* this, GlobalContext* globalCtx); void func_80AEE414(EnTk* this, GlobalContext* globalCtx); +void func_80AEE478(EnTk* this, GlobalContext* globalCtx); void func_80AEE4D0(EnTk* this, GlobalContext* globalCtx); +void func_80AEE650(EnTk* this, GlobalContext* globalCtx); void func_80AEE6B8(EnTk* this, GlobalContext* globalCtx); +void func_80AEE784(EnTk* this, GlobalContext* globalCtx); void func_80AEE9B0(EnTk* this, GlobalContext* globalCtx); +void func_80AEEAD4(EnTk* this, GlobalContext* globalCtx); +void func_80AEEB88(EnTk* this, GlobalContext* globalCtx); +void func_80AEED38(EnTk* this, GlobalContext* globalCtx); +void func_80AEF048(EnTk* this, GlobalContext* globalCtx); +void func_80AEF094(EnTk* this, GlobalContext* globalCtx); +void func_80AEF15C(EnTk* this, GlobalContext* globalCtx); +void func_80AEF1B4(EnTk* this, GlobalContext* globalCtx); +void func_80AEF1C4(EnTk* this, GlobalContext* globalCtx); +void func_80AEF210(EnTk* this, GlobalContext* globalCtx); +void func_80AEF220(EnTk* this, GlobalContext* globalCtx); +void func_80AEF278(EnTk* this, GlobalContext* globalCtx); +void func_80AEF2C8(Actor* thisx, GlobalContext* globalCtx); +void func_80AEF2D8(Actor* thisx, GlobalContext* globalCtx); +void func_80AEF5F4(Actor* thisx, GlobalContext* globalCtx); + +static s32 D_80AF0050; + +static u8 D_80AEF800[] = { + /* 0x0 */ SCHEDULE_CMD_CHECK_TIME_RANGE_L(6, 0, 18, 0, 0x8 - 0x7), + /* 0x7 */ SCHEDULE_CMD_RET_NONE(), + /* 0x8 */ SCHEDULE_CMD_RET_TIME(6, 0, 18, 0, 1), + /* 0xE */ SCHEDULE_CMD_RET_NONE(), +}; -#if 0 const ActorInit En_Tk_InitVars = { ACTOR_EN_TK, ACTORCAT_NPC, @@ -35,130 +81,1312 @@ const ActorInit En_Tk_InitVars = { (ActorFunc)EnTk_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AEF830 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 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_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 30, 52, 0, { 0, 0, 0 } }, }; -#endif +// part of the collider?? +static u32 D_80AEF85C[] = { + 0x00000000, + 0x00000000, + 0xFF000000, +}; -extern ColliderCylinderInit D_80AEF830; +static AnimationSpeedInfo D_80AEF868[] = { + { &object_tk_Anim_001FA8, 1.0f, ANIMMODE_LOOP, -10.0f }, { &object_tk_Anim_001FA8, 2.0f, ANIMMODE_LOOP, -10.0f }, + { &object_tk_Anim_0030A4, 1.0f, ANIMMODE_LOOP, -10.0f }, { &object_tk_Anim_001144, 1.0f, ANIMMODE_ONCE, -10.0f }, + { &object_tk_Anim_003724, 1.0f, ANIMMODE_ONCE, -10.0f }, { &object_tk_Anim_003FB8, 1.0f, ANIMMODE_LOOP, -10.0f }, + { &object_tk_Anim_0020C8, 1.0f, ANIMMODE_LOOP, -10.0f }, { &object_tk_Anim_003B10, 1.0f, ANIMMODE_LOOP, -10.0f }, +}; -extern UNK_TYPE D_0600B530; -extern UNK_TYPE D_0600B9E8; +static s32 D_80AEF8E8[2] = { 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEC460.s") +static f32 D_80AEF8F0[] = { + 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, + 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, 0.637399971485f, + 1.88639998436f, 3.44770002365f, 5.29629993439f, 7.39470005035f, 9.60550022125f, 11.9537000656f, + 14.30189991f, 16.6000995636f, 18.8108997345f, 20.8342990875f, 22.6203994751f, 24.1441993713f, + 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, + 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, 25.3057994843f, + 25.3057994843f, 26.5048999786f, 28.0412006378f, 29.9146995544f, 31.9881000519f, 34.2238998413f, + 36.572101593f, 38.932800293f, 41.28099823f, 43.5416984558f, 45.6276016235f, 47.4511985779f, + 49.0f, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEC524.s") +typedef struct { + /* 0x00 */ Actor* unk_00; + /* 0x04 */ f32 unk_04; +} EnTkStruct; // size = 0x8? -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEC658.s") +void func_80AEC460(EnTk* this) { + if (DECR(this->unk_2C4) == 0) { + this->unk_2C2++; + if (this->unk_2C2 >= 3) { + this->unk_2C0--; + if (this->unk_2C0 < 0) { + this->unk_2C4 = Rand_S16Offset(30, 30); + this->unk_2C0 = 2; + if (Rand_ZeroOne() > 0.5f) { + this->unk_2C0++; + } + } + this->unk_2C2 = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/EnTk_Init.s") +f32 func_80AEC524(f32 arg0) { + f32 temp_f0; + f32 ret; + s32 temp_a0; + s32 temp_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/EnTk_Destroy.s") + while ((arg0 >= ARRAY_COUNT(D_80AEF8F0)) || (arg0 < 0.0f)) { + if (arg0 >= ARRAY_COUNT(D_80AEF8F0)) { + arg0 -= ARRAY_COUNT(D_80AEF8F0); + } else if (arg0 < 0.0f) { + arg0 += ARRAY_COUNT(D_80AEF8F0); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECA3C.s") + // temp_f0 always becomes 0 + temp_a1 = arg0; + temp_a0 = temp_a1 + 1; + temp_f0 = arg0 - temp_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECA90.s") + if (arg0 != temp_a1) { + if (temp_a0 >= ARRAY_COUNT(D_80AEF8F0)) { + temp_a0 -= ARRAY_COUNT(D_80AEF8F0); + ret = (((D_80AEF8F0[temp_a0] + D_80AEF8F0[ARRAY_COUNT(D_80AEF8F0) - 1]) - D_80AEF8F0[temp_a1]) * temp_f0) + + D_80AEF8F0[temp_a1]; + } else { + ret = ((D_80AEF8F0[temp_a0] - D_80AEF8F0[temp_a1]) * temp_f0) + D_80AEF8F0[temp_a1]; + } + } else { + ret = D_80AEF8F0[temp_a1]; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECB0C.s") +void func_80AEC658(SkelAnime* skelAnime, f32 arg1, f32 arg2, f32* arg3, f32* arg4) { + static f32 D_80AEF9B4[] = { 0.95f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 1.25f, 1.48f, 1.68f, 1.77f, 1.88f, 1.88f, 1.84f, + 1.77f, 1.62f, 1.43f, 1.22f, 0.93f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.96f, 1.23f, 1.5f, + 1.66f, 1.79f, 1.88f, 1.89f, 1.88f, 1.81f, 1.67f, 1.46f, 1.24f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECB6C.s") + *arg3 = D_80AEF9B4[(s32)skelAnime->curFrame] * 0.5f * skelAnime->playSpeed * arg2; + *arg4 = (func_80AEC524(skelAnime->curFrame) - func_80AEC524(arg1)) * arg2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECE0C.s") + while (*arg4 < 0.0f) { + *arg4 += D_80AEF8F0[(s32)skelAnime->animLength - 1] * arg2; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AECE60.s") +void EnTk_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTk* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED354.s") + this->unk_2B0 = ENTK_GET_F(&this->actor); + this->unk_2B1 = ENTK_GET_7F0(&this->actor); + Collider_InitCylinder(globalCtx, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED38C.s") + if (Flags_GetSwitch(globalCtx, this->unk_2B1)) { + if (this->unk_2B0 == 0) { + Actor_MarkForDeath(&this->actor); + return; + } + } else if (this->unk_2B0 == 2) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED4F8.s") + if ((this->unk_2B0 == 1) || (this->unk_2B0 == 3)) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.update = func_80AEF2C8; + this->actor.draw = NULL; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED544.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tk_Skel_00B9E8, NULL, this->jointTable, this->morphTable, + 18); + Animation_Change(&this->skelAnime, &object_tk_Anim_0030A4, 1.0f, 0.0f, + Animation_GetLastFrame(&object_tk_Anim_0030A4.common), 0, 0.0f); + this->unk_318 = 0; + this->unk_2D4 = -1; + Actor_SetScale(&this->actor, 0.01f); + this->actor.targetMode = 1; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED610.s") + if (this->unk_2B0 == 2) { + this->unk_316 = 0; + this->actor.update = func_80AEF5F4; + func_80AECA3C(this, globalCtx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED898.s") + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.gravity = -1.0f; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.flags |= ACTOR_FLAG_10; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 0, &this->unk_2D4); + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AED940.s") + switch (this->unk_2B0) { + case 4: + if (D_80AF0050 != 0) { + Actor_MarkForDeath(&this->actor); + return; + } + D_80AF0050 = 1; + this->actor.room = -1; + this->actor.update = func_80AEF2D8; + this->unk_2D8 = 0.0f; + func_80AECB0C(this, globalCtx); + func_80AEF2D8(&this->actor, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDBEC.s") + case 0: + this->unk_2D0 = -1; + this->unk_310 = 0; + this->unk_2E4 = 0; + func_80AED898(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDC4C.s") + default: + Actor_MarkForDeath(&this->actor); + return; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDCBC.s") +void EnTk_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTk* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDD4C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDDA0.s") +void func_80AECA3C(EnTk* this, GlobalContext* globalCtx) { + this->unk_316 = 0; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->actionFunc = func_80AECA90; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDE10.s") +void func_80AECA90(EnTk* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.msgMode = 0; + globalCtx->msgCtx.unk11F10 = 0; + func_80AEDE10(this, globalCtx); + } else if (this->actor.xzDistToPlayer < 100.0f) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEDF5C.s") +void func_80AECB0C(EnTk* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + this->unk_3CC = 0xFF; + this->unk_2DC = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 0, &this->unk_2D4); + this->actionFunc = func_80AECB6C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE2A8.s") +void func_80AECB6C(EnTk* this, GlobalContext* globalCtx) { + f32 temp_f0; + s32 temp2; + s32 temp3; + f32 sp48; + f32 sp44; + ScheduleResult sp34; + u8 temp4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE2C0.s") + this->actor.textId = 0; + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.msgMode = 0; + globalCtx->msgCtx.unk11F10 = 0; + func_80AED4F8(this, globalCtx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE300.s") + if (REG(15) != 0.0f) { + this->skelAnime.playSpeed = (f32)func_800FE620(globalCtx) / REG(15); + } else { + this->skelAnime.playSpeed = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE374.s") + if (this->unk_2CA & 0x10) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 5, &this->unk_2D4); + sp48 = 1.0f; + sp44 = 22.0f; + } else { + func_80AEC658(&this->skelAnime, this->unk_320, 1.0f, &sp48, &sp44); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE414.s") + temp2 = REG(15) * sp44; + temp_f0 = temp2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE478.s") + this->unk_2DC += (REG(15) * sp44) - temp2; + temp3 = this->unk_2DC; + this->unk_3D0 = temp2 + temp3; + this->unk_2DC -= temp3; + this->unk_2E0 += REG(15); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE4D0.s") + if (Schedule_RunScript(globalCtx, D_80AEF800, &sp34)) { + if ((this->unk_3CC != sp34.result) && !func_80AED354(this, globalCtx, &sp34)) { + return; + } + temp4 = sp34.result; + } else { + sp34.result = 0; + temp4 = sp34.result; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE650.s") + if (!temp4 && (this->unk_3CC != 0)) { + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + } else if (temp4 && (this->unk_3CC == 0)) { + this->actor.flags |= ACTOR_FLAG_1; + this->actor.draw = EnTk_Draw; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE6B8.s") + this->unk_3CC = sp34.result; + func_80AECE0C(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE784.s") + if (this->unk_3CE & 8) { + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE7E0.s") +void func_80AECE0C(EnTk* this, GlobalContext* globalCtx) { + if (this->unk_3CC != 0) { + if (1) {} + func_80AECE60(this, globalCtx); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 4, 0x1555, 0xB6); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE86C.s") +s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { + EnDoor* door; + f32 spA0[265]; + Vec3f sp94; + Vec3f sp88; + Vec3f sp7C; + s32 sp78; + s32 sp74; + Actor* door2; + Actor* door1; + s32 pad2[1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEE9B0.s") + func_8013AF00(spA0, 3, this->unk_3C8->count + 3); + if (!(this->unk_3CE & 4)) { + 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); + this->actor.world.pos.y = sp7C.y; + } else { + sp7C = this->unk_3D4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEEA4C.s") + this->actor.world.pos.x = sp7C.x; + this->actor.world.pos.z = sp7C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEEAD4.s") + if (!(this->unk_3CE & 4)) { + Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.world.pos); + this->unk_3CE |= 4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEEB88.s") + if ((globalCtx->unk_18B4A != 0) || (this->unk_3D0 == 0)) { + sp78 = this->unk_3F0; + sp74 = this->unk_3EC; + sp7C = this->actor.world.pos; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEED38.s") + this->unk_3D4 = gZeroVec3f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF048.s") + 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)) { + this->unk_3CE |= 8; + } else { + sp94 = this->actor.world.pos; + sp88 = this->unk_3D4; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp94, &sp88); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF094.s") + if ((globalCtx->unk_18B4A != 0) || (this->unk_3D0 == 0)) { + this->unk_3F0 = sp78; + this->unk_3EC = sp74; + this->unk_3D4 = sp7C; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF15C.s") + door = NULL; + if (!(this->unk_2CA & 0xC00)) { + door1 = NULL; + label: + do { + 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)) <= + 0x2000) { + this->unk_2CA |= 0x400; + door = (EnDoor*)door1; + break; + } + } + door1 = door1->next; + } + } while (door1 != NULL); + } else { + door2 = NULL; + do { + door2 = SubS_FindActor(globalCtx, door2, ACTORCAT_DOOR, ACTOR_EN_DOOR); + if (door2 != NULL) { + if (Actor_XZDistanceBetweenActors(&this->actor, door2) <= 160.0f) { + door = (EnDoor*)door2; + break; + } + door2 = door2->next; + } + } while (door2 != NULL); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF1B4.s") + if ((door != NULL) && (this->unk_2CA & 0x400)) { + Vec3f sp5C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF1C4.s") + Actor_OffsetOfPointInActorCoords(&this->actor, &sp5C, &door->dyna.actor.world.pos); + door->unk_1A7 = 2; + if (sp5C.z < -20.0f) { + this->unk_2CA &= ~0x400; + this->unk_2CA |= 0x800; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF210.s") + if (door != NULL) { + if ((this->unk_2CA & 0x800) && (door->unk_1A7 == 0)) { + this->unk_2CA &= ~0x800; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF220.s") + if (!(this->unk_3CE & 8) && !(this->unk_2CA & 0x10) && (this->actor.xzDistToPlayer < 100.0f)) { + func_8013E8F8(&this->actor, globalCtx, 100.0f, 100.0f, EXCH_ITEM_NONE, 0x4000, 0x4000); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF278.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF2C8.s") +s32 func_80AED354(EnTk* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + s32 phi_v1 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF2D8.s") + if (arg2->result != 0) { + phi_v1 = func_80AED38C(this, globalCtx, arg2); + } + return phi_v1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/EnTk_Update.s") +s32 func_80AED38C(EnTk* this, GlobalContext* globalCtx, ScheduleResult* arg2) { + u16 sp1E = SCHEDULE_TIME_NOW; + u8 params = ENTK_GET_F800(&this->actor); + u16 phi_a1; + s32 idx = arg2->result - 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF5F4.s") + this->unk_3C8 = SubS_GetAdditionalPath(globalCtx, params, D_80AEF8E8[idx + 1]); + if (this->unk_3C8 == 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF65C.s") + if ((this->unk_3CC <= 0) && (this->unk_3CC != 0) && (this->unk_3D0 >= 0)) { + phi_a1 = sp1E; + } else { + phi_a1 = arg2->time0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/func_80AEF6A4.s") + this->unk_3E4 = arg2->time1 - phi_a1; + this->unk_3F0 = sp1E - phi_a1; + phi_a1 = this->unk_3C8->count - 2; + this->unk_3E8 = this->unk_3E4 / phi_a1; + this->unk_3EC = (this->unk_3F0 / this->unk_3E8) + 2; + this->unk_3CE &= ~4; + this->unk_3CE &= ~8; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tk/EnTk_Draw.s") +void func_80AED4F8(EnTk* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->actionFunc = func_80AED610; +} + +void func_80AED544(EnTk* this, GlobalContext* globalCtx) { + if (!(gSaveContext.save.weekEventReg[31] & 0x10)) { + Message_StartTextbox(globalCtx, 0x13FE, &this->actor); + gSaveContext.save.weekEventReg[31] |= 0x10; + } else if (gSaveContext.save.time < CLOCK_TIME(9, 0)) { + Message_StartTextbox(globalCtx, 0x13FF, &this->actor); + } else if (gSaveContext.save.time < CLOCK_TIME(12, 0)) { + Message_StartTextbox(globalCtx, 0x1400, &this->actor); + } else if (gSaveContext.save.time < CLOCK_TIME(15, 0)) { + Message_StartTextbox(globalCtx, 0x1401, &this->actor); + } else { + Message_StartTextbox(globalCtx, 0x1402, &this->actor); + } +} + +void func_80AED610(EnTk* this, GlobalContext* globalCtx) { + if ((this->unk_2D4 == 4) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 7, &this->unk_2D4); + } + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + if (Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer - 0x1555, 0x71C)) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 4, &this->unk_2D4); + Message_StartTextbox(globalCtx, 0x13FD, &this->actor); + } else if (CURRENT_DAY != 2) { + func_80AED544(this, globalCtx); + } else if (!Flags_GetSwitch(globalCtx, ENTK_GET_7F0(&this->actor))) { + Message_StartTextbox(globalCtx, 0x1403, &this->actor); + } else if (gSaveContext.save.weekEventReg[60] & 2) { + func_80AED544(this, globalCtx); + } else { + Message_StartTextbox(globalCtx, 0x1413, &this->actor); + } + break; + } + + case 1: + case 2: + case 3: + break; + + case 4: + case 5: + case 6: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x13FD: + this->unk_2CA |= 0x10; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 0, &this->unk_2D4); + this->skelAnime.playSpeed = 10.0f; + this->actionFunc = func_80AECB6C; + break; + + case 0x13FE: + func_80151938(globalCtx, 0x13FF); + break; + + case 0x1413: + func_801159EC(30); + gSaveContext.save.weekEventReg[60] |= 2; + func_80151938(globalCtx, 0x13FF); + break; + + case 0x13FF: + case 0x1400: + case 0x1401: + case 0x1402: + case 0x1403: + case 0x1404: + case 0x1405: + case 0x1406: + case 0x1407: + case 0x1408: + case 0x1409: + case 0x140A: + case 0x140B: + case 0x140C: + case 0x140D: + case 0x140E: + case 0x140F: + case 0x1410: + case 0x1411: + case 0x1412: + default: + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 0, &this->unk_2D4); + this->actionFunc = func_80AECB6C; + break; + } + } + break; + } +} + +void func_80AED898(EnTk* this, GlobalContext* globalCtx) { + this->unk_316 = 0; + this->actor.speedXZ = 0.0f; + if (this->unk_2CA & 0x1000) { + if ((this->unk_2D4 == 4) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 7, &this->unk_2D4); + } + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + } + this->actionFunc = func_80AED940; +} + +void func_80AED940(EnTk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Actor* actor; + Vec3f sp44; + + if ((this->unk_2D4 != 4) && (this->unk_2D4 != 7)) { + s16 temp_v0 = (this->actor.shape.rot.y - this->actor.yawTowardsPlayer) + 0x1555; + + if (ABS(temp_v0) < 0x1800) { + Math_SmoothStepToS(&this->unk_31C, temp_v0, 3, 0x71C, 0); + } else { + Math_SmoothStepToS(&this->unk_31C, 0, 3, 0x71C, 0); + } + + Math_Vec3f_Copy(&sp44, &player->actor.world.pos); + sp44.y = player->bodyPartsPos[7].y + 3.0f; + temp_v0 = Math_Vec3f_Pitch(&this->actor.focus.pos, &sp44); + if (ABS(temp_v0) < 0x800) { + Math_SmoothStepToS(&this->unk_31A, temp_v0, 3, 0x16C, 0); + } else { + Math_SmoothStepToS(&this->unk_31A, 0, 3, 0x16C, 0); + } + } + + if ((this->unk_2D4 == 4) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 7, &this->unk_2D4); + } + + if (!(this->unk_2CA & 0x40)) { + actor = NULL; + + do { + 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); + Math_Vec3s_Copy(&this->unk_2F8, &actor->world.rot); + Actor_MarkForDeath(actor); + this->unk_2CA |= 0x40; + break; + } + actor = actor->next; + } + } while (actor != NULL); + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_2CA &= ~0x80; + this->actor.flags &= ~ACTOR_FLAG_10000; + globalCtx->msgCtx.msgMode = 0; + globalCtx->msgCtx.unk11F10 = 0; + func_80AEDE10(this, globalCtx); + } else if (!(this->unk_2CA & 0x80)) { + if (this->actor.xzDistToPlayer < 100.0f) { + func_8013E8F8(&this->actor, globalCtx, 100.0f, 100.0f, EXCH_ITEM_NONE, 0x4000, 0x4000); + } + } else { + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + } +} + +void func_80AEDBEC(EnTk* this, GlobalContext* globalCtx) { + this->actor.params = -1; + this->unk_2E8 = 0; + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->actionFunc = func_80AEDC4C; +} + +void func_80AEDC4C(EnTk* this, GlobalContext* globalCtx) { + if ((this->actor.params >= 0) && SubS_StartActorCutscene(&this->actor, this->cutscenes[1], this->actor.params, + SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + this->unk_2E8 = ActorCutscene_GetLength(this->cutscenes[1]); + func_80151938(globalCtx, 0x1411); + func_80AEDCBC(this, globalCtx); + } +} + +void func_80AEDCBC(EnTk* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 10.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 5, &this->unk_2D4); + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_2EC); + Math_Vec3f_Copy(&this->actor.prevPos, &this->unk_2EC); + Math_Vec3s_Copy(&this->actor.world.rot, &this->unk_2F8); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->unk_2F8); + this->actionFunc = func_80AEDD4C; +} + +void func_80AEDD4C(EnTk* this, GlobalContext* globalCtx) { + this->unk_2E8--; + if (this->unk_2E8 <= 0) { + ActorCutscene_Stop(this->cutscenes[1]); + func_801477B4(globalCtx); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80AEDDA0(EnTk* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->actor.flags |= ACTOR_FLAG_10000; + this->unk_2CA |= 0x80; + this->actionFunc = func_80AED940; +} + +void func_80AEDE10(EnTk* this, GlobalContext* globalCtx) { + switch (this->unk_2B0) { + case 0: + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->unk_2E6 = 0x1404; + break; + } + + switch (this->unk_310) { + case 0: + this->unk_2CA &= ~0x1000; + if (!(gSaveContext.save.weekEventReg[52] & 0x80)) { + this->unk_2E6 = 0x1405; + } else { + this->unk_2E6 = 0x140B; + } + break; + + case 2: + this->unk_2E6 = 0x140D; + break; + + case 4: + Message_StartTextbox(globalCtx, 0x140F, &this->actor); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + break; + + case 3: + Message_StartTextbox(globalCtx, 0x1410, &this->actor); + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + break; + } + break; + + case 2: + this->unk_2E6 = 0x1414; + break; + } + + this->actionFunc = func_80AEDF5C; +} + +void func_80AEDF5C(EnTk* this, GlobalContext* globalCtx) { + if ((this->unk_2D4 == 4) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 7, &this->unk_2D4); + } + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 0: + switch (this->unk_2E6) { + case 0x1404: + case 0x1405: + case 0x140B: + case 0x140D: + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer - 0x1555, 1, 0x71C, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (!Math_SmoothStepToS(&this->unk_31A, 0, 3, 0x16C, 10) && + !Math_SmoothStepToS(&this->unk_31C, 0, 3, 0x71C, 10) && + (this->actor.shape.rot.y == (s16)(this->actor.yawTowardsPlayer - 0x1555))) { + if (this->unk_2E6 == 0x1404) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 4, &this->unk_2D4); + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + } + Message_StartTextbox(globalCtx, this->unk_2E6, &this->actor); + } + break; + + case 0x1414: + Message_StartTextbox(globalCtx, this->unk_2E6, &this->actor); + break; + } + break; + + case 1: + case 2: + case 3: + break; + + case 4: + case 5: + case 6: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1404: + this->unk_2CA |= 0x1000; + func_80AED898(this, globalCtx); + break; + + case 0x1405: + func_80151938(globalCtx, 0x1406); + break; + + case 0x1406: + func_80151938(globalCtx, 0x1407); + break; + + case 0x1407: + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + func_80151938(globalCtx, 0x1409); + } else { + func_8019F230(); + func_80151938(globalCtx, 0x1408); + } + break; + + case 0x1408: + func_80151938(globalCtx, 0x1407); + break; + + case 0x1409: + func_80151938(globalCtx, 0x140A); + break; + + case 0x140A: + gSaveContext.save.weekEventReg[52] |= 0x80; + + case 0x140B: + func_80AEE784(this, globalCtx); + break; + + case 0x140D: + this->unk_2CA |= 2; + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + globalCtx->msgCtx.msgMode = 0x44; + func_80AEE2A8(this, globalCtx); + } else { + func_8019F230(); + func_80151938(globalCtx, 0x140E); + } + break; + + case 0x140E: + case 0x140F: + case 0x1410: + func_80AEE784(this, globalCtx); + break; + + case 0x1414: + func_80AECA3C(this, globalCtx); + break; + } + } + break; + } +} + +void func_80AEE2A8(EnTk* this, GlobalContext* globalCtx) { + this->actionFunc = func_80AEE2C0; +} + +void func_80AEE2C0(EnTk* this, GlobalContext* globalCtx) { + if (SubS_StartActorCutscene(&this->actor, this->cutscenes[0], 0x7C, SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + func_80AEE374(this, globalCtx); + } +} + +s32 func_80AEE300(GlobalContext* globalCtx, Actor* arg1, Actor* arg2, void* _arg3) { + EnTkStruct* arg3 = (EnTkStruct*)_arg3; + f32 temp_f0; + + if ((arg2 != arg1) && (ENTK_GET_F(arg2) == 3)) { + temp_f0 = Actor_DistanceBetweenActors(arg1, arg2); + if (temp_f0 < arg3->unk_04) { + arg3->unk_00 = arg2; + arg3->unk_04 = temp_f0; + } + } + return false; +} + +void func_80AEE374(EnTk* this, GlobalContext* globalCtx) { + EnTkStruct sp30; + + sp30.unk_00 = NULL; + sp30.unk_04 = FLT_MAX; + + SubS_FindActorCustom(globalCtx, &this->actor, NULL, ACTORCAT_NPC, ACTOR_EN_TK, &sp30, func_80AEE300); + if (sp30.unk_00 == 0) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2CC = Actor_YawToPoint(&this->actor, &sp30.unk_00->world.pos); + this->actionFunc = func_80AEE414; + } +} + +void func_80AEE414(EnTk* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_2CC, 2, 0xE38, 0x5B); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->actor.shape.rot.y == this->unk_2CC) { + func_80AEE478(this, globalCtx); + } +} + +void func_80AEE478(EnTk* this, GlobalContext* globalCtx) { + this->unk_310 = 2; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 3, &this->unk_2D4); + this->actionFunc = func_80AEE4D0; +} + +void func_80AEE4D0(EnTk* this, GlobalContext* globalCtx) { + Actor* bigPoe; + + if ((this->skelAnime.curFrame > 33.0f) && (this->skelAnime.curFrame < 41.0f)) { + func_800BBFB0(globalCtx, &this->unk_2B4, 10.0f, 2, 50, 30, 1); + } + + if (Animation_OnFrame(&this->skelAnime, 33.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIG_UP); + } + + if (!(this->unk_2CA & 0x20)) { + if (Animation_OnFrame(&this->skelAnime, 37.0f)) { + bigPoe = NULL; + do { + bigPoe = SubS_FindActor(globalCtx, bigPoe, ACTORCAT_PROP, ACTOR_EN_BIGPO); + + if (bigPoe != NULL) { + if ((bigPoe->params == 3) && (Actor_DistanceBetweenActors(&this->actor, bigPoe) < 80.0f)) { + bigPoe->params = 4; + this->unk_2CA |= 0x20; + this->unk_2E4++; + } + bigPoe = bigPoe->next; + } + } while (bigPoe != NULL); + } + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80AEE650(this, globalCtx); + } +} + +void func_80AEE650(EnTk* this, GlobalContext* globalCtx) { + if (this->unk_36C < ARRAY_COUNT(this->unk_324)) { + Math_Vec3f_Copy(&this->unk_324[this->unk_36C], &this->actor.world.pos); + this->unk_36C++; + } + this->actionFunc = func_80AEE6B8; +} + +void func_80AEE6B8(EnTk* this, GlobalContext* globalCtx) { + if (this->unk_2CA & 0x20) { + if (this->unk_2E4 >= 3) { + ActorCutscene_Stop(this->cutscenes[0]); + func_801477B4(globalCtx); + func_80AEDBEC(this, globalCtx); + } else if (SubS_StartActorCutscene(&this->actor, 0x7C, this->cutscenes[0], SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + this->unk_310 = 3; + func_80AEDE10(this, globalCtx); + this->unk_2CA &= ~0x20; + } + } else if (SubS_StartActorCutscene(&this->actor, 0x7C, this->cutscenes[0], SUBS_CUTSCENE_SET_UNK_LINK_FIELDS)) { + this->unk_310 = 4; + func_80AEDE10(this, globalCtx); + } +} + +void func_80AEE784(EnTk* this, GlobalContext* globalCtx) { + this->unk_2D0 = -1; + this->unk_310 = 1; + Math_Vec3s_Copy(&this->actor.world.rot, &this->actor.shape.rot); + func_80AEEAD4(this, globalCtx); + this->actionFunc = func_80AEE9B0; +} + +s32 func_80AEE7E0(Vec3f* arg0, f32 arg1, Vec3f* arg2, s32 arg3) { + s32 i; + s32 ret = true; + + for (i = 0; i < arg3; i++) { + if (Math_Vec3f_DistXZ(arg0, &arg2[i]) < arg1) { + ret = false; + break; + } + } + return ret; +} + +s32 func_80AEE86C(EnTk* this, GlobalContext* globalCtx) { + static Vec3f D_80AEFA78 = { 0.0f, 20.0f, 32.0f }; + s32 pad; + s32 ret = false; + s32 pad2; + CollisionPoly* sp38; + s32 sp34; + Vec3f sp28; + + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80AEFA78, &sp28); + if ((BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &sp38, &sp34, &sp28) != BGCHECK_Y_MIN) && + (func_800C9BB8(&globalCtx->colCtx, sp38, sp34) == 1) && (this->unk_2D0 == (u32)1) && + (this->actor.xyzDistToPlayerSq <= SQ(115.0f)) && + func_80AEE7E0(&this->actor.world.pos, 100.0f, this->unk_324, this->unk_36C) && + (((this->unk_2CA & 2) && (Math_Vec3f_DistXZ(&this->unk_300, &sp28) >= 100.0f)) || !(this->unk_2CA & 2)) && + !Play_InCsMode(globalCtx)) { + Math_Vec3f_Copy(&this->unk_300, &sp28); + ret = true; + } + return ret; +} + +void func_80AEE9B0(EnTk* this, GlobalContext* globalCtx) { + this->unk_30C(this, globalCtx); + + func_80AEEAD4(this, globalCtx); + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &this->unk_300) >= 100.0f) { + this->unk_2CA &= ~2; + } + + if (func_80AEE86C(this, globalCtx)) { + this->unk_310 = 2; + func_80AEDDA0(this, globalCtx); + } +} + +s32 func_80AEEA4C(EnTk* this, GlobalContext* globalCtx) { + s32 ret; + + if (this->unk_2CA & 1) { + ret = 3; + } else if (this->actor.xyzDistToPlayerSq < SQ(60.0f)) { + ret = 0; + } else if (this->actor.isTargeted || (globalCtx->actorCtx.targetContext.unk_94 == &this->actor) || + (this->actor.xyzDistToPlayerSq < SQ(80.0f))) { + ret = 1; + } else { + ret = 2; + } + return ret; +} + +void func_80AEEAD4(EnTk* this, GlobalContext* globalCtx) { + s32 sp24 = func_80AEEA4C(this, globalCtx); + + if (sp24 != this->unk_2D0) { + switch (sp24) { + case 0: + func_80AEF220(this, globalCtx); + break; + + case 1: + func_80AEF048(this, globalCtx); + break; + + case 2: + func_80AEEB88(this, globalCtx); + break; + + case 3: + func_80AEF15C(this, globalCtx); + break; + + case 4: + func_80AEF1C4(this, globalCtx); + break; + } + this->unk_2D0 = sp24; + } +} + +void func_80AEEB88(EnTk* this, GlobalContext* globalCtx) { + s32 sp74; + Vec3f sp68; + s32 i; + f32 temp; + + for (i = 0; i < 8; i++) { + sp68.x = Math_SinS(this->actor.world.rot.y + (i * 0x2000)) * 80.0f; + sp68.z = Math_CosS(this->actor.world.rot.y + (i * 0x2000)) * 80.0f; + + sp68.x += this->actor.world.pos.x; + sp68.y = this->actor.world.pos.y + 50.0f; + sp68.z += this->actor.world.pos.z; + + temp = BgCheck_EntityRaycastFloor3(&globalCtx->colCtx, &this->actor.floorPoly, &sp74, &sp68) - + this->actor.world.pos.y; + if (temp <= -80.0f) { + break; + } + } + + if (i == 8) { + this->unk_2CC = BINANG_ROT180((Rand_Centered() * 0x8000) + this->actor.yawTowardsPlayer); + } else { + this->unk_2CC = this->actor.world.rot.y + (i * 0x2000); + } + + this->unk_2C6 = 100; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 1, &this->unk_2D4); + this->unk_30C = func_80AEED38; +} + +void func_80AEED38(EnTk* this, GlobalContext* globalCtx) { + f32 sp64; + Vec3f sp58; + s16 sp56 = this->actor.shape.rot.y; + Vec3f sp48; + Vec3f sp3C; + + Math_Vec3f_Copy(&sp58, &this->actor.world.pos); + sp58.x += (Math_SinS(sp56) * 20.0f); + sp58.y += 30.0f; + sp58.z += Math_CosS(sp56) * 20.0f; + + if (BgCheck_SphVsFirstWall(&globalCtx->colCtx, &sp58, 20.0f)) { + Math_Vec3f_Copy(&sp48, &this->actor.world.pos); + sp56 = BINANG_ADD(this->actor.shape.rot.y, 0x4000); + sp48.x += (Math_SinS(sp56) * 20.0f); + sp48.y += 30.0f; + sp48.z += Math_CosS(sp56) * 20.0f; + + Math_Vec3f_Copy(&sp3C, &this->actor.world.pos); + sp56 = BINANG_SUB(this->actor.shape.rot.y, 0x4000); + sp3C.x += (Math_SinS(sp56) * 20.0f); + sp3C.y += 30.0f; + sp3C.z += Math_CosS(sp56) * 20.0f; + + if (BgCheck_SphVsFirstWall(&globalCtx->colCtx, &sp48, 20.0f)) { + if (BgCheck_SphVsFirstWall(&globalCtx->colCtx, &sp3C, 20.0f)) { + this->unk_2CC = this->actor.shape.rot.y - 0x4000; + } else { + this->unk_2CC = this->actor.shape.rot.y - 0x4000; + } + } else { + this->unk_2CC = this->actor.shape.rot.y + 0x4000; + } + } + + if (this->unk_2CA & 0x200) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 1, &this->unk_2D4); + func_80AEC658(&this->skelAnime, this->unk_320, 1.0f, &this->actor.speedXZ, &sp64); + } + + if (this->actor.speedXZ > 0.5f) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2CC, 2, 0xAAA, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + } + + if (Message_GetState(&globalCtx->msgCtx) == 0 && !Play_InCsMode(globalCtx) && (this->unk_2C6-- <= 0)) { + Message_StartTextbox(globalCtx, 0x140C, NULL); + this->unk_2CA |= 0x4000; + this->unk_2C6 = 200; + } +} + +void func_80AEF048(EnTk* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 1, &this->unk_2D4); + this->unk_30C = func_80AEF094; +} + +void func_80AEF094(EnTk* this, GlobalContext* globalCtx) { + f32 sp2C; + + if (this->unk_2CA & 0x200) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + } else { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 1, &this->unk_2D4); + func_80AEC658(&this->skelAnime, this->unk_320, 1.0f, &this->actor.speedXZ, &sp2C); + } + + if (this->actor.speedXZ >= 0.5f) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 2, 0x38E, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + } +} + +void func_80AEF15C(EnTk* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->unk_30C = func_80AEF1B4; +} + +void func_80AEF1B4(EnTk* this, GlobalContext* globalCtx) { +} + +void func_80AEF1C4(EnTk* this, GlobalContext* globalCtx) { + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->unk_30C = func_80AEF210; +} + +void func_80AEF210(EnTk* this, GlobalContext* globalCtx) { +} + +void func_80AEF220(EnTk* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + SubS_ChangeAnimationBySpeedInfo(&this->skelAnime, D_80AEF868, 2, &this->unk_2D4); + this->unk_30C = func_80AEF278; +} + +void func_80AEF278(EnTk* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer - 0x1555, 3, 0x1C7, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; +} + +void func_80AEF2C8(Actor* thisx, GlobalContext* globalCtx) { +} + +void func_80AEF2D8(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTk* this = THIS; + + if (this->actor.draw != NULL) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + this->unk_320 = this->skelAnime.curFrame; + SkelAnime_Update(&this->skelAnime); + + if ((this->actor.draw != NULL) && ((this->unk_2D4 == 0) || (this->unk_2D4 == 1)) && + (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 24.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_WALK); + } + + this->actionFunc(this, globalCtx); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 0.0f, 4); + func_80AEC460(this); +} + +void EnTk_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTk* this = THIS; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + this->unk_320 = this->skelAnime.curFrame; + SkelAnime_Update(&this->skelAnime); + func_80AEC460(this); + + if (((this->unk_2D4 == 0) || (this->unk_2D4 == 1)) && + (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 24.0f))) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_GOLON_WALK); + } + + this->unk_2CA &= ~1; + + if (this->actor.floorBgId != BGCHECK_SCENE) { + BgDanpeiMovebg* platform = (BgDanpeiMovebg*)DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId); + + if (platform != NULL) { + if (platform->dyna.actor.id == ACTOR_BG_DANPEI_MOVEBG) { + platform->unk_1CC |= 1; + if (platform->unk_1CC & 2) { + this->unk_2CA |= 1; + } + } + } else { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + Math_Vec3f_Copy(&this->actor.prevPos, &this->actor.home.pos); + } + } + + this->actionFunc(this, globalCtx); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 0.0f, 5); + + if ((this->unk_2B0 == 0) && + (func_800C9B40(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId) == 12)) { + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.prevPos); + this->unk_2CA |= 0x200; + this->actor.velocity.y = 0.0f; + } else { + this->unk_2CA &= ~0x200; + } + + if (!(this->unk_2CA & 0x200)) { + if (!(this->actor.bgCheckFlags & 1)) { + func_800B9010(&this->actor, NA_SE_EV_HONEYCOMB_FALL - SFX_FLAG); + } else if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_HUMAN_BOUND); + } + } +} + +void func_80AEF5F4(Actor* thisx, GlobalContext* globalCtx) { + EnTk* this = THIS; + + this->unk_316 += 0x46C8; + this->unk_318 = Math_SinS(this->unk_316) * 900.0f; + this->actionFunc(this, globalCtx); +} + +s32 EnTk_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnTk* this = THIS; + + if (limbIndex == 16) { + rot->z += this->unk_31A; + rot->y += this->unk_31C; + } + return false; +} + +void EnTk_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80AEFA84 = { 0.0f, 0.0f, 4600.0f }; + EnTk* this = THIS; + + if (this->unk_2B0 != 2) { + switch (limbIndex) { + case 16: + Matrix_MultZero(&this->actor.focus.pos); + break; + + case 14: + Matrix_MultVec3f(&D_80AEFA84, &this->unk_2B4); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, object_tk_DL_00B530); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + break; + } + } +} + +void EnTk_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80AEFA90[] = { + object_tk_Tex_004390, + object_tk_Tex_004B90, + object_tk_Tex_005390, + }; + s32 pad; + EnTk* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 25); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AEFA90[this->unk_2C2])); + + Matrix_RotateYS(this->unk_318, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTk_OverrideLimbDraw, EnTk_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.h b/src/overlays/actors/ovl_En_Tk/z_en_tk.h index 0f79cba14..119ae2b2b 100644 --- a/src/overlays/actors/ovl_En_Tk/z_en_tk.h +++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.h @@ -6,12 +6,61 @@ struct EnTk; typedef void (*EnTkActionFunc)(struct EnTk*, GlobalContext*); +typedef void (*EnTkUnkFunc)(struct EnTk*, GlobalContext*); + +#define ENTK_GET_F(thisx) ((thisx)->params & 0xF) +#define ENTK_GET_7F0(thisx) (((thisx)->params >> 4) & 0x7F) +#define ENTK_GET_F800(thisx) ((((thisx)->params >> 0xB) & 0x1F) & 0xFF) typedef struct EnTk { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnTkActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x268]; + /* 0x018C */ ColliderCylinder collider; + /* 0x01D8 */ Vec3s jointTable[18]; + /* 0x0244 */ Vec3s morphTable[18]; + /* 0x02B0 */ s8 unk_2B0; + /* 0x02B1 */ s8 unk_2B1; + /* 0x02B4 */ Vec3f unk_2B4; + /* 0x02C0 */ s16 unk_2C0; + /* 0x02C2 */ s16 unk_2C2; + /* 0x02C4 */ s16 unk_2C4; + /* 0x02C6 */ s16 unk_2C6; + /* 0x02C8 */ UNK_TYPE1 unk2C8[0x2]; + /* 0x02CA */ u16 unk_2CA; + /* 0x02CC */ s16 unk_2CC; + /* 0x02D0 */ s32 unk_2D0; + /* 0x02D4 */ s32 unk_2D4; + /* 0x02D8 */ f32 unk_2D8; + /* 0x02DC */ f32 unk_2DC; + /* 0x02E0 */ s32 unk_2E0; + /* 0x02E4 */ s16 unk_2E4; + /* 0x02E6 */ u16 unk_2E6; + /* 0x02E8 */ s16 unk_2E8; + /* 0x02EC */ Vec3f unk_2EC; + /* 0x02F8 */ Vec3s unk_2F8; + /* 0x0300 */ Vec3f unk_300; + /* 0x030C */ EnTkUnkFunc unk_30C; + /* 0x0310 */ s16 unk_310; + /* 0x0312 */ s16 cutscenes[2]; + /* 0x0316 */ s16 unk_316; + /* 0x0318 */ s16 unk_318; + /* 0x031A */ s16 unk_31A; + /* 0x031C */ s16 unk_31C; + /* 0x0320 */ f32 unk_320; + /* 0x0324 */ Vec3f unk_324[6]; + /* 0x036C */ s32 unk_36C; + /* 0x0370 */ UNK_TYPE1 unk370[0x58]; + /* 0x03C8 */ Path* unk_3C8; + /* 0x03CC */ u8 unk_3CC; + /* 0x03CE */ u16 unk_3CE; + /* 0x03D0 */ s32 unk_3D0; + /* 0x03D4 */ Vec3f unk_3D4; + /* 0x03E0 */ f32 unk_3E0; + /* 0x03E4 */ s32 unk_3E4; + /* 0x03E8 */ s32 unk_3E8; + /* 0x03EC */ s32 unk_3EC; + /* 0x03F0 */ s32 unk_3F0; } EnTk; // size = 0x3F4 extern const ActorInit En_Tk_InitVars; 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 2658799b4..fc06cff18 100644 --- a/src/overlays/actors/ovl_En_Torch/z_en_torch.c +++ b/src/overlays/actors/ovl_En_Torch/z_en_torch.c @@ -1,3 +1,9 @@ +/* + * File: z_en_torch.c + * Overlay: ovl_En_Torch + * Description: Grotto chest spawner + */ + #include "z_en_torch.h" #define FLAGS 0x00000000 @@ -15,7 +21,7 @@ static u8 sChestContents[] = { 0x02, 0x04, 0x05, 0x06, 0x36, 0x3A, 0x14, 0x14 }; void EnTorch_Init(Actor* thisx, GlobalContext* globalCtx) { EnTorch* this = THIS; - s8 returnData = gSaveContext.respawn[3].data; + s8 returnData = gSaveContext.respawn[RESPAWN_MODE_UNK_3].data; Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOX, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, diff --git a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c index d02573039..c6931fac5 100644 --- a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c +++ b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.c @@ -5,7 +5,9 @@ */ #include "z_en_torch2.h" -#define FLAGS 0x00000010 +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnTorch2*)thisx) @@ -30,9 +32,22 @@ const ActorInit En_Torch2_InitVars = { }; static ColliderCylinderInit sCylinderInit = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1 | OC1_TYPE_2, - OC2_TYPE_2, COLSHAPE_CYLINDER }, - { ELEMTYPE_UNK2, { 0x00100000, 0, 0 }, { 0xF7CFFFFF, 0, 0 }, TOUCH_NONE, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON }, + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_1 | OC1_TYPE_2, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00100000, 0, 0 }, + { 0xF7CFFFFF, 0, 0 }, + TOUCH_NONE, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 60, 0, { 0, 0, 0 } }, }; @@ -43,11 +58,11 @@ static InitChainEntry sInitChain[] = { // Shells for each of Link's different forms // (Playing elegy as Fierce Deity puts down a human shell) static Gfx* sShellDLists[] = { - D_0401C430, // Human - D_04048DF0, // Zora - D_04089070, // Deku - D_04057B10, // Goron - D_0401C430, // Human + gameplay_keep_DL_01C430, // Human + gameplay_keep_DL_048DF0, // Zora + gameplay_keep_DL_089070, // Deku + gameplay_keep_DL_057B10, // Goron + gameplay_keep_DL_01C430, // Human }; void EnTorch2_Init(Actor* thisx, GlobalContext* globalCtx) { @@ -60,9 +75,9 @@ void EnTorch2_Init(Actor* thisx, GlobalContext* globalCtx) { // params: which form Link is in (e.g. human, deku, etc.) params = this->actor.params; if (params != TORCH2_PARAM_DEKU) { - this->actor.flags |= 0x4000000; // Can press switch + this->actor.flags |= ACTOR_FLAG_4000000; // Can press switch if (params == TORCH2_PARAM_GORON) { - this->actor.flags |= 0x20000; // Can press heavy switches + this->actor.flags |= ACTOR_FLAG_20000; // Can press heavy switches } } this->framesUntilNextState = 20; @@ -72,7 +87,8 @@ void EnTorch2_Destroy(Actor* thisx, GlobalContext* globalCtx) { EnTorch2* this = THIS; Collider_DestroyCylinder(globalCtx, &this->collider); - func_80169DCC(globalCtx, this->actor.params + 3, 0xFF, 0, 0xBFF, &this->actor.world.pos, this->actor.shape.rot.y); + Play_SetRespawnData(&globalCtx->state, this->actor.params + RESPAWN_MODE_GORON - 1, 0xFF, 0, 0xBFF, + &this->actor.world.pos, this->actor.shape.rot.y); globalCtx->actorCtx.unk254[this->actor.params] = 0; } @@ -88,7 +104,7 @@ void EnTorch2_Update(Actor* thisx, GlobalContext* globalCtx) { } this->actor.gravity = -1.0f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 70.0f, 0x05); if (this->framesUntilNextState == 0) { @@ -108,7 +124,7 @@ void EnTorch2_Update(Actor* thisx, GlobalContext* globalCtx) { targetAlpha = 0; } else if (this->state == TORCH2_STATE_FADING_IN) { // Stay semitransparent until the player moves away - if ((this->actor.xzDistToPlayer > 32.0f) || (fabsf(this->actor.yDistToPlayer) > 70.0f)) { + if ((this->actor.xzDistToPlayer > 32.0f) || (fabsf(this->actor.playerHeightRel) > 70.0f)) { this->state = TORCH2_STATE_SOLID; } targetAlpha = 60; @@ -140,25 +156,24 @@ void EnTorch2_UpdateDeath(Actor* thisx, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); } else { this->actor.gravity = -1.0f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); } } -void EnTorch2_Draw(Actor* thisx, GlobalContext* globalCtx) { +void EnTorch2_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; EnTorch2* this = THIS; - - GlobalContext* unused = globalCtx; Gfx* gfx = sShellDLists[thisx->params]; OPEN_DISPS(globalCtx->state.gfxCtx); if (this->alpha == 0xFF) { Scene_SetRenderModeXlu(globalCtx, 0, 0x01); gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); - func_800BDFC0(globalCtx, gfx); + Gfx_DrawDListOpa(globalCtx, gfx); } else { Scene_SetRenderModeXlu(globalCtx, 1, 0x02); gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, this->alpha); - func_800BE03C(globalCtx, gfx); + Gfx_DrawDListXlu(globalCtx, gfx); } CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.h b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.h index 70e5cd7cf..744a7975c 100644 --- a/src/overlays/actors/ovl_En_Torch2/z_en_torch2.h +++ b/src/overlays/actors/ovl_En_Torch2/z_en_torch2.h @@ -14,19 +14,19 @@ typedef struct EnTorch2 { } EnTorch2; // size = 0x194 typedef enum { - TORCH2_PARAM_HUMAN, - TORCH2_PARAM_GORON, - TORCH2_PARAM_ZORA, - TORCH2_PARAM_DEKU, - TORCH2_PARAM_FIERCE_DEITY, + /* 0 */ TORCH2_PARAM_HUMAN, + /* 1 */ TORCH2_PARAM_GORON, + /* 2 */ TORCH2_PARAM_ZORA, + /* 3 */ TORCH2_PARAM_DEKU, + /* 4 */ TORCH2_PARAM_FIERCE_DEITY, } EnTorch2Param; typedef enum { - TORCH2_STATE_INITIALIZED, - TORCH2_STATE_FADING_IN, - TORCH2_STATE_SOLID, - TORCH2_STATE_IDLE, - TORCH2_STATE_DYING, + /* 0 */ TORCH2_STATE_INITIALIZED, + /* 1 */ TORCH2_STATE_FADING_IN, + /* 2 */ TORCH2_STATE_SOLID, + /* 3 */ TORCH2_STATE_IDLE, + /* 4 */ TORCH2_STATE_DYING, } EnTorch2State; extern const ActorInit En_Torch2_InitVars; diff --git a/src/overlays/actors/ovl_En_Toto/z_en_toto.c b/src/overlays/actors/ovl_En_Toto/z_en_toto.c index 4716439cb..f12baac71 100644 --- a/src/overlays/actors/ovl_En_Toto/z_en_toto.c +++ b/src/overlays/actors/ovl_En_Toto/z_en_toto.c @@ -5,12 +5,13 @@ */ #include "z_en_toto.h" +#include "objects/object_zm/object_zm.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnToto*)thisx) -#define ENTOTO_WEEK_EVENT_FLAGS (gSaveContext.weekEventReg[50] & 1 || gSaveContext.weekEventReg[51] & 0x80) +#define ENTOTO_WEEK_EVENT_FLAGS (gSaveContext.save.weekEventReg[50] & 1 || gSaveContext.save.weekEventReg[51] & 0x80) void EnToto_Init(Actor* thisx, GlobalContext* globalCtx); void EnToto_Destroy(Actor* thisx, GlobalContext* globalCtx); @@ -61,23 +62,6 @@ const ActorInit En_Toto_InitVars = { (ActorFunc)EnToto_Draw, }; -extern AnimationHeader D_06000C80; -extern AnimationHeader D_06001324; -extern AnimationHeader D_060016A4; -extern AnimationHeader D_06001DF0; -extern AnimationHeader D_060022C8; -extern AnimationHeader D_060028B8; -extern AnimationHeader D_06002F20; -extern AnimationHeader D_06003AA8; -extern UNK_TYPE D_06008AE8; -extern UNK_TYPE D_0600A068; -extern UNK_TYPE D_0600A468; -extern FlexSkeletonHeader D_0600A978; -extern AnimationHeader D_0600B3E0; -extern AnimationHeader D_0600B894; -extern AnimationHeader D_0600BC08; -extern AnimationHeader D_0600C880; - static ColliderCylinderInit sCylinderInit = { { COLTYPE_METAL, @@ -142,7 +126,8 @@ static EnTotoText D_80BA5074[] = { { 4, 0, 0x2AE4 }, }; -static AnimationHeader* D_80BA5078[] = { &D_060028B8, &D_0600B894, &D_06002F20, &D_0600BC08 }; +static AnimationHeader* D_80BA5078[] = { &object_zm_Anim_0028B8, &object_zm_Anim_00B894, &object_zm_Anim_002F20, + &object_zm_Anim_00BC08 }; static EnTotoText D_80BA5088[] = { { 5, 0, 0 }, { 6, 20, 0 }, { 7, 0, 0 }, { 8, 9, 0 }, { 9, 10, 0 }, { 1, 0, 0 }, { 10, 0, 0 }, @@ -199,15 +184,16 @@ void EnToto_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); - if (globalCtx->sceneNum == 0x15 && (gSaveContext.time >= 0x4000 && gSaveContext.time < 0xE555)) { + if (globalCtx->sceneNum == SCENE_MILK_BAR && + (gSaveContext.save.time >= CLOCK_TIME(6, 0) && gSaveContext.save.time < CLOCK_TIME(21, 30))) { Actor_MarkForDeath(&this->actor); return; } - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); this->actor.bgCheckFlags |= 0x400; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600A978, - ((globalCtx->sceneNum == 0x12) ? &D_06003AA8 : &D_0600C880), this->jointTable, this->morphTable, - 18); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zm_Skel_00A978, + ((globalCtx->sceneNum == SCENE_SONCHONOIE) ? &object_zm_Anim_003AA8 : &object_zm_Anim_00C880), + this->jointTable, this->morphTable, 18); func_80BA36C0(this, globalCtx, 0); this->actor.shape.rot.x = 0; } @@ -219,22 +205,23 @@ void EnToto_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void func_80BA383C(EnToto* this, GlobalContext* globalCtx) { - if (SkelAnime_Update(&this->skelAnime) && this->actionFuncIndex == 1 && this->skelAnime.animation != &D_06000C80) { - if (globalCtx->msgCtx.unk11F04 != 0x2A98 && globalCtx->msgCtx.unk11F04 != 0x2A99) { + if (SkelAnime_Update(&this->skelAnime) && this->actionFuncIndex == 1 && + this->skelAnime.animation != &object_zm_Anim_000C80) { + if (globalCtx->msgCtx.currentTextId != 0x2A98 && globalCtx->msgCtx.currentTextId != 0x2A99) { if (this->unk2B4 & 1 || Rand_ZeroOne() > 0.5f) { this->unk2B4 = (this->unk2B4 + 1) & 3; } } Animation_PlayOnce(&this->skelAnime, D_80BA5078[this->unk2B4]); } - func_800BBB74(&this->unk260, 0x14, 0x50, 3); + func_800BBB74(this->unk260, 0x14, 0x50, 3); } void func_80BA3930(EnToto* this, GlobalContext* globalCtx) { - AnimationHeader* animationHeader = &D_0600C880; + AnimationHeader* animationHeader = &object_zm_Anim_00C880; - if (globalCtx->sceneNum == 0x12) { - animationHeader = &D_06003AA8; + if (globalCtx->sceneNum == SCENE_SONCHONOIE) { + animationHeader = &object_zm_Anim_003AA8; } Animation_MorphToLoop(&this->skelAnime, animationHeader, -4.0f); } @@ -253,27 +240,29 @@ void func_80BA39C8(EnToto* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); func_80BA383C(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx) != 0) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80BA36C0(this, globalCtx, 1); - if (globalCtx->sceneNum != 0x12) { - Actor_SetSwitchFlag(globalCtx, this->actor.params & 0x7F); + if (globalCtx->sceneNum != SCENE_SONCHONOIE) { + Flags_SetSwitch(globalCtx, this->actor.params & 0x7F); } else if (player->transformation == PLAYER_FORM_DEKU) { - Actor_SetSwitchFlag(globalCtx, this->actor.home.rot.x); + Flags_SetSwitch(globalCtx, this->actor.home.rot.x); } this->unk2B6 = 0; return; } - if ((globalCtx->sceneNum == 0x15 && !(gSaveContext.time >= 0x4000 && gSaveContext.time < 0xED02)) || - (globalCtx->sceneNum != 0x15 && func_80BA397C(this, 0x2000))) { + //! @TODO: 0xED02 nor 0xED01 match CLOCK_TIME macro + if ((globalCtx->sceneNum == SCENE_MILK_BAR && + !(gSaveContext.save.time >= CLOCK_TIME(6, 0) && gSaveContext.save.time < 0xED02)) || + (globalCtx->sceneNum != SCENE_MILK_BAR && func_80BA397C(this, 0x2000))) { if (this->unk2B6 != 0) { this->text = D_80BA5044; - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, 0); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 9999.9f, 9999.9f, EXCH_ITEM_NONE); } else { - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 50.0f); - if (globalCtx->sceneNum == 0x12) { + if (globalCtx->sceneNum == SCENE_SONCHONOIE) { if (player->transformation == PLAYER_FORM_DEKU) { if (!Flags_GetSwitch(globalCtx, this->actor.home.rot.x)) { this->text = D_80BA5068; @@ -297,14 +286,14 @@ void func_80BA39C8(EnToto* this, GlobalContext* globalCtx) { } void func_80BA3BFC(EnToto* this, GlobalContext* globalCtx) { - if (globalCtx->sceneNum == 0x12) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06000C80, -4.0f); + if (globalCtx->sceneNum == SCENE_SONCHONOIE) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_zm_Anim_000C80, -4.0f); this->unk2B4 = 0; } else { if (this->text->unk0 == 4) { func_80151BB4(globalCtx, 9); } - Animation_MorphToLoop(&this->skelAnime, &D_0600B3E0, -4.0f); + Animation_MorphToLoop(&this->skelAnime, &object_zm_Anim_00B3E0, -4.0f); } } @@ -315,7 +304,7 @@ void func_80BA3C88(EnToto* this) { void func_80BA3CC4(EnToto* this, GlobalContext* globalCtx) { func_80BA383C(this, globalCtx); func_80BA3C88(this); - if (func_800B867C(&this->actor, globalCtx)) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { func_80BA36C0(this, globalCtx, this->text->unk1); } else { func_80BA4C44(this, globalCtx); @@ -327,7 +316,7 @@ void func_80BA3D38(EnToto* this, GlobalContext* globalCtx) { this->text = ENTOTO_WEEK_EVENT_FLAGS ? D_80BA50BC : D_80BA5088; func_80BA4C0C(this, globalCtx); globalCtx->actorCtx.unk5 |= 0x20; - this->unk260 = 0; + this->unk260[0] = 0; } void func_80BA3DBC(EnToto* this, GlobalContext* globalCtx) { @@ -393,7 +382,7 @@ s32 func_80BA3FB0(EnToto* this, GlobalContext* globalCtx) { s32 func_80BA3FCC(EnToto* this, GlobalContext* globalCtx) { if (DECR(this->unk2B1) == 0) { - func_801518B0(globalCtx, this->text->textId, NULL); + Message_StartTextbox(globalCtx, this->text->textId, NULL); return 1; } return 0; @@ -419,21 +408,21 @@ s32 func_80BA407C(EnToto* this, GlobalContext* globalCtx) { } s32 func_80BA40D4(EnToto* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { return 1; } return 0; } s32 func_80BA4128(EnToto* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 2) { + if (Message_GetState(&globalCtx->msgCtx) == 2) { return 1; } return 0; } s32 func_80BA415C(EnToto* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 4 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 4 && Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex != 0) { func_8019F230(); } else { @@ -449,8 +438,8 @@ s32 func_80BA4204(EnToto* this, GlobalContext* globalCtx) { if (DECR(this->unk2B1) == 0) { if (!ENTOTO_WEEK_EVENT_FLAGS) { - temp_v1_2 = &D_80BA50DC[gSaveContext.playerForm - 1]; - func_801518B0(globalCtx, (this->text->unk0 == 6) ? temp_v1_2->unk0 : temp_v1_2->unk4, NULL); + temp_v1_2 = &D_80BA50DC[gSaveContext.save.playerForm - 1]; + Message_StartTextbox(globalCtx, (this->text->unk0 == 6) ? temp_v1_2->unk0 : temp_v1_2->unk4, NULL); } return 1; } @@ -517,7 +506,6 @@ s32 func_80BA4530(EnToto* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); EnTotoUnkStruct2* temp_s0; s32 i; - u16 tmp; func_80BA3C88(this); if (player->actor.world.pos.z > -270.0f) { @@ -528,7 +516,7 @@ s32 func_80BA4530(EnToto* this, GlobalContext* globalCtx) { return this->text->unk1; } if (player->actor.bgCheckFlags & 1) { - temp_s0 = &D_80BA50DC[gSaveContext.playerForm - 1]; + temp_s0 = &D_80BA50DC[gSaveContext.save.playerForm - 1]; if (func_80BA44D4(temp_s0, player)) { Math_Vec3s_ToVec3f(&player->actor.world.pos, &temp_s0->unk6); player->actor.shape.rot.y = 0; @@ -541,8 +529,8 @@ s32 func_80BA4530(EnToto* this, GlobalContext* globalCtx) { if (this->unk2B1 < 10) { this->unk2B1++; if (this->unk2B1 >= 10) { - tmp = gSaveContext.playerForm; // Needed for regalloc possible FAKE MATCH - func_801518B0(globalCtx, D_80BA50DC[tmp - 1].unk2, NULL); + Message_StartTextbox(globalCtx, + D_80BA50DC[((void)0, gSaveContext.save.playerForm) - 1].unk2, NULL); } } return 0; @@ -561,18 +549,18 @@ s32 func_80BA46D8(EnToto* this, GlobalContext* globalCtx) { } s32 func_80BA4740(EnToto* this, GlobalContext* globalCtx) { - if (globalCtx->msgCtx.unk1202A == 4) { - if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { - gSaveContext.weekEventReg[56] |= 0x10; + if (globalCtx->msgCtx.ocarinaMode == 4) { + if (gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + gSaveContext.save.weekEventReg[56] |= 0x10; } - if (gSaveContext.playerForm == PLAYER_FORM_DEKU) { - gSaveContext.weekEventReg[56] |= 0x20; + if (gSaveContext.save.playerForm == PLAYER_FORM_DEKU) { + gSaveContext.save.weekEventReg[56] |= 0x20; } - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { - gSaveContext.weekEventReg[56] |= 0x40; + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + gSaveContext.save.weekEventReg[56] |= 0x40; } - if (gSaveContext.playerForm == PLAYER_FORM_GORON) { - gSaveContext.weekEventReg[56] |= 0x80; + if (gSaveContext.save.playerForm == PLAYER_FORM_GORON) { + gSaveContext.save.weekEventReg[56] |= 0x80; } return 1; } @@ -584,20 +572,20 @@ s32 func_80BA47E0(EnToto* this, GlobalContext* globalCtx) { s32 i; this->unk2B3 = 0; - if (gSaveContext.weekEventReg[56] & 0x10) { + if (gSaveContext.save.weekEventReg[56] & 0x10) { this->unk2B3 += 1; } - if (gSaveContext.weekEventReg[56] & 0x20) { + if (gSaveContext.save.weekEventReg[56] & 0x20) { this->unk2B3 += 2; } - if (gSaveContext.weekEventReg[56] & 0x40) { + if (gSaveContext.save.weekEventReg[56] & 0x40) { this->unk2B3 += 4; } - if (gSaveContext.weekEventReg[56] & 0x80) { + if (gSaveContext.save.weekEventReg[56] & 0x80) { this->unk2B3 += 8; } for (i = 0; i < 4; i++) { - if (gSaveContext.playerForm != (i + 1) && (D_80BA5128[i] & this->unk2B3)) { + if (gSaveContext.save.playerForm != (i + 1) && (D_80BA5128[i] & this->unk2B3)) { Math_Vec3s_ToVec3f(&spawnPos, &D_80BA50DC[i].unk6); Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_PLAYER, spawnPos.x, spawnPos.y, spawnPos.z, i + 2, 0, 0, -1); @@ -612,7 +600,7 @@ s32 func_80BA47E0(EnToto* this, GlobalContext* globalCtx) { s32 func_80BA49A4(EnToto* this, GlobalContext* globalCtx) { func_800B7298(globalCtx, NULL, 0x44); - func_801A31EC(0x54, 4, this->unk2B3 ^ 0xF); + func_801A31EC(NA_BGM_BALLAD_OF_THE_WIND_FISH, 4, this->unk2B3 ^ 0xF); this->unk2B1 = 4; return 0; } @@ -621,8 +609,8 @@ s32 func_80BA4A00(EnToto* this, GlobalContext* globalCtx) { Actor* actor; if (DECR(this->unk2B1) == 0) { - if (!func_801A2DE0(0x54)) { - actor = (Actor*)GET_PLAYER(globalCtx); // Needed for regalloc, possible FAKE MATCH + if (!Audio_IsSequencePlaying(NA_BGM_BALLAD_OF_THE_WIND_FISH)) { + actor = &GET_PLAYER(globalCtx)->actor; actor = actor->next; while (actor != NULL) { Actor_MarkForDeath(actor); @@ -634,9 +622,9 @@ s32 func_80BA4A00(EnToto* this, GlobalContext* globalCtx) { func_800B7298(globalCtx, NULL, 0x45); if (this->unk2B3 == 0xF) { if (CURRENT_DAY == 1) { - gSaveContext.weekEventReg[50] |= 1; + gSaveContext.save.weekEventReg[50] |= 1; } else { - gSaveContext.weekEventReg[51] |= 0x80; + gSaveContext.save.weekEventReg[51] |= 0x80; } } else { func_80BA402C(this, globalCtx); @@ -652,17 +640,17 @@ s32 func_80BA4B24(EnToto* this, GlobalContext* globalCtx) { if (func_80BA40D4(this, globalCtx)) { player = GET_PLAYER(globalCtx); - Animation_MorphToPlayOnce(&this->skelAnime, &D_060028B8, -4.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_zm_Anim_0028B8, -4.0f); if (player->transformation == PLAYER_FORM_ZORA) { if (!Flags_GetSwitch(globalCtx, this->actor.params & 0x7F)) { - Actor_SetSwitchFlag(globalCtx, this->actor.params & 0x7F); + Flags_SetSwitch(globalCtx, this->actor.params & 0x7F); return 1; } else { return 3; } } else { if (!Flags_GetSwitch(globalCtx, (this->actor.params >> 7) & 0x7F)) { - Actor_SetSwitchFlag(globalCtx, (this->actor.params >> 7) & 0x7F); + Flags_SetSwitch(globalCtx, (this->actor.params >> 7) & 0x7F); return 4; } else { return 7; @@ -688,16 +676,16 @@ s32 func_80BA4C44(EnToto* this, GlobalContext* globalCtx) { } void func_80BA4CB4(EnToto* this, GlobalContext* globalCtx) { - CsCmdActorAction* action; + CsCmdActorAction* action = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 525)]; - action = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x20D)]; - if (this->unk2B5 != action->unk0) { - this->unk2B5 = action->unk0; + if (this->unk2B5 != action->action) { + this->unk2B5 = action->action; if (this->unk2B5 != 4) { if (this->unk2B5 == 3) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001DF0, -4.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &object_zm_Anim_001DF0, -4.0f); } else { - Animation_PlayOnce(&this->skelAnime, this->unk2B5 == 1 ? &D_060016A4 : &D_060022C8); + Animation_PlayOnce(&this->skelAnime, + this->unk2B5 == 1 ? &object_zm_Anim_0016A4 : &object_zm_Anim_0022C8); if (this->unk2B5 == 2 && this->unk2B3 != 0xF) { func_80151BB4(globalCtx, 9); func_80151BB4(globalCtx, 10); @@ -708,11 +696,11 @@ void func_80BA4CB4(EnToto* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 0x320); if (SkelAnime_Update(&this->skelAnime)) { if (this->unk2B5 != 3) { - Animation_PlayLoop(&this->skelAnime, this->unk2B5 == 1 ? &D_0600C880 : &D_06001324); + Animation_PlayLoop(&this->skelAnime, this->unk2B5 == 1 ? &object_zm_Anim_00C880 : &object_zm_Anim_001324); } } if (this->unk2B5 == 4 && !Actor_HasParent(&this->actor, globalCtx)) { - func_800B8A1C(&this->actor, globalCtx, 0x83, 9999.9f, 9999.9f); + Actor_PickUp(&this->actor, globalCtx, GI_MASK_CIRCUS_LEADER, 9999.9f, 9999.9f); } } @@ -720,7 +708,7 @@ void EnToto_Update(Actor* thisx, GlobalContext* globalCtx) { EnToto* this = THIS; s32 pad; - if (func_800EE29C(globalCtx, 0x20D)) { + if (Cutscene_CheckActorAction(globalCtx, 0x20D)) { func_80BA4CB4(this, globalCtx); } else { D_80BA51B8[this->actionFuncIndex](this, globalCtx); @@ -730,18 +718,18 @@ void EnToto_Update(Actor* thisx, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); - Actor_SetHeight(&this->actor, 40.0f); + Actor_SetFocus(&this->actor, 40.0f); } void EnToto_Draw(Actor* thisx, GlobalContext* globalCtx) { - void* sp4C[] = { &D_06008AE8, &D_0600A068, &D_0600A468 }; + TexturePtr sp4C[] = { object_zm_Tex_008AE8, object_zm_Tex_00A068, object_zm_Tex_00A468 }; EnToto* this = THIS; s32 pad; OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp4C[this->unk260])); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp4C[this->unk260[0]])); Scene_SetRenderModeXlu(globalCtx, 0, 1); SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, NULL, &this->actor); diff --git a/src/overlays/actors/ovl_En_Toto/z_en_toto.h b/src/overlays/actors/ovl_En_Toto/z_en_toto.h index aa9628426..cdfe3294e 100644 --- a/src/overlays/actors/ovl_En_Toto/z_en_toto.h +++ b/src/overlays/actors/ovl_En_Toto/z_en_toto.h @@ -26,7 +26,7 @@ typedef struct EnToto { /* 0x144 */ SkelAnime skelAnime; /* 0x188 */ Vec3s jointTable[18]; /* 0x1F4 */ Vec3s morphTable[18]; - /* 0x260 */ s16 unk260; + /* 0x260 */ s16 unk260[2]; /* 0x264 */ ColliderCylinder collider; /* 0x2B0 */ u8 actionFuncIndex; /* 0x2B1 */ u8 unk2B1; 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 0291851a1..470f4908a 100644 --- a/src/overlays/actors/ovl_En_Trt/z_en_trt.c +++ b/src/overlays/actors/ovl_En_Trt/z_en_trt.c @@ -5,8 +5,10 @@ */ #include "z_en_trt.h" +#include "objects/object_trt/object_trt.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnTrt*)thisx) @@ -20,11 +22,11 @@ void EnTrt_Update(Actor* thisx, GlobalContext* globalCtx); void EnTrt_Draw(Actor* thisx, GlobalContext* globalCtx); void EnTrt_GetCutscenes(EnTrt* this, GlobalContext* globalCtx); -s32 EnTrt_ReturnItemToShelf(EnTrt* this); void EnTrt_ResetItemPosition(EnTrt* this); +void EnTrt_UpdateHeadYawAndPitch(EnTrt* this, GlobalContext* globalCtx); +s32 EnTrt_ReturnItemToShelf(EnTrt* this); s32 EnTrt_FacingShopkeeperDialogResult(EnTrt* this, GlobalContext* globalCtx); s32 EnTrt_TakeItemOffShelf(EnTrt* this); -void EnTrt_UpdateHeadYawAndPitch(EnTrt* this, GlobalContext* globalCtx); void EnTrt_BeginInteraction(EnTrt* this, GlobalContext* globalCtx); void EnTrt_IdleSleeping(EnTrt* this, GlobalContext* globalCtx); @@ -62,29 +64,17 @@ void EnTrt_Blink(EnTrt* this); void EnTrt_OpenEyes2(EnTrt* this); void EnTrt_NodOff(EnTrt* this); -extern UNK_TYPE D_0401F740; -extern UNK_TYPE D_0401F8C0; -extern UNK_TYPE D_0401F7C0; -extern FlexSkeletonHeader D_0600FEF0; -extern AnimationHeader D_0600FD34; -extern AnimationHeader D_0600DE68; -extern AnimationHeader D_06002224; -extern AnimationHeader D_06001EF4; -extern AnimationHeader D_060030EC; -extern AnimationHeader D_0600D52C; -extern AnimationHeader D_06002CB0; -extern AnimationHeader D_0600EE98; -extern AnimationHeader D_06003D78; -extern AnimationHeader D_06000A44; -extern TexturePtr D_0600B0B8; -extern TexturePtr D_0600B8B8; -extern TexturePtr D_0600C0B8; - -static ActorAnimationEntryS sAnimations[] = { - { &D_0600DE68, 1.0f, 0, -1, 2, 0 }, { &D_0600EE98, 1.0f, 0, -1, 2, 0 }, { &D_0600FD34, 1.0f, 0, -1, 0, 0 }, - { &D_060030EC, 1.0f, 0, -1, 2, 0 }, { &D_06003D78, 1.0f, 0, -1, 2, 0 }, { &D_0600D52C, 1.0f, 0, -1, 0, 0 }, - { &D_06000A44, 1.0f, 0, -1, 0, 0 }, { &D_06001EF4, 1.0f, 0, -1, 0, 0 }, { &D_06002224, 1.0f, 0, -1, 0, 0 }, - { &D_06002CB0, 1.0f, 0, -1, 0, 0 }, +static AnimationInfoS sAnimations[] = { + { &object_trt_Anim_00DE68, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00EE98, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00FD34, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_0030EC, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_003D78, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00D52C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_000A44, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_001EF4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_002224, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_002CB0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, }; const ActorInit En_Trt_InitVars = { @@ -107,17 +97,17 @@ static ShopItem sShop[] = { { SI_POTION_BLUE, { -12, 32, -36 } }, }; -void EnTrt_ChangeAnim(SkelAnime* skelAnime, ActorAnimationEntryS* animations, s32 idx) { +void EnTrt_ChangeAnim(SkelAnime* skelAnime, AnimationInfoS* animations, s32 idx) { f32 frameCount; animations += idx; if (animations->frameCount < 0) { - frameCount = Animation_GetLastFrame(animations->animationSeg); + frameCount = Animation_GetLastFrame(animations->animation); } else { frameCount = animations->frameCount; } - Animation_Change(skelAnime, animations->animationSeg, animations->playbackSpeed, animations->frame, frameCount, - animations->mode, animations->transitionRate); + Animation_Change(skelAnime, animations->animation, animations->playSpeed, animations->startFrame, frameCount, + animations->mode, animations->morphFrames); } s32 EnTrt_TestItemSelected(GlobalContext* globalCtx) { @@ -159,7 +149,7 @@ void EnTrt_UpdateCursorPos(GlobalContext* globalCtx, EnTrt* this) { f32 xOffset = 0.0f; f32 yOffset = 17.0f; - func_800B8898(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); + Actor_GetScreenPos(globalCtx, &this->items[this->cursorIdx]->actor, &x, &y); this->cursorPos.x = x + xOffset; this->cursorPos.y = y + yOffset; this->cursorPos.z = 1.2f; @@ -199,7 +189,7 @@ u16 EnTrt_GetItemTextId(EnTrt* this) { u16 EnTrt_GetItemChoiceTextId(EnTrt* this) { EnGirlA* item = this->items[this->cursorIdx]; - if (item->actor.params == SI_POTION_BLUE && !(gSaveContext.weekEventReg[0x35] & 0x10)) { + if (item->actor.params == SI_POTION_BLUE && !(gSaveContext.save.weekEventReg[53] & 0x10)) { this->textId = 0x881; return 0x881; } @@ -213,8 +203,8 @@ void EnTrt_EndInteraction(GlobalContext* globalCtx, EnTrt* this) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENTRT_CUTSCENESTATE_STOPPED; } - func_800B84D0(&this->actor, globalCtx); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; Interface_ChangeAlpha(50); this->drawCursor = 0; @@ -312,7 +302,7 @@ u8 EnTrt_SetCursorIndexFromNeutral(EnTrt* this, u8 shelfOffset) { } void EnTrt_Hello(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (this->cutsceneState == ENTRT_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { @@ -322,7 +312,7 @@ void EnTrt_Hello(EnTrt* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if (talkState == 5 && func_80147624(globalCtx)) { + if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { play_sound(NA_SE_SY_MESSAGE_PASS); if (!EnTrt_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx))) { EnTrt_StartShopping(globalCtx, this); @@ -331,7 +321,7 @@ void EnTrt_Hello(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_GetMushroom(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); this->tmpGetMushroomCutscene = this->getMushroomCutscene; @@ -340,24 +330,24 @@ void EnTrt_GetMushroom(EnTrt* this, GlobalContext* globalCtx) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING_SPECIAL) { player->stateFlags2 &= ~0x20000000; } - } else if (talkState == 5 && func_80147624(globalCtx)) { + } else if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x883: this->textId = 0x884; - func_801518B0(globalCtx, this->textId, &this->actor); - gSaveContext.weekEventReg[0x35] |= 8; - func_80123D50(globalCtx, GET_PLAYER(globalCtx), 18, 21); + Message_StartTextbox(globalCtx, this->textId, &this->actor); + gSaveContext.save.weekEventReg[53] |= 8; + func_80123D50(globalCtx, GET_PLAYER(globalCtx), ITEM_BOTTLE, PLAYER_AP_BOTTLE); break; case 0x888: this->textId = 0x889; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); break; case 0x889: if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING_SPECIAL) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENTRT_CUTSCENESTATE_STOPPED; } - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = EnTrt_PayForMushroom; break; @@ -372,15 +362,15 @@ void EnTrt_GetMushroom(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_PayForMushroom(EnTrt* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - func_80123D50(globalCtx, GET_PLAYER(globalCtx), 18, 21); + func_80123D50(globalCtx, GET_PLAYER(globalCtx), ITEM_BOTTLE, PLAYER_AP_BOTTLE); this->actionFunc = EnTrt_SetupItemGiven; } else { - func_800B8A1C(&this->actor, globalCtx, GI_RUPEE_RED, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_RED, 300.0f, 300.0f); } } void EnTrt_Goodbye(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x886: this->textId = 0x887; @@ -395,45 +385,45 @@ void EnTrt_Goodbye(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_SetupTryToGiveRedPotion(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { if (this->textId == 0x88F) { - if (func_80114E90() || !(gSaveContext.weekEventReg[0xC] & 0x10)) { + if (Interface_HasEmptyBottle() || !(gSaveContext.save.weekEventReg[12] & 0x10)) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENTRT_CUTSCENESTATE_STOPPED; } - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = EnTrt_GiveRedPotionForKoume; } else { this->tmpTextId = this->textId; this->textId = 0x88E; - gSaveContext.weekEventReg[0x55] |= 8; - func_801518B0(globalCtx, this->textId, &this->actor); + gSaveContext.save.weekEventReg[85] |= 8; + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->actionFunc = EnTrt_EndConversation; } } else { - if (gSaveContext.weekEventReg[0xC] & 8) { + if (gSaveContext.save.weekEventReg[12] & 8) { this->textId = 0x83D; EnTrt_SetupStartShopping(globalCtx, this, 0); - } else if (gSaveContext.weekEventReg[0x54] & 0x40) { + } else if (gSaveContext.save.weekEventReg[84] & 0x40) { this->textId = 0x83B; - if (func_80114F2C(ITEM_POTION_RED)) { + if (Interface_HasItemInBottle(ITEM_POTION_RED)) { EnTrt_SetupStartShopping(globalCtx, this, false); } else { this->actionFunc = EnTrt_TryToGiveRedPotion; } - } else if (gSaveContext.weekEventReg[0x10] & 0x10) { + } else if (gSaveContext.save.weekEventReg[16] & 0x10) { this->timer = 30; this->textId = 0x838; this->cutsceneState = ENTRT_CUTSCENESTATE_PLAYING_SPECIAL; this->actionFunc = EnTrt_Surprised; return; - } else if (gSaveContext.weekEventReg[0x11] & 1) { + } else if (gSaveContext.save.weekEventReg[17] & 1) { this->textId = 0x835; EnTrt_SetupStartShopping(globalCtx, this, false); } - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); } } } @@ -443,16 +433,16 @@ void EnTrt_GiveRedPotionForKoume(EnTrt* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; - if (!(gSaveContext.weekEventReg[0xC] & 0x10)) { - gSaveContext.weekEventReg[0xC] |= 0x10; + if (!(gSaveContext.save.weekEventReg[12] & 0x10)) { + gSaveContext.save.weekEventReg[12] |= 0x10; } - gSaveContext.weekEventReg[0x54] |= 0x40; + gSaveContext.save.weekEventReg[84] |= 0x40; player->stateFlags2 &= ~0x20000000; this->actionFunc = EnTrt_GivenRedPotionForKoume; - } else if (gSaveContext.weekEventReg[0xC] & 0x10) { - func_800B8A1C(&this->actor, globalCtx, GI_POTION_RED, 300.0f, 300.0f); + } else if (gSaveContext.save.weekEventReg[12] & 0x10) { + Actor_PickUp(&this->actor, globalCtx, GI_POTION_RED, 300.0f, 300.0f); } else { - func_800B8A1C(&this->actor, globalCtx, GI_BOTTLE_POTION_RED, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, GI_BOTTLE_POTION_RED, 300.0f, 300.0f); } } @@ -460,7 +450,7 @@ void EnTrt_GivenRedPotionForKoume(EnTrt* this, GlobalContext* globalCtx) { //! @bug: player is set to NULL not PLAYER Player* player = NULL; - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { ActorCutscene_StartAndSetFlag(this->cutscene, &this->actor); @@ -476,20 +466,20 @@ void EnTrt_GivenRedPotionForKoume(EnTrt* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); this->actionFunc = EnTrt_ItemGiven; } } void EnTrt_EndConversation(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (talkState == 5) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnTrt_EndInteraction(globalCtx, this); } } else if (talkState == 6) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnTrt_EndInteraction(globalCtx, this); } } @@ -510,7 +500,7 @@ s32 EnTrt_FacingShopkeeperDialogResult(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_FaceShopkeeper(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); u8 cursorIdx; if (this->cutsceneState == ENTRT_CUTSCENESTATE_WAITING) { @@ -531,7 +521,7 @@ void EnTrt_FaceShopkeeper(EnTrt* this, GlobalContext* globalCtx) { } else if (talkState == 4) { func_8011552C(globalCtx, 6); if (!EnTrt_TestEndInteraction(this, globalCtx, CONTROLLER1(globalCtx))) { - if ((!func_80147624(globalCtx) || !EnTrt_FacingShopkeeperDialogResult(this, globalCtx)) && + if ((!Message_ShouldAdvance(globalCtx) || !EnTrt_FacingShopkeeperDialogResult(this, globalCtx)) && (this->stickAccumX > 0)) { cursorIdx = EnTrt_SetCursorIndexFromNeutral(this, 2); if (cursorIdx != CURSOR_INVALID) { @@ -617,7 +607,7 @@ s32 EnTrt_HasPlayerSelectedItem(GlobalContext* globalCtx, EnTrt* this, Input* in } void EnTrt_BrowseShelf(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); s32 pad; u8 prevCursorIdx = this->cursorIdx; u8 cursorIdx; @@ -646,8 +636,8 @@ void EnTrt_BrowseShelf(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_SetupBuyItemWithFanfare(GlobalContext* globalCtx, EnTrt* this) { Player* player = GET_PLAYER(globalCtx); - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); - globalCtx->msgCtx.unk11F22 = 0x43; + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; player->stateFlags2 &= ~0x20000000; Interface_ChangeAlpha(50); @@ -712,12 +702,12 @@ void EnTrt_HandleCanBuyItem(GlobalContext* globalCtx, EnTrt* this) { void EnTrt_SelectItem(EnTrt* this, GlobalContext* globalCtx) { EnGirlA* item = this->items[this->cursorIdx]; - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (EnTrt_TakeItemOffShelf(this)) { if (talkState == 4) { func_8011552C(globalCtx, 6); - if (!EnTrt_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && func_80147624(globalCtx)) { + if (!EnTrt_TestCancelOption(this, globalCtx, CONTROLLER1(globalCtx)) && Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: EnTrt_HandleCanBuyItem(globalCtx, this); @@ -729,8 +719,8 @@ void EnTrt_SelectItem(EnTrt* this, GlobalContext* globalCtx) { break; } } - } else if (talkState == 5 && func_80147624(globalCtx)) { - if (!func_80114E90()) { + } else if (talkState == 5 && Message_ShouldAdvance(globalCtx)) { + if (!Interface_HasEmptyBottle()) { play_sound(NA_SE_SY_ERROR); EnTrt_SetupCannotBuy(globalCtx, this, 0x846); } else { @@ -742,7 +732,7 @@ void EnTrt_SelectItem(EnTrt* this, GlobalContext* globalCtx) { this->drawCursor = 0; this->shopItemSelectedTween = 0.0f; item->boughtFunc(globalCtx, item); - gSaveContext.weekEventReg[0x35] |= 0x10; + gSaveContext.save.weekEventReg[53] |= 0x10; } } } @@ -751,14 +741,14 @@ void EnTrt_SelectItem(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_IdleSleeping(EnTrt* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); - if ((gSaveContext.weekEventReg[0x55] & 8) && !(gSaveContext.weekEventReg[0x54] & 0x40)) { + if ((gSaveContext.save.weekEventReg[85] & 8) && !(gSaveContext.save.weekEventReg[84] & 0x40)) { this->textId = 0x88F; } else if (!(this->flags & ENTRT_MET)) { this->textId = 0x834; } else { this->textId = 0x83E; } - if (!(gSaveContext.weekEventReg[0x35] & 8)) { + if (!(gSaveContext.save.weekEventReg[53] & 8)) { this->talkOptionTextId = 0x845; } else if (this->flags & ENTRT_GIVEN_MUSHROOM) { this->talkOptionTextId = 0x882; @@ -771,10 +761,10 @@ void EnTrt_IdleSleeping(EnTrt* this, GlobalContext* globalCtx) { player->transformation == PLAYER_FORM_DEKU) { this->textId = 0x850; } - if (Player_GetMask(globalCtx) == PLAYER_MASK_MASK_OF_SCENTS) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_SCENTS) { this->textId = 0x890; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (player->transformation == PLAYER_FORM_HUMAN) { this->flags |= ENTRT_MET; } @@ -796,7 +786,7 @@ void EnTrt_IdleSleeping(EnTrt* this, GlobalContext* globalCtx) { if (DECR(this->timer) == 0) { this->timer = 40; EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 1); - this->animationIdx = 1; + this->animationIndex = 1; this->actionFunc = EnTrt_IdleAwake; this->blinkFunc = EnTrt_OpenThenCloseEyes; } @@ -810,7 +800,7 @@ void EnTrt_IdleAwake(EnTrt* this, GlobalContext* globalCtx) { this->flags &= ~ENTRT_FULLY_AWAKE; if (player->transformation == PLAYER_FORM_HUMAN || player->transformation == PLAYER_FORM_FIERCE_DEITY) { - if (Player_GetMask(globalCtx) == PLAYER_MASK_MASK_OF_SCENTS) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_SCENTS) { this->textId = 0x890; } else { this->textId = this->tmpTextId; @@ -818,7 +808,7 @@ void EnTrt_IdleAwake(EnTrt* this, GlobalContext* globalCtx) { } else { this->textId = 0x850; } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCurrentIndex() == 0x7C) { ActorCutscene_Stop(0x7C); @@ -842,7 +832,7 @@ void EnTrt_IdleAwake(EnTrt* this, GlobalContext* globalCtx) { if (DECR(this->timer) == 0) { this->timer = Rand_S16Offset(150, 100); EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 2); - this->animationIdx = 2; + this->animationIndex = 2; this->sleepSoundTimer = 10; this->actor.textId = 0; this->actionFunc = EnTrt_IdleSleeping; @@ -852,7 +842,7 @@ void EnTrt_IdleAwake(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_BeginInteraction(EnTrt* this, GlobalContext* globalCtx) { s16 curFrame = this->skelAnime.curFrame / this->skelAnime.playSpeed; - s16 animLastFrame = Animation_GetLastFrame(&D_060030EC) / (s16)this->skelAnime.playSpeed; + s16 animLastFrame = Animation_GetLastFrame(&object_trt_Anim_0030EC) / (s16)this->skelAnime.playSpeed; if (this->cutsceneState == ENTRT_CUTSCENESTATE_WAITING) { if (ActorCutscene_GetCanPlayNext(this->cutscene)) { @@ -862,14 +852,14 @@ void EnTrt_BeginInteraction(EnTrt* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } else if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING_SPECIAL) { - if (this->animationIdx != 5) { + if (this->animationIndex != 5) { if (curFrame == animLastFrame) { EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 3); - this->animationIdx = 3; + this->animationIndex = 3; this->blinkFunc = EnTrt_OpenEyesThenSetToBlink; this->timer = 10; this->cutsceneState = ENTRT_CUTSCENESTATE_PLAYING; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOTAKE_SURPRISED2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOTAKE_SURPRISED2); } } else { this->blinkFunc = EnTrt_OpenEyesThenSetToBlink; @@ -879,12 +869,12 @@ void EnTrt_BeginInteraction(EnTrt* this, GlobalContext* globalCtx) { } else if (DECR(this->timer) == 0) { this->timer = Rand_S16Offset(40, 20); EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 5); - func_801518B0(globalCtx, this->textId, &this->actor); - this->animationIdx = 5; + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->animationIndex = 5; switch (this->textId) { case 0x834: - if (!(gSaveContext.weekEventReg[0xC] & 8) && !(gSaveContext.weekEventReg[0x54] & 0x40) && - !(gSaveContext.weekEventReg[0x10] & 0x10) && !(gSaveContext.weekEventReg[0x11] & 1)) { + if (!(gSaveContext.save.weekEventReg[12] & 8) && !(gSaveContext.save.weekEventReg[84] & 0x40) && + !(gSaveContext.save.weekEventReg[16] & 0x10) && !(gSaveContext.save.weekEventReg[17] & 1)) { func_8011552C(globalCtx, 6); this->stickLeftPrompt.isEnabled = false; this->stickRightPrompt.isEnabled = true; @@ -921,27 +911,27 @@ void EnTrt_Surprised(EnTrt* this, GlobalContext* globalCtx) { } else if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING_SPECIAL) { if (DECR(this->timer) == 0) { EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 4); - this->animationIdx = 4; + this->animationIndex = 4; this->blinkFunc = EnTrt_OpenEyes2; - Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOTAKE_SURPRISED); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOTAKE_SURPRISED); this->timer = 30; this->cutsceneState = ENTRT_CUTSCENESTATE_PLAYING; } } else if (DECR(this->timer) == 0) { this->timer = Rand_S16Offset(40, 20); EnTrt_ChangeAnim(&this->skelAnime, sAnimations, 5); - func_801518B0(globalCtx, this->textId, &this->actor); - this->animationIdx = 5; + Message_StartTextbox(globalCtx, this->textId, &this->actor); + this->animationIndex = 5; this->actionFunc = EnTrt_TryToGiveRedPotionAfterSurprised; } } void EnTrt_TryToGiveRedPotionAfterSurprised(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); this->blinkFunc = EnTrt_Blink; - if (talkState == 6 && func_80147624(globalCtx)) { - if (func_80114E90() || !(gSaveContext.weekEventReg[0xC] & 0x10)) { + if (talkState == 6 && Message_ShouldAdvance(globalCtx)) { + if (Interface_HasEmptyBottle() || !(gSaveContext.save.weekEventReg[12] & 0x10)) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENTRT_CUTSCENESTATE_STOPPED; @@ -950,34 +940,34 @@ void EnTrt_TryToGiveRedPotionAfterSurprised(EnTrt* this, GlobalContext* globalCt } else { this->tmpTextId = this->textId; this->textId = 0x88E; - gSaveContext.weekEventReg[0x55] |= 8; - func_801518B0(globalCtx, this->textId, &this->actor); + gSaveContext.save.weekEventReg[85] |= 8; + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->actionFunc = EnTrt_EndConversation; } } } void EnTrt_TryToGiveRedPotion(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { if (this->textId == 0x83C) { - if (func_80114E90()) { + if (Interface_HasEmptyBottle()) { if (this->cutsceneState == ENTRT_CUTSCENESTATE_PLAYING) { ActorCutscene_Stop(this->cutscene); this->cutsceneState = ENTRT_CUTSCENESTATE_STOPPED; } - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; this->actionFunc = EnTrt_GiveRedPotionForKoume; } else { this->tmpTextId = this->textId; this->textId = 0x88E; - gSaveContext.weekEventReg[0x55] |= 8; - func_801518B0(globalCtx, this->textId, &this->actor); + gSaveContext.save.weekEventReg[85] |= 8; + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->actionFunc = EnTrt_EndConversation; } } else { this->textId = 0x83C; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); } } } @@ -999,7 +989,7 @@ void EnTrt_ItemGiven(EnTrt* this, GlobalContext* globalCtx) { ActorCutscene_SetIntentToPlay(this->cutscene); } } - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { switch (this->textId) { case 0x889: this->textId = 0x88A; @@ -1020,30 +1010,30 @@ void EnTrt_ItemGiven(EnTrt* this, GlobalContext* globalCtx) { } func_80151938(globalCtx, this->textId); } else { - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } void EnTrt_SetupEndInteraction(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { EnTrt_EndInteraction(globalCtx, this); } } void EnTrt_ShopkeeperGone(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { - func_801518B0(globalCtx, this->textId, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, this->textId, &this->actor); } else { if ((player->actor.world.pos.x >= -50.0f && player->actor.world.pos.x <= 50.0f) && (player->actor.world.pos.z >= -19.0f && player->actor.world.pos.z <= 30.0f)) { func_800B8614(&this->actor, globalCtx, 200.0f); } } - if (talkState == 6 && func_80147624(globalCtx)) { - if (gSaveContext.weekEventReg[0x14] & 2) { + if (talkState == 6 && Message_ShouldAdvance(globalCtx)) { + if (gSaveContext.save.weekEventReg[20] & 2) { globalCtx->nextEntranceIndex = 0xC50; } else { globalCtx->nextEntranceIndex = 0x8450; @@ -1055,7 +1045,7 @@ void EnTrt_ShopkeeperGone(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_CannotBuy(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->actionFunc = this->tmpActionFunc; func_80151938(globalCtx, EnTrt_GetItemTextId(this)); } @@ -1064,7 +1054,7 @@ void EnTrt_CannotBuy(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_CanBuy(EnTrt* this, GlobalContext* globalCtx) { EnGirlA* item; - if (func_80152498(&globalCtx->msgCtx) == 5 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 5 && Message_ShouldAdvance(globalCtx)) { this->shopItemSelectedTween = 0.0f; EnTrt_ResetItemPosition(this); item = this->items[this->cursorIdx]; @@ -1079,12 +1069,12 @@ void EnTrt_BuyItemWithFanfare(EnTrt* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = EnTrt_SetupItemGiven; } else { - func_800B8A1C(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); + Actor_PickUp(&this->actor, globalCtx, this->items[this->cursorIdx]->getItemId, 300.0f, 300.0f); } } void EnTrt_SetupItemGiven(EnTrt* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { this->actionFunc = EnTrt_ItemGiven; if (this->cutsceneState == ENTRT_CUTSCENESTATE_STOPPED) { if (ActorCutscene_GetCurrentIndex() == 0x7C) { @@ -1093,18 +1083,18 @@ void EnTrt_SetupItemGiven(EnTrt* this, GlobalContext* globalCtx) { this->cutscene = this->lookToShopkeeperCutscene; ActorCutscene_SetIntentToPlay(this->cutscene); } - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); } } void EnTrt_ContinueShopping(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); EnGirlA* item; if (talkState == 4) { func_8011552C(globalCtx, 6); - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnTrt_ResetItemPosition(this); item = this->items[this->cursorIdx]; item->restockFunc(globalCtx, item); @@ -1114,9 +1104,9 @@ void EnTrt_ContinueShopping(EnTrt* this, GlobalContext* globalCtx) { func_8019F208(); player->actor.shape.rot.y = BINANG_ROT180(player->actor.shape.rot.y); player->stateFlags2 |= 0x20000000; - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); EnTrt_SetupStartShopping(globalCtx, this, true); - func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + func_800B85E0(&this->actor, globalCtx, 400.0f, EXCH_ITEM_MINUS1); break; case 1: default: @@ -1127,7 +1117,7 @@ void EnTrt_ContinueShopping(EnTrt* this, GlobalContext* globalCtx) { } } } else if (talkState == 5) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { EnTrt_ResetItemPosition(this); item = this->items[this->cursorIdx]; item->restockFunc(globalCtx, item); @@ -1231,10 +1221,7 @@ void EnTrt_UpdateCursorAnim(EnTrt* this) { void EnTrt_UpdateStickDirectionPromptAnim(EnTrt* this) { f32 arrowAnimTween = this->arrowAnimTween; f32 stickAnimTween = this->stickAnimTween; - - // Possbily fake temps - s32 maxColor = 255; - f32 tmp; + s32 maxColor = 255; //! FAKE: if (this->arrowAnimState == 0) { arrowAnimTween += 0.05f; @@ -1261,31 +1248,33 @@ void EnTrt_UpdateStickDirectionPromptAnim(EnTrt* this) { stickAnimTween = 0.0f; this->stickAnimState = 0; } - - tmp = 155.0f * arrowAnimTween; - this->stickAnimTween = stickAnimTween; this->stickLeftPrompt.arrowColor.r = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.g = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); - this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100, arrowAnimTween); + this->stickLeftPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickLeftPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowColor.r = (maxColor - ((s32)tmp)) & 0xFF; - this->stickRightPrompt.arrowColor.g = (255 - ((s32)tmp)) & 0xFF; + this->stickRightPrompt.arrowTexX = 290.0f; + + this->stickRightPrompt.arrowColor.r = COL_CHAN_MIX(maxColor, 155.0f, arrowAnimTween); + this->stickRightPrompt.arrowColor.g = COL_CHAN_MIX(255, 155.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.b = COL_CHAN_MIX(0, -100.0f, arrowAnimTween); this->stickRightPrompt.arrowColor.a = COL_CHAN_MIX(200, 50.0f, arrowAnimTween); - this->stickRightPrompt.arrowTexX = 290.0f; this->stickLeftPrompt.arrowTexX = 33.0f; this->stickRightPrompt.stickTexX = 274.0f; this->stickRightPrompt.stickTexX += 8.0f * stickAnimTween; + this->stickLeftPrompt.stickTexX = 49.0f; this->stickLeftPrompt.stickTexX -= 8.0f * stickAnimTween; - this->stickLeftPrompt.arrowTexY = this->stickRightPrompt.arrowTexY = 91.0f; - this->stickLeftPrompt.stickTexY = this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + + this->stickRightPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.stickTexY = 95.0f; } void EnTrt_OpenEyes(EnTrt* this) { @@ -1368,12 +1357,12 @@ void EnTrt_OpenEyesThenSetToBlink(EnTrt* this) { } void EnTrt_TalkToShopkeeper(EnTrt* this, GlobalContext* globalCtx) { - u8 talkState = talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = talkState = Message_GetState(&globalCtx->msgCtx); Player* player = GET_PLAYER(globalCtx); s32 itemGiven; if (talkState == 5) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { if (this->talkOptionTextId == 0x845 || this->talkOptionTextId == 0x882) { func_80151938(globalCtx, 0xFF); } else { @@ -1382,15 +1371,15 @@ void EnTrt_TalkToShopkeeper(EnTrt* this, GlobalContext* globalCtx) { } } else if (talkState == 16) { itemGiven = func_80123810(globalCtx); - if (itemGiven > 0) { - if (itemGiven == ITEM_MUSHROOM) { - if (gSaveContext.weekEventReg[0x35] & 8) { + if (itemGiven > EXCH_ITEM_NONE) { + if (itemGiven == EXCH_ITEM_1E) { + if (gSaveContext.save.weekEventReg[53] & 8) { player->actor.textId = 0x888; } else { player->actor.textId = 0x883; } this->textId = player->actor.textId; - player->unk_A87 = itemGiven; + player->exchangeItemId = itemGiven; this->actionFunc = EnTrt_GetMushroom; } else { if (this->flags & ENTRT_GIVEN_MUSHROOM) { @@ -1402,13 +1391,13 @@ void EnTrt_TalkToShopkeeper(EnTrt* this, GlobalContext* globalCtx) { this->actionFunc = EnTrt_Goodbye; } func_801477B4(globalCtx); - } else if (itemGiven < 0) { + } else if (itemGiven < EXCH_ITEM_NONE) { if (this->flags & ENTRT_GIVEN_MUSHROOM) { this->textId = 0x88B; } else { this->textId = 0x886; } - func_801518B0(globalCtx, this->textId, &this->actor); + Message_StartTextbox(globalCtx, this->textId, &this->actor); this->actionFunc = EnTrt_Goodbye; } } @@ -1452,8 +1441,9 @@ void EnTrt_LookToShopkeeperFromShelf(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_InitShopkeeper(EnTrt* this, GlobalContext* globalCtx) { - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600FEF0, &D_0600FD34, NULL, NULL, 0); - if (!(gSaveContext.weekEventReg[0xC] & 8) && !(gSaveContext.weekEventReg[0x54] & 0x40) && gSaveContext.day >= 2) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_trt_Skel_00FEF0, &object_trt_Anim_00FD34, NULL, NULL, 0); + if (!(gSaveContext.save.weekEventReg[12] & 8) && !(gSaveContext.save.weekEventReg[84] & 0x40) && + gSaveContext.save.day >= 2) { this->actor.draw = NULL; } else { this->actor.draw = EnTrt_Draw; @@ -1461,17 +1451,15 @@ void EnTrt_InitShopkeeper(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_InitShop(EnTrt* this, GlobalContext* globalCtx) { - u32 maxcolor = 255; - EnTrt* this2; - EnTrt_GetCutscenes(this, globalCtx); this->cutscene = this->lookForwardCutscene; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); EnTrt_InitShopkeeper(this, globalCtx); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->actor.colChkInfo.cylRadius = 50; this->timer = Rand_S16Offset(40, 20); - if (!(gSaveContext.weekEventReg[0xC] & 8) && !(gSaveContext.weekEventReg[0x54] & 0x40) && gSaveContext.day >= 2) { + if (!(gSaveContext.save.weekEventReg[12] & 8) && !(gSaveContext.save.weekEventReg[84] & 0x40) && + gSaveContext.save.day >= 2) { this->textId = 0x84A; this->actionFunc = EnTrt_ShopkeeperGone; } else { @@ -1480,58 +1468,55 @@ void EnTrt_InitShop(EnTrt* this, GlobalContext* globalCtx) { this->actionFunc = EnTrt_IdleSleeping; } + this->cursorPos.y = this->cursorPos.x = 100.0f; this->stickAccumY = 0; this->stickAccumX = 0; + this->cursorIdx = 0; - this->cursorPos.y = this->cursorPos.x = 100.0f; this->cursorPos.z = 1.2f; this->cursorColor.r = 0; this->cursorColor.g = 80; - this->cursorColor.b = maxcolor; - this->cursorColor.a = maxcolor; + this->cursorColor.b = 255; + this->cursorColor.a = 255; this->cursorAnimTween = 0.0f; this->cursorAnimState = 0; this->drawCursor = 0; - this2 = this; - this->stickLeftPrompt.stickColor.r = 200; - this2->stickLeftPrompt.stickColor.g = 200; - this2->stickLeftPrompt.stickColor.b = 200; - this2->stickLeftPrompt.stickColor.a = 180; - this2->stickLeftPrompt.stickTexX = 49.0f; - this2->stickLeftPrompt.stickTexY = 95.0f; - this2->stickLeftPrompt.arrowColor.r = maxcolor; - this2->stickLeftPrompt.arrowColor.g = maxcolor; - this2->stickLeftPrompt.arrowColor.b = 0; - this2->stickLeftPrompt.arrowColor.a = 200; - this2->stickLeftPrompt.arrowTexX = 33.0f; - this2->stickLeftPrompt.arrowTexY = 91.0f; - this2->stickLeftPrompt.texZ = 1.0f; - this2->stickLeftPrompt.isEnabled = false; + this->stickLeftPrompt.stickColor.g = 200; + this->stickLeftPrompt.stickColor.b = 200; + this->stickLeftPrompt.stickColor.a = 180; + this->stickLeftPrompt.stickTexX = 49.0f; + this->stickLeftPrompt.stickTexY = 95.0f; + this->stickLeftPrompt.arrowColor.r = 255; + this->stickLeftPrompt.arrowColor.g = 255; + this->stickLeftPrompt.arrowColor.b = 0; + this->stickLeftPrompt.arrowColor.a = 200; + this->stickLeftPrompt.arrowTexX = 33.0f; + this->stickLeftPrompt.arrowTexY = 91.0f; + this->stickLeftPrompt.texZ = 1.0f; + this->stickLeftPrompt.isEnabled = false; - if (1) {} + this->stickRightPrompt.stickColor.r = 200; + this->stickRightPrompt.stickColor.g = 200; + this->stickRightPrompt.stickColor.b = 200; + this->stickRightPrompt.stickColor.a = 180; + this->stickRightPrompt.stickTexX = 274.0f; + this->stickRightPrompt.stickTexY = 95.0f; + this->stickRightPrompt.arrowColor.r = 255; + this->stickRightPrompt.arrowColor.g = 0; + this->stickRightPrompt.arrowColor.b = 0; + this->stickRightPrompt.arrowColor.a = 200; + this->stickRightPrompt.arrowTexX = 290.0f; + this->stickRightPrompt.arrowTexY = 91.0f; + this->stickRightPrompt.texZ = 1.0f; + this->stickRightPrompt.isEnabled = false; - this2->stickRightPrompt.stickColor.r = 200; - this2->stickRightPrompt.stickColor.g = 200; - this2->stickRightPrompt.stickColor.b = 200; - this2->stickRightPrompt.stickColor.a = 180; - this2->stickRightPrompt.stickTexX = 274.0f; - this2->stickRightPrompt.stickTexY = 95.0f; - this2->stickRightPrompt.arrowColor.r = maxcolor; - this2->stickRightPrompt.arrowColor.g = 0; - this2->stickRightPrompt.arrowColor.b = 0; - this2->stickRightPrompt.arrowColor.a = 200; - this2->stickRightPrompt.arrowTexX = 290.0f; - this2->stickRightPrompt.arrowTexY = 91.0f; - this2->stickRightPrompt.texZ = 1.0f; - this2->stickRightPrompt.isEnabled = false; - - this2->arrowAnimTween = 0.0f; - this2->stickAnimTween = 0.0f; - this2->arrowAnimState = 0; - this2->stickAnimState = 0; - this2->shopItemSelectedTween = 0.0f; + this->arrowAnimTween = 0.0f; + this->stickAnimTween = 0.0f; + this->arrowAnimState = 0; + this->stickAnimState = 0; + this->shopItemSelectedTween = 0.0f; this->actor.gravity = 0.0f; Actor_SetScale(&this->actor, sActorScale); @@ -1539,11 +1524,11 @@ void EnTrt_InitShop(EnTrt* this, GlobalContext* globalCtx) { this->blinkTimer = 20; this->eyeTextureIdx = 0; this->blinkFunc = EnTrt_EyesClosed; - if (gSaveContext.weekEventReg[0x35] & 8) { + if (gSaveContext.save.weekEventReg[53] & 8) { this->flags |= ENTRT_GIVEN_MUSHROOM; } - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; } void EnTrt_GetCutscenes(EnTrt* this, GlobalContext* globalCtx) { @@ -1554,7 +1539,10 @@ void EnTrt_GetCutscenes(EnTrt* this, GlobalContext* globalCtx) { } void EnTrt_DrawCursor(GlobalContext* globalCtx, EnTrt* this, f32 x, f32 y, f32 z, u8 drawCursor) { - s32 ulx, uly, lrx, lry; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; f32 w; s32 dsdx; s32 pad; @@ -1564,7 +1552,7 @@ void EnTrt_DrawCursor(GlobalContext* globalCtx, EnTrt* this, f32 x, f32 y, f32 z func_8012C654(globalCtx->state.gfxCtx); gDPSetPrimColor(OVERLAY_DISP++, 0, 0, this->cursorColor.r, this->cursorColor.g, this->cursorColor.b, this->cursorColor.a); - gDPLoadTextureBlock_4b(OVERLAY_DISP++, &D_0401F740, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, + gDPLoadTextureBlock_4b(OVERLAY_DISP++, gSelectionCursorTex, G_IM_FMT_IA, 16, 16, 0, G_TX_MIRROR | G_TX_WRAP, G_TX_MIRROR | G_TX_WRAP, 4, 4, G_TX_NOLOD, G_TX_NOLOD); w = 16.0f * z; ulx = (x - w) * 4.0f; @@ -1580,11 +1568,16 @@ void EnTrt_DrawCursor(GlobalContext* globalCtx, EnTrt* this, f32 x, f32 y, f32 z void EnTrt_DrawTextRec(GlobalContext* globalCtx, s32 r, s32 g, s32 b, s32 a, f32 x, f32 y, f32 z, s32 s, s32 t, f32 dx, f32 dy) { f32 unk; - s32 ulx, uly, lrx, lry; - f32 w, h; - s32 dsdx, dtdy; + s32 ulx; + s32 uly; + s32 lrx; + s32 lry; + f32 w; + f32 h; + s32 dsdx; + s32 dtdy; - ((void)"../z_en_trt.c"); // Unreferenced + (void)"../z_en_trt.c"; OPEN_DISPS(globalCtx->state.gfxCtx); gDPPipeSync(OVERLAY_DISP++); @@ -1610,21 +1603,15 @@ void EnTrt_DrawStickDirectionPrompt(GlobalContext* globalCtx, EnTrt* this) { s32 drawStickRightPrompt = this->stickLeftPrompt.isEnabled; s32 drawStickLeftPrompt = this->stickRightPrompt.isEnabled; - ((void)"../z_en_trt.c"); // Unreferenced + (void)"../z_en_trt.c"; OPEN_DISPS(globalCtx->state.gfxCtx); if (drawStickRightPrompt || drawStickLeftPrompt) { func_8012C654(globalCtx->state.gfxCtx); gDPSetCombineMode(OVERLAY_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F8C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 191, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 23 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnTrt_DrawTextRec(globalCtx, this->stickLeftPrompt.arrowColor.r, this->stickLeftPrompt.arrowColor.g, this->stickLeftPrompt.arrowColor.b, this->stickLeftPrompt.arrowColor.a, @@ -1637,15 +1624,9 @@ void EnTrt_DrawStickDirectionPrompt(GlobalContext* globalCtx, EnTrt* this) { this->stickRightPrompt.arrowTexX, this->stickRightPrompt.arrowTexY, this->stickRightPrompt.texZ, 0, 0, 1.0f, 1.0f); } - gDPSetTextureImage(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 1, &D_0401F7C0); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_16b, 0, 0x0000, G_TX_LOADTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPLoadSync(OVERLAY_DISP++); - gDPLoadBlock(OVERLAY_DISP++, G_TX_LOADTILE, 0, 0, 127, 1024); - gDPPipeSync(OVERLAY_DISP++); - gDPSetTile(OVERLAY_DISP++, G_IM_FMT_IA, G_IM_SIZ_8b, 2, 0x0000, G_TX_RENDERTILE, 0, G_TX_NOMIRROR | G_TX_WRAP, - G_TX_NOMASK, G_TX_NOLOD, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOLOD); - gDPSetTileSize(OVERLAY_DISP++, G_TX_RENDERTILE, 0, 0, 15 * 4, 15 * 4); + gDPLoadTextureBlock(OVERLAY_DISP++, gControlStickTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 16, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); if (drawStickRightPrompt) { EnTrt_DrawTextRec(globalCtx, this->stickLeftPrompt.stickColor.r, this->stickLeftPrompt.stickColor.g, this->stickLeftPrompt.stickColor.b, this->stickLeftPrompt.stickColor.a, @@ -1690,7 +1671,7 @@ void EnTrt_Update(Actor* thisx, GlobalContext* globalCtx) { EnTrt_UpdateCursorAnim(this); EnTrt_UpdateHeadYawAndPitch(this, globalCtx); this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->actor, 90.0f); + Actor_SetFocus(&this->actor, 90.0f); SkelAnime_Update(&this->skelAnime); EnTrt_UpdateCollider(this, globalCtx); } @@ -1712,13 +1693,13 @@ 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_CopyCurrentState(¤tState); - func_8018219C(¤tState, &newRot, MTXMODE_NEW); + Matrix_MultVec3f(&zeroVec, &newPos); + Matrix_Get(¤tState); + Matrix_MtxFToYXZRot(¤tState, &newRot, false); *pos = newPos; if (isFullyAwake) { newRot.x += pitch; @@ -1746,7 +1727,7 @@ s32 EnTrt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if (limbIndex == 14) { *dList = NULL; } - return 0; + return false; } void EnTrt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { @@ -1759,28 +1740,28 @@ void EnTrt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve } if (limbIndex == 21) { EnTrt_UpdateHeadPosAndRot(this->headPitch, this->headYaw, &this->headPos, &this->headRot, isFullyAwake); - Matrix_InsertTranslation(this->headPos.x, this->headPos.y, this->headPos.z, MTXMODE_NEW); + Matrix_Translate(this->headPos.x, this->headPos.y, this->headPos.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - Matrix_RotateY(this->headRot.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->headRot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->headRot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->headRot.z, MTXMODE_APPLY); } } -void EnTrt_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +void EnTrt_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { EnTrt* this = THIS; if (limbIndex == 21) { - Matrix_InsertTranslation(this->headPos.x, this->headPos.y, this->headPos.z, MTXMODE_NEW); + Matrix_Translate(this->headPos.x, this->headPos.y, this->headPos.z, MTXMODE_NEW); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); - Matrix_RotateY(this->headRot.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->headRot.x, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->headRot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->headRot.z, MTXMODE_APPLY); } } void EnTrt_Draw(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sEyeTextures[] = { &D_0600B0B8, &D_0600B8B8, &D_0600C0B8 }; + static TexturePtr sEyeTextures[] = { object_trt_Tex_00B0B8, object_trt_Tex_00B8B8, object_trt_Tex_00C0B8 }; EnTrt* this = THIS; s32 pad; @@ -1789,8 +1770,9 @@ void EnTrt_Draw(Actor* thisx, GlobalContext* globalCtx) { func_8012C28C(globalCtx->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTextureIdx])); gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sEyeTextures[this->eyeTextureIdx])); - func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, - EnTrt_OverrideLimbDraw, EnTrt_PostLimbDraw, EnTrt_UnkActorDraw, &this->actor); + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTrt_OverrideLimbDraw, EnTrt_PostLimbDraw, + EnTrt_TransformLimbDraw, &this->actor); EnTrt_DrawCursor(globalCtx, this, this->cursorPos.x, this->cursorPos.y, this->cursorPos.z, this->drawCursor); EnTrt_DrawStickDirectionPrompt(globalCtx, this); diff --git a/src/overlays/actors/ovl_En_Trt/z_en_trt.h b/src/overlays/actors/ovl_En_Trt/z_en_trt.h index 2df343dfc..eb243317b 100644 --- a/src/overlays/actors/ovl_En_Trt/z_en_trt.h +++ b/src/overlays/actors/ovl_En_Trt/z_en_trt.h @@ -41,7 +41,7 @@ typedef struct EnTrt { /* 0x3F0 */ Color_RGBAu32 cursorColor; /* 0x400 */ u8 drawCursor; /* 0x402 */ s16 timer; - /* 0x404 */ s16 animationIdx; + /* 0x404 */ s16 animationIndex; /* 0x406 */ u16 textId; /* 0x408 */ u16 tmpTextId; /* 0x40A */ u16 talkOptionTextId; 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 3de9370ff..f2b8c9138 100644 --- a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c +++ b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c @@ -1,6 +1,13 @@ -#include "z_en_trt2.h" +/* + * File: z_en_trt2.c + * Overlay: ovl_En_Trt2 + * Description: Kotake in Southern Swamp and Woods of Mystery + */ -#define FLAGS 0x00000009 +#include "z_en_trt2.h" +#include "objects/object_trt/object_trt.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnTrt2*)thisx) @@ -8,10 +15,30 @@ void EnTrt2_Init(Actor* thisx, GlobalContext* globalCtx); void EnTrt2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTrt2_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80AD46F8(EnTrt2* this); +s32 func_80AD475C(EnTrt2* this, Path* path, s32 arg2); +s16 func_80AD48F8(Path* path, s32 arg1, Vec3f* arg2, f32* arg3); +f32 func_80AD49B8(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3); +void func_80AD4A78(EnTrt2* this, GlobalContext* globalCtx); +s32 func_80AD4B08(GlobalContext* globalCtx); void func_80AD4DB4(EnTrt2* this, GlobalContext* globalCtx); void func_80AD4FE4(EnTrt2* this, GlobalContext* globalCtx); +void func_80AD5234(EnTrt2* this, GlobalContext* globalCtx); +void func_80AD56E8(Actor* thisx, GlobalContext* globalCtx); + +static AnimationInfoS sAnimations[] = { + { &object_trt_Anim_00DE68, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00EE98, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00FD34, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_0030EC, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_003D78, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_trt_Anim_00D52C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_000A44, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_001EF4, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_002224, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_trt_Anim_002CB0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -#if 0 const ActorInit En_Trt2_InitVars = { ACTOR_EN_TRT2, ACTORCAT_NPC, @@ -24,18 +51,29 @@ const ActorInit En_Trt2_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AD58A0 = { - { COLTYPE_NONE, 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_NONE, + 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, + }, { 32, 56, 30, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80AD58CC = { 1, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80AD58D8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -70,111 +108,833 @@ static DamageTable D_80AD58D8 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AD5964[] = { +void func_80AD3380(SkelAnime* skelAnime, AnimationInfoS* animation, s32 arg2) { + f32 phi_f0; + + animation += arg2; + + if (animation->frameCount < 0) { + phi_f0 = Animation_GetLastFrame(animation->animation); + } else { + phi_f0 = animation->frameCount; + } + Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, phi_f0, + animation->mode, animation->morphFrames); +} + +void func_80AD341C(EnTrt2* 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); +} + +void func_80AD349C(EnTrt2* this) { + if ((gSaveContext.save.weekEventReg[85] & 0x10) && !(gSaveContext.save.weekEventReg[84] & 0x40)) { + this->unk_3A8 = 0x88F; + } else if (this->unk_3A8 == 0) { + this->unk_3A8 = 0x84B; + } else if (gSaveContext.save.weekEventReg[16] & 0x10) { + this->unk_3A8 = 0x838; + } else if (gSaveContext.save.weekEventReg[17] & 1) { + this->unk_3A8 = 0x84D; + } else { + this->unk_3A8 = 0x849; + } +} + +void func_80AD3530(EnTrt2* this, GlobalContext* globalCtx) { + s16 phi_a1; + f32 sp30; + + func_80AD46F8(this); + if (this->path != NULL) { + phi_a1 = func_80AD48F8(this->path, this->unk_1E4, &this->actor.world.pos, &sp30); + if (this->actor.bgCheckFlags & 8) { + phi_a1 = this->actor.wallYaw; + } + Math_SmoothStepToS(&this->actor.world.rot.y, phi_a1, 4, 1000, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (func_80AD475C(this, this->path, this->unk_1E4)) { + if (this->unk_1E4 >= (this->path->count - 1)) { + this->unk_1E4 = 0; + } else { + this->unk_1E4++; + } + } + Math_ApproachF(&this->actor.speedXZ, 1.5f, 0.2f, 1.0f); + } + + Actor_MoveWithGravity(&this->actor); + + if (DECR(this->unk_3AE) == 0) { + this->unk_3AE = Rand_S16Offset(20, 20); + func_80AD3380(&this->skelAnime, sAnimations, 7); + this->unk_3B2 = 5; + } +} + +void func_80AD3664(EnTrt2* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->unk_3DA)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_3DA, &this->actor); + if (this->unk_3D9 == 0) { + this->unk_3B2 = 1; + } else { + this->unk_3B2 = 2; + } + } else { + ActorCutscene_SetIntentToPlay(this->unk_3DA); + return; + } + func_800B9010(&this->actor, NA_SE_EN_KOTAKE_FLY - SFX_FLAG); +} + +void func_80AD36EC(EnTrt2* this, GlobalContext* globalCtx) { + Vec3s sp30; + f32 sp2C; + + if (this->path != NULL) { + sp2C = func_80AD49B8(this->path, this->unk_1E4, &this->actor.world.pos, &sp30); + this->actor.shape.rot.y += 0x1000; + Math_ApproachF(&this->actor.velocity.y, 0.5f, 0.2f, 1.0f); + if (sp2C < 5.0f) { + if (this->unk_1E4 >= (this->path->count - 1)) { + this->unk_1E4 = 0; + this->unk_3D9 = 1; + this->actor.velocity.y = 0.0f; + this->path = SubS_GetPathByIndex(globalCtx, this->path->unk1, -1); + ActorCutscene_Stop(this->unk_3DA); + this->unk_3DA = ActorCutscene_GetAdditionalCutscene(this->unk_3DA); + ActorCutscene_SetIntentToPlay(this->unk_3DA); + this->unk_3B2 = 0; + } else { + this->unk_1E4++; + } + } + } + Actor_MoveWithGravity(&this->actor); + func_800B9010(&this->actor, NA_SE_EN_KOTAKE_FLY - SFX_FLAG); + if ((this->actor.shape.rot.y >= 0x2800) && (this->actor.shape.rot.y < 0x3800)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOTAKE_ROLL); + } +} + +void func_80AD381C(EnTrt2* this, GlobalContext* globalCtx) { + if ((CURRENT_DAY == 2) || (CURRENT_DAY == 3)) { + if (func_80AD4B08(globalCtx) == 1) { + this->actor.world.pos.y -= 50.0f; + this->unk_3D9 = 0; + this->unk_3B2 = 0; + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_10; + } + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80AD38B8(EnTrt2* this, GlobalContext* globalCtx) { + Vec3s sp30; + + if (this->unk_3D9 == 2) { + Actor_MarkForDeath(&this->actor); + } + + if (this->path != NULL) { + func_80AD49B8(this->path, this->unk_1E4, &this->actor.world.pos, &sp30); + Math_SmoothStepToS(&this->actor.world.rot.y, sp30.y, 4, 1000, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.shape.rot.x, sp30.x, 4, 1000, 1); + this->actor.world.rot.x = -this->actor.shape.rot.x; + if (func_80AD475C(this, this->path, this->unk_1E4)) { + if (this->unk_1E4 >= (this->path->count - 1)) { + ActorCutscene_Stop(this->unk_3DA); + this->unk_3D9 = 2; + } else { + this->unk_1E4++; + } + } + + if (this->actor.bgCheckFlags & 8) { + if (this->unk_1E4 >= (this->path->count - 1)) { + ActorCutscene_Stop(this->unk_3DA); + this->unk_3D9 = 2; + } else { + sp30.y = this->actor.wallYaw; + } + } + Math_ApproachF(&this->actor.speedXZ, 5.0f, 0.2f, 1.0f); + } + + Actor_MoveWithoutGravity(&this->actor); + func_800B9010(&this->actor, NA_SE_EN_KOTAKE_FLY - SFX_FLAG); +} + +void func_80AD3A24(EnTrt2* this, GlobalContext* globalCtx) { + func_80AD46F8(this); + if (this->actor.speedXZ > 0.05f) { + Math_ApproachF(&this->actor.speedXZ, 0.0f, 0.2f, 1.0f); + } else if (DECR(this->unk_3AE) == 0) { + this->unk_3AE = Rand_S16Offset(100, 50); + func_80AD3380(&this->skelAnime, sAnimations, 6); + this->unk_3B2 = 4; + } + Actor_MoveWithGravity(&this->actor); +} + +void func_80AD3AE4(EnTrt2* this, GlobalContext* globalCtx) { + if (this->actor.world.pos.y < this->actor.home.pos.y) { + Math_ApproachF(&this->actor.velocity.y, 0.5f, 0.2f, 0.1f); + } else { + this->actor.velocity.y = 0.0f; + func_80AD3380(&this->skelAnime, sAnimations, 6); + this->unk_3B2 = 4; + } + Actor_MoveWithGravity(&this->actor); +} + +void func_80AD3B6C(EnTrt2* this, GlobalContext* globalCtx) { + if (DECR(this->unk_3B0) == 0) { + this->unk_3B0 = 10; + this->actor.velocity.y = -1.0f; + func_80AD3380(&this->skelAnime, sAnimations, 8); + this->unk_3B2 = 8; + } +} + +void func_80AD3BE4(EnTrt2* this, GlobalContext* globalCtx) { + s16 sp2E = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + Math_ScaledStepToS(&this->unk_3C0, sp2E, 400); + Math_SmoothStepToS(&this->unk_3C0, sp2E, 4, 10000, 0); + this->actor.world.rot.y += this->unk_3C0; + this->actor.shape.rot.y = this->actor.world.rot.y; + if (this->actor.world.pos.y < 5.0f) { + func_80AD3380(&this->skelAnime, sAnimations, 9); + this->unk_3B2 = 9; + } +} + +void func_80AD3C94(EnTrt2* this, GlobalContext* globalCtx) { + if (this->actor.world.pos.y < 5.0f) { + func_80AD4A78(this, globalCtx); + if (this->actor.bgCheckFlags & 1) { + this->unk_3B2 = 0xF; + } + } +} + +void func_80AD3CEC(EnTrt2* this, GlobalContext* globalCtx) { + u8 sp27 = Message_GetState(&globalCtx->msgCtx); + + func_80AD46F8(this); + if (this->unk_3D8) { + Message_StartTextbox(globalCtx, this->unk_3A8, &this->actor); + this->unk_3D8 = false; + } else if ((sp27 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + func_80AD3380(&this->skelAnime, sAnimations, 6); + this->unk_3B2 = 4; + } +} + +void func_80AD3DA4(EnTrt2* this, GlobalContext* globalCtx) { + this->actor.velocity.y = 0.0f; + Message_StartTextbox(globalCtx, this->unk_3A8, &this->actor); + + if (this->unk_3A8 == 0x838) { + this->unk_3B2 = 11; + return; + } else if (this->unk_3A8 == 0x88F) { + if (Interface_HasEmptyBottle()) { + this->unk_3B2 = 11; + } else { + this->unk_3B2 = 10; + } + } else { + this->unk_3B2 = 10; + } +} + +void func_80AD3E34(EnTrt2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (Interface_HasEmptyBottle()) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_3B2 = 12; + } else { + gSaveContext.save.weekEventReg[85] |= 0x10; + this->unk_3A8 = 0x88E; + Message_StartTextbox(globalCtx, this->unk_3A8, &this->actor); + this->unk_3B2 = 10; + } + } +} + +void func_80AD3EF0(EnTrt2* this, GlobalContext* globalCtx) { + u8 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + if (temp_v0 == 6) { + if (Message_ShouldAdvance(globalCtx)) { + if ((Interface_HasEmptyBottle() && !(gSaveContext.save.weekEventReg[84] & 0x40)) || + !(gSaveContext.save.weekEventReg[12] & 0x10)) { + this->unk_3B2 = 12; + } else { + gSaveContext.save.weekEventReg[85] |= 0x10; + this->unk_3A8 = 0x88E; + Message_StartTextbox(globalCtx, this->unk_3A8, &this->actor); + this->unk_3B2 = 10; + } + } + } else if ((temp_v0 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_3B2 = 12; + } +} + +void func_80AD3FF4(EnTrt2* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + if (!(gSaveContext.save.weekEventReg[12] & 0x10)) { + gSaveContext.save.weekEventReg[12] |= 0x10; + } + gSaveContext.save.weekEventReg[84] |= 0x40; + this->actor.parent = NULL; + this->unk_3B2 = 14; + } else if (gSaveContext.save.weekEventReg[12] & 0x10) { + Actor_PickUp(&this->actor, globalCtx, GI_POTION_RED, 300.0f, 300.0f); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_BOTTLE_POTION_RED, 300.0f, 300.0f); + } +} + +void func_80AD40AC(EnTrt2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 6) && Message_ShouldAdvance(globalCtx)) { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + this->unk_3B2 = 13; + } +} + +void func_80AD4110(EnTrt2* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_3A8 = 0x84C; + func_80151938(globalCtx, this->unk_3A8); + this->unk_3B2 = 10; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_80AD417C(EnTrt2* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + if (this->unk_3A8 == 0x84B) { + func_80AD349C(this); + func_80AD3DA4(this, globalCtx); + } else { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + if (this->unk_3A8 == 0x84C) { + func_80AD3380(&this->skelAnime, sAnimations, 6); + this->path = SubS_GetPathByIndex(globalCtx, ENTRT2_GET_FC00(&this->actor), 0x3F); + this->unk_3B2 = 18; + } else if (this->unk_3A8 == 0x88F) { + this->unk_3A8 = 0x88E; + Message_StartTextbox(globalCtx, this->unk_3A8, &this->actor); + } else { + this->actor.textId = 0; + this->unk_3B2 = 15; + } + } + } +} + +void func_80AD4298(EnTrt2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCanPlayNext(this->unk_3DA)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_3DA, &this->actor); + player->stateFlags1 |= 0x20; + this->unk_3B2 = 6; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_3DA); + } +} + +void func_80AD431C(EnTrt2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags1 &= ~0x20; + Actor_MarkForDeath(&this->actor); +} + +void func_80AD434C(EnTrt2* this, GlobalContext* globalCtx) { + this->actor.shape.rot.y += 0x1000; + Math_ApproachF(&this->actor.velocity.y, 1.5f, 0.2f, 0.1f); + + if (this->actor.world.pos.y > 200.0f) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_3B2 = 0x13; + ActorCutscene_Stop(this->unk_3DA); + } else { + s32 i; + Vec3f sp68; + Vec3f sp5C = { 0.0f, 0.5f, 0.0f }; + + for (i = (s32)this->skelAnime.animLength - (s32)this->skelAnime.curFrame; i >= 0; i -= 2) { + sp68.x = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.x; + sp68.z = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.z; + sp68.y = randPlusMinusPoint5Scaled(50.0f) + (this->actor.world.pos.y + 20.0f); + func_800B3030(globalCtx, &sp68, &sp5C, &sp5C, 100, 0, 3); + } + + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + } else if (this->actor.world.pos.y < 5.0f) { + func_80AD4A78(this, globalCtx); + } + + Actor_MoveWithGravity(&this->actor); + + if ((this->actor.shape.rot.y >= 0x2800) && (this->actor.shape.rot.y < 0x3800)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOTAKE_ROLL); + } +} + +void func_80AD4550(EnTrt2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u8 sp23 = Message_GetState(&globalCtx->msgCtx); + + if ((player->transformation != PLAYER_FORM_HUMAN) && (player->transformation != PLAYER_FORM_FIERCE_DEITY)) { + func_80AD3380(&this->skelAnime, sAnimations, 7); + this->unk_3B2 = 17; + } + + if ((sp23 == 5) && Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; + globalCtx->msgCtx.unk12023 = 4; + } +} + +void func_80AD4608(EnTrt2* this) { + s16 temp = this->unk_3B6 - 1; + + if (temp != 0) { + this->unk_3B6 = temp; + return; + } + + temp = this->unk_3B8 + 1; + if (temp >= 3) { + this->unk_3B8 = 0; + this->unk_3B6 = (s32)(Rand_ZeroOne() * 60.0f) + 20; + } else { + this->unk_3B8 = temp; + this->unk_3B6 = 1; + } +} + +void func_80AD469C(EnTrt2* this, GlobalContext* globalCtx) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_trt_Skel_00FEF0, &object_trt_Anim_000A44, NULL, NULL, 0); + this->actor.draw = func_80AD56E8; +} + +void func_80AD46F8(EnTrt2* this) { + if ((this->actor.home.pos.y + 60.0f) < this->actor.world.pos.y) { + this->actor.velocity.y = -0.2f; + } else if (this->actor.world.pos.y <= (this->actor.home.pos.y + 50.0f)) { + this->actor.velocity.y = 0.2f; + } +} + +s32 func_80AD475C(EnTrt2* this, Path* path, s32 arg2) { + Vec3s* points; + s32 count; + f32 phi_f12; + s32 ret; + f32 phi_f14; + s32 arg = arg2; + f32 sp44; + f32 sp40; + f32 sp3C; + Vec3f sp30; + + points = Lib_SegmentedToVirtual(path->points); + count = path->count; + ret = false; + Math_Vec3s_ToVec3f(&sp30, &points[arg]); + + if (arg == 0) { + phi_f12 = points[1].x - points[0].x; + phi_f14 = points[1].z - points[0].z; + } else if ((count - 1) == arg) { + phi_f12 = points[count - 1].x - points[count - 2].x; + phi_f14 = points[count - 1].z - points[count - 2].z; + } else { + phi_f12 = points[arg + 1].x - points[arg - 1].x; + phi_f14 = points[arg + 1].z - points[arg - 1].z; + } + + 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) { + ret = true; + } + return ret; +} + +s16 func_80AD48F8(Path* path, s32 arg1, Vec3f* arg2, f32* arg3) { + Vec3s* points; + f32 phi_f14; + f32 phi_f12; + + if (path != NULL) { + points = Lib_SegmentedToVirtual(path->points); + points = &points[arg1]; + phi_f14 = points->x - arg2->x; + phi_f12 = points->z - arg2->z; + } else { + phi_f14 = 0.0f; + phi_f12 = 0.0f; + } + *arg3 = SQ(phi_f14) + SQ(phi_f12); + return RADF_TO_BINANG(Math_Acot2F(phi_f12, phi_f14)); +} + +f32 func_80AD49B8(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3) { + s32 pad; + Vec3f sp20; + Vec3s* temp_v1; + + if (path != NULL) { + temp_v1 = Lib_SegmentedToVirtual(path->points); + temp_v1 = &temp_v1[arg1]; + + sp20.x = temp_v1->x; + sp20.y = temp_v1->y; + sp20.z = temp_v1->z; + } + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + return sp20.y - arg2->y; +} + +void func_80AD4A78(EnTrt2* this, GlobalContext* globalCtx) { + Vec3f sp34; + + sp34.x = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.x; + sp34.y = this->actor.world.pos.y; + sp34.z = randPlusMinusPoint5Scaled(15.0f) + this->actor.world.pos.z; + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &sp34, 50.0f, 0, 2.0f, 0, 0, 0); +} + +s32 func_80AD4B08(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret; + + if (SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, player->actor.floorPoly, player->actor.floorBgId) == 0x15) { + ret = true; + } else { + ret = false; + } + return ret; +} + +s32 func_80AD4B4C(EnTrt2* this, GlobalContext* globalCtx) { + s32 sp24 = false; + Player* player = GET_PLAYER(globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + sp24 = true; + this->actor.speedXZ = 0.0f; + func_80AD349C(this); + this->unk_3B4 = this->unk_3B2; + if (this->actor.bgCheckFlags & 1) { + if ((player->transformation != PLAYER_FORM_HUMAN) && (player->transformation != PLAYER_FORM_FIERCE_DEITY)) { + this->unk_3A8 = 0x84F; + } + func_80AD3DA4(this, globalCtx); + } else if ((player->transformation == PLAYER_FORM_HUMAN) || + (player->transformation == PLAYER_FORM_FIERCE_DEITY)) { + this->unk_3B2 = 16; + this->actor.velocity.y = 1.5f; + } else { + this->unk_3A8 = 0x84F; + this->unk_3D8 = true; + func_80AD3380(&this->skelAnime, sAnimations, 7); + this->unk_3B2 = 7; + } + } + return sp24; +} + +s32 func_80AD4C4C(EnTrt2* this) { + if (this->actor.bgCheckFlags & 1) { + if (this->actor.xzDistToPlayer < 100.0f) { + return true; + } + } else if ((this->actor.xzDistToPlayer > 50.0f) && (this->actor.xzDistToPlayer < 200.0f)) { + return true; + } + return false; +} + +s32 func_80AD4CCC(EnTrt2* this, GlobalContext* globalCtx) { + s16 sp1E = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + Player* player = GET_PLAYER(globalCtx); + + if (((this->unk_3B2 == 4) || (this->unk_3B2 == 5)) && this->actor.isTargeted && !(this->actor.bgCheckFlags & 1) && + ((player->transformation == PLAYER_FORM_HUMAN) || (player->transformation == PLAYER_FORM_FIERCE_DEITY))) { + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 1.5f; + this->unk_3B2 = 16; + return true; + } + + if (func_80AD4C4C(this) && this->actor.isTargeted && (sp1E < 0x4000) && (sp1E > -0x4000)) { + func_800B863C(&this->actor, globalCtx); + } + + return true; +} + +void func_80AD4DB4(EnTrt2* this, GlobalContext* globalCtx) { + static Vec3f D_80AD5904 = { 0.0f, 50.0f, 0.0 }; + + this->actor.flags &= ~ACTOR_FLAG_10; + Actor_SetObjectDependency(globalCtx, &this->actor); + Actor_SetScale(&this->actor, 0.008f); + this->path = SubS_GetPathByIndex(globalCtx, ENTRT2_GET_FC00(&this->actor), 0x3F); + this->unk_3AE = Rand_S16Offset(100, 50); + this->unk_3B0 = 10; + this->unk_3A8 = 0; + + this->actor.world.pos.x += D_80AD5904.x; + this->actor.world.pos.y += D_80AD5904.y; + this->actor.world.pos.z += D_80AD5904.z; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + func_80AD469C(this, globalCtx); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.colChkInfo.cylRadius = 50; + + this->unk_3C0 = 0; + this->unk_3D8 = false; + this->unk_3DA = this->actor.cutscene; + this->unk_3B6 = 20; + this->unk_3B8 = 0; + this->unk_3BC = func_80AD4608; + + if (gSaveContext.save.weekEventReg[12] & 8) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (gSaveContext.save.weekEventReg[84] & 0x40) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((globalCtx->sceneNum == SCENE_20SICHITAI) || (globalCtx->sceneNum == SCENE_20SICHITAI2)) { + if (gSaveContext.save.day == 2) { + if (!(gSaveContext.save.weekEventReg[15] & 0x80)) { + gSaveContext.save.weekEventReg[15] |= 0x80; + this->unk_3B2 = 3; + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } else if (gSaveContext.save.day == 2) { + if (gSaveContext.save.weekEventReg[15] & 0x80) { + this->unk_3B2 = 4; + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } else if (gSaveContext.save.day == 3) { + this->unk_3B2 = 4; + } + this->actionFunc = func_80AD4FE4; +} + +void func_80AD4FE4(EnTrt2* this, GlobalContext* globalCtx) { + static EnTrt2UnkFunc2 D_80AD5910[] = { + func_80AD3664, func_80AD36EC, func_80AD38B8, func_80AD381C, func_80AD3530, func_80AD3A24, func_80AD434C, + func_80AD3CEC, func_80AD3BE4, func_80AD3C94, func_80AD417C, func_80AD3EF0, func_80AD3FF4, func_80AD4110, + func_80AD40AC, func_80AD4550, func_80AD3B6C, func_80AD3AE4, func_80AD4298, func_80AD431C, func_80AD3E34, + }; + + this->unk_3BC(this); + + D_80AD5910[this->unk_3B2](this, globalCtx); + Actor_MoveWithGravity(&this->actor); + + if (globalCtx->sceneNum != SCENE_20SICHITAI) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 26.0f, 10.0f, 0.0f, 5); + } + + Actor_SetFocus(&this->actor, 90.0f); + SkelAnime_Update(&this->skelAnime); +} + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 3, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), }; -#endif +void EnTrt2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTrt2* this = THIS; -extern ColliderCylinderInit D_80AD58A0; -extern CollisionCheckInfoInit2 D_80AD58CC; -extern DamageTable D_80AD58D8; -extern InitChainEntry D_80AD5964[]; + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actionFunc = func_80AD4DB4; +} -extern UNK_TYPE D_06000A44; +void EnTrt2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTrt2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3380.s") + SkelAnime_Free(&this->skelAnime, globalCtx); + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD341C.s") +void EnTrt2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTrt2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD349C.s") + if ((this->unk_3B2 != 6) && (this->unk_3B2 != 10) && (this->unk_3B2 != 13) && (this->unk_3B2 != 14) && + (this->unk_3B2 != 16) && (this->unk_3B2 != 8) && (this->unk_3B2 != 9)) { + func_80AD4B4C(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3530.s") + this->actionFunc(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3664.s") + func_80AD341C(this, globalCtx); + func_80AD5234(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD36EC.s") + if ((this->unk_3B2 != 6) && (this->unk_3B2 != 10) && (this->unk_3B2 != 13) && (this->unk_3B2 != 14) && + (this->unk_3B2 != 16) && (this->unk_3B2 != 8) && (this->unk_3B2 != 9)) { + func_80AD4CCC(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD381C.s") +void func_80AD5234(EnTrt2* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD38B8.s") + Math_SmoothStepToS(&this->unk_3D6, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 4, 0x38E0, 1); + this->unk_3D6 = CLAMP(this->unk_3D6, -0x38E0, 0x38E0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3A24.s") + sp40 = player->actor.world.pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3AE4.s") + if (this->unk_3B2 == 8) { + sp40.y = player->bodyPartsPos[7].y + 3.0f; + } else { + sp40.y = player->bodyPartsPos[7].y + 45.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3B6C.s") + sp34 = this->actor.world.pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3BE4.s") + Math_SmoothStepToS(&this->unk_3D4, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x1C70, 1); + this->unk_3D4 = CLAMP(this->unk_3D4, -0x1C70, 0x1C70); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3C94.s") +void func_80AD5394(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4) { + Vec3f sp7C; + Vec3f sp70 = gZeroVec3f; + Vec3s sp68; + MtxF sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3CEC.s") + Matrix_MultVec3f(&sp70, &sp7C); + Matrix_Get(&sp28); + Matrix_MtxFToYXZRot(&sp28, &sp68, false); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3DA4.s") + *arg2 = sp7C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3E34.s") + if (arg4) { + sp68.x += arg0; + sp68.y += arg1; + Math_SmoothStepToS(&arg3->x, sp68.x, 4, 0x1FFE, 1); + Math_SmoothStepToS(&arg3->y, sp68.y, 4, 0x1FFE, 1); + Math_SmoothStepToS(&arg3->z, sp68.z, 4, 0x1FFE, 1); + } else { + arg3->x = sp68.x; + arg3->y = sp68.y; + arg3->z = sp68.z; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3EF0.s") +s32 EnTrt2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTrt2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD3FF4.s") + if ((limbIndex == 8) || (limbIndex == 13) || (limbIndex == 19)) { + rot->y += (s16)Math_SinS(this->unk_33C[limbIndex]) * 200; + rot->z += (s16)Math_CosS(this->unk_372[limbIndex]) * 200; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD40AC.s") +void EnTrt2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTrt2* this = THIS; + Vec3f sp30 = { 0.0f, -30.0f, 0.0f }; + s32 phi_v0 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4110.s") + if (this->unk_3B2 >= 8) { + phi_v0 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD417C.s") + if (limbIndex == 21) { + func_80AD5394(this->unk_3D4, this->unk_3D6, &this->unk_3C8, &this->unk_3C2, phi_v0); + Matrix_Translate(this->unk_3C8.x, this->unk_3C8.y, this->unk_3C8.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_3C2.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_3C2.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_3C2.z, MTXMODE_APPLY); + Matrix_MultVec3f(&sp30, &this->actor.focus.pos); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4298.s") +void EnTrt2_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTrt2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD431C.s") + if (limbIndex == 21) { + Matrix_Translate(this->unk_3C8.x, this->unk_3C8.y, this->unk_3C8.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_3C2.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_3C2.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_3C2.z, MTXMODE_APPLY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD434C.s") +void func_80AD56E8(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80AD5978[] = { + object_trt_Tex_00B0B8, + object_trt_Tex_00B8B8, + object_trt_Tex_00C0B8, + }; + s32 pad; + EnTrt2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4550.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4608.s") + func_8012C28C(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD469C.s") + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AD5978[this->unk_3B8])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AD5978[this->unk_3B8])); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD46F8.s") + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTrt2_OverrideLimbDraw, EnTrt2_PostLimbDraw, + EnTrt2_TransformLimbDraw, &this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD475C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD48F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD49B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4A78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4B4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4C4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4CCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4DB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD4FE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/EnTrt2_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/EnTrt2_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/EnTrt2_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD5234.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD5394.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD54C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD5584.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD566C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Trt2/func_80AD56E8.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..bab274721 100644 --- a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h +++ b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h @@ -6,11 +6,39 @@ struct EnTrt2; typedef void (*EnTrt2ActionFunc)(struct EnTrt2*, GlobalContext*); +typedef void (*EnTrt2UnkFunc)(struct EnTrt2*); +typedef void (*EnTrt2UnkFunc2)(struct EnTrt2*, GlobalContext*); + +#define ENTRT2_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) typedef struct EnTrt2 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnTrt2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x294]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnTrt2ActionFunc actionFunc; + /* 0x148 */ UNK_TYPE1 unk_148[8]; + /* 0x150 */ SkelAnime skelAnime; + /* 0x194 */ ColliderCylinder collider; + /* 0x1E0 */ Path* path; + /* 0x1E4 */ s32 unk_1E4; + /* 0x1E8 */ UNK_TYPE1 unk_1E8[0x154]; + /* 0x33C */ s16 unk_33C[27]; + /* 0x372 */ s16 unk_372[27]; + /* 0x3A8 */ u16 unk_3A8; + /* 0x3AA */ UNK_TYPE1 unk_3AA[4]; + /* 0x3AE */ s16 unk_3AE; + /* 0x3B0 */ s16 unk_3B0; + /* 0x3B2 */ s16 unk_3B2; + /* 0x3B4 */ s16 unk_3B4; + /* 0x3B6 */ s16 unk_3B6; + /* 0x3B8 */ s16 unk_3B8; + /* 0x3BC */ EnTrt2UnkFunc unk_3BC; + /* 0x3C0 */ s16 unk_3C0; + /* 0x3C2 */ Vec3s unk_3C2; + /* 0x3C8 */ Vec3f unk_3C8; + /* 0x3D4 */ s16 unk_3D4; + /* 0x3D6 */ s16 unk_3D6; + /* 0x3D8 */ u8 unk_3D8; + /* 0x3D9 */ u8 unk_3D9; + /* 0x3DA */ s16 unk_3DA; } 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 cd35652cc..d428553f8 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -1,6 +1,13 @@ -#include "z_en_tru.h" +/* + * File: z_en_tru.c + * Overlay: ovl_En_Tru + * Description: Koume in Woods of Mystery + */ -#define FLAGS 0x00000039 +#include "z_en_tru.h" +#include "objects/object_tru/object_tru.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTru*)thisx) @@ -9,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, @@ -25,91 +68,1194 @@ 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" +#include "objects/gameplay_keep/gameplay_keep.h" + +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 TexturePtr D_80A8B280[] = { + gDust8Tex, gDust7Tex, gDust6Tex, gDust5Tex, gDust4Tex, gDust3Tex, gDust2Tex, gDust1Tex, +}; + +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 AnimationInfoS D_80A8B2D8[] = { + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_0108AC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_009348, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_tru_Anim_00EEDC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_014728, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_tru_Anim_01B5C4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_tru_Anim_007FA0, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_016B4C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_011F88, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_003698, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_002BD8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, ANIMMODE_LOOP, 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_Translate(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + Matrix_Translate(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_Translate(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Push(); + + 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_Translate(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_ReplaceRotation(&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_Pop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +void func_80A85F84(EnTruUnkStruct* arg0, GlobalContext* globalCtx); +#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 = SubS_ChangeAnimationByInfoS(&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_Push(); + 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_RotateXS(-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_Pop(); -#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_Push(); + 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_RotateXS(-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_Pop(); + + 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->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.save.weekEventReg[16] & 0x10)) { + return D_80A88918; + } + + if ((this->unk_34E & 0x1000) && !(gSaveContext.save.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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_34E &= ~0x80; + } + this->unk_34E &= ~(0x4000 | 0x2000); + + if ((player->exchangeItemId == 35) || (player->exchangeItemId == 36)) { + this->unk_34E |= 0x2000; + this->unk_38C = player->exchangeItemId; + } else if (player->exchangeItemId != 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); + SubS_UpdateFlags(&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 = Lib_SegmentedToVirtual(this->path->points); + if (SubS_HasReachedPoint(&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_MoveWithGravity(&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.save.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) { + EnTru* this = THIS; + s32 ret = 0; + s32 temp_v0 = Message_GetState(&globalCtx->msgCtx); + + switch (temp_v0) { + case 4: + case 5: + if (Message_ShouldAdvance(globalCtx)) { + case 16: + temp_v0 = func_80123810(globalCtx); + if ((temp_v0 == 35) || (temp_v0 == 36)) { + this->unk_34E |= 8; + if (temp_v0 == 35) { + this->unk_390 = 1; + } else { + this->unk_390 = 2; + } + this->unk_378 = func_80A87880; + this->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); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOUME_DRINK); + } else if (Animation_OnFrame(&this->skelAnime, 90.0f)) { + Actor_PlaySfxAtPos(&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(Camera_GetCamDirYaw(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->state, 1, 160, 160, 160, 0); + this->unk_370 = 20; + this->unk_372 = 10; + this->unk_364++; + } else if (Animation_OnFrame(&this->skelAnime, 22.0f)) { + Actor_PlaySfxAtPos(&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->exchangeItemId != 0) { + player->exchangeItemId = 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); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOUME_AWAY); + Actor_PlaySfxAtPos(&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.save.weekEventReg[12] |= 8; + } + break; + } + + if (ret == true) { + this->actor.flags &= ~ACTOR_FLAG_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.save.weekEventReg[16] & 0x10)) { + if (func_80A873B8(this)) { + SubS_UpdateFlags(&this->unk_34E, 3, 7); + } else { + SubS_UpdateFlags(&this->unk_34E, 0, 7); + } + } else if (this->unk_34E & 0x40) { + if (func_80A873B8(this)) { + SubS_UpdateFlags(&this->unk_34E, 3, 7); + } else { + SubS_UpdateFlags(&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.save.weekEventReg[16] & 0x10) && (fabsf(this->actor.playerHeightRel) < 10.0f) && + (this->actor.xzDistToPlayer < 140.0f)) { + SubS_UpdateFlags(&this->unk_34E, 4, 7); + this->unk_34E |= 0x1040; + this->unk_362 = Rand_S16Offset(40, 20); + } else if (func_80A873B8(this)) { + SubS_UpdateFlags(&this->unk_34E, 3, 7); + } else { + SubS_UpdateFlags(&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.save.weekEventReg[16] & 0x10)) { + func_80A86924(this, 0); + } else if (this->unk_34E & 0x80) { + func_80A86924(this, 0); + func_80A86460(this); + } else if (gSaveContext.save.weekEventReg[16] & 0x10) { + func_80A86924(this, 6); + } + + SubS_UpdateFlags(&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 &= ~ACTOR_FLAG_100; + this->unk_1E8 = 0; + this->actionFunc = func_80A87FD0; + } +} + +void EnTru_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + + if ((gSaveContext.save.entranceIndex != 0xC200) || (gSaveContext.save.weekEventReg[12] & 8)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 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 = SubS_GetDayDependentPath(globalCtx, ENTRU_GET_PATH(&this->actor), 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.save.weekEventReg[16] & 0x10) { + func_80A86924(this, 5); + } else { + this->unk_388 = EXCH_ITEM_NONE; + } + + 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) ? EXCH_ITEM_NONE : EXCH_ITEM_NONE; + + 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_MultZero(&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_MultVec3f(&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 EnTru_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTru* this = THIS; + s32 pad[3]; + s32 overrideRot; + s32 stepRot; + + if (this->unk_34E & 0x10) { + stepRot = false; + } else { + stepRot = true; + } + + if (this->unk_34E & 0x20) { + overrideRot = true; + } else { + overrideRot = false; + } + + if (!stepRot) { + overrideRot = false; + } + + if (limbIndex == 21) { + SubS_UpdateLimb(this->unk_366, this->unk_368 + this->actor.shape.rot.y, &this->unk_1EC, &this->unk_204, stepRot, + overrideRot); + Matrix_Pop(); + Matrix_Translate(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 (overrideRot) { + s16 oldZ = this->unk_204.z; + + this->unk_204.z = this->unk_204.x; + this->unk_204.x = oldZ; + } + Matrix_RotateYS(this->unk_204.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_204.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_204.z, MTXMODE_APPLY); + Matrix_Push(); + } +} + +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])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, + EnTru_TransformLimbDraw, &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..d1090cec4 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,57 @@ struct EnTru; typedef void (*EnTruActionFunc)(struct EnTru*, GlobalContext*); +typedef s32 (*EnTruUnkFunc)(Actor*, GlobalContext*); + +#define ENTRU_GET_PATH(thisx) ((thisx)->params & 0xFF) + +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.c b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.c index 53fe4b195..3be859a99 100644 --- a/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.c +++ b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.c @@ -1,6 +1,13 @@ -#include "z_en_tru_mt.h" +/* + * File: z_en_tru_mt.c + * Overlay: ovl_En_Tru_Mt + * Description: Koume's Target Game - Koume on Broom + */ -#define FLAGS 0x00000039 +#include "z_en_tru_mt.h" +#include "overlays/actors/ovl_En_Jc_Mato/z_en_jc_mato.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnTruMt*)thisx) @@ -13,7 +20,6 @@ void func_80B76A64(EnTruMt* this, GlobalContext* globalCtx); void func_80B76BB8(EnTruMt* this, GlobalContext* globalCtx); void func_80B76C38(EnTruMt* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Tru_Mt_InitVars = { ACTOR_EN_TRU_MT, ACTORCAT_NPC, @@ -26,15 +32,27 @@ const ActorInit En_Tru_Mt_InitVars = { (ActorFunc)EnTruMt_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80B77510 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 22 }, 100 }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B7753C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -69,58 +87,492 @@ static DamageTable D_80B7753C = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static AnimationInfoS D_80B7755C[] = { + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_0108AC, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_009348, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_00EEDC, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_014728, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_tru_Anim_01B5C4, 1.0f, 0, -1, ANIMMODE_ONCE, 0 }, + { &object_tru_Anim_007FA0, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_016B4C, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &object_tru_Anim_011F88, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_003698, 1.0f, 0, -1, ANIMMODE_ONCE, -4 }, + { &object_tru_Anim_002BD8, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, +}; -extern ColliderSphereInit D_80B77510; -extern DamageTable D_80B7753C; +Vec3f D_80B7765C = { 3000.0f, -800.0f, 0.0f }; -extern UNK_TYPE D_060004C8; -extern UNK_TYPE D_0601AA60; +Vec3f D_80B77668 = { 0.0f, 0.0f, -3000.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76030.s") +s32 func_80B76030(SkelAnime* skelAnime, s16 arg1) { + s16 endFrame; + s16 startFrame; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76110.s") + if ((arg1 >= 0) && (arg1 < ARRAY_COUNT(D_80B7755C))) { + endFrame = D_80B7755C[arg1].frameCount; + if (endFrame < 0) { + endFrame = Animation_GetLastFrame(D_80B7755C[arg1].animation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76188.s") + startFrame = D_80B7755C[arg1].startFrame; + if (startFrame < 0) { + startFrame = Animation_GetLastFrame(D_80B7755C[arg1].animation); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B761FC.s") + Animation_Change(skelAnime, D_80B7755C[arg1].animation, D_80B7755C[arg1].playSpeed, startFrame, endFrame, + D_80B7755C[arg1].mode, D_80B7755C[arg1].morphFrames); + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76368.s") +void func_80B76110(EnTruMt* this) { + if (DECR(this->unk_34E) == 0) { + this->unk_34C++; + if (this->unk_34C >= 3) { + this->unk_34E = Rand_S16Offset(30, 30); + this->unk_34C = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B763C4.s") +void func_80B76188(EnTruMt* this) { + this->unk_38E.x = Math_CosS(this->unk_38A) * this->unk_38C; + this->unk_38A += 0x1555; + Math_SmoothStepToS(&this->unk_38C, 0, 4, 0x3E8, 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76440.s") +s32 func_80B761FC(EnTruMt* this, GlobalContext* globalCtx) { + this->collider.dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.dim.worldSphere.center.y = this->actor.world.pos.y + 16.0f; + this->collider.dim.worldSphere.center.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76540.s") + if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == 0xF)) { + if (!(((EnJcMato*)this->actor.child)->collider.base.acFlags & AC_HIT) && + (this->actor.child->colChkInfo.damageEffect != 0xF)) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_3A4 == 0) { + this->unk_3A4 = 1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOUME_DAMAGE); + } else { + this->unk_3A4 = 0; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_KOUME_DAMAGE2); + } + globalCtx->interfaceCtx.unk_25E = 1; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 25); + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76600.s") + if (this->unk_38C >= 0xB7) { + func_80B76188(this); + } else { + this->unk_38E.x = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B7679C.s") + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B768F0.s") +s32 func_80B76368(EnTruMt* this, GlobalContext* globalCtx) { + Actor* bgActor = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76924.s") + while (bgActor != NULL) { + if (bgActor->id == ACTOR_BG_INGATE) { + this->unk_394 = bgActor->shape.rot.y; + this->unk_398 = bgActor->world.pos; + return true; + } + bgActor = bgActor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76980.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76A64.s") +s32 func_80B763C4(EnTruMt* this, GlobalContext* globalCtx) { + Actor* foundActor; + Actor* actor = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76BB8.s") + while (true) { + foundActor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_TRU_MT); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76C38.s") + if (foundActor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/EnTruMt_Init.s") + if ((EnTruMt*)foundActor != this) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/EnTruMt_Destroy.s") + foundActor = foundActor->next; + if (foundActor == NULL) { + break; + } + actor = foundActor; + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/EnTruMt_Update.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B76ED4.s") +void func_80B76440(EnTruMt* this, GlobalContext* globalCtx) { + if (func_80B76368(this, globalCtx)) { + s16 temp_v1 = this->unk_394 - Math_Vec3f_Yaw(&this->unk_398, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B77008.s") + if ((temp_v1 <= -0x2000) || (temp_v1 >= 0x2000)) { + Math_ApproachF(&this->actor.speedXZ, 7.0f, 0.2f, 1.0f); + } else if (this->actor.xzDistToPlayer < 300.0f) { + Math_ApproachF(&this->actor.speedXZ, 7.0f, 0.2f, 1.0f); + } else if (this->actor.xzDistToPlayer > 500.0f) { + Math_ApproachF(&this->actor.speedXZ, 2.5f, 0.2f, 1.0f); + } else { + Math_ApproachF(&this->actor.speedXZ, 4.0f, 0.2f, 1.0f); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B77078.s") +f32 func_80B76540(Path* path, s32 arg1, Vec3f* arg2, Vec3s* arg3) { + s32 pad; + Vec3f sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/func_80B77354.s") + if (path != NULL) { + Vec3s* temp_v1 = Lib_SegmentedToVirtual(path->points); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru_Mt/EnTruMt_Draw.s") + temp_v1 = &temp_v1[arg1]; + sp20.x = temp_v1->x; + sp20.y = temp_v1->y; + sp20.z = temp_v1->z; + } + arg3->y = Math_Vec3f_Yaw(arg2, &sp20); + arg3->x = Math_Vec3f_Pitch(arg2, &sp20); + + return sp20.y - arg2->y; +} + +s32 func_80B76600(EnTruMt* 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; + + Math_Vec3s_ToVec3f(&sp30, &sp5C[idx]); + + 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; + } + + 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; + } + + return sp50; +} + +void func_80B7679C(EnTruMt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; + + Math_SmoothStepToS(&this->unk_34A, (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - 0x4000, 4, 0x38E0, 1); + this->unk_34A = CLAMP(this->unk_34A, -0x38E0, 0x38E0); + + sp40 = player->actor.world.pos; + sp40.y = player->bodyPartsPos[7].y + 3.0f; + + sp34 = this->actor.world.pos; + sp34.y += 30.0f; + + Math_SmoothStepToS(&this->unk_348, Math_Vec3f_Pitch(&sp34, &sp40), 4, 0x1C70, 1); + this->unk_348 = CLAMP(this->unk_348, -0x1C70, 0x1C70); +} + +s32 func_80B768F0(EnTruMt* this, GlobalContext* globalCtx) { + if (this->unk_328 & 0x10) { + func_80B7679C(this, globalCtx); + } + return true; +} + +void func_80B76924(EnTruMt* this) { + this->unk_38E.z = Math_SinS(this->unk_388) * 30.0f * (0x10000 / 360.0f); + this->unk_388 += 0x400; +} + +void func_80B76980(EnTruMt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (gSaveContext.unk_3F3C >= 10) { + Message_StartTextbox(globalCtx, 0x87F, &this->actor); + gSaveContext.eventInf[3] |= 0x40; + gSaveContext.eventInf[4] |= 1; + player->stateFlags3 &= ~0x400; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80B76BB8; + } else if (gSaveContext.eventInf[4] & 1) { + u32 score = gSaveContext.minigameScore; + + if (((gSaveContext.save.unk_EE8 & 0xFFFF0000) >> 0x10) < score) { + gSaveContext.save.unk_EE8 = + ((gSaveContext.minigameScore & 0xFFFF) << 0x10) | (gSaveContext.save.unk_EE8 & 0xFFFF); + gSaveContext.eventInf[3] |= 0x80; + } + } +} + +void func_80B76A64(EnTruMt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3s sp34; + + func_80B76924(this); + func_80B76980(this, globalCtx); + player->stateFlags3 |= 0x400; + + if (this->path != NULL) { + func_80B76540(this->path, this->unk_36C, &this->actor.world.pos, &sp34); + Math_SmoothStepToS(&this->actor.world.rot.y, sp34.y, 4, 0x3E8, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.shape.rot.x, sp34.x, 4, 0x3E8, 1); + + this->actor.world.rot.x = -this->actor.shape.rot.x; + this->actor.shape.rot.z = CLAMP(this->actor.world.rot.y, -0x1770, 0x1770); + this->actor.world.rot.z = this->actor.shape.rot.z; + + if (func_80B76600(this, this->path, this->unk_36C)) { + if (this->unk_36C >= (this->path->count - 1)) { + this->actionFunc = func_80B76C38; + this->actor.speedXZ = 0.0f; + return; + } + this->unk_36C++; + } + func_80B76440(this, globalCtx); + } +} + +void func_80B76BB8(EnTruMt* this, GlobalContext* globalCtx) { + if (Message_GetState(&globalCtx->msgCtx) == 5) { + if (Message_ShouldAdvance(globalCtx)) { + globalCtx->nextEntranceIndex = 0xA810; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + globalCtx->sceneLoadFlag = 0x14; + } + } +} + +void func_80B76C38(EnTruMt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_80B76924(this); + func_80B76980(this, globalCtx); + player->stateFlags3 |= 0x400; +} + +void EnTruMt_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTruMt* this = THIS; + + if (!(gSaveContext.eventInf[3] & 0x20)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_80B763C4(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tru_Skel_01AA60, NULL, this->jointTable, this->morphTable, + OBJECT_TRU_LIMB_MAX); + + Collider_InitSphere(globalCtx, &this->collider); + Collider_SetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + + this->collider.dim.worldSphere.radius = 22; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->path = SubS_GetPathByIndex(globalCtx, ENTRUMT_GET_FF(&this->actor), 0x3F); + this->actor.targetMode = 0; + + Actor_SetScale(&this->actor, 0.008f); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + this->unk_328 = 0; + this->actor.room = -1; + this->path = SubS_GetPathByIndex(globalCtx, ENTRUMT_GET_FC00(&this->actor), 0x3F); + func_80B76030(&this->skelAnime, 14); + this->actionFunc = func_80B76A64; +} + +void EnTruMt_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTruMt* this = THIS; + + Collider_DestroySphere(globalCtx, &this->collider); +} + +void EnTruMt_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTruMt* this = THIS; + + func_80B768F0(this, globalCtx); + SkelAnime_Update(&this->skelAnime); + + this->actionFunc(this, globalCtx); + + func_80B76110(this); + Actor_SetFocus(&this->actor, 34.0f); + + if (!(gSaveContext.eventInf[4] & 1)) { + func_80B761FC(this, globalCtx); + } + + Actor_MoveWithoutGravity(&this->actor); +} + +void func_80B76ED4(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4) { + Vec3f sp7C; + Vec3f sp70 = gZeroVec3f; + Vec3s sp68; + MtxF sp28; + + Matrix_MultVec3f(&sp70, &sp7C); + Matrix_Get(&sp28); + Matrix_MtxFToYXZRot(&sp28, &sp68, false); + + *arg2 = sp7C; + + if (arg4 != 0) { + sp68.x += arg0; + sp68.y += arg1; + Math_SmoothStepToS(&arg3->x, sp68.x, 4, 0x1FFE, 1); + Math_SmoothStepToS(&arg3->y, sp68.y, 4, 0x1FFE, 1); + Math_SmoothStepToS(&arg3->z, sp68.z, 4, 0x1FFE, 1); + } else { + arg3->x = sp68.x; + arg3->y = sp68.y; + arg3->z = sp68.z; + } +} + +s32 EnTruMt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTruMt* this = THIS; + + if (limbIndex == OBJECT_TRU_LIMB_15) { + Matrix_MultVec3f(&gZeroVec3f, &this->unk_35C); + } + + if (limbIndex == OBJECT_TRU_LIMB_15) { + Matrix_MultVec3f(&D_80B7765C, &this->unk_350); + } + return false; +} + +void EnTruMt_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnTruMt* this = THIS; + MtxF* sp54; + s32 phi_v0; + + if (limbIndex == OBJECT_TRU_LIMB_15) { + if (this->unk_328 & 0x10) { + phi_v0 = 1; + } else { + phi_v0 = 0; + } + func_80B76ED4(this->unk_348, this->unk_34A, &this->unk_33C, &this->unk_336, phi_v0); + Matrix_Translate(this->unk_33C.x, this->unk_33C.y, this->unk_33C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_336.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_336.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_336.z, MTXMODE_APPLY); + } + + if (limbIndex == OBJECT_TRU_LIMB_0E) { + func_8012C28C(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_MultVec3f(&D_80B77668, &this->unk_370); + Matrix_Translate(this->unk_370.x, this->unk_370.y, this->unk_370.z, MTXMODE_NEW); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), MTXMODE_APPLY); + Matrix_RotateZS(this->unk_38E.z, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_38E.x, MTXMODE_APPLY); + Matrix_Scale(0.008f, 0.008f, 0.008f, 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_tru_DL_0004C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + sp54 = Matrix_GetCurrent(); + if ((this->actor.child == NULL) || (this->actor.child->update == NULL)) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_JC_MATO, sp54->xw, sp54->yw, + sp54->zw, this->unk_38E.x, BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))), + this->unk_38E.z, -1); + } else if (!((EnJcMato*)this->actor.child)->hitFlag) { + this->actor.child->world.pos.x = sp54->xw; + this->actor.child->world.pos.y = sp54->yw; + this->actor.child->world.pos.z = sp54->zw; + + this->actor.child->world.rot = this->unk_38E; + this->actor.child->world.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); + + this->actor.child->shape.rot = this->actor.child->world.rot; + } + } +} + +void EnTruMt_TransformLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTruMt* this = THIS; + + if (limbIndex == OBJECT_TRU_LIMB_15) { + Matrix_Translate(this->unk_33C.x, this->unk_33C.y, this->unk_33C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateYS(this->unk_336.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_336.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_336.z, MTXMODE_APPLY); + } +} + +void EnTruMt_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTruMt* this = THIS; + TexturePtr sp48[] = { + object_tru_Tex_018FA0, + object_tru_Tex_0197A0, + object_tru_Tex_019FA0, + }; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp48[this->unk_34C])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(sp48[this->unk_34C])); + + SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTruMt_OverrideLimbDraw, EnTruMt_PostLimbDraw, + EnTruMt_TransformLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..049c11ecd 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 @@ -2,15 +2,43 @@ #define Z_EN_TRU_MT_H #include "global.h" +#include "objects/object_tru/object_tru.h" struct EnTruMt; typedef void (*EnTruMtActionFunc)(struct EnTruMt*, GlobalContext*); +#define ENTRUMT_GET_FF(thisx) ((thisx)->params & 0xFF) +#define ENTRUMT_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + typedef struct EnTruMt { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTruMtActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x260]; + /* 0x0148 */ SkelAnime skelAnime; + /* 0x018C */ ColliderSphere collider; + /* 0x01E4 */ Vec3s jointTable[OBJECT_TRU_LIMB_MAX]; + /* 0x0286 */ Vec3s morphTable[OBJECT_TRU_LIMB_MAX]; + /* 0x0328 */ u16 unk_328; + /* 0x032A */ UNK_TYPE1 unk32A[0xC]; + /* 0x0336 */ Vec3s unk_336; + /* 0x033C */ Vec3f unk_33C; + /* 0x0348 */ s16 unk_348; + /* 0x034A */ s16 unk_34A; + /* 0x034C */ s16 unk_34C; + /* 0x034E */ s16 unk_34E; + /* 0x0350 */ Vec3f unk_350; + /* 0x035C */ Vec3f unk_35C; + /* 0x0368 */ Path* path; + /* 0x036C */ s32 unk_36C; + /* 0x0370 */ Vec3f unk_370; + /* 0x037C */ UNK_TYPE1 unk37C[0xC]; + /* 0x0388 */ s16 unk_388; + /* 0x038A */ s16 unk_38A; + /* 0x038C */ s16 unk_38C; + /* 0x038E */ Vec3s unk_38E; + /* 0x0394 */ s16 unk_394; + /* 0x0398 */ Vec3f unk_398; + /* 0x03A4 */ u8 unk_3A4; } EnTruMt; // size = 0x3A8 extern const ActorInit En_Tru_Mt_InitVars; diff --git a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c index f8129b237..217d32540 100644 --- a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c +++ b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.c @@ -1,6 +1,13 @@ -#include "z_en_tsn.h" +/* + * File: z_en_tsn.c + * Overlay: ovl_En_Tsn + * Description: Great Bay - Fisherman + */ -#define FLAGS 0x02000019 +#include "z_en_tsn.h" +#include "objects/object_tsn/object_tsn.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnTsn*)thisx) @@ -9,7 +16,18 @@ void EnTsn_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTsn_Update(Actor* thisx, GlobalContext* globalCtx); void EnTsn_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80AE0010(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0304(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0418(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0460(EnTsn* this, GlobalContext* globalCtx); +void func_80AE04C4(EnTsn* this, GlobalContext* globalCtx); +void func_80AE04FC(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0704(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0C88(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0D10(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0D78(EnTsn* this, GlobalContext* globalCtx); +void func_80AE0F84(Actor* thisx, GlobalContext* globalCtx); + const ActorInit En_Tsn_InitVars = { ACTOR_EN_TSN, ACTORCAT_NPC, @@ -22,58 +40,597 @@ const ActorInit En_Tsn_InitVars = { (ActorFunc)EnTsn_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AE1190 = { - { 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_80AE11BC = { 0.0f, 0.0f, 0.0f }; -extern ColliderCylinderInit D_80AE1190; +TexturePtr D_80AE11C8[] = { object_tsn_Tex_0073B8, object_tsn_Tex_0085B8 }; -extern UNK_TYPE D_06001198; -extern UNK_TYPE D_060092FC; +EnTsn* func_80ADFCA0(GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFCA0.s") + while (npc != NULL) { + if ((npc->id == ACTOR_EN_TSN) && !ENTSN_GET_100(npc)) { + return (EnTsn*)npc; + } + npc = npc->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFCEC.s") + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Init.s") +void func_80ADFCEC(EnTsn* this, GlobalContext* globalCtx) { + this->actionFunc = func_80AE0C88; + this->actor.update = func_80AE0F84; + this->actor.destroy = NULL; + this->actor.draw = NULL; + this->actor.targetMode = 7; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Destroy.s") + switch (ENTSN_GET_F(&this->actor)) { + case ENTSN_F_0: + if (gSaveContext.save.weekEventReg[26] & 8) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.textId = 0x106E; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80ADFF84.s") + case ENTSN_F_1: + if (gSaveContext.save.weekEventReg[26] & 4) { + this->actor.textId = 0x1091; + } else { + this->actor.textId = 0x108A; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0010.s") + if (gSaveContext.save.weekEventReg[55] & 0x80) { + if ((ENTSN_GET_F(&this->actor)) == ENTSN_F_0) { + this->actionFunc = func_80AE0D78; + } else { + Actor_MarkForDeath(&this->actor); + } + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0304.s") + this->unk_1D8 = func_80ADFCA0(globalCtx); + this->unk_220 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0418.s") + if (this->unk_1D8 == NULL) { + Actor_MarkForDeath(&this->actor); + } else if ((ENTSN_GET_F(&this->actor)) == ENTSN_F_1) { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 6); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0460.s") +void EnTsn_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE04C4.s") + if (ENTSN_GET_100(&this->actor)) { + func_80ADFCEC(this, globalCtx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE04FC.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tsn_Skel_008AB8, &object_tsn_Anim_0092FC, NULL, NULL, 0); + Animation_PlayLoop(&this->skelAnime, &object_tsn_Anim_0092FC); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0698.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_220 = 0; + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0704.s") + if (gSaveContext.save.weekEventReg[55] & 0x80) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0C88.s") +void EnTsn_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0D10.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0D78.s") +void func_80ADFF84(EnTsn* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Update.s") + if (gSaveContext.save.weekEventReg[26] & 8) { + textId = 0x107E; + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[25] & 0x80) { + textId = 0x1083; + } else { + textId = 0x107F; + } + } else if (gSaveContext.save.weekEventReg[26] & 1) { + textId = 0x1089; + } else { + textId = 0x1084; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0F84.s") + Message_StartTextbox(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE0FA8.s") +void func_80AE0010(EnTsn* this, GlobalContext* globalCtx) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x107F: + case 0x1080: + case 0x1081: + case 0x1082: + case 0x1083: + case 0x1084: + case 0x1085: + case 0x1086: + case 0x1087: + case 0x1088: + case 0x1089: + case 0x1093: + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + this->actor.shape.rot.y = this->actor.world.rot.y; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/func_80AE1024.s") + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x107F: + case 0x1081: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tsn/EnTsn_Draw.s") + case 0x1080: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_001198, -10.0f); + break; + + case 0x1082: + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + gSaveContext.save.weekEventReg[25] |= 0x80; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1083: + gSaveContext.save.weekEventReg[25] |= 0x80; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1084: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_000964, -10.0f); + break; + + case 0x1085: + case 0x1086: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1089: + case 0x1093: + gSaveContext.save.weekEventReg[26] |= 1; + func_801477B4(globalCtx); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + + case 0x1087: + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_001198, -10.0f); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1088: + gSaveContext.save.weekEventReg[26] |= 1; + if (INV_CONTENT(ITEM_MASK_ZORA) == ITEM_MASK_ZORA) { + func_801477B4(globalCtx); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + } else { + func_80151938(globalCtx, 0x1093); + Animation_MorphToLoop(&this->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + } + break; + + case 0x107E: + func_801477B4(globalCtx); + this->actionFunc = func_80AE0304; + this->actor.textId = 0; + break; + } + } +} + +void func_80AE0304(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0010; + this->unk_220 |= 1; + if (this->actor.textId == 0) { + func_80ADFF84(this, globalCtx); + } + } else if ((this->actor.xzDistToPlayer < 150.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 160.0f); + this->unk_220 |= 1; + } else { + this->unk_220 &= ~1; + } + if (ENTSN_GET_Z(&this->actor)) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 6, 0x1838, 0x64); + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.home.rot.y, 6, 0x1838, 0x64); + } + this->actor.shape.rot.y = this->actor.world.rot.y; +} + +void func_80AE0418(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + Message_StartTextbox(globalCtx, 0x107D, NULL); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80AE0460(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + ENTSN_SET_Z(&this->unk_1D8->actor, false); + this->actionFunc = func_80AE0418; + } else { + Actor_PickUp(&this->actor, globalCtx, GI_95, 2000.0f, 1000.0f); + } +} + +void func_80AE04C4(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->actionFunc = func_80AE0C88; + } +} + +void func_80AE04FC(EnTsn* this, GlobalContext* globalCtx) { + s32 sp24; + Player* player = GET_PLAYER(globalCtx); + + if (Message_GetState(&globalCtx->msgCtx) == 0x10) { + sp24 = func_80123810(globalCtx); + if (sp24 != 0) { + gSaveContext.save.weekEventReg[26] |= 2; + } + + if (sp24 > 0) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0704; + if (sp24 == 19) { + if (CHECK_QUEST_ITEM(QUEST_UNK_19)) { + if (func_8013A4C4(1 | 8)) { + player->actor.textId = 0x107B; + return; + } + + if (func_8013A4C4(1 | 2 | 8)) { + player->actor.textId = 0x10A9; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + if (sp24 == 13) { + player->actor.textId = 0x1075; + return; + } + + player->actor.textId = 0x1078; + this->unk_220 |= 8; + return; + } + + if (sp24 < 0) { + func_80151938(globalCtx, 0x1078); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_001198, -10.0f); + this->actionFunc = func_80AE0704; + } + } +} + +void func_80AE0698(EnTsn* this, GlobalContext* globalCtx) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0C88; + this->unk_220 &= ~2; + this->actor.focus.pos = this->actor.world.pos; + ActorCutscene_Stop(this->actor.cutscene); + ENTSN_SET_Z(&this->unk_1D8->actor, false); +} + +void func_80AE0704(EnTsn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad[2]; + + if ((this->unk_220 & 8) && (globalCtx->msgCtx.currentTextId == 0x1078)) { + this->unk_220 &= ~8; + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_001198, -10.0f); + } + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 2: + break; + + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x106E: + if (gSaveContext.save.weekEventReg[25] & 0x40) { + func_80151938(globalCtx, 0x1074); + } else { + func_80151938(globalCtx, 0x106F); + } + this->unk_220 |= 2; + gSaveContext.save.weekEventReg[25] |= 0x40; + ENTSN_SET_Z(&this->unk_1D8->actor, true); + this->unk_220 |= 4; + break; + + case 0x106F: + case 0x1070: + case 0x1071: + case 0x1072: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1076: + case 0x1079: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_000964, -10.0f); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x107A: + func_80151938(globalCtx, 0x10A6); + break; + + case 0x1075: + case 0x1078: + player->exchangeItemId = 0; + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + break; + + case 0x107C: + if (Interface_HasEmptyBottle()) { + gSaveContext.save.weekEventReg[26] |= 8; + func_801477B4(globalCtx); + this->actionFunc = func_80AE0460; + func_80AE0460(this, globalCtx); + this->unk_220 &= ~2; + this->actor.focus.pos = this->actor.world.pos; + ActorCutscene_Stop(this->actor.cutscene); + this->actor.flags &= ~ACTOR_FLAG_100; + REMOVE_QUEST_ITEM(QUEST_UNK_19); + } else { + func_80151938(globalCtx, 0x10A8); + } + break; + + case 0x1073: + case 0x1074: + func_80151938(globalCtx, 0xFF); + this->actionFunc = func_80AE04FC; + break; + + case 0x107B: + player->exchangeItemId = 0; + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + break; + + case 0x1077: + case 0x10A6: + case 0x10A8: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + func_80AE0698(this, globalCtx); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_80AE04C4; + break; + + case 0x108A: + case 0x1091: + gSaveContext.save.weekEventReg[26] |= 4; + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + this->unk_220 |= 2; + this->actor.textId = 0x1091; + break; + + case 0x108B: + case 0x108C: + case 0x108D: + case 0x108E: + case 0x108F: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1092: + if (gSaveContext.save.weekEventReg[26] & 8) { + func_80AE0698(this, globalCtx); + } else { + func_80151938(globalCtx, 0x10A7); + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_000964, -10.0f); + } + break; + + case 0x10A7: + Animation_MorphToLoop(&this->unk_1D8->skelAnime, &object_tsn_Anim_0092FC, -10.0f); + func_80AE0698(this, globalCtx); + break; + + case 0x1090: + func_80AE0698(this, globalCtx); + break; + + case 0x10A9: + func_80AE0698(this, globalCtx); + this->actor.flags &= ~ACTOR_FLAG_100; + this->actionFunc = func_80AE04C4; + break; + } + } + } + + if (this->unk_220 & 2) { + if (this->unk_1D8 != NULL) { + Math_SmoothStepToF(&this->actor.focus.pos.x, this->unk_1D8->actor.focus.pos.x, 0.8f, 100.0f, 5.0f); + Math_SmoothStepToF(&this->actor.focus.pos.y, this->unk_1D8->actor.focus.pos.y, 0.8f, 100.0f, 5.0f); + Math_SmoothStepToF(&this->actor.focus.pos.z, this->unk_1D8->actor.focus.pos.z, 0.8f, 100.0f, 5.0f); + } + } + + if (this->unk_220 & 4) { + if (this->actor.cutscene == -1) { + this->unk_220 &= ~4; + } else if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->unk_220 &= ~4; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} + +void func_80AE0C88(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0704; + if ((this->actor.textId == 0x108A) || (this->actor.textId == 0x1091)) { + this->unk_220 |= 4; + ENTSN_SET_Z(&this->unk_1D8->actor, true); + } + } else if (this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 1000.0f); + } +} + +void func_80AE0D10(EnTsn* this, GlobalContext* globalCtx) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = func_80AE0D78; + ActorCutscene_Stop(this->actor.cutscene); + } +} + +void func_80AE0D78(EnTsn* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80AE0D10; + this->unk_220 |= 4; + } else if (this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 1000.0f); + } +} + +void EnTsn_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTsn* this = THIS; + + this->actionFunc(this, globalCtx); + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 25.0f, 0.0f, 4); + SkelAnime_Update(&this->skelAnime); + + if (this->unk_220 & 1) { + func_800E9250(globalCtx, &this->actor, &this->unk_222, &this->unk_228, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_222.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_222.y, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_228.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_228.y, 0, 6, 0x1838, 0x64); + } + + if (DECR(this->unk_230) == 0) { + this->unk_230 = Rand_S16Offset(60, 60); + } + + if ((this->unk_230 == 1) || (this->unk_230 == 3)) { + this->unk_22E = 1; + } else { + this->unk_22E = 0; + } +} + +void func_80AE0F84(Actor* thisx, GlobalContext* globalCtx) { + EnTsn* this = THIS; + + this->actionFunc(this, globalCtx); +} + +s32 EnTsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnTsn* this = THIS; + s16 shifted = this->unk_222.x >> 1; + + if (limbIndex == 15) { + rot->x += this->unk_222.y; + rot->z += shifted; + } + + if (limbIndex == 8) { + rot->x += this->unk_228.y; + rot->z += shifted; + } + return false; +} + +void EnTsn_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTsn* this = THIS; + Vec3f sp18 = D_80AE11BC; + + if (limbIndex == 15) { + Matrix_MultVec3f(&sp18, &this->actor.focus.pos); + } +} + +void EnTsn_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTsn* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C5B0(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80AE11C8[this->unk_22E])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80AE11C8[this->unk_22E])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTsn_OverrideLimbDraw, EnTsn_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h index 6b7810cf6..64df6ac42 100644 --- a/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h +++ b/src/overlays/actors/ovl_En_Tsn/z_en_tsn.h @@ -7,11 +7,26 @@ struct EnTsn; typedef void (*EnTsnActionFunc)(struct EnTsn*, GlobalContext*); +#define ENTSN_GET_F(thisx) ((thisx)->params & 0xF) +#define ENTSN_GET_100(thisx) ((thisx)->params & 0x100) +#define ENTSN_GET_Z(thisx) ((thisx)->home.rot.z) +#define ENTSN_SET_Z(thisx, state) ((thisx)->home.rot.z = state) + +#define ENTSN_F_0 0 +#define ENTSN_F_1 1 + typedef struct EnTsn { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ SkelAnime skelAnime; /* 0x01D4 */ EnTsnActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x5C]; + /* 0x01D8 */ struct EnTsn* unk_1D8; + /* 0x01DC */ UNK_TYPE1 unk1DC[0x44]; + /* 0x0220 */ u16 unk_220; + /* 0x0222 */ Vec3s unk_222; + /* 0x0228 */ Vec3s unk_228; + /* 0x022E */ s16 unk_22E; + /* 0x0230 */ s16 unk_230; } EnTsn; // size = 0x234 extern const ActorInit En_Tsn_InitVars; diff --git a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c index 06ef6ef3f..18476aa4e 100644 --- a/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c +++ b/src/overlays/actors/ovl_En_Tubo_Trap/z_en_tubo_trap.c @@ -1,4 +1,11 @@ +/* + * File: z_en_tubo_trap.c + * Overlay: ovl_En_Tubo_Trap + * Description: Flying Pot Trap Enemy + */ + #include "z_en_tubo_trap.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" #define FLAGS 0x00000000 @@ -57,7 +64,7 @@ void EnTuboTrap_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); this->actor.shape.rot.z = 0; this->actor.world.rot.z = 0; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 1.8f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 1.8f); Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); this->actionFunc = EnTuboTrap_Idle; @@ -71,10 +78,10 @@ void EnTuboTrap_Destroy(Actor* thisx, GlobalContext* globalCtx) { void EnTuboTrap_DropCollectible(EnTuboTrap* this, GlobalContext* globalCtx) { s32 itemParam = ((this->actor.params >> 8) & 0x3F); - s32 dropCount = func_800A8150(itemParam); + s32 dropItem00Id = func_800A8150(itemParam); - if (dropCount >= 0) { - Item_DropCollectible(globalCtx, &this->actor.world.pos, ((this->actor.params & 0x7F) << 8) | dropCount); + if (dropItem00Id > ITEM00_NO_DROP) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ((this->actor.params & 0x7F) << 8) | dropItem00Id); } } @@ -113,7 +120,8 @@ void EnTuboTrap_SpawnEffectsOnLand(EnTuboTrap* this, GlobalContext* globalCtx) { arg5 = 0x20; } EffectSsKakera_Spawn(globalCtx, &pos, &vel, actorPos, -0xF0, arg5, 0x14, 0, 0, - ((Rand_ZeroOne() * 85.0f) + 15.0f), 0, 0, 0x3C, -1, GAMEPLAY_DANGEON_KEEP, D_05018090); + ((Rand_ZeroOne() * 85.0f) + 15.0f), 0, 0, 0x3C, -1, GAMEPLAY_DANGEON_KEEP, + gameplay_dangeon_keep_DL_018090); } func_800BBFB0(globalCtx, actorPos, 30.0f, 4, 0x14, 0x32, 0); @@ -131,7 +139,7 @@ void EnTuboTrap_SpawnEffectsInWater(EnTuboTrap* this, GlobalContext* globalCtx) Vec3f* actorPos = &this->actor.world.pos; pos = *actorPos; - pos.y += this->actor.yDistToWater; + pos.y += this->actor.depthInWater; EffectSsGSplash_Spawn(globalCtx, &pos, NULL, NULL, 0, 0x190); @@ -158,7 +166,8 @@ void EnTuboTrap_SpawnEffectsInWater(EnTuboTrap* this, GlobalContext* globalCtx) } EffectSsKakera_Spawn(globalCtx, &pos, &vel, actorPos, -0xAA, arg5, 0x32, 5, 0, - ((Rand_ZeroOne() * 85.0f) + 15.0f), 0, 0, 0x46, -1, GAMEPLAY_DANGEON_KEEP, D_05018090); + ((Rand_ZeroOne() * 85.0f) + 15.0f), 0, 0, 0x46, -1, GAMEPLAY_DANGEON_KEEP, + gameplay_dangeon_keep_DL_018090); } } @@ -166,9 +175,9 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); Player* player2 = GET_PLAYER(globalCtx); - if ((this->actor.bgCheckFlags & 0x20) && (this->actor.yDistToWater > 15.0f)) { + if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 15.0f)) { EnTuboTrap_SpawnEffectsInWater(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_BOMB_DROP_WATER); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_BOMB_DROP_WATER); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -177,8 +186,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (this->collider.base.atFlags & AT_BOUNCED) { this->collider.base.atFlags &= ~AT_BOUNCED; EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_SHIELD_REFLECT_SW); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_SHIELD_REFLECT_SW); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -187,8 +196,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (this->collider.base.acFlags & AC_HIT) { this->collider.base.acFlags &= ~AC_HIT; EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_EXPLOSION); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -199,8 +208,8 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if (&player->actor == this->collider.base.at) { EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); - Audio_PlaySoundAtPosition(globalCtx, &player2->actor.world.pos, 40, NA_SE_PL_BODY_HIT); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &player2->actor.world.pos, 40, NA_SE_PL_BODY_HIT); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); return; @@ -209,7 +218,7 @@ void EnTuboTrap_HandleImpact(EnTuboTrap* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 8) || (this->actor.bgCheckFlags & 1)) { EnTuboTrap_SpawnEffectsOnLand(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_POT_BROKEN); EnTuboTrap_DropCollectible(this, globalCtx); Actor_MarkForDeath(&this->actor); } @@ -226,10 +235,10 @@ void EnTuboTrap_Idle(EnTuboTrap* this, GlobalContext* globalCtx) { if ((this->actor.xzDistToPlayer < 200.0f) && (this->actor.world.pos.y <= player->actor.world.pos.y)) { startingRotation = this->actor.home.rot.z; - if ((startingRotation == 0) || (this->actor.yDistToPlayer <= (startingRotation * 10.0f))) { + if ((startingRotation == 0) || (this->actor.playerHeightRel <= (startingRotation * 10.0f))) { func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_ENEMY); currentHeight = this->actor.world.pos.y; - this->actor.flags |= 0x11; // always update and can target + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_10); // always update and can target transformationHeight = sTransformationHeight[player->transformation]; @@ -239,7 +248,7 @@ void EnTuboTrap_Idle(EnTuboTrap* this, GlobalContext* globalCtx) { this->targetHeight += transformationHeight; } this->originPos = this->actor.world.pos; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_POT_MOVE_START); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_POT_MOVE_START); this->actionFunc = EnTuboTrap_Levitate; } } @@ -266,7 +275,7 @@ void EnTuboTrap_FlyAtPlayer(EnTuboTrap* this, GlobalContext* globalCtx) { // But in MM, certain sfxIds got reordered and devs forgot to update: // In MM, NA_SE_EN_MIZUBABA2_ATTACK is the old value 0x3837 // In MM, NA_SE_EN_TUBOOCK_FLY is the new value 0x3AE0 - Audio_PlayActorSound2(&this->actor, NA_SE_EN_MIZUBABA2_ATTACK - SFX_FLAG); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_MIZUBABA2_ATTACK - SFX_FLAG); if ((SQ(dX) + SQ(dY) + SQ(dZ) > SQ(240.0f))) { Math_ApproachF(&this->actor.gravity, -3.0f, 0.2f, 0.5f); @@ -281,17 +290,17 @@ void EnTuboTrap_Update(Actor* thisx, GlobalContext* globalCtx) { s32 padding; this->actionFunc(this, globalCtx); - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f, 10.0f, 20.0f, 0x1F); - Actor_SetHeight(&this->actor, 0.0f); + Actor_SetFocus(&this->actor, 0.0f); if (this->actor.projectedPos.z < 811.0f) { if (this->actor.projectedPos.z > 300.0f) { this->actor.shape.shadowAlpha = (u8)((811 - (s32)this->actor.projectedPos.z) >> 1); - this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; } else if (this->actor.projectedPos.z > -10.0f) { this->actor.shape.shadowAlpha = 255; - this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; } else { this->actor.shape.shadowDraw = NULL; } @@ -305,6 +314,5 @@ void EnTuboTrap_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnTuboTrap_Draw(Actor* thisx, GlobalContext* globalCtx) { - // Gfx_DrawDListOpa with a display list - func_800BDFC0(globalCtx, D_05017EA0); + Gfx_DrawDListOpa(globalCtx, gameplay_dangeon_keep_DL_017EA0); } diff --git a/src/overlays/actors/ovl_En_Twig/z_en_twig.c b/src/overlays/actors/ovl_En_Twig/z_en_twig.c index 383354eed..c2cae36c3 100644 --- a/src/overlays/actors/ovl_En_Twig/z_en_twig.c +++ b/src/overlays/actors/ovl_En_Twig/z_en_twig.c @@ -1,6 +1,12 @@ +/* + * File: z_en_twig.c + * Overlay: ovl_En_Twig + * Description: Beaver Race Ring + */ + #include "z_en_twig.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnTwig*)thisx) diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c index e3ceb9721..170cc6edb 100644 --- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c +++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.c @@ -1,6 +1,12 @@ +/* + * File: z_en_viewer.c + * Overlay: ovl_En_Viewer + * Description: Cutscene Actors? + */ + #include "z_en_viewer.h" -#define FLAGS 0x00200030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_200000) #define THIS ((EnViewer*)thisx) 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_Vm/z_en_vm.c b/src/overlays/actors/ovl_En_Vm/z_en_vm.c index 2b7072ab6..77449c7a3 100644 --- a/src/overlays/actors/ovl_En_Vm/z_en_vm.c +++ b/src/overlays/actors/ovl_En_Vm/z_en_vm.c @@ -1,6 +1,15 @@ -#include "z_en_vm.h" +/* + * File: z_en_vm.c + * Overlay: ovl_En_Vm + * Description: Beamos + */ -#define FLAGS 0x00000405 +#include "z_en_vm.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_vm/object_vm.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_400) #define THIS ((EnVm*)thisx) @@ -9,7 +18,17 @@ void EnVm_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnVm_Update(Actor* thisx, GlobalContext* globalCtx); void EnVm_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_808CC420(EnVm* this); +void func_808CC490(EnVm* this, GlobalContext* globalCtx); +void func_808CC5C4(EnVm* this); +void func_808CC610(EnVm* this, GlobalContext* globalCtx); +void func_808CC788(EnVm* this); +void func_808CC820(EnVm* this, GlobalContext* globalCtx); +void func_808CCAA4(EnVm* this, GlobalContext* globalCtx); +void func_808CCB08(EnVm* this); +void func_808CCB50(EnVm* this, GlobalContext* globalCtx); +void func_808CCCF0(EnVm* this, GlobalContext* globalCtx); + const ActorInit En_Vm_InitVars = { ACTOR_EN_VM, ACTORCAT_ENEMY, @@ -22,40 +41,72 @@ const ActorInit En_Vm_InitVars = { (ActorFunc)EnVm_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_808CD4C0[2] = { +static ColliderJntSphElementInit sJntSphElementsInit[] = { { - { 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, + }, { 2, { { 0, 0, 0 }, 20 }, 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, + }, { 10, { { 0, 2300, 0 }, 33 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808CD508 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_808CD4C0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit, }; -// static ColliderTrisElementInit sTrisElementsInit[1] = { -static ColliderTrisElementInit D_808CD518[1] = { +static ColliderTrisElementInit sTrisElementsInit[] = { { - { 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_808CD554 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 1, D_808CD518, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + 1, + sTrisElementsInit, }; -// static DamageTable sDamageTable = { -static DamageTable D_808CD564 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xF), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0xF), @@ -90,62 +141,417 @@ static DamageTable D_808CD564 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808CD584 = { 2, 25, 100, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 2, 25, 100, MASS_IMMOVABLE }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808CD5AC[] = { +TexturePtr D_808CD58C[] = { + gameplay_keep_Tex_03F300, gameplay_keep_Tex_03FB00, gameplay_keep_Tex_040300, gameplay_keep_Tex_040B00, + gameplay_keep_Tex_041300, gameplay_keep_Tex_041B00, gameplay_keep_Tex_042300, gameplay_keep_Tex_042B00, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 14, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_CONTINUE), ICHAIN_S8(hintId, 57, ICHAIN_STOP), }; -#endif +s32 D_808CD5B8 = false; -extern ColliderJntSphElementInit D_808CD4C0[2]; -extern ColliderJntSphInit D_808CD508; -extern ColliderTrisElementInit D_808CD518[1]; -extern ColliderTrisInit D_808CD554; -extern DamageTable D_808CD564; -extern CollisionCheckInfoInit D_808CD584; -extern InitChainEntry D_808CD5AC[]; +Color_RGBA8 D_808CD5BC = { 0, 0, 255, 0 }; -extern UNK_TYPE D_06000068; +Color_RGBA8 D_808CD5C0 = { 255, 255, 255, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/EnVm_Init.s") +void EnVm_Init(Actor* thisx, GlobalContext* globalCtx) { + EnVm* this = THIS; + s32 i; + s32 params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/EnVm_Destroy.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 35.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_vm_Skel_003F60, &object_vm_Anim_000068, this->jointTable, + this->morphTable, 11); + Collider_InitAndSetTris(globalCtx, &this->colliderTris, &this->actor, &sTrisInit, this->colliderTrisElements); + Collider_InitAndSetJntSph(globalCtx, &this->colliderJntSph, &this->actor, &sJntSphInit, + this->colliderJntSphElements); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC420.s") + params = ENVM_GET_FF00(thisx); + if ((params == ENVM_FF00_FF) || (params == ENVM_FF00_0)) { + params = ENVM_FF00_5; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC490.s") + this->unk_21C = params * 40.0f; + thisx->params &= 0xFF; + this->actor.bgCheckFlags |= 0x400; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC5C4.s") + if (!D_808CD5B8) { + for (i = 0; i < ARRAY_COUNT(D_808CD58C); i++) { + D_808CD58C[i] = Lib_SegmentedToVirtual(D_808CD58C[i]); + } + D_808CD5B8 = true; + } + func_808CC420(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC610.s") +void EnVm_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnVm* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC788.s") + Collider_DestroyTris(globalCtx, &this->colliderTris); + Collider_DestroyJntSph(globalCtx, &this->colliderJntSph); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CC820.s") +void func_808CC420(EnVm* this) { + f32 lastFrame = Animation_GetLastFrame(&object_vm_Anim_000068); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCA10.s") + Animation_Change(&this->skelAnime, &object_vm_Anim_000068, 1.0f, lastFrame, lastFrame, ANIMMODE_ONCE, 0.0f); + this->actionFunc = func_808CC490; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCAA4.s") +void func_808CC490(EnVm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp22; + s16 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCB08.s") + Math_ApproachS(&this->unk_216, 0, 0xA, 0x5DC); + this->unk_218 -= 0x1F4; + func_800B9010(&this->actor, NA_SE_EN_BIMOS_ROLL_HEAD - SFX_FLAG); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCB50.s") + if (this->actor.xzDistToPlayer <= this->unk_21C) { + if ((this->actor.playerHeightRel <= 80.0f) && (this->actor.playerHeightRel >= -160.0f)) { + sp22 = BINANG_SUB(this->actor.yawTowardsPlayer - this->unk_218, this->actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCBE4.s") + temp_v0 = Math_Vec3f_Pitch(&this->actor.focus.pos, &player->actor.world.pos); + if (temp_v0 > 0x1B91) { + temp_v0 = 0x1B91; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCCF0.s") + if ((ABS_ALT(sp22) <= 0x2710) && (temp_v0 >= 0xE38) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE)) { + func_808CC5C4(this); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CCDE4.s") +void func_808CC5C4(EnVm* this) { + Animation_PlayLoopSetSpeed(&this->skelAnime, &object_vm_Anim_000068, 2.0f); + this->unk_214 = 10; + this->actionFunc = func_808CC610; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/EnVm_Update.s") +void func_808CC610(EnVm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp3A; + s16 sp38; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CD020.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/func_808CD08C.s") + sp38 = Math_Vec3f_Pitch(&this->actor.focus.pos, &player->actor.world.pos); + sp38 = CLAMP_MAX(sp38, 0x1B91); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Vm/EnVm_Draw.s") + sp3A = BINANG_ADD((s32)((this->unk_21C - this->actor.xzDistToPlayer) * 60.0f), 4000); + sp3A = CLAMP_MAX(sp3A, 0x1000); + + Math_SmoothStepToS(&this->unk_216, sp38, 10, 4000, 0); + + if ((sp38 < 0xAAA) || (sp3A <= 0)) { + func_808CC420(this); + } else if (Math_ScaledStepToS(&this->unk_218, BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y), + sp3A)) { + this->unk_214--; + if (this->unk_214 == 0) { + EffectSsDeadDd_Spawn(globalCtx, &this->unk_228, &gZeroVec3f, &gZeroVec3f, &D_808CD5BC, &D_808CD5C0, 150, + -25, 16, 20); + func_808CC788(this); + } + } +} + +void func_808CC788(EnVm* this) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BIMOS_AIM); + Animation_Change(&this->skelAnime, &object_vm_Anim_000068, 3.0f, 3.0f, 7.0f, ANIMMODE_ONCE, 0.0f); + this->unk_214 = 305; + this->unk_220 = 0.06f; + this->colliderTris.base.atFlags &= ~AT_HIT; + this->actionFunc = func_808CC820; +} + +void func_808CC820(EnVm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp32; + f32 temp_f2; + + if (SkelAnime_Update(&this->skelAnime)) { + this->skelAnime.curFrame = this->skelAnime.startFrame; + } + + sp32 = Math_Vec3f_Pitch(&this->actor.focus.pos, &player->actor.world.pos); + sp32 = CLAMP_MAX(sp32, 0x1B91); + + if (this->colliderTris.base.atFlags & AT_HIT) { + this->colliderTris.base.atFlags &= ~AT_HIT; + this->unk_214 = 0; + if (this->unk_220 > 0.01f) { + this->unk_220 = 0.01f; + } + } + + if ((this->unk_216 < 0xAAA) || (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) || (this->unk_214 == 0)) { + this->unk_214 = 0; + if (Math_StepToF(&this->unk_220, 0.0f, 0.003f)) { + this->unk_210 = 0; + this->unk_224 = 0.0f; + func_808CC420(this); + } + } else { + this->unk_214--; + if (this->unk_214 <= 300) { + Math_ApproachS(&this->unk_218, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 0xA, 0xDAC); + Math_ApproachS(&this->unk_216, sp32, 0xA, 0xDAC); + + temp_f2 = Math_Vec3f_DistXYZ(&this->actor.focus.pos, &player->actor.world.pos) + 40.0f; + if (this->unk_224 < temp_f2) { + Math_StepToF(&this->unk_224, temp_f2, 40.0f); + } + + Math_StepToF(&this->unk_220, 0.01f, 0.012f); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + + if (this->unk_210 == 0) { + this->unk_210 = 1; + } + } + } +} + +void func_808CCA10(EnVm* this) { + Animation_Change(&this->skelAnime, &object_vm_Anim_000068, -1.0f, Animation_GetLastFrame(&object_vm_Anim_000068), + 0.0f, ANIMMODE_ONCE, 0.0f); + this->unk_214 = 100; + this->unk_210 = 0; + this->unk_224 = 0.0f; + this->unk_220 = 0.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = func_808CCAA4; +} + +void func_808CCAA4(EnVm* this, GlobalContext* globalCtx) { + Math_ApproachS(&this->unk_216, 0, 0xA, 0x5DC); + SkelAnime_Update(&this->skelAnime); + if (this->unk_214 == 0) { + func_808CCB08(this); + } else { + this->unk_214--; + } +} + +void func_808CCB08(EnVm* this) { + Animation_PlayOnce(&this->skelAnime, &object_vm_Anim_000068); + this->unk_214 = -1; + this->actionFunc = func_808CCB50; +} + +void func_808CCB50(EnVm* this, GlobalContext* globalCtx) { + Math_ApproachS(&this->unk_216, 0, 0xA, 0x5DC); + + if (this->unk_214 > 0) { + this->unk_214--; + } else if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_214 == -1) { + this->unk_214 = 10; + this->skelAnime.curFrame = 0.0f; + this->skelAnime.playSpeed = 2.0f; + } else { + func_808CC420(this); + } + } +} + +void func_808CCBE4(EnVm* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &object_vm_Anim_000068, -1.0f, Animation_GetLastFrame(&object_vm_Anim_000068), + 0.0f, ANIMMODE_ONCE, 0.0f); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 33); + this->unk_214 = 33; + this->unk_220 = 0.0f; + this->unk_224 = 0.0f; + this->actor.shape.yOffset = (this->actor.world.pos.y - this->actor.focus.pos.y) * 71.428566f; + this->actor.world.pos.y = this->actor.focus.pos.y; + this->actor.velocity.y = 8.0f; + this->actor.gravity = -0.5f; + this->actor.speedXZ = Rand_ZeroOne() + 1.0f; + this->unk_210 = 0; + this->actor.flags |= ACTOR_FLAG_10; + this->actionFunc = func_808CCCF0; +} + +void func_808CCCF0(EnVm* this, GlobalContext* globalCtx) { + this->unk_216 += 0x5DC; + this->unk_218 += 0x9C4; + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 40.0f, 7); + + this->unk_214--; + if (this->unk_214 == 1) { + 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, 0x6FF, 0); + + if (bomb != NULL) { + bomb->timer = 0; + } + } else if (this->unk_214 == 0) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xB0); + Actor_MarkForDeath(&this->actor); + } +} + +void func_808CCDE4(EnVm* this, GlobalContext* globalCtx) { + s32 i; + s16 temp_v0; + + if (this->colliderJntSph.base.acFlags & AC_HIT) { + this->colliderJntSph.base.acFlags &= ~AC_HIT; + + for (i = 0; i < ARRAY_COUNT(this->colliderJntSphElements); i++) { + if (this->colliderJntSph.elements[i].info.bumperFlags & BUMP_HIT) { + break; + } + } + + if (i != ARRAY_COUNT(this->colliderJntSphElements)) { + func_800BE5CC(&this->actor, &this->colliderJntSph, i); + if (this->actor.colChkInfo.damageEffect == 0) { + func_808CCBE4(this, globalCtx); + } else if ((i == 0) && (this->actionFunc != func_808CCAA4)) { + temp_v0 = (this->actor.world.rot.y - this->actor.shape.rot.y) - this->unk_218; + if (ABS_ALT(temp_v0) > 0x6000) { + func_808CCA10(this); + } + } + } + } +} + +void EnVm_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnVm* this = THIS; + + func_808CCDE4(this, globalCtx); + + if (this->unk_210 == 2) { + func_800B31BC(globalCtx, &this->unk_234, 20, -1, 155, 10); + if ((globalCtx->gameplayFrames % 2) != 0) { + func_800BBFB0(globalCtx, &this->unk_234, 6.0f, 1, 120, 20, 1); + } + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_BIMOS_LAZER_GND - SFX_FLAG); + } + + if (this->unk_224 > 0.0f) { + func_800B9010(&this->actor, NA_SE_EN_BIMOS_LAZER - SFX_FLAG); + } + + this->actionFunc(this, globalCtx); + + this->unk_212 += 12; + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + if (this->actionFunc != func_808CCCF0) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + } +} + +s32 EnVm_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnVm* this = THIS; + + if (limbIndex == OBJECT_VM_LIMB_02) { + rot->x += this->unk_216; + rot->y += this->unk_218; + } else if ((limbIndex == OBJECT_VM_LIMB_0A) && (this->actionFunc == func_808CCCF0)) { + *dList = NULL; + } + return false; +} + +void EnVm_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + s32 pad; + EnVm* this = THIS; + Vec3f sp5C; + Vec3f sp50; + CollisionPoly* sp4C; + s32 sp48; + + Collider_UpdateSpheres(limbIndex, &this->colliderJntSph); + + if (limbIndex == OBJECT_VM_LIMB_02) { + sp4C = NULL; + + Matrix_MultZero(&this->actor.focus.pos); + Matrix_MultVecZ(1600.0f, &this->unk_228); + Matrix_MultVecZ(this->unk_224 * 71.428566f, &this->unk_234); + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.focus.pos, &this->unk_234, &sp5C, &sp4C, true, + true, false, true, &sp48)) { + this->unk_224 = Math_Vec3f_DistXYZ(&this->actor.focus.pos, &sp5C) - 5.0f; + this->unk_210 = 2; + Math_Vec3f_Copy(&this->unk_234, &sp5C); + } else if (this->unk_210 != 0) { + this->unk_210 = 1; + } + + sp50.x = this->unk_234.x + (Math_CosS(this->actor.shape.rot.y + this->unk_218) * 5.0f); + sp50.y = this->unk_234.y; + sp50.z = this->unk_234.z - (Math_SinS(this->actor.shape.rot.y + this->unk_218) * 5.0f); + + Collider_SetTrisVertices(&this->colliderTris, 0, &this->actor.focus.pos, &this->unk_234, &sp50); + } +} + +void EnVm_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnVm* this = THIS; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + gSPDisplayList(&gfx[0], &sSetupDL[6 * 25]); + + POLY_OPA_DISP = &gfx[1]; + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnVm_OverrideLimbDraw, + EnVm_PostLimbDraw, &this->actor); + + if (this->unk_210 == 2) { + gfx = POLY_XLU_DISP; + + gSPDisplayList(&gfx[0], &sSetupDL[6 * 60]); + gDPSetColorDither(&gfx[1], G_CD_DISABLE); + + Matrix_Translate(this->unk_234.x, this->unk_234.y + 10.0f, this->unk_234.z, MTXMODE_NEW); + Matrix_Scale(0.8f, 0.8f, 0.8f, MTXMODE_APPLY); + + gSPMatrix(&gfx[2], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(&gfx[3], 0, 0, 255, 255, 255, 168); + gDPSetEnvColor(&gfx[4], 0, 0, 255, 0); + gSPSegment(&gfx[5], 0x08, D_808CD58C[globalCtx->gameplayFrames & 7]); + gSPDisplayList(&gfx[6], gameplay_keep_DL_044300); + + POLY_XLU_DISP = &gfx[7]; + } + + if (this->unk_224 > 0.0f) { + gfx = POLY_OPA_DISP; + + gSPSegment(&gfx[0], 0x08, func_8012CB28(globalCtx->state.gfxCtx, 0, this->unk_212)); + + Matrix_Translate(this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z, MTXMODE_NEW); + Matrix_RotateZYX(this->unk_216, this->unk_218 + this->actor.shape.rot.y, 0, MTXMODE_APPLY); + Matrix_Scale(this->unk_220, this->unk_220, this->unk_224 * 0.0015f, MTXMODE_APPLY); + + gSPMatrix(&gfx[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[2], object_vm_DL_002728); + + POLY_OPA_DISP = &gfx[3]; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Vm/z_en_vm.h b/src/overlays/actors/ovl_En_Vm/z_en_vm.h index ad5c43abb..1901ac34a 100644 --- a/src/overlays/actors/ovl_En_Vm/z_en_vm.h +++ b/src/overlays/actors/ovl_En_Vm/z_en_vm.h @@ -7,11 +7,32 @@ struct EnVm; typedef void (*EnVmActionFunc)(struct EnVm*, GlobalContext*); +#define ENVM_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +#define ENVM_FF00_0 0 +#define ENVM_FF00_5 5 +#define ENVM_FF00_FF 0xFF + typedef struct EnVm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC8]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[11]; + /* 0x01CA */ Vec3s morphTable[11]; /* 0x020C */ EnVmActionFunc actionFunc; - /* 0x0210 */ char unk_210[0x14C]; + /* 0x0210 */ u8 unk_210; + /* 0x0212 */ s16 unk_212; + /* 0x0214 */ s16 unk_214; + /* 0x0216 */ s16 unk_216; + /* 0x0218 */ s16 unk_218; + /* 0x021C */ f32 unk_21C; + /* 0x0220 */ f32 unk_220; + /* 0x0224 */ f32 unk_224; + /* 0x0228 */ Vec3f unk_228; + /* 0x0234 */ Vec3f unk_234; + /* 0x0240 */ ColliderJntSph colliderJntSph; + /* 0x0260 */ ColliderJntSphElement colliderJntSphElements[2]; + /* 0x02E0 */ ColliderTris colliderTris; + /* 0x0300 */ ColliderTrisElement colliderTrisElements[1]; } EnVm; // size = 0x35C extern const ActorInit En_Vm_InitVars; diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c index c56a4a166..8ebb04c22 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.c @@ -1,6 +1,14 @@ -#include "z_en_wallmas.h" +/* + * File: z_en_wallmas.c + * Overlay: ovl_En_Wallmas + * Description: Wallmaster + */ -#define FLAGS 0x00000415 +#include "z_en_wallmas.h" +#include "overlays/actors/ovl_En_Encount1/z_en_encount1.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((EnWallmas*)thisx) @@ -9,22 +17,32 @@ void EnWallmas_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWallmas_Update(Actor* thisx, GlobalContext* globalCtx); void EnWallmas_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80874BE4(EnWallmas* this, GlobalContext* globalCtx); -void func_80874DE8(EnWallmas* this, GlobalContext* globalCtx); -void func_80874FD8(EnWallmas* this, GlobalContext* globalCtx); -void func_80875054(EnWallmas* this, GlobalContext* globalCtx); -void func_80875108(EnWallmas* this, GlobalContext* globalCtx); -void func_8087520C(EnWallmas* this, GlobalContext* globalCtx); -void func_808752CC(EnWallmas* this, GlobalContext* globalCtx); -void func_80875484(EnWallmas* this, GlobalContext* globalCtx); -void func_8087556C(EnWallmas* this, GlobalContext* globalCtx); -void func_80875638(EnWallmas* this, GlobalContext* globalCtx); -void func_8087571C(EnWallmas* this, GlobalContext* globalCtx); -void func_80875910(EnWallmas* this, GlobalContext* globalCtx); -void func_8087596C(EnWallmas* this, GlobalContext* globalCtx); -void func_80875A0C(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_TimerInit(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_WaitToDrop(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupDrop(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_Drop(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupLand(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_Land(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupStand(EnWallmas* this); +void EnWallmas_Stand(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupWalk(EnWallmas* this); +void EnWallmas_Walk(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupJumpToCeiling(EnWallmas* this); +void EnWallmas_JumpToCeiling(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupReturnToCeiling(EnWallmas* this); +void EnWallmas_ReturnToCeiling(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_Damage(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupCooldown(EnWallmas* this); +void EnWallmas_Cooldown(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupDie(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_Die(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_SetupTakePlayer(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_TakePlayer(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_ProximityOrSwitchInit(EnWallmas* this); +void EnWallmas_WaitForProximity(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_WaitForSwitchFlag(EnWallmas* this, GlobalContext* globalCtx); +void EnWallmas_Stun(EnWallmas* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Wallmas_InitVars = { ACTOR_EN_WALLMAS, ACTORCAT_ENEMY, @@ -37,147 +55,704 @@ const ActorInit En_Wallmas_InitVars = { (ActorFunc)EnWallmas_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80876360 = { - { COLTYPE_HIT0, 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_HIT0, + 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, + }, { 30, 40, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_8087638C = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(1, 0x0), - /* Explosives */ DMG_ENTRY(1, 0x0), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(1, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0xF), - /* Goron punch */ DMG_ENTRY(1, 0x0), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0x0), - /* Fire arrow */ DMG_ENTRY(2, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x1), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(2, 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, 0x0), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* 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, 0x0), +typedef enum { + /* 0x0 */ WALLMASTER_DMGEFF_NONE, + /* 0x1 */ WALLMASTER_DMGEFF_STUN, + /* 0x2 */ WALLMASTER_DMGEFF_FIRE_ARROW, + /* 0x3 */ WALLMASTER_DMGEFF_ICE_ARROW, + /* 0x4 */ WALLMASTER_DMGEFF_LIGHT_ARROW, + /* 0x5 */ WALLMASTER_DMGEFF_ZORA_MAGIC, + /* 0xF */ WALLMASTER_DMGEFF_HOOKSHOT = 0xF +} EnWallmasDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, WALLMASTER_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, WALLMASTER_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Sword */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Fire arrow */ DMG_ENTRY(2, WALLMASTER_DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(1, WALLMASTER_DMGEFF_ICE_ARROW), + /* Light arrow */ DMG_ENTRY(2, WALLMASTER_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Deku spin */ DMG_ENTRY(0, WALLMASTER_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(2, WALLMASTER_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, WALLMASTER_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, WALLMASTER_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Zora punch */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, WALLMASTER_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, WALLMASTER_DMGEFF_NONE), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808763AC = { 3, 30, 40, 150 }; +static CollisionCheckInfoInit sColChkInfoInit = { 3, 30, 40, 150 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808763B4[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 48, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 5500, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -1500, ICHAIN_STOP), }; -#endif +static f32 sYOffsetPerForm[] = { 50.0f, 55.0f, 50.0f, 20.0f, 30.0f }; -extern ColliderCylinderInit D_80876360; -extern DamageTable D_8087638C; -extern CollisionCheckInfoInit D_808763AC; -extern InitChainEntry D_808763B4[]; +/** + * This maps a given limb based on its limbIndex to its appropriate index + * in the limbPos array. An index of -1 indicates that the limb is not part + * of the limbPos array. + */ +static s8 sLimbIndexToLimbPosIndex[] = { + -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, -1, -1, 3, -1, 4, -1, -1, 5, -1, -1, -1, 6, 7, -1, 8, +}; -extern UNK_TYPE D_06000590; -extern UNK_TYPE D_06000EA4; -extern UNK_TYPE D_060019CC; -extern UNK_TYPE D_0600299C; -extern UNK_TYPE D_060041F4; -extern UNK_TYPE D_06008688; -extern UNK_TYPE D_06009244; -extern UNK_TYPE D_06009520; -extern UNK_TYPE D_06009DB0; -extern UNK_TYPE D_0600A054; +void EnWallmas_Init(Actor* thisx, GlobalContext* globalCtx) { + EnWallmas* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/EnWallmas_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.5f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWallmasterSkel, &gWallmasterIdleAnim, this->jointTable, + this->morphTable, WALLMASTER_LIMB_MAX); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/EnWallmas_Destroy.s") + this->switchFlag = WALLMASTER_GET_SWITCH_FLAG(thisx); + this->actor.params &= 0xFF; + this->detectionRadius = this->actor.shape.rot.x * 40.0f * 0.1f; + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = 0; + if (this->detectionRadius <= 0.0f) { + this->detectionRadius = 200.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874A88.s") + Actor_SetFocus(&this->actor, 25.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874B04.s") + if (WALLMASTER_IS_FROZEN(&this->actor)) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, + this->actor.world.pos.y - 15.0f, this->actor.world.pos.z, this->actor.world.rot.x, + (this->actor.world.rot.y + 0x5900), this->actor.world.rot.z, 0xFF50); + this->actor.params &= ~0x80; + EnWallmas_SetupReturnToCeiling(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874B88.s") + if (WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_FLAG) { + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874BE4.s") + EnWallmas_ProximityOrSwitchInit(this); + } else if (WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_PROXIMITY) { + EnWallmas_ProximityOrSwitchInit(this); + } else { + EnWallmas_TimerInit(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874D1C.s") +void EnWallmas_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWallmas* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874DE8.s") + Collider_DestroyCylinder(globalCtx, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874F14.s") + if (this->actor.parent != NULL) { + EnEncount1* encount1 = (EnEncount1*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80874FD8.s") + if ((encount1->actor.update != NULL) && (encount1->unk_14E > 0)) { + encount1->unk_14E--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875014.s") +void EnWallmas_Freeze(EnWallmas* this) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffFrozenSteamScale = 0.82500005f; + this->drawDmgEffAlpha = 1.0f; + this->collider.base.colType = 3; + this->timer = 80; + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875054.s") +void EnWallmas_ThawIfFrozen(EnWallmas* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider.base.colType = 0; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 11, 2, 0.3f, 0.2f); + this->actor.flags |= ACTOR_FLAG_400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808750B8.s") +void EnWallmas_TimerInit(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875108.s") + this->actor.flags &= ~ACTOR_FLAG_1; + this->actor.flags |= ACTOR_FLAG_20; + this->timer = 130; + this->actor.velocity.y = 0.0f; + this->actor.world.pos.y = player->actor.world.pos.y; + this->actor.floorHeight = player->actor.floorHeight; + this->actor.draw = EnWallmas_Draw; + this->actionFunc = EnWallmas_WaitToDrop; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808751C4.s") +void EnWallmas_WaitToDrop(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f* playerPos = &player->actor.world.pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_8087520C.s") + this->actor.world.pos = *playerPos; + this->actor.floorHeight = player->actor.floorHeight; + this->actor.floorPoly = player->actor.floorPoly; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875248.s") + if (this->timer != 0) { + this->timer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808752CC.s") + if ((player->stateFlags1 & 0x08100000) || (player->stateFlags2 & 0x80) || (player->unk_B5E > 0) || + (player->actor.freezeTimer > 0) || !(player->actor.bgCheckFlags & 1) || + ((WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_PROXIMITY) && + (Math_Vec3f_DistXZ(&this->actor.home.pos, playerPos) > (120.f + this->detectionRadius)))) { + func_801A75E8(NA_SE_EN_FALL_AIM); + this->timer = 130; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808753F0.s") + if (this->timer == 80) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_AIM); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875484.s") + if (this->timer == 0) { + EnWallmas_SetupDrop(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875518.s") +void EnWallmas_SetupDrop(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_8087556C.s") + Animation_Change(&this->skelAnime, &gWallmasterLungeAnim, 0.0f, 20.0f, + Animation_GetLastFrame(&gWallmasterLungeAnim), ANIMMODE_ONCE, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808755A8.s") + this->yTarget = player->actor.world.pos.y; + this->actor.world.pos.y = player->actor.world.pos.y + 300.0f; + this->actor.shape.rot.y = player->actor.shape.rot.y + 0x8000; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.floorHeight = player->actor.floorHeight; + this->actor.flags |= ACTOR_FLAG_1; + this->actor.flags &= ~ACTOR_FLAG_20; + this->actionFunc = EnWallmas_Drop; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875638.s") +void EnWallmas_Drop(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808756AC.s") + if ((player->stateFlags2 & 0x80) || (player->actor.freezeTimer > 0)) { + EnWallmas_SetupReturnToCeiling(this); + } else if (!Play_InCsMode(globalCtx) && !(player->stateFlags2 & 0x10) && (player->invincibilityTimer >= 0) && + (this->actor.xzDistToPlayer < 30.0f) && (this->actor.playerHeightRel < -5.0f) && + (-(f32)(player->cylinder.dim.height + 10) < this->actor.playerHeightRel)) { + EnWallmas_SetupTakePlayer(this, globalCtx); + } else if (this->actor.world.pos.y <= this->yTarget) { + this->actor.world.pos.y = this->yTarget; + this->actor.velocity.y = 0.0f; + EnWallmas_SetupLand(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_8087571C.s") +void EnWallmas_SetupLand(EnWallmas* this, GlobalContext* globalCtx) { + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 1.0f, 41.0f, Animation_GetLastFrame(&gWallmasterJumpAnim), + ANIMMODE_ONCE, -3.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808758C8.s") + Actor_SpawnFloorDustRing(globalCtx, &this->actor, &this->actor.world.pos, 15.0f, 6, 20.0f, 300, 100, true); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_LAND); + this->actionFunc = EnWallmas_Land; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875910.s") +void EnWallmas_Land(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + EnWallmas_SetupStand(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_8087596C.s") +void EnWallmas_SetupStand(EnWallmas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterStandUpAnim); + this->actionFunc = EnWallmas_Stand; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808759B8.s") +void EnWallmas_Stand(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + EnWallmas_SetupWalk(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875A0C.s") + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 0xB6); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875A74.s") +void EnWallmas_SetupWalk(EnWallmas* this) { + Animation_PlayOnceSetSpeed(&this->skelAnime, &gWallmasterWalkAnim, 3.0f); + this->actor.speedXZ = 3.0f; + this->actionFunc = EnWallmas_Walk; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/EnWallmas_Update.s") +void EnWallmas_Walk(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + EnWallmas_SetupJumpToCeiling(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80875F04.s") + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 0xB6); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 12.0f) || + Animation_OnFrame(&this->skelAnime, 24.0f) || Animation_OnFrame(&this->skelAnime, 36.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_WALK); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_808760A4.s") +void EnWallmas_SetupJumpToCeiling(EnWallmas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterStopWalkAnim); + this->actor.speedXZ = 0.0f; + this->actionFunc = EnWallmas_JumpToCeiling; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/func_80876118.s") +void EnWallmas_JumpToCeiling(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + EnWallmas_SetupReturnToCeiling(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wallmas/EnWallmas_Draw.s") +void EnWallmas_SetupReturnToCeiling(EnWallmas* this) { + this->timer = 0; + this->actor.speedXZ = 0.0f; + Animation_Change(&this->skelAnime, &gWallmasterJumpAnim, 3.0f, 0.0f, Animation_GetLastFrame(&gWallmasterJumpAnim), + ANIMMODE_ONCE, -3.0f); + this->actionFunc = EnWallmas_ReturnToCeiling; +} + +void EnWallmas_ReturnToCeiling(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + if (this->skelAnime.curFrame > 20.0f) { + this->actor.world.pos.y += 30.0f; + this->timer += 9; + this->actor.flags &= ~ACTOR_FLAG_2000; + } + + if (Animation_OnFrame(&this->skelAnime, 20.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_UP); + } + + if (this->actor.playerHeightRel < -900.0f) { + if (WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_FLAG) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_TIMER_ONLY) || + (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->detectionRadius)) { + EnWallmas_TimerInit(this, globalCtx); + } else { + EnWallmas_ProximityOrSwitchInit(this); + } + } +} + +void EnWallmas_SetupDamage(EnWallmas* this, s32 arg1) { + Animation_MorphToPlayOnce(&this->skelAnime, &gWallmasterDamageAnim, -3.0f); + + if (arg1) { + func_800BE504(&this->actor, &this->collider); + } + + Actor_SetColorFilter(&this->actor, 0x4000, 255, 0, 20); + this->actor.speedXZ = 5.0f; + this->actor.velocity.y = 10.0f; + this->actionFunc = EnWallmas_Damage; +} + +void EnWallmas_Damage(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->actor.colChkInfo.health == 0) { + EnWallmas_SetupDie(this, globalCtx); + } else { + EnWallmas_SetupCooldown(this); + } + } + + if (Animation_OnFrame(&this->skelAnime, 13.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.2f); +} + +void EnWallmas_SetupCooldown(EnWallmas* this) { + Animation_PlayOnce(&this->skelAnime, &gWallmasterRecoverFromDamageAnim); + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnWallmas_Cooldown; +} + +void EnWallmas_Cooldown(EnWallmas* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + EnWallmas_SetupReturnToCeiling(this); + } +} + +void EnWallmas_SetupDie(EnWallmas* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 250, -10, 2); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + this->actionFunc = EnWallmas_Die; +} + +void EnWallmas_Die(EnWallmas* this, GlobalContext* globalCtx) { + if (Math_StepToF(&this->actor.scale.x, 0.0f, 0.0015f)) { + Actor_SetScale(&this->actor, 0.01f); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + Actor_MarkForDeath(&this->actor); + } + + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = this->actor.scale.x; +} + +void EnWallmas_SetupTakePlayer(EnWallmas* this, GlobalContext* globalCtx) { + Animation_MorphToPlayOnce(&this->skelAnime, &gWallmasterHoverAnim, -5.0f); + this->timer = -30; + this->actionFunc = EnWallmas_TakePlayer; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->yTarget = this->actor.playerHeightRel; + func_800B724C(globalCtx, &this->actor, 18); +} + +void EnWallmas_TakePlayer(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Animation_OnFrame(&this->skelAnime, 1.0f)) { + func_800B8E58(player, player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_CATCH); + } + + if (SkelAnime_Update(&this->skelAnime)) { + player->actor.world.pos.x = this->actor.world.pos.x; + player->actor.world.pos.z = this->actor.world.pos.z; + + if (this->timer < 0) { + this->actor.world.pos.y += 2.0f; + } else { + this->actor.world.pos.y += 10.0f; + } + + player->actor.world.pos.y = this->actor.world.pos.y - sYOffsetPerForm[((void)0, gSaveContext.save.playerForm)]; + if (this->timer == -30) { + func_800B8E58(player, player->ageProperties->unk_92 + NA_SE_VO_LI_TAKEN_AWAY); + } + + if (this->timer == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_UP); + } + + this->timer += 2; + } else { + Math_StepToF(&this->actor.world.pos.y, + sYOffsetPerForm[((void)0, gSaveContext.save.playerForm)] + player->actor.world.pos.y, 5.0f); + } + + Math_StepToF(&this->actor.world.pos.x, player->actor.world.pos.x, 3.0f); + Math_StepToF(&this->actor.world.pos.z, player->actor.world.pos.z, 3.0f); + + if (this->timer == 30) { + play_sound(NA_SE_OC_ABYSS); + func_80169FDC(&globalCtx->state); + } +} + +void EnWallmas_ProximityOrSwitchInit(EnWallmas* this) { + this->timer = 0; + this->actor.draw = NULL; + this->actor.flags &= ~ACTOR_FLAG_1; + if (WALLMASTER_GET_TYPE(&this->actor) == WALLMASTER_TYPE_PROXIMITY) { + this->actionFunc = EnWallmas_WaitForProximity; + } else { + this->actionFunc = EnWallmas_WaitForSwitchFlag; + } +} + +void EnWallmas_WaitForProximity(EnWallmas* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < this->detectionRadius) { + EnWallmas_TimerInit(this, globalCtx); + } +} + +void EnWallmas_WaitForSwitchFlag(EnWallmas* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + EnWallmas_TimerInit(this, globalCtx); + this->timer = 81; + } +} + +void EnWallmas_SetupStun(EnWallmas* 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 = EnWallmas_Stun; +} + +void EnWallmas_Stun(EnWallmas* this, GlobalContext* globalCtx) { + if (this->timer != 0) { + this->timer--; + } + + if (this->timer == 0) { + EnWallmas_ThawIfFrozen(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + EnWallmas_SetupDamage(this, false); + } else { + this->actor.world.rot.y = this->actor.shape.rot.y; + EnWallmas_SetupReturnToCeiling(this); + } + } +} + +void EnWallmas_UpdateDamage(EnWallmas* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_SetDropFlag(&this->actor, &this->collider.info); + + if ((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + (!(this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { + if (Actor_ApplyDamage(&this->actor) == 0) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_DAIOCTA_REVERSE); + this->actor.flags &= ~ACTOR_FLAG_1; + } else if (this->actor.colChkInfo.damage != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_FALL_DAMAGE); + } + + EnWallmas_ThawIfFrozen(this, globalCtx); + + if (this->actor.colChkInfo.damageEffect != WALLMASTER_DMGEFF_HOOKSHOT) { + if (this->actor.colChkInfo.damageEffect == WALLMASTER_DMGEFF_ICE_ARROW) { + EnWallmas_Freeze(this); + if (this->actor.colChkInfo.health == 0) { + this->timer = 3; + this->collider.base.acFlags &= ~AC_ON; + } + + EnWallmas_SetupStun(this); + } else if (this->actor.colChkInfo.damageEffect == WALLMASTER_DMGEFF_STUN) { + this->timer = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + EnWallmas_SetupStun(this); + } else if (this->actor.colChkInfo.damageEffect == WALLMASTER_DMGEFF_ZORA_MAGIC) { + this->timer = 40; + Actor_SetColorFilter(&this->actor, 0, 255, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->drawDmgEffScale = 0.55f; + this->drawDmgEffAlpha = 2.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_MEDIUM; + EnWallmas_SetupStun(this); + } else { + if (this->actor.colChkInfo.damageEffect == WALLMASTER_DMGEFF_FIRE_ARROW) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + } else if (this->actor.colChkInfo.damageEffect == WALLMASTER_DMGEFF_LIGHT_ARROW) { + this->drawDmgEffAlpha = 4.0f; + this->drawDmgEffScale = 0.55f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + 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); + } + + EnWallmas_SetupDamage(this, true); + } + } + } + } +} + +void EnWallmas_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnWallmas* this = THIS; + + EnWallmas_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + + if ((this->actionFunc != EnWallmas_WaitToDrop) && (this->actionFunc != EnWallmas_WaitForProximity) && + (this->actionFunc != EnWallmas_TakePlayer) && (this->actionFunc != EnWallmas_WaitForSwitchFlag)) { + if ((this->actionFunc != EnWallmas_ReturnToCeiling) && (this->actionFunc != EnWallmas_TakePlayer)) { + Actor_MoveWithGravity(&this->actor); + } + + if (this->actionFunc != EnWallmas_Drop) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 25.0f, 0.0f, 0x1DU); + } + + if ((this->actionFunc != EnWallmas_Die) && (this->actionFunc != EnWallmas_Drop)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if ((this->actionFunc != EnWallmas_Damage) && (this->actor.bgCheckFlags & 1) && + (this->actor.freezeTimer == 0)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + + Actor_SetFocus(&this->actor, 25.0f); + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.275f; + this->drawDmgEffScale = CLAMP_MAX(this->drawDmgEffScale, 0.55f); + } else if (Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.55f, 0.01375f) == 0) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } + } +} + +void EnWallmas_DrawShadow(EnWallmas* this, GlobalContext* globalCtx) { + s32 pad; + f32 xzScale; + MtxF mf; + Gfx* gfx; + + if ((this->actor.floorPoly != NULL) && ((this->timer < 81) || (this->actionFunc == EnWallmas_Stun))) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + gSPDisplayList(&gfx[0], &sSetupDL[6 * 44]); + gDPSetPrimColor(&gfx[1], 0, 0, 0, 0, 0, 255); + func_800C0094(this->actor.floorPoly, this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + &mf); + Matrix_Mult(&mf, MTXMODE_NEW); + + if ((this->actionFunc != EnWallmas_WaitToDrop) && (this->actionFunc != EnWallmas_ReturnToCeiling) && + (this->actionFunc != EnWallmas_TakePlayer) && (this->actionFunc != EnWallmas_WaitForSwitchFlag)) { + xzScale = this->actor.scale.x * 50.0f; + } else { + xzScale = CLAMP_MAX(80 - this->timer, 80) * 0.00625f; + } + + Matrix_Scale(xzScale, 1.0f, xzScale, MTXMODE_APPLY); + gSPMatrix(&gfx[2], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[3], gCircleShadowDL); + + POLY_OPA_DISP = &gfx[4]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +s32 EnWallmas_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnWallmas* this = THIS; + + if (limbIndex == WALLMASTER_LIMB_ROOT) { + if (this->actionFunc != EnWallmas_TakePlayer) { + pos->z -= 1600.0f; + } else { + pos->z -= (1600.0f * (this->skelAnime.endFrame - this->skelAnime.curFrame)) / this->skelAnime.endFrame; + } + } + + return false; +} + +void EnWallmas_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnWallmas* this = THIS; + Gfx* gfx; + + if (sLimbIndexToLimbPosIndex[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[sLimbIndexToLimbPosIndex[limbIndex]]); + } + + if (limbIndex == WALLMASTER_LIMB_WRIST) { + Matrix_MultVecX(1000.0f, &this->limbPos[9]); + Matrix_MultVecX(-1000.0f, &this->limbPos[10]); + } else if (limbIndex == WALLMASTER_LIMB_HAND) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gfx = POLY_OPA_DISP; + + Matrix_Push(); + Matrix_Translate(1600.0f, -700.0f, -1700.0f, MTXMODE_APPLY); + Matrix_RotateYS(0x2AAA, MTXMODE_APPLY); + Matrix_RotateZS(0xAAA, MTXMODE_APPLY); + Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY); + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], gWallmasterLittleFingerDL); + + POLY_OPA_DISP = &gfx[2]; + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnWallmas_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnWallmas* this = THIS; + + if (this->actionFunc != EnWallmas_WaitToDrop) { + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnWallmas_OverrideLimbDraw, EnWallmas_PostLimbDraw, + &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } + + if (this->actor.colorFilterTimer != 0) { + func_800AE5A0(globalCtx); + } + + EnWallmas_DrawShadow(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h index 1bd6fbe83..06d4d24d1 100644 --- a/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h +++ b/src/overlays/actors/ovl_En_Wallmas/z_en_wallmas.h @@ -2,16 +2,54 @@ #define Z_EN_WALLMAS_H #include "global.h" +#include "objects/object_wallmaster/object_wallmaster.h" + +#define WALLMASTER_GET_TYPE(thisx) ((thisx)->params) +#define WALLMASTER_GET_SWITCH_FLAG(thisx) (((thisx)->params >> 8) & 0xFF) +#define WALLMASTER_IS_FROZEN(thisx) ((thisx)->params & 0x80) + +/** + * This type determines under what conditions the Wallmaster will drop from the ceiling. + * - WALLMASTER_TYPE_TIMER_ONLY: These Wallmasters don't check for anything to determine + * whether or not to drop; they just set a 130-frame timer and drop once it reaches 0. + * - WALLMASTER_TYPE_PROXIMITY: These Wallmasters ensure that the player in within a certain + * distance of their current position (as dictated by detectionRadius); once the player + * enters that range, they set a 130-frame timer and drop once it reaches 0. + * - WALLMASTER_TYPE_FLAG: These Wallmasters wait for a certain switch flag to be activated, + * as specified in their params. Once this switch is activated, they set an 81-frame timer + * and drop once it reaches 0. + * + * While in the "waiting to drop" state, all Wallmaster variations can be forced to reset the + * timer to 130 frames if the player enters certain states (e.g., if the player is no longer + * touching the ground). Additionally, WALLMASTER_TYPE_PROXIMITY-type Wallmasters will reset + * the timer to 130 frames if the player strays too far from the Wallmaster's current position. + */ +typedef enum { + /* 0x00 */ WALLMASTER_TYPE_TIMER_ONLY, + /* 0x01 */ WALLMASTER_TYPE_PROXIMITY, + /* 0x02 */ WALLMASTER_TYPE_FLAG +} WallmasterType; struct EnWallmas; typedef void (*EnWallmasActionFunc)(struct EnWallmas*, GlobalContext*); typedef struct EnWallmas { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnWallmasActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x218]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnWallmasActionFunc actionFunc; + /* 0x18C */ u8 drawDmgEffType; + /* 0x18E */ s16 timer; + /* 0x190 */ s16 switchFlag; + /* 0x192 */ Vec3s jointTable[WALLMASTER_LIMB_MAX]; + /* 0x228 */ Vec3s morphTable[WALLMASTER_LIMB_MAX]; + /* 0x2C0 */ f32 yTarget; + /* 0x2C4 */ f32 detectionRadius; + /* 0x2C8 */ f32 drawDmgEffAlpha; + /* 0x2CC */ f32 drawDmgEffScale; + /* 0x2D0 */ f32 drawDmgEffFrozenSteamScale; + /* 0x2D4 */ Vec3f limbPos[11]; + /* 0x358 */ ColliderCylinder collider; } EnWallmas; // size = 0x3A4 extern const ActorInit En_Wallmas_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..4065bdf39 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 @@ -5,8 +5,9 @@ */ #include "z_en_warp_uzu.h" +#include "objects/object_warp_uzu/object_warp_uzu.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnWarpUzu*)thisx) @@ -59,8 +60,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_06000EC0[]; - void EnWarpUzu_Init(Actor* thisx, GlobalContext* globalCtx) { EnWarpUzu* this = THIS; @@ -81,8 +80,8 @@ void func_80A66208(EnWarpUzu* this, GlobalContext* globalCtx) { Vec3f sp24; this->actor.textId = 0; - Matrix_RotateY(this->actor.shape.rot.y, 0); - Matrix_MultiplyVector3fByState(&D_80A664FC, &sp24); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3f(&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); this->actionFunc = func_80A66278; @@ -96,7 +95,7 @@ void func_80A66278(EnWarpUzu* this, GlobalContext* globalCtx) { do { player = GET_PLAYER(globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { func_80A66384(this, globalCtx); } else { phi_a0 = ABS((s16)(Actor_YawBetweenActors(&this->actor, &player->actor) - this->actor.shape.rot.y)); @@ -113,8 +112,8 @@ void func_80A66278(EnWarpUzu* this, GlobalContext* globalCtx) { void func_80A66384(EnWarpUzu* this, GlobalContext* globalCtx) { globalCtx->nextEntranceIndex = 0x22A0; - gSaveContext.respawn[0].entranceIndex = globalCtx->nextEntranceIndex; - func_80169EFC(globalCtx); + gSaveContext.respawn[RESTART_MODE_DOWN].entranceIndex = globalCtx->nextEntranceIndex; + func_80169EFC(&globalCtx->state); gSaveContext.respawnFlag = -2; this->actionFunc = EnWarpUzu_DoNothing; } @@ -133,5 +132,5 @@ void EnWarpUzu_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnWarpUzu_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000EC0); + Gfx_DrawDListOpa(globalCtx, object_warp_uzu_DL_000EC0); } diff --git a/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.c b/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.c index 7ee643f03..5759b0a9b 100644 --- a/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.c +++ b/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.c @@ -1,21 +1,29 @@ -#include "z_en_warp_tag.h" +/* + * File: z_en_warp_tag.c + * Overlay: ovl_En_Warp_tag + * Description: Warp to Trial Entrance + * if GoronTrial, has model: Uses GAMEPLAY_DANGEON_KEEP object assigned in EnWarptag_Init + */ -#define FLAGS 0x0A000011 +#include "z_en_warp_tag.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000 | ACTOR_FLAG_8000000) #define THIS ((EnWarptag*)thisx) void EnWarptag_Init(Actor* thisx, GlobalContext* globalCtx); void EnWarptag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWarptag_Update(Actor* thisx, GlobalContext* globalCtx); +void EnWarpTag_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809C085C(EnWarptag* this, GlobalContext* globalCtx); -void func_809C08E0(EnWarptag* this, GlobalContext* globalCtx); -void func_809C09A0(EnWarptag* this, GlobalContext* globalCtx); -void func_809C0A20(EnWarptag* this, GlobalContext* globalCtx); -void func_809C0AB4(EnWarptag* this, GlobalContext* globalCtx); -void func_809C0E30(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_CheckDungeonKeepObject(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_WaitForPlayer(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_Unused809C09A0(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_Unused809C0A20(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_RespawnPlayer(EnWarptag* this, GlobalContext* globalCtx); +void EnWarpTag_GrottoReturn(EnWarptag* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Warp_tag_InitVars = { ACTOR_EN_WARP_TAG, ACTORCAT_ITEMACTION, @@ -28,32 +36,238 @@ const ActorInit En_Warp_tag_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809C1008[] = { +// this appears to be unused, as the code never accesses it in known vanilla cases +// these unknown values get passed to a unknown z_message function +u8 D_809C1000[] = { 0x28, 0x29, 0x2A, 0x2B, 0x2D, 0x2C, 0, 0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), ICHAIN_VEC3S(shape.rot, 0, ICHAIN_STOP), }; -#endif +void EnWarptag_Init(Actor* thisx, GlobalContext* globalCtx) { + EnWarptag* this = THIS; -extern InitChainEntry D_809C1008[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetFocus(&this->dyna.actor, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/EnWarptag_Init.s") + if (GET_WARPTAG_3C0_MAX(thisx) == WARPTAG_3C0_MAX) { + this->dyna.actor.flags &= ~ACTOR_FLAG_1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/EnWarptag_Destroy.s") + if (GET_WARPTAG_INVISIBLE(&this->dyna.actor)) { + this->actionFunc = EnWarpTag_WaitForPlayer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C085C.s") + } else { + if ((this->dangeonKeepObject = Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_DANGEON_KEEP)) < 0) { + Actor_MarkForDeath(&this->dyna.actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C08E0.s") + this->actionFunc = EnWarpTag_CheckDungeonKeepObject; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C09A0.s") + } else { // not used by known variants + this->actionFunc = EnWarpTag_Unused809C09A0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C0A20.s") +void EnWarptag_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWarptag* this = THIS; + if (this->dyna.actor.draw != NULL) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C0AB4.s") +/** + * Loads DynaPoly from GAMEPLAY_DANGEON_KEEP. + */ +void EnWarpTag_CheckDungeonKeepObject(EnWarptag* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->dangeonKeepObject)) { + this->actionFunc = EnWarpTag_WaitForPlayer; + DynaPolyActor_Init(&this->dyna, 0x1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gWarpTagGoronTrialBaseCollider); + this->dyna.actor.objBankIndex = this->dangeonKeepObject; + this->dyna.actor.draw = EnWarpTag_Draw; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C0E30.s") +void EnWarpTag_WaitForPlayer(EnWarptag* this, GlobalContext* globalCtx) { + if (!Player_InCsMode(&globalCtx->state) && (this->dyna.actor.xzDistToPlayer <= 30.0f) && + (this->dyna.actor.playerHeightRel <= 10.0f)) { + if (GET_WARPTAG_INVISIBLE(&this->dyna.actor)) { + func_800B7298(globalCtx, NULL, 0x51); + this->actionFunc = EnWarpTag_GrottoReturn; + } else { + func_800B7298(globalCtx, NULL, 0xF); + this->actionFunc = EnWarpTag_RespawnPlayer; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/EnWarptag_Update.s") +/** + * Unused ActionFunc: assigned in EnWarpTag_Init, no known variants use. + */ +void EnWarpTag_Unused809C09A0(EnWarptag* this, GlobalContext* globalCtx) { + if (func_800B8718(&this->dyna.actor, &globalCtx->state)) { + // func above: checks for ACTOR_FLAG_20000000, returns true and resets if set, else return false + // this actor doesnt have that flag set default, or in init, and this is called shortly after init + // and I doubt its set externally by another actor, so I believe this is unused + // might be a bug, they might have meant to set actor flag (0x2000 0000) up above but mistyped (0x200 0000) + // also GET_WARPTAG_3C0 should always return 2C0 -> 0xF for all known in-game uses, which is OOB + func_80152434(globalCtx, D_809C1000[GET_WARPTAG_3C0(&this->dyna.actor)]); // unk message function + this->actionFunc = EnWarpTag_Unused809C0A20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Warp_tag/func_809C0F3C.s") + } else { + func_800B8804(&this->dyna.actor, globalCtx, 50.0f); // updates player->unk_A90 + } +} + +/** + * Unused ActionFunc: assigned by EnWarpTag_Unused809C09A0, no known variants use. + */ +void EnWarpTag_Unused809C0A20(EnWarptag* this, GlobalContext* globalCtx) { + if (globalCtx->msgCtx.ocarinaMode == 9) { + func_800B7298(globalCtx, NULL, 7); + this->actionFunc = EnWarpTag_RespawnPlayer; + ActorCutscene_Stop(ActorCutscene_GetCurrentIndex()); + + } else if (globalCtx->msgCtx.ocarinaMode >= 2) { + globalCtx->msgCtx.ocarinaMode = 4; + this->actionFunc = EnWarpTag_Unused809C09A0; + } +} + +/** + * ActionFunc: Goron Trial (Moon), respawn at the beginning of goron rolling track, try again. + */ +void EnWarpTag_RespawnPlayer(EnWarptag* this, GlobalContext* globalCtx) { + ActorEntry* playerActorEntry; + Player* player; + s32 playerSpawnIndex; + s32 new15E; + s32 entranceIndex; + u32 playerSpawnIndexPerForm[PLAYER_FORM_MAX]; + u8 playerForm; + s16 playerParams; + + player = GET_PLAYER(globalCtx); + if (globalCtx->playerActorCsIds[4] >= 0 && ActorCutscene_GetCurrentIndex() != globalCtx->playerActorCsIds[4]) { + if (ActorCutscene_GetCanPlayNext(globalCtx->playerActorCsIds[4]) == 0) { + ActorCutscene_SetIntentToPlay(globalCtx->playerActorCsIds[4]); + + } else { + ActorCutscene_StartAndSetUnkLinkFields(globalCtx->playerActorCsIds[4], &this->dyna.actor); + func_800B8E58(player, NA_SE_PL_WARP_PLATE); + func_8016566C(0); + } + + } else { + f32 diffX = player->actor.world.pos.x - this->dyna.actor.world.pos.x; + Vec3f newRespawnPos; + f32 diffZ = player->actor.world.pos.z - this->dyna.actor.world.pos.z; + f32 distance = sqrtf(SQ(diffX) + SQ(diffZ)); + + // some weird float behavior prevention? + if (distance != 0.0f) { + distance = (distance - 1.0f) / distance; + distance = CLAMP_MIN(distance, 0.0f); + } + + player->actor.world.pos.x = this->dyna.actor.world.pos.x + (diffX * distance); + player->actor.world.pos.z = this->dyna.actor.world.pos.z + (diffZ * distance); + + if (Math_StepToS(&this->unkValue15E, 0x2710, 0xC8)) { + player->stateFlags3 |= 0x1; + player->actor.gravity = -0.5f; + + if (this->dyna.actor.playerHeightRel < -80.0f) { + playerSpawnIndexPerForm[PLAYER_FORM_FIERCE_DEITY] = GET_WARPTAG_EXIT_INDEX(&this->dyna.actor); + playerSpawnIndexPerForm[PLAYER_FORM_HUMAN] = playerSpawnIndexPerForm[PLAYER_FORM_FIERCE_DEITY]; + playerSpawnIndexPerForm[PLAYER_FORM_GORON] = this->dyna.actor.world.rot.x; + playerSpawnIndexPerForm[PLAYER_FORM_ZORA] = this->dyna.actor.world.rot.y; + playerSpawnIndexPerForm[PLAYER_FORM_DEKU] = this->dyna.actor.world.rot.z; + + if (this->dyna.actor.draw != NULL) { + playerForm = PLAYER_BOOTS_FIERCE_DEITY; + } else { + playerForm = player->transformation; + } + + entranceIndex = gSaveContext.save.entranceIndex; + + playerSpawnIndex = playerSpawnIndexPerForm[playerForm]; + playerActorEntry = &globalCtx->linkActorEntry[playerSpawnIndex]; + newRespawnPos.x = playerActorEntry->pos.x; + newRespawnPos.y = playerActorEntry->pos.y; + newRespawnPos.z = playerActorEntry->pos.z; + + if (GET_WARPTAG_3C0_MAX(&this->dyna.actor) == WARPTAG_3C0_MAX) { + playerParams = 0x9FF; + } else { // not used by any known variant + playerParams = 0x8FF; + } + + // why are we getting player home rotation from the room data? doesnt player have home.rot.y? + // especially because we are converting from deg to binang, but isnt home.rot.y already in binang?? + Play_SetRespawnData( + &globalCtx->state, 0, entranceIndex, // parameter 3 is called "sceneSetup" + globalCtx->setupEntranceList[playerSpawnIndex].room, playerParams, &newRespawnPos, + ((((playerActorEntry->rot.y >> 7) & 0x1FF) / 180.0f) * 32768.0f)); // DEG_TO_BINANG ? + + func_80169EFC(&globalCtx->state); + gSaveContext.respawnFlag = ~0x4; + func_80165690(); + } + } + + player->actor.shape.rot.y += this->unkValue15E; + new15E = this->unkValue15E - 0xFA0; + if (new15E < 0) { + new15E = 0; + } + func_80165658(new15E * 0.04f); // unknown Play_ function + } +} + +/** + * ActionFunc: Deku Playground, return to North Clock Town. + */ +void EnWarpTag_GrottoReturn(EnWarptag* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() != this->dyna.actor.cutscene) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } + + if (this->grottoExitDelay++ == 10) { + globalCtx->nextEntranceIndex = globalCtx->setupExitList[GET_WARPTAG_EXIT_INDEX(&this->dyna.actor)]; + Scene_SetExitFade(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + func_8019F128(NA_SE_OC_SECRET_HOLE_OUT); + func_801A4058(5); + if (1) {} + gSaveContext.seqIndex = 0xFF; + gSaveContext.nightSeqIndex = 0xFF; + } +} + +void EnWarptag_Update(Actor* thisx, GlobalContext* globalCtx) { + EnWarptag* this = THIS; + this->actionFunc(this, globalCtx); +} + +/** + * Only draws for Goron Trial (a rainblow animated target). + */ +void EnWarpTag_Draw(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&gWarpTagRainbowAnimMat)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, gWarpTagGoronTrialBaseDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.h b/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.h index 1be6eb5ec..925fda930 100644 --- a/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.h +++ b/src/overlays/actors/ovl_En_Warp_tag/z_en_warp_tag.h @@ -8,11 +8,27 @@ struct EnWarptag; typedef void (*EnWarptagActionFunc)(struct EnWarptag*, GlobalContext*); typedef struct EnWarptag { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; - /* 0x0160 */ EnWarptagActionFunc actionFunc; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ s8 dangeonKeepObject; + /* 0x15E */ union { + s16 reusedValue; // default name + s16 unkValue15E; // passed to unk play func, mods player rotation, stepped to 0x2710 + s16 grottoExitDelay; // 10 frame delay before player can leave the grotto + }; + /* 0x160 */ EnWarptagActionFunc actionFunc; } EnWarptag; // size = 0x164 extern const ActorInit En_Warp_tag_InitVars; +// Only two known Variants: +// Goron Trial (MOON): 0x03C1 +// Deku Playground: 0x83C0 + +#define GET_WARPTAG_3C0_MAX(thisx) ((thisx)->params & 0x3C0) +#define GET_WARPTAG_3C0(thisx) (((thisx)->params >> 6) & 0xF) +#define GET_WARPTAG_EXIT_INDEX(thisx) ((thisx)->params & 0x3F) +#define GET_WARPTAG_INVISIBLE(thisx) ((thisx)->params < 0) // 0x8000 flag + +#define WARPTAG_3C0_MAX 0x3C0 + #endif // Z_EN_WARP_TAG_H 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 4bcf2b765..df347dc36 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 @@ -1,6 +1,14 @@ -#include "z_en_water_effect.h" +/* + * File: z_en_water_effect.c + * Overlay: ovl_En_Water_Effect + * Description: Water splashing effect (used for Gyorg) + */ -#define FLAGS 0x00000035 +#include "z_en_water_effect.h" +#include "objects/object_water_effect/object_water_effect.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnWaterEffect*)thisx) @@ -9,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, @@ -22,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 &= ~ACTOR_FLAG_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; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &ptr->unk_04, 30, NA_SE_EV_BOMB_DROP_WATER); + } else { + ptr->unk_04.y = this->actor.floorHeight; + if (ptr->unk_2A == 0) { + SoundSource_PlaySfxAtFixedWorldPos(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; + SoundSource_PlaySfxAtFixedWorldPos(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_RotateYF((2.0f * (j * M_PI)) / 5.5f, MTXMODE_NEW); + Matrix_MultVecZ(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(gDust1Tex)); + 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_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + + if (ptr->unk_00 == 1) { + Matrix_RotateYS(Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx)), MTXMODE_APPLY); + } else { + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + } + + Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY); + Matrix_RotateZF(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(gDust1Tex)); + 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_Translate(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_RotateYF(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.actorLists[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 (!Play_InCsMode(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, 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); + } + SoundSource_PlaySfxAtFixedWorldPos(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_Translate(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + + if (ptr->unk_2A >= 2) { + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + } else { + Matrix_RotateYS(Camera_GetInputDirYaw(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_RotateYF(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_Translate(ptr->unk_04.x, ptr->unk_04.y + 5.0f, ptr->unk_04.z, MTXMODE_NEW); + Matrix_RotateXS(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_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(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_Push(); + Matrix_Push(); + Matrix_Push(); + + 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_Pop(); + + 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_Pop(); + } else { + Matrix_Pop(); + Matrix_Pop(); + } + + 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_Pop(); + + 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(gDust1Tex)); + 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_Translate(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_RotateYF(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_Wdhand/z_en_wdhand.c b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c index 385950209..b21e2f0b8 100644 --- a/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c +++ b/src/overlays/actors/ovl_En_Wdhand/z_en_wdhand.c @@ -1,6 +1,12 @@ +/* + * File: z_en_wdhand.c + * Overlay: ovl_En_Wdhand + * Description: Dexihand + */ + #include "z_en_wdhand.h" -#define FLAGS 0x00000005 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4) #define THIS ((EnWdhand*)thisx) diff --git a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c index 401bf50b2..0f81d088d 100644 --- a/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c +++ b/src/overlays/actors/ovl_En_Weather_Tag/z_en_weather_tag.c @@ -1,6 +1,12 @@ +/* + * File: z_en_weather_tag.c + * Overlay: ovl_En_Weather_Tag + * Description: Local weather changes + */ + #include "z_en_weather_tag.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnWeatherTag*)thisx) @@ -55,13 +61,13 @@ void EnWeatherTag_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void EnWeatherTag_Init(Actor* thisx, GlobalContext* globalCtx) { - EnWeatherTag* this = (EnWeatherTag*)thisx; + EnWeatherTag* this = THIS; s32 pad; Path* path; s32 pathID; // flag: is targetable. Should do nothing as not set by default above - this->actor.flags &= ~1; + this->actor.flags &= ~ACTOR_FLAG_1; switch (WEATHER_TAG_TYPE(this)) { case WEATHERTAG_TYPE_UNK0: @@ -71,7 +77,7 @@ void EnWeatherTag_Init(Actor* thisx, GlobalContext* globalCtx) { EnWeatherTag_SetupAction(this, func_80966A08); break; case WEATHERTAG_TYPE_UNK1: - if (gSaveContext.weekEventReg[0x34] & 0x20) { // if cleared STT + if (gSaveContext.save.weekEventReg[52] & 0x20) { // if cleared STT Actor_MarkForDeath(&this->actor); } EnWeatherTag_SetupAction(this, func_80966B08); @@ -185,11 +191,11 @@ void func_8096689C(EnWeatherTag* this, GlobalContext* globalCtx) { globalCtx->envCtx.windSpeed = (this->actor.world.rot.z * partialResult) + 30.0f; if (partialResult > 0.01f) { - globalCtx->envCtx.unk_EA = 8; + globalCtx->envCtx.sandstormState = 8; D_801F4E30 = 0x9B; - } else if (globalCtx->envCtx.unk_EA == 8) { + } else if (globalCtx->envCtx.sandstormState == 8) { D_801F4E30 = 0; - globalCtx->envCtx.unk_EA = 9; + globalCtx->envCtx.sandstormState = 9; } } @@ -243,10 +249,10 @@ void func_80966BF4(EnWeatherTag* this, GlobalContext* globalCtx) { u8 newUnk20; CsCmdActorAction* tmpAction; - if (func_800EE29C(globalCtx, 0x237) != 0) { - tmpAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x237)]; - if ((globalCtx->csCtx.frames >= tmpAction->startFrame) && (tmpAction->unk0 >= 2)) { - switch (gSaveContext.day) { + if (Cutscene_CheckActorAction(globalCtx, 567)) { + tmpAction = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 567)]; + if ((globalCtx->csCtx.frames >= tmpAction->startFrame) && (tmpAction->action >= 2)) { + switch (gSaveContext.save.day) { case 0: case 1: default: @@ -276,7 +282,7 @@ void func_80966BF4(EnWeatherTag* this, GlobalContext* globalCtx) { void func_80966D20(EnWeatherTag* this, GlobalContext* globalCtx) { u8 newUnk20; - switch (gSaveContext.day) { + switch (gSaveContext.save.day) { case 0: case 1: default: @@ -416,27 +422,27 @@ void func_809672DC(EnWeatherTag* this, GlobalContext* globalCtx) { f32 range; f32 strength = 0.0f; - func_800BCCDC(this->pathPoints, this->pathCount, &GET_PLAYER(globalCtx)->actor.world.pos, &this->actor.world.pos, - 0); + Actor_GetClosestPosOnPath(this->pathPoints, this->pathCount, &GET_PLAYER(globalCtx)->actor.world.pos, + &this->actor.world.pos, false); distance = Actor_XZDistanceBetweenActors(&player->actor, &this->actor); range = WEATHER_TAG_RANGE100(this); if (distance < range) { - globalCtx->envCtx.unk_EA = 6; + globalCtx->envCtx.sandstormState = 6; strength = 1.0f - (distance / range); if (0.8f < strength) { strength = 1.0f; } D_801F4E30 = (200.0f * strength); } else { - if (globalCtx->envCtx.unk_EA == 6) { + if (globalCtx->envCtx.sandstormState == 6) { D_801F4E30 = 0; - globalCtx->envCtx.unk_EA = 7; + globalCtx->envCtx.sandstormState = 7; } } - Math_SmoothStepToS(&globalCtx->envCtx.unk_8C.fogNear, (s16)(-40.0f * strength), 1, 1, 1); + Math_SmoothStepToS(&globalCtx->envCtx.lightSettings.fogNear, (s16)(-40.0f * strength), 1, 1, 1); } // WEATHERTAG_TYPE_LOCALDAY2RAIN: rain proximity as approaching rainy scene @@ -446,7 +452,8 @@ void func_809674C8(EnWeatherTag* this, GlobalContext* globalCtx) { if (Actor_XZDistanceBetweenActors(&player->actor, &this->actor) < WEATHER_TAG_RANGE100(this)) { if (CURRENT_DAY == 2) { - if ((gSaveContext.time >= 0x4AAA) && (gSaveContext.time < 0xBAAA) && (globalCtx->envCtx.unk_F2[2] == 0)) { + if ((gSaveContext.save.time >= CLOCK_TIME(7, 0)) && (gSaveContext.save.time < CLOCK_TIME(17, 30)) && + (globalCtx->envCtx.unk_F2[2] == 0)) { D_801BDBB0 = 1; func_800FD78C(globalCtx); @@ -474,19 +481,16 @@ void func_80967608(EnWeatherTag* this, GlobalContext* globalCtx) { } void EnWeatherTag_Update(Actor* thisx, GlobalContext* globalCtx) { - EnWeatherTag* this = (EnWeatherTag*)thisx; - u16 oldTime; + EnWeatherTag* this = THIS; this->actionFunc(this, globalCtx); - 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)) { + if ((globalCtx->actorCtx.unk5 & 2) && (globalCtx->msgCtx.msgMode != 0) && + (globalCtx->msgCtx.currentTextId == 0x5E6) && (!FrameAdvance_IsEnabled(&globalCtx->state)) && + (globalCtx->sceneLoadFlag == 0) && (ActorCutscene_GetCurrentIndex() == -1) && (globalCtx->csCtx.state == 0)) { - oldTime = gSaveContext.time; - gSaveContext.time = (u16)REG(0xF) + oldTime; // cast req - if (REG(0xF) != 0) { - oldTime = gSaveContext.time; - gSaveContext.time = (u16)gSaveContext.unk_14 + oldTime; + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)REG(15); + if (REG(15) != 0) { + gSaveContext.save.time = ((void)0, gSaveContext.save.time) + (u16)((void)0, gSaveContext.save.daySpeed); } } } 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 cf8edba5a..89e765b98 100644 --- a/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -1,6 +1,14 @@ -#include "z_en_wf.h" +/* + * File: z_en_wf.c + * Overlay: ovl_En_Wf + * Description: Wolfos and White Wolfos + */ -#define FLAGS 0x00000415 +#include "z_en_wf.h" +#include "overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h" +#include "overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((EnWf*)thisx) @@ -9,28 +17,44 @@ void EnWf_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWf_Update(Actor* thisx, GlobalContext* globalCtx); void EnWf_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80990F0C(EnWf* this); void func_80990F50(EnWf* this, GlobalContext* globalCtx); +void func_80990FC8(EnWf* this); void func_80991040(EnWf* this, GlobalContext* globalCtx); void func_80991174(EnWf* this, GlobalContext* globalCtx); +void func_80991200(EnWf* this); void func_80991280(EnWf* this, GlobalContext* globalCtx); +void func_80991438(EnWf* this); void func_8099149C(EnWf* this, GlobalContext* globalCtx); +void func_80991738(EnWf* this); void func_8099177C(EnWf* this, GlobalContext* globalCtx); +void func_80991948(EnWf* this); void func_809919F4(EnWf* this, GlobalContext* globalCtx); +void func_80991C04(EnWf* this); void func_80991C80(EnWf* this, GlobalContext* globalCtx); void func_80992068(EnWf* this, GlobalContext* globalCtx); +void func_8099223C(EnWf* this); void func_809922B4(EnWf* this, GlobalContext* globalCtx); void func_809923E4(EnWf* this, GlobalContext* globalCtx); void func_809924EC(EnWf* this, GlobalContext* globalCtx); +void func_809926D0(EnWf* this); void func_80992784(EnWf* this, GlobalContext* globalCtx); +void func_8099282C(EnWf* this); void func_809928CC(EnWf* this, GlobalContext* globalCtx); +void func_80992A74(EnWf* this, GlobalContext* globalCtx); void func_80992B8C(EnWf* this, GlobalContext* globalCtx); +void func_80992D6C(EnWf* this); void func_80992E0C(EnWf* this, GlobalContext* globalCtx); +void func_80992FD4(EnWf* this); void func_80993018(EnWf* this, GlobalContext* globalCtx); +void func_80993148(EnWf* this); void func_80993194(EnWf* this, GlobalContext* globalCtx); +void func_80993350(EnWf* this); void func_809933A0(EnWf* this, GlobalContext* globalCtx); +void func_80993524(EnWf* this); void func_8099357C(EnWf* this, GlobalContext* globalCtx); +s32 func_8099408C(GlobalContext* globalCtx, EnWf* this); -#if 0 const ActorInit En_Wf_InitVars = { ACTOR_EN_WF, ACTORCAT_PROP, @@ -43,48 +67,107 @@ const ActorInit En_Wf_InitVars = { (ActorFunc)EnWf_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[4] = { -static ColliderJntSphElementInit D_80994170[4] = { +static ColliderJntSphElementInit sJntSphElementsInit[4] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 15, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 21, { { 0, 0, 0 }, 15 }, 100 }, }, { - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 17, { { 800, 0, 0 }, 25 }, 100 }, }, { - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 12, { { 0, 0, 0 }, 30 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80994200 = { - { COLTYPE_METAL, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 4, D_80994170, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_METAL, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 4, + sJntSphElementsInit, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80994210 = { - { COLTYPE_HIT5, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HIT5, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 20, 50, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8099423C = { - { COLTYPE_HIT5, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT5, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 15, 20, -15, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80994268 = { +static DamageTable sDamageTable1 = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -119,8 +202,7 @@ static DamageTable D_80994268 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static DamageTable sDamageTable = { -static DamageTable D_80994288 = { +static DamageTable sDamageTable2 = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -155,145 +237,1368 @@ static DamageTable D_80994288 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_809942A8 = { 8, 50, 100, MASS_HEAVY }; +static CollisionCheckInfoInit sColChkInfoInit = { 8, 50, 100, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809942D0[] = { +static TexturePtr sNormalEyeTextures[] = { + gWolfosNormalEyeOpenTex, + gWolfosNormalEyeHalfTex, + gWolfosNormalEyeNarrowTex, + gWolfosNormalEyeHalfTex, +}; + +static TexturePtr sWhiteEyeTextures[] = { + gWolfosWhiteEyeOpenTex, + gWolfosWhiteEyeHalfTex, + gWolfosWhiteEyeNarrowTex, + gWolfosWhiteEyeHalfTex, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), }; -#endif +static s32 D_809942D8 = 0; -extern ColliderJntSphElementInit D_80994170[4]; -extern ColliderJntSphInit D_80994200; -extern ColliderCylinderInit D_80994210; -extern ColliderCylinderInit D_8099423C; -extern DamageTable D_80994268; -extern DamageTable D_80994288; -extern CollisionCheckInfoInit D_809942A8; -extern InitChainEntry D_809942D0[]; +void EnWf_Init(Actor* thisx, GlobalContext* globalCtx) { + EnWf* this = THIS; + s32 i; + s32 temp_s0; -extern UNK_TYPE D_06004638; -extern UNK_TYPE D_06004A90; -extern UNK_TYPE D_06004C44; -extern UNK_TYPE D_060053D0; -extern UNK_TYPE D_06005700; -extern UNK_TYPE D_06009808; -extern UNK_TYPE D_06009A50; -extern UNK_TYPE D_0600A3CC; + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 70.0f); + this->actor.shape.shadowAlpha = 150; + Collider_InitAndSetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit, this->collider1Elements); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->collider3, &this->actor, &sCylinderInit2); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/EnWf_Init.s") + if (this->actor.shape.rot.x <= 0) { + this->unk_2A8 = 10000.0f; + } else { + this->unk_2A8 = this->actor.shape.rot.x * 40.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/EnWf_Destroy.s") + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809907D4.s") + if (ENWF_GET_80(&this->actor)) { + this->unk_295 = true; + } else { + this->unk_295 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990854.s") + if (this->unk_295) { + temp_s0 = this->actor.shape.rot.z + 100; + temp_s0 = CLAMP(temp_s0, 1, 255); + this->actor.shape.rot.z = 0; + this->actor.world.rot.z = 0; + this->actor.child = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_ICE_POLY, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, + temp_s0 | 0xFF00); + if (this->actor.child != NULL) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809908E0.s") + this->actor.child->xzDistToPlayer = Actor_XZDistanceBetweenActors(&this->actor, &player->actor); + this->unk_2A4 = (temp_s0 * 0.5f) + 45.0f; + this->unk_29C = 0x32000 / this->unk_2A4; + this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, &player->actor); + this->actor.world.pos.x -= this->unk_2A4 * Math_SinS(this->actor.shape.rot.y); + this->actor.world.pos.z -= this->unk_2A4 * Math_CosS(this->actor.shape.rot.y); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990948.s") + if (Flags_GetClear(globalCtx, this->actor.room)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990C6C.s") + this->actor.params &= 0x3F; + Actor_SetScale(&this->actor, 0.0075f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990E4C.s") + if (this->actor.params == 0) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWolfosNormalSkel, &gWolfosWaitingAnim, this->jointTable, + this->morphTable, WOLFOS_NORMAL_LIMB_MAX); + this->actor.hintId = 0x4C; + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable2, &sColChkInfoInit); + this->collider1.elements[0].info.toucher.damage = 8; + this->collider1.elements[1].info.toucher.damage = 8; + this->actor.colChkInfo.health = 6; + } else { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gWolfosWhiteSkel, &gWolfosWaitingAnim, this->jointTable, + this->morphTable, WOLFOS_WHITE_LIMB_MAX); + this->actor.hintId = 0x57; + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable1, &sColChkInfoInit); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990EAC.s") + if (this->actor.child == NULL) { + func_80990F0C(this); + this->unk_2A0 = 0; + } else { + func_80992FD4(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990ED4.s") + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 5); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990F0C.s") + if (D_809942D8 == 0) { + for (i = 0; i < ARRAY_COUNT(sNormalEyeTextures); i++) { + sNormalEyeTextures[i] = Lib_SegmentedToVirtual(sNormalEyeTextures[i]); + sWhiteEyeTextures[i] = Lib_SegmentedToVirtual(sWhiteEyeTextures[i]); + } + D_809942D8 = 1; + } + this->unk_2A2 = Rand_ZeroFloat(96.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990F50.s") +void EnWf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWf* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80990FC8.s") + Collider_DestroyJntSph(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); + Collider_DestroyCylinder(globalCtx, &this->collider3); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991040.s") +void func_809907D4(EnWf* this) { + this->drawDmgEffScale = 0.75f; + this->drawDmgEffFrozenSteamScale = 1.125f; + this->drawDmgEffAlpha = 1.0f; + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX; + this->collider2.base.colType = COLTYPE_HIT3; + this->collider3.base.colType = COLTYPE_HIT3; + this->unk_2A0 = 80; + this->actor.flags &= ~ACTOR_FLAG_400; + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809910F0.s") +void func_80990854(EnWf* this, GlobalContext* globalCtx) { + if (this->drawDmgEffType == ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->collider2.base.colType = COLTYPE_HIT5; + this->collider3.base.colType = COLTYPE_HIT5; + this->drawDmgEffAlpha = 0.0f; + Actor_SpawnIceEffects(globalCtx, &this->actor, this->limbPos, 10, 2, 0.3f, 0.2f); + this->actor.flags |= ACTOR_FLAG_400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991174.s") +void EnWf_Blink(EnWf* this) { + if (this->eyeIndex != 0) { + this->eyeIndex++; + if (this->eyeIndex == 4) { + this->eyeIndex = 0; + } + } else if (Rand_ZeroOne() < 0.05f) { + this->eyeIndex = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991200.s") +s32 func_80990948(GlobalContext* globalCtx, EnWf* this, s16 arg2) { + Player* player = GET_PLAYER(globalCtx); + s32 sp38; + s32 pad; + s32 pad2; + s16 sp2E; + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991280.s") + sp38 = ABS_ALT(BINANG_SUB(this->actor.wallYaw, this->actor.shape.rot.y)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991438.s") + if (((this->unk_295 == 0) || + ((this->unk_295 == 1) && (this->actor.child != NULL) && (this->actor.child->update != NULL))) && + (this->actor.xzDistToPlayer > 160.0f) && + (this->unk_2A8 < Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos))) { + func_80993524(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099149C.s") + if (func_800BE184(globalCtx, &this->actor, 100.0f, 10000, 12000, this->actor.shape.rot.y) && + ((player->swordAnimation == 0x11) || ((globalCtx->gameplayFrames % 2) != 0))) { + func_8099282C(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991738.s") + if (func_800BE184(globalCtx, &this->actor, 100.0f, 24000, 0x2AA8, this->actor.shape.rot.y)) { + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if ((this->actor.bgCheckFlags & 8) && (sp38 < 12000)) { + func_809926D0(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099177C.s") + if ((player->swordAnimation == 0x11) || ((globalCtx->gameplayFrames % 2) != 0)) { + func_8099282C(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991948.s") + func_8099223C(this); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809919F4.s") + actor = func_800BC444(globalCtx, &this->actor, 80.0f); + if ((actor != NULL) && (actor->id == ACTOR_EN_BOM_CHU)) { + EnBomChu* bomchu = (EnBomChu*)actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991C04.s") + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if (BINANG_ROT180(this->actor.shape.rot.y - bomchu->actor.world.rot.y) < 16000) { + func_809926D0(this); + } + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991C80.s") + if (arg2 != 0) { + if (!Actor_IsFacingPlayer(&this->actor, 7000)) { + func_80992A74(this, globalCtx); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80991FD8.s") + sp2E = player->actor.shape.rot.y - this->actor.shape.rot.y; + if ((this->actor.xzDistToPlayer <= 80.0f) && !Actor_OtherIsTargeted(globalCtx, &this->actor)) { + if (((globalCtx->gameplayFrames % 8) != 0) || (ABS_ALT(sp2E) < 0x38E0)) { + func_80991C04(this); + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992068.s") + func_80991948(this); + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099223C.s") +void func_80990C6C(EnWf* this, GlobalContext* globalCtx, s32 arg2) { + static Vec3f D_809942DC = { 0.0f, 0.1f, 0.0f }; + static Color_RGBA8 D_809942E8 = { 185, 140, 70, 255 }; + static Color_RGBA8 D_809942EC = { 255, 255, 255, 255 }; + s32 i; + Vec3f sp88; + u32 temp_v0; + Color_RGBA8* phi_s1; + s16 phi_s6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809922B4.s") + if (this->actor.floorPoly != NULL) { + temp_v0 = func_800C99D4(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); + if (temp_v0 != 5) { + if ((temp_v0 == 15) || (temp_v0 == 14)) { + phi_s1 = &D_809942EC; + phi_s6 = Rand_ZeroFloat(150.0f) + 350.0f; + arg2 += 2; + } else { + phi_s1 = &D_809942E8; + phi_s6 = Rand_ZeroFloat(100.0f) + 250.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809923B0.s") + for (i = 0; i < arg2; i++) { + 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, &gZeroVec3f, &D_809942DC, phi_s1, phi_s1, phi_s6, 5, + Rand_ZeroFloat(5.0f) + 14.0f); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809923E4.s") +void func_80990E4C(EnWf* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, 1.0f) && (this->actor.bgCheckFlags & 1)) { + func_80990C6C(this, globalCtx, 2); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_WALK); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099245C.s") +s32 func_80990EAC(EnWf* this) { + ObjIcePoly* icePoly = (ObjIcePoly*)this->actor.child; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809924EC.s") + if (icePoly->unk_148 < 200) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809926D0.s") +void func_80990ED4(EnWf* this) { + this->actor.child = NULL; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_APPEAR); + func_80991438(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992784.s") +void func_80990F0C(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + this->actor.shape.shadowScale = 0.0f; + this->actor.scale.y = 0.0f; + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_2A0 = 60; + this->actionFunc = func_80990F50; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099282C.s") +void func_80990F50(EnWf* this, GlobalContext* globalCtx) { + f32 phi_f2 = 240.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809928CC.s") + if (this->unk_2A0 != 0) { + this->unk_2A0--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992A74.s") + if (this->unk_2A0 <= 0) { + if (this->unk_2A8 < 240.0f) { + phi_f2 = this->unk_2A8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992B8C.s") + if (this->actor.xzDistToPlayer < phi_f2) { + func_80990FC8(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992D6C.s") +void func_80990FC8(EnWf* this) { + Animation_Change(&this->skelAnime, &gWolfosRearingUpFallingOverAnim, 0.5f, 0.0f, 7.0f, 3, 0.0f); + this->unk_2A0 = 5; + this->actor.flags |= ACTOR_FLAG_1; + this->actionFunc = func_80991040; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992E0C.s") +void func_80991040(EnWf* this, GlobalContext* globalCtx) { + if (this->unk_2A0 != 0) { + this->actor.scale.y += this->actor.scale.x * 0.2f; + Math_StepToF(&this->actor.shape.shadowScale, 70.0f, 14.0f); + this->unk_2A0--; + if (this->unk_2A0 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_APPEAR); + } + } else if (SkelAnime_Update(&this->skelAnime)) { + this->actor.scale.y = this->actor.scale.x; + func_80991200(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80992FD4.s") +void func_809910F0(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + this->actor.speedXZ = 0.0f; + Animation_Change(&this->skelAnime, &gWolfosRearingUpFallingOverAnim, 0.5f, 0.0f, 7.0f, 3, -5.0f); + this->unk_2A0 = 5; + this->actionFunc = func_80991174; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993018.s") +void func_80991174(EnWf* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_2A0 > 0) { + this->actor.scale.y -= this->actor.scale.x * 0.2f; + Math_StepToF(&this->actor.shape.shadowScale, 0.0f, 14.0f); + this->unk_2A0--; + } else { + func_80990F0C(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993148.s") +void func_80991200(EnWf* this) { + this->collider2.base.acFlags |= AC_ON; + Animation_MorphToLoop(&this->skelAnime, &gWolfosWaitingAnim, -4.0f); + this->unk_2A0 = (s32)Rand_ZeroFloat(10.0f) + 2; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_80991280; + this->actor.speedXZ = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993194.s") +void func_80991280(EnWf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 temp_v0; + s32 phi_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993350.s") + SkelAnime_Update(&this->skelAnime); + if (this->unk_298 != 0) { + temp_v0 = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->unk_29E; + if (ABS_ALT(temp_v0) > 0x2000) { + this->unk_298--; + return; + } + this->unk_298 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_809933A0.s") + if (!func_8099408C(globalCtx, this) && !func_80990948(globalCtx, this, 0)) { + phi_v1 = ABS_ALT(BINANG_SUB(player->actor.shape.rot.y, this->actor.shape.rot.y)); + if ((this->actor.xzDistToPlayer < 80.0f) && (player->swordState != 0) && (phi_v1 >= 0x1F40)) { + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80991948(this); + } else { + this->unk_2A0--; + if (this->unk_2A0 == 0) { + if (Actor_IsFacingPlayer(&this->actor, 0x1555)) { + if (Rand_ZeroOne() > 0.3f) { + func_80991438(this); + } else { + func_80991948(this); + } + } else { + func_80991738(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993524.s") + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099357C.s") +void func_80991438(EnWf* this) { + this->collider2.base.acFlags |= AC_ON; + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.speedXZ = 8.0f; + this->actionFunc = func_8099149C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993738.s") +void func_8099149C(EnWf* this, GlobalContext* globalCtx) { + f32 sp2C; + s32 sp28; + s32 pad; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099386C.s") + if (!func_8099408C(globalCtx, this)) { + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 500); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Actor_OtherIsTargeted(globalCtx, &this->actor)) { + sp2C = 150.0f; + } else { + sp2C = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/EnWf_Update.s") + sp28 = ABS_ALT(BINANG_SUB(player->actor.shape.rot.y, this->actor.shape.rot.y)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993E50.s") + if ((this->actor.xzDistToPlayer < (150.0f + sp2C)) && (player->swordState != 0) && (sp28 >= 0x1F40)) { + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if (Rand_ZeroOne() > 0.7f) { + func_80991948(this); + return; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_80993E94.s") + SkelAnime_Update(&this->skelAnime); + if (!func_80990948(globalCtx, this, 0)) { + if (!Actor_IsFacingPlayer(&this->actor, 0x11C7)) { + if (Rand_ZeroOne() > 0.5f) { + func_80991948(this); + } else { + func_80991200(this); + } + } else if (this->actor.xzDistToPlayer < (90.0f + sp2C)) { + if (!Actor_OtherIsTargeted(globalCtx, &this->actor) && + ((Rand_ZeroOne() > 0.03f) || ((this->actor.xzDistToPlayer <= 80.0f) && (sp28 < 0x38E0)))) { + func_80991C04(this); + } else if (Actor_OtherIsTargeted(globalCtx, &this->actor) && (Rand_ZeroOne() > 0.5f)) { + func_8099223C(this); + } else { + func_80991948(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/EnWf_Draw.s") + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wf/func_8099408C.s") + func_80990E4C(this, globalCtx); + } + } +} + +void func_80991738(EnWf* this) { + Animation_MorphToLoop(&this->skelAnime, &gWolfosSidesteppingAnim, -4.0f); + this->actionFunc = func_8099177C; +} + +void func_8099177C(EnWf* this, GlobalContext* globalCtx) { + s16 temp_v0; + s16 phi_v1; + f32 phi_f2; + f32 phi_f12; + + if (!func_8099408C(globalCtx, this) && !func_80990948(globalCtx, this, 0)) { + temp_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (temp_v0 > 0) { + phi_v1 = (temp_v0 * 0.25f) + 2000.0f; + } else { + phi_v1 = (temp_v0 * 0.25f) - 2000.0f; + } + + this->actor.shape.rot.y += phi_v1; + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (temp_v0 > 0) { + phi_f2 = phi_v1 * 0.5f; + phi_f12 = 1.0f; + if (phi_f2 > 1.0f) { + phi_f2 = phi_f12; + } + } else { + phi_f2 = phi_v1 * 0.5f; + phi_f12 = -1.0f; + if (phi_f2 < -1.0f) { + phi_f2 = phi_f12; + } + } + + this->skelAnime.playSpeed = -phi_f2; + SkelAnime_Update(&this->skelAnime); + if (Actor_IsFacingPlayer(&this->actor, 0x1555)) { + if (Rand_ZeroOne() > 0.8f) { + func_80991948(this); + } else { + func_80991438(this); + } + } + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } + } +} + +void func_80991948(EnWf* this) { + this->collider2.base.acFlags |= AC_ON; + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + if (Rand_ZeroOne() > 0.5f) { + this->unk_29A = 16000; + } else { + this->unk_29A = -16000; + } + this->actor.speedXZ = 6.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_2A0 = (s32)Rand_ZeroFloat(30.0f) + 30; + this->actionFunc = func_809919F4; +} + +void func_809919F4(EnWf* this, GlobalContext* globalCtx) { + s16 sp26; + Player* player = GET_PLAYER(globalCtx); + s16 temp_v0; + + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + this->unk_29A, 2500); + if (!func_8099408C(globalCtx, this) && !func_80990948(globalCtx, this, 0)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + sp26 = BINANG_ROT180(player->actor.shape.rot.y + this->unk_29A); + if (this->actor.bgCheckFlags & 8) { + temp_v0 = (this->actor.wallYaw - this->actor.yawTowardsPlayer) - this->unk_29A; + if (ABS_ALT(temp_v0) > 0x2EE0) { + this->unk_29A = -this->unk_29A; + } + } + + SkelAnime_Update(&this->skelAnime); + func_80990E4C(this, globalCtx); + + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } + + if ((Math_CosS(sp26 - this->actor.shape.rot.y) < -0.85f) && !Actor_OtherIsTargeted(globalCtx, &this->actor) && + (this->actor.xzDistToPlayer <= 80.0f)) { + func_80991C04(this); + } else { + this->unk_2A0--; + if (this->unk_2A0 == 0) { + if (Actor_OtherIsTargeted(globalCtx, &this->actor) && (Rand_ZeroOne() > 0.5f)) { + func_8099223C(this); + } else { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(3.0f) + 1; + } + } + } + } +} + +void func_80991C04(EnWf* this) { + this->collider2.base.acFlags |= AC_ON; + Animation_PlayOnce(&this->skelAnime, &gWolfosSlashingAnim); + this->collider1.base.atFlags &= ~AT_BOUNCED; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->unk_2A0 = 7; + this->skelAnime.endFrame = 20.0f; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80991C80; +} + +void func_80991C80(EnWf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp30; + s32 sp2C; + s16 sp2A; + + sp2A = BINANG_SUB(player->actor.shape.rot.y, this->actor.shape.rot.y); + sp30 = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)); + + this->actor.speedXZ = 0.0f; + if (((this->skelAnime.curFrame >= 9.0f) && (this->skelAnime.curFrame < 13.0f)) || + ((this->skelAnime.curFrame >= 17.0f) && (this->skelAnime.curFrame < 20.0f))) { + if (!(this->collider1.base.atFlags & AT_ON)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_ATTACK); + } + this->collider1.base.atFlags |= AT_ON; + } else { + this->collider1.base.atFlags &= ~AT_ON; + } + + sp2C = Animation_OnFrame(&this->skelAnime, 15.0f); + if (((sp2C != 0) && !Actor_IsTargeted(globalCtx, &this->actor) && + (!Actor_IsFacingPlayer(&this->actor, 0x2000) || (this->actor.xzDistToPlayer >= 100.0f))) || + SkelAnime_Update(&this->skelAnime)) { + if ((sp2C == 0) && (this->unk_2A0 != 0)) { + this->actor.shape.rot.y += (s16)(0xCCC * (1.5f + ((this->unk_2A0 - 4) * 0.4f))); + func_80990C6C(this, globalCtx, 1); + this->unk_2A0--; + } else if (!Actor_IsFacingPlayer(&this->actor, 0x1554) && (sp2C == 0)) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(5.0f) + 5; + if (sp30 >= 0x32C9) { + this->unk_298 = 7; + } + } else if ((Rand_ZeroOne() > 0.7f) || (this->actor.xzDistToPlayer >= 120.0f)) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(5.0f) + 5; + } else { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if (Rand_ZeroOne() > 0.7f) { + func_80992A74(this, globalCtx); + } else if (ABS_ALT(sp2A) < 0x2711) { + if (sp30 >= 0x3E81) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80991948(this); + } else { + func_80990948(globalCtx, this, 1); + } + } else { + func_80991948(this); + } + } + } +} + +void func_80991FD8(EnWf* this) { + f32 phi_f0 = 1.0f; + + if (this->skelAnime.curFrame > 15.0f) { + phi_f0 = 15.0f; + } + Animation_Change(&this->skelAnime, &gWolfosSlashingAnim, -0.5f, this->skelAnime.curFrame - 1.0f, phi_f0, 3, 0.0f); + this->collider1.base.atFlags &= ~AT_ON; + this->actionFunc = func_80992068; +} + +void func_80992068(EnWf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp28; + s16 sp26; + + sp26 = BINANG_SUB(player->actor.shape.rot.y, this->actor.shape.rot.y); + sp28 = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)); + + if (SkelAnime_Update(&this->skelAnime)) { + if (!Actor_IsFacingPlayer(&this->actor, 0x1554)) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(5.0f) + 5; + if (sp28 > 0x32C8) { + this->unk_298 = 30; + } + } else if ((Rand_ZeroOne() > 0.7f) || (this->actor.xzDistToPlayer >= 120.0f)) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(5.0f) + 5; + } else { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if (Rand_ZeroOne() > 0.7f) { + func_80992A74(this, globalCtx); + } else if (ABS_ALT(sp26) < 0x2711) { + if (sp28 > 0x3E80) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80991948(this); + } else { + func_80990948(globalCtx, this, 1); + } + } else { + func_80991948(this); + } + } + } +} + +void func_8099223C(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + Animation_MorphToPlayOnce(&this->skelAnime, &gWolfosBackflippingAnim, -3.0f); + this->unk_2A0 = 0; + this->actor.speedXZ = -6.0f; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP); + this->actionFunc = func_809922B4; +} + +void func_809922B4(EnWf* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (!Actor_OtherIsTargeted(globalCtx, &this->actor) && (this->actor.xzDistToPlayer < 170.0f) && + (this->actor.xzDistToPlayer > 140.0f) && (Rand_ZeroOne() < 0.2f)) { + func_80991438(this); + } else if ((globalCtx->gameplayFrames % 2) != 0) { + func_80992A74(this, globalCtx); + } else { + func_80991200(this); + } + } + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } +} + +void func_809923B0(EnWf* this) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = 0.0f; + } + this->actionFunc = func_809923E4; +} + +void func_809923E4(EnWf* this, GlobalContext* globalCtx) { + if (this->unk_2A0 != 0) { + this->unk_2A0--; + } + + if (this->unk_2A0 == 0) { + func_80990854(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + func_80992D6C(this); + } else { + func_80990948(globalCtx, this, 1); + } + } +} + +void func_8099245C(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + Animation_MorphToPlayOnce(&this->skelAnime, &gWolfosDamagedAnim, -4.0f); + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = -4.0f; + } + this->unk_298 = 0; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_DAMAGE); + this->actionFunc = func_809924EC; +} + +void func_809924EC(EnWf* this, GlobalContext* globalCtx) { + s16 sp26; + + if (this->actor.bgCheckFlags & 2) { + this->actor.speedXZ = 0.0f; + } + + if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ < 0.0f)) { + this->actor.speedXZ += 0.05f; + } + + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3000); + if (SkelAnime_Update(&this->skelAnime)) { + sp26 = this->actor.wallYaw - this->actor.shape.rot.y; + + if (func_80990948(globalCtx, this, 0)) { + return; + } + + if ((this->actor.bgCheckFlags & 8) && (ABS_ALT(sp26) < 0x2EE0) && (this->actor.xzDistToPlayer < 120.0f)) { + func_809926D0(this); + } else if (!func_8099408C(globalCtx, this)) { + if ((this->actor.xzDistToPlayer <= 80.0f) && !Actor_OtherIsTargeted(globalCtx, &this->actor) && + ((globalCtx->gameplayFrames % 8) != 0)) { + func_80991C04(this); + } else if (Rand_ZeroOne() > 0.5f) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(5.0f) + 5; + this->unk_298 = 30; + } else { + func_8099223C(this); + } + } + } +} + +void func_809926D0(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + Animation_Change(&this->skelAnime, &gWolfosBackflippingAnim, -1.0f, + Animation_GetLastFrame(&gWolfosBackflippingAnim.common), 0.0f, 2, -3.0f); + this->unk_2A0 = 0; + this->actor.speedXZ = 6.5f; + this->actor.velocity.y = 15.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_TEKU_JUMP); + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_80992784; +} + +void func_80992784(EnWf* this, GlobalContext* globalCtx) { + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2500); + if (SkelAnime_Update(&this->skelAnime) && (this->actor.bgCheckFlags & (2 | 1))) { + this->actor.shape.rot.x = 0; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->actor.world.pos.y = this->actor.floorHeight; + if (!Actor_OtherIsTargeted(globalCtx, &this->actor)) { + func_80991C04(this); + } else { + func_80991200(this); + } + } +} + +void func_8099282C(EnWf* this) { + this->collider2.base.acFlags |= AC_ON; + this->collider1.base.atFlags &= ~AT_ON; + this->unk_2A0 = 10; + this->actor.speedXZ = 0.0f; + Animation_Change(&this->skelAnime, &gWolfosBlockingAnim, -1.0f, Animation_GetLastFrame(&gWolfosBlockingAnim.common), + 0.0f, 2, -2.0f); + this->actionFunc = func_809928CC; +} + +void func_809928CC(EnWf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 sp2A; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_2A0 != 0) { + this->unk_2A0--; + } else if (func_800BE184(globalCtx, &this->actor, 100.0f, 10000, 0x4000, this->actor.shape.rot.y)) { + if ((player->swordAnimation != 0x11) || ((globalCtx->gameplayFrames % 2) != 0)) { + this->unk_2A0 = 10; + } else { + func_8099223C(this); + } + } else if (Actor_IsFacingPlayer(&this->actor, 0x4000) && (this->actor.xzDistToPlayer < 60.0f) && + (fabsf(this->actor.playerHeightRel) < 50.0f)) { + sp2A = player->actor.shape.rot.y - this->actor.shape.rot.y; + if (!Actor_OtherIsTargeted(globalCtx, &this->actor) && + (((globalCtx->gameplayFrames % 2) != 0) || (ABS_ALT(sp2A) < 0x38E0))) { + func_80991C04(this); + } else { + func_80991948(this); + } + } else { + func_80991948(this); + } + } +} + +void func_80992A74(EnWf* this, GlobalContext* globalCtx) { + Player* player; + f32 temp_f0; + + this->collider2.base.acFlags |= AC_ON; + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + player = GET_PLAYER(globalCtx); + temp_f0 = Math_SinS((player->actor.shape.rot.y + this->unk_29A) - this->actor.yawTowardsPlayer); + if (temp_f0 > 0.0f) { + this->unk_29A = 16000; + } else if (temp_f0 < 0.0f) { + this->unk_29A = -16000; + } else if (Rand_ZeroOne() > 0.5f) { + this->unk_29A = 16000; + } else { + this->unk_29A = -16000; + } + this->actor.speedXZ = 6.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->unk_2A0 = (s32)Rand_ZeroFloat(10.0f) + 5; + this->actionFunc = func_80992B8C; +} + +void func_80992B8C(EnWf* this, GlobalContext* globalCtx) { + s32 sp28; + s32 sp2C; + Player* player = GET_PLAYER(globalCtx); + + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer + this->unk_29A, 2000); + if (this->actor.bgCheckFlags & 8) { + sp2C = BINANG_SUB((this->actor.wallYaw - this->actor.yawTowardsPlayer), this->unk_29A); + if (ABS_ALT(sp2C) > 0x2EE0) { + this->unk_29A = -this->unk_29A; + } + } + + this->actor.world.rot.y = this->actor.shape.rot.y; + SkelAnime_Update(&this->skelAnime); + + if (!func_80990948(globalCtx, this, 0)) { + this->unk_2A0--; + if (this->unk_2A0 == 0) { + sp28 = ABS_ALT(BINANG_SUB(player->actor.shape.rot.y, this->actor.yawTowardsPlayer)); + if (sp28 >= 0x3A98) { + func_80991200(this); + this->unk_2A0 = (s32)Rand_ZeroFloat(3.0f) + 1; + } else { + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->actor.xzDistToPlayer <= 80.0f) && !Actor_OtherIsTargeted(globalCtx, &this->actor) && + (((globalCtx->gameplayFrames % 4) == 0) || (sp28 < 0x38E0))) { + func_80991C04(this); + } else { + func_80991438(this); + } + } + } + + func_80990E4C(this, globalCtx); + + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } + } +} + +void func_80992D6C(EnWf* this) { + this->collider2.base.acFlags &= ~AC_ON; + Animation_MorphToPlayOnce(&this->skelAnime, &gWolfosRearingUpFallingOverAnim, -4.0f); + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ = -6.0f; + } + this->actor.flags &= ~ACTOR_FLAG_1; + this->unk_2A0 = 25; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_DEAD); + this->actionFunc = func_80992E0C; +} + +void func_80992E0C(EnWf* this, GlobalContext* globalCtx) { + static Vec3f D_809942F0 = { 0.0f, 0.5f, 0.0f }; + + if (this->actor.bgCheckFlags & 2) { + this->actor.speedXZ = 0.0f; + } + + if (this->actor.bgCheckFlags & 1) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + } + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_295 != 0) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x70); + } else { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60); + } + Actor_MarkForDeath(&this->actor); + } else { + s32 i; + Vec3f sp60; + + if (this->unk_2A0 == 25) { + SoundSource_PlaySfxEachFrameAtFixedWorldPos(globalCtx, &this->actor.world.pos, 36, + NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + + this->unk_2A0--; + + for (i = (25 - this->unk_2A0) >> 1; i >= 0; i--) { + sp60.x = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.x; + sp60.z = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.z; + sp60.y = randPlusMinusPoint5Scaled(50.0f) + (this->actor.world.pos.y + 20.0f); + func_800B3030(globalCtx, &sp60, &D_809942F0, &D_809942F0, 100, 0, 2); + } + + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } +} + +void func_80992FD4(EnWf* this) { + Animation_MorphToLoop(&this->skelAnime, &gWolfosWaitingAnim, -4.0f); + this->actionFunc = func_80993018; +} + +void func_80993018(EnWf* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + if (func_80990EAC(this)) { + func_80990ED4(this); + } else if (this->actor.child->xzDistToPlayer < (80.0f + this->unk_2A4)) { + func_80993350(this); + } else { + s16 temp_v0 = Actor_YawBetweenActors(this->actor.child, &this->actor); + s16 temp_v1 = BINANG_SUB(temp_v0 - this->actor.child->yawTowardsPlayer, 0x8000); + + if (ABS_ALT(temp_v1) > 0x800) { + func_80993148(this); + } else { + Math_ScaledStepToS(&this->actor.shape.rot.y, BINANG_ROT180(temp_v0), 0x800); + } + } + } else { + func_80990ED4(this); + } +} + +void func_80993148(EnWf* this) { + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80993194; +} + +void func_80993194(EnWf* this, GlobalContext* globalCtx) { + s16 sp36; + s16 sp34; + s16 sp32; + + SkelAnime_Update(&this->skelAnime); + func_80990E4C(this, globalCtx); + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + if (func_80990EAC(this)) { + func_80990ED4(this); + } else { + if (this->actor.child->xzDistToPlayer < (80.0f + this->unk_2A4)) { + func_80993350(this); + } else { + sp36 = Actor_YawBetweenActors(this->actor.child, &this->actor); + sp34 = Math_SmoothStepToS(&sp36, BINANG_ROT180(this->actor.child->yawTowardsPlayer), 10, this->unk_29C, + 16); + this->actor.world.pos.x = (Math_SinS(sp36) * this->unk_2A4) + this->actor.child->world.pos.x; + this->actor.world.pos.z = (Math_CosS(sp36) * this->unk_2A4) + this->actor.child->world.pos.z; + if (sp34 < -0x800) { + sp32 = sp36 - 0x4000; + } else if (sp34 > 0x800) { + sp32 = sp36 + 0x4000; + } else { + sp32 = sp36 + 0x8000; + func_80992FD4(this); + } + Math_ScaledStepToS(&this->actor.shape.rot.y, sp32, 0x800); + } + } + } else { + func_80990ED4(this); + } + + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } +} + +void func_80993350(EnWf* this) { + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_APPEAR); + this->actionFunc = func_809933A0; +} + +void func_809933A0(EnWf* this, GlobalContext* globalCtx) { + s16 sp2E; + s16 sp2C; + s16 phi_a1; + + SkelAnime_Update(&this->skelAnime); + func_80990E4C(this, globalCtx); + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + if (func_80990EAC(this)) { + func_80990ED4(this); + } else { + sp2E = Actor_YawBetweenActors(this->actor.child, &this->actor); + Math_ScaledStepToS(&sp2E, this->actor.child->yawTowardsPlayer, this->unk_29C >> 2); + sp2C = sp2E - this->actor.child->yawTowardsPlayer; + this->actor.world.pos.x = (Math_SinS(sp2E) * this->unk_2A4) + this->actor.child->world.pos.x; + this->actor.world.pos.z = (Math_CosS(sp2E) * this->unk_2A4) + this->actor.child->world.pos.z; + if (sp2C > 0) { + phi_a1 = sp2E - 0x4000; + } else { + phi_a1 = sp2E + 0x4000; + } + Math_ScaledStepToS(&this->actor.shape.rot.y, phi_a1, 0x800); + if (ABS_ALT(sp2C) < 0x3000) { + func_80991438(this); + } + } + } else { + func_80990ED4(this); + } + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } +} + +void func_80993524(EnWf* this) { + Animation_MorphToLoop(&this->skelAnime, &gWolfosRunningAnim, -4.0f); + this->actor.speedXZ = 6.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_8099357C; +} + +void func_8099357C(EnWf* this, GlobalContext* globalCtx) { + s16 sp2E; + + SkelAnime_Update(&this->skelAnime); + func_80990E4C(this, globalCtx); + if (this->unk_295 != 0) { + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + sp2E = Actor_YawBetweenActors(&this->actor, this->actor.child); + if (func_80990EAC(this)) { + this->actor.child = NULL; + func_80991738(this); + return; + } + + if (this->actor.bgCheckFlags & 8) { + if (BINANG_SUB(sp2E, this->actor.wallYaw) > 0) { + sp2E = this->actor.wallYaw - 0x4000; + } else { + sp2E = this->actor.wallYaw + 0x4000; + } + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, sp2E, 10, 0x800, 16); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (Actor_XZDistanceBetweenActors(&this->actor, this->actor.child) < (this->unk_2A4 + 10.0f)) { + func_80993148(this); + } + } else { + this->actor.child = NULL; + func_80991738(this); + } + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 10, 0x800, + 16); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 40.0f) { + func_809910F0(this); + } + } + + if (this->unk_2A2 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WOLFOS_CRY); + } +} + +void func_80993738(EnWf* this, GlobalContext* globalCtx) { + if ((this->actionFunc == func_80991280) && (this->unk_298 != 0)) { + this->unk_29E = Math_SinS(this->unk_298 * 4200) * 8920.0f; + } else if ((this->actionFunc == func_80991C80) || (this->actionFunc == func_8099357C) || + (this->actionFunc == func_80991040) || (this->actionFunc == func_80991174)) { + Math_ScaledStepToS(&this->unk_29E, 0, 1000); + } else if (this->actionFunc != func_809923E4) { + Math_ScaledStepToS(&this->unk_29E, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 1000); + this->unk_29E = CLAMP(this->unk_29E, -0x3127, 0x3127); + } +} + +void func_8099386C(EnWf* this, GlobalContext* globalCtx) { + s32 pad; + ColliderCylinder* collider; + + if (this->collider1.base.acFlags & AC_BOUNCED) { + this->collider1.base.acFlags &= ~(AC_BOUNCED | AC_HIT); + this->collider2.base.acFlags &= ~AC_HIT; + this->collider3.base.acFlags &= ~AC_HIT; + return; + } + + if ((this->collider2.base.acFlags & AC_HIT) || (this->collider3.base.acFlags & AC_HIT)) { + if ((!(this->collider2.base.acFlags & AC_HIT) && (this->collider3.base.acFlags & AC_HIT)) || + !Actor_IsFacingPlayer(&this->actor, 0x4A38)) { + this->actor.colChkInfo.damage *= 4; + } + + if (this->collider2.base.acFlags & AC_HIT) { + Actor_SetDropFlag(&this->actor, &this->collider2.info); + collider = &this->collider2; + } else { + Actor_SetDropFlag(&this->actor, &this->collider3.info); + collider = &this->collider3; + } + + this->collider2.base.acFlags &= ~AC_HIT; + this->collider3.base.acFlags &= ~AC_HIT; + this->collider1.base.atFlags &= ~AT_ON; + + if (((this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) || + !(collider->info.acHitInfo->toucher.dmgFlags & + (0x80000 | 0x40000 | 0x10000 | 0x8000 | 0x2000 | 0x1000 | 0x80 | 0x20 | 0x10 | 0x2 | 0x1))) && + (this->actor.colChkInfo.damageEffect != 0xF)) { + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + func_80990854(this, globalCtx); + + if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2A0 = 40; + Actor_SetColorFilter(&this->actor, 0, 0x78, 0, 40); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_809923B0(this); + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_2A0 = 40; + Actor_SetColorFilter(&this->actor, 0, 0xFF, 0, 40); + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_ELECTRIC_SPARKS_SMALL; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 2.0f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_809923B0(this); + } else if (this->actor.colChkInfo.damageEffect == 3) { + func_809907D4(this); + if (this->actor.colChkInfo.health == 0) { + this->unk_2A0 = 3; + this->collider2.base.acFlags &= ~AC_ON; + } + func_809923B0(this); + } else { + if (this->actor.colChkInfo.damageEffect == 2) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_FIRE; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->drawDmgEffType = ACTOR_DRAW_DMGEFF_LIGHT_ORBS; + this->drawDmgEffScale = 0.75f; + this->drawDmgEffAlpha = 4.0f; + 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); + } + + Actor_SetColorFilter(&this->actor, 0x4000, 0xFF, 0, 8); + if (this->actor.colChkInfo.health == 0) { + func_80992D6C(this); + } else { + func_8099245C(this); + } + } + } + } +} + +void EnWf_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnWf* this = THIS; + + if (this->unk_2A2 == 0) { + this->unk_2A2 = 96; + } else { + this->unk_2A2--; + } + + func_8099386C(this, globalCtx); + if (this->actionFunc != func_809923E4) { + EnWf_Blink(this); + } + + this->actionFunc(this, globalCtx); + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 32.0f, 30.0f, 60.0f, 0x1D); + func_80993738(this, globalCtx); + + if (this->actor.bgCheckFlags & (2 | 1)) { + func_800BE3D0(&this->actor, this->actor.shape.rot.y, &this->actor.shape.rot); + } else { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 600); + Math_ScaledStepToS(&this->actor.shape.rot.z, 0, 600); + } + + if (this->actionFunc != func_80990F50) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + if (this->collider2.base.acFlags & AC_ON) { + Collider_UpdateCylinder(&this->actor, &this->collider2); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider3.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + + if (this->actionFunc == func_809928CC) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + if (this->collider1.base.atFlags & AT_ON) { + if (!(this->collider1.base.atFlags & AT_BOUNCED)) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } else { + func_80991FD8(this); + } + } + + Actor_SetFocus(&this->actor, 25.0f); + + if (this->drawDmgEffAlpha > 0.0f) { + if (this->drawDmgEffType != ACTOR_DRAW_DMGEFF_FROZEN_NO_SFX) { + Math_StepToF(&this->drawDmgEffAlpha, 0.0f, 0.05f); + this->drawDmgEffScale = (this->drawDmgEffAlpha + 1.0f) * 0.375f; + if (this->drawDmgEffScale > 0.75f) { + this->drawDmgEffScale = 0.75f; + } else { + this->drawDmgEffScale = this->drawDmgEffScale; + } + } else if (!Math_StepToF(&this->drawDmgEffFrozenSteamScale, 0.75f, 0.01875f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 EnWf_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnWf* this = THIS; + + if ((limbIndex == WOLFOS_NORMAL_LIMB_HEAD) || (limbIndex == WOLFOS_NORMAL_LIMB_EYES)) { + rot->y -= this->unk_29E; + } + return false; +} + +void EnWf_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static s8 D_809942FC[] = { + -1, -1, -1, -1, -1, 0, 1, -1, -1, -1, -1, 2, -1, 3, 4, 5, 6, -1, -1, 7, 8, 9, + }; + EnWf* this = THIS; + Vec3f sp20; + + Collider_UpdateSpheres(limbIndex, &this->collider1); + + if (D_809942FC[limbIndex] != -1) { + Matrix_MultZero(&this->limbPos[D_809942FC[limbIndex]]); + } + + if (limbIndex == WOLFOS_NORMAL_LIMB_TAIL) { + Matrix_MultVecX(1200.0f, &sp20); + this->collider3.dim.pos.x = sp20.x; + this->collider3.dim.pos.y = sp20.y; + this->collider3.dim.pos.z = sp20.z; + } +} + +void EnWf_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnWf* this = THIS; + + if (this->actionFunc != func_80990F50) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->actor.params == 0) { + gSPSegment(POLY_OPA_DISP++, 0x08, sNormalEyeTextures[this->eyeIndex]); + } else { + gSPSegment(POLY_OPA_DISP++, 0x08, sWhiteEyeTextures[this->eyeIndex]); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnWf_OverrideLimbDraw, EnWf_PostLimbDraw, &this->actor); + Actor_DrawDamageEffects(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->drawDmgEffScale, this->drawDmgEffFrozenSteamScale, this->drawDmgEffAlpha, + this->drawDmgEffType); + } +} + +s32 func_8099408C(GlobalContext* globalCtx, EnWf* this) { + Actor* temp_v0 = func_800BC270(globalCtx, &this->actor, 80.0f, 0x138B0); + s16 temp_v1; + + if (temp_v0 != NULL) { + temp_v1 = (Actor_YawBetweenActors(&this->actor, temp_v0) - this->actor.shape.rot.y) - this->unk_29E; + if (ABS_ALT(temp_v1) < 0x3000) { + if (Rand_ZeroOne() < 0.5f) { + func_8099223C(this); + } else { + func_8099282C(this); + } + return true; + } + } + return false; +} diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.h b/src/overlays/actors/ovl_En_Wf/z_en_wf.h index 8e3d132ab..94cfb18e7 100644 --- a/src/overlays/actors/ovl_En_Wf/z_en_wf.h +++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.h @@ -2,16 +2,39 @@ #define Z_EN_WF_H #include "global.h" +#include "objects/object_wf/object_wf.h" struct EnWf; typedef void (*EnWfActionFunc)(struct EnWf*, GlobalContext*); +#define ENWF_GET_80(thisx) ((thisx)->params & 0x80) + typedef struct EnWf { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x14C]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[WOLFOS_NORMAL_LIMB_MAX]; + /* 0x020C */ Vec3s morphTable[WOLFOS_NORMAL_LIMB_MAX]; /* 0x0290 */ EnWfActionFunc actionFunc; - /* 0x0294 */ char unk_294[0x254]; + /* 0x0294 */ u8 eyeIndex; + /* 0x0295 */ u8 unk_295; + /* 0x0296 */ u8 drawDmgEffType; + /* 0x0298 */ s16 unk_298; + /* 0x029A */ s16 unk_29A; + /* 0x029C */ s16 unk_29C; + /* 0x029E */ s16 unk_29E; + /* 0x02A0 */ s16 unk_2A0; + /* 0x02A2 */ u16 unk_2A2; + /* 0x02A4 */ f32 unk_2A4; + /* 0x02A8 */ f32 unk_2A8; + /* 0x02AC */ f32 drawDmgEffAlpha; + /* 0x02B0 */ f32 drawDmgEffScale; + /* 0x02B4 */ f32 drawDmgEffFrozenSteamScale; + /* 0x02B8 */ Vec3f limbPos[10]; + /* 0x0330 */ ColliderJntSph collider1; + /* 0x0350 */ ColliderJntSphElement collider1Elements[4]; + /* 0x0450 */ ColliderCylinder collider2; + /* 0x049C */ ColliderCylinder collider3; } EnWf; // size = 0x4E8 extern const ActorInit En_Wf_InitVars; diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c index 2190b28cd..7279650e7 100644 --- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c +++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.c @@ -1,6 +1,14 @@ +/* + * File: z_en_wiz.c + * Overlay: ovl_En_Wiz + * Description: Wizzrobe + */ + #include "z_en_wiz.h" -#define FLAGS 0x88101035 +#define FLAGS \ + (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_1000 | ACTOR_FLAG_100000 | \ + ACTOR_FLAG_8000000 | ACTOR_FLAG_80000000) #define THIS ((EnWiz*)thisx) 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_Brock/z_en_wiz_brock.c b/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.c index 48ad84d58..ddfa6af47 100644 --- a/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.c +++ b/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.c @@ -1,15 +1,33 @@ -#include "z_en_wiz_brock.h" +/* + * File: z_en_wiz_brock.c + * Overlay: ovl_En_Wiz_Brock + * Description: Wizzrobe Warp Platform + */ -#define FLAGS 0x08000010 +#include "z_en_wiz_brock.h" +#include "objects/object_wiz/object_wiz.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_8000000) #define THIS ((EnWizBrock*)thisx) +typedef enum { + PLATFORM_TYPE_INACTIVE, + PLATFORM_TYPE_FIRE, + PLATFORM_TYPE_ICE, + PLATFORM_TYPE_MAX, +} PlatformType; + void EnWizBrock_Init(Actor* thisx, GlobalContext* globalCtx); void EnWizBrock_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWizBrock_Update(Actor* thisx, GlobalContext* globalCtx); void EnWizBrock_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnWizBrock_SetupUpdateStatus(EnWizBrock* this, GlobalContext* globalCtx); +void EnWizBrock_UpdateStatus(EnWizBrock* this, GlobalContext* globalCtx); + +s16 platformCount = 0; + const ActorInit En_Wiz_Brock_InitVars = { ACTOR_EN_WIZ_BROCK, ACTORCAT_PROP, @@ -22,19 +40,106 @@ const ActorInit En_Wiz_Brock_InitVars = { (ActorFunc)EnWizBrock_Draw, }; -#endif +void EnWizBrock_Init(Actor* thisx, GlobalContext* globalCtx) { + EnWizBrock* this = THIS; + CollisionHeader* colHeader = NULL; -extern UNK_TYPE D_060010E8; -extern UNK_TYPE D_06001690; + DynaPolyActor_Init(&this->dyna, 0); + CollisionHeader_GetVirtual(&object_wiz_Colheader_001690, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + this->dyna.actor.colChkInfo.health = 3; + this->unk_1A6 = 0; + Actor_SetScale(&this->dyna.actor, 0.01f); + this->platformNum = platformCount++; + this->actionFunc = EnWizBrock_SetupUpdateStatus; + this->dyna.actor.scale.x = this->dyna.actor.scale.y = this->dyna.actor.scale.z = 0.01f; + this->alpha = 255.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/EnWizBrock_Init.s") +void EnWizBrock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWizBrock* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/EnWizBrock_Destroy.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/func_80A490E4.s") +void EnWizBrock_SetupUpdateStatus(EnWizBrock* this, GlobalContext* globalCtx) { + this->actionFunc = EnWizBrock_UpdateStatus; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/func_80A490FC.s") +/** + * @brief Checks the platform status, when the Wizzrobe is defeated, which triggers timer to + * count up to 30 at which point the platforms are despawned. + */ +void EnWizBrock_UpdateStatus(EnWizBrock* this, GlobalContext* globalCtx) { + if (this->platformType == PLATFORM_TYPE_INACTIVE) { + if (this->dyna.actor.colChkInfo.health != PLATFORM_TYPE_MAX) { + this->platformType = this->dyna.actor.colChkInfo.health; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/EnWizBrock_Update.s") + if (this->dyna.actor.colChkInfo.health == 0) { + this->timer++; + if (this->timer > (BREG(49) + 30)) { + Math_ApproachZeroF(&this->dyna.actor.scale.y, (BREG(50) / 10.0f) + 0.3f, (BREG(51) / 10000.0f) + 0.003f); + Math_ApproachZeroF(&this->alpha, (BREG(52) / 10.0f) + 1.0f, (BREG(53) / 10.0f) + 35.0f); + Math_ApproachF(&this->dyna.actor.scale.x, (BREG(54) / 100.0f) + 0.02f, (BREG(55) / 100.0f) + 0.2f, + (BREG(56) / 1000.0f) + 0.002f); + this->dyna.actor.scale.z = this->dyna.actor.scale.x; + if (this->dyna.actor.scale.y < 0.001f) { + Actor_MarkForDeath(&this->dyna.actor); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Brock/EnWizBrock_Draw.s") +void EnWizBrock_Update(Actor* thisx, GlobalContext* globalCtx) { + EnWizBrock* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void EnWizBrock_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnWizBrock* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + if (this->dyna.actor.colChkInfo.health != 0) { + Scene_SetRenderModeXlu(globalCtx, 0, 1); + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + Gfx_DrawDListOpa(globalCtx, gWizzrobePlatform); + + } else { + Scene_SetRenderModeXlu(globalCtx, 1, 2); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, (s16)this->alpha); + Gfx_DrawDListXlu(globalCtx, gWizzrobePlatform); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (this->platformType != PLATFORM_TYPE_INACTIVE) { + OPEN_DISPS(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&gWizzrobePlatformTexAnim)); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 255, 255); + if (this->platformType == PLATFORM_TYPE_FIRE) { + gDPSetEnvColor(POLY_XLU_DISP++, 255, 00, 100, (s16)this->alpha); + } else { + gDPSetEnvColor(POLY_XLU_DISP++, 50, 00, 255, (s16)this->alpha); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gWizzrobePlatformCenter); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.h b/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.h index 30932c5ac..ac900777e 100644 --- a/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.h +++ b/src/overlays/actors/ovl_En_Wiz_Brock/z_en_wiz_brock.h @@ -8,10 +8,14 @@ struct EnWizBrock; typedef void (*EnWizBrockActionFunc)(struct EnWizBrock*, GlobalContext*); typedef struct EnWizBrock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x5C]; - /* 0x01A0 */ EnWizBrockActionFunc actionFunc; - /* 0x01A4 */ char unk_1A4[0xC]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ UNK_TYPE1 unk_15C[0x44]; + /* 0x1A0 */ EnWizBrockActionFunc actionFunc; + /* 0x1A4 */ s16 timer; // Counter for despawing blocks (Max of 37) + /* 0x1A6 */ s16 unk_1A6; // TODO: set but not used maybe used in wizzrobe? + /* 0x1A8 */ s16 platformNum; // Numeric identifier for platform + /* 0x1AA */ s16 platformType; // Determines element type for platform (ice/fire) + /* 0x1AC */ f32 alpha; } EnWizBrock; // size = 0x1B0 extern const ActorInit En_Wiz_Brock_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 8c45955ec..53713bbb1 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 @@ -1,6 +1,14 @@ -#include "z_en_wiz_fire.h" +/* + * File: z_en_wiz_fire.c + * Overlay: ovl_En_Wiz_Fire + * Description: Wizzrobe Fire/Ice Attack + */ -#define FLAGS 0x08000015 +#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 (ACTOR_FLAG_1 | ACTOR_FLAG_4 | ACTOR_FLAG_10 | ACTOR_FLAG_8000000) #define THIS ((EnWizFire*)thisx) @@ -15,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, @@ -29,51 +42,834 @@ 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 &= ~ACTOR_FLAG_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.lightSettings.fogColor[2] = 0; + globalCtx->envCtx.lightSettings.fogColor[1] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.fogColor[0] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor2[2] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor2[1] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor2[0] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor1[2] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor1[1] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.diffuseColor1[0] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.ambientColor[2] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.ambientColor[1] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.ambientColor[0] = globalCtx->envCtx.lightSettings.fogColor[2]; + globalCtx->envCtx.lightSettings.fogNear = globalCtx->envCtx.lightSettings.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_Push(); + Matrix_RotateYS(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_RotateXS(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_MultVec3f(&sp44, &this->actor.velocity); + Matrix_Pop(); + 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_Push(); + Matrix_RotateYS((s16)randPlusMinusPoint5Scaled(0x100) + this->actor.world.rot.y, MTXMODE_NEW); + sp54.z = randPlusMinusPoint5Scaled(2.0f) + 8.0f; + Matrix_MultVec3f(&sp54, &this->actor.velocity); + Matrix_Pop(); + + 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); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + this->unk_16A = Rand_S16Offset(70, 30); + if (this->unk_16A != 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_WIZ_EXP - SFX_FLAG); + } + } else if (this->unk_16A != 0) { + Actor_PlaySfxAtPos(&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; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + + if (func_8012405C(globalCtx) && (this->collider.base.atFlags & AT_BOUNCED)) { + Actor_PlaySfxAtPos(&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; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + } + + if (this->unk_168 != 0) { + Actor_PlaySfxAtPos(&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); + Actor_PlaySfxAtPos(&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; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + this->actor.world.pos.y = this->actor.floorHeight + 10.0f; + Actor_SetFocus(&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); + Actor_PlaySfxAtPos(&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.lightSettings.fogNear = (phi_f0 - (s16)globalCtx->envCtx.unk_C4.fogNear) * this->unk_204; + + globalCtx->envCtx.lightSettings.ambientColor[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.ambientColor[0]) * this->unk_204; + globalCtx->envCtx.lightSettings.ambientColor[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.ambientColor[1]) * this->unk_204; + globalCtx->envCtx.lightSettings.ambientColor[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.ambientColor[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.lightSettings.diffuseColor1[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor1[0]) * this->unk_204; + globalCtx->envCtx.lightSettings.diffuseColor1[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor1[1]) * this->unk_204; + globalCtx->envCtx.lightSettings.diffuseColor1[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor1[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.lightSettings.diffuseColor2[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor[0]) * this->unk_204; + globalCtx->envCtx.lightSettings.diffuseColor2[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor[1]) * this->unk_204; + globalCtx->envCtx.lightSettings.diffuseColor2[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.lightSettings.fogColor[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.fogColor[0]) * this->unk_204; + globalCtx->envCtx.lightSettings.fogColor[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.fogColor[1]) * this->unk_204; + globalCtx->envCtx.lightSettings.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_UpdatePos(&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) { + Actor_PlaySfxAtPos(&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_Translate(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_RotateYS(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_Push(); + Matrix_Translate(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_Pop(); + Matrix_Push(); + Matrix_Translate(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Pop(); + Matrix_Translate(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Push(); + + 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_Translate(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_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateZS(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_Pop(); + + 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_Translate(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_Mult(&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_Translate(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&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_Wood02/z_en_wood02.c b/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c index d111e7bba..446d92cbd 100644 --- a/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c +++ b/src/overlays/actors/ovl_En_Wood02/z_en_wood02.c @@ -1,4 +1,11 @@ +/* + * File: z_en_wood02.c + * Overlay: ovl_En_Wood02 + * Description: Trees, shrubs + */ + #include "z_en_wood02.h" +#include "objects/object_wood02/object_wood02.h" #define FLAGS 0x00000000 @@ -9,7 +16,28 @@ void EnWood02_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWood02_Update(Actor* thisx, GlobalContext* globalCtx); void EnWood02_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +/** + * WOOD_SPAWN_SPAWNER is also used by some individual trees: EnWood02_Update also checks for parent before running any + * despawning code. + * */ +typedef enum { + /* 0 */ WOOD_SPAWN_NORMAL, + /* 1 */ WOOD_SPAWN_SPAWNED, + /* 2 */ WOOD_SPAWN_SPAWNER +} WoodSpawnType; + +typedef enum { + /* 0 */ WOOD_DRAW_TREE_CONICAL, + /* 1 */ WOOD_DRAW_TREE_OVAL, + /* 2 */ WOOD_DRAW_TREE_KAKARIKO_ADULT, + /* 3 */ WOOD_DRAW_BUSH_GREEN, + /* 4 */ WOOD_DRAW_4, // Used for black bushes and green leaves + /* 5 */ WOOD_DRAW_LEAF_YELLOW +} WoodDrawType; + +static f32 sSpawnCos; +static f32 sSpawnSin; + const ActorInit En_Wood02_InitVars = { ACTOR_EN_WOOD02, ACTORCAT_PROP, @@ -22,29 +50,464 @@ const ActorInit En_Wood02_InitVars = { (ActorFunc)EnWood02_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808C4D00 = { - { COLTYPE_TREE, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK5, { 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_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0x0100020A, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 60, 0, { 0, 0, 0 } }, }; -#endif +static f32 sSpawnDistance[] = { 707.0f, 525.0f, 510.0f, 500.0f, 566.0f, 141.0f }; -extern ColliderCylinderInit D_808C4D00; +static s16 sSpawnAngle[] = { 0x1FFF, 0x4C9E, 0x77F5, 0xA5C9, -0x293D, 0xA000 }; -extern UNK_TYPE D_06000700; +static InitChainEntry sInitChain[] = { + ICHAIN_F32(targetArrowOffset, 5600, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/func_808C3C00.s") +Gfx* D_808C4D54[] = { + object_wood02_DL_0078D0, object_wood02_DL_007CA0, object_wood02_DL_008160, object_wood02_DL_000090, + object_wood02_DL_000340, object_wood02_DL_000340, object_wood02_DL_000700, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/func_808C3D28.s") +Gfx* D_808C4D70[] = { + object_wood02_DL_007968, + object_wood02_DL_007D38, + object_wood02_DL_0080D0, + NULL, + NULL, + NULL, + object_wood02_DL_007AD0, + object_wood02_DL_007E20, + object_wood02_DL_009340, + object_wood02_DL_000160, + object_wood02_DL_000440, + object_wood02_DL_000700, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/EnWood02_Init.s") +s32 EnWood02_SpawnZoneCheck(EnWood02* this, GlobalContext* globalCtx, Vec3f* arg2) { + f32 phi_f12; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/EnWood02_Destroy.s") + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, arg2, &this->actor.projectedPos, + &this->actor.projectedW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/func_808C4458.s") + if (this->actor.projectedW == 0.0f) { + phi_f12 = 1000.0f; + } else { + phi_f12 = fabsf(1.0f / this->actor.projectedW); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/EnWood02_Update.s") + if (((-this->actor.uncullZoneScale < this->actor.projectedPos.z) && + (this->actor.projectedPos.z < (this->actor.uncullZoneForward + this->actor.uncullZoneScale)) && + (((fabsf(this->actor.projectedPos.x) - this->actor.uncullZoneScale) * phi_f12) < 1.0f)) && + (((this->actor.projectedPos.y + this->actor.uncullZoneDownward) * phi_f12) > -1.0f) && + (((this->actor.projectedPos.y - this->actor.uncullZoneScale) * phi_f12) < 1.0f)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wood02/EnWood02_Draw.s") +/** Spawns similar-looking trees or bushes only when the player is sufficiently close. Presumably done this way to keep + * memory usage down in Hyrule Field. */ +void EnWood02_SpawnOffspring(EnWood02* this, GlobalContext* globalCtx) { + EnWood02* child; + s32 extraRot; + Vec3f childPos; + s32 unk; + s32 i; + s16 childParams; + + for (i = 4; i >= 0; i--) { + extraRot = 0; + if (!(this->unk_14A[i] & 0x7F)) { + if (this->actor.params == WOOD_BUSH_GREEN_LARGE_SPAWNER) { + extraRot = 0x4000; + } + + sSpawnCos = Math_CosS(sSpawnAngle[i] + this->actor.world.rot.y + extraRot); + sSpawnSin = Math_SinS(sSpawnAngle[i] + this->actor.world.rot.y + extraRot); + + childPos.x = (sSpawnDistance[i] * sSpawnSin) + this->actor.home.pos.x; + childPos.y = this->actor.home.pos.y; + childPos.z = (sSpawnDistance[i] * sSpawnCos) + this->actor.home.pos.z; + + if (EnWood02_SpawnZoneCheck(this, globalCtx, &childPos)) { + if (this->unk_14A[i] & 0x80) { + unk = 0; + } else { + unk = this->actor.home.rot.z; + } + + childParams = ((this->unk_144 << 8) & 0xFF00) | (this->actor.params + 1); + child = (EnWood02*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_WOOD02, + childPos.x, childPos.y, childPos.z, this->actor.world.rot.x, + sSpawnAngle[i], unk, childParams); + if (child != NULL) { + child->unk_14A[0] = i; + this->unk_14A[i] |= 1; + child->actor.projectedPos = this->actor.projectedPos; + } else { + this->unk_14A[i] &= 0x80; + } + } + } + } +} + +void EnWood02_Init(Actor* thisx, GlobalContext* globalCtx) { + s16 spawnType = 0; + f32 actorScale = 1.0f; + EnWood02* this = THIS; + s32 pad; + CollisionPoly* outPoly; + s32 bgId; + f32 floorY; + s16 extraRot; + + this->actor.world.rot.z = 0; + this->unk_144 = ENWOOD02_GET_FF00(&this->actor); + this->unk_146 = -1; + this->actor.shape.rot.z = this->actor.world.rot.z; + + if (this->unk_144 & 0x80) { + this->unk_144 = -1; + } + + this->actor.params &= 0xFF; + this->unk_148 = this->actor.home.rot.z; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if ((this->actor.params < WOOD_BUSH_GREEN_SMALL) || (this->actor.params == WOOD_TREE_SPECIAL)) { + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + } + + if ((this->actor.params == WOOD_TREE_SPECIAL) && !gSaveContext.save.isNight && (this->unk_144 != -1) && + !Flags_GetCollectible(globalCtx, this->unk_144)) { + this->actor.child = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_ANI, this->actor.world.pos.x, + this->actor.world.pos.y + 120.0f, this->actor.world.pos.z - 15.0f, 0, 0, 0, 1); + if (this->actor.child != NULL) { + this->actor.child->cutscene = this->actor.cutscene; + } + this->unk_151 = 1; + } else { + this->actor.child = NULL; + this->unk_151 = 0; + } + + switch (this->actor.params) { + case WOOD_BUSH_GREEN_LARGE_SPAWNER: + case WOOD_BUSH_BLACK_LARGE_SPAWNER: + spawnType = 1; + + case WOOD_BUSH_GREEN_LARGE_SPAWNED: + case WOOD_BUSH_BLACK_LARGE_SPAWNED: + spawnType++; + + case WOOD_TREE_CONICAL_LARGE: + case WOOD_BUSH_GREEN_LARGE: + case WOOD_BUSH_BLACK_LARGE: + case WOOD_TREE_SPECIAL: + actorScale = 1.5f; + this->actor.uncullZoneForward = 4000.0f; + this->actor.uncullZoneScale = 2000.0f; + this->actor.uncullZoneDownward = 2400.0f; + break; + + case WOOD_TREE_CONICAL_SPAWNER: + case WOOD_TREE_OVAL_YELLOW_SPAWNER: + case WOOD_TREE_OVAL_GREEN_SPAWNER: + case WOOD_BUSH_GREEN_SMALL_SPAWNER: + case WOOD_BUSH_BLACK_SMALL_SPAWNER: + spawnType = 1; + + case WOOD_TREE_CONICAL_SPAWNED: + case WOOD_TREE_OVAL_YELLOW_SPAWNED: + case WOOD_TREE_OVAL_GREEN_SPAWNED: + case WOOD_BUSH_GREEN_SMALL_SPAWNED: + case WOOD_BUSH_BLACK_SMALL_SPAWNED: + spawnType++; + + case WOOD_TREE_CONICAL_MEDIUM: + case WOOD_TREE_OVAL_GREEN: + case WOOD_TREE_KAKARIKO_ADULT: + case WOOD_BUSH_GREEN_SMALL: + case WOOD_BUSH_BLACK_SMALL: + this->actor.uncullZoneForward = 4000.0f; + this->actor.uncullZoneScale = 800.0f; + this->actor.uncullZoneDownward = 1800.0f; + break; + + case WOOD_TREE_CONICAL_SMALL: + actorScale = 0.6f; + this->actor.uncullZoneForward = 4000.0f; + this->actor.uncullZoneScale = 400.0f; + this->actor.uncullZoneDownward = 1000.0f; + break; + + case WOOD_LEAF_GREEN: + case WOOD_LEAF_YELLOW: + this->unk_14A[0] = 75; + actorScale = 0.02f; + this->actor.velocity.x = randPlusMinusPoint5Scaled(6.0f); + this->actor.velocity.z = randPlusMinusPoint5Scaled(6.0f); + this->actor.velocity.y = (Rand_ZeroOne() * 1.25f) + -3.1f; + break; + } + + if (this->actor.params < WOOD_TREE_OVAL_GREEN) { + this->drawType = WOOD_DRAW_TREE_CONICAL; + } else if (this->actor.params < WOOD_TREE_KAKARIKO_ADULT) { + this->drawType = WOOD_DRAW_TREE_OVAL; + } else if (this->actor.params < WOOD_BUSH_GREEN_SMALL) { + this->drawType = WOOD_DRAW_TREE_KAKARIKO_ADULT; + } else if (this->actor.params < WOOD_BUSH_BLACK_SMALL) { + this->drawType = WOOD_DRAW_BUSH_GREEN; + } else if (this->actor.params < WOOD_LEAF_YELLOW) { + this->drawType = WOOD_DRAW_4; + } else if (this->actor.params == WOOD_TREE_SPECIAL) { + this->drawType = WOOD_DRAW_TREE_CONICAL; + } else { + this->drawType = WOOD_DRAW_LEAF_YELLOW; + } + + Actor_SetScale(&this->actor, actorScale); + this->spawnType = spawnType; + + if (spawnType != WOOD_SPAWN_NORMAL) { + extraRot = 0; + if (this->actor.params == WOOD_BUSH_GREEN_LARGE_SPAWNER) { + extraRot = 0x4000; + } + + if (spawnType == WOOD_SPAWN_SPAWNER) { + EnWood02_SpawnOffspring(this, globalCtx); + sSpawnCos = Math_CosS(sSpawnAngle[5] + this->actor.world.rot.y + extraRot); + sSpawnSin = Math_SinS(sSpawnAngle[5] + this->actor.world.rot.y + extraRot); + this->actor.world.pos.x += sSpawnSin * sSpawnDistance[5]; + this->actor.world.pos.z += sSpawnCos * sSpawnDistance[5]; + } else { + this->actor.flags |= ACTOR_FLAG_10; + this->unk_151 = 2; + } + + // Snap to floor, or remove if over void + this->actor.world.pos.y += 200.0f; + floorY = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &outPoly, &bgId, &this->actor, &this->actor.world.pos); + + if (floorY > BGCHECK_Y_MIN) { + this->actor.world.pos.y = floorY; + } else { + Actor_MarkForDeath(&this->actor); + return; + } + } + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + this->actor.home.rot.y = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; +} + +void EnWood02_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWood02* this = THIS; + + if ((this->actor.params < WOOD_BUSH_GREEN_SMALL) || (this->actor.params == WOOD_TREE_SPECIAL)) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} + +void func_808C4458(EnWood02* this, GlobalContext* globalCtx, Vec3f* arg2, u16 arg3) { + s32 pad[2]; + s32 sp24; + + if (this->unk_148 != 0) { + if ((this->unk_144 == -1) || !Flags_GetCollectible(globalCtx, this->unk_144)) { + if ((this->unk_148 < 0) && (this->unk_148 >= -0x10)) { + if (arg3 & 1) { + Item_DropCollectibleRandom(globalCtx, &this->actor, arg2, ((-1 - this->unk_148) * 0x10) | 0x8000); + } else { + Item_DropCollectibleRandom(globalCtx, &this->actor, arg2, (-1 - this->unk_148) * 0x10); + } + } else if (this->unk_148 > 0) { + sp24 = func_800A8150(this->unk_148 - 1); + if (sp24 >= 0) { + if (this->unk_144 == -1) { + Item_DropCollectible(globalCtx, arg2, sp24); + } else { + Item_DropCollectible(globalCtx, arg2, ((this->unk_144 & 0x7F) << 8) | sp24); + } + } + } + } + this->unk_148 = 0; + } +} + +void EnWood02_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWood02* this = THIS; + f32 wobbleAmplitude; + + // Despawn extra trees in a group if out of range + if ((this->spawnType == WOOD_SPAWN_SPAWNED) && (thisx->parent != NULL)) { + if (!(thisx->flags & 0x40) && (this->unk_151 != 2)) { + s32 index = this->unk_14A[0]; + s32 phi_v0 = 0; + + if (this->unk_148 == 0) { + phi_v0 = 0x80; + } + + ((EnWood02*)thisx->parent)->unk_14A[index] = phi_v0; + + Actor_MarkForDeath(thisx); + return; + } + this->unk_151 = 0; + } else if (this->spawnType == WOOD_SPAWN_SPAWNER) { + EnWood02_SpawnOffspring(this, globalCtx); + } + + if ((thisx->params < WOOD_BUSH_GREEN_SMALL) || (thisx->params == WOOD_TREE_SPECIAL)) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_PlaySfxAtPos(thisx, NA_SE_IT_REFLECTION_WOOD); + } + + if (thisx->home.rot.y != 0) { + Vec3f dropsSpawnPt = thisx->world.pos; + + dropsSpawnPt.y += 200.0f; + + func_808C4458(this, globalCtx, &dropsSpawnPt, 0); + + // Spawn falling leaves + if (this->unk_146 >= -1) { + s32 i; + s32 leavesParams = WOOD_LEAF_GREEN; + + if ((thisx->params == WOOD_TREE_OVAL_YELLOW_SPAWNER) || + (thisx->params == WOOD_TREE_OVAL_YELLOW_SPAWNED)) { + leavesParams = WOOD_LEAF_YELLOW; + } + Actor_PlaySfxAtPos(thisx, NA_SE_EV_TREE_SWING); + + for (i = 3; i >= 0; i--) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WOOD02, dropsSpawnPt.x, dropsSpawnPt.y, + dropsSpawnPt.z, 0, randPlusMinusPoint5Scaled(0xFFFF), 0, leavesParams); + } + } + + if ((thisx->child != NULL) && (this->unk_151 == 1)) { + thisx->child->home.rot.x = 1; + this->unk_151 = 0; + } + + if ((thisx->params == WOOD_TREE_SPECIAL) && (this->unk_144 != -1)) { + Flags_SetCollectible(globalCtx, this->unk_144); + this->unk_144 = -1; + } + this->unk_146 = -0x15; + thisx->home.rot.y = 0; + } + + if (thisx->xzDistToPlayer < 600.0f) { + Collider_UpdateCylinder(thisx, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } else if ((thisx->params < WOOD_LEAF_GREEN) || (thisx->params == WOOD_TREE_SPECIAL)) { // not leaves + Player* player = GET_PLAYER(globalCtx); + + if ((this->unk_146 >= -1) && (((player->rideActor == NULL) && (sqrtf(thisx->xyzDistToPlayerSq) < 20.0f) && + (player->linearVelocity != 0.0f)) || + ((player->rideActor != NULL) && (sqrtf(thisx->xyzDistToPlayerSq) < 60.0f) && + (player->rideActor->speedXZ != 0.0f)))) { + func_808C4458(this, globalCtx, &thisx->world.pos, 1); + this->unk_146 = -0x15; + Actor_PlaySfxAtPos(thisx, NA_SE_EV_TREE_SWING); + } + } else { // Leaves + this->unk_146++; + Math_ApproachF(&thisx->velocity.x, 0.0f, 1.0f, 5.0f * 0.01f); + Math_ApproachF(&thisx->velocity.z, 0.0f, 1.0f, 5.0f * 0.01f); + Actor_UpdatePos(thisx); + thisx->shape.rot.z = Math_SinS(this->unk_146 * 0xBB8) * 16384.0f; + this->unk_14A[0]--; + if (this->unk_14A[0] == 0) { + Actor_MarkForDeath(thisx); + } + } + + // Wobble from impact + if (this->unk_146 < -1) { + this->unk_146++; + wobbleAmplitude = Math_SinS((this->unk_146 ^ 0xFFFF) * 0x3332) * 250.0f; + thisx->shape.rot.x = Math_CosS(thisx->yawTowardsPlayer - thisx->shape.rot.y) * wobbleAmplitude; + thisx->shape.rot.z = Math_SinS(thisx->yawTowardsPlayer - thisx->shape.rot.y) * wobbleAmplitude; + } +} + +void EnWood02_Draw(Actor* thisx, GlobalContext* globalCtx) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s16 type; + s16 pad; + u8 red; + u8 green; + u8 blue; + + OPEN_DISPS(gfxCtx); + type = thisx->params; + + if ((type == WOOD_TREE_OVAL_GREEN_SPAWNER) || (type == WOOD_TREE_OVAL_GREEN_SPAWNED) || + (type == WOOD_TREE_OVAL_GREEN) || (type == WOOD_LEAF_GREEN)) { + red = 50; + green = 170; + blue = 70; + } else if ((type == WOOD_TREE_OVAL_YELLOW_SPAWNER) || (type == WOOD_TREE_OVAL_YELLOW_SPAWNED) || + (type == WOOD_LEAF_YELLOW)) { + red = 180; + green = 155; + blue = 0; + } else { + red = green = blue = 255; + } + + func_8012C2DC(gfxCtx); + + if ((thisx->params == WOOD_LEAF_GREEN) || (thisx->params == WOOD_LEAF_YELLOW)) { + func_8012C28C(gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, red, green, blue, 127); + + Gfx_DrawDListOpa(globalCtx, object_wood02_DL_000700); + } else if (D_808C4D70[THIS->drawType & 0xF] != NULL) { + Gfx_DrawDListOpa(globalCtx, D_808C4D54[THIS->drawType & 0xF]); + + gDPSetEnvColor(POLY_XLU_DISP++, red, green, blue, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_808C4D70[THIS->drawType & 0xF]); + } else { + func_8012C2DC(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_808C4D54[THIS->drawType & 0xF]); + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h b/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h index ef638cfcd..310d1e5de 100644 --- a/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h +++ b/src/overlays/actors/ovl_En_Wood02/z_en_wood02.h @@ -5,11 +5,51 @@ struct EnWood02; +#define ENWOOD02_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + typedef struct EnWood02 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x5C]; + /* 0x144 */ s16 unk_144; + /* 0x146 */ s16 unk_146; + /* 0x148 */ s16 unk_148; + /* 0x14A */ u8 unk_14A[5]; + /* 0x14F */ u8 spawnType; + /* 0x150 */ u8 drawType; + /* 0x151 */ u8 unk_151; + /* 0x154 */ ColliderCylinder collider; } EnWood02; // size = 0x1A0 +// Types with SPAWNED in the name are those that can be managed by a spawner, however the actor allows you to spawn them +// on their own without a spawner as well. +typedef enum { + /* 0x00 */ WOOD_TREE_CONICAL_LARGE, + /* 0x01 */ WOOD_TREE_CONICAL_MEDIUM, + /* 0x02 */ WOOD_TREE_CONICAL_SMALL, + /* 0x03 */ WOOD_TREE_CONICAL_SPAWNER, + /* 0x04 */ WOOD_TREE_CONICAL_SPAWNED, + /* 0x05 */ WOOD_TREE_OVAL_GREEN, + /* 0x06 */ WOOD_TREE_OVAL_YELLOW_SPAWNER, + /* 0x07 */ WOOD_TREE_OVAL_YELLOW_SPAWNED, + /* 0x08 */ WOOD_TREE_OVAL_GREEN_SPAWNER, + /* 0x09 */ WOOD_TREE_OVAL_GREEN_SPAWNED, + /* 0x0A */ WOOD_TREE_KAKARIKO_ADULT, + /* 0x0B */ WOOD_BUSH_GREEN_SMALL, + /* 0x0C */ WOOD_BUSH_GREEN_LARGE, + /* 0x0D */ WOOD_BUSH_GREEN_SMALL_SPAWNER, + /* 0x0E */ WOOD_BUSH_GREEN_SMALL_SPAWNED, + /* 0x0F */ WOOD_BUSH_GREEN_LARGE_SPAWNER, + /* 0x10 */ WOOD_BUSH_GREEN_LARGE_SPAWNED, + /* 0x11 */ WOOD_BUSH_BLACK_SMALL, + /* 0x12 */ WOOD_BUSH_BLACK_LARGE, + /* 0x13 */ WOOD_BUSH_BLACK_SMALL_SPAWNER, + /* 0x14 */ WOOD_BUSH_BLACK_SMALL_SPAWNED, + /* 0x15 */ WOOD_BUSH_BLACK_LARGE_SPAWNER, + /* 0x16 */ WOOD_BUSH_BLACK_LARGE_SPAWNED, + /* 0x17 */ WOOD_LEAF_GREEN, + /* 0x18 */ WOOD_LEAF_YELLOW, + /* 0x1A */ WOOD_TREE_SPECIAL = 0x1A +} WoodType; + extern const ActorInit En_Wood02_InitVars; #endif // Z_EN_WOOD02_H diff --git a/src/overlays/actors/ovl_En_Yb/z_en_yb.c b/src/overlays/actors/ovl_En_Yb/z_en_yb.c index 8704d9ea5..b23282c31 100644 --- a/src/overlays/actors/ovl_En_Yb/z_en_yb.c +++ b/src/overlays/actors/ovl_En_Yb/z_en_yb.c @@ -1,6 +1,13 @@ -#include "z_en_yb.h" +/* + * File: z_en_yb.c + * Overlay: ovl_En_Yb + * Description: Kamaro the Dancing Ghost + */ -#define FLAGS 0x02000019 +#include "z_en_yb.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((EnYb*)thisx) @@ -9,16 +16,22 @@ void EnYb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnYb_Update(Actor* thisx, GlobalContext* globalCtx); void EnYb_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BFA730(EnYb* this, GlobalContext* globalCtx); -void func_80BFA868(EnYb* this, GlobalContext* globalCtx); -void func_80BFA91C(EnYb* this, GlobalContext* globalCtx); -void func_80BFA9D4(EnYb* this, GlobalContext* globalCtx); -void func_80BFAB4C(EnYb* this, GlobalContext* globalCtx); -void func_80BFABF0(EnYb* this, GlobalContext* globalCtx); -void func_80BFAC88(EnYb* this, GlobalContext* globalCtx); -void func_80BFAE80(EnYb* this, GlobalContext* globalCtx); +void EnYb_Idle(EnYb* this, GlobalContext* globalCtx); +void EnYb_TeachingDanceFinish(EnYb* this, GlobalContext* globalCtx); +void EnYb_SetupLeaving(EnYb* this, GlobalContext* globalCtx); + +void EnYb_UpdateAnimation(EnYb* this, GlobalContext* globalCtx); +void EnYb_FinishTeachingCutscene(EnYb* this); +void EnYb_Disappear(EnYb* this, GlobalContext* globalCtx); +void EnYb_ReceiveMask(EnYb* this, GlobalContext* globalCtx); +void EnYb_Talk(EnYb* this, GlobalContext* globalCtx); +void EnYb_TeachingDance(EnYb* this, GlobalContext* globalCtx); +void EnYb_WaitForMidnight(EnYb* this, GlobalContext* globalCtx); + +void EnYb_ActorShadowFunc(Actor* thisx, Lights* mapper, GlobalContext* globalCtx); +void EnYb_SetAnimation(GlobalContext*, EnYb*, s16, u8, f32); +s32 EnYb_CanTalk(EnYb* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Yb_InitVars = { ACTOR_EN_YB, ACTORCAT_NPC, @@ -31,59 +44,439 @@ const ActorInit En_Yb_InitVars = { (ActorFunc)EnYb_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BFB2B0 = { - { 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, + }, { 20, 40, 0, { 0, 0, 0 } }, }; -#endif +// crashes if I try to mod it in to look at it +// assumption: draw uses two different skeleton functions, might be incompatible +static AnimationHeader* gYbUnusedAnimations[] = { &object_yb_Anim_000200 }; -extern ColliderCylinderInit D_80BFB2B0; +static LinkAnimationHeader* gLinkAnimations[] = { &gameplay_keep_Linkanim_00DF28, &gameplay_keep_Linkanim_00CF98 }; -extern UNK_TYPE D_06000200; +static Vec3f D_80BFB2E8 = { 0.0f, 0.5f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/EnYb_Init.s") +static Vec3f D_80BFB2F4 = { 500.0f, -500.0, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/EnYb_Destroy.s") +static Vec3f D_80BFB300 = { 500.0f, -500.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA2FC.s") +void EnYb_Init(Actor* thisx, GlobalContext* globalCtx) { + EnYb* this = THIS; + s16 tempCutscene; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA350.s") + Actor_SetScale(&this->actor, 0.01f); + ActorShape_Init(&this->actor.shape, 0.0f, EnYb_ActorShadowFunc, 20.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA444.s") + // @Bug this alignment is because of player animations, but should be using ALIGN16 + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gYbSkeleton, &object_yb_Anim_000200, + (uintptr_t)this->jointTable & ~0xF, (uintptr_t)this->morphTable & ~0xF, YB_LIMB_MAX); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA5CC.s") + Animation_PlayLoop(&this->skelAnime, &object_yb_Anim_000200); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA634.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actionFunc = EnYb_Idle; + this->currentAnimIndex = 3; // gets overwritten to 2 in EnYb_SetAnimation later + this->actor.terminalVelocity = -9.0f; + this->actor.gravity = -1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA67C.s") + EnYb_SetAnimation(globalCtx, this, 2, ANIMMODE_LOOP, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA6E0.s") + tempCutscene = this->actor.cutscene; + for (i = 0; i < ARRAY_COUNT(this->cutscenes); i++) { + this->cutscenes[i] = tempCutscene; + if (tempCutscene != -1) { + this->actor.cutscene = tempCutscene; + tempCutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA710.s") + this->cutsceneIndex = -1; + this->actor.cutscene = this->cutscenes[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA730.s") + // between midnight and morning start spawned + if (gSaveContext.save.time < CLOCK_TIME(6, 0)) { + this->alpha = 255; + } else { // else (night 6pm to midnight): wait to appear + this->alpha = 0; + this->actionFunc = EnYb_WaitForMidnight; + this->actor.flags &= ~ACTOR_FLAG_1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA868.s") + // check if already healed + if (gSaveContext.save.weekEventReg[82] & 4) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA91C.s") +void EnYb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnYb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFA9D4.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFAB4C.s") +void func_80BFA2FC(GlobalContext* globalCtx) { + if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { + func_80151BB4(globalCtx, 0x34); + } + func_80151BB4(globalCtx, 0xF); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFABF0.s") +/** + * Custom shadow draw function of type ActorShadowFunc. + */ +void EnYb_ActorShadowFunc(Actor* thisx, Lights* mapper, GlobalContext* globalCtx) { + Vec3f oldPos; + EnYb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFAC88.s") + if (this->alpha > 0) { + if (this->currentAnimIndex == 2) { + f32 tempScale = (((27.0f - this->shadowPos.y) + this->actor.world.pos.y) * ((1 / 2.25f) * 0.001f)) + 0.01f; + this->actor.scale.x = tempScale; + } + Math_Vec3f_Copy(&oldPos, &this->actor.world.pos); + Math_Vec3f_Copy(&this->actor.world.pos, &this->shadowPos); + func_800B4AEC(globalCtx, &this->actor, 50.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFAE80.s") + if (oldPos.y < this->actor.floorHeight) { + this->actor.world.pos.y = this->actor.floorHeight; + } else { + this->actor.world.pos.y = oldPos.y; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/EnYb_Update.s") + ActorShadow_DrawCircle(&this->actor, mapper, globalCtx); + Math_Vec3f_Copy(&this->actor.world.pos, &oldPos); + this->actor.scale.x = 0.01f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFB074.s") +void EnYb_SetAnimation(GlobalContext* globalCtx, EnYb* this, s16 animIndex, u8 animMode, f32 transitionRate) { + if (animIndex >= 0 && animIndex < 3) { + if (animIndex != this->currentAnimIndex || animMode != ANIMMODE_LOOP) { + if (animIndex > 0) { + if (animMode == ANIMMODE_LOOP) { + LinkAnimation_Change(globalCtx, &this->skelAnime, gLinkAnimations[animIndex - 1], 1.0f, 0.0f, + Animation_GetLastFrame(gLinkAnimations[animIndex - 1]), ANIMMODE_LOOP, + transitionRate); + } else { + // unused case, (only called once with animMode = ANIMMODE_LOOP) + LinkAnimation_Change(globalCtx, &this->skelAnime, gLinkAnimations[animIndex - 1], 1.0f, 0.0f, + Animation_GetLastFrame(gLinkAnimations[animIndex - 1]), ANIMMODE_LOOP, + transitionRate); + } + } else { + // unused case, (only called once with animIndex = 2) + AnimationHeader* animationPtr = gYbUnusedAnimations[animIndex]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/func_80BFB0E0.s") + if (1) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Yb/EnYb_Draw.s") + Animation_Change(&this->skelAnime, gYbUnusedAnimations[animIndex], 1.0f, 0.0f, + Animation_GetLastFrame(animationPtr), animMode, transitionRate); + } + this->currentAnimIndex = animIndex; + } + } +} + +s32 EnYb_CanTalk(EnYb* this, GlobalContext* globalCtx) { + if (this->actor.xzDistToPlayer < 100.0f && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x3000)) { + return true; + } else { + return false; + } +} + +void EnYb_UpdateAnimation(EnYb* this, GlobalContext* globalCtx) { + if (this->currentAnimIndex <= 0) { + SkelAnime_Update(&this->skelAnime); + } else { + LinkAnimation_Update(globalCtx, &this->skelAnime); + } +} + +void EnYb_FinishTeachingCutscene(EnYb* this) { + if (this->cutsceneIndex != -1) { + if (ActorCutscene_GetCurrentIndex() == this->cutscenes[this->cutsceneIndex]) { + ActorCutscene_Stop(this->cutscenes[this->cutsceneIndex]); + } + this->cutsceneIndex = -1; + } +} + +void EnYb_ChangeCutscene(EnYb* this, s16 cutsceneId) { + EnYb_FinishTeachingCutscene(this); + this->cutsceneIndex = cutsceneId; +} + +/** + * Sets a flag that enables the Kamaro dancing proximity music at night. + */ +void EnYb_EnableProximityMusic(EnYb* this) { + func_800B9084(&this->actor); +} + +void EnYb_Disappear(EnYb* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp60; + s32 i; + + EnYb_UpdateAnimation(this, globalCtx); + for (i = 3; i >= 0; i--) { + sp60.x = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.x; + sp60.z = randPlusMinusPoint5Scaled(60.0f) + this->actor.world.pos.z; + sp60.y = randPlusMinusPoint5Scaled(50.0f) + (this->actor.world.pos.y + 20.0f); + func_800B3030(globalCtx, &sp60, &D_80BFB2E8, &D_80BFB2E8, 100, 0, 2); + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EN_EXTINCT); + if (this->alpha > 10) { + this->alpha -= 10; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnYb_SetupLeaving(EnYb* this, GlobalContext* globalCtx) { + EnYb_UpdateAnimation(this, globalCtx); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + this->actionFunc = EnYb_Talk; + // I am counting on you + Message_StartTextbox(globalCtx, 0x147D, &this->actor); + func_80BFA2FC(globalCtx); + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } + EnYb_EnableProximityMusic(this); +} + +void EnYb_ReceiveMask(EnYb* this, GlobalContext* globalCtx) { + EnYb_UpdateAnimation(this, globalCtx); + // Player is parent: receiving the Kamaro mask + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = EnYb_SetupLeaving; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_MASK_KAMARO, 10000.0f, 100.0f); + } + EnYb_EnableProximityMusic(this); +} + +void EnYb_Talk(EnYb* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + EnYb_UpdateAnimation(this, globalCtx); + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x147D: // I am counting on you + func_801477B4(globalCtx); + this->actionFunc = EnYb_Disappear; + gSaveContext.save.weekEventReg[82] |= 0x4; + break; + case 0x147C: // Spread my dance across the world + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAMARO) { + func_801477B4(globalCtx); + this->actionFunc = EnYb_Idle; + + } else if (INV_CONTENT(ITEM_MASK_KAMARO) == ITEM_MASK_KAMARO) { + func_80151938(globalCtx, 0x147D); // I am counting on you + func_80BFA2FC(globalCtx); + + } else { + func_801477B4(globalCtx); + this->actionFunc = EnYb_ReceiveMask; + EnYb_ReceiveMask(this, globalCtx); + } + break; + default: + func_801477B4(globalCtx); + this->actionFunc = EnYb_Idle; + break; + } + } + EnYb_EnableProximityMusic(this); +} + +void EnYb_TeachingDanceFinish(EnYb* this, GlobalContext* globalCtx) { + EnYb_UpdateAnimation(this, globalCtx); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = EnYb_Talk; + // Spread my dance across the world + Message_StartTextbox(globalCtx, 0x147C, &this->actor); + this->actor.flags &= ~ACTOR_FLAG_10000; + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } + EnYb_EnableProximityMusic(this); +} + +// dancing countdown +void EnYb_TeachingDance(EnYb* this, GlobalContext* globalCtx) { + EnYb_UpdateAnimation(this, globalCtx); + + if (this->teachingCutsceneTimer > 0) { + this->teachingCutsceneTimer--; + } else { + EnYb_FinishTeachingCutscene(this); + this->actionFunc = EnYb_TeachingDanceFinish; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } + EnYb_EnableProximityMusic(this); +} + +void EnYb_Idle(EnYb* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + EnYb_UpdateAnimation(this, globalCtx); + if (this->actor.xzDistToPlayer < 180.0f && fabsf(this->actor.playerHeightRel) < 50.0f && + globalCtx->msgCtx.ocarinaMode == 3 && globalCtx->msgCtx.unk1202E == 7 && + gSaveContext.save.playerForm == PLAYER_FORM_HUMAN) { + this->actionFunc = EnYb_TeachingDance; + this->teachingCutsceneTimer = 200; + EnYb_ChangeCutscene(this, 0); + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + func_80BFA2FC(globalCtx); + this->actionFunc = EnYb_Talk; + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAMARO) { + // I have taught you, go use it + Message_StartTextbox(globalCtx, 0x147C, &this->actor); + } else { + // regular talk to him first dialogue + Message_StartTextbox(globalCtx, 0x147B, &this->actor); + } + } else if (EnYb_CanTalk(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + + if (this->playerOcarinaOut & 1) { + if (!(player->stateFlags2 & 0x8000000)) { + this->playerOcarinaOut &= ~1; + } + } else if ((player->stateFlags2 & 0x8000000) && this->actor.xzDistToPlayer < 180.0f && + fabsf(this->actor.playerHeightRel) < 50.0f) { + this->playerOcarinaOut |= 1; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + } + + EnYb_EnableProximityMusic(this); +} + +void EnYb_WaitForMidnight(EnYb* this, GlobalContext* globalCtx) { + if (gSaveContext.save.time < CLOCK_TIME(6, 0)) { + EnYb_UpdateAnimation(this, globalCtx); + this->alpha += 5; + if (this->alpha > 250) { + this->alpha = 255; + this->actor.flags |= ACTOR_FLAG_1; + this->actionFunc = EnYb_Idle; + } + EnYb_EnableProximityMusic(this); + } +} + +void EnYb_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnYb* this = THIS; + + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_1)) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + if (CHECK_FLAG_ALL(this->actor.flags, ACTOR_FLAG_1)) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 25.0f, 40.0f, 5); + } + + this->actionFunc(this, globalCtx); + + if (this->cutsceneIndex != -1 && ActorCutscene_GetCurrentIndex() != this->cutscenes[this->cutsceneIndex]) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->cutscenes[this->cutsceneIndex]); + } else if (ActorCutscene_GetCanPlayNext(this->cutscenes[this->cutsceneIndex])) { + if (this->cutsceneIndex == 0) { + ActorCutscene_StartAndSetUnkLinkFields(this->cutscenes[this->cutsceneIndex], &this->actor); + } + } else { + ActorCutscene_SetIntentToPlay(this->cutscenes[this->cutsceneIndex]); + } + } +} + +void EnYb_PostLimbDrawOpa(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnYb* this = THIS; + + if (limbIndex == YB_LIMB_HEAD) { + Matrix_MultVec3f(&D_80BFB2F4, &this->actor.focus.pos); + } + if (limbIndex == YB_LIMB_LEGS_ROOT) { + Matrix_MultVec3f(&gZeroVec3f, &this->shadowPos); + } +} + +void EnYb_PostLimbDrawXlu(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnYb* this = THIS; + + if (limbIndex == YB_LIMB_HEAD) { + Matrix_MultVec3f(&D_80BFB300, &this->actor.focus.pos); + } + if (limbIndex == YB_LIMB_LEGS_ROOT) { + Matrix_MultVec3f(&gZeroVec3f, &this->shadowPos); + } +} + +void EnYb_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnYb* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->alpha != 0) { + if (this->alpha < 255) { + if (this->alpha > 128) { + func_8012C2B4(POLY_XLU_DISP++); + Scene_SetRenderModeXlu(globalCtx, 2, 2); + } else { + func_8012C304(POLY_XLU_DISP++); + Scene_SetRenderModeXlu(globalCtx, 1, 2); + } + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->alpha); + + if (1) {} + + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnYb_PostLimbDrawXlu, &this->actor, POLY_XLU_DISP); + + } else { + func_8012C28C(globalCtx->state.gfxCtx); + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, EnYb_PostLimbDrawOpa, &this->actor); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Yb/z_en_yb.h b/src/overlays/actors/ovl_En_Yb/z_en_yb.h index ca8a59d93..1b4c898a2 100644 --- a/src/overlays/actors/ovl_En_Yb/z_en_yb.h +++ b/src/overlays/actors/ovl_En_Yb/z_en_yb.h @@ -2,17 +2,28 @@ #define Z_EN_YB_H #include "global.h" +#include "objects/object_yb/object_yb.h" struct EnYb; typedef void (*EnYbActionFunc)(struct EnYb*, GlobalContext*); typedef struct EnYb { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x2DC]; - /* 0x0420 */ EnYbActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[YB_LIMB_MAX]; + /* 0x20C */ UNK_TYPE1 unkPadding20C[0x94]; + /* 0x2A0 */ Vec3s morphTable[YB_LIMB_MAX]; + /* 0x324 */ UNK_TYPE1 unkPadding324[0x94]; + /* 0x3B8 */ ColliderCylinder collider; + /* 0x404 */ Vec3f shadowPos; + /* 0x410 */ u16 playerOcarinaOut; + /* 0x412 */ s16 currentAnimIndex; + /* 0x414 */ s16 alpha; + /* 0x416 */ s16 cutscenes[2]; + /* 0x41A */ s16 cutsceneIndex; + /* 0x41C */ s16 teachingCutsceneTimer; + /* 0x420 */ EnYbActionFunc actionFunc; } EnYb; // size = 0x424 -extern const ActorInit En_Yb_InitVars; - #endif // Z_EN_YB_H diff --git a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c index b029e220a..004907003 100644 --- a/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c +++ b/src/overlays/actors/ovl_En_Zl1/z_en_zl1.c @@ -1,6 +1,12 @@ +/* + * File: z_en_zl1.c + * Overlay: ovl_En_Zl1 + * Description: [Empty] + */ + #include "z_en_zl1.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnZl1*)thisx) 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 cef6afd3d..731af3772 100644 --- a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -1,6 +1,12 @@ +/* + * File: z_en_zl4.c + * Overlay: ovl_En_Zl4 + * Description: Glitched early version of Skull Kid stuck in a T-pose + */ + #include "z_en_zl4.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((EnZl4*)thisx) diff --git a/src/overlays/actors/ovl_En_Zo/z_en_zo.c b/src/overlays/actors/ovl_En_Zo/z_en_zo.c index 575bf65de..2c5f76f2e 100644 --- a/src/overlays/actors/ovl_En_Zo/z_en_zo.c +++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.c @@ -1,6 +1,13 @@ -#include "z_en_zo.h" +/* + * File: z_en_zo.c + * Overlay: ovl_En_Zo + * Description: Zoras (unused) + */ -#define FLAGS 0x00000019 +#include "z_en_zo.h" +#include "objects/object_zo/object_zo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnZo*)thisx) @@ -9,12 +16,10 @@ void EnZo_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZo_Update(Actor* thisx, GlobalContext* globalCtx); void EnZo_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8099EBD8(EnZo* this, GlobalContext* globalCtx); -void func_8099EC50(EnZo* this, GlobalContext* globalCtx); -void func_8099ED4C(EnZo* this, GlobalContext* globalCtx); -void func_8099EE24(EnZo* this, GlobalContext* globalCtx); +void EnZo_FollowPath(EnZo* this, GlobalContext* globalCtx); +void EnZo_TreadWater(EnZo* this, GlobalContext* globalCtx); +void EnZo_DoNothing(EnZo* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Zo_InitVars = { ACTOR_EN_ZO, ACTORCAT_NPC, @@ -27,86 +32,342 @@ const ActorInit En_Zo_InitVars = { (ActorFunc)EnZo_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8099F4B0 = { - { COLTYPE_HIT0, 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 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 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 64, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_8099F4DC = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_8099F4E8 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(0, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(0, 0x0), - /* Zora boomerang */ DMG_ENTRY(0, 0x0), - /* Normal arrow */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0x0), - /* Goron punch */ DMG_ENTRY(0, 0x0), - /* Sword */ DMG_ENTRY(0, 0x0), - /* Goron pound */ DMG_ENTRY(0, 0x0), - /* Fire arrow */ DMG_ENTRY(0, 0x0), - /* Ice arrow */ DMG_ENTRY(0, 0x0), - /* Light arrow */ DMG_ENTRY(0, 0x0), - /* Goron spikes */ DMG_ENTRY(0, 0x0), - /* Deku spin */ DMG_ENTRY(0, 0x0), - /* Deku bubble */ DMG_ENTRY(0, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(0, 0x0), - /* Zora punch */ DMG_ENTRY(0, 0x0), - /* Spin attack */ DMG_ENTRY(0, 0x0), - /* 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(0, 0x0), +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, 0), + /* Deku Stick */ DMG_ENTRY(0, 0), + /* Horse trample */ DMG_ENTRY(0, 0), + /* Explosives */ DMG_ENTRY(0, 0), + /* Zora boomerang */ DMG_ENTRY(0, 0), + /* Normal arrow */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0), + /* Hookshot */ DMG_ENTRY(0, 0), + /* Goron punch */ DMG_ENTRY(0, 0), + /* Sword */ DMG_ENTRY(0, 0), + /* Goron pound */ DMG_ENTRY(0, 0), + /* Fire arrow */ DMG_ENTRY(0, 0), + /* Ice arrow */ DMG_ENTRY(0, 0), + /* Light arrow */ DMG_ENTRY(0, 0), + /* Goron spikes */ DMG_ENTRY(0, 0), + /* Deku spin */ DMG_ENTRY(0, 0), + /* Deku bubble */ DMG_ENTRY(0, 0), + /* Deku launch */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0), + /* Zora barrier */ DMG_ENTRY(0, 0), + /* Normal shield */ DMG_ENTRY(0, 0), + /* Light ray */ DMG_ENTRY(0, 0), + /* Thrown object */ DMG_ENTRY(0, 0), + /* Zora punch */ DMG_ENTRY(0, 0), + /* Spin attack */ DMG_ENTRY(0, 0), + /* Sword beam */ DMG_ENTRY(0, 0), + /* Normal Roll */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0), + /* Unblockable */ DMG_ENTRY(0, 0), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0), + /* Powder Keg */ DMG_ENTRY(0, 0), }; -#endif +static AnimationInfoS sAnimations[] = { + { &gZoraIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, 0 }, + { &gZoraIdleAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gZoraSurfacingAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gZoraHandsOnHipsTappingFootAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gZoraArmsOpenAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gZoraThrowRupeeAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, + { &gZoraWalkAnim, 1.0f, 0, -1, ANIMMODE_LOOP, -4 }, +}; -extern ColliderCylinderInit D_8099F4B0; -extern CollisionCheckInfoInit2 D_8099F4DC; -extern DamageTable D_8099F4E8; +s8 sBodyParts[] = { -1, 1, 12, 13, 14, 9, 10, 11, 0, 6, 7, 8, 3, 4, 5, 2, -1, -1, -1, -1 }; +s8 sParentBodyParts[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13 }; +u8 sShadowSizes[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -extern UNK_TYPE D_0600D208; +s32 EnZo_SetAnimation(SkelAnime* skelAnime, s16 index) { + s16 frameCount; + s32 didChange = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099E790.s") + if ((index >= 0) && (index < ARRAY_COUNT(sAnimations))) { + didChange = true; + frameCount = sAnimations[index].frameCount; + if (frameCount < 0) { + frameCount = Animation_GetLastFrame(sAnimations[index].animation); + } + Animation_Change(skelAnime, sAnimations[index].animation, sAnimations[index].playSpeed, + sAnimations[index].startFrame, frameCount, sAnimations[index].mode, + sAnimations[index].morphFrames); + } + return didChange; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099E858.s") +s32 EnZo_PlayWalkingSound(EnZo* this, GlobalContext* globalCtx) { + u8 leftWasGrounded; + u8 rightWasGrounded; + s32 waterSfxId; + u16 sfxId; + u8 isFootGrounded; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099E96C.s") + leftWasGrounded = this->isLeftFootGrounded; + rightWasGrounded = this->isRightFootGrounded; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099E9E0.s") + if (this->actor.bgCheckFlags & 0x20) { + if (this->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, this->actor.floorPoly, this->actor.floorBgId) + SFX_FLAG; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099EA60.s") + this->isLeftFootGrounded = isFootGrounded = SubS_IsFloorAbove(globalCtx, &this->leftFootPos, -6.0f); + if ((this->isLeftFootGrounded) && (!leftWasGrounded) && (isFootGrounded)) { + Actor_PlaySfxAtPos(&this->actor, sfxId); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099EBD8.s") + this->isRightFootGrounded = isFootGrounded = SubS_IsFloorAbove(globalCtx, &this->rightFootPos, -6.0f); + if ((this->isRightFootGrounded) && (!rightWasGrounded) && (isFootGrounded)) { + Actor_PlaySfxAtPos(&this->actor, sfxId); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099EC50.s") + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099ED4C.s") +void EnZo_Blink(EnZo* this, s32 maxEyeIndex) { + if (DECR(this->blinkTimer) == 0) { + this->eyeIndex++; + if (this->eyeIndex >= maxEyeIndex) { + this->eyeIndex = 0; + this->blinkTimer = Rand_S16Offset(30, 30); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099EE24.s") +void EnZo_UpdateCollider(EnZo* 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/EnZo_Init.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_En_Zo/EnZo_Destroy.s") +void EnZo_LookAtPlayer(EnZo* this, GlobalContext* globalCtx) { + static TurnOptionsSet sTurnOptions = { + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + { 0xFA0, 4, 1, 3 }, + { 0x1770, 4, 1, 6 }, + }; + Player* player = GET_PLAYER(globalCtx); + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/EnZo_Update.s") + SkelAnime_Update(&this->skelAnime); + if (SubS_AngleDiffLessEqual(this->actor.shape.rot.y, 0x2710, this->actor.yawTowardsPlayer)) { + point.x = player->actor.world.pos.x; + point.y = player->bodyPartsPos[7].y + 3.0f; + point.z = player->actor.world.pos.z; + SubS_TurnToPoint(&point, &this->actor.focus.pos, &this->actor.shape.rot, &this->turnTarget, &this->headRot, + &this->upperBodyRot, &sTurnOptions); + } else { + Math_SmoothStepToS(&this->turnTarget.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->turnTarget.y, 0, 4, 1000, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099EFF4.s") + Math_SmoothStepToS(&this->headRot.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->headRot.y, 0, 4, 1000, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/func_8099F15C.s") + Math_SmoothStepToS(&this->upperBodyRot.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->upperBodyRot.y, 0, 4, 1000, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zo/EnZo_Draw.s") + EnZo_Blink(this, 3); + SubS_FillLimbRotTables(globalCtx, this->limbRotY, this->limbRotZ, 20); +} + +void EnZo_Walk(EnZo* this, GlobalContext* globalCtx) { + if (ENZO_GET_PATH(&this->actor) != ENZO_NO_PATH) { + EnZo_SetAnimation(&this->skelAnime, 6); + } + + if (ENZO_GET_PATH(&this->actor) != ENZO_NO_PATH) { + this->actionFunc = EnZo_FollowPath; + } else { + this->actionFunc = EnZo_DoNothing; + } +} + +void EnZo_FollowPath(EnZo* this, GlobalContext* globalCtx) { + s16 speed; + Vec3f pos; + + Math_SmoothStepToF(&this->actor.speedXZ, 1.0f, 0.4f, 1000.0f, 0.0f); + speed = this->actor.speedXZ * 400.0f; + if (SubS_CopyPointFromPath(this->path, this->waypoint, &pos) && SubS_MoveActorToPoint(&this->actor, &pos, speed)) { + this->waypoint++; + if (this->waypoint >= this->path->count) { + this->waypoint = 0; + } + } + + if (this->actor.depthInWater > 60.0f) { + EnZo_SetAnimation(&this->skelAnime, 1); + this->actionFunc = EnZo_TreadWater; + this->actor.gravity = 0.0f; + this->actor.speedXZ = 0.0f; + } +} + +void EnZo_TreadWater(EnZo* this, GlobalContext* globalCtx) { + f32 targetYVel; + + if (this->actor.depthInWater < (sREG(0) + 50.0f)) { + targetYVel = -1.0f; + } else { + targetYVel = 1.0f; + } + Math_ApproachF(&this->actor.velocity.y, targetYVel, (sREG(1) + 18.0f) * 0.01f, (sREG(2) + 12.0f) * 0.01f); +} + +void EnZo_DoNothing(EnZo* this, GlobalContext* globalCtx) { +} + +void EnZo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnZo* this = THIS; + s32 pad; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gZoraSkel, NULL, this->jointTable, this->morphTable, 20); + EnZo_SetAnimation(&this->skelAnime, 0); + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + this->path = SubS_GetPathByIndex(globalCtx, ENZO_GET_PATH(&this->actor), ENZO_NO_PATH); + Actor_SetScale(&this->actor, 0.01f); + + this->actionFunc = EnZo_Walk; + this->actor.gravity = -4.0f; +} + +void EnZo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZo* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnZo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnZo* this = THIS; + + this->actionFunc(this, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + EnZo_LookAtPlayer(this, globalCtx); + EnZo_PlayWalkingSound(this, globalCtx); + EnZo_UpdateCollider(this, globalCtx); +} + +s32 EnZo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnZo* this = THIS; + + if (limbIndex == 15) { + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->headRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->headRot.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == 8) { + Matrix_RotateXS(-this->upperBodyRot.y, MTXMODE_APPLY); + Matrix_RotateZS(-this->upperBodyRot.x, MTXMODE_APPLY); + } + + if ((limbIndex == 8) || (limbIndex == 9) || (limbIndex == 12)) { + rot->y += (s16)(Math_SinS(this->limbRotY[limbIndex]) * 200.0f); + rot->z += (s16)(Math_CosS(this->limbRotZ[limbIndex]) * 200.0f); + } + return false; +} + +void EnZo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnZo* this = THIS; + Vec3f sp30 = { 400.0f, 0.0f, 0.0f }; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + + if (sBodyParts[limbIndex] >= 0) { + Matrix_MultVec3f(&zeroVec, &this->bodyPartsPos[sBodyParts[limbIndex]]); + } + if (limbIndex == 15) { + Matrix_MultVec3f(&sp30, &this->actor.focus.pos); + } + if (limbIndex == 4) { + Matrix_MultVec3f(&zeroVec, &this->leftFootPos); + } + if (limbIndex == 7) { + Matrix_MultVec3f(&zeroVec, &this->rightFootPos); + } +} + +static Gfx sTransparencyDlist[] = { + gsDPSetRenderMode(AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + G_RM_FOG_SHADE_A, + AA_EN | Z_CMP | Z_UPD | IM_RD | CLR_ON_CVG | CVG_DST_WRAP | ZMODE_XLU | FORCE_BL | + GBL_c2(G_BL_CLR_IN, G_BL_A_IN, G_BL_CLR_MEM, G_BL_1MA)), + gsDPSetAlphaCompare(G_AC_THRESHOLD), + gsSPEndDisplayList(), +}; + +void EnZo_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnZo* this = THIS; + s32 i; + u8* shadowTex = GRAPH_ALLOC(globalCtx->state.gfxCtx, SUBS_SHADOW_TEX_SIZE); + u8* shadowTexIter; + TexturePtr eyeTextures[] = { gZoraEyeOpenTex, gZoraEyeHalfTex, gZoraEyeClosedTex }; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + gDPPipeSync(POLY_OPA_DISP++); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(eyeTextures[this->eyeIndex])); + gSPSegment(POLY_OPA_DISP++, 0x0C, &sTransparencyDlist[2]); + + POLY_OPA_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnZo_OverrideLimbDraw, EnZo_PostLimbDraw, &this->actor, POLY_OPA_DISP); + Matrix_RotateXS(0, MTXMODE_NEW); + + for (i = 0, shadowTexIter = shadowTex; i < SUBS_SHADOW_TEX_SIZE; i++) { + *shadowTexIter = 0; + shadowTexIter++; + } + for (i = 0; i < 5; i++) { + SubS_GenShadowTex(this->bodyPartsPos, &this->actor.world.pos, shadowTex, i / 5.0f, + ARRAY_COUNT(this->bodyPartsPos), sShadowSizes, sParentBodyParts); + } + + SubS_DrawShadowTex(&this->actor, &globalCtx->state, shadowTex); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..b5faef776 100644 --- a/src/overlays/actors/ovl_En_Zo/z_en_zo.h +++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.h @@ -7,12 +7,33 @@ struct EnZo; typedef void (*EnZoActionFunc)(struct EnZo*, GlobalContext*); +#define ENZO_GET_PATH(thisx) (((thisx)->params & 0x7E00) >> 9) +#define ENZO_NO_PATH 0x3F + typedef struct EnZo { /* 0x0000 */ Actor actor; /* 0x0144 */ EnZoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2DC]; + /* 0x0148 */ SkelAnime skelAnime; + /* 0x0194 */ ColliderCylinder collider; + /* 0x01D8 */ UNK_TYPE1 unk_1D8[0x4]; + /* 0x01DC */ Path* path; + /* 0x01E0 */ s16 waypoint; + /* 0x01E4 */ Vec3f leftFootPos; + /* 0x01F0 */ Vec3f rightFootPos; + /* 0x01FC */ u8 isLeftFootGrounded; + /* 0x01FD */ u8 isRightFootGrounded; + /* 0x01FE */ Vec3s jointTable[20]; + /* 0x0276 */ Vec3s morphTable[20]; + /* 0x02EE */ Vec3s turnTarget; + /* 0x02F4 */ Vec3s headRot; + /* 0x02FA */ Vec3s upperBodyRot; + /* 0x0300 */ UNK_TYPE1 unk_300[0x12]; + /* 0x0312 */ s16 limbRotY[20]; + /* 0x033A */ s16 limbRotZ[20]; + /* 0x0364 */ Vec3f bodyPartsPos[15]; + /* 0x041A */ UNK_TYPE1 unk_41A[0x6]; + /* 0x041E */ s16 eyeIndex; + /* 0x0420 */ s16 blinkTimer; } EnZo; // size = 0x424 -extern const ActorInit En_Zo_InitVars; - #endif // Z_EN_ZO_H diff --git a/src/overlays/actors/ovl_En_Zob/z_en_zob.c b/src/overlays/actors/ovl_En_Zob/z_en_zob.c index 272250134..24b03ab5f 100644 --- a/src/overlays/actors/ovl_En_Zob/z_en_zob.c +++ b/src/overlays/actors/ovl_En_Zob/z_en_zob.c @@ -1,6 +1,13 @@ -#include "z_en_zob.h" +/* + * File: z_en_zob.c + * Overlay: ovl_En_Zob + * Description: Zora Bassist Japas + */ -#define FLAGS 0x00000009 +#include "z_en_zob.h" +#include "objects/object_zob/object_zob.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnZob*)thisx) @@ -9,10 +16,13 @@ void EnZob_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZob_Update(Actor* thisx, GlobalContext* globalCtx); void EnZob_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B9F7E4(EnZob* this, s16 arg1, u8 arg2); void func_80B9FD24(EnZob* this, GlobalContext* globalCtx); void func_80B9FDDC(EnZob* this, GlobalContext* globalCtx); void func_80B9FE1C(EnZob* this, GlobalContext* globalCtx); +void func_80B9FE5C(EnZob* this, GlobalContext* globalCtx); void func_80B9FF20(EnZob* this, GlobalContext* globalCtx); +void func_80B9FF80(EnZob* this, GlobalContext* globalCtx); void func_80BA005C(EnZob* this, GlobalContext* globalCtx); void func_80BA00BC(EnZob* this, GlobalContext* globalCtx); void func_80BA0318(EnZob* this, GlobalContext* globalCtx); @@ -27,7 +37,6 @@ void func_80BA0BB4(EnZob* this, GlobalContext* globalCtx); void func_80BA0C14(EnZob* this, GlobalContext* globalCtx); void func_80BA0CF4(EnZob* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Zob_InitVars = { ACTOR_EN_ZOB, ACTORCAT_NPC, @@ -40,79 +49,727 @@ const ActorInit En_Zob_InitVars = { (ActorFunc)EnZob_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BA10D0 = { - { 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 +static AnimationHeader* sAnimations[] = { + &object_zob_Anim_0027D0, &object_zob_Anim_002B38, &object_zob_Anim_0037A0, + &object_zob_Anim_0043C4, &object_zob_Anim_005224, &object_zob_Anim_005E90, + &object_zob_Anim_006998, &object_zob_Anim_011144, &object_zob_Anim_001FD4, +}; -extern ColliderCylinderInit D_80BA10D0; +Vec3f D_80BA1120 = { 300.0f, 900.0f, 0.0f }; -extern UNK_TYPE D_06006998; +void EnZob_Init(Actor* thisx, GlobalContext* globalCtx) { + EnZob* this = THIS; + s32 i; + s16 cs; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/EnZob_Init.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.0115f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zob_Skel_010810, &object_zob_Anim_006998, this->jointTable, + this->morphTable, 24); + Animation_PlayLoop(&this->skelAnime, &object_zob_Anim_006998); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_2F4 = 0; + this->unk_30E = -1; + this->unk_310 = 0; + this->unk_302 = 9; + this->unk_304 = 0; + this->actor.terminalVelocity = -4.0f; + this->actor.gravity = -4.0f; + func_80B9F7E4(this, 6, 2); + this->actionFunc = func_80BA0728; + this->actor.textId = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/EnZob_Destroy.s") + cs = this->actor.cutscene; + for (i = 0; i < ARRAY_COUNT(this->unk_306); i++) { + this->unk_306[i] = cs; + if (cs != -1) { + this->actor.cutscene = cs; + cs = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9F7E4.s") + this->actor.cutscene = this->unk_306[0]; + this->actor.flags |= ACTOR_FLAG_2000000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9F86C.s") + switch (ENZOB_GET_F(&this->actor)) { + case ENZOB_F_1: + if (gSaveContext.save.weekEventReg[78] & 1) { + this->actionFunc = func_80BA0BB4; + } else { + this->actionFunc = func_80BA0AD8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FA3C.s") + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FC0C.s") + case ENZOB_F_2: + this->actionFunc = func_80BA0CF4; + this->unk_2F4 |= 0x20; + this->unk_312 = -1; + func_80B9F7E4(this, 0, 2); + this->unk_304 = 5; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FC70.s") + default: + if (gSaveContext.save.weekEventReg[55] & 0x80) { + Actor_MarkForDeath(&this->actor); + } + this->actor.flags |= ACTOR_FLAG_10; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FCA0.s") +void EnZob_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZob* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FD24.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FDDC.s") +void func_80B9F7E4(EnZob* this, s16 arg1, u8 arg2) { + Animation_Change(&this->skelAnime, sAnimations[arg1], 1.0f, 0.0f, Animation_GetLastFrame(sAnimations[arg1]), arg2, + -5.0f); + this->unk_302 = arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FE1C.s") +void func_80B9F86C(EnZob* this) { + if (SkelAnime_Update(&this->skelAnime)) { + switch (this->unk_304) { + case 0: + if (Rand_ZeroFloat(1.0f) > 0.7f) { + if (this->unk_302 == 6) { + func_80B9F7E4(this, 7, 2); + } else { + func_80B9F7E4(this, 6, 2); + } + } else { + func_80B9F7E4(this, this->unk_302, 2); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FE5C.s") + case 1: + func_80B9F7E4(this, 3, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FF20.s") + case 2: + func_80B9F7E4(this, 4, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80B9FF80.s") + case 3: + func_80B9F7E4(this, 5, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA005C.s") + case 4: + if (this->unk_302 == 3) { + func_80B9F7E4(this, 0, 0); + } else { + func_80B9F7E4(this, 3, 2); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA00BC.s") + case 5: + if (Rand_ZeroFloat(1.0f) < 0.8f) { + func_80B9F7E4(this, this->unk_302, 2); + } else if (this->unk_302 == 0) { + func_80B9F7E4(this, 1, 2); + } else { + func_80B9F7E4(this, 0, 2); + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0318.s") + SkelAnime_Update(&this->skelAnime); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0374.s") +void func_80B9FA3C(EnZob* this, GlobalContext* globalCtx) { + u16 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0610.s") + this->unk_2F4 |= 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA06BC.s") + if (gSaveContext.save.playerForm != PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[30] & 2) { + textId = 0x11F9; + } else { + textId = 0x11F8; + } + this->unk_304 = 3; + func_80B9F7E4(this, 5, 0); + } else if (this->unk_2F4 & 0x10) { + textId = 0x1210; + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + } else if (gSaveContext.save.weekEventReg[31] & 8) { + textId = 0x1205; + this->unk_304 = 1; + func_80B9F7E4(this, 3, 0); + } else if (this->unk_2F4 & 8) { + textId = 0x1215; + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + } else if (this->unk_2F4 & 2) { + textId = 0x1203; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + } else if (gSaveContext.save.weekEventReg[30] & 8) { + textId = 0x11FA; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + } else if (!(gSaveContext.save.weekEventReg[30] & 4)) { + gSaveContext.save.weekEventReg[30] |= 4; + textId = 0x11FB; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + } else { + textId = 0x1201; + this->unk_304 = 3; + func_80B9F7E4(this, 4, 2); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0728.s") + Message_StartTextbox(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA08E8.s") +void func_80B9FC0C(EnZob* this) { + if (this->unk_30E != -1) { + if (ActorCutscene_GetCurrentIndex() == this->unk_306[this->unk_30E]) { + ActorCutscene_Stop(this->unk_306[this->unk_30E]); + } + this->unk_30E = -1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA09E0.s") +void func_80B9FC70(EnZob* this, s16 arg1) { + func_80B9FC0C(this); + this->unk_30E = arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0A04.s") +void func_80B9FCA0(EnZob* this, GlobalContext* globalCtx) { + func_801477B4(globalCtx); + globalCtx->msgCtx.ocarinaMode = 4; + func_80B9FC0C(this); + this->unk_2F4 &= ~1; + this->actionFunc = func_80BA0728; + this->unk_304 = 0; + func_80B9F7E4(this, 6, 2); + func_800B8718(&this->actor, &globalCtx->state); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0AD8.s") +void func_80B9FD24(EnZob* this, GlobalContext* globalCtx) { + s32 actionIndex; + s16 action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0BB4.s") + func_80B9F86C(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0C14.s") + if (Cutscene_CheckActorAction(globalCtx, 500)) { + this->unk_30E = -1; + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 500); + action = globalCtx->csCtx.actorActions[actionIndex]->action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0CF4.s") + if (action != this->unk_310) { + this->unk_310 = action; + switch (action) { + case 1: + func_80B9F7E4(this, 8, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/EnZob_Update.s") + case 2: + func_80B9F7E4(this, 7, 0); + break; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0F64.s") +void func_80B9FDDC(EnZob* this, GlobalContext* globalCtx) { + Message_StartTextbox(globalCtx, 0x120C, &this->actor); + this->actionFunc = func_80BA00BC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/func_80BA0FAC.s") +void func_80B9FE1C(EnZob* this, GlobalContext* globalCtx) { + Message_StartTextbox(globalCtx, 0x1211, &this->actor); + this->actionFunc = func_80BA00BC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zob/EnZob_Draw.s") +void func_80B9FE5C(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (globalCtx->msgCtx.ocarinaMode == 3) { + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80B9FDDC; + func_80B9FC70(this, 0); + } else if (Message_GetState(&globalCtx->msgCtx) == 11) { + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80B9FE1C; + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + func_80B9FC70(this, 0); + } +} + +void func_80B9FF20(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (Message_GetState(&globalCtx->msgCtx) == 7) { + func_80152434(globalCtx, 0x42); + this->actionFunc = func_80B9FE5C; + func_80B9FC70(this, 2); + } +} + +void func_80B9FF80(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (globalCtx->msgCtx.ocarinaMode == 3) { + this->actionFunc = func_80B9FF20; + this->unk_304 = 6; + func_80B9F7E4(this, 1, 0); + func_80152434(globalCtx, 0x3E); + func_80B9FC70(this, 1); + } else if (Message_GetState(&globalCtx->msgCtx) == 11) { + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80B9FE1C; + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + func_80B9FC70(this, 0); + } +} + +void func_80BA005C(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (Message_GetState(&globalCtx->msgCtx) == 7) { + func_80152434(globalCtx, 0x41); + this->actionFunc = func_80B9FF80; + func_80B9FC70(this, 2); + } +} + +void func_80BA00BC(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 4: + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.currentTextId == 0x1212)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 1: + func_8019F208(); + func_80151938(globalCtx, 0x1209); + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + break; + + case 0: + func_8019F230(); + func_80151938(globalCtx, 0x1213); + break; + } + } + break; + + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1208: + case 0x120E: + case 0x1216: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x120C: + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80B9FD24; + func_80B9F7E4(this, 8, 0); + func_80B9FC70(this, 3); + break; + + case 0x120D: + case 0x1211: + case 0x1213: + case 0x1217: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + this->unk_304 = 3; + func_80B9F7E4(this, 4, 2); + break; + + case 0x1218: + func_80B9FCA0(this, globalCtx); + break; + + case 0x1214: + this->unk_2F4 |= 8; + func_80B9FCA0(this, globalCtx); + break; + + case 0x120F: + gSaveContext.save.weekEventReg[31] |= 8; + this->unk_2F4 |= 0x10; + func_80B9FCA0(this, globalCtx); + break; + + case 0x1209: + func_80152434(globalCtx, 0x3D); + this->unk_304 = 4; + func_80B9F7E4(this, 0, 0); + this->actionFunc = func_80BA005C; + func_80B9FC70(this, 1); + break; + } + } + break; + } +} + +void func_80BA0318(EnZob* this, GlobalContext* globalCtx) { + func_80152434(globalCtx, 0x3D); + this->unk_304 = 4; + func_80B9F7E4(this, 0, 0); + this->actionFunc = func_80BA005C; + func_80B9FC70(this, 1); +} + +void func_80BA0374(EnZob* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_80B9F86C(this); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 4: + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.currentTextId == 0x1205)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + func_80151938(globalCtx, 0x1207); + func_80B9F7E4(this, 2, 2); + break; + + case 1: + func_8019F230(); + func_80151938(globalCtx, 0x1206); + break; + } + } + break; + + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x11F8: + gSaveContext.save.weekEventReg[30] |= 2; + func_80151938(globalCtx, 0x11F9); + break; + + case 0x11F9: + func_801477B4(globalCtx); + this->actionFunc = func_80BA0728; + this->unk_304 = 0; + func_80B9F7E4(this, 6, 2); + this->unk_2F4 &= ~1; + break; + + case 0x11FB: + case 0x11FC: + case 0x11FF: + case 0x1201: + case 0x1203: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x11FD: + this->unk_304 = 3; + func_80B9F7E4(this, 4, 2); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x11FE: + this->unk_304 = 1; + func_80B9F7E4(this, 3, 0); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x11FA: + case 0x1200: + case 0x1202: + case 0x1204: + case 0x1206: + case 0x120F: + case 0x1210: + case 0x1215: + func_801477B4(globalCtx); + this->actionFunc = func_80BA0728; + this->unk_304 = 0; + func_80B9F7E4(this, 6, 2); + this->unk_2F4 &= ~1; + this->unk_2F4 |= 2; + break; + + case 0x1207: + func_801477B4(globalCtx); + this->actionFunc = func_80BA0318; + player->unk_A90 = &this->actor; + player->stateFlags3 |= 0x20; + break; + } + } + break; + } +} + +void func_80BA0610(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + Message_StartTextbox(globalCtx, 0x120D, &this->actor); + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + func_80B9FC70(this, 0); + this->actionFunc = func_80BA00BC; + } else { + func_800B8614(&this->actor, globalCtx, 500.0f); + } +} + +void func_80BA06BC(EnZob* this, GlobalContext* globalCtx) { + func_80B9FD24(this, globalCtx); + if (!Cutscene_CheckActorAction(globalCtx, 500)) { + this->actionFunc = func_80BA0610; + this->actor.flags |= ACTOR_FLAG_10000; + func_80BA0610(this, globalCtx); + } +} + +void func_80BA0728(EnZob* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp28; + + func_80B9F86C(this); + + if (func_800B8718(&this->actor, &globalCtx->state)) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + Message_StartTextbox(globalCtx, 0x1208, NULL); + gSaveContext.save.weekEventReg[30] |= 8; + } else { + Message_StartTextbox(globalCtx, 0x1216, NULL); + } + this->actionFunc = func_80BA00BC; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + this->unk_30E = 0; + this->unk_2F4 |= 1; + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BA0374; + func_80B9FA3C(this, globalCtx); + } else if (Cutscene_CheckActorAction(globalCtx, 500)) { + this->actionFunc = func_80BA06BC; + } else if ((this->actor.xzDistToPlayer < 180.0f) && (this->actor.xzDistToPlayer > 60.0f) && + Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && Actor_IsFacingPlayer(&this->actor, 0x3000)) { + func_800B8614(&this->actor, globalCtx, 150.0f); + func_800B874C(&this->actor, globalCtx, 200.0f, 150.0f); + } + + sp28.x = this->actor.projectedPos.x; + sp28.y = this->actor.projectedPos.y; + sp28.z = this->actor.projectedPos.z; + func_801A1FB4(3, &sp28, 0x6C, 1000.0f); +} + +void func_80BA08E8(EnZob* this, GlobalContext* globalCtx) { + s32 textId; + + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[79] & 1) { + textId = 0x1257; + this->unk_304 = 3; + func_80B9F7E4(this, 4, 2); + } else if (gSaveContext.save.weekEventReg[78] & 0x40) { + textId = 0x1256; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + } else { + textId = 0x1255; + gSaveContext.save.weekEventReg[78] |= 0x40; + this->unk_304 = 1; + func_80B9F7E4(this, 2, 2); + } + } else { + textId = 0x1254; + this->unk_304 = 3; + func_80B9F7E4(this, 5, 2); + } + + Message_StartTextbox(globalCtx, textId, &this->actor); +} + +void func_80BA09E0(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); +} + +void func_80BA0A04(EnZob* this, GlobalContext* globalCtx) { + u8 temp_v0; + + func_80B9F86C(this); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + + temp_v0 = Message_GetState(&globalCtx->msgCtx); + if (temp_v0 != 2) { + if ((temp_v0 == 5) && Message_ShouldAdvance(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = func_80BA0AD8; + this->unk_304 = 0; + func_80B9F7E4(this, 6, 2); + } + } else { + this->actionFunc = func_80BA0AD8; + this->unk_304 = 0; + func_80B9F7E4(this, 6, 2); + } +} + +void func_80BA0AD8(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + + if (this->actor.home.rot.y != this->actor.shape.rot.y) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BA0A04; + func_80BA08E8(this, globalCtx); + } else if ((this->actor.xzDistToPlayer < 120.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x3000)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80BA0BB4(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (gSaveContext.save.weekEventReg[79] & 1) { + this->actionFunc = func_80BA09E0; + func_80B9F7E4(this, 0, 2); + this->unk_304 = 5; + } +} + +void func_80BA0C14(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + + if (this->unk_312 < 799) { + this->unk_312 += 200; + } else { + this->unk_312 += 30; + } + + if (this->unk_312 > 999) { + this->unk_312 = 999; + } + + if (Cutscene_CheckActorAction(globalCtx, 515)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 515)]->action == 1) { + this->actionFunc = func_80BA0CF4; + this->unk_312 = -1; + } + } else { + this->actionFunc = func_80BA0CF4; + this->unk_312 = -1; + } +} + +void func_80BA0CF4(EnZob* this, GlobalContext* globalCtx) { + func_80B9F86C(this); + if (Cutscene_CheckActorAction(globalCtx, 515) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 515)]->action == 2)) { + this->actionFunc = func_80BA0C14; + } +} + +void EnZob_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZob* this = THIS; + + Actor_MoveWithGravity(&this->actor); + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 4); + + this->actionFunc(this, globalCtx); + + if ((this->unk_30E != -1) && (ActorCutscene_GetCurrentIndex() != this->unk_306[this->unk_30E])) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_306[this->unk_30E]); + } else if (ActorCutscene_GetCanPlayNext(this->unk_306[this->unk_30E])) { + ActorCutscene_Start(this->unk_306[this->unk_30E], &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->unk_306[this->unk_30E]); + } + } + + if (this->unk_2F4 & 1) { + func_800E9250(globalCtx, &this->actor, &this->unk_2F6, &this->unk_2FC, this->actor.focus.pos); + } else { + Math_SmoothStepToS(&this->unk_2F6.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2F6.y, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2FC.x, 0, 6, 6200, 100); + Math_SmoothStepToS(&this->unk_2FC.y, 0, 6, 6200, 100); + } +} + +s32 func_80BA0F64(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnZob* this = THIS; + + if (limbIndex == 9) { + rot->x += this->unk_2F6.y; + rot->y += this->unk_2F6.x; + } + return false; +} + +void func_80BA0FAC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnZob* this = THIS; + + if (limbIndex == 9) { + Matrix_MultVec3f(&D_80BA1120, &this->actor.focus.pos); + } +} + +void EnZob_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnZob* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_2F4 & 0x20) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 0, 0, 0, 0, this->unk_312, 1000); + } + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80BA0F64, func_80BA0FAC, &this->actor); + + if (this->unk_2F4 & 0x20) { + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Zob/z_en_zob.h b/src/overlays/actors/ovl_En_Zob/z_en_zob.h index 233842303..18834f17e 100644 --- a/src/overlays/actors/ovl_En_Zob/z_en_zob.h +++ b/src/overlays/actors/ovl_En_Zob/z_en_zob.h @@ -7,9 +7,28 @@ struct EnZob; typedef void (*EnZobActionFunc)(struct EnZob*, GlobalContext*); +#define ENZOB_GET_F(thisx) ((thisx)->params & 0xF) + +enum { + /* 1 */ ENZOB_F_1 = 1, + /* 2 */ ENZOB_F_2, +}; + typedef struct EnZob { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1D0]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ ColliderCylinder collider; + /* 0x02F4 */ u16 unk_2F4; + /* 0x02F6 */ Vec3s unk_2F6; + /* 0x02FC */ Vec3s unk_2FC; + /* 0x0302 */ s16 unk_302; + /* 0x0304 */ u16 unk_304; + /* 0x0306 */ s16 unk_306[4]; + /* 0x030E */ s16 unk_30E; + /* 0x0310 */ s16 unk_310; + /* 0x0312 */ s16 unk_312; /* 0x0314 */ EnZobActionFunc actionFunc; } EnZob; // size = 0x318 diff --git a/src/overlays/actors/ovl_En_Zod/z_en_zod.c b/src/overlays/actors/ovl_En_Zod/z_en_zod.c index 3a28b8616..f908ceafa 100644 --- a/src/overlays/actors/ovl_En_Zod/z_en_zod.c +++ b/src/overlays/actors/ovl_En_Zod/z_en_zod.c @@ -1,6 +1,12 @@ +/* + * File: z_en_zod.c + * Overlay: ovl_En_Zod + * Description: Zora Drummer Tijo + */ + #include "z_en_zod.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnZod*)thisx) 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 babf4a063..925eaeec0 100644 --- a/src/overlays/actors/ovl_En_Zog/z_en_zog.c +++ b/src/overlays/actors/ovl_En_Zog/z_en_zog.c @@ -1,6 +1,13 @@ -#include "z_en_zog.h" +/* + * File: z_en_zog.c + * Overlay: ovl_En_Zog + * Description: Mikau + */ -#define FLAGS 0x00000009 +#include "z_en_zog.h" +#include "objects/object_zog/object_zog.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnZog*)thisx) @@ -24,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, @@ -37,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); + ActorShadow_DrawCircle(&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.currentCsIndex != 2) || (gSaveContext.sceneSetupIndex != 0) || + (globalCtx->sceneNum != SCENE_30GYOSON))) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.terminalVelocity = -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 |= ACTOR_FLAG_10000; + 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.save.weekEventReg[88] & 0x10)) { + this->unk_302 = this->unk_300 = 0; + this->unk_2FC = this->unk_2FE = 3; + this->actor.flags |= ACTOR_FLAG_2000000; + this->actor.flags &= ~ACTOR_FLAG_10000; + this->unk_31C = 2; + this->unk_31E = 0; + + Animation_PlayLoop(&this->skelAnime, D_80B958DC[0]); + this->actor.textId = 0x1009; + if (gSaveContext.save.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 (Cutscene_CheckActorAction(globalCtx, 471)) { + sp3E = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 471)]->action; + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 471)); + + switch (this->unk_306) { + case 2: + if (globalCtx->csCtx.frames == 60) { + Actor_PlaySfxAtPos(&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; + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + } +} + +void func_80B94470(EnZog* this, GlobalContext* globalCtx) { + if (Message_GetState(&globalCtx->msgCtx) == 5) { + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.currentTextId == 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_300 = 2; + this->actionFunc = func_80B94470; + } else if ((globalCtx->msgCtx.ocarinaMode == 3) && (this->actor.xzDistToPlayer < 120.0f)) { + if ((globalCtx->msgCtx.unk1202E == 7) && (gSaveContext.save.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 |= ACTOR_FLAG_2000000; + gSaveContext.save.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 (Message_GetState(&globalCtx->msgCtx)) { + case 4: + if (Message_ShouldAdvance(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 (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1008: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1009: + this->unk_300 = 4; + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1014: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->unk_300 = 2; + this->actionFunc = func_80B946FC; + } else if ((globalCtx->msgCtx.ocarinaMode == 3) && (this->actor.xzDistToPlayer < 120.0f)) { + if ((globalCtx->msgCtx.unk1202E == 7) && (gSaveContext.save.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 |= ACTOR_FLAG_2000000; + if (gSaveContext.save.weekEventReg[29] & 0x20) { + this->actor.textId = 0x1009; + } else { + this->actor.textId = 0x1008; + gSaveContext.save.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))) { + Actor_PlaySfxAtPos(&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) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_PL_WALK_WATER0); + } else { + Actor_PlaySfxAtPos(&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.terminalVelocity = -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 ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + this->unk_320 = 5; + switch (globalCtx->msgCtx.currentTextId) { + case 0x1004: + case 0x1005: + case 0x1006: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 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, player->ageProperties->unk_92 + NA_SE_VO_LI_PUSH); + } + } + this->actor.speedXZ *= 0.3f; + } + + if (ABS_ALT(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0x5000) { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 60.0f, 40.0f); + } + + if (this->unk_324 > 0) { + this->unk_324--; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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.terminalVelocity = 0.0f; + this->actor.gravity = 0.0f; + this->unk_31C = 1; + this->unk_31E = 0; + func_80B93BA8(this, 0); + gSaveContext.save.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 (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + 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 &= ~ACTOR_FLAG_10000; + gSaveContext.save.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_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 5); + if (Cutscene_CheckActorAction(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))) { + Actor_PlaySfxAtPos(&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 EnZog_PostLimbDraw(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_MultVec3f(&D_80B959B8, &this->actor.focus.pos); + } + D_80B959B8.y = 0.0f; + + if (limbIndex == 1) { + Matrix_MultVec3f(&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_MultVec3f(&D_80B959C4, &this->actor.focus.pos); + } + D_80B959C4.y = 0.0f; + + if (limbIndex == 1) { + Matrix_MultVec3f(&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, EnZog_PostLimbDraw, &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_En_Zoraegg/z_en_zoraegg.c b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c index 05a99edff..b65da70e2 100644 --- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c +++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.c @@ -1,6 +1,14 @@ -#include "z_en_zoraegg.h" +/* + * File: z_en_zoraegg.c + * Overlay: ovl_En_Zoraegg + * Description: Zora Egg + */ -#define FLAGS 0x00000010 +#include "z_en_zoraegg.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_zoraegg/object_zoraegg.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((EnZoraegg*)thisx) @@ -9,7 +17,27 @@ void EnZoraegg_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZoraegg_Update(Actor* thisx, GlobalContext* globalCtx); void EnZoraegg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +s32 func_80B319A8(GlobalContext* globalCtx); +void func_80B32084(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32094(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B320E0(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B321D0(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32228(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B322BC(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32390(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B324B0(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32644(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B326F4(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32820(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32928(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32A88(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32B10(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32B3C(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32B70(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32BB8(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32C34(EnZoraegg* this, GlobalContext* globalCtx); +void func_80B32D08(EnZoraegg* this, GlobalContext* globalCtx); + const ActorInit En_Zoraegg_InitVars = { ACTOR_EN_ZORAEGG, ACTORCAT_ITEMACTION, @@ -22,86 +50,843 @@ const ActorInit En_Zoraegg_InitVars = { (ActorFunc)EnZoraegg_Draw, }; -#endif +void func_80B31590(EnZoraegg* this) { + this->actor.shape.yOffset = 0.0f; -extern UNK_TYPE D_060005D4; -extern UNK_TYPE D_06004D20; -extern UNK_TYPE D_06004FE4; -extern UNK_TYPE D_06005098; -extern UNK_TYPE D_06005250; + if (this->actor.home.rot.x == 0) { + this->actor.scale.x = 0.4f; + } else { + this->actor.scale.x = this->actor.home.rot.x * 0.04f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31590.s") + if (this->actor.home.rot.z == 0) { + this->actor.scale.z = 0.4f; + } else { + this->actor.scale.z = this->actor.home.rot.z * 0.04f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/EnZoraegg_Init.s") + this->actor.shape.rot.z = 0; + this->actor.scale.y = 0.4f; + this->actor.draw = NULL; + this->actor.shape.rot.y = this->actor.shape.rot.z; + this->actor.shape.rot.x = this->actor.shape.rot.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/EnZoraegg_Destroy.s") +void EnZoraegg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZoraegg* this = THIS; + u16 sp40[] = { 457, 458, 459, 460, 461, 462, 464 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B319A8.s") + Actor_SetScale(&this->actor, 0.006f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zoraegg_Skel_004C90, &object_zoraegg_Anim_005098, + this->jointTable, this->morphTable, 7); + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_005098); + ActorShape_Init(&this->actor.shape, 1100.0f, NULL, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B319D0.s") + this->actionFunc = func_80B32084; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31A34.s") + this->unk_1ED = 255; + this->unk_1EC = 0; + this->unk_1EA = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31C40.s") + this->unk_1E0 = 1.0f; + this->unk_1E4 = 0.0f; + this->actor.velocity.y = -10.0f; + this->actor.terminalVelocity = -10.0f; + this->actor.gravity = -5.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31CB4.s") + switch (ENZORAEGG_GET_1F(&this->actor)) { + case ENZORAEGG_1F_0: + if (Flags_GetSwitch(globalCtx, ENZORAEGG_GET_FE00(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31D14.s") + case ENZORAEGG_1F_17: + if (func_80B319A8(globalCtx) >= 7) { + Actor_MarkForDeath(&this->actor); + this->actor.home.rot.z = 1; + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31D64.s") + case ENZORAEGG_1F_3: + case ENZORAEGG_1F_4: + case ENZORAEGG_1F_5: + case ENZORAEGG_1F_6: + case ENZORAEGG_1F_7: + case ENZORAEGG_1F_8: + case ENZORAEGG_1F_9: + if (gSaveContext.save.weekEventReg[19] & 0x40) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B31E00.s") + case ENZORAEGG_1F_10: + case ENZORAEGG_1F_11: + case ENZORAEGG_1F_12: + case ENZORAEGG_1F_13: + case ENZORAEGG_1F_14: + case ENZORAEGG_1F_15: + case ENZORAEGG_1F_16: + if (!(gSaveContext.save.weekEventReg[19] & 0x40)) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32084.s") + switch (ENZORAEGG_GET_1F(&this->actor)) { + case ENZORAEGG_1F_0: + this->actionFunc = func_80B320E0; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.targetMode = 3; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32094.s") + case ENZORAEGG_1F_1: + this->actionFunc = func_80B322BC; + func_80B31590(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B320E0.s") + case ENZORAEGG_1F_2: + this->actionFunc = func_80B32390; + func_80B31590(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B321D0.s") + case ENZORAEGG_1F_3: + case ENZORAEGG_1F_4: + case ENZORAEGG_1F_5: + case ENZORAEGG_1F_6: + case ENZORAEGG_1F_7: + case ENZORAEGG_1F_8: + case ENZORAEGG_1F_9: + this->actorActionCmd = sp40[(ENZORAEGG_GET_1F(&this->actor)) - ENZORAEGG_1F_3]; + Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_001E08); + this->unk_1EC = 1; + this->unk_1EE = 0; + this->unk_1EF = 0; + this->actionFunc = func_80B32B10; + if (((ENZORAEGG_GET_1F(&this->actor)) - ENZORAEGG_1F_3) >= func_80B319A8(globalCtx)) { + this->actionFunc = func_80B32B3C; + this->actor.draw = NULL; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32228.s") + case ENZORAEGG_1F_10: + case ENZORAEGG_1F_11: + case ENZORAEGG_1F_12: + case ENZORAEGG_1F_13: + case ENZORAEGG_1F_14: + case ENZORAEGG_1F_15: + case ENZORAEGG_1F_16: + this->actorActionCmd = sp40[(ENZORAEGG_GET_1F(&this->actor)) - ENZORAEGG_1F_10]; + this->unk_1EC = 2; + this->actionFunc = func_80B324B0; + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + this->unk_1EE = 0; + this->unk_1ED = 0; + this->unk_1EA |= 3; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B322BC.s") + case ENZORAEGG_1F_17: + Actor_SetScale(&this->actor, 0.0006f); + this->actionFunc = func_80B32D08; + this->actor.world.pos.y -= this->actor.shape.yOffset * this->actor.scale.y; + this->actor.shape.rot.x = 0; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = -10.0f; + this->actor.gravity = -1.0f; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32390.s") +void EnZoraegg_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B324B0.s") +s32 func_80B319A8(GlobalContext* globalCtx) { + return gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 & 7; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32644.s") +void func_80B319D0(GlobalContext* globalCtx, s32 arg1) { + if ((arg1 < 8) && (arg1 >= 0)) { + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 &= ~7; + gSaveContext.save.permanentSceneFlags[globalCtx->sceneNum].unk_14 |= arg1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B326F4.s") +void func_80B31A34(EnZoraegg* this) { + s32 curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32820.s") + if (this->unk_1EA & 1) { + this->unk_1EE = this->unk_1EF = 100; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32928.s") + curFrame = this->skelAnime.curFrame; + if (curFrame < 6) { + this->unk_1EE = 0; + this->unk_1EF = 0; + } else if (curFrame < 93) { + this->unk_1EE = Math_SinS((curFrame * 0xBC) - 0x468) * 100.0f; + if (curFrame >= 89) { + this->unk_1EF = Math_SinS((curFrame * 0x1000) - (0x59 * 0x1000)) * 100.0f; + } else { + this->unk_1EF = 0; + } + } else { + this->unk_1EE = this->unk_1EF = 100; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32A88.s") +void func_80B31C40(EnZoraegg* this, GlobalContext* globalCtx) { + Actor_MoveWithGravity(&this->actor); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); + this->actor.focus.pos.y += 10.0f; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32B10.s") +Actor* func_80B31CB4(GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32B3C.s") + while (actor != NULL) { + if ((actor->id == ACTOR_EN_ZORAEGG) && (ENZORAEGG_GET_1F(actor) == ENZORAEGG_1F_17) && + (actor->home.rot.z == 0)) { + actor->home.rot.z = 1; + return actor; + } + actor = actor->next; + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32B70.s") +Actor* func_80B31D14(GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32BB8.s") + while (actor != NULL) { + if ((actor->id == ACTOR_EN_ZORAEGG) && (ENZORAEGG_GET_1F(actor) == ENZORAEGG_1F_3)) { + return actor; + } + actor = actor->next; + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32C34.s") +void func_80B31D64(EnZoraegg* this, GlobalContext* globalCtx, s32 arg2, f32 arg3) { + Vec3f sp24 = this->actor.world.pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32D08.s") + sp24.y += arg3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/EnZoraegg_Update.s") + if ((globalCtx->gameplayFrames & arg2) == 0) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, 0.0f, 10.0f, 0.13f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B32F04.s") +void func_80B31E00(EnZoraegg* this) { + f32 sp20[] = { + 1.0f, + 1.075f, + 1.15f, + 1.075f, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B331C8.s") + if (this->unk_1E8 < 112) { + if (this->unk_1E8 > 10) { + this->unk_1ED = (s32)((112.0f - this->unk_1E8) * 2.5f) & 0xFF; + } + } else { + this->unk_1ED = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B3336C.s") + if (this->unk_1E8 < 10) { + this->unk_1E0 = sp20[this->unk_1E8 & 3]; + } else if (this->unk_1E8 < 22) { + this->unk_1E0 = (Math_SinS((this->unk_1E8 - 10.0f) * (4096.0f / 3)) * 0.8f) + 1.0f; + } else if (this->unk_1E8 < 26) { + this->unk_1E0 = (Math_CosS((this->unk_1E8 - 22.0f) * 4096.0f) * 0.8f) + 1.0f; + } else if (this->unk_1E8 < 32) { + this->unk_1E0 = sp20[(this->unk_1E8 - 1) & 3]; + } else if (this->unk_1E8 < 47) { + this->unk_1E0 = 1.0f; + } else if (this->unk_1E8 < 53) { + this->unk_1E0 = sp20[(this->unk_1E8 - 2) & 3]; + } else if (this->unk_1E8 < 74) { + this->unk_1E0 = 1.0f - ((this->unk_1E8 - 53.0f) * (1.0f / 105)); + } else if (this->unk_1E8 < 112) { + this->unk_1E0 = (this->unk_1E0 * 0.9f) + 0.15f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B333DC.s") + if ((this->unk_1E8 == 111) || (this->unk_1E8 == 32)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_BORN); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B33480.s") +void func_80B32084(EnZoraegg* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/func_80B33818.s") +void func_80B32094(EnZoraegg* this, GlobalContext* globalCtx) { + if (Message_GetState(&globalCtx->msgCtx) == 2) { + this->actionFunc = func_80B320E0; + } + func_80B31C40(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zoraegg/EnZoraegg_Draw.s") +void func_80B320E0(EnZoraegg* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + Flags_SetSwitch(globalCtx, ENZORAEGG_GET_FE00(&this->actor)); + Actor_MarkForDeath(&this->actor); + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80B32094; + Message_StartTextbox(globalCtx, 0x24B, &this->actor); + } else { + Actor_PickUp(&this->actor, globalCtx, GI_MAX, 80.0f, 60.0f); + if (this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 110.0f); + } + } + + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + this->actor.targetMode = 3; + func_80B31C40(this, globalCtx); +} + +void func_80B321D0(EnZoraegg* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) { + this->actionFunc = func_80B322BC; + func_80B319D0(globalCtx, func_80B319A8(globalCtx) + 1); + } +} + +void func_80B32228(EnZoraegg* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, this->unk_1DC); + this->actionFunc = func_80B321D0; + } else { + if (this->unk_1E8 > 0) { + this->unk_1E8--; + } else if (this->unk_1E8 == 0) { + ActorCutscene_Stop(player->unk_A86); + player->unk_A86 = -1; + this->unk_1E8 = -1; + } + + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80B322BC(EnZoraegg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actor.cutscene != -1) { + this->unk_1DC = func_80B31CB4(globalCtx); + if (this->unk_1DC != NULL) { + this->unk_1E8 = 3; + this->actionFunc = func_80B32228; + return; + } + } + + if ((fabsf(player->actor.world.pos.x - this->actor.world.pos.x) < (100.0f * this->actor.scale.x)) && + (fabsf(player->actor.world.pos.z - this->actor.world.pos.z) < (100.0f * this->actor.scale.z))) { + func_8012300C(globalCtx, 25); + } +} + +void func_80B32390(EnZoraegg* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + Actor* temp_v0 = func_80B31D14(globalCtx); + + if (temp_v0 != NULL) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, temp_v0); + gSaveContext.eventInf[3] |= 8; + Actor_MarkForDeath(&this->actor); + } + } else if ((func_80B319A8(globalCtx) >= 7) && + (fabsf(player->actor.world.pos.x - this->actor.world.pos.x) < (100.0f * this->actor.scale.x)) && + (fabsf(player->actor.world.pos.z - this->actor.world.pos.z) < (100.0f * this->actor.scale.z)) && + (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 30.0f)) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80B324B0(EnZoraegg* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCmd)) { + if (this->unk_1EA & 4) { + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCmd) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)]->action == + 3)) { + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + this->unk_1EA &= ~4; + } + } else { + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCmd) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)]->action == + 4)) { + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004E04); + this->unk_1EA |= 4; + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)); + + if ((this->unk_1EA & 4) && Animation_OnFrame(&this->skelAnime, this->unk_1E4)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_SWIM_1); + this->unk_1E4 = Rand_ZeroFloat(5.0f); + } + } else if (this->unk_1EA & 4) { + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + this->unk_1EA &= ~4; + } +} + +void func_80B32644(EnZoraegg* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + Animation_PlayLoop(&this->skelAnime, &object_zoraegg_Anim_004FE4); + this->unk_1EE = 0; + this->unk_1EA |= 2; + } + + if (!Cutscene_CheckActorAction(globalCtx, this->actorActionCmd)) { + this->actionFunc = func_80B324B0; + } else { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)); + + if (this->unk_1EE > 25) { + this->unk_1EE -= 25; + } else { + this->unk_1EE = 0; + } + } +} + +void func_80B326F4(EnZoraegg* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCmd) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)]->action == 3)) { + Animation_Change(&this->skelAnime, &object_zoraegg_Anim_004D20, 1.0f, 0.0f, + Animation_GetLastFrame(&object_zoraegg_Anim_004D20), 2, 5.0f); + this->unk_1E8 = 0; + this->actionFunc = func_80B32644; + gSaveContext.save.weekEventReg[19] |= 0x40; + this->unk_1EC = 2; + this->unk_1EE = 100; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_SWIM_2); + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)); + + if (Animation_OnFrame(&this->skelAnime, 4.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_SWIM_1); + } +} + +void func_80B32820(EnZoraegg* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_1E8 >= 2) { + this->actionFunc = func_80B326F4; + Animation_Change(&this->skelAnime, &object_zoraegg_Anim_005098, 1.0f, 0.0f, + Animation_GetLastFrame(&object_zoraegg_Anim_005098), 0, 10.0f); + this->unk_1E8 = 0; + SkelAnime_Update(&this->skelAnime); + return; + } + + Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4); + this->unk_1E8 += 1; + SkelAnime_Update(&this->skelAnime); + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)); + + if (Animation_OnFrame(&this->skelAnime, 16.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_SWIM_0); + } +} + +void func_80B32928(EnZoraegg* this, GlobalContext* globalCtx) { + if (this->unk_1E8 < 112) { + this->unk_1E8++; + } + + if (SkelAnime_Update(&this->skelAnime)) { + Animation_PlayOnce(&this->skelAnime, &object_zoraegg_Anim_0005D4); + this->unk_1EA |= 1; + this->actionFunc = func_80B32820; + this->unk_1E8 = 0; + this->actor.velocity.y = 0.0f; + return; + } + + func_80B31A34(this); + func_80B31E00(this); + + if (this->unk_1E8 < 112) { + if ((this->unk_1E8 >= 69) && (this->unk_1E8 < 72)) { + func_80B31D64(this, globalCtx, 0, 0.0f); + func_80B31D64(this, globalCtx, 0, 0.0f); + func_80B31D64(this, globalCtx, 0, 0.0f); + } else { + func_80B31D64(this, globalCtx, 0xD, 0.0f); + } + } + + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, + Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)); + + if (Animation_OnFrame(&this->skelAnime, 97.0f) || Animation_OnFrame(&this->skelAnime, 101.0f) || + Animation_OnFrame(&this->skelAnime, 105.0f)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_KIDS_SWIM_1); + } +} + +void func_80B32A88(EnZoraegg* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, this->actorActionCmd) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, this->actorActionCmd)]->action == 2)) { + this->unk_1E8 = 0; + this->actionFunc = func_80B32928; + } + func_80B31D64(this, globalCtx, 13, 0.0f); +} + +void func_80B32B10(EnZoraegg* this, GlobalContext* globalCtx) { + if (gSaveContext.eventInf[3] & 8) { + this->actionFunc = func_80B32A88; + } +} + +void func_80B32B3C(EnZoraegg* this, GlobalContext* globalCtx) { + if (gSaveContext.eventInf[3] & 8) { + this->actionFunc = func_80B32A88; + this->actor.draw = EnZoraegg_Draw; + } +} + +void func_80B32B70(EnZoraegg* this, GlobalContext* globalCtx) { + func_80B31C40(this, globalCtx); + if (Cutscene_CheckActorAction(globalCtx, 0x1C9)) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B32BB8(EnZoraegg* this, GlobalContext* globalCtx) { + func_80B31C40(this, globalCtx); + func_80B31D64(this, globalCtx, 13, 0.0f); + + if (this->actor.bgCheckFlags & 0x1) { + this->actionFunc = func_80B32B70; + } + + if (Cutscene_CheckActorAction(globalCtx, 0x1C9)) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80B32C34(EnZoraegg* this, GlobalContext* globalCtx) { + WaterBox* sp34; + f32 sp30; + s32 pad; + + Actor_MoveWithGravity(&this->actor); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); + this->actor.focus.pos.y += 10.0f; + sp30 = this->actor.world.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp30, + &sp34)) { + if ((this->actor.world.pos.y + 50.0f) < sp30) { + this->actionFunc = func_80B32BB8; + } + + func_80B31D64(this, globalCtx, 0, -20.0f); + func_80B31D64(this, globalCtx, 0, -20.0f); + } +} + +void func_80B32D08(EnZoraegg* this, GlobalContext* globalCtx) { + WaterBox* sp44; + f32 sp40; + Vec3f sp34; + s32 pad; + + Actor_MoveWithGravity(&this->actor); + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); + this->actor.focus.pos.y += 10.0f; + sp40 = this->actor.world.pos.y; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp40, + &sp44)) { + if (this->actor.world.pos.y < sp40) { + sp34.x = this->actor.world.pos.x; + sp34.y = sp40; + sp34.z = this->actor.world.pos.z; + + EffectSsGRipple_Spawn(globalCtx, &sp34, 150, 500, 0); + EffectSsGSplash_Spawn(globalCtx, &sp34, NULL, NULL, 0, 200); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_INTO_WATER_L); + + this->actionFunc = func_80B32C34; + this->actor.velocity.y = -1.0f; + this->actor.terminalVelocity = -1.0f; + this->actor.gravity = -1.0f; + } + } + + if (this->actor.scale.x < 0.006f) { + Actor_SetScale(&this->actor, this->actor.scale.x + 0.0012f); + } + + if (this->actor.scale.x > 0.006f) { + Actor_SetScale(&this->actor, 0.006f); + } +} + +void EnZoraegg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnZoraegg* this = THIS; + + this->actionFunc(this, globalCtx); + + if (DECR(this->unk_1F4) == 0) { + this->unk_1F4 = Rand_S16Offset(60, 60); + } + + this->unk_1F2 = this->unk_1F4; + if (this->unk_1F2 >= 3) { + this->unk_1F2 = 0; + } +} + +void func_80B32F04(Actor* thisx, GlobalContext* globalCtx) { + f32 sp7C; + f32 sp78; + f32 sp74; + EnZoraegg* this = THIS; + s32 pad[3]; + s16 sp62; + s16 sp60; + f32 temp_f2; + Gfx* gfx; + Vec3f sp4C; + s32 pad2; + + Matrix_Push(); + + sp4C = GET_ACTIVE_CAM(globalCtx)->eye; + + sp62 = Math_Vec3f_Yaw(&sp4C, &this->actor.focus.pos); + sp60 = -Math_Vec3f_Pitch(&sp4C, &this->actor.focus.pos); + + sp74 = -((15.0f * Math_SinS(sp62)) * Math_CosS(sp60)); + sp78 = -(15.0f * Math_SinS(sp60)); + sp7C = -((15.0f * Math_CosS(sp62)) * Math_CosS(sp60)); + + Matrix_Translate(this->actor.world.pos.x + sp74, this->actor.world.pos.y + sp78 + 6.0f, + temp_f2 = this->actor.world.pos.z + sp7C, MTXMODE_NEW); + + sp7C = Math_SinS(globalCtx->gameplayFrames * 0x4000); + + Matrix_Scale(this->actor.scale.x * (((sp7C + 1.0f) * 0.1f) + 9.0f), + this->actor.scale.y * (((sp7C + 1.0f) * 0.1f) + 9.0f), + this->actor.scale.z * (((sp7C + 1.0f) * 0.1f) + 9.0f), MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_XLU_DISP; + gfx = func_8012C868(gfx); + + 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); + gSPDisplayList(gfx++, gameplay_keep_DL_029CB0); + + gDPSetPrimColor(gfx++, 0, 0, 120, 180, 200, (s32)(this->unk_1ED * (20.0f / 51))); + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, gameplay_keep_DL_029CF0); + + POLY_XLU_DISP = gfx; + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80B331C8(Actor* thisx, GlobalContext* globalCtx) { + EnZoraegg* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + + Matrix_Scale(this->unk_1E0, this->unk_1E0, this->unk_1E0, MTXMODE_APPLY); + + if (this->unk_1ED >= 254) { + func_8012C28C(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_OPA_SURF2); + gSPDisplayList(POLY_OPA_DISP++, object_zoraegg_DL_005250); + } else { + func_8012C304(POLY_XLU_DISP++); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_SURF2); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_1ED); + gSPDisplayList(POLY_XLU_DISP++, object_zoraegg_DL_005250); + } + + Matrix_Pop(); + + func_80B32F04(thisx, globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 EnZoraegg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnZoraegg* this = THIS; + + switch (this->unk_1EC) { + case 1: + if ((limbIndex != 1) && (limbIndex != 3) && (limbIndex != 4)) { + *dList = NULL; + } + break; + + case 2: + if ((limbIndex != 1) && (limbIndex != 3)) { + *dList = NULL; + } + break; + } + return false; +} + +void func_80B333DC(GlobalContext* globalCtx, Gfx** dList, f32 arg2) { + Matrix_Push(); + Matrix_Scale(arg2, arg2, arg2, MTXMODE_APPLY); + + OPEN_DISPS(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++, *dList); + + Matrix_Pop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnZoraegg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnZoraegg* this = THIS; + f32 temp_f20; + f32 temp_f2; + + switch (this->unk_1EC) { + case 1: + switch (limbIndex) { + case 2: + temp_f20 = this->unk_1EE * 0.01f; + Matrix_Push(); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + + OPEN_DISPS(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++, *dList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + break; + + case 4: + Matrix_Pop(); + break; + + case 5: + case 6: + temp_f20 = this->unk_1EF * 0.01f; + func_80B333DC(globalCtx, dList, temp_f20); + break; + } + break; + + case 2: + switch (limbIndex) { + case 2: + temp_f20 = (this->unk_1EE * 0.005f) + 0.5f; + Matrix_Push(); + Matrix_Scale(1.0f, temp_f20, temp_f20, MTXMODE_APPLY); + + OPEN_DISPS(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++, *dList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + break; + + case 4: + temp_f2 = 1.0f / ((this->unk_1EE * 0.005f) + 0.5f); + temp_f20 = (this->unk_1EE * 0.0035f) + 0.65f; + Matrix_Scale(1.0f, temp_f20 * temp_f2, temp_f2, MTXMODE_APPLY); + + OPEN_DISPS(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++, *dList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Matrix_Pop(); + break; + + case 5: + case 6: + temp_f20 = this->unk_1EE * 0.01f; + func_80B333DC(globalCtx, dList, temp_f20); + break; + } + break; + } +} + +TexturePtr D_80B33950[] = { object_zoraegg_Tex_003430, object_zoraegg_Tex_004430, object_zoraegg_Tex_004830 }; + +void func_80B33818(Actor* thisx, GlobalContext* globalCtx) { + EnZoraegg* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80B33950[this->unk_1F2])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnZoraegg_OverrideLimbDraw, EnZoraegg_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnZoraegg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnZoraegg* this = THIS; + + if (this->unk_1ED > 0) { + func_80B331C8(thisx, globalCtx); + } + + if (this->unk_1ED != 255) { + func_80B33818(thisx, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h index 8c458c46e..fb65579fa 100644 --- a/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h +++ b/src/overlays/actors/ovl_En_Zoraegg/z_en_zoraegg.h @@ -7,9 +7,55 @@ struct EnZoraegg; typedef void (*EnZoraeggActionFunc)(struct EnZoraegg*, GlobalContext*); +#define ENZORAEGG_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENZORAEGG_GET_FE00(thisx) (((thisx)->params & 0xFE00) >> 9) + +enum { + /* 0 */ ENZORAEGG_1F_0, + /* 1 */ ENZORAEGG_1F_1, + /* 2 */ ENZORAEGG_1F_2, + /* 3 */ ENZORAEGG_1F_3, + /* 4 */ ENZORAEGG_1F_4, + /* 5 */ ENZORAEGG_1F_5, + /* 6 */ ENZORAEGG_1F_6, + /* 7 */ ENZORAEGG_1F_7, + /* 8 */ ENZORAEGG_1F_8, + /* 9 */ ENZORAEGG_1F_9, + /* 10 */ ENZORAEGG_1F_10, + /* 11 */ ENZORAEGG_1F_11, + /* 12 */ ENZORAEGG_1F_12, + /* 13 */ ENZORAEGG_1F_13, + /* 14 */ ENZORAEGG_1F_14, + /* 15 */ ENZORAEGG_1F_15, + /* 16 */ ENZORAEGG_1F_16, + /* 17 */ ENZORAEGG_1F_17, + /* 18 */ ENZORAEGG_1F_18, + /* 19 */ ENZORAEGG_1F_19, + /* 20 */ ENZORAEGG_1F_20, + /* 21 */ ENZORAEGG_1F_21, + /* 22 */ ENZORAEGG_1F_22, + /* 23 */ ENZORAEGG_1F_23, + /* 24 */ ENZORAEGG_1F_24, + /* 25 */ ENZORAEGG_1F_25, +}; + typedef struct EnZoraegg { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xB4]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[7]; + /* 0x01B2 */ Vec3s morphTable[7]; + /* 0x01DC */ Actor* unk_1DC; + /* 0x01E0 */ f32 unk_1E0; + /* 0x01E4 */ f32 unk_1E4; + /* 0x01E8 */ s16 unk_1E8; + /* 0x01EA */ u16 unk_1EA; + /* 0x01EC */ u8 unk_1EC; + /* 0x01ED */ u8 unk_1ED; + /* 0x01EE */ u8 unk_1EE; + /* 0x01EF */ u8 unk_1EF; + /* 0x01F0 */ u16 actorActionCmd; + /* 0x01F2 */ s16 unk_1F2; + /* 0x01F4 */ s16 unk_1F4; /* 0x01F8 */ EnZoraeggActionFunc actionFunc; } EnZoraegg; // size = 0x1FC diff --git a/src/overlays/actors/ovl_En_Zos/z_en_zos.c b/src/overlays/actors/ovl_En_Zos/z_en_zos.c index d87428967..0f299f255 100644 --- a/src/overlays/actors/ovl_En_Zos/z_en_zos.c +++ b/src/overlays/actors/ovl_En_Zos/z_en_zos.c @@ -1,6 +1,13 @@ -#include "z_en_zos.h" +/* + * File: z_en_zos.c + * Overlay: ovl_En_Zos + * Description: Zora Synthesizer - Evan + */ -#define FLAGS 0x02000009 +#include "z_en_zos.h" +#include "objects/object_zos/object_zos.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_2000000) #define THIS ((EnZos*)thisx) @@ -9,7 +16,24 @@ void EnZos_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZos_Update(Actor* thisx, GlobalContext* globalCtx); void EnZos_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BBAE84(EnZos* this, s16 arg1, u8 arg2); +void func_80BBB2C4(EnZos* this, GlobalContext* globalCtx); +void func_80BBB354(EnZos* this, GlobalContext* globalCtx); +void func_80BBB4CC(EnZos* this, GlobalContext* globalCtx); +void func_80BBB574(EnZos* this, GlobalContext* globalCtx); +void func_80BBB718(EnZos* this, GlobalContext* globalCtx); +void func_80BBB8AC(EnZos* this, GlobalContext* globalCtx); +void func_80BBBB84(EnZos* this, GlobalContext* globalCtx); +void func_80BBBCBC(EnZos* this, GlobalContext* globalCtx); +void func_80BBBD5C(EnZos* this, GlobalContext* globalCtx); +void func_80BBBDE0(EnZos* this, GlobalContext* globalCtx); +void func_80BBC070(EnZos* this, GlobalContext* globalCtx); +void func_80BBC14C(EnZos* this, GlobalContext* globalCtx); +void func_80BBC22C(EnZos* this, GlobalContext* globalCtx); +void func_80BBC24C(EnZos* this, GlobalContext* globalCtx); +void func_80BBC298(EnZos* this, GlobalContext* globalCtx); +void func_80BBC37C(EnZos* this, GlobalContext* globalCtx); + const ActorInit En_Zos_InitVars = { ACTOR_EN_ZOS, ACTORCAT_NPC, @@ -22,74 +46,696 @@ const ActorInit En_Zos_InitVars = { (ActorFunc)EnZos_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BBC6F0 = { - { 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, + }, { 60, 40, 0, { 0, 0, 0 } }, }; -#endif +void EnZos_Init(Actor* thisx, GlobalContext* globalCtx) { + EnZos* this = THIS; -extern ColliderCylinderInit D_80BBC6F0; + Actor_SetScale(&this->actor, 0.0115f); + this->actionFunc = func_80BBBDE0; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 30.0f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zos_Skel_015238, &object_zos_Anim_00A164, this->jointTable, + this->morphTable, 18); + Animation_PlayLoop(&this->skelAnime, &object_zos_Anim_00A164); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_2B6 = 0; + this->actor.terminalVelocity = -4.0f; + this->actor.gravity = -4.0f; + func_80BBAE84(this, 0, 2); -extern UNK_TYPE D_0600A164; -extern UNK_TYPE D_060136E0; + switch (ENZOS_GET_F(&this->actor)) { + case ENZOS_F_1: + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/EnZos_Init.s") + if (gSaveContext.save.weekEventReg[78] & 1) { + this->actionFunc = func_80BBC24C; + } else { + this->actionFunc = func_80BBC14C; + } + func_80BBAE84(this, 0, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/EnZos_Destroy.s") + case ENZOS_F_2: + this->actionFunc = func_80BBC37C; + func_80BBAE84(this, 7, 2); + this->unk_2BC = -1; + this->unk_2B6 |= 0x40; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBAE84.s") + default: + if (gSaveContext.save.weekEventReg[55] & 0x80) { + Actor_MarkForDeath(&this->actor); + } + this->actor.flags |= ACTOR_FLAG_10; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBAF5C.s") +void EnZos_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZos* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBAFFC.s") + gSaveContext.save.weekEventReg[52] &= (u8)~0x10; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB0D4.s") +void func_80BBAE84(EnZos* this, s16 arg1, u8 arg2) { + static AnimationHeader* sAnimations[] = { + &object_zos_Anim_00A164, &object_zos_Anim_01621C, &object_zos_Anim_016980, &object_zos_Anim_007C40, + &object_zos_Anim_008630, &object_zos_Anim_0090CC, &object_zos_Anim_009830, &object_zos_Anim_005E04, + &object_zos_Anim_007334, &object_zos_Anim_0048D4, &object_zos_Anim_001CFC, &object_zos_Anim_005E04, + &object_zos_Anim_007334, + }; + f32 phi_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB15C.s") + if ((arg1 != this->unk_2B8) && (arg1 >= 0) && (arg1 < 13)) { + if (arg1 > 10) { + phi_f0 = 29.0f; + } else { + phi_f0 = Animation_GetLastFrame(sAnimations[arg1]); + } + Animation_Change(&this->skelAnime, sAnimations[arg1], 1.0f, 0.0f, phi_f0, arg2, -5.0f); + this->unk_2B8 = arg1; + this->unk_2B6 &= ~0x80; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB2C4.s") +s32 func_80BBAF5C(EnZos* this, GlobalContext* globalCtx) { + if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + ((!Actor_IsFacingPlayer(&this->actor, 0x4000) && (this->actor.home.rot.y == this->actor.shape.rot.y)) || + (Actor_IsFacingPlayer(&this->actor, 0x3000) && (this->actor.home.rot.y != this->actor.shape.rot.y))) && + (this->actor.xzDistToPlayer < 100.0f)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB354.s") +s32 func_80BBAFFC(EnZos* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + switch ((s16)Rand_ZeroFloat(4.0f)) { + case 0: + func_80BBAE84(this, 7, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB414.s") + case 1: + func_80BBAE84(this, 8, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB4CC.s") + case 2: + func_80BBAE84(this, 11, 2); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB574.s") + default: + func_80BBAE84(this, 12, 2); + break; + } + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB718.s") +void func_80BBB0D4(EnZos* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime)) { + if (Rand_ZeroFloat(1.0f) < 0.9f) { + func_80BBAE84(this, 0, 2); + } else { + func_80BBAE84(this, 1, 2); + } + SkelAnime_Update(&this->skelAnime); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBB8AC.s") +void func_80BBB15C(EnZos* this, GlobalContext* globalCtx) { + s32 textId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBBB84.s") + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (this->unk_2B6 & 8) { + textId = 0x1235; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 2; + } else if (this->unk_2B6 & 4) { + textId = 0x123E; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 2; + } else if (gSaveContext.save.weekEventReg[40] & 0x20) { + textId = 0x1236; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 0x80; + } else { + textId = 0x1231; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 0x80; + } + } else { + this->unk_2B6 &= ~2; + if (gSaveContext.save.weekEventReg[39] & 0x10) { + textId = 0x1243; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 0x80; + } else { + textId = 0x1244; + gSaveContext.save.weekEventReg[39] |= 0x10; + func_80BBAE84(this, 4, 0); + this->unk_2B6 |= 0x10; + } + } + Message_StartTextbox(globalCtx, textId, &this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBBCBC.s") +void func_80BBB2C4(EnZos* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + Message_StartTextbox(globalCtx, 0x124F, &this->actor); + this->actionFunc = func_80BBB8AC; + this->actor.flags &= ~ACTOR_FLAG_10000; + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBBD5C.s") +void func_80BBB354(EnZos* this, GlobalContext* globalCtx) { + s32 item; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBBDE0.s") + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80BBB2C4; + gSaveContext.save.weekEventReg[39] |= 0x20; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } else { + if (gSaveContext.save.weekEventReg[39] & 0x20) { + item = GI_RUPEE_PURPLE; + } else { + item = GI_HEART_PIECE; + } + Actor_PickUp(&this->actor, globalCtx, item, 10000.0f, 50.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBBFBC.s") +void func_80BBB414(EnZos* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC070.s") + if (Cutscene_CheckActorAction(globalCtx, 501)) { + s16 action = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 501)]->action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC14C.s") + if (action != this->unk_2BA) { + this->unk_2BA = action; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC22C.s") + switch (action) { + case 1: + func_80BBAE84(this, 1, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC24C.s") + case 2: + func_80BBAE84(this, 10, 0); + break; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC298.s") +void func_80BBB4CC(EnZos* this, GlobalContext* globalCtx) { + func_80BBB414(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC37C.s") + if ((this->actor.cutscene != -1) && (ActorCutscene_GetCurrentIndex() != this->actor.cutscene)) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_Start(this->actor.cutscene, &this->actor); + this->actor.cutscene = -1; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/EnZos_Update.s") +void func_80BBB574(EnZos* this, GlobalContext* globalCtx) { + if (!(this->unk_2B6 & 0x10)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC4E4.s") + if (func_80BBAFFC(this, globalCtx)) { + if (this->unk_2B6 & 0x20) { + this->unk_2B6 &= ~0x20; + func_80151938(globalCtx, 0x124C); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/func_80BBC500.s") + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x124B: + if (this->unk_2B8 == 9) { + globalCtx->msgCtx.unk11F10 = 0; + this->unk_2B6 |= 0x20; + } else { + func_80151938(globalCtx, 0x124C); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zos/EnZos_Draw.s") + case 0x124C: + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80BBB4CC; + func_80BBAE84(this, 10, 0); + break; + + case 0x124D: + this->unk_2B6 &= ~0x10; + func_80BBAE84(this, 6, 0); + func_80151938(globalCtx, 0x124E); + break; + + case 0x124E: + func_801477B4(globalCtx); + this->actionFunc = func_80BBB354; + func_80BBB354(this, globalCtx); + break; + } + } +} + +void func_80BBB718(EnZos* this, GlobalContext* globalCtx) { + s32 sp24; + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + + if (Message_GetState(&globalCtx->msgCtx) == 0x10) { + sp24 = func_80123810(globalCtx); + if (sp24 > 0) { + func_801477B4(globalCtx); + + if (sp24 == 25) { + player->actor.textId = 0x1232; + func_80BBAE84(this, 5, 0); + this->unk_2B6 |= 8; + gSaveContext.save.weekEventReg[40] |= 0x20; + } else if (gSaveContext.save.weekEventReg[39] & 8) { + player->actor.textId = 0x1241; + } else { + player->actor.textId = 0x1237; + gSaveContext.save.weekEventReg[39] |= 8; + func_80BBAE84(this, 4, 0); + this->unk_2B6 |= 4; + } + this->actionFunc = func_80BBB8AC; + } else if (sp24 < 0) { + if (gSaveContext.save.weekEventReg[39] & 8) { + func_80151938(globalCtx, 0x1241); + } else { + func_80151938(globalCtx, 0x1237); + gSaveContext.save.weekEventReg[39] |= 8; + func_80BBAE84(this, 4, 0); + this->unk_2B6 |= 4; + } + this->actionFunc = func_80BBB8AC; + } + } +} + +void func_80BBB8AC(EnZos* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + + if (!(this->unk_2B6 & 0x10)) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->unk_2B6 & 0x80) && (this->actor.yawTowardsPlayer == this->actor.shape.rot.y)) { + func_80BBAE84(this, 3, 0); + } + } + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1237: + player->exchangeItemId = 0; + + case 0x1238: + case 0x123A: + case 0x123B: + case 0x123C: + case 0x123E: + case 0x123F: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1244: + this->unk_2B6 &= ~0x10; + func_80BBAE84(this, 6, 0); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1232: + case 0x1241: + player->exchangeItemId = 0; + + case 0x1239: + case 0x1246: + func_80BBAE84(this, 6, 0); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1233: + func_80BBAE84(this, 5, 0); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1245: + case 0x1248: + func_80BBAE84(this, 3, 0); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1231: + func_80151938(globalCtx, 0xFF); + this->actionFunc = func_80BBB718; + break; + + case 0x1243: + case 0x1249: + func_80BBAE84(this, 2, 0); + func_801477B4(globalCtx); + this->actionFunc = func_80BBBDE0; + this->unk_2B6 |= 1; + break; + + case 0x1234: + case 0x123D: + case 0x1242: + func_80BBAE84(this, 2, 0); + Actor_ProcessTalkRequest(&this->actor, &globalCtx->state); + func_801477B4(globalCtx); + this->actionFunc = func_80BBBDE0; + this->unk_2B6 |= 1; + break; + + case 0x1236: + func_80BBAE84(this, 2, 0); + func_801477B4(globalCtx); + this->actionFunc = func_80BBBDE0; + this->unk_2B6 |= 1; + break; + + default: + if (0) {} + func_801477B4(globalCtx); + this->actionFunc = func_80BBBDE0; + this->unk_2B6 |= 1; + break; + } + } +} + +void func_80BBBB84(EnZos* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + Message_StartTextbox(globalCtx, 0x1248, &this->actor); + this->actionFunc = func_80BBB8AC; + func_80BBAE84(this, 6, 0); + this->unk_2B6 |= 2; + } else if (gSaveContext.save.weekEventReg[41] & 0x10) { + Message_StartTextbox(globalCtx, 0x124A, &this->actor); + this->actionFunc = func_80BBB8AC; + func_80BBAE84(this, 6, 0); + } else { + gSaveContext.save.weekEventReg[41] |= 0x10; + Message_StartTextbox(globalCtx, 0x124B, &this->actor); + this->actionFunc = func_80BBB574; + func_80BBAE84(this, 9, 2); + this->unk_2B6 |= 0x10; + } + } else { + func_800B8614(&this->actor, globalCtx, 300.0f); + } +} + +void func_80BBBCBC(EnZos* this, GlobalContext* globalCtx) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + func_80BBAE84(this, 5, 0); + Message_StartTextbox(globalCtx, 0x124D, &this->actor); + this->actionFunc = func_80BBB574; + } else { + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} + +void func_80BBBD5C(EnZos* this, GlobalContext* globalCtx) { + func_80BBB414(this, globalCtx); + if (!Cutscene_CheckActorAction(globalCtx, 0x1F5)) { + this->actionFunc = func_80BBBCBC; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + } +} + +void func_80BBBDE0(EnZos* this, GlobalContext* globalCtx) { + Actor* thisx = &this->actor; + Vec3f sp28; + + if (this->unk_2B6 & 1) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200); + this->actor.world.rot.y = thisx->shape.rot.y; + if (this->actor.home.rot.y == thisx->shape.rot.y) { + func_80BBAE84(this, 0, 2); + this->unk_2B6 &= ~1; + } + } + + func_80BBB0D4(this, globalCtx); + + if (globalCtx->msgCtx.ocarinaMode == 0x2A) { + globalCtx->msgCtx.ocarinaMode = 4; + this->actionFunc = func_80BBBB84; + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8614(&this->actor, globalCtx, 120.0f); + return; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BBB8AC; + func_80BBB15C(this, globalCtx); + } else if (Cutscene_CheckActorAction(globalCtx, 0x1F5)) { + this->actionFunc = func_80BBBD5C; + } else if (func_80BBAF5C(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + + if (!Actor_IsFacingPlayer(&this->actor, 0x4000) && (this->actor.xzDistToPlayer < 100.0f)) { + gSaveContext.save.weekEventReg[52] |= 0x10; + } else { + gSaveContext.save.weekEventReg[52] &= (u8)~0x10; + } + + sp28.x = this->actor.projectedPos.x; + sp28.y = this->actor.projectedPos.y; + sp28.z = this->actor.projectedPos.z; + func_801A1FB4(3, &sp28, 110, 1000.0f); +} + +void func_80BBBFBC(EnZos* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[79] & 1) { + textId = 0x125B; + } else if (gSaveContext.save.weekEventReg[78] & 0x80) { + textId = 0x125A; + } else { + textId = 0x1259; + gSaveContext.save.weekEventReg[78] |= 0x80; + } + func_80BBAE84(this, 5, 0); + } else { + textId = 0x1258; + func_80BBAE84(this, 6, 0); + } + Message_StartTextbox(globalCtx, textId, &this->actor); +} + +void func_80BBC070(EnZos* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 5: + if (Message_ShouldAdvance(globalCtx)) { + func_80BBAE84(this, 2, 0); + func_801477B4(globalCtx); + this->actionFunc = func_80BBC14C; + this->unk_2B6 |= 1; + } + break; + + case 2: + func_80BBAE84(this, 2, 0); + this->actionFunc = func_80BBC14C; + this->unk_2B6 |= 1; + break; + } +} + +void func_80BBC14C(EnZos* this, GlobalContext* globalCtx) { + Actor* thisx = &this->actor; + + if (this->unk_2B6 & 1) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200); + this->actor.world.rot.y = thisx->shape.rot.y; + if (this->actor.home.rot.y == this->actor.shape.rot.y) { + func_80BBAE84(this, 0, 2); + this->unk_2B6 &= ~1; + } + } + + func_80BBB0D4(this, globalCtx); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BBC070; + func_80BBBFBC(this, globalCtx); + } else if (func_80BBAF5C(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void func_80BBC22C(EnZos* this, GlobalContext* globalCtx) { + func_80BBAFFC(this, globalCtx); +} + +void func_80BBC24C(EnZos* this, GlobalContext* globalCtx) { + func_80BBB0D4(this, globalCtx); + if (gSaveContext.save.weekEventReg[79] & 1) { + this->actionFunc = func_80BBC22C; + func_80BBAE84(this, 7, 2); + } +} + +void func_80BBC298(EnZos* this, GlobalContext* globalCtx) { + func_80BBAFFC(this, globalCtx); + + if (this->unk_2BC < 799) { + this->unk_2BC += 200; + } else { + this->unk_2BC += 30; + } + + if (this->unk_2BC > 999) { + this->unk_2BC = 999; + } + + if (Cutscene_CheckActorAction(globalCtx, 515)) { + if (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 515)]->action == 1) { + this->actionFunc = func_80BBC37C; + this->unk_2BC = -1; + } + } else { + this->actionFunc = func_80BBC37C; + this->unk_2BC = -1; + } +} + +void func_80BBC37C(EnZos* this, GlobalContext* globalCtx) { + func_80BBAFFC(this, globalCtx); + if (Cutscene_CheckActorAction(globalCtx, 515) && + (globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 515)]->action == 3)) { + this->actionFunc = func_80BBC298; + } +} + +void EnZos_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZos* this = THIS; + + Actor_MoveWithGravity(&this->actor); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 30.0f, 4); + + this->actionFunc(this, globalCtx); + + if (DECR(this->unk_2AE) == 0) { + this->unk_2AE = Rand_S16Offset(60, 60); + } + + this->unk_2AC = this->unk_2AE; + if (this->unk_2AC >= 3) { + this->unk_2AC = 0; + } +} + +s32 func_80BBC4E4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; +} + +void func_80BBC500(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80BBC750 = { 0.0f, 0.0f, 0.0f }; + + if (limbIndex == 9) { + Matrix_MultVec3f(&D_80BBC750, &thisx->focus.pos); + } +} + +void EnZos_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80BBC75C[] = { + object_zos_Tex_010918, + object_zos_Tex_011118, + object_zos_Tex_011918, + }; + EnZos* this = THIS; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_2B6 & 0x40) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 0, 0, 0, 0, this->unk_2BC, 1000); + } + + gfx = POLY_OPA_DISP; + + gSPSegment(&gfx[0], 0x08, Lib_SegmentedToVirtual(D_80BBC75C[this->unk_2AC])); + + Matrix_Push(); + Matrix_RotateYS(this->actor.home.rot.y - this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -974.4f, MTXMODE_APPLY); + + gSPMatrix(&gfx[1], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[2], object_zos_DL_0136E0); + gSPDisplayList(&gfx[3], object_zos_DL_013088); + + POLY_OPA_DISP = &gfx[4]; + + Matrix_Pop(); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_80BBC4E4, func_80BBC500, &this->actor); + + if (this->unk_2B6 & 0x40) { + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Zos/z_en_zos.h b/src/overlays/actors/ovl_En_Zos/z_en_zos.h index dbee5eb8c..991f08d57 100644 --- a/src/overlays/actors/ovl_En_Zos/z_en_zos.h +++ b/src/overlays/actors/ovl_En_Zos/z_en_zos.h @@ -7,9 +7,26 @@ struct EnZos; typedef void (*EnZosActionFunc)(struct EnZos*, GlobalContext*); +#define ENZOS_GET_F(thisx) ((thisx)->params & 0xF) + +enum { + /* 1 */ ENZOS_F_1 = 1, + /* 2 */ ENZOS_F_2, +}; + typedef struct EnZos { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x17C]; + /* 0x0144 */ Vec3s jointTable[18]; + /* 0x01B0 */ Vec3s morphTable[18]; + /* 0x021C */ SkelAnime skelAnime; + /* 0x0260 */ ColliderCylinder collider; + /* 0x02AC */ s16 unk_2AC; + /* 0x02AE */ s16 unk_2AE; + /* 0x02B0 */ UNK_TYPE1 unk2B0[6]; + /* 0x02B6 */ u16 unk_2B6; + /* 0x02B8 */ s16 unk_2B8; + /* 0x02BA */ s16 unk_2BA; + /* 0x02BC */ s16 unk_2BC; /* 0x02C0 */ EnZosActionFunc actionFunc; } EnZos; // size = 0x2C4 diff --git a/src/overlays/actors/ovl_En_Zot/z_en_zot.c b/src/overlays/actors/ovl_En_Zot/z_en_zot.c index c1f0b3351..1cf8ad992 100644 --- a/src/overlays/actors/ovl_En_Zot/z_en_zot.c +++ b/src/overlays/actors/ovl_En_Zot/z_en_zot.c @@ -1,12 +1,13 @@ /* * File: z_en_zot.c * Overlay: ovl_En_Zot - * Description: Great Bay - Zora With Directions to Zora Hall + * Description: Great Bay - Zora With Directions to Zora Hall / Pot Game Zora */ #include "z_en_zot.h" +#include "objects/object_zo/object_zo.h" -#define FLAGS 0x00000019 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnZot*)thisx) @@ -30,21 +31,6 @@ void func_80B990A4(EnZot* this, GlobalContext* globalCtx); void func_80B992C0(EnZot* this, GlobalContext* globalCtx); void func_80B99384(EnZot* this, GlobalContext* globalCtx); -extern AnimationHeader D_06002898; -extern AnimationHeader D_06004248; -extern UNK_PTR D_060050A0; -extern UNK_PTR D_060058A0; -extern UNK_PTR D_060060A0; -extern FlexSkeletonHeader D_0600D208; -extern AnimationHeader D_0600DE20; -extern AnimationHeader D_0600DF54; -extern AnimationHeader D_0600E400; -extern AnimationHeader D_0600EDF0; -extern AnimationHeader D_0600F4E8; -extern AnimationHeader D_0600FDF0; -extern AnimationHeader D_06010B18; -extern AnimationHeader D_06011424; - const ActorInit En_Zot_InitVars = { ACTOR_EN_ZOT, ACTORCAT_NPC, @@ -81,7 +67,7 @@ void func_80B965D0(EnZot* this, GlobalContext* globalCtx) { s32 i; if ((this->path != NULL) && (this->path->count >= 5)) { - Vec3s* points = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); + Vec3s* points = Lib_SegmentedToVirtual(this->path->points); for (i = 0; i < ARRAY_COUNT(this->unk_2D8); i++, points++) { if (this->unk_2D8[i] == NULL) { @@ -93,15 +79,15 @@ void func_80B965D0(EnZot* this, GlobalContext* globalCtx) { } void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { - EnZot* this = THIS; GlobalContext* globalCtx = globalCtx2; + EnZot* this = THIS; s32 i; - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); Actor_SetScale(&this->actor, 0.01f); this->actionFunc = func_80B97100; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600D208, &D_06004248, this->jointTable, this->morphTable, 20); - Animation_PlayLoop(&this->skelAnime, &D_0600DE20); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gZoraSkel, &gZoraIdleAnim, this->jointTable, this->morphTable, 20); + Animation_PlayLoop(&this->skelAnime, &object_zo_Anim_00DE20); this->unk_2F0 = 0; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); @@ -110,7 +96,7 @@ void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->actor.world.rot.z = this->actor.shape.rot.z = 0; this->actor.targetMode = 6; - this->actor.minVelocityY = -4.0f; + this->actor.terminalVelocity = -4.0f; this->actor.gravity = -4.0f; switch (ENZOT_GET_1F(thisx)) { @@ -168,7 +154,7 @@ void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { break; case 8: - this->actor.flags |= 0x2000000; + this->actor.flags |= ACTOR_FLAG_2000000; this->actionFunc = func_80B98CA8; func_80B96BEC(this, 5, 0); break; @@ -198,14 +184,14 @@ void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { func_80B96BEC(this, 2, 0); this->actor.colChkInfo.cylRadius = 0; this->actor.shape.yOffset = -1400.0f; - if (!(gSaveContext.weekEventReg[55] & 0x80)) { + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { Actor_MarkForDeath(&this->actor); } break; case 18: this->actionFunc = func_80B99384; - if (!(gSaveContext.weekEventReg[55] & 0x80)) { + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { Actor_MarkForDeath(&this->actor); } break; @@ -233,7 +219,7 @@ void EnZot_Init(Actor* thisx, GlobalContext* globalCtx2) { break; } - if ((ENZOT_GET_1F(thisx) >= 2) && (ENZOT_GET_1F(thisx) < 11) && (gSaveContext.weekEventReg[55] & 0x80)) { + if ((ENZOT_GET_1F(thisx) >= 2) && (ENZOT_GET_1F(thisx) < 11) && (gSaveContext.save.weekEventReg[55] & 0x80)) { Actor_MarkForDeath(&this->actor); } } @@ -243,14 +229,15 @@ void EnZot_Destroy(Actor* thisx, GlobalContext* globalCtx) { Collider_DestroyCylinder(globalCtx, &this->collider); if (ENZOT_GET_1F(&this->actor) == 8) { - gSaveContext.weekEventReg[41] &= (u8)~0x20; + gSaveContext.save.weekEventReg[41] &= (u8)~0x20; } } void func_80B96BEC(EnZot* this, s16 arg1, u8 arg2) { static AnimationHeader* sAnimations[] = { - &D_0600DE20, &D_06002898, &D_0600F4E8, &D_0600E400, &D_0600FDF0, - &D_06010B18, &D_06011424, &D_0600EDF0, &D_0600DF54, &D_0600DF54, + &object_zo_Anim_00DE20, &gZoraWalkAnim, &object_zo_Anim_00F4E8, &object_zo_Anim_00E400, + &object_zo_Anim_00FDF0, &object_zo_Anim_010B18, &object_zo_Anim_011424, &object_zo_Anim_00EDF0, + &object_zo_Anim_00DF54, &object_zo_Anim_00DF54, }; if ((arg1 >= 0) && (arg1 < 10)) { @@ -288,7 +275,7 @@ void func_80B96D4C(EnZot* this) { } s32 func_80B96DF0(EnZot* this, GlobalContext* globalCtx) { - if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && Actor_IsActorFacingLink(&this->actor, 0x3000) && + if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && Actor_IsFacingPlayer(&this->actor, 0x3000) && (this->actor.xzDistToPlayer < 100.0f)) { return true; } @@ -372,30 +359,30 @@ void func_80B97100(EnZot* this, GlobalContext* globalCtx) { void func_80B97110(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { textId = 0x125F; - if (gSaveContext.weekEventReg[28] & 0x80) { + if (gSaveContext.save.weekEventReg[28] & 0x80) { textId = 0x1261; } else { - gSaveContext.weekEventReg[28] |= 0x80; + gSaveContext.save.weekEventReg[28] |= 0x80; } } else { textId = 0x125C; - if (gSaveContext.weekEventReg[28] & 0x40) { + if (gSaveContext.save.weekEventReg[28] & 0x40) { textId = 0x125E; } else { - gSaveContext.weekEventReg[28] |= 0x40; + gSaveContext.save.weekEventReg[28] |= 0x40; } } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B97194(EnZot* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x125C: case 0x125F: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x125D: @@ -410,11 +397,11 @@ void func_80B97194(EnZot* this, GlobalContext* globalCtx) { } void func_80B97240(EnZot* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B97194; func_80B97110(this, globalCtx); - } else if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && - Actor_IsActorFacingLink(&this->actor, 0x3000)) { + } else if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x3000)) { func_800B8614(&this->actor, globalCtx, 120.0f); } } @@ -422,51 +409,51 @@ void func_80B97240(EnZot* this, GlobalContext* globalCtx) { void func_80B972E8(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.weekEventReg[29] & 0x10) { - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[29] & 0x10) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { textId = 0x126A; - if (gSaveContext.weekEventReg[29] & 1) { + if (gSaveContext.save.weekEventReg[29] & 1) { textId = 0x126D; } else { - gSaveContext.weekEventReg[29] |= 1; + gSaveContext.save.weekEventReg[29] |= 1; } } else { textId = 0x1267; - if (gSaveContext.weekEventReg[29] & 2) { + if (gSaveContext.save.weekEventReg[29] & 2) { textId = 0x1269; } else { - gSaveContext.weekEventReg[29] |= 2; + gSaveContext.save.weekEventReg[29] |= 2; } } - } else if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { textId = 0x1265; - if (gSaveContext.weekEventReg[29] & 4) { + if (gSaveContext.save.weekEventReg[29] & 4) { textId = 0x1266; } else { - gSaveContext.weekEventReg[29] |= 4; + gSaveContext.save.weekEventReg[29] |= 4; } } else { textId = 0x1262; - if (gSaveContext.weekEventReg[29] & 8) { + if (gSaveContext.save.weekEventReg[29] & 8) { textId = 0x1264; } else { - gSaveContext.weekEventReg[29] |= 8; + gSaveContext.save.weekEventReg[29] |= 8; } } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B973BC(EnZot* this, GlobalContext* globalCtx) { func_80B96D4C(this); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x126E: case 0x1270: case 0x1273: case 0x1274: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x1272: @@ -479,7 +466,7 @@ void func_80B973BC(EnZot* this, GlobalContext* globalCtx) { break; case 0x1275: - if (gSaveContext.rupees < 10) { + if (gSaveContext.save.playerData.rupees < 10) { func_80151938(globalCtx, 0x1277); } else { func_80151938(globalCtx, 0x1278); @@ -497,7 +484,7 @@ void func_80B973BC(EnZot* this, GlobalContext* globalCtx) { case 0x1279: func_801477B4(globalCtx); func_80B965D0(this, globalCtx); - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; this->actor.textId = 0; this->actionFunc = func_80B97708; if ((this->actor.cutscene != -1) && !(this->unk_2F2 & 1)) { @@ -525,28 +512,29 @@ void func_80B973BC(EnZot* this, GlobalContext* globalCtx) { void func_80B975F8(EnZot* this, GlobalContext* globalCtx) { func_80B96D4C(this); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B973BC; } else { - func_800B8500(&this->actor, globalCtx, 10000.0f, 1000.0f, 0); + func_800B8500(&this->actor, globalCtx, 10000.0f, 1000.0f, EXCH_ITEM_NONE); } } void func_80B9765C(EnZot* this, GlobalContext* globalCtx) { - if (1) { - do { } while (0); } - func_80B96D4C(this); - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - u16 temp = globalCtx->msgCtx.unk11F04; - u32 temp2; + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + s32 requiredScopeTemp; - if ((temp == 0x1262) || (temp == 0x1267) || (temp == 0x126A) || (temp == 0x126B)) { - temp2 = temp; - func_80151938(globalCtx, temp2 + 1); - } else { - func_801477B4(globalCtx); - this->actionFunc = func_80B97708; + switch (globalCtx->msgCtx.currentTextId) { + case 0x1262: + case 0x1267: + case 0x126A: + case 0x126B: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + default: + func_801477B4(globalCtx); + this->actionFunc = func_80B97708; + break; } } } @@ -558,7 +546,7 @@ void func_80B97708(EnZot* this, GlobalContext* globalCtx) { func_80B96D4C(this); Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B9765C; func_80B972E8(this, globalCtx); return; @@ -571,15 +559,15 @@ void func_80B97708(EnZot* this, GlobalContext* globalCtx) { } if (phi_v1 != 0) { - gSaveContext.weekEventReg[29] |= 0x10; - this->actor.flags |= 0x10000; + gSaveContext.save.weekEventReg[29] |= 0x10; + this->actor.flags |= ACTOR_FLAG_10000; if (phi_v1 == 5) { - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { this->actor.textId = 0x126E; } else { this->actor.textId = 0x1272; } - } else if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { this->actor.textId = 0x1273; } else { this->actor.textId = 0x1276; @@ -596,66 +584,66 @@ void func_80B9787C(EnZot* this, GlobalContext* globalCtx) { u16 textId; if (this->actor.textId == 0) { - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { switch (ENZOT_GET_1F(&this->actor)) { case 2: - if (gSaveContext.weekEventReg[37] & 0x40) { + if (gSaveContext.save.weekEventReg[37] & 0x40) { textId = 0x127E; } else { textId = 0x127C; - gSaveContext.weekEventReg[37] |= 0x40; + gSaveContext.save.weekEventReg[37] |= 0x40; } break; case 3: - if (gSaveContext.weekEventReg[38] & 1) { + if (gSaveContext.save.weekEventReg[38] & 1) { textId = 0x1284; } else { textId = 0x1282; - gSaveContext.weekEventReg[38] |= 1; + gSaveContext.save.weekEventReg[38] |= 1; } break; default: - if (gSaveContext.weekEventReg[38] & 4) { + if (gSaveContext.save.weekEventReg[38] & 4) { textId = 0x128A; } else { textId = 0x1288; - gSaveContext.weekEventReg[38] |= 4; + gSaveContext.save.weekEventReg[38] |= 4; } break; } } else { switch (ENZOT_GET_1F(&this->actor)) { case 2: - if (gSaveContext.weekEventReg[37] & 0x20) { + if (gSaveContext.save.weekEventReg[37] & 0x20) { textId = 0x127B; } else { textId = 0x1279; - gSaveContext.weekEventReg[37] |= 0x20; + gSaveContext.save.weekEventReg[37] |= 0x20; } break; case 3: - if (gSaveContext.weekEventReg[37] & 0x80) { + if (gSaveContext.save.weekEventReg[37] & 0x80) { textId = 0x1281; } else { textId = 0x127F; - gSaveContext.weekEventReg[37] |= 0x80; + gSaveContext.save.weekEventReg[37] |= 0x80; } break; default: - if (gSaveContext.weekEventReg[38] & 2) { + if (gSaveContext.save.weekEventReg[38] & 2) { textId = 0x1287; } else { textId = 0x1285; - gSaveContext.weekEventReg[38] |= 2; + gSaveContext.save.weekEventReg[38] |= 2; } break; } } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } } @@ -670,15 +658,15 @@ void func_80B979DC(EnZot* this, GlobalContext* globalCtx) { } void func_80B97A44(EnZot* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x1279: case 0x127C: case 0x127F: case 0x1282: case 0x1285: case 0x1288: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x127D: @@ -708,7 +696,7 @@ void func_80B97A44(EnZot* this, GlobalContext* globalCtx) { void func_80B97B5C(EnZot* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B97A44; func_80B9787C(this, globalCtx); } else if (func_80B96DF0(this, globalCtx)) { @@ -719,28 +707,28 @@ void func_80B97B5C(EnZot* this, GlobalContext* globalCtx) { void func_80B97BF8(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { textId = 0x128C; } else { textId = 0x128B; } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B97C40(EnZot* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { func_801477B4(globalCtx); this->actionFunc = func_80B97CC8; } } void func_80B97CC8(EnZot* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B97C40; - func_801518B0(globalCtx, 0x128B, &this->actor); - } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + Message_StartTextbox(globalCtx, 0x128B, &this->actor); + } else if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { func_800B8614(&this->actor, globalCtx, 120.0f); } } @@ -755,7 +743,7 @@ void func_80B97D6C(EnZot* this, GlobalContext* globalCtx) { } if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 5.0f)) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_ZORA_WALK); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ZORA_WALK); } } @@ -779,18 +767,18 @@ void func_80B97E4C(EnZot* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.shape.rot.y; } - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x128C: this->unk_2F2 &= ~4; func_80B96BEC(this, 6, 2); - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x128D: case 0x128E: case 0x128F: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x1290: @@ -798,7 +786,7 @@ void func_80B97E4C(EnZot* this, GlobalContext* globalCtx) { this->actionFunc = func_80B97D6C; this->unk_2F2 |= 4; func_80B96BEC(this, 3, 0); - gSaveContext.weekEventReg[38] |= 8; + gSaveContext.save.weekEventReg[38] |= 8; break; case 0x128B: @@ -812,16 +800,16 @@ void func_80B97E4C(EnZot* this, GlobalContext* globalCtx) { void func_80B97FD0(EnZot* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x800, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B97E4C; func_80B97BF8(this, globalCtx); - } else if (gSaveContext.weekEventReg[38] & 8) { - if ((this->actor.xzDistToPlayer < 120.0f) && (gSaveContext.playerForm == PLAYER_FORM_ZORA)) { + } else if (gSaveContext.save.weekEventReg[38] & 8) { + if ((this->actor.xzDistToPlayer < 120.0f) && (gSaveContext.save.playerForm == PLAYER_FORM_ZORA)) { this->unk_2F2 |= 4; this->actionFunc = func_80B97E0C; func_80B96BEC(this, 6, 2); } - } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + } else if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { func_800B8614(&this->actor, globalCtx, 120.0f); } } @@ -846,38 +834,38 @@ void func_80B98178(EnZot* this, GlobalContext* globalCtx) { switch (ENZOT_GET_1F(&this->actor)) { case 6: - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { if (CURRENT_DAY == 3) { textId = 0x129D; - } else if (gSaveContext.weekEventReg[39] & 1) { + } else if (gSaveContext.save.weekEventReg[39] & 1) { textId = 0x129C; } else { textId = 0x129B; - gSaveContext.weekEventReg[39] |= 1; + gSaveContext.save.weekEventReg[39] |= 1; } - } else if (gSaveContext.weekEventReg[38] & 0x80) { + } else if (gSaveContext.save.weekEventReg[38] & 0x80) { textId = 0x1293; } else { textId = 0x1291; - gSaveContext.weekEventReg[38] |= 0x80; + gSaveContext.save.weekEventReg[38] |= 0x80; } break; case 7: - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { - if (gSaveContext.weekEventReg[39] & 4) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[39] & 4) { textId = 0x12AA; } else { textId = 0x12A6; - gSaveContext.weekEventReg[39] |= 4; + gSaveContext.save.weekEventReg[39] |= 4; } } else if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { textId = 0x12A0; - } else if (gSaveContext.weekEventReg[39] & 2) { + } else if (gSaveContext.save.weekEventReg[39] & 2) { textId = 0x12A5; } else { textId = 0x12A2; - gSaveContext.weekEventReg[39] |= 2; + gSaveContext.save.weekEventReg[39] |= 2; } break; @@ -889,25 +877,25 @@ void func_80B98178(EnZot* this, GlobalContext* globalCtx) { case 16: case 17: phi_v0 = (ENZOT_GET_1F(&this->actor) * 4) - 44; - if (gSaveContext.weekEventReg[79] & 1) { + if (gSaveContext.save.weekEventReg[79] & 1) { phi_v0 += 2; } - if (gSaveContext.playerForm != PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm != PLAYER_FORM_ZORA) { phi_v0++; } textId = phi_v0 + 0x1302; break; default: - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { textId = 0x129F; } else { textId = 0x1295; } break; } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B98348(EnZot* this, GlobalContext* globalCtx) { @@ -916,7 +904,7 @@ void func_80B98348(EnZot* this, GlobalContext* globalCtx) { if (ENZOT_GET_1F(&this->actor) == 7) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - } else if (Actor_IsActorFacingLink(&this->actor, 0x3000)) { + } else if (Actor_IsFacingPlayer(&this->actor, 0x3000)) { this->unk_2F2 &= ~8; } else { this->unk_2F2 |= 8; @@ -935,15 +923,15 @@ void func_80B98348(EnZot* this, GlobalContext* globalCtx) { void func_80B9849C(EnZot* this, GlobalContext* globalCtx) { func_80B98348(this, globalCtx); - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->unk_2D4 == 2) { - func_801518B0(globalCtx, 0x12AD, &this->actor); + Message_StartTextbox(globalCtx, 0x12AD, &this->actor); } else { - func_801518B0(globalCtx, 0x12B0, &this->actor); + Message_StartTextbox(globalCtx, 0x12B0, &this->actor); } this->actionFunc = func_80B98728; } else { - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_MINUS1); } } @@ -952,34 +940,34 @@ void func_80B9854C(EnZot* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { this->actor.parent = NULL; this->actionFunc = func_80B9849C; - this->actor.flags |= 0x10000; - func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, -1); + this->actor.flags |= ACTOR_FLAG_10000; + func_800B8500(&this->actor, globalCtx, 1000.0f, 1000.0f, EXCH_ITEM_MINUS1); } else { - func_800B8A1C(&this->actor, globalCtx, this->unk_2D4, 10000.0f, 50.0f); + Actor_PickUp(&this->actor, globalCtx, this->unk_2D4, 10000.0f, 50.0f); } } void func_80B985EC(EnZot* this, GlobalContext* globalCtx) { - s32 temp_v0; + s32 itemActionParam; Player* player = GET_PLAYER(globalCtx); func_80B98348(this, globalCtx); - if (func_80152498(&globalCtx->msgCtx) == 0x10) { - temp_v0 = func_80123810(globalCtx); - if (temp_v0 > 0) { + if (Message_GetState(&globalCtx->msgCtx) == 0x10) { + itemActionParam = func_80123810(globalCtx); + if (itemActionParam > PLAYER_AP_NONE) { func_801477B4(globalCtx); - if ((temp_v0 == 0x13) && CHECK_QUEST_ITEM(25) && func_8013A4C4(4)) { + if ((itemActionParam == PLAYER_AP_PICTO_BOX) && CHECK_QUEST_ITEM(QUEST_UNK_19) && func_8013A4C4(4)) { if (func_8013A4C4(5) && func_8013A4C4(6)) { player->actor.textId = 0x12AE; } else { player->actor.textId = 0x12AC; } - REMOVE_QUEST_ITEM(25); + REMOVE_QUEST_ITEM(QUEST_UNK_19); } else { player->actor.textId = 0x12AB; } this->actionFunc = func_80B98728; - } else if (temp_v0 < 0) { + } else if (itemActionParam < PLAYER_AP_NONE) { func_80151938(globalCtx, 0x12AB); this->actionFunc = func_80B98728; } @@ -989,9 +977,9 @@ void func_80B985EC(EnZot* this, GlobalContext* globalCtx) { void func_80B98728(EnZot* this, GlobalContext* globalCtx) { func_80B98348(this, globalCtx); - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 4: - if (func_80147624(globalCtx) && (globalCtx->msgCtx.unk11F04 == 0x1293)) { + if (Message_ShouldAdvance(globalCtx) && (globalCtx->msgCtx.currentTextId == 0x1293)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); @@ -1007,8 +995,8 @@ void func_80B98728(EnZot* this, GlobalContext* globalCtx) { break; case 5: - if (func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x1291: case 0x1292: case 0x1296: @@ -1025,7 +1013,7 @@ void func_80B98728(EnZot* this, GlobalContext* globalCtx) { case 0x12A7: case 0x12A8: case 0x12AE: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x12A9: @@ -1064,7 +1052,7 @@ void func_80B98728(EnZot* this, GlobalContext* globalCtx) { default: func_801477B4(globalCtx); this->actionFunc = func_80B98998; - this->actor.flags &= ~0x10000; + this->actor.flags &= ~ACTOR_FLAG_10000; break; } } @@ -1074,11 +1062,11 @@ void func_80B98728(EnZot* this, GlobalContext* globalCtx) { void func_80B98998(EnZot* this, GlobalContext* globalCtx) { this->unk_2F2 &= ~8; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B98728; func_80B98178(this, globalCtx); - } else if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && - Actor_IsActorFacingLink(&this->actor, 0x7000)) { + } else if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x7000)) { func_800B8614(&this->actor, globalCtx, 120.0f); } } @@ -1086,44 +1074,44 @@ void func_80B98998(EnZot* this, GlobalContext* globalCtx) { void func_80B98A4C(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { - if (gSaveContext.weekEventReg[39] & 0x80) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[39] & 0x80) { textId = 0x12B6; } else { textId = 0x12B4; - gSaveContext.weekEventReg[39] |= 0x80; + gSaveContext.save.weekEventReg[39] |= 0x80; } - } else if (gSaveContext.weekEventReg[39] & 0x40) { + } else if (gSaveContext.save.weekEventReg[39] & 0x40) { textId = 0x12B3; } else { textId = 0x12B1; - gSaveContext.weekEventReg[39] |= 0x40; + gSaveContext.save.weekEventReg[39] |= 0x40; } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B98AD0(EnZot* this, GlobalContext* globalCtx) { - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x12B1: case 0x12B4: case 0x12B7: case 0x12B9: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x12B8: func_801477B4(globalCtx); this->actionFunc = func_80B98CA8; - gSaveContext.weekEventReg[41] &= (u8)~0x20; - func_8019C300(0); + gSaveContext.save.weekEventReg[41] &= (u8)~0x20; + AudioOcarina_SetInstrumentId(OCARINA_INSTRUMENT_OFF); break; case 0x12BA: func_801477B4(globalCtx); this->actionFunc = func_80B98CA8; - gSaveContext.weekEventReg[41] |= 0x20; - func_8019C300(0); + gSaveContext.save.weekEventReg[41] |= 0x20; + AudioOcarina_SetInstrumentId(OCARINA_INSTRUMENT_OFF); break; default: @@ -1135,13 +1123,13 @@ void func_80B98AD0(EnZot* this, GlobalContext* globalCtx) { } void func_80B98BF4(EnZot* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { - this->actor.flags &= ~0x10000; - if (gSaveContext.weekEventReg[41] & 0x20) { - func_801518B0(globalCtx, 0x12B7, &this->actor); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags &= ~ACTOR_FLAG_10000; + if (gSaveContext.save.weekEventReg[41] & 0x20) { + Message_StartTextbox(globalCtx, 0x12B7, &this->actor); this->actionFunc = func_80B98AD0; } else { - func_801518B0(globalCtx, 0x12B9, &this->actor); + Message_StartTextbox(globalCtx, 0x12B9, &this->actor); this->actionFunc = func_80B98AD0; } } else { @@ -1150,46 +1138,46 @@ void func_80B98BF4(EnZot* this, GlobalContext* globalCtx) { } void func_80B98CA8(EnZot* this, GlobalContext* globalCtx) { - if (func_800B8718(&this->actor, globalCtx)) { - globalCtx->msgCtx.unk1202A = 4; - func_8019B544(0xFFFF); + if (func_800B8718(&this->actor, &globalCtx->state)) { + globalCtx->msgCtx.ocarinaMode = 4; + AudioOcarina_StartDefault(0xFFFF); this->actionFunc = func_80B98BF4; - this->actor.flags |= 0x10000; + this->actor.flags |= ACTOR_FLAG_10000; func_800B8614(&this->actor, globalCtx, 120.0f); - } else if (func_800B84D0(&this->actor, globalCtx)) { + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B98AD0; func_80B98A4C(this, globalCtx); } else { - if ((this->actor.xzDistToPlayer < 100.0f) && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx)) { + if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx)) { func_800B8614(&this->actor, globalCtx, 120.0f); } - if ((gSaveContext.playerForm == PLAYER_FORM_ZORA) || (this->actor.xzDistToPlayer < 100.0f)) { + if ((gSaveContext.save.playerForm == PLAYER_FORM_ZORA) || (this->actor.xzDistToPlayer < 100.0f)) { func_800B874C(&this->actor, globalCtx, 120.0, 100.0f); } } if (this->actor.xzDistToPlayer > 100.0f) { - gSaveContext.weekEventReg[41] &= (u8)~0x20; + gSaveContext.save.weekEventReg[41] &= (u8)~0x20; } } void func_80B98E10(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { - if (gSaveContext.weekEventReg[40] & 4) { + if (gSaveContext.save.weekEventReg[40] & 4) { textId = 0x12C5; } else { textId = 0x12C3; - gSaveContext.weekEventReg[40] |= 4; + gSaveContext.save.weekEventReg[40] |= 4; } - } else if (gSaveContext.weekEventReg[40] & 2) { + } else if (gSaveContext.save.weekEventReg[40] & 2) { textId = 0x12C2; } else { textId = 0x12C0; - gSaveContext.weekEventReg[40] |= 2; + gSaveContext.save.weekEventReg[40] |= 2; } } else { if (Flags_GetSwitch(globalCtx, this->actor.home.rot.z & 0x7F)) { @@ -1199,15 +1187,15 @@ void func_80B98E10(EnZot* this, GlobalContext* globalCtx) { textId = 0x12BE; this->unk_2F2 |= 0x10; } - } else if (gSaveContext.weekEventReg[40] & 1) { + } else if (gSaveContext.save.weekEventReg[40] & 1) { textId = 0x12BC; } else { - gSaveContext.weekEventReg[40] |= 1; + gSaveContext.save.weekEventReg[40] |= 1; this->unk_2F2 |= 4; textId = 0x12BB; } } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B98F30(EnZot* this, GlobalContext* globalCtx) { @@ -1215,7 +1203,7 @@ void func_80B98F30(EnZot* this, GlobalContext* globalCtx) { this->actor.parent = NULL; this->actionFunc = func_80B990A4; } else { - func_800B8A1C(&this->actor, globalCtx, 2, 10000.0f, 50.0f); + Actor_PickUp(&this->actor, globalCtx, GI_RUPEE_BLUE, 10000.0f, 50.0f); } } @@ -1225,15 +1213,15 @@ void func_80B98F94(EnZot* this, GlobalContext* globalCtx) { this->actor.world.rot.y = this->actor.shape.rot.y; } - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - switch (globalCtx->msgCtx.unk11F04) { + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { case 0x12BB: this->unk_2F2 &= ~4; case 0x12BC: case 0x12C0: case 0x12C3: - func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); break; case 0x12BE: @@ -1253,10 +1241,10 @@ void func_80B98F94(EnZot* this, GlobalContext* globalCtx) { void func_80B990A4(EnZot* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x400, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B98F94; func_80B98E10(this, globalCtx); - } else if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + } else if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { func_800B8614(&this->actor, globalCtx, 120.0f); } } @@ -1264,20 +1252,20 @@ void func_80B990A4(EnZot* this, GlobalContext* globalCtx) { void func_80B99160(EnZot* this, GlobalContext* globalCtx) { u16 textId; - if (gSaveContext.playerForm == PLAYER_FORM_ZORA) { - if (gSaveContext.weekEventReg[40] & 0x10) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[40] & 0x10) { textId = 0x12CD; } else { textId = 0x12CA; - gSaveContext.weekEventReg[40] |= 0x10; + gSaveContext.save.weekEventReg[40] |= 0x10; } - } else if (gSaveContext.weekEventReg[40] & 8) { + } else if (gSaveContext.save.weekEventReg[40] & 8) { textId = 0x12C9; } else { textId = 0x12C6; - gSaveContext.weekEventReg[40] |= 8; + gSaveContext.save.weekEventReg[40] |= 8; } - func_801518B0(globalCtx, textId, &this->actor); + Message_StartTextbox(globalCtx, textId, &this->actor); } void func_80B991E4(EnZot* this, GlobalContext* globalCtx) { @@ -1286,8 +1274,8 @@ void func_80B991E4(EnZot* this, GlobalContext* globalCtx) { Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); this->actor.world.rot.y = this->actor.shape.rot.y; - if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { - u16 temp = globalCtx->msgCtx.unk11F04; + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + u16 temp = globalCtx->msgCtx.currentTextId; u32 temp2; if ((temp == 0x12C6) || (temp == 0x12C7) || (temp == 0x12CA) || (temp == 0x12CB)) { @@ -1302,13 +1290,13 @@ void func_80B991E4(EnZot* this, GlobalContext* globalCtx) { } void func_80B992C0(EnZot* this, GlobalContext* globalCtx) { - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actionFunc = func_80B991E4; func_80B99160(this, globalCtx); this->actor.speedXZ = 0.0f; func_80B96BEC(this, 0, 0); } else { - if (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { + if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && (this->actor.xzDistToPlayer < 100.0f)) { func_800B8614(&this->actor, globalCtx, 120.0f); } this->actor.speedXZ = 1.5f; @@ -1323,7 +1311,7 @@ void EnZot_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnZot* this = THIS; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Collider_UpdateCylinder(&this->actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 15.0f, 30.0f, 5); @@ -1368,15 +1356,15 @@ s32 EnZot_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, s32 pad; if (limbIndex == 15) { - Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_2C4.y, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_2C4.x, MTXMODE_APPLY); - Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2C4.y, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2C4.x, MTXMODE_APPLY); + Matrix_Translate(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); } if (limbIndex == 8) { - Matrix_InsertXRotation_s(this->unk_2CA.y * -1, MTXMODE_APPLY); - Matrix_InsertZRotation_s(this->unk_2CA.x * -1, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_2CA.y * -1, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_2CA.x * -1, MTXMODE_APPLY); } if (((this->unk_2F0 == 8) || (this->unk_2F0 == 9)) && @@ -1392,15 +1380,15 @@ void EnZot_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve EnZot* this = THIS; if (limbIndex == 15) { - Matrix_MultiplyVector3fByState(&D_80B99934, &this->actor.focus.pos); + Matrix_MultVec3f(&D_80B99934, &this->actor.focus.pos); } } void EnZot_Draw(Actor* thisx, GlobalContext* globalCtx) { - UNK_PTR sp4C[] = { - &D_060050A0, - &D_060058A0, - &D_060060A0, + TexturePtr sp4C[] = { + gZoraEyeOpenTex, + gZoraEyeHalfTex, + gZoraEyeClosedTex, }; EnZot* this = THIS; diff --git a/src/overlays/actors/ovl_En_Zov/z_en_zov.c b/src/overlays/actors/ovl_En_Zov/z_en_zov.c index e4d6a51ed..4bb5f2a5a 100644 --- a/src/overlays/actors/ovl_En_Zov/z_en_zov.c +++ b/src/overlays/actors/ovl_En_Zov/z_en_zov.c @@ -1,6 +1,14 @@ -#include "z_en_zov.h" +/* + * File: z_en_zov.c + * Overlay: ovl_En_Zov + * Description: Zora Vocalist - Lulu + */ -#define FLAGS 0x00000009 +#include "z_en_zov.h" +#include "objects/object_zov/object_zov.h" +#include "overlays/actors/ovl_En_Elf/z_en_elf.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((EnZov*)thisx) @@ -9,6 +17,7 @@ void EnZov_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnZov_Update(Actor* thisx, GlobalContext* globalCtx); void EnZov_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80BD1570(EnZov* this, s16 index, u8 mode); void func_80BD187C(EnZov* this, GlobalContext* globalCtx); void func_80BD19FC(EnZov* this, GlobalContext* globalCtx); void func_80BD1BF0(EnZov* this, GlobalContext* globalCtx); @@ -17,8 +26,8 @@ void func_80BD1C84(EnZov* this, GlobalContext* globalCtx); void func_80BD1D94(EnZov* this, GlobalContext* globalCtx); void func_80BD1DB8(EnZov* this, GlobalContext* globalCtx); void func_80BD1F1C(EnZov* this, GlobalContext* globalCtx); +s32 func_80BD1FC8(GlobalContext* globalCtx, EnZov* this); -#if 0 const ActorInit En_Zov_InitVars = { ACTOR_EN_ZOV, ACTORCAT_NPC, @@ -31,63 +40,594 @@ const ActorInit En_Zov_InitVars = { (ActorFunc)EnZov_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BD26E0 = { - { 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, + }, { 20, 40, 0, { 0, 0, 0 } }, }; -#endif +static AnimationHeader* D_80BD270C[] = { + &object_zov_Anim_00D3EC, &object_zov_Anim_008120, &object_zov_Anim_00B4CC, &object_zov_Anim_00A888, + &object_zov_Anim_00C510, &object_zov_Anim_00CAA8, &object_zov_Anim_008120, &object_zov_Anim_00A888, + &object_zov_Anim_002B5C, &object_zov_Anim_00418C, &object_zov_Anim_005A6C, &object_zov_Anim_0066A4, + &object_zov_Anim_0017D4, &object_zov_Anim_0023F4, +}; -extern ColliderCylinderInit D_80BD26E0; +static Vec3f D_80BD2744 = { 400.0f, 600.0f, 0.0f }; -extern UNK_TYPE D_0600D3EC; +static Vec3f D_80BD2750 = { 400.0f, 600.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/EnZov_Init.s") +static TexturePtr D_80BD275C[] = { object_zov_Tex_013C38, object_zov_Tex_015138, object_zov_Tex_014138 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/EnZov_Destroy.s") +static TexturePtr D_80BD2768[] = { object_zov_Tex_0135F8, object_zov_Tex_014538 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD13DC.s") +static s8 D_80BD2770[] = { + 1, 2, 1, 0, 0, 1, 2, 1, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1440.s") +void EnZov_Init(Actor* thisx, GlobalContext* globalCtx) { + EnZov* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1470.s") + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zov_Skel_016258, &object_zov_Anim_00D3EC, this->jontTable, + this->morphTable, 23); + Animation_PlayLoop(&this->skelAnime, &object_zov_Anim_00D3EC); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1570.s") + this->unk_320 = 0; + this->unk_32C = -1; + this->unk_326 = -1; + this->unk_328[0] = this->actor.cutscene; + this->unk_328[1] = 0x7C; + this->unk_322 = 0; + this->actionFunc = func_80BD1C84; + this->unk_144 = func_80BD1FC8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD15A4.s") + Math_Vec3f_Copy(&this->unk_2FC, &this->actor.world.pos); + Math_Vec3f_Copy(&this->unk_308, &this->actor.world.pos); + Math_Vec3f_Copy(&this->unk_314, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD160C.s") + switch (ENZOV_GET_F(&this->actor)) { + case ENZOV_F_1: + this->actionFunc = func_80BD1F1C; + func_80BD1570(this, 9, 0); + if (!(gSaveContext.save.weekEventReg[55] & 0x80)) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1764.s") + case ENZOV_F_2: + this->actionFunc = func_80BD1C38; + this->actor.shape.shadowDraw = NULL; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD187C.s") + default: + this->unk_320 |= 2; + if ((gSaveContext.save.weekEventReg[55] & 0x80) || (gSaveContext.save.weekEventReg[53] & 0x20)) { + Actor_MarkForDeath(&this->actor); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD19FC.s") +void EnZov_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZov* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1AE0.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1BF0.s") +void func_80BD13DC(EnZov* this) { + if (this->unk_32C != -1) { + if (ActorCutscene_GetCurrentIndex() == this->unk_328[this->unk_32C]) { + ActorCutscene_Stop(this->unk_328[this->unk_32C]); + } + this->unk_32C = -1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1C38.s") +void func_80BD1440(EnZov* this, s16 arg1) { + func_80BD13DC(this); + this->unk_32C = arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1C84.s") +void func_80BD1470(EnZov* this, s16 index, u8 mode, f32 transitionRate) { + f32 frame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1D30.s") + if (((index != this->unk_322) || mode) && (index >= 0) && (index < ARRAY_COUNT(D_80BD270C))) { + switch (index) { + case 6: + frame = 30.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1D94.s") + case 7: + frame = 57.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1DB8.s") + default: + frame = 0.0f; + break; + } + Animation_Change(&this->skelAnime, D_80BD270C[index], 1.0f, frame, Animation_GetLastFrame(D_80BD270C[index]), + mode, transitionRate); + this->unk_322 = index; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1F1C.s") +void func_80BD1570(EnZov* this, s16 index, u8 mode) { + func_80BD1470(this, index, mode, 5.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD1FC8.s") +s32 func_80BD15A4(EnZov* this, GlobalContext* globalCtx) { + if ((this->actor.xzDistToPlayer < 100.0f) && Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && + Actor_IsFacingPlayer(&this->actor, 0x3000)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/EnZov_Update.s") +void func_80BD160C(EnZov* this, GlobalContext* globalCtx) { + s32 textId = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD2380.s") + if (gSaveContext.save.weekEventReg[53] & 0x20) { + this->unk_320 &= ~2; + if (gSaveContext.save.playerForm != PLAYER_FORM_ZORA) { + textId = 0x1024; + if ((this->unk_322 == 0) || (this->unk_322 == 4)) { + func_80BD1570(this, 4, 2); + } else { + func_80BD1570(this, 6, 2); + } + } else if (this->unk_320 & 4) { + textId = 0x1023; + } else { + textId = 0x1022; + this->unk_320 |= 4; + func_80BD1570(this, 3, 2); + } + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + func_80BD1570(this, 2, 2); + this->actionFunc = func_80BD19FC; + this->unk_324 = 10; + func_80BD1440(this, 0); + } else { + textId = 0x1020; + func_80BD1570(this, 5, 2); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/func_80BD2404.s") + this->unk_320 |= 1; + if (textId != 0) { + Message_StartTextbox(globalCtx, textId, &this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zov/EnZov_Draw.s") +void func_80BD1764(EnZov* this) { + if (SkelAnime_Update(&this->skelAnime)) { + switch (this->unk_322) { + case 1: + case 6: + func_80BD1570(this, 6, 2); + break; + + case 3: + case 7: + func_80BD1570(this, 7, 2); + break; + + case 4: + func_80BD1570(this, 0, 0); + break; + + case 8: + func_80BD1570(this, 9, 0); + break; + + case 10: + func_80BD1570(this, 11, 0); + break; + + case 12: + func_80BD1570(this, 13, 0); + break; + + default: + func_80BD1570(this, 0, 0); + this->unk_320 &= ~1; + break; + } + + SkelAnime_Update(&this->skelAnime); + } +} + +void func_80BD187C(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1022: + func_80151938(globalCtx, 0x1023); + break; + + case 0x1023: + if ((this->unk_322 != 6) && (this->unk_322 != 1)) { + func_80BD1570(this, 1, 2); + } + func_801477B4(globalCtx); + this->actionFunc = func_80BD1C84; + break; + + case 0x1024: + if (this->unk_322 != 6) { + func_80BD1570(this, 0, 0); + } + func_801477B4(globalCtx); + this->actionFunc = func_80BD1C84; + break; + + default: + this->unk_320 &= ~1; + func_80BD1570(this, 0, 0); + func_801477B4(globalCtx); + this->actionFunc = func_80BD1C84; + break; + } + } + break; + + case 2: + func_801477B4(globalCtx); + this->actionFunc = func_80BD1C84; + this->unk_320 &= ~1; + func_80BD1570(this, 0, 0); + break; + } +} + +void func_80BD19FC(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + if (this->unk_322 == 0) { + if (!(this->unk_320 & 2)) { + this->unk_320 |= 2; + this->unk_2EE = 3; + } + + if (this->unk_324 > 0) { + this->unk_324--; + } else { + func_80BD13DC(this); + Message_StartTextbox(globalCtx, 0x1021, &this->actor); + ((EnElf*)(GET_PLAYER(globalCtx)->tatlActor))->unk_264 |= 4; + Actor_ChangeFocus(&this->actor, globalCtx, GET_PLAYER(globalCtx)->tatlActor); + this->actionFunc = func_80BD187C; + } + } else if (Animation_OnFrame(&this->skelAnime, 10.0f)) { + this->unk_320 &= ~2; + this->unk_2EE = 3; + } +} + +s32 func_80BD1AE0(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + + if (Cutscene_CheckActorAction(globalCtx, 504)) { + s16 action = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 504)]->action; + + if (action != this->unk_326) { + this->unk_326 = action; + switch (this->unk_326) { + case 1: + func_80BD1570(this, 0, 0); + break; + + case 2: + func_80BD1570(this, 8, 2); + this->unk_320 |= 0x10; + break; + + case 3: + func_80BD1470(this, 10, 2, 0.0f); + break; + + case 4: + func_80BD1570(this, 12, 2); + break; + } + } + return true; + } + + return false; +} + +void func_80BD1BF0(EnZov* this, GlobalContext* globalCtx) { + if (!func_80BD1AE0(this, globalCtx)) { + func_80BD1570(this, 0, 0); + this->actionFunc = func_80BD1C84; + } +} + +void func_80BD1C38(EnZov* this, GlobalContext* globalCtx) { + if (func_80BD1AE0(this, globalCtx)) { + Cutscene_ActorTranslateAndYaw(&this->actor, globalCtx, Cutscene_GetActorActionIndex(globalCtx, 504)); + } +} + +void func_80BD1C84(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BD187C; + func_80BD160C(this, globalCtx); + } else if (func_80BD15A4(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } + + if (Cutscene_CheckActorAction(globalCtx, 0x1F8)) { + this->actionFunc = func_80BD1BF0; + func_80BD1BF0(this, globalCtx); + } +} + +void func_80BD1D30(EnZov* this, GlobalContext* globalCtx) { + u16 textId; + + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[79] & 1) { + textId = 0x1032; + } else { + textId = 0x1033; + } + } else { + textId = 0x1031; + } + Message_StartTextbox(globalCtx, textId, &this->actor); +} + +void func_80BD1D94(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); +} + +void func_80BD1DB8(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if ((Message_GetState(&globalCtx->msgCtx) == 5) && Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x1033: + case 0x1034: + case 0x1035: + case 0x1036: + case 0x1037: + case 0x1038: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + case 0x1039: + globalCtx->nextEntranceIndex = globalCtx->setupExitList[ENZOV_GET_FE00(&this->actor)]; + globalCtx->unk_1887F = 5; + globalCtx->sceneLoadFlag = 0x14; + gSaveContext.save.weekEventReg[78] |= 1; + this->actionFunc = func_80BD1D94; + globalCtx->msgCtx.unk11F10 = 0; + Audio_QueueSeqCmd(0x101400FF); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = func_80BD1F1C; + break; + } + } +} + +void func_80BD1F1C(EnZov* this, GlobalContext* globalCtx) { + func_80BD1764(this); + + if (this->actor.home.rot.y != this->actor.shape.rot.y) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 2, 0x1000, 0x200); + this->actor.world.rot.y = this->actor.shape.rot.y; + } + + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BD1DB8; + func_80BD1D30(this, globalCtx); + } else if (func_80BD15A4(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +s32 func_80BD1FC8(GlobalContext* globalCtx, EnZov* this) { + s32 ret; + s32 pad; + + ret = func_8013A530(globalCtx, &this->actor, 4, &this->actor.focus.pos, &this->actor.shape.rot, 10.0f, 300.0f, -1); + ret |= func_8013A530(globalCtx, &this->actor, 5, &this->unk_308, &this->actor.shape.rot, 50.0f, 160.0f, 0x3000); + ret |= func_8013A530(globalCtx, &this->actor, 6, &this->unk_314, &this->actor.shape.rot, 50.0f, 160.0f, 0x3000); + return ret; +} + +void EnZov_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZov* this = THIS; + + Actor_MoveWithGravity(&this->actor); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 4); + + this->actionFunc(this, globalCtx); + + if (!Cutscene_CheckActorAction(globalCtx, 0x1F8)) { + this->unk_320 &= ~0x10; + } + + if ((this->unk_320 & 1) && func_80BD15A4(this, globalCtx)) { + func_800E9250(globalCtx, &this->actor, &this->unk_2F0, &this->unk_2F6, this->actor.focus.pos); + } else { + if ((this->unk_320 & 0x10) && (this->unk_322 == 0)) { + Math_SmoothStepToS(&this->unk_2F0.x, -0x1B58, 6, 0x1838, 0x64); + } else { + Math_SmoothStepToS(&this->unk_2F0.x, 0, 6, 0x1838, 0x64); + } + Math_SmoothStepToS(&this->unk_2F0.y, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_2F6.x, 0, 6, 0x1838, 0x64); + Math_SmoothStepToS(&this->unk_2F6.y, 0, 6, 0x1838, 0x64); + } + + if (DECR(this->unk_2EE) == 0) { + this->unk_2EE = Rand_S16Offset(60, 60); + } + + this->unk_2EC = this->unk_2EE; + if (this->unk_2EC >= 3) { + this->unk_2EC = 0; + } + + if ((this->unk_32C != -1) && (ActorCutscene_GetCurrentIndex() != this->unk_328[this->unk_32C])) { + if ((this->unk_32C == 0) && (ActorCutscene_GetCurrentIndex() == 0x7C)) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_328[this->unk_32C]); + } else if (ActorCutscene_GetCanPlayNext(this->unk_328[this->unk_32C])) { + ActorCutscene_Start(this->unk_328[this->unk_32C], &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->unk_328[this->unk_32C]); + } + } +} + +s32 EnZov_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnZov* this = THIS; + + if (limbIndex == 12) { + rot->x += this->unk_2F0.y; + if ((this->unk_320 & 0x10) && (this->unk_322 == 0)) { + rot->z += this->unk_2F0.x; + } + } + + if (limbIndex == 11) { + rot->x += this->unk_2F6.y; + } + return false; +} + +void EnZov_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnZov* this = THIS; + + if (limbIndex == 12) { + Matrix_MultVec3f(&D_80BD2744, &this->actor.focus.pos); + Math_Vec3f_Copy(&this->unk_2FC, &this->actor.focus.pos); + this->unk_2FC.y += 10.0f; + } + + if (limbIndex == 18) { + Matrix_MultVec3f(&D_80BD2750, &this->unk_308); + } + + if (limbIndex == 13) { + Matrix_MultVec3f(&D_80BD2750, &this->unk_314); + } +} + +void EnZov_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnZov* this = THIS; + Gfx* gfx; + s32 curFrame; + s32 phi_a1; + u8 phi_v1; + + if (1) {} + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + phi_a1 = 0; + curFrame = this->skelAnime.curFrame; + phi_v1 = this->unk_2EC; + + switch (this->unk_322) { + case 0: + if ((this->unk_2EC == 0) && !(this->unk_320 & 0x10)) { + phi_v1 = 1; + } + break; + + case 5: + if (this->unk_2EC == 0) { + phi_v1 = 1; + } + break; + + case 2: + if (curFrame < 23) { + phi_v1 = 0; + } else if (curFrame >= 26) { + phi_v1 = 1; + } else if (curFrame == 24) { + phi_v1 = 0; + } else { + phi_v1 = 1; + } + break; + + case 3: + case 7: + if (curFrame <= 50) { + if (curFrame < 43) { + phi_v1 = 0; + } else { + phi_v1 = D_80BD2770[(curFrame - 43) & 3]; + } + } + phi_a1 = 1; + break; + + case 4: + if ((curFrame < 14) || (curFrame >= 24)) { + phi_v1 = 1; + } else { + phi_v1 = D_80BD2770[4 + ((curFrame - 14) & 3)]; + } + phi_a1 = 1; + break; + + case 8: + phi_v1 = 0; + break; + + case 9: + phi_v1 = 0; + phi_a1 = 1; + break; + } + + gfx = POLY_OPA_DISP; + gSPSegment(&gfx[0], 0x09, Lib_SegmentedToVirtual(D_80BD275C[phi_v1])); + gSPSegment(&gfx[1], 0x08, Lib_SegmentedToVirtual(D_80BD2768[phi_a1])); + POLY_OPA_DISP = &gfx[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnZov_OverrideLimbDraw, EnZov_PostLimbDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Zov/z_en_zov.h b/src/overlays/actors/ovl_En_Zov/z_en_zov.h index 2a4650544..ce1cc9d0f 100644 --- a/src/overlays/actors/ovl_En_Zov/z_en_zov.h +++ b/src/overlays/actors/ovl_En_Zov/z_en_zov.h @@ -6,10 +6,34 @@ struct EnZov; typedef void (*EnZovActionFunc)(struct EnZov*, GlobalContext*); +typedef s32 (*EnZovUnkFunc)(GlobalContext*, struct EnZov*); + +#define ENZOV_GET_F(thisx) ((thisx)->params & 0xF) +#define ENZOV_GET_FE00(thisx) (((thisx)->params & 0xFE00) >> 9) + +#define ENZOV_F_1 1 +#define ENZOV_F_2 2 typedef struct EnZov { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1EC]; + /* 0x0144 */ EnZovUnkFunc unk_144; + /* 0x0148 */ Vec3s jontTable[23]; + /* 0x01D2 */ Vec3s morphTable[23]; + /* 0x025C */ SkelAnime skelAnime; + /* 0x02A0 */ ColliderCylinder collider; + /* 0x02EC */ s16 unk_2EC; + /* 0x02EE */ s16 unk_2EE; + /* 0x02F0 */ Vec3s unk_2F0; + /* 0x02F6 */ Vec3s unk_2F6; + /* 0x02FC */ Vec3f unk_2FC; + /* 0x0308 */ Vec3f unk_308; + /* 0x0314 */ Vec3f unk_314; + /* 0x0320 */ u16 unk_320; + /* 0x0322 */ s16 unk_322; + /* 0x0324 */ s16 unk_324; + /* 0x0326 */ s16 unk_326; + /* 0x0328 */ s16 unk_328[2]; + /* 0x032C */ s16 unk_32C; /* 0x0330 */ EnZovActionFunc actionFunc; } EnZov; // size = 0x334 diff --git a/src/overlays/actors/ovl_En_Zow/z_en_zow.c b/src/overlays/actors/ovl_En_Zow/z_en_zow.c index 9fd768879..d29141499 100644 --- a/src/overlays/actors/ovl_En_Zow/z_en_zow.c +++ b/src/overlays/actors/ovl_En_Zow/z_en_zow.c @@ -1,6 +1,13 @@ -#include "z_en_zow.h" +/* + * File: z_en_zow.c + * Overlay: ovl_En_Zow + * Description: Great Bay - Zora Complaining About Water + */ -#define FLAGS 0x00000019 +#include "z_en_zow.h" +#include "objects/object_zo/object_zo.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10) #define THIS ((EnZow*)thisx) @@ -15,7 +22,6 @@ void func_80BDD634(EnZow* this, GlobalContext* globalCtx); void func_80BDD6BC(EnZow* this, GlobalContext* globalCtx); void func_80BDD79C(EnZow* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Zow_InitVars = { ACTOR_EN_ZOW, ACTORCAT_NPC, @@ -28,72 +34,617 @@ const ActorInit En_Zow_InitVars = { (ActorFunc)EnZow_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BDDCF0 = { - { 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_80BDDD1C = { 0.0f, 1.0f, 0.0f }; -extern ColliderCylinderInit D_80BDDCF0; +Vec3f D_80BDDD28 = { 0.0f, -1.0f, 0.0f }; -extern UNK_TYPE D_06002A50; -extern UNK_TYPE D_06002C10; -extern UNK_TYPE D_06004248; -extern UNK_TYPE D_0600D288; +void func_80BDC270(EnZowStruct* ptr, Vec3f* arg1, f32 arg2, f32 arg3, u8 arg4) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC270.s") + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 1; + ptr->unk_14 = *arg1; + ptr->unk_04 = arg2; + ptr->unk_08 = arg3; + ptr->unk_0F = arg4; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC2D8.s") +void func_80BDC2D8(EnZow* this, EnZowStruct* ptr, Vec3f* arg2) { + s16 i; + f32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC3C0.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++, ptr++) { + if (ptr->unk_00 == 0) { + temp = this->actor.world.pos.y + this->actor.depthInWater; + if (temp <= arg2->y) { + continue; + } + ptr->unk_00 = 3; + ptr->unk_14 = *arg2; + ptr->unk_20 = *arg2; + ptr->unk_2C = D_80BDDD1C; + ptr->unk_04 = ((Rand_ZeroOne() - 0.5f) * 0.02f) + 0.12f; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC50C.s") +void func_80BDC3C0(EnZowStruct* ptr, Vec3f* arg1, Vec3f* arg2, f32 arg3) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC5C8.s") + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 != 2) { + ptr->unk_00 = 2; + ptr->unk_14 = *arg1; + ptr->unk_20 = D_80BDDD28; + ptr->unk_2C = *arg2; + ptr->unk_0F = (Rand_ZeroOne() * 100.0f) + 100.0f; + ptr->unk_04 = arg3; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC6F8.s") +void func_80BDC50C(EnZowStruct* ptr) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC830.s") + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 == 1) { + Math_ApproachF(&ptr->unk_04, ptr->unk_08, 0.2f, 0.8f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDC9DC.s") + if (ptr->unk_0F > 20) { + ptr->unk_0F -= 20; + } else { + ptr->unk_0F = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDCB84.s") + if (ptr->unk_0F == 0) { + ptr->unk_00 = 0; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDCD38.s") +void func_80BDC5C8(EnZow* this, EnZowStruct* ptr) { + f32 temp_f2; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDCDA8.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++, ptr++) { + if (ptr->unk_00 == 3) { + ptr->unk_14.x = ((Rand_ZeroOne() * 0.5f) - 0.25f) + ptr->unk_20.x; + ptr->unk_14.z = ((Rand_ZeroOne() * 0.5f) - 0.25f) + ptr->unk_20.z; + ptr->unk_14.y += ptr->unk_2C.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/EnZow_Init.s") + temp_f2 = this->actor.world.pos.y + this->actor.depthInWater; + if (temp_f2 <= ptr->unk_14.y) { + ptr->unk_00 = 0; + ptr->unk_14.y = temp_f2; + func_80BDC270(ptr, &ptr->unk_14, 0.06f, 0.12f, 200); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/EnZow_Destroy.s") +void func_80BDC6F8(EnZow* this, EnZowStruct* ptr) { + s16 i; + f32 temp_f0_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD04C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++, ptr++) { + if (ptr->unk_00 == 2) { + ptr->unk_14.x += ptr->unk_2C.x; + ptr->unk_14.y += ptr->unk_2C.y; + ptr->unk_14.z += ptr->unk_2C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD154.s") + if (ptr->unk_2C.y >= -20.0f) { + ptr->unk_2C.y += ptr->unk_20.y; + } else { + ptr->unk_2C.y = -20.0f; + ptr->unk_20.y = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD1E0.s") + temp_f0_2 = this->actor.world.pos.y + this->actor.depthInWater; + if (ptr->unk_14.y < temp_f0_2) { + ptr->unk_00 = 0; + ptr->unk_14.y = temp_f0_2; + func_80BDC270(ptr, &ptr->unk_14, 0.06f, 0.12f, 200); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD350.s") +void func_80BDC830(EnZowStruct* ptr, GlobalContext* globalCtx) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD490.s") + OPEN_DISPS(globalCtx->state.gfxCtx); + u8 flag = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD570.s") + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD634.s") + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 == 1) { + if (!flag) { + gDPPipeSync(POLY_XLU_DISP++); + gSPDisplayList(POLY_XLU_DISP++, object_zo_DL_00D220); + gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0); + if (1) {} + flag = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD6BC.s") + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, ptr->unk_0F); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDD79C.s") + Matrix_Translate(ptr->unk_14.x, ptr->unk_14.y, ptr->unk_14.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_04, 1.0f, ptr->unk_04, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/EnZow_Update.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_zo_DL_00D288); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDDA7C.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDDAA0.s") +void func_80BDC9DC(EnZowStruct* ptr, GlobalContext* globalCtx) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/func_80BDDAE0.s") + OPEN_DISPS(globalCtx->state.gfxCtx); + u8 flag = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zow/EnZow_Draw.s") + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 == 3) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, object_zo_DL_0029F0); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 150, 150, 150, 0); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + if (1) {} + flag = true; + } + + Matrix_Translate(ptr->unk_14.x, ptr->unk_14.y, ptr->unk_14.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(ptr->unk_04, ptr->unk_04, 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_zo_DL_002A50); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80BDCB84(EnZowStruct* ptr, GlobalContext* globalCtx) { + s16 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + u8 flag = false; + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 15; i++, ptr++) { + if (ptr->unk_00 == 2) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, object_zo_DL_002BA0); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 200, 0); + if (1) {} + flag = true; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 180, 180, 180, ptr->unk_0F); + + Matrix_Translate(ptr->unk_14.x, ptr->unk_14.y, ptr->unk_14.z, MTXMODE_NEW); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_Scale(ptr->unk_04, ptr->unk_04, 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_zo_DL_002C10); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80BDCD38(EnZow* this, EnZowStruct* ptr, f32 arg2, f32 arg3, u8 arg4) { + static Vec3f D_80BDDD34 = { 0.0f, 0.0f, 0.0f }; + + D_80BDDD34.x = this->actor.world.pos.x; + D_80BDDD34.y = this->actor.world.pos.y + this->actor.depthInWater; + D_80BDDD34.z = this->actor.world.pos.z; + func_80BDC270(ptr, &D_80BDDD34, arg2, arg3, arg4); +} + +void func_80BDCDA8(EnZow* this, EnZowStruct* ptr) { + Vec3f sp84; + Vec3f sp78; + f32 temp_f20; + f32 temp_f22; + s32 i; + + for (i = 0; i < 10; i++) { + temp_f20 = (Rand_ZeroOne() * 1.5f) + 0.5f; + temp_f22 = Rand_ZeroOne() * 6.28f; + + sp78.y = (Rand_ZeroOne() * 3.0f) + 3.0f; + sp78.x = sinf(temp_f22) * temp_f20; + sp78.z = cosf(temp_f22) * temp_f20; + + sp84 = this->actor.world.pos; + sp84.x += sp78.x * 6.0f; + sp84.z += sp78.z * 6.0f; + sp84.y += this->actor.depthInWater; + + func_80BDC3C0(ptr, &sp84, &sp78, 0.08f); + } +} + +void EnZow_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZow* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 20.0f); + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = func_80BDD79C; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gZoraSkel, &gZoraIdleAnim, this->jointTable, this->morphTable, 20); + Animation_PlayOnce(&this->skelAnime, &gZoraSurfacingAnim); + this->unk_2C8 = 1; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.shape.rot.z = 0; + this->unk_2CA = 0; + this->unk_2CC = 0; + this->unk_2CE = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.textId = 0; + this->actor.world.rot.z = this->actor.shape.rot.z; + this->actor.flags &= ~ACTOR_FLAG_1; +} + +void EnZow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZow* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +AnimationHeader* sAnimations[] = { &object_zo_Anim_004168, &gZoraSurfacingAnim, &gZoraSurfacingAnim }; + +void func_80BDD04C(EnZow* this, s16 arg1, u8 arg2) { + if ((arg1 >= 0) && (arg1 < 3)) { + if (arg1 < 2) { + Animation_Change(&this->skelAnime, sAnimations[arg1], 1.0f, 0.0f, Animation_GetLastFrame(sAnimations[arg1]), + arg2, -5.0f); + } else { + Animation_Change(&this->skelAnime, sAnimations[arg1], -1.0f, Animation_GetLastFrame(sAnimations[arg1]), + 0.0f, arg2, 0.0f); + } + this->unk_2C8 = arg1; + } +} + +s32 func_80BDD154(EnZow* this, GlobalContext* globalCtx) { + if (Player_IsFacingActor(&this->actor, 0x3000, globalCtx) && Actor_IsFacingPlayer(&this->actor, 0x3000) && + (this->actor.xzDistToPlayer < 170.0f) && (fabsf(this->actor.playerHeightRel) < 100.0f)) { + return true; + } + return false; +} + +void func_80BDD1E0(EnZow* this, GlobalContext* globalCtx) { + u16 phi_a1; + + if (ENZOW_GET_F(&this->actor) == ENZOW_F_1) { + if (gSaveContext.save.weekEventReg[55] & 0x80) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[78] & 4) { + phi_a1 = 0x12FD; + } else { + phi_a1 = 0x12FA; + gSaveContext.save.weekEventReg[78] |= 4; + } + } else if (gSaveContext.save.weekEventReg[78] & 0x10) { + phi_a1 = 0x1301; + } else { + gSaveContext.save.weekEventReg[78] |= 0x10; + phi_a1 = 0x12FF; + } + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[78] & 8) { + phi_a1 = 0x12F8; + } else { + phi_a1 = 0x12F3; + gSaveContext.save.weekEventReg[78] |= 8; + } + } else if (gSaveContext.save.weekEventReg[78] & 0x10) { + phi_a1 = 0x1301; + } else { + gSaveContext.save.weekEventReg[78] |= 0x10; + phi_a1 = 0x12FF; + } + } else if (gSaveContext.save.weekEventReg[55] & 0x80) { + if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + phi_a1 = 0x12EC; + } else { + phi_a1 = 0x12F1; + } + } else if (gSaveContext.save.playerForm == PLAYER_FORM_ZORA) { + if (gSaveContext.save.weekEventReg[78] & 2) { + phi_a1 = 0x12EB; + } else { + phi_a1 = 0x12E8; + gSaveContext.save.weekEventReg[78] |= 2; + } + } else { + phi_a1 = 0x12EF; + } + Message_StartTextbox(globalCtx, phi_a1, &this->actor); +} + +void func_80BDD350(EnZow* this, GlobalContext* globalCtx) { + if (this->unk_2CA & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DIVE_WATER); + func_80BDCDA8(this, this->unk_2D0); + this->actor.flags &= ~ACTOR_FLAG_1; + this->skelAnime.playSpeed = 0.0f; + this->actor.velocity.y = -4.0f; + } + + if (this->actor.depthInWater > 120.0f) { + Math_ApproachF(&this->actor.velocity.y, 0.0f, 0.4f, 0.6f); + if (this->actor.velocity.y > -0.1f) { + this->actor.velocity.y = 0.0f; + this->actionFunc = func_80BDD79C; + } + } + + if ((this->actor.bgCheckFlags & 1) || (this->actor.depthInWater > 180.0f)) { + this->actor.velocity.y = 0.0f; + this->actionFunc = func_80BDD79C; + } + + if (this->skelAnime.playSpeed <= 0.0f) { + if (this->unk_2CE >= 6) { + this->unk_2CE -= 5; + return; + } else { + this->unk_2CE = 0; + } + } +} + +void func_80BDD490(EnZow* this, GlobalContext* globalCtx) { + this->actor.velocity.y = 0.0f; + if (this->actor.xzDistToPlayer > 440.0f) { + this->actionFunc = func_80BDD350; + func_80BDD04C(this, 2, 2); + } else if (this->unk_2CA & 2) { + func_80BDD04C(this, 0, 0); + } + + if ((globalCtx->gameplayFrames & 7) == 0) { + func_80BDCD38(this, this->unk_2D0, 0.2f, 1.0f, 200); + } + + if (this->unk_2CE < 245) { + this->unk_2CE += 10; + } else { + this->unk_2CE = 255; + } +} + +void func_80BDD570(EnZow* this, GlobalContext* globalCtx) { + func_80BDD490(this, globalCtx); + + switch (Message_GetState(&globalCtx->msgCtx)) { + case 5: + if (Message_ShouldAdvance(globalCtx)) { + switch (globalCtx->msgCtx.currentTextId) { + case 0x12E8: + case 0x12E9: + case 0x12EC: + case 0x12ED: + case 0x12EF: + case 0x12F1: + case 0x12F3: + case 0x12F4: + case 0x12F5: + case 0x12F6: + case 0x12F8: + case 0x12FA: + case 0x12FB: + case 0x12FD: + case 0x12FF: + func_80151938(globalCtx, globalCtx->msgCtx.currentTextId + 1); + break; + + default: + func_801477B4(globalCtx); + break; + } + } + break; + + case 2: + this->actionFunc = func_80BDD634; + break; + } +} + +void func_80BDD634(EnZow* this, GlobalContext* globalCtx) { + func_80BDD490(this, globalCtx); + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actionFunc = func_80BDD570; + func_80BDD1E0(this, globalCtx); + } else if (func_80BDD154(this, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 180.0f); + } +} + +void func_80BDD6BC(EnZow* this, GlobalContext* globalCtx) { + if (this->unk_2CE < 245) { + this->unk_2CE += 10; + } else { + this->unk_2CE = 255; + } + + if (this->actor.depthInWater < 54.0f) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_OUT_OF_WATER); + func_80BDCDA8(this, this->unk_2D0); + func_80BDD04C(this, 1, 2); + this->actor.flags |= ACTOR_FLAG_1; + this->actor.velocity.y = 0.0f; + this->actionFunc = func_80BDD634; + } else if (this->actor.depthInWater < 80.0f) { + Math_ApproachF(&this->actor.velocity.y, 2.0f, 0.4f, 0.6f); + } +} + +void func_80BDD79C(EnZow* this, GlobalContext* globalCtx) { + if (this->actor.xzDistToPlayer < 400.0f) { + this->actor.velocity.y = 4.0f; + this->actionFunc = func_80BDD6BC; + } + + if (this->unk_2CE >= 6) { + this->unk_2CE -= 5; + } else { + this->unk_2CE = 0; + } + + if (this->actor.depthInWater > 180.0f) { + this->actor.world.pos.y = this->actor.world.pos.y + -180.0f + this->actor.depthInWater; + } +} + +void EnZow_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZow* this = THIS; + Vec3f sp34; + + Actor_MoveWithGravity(&this->actor); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 15.0f, 30.0f, 5); + + if (this->unk_2CE != 0) { + this->unk_2CA &= ~2; + if (SkelAnime_Update(&this->skelAnime)) { + this->unk_2CA |= 2; + } + } else { + this->unk_2CA |= 2; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0x800, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + + this->actionFunc(this, globalCtx); + + if (this->unk_2CE != 0) { + if ((globalCtx->state.frames & 8) != 0) { + sp34 = this->actor.world.pos; + sp34.y += ((Rand_ZeroOne() - 0.5f) * 10.0f) + 18.0f; + sp34.x += (Rand_ZeroOne() - 0.5f) * 28.0f; + sp34.z += (Rand_ZeroOne() - 0.5f) * 28.0f; + func_80BDC2D8(this, this->unk_2D0, &sp34); + } + + if (DECR(this->unk_2C6) == 0) { + this->unk_2C6 = Rand_S16Offset(60, 60); + } + + this->unk_2C4 = this->unk_2C6; + if (this->unk_2C4 >= 3) { + this->unk_2C4 = 0; + } + } + + this->actor.shape.shadowAlpha = this->unk_2CE; + func_80BDC50C(this->unk_2D0); + func_80BDC5C8(this, this->unk_2D0); + func_80BDC6F8(this, this->unk_2D0); +} + +Gfx* func_80BDDA7C(GraphicsContext* gfxCtx) { + Gfx* gfx = GRAPH_ALLOC(gfxCtx, sizeof(Gfx) * 2); + + gSPEndDisplayList(gfx); + + return gfx; +} + +Vec3f D_80BDDD4C = { 400.0f, 0.0f, 0.0f }; + +void func_80BDDAA0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + if (limbIndex == 15) { + Matrix_MultVec3f(&D_80BDDD4C, &thisx->focus.pos); + } +} + +void func_80BDDAE0(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + func_80BDDAA0(globalCtx, limbIndex, dList, rot, thisx); +} + +void EnZow_Draw(Actor* thisx, GlobalContext* globalCtx) { + TexturePtr sp54[] = { + gZoraEyeOpenTex, + gZoraEyeHalfTex, + gZoraEyeClosedTex, + }; + EnZow* this = THIS; + + Matrix_Push(); + + func_80BDC830(this->unk_2D0, globalCtx); + func_80BDC9DC(this->unk_2D0, globalCtx); + func_80BDCB84(this->unk_2D0, globalCtx); + + Matrix_Pop(); + + if (this->unk_2CE != 0) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_2CE >= 255) { + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sp54[this->unk_2C4])); + gSPSegment(POLY_OPA_DISP++, 0x0C, func_80BDDA7C(globalCtx->state.gfxCtx)); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, func_80BDDAA0, &this->actor); + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(sp54[this->unk_2C4])); + + func_800BDAA0(globalCtx, &this->skelAnime, NULL, func_80BDDAE0, &this->actor, this->unk_2CE); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Zow/z_en_zow.h b/src/overlays/actors/ovl_En_Zow/z_en_zow.h index 976e4e29b..e169e2816 100644 --- a/src/overlays/actors/ovl_En_Zow/z_en_zow.h +++ b/src/overlays/actors/ovl_En_Zow/z_en_zow.h @@ -7,9 +7,35 @@ struct EnZow; typedef void (*EnZowActionFunc)(struct EnZow*, GlobalContext*); +#define ENZOW_GET_F(thisx) ((thisx)->params & 0xF) + +#define ENZOW_F_1 1 + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ UNK_TYPE1 unk_0C[0x3]; + /* 0x0F */ u8 unk_0F; + /* 0x10 */ UNK_TYPE1 unk_10[0x4]; + /* 0x14 */ Vec3f unk_14; + /* 0x20 */ Vec3f unk_20; + /* 0x2C */ Vec3f unk_2C; +} EnZowStruct; // size = 0x38 + typedef struct EnZow { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4D4]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ ColliderCylinder collider; + /* 0x01D4 */ Vec3s jointTable[20]; + /* 0x024C */ Vec3s morphTable[20]; + /* 0x02C4 */ s16 unk_2C4; + /* 0x02C6 */ s16 unk_2C6; + /* 0x02C8 */ s16 unk_2C8; + /* 0x02CA */ u16 unk_2CA; + /* 0x02CC */ s16 unk_2CC; + /* 0x02CE */ s16 unk_2CE; + /* 0x02D0 */ EnZowStruct unk_2D0[15]; /* 0x0618 */ EnZowActionFunc actionFunc; } EnZow; // size = 0x61C diff --git a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c index 453f912e4..d02bb91da 100644 --- a/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c +++ b/src/overlays/actors/ovl_Item_B_Heart/z_item_b_heart.c @@ -5,6 +5,7 @@ */ #include "z_item_b_heart.h" +#include "objects/object_gi_hearts/object_gi_hearts.h" #define FLAGS 0x00000000 @@ -36,13 +37,10 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), }; -extern Gfx D_06001290[]; -extern Gfx D_06001470[]; - void ItemBHeart_Init(Actor* thisx, GlobalContext* globalCtx) { ItemBHeart* this = THIS; - if (Actor_GetCollectibleFlag(globalCtx, 0x1F)) { + if (Flags_GetCollectible(globalCtx, 0x1F)) { Actor_MarkForDeath(&this->actor); return; } @@ -69,10 +67,10 @@ void ItemBHeart_Update(Actor* thisx, GlobalContext* globalCtx) { if (!(this->unk_168 < 0.5f)) { if (Actor_HasParent(&this->actor, globalCtx)) { - Actor_SetCollectibleFlag(globalCtx, 0x1F); + Flags_SetCollectible(globalCtx, 0x1F); Actor_MarkForDeath(&this->actor); } else { - func_800B8A1C(&this->actor, globalCtx, 0xD, 30.0f, 80.0f); + Actor_PickUp(&this->actor, globalCtx, GI_HEART_CONTAINER, 30.0f, 80.0f); } } } @@ -90,7 +88,7 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - blueWarpActor = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first; + blueWarpActor = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; while (blueWarpActor != NULL) { if ((blueWarpActor->id == ACTOR_DOOR_WARP1) && (blueWarpActor->projectedPos.z > this->actor.projectedPos.z)) { @@ -103,13 +101,13 @@ void ItemBHeart_Draw(Actor* thisx, GlobalContext* globalCtx) { if (flag || thisx->world.rot.y != 0) { 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++, D_06001290); - gSPDisplayList(POLY_XLU_DISP++, D_06001470); + gSPDisplayList(POLY_XLU_DISP++, object_gi_hearts_DL_001290); + gSPDisplayList(POLY_XLU_DISP++, object_gi_hearts_DL_001470); } else { 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_06001290); - gSPDisplayList(POLY_OPA_DISP++, D_06001470); + gSPDisplayList(POLY_OPA_DISP++, object_gi_hearts_DL_001290); + gSPDisplayList(POLY_OPA_DISP++, object_gi_hearts_DL_001470); } CLOSE_DISPS(globalCtx->state.gfxCtx); 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 66a68363a..82b29e716 100644 --- a/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -1,6 +1,12 @@ +/* + * File: z_item_etcetera.c + * Overlay: ovl_Item_Etcetera + * Description: Leftover OoT Collectible Items (bottle, key, Fire Arrow, etc.) + */ + #include "z_item_etcetera.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ItemEtcetera*)thisx) diff --git a/src/overlays/actors/ovl_Item_Inbox/z_item_inbox.c b/src/overlays/actors/ovl_Item_Inbox/z_item_inbox.c index 8bcb67a98..7017dfcec 100644 --- a/src/overlays/actors/ovl_Item_Inbox/z_item_inbox.c +++ b/src/overlays/actors/ovl_Item_Inbox/z_item_inbox.c @@ -1,6 +1,12 @@ +/* + * File: z_item_inbox.c + * Overlay: ovl_Item_Inbox + * Description: + */ + #include "z_item_inbox.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((ItemInbox*)thisx) @@ -34,7 +40,7 @@ void ItemInbox_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void ItemInbox_Idle(ItemInbox* this, GlobalContext* globalCtx) { - if (Actor_GetChestFlag(globalCtx, (this->actor.params >> 8) & 0x1F)) { + if (Flags_GetTreasure(globalCtx, (this->actor.params >> 8) & 0x1F)) { Actor_MarkForDeath(&this->actor); } } 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 b9aee5f76..eee9de294 100644 --- a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c +++ b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c @@ -1,6 +1,14 @@ -#include "z_mir_ray.h" +/* + * File: z_mir_ray.c + * Overlay: ovl_Mir_Ray + * Description: Reflectible light ray (unused, somewhat broken) + * Note: This actor is unchanged from OoT, and will not work correctly + */ -#define FLAGS 0x00000030 +#include "z_mir_ray.h" +#include "objects/object_mir_ray/object_mir_ray.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((MirRay*)thisx) @@ -9,7 +17,30 @@ void MirRay_Destroy(Actor* thisx, GlobalContext* globalCtx); void MirRay_Update(Actor* thisx, GlobalContext* globalCtx); void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +s32 MirRay_CheckInFrustum(Vec3f* vecA, Vec3f* vecB, f32 pointx, f32 pointy, f32 pointz, s16 radiusA, s16 radiusB); + +typedef struct { + /* 0x00 */ Vec3f pos; + /* 0x0C */ MtxF mtx; + /* 0x4C */ CollisionPoly* reflectionPoly; + /* 0x50 */ u8 opacity; +} MirRayShieldReflection; // size = 0x54 + +typedef struct { + /* 0x00 */ Vec3s sourcePoint; + /* 0x06 */ Vec3s poolPoint; // point at center of light pool on floor for windows and BigMirror, same as source + // point for Cobra Mirror + /* 0x0C */ s16 sourceEndRadius; // Radius of beam frustum at the source end + /* 0x0E */ s16 poolEndRadius; // Radius of beam frustum at the pool end + /* 0x10 */ f32 unk_10; // placement of collider center along beam + /* 0x14 */ s16 unk_14; // collider radius before scaled + /* 0x16 */ s16 lgtPtMaxRad; // light point max radius + /* 0x18 */ f32 unk_18; // placement of light point between source and reflection point (pool point for windows, + // player for mirrors) + /* 0x1C */ Color_RGB8 color; + /* 0x1F */ u8 params; +} MirRayDataEntry; // size = 0x20 + const ActorInit Mir_Ray_InitVars = { ACTOR_MIR_RAY, ACTORCAT_ITEMACTION, @@ -22,64 +53,670 @@ const ActorInit Mir_Ray_InitVars = { (ActorFunc)MirRay_Draw, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_808E3BF4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, +u8 D_808E3BF0 = false; + +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x00200000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_808E3C44[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00200000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 0, { { 0, 0, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_808E3C68 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_JNTSPH, }, - 1, D_808E3C44, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808E3DB8[] = { +// Note: this data is unchanged from OoT and hardcoded for Spirit Temple, so the actor will not work at all without +// modification. + +MirRayDataEntry sMirRayData[] = { + { + { -0x488, 0x2AE, -0x370 }, + { -0x398, 0x1E0, -0x379 }, + 30, + 50, + 1.0f, + 50, + 150, + 0.8f, + { 255, 255, 255 }, + 2, + }, + { + { -0x740, 0x444, -0xBE }, + { -0x6A7, 0x349, -0xBA }, + 30, + 70, + 0.88f, + 0x36, + 150, + 0.8f, + { 255, 255, 255 }, + 2, + }, + { + { 0x557, 0x2E2, -0x35C }, + { 0x443, 0x1DC, -0x35C }, + 30, + 0x55, + 0.0f, + 0, + 150, + 0.8f, + { 255, 255, 255 }, + 0, + }, + { + { 0x898, 0x44F, -0xDC }, + { 0x7F8, 0x34B, -0xDC }, + 30, + 60, + 0.0f, + 0, + 150, + 0.8f, + { 255, 255, 255 }, + 1, + }, + { + { -0x230, 0x879, -0x136 }, + { -0x230, 0x6CF, -0x136 }, + 30, + 70, + 0.0f, + 0, + 150, + 0.8f, + { 255, 255, 255 }, + 0, + }, + { + { 0x3C, 0x70A, -0x442 }, + { 0x3C, 0x3CD, -0x442 }, + 30, + 70, + 0.0f, + 0, + 150, + 0.9f, + { 255, 255, 255 }, + 13, + }, + { + { 0x474, 0x1E0, -0x35C }, + { 0x474, 0x1E0, -0x35C }, + 30, + 30, + 1.0f, + 10, + 100, + 0.9f, + { 255, 255, 255 }, + 14, + }, + { + { -0x230, 0x6CF, -0x136 }, + { + -0x230, + 0x6CF, + -0x136, + }, + 30, + 30, + 0.0f, + 0, + 100, + 0.94f, + { 255, 255, 255 }, + 12, + }, + { + { 0x3C, 0x6CF, -0x136 }, + { 0x3C, 0x6CF, -0x136 }, + 30, + 30, + 0.0f, + 0, + 100, + 0.94f, + { 255, 255, 255 }, + 12, + }, + { + { -0x496, 0x1C0, 0x4AA }, + { -0x496, 0x94, 0x4AA }, + 50, + 100, + 1.0f, + 50, + 150, + 0.8f, + { 255, 255, 255 }, + 3, + }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1000, ICHAIN_STOP), }; +const char D_808E3DD0[] = "反射光 発生失敗"; + +void MirRay_SetupCollider(MirRay* this) { + MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)]; + f32 x = (this->poolPt.x - this->sourcePt.x) * dataEntry->unk_10; + f32 y = (this->poolPt.y - this->sourcePt.y) * dataEntry->unk_10; + f32 z = (this->poolPt.z - this->sourcePt.z) * dataEntry->unk_10; + + this->collider1.elements[0].dim.worldSphere.center.x = this->sourcePt.x + x; + this->collider1.elements[0].dim.worldSphere.center.y = this->sourcePt.y + y; + this->collider1.elements[0].dim.worldSphere.center.z = this->sourcePt.z + z; + + this->collider1.elements[0].dim.worldSphere.radius = dataEntry->unk_14 * this->collider1.elements->dim.scale; +} + +// Set up a light point between source point and reflection point. Reflection point is the pool point (for windows) or +// at the player position (for mirrors) +void MirRay_MakeShieldLight(MirRay* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)]; + Vec3f reflectionPt; + Vec3s lightPt; + + if (MirRay_CheckInFrustum(&this->sourcePt, &this->poolPt, player->actor.world.pos.x, + player->actor.world.pos.y + 30.0f, player->actor.world.pos.z, this->sourceEndRad, + this->poolEndRad)) { + if (dataEntry->params & 8) { + Math_Vec3f_Diff(&player->actor.world.pos, &this->sourcePt, &reflectionPt); + } else { + Math_Vec3f_Diff(&this->poolPt, &this->sourcePt, &reflectionPt); + } + + lightPt.x = (dataEntry->unk_18 * reflectionPt.x) + this->sourcePt.x; + lightPt.y = (dataEntry->unk_18 * reflectionPt.y) + this->sourcePt.y; + lightPt.z = (dataEntry->unk_18 * reflectionPt.z) + this->sourcePt.z; + + // Fade up + Math_StepToS(&this->lightPointRad, dataEntry->lgtPtMaxRad, 6); + Lights_PointNoGlowSetInfo(&this->lightInfo, lightPt.x, lightPt.y, lightPt.z, dataEntry->color.r, + dataEntry->color.g, dataEntry->color.b, this->lightPointRad); + } else { + // Fade down + Math_StepToS(&this->lightPointRad, 0, 6); + Lights_PointSetColorAndRadius(&this->lightInfo, dataEntry->color.r, dataEntry->color.g, dataEntry->color.b, + this->lightPointRad); + } +} + +void MirRay_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + MirRay* this = THIS; + MirRayDataEntry* dataEntry = &sMirRayData[MIRRAY_LOCATION(&this->actor)]; + + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + + if (MIRRAY_LOCATION(&this->actor) >= MIRRAY_MAX) { + Actor_MarkForDeath(&this->actor); + } + + this->sourcePt.x = dataEntry->sourcePoint.x; + this->sourcePt.y = dataEntry->sourcePoint.y; + this->sourcePt.z = dataEntry->sourcePoint.z; + this->sourceEndRad = dataEntry->sourceEndRadius; + + this->poolPt.x = dataEntry->poolPoint.x; + this->poolPt.y = dataEntry->poolPoint.y; + this->poolPt.z = dataEntry->poolPoint.z; + this->poolEndRad = dataEntry->poolEndRadius; + + Lights_PointNoGlowSetInfo(&this->lightInfo, this->sourcePt.x, this->sourcePt.y, this->sourcePt.z, 255, 255, 255, + 100); + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); + + this->shieldCorners[0].x = -536.0f; + this->shieldCorners[0].y = -939.0f; + + this->shieldCorners[1].x = -1690.0f; + this->shieldCorners[1].y = 0.0f; + + this->shieldCorners[2].x = -536.0f; + this->shieldCorners[2].y = 938.0f; + + this->shieldCorners[3].x = 921.0f; + this->shieldCorners[3].y = 0.0f; + + this->shieldCorners[4].x = 758.0f; + this->shieldCorners[4].y = 800.0f; + + this->shieldCorners[5].x = 758.0f; + this->shieldCorners[5].y = -800.0f; + + if (dataEntry->params & 2) { + Collider_InitJntSph(globalCtx, &this->collider1); + Collider_SetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit, this->collider1Elements); + if (!(dataEntry->params & 4)) { // Beams not from mirrors + MirRay_SetupCollider(this); + } + } + + Collider_InitQuad(globalCtx, &this->collider2); + Collider_SetQuad(globalCtx, &this->collider2, &this->actor, &sQuadInit); + + if ((MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_CEILINGMIRROR) || + (MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_COBRA1) || + (MIRRAY_LOCATION(&this->actor) == MIRRAY_SPIRIT_TOPROOM_COBRA2)) { + this->actor.room = -1; + } +} + +void MirRay_Destroy(Actor* thisx, GlobalContext* globalCtx) { + MirRay* this = THIS; + + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); + + if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 2) { + Collider_DestroyJntSph(globalCtx, &this->collider1); + } + + Collider_DestroyQuad(globalCtx, &this->collider2); +} + +void MirRay_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + MirRay* this = THIS; + Player* player = GET_PLAYER(globalCtx); + + D_808E3BF0 = false; + + if (!this->unLit) { + if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 2) { + if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 4) { + MirRay_SetupCollider(this); + } + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + + if (this->reflectIntensity > 0.0f) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + + MirRay_MakeShieldLight(this, globalCtx); + + if (this->reflectIntensity > 0.0f) { + func_800B8F98(&player->actor, NA_SE_IT_SHIELD_BEAM - SFX_FLAG); + } + } +} + +void MirRay_SetIntensity(MirRay* this, GlobalContext* globalCtx) { + f32 sp4C[3]; + s32 pad[4]; + Player* player = GET_PLAYER(globalCtx); + MtxF* shieldMtx = &player->shieldMf; + f32 temp_f0; + f32 temp_f0_2; + f32 temp_f2; + + this->reflectIntensity = 0.0f; + + if (MirRay_CheckInFrustum(&this->sourcePt, &this->poolPt, shieldMtx->xw, shieldMtx->yw, shieldMtx->zw, + this->sourceEndRad, this->poolEndRad)) { + temp_f0 = sqrtf(SQ(shieldMtx->zz) + (SQ(shieldMtx->xz) + SQ(shieldMtx->yz))); + if (temp_f0 == 0.0f) { + this->reflectRange = 1.0f; + } else { + this->reflectRange = 1.0f / temp_f0; + } + + if (sMirRayData[MIRRAY_LOCATION(&this->actor)].params & 1) { + this->reflectIntensity = 1.0f; + } else { + sp4C[0] = this->poolPt.x - this->sourcePt.x; + sp4C[1] = this->poolPt.y - this->sourcePt.y; + sp4C[2] = this->poolPt.z - this->sourcePt.z; + + temp_f2 = (-shieldMtx->xz * sp4C[0]) - (shieldMtx->yz * sp4C[1]) - (shieldMtx->zz * sp4C[2]); + + if (temp_f2 < 0.0f) { + temp_f0_2 = sqrtf(SQ(sp4C[0]) + SQ(sp4C[1]) + SQ(sp4C[2])); + if ((temp_f0 != 0.0f) && (temp_f0_2 != 0.0f)) { + this->reflectIntensity = -temp_f2 / (temp_f0 * temp_f0_2); + } + } + } + } +} + +// Draws six images, one for each corner of the shield, by finding the intersection of a line segment from the corner +// perpendicular to the shield with the nearest collision (if any). +void MirRay_SetupReflectionPolys(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection) { + s32 i; + Player* player = GET_PLAYER(globalCtx); + MtxF* shieldMtx = &player->shieldMf; + Vec3f posA; + Vec3f posB; + Vec3f sp70; + CollisionPoly* outPoly; + f32 sp60[3]; + + sp60[0] = -(shieldMtx->xz * this->reflectRange) * this->reflectIntensity * 400.0f; + sp60[1] = -(shieldMtx->yz * this->reflectRange) * this->reflectIntensity * 400.0f; + sp60[2] = -(shieldMtx->zz * this->reflectRange) * this->reflectIntensity * 400.0f; + + for (i = 0; i < ARRAY_COUNT(this->shieldCorners); i++) { + posA.x = + (shieldMtx->xw + (this->shieldCorners[i].x * shieldMtx->xx)) + (this->shieldCorners[i].y * (*shieldMtx).xy); + posA.y = + (shieldMtx->yw + (this->shieldCorners[i].x * shieldMtx->yx)) + (this->shieldCorners[i].y * (*shieldMtx).yy); + posA.z = + (shieldMtx->zw + (this->shieldCorners[i].x * shieldMtx->zx)) + (this->shieldCorners[i].y * (*shieldMtx).zy); + + posB.x = sp60[0] + posA.x; + posB.y = sp60[1] + posA.y; + posB.z = sp60[2] + posA.z; + + if (BgCheck_AnyLineTest1(&globalCtx->colCtx, &posA, &posB, &sp70, &outPoly, 1)) { + reflection[i].reflectionPoly = outPoly; + } else { + reflection[i].reflectionPoly = NULL; + } + } +} + +// Remove reflections that are in the same position and are sufficiently near to the same plane +void MirRay_RemoveSimilarReflections(MirRayShieldReflection* reflection) { + s32 i; + s32 j; + + for (i = 0; i < 6; i++) { + for (j = i + 1; j < 6; j++) { + if ((reflection[i].reflectionPoly != NULL) && (reflection[j].reflectionPoly != NULL)) { + if ((ABS(reflection[i].reflectionPoly->normal.x - reflection[j].reflectionPoly->normal.x) < 100) && + (ABS(reflection[i].reflectionPoly->normal.y - reflection[j].reflectionPoly->normal.y) < 100) && + (ABS(reflection[i].reflectionPoly->normal.z - reflection[j].reflectionPoly->normal.z) < 100) && + (reflection[i].reflectionPoly->dist == reflection[j].reflectionPoly->dist)) { + reflection[j].reflectionPoly = NULL; + } + } + } + } +} + +// Creates the reflected beam's collider (to interact with objects) and places and orients the shield images +#ifdef NON_MATCHING +// Beginning block re-ordered +void MirRay_ReflectedBeam(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + f32 temp_f0; + Vec3f vecB; + Vec3f vecD; + Vec3f sp118; + Vec3f sp10C; + Vec3f sp100; + Vec3f intersection; + f32 spE8[3]; + f32 normalVec[3]; + MtxF* shieldMtx = &player->shieldMf; + Vec3f vecA; + Vec3f vecC; + + spE8[0] = -(shieldMtx->xz * this->reflectRange) * this->reflectIntensity * 400.0f; + spE8[1] = -(shieldMtx->yz * this->reflectRange) * this->reflectIntensity * 400.0f; + spE8[2] = -(shieldMtx->zz * this->reflectRange) * this->reflectIntensity * 400.0f; + + vecB.x = shieldMtx->xw; + vecB.y = shieldMtx->yw; + vecB.z = shieldMtx->zw; + + vecD.x = spE8[0] + vecB.x; + vecD.y = spE8[1] + vecB.y; + vecD.z = spE8[2] + vecB.z; + + vecA.x = vecB.x + (shieldMtx->xx * 300.0f); + vecA.y = vecB.y + (shieldMtx->yx * 300.0f); + vecA.z = vecB.z + (shieldMtx->zx * 300.0f); + + vecC.x = vecD.x + (shieldMtx->xx * 300.0f); + vecC.y = vecD.y + (shieldMtx->yx * 300.0f); + vecC.z = vecD.z + (shieldMtx->zx * 300.0f); + + Collider_SetQuadVertices(&this->collider2, &vecA, &vecB, &vecC, &vecD); + + for (i = 0; i < 6; i++) { + if (reflection[i].reflectionPoly != NULL) { + normalVec[0] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.x); + normalVec[1] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.y); + normalVec[2] = COLPOLY_GET_NORMAL(reflection[i].reflectionPoly->normal.z); + + if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist, + &vecB, &vecD, &sp118, 1)) { + + reflection[i].pos.x = sp118.x; + reflection[i].pos.y = sp118.y; + reflection[i].pos.z = sp118.z; + + temp_f0 = sqrtf(SQ(sp118.x - vecB.x) + SQ(sp118.y - vecB.y) + SQ(sp118.z - vecB.z)); + + if (temp_f0 < (this->reflectIntensity * 600.0f)) { + reflection[i].opacity = 200; + } else { + reflection[i].opacity = (s32)(800.0f - temp_f0); + } + + reflection[i].opacity = (s32)(reflection[i].opacity * 1.275f); + + sp10C.x = (shieldMtx->xx * 100.0f) + vecB.x; + sp10C.y = (shieldMtx->yx * 100.0f) + vecB.y; + sp10C.z = (shieldMtx->zx * 100.0f) + vecB.z; + + sp100.x = (spE8[0] * 4.0f) + sp10C.x; + sp100.y = (spE8[1] * 4.0f) + sp10C.y; + sp100.z = (spE8[2] * 4.0f) + sp10C.z; + + reflection[i].mtx.xx = reflection[i].mtx.yy = reflection[i].mtx.zz = reflection[i].mtx.ww = 1.0f; + + reflection[i].mtx.yx = reflection[i].mtx.zx = reflection[i].mtx.wx = reflection[i].mtx.xy = + reflection[i].mtx.zy = reflection[i].mtx.wy = reflection[i].mtx.xz = reflection[i].mtx.yz = + reflection[i].mtx.wz = reflection[i].mtx.xw = reflection[i].mtx.yw = reflection[i].mtx.zw = + 0.0f; + + if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist, + &sp10C, &sp100, &intersection, 1)) { + reflection[i].mtx.xx = intersection.x - sp118.x; + reflection[i].mtx.yx = intersection.y - sp118.y; + reflection[i].mtx.zx = intersection.z - sp118.z; + } + + sp10C.x = (shieldMtx->xy * 100.0f) + vecB.x; + sp10C.y = (shieldMtx->yy * 100.0f) + vecB.y; + sp10C.z = (shieldMtx->zy * 100.0f) + vecB.z; + + sp100.x = (spE8[0] * 4.0f) + sp10C.x; + sp100.y = (spE8[1] * 4.0f) + sp10C.y; + sp100.z = (spE8[2] * 4.0f) + sp10C.z; + + if (Math3D_LineSegVsPlane(normalVec[0], normalVec[1], normalVec[2], reflection[i].reflectionPoly->dist, + &sp10C, &sp100, &intersection, 1)) { + reflection[i].mtx.xy = intersection.x - sp118.x; + reflection[i].mtx.yy = intersection.y - sp118.y; + reflection[i].mtx.zy = intersection.z - sp118.z; + } + } else { + reflection[i].reflectionPoly = NULL; + } + } + } +} +#else +void MirRay_ReflectedBeam(MirRay* this, GlobalContext* globalCtx, MirRayShieldReflection* reflection); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_ReflectedBeam.s") #endif -extern ColliderQuadInit D_808E3BF4; -extern ColliderJntSphElementInit D_808E3C44[1]; -extern ColliderJntSphInit D_808E3C68; -extern InitChainEntry D_808E3DB8[]; +void MirRay_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + MirRay* this = THIS; + Player* player = GET_PLAYER(globalCtx); + MirRayShieldReflection reflection[6]; + s32 i; -extern UNK_TYPE D_060003F8; + this->reflectIntensity = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/D_808E3DD0.s") + if (!D_808E3BF0 && !this->unLit && func_80124088(globalCtx)) { + Matrix_Mult(&player->shieldMf, MTXMODE_NEW); + MirRay_SetIntensity(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2600.s") + if (this->reflectIntensity <= 0.0f) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E26C8.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Init.s") + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Scale(1.0f, 1.0f, this->reflectIntensity, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Destroy.s") + 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)(s8)(this->reflectIntensity * 100.0f)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Update.s") + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_mir_ray_Matanimheader_0003F8)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2C68.s") + gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_000168); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2E1C.s") + MirRay_SetupReflectionPolys(this, globalCtx, reflection); + MirRay_RemoveSimilarReflections(reflection); + MirRay_ReflectedBeam(this, globalCtx, reflection); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E2FF8.s") + if (reflection[0].reflectionPoly == NULL) { + reflection[0].opacity = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E30FC.s") + for (i = 1; i < ARRAY_COUNT(reflection); i++) { + if (reflection[i].reflectionPoly != NULL) { + if (reflection[0].opacity < reflection[i].opacity) { + reflection[0].opacity = reflection[i].opacity; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/MirRay_Draw.s") + for (i = 0; i < ARRAY_COUNT(reflection); i++) { + if (reflection[i].reflectionPoly != NULL) { + Matrix_Translate(reflection[i].pos.x, reflection[i].pos.y, reflection[i].pos.z, MTXMODE_NEW); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + Matrix_Mult(&reflection[i].mtx, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray/func_808E3984.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, reflection[0].opacity); + gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_0004B0); + } + } + + D_808E3BF0 = true; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +// Computes if the Point (pointx, pointy, pointz) lies within the right conical frustum with one end centred at vecA +// with radius radiusA, the other at vecB with radius radiusB +s32 MirRay_CheckInFrustum(Vec3f* vecA, Vec3f* vecB, f32 pointx, f32 pointy, f32 pointz, s16 radiusA, s16 radiusB) { + f32 coneRadius; + f32 closestPtx; + f32 closestPty; + f32 closestPtz; + Vec3f vecdiff; + f32 dist; + Vec3f sp5C; + Vec3f sp50; + Vec3f sp44; + + vecdiff.x = vecB->x - vecA->x; + vecdiff.y = vecB->y - vecA->y; + vecdiff.z = vecB->z - vecA->z; + if (1) {} + + dist = SQ(vecdiff.x) + SQ(vecdiff.y) + SQ(vecdiff.z); + + if (dist == 0.0f) { + return false; + } + + dist = + (((pointx - vecA->x) * vecdiff.x) + ((pointy - vecA->y) * vecdiff.y) + ((pointz - vecA->z) * vecdiff.z)) / dist; + + // Closest point on line A-B to Point + closestPtx = (vecdiff.x * dist) + vecA->x; + closestPty = (vecdiff.y * dist) + vecA->y; + closestPtz = (vecdiff.z * dist) + vecA->z; + + // Diameter of the double cone on the perpendicular plane through the closest point + coneRadius = ((radiusB - radiusA) * dist) + radiusA; + + // If the Point is within the bounding double cone, check if it is in the frustum by checking whether it is between + // the bounding planes + if ((SQ(closestPtx - pointx) + SQ(closestPty - pointy) + SQ(closestPtz - pointz)) <= SQ(coneRadius)) { + if (1) {} + + // Stores the vector difference again + Math_Vec3f_Diff(vecB, vecA, &sp5C); + + sp50.x = pointx - vecA->x; + sp50.y = pointy - vecA->y; + sp50.z = pointz - vecA->z; + + if (Math3D_Parallel(&sp5C, &sp50) < 0.0f) { + return false; + } + + sp44.x = pointx - vecB->x; + sp44.y = pointy - vecB->y; + sp44.z = pointz - vecB->z; + + if (Math3D_Parallel(&sp5C, &sp44) > 0.0f) { + return false; + } + return true; + } + return false; +} diff --git a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h index c03b48c6b..4d748e3b5 100644 --- a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h +++ b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h @@ -5,9 +5,39 @@ struct MirRay; +#define MIRRAY_LOCATION(thisx) ((thisx)->params) + +// Locations of light beams in sMirRayData +typedef enum { + /* 0 */ MIRRAY_SPIRIT_BOMBCHUIWAROOM_DOWNLIGHT, + /* 1 */ MIRRAY_SPIRIT_SUNBLOCKROOM_DOWNLIGHT, + /* 2 */ MIRRAY_SPIRIT_SINGLECOBRAROOM_DOWNLIGHT, + /* 3 */ MIRRAY_SPIRIT_ARMOSROOM_DOWNLIGHT, + /* 4 */ MIRRAY_SPIRIT_TOPROOM_DOWNLIGHT, + /* 5 */ MIRRAY_SPIRIT_TOPROOM_CEILINGMIRROR, + /* 6 */ MIRRAY_SPIRIT_SINGLECOBRAROOM_COBRA, + /* 7 */ MIRRAY_SPIRIT_TOPROOM_COBRA1, + /* 8 */ MIRRAY_SPIRIT_TOPROOM_COBRA2, + /* 9 */ MIRRAY_GANONSCASTLE_SPIRITTRIAL_DOWNLIGHT, + /* 10 */ MIRRAY_MAX, +} MirRayBeamLocations; + typedef struct MirRay { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x164]; + /* 0x0000 */ Actor actor; + /* 0x0144 */ ColliderJntSph collider1; + /* 0x0164 */ ColliderJntSphElement collider1Elements[1]; + /* 0x01A4 */ ColliderQuad collider2; + /* 0x0224 */ f32 reflectIntensity; // Reflection occurs if it is positive, brightness depends on it + /* 0x0228 */ Vec3f shieldCorners[6]; + /* 0x0270 */ f32 reflectRange; + /* 0x0274 */ Vec3f sourcePt; + /* 0x0280 */ Vec3f poolPt; + /* 0x028C */ s16 sourceEndRad; + /* 0x028E */ s16 poolEndRad; + /* 0x0290 */ s16 lightPointRad; + /* 0x0294 */ LightNode* lightNode; + /* 0x0298 */ LightInfo lightInfo; + /* 0x02A6 */ u8 unLit; // Conditioned on. set in Cobra? } MirRay; // size = 0x2A8 extern const ActorInit Mir_Ray_InitVars; 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 75517b3fd..f6e8750cb 100644 --- a/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c +++ b/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c @@ -1,6 +1,12 @@ +/* + * File: z_mir_ray2.c + * Overlay: ovl_Mir_Ray2 + * Description: Reflectable light ray (static beam) + */ + #include "z_mir_ray2.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((MirRay2*)thisx) 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 35978d4c2..f5209c392 100644 --- a/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c +++ b/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c @@ -1,6 +1,13 @@ -#include "z_mir_ray3.h" +/* + * File: z_mir_ray3.c + * Overlay: ovl_Mir_Ray3 + * Description: Mirror shield reflection and glow + */ -#define FLAGS 0x00000030 +#include "z_mir_ray3.h" +#include "objects/object_mir_ray/object_mir_ray.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((MirRay3*)thisx) @@ -9,7 +16,6 @@ void MirRay3_Destroy(Actor* thisx, GlobalContext* globalCtx); void MirRay3_Update(Actor* thisx, GlobalContext* globalCtx); void MirRay3_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Mir_Ray3_InitVars = { ACTOR_MIR_RAY3, ACTORCAT_ITEMACTION, @@ -22,39 +28,398 @@ const ActorInit Mir_Ray3_InitVars = { (ActorFunc)MirRay3_Draw, }; -// static ColliderQuadInit sQuadInit = { -static ColliderQuadInit D_80B9F420 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_NONE, OC2_NONE, COLSHAPE_QUAD, }, - { ELEMTYPE_UNK0, { 0x00200000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, +static ColliderQuadInit sQuadInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_NONE, + OC2_NONE, + COLSHAPE_QUAD, + }, + { + ELEMTYPE_UNK0, + { 0x00200000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B9F470 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_NONE, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00200000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00200000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 10, 10, 0, { 0, 0, 0 } }, }; +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ MtxF unk_0C; + /* 0x4C */ CollisionPoly* unk_4C; + /* 0x50 */ u8 unk_50; +} MirRay3Struct; // size = 0x54 + +void MirRay3_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + MirRay3* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + Actor_SetScale(&this->actor, 1.0f); + + this->unk_218[0].x = -536.0f; + this->unk_218[0].y = -939.0f; + + this->unk_218[1].x = -1690.0f; + this->unk_218[1].y = 0.0f; + + this->unk_218[2].x = -536.0f; + this->unk_218[2].y = 938.0f; + + this->unk_218[3].x = 921.0f; + this->unk_218[3].y = 0.0f; + + this->unk_218[4].x = 758.0f; + this->unk_218[4].y = 800.0f; + + this->unk_218[5].x = 758.0f; + this->unk_218[5].y = -800.0f; + + Collider_InitQuad(globalCtx, &this->colliderQuad); + Collider_SetQuad(globalCtx, &this->colliderQuad, &this->actor, &sQuadInit); + Collider_InitCylinder(globalCtx, &this->colliderCylinder); + Collider_SetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + this->actor.world.rot.x = this->actor.shape.rot.x = 0; +} + +void MirRay3_Destroy(Actor* thisx, GlobalContext* globalCtx) { + MirRay3* this = THIS; + + Collider_DestroyQuad(globalCtx, &this->colliderQuad); + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); +} + +void MirRay3_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[2]; + MirRay3* this = THIS; + Player* player = GET_PLAYER(globalCtx); + + this->unk_210 &= ~1; + + if (this->unk_214 > 0.5f) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderQuad.base); + } + + this->unk_210 &= ~2; + + if (func_8012405C(globalCtx)) { + if (this->colliderCylinder.base.acFlags & AC_HIT) { + this->unk_210 |= 2; + } + this->actor.world.pos.x = player->shieldMf.mf[3][0]; + this->actor.world.pos.y = player->shieldMf.mf[3][1]; + this->actor.world.pos.z = player->shieldMf.mf[3][2]; + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + + if (this->unk_214 > 0.1f) { + func_800B8F98(&player->actor, NA_SE_IT_SHIELD_BEAM - SFX_FLAG); + } + + Math_ApproachZeroF(&this->unk_214, 1.0f, 0.1f); +} + +void func_80B9E544(MirRay3* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + MtxF* shieldMtx = &player->shieldMf; + f32 temp_f0; + + if (this->unk_210 & 2) { + temp_f0 = sqrtf(SQ(shieldMtx->mf[2][0]) + SQ(shieldMtx->mf[2][1]) + SQ(shieldMtx->mf[2][2])); + if (temp_f0 == 0.0f) { + this->unk_260 = 1.0f; + } else { + this->unk_260 = 1.0f / temp_f0; + } + Math_ApproachF(&this->unk_214, 1.0f, 0.5f, 0.25f); + } +} + +void func_80B9E5F4(MirRay3* this, GlobalContext* globalCtx, MirRay3Struct* ptr) { + Player* player = GET_PLAYER(globalCtx); + MtxF* shieldMtx = &player->shieldMf; + s32 i; + Vec3f sp88; + Vec3f sp7C; + Vec3f sp70; + CollisionPoly* sp6C; + f32 sp60[3]; + + sp60[0] = -(shieldMtx->mf[2][0] * this->unk_260) * this->unk_214 * 400.0f; + sp60[1] = -(shieldMtx->mf[2][1] * this->unk_260) * this->unk_214 * 400.0f; + sp60[2] = -(shieldMtx->mf[2][2] * this->unk_260) * this->unk_214 * 400.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_218); i++) { + sp88.x = (shieldMtx->mf[3][0] + (this->unk_218[i].x * shieldMtx->mf[0][0])) + + (this->unk_218[i].y * shieldMtx->mf[1][0]); + sp88.y = (shieldMtx->mf[3][1] + (this->unk_218[i].x * shieldMtx->mf[0][1])) + + (this->unk_218[i].y * shieldMtx->mf[1][1]); + sp88.z = (shieldMtx->mf[3][2] + (this->unk_218[i].x * shieldMtx->mf[0][2])) + + (this->unk_218[i].y * shieldMtx->mf[1][2]); + + sp7C.x = sp60[0] + sp88.x; + sp7C.y = sp60[1] + sp88.y; + sp7C.z = sp60[2] + sp88.z; + + if (BgCheck_AnyLineTest1(&globalCtx->colCtx, &sp88, &sp7C, &sp70, &sp6C, true)) { + ptr[i].unk_4C = sp6C; + } else { + ptr[i].unk_4C = NULL; + } + } +} + +void func_80B9E7D0(MirRay3Struct* ptr) { + s32 i; + s32 j; + + for (i = 0; i < 6; i++) { + for (j = i + 1; j < 6; j++) { + if ((ptr[i].unk_4C != NULL) && (ptr[j].unk_4C != NULL)) { + if ((ABS(ptr[i].unk_4C->normal.x - ptr[j].unk_4C->normal.x) < 100) && + (ABS(ptr[i].unk_4C->normal.y - ptr[j].unk_4C->normal.y) < 100) && + (ABS(ptr[i].unk_4C->normal.z - ptr[j].unk_4C->normal.z) < 100) && + (ptr[i].unk_4C->dist == ptr[j].unk_4C->dist)) { + ptr[j].unk_4C = NULL; + } + } + } + } +} + +#ifdef NON_MATCHING +void func_80B9E8D4(MirRay3* this, GlobalContext* globalCtx, MirRay3Struct* ptr) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + MtxF* shieldMf = &player->shieldMf; + Vec3f sp140; + Vec3f sp134; + Vec3f sp128; + Vec3f sp11C; + Vec3f sp110; + Vec3f sp104; + f32 spF8[3]; + f32 spEC[3]; + f32 temp_f0; + f32 temp_f26; + f32 temp_f2; + Vec3f spD4; + Vec3f spC8; + CollisionPoly* spC4; + + spF8[0] = -(shieldMf->mf[2][0] * this->unk_260) * this->unk_214 * 400.0f; + spF8[1] = -(shieldMf->mf[2][1] * this->unk_260) * this->unk_214 * 400.0f; + spF8[2] = -(shieldMf->mf[2][2] * this->unk_260) * this->unk_214 * 400.0f; + + sp140.x = shieldMf->mf[3][0]; + sp140.y = shieldMf->mf[3][1]; + sp140.z = shieldMf->mf[3][2]; + + sp134.x = spF8[0] + sp140.x; + sp134.y = spF8[1] + sp140.y; + sp134.z = spF8[2] + sp140.z; + + temp_f26 = this->unk_214 * 400.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_218); i++) { + if (ptr[i].unk_4C != NULL) { + spEC[0] = COLPOLY_GET_NORMAL(ptr[i].unk_4C->normal.x); + spEC[1] = COLPOLY_GET_NORMAL(ptr[i].unk_4C->normal.y); + spEC[2] = COLPOLY_GET_NORMAL(ptr[i].unk_4C->normal.z); + + if (Math3D_LineSegVsPlane(spEC[0], spEC[1], spEC[2], ptr[i].unk_4C->dist, &sp140, &sp134, &sp128, true)) { + ptr[i].unk_00.x = sp128.x; + ptr[i].unk_00.y = sp128.y; + ptr[i].unk_00.z = sp128.z; + + temp_f0 = sqrtf(SQ(sp128.x - sp140.x) + SQ(sp128.y - sp140.y) + SQ(sp128.z - sp140.z)); + + if (temp_f0 < (temp_f26 * 0.9f)) { + ptr[i].unk_50 = 0xFF; + } else if (temp_f26 < temp_f0) { + ptr[i].unk_50 = 0; + } else { + ptr[i].unk_50 = (s32)((10.0f - ((10.0f / temp_f26) * temp_f0)) * 255.0f); + } + + sp11C.x = (shieldMf->mf[0][0] * 100.0f) + sp140.x; + sp11C.y = (shieldMf->mf[0][1] * 100.0f) + sp140.y; + sp11C.z = (shieldMf->mf[0][2] * 100.0f) + sp140.z; + + sp110.x = (spF8[0] * 4.0f) + sp11C.x; + sp110.y = (spF8[1] * 4.0f) + sp11C.y; + sp110.z = (spF8[2] * 4.0f) + sp11C.z; + + ptr[i].unk_0C.mf[0][0] = ptr[i].unk_0C.mf[1][1] = ptr[i].unk_0C.mf[2][2] = ptr[i].unk_0C.mf[3][3] = + 1.0f; + + ptr[i].unk_0C.mf[0][1] = ptr[i].unk_0C.mf[0][2] = ptr[i].unk_0C.mf[0][3] = ptr[i].unk_0C.mf[1][0] = + ptr[i].unk_0C.mf[1][2] = ptr[i].unk_0C.mf[1][3] = ptr[i].unk_0C.mf[2][0] = ptr[i].unk_0C.mf[2][1] = + ptr[i].unk_0C.mf[2][3] = ptr[i].unk_0C.mf[3][0] = ptr[i].unk_0C.mf[3][1] = + ptr[i].unk_0C.mf[3][2] = 0.0f; + + if (Math3D_LineSegVsPlane(spEC[0], spEC[1], spEC[2], ptr[i].unk_4C->dist, &sp11C, &sp110, &sp104, + true)) { + ptr[i].unk_0C.mf[0][0] = sp104.x - sp128.x; + ptr[i].unk_0C.mf[0][1] = sp104.y - sp128.y; + ptr[i].unk_0C.mf[0][2] = sp104.z - sp128.z; + } + + sp11C.x = (shieldMf->mf[1][0] * 100.0f) + sp140.x; + sp11C.y = (shieldMf->mf[1][1] * 100.0f) + sp140.y; + sp11C.z = (shieldMf->mf[1][2] * 100.0f) + sp140.z; + + sp110.x = (spF8[0] * 4.0f) + sp11C.x; + sp110.y = (spF8[1] * 4.0f) + sp11C.y; + sp110.z = (spF8[2] * 4.0f) + sp11C.z; + + if (Math3D_LineSegVsPlane(spEC[0], spEC[1], spEC[2], ptr[i].unk_4C->dist, &sp11C, &sp110, &sp104, + true)) { + ptr[i].unk_0C.mf[1][0] = sp104.x - sp128.x; + ptr[i].unk_0C.mf[1][1] = sp104.y - sp128.y; + ptr[i].unk_0C.mf[1][2] = sp104.z - sp128.z; + } + } else { + ptr[i].unk_4C = NULL; + } + } + } + + temp_f2 = this->unk_214 * 400.0f; + + spF8[0] = -(this->unk_260 * shieldMf->mf[2][0]); + spF8[1] = -(this->unk_260 * shieldMf->mf[2][1]); + spF8[2] = -(this->unk_260 * shieldMf->mf[2][2]); + + sp134.x = (spF8[0] * temp_f2) + sp140.x; + sp134.y = (spF8[1] * temp_f2) + sp140.y; + sp134.z = (spF8[2] * temp_f2) + sp140.z; + + if (!BgCheck_AnyLineTest1(&globalCtx->colCtx, &sp140, &sp134, &sp128, &spC4, 1)) { + Math_Vec3f_Copy(&sp128, &sp134); + } + + sp128.x += spF8[0] * 5.0f; + sp128.y += spF8[1] * 5.0f; + sp128.z += spF8[2] * 5.0f; + + spD4.x = (shieldMf->mf[0][0] * 300.0f) + sp140.x; + spD4.y = (shieldMf->mf[0][1] * 300.0f) + sp140.y; + spD4.z = (shieldMf->mf[0][2] * 300.0f) + sp140.z; + + spC8.x = (shieldMf->mf[0][0] * 300.0f) + sp128.x; + spC8.y = (shieldMf->mf[0][1] * 300.0f) + sp128.y; + spC8.z = (shieldMf->mf[0][2] * 300.0f) + sp128.z; + + Collider_SetQuadVertices(&this->colliderQuad, &spD4, &sp140, &spC8, &sp128); +} +#else +void func_80B9E8D4(MirRay3* this, GlobalContext* globalCtx, MirRay3Struct* ptr); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/func_80B9E8D4.s") #endif -extern ColliderQuadInit D_80B9F420; -extern ColliderCylinderInit D_80B9F470; +void MirRay3_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[2]; + MirRay3* this = THIS; + MirRay3Struct sp8C[6]; + Player* player = GET_PLAYER(globalCtx); + s32 i; + f32 temp; + u16 time; -extern UNK_TYPE D_060003F8; + if (!(this->unk_210 & 1) && func_8012405C(globalCtx)) { + Matrix_Mult(&player->shieldMf, MTXMODE_NEW); + func_80B9E544(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/MirRay3_Init.s") + if (this->unk_214 <= 0.1f) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/MirRay3_Destroy.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/MirRay3_Update.s") + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Scale(1.0f, 1.0f, this->unk_214, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/func_80B9E544.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/func_80B9E5F4.s") + if (MIRRAY3_GET_F(&this->actor) == MIRRAY3_F_1) { + time = gSaveContext.save.time; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/func_80B9E7D0.s") + if (time > CLOCK_TIME(12, 0)) { + time = (DAY_LENGTH - 1) - time; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/func_80B9E8D4.s") + temp = (time * (1.0f / 0x8000)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x78, 255, 255, 255, (u8)(s8)(100 * this->unk_214)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Mir_Ray3/MirRay3_Draw.s") + gDPSetEnvColor(POLY_XLU_DISP++, 218, 225, (u8)((100.0f * temp) + 105.0f), 255); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x78, 255, 255, 255, (u8)(s8)(100 * this->unk_214)); + gDPSetEnvColor(POLY_XLU_DISP++, 218, 225, 205, 255); + } + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_mir_ray_Matanimheader_0003F8)); + + gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_000168); + + func_80B9E5F4(this, globalCtx, sp8C); + func_80B9E7D0(sp8C); + func_80B9E8D4(this, globalCtx, sp8C); + + if (sp8C[0].unk_4C == NULL) { + sp8C[0].unk_50 = 0; + } + + for (i = 1; i < ARRAY_COUNT(sp8C); i++) { + if ((sp8C[i].unk_4C != NULL) && (sp8C[0].unk_50 < sp8C[i].unk_50)) { + sp8C[0].unk_50 = sp8C[i].unk_50; + } + } + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_AA_ZB_XLU_DECAL2); + + for (i = 0; i < ARRAY_COUNT(sp8C); i++) { + if (sp8C[i].unk_4C != NULL) { + Matrix_Translate(sp8C[i].unk_00.x, sp8C[i].unk_00.y, sp8C[i].unk_00.z, MTXMODE_NEW); + Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); + Matrix_Mult(&sp8C[i].unk_0C, 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, sp8C[0].unk_50); + gSPDisplayList(POLY_XLU_DISP++, object_mir_ray_DL_0004B0); + } + } + + this->unk_210 |= 1; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.h b/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.h index 18510673d..7aecd111f 100644 --- a/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.h +++ b/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.h @@ -5,9 +5,18 @@ struct MirRay3; +#define MIRRAY3_GET_F(thisx) ((thisx)->params & 0xF) + +#define MIRRAY3_F_1 1 + typedef struct MirRay3 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x120]; + /* 0x144 */ ColliderQuad colliderQuad; + /* 0x1C4 */ ColliderCylinder colliderCylinder; + /* 0x210 */ u16 unk_210; + /* 0x214 */ f32 unk_214; + /* 0x218 */ Vec3f unk_218[6]; + /* 0x260 */ f32 unk_260; } MirRay3; // size = 0x264 extern const ActorInit Mir_Ray3_InitVars; 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 2111f1d0f..97865650d 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c @@ -5,8 +5,9 @@ */ #include "z_obj_aqua.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjAqua*)thisx) @@ -57,7 +58,7 @@ static ColliderCylinderInit sCylinderInit = { static InitChainEntry sInitChain[] = { ICHAIN_VEC3S(shape.rot, 0, ICHAIN_CONTINUE), ICHAIN_VEC3S(world.rot, 0, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -4000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(gravity, -900, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(terminalVelocity, -4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 300, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 300, ICHAIN_STOP), }; @@ -66,15 +67,13 @@ 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; s32 angleOffset = 0; s32 i; - sp58.y = this->actor.world.pos.y + this->actor.yDistToWater; + sp58.y = this->actor.world.pos.y + this->actor.depthInWater; for (i = 0; i < 4; i++) { sp58.x = this->actor.world.pos.x + Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f; sp58.z = this->actor.world.pos.z + Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + angleOffset) * 8.0f; @@ -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) { @@ -124,7 +123,7 @@ void func_80ACBA10(ObjAqua* this) { func_800C0094(this->actor.floorPoly, this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, &sp2C); - func_8018219C(&sp2C, &this->actor.shape.rot, 0); + Matrix_MtxFToYXZRot(&sp2C, &this->actor.shape.rot, false); } s32 func_80ACBA60(ObjAqua* this, GlobalContext* globalCtx) { @@ -133,8 +132,8 @@ s32 func_80ACBA60(ObjAqua* this, GlobalContext* globalCtx) { f32 ySurface; s32 bgId; - if (func_800C9EBC(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &ySurface, - &waterBox, &bgId) && + if (WaterBox_GetSurfaceImpl(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &ySurface, &waterBox, &bgId) && (this->actor.world.pos.y < ySurface)) { return true; } @@ -151,7 +150,7 @@ void ObjAqua_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.scale.z = 0.0009f; Collider_InitCylinder(globalCtx, &this->collider); Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); - ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 60.0f); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 60.0f); if (1) {}; this->actor.shape.shadowAlpha = 140; this->alpha = 255; @@ -181,11 +180,11 @@ void func_80ACBC8C(ObjAqua* this, GlobalContext* globalCtx) { if (this->actor.bgCheckFlags & 1) { func_80ACB7F4(this, globalCtx); func_80ACBA10(this); - Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOTTLE_WATERING); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOTTLE_WATERING); func_80ACBD34(this); } else { func_80ACB6A0(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EV_BOMB_DROP_WATER); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 0x28, NA_SE_EV_BOMB_DROP_WATER); Actor_MarkForDeath(&this->actor); } } else if (this->counter <= 0) { @@ -255,7 +254,7 @@ void ObjAqua_Update(Actor* thisx, GlobalContext* globalCtx) { Math_Vec3f_StepTo(&this->actor.scale, &D_80ACC320, 0.0004f); } this->actor.velocity.y *= 0.9f; - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f, 4.0f, 0.0f, 5); if (this->actionFunc != func_80ACBDFC) { Collider_UpdateCylinder(&this->actor, &this->collider); @@ -269,7 +268,7 @@ void ObjAqua_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjAqua* this = THIS; s32 framesTemp; s32 pad; - s16 yaw = func_800DFCDC(globalCtx->cameraPtrs[globalCtx->activeCamera]) + 0x8000; + s16 yaw = Camera_GetCamDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) + 0x8000; s32 actionFuncTemp = this->actionFunc == func_80ACBDFC; OPEN_DISPS(globalCtx->state.gfxCtx); @@ -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_RotateZS(rotation, MTXMODE_APPLY); + Matrix_Scale(1.3f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateZS(rotation * -1, MTXMODE_APPLY); + Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, MTXMODE_APPLY); } - Matrix_RotateY(yaw, 1); + Matrix_RotateYS(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_Aqua/z_obj_aqua.h b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h index 0c8bdc714..8360ae1e2 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h @@ -4,6 +4,7 @@ #include "global.h" #define AQUA_HOT(thisx) ((thisx)->params & 1) +#define OBJAQUA_1 1 struct ObjAqua; diff --git a/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.c b/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.c index e678d6f27..3e72b809e 100644 --- a/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.c +++ b/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.c @@ -1,6 +1,13 @@ -#include "z_obj_armos.h" +/* + * File: z_obj_armos.c + * Overlay: ovl_Obj_Armos + * Description: Non-hostile Armos statues + */ -#define FLAGS 0x04000010 +#include "z_obj_armos.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_4000000) #define THIS ((ObjArmos*)thisx) @@ -9,11 +16,13 @@ void ObjArmos_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjArmos_Update(Actor* thisx, GlobalContext* globalCtx); void ObjArmos_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_809A54B4(ObjArmos* this); void func_809A54E0(ObjArmos* this, GlobalContext* globalCtx); +void func_809A5610(ObjArmos* this); void func_809A562C(ObjArmos* this, GlobalContext* globalCtx); +void func_809A57D8(ObjArmos* this); void func_809A57F4(ObjArmos* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Armos_InitVars = { ACTOR_OBJ_ARMOS, ACTORCAT_PROP, @@ -26,51 +35,358 @@ const ActorInit Obj_Armos_InitVars = { (ActorFunc)ObjArmos_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809A5BC0[] = { - ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 120, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 250, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, -4000, ICHAIN_CONTINUE), +s16 D_809A5BB0[] = { 1, -1, 0, 0 }; +s16 D_809A5BB8[] = { 0, 0, 1, -1 }; + +static InitChainEntry sInitChain[] = { + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 120, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 250, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -4000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_STOP), }; -#endif +s32 func_809A4E00(ObjArmos* this, GlobalContext* globalCtx, s16 arg2) { + return !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 1) || + !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 28); +} -extern InitChainEntry D_809A5BC0[]; +s32 func_809A4E68(ObjArmos* this) { + s16 temp_v0; -extern UNK_TYPE D_0600033C; + if (fabsf(this->dyna.pushForce) > 0.1f) { + temp_v0 = BINANG_ADD(this->dyna.yRotation, 0x2000); + if (this->dyna.pushForce < 0.0f) { + temp_v0 = BINANG_ROT180(temp_v0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A4E00.s") + if (temp_v0 < -0x4000) { + return 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A4E68.s") + if (temp_v0 < 0) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A4F00.s") + if (temp_v0 < 0x4000) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A500C.s") + return 0; + } + return -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A518C.s") +s32 func_809A4F00(ObjArmos* this, s32 arg1) { + s32 temp_v0 = OBJARMOS_GET_ROTZ_7(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/ObjArmos_Init.s") + if (temp_v0 == OBJARMOS_ROT_7_0) { + return arg1 == 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/ObjArmos_Destroy.s") + if (temp_v0 == OBJARMOS_ROT_7_1) { + return arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A54B4.s") + if (temp_v0 == OBJARMOS_ROT_7_2) { + return arg1 == 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A54E0.s") + if (temp_v0 == OBJARMOS_ROT_7_3) { + return arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A5610.s") + if (temp_v0 == OBJARMOS_ROT_7_4) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A562C.s") + if (temp_v0 == OBJARMOS_ROT_7_5) { + return arg1 == 2 || arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A57D8.s") + if (temp_v0 == OBJARMOS_ROT_7_6) { + if (this->unk_26E != 0) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A57F4.s") + if (this->unk_270 != 0) { + return arg1 == 2 || arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/ObjArmos_Update.s") + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A5960.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/func_809A5A3C.s") +s32 func_809A500C(ObjArmos* this, s32 arg1) { + s32 temp_v0 = OBJARMOS_GET_ROTZ_7(&this->dyna.actor); + s32 temp_v1 = OBJARMOS_GET_ROTX_F(&this->dyna.actor); + s32 temp; + s32 temp2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Armos/ObjArmos_Draw.s") + if (temp_v0 == OBJARMOS_ROT_7_0) { + return this->unk_26E < temp_v1; + } + + if (temp_v0 == OBJARMOS_ROT_7_1) { + return -temp_v1 < this->unk_26E; + } + + if (temp_v0 == OBJARMOS_ROT_7_2) { + return this->unk_270 < temp_v1; + } + + if (temp_v0 == OBJARMOS_ROT_7_3) { + return -temp_v1 < this->unk_270; + } + + if (temp_v0 == OBJARMOS_ROT_7_4) { + temp = D_809A5BB0[arg1] + this->unk_26E; + return temp <= temp_v1 && -temp_v1 <= temp; + } + + if (temp_v0 == OBJARMOS_ROT_7_5) { + temp2 = D_809A5BB8[arg1] + this->unk_270; + return temp2 <= temp_v1 && -temp_v1 <= temp2; + } + + if (temp_v0 == OBJARMOS_ROT_7_6) { + if ((arg1 == 0) || (arg1 == 1)) { + temp = D_809A5BB0[arg1] + this->unk_26E; + return temp <= temp_v1 && -temp_v1 <= temp; + } + + temp2 = D_809A5BB8[arg1] + this->unk_270; + return temp2 <= temp_v1 && -temp_v1 <= temp2; + } + + return false; +} + +void func_809A518C(ObjArmos* this, s32 arg1) { + this->unk_26E += D_809A5BB0[arg1]; + this->unk_270 += D_809A5BB8[arg1]; + + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_25C = &this->dyna.actor.world.pos.x; + this->unk_260 = this->dyna.actor.home.pos.x + (this->unk_26E * 60); + } else { + this->unk_25C = &this->dyna.actor.world.pos.z; + this->unk_260 = this->dyna.actor.home.pos.z + (this->unk_270 * 60); + } + this->unk_264 = arg1; +} + +void ObjArmos_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjArmos* this = THIS; + s32 sp44 = OBJARMOS_GET_ROTZ_7(&this->dyna.actor); + s32 sp40 = OBJARMOS_GET_ROTX_F(&this->dyna.actor); + f32 sp3C = Animation_GetLastFrame(&gArmosPushedBackAnim); + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + this->dyna.actor.home.rot.y = this->dyna.actor.world.rot.x = this->dyna.actor.world.rot.y = + this->dyna.actor.world.rot.z = this->dyna.actor.shape.rot.x = this->dyna.actor.shape.rot.z = 0; + + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_am_Colheader_005CF8); + + SkelAnime_Init(globalCtx, &this->skelAnime, &object_am_Skel_005948, &gArmosPushedBackAnim, this->jointTable, + this->morphTable, OBJECT_AM_LIMB_MAX); + + Animation_Change(&this->skelAnime, &gArmosPushedBackAnim, 0.0f, sp3C, sp3C, ANIMMODE_ONCE, 0.0f); + + if (sp40 == 0) { + func_809A57D8(this); + } else if (Flags_GetSwitch(globalCtx, OBJARMOS_GET_7F(&this->dyna.actor))) { + if (sp44 == OBJARMOS_ROT_7_0) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + (sp40 * 60); + func_809A57D8(this); + } else if (sp44 == OBJARMOS_ROT_7_1) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x - (sp40 * 60); + func_809A57D8(this); + } else if (sp44 == OBJARMOS_ROT_7_2) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + (sp40 * 60); + func_809A57D8(this); + } else if (sp44 == OBJARMOS_ROT_7_3) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z - (sp40 * 60); + func_809A57D8(this); + } else { + func_809A54B4(this); + } + } else { + func_809A54B4(this); + } +} + +void ObjArmos_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjArmos* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_809A54B4(ObjArmos* this) { + this->actionFunc = func_809A54E0; + this->unk_24C = 4; + this->unk_266[1] = 0; + this->unk_266[2] = 0; + this->unk_266[3] = 0; + this->unk_266[0] = 0; +} + +void func_809A54E0(ObjArmos* this, GlobalContext* globalCtx) { + s32 i; + s32 sp20 = func_809A4E68(this); + + for (i = 0; i < ARRAY_COUNT(this->unk_266); i++) { + if (sp20 == i) { + this->unk_266[i]++; + } else if (this->unk_266[i] > 0) { + this->unk_266[i]--; + } + } + + if (sp20 != -1) { + if ((this->unk_266[sp20] >= 9) && func_809A4F00(this, sp20) && func_809A500C(this, sp20) && + !func_809A4E00(this, globalCtx, (this->dyna.pushForce > 0.0f) ? 90 : 120)) { + func_809A518C(this, sp20); + func_809A5610(this); + } else { + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + } +} + +void func_809A5610(ObjArmos* this) { + this->actionFunc = func_809A562C; + this->unk_24C = 5; +} + +void func_809A562C(ObjArmos* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player; + f32 temp2 = this->unk_260 - *this->unk_25C; + s32 temp; + s32 sp20; + + if (Math_StepToF(this->unk_25C, this->unk_260, (Math_SinS(fabsf(temp2) * 546.13336f) * 1.6f) + 1.0f)) { + player = GET_PLAYER(globalCtx); + temp = OBJARMOS_GET_ROTZ_7(&this->dyna.actor); + sp20 = false; + + if ((temp == OBJARMOS_ROT_7_4) || (temp == OBJARMOS_ROT_7_5) || (temp == OBJARMOS_ROT_7_6)) { + if (!func_809A500C(this, this->unk_264) || func_809A4E00(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else if (func_809A500C(this, this->unk_264)) { + if (func_809A4E00(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Flags_SetSwitch(globalCtx, OBJARMOS_GET_7F(&this->dyna.actor)); + sp20 = true; + } + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + + if (!sp20) { + func_809A54B4(this); + } else { + func_809A57D8(this); + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + } +} + +void func_809A57D8(ObjArmos* this) { + this->actionFunc = func_809A57F4; + this->unk_24C = 4; +} + +void func_809A57F4(ObjArmos* this, GlobalContext* globalCtx) { + if (fabsf(this->dyna.pushForce) > 0.1f) { + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void ObjArmos_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjArmos* this = THIS; + s32 sp2C; + + this->actionFunc(this, globalCtx); + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + + if (this->unk_24C != 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 20.0f, 30.0f, 0.0f, this->unk_24C); + + if ((this->actionFunc == func_809A54E0) && (this->dyna.actor.bgCheckFlags & 1) && + (DynaPoly_GetActor(&globalCtx->colCtx, this->dyna.actor.floorBgId) == NULL)) { + this->unk_24C = 0; + } + + this->unk_250.x = (Math_SinS(this->dyna.actor.shape.rot.y) * -9.0f) + this->dyna.actor.world.pos.x; + this->unk_250.y = this->dyna.actor.world.pos.y + 20.0f; + this->unk_250.z = (Math_CosS(this->dyna.actor.shape.rot.y) * -9.0f) + this->dyna.actor.world.pos.z; + + this->dyna.actor.floorHeight = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->dyna.actor.floorPoly, + &sp2C, &this->dyna.actor, &this->unk_250); + } +} + +void func_809A5960(ObjArmos* this, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + Vec3f sp28; + + sp28.x = Math_SinS(this->dyna.actor.shape.rot.y); + Matrix_SetTranslateRotateYXZ((sp28.x * -9.0f) + this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + (Math_CosS(this->dyna.actor.shape.rot.y) * -9.0f) + this->dyna.actor.world.pos.z, + &this->dyna.actor.shape.rot); + Matrix_Scale(0.014f, 0.014f, 0.014f, MTXMODE_APPLY); + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 0); + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->dyna.actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_809A5A3C(ObjArmos* this, GlobalContext* globalCtx) { + s32 pad[2]; + MtxF sp48; + + if (this->dyna.actor.floorPoly != NULL) { + 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, 255); + + func_800C0094(this->dyna.actor.floorPoly, this->unk_250.x, this->dyna.actor.floorHeight, this->unk_250.z, + &sp48); + Matrix_Put(&sp48); + Matrix_Scale(0.6f, 1.0f, 0.6f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gCircleShadowDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void ObjArmos_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjArmos* this = THIS; + + func_809A5960(this, globalCtx); + func_809A5A3C(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.h b/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.h index cfc360daa..0a03d4915 100644 --- a/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.h +++ b/src/overlays/actors/ovl_Obj_Armos/z_obj_armos.h @@ -2,16 +2,40 @@ #define Z_OBJ_ARMOS_H #include "global.h" +#include "objects/object_am/object_am.h" struct ObjArmos; typedef void (*ObjArmosActionFunc)(struct ObjArmos*, GlobalContext*); +#define OBJARMOS_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJARMOS_GET_ROTZ_7(thisx) ((thisx)->home.rot.z & 7) +#define OBJARMOS_GET_ROTX_F(thisx) ((thisx)->home.rot.x & 0xF) + +enum { + /* 0 */ OBJARMOS_ROT_7_0, + /* 1 */ OBJARMOS_ROT_7_1, + /* 2 */ OBJARMOS_ROT_7_2, + /* 3 */ OBJARMOS_ROT_7_3, + /* 4 */ OBJARMOS_ROT_7_4, + /* 5 */ OBJARMOS_ROT_7_5, + /* 6 */ OBJARMOS_ROT_7_6, +}; + typedef struct ObjArmos { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x104]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ SkelAnime skelAnime; + /* 0x01A0 */ Vec3s jointTable[OBJECT_AM_LIMB_MAX]; + /* 0x01F4 */ Vec3s morphTable[OBJECT_AM_LIMB_MAX]; /* 0x0248 */ ObjArmosActionFunc actionFunc; - /* 0x024C */ char unk_24C[0x28]; + /* 0x024C */ u32 unk_24C; + /* 0x0250 */ Vec3f unk_250; + /* 0x025C */ f32* unk_25C; + /* 0x0260 */ f32 unk_260; + /* 0x0264 */ s16 unk_264; + /* 0x0266 */ s16 unk_266[4]; + /* 0x026E */ s16 unk_26E; + /* 0x0270 */ s16 unk_270; } ObjArmos; // size = 0x274 extern const ActorInit Obj_Armos_InitVars; 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 b261af7ed..3ee4be021 100644 --- a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c +++ b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c @@ -1,6 +1,14 @@ -#include "z_obj_bean.h" +/* + * File: z_obj_bean.c + * Overlay: ovl_Obj_Bean + * Description: Floating Bean Plant / Soft Soil + */ -#define FLAGS 0x00400000 +#include "z_obj_bean.h" +#include "objects/object_mamenoki/object_mamenoki.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_400000) #define THIS ((ObjBean*)thisx) @@ -8,7 +16,50 @@ void ObjBean_Init(Actor* thisx, GlobalContext* globalCtx); void ObjBean_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjBean_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80937C10(ObjBean* this); +void func_80937C24(ObjBean* this); +void func_80937CA0(ObjBean* this); +void func_80937CE4(ObjBean* this); +void func_80937D54(ObjBean* this); +void func_80937DD8(ObjBean* this); +void func_80937DEC(ObjBean* this, GlobalContext* globalCtx); +void func_80937FB0(ObjBean* this); +void func_80937FC8(ObjBean* this, GlobalContext* globalCtx); +void func_809381B0(ObjBean* this); +void func_809381C4(ObjBean* this, GlobalContext* globalCtx); +void func_80938284(ObjBean* this); +void func_80938298(ObjBean* this, GlobalContext* globalCtx); +void func_8093833C(ObjBean* this); +void func_80938358(ObjBean* this, GlobalContext* globalCtx); +void func_809383B4(ObjBean* this); +void func_809383D0(ObjBean* this, GlobalContext* globalCtx); +void func_80938408(ObjBean* this); +void func_80938444(ObjBean* this, GlobalContext* globalCtx); +void func_809384E8(ObjBean* this); +void func_80938504(ObjBean* this, GlobalContext* globalCtx); +void func_80938588(ObjBean* this); +void func_809385A8(ObjBean* this, GlobalContext* globalCtx); +void func_80938670(ObjBean* this); +void func_8093868C(ObjBean* this, GlobalContext* globalCtx); +void func_80938704(ObjBean* this); +void func_80938728(ObjBean* this, GlobalContext* globalCtx); +void func_8093876C(ObjBean* this); +void func_80938780(ObjBean* this, GlobalContext* globalCtx); +void func_80938804(ObjBean* this); +void func_80938834(ObjBean* this, GlobalContext* globalCtx); +void func_80938874(ObjBean* this); +void func_809388A8(ObjBean* this, GlobalContext* globalCtx); +void func_8093892C(ObjBean* this); +void func_80938958(ObjBean* this, GlobalContext* globalCtx); +void func_809389BC(ObjBean* this, GlobalContext* globalCtx); +void func_80938A14(ObjBean* this); +void func_80938A5C(ObjBean* this, GlobalContext* globalCtx); +void func_80938AA4(ObjBean* this); +void func_80938AD8(ObjBean* this, GlobalContext* globalCtx); +void func_80938C1C(Actor* thisx, GlobalContext* globalCtx); +void func_80938E00(Actor* thisx, GlobalContext* globalCtx); +void func_80938F50(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Bean_InitVars = { ACTOR_OBJ_BEAN, ACTORCAT_BG, @@ -21,160 +72,895 @@ const ActorInit Obj_Bean_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80938FA0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 64, 30, -31, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80938FCC = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_OTHER, OC1_NONE, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_OTHER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 10, 10, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8093902C[] = { +static Vec2f D_80938FF8[4] = { + { 3.0f, 0.3f }, + { 10.0f, 0.5f }, + { 30.0f, 0.5f }, + { 3.0f, 0.3f }, +}; + +void func_80936CF0(ObjBean* this, GlobalContext* globalCtx) { + Vec3f sp24; + s32 sp20; + + sp24.x = this->dyna.actor.world.pos.x; + sp24.y = this->dyna.actor.world.pos.y + 29.999998f; + sp24.z = this->dyna.actor.world.pos.z; + this->dyna.actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &sp20, &this->dyna.actor, &sp24); +} + +s32 func_80936D58(ObjBean* this, GlobalContext* globalCtx) { + static Vec3f D_80939018 = { 0.0f, 30.0f, 0.0f }; + s32 pad; + s32 spB8; + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + Vec3f sp88; + MtxF sp48; + + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_80939018, &spAC); + Math_Vec3f_Sum(&this->dyna.actor.world.pos, &spAC, &spA0); + Math_Vec3f_Diff(&this->dyna.actor.world.pos, &spAC, &sp94); + + if (BgCheck_EntityLineTest2(&globalCtx->colCtx, &spA0, &sp94, &sp88, &this->dyna.actor.floorPoly, true, true, true, + true, &spB8, &this->dyna.actor)) { + this->dyna.actor.world.pos.x = (COLPOLY_GET_NORMAL(this->dyna.actor.floorPoly->normal.x) * 1.9f) + sp88.x; + this->dyna.actor.world.pos.y = (COLPOLY_GET_NORMAL(this->dyna.actor.floorPoly->normal.y) * 1.9f) + sp88.y; + this->dyna.actor.world.pos.z = (COLPOLY_GET_NORMAL(this->dyna.actor.floorPoly->normal.z) * 1.9f) + sp88.z; + func_800C0094(this->dyna.actor.floorPoly, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &sp48); + Matrix_Put(&sp48); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Get(&sp48); + Matrix_MtxFToYXZRot(&sp48, &this->dyna.actor.shape.rot, false); + return true; + } + return false; +} + +void func_80936F04(ObjBean* this) { + this->unk_1AC = this->unk_1AE = this->unk_1B0 = 0; + this->unk_1C8 = 0.0f; +} + +void func_80936F24(ObjBean* this) { + this->unk_1AC += 0xB6; + this->unk_1AE += 0xFB; + this->unk_1B0 += 0x64; + Math_StepToF(&this->unk_1C8, 2.0f, 0.1f); + this->unk_1CC = (Math_SinS(this->unk_1AC * 3) + Math_SinS(this->unk_1AE * 3)) * this->unk_1C8; + this->unk_1D0 = (Math_CosS(this->unk_1AC * 4) + Math_CosS(this->unk_1AE * 4)) * this->unk_1C8; + this->dyna.actor.scale.z = + ((Math_SinS(this->unk_1B0 * 5) * 0.06f) + (Math_SinS(this->unk_1AE * 8) * 0.01f) + 1.07f) * 0.1f; + this->dyna.actor.scale.x = this->dyna.actor.scale.z; + this->dyna.actor.scale.y = ((Math_CosS(this->unk_1B0 * 10) * 0.2f) + 1.0f) * 0.1f; + this->dyna.actor.shape.rot.y = (this->dyna.actor.home.rot.y + (s32)(Math_SinS(this->unk_1AC * 3) * 1000.0f)) + + (s32)(Math_SinS(this->unk_1B0 * 2) * 2100.0f); +} + +void func_80937130(ObjBean* this) { + this->unk_1AC = this->unk_1AE = this->unk_1B0 = 0; + Actor_SetScale(&this->dyna.actor, 0.0f); +} + +void func_80937160(ObjBean* this) { + this->unk_1AC += 0x384; + if (this->unk_1AC > 0x5FFF) { + this->unk_1AC = 0x5FFF; + } + + this->unk_1AE += 0x258; + if (this->unk_1AE > 0x4000) { + this->unk_1AE = 0x4000; + } + + this->dyna.actor.scale.y = Math_SinS(this->unk_1AC) * 0.16970563f; + this->dyna.actor.scale.x = this->dyna.actor.scale.z = Math_SinS(this->unk_1AE) * 0.10700001f; + Math_StepToF(&this->unk_1CC, 0.0f, 0.1f); + Math_StepToF(&this->unk_1D0, 0.0f, 0.1f); + Math_ScaledStepToS(&this->dyna.actor.shape.rot.y, this->dyna.actor.home.rot.y, 100); +} + +void func_80937238(ObjBean* this) { + this->dyna.actor.world.pos.x = this->unk_1BC.x + this->unk_1CC; + this->dyna.actor.world.pos.y = this->unk_1BC.y; + this->dyna.actor.world.pos.z = this->unk_1BC.z + this->unk_1D0; +} + +void func_80937268(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1D8 = globalCtx->setupPathList[OBJBEAN_GET_3F00(&this->dyna.actor)].count - 1; + this->unk_1DA = 0; + this->unk_1DC = 1; +} + +void func_809372A8(ObjBean* this) { + Math_Vec3s_ToVec3f(&this->unk_1BC, this->unk_1D4); +} + +void func_809372D0(ObjBean* this) { + Actor* actor = &this->dyna.actor; + Vec3f sp38; + f32 sp34; + f32 temp_f2; + f32 temp_f12; + + Math_Vec3s_ToVec3f(&sp38, &this->unk_1D4[this->unk_1DC]); + Math_Vec3f_Diff(&sp38, &this->unk_1BC, &actor->velocity); + + sp34 = Math3D_Vec3fMagnitude(&actor->velocity); + temp_f2 = D_80938FF8[this->unk_1DE].x; + temp_f12 = D_80938FF8[this->unk_1DE].z; + if (sp34 < (actor->speedXZ * 8.0f)) { + temp_f2 = ((temp_f2 - 2.0f) * 0.1f) + 2.0f; + temp_f12 *= 0.4f; + } + + Math_StepToF(&actor->speedXZ, temp_f2, temp_f12); + + if ((actor->speedXZ + 0.05f) < sp34) { + Math_Vec3f_Scale(&actor->velocity, actor->speedXZ / sp34); + this->unk_1BC.x += actor->velocity.x; + this->unk_1BC.y += actor->velocity.y; + this->unk_1BC.z += actor->velocity.z; + } else { + Math_Vec3f_Copy(&this->unk_1BC, &sp38); + this->unk_1DA = this->unk_1DC; + if (this->unk_1DA >= this->unk_1D8) { + this->unk_1DC = 0; + } else { + this->unk_1DC++; + } + actor->speedXZ *= 0.5f; + } +} + +s32 func_80937468(ObjBean* this, GlobalContext* globalCtx) { + Actor* bgActor = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; + + while (bgActor != NULL) { + if ((bgActor->id == ACTOR_EN_HORSE) && + (Math3D_Vec3fDistSq(&bgActor->world.pos, &this->dyna.actor.world.pos) < SQ(100.0f))) { + return true; + } + bgActor = bgActor->next; + } + + return false; +} + +ObjBean* func_809374F8(ObjBean* this, GlobalContext* globalCtx) { + Actor* bgActor = globalCtx->actorCtx.actorLists[ACTORCAT_BG].first; + s32 params = OBJBEAN_GET_3F80(&this->dyna.actor, 0); + + while (bgActor != NULL) { + if (bgActor->id == ACTOR_OBJ_BEAN) { + s32 params2 = OBJBEAN_GET_C000(bgActor); + + if (!params2 && (bgActor->room == this->dyna.actor.room) && !OBJBEAN_GET_80(bgActor) && + (params == OBJBEAN_GET_7F(bgActor, 0)) && + (Math3D_Vec3fDistSq(&bgActor->world.pos, &this->dyna.actor.world.pos) < SQ(10.0f))) { + break; + } + } + bgActor = bgActor->next; + } + + return (ObjBean*)bgActor; +} + +void func_809375C8(ObjBean* this, GlobalContext* globalCtx) { + ObjBean* bean = func_809374F8(this, globalCtx); + + if (bean != NULL) { + bean->unk_200 = 1; + } +} + +void func_809375F4(ObjBean* this, GlobalContext* globalCtx) { + static Gfx* D_80939024[] = { + gKakeraLeafMiddle, + gKakeraLeafTip, + }; + Vec3f spC4; + Vec3f spB8; + f32 temp_f20; + s32 temp_s2; + s16 temp_s1 = 0; + s32 phi_s3; + s32 phi_v0; + s32 i; + + for (i = 0; i < 36; i++) { + temp_s1 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 60.0f; + + spC4.x = (Math_SinS(temp_s1) * temp_f20) + this->dyna.actor.world.pos.x; + spC4.y = this->dyna.actor.world.pos.y; + spC4.z = (Math_CosS(temp_s1) * temp_f20) + this->dyna.actor.world.pos.z; + + spB8.x = Math_SinS(temp_s1) * 3.5f; + spB8.y = Rand_ZeroOne() * 13.0f; + spB8.z = Math_CosS(temp_s1) * 3.5f; + + spB8.x += this->dyna.actor.world.pos.x - this->dyna.actor.prevPos.x; + spB8.y += this->dyna.actor.world.pos.y - this->dyna.actor.prevPos.y; + spB8.z += this->dyna.actor.world.pos.z - this->dyna.actor.prevPos.z; + + temp_s2 = (s32)(Rand_ZeroOne() * 180.0f) + 30; + + phi_v0 = 0x40; + if (temp_s2 < 0x5A) { + phi_s3 = -0x50; + if (Rand_ZeroOne() < 0.1f) { + phi_v0 = 0x60; + } else { + phi_v0 = 0x40; + } + } else { + phi_s3 = -100; + phi_v0 = 0x40; + } + EffectSsKakera_Spawn(globalCtx, &spC4, &spB8, &spC4, phi_s3, phi_v0, 40, 3, 0, temp_s2, 0, 0, + (temp_s2 >> 3) + 40, -1, GAMEPLAY_KEEP, D_80939024[i & 1]); + } +} + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 2500, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif - -extern ColliderCylinderInit D_80938FA0; -extern ColliderCylinderInit D_80938FCC; -extern InitChainEntry D_8093902C[]; - -extern UNK_TYPE D_06000090; -extern UNK_TYPE D_060004BC; -extern UNK_TYPE D_06002208; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80936CF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80936D58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80936F04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80936F24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937130.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937160.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937268.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809372A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809372D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937468.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809374F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809375C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809375F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/ObjBean_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/ObjBean_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937B54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937C10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937C24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937C30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937CA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937CE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937D54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937DD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937DEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937FB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80937FC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809381B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809381C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938284.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938298.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_8093833C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938358.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809383B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809383D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938408.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938444.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809384E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938504.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938588.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809385A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938670.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_8093868C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938704.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938728.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_8093876C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938780.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938804.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938834.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938874.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809388A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_8093892C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938958.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938998.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_809389BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938A14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938A5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938AA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938AD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938C1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/ObjBean_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938E00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bean/func_80938F50.s") +void ObjBean_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjBean* this = THIS; + s32 sp2C = OBJBEAN_GET_C000(&this->dyna.actor); + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_1FE = 0; + this->unk_1B8 = 0.1f; + DynaPolyActor_Init(&this->dyna, 3); + Collider_InitCylinder(globalCtx, &this->collider); + + if ((sp2C == ENOBJBEAN_GET_C000_1) || (sp2C == ENOBJBEAN_GET_C000_2)) { + this->dyna.actor.update = func_80938C1C; + this->dyna.actor.textId = 0xFD; + if (sp2C == ENOBJBEAN_GET_C000_1) { + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit2); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + } + this->dyna.actor.flags |= ACTOR_FLAG_10; + func_80937C10(this); + if (!func_80936D58(this, globalCtx)) { + Actor_MarkForDeath(&this->dyna.actor); + } else { + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->dyna.actor, 7); + func_80937DD8(this); + } + } else { + s32 params2 = OBJBEAN_GET_3F00(&this->dyna.actor); + Path* path = &globalCtx->setupPathList[params2]; + + this->unk_1DE = OBJBEAN_GET_3(&this->dyna.actor); + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.home.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + this->unk_1FE |= 2; + + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_mamenoki_Colheader_0004BC); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit1); + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + + this->unk_1D4 = Lib_SegmentedToVirtual(path->points); + + func_80937268(this, globalCtx); + func_809372A8(this); + func_80937238(this); + ActorShape_Init(&this->dyna.actor.shape, 0.0f, ActorShadow_DrawCircle, 8.8f); + func_80936CF0(this, globalCtx); + + if (!OBJBEAN_GET_80(&this->dyna.actor) && Flags_GetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 0)) && + !Flags_GetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 1)) && func_800FE9B4(globalCtx)) { + Flags_SetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 1)); + } + + if (OBJBEAN_GET_80(&this->dyna.actor) || Flags_GetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 1))) { + func_80938804(this); + } else { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + func_80938704(this); + } + } +} + +void ObjBean_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjBean* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80937B54(ObjBean* this) { + Math_StepToS(&this->unk_1EE, this->unk_1F0, this->unk_1F2); + Math_StepToS(&this->unk_1F4, this->unk_1F6, this->unk_1F8); + this->unk_1FA += this->unk_1F4; + this->unk_1FC = 6372.0f - (Math_SinS(this->unk_1FA) * this->unk_1EE); + this->dyna.actor.scale.y = Math_SinS(this->unk_1FC) * 0.17434467f; + this->dyna.actor.scale.x = this->dyna.actor.scale.z = Math_CosS(this->unk_1FC) * 0.12207746f; +} + +void func_80937C10(ObjBean* this) { + this->unk_1E8 = func_80937C24; +} + +void func_80937C24(ObjBean* this) { +} + +void func_80937C30(ObjBean* this) { + this->unk_1E8 = func_80937CA0; + this->unk_1EC = Rand_S16Offset(12, 40); + this->unk_1F0 = Rand_S16Offset(200, 400); + this->unk_1F2 = 20; + this->unk_1F6 = Rand_S16Offset(100, 800); + this->unk_1F8 = 20; +} + +void func_80937CA0(ObjBean* this) { + this->unk_1EC--; + func_80937B54(this); + if (this->unk_1EC < 0) { + func_80937CE4(this); + } +} + +void func_80937CE4(ObjBean* this) { + this->unk_1E8 = func_80937D54; + this->unk_1EC = Rand_S16Offset(30, 4); + this->unk_1F0 = Rand_S16Offset(2000, 1000); + this->unk_1F2 = 200; + this->unk_1F6 = Rand_S16Offset(14000, 6000); + this->unk_1F8 = 4000; +} + +void func_80937D54(ObjBean* this) { + this->unk_1EC--; + if (this->unk_1EC == 14) { + this->unk_1F0 = Rand_S16Offset(200, 400); + this->unk_1F6 = Rand_S16Offset(100, 500); + this->unk_1F8 = 2000; + } + + func_80937B54(this); + + if (this->unk_1EC < 0) { + func_80937C30(this); + } +} + +void func_80937DD8(ObjBean* this) { + this->actionFunc = func_80937DEC; +} + +void func_80937DEC(ObjBean* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20 = OBJBEAN_GET_C000(&this->dyna.actor); + + if (sp20 == ENOBJBEAN_GET_C000_1) { + s32 pad2; + + if (func_809374F8(this, globalCtx) == NULL) { + this->unk_1FF = false; + } else { + this->unk_1FF = true; + } + } else { + this->unk_1FF = false; + } + + if (this->unk_1FF && !Flags_GetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 1)) && + Flags_GetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 0)) && func_800FE9B4(globalCtx)) { + Flags_SetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 1)); + } + + if (this->unk_1FF && Flags_GetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 1))) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + if (sp20 == ENOBJBEAN_GET_C000_2) { + this->dyna.actor.draw = func_80938F50; + } else { + this->dyna.actor.draw = func_80938E00; + } + + if (this->unk_1FF && Flags_GetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 0))) { + this->unk_1FE |= 5; + func_80937C30(this); + } else { + this->unk_1FE |= 1; + func_80937C10(this); + } + + if (Flags_GetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 0))) { + this->unk_1E4 = 5; + } else { + this->unk_1E4 = 0; + } + + func_80937FB0(this); +} + +void func_80937FB0(ObjBean* this) { + this->unk_1E0 = 0; + this->actionFunc = func_80937FC8; +} + +void func_80937FC8(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1E8(this); + + if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state)) { + if (Player_GetExchangeItemId(globalCtx) == EXCH_ITEM_2E) { + func_809383B4(this); + Flags_SetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 0)); + } + + if (Flags_GetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 0))) { + this->unk_1E4 = 5; + } else { + s32 pad; + + this->unk_1E4 = 0; + } + } else if (this->unk_1E4 == 1) { + this->unk_1DF = 16; + func_809381B0(this); + } else if (((this->collider.base.acFlags & AC_HIT) && (this->collider.base.ac != NULL) && + (this->collider.base.ac->id == ACTOR_OBJ_AQUA)) || + ((this->unk_1FF != 0) && (this->unk_1FE & 4) && (this->dyna.actor.xzDistToPlayer < 300.0f) && + func_800FE9B4(globalCtx))) { + func_809375C8(this, globalCtx); + Flags_SetSwitch(globalCtx, OBJBEAN_GET_3F80(&this->dyna.actor, 1)); + this->unk_1E4 = 6; + func_80938670(this); + } else if (this->unk_1FF != 0) { + if (this->unk_1FE & 4) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->dyna.actor.xzDistToPlayer < 150.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } else { + func_800B85E0(&this->dyna.actor, globalCtx, 28.0f, 0x2E); + } + } +} + +void func_809381B0(ObjBean* this) { + this->actionFunc = func_809381C4; +} + +void func_809381C4(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1E8(this); + + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + if (this->dyna.actor.cutscene >= 0) { + func_800B7298(globalCtx, &this->dyna.actor, 1); + } + this->unk_1E4 = 2; + func_80938284(this); + } else if (this->unk_1E4 == 4) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + play_sound(NA_SE_SY_ERROR); + this->unk_1E4 = 0; + func_80937FB0(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80938284(ObjBean* this) { + this->actionFunc = func_80938298; +} + +void func_80938298(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1E8(this); + + if (this->unk_1E0 >= 3) { + this->unk_1E4 = 3; + Flags_SetSwitch(globalCtx, OBJBEAN_GET_7F(&this->dyna.actor, 0)); + this->unk_1E4 = 5; + func_8093833C(this); + } else if (this->unk_1E4 == 4) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + play_sound(NA_SE_SY_ERROR); + this->unk_1E4 = 0; + func_80937FB0(this); + } +} + +void func_8093833C(ObjBean* this) { + this->actionFunc = func_80938358; + this->unk_1B2 = 4; +} + +void func_80938358(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1E8(this); + + if (this->unk_1B2 <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + func_80937FB0(this); + } +} + +void func_809383B4(ObjBean* this) { + this->unk_1B2 = 60; + this->actionFunc = func_809383D0; +} + +void func_809383D0(ObjBean* this, GlobalContext* globalCtx) { + if (this->unk_1B2 <= 0) { + this->unk_1FE |= 4; + func_80938408(this); + } +} + +void func_80938408(ObjBean* this) { + Actor_SetScale(&this->dyna.actor, 0.01f); + this->actionFunc = func_80938444; +} + +void func_80938444(ObjBean* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20 = Math_StepToF(&this->dyna.actor.scale.y, 0.16672663f, 0.01f) & 1; + + sp20 &= Math_StepToF(&this->dyna.actor.scale.x, 0.03569199f, 0.00113f); + + this->dyna.actor.scale.z = this->dyna.actor.scale.x; + if (sp20) { + if (this->unk_1B2 <= 0) { + func_809384E8(this); + } + } else { + this->unk_1B2 = 1; + } + func_800B9010(&this->dyna.actor, NA_SE_PL_PLANT_GROW_UP - SFX_FLAG); +} + +void func_809384E8(ObjBean* this) { + this->unk_1AC = 0x33E9; + this->actionFunc = func_80938504; +} + +void func_80938504(ObjBean* this, GlobalContext* globalCtx) { + this->unk_1AC -= 2400; + this->dyna.actor.scale.y = Math_SinS(this->unk_1AC) * 0.17434467f; + this->dyna.actor.scale.x = this->dyna.actor.scale.z = Math_CosS(this->unk_1AC) * 0.12207746f; + if (this->unk_1AC < 6372) { + func_80938588(this); + } +} + +void func_80938588(ObjBean* this) { + this->unk_1AC = 0; + this->unk_1AE = 3000; + this->actionFunc = func_809385A8; +} + +void func_809385A8(ObjBean* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp22; + + this->unk_1AC += 16000; + this->unk_1AE -= 200; + sp22 = 6372.0f - (Math_SinS(this->unk_1AC) * this->unk_1AE); + this->dyna.actor.scale.y = Math_SinS(sp22) * 0.17434467f; + this->dyna.actor.scale.x = this->dyna.actor.scale.z = Math_CosS(sp22) * 0.12207746f; + if (this->unk_1AE < 0) { + func_80937C30(this); + func_80937FB0(this); + } +} + +void func_80938670(ObjBean* this) { + this->actionFunc = func_8093868C; + this->unk_1B2 = 73; +} + +void func_8093868C(ObjBean* this, GlobalContext* globalCtx) { + if (this->unk_1B2 <= 0) { + Actor_MarkForDeath(&this->dyna.actor); + } else if (this->unk_1B2 <= 20) { + this->dyna.actor.scale.x *= 0.89f; + this->dyna.actor.scale.y *= 0.89f; + this->dyna.actor.scale.z *= 0.89f; + this->unk_1B8 *= 0.89f; + } +} + +void func_80938704(ObjBean* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->dyna.actor.draw = NULL; + this->actionFunc = func_80938728; +} + +void func_80938728(ObjBean* this, GlobalContext* globalCtx) { + if (this->unk_200 != 0) { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + func_8093876C(this); + } +} + +void func_8093876C(ObjBean* this) { + this->actionFunc = func_80938780; +} + +void func_80938780(ObjBean* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + if (this->dyna.actor.cutscene >= 0) { + func_800B7298(globalCtx, &this->dyna.actor, 1); + } + this->unk_1B4 = 36; + func_80937130(this); + func_80938AA4(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80938804(ObjBean* this) { + this->dyna.actor.flags &= ~ACTOR_FLAG_10; + this->dyna.actor.draw = func_80938E00; + this->actionFunc = func_80938834; +} + +void func_80938834(ObjBean* this, GlobalContext* globalCtx) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + func_80938874(this); + } + func_80936F24(this); +} + +void func_80938874(ObjBean* this) { + this->actionFunc = func_809388A8; + this->dyna.actor.draw = func_80938E00; + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->dyna.actor.speedXZ = 0.0f; +} + +void func_809388A8(ObjBean* this, GlobalContext* globalCtx) { + func_809372D0(this); + if (this->unk_1DA == this->unk_1D8) { + func_80937268(this, globalCtx); + func_809372A8(this); + func_8093892C(this); + } else if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + func_800B9010(&this->dyna.actor, NA_SE_PL_PLANT_MOVE - SFX_FLAG); + } + func_80936F24(this); +} + +void func_8093892C(ObjBean* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->dyna.actor.draw = func_80938E00; + this->actionFunc = func_80938958; +} + +void func_80938958(ObjBean* this, GlobalContext* globalCtx) { + if (!DynaPolyActor_IsInRidingRotatingState(&this->dyna)) { + func_80938804(this); + } + func_80936F24(this); +} + +void func_80938998(ObjBean* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->dyna.actor.draw = NULL; + this->actionFunc = func_809389BC; +} + +void func_809389BC(ObjBean* this, GlobalContext* globalCtx) { + if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + func_80937268(this, globalCtx); + func_809372A8(this); + func_80937238(this); + func_80938A14(this); + } +} + +void func_80938A14(ObjBean* this) { + this->dyna.actor.draw = NULL; + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->unk_1B2 = 100; + func_80937130(this); + this->actionFunc = func_80938A5C; +} + +void func_80938A5C(ObjBean* this, GlobalContext* globalCtx) { + if (func_80937468(this, globalCtx)) { + this->unk_1B2 = 100; + } else if (this->unk_1B2 <= 0) { + func_80938AA4(this); + } +} + +void func_80938AA4(ObjBean* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->dyna.actor.draw = func_80938E00; + this->unk_1B2 = 30; + this->actionFunc = func_80938AD8; +} + +void func_80938AD8(ObjBean* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30 = func_80937468(this, globalCtx); + + func_80937160(this); + if (this->unk_1B2 == 25) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_PL_PLANT_GROW_BIG); + } + + if (sp30 != 0) { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } else { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + + if (this->dyna.actor.xzDistToPlayer < 74.0f) { + Player* player = GET_PLAYER(globalCtx); + f32 sp28 = 74.0f - this->dyna.actor.xzDistToPlayer; + f32 sin; + f32 cos; + + if (sp28 > 8.0f) { + sp28 = 8.0f; + } + + sin = Math_SinS(this->dyna.actor.yawTowardsPlayer) * sp28; + cos = Math_CosS(this->dyna.actor.yawTowardsPlayer) * sp28; + + player->actor.world.pos.x += sin; + player->actor.world.pos.z += cos; + } + + if ((this->unk_1B2 <= 0) && (sp30 == 0)) { + func_80936F04(this); + func_80938804(this); + } +} + +void func_80938C1C(Actor* thisx, GlobalContext* globalCtx) { + ObjBean* this = THIS; + + if (this->unk_1B2 > 0) { + this->unk_1B2--; + } + + if (this->unk_1DF > 0) { + this->unk_1DF--; + if (this->unk_1DF == 0) { + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + } + + this->actionFunc(this, globalCtx); +} + +void ObjBean_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjBean* this = THIS; + + if (this->unk_1B2 > 0) { + this->unk_1B2--; + } + + this->actionFunc(this, globalCtx); + + if (this->unk_1B4 > 0) { + this->unk_1B4--; + if (this->unk_1B4 == 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + } + } + + if (this->dyna.actor.draw != NULL) { + func_80937238(this); + if (this->dyna.actor.xzDistToPlayer < 150.0f) { + this->collider.dim.radius = (this->dyna.actor.scale.x * 640.0f) + 0.5f; + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + func_80936CF0(this, globalCtx); + this->dyna.actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->dyna.actor.shape.shadowScale = this->dyna.actor.scale.x * 88.0f; + if (func_80937468(this, globalCtx)) { + func_809375F4(this, globalCtx); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + func_80938998(this); + } + } else { + this->dyna.actor.shape.shadowDraw = NULL; + } + Actor_SetFocus(&this->dyna.actor, 6.0f); +} + +void func_80938E00(Actor* thisx, GlobalContext* globalCtx) { + ObjBean* 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); + + if (this->unk_1FE & 4) { + gSPDisplayList(POLY_OPA_DISP++, object_mamenoki_DL_000090); + } + + if (this->unk_1FE & 2) { + gSPDisplayList(POLY_OPA_DISP++, object_mamenoki_DL_0002D0); + } + + if (this->unk_1FE & 1) { + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(this->unk_1B8, this->unk_1B8, this->unk_1B8, 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_mamenoki_DL_000530); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80938F50(Actor* thisx, GlobalContext* globalCtx) { + ObjBean* this = THIS; + + Gfx_DrawDListXlu(globalCtx, object_mamenoki_DL_002208); +} diff --git a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h index 876f2537a..da6e4a22c 100644 --- a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h +++ b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.h @@ -6,12 +6,57 @@ struct ObjBean; typedef void (*ObjBeanActionFunc)(struct ObjBean*, GlobalContext*); +typedef void (*ObjBeanUnkFunc)(struct ObjBean*); + +#define OBJBEAN_GET_7F(thisx, x) (((thisx)->params + (x)) & 0x7F) +#define OBJBEAN_GET_80(thisx) (((thisx)->params >> 7) & 1) +#define OBJBEAN_GET_3F00(thisx) (((thisx)->params >> 8) & 0x3F) +#define OBJBEAN_GET_3F80(thisx, x) ((((thisx)->params >> 7) + (x)) & 0x7F) +#define OBJBEAN_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) + +#define OBJBEAN_GET_3(thisx) ((thisx)->home.rot.z & 3) + +enum { + /* 0x00 */ ENOBJBEAN_GET_C000_0, + /* 0x01 */ ENOBJBEAN_GET_C000_1, + /* 0x02 */ ENOBJBEAN_GET_C000_2, +}; typedef struct ObjBean { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ ObjBeanActionFunc actionFunc; - /* 0x0160 */ char unk_160[0xA4]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ObjBeanActionFunc actionFunc; + /* 0x160 */ ColliderCylinder collider; + /* 0x1AC */ s16 unk_1AC; + /* 0x1AE */ s16 unk_1AE; + /* 0x1B0 */ s16 unk_1B0; + /* 0x1B2 */ s16 unk_1B2; + /* 0x1B4 */ s8 unk_1B4; + /* 0x1B8 */ f32 unk_1B8; + /* 0x1BC */ Vec3f unk_1BC; + /* 0x1C8 */ f32 unk_1C8; + /* 0x1CC */ f32 unk_1CC; + /* 0x1D0 */ f32 unk_1D0; + /* 0x1D4 */ Vec3s* unk_1D4; + /* 0x1D8 */ s16 unk_1D8; + /* 0x1DA */ s16 unk_1DA; + /* 0x1DC */ s16 unk_1DC; + /* 0x1DE */ s8 unk_1DE; + /* 0x1DF */ s8 unk_1DF; + /* 0x1E0 */ s8 unk_1E0; + /* 0x1E4 */ s32 unk_1E4; + /* 0x1E8 */ ObjBeanUnkFunc unk_1E8; + /* 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; + /* 0x1FE */ u8 unk_1FE; + /* 0x1FF */ u8 unk_1FF; + /* 0x200 */ u8 unk_200; } ObjBean; // size = 0x204 extern const ActorInit Obj_Bean_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.c b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.c index de7f30fbd..602311116 100644 --- a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.c +++ b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.c @@ -5,8 +5,9 @@ */ #include "z_obj_bell.h" +#include "objects/object_f52_obj/object_f52_obj.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjBell*)thisx) @@ -111,14 +112,6 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(1, 0xE), }; -extern CollisionHeader D_06001BA8; -extern Gfx D_06000570[]; // Bell post -extern Gfx D_06000698[]; // Bell -extern Gfx D_060007A8[]; // Bell Base -extern Gfx D_06000840[]; // Bell Shadow -extern Gfx D_060008D0[]; // Bell Hook -extern Gfx D_06000960[]; // Bell Designs - s32 func_80A35510(ObjBell* this, s32 arg1) { Vec3f bumperPos; Vec3f worldPos; @@ -126,19 +119,16 @@ s32 func_80A35510(ObjBell* this, s32 arg1) { if (((arg1 == 0) && (this->unk_21C < 1000.0f)) || ((arg1 == 1) && (this->unk_21C < 4000.0f)) || (arg1 == 2)) { phi_a3 = true; - } else { - phi_a3 = phi_a3; } switch (arg1) { case 0: - this->unk_21C += this->unk_21C > 1000.0f ? 250.0f : 1000.0f; + this->unk_21C += ((this->unk_21C > 1000.0f) ? 250.0f : 1000.0f); break; case 1: - this->unk_21C += this->unk_21C > 3000.0f ? 750.0f : 3000.0f; + this->unk_21C += ((this->unk_21C > 3000.0f) ? 750.0f : 3000.0f); break; case 2: - if (1) {} this->unk_21C += 9000.0f; break; } @@ -198,11 +188,11 @@ s32 func_80A357A8(ObjBell* this, GlobalContext* globalCtx) { this->unk_20E = 10; switch (this->dyna.actor.colChkInfo.damageEffect) { case 15: - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BIGBELL); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIGBELL); func_80A35510(this, 1); break; case 14: - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BIGBELL); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BIGBELL); func_80A35510(this, 2); break; default: @@ -223,49 +213,49 @@ void func_80A358FC(ObjBell* this, GlobalContext* globalCtx) { } void func_80A359B4(Actor* thisx, GlobalContext* globalCtx) { - Matrix_InsertTranslation(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); + Matrix_Translate(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); - Matrix_InsertTranslation(0.0f, 2600.0f, 0.0f, MTXMODE_APPLY); - Matrix_RotateY(thisx->world.rot.y, MTXMODE_APPLY); - Matrix_InsertXRotation_s(thisx->world.rot.x, MTXMODE_APPLY); - Matrix_RotateY(-thisx->world.rot.y, MTXMODE_APPLY); - Matrix_InsertTranslation(0.0f, -2600.0f, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 2600.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateYS(thisx->world.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(thisx->world.rot.x, MTXMODE_APPLY); + Matrix_RotateYS(-thisx->world.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, -2600.0f, 0.0f, MTXMODE_APPLY); 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_06000698); - gSPDisplayList(POLY_OPA_DISP++, D_060008D0); - gSPDisplayList(POLY_OPA_DISP++, D_06000960); - gSPDisplayList(POLY_OPA_DISP++, D_060007A8); + gSPDisplayList(POLY_OPA_DISP++, object_f52_obj_DL_000698); + gSPDisplayList(POLY_OPA_DISP++, object_f52_obj_DL_0008D0); + gSPDisplayList(POLY_OPA_DISP++, object_f52_obj_DL_000960); + gSPDisplayList(POLY_OPA_DISP++, object_f52_obj_DL_0007A8); CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80A35B18(Actor* thisx, GlobalContext* globalCtx) { - Matrix_InsertTranslation(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, MTXMODE_NEW); + Matrix_Translate(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.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_RotateYS(thisx->shape.rot.y, MTXMODE_APPLY); 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_06000570); + gSPDisplayList(POLY_OPA_DISP++, object_f52_obj_DL_000570); CLOSE_DISPS(globalCtx->state.gfxCtx); } void func_80A35BD4(Actor* thisx, GlobalContext* globalCtx) { - Matrix_InsertTranslation(thisx->world.pos.x, thisx->world.pos.y - 4.0f, thisx->world.pos.z, MTXMODE_NEW); + Matrix_Translate(thisx->world.pos.x, thisx->world.pos.y - 4.0f, thisx->world.pos.z, MTXMODE_NEW); Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); 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); - gSPDisplayList(POLY_XLU_DISP++, D_06000840); + gSPDisplayList(POLY_XLU_DISP++, object_f52_obj_DL_000840); CLOSE_DISPS(globalCtx->state.gfxCtx); } void ObjBell_Init(Actor* thisx, GlobalContext* globalCtx) { ObjBell* this = THIS; - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06001BA8); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_f52_obj_Colheader_001BA8); Actor_SetScale(&this->dyna.actor, 0.08f); Collider_InitAndSetSphere(globalCtx, &this->collider1, &this->dyna.actor, &sCylinderInit1); Collider_InitAndSetSphere(globalCtx, &this->collider2, &this->dyna.actor, &sCylinderInit2); @@ -275,7 +265,7 @@ void ObjBell_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjBell_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjBell* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroySphere(globalCtx, &this->collider1); Collider_DestroySphere(globalCtx, &this->collider2); } @@ -300,9 +290,9 @@ void ObjBell_Draw(Actor* thisx, GlobalContext* globalCtx) { func_80A35BD4(thisx, globalCtx); func_80A359B4(thisx, globalCtx); Math_Vec3s_ToVec3f(&sp30, &this->collider1.dim.modelSphere.center); - Matrix_MultiplyVector3fByState(&sp30, &sp24); + Matrix_MultVec3f(&sp30, &sp24); Math_Vec3f_ToVec3s(&this->collider1.dim.worldSphere.center, &sp24); Math_Vec3s_ToVec3f(&sp30, &this->collider2.dim.modelSphere.center); - Matrix_MultiplyVector3fByState(&sp30, &sp24); + Matrix_MultVec3f(&sp30, &sp24); Math_Vec3f_ToVec3s(&this->collider2.dim.worldSphere.center, &sp24); } 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.c b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.c index c7d0abb14..8a1ae2df7 100644 --- a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.c +++ b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.c @@ -1,4 +1,12 @@ +/* + * File: z_obj_bigicicle.c + * Overlay: ovl_Obj_Bigicicle + * Description: Large icicles + */ + #include "z_obj_bigicicle.h" +#include "overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h" +#include "objects/object_bigicicle/object_bigicicle.h" #define FLAGS 0x00000000 @@ -15,7 +23,6 @@ void func_80AE9180(ObjBigicicle* this, GlobalContext* globalCtx); void func_80AE9258(ObjBigicicle* this, GlobalContext* globalCtx); void func_80AE939C(ObjBigicicle* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Bigicicle_InitVars = { ACTOR_OBJ_BIGICICLE, ACTORCAT_PROP, @@ -28,51 +35,287 @@ const ActorInit Obj_Bigicicle_InitVars = { (ActorFunc)ObjBigicicle_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AE9820 = { - { COLTYPE_HARD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HARD, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00003820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 23, 68, -40, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AE984C = { - { 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 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + 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 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 31, 90, -150, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AE9888[] = { +AnimatedMaterial* D_80AE9878 = object_bigicicle_Matanimheader_001678; + +Vec3f D_80AE987C = { 0.0f, -1.0f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(gravity, -2, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 5600, ICHAIN_STOP), }; -#endif +s32 D_80AE9890 = false; -extern ColliderCylinderInit D_80AE9820; -extern ColliderCylinderInit D_80AE984C; -extern InitChainEntry D_80AE9888[]; +Color_RGBA8 D_80AE9894 = { 250, 250, 250, 255 }; +Color_RGBA8 D_80AE9898 = { 180, 180, 180, 255 }; -extern UNK_TYPE D_060009B0; -extern UNK_TYPE D_060014F0; +Gfx* D_80AE989C[] = { object_bigicicle_DL_001D10, object_bigicicle_DL_002530, object_bigicicle_DL_002C20 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/ObjBigicicle_Init.s") +Gfx* D_80AE98A8[] = { + object_bigicicle_DL_000B20, + object_bigicicle_DL_000D60, + object_bigicicle_DL_000F40, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/ObjBigicicle_Destroy.s") +void ObjBigicicle_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjBigicicle* this = THIS; + f32 sp30; + s32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE8DE4.s") + Actor_ProcessInitChain(&this->actor, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE8FD4.s") + sp28 = OBJBIGICLE_GET_FF00(&this->actor); + if ((sp28 == 0) || (sp28 == 0xFF)) { + sp28 = 0x3C; + } + Actor_SetScale(&this->actor, sp28 * 0.001f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE9090.s") + this->actor.params &= 0xFF; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + sp30 = sp28 * (1.0f / 60.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE9180.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + this->collider1.dim.radius = this->collider1.dim.radius * sp30; + this->collider1.dim.height = this->collider1.dim.height * sp30; + this->collider1.dim.yShift = this->collider1.dim.yShift * sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE9258.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); + this->collider2.dim.radius = this->collider2.dim.radius * sp30; + this->collider2.dim.height = this->collider2.dim.height * sp30; + this->collider2.dim.yShift = this->collider2.dim.yShift * sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/func_80AE939C.s") + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/ObjBigicicle_Update.s") + this->unk_148 = this->actor.shape.rot.x; + this->actor.shape.rot.x = 0x4000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bigicicle/ObjBigicicle_Draw.s") + Collider_UpdateCylinder(&this->actor, &this->collider1); + Collider_UpdateCylinder(&this->actor, &this->collider2); + + if (!D_80AE9890) { + D_80AE9878 = Lib_SegmentedToVirtual(D_80AE9878); + D_80AE9890 = true; + } + + this->unk_149 = 0; + this->actionFunc = func_80AE8FD4; +} + +void ObjBigicicle_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjBigicicle* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); +} + +void func_80AE8DE4(ObjBigicicle* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp98; + Vec3f sp8C; + f32 temp_f20 = this->actor.scale.x * (50.0f / 3.0f); + + for (i = 0; i < 10; i++) { + sp98.x = (randPlusMinusPoint5Scaled(4.0f) * temp_f20) + this->actor.world.pos.x; + sp98.y = ((Rand_ZeroFloat(20.0f) - 35.0f) * temp_f20) + this->actor.world.pos.y; + sp98.z = (randPlusMinusPoint5Scaled(4.0f) * temp_f20) + this->actor.world.pos.z; + + sp8C.x = randPlusMinusPoint5Scaled(13.0f); + sp8C.y = Rand_ZeroFloat(2.0f); + sp8C.z = randPlusMinusPoint5Scaled(13.0f); + + EffectSsHahen_Spawn(globalCtx, &sp98, &sp8C, &D_80AE987C, 2, (Rand_ZeroFloat(20.0f) + 30.0f) * temp_f20, + OBJECT_BIGICICLE, 0x28, object_bigicicle_DL_0009B0); + } + + sp98.x = this->actor.world.pos.x; + sp98.y = this->actor.world.pos.y - (25.0f * temp_f20); + sp98.z = this->actor.world.pos.z; + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &sp98, 40, NA_SE_EV_ICE_PIECE); +} + +void func_80AE8FD4(ObjBigicicle* this, GlobalContext* globalCtx) { + if ((this->collider1.base.acFlags & AC_HIT) || + ((this->collider2.base.acFlags & AC_HIT) && (this->collider2.info.acHitInfo->toucher.dmgFlags & 0x3820))) { + if ((this->unk_148 == 0) || (this->unk_149 == 1)) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = func_80AE9090; + return; + } + + func_80AE8DE4(this, globalCtx); + this->unk_149++; + this->unk_14A = 50; + this->actionFunc = func_80AE9180; + } +} + +void func_80AE9090(ObjBigicicle* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->unk_149++; + func_80AE8DE4(this, globalCtx); + if (this->unk_149 == 2) { + f32 temp_f0 = this->actor.scale.y * 2100.0f; + + this->actor.flags |= ACTOR_FLAG_10; + this->actor.shape.yOffset = 2100.0f; + this->actor.world.pos.y -= temp_f0; + this->collider1.dim.yShift += (s16)temp_f0; + this->collider2.dim.yShift += (s16)temp_f0; + this->actionFunc = func_80AE9258; + } else { + this->unk_14A = 50; + this->actionFunc = func_80AE9180; + } + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80AE9180(ObjBigicicle* this, GlobalContext* globalCtx) { + this->unk_14A--; + + if (this->unk_14A > 0) { + this->unk_14A--; + this->actor.shape.rot.x = BINANG_ADD((s32)(randPlusMinusPoint5Scaled(1408.0f) * 0.02f * this->unk_14A), 0x4000); + this->actor.shape.rot.z = randPlusMinusPoint5Scaled(1408.0f) * 0.02f * this->unk_14A; + } else { + this->actor.shape.rot.x = 0x4000; + this->actor.shape.rot.z = 0; + ActorCutscene_Stop(this->actor.cutscene); + this->actionFunc = func_80AE8FD4; + } +} + +void func_80AE9258(ObjBigicicle* this, GlobalContext* globalCtx) { + Actor* itemAction; + f32 temp_f0; + ObjIcePoly* icePoly; + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + itemAction = globalCtx->actorCtx.actorLists[ACTORCAT_ITEMACTION].first; + + while (itemAction != NULL) { + if (itemAction->id == ACTOR_OBJ_ICE_POLY) { + icePoly = (ObjIcePoly*)itemAction; + temp_f0 = this->actor.world.pos.y - icePoly->actor.world.pos.y; + if ((temp_f0 < icePoly->colliders1[0].dim.height) && (temp_f0 > 0.0f) && + (Actor_XZDistanceBetweenActors(&this->actor, &icePoly->actor) < icePoly->colliders1[0].dim.radius)) { + Flags_SetSwitch(globalCtx, this->actor.params); + this->actionFunc = func_80AE939C; + return; + } + } + itemAction = itemAction->next; + } + + if (this->actor.bgCheckFlags & 1) { + this->actionFunc = func_80AE939C; + } else { + Collider_UpdateCylinder(&this->actor, &this->collider1); + Collider_UpdateCylinder(&this->actor, &this->collider2); + } +} + +void func_80AE939C(ObjBigicicle* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp98; + Vec3f sp8C; + f32 temp_f20 = this->actor.scale.x * (50.0f / 3.0f); + + for (i = 0; i < 20; i++) { + sp8C.x = randPlusMinusPoint5Scaled(15.0f); + sp8C.y = Rand_ZeroFloat(7.0f) + 3.0f; + sp8C.z = randPlusMinusPoint5Scaled(15.0f); + + sp98.x = this->actor.world.pos.x + (sp8C.x * 5.0f * temp_f20); + sp98.y = this->actor.world.pos.y + (sp8C.y * 7.0f * temp_f20); + sp98.z = this->actor.world.pos.z + (sp8C.z * 5.0f * temp_f20); + + EffectSsHahen_Spawn(globalCtx, &sp98, &sp8C, &D_80AE987C, 2, (Rand_ZeroFloat(30.0f) + 40.0f) * temp_f20, + OBJECT_BIGICICLE, 30, object_bigicicle_DL_0009B0); + } + + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_GLASSBROKEN_IMPACT); + ActorCutscene_Stop(this->actor.cutscene); + Actor_MarkForDeath(&this->actor); +} + +void ObjBigicicle_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjBigicicle* this = THIS; + Vec3f sp44; + + this->actionFunc(this, globalCtx); + + if (Rand_ZeroOne() < 0.05f) { + sp44.x = (((215.0f + Rand_ZeroFloat(65.0f)) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1)) * this->actor.scale.x) + + this->actor.world.pos.x; + sp44.y = ((((Rand_ZeroFloat(1400.0f) + -150.0f) - 2100.0f) + this->actor.shape.yOffset) * this->actor.scale.y) + + this->actor.world.pos.y; + sp44.z = (((215.0f + Rand_ZeroFloat(65.0f)) * ((Rand_ZeroOne() < 0.5f) ? -1 : 1)) * this->actor.scale.z) + + this->actor.world.pos.z; + + EffectSsKirakira_SpawnDispersed(globalCtx, &sp44, &gZeroVec3f, &gZeroVec3f, &D_80AE9894, &D_80AE9898, 2000, 5); + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); +} + +void ObjBigicicle_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjBigicicle* this = THIS; + + Gfx_DrawDListXlu(globalCtx, D_80AE989C[this->unk_149]); + Gfx_DrawDListXlu(globalCtx, D_80AE98A8[this->unk_149]); + AnimatedMat_Draw(globalCtx, D_80AE9878); + Gfx_DrawDListXlu(globalCtx, object_bigicicle_DL_0014F0); +} 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..1744a81b4 100644 --- a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h +++ b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h @@ -7,10 +7,16 @@ struct ObjBigicicle; typedef void (*ObjBigicicleActionFunc)(struct ObjBigicicle*, GlobalContext*); +#define OBJBIGICLE_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + typedef struct ObjBigicicle { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjBigicicleActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ u8 unk_148; + /* 0x0149 */ u8 unk_149; + /* 0x014A */ s16 unk_14A; + /* 0x014C */ ColliderCylinder collider1; + /* 0x0198 */ ColliderCylinder collider2; } 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 f5995d718..2d3a6f2d5 100644 --- a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c +++ b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c @@ -1,15 +1,22 @@ -#include "z_obj_blockstop.h" +/* + * File: z_obj_blockstop.c + * Overlay: ovl_Obj_Blockstop + * Description: Push Block Trigger - Blockstop switch triggered by pushblock (Snowhead) + */ -#define FLAGS 0x00000010 +#include "z_obj_blockstop.h" +#include "overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjBlockstop*)thisx) void ObjBlockstop_Init(Actor* thisx, GlobalContext* globalCtx); void ObjBlockstop_Update(Actor* thisx, GlobalContext* globalCtx); -void func_809466F0(ObjBlockstop* this, GlobalContext* globalCtx); +void ObjBlockstop_CheckForBlock(ObjBlockstop* this, GlobalContext* globalCtx); +void ObjBlockstop_TryPlayCutscene(ObjBlockstop* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Blockstop_InitVars = { ACTOR_OBJ_BLOCKSTOP, ACTORCAT_PROP, @@ -22,12 +29,47 @@ const ActorInit Obj_Blockstop_InitVars = { (ActorFunc)NULL, }; -#endif +void ObjBlockstop_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjBlockstop* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Blockstop/ObjBlockstop_Init.s") + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + Actor_MarkForDeath(&this->actor); + } + this->actionFunc = ObjBlockstop_CheckForBlock; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Blockstop/func_809466F0.s") +void ObjBlockstop_CheckForBlock(ObjBlockstop* this, GlobalContext* globalCtx) { + Actor* prop = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Blockstop/func_809467E8.s") + while (prop != NULL) { + if ((prop->id == ACTOR_OBJ_OSHIHIKI) && (fabsf(prop->world.pos.x - this->actor.world.pos.x) < 20.0f) && + (fabsf(prop->world.pos.z - this->actor.world.pos.z) < 20.0f) && + (fabsf(prop->world.pos.y - this->actor.world.pos.y) < 20.0f)) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Blockstop/ObjBlockstop_Update.s") + s32 params = OBJOSHIHIKI_GET_F(prop); + if (params < 3) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = ObjBlockstop_TryPlayCutscene; + } + } + prop = prop->next; + } +} + +void ObjBlockstop_TryPlayCutscene(ObjBlockstop* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + Flags_SetSwitch(globalCtx, this->actor.params); + if (ActorCutscene_GetLength(this->actor.cutscene) != -1) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + } + Actor_MarkForDeath(&this->actor); + return; + } + ActorCutscene_SetIntentToPlay(this->actor.cutscene); +} + +void ObjBlockstop_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjBlockstop* this = THIS; + + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Boat/z_obj_boat.c b/src/overlays/actors/ovl_Obj_Boat/z_obj_boat.c index 70c672628..880d72b3f 100644 --- a/src/overlays/actors/ovl_Obj_Boat/z_obj_boat.c +++ b/src/overlays/actors/ovl_Obj_Boat/z_obj_boat.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_boat.c + * Overlay: ovl_Obj_Boat + * Description: Pirate Boat + */ + #include "z_obj_boat.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjBoat*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c index ad40c5a75..55304d195 100644 --- a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c +++ b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_bombiwa.c + * Overlay: ovl_Obj_Bombiwa + * Description: Bombable boulder + */ + #include "z_obj_bombiwa.h" +#include "objects/object_bombiwa/object_bombiwa.h" #define FLAGS 0x00000000 @@ -8,10 +15,15 @@ void ObjBombiwa_Init(Actor* thisx, GlobalContext* globalCtx); void ObjBombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjBombiwa_Update(Actor* thisx, GlobalContext* globalCtx); +s32 func_809393B0(Actor* thisx); +s32 func_80939470(Actor* thisx); +void func_80939EE0(ObjBombiwa* this); void func_80939EF4(ObjBombiwa* this, GlobalContext* globalCtx); +void func_8093A080(ObjBombiwa* this); void func_8093A1F0(ObjBombiwa* this, GlobalContext* globalCtx); +void func_8093A418(Actor* thisx, GlobalContext* globalCtx); +void func_8093A608(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Bombiwa_InitVars = { ACTOR_OBJ_BOMBIWA, ACTORCAT_PROP, @@ -24,70 +36,495 @@ const ActorInit Obj_Bombiwa_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8093A940 = { - { 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 }, { 0x81C37FBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + 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 }, + { 0x81C37FBE, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 55, 70, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8093A96C = { - { 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 }, { 0x81C37BBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + 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 }, + { 0x81C37BBE, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 75, 130, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_8093A9B8 = { 0, 12, 60, MASS_IMMOVABLE }; +typedef struct { + /* 0x00 */ ColliderCylinderInit* collider; + /* 0x04 */ ActorShadowFunc unk_04; + /* 0x08 */ ActorFunc unk_08; + /* 0x0C */ s32 (*unk_0C)(Actor*); +} ObjBombiwaStruct2; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8093A9C0[] = { +static ObjBombiwaStruct2 D_8093A998[] = { + { &sCylinderInit1, ActorShadow_DrawCircle, func_8093A418, func_809393B0 }, + { &sCylinderInit2, NULL, func_8093A608, func_80939470 }, +}; + +static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -#endif +static s16 D_8093A9D0[] = { + 17, 14, 10, 8, 7, 5, 3, 2, +}; -extern ColliderCylinderInit D_8093A940; -extern ColliderCylinderInit D_8093A96C; -extern CollisionCheckInfoInit D_8093A9B8; -extern InitChainEntry D_8093A9C0[]; +static s16 D_8093A9E0[] = { + 16, 12, 8, 6, 5, 4, 3, 2, +}; -extern UNK_TYPE D_060009E0; -extern UNK_TYPE D_06004560; -extern UNK_TYPE D_06005990; +s32 func_809393B0(Actor* thisx) { + ObjBombiwa* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_809393B0.s") + if (this->collider.base.acFlags & AC_HIT) { + Actor* ac = this->collider.base.ac; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939470.s") + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000000) { + if ((ac != NULL) && (Math3D_Vec3fDistSq(&this->actor.world.pos, &ac->world.pos) < SQ(150.0f))) { + return true; + } + } else if (this->collider.info.acHitInfo->toucher.dmgFlags & 8) { + if ((ac != NULL) && (Math3D_Vec3fDistSq(&this->actor.world.pos, &ac->world.pos) < SQ(95.0f))) { + return true; + } + } else if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x500) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_8093951C.s") +s32 func_80939470(Actor* thisx) { + ObjBombiwa* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939594.s") + if (this->collider.base.acFlags & AC_HIT) { + Actor* temp_v0 = this->collider.base.ac; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/ObjBombiwa_Init.s") + if (temp_v0 != NULL) { + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000000) { + if (Math3D_Vec3fDistSq(&this->actor.world.pos, &temp_v0->world.pos) < SQ(175.0f)) { + return true; + } + } else if ((this->collider.info.acHitInfo->toucher.dmgFlags & 8) && + (Math3D_Vec3fDistSq(&this->actor.world.pos, &temp_v0->world.pos) < SQ(115.0f))) { + return true; + } + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/ObjBombiwa_Destroy.s") +s32 func_8093951C(ObjBombiwa* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* sp30; + f32 sp2C; + s32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939794.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_Obj_Bombiwa/func_80939994.s") +void func_80939594(ObjBombiwa* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp28; + s32 sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939C50.s") + sp28.x = this->actor.world.pos.x; + sp28.y = this->actor.world.pos.y + 30.0f; + sp28.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939EE0.s") + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp24, &this->actor, &sp28); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_80939EF4.s") +void ObjBombiwa_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjBombiwa* this = THIS; + s32 sp34 = OBJBOMBIWA_GET_100(&this->actor); + s32 pad2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_8093A080.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitCylinder(globalCtx, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_8093A1F0.s") + if (Flags_GetSwitch(globalCtx, OBJBOMBIWA_GET_7F(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/ObjBombiwa_Update.s") + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, D_8093A998[sp34].collider); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_8093A418.s") + if (sp34 == OBJBOMBIWA_100_0) { + if (this->actor.shape.rot.y == 0) { + this->actor.shape.rot.y = this->actor.world.rot.y = (u32)Rand_Next() >> 0x10; + } + func_80939594(this, globalCtx); + } + ActorShape_Init(&this->actor.shape, -200.0f, D_8093A998[sp34].unk_04, 9.8f); + this->actor.world.pos.y = this->actor.home.pos.y + 20.0f; + this->actor.draw = D_8093A998[sp34].unk_08; + if (func_8093951C(this, globalCtx)) { + this->unk_203 |= 1; + } + func_80939EE0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Bombiwa/func_8093A608.s") +void ObjBombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyCylinder(globalCtx, &THIS->collider); +} + +void func_80939794(ObjBombiwa* this, GlobalContext* globalCtx) { + Vec3f spB4; + Vec3f spA8; + s32 phi_v1; + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_8093A9D0); i++) { + spB4.x = ((Rand_ZeroOne() - 0.5f) * 10.0f) + this->actor.home.pos.x; + spB4.y = (Rand_ZeroOne() * 5.0f) + this->actor.home.pos.y + 8.0f; + spB4.z = ((Rand_ZeroOne() - 0.5f) * 10.0f) + this->actor.home.pos.z; + + spA8.x = (Rand_ZeroOne() - 0.5f) * 15.0f; + spA8.y = (Rand_ZeroOne() * 16.0f) + 5.0f; + spA8.z = (Rand_ZeroOne() - 0.5f) * 15.0f; + + if (D_8093A9D0[i] > 10) { + phi_v1 = 0x25; + } else { + phi_v1 = 0x21; + } + EffectSsKakera_Spawn(globalCtx, &spB4, &spA8, &spB4, -400, phi_v1, 10, 2, 0, D_8093A9D0[i], 1, 0, 60, -1, + OBJECT_BOMBIWA, object_bombiwa_DL_0009E0); + } + + func_800BBFB0(globalCtx, &this->actor.world.pos, 60.0f, 8, 80, 140, 1); +} + +void func_80939994(GlobalContext* globalCtx, Vec3f* arg1) { + Vec3f spAC; + Vec3f spA0; + s16 phi_v0; + s16 life; + s32 i; + + for (i = 0; i < 16; i++) { + spAC.x = (Rand_ZeroOne() - 0.5f) * 80.0f; + spAC.y = Rand_ZeroOne() * 120.0f; + spAC.z = (Rand_ZeroOne() - 0.5f) * 80.0f; + + spA0.x = ((Rand_ZeroOne() - 0.5f) * 3.0f) + (spAC.x * 0.2f); + spA0.y = (Rand_ZeroOne() * 16.0f) + 5.0f; + spA0.z = ((Rand_ZeroOne() - 0.5f) * 3.0f) + (spAC.z * 0.2f); + + spAC.x += arg1->x; + spAC.y += arg1->y; + spAC.z += arg1->z; + + if (i >= 14) { + phi_v0 = 33; + life = 60; + } else if (i >= 12) { + phi_v0 = 65; + life = 60; + } else { + life = 40; + if (Rand_ZeroOne() < 0.7f) { + phi_v0 = 64; + } else { + phi_v0 = 32; + } + } + EffectSsKakera_Spawn(globalCtx, &spAC, &spA0, &spAC, -450, phi_v0, 15, 0, 0, i, 1, 0, life, -1, OBJECT_BOMBIWA, + object_bombiwa_DL_005990); + } + + func_800BBFB0(globalCtx, arg1, 120.0f, 3, 80, 140, 1); + + spAC.x = arg1->x; + spAC.y = arg1->y + 70.0f; + spAC.z = arg1->z; + + func_800BBFB0(globalCtx, &spAC, 120.0f, 3, 80, 140, 1); +} + +void func_80939C50(GlobalContext* globalCtx, Vec3f* arg1) { + Vec3f spBC; + Vec3f spB0; + s32 phi_v0; + s32 phi_s0; + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_8093A9E0); i++) { + spBC.x = (Rand_ZeroOne() - 0.5f) * 15.0f; + spBC.y = (Rand_ZeroOne() - 0.2f) * 10.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) * 15.0f; + + spB0.x = ((Rand_ZeroOne() - 0.5f) * 3.0f) + (spBC.x * 0.85f); + spB0.y = (Rand_ZeroOne() * 15.0f) + 8.0f; + spB0.z = ((Rand_ZeroOne() - 0.5f) * 3.0f) + (spBC.z * 0.85f); + + spBC.x += arg1->x; + spBC.y += arg1->y; + spBC.z += arg1->z; + + if (i == 0) { + phi_v0 = 33; + phi_s0 = 60; + } else if (i == 1) { + phi_v0 = 65; + phi_s0 = 60; + } else { + phi_s0 = 40; + if (Rand_ZeroOne() < 0.7f) { + phi_v0 = 64; + } else { + phi_v0 = 32; + } + } + EffectSsKakera_Spawn(globalCtx, &spBC, &spB0, &spBC, -450, phi_v0, 15, 0, 0, D_8093A9E0[i], 1, 0, phi_s0, -1, + OBJECT_BOMBIWA, object_bombiwa_DL_005990); + } + + func_800BBFB0(globalCtx, arg1, 60.0f, 4, 80, 140, 1); +} + +void func_80939EE0(ObjBombiwa* this) { + this->actionFunc = func_80939EF4; +} + +void func_80939EF4(ObjBombiwa* this, GlobalContext* globalCtx) { + s32 pad; + s32 params = OBJBOMBIWA_GET_100(&this->actor); + ObjBombiwaStruct2* sp28 = &D_8093A998[params]; + + if (this->collider.base.acFlags & AC_HIT) { + this->unk_202 = 5; + } + + if (sp28->unk_0C(&this->actor)) { + Flags_SetSwitch(globalCtx, OBJBOMBIWA_GET_7F(&this->actor)); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_WALL_BROKEN); + if (OBJBOMBIWA_GET_8000(&this->actor)) { + play_sound(NA_SE_SY_CORRECT_CHIME); + } + + if (params == OBJBOMBIWA_100_0) { + func_80939794(this, globalCtx); + Actor_MarkForDeath(&this->actor); + } else { + func_80939994(globalCtx, &this->actor.world.pos); + this->actor.flags |= ACTOR_FLAG_10; + func_8093A080(this); + } + } else { + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actor.xzDistToPlayer < 1400.0f) { + if (this->unk_202 > 0) { + this->unk_202--; + if (this->unk_202 == 0) { + this->collider.base.colType = COLTYPE_HARD; + } else { + this->collider.base.colType = COLTYPE_NONE; + } + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void func_8093A080(ObjBombiwa* this) { + ObjBombiwaStruct* ptr; + s16 phi_s2; + s32 i; + + for (i = 0, phi_s2 = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s2 += 0x4000) { + ptr = &this->unk_190[i]; + + ptr->unk_00 = (Rand_ZeroOne() * 0.1f) + 0.05f; + + ptr->unk_04.x = (Math_SinS(phi_s2) * 50.0f) + this->actor.world.pos.x; + ptr->unk_04.y = ((i + 1) * 31.0f) + this->actor.world.pos.y; + ptr->unk_04.z = (Math_CosS(phi_s2) * 50.0f) + this->actor.world.pos.z; + + ptr->unk_10 = i + 3.0f; + ptr->unk_14.x = phi_s2; + ptr->unk_14.y = (u32)Rand_Next() >> 0x10; + ptr->unk_14.z = 0; + ptr->unk_1A = 0; + } + + this->unk_200 = 0; + this->unk_201 = 80; + this->actionFunc = func_8093A1F0; +} + +void func_8093A1F0(ObjBombiwa* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + Vec3f sp9C; + ObjBombiwaStruct* ptr; + CollisionPoly* sp94; + s32 sp90; + f32 temp_f0; + s16 phi_s1; + + for (i = 0, phi_s1 = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s1 += 0x4000) { + ptr = &this->unk_190[i]; + + if (ptr->unk_1A != 0) { + continue; + } + + ptr->unk_10 -= 3.0f; + + ptr->unk_04.x += Math_SinS(phi_s1) * 1.5f; + ptr->unk_04.y += ptr->unk_10; + ptr->unk_04.z += Math_CosS(phi_s1) * 1.5f; + + ptr->unk_14.x += 0x5DC; + + sp9C.x = ptr->unk_04.x; + sp9C.y = ptr->unk_04.y + 30.0f; + sp9C.z = ptr->unk_04.z; + + temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp94, &sp90, &this->actor, &sp9C); + if ((temp_f0 <= (BGCHECK_Y_MIN + 10.0f)) || ((ptr->unk_04.y - (200.0f * ptr->unk_00)) < temp_f0)) { + this->unk_200++; + ptr->unk_1A = 1; + func_80939C50(globalCtx, &ptr->unk_04); + } + } + + this->unk_201--; + if ((this->unk_200 >= 4) || (this->unk_201 <= 0)) { + Actor_MarkForDeath(&this->actor); + } +} + +void ObjBombiwa_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjBombiwa* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void func_8093A418(Actor* thisx, GlobalContext* globalCtx) { + ObjBombiwa* this = THIS; + f32 sp28; + + if ((this->actor.projectedPos.z <= 2200.0f) || ((this->unk_203 & 1) && (this->actor.projectedPos.z < 2300.0f))) { + this->actor.shape.shadowAlpha = 160; + Gfx_DrawDListOpa(globalCtx, object_bombiwa_DL_0009E0); + return; + } + + if (this->actor.projectedPos.z < 2300.0f) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + sp28 = (2300.0f - this->actor.projectedPos.z) * 2.55f; + + this->actor.shape.shadowAlpha = sp28 * (32.0f / 51); + 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, (s32)sp28); + gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_000AF0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + this->actor.shape.shadowAlpha = 0; + } +} + +void func_8093A608(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[8]; + ObjBombiwa* this = THIS; + f32 sp38; + s32 i; + ObjBombiwaStruct* ptr; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->actionFunc == func_80939EF4) { + if ((this->actor.projectedPos.z <= 2200.0f) || + ((this->unk_203 & 1) && (this->actor.projectedPos.z < 2300.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, 0x9B, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, object_bombiwa_DL_004560); + + 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_004688); + } else if (this->actor.projectedPos.z < 2300.0f) { + sp38 = (2300.0f - this->actor.projectedPos.z) * 2.55f; + 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, 0x9B, 255, 255, 255, (s32)sp38); + gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_004560); + } + } else { + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) { + ptr = &this->unk_190[i]; + + if (ptr->unk_1A == 0) { + Matrix_SetTranslateRotateYXZ(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, &ptr->unk_14); + Matrix_Scale(ptr->unk_00, ptr->unk_00, ptr->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++, object_bombiwa_DL_005990); + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h index 36fafc7e6..54d4024e9 100644 --- a/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h +++ b/src/overlays/actors/ovl_Obj_Bombiwa/z_obj_bombiwa.h @@ -7,9 +7,28 @@ struct ObjBombiwa; typedef void (*ObjBombiwaActionFunc)(struct ObjBombiwa*, GlobalContext*); +#define OBJBOMBIWA_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJBOMBIWA_GET_100(thisx) (((thisx)->params >> 8) & 1) +#define OBJBOMBIWA_GET_8000(thisx) (((thisx)->params >> 0xF) & 1) + +#define OBJBOMBIWA_100_0 0 + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ f32 unk_10; + /* 0x14 */ Vec3s unk_14; + /* 0x1A */ s16 unk_1A; +} ObjBombiwaStruct; // size = 0x1C + typedef struct ObjBombiwa { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC0]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ ObjBombiwaStruct unk_190[4]; + /* 0x0200 */ s8 unk_200; + /* 0x0201 */ s8 unk_201; + /* 0x0202 */ s8 unk_202; + /* 0x0203 */ u8 unk_203; /* 0x0204 */ ObjBombiwaActionFunc actionFunc; } ObjBombiwa; // size = 0x208 diff --git a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c index 0d5a2c1b9..b8da1a9f6 100644 --- a/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c +++ b/src/overlays/actors/ovl_Obj_Boyo/z_obj_boyo.c @@ -7,8 +7,9 @@ #include "z_obj_boyo.h" #include "overlays/actors/ovl_En_Kaizoku/z_en_kaizoku.h" #include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_boyo/object_boyo.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjBoyo*)thisx) @@ -56,9 +57,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_06000300[]; -extern AnimatedMaterial D_06000E88; - void ObjBoyo_Init(Actor* thisx, GlobalContext* globalCtx) { ObjBoyo* this = THIS; @@ -67,7 +65,7 @@ void ObjBoyo_Init(Actor* thisx, GlobalContext* globalCtx) { Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); Collider_UpdateCylinder(&this->actor, &this->collider); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - this->unk_190 = Lib_SegmentedToVirtual(&D_06000E88); + this->unk_190 = Lib_SegmentedToVirtual(object_boyo_Matanimheader_000E88); } void ObjBoyo_Destroy(Actor* thisx, GlobalContext* globalCtx2) { @@ -121,8 +119,8 @@ Actor* ObjBoyo_GetCollidedActor(ObjBoyo* this, GlobalContext* globalCtx, s32* nu } void ObjBoyo_Update(Actor* thisx, GlobalContext* globalCtx2) { - ObjBoyo* this = THIS; GlobalContext* globalCtx = globalCtx2; + ObjBoyo* this = THIS; Actor* target; s32 num; @@ -182,5 +180,5 @@ void ObjBoyo_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjBoyo* this = THIS; AnimatedMat_Draw(globalCtx, this->unk_190); - func_800BDFC0(globalCtx, D_06000300); + Gfx_DrawDListOpa(globalCtx, object_boyo_DL_000300); } diff --git a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.c b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.c index 45260a7b7..c90e5d8f8 100644 --- a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.c +++ b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.c @@ -1,23 +1,38 @@ -#include "z_obj_chan.h" +/* + * File: z_obj_chan.c + * Overlay: ovl_Obj_Chan + * Description: Goron Shrine chandelier + * + * This actor class is used for both the chandelier and its sub-components. + * The distinction is made using the subtype actor parameter: + * - 0 for the chandelier itself + * - 1 for one of the 5 breakable pots that are attached to the chandelier + */ -#define FLAGS 0x00000030 +#include "z_obj_chan.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_obj_chan/object_obj_chan.h" +#include "objects/object_tsubo/object_tsubo.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjChan*)thisx) +#define OBJCHAN_ROTATION_SPEED 364 // == (65536 * 2/360) i.e. 2 degrees per second + void ObjChan_Init(Actor* thisx, GlobalContext* globalCtx); void ObjChan_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjChan_Update(Actor* thisx, GlobalContext* globalCtx); void ObjChan_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80BB9F24(ObjChan* this, GlobalContext* globalCtx); -void func_80BBA314(ObjChan* this, GlobalContext* globalCtx); +void ObjChan_ChandelierAction(ObjChan* this, GlobalContext* globalCtx); +void ObjChan_PotAction(ObjChan* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Chan_InitVars = { ACTOR_OBJ_CHAN, ACTORCAT_BG, FLAGS, - OBJECT_OBJECT_UNSET_CHAN, + OBJECT_OBJ_CHAN, sizeof(ObjChan), (ActorFunc)ObjChan_Init, (ActorFunc)ObjChan_Destroy, @@ -25,49 +40,397 @@ const ActorInit Obj_Chan_InitVars = { (ActorFunc)ObjChan_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BBAB30 = { - { COLTYPE_HARD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sObjChanCylinderInit = { + { + COLTYPE_HARD, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 48, 76, -60, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BBAB5C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void ObjChan_InitChandelier(ObjChan* this2, GlobalContext* globalCtx); +void ObjChan_InitPot(ObjChan* this, GlobalContext* globalCtx); +void ObjChan_CreateSmashParticles(ObjChan* this, GlobalContext* globalCtx); +void ObjChan_DrawPot(Actor* thisx, GlobalContext* globalCtx); +void ObjChan_DrawFire(ObjChan* this, GlobalContext* globalCtx); -extern ColliderCylinderInit D_80BBAB30; -extern InitChainEntry D_80BBAB5C[]; +static Vec3f sObjChanFlameSize[2] = { + { 0.16f, 0.11f, 1.0f }, + { 0.13f, 0.09f, 1.0f }, +}; +static f32 sObjChanFlameYOffset[2] = { 1800, 1800 }; +static s32 sObjChanLoaded; -extern UNK_TYPE D_06000AF0; -extern UNK_TYPE D_06001960; -extern UNK_TYPE D_06002358; +void ObjChan_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjChan* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/ObjChan_Init.s") + if (OBJCHAN_SUBTYPE(&this->actor) == OBJCHAN_SUBTYPE_CHANDELIER) { + if (sObjChanLoaded) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actor.room = -1; + sObjChanLoaded = true; + } + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sObjChanCylinderInit); + SubS_FillCutscenesList(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); + switch (OBJCHAN_SUBTYPE(&this->actor)) { + case OBJCHAN_SUBTYPE_CHANDELIER: + this->rotation = this->actor.shape.rot.y; + this->actor.shape.rot.y = 0; + ObjChan_InitChandelier(this, globalCtx); + break; + case OBJCHAN_SUBTYPE_POT: + this->actor.draw = ObjChan_DrawPot; + ObjChan_InitPot(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/ObjChan_Destroy.s") +void ObjChan_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjChan* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BB9A1C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BB9B40.s") +u32 func_80BB9A1C(ObjChan* this, f32 arg1) { + f32 temp_f6; + f32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BB9C08.s") + sp20 = Math_SinS(this->unk1D4) * this->unk1D0; + temp_f6 = (Math_CosS(this->unk1D4) * 0.03834952f * this->unk1D0) + arg1; + if (temp_f6 != 0.0f) { + this->unk1D4 = RADF_TO_BINANG(func_80086B30(sp20 * 0.03834952f, temp_f6)); + } else if (sp20 >= 0.0f) { + this->unk1D4 = 0x4000; + } else { + this->unk1D4 = -0x4000; + } + if (Math_CosS(this->unk1D4) != 0.0f) { + this->unk1D0 = (temp_f6 / (Math_CosS(this->unk1D4) * 0.03834952f)); + } else { + this->unk1D0 = sp20; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BB9F24.s") +void ObjChan_CalculatePotPosition(Vec3f* childPosOut, Vec3s* childRotOut, Vec3f* parentPos, Vec3s* parentRot, + s16 childAngle) { + Vec3f offset; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BBA2FC.s") + Matrix_RotateYS(parentRot->y, MTXMODE_NEW); + Matrix_RotateXS(parentRot->x, MTXMODE_APPLY); + Matrix_RotateZS(parentRot->z, MTXMODE_APPLY); + Matrix_RotateYS(childAngle, MTXMODE_APPLY); + Matrix_MultVecX(-280.0f, &offset); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BBA314.s") + childPosOut->x = parentPos->x + offset.x; + childPosOut->y = parentPos->y + offset.y; + childPosOut->z = parentPos->z + offset.z; + Math_Vec3s_Copy(childRotOut, parentRot); + childRotOut->y += childAngle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BBA488.s") +//! @TODO: Possibly takes actor and recasts +void ObjChan_InitChandelier(ObjChan* this2, GlobalContext* globalCtx) { + ObjChan* this = this2; + s32 i; + ObjChan* temp_v0; + Vec3f childPos; + Vec3s childRot; + CollisionPoly* sp94; + s32 sp90; + Vec3f sp84; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/ObjChan_Update.s") + Math_Vec3f_Copy(&this->unk1C0, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/ObjChan_Draw.s") + Math_Vec3f_Copy(&sp84, &this->actor.world.pos); + sp84.y += 1600.0f; + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp84, &this->unk1C0, &sp94, false, false, + true, true, &sp90)) { + this->unk1CC = this->actor.world.pos.y - this->unk1C0.y; + } else { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BBA894.s") + for (i = 0; i < 5; i++) { + ObjChan_CalculatePotPosition(&childPos, &childRot, &this->actor.world.pos, &this->actor.shape.rot, + (s32)(i * 360.0f / 5.0f * (65536.0f / 360.0f)) + this->rotation); + temp_v0 = (ObjChan*)Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_OBJ_CHAN, childPos.x, childPos.y, childPos.z, childRot.x, childRot.y, + childRot.z, (this->actor.params & 0xFFF) | 0x1000, this->actor.cutscene, this->actor.unk20, &this->actor); + if (temp_v0 != NULL) { + this->pots[i] = temp_v0; + temp_v0->myPotIndex = i; + temp_v0->actor.cutscene = this->actor.cutscene; + } else { + Actor_MarkForDeath(&this->actor); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Chan/func_80BBA930.s") + if (Flags_GetSwitch(globalCtx, this->actor.params & 0x7F)) { + this->stateFlags |= OBJCHAN_STATE_FIRE_DELAY; + this->stateFlags |= OBJCHAN_STATE_ON_FIRE; + + this->rotationSpeed = OBJCHAN_ROTATION_SPEED; + this->flameSize = 1.0f; + + for (i = 0; i < 5; i++) { + if (this->pots[i] != NULL) { + this->pots[i]->stateFlags |= OBJCHAN_STATE_FIRE_DELAY; + this->pots[i]->stateFlags |= OBJCHAN_STATE_ON_FIRE; + this->pots[i]->flameSize = 1.0f; + } + } + } + this->collider.dim.radius = 45; + this->collider.dim.height = 60; + this->collider.dim.yShift = -20; + this->actionFunc = ObjChan_ChandelierAction; +} + +//! @TODO: More descriptive name than Action? +void ObjChan_ChandelierAction(ObjChan* this2, GlobalContext* globalCtx) { + ObjChan* this = this2; + ObjChan* temp; + s32 i; + Vec3f sp60; + Vec3s sp58; + + if (this->unk1D0 > 0.0f) { + this->unk1D4 += 0x190; + if (this->unk1D0 <= 400.0f) { + this->unk1D0 = this->unk1D0 * 0.99f; + } else { + this->unk1D0 = this->unk1D0 - 1.0f; + } + if (this->unk1D0 < 0.0f) { + this->unk1D4 = 0; + this->unk1D0 = 0.0f; + } + } + this->actor.shape.rot.z = (Math_SinS(this->unk1D4) * this->unk1D0); + if ((this->stateFlags & OBJCHAN_STATE_START_CUTSCENE) && + SubS_StartActorCutscene(&this->actor, this->cutscenes[0], -1, 0)) { + this->stateFlags |= OBJCHAN_STATE_CUTSCENE; + this->stateFlags &= ~OBJCHAN_STATE_START_CUTSCENE; + } + if ((this->stateFlags & OBJCHAN_STATE_CUTSCENE) && this->rotationSpeed == OBJCHAN_ROTATION_SPEED) { + this->stateFlags &= ~OBJCHAN_STATE_CUTSCENE; + ActorCutscene_Stop(this->cutscenes[0]); + } + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateYS(this->rotation, MTXMODE_APPLY); + Matrix_MultVecY(this->unk1CC, &this->actor.world.pos); + Math_Vec3f_Sum(&this->actor.world.pos, &this->unk1C0, &this->actor.world.pos); + Collider_UpdateCylinder(&this->actor, &this->collider); + for (i = 0; i < 5; i++) { + temp = this->pots[i]; + if (temp != NULL) { + ObjChan_CalculatePotPosition(&sp60, &sp58, &this->actor.world.pos, &this->actor.shape.rot, + (s32)(i * 360.0f / 5.0f * (65536.0f / 360.0f)) + this->rotation); + Math_Vec3f_Copy(&temp->actor.world.pos, &sp60); + Math_Vec3s_Copy(&temp->actor.shape.rot, &this->actor.shape.rot); + temp->actor.shape.rot.y = this->rotation; + Math_Vec3f_ToVec3s(&temp->collider.dim.pos, &temp->actor.world.pos); + } + } + if ((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x800)) { + Flags_SetSwitch(globalCtx, this->actor.params & 0x7F); + } + if (Flags_GetSwitch(globalCtx, this->actor.params & 0x7F)) { + if (!(this->stateFlags & OBJCHAN_STATE_FIRE_DELAY)) { + this->rotationSpeed = 0; + this->flameSize = 0.0f; + for (i = 0; i < 5; i++) { + temp = this->pots[i]; + if (temp != NULL) { + this->pots[i]->stateFlags |= OBJCHAN_STATE_FIRE_DELAY; + this->pots[i]->fireDelayFrames = 20 + i * 5; + this->pots[i]->flameSize = 0.0f; + } + } + this->stateFlags |= OBJCHAN_STATE_FIRE_DELAY; + this->stateFlags |= OBJCHAN_STATE_ON_FIRE; + this->stateFlags |= OBJCHAN_STATE_START_CUTSCENE; + } else { + Math_StepToF(&this->flameSize, 1.0f, 0.05f); + this->rotation += this->rotationSpeed; + Math_StepToS(&this->rotationSpeed, OBJCHAN_ROTATION_SPEED, 5); + func_800B9010(&this->actor, NA_SE_EV_CHANDELIER_ROLL - SFX_FLAG); + } + } +} + +void ObjChan_InitPot(ObjChan* this, GlobalContext* globalCtx) { + this->actionFunc = ObjChan_PotAction; +} + +void ObjChan_PotAction(ObjChan* this, GlobalContext* globalCtx) { + s32 potBreaks; + s32 phi_v1; + + potBreaks = false; + if ((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x4004000)) { + potBreaks = true; + } + if (this->stateFlags & OBJCHAN_STATE_ON_FIRE) { + Math_StepToF(&this->flameSize, 1.0f, 0.05f); + } else if (this->stateFlags & OBJCHAN_STATE_FIRE_DELAY) { + this->fireDelayFrames--; + if (this->fireDelayFrames <= 0) { + this->stateFlags |= OBJCHAN_STATE_ON_FIRE; + } + } + if (potBreaks) { + ObjChan_CreateSmashParticles(this, globalCtx); + ((ObjChan*)this->actor.parent)->pots[this->myPotIndex] = NULL; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_CHANDELIER_BROKEN); + func_80BB9A1C((ObjChan*)this->actor.parent, 40.0f); + if (this->myPotIndex == 4) { + if (!(((void)0, gSaveContext.save.weekEventReg[0x25]) & 0x10)) { + gSaveContext.save.weekEventReg[0x25] = ((void)0, gSaveContext.save.weekEventReg[0x25]) | 0x10; + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_MM, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0x8000, + this->actor.cutscene, this->actor.unk20, NULL); + } + } + Actor_MarkForDeath(&this->actor); + } +} + +void ObjChan_CreateSmashParticles(ObjChan* this, GlobalContext* globalCtx) { + s16 new_var = 0; + s32 phi_s0; + Vec3f spDC; + Vec3f spD0; + f32 temp_f0; + f32 new_var2; + s16 temp_s1 = 0; + s32 temp_s2; + f32 spAC; + f32 spA8 = new_var + 15.0f; + f32 spA4 = new_var + (spAC = 110.0f); + + for (temp_s2 = 0, temp_s1 = 0; temp_s2 != 18; temp_s2++, temp_s1 += 0x4E20) { + f32 sin = Math_SinS(temp_s1); + f32 cos = Math_CosS(temp_s1); + spDC.x = sin * 8.0f; + spDC.y = Rand_ZeroOne() * 12.0f + 2.0f; + spDC.z = cos * 8.0f; + spD0.x = spDC.x * 0.23f; + spD0.y = Rand_ZeroOne() * 5.0f + 2.5f; + spD0.z = spDC.z * 0.23f; + temp_f0 = Rand_ZeroOne(); + if (temp_f0 < 0.2f) { + phi_s0 = 0x60; + } else if (temp_f0 < 0.6f) { + phi_s0 = 0x40; + } else { + phi_s0 = 0x20; + } + new_var2 = spA4 * Rand_ZeroOne(); + EffectSsKakera_Spawn(globalCtx, &spDC, &spD0, &this->actor.world.pos, -260, phi_s0, 20, 0, 0, spA8 + new_var2, + 0, 0, 50, -1, OBJECT_TSUBO, object_tsubo_DL_001960); + } + func_800BBFB0(globalCtx, &this->actor.world.pos, 30.0f, 2, 20, 50, true); + func_800BBFB0(globalCtx, &this->actor.world.pos, 30.0f, 2, 10, 80, true); +} + +void ObjChan_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjChan* this = THIS; + + this->actionFunc(this, globalCtx); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjChan_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjChan* this = THIS; + Gfx* opa; + Gfx* xlu; + + OPEN_DISPS(globalCtx->state.gfxCtx); + Matrix_RotateYS(this->rotation, MTXMODE_APPLY); + + opa = Gfx_CallSetupDL(POLY_OPA_DISP, 0x19); + gSPMatrix(&opa[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(&opa[1], object_obj_chan_DL_000AF0); + POLY_OPA_DISP = &opa[2]; + + xlu = func_8012C2B4(POLY_XLU_DISP); + gSPMatrix(&xlu[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(&xlu[1], object_obj_chan_DL_000A10); + POLY_XLU_DISP = &xlu[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Matrix_Push(); + if (this->stateFlags & OBJCHAN_STATE_ON_FIRE) { + ObjChan_DrawFire(this, globalCtx); + } + Matrix_Pop(); +} + +void ObjChan_DrawPot(Actor* thisx, GlobalContext* globalCtx) { + ObjChan* this = THIS; + s32 pad; + Gfx* dl; + + OPEN_DISPS(globalCtx->state.gfxCtx); + dl = Gfx_CallSetupDL(POLY_OPA_DISP, 0x19); + gSPMatrix(&dl[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); + gSPDisplayList(&dl[1], object_obj_chan_DL_002358); + POLY_OPA_DISP = &dl[2]; + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (this->stateFlags & OBJCHAN_STATE_ON_FIRE) { + ObjChan_DrawFire(this, globalCtx); + } +} + +void ObjChan_DrawFire(ObjChan* this, GlobalContext* globalCtx) { + u32 sp4C; + Gfx* dl; + OPEN_DISPS(globalCtx->state.gfxCtx); + + sp4C = globalCtx->gameplayFrames; + + Matrix_RotateYS(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx)) - this->actor.shape.rot.y - this->rotation + 0x8000, + MTXMODE_APPLY); + Matrix_Scale(sObjChanFlameSize[OBJCHAN_SUBTYPE(&this->actor)].x * this->flameSize, + sObjChanFlameSize[OBJCHAN_SUBTYPE(&this->actor)].y * this->flameSize, 1.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, sObjChanFlameYOffset[OBJCHAN_SUBTYPE(&this->actor)], 0.0f, MTXMODE_APPLY); + + dl = func_8012C2B4(POLY_XLU_DISP); + gSPMatrix(&dl[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_LOAD); + gMoveWd(&dl[1], 6, 32, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 32, 64, 1, 0U, -sp4C * 20, 32, 128)); + gDPSetPrimColor(&dl[2], 128, 128, 255, 255, 0, 255); + gDPSetEnvColor(&dl[3], 255, 0, 0, 0); + gSPDisplayList(&dl[4], &gGameplayKeepDrawFlameDL); + POLY_XLU_DISP = &dl[5]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..2b11335b3 100644 --- a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h +++ b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h @@ -5,12 +5,56 @@ struct ObjChan; +#define OBJCHAN_SUBTYPE(thisx) (((thisx)->params >> 12) & 0xF) +#define OBJCHAN_SUBTYPE_CHANDELIER 0 +#define OBJCHAN_SUBTYPE_POT 1 + +/*** stateFlags ***/ +/* + * After the chandelier is hit by a fire attack, each pot gets OBJCHAN_STATE_FIRE_DELAY state and counts down a number of frames until it catches fire. + * The delay is different for each pot. Remaining frame count is stored in fireDelayFrames. + * The main actor also gets this flag but it's always equivalent to OBJCHAN_STATE_ON_FIRE. + */ +#define OBJCHAN_STATE_FIRE_DELAY (1 << 0) +/** + * Pot is now on fire. After this state is set the flame grows to full size over 20 frames. Flame size is stored in flameSize. + * OBJCHAN_STATE_FIRE_DELAY is not cleared when this flag is set. + * The main actor also gets this flag. + */ +#define OBJCHAN_STATE_ON_FIRE (1 << 1) // Pot has fire. Flame grows to full size over about 1 second. Flame size is stored in fireSize. +/** + * Only for the main actor. + * Once set, the actor tries to start a cutscene. + * Once cutscene is started, this flag is unset and OBJCHAN_STATE_MAIN_STOP_CUTSCENE_AT_FULL_SPEED is set. + */ +#define OBJCHAN_STATE_START_CUTSCENE (1 << 2) +/** + * Only for the main actor. + * Cutscene is running. Once set, the actor waits for full rotation speed and then cancels the cutscene. + */ +#define OBJCHAN_STATE_CUTSCENE (1 << 3) + + + typedef void (*ObjChanActionFunc)(struct ObjChan*, GlobalContext*); typedef struct ObjChan { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjChanActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ ColliderCylinder collider; + /* 0x0194 */ u8 myPotIndex; // For OBJCHAN_SUBTYPE_POT: which pot is this? + /* 0x0196 */ s16 fireDelayFrames; + /* 0x0198 */ UNK_TYPE1 unk198[0x12]; + /* 0x01AA */ u8 stateFlags; + /* 0x01AC */ struct ObjChan* pots[5]; // For OBJCHAN_SUBTYPE_BODY: pointers to pot actors + /* 0x01C0 */ Vec3f unk1C0; + /* 0x01CC */ f32 unk1CC; + /* 0x01D0 */ f32 unk1D0; + /* 0x01D4 */ s16 unk1D4; + /* 0x01D8 */ f32 flameSize; + /* 0x01DC */ s16 rotationSpeed; // Main object only. Slowly ramps up under some circumstances. In other circumstances it's immediately set to maximum speed. + /* 0x01DE */ s16 rotation; // Increases as the chandelier spins. Don't know why they didn't use the actor's rotation variable. + /* 0x01E0 */ s16 cutscenes[2]; } 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 0208d59b7..7de79a2be 100644 --- a/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c +++ b/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_chikuwa.c + * Overlay: ovl_Obj_Chikuwa + * Description: Falling row of blocks (unused) + */ + #include "z_obj_chikuwa.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjChikuwa*)thisx) 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 386915dee..737f9ef46 100644 --- a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c +++ b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_comb.c + * Overlay: ovl_Obj_Comb + * Description: Beehive + */ + #include "z_obj_comb.h" +#include "objects/object_comb/object_comb.h" #define FLAGS 0x00000000 @@ -9,11 +16,12 @@ void ObjComb_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjComb_Update(Actor* thisx, GlobalContext* globalCtx); void ObjComb_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_8098DC44(ObjComb* this); void func_8098DC60(ObjComb* this, GlobalContext* globalCtx); void func_8098DEA0(ObjComb* this, GlobalContext* globalCtx); +void func_8098E098(ObjComb* this); void func_8098E0B8(ObjComb* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Comb_InitVars = { ACTOR_OBJ_COMB, ACTORCAT_PROP, @@ -26,71 +34,538 @@ const ActorInit Obj_Comb_InitVars = { (ActorFunc)ObjComb_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8098E440[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x05CBFFBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x05CBFFBE, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8098E464 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 1, D_8098E440, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8098E474[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), }; -#endif +s32 func_8098CE40(ObjComb* this, GlobalContext* globalCtx) { + s32 phi_a2 = -1; + s32 temp_v0 = (OBJCOMB_GET_1F(&this->actor) << 2) | 0xFF01; -extern ColliderJntSphElementInit D_8098E440[1]; -extern ColliderJntSphInit D_8098E464; -extern InitChainEntry D_8098E474[]; + if ((u8)temp_v0 & 3) { + phi_a2 = ((temp_v0 & 0x3FC) >> 2) & 0xFF; + } -extern UNK_TYPE D_06000CB0; -extern UNK_TYPE D_06001040; + return ((phi_a2 < 0) == 1) || !Flags_GetTreasure(globalCtx, phi_a2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098CE40.s") +void func_8098CEAC(ObjComb* this, GlobalContext* globalCtx) { + Vec3f spDC; + Vec3f spD0; + Vec3f spC4; + s32 i; + f32 temp_f20; + s16 temp_s2 = 0; + s16 temp_f10; + s32 phi_s0; + s32 phi_v0; + s32 phi_s1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098CEAC.s") + for (i = 0; i < 31; i++) { + temp_s2 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D19C.s") + spDC.x = Math_SinS(temp_s2) * temp_f20; + spDC.y = (i - 15) * 0.7f; + spDC.z = Math_CosS(temp_s2) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D47C.s") + Math_Vec3f_Sum(&spDC, &this->actor.world.pos, &spD0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D6E0.s") + spC4.x = (Rand_ZeroOne() - 0.5f) + (spDC.x * 0.5f); + spC4.y = (Rand_ZeroOne() - 0.5f) + (spDC.y * 0.6f); + spC4.z = (Rand_ZeroOne() - 0.5f) + (spDC.z * 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D870.s") + temp_f10 = (Rand_ZeroOne() * 72.0f) + 25.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D8C8.s") + if (temp_f10 < 40) { + phi_s0 = -200; + phi_s1 = 40; + } else if (temp_f10 < 70) { + phi_s0 = -280; + phi_s1 = 30; + } else { + phi_s0 = -340; + phi_s1 = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098D99C.s") + temp_f20 = Rand_ZeroOne(); + if (temp_f20 < 0.1f) { + phi_v0 = 0x60; + } else if (temp_f20 < 0.8f) { + phi_v0 = 0x40; + } else { + phi_v0 = 0x20; + } + EffectSsKakera_Spawn(globalCtx, &spD0, &spC4, &spD0, phi_s0, phi_v0, phi_s1, 4, 0, temp_f10, 0, 0, 60, -1, + OBJECT_COMB, object_comb_DL_001040); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098DA74.s") + spD0.x = this->actor.world.pos.x; + spD0.y = this->actor.world.pos.y - 10.0f; + spD0.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/ObjComb_Init.s") + func_800BBFB0(globalCtx, &spD0, 40.0f, 6, 70, 60, 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/ObjComb_Destroy.s") +void func_8098D19C(ObjComb* this, GlobalContext* globalCtx) { + Vec3f spDC; + Vec3f spD0; + Vec3f spC4; + f32 temp_f20; + s16 temp_s2 = 0; + s16 temp_f8; + s32 phi_s0; + s32 phi_v0; + s32 phi_s1; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098DC44.s") + for (i = 0; i < 31; i++) { + temp_s2 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098DC60.s") + spDC.x = Math_SinS(temp_s2) * temp_f20; + spDC.y = i * 0.7f; + spDC.z = Math_CosS(temp_s2) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098DE58.s") + Math_Vec3f_Sum(&spDC, &this->actor.world.pos, &spD0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098DEA0.s") + spC4.x = (Rand_ZeroOne() - 0.5f) + (spDC.x * 0.5f); + spC4.y = (Rand_ZeroOne() * 0.5f) + (spDC.y * 0.5f); + spC4.z = (Rand_ZeroOne() - 0.5f) + (spDC.z * 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098E098.s") + temp_f8 = (Rand_ZeroOne() * 72.0f) + 25.0f; + if (temp_f8 < 40) { + phi_s0 = -200; + phi_s1 = 40; + } else if (temp_f8 < 70) { + phi_s0 = -280; + phi_s1 = 30; + } else { + phi_s0 = -340; + phi_s1 = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/func_8098E0B8.s") + temp_f20 = Rand_ZeroOne(); + if (temp_f20 < 0.1f) { + phi_v0 = 0x60; + } else if (temp_f20 < 0.8f) { + phi_v0 = 0x40; + } else { + phi_v0 = 0x20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/ObjComb_Update.s") + EffectSsKakera_Spawn(globalCtx, &spD0, &spC4, &spD0, phi_s0, phi_v0, phi_s1, 4, 0, temp_f8, 0, 0, 60, -1, + OBJECT_COMB, object_comb_DL_001040); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Comb/ObjComb_Draw.s") + spD0.x = this->actor.world.pos.x; + spD0.y = this->actor.world.pos.y + 20.0f; + spD0.z = this->actor.world.pos.z; + + func_800BBFB0(globalCtx, &spD0, 40.0f, 6, 70, 60, 1); +} + +void func_8098D47C(ObjComb* this, GlobalContext* globalCtx) { + Vec3f spD4; + Vec3f spC8; + Vec3f spBC; + f32 temp_f20; + s16 temp_s1 = 0; + s16 temp_f10; + s32 phi_s0; + s32 phi_v0; + s32 i; + + for (i = 0; i < 21; i++) { + temp_s1 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 10.0f; + + spD4.x = Math_SinS(temp_s1) * temp_f20; + spD4.y = i * 0.25f; + spD4.z = Math_CosS(temp_s1) * temp_f20; + + Math_Vec3f_Sum(&spD4, &this->actor.world.pos, &spC8); + + spBC.x = (Rand_ZeroOne() - 0.5f) + (spD4.x * 0.5f); + spBC.y = Rand_ZeroOne() + (spD4.y * 0.6f) + 6.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) + (spD4.z * 0.5f); + + temp_f10 = (Rand_ZeroOne() * 72.0f) + 25.0f; + if (temp_f10 < 40) { + phi_s0 = -100; + } else if (temp_f10 < 70) { + phi_s0 = -180; + } else { + phi_s0 = -240; + } + + if (Rand_ZeroOne() < 0.2f) { + phi_v0 = 0x40; + } else { + phi_v0 = 0x20; + } + + EffectSsKakera_Spawn(globalCtx, &spC8, &spBC, &spC8, phi_s0, phi_v0, 40, 0, 0, temp_f10, 0, 0, 80, -1, + OBJECT_COMB, object_comb_DL_001040); + } +} + +void func_8098D6E0(ObjComb* this, GlobalContext* globalCtx) { + s32 i; + Vec3f sp70; + f32 temp_f0; + f32 temp_f20; + s32 temp; + + sp70.y = this->actor.world.pos.y + this->actor.depthInWater; + + for (temp = 0, i = 0; i < 8; i++, temp += 0x2000) { + temp_f0 = Rand_ZeroOne(); + temp_f20 = ((1.0f - SQ(temp_f0)) * 14.0f) + 4.0f; + sp70.x = (Math_SinS((s32)(Rand_ZeroOne() * 8000.0f) + temp) * temp_f20) + this->actor.world.pos.x; + sp70.z = (Math_CosS((s32)(Rand_ZeroOne() * 8000.0f) + temp) * temp_f20) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp70, NULL, NULL, 0, 200); + } + + sp70.x = this->actor.world.pos.x; + sp70.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp70, NULL, NULL, 0, 300); +} + +void func_8098D870(ObjComb* this, GlobalContext* globalCtx) { + s32 temp_v0 = func_800A8150(OBJCOMB_GET_3F(&this->actor)); + + if (temp_v0 >= 0) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ((OBJCOMB_GET_7F00(&this->actor)) << 8) | temp_v0); + } +} + +void func_8098D8C8(ObjComb* this, GlobalContext* globalCtx) { + s32 params = OBJCOMB_GET_F(&this->actor); + s32 i; + s32 phi_s5; + + if (this->actionFunc == func_8098DC60) { + phi_s5 = 2; + } else { + phi_s5 = 1; + } + this->unk_1B6 = 0; + + for (i = 0; i < params; i++) { + if (Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BEE, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, phi_s5)) { + this->unk_1B6 = 1; + } + } +} + +void func_8098D99C(ObjComb* this, GlobalContext* globalCtx) { + s32 params; + Actor* temp_v0; + + if (func_8098CE40(this, globalCtx)) { + params = (OBJCOMB_GET_1F(&this->actor) << 2) | 0xFF01; + temp_v0 = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_SW, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.home.rot.y, 0, params); + + if (temp_v0 != NULL) { + temp_v0->parent = &this->actor; + if (this->actionFunc == func_8098DC60) { + temp_v0->velocity.y = 8.0f; + temp_v0->speedXZ = 2.0f; + } else { + temp_v0->velocity.y = 10.0f; + temp_v0->speedXZ = 2.0f; + } + this->unk_1B6 = 1; + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + } + } +} + +void func_8098DA74(ObjComb* this, GlobalContext* globalCtx) { + s32 temp_v0 = OBJCOMB_GET_8000(&this->actor) | OBJCOMB_GET_80(&this->actor); + + if (temp_v0 == 0) { + func_8098D870(this, globalCtx); + } else if (temp_v0 == 1) { + func_8098D8C8(this, globalCtx); + } else { + func_8098D99C(this, globalCtx); + } +} + +void ObjComb_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjComb* this = THIS; + s32 sp2C = OBJCOMB_GET_8000(&this->actor) | OBJCOMB_GET_80(&this->actor); + + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitJntSph(globalCtx, &this->collider); + + if ((sp2C == 1) && OBJCOMB_GET_10(&this->actor) && (gSaveContext.save.weekEventReg[83] & 2)) { + Actor_MarkForDeath(&this->actor); + return; + } + + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->colliderElement); + + if ((sp2C == 0) && func_800A81A4(globalCtx, OBJCOMB_GET_3F(&this->actor), OBJCOMB_GET_7F00(&this->actor))) { + this->unk_1B7 = 1; + this->actor.flags |= ACTOR_FLAG_10; + } + + if ((sp2C != 2) || !func_8098CE40(this, globalCtx)) { + this->unk_1B8 = -1; + } + func_8098DC44(this); +} + +void ObjComb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyJntSph(globalCtx, &THIS->collider); +} + +void func_8098DC44(ObjComb* this) { + this->unk_1AC = 0x2EE0; + this->actionFunc = func_8098DC60; +} + +void func_8098DC60(ObjComb* this, GlobalContext* globalCtx) { + s32 temp_a0; + s8 temp_v0; + u32 temp_v1; + + this->unk_1AA += this->unk_1AC; + if (this->unk_1B3) { + this->collider.base.acFlags &= ~AC_HIT; + } + + this->unk_1A8 -= 0x32; + if (this->unk_1A8 < 0) { + this->unk_1A8 = 0; + } + + if (this->unk_1B3) { + if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x0182C29C) { + func_8098CEAC(this, globalCtx); + func_8098DA74(this, globalCtx); + Actor_MarkForDeath(&this->actor); + } else { + s32 dmgFlags = this->collider.elements->info.acHitInfo->toucher.dmgFlags; + + if (dmgFlags & 0x13820) { + this->unk_1A8 = 0xDAC; + this->unk_1AC = 0x36B0; + } else { + this->unk_1A8 = 0x5DC; + this->unk_1AC = 0x2EE0; + } + + if ((this->unk_1B2 <= 0) && (dmgFlags & 0x13820)) { + if (this->unk_1B5 == 0) { + this->unk_1B5 = 1; + this->actor.flags |= ACTOR_FLAG_10; + } + this->unk_1B2 = 20; + } + } + } else { + if (this->unk_1B8 >= 0) { + if (this->unk_1B8 == 0) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EN_STALGOLD_ROLL); + if (Rand_ZeroOne() < 0.1f) { + this->unk_1B8 = Rand_S16Offset(40, 80); + } else { + this->unk_1B8 = 8; + } + } else { + this->unk_1B8--; + } + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actor.update != NULL) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + this->actor.shape.rot.x = (s32)(Math_SinS(this->unk_1AA) * this->unk_1A8) + this->actor.home.rot.x; +} + +void func_8098DE58(ObjComb* this) { + this->actor.flags |= ACTOR_FLAG_10; + this->unk_1B4 = 100; + this->actor.terminalVelocity = -20.0f; + this->actor.gravity = -1.5f; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_8098DEA0; +} + +void func_8098DEA0(ObjComb* this, GlobalContext* globalCtx) { + this->unk_1B4--; + if ((this->actor.bgCheckFlags & 1) || (this->unk_1B4 <= 0)) { + func_8098DA74(this, globalCtx); + if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 30.0f)) { + func_8098D47C(this, globalCtx); + } else { + func_8098D19C(this, globalCtx); + } + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_HONEYCOMB_BROKEN); + func_8098E098(this); + } else { + if (this->actor.bgCheckFlags & 0x40) { + func_8098D6E0(this, globalCtx); + } + + if (this->actor.bgCheckFlags & 0x20) { + this->actor.gravity = -0.5f; + this->actor.velocity.y *= 0.8f; + this->unk_1AE >>= 1; + this->unk_1B0 >>= 1; + } else { + this->actor.gravity = -1.5f; + this->actor.velocity.y *= 0.96f; + + this->unk_1AE += 0x1F4; + if (this->unk_1AE > 0x7D0) { + this->unk_1AE = 0x7D0; + } + + this->unk_1B0 += 0xC8; + if (this->unk_1B0 > 0x258) { + this->unk_1B0 = 0x258; + } + func_800B9010(&this->actor, NA_SE_EV_HONEYCOMB_FALL - SFX_FLAG); + } + + Actor_MoveWithGravity(&this->actor); + this->actor.shape.rot.x += this->unk_1AE; + this->actor.shape.rot.y += this->unk_1B0; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 12.0f, 0.0f, 5); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_8098E098(ObjComb* this) { + this->actor.draw = NULL; + this->unk_1B4 = 20; + this->actionFunc = func_8098E0B8; +} + +void func_8098E0B8(ObjComb* this, GlobalContext* globalCtx) { + this->unk_1B4--; + if (this->unk_1B4 <= 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((this->unk_1B4 == 10) && (this->unk_1B6 != 0) && (this->unk_1B5 == 2) && (this->actor.cutscene >= 0)) { + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + func_800B7298(globalCtx, &this->actor, 4); + } + } +} + +void ObjComb_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjComb* this = THIS; + + this->unk_1B3 = (this->collider.base.acFlags & AC_HIT) != 0; + if (this->unk_1B3) { + this->collider.base.acFlags &= ~AC_HIT; + } + + if (this->unk_1B2 > 0) { + this->unk_1B2--; + if (this->unk_1B2 == 0) { + func_8098DE58(this); + } + } + + this->actionFunc(this, globalCtx); + + if (this->actor.update == NULL) { + if ((this->unk_1B5 == 2) && (func_800F2138(this->actor.cutscene) == -1)) { + ActorCutscene_Stop(this->actor.cutscene); + this->unk_1B5 = 0; + } + } else { + if (this->unk_1B5 != 0) { + Actor_SetFocus(&this->actor, 0.0f); + if (this->unk_1B5 == 1) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + if (this->actor.cutscene >= 0) { + func_800B7298(globalCtx, &this->actor, 1); + } + + if (((OBJCOMB_GET_8000(&this->actor) | OBJCOMB_GET_80(&this->actor)) == 1) && + OBJCOMB_GET_10(&this->actor)) { + gSaveContext.save.weekEventReg[83] |= 2; + } + + this->unk_1B5 = 2; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + } + } + + if (this->unk_1B7 != 0) { + globalCtx->actorCtx.unk5 |= 8; + this->actor.flags |= ACTOR_FLAG_10; + } + } +} + +void ObjComb_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjComb* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y + (118.0f * this->actor.scale.y), + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Translate(0.0f, -(this->actor.scale.y * 118.0f), 0.0f, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.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++, object_comb_DL_000CB0); + + Collider_UpdateSpheres(0, &this->collider); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..fc47df429 100644 --- a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -7,10 +7,31 @@ struct ObjComb; typedef void (*ObjCombActionFunc)(struct ObjComb*, GlobalContext*); +#define OBJCOMB_GET_F(thisx) ((thisx)->params & 0xF) +#define OBJCOMB_GET_10(thisx) (((thisx)->params >> 4) & 0x1) +#define OBJCOMB_GET_1F(thisx) ((thisx)->params & 0x1F) +#define OBJCOMB_GET_3F(thisx) ((thisx)->params & 0x3F) +#define OBJCOMB_GET_80(thisx) (((thisx)->params >> 7) & 0x1) +#define OBJCOMB_GET_7F00(thisx) (((thisx)->params >> 0x8) & 0x7F) +#define OBJCOMB_GET_8000(thisx) (((thisx)->params >> 0xE) & 2) + typedef struct ObjComb { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjCombActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x74]; + /* 0x0148 */ ColliderJntSph collider; + /* 0x0168 */ ColliderJntSphElement colliderElement; + /* 0x01A8 */ s16 unk_1A8; + /* 0x01AA */ s16 unk_1AA; + /* 0x01AC */ s16 unk_1AC; + /* 0x01AE */ s16 unk_1AE; + /* 0x01B0 */ s16 unk_1B0; + /* 0x01B2 */ s8 unk_1B2; + /* 0x01B3 */ s8 unk_1B3; + /* 0x01B4 */ s8 unk_1B4; + /* 0x01B5 */ s8 unk_1B5; + /* 0x01B6 */ s8 unk_1B6; + /* 0x01B7 */ s8 unk_1B7; + /* 0x01B8 */ s8 unk_1B8; } 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 15c7d2b7c..aa72f3052 100644 --- a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c +++ b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_danpeilift.c + * Overlay: ovl_Obj_Danpeilift + * Description: Deku Shrine & Snowhead Temple floating blocks + */ + #include "z_obj_danpeilift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjDanpeilift*)thisx) @@ -14,7 +20,7 @@ const ActorInit Obj_Danpeilift_InitVars = { ACTOR_OBJ_DANPEILIFT, ACTORCAT_BG, FLAGS, - OBJECT_OBJECT_UNSET_DANPEILIFT, + OBJECT_OBJ_DANPEILIFT, sizeof(ObjDanpeilift), (ActorFunc)ObjDanpeilift_Init, (ActorFunc)ObjDanpeilift_Destroy, diff --git a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c index 8c5b70ec3..2fba4b96a 100644 --- a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c +++ b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_demo.c + * Overlay: ovl_Obj_Demo + * Description: + */ + #include "z_obj_demo.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjDemo*)thisx) 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_Dhouse/z_obj_dhouse.c b/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.c index 42ef837c4..c6eef8626 100644 --- a/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.c +++ b/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.c @@ -1,6 +1,13 @@ -#include "z_obj_dhouse.h" +/* + * File: z_obj_dhouse.c + * Overlay: ovl_Obj_Dhouse + * Description: Stone bridge that Keeta sleeps under + */ -#define FLAGS 0x00400010 +#include "z_obj_dhouse.h" +#include "objects/object_dhouse/object_dhouse.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_400000) #define THIS ((ObjDhouse*)thisx) @@ -9,7 +16,17 @@ void ObjDhouse_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjDhouse_Update(Actor* thisx, GlobalContext* globalCtx); void ObjDhouse_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B12E7C(ObjDhouse* this, GlobalContext* globalCtx, ObjDhouseStruct1* ptr, ObjDhouseStruct3* ptr3); +void func_80B13170(ObjDhouse* this, GlobalContext* globalCtx, ObjDhouseStruct1* ptr, ObjDhouseStruct3* ptr3); +void func_80B13908(ObjDhouse* this); +void func_80B1391C(ObjDhouse* this, GlobalContext* globalCtx); +void func_80B1392C(ObjDhouse* this); +void func_80B13940(ObjDhouse* this, GlobalContext* globalCtx); +void func_80B139D8(ObjDhouse* this); +void func_80B139F4(ObjDhouse* this, GlobalContext* globalCtx); +void func_80B13C08(Actor* thisx, GlobalContext* globalCtx); +void func_80B13E40(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Dhouse_InitVars = { ACTOR_OBJ_DHOUSE, ACTORCAT_BG, @@ -22,58 +39,504 @@ const ActorInit Obj_Dhouse_InitVars = { (ActorFunc)ObjDhouse_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B13FB4[] = { +ObjDhouseStruct3 D_80B13E90[] = { + { + object_dhouse_DL_006E28, + object_dhouse_DL_006CE0, + { 84.2f, 30.480001f, 109.68001f }, + { 3.0f, 21.0f, 11.0f }, + 5500, + 500, + -500, + 7, + }, + { + object_dhouse_DL_0070A8, + object_dhouse_DL_006EF8, + { 40.8f, -38.72f, 62.12f }, + { -5.0f, 22.0f, 8.0f }, + 600, + -300, + 2000, + 4, + }, + { + object_dhouse_DL_007348, + object_dhouse_DL_007190, + { 125.31999f, -34.52f, 62.12f }, + { 8.0f, 13.0f, 6.0f }, + -2400, + 200, + -300, + 4, + }, + { + object_dhouse_DL_007568, + object_dhouse_DL_007438, + { 150.56f, -80.520004f, 62.12f }, + { -4.0f, 7.0f, 3.0f }, + 100, + 50, + 850, + 8, + }, + { + object_dhouse_DL_007780, + object_dhouse_DL_007638, + { 82.08f, 21.32f, -99.64f }, + { -7.0f, 34.0f, -1.0f }, + -2400, + -100, + 1000, + 5, + }, + { + object_dhouse_DL_007A00, + object_dhouse_DL_007850, + { 45.64f, -38.16f, -56.24f }, + { -1.0f, 20.0f, -16.0f }, + -2000, + 700, + 500, + 6, + }, + { + object_dhouse_DL_007C98, + object_dhouse_DL_007AE8, + { 140.4f, -60.84f, -56.24f }, + { 2.0f, 27.0f, -10.0f }, + -1000, + -500, + -500, + 9, + }, +}; + +Vec3f D_80B13FA8 = { 0.0f, 0.3f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 8000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 1000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +Vec3f D_80B13FC4 = { 160.0f, 0.0f, 240.0f }; -extern InitChainEntry D_80B13FB4[]; +void ObjDhouse_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjDhouse* this = THIS; -extern UNK_TYPE D_06004928; -extern UNK_TYPE D_06005A78; -extern UNK_TYPE D_06008040; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/ObjDhouse_Init.s") + DynaPolyActor_Init(&this->dyna, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/ObjDhouse_Destroy.s") + if (Flags_GetSwitch(globalCtx, OBJDHOUSE_GET_7F(&this->dyna.actor))) { + this->dyna.actor.draw = func_80B13E40; + func_80B13908(this); + } else { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_dhouse_Colheader_008040); + this->dyna.actor.flags |= ACTOR_FLAG_10; + func_80B1392C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B12A50.s") +void ObjDhouse_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjDhouse* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B12A88.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B12B38.s") +void func_80B12A50(ObjDhouseStruct1* this, ObjDhouseStruct3* ptr3, Vec3f* arg2) { + arg2->x = this->unk_00.x + ptr3->unk_08.x; + arg2->y = this->unk_00.y + ptr3->unk_08.y; + arg2->z = this->unk_00.z + ptr3->unk_08.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B12D78.s") +void func_80B12A88(Actor* thisx) { + ObjDhouse* this = THIS; + s32 i; + ObjDhouseStruct1* ptr; + ObjDhouseStruct3* ptr3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B12E7C.s") + for (i = 0, ptr = &this->unk_160[0], ptr3 = &D_80B13E90[0]; i < ARRAY_COUNT(this->unk_160); i++, ptr3++, ptr++) { + Math_Vec3f_Copy(&ptr->unk_00, &this->dyna.actor.world.pos); + Math_Vec3f_Copy(&ptr->unk_0C, &ptr3->unk_14); + ptr->unk_18 = this->dyna.actor.shape.rot; + ptr->unk_1E = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13170.s") +void func_80B12B38(ObjDhouse* this2, GlobalContext* globalCtx) { + ObjDhouse* this = this2; + s32 i; + f32 temp_f0; + CollisionPoly* sp90; + s32 phi_s3; + Vec3f sp80; + s32 sp7C; + ObjDhouseStruct1* ptr; + ObjDhouseStruct3* ptr3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13474.s") + for (i = 0, ptr = &this->unk_160[0], ptr3 = &D_80B13E90[0]; i < ARRAY_COUNT(this->unk_160); i++, ptr3++, ptr++) { + if (ptr->unk_1E >= 0) { + if (ptr->unk_1E >= ptr3->unk_26) { + ptr->unk_0C.y -= 2.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13724.s") + Math_Vec3f_Scale(&ptr->unk_0C, 0.96f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13908.s") + ptr->unk_00.x += ptr->unk_0C.x; + ptr->unk_00.y += ptr->unk_0C.y; + ptr->unk_00.z += ptr->unk_0C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B1391C.s") + ptr->unk_18.x += ptr3->unk_20.x; + ptr->unk_18.y += ptr3->unk_20.y; + ptr->unk_18.z += ptr3->unk_20.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B1392C.s") + if (ptr->unk_1E == ptr3->unk_26) { + func_80B12E7C(this, globalCtx, ptr, ptr3); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13940.s") + phi_s3 = false; + if (ptr->unk_0C.y < 0.0f) { + func_80B12A50(ptr, ptr3, &sp80); + temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp90, &sp7C, &this->dyna.actor, &sp80); + if (((sp80.y - 35.0f) < temp_f0) && (temp_f0 > (BGCHECK_Y_MIN + 1.0f))) { + phi_s3 = true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B139D8.s") + if (phi_s3) { + ptr->unk_1E = -1; + func_80B13170(this, globalCtx, ptr, ptr3); + } else if (ptr->unk_1E > 60) { + ptr->unk_1E = -1; + } else { + ptr->unk_1E++; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B139F4.s") +s32 func_80B12D78(ObjDhouse* this) { + s32 i; + ObjDhouseStruct2* ptr2 = &this->unk_240[0]; + s32 count = 0; + ObjDhouseStruct2* ptr22 = &this->unk_240[1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/ObjDhouse_Update.s") + for (i = 1; i < ARRAY_COUNT(this->unk_240); i++, ptr22++) { + if (ptr22->unk_28 < ptr2->unk_28) { + ptr2 = ptr22; + count = i; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/ObjDhouse_Draw.s") + return count; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13C08.s") +void func_80B12E7C(ObjDhouse* this, GlobalContext* globalCtx, ObjDhouseStruct1* ptr, ObjDhouseStruct3* ptr3) { + s32 i; + Vec3f spA0; + Vec3f sp94; + Vec3f sp88; + ObjDhouseStruct2* ptr2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dhouse/func_80B13E40.s") + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultVec3fXZ(&D_80B13FC4, &sp94); + sp94.y = 100.0f; + func_80B12A50(ptr, ptr3, &spA0); + + for (i = 0; i < 15; i++) { + ptr2 = &this->unk_240[func_80B12D78(this)]; + + ptr2->unk_00.x = Rand_ZeroOne() - 0.5f; + ptr2->unk_00.y = Rand_ZeroOne(); + ptr2->unk_00.z = Rand_ZeroOne() - 0.5f; + + ptr2->unk_0C.x = ptr2->unk_00.x * 24.0f; + ptr2->unk_0C.y = ptr2->unk_00.y * 34.0f; + ptr2->unk_0C.z = ptr2->unk_00.z * 24.0f; + + ptr2->unk_00.x = (ptr2->unk_00.x * 140.0f) + spA0.x; + ptr2->unk_00.y = ((ptr2->unk_00.y - 0.2f) * 50.0f) + spA0.y; + ptr2->unk_00.z = (ptr2->unk_00.z * 140.0f) + spA0.z; + + ptr2->unk_18 = (Rand_ZeroOne() * 0.057f) + 0.003f; + + ptr2->unk_1C.x = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.y = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.z = (u32)Rand_Next() >> 0x10; + + ptr2->unk_22 = ((u32)Rand_Next() >> 0x11) - 0x3FFF; + ptr2->unk_24 = ((u32)Rand_Next() >> 0x13) - 0xFFF; + ptr2->unk_26 = ((u32)Rand_Next() >> 0x12) - 0x1FFF; + ptr2->unk_29 = 0; + ptr2->unk_28 = 40; + + if ((i % 2) != 0) { + sp88.x = ((Rand_ZeroOne() - 0.5f) * sp94.x) + ptr2->unk_00.x; + sp88.y = ((Rand_ZeroOne() - 0.3f) * sp94.y) + ptr2->unk_00.y; + sp88.z = ((Rand_ZeroOne() - 0.5f) * sp94.z) + ptr2->unk_00.z; + + func_800B1210(globalCtx, &sp88, &gZeroVec3f, &D_80B13FA8, (s32)(Rand_ZeroOne() * 130.0f) + 20, + (s32)(Rand_ZeroOne() * 140.0f) + 60); + } + } +} + +void func_80B13170(ObjDhouse* this, GlobalContext* globalCtx, ObjDhouseStruct1* ptr, ObjDhouseStruct3* ptr3) { + s32 i; + Vec3f sp98; + Vec3f sp8C; + ObjDhouseStruct2* ptr2; + + func_80B12A50(ptr, ptr3, &sp98); + + for (i = 0; i < 11; i++) { + ptr2 = &this->unk_240[func_80B12D78(this)]; + + ptr2->unk_00.x = Rand_ZeroOne() - 0.5f; + ptr2->unk_00.y = Rand_ZeroOne(); + ptr2->unk_00.z = Rand_ZeroOne() - 0.5f; + + ptr2->unk_0C.x = ptr2->unk_00.x * 23.0f; + ptr2->unk_0C.y = (ptr2->unk_00.y * 19.0f) + 5.0f; + ptr2->unk_0C.z = ptr2->unk_00.z * 23.0f; + + ptr2->unk_00.x = (ptr2->unk_00.x * 80.0f) + sp98.x; + ptr2->unk_00.y = (ptr2->unk_00.y * 23.0f) + sp98.y + 15.0f; + ptr2->unk_00.z = (ptr2->unk_00.z * 80.0f) + sp98.z; + + ptr2->unk_1C.x = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.y = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.z = (u32)Rand_Next() >> 0x10; + + ptr2->unk_22 = ((u32)Rand_Next() >> 0x12) - 0x1FFF; + ptr2->unk_24 = ((u32)Rand_Next() >> 0x13) - 0xFFF; + ptr2->unk_26 = ((u32)Rand_Next() >> 0x12) - 0x1FFF; + + ptr2->unk_28 = 40; + + if (i < 3) { + ptr2->unk_18 = (Rand_ZeroOne() * 0.06f) + 0.12f; + ptr2->unk_29 = 1; + } else { + ptr2->unk_18 = (Rand_ZeroOne() * 0.05f) + 0.003f; + ptr2->unk_29 = 0; + } + + if ((i % 2) != 0) { + sp8C.x = ((Rand_ZeroOne() - 0.5f) * 160.0f) + ptr2->unk_00.x; + sp8C.y = (Rand_ZeroOne() * 120.0f) + ptr2->unk_00.y; + sp8C.z = ((Rand_ZeroOne() - 0.5f) * 160.0f) + ptr2->unk_00.z; + + func_800B1210(globalCtx, &sp8C, &gZeroVec3f, &D_80B13FA8, (s32)(Rand_ZeroOne() * 140.0f) + 20, + (s32)(Rand_ZeroOne() * 140.0f) + 40); + } + } +} + +void func_80B13474(ObjDhouse* this, GlobalContext* globalCtx, Vec3f* arg2) { + s32 i; + Vec3f sp88; + ObjDhouseStruct2* ptr2; + + for (i = 0; i < 5; i++) { + ptr2 = &this->unk_240[func_80B12D78(this)]; + + ptr2->unk_00.x = Rand_ZeroOne() - 0.5f; + ptr2->unk_00.y = Rand_ZeroOne(); + ptr2->unk_00.z = Rand_ZeroOne() - 0.5f; + + ptr2->unk_0C.x = ptr2->unk_00.x * 18.0f; + ptr2->unk_0C.y = ptr2->unk_00.y * 23.0f; + ptr2->unk_0C.z = ptr2->unk_00.z * 18.0f; + + ptr2->unk_00.x = (ptr2->unk_00.x * 40.0f) + arg2->x; + ptr2->unk_00.y = ((ptr2->unk_00.y - 0.4f) * 20.0f) + arg2->y; + ptr2->unk_00.z = (ptr2->unk_00.z * 40.0f) + arg2->z; + + ptr2->unk_1C.x = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.y = (u32)Rand_Next() >> 0x10; + ptr2->unk_1C.z = (u32)Rand_Next() >> 0x10; + + ptr2->unk_22 = ((u32)Rand_Next() >> 0x12) - 0x1FFF; + ptr2->unk_24 = ((u32)Rand_Next() >> 0x13) - 0xFFF; + ptr2->unk_26 = ((u32)Rand_Next() >> 0x12) - 0x1FFF; + + ptr2->unk_28 = 40; + ptr2->unk_18 = (Rand_ZeroOne() * 0.07f) + 0.003f; + ptr2->unk_29 = 0; + + sp88.x = ((Rand_ZeroOne() * 70.0f) - 35.0f) + ptr2->unk_00.x; + sp88.y = (Rand_ZeroOne() * 60.0f) + ptr2->unk_00.y; + sp88.z = ((Rand_ZeroOne() * 70.0f) - 35.0f) + ptr2->unk_00.z; + + func_800B1210(globalCtx, &sp88, &gZeroVec3f, &D_80B13FA8, (s32)(Rand_ZeroOne() * 80.0f) + 20, + (s32)(Rand_ZeroOne() * 90.0f) + 40); + } +} + +void func_80B13724(ObjDhouse* this, GlobalContext* globalCtx) { + f32 temp_f0; + f32 temp_f20 = this->dyna.actor.home.pos.y - 300.0f; + s32 i; + CollisionPoly* sp80; + ObjDhouseStruct2* ptr2; + Vec3f sp70; + s32 sp6C; + + for (i = 0, ptr2 = &this->unk_240[0]; i < ARRAY_COUNT(this->unk_240); i++, ptr2++) { + if (ptr2->unk_28 > 0) { + ptr2->unk_0C.y -= 2.2f; + + Math_Vec3f_Scale(&ptr2->unk_0C, 0.95f); + + ptr2->unk_00.x += ptr2->unk_0C.x; + ptr2->unk_00.y += ptr2->unk_0C.y; + ptr2->unk_00.z += ptr2->unk_0C.z; + + if (ptr2->unk_00.y < temp_f20) { + ptr2->unk_28 = 0; + } else { + ptr2->unk_1C.x += ptr2->unk_22; + ptr2->unk_1C.y += ptr2->unk_24; + ptr2->unk_1C.z += ptr2->unk_26; + ptr2->unk_28--; + + if (ptr2->unk_29 & 1) { + temp_f0 = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp80, &sp6C, &this->dyna.actor, &ptr2->unk_00); + if (((ptr2->unk_00.y - 20.0f) < temp_f0) && (temp_f0 > BGCHECK_Y_MIN + 1.0f)) { + Math_Vec3f_Copy(&sp70, &ptr2->unk_00); + ptr2->unk_28 = 0; + func_80B13474(this, globalCtx, &sp70); + } + } + } + } + } +} + +void func_80B13908(ObjDhouse* this) { + this->actionFunc = func_80B1391C; +} + +void func_80B1391C(ObjDhouse* this, GlobalContext* globalCtx) { +} + +void func_80B1392C(ObjDhouse* this) { + this->actionFunc = func_80B13940; +} + +void func_80B13940(ObjDhouse* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + s32 sp20 = false; + + if (Flags_GetSwitch(globalCtx, OBJDHOUSE_GET_7F(&this->dyna.actor))) { + sp20 = true; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_EXPLSION_LONG); + } + + if (sp20) { + func_80B12A88(&this->dyna.actor); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.draw = func_80B13C08; + this->dyna.actor.flags |= ACTOR_FLAG_20; + func_80B139D8(this); + } +} + +void func_80B139D8(ObjDhouse* this) { + this->unk_1370 = 120; + this->actionFunc = func_80B139F4; +} + +void func_80B139F4(ObjDhouse* this, GlobalContext* globalCtx) { + Camera* camera = GET_ACTIVE_CAM(globalCtx); + s16 quake; + + if (this->unk_1370 == 117) { + quake = Quake_Add(camera, 3); + Quake_SetSpeed(quake, 20000); + Quake_SetQuakeValues(quake, 8, 0, 0, 0); + Quake_SetCountdown(quake, 17); + } else if (this->unk_1370 == 105) { + quake = Quake_Add(camera, 3); + Quake_SetSpeed(quake, 20000); + Quake_SetQuakeValues(quake, 7, 0, 0, 0); + Quake_SetCountdown(quake, 20); + } else if (this->unk_1370 == 90) { + quake = Quake_Add(camera, 3); + Quake_SetSpeed(quake, 20000); + Quake_SetQuakeValues(quake, 5, 0, 0, 0); + Quake_SetCountdown(quake, 62); + } + + this->unk_1370--; + if (this->unk_1370 <= 0) { + this->dyna.actor.draw = func_80B13E40; + this->dyna.actor.flags &= ~ACTOR_FLAG_20; + this->dyna.actor.flags &= ~ACTOR_FLAG_10; + func_80B13908(this); + } else { + func_80B12B38(this, globalCtx); + func_80B13724(this, globalCtx); + } +} + +void ObjDhouse_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjDhouse* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjDhouse_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, object_dhouse_DL_005A78); +} + +void func_80B13C08(Actor* thisx, GlobalContext* globalCtx) { + ObjDhouse* this = THIS; + ObjDhouseStruct1* ptr; + ObjDhouseStruct2* ptr2; + ObjDhouseStruct3* ptr3; + s32 i; + + 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_dhouse_DL_004928); + + for (i = 0, ptr = &this->unk_160[0], ptr3 = &D_80B13E90[0]; i < ARRAY_COUNT(this->unk_160); i++, ptr3++, ptr++) { + if (ptr->unk_1E >= 0) { + Matrix_SetTranslateRotateYXZ(ptr->unk_00.x + ptr3->unk_08.x, ptr->unk_00.y + ptr3->unk_08.y, + ptr->unk_00.z + ptr3->unk_08.z, &ptr->unk_18); + Matrix_Translate(-ptr3->unk_08.x, -ptr3->unk_08.y, -ptr3->unk_08.z, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, ptr3->unk_00); + gSPDisplayList(POLY_OPA_DISP++, ptr3->unk_04); + } + } + + for (i = 0, ptr2 = &this->unk_240[0]; i < ARRAY_COUNT(this->unk_240); i++, ptr2++) { + if (ptr2->unk_28 > 0) { + Matrix_SetTranslateRotateYXZ(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, &ptr2->unk_1C); + Matrix_Scale(ptr2->unk_18, ptr2->unk_18, ptr2->unk_18, 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_dhouse_DL_0081D8); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80B13E40(Actor* thisx, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, object_dhouse_DL_004928); +} diff --git a/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.h b/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.h index 793aabfac..053928c1c 100644 --- a/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.h +++ b/src/overlays/actors/ovl_Obj_Dhouse/z_obj_dhouse.h @@ -7,11 +7,42 @@ struct ObjDhouse; typedef void (*ObjDhouseActionFunc)(struct ObjDhouse*, GlobalContext*); +#define OBJDHOUSE_GET_7F(thisx) ((thisx)->params & 0x7F) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ Vec3s unk_18; + /* 0x1E */ s8 unk_1E; +} ObjDhouseStruct1; // size = 0x20 + +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; + /* 0x26 */ s16 unk_26; + /* 0x28 */ s8 unk_28; + /* 0x29 */ u8 unk_29; +} ObjDhouseStruct2; // size = 0x2C + +typedef struct { + /* 0x00 */ Gfx* unk_00; + /* 0x04 */ Gfx* unk_04; + /* 0x08 */ Vec3f unk_08; + /* 0x14 */ Vec3f unk_14; + /* 0x20 */ Vec3s unk_20; + /* 0x26 */ s8 unk_26; +} ObjDhouseStruct3; // size = 0x28 + typedef struct ObjDhouse { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjDhouseActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x1214]; + /* 0x0160 */ ObjDhouseStruct1 unk_160[7]; + /* 0x0240 */ ObjDhouseStruct2 unk_240[100]; + /* 0x1370 */ s16 unk_1370; } ObjDhouse; // size = 0x1374 extern const ActorInit Obj_Dhouse_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Dinner/z_obj_dinner.c b/src/overlays/actors/ovl_Obj_Dinner/z_obj_dinner.c index 604d1dbbe..57f9d7550 100644 --- a/src/overlays/actors/ovl_Obj_Dinner/z_obj_dinner.c +++ b/src/overlays/actors/ovl_Obj_Dinner/z_obj_dinner.c @@ -1,6 +1,13 @@ -#include "z_obj_dinner.h" +/* + * File: z_obj_dinner.c + * Overlay: ovl_Obj_Dinner + * Description: Cremia and Romani's dinner + */ -#define FLAGS 0x00000020 +#include "z_obj_dinner.h" +#include "objects/object_obj_dinner/object_obj_dinner.h" + +#define FLAGS (ACTOR_FLAG_20) #define THIS ((ObjDinner*)thisx) @@ -13,7 +20,7 @@ const ActorInit Obj_Dinner_InitVars = { ACTOR_OBJ_DINNER, ACTORCAT_PROP, FLAGS, - OBJECT_OBJECT_UNSET_DINNER, + OBJECT_OBJ_DINNER, sizeof(ObjDinner), (ActorFunc)ObjDinner_Init, (ActorFunc)ObjDinner_Destroy, @@ -21,12 +28,10 @@ const ActorInit Obj_Dinner_InitVars = { (ActorFunc)ObjDinner_Draw, }; -extern Gfx D_060011E0[]; - void ObjDinner_Init(Actor* thisx, GlobalContext* globalCtx) { ObjDinner* this = THIS; - if (gSaveContext.isNight != true || (CURRENT_DAY == 3 && gSaveContext.weekEventReg[0x16] & 1)) { + if (gSaveContext.save.isNight != true || (CURRENT_DAY == 3 && gSaveContext.save.weekEventReg[22] & 1)) { Actor_MarkForDeath(&this->actor); } Actor_SetScale(&this->actor, 0.1f); @@ -43,7 +48,7 @@ void ObjDinner_Draw(Actor* thisx, GlobalContext* globalCtx) { 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_060011E0); + gSPDisplayList(POLY_OPA_DISP++, object_obj_dinner_DL_0011E0); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.c b/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.c index 680148896..163dd851d 100644 --- a/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.c +++ b/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.c @@ -1,6 +1,13 @@ -#include "z_obj_dora.h" +/* + * File: z_obj_dora.c + * Overlay: ovl_Obj_Dora + * Description: Swordsman's School - Gong + */ -#define FLAGS 0x00000010 +#include "z_obj_dora.h" +#include "assets/objects/object_dora/object_dora.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjDora*)thisx) @@ -9,7 +16,25 @@ void ObjDora_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjDora_Update(Actor* thisx, GlobalContext* globalCtx); void ObjDora_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObjDora_SetupWait(ObjDora* this); +void ObjDora_Wait(ObjDora* this, GlobalContext* globalCtx); +void ObjDora_SetupMoveGong(ObjDora* this); +void ObjDora_MoveGong(ObjDora* this, GlobalContext* globalCtx); +s32 ObjDora_IsHalfHour(u16 time); +void ObjDora_UpdateCollision(ObjDora* this, GlobalContext* globalCtx); + +typedef enum { + /* 0x0 */ DORA_HIT_NONE, + /* 0x1 */ DORA_HIT_LIGHT, + /* 0x2 */ DORA_HIT_STRONG +} ObjDoraHitStrength; + +typedef enum { + /* 0x0 */ DORA_DMGEFF_NONE, + /* 0xE */ DORA_DMGEFF_STRONG = 0xE, + /* 0xF */ DORA_DMGEFF_LIGHT +} ObjDoraDamageEffect; + const ActorInit Obj_Dora_InitVars = { ACTOR_OBJ_DORA, ACTORCAT_NPC, @@ -22,104 +47,306 @@ const ActorInit Obj_Dora_InitVars = { (ActorFunc)ObjDora_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[6] = { -static ColliderTrisElementInit D_80B61310[6] = { +static ColliderTrisElementInit sTrisElementsInit[6] = { { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0x00100000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0x00100000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, -35.0f, 0.0f }, { 260.0f, -185.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0x00100000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0x00100000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 260.0f, -185.0f, 0.0f }, { 260.0f, -485.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 260.0f, -485.0f, 0.0f }, { 0.0f, -635.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, -635.0f, 0.0f }, { -260.0f, -485.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -260.0f, -485.0f, 0.0f }, { -260.0f, -185.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -260.0f, -185.0f, 0.0f }, { 0.0f, -35.0f, 0.0f }, { 0.0f, -335.0f, 0.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B61478 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_TRIS, }, - 6, D_80B61310, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + 6, + sTrisElementsInit, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B61488 = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(2, 0xF), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(0, 0x0), - /* Zora boomerang */ DMG_ENTRY(0, 0xF), - /* Normal arrow */ DMG_ENTRY(0, 0xF), - /* UNK_DMG_0x06 */ DMG_ENTRY(2, 0xF), - /* Hookshot */ DMG_ENTRY(0, 0xF), - /* Goron punch */ DMG_ENTRY(2, 0xE), - /* Sword */ DMG_ENTRY(1, 0xF), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(0, 0xF), - /* Ice arrow */ DMG_ENTRY(0, 0xF), - /* Light arrow */ DMG_ENTRY(0, 0xF), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0xF), - /* Deku bubble */ DMG_ENTRY(0, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0x0), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0xF), - /* Zora punch */ DMG_ENTRY(0, 0xF), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* 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(0, 0x0), +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(2, DORA_DMGEFF_LIGHT), + /* Horse trample */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Zora boomerang */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Normal arrow */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* UNK_DMG_0x06 */ DMG_ENTRY(2, DORA_DMGEFF_LIGHT), + /* Hookshot */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Goron punch */ DMG_ENTRY(2, DORA_DMGEFF_STRONG), + /* Sword */ DMG_ENTRY(1, DORA_DMGEFF_LIGHT), + /* Goron pound */ DMG_ENTRY(1, DORA_DMGEFF_LIGHT), + /* Fire arrow */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Ice arrow */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Light arrow */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, DORA_DMGEFF_LIGHT), + /* Deku spin */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Deku bubble */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Normal shield */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, DORA_DMGEFF_LIGHT), + /* Zora punch */ DMG_ENTRY(0, DORA_DMGEFF_LIGHT), + /* Spin attack */ DMG_ENTRY(1, DORA_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, DORA_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(0, DORA_DMGEFF_NONE), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B614A8 = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -#endif +void ObjDora_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjDora* this = THIS; + s32 i; + s32 j; + Vec3f vtx[3]; + s32 buf = 0; + s32 buff2 = 0; -extern ColliderTrisElementInit D_80B61310[6]; -extern ColliderTrisInit D_80B61478; -extern DamageTable D_80B61488; -extern CollisionCheckInfoInit2 D_80B614A8; + Actor_SetScale(&this->actor, 0.1f); + ActorShape_Init(&this->actor.shape, 0.0f, &ActorShadow_DrawCircle, 36.0f); -extern UNK_TYPE D_06004160; + this->gongRotation.x = 0; + this->gongRotation.z = 0; + this->gongAngle.x = 0; + this->gongAngle.z = 0; + this->lastGongHitType = DORA_HIT_NONE; + this->rupeeDropTimer = 0; + this->collisionCooldownTimer = 0; + this->unk3AA = 0; + this->gongForce.x = 0.0f; + this->gongForce.y = 0.0f; + this->gongForce.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/ObjDora_Init.s") + Collider_InitTris(globalCtx, &this->colliderTris); + Collider_SetTris(globalCtx, &this->colliderTris, &this->actor, &sTrisInit, this->colliderTrisElements); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/ObjDora_Destroy.s") + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60C9C.s") + for (i = 0; i < ARRAY_COUNT(this->colliderTrisElements); i++) { + for (j = 0; j < ARRAY_COUNT(vtx); j++) { + Matrix_MultVec3f(&sTrisElementsInit[i].dim.vtx[j], &vtx[j]); + } + Collider_SetTrisVertices(&this->colliderTris, i, &vtx[0], &vtx[1], &vtx[2]); + } + ObjDora_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60CB0.s") +void ObjDora_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjDora* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60CC0.s") + Collider_DestroyTris(globalCtx, &this->colliderTris); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60D34.s") +void ObjDora_SetupWait(ObjDora* this) { + this->actionFunc = ObjDora_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60E54.s") +void ObjDora_Wait(ObjDora* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/func_80B60EE8.s") +void ObjDora_SetupMoveGong(ObjDora* this) { + if (this->lastGongHitType == DORA_HIT_LIGHT) { + this->gongForce.x = 2.0f; + this->gongForce.y = 5461.0f; + this->gongForce.z = 1820.0f; + } else { + this->gongForce.x = 4.0f; + this->gongForce.y = 12743.0f; + this->gongForce.z = 5461.0f; + } + this->gongAngle.x = 0; + this->gongAngle.z = 0; + this->actionFunc = ObjDora_MoveGong; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/ObjDora_Update.s") +void ObjDora_MoveGong(ObjDora* this, GlobalContext* globalCtx) { -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dora/ObjDora_Draw.s") + if ((this->gongForce.y < 182.0f) && (this->gongForce.z < 182.0f)) { + this->lastGongHitType = DORA_HIT_LIGHT; + ObjDora_SetupWait(this); + } + + Math_SmoothStepToF(&this->gongForce.x, 0, 0.2f, 0.2f, 0.1f); + Math_SmoothStepToF(&this->gongForce.y, 0, 0.5f, 54.0f, 18.0f); + Math_SmoothStepToF(&this->gongForce.z, 0, 0.5f, 54.0f, 18.0f); + this->gongAngle.x += 0x1555; + this->gongAngle.z += 0x238E; + this->gongRotation.x = Math_SinS(this->gongAngle.x) * this->gongForce.y; + this->gongRotation.z = Math_SinS(this->gongAngle.z) * this->gongForce.z; +} + +s32 ObjDora_IsHalfHour(u16 time) { + f32 timeHalfHour = time; + + timeHalfHour -= (CLOCK_TIME_F(0, 30) * (s32)(time / CLOCK_TIME_F(0, 30))); + if ((timeHalfHour < CLOCK_TIME_F(0, 1)) || (CLOCK_TIME_F(0, 29) < timeHalfHour)) { + return true; + } + + return false; +} + +void ObjDora_UpdateCollision(ObjDora* this, GlobalContext* globalCtx) { + Actor* itemDrop; + u16 time; + + if (this->colliderTris.base.acFlags & AC_HIT) { + time = gSaveContext.save.time; + this->colliderTris.base.acFlags &= ~AC_HIT; + this->collisionCooldownTimer = 5; + + switch (this->actor.colChkInfo.damageEffect) { + case DORA_DMGEFF_STRONG: + case DORA_DMGEFF_LIGHT: + if (this->actor.colChkInfo.damageEffect == DORA_DMGEFF_LIGHT) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DORA_S); + this->lastGongHitType = DORA_HIT_LIGHT; + } else { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_DORA_L); + this->lastGongHitType = DORA_HIT_STRONG; + } + + func_800BC848(&this->actor, globalCtx, 5, 10); + ObjDora_SetupMoveGong(this); + + if ((ObjDora_IsHalfHour(time) == true) && (this->rupeeDropTimer == 0)) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + itemDrop = Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_RUPEE_BLUE); + itemDrop->world.rot.y = this->actor.world.rot.y; + itemDrop->world.rot.y += (s32)(Rand_Centered() * 90.0f * (0x10000 / 360.0f)); + itemDrop->velocity.y = 5.0f; + itemDrop->gravity = -1.0f; + this->rupeeDropTimer = 40; + } + break; + } + } + + if (this->rupeeDropTimer > 0) { + this->rupeeDropTimer--; + } + + if (this->collisionCooldownTimer > 0) { + this->collisionCooldownTimer--; + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + } +} + +void ObjDora_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjDora* this = THIS; + + this->actionFunc(this, globalCtx); + ObjDora_UpdateCollision(this, globalCtx); +} + +void ObjDora_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f position = { 0.0f, -61.5f, 0.0f }; + ObjDora* this = THIS; + f32 gongForceX; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->actionFunc == ObjDora_MoveGong) { + gongForceX = this->gongForce.x; + if ((globalCtx->state.frames % 2) != 0) { + gongForceX *= -1.0f; + } + + Matrix_Push(); + Matrix_RotateXS(this->gongRotation.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++, &gDoraGongDL); + + Matrix_Translate(position.x, position.y + gongForceX, position.z + gongForceX, MTXMODE_APPLY); + Matrix_RotateXS(this->gongRotation.z - this->gongRotation.x, MTXMODE_APPLY); + Matrix_Translate(-position.x, -position.y, -position.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++, &gDoraChainDL); + + Matrix_Pop(); + } else { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, &gDoraChainDL); + gSPDisplayList(POLY_OPA_DISP++, &gDoraGongDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.h b/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.h index a40405b34..a2dbbea16 100644 --- a/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.h +++ b/src/overlays/actors/ovl_Obj_Dora/z_obj_dora.h @@ -9,9 +9,16 @@ typedef void (*ObjDoraActionFunc)(struct ObjDora*, GlobalContext*); typedef struct ObjDora { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x248]; + /* 0x0144 */ ColliderTris colliderTris; + /* 0x0164 */ ColliderTrisElement colliderTrisElements[6]; /* 0x038C */ ObjDoraActionFunc actionFunc; - /* 0x0390 */ char unk_390[0x1C]; + /* 0x0390 */ Vec3f gongForce; + /* 0x039C */ Vec2s gongAngle; + /* 0x03A0 */ s16 lastGongHitType; + /* 0x03A2 */ Vec2s gongRotation; // gongAngle * gongForce. Used in ObjDora_Draw. + /* 0x03A6 */ s16 rupeeDropTimer; + /* 0x03A8 */ s16 collisionCooldownTimer; + /* 0x03AA */ s16 unk3AA; // Set but not used } ObjDora; // size = 0x3AC extern const ActorInit Obj_Dora_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 96d817a70..dbc945109 100644 --- a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c +++ b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_dowsing.c + * Overlay: ovl_Obj_Dowsing + * Description: + */ + #include "z_obj_dowsing.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjDowsing*)thisx) @@ -8,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, @@ -21,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 Flags_GetCollectible(globalCtx, flag); + } else if (type == DOWSING_CHEST) { + return Flags_GetTreasure(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_Driftice/z_obj_driftice.c b/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.c index 1f6dc10fe..abc8d6c85 100644 --- a/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.c +++ b/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_driftice.c + * Overlay: ovl_Obj_Driftice + * Description: Floating Ice Platforms in Mountain Village + */ + #include "z_obj_driftice.h" +#include "objects/object_driftice/object_driftice.h" #define FLAGS 0x00000000 @@ -9,7 +16,15 @@ void ObjDriftice_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjDriftice_Update(Actor* thisx, GlobalContext* globalCtx); void ObjDriftice_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A671A8(ObjDriftice* this); +void func_80A671BC(ObjDriftice* this, GlobalContext* globalCtx); +void func_80A671CC(ObjDriftice* this); +void func_80A671E0(ObjDriftice* this, GlobalContext* globalCtx); +void func_80A6743C(ObjDriftice* this); +void func_80A67450(ObjDriftice* this, GlobalContext* globalCtx); +void func_80A674A8(ObjDriftice* this); +void func_80A674C4(ObjDriftice* this, GlobalContext* globalCtx); + const ActorInit Obj_Driftice_InitVars = { ACTOR_OBJ_DRIFTICE, ACTORCAT_BG, @@ -22,52 +37,423 @@ const ActorInit Obj_Driftice_InitVars = { (ActorFunc)ObjDriftice_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A676F4[] = { +static f32 D_80A67620[][3] = { + { 1.0f, 150.0f, 150.0f }, + { 1.5f, 250.0f, 200.0f }, + { 2.0f, 350.0f, 250.0f }, +}; + +static f32 D_80A67644[] = { 1.5f, 3.0f, 4.5f, 6.0f, 7.5f, 9.0f, 10.5f, 0.0f }; + +static f32 D_80A67664[][4] = { + { 0.6f, 0.5f, 0.2f, 0.4f }, + { 0.8f, 0.7f, 0.35f, 0.7f }, + { 1.0f, 1.0f, 0.8f, 1.0f }, +}; + +typedef struct { + /* 0x0 */ s16 unk_00; + /* 0x2 */ s16 unk_02; + /* 0x4 */ f32 unk_04; + /* 0x8 */ f32 unk_08; +} ObjDrifticeDataStruct; // size = 0xC + +static ObjDrifticeDataStruct D_80A67694[] = { + { 0x12C, 0x64, 1.3f, 2.0f }, + { 0x258, 0x1F4, 1.2f, 1.8f }, + { 0x4B0, 0x3E8, 1.1f, 1.5f }, +}; + +static ObjDrifticeDataStruct D_80A676B8[] = { { 0x320, 0x190, 200.0f, 400.0f }, { 0x5DC, 0x258, 100.0f, 300.0f } }; + +static ObjDrifticeDataStruct D_80A676D0[] = { + { 0x12C, 0x64, 300.0f, 700.0f }, + { 0x258, 0x258, 200.0f, 400.0f }, + { 0x4B0, 0x4B0, 100.0f, 300.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_STOP), }; -#endif +void func_80A66570(ObjDriftice* this, s32 arg1) { + Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->unk_16C[arg1]); +} -extern InitChainEntry D_80A676F4[]; +void func_80A665AC(s16* arg0, s16 arg1) { + if (arg1 < *arg0) { + *arg0 = arg1; + } else if (*arg0 < -arg1) { + *arg0 = -arg1; + } +} -extern UNK_TYPE D_060016A0; -extern UNK_TYPE D_06001AA8; +f32 func_80A665EC(ObjDrifticeStruct* arg0, ObjDriftice* this) { + f32 phi_f2 = 0.0f; + f32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A66570.s") + if (this->unk_248 >= 10) { + sp20 = -8.0f; + } else if (this->unk_248 < -9) { + sp20 = 0.0f; + } else if (this->unk_248 > 0) { + sp20 = (Math_CosS(fabsf(this->unk_248) * (0x8000 * 0.1f)) - 1.0f) * 4.0f; + } else { + sp20 = (Math_CosS(fabsf(this->unk_248) * (0x8000 * 0.1f)) + 1.0f) * -4.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A665AC.s") + if (this->unk_248 > 0) { + if (arg0->unk_00.unk_00 > 0) { + arg0->unk_00.unk_00--; + } else { + arg0->unk_00.unk_00 = Rand_S16Offset(30, 70); + arg0->unk_00.unk_04 = Rand_S16Offset(1000, 1000); + arg0->unk_00.unk_0C = (Rand_ZeroOne() * 1.5f) + 1.0f; + arg0->unk_00.unk_10 = fabsf(arg0->unk_00.unk_0C - arg0->unk_00.unk_08) * 0.05f; + } + } else { + arg0->unk_00.unk_00 = 0; + arg0->unk_00.unk_0C = phi_f2; + arg0->unk_00.unk_10 = (fabsf(arg0->unk_00.unk_0C - arg0->unk_00.unk_08) * 0.05f) + 0.02f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A665EC.s") + arg0->unk_00.unk_02 += arg0->unk_00.unk_04; + Math_StepToF(&arg0->unk_00.unk_08, arg0->unk_00.unk_0C, arg0->unk_00.unk_10); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A667F0.s") + sp20 += (Math_SinS(arg0->unk_00.unk_02) * arg0->unk_00.unk_08); + return sp20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A66930.s") +f32 func_80A667F0(ObjDrifticeStruct3* arg0, ObjDriftice* this) { + f32 temp_f20 = 0.0f; + ObjDrifticeStruct3* temp_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A66C4C.s") + for (i = 0; i < 3; i++) { + temp_s0 = &arg0[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A66E30.s") + if (temp_s0->unk_00 > 0) { + temp_s0->unk_00--; + } else { + temp_s0->unk_00 = Rand_S16Offset(30, 70); + temp_s0->unk_04 = Rand_S16Offset(D_80A67694[i].unk_00, D_80A67694[i].unk_02); + temp_s0->unk_0C = D_80A67694[i].unk_04 + (D_80A67694[i].unk_08 * Rand_ZeroOne()); + temp_s0->unk_10 = fabsf(temp_s0->unk_0C - temp_s0->unk_08) * 0.05f; + } + temp_s0->unk_02 += temp_s0->unk_04; + Math_StepToF(&temp_s0->unk_08, temp_s0->unk_0C, temp_s0->unk_10); + temp_f20 += Math_SinS(temp_s0->unk_02) * temp_s0->unk_08; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/ObjDriftice_Init.s") + return temp_f20; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/ObjDriftice_Destroy.s") +void func_80A66930(ObjDrifticeStruct2* arg0, ObjDriftice* this, s16* arg2, s16* arg3) { + ObjDrifticeStruct3* temp_s0; + f32 temp_f22 = 0.0f; + s16 phi_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A671A8.s") + if (this->unk_248 > 0) { + f32 temp_f20 = this->dyna.actor.xzDistToPlayer * this->unk_240 * 0.0007075472f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A671BC.s") + if (temp_f20 > 1.0f) { + temp_f20 = 1.0f; + } else if (temp_f20 < 0.01f) { + temp_f20 = 0.01f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A671CC.s") + Math_StepToS(&arg0->unk_00[1], 1200.0f * temp_f20, 0x64); + phi_s0 = 2500.0f * temp_f20; + Math_StepToS(&arg0->unk_00[3], Math_CosS(arg0->unk_00[2] * 6.5536f) * (120.0f * temp_f20), 0x28); + Math_StepToF(&arg0->unk_08, 1.0f, 0.02f); + } else { + Math_StepToS(&arg0->unk_00[1], 0, 0x96); + phi_s0 = 0; + Math_StepToS(&arg0->unk_00[3], 20, 7); + Math_StepToF(&arg0->unk_08, 0.0f, 0.02f); + } + Math_ScaledStepToS(arg0->unk_00, this->dyna.actor.yawTowardsPlayer, arg0->unk_00[1]); + *arg3 = arg0->unk_00[0]; + Math_ScaledStepToS(&arg0->unk_00[2], phi_s0, arg0->unk_00[3]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A671E0.s") + for (i = 0; i < 2; i++) { + temp_s0 = &arg0->unk_0C[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A6743C.s") + if (temp_s0->unk_00 > 0) { + temp_s0->unk_00--; + } else { + temp_s0->unk_00 = Rand_S16Offset(30, 70); + temp_s0->unk_04 = Rand_S16Offset(D_80A676B8[i].unk_00, D_80A676B8[i].unk_02); + temp_s0->unk_0C = D_80A676B8[i].unk_04 + (D_80A676B8[i].unk_08 * Rand_ZeroOne()); + temp_s0->unk_10 = fabsf(temp_s0->unk_0C - temp_s0->unk_08) * 0.033333335f; + } + temp_s0->unk_02 += temp_s0->unk_04; + Math_StepToF(&temp_s0->unk_08, temp_s0->unk_0C, temp_s0->unk_10); + temp_f22 += Math_SinS(temp_s0->unk_02) * temp_s0->unk_08; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A67450.s") + temp_f22 *= arg0->unk_08; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A674A8.s") + //! FAKE: + *arg2 = arg0->unk_00[2] + (s32)((void)0, temp_f22); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/func_80A674C4.s") +void func_80A66C4C(ObjDrifticeStruct4* arg0, ObjDriftice* this, s16* arg2, s16* arg3) { + ObjDrifticeStruct3* temp_s0; + f32 temp_f20 = 0.0f; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/ObjDriftice_Update.s") + if (arg0->unk_00[0] > 0) { + arg0->unk_00[0]--; + } else { + arg0->unk_00[0] = Rand_S16Offset(30, 70); + arg0->unk_00[2] = Rand_S16Offset(-200, 200); + arg0->unk_00[4] = Rand_S16Offset(-400, 400); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Driftice/ObjDriftice_Draw.s") + Math_StepToS(&arg0->unk_00[1], arg0->unk_00[2], 0x32); + Math_StepToS(&arg0->unk_00[3], arg0->unk_00[4], 0x32); + + *arg3 = arg0->unk_00[3] + arg0->unk_00[1]; + + for (i = 0; i < 3; i++) { + temp_s0 = &arg0->unk_0C[i]; + + if (temp_s0->unk_00 > 0) { + temp_s0->unk_00--; + } else { + temp_s0->unk_00 = Rand_S16Offset(30, 70); + temp_s0->unk_04 = Rand_S16Offset(D_80A676D0[i].unk_00, D_80A676D0[i].unk_02); + temp_s0->unk_0C = D_80A676D0[i].unk_04 + (D_80A676D0[i].unk_08 * Rand_ZeroOne()); + temp_s0->unk_10 = fabsf(temp_s0->unk_0C - temp_s0->unk_08) * 0.033333335f; + } + temp_s0->unk_02 += temp_s0->unk_04; + Math_StepToF(&temp_s0->unk_08, temp_s0->unk_0C, temp_s0->unk_10); + temp_f20 += Math_SinS(temp_s0->unk_02) * temp_s0->unk_08; + } + + *arg2 = temp_f20; +} + +void func_80A66E30(ObjDrifticeStruct* arg0, ObjDriftice* this) { + f32 temp; + f32* temp_s1 = D_80A67664[OBJDRIFTICE_GET_ROT(&this->dyna.actor) - 1]; + s16 sp36; + s16 sp34; + s16 sp32; + s16 sp30; + f32 sp2C; + f32 sp28; + f32 sp24; + s16 sp22; + + sp2C = func_80A665EC(arg0, this); + sp28 = func_80A667F0(arg0->unk_14, this); + func_80A66930(&arg0->unk_50, this, &sp32, &sp30); + func_80A66C4C(&arg0->unk_84, this, &sp36, &sp34); + + this->dyna.actor.shape.yOffset = this->unk_240 * ((sp28 * temp_s1[1]) + (sp2C * temp_s1[0])); + + sp24 = (sp32 * temp_s1[2]) + (sp36 * temp_s1[3]) * (temp = 1.0f); + sp22 = (sp34 + sp30) - this->dyna.actor.shape.rot.y; + + this->dyna.actor.shape.rot.x = Math_CosS(sp22) * sp24; + func_80A665AC(&this->dyna.actor.shape.rot.x, 0xA28); + this->dyna.actor.shape.rot.z = -Math_SinS(sp22) * sp24; + func_80A665AC(&this->dyna.actor.shape.rot.z, 0xA28); +} + +void ObjDriftice_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjDriftice* this = THIS; + f32* sp2C = D_80A67620[OBJDRIFTICE_GET_3(&this->dyna.actor)]; + Path* path; + s32 phi_a1; + s32 sp20; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.world.rot.z = 0; + + Actor_SetScale(&this->dyna.actor, sp2C[0] * 0.035377357f); + this->dyna.actor.uncullZoneScale = sp2C[1]; + this->dyna.actor.uncullZoneDownward = sp2C[2]; + this->unk_240 = 1.0f / this->dyna.actor.scale.x; + this->unk_23C = D_80A67644[OBJDRIFTICE_GET_E00(&this->dyna.actor)]; + + sp20 = 0; + if (this->unk_23C < 0.01f) { + sp20 = 1; + } + + this->unk_244 = thisx->home.rot.z * 45.511112f; + + phi_a1 = 0; + if (sp20 == 0) { + phi_a1 = 1; + } + + if (thisx->home.rot.z != 0) { + phi_a1 |= 3; + } + + DynaPolyActor_Init(&this->dyna, phi_a1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_driftice_Colheader_001AA8); + + if (sp20 != 0) { + func_80A671A8(this); + } else { + this->dyna.actor.flags |= ACTOR_FLAG_10; + + path = &globalCtx->setupPathList[OBJDRIFTICE_GET_1FC(&this->dyna.actor)]; + this->unk_164 = 0; + this->unk_160 = path->count - 1; + this->unk_168 = 1; + + this->unk_16C = Lib_SegmentedToVirtual(path->points); + func_80A66570(this, this->unk_164); + func_80A671CC(this); + } +} + +void ObjDriftice_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjDriftice* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80A671A8(ObjDriftice* this) { + this->actionFunc = func_80A671BC; +} + +void func_80A671BC(ObjDriftice* this, GlobalContext* globalCtx) { +} + +void func_80A671CC(ObjDriftice* this) { + this->actionFunc = func_80A671E0; +} + +void func_80A671E0(ObjDriftice* this, GlobalContext* globalCtx) { + f32 phi_f0; + Vec3f sp40; + f32 sp3C; + f32 phi_f12; + Vec3s* points; + s32 sp30; + Actor* thisx = &this->dyna.actor; + + Math_Vec3s_ToVec3f(&sp40, &(&this->unk_16C[this->unk_164])[this->unk_168]); + Math_Vec3f_Diff(&sp40, &this->dyna.actor.world.pos, &thisx->velocity); + + sp3C = Math3D_Vec3fMagnitude(&thisx->velocity); + if (sp3C < (this->unk_23C * 8.0f)) { + phi_f0 = this->unk_23C * 0.4f; + phi_f12 = this->unk_23C * 0.05f; + } else { + phi_f0 = this->unk_23C; + phi_f12 = this->unk_23C * 0.13f; + } + + Math_StepToF(&this->dyna.actor.speedXZ, phi_f0, phi_f12); + + if ((this->dyna.actor.speedXZ + 0.05f) < sp3C) { + Math_Vec3f_Scale(&this->dyna.actor.velocity, this->dyna.actor.speedXZ / sp3C); + this->dyna.actor.world.pos.x += this->dyna.actor.velocity.x; + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; + this->dyna.actor.world.pos.z += this->dyna.actor.velocity.z; + } else { + sp30 = true; + this->unk_164 += this->unk_168; + + if (1) {} + + this->dyna.actor.speedXZ *= 0.5f; + if (((this->unk_164 >= this->unk_160) && (this->unk_168 > 0)) || + ((this->unk_164 <= 0) && (this->unk_168 < 0))) { + if (!OBJDRIFTICE_GET_1000(&this->dyna.actor)) { + this->unk_168 = -this->unk_168; + func_80A674A8(this); + } else { + points = &this->unk_16C[this->unk_160]; + + if (this->unk_168 > 0) { + this->unk_164 = 0; + } else { + this->unk_164 = this->unk_160; + } + + if ((this->unk_16C[0].x != points->x) || (this->unk_16C[0].y != points->y) || + (this->unk_16C[0].z != points->z)) { + func_80A6743C(this); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + sp30 = false; + } + } + } + + if (sp30) { + func_80A66570(this, this->unk_164); + } + } +} + +void func_80A6743C(ObjDriftice* this) { + this->actionFunc = func_80A67450; +} + +void func_80A67450(ObjDriftice* this, GlobalContext* globalCtx) { + if (this->unk_248 < 0) { + func_80A66570(this, this->unk_164); + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + func_80A671CC(this); + } +} + +void func_80A674A8(ObjDriftice* this) { + this->unk_24C = 10; + this->actionFunc = func_80A674C4; +} + +void func_80A674C4(ObjDriftice* this, GlobalContext* globalCtx) { + this->unk_24C--; + if (this->unk_24C <= 0) { + this->dyna.actor.speedXZ = 0.0f; + func_80A671CC(this); + } +} + +void ObjDriftice_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjDriftice* this = THIS; + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + if (this->unk_248 < 0) { + this->unk_248 = 1; + } else { + this->unk_248++; + } + } else { + if (this->unk_248 > 0) { + this->unk_248 = -1; + } else { + this->unk_248--; + } + } + + this->dyna.actor.shape.rot.y += this->unk_244; + + this->actionFunc(this, globalCtx); + + if (OBJDRIFTICE_GET_ROT(&this->dyna.actor) && (this->dyna.actor.flags & ACTOR_FLAG_40)) { + func_80A66E30(&this->unk_170, this); + } +} + +void ObjDriftice_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjDriftice* this = THIS; + + Gfx_DrawDListOpa(globalCtx, object_driftice_DL_0016A0); +} diff --git a/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.h b/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.h index cdfc01f17..190fbdcb6 100644 --- a/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.h +++ b/src/overlays/actors/ovl_Obj_Driftice/z_obj_driftice.h @@ -7,11 +7,53 @@ struct ObjDriftice; typedef void (*ObjDrifticeActionFunc)(struct ObjDriftice*, GlobalContext*); +#define OBJDRIFTICE_GET_3(thisx) ((thisx)->params & 3) +#define OBJDRIFTICE_GET_1FC(thisx) (((thisx)->params >> 2) & 0x7F) +#define OBJDRIFTICE_GET_E00(thisx) (((thisx)->params >> 9) & 7) +#define OBJDRIFTICE_GET_1000(thisx) (((thisx)->params >> 0xC) & 1) +#define OBJDRIFTICE_GET_ROT(thisx) ((thisx)->home.rot.x & 3) + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ s16 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; +} ObjDrifticeStruct3; // size = 0x14 + +typedef struct { + /* 0x00 */ s16 unk_00[2]; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ ObjDrifticeStruct3 unk_0C[2]; +} ObjDrifticeStruct2; // size = 0x34 + +typedef struct { + /* 0x00 */ s16 unk_00[6]; + /* 0x0C */ ObjDrifticeStruct3 unk_0C[3]; +} ObjDrifticeStruct4; // size = 0x48 + +typedef struct { + /* 0x00 */ ObjDrifticeStruct3 unk_00; + /* 0x14 */ ObjDrifticeStruct3 unk_14[3]; + /* 0x50 */ ObjDrifticeStruct2 unk_50; + /* 0x84 */ ObjDrifticeStruct4 unk_84; +} ObjDrifticeStruct; // size = 0xCC + typedef struct ObjDriftice { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjDrifticeActionFunc actionFunc; - /* 0x0160 */ char unk_160[0xF0]; + /* 0x0160 */ s32 unk_160; + /* 0x0164 */ s32 unk_164; + /* 0x0168 */ s32 unk_168; + /* 0x016C */ Vec3s* unk_16C; + /* 0x0170 */ ObjDrifticeStruct unk_170; + /* 0x023C */ f32 unk_23C; + /* 0x0240 */ f32 unk_240; + /* 0x0244 */ s16 unk_244; + /* 0x0248 */ s32 unk_248; + /* 0x024C */ s32 unk_24C; } ObjDriftice; // size = 0x250 extern const ActorInit Obj_Driftice_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Ending/z_obj_ending.c b/src/overlays/actors/ovl_Obj_Ending/z_obj_ending.c index 7ae7399ca..5109cf284 100644 --- a/src/overlays/actors/ovl_Obj_Ending/z_obj_ending.c +++ b/src/overlays/actors/ovl_Obj_Ending/z_obj_ending.c @@ -5,8 +5,9 @@ */ #include "z_obj_ending.h" +#include "objects/object_ending_obj/object_ending_obj.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjEnding*)thisx) @@ -26,14 +27,9 @@ const ActorInit Obj_Ending_InitVars = { (ActorFunc)ObjEnding_Draw, }; -extern Gfx D_060003D0[]; -extern Gfx D_060031A0[]; -extern Gfx D_06003440[]; -extern AnimatedMaterial D_06001FF8; - static ObjEndingModelInfo sModelInfo[] = { - { { D_06003440, D_060031A0 }, NULL }, - { { NULL, D_060003D0 }, &D_06001FF8 }, + { { object_ending_obj_DL_003440, object_ending_obj_DL_0031A0 }, NULL }, + { { NULL, object_ending_obj_DL_0003D0 }, object_ending_obj_Matanimheader_001FF8 }, }; static InitChainEntry sInitChain[] = { @@ -48,7 +44,7 @@ void ObjEnding_Init(Actor* thisx, GlobalContext* globalCtx) { this->modelInfo = &sModelInfo[thisx->params]; animMat = this->modelInfo->animMat; if (animMat != NULL) { - this->animMat = (AnimatedMaterial*)Lib_SegmentedToVirtual(animMat); + this->animMat = Lib_SegmentedToVirtual(animMat); } } @@ -65,10 +61,10 @@ void ObjEnding_Draw(Actor* thisx, GlobalContext* globalCtx) { } dl1 = this->modelInfo->dLists[0]; if (dl1 != NULL) { - func_800BDFC0(globalCtx, dl1); + Gfx_DrawDListOpa(globalCtx, dl1); } dl2 = this->modelInfo->dLists[1]; if (dl2 != NULL) { - func_800BE03C(globalCtx, dl2); + Gfx_DrawDListXlu(globalCtx, dl2); } } 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 e34d5321c..7d662432a 100644 --- a/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c +++ b/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c @@ -1,6 +1,13 @@ -#include "z_obj_entotu.h" +/* + * File: z_obj_entotu.c + * Overlay: ovl_Obj_Entotu + * Description: Clock Town Smoking Chimney + */ -#define FLAGS 0x00000030 +#include "z_obj_entotu.h" +#include "objects/object_f53_obj/object_f53_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjEntotu*)thisx) @@ -9,7 +16,6 @@ void ObjEntotu_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjEntotu_Update(Actor* thisx, GlobalContext* globalCtx); void ObjEntotu_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Entotu_InitVars = { ACTOR_OBJ_ENTOTU, ACTORCAT_PROP, @@ -22,23 +28,146 @@ const ActorInit Obj_Entotu_InitVars = { (ActorFunc)ObjEntotu_Draw, }; -#endif +#include "overlays/ovl_Obj_Entotu/ovl_Obj_Entotu.c" -extern UNK_TYPE D_06000158; -extern UNK_TYPE D_06001C00; +s32 func_80A34700(s16 minutes) { + s32 ret = 0; + s16 time = TIME_TO_MINUTES_F(gSaveContext.save.time); + s32 hours = time / 60; + s32 currMinutes = time % 60; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/func_80A34700.s") + if (hours >= 16) { + if ((hours == 16) && (currMinutes < minutes)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/func_80A349C0.s") + if (hours >= 20) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/func_80A34A44.s") + if ((hours == 19) && (minutes < currMinutes)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/func_80A34B28.s") + ret = 3; + } else if (hours >= 11) { + if ((hours == 11) && (currMinutes < minutes)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/ObjEntotu_Init.s") + if (hours >= 14) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/ObjEntotu_Destroy.s") + if ((hours == 13) && (minutes < currMinutes)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/ObjEntotu_Update.s") + ret = 2; + } else if (hours >= 6) { + if ((hours == 6) && (currMinutes < minutes)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Entotu/ObjEntotu_Draw.s") + if (hours >= 9) { + return 0; + } + + if ((hours == 8) && (minutes < currMinutes)) { + return 0; + } + + ret = 1; + } + return ret; +} + +void func_80A349C0(ObjEntotu* this) { + s32 temp_v0 = func_80A34700(this->unk_1C6); + u8 temp = temp_v0; + s16 temp2 = this->unk_1C4; + + if (temp_v0 != temp2) { + this->unk_1C4 = temp; + this->unk_1C6 = Rand_S16Offset(0, 59); + } + + temp2 = this->unk_1C4; + Math_ApproachF(&this->unk_1B8.x, (temp2 == 0) ? 0.0f : 1.0f, 0.02f, 1000.0f); +} + +void func_80A34A44(ObjEntotu* this, GlobalContext* globalCtx) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.0f, MTXMODE_APPLY); + + 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_f53_obj_DL_000158); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A34B28(ObjEntotu* this, GlobalContext* globalCtx) { + u8 sp57; + u8 sp56; + s32 i; + + this->unk_1B8.y += 1.8f; + this->unk_1B8.z += 0.6f; + sp57 = 0x7F - (u8)this->unk_1B8.y; + sp56 = 0x7F - (u8)this->unk_1B8.z; + + this->unk_1B8.x = CLAMP(this->unk_1B8.x, 0.0f, 1.0f); + + for (i = 0; i < ARRAY_COUNT(ovl_Obj_Entotu_Vtx_000D10); i++) { + this->unk_148[i].v.cn[3] = ovl_Obj_Entotu_Vtx_000D10[i].v.cn[3] * this->unk_1B8.x; + } + + if (this->unk_1B8.x > 0.0f) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.0f, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, sp57, 0x20, 0x20, 1, 0, sp56, 0x20, 0x20)); + gSPSegment(POLY_XLU_DISP++, 0x09, Lib_SegmentedToVirtual(this->unk_148)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_f53_obj_DL_001C00); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void ObjEntotu_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjEntotu* this = THIS; + + Lib_MemCpy(this->unk_148, ovl_Obj_Entotu_Vtx_000D10, sizeof(ovl_Obj_Entotu_Vtx_000D10)); + this->unk_1C6 = Rand_S16Offset(0, 59); + this->unk_1C4 = 0; +} + +void ObjEntotu_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void ObjEntotu_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjEntotu* this = THIS; + + func_80A349C0(this); +} + +void ObjEntotu_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjEntotu* this = THIS; + + func_80A34B28(this, globalCtx); + func_80A34A44(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h b/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h index 5d0b3cedd..a00a7fcd4 100644 --- a/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h +++ b/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.h @@ -7,7 +7,11 @@ struct ObjEntotu; typedef struct ObjEntotu { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x84]; + /* 0x144 */ UNK_TYPE1 unk144[4]; + /* 0x148 */ Vtx unk_148[7]; + /* 0x1B8 */ Vec3f unk_1B8; + /* 0x1C4 */ u8 unk_1C4; + /* 0x1C6 */ s16 unk_1C6; } ObjEntotu; // size = 0x1C8 extern const ActorInit Obj_Entotu_InitVars; 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 f252efbd5..eb91a93d4 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c @@ -5,8 +5,9 @@ */ #include "z_obj_etcetera.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjEtcetera*)thisx) @@ -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); @@ -52,8 +53,6 @@ static ColliderCylinderInit sCylinderInit = { { 20, 14, 0, { 0, 0, 0 } }, }; -extern ColliderCylinderInit D_80A7C790; - static s16 objectIds[] = { GAMEPLAY_KEEP, GAMEPLAY_KEEP, @@ -88,7 +87,7 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx) { pos.x = this->dyna.actor.world.pos.x; pos.y = this->dyna.actor.world.pos.y + 10.0f; pos.z = this->dyna.actor.world.pos.z; - func_800C411C(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &floorBgId, &this->dyna.actor, &pos); + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->dyna.actor.floorPoly, &floorBgId, &this->dyna.actor, &pos); this->dyna.actor.floorBgId = floorBgId; Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); Collider_UpdateCylinder(&this->dyna.actor, &this->collider); @@ -101,10 +100,15 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjEtcetera* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); 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 +123,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,27 +136,28 @@ 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) && - (this->dyna.actor.yDistToPlayer > 0.0f)) { + (this->dyna.actor.playerHeightRel > 0.0f)) { // Player is hovering above the Deku Flower - minOscillationTimer = 10 - (s32)(this->dyna.actor.yDistToPlayer * 0.05f); + minOscillationTimer = 10 - (s32)(this->dyna.actor.playerHeightRel * 0.05f); if (this->oscillationTimer < minOscillationTimer) { this->oscillationTimer = minOscillationTimer; } } else { - if (func_800CAF70(&this->dyna)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { 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,20 +168,20 @@ 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) { - if (func_800CAF70(&this->dyna)) { +void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, GlobalContext* globalCtx) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { this->burrowFlag |= 1; } else { this->burrowFlag &= ~1; @@ -187,14 +193,19 @@ 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 func_800CAF70 takes a DynaPolyActor. + // it's more likely they used dyna given that DynaPolyActor_IsInRidingMovingState takes a DynaPolyActor. DynaPolyActor* dyna = &this->dyna; f32 scaleTemp; - if (func_800CAF70(dyna)) { + if (DynaPolyActor_IsInRidingMovingState(dyna)) { this->burrowFlag |= 1; } else { this->burrowFlag &= ~1; @@ -208,12 +219,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 +232,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; @@ -232,27 +248,27 @@ void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) { if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { this->dyna.actor.objBankIndex = this->objIndex; - Actor_SetObjectSegment(globalCtx, &this->dyna.actor); - BcCheck3_BgActorInit(&this->dyna, 1); + Actor_SetObjectDependency(globalCtx, &this->dyna.actor); + DynaPolyActor_Init(&this->dyna, 1); thisCollisionHeader = collisionHeaders[type]; if (thisCollisionHeader != 0) { - BgCheck_RelocateMeshHeader(thisCollisionHeader, &colHeader); + CollisionHeader_GetVirtual(thisCollisionHeader, &colHeader); } - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); type = DEKU_FLOWER_TYPE(&this->dyna.actor); 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 +286,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; @@ -292,13 +308,18 @@ void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx) { if (floorBgId == BGCHECK_SCENE) { floorPoly = this->dyna.actor.floorPoly; if (floorPoly != NULL && this->burrowFlag & 1) { - func_800FAAB4(globalCtx, func_800C9C9C(&globalCtx->colCtx, floorPoly, floorBgId)); + func_800FAAB4(globalCtx, SurfaceType_GetLightSettingIndex(&globalCtx->colCtx, floorPoly, floorBgId)); } } this->actionFunc(this, 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 +332,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_Fireshield/z_obj_fireshield.c b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c index 04ff86bf9..705dc93bf 100644 --- a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c +++ b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.c @@ -1,6 +1,13 @@ -#include "z_obj_fireshield.h" +/* + * File: z_obj_fireshield.c + * Overlay: ovl_Obj_Fireshield + * Description: Ring of fire + */ -#define FLAGS 0x00000010 +#include "z_obj_fireshield.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjFireshield*)thisx) @@ -9,12 +16,12 @@ void ObjFireshield_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjFireshield_Update(Actor* thisx, GlobalContext* globalCtx); void ObjFireshield_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80A4CABC(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CB7C(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CCBC(ObjFireshield* this, GlobalContext* globalCtx); -void func_80A4CD28(ObjFireshield* this, GlobalContext* globalCtx); +void func_80A4CABC(ObjFireshield* this); +void func_80A4CB7C(ObjFireshield* this); +void func_80A4CC54(ObjFireshield* this); +void func_80A4CCBC(ObjFireshield* this); +void func_80A4CD28(ObjFireshield* this); -#if 0 const ActorInit Obj_Fireshield_InitVars = { ACTOR_OBJ_FIRESHIELD, ACTORCAT_PROP, @@ -27,49 +34,365 @@ const ActorInit Obj_Fireshield_InitVars = { (ActorFunc)ObjFireshield_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A4D820 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x01, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x01, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_ON, + }, { 28, 144, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A4D8A4[] = { +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; +} ObjFireshieldStruct; // size = 0x8 + +ObjFireshieldStruct D_80A4D84C[] = { + { 1.0f, 200.0f }, + { 2.0f, 400.0f }, + { 3.0f, 700.0f }, +}; + +s32 D_80A4D864[] = { 0, 0, 0, 0 }; +s32 D_80A4D874[] = { 0, 0, 0, 0 }; +s32 D_80A4D884[] = { 0, 0, 0, 0 }; +s32 D_80A4D894[] = { 0, 0, 0, 0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void func_80A4CA90(ObjFireshield* this) { + if (this->actor.cutscene >= 0) { + this->actionFunc = func_80A4CABC; + } else { + this->actionFunc = func_80A4CC54; + } +} -extern ColliderCylinderInit D_80A4D820; -extern InitChainEntry D_80A4D8A4[]; +void func_80A4CABC(ObjFireshield* this) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CA90.s") + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + s32 sp18 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_a0 = (sp18 & ~0x1F) >> 5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CABC.s") + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + this->actionFunc = func_80A4CB7C; + this->unk_194 = 20; + D_80A4D884[temp_a0] |= 1 << (sp18 & 0x1F); + D_80A4D894[temp_a0] |= 1 << (sp18 & 0x1F); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CB7C.s") +void func_80A4CB7C(ObjFireshield* this) { + s32 pad; + s32 sp18 = OBJFIRESHIELD_GET_7F(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CC54.s") + if (this->unk_194 > 0) { + if (this->unk_194 == 20) { + D_80A4D884[(sp18 & ~0x1F) >> 5] &= ~(1 << (sp18 & 0x1F)); + } + this->unk_194--; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CCBC.s") + ActorCutscene_Stop(this->actor.cutscene); + this->actionFunc = func_80A4CD28; + D_80A4D894[(sp18 & ~0x1F) >> 5] &= ~(1 << (sp18 & 0x1F)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CD28.s") +void func_80A4CC54(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_v1 = 1 << (temp_v0 & 0x1F); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CD34.s") + this->actionFunc = func_80A4CCBC; + D_80A4D884[(temp_v0 & ~0x1F) >> 5] |= temp_v1; + D_80A4D894[(temp_v0 & ~0x1F) >> 5] |= temp_v1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4CE28.s") +void func_80A4CCBC(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4D174.s") + this->actionFunc = func_80A4CD28; + D_80A4D884[(temp_v0 & ~0x1F) >> 5] &= ~(1 << (temp_v0 & 0x1F)); + D_80A4D894[(temp_v0 & ~0x1F) >> 5] &= ~(1 << (temp_v0 & 0x1F)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/func_80A4D1CC.s") +void func_80A4CD28(ObjFireshield* this) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Init.s") +void func_80A4CD34(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjFireshield* this = THIS; + s32 sp24 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_7F(&this->actor)); + s32 phi_v1; + s32 phi_a0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Destroy.s") + if (this->unk_1A8 == 0) { + if (OBJFIRESHIELD_GET_2000(&this->actor)) { + phi_v1 = false; + phi_a0 = false; + } else { + phi_v1 = Flags_GetTreasure(globalCtx, OBJFIRESHIELD_GET_1F00(&this->actor)); + phi_a0 = false; + } + } else { + phi_a0 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_3F80(&this->actor)); + phi_v1 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Update.s") + if (phi_v1 || phi_a0) { + this->unk_19C = 0; + } else if (sp24) { + this->unk_19C = 0; + } else { + this->unk_19C = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Fireshield/ObjFireshield_Draw.s") + if (this->unk_19C == 0) { + this->unk_198 = 0.0f; + } else { + this->unk_198 = 1.0f; + } +} + +void func_80A4CE28(ObjFireshield* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 pad2[2]; + s32 sp24; + s32 sp20; + + if (this->unk_1A8 == 0) { + if (OBJFIRESHIELD_GET_2000(&this->actor)) { + sp24 = false; + sp20 = false; + } else { + sp24 = Flags_GetTreasure(globalCtx, OBJFIRESHIELD_GET_1F00(&this->actor)); + sp20 = false; + } + } else { + sp20 = Flags_GetSwitch(globalCtx, OBJFIRESHIELD_GET_3F80(&this->actor)); + sp24 = false; + } + + if (!sp24 || !sp20 || (this->unk_19C != 0)) { + s32 sp1C = Flags_GetSwitch(globalCtx, sp30); + s32 temp_v0 = (sp30 & ~0x1F) >> 5; + + if (this->unk_19C == 2) { + if (Math_StepToF(&this->unk_198, 1.0f, 0.03f)) { + this->unk_19C = 1; + if (((this->actor.home.rot.z * 10) > 0) && (this->unk_1A7 != 0)) { + Flags_UnsetSwitch(globalCtx, sp30); + sp1C = false; + } + } + } else if (this->unk_19C == 3) { + if (Math_StepToF(&this->unk_198, 0.0f, 0.03f)) { + this->unk_19C = 0; + } + } + + if ((this->unk_1A0 > 0) && (this->unk_19C == 1) && ((this->actor.home.rot.z * 10) > 0) && + !(D_80A4D894[temp_v0] & (1 << (sp30 & 0x1F)))) { + this->unk_1A0 = 0; + } + + if ((this->unk_19C == 0) || (this->unk_19C == 3)) { + if (!sp24 && !sp20) { + if ((this->actor.home.rot.z * 10) > 0) { + if (this->unk_1A0 > 1) { + this->unk_1A0--; + } + + if (this->unk_1A0 == 1) { + this->unk_19C = 2; + } + } + + if (!sp1C) { + this->unk_19C = 2; + } + } + } else if (sp24 || sp20) { + this->unk_19C = 3; + } else if (sp1C && ((this->unk_19C == 1) || (this->unk_19C == 2))) { + if ((D_80A4D884[temp_v0] & 1 << (sp30 & 0x1F)) && !(D_80A4D874[temp_v0] & 1 << (sp30 & 0x1F))) { + this->unk_19C = 3; + } else if (((this->actor.home.rot.z * 10) == 0) || (this->unk_1A0 == 0)) { + if ((this->actor.home.rot.z * 10) > 0) { + this->unk_1A0 = this->actor.home.rot.z * 10; + } + + if (this->unk_1A7 != 0) { + func_80A4CA90(this); + } + } + } + } +} + +void func_80A4D174(ObjFireshield* this) { + s32 temp_v0 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_v1 = 1 << (temp_v0 & 0x1F); + + if (!(D_80A4D864[(temp_v0 & ~0x1F) >> 5] & temp_v1)) { + this->unk_1A7 = 1; + D_80A4D864[(temp_v0 & ~0x1F) >> 5] |= temp_v1; + } +} + +void func_80A4D1CC(void) { + D_80A4D864[0] = 0; + D_80A4D864[1] = 0; + D_80A4D864[2] = 0; + D_80A4D864[3] = 0; +} + +void ObjFireshield_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + s32 temp = 0x8000; + ObjFireshieldStruct* sp2C = &D_80A4D84C[OBJFIRESHIELD_GET_C000(&this->actor)]; + s32 sp28 = OBJFIRESHIELD_GET_ROTX(&this->actor); + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (sp28) { + this->actor.shape.rot.z = temp; + } else { + this->actor.shape.rot.z = 0; + } + + this->actor.world.rot.z = 0; + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = 0; + + this->actor.scale.x = sp2C->unk_00 * 0.0348f; + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = 0.05f; + + this->actor.uncullZoneScale = sp2C->unk_04; + this->unk_1A4 = Rand_ZeroOne() * 128.0f; + + if ((this->actor.home.rot.z * 10) < 0) { + this->unk_1A8 = 1; + this->actor.home.rot.z = -thisx->home.rot.z; + } + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + + this->collider.dim.radius *= sp2C->unk_00; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + func_80A4D174(this); + func_80A4CD34(&this->actor, globalCtx); + this->actionFunc = func_80A4CD28; +} + +void ObjFireshield_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void ObjFireshield_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + ObjFireshield* this2 = THIS; + s32 sp44 = OBJFIRESHIELD_GET_ROTX(&this->actor); + s32 sp40 = OBJFIRESHIELD_GET_7F(&this->actor); + s32 temp_a0; + s32 temp_v1; + + func_80A4D1CC(); + + if (this->unk_1A7 != 0) { + temp_a0 = (sp40 & ~0x1F) >> 5; + temp_v1 = 1 << (sp40 & 0x1F); + if ((D_80A4D884[temp_a0] & temp_v1)) { + D_80A4D874[temp_a0] |= temp_v1; + } else { + D_80A4D874[temp_a0] &= ~temp_v1; + } + } + + this->unk_1A4++; + + this->actionFunc(this); + + if (this->actionFunc == func_80A4CABC) { + this->collider.base.atFlags &= ~AT_HIT; + } else if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + func_800B8D98(globalCtx, &this->actor, 5.0f, this->actor.yawTowardsPlayer, 1.0f); + } + + func_80A4CE28(this, globalCtx); + + this->actor.world.pos.y = ((sp44 ? 144.0f : -144.0f) * (1.0f - this2->unk_198)) + this->actor.home.pos.y; + + this->unk_1A6 = this->unk_198 * 255.0f; + + if (this->unk_198 >= 0.7f) { + Player* player = GET_PLAYER(globalCtx); + + this->collider.dim.height = this->unk_198 * 80.0f; + + if (sp44) { + this->collider.dim.yShift = + (s32)(this->actor.home.pos.y - this->actor.world.pos.y) - this->collider.dim.height; + } else { + this->collider.dim.yShift = this->actor.home.pos.y - this->actor.world.pos.y; + } + + func_800B9010(&this->actor, NA_SE_EV_BURNING - SFX_FLAG); + + if (player->transformation == PLAYER_FORM_GORON) { + this->collider.info.toucher.damage = 0; + this->collider.info.toucher.effect = 0; + } else { + this->collider.info.toucher.damage = 4; + this->collider.info.toucher.effect = 1; + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void ObjFireshield_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjFireshield* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 220, 0, this->unk_1A6); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, this->unk_1A4 & 0x7F, 0, 0x20, 0x40, 1, 0, + (this->unk_1A4 * -15) & 0xFF, 0x20, 0x40)); + 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_02E510); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h index f39039793..4d6a971eb 100644 --- a/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h +++ b/src/overlays/actors/ovl_Obj_Fireshield/z_obj_fireshield.h @@ -5,13 +5,27 @@ struct ObjFireshield; -typedef void (*ObjFireshieldActionFunc)(struct ObjFireshield*, GlobalContext*); +typedef void (*ObjFireshieldActionFunc)(struct ObjFireshield*); + +#define OBJFIRESHIELD_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJFIRESHIELD_GET_1F00(thisx) (((thisx)->params >> 8) & 0x1F) +#define OBJFIRESHIELD_GET_2000(thisx) (((thisx)->params >> 0xD) & 1) +#define OBJFIRESHIELD_GET_3F80(thisx) (((thisx)->params >> 7) & 0x7F) +#define OBJFIRESHIELD_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) +#define OBJFIRESHIELD_GET_ROTX(thisx) ((thisx)->home.rot.x & 1) typedef struct ObjFireshield { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ ObjFireshieldActionFunc actionFunc; - /* 0x0194 */ char unk_194[0x18]; + /* 0x0194 */ s32 unk_194; + /* 0x0198 */ f32 unk_198; + /* 0x019C */ s32 unk_19C; + /* 0x01A0 */ s32 unk_1A0; + /* 0x01A4 */ s16 unk_1A4; + /* 0x01A6 */ u8 unk_1A6; + /* 0x01A7 */ s8 unk_1A7; + /* 0x01A8 */ s8 unk_1A8; } ObjFireshield; // size = 0x1AC extern const ActorInit Obj_Fireshield_InitVars; 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 5e16c553e..57964559d 100644 --- a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c +++ b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_flowerpot.c + * Overlay: ovl_Obj_Flowerpot + * Description: Breakable Pot With Grass + */ + #include "z_obj_flowerpot.h" +#include "objects/object_flowerpot/object_flowerpot.h" #define FLAGS 0x00000000 @@ -9,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, @@ -22,86 +43,652 @@ 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(terminalVelocity, -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_GetCurrent(); + 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) { + SoundSource_PlaySfxAtFixedWorldPos(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) { + SoundSource_PlaySfxAtFixedWorldPos(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_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_MultVec3f(&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 = ActorShadow_DrawCircle; + 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_SetTranslateRotateYXZ(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* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjFlowerpot* this = THIS; + + 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 |= ACTOR_FLAG_10; + if (func_800A817C(ENOBJFLOWERPOT_GET_3F(&this->actor))) { + func_80A1B914(this, globalCtx); + } + + //! @bug: This function should only pass Player*: it uses *(this + 0x153), which is meant to be + //! player->currentMask, but in this case is garbage in the collider + func_800B8E58((Player*)this, 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 & BUMP_HIT) && + (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 & BUMP_HIT) { + if (!(this->unk_1EA & 2)) { + this->unk_1EA |= 2; + this->collider.elements[1].info.bumperFlags &= ~BUMP_ON; + func_80A1C0FC(this, globalCtx); + func_80A1B914(this, globalCtx); + func_80A1B9CC(this, globalCtx); + } + } + + if (this->unk_1EA & 1) { + Actor_MoveWithGravity(&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 &= ~ACTOR_FLAG_10; + 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) { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 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), NA_SE_PL_PUT_DOWN_POT); + this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; + } else { + Actor_MoveWithGravity(&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); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_MoveWithGravity(&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 04f4635a6..7bdaa8654 100644 --- a/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c +++ b/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c @@ -1,6 +1,13 @@ -#include "z_obj_funen.h" +/* + * File: z_obj_funen.c + * Overlay: ovl_Obj_Funen + * Description: Unused(?) Stone Tower smoke + */ -#define FLAGS 0x00000030 +#include "z_obj_funen.h" +#include "objects/object_funen/object_funen.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjFunen*)thisx) @@ -13,8 +20,6 @@ const ActorInit Obj_Funen_InitVars = { (ActorFunc)Actor_Noop, (ActorFunc)Actor_Noop, (ActorFunc)ObjFunen_Draw, }; -extern Gfx D_060000D0[]; - f32 D_80A198D0[] = { 0.1f, 0.024390244f }; void ObjFunen_Init(Actor* thisx, GlobalContext* globalCtx) { @@ -30,7 +35,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_RotateYS((s16)(Camera_GetCamDirYaw(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); @@ -38,6 +43,6 @@ void ObjFunen_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPSegment(POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, temp, 0x20, 0x20, 1, 0, temp, 0x20, 0x20)); - gSPDisplayList(POLY_XLU_DISP++, D_060000D0); + gSPDisplayList(POLY_XLU_DISP++, object_funen_DL_0000D0); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 7a20bab74..bedb0a38f 100644 --- a/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c +++ b/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c @@ -1,12 +1,13 @@ /* - * File z_obj_ghaka.c + * File: z_obj_ghaka.c * Overlay: ovl_Obj_Ghaka * Description: Darmani's Gravestone */ #include "z_obj_ghaka.h" +#include "objects/object_ghaka/object_ghaka.h" -#define FLAGS 0x00000029 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_20) #define THIS ((ObjGhaka*)thisx) @@ -42,12 +43,8 @@ static InitChainEntry D_80B3C96C[] = { ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), }; -extern Gfx D_06001A20[]; -extern Gfx D_06001980[]; -extern CollisionHeader D_06003CD0; - void func_80B3C260(ObjGhaka* this) { - if (gSaveContext.weekEventReg[20] & 0x20) { + if (gSaveContext.save.weekEventReg[20] & 0x20) { this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + 100.0f; } this->actionFunc = func_80B3C39C; @@ -62,7 +59,7 @@ void func_80B3C2B0(ObjGhaka* this) { } void func_80B3C2C4(ObjGhaka* this, GlobalContext* globalCtx) { - if (!(gSaveContext.weekEventReg[20] & 0x20)) { + if (!(gSaveContext.save.weekEventReg[20] & 0x20)) { Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_BG_GORON_OYU, 0.0f, 25.0f, 261.0f, 0, 0, 0, 0, this->dyna.actor.cutscene, this->dyna.actor.unk20, 0); } else { @@ -75,7 +72,7 @@ void func_80B3C39C(ObjGhaka* this, GlobalContext* globalCtx) { Player* player = GET_PLAYER(globalCtx); s16 distDiff = this->dyna.actor.yawTowardsPlayer - this->dyna.actor.shape.rot.y; - if (func_800B84D0(&this->dyna.actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state)) { func_80B3C29C(this); } else if (this->dyna.actor.xzDistToPlayer < 100.0f || this->dyna.actor.isTargeted) { if (distDiff <= -0x5556 || distDiff >= 0x5556) { @@ -87,40 +84,41 @@ void func_80B3C39C(ObjGhaka* this, GlobalContext* globalCtx) { } } } - if (this->dyna.unk148 < 0.0f && !(gSaveContext.weekEventReg[20] & 0x20) && + + if (this->dyna.pushForce < 0.0f && !(gSaveContext.save.weekEventReg[20] & 0x20) && player->transformation == PLAYER_FORM_GORON) { func_80B3C2B0(this); } else { player->stateFlags2 &= ~0x10; - this->dyna.unk148 = 0.0f; + this->dyna.pushForce = 0.0f; } } void func_80B3C4E0(ObjGhaka* this, GlobalContext* globalCtx) { - u8 talkState = func_80152498(&globalCtx->msgCtx); + u8 talkState = Message_GetState(&globalCtx->msgCtx); if (talkState == 5) { - if (func_80147624(globalCtx)) { - globalCtx->msgCtx.unk11F22 = 0x43; + if (Message_ShouldAdvance(globalCtx)) { + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; func_80B3C260(this); } } else if (talkState == 4) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (globalCtx->msgCtx.choiceIndex) { case 0: func_8019F208(); this->dyna.actor.textId = 0xCF5; - func_801518B0(globalCtx, this->dyna.actor.textId, &this->dyna.actor); + Message_StartTextbox(globalCtx, this->dyna.actor.textId, &this->dyna.actor); break; case 1: func_8019F208(); this->dyna.actor.textId = 0xCF7; - func_801518B0(globalCtx, this->dyna.actor.textId, &this->dyna.actor); + Message_StartTextbox(globalCtx, this->dyna.actor.textId, &this->dyna.actor); break; case 2: func_8019F230(); - globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.msgMode = 0x43; globalCtx->msgCtx.unk12023 = 4; func_80B3C260(this); } @@ -136,13 +134,13 @@ void func_80B3C624(ObjGhaka* this, GlobalContext* globalCtx) { if (stepTemp) { player->stateFlags2 &= ~0x10; - this->dyna.unk148 = 0.0f; + this->dyna.pushForce = 0.0f; func_80B3C2C4(this, globalCtx); - gSaveContext.weekEventReg[20] |= 0x20; + gSaveContext.save.weekEventReg[20] |= 0x20; func_80B3C260(this); - func_8019F1C0(&D_80B3C960, NA_SE_EV_BLOCK_BOUND); + Audio_PlaySfxAtPos(&D_80B3C960, NA_SE_EV_BLOCK_BOUND); } else { - func_8019F1C0(&D_80B3C960, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + Audio_PlaySfxAtPos(&D_80B3C960, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); } } @@ -153,14 +151,14 @@ void ObjGhaka_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->dyna.actor, D_80B3C96C); Actor_SetScale(&this->dyna.actor, 0.1f); - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck_RelocateMeshHeader(&D_06003CD0, &colHeader); - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, colHeader); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&object_ghaka_Colheader_003CD0, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 0x4); if (this->dyna.actor.floorPoly == 0) { Actor_MarkForDeath(&this->dyna.actor); } - if (gSaveContext.weekEventReg[20] & 0x20) { + if (gSaveContext.save.weekEventReg[20] & 0x20) { func_80B3C2C4(this, globalCtx); } func_80B3C260(this); @@ -169,7 +167,7 @@ void ObjGhaka_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjGhaka_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjGhaka* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjGhaka_Update(Actor* thisx, GlobalContext* globalCtx) { @@ -185,9 +183,9 @@ void ObjGhaka_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++, D_06001A20); + gSPDisplayList(POLY_OPA_DISP++, object_ghaka_DL_001A20); 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++, D_06001980); + gSPDisplayList(POLY_XLU_DISP++, object_ghaka_DL_001980); CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 23a09d80f..51f2febc7 100644 --- a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c +++ b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c @@ -1,6 +1,14 @@ -#include "z_obj_grass.h" +/* + * File: z_obj_grass.c + * Overlay: ovl_Obj_Grass + * Description: "Master" instance of grass for unit spawned by Obj_Grass_Unit + */ -#define FLAGS 0x00000030 +#include "z_obj_grass.h" +#include "overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjGrass*)thisx) @@ -9,7 +17,13 @@ void ObjGrass_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjGrass_Update(Actor* thisx, GlobalContext* globalCtx); void ObjGrass_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +ObjGrassStruct1* D_809AADA0[4]; +f32 D_809AADB0[4]; +ObjGrassStruct1_1* D_809AADC0[20]; +f32 D_809AAE10[20]; + +#include "overlays/ovl_Obj_Grass/ovl_Obj_Grass.c" + const ActorInit Obj_Grass_InitVars = { ACTOR_OBJ_GRASS, ACTORCAT_PROP, @@ -22,41 +36,486 @@ const ActorInit Obj_Grass_InitVars = { (ActorFunc)ObjGrass_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809AAB20 = { - { 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 } }, }; -#endif +Vec3f D_809AAB4C[] = { + { 0.0f, 0.707099974155f, 0.707099974155f }, + { 0.707099974155f, 0.707099974155f, 0.0f }, + { 0.0f, 0.707099974155f, -0.707099974155f }, + { -0.707099974155f, 0.707099974155f, 0.0f }, +}; -extern ColliderCylinderInit D_809AAB20; +s16 D_809AAB7C[] = { 0x6C, 0x66, 0x60, 0x54, 0x42, 0x37, 0x2A, 0x26 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A9110.s") +s32 func_809A9110(GlobalContext* globalCtx, Vec3f* arg1) { + f32 sp2C; + Vec3f sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A91FC.s") + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, arg1, &sp20, &sp2C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A92D0.s") + if ((globalCtx->unk_187F0.z * -130.13191f) < sp20.z) { + if (sp2C < 1.0f) { + sp2C = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A9314.s") + if (((fabsf(sp20.x) - (130.13191f * globalCtx->unk_187F0.x)) < sp2C) && + ((fabsf(sp20.y) - (130.13191f * globalCtx->unk_187F0.y)) < sp2C)) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/ObjGrass_Init.s") +void func_809A91FC(MtxF* matrix) { + s32 i; + MtxF* temp = Matrix_GetCurrent(); + f32* tmp = &temp->xx; + f32* tmp2 = &matrix->xx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/ObjGrass_Destroy.s") + for (i = 0; i < 16; i++) { + *tmp++ += *tmp2++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A9790.s") +void func_809A92D0(ObjGrassStruct1_1* ptr, GlobalContext* globalCtx) { + if (!(ptr->unk_0E & 0x10)) { + Item_DropCollectibleRandom(globalCtx, NULL, &ptr->unk_00, ptr->unk_0E * 0x10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A983C.s") +void func_809A9314(ObjGrassStruct1_1* ptr, GlobalContext* globalCtx) { + Vec3f spBC; + Vec3f spB0; + s32 i; + Vec3f* ptr2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809A9DB8.s") + for (i = 0; i < ARRAY_COUNT(D_809AAB4C); i++) { + ptr2 = &D_809AAB4C[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/ObjGrass_Update.s") + spB0.x = ptr->unk_00.x + (ptr2->x * 8.0f); + spB0.y = (ptr->unk_00.y + (ptr2->y * 8.0f)) + 10.0f; + spB0.z = ptr->unk_00.z + (ptr2->z * 8.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809AA278.s") + spBC.x = (Rand_ZeroOne() - 0.5f) * 8.0f; + spBC.y = Rand_ZeroOne() * 10.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) * 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809AA54C.s") + EffectSsKakera_Spawn(globalCtx, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0, + D_809AAB7C[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, 1, gKakeraLeafMiddle); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/func_809AA798.s") + spB0.x = ptr->unk_00.x + (ptr2->x * 16.0f); + spB0.y = (ptr->unk_00.y + (ptr2->y * 16.0f)) + 10.0f; + spB0.z = ptr->unk_00.z + (ptr2->z * 16.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass/ObjGrass_Draw.s") + spBC.x = (Rand_ZeroOne() - 0.5f) * 6.0f; + spBC.y = Rand_ZeroOne() * 10.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) * 6.0f; + + EffectSsKakera_Spawn(globalCtx, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0, + D_809AAB7C[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, 1, gKakeraLeafTip); + } +} + +void ObjGrass_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjGrass* this = THIS; + s32 i; + + Actor_SetScale(&this->actor, 0.4f); + + for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) { + Collider_InitCylinder(globalCtx, &this->unk_2948[i].collider); + Collider_SetCylinder(globalCtx, &this->unk_2948[i].collider, &this->actor, &sCylinderInit); + } + + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_3288 = (u32)Rand_Next() >> 0x10; + this->unk_328A = (u32)Rand_Next() >> 0x10; + this->unk_328C = (u32)Rand_Next() >> 0x10; + this->unk_328E = (u32)Rand_Next() >> 0x10; + this->unk_3290 = (u32)Rand_Next() >> 0x10; +} + +void ObjGrass_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjGrass* this = THIS; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) { + Collider_DestroyCylinder(globalCtx, &this->unk_2948[i].collider); + } + + for (i = 0; i < ARRAY_COUNT(this->unk_3298); i++) { + ObjGrassCarry** ptr = &this->unk_3298[i]; + + if (*ptr != NULL) { + (*ptr)->unk_190 = 0; + *ptr = NULL; + } + } +} + +void func_809A9790(ObjGrass* this, GlobalContext* globalCtx) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) { + ObjGrassStruct1_1* ptr = this->unk_2948[i].unk_4C; + + if ((ptr != NULL) && (this->unk_2948[i].collider.base.acFlags & AC_HIT)) { + func_809A9314(ptr, globalCtx); + func_809A92D0(ptr, globalCtx); + ptr->unk_0F |= 4; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &ptr->unk_00, 20, NA_SE_EV_PLANT_BROKEN); + } + } +} + +void func_809A983C(ObjGrass* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 i; + s32 j; + s32 x; + s32 y; + f32 temp_f0; + ObjGrassStruct1* ptr; + ObjGrassStruct1_1* ptr2; + ObjGrassStruct2* ptr3; + s16 yaw; + + for (i = 0; i < ARRAY_COUNT(D_809AADC0); i++) { + D_809AADC0[i] = NULL; + D_809AAE10[i] = 422500.0f; + } + + for (i = 0; i < ARRAY_COUNT(D_809AADA0); i++) { + D_809AADA0[i] = NULL; + D_809AADB0[i] = 422500.0f; + } + + for (i = 0; i < this->unk_2944; i++) { + ptr = &this->unk_144[i]; + + for (j = 0; j < ptr->unk_FC; j++) { + ptr->unk_0C[j].unk_0F &= (u16)~2; + } + } + + for (i = 0; i < this->unk_2944; i++) { + ptr = &this->unk_144[i]; + temp_f0 = Math3D_Vec3fDistSq(&ptr->unk_00, &player->actor.world.pos); + + for (j = 0; j < ARRAY_COUNT(D_809AADB0); j++) { + if (temp_f0 < D_809AADB0[j]) { + break; + } + } + + if (j < ARRAY_COUNT(D_809AADB0)) { + for (x = 2; x >= j; x--) { + D_809AADB0[x + 1] = D_809AADB0[x]; + D_809AADA0[x + 1] = D_809AADA0[x]; + } + + D_809AADB0[j] = temp_f0; + D_809AADA0[j] = ptr; + } + } + + this->unk_3294 = NULL; + + for (i = 0; i < ARRAY_COUNT(D_809AADA0); i++) { + ptr = D_809AADA0[i]; + + if (ptr != NULL) { + for (j = 0; j < ptr->unk_FC; j++) { + if (!(ptr->unk_0C[j].unk_0F & 4)) { + temp_f0 = Math3D_Vec3fDistSq(&ptr->unk_0C[j].unk_00, &player->actor.world.pos); + + for (x = 0; x < ARRAY_COUNT(D_809AAE10); x++) { + if (temp_f0 < D_809AAE10[x]) { + break; + } + } + + if (x < ARRAY_COUNT(D_809AAE10)) { + for (y = 18; y >= x; y--) { + D_809AAE10[y + 1] = D_809AAE10[y]; + D_809AADC0[y + 1] = D_809AADC0[y]; + } + + D_809AAE10[x] = temp_f0; + D_809AADC0[x] = &ptr->unk_0C[j]; + + if (temp_f0 < 2500.0f) { + yaw = player->actor.shape.rot.y - + Math_Vec3f_Yaw(&player->actor.world.pos, &ptr->unk_0C[j].unk_00); + + if (ABS_ALT(yaw) < 0x2000) { + this->unk_3294 = &ptr->unk_0C[j]; + } + } + } + } + } + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_2948); i++) { + ptr3 = &this->unk_2948[i]; + + ptr3->collider.base.acFlags &= (u16)~AC_HIT; + ptr3->collider.base.ocFlags1 &= (u16)~OC1_HIT; + + ptr2 = D_809AADC0[i]; + if (ptr2 != NULL) { + ptr3->collider.dim.pos.x = ptr2->unk_00.x; + ptr3->collider.dim.pos.y = ptr2->unk_00.y; + ptr3->collider.dim.pos.z = ptr2->unk_00.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &ptr3->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &ptr3->collider.base); + ptr2->unk_0F |= 2; + ptr3->unk_4C = ptr2; + } else { + ptr3->unk_4C = NULL; + } + } +} + +void func_809A9DB8(ObjGrass* this) { + s32 i; + s32 pad; + f32* ptr; + f32 temp_f28; + f32 spA4; + f32 spA0; + f32 temp_f22; + f32 temp_f24; + f32 sp94; + f32 sp90; + f32 temp_f26; + f32 sp6C[8]; + f32 tempf1; + f32 tempf2; + f32 tempf3; + f32 tempf4; + f32 tempf5; + f32 temp_f16; + f32 temp_f20; + + this->unk_3288 += 70; + this->unk_328A += 300; + this->unk_328C += 700; + this->unk_328E += 1300; + this->unk_3290 += 8900; + + temp_f24 = Math_SinS(this->unk_3288); + temp_f28 = Math_SinS(this->unk_328A); + temp_f26 = Math_SinS(this->unk_328C); + spA4 = Math_SinS(this->unk_328E) * 1.2f; + spA0 = Math_SinS(this->unk_3290) * 1.5f; + temp_f22 = Math_CosS(this->unk_3288); + temp_f20 = Math_CosS(this->unk_328A); + sp94 = Math_CosS(this->unk_328C); + sp90 = Math_CosS(this->unk_328E) * 1.3f; + temp_f16 = Math_CosS(this->unk_3290) * 1.7f; + + sp6C[0] = (temp_f24 - temp_f20) * temp_f26 * temp_f22 * temp_f24 * 0.0015f; + sp6C[1] = (temp_f28 - sp94) * spA4 * temp_f20 * temp_f24 * 0.0015f; + sp6C[2] = (temp_f26 - sp90) * sp94 * temp_f24 * temp_f22 * 0.0015f; + sp6C[3] = (spA4 - temp_f20) * sp90 * temp_f28 * temp_f22 * 0.0015f; + sp6C[4] = (temp_f24 - sp94) * temp_f24 * temp_f28 * spA0 * 0.0015f; + sp6C[5] = (temp_f28 - sp90) * temp_f26 * spA4 * spA0 * 0.0015f; + sp6C[6] = (temp_f26 - temp_f22) * temp_f22 * temp_f20 * temp_f16 * 0.0015f; + sp6C[7] = (spA4 - temp_f20) * sp94 * sp90 * temp_f16 * 0.0015f; + + for (i = 0; i < ARRAY_COUNT(this->unk_2F88); i++) { + ptr = &this->unk_2F88[i].mf[0][0]; + + tempf1 = sp6C[(i + 0) & 7]; + tempf2 = sp6C[(i + 1) & 7]; + tempf3 = sp6C[(i + 2) & 7]; + tempf4 = sp6C[(i + 3) & 7]; + tempf5 = sp6C[(i + 4) & 7]; + + ptr[0] = sp6C[1] * 0.2f; + ptr[1] = tempf1; + ptr[2] = tempf2; + ptr[3] = 0.0f; + + ptr[4] = tempf3; + ptr[5] = sp6C[0]; + ptr[6] = tempf3; + ptr[7] = 0.0f; + + ptr[8] = tempf4; + ptr[9] = tempf5; + ptr[10] = sp6C[3] * 0.2f; + ptr[11] = 0.0f; + + ptr[12] = 0.0f; + ptr[13] = 0.0f; + ptr[14] = 0.0f; + ptr[15] = 0.0f; + } +} + +void ObjGrass_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjGrass* this = THIS; + + func_809A9790(this, globalCtx); + func_809A983C(this, globalCtx); + func_809A9DB8(this); +} + +void func_809AA278(ObjGrass* this, GlobalContext* globalCtx) { + ObjGrassStruct1* ptr; + ObjGrassStruct1_1* ptr2; + s32 i; + s32 j; + f32 distSq; + f32 temp_f22; + + for (i = 0; i < this->unk_2944; i++) { + ptr = &this->unk_144[i]; + + temp_f22 = Math3D_Vec3fDistSq(&ptr->unk_00, &GET_ACTIVE_CAM(globalCtx)->eye); + + if ((temp_f22 < SQ(1280.0f)) && func_809A9110(globalCtx, &ptr->unk_00)) { + ptr->unk_FE |= 1; + + for (j = 0; j < ptr->unk_FC; j++) { + ptr2 = &ptr->unk_0C[j]; + + if (ptr2->unk_0F & 4) { + ptr2->unk_10 = 255; + ptr2->unk_0F &= ~1; + } else { + ptr2->unk_0F |= 1; + if (temp_f22 < SQ(980.0f)) { + ptr2->unk_10 = 255; + } else { + distSq = Math3D_Vec3fDistSq(&ptr2->unk_00, &GET_ACTIVE_CAM(globalCtx)->eye); + if ((distSq <= SQ(1080.0f)) || ((ptr2->unk_0F & 8) && (distSq < SQ(1180.0f)))) { + ptr2->unk_10 = 255; + } else if (distSq >= SQ(1180.0f)) { + ptr2->unk_10 = 0; + } else { + ptr2->unk_10 = (1180.0f - sqrtf(distSq)) * 2.55f; + } + } + } + } + } else { + ptr->unk_FE &= ~1; + } + } +} + +void func_809AA54C(Actor* thisx, GlobalContext* globalCtx2) { + ObjGrass* this = THIS; + GlobalContext* globalCtx = globalCtx2; + Lights* temp_s0; + ObjGrassStruct1* ptr; + s32 i; + s32 j; + Vec3s sp70 = { 0, 0, 0 }; + ObjGrassStruct1_1* ptr2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AA9F0); + + for (i = 0; i < this->unk_2944; i++) { + ptr = &this->unk_144[i]; + + if (ptr->unk_FE & 1) { + temp_s0 = LightContext_NewLights(&globalCtx->lightCtx, globalCtx->state.gfxCtx); + Lights_BindAll(temp_s0, globalCtx->lightCtx.listHead, &ptr->unk_00, globalCtx); + Lights_Draw(temp_s0, globalCtx->state.gfxCtx); + + for (j = 0; j < ptr->unk_FC; j++) { + ptr2 = &ptr->unk_0C[j]; + + if ((ptr2->unk_0F & 1) && (ptr2->unk_10 == 255)) { + sp70.y = ptr2->unk_0C; + Matrix_SetTranslateRotateYXZ(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, &sp70); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + if (ptr2->unk_0F & 2) { + func_809A91FC(&this->unk_2F88[j]); + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gObjGrass_D_809AAAE0); + } + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_809AA798(Actor* thisx, GlobalContext* globalCtx) { + ObjGrass* this = THIS; + ObjGrassStruct1* ptr; + ObjGrassStruct1_1* ptr2; + s32 i; + s32 j; + Vec3s sp6C = { 0, 0, 0 }; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAA68); + + for (i = 0; i < this->unk_2944; i++) { + ptr = &this->unk_144[i]; + + if (ptr->unk_FE & 1) { + for (j = 0; j < ptr->unk_FC; j++) { + ptr2 = &ptr->unk_0C[j]; + + if ((ptr2->unk_0F & 1) && (ptr2->unk_10 > 0) && (ptr2->unk_10 < 255)) { + sp6C.y = ptr2->unk_0C; + Matrix_SetTranslateRotateYXZ(ptr2->unk_00.x, ptr2->unk_00.y, ptr2->unk_00.z, &sp6C); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 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, ptr2->unk_10); + gSPDisplayList(POLY_XLU_DISP++, gObjGrass_D_809AAAE0); + } + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjGrass_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjGrass* this = THIS; + + func_809AA278(this, globalCtx); + func_809AA54C(thisx, globalCtx); + func_809AA798(thisx, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.h b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.h index e05e1618e..1c87108df 100644 --- a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.h +++ b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.h @@ -2,12 +2,46 @@ #define Z_OBJ_GRASS_H #include "global.h" +#include "overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h" struct ObjGrass; +struct ObjGrassCarry; + +typedef struct ObjGrassStruct1_1 { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ s8 unk_0E; + /* 0x0F */ u8 unk_0F; + /* 0x10 */ u8 unk_10; + /* 0x11 */ UNK_TYPE1 unk_11[0x3]; +} ObjGrassStruct1_1; // size = 0x14 + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ ObjGrassStruct1_1 unk_0C[12]; + /* 0xFC */ s16 unk_FC; + /* 0xFE */ u8 unk_FE; +} ObjGrassStruct1; // size = 0x100 + +typedef struct { + /* 0x00 */ ColliderCylinder collider; + /* 0x4C */ ObjGrassStruct1_1* unk_4C; +} ObjGrassStruct2; // size = 0x50 typedef struct ObjGrass { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_0144[0x315C]; + /* 0x0144 */ ObjGrassStruct1 unk_144[40]; + /* 0x2944 */ s16 unk_2944; + /* 0x2948 */ ObjGrassStruct2 unk_2948[20]; + /* 0x2F88 */ MtxF unk_2F88[12]; + /* 0x3288 */ s16 unk_3288; + /* 0x328A */ s16 unk_328A; + /* 0x328C */ s16 unk_328C; + /* 0x328E */ s16 unk_328E; + /* 0x3290 */ s16 unk_3290; + /* 0x3292 */ s16 unk_3292; + /* 0x3294 */ ObjGrassStruct1_1* unk_3294; + /* 0x3298 */ struct ObjGrassCarry* unk_3298[2]; } ObjGrass; // size = 0x32A0 extern const ActorInit Obj_Grass_InitVars; 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 1a3cbfeb4..2e9df3323 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,6 +1,15 @@ -#include "z_obj_grass_carry.h" +/* + * File: z_obj_grass_carry.c + * Overlay: ovl_Obj_Grass_Carry + * Description: Grass that the player is holding (spawned by Obj_Grass_Unit) + */ -#define FLAGS 0x00800030 +#include "z_obj_grass_carry.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "overlays/actors/ovl_Obj_Grass/z_obj_grass.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_800000) #define THIS ((ObjGrassCarry*)thisx) @@ -8,7 +17,18 @@ void ObjGrassCarry_Init(Actor* thisx, GlobalContext* globalCtx); void ObjGrassCarry_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjGrassCarry_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809AB3C4(ObjGrassCarry* this); +void func_809AB3D8(ObjGrassCarry* this, GlobalContext* globalCtx); +void func_809AB428(ObjGrassCarry* this); +void func_809AB43C(ObjGrassCarry* this, GlobalContext* globalCtx); +void func_809AB474(ObjGrassCarry* this); +void func_809AB4A8(ObjGrassCarry* this, GlobalContext* globalCtx); +void func_809AB5FC(ObjGrassCarry* this); +void func_809AB610(ObjGrassCarry* this, GlobalContext* globalCtx); +void func_809AB6FC(ObjGrassCarry* this); +void func_809AB77C(ObjGrassCarry* this, GlobalContext* globalCtx); +void func_809ABB7C(Actor* this, GlobalContext* globalCtx); + const ActorInit Obj_Grass_Carry_InitVars = { ACTOR_OBJ_GRASS_CARRY, ACTORCAT_PROP, @@ -21,61 +41,320 @@ const ActorInit Obj_Grass_Carry_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809ABBD0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_NONE, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_NONE, + OCELEM_ON, + }, { 10, 44, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809ABC4C[] = { +s16 D_809ABBFC = 0; +s16 D_809ABC00 = 0; +s16 D_809ABC04 = 0; +s16 D_809ABC08 = 0; + +Vec3f D_809ABC0C[] = { + { 0.0f, 0.7071f, 0.7071f }, + { 0.7071f, 0.7071f, 0.0f }, + { 0.0f, 0.7071f, -0.7071f }, + { -0.7071f, 0.7071f, 0.0f }, +}; + +s16 D_809ABC3C[] = { 0x6C, 0x66, 0x60, 0x54, 0x42, 0x37, 0x2A, 0x26 }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32_DIV1000(gravity, -3200, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -17000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_STOP), }; -#endif +void func_809AAE60(ObjGrassCarry* this) { + this->actor.velocity.y += this->actor.gravity; + if (this->actor.velocity.y < this->actor.terminalVelocity) { + this->actor.velocity.y = this->actor.terminalVelocity; + } +} -extern ColliderCylinderInit D_809ABBD0; -extern InitChainEntry D_809ABC4C[]; +void func_809AAE94(Vec3f* arg0, f32 arg1) { + arg1 += ((Rand_ZeroOne() * 0.2f) - 0.1f) * arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAE60.s") + arg0->x -= (arg0->x * arg1); + arg0->y -= (arg0->y * arg1); + arg0->z -= (arg0->z * arg1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAE94.s") +void func_809AAF18(ObjGrassCarry* this) { + func_809AAE60(this); + func_809AAE94(&this->actor.velocity, 0.05f); + Actor_UpdatePos(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAF18.s") +void func_809AAF58(ObjGrassCarry* this, GlobalContext* globalCtx) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAF58.s") +void func_809AAF9C(Vec3f* arg0, s16 arg1, GlobalContext* globalCtx) { + if (!(arg1 & 0x10)) { + Item_DropCollectibleRandom(globalCtx, NULL, arg0, arg1 * 0x10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAF9C.s") +void func_809AAFE8(Vec3f* arg0, GlobalContext* globalCtx) { + Vec3f spBC; + Vec3f spB0; + s32 i; + Vec3f* ptr; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AAFE8.s") + for (i = 0; i < ARRAY_COUNT(D_809ABC0C); i++) { + ptr = &D_809ABC0C[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/ObjGrassCarry_Init.s") + spB0.x = arg0->x + (ptr->x * 8.0f); + spB0.y = arg0->y + (ptr->y * 8.0f) + 10.0f; + spB0.z = arg0->z + (ptr->z * 8.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/ObjGrassCarry_Destroy.s") + spBC.x = (Rand_ZeroOne() - 0.5f) * 8.0f; + spBC.y = Rand_ZeroOne() * 10.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) * 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB3C4.s") + EffectSsKakera_Spawn(globalCtx, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0, + D_809ABC3C[(s32)(Rand_ZeroOne() * 111.1f) & 7], 0, 0, 80, -1, 1, gKakeraLeafMiddle); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB3D8.s") + spB0.x = arg0->x + (ptr->x * 16.0f); + spB0.y = arg0->y + (ptr->y * 16.0f) + 10.0f; + spB0.z = arg0->z + (ptr->z * 16.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB428.s") + spBC.x = (Rand_ZeroOne() - 0.5f) * 6.0f; + spBC.y = Rand_ZeroOne() * 10.0f; + spBC.z = (Rand_ZeroOne() - 0.5f) * 6.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB43C.s") + EffectSsKakera_Spawn(globalCtx, &spB0, &spBC, &spB0, -100, 64, 40, 3, 0, + D_809ABC3C[(s32)(Rand_ZeroOne() * 111.1f) % 7], 0, 0, 80, -1, 1, gKakeraLeafTip); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB474.s") +void ObjGrassCarry_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjGrassCarry* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB4A8.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = 80; + func_809AB3C4(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB5FC.s") +void ObjGrassCarry_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjGrassCarry* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB610.s") + Collider_DestroyCylinder(globalCtx, &this->collider); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB6FC.s") + if (this->unk_190 != NULL) { + ObjGrassCarry** carry = &this->unk_190->unk_3298[this->actor.params]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809AB77C.s") + if (this == *carry) { + *carry = NULL; + this->unk_190 = NULL; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/ObjGrassCarry_Update.s") +void func_809AB3C4(ObjGrassCarry* this) { + this->actionFunc = func_809AB3D8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Grass_Carry/func_809ABB7C.s") +void func_809AB3D8(ObjGrassCarry* this, GlobalContext* globalCtx) { + if (this->unk_190 != NULL) { + if (this->actor.params != this->unk_190->unk_3292) { + func_809AB474(this); + } else { + func_809AB428(this); + } + } +} + +void func_809AB428(ObjGrassCarry* this) { + this->actionFunc = func_809AB43C; +} + +void func_809AB43C(ObjGrassCarry* this, GlobalContext* globalCtx) { + if (this->actor.params != this->unk_190->unk_3292) { + func_809AB474(this); + } +} + +void func_809AB474(ObjGrassCarry* this) { + this->actor.shape.rot.z = 0; + this->actionFunc = func_809AB4A8; + this->unk_194 = NULL; + this->actor.shape.rot.y = this->actor.shape.rot.z; + this->actor.shape.rot.x = this->actor.shape.rot.z; + this->actor.world.rot.z = this->actor.shape.rot.z; + this->actor.world.rot.y = this->actor.shape.rot.z; + this->actor.world.rot.x = this->actor.shape.rot.z; +} + +void func_809AB4A8(ObjGrassCarry* this, GlobalContext* globalCtx) { + ObjGrassCarry* this2 = this; + + if (Actor_HasParent(&this->actor, globalCtx)) { + func_809AB5FC(this); + if (this->unk_194 != NULL) { + this->unk_194->unk_0F |= 4; + } + this->actor.draw = func_809ABB7C; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + this->actor.shape.shadowAlpha = 60; + this->actor.shape.shadowScale = 1.0f; + this->unk_190->unk_3292 ^= 1; + this->actor.room = -1; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT); + } else if (this->unk_190->unk_3294 != NULL) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_194 = this->unk_190->unk_3294; + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_194->unk_00); + this->actor.shape.rot.y = this->actor.world.rot.y = this->unk_194->unk_0C; + this->unk_198 = this2->unk_194->unk_0E; + this->actor.xzDistToPlayer = Actor_XZDistanceBetweenActors(&this->actor, &player->actor); + this->actor.playerHeightRel = Actor_HeightDiff(&this->actor, &player->actor); + this->actor.xyzDistToPlayerSq = SQ(this->actor.xzDistToPlayer) + SQ(this->actor.playerHeightRel); + this->actor.yawTowardsPlayer = Actor_YawBetweenActors(&this->actor, &player->actor); + Actor_LiftActor(&this->actor, globalCtx); + } +} + +void func_809AB5FC(ObjGrassCarry* this) { + this->actionFunc = func_809AB610; +} + +void func_809AB610(ObjGrassCarry* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; + + if (Actor_HasNoParent(&this->actor, globalCtx)) { + func_809AB6FC(this); + 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; + this->actor.gravity = -0.1f; + this->actor.terminalVelocity = -17.0f; + func_809AAF18(this); + func_809AAF58(this, globalCtx); + this->actor.gravity = -3.2f; + } 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_809AB6FC(ObjGrassCarry* this) { + this->actionFunc = func_809AB77C; + D_809ABBFC = -0xBB8; + D_809ABC04 = (Rand_ZeroOne() - 0.5f) * 1600.0f; + D_809ABC00 = 0; + D_809ABC08 = 0; + this->unk_19A = 60; +} + +void func_809AB77C(ObjGrassCarry* this, GlobalContext* globalCtx) { + s16 phi_s0; + s32 temp_v0 = (this->collider.base.atFlags & AT_HIT) != 0; + Vec3f sp5C; + s32 i; + + if (temp_v0) { + this->collider.base.atFlags &= ~AT_HIT; + } + + this->unk_19A--; + + if ((this->actor.bgCheckFlags & (1 | 2 | 8)) || temp_v0 || (this->unk_19A <= 0)) { + func_809AAFE8(&this->actor.world.pos, globalCtx); + func_809AAF9C(&this->actor.world.pos, this->unk_198, globalCtx); + + this->actor.draw = NULL; + this->actor.shape.shadowDraw = NULL; + + if (this->unk_190 != NULL) { + this->actor.room = this->unk_190->actor.room; + } + + if (!(this->actor.bgCheckFlags & 0x20)) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN); + } + func_809AB428(this); + return; + } + + if (this->actor.bgCheckFlags & 0x40) { + sp5C.y = this->actor.world.pos.y + this->actor.depthInWater; + + for (phi_s0 = 0, i = 0; i < 4; i++, phi_s0 += 0x4000) { + sp5C.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.x; + sp5C.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp5C, NULL, NULL, 0, 190); + } + + sp5C.x = this->actor.world.pos.x; + sp5C.z = this->actor.world.pos.z; + + EffectSsGSplash_Spawn(globalCtx, &sp5C, NULL, NULL, 0, 280); + EffectSsGRipple_Spawn(globalCtx, &sp5C, 300, 700, 0); + + this->actor.terminalVelocity = -3.0f; + this->actor.velocity.x *= 0.1f; + this->actor.velocity.y *= 0.4f; + this->actor.velocity.z *= 0.1f; + this->actor.gravity *= 0.5f; + + D_809ABC00 = D_809ABC00 >> 1; + D_809ABBFC = D_809ABBFC >> 1; + D_809ABC08 = D_809ABC08 >> 1; + D_809ABC04 = D_809ABC04 >> 1; + this->actor.bgCheckFlags &= ~0x40; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + } + + Math_StepToS(&D_809ABC00, D_809ABBFC, 0x1F4); + Math_StepToS(&D_809ABC08, D_809ABC04, 0xAA); + this->actor.shape.rot.x += D_809ABC00; + this->actor.shape.rot.y += D_809ABC08; + func_809AAF18(this); + func_809AAF58(this, globalCtx); + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjGrassCarry_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjGrassCarry* this = THIS; + + if (this->unk_190 == NULL) { + if ((this->actionFunc != func_809AB610) && (this->actionFunc != func_809AB77C)) { + Actor_MarkForDeath(&this->actor); + return; + } + } + + this->actionFunc(this, globalCtx); +} + +void func_809ABB7C(Actor* this, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, gKusaBushType1); +} diff --git a/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h b/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h index 90ded06c5..50d2f61f7 100644 --- a/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h +++ b/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.h @@ -4,12 +4,18 @@ #include "global.h" struct ObjGrassCarry; +struct ObjGrass; +struct ObjGrassStruct1_1; typedef void (*ObjGrassCarryActionFunc)(struct ObjGrassCarry*, GlobalContext*); typedef struct ObjGrassCarry { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x58]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ struct ObjGrass* unk_190; + /* 0x0194 */ struct ObjGrassStruct1_1* unk_194; + /* 0x0198 */ s16 unk_198; + /* 0x019A */ s16 unk_19A; /* 0x019C */ ObjGrassCarryActionFunc actionFunc; } ObjGrassCarry; // size = 0x1A0 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 77bd96c24..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,3 +1,9 @@ +/* + * File: z_obj_grass_unit.c + * Overlay: ovl_Obj_Grass_Unit + * Description: Spawner for circular patch of grass + */ + #include "z_obj_grass_unit.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c index f053fc20a..d3199e8d8 100644 --- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c +++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.c @@ -1,6 +1,13 @@ -#include "z_obj_hakaisi.h" +/* + * File: z_obj_hakaisi.c + * Overlay: ovl_Obj_Hakaisi + * Description: Gravestone + */ -#define FLAGS 0x00000029 +#include "z_obj_hakaisi.h" +#include "objects/object_hakaisi/object_hakaisi.h" + +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_20) #define THIS ((ObjHakaisi*)thisx) @@ -9,7 +16,27 @@ void ObjHakaisi_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjHakaisi_Update(Actor* thisx, GlobalContext* globalCtx); void ObjHakaisi_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B1444C(ObjHakaisi* this); +void func_80B14460(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B14510(ObjHakaisi* this); +void func_80B14524(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B14558(ObjHakaisi* this); +void func_80B1456C(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B145F4(ObjHakaisi* this); +void func_80B14648(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B149A8(ObjHakaisi* this); +void func_80B149C0(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B14A24(ObjHakaisi* this, GlobalContext* globalCtx, Vec3f vec); +void func_80B14B6C(ObjHakaisi* this, GlobalContext* globalCtx, Vec3f vec, s16 arg3); +void func_80B14CF8(GlobalContext* globalCtx, Vec3f vec, s16 arg2, s16 arg3, s32 arg4); +void func_80B14F4C(ObjHakaisi* this, GlobalContext* globalCtx, s32 arg2); +void func_80B151E0(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B15254(Actor* thisx, GlobalContext* globalCtx); +void func_80B15264(ObjHakaisi* this); +void func_80B15330(ObjHakaisi* this, GlobalContext* globalCtx); +void func_80B1544C(Actor* thisx, GlobalContext* globalCtx); +void func_80B154A0(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Hakaisi_InitVars = { ACTOR_OBJ_HAKAISI, ACTORCAT_PROP, @@ -22,57 +49,395 @@ const ActorInit Obj_Hakaisi_InitVars = { (ActorFunc)ObjHakaisi_Draw, }; -#endif +Vec3f D_80B155B0 = { 0.0f, 25.0f, 30.0f }; -extern UNK_TYPE D_06001F10; -extern UNK_TYPE D_060021B0; -extern UNK_TYPE D_06002650; -extern UNK_TYPE D_06002FC4; +Vec3f D_80B155BC[] = { { 0.0f, 65.0f, 8.0f }, { 0.0f, 35.0f, 8.0f }, { 0.0f, 15.0f, 8.0f } }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/ObjHakaisi_Init.s") +Vec3f D_80B155E0 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/ObjHakaisi_Destroy.s") +Vec3f D_80B155EC = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B1444C.s") +Color_RGBA8 D_80B155F8 = { 170, 130, 90, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14460.s") +Color_RGBA8 D_80B155FC = { 100, 60, 20, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14510.s") +Vec3f D_80B15600 = { 1.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14524.s") +void ObjHakaisi_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjHakaisi* this = THIS; + CollisionHeader* sp7C = NULL; + MtxF sp3C; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14558.s") + switch (OBJHAKAISI_GET_FF(&this->dyna.actor)) { + case 0: + this->dyna.actor.textId = 0x13F9; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B1456C.s") + case 1: + this->dyna.actor.textId = 0x13FA; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B145F4.s") + case 2: + this->dyna.actor.textId = 0x13FB; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14648.s") + case 3: + this->dyna.actor.textId = 0x13FC; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B149A8.s") + case 4: + case 5: + func_80B151E0(this, globalCtx); + return; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B149C0.s") + default: + this->dyna.actor.textId = 0x1412; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14A24.s") + Actor_SetScale(&this->dyna.actor, 1.0f); + this->dyna.actor.targetMode = 0; + this->dyna.actor.colChkInfo.health = 30; + if (OBJHAKAISI_GET_FF(&this->dyna.actor) == 3) { + this->dyna.actor.draw = NULL; + func_80B1444C(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14B6C.s") + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&object_hakaisi_Colheader_002FC4, &sp7C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14CF8.s") + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp7C); + this->unk_19A = 0; + this->unk_198 = 0; + this->switchFlag = OBJHAKAISI_GET_SWITCHFLAG(thisx); + this->unk_196 = this->dyna.actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B14F4C.s") + if (this->switchFlag == 0xFF) { + this->switchFlag = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/ObjHakaisi_Update.s") + if ((this->switchFlag != -1) && Flags_GetSwitch(globalCtx, this->switchFlag)) { + Actor_MarkForDeath(&this->dyna.actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/ObjHakaisi_Draw.s") + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B151E0.s") + if (this->dyna.actor.floorPoly == NULL) { + Actor_MarkForDeath(&this->dyna.actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B15254.s") + func_800C0094(this->dyna.actor.floorPoly, this->dyna.actor.world.pos.x, this->dyna.actor.floorHeight, + this->dyna.actor.world.pos.z, &sp3C); + Matrix_Put(&sp3C); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + Matrix_Get(&sp3C); + Matrix_MtxFToYXZRot(&sp3C, &this->dyna.actor.shape.rot, true); + this->dyna.actor.world.rot = this->dyna.actor.shape.rot; + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + Matrix_MultVec3f(&D_80B155B0, &this->dyna.actor.focus.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B15264.s") + for (i = 0; i < ARRAY_COUNT(D_80B155BC); i++) { + Matrix_MultVec3f(&D_80B155BC[i], &this->unk_160[i]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B15330.s") + func_80B1444C(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B1544C.s") +void ObjHakaisi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjHakaisi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hakaisi/func_80B154A0.s") + if (OBJHAKAISI_GET_FF(&this->dyna.actor) != 3) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} + +void func_80B1444C(ObjHakaisi* this) { + this->actionFunc = func_80B14460; +} + +void func_80B14460(ObjHakaisi* this, GlobalContext* globalCtx) { + s16 sp26 = BINANG_SUB(this->dyna.actor.shape.rot.y, this->dyna.actor.yawTowardsPlayer); + + if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state)) { + func_80B14510(this); + } else if (this->dyna.actor.textId != 0) { + if (ABS_ALT(sp26) < 0x2000) { + func_800B8614(&this->dyna.actor, globalCtx, 100.0f); + } + } + + if (this->unk_198 == 1) { + func_80B14558(this); + } +} + +void func_80B14510(ObjHakaisi* this) { + this->actionFunc = func_80B14524; +} + +void func_80B14524(ObjHakaisi* this, GlobalContext* globalCtx) { + if (Actor_TextboxIsClosing(&this->dyna.actor, globalCtx)) { + func_80B1444C(this); + } +} + +void func_80B14558(ObjHakaisi* this) { + this->actionFunc = func_80B1456C; +} + +void func_80B1456C(ObjHakaisi* this, GlobalContext* globalCtx) { + if (this->unk_196 != -1) { + if (ActorCutscene_GetCanPlayNext(this->unk_196)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_196, &this->dyna.actor); + } else { + ActorCutscene_SetIntentToPlay(this->unk_196); + } + } + if (this->dyna.actor.colChkInfo.health < 30) { + func_80B145F4(this); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} + +void func_80B145F4(ObjHakaisi* this) { + this->unk_19A = 0; + this->dyna.actor.flags |= ACTOR_FLAG_8000000; + this->dyna.actor.flags &= ~ACTOR_FLAG_1; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WALL_BROKEN); + this->actionFunc = func_80B14648; +} + +void func_80B14648(ObjHakaisi* this, GlobalContext* globalCtx) { + if (this->unk_19A < 2) { + func_80B14CF8(globalCtx, this->unk_160[this->unk_194], 100, 30, 5); + } + + this->unk_19A++; + + if (this->dyna.actor.colChkInfo.health == 0) { + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14B6C(this, globalCtx, this->unk_160[this->unk_194], 70); + Flags_SetSwitch(globalCtx, this->switchFlag); + this->dyna.actor.draw = NULL; + func_80B149A8(this); + } + + if (this->unk_19E != this->dyna.actor.colChkInfo.health) { + if ((this->unk_19E > 20) && (this->dyna.actor.colChkInfo.health <= 20)) { + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14F4C(this, globalCtx, 0); + func_80B14B6C(this, globalCtx, this->unk_160[this->unk_194], 40); + this->unk_194 = 1; + } else if ((this->unk_19E > 10) && (this->dyna.actor.colChkInfo.health <= 10)) { + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14A24(this, globalCtx, this->unk_160[this->unk_194]); + func_80B14B6C(this, globalCtx, this->unk_160[this->unk_194], 60); + this->unk_194 = 2; + } + this->unk_19A = 0; + this->dyna.actor.shape.yOffset -= 3.0f; + } + + Math_ApproachZeroF(&this->dyna.actor.shape.yOffset, 0.8f, 100.0f); + this->unk_19E = this->dyna.actor.colChkInfo.health; +} + +void func_80B149A8(ObjHakaisi* this) { + this->unk_19A = 0; + this->actionFunc = func_80B149C0; +} + +void func_80B149C0(ObjHakaisi* this, GlobalContext* globalCtx) { + if (this->unk_19A < 60) { + this->unk_19A++; + } else if ((this->unk_196 != -1) && !ActorCutscene_GetCanPlayNext(this->unk_196)) { + ActorCutscene_Stop(this->unk_196); + } +} + +void func_80B14A24(ObjHakaisi* this, GlobalContext* globalCtx, Vec3f vec) { + s32 i; + + func_80B14CF8(globalCtx, vec, 100, 30, 5); + + for (i = 0; i < 5; i++) { + vec.x += Rand_Centered() * 20.0f; + vec.y += Rand_ZeroOne() * 5.0f; + vec.z += Rand_Centered() * 20.0f; + EffectSsHahen_SpawnBurst(globalCtx, &vec, 5.0f, 0, 20, 15, 3, OBJECT_HAKAISI, 10, object_hakaisi_DL_0021B0); + } +} + +void func_80B14B6C(ObjHakaisi* this, GlobalContext* globalCtx, Vec3f vec, s16 arg3) { + s32 i; + s16 temp_s1; + Vec3f sp6C; + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WALL_BROKEN); + + for (i = 0; i < 5; i++) { + temp_s1 = Rand_Next(); + + sp6C.x = (Math_SinS(temp_s1) * 15.0f) + vec.x; + sp6C.y = (Rand_ZeroOne() * 3.0f) + vec.y; + sp6C.z = (Math_CosS(temp_s1) * 15.0f) + vec.z; + + EffectSsHahen_SpawnBurst(globalCtx, &sp6C, 10.0f, 0, arg3, 30, 2, OBJECT_HAKAISI, 15, object_hakaisi_DL_0021B0); + } + + func_80B14CF8(globalCtx, vec, 100, 50, 20); +} + +void func_80B14CF8(GlobalContext* globalCtx, Vec3f vec, s16 arg2, s16 arg3, s32 arg4) { + s32 i; + s16 temp_s0; + Vec3f spAC; + Vec3f spA0 = D_80B155E0; + Vec3f sp94 = D_80B155EC; + f32 temp_f20; + f32 temp_f22; + + for (i = 0; i < arg4; i++) { + temp_f20 = Rand_ZeroOne() * 30.0f; + temp_f22 = Rand_ZeroOne() * 1.5f; + temp_s0 = Rand_Next(); + + spAC.x = (Math_SinS(temp_s0) * temp_f20) + vec.x; + spAC.y = (Rand_Centered() * 4.0f) + vec.y; + spAC.z = (Math_CosS(temp_s0) * temp_f20) + vec.z; + + spA0.x += temp_f22 * Math_SinS(temp_s0); + spA0.y += Rand_Centered() + 0.5f; + spA0.z += temp_f22 * Math_CosS(temp_s0); + + sp94.x = -0.1f * spA0.x; + sp94.y = -0.1f * spA0.y; + sp94.z = -0.1f * spA0.z; + + func_800B0EB0(globalCtx, &spAC, &spA0, &sp94, &D_80B155F8, &D_80B155FC, arg2, arg3, 10); + } +} + +void func_80B14F4C(ObjHakaisi* this, GlobalContext* globalCtx, s32 arg2) { + if (arg2 == 0) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_HAKAISI, this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y + 55.0f, this->dyna.actor.world.pos.z - 10.0f, + this->dyna.actor.shape.rot.x, this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, 4); + } else { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_HAKAISI, this->dyna.actor.world.pos.x + 20.0f, + this->dyna.actor.world.pos.y + 30.0f, this->dyna.actor.world.pos.z - 10.0f, + this->dyna.actor.shape.rot.x, this->dyna.actor.shape.rot.y, this->dyna.actor.shape.rot.z, 5); + } +} + +void ObjHakaisi_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjHakaisi* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjHakaisi_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjHakaisi* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_194 == 0) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_hakaisi_DL_002650); + } else if (this->unk_194 == 1) { + Matrix_Scale(0.1f, 0.1f, 0.1f, 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_hakaisi_DL_0029C0); + } else { + Matrix_Scale(0.1f, 0.1f, 0.1f, 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_hakaisi_DL_002CC0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80B151E0(ObjHakaisi* this, GlobalContext* globalCtx) { + this->dyna.actor.update = func_80B1544C; + this->dyna.actor.draw = func_80B154A0; + this->dyna.actor.destroy = func_80B15254; + Actor_SetScale(&this->dyna.actor, 0.1f); + this->dyna.actor.shape.yOffset = 100.0f; + this->dyna.actor.flags &= ~ACTOR_FLAG_1; + func_80B15264(this); +} + +void func_80B15254(Actor* thisx, GlobalContext* globalCtx) { +} + +void func_80B15264(ObjHakaisi* this) { + s32 pad; + s16 sp32 = Rand_Next(); + + Matrix_RotateZYX(Rand_Next(), Rand_Next(), Rand_Next(), MTXMODE_NEW); + Matrix_MultVec3f(&D_80B15600, &this->unk_184); + this->dyna.actor.gravity = -1.0f; + this->unk_19C = Rand_Next() >> 0x12; + this->dyna.actor.velocity.x = Math_SinS(sp32) * 4.0f; + this->dyna.actor.velocity.z = Math_CosS(sp32) * 4.0f; + this->dyna.actor.velocity.y = 7.0f; + this->actionFunc = func_80B15330; +} + +void func_80B15330(ObjHakaisi* this, GlobalContext* globalCtx) { + s32 pad; + MtxF sp34; + + this->dyna.actor.velocity.y += this->dyna.actor.gravity; + Actor_UpdatePos(&this->dyna.actor); + + if (this->dyna.actor.bgCheckFlags & 2) { + func_80B14B6C(this, globalCtx, this->dyna.actor.world.pos, 40); + func_80B14CF8(globalCtx, this->dyna.actor.world.pos, 100, 30, 10); + Actor_MarkForDeath(&this->dyna.actor); + } + + Matrix_RotateAxisS(this->unk_19C, &this->unk_184, MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + Matrix_Get(&sp34); + + Matrix_MtxFToYXZRot(&sp34, &this->dyna.actor.shape.rot, false); +} + +void func_80B1544C(Actor* thisx, GlobalContext* globalCtx) { + ObjHakaisi* this = THIS; + + this->actionFunc(this, globalCtx); + + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 0.0f, 0.0f, 0.0f, 4); +} + +void func_80B154A0(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (OBJHAKAISI_GET_FF(thisx) == 4) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_hakaisi_DL_001F10); + } else { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_hakaisi_DL_0021B0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..4f1d1ada9 100644 --- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h +++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h @@ -7,11 +7,21 @@ struct ObjHakaisi; typedef void (*ObjHakaisiActionFunc)(struct ObjHakaisi*, GlobalContext*); +#define OBJHAKAISI_GET_FF(thisx) ((thisx)->params & 0xFF) +#define OBJHAKAISI_GET_SWITCHFLAG(thisx) (((thisx)->params & 0xFF00) >> 8) + typedef struct ObjHakaisi { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjHakaisiActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x40]; + /* 0x0160 */ Vec3f unk_160[3]; + /* 0x0184 */ Vec3f unk_184; + /* 0x0190 */ s32 switchFlag; + /* 0x0194 */ s16 unk_194; + /* 0x0196 */ s16 unk_196; + /* 0x0198 */ s16 unk_198; + /* 0x019A */ s16 unk_19A; + /* 0x019C */ s16 unk_19C; + /* 0x019E */ u8 unk_19E; } 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 34fb4e0fc..10d8891ef 100644 --- a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -1,6 +1,13 @@ -#include "z_obj_hamishi.h" +/* + * File: z_obj_hamishi.c + * Overlay: ovl_Obj_Hamishi + * Description: Bronze boulder + */ -#define FLAGS 0x00000010 +#include "z_obj_hamishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjHamishi*)thisx) @@ -9,7 +16,6 @@ void ObjHamishi_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjHamishi_Update(Actor* thisx, GlobalContext* globalCtx); void ObjHamishi_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Hamishi_InitVars = { ACTOR_OBJ_HAMISHI, ACTORCAT_PROP, @@ -22,44 +28,261 @@ const ActorInit Obj_Hamishi_InitVars = { (ActorFunc)ObjHamishi_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809A1AA0 = { - { 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 }, { 0x81C37FB6, 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 }, + { 0x81C37FB6, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 50, 70, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_809A1ACC = { 0, 12, 60, MASS_IMMOVABLE }; +static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809A1AE8[] = { +s16 D_809A1AD4[] = { + 145, 135, 115, 85, 75, 53, 45, 40, 35, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -#endif +void func_809A0F20(Actor* thisx, GlobalContext* globalCtx) { + ObjHamishi* this = THIS; -extern ColliderCylinderInit D_809A1AA0; -extern CollisionCheckInfoInit D_809A1ACC; -extern InitChainEntry D_809A1AE8[]; + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/func_809A0F20.s") +void func_809A0F78(ObjHamishi* this) { + if (this->unk_198 > 0) { + this->unk_198--; + this->unk_19A += 0x1388; + this->unk_19C += 0xE10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/func_809A0F78.s") + Math_StepToF(&this->unk_190, 0.0f, 0.15f); + Math_StepToF(&this->unk_194, 0.0f, 40.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/func_809A10F4.s") + this->actor.world.pos.x = (Math_SinS(this->unk_19A * 4) * this->unk_190) + this->actor.home.pos.x; + this->actor.world.pos.z = (Math_CosS(this->unk_19A * 7) * this->unk_190) + this->actor.home.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/func_809A13A0.s") + this->actor.shape.rot.x = (s32)(Math_SinS(this->unk_19C * 4) * this->unk_194) + this->actor.home.rot.x; + this->actor.shape.rot.z = (s32)(Math_CosS(this->unk_19C * 7) * this->unk_194) + this->actor.home.rot.z; + } else { + Math_StepToF(&this->actor.world.pos.x, this->actor.home.pos.x, 1.0f); + Math_StepToF(&this->actor.world.pos.z, this->actor.home.pos.z, 1.0f); + Math_ScaledStepToS(&this->actor.shape.rot.x, this->actor.home.rot.x, 0xBB8); + Math_ScaledStepToS(&this->actor.shape.rot.z, this->actor.home.rot.z, 0xBB8); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/func_809A1408.s") +void func_809A10F4(ObjHamishi* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spC8; + Vec3f spBC; + f32 temp_f20; + s16 temp_s0 = 1000; + s32 gravity; + s32 phi_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/ObjHamishi_Init.s") + for (i = 0; i < ARRAY_COUNT(D_809A1AD4); i++) { + temp_s0 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/ObjHamishi_Destroy.s") + spBC.x = (Math_SinS(temp_s0) * temp_f20) + this->actor.world.pos.x; + spBC.y = (Rand_ZeroOne() * 40.0f) + this->actor.world.pos.y + 5.0f; + spBC.z = (Math_CosS(temp_s0) * temp_f20) + this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/ObjHamishi_Update.s") + temp_f20 = (Rand_ZeroOne() * 10.0f) + 2.0f; + spC8.x = Math_SinS(temp_s0) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hamishi/ObjHamishi_Draw.s") + spC8.y = (Rand_ZeroOne() * 15.0f) + (Rand_ZeroOne() * i * 2.5f); + spC8.z = Math_CosS(temp_s0) * temp_f20; + + if (i == 0) { + phi_v0 = 41; + gravity = -450; + } else if (i < 4) { + phi_v0 = 37; + gravity = -380; + } else { + phi_v0 = 69; + gravity = -320; + } + + EffectSsKakera_Spawn(globalCtx, &spBC, &spC8, &this->actor.world.pos, gravity, phi_v0, 30, 5, 0, D_809A1AD4[i], + 3, 0, 70, 1, GAMEPLAY_FIELD_KEEP, gameplay_field_keep_DL_006420); + } + + func_800BBFB0(globalCtx, &this->actor.world.pos, 140.0f, 6, 180, 90, 1); + func_800BBFB0(globalCtx, &this->actor.world.pos, 140.0f, 12, 80, 90, 1); +} + +void func_809A13A0(ObjHamishi* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp28; + s32 sp24; + + sp28.x = this->actor.world.pos.x; + sp28.y = this->actor.world.pos.y + 30.0f; + sp28.z = this->actor.world.pos.z; + + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp24, &this->actor, &sp28); +} + +s32 func_809A1408(ObjHamishi* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* sp30; + f32 sp2C; + s32 sp28; + + 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; +} + +void ObjHamishi_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjHamishi* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (globalCtx->csCtx.state != 0) { + this->actor.uncullZoneForward += 1000.0f; + } + + if (this->actor.shape.rot.y == 0) { + this->actor.shape.rot.y = (u32)Rand_Next() >> 0x10; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actor.home.rot.y = this->actor.shape.rot.y; + } + + func_809A0F20(&this->actor, globalCtx); + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + func_809A13A0(this, globalCtx); + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 2.3f); + + if (Flags_GetSwitch(globalCtx, OBJHAMISHI_GET_SWITCHFLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.shape.yOffset = 80.0f; + + if (func_809A1408(this, globalCtx)) { + this->unk_1A2 |= 1; + } +} + +void ObjHamishi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyCylinder(globalCtx, &THIS->collider); +} + +void ObjHamishi_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjHamishi* this = THIS; + s32 sp24 = (this->collider.base.acFlags & AC_HIT) != 0; + + func_809A0F78(this); + + if (sp24) { + this->unk_1A1 = 5; + this->collider.base.acFlags &= ~AC_HIT; + } + + if (sp24) { + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000500) { + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x400) { + this->unk_1A0 = 26; + } else { + this->unk_1A0 = 11; + } + + if (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000000) { + this->unk_19E = 2; + } else { + this->unk_19E++; + } + + if (this->unk_19E < 2) { + this->unk_198 = 15; + this->unk_190 = 2.0f; + this->unk_194 = 400.0f; + } else { + func_809A10F4(this, globalCtx); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_WALL_BROKEN); + Flags_SetSwitch(globalCtx, OBJHAMISHI_GET_SWITCHFLAG(&this->actor)); + Actor_MarkForDeath(&this->actor); + } + } + } + + if (this->actor.update != NULL) { + if (this->unk_1A1 > 0) { + this->unk_1A1--; + if (this->unk_1A1 == 0) { + this->collider.base.colType = COLTYPE_HARD; + } else { + this->collider.base.colType = COLTYPE_NONE; + } + } + + if (this->unk_1A0 > 0) { + this->unk_1A0--; + } else if ((this->actor.flags & ACTOR_FLAG_40) && (this->actor.xzDistToPlayer < 1000.0f)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actor.xzDistToPlayer < 600.0f) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void ObjHamishi_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjHamishi* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((thisx->projectedPos.z <= 2150.0f) || ((this->unk_1A2 & 1) && (thisx->projectedPos.z < 2250.0f))) { + thisx->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, 170, 130, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_field_keep_DL_0061E8); + } else if (thisx->projectedPos.z < 2250.0f) { + f32 sp20 = (2250.0f - thisx->projectedPos.z) * 2.55f; + + thisx->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, 170, 130, (s32)sp20); + gSPDisplayList(POLY_XLU_DISP++, gameplay_field_keep_DL_0061E8); + } else { + thisx->shape.shadowAlpha = 0; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h index 1305f49ee..da838d480 100644 --- a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h +++ b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.h @@ -5,9 +5,20 @@ struct ObjHamishi; +#define OBJHAMISHI_GET_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) + typedef struct ObjHamishi { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x60]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ f32 unk_190; + /* 0x194 */ f32 unk_194; + /* 0x198 */ s16 unk_198; + /* 0x19A */ s16 unk_19A; + /* 0x19C */ s16 unk_19C; + /* 0x19E */ s16 unk_19E; + /* 0x1A0 */ s8 unk_1A0; + /* 0x1A1 */ s8 unk_1A1; + /* 0x1A2 */ u8 unk_1A2; } ObjHamishi; // size = 0x1A4 extern const ActorInit Obj_Hamishi_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c index b82932eaa..93578ac40 100644 --- a/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c +++ b/src/overlays/actors/ovl_Obj_Hana/z_obj_hana.c @@ -5,6 +5,7 @@ */ #include "z_obj_hana.h" +#include "objects/object_hana/object_hana.h" #define FLAGS 0x00000000 @@ -27,8 +28,6 @@ const ActorInit Obj_Hana_InitVars = { (ActorFunc)ObjHana_Draw, }; -extern Gfx D_06000500[]; - static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 900, ICHAIN_CONTINUE), @@ -49,5 +48,5 @@ void ObjHana_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjHana_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000500); + Gfx_DrawDListOpa(globalCtx, object_hana_DL_000500); } diff --git a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.c b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.c index 17ce38ce9..840488810 100644 --- a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.c +++ b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.c @@ -1,6 +1,13 @@ -#include "z_obj_hariko.h" +/* + * File: z_obj_hariko.c + * Overlay: ovl_Obj_Hariko + * Description: Little Cow Statue Head + */ -#define FLAGS 0x02000020 +#include "z_obj_hariko.h" +#include "assets/objects/object_hariko/object_hariko.h" + +#define FLAGS (ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((ObjHariko*)thisx) @@ -9,10 +16,12 @@ void ObjHariko_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjHariko_Update(Actor* thisx, GlobalContext* globalCtx); void ObjHariko_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80B66A90(ObjHariko* this, GlobalContext* globalCtx); -void func_80B66AC4(ObjHariko* this, GlobalContext* globalCtx); +void ObjHariko_SetupWait(ObjHariko* this); +void ObjHariko_Wait(ObjHariko* this, GlobalContext* globalCtx); +void ObjHariko_SetupBobHead(ObjHariko* this); +void ObjHariko_BobHead(ObjHariko* this, GlobalContext* globalCtx); +void ObjHariko_CheckForQuakes(ObjHariko* this); -#if 0 const ActorInit Obj_Hariko_InitVars = { ACTOR_OBJ_HARIKO, ACTORCAT_PROP, @@ -25,24 +34,71 @@ const ActorInit Obj_Hariko_InitVars = { (ActorFunc)ObjHariko_Draw, }; -#endif +void ObjHariko_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjHariko* this = THIS; -extern UNK_TYPE D_06000080; + Actor_SetScale(&this->actor, 0.1f); + this->headRotation.x = 0; + this->headRotation.y = 0; + this->headRotation.z = 0; + this->headOffset = 0; + this->bobbleStep = 0.0f; + ObjHariko_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/ObjHariko_Init.s") +void ObjHariko_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/ObjHariko_Destroy.s") +void ObjHariko_SetupWait(ObjHariko* this) { + this->actionFunc = ObjHariko_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/func_80B66A7C.s") +void ObjHariko_Wait(ObjHariko* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/func_80B66A90.s") +void ObjHariko_SetupBobHead(ObjHariko* this) { + this->bobbleStep = 2730.0f; + this->unk154 = 0; + this->actionFunc = ObjHariko_BobHead; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/func_80B66AA0.s") +void ObjHariko_BobHead(ObjHariko* this, GlobalContext* globalCtx) { + this->headOffset += 0x1555; + this->headRotation.x = Math_SinS(this->headOffset) * this->bobbleStep; + this->headRotation.y = Math_CosS(this->headOffset) * this->bobbleStep; + Math_SmoothStepToF(&this->bobbleStep, 0, 0.5f, 18.0f, 18.0f); + if (this->bobbleStep < 182.0f) { + ObjHariko_SetupWait(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/func_80B66AC4.s") +void ObjHariko_CheckForQuakes(ObjHariko* this) { + if (Quake_NumActiveQuakes() != 0) { + ObjHariko_SetupBobHead(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/func_80B66B78.s") +void ObjHariko_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjHariko* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/ObjHariko_Update.s") + this->actionFunc(this, globalCtx); + ObjHariko_CheckForQuakes(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hariko/ObjHariko_Draw.s") +void ObjHariko_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjHariko* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + + Matrix_Push(); + Matrix_RotateXS(this->headRotation.x, MTXMODE_APPLY); + Matrix_RotateYS(this->headRotation.y, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gHarikoBodyDL); + gSPDisplayList(POLY_OPA_DISP++, gHarikoFaceDL); + + Matrix_Pop(); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} 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..12d4fe505 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,10 @@ typedef void (*ObjHarikoActionFunc)(struct ObjHariko*, GlobalContext*); typedef struct ObjHariko { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjHarikoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x10]; + /* 0x0148 */ f32 bobbleStep; + /* 0x014C */ Vec3s headRotation; + /* 0x0152 */ s16 headOffset; + /* 0x0154 */ s16 unk154; // Set but not used } ObjHariko; // size = 0x158 extern const ActorInit Obj_Hariko_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c index d2878b2ad..4e6b3791d 100644 --- a/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c +++ b/src/overlays/actors/ovl_Obj_Hgdoor/z_obj_hgdoor.c @@ -1,6 +1,13 @@ -#include "z_obj_hgdoor.h" +/* + * File: z_obj_hgdoor.c + * Overlay: ovl_Obj_Hgdoor + * Description: Music Box House - Closet Door + */ -#define FLAGS 0x00100000 +#include "z_obj_hgdoor.h" +#include "objects/object_hgdoor/object_hgdoor.h" + +#define FLAGS (ACTOR_FLAG_100000) #define THIS ((ObjHgdoor*)thisx) @@ -19,13 +26,6 @@ void func_80BD4460(ObjHgdoor* this); void func_80BD4478(ObjHgdoor* this, GlobalContext* globalCtx); s32 func_80BD44D0(ObjHgdoor* this, GlobalContext* globalCtx); -extern CollisionHeader D_06001D10; -extern CollisionHeader D_060018C0; -extern Gfx D_06001AB0[]; -extern Gfx D_06001BA8[]; -extern Gfx D_06001670[]; -extern Gfx D_06001768[]; - const ActorInit Obj_Hgdoor_InitVars = { ACTOR_OBJ_HGDOOR, ACTORCAT_PROP, @@ -43,7 +43,7 @@ static s32 unused = 0; static s32 unused2 = 0; void ObjHgdoor_SetChild(ObjHgdoor* this, GlobalContext* globalCtx) { - Actor* actorIterator = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + Actor* actorIterator = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; while (actorIterator) { if ((actorIterator->id == ACTOR_OBJ_HGDOOR) && (&this->dyna.actor != actorIterator)) { @@ -55,7 +55,7 @@ void ObjHgdoor_SetChild(ObjHgdoor* this, GlobalContext* globalCtx) { } void ObjHgdoor_SetParent(ObjHgdoor* this, GlobalContext* globalCtx) { - Actor* actorIterator = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + Actor* actorIterator = globalCtx->actorCtx.actorLists[ACTORCAT_PROP].first; while (actorIterator) { if (actorIterator->id == ACTOR_EN_HG) { @@ -72,13 +72,13 @@ void ObjHgdoor_Init(Actor* thisx, GlobalContext* globalCtx) { CollisionHeader* header = NULL; Actor_SetScale(&this->dyna.actor, 0.1f); - BcCheck3_BgActorInit(&this->dyna, 1); + DynaPolyActor_Init(&this->dyna, 1); if (OBJHGDOOR_IS_RIGHT_DOOR(&this->dyna.actor)) { - BgCheck_RelocateMeshHeader(&D_06001D10, &header); + CollisionHeader_GetVirtual(&object_hgdoor_Colheader_001D10, &header); } else { - BgCheck_RelocateMeshHeader(&D_060018C0, &header); + CollisionHeader_GetVirtual(&object_hgdoor_Colheader_0018C0, &header); } - this->dyna.bgId = BgCheck_AddActorMesh(globalCtx, &globalCtx->colCtx.dyna, &this->dyna, header); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, header); this->rotation = 0; this->timer = 0; this->cutscene = this->dyna.actor.cutscene; @@ -88,7 +88,7 @@ void ObjHgdoor_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjHgdoor_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjHgdoor* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjHgdoor_SetupCheckShouldOpen(ObjHgdoor* this) { @@ -96,8 +96,8 @@ void ObjHgdoor_SetupCheckShouldOpen(ObjHgdoor* this) { } void ObjHgdoor_CheckShouldOpen(ObjHgdoor* this, GlobalContext* globalCtx) { - if (!(gSaveContext.weekEventReg[75] & 0x20) && !(gSaveContext.weekEventReg[52] & 0x20) && - (this->dyna.actor.xzDistToPlayer < 100.0f) && (this->dyna.actor.yDistToPlayer < 40.0f) && + if (!(gSaveContext.save.weekEventReg[75] & 0x20) && !(gSaveContext.save.weekEventReg[52] & 0x20) && + (this->dyna.actor.xzDistToPlayer < 100.0f) && (this->dyna.actor.playerHeightRel < 40.0f) && OBJHGDOOR_IS_RIGHT_DOOR(&this->dyna.actor)) { ObjHgdoor_SetChild(this, globalCtx); ObjHgdoor_SetParent(this, globalCtx); @@ -128,15 +128,15 @@ void func_80BD433C(ObjHgdoor* this) { } void func_80BD4358(ObjHgdoor* this, GlobalContext* globalCtx) { - u32 actionIndex; + s32 actionIndex; - if (func_800EE29C(globalCtx, 0x1E3)) { - actionIndex = func_800EE200(globalCtx, 0x1E3); - if (this->unk166 != globalCtx->csCtx.npcActions[actionIndex]->unk0) { - this->unk166 = globalCtx->csCtx.npcActions[actionIndex]->unk0; - switch (globalCtx->csCtx.npcActions[actionIndex]->unk0) { + if (Cutscene_CheckActorAction(globalCtx, 483)) { + actionIndex = Cutscene_GetActorActionIndex(globalCtx, 483); + if (this->unk166 != globalCtx->csCtx.actorActions[actionIndex]->action) { + this->unk166 = globalCtx->csCtx.actorActions[actionIndex]->action; + switch (globalCtx->csCtx.actorActions[actionIndex]->action) { case 1: - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WOOD_DOOR_OPEN_SPEEDY); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_WOOD_DOOR_OPEN_SPEEDY); if ((this->dyna.actor.parent != NULL) && (this->dyna.actor.parent->id == ACTOR_EN_HG)) { this->dyna.actor.parent->colChkInfo.health = 1; } @@ -197,11 +197,11 @@ void ObjHgdoor_Draw(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); if (OBJHGDOOR_IS_RIGHT_DOOR(thisx)) { - gSPDisplayList(POLY_OPA_DISP++, D_06001AB0); - gSPDisplayList(POLY_OPA_DISP++, D_06001BA8); + gSPDisplayList(POLY_OPA_DISP++, object_hgdoor_DL_001AB0); + gSPDisplayList(POLY_OPA_DISP++, object_hgdoor_DL_001BA8); } else { - gSPDisplayList(POLY_OPA_DISP++, D_06001670); - gSPDisplayList(POLY_OPA_DISP++, D_06001768); + gSPDisplayList(POLY_OPA_DISP++, object_hgdoor_DL_001670); + gSPDisplayList(POLY_OPA_DISP++, object_hgdoor_DL_001768); } CLOSE_DISPS(globalCtx->state.gfxCtx); 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 89346ce0e..1ce6faa7d 100644 --- a/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c +++ b/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c @@ -1,6 +1,13 @@ -#include "z_obj_hsstump.h" +/* + * File: z_obj_hsstump.c + * Overlay: ovl_Obj_HsStump + * Description: Ikana Canyon - Hookshotable Tree + */ -#define FLAGS 0x00000010 +#include "z_obj_hsstump.h" +#include "objects/object_hsstump/object_hsstump.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjHsStump*)thisx) @@ -30,19 +37,16 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 180, ICHAIN_STOP), }; -static Vec3f iceSmokeAccel = { 0.0f, 0.0f, 0.0f }; - -extern Gfx D_060003B8[]; -extern CollisionHeader D_060011B0; +static Vec3f sIceSmokeAccel = { 0.0f, 0.0f, 0.0f }; void ObjHsStump_Init(Actor* thisx, GlobalContext* globalCtx) { ObjHsStump* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); this->isHidden = OBJHSSTUMP_GET_ISHIDDEN(thisx); - this->switchFlag = OBJHSSTUMP_GET_SWITCHFLAG(thisx); // Must be thisx to match - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_060011B0); + this->switchFlag = OBJHSSTUMP_GET_SWITCHFLAG(thisx); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_hsstump_Colheader_0011B0); switch (this->isHidden) { case true: if (Flags_GetSwitch(globalCtx, this->switchFlag)) { @@ -83,43 +87,43 @@ void ObjHsStump_Appear(ObjHsStump* this, GlobalContext* globalCtx) { this->dyna.actor.shape.rot.z = (Math_SinS(this->rotAngle * 2) * this->rotFactor) + this->dyna.actor.home.rot.z; this->rotAngle += 0x2000; } - if (this->framesAppeared < 11) { + if (this->framesAppeared <= 10) { if (this->framesAppeared == 0) { s32 i; - f32 angle; + f32 angleDeg; s16 numDirections = 4; Vec3f iceSmokePosOffset; Vec3f iceSmokeVelOffset; s16 offsetAngle; Vec3f iceSmokeVel; - f32 angleBinary; + f32 angleBrad; Vec3f iceSmokePos; iceSmokePosOffset.x = 1.0f; iceSmokePosOffset.y = 0.5f; iceSmokePosOffset.z = 0.0f; + iceSmokeVelOffset.x = 1.0f; iceSmokeVelOffset.y = 0.5f; iceSmokeVelOffset.z = 0.0f; - angle = 360.0f / numDirections; - i = angle * (0x10000 / 360.0f); - angleBinary = i; + angleDeg = (360.0f / numDirections); + angleBrad = (s32)(angleDeg * (0x10000 / 360.0f)); for (i = 0; i < numDirections; i++) { - offsetAngle = i * angleBinary; + offsetAngle = i * angleBrad; Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.world.pos, offsetAngle, &iceSmokePosOffset, &iceSmokePos); - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); - EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVel, &iceSmokeAccel, 100); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); + EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVel, &sIceSmokeAccel, 100); } } } if (this->framesAppeared >= 10) { - Math_SmoothStepToF(&this->dyna.actor.scale.x, 0.17999999f, 1.0f, 0.01f, 0.001f); + Math_SmoothStepToF(&this->dyna.actor.scale.x, 18.0f * 0.01f, 1.0f, 0.01f, 0.001f); Actor_SetScale(&this->dyna.actor, this->dyna.actor.scale.x); } - if (this->dyna.actor.scale.x == 0.17999999f) { + if (this->dyna.actor.scale.x == 18.0f * 0.01f) { this->isHidden = false; func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); ObjHsStump_SetupIdle(this, globalCtx); @@ -130,7 +134,7 @@ void ObjHsStump_Appear(ObjHsStump* this, GlobalContext* globalCtx) { void ObjHsStump_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjHsStump* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjHsStump_Update(Actor* thisx, GlobalContext* globalCtx) { @@ -140,5 +144,5 @@ void ObjHsStump_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjHsStump_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_060003B8); + Gfx_DrawDListOpa(globalCtx, object_hsstump_DL_0003B8); } diff --git a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c index edb8df061..373815365 100644 --- a/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c +++ b/src/overlays/actors/ovl_Obj_Hsblock/z_obj_hsblock.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_hsblock.c + * Overlay: ovl_Obj_Hsblock + * Description: Hookshot Block + */ + #include "z_obj_hsblock.h" #define FLAGS 0x00000000 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 43975537b..3fc7f84b1 100644 --- a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c +++ b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c @@ -1,6 +1,13 @@ -#include "z_obj_hugebombiwa.h" +/* + * File: z_obj_hugebombiwa.c + * Overlay: ovl_Obj_Hugebombiwa + * Description: Boulder Blocking Goron Racetrack/Milk Road + */ -#define FLAGS 0x00000010 +#include "z_obj_hugebombiwa.h" +#include "objects/object_bombiwa/object_bombiwa.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjHugebombiwa*)thisx) @@ -9,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, @@ -22,64 +38,686 @@ 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* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjHugebombiwa* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A541F4.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54600.s") +void func_80A54BF0(ObjHugebombiwa* this) { + this->actionFunc = func_80A54C04; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54980.s") +void func_80A54C04(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54A0C.s") + if (this->collider.base.acFlags & AC_HIT) { + this->unk_4B3 = 5; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Init.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_Destroy.s") + this->collider.base.acFlags &= ~AC_HIT; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54BF0.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_80A54C04.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_80A54CD8.s") +void func_80A54CD8(ObjHugebombiwa* this) { + this->actionFunc = func_80A54CEC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54CEC.s") +void func_80A54CEC(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54E10.s") + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + Flags_SetSwitch(globalCtx, ENHUGEBOMBIWA_GET_7F(&this->actor)); + if (!(ENHUGEBOMBIWA_GET_100(&this->actor)) && + ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_17SETUGEN2))) { + gSaveContext.save.weekEventReg[19] |= 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55064.s") + if (!(ENHUGEBOMBIWA_GET_100(&this->actor))) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_WALL_BROKEN); + } else { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_SNOWBALL_BROKEN); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55310.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_80A55564.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/ObjHugebombiwa_Update.s") + Matrix_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Draw.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/func_80A55B34.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; + + 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_MultVec3f(&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_Pop(); + 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_Push(); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_NEW); + + 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_MultVec3f(&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_Pop(); + 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_SetTranslateRotateYXZ(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)) { + Gfx_DrawDListOpa(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_SetTranslateRotateYXZ(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_Translate(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_Hunsui/z_obj_hunsui.c b/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.c index a30fb95d2..4e09bb655 100644 --- a/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.c +++ b/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.c @@ -1,6 +1,14 @@ -#include "z_obj_hunsui.h" +/* + * File: z_obj_hunsui.c + * Overlay: ovl_Obj_Hunsui + * Description: Switch-Activated Geyser + */ -#define FLAGS 0x00000030 +#include "prevent_bss_reordering.h" +#include "z_obj_hunsui.h" +#include "objects/object_hunsui/object_hunsui.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjHunsui*)thisx) @@ -9,7 +17,36 @@ void ObjHunsui_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjHunsui_Update(Actor* thisx, GlobalContext* globalCtx); void ObjHunsui_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B9CE64(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D0FC(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D120(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D2BC(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D4D0(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D508(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9D714(ObjHunsui* this, GlobalContext* globalCtx); +void func_80B9DA60(Actor* thisx, GlobalContext* globalCtx); + +AnimatedMaterial* D_80B9DED0; +AnimatedMaterial* D_80B9DED4; + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; +} ObjHansuiBssStruct; // size = 0x3 + +ObjHansuiBssStruct D_80B9DED8; + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; +} ObjHansuiStruct; // size = 0x2 + +ObjHansuiStruct D_80B9DC70[] = { + { 1, 1 }, { 1, 0 }, { 2, 3 }, { 2, 1 }, { 2, 2 }, { 2, 0 }, { 3, 7 }, + { 3, 3 }, { 3, 5 }, { 3, 1 }, { 3, 6 }, { 3, 2 }, { 3, 4 }, { 3, 0 }, +}; + const ActorInit Obj_Hunsui_InitVars = { ACTOR_OBJ_HUNSUI, ACTORCAT_BG, @@ -22,42 +59,622 @@ const ActorInit Obj_Hunsui_InitVars = { (ActorFunc)ObjHunsui_Draw, }; -#endif +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), +}; -extern UNK_TYPE D_06000220; -extern UNK_TYPE D_06000C74; -extern UNK_TYPE D_06000EC0; +s32 func_80B9C450(GlobalContext* globalCtx, s32 arg1, s32 arg2) { + s32 sp2C = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9C450.s") + if (arg2 < ARRAY_COUNT(D_80B9DC70)) { + s32 val = D_80B9DC70[arg2].unk_00; + s32 val3 = D_80B9DC70[arg2].unk_01; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9C5E8.s") + while (val--) { + if ((1 << val) & val3) { + if (!Flags_GetSwitch(globalCtx, arg1 + val)) { + sp2C = 0; + break; + } + } else if (Flags_GetSwitch(globalCtx, arg1 + val)) { + sp2C = 0; + break; + } + } + } else { + sp2C = 0; + switch (arg2) { + case 14: + if (!Flags_GetSwitch(globalCtx, arg1)) { + sp2C = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/ObjHunsui_Init.s") + if (Flags_GetSwitch(globalCtx, arg1 + 1) && Flags_GetSwitch(globalCtx, arg1 + 2) && + Flags_GetSwitch(globalCtx, arg1 + 3)) { + sp2C += 2; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/ObjHunsui_Destroy.s") + case 15: + if (!Flags_GetSwitch(globalCtx, arg1) || + (Flags_GetSwitch(globalCtx, arg1 + 1) && Flags_GetSwitch(globalCtx, arg1 + 2) && + Flags_GetSwitch(globalCtx, arg1 + 3))) { + sp2C = 1; + } + break; + } + } + return sp2C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/ObjHunsui_Update.s") +void func_80B9C5E8(ObjHunsui* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 temp_f10; + f32 temp_f16; + Vec3f sp40; + s16 sp3E; + f32 sp38; + f32 sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9CE64.s") + if ((this->dyna.actor.xzDistToPlayer < (45.0f * this->dyna.actor.scale.x * 10.0f)) && + (this->dyna.actor.playerHeightRel < -21.0f)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + this->unk_172 &= ~8; + this->unk_19C = 0.0f; + this->unk_1A0 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D094.s") + this->unk_18C++; + if (this->unk_18C >= 3) { + this->unk_18C = 0; + Math_Vec3f_Copy(&sp40, &player->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D0FC.s") + sp40.x += randPlusMinusPoint5Scaled(10.0f); + sp40.z += randPlusMinusPoint5Scaled(10.0f); + sp40.y += Rand_ZeroFloat(2.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D120.s") + EffectSsGSplash_Spawn(globalCtx, &sp40, NULL, NULL, 2.0f * Rand_ZeroOne(), 1); + } + } else { + this->unk_172 |= 8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D288.s") + this->unk_18C++; + if (this->unk_18C >= 3) { + Math_Vec3f_Copy(&sp40, &player->actor.world.pos); + this->unk_18C = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D2BC.s") + sp40.x += randPlusMinusPoint5Scaled(10.0f); + sp40.z += randPlusMinusPoint5Scaled(10.0f); + sp40.y += Rand_ZeroFloat(45.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D334.s") + EffectSsGSplash_Spawn(globalCtx, &sp40, NULL, NULL, 1, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D4D0.s") + sp3E = BINANG_ROT180(player->actor.world.rot.y - this->dyna.actor.yawTowardsPlayer); + player->actor.gravity = 0.0f; + player->actor.velocity.y = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D508.s") + if ((this->unk_160 != OBJHUNSUI_F000_5) && (this->unk_160 != OBJHUNSUI_F000_6)) { + Math_SmoothStepToF(&player->actor.world.pos.y, this->dyna.actor.world.pos.y, 0.5f, 4.0f, 1.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9D714.s") + if ((sp3E < 0x4000) && (sp3E > -0x4000)) { + this->unk_1A4 = BINANG_ROT180(player->actor.world.rot.y); + sp34 = this->dyna.actor.xzDistToPlayer / (45.0f * this->dyna.actor.scale.x * 10.0f); + if (1) {} + sp38 = this->dyna.actor.xzDistToPlayer / (45.0f * this->dyna.actor.scale.x * 10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/ObjHunsui_Draw.s") + if (sp38 > 1.0f) { + sp38 = sp34; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hunsui/func_80B9DA60.s") + player->linearVelocity *= sp38; + + if ((this->unk_160 == OBJHUNSUI_F000_5) || (this->unk_160 == OBJHUNSUI_F000_6)) { + Math_ApproachF(&this->unk_1A0, 4.5f, 2.0f, 1.0f); + Math_ApproachF(&this->unk_19C, this->unk_1A0, 2.0f, 0.3f * sp38); + } else { + Math_ApproachF(&this->unk_1A0, 3.0f, 1.0f, 1.0f); + Math_ApproachF(&this->unk_19C, this->unk_1A0, 1.0f, 0.3f * sp38); + } + } else { + this->unk_1A4 = player->actor.world.rot.y; + player->linearVelocity *= 0.5f; + Math_ApproachF(&this->unk_1A0, 3.0f, 1.0f, 1.0f); + Math_ApproachF(&this->unk_19C, this->unk_1A0, 1.0f, 0.1f); + } + player->unk_B84 = this->unk_1A4; + player->unk_B80 = this->unk_19C; + } + } else { + if (this->unk_172 & 8) { + player->linearVelocity = this->unk_19C + player->linearVelocity; + player->currentYaw = this->unk_1A4; + } + this->unk_1A0 = 0.0f; + this->unk_19C = 0.0f; + this->unk_172 &= ~8; + } +} + +void ObjHunsui_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjHunsui* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->unk_160 = OBJHUNSUI_GET_F000(thisx); + this->unk_164 = OBJHUNSUI_GET_F80(thisx); + this->unk_168 = OBJHUNSUI_GET_7F(thisx); + DynaPolyActor_Init(&this->dyna, 1); + + if ((this->unk_160 != OBJHUNSUI_F000_5) && (this->unk_160 != OBJHUNSUI_F000_6)) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_hunsui_Colheader_000C74); + } + + D_80B9DED0 = Lib_SegmentedToVirtual(object_hunsui_Matanimheader_000BF0); + D_80B9DED4 = Lib_SegmentedToVirtual(object_hunsui_Matanimheader_001888); + SubS_FillCutscenesList(&this->dyna.actor, &this->unk_170, 1); + this->unk_18C = 0; + + switch (this->unk_160) { + case OBJHUNSUI_F000_1: + case OBJHUNSUI_F000_2: + case OBJHUNSUI_F000_3: + case OBJHUNSUI_F000_4: + case OBJHUNSUI_F000_5: + case OBJHUNSUI_F000_6: + this->dyna.actor.uncullZoneScale = 900.0f; + this->dyna.actor.uncullZoneDownward = 90.0f; + this->dyna.actor.uncullZoneForward = 4000.0f; + break; + } + + switch (this->unk_160) { + case OBJHUNSUI_F000_5: + if (D_80B9DED8.unk_01 == 0) { + D_80B9DED8.unk_01 = 1; + this->unk_16C = this->dyna.actor.room; + this->unk_16D = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.room = -1; + } else { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + break; + + case OBJHUNSUI_F000_6: + if (D_80B9DED8.unk_02 == 0) { + D_80B9DED8.unk_02 = 1; + this->unk_16C = this->dyna.actor.room; + this->unk_16D = this->dyna.actor.world.rot.z; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.room = -1; + } else { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + break; + } + + switch (this->unk_160) { + case OBJHUNSUI_F000_0: + if (D_80B9DED8.unk_00 == 0) { + D_80B9DED8.unk_00 = 1; + this->unk_16C = this->dyna.actor.room; + this->unk_16D = this->unk_164; + // clang-format off + this->dyna.actor.room = -1; this->actionFunc = func_80B9D714; + // clang-format on + } else { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + break; + + case OBJHUNSUI_F000_2: + this->unk_172 |= 1; + + case OBJHUNSUI_F000_1: + this->dyna.actor.draw = func_80B9DA60; + if ((this->unk_172 & 1) && func_80B9C450(globalCtx, this->unk_168, this->unk_164)) { + this->unk_174 = 240.0f; + this->unk_172 |= 4; + this->unk_184 = 0xFF0; + } else { + this->unk_174 = -30.0f; + this->unk_172 |= 2; + this->unk_184 = 0; + } + this->unk_178 = this->unk_174; + this->unk_180 = func_80B9C450(globalCtx, this->unk_168, this->unk_164); + this->actionFunc = func_80B9CE64; + break; + + case OBJHUNSUI_F000_4: + this->unk_172 |= 1; + + case OBJHUNSUI_F000_3: + case OBJHUNSUI_F000_5: + case OBJHUNSUI_F000_6: + this->dyna.actor.draw = func_80B9DA60; + if ((this->unk_160 == OBJHUNSUI_F000_5) || (this->unk_160 == OBJHUNSUI_F000_6)) { + func_80B9D2BC(this, globalCtx); + this->unk_178 = this->unk_174; + } else { + if ((this->unk_172 & 1) || func_80B9C450(globalCtx, this->unk_168, this->unk_164)) { + func_80B9D4D0(this, globalCtx); + } else { + func_80B9D0FC(this, globalCtx); + } + this->unk_178 = this->unk_174; + } + break; + } +} + +void ObjHunsui_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjHunsui* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void ObjHunsui_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjHunsui* this = THIS; + + this->actionFunc(this, globalCtx); + + if ((this->unk_172 & 0x40) && SubS_StartActorCutscene(&this->dyna.actor, this->unk_17C, -1, 0)) { + this->unk_172 &= ~0x40; + } + + if (this->unk_1AC > 1024.0f) { + this->unk_1AC -= 1024.0f; + } + + if (this->unk_1AC <= 0.0f) { + this->unk_1AC += 1024.0f; + } +} + +void func_80B9CE64(ObjHunsui* this, GlobalContext* globalCtx) { + s32 sp2C; + f32 sins; + + if (!(this->unk_172 & 2)) { + func_80B9C5E8(this, globalCtx); + } + + this->unk_18A += 0x71C; + Math_SmoothStepToF(&this->unk_190, this->unk_194, 1.0f, 0.2f, 0.01f); + + sp2C = func_80B9C450(globalCtx, this->unk_168, this->unk_164); + + if (!(this->unk_172 & 1)) { + if (sp2C != this->unk_180) { + this->unk_17C = this->unk_170; + this->unk_172 |= 0x40; + } + } + + if ((this->unk_172 & 1) || (sp2C != 0)) { + this->unk_172 &= ~2; + if (this->unk_186 == 0) { + this->unk_172 |= 0x10; + this->unk_174 = 240.0f; + if (this->unk_178 == 240.0f) { + if (this->unk_188++ > 40) { + this->unk_188 = 0; + this->unk_186 = 1; + this->unk_194 = 0.0f; + } else { + this->unk_194 = 8.0f; + } + } + } else { + this->unk_174 = 30.0f; + if (this->unk_178 == 30.0f) { + if (this->unk_188++ > 40) { + this->unk_188 = 0; + this->unk_186 = 0; + this->unk_194 = 0.0f; + } else { + this->unk_194 = 8.0f; + } + } + } + } else { + this->unk_174 = -30.0f; + if (this->unk_178 == -30.0f) { + this->unk_172 &= ~0x10; + this->unk_172 |= 2; + } + } + + sins = Math_SinS(this->unk_18A); + this->unk_198 = sins * this->unk_190; + if (!(this->unk_172 & 0x40)) { + Math_SmoothStepToF(&this->unk_178, this->unk_174, 0.6f, 10.5f, 0.05f); + } + + this->dyna.actor.world.pos.y = this->unk_198 + (this->dyna.actor.home.pos.y + this->unk_178); + this->unk_180 = sp2C; +} + +void func_80B9D094(ObjHunsui* this, GlobalContext* globalCtx) { + f32 sins; + + this->unk_18A += 0x71C; + Math_SmoothStepToF(&this->unk_190, this->unk_194, 1.0f, 0.2f, 0.01f); + sins = Math_SinS(this->unk_18A); + this->unk_198 = sins * this->unk_190; +} + +void func_80B9D0FC(ObjHunsui* this, GlobalContext* globalCtx) { + this->unk_174 = -30.0f; + this->actionFunc = func_80B9D120; +} + +void func_80B9D120(ObjHunsui* this, GlobalContext* globalCtx) { + if (((this->unk_160 == OBJHUNSUI_F000_5) || (this->unk_160 == OBJHUNSUI_F000_6)) && + (this->unk_16C != globalCtx->roomCtx.currRoom.num) && (this->unk_16C != globalCtx->roomCtx.prevRoom.num) && + ((this->unk_16D != globalCtx->roomCtx.currRoom.num) && (this->unk_16D != globalCtx->roomCtx.prevRoom.num))) { + switch (this->unk_160) { + case OBJHUNSUI_F000_5: + D_80B9DED8.unk_01 = 0; + break; + + case OBJHUNSUI_F000_6: + D_80B9DED8.unk_02 = 0; + break; + } + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + func_80B9D094(this, globalCtx); + if (!(this->unk_172 & 0x40)) { + Math_SmoothStepToF(&this->unk_178, this->unk_174, 0.6f, 10.5f, 0.05f); + } + + this->dyna.actor.world.pos.y = this->unk_198 + (this->dyna.actor.home.pos.y + this->unk_178); + if (this->unk_178 == this->unk_174) { + this->unk_172 &= ~0x10; + this->unk_172 |= 2; + } + + if (func_80B9C450(globalCtx, this->unk_168, this->unk_164)) { + this->unk_17C = this->unk_170; + this->unk_172 |= 0x40; + func_80B9D4D0(this, globalCtx); + } +} + +s32 func_80B9D288(GlobalContext* globalCtx, Actor* thisx, Actor* iter, void* verifyData) { + s32 ret = false; + + if (BGDBLUEMOVEBG_GET_F(iter) == BGDBLUEMOVEBG_F_8) { + ret = true; + } + return ret; +} + +void func_80B9D2BC(ObjHunsui* this, GlobalContext* globalCtx) { + if ((this->unk_172 & 1) || func_80B9C450(globalCtx, this->unk_168, this->unk_164)) { + func_80B9D4D0(this, globalCtx); + } else { + this->unk_172 |= 2; + func_80B9D0FC(this, globalCtx); + } +} + +void func_80B9D334(ObjHunsui* this, GlobalContext* globalCtx) { + Vec3f sp74; + s32 i; + s32 phi_s2 = 0; + s32 phi_s3; + + switch (this->unk_160) { + case OBJHUNSUI_F000_5: + phi_s2 = 1; + break; + + case OBJHUNSUI_F000_6: + break; + } + + if (this->unk_1B4 != NULL) { + phi_s3 = false; + for (i = 0; i < 8; i++) { + if (this->unk_1B4->unk_300[phi_s2][i] == (phi_s2 + 1)) { + phi_s3 = true; + Math_Vec3f_Copy(&sp74, &this->unk_1B4->unk_238[phi_s2][i]); + this->unk_174 = sp74.y - this->dyna.actor.home.pos.y; + if (this->unk_174 > 240.0f) { + this->unk_174 = 240.0f; + } + this->unk_190 = 0.0f; + this->unk_198 = 0.0f; + this->unk_18A = 0; + } + } + + if (!phi_s3) { + this->unk_174 = 240; + } + } else { + Actor* dblueMovebg = SubS_FindActorCustom(globalCtx, &this->dyna.actor, NULL, ACTORCAT_BG, + ACTOR_BG_DBLUE_MOVEBG, NULL, func_80B9D288); + + if (dblueMovebg != NULL) { + this->unk_1B4 = (BgDblueMovebg*)dblueMovebg; + func_80B9D2BC(this, globalCtx); + } + } +} + +void func_80B9D4D0(ObjHunsui* this, GlobalContext* globalCtx) { + this->unk_172 &= ~2; + this->unk_172 |= 0x10; + this->unk_174 = 240.0f; + this->actionFunc = func_80B9D508; +} + +void func_80B9D508(ObjHunsui* this, GlobalContext* globalCtx) { + if (((this->unk_160 == OBJHUNSUI_F000_5) || (this->unk_160 == OBJHUNSUI_F000_6)) && + (this->unk_16C != globalCtx->roomCtx.currRoom.num) && (this->unk_16C != globalCtx->roomCtx.prevRoom.num) && + (this->unk_16D != globalCtx->roomCtx.currRoom.num) && (this->unk_16D != globalCtx->roomCtx.prevRoom.num)) { + switch (this->unk_160) { + case OBJHUNSUI_F000_5: + D_80B9DED8.unk_01 = 0; + break; + + case OBJHUNSUI_F000_6: + D_80B9DED8.unk_02 = 0; + break; + } + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + func_80B9C5E8(this, globalCtx); + func_80B9D094(this, globalCtx); + + if (((this->unk_160 == OBJHUNSUI_F000_5) || (this->unk_160 == OBJHUNSUI_F000_6)) && + (globalCtx->roomCtx.currRoom.num == 8)) { + func_80B9D334(this, globalCtx); + } + + if (!(this->unk_172 & 0x40)) { + Math_SmoothStepToF(&this->unk_178, this->unk_174, 0.6f, 10.5f, 0.05f); + } + + this->dyna.actor.world.pos.y = this->unk_198 + (this->dyna.actor.home.pos.y + this->unk_178); + + if ((this->unk_160 == OBJHUNSUI_F000_6) || (this->unk_160 == OBJHUNSUI_F000_5)) { + this->unk_1AC += -10.0f + (1.8f * (this->dyna.actor.world.pos.y - this->dyna.actor.prevPos.y)); + this->unk_1B0 += -8.0f + (0.9f * (this->dyna.actor.world.pos.y - this->dyna.actor.prevPos.y)); + } + + if (!(this->unk_172 & 1) && !func_80B9C450(globalCtx, this->unk_168, this->unk_164)) { + this->unk_17C = this->unk_170; + this->unk_172 |= 0x40; + func_80B9D0FC(this, globalCtx); + } +} + +void func_80B9D714(ObjHunsui* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + s16 cs; + f32 sp28; + + if ((this->unk_16C != globalCtx->roomCtx.currRoom.num) && (this->unk_16C != globalCtx->roomCtx.prevRoom.num) && + (this->unk_16D != globalCtx->roomCtx.currRoom.num) && (this->unk_16D != globalCtx->roomCtx.prevRoom.num)) { + Actor_MarkForDeath(&this->dyna.actor); + } else { + if (Flags_GetSwitch(globalCtx, this->unk_168)) { + this->unk_172 &= ~2; + this->unk_172 |= 0x10; + cs = this->dyna.actor.cutscene; + + if (this->unk_16E == 0) { + if ((cs >= 0) && !ActorCutscene_GetCanPlayNext(cs)) { + ActorCutscene_SetIntentToPlay(cs); + } else if (cs >= 0) { + ActorCutscene_StartAndSetUnkLinkFields(cs, &this->dyna.actor); + this->unk_16E = -1; + } else { + this->unk_16E = 40; + } + } else if (this->unk_16E < 0) { + if (func_800F22C4(cs, &this->dyna.actor)) { + this->unk_16E = 40; + } + } else { + s32 pad; + + if (Math_SmoothStepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 800.0f, 0.1f, 8.0f, + 1.0f) < 0.5f) { + if (DECR(this->unk_16E) == 0) { + Flags_UnsetSwitch(globalCtx, this->unk_168); + } + } + this->dyna.actor.velocity.y = this->dyna.actor.world.pos.y - this->dyna.actor.prevPos.y; + } + } else { + Math_StepToF(&this->dyna.actor.velocity.y, -10.0f, 4.0f); + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; + if (this->dyna.actor.world.pos.y < this->dyna.actor.home.pos.y) { + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + this->unk_172 &= ~0x10; + this->unk_172 |= 2; + } + } + } + + if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + if (this->dyna.actor.xzDistToPlayer < 45.0f) { + if ((this->dyna.actor.playerHeightRel < -this->dyna.actor.velocity.y) && + (this->dyna.actor.playerHeightRel >= -800.0f)) { + sp28 = (45.0f - this->dyna.actor.xzDistToPlayer) * 0.5f; + player->actor.world.pos.x += sp28 * Math_SinS(this->dyna.actor.yawTowardsPlayer); + player->actor.world.pos.z += sp28 * Math_CosS(this->dyna.actor.yawTowardsPlayer); + } + } + } +} + +void ObjHunsui_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjHunsui* this = THIS; + + if (this->unk_172 & 0x10) { + f32 temp_f8 = (this->dyna.actor.world.pos.y - this->dyna.actor.home.pos.y) / 800.0f; + + func_8019FAD8(&this->dyna.actor.projectedPos, NA_SE_EV_WATER_PILLAR - SFX_FLAG, 1.0f + temp_f8); + } + + if (!(this->unk_172 & 2)) { + AnimatedMat_Draw(globalCtx, D_80B9DED0); + Gfx_DrawDListXlu(globalCtx, object_hunsui_DL_000220); + } +} + +void func_80B9DA60(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjHunsui* this = THIS; + f32 temp; + + if (this->unk_172 & 0x10) { + temp = 1.0f + ((this->unk_178 - 240.0f) / 270.0f); + func_8019FAD8(&this->dyna.actor.projectedPos, NA_SE_EV_WATER_PILLAR - SFX_FLAG, 1.0f + temp); + } + + if ((this->dyna.actor.flags & ACTOR_FLAG_40) && !(this->unk_172 & 2)) { + if ((this->unk_160 == OBJHUNSUI_F000_6) || (this->unk_160 == OBJHUNSUI_F000_5)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, (globalCtx->gameplayFrames % 128) * -9, 0x20, + 0x20, 1, 0, (globalCtx->gameplayFrames % 128) * -8, 0x20, 0x20)); + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, (s32)this->unk_1AC, 0x20, 0x20, 1, 0, + (s32)this->unk_1B0, 0x20, 0x20)); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + AnimatedMat_DrawXlu(globalCtx, D_80B9DED4); + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x7F, 255, 255, 255, 127); + + Gfx_DrawDListXlu(globalCtx, object_hunsui_DL_000EC0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.h b/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.h index e4bacf821..cbf1e4f13 100644 --- a/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.h +++ b/src/overlays/actors/ovl_Obj_Hunsui/z_obj_hunsui.h @@ -2,16 +2,56 @@ #define Z_OBJ_HUNSUI_H #include "global.h" +#include "overlays/actors/ovl_Bg_Dblue_Movebg/z_bg_dblue_movebg.h" struct ObjHunsui; typedef void (*ObjHunsuiActionFunc)(struct ObjHunsui*, GlobalContext*); +#define OBJHUNSUI_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJHUNSUI_GET_F80(thisx) (((thisx)->params >> 7) & 0x1F) +#define OBJHUNSUI_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) + +enum { + /* 0 */ OBJHUNSUI_F000_0, + /* 1 */ OBJHUNSUI_F000_1, + /* 2 */ OBJHUNSUI_F000_2, + /* 3 */ OBJHUNSUI_F000_3, + /* 4 */ OBJHUNSUI_F000_4, + /* 5 */ OBJHUNSUI_F000_5, + /* 6 */ OBJHUNSUI_F000_6, +}; + typedef struct ObjHunsui { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjHunsuiActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x58]; + /* 0x0160 */ s16 unk_160; + /* 0x0164 */ s32 unk_164; + /* 0x0168 */ s32 unk_168; + /* 0x016C */ s8 unk_16C; + /* 0x016D */ s8 unk_16D; + /* 0x016E */ s8 unk_16E; + /* 0x0170 */ s16 unk_170; + /* 0x0172 */ u16 unk_172; + /* 0x0174 */ f32 unk_174; + /* 0x0178 */ f32 unk_178; + /* 0x017C */ s16 unk_17C; + /* 0x0180 */ s32 unk_180; + /* 0x0184 */ s16 unk_184; + /* 0x0186 */ s16 unk_186; + /* 0x0188 */ s16 unk_188; + /* 0x018A */ s16 unk_18A; + /* 0x018C */ s16 unk_18C; + /* 0x0190 */ f32 unk_190; + /* 0x0194 */ f32 unk_194; + /* 0x0198 */ f32 unk_198; + /* 0x019C */ f32 unk_19C; + /* 0x01A0 */ f32 unk_1A0; + /* 0x01A4 */ s16 unk_1A4; + /* 0x0196 */ UNK_TYPE1 unk1A6[0x6]; + /* 0x01AC */ f32 unk_1AC; + /* 0x01B0 */ f32 unk_1B0; + /* 0x01B4 */ BgDblueMovebg* unk_1B4; } ObjHunsui; // size = 0x1B8 extern const ActorInit Obj_Hunsui_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c index 3715be349..bdffb1b52 100644 --- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c +++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.c @@ -1,6 +1,14 @@ -#include "z_obj_ice_poly.h" +/* + * File: z_obj_ice_poly.c + * Overlay: ovl_Obj_Ice_Poly + * Description: Large Block of Meltable Ice + */ -#define FLAGS 0x00000010 +#include "z_obj_ice_poly.h" +#include "overlays/actors/ovl_Obj_Aqua/z_obj_aqua.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjIcePoly*)thisx) @@ -9,11 +17,11 @@ void ObjIcePoly_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjIcePoly_Update(Actor* thisx, GlobalContext* globalCtx); void ObjIcePoly_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80931828(ObjIcePoly* this, GlobalContext* globalCtx); void func_80931A38(ObjIcePoly* this, GlobalContext* globalCtx); void func_80931E58(ObjIcePoly* this, GlobalContext* globalCtx); void func_80931EEC(ObjIcePoly* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Ice_Poly_InitVars = { ACTOR_OBJ_ICE_POLY, ACTORCAT_ITEMACTION, @@ -26,37 +34,327 @@ const ActorInit Obj_Ice_Poly_InitVars = { (ActorFunc)ObjIcePoly_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80932320 = { - { COLTYPE_HARD, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x02, 0x00 }, { 0xF7CFF7FF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x02, 0x00 }, + { 0xF7CFF7FF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 50, 105, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8093234C = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_NONE, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK5, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_NONE, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK5, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 65, 105, 0, { 0, 0, 0 } }, }; -#endif +static Color_RGBA8 D_80932378 = { 250, 250, 250, 255 }; +static Color_RGBA8 D_8093237C = { 180, 180, 180, 255 }; -extern ColliderCylinderInit D_80932320; -extern ColliderCylinderInit D_8093234C; +void ObjIcePoly_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjIcePoly* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/ObjIcePoly_Init.s") + this->unk_149 = OBJICEPOLY_GET_FF00(thisx); + thisx->params &= 0xFF; + thisx->uncullZoneForward = 5600.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/ObjIcePoly_Destroy.s") + Actor_SetScale(thisx, thisx->params * 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/func_80931828.s") + for (i = 0; i < ARRAY_COUNT(this->colliders1); i++) { + Collider_InitAndSetCylinder(globalCtx, &this->colliders1[i], thisx, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->colliders2[i], thisx, &sCylinderInit2); + Collider_UpdateCylinder(thisx, &this->colliders1[i]); + Collider_UpdateCylinder(thisx, &this->colliders2[i]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/func_80931A38.s") + this->colliders1[0].dim.radius = thisx->scale.x * 48.0f; + this->colliders1[0].dim.height = thisx->scale.y * 58.0f; + this->colliders2[0].dim.height = this->colliders1[0].dim.height; + this->colliders2[0].dim.radius = this->colliders1[0].dim.radius + 17; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/func_80931E58.s") + this->colliders1[1].dim.radius = thisx->scale.x * 23.0f; + this->colliders1[1].dim.height = thisx->scale.y * 50.0f; + this->colliders2[1].dim.radius = this->colliders1[1].dim.radius; + this->colliders2[1].dim.height = this->colliders1[1].dim.height; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/func_80931EEC.s") + this->colliders1[1].dim.yShift = this->colliders1[0].dim.height; + this->colliders2[1].dim.yShift = this->colliders1[1].dim.yShift; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/ObjIcePoly_Update.s") + thisx->colChkInfo.mass = MASS_IMMOVABLE; + this->unk_148 = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Ice_Poly/ObjIcePoly_Draw.s") + Actor_SetFocus(thisx, thisx->scale.y * 30.0f); + + thisx->shape.rot.x = 0x500; + thisx->shape.rot.z = -0x500; + + if (((this->unk_149 != OBJICEPOLY_FF_FF) && Flags_GetSwitch(globalCtx, this->unk_149)) || + ((globalCtx->sceneNum == SCENE_KAJIYA) && (gSaveContext.save.weekEventReg[33] & 0x80))) { + Actor_MarkForDeath(thisx); + return; + } + + this->actionFunc = func_80931A38; +} + +void ObjIcePoly_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjIcePoly* this = THIS; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->colliders1); i++) { + Collider_DestroyCylinder(globalCtx, &this->colliders1[i]); + Collider_DestroyCylinder(globalCtx, &this->colliders2[i]); + } +} + +void func_80931828(ObjIcePoly* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_80932380 = { 170, 255, 255, 255 }; + static Color_RGBA8 D_80932384 = { 0, 50, 100, 255 }; + static Vec3f D_80932388 = { 0.0f, -1.0f, 0.0f }; + f32 temp; + Vec3f spA0; + Vec3f sp94; + f32 sp90; + s32 i; + CollisionPoly* sp88; + + spA0.x = this->actor.world.pos.x; + spA0.y = (this->colliders1[0].dim.height * 2) + this->actor.world.pos.y; + spA0.z = this->actor.world.pos.z; + + sp90 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp88, &spA0); + if (sp90 < this->actor.world.pos.y) { + sp90 = this->actor.world.pos.y; + } + temp = spA0.y - sp90; + + for (i = 0; i < 30; i++) { + sp94.x = randPlusMinusPoint5Scaled(12.0f); + sp94.y = Rand_ZeroFloat(15.0f); + sp94.z = randPlusMinusPoint5Scaled(12.0f); + + spA0.x = (this->colliders1[0].dim.radius * (sp94.x * (1.0f / 12))) + this->actor.world.pos.x; + spA0.z = (this->colliders1[0].dim.radius * (sp94.z * (1.0f / 12))) + this->actor.world.pos.z; + spA0.y = Rand_ZeroFloat(temp) + sp90; + EffectSsEnIce_Spawn(globalCtx, &spA0, (Rand_ZeroFloat(0.4f) + 0.3f) * this->actor.scale.x, &sp94, &D_80932388, + &D_80932380, &D_80932384, 40); + } +} + +void func_80931A38(ObjIcePoly* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp6C; + s32 i; + s32 pad2; + s32 phi_v0; + s32 pad3; + f32 sp58; + + if (!(player->stateFlags2 & 0x4000) && (this->unk_14A != 0)) { + this->unk_14A--; + } + + if ((this->colliders1[0].base.atFlags & AT_HIT) || (this->colliders1[1].base.atFlags & AT_HIT)) { + this->unk_14A = 40; + this->colliders1[0].base.atFlags &= ~AT_HIT; + this->colliders1[1].base.atFlags &= ~AT_HIT; + } + + if (((this->colliders2[0].base.acFlags & AC_HIT) && + ((this->colliders2[0].base.ac == NULL) || + ((this->colliders2[0].base.ac->id != ACTOR_OBJ_AQUA) && + (this->colliders2[0].info.acHitInfo->toucher.dmgFlags == 0x800)) || + ((this->colliders2[0].base.ac->id == ACTOR_OBJ_AQUA) && + (this->colliders2[0].base.ac->params == OBJAQUA_1)))) || + ((this->colliders2[1].base.acFlags & AC_HIT) && + ((this->colliders2[1].base.ac == NULL) || + ((this->colliders2[1].base.ac->id != ACTOR_OBJ_AQUA) && + (this->colliders2[1].info.acHitInfo->toucher.dmgFlags == 0x800)) || + ((this->colliders2[1].base.ac->id == ACTOR_OBJ_AQUA) && + (this->colliders2[1].base.ac->params == OBJAQUA_1))))) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->unk_14A = 0; + this->actionFunc = func_80931E58; + this->actor.focus.rot.y = this->actor.yawTowardsPlayer; + + if (globalCtx->sceneNum == SCENE_00KEIKOKU) { + Actor* actor = NULL; + + do { + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_ITEMACTION, ACTOR_OBJ_ICE_POLY); + if (actor != NULL) { + if ((&this->actor != actor) && (&this->actor != actor)) { + ((ObjIcePoly*)actor)->unk_14A = 0; + ((ObjIcePoly*)actor)->actionFunc = func_80931E58; + } + actor = actor->next; + } + } while (actor != NULL); + } + } else if ((this->unk_149 != OBJICEPOLY_FF_FF) && Flags_GetSwitch(globalCtx, this->unk_149)) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->unk_14A = 1; + this->actionFunc = func_80931E58; + } else { + if ((this->actor.parent != NULL) && (this->actor.parent->update != NULL)) { + this->actor.parent->freezeTimer = 40; + } else { + this->actor.parent = NULL; + } + + if (this->unk_14A == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliders1[0].base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliders1[1].base); + } + + for (i = 0; i < ARRAY_COUNT(this->colliders1); i++) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliders1[i].base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliders1[i].base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliders2[i].base); + } + } + + if (Rand_ZeroOne() < 0.05f) { + sp58 = Rand_ZeroOne(); + if (Rand_ZeroOne() < 0.5f) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + sp6C.x = (phi_v0 * (15.0f + (sp58 * 15.0f)) * this->actor.scale.x) + this->actor.world.pos.x; + sp6C.y = (((Rand_ZeroOne() * 90.0f) + 10.0f) * this->actor.scale.y) + this->actor.world.pos.y; + + sp58 = Rand_ZeroOne(); + if (Rand_ZeroOne() < 0.5f) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + sp6C.z = (phi_v0 * (15.0f + (sp58 * 15.0f)) * this->actor.scale.z) + this->actor.world.pos.z; + + EffectSsKirakira_SpawnDispersed(globalCtx, &sp6C, &gZeroVec3f, &gZeroVec3f, &D_80932378, &D_8093237C, 2000, 5); + } +} + +void func_80931E58(ObjIcePoly* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + if (this->unk_14A == 1) { + func_80931828(this, globalCtx); + Actor_MarkForDeath(&this->actor); + } else { + this->unk_14A = 40; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_ICE_MELT); + this->actionFunc = func_80931EEC; + } + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80931EEC(ObjIcePoly* this, GlobalContext* globalCtx) { + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + f32 temp_f20; + s32 i; + s32 phi_v0; + + spAC.x = 0.0f; + spAC.y = this->actor.scale.y; + spAC.z = 0.0f; + + spA0.x = 0.0f; + spA0.y = this->actor.scale.y; + spA0.z = 0.0f; + + for (i = 0; i < 2; i++) { + temp_f20 = Rand_ZeroOne(); + if (Rand_ZeroOne() < 0.5f) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + sp94.x = (phi_v0 * (20.0f + (20.0f * temp_f20)) * this->actor.scale.x) + this->actor.world.pos.x; + sp94.y = (Rand_ZeroOne() * this->actor.scale.y * 50.0f) + this->actor.world.pos.y; + + temp_f20 = Rand_ZeroOne(); + if (Rand_ZeroOne() < 0.5f) { + phi_v0 = -1; + } else { + phi_v0 = 1; + } + sp94.z = (phi_v0 * (20.0f + (20.0f * temp_f20)) * this->actor.scale.x) + this->actor.world.pos.z; + + func_800B0DE0(globalCtx, &sp94, &spA0, &spAC, &D_80932378, &D_8093237C, + ((Rand_ZeroOne() * 100.0f) + 350.0f) * this->actor.scale.x, this->actor.scale.x * 20.0f); + } + + if (this->unk_14A != 0) { + this->unk_14A--; + } + + this->actor.scale.y = this->actor.params * 0.01f * (0.5f + (this->unk_14A * 0.0125f)); + this->unk_148 -= 6; + + if (this->unk_14A == 0) { + ActorCutscene_Stop(this->actor.cutscene); + if (this->unk_149 != OBJICEPOLY_FF_FF) { + Flags_SetSwitch(globalCtx, this->unk_149); + } + Actor_MarkForDeath(&this->actor); + } +} + +void ObjIcePoly_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjIcePoly* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjIcePoly_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjIcePoly* 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); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, globalCtx->gameplayFrames % 256, 0x20, 0x10, 1, 0, + (globalCtx->gameplayFrames * 2) % 256, 0x40, 0x20)); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, this->unk_148); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_050D10); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h index d23020f8a..b34866e3c 100644 --- a/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h +++ b/src/overlays/actors/ovl_Obj_Ice_Poly/z_obj_ice_poly.h @@ -7,10 +7,18 @@ struct ObjIcePoly; typedef void (*ObjIcePolyActionFunc)(struct ObjIcePoly*, GlobalContext*); +#define OBJICEPOLY_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +#define OBJICEPOLY_FF_FF 0xFF + typedef struct ObjIcePoly { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjIcePolyActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x134]; + /* 0x0148 */ u8 unk_148; + /* 0x0149 */ u8 unk_149; + /* 0x014A */ s16 unk_14A; + /* 0x014C */ ColliderCylinder colliders1[2]; + /* 0x01E4 */ ColliderCylinder colliders2[2]; } ObjIcePoly; // size = 0x27C extern const ActorInit Obj_Ice_Poly_InitVars; 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 d94173f1e..a4db0d04e 100644 --- a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c +++ b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c @@ -1,6 +1,13 @@ -#include "z_obj_iceblock.h" +/* + * File: z_obj_iceblock.c + * Overlay: ovl_Obj_Iceblock + * Description: Ice Block That Appears After Freezing Enemy + */ -#define FLAGS 0x00000010 +#include "z_obj_iceblock.h" +#include "objects/object_ice_block/object_ice_block.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjIceblock*)thisx) @@ -9,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 ObjIceBlock_SetupAttemptSpawnCutscene(ObjIceblock* this); +void ObjIceBlock_AttemptSpawnCutscene(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, @@ -22,158 +57,1508 @@ 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[] = { +static AnimatedMaterial* sCubeSublimatingAirTexMat = 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.terminalVelocity) { + this->dyna.actor.velocity.y = this->dyna.actor.terminalVelocity; + } + 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, true, false, false, true, &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, true, false, false, true, &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, true, false, false, true, &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 & ACTOR_FLAG_40) { + 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 & ACTOR_FLAG_40) { + 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 & ACTOR_FLAG_40) { + 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 & ACTOR_FLAG_40) { + 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_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(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_MultVec3f(&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_RotateYS(this->unk_254.y + this->dyna.actor.home.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->unk_254.x + this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(this->unk_254.z + this->dyna.actor.home.rot.z, MTXMODE_APPLY); + Matrix_Get(&sp40); + Matrix_MtxFToYXZRot(&sp40, &temp_s1->shape.rot, true); + } 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_F32_DIV1000(terminalVelocity, -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 (!GET_ICEBLOCK_SNAP_ROT(&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, &gIceBlockDynaColHeader); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + + if (GET_ICEBLOCK_ICEBERG(&this->dyna.actor)) { + this->collider.dim.yShift = -100; + this->collider.dim.height = 126; + this->collider.dim.radius = 29; + } + + if (sCubeSublimatingAirTexMat == NULL) { + sCubeSublimatingAirTexMat = Lib_SegmentedToVirtual(gIceBlockCubeSublimatingAirTexAnim); + } + + // ... this is init, why would this value be set? + 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 (GET_ICEBLOCK_ICEBERG(&this->dyna.actor)) { + this->unk_2B4 = -1.0f; + } + + this->unk_2B0 = 0; + this->extendedDrawFunc = func_80A26B64; + ObjIceBlock_SetupAttemptSpawnCutscene(this); + this->meltTimer = 450; // (450/20) = 22 seconds +} + +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 ObjIceBlock_SetupAttemptSpawnCutscene(ObjIceblock* this) { + this->actionFunc = ObjIceBlock_AttemptSpawnCutscene; +} + +void ObjIceBlock_AttemptSpawnCutscene(ObjIceblock* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->extendedDrawFunc = func_80A26BF8; + this->spawnCutsceneTimer = 80; + func_80A25824(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80A25824(ObjIceblock* this) { + this->actionFunc = func_80A2586C; + this->stateTimer = 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->stateTimer > 0) { + this->stateTimer--; + return; + } + + if (Math_StepToF(&this->dyna.actor.scale.x, 0.1f, 0.02f)) { + Actor_SetScale(&this->dyna.actor, 0.1f); + if (GET_ICEBLOCK_ICEBERG(&this->dyna.actor)) { + this->unk_2B4 = 0.05f; + } + func_80A25978(this); + } else { + Actor_SetScale(&this->dyna.actor, this->dyna.actor.scale.x); + this->stateTimer = 2; + } + + func_80A2319C(this, this->dyna.actor.scale.x); + + if (this->dyna.actor.flags & ACTOR_FLAG_40) { + 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->stateTimer = 4; +} + +void func_80A25994(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + + func_80A236D4(this, &this->dyna.actor.home.pos); + if (this->stateTimer > 0) { + this->stateTimer--; + return; + } + + if (this->dyna.actor.flags & ACTOR_FLAG_40) { + func_80A2339C(globalCtx, &this->dyna.actor.world.pos, this->dyna.actor.scale.x, 1.2f, 15); + if (GET_ICEBLOCK_ICEBERG(&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 (GET_ICEBLOCK_ICEBERG(&this->dyna.actor)) { + this->unk_2B4 = 0.1f; + } + + func_80A25A8C(this); + this->extendedDrawFunc = func_80A26B74; +} + +void func_80A25A8C(ObjIceblock* this) { + this->actionFunc = func_80A25AA8; + this->stateTimer = 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->stateTimer > 0) { + this->stateTimer--; + 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 (GET_ICEBLOCK_ICEBERG(&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)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + + if (func_80A24954(this, globalCtx)) { + func_80A2491C(this); + if (this->unk_2B0 == 3) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + func_80A2541C(this, globalCtx); + func_80A25CF4(this); + } else { + func_800B9010(&this->dyna.actor, NA_SE_PL_SLIP_ICE_LEVEL - SFX_FLAG); + } +} + +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) && + !Player_InCsMode(&globalCtx->state)) { + 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->stateTimer = 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->stateTimer > 0) { + this->stateTimer--; + } + + 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->stateTimer == 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) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + func_80A23B88(this); + func_80A25FA0(this); + } else { + func_800B9010(&this->dyna.actor, NA_SE_PL_SLIP_ICE_LEVEL - SFX_FLAG); + } + + func_80A24DD0(this, globalCtx); +} + +void func_80A262BC(ObjIceblock* this) { + this->actionFunc = func_80A262EC; + this->dyna.actor.velocity.y *= 0.7f; + this->stateTimer = -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->stateTimer > 0) { + this->stateTimer--; + } + + if (this->stateTimer == -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->stateTimer = 3; + } else { + this->stateTimer = 0; + } + } else if (this->stateTimer == 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->stateTimer = 40; +} + +void func_80A265C0(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + ObjIceBlockUnkStruct4* ptr; + + if (func_80A25238(this) != -1) { + func_80A2541C(this, globalCtx); + } + + if (this->stateTimer > 0) { + this->stateTimer--; + } else { + ptr = &this->unk_27C; + this->stateTimer = 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 (GET_ICEBLOCK_ICEBERG(&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->meltTimer > 0) { + this->meltTimer--; + } + } + + if (((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x800)) || + (this->meltTimer == 0)) { + this->meltTimer = -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); + } + + // this could have been in the actionFunc? + if (this->spawnCutsceneTimer > 0) { + this->spawnCutsceneTimer--; + if (this->spawnCutsceneTimer == 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 (GET_ICEBLOCK_ICEBERG(&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_SetFocus(&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) { +} + +// draw func +void func_80A26B74(ObjIceblock* this, GlobalContext* globalCtx) { + Gfx_DrawDListXlu(globalCtx, gIceBlockCubeDL); + if (GET_ICEBLOCK_ICEBERG(&this->dyna.actor) && (this->unk_2B4 > 0.0f)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gIceBlockIceBergSublimatingAirTexAnim)); + Gfx_DrawDListXlu(globalCtx, gIceBlockIceBergDL); + } +} + +// draw func +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_SetTranslateRotateYXZ(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++, gIceBlockCubeDL); + } + + if (GET_ICEBLOCK_ICEBERG(&this->dyna.actor) && (this->unk_2B4 > 0.0f)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gIceBlockIceBergSublimatingAirTexAnim)); + Matrix_SetTranslateRotateYXZ(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++, gIceBlockIceBergDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjIceblock_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjIceblock* this = THIS; + + AnimatedMat_Draw(globalCtx, sCubeSublimatingAirTexMat); + this->extendedDrawFunc(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..52460b87d 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 (*ObjIceblockExtendedDrawFunc)(struct ObjIceblock*, GlobalContext*); + +#define GET_ICEBLOCK_SNAP_ROT(thisx) (((thisx)->params >> 1) & 1) +#define GET_ICEBLOCK_ICEBERG(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 */ ObjIceblockExtendedDrawFunc extendedDrawFunc; + /* 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 stateTimer; // re-used per-actionFunc + /* 0x02A2 */ s16 unk_2A2; + /* 0x02A4 */ f32 unk_2A4; + /* 0x02A8 */ f32 unk_2A8; + /* 0x02AC */ s16 unk_2AC; + /* 0x02AE */ s16 meltTimer; // starts at 450 frames = 22 seconds + /* 0x02B0 */ s8 unk_2B0; + /* 0x02B1 */ s8 spawnCutsceneTimer; + /* 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 eed1be594..53d1d7669 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 @@ -1,6 +1,13 @@ -#include "z_obj_jg_gakki.h" +/* + * File: z_obj_jg_gakki.c + * Overlay: ovl_Obj_Jg_Gakki + * Description: Goron Elder's Drum + */ -#define FLAGS 0x00000020 +#include "z_obj_jg_gakki.h" +#include "objects/object_jg/object_jg.h" + +#define FLAGS (ACTOR_FLAG_20) #define THIS ((ObjJgGakki*)thisx) @@ -9,7 +16,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, @@ -22,14 +28,39 @@ const ActorInit Obj_Jg_Gakki_InitVars = { (ActorFunc)ObjJgGakki_Draw, }; -#endif +void ObjJgGakki_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjJgGakki* this = THIS; + f32 frameCount = Animation_GetLastFrame(&gGoronElderDrumTakeOutAnim); -extern UNK_TYPE D_0601B1E8; + ActorShape_Init(&this->actor.shape, 0.0f, ActorShadow_DrawCircle, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &gGoronElderDrumSkel, NULL, NULL, NULL, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Init.s") + if (((globalCtx->sceneNum == SCENE_SPOT00) && (gSaveContext.sceneSetupIndex == 7)) && + (globalCtx->csCtx.currentCsIndex == 0)) { + Animation_Change(&this->skelAnime, &gGoronElderDrumTakeOutAnim, 1.0f, frameCount, frameCount, 2, 0.0f); + } else if ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA)) { + Animation_Change(&this->skelAnime, &gGoronElderDrumTakeOutAnim, 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_Destroy.s") +void ObjJgGakki_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjJgGakki* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Update.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Draw.s") +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_Jgame_Light/z_obj_jgame_light.c b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c index 56fd79ff7..68e7717c1 100644 --- a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c +++ b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_jgame_light.c + * Overlay: ovl_Obj_Jgame_Light + * Description: Fisherman's Jumping Game - Torch + */ + #include "z_obj_jgame_light.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjJgameLight*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h index 12d958e73..50023c252 100644 --- a/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h +++ b/src/overlays/actors/ovl_Obj_Jgame_Light/z_obj_jgame_light.h @@ -5,6 +5,8 @@ struct ObjJgameLight; +#define OBJJGAMELIGHT_GET_7F(thisx) ((thisx)->params & 0x7F) + typedef struct ObjJgameLight { /* 0x000 */ Actor actor; /* 0x144 */ char unk_144[0x78]; diff --git a/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.c b/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.c index 6d3a16e56..1ca1c4b58 100644 --- a/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.c +++ b/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_kendo_kanban.c + * Overlay: ovl_Obj_Kendo_Kanban + * Description: Swordsman's School - Cuttable Board + */ + #include "z_obj_kendo_kanban.h" +#include "objects/object_dora/object_dora.h" #define FLAGS 0x00000000 @@ -9,11 +16,14 @@ void ObjKendoKanban_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjKendoKanban_Update(Actor* thisx, GlobalContext* globalCtx); void ObjKendoKanban_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B65880(ObjKendoKanban* this); void func_80B65894(ObjKendoKanban* this, GlobalContext* globalCtx); +void func_80B658A4(ObjKendoKanban* this, GlobalContext* globalCtx); void func_80B65CE0(ObjKendoKanban* this, GlobalContext* globalCtx); void func_80B65D68(ObjKendoKanban* this, GlobalContext* globalCtx); +void func_80B65DA8(ObjKendoKanban* this, GlobalContext* globalCtx); +s32 func_80B6618C(ObjKendoKanban* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Kendo_Kanban_InitVars = { ACTOR_OBJ_KENDO_KANBAN, ACTORCAT_NPC, @@ -26,33 +36,89 @@ const ActorInit Obj_Kendo_Kanban_InitVars = { (ActorFunc)ObjKendoKanban_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[2] = { -static ColliderTrisElementInit D_80B6673C[2] = { +Vec3f D_80B66660 = { -1.5f, 10.0f, 0.5f }; +Vec3f D_80B6666C = { 1.5f, 10.0f, 0.5f }; +Vec3f D_80B66678 = { 0.0f, 4.0f, -1.0f }; +Vec3f D_80B66684 = { 1.0f, 7.0f, 4.0f }; +Vec3f D_80B66690 = { -150.0f, 425.0f, 40.0f }; +Vec3f D_80B6669C = { 150.0f, 425.0f, 40.0f }; +Vec3f D_80B666A8 = { 0.0f, 140.0f, 40.0f }; +Vec3f D_80B666B4 = { 0.0f, 565.0f, 40.0f }; + +Gfx* D_80B666C0 = gKendoKanbanTopRightDL; +Gfx* D_80B666C4 = gKendoKanbanTopLeftDL; +Gfx* D_80B666C8 = gKendoKanbanBottomRightDL; +Gfx* D_80B666CC = gKendoKanbanBottomLeftDL; + +Vec3f D_80B666D0 = { -300.0f, 850.0f, 40.0f }; +Vec3f D_80B666DC = { 10.0f, 850.0f, 40.0f }; +Vec3f D_80B666E8 = { 300.0f, 850.0f, 40.0f }; +Vec3f D_80B666F4 = { -300.0f, 310.0f, 40.0f }; +Vec3f D_80B66700 = { 0.0f, 280.0f, 40.0f }; +Vec3f D_80B6670C = { 300.0f, 250.0f, 40.0f }; +Vec3f D_80B66718 = { -300.0f, 10.0f, 40.0f }; +Vec3f D_80B66724 = { 0.0f, 10.0f, 40.0f }; +Vec3f D_80B66730 = { 300.0f, 10.0f, 40.0f }; + +static ColliderTrisElementInit sTrisElementsInit[] = { { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0x01000202, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -300.0f, 850.0f, 40.0f }, { -300.0f, 10.0f, 40.0f }, { 300.0f, 850.0f, 40.0f } } }, }, { - { ELEMTYPE_UNK5, { 0x00000000, 0x00, 0x00 }, { 0x01000202, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK5, + { 0x00000000, 0x00, 0x00 }, + { 0x01000202, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 300.0f, 850.0f, 40.0f }, { 300.0f, 10.0f, 40.0f }, { -300.0f, 10.0f, 40.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B667B4 = { - { COLTYPE_TREE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, }, - 2, D_80B6673C, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_TREE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + 2, + sTrisElementsInit, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B667C4 = { - { COLTYPE_TREE, 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 | BUMP_HOOKABLE, 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 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 33, 80, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B667F0 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -87,41 +153,357 @@ static DamageTable D_80B667F0 = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B66810 = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -#endif +Vec3f D_80B6681C = { 0.0f, 0.0f, 0.0f }; +Vec3f D_80B66828 = { 1.0f, 0.0f, 0.0f }; -extern ColliderTrisElementInit D_80B6673C[2]; -extern ColliderTrisInit D_80B667B4; -extern ColliderCylinderInit D_80B667C4; -extern DamageTable D_80B667F0; -extern CollisionCheckInfoInit2 D_80B66810; +void ObjKendoKanban_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad[2]; + ObjKendoKanban* this = THIS; + Vec3f sp70[3]; + s32 i; + s32 j; -extern UNK_TYPE D_06000180; + Actor_SetScale(&this->actor, 0.1f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/ObjKendoKanban_Init.s") + Collider_InitCylinder(globalCtx, &this->colliderCylinder); + Collider_SetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Collider_InitTris(globalCtx, &this->colliderTris); + Collider_SetTris(globalCtx, &this->colliderTris, &this->actor, &sTrisInit, this->colliderTrisElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/ObjKendoKanban_Destroy.s") + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65880.s") + for (i = 0; i < ARRAY_COUNT(this->colliderTrisElements); i++) { + for (j = 0; j < ARRAY_COUNT(sp70); j++) { + Matrix_MultVec3f(&sTrisElementsInit[i].dim.vtx[j], &sp70[j]); + } + Collider_SetTrisVertices(&this->colliderTris, i, &sp70[0], &sp70[1], &sp70[2]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65894.s") + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B658A4.s") + this->unk_30C = OBJKENDOKANBAN_GET_F(&this->actor); + this->actor.gravity = -2.0f; + this->unk_2CC = D_80B6681C; + this->unk_2D8 = D_80B6681C; + this->unk_2E4 = D_80B6681C; + this->unk_2F0 = D_80B66828; + this->unk_302 = 0; + this->unk_304 = 0; + this->unk_2FC = -1; + this->unk_300 = 0; + this->unk_308 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65CE0.s") + for (i = 0; i < ARRAY_COUNT(this->unk_26C); i++) { + this->unk_26C[i] = this->unk_29C[i] = D_80B6681C; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65D54.s") + this->unk_30A = 0; + if (this->unk_30C == OBJKENDOKANBAN_F_0) { + func_80B65880(this); + } else { + func_80B658A4(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65D68.s") +void ObjKendoKanban_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjKendoKanban* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B65DA8.s") + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroyTris(globalCtx, &this->colliderTris); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B6618C.s") +void func_80B65880(ObjKendoKanban* this) { + this->actionFunc = func_80B65894; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/func_80B66304.s") +void func_80B65894(ObjKendoKanban* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/ObjKendoKanban_Update.s") +void func_80B658A4(ObjKendoKanban* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + if (this->unk_30C == OBJKENDOKANBAN_F_0) { + if ((player->swordAnimation == 0) || (player->swordAnimation == 1) || (player->swordAnimation == 0x14)) { + this->unk_30C = (OBJKENDOKANBAN_F_4 | OBJKENDOKANBAN_F_1); + this->unk_304 = 0x71C; + this->actor.velocity = D_80B6666C; + this->unk_2CC = D_80B6669C; + + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_KENDO_KANBAN, + this->actor.home.pos.x - 5.0f, this->actor.home.pos.y, this->actor.home.pos.z, 0, 0, 0, + 0xA); + + this->unk_29C[0] = D_80B666DC; + this->unk_29C[1] = D_80B666E8; + this->unk_29C[2] = D_80B66730; + this->unk_29C[3] = D_80B66724; + } else { + this->unk_30C = (OBJKENDOKANBAN_F_8 | OBJKENDOKANBAN_F_4); + this->unk_304 = -0x71C; + this->actor.velocity = D_80B66678; + this->unk_2CC = D_80B666A8; + + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_OBJ_KENDO_KANBAN, + this->actor.home.pos.x, this->actor.home.pos.y + 5.0f, this->actor.home.pos.z, 0, 0, 0, + 3); + + this->unk_29C[0] = D_80B666F4; + this->unk_29C[1] = D_80B6670C; + this->unk_29C[2] = D_80B66730; + this->unk_29C[3] = D_80B66718; + } + } else if (this->unk_30C == (OBJKENDOKANBAN_F_8 | OBJKENDOKANBAN_F_2)) { + this->unk_304 = 0x71C; + this->actor.velocity = D_80B66660; + this->unk_2CC = D_80B66690; + + this->unk_29C[0] = D_80B666D0; + this->unk_29C[1] = D_80B666DC; + this->unk_29C[2] = D_80B66724; + this->unk_29C[3] = D_80B66718; + } else if (this->unk_30C == (OBJKENDOKANBAN_F_2 | OBJKENDOKANBAN_F_1)) { + this->unk_304 = 0x71C; + this->actor.velocity = D_80B66684; + this->unk_2CC = D_80B666B4; + + this->unk_29C[0] = D_80B666D0; + this->unk_29C[1] = D_80B666E8; + this->unk_29C[2] = D_80B6670C; + this->unk_29C[3] = D_80B666F4; + } + + this->unk_30A = 0; + this->actionFunc = func_80B65CE0; +} + +void func_80B65CE0(ObjKendoKanban* this, GlobalContext* globalCtx) { + this->actor.velocity.y += this->actor.gravity; + Actor_UpdatePos(&this->actor); + this->unk_302 += this->unk_304; + func_80B65DA8(this, globalCtx); + if (this->actor.world.pos.y < -200.0f) { + this->actor.world.pos.y = -200.0f; + } +} + +void func_80B65D54(ObjKendoKanban* this) { + this->actionFunc = func_80B65D68; +} + +void func_80B65D68(ObjKendoKanban* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_80B6618C(this, globalCtx) == 1) { + player->unk_AC0 = 700.0f; + } +} + +void func_80B65DA8(ObjKendoKanban* this, GlobalContext* globalCtx) { + Vec3f sp5C; + s32 pad[2]; + Vec3f sp48; + s32 pad2; + s32 index = 0; + s32 i; + f32 sp38; + + sp5C = this->unk_26C[0]; + sp48 = this->actor.world.pos; + + sp48.x -= this->unk_2D8.x; + sp48.y -= this->unk_2D8.y; + sp48.z -= this->unk_2D8.z; + + sp38 = (this->unk_2F0.x * sp48.z) + (this->unk_2F0.z * -sp48.x); + + if (sp38 < 0.0f) { + this->unk_304 += 0x64; + } else { + this->unk_304 -= 0x64; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_26C); i++) { + if (this->unk_26C[i].y < sp5C.y) { + sp5C = this->unk_26C[i]; + index = i; + } + } + + if (index != this->unk_2FC) { + this->unk_300 = 1; + this->unk_2FC = index; + this->unk_2E4 = this->unk_29C[index]; + + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_MultVec3f(&this->unk_2E4, &this->actor.world.pos); + this->actor.world.pos = sp5C; + this->actor.prevPos = this->actor.world.pos; + Matrix_Pop(); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + if (this->actor.bgCheckFlags & 1) { + this->actor.velocity.x *= 0.8f; + this->actor.velocity.z *= 0.8f; + } + + if (this->unk_300 == 1) { + if (this->unk_308 >= 7) { + s16 temp_v0_3 = this->unk_302 & 0x3FFF; + + if (temp_v0_3 >= 0x2000) { + temp_v0_3 -= 0x4000; + } + this->unk_302 -= temp_v0_3; + this->unk_304 = 0; + func_80B65D54(this); + return; + } + + if (this->actor.bgCheckFlags & 2) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + this->unk_300 = 0; + this->actor.velocity.y *= 0.5f; + } else if (this->actor.bgCheckFlags & 1) { + this->unk_308++; + this->unk_300 = 0; + this->actor.velocity.x *= 0.3f; + this->actor.velocity.z *= 0.3f; + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_WOODPLATE_BOUND); + + if (sp38 > 0.0f) { + if (this->unk_304 > 0) { + this->unk_304 *= 1.2f; + } else { + this->unk_304 *= -0.6f; + } + } else if (this->unk_304 < 0) { + this->unk_304 *= 1.2f; + } else { + this->unk_304 *= -0.6f; + } + } + } +} + +s32 func_80B6618C(ObjKendoKanban* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 phi_v0; + s32 phi_v1 = 0; + s32 i; + f32 x; + f32 z; + f32 x2; + f32 z2; + + for (i = 0; i < ARRAY_COUNT(this->unk_26C); i++) { + if (i != 3) { + phi_v0 = i + 1; + } else { + phi_v0 = 0; + } + + z = this->unk_26C[i].z - player->actor.world.pos.z; + x = this->unk_26C[i].x - player->actor.world.pos.x; + + z2 = (this->unk_26C[phi_v0].z - player->actor.world.pos.z); + x2 = (this->unk_26C[phi_v0].x - player->actor.world.pos.x); + + if ((x * z2) < (z * x2)) { + if (phi_v1 == 0) { + phi_v1 = 1; + } else if (phi_v1 != 1) { + return false; + } + } else if (phi_v1 == 0) { + phi_v1 = -1; + } else if (phi_v1 != -1) { + return false; + } + } + return true; +} + +void func_80B66304(ObjKendoKanban* this, GlobalContext* globalCtx) { + if ((this->actionFunc != func_80B65CE0) && (this->actionFunc != func_80B65D68)) { + if (this->colliderTris.base.acFlags & AC_HIT) { + this->colliderTris.base.acFlags &= ~AC_HIT; + func_80B658A4(this, globalCtx); + } + + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + this->colliderCylinder.dim.pos.z -= (s16)(20.0f * Math_CosS(this->actor.shape.rot.y)); + this->colliderCylinder.dim.pos.x -= (s16)(20.0f * Math_SinS(this->actor.shape.rot.y)); + + if (this->actionFunc == func_80B65894) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } +} + +void ObjKendoKanban_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjKendoKanban* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80B66304(this, globalCtx); +} + +#ifdef NON_MATCHING +void ObjKendoKanban_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjKendoKanban* this = THIS; + s32 i; + Gfx* poly; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_30C == OBJKENDOKANBAN_F_0) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gKendoKanbanDL); + } else { + Matrix_RotateAxisS(this->unk_302, &this->unk_2F0, MTXMODE_APPLY); + Matrix_Translate(-this->unk_2E4.x, -this->unk_2E4.y, -this->unk_2E4.z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->unk_30C & OBJKENDOKANBAN_F_1) { + gSPDisplayList(POLY_OPA_DISP++, D_80B666C0); + } + + if (this->unk_30C & OBJKENDOKANBAN_F_2) { + gSPDisplayList(POLY_OPA_DISP++, D_80B666C4); + } + + if (this->unk_30C & OBJKENDOKANBAN_F_4) { + gSPDisplayList(POLY_OPA_DISP++, D_80B666C8); + } + + if (this->unk_30C & OBJKENDOKANBAN_F_8) { + gSPDisplayList(POLY_OPA_DISP++, D_80B666CC); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_26C); i++) { + Matrix_MultVec3f(&this->unk_29C[i], &this->unk_26C[i]); + } + + Matrix_MultVec3f(&this->unk_2CC, &this->unk_2D8); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kendo_Kanban/ObjKendoKanban_Draw.s") +#endif diff --git a/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.h b/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.h index 6adb95dd1..a8c4f8d7c 100644 --- a/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.h +++ b/src/overlays/actors/ovl_Obj_Kendo_Kanban/z_obj_kendo_kanban.h @@ -7,11 +7,34 @@ struct ObjKendoKanban; typedef void (*ObjKendoKanbanActionFunc)(struct ObjKendoKanban*, GlobalContext*); +#define OBJKENDOKANBAN_GET_F(thisx) ((thisx)->params & 0xF) + +#define OBJKENDOKANBAN_F_0 0 +#define OBJKENDOKANBAN_F_1 (1 << 0) +#define OBJKENDOKANBAN_F_2 (1 << 1) +#define OBJKENDOKANBAN_F_4 (1 << 2) +#define OBJKENDOKANBAN_F_8 (1 << 3) + typedef struct ObjKendoKanban { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x124]; + /* 0x0144 */ ColliderCylinder colliderCylinder; + /* 0x0190 */ ColliderTris colliderTris; + /* 0x01B0 */ ColliderTrisElement colliderTrisElements[2]; /* 0x0268 */ ObjKendoKanbanActionFunc actionFunc; - /* 0x026C */ char unk_26C[0xA4]; + /* 0x026C */ Vec3f unk_26C[4]; + /* 0x029C */ Vec3f unk_29C[4]; + /* 0x02CC */ Vec3f unk_2CC; + /* 0x02D8 */ Vec3f unk_2D8; + /* 0x02E4 */ Vec3f unk_2E4; + /* 0x02F0 */ Vec3f unk_2F0; + /* 0x02FC */ s32 unk_2FC; + /* 0x0300 */ s16 unk_300; + /* 0x0302 */ s16 unk_302; + /* 0x0304 */ s16 unk_304; + /* 0x0306 */ UNK_TYPE1 pad306[2]; + /* 0x0308 */ s16 unk_308; + /* 0x030A */ s16 unk_30A; + /* 0x030C */ u8 unk_30C; } ObjKendoKanban; // size = 0x310 extern const ActorInit Obj_Kendo_Kanban_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Kepn_Koya/z_obj_kepn_koya.c b/src/overlays/actors/ovl_Obj_Kepn_Koya/z_obj_kepn_koya.c index 09f345323..4f8bc1d3a 100644 --- a/src/overlays/actors/ovl_Obj_Kepn_Koya/z_obj_kepn_koya.c +++ b/src/overlays/actors/ovl_Obj_Kepn_Koya/z_obj_kepn_koya.c @@ -1,4 +1,11 @@ +/* + * File: z_obj_kepn_koya.c + * Overlay: ovl_Obj_Kepn_Koya + * Description: Gorman Bros. Buildings + */ + #include "z_obj_kepn_koya.h" +#include "objects/object_kepn_koya/object_kepn_koya.h" #define FLAGS 0x00000000 @@ -26,17 +33,14 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 900, ICHAIN_STOP), }; -extern CollisionHeader D_0600805C; -extern Gfx D_06003478[]; - void ObjKepnKoya_Init(Actor* thisx, GlobalContext* globalCtx) { ObjKepnKoya* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); Actor_SetScale(&this->dyna.actor, 0.1f); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_0600805C); - if (this->dyna.bgId == 0x32) { + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_kepn_koya_Colheader_00805C); + if (this->dyna.bgId == BG_ACTOR_MAX) { Actor_MarkForDeath(&this->dyna.actor); } } @@ -44,12 +48,12 @@ void ObjKepnKoya_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjKepnKoya_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjKepnKoya* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjKepnKoya_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjKepnKoya_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06003478); + Gfx_DrawDListOpa(globalCtx, object_kepn_koya_DL_003478); } 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 3fc376dc4..979848c3b 100644 --- a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c +++ b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c @@ -5,8 +5,10 @@ */ #include "z_obj_kibako.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_kibako/object_kibako.h" -#define FLAGS 0x04000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_4000000) #define THIS ((ObjKibako*)thisx) @@ -66,30 +68,27 @@ 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), - ICHAIN_F32_DIV1000(minVelocityY, -18000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -18000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 60, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 60, ICHAIN_STOP), }; void ObjKibako_SpawnCollectible(ObjKibako* this, GlobalContext* globalCtx) { - s32 collectible; + s32 dropItem00Id; if (this->isDropCollected == 0) { - collectible = func_800A8150(KIBAKO_COLLECTIBLE_ID(&this->actor)); - if (collectible >= 0) { + dropItem00Id = func_800A8150(KIBAKO_COLLECTIBLE_ID(&this->actor)); + if (dropItem00Id > ITEM00_NO_DROP) { Item_DropCollectible(globalCtx, &this->actor.world.pos, - collectible | KIBAKO_COLLECTIBLE_FLAG(&this->actor) << 8); + dropItem00Id | KIBAKO_COLLECTIBLE_FLAG(&this->actor) << 8); this->isDropCollected = 1; } } @@ -97,7 +96,7 @@ void ObjKibako_SpawnCollectible(ObjKibako* this, GlobalContext* globalCtx) { void ObjKibako_SetShadow(ObjKibako* this) { if ((this->actor.projectedPos.z < 370.0f) && (this->actor.projectedPos.z > -10.0f)) { - this->actor.shape.shadowDraw = func_800B4024; + this->actor.shape.shadowDraw = ActorShadow_DrawSquare; this->actor.shape.shadowScale = 1.4f; this->actor.shape.shadowAlpha = (this->actor.projectedPos.z < 200.0f) ? 100 : (400 - ((s32)this->actor.projectedPos.z)) >> 1; @@ -121,8 +120,8 @@ void func_80926318(ObjKibako* this, GlobalContext* globalCtx) { if (this->actor.xzDistToPlayer < 100.0f) { angle = this->actor.yawTowardsPlayer - GET_PLAYER(globalCtx)->actor.world.rot.y; - if (ABS_ALT(angle) >= 0x5556) { - func_800B8A1C(&this->actor, globalCtx, 0, 36.0f, 30.0f); + if (ABS_ALT(angle) > 0x5555) { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 36.0f, 30.0f); } } } @@ -134,8 +133,8 @@ void func_80926394(ObjKibako* this, GlobalContext* globalCtx) { } void ObjKibako_Init(Actor* thisx, GlobalContext* globalCtx2) { - ObjKibako* this = THIS; GlobalContext* globalCtx = globalCtx2; + ObjKibako* this = THIS; s32 whichBankIndex; whichBankIndex = KIBAKO_BANK_INDEX(thisx); @@ -213,7 +212,7 @@ void ObjKibako_WaterBreak(ObjKibako* this, GlobalContext* globalCtx) { Vec3f pos; Vec3f velocity; - pos.y = worldPos->y + this->actor.yDistToWater; + pos.y = worldPos->y + this->actor.depthInWater; for (angle = 0, i = 0; i < 5; i++, angle += 0x3333) { pos.x = (Math_SinS(((s32)(Rand_ZeroOne() * 6000.0f)) + angle) * 15.0f) + worldPos->x; pos.z = (Math_CosS(((s32)(Rand_ZeroOne() * 6000.0f)) + angle) * 15.0f) + worldPos->z; @@ -252,7 +251,7 @@ void func_80926B40(ObjKibako* this) { } void func_80926B54(ObjKibako* this, GlobalContext* globalCtx) { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 18.0f, 15.0f, 0.0f, 0x45); if (Object_IsLoaded(&globalCtx->objectCtx, this->bankIndex)) { this->actor.draw = ObjKibako_Draw; @@ -272,24 +271,27 @@ void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx) { if (Actor_HasParent(&this->actor, globalCtx)) { ObjKibako_SetupHeld(this); this->actor.room = -1; - this->actor.colChkInfo.mass = 0x78; + this->actor.colChkInfo.mass = 120; if (func_800A817C(KIBAKO_COLLECTIBLE_ID(&this->actor))) { ObjKibako_SpawnCollectible(this, globalCtx); } - func_800B8E58(&this->actor, NA_SE_PL_PULL_UP_WOODBOX); - } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.yDistToWater > 19.0f)) { + + //! @bug: This function should only pass Player*: it uses *(this + 0x153), which is meant to be + //! player->currentMask, but in this case is garbage in the collider + func_800B8E58((Player*)this, NA_SE_PL_PULL_UP_WOODBOX); + } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 19.0f)) { ObjKibako_WaterBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); Actor_MarkForDeath(&this->actor); } else if (this->collider.base.acFlags & AC_HIT) { ObjKibako_AirBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); Actor_MarkForDeath(&this->actor); } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); func_809262BC(this); Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 18.0f, 15.0f, 0.0f, 0x45); @@ -298,7 +300,7 @@ void ObjKibako_Idle(ObjKibako* this, GlobalContext* globalCtx) { } if ((this->actor.colChkInfo.mass != MASS_IMMOVABLE) && - (Math3D_DistanceSquared(&this->actor.world.pos, &this->actor.prevPos) < 0.01f)) { + (Math3D_Vec3fDistSq(&this->actor.world.pos, &this->actor.prevPos) < 0.01f)) { this->actor.colChkInfo.mass = MASS_IMMOVABLE; } @@ -333,7 +335,7 @@ void ObjKibako_SetupHeld(ObjKibako* this) { void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx) { s32 pad; Vec3f pos; - s32 sp2C; + s32 bgId; func_80926394(this, globalCtx); if (Actor_HasNoParent(&this->actor, globalCtx)) { @@ -341,18 +343,19 @@ void ObjKibako_Held(ObjKibako* this, GlobalContext* globalCtx) { if (fabsf(this->actor.speedXZ) < 0.1f) { ObjKibako_SetupIdle(this); this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_PUT_DOWN_WOODBOX); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_PUT_DOWN_WOODBOX); } else { - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); ObjKibako_SetupThrown(this); - this->actor.flags &= ~0x4000000; + this->actor.flags &= ~ACTOR_FLAG_4000000; } Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 18.0f, 15.0f, 0.0f, 0x45); } else { pos.x = this->actor.world.pos.x; pos.y = this->actor.world.pos.y + 20.0f; pos.z = this->actor.world.pos.z; - this->actor.floorHeight = func_800C411C(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &pos); + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &bgId, &this->actor, &pos); } } @@ -384,20 +387,20 @@ void ObjKibako_Thrown(ObjKibako* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 0xB) || (atHit) || (this->timer <= 0)) { ObjKibako_AirBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); Actor_MarkForDeath(&this->actor); } else { if (this->actor.bgCheckFlags & 0x40) { ObjKibako_WaterBreak(this, globalCtx); ObjKibako_SpawnCollectible(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); - Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); Actor_MarkForDeath(&this->actor); } else { if (this->actor.velocity.y < -0.05f) { this->actor.gravity = -2.3f; } - Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_MoveWithGravity(&this->actor); Math_StepToS(&D_80927384, D_80927380, 0xA0); Math_StepToS(&D_8092738C, D_80927388, 0xA0); this->actor.shape.rot.x = (s16)(this->actor.shape.rot.x + D_80927384); @@ -418,5 +421,5 @@ void ObjKibako_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjKibako_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, sDisplayLists[KIBAKO_BANK_INDEX(thisx)]); + Gfx_DrawDListOpa(globalCtx, sDisplayLists[KIBAKO_BANK_INDEX(thisx)]); } 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 dd87d150d..c0e5d8b4b 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; @@ -68,7 +65,7 @@ s32 ObjKibako2_ContainsSkulltula(ObjKibako2* this, GlobalContext* globalCtx) { if ((u16)actorSpawnParam & 3) { flag = ((actorSpawnParam & 0x3FC) >> 2) & 0xFF; } - return !(flag >= 0 && Actor_GetChestFlag(globalCtx, flag)); + return !(flag >= 0 && Flags_GetTreasure(globalCtx, flag)); } void ObjKibako2_Break(ObjKibako2* this, GlobalContext* globalCtx) { @@ -103,17 +100,17 @@ 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); } void ObjKibako2_SpawnCollectible(ObjKibako2* this, GlobalContext* globalCtx) { - s32 collectible = func_800A8150(KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor)); + s32 dropItem00Id = func_800A8150(KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor)); - if (collectible >= 0) { + if (dropItem00Id > ITEM00_NO_DROP) { Item_DropCollectible(globalCtx, &this->dyna.actor.world.pos, - collectible | KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor) << 8); + dropItem00Id | KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor) << 8); } } @@ -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); - BcCheck3_BgActorInit(&this->dyna, 0); + DynaPolyActor_Init(&this->dyna, 0); Collider_InitCylinder(globalCtx, &this->collider); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BgCheck3_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; @@ -164,7 +161,7 @@ void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) { if (func_800A81A4(globalCtx, KIBAKO2_COLLECTIBLE_ID(&this->dyna.actor), KIBAKO2_COLLECTIBLE_FLAG(&this->dyna.actor))) { this->unk_1AC = 1; - this->dyna.actor.flags |= 0x10; + this->dyna.actor.flags |= ACTOR_FLAG_10; } } if ((contents != CONTENTS_SKULLTULA) || !ObjKibako2_ContainsSkulltula(this, globalCtx)) { @@ -177,7 +174,7 @@ void ObjKibako2_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjKibako2* this = THIS; Collider_DestroyCylinder(globalCtx, &this->collider); - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } s32 ObjKibako2_ShouldBreak(ObjKibako2* this) { @@ -190,12 +187,12 @@ s32 ObjKibako2_ShouldBreak(ObjKibako2* this) { if (ac != NULL) { if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 31)) { // Powder Keg - if (Math3D_DistanceSquared(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(160.0f)) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(160.0f)) { shouldBreak = true; } } else if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 3)) { // Explosives - if (Math3D_DistanceSquared(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(100.0f)) { + if (Math3D_Vec3fDistSq(&this->dyna.actor.world.pos, &ac->world.pos) < SQ(100.0f)) { shouldBreak = true; } } else if (this->collider.info.acHitInfo->toucher.dmgFlags & (1 << 8 | 1 << 10)) { @@ -212,8 +209,8 @@ s32 ObjKibako2_ShouldBreak(ObjKibako2* this) { void ObjKibako2_Idle(ObjKibako2* this, GlobalContext* globalCtx) { if (ObjKibako2_ShouldBreak(this)) { ObjKibako2_Break(this, globalCtx); - Audio_PlaySoundAtPosition(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); - this->dyna.actor.flags |= 0x10; + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 20, NA_SE_EV_WOODBOX_BREAK); + this->dyna.actor.flags |= ACTOR_FLAG_10; func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); this->dyna.actor.draw = NULL; this->actionFunc = ObjKibako2_Kill; @@ -236,7 +233,7 @@ void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) { if (this->skulltulaNoiseTimer >= 0) { if (this->skulltulaNoiseTimer == 0) { - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EN_STALGOLD_ROLL); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_STALGOLD_ROLL); if (Rand_ZeroOne() < 0.1f) { this->skulltulaNoiseTimer = Rand_S16Offset(40, 80); } else { @@ -250,5 +247,5 @@ void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000960); + Gfx_DrawDListOpa(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_Kinoko/z_obj_kinoko.c b/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.c index 3a5e17df3..33cadc8f6 100644 --- a/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.c +++ b/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.c @@ -1,6 +1,13 @@ -#include "z_obj_kinoko.h" +/* + * File: z_obj_kinoko.c + * Overlay: ovl_Obj_Kinoko + * Description: Mushroom + */ -#define FLAGS 0x00000010 +#include "z_obj_kinoko.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjKinoko*)thisx) @@ -9,7 +16,6 @@ void ObjKinoko_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjKinoko_Update(Actor* thisx, GlobalContext* globalCtx); void ObjKinoko_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Kinoko_InitVars = { ACTOR_OBJ_KINOKO, ACTORCAT_ITEMACTION, @@ -22,12 +28,63 @@ const ActorInit Obj_Kinoko_InitVars = { (ActorFunc)ObjKinoko_Draw, }; -#endif +void ObjKinoko_Init(Actor* thisx, GlobalContext* globalCtx) { + thisx->world.pos.y += 4.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kinoko/ObjKinoko_Init.s") +void ObjKinoko_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kinoko/ObjKinoko_Destroy.s") +void ObjKinoko_Update(Actor* thisx, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kinoko/ObjKinoko_Update.s") + if (player->currentMask != PLAYER_MASK_SCENTS) { + thisx->draw = NULL; + thisx->hintId = 0xFF; + thisx->flags &= ~ACTOR_FLAG_1; + } else { + thisx->draw = ObjKinoko_Draw; + thisx->hintId = 0x64; + thisx->flags |= ACTOR_FLAG_1; + if (Actor_HasParent(thisx, globalCtx)) { + Flags_SetCollectible(globalCtx, OBJ_KINOKO_GET_FLAG(thisx)); + Actor_MarkForDeath(thisx); + return; + } + Actor_PickUp(thisx, globalCtx, GI_MAX, 20.0f, 10.0f); + if (Math_SmoothStepToF(&thisx->speedXZ, 0.0f, 0.04f, 2.0f, 0.5f) < 0.5f) { + thisx->scale.x = 0.0f; + thisx->speedXZ = 110.0f; + thisx->velocity.x = 0.2f; + } + if (Math_SmoothStepToF(&thisx->scale.x, thisx->velocity.x, 0.04f, 0.004f, 0.001f) < + ((thisx->velocity.x == 0.0f) ? 0.0f : 0.05f)) { + thisx->velocity.x = 0.0f; + } + thisx->scale.y = thisx->scale.x; + thisx->scale.z = thisx->scale.x; + thisx->shape.rot.y = Camera_GetCamDirYaw(globalCtx->cameraPtrs[globalCtx->activeCamera]) + 0x8000; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kinoko/ObjKinoko_Draw.s") +void ObjKinoko_Draw(Actor* thisx, GlobalContext* globalCtx) { + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gfx = POLY_XLU_DISP; + gDPSetPrimColor(&gfx[0], 0, 0, 169, 63, 186, (u8)thisx->speedXZ); + gDPSetEnvColor(&gfx[1], 110, 44, 200, 100); + gDPSetRenderMode(&gfx[2], G_RM_PASS, G_RM_ZB_CLD_SURF2); + gSPMatrix(&gfx[3], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[4], &gameplay_keep_DL_029D10[2]); + Matrix_RotateXS(-0x4000, MTXMODE_APPLY); + gSPMatrix(&gfx[5], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[6], &gameplay_keep_DL_029D10[2]); + POLY_XLU_DISP = &gfx[7]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.h b/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.h index 9ae26adf9..9073e3e14 100644 --- a/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.h +++ b/src/overlays/actors/ovl_Obj_Kinoko/z_obj_kinoko.h @@ -11,4 +11,6 @@ typedef struct ObjKinoko { extern const ActorInit Obj_Kinoko_InitVars; +#define OBJ_KINOKO_GET_FLAG(thisx) ((thisx)->params & 0x7F) + #endif // Z_OBJ_KINOKO_H diff --git a/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.c b/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.c index 8153c8556..5080c19e6 100644 --- a/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.c +++ b/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.c @@ -1,6 +1,13 @@ -#include "z_obj_kzsaku.h" +/* + * File: z_obj_kzsaku.c + * Overlay: ovl_Obj_Kzsaku + * Description: Underwater grate + */ -#define FLAGS 0x00000030 +#include "z_obj_kzsaku.h" +#include "objects/object_kzsaku/object_kzsaku.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjKzsaku*)thisx) @@ -9,7 +16,13 @@ void ObjKzsaku_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjKzsaku_Update(Actor* thisx, GlobalContext* globalCtx); void ObjKzsaku_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObjKzsaku_SetupIdle(ObjKzsaku* this); +void func_80C08BBC(ObjKzsaku* this); +void func_80C08C84(ObjKzsaku* this); +void ObjKzsaku_Idle(ObjKzsaku* this, GlobalContext* globalCtx); +void ObjKzsaku_Rise(ObjKzsaku* this, GlobalContext* globalCtx); +void func_80C08CB0(ObjKzsaku* this, GlobalContext* globalCtx); + const ActorInit Obj_Kzsaku_InitVars = { ACTOR_OBJ_KZSAKU, ACTORCAT_PROP, @@ -22,27 +35,96 @@ const ActorInit Obj_Kzsaku_InitVars = { (ActorFunc)ObjKzsaku_Draw, }; -#endif +void ObjKzsaku_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjKzsaku* this = THIS; + CollisionHeader* col = NULL; -extern UNK_TYPE D_06000040; -extern UNK_TYPE D_06001118; + Actor_SetScale(&this->dyna.actor, 1.0f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&object_kzsaku_Colheader_001118, &col); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/ObjKzsaku_Init.s") + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, thisx, col); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/ObjKzsaku_Destroy.s") + this->switchFlag = KZSAKU_GET_SWITCHFLAG(thisx); + this->raisedAmount = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08B60.s") + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + func_80C08C84(this); + } else { + ObjKzsaku_SetupIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08B7C.s") +void ObjKzsaku_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjKzsaku* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08BBC.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08BD0.s") +void ObjKzsaku_SetupIdle(ObjKzsaku* this) { + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + this->actionFunc = ObjKzsaku_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08C84.s") +void ObjKzsaku_Idle(ObjKzsaku* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, this->switchFlag)) { + func_80C08BBC(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/func_80C08CB0.s") +void func_80C08BBC(ObjKzsaku* this) { + this->actionFunc = ObjKzsaku_Rise; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/ObjKzsaku_Update.s") +void ObjKzsaku_Rise(ObjKzsaku* this, GlobalContext* globalCtx) { + if (this->dyna.actor.cutscene != -1) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } + } + if (this->raisedAmount < 450.0f) { + func_800B9010(&this->dyna.actor, NA_SE_EV_METALDOOR_SLIDE - SFX_FLAG); + this->raisedAmount += 15.0f; + } else { + func_80C08C84(this); + } + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + this->raisedAmount; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Kzsaku/ObjKzsaku_Draw.s") +void func_80C08C84(ObjKzsaku* this) { + this->timer = 0; + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 450.0f; + this->actionFunc = func_80C08CB0; +} + +void func_80C08CB0(ObjKzsaku* this, GlobalContext* globalCtx) { + if (this->timer <= 20) { + if (this->timer == 20) { + if (ActorCutscene_GetCurrentIndex() == this->dyna.actor.cutscene) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + } + this->timer = 21; + } else { + this->timer++; + } + } +} + +void ObjKzsaku_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjKzsaku* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjKzsaku_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++, object_kzsaku_DL_000040); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.h b/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.h index 32b634677..8c126412d 100644 --- a/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.h +++ b/src/overlays/actors/ovl_Obj_Kzsaku/z_obj_kzsaku.h @@ -3,15 +3,18 @@ #include "global.h" +#define KZSAKU_GET_SWITCHFLAG(thisx) (((thisx)->params & 0x7F00) >> 8) + struct ObjKzsaku; typedef void (*ObjKzsakuActionFunc)(struct ObjKzsaku*, GlobalContext*); typedef struct ObjKzsaku { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjKzsakuActionFunc actionFunc; - /* 0x0160 */ char unk_160[0xC]; + /* 0x0160 */ f32 raisedAmount; + /* 0x0164 */ s32 switchFlag; + /* 0x0168 */ s16 timer; } ObjKzsaku; // size = 0x16C extern const ActorInit Obj_Kzsaku_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c index c1d56bf8d..300e299aa 100644 --- a/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c +++ b/src/overlays/actors/ovl_Obj_Lift/z_obj_lift.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_lift.c + * Overlay: ovl_Obj_Lift + * Description: Dampé's Grave - Brown Elevator + */ + #include "z_obj_lift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjLift*)thisx) @@ -25,7 +31,7 @@ const ActorInit Obj_Lift_InitVars = { // static InitChainEntry sInitChain[] = { static InitChainEntry D_8093DD84[] = { ICHAIN_F32_DIV1000(gravity, -600, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -15000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -15000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 350, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 350, ICHAIN_STOP), diff --git a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c index d955a5aa3..bd86f2dea 100644 --- a/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c +++ b/src/overlays/actors/ovl_Obj_Lightblock/z_obj_lightblock.c @@ -5,6 +5,7 @@ */ #include "z_obj_lightblock.h" +#include "objects/object_lightblock/object_lightblock.h" #define FLAGS 0x00000000 @@ -72,9 +73,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -extern CollisionHeader D_06000B80; extern Gfx D_801AEF88[]; -extern Gfx D_06000178[]; extern Gfx D_801AEFA0[]; void func_80AF3910(ObjLightblock* this, GlobalContext* globalCtx) { @@ -91,12 +90,12 @@ void ObjLightblock_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); Actor_SetScale(&this->dyna.actor, typeVars->scale); - BcCheck3_BgActorInit(&this->dyna, 0); + DynaPolyActor_Init(&this->dyna, 0); Collider_InitCylinder(globalCtx, &this->collider); if (Flags_GetSwitch(globalCtx, LIGHTBLOCK_DESTROYED(&this->dyna.actor))) { Actor_MarkForDeath(&this->dyna.actor); } else { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000B80); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_lightblock_Colheader_000B80); Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); Collider_UpdateCylinder(&this->dyna.actor, &this->collider); this->collider.dim.radius = typeVars->radius; @@ -110,7 +109,7 @@ void ObjLightblock_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjLightblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjLightblock* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); Collider_DestroyCylinder(globalCtx, &this->collider); } @@ -148,7 +147,7 @@ void func_80AF3B8C(ObjLightblock* this) { void func_80AF3BA0(ObjLightblock* this, GlobalContext* globalCtx) { if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); - Actor_SetSwitchFlag(globalCtx, LIGHTBLOCK_DESTROYED(&this->dyna.actor)); + Flags_SetSwitch(globalCtx, LIGHTBLOCK_DESTROYED(&this->dyna.actor)); func_80AF3910(this, globalCtx); func_80AF3C18(this); } else { @@ -195,13 +194,13 @@ void ObjLightblock_Draw(Actor* thisx, GlobalContext* globalCtx) { 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, 0x80, 255, 255, 255, this->alpha); - gSPDisplayList(POLY_XLU_DISP++, D_06000178); + gSPDisplayList(POLY_XLU_DISP++, object_lightblock_DL_000178); } else { 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, 0x80, 255, 255, 255, 255); - gSPDisplayList(POLY_OPA_DISP++, D_06000178); + gSPDisplayList(POLY_OPA_DISP++, object_lightblock_DL_000178); } CLOSE_DISPS(globalCtx->state.gfxCtx); } 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 4237e0992..b1d54899b 100644 --- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -1,6 +1,13 @@ -#include "z_obj_lightswitch.h" +/* + * File: z_obj_lightswitch.c + * Overlay: ovl_Obj_Lightswitch + * Description: Sun Switch / STT Flip switch + */ -#define FLAGS 0x00000010 +#include "z_obj_lightswitch.h" +#include "objects/object_lightswitch/object_lightswitch.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjLightswitch*)thisx) @@ -20,13 +27,6 @@ void ObjLightSwitch_SetupDisabled(ObjLightswitch* this); void ObjLightSwitch_Disabled(ObjLightswitch* this, GlobalContext* globalCtx); void ObjLightswitch_Idle(ObjLightswitch* this, GlobalContext* globalCtx); -extern Gfx D_06000260[]; -extern Gfx D_06000398[]; -extern Gfx D_06000408[]; -extern Gfx D_06000C20[]; -extern Gfx D_06000420[]; -extern Gfx D_06001420[]; - const ActorInit Obj_Lightswitch_InitVars = { ACTOR_OBJ_LIGHTSWITCH, ACTORCAT_SWITCH, @@ -67,10 +67,10 @@ static ColliderJntSphInit sJntSphInit = { }; // different face addresses for (sleep -> waking -> awake) of light switch face -static Gfx* sLightswitchFaceGfx[] = { - D_06000C20, - D_06000420, - D_06001420, +static TexturePtr sLightswitchFaceGfx[] = { + object_lightswitch_Tex_000C20, + object_lightswitch_Tex_000420, + object_lightswitch_Tex_001420, }; static Color_RGBA8 sLightswitchEffectPrimColor = { 255, 255, 160, 160 }; @@ -89,9 +89,9 @@ void ObjLightswitch_InitCollider(ObjLightswitch* this, GlobalContext* globalCtx) Collider_InitJntSph(globalCtx, &this->collider); Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->elements); this->actor.colChkInfo.mass = MASS_IMMOVABLE; - Matrix_SetStateRotationAndTranslation(this->actor.world.pos.x, - this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y), - this->actor.world.pos.z, &this->actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, + this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y), + this->actor.world.pos.z, &this->actor.shape.rot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); Collider_UpdateSpheres(0, &this->collider); } @@ -100,9 +100,9 @@ void ObjLightswitch_UpdateSwitchFlags(ObjLightswitch* this, GlobalContext* globa if (this) {} if (set) { - Actor_SetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)); + Flags_SetSwitch(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)); } else { - Actor_UnsetSwitchFlag(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)); + Flags_UnsetSwitch(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)); } } @@ -139,7 +139,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); } } @@ -153,7 +153,7 @@ void ObjLightswitch_Init(Actor* thisx, GlobalContext* globalCtx) { isSwitchActivated = Flags_GetSwitch(globalCtx, GET_LIGHTSWITCH_SWITCHFLAG(this)); isTriggered = false; Actor_ProcessInitChain(&this->actor, sInitChain); - Actor_SetHeight(&this->actor, 0.0f); + Actor_SetFocus(&this->actor, 0.0f); if (isSwitchActivated) { if (GET_LIGHTSWITCH_TYPE(this) == LIGHTSWITCH_TYPE_FAKE) { @@ -231,7 +231,7 @@ void ObjLightSwitch_SetupAsleep(ObjLightswitch* this) { void ObjLightSwitch_Asleep(ObjLightswitch* this, GlobalContext* globalCtx) { if (this->colorShiftTimer == 0) { - Audio_PlayActorSound2(&this->actor, NA_SE_EV_SUN_MARK_FLASH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SUN_MARK_FLASH); } this->colorShiftTimer++; @@ -244,7 +244,7 @@ void ObjLightSwitch_Asleep(ObjLightswitch* this, GlobalContext* globalCtx) { ObjLightSwitch_SetupEnabled(this); } else if (this->colorShiftTimer == 15) { this->faceState = LIGHTSWITCH_FACE_WAKING; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FOOT_SWITCH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FOOT_SWITCH); } } @@ -302,7 +302,7 @@ void ObjLightSwitch_Disabled(ObjLightswitch* this, GlobalContext* globalCtx) { ObjLightswitch_SetupIdle(this); } else if (this->colorShiftTimer == 15) { this->faceState = LIGHTSWITCH_FACE_ASLEEP; - Audio_PlayActorSound2(&this->actor, NA_SE_EV_FOOT_SWITCH); + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_FOOT_SWITCH); } } @@ -379,21 +379,21 @@ void ObjLightSwitch_DrawOpa(ObjLightswitch* this, GlobalContext* globalCtx) { tempPos.z = this->actor.world.pos.z; gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sLightswitchFaceGfx[this->faceState])); - gSPDisplayList(POLY_OPA_DISP++, D_06000260); + gSPDisplayList(POLY_OPA_DISP++, object_lightswitch_DL_000260); tempRot.x = this->actor.shape.rot.x; tempRot.y = this->actor.shape.rot.y; tempRot.z = this->actor.shape.rot.z + this->edgeRot; - Matrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot); + Matrix_SetTranslateRotateYXZ(tempPos.x, tempPos.y, tempPos.z, &tempRot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.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_06000398); + gSPDisplayList(POLY_OPA_DISP++, object_lightswitch_DL_000398); tempRot.z = this->actor.shape.rot.z - this->edgeRot; - Matrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot); + Matrix_SetTranslateRotateYXZ(tempPos.x, tempPos.y, tempPos.z, &tempRot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.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_06000408); + gSPDisplayList(POLY_OPA_DISP++, object_lightswitch_DL_000408); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -415,21 +415,21 @@ void ObjLightSwitch_DrawXlu(ObjLightswitch* this, GlobalContext* globalCtx) { tempPos.z = this->actor.world.pos.z; 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(sLightswitchFaceGfx[this->faceState])); - gSPDisplayList(POLY_XLU_DISP++, D_06000260); + gSPDisplayList(POLY_XLU_DISP++, object_lightswitch_DL_000260); tempRot.x = this->actor.shape.rot.x; tempRot.y = this->actor.shape.rot.y; tempRot.z = this->actor.shape.rot.z + this->edgeRot; - Matrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot); + Matrix_SetTranslateRotateYXZ(tempPos.x, tempPos.y, tempPos.z, &tempRot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.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++, D_06000398); + gSPDisplayList(POLY_XLU_DISP++, object_lightswitch_DL_000398); tempRot.z = this->actor.shape.rot.z - this->edgeRot; - Matrix_SetStateRotationAndTranslation(tempPos.x, tempPos.y, tempPos.z, &tempRot); + Matrix_SetTranslateRotateYXZ(tempPos.x, tempPos.y, tempPos.z, &tempRot); Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.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++, D_06000408); + gSPDisplayList(POLY_XLU_DISP++, object_lightswitch_DL_000408); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Obj_Lupygamelift/z_obj_lupygamelift.c b/src/overlays/actors/ovl_Obj_Lupygamelift/z_obj_lupygamelift.c index 81141154a..d804f6b63 100644 --- a/src/overlays/actors/ovl_Obj_Lupygamelift/z_obj_lupygamelift.c +++ b/src/overlays/actors/ovl_Obj_Lupygamelift/z_obj_lupygamelift.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_lupygamelift.c + * Overlay: ovl_Obj_Lupygamelift + * Description: Deku Scrub Playground - Rupee Elevator + */ + #include "z_obj_lupygamelift.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjLupygamelift*)thisx) 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 b8a8e1b30..a5aaefd4f 100644 --- a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c +++ b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_makekinsuta.c + * Overlay: ovl_Obj_Makekinsuta + * Description: Swamp Spider House - Soft soil with Skulltula hiding in it + */ + #include "z_obj_makekinsuta.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjMakekinsuta*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c index a704f2773..1645f8469 100644 --- a/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c +++ b/src/overlays/actors/ovl_Obj_Makeoshihiki/z_obj_makeoshihiki.c @@ -6,7 +6,7 @@ #include "z_obj_makeoshihiki.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjMakeoshihiki*)thisx) @@ -43,15 +43,15 @@ void ObjMakeoshihiki_SetSwitchFlags(ObjMakeoshihiki* this, GlobalContext* global switchFlag1 = OBJMAKEOSHIHIKI_GET_SWITCHFLAG_1(this); if (pathIndex & 2) { - Actor_SetSwitchFlag(globalCtx, switchFlag2); + Flags_SetSwitch(globalCtx, switchFlag2); } else { - Actor_UnsetSwitchFlag(globalCtx, switchFlag2); + Flags_UnsetSwitch(globalCtx, switchFlag2); } if (pathIndex & 1) { - Actor_SetSwitchFlag(globalCtx, switchFlag1); + Flags_SetSwitch(globalCtx, switchFlag1); } else { - Actor_UnsetSwitchFlag(globalCtx, switchFlag1); + Flags_UnsetSwitch(globalCtx, switchFlag1); } } @@ -85,7 +85,7 @@ void ObjMakeoshihiki_Update(Actor* thisx, GlobalContext* globalCtx) { } else { for (loopPathIndex = 0; loopPathIndex < this->pathCount; loopPathIndex++) { Math_Vec3s_ToVec3f(&pathPointF, &this->pathPoints[loopPathIndex]); - if (Math3D_DistanceSquared(&this->actor.child->world.pos, &pathPointF) < SQ(0.5f)) { + if (Math3D_Vec3fDistSq(&this->actor.child->world.pos, &pathPointF) < SQ(0.5f)) { ObjMakeoshihiki_SetSwitchFlags(this, globalCtx, loopPathIndex); return; } diff --git a/src/overlays/actors/ovl_Obj_Milk_Bin/z_obj_milk_bin.c b/src/overlays/actors/ovl_Obj_Milk_Bin/z_obj_milk_bin.c index 5af876303..a32f791bc 100644 --- a/src/overlays/actors/ovl_Obj_Milk_Bin/z_obj_milk_bin.c +++ b/src/overlays/actors/ovl_Obj_Milk_Bin/z_obj_milk_bin.c @@ -5,6 +5,7 @@ */ #include "z_obj_milk_bin.h" +#include "objects/object_obj_milk_bin/object_obj_milk_bin.h" #define FLAGS 0x00000000 @@ -15,14 +16,11 @@ void ObjMilkBin_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjMilkBin_Update(Actor* thisx, GlobalContext* globalCtx); void ObjMilkBin_Draw(Actor* thisx, GlobalContext* globalCtx); -// gMilkBinMilkJarDL -extern Gfx D_060004B0[]; - const ActorInit Obj_Milk_Bin_InitVars = { ACTOR_OBJ_MILK_BIN, ACTORCAT_PROP, FLAGS, - OBJECT_OBJECT_UNSET_MILK_BIN, + OBJECT_OBJ_MILK_BIN, sizeof(ObjMilkBin), (ActorFunc)ObjMilkBin_Init, (ActorFunc)ObjMilkBin_Destroy, @@ -60,7 +58,7 @@ void ObjMilkBin_Init(Actor* thisx, GlobalContext* globalCtx) { this->disableDraw = 0; this->type = thisx->params; - if ((this->type == OBJ_MILK_BIN_TYPE_2) && !(gSaveContext.weekEventReg[0x34] & 1)) { + if ((this->type == OBJ_MILK_BIN_TYPE_2) && !(gSaveContext.save.weekEventReg[52] & 1)) { this->disableDraw |= 1; } } @@ -72,18 +70,18 @@ void ObjMilkBin_Destroy(Actor* thisx, GlobalContext* globalCtx) { } void ObjMilkBin_Update(Actor* thisx, GlobalContext* globalCtx2) { - ObjMilkBin* this = THIS; GlobalContext* globalCtx = globalCtx2; + ObjMilkBin* this = THIS; if (this->type == OBJ_MILK_BIN_TYPE_1) { - if (gSaveContext.weekEventReg[0x16] & 1) { - if (((gSaveContext.day == 2) && (gSaveContext.isNight == 1)) || (gSaveContext.day >= 3)) { + if (gSaveContext.save.weekEventReg[22] & 1) { + if (((gSaveContext.save.day == 2) && (gSaveContext.save.isNight == 1)) || (gSaveContext.save.day >= 3)) { Actor_MarkForDeath(&this->actor); return; } } } else if (this->type == OBJ_MILK_BIN_TYPE_2) { - if (gSaveContext.weekEventReg[0x34] & 1) { + if (gSaveContext.save.weekEventReg[52] & 1) { this->disableDraw &= ~1; } else { this->disableDraw |= 1; @@ -100,6 +98,6 @@ void ObjMilkBin_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjMilkBin* this = THIS; if (!(this->disableDraw & 1)) { - func_800BDFC0(globalCtx, D_060004B0); + Gfx_DrawDListOpa(globalCtx, gMilkBinMilkJarDL); } } diff --git a/src/overlays/actors/ovl_Obj_Mine/z_obj_mine.c b/src/overlays/actors/ovl_Obj_Mine/z_obj_mine.c index a1f127eaa..5b5e80d39 100644 --- a/src/overlays/actors/ovl_Obj_Mine/z_obj_mine.c +++ b/src/overlays/actors/ovl_Obj_Mine/z_obj_mine.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_mine.c + * Overlay: ovl_Obj_Mine + * Description: Spike metal Mine + */ + #include "z_obj_mine.h" #define FLAGS 0x00000000 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 13379e5f0..d6d780a04 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,12 +1,13 @@ /* - * File z_obj_moon_stone.c + * File: z_obj_moon_stone.c * Overlay: ovl_Obj_Moon_Stone * Description: Moon's Tear */ #include "z_obj_moon_stone.h" +#include "objects/object_gi_reserve00/object_gi_reserve00.h" -#define FLAGS 0x00100010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000) #define THIS ((ObjMoonStone*)thisx) @@ -36,10 +37,6 @@ const ActorInit Obj_Moon_Stone_InitVars = { (ActorFunc)ObjMoonStone_Draw, }; -extern AnimatedMaterial D_06001C60; -extern Gfx D_06000D78[]; -extern Gfx D_06000C80[]; - void ObjMoonStone_Init(Actor* thisx, GlobalContext* globalCtx) { ObjMoonStone* this = THIS; @@ -50,19 +47,17 @@ void ObjMoonStone_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.focus.pos.y += 10.0f; if (this->unk194 == 0) { this->actor.colChkInfo.health = 0; - this->actor.flags |= 9; + this->actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); func_80C0662C(this); - } else { - if ((gSaveContext.weekEventReg[74] & 0x40) == 0) { - if ((gSaveContext.weekEventReg[74] & 0x80)) { - Actor_Spawn(&globalCtx->actorCtx, globalCtx, 1, this->actor.world.pos.x, this->actor.world.pos.y, - this->actor.world.pos.z, 0, 0, 0, -1); - } - this->actor.flags &= ~1; - func_80C0673C(this); - } else { - Actor_MarkForDeath(&this->actor); + } else if (!(gSaveContext.save.weekEventReg[74] & 0x40)) { + if ((gSaveContext.save.weekEventReg[74] & 0x80)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, 1, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, -1); } + this->actor.flags &= ~ACTOR_FLAG_1; + func_80C0673C(this); + } else { + Actor_MarkForDeath(&this->actor); } } @@ -78,9 +73,9 @@ void func_80C06640(ObjMoonStone* this, GlobalContext* globalCtx) { s16 sp1A = this->actor.yawTowardsPlayer - 0x8000; sp1A -= player->actor.shape.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { this->actor.colChkInfo.health = 1; - func_801518B0(globalCtx, 0x5E3U, &this->actor); + Message_StartTextbox(globalCtx, 0x5E3U, &this->actor); func_80C066F8(this); } else { s32 phi_v0 = ABS_ALT(sp1A); @@ -95,22 +90,22 @@ void func_80C066F8(ObjMoonStone* this) { } void func_80C0670C(ObjMoonStone* this, GlobalContext* globalCtx) { - if (func_800B867C(&this->actor, globalCtx) != 0) { + if (Actor_TextboxIsClosing(&this->actor, globalCtx)) { this->actor.colChkInfo.health = 0; func_80C0662C(this); } } void func_80C0673C(ObjMoonStone* this) { - if ((gSaveContext.weekEventReg[74] & 0x80) == 0) { + if (!(gSaveContext.save.weekEventReg[74] & 0x80)) { this->actor.draw = NULL; } this->actionFunc = func_80C06768; } void func_80C06768(ObjMoonStone* this, GlobalContext* globalCtx) { - if ((gSaveContext.weekEventReg[74] & 0x80)) { - if (this->actor.draw == 0) { + if ((gSaveContext.save.weekEventReg[74] & 0x80)) { + if (this->actor.draw == NULL) { this->actor.draw = ObjMoonStone_Draw; Actor_Spawn(&globalCtx->actorCtx, globalCtx, 1, this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, -1); @@ -122,7 +117,7 @@ void func_80C06768(ObjMoonStone* this, GlobalContext* globalCtx) { this->actor.draw = NULL; func_80C0685C(this); } else if (this->actor.xzDistToPlayer < 25.0f) { - func_800B8A1C(&this->actor, globalCtx, 0x96, 100.0f, 30.0f); + Actor_PickUp(&this->actor, globalCtx, GI_MOON_TEAR, 100.0f, 30.0f); } } } @@ -132,8 +127,8 @@ void func_80C0685C(ObjMoonStone* this) { } void func_80C06870(ObjMoonStone* this, GlobalContext* globalCtx) { - if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { - gSaveContext.weekEventReg[74] |= 0x40; + if (Message_GetState(&globalCtx->msgCtx) == 6 && Message_ShouldAdvance(globalCtx)) { + gSaveContext.save.weekEventReg[74] |= 0x40; Actor_MarkForDeath(&this->actor); } } @@ -142,7 +137,7 @@ void ObjMoonStone_Update(Actor* thisx, GlobalContext* globalCtx) { ObjMoonStone* this = THIS; Player* player = GET_PLAYER(globalCtx); - if ((player->stateFlags1 & 0x10000282) == 0) { + if (!(player->stateFlags1 & 0x10000282)) { this->actionFunc(this, globalCtx); } } @@ -153,11 +148,11 @@ void ObjMoonStone_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06001C60)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(object_gi_reserve00_Matanimheader_001C60)); 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); + gSPDisplayList(POLY_OPA_DISP++, object_gi_reserve00_DL_000D78); + Matrix_ReplaceRotation(&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); + gSPDisplayList(POLY_XLU_DISP++, object_gi_reserve00_DL_000C80); 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 c0bcd9bd5..f81b4fe47 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,6 +1,12 @@ +/* + * File: z_obj_mu_pict.c + * Overlay: ovl_Obj_Mu_Pict + * Description: Handles dialogue for checking the Garo/Gibdo poster in the Music Box House + */ + #include "z_obj_mu_pict.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((ObjMuPict*)thisx) @@ -34,7 +40,7 @@ const ActorInit Obj_Mu_Pict_InitVars = { void ObjMuPict_Init(Actor* thisx, GlobalContext* globalCtx) { ObjMuPict* this = THIS; - if (!(gSaveContext.weekEventReg[75] & 0x20) && !(gSaveContext.weekEventReg[52] & 0x20)) { + if (!(gSaveContext.save.weekEventReg[75] & 0x20) && !(gSaveContext.save.weekEventReg[52] & 0x20)) { Actor_MarkForDeath(&this->actor); } @@ -57,7 +63,7 @@ void func_80C06B5C(ObjMuPict* this) { void func_80C06B70(ObjMuPict* this, GlobalContext* globalCtx) { s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; - if (func_800B84D0(&this->actor, globalCtx)) { + if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { if (this->actor.cutscene < 0) { func_80C06DC8(this, globalCtx); func_80C06CC4(this); @@ -92,7 +98,7 @@ void func_80C06CC4(ObjMuPict* this) { } void func_80C06CD8(ObjMuPict* this, GlobalContext* globalCtx) { - switch (func_80152498(&globalCtx->msgCtx)) { + switch (Message_GetState(&globalCtx->msgCtx)) { case 0: case 1: case 2: @@ -103,7 +109,7 @@ void func_80C06CD8(ObjMuPict* this, GlobalContext* globalCtx) { func_80C06E88(this, globalCtx); break; case 6: - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { func_80C06B5C(this); if (this->actor.cutscene >= 0) { ActorCutscene_Stop(this->actor.cutscene); @@ -116,7 +122,7 @@ void func_80C06CD8(ObjMuPict* this, GlobalContext* globalCtx) { } void func_80C06D90(ObjMuPict* this, GlobalContext* globalCtx) { - Actor* actorPtr = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + Actor* actorPtr = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; while (actorPtr != NULL) { if (actorPtr->id == ACTOR_EN_HGO) { @@ -131,51 +137,51 @@ void func_80C06DC8(ObjMuPict* this, GlobalContext* globalCtx) { if (this->unk14A == 0) { if (this->unk148 == 0) { this->unk148 = 1; - func_801518B0(globalCtx, 0x159A, &this->actor); + Message_StartTextbox(globalCtx, 0x159A, &this->actor); this->textId = 0x159A; } else { - func_801518B0(globalCtx, 0x159D, &this->actor); + Message_StartTextbox(globalCtx, 0x159D, &this->actor); this->textId = 0x159D; } } else if (this->unk148 == 0) { this->unk148 = 1; - func_801518B0(globalCtx, 0x15A0, &this->actor); + Message_StartTextbox(globalCtx, 0x15A0, &this->actor); this->textId = 0x15A0; } else { - func_801518B0(globalCtx, 0x15A3, &this->actor); + Message_StartTextbox(globalCtx, 0x15A3, &this->actor); this->textId = 0x15A3; } } void func_80C06E88(ObjMuPict* this, GlobalContext* globalCtx) { - if (func_80147624(globalCtx)) { + if (Message_ShouldAdvance(globalCtx)) { switch (this->textId) { case 0x159A: - func_801518B0(globalCtx, 0x159B, &this->actor); + Message_StartTextbox(globalCtx, 0x159B, &this->actor); this->textId = 0x159B; break; case 0x159B: - func_801518B0(globalCtx, 0x159C, &this->actor); + Message_StartTextbox(globalCtx, 0x159C, &this->actor); this->textId = 0x159C; break; case 0x159D: - func_801518B0(globalCtx, 0x159E, &this->actor); + Message_StartTextbox(globalCtx, 0x159E, &this->actor); this->textId = 0x159E; break; case 0x159E: - func_801518B0(globalCtx, 0x159F, &this->actor); + Message_StartTextbox(globalCtx, 0x159F, &this->actor); this->textId = 0x159F; break; case 0x15A0: - func_801518B0(globalCtx, 0x15A1, &this->actor); + Message_StartTextbox(globalCtx, 0x15A1, &this->actor); this->textId = 0x15A1; break; case 0x15A1: - func_801518B0(globalCtx, 0x15A2, &this->actor); + Message_StartTextbox(globalCtx, 0x15A2, &this->actor); this->textId = 0x15A2; break; case 0x15A3: - func_801518B0(globalCtx, 0x15A4, &this->actor); + Message_StartTextbox(globalCtx, 0x15A4, &this->actor); this->textId = 0x15A4; break; } 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 22efe55d9..b24354482 100644 --- a/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c +++ b/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_mure.c + * Overlay: ovl_Obj_Mure + * Description: Bugs, Insects, Butterfly spawner and behavior + */ + #include "z_obj_mure.h" #define FLAGS 0x00000000 @@ -8,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, @@ -25,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* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + 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( + &globalCtx2->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 |= ACTOR_FLAG_10; + 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 &= ~ACTOR_FLAG_10; + 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.c b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c index cb04a8170..49101b746 100644 --- a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c +++ b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_mure2.c + * Overlay: ovl_Obj_Mure2 + * Description: Circle of rocks spawner + */ + #include "z_obj_mure2.h" #define FLAGS 0x00000000 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.c b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.c index 043c6b8e1..bdeb9c702 100644 --- a/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.c +++ b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_mure3.c + * Overlay: ovl_Obj_Mure3 + * Description: Group Rupee spawner + */ + #include "z_obj_mure3.h" #define FLAGS 0x00000000 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_Nozoki/z_obj_nozoki.c b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c index 567cf43b4..2ff0e093e 100644 --- a/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c +++ b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.c @@ -1,6 +1,14 @@ -#include "z_obj_nozoki.h" +/* + * File: z_obj_nozoki.c + * Overlay: ovl_Obj_Nozoki + * Description: Sakon's Hideout Objects (Sun's Mask, doors, etc) + */ -#define FLAGS 0x00000010 +#include "z_obj_nozoki.h" +#include "objects/object_secom_obj/object_secom_obj.h" +#include "prevent_bss_reordering.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjNozoki*)thisx) @@ -8,17 +16,23 @@ void ObjNozoki_Init(Actor* thisx, GlobalContext* globalCtx); void ObjNozoki_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjNozoki_Update(Actor* thisx, GlobalContext* globalCtx); +void ObjNozoki_SetupAction(ObjNozoki* this, ObjNozokiActionFunc actionFunc); void func_80BA2514(ObjNozoki* this, GlobalContext* globalCtx); +void func_80BA27C4(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA28DC(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA2AB4(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA2BA4(ObjNozoki* this, GlobalContext* globalCtx); +void func_80BA2C94(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA3044(ObjNozoki* this, GlobalContext* globalCtx); +void func_80BA311C(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA3230(ObjNozoki* this, GlobalContext* globalCtx); void func_80BA3344(ObjNozoki* this, GlobalContext* globalCtx); +void ObjNozoki_Draw(Actor* thisx, GlobalContext* globalCtx); -void ObjNozoki_SetupAction(ObjNozoki* this, ObjNozokiActionFunc actionFunc); +s32 D_80BA36B0; +s32 D_80BA36B4; +f32 D_80BA36B8; -#if 0 const ActorInit Obj_Nozoki_InitVars = { ACTOR_OBJ_NOZOKI, ACTORCAT_ITEMACTION, @@ -31,54 +45,428 @@ const ActorInit Obj_Nozoki_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BA34B0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F(scale, 1, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 0, ICHAIN_STOP), }; -#endif +s16 D_80BA34B8[] = { OBJECT_SECOM_OBJ, OBJECT_GI_MSSA, OBJECT_SECOM_OBJ, OBJECT_SECOM_OBJ }; -extern InitChainEntry D_80BA34B0[]; +Vec3f D_80BA34C0 = { 0.0f, 0.0f, -1110.0f }; -extern UNK_TYPE D_060001C0; +Vec3f D_80BA34CC = { 0.0f, 0.0f, 38.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/ObjNozoki_SetupAction.s") +f32 D_80BA34D8[] = { 100.0f, 9999.0f, 9999.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/ObjNozoki_Init.s") +f32 D_80BA34E4[] = { 0.5f, 0.25f, 1.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/ObjNozoki_Destroy.s") +void ObjNozoki_SetupAction(ObjNozoki* this, ObjNozokiActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2514.s") +void ObjNozoki_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjNozoki* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA26A8.s") + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + this->unk_15F = this->dyna.actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2708.s") + if (globalCtx->sceneNum == SCENE_AYASHIISHOP) { + this->unk_15C = 4; + ObjNozoki_SetupAction(this, func_80BA3230); + this->dyna.actor.colChkInfo.cylRadius = -40; + } else { + this->unk_15C = OBJNOZOKI_GET_180(&this->dyna.actor); + if (this->unk_15C == 0) { + DynaPolyActor_Init(&this->dyna, 0); + } + ObjNozoki_SetupAction(this, func_80BA2514); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2790.s") +void ObjNozoki_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjNozoki* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA27C4.s") + if (this->unk_15C == 0) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA28DC.s") +void func_80BA2514(ObjNozoki* this, GlobalContext* globalCtx) { + s32 sp24 = Object_GetIndex(&globalCtx->objectCtx, D_80BA34B8[this->unk_15C]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2AB4.s") + if (sp24 < 0) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2B64.s") + if (Object_IsLoaded(&globalCtx->objectCtx, sp24)) { + this->dyna.actor.objBankIndex = sp24; + this->dyna.actor.draw = ObjNozoki_Draw; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2BA4.s") + if (this->unk_15C == 0) { + Actor_SetObjectDependency(globalCtx, &this->dyna.actor); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_secom_obj_Colheader_0001C0); + if (ActorCutscene_GetAdditionalCutscene(this->unk_15F) >= 0) { + this->dyna.actor.params |= OBJNOZOKI_400; + } + ObjNozoki_SetupAction(this, func_80BA27C4); + } else if (this->unk_15C == 1) { + Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.world.pos, this->dyna.actor.shape.rot.y, &D_80BA34C0, + &this->dyna.actor.home.pos); + Actor_SetScale(&this->dyna.actor, 0.6f); + this->dyna.actor.flags |= ACTOR_FLAG_20; + ObjNozoki_SetupAction(this, func_80BA2BA4); + } else if (this->unk_15C == 2) { + Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.home.pos, this->dyna.actor.shape.rot.y, &D_80BA34CC, + &this->dyna.actor.focus.pos); + Math_Vec3f_Copy(&this->dyna.actor.world.pos, &this->dyna.actor.focus.pos); + ObjNozoki_SetupAction(this, func_80BA3044); + } else { + ObjNozoki_SetupAction(this, func_80BA311C); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2C28.s") +s32 func_80BA26A8(ObjNozoki* this) { + if (this->unk_15F < 0) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA2C94.s") + if (ActorCutscene_GetCanPlayNext(this->unk_15F)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_15F, &this->dyna.actor); + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA3044.s") + ActorCutscene_SetIntentToPlay(this->unk_15F); + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA311C.s") +s32 func_80BA2708(ObjNozoki* this, GlobalContext* globalCtx) { + Actor* enemy = globalCtx->actorCtx.actorLists[ACTORCAT_ENEMY].first; + Vec3f sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA3230.s") + while (enemy != NULL) { + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &sp30, &enemy->world.pos); + if (sp30.z >= 0.0f) { + return false; + } + enemy = enemy->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA3344.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/ObjNozoki_Update.s") +void func_80BA2790(ObjNozoki* this) { + ObjNozoki_SetupAction(this, func_80BA28DC); + this->dyna.actor.velocity.y = 0.0f; + this->unk_15E = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Nozoki/func_80BA3434.s") +void func_80BA27C4(ObjNozoki* this, GlobalContext* globalCtx) { + if (!(globalCtx->actorCtx.unk5 & 0x20)) { + if (OBJNOZOKI_GET_200(&this->dyna.actor)) { + if (!func_80BA2708(this, globalCtx)) { + return; + } + } else { + if (D_80BA36B0 != 0) { + globalCtx->actorCtx.unk5 |= 0x80; + } + + if (!Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + return; + } + } + + if ((D_80BA36B0 == 0) || func_80BA26A8(this)) { + func_80BA2790(this); + if (D_80BA36B0 == 0) { + this->unk_15E = 25; + play_sound(NA_SE_SY_SECOM_WARNING); + } else { + this->unk_15E = ActorCutscene_GetLength(this->unk_15F); + if (this->unk_15E < 0) { + this->unk_15E = 50; + } + globalCtx->actorCtx.unk5 |= 0x10; + } + } + GET_PLAYER(globalCtx)->linearVelocity = 0.0f; + } +} + +void func_80BA28DC(ObjNozoki* this, GlobalContext* globalCtx) { + if (this->unk_15E != 0) { + if (DECR(this->unk_15E) == 0) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_OPEN); + } + return; + } + + if (!(globalCtx->actorCtx.unk5 & 0x20)) { + Math_StepToF(&this->dyna.actor.velocity.y, 15.0f, 3.0f); + Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 200.0f, this->dyna.actor.velocity.y); + + if (OBJNOZOKI_GET_200(&this->dyna.actor)) { + if (!Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + return; + } + } else if (Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + s32 cs = this->dyna.actor.cutscene; + + if (cs == this->unk_15F) { + if (OBJNOZOKI_GET_400(&this->dyna.actor)) { + Vec3f sp28; + + Actor_OffsetOfPointInActorCoords(&this->dyna.actor, &sp28, &GET_PLAYER(globalCtx)->actor.world.pos); + if (sp28.z < -20.0f) { + this->unk_15F = ActorCutscene_GetAdditionalCutscene(this->unk_15F); + } + } + } else if (D_80BA36B4 == 0) { + if (func_80BA26A8(this)) { + D_80BA36B4 = 1; + } + } else if (ActorCutscene_GetCurrentIndex() != this->unk_15F) { + this->unk_15F = cs; + this->dyna.actor.params &= ~OBJNOZOKI_400; + Audio_QueueSeqCmd(0x881A); + } + return; + } + } + + ObjNozoki_SetupAction(this, func_80BA2AB4); + this->dyna.actor.velocity.y = 0.0f; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_SLIDE_DOOR_CLOSE); +} + +void func_80BA2AB4(ObjNozoki* this, GlobalContext* globalCtx) { + this->dyna.actor.velocity.y = 30.0f; + + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 30.0f) && (D_80BA36B0 == 0)) { + ObjNozoki_SetupAction(this, func_80BA27C4); + D_80BA36B0 = 1; + } + + if (!(globalCtx->actorCtx.unk5 & 0x20)) { + if (!(OBJNOZOKI_GET_200(&this->dyna.actor)) && + Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + func_80BA2790(this); + } + } +} + +void func_80BA2B64(ObjNozoki* this, GlobalContext* globalCtx, s32 arg2, s32 arg3) { + this->unk_15D = arg2; + this->unk_15E = 80; + Flags_UnsetSwitch(globalCtx, arg3); +} + +void func_80BA2BA4(ObjNozoki* this, GlobalContext* globalCtx) { + if (!Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + this->dyna.actor.shape.rot.x = -0x1F40; + this->unk_15E = 80; + } else if (DECR(this->unk_15E) == 0) { + ObjNozoki_SetupAction(this, func_80BA2C94); + } +} + +s32 func_80BA2C28(ObjNozoki* this) { + s32 i; + s16 cs = this->unk_15F; + + for (i = 0; i < 3; i++) { + if (ActorCutscene_GetCurrentIndex() == cs) { + return i; + } + cs = ActorCutscene_GetAdditionalCutscene(cs); + } + + return -1; +} + +void func_80BA2C94(ObjNozoki* this, GlobalContext* globalCtx) { + s32 temp_v0 = func_80BA2C28(this); + f32 sp38; + f32 sp34; + f32 temp_f0; + + if (temp_v0 >= 0) { + D_80BA36B4 = temp_v0; + } + + if ((temp_v0 < 0) && Play_InCsMode(globalCtx)) { + return; + } + + if (D_80BA36B8 < D_80BA34D8[D_80BA36B4]) { + sp38 = this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y; + + if ((this->unk_15D != 1) && Flags_GetSwitch(globalCtx, this->dyna.actor.world.rot.z)) { + func_80BA2B64(this, globalCtx, 1, this->dyna.actor.world.rot.x); + } else if ((this->unk_15D != 2) && Flags_GetSwitch(globalCtx, this->dyna.actor.world.rot.x)) { + func_80BA2B64(this, globalCtx, 2, this->dyna.actor.world.rot.z); + } else if (DECR(this->unk_15E) == 0) { + this->unk_15D = 0; + Flags_UnsetSwitch(globalCtx, this->dyna.actor.world.rot.z); + Flags_UnsetSwitch(globalCtx, this->dyna.actor.world.rot.x); + } + + Math_StepToF(&this->dyna.actor.speedXZ, D_80BA34E4[this->unk_15D], 0.1f); + + if ((globalCtx->actorCtx.unk5 & 0x40) || (globalCtx->actorCtx.unk5 & 0x20)) { + temp_f0 = 0.5f; + } else { + temp_f0 = this->dyna.actor.speedXZ; + } + + sp34 = Math_Vec3f_StepToXZ(&this->dyna.actor.world.pos, &this->dyna.actor.home.pos, temp_f0); + + D_80BA36B8 += this->dyna.actor.speedXZ; + + if (globalCtx->actorCtx.unk5 & 0x40) { + if (sp34 <= 5.0f) { + Actor_MarkForDeath(&this->dyna.actor); + } + } else if (!(globalCtx->actorCtx.unk5 & 0x20) && (GET_PLAYER(globalCtx)->actor.id == ACTOR_PLAYER) && + Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG2(&this->dyna.actor)) && (sp38 < 20.0f)) { + static Vec3f D_80BA34F0 = { 0.0f, 0.0f, 50.0f }; + + globalCtx->actorCtx.unk5 |= 0x40; + Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.home.pos, this->dyna.actor.shape.rot.y, &D_80BA34F0, + &this->dyna.actor.world.pos); + this->dyna.actor.shape.rot.x = -0x1F40; + } else if (sp34 < 50.0f) { + globalCtx->actorCtx.unk5 |= 0x20; + + if (sp34 < 20.0f) { + this->dyna.actor.velocity.y -= 0.4f; + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; + + sp38 = this->dyna.actor.home.pos.y - this->dyna.actor.world.pos.y; + if (sp38 >= 100.0f) { + Actor_MarkForDeath(&this->dyna.actor); + } + + this->dyna.actor.shape.rot.x = -0x1F40 - (s16)(sp38 * 400.0f); + } + } + } + + this->dyna.actor.velocity.x += this->dyna.actor.speedXZ * 0.66f; + if (this->dyna.actor.velocity.x >= 0x10000) { + this->dyna.actor.velocity.x -= 0x10000; + } + + globalCtx->roomCtx.unk7A[0] = this->dyna.actor.velocity.x; + + func_8019FAD8(&D_801DB4A4, NA_SE_EV_SECOM_CONVEYOR - SFX_FLAG, this->dyna.actor.speedXZ); +} + +void func_80BA3044(ObjNozoki* this, GlobalContext* globalCtx) { + Vec3f* sp1C = &this->dyna.actor.focus.pos; + + if (this->unk_15D == 0) { + if (globalCtx->actorCtx.unk5 & 0x40) { + this->unk_15D = 1; + this->unk_15E = 20; + Math_Vec3f_Copy(&this->dyna.actor.world.pos, sp1C); + } else if (!(globalCtx->actorCtx.unk5 & 0x20) && + Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + sp1C = &this->dyna.actor.home.pos; + } + } else if (DECR(this->unk_15E) == 0) { + sp1C = &this->dyna.actor.home.pos; + } + + Math_Vec3f_StepToXZ(&this->dyna.actor.world.pos, sp1C, 8.0f); +} + +void func_80BA311C(ObjNozoki* this, GlobalContext* globalCtx) { + if (this->unk_15D == 0) { + if (Flags_GetSwitch(globalCtx, OBJNOZOKI_GET_SWITCHFLAG1(&this->dyna.actor))) { + this->unk_15D = 1; + this->unk_15E = 70; + } + } else if (this->unk_15D == 1) { + if (D_80BA36B8 > 40.0f) { + this->unk_15D = 2; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_PL_SIT_ON_HORSE); + } else if (this->unk_15E != 0) { + if (DECR(this->unk_15E) == 0) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_CONVEYOR_SHUTTER_OPEN); + } + } else { + Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y + 50.0f, 4.0f); + } + } else { + Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 4.0f); + } +} + +void func_80BA3230(ObjNozoki* this, GlobalContext* globalCtx) { + if (gSaveContext.save.weekEventReg[64] & 0x20) { + Actor* npc = globalCtx->actorCtx.actorLists[ACTORCAT_NPC].first; + Actor* test3 = SubS_FindActor(globalCtx, npc, ACTORCAT_NPC, ACTOR_EN_TEST3); + + if ((test3 != NULL) && (test3->draw != NULL)) { + if ((globalCtx->curSpawn == 3) && !(gSaveContext.save.weekEventReg[64] & 0x40)) { + this->dyna.actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10000); + this->dyna.actor.textId = 0x297A; + } else { + this->dyna.actor.flags |= (ACTOR_FLAG_1 | ACTOR_FLAG_8); + if (gSaveContext.save.weekEventReg[64] & 0x40) { + this->dyna.actor.textId = 0; + } else { + this->dyna.actor.textId = 0x2979; + } + } + + if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state)) { + ObjNozoki_SetupAction(this, func_80BA3344); + } else { + func_800B8614(&this->dyna.actor, globalCtx, 50.0f); + } + } + } +} + +void func_80BA3344(ObjNozoki* this, GlobalContext* globalCtx) { + if ((globalCtx->curSpawn == 3) && !(gSaveContext.save.weekEventReg[64] & 0x40)) { + if (Actor_TextboxIsClosing(&this->dyna.actor, globalCtx)) { + gSaveContext.save.weekEventReg[64] |= 0x40; + this->dyna.actor.flags &= ~ACTOR_FLAG_10000; + ObjNozoki_SetupAction(this, func_80BA3230); + } + } else if ((this->dyna.actor.textId == 0) || Actor_TextboxIsClosing(&this->dyna.actor, globalCtx)) { + globalCtx->nextEntranceIndex = 0xE20; + globalCtx->sceneLoadFlag = 0x14; + } +} + +void ObjNozoki_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjNozoki* this = THIS; + + this->actionFunc(this, globalCtx); +} + +Gfx* D_80BA34FC[] = { + object_secom_obj_DL_000080, + (Gfx*)0x0A0001A0, //! @bug This dlist should point to a dlist in OBJECT_GI_MSSA, but the segment and the offset are + //! wrong. This doesn't have side effects because of the extra check in the Draw function + object_secom_obj_DL_001230, + object_secom_obj_DL_001300, +}; + +void ObjNozoki_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjNozoki* this = THIS; + + if (this->unk_15C == 1) { + GetItem_Draw(globalCtx, GID_39); + } else { + Gfx_DrawDListOpa(globalCtx, D_80BA34FC[this->unk_15C]); + } +} diff --git a/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.h b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.h index 164e25ecc..08af2bc02 100644 --- a/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.h +++ b/src/overlays/actors/ovl_Obj_Nozoki/z_obj_nozoki.h @@ -7,9 +7,20 @@ struct ObjNozoki; typedef void (*ObjNozokiActionFunc)(struct ObjNozoki*, GlobalContext*); +#define OBJNOZOKI_GET_SWITCHFLAG1(thisx) ((thisx)->params & 0x7F) +#define OBJNOZOKI_GET_180(thisx) (((thisx)->params >> 7) & 3) +#define OBJNOZOKI_GET_200(thisx) ((thisx)->params & 0x200) +#define OBJNOZOKI_GET_400(thisx) ((thisx)->params & 0x400) +#define OBJNOZOKI_GET_SWITCHFLAG2(thisx) (((thisx)->params >> 9) & 0x7F) + +#define OBJNOZOKI_400 0x400 + typedef struct ObjNozoki { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ u8 unk_15C; + /* 0x015D */ u8 unk_15D; + /* 0x015E */ s8 unk_15E; + /* 0x015F */ s8 unk_15F; /* 0x0160 */ ObjNozokiActionFunc actionFunc; } ObjNozoki; // size = 0x164 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 04cf0040f..731bc4328 100644 --- a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c +++ b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_ocarinalift.c + * Overlay: ovl_Obj_Ocarinalift + * Description: Elevator With Triforce Texture (unused?) + */ + #include "z_obj_ocarinalift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjOcarinalift*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c index ab6b573a6..fac52301a 100644 --- a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c +++ b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.c @@ -1,6 +1,14 @@ -#include "z_obj_oshihiki.h" +/* + * File: z_obj_oshihiki.c + * Overlay: ovl_Obj_Oshihiki + * Description: Pushable Block + */ -#define FLAGS 0x00000010 +#include "z_obj_oshihiki.h" +#include "overlays/actors/ovl_Obj_Switch/z_obj_switch.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjOshihiki*)thisx) @@ -9,7 +17,14 @@ void ObjOshihiki_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjOshihiki_Update(Actor* thisx, GlobalContext* globalCtx); void ObjOshihiki_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObjOshihiki_OnScene(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_SetupOnActor(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_OnActor(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_SetupPush(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_Push(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_SetupFall(ObjOshihiki* this, GlobalContext* globalCtx); +void ObjOshihiki_Fall(ObjOshihiki* this, GlobalContext* globalCtx); + const ActorInit Obj_Oshihiki_InitVars = { ACTOR_OBJ_OSHIHIKI, ACTORCAT_PROP, @@ -22,69 +37,567 @@ const ActorInit Obj_Oshihiki_InitVars = { (ActorFunc)ObjOshihiki_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80918898[] = { +static f32 sScales[] = { 0.1f, 0.2f, 0.4f, 0.1f, 0.2f, 0.4f }; + +static Color_RGB8 sColors[] = { + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 500, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -#endif +// The vertices and center of the bottom face +static Vec3f sColCheckPoints[] = { + { 29.99f, 1.01f, -29.99f }, { -29.99f, 1.01f, -29.99f }, { -29.99f, 1.01f, 29.99f }, + { 29.99f, 1.01f, 29.99f }, { 0.0f, 1.01f, 0.0f }, +}; -extern InitChainEntry D_80918898[]; +static Vec2f sFaceVtx[] = { + { -30.0f, 0.0f }, { 30.0f, 0.0f }, { -30.0f, 60.0f }, { 30.0f, 60.0f }, { -30.0f, 20.0f }, { 30.0f, 20.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917290.s") +static Vec2f sFaceDirection[] = { + { 1.0f, 1.0f }, { -1.0f, 1.0f }, { 1.0f, -1.0f }, { -1.0f, -1.0f }, { 1.0f, 3.0f }, { -1.0f, 3.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_809172E4.s") +s8 D_80918940[] = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_8091734C.s") +void ObjOshihiki_RotateXZ(Vec3f* out, Vec3f* in, f32 sn, f32 cs) { + out->x = (in->z * sn) + (in->x * cs); + out->y = in->y; + out->z = (in->z * cs) - (in->x * sn); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917378.s") +s32 ObjOshihiki_StrongEnough(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 strength = OBJOSHIHIKI_GET_F(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917408.s") + if (this->cantMove) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917538.s") + if ((strength == OBJOSHIHIKI_F_0) || (strength == OBJOSHIHIKI_F_3)) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917604.s") + if (func_80124020() >= 2) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_8091763C.s") +void ObjOshihiki_ResetFloors(ObjOshihiki* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_8091768C.s") + for (i = 0; i < ARRAY_COUNT(this->floorBgIds); i++) { + this->floorBgIds[i] = BGCHECK_SCENE; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/ObjOshihiki_Init.s") +ObjOshihiki* ObjOshihiki_GetBlockUnder(ObjOshihiki* this, GlobalContext* globalCtx) { + DynaPolyActor* dyna; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/ObjOshihiki_Destroy.s") + if ((this->floorBgIds[this->highestFloor] != BGCHECK_SCENE) && + (fabsf(this->dyna.actor.floorHeight - this->dyna.actor.world.pos.y) < 0.001f)) { + dyna = DynaPoly_GetActor(&globalCtx->colCtx, this->floorBgIds[this->highestFloor]); + if ((dyna != NULL) && (dyna->actor.id == ACTOR_OBJ_OSHIHIKI)) { + return (ObjOshihiki*)dyna; + } + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917840.s") +void ObjOshihiki_UpdateInitPos(ObjOshihiki* this) { + if (this->dyna.actor.home.pos.x < this->dyna.actor.world.pos.x) { + while ((this->dyna.actor.world.pos.x - this->dyna.actor.home.pos.x) >= 60.0f) { + this->dyna.actor.home.pos.x += 60.0f; + } + } else { + while ((this->dyna.actor.home.pos.x - this->dyna.actor.world.pos.x) >= 60.0f) { + this->dyna.actor.home.pos.x -= 60.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_809179A0.s") + if (this->dyna.actor.home.pos.z < this->dyna.actor.world.pos.z) { + while ((this->dyna.actor.world.pos.z - this->dyna.actor.home.pos.z) >= 60.0f) { + this->dyna.actor.home.pos.z += 60.0f; + } + } else { + while ((this->dyna.actor.home.pos.z - this->dyna.actor.world.pos.z) >= 60.0f) { + this->dyna.actor.home.pos.z -= 60.0f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917AEC.s") +s32 ObjOshihiki_NoSwitchPress(ObjOshihiki* this, DynaPolyActor* dyna, GlobalContext* globalCtx) { + s16 dynaSwitchFlag; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917B44.s") + if (dyna == NULL) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917B9C.s") + if (dyna->actor.id == ACTOR_OBJ_SWITCH) { + dynaSwitchFlag = OBJSWITCH_GET_7F00(&dyna->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917C14.s") + switch (OBJSWITCH_GET_33(&dyna->actor)) { + case OBJSWITCH_NORMAL_BLUE: + if ((dynaSwitchFlag == OBJOSHIHIKI_GET_7F00(&this->dyna.actor)) && + Flags_GetSwitch(globalCtx, dynaSwitchFlag)) { + return false; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917E8C.s") + case OBJSWITCH_INVERSE_BLUE: + if ((dynaSwitchFlag == OBJOSHIHIKI_GET_7F00(&this->dyna.actor)) && + !Flags_GetSwitch(globalCtx, dynaSwitchFlag)) { + return false; + } + break; + } + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917F88.s") +void ObjOshihiki_SetScale(ObjOshihiki* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->dyna.actor, sScales[OBJOSHIHIKI_GET_F(&this->dyna.actor)]); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80917FC0.s") +void ObjOshihiki_SetTextureStep(ObjOshihiki* this, GlobalContext* globalCtx) { + switch (OBJOSHIHIKI_GET_F(&this->dyna.actor)) { + case OBJOSHIHIKI_F_0: + case OBJOSHIHIKI_F_3: + this->textureStep = 0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_809180C8.s") + case OBJOSHIHIKI_F_1: + case OBJOSHIHIKI_F_4: + this->textureStep = 1; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80918108.s") + case OBJOSHIHIKI_F_2: + case OBJOSHIHIKI_F_5: + this->textureStep = 2; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80918314.s") +void ObjOshihiki_SetColor(ObjOshihiki* this, GlobalContext* globalCtx) { + Color_RGB8* src = &sColors[OBJOSHIHIKI_GET_F0(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_8091834C.s") + this->color.r = src->r; + this->color.g = src->g; + this->color.b = src->b; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_8091851C.s") +void ObjOshihiki_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjOshihiki* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/func_80918574.s") + DynaPolyActor_Init(&this->dyna, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/ObjOshihiki_Update.s") + if ((OBJOSHIHIKI_GET_FF00(&this->dyna.actor) >= OBJOSHIHIKI_FF00_0) && + (OBJOSHIHIKI_GET_FF00(&this->dyna.actor) < OBJOSHIHIKI_FF00_80)) { + if (Flags_GetSwitch(globalCtx, OBJOSHIHIKI_GET_7F00(&this->dyna.actor))) { + switch (OBJOSHIHIKI_GET_F(&this->dyna.actor)) { + case OBJOSHIHIKI_F_0: + case OBJOSHIHIKI_F_1: + case OBJOSHIHIKI_F_2: + Actor_MarkForDeath(&this->dyna.actor); + return; + } + } else { + switch (OBJOSHIHIKI_GET_F(&this->dyna.actor)) { + case OBJOSHIHIKI_F_3: + case OBJOSHIHIKI_F_4: + case OBJOSHIHIKI_F_5: + Actor_MarkForDeath(&this->dyna.actor); + return; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Oshihiki/ObjOshihiki_Draw.s") + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gameplay_dangeon_keep_Colheader_007498); + this->texture = Lib_SegmentedToVirtual(gameplay_dangeon_keep_Matanimheader_01B370); + ObjOshihiki_SetScale(this, globalCtx); + ObjOshihiki_SetTextureStep(this, globalCtx); + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + ObjOshihiki_SetColor(this, globalCtx); + ObjOshihiki_ResetFloors(this); + ObjOshihiki_SetupOnActor(this, globalCtx); +} + +void ObjOshihiki_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjOshihiki* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void ObjOshihiki_SetFloors(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f colCheckPoint; + Vec3f colCheckOffset; + s32 i; + + for (i = 0; i < ARRAY_COUNT(sColCheckPoints); i++) { + colCheckOffset.x = sColCheckPoints[i].x * (this->dyna.actor.scale.x * 10.0f); + colCheckOffset.y = sColCheckPoints[i].y * (this->dyna.actor.scale.y * 10.0f); + colCheckOffset.z = sColCheckPoints[i].z * (this->dyna.actor.scale.z * 10.0f); + + ObjOshihiki_RotateXZ(&colCheckPoint, &colCheckOffset, this->yawSin, this->yawCos); + + colCheckPoint.x += this->dyna.actor.world.pos.x; + colCheckPoint.y += this->dyna.actor.prevPos.y; + colCheckPoint.z += this->dyna.actor.world.pos.z; + + this->floorHeights[i] = BgCheck_EntityRaycastFloor6( + &globalCtx->colCtx, &this->floorPolys[i], &this->floorBgIds[i], &this->dyna.actor, &colCheckPoint, 0.0f); + } +} + +s16 ObjOshihiki_GetHighestFloor(ObjOshihiki* this) { + s32 i; + s16 highestFloor = 0; + + for (i = 1; i < ARRAY_COUNT(this->floorHeights); i++) { + if (this->floorHeights[i] > this->floorHeights[highestFloor]) { + highestFloor = i; + } else if ((this->floorBgIds[i] == BGCHECK_SCENE) && + ((this->floorHeights[i] - this->floorHeights[highestFloor]) > -0.001f)) { + highestFloor = i; + } + } + + return highestFloor; +} + +void ObjOshihiki_SetGround(ObjOshihiki* this, GlobalContext* globalCtx) { + ObjOshihiki_ResetFloors(this); + ObjOshihiki_SetFloors(this, globalCtx); + this->highestFloor = ObjOshihiki_GetHighestFloor(this); + this->dyna.actor.floorHeight = this->floorHeights[this->highestFloor]; +} + +s32 ObjOshihiki_CheckFloor(ObjOshihiki* this, GlobalContext* globalCtx) { + ObjOshihiki_SetGround(this, globalCtx); + + if ((this->dyna.actor.floorHeight - this->dyna.actor.world.pos.y) >= -0.001f) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; + return true; + } + return false; +} + +s32 ObjOshihiki_CheckGround(ObjOshihiki* this, GlobalContext* globalCtx) { + if (this->dyna.actor.world.pos.y <= BGCHECK_Y_MIN + 10.0f) { + Actor_MarkForDeath(&this->dyna.actor); + return false; + } + + if ((this->dyna.actor.floorHeight - this->dyna.actor.world.pos.y) >= -0.001f) { + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; + return true; + } + return false; +} + +s32 ObjOshihiki_CheckWall(GlobalContext* globalCtx, s16 angle, f32 direction, ObjOshihiki* this) { + f32 maxDists[2]; + f32 maxDist; + f32 sn; + f32 cs; + s32 i; + Vec3f faceVtx; + Vec3f faceVtxNext; + Vec3f posResult; + Vec3f faceVtxOffset; + s32 bgId; + CollisionPoly* outPoly; + + sn = Math_SinS(angle); + cs = Math_CosS(angle); + + maxDists[0] = ((this->dyna.actor.scale.x * 300.0f) + 60.0f) - 0.5f; + if (direction > 0.0f) { + maxDists[1] = maxDists[0]; + } else { + maxDists[0] = -maxDists[0]; + maxDists[1] = -(((this->dyna.actor.scale.x * 300.0f) + 90.0f) - 0.5f); + } + + for (i = 0; i < ARRAY_COUNT(sFaceDirection); i++) { + maxDist = maxDists[D_80918940[i]]; + + faceVtxOffset.x = (sFaceVtx[i].x * this->dyna.actor.scale.x * 10.0f) + sFaceDirection[i].x; + faceVtxOffset.y = (sFaceVtx[i].z * this->dyna.actor.scale.y * 10.0f) + sFaceDirection[i].z; + faceVtxOffset.z = 0.0f; + + ObjOshihiki_RotateXZ(&faceVtx, &faceVtxOffset, sn, cs); + + faceVtx.x += this->dyna.actor.world.pos.x; + faceVtx.y += this->dyna.actor.world.pos.y; + faceVtx.z += this->dyna.actor.world.pos.z; + + faceVtxNext.x = (maxDist * sn) + faceVtx.x; + faceVtxNext.y = faceVtx.y; + faceVtxNext.z = (maxDist * cs) + faceVtx.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &faceVtx, &faceVtxNext, &posResult, &outPoly, true, false, + false, true, &bgId, &this->dyna.actor, 0.0f)) { + return true; + } + } + return false; +} + +s32 ObjOshihiki_MoveWithBlockUnder(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 pad; + ObjOshihiki* blockUnder = ObjOshihiki_GetBlockUnder(this, globalCtx); + + if ((blockUnder != NULL) && (blockUnder->stateFlags & PUSHBLOCK_SETUP_PUSH)) { + if (!ObjOshihiki_CheckWall(globalCtx, blockUnder->dyna.yRotation, blockUnder->direction, this)) { + this->blockUnder = blockUnder; + } + } + + if (this->stateFlags & PUSHBLOCK_MOVE_UNDER) { + if (this->blockUnder != NULL) { + if (this->blockUnder->stateFlags & PUSHBLOCK_PUSH) { + this->underDistX = this->blockUnder->dyna.actor.world.pos.x - this->blockUnder->dyna.actor.prevPos.x; + this->underDistZ = this->blockUnder->dyna.actor.world.pos.z - this->blockUnder->dyna.actor.prevPos.z; + this->dyna.actor.world.pos.x += this->underDistX; + this->dyna.actor.world.pos.z += this->underDistZ; + ObjOshihiki_UpdateInitPos(this); + return true; + } + + if (!(this->blockUnder->stateFlags & PUSHBLOCK_SETUP_PUSH)) { + this->blockUnder = NULL; + } + } + } + return false; +} + +void ObjOshihiki_SetupOnScene(ObjOshihiki* this, GlobalContext* globalCtx) { + this->stateFlags |= PUSHBLOCK_SETUP_ON_SCENE; + this->dyna.actor.gravity = 0.0f; + this->dyna.actor.velocity.z = 0.0f; + this->dyna.actor.velocity.y = 0.0f; + this->dyna.actor.velocity.x = 0.0f; + this->actionFunc = ObjOshihiki_OnScene; +} + +void ObjOshihiki_OnScene(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + this->stateFlags |= PUSHBLOCK_ON_SCENE; + + if (this->timer <= 0) { + if (fabsf(this->dyna.pushForce) > 0.001f) { + if (ObjOshihiki_StrongEnough(this, globalCtx)) { + if (!ObjOshihiki_CheckWall(globalCtx, this->dyna.yRotation, this->dyna.pushForce, this)) { + this->direction = this->dyna.pushForce; + ObjOshihiki_SetupPush(this, globalCtx); + return; + } + } + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } + } else if (fabsf(this->dyna.pushForce) > 0.001f) { + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void ObjOshihiki_SetupOnActor(ObjOshihiki* this, GlobalContext* globalCtx) { + this->stateFlags |= PUSHBLOCK_SETUP_ON_ACTOR; + this->dyna.actor.velocity.z = 0.0f; + this->dyna.actor.velocity.y = 0.0f; + this->dyna.actor.velocity.x = 0.0f; + this->dyna.actor.gravity = -1.0f; + this->actionFunc = ObjOshihiki_OnActor; +} + +void ObjOshihiki_OnActor(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + DynaPolyActor* dyna; + s32 sp20 = false; + + this->stateFlags |= PUSHBLOCK_ON_ACTOR; + Actor_MoveWithGravity(&this->dyna.actor); + + if (ObjOshihiki_CheckFloor(this, globalCtx)) { + if (this->floorBgIds[this->highestFloor] == BGCHECK_SCENE) { + ObjOshihiki_SetupOnScene(this, globalCtx); + } else { + dyna = DynaPoly_GetActor(&globalCtx->colCtx, this->floorBgIds[this->highestFloor]); + if (dyna != NULL) { + DynaPolyActor_SetRidingFallingState(dyna); + DynaPolyActor_SetSwitchPressedState(dyna); + if ((this->timer <= 0) && (fabsf(this->dyna.pushForce) > 0.001f) && + ObjOshihiki_StrongEnough(this, globalCtx) && ObjOshihiki_NoSwitchPress(this, dyna, globalCtx) && + !ObjOshihiki_CheckWall(globalCtx, this->dyna.yRotation, this->dyna.pushForce, this)) { + this->direction = this->dyna.pushForce; + ObjOshihiki_SetupPush(this, globalCtx); + sp20 = true; + } + } else { + ObjOshihiki_SetupOnScene(this, globalCtx); + } + } + } else if (this->floorBgIds[this->highestFloor] == BGCHECK_SCENE) { + ObjOshihiki_SetupFall(this, globalCtx); + } else { + dyna = DynaPoly_GetActor(&globalCtx->colCtx, this->floorBgIds[this->highestFloor]); + if ((dyna != NULL) && (dyna->flags & 1)) { + DynaPolyActor_SetRidingFallingState(dyna); + DynaPolyActor_SetSwitchPressedState(dyna); + this->dyna.actor.world.pos.y = this->dyna.actor.floorHeight; + } else { + ObjOshihiki_SetupFall(this, globalCtx); + } + } + + if (!sp20 && (fabsf(this->dyna.pushForce) > 0.001f)) { + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void ObjOshihiki_SetupPush(ObjOshihiki* this, GlobalContext* globalCtx) { + this->stateFlags |= PUSHBLOCK_SETUP_PUSH; + this->dyna.actor.gravity = 0.0f; + this->pushSpeed = 2.0f; + this->actionFunc = ObjOshihiki_Push; +} + +void ObjOshihiki_Push(ObjOshihiki* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + f32 pushDistSigned; + s32 stopFlag; + + this->stateFlags |= PUSHBLOCK_PUSH; + stopFlag = Math_StepToF(&this->pushDist, 60.0f, this->pushSpeed); + + pushDistSigned = ((this->direction >= 0.0f) ? 1.0f : -1.0f) * this->pushDist; + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + (pushDistSigned * this->yawSin); + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + (pushDistSigned * this->yawCos); + + if (!ObjOshihiki_CheckFloor(this, globalCtx)) { + this->dyna.actor.home.pos.x = this->dyna.actor.world.pos.x; + this->dyna.actor.home.pos.z = this->dyna.actor.world.pos.z; + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + this->pushDist = 0.0f; + this->pushSpeed = 0.0f; + ObjOshihiki_SetupFall(this, globalCtx); + } else if (stopFlag) { + player = GET_PLAYER(globalCtx); + + if (ObjOshihiki_CheckWall(globalCtx, this->dyna.yRotation, this->dyna.pushForce, this)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + + this->dyna.actor.home.pos.x = this->dyna.actor.world.pos.x; + this->dyna.actor.home.pos.z = this->dyna.actor.world.pos.z; + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + this->pushDist = 0.0f; + this->pushSpeed = 0.0f; + this->timer = 10; + + if (this->floorBgIds[this->highestFloor] == BGCHECK_SCENE) { + ObjOshihiki_SetupOnScene(this, globalCtx); + } else { + ObjOshihiki_SetupOnActor(this, globalCtx); + } + } + + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); +} + +void ObjOshihiki_SetupFall(ObjOshihiki* this, GlobalContext* globalCtx) { + this->stateFlags |= PUSHBLOCK_SETUP_FALL; + this->dyna.actor.velocity.z = 0.0f; + this->dyna.actor.velocity.y = 0.0f; + this->dyna.actor.velocity.x = 0.0f; + this->dyna.actor.gravity = -1.0f; + ObjOshihiki_SetGround(this, globalCtx); + this->actionFunc = ObjOshihiki_Fall; +} + +void ObjOshihiki_Fall(ObjOshihiki* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 temp_t4; + + this->stateFlags |= PUSHBLOCK_FALL; + + if (fabsf(this->dyna.pushForce) > 0.001f) { + this->dyna.pushForce = 0.0f; + player->stateFlags2 &= ~0x10; + } + + Actor_MoveWithGravity(&this->dyna.actor); + + if (ObjOshihiki_CheckGround(this, globalCtx)) { + if (this->floorBgIds[this->highestFloor] == BGCHECK_SCENE) { + ObjOshihiki_SetupOnScene(this, globalCtx); + } else { + ObjOshihiki_SetupOnActor(this, globalCtx); + } + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Actor_PlaySfxAtPos(&this->dyna.actor, + SurfaceType_GetSfx(&globalCtx->colCtx, this->floorPolys[this->highestFloor], + this->floorBgIds[this->highestFloor]) + + SFX_FLAG); + } +} + +void ObjOshihiki_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjOshihiki* this = THIS; + + this->stateFlags &= + ~(PUSHBLOCK_SETUP_FALL | PUSHBLOCK_FALL | PUSHBLOCK_SETUP_PUSH | PUSHBLOCK_PUSH | PUSHBLOCK_SETUP_ON_ACTOR | + PUSHBLOCK_ON_ACTOR | PUSHBLOCK_SETUP_ON_SCENE | PUSHBLOCK_ON_SCENE); + this->stateFlags |= PUSHBLOCK_MOVE_UNDER; + if (this->timer > 0) { + this->timer--; + } + + this->dyna.actor.world.rot.y = this->dyna.yRotation; + this->yawSin = Math_SinS(this->dyna.actor.world.rot.y); + this->yawCos = Math_CosS(this->dyna.actor.world.rot.y); + + if (this->actionFunc != NULL) { + this->actionFunc(this, globalCtx); + } +} + +void ObjOshihiki_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjOshihiki* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (ObjOshihiki_MoveWithBlockUnder(this, globalCtx)) { + Matrix_Translate(this->underDistX * 10.0f, 0.0f, this->underDistZ * 10.0f, MTXMODE_APPLY); + } + + this->stateFlags &= ~PUSHBLOCK_MOVE_UNDER; + func_8012C28C(globalCtx->state.gfxCtx); + AnimatedMat_DrawStep(globalCtx, this->texture, this->textureStep); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0xFF, 0xFF, this->color.r, this->color.g, this->color.b, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_dangeon_keep_DL_0182A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h index 4b265f4be..e08630132 100644 --- a/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h +++ b/src/overlays/actors/ovl_Obj_Oshihiki/z_obj_oshihiki.h @@ -7,11 +7,57 @@ struct ObjOshihiki; typedef void (*ObjOshihikiActionFunc)(struct ObjOshihiki*, GlobalContext*); +#define OBJOSHIHIKI_GET_F(thisx) ((thisx)->params & 0xF) +#define OBJOSHIHIKI_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) +#define OBJOSHIHIKI_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) +#define OBJOSHIHIKI_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +enum { + /* 0 */ OBJOSHIHIKI_F_0, + /* 1 */ OBJOSHIHIKI_F_1, + /* 2 */ OBJOSHIHIKI_F_2, + /* 3 */ OBJOSHIHIKI_F_3, + /* 4 */ OBJOSHIHIKI_F_4, + /* 5 */ OBJOSHIHIKI_F_5, + /* 6 */ OBJOSHIHIKI_F_6, + /* 7 */ OBJOSHIHIKI_F_7, + /* 8 */ OBJOSHIHIKI_F_8, +}; + +#define OBJOSHIHIKI_FF00_0 0 +#define OBJOSHIHIKI_FF00_80 0x80 + +#define PUSHBLOCK_ON_SCENE (1 << 0) +#define PUSHBLOCK_SETUP_ON_SCENE (1 << 1) +#define PUSHBLOCK_ON_ACTOR (1 << 2) +#define PUSHBLOCK_SETUP_ON_ACTOR (1 << 3) +#define PUSHBLOCK_PUSH (1 << 4) +#define PUSHBLOCK_SETUP_PUSH (1 << 5) +#define PUSHBLOCK_FALL (1 << 6) +#define PUSHBLOCK_SETUP_FALL (1 << 7) +#define PUSHBLOCK_MOVE_UNDER (1 << 8) + typedef struct ObjOshihiki { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjOshihikiActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x6C]; + /* 0x0160 */ u16 stateFlags; + /* 0x0162 */ s16 timer; + /* 0x0164 */ f32 yawSin; + /* 0x0168 */ f32 yawCos; + /* 0x016C */ f32 pushSpeed; + /* 0x0170 */ f32 pushDist; + /* 0x0174 */ f32 direction; + /* 0x0178 */ s32 floorBgIds[5]; + /* 0x018C */ CollisionPoly* floorPolys[5]; + /* 0x01A0 */ f32 floorHeights[5]; + /* 0x01B4 */ s16 highestFloor; + /* 0x01B6 */ u8 cantMove; + /* 0x01B8 */ struct ObjOshihiki* blockUnder; + /* 0x01BC */ f32 underDistX; + /* 0x01C0 */ f32 underDistZ; + /* 0x01C4 */ s8 textureStep; + /* 0x01C5 */ Color_RGB8 color; + /* 0x01C8 */ AnimatedMaterial* texture; } ObjOshihiki; // size = 0x1CC extern const ActorInit Obj_Oshihiki_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c index 5f61a8a3e..0f594f1e1 100644 --- a/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c +++ b/src/overlays/actors/ovl_Obj_Purify/z_obj_purify.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_purify.c + * Overlay: ovl_Obj_Purify + * Description: Poisoned/Purified Water Elements + */ + #include "z_obj_purify.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjPurify*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c index a9f582a37..95b9a3a13 100644 --- a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c +++ b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.c @@ -1,6 +1,14 @@ -#include "z_obj_pzlblock.h" +/* + * File: z_obj_pzlblock.c + * Overlay: ovl_Obj_Pzlblock + * Description: Puzzle Block + */ -#define FLAGS 0x04000010 +#include "z_obj_pzlblock.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_secom_obj/object_secom_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_4000000) #define THIS ((ObjPzlblock*)thisx) @@ -8,7 +16,15 @@ void ObjPzlblock_Init(Actor* thisx, GlobalContext* globalCtx); void ObjPzlblock_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjPzlblock_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_809A3A48(ObjPzlblock* this); +void func_809A3A74(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3BA4(ObjPzlblock* this); +void func_809A3BC0(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3D1C(ObjPzlblock* this); +void func_809A3D38(ObjPzlblock* this, GlobalContext* globalCtx); +void func_809A3E58(Actor* thisx, GlobalContext* globalCtx); +void func_809A3F0C(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Pzlblock_InitVars = { ACTOR_OBJ_PZLBLOCK, ACTORCAT_PROP, @@ -21,46 +37,337 @@ const ActorInit Obj_Pzlblock_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_809A4078[] = { +s16 D_809A4050[] = { 1, -1, 0, 0 }; +s16 D_809A4058[] = { 0, 0, 1, -1 }; + +typedef struct { + /* 0x0 */ s16 unk_00; + /* 0x4 */ CollisionHeader* unk_04; + /* 0x8 */ Gfx* unk_08; +} ObjPzlblockStruct; + +ObjPzlblockStruct D_809A4060[] = { + { GAMEPLAY_DANGEON_KEEP, &gameplay_dangeon_keep_Colheader_01D488, gameplay_dangeon_keep_DL_01C228 }, + { OBJECT_SECOM_OBJ, &object_secom_obj_Colheader_002CB8, object_secom_obj_DL_001A58 }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3S(world.rot, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif +Color_RGB8 D_809A4088[] = { + { 180, 150, 250 }, { 100, 180, 150 }, { 0, 0, 255 }, { 255, 255, 0 }, + { 0, 255, 255 }, { 255, 0, 255 }, { 0, 0, 0 }, { 255, 255, 255 }, +}; -extern InitChainEntry D_809A4078[]; +s32 func_809A33E0(ObjPzlblock* this, GlobalContext* globalCtx, s16 arg2) { + return !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 1) || + !DynaPolyActor_ValidateMove(globalCtx, &this->dyna, 30, arg2, 28); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A33E0.s") +s32 func_809A3448(ObjPzlblock* this) { + s16 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3448.s") + if (fabsf(this->dyna.pushForce) > 0.1f) { + temp_v0 = BINANG_ADD(this->dyna.yRotation, 0x2000); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A34E0.s") + if (this->dyna.pushForce < 0.0f) { + temp_v0 = BINANG_ROT180(temp_v0); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A35EC.s") + if (temp_v0 < -0x4000) { + return 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A376C.s") + if (temp_v0 < 0) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Init.s") + if (temp_v0 < 0x4000) { + return 2; + } + return 0; + } + return -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Destroy.s") +s32 func_809A34E0(ObjPzlblock* this, s32 arg1) { + s32 temp_v0 = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3A48.s") + if (temp_v0 == 0) { + return arg1 == 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3A74.s") + if (temp_v0 == 1) { + return arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3BA4.s") + if (temp_v0 == 2) { + return arg1 == 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3BC0.s") + if (temp_v0 == 3) { + return arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3D1C.s") + if (temp_v0 == 4) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3D38.s") + if (temp_v0 == 5) { + return arg1 == 2 || arg1 == 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/ObjPzlblock_Update.s") + if (temp_v0 == 6) { + if (this->unk_176 != 0) { + return arg1 == 0 || arg1 == 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3E58.s") + if (this->unk_178 != 0) { + return arg1 == 2 || arg1 == 3; + } + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Pzlblock/func_809A3F0C.s") +s32 func_809A35EC(ObjPzlblock* this, s32 arg1) { + s32 temp_v0 = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 temp_v1 = this->dyna.actor.home.rot.x & 0xF; + s32 temp; + + if (temp_v0 == 0) { + return this->unk_176 < temp_v1; + } + + if (temp_v0 == 1) { + return -temp_v1 < this->unk_176; + } + + if (temp_v0 == 2) { + return this->unk_178 < temp_v1; + } + + if (temp_v0 == 3) { + return -temp_v1 < this->unk_178; + } + + if (temp_v0 == 4) { + temp = D_809A4050[arg1] + this->unk_176; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + if (temp_v0 == 5) { + temp = D_809A4058[arg1] + this->unk_178; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + if (temp_v0 == 6) { + if ((arg1 == 0) || (arg1 == 1)) { + temp = D_809A4050[arg1] + this->unk_176; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + temp = D_809A4058[arg1] + this->unk_178; + return (temp_v1 >= temp) && (-temp_v1 <= temp); + } + + return false; +} + +void func_809A376C(ObjPzlblock* this, s32 arg1) { + this->unk_176 += D_809A4050[arg1]; + this->unk_178 += D_809A4058[arg1]; + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_164 = &this->dyna.actor.world.pos.x; + this->unk_168 = this->dyna.actor.home.pos.x + (this->unk_176 * 60); + } else { + this->unk_164 = &this->dyna.actor.world.pos.z; + this->unk_168 = this->dyna.actor.home.pos.z + (this->unk_178 * 60); + } + this->unk_16C = arg1; +} + +void ObjPzlblock_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjPzlblock* this = THIS; + s32 sp2C = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 sp28 = this->dyna.actor.home.rot.x & 0xF; + ObjPzlblockStruct* sp24 = &D_809A4060[OBJPZLBLOCK_GET_1000(&this->dyna.actor)]; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, 0.1f); + + this->dyna.actor.home.rot.y = 0; + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + + DynaPolyActor_Init(&this->dyna, 0); + + this->unk_17A = Object_GetIndex(&globalCtx->objectCtx, sp24->unk_00); + + if (sp28 == 0) { + func_809A3D1C(this); + } else if (Flags_GetSwitch(globalCtx, OBJPZLBLOCK_GET_7F(&this->dyna.actor))) { + if (sp2C == 0) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 1) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x - (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 2) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + (sp28 * 60); + func_809A3D1C(this); + } else if (sp2C == 3) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z - (sp28 * 60); + func_809A3D1C(this); + } else { + func_809A3A48(this); + } + } else { + func_809A3A48(this); + } +} + +void ObjPzlblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_809A3A48(ObjPzlblock* this) { + this->actionFunc = func_809A3A74; + this->unk_16E[1] = 0; + this->unk_16E[2] = 0; + this->unk_16E[3] = 0; + this->unk_16E[0] = 0; + this->unk_160 = 4; +} + +void func_809A3A74(ObjPzlblock* this, GlobalContext* globalCtx) { + s32 i; + s32 sp20 = func_809A3448(this); + + for (i = 0; i < ARRAY_COUNT(this->unk_16E); i++) { + if (sp20 == i) { + this->unk_16E[i]++; + } else if (this->unk_16E[i] > 0) { + this->unk_16E[i]--; + } + } + + if (sp20 != -1) { + if ((this->unk_16E[sp20] >= 11) && func_809A34E0(this, sp20) && func_809A35EC(this, sp20)) { + if (!func_809A33E0(this, globalCtx, (this->dyna.pushForce > 0.0f) ? 90 : 120)) { + func_809A376C(this, sp20); + func_809A3BA4(this); + return; + } + } + + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void func_809A3BA4(ObjPzlblock* this) { + this->actionFunc = func_809A3BC0; + this->unk_160 = 5; +} + +void func_809A3BC0(ObjPzlblock* this, GlobalContext* globalCtx) { + if (Math_StepToF(this->unk_164, this->unk_168, 2.3f)) { + Player* player = GET_PLAYER(globalCtx); + s32 params = OBJPZLBLOCK_GET_ROTZ(&this->dyna.actor); + s32 pad; + s32 sp20 = 0; + + if ((params == 4) || (params == 5) || (params == 6)) { + if (!func_809A35EC(this, this->unk_16C) || func_809A33E0(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else if (func_809A35EC(this, this->unk_16C)) { + if (func_809A33E0(this, globalCtx, 0x5A)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + } else { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + Flags_SetSwitch(globalCtx, OBJPZLBLOCK_GET_7F(&this->dyna.actor)); + sp20 = 1; + } + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + if (sp20 == 0) { + func_809A3A48(this); + } else { + func_809A3D1C(this); + } + } else { + func_800B9010(&this->dyna.actor, NA_SE_EV_ROCK_SLIDE - SFX_FLAG); + } +} + +void func_809A3D1C(ObjPzlblock* this) { + this->actionFunc = func_809A3D38; + this->unk_160 = 4; +} + +void func_809A3D38(ObjPzlblock* this, GlobalContext* globalCtx) { + if (fabsf(this->dyna.pushForce) > 0.1f) { + GET_PLAYER(globalCtx)->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; + } +} + +void ObjPzlblock_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjPzlblock* this = THIS; + + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 0.0f, 4); + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_17A)) { + ObjPzlblockStruct* sp2C = &D_809A4060[OBJPZLBLOCK_GET_1000(&this->dyna.actor)]; + + this->dyna.actor.objBankIndex = this->unk_17A; + Actor_SetObjectDependency(globalCtx, &this->dyna.actor); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, sp2C->unk_04); + this->dyna.actor.update = func_809A3E58; + this->dyna.actor.draw = func_809A3F0C; + } +} + +void func_809A3E58(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblock* this = THIS; + + this->actionFunc(this, globalCtx); + + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y; + + if (this->unk_160 != 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->dyna.actor, 15.0f, 30.0f, 0.0f, this->unk_160); + if (((this->actionFunc == func_809A3A74) || (this->actionFunc == func_809A3D38)) && + (this->dyna.actor.bgCheckFlags & 1) && !DynaPoly_GetActor(&globalCtx->colCtx, this->dyna.actor.floorBgId)) { + this->unk_160 = 0; + } + } +} + +void func_809A3F0C(Actor* thisx, GlobalContext* globalCtx) { + ObjPzlblockStruct* sp2C = &D_809A4060[OBJPZLBLOCK_GET_1000(thisx)]; + Color_RGB8* sp28 = &D_809A4088[OBJPZLBLOCK_GET_700(thisx)]; + + 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); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, sp28->r, sp28->g, sp28->b, 255); + gSPDisplayList(POLY_OPA_DISP++, sp2C->unk_08); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h index 437583f62..fa1ca1f59 100644 --- a/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h +++ b/src/overlays/actors/ovl_Obj_Pzlblock/z_obj_pzlblock.h @@ -5,9 +5,24 @@ struct ObjPzlblock; +typedef void (*ObjPzlblockActionFunc)(struct ObjPzlblock*, GlobalContext*); + +#define OBJPZLBLOCK_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJPZLBLOCK_GET_700(thisx) (((thisx)->params >> 8) & 7) +#define OBJPZLBLOCK_GET_1000(thisx) (((thisx)->params >> 0xC) & 1) +#define OBJPZLBLOCK_GET_ROTZ(thisx) ((thisx)->home.rot.z & 7) + typedef struct ObjPzlblock { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x38]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ObjPzlblockActionFunc actionFunc; + /* 0x160 */ s32 unk_160; + /* 0x164 */ f32* unk_164; + /* 0x168 */ f32 unk_168; + /* 0x16C */ s16 unk_16C; + /* 0x16E */ s16 unk_16E[4]; + /* 0x176 */ s16 unk_176; + /* 0x178 */ s16 unk_178; + /* 0x17A */ s8 unk_17A; } ObjPzlblock; // size = 0x17C extern const ActorInit Obj_Pzlblock_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c index eb9202197..24f3fe0d6 100644 --- a/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c +++ b/src/overlays/actors/ovl_Obj_Raillift/z_obj_raillift.c @@ -5,8 +5,9 @@ */ #include "z_obj_raillift.h" +#include "objects/object_raillift/object_raillift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjRaillift*)thisx) @@ -26,12 +27,6 @@ void ObjRaillift_Teleport(ObjRaillift* this, GlobalContext* globalCtx); void ObjRaillift_Wait(ObjRaillift* this, GlobalContext* globalCtx); void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx); -extern CollisionHeader D_06004FF8; -extern CollisionHeader D_060048D0; -extern Gfx D_06004BF0[]; -extern Gfx D_06000208[]; -extern Gfx D_060071B8[]; - const ActorInit Obj_Raillift_InitVars = { ACTOR_OBJ_RAILLIFT, ACTORCAT_BG, @@ -51,7 +46,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -static CollisionHeader* sColHeaders[] = { &D_06004FF8, &D_060048D0 }; +static CollisionHeader* sColHeaders[] = { &object_raillift_Colheader_004FF8, &object_raillift_Colheader_0048D0 }; void ObjRaillift_UpdatePosition(ObjRaillift* this, s32 idx) { Math_Vec3s_ToVec3f(&this->dyna.actor.world.pos, &this->points[idx]); @@ -70,8 +65,8 @@ void ObjRaillift_Init(Actor* thisx, GlobalContext* globalCtx) { thisx->world.rot.x = 0; thisx->shape.rot.z = 0; thisx->world.rot.z = 0; - BcCheck3_BgActorInit(&this->dyna, 1); - BgCheck3_LoadMesh(globalCtx, &this->dyna, sColHeaders[type]); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, sColHeaders[type]); this->speed = OBJRAILLIFT_GET_SPEED(thisx); if (this->speed < 0.0f) { this->speed = -this->speed; @@ -94,7 +89,7 @@ void ObjRaillift_Init(Actor* thisx, GlobalContext* globalCtx) { this->curPoint = OBJRAILLIFT_GET_STARTING_POINT(thisx); this->endPoint = path->count - 1; this->direction = 1; - this->points = (Vec3s*)Lib_SegmentedToVirtual(path->points); + this->points = Lib_SegmentedToVirtual(path->points); ObjRaillift_UpdatePosition(this, this->curPoint); if (OBJRAILLIFT_HAS_FLAG(thisx) && !Flags_GetSwitch(globalCtx, OBJRAILLIFT_GET_FLAG(thisx))) { this->actionFunc = ObjRaillift_Idle; @@ -107,7 +102,7 @@ void ObjRaillift_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjRaillift_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjRaillift* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjRaillift_DoNothing(ObjRaillift* this, GlobalContext* globalCtx) { @@ -187,7 +182,7 @@ void ObjRaillift_Move(ObjRaillift* this, GlobalContext* globalCtx) { Will teleport to what ever curpoint is set to */ void ObjRaillift_Teleport(ObjRaillift* this, GlobalContext* globalCtx) { - if (!func_800CAF70(&this->dyna)) { + if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { ObjRaillift_UpdatePosition(this, this->curPoint); func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); this->actionFunc = ObjRaillift_Move; @@ -226,7 +221,7 @@ void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx) { f32 step; this->actionFunc(this, globalCtx); - Actor_SetHeight(&this->dyna.actor, 10.0f); + Actor_SetFocus(&this->dyna.actor, 10.0f); if (this->cutsceneTimer > 0) { this->cutsceneTimer--; if (this->cutsceneTimer == 0) { @@ -237,7 +232,7 @@ void ObjRaillift_Update(Actor* thisx, GlobalContext* globalCtx) { s32 requiredScopeTemp; this->isWeightOnPrev = this->isWeightOn; - if (func_800CAF70(&this->dyna)) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { this->isWeightOn = true; } else { this->isWeightOn = false; @@ -275,7 +270,7 @@ void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx) { Gfx_TwoTexScrollEnvColor(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames, 0, 32, 32, 1, 0, 0, 32, 32, 0, 0, 0, 160)); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_OPA_DISP++, D_06004BF0); + gSPDisplayList(POLY_OPA_DISP++, object_raillift_DL_004BF0); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -283,12 +278,12 @@ void ObjRaillift_Draw(Actor* thisx, GlobalContext* globalCtx) { The non-colorful platforms are the ones found in Woodfall Temple */ void ObjRaillift_DrawDekuFlowerPlatform(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000208); + Gfx_DrawDListOpa(globalCtx, object_raillift_DL_000208); } /* The colorful platforms are the ones found in Deku Palace */ void ObjRaillift_DrawDekuFlowerPlatformColorful(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_060071B8); + Gfx_DrawDListOpa(globalCtx, object_raillift_DL_0071B8); } 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 219e89321..ff0c8d270 100644 --- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c +++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_roomtimer.c + * Overlay: ovl_Obj_Roomtimer + * Description: + */ + #include "z_obj_roomtimer.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjRoomtimer*)thisx) @@ -12,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, @@ -25,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 (Flags_GetClearTemp(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->state); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80973DE0(ObjRoomtimer* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + Flags_SetClear(globalCtx, this->actor.room); + Flags_SetSwitch(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_Rotlift/z_obj_rotlift.c b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c index 2f10d6a68..6163c753c 100644 --- a/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c +++ b/src/overlays/actors/ovl_Obj_Rotlift/z_obj_rotlift.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_rotlift.c + * Overlay: ovl_Obj_Rotlift + * Description: Deku Moon Dungeon - Spiked Rotating Platforms + */ + #include "z_obj_rotlift.h" #define FLAGS 0x00000000 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 d067ff2b3..f6f744d15 100644 --- a/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c +++ b/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_shutter.c + * Overlay: ovl_Obj_Shutter + * Description: Unused West Clock Town bank closing shutter + */ + #include "z_obj_shutter.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjShutter*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.c b/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.c index 83612cfa3..1253747e4 100644 --- a/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.c +++ b/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.c @@ -1,6 +1,13 @@ -#include "z_obj_skateblock.h" +/* + * File: z_obj_skateblock.c + * Overlay: ovl_Obj_Skateblock + * Description: Pushable block that slides on ice + */ -#define FLAGS 0x00000010 +#include "z_obj_skateblock.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjSkateblock*)thisx) @@ -9,7 +16,17 @@ void ObjSkateblock_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSkateblock_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSkateblock_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A22308(ObjSkateblock* this); +void func_80A22334(ObjSkateblock* this, GlobalContext* globalCtx); +void func_80A2244C(ObjSkateblock* this); +void func_80A224A4(ObjSkateblock* this, GlobalContext* globalCtx); +void func_80A22628(ObjSkateblock* this); +void func_80A2264C(ObjSkateblock* this, GlobalContext* globalCtx); +void func_80A22728(ObjSkateblock* this); +void func_80A2273C(ObjSkateblock* this, GlobalContext* globalCtx); +void func_80A227A4(ObjSkateblock* this); +void func_80A227C0(ObjSkateblock* this, GlobalContext* globalCtx); + const ActorInit Obj_Skateblock_InitVars = { ACTOR_OBJ_SKATEBLOCK, ACTORCAT_BG, @@ -22,76 +39,658 @@ const ActorInit Obj_Skateblock_InitVars = { (ActorFunc)ObjSkateblock_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A22AE0[] = { - ICHAIN_F32_DIV1000(gravity, -1700, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, 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), +s32 D_80A22A10 = 0; + +s32 D_80A22A14 = 0; + +AnimatedMaterial* D_80A22A18 = NULL; + +Vec2f D_80A22A1C[] = { + { -300.0f, 300.0f }, { 300.0f, 300.0f }, { -300.0f, -300.0f }, { 300.0f, -300.0f }, { 0.0f, 0.0f }, }; -#endif +Vec2f D_80A22A44[] = { + { 0.5f, -0.5f }, { -0.5f, -0.5f }, { 0.5f, 0.5f }, { -0.5f, 0.5f }, { 0.0f, 0.0f }, +}; -extern InitChainEntry D_80A22AE0[]; +Vec2f D_80A22A6C[] = { + { -300.0f, 0.0f }, { 300.0f, 0.0f }, { -300.0f, 600.0f }, { 300.0f, 600.0f }, { 0.0f, 300.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21150.s") +Vec2f D_80A22A94[] = { + { 1.0f, 1.0f }, { -1.0f, 1.0f }, { 1.0f, -1.0f }, { -1.0f, -1.0f }, { 0.0f, 0.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A211F4.s") +f32 D_80A22ABC[] = { -300.0f, 300.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A212F0.s") +f32 D_80A22AC4[] = { 1.0f, -1.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21370.s") +Vec3f D_80A22ACC = { 0.0f, 0.3f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21548.s") +Color_RGBA8 D_80A22AD8 = { 250, 250, 250, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A216D4.s") +Color_RGBA8 D_80A22ADC = { 180, 180, 180, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21934.s") +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(gravity, -1700, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(terminalVelocity, -20000, 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), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21990.s") +f32 D_80A22AF8[] = { 14.0f, -14.0f, 14.0f, -14.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21C30.s") +Color_RGB8 D_80A22B08[] = { + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, + { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, { 255, 255, 255 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21C88.s") +s32 func_80A21150(ObjSkateblock* this) { + s32 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21CB4.s") + if (fabsf(this->dyna.pushForce) > 0.1f) { + if (this->dyna.pushForce > 0.0f) { + temp_v0 = BINANG_ADD(this->dyna.yRotation, 0x2000); + } else { + temp_v0 = BINANG_SUB(this->dyna.yRotation, 0x6000); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21CD8.s") + if (temp_v0 < -0x4000) { + return 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21D1C.s") + if (temp_v0 < 0) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21E9C.s") + if (temp_v0 < 0x4000) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21F68.s") + return 0; + } + return -1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A21F74.s") +void func_80A211F4(ObjSkateblock* this, s32 arg1) { + s32 i; + s32 phi_v0 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/ObjSkateblock_Init.s") + if (this->dyna.pushForce > 0.0f) { + phi_v0 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/ObjSkateblock_Destroy.s") + for (i = 0; i < ARRAY_COUNT(this->unk_172); i++) { + if ((arg1 == i) && phi_v0) { + this->unk_172[i]++; + } else if (this->unk_172[i] > 0) { + this->unk_172[i]--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A22308.s") +void func_80A212F0(Vec3f* arg0, Vec3f* arg1, s16 arg2) { + f32 sp1C = Math_SinS(arg2); + f32 temp_f0 = Math_CosS(arg2); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A22334.s") + arg0->x = (arg1->z * sp1C) + (arg1->x * temp_f0); + arg0->y = arg1->y; + arg0->z = (arg1->z * temp_f0) - (arg1->x * sp1C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A2244C.s") +s32 func_80A21370(ObjSkateblock* this, GlobalContext* globalCtx) { + ObjSkateblockFloor* floor; + s32 i; + s32 pad; + s32 sp98; + Vec3f sp8C; + s32 sp88; + f32 phi_f20 = BGCHECK_Y_MIN; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A224A4.s") + sp88 = false; + sp8C.y = this->dyna.actor.world.pos.y + 40.0f; + sp98 = -1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A22628.s") + for (i = 0; i < ARRAY_COUNT(this->unk_184); i++) { + floor = &this->unk_184[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A2264C.s") + floor->poly = NULL; + floor->height = BGCHECK_Y_MIN; + floor->bgId = BG_ACTOR_MAX; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A22728.s") + sp8C.x = this->dyna.actor.world.pos.x + ((D_80A22A1C[i].x * this->dyna.actor.scale.x) + D_80A22A44[i].x); + sp8C.z = this->dyna.actor.world.pos.z + ((D_80A22A1C[i].z * this->dyna.actor.scale.z) + D_80A22A44[i].z); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A2273C.s") + floor->height = + BgCheck_EntityRaycastFloor6(&globalCtx->colCtx, &floor->poly, &floor->bgId, &this->dyna.actor, &sp8C, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A227A4.s") + if (floor->height > BGCHECK_Y_MIN + 1.0f) { + sp88 = true; + if (phi_f20 < floor->height) { + phi_f20 = floor->height; + sp98 = i; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/func_80A227C0.s") + if (sp98 >= 0) { + this->dyna.actor.floorPoly = this->unk_184[sp98].poly; + this->dyna.actor.floorHeight = this->unk_184[sp98].height; + this->dyna.actor.floorBgId = this->unk_184[sp98].bgId; + } + return sp88; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/ObjSkateblock_Update.s") +s32 func_80A21548(ObjSkateblock* this, GlobalContext* globalCtx) { + s32 i; + ObjSkateblockFloor* floor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Skateblock/ObjSkateblock_Draw.s") + this->unk_1C1 &= ~4; + + if (func_80A21370(this, globalCtx)) { + f32 maxHeight = BGCHECK_Y_MIN; + s32 phi_v1 = false; + f32 temp_f12 = this->dyna.actor.world.pos.y - 10.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_184); i++) { + floor = &this->unk_184[i]; + if ((temp_f12 < floor->height) && (floor->height > maxHeight)) { + maxHeight = floor->height; + phi_v1 = true; + } + } + + if (phi_v1) { + this->dyna.actor.world.pos.y = maxHeight; + this->unk_1C1 |= 4; + this->dyna.actor.velocity.y = 0.0f; + } + return phi_v1; + } + return false; +} + +s32 func_80A216D4(ObjSkateblock* this, GlobalContext* globalCtx, f32 arg2, Vec3f* arg3) { + s32 pad; + f32 spE8; + f32 spE4; + s32 i; + Vec3f spD4; + Vec3f spC8; + Vec3f spBC; + Vec3f spB0; + f32 temp_f20; + f32 temp_f24; + s32 spA4; + CollisionPoly* spA0; + s32 ret; + f32 temp_f26; + s16 sp96 = this->dyna.yRotation; + f32 temp_f2; + + if (this->dyna.pushForce < 0.0f) { + sp96 -= 0x8000; + } + spE8 = Math_SinS(sp96); + spE4 = Math_CosS(sp96); + + temp_f2 = Math3D_Distance(&this->dyna.actor.world.pos, &this->dyna.actor.prevPos) + + (300.0f * this->dyna.actor.scale.z) + arg2; + temp_f24 = temp_f2 * spE8; + temp_f26 = temp_f2 * spE4; + + ret = false; + temp_f20 = FLT_MAX; + + for (i = 0; i < ARRAY_COUNT(D_80A22A6C); i++) { + spBC.x = (D_80A22A6C[i].x * this->dyna.actor.scale.x) + D_80A22A94[i].x; + spBC.y = (D_80A22A6C[i].z * this->dyna.actor.scale.y) + D_80A22A94[i].z; + spBC.z = 0.0f; + + func_80A212F0(&spD4, &spBC, sp96); + + spD4.x += this->dyna.actor.prevPos.x; + spD4.y += this->dyna.actor.prevPos.y; + spD4.z += this->dyna.actor.prevPos.z; + + spC8.x = temp_f24 + spD4.x; + spC8.y = spD4.y; + spC8.z = temp_f26 + spD4.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spD4, &spC8, &spB0, &spA0, true, false, false, true, &spA4, + &this->dyna.actor, 0.0f)) { + temp_f2 = Math3D_Vec3fDistSq(&spD4, &spB0); + if (temp_f2 < temp_f20) { + temp_f20 = temp_f2; + ret = true; + Math_Vec3f_Diff(&spB0, &spC8, arg3); + } + } + } + return ret; +} + +s32 func_80A21934(ObjSkateblock* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + if (func_80A216D4(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_80A21990(ObjSkateblock* this, GlobalContext* globalCtx, Vec3f* arg2) { + s32 i; + f32 sp100; + s16 phi_s6 = this->dyna.yRotation; + f32 phi_f22; + Vec3f spEC; + Vec3f spE0; + Vec3f spD4; + Vec3f spC8; + f32 temp_f0; + f32 temp_f12; + s32 spBC; + CollisionPoly* spB8; + s32 ret; + f32 temp_f26; + f32 temp_f28; + f32 temp_f30; + + if (this->dyna.pushForce < 0.0f) { + phi_s6 -= 0x8000; + } + + sp100 = Math_SinS(phi_s6); + temp_f26 = Math_CosS(phi_s6); + + temp_f12 = + (300.0f * this->dyna.actor.scale.z + Math3D_Distance(&this->dyna.actor.world.pos, &this->dyna.actor.prevPos)) + + 2.0f; + temp_f28 = -temp_f12 * sp100; + temp_f30 = -temp_f12 * temp_f26; + + ret = false; + phi_f22 = FLT_MAX; + + for (i = 0; i < ARRAY_COUNT(D_80A22ABC); i++) { + spD4.x = (D_80A22ABC[i] * this->dyna.actor.scale.x) + D_80A22AC4[i]; + spD4.y = -10.0f; + spD4.z = 0.0f; + + func_80A212F0(&spEC, &spD4, phi_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, true, false, false, true, &spBC, + &this->dyna.actor, 0.0f)) { + temp_f0 = Math3D_Vec3fDistSq(&spEC, &spC8); + if (temp_f0 < phi_f22) { + ret = true; + arg2->x = (spC8.x - spEC.x) + (300.0f * this->dyna.actor.scale.z * sp100); + arg2->y = 0.0f; + arg2->z = (spC8.z - spEC.z) + (300.0f * this->dyna.actor.scale.z * temp_f26); + phi_f22 = temp_f0; + } + } + } + return ret; +} + +s32 func_80A21C30(ObjSkateblock* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + if (func_80A21990(this, globalCtx, &sp1C)) { + this->dyna.actor.world.pos.x += sp1C.x; + this->dyna.actor.world.pos.z += sp1C.z; + return true; + } + + return false; +} + +void func_80A21C88(ObjSkateblock* this, s32 arg1) { + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_16C = &this->dyna.actor.world.pos.x; + } else { + this->unk_16C = &this->dyna.actor.world.pos.z; + } + this->unk_170 = arg1; +} + +void func_80A21CB4(ObjSkateblock* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; +} + +void func_80A21CD8(ObjSkateblock* this) { + this->dyna.actor.velocity.y += this->dyna.actor.gravity; + if (this->dyna.actor.velocity.y < this->dyna.actor.terminalVelocity) { + this->dyna.actor.velocity.y = this->dyna.actor.terminalVelocity; + } + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; +} + +void func_80A21D1C(ObjSkateblock* this) { + f32 sp4; + f32 temp_f14; + f32 temp_f16; + f32 temp_f6; + f32 phi_f2; + + temp_f14 = this->dyna.actor.world.pos.x - this->dyna.actor.home.pos.x; + phi_f2 = ((temp_f14 >= 0.0f) ? 0.5f : -0.5f); + sp4 = ((s32)(phi_f2 + temp_f14) / 30) * 30; + temp_f14 -= sp4; + + if (fabsf(temp_f14) < 3.0f) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + sp4; + } + + temp_f16 = this->dyna.actor.world.pos.z - this->dyna.actor.home.pos.z; + phi_f2 = ((temp_f16 >= 0.0f) ? 0.5f : -0.5f); + temp_f6 = ((s32)(phi_f2 + temp_f16) / 30) * 30; + temp_f16 -= temp_f6; + + if (fabsf(temp_f16) < 3.0f) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + temp_f6; + } +} + +void func_80A21E9C(ObjSkateblock* this, GlobalContext* globalCtx) { + DynaPolyActor* temp_v0; + s32 i; + ObjSkateblockFloor* ptr; + + if (!(this->unk_1C1 & 4)) { + return; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_184); i++) { + ptr = &this->unk_184[i]; + + temp_v0 = DynaPoly_GetActor(&globalCtx->colCtx, ptr->bgId); + if ((temp_v0 != NULL) && (temp_v0->actor.id == ACTOR_OBJ_SKATEBLOCK)) { + ObjSkateblock* skateBlock = (ObjSkateblock*)temp_v0; + f32 height = this->dyna.actor.world.pos.y - ptr->height; + + if (fabsf(height) < 0.1f) { + skateBlock->unk_1C1 |= 2; + } + } + } +} + +void func_80A21F68(ObjSkateblock* this) { + this->unk_17C = 0; +} + +void func_80A21F74(ObjSkateblock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f spA8; + Vec3f sp9C; + f32 phi_f22; + s32 i; + f32 temp; + s32 pad2; + s16 sp8A = this->dyna.yRotation; + + if (this->dyna.pushForce < 0.0f) { + sp8A -= 0x8000; + } + + this->unk_17C++; + + if (this->dyna.actor.flags & ACTOR_FLAG_40) { + if (this->unk_17C >= 46) { + phi_f22 = 1.0f; + } else { + phi_f22 = (this->unk_17C * 0.017777778f) + 0.2f; + } + sp9C.y = 12.0f; + + for (i = 0; i < 2; i++) { + if (phi_f22 < (Rand_ZeroOne() * 1.2f)) { + continue; + } + this->unk_180 += Rand_ZeroOne(); + + if (this->unk_180 > 1.0f) { + this->unk_180 -= 1.0f; + } + + sp9C.x = (this->unk_180 - 0.5f) * 600.0f * this->dyna.actor.scale.x; + sp9C.z = (this->dyna.actor.scale.z * -300.0f) + 4.0f; + + func_80A212F0(&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 = ((Rand_ZeroOne() * 800.0f) + (1600.0f * this->dyna.actor.scale.x)) * phi_f22; + func_800B0E48(globalCtx, &spA8, &gZeroVec3f, &D_80A22ACC, &D_80A22AD8, &D_80A22ADC, temp, + (Rand_ZeroOne() * 20.0f) + 30.0f); + } + } +} + +void ObjSkateblock_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjSkateblock* this = THIS; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gameplay_dangeon_keep_Colheader_007498); + if (D_80A22A18 == NULL) { + D_80A22A18 = Lib_SegmentedToVirtual(gameplay_dangeon_keep_Matanimheader_01B370); + } + func_80A22308(this); + this->unk_1C0 = D_80A22A14; + D_80A22A14++; + D_80A22A14 &= 0x1F; +} + +void ObjSkateblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSkateblock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void func_80A22308(ObjSkateblock* this) { + this->actionFunc = func_80A22334; + this->unk_172[1] = 0; + this->unk_172[2] = 0; + this->unk_172[3] = 0; + this->unk_172[0] = 0; + this->dyna.actor.velocity.y = 0.0f; +} + +void func_80A22334(ObjSkateblock* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30; + s32 sp2C; + Vec3f sp20; + + func_80A21CD8(this); + func_80A21548(this, globalCtx); + sp2C = func_80A21150(this); + func_80A211F4(this, sp2C); + + sp30 = true; + + if (sp2C == -1) { + sp30 = false; + } else if (!(this->unk_1C1 & 2) && (this->unk_172[sp2C] > 10) && (D_80A22A10 == 0) && + !func_80A216D4(this, globalCtx, 2.0f, &sp20) && !Player_InCsMode(&globalCtx->state)) { + func_80A21C88(this, sp2C); + func_80A2244C(this); + sp30 = false; + func_800B7298(globalCtx, &this->dyna.actor, 7); + this->unk_1C1 |= 1; + } + + if (sp30) { + func_80A21CB4(this, globalCtx); + } +} + +void func_80A2244C(ObjSkateblock* this) { + this->actionFunc = func_80A224A4; + this->unk_168 = D_80A22AF8[this->unk_170]; + this->unk_164 = 0.0f; + this->unk_17A = 15; + this->dyna.actor.velocity.y = this->dyna.actor.gravity; + func_80A21F68(this); +} + +void func_80A224A4(ObjSkateblock* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp28 = false; + s32 sp24 = false; + + Math_StepToF(&this->unk_164, this->unk_168, 0.75f); + + *this->unk_16C += this->unk_164; + + if (func_80A21934(this, globalCtx)) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + func_80A21D1C(this); + sp28 = true; + } else { + func_800B9010(&this->dyna.actor, NA_SE_PL_SLIP_ICE_LEVEL - SFX_FLAG); + } + + func_80A21CD8(this); + + if (!func_80A21548(this, globalCtx)) { + func_80A21C30(this, globalCtx); + func_80A21D1C(this); + func_80A22628(this); + sp24 = true; + } else if (sp28) { + func_80A22308(this); + } + + if (this->unk_17A > 0) { + this->unk_17A--; + } + + if (sp24 || sp28 || (this->unk_17A == 1)) { + func_80A21CB4(this, globalCtx); + } + + if ((this->unk_1C1 & 1) && (sp24 || sp28 || (this->dyna.actor.xzDistToPlayer > 400.0f))) { + this->unk_1C1 &= ~1; + func_800B7298(globalCtx, &this->dyna.actor, 6); + } + + func_80A21F74(this, globalCtx); +} + +void func_80A22628(ObjSkateblock* this) { + this->actionFunc = func_80A2264C; + this->unk_160 = this->dyna.actor.world.pos.y; + this->dyna.actor.velocity.y = this->dyna.actor.gravity; +} + +void func_80A2264C(ObjSkateblock* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp20; + + if (func_80A21150(this) != -1) { + func_80A21CB4(this, globalCtx); + } + func_80A21CD8(this); + + sp20 = func_80A21548(this, globalCtx); + if (sp20 || ((this->unk_160 - this->dyna.actor.world.pos.y) > 300.0f)) { + if (func_800C9B40(&globalCtx->colCtx, this->dyna.actor.floorPoly, this->dyna.actor.floorBgId) == 12) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.draw = NULL; + func_80A22728(this); + return; + } + } + + if (sp20) { + func_80A22308(this); + } +} + +void func_80A22728(ObjSkateblock* this) { + this->actionFunc = func_80A2273C; +} + +void func_80A2273C(ObjSkateblock* this, GlobalContext* globalCtx) { + if (!DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x; + this->dyna.actor.world.pos.y = (this->dyna.actor.home.pos.y - (600.0f * this->dyna.actor.scale.y)) - 10.0f; + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z; + + func_80A227A4(this); + } +} + +void func_80A227A4(ObjSkateblock* this) { + this->actionFunc = func_80A227C0; + this->unk_17A = 40; +} + +void func_80A227C0(ObjSkateblock* this, GlobalContext* globalCtx) { + if (func_80A21150(this) != -1) { + func_80A21CB4(this, globalCtx); + } + + if (this->unk_17A > 0) { + this->unk_17A--; + return; + } + + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->dyna.actor.draw = ObjSkateblock_Draw; + + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.home.pos.y, 1.0f)) { + func_80A22308(this); + } + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + D_80A22A10 |= 1 << this->unk_1C0; + } +} + +void ObjSkateblock_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjSkateblock* this = THIS; + + D_80A22A10 &= ~(1 << this->unk_1C0); + this->actionFunc(this, globalCtx); + this->unk_1C1 &= ~2; +} + +void ObjSkateblock_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSkateblock* this = THIS; + Color_RGB8* sp2C = &D_80A22B08[OBJSKAEBLOCK_GET_F(&this->dyna.actor)]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + AnimatedMat_DrawStep(globalCtx, D_80A22A18, 0); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0xFF, 0xFF, sp2C->r, sp2C->g, sp2C->b, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_dangeon_keep_DL_0182A8); + + func_80A21E9C(this, globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.h b/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.h index 00f3a0f1b..c26a93844 100644 --- a/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.h +++ b/src/overlays/actors/ovl_Obj_Skateblock/z_obj_skateblock.h @@ -7,11 +7,29 @@ struct ObjSkateblock; typedef void (*ObjSkateblockActionFunc)(struct ObjSkateblock*, GlobalContext*); +#define OBJSKAEBLOCK_GET_F(thisx) ((thisx)->params & 0xF) + +typedef struct { + /* 0x00 */ CollisionPoly* poly; + /* 0x04 */ f32 height; + /* 0x08 */ s32 bgId; +} ObjSkateblockFloor; // size = 0xC + typedef struct ObjSkateblock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjSkateblockActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x64]; + /* 0x0160 */ f32 unk_160; + /* 0x0164 */ f32 unk_164; + /* 0x0168 */ f32 unk_168; + /* 0x016C */ f32* unk_16C; + /* 0x0170 */ s16 unk_170; + /* 0x0172 */ s16 unk_172[4]; + /* 0x017A */ s16 unk_17A; + /* 0x017C */ s16 unk_17C; + /* 0x0180 */ f32 unk_180; + /* 0x0184 */ ObjSkateblockFloor unk_184[5]; + /* 0x01C0 */ u8 unk_1C0; + /* 0x01C1 */ u8 unk_1C1; } ObjSkateblock; // size = 0x1C4 extern const ActorInit Obj_Skateblock_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.c b/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.c index dae5c4711..83e286e97 100644 --- a/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.c +++ b/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.c @@ -1,6 +1,13 @@ -#include "z_obj_smork.h" +/* + * File: z_obj_smork.c + * Overlay: ovl_Obj_Smork + * Description: Romani Ranch Chimney Smoke + */ -#define FLAGS 0x00000030 +#include "z_obj_smork.h" +#include "objects/object_f53_obj/object_f53_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjSmork*)thisx) @@ -9,7 +16,6 @@ void ObjSmork_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSmork_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSmork_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Smork_InitVars = { ACTOR_OBJ_SMORK, ACTORCAT_PROP, @@ -22,20 +28,124 @@ const ActorInit Obj_Smork_InitVars = { (ActorFunc)ObjSmork_Draw, }; -#endif +#include "overlays/ovl_Obj_Smork/ovl_Obj_Smork.c" -extern UNK_TYPE D_06001C00; +u8 func_80A3D680(s16 arg0) { + u8 ret = 0; + s16 temp_f18 = TIME_TO_MINUTES_F(gSaveContext.save.time); + s32 hours = temp_f18 / 60; + s32 minutes = temp_f18 % 60; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/func_80A3D680.s") + if (hours >= 16) { + if ((hours == 16) && (minutes < arg0)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/func_80A3D940.s") + if (hours >= 20) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/func_80A3D9C4.s") + if ((hours == 19) && (arg0 < minutes)) { + return 0; + } + ret = 3; + } else if (hours >= 11) { + if ((hours == 11) && (minutes < arg0)) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/ObjSmork_Init.s") + if (hours >= 14) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/ObjSmork_Destroy.s") + if ((hours == 13) && (arg0 < minutes)) { + return 0; + } + ret = 2; + } else if (hours >= 6) { + if ((hours == 6) && (minutes < arg0)) { + return 0; + } + if (hours >= 9) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/ObjSmork_Update.s") + if ((hours == 8) && (arg0 < minutes)) { + return 0; + } + ret = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Smork/ObjSmork_Draw.s") + return ret; +} + +void func_80A3D940(ObjSmork* this) { + u8 temp_v0 = func_80A3D680(this->unk_1C6); + + if (temp_v0 != this->unk_1C4) { + this->unk_1C4 = temp_v0; + this->unk_1C6 = Rand_S16Offset(0, 59); + } + + Math_ApproachF(&this->unk_1B8, (this->unk_1C4 == 0) ? 0.0f : 1.0f, 0.02f, 1000.0f); +} + +void func_80A3D9C4(ObjSmork* this, GlobalContext* globalCtx) { + u8 sp57; + u8 sp56; + s32 i; + + this->unk_1BC += 1.8f; + this->unk_1C0 += 0.6f; + + sp57 = 127 - (u8)this->unk_1BC; + sp56 = 127 - (u8)this->unk_1C0; + + this->unk_1B8 = CLAMP(this->unk_1B8, 0.0f, 1.0f); + + for (i = 0; i < ARRAY_COUNT(this->unk_148); i++) { + this->unk_148[i].v.cn[3] = ovl_Obj_Smork_Vtx_000C10[i].v.cn[3] * this->unk_1B8; + } + + if (this->unk_1B8 > 0.0f) { + Matrix_Translate(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + this->actor.shape.rot.y = BINANG_ROT180(Camera_GetCamDirYaw(GET_ACTIVE_CAM(globalCtx))); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.0f, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, sp57, 0x20, 0x20, 1, 0, sp56, 0x20, 0x20)); + gSPSegment(POLY_XLU_DISP++, 0x09, Lib_SegmentedToVirtual(this->unk_148)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_f53_obj_DL_001C00); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void ObjSmork_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjSmork* this = THIS; + + Lib_MemCpy(this->unk_148, ovl_Obj_Smork_Vtx_000C10, sizeof(Vtx) * ARRAY_COUNT(ovl_Obj_Smork_Vtx_000C10)); + this->unk_1C6 = Rand_S16Offset(0, 59); + this->unk_1C4 = 0; +} + +void ObjSmork_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void ObjSmork_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjSmork* this = THIS; + + func_80A3D940(this); +} + +void ObjSmork_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSmork* this = THIS; + + func_80A3D9C4(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.h b/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.h index dd6ab4cf7..5ab3e405c 100644 --- a/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.h +++ b/src/overlays/actors/ovl_Obj_Smork/z_obj_smork.h @@ -7,7 +7,13 @@ struct ObjSmork; typedef struct ObjSmork { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x84]; + /* 0x144 */ UNK_TYPE1 unk_144[4]; + /* 0x148 */ Vtx unk_148[7]; + /* 0x1B8 */ f32 unk_1B8; + /* 0x1BC */ f32 unk_1BC; + /* 0x1C0 */ f32 unk_1C0; + /* 0x1C4 */ u8 unk_1C4; + /* 0x1C6 */ s16 unk_1C6; } ObjSmork; // size = 0x1C8 extern const ActorInit Obj_Smork_InitVars; 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 a927cadfc..3979479f6 100644 --- a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c +++ b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c @@ -1,4 +1,12 @@ +/* + * File: z_obj_snowball.c + * Overlay: ovl_Obj_Snowball + * Description: Large Snowball + */ + #include "z_obj_snowball.h" +#include "objects/object_goroiwa/object_goroiwa.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -9,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, @@ -22,80 +45,796 @@ 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), }; -#endif +void func_80B02CD0(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; -extern ColliderJntSphElementInit D_80B04F50[1]; -extern ColliderJntSphInit D_80B04F74; -extern InitChainEntry D_80B04FD4[]; + 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); +} -extern UNK_TYPE D_060082D0; -extern UNK_TYPE D_06008B90; +void func_80B02D58(ObjSnowball* this, GlobalContext* globalCtx) { + s32 temp_v0 = func_800A8150(OBJSNOWBALL_GET_3F(&this->actor)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02CD0.s") + if (temp_v0 >= 0) { + Item_DropCollectible(globalCtx, &this->actor.home.pos, (OBJSNOWBALL_GET_7F00(&this->actor) << 8) | temp_v0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02D58.s") +void func_80B02DB0(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02DB0.s") + 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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02E54.s") +void func_80B02E54(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02EE4.s") + 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); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B030F8.s") +void func_80B02EE4(ObjSnowball* this, GlobalContext* globalCtx) { + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + Vec3s* hitPos = &this->collider.elements->info.bumper.hitPos; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03688.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03A80.s") + spA0.x = (Rand_ZeroOne() - 0.5f) * 1.6f; + spA0.y = -0.8f; + spA0.z = (Rand_ZeroOne() - 0.5f) * 1.6f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03E2C.s") + spAC.x = spA0.x * -0.06f; + spAC.y = spA0.y * -0.06f; + spAC.z = spA0.z * -0.06f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03FF8.s") + func_800B0E48(globalCtx, &sp94, &spA0, &spAC, &D_80B04FB4, &D_80B04FB8, (s32)(Rand_ZeroOne() * 30.0f) + 15, + (s32)(Rand_ZeroOne() * 40.0f) + 30); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Init.s") +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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Destroy.s") + 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; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04338.s") + temp_f20 = (Rand_ZeroOne() * (40.0f * this->unk_20C)) + 20.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04350.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04540.s") + spF0.x = spFC.x * 0.16f * phi_f22; + spF0.y = (Rand_ZeroOne() * 16.0f) + 3.0f; + spF0.z = spFC.z * 0.16f * phi_f22; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B0457C.s") + spFC.x += this->actor.world.pos.x; + spFC.y += this->actor.world.pos.y; + spFC.z += this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04608.s") + scale = ((Rand_ZeroOne() * 15.0f) + 30.0f) * this->unk_20C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04648.s") + EffectSsKakera_Spawn(globalCtx, &spFC, &spF0, &spFC, gravity, phi_s0, 30, 0, 0, scale, phi_s4, 0, 50, -1, + OBJECT_GOROIWA, 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B046E4.s") + 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); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B047C0.s") + if (this->unk_210 != 0) { + temp_f26 = this->unk_20C * 60.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B48.s") + 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); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B60.s") + spFC.x = Math_SinS(phi_s6); + spFC.z = Math_CosS(phi_s6); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Update.s") + spF0.x = 2.0f * spFC.x; + spF0.y = (2.0f * Rand_ZeroOne()) + 1.0f; + spF0.z = 2.0f * spFC.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Draw.s") + spFC.x *= temp_f22 * temp_f26; + spFC.y = temp_f20 * temp_f26; + spFC.z *= temp_f22 * temp_f26; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04D34.s") + 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); + } + } +} + +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; + s16 phi_s2; + s16 phi_s0; + s16 phi_s3; + s32 phi_s5; + s32 tmp; + s32 pad; + + for (i = 0, phi_s5 = 0; i < 13; i++, phi_s5 += 0x1999) { + tmp = i & 3; + + 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 (tmp == 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 (tmp == 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, OBJECT_GOROIWA, 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); + } +} + +void func_80B03E2C(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct* ptr; + s32 i; + + 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; + + 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; + + 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); + + ptr->unk_1C.x = 0; + ptr->unk_1C.z = 0; + + ptr->unk_22 = (s32)(Rand_ZeroOne() * 400.0f) + 1100; + ptr->unk_26 = Rand_ZeroOne() * -600.0f; + ptr->unk_2D = 0; + ptr->unk_2C = 0; + } +} + +void func_80B03FF8(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + s16 rotY = this->actor.home.rot.y; + ObjSnowballStruct2* sp18 = &D_80B04F84[rotY]; + + if (sp18->unk_04 != NULL) { + sp18->unk_04(this, globalCtx); + } + + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_SNOWBALL_BROKEN); + + if (rotY == 5) { + Flags_SetSwitch(globalCtx, OBJSNOWBALL_GET_3F(&this->actor)); + } +} + +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; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + sp34 = sp40 == 1; + if (sp34) { + phi_f20 = 1.5f; + } else { + phi_f20 = 1.0f; + } + + Actor_SetScale(&this->actor, 0.1f * phi_f20); + + 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; + + if (sp34) { + this->actor.textId = 0x238; + this->actor.flags |= ACTOR_FLAG_1; + this->actor.targetArrowOffset = 1400.0f / 3.0f; + Actor_SetFocus(&this->actor, 24.0f); + this->actor.targetMode = 3; + } + + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->actor.colChkInfo.mass = MASS_HEAVY; + + 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; + + sp48.x = this->actor.home.pos.x; + sp48.y = this->actor.home.pos.y + 30.0f; + sp48.z = this->actor.home.pos.z; + + 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); + } + + func_80B04338(this, globalCtx); + + if ((sp40 == 5) && Flags_GetSwitch(globalCtx, OBJSNOWBALL_GET_3F(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } +} + +void ObjSnowball_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void func_80B04338(ObjSnowball* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B04350; +} + +void func_80B04350(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + s32 flag = (this->collider.base.acFlags & AC_HIT) != 0; + + 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 |= ACTOR_FLAG_10; + if (this->actor.home.rot.y == 1) { + this->actor.flags &= ~(ACTOR_FLAG_1 | ACTOR_FLAG_8); + } + + 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; + } + Actor_PlaySfxAtPos(&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_RotateZYX(ptr->unk_1C.x, ptr->unk_1C.y, ptr->unk_1C.z, MTXMODE_NEW); + Matrix_MultVec3f(&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 (Actor_TextboxIsClosing(&this->actor, globalCtx)) { + this->actor.flags &= ~ACTOR_FLAG_10; + this->unk_211 = 0; + } + } else if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state)) { + this->actor.flags |= ACTOR_FLAG_10; + 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 = ActorShadow_DrawCircle; + } else if (this->actor.projectedPos.z > -30.0f) { + this->actor.shape.shadowAlpha = 130; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + } else { + this->actor.shape.shadowDraw = NULL; + } + } else { + this->actor.shape.shadowDraw = NULL; + } +} + +void ObjSnowball_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball* this = THIS; + + Gfx_DrawDListOpa(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_SetTranslateRotateYXZ(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); + Gfx_DrawDListOpa(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_Put(&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++, gCircleShadowDL); + + 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_Snowball2/z_obj_snowball2.c b/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.c index fa6b60135..5356e2e88 100644 --- a/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.c +++ b/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.c @@ -1,6 +1,13 @@ -#include "z_obj_snowball2.h" +/* + * File: z_obj_snowball2.c + * Overlay: ovl_Obj_Snowball2 + * Description: Small Snowball + */ -#define FLAGS 0x00800000 +#include "z_obj_snowball2.h" +#include "objects/object_goroiwa/object_goroiwa.h" + +#define FLAGS (ACTOR_FLAG_800000) #define THIS ((ObjSnowball2*)thisx) @@ -9,7 +16,16 @@ void ObjSnowball2_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSnowball2_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSnowball2_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B38E20(ObjSnowball2* this); +void func_80B39C78(ObjSnowball2* this); +void func_80B39C9C(ObjSnowball2* this, GlobalContext* globalCtx); +void func_80B39F60(ObjSnowball2* this); +void func_80B39FA8(ObjSnowball2* this, GlobalContext* globalCtx); +void func_80B3A0D8(ObjSnowball2* this); +void func_80B3A13C(ObjSnowball2* this, GlobalContext* globalCtx); +void func_80B3A498(ObjSnowball2* this); +void func_80B3A500(ObjSnowball2* this, GlobalContext* globalCtx); + const ActorInit Obj_Snowball2_InitVars = { ACTOR_OBJ_SNOWBALL2, ACTORCAT_PROP, @@ -22,82 +38,587 @@ const ActorInit Obj_Snowball2_InitVars = { (ActorFunc)ObjSnowball2_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80B3A8E0[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x0583FFBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x0583FFBE, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 15 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B3A904 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 1, D_80B3A8E0, // 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, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B3A93C[] = { - ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 25, ICHAIN_STOP), +Color_RGBA8 D_80B3A914 = { 250, 250, 250, 255 }; + +Color_RGBA8 D_80B3A918 = { 180, 180, 180, 255 }; + +Gfx* D_80B3A91C[] = { + object_goroiwa_DL_0072F0, + object_goroiwa_DL_0077D0, + object_goroiwa_DL_007C60, + object_goroiwa_DL_007C60, }; -#endif +Vec3f D_80B3A92C = { 0.0f, 0.3f, 0.0f }; -extern ColliderJntSphElementInit D_80B3A8E0[1]; -extern ColliderJntSphInit D_80B3A904; -extern InitChainEntry D_80B3A93C[]; +void func_80B38E20(ObjSnowball2* this) { + Matrix_SetTranslateRotateYXZ(this->actor.world.pos.x, + this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y), + this->actor.world.pos.z, &this->actor.shape.rot); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Collider_UpdateSpheres(0, &this->collider); +} -extern UNK_TYPE D_06008B90; +void func_80B38E88(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 temp_v0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B38E20.s") + if (this->unk_1AE == 0) { + temp_v0 = func_800A8150(ENOBJSNOWBALL2_GET_3F(&this->actor)); + if (temp_v0 >= 0) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, + (ENOBJSNOWBALL2_GET_7F00(&this->actor) << 8) | temp_v0); + this->unk_1AE = 1; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B38E88.s") +void func_80B38EFC(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + Vec3f spA4; + Vec3f sp98; + Vec3f sp8C; + f32 sp88 = this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B38EFC.s") + for (i = 0; i < 2; i++) { + sp8C.x = ((Rand_ZeroOne() * 30.0f) - 15.0f) + this->actor.world.pos.x; + sp8C.y = ((Rand_ZeroOne() * 20.0f) - 10.0f) + sp88; + sp8C.z = ((Rand_ZeroOne() * 30.0f) - 15.0f) + this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39108.s") + sp98.x = (Rand_ZeroOne() - 0.5f) * 1.6f; + sp98.y = -1.5f; + sp98.z = (Rand_ZeroOne() - 0.5f) * 1.6f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39470.s") + spA4.x = sp98.x * -0.06f; + spA4.y = sp98.y * -0.06f; + spA4.z = sp98.z * -0.06f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B395C4.s") + func_800B0E48(globalCtx, &sp8C, &sp98, &spA4, &D_80B3A914, &D_80B3A918, (s32)(Rand_ZeroOne() * 40.0f) + 10, + (s32)(Rand_ZeroOne() * 30.0f) + 10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B395EC.s") +void func_80B39108(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 phi_s5; + s16 phi_s1; + s32 phi_v0; + s32 i; + u32 temp; + s32 temp_s3; + Vec3f spDC; + Vec3f spD0; + f32 temp_f2; + f32 spC8 = this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y); + f32 temp_f0; + f32 temp_f12; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39638.s") + for (i = 0, phi_s5 = 0; i < 11; i++, phi_s5 += (0x10000 / 11)) { + temp_s3 = (s32)(Rand_ZeroOne() * 5957.0f) + phi_s5; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39834.s") + if (((u32)Rand_Next() >> 0x1E) == 0) { + phi_s1 = 0x20; + } else { + phi_s1 = 0x40; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39908.s") + if ((i & 3) == 0) { + phi_s1 |= 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39B28.s") + temp_f0 = Rand_ZeroOne(); + temp_f20 = (1.0f - SQ(temp_f0)) * 12.0f; + temp_f22 = Math_SinS(temp_s3); + temp_f24 = Math_CosS(temp_s3); + temp_f12 = (Rand_ZeroOne() * 1.6f) - 0.8f; + temp_f2 = fabsf(temp_f12) * temp_f12; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39B5C.s") + spDC.x = temp_f22 * 4.0f; + spDC.y = (temp_f2 * 6.0f) + 9.0f; + spDC.z = temp_f24 * 4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/ObjSnowball2_Init.s") + spD0.x = (temp_f22 * temp_f20) + this->actor.world.pos.x; + spD0.y = (temp_f2 * temp_f20) + spC8; + spD0.z = (temp_f24 * temp_f20) + this->actor.world.pos.z; + temp = Rand_Next(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/ObjSnowball2_Destroy.s") + if ((i & 3) == 0) { + phi_v0 = 1; + } else { + phi_v0 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39C78.s") + EffectSsKakera_Spawn(globalCtx, &spD0, &spDC, &spD0, -300, phi_s1, 30, 0, 0, (temp >> 0x1D) + 8, phi_v0, 0, 50, + -1, OBJECT_GOROIWA, D_80B3A91C[i & 3]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39C9C.s") + spD0.x += (Rand_ZeroOne() - 0.5f) * 40.0f; + spD0.y += (Rand_ZeroOne() - 0.3f) * 45.0f; + spD0.z += (Rand_ZeroOne() - 0.5f) * 40.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39F60.s") + func_800B0E48(globalCtx, &spD0, &gZeroVec3f, &D_80B3A92C, &D_80B3A914, &D_80B3A918, + (s32)(Rand_ZeroOne() * 70.0f) + 10, (s32)(Rand_ZeroOne() * 100.0f) + 10); + } + spD0.y = (temp_f2 * temp_f20) + spC8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B39FA8.s") +void func_80B39470(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + Vec3f sp58; + s32 phi_s0; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B3A0D8.s") + sp58.y = this->actor.world.pos.y + this->actor.depthInWater; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B3A13C.s") + for (phi_s0 = 0, i = 0; i < 5; i++, phi_s0 += (0x10000 / 5)) { + sp58.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.x; + sp58.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 200); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B3A498.s") + sp58.x = this->actor.world.pos.x; + sp58.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 300); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/func_80B3A500.s") +void func_80B395C4(GlobalContext* this, Vec3f* arg1) { + EffectSsGRipple_Spawn(this, arg1, 200, 700, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/ObjSnowball2_Update.s") +void func_80B395EC(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + Vec3f sp18; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball2/ObjSnowball2_Draw.s") + sp18.x = this->actor.world.pos.x; + sp18.y = this->actor.world.pos.y + this->actor.depthInWater; + sp18.z = this->actor.world.pos.z; + func_80B395C4(globalCtx, &sp18); +} + +void func_80B39638(GlobalContext* globalCtx, Vec3f* arg1) { + static s16 D_80B3A938 = 0; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + Vec3f sp98; + Vec3f sp8C; + Vec3f sp80; + f32 temp_f2; + s32 i; + + D_80B3A938 += (s16)((u32)Rand_Next() >> 0x11); + + for (i = 0; i < 2; i++) { + D_80B3A938 += 0x8000; + temp_f20 = Rand_ZeroOne(); + temp_f22 = Math_SinS(D_80B3A938) * temp_f20; + temp_f24 = Rand_ZeroOne(); + temp_f2 = Math_CosS(D_80B3A938) * temp_f20; + + sp98.x = arg1->x + (temp_f22 * 5.0f); + sp98.y = arg1->y + (temp_f24 * 25.0f); + sp98.z = arg1->z + (temp_f2 * 5.0f); + + sp8C.x = temp_f22 * 1.55f; + sp8C.y = temp_f24 * -0.7f; + sp8C.z = temp_f2 * 1.55f; + + sp80.x = sp8C.x * -0.02f; + sp80.y = sp8C.y * -0.025f; + sp80.z = sp8C.z * -0.02f; + + EffectSsIceSmoke_Spawn(globalCtx, &sp98, &sp8C, &sp80, (s32)(Rand_ZeroOne() * 30.0f) + 68); + } +} + +void func_80B39834(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + s32 i; + + for (i = 0; i < 3; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, 20.0f, 30.0f, (Rand_ZeroOne() * 0.11f) + 0.03f); + } +} + +void func_80B39908(ObjSnowball2* this, GlobalContext* globalCtx) { + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + s32 i; + + if (this->collider.elements[0].info.bumperFlags & BUMP_HIT) { + Vec3s* hitPos = &this->collider.elements[0].info.bumper.hitPos; + + 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_80B3A914, &D_80B3A918, (s32)(Rand_ZeroOne() * 40.0f) + 10, + (s32)(Rand_ZeroOne() * 30.0f) + 10); + } + } +} + +void func_80B39B28(ObjSnowball2* this, GlobalContext* globalCtx) { + if ((this->unk_1AE == 0) && (globalCtx->roomCtx.currRoom.num != this->unk_1AF)) { + this->unk_1AE = 1; + } +} + +void func_80B39B5C(ObjSnowball2* this, GlobalContext* globalCtx) { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_SMALL_SNOWBALL_BROKEN); +} + +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(terminalVelocity, -20000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 25, ICHAIN_STOP), +}; + +void ObjSnowball2_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitJntSph(globalCtx, &this->collider); + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->actor.shape.rot.y = (u32)Rand_Next() >> 0x10; + ActorShape_Init(&this->actor.shape, 200.0f, NULL, 12.5f); + this->actor.shape.shadowAlpha = 130; + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + func_80B38E20(this); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_1AF = this->actor.room; + func_80B39C78(this); +} + +void ObjSnowball2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void func_80B39C78(ObjSnowball2* this) { + this->actor.flags |= ACTOR_FLAG_10; + this->unk_1AD = 0; + this->actionFunc = func_80B39C9C; +} + +void func_80B39C9C(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp38 = (this->collider.base.acFlags & AC_HIT) != 0; + s32 pad2; + + if (sp38) { + this->collider.base.acFlags &= ~AC_HIT; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.room = -1; + this->actor.flags |= ACTOR_FLAG_10; + if (func_800A817C(ENOBJSNOWBALL2_GET_3F(&this->actor))) { + func_80B38E88(this, globalCtx); + } + func_80B38EFC(this, globalCtx); + func_800B8E58(GET_PLAYER(globalCtx), NA_SE_PL_PULL_UP_SNOWBALL); + func_80B39F60(this); + } else if ((this->actor.bgCheckFlags & 0x20) && + ((this->actor.shape.yOffset * this->actor.scale.y) < this->actor.depthInWater)) { + func_80B3A498(this); + } else if (sp38 && (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x0583FFBC)) { + func_80B38E88(this, globalCtx); + func_80B39108(this, globalCtx); + func_80B39B5C(this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } else { + if (sp38 && (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 2)) { + func_80B39908(this, globalCtx); + } + + if (this->unk_1AD == 0) { + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0x44); + if ((this->actor.bgCheckFlags & 1) && + (DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId) == NULL)) { + this->unk_1AD = 1; + this->actor.flags &= ~ACTOR_FLAG_10; + } + } + + if (this->actor.xzDistToPlayer < 800.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->actor.xzDistToPlayer < 150.0f) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->actor.xzDistToPlayer < 100.0f) { + if (ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, GET_PLAYER(globalCtx)->actor.world.rot.y)) >= + 0x5556) { + Actor_PickUp(&this->actor, globalCtx, GI_NONE, 36.0f, 30.0f); + } + } + } + } + } +} + +void func_80B39F60(ObjSnowball2* this) { + this->actor.world.pos.y += (600.0f - this->actor.shape.yOffset) * this->actor.scale.y; + this->unk_1AC = 4; + this->actor.shape.yOffset = 600.0f; + this->actionFunc = func_80B39FA8; +} + +void func_80B39FA8(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; + + func_80B39B28(this, globalCtx); + + if (this->unk_1AC > 0) { + this->unk_1AC--; + func_80B38EFC(this, globalCtx); + } + + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actor.room = globalCtx->roomCtx.currRoom.num; + this->actor.speedXZ *= 3.8f; + this->actor.velocity.y *= 0.4f; + this->actor.gravity = -2.8f; + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0x45); + func_80B3A0D8(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; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30); + } +} + +void func_80B3A0D8(ObjSnowball2* this) { + this->unk_1AC = 60; + this->actor.colChkInfo.mass = 180; + this->unk_1A8 = Rand_S16Offset(-5000, 4000); + this->unk_1AA = Rand_S16Offset(-800, 1600); + this->actionFunc = func_80B3A13C; +} + +void func_80B3A13C(ObjSnowball2* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp38 = (this->collider.base.atFlags & AT_HIT) != 0; + s32 sp34 = (this->collider.base.ocFlags1 & OC1_HIT) != 0; + s32 sp30; + + if (sp38) { + this->collider.base.atFlags &= ~AT_HIT; + } + + if (sp34) { + this->collider.base.ocFlags1 &= ~OC1_HIT; + } + + if (this->unk_1AC > 0) { + this->unk_1AC--; + } + + func_80B39B28(this, globalCtx); + + if ((((this->actor.bgCheckFlags & 9) || sp38) && !(this->actor.bgCheckFlags & 0x20)) || (this->unk_1AC <= 0)) { + func_80B38E88(this, globalCtx); + func_80B39108(this, globalCtx); + func_80B39B5C(this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } + + sp30 = false; + if (this->actor.bgCheckFlags & 0x60) { + if ((this->actor.bgCheckFlags & 0x40) || (this->actor.speedXZ > 3.0f)) { + if (this->actor.depthInWater < (1200.0f * this->actor.scale.y)) { + func_80B39470(&this->actor, globalCtx); + func_80B395EC(&this->actor, globalCtx); + } + if (this->actor.bgCheckFlags & 0x40) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_BOMB_DROP_WATER); + } + } else if ((((globalCtx->gameplayFrames % 16) == 0) || (((u32)Rand_Next() >> 0x10) == 0)) && + (this->actor.depthInWater < (1200.0f * this->actor.scale.y))) { + func_80B395EC(&this->actor, globalCtx); + } + + func_80B39834(&this->actor, globalCtx); + this->unk_1A8 >>= 1; + this->unk_1AA >>= 1; + + if (sp34) { + this->actor.speedXZ *= 0.8f; + } else { + this->actor.speedXZ *= 0.65f; + } + this->actor.velocity.y *= 0.27f; + this->actor.gravity *= 0.27f; + if (this->actor.speedXZ < 0.4f) { + sp30 = true; + } + } else { + if (sp34) { + this->actor.speedXZ *= 0.8f; + } else { + this->actor.speedXZ *= 0.96f; + } + this->actor.velocity.y *= 0.96f; + } + + Actor_MoveWithGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 15.0f, 0.0f, 0x45); + this->actor.shape.rot.x += this->unk_1A8; + this->actor.shape.rot.y += this->unk_1AA; + func_80B38E20(this); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (sp30) { + func_80B3A498(this); + } else { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B3A498(ObjSnowball2* this) { + this->actor.home.pos.x = this->actor.world.pos.x; + this->unk_1AC = 46; + this->actor.flags |= ACTOR_FLAG_10; + this->actor.home.pos.y = this->actor.world.pos.y + this->actor.depthInWater; + this->actor.home.pos.z = this->actor.world.pos.z; + this->actor.world.pos.y = this->actor.world.pos.y + (this->actor.shape.yOffset * this->actor.scale.y); + this->actor.shape.yOffset = 0.0f; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80B3A500; +} + +void func_80B3A500(ObjSnowball2* this, GlobalContext* globalCtx) { + f32 phi_f0; + s32 pad; + f32 temp_f14 = this->actor.home.pos.y - this->actor.world.pos.y; + f32 temp_f12 = this->actor.scale.y * 600.0f; + + this->unk_1AC--; + + this->actor.speedXZ *= 0.7f; + + this->unk_1A8 >>= 1; + this->unk_1AA >>= 1; + + this->actor.shape.rot.x += this->unk_1A8; + this->actor.shape.rot.y += this->unk_1AA; + + if (temp_f14 < -temp_f12) { + this->actor.gravity = this->actor.scale.y * -40.0f; + phi_f0 = 0.94f; + } else if (temp_f12 < temp_f14) { + this->actor.gravity = this->actor.scale.y * 24.0f; + phi_f0 = 0.8f; + } else if (temp_f12 > 0.001f) { + this->actor.gravity = (((1.6f * temp_f14) / temp_f12) + -1.0f + 0.6f) * 0.5f * 40.0f * this->actor.scale.y; + phi_f0 = (((-0.13999999f * temp_f14) / temp_f12) + 0.94f + 0.8f) * 0.5f; + } else { + this->actor.gravity = 0.0f; + phi_f0 = 1.0f; + } + + this->actor.velocity.y *= phi_f0; + this->actor.velocity.y += this->actor.gravity; + this->actor.world.pos.y += this->actor.velocity.y; + + if (((globalCtx->gameplayFrames % 16) == 0) || (((u32)Rand_Next() >> 0x10) == 0)) { + func_80B395C4(globalCtx, &this->actor.home.pos); + } + + if (this->unk_1AC <= 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->unk_1AC < 20) { + this->actor.scale.x -= 0.00125f; + if (this) {} + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + + if ((this->unk_1AC >= 6) && (temp_f14 < temp_f12)) { + func_80B39638(globalCtx, &this->actor.home.pos); + } + + if (this->unk_1AC == 10) { + func_80B38E88(this, globalCtx); + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + } else { + func_80B38E20(this); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void ObjSnowball2_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + + this->actionFunc(this, globalCtx); + + if (this->actor.projectedPos.z < 460.0f) { + if (this->actor.projectedPos.z > 200.0f) { + this->actor.shape.shadowAlpha = (460 - (s32)this->actor.projectedPos.z) >> 1; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + } else if (this->actor.projectedPos.z > -10.0f) { + this->actor.shape.shadowAlpha = 130; + this->actor.shape.shadowDraw = ActorShadow_DrawCircle; + } else { + this->actor.shape.shadowDraw = NULL; + } + } else { + this->actor.shape.shadowDraw = NULL; + } +} + +void ObjSnowball2_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball2* this = THIS; + + Gfx_DrawDListOpa(globalCtx, object_goroiwa_DL_008B90); +} diff --git a/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.h b/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.h index cbffe01f2..120358a80 100644 --- a/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.h +++ b/src/overlays/actors/ovl_Obj_Snowball2/z_obj_snowball2.h @@ -7,11 +7,21 @@ struct ObjSnowball2; typedef void (*ObjSnowball2ActionFunc)(struct ObjSnowball2*, GlobalContext*); +#define ENOBJSNOWBALL2_GET_3F(thisx) ((thisx)->params & 0x3F) +#define ENOBJSNOWBALL2_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + typedef struct ObjSnowball2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x60]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colliderElements[1]; /* 0x01A4 */ ObjSnowball2ActionFunc actionFunc; - /* 0x01A8 */ char unk_1A8[0xC]; + /* 0x01A8 */ s16 unk_1A8; + /* 0x01AA */ s16 unk_1AA; + /* 0x01AC */ s8 unk_1AC; + /* 0x01AD */ u8 unk_1AD; + /* 0x01AE */ s8 unk_1AE; + /* 0x01AF */ s8 unk_1AF; + /* 0x01B0 */ UNK_TYPE1 unk1B0[4]; } ObjSnowball2; // size = 0x1B4 extern const ActorInit Obj_Snowball2_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c index d80f30fa0..231dd99f3 100644 --- a/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c +++ b/src/overlays/actors/ovl_Obj_Sound/z_obj_sound.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_sound.c + * Overlay: ovl_Obj_Sound + * Description: Plays certain sounds (e.g., swamp waterfall noise) + */ + #include "z_obj_sound.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjSound*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.c b/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.c index 95c1e0402..37ceb7268 100644 --- a/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.c +++ b/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.c @@ -1,6 +1,13 @@ -#include "z_obj_spidertent.h" +/* + * File: z_obj_spidertent.c + * Overlay: ovl_Obj_Spidertent + * Description: Tent-Shaped Spider Web + */ -#define FLAGS 0x10000000 +#include "z_obj_spidertent.h" +#include "objects/object_spidertent/object_spidertent.h" + +#define FLAGS (ACTOR_FLAG_10000000) #define THIS ((ObjSpidertent*)thisx) @@ -9,7 +16,13 @@ void ObjSpidertent_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSpidertent_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSpidertent_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B307E0(ObjSpidertent* this); +void func_80B30808(ObjSpidertent* this, GlobalContext* globalCtx); +void func_80B30A2C(ObjSpidertent* this); +void func_80B30A4C(ObjSpidertent* this, GlobalContext* globalCtx); +void func_80B30AD4(ObjSpidertent* this); +void func_80B30AF8(ObjSpidertent* this, GlobalContext* globalCtx); + const ActorInit Obj_Spidertent_InitVars = { ACTOR_OBJ_SPIDERTENT, ACTORCAT_BG, @@ -22,118 +35,791 @@ const ActorInit Obj_Spidertent_InitVars = { (ActorFunc)ObjSpidertent_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[6] = { -static ColliderTrisElementInit D_80B31060[6] = { +static ColliderTrisElementInit sTrisElementsInit1[] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 68.80000305175781f, 0.0f, 18.799999237060547f }, { 76.30000305175781f, 0.0f, -63.79999923706055f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 68.80000305175781f, 0.0f, 18.799999237060547f }, + { 76.30000305175781f, 0.0f, -63.79999923706055f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 76.30000305175781f, 0.0f, -63.79999923706055f }, { 23.799999237060547f, 0.0f, -116.30000305175781f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 76.30000305175781f, 0.0f, -63.79999923706055f }, + { 23.799999237060547f, 0.0f, -116.30000305175781f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 23.799999237060547f, 0.0f, -116.30000305175781f }, { -111.30000305175781f, 0.0f, -26.299999237060547f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 23.799999237060547f, 0.0f, -116.30000305175781f }, + { -111.30000305175781f, 0.0f, -26.299999237060547f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { -111.30000305175781f, 0.0f, -26.299999237060547f }, { -81.30000305175781f, 0.0f, 78.80000305175781f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { -111.30000305175781f, 0.0f, -26.299999237060547f }, + { -81.30000305175781f, 0.0f, 78.80000305175781f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { -81.30000305175781f, 0.0f, 78.80000305175781f }, { 23.799999237060547f, 0.0f, 108.80000305175781f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { -81.30000305175781f, 0.0f, 78.80000305175781f }, + { 23.799999237060547f, 0.0f, 108.80000305175781f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 23.799999237060547f, 0.0f, 108.80000305175781f }, { 68.80000305175781f, 0.0f, 18.799999237060547f }, { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 23.799999237060547f, 0.0f, 108.80000305175781f }, + { 68.80000305175781f, 0.0f, 18.799999237060547f }, + { 1.2999999523162842f, 40.0f, -3.799999952316284f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B311C8 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 6, D_80B31060, // sTrisElementsInit, +static ColliderTrisInit sTrisInit1 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + 6, + sTrisElementsInit1, }; -// static ColliderTrisElementInit sTrisElementsInit[6] = { -static ColliderTrisElementInit D_80B311D8[6] = { +static ColliderTrisElementInit sTrisElementsInit2[] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 17.799999237060547f, 0.0f, 81.5999984741211f }, { 51.599998474121094f, 0.0f, 14.100000381469727f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 17.799999237060547f, 0.0f, 81.5999984741211f }, + { 51.599998474121094f, 0.0f, 14.100000381469727f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { -60.900001525878906f, 0.0f, 59.099998474121094f }, { 17.799999237060547f, 0.0f, 81.5999984741211f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { -60.900001525878906f, 0.0f, 59.099998474121094f }, + { 17.799999237060547f, 0.0f, 81.5999984741211f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { -83.4000015258789f, 0.0f, -19.700000762939453f }, { -60.900001525878906f, 0.0f, 59.099998474121094f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { -83.4000015258789f, 0.0f, -19.700000762939453f }, + { -60.900001525878906f, 0.0f, 59.099998474121094f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 17.799999237060547f, 0.0f, -87.19999694824219f }, { -83.4000015258789f, 0.0f, -19.700000762939453f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 17.799999237060547f, 0.0f, -87.19999694824219f }, + { -83.4000015258789f, 0.0f, -19.700000762939453f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 57.20000076293945f, 0.0f, -47.79999923706055f }, { 17.799999237060547f, 0.0f, -87.19999694824219f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 57.20000076293945f, 0.0f, -47.79999923706055f }, + { 17.799999237060547f, 0.0f, -87.19999694824219f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, - { { { 51.599998474121094f, 0.0f, 14.100000381469727f }, { 57.20000076293945f, 0.0f, -47.79999923706055f }, { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, + { { { 51.599998474121094f, 0.0f, 14.100000381469727f }, + { 57.20000076293945f, 0.0f, -47.79999923706055f }, + { 0.8999999761581421f, 30.0f, -2.799999952316284f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80B31340 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 6, D_80B311D8, // sTrisElementsInit, +static ColliderTrisInit sTrisInit2 = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + 6, + sTrisElementsInit2, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B31418[] = { +typedef struct { + /* 0x00 */ Gfx* unk_00; + /* 0x04 */ CollisionHeader* unk_04; + /* 0x08 */ ColliderTrisInit* unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ f32 unk_20; + /* 0x24 */ f32 unk_24; +} ObjSpidertentStruct; + +ObjSpidertentStruct D_80B31350[] = { + { + object_spidertent_DL_000070, + &object_spidertent_Colheader_0011AC, + &sTrisInit1, + 0.9f, + 1.3f, + 40.0f, + -3.8f, + SQ(120.0f), + 240.0f, + 200.0f, + }, + { + object_spidertent_DL_001250, + &object_spidertent_Colheader_00238C, + &sTrisInit2, + 0.9f, + 0.9f, + 30.0f, + -2.8f, + SQ(88.0f), + 176.0f, + 168.0f, + }, +}; + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ s8 unk_0E; + /* 0x0F */ s8 unk_0F; + /* 0x10 */ Color_RGBA8 unk_10; + /* 0x14 */ Color_RGBA8 unk_14; +} ObjSpidertentStruct2; + +ObjSpidertentStruct2 D_80B313A0[] = { + { + -20.0f, + 6.0f, + 0.0f, + 100, + 14, + 5, + { 255, 255, 160, 160 }, + { 255, 0, 0, 0 }, + }, + { + 0.0f, + 4.0f, + 1.2f, + 80, + 9, + 3, + { 255, 255, 160, 120 }, + { 255, 0, 0, 0 }, + }, + { + 0.0f, + 4.2f, + 0.3f, + 70, + 12, + 2, + { 255, 255, 160, 100 }, + { 55, 0, 0, 0 }, + }, + { + 0.0f, + 3.0f, + 0.0f, + 20, + 6, + 2, + { 255, 100, 20, 80 }, + { 255, 0, 0, 0 }, + }, +}; + +Vec3f D_80B31400 = { 1.0f, 0.0f, 0.0f }; +Vec3f D_80B3140C = { 0.0f, 1.0f, 0.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), }; +s32 func_80B2FB10(Vec3f* arg0, Vec3f* arg1) { + f32 temp_f0 = Math3D_LengthSquared(arg0); + f32 temp_f2; + + if (temp_f0 < 9.999999e-9f) { + return false; + } + temp_f2 = 1.0f / sqrtf(temp_f0); + arg1->x = arg0->x * temp_f2; + arg1->y = arg0->y * temp_f2; + arg1->z = arg0->z * temp_f2; + return true; +} + +s32 func_80B2FB94(Vec3f* arg0, f32 arg1, TriNorm* triNorm, Vec3f* arg3, f32* arg4) { + f32 temp_f0; + f32 temp_f0_2; + f32 temp_f16; + Vec3f sp48; + Vec3f sp3C; + f32 temp_f2; + f32 temp_f2_2; + + temp_f0 = triNorm->plane.normal.x * arg1; + temp_f2 = triNorm->plane.normal.y * arg1; + temp_f16 = triNorm->plane.normal.z * arg1; + + sp48.x = arg0->x + temp_f0; + sp48.y = arg0->y + temp_f2; + sp48.z = arg0->z + temp_f16; + + sp3C.x = arg0->x - temp_f0; + sp3C.y = arg0->y - temp_f2; + sp3C.z = arg0->z - temp_f16; + + if (Math3D_LineSegVsPlane(triNorm->plane.normal.x, triNorm->plane.normal.y, triNorm->plane.normal.z, + triNorm->plane.originDist, &sp48, &sp3C, arg3, 0)) { + temp_f0_2 = Math3D_Vec3fDistSq(arg0, arg3); + temp_f2_2 = SQ(arg1) - temp_f0_2; + if (SQ(arg1) < temp_f0_2) { + return false; + } + *arg4 = sqrtf(temp_f2_2); + return true; + } + return false; +} + +s32 func_80B2FC98(TriNorm* triNorm, Vec3f* arg1) { + Vec3f sp84; + Vec3f sp78; + Vec3f* vtx; + Vec3f* vtx2; + Vec3f sp4C[3]; + s32 i; + + if (triNorm->plane.normal.x > 0.5f) { + vtx = &triNorm->vtx[0]; + vtx2 = &triNorm->vtx[2]; + + for (i = 0; i < ARRAY_COUNT(sp4C); i++, vtx = &triNorm->vtx[i]) { + sp84.x = 0.0f; + sp84.y = vtx->y - arg1->y; + sp84.z = vtx->z - arg1->z; + + sp78.x = 0.0f; + sp78.y = vtx2->y - arg1->y; + sp78.z = vtx2->z - arg1->z; + + Math3D_CrossProduct(&sp84, &sp78, &sp4C[i]); + + vtx2 = vtx; + } + + return ((sp4C[0].x >= 0.0f) && (sp4C[1].x >= 0.0f) && (sp4C[2].x >= 0.0f)) || + ((sp4C[0].x < 0.0f) && (sp4C[1].x < 0.0f) && (sp4C[2].x < 0.0f)); + } else if (triNorm->plane.normal.y > 0.5f) { + vtx = &triNorm->vtx[0]; + vtx2 = &triNorm->vtx[2]; + + for (i = 0; i < ARRAY_COUNT(sp4C); i++, vtx = &triNorm->vtx[i]) { + sp84.x = vtx->x - arg1->x; + sp84.y = 0.0f; + sp84.z = vtx->z - arg1->z; + + sp78.x = vtx2->x - arg1->x; + sp78.y = 0.0f; + sp78.z = vtx2->z - arg1->z; + + Math3D_CrossProduct(&sp84, &sp78, &sp4C[i]); + + vtx2 = vtx; + } + + return ((sp4C[0].y >= 0.0f) && (sp4C[1].y >= 0.0f) && (sp4C[2].y >= 0.0f)) || + ((sp4C[0].y < 0.0f) && (sp4C[1].y < 0.0f) && (sp4C[2].y < 0.0f)); + } else { + vtx = &triNorm->vtx[0]; + vtx2 = &triNorm->vtx[2]; + + for (i = 0; i < ARRAY_COUNT(sp4C); i++, vtx = &triNorm->vtx[i]) { + sp84.x = vtx->x - arg1->x; + sp84.y = vtx->y - arg1->y; + sp84.z = 0.0f; + + sp78.x = vtx2->x - arg1->x; + sp78.y = vtx2->y - arg1->y; + sp78.z = 0.0f; + + Math3D_CrossProduct(&sp84, &sp78, &sp4C[i]); + + vtx2 = vtx; + } + + return ((sp4C[0].z >= 0.0f) && (sp4C[1].z >= 0.0f) && (sp4C[2].z >= 0.0f)) || + ((sp4C[0].z < 0.0f) && (sp4C[1].z < 0.0f) && (sp4C[2].z < 0.0f)); + } +} + +void func_80B300F4(ObjSpidertent* thisx, GlobalContext* globalCtx, TriNorm* triNorm, Vec3f* arg3, f32 arg4, s32 arg5) { + ObjSpidertent* this = THIS; + ObjSpidertentStruct* spE0 = &D_80B31350[OBJSPIDERTENT_GET_1(&this->dyna.actor)]; + f32 temp_f24; + f32 phi_f22; + s32 i; + f32 temp_f0; + Vec3f spC4; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + Vec3f sp88; + f32 temp_f2; + ObjSpidertentStruct2* sp80 = &D_80B313A0[arg5]; + + spAC.x = triNorm->plane.normal.x; + spAC.y = triNorm->plane.normal.y; + spAC.z = triNorm->plane.normal.z; + + if (triNorm->plane.normal.y < 0.5f) { + Math3D_CrossProduct(&spAC, &D_80B3140C, &sp88); + } else { + Math3D_CrossProduct(&spAC, &D_80B31400, &sp88); + } + + if (func_80B2FB10(&sp88, &spA0)) { + phi_f22 = 0.0f; + temp_f24 = (2 * M_PI) / sp80->unk_0F; + + for (i = 0; i < sp80->unk_0F; i++) { + temp_f2 = (Rand_ZeroOne() * temp_f24) + phi_f22; + Matrix_RotateAxisF(temp_f2, &spAC, MTXMODE_NEW); + Matrix_MultVec3f(&spA0, &sp94); + + if (arg5 == 0) { + spC4.x = (sp94.x * arg4) + arg3->x; + spC4.y = (sp94.y * arg4) + arg3->y; + spC4.z = (sp94.z * arg4) + arg3->z; + } else { + temp_f0 = Rand_ZeroOne(); + temp_f0 = (1.0f - SQ(temp_f0)) * arg4; + spC4.x = (sp94.x * temp_f0) + arg3->x; + spC4.y = (sp94.y * temp_f0) + arg3->y; + spC4.z = (sp94.z * temp_f0) + arg3->z; + } + + if ((Math3D_Vec3fDistSq(&spC4, &this->dyna.actor.world.pos) < spE0->unk_1C) && + func_80B2FC98(triNorm, &spC4)) { + spB8.x = sp80->unk_08 * sp94.x; + spB8.y = sp80->unk_08 * sp94.y; + spB8.z = sp80->unk_08 * sp94.z; + + EffectSsDeadDb_Spawn(globalCtx, &spC4, &spB8, &gZeroVec3f, &sp80->unk_10, &sp80->unk_14, sp80->unk_0C, + 0, sp80->unk_0E); + } + + phi_f22 += temp_f24; + } + } +} + +void func_80B30410(ObjSpidertent* this, Vec3f* arg1) { + s32 i; + + Math_Vec3f_Copy(&this->unk_3A4, arg1); + this->unk_3C2 = 255; + this->unk_3C3 = 255; + this->unk_3C4 = 255; + this->unk_3C5 = 255; + for (i = 0; i < ARRAY_COUNT(D_80B313A0); i++) { + this->unk_3B0[i] = D_80B313A0[i].unk_00; + } + this->unk_3C0 = 0; +} + +s32 func_80B30480(ObjSpidertent* this, GlobalContext* globalCtx, Vec3f* arg2) { + Player* player = GET_PLAYER(globalCtx); + TriNorm* triNorm; + s32 i; + Vec3f sp58; + f32 sp54; + + if (player->itemActionParam == 7) { + if (player->unk_B28 > 0) { + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + triNorm = &this->collider.elements[i].dim; + + if (func_80B2FB94(&player->swordInfo[0].tip, 6.0f, triNorm, &sp58, &sp54) && + func_80B2FC98(triNorm, &sp58)) { + break; + } + } + + if (i < ARRAY_COUNT(this->colliderElements)) { + Math_Vec3f_Copy(arg2, &player->swordInfo[0].tip); + return true; + } + } + } + return false; +} + +void ObjSpidertent_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSpidertent* this = THIS; + s32 temp_s1 = OBJSPIDERTENT_GET_1(&this->dyna.actor); + ObjSpidertentStruct* ptr = &D_80B31350[temp_s1]; + ColliderTrisElementInit* element; + Vec3f sp70[3]; + Vec3f sp64; + s32 i; + s32 j; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + Collider_InitTris(globalCtx, &this->collider); + + if (Flags_GetSwitch(globalCtx, OBJSPIDERTENT_GET_7F00(&this->dyna.actor))) { + Actor_MarkForDeath(&this->dyna.actor); + return; + } + + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, ptr->unk_04); + Collider_SetTris(globalCtx, &this->collider, &this->dyna.actor, D_80B31350[temp_s1].unk_08, this->colliderElements); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + + sp64.x = ptr->unk_10 * 1.2f; + sp64.y = ptr->unk_10 * 1.2f; + sp64.z = ptr->unk_10 * 1.2f; + + Matrix_MultVec3f(&sp64, &this->dyna.actor.focus.pos); + Matrix_Translate(ptr->unk_10, ptr->unk_14 + 5.0f, ptr->unk_18, MTXMODE_APPLY); + Matrix_Scale(ptr->unk_0C, ptr->unk_0C, ptr->unk_0C, MTXMODE_APPLY); + Matrix_Translate(-ptr->unk_10, -ptr->unk_14, -ptr->unk_18, MTXMODE_APPLY); + + for (i = 0; i < 6; i++) { + element = &ptr->unk_08->elements[i]; + + for (j = 0; j < ARRAY_COUNT(sp70); j++) { + Matrix_MultVec3f(&element->dim.vtx[j], &sp70[j]); + } + + Collider_SetTrisVertices(&this->collider, i, &sp70[0], &sp70[1], &sp70[2]); + } + + func_80B307E0(this); +} + +void ObjSpidertent_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSpidertent* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyTris(globalCtx, &this->collider); +} + +void func_80B307E0(ObjSpidertent* this) { + this->unk_3C2 = 255; + this->unk_3C3 = 255; + this->unk_3C4 = 255; + this->unk_3C5 = 255; + this->actionFunc = func_80B30808; +} + +void func_80B30808(ObjSpidertent* this, GlobalContext* globalCtx) { + s32 phi_s4; + s32 i; + ObjSpidertentStruct* ptr2 = &D_80B31350[OBJSPIDERTENT_GET_1(&this->dyna.actor)]; + Vec3f sp70; + Vec3s* hitPos; + ColliderTrisElement* ptr; + f32 temp_f0; + s32 phi_s1; + Vec3f sp54; + f32 phi_f20; + s32 phi_s0 = false; + + if (this->collider.base.acFlags & AC_HIT) { + Player* player = GET_PLAYER(globalCtx); + + this->collider.base.acFlags &= ~AC_HIT; + phi_s1 = 0; + phi_s4 = -1; + phi_f20 = FLT_MAX; + + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + ptr = &this->collider.elements[i]; + + if (ptr->info.bumperFlags & BUMP_HIT) { + sp54.x = ptr->info.bumper.hitPos.x; + sp54.y = ptr->info.bumper.hitPos.y; + sp54.z = ptr->info.bumper.hitPos.z; + + temp_f0 = Math3D_Vec3fDistSq(&sp54, &player->actor.world.pos); + if (temp_f0 < phi_f20) { + phi_f20 = temp_f0; + phi_s4 = i; + } + } + } + + if (phi_s4 >= 0) { + hitPos = &this->collider.elements[phi_s4].info.bumper.hitPos; + + sp70.x = hitPos->x; + sp70.y = hitPos->y; + sp70.z = hitPos->z; + } else { + Math_Vec3f_Copy(&sp70, &this->dyna.actor.world.pos); + } + phi_s0 = true; + } else if ((this->dyna.actor.xzDistToPlayer < ptr2->unk_24) && func_80B30480(this, globalCtx, &sp70)) { + phi_s0 = true; + } + + if (phi_s0) { + func_80B30410(this, &sp70); + func_80B30A2C(this); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void func_80B30A2C(ObjSpidertent* this) { + this->dyna.actor.flags |= ACTOR_FLAG_10; + this->actionFunc = func_80B30A4C; +} + +void func_80B30A4C(ObjSpidertent* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + if (this->dyna.actor.cutscene >= 0) { + func_800B7298(globalCtx, &this->dyna.actor, 1); + } + Flags_SetSwitch(globalCtx, OBJSPIDERTENT_GET_7F00(&this->dyna.actor)); + func_80B30AD4(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80B30AD4(ObjSpidertent* this) { + this->unk_3C1 = 80; + this->unk_3C6 = 0; + this->unk_3C7 = 0; + this->actionFunc = func_80B30AF8; +} + +#ifdef NON_MATCHING +void func_80B30AF8(ObjSpidertent* this, GlobalContext* globalCtx) { + ObjSpidertentStruct* temp_s0 = &D_80B31350[OBJSPIDERTENT_GET_1(&this->dyna.actor)]; + TriNorm* triNorm; + s32 i; + s32 j; + s32 pad; + Vec3f sp60; + f32 sp5C; + + this->unk_3C6++; + + if (this->unk_3C6 < 40) { + if (this->unk_3C2 > 2) { + this->unk_3C2 -= 2; + } else { + this->unk_3C2 = 0; + } + + if (this->unk_3C3 > 5) { + this->unk_3C3 -= 5; + } else { + this->unk_3C3 = 0; + } + + if (this->unk_3C4 > 5) { + this->unk_3C4 -= 5; + } else { + this->unk_3C4 = 0; + } + + if (this->unk_3C5 > 1) { + this->unk_3C5--; + } else { + this->unk_3C5 = 0; + } + } else { + if (this->unk_3C2 > 4) { + this->unk_3C2 -= 4; + } else { + this->unk_3C2 = 0; + } + + if (this->unk_3C3 < 255) { + this->unk_3C3++; + } else { + this->unk_3C3 = 255; + } + + if (this->unk_3C4 < 255) { + this->unk_3C4++; + } else { + this->unk_3C4 = 255; + } + + if (this->unk_3C5 > 10) { + this->unk_3C5 -= 10; + } else { + this->unk_3C5 = 0; + } + } + + this->unk_3C1--; + if (this->unk_3C1 == 40) { + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + + if (this->unk_3C1 >= 0x20) { + if (this->unk_3C7 > 0) { + this->unk_3C7--; + } else if (this->unk_3C1 >= 0x33) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EN_EXTINCT); + this->unk_3C7 = Rand_S16Offset(2, 2); + } else { + SoundSource_PlaySfxAtFixedWorldPos(globalCtx, &this->dyna.actor.world.pos, 11, NA_SE_EN_EXTINCT); + this->unk_3C7 = Rand_S16Offset(2, 4); + } + + for (j = 0; j < ARRAY_COUNT(this->unk_3B0); j++) { + this->unk_3B0[j] += D_80B313A0[j].unk_04; + if (temp_s0->unk_20 < this->unk_3B0[j]) { + this->unk_3C0 |= (1 << j); + } + } + + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + triNorm = &this->collider.elements[i].dim; + + for (j = 0; j < ARRAY_COUNT(this->unk_3B0); j++) { + if (!(this->unk_3B0[j] < 5.0f) && !(this->unk_3C0 & (1 << j)) && + func_80B2FB94(&this->unk_3A4, this->unk_3B0[j], triNorm, &sp60, &sp5C)) { + func_80B300F4(this, globalCtx, triNorm, &sp60, sp5C, j); + } + } + } + } else if (this->unk_3C1 <= 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + Actor_MarkForDeath(&this->dyna.actor); + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30AF8.s") #endif -extern ColliderTrisElementInit D_80B31060[6]; -extern ColliderTrisInit D_80B311C8; -extern ColliderTrisElementInit D_80B311D8[6]; -extern ColliderTrisInit D_80B31340; -extern InitChainEntry D_80B31418[]; +void ObjSpidertent_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjSpidertent* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B2FB10.s") + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B2FB94.s") +void ObjSpidertent_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSpidertent* this = THIS; + s32 params = OBJSPIDERTENT_GET_1(&this->dyna.actor); + s32 temp_f18 = this->unk_3C5 * (29.0f / 51); + Gfx* gfx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B2FC98.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B300F4.s") + gfx = POLY_XLU_DISP; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30410.s") + gSPDisplayList(gfx++, &sSetupDL[6 * 25]); + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(gfx++, 0, 0xFF, this->unk_3C2, this->unk_3C3, this->unk_3C4, temp_f18); + gSPDisplayList(gfx++, D_80B31350[params].unk_00); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30480.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/ObjSpidertent_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/ObjSpidertent_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B307E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30808.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30A2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30A4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30AD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/func_80B30AF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/ObjSpidertent_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spidertent/ObjSpidertent_Draw.s") + POLY_XLU_DISP = gfx; + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.h b/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.h index a40faa86a..9289bd365 100644 --- a/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.h +++ b/src/overlays/actors/ovl_Obj_Spidertent/z_obj_spidertent.h @@ -7,9 +7,23 @@ struct ObjSpidertent; typedef void (*ObjSpidertentActionFunc)(struct ObjSpidertent*, GlobalContext*); +#define OBJSPIDERTENT_GET_1(thisx) ((thisx)->params & 1) +#define OBJSPIDERTENT_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + typedef struct ObjSpidertent { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x284]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderTris collider; + /* 0x017C */ ColliderTrisElement colliderElements[6]; + /* 0x03A4 */ Vec3f unk_3A4; + /* 0x03B0 */ f32 unk_3B0[4]; + /* 0x03C0 */ u8 unk_3C0; + /* 0x03C1 */ s8 unk_3C1; + /* 0x03C2 */ u8 unk_3C2; + /* 0x03C3 */ u8 unk_3C3; + /* 0x03C4 */ u8 unk_3C4; + /* 0x03C5 */ u8 unk_3C5; + /* 0x03C6 */ s8 unk_3C6; + /* 0x03C7 */ s8 unk_3C7; /* 0x03C8 */ ObjSpidertentActionFunc actionFunc; } ObjSpidertent; // size = 0x3CC 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 c9a881180..2b15ef0b6 100644 --- a/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c +++ b/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c @@ -1,6 +1,13 @@ -#include "z_obj_spinyroll.h" +/* + * File: z_obj_spinyroll.c + * Overlay: ovl_Obj_Spinyroll + * Description: Horizontal Spike-Covered Log + */ -#define FLAGS 0x00000010 +#include "z_obj_spinyroll.h" +#include "objects/object_spinyroll/object_spinyroll.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjSpinyroll*)thisx) @@ -9,7 +16,18 @@ void ObjSpinyroll_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSpinyroll_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSpinyroll_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A1E9C4(ObjSpinyroll* this); +void func_80A1E9E0(ObjSpinyroll* this, GlobalContext* globalCtx); +void func_80A1EA4C(ObjSpinyroll* this, GlobalContext* globalCtx); +void func_80A1EAAC(ObjSpinyroll* this); +void func_80A1EAE0(ObjSpinyroll* this, GlobalContext* globalCtx); +void func_80A1EB40(ObjSpinyroll* this); +void func_80A1EB54(ObjSpinyroll* this, GlobalContext* globalCtx); +void func_80A1EC24(ObjSpinyroll* this); +void func_80A1EC38(ObjSpinyroll* this, GlobalContext* globalCtx); +void func_80A1ECC0(ObjSpinyroll* this); +void func_80A1ECD4(ObjSpinyroll* this, GlobalContext* globalCtx); + const ActorInit Obj_Spinyroll_InitVars = { ACTOR_OBJ_SPINYROLL, ACTORCAT_PROP, @@ -22,121 +40,669 @@ const ActorInit Obj_Spinyroll_InitVars = { (ActorFunc)ObjSpinyroll_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[6] = { -static ColliderTrisElementInit D_80A1F040[6] = { +static ColliderTrisElementInit sTrisElementsInit[] = { { - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -60.0f, 0.0f, 17.0f }, { 60.0f, 0.0f, 17.0f }, { 60.0f, 40.0f, 17.0f } } }, }, { - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -60.0f, 0.0f, 17.0f }, { 60.0f, 40.0f, 17.0f }, { -60.0f, 40.0f, 17.0f } } }, }, { - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 60.0f, 0.0f, -17.0f }, { -60.0f, 0.0f, -17.0f }, { -60.0f, 40.0f, -17.0f } } }, }, { - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 60.0f, 0.0f, -17.0f }, { -60.0f, 40.0f, -17.0f }, { 60.0f, 40.0f, -17.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 60.0f, 20.0f, -12.0f }, { -60.0f, 20.0f, -12.0f }, { -60.0f, 20.0f, 12.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x04, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x04, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 60.0f, 20.0f, -12.0f }, { -60.0f, 20.0f, 12.0f }, { 60.0f, 20.0f, 12.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80A1F1A8 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 6, D_80A1F040, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + 6, + sTrisElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A1F204[] = { +f32 D_80A1F1B8[] = { 1.0f, 2.0f, 4.0f }; + +f32 D_80A1F1C4[] = { + 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, +}; + +s16 D_80A1F1E4[] = { + 1, 10, 20, 30, 40, 50, 60, 70, +}; + +f32 D_80A1F1F4[] = { 30.0f, -30.0f }; + +f32 D_80A1F1FC[] = { 9.0f, -9.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; +s16 D_80A1F20C[] = { 0xFA0, -0xFA0 }; + +void func_80A1DA50(GlobalContext* globalCtx, ObjSpinyroll* this, Vec3f* arg2, Vec3f* arg3) { + Vec3f sp1C; + + Math_Vec3f_Sum(arg2, arg3, &sp1C); + Math_Vec3f_Scale(&sp1C, 0.5f); + EffectSsHitMark_SpawnFixedScale(globalCtx, 3, &sp1C); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_IT_SHIELD_REFLECT_SW); +} + +void func_80A1DAAC(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_80A1DB2C(Actor* thisx) { + ObjSpinyroll* this = THIS; + s32 i; + s32 j; + s32 params = OBJSPINYROLL_GET_C000(&this->dyna.actor); + Vec3f sp7C[3]; + Vec3f sp70; + f32 temp = D_80A1F1B8[params]; + ColliderTrisElementInit* ptr; + + for (i = 0; i < ARRAY_COUNT(this->colliderElements); i++) { + for (j = 0; j < ARRAY_COUNT(sp7C); j++) { + ptr = &sTrisInit.elements[i]; + + sp70.x = ptr->dim.vtx[j].x * temp; + sp70.y = ptr->dim.vtx[j].y; + sp70.z = ptr->dim.vtx[j].z; + + func_80A1DAAC(&sp7C[j], &sp70, this->dyna.actor.shape.rot.y); + Math_Vec3f_Sum(&sp7C[j], &this->dyna.actor.world.pos, &sp7C[j]); + } + Collider_SetTrisVertices(&this->collider, i, &sp7C[0], &sp7C[1], &sp7C[2]); + } +} + +void func_80A1DC5C(ObjSpinyroll* this) { + this->unk_4D8 += 0x5DC0; + Math_StepToF(&this->unk_4D4, 0.0f, 0.32f); + this->unk_4D0 = ((Math_SinS(this->unk_4D8) + 1.0f) * this->unk_4D4) + 24.0f; +} + +void func_80A1DCCC(ObjSpinyroll* this) { + f32 phi_f2; + + if (this->dyna.actor.speedXZ > 3.0f) { + phi_f2 = 3.0f; + } else { + phi_f2 = this->dyna.actor.speedXZ; + } + + if (this->unk_4D4 < phi_f2) { + this->unk_4D4 = phi_f2; + } +} + +void func_80A1DD18(ObjSpinyroll* this) { + f32 temp_f0; + Vec3f* sp20 = &this->unk_4AC[this->unk_4A8 ^ 1]; + + Math_Vec3f_Diff(sp20, &this->dyna.actor.world.pos, &this->unk_4C4); + + temp_f0 = Math3D_Vec3fMagnitude(&this->unk_4C4); + if (temp_f0 < 0.01f) { + Math_Vec3f_Diff(sp20, &this->unk_4AC[this->unk_4A8], &this->unk_4C4); + + temp_f0 = Math3D_Vec3fMagnitude(&this->unk_4C4); + if (temp_f0 < 0.01f) { + Math_Vec3f_Copy(&this->unk_4C4, &gZeroVec3f); + return; + } + } + Math_Vec3f_Scale(&this->unk_4C4, 1.0f / temp_f0); +} + +void func_80A1DE10(ObjSpinyroll* this) { + this->dyna.actor.world.rot.y = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &this->unk_4AC[this->unk_4A8 ^ 1]); +} + +void func_80A1DE58(ObjSpinyroll* this) { + this->unk_4A8 = 0; + func_80A1DE10(this); + func_80A1DD18(this); +} + +void func_80A1DE84(ObjSpinyroll* this) { + this->unk_4A8 ^= 1; + func_80A1DE10(this); + func_80A1DD18(this); +} + +s32 func_80A1DEB8(ObjSpinyroll* this) { + s32 pad; + s32 sp30 = this->unk_4A8 ^ 1; + Vec3f sp24; + + Math_StepToF(&this->dyna.actor.speedXZ, this->unk_4A4, this->unk_4A4 * 0.2f); + + this->dyna.actor.world.pos.x += this->dyna.actor.speedXZ * this->unk_4C4.x; + this->dyna.actor.world.pos.y += this->dyna.actor.speedXZ * this->unk_4C4.y; + this->dyna.actor.world.pos.z += this->dyna.actor.speedXZ * this->unk_4C4.z; + + Math_Vec3f_Diff(&this->unk_4AC[sp30], &this->dyna.actor.world.pos, &sp24); + + return Math3D_LengthSquared(&sp24) < (SQ(this->dyna.actor.speedXZ) + 0.05f); +} + +void func_80A1DFA0(ObjSpinyroll* this) { + f32 temp_f0; + f32 phi_f12; + s32 i; + s32 j; + f32 temp_f2; + + this->unk_3A4.unk_F4 = (s32)(D_80A1F1B8[OBJSPINYROLL_GET_C000(&this->dyna.actor)] * 120.0f * (1.0f / 58)) + 2; + + temp_f0 = (D_80A1F1B8[OBJSPINYROLL_GET_C000(&this->dyna.actor)] * 120.0f) - 2.0f; + temp_f2 = temp_f0 / (this->unk_3A4.unk_F4 - 1); + temp_f0 *= 0.5f; + + for (i = 0; i < ARRAY_COUNT(this->unk_3A4.unk_00); i++) { + for (j = 0, phi_f12 = temp_f0; j < this->unk_3A4.unk_F4; j++, phi_f12 -= temp_f2) { + this->unk_3A4.unk_00[i].unk_00[j].unk_00 = phi_f12; + } + } +} + +#ifdef NON_MATCHING +// globalCtx not in s reg, something with ptr->unk_F0 = temp_s1; line +s32 func_80A1E074(ObjSpinyroll* this, GlobalContext* globalCtx, Vec3f* arg2, s32 arg3) { + s32 i; + s32 j; + ObjSpinyrollStruct2* ptr = &this->unk_3A4; + f32 temp_f0; + f32 temp_f20; + Vec3f spC8; + Vec3f spBC; + Vec3f spB0; + ObjSpinyrollStruct* temp_s1; + f32 temp_f22; + f32 temp_f24; + f32 temp; + s32 sp98; + + spC8.y = this->dyna.actor.world.pos.y + 10.0f; + spBC.y = spC8.y; + sp98 = false; + temp_f20 = FLT_MAX; + ptr->unk_F0 = NULL; + + for (i = 0; i < ARRAY_COUNT(this->unk_3A4.unk_00); i++) { + temp = D_80A1F1F4[i]; + temp_f22 = temp * this->unk_4C4.x; + temp_f24 = temp * this->unk_4C4.z; + temp_s1 = &ptr->unk_00[i]; + + for (j = 0; j < ptr->unk_F4; j++) { + spC8.x = + (temp_s1->unk_00[j].unk_00 * Math_CosS(this->dyna.actor.world.rot.y)) + this->dyna.actor.world.pos.x; + spC8.z = + (temp_s1->unk_00[j].unk_00 * -Math_SinS(this->dyna.actor.world.rot.y)) + this->dyna.actor.world.pos.z; + + spBC.x = temp_f22 + spC8.x; + spBC.z = temp_f24 + spC8.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spC8, &spBC, &spB0, &temp_s1->unk_00[j].unk_04, 1, 0, 0, 1, + &temp_s1->unk_00[j].bgId, &this->dyna.actor, 0.0f)) { + if (arg3 && (this->dyna.actor.flags & ACTOR_FLAG_40)) { + func_80A1DA50(globalCtx, this, &spC8, &spB0); + } + + temp_f0 = Math3D_Vec3fDistSq(&spC8, &spB0); + if (temp_f0 < temp_f20) { + temp_f20 = temp_f0; + sp98 = true; + Math_Vec3f_Diff(&spB0, &spBC, arg2); + ptr->unk_F0 = temp_s1; + } + } + } + } + + return sp98; +} +#else +s32 func_80A1E074(ObjSpinyroll* this, GlobalContext* globalCtx, Vec3f* arg2, s32 arg3); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E074.s") #endif -extern ColliderTrisElementInit D_80A1F040[6]; -extern ColliderTrisInit D_80A1F1A8; -extern InitChainEntry D_80A1F204[]; +s32 func_80A1E2D8(ObjSpinyroll* this, GlobalContext* globalCtx, s32 arg2) { + Vec3f sp1C; -extern UNK_TYPE D_06000460; -extern UNK_TYPE D_06000E68; + if (func_80A1E074(this, globalCtx, &sp1C, arg2)) { + this->dyna.actor.world.pos.x += sp1C.x; + this->dyna.actor.world.pos.z += sp1C.z; + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DA50.s") +s32 func_80A1E334(CollisionContext* colCtx, f32* arg1, CollisionPoly** polyOut, s32* bgId, Vec3f* arg4, + ObjSpinyroll* this) { + f32 temp_f0 = BgCheck_EntityRaycastFloor5(colCtx, polyOut, bgId, &this->dyna.actor, arg4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DAAC.s") + *arg1 = temp_f0; + return *arg1 > (BGCHECK_Y_MIN + 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DB2C.s") +s32 func_80A1E394(CollisionContext* colCtx, f32* arg1, CollisionPoly** polyOut, s32* bgId, Vec3f* arg4, + ObjSpinyroll* this) { + return BgCheck_EntityCheckCeiling(colCtx, arg1, arg4, 24.0f, polyOut, bgId, &this->dyna.actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DC5C.s") +#ifdef NON_MATCHING +s32 func_80A1E3D8(ObjSpinyroll* this, GlobalContext* globalCtx, f32* arg2, s32 arg3) { + f32 temp_f20; + ObjSpinyrollStruct2* spC8; + f32 phi_f22; + ObjSpinyrollColFunc spC0; + s32 i; + s32 j; + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + ObjSpinyrollStruct* temp_s0; + f32 phi_f26; + s32 sp84; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DCCC.s") + spC8 = &this->unk_3A4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DD18.s") + if (this->unk_4C4.y > 0.0f) { + spC0 = func_80A1E394; + phi_f26 = this->dyna.actor.world.pos.y + 48.0f; + } else { + spC0 = func_80A1E334; + phi_f26 = this->dyna.actor.world.pos.y; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DE10.s") + sp84 = false; + sp94.y = this->dyna.actor.world.pos.y + 24.0f; + phi_f22 = FLT_MAX; + spC8->unk_F0 = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DE58.s") + for (i = 0; i < ARRAY_COUNT(this->unk_3A4.unk_00); i++) { + sp94.z = D_80A1F1FC[i]; + temp_s0 = &spC8->unk_00[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DE84.s") + for (j = 0; j < spC8->unk_F4; j++) { + sp94.x = temp_s0->unk_00[j].unk_00; + func_80A1DAAC(&spAC, &sp94, this->dyna.actor.world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DEB8.s") + spAC.x += this->dyna.actor.world.pos.x; + spAC.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1DFA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E074.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E2D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E334.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E394.s") + if (spC0(&globalCtx->colCtx, &spA0.y, &temp_s0->unk_00[j].unk_04, &temp_s0->unk_00[j].bgId, &spAC, this)) { + temp_f20 = fabsf(spA0.y - spAC.y); + if (temp_f20 <= 24.0f) { + if (arg3 && (this->dyna.actor.flags & ACTOR_FLAG_40)) { + spA0.x = spAC.x; + spA0.z = spAC.z; + func_80A1DA50(globalCtx, this, &spAC, &spA0); + } + if (temp_f20 < phi_f22) { + sp84 = true; + *arg2 = spA0.y - phi_f26; + phi_f22 = temp_f20; + spC8->unk_F0 = temp_s0; + } + } + } + } + } + return sp84; +} +#else +s32 func_80A1E3D8(ObjSpinyroll* this, GlobalContext* globalCtx, f32* arg2, s32 arg3); #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E3D8.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E648.s") +s32 func_80A1E648(ObjSpinyroll* this, GlobalContext* globalCtx, s32 arg2) { + f32 sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E694.s") + if (func_80A1E3D8(this, globalCtx, &sp1C, arg2)) { + this->dyna.actor.world.pos.y += sp1C; + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E6D4.s") +DynaPolyActor* func_80A1E694(ObjSpinyroll* this, GlobalContext* globalCtx) { + if (this->unk_3A4.unk_F0 != NULL) { + return DynaPoly_GetActor(&globalCtx->colCtx, this->unk_3A4.unk_F0->unk_00[0].bgId); + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/ObjSpinyroll_Init.s") +s32 func_80A1E6D4(ObjSpinyroll* this, GlobalContext* globalCtx) { + DynaPolyActor* temp_v0 = func_80A1E694(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/ObjSpinyroll_Destroy.s") + if ((temp_v0 != NULL) && (Math3D_Vec3fDistSq(&temp_v0->actor.world.pos, &temp_v0->actor.prevPos) > SQ(0.01f))) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E9C4.s") +void ObjSpinyroll_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSpinyroll* this = THIS; + f32 sp44; + Path* path; + s32 pad2; + Vec3s* points; + Vec3s* sp34; + Vec3s* sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1E9E0.s") + sp44 = D_80A1F1B8[OBJSPINYROLL_GET_C000(&this->dyna.actor)]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.world.rot.z = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EA10.s") + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EA4C.s") + this->dyna.actor.scale.x = 0.1f * sp44; + this->dyna.actor.scale.y = 0.1f; + this->dyna.actor.scale.z = 0.1f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EAAC.s") + this->dyna.actor.uncullZoneScale = 250.0f * sp44; + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_spinyroll_Colheader_000E68); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EAE0.s") + Collider_InitTris(globalCtx, &this->collider); + Collider_SetTris(globalCtx, &this->collider, &this->dyna.actor, &sTrisInit, this->colliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EB40.s") + if (OBJSPINYROLL_GET_7F(&this->dyna.actor) == OBJSPINYROLL_GET_7F_7F) { + func_80A1E9C4(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EB54.s") + this->dyna.actor.world.rot.y = 0; + func_80A1DFA0(this); + this->unk_4A4 = D_80A1F1C4[OBJSPINYROLL_GET_380(thisx)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EC24.s") + path = &globalCtx->setupPathList[OBJSPINYROLL_GET_7F(&this->dyna.actor)]; + points = Lib_SegmentedToVirtual(path->points); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1EC38.s") + sp34 = &points[0]; + sp30 = &points[1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1ECC0.s") + Math_Vec3s_ToVec3f(&this->unk_4AC[0], sp34); + Math_Vec3s_ToVec3f(&this->unk_4AC[1], sp30); + Math_Vec3f_Copy(&this->dyna.actor.world.pos, &this->unk_4AC[0]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/func_80A1ECD4.s") + if ((sp34->x == sp30->x) && (sp34->y != sp30->y) && (sp34->z == sp30->z)) { + this->unk_49C = true; + } else if (((sp34->x != sp30->x) && (sp34->y == sp30->y) && (sp34->z == sp30->z)) || + ((sp34->x == sp30->x) && (sp34->y == sp30->y) && (sp34->z != sp30->z))) { + this->unk_49C = false; + } else { + Actor_MarkForDeath(&this->dyna.actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/ObjSpinyroll_Update.s") + func_80A1DE58(this); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + func_80A1EAAC(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Spinyroll/ObjSpinyroll_Draw.s") +void ObjSpinyroll_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSpinyroll* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyTris(globalCtx, &this->collider); +} + +void func_80A1E9C4(ObjSpinyroll* this) { + this->dyna.actor.speedXZ = 0.0f; + this->actionFunc = func_80A1E9E0; +} + +void func_80A1E9E0(ObjSpinyroll* this, GlobalContext* globalCtx) { + this->unk_4DA += 0x6E; + if (this->unk_4DA > 0xFA0) { + this->unk_4DA = 0xFA0; + } +} + +void func_80A1EA10(ObjSpinyroll* this) { + this->actionFunc = func_80A1EA4C; + this->unk_4E2 = D_80A1F1E4[OBJSPINYROLL_GET_1C00(&this->dyna.actor)]; + this->dyna.actor.speedXZ = 0.0f; +} + +void func_80A1EA4C(ObjSpinyroll* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->unk_4DA, 0, this->unk_4DE)) { + if (this->unk_4E2 > 0) { + this->unk_4E2--; + if (this->unk_4E2 <= 0) { + func_80A1EAAC(this); + } + } + } +} + +void func_80A1EAAC(ObjSpinyroll* this) { + this->actionFunc = func_80A1EAE0; + this->unk_4DC = D_80A1F20C[this->unk_4A8]; + this->dyna.actor.speedXZ = 0.0f; +} + +void func_80A1EAE0(ObjSpinyroll* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->unk_4DA, this->unk_4DC, 0x6E)) { + if (!this->unk_49C) { + func_80A1EB40(this); + } else { + func_80A1ECC0(this); + } + } +} + +void func_80A1EB40(ObjSpinyroll* this) { + this->actionFunc = func_80A1EB54; +} + +void func_80A1EB54(ObjSpinyroll* this, GlobalContext* globalCtx) { + s32 sp24 = func_80A1DEB8(this); + + if (func_80A1E2D8(this, globalCtx, 1)) { + if (func_80A1E694(this, globalCtx) != NULL) { + func_80A1DCCC(this); + this->unk_4DE = 0x7D0; + func_80A1EC24(this); + } else { + func_80A1DE84(this); + func_80A1DCCC(this); + this->unk_4DE = 0x7D0; + func_80A1EA10(this); + } + } else if (sp24 != 0) { + func_80A1DE84(this); + func_80A1DCCC(this); + this->unk_4DE = 0x78; + func_80A1EA10(this); + } +} + +void func_80A1EC24(ObjSpinyroll* this) { + this->actionFunc = func_80A1EC38; +} + +void func_80A1EC38(ObjSpinyroll* this, GlobalContext* globalCtx) { + s32 sp24 = true; + + Math_ScaledStepToS(&this->unk_4DA, 0, this->unk_4DE); + + if (func_80A1E2D8(this, globalCtx, 0) && func_80A1E6D4(this, globalCtx)) { + sp24 = false; + } + + if (sp24) { + func_80A1DE84(this); + func_80A1EA10(this); + } +} + +void func_80A1ECC0(ObjSpinyroll* this) { + this->actionFunc = func_80A1ECD4; +} + +void func_80A1ECD4(ObjSpinyroll* this, GlobalContext* globalCtx) { + s32 sp24 = func_80A1DEB8(this); + + if (func_80A1E648(this, globalCtx, 1)) { + func_80A1DE84(this); + func_80A1DCCC(this); + this->unk_4DE = 0x7D0; + func_80A1EA10(this); + } else if (sp24) { + func_80A1DE84(this); + func_80A1DCCC(this); + this->unk_4DE = 0x78; + func_80A1EA10(this); + } +} + +void ObjSpinyroll_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjSpinyroll* this = THIS; + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + func_80A1DCCC(this); + } + + this->actionFunc(this, globalCtx); + + this->unk_4E0 += this->unk_4DA; + func_80A1DC5C(this); + func_80A1DB2C(thisx); + + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjSpinyroll_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSpinyroll* this = THIS; + f32 temp_f26; + f32 temp_f28; + s32 temp_s1 = OBJSPINYROLL_GET_C000(&this->dyna.actor); + s32 phi_s4; + f32 phi_f22; + f32 phi_f24; + s32 i; + f32 temp_f30; + Vec3s sp84; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + temp_f26 = Math_CosS(this->dyna.actor.shape.rot.y) * 120.0f; + temp_f28 = Math_SinS(this->dyna.actor.shape.rot.y) * -120.0f; + temp_f30 = this->dyna.actor.world.pos.y + this->unk_4D0; + + if (temp_s1 == OBJSPINYROLL_GET_C000_0) { + phi_s4 = 1; + phi_f22 = this->dyna.actor.world.pos.x; + phi_f24 = this->dyna.actor.world.pos.z; + } else if (temp_s1 == OBJSPINYROLL_GET_C000_1) { + phi_s4 = 2; + phi_f22 = this->dyna.actor.world.pos.x - (temp_f26 * 0.5f); + phi_f24 = this->dyna.actor.world.pos.z - (temp_f28 * 0.5f); + } else { + phi_s4 = 4; + phi_f22 = this->dyna.actor.world.pos.x - (temp_f26 * 1.5f); + phi_f24 = this->dyna.actor.world.pos.z - (temp_f28 * 1.5f); + } + + sp84.x = this->dyna.actor.shape.rot.x + this->unk_4E0; + sp84.y = this->dyna.actor.shape.rot.y; + sp84.z = this->dyna.actor.shape.rot.z; + + for (i = 0; i < phi_s4; i++) { + Matrix_SetTranslateRotateYXZ(phi_f22, temp_f30, phi_f24, &sp84); + Matrix_Scale(0.1f, 0.1f, 0.1f, 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_spinyroll_DL_000460); + + phi_f22 += temp_f26; + phi_f24 += temp_f28; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.h b/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.h index b06064316..b35627b13 100644 --- a/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.h +++ b/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.h @@ -6,12 +6,54 @@ struct ObjSpinyroll; typedef void (*ObjSpinyrollActionFunc)(struct ObjSpinyroll*, GlobalContext*); +typedef s32 (*ObjSpinyrollColFunc)(CollisionContext*, f32*, CollisionPoly**, s32*, Vec3f*, struct ObjSpinyroll*); + +#define OBJSPINYROLL_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJSPINYROLL_GET_380(thisx) (((thisx)->params >> 7) & 7) +#define OBJSPINYROLL_GET_1C00(thisx) (((thisx)->params >> 0xA) & 7) +#define OBJSPINYROLL_GET_C000(thisx) (((thisx)->params >> 0xE) & 3) + +#define OBJSPINYROLL_GET_7F_7F 0x7F +#define OBJSPINYROLL_GET_C000_0 0 +#define OBJSPINYROLL_GET_C000_1 1 + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ CollisionPoly* unk_04; + /* 0x08 */ s32 bgId; +} ObjSpinyrollSubStruct; // size = 0xC + +typedef struct { + /* 0x00 */ ObjSpinyrollSubStruct unk_00[10]; +} ObjSpinyrollStruct; // size = 0x78 + +typedef struct { + /* 0x00 */ ObjSpinyrollStruct unk_00[2]; + /* 0xF0 */ ObjSpinyrollStruct* unk_F0; + /* 0xF4 */ s32 unk_F4; +} ObjSpinyrollStruct2; // size = 0xF8? typedef struct ObjSpinyroll { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x35C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderTris collider; + /* 0x017C */ ColliderTrisElement colliderElements[6]; + /* 0x03A4 */ ObjSpinyrollStruct2 unk_3A4; + ///* 0x0494 */ ObjSpinyrollStruct* unk_494; // alternative testing + ///* 0x0498 */ s32 unk_498; + /* 0x049C */ s32 unk_49C; /* 0x04A0 */ ObjSpinyrollActionFunc actionFunc; - /* 0x04A4 */ char unk_4A4[0x40]; + /* 0x04A4 */ f32 unk_4A4; + /* 0x04A8 */ s32 unk_4A8; + /* 0x04AC */ Vec3f unk_4AC[2]; + /* 0x04C4 */ Vec3f unk_4C4; + /* 0x04D0 */ f32 unk_4D0; + /* 0x04D4 */ f32 unk_4D4; + /* 0x04D8 */ s16 unk_4D8; + /* 0x04DA */ s16 unk_4DA; + /* 0x04DC */ s16 unk_4DC; + /* 0x04DE */ s16 unk_4DE; + /* 0x04E0 */ s16 unk_4E0; + /* 0x04E2 */ s16 unk_4E2; } ObjSpinyroll; // size = 0x4E4 extern const ActorInit Obj_Spinyroll_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c index 79077e7d2..8b61f265b 100644 --- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c +++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.c @@ -1,15 +1,75 @@ -#include "z_obj_switch.h" +/* + * File: z_obj_switch.c + * Overlay: ovl_Obj_Switch + * Description: Floor and Eye Switches + */ -#define FLAGS 0x00000010 +#include "z_obj_switch.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjSwitch*)thisx) +#define COS_OF_5_PI_DIV_8 -0.38268343f + void ObjSwitch_Init(Actor* thisx, GlobalContext* globalCtx); void ObjSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSwitch_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSwitch_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObjSwitch_FloorSwitchUpInit(ObjSwitch* this); +void ObjSwitch_FloorSwitchPushDownInit(ObjSwitch* this); +void ObjSwitch_FloorSwitchDownInit(ObjSwitch* this); +void ObjSwitch_FloorSwitchRiseUpInit(ObjSwitch* this); +void ObjSwitch_EyeSwitchFrozenInit(ObjSwitch* this); +void ObjSwitch_EyeSwitchOpenInit(ObjSwitch* this); +void ObjSwitch_EyeSwitchClosingInit(ObjSwitch* this); +void ObjSwitch_EyeSwitchClosedInit(ObjSwitch* this); +void ObjSwitch_EyeSwitchOpeningInit(ObjSwitch* this); +void ObjSwitch_CrystalSwitchOffInit(ObjSwitch* this); +void ObjSwitch_CrystalSwitchTurnOnInit(ObjSwitch* this); +void ObjSwitch_CrystalSwitchOnInit(ObjSwitch* this); +void ObjSwitch_CrystalSwitchTurnOffInit(ObjSwitch* this); +void ObjSwitch_LargeFloorSwitchUpInit(ObjSwitch* this); +void ObjSwitch_LargeFloorSwitchPushDownInit(ObjSwitch* this); +void ObjSwitch_LargeFloorSwitchDownInit(ObjSwitch* this); +void ObjSwitch_LargeFloorSwitchRiseUpInit(ObjSwitch* this); + +void ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_TryPlayCutscene(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_FloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_FloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_FloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_FloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_EyeSwitchUnfrozen(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_EyeSwitchOpen(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_EyeSwitchClosing(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_EyeSwitchClosed(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_EyeSwitchOpening(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_CrystalSwitchOff(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_CrystalSwitchTurnOn(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_CrystalSwitchOn(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_CrystalSwitchTurnOff(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_LargeFloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_LargeFloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_LargeFloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_LargeFloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx); + +void ObjSwitch_DrawFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_DrawRustyFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_DrawVisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_DrawInvisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_DrawEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx); +void ObjSwitch_DrawCrystalSwitch(ObjSwitch* this, GlobalContext* globalCtx); + +static TexturePtr sEyeSwitchTextures[][4] = { + { gEyeSwitchGoldOpenTex, gEyeSwitchGoldOpeningTex, gEyeSwitchGoldClosingTex, gEyeSwitchGoldClosedTex }, + { gEyeSwitchSilverOpenTex, gEyeSwitchSilverHalfTex, gEyeSwitchSilverClosedTex, gEyeSwitchSilverClosedTex }, +}; + +static s32 sIsSegmentTableInit = false; + const ActorInit Obj_Switch_InitVars = { ACTOR_OBJ_SWITCH, ACTORCAT_SWITCH, @@ -22,183 +82,970 @@ const ActorInit Obj_Switch_InitVars = { (ActorFunc)ObjSwitch_Draw, }; -// static ColliderTrisElementInit sTrisElementsInit[2] = { -static ColliderTrisElementInit D_8093CCD4[2] = { +static f32 sHeights[] = { 10.0f, 10.0f, 0.0f, 30.0f, 30.0f, 15.0f }; + +static f32 sScale[] = { 0.123f, 0.123f, 0.1f, 0.118f, 0.118f, 0.248f }; + +static ColliderTrisElementInit sRustyFloorTrisElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000400, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000400, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { -20.0f, 19.0f, -20.0f }, { -20.0f, 19.0f, 20.0f }, { 20.0f, 19.0f, 20.0f } } }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000400, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000400, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 20.0f, 19.0f, 20.0f }, { 20.0f, 19.0f, -20.0f }, { -20.0f, 19.0f, -20.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_8093CD4C = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 2, D_8093CCD4, // sTrisElementsInit, +static ColliderTrisInit sRustyFloorTrisInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + ARRAY_COUNT(sRustyFloorTrisElementsInit), + sRustyFloorTrisElementsInit, }; -// static ColliderTrisElementInit sTrisElementsInit[2] = { -static ColliderTrisElementInit D_8093CD5C[2] = { +static ColliderTrisElementInit sEyeSwitchTrisElementsInit[2] = { { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00003820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 23.0f, 8.5f }, { -23.0f, 0.0f, 8.5f }, { 0.0f, -23.0f, 8.5f } } }, }, { - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00003820, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00003820, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 23.0f, 8.5f }, { 0.0f, -23.0f, 8.5f }, { 23.0f, 0.0f, 8.5f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_8093CDD4 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_TRIS, }, - 2, D_8093CD5C, // sTrisElementsInit, +static ColliderTrisInit sEyeSwitchTrisInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_TRIS, + }, + ARRAY_COUNT(sEyeSwitchTrisElementsInit), + sEyeSwitchTrisElementsInit, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8093CDE4[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x01CBFFBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x01CBFFBE, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 300, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8093CE08 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 1, D_8093CDE4, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + ARRAY_COUNT(sJntSphElementsInit), + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8093CE18[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif +static Color_RGB8 sSakonHideoutColor[2] = { { 250, 90, 60 }, { 255, 255, 255 } }; -extern ColliderTrisElementInit D_8093CCD4[2]; -extern ColliderTrisInit D_8093CD4C; -extern ColliderTrisElementInit D_8093CD5C[2]; -extern ColliderTrisInit D_8093CDD4; -extern ColliderJntSphElementInit D_8093CDE4[1]; -extern ColliderJntSphInit D_8093CE08; -extern InitChainEntry D_8093CE18[]; +static Gfx* sFloorSwitchDL[] = { gFloorSwitch1DL, gFloorSwitch3DL, gFloorSwitch2DL, gFloorSwitch2DL, gFloorSwitch1DL }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093ABD0.s") +static Gfx* sEyeSwitchDL[] = { gEyeSwitchGoldDL, gEyeSwitchSilverDL }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AC6C.s") +static AnimatedMaterial* sCrystalSwitchAnimatedMat; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093ADA8.s") +void ObjSwitch_InitJntSphCollider(ObjSwitch* this, GlobalContext* globalCtx, ColliderJntSphInit* init) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE1C.s") + Collider_InitJntSph(globalCtx, &this->colliderJntSph); + Collider_SetJntSph(globalCtx, &this->colliderJntSph, &this->dyna.actor, init, this->colliderJntSphElements); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y + + (this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y), + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(this->dyna.actor.scale.x, this->dyna.actor.scale.y, this->dyna.actor.scale.z, MTXMODE_APPLY); + Collider_UpdateSpheres(0, &this->colliderJntSph); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE74.s") +void ObjSwitch_InitTrisCollider(ObjSwitch* this, GlobalContext* globalCtx, ColliderTrisInit* init) { + s32 pad; + s32 i; + s32 j; + Vec3f vtx[3]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AE88.s") + Collider_InitTris(globalCtx, &this->colliderTris); + Collider_SetTris(globalCtx, &this->colliderTris, &this->dyna.actor, init, this->colliderTrisElements); + Matrix_Push(); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, + this->dyna.actor.world.pos.y + + this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AEC4.s") + for (i = 0; i < ARRAY_COUNT(this->colliderTrisElements); i++) { + if (this) {} + for (j = 0; j < ARRAY_COUNT(vtx); j++) { + Matrix_MultVec3f(&init->elements[i].dim.vtx[j], &vtx[j]); + } + Collider_SetTrisVertices(&this->colliderTris, i, &vtx[0], &vtx[1], &vtx[2]); + } + Matrix_Pop(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AEF0.s") +Actor* ObjSwitch_SpawnIce(ObjSwitch* this, GlobalContext* globalCtx) { + return Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_OBJ_ICE_POLY, + this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y - 25.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, 0xFF32); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AF1C.s") +void ObjSwitch_SetSwitchFlagState(ObjSwitch* this, GlobalContext* globalCtx, s32 setFlag) { + if (setFlag) { + s32 flag = OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093AF54.s") + Flags_SetSwitch(globalCtx, flag); + } else { + s32 flag = OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Init.s") + Flags_UnsetSwitch(globalCtx, flag); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Destroy.s") +void ObjSwitch_CrystalUpdateTimer(ObjSwitch* this) { + this->crystalAnimTimer++; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B648.s") +void ObjSwitch_StopCutscene(ObjSwitch* this) { + if (this->isPlayingCutscene) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + this->isPlayingCutscene = false; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B668.s") +void ObjSwitch_PlayFootSwitchSfx(ObjSwitch* this) { + if (this->sfxTimer <= 0) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_FOOT_SWITCH); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B6F4.s") +void ObjSwitch_PlayDiamondSwitchSfx(ObjSwitch* this) { + if (this->sfxTimer <= 0) { + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_DIAMOND_SWITCH); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B710.s") +void ObjSwitch_SetFloorSwitchSnapPlayerState(ObjSwitch* this, s32 state) { + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + this->floorSwitchPlayerSnapState = state; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B92C.s") +void ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad; + Player* player; + f32 centerDisplacement; + s16 yaw; + f32 cos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B940.s") + if (globalCtx->actorCtx.unk5 & 0x80) { + player = GET_PLAYER(globalCtx); + // compute yawTowardsPlayer relative to model space + yaw = BINANG_SUB(this->dyna.actor.yawTowardsPlayer, this->dyna.actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B9C0.s") + // clamps yaw to the range -45 to 45 degrees, such that 0 degrees follows along the apothem + yaw += 0x2000; + yaw &= 0x3FFF; + yaw -= 0x2000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093B9E4.s") + // set centerDisplacement to the length of the apothem for the floor switch square + // only OBJSWITCH_TYPE_FLOOR and OBJSWITCH_TYPE_FLOOR_LARGE are supported + centerDisplacement = OBJ_SWITCH_GET_TYPE(&this->dyna.actor) == OBJSWITCH_TYPE_FLOOR ? 24.0f : 48.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BB5C.s") + cos = Math_CosS(yaw); + if (fabsf(cos) > 0.01f) { + // compute how far to displace the player so that the player is touching an edge + centerDisplacement /= cos; + // if the player is already inside the square, don't move them + if (centerDisplacement < this->dyna.actor.xzDistToPlayer) { + player->actor.world.pos.x = + Math_SinS(this->dyna.actor.yawTowardsPlayer) * centerDisplacement + this->dyna.actor.world.pos.x; + player->actor.world.pos.z = + Math_CosS(this->dyna.actor.yawTowardsPlayer) * centerDisplacement + this->dyna.actor.world.pos.z; + } + player->linearVelocity = 0.0f; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BB70.s") +void ObjSwitch_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + s32 type; + u32 isSwitchFlagSet; + ObjSwitch* this = THIS; + s32 pad2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BBD0.s") + isSwitchFlagSet = Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor)); + type = OBJ_SWITCH_GET_TYPE(&this->dyna.actor); + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + Actor_SetScale(&this->dyna.actor, sScale[type]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BCC8.s") + if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY || type == OBJSWITCH_TYPE_FLOOR_LARGE) { + if (type == OBJSWITCH_TYPE_FLOOR_LARGE) { + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 1.9f; + } else { + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y + 1.0f; + } + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gFloorSwitchCol); + } + if (type == OBJSWITCH_TYPE_FLOOR) { + if (globalCtx->sceneNum == SCENE_SECOM) { + this->floorSwitchUpScale = 33.0f / 200.0f / 3.0f; + this->floorSwitchDownScale = 33.0f / 2000.0f / 3.0f; + } else { + this->floorSwitchUpScale = 33.0f / 200.0f; + this->floorSwitchDownScale = 33.0f / 2000.0f; + } + } + if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_LARGE) { + if (globalCtx->sceneNum == SCENE_SECOM) { + Color_RGB8* color = &sSakonHideoutColor[OBJ_SWITCH_GET_COLOR_ID(&this->dyna.actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BCDC.s") + this->color.r = color->r; + this->color.g = color->g; + this->color.b = color->b; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.world.rot.z = 0; + } else { + this->color.r = 255; + this->color.g = 255; + this->color.b = 255; + } + } + Actor_SetFocus(&this->dyna.actor, sHeights[type]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BD34.s") + if (type == OBJSWITCH_TYPE_FLOOR_RUSTY) { + ObjSwitch_InitTrisCollider(this, globalCtx, &sRustyFloorTrisInit); + } else if (type == OBJSWITCH_TYPE_EYE) { + ObjSwitch_InitTrisCollider(this, globalCtx, &sEyeSwitchTrisInit); + } else if (type == OBJSWITCH_TYPE_CRYSTAL || type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) { + ObjSwitch_InitJntSphCollider(this, globalCtx, &sJntSphInit); + } + if (type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) { + this->dyna.actor.targetMode = 4; + this->dyna.actor.flags |= 1; + } + this->dyna.actor.colChkInfo.mass = MASS_IMMOVABLE; + if (OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) { + if (ObjSwitch_SpawnIce(this, globalCtx) == NULL) { + OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor); + } + this->sfxTimer = 0; + } else { + this->sfxTimer = 10; + } + if (OBJ_SWITCH_IS_INVISIBLE(&this->dyna.actor)) { + this->dyna.actor.flags |= 0x80; + } + if (type == OBJSWITCH_TYPE_EYE) { + if (sIsSegmentTableInit == false) { + s32 i; + s32 j; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BD4C.s") + sIsSegmentTableInit = true; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BDAC.s") + for (i = 0; i < ARRAY_COUNT(sEyeSwitchTextures); i++) { + for (j = 0; j < ARRAY_COUNT(*sEyeSwitchTextures); j++) { + sEyeSwitchTextures[i][j] = Lib_SegmentedToVirtual(sEyeSwitchTextures[i][j]); + } + } + } + } + if (type == OBJSWITCH_TYPE_CRYSTAL) { + sCrystalSwitchAnimatedMat = Lib_SegmentedToVirtual(&gCrystalSwitchAnimatedMat); + } + if (OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) { + ObjSwitch_EyeSwitchFrozenInit(this); + } else if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY) { + if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET_INVERTED) { + if (isSwitchFlagSet) { + ObjSwitch_FloorSwitchUpInit(this); + } else { + ObjSwitch_FloorSwitchDownInit(this); + } + } else { + if (isSwitchFlagSet) { + ObjSwitch_FloorSwitchDownInit(this); + } else { + ObjSwitch_FloorSwitchUpInit(this); + } + } + } else if (type == OBJSWITCH_TYPE_EYE) { + if (isSwitchFlagSet) { + ObjSwitch_EyeSwitchClosedInit(this); + } else { + ObjSwitch_EyeSwitchOpenInit(this); + } + } else if (type == OBJSWITCH_TYPE_CRYSTAL || type == OBJSWITCH_TYPE_CRYSTAL_TARGETABLE) { + if (isSwitchFlagSet) { + ObjSwitch_CrystalSwitchOnInit(this); + } else { + ObjSwitch_CrystalSwitchOffInit(this); + } + } else if (type == OBJSWITCH_TYPE_FLOOR_LARGE) { + if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET_INVERTED) { + if (isSwitchFlagSet) { + ObjSwitch_LargeFloorSwitchUpInit(this); + } else { + ObjSwitch_LargeFloorSwitchDownInit(this); + } + } else { + if (isSwitchFlagSet) { + ObjSwitch_LargeFloorSwitchDownInit(this); + } else { + ObjSwitch_LargeFloorSwitchUpInit(this); + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BDC0.s") +void ObjSwitch_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSwitch* this = THIS; + s32 type = OBJ_SWITCH_GET_TYPE(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BE10.s") + if (type == OBJSWITCH_TYPE_FLOOR || type == OBJSWITCH_TYPE_FLOOR_RUSTY || type == OBJSWITCH_TYPE_FLOOR_LARGE) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } + switch (type) { + case OBJSWITCH_TYPE_FLOOR_RUSTY: + case OBJSWITCH_TYPE_EYE: + Collider_DestroyTris(globalCtx, &this->colliderTris); + break; + case OBJSWITCH_TYPE_CRYSTAL: + case OBJSWITCH_TYPE_CRYSTAL_TARGETABLE: + Collider_DestroyJntSph(globalCtx, &this->colliderJntSph); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BE2C.s") +void ObjSwitch_TryPlayCutsceneInit(ObjSwitch* this, GlobalContext* globalCtx, ObjSwitchSetupActionFunc actionFunc, + s32 nextSwitchFlagState) { + this->setupFunc = actionFunc; + this->nextSwitchFlagState = nextSwitchFlagState; + this->actionFunc = ObjSwitch_TryPlayCutscene; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BEF0.s") +void ObjSwitch_TryPlayCutscene(ObjSwitch* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + ObjSwitch_SetSwitchFlagState(this, globalCtx, this->nextSwitchFlagState); + if (this->floorSwitchPlayerSnapState == 1) { + this->floorSwitchPlayerSnapState = 2; + } + this->isPlayingCutscene = true; + this->setupFunc(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF04.s") +void ObjSwitch_FloorSwitchUpInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_FloorSwitchUp; + this->dyna.actor.scale.y = this->floorSwitchUpScale; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF50.s") +void ObjSwitch_FloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093BF70.s") + if (OBJ_SWITCH_GET_TYPE(&this->dyna.actor) == OBJSWITCH_TYPE_FLOOR_RUSTY) { + if (this->colliderTris.base.acFlags & AC_HIT) { + this->colliderTris.base.acFlags &= ~AT_HIT; + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + } + } else { + switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) { + case OBJSWITCH_SUBTYPE_ONCE: + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true); + } + break; + case OBJSWITCH_SUBTYPE_SYNC: + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true); + } else if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + ObjSwitch_FloorSwitchPushDownInit(this); + } + break; + case OBJSWITCH_SUBTYPE_TOGGLE: + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + s32 isSwitchFlagNotSet = + Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor)) ? false : true; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C0A4.s") + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, + isSwitchFlagNotSet); + } + break; + case OBJSWITCH_SUBTYPE_RESET: + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchPushDownInit, true); + } + break; + case OBJSWITCH_SUBTYPE_RESET_INVERTED: + if (DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 2); + ObjSwitch_SetSwitchFlagState(this, globalCtx, false); + ObjSwitch_FloorSwitchPushDownInit(this); + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C0B8.s") +void ObjSwitch_FloorSwitchPushDownInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_FloorSwitchPushDown; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C138.s") +void ObjSwitch_FloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y -= 0.0495f; + if (this->dyna.actor.scale.y <= this->floorSwitchDownScale) { + ObjSwitch_PlayFootSwitchSfx(this); + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + ObjSwitch_StopCutscene(this); + ObjSwitch_FloorSwitchDownInit(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C15C.s") +void ObjSwitch_FloorSwitchDownInit(ObjSwitch* this) { + this->floorSwitchReleaseTimer = 6; + this->actionFunc = ObjSwitch_FloorSwitchDown; + this->dyna.actor.scale.y = this->floorSwitchDownScale; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C23C.s") +void ObjSwitch_FloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad; + u32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C250.s") + switch (subType) { + case OBJSWITCH_SUBTYPE_ONCE: + case OBJSWITCH_SUBTYPE_SYNC: + if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + if (globalCtx->sceneNum == SCENE_SECOM && DynaPolyActor_IsInSwitchPressedState(&this->dyna)) { + ObjSwitch_SetSwitchFlagState(this, globalCtx, true); + } else { + ObjSwitch_FloorSwitchRiseUpInit(this); + } + } + break; + case OBJSWITCH_SUBTYPE_TOGGLE: + case OBJSWITCH_SUBTYPE_RESET: + case OBJSWITCH_SUBTYPE_RESET_INVERTED: + if (!DynaPolyActor_IsInSwitchPressedState(&this->dyna) && + (Player_InCsMode(&globalCtx->state) == 0 || globalCtx->sceneNum == SCENE_SECOM)) { + if (this->floorSwitchReleaseTimer <= 0) { + if (subType == OBJSWITCH_SUBTYPE_RESET) { + ObjSwitch_SetSwitchFlagState(this, globalCtx, false); + ObjSwitch_FloorSwitchRiseUpInit(this); + } else if (subType == OBJSWITCH_SUBTYPE_RESET_INVERTED) { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_FloorSwitchRiseUpInit, true); + } else { + ObjSwitch_FloorSwitchRiseUpInit(this); + } + } + } else { + if (globalCtx->sceneNum == SCENE_SECOM) { + this->floorSwitchReleaseTimer = 2; + } else { + this->floorSwitchReleaseTimer = 6; + } + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C2B4.s") +void ObjSwitch_FloorSwitchRiseUpInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_FloorSwitchRiseUp; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C2D4.s") +void ObjSwitch_FloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y += 0.0495f; + if (this->floorSwitchUpScale <= this->dyna.actor.scale.y) { + ObjSwitch_PlayFootSwitchSfx(this); + ObjSwitch_StopCutscene(this); + ObjSwitch_FloorSwitchUpInit(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C3C8.s") +s32 ObjSwitch_IsEyeSwitchHit(ObjSwitch* this) { + Actor* acActor; + Actor* actor = &this->dyna.actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C3DC.s") + if ((this->colliderTris.base.acFlags & AC_HIT) && !(this->collisionFlags & AC_HIT)) { + acActor = this->colliderTris.base.ac; + if (acActor != NULL) { + Vec3f sp2C; + Vec3f sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C460.s") + Matrix_Push(); + Matrix_RotateYS(acActor->world.rot.y, MTXMODE_NEW); + Matrix_RotateXS(acActor->world.rot.x, MTXMODE_APPLY); + Matrix_MultVecZ(1.0f, &sp2C); + Matrix_RotateYS(actor->shape.rot.y, MTXMODE_NEW); + Matrix_RotateXS(actor->shape.rot.x, MTXMODE_APPLY); + Matrix_RotateZS(actor->shape.rot.z, MTXMODE_APPLY); + Matrix_MultVecZ(1.0f, &sp20); + Matrix_Pop(); + if ((Math3D_Parallel(&sp2C, &sp20) < COS_OF_5_PI_DIV_8)) { + return true; + } + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C488.s") +void ObjSwitch_EyeSwitchFrozenInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_EyeSwitchUnfrozen; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C584.s") +void ObjSwitch_EyeSwitchUnfrozen(ObjSwitch* this, GlobalContext* globalCtx) { + if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + ObjSwitch_EyeSwitchClosedInit(this); + } else { + ObjSwitch_EyeSwitchOpenInit(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C598.s") +void ObjSwitch_EyeSwitchOpenInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_EyeSwitchOpen; + this->eyeTexIndex = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Update.s") +void ObjSwitch_EyeSwitchOpen(ObjSwitch* this, GlobalContext* globalCtx) { + if (ObjSwitch_IsEyeSwitchHit(this) || OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) { + OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_EyeSwitchClosingInit, true); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C778.s") +void ObjSwitch_EyeSwitchClosingInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_EyeSwitchClosing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C888.s") +void ObjSwitch_EyeSwitchClosing(ObjSwitch* this, GlobalContext* globalCtx) { + this->eyeTexIndex++; + if (this->eyeTexIndex >= 3) { + ObjSwitch_StopCutscene(this); + ObjSwitch_PlayFootSwitchSfx(this); + ObjSwitch_EyeSwitchClosedInit(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C8B8.s") +void ObjSwitch_EyeSwitchClosedInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_EyeSwitchClosed; + this->eyeTexIndex = 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093C99C.s") +void ObjSwitch_EyeSwitchClosed(ObjSwitch* this, GlobalContext* globalCtx) { + switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) { + case OBJSWITCH_SUBTYPE_ONCE: + if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor); + ObjSwitch_EyeSwitchOpeningInit(this); + } + break; + case OBJSWITCH_SUBTYPE_TOGGLE: + if (ObjSwitch_IsEyeSwitchHit(this) || OBJ_SWITCH_IS_FROZEN(&this->dyna.actor)) { + OBJ_SWITCH_UNSET_FROZEN(&this->dyna.actor); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_EyeSwitchOpeningInit, false); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093CA80.s") +void ObjSwitch_EyeSwitchOpeningInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_EyeSwitchOpening; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/func_8093CAC4.s") +void ObjSwitch_EyeSwitchOpening(ObjSwitch* this, GlobalContext* globalCtx) { + this->eyeTexIndex--; + if (this->eyeTexIndex <= 0) { + ObjSwitch_StopCutscene(this); + ObjSwitch_PlayFootSwitchSfx(this); + ObjSwitch_EyeSwitchOpenInit(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Switch/ObjSwitch_Draw.s") +void ObjSwitch_CrystalSwitchOffInit(ObjSwitch* this) { + this->color.r = 0; + this->color.g = 0; + this->color.b = 0; + this->actionFunc = ObjSwitch_CrystalSwitchOff; +} + +void ObjSwitch_CrystalSwitchOff(ObjSwitch* this, GlobalContext* globalCtx) { + s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0; + s32 canActivate = switchHit && !(this->collisionFlags & AC_HIT) && (this->disableCrystalSwitchTimer <= 0); + + if (switchHit) { + this->disableCrystalSwitchTimer = 10; + } + switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) { + case OBJSWITCH_SUBTYPE_ONCE: + if (canActivate) { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true); + } + break; + case OBJSWITCH_SUBTYPE_SYNC: + if (canActivate) { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true); + + } else if (Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + this->disableCrystalSwitchTimer = 10; + ObjSwitch_CrystalSwitchTurnOnInit(this); + } + break; + case OBJSWITCH_SUBTYPE_TOGGLE: + if (canActivate) { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOnInit, true); + } + ObjSwitch_CrystalUpdateTimer(this); + break; + } +} + +void ObjSwitch_CrystalSwitchTurnOnInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_CrystalSwitchTurnOn; +} + +void ObjSwitch_CrystalSwitchTurnOn(ObjSwitch* this, GlobalContext* globalCtx) { + s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0; + s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); + + if (switchHit) { + this->disableCrystalSwitchTimer = 10; + } + ObjSwitch_StopCutscene(this); + if (subType == OBJSWITCH_SUBTYPE_TOGGLE) { + ObjSwitch_CrystalUpdateTimer(this); + } + ObjSwitch_PlayDiamondSwitchSfx(this); + ObjSwitch_CrystalSwitchOnInit(this); +} + +void ObjSwitch_CrystalSwitchOnInit(ObjSwitch* this) { + this->color.r = 255; + this->color.g = 255; + this->color.b = 255; + this->actionFunc = ObjSwitch_CrystalSwitchOn; +} + +void ObjSwitch_CrystalSwitchOn(ObjSwitch* this, GlobalContext* globalCtx) { + s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0; + s32 canActivate = switchHit && !(this->collisionFlags & AC_HIT) && (this->disableCrystalSwitchTimer <= 0); + + if (switchHit) { + this->disableCrystalSwitchTimer = 10; + } + switch (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)) { + case OBJSWITCH_SUBTYPE_ONCE: + case OBJSWITCH_SUBTYPE_SYNC: + if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + this->disableCrystalSwitchTimer = 10; + ObjSwitch_CrystalSwitchTurnOffInit(this); + } + break; + case OBJSWITCH_SUBTYPE_TOGGLE: + if (canActivate) { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_CrystalSwitchTurnOffInit, false); + } + } + ObjSwitch_CrystalUpdateTimer(this); +} + +void ObjSwitch_CrystalSwitchTurnOffInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_CrystalSwitchTurnOff; +} + +void ObjSwitch_CrystalSwitchTurnOff(ObjSwitch* this, GlobalContext* globalCtx) { + s32 switchHit = (this->colliderJntSph.base.acFlags & AC_HIT) != 0; + + if (switchHit) { + this->disableCrystalSwitchTimer = 10; + } + ObjSwitch_StopCutscene(this); + ObjSwitch_CrystalUpdateTimer(this); + ObjSwitch_PlayDiamondSwitchSfx(this); + ObjSwitch_CrystalSwitchOffInit(this); +} + +void ObjSwitch_LargeFloorSwitchUpInit(ObjSwitch* this) { + this->dyna.actor.scale.y = 0.2475f; + this->actionFunc = ObjSwitch_LargeFloorSwitchUp; +} + +void ObjSwitch_LargeFloorSwitchUp(ObjSwitch* this, GlobalContext* globalCtx) { + s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); + + if (subType == OBJSWITCH_SUBTYPE_ONCE) { + if (DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchPushDownInit, true); + } + } else if (subType == OBJSWITCH_SUBTYPE_RESET) { + if (DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 1); + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchPushDownInit, true); + } + } else if (subType == OBJSWITCH_SUBTYPE_RESET_INVERTED && DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna)) { + ObjSwitch_SetFloorSwitchSnapPlayerState(this, 2); + ObjSwitch_SetSwitchFlagState(this, globalCtx, false); + ObjSwitch_LargeFloorSwitchPushDownInit(this); + } +} + +void ObjSwitch_LargeFloorSwitchPushDownInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_LargeFloorSwitchPushDown; +} + +void ObjSwitch_LargeFloorSwitchPushDown(ObjSwitch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y -= 0.074250005f; + if (this->dyna.actor.scale.y <= 33.0f / 2000.0f) { + ObjSwitch_PlayFootSwitchSfx(this); + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); + ObjSwitch_StopCutscene(this); + ObjSwitch_LargeFloorSwitchDownInit(this); + } +} + +void ObjSwitch_LargeFloorSwitchDownInit(ObjSwitch* this) { + this->dyna.actor.scale.y = 33.0f / 2000.0f; + this->floorSwitchReleaseTimer = 6; + this->actionFunc = ObjSwitch_LargeFloorSwitchDown; +} + +void ObjSwitch_LargeFloorSwitchDown(ObjSwitch* this, GlobalContext* globalCtx) { + s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); + + if (subType == OBJSWITCH_SUBTYPE_ONCE) { + if (!Flags_GetSwitch(globalCtx, OBJ_SWITCH_GET_SWITCH_FLAG(&this->dyna.actor))) { + ObjSwitch_LargeFloorSwitchRiseUpInit(this); + } + } else if (subType == OBJSWITCH_SUBTYPE_RESET || subType == OBJSWITCH_SUBTYPE_RESET_INVERTED) { + if (!DynaPolyActor_IsInHeavySwitchPressedState(&this->dyna) && !Player_InCsMode(&globalCtx->state)) { + if (this->floorSwitchReleaseTimer <= 0) { + if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_RESET) { + ObjSwitch_SetSwitchFlagState(this, globalCtx, false); + ObjSwitch_LargeFloorSwitchRiseUpInit(this); + } else { + ObjSwitch_TryPlayCutsceneInit(this, globalCtx, ObjSwitch_LargeFloorSwitchRiseUpInit, true); + } + } + } else { + this->floorSwitchReleaseTimer = 6; + } + } +} + +void ObjSwitch_LargeFloorSwitchRiseUpInit(ObjSwitch* this) { + this->actionFunc = ObjSwitch_LargeFloorSwitchRiseUp; +} + +void ObjSwitch_LargeFloorSwitchRiseUp(ObjSwitch* this, GlobalContext* globalCtx) { + this->dyna.actor.scale.y += 0.074250005f; + if (this->dyna.actor.scale.y >= 0.2475f) { + ObjSwitch_PlayFootSwitchSfx(this); + ObjSwitch_StopCutscene(this); + ObjSwitch_LargeFloorSwitchUpInit(this); + } +} + +void ObjSwitch_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjSwitch* this = THIS; + + if (this->floorSwitchReleaseTimer > 0) { + this->floorSwitchReleaseTimer--; + } + if (this->sfxTimer > 0) { + this->sfxTimer--; + } + this->actionFunc(this, globalCtx); + if (this->floorSwitchPlayerSnapState != 0) { + s32 pad; + + dummy: + ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge(this, globalCtx); + if (this->floorSwitchPlayerSnapState == 2) { + this->floorSwitchPlayerSnapState = 0; + } + } + switch (OBJ_SWITCH_GET_TYPE(&this->dyna.actor)) { + case OBJSWITCH_TYPE_FLOOR: + case OBJSWITCH_TYPE_FLOOR_RUSTY: + case OBJSWITCH_TYPE_FLOOR_LARGE: + this->collisionFlags = this->dyna.stateFlags; + break; + case OBJSWITCH_TYPE_EYE: + this->collisionFlags = this->colliderTris.base.acFlags; + this->colliderTris.base.acFlags &= ~AC_HIT; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + break; + case OBJSWITCH_TYPE_CRYSTAL: + case OBJSWITCH_TYPE_CRYSTAL_TARGETABLE: + if (!Player_InCsMode(&globalCtx->state)) { + if (this->disableCrystalSwitchTimer > 0) { + this->disableCrystalSwitchTimer--; + } + } + if (this->disableCrystalSwitchTimer == 0) { + this->colliderJntSph.base.colType = sJntSphInit.base.colType; + } else { + this->colliderJntSph.base.colType = COLTYPE_NONE; + } + this->collisionFlags = this->colliderJntSph.base.acFlags; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderJntSph.base); + } +} + +void ObjSwitch_DrawFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad[2]; + + if (OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor) == OBJSWITCH_SUBTYPE_ONCE) { + Gfx* opa; + + OPEN_DISPS(globalCtx->state.gfxCtx); + opa = POLY_OPA_DISP; + gSPDisplayList(opa++, &sSetupDL[6 * 25]); + gSPMatrix(opa++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(opa++, 0, 0x80, this->color.r, this->color.g, this->color.b, 255); + gSPDisplayList(opa++, gFloorSwitch1DL); + POLY_OPA_DISP = opa; + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + Gfx_DrawDListOpa(globalCtx, sFloorSwitchDL[OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor)]); + } +} + +void ObjSwitch_DrawRustyFloorSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + Gfx_DrawDListOpa(globalCtx, gRustyFloorSwitchDL); +} + +void ObjSwitch_DrawVisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad; + s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); + + 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); + gSPSegment(POLY_OPA_DISP++, 0x08, sEyeSwitchTextures[subType][this->eyeTexIndex]); + gSPDisplayList(POLY_OPA_DISP++, sEyeSwitchDL[subType]); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjSwitch_DrawInvisibleEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad; + s32 subType = OBJ_SWITCH_GET_SUBTYPE(&this->dyna.actor); + + 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); + gSPSegment(POLY_XLU_DISP++, 0x08, sEyeSwitchTextures[subType][this->eyeTexIndex]); + gSPDisplayList(POLY_XLU_DISP++, sEyeSwitchDL[subType]); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjSwitch_DrawEyeSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + if (OBJ_SWITCH_IS_INVISIBLE(&this->dyna.actor)) { + ObjSwitch_DrawInvisibleEyeSwitch(this, globalCtx); + } else { + ObjSwitch_DrawVisibleEyeSwitch(this, globalCtx); + } +} + +void ObjSwitch_DrawCrystalSwitch(ObjSwitch* this, GlobalContext* globalCtx) { + s32 pad[2]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_800B8118(&this->dyna.actor, globalCtx, 0); + AnimatedMat_DrawStep(globalCtx, sCrystalSwitchAnimatedMat, this->crystalAnimTimer); + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(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++, gCrystalSwitchBaseDL); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, this->color.r, this->color.g, this->color.b, 255); + gSPDisplayList(POLY_OPA_DISP++, gCrystalSwitchCoreDL); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gCrystalSwitchDiamondDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjSwitch_Draw(Actor* thisx, GlobalContext* globalCtx) { + static ObjSwitchDrawFunc drawFunc[] = { + ObjSwitch_DrawFloorSwitch, ObjSwitch_DrawRustyFloorSwitch, ObjSwitch_DrawEyeSwitch, + ObjSwitch_DrawCrystalSwitch, ObjSwitch_DrawCrystalSwitch, ObjSwitch_DrawFloorSwitch, + }; + ObjSwitch* this = THIS; + + drawFunc[OBJ_SWITCH_GET_TYPE(&this->dyna.actor)](this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h index 96b5f2bb6..42ee4207f 100644 --- a/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h +++ b/src/overlays/actors/ovl_Obj_Switch/z_obj_switch.h @@ -5,15 +5,69 @@ struct ObjSwitch; -typedef void (*ObjSwitchActionFunc)(struct ObjSwitch*, GlobalContext*); +typedef void (*ObjSwitchActionFunc)(struct ObjSwitch* this, GlobalContext* globalCtx); +typedef void (*ObjSwitchDrawFunc)(struct ObjSwitch* this, GlobalContext* globalCtx); +typedef void (*ObjSwitchSetupActionFunc)(struct ObjSwitch* this); + +typedef enum { + /* 0 */ OBJSWITCH_TYPE_FLOOR, + /* 1 */ OBJSWITCH_TYPE_FLOOR_RUSTY, // Unused, incomplete implementation + /* 2 */ OBJSWITCH_TYPE_EYE, + /* 3 */ OBJSWITCH_TYPE_CRYSTAL, + /* 4 */ OBJSWITCH_TYPE_CRYSTAL_TARGETABLE, + /* 5 */ OBJSWITCH_TYPE_FLOOR_LARGE +} ObjSwitchType; + +typedef enum { + /* 0 */ OBJSWITCH_SUBTYPE_ONCE, // Set Switch Flag when activated, stays activated + /* 1 */ OBJSWITCH_SUBTYPE_TOGGLE, // Toggle Switch Flag when activated + /* 2 */ OBJSWITCH_SUBTYPE_RESET, // Floor type only, set switch flag when pressed, unset when released + /* 3 */ OBJSWITCH_SUBTYPE_RESET_INVERTED, // Floor type only, set switch flag when not pressed, unset when pressed + /* 4 */ OBJSWITCH_SUBTYPE_SYNC // Crystal type only, syncronizes all crystal fl +} ObjSwitchSubType; + +#define OBJSWITCH_GET_33(thisx) ((thisx)->params & 0x33) +#define OBJSWITCH_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + +#define OBJSWITCH_NORMAL_BLUE 0x20 +#define OBJSWITCH_INVERSE_BLUE 0x30 typedef struct ObjSwitch { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; + /* 0x0000 */ DynaPolyActor dyna; /* 0x015C */ ObjSwitchActionFunc actionFunc; - /* 0x0160 */ char unk_160[0xF8]; + /* 0x0160 */ s16 floorSwitchReleaseTimer; + /* 0x0162 */ s16 disableCrystalSwitchTimer; + /* 0x0164 */ s8 eyeTexIndex; + /* 0x0165 */ s8 sfxTimer; + /* 0x0168 */ s32 crystalAnimTimer; + /* 0x016C */ Color_RGB8 color; + /* 0x016F */ u8 collisionFlags; + /* 0x0170 */ s8 floorSwitchPlayerSnapState; + /* 0x0171 */ s8 nextSwitchFlagState; + /* 0x0172 */ s8 isPlayingCutscene; + /* 0x0174 */ ObjSwitchSetupActionFunc setupFunc; + union { + struct { + /* 0x0178 */ ColliderJntSph colliderJntSph; + /* 0x0198 */ ColliderJntSphElement colliderJntSphElements[1]; + }; + struct { + /* 0x0178 */ ColliderTris colliderTris; + /* 0x0198 */ ColliderTrisElement colliderTrisElements[2]; + }; + }; + /* 0x0250 */ f32 floorSwitchUpScale; + /* 0x0254 */ f32 floorSwitchDownScale; } ObjSwitch; // size = 0x258 extern const ActorInit Obj_Switch_InitVars; +#define OBJ_SWITCH_GET_TYPE(thisx) ((thisx)->params&7) +#define OBJ_SWITCH_GET_SUBTYPE(thisx) ((thisx)->params >> 4 & 7) +#define OBJ_SWITCH_GET_SWITCH_FLAG(thisx) ((thisx)->params >> 8 & 0x7F) +#define OBJ_SWITCH_IS_FROZEN(thisx) ((thisx)->params >> 7 & 1) +#define OBJ_SWITCH_UNSET_FROZEN(thisx) ((thisx)->params &= ~(1 << 7)) +#define OBJ_SWITCH_IS_INVISIBLE(thisx) ((thisx)->params >> 3 & 1) +#define OBJ_SWITCH_GET_COLOR_ID(thisx) ((thisx)->home.rot.z&1) + #endif // Z_OBJ_SWITCH_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 f8c1bcd35..cea97efe9 100644 --- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c +++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_swprize.c + * Overlay: ovl_Obj_Swprize + * Description: Spawns item drop from soft soil + */ + #include "z_obj_swprize.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjSwprize*)thisx) 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 fb7074693..9001ea27a 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -5,9 +5,11 @@ */ #include "z_obj_syokudai.h" +#include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" +#include "objects/object_syokudai/object_syokudai.h" -#define FLAGS 0x00000410 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_400) #define THIS ((ObjSyokudai*)thisx) @@ -16,10 +18,6 @@ void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx); -extern Gfx D_060003A0[]; // sObjectSyokudaiTypeSwitchCausesFlameDL -extern Gfx D_06000870[]; // sObjectSyokudaiTypeNoSwitchDL -extern Gfx D_06000B90[]; // sObjectSyokudaiTypeFlameCausesSwitchDL - const ActorInit Obj_Syokudai_InitVars = { ACTOR_OBJ_SYOKUDAI, ACTORCAT_PROP, @@ -81,7 +79,11 @@ static InitChainEntry sInitChain[] = { static u8 sColTypes[] = { COLTYPE_METAL, COLTYPE_WOOD, COLTYPE_WOOD }; -static Gfx* sDLists[] = { D_060003A0, D_06000B90, D_06000870 }; +static Gfx* sDLists[] = { + gObjectSyokudaiTypeSwitchCausesFlameDL, + gObjectSyokudaiTypeFlameCausesSwitchDL, + gObjectSyokudaiTypeNoSwitchDL, +}; static s32 sNumLitTorchesInGroup; @@ -115,7 +117,7 @@ void ObjSyokudai_Init(Actor* thisx, GlobalContext* globalCtx) { sNumLitTorchesInGroup = 0; } this->flameTexScroll = (u32)(Rand_ZeroOne() * OBJ_SYOKUDAI_SNUFF_DEFAULT); - Actor_SetHeight(thisx, 60.0f); + Actor_SetFocus(thisx, 60.0f); } void ObjSyokudai_Destroy(Actor* thisx, GlobalContext* globalCtx) { @@ -145,7 +147,7 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { if (ActorCutscene_GetCanPlayNext(thisx->cutscene) != 0) { ActorCutscene_StartAndSetUnkLinkFields(thisx->cutscene, thisx); if (this->pendingAction >= OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH) { - Actor_SetSwitchFlag(globalCtx, switchFlag); + Flags_SetSwitch(globalCtx, switchFlag); } } else { ActorCutscene_SetIntentToPlay(thisx->cutscene); @@ -155,13 +157,13 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_NONE; } } else { - if (func_800CA1E8(globalCtx, &globalCtx->colCtx, thisx->world.pos.x, thisx->world.pos.z, &waterSurface, - &waterBox) && + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, thisx->world.pos.x, thisx->world.pos.z, &waterSurface, + &waterBox) && ((waterSurface - thisx->world.pos.y) > OBJ_SYOKUDAI_FLAME_HEIGHT)) { this->snuffTimer = OBJ_SYOKUDAI_SNUFF_OUT; if (type == OBJ_SYOKUDAI_TYPE_FLAME_CAUSES_SWITCH) { - Actor_UnsetSwitchFlag(globalCtx, switchFlag); + Flags_UnsetSwitch(globalCtx, switchFlag); if (groupSize != 0) { this->snuffTimer = OBJ_SYOKUDAI_SNUFF_GROUP_BY_WATER; } @@ -194,7 +196,7 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { if (this->flameCollider.info.acHitInfo->toucher.dmgFlags & 0x820) { interaction = OBJ_SYOKUDAI_INTERACTION_ARROW_FA; } - } else if (player->itemActionParam == 7) { + } else if (player->itemActionParam == PLAYER_AP_STICK) { Vec3f stickTipSeparationVec; Math_Vec3f_Diff(&player->swordInfo[0].tip, &thisx->world.pos, &stickTipSeparationVec); @@ -208,7 +210,7 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { if (interaction <= OBJ_SYOKUDAI_INTERACTION_STICK) { if (player->unk_B28 == 0) { player->unk_B28 = 0xD2; - func_8019F1C0(&thisx->projectedPos, NA_SE_EV_FLAME_IGNITION); + Audio_PlaySfxAtPos(&thisx->projectedPos, NA_SE_EV_FLAME_IGNITION); } else if (player->unk_B28 < 0xC8) { player->unk_B28 = 0xC8; } @@ -219,7 +221,7 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { (flameColliderHurtboxActor->id == ACTOR_EN_ARROW)) { flameColliderHurtboxActor->params = 0; - ((EnArrow*)flameColliderHurtboxActor)->unk_1C0 = 0x800; + ((EnArrow*)flameColliderHurtboxActor)->collider.info.toucher.dmgFlags = 0x800; } } if ((this->snuffTimer > OBJ_SYOKUDAI_SNUFF_NEVER) && @@ -241,7 +243,7 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { } else if (thisx->cutscene >= 0) { this->pendingAction = OBJ_SYOKUDAI_PENDING_ACTION_CUTSCENE_AND_SWITCH; } else { - Actor_SetSwitchFlag(globalCtx, switchFlag); + Flags_SetSwitch(globalCtx, switchFlag); this->snuffTimer = OBJ_SYOKUDAI_SNUFF_NEVER; } } else { @@ -252,8 +254,8 @@ void ObjSyokudai_Update(Actor* thisx, GlobalContext* globalCtx2) { OBJ_SYOKUDAI_SNUFF_TIMER_INITIAL(groupSize) + OBJ_SYOKUDAI_SNUFF_TIMER_JUST_LIT_BONUS; } } - func_801A5CFC(NA_SE_EV_FLAME_IGNITION, &thisx->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, - &D_801DB4B8); + Audio_PlaySfxGeneral(NA_SE_EV_FLAME_IGNITION, &thisx->projectedPos, 4, &D_801DB4B0, &D_801DB4B0, + &D_801DB4B8); } } } @@ -310,11 +312,12 @@ void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx) { (this->flameTexScroll * -OBJ_SYOKUDAI_SNUFF_DEFAULT) & 0x1FF, 0x20, 0x80)); gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255); gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); - Matrix_InsertTranslation(0.0f, OBJ_SYOKUDAI_FLAME_HEIGHT, 0.0f, MTXMODE_APPLY); - Matrix_RotateY(BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - thisx->shape.rot.y), MTXMODE_APPLY); + Matrix_Translate(0.0f, OBJ_SYOKUDAI_FLAME_HEIGHT, 0.0f, MTXMODE_APPLY); + Matrix_RotateYS(BINANG_ROT180(Camera_GetCamDirYaw(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.c b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c index 0b2c789f2..65c984981 100644 --- a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c +++ b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_takaraya_wall.c + * Overlay: ovl_Obj_Takaraya_Wall + * Description: Treasure Chest Shop rising wall + */ + #include "z_obj_takaraya_wall.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjTakarayaWall*)thisx) 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_Taru/z_obj_taru.c b/src/overlays/actors/ovl_Obj_Taru/z_obj_taru.c index 2fc319692..6d7fd7552 100644 --- a/src/overlays/actors/ovl_Obj_Taru/z_obj_taru.c +++ b/src/overlays/actors/ovl_Obj_Taru/z_obj_taru.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_taru.c + * Overlay: ovl_Obj_Taru + * Description: Wooden Barrel + */ + #include "z_obj_taru.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Obj_Toge/z_obj_toge.c b/src/overlays/actors/ovl_Obj_Toge/z_obj_toge.c index 3d4edd76e..0471b6bd7 100644 --- a/src/overlays/actors/ovl_Obj_Toge/z_obj_toge.c +++ b/src/overlays/actors/ovl_Obj_Toge/z_obj_toge.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_toge.c + * Overlay: ovl_Obj_Toge + * Description: Blade Trap + */ + #include "z_obj_toge.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjToge*)thisx) @@ -35,7 +41,7 @@ static ColliderCylinderInit D_809A4CB0 = { // static InitChainEntry sInitChain[] = { static InitChainEntry D_809A4D14[] = { - ICHAIN_F32_DIV1000(minVelocityY, 0, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, 0, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 150, ICHAIN_STOP), 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 22bcddc57..1567e90cc 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,8 +5,9 @@ */ #include "z_obj_tokei_step.h" +#include "objects/object_tokei_step/object_tokei_step.h" -#define FLAGS 0x00400010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_400000) #define THIS ((ObjTokeiStep*)thisx) @@ -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_GetCurrent(); - sysMatrix = Matrix_GetCurrentState(); - sysMatrix->wx = panel->pos.x; - sysMatrix->wy = panel->pos.y; - sysMatrix->wz = panel->pos.z; + mtx->xw = panel->pos.x; + mtx->yw = panel->pos.y; + mtx->zw = 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_RotateYS(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]; - Matrix_MultiplyVector3fByState(&dustSpawnOffset, &dustSpawnPos); + dustSpawnOffset.x = sDustSpawnXOffsets[i]; + Matrix_MultVec3f(&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)); } } @@ -100,15 +96,15 @@ void ObjTokeiStep_InitSteps(ObjTokeiStep* this) { Vec3f panelOffset; s32 pad; - Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, - this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); 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); + Matrix_MultVec3f(&panelOffset, &panel->pos); panel->posChangeY = 0.0f; panel->numBounces = 0; } @@ -119,15 +115,15 @@ void ObjTokeiStep_InitStepsOpen(ObjTokeiStep* this) { ObjTokeiStepPanel* panel; Vec3f panelOffset; - Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, - this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_SetTranslateRotateYXZ(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + 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); + Matrix_MultVec3f(&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,25 +141,25 @@ 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); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_CLOCK_TOWER_STAIR_MOVE); panel->hasSoundPlayed = true; } 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; } @@ -195,17 +191,18 @@ void ObjTokeiStep_Init(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - if ((globalCtx->sceneNum == 0x6F) && (gSaveContext.sceneSetupIndex == 2) && (globalCtx->csCtx.unk_12 == 0)) { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000968); + DynaPolyActor_Init(&this->dyna, 0); + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 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.save.time < CLOCK_TIME(6, 0))) || (gSaveContext.save.day >= 4)) { this->dyna.actor.draw = ObjTokeiStep_DrawOpen; ObjTokeiStep_InitStepsOpen(this); ObjTokeiStep_SetupDoNothingOpen(this); } else { - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000968); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClocktowerPanelCol); ObjTokeiStep_InitSteps(this); ObjTokeiStep_SetupDoNothing(this); } @@ -214,7 +211,7 @@ void ObjTokeiStep_Init(Actor* thisx, GlobalContext* globalCtx) { void ObjTokeiStep_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjTokeiStep_SetupBeginOpen(ObjTokeiStep* this) { @@ -224,9 +221,10 @@ void ObjTokeiStep_SetupBeginOpen(ObjTokeiStep* this) { void ObjTokeiStep_BeginOpen(ObjTokeiStep* this, GlobalContext* globalCtx) { CsCmdActorAction* action; - if (func_800EE29C(globalCtx, 0x86)) { - action = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x86)]; - if ((globalCtx->csCtx.frames == (*action).startFrame) && action->unk0) { + if (Cutscene_CheckActorAction(globalCtx, 134)) { + action = globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 134)]; + + if ((action->startFrame == globalCtx->csCtx.frames) && (action->action != 0)) { this->dyna.actor.draw = ObjTokeiStep_DrawOpen; ObjTokeiStep_SetupOpen(this); } @@ -253,7 +251,7 @@ void ObjTokeiStep_Open(ObjTokeiStep* this, GlobalContext* globalCtx) { } void ObjTokeiStep_SetupDoNothingOpen(ObjTokeiStep* this) { - this->dyna.actor.flags &= ~0x10; + this->dyna.actor.flags &= ~ACTOR_FLAG_10; this->actionFunc = ObjTokeiStep_DoNothingOpen; } @@ -269,12 +267,12 @@ void ObjTokeiStep_Update(Actor* thisx, GlobalContext* globalCtx) { void ObjTokeiStep_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; - func_800BDFC0(globalCtx, D_06000088); + Gfx_DrawDListOpa(globalCtx, gClocktowerPanelDL); } void ObjTokeiStep_DrawOpen(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; - int i; + s32 i; ObjTokeiStepPanel* panel; Gfx* gfx; @@ -282,11 +280,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_Tokei_Tobira/z_obj_tokei_tobira.c b/src/overlays/actors/ovl_Obj_Tokei_Tobira/z_obj_tokei_tobira.c index 2ac8a64a6..9ffa6d446 100644 --- a/src/overlays/actors/ovl_Obj_Tokei_Tobira/z_obj_tokei_tobira.c +++ b/src/overlays/actors/ovl_Obj_Tokei_Tobira/z_obj_tokei_tobira.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_tokei_tobira.c + * Overlay: ovl_Obj_Tokei_Tobira + * Description: Clock Tower - Swinging Doors + */ + #include "z_obj_tokei_tobira.h" #define FLAGS 0x00000000 diff --git a/src/overlays/actors/ovl_Obj_Tokei_Turret/z_obj_tokei_turret.c b/src/overlays/actors/ovl_Obj_Tokei_Turret/z_obj_tokei_turret.c index f1247cfef..327183cfd 100644 --- a/src/overlays/actors/ovl_Obj_Tokei_Turret/z_obj_tokei_turret.c +++ b/src/overlays/actors/ovl_Obj_Tokei_Turret/z_obj_tokei_turret.c @@ -1,3 +1,9 @@ +/* + * File: z_obj_tokei_turret.c + * Overlay: ovl_Obj_Tokei_Turret + * Description: South Clock Town - Flags & Carnival Platform + */ + #include "z_obj_tokei_turret.h" #define FLAGS 0x00000000 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 484e0bf3a..546e29a8e 100644 --- a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c +++ b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c @@ -1,42 +1,72 @@ -#include "z_obj_tokeidai.h" +/* + * File: z_obj_tokeidai.c + * Overlay: ovl_Obj_Tokeidai + * Description: Components of the Clock Tower. Also used for wall clocks. The specific components are: + * - ClockFace: The decorated face of the clock that spins every hour. + * - MinuteRing: The ring around the clock face that spins every two minutes. + * - ExteriorGear: The two gears on the side of the tower that spin every two minutes. + * - SunAndMoonPanel: A panel with a sun and moon image that tells whether it is day or night. + * - Counterweight: The spinning weight on top of the tower that emits a spotlight at night. + * - StaircaseToRooftop: The staircase to tower's rooftop that opens after midnight on the Final Day. + * - TerminaFieldWalls: The walls of the Clock Tower visible from Termina Field. + * - UnusedWall: A single wall of the Clock Tower, unused in the final game. + * + * Sometimes, the ClockFace, MinuteRing, and SunAndMoonPanel are treated as a single clock entity. + * This is called Clock if it applies to both the Clock Tower clock and wall clocks, and + * TowerClock/WallClock, respectively, if it only applies to one of them. + * + * 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, which is handled + * via the series of action functions labeled with TowerOpening. + * + * All components have at least one of these three actions: + * - Idle: The "default" action, and for some components the only action. + * The component is either completely still, or it's telling the time, depending on the component. + * - OpenedIdle: The action for certain Clock Tower components after midnight on the Final Day. + * The TowerClock, ExteriorGears, and Counterweight no longer tell time and are moved to a different position. + * Called "opened" because it corresponds to when the staircase to the tower's rooftop is opened up. + * - Collapse: The action for certain Clock Tower components when the moon crashes into Termina. + * This action is responsible for making the component fall during the moon crash cutscene. + */ -#define FLAGS 0x00000030 +#include "z_obj_tokeidai.h" +#include "objects/object_obj_tokeidai/object_obj_tokeidai.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjTokeidai*)thisx) +#define GET_CURRENT_CLOCK_HOUR(this) ((s32)((this)->clockTime * (24.0f / 0x10000))) +#define GET_CURRENT_CLOCK_MINUTE(this) ((s32)((this)->clockTime * (360 * 2.0f / 0x10000)) % 30) +#define GET_CLOCK_FACE_ROTATION(currentClockHour) ((s16)(currentClockHour * (0x10000 / 24.0f))) +#define GET_MINUTE_RING_OR_EXTERIOR_GEAR_ROTATION(currentClockMinute) \ + ((s16)(currentClockMinute * (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_ExteriorGear_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_ExteriorGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TerminaFieldWalls_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_StaircaseToRooftop_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_ExteriorGear_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Tokeidai_InitVars = { ACTOR_OBJ_TOKEIDAI, ACTORCAT_PROP, FLAGS, - OBJECT_OBJECT_UNSET_TOKEIDAI, + OBJECT_OBJ_TOKEIDAI, sizeof(ObjTokeidai), (ActorFunc)ObjTokeidai_Init, (ActorFunc)ObjTokeidai_Destroy, @@ -44,87 +74,830 @@ 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 panel based on the time of day. The actual + * angle can differ from the target angle if the panel is in + * the middle of rotating. + */ +s32 ObjTokeidai_GetTargetSunMoonPanelRotation(void) { + if (gSaveContext.save.isNight) { + return 0x8000; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2790.s") +void ObjTokeidai_SetupClockOrExteriorGear(ObjTokeidai* this) { + s32 currentClockMinute = GET_CURRENT_CLOCK_MINUTE(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB27B4.s") + this->clockMinute = currentClockMinute; + this->minuteRingOrExteriorGearRotation = GET_MINUTE_RING_OR_EXTERIOR_GEAR_ROTATION(currentClockMinute); + this->minuteRingOrExteriorGearRotationalVelocity = 0x3C; + this->minuteRingOrExteriorGearRotationTimer = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2834.s") +void ObjTokeidai_Clock_Init(ObjTokeidai* this) { + s32 currentClockHour; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB28C8.s") + ObjTokeidai_SetupClockOrExteriorGear(this); + currentClockHour = GET_CURRENT_CLOCK_HOUR(this); + this->clockHour = currentClockHour; + this->clockFaceRotation = GET_CLOCK_FACE_ROTATION(currentClockHour); + this->clockFaceRotationalVelocity = 0; + this->clockFaceRotationTimer = 0; + this->sunMoonPanelRotationalVelocity = 0; + this->sunMoonPanelRotation = ObjTokeidai_GetTargetSunMoonPanelRotation(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB29F8.s") +void ObjTokeidai_ExteriorGear_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.draw = ObjTokeidai_ExteriorGear_Draw; + this->opaDList = gClockTowerExteriorGearDL; + ObjTokeidai_SetupClockOrExteriorGear(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2BBC.s") + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0))) { + ObjTokeidai_SetupTowerOpening(this); + } else if ((CURRENT_DAY == 3 && gSaveContext.save.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) { + this->actionFunc = ObjTokeidai_ExteriorGear_OpenedIdle; + this->actor.world.pos.y += this->actor.scale.y * 1900.0f; + this->actor.shape.yOffset = 1500.0f; + gSaveContext.save.weekEventReg[8] |= 0x40; + } else { + this->actionFunc = ObjTokeidai_ExteriorGear_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.currentCsIndex == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0))) { + ObjTokeidai_SetupTowerOpening(this); + } else if ((CURRENT_DAY == 3 && gSaveContext.save.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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3010.s") + this->clockFaceZTranslation = -0x140; + this->actor.shape.rot.x = -0x4000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB319C.s") + this->actor.home.pos = this->actor.world.pos; + this->actor.home.pos.y -= 1178.0f; + this->actor.home.pos.z += 13.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3240.s") + this->actionFunc = ObjTokeidai_TowerClock_OpenedIdle; + } else { + this->actionFunc = ObjTokeidai_TowerClock_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB32F0.s") +void ObjTokeidai_Counterweight_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3370.s") + this->actor.draw = ObjTokeidai_Counterweight_Draw; + this->opaDList = gClockTowerCounterweightDL; + this->xluDList = gClockTowerSpotlightDL; + if (gSaveContext.save.isNight) { + this->spotlightIntensity = 100; + } else { + this->spotlightIntensity = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB34CC.s") + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0))) { + this->spotlightIntensity = 0; + ObjTokeidai_SetupTowerOpening(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3544.s") + 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); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3598.s") + 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.save.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_80AB363C.s") +void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB365C.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->clockTime = gSaveContext.save.time; + this->actor.home.rot.x = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB36C4.s") + switch (OBJ_TOKEIDAI_TYPE(&this->actor)) { + case OBJ_TOKEIDAI_TYPE_EXTERIOR_GEAR_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_ExteriorGear_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3808.s") + case OBJ_TOKEIDAI_TYPE_EXTERIOR_GEAR_CLOCK_TOWN: + ObjTokeidai_ExteriorGear_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3880.s") + case OBJ_TOKEIDAI_TYPE_UNUSED_WALL: + this->opaDList = gClockTowerUnusedTowerWallDL; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB38B0.s") + case OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD: + Actor_SetScale(&this->actor, 1.0f); + this->opaDList = gClockTowerTerminaFieldWallsDL; + this->actionFunc = ObjTokeidai_TerminaFieldWalls_Idle; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB39BC.s") + case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_TowerClock_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3A7C.s") + case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN: + ObjTokeidai_TowerClock_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3B34.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BB0.s") + 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; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BD8.s") + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_Counterweight_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BE8.s") + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN: + ObjTokeidai_Counterweight_Init(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3C50.s") + case OBJ_TOKEIDAI_TYPE_STAIRCASE_TO_ROOFTOP: + this->opaDList = gClockTowerStaircaseToRooftopDL; + this->xluDList = gClockTowerEmptyDL; + this->actionFunc = ObjTokeidai_StaircaseToRooftop_Idle; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3CCC.s") +void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3ED0.s") +void ObjTokeidai_RotateOnMinuteChange(ObjTokeidai* this, s32 playSfx) { + s32 currentClockMinute = GET_CURRENT_CLOCK_MINUTE(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4040.s") + if (currentClockMinute != this->clockMinute) { + if (this->minuteRingOrExteriorGearRotationTimer == 8 && playSfx) { + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CLOCK_TOWER_SECOND_HAND); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4080.s") + if (this->minuteRingOrExteriorGearRotationTimer > 8) { + // This actually performs the rotation to the next minute + // for the minute ring or exterior gear. + this->minuteRingOrExteriorGearRotationalVelocity += 0x3C; + this->minuteRingOrExteriorGearRotation += this->minuteRingOrExteriorGearRotationalVelocity; + } else { + // This makes the minute ring or exterior gear wiggle in place for a bit + // before rotating to the next position. + if ((this->minuteRingOrExteriorGearRotationTimer & 3) == 0) { + this->minuteRingOrExteriorGearRotation += 0x5A; + } + if ((this->minuteRingOrExteriorGearRotationTimer & 3) == 1) { + this->minuteRingOrExteriorGearRotation -= 0x5A; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4160.s") + this->minuteRingOrExteriorGearRotationTimer++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Update.s") + if ((currentClockMinute == 15 && this->minuteRingOrExteriorGearRotation < 0) || + (currentClockMinute != 15 && + this->minuteRingOrExteriorGearRotation > GET_MINUTE_RING_OR_EXTERIOR_GEAR_ROTATION(currentClockMinute))) { + this->minuteRingOrExteriorGearRotation = GET_MINUTE_RING_OR_EXTERIOR_GEAR_ROTATION(currentClockMinute); + this->clockMinute = currentClockMinute; + this->minuteRingOrExteriorGearRotationalVelocity = 0x5A; + this->minuteRingOrExteriorGearRotationTimer = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Draw.s") +void ObjTokeidai_ExteriorGear_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_MoveWithGravity(&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_80AB4394.s") +void ObjTokeidai_ExteriorGear_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 132) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 2) { + this->actionFunc = ObjTokeidai_ExteriorGear_Collapse; + this->actor.speedXZ = this->actor.scale.y * 5.0f; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = 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_80AB4664.s") +/** + * 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; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4894.s") + this->actor.world.pos.z += 4.0f; + Actor_MoveWithGravity(&this->actor); + if (this->actor.world.pos.y < 0.0f) { + this->actionFunc = ObjTokeidai_DoNothing; + } +} + +/** + * This makes the tower's clock slide off as the moon crashes into it. It's + * the tower clock's equivalent to other components' Collapse functions. + */ +void ObjTokeidai_TowerClock_SlideOff(ObjTokeidai* this, GlobalContext* globalCtx) { + f32 cos; + f32 sin; + Actor* thisx = &this->actor; + + if (this->slidingClockFaceAngle < 0x4000) { + this->slidingClockFaceAngle += 0x28; + } + if (this->slidingClockFaceAngle > 0x800) { + this->aerialClockFaceSpeed += 4; + } + + 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->terminalVelocity = -7.5f; + thisx->gravity = -0.75f; + thisx->velocity.y = -2.0f; + } + } + + 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; +} + +void ObjTokeidai_TowerClock_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 132) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 1) { + this->actionFunc = ObjTokeidai_TowerClock_SlideOff; + this->slidingClockFaceAngle = 0; + this->aerialClockFaceSpeed = -0xD; + } +} + +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_MoveWithGravity(&this->actor); + } +} + +void ObjTokeidai_Counterweight_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 132) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 3) { + this->actionFunc = ObjTokeidai_Counterweight_Collapse; + this->xRotation = 0; + this->actor.velocity.y = 0.0f; + this->actor.terminalVelocity = this->actor.scale.y * -50.0f; + this->actor.gravity = this->actor.scale.y * -5.0f; + } +} + +void ObjTokeidai_TerminaFieldWalls_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { + if (this->actor.shape.rot.x < 0x4000) { + this->actor.shape.rot.x += 0x28; + } +} + +void ObjTokeidai_TerminaFieldWalls_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 132) != 0 && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 1) { + this->actionFunc = ObjTokeidai_TerminaFieldWalls_Collapse; + } +} + +void ObjTokeidai_TowerOpening_EndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) { + if (Cutscene_CheckActorAction(globalCtx, 132) != 0 && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 5) { + gSaveContext.save.weekEventReg[8] |= 0x40; + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.currentCsIndex == 0))) { + Audio_SetCutsceneFlag(false); + gSaveContext.save.cutscene = 0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.respawnFlag = 2; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->nextEntranceIndex = gSaveContext.respawn[RESTART_MODE_RETURN].entranceIndex; + globalCtx->unk_1887F = 2; + if (gSaveContext.respawn[RESTART_MODE_RETURN].playerParams == 0xCFF) { + gSaveContext.nextTransition = 0x15; + } else { + gSaveContext.nextTransition = 2; + } + } + this->actionFunc = ObjTokeidai_DoNothing; + } +} + +void ObjTokeidai_TowerOpening_FinishOpening(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; + + 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; + } + } + } +} + +void ObjTokeidai_TowerOpening_Wait(ObjTokeidai* this, GlobalContext* globalCtx) { + if (this->openingWaitTimer > 0) { + this->openingWaitTimer--; + } else { + this->actionFunc = ObjTokeidai_TowerOpening_FinishOpening; + this->openingWaitTimer = 0; + } +} + +void ObjTokeidai_TowerOpening_DropCounterweight(ObjTokeidai* this, GlobalContext* globalCtx) { + this->xRotation += this->counterweightRotationalVelocity; + if (this->xRotation < 0x4000) { + this->counterweightRotationalVelocity += this->counterweightRotationalAcceleration; + return; + } + + this->counterweightRotationalAcceleration = 0x14; + this->xRotation = 0x4000; + switch (this->boundCount) { + case 0: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_0); + break; + + case 1: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_1); + break; + + case 2: + Actor_PlaySfxAtPos(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_2); + break; + } + this->boundCount++; + + 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; + } +} + +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)) { + Actor_PlaySfxAtPos(&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)) { + Actor_PlaySfxAtPos(&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 ((Cutscene_CheckActorAction(globalCtx, 132) && + globalCtx->csCtx.actorActions[Cutscene_GetActorActionIndex(globalCtx, 132)]->action == 4) || + (gSaveContext.save.weekEventReg[8] & 0x40)) { + this->actionFunc = ObjTokeidai_TowerOpening_RaiseTower; + } +} + +/** + * Sets up the sequence where the Clock Tower 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_StaircaseToRooftop_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (((CURRENT_DAY == 3 && gSaveContext.save.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) || + (gSaveContext.save.weekEventReg[8] & 0x40)) { + this->actor.draw = ObjTokeidai_Draw; + } else { + this->actor.draw = NULL; + } +} + +s32 ObjTokeidai_IsPostFirstCycleFinalHours(ObjTokeidai* this, GlobalContext* globalCtx) { + if (gSaveContext.save.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + return false; + } + if (CURRENT_DAY == 3 && gSaveContext.save.time < CLOCK_TIME(6, 0)) { + ObjTokeidai_SetupTowerOpening(this); + return true; + } + return false; +} + +void ObjTokeidai_RotateOnHourChange(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 currentClockHour = GET_CURRENT_CLOCK_HOUR(this); + + if (currentClockHour != 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 ((currentClockHour == 12 && this->clockFaceRotation < 0) || + (currentClockHour != 12 && this->clockFaceRotation > GET_CLOCK_FACE_ROTATION(currentClockHour))) { + this->clockFaceRotation = GET_CLOCK_FACE_ROTATION(currentClockHour); + this->clockHour = currentClockHour; + this->clockFaceRotationalVelocity = 0; + this->clockFaceRotationTimer = 0; + } + } + + // If the sun and moon panel doesn't have the target rotation (e.g., the time of day + // just changed), rotate it until it matches the target. + if (this->sunMoonPanelRotation != ObjTokeidai_GetTargetSunMoonPanelRotation()) { + if (this->clockHour == 6) { + this->sunMoonPanelRotationalVelocity += 0x222; + this->sunMoonPanelRotation += this->sunMoonPanelRotationalVelocity; + if (this->sunMoonPanelRotation > 0x10000) { + this->sunMoonPanelRotation = ObjTokeidai_GetTargetSunMoonPanelRotation(); + this->sunMoonPanelRotationalVelocity = 0; + } + } + if (this->clockHour == 18) { + this->sunMoonPanelRotationalVelocity += 0x222; + this->sunMoonPanelRotation += this->sunMoonPanelRotationalVelocity; + if (this->sunMoonPanelRotation > 0x8000) { + this->sunMoonPanelRotation = ObjTokeidai_GetTargetSunMoonPanelRotation(); + this->sunMoonPanelRotationalVelocity = 0; + } + } + } +} + +void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (CURRENT_DAY == 3 && this->clockHour < 6 && gSaveContext.save.time < CLOCK_TIME(6, 0)) { + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_SetupTowerOpening(this); + gSaveContext.save.weekEventReg[8] |= 0x40; + return; + } + + if (globalCtx->csCtx.state != 0) { + this->actor.home.rot.x = 1; + this->clockTime += 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->clockTime = gSaveContext.save.time; + if (this->actor.home.rot.x != 0) { + ObjTokeidai_Clock_Init(this); + this->actor.home.rot.x = 0; + } + } + + if (CURRENT_DAY != 3 || gSaveContext.save.time >= CLOCK_TIME(6, 0)) { + ObjTokeidai_RotateOnMinuteChange(this, true); + } + ObjTokeidai_RotateOnHourChange(this, globalCtx); +} + +void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + this->clockTime = gSaveContext.save.time; + ObjTokeidai_RotateOnMinuteChange(this, true); + ObjTokeidai_RotateOnHourChange(this, globalCtx); +} + +void ObjTokeidai_ExteriorGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) { + this->actor.draw = ObjTokeidai_ExteriorGear_Draw; + } else { + if (globalCtx->csCtx.state != 0) { + this->actor.home.rot.x = 1; + this->clockTime += 3; + this->actor.draw = ObjTokeidai_ExteriorGear_Draw; + } else { + if ((globalCtx->actorCtx.unk5 & 2) == 0 && + OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_EXTERIOR_GEAR_TERMINA_FIELD && + ActorCutscene_GetCurrentIndex() == -1) { + this->actor.draw = NULL; + } + this->clockTime = gSaveContext.save.time; + if (this->actor.home.rot.x != 0) { + ObjTokeidai_SetupClockOrExteriorGear(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.save.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); +} + +/** + * Used for TerminaFieldWalls StaircaseToRooftop, and UnusedWall + */ +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_Translate(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -1791.0f, MTXMODE_APPLY); + Matrix_RotateXS(-this->xRotation, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 1791.0f, MTXMODE_APPLY); + + Matrix_Push(); + Matrix_RotateZS(-this->minuteRingOrExteriorGearRotation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gClockTowerMinuteRingDL); + Matrix_Pop(); + + Matrix_Translate(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++, gClockTowerClockCenterAndHandDL); + + Matrix_RotateZS(-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++, gWallClockClockFace); + } else { + gSPDisplayList(POLY_OPA_DISP++, gClockTowerClockFace); + } + + Matrix_Translate(0.0f, -1112.0f, -19.6f, MTXMODE_APPLY); + Matrix_RotateYS(this->sunMoonPanelRotation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gClockTowerSunAndMoonPanelDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + u32 gameplayFrames = globalCtx->gameplayFrames; + ObjTokeidai* this = THIS; + + Matrix_RotateYS(-this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, -5480.0f, 80.0f, MTXMODE_APPLY); + Matrix_RotateXS(-this->xRotation, MTXMODE_APPLY); + Matrix_Translate(0.0f, 5480.0f, -80.0f, MTXMODE_APPLY); + Matrix_RotateYS(this->actor.shape.rot.y, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + // For scrolling the spotlight's mask texture down the length of the light beam. + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, -gameplayFrames, 0, 0x20, 0x20)); + + // Draws the counterweight + 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); + + // Draws the spotlight + 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_ExteriorGear_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_Translate(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -1791.0f, MTXMODE_APPLY); + Matrix_RotateYS(-this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(-this->xRotation, MTXMODE_APPLY); + Matrix_RotateYS(thisx->shape.rot.y, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, 1791.0f, MTXMODE_APPLY); + Matrix_RotateZS(this->minuteRingOrExteriorGearRotation, 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++, gClockTowerExteriorGearDL); + + 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..48e44614d 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_EXTERIOR_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_EXTERIOR_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_TO_ROOFTOP, +} 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 minuteRingOrExteriorGearRotation; + /* 0x14E */ s16 minuteRingOrExteriorGearRotationalVelocity; + /* 0x150 */ s16 minuteRingOrExteriorGearRotationTimer; + /* 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 sunMoonPanelRotation; + /* 0x15C */ union { + s16 sunMoonPanelRotationalVelocity; + 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 clockTime; // can differ from the actual time, e.g., in cutscenes + /* 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 1ae3bf122..b91cbcf7e 100644 --- a/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c +++ b/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_toudai.c + * Overlay: ovl_Obj_Toudai + * Description: Unused early Clock Tower Spotlight + */ + #include "z_obj_toudai.h" -#define FLAGS 0x00000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjToudai*)thisx) 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 8ffee7d20..223ebad74 100644 --- a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c +++ b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c @@ -1,6 +1,13 @@ -#include "z_obj_tree.h" +/* + * File: z_obj_tree.c + * Overlay: ovl_Obj_Tree + * Description: Single branching tree (e.g. North Clock Town) + */ -#define FLAGS 0x02000000 +#include "z_obj_tree.h" +#include "objects/object_tree/object_tree.h" + +#define FLAGS (ACTOR_FLAG_2000000) #define THIS ((ObjTree*)thisx) @@ -9,7 +16,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, @@ -22,15 +32,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), @@ -65,32 +87,111 @@ 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 +void ObjTree_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjTree* this = THIS; + CollisionHeader* colHeader = NULL; -extern ColliderCylinderInit D_80B9A570; -extern DamageTable D_80B9A59C; -extern CollisionCheckInfoInit2 D_80B9A5BC; + 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(&object_tree_Colheader_001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } -extern UNK_TYPE D_06000680; -extern UNK_TYPE D_06001B2C; + 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_Init.s") + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + this->collider.dim.height = 220; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Destroy.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_80B9A20C.s") +void ObjTree_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjTree* this = THIS; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A220.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_80B9A230.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A27C.s") +void ObTree_SetupDoNothing(ObjTree* this) { + this->actionFunc = ObTree_DoNothing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A348.s") +void ObTree_DoNothing(ObjTree* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Update.s") +void ObTree_SetupSway(ObjTree* this) { + this->timer = 0; + this->swayAmplitude = 546.0f; + this->swayVelocity = 35 * 0x10000 / 360; + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_TREE_SWING); + this->actionFunc = ObTree_Sway; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Draw.s") +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++, object_tree_DL_000680); + + Matrix_RotateZYX(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++, object_tree_DL_0007C8); + + 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.c b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c index d9f944527..af00e5c64 100644 --- a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c +++ b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_tsubo.c + * Overlay: ovl_Obj_Tsubo + * Description: Pots + */ + #include "z_obj_tsubo.h" -#define FLAGS 0x04800010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_800000 | ACTOR_FLAG_4000000) #define THIS ((ObjTsubo*)thisx) @@ -37,7 +43,7 @@ static ColliderCylinderInit D_809295B0 = { // static InitChainEntry sInitChain[] = { static InitChainEntry D_809295DC[] = { ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(terminalVelocity, -20000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), diff --git a/src/overlays/actors/ovl_Obj_Um/z_obj_um.c b/src/overlays/actors/ovl_Obj_Um/z_obj_um.c index fe474e428..324d13e4b 100644 --- a/src/overlays/actors/ovl_Obj_Um/z_obj_um.c +++ b/src/overlays/actors/ovl_Obj_Um/z_obj_um.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_um.c + * Overlay: ovl_Obj_Um + * Description: Cremia's cart and milk run quest + */ + #include "z_obj_um.h" -#define FLAGS 0x00000039 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8 | ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjUm*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c index 32b9d49dc..35371b605 100644 --- a/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c +++ b/src/overlays/actors/ovl_Obj_Usiyane/z_obj_usiyane.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_usiyane.c + * Overlay: ovl_Obj_Usiyane + * Description: Roof of Cow Barn + */ + #include "z_obj_usiyane.h" -#define FLAGS 0x00000020 +#define FLAGS (ACTOR_FLAG_20) #define THIS ((ObjUsiyane*)thisx) @@ -14,7 +20,7 @@ const ActorInit Obj_Usiyane_InitVars = { ACTOR_OBJ_USIYANE, ACTORCAT_PROP, FLAGS, - OBJECT_OBJECT_UNSET_USIYANE, + OBJECT_OBJ_USIYANE, sizeof(ObjUsiyane), (ActorFunc)ObjUsiyane_Init, (ActorFunc)ObjUsiyane_Destroy, diff --git a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c index 38ade90d7..8741fc01b 100644 --- a/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c +++ b/src/overlays/actors/ovl_Obj_Visiblock/z_obj_visiblock.c @@ -1,6 +1,13 @@ -#include "z_obj_visiblock.h" +/* + * File: z_obj_visiblock.c + * Overlay: ovl_Obj_Visiblock + * Description: Lens of Truth Platform + */ -#define FLAGS 0x00000080 +#include "z_obj_visiblock.h" +#include "objects/object_visiblock/object_visiblock.h" + +#define FLAGS (ACTOR_FLAG_80) #define THIS ((ObjVisiblock*)thisx) @@ -27,23 +34,20 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern CollisionHeader D_06000AD0; -extern Gfx D_06000140[]; - void ObjVisiblock_Init(Actor* thisx, GlobalContext* globalCtx) { ObjVisiblock* this = THIS; Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - BcCheck3_BgActorInit(&this->dyna, 0); - BgCheck3_LoadMesh(globalCtx, &this->dyna, &D_06000AD0); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_visiblock_Colheader_000AD0); } void ObjVisiblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { ObjVisiblock* this = THIS; - BgCheck_RemoveActorMesh(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); } void ObjVisiblock_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BE03C(globalCtx, D_06000140); + Gfx_DrawDListXlu(globalCtx, object_visiblock_DL_000140); } 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 ffbd6a511..067bd58ec 100644 --- a/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c +++ b/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c @@ -1,6 +1,13 @@ -#include "z_obj_vspinyroll.h" +/* + * File: z_obj_vspinyroll.c + * Overlay: ovl_Obj_Vspinyroll + * Description: Vertical Spiked rollers + */ -#define FLAGS 0x00000010 +#include "z_obj_vspinyroll.h" +#include "objects/object_spinyroll/object_spinyroll.h" + +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjVspinyroll*)thisx) @@ -9,13 +16,17 @@ void ObjVspinyroll_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjVspinyroll_Update(Actor* thisx, GlobalContext* globalCtx); void ObjVspinyroll_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A3CEC4(ObjVspinyroll* this); void func_80A3CEE0(ObjVspinyroll* this, GlobalContext* globalCtx); void func_80A3CF4C(ObjVspinyroll* this, GlobalContext* globalCtx); +void func_80A3CFAC(ObjVspinyroll* this); void func_80A3CFE0(ObjVspinyroll* this, GlobalContext* globalCtx); +void func_80A3D024(ObjVspinyroll* this); void func_80A3D038(ObjVspinyroll* this, GlobalContext* globalCtx); +void func_80A3D0E8(ObjVspinyroll* this); void func_80A3D0FC(ObjVspinyroll* this, GlobalContext* globalCtx); +void func_80A3D2C0(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Vspinyroll_InitVars = { ACTOR_OBJ_VSPINYROLL, ACTORCAT_PROP, @@ -28,77 +39,417 @@ const ActorInit Obj_Vspinyroll_InitVars = { (ActorFunc)ObjVspinyroll_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A3D488 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +f32 D_80A3D450[] = { 1.0f, 2.0f }; + +f32 D_80A3D458[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f }; + +s16 D_80A3D478[] = { 1, 10, 20, 30, 40, 50, 60, 70 }; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 30, 120, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A3D4D4[] = { +f32 D_80A3D4B4[] = { 1.0f, 1.0f, -1.0f, -1.0f }; + +f32 D_80A3D4C4[] = { 29.0f, -29.0f, 29.0f, -29.0f }; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 500, ICHAIN_STOP), }; -#endif +s16 D_80A3D4DC[] = { 0xFA0, -0xFA0 }; -extern ColliderCylinderInit D_80A3D488; -extern InitChainEntry D_80A3D4D4[]; +void func_80A3C4E0(Vec3f* arg0, Vec3f* arg1, s16 arg2) { + f32 sp1C = Math_SinS(arg2); + f32 temp_f0 = Math_CosS(arg2); -extern UNK_TYPE D_06000460; -extern UNK_TYPE D_06000F80; + arg0->x = (arg1->z * sp1C) + (arg1->x * temp_f0); + arg0->y = arg1->y; + arg0->z = (arg1->z * temp_f0) - (arg1->x * sp1C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C4E0.s") +void func_80A3C560(ObjVspinyroll* this) { + f32 magnitude; + Vec3f* sp20 = &this->unk_39C[this->unk_398 ^ 1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C560.s") + Math_Vec3f_Diff(sp20, &this->dyna.actor.world.pos, &this->unk_3B4); + magnitude = Math3D_Vec3fMagnitude(&this->unk_3B4); + if (magnitude < 0.01f) { + Math_Vec3f_Diff(sp20, &this->unk_39C[this->unk_398], &this->unk_3B4); + magnitude = Math3D_Vec3fMagnitude(&this->unk_3B4); + if (magnitude < 0.01f) { + Math_Vec3f_Copy(&this->unk_3B4, &gZeroVec3f); + return; + } + } + Math_Vec3f_Scale(&this->unk_3B4, 1.0f / magnitude); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C658.s") +void func_80A3C658(ObjVspinyroll* this) { + this->dyna.actor.world.rot.y = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &this->unk_39C[this->unk_398 ^ 1]); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C6A0.s") +void func_80A3C6A0(ObjVspinyroll* this) { + this->unk_398 = 0; + func_80A3C658(this); + func_80A3C560(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C6CC.s") +void func_80A3C6CC(ObjVspinyroll* this) { + this->unk_398 ^= 1; + func_80A3C658(this); + func_80A3C560(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C700.s") +s32 func_80A3C700(ObjVspinyroll* this) { + s32 pad; + s32 sp30 = this->unk_398 ^ 1; + Vec3f sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C7E8.s") + Math_StepToF(&this->dyna.actor.speedXZ, this->unk_394, this->unk_394 * 0.2f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3C8D8.s") + this->dyna.actor.world.pos.x += this->dyna.actor.speedXZ * this->unk_3B4.x; + this->dyna.actor.world.pos.y += this->dyna.actor.speedXZ * this->unk_3B4.y; + this->dyna.actor.world.pos.z += this->dyna.actor.speedXZ * this->unk_3B4.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CB94.s") + Math_Vec3f_Diff(&this->unk_39C[sp30], &this->dyna.actor.world.pos, &sp24); + return Math3D_LengthSquared(&sp24) < (SQ(this->dyna.actor.speedXZ) + 0.05f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CBF0.s") +void func_80A3C7E8(ObjVspinyroll* this) { + f32 phi_f2; + s32 i; + s32 j; + f32 tempf; + s32 index = D_80A3D450[OBJVSPINYROLL_GET_4000(&this->dyna.actor)] * 120.0f * (1.0f / 58.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CC30.s") + index += 2; + this->unk_1A8.unk_1E4 = index * 4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CC84.s") + tempf = ((D_80A3D450[OBJVSPINYROLL_GET_4000(&this->dyna.actor)] * 120.0f) - 2.0f) / (index - 1); + phi_f2 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/ObjVspinyroll_Init.s") + for (i = 0, j = 0; i < this->unk_1A8.unk_1E4; i++) { + this->unk_1A8.unk_000[i].unk_00.x = D_80A3D4C4[j]; + this->unk_1A8.unk_000[i].unk_00.y = phi_f2; + this->unk_1A8.unk_000[i].unk_00.z = D_80A3D4B4[j]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/ObjVspinyroll_Destroy.s") + j++; + if (j >= 4) { + j = 0; + phi_f2 += tempf; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CEC4.s") +s32 func_80A3C8D8(ObjVspinyroll* this, GlobalContext* globalCtx, Vec3f* arg2, s32 arg3) { + s32 pad; + ObjVspinyrollStruct3* unk_1A8 = &this->unk_1A8; + ObjVspinyrollStruct2* ptr; + s32 i; + Vec3f spE4; + Vec3f spD8; + Vec3f spCC; + Vec3f spC0; + Vec3f spB4; + Vec3f spA8; + f32 temp_f20 = FLT_MAX; + f32 temp_f0; + s32 sp9C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CEE0.s") + spE4.z = 0.0f; + sp9C = false; + unk_1A8->unk_1E0 = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CF10.s") + for (i = 0; i < unk_1A8->unk_1E4; i++) { + ptr = &unk_1A8->unk_000[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CF4C.s") + spE4.x = ptr->unk_00.x; + spE4.y = ptr->unk_00.y; + func_80A3C4E0(&spD8, &spE4, this->dyna.actor.world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CFAC.s") + spD8.x += this->dyna.actor.world.pos.x; + spD8.y += this->dyna.actor.world.pos.y; + spD8.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3CFE0.s") + Math_Vec3f_Copy(&spCC, &spD8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3D024.s") + spCC.x += 30.0f * this->unk_3B4.x; + spCC.z += 30.0f * this->unk_3B4.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3D038.s") + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spD8, &spCC, &spC0, &unk_1A8->unk_000[i].collisionPoly, true, + false, false, true, &unk_1A8->unk_000[i].bgId, &this->dyna.actor, 0.0f)) { + if ((arg3 != 0) && (this->dyna.actor.flags & ACTOR_FLAG_40)) { + spA8.x = ptr->unk_00.x * 0.2f; + spA8.y = ptr->unk_00.y; + spA8.z = 20.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3D0E8.s") + func_80A3C4E0(&spB4, &spA8, this->dyna.actor.world.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3D0FC.s") + spB4.x += this->dyna.actor.world.pos.x; + spB4.y += this->dyna.actor.world.pos.y; + spB4.z += this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/ObjVspinyroll_Update.s") + EffectSsHitMark_SpawnFixedScale(globalCtx, 3, &spB4); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_IT_SHIELD_REFLECT_SW); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/ObjVspinyroll_Draw.s") + temp_f0 = Math3D_Vec3fDistSq(&spD8, &spC0); + if (temp_f0 < temp_f20) { + temp_f20 = temp_f0; + sp9C = true; + Math_Vec3f_Diff(&spC0, &spCC, arg2); + unk_1A8->unk_1E0 = ptr; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Vspinyroll/func_80A3D2C0.s") + return sp9C; +} + +s32 func_80A3CB94(ObjVspinyroll* this, GlobalContext* globalCtx, s32 arg2) { + Vec3f sp1C; + + if (func_80A3C8D8(this, globalCtx, &sp1C, arg2)) { + this->dyna.actor.world.pos.x += sp1C.x; + this->dyna.actor.world.pos.z += sp1C.z; + return true; + } + return false; +} + +DynaPolyActor* func_80A3CBF0(ObjVspinyroll* this, GlobalContext* globalCtx) { + if (this->unk_1A8.unk_1E0 != NULL) { + return DynaPoly_GetActor(&globalCtx->colCtx, this->unk_1A8.unk_1E0->bgId); + } + return NULL; +} + +s32 func_80A3CC30(ObjVspinyroll* this, GlobalContext* globalCtx) { + DynaPolyActor* actor = func_80A3CBF0(this, globalCtx); + + if ((actor != NULL) && (Math3D_Vec3fDistSq(&actor->actor.world.pos, &actor->actor.prevPos) > 0.0001f)) { + return true; + } + return false; +} + +void func_80A3CC84(f32 arg0) { + MtxF* matrix = Matrix_GetCurrent(); + + matrix->yw += arg0; +} + +void ObjVspinyroll_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjVspinyroll* this = THIS; + s32 params = OBJVSPINYROLL_GET_4000(&this->dyna.actor); + f32 sp40 = D_80A3D450[params]; + s32 pad2; + Path* path; + Vec3s* points; + Vec3s* point1; + Vec3s* point2; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.scale.y = 0.1f * sp40; + this->dyna.actor.scale.z = 0.1f; + this->dyna.actor.uncullZoneScale = 300.0f * sp40; + this->dyna.actor.scale.x = 0.1f; + + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_spinyroll_Colheader_000F80); + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + + if (params == OBJVSPINYROLL_4000_1) { + this->dyna.actor.draw = func_80A3D2C0; + this->collider.dim.height = 240; + } + + if (OBJVSPINYROLL_GET_7F(&this->dyna.actor) == OBJVSPINYROLL_7F_7F) { + func_80A3CEC4(this); + return; + } + + this->dyna.actor.world.rot.y = 0; + func_80A3C7E8(this); + this->unk_394 = D_80A3D458[OBJVSPINYROLL_GET_380(thisx)]; + + path = &globalCtx->setupPathList[OBJVSPINYROLL_GET_7F(&this->dyna.actor)]; + points = Lib_SegmentedToVirtual(path->points); + point1 = &points[0]; + point2 = &points[1]; + + Math_Vec3s_ToVec3f(&this->unk_39C[0], point1); + Math_Vec3s_ToVec3f(&this->unk_39C[1], point2); + + Math_Vec3f_Copy(&this->dyna.actor.world.pos, &this->unk_39C[0]); + + func_80A3C6A0(this); + this->dyna.actor.shape.rot.y = this->dyna.actor.world.rot.y; + func_80A3CFAC(this); +} + +void ObjVspinyroll_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjVspinyroll* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80A3CEC4(ObjVspinyroll* this) { + this->dyna.actor.speedXZ = 0.0f; + this->actionFunc = func_80A3CEE0; +} + +void func_80A3CEE0(ObjVspinyroll* this, GlobalContext* globalCtx) { + this->unk_3C0 += 0x6E; + if (this->unk_3C0 > 0xFA0) { + this->unk_3C0 = 0xFA0; + } +} + +void func_80A3CF10(ObjVspinyroll* this) { + this->actionFunc = func_80A3CF4C; + this->unk_3C8 = D_80A3D478[OBJVSPINYROLL_GET_1C00(&this->dyna.actor)]; + this->dyna.actor.speedXZ = 0.0f; +} + +void func_80A3CF4C(ObjVspinyroll* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->unk_3C0, 0, this->unk_3C4) && (this->unk_3C8 > 0)) { + this->unk_3C8--; + if (this->unk_3C8 <= 0) { + func_80A3CFAC(this); + } + } +} + +void func_80A3CFAC(ObjVspinyroll* this) { + this->actionFunc = func_80A3CFE0; + this->unk_3C2 = D_80A3D4DC[this->unk_398]; + this->dyna.actor.speedXZ = 0.0f; +} + +void func_80A3CFE0(ObjVspinyroll* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->unk_3C0, this->unk_3C2, 0x6E)) { + func_80A3D024(this); + } +} + +void func_80A3D024(ObjVspinyroll* this) { + this->actionFunc = func_80A3D038; +} + +void func_80A3D038(ObjVspinyroll* this, GlobalContext* globalCtx) { + s32 sp24 = func_80A3C700(this); + + if (func_80A3CB94(this, globalCtx, 1)) { + this->unk_3C4 = 0x7D0; + if (func_80A3CBF0(this, globalCtx) != NULL) { + func_80A3D0E8(this); + } else { + func_80A3C6CC(this); + func_80A3CF10(this); + } + } else if (sp24 != 0) { + func_80A3C6CC(this); + this->unk_3C4 = 120; + func_80A3CF10(this); + } +} + +void func_80A3D0E8(ObjVspinyroll* this) { + this->actionFunc = func_80A3D0FC; +} + +void func_80A3D0FC(ObjVspinyroll* this, GlobalContext* globalCtx) { + s32 sp24 = true; + + Math_ScaledStepToS(&this->unk_3C0, 0, this->unk_3C4); + if (func_80A3CB94(this, globalCtx, 0) && func_80A3CC30(this, globalCtx)) { + sp24 = false; + } + + if (sp24) { + func_80A3C6CC(this); + func_80A3CF10(this); + } +} + +void ObjVspinyroll_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjVspinyroll* this = THIS; + + this->actionFunc(this, globalCtx); + + this->unk_3C6 += this->unk_3C0; + + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjVspinyroll_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjVspinyroll* this = THIS; + + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 60.0f, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + Matrix_RotateZS(this->dyna.actor.shape.rot.z + 0x4000, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x + this->unk_3C6, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Gfx_DrawDListOpa(globalCtx, object_spinyroll_DL_000460); +} + +void func_80A3D2C0(Actor* thisx, GlobalContext* globalCtx) { + ObjVspinyroll* this = THIS; + Vec3s sp3C; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + sp3C.x = this->dyna.actor.shape.rot.x + this->unk_3C6; + sp3C.y = this->dyna.actor.shape.rot.y; + sp3C.z = this->dyna.actor.shape.rot.z + 0x4000; + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 60.0f, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateYS(sp3C.y, MTXMODE_APPLY); + Matrix_RotateZS(sp3C.z, MTXMODE_APPLY); + Matrix_RotateXS(sp3C.x, MTXMODE_APPLY); + Matrix_Scale(0.1f, 0.1f, 0.1f, 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_spinyroll_DL_000460); + + func_80A3CC84(120.0f); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_spinyroll_DL_000460); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.h b/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.h index 371eb7b4f..15879f86e 100644 --- a/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.h +++ b/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.h @@ -7,11 +7,40 @@ struct ObjVspinyroll; typedef void (*ObjVspinyrollActionFunc)(struct ObjVspinyroll*, GlobalContext*); +#define OBJVSPINYROLL_GET_7F(thisx) ((thisx)->params & 0x7F) +#define OBJVSPINYROLL_GET_380(thisx) (((thisx)->params >> 7) & 7) +#define OBJVSPINYROLL_GET_1C00(thisx) (((thisx)->params >> 0xA) & 7) +#define OBJVSPINYROLL_GET_4000(thisx) (((thisx)->params >> 0xE) & 1) + +#define OBJVSPINYROLL_7F_7F 0x7F +#define OBJVSPINYROLL_4000_1 1 + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ CollisionPoly* collisionPoly; + /* 0x10 */ s32 bgId; +} ObjVspinyrollStruct2; // size = 0x14 + +typedef struct { + /* 0x000 */ ObjVspinyrollStruct2 unk_000[24]; + /* 0x1E0 */ ObjVspinyrollStruct2* unk_1E0; + /* 0x1E4 */ s32 unk_1E4; +} ObjVspinyrollStruct3; // size = 0x1E8 + typedef struct ObjVspinyroll { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x24C]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; + /* 0x01A8 */ ObjVspinyrollStruct3 unk_1A8; /* 0x0390 */ ObjVspinyrollActionFunc actionFunc; - /* 0x0394 */ char unk_394[0x38]; + /* 0x0394 */ f32 unk_394; + /* 0x0398 */ s32 unk_398; + /* 0x039C */ Vec3f unk_39C[2]; + /* 0x03B4 */ Vec3f unk_3B4; + /* 0x03C0 */ s16 unk_3C0; + /* 0x03C2 */ s16 unk_3C2; + /* 0x03C4 */ s16 unk_3C4; + /* 0x03C6 */ s16 unk_3C6; + /* 0x03C8 */ s16 unk_3C8; } ObjVspinyroll; // size = 0x3CC extern const ActorInit Obj_Vspinyroll_InitVars; 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..c676b4960 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c @@ -5,8 +5,10 @@ */ #include "z_obj_warpstone.h" +#include "objects/object_sek/object_sek.h" +#include "objects/gameplay_keep/gameplay_keep.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((ObjWarpstone*)thisx) @@ -20,10 +22,6 @@ s32 ObjWarpstone_BeginOpeningCutscene(ObjWarpstone* this, GlobalContext* globalC s32 ObjWarpstone_PlayOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx); s32 ObjWarpstone_OpenedIdle(ObjWarpstone* this, GlobalContext* globalCtx); -extern Gfx D_04023210[]; // gOwlStatueWhiteFlashDL -extern Gfx D_060001D0[]; // gOwlStatueClosedDL -extern Gfx D_06003770[]; // gOwlStatueOpenedDL - const ActorInit Obj_Warpstone_InitVars = { ACTOR_OBJ_WARPSTONE, ACTORCAT_ITEMACTION, @@ -60,7 +58,7 @@ static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 1, ICHAIN_STOP), }; -static Gfx* sOwlStatueDLs[] = { D_060001D0, D_06003770 }; +static Gfx* sOwlStatueDLs[] = { gOwlStatueClosedDL, gOwlStatueOpenedDL }; void ObjWarpstone_SetupAction(ObjWarpstone* this, ObjWarpstoneActionFunc actionFunc) { this->actionFunc = actionFunc; @@ -71,7 +69,7 @@ void ObjWarpstone_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); - Actor_SetHeight(&this->dyna.actor, 40.0f); + Actor_SetFocus(&this->dyna.actor, 40.0f); if (!OBJ_WARPSTONE_IS_ACTIVATED(OBJ_WARPSTONE_GET_ID(this))) { ObjWarpstone_SetupAction(this, ObjWarpstone_ClosedIdle); @@ -102,7 +100,7 @@ s32 ObjWarpstone_BeginOpeningCutscene(ObjWarpstone* this, GlobalContext* globalC if (this->dyna.actor.cutscene < 0 || ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); ObjWarpstone_SetupAction(this, ObjWarpstone_PlayOpeningCutscene); - Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_OWL_WARP_SWITCH_ON); + Actor_PlaySfxAtPos(&this->dyna.actor, NA_SE_EV_OWL_WARP_SWITCH_ON); } else { ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); } @@ -112,7 +110,7 @@ s32 ObjWarpstone_BeginOpeningCutscene(ObjWarpstone* this, GlobalContext* globalC s32 ObjWarpstone_PlayOpeningCutscene(ObjWarpstone* this, GlobalContext* globalCtx) { if (this->openingCSTimer++ >= OBJ_WARPSTONE_TIMER_ACTIVATE_THRESHOLD) { ActorCutscene_Stop(this->dyna.actor.cutscene); - func_80143A10(OBJ_WARPSTONE_GET_ID(this)); + Sram_ActivateOwl(OBJ_WARPSTONE_GET_ID(this)); ObjWarpstone_SetupAction(this, ObjWarpstone_OpenedIdle); } else if (this->openingCSTimer < OBJ_WARPSTONE_TIMER_OPEN_THRESHOLD) { Math_StepToF(&this->dyna.actor.velocity.x, 0.01f, 0.001f); @@ -138,24 +136,25 @@ void ObjWarpstone_Update(Actor* thisx, GlobalContext* globalCtx) { s32 pad; if (this->isTalking) { - if (func_800B867C(&this->dyna.actor, globalCtx) != 0) { + if (Actor_TextboxIsClosing(&this->dyna.actor, globalCtx)) { this->isTalking = false; - } else if ((func_80152498(&globalCtx->msgCtx) == 4) && (func_80147624(globalCtx))) { + } else if ((Message_GetState(&globalCtx->msgCtx) == 4) && Message_ShouldAdvance(globalCtx)) { if (globalCtx->msgCtx.choiceIndex != 0) { func_8019F208(); - globalCtx->msgCtx.unk11F22 = 0x4D; + globalCtx->msgCtx.msgMode = 0x4D; globalCtx->msgCtx.unk120D6 = 0; globalCtx->msgCtx.unk120D4 = 0; - gSaveContext.owlSaveLocation = OBJ_WARPSTONE_GET_ID(this); + gSaveContext.save.owlSaveLocation = OBJ_WARPSTONE_GET_ID(this); } else { func_801477B4(globalCtx); } } - } else if (func_800B84D0(&this->dyna.actor, globalCtx)) { + } else if (Actor_ProcessTalkRequest(&this->dyna.actor, &globalCtx->state)) { this->isTalking = true; } else if (!this->actionFunc(this, globalCtx)) { func_800B863C(&this->dyna.actor, globalCtx); } + Collider_ResetCylinderAC(globalCtx, &this->collider.base); Collider_UpdateCylinder(&this->dyna.actor, &this->collider); CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); @@ -163,30 +162,30 @@ void ObjWarpstone_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjWarpstone_Draw(Actor* thisx, GlobalContext* globalCtx2) { - ObjWarpstone* this = THIS; GlobalContext* globalCtx = globalCtx2; + ObjWarpstone* this = THIS; - func_800BDFC0(globalCtx, sOwlStatueDLs[this->modelIndex]); + Gfx_DrawDListOpa(globalCtx, sOwlStatueDLs[this->modelIndex]); if (this->dyna.actor.home.rot.x != 0) { OPEN_DISPS(globalCtx->state.gfxCtx); 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_InsertTranslation(0.0f, 0.0f, 30.0f, MTXMODE_APPLY); + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 34.0f, + this->dyna.actor.world.pos.z, MTXMODE_NEW); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_Translate(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); - Matrix_StatePush(); + Matrix_Push(); gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 128, 128, 255, 255, 200, this->dyna.actor.home.rot.x); gDPSetEnvColor(POLY_XLU_DISP++, 100, 200, 0, 255); - Matrix_InsertZRotation_f((((globalCtx->gameplayFrames * 1500) & 0xFFFF) * M_PI) / 0x8000, MTXMODE_APPLY); + Matrix_RotateZF((((globalCtx->gameplayFrames * 1500) & 0xFFFF) * M_PI) / 0x8000, 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_04023210); - Matrix_StatePop(); - Matrix_InsertZRotation_f((~((globalCtx->gameplayFrames * 1200) & 0xFFFF) * M_PI) / 0x8000, MTXMODE_APPLY); + gSPDisplayList(POLY_XLU_DISP++, gOwlStatueWhiteFlashDL); + Matrix_Pop(); + Matrix_RotateZF((~((globalCtx->gameplayFrames * 1200) & 0xFFFF) * M_PI) / 0x8000, 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_04023210); + gSPDisplayList(POLY_XLU_DISP++, gOwlStatueWhiteFlashDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } } diff --git a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h index 47163ec2c..37cfb99ab 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.h @@ -29,6 +29,6 @@ typedef struct ObjWarpstone { extern const ActorInit Obj_Warpstone_InitVars; #define OBJ_WARPSTONE_GET_ID(this) ((u16)(this->dyna.actor.params & 0xF)) -#define OBJ_WARPSTONE_IS_ACTIVATED(owlId) (((void)0,gSaveContext.owlActivationFlags) & (u16)gBitFlags[owlId]) +#define OBJ_WARPSTONE_IS_ACTIVATED(owlId) (((void)0, gSaveContext.save.playerData.owlActivationFlags) & (u16)gBitFlags[owlId]) #endif // Z_OBJ_WARPSTONE_H diff --git a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c index 778b78162..f72645e49 100644 --- a/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c +++ b/src/overlays/actors/ovl_Obj_Wind/z_obj_wind.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_wind.c + * Overlay: ovl_Obj_Wind + * Description: Updraft Current (STT) and Water Current (PFInterior) + */ + #include "z_obj_wind.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjWind*)thisx) diff --git a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.c b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.c index ab8df497c..34d82523f 100644 --- a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.c +++ b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.c @@ -1,48 +1,128 @@ +/* + * File: z_obj_wturn.c + * Overlay: ovl_Obj_Wturn + * Description: Stone Tower Temple Inverter + */ + #include "z_obj_wturn.h" -#define FLAGS 0x02100010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_100000 | ACTOR_FLAG_2000000) #define THIS ((ObjWturn*)thisx) void ObjWturn_Init(Actor* thisx, GlobalContext* globalCtx); void ObjWturn_Update(Actor* thisx, GlobalContext* globalCtx); +void func_808A7954(ObjWturn* this); void func_808A7968(ObjWturn* this, GlobalContext* globalCtx); +void func_808A7A24(ObjWturn* this); void func_808A7A5C(ObjWturn* this, GlobalContext* globalCtx); +void func_808A7AAC(ObjWturn* this, GlobalContext* globalCtx); void func_808A7BA0(ObjWturn* this, GlobalContext* globalCtx); +void func_808A7C04(ObjWturn* this, GlobalContext* globalCtx); void func_808A7C78(ObjWturn* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Wturn_InitVars = { - ACTOR_OBJ_WTURN, - ACTORCAT_ITEMACTION, - FLAGS, - GAMEPLAY_KEEP, - sizeof(ObjWturn), - (ActorFunc)ObjWturn_Init, - (ActorFunc)Actor_Noop, - (ActorFunc)ObjWturn_Update, - (ActorFunc)NULL, + ACTOR_OBJ_WTURN, ACTORCAT_ITEMACTION, FLAGS, + GAMEPLAY_KEEP, sizeof(ObjWturn), (ActorFunc)ObjWturn_Init, + (ActorFunc)Actor_Noop, (ActorFunc)ObjWturn_Update, (ActorFunc)NULL, }; -#endif +void ObjWturn_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjWturn* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/ObjWturn_Init.s") + func_808A7954(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7954.s") +void func_808A7954(ObjWturn* this) { + this->actionFunc = func_808A7968; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7968.s") +void func_808A7968(ObjWturn* this, GlobalContext* globalCtx) { + if (globalCtx->msgCtx.ocarinaMode >= 28 && globalCtx->msgCtx.ocarinaMode < 39) { + Flags_UnsetSwitch(globalCtx, this->actor.params); + Actor_MarkForDeath(&this->actor); + } else if ((Flags_GetSwitch(globalCtx, this->actor.params) && (globalCtx->sceneNum == SCENE_F40)) || + (!Flags_GetSwitch(globalCtx, this->actor.params) && (globalCtx->sceneNum == SCENE_F41))) { + func_808A7A24(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7A24.s") +void func_808A7A24(ObjWturn* this) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = func_808A7A5C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7A5C.s") +void func_808A7A5C(ObjWturn* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + func_808A7AAC(this, globalCtx); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7AAC.s") +void func_808A7AAC(ObjWturn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f eye; + Vec3f at; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7BA0.s") + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + func_8016566C(140); + this->camId = ActorCutscene_GetCurrentCamera(this->actor.cutscene); + func_800B7298(globalCtx, &this->actor, 21); + at.x = player->actor.focus.pos.x; + at.z = player->actor.focus.pos.z; + at.y = player->actor.focus.pos.y; + eye.x = (Math_SinS(this->actor.shape.rot.y) * 150.0f) + at.x; + eye.z = (Math_CosS(this->actor.shape.rot.y) * 150.0f) + at.z; + eye.y = at.y + 4.0f; + Play_CameraSetAtEye(globalCtx, this->camId, &at, &eye); + this->actionFunc = func_808A7BA0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7C04.s") +void func_808A7BA0(ObjWturn* this, GlobalContext* globalCtx) { + if (Math_ScaledStepToS(&this->actor.shape.rot.z, -0x8000, 0x0200)) { + func_808A7C04(this, globalCtx); + } + func_800B8FE8(&this->actor, NA_SE_EV_EARTHQUAKE - SFX_FLAG); + Play_CameraSetRoll(globalCtx, this->camId, this->actor.shape.rot.z); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/func_808A7C78.s") +void func_808A7C04(ObjWturn* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Wturn/ObjWturn_Update.s") + this->actor.world.pos.y += this->actor.playerHeightRel; + player->actor.shape.shadowAlpha = 0; + func_800B7298(globalCtx, &this->actor, 0x54); + func_800B8E58(player, NA_SE_VO_NAVY_ENEMY); + this->unk_14A = 0; + func_80165690(); + this->actionFunc = func_808A7C78; +} + +void func_808A7C78(ObjWturn* this, GlobalContext* globalCtx) { + static Vec3f D_808A7DC0 = { 0.0f, -1.0f, 0.0f }; + Camera* camera = Play_GetCamera(globalCtx, this->camId); + Player* player = GET_PLAYER(globalCtx); + + this->unk_14A++; + player->actor.world.pos.y = this->actor.world.pos.y + this->unk_14A * 4.0f; + Play_CameraSetAtEyeUp(globalCtx, this->camId, &player->actor.focus.pos, &camera->eye, &D_808A7DC0); + if (this->unk_14A == 1) { + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 3; + gSaveContext.nextCutsceneIndex = 0; + if (globalCtx->sceneNum == 0x58) { + globalCtx->nextEntranceIndex = 0xAC00; + } else { + globalCtx->nextEntranceIndex = 0xAA10; + } + globalCtx->sceneLoadFlag = 0x14; + } +} + +void ObjWturn_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjWturn* this = THIS; + + this->actionFunc(this, globalCtx); +} 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..0390ac7a8 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,8 @@ typedef void (*ObjWturnActionFunc)(struct ObjWturn*, GlobalContext*); typedef struct ObjWturn { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjWturnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ s16 camId; + /* 0x014A */ s16 unk_14A; } 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 76100efc6..7e9f6cb29 100644 --- a/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c +++ b/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_y2lift.c + * Overlay: ovl_Obj_Y2lift + * Description: Unused elevator platform + */ + #include "z_obj_y2lift.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjY2lift*)thisx) 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 be1c5f9d5..4bfced35c 100644 --- a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c +++ b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c @@ -1,6 +1,12 @@ +/* + * File: z_obj_y2shutter.c + * Overlay: ovl_Obj_Y2shutter + * Description: Pirates' Fortress sliding grate + */ + #include "z_obj_y2shutter.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((ObjY2shutter*)thisx) 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 1f63b1389..997941057 100644 --- a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c +++ b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c @@ -1,6 +1,13 @@ -#include "z_obj_yado.h" +/* + * File: z_obj_yado.c + * Overlay: ovl_Obj_Yado + * Description: Stockpot Inn - 2nd Floor Window + */ -#define FLAGS 0x00000030 +#include "z_obj_yado.h" +#include "objects/object_yado_obj/object_yado_obj.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20) #define THIS ((ObjYado*)thisx) @@ -9,7 +16,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, @@ -22,22 +28,46 @@ 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[]; +void ObjYado_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -extern UNK_TYPE D_06000430; -extern UNK_TYPE D_060012E8; + Actor_ProcessInitChain(&this->actor, sInitChain); + D_80C16470 = Lib_SegmentedToVirtual(object_yado_obj_Matanimheader_0012E8); + this->isNight = gSaveContext.save.isNight; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Init.s") +void ObjYado_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Destroy.s") +void ObjYado_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Update.s") + this->isNight = gSaveContext.save.isNight; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Draw.s") +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); + Gfx_DrawDListOpa(globalCtx, object_yado_obj_DL_000430); + Gfx_DrawDListXlu(globalCtx, object_yado_obj_DL_000320); + + 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_Obj_Yasi/z_obj_yasi.c b/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.c index c0a4f0b6a..3dfea0818 100644 --- a/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.c +++ b/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.c @@ -1,20 +1,28 @@ +/* + * File: z_obj_yasi.c + * Overlay: ovl_Obj_Yasi + * Description: Palm Tree + */ + #include "z_obj_yasi.h" +#include "objects/object_obj_yasi/object_obj_yasi.h" #define FLAGS 0x00000000 #define THIS ((ObjYasi*)thisx) +#define CAN_DROP_NUT(thisx) (thisx->params < 0) + void ObjYasi_Init(Actor* thisx, GlobalContext* globalCtx); void ObjYasi_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjYasi_Update(Actor* thisx, GlobalContext* globalCtx); void ObjYasi_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Yasi_InitVars = { ACTOR_OBJ_YASI, ACTORCAT_PROP, FLAGS, - OBJECT_OBJECT_UNSET_YASI, + OBJECT_OBJ_YASI, sizeof(ObjYasi), (ActorFunc)ObjYasi_Init, (ActorFunc)ObjYasi_Destroy, @@ -22,25 +30,72 @@ const ActorInit Obj_Yasi_InitVars = { (ActorFunc)ObjYasi_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BB4D90[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 800, ICHAIN_STOP), }; -#endif +void ObjYasi_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjYasi* this = THIS; -extern InitChainEntry D_80BB4D90[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_obj_yasi_Colheader_001428); -extern UNK_TYPE D_06000360; -extern UNK_TYPE D_06001428; + this->dyna.actor.home.rot.y = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yasi/ObjYasi_Init.s") + if (OBJYASI_IS_WIDE(thisx)) { + this->dyna.actor.scale.x = 0.2f; + this->dyna.actor.scale.z = 0.2f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yasi/ObjYasi_Destroy.s") +void ObjYasi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjYasi* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yasi/ObjYasi_Update.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yasi/ObjYasi_Draw.s") +void ObjYasi_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjYasi* this = THIS; + s16 temp; + Vec3f dropPos; + + if (this->dyna.actor.home.rot.z != 0) { + if (CAN_DROP_NUT(thisx)) { + if (Rand_ZeroOne() < 0.5f) { + dropPos.x = this->dyna.actor.world.pos.x; + dropPos.y = this->dyna.actor.world.pos.y + 280.0f; + dropPos.z = this->dyna.actor.world.pos.z; + Item_DropCollectible(globalCtx, &dropPos, ITEM00_NUTS_1); + } + } + this->dyna.actor.home.rot.y = GET_PLAYER(globalCtx)->actor.shape.rot.y; + this->dyna.actor.home.rot.x = 400; + this->dyna.actor.home.rot.z = 0; + } + temp = (s16)(this->dyna.actor.shape.rot.x * 0.1f); + this->dyna.actor.home.rot.x -= temp; + this->dyna.actor.shape.rot.x += + BINANG_SUB(this->dyna.actor.home.rot.x, (s16)(this->dyna.actor.shape.rot.x * 0.08f)); +} + +void ObjYasi_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjYasi* this = THIS; + + Matrix_Translate(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + + if (this->dyna.actor.shape.rot.x != 0) { + Matrix_RotateYS(this->dyna.actor.home.rot.y, MTXMODE_APPLY); + Matrix_RotateXS(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_RotateYS(BINANG_SUB(this->dyna.actor.shape.rot.y, this->dyna.actor.home.rot.y), MTXMODE_APPLY); + } else { + Matrix_RotateYS(this->dyna.actor.shape.rot.y, MTXMODE_APPLY); + } + + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Gfx_DrawDListOpa(globalCtx, object_obj_yasi_DL_000360); +} diff --git a/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.h b/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.h index 3671a776c..f4ab9ca9c 100644 --- a/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.h +++ b/src/overlays/actors/ovl_Obj_Yasi/z_obj_yasi.h @@ -6,10 +6,11 @@ struct ObjYasi; typedef struct ObjYasi { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x18]; + /* 0x000 */ DynaPolyActor dyna; } ObjYasi; // size = 0x15C extern const ActorInit Obj_Yasi_InitVars; +#define OBJYASI_IS_WIDE(thisx) ((thisx)->params & 1) + #endif // Z_OBJ_YASI_H 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 7cd8eab45..2f976f2cc 100644 --- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -1,6 +1,13 @@ -#include "z_object_kankyo.h" +/* + * File: z_object_kankyo.c + * Overlay: ovl_Object_Kankyo + * Description: Snow, rain in Skull Kid backstory cutscene, and bubbles deep in Pinnacle Rock + */ -#define FLAGS 0x02000030 +#include "z_object_kankyo.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((ObjectKankyo*)thisx) @@ -9,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, @@ -27,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 = (Camera_GetCamDirPitch(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 = (-Camera_GetCamDirPitch(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.sandstormState = 10; + } else { + D_801F4E30 = 0; + globalCtx->envCtx.sandstormState = 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[CAM_ID_MAIN]->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(gDust5Tex)); + } + + Matrix_Translate(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_Mult(&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 = Camera_GetWaterYPos(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[CAM_ID_MAIN]->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_Translate(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_Mult(&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(gDust5Tex)); + 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_Translate(temp_f20, temp_f22, temp_f2, MTXMODE_NEW); + + gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + Matrix_RotateYS((s16)this->unk_14C[2].unk_04 + (s16)(i << 5), MTXMODE_APPLY); + Matrix_RotateXS((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_Translate(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 18bdbf1e7..18d28f8c7 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_spot.c + * Overlay: ovl_Oceff_Spot + * Description: Sun's Song Ocarina Effect + */ + #include "z_oceff_spot.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffSpot*)thisx) 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 b287f82f3..1939b1ef0 100644 --- a/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c +++ b/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_storm.c + * Overlay: ovl_Oceff_Storm + * Description: Song of Storms Ocarina Effect + */ + #include "z_oceff_storm.h" -#define FLAGS 0x02000030 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_20 | ACTOR_FLAG_2000000) #define THIS ((OceffStorm*)thisx) 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 6b15732af..1179f5ba2 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c +++ b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe.c + * Overlay: ovl_Oceff_Wipe + * Description: Song of Time Ocarina Effect + */ + #include "z_oceff_wipe.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe*)thisx) 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 aa0adb3ca..61a1ae549 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c +++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe2.c + * Overlay: ovl_Oceff_Wipe2 + * Description: Epona's Song Ocarina Effect + */ + #include "z_oceff_wipe2.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe2*)thisx) 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 318f19291..f91385daa 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c +++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c @@ -1,6 +1,13 @@ +/* + * File: z_oceff_wipe3.c + * Overlay: ovl_Oceff_Wipe3 + * Description: Unused OoT Saria's Song Ocarina Effect + */ + +#include "prevent_bss_reordering.h" #include "z_oceff_wipe3.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe3*)thisx) 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 f7b1611f0..b985aadad 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c +++ b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe4.c + * Overlay: ovl_Oceff_Wipe4 + * Description: Scarecrow's Song Ocarina Effect + */ + #include "z_oceff_wipe4.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe4*)thisx) 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 74c7e17d3..e39a4aa4c 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c +++ b/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe5.c + * Overlay: ovl_Oceff_Wipe5 + * Description: Sonata/Lullaby/Bossa Nova/Elegy/Oath Ocarina Effect + */ + #include "z_oceff_wipe5.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe5*)thisx) 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 cefe27e50..a54ca583c 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c +++ b/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe6.c + * Overlay: ovl_Oceff_Wipe6 + * Description: Song of Soaring Ocarina Effect + */ + #include "z_oceff_wipe6.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe6*)thisx) @@ -9,7 +15,6 @@ void OceffWipe6_Destroy(Actor* thisx, GlobalContext* globalCtx); void OceffWipe6_Update(Actor* thisx, GlobalContext* globalCtx); void OceffWipe6_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Oceff_Wipe6_InitVars = { ACTOR_OCEFF_WIPE6, ACTORCAT_ITEMACTION, @@ -22,12 +27,75 @@ const ActorInit Oceff_Wipe6_InitVars = { (ActorFunc)OceffWipe6_Draw, }; -#endif +#include "overlays/ovl_Oceff_Wipe6/ovl_Oceff_Wipe6.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe6/OceffWipe6_Init.s") +void OceffWipe6_Init(Actor* thisx, GlobalContext* globalCtx) { + OceffWipe6* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe6/OceffWipe6_Destroy.s") + Actor_SetScale(&this->actor, 1.0f); + this->counter = 0; + this->actor.world.pos = GET_ACTIVE_CAM(globalCtx)->eye; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe6/OceffWipe6_Update.s") +void OceffWipe6_Destroy(Actor* thisx, GlobalContext* globalCtx) { + func_80115D5C(&globalCtx->state); + globalCtx->msgCtx.unk120B0 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Oceff_Wipe6/OceffWipe6_Draw.s") +void OceffWipe6_Update(Actor* thisx, GlobalContext* globalCtx) { + OceffWipe6* this = THIS; + + this->actor.world.pos = GET_ACTIVE_CAM(globalCtx)->eye; + if (this->counter < 100) { + this->counter++; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void OceffWipe6_Draw(Actor* thisx, GlobalContext* globalCtx) { + OceffWipe6* this = THIS; + f32 z; + u8 alpha; + s32 i; + s32 counter; + Vec3f activeCamEye; + s32 pad; + Vec3f quakeOffset; + s32 pad2; + + activeCamEye = GET_ACTIVE_CAM(globalCtx)->eye; + Camera_GetQuakeOffset(&quakeOffset, GET_ACTIVE_CAM(globalCtx)); + + if (this->counter < 32) { + counter = this->counter; + z = Math_SinS(counter * 0x200) * 1220.0f; + } else { + z = 1220.0f; + } + + if (this->counter >= 80) { + alpha = 12 * (100 - this->counter); + } else { + alpha = 255; + } + + for (i = 1; i < ARRAY_COUNT(gOceff6Vtx); i += 2) { + gOceff6Vtx[i].v.cn[3] = alpha; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Translate(activeCamEye.x + quakeOffset.x, activeCamEye.y + quakeOffset.y, activeCamEye.z + quakeOffset.z, + MTXMODE_NEW); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Matrix_ReplaceRotation(&globalCtx->billboardMtxF); + Matrix_RotateXS(0x708, MTXMODE_APPLY); + Matrix_Translate(0.0f, 0.0f, -z, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + AnimatedMat_Draw(globalCtx, ovl_Oceff_Wipe6_Matanimheader_000338); + gSPDisplayList(POLY_XLU_DISP++, gOceff6DL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.h b/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.h index 0b845e133..c37e3f9d4 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.h +++ b/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.h @@ -7,7 +7,7 @@ struct OceffWipe6; typedef struct OceffWipe6 { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ s16 counter; } OceffWipe6; // size = 0x148 extern const ActorInit Oceff_Wipe6_InitVars; 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 c1151dd94..da295b768 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c +++ b/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c @@ -1,6 +1,12 @@ +/* + * File: z_oceff_wipe7.c + * Overlay: ovl_Oceff_Wipe7 + * Description: Song of Healing Ocarina Effect + */ + #include "z_oceff_wipe7.h" -#define FLAGS 0x02000010 +#define FLAGS (ACTOR_FLAG_10 | ACTOR_FLAG_2000000) #define THIS ((OceffWipe7*)thisx) 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_Shot_Sun/z_shot_sun.c b/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c index 73aa5ac9f..38acb813e 100644 --- a/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c +++ b/src/overlays/actors/ovl_Shot_Sun/z_shot_sun.c @@ -1,6 +1,12 @@ +/* + * File: z_shot_sun.c + * Overlay: ovl_Shot_Sun + * Description: + */ + #include "z_shot_sun.h" -#define FLAGS 0x00000009 +#define FLAGS (ACTOR_FLAG_1 | ACTOR_FLAG_8) #define THIS ((ShotSun*)thisx) 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 94ec87a4b..51a2fa695 100644 --- a/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c +++ b/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c @@ -1,6 +1,12 @@ +/* + * File: z_tg_sw.c + * Overlay: ovl_TG_Sw + * Description: Skulltula spider bonk detector + */ + #include "z_tg_sw.h" -#define FLAGS 0x00000010 +#define FLAGS (ACTOR_FLAG_10) #define THIS ((TGSw*)thisx) @@ -34,7 +40,7 @@ void TGSw_ActionDecider(TGSw* this, GlobalContext* globalCtx) { scaledAbsoluteRotY = ABS_ALT(this->actor.world.rot.y) * 4.0f; scaledAbsoluteRotZ = ABS_ALT(this->actor.world.rot.z) * 4.0f; - if ((scaledAbsoluteRotZ < this->actor.xzDistToPlayer) || (scaledAbsoluteRotY < this->actor.yDistToPlayer)) { + if ((scaledAbsoluteRotZ < this->actor.xzDistToPlayer) || (scaledAbsoluteRotY < this->actor.playerHeightRel)) { return; } unk1F4 = globalCtx->actorCtx.unk1F4; @@ -50,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; } @@ -65,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..bc3e3c1e8 --- /dev/null +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -0,0 +1,1302 @@ +/* + * 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; + +void Player_Init(Actor* thisx, GlobalContext* globalCtx); +void Player_Destroy(Actor* thisx, GlobalContext* globalCtx); +void Player_Update(Actor* thisx, GlobalContext* globalCtx); +void Player_Draw(Actor* thisx, GlobalContext* globalCtx); + +#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/Player_Init.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/Player_Update.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/Player_Draw.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/Player_Destroy.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_En_Ice_Block/z_eff_en_ice_block.c b/src/overlays/effects/ovl_Effect_En_Ice_Block/z_eff_en_ice_block.c index 62c56c04b..a2449af92 100644 --- a/src/overlays/effects/ovl_Effect_En_Ice_Block/z_eff_en_ice_block.c +++ b/src/overlays/effects/ovl_Effect_En_Ice_Block/z_eff_en_ice_block.c @@ -1,31 +1,85 @@ /* * File: z_eff_en_ice_block.c * Overlay: ovl_Effect_En_Ice_Block - * Description: + * Description: Ice Shard (Pentagon shaped) thrown off of the Obj_Iceblock actor during growth animation + * Object Requirement: OBJECT_ICE_BLOCK */ #include "z_eff_en_ice_block.h" +#include "objects/object_ice_block/object_ice_block.h" #define PARAMS ((EffectEnIceBlockInitParams*)initParamsx) -s32 EffectEnIceBlock_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectEnIceBlock_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectEnIceBlock_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectEnIceBlock_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_En_Ice_Block_InitVars = { EFFECT_EN_ICE_BLOCK, EffectEnIceBlock_Init, }; -#endif +#define rObjId regs[0] +#define rScale regs[1] +#define rRot regs[2] +#define rRotVel regs[3] -extern UNK_TYPE D_06000A38; +u32 EffectEnIceBlock_CheckIceBlockObject(EffectSs* this, GlobalContext* globalCtx) { + if (((this->rObjId = Object_GetIndex(&globalCtx->objectCtx, OBJECT_ICE_BLOCK)) < 0) || + (!Object_IsLoaded(&globalCtx->objectCtx, this->rObjId))) { + this->life = -1; + this->draw = NULL; + return false; + } else { + return true; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_En_Ice_Block/func_80A22D40.s") +u32 EffectEnIceBlock_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectEnIceBlockInitParams* params = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_En_Ice_Block/EffectEnIceBlock_Init.s") + Math_Vec3f_Copy(&this->pos, ¶ms->pos); + Math_Vec3f_Copy(&this->velocity, ¶ms->velocity); + Math_Vec3f_Copy(&this->accel, ¶ms->accel); + this->rScale = params->scale; + this->rRot = Rand_ZeroOne() * 65535.0f; + this->rRotVel = (s32)(Rand_ZeroOne() * 512.0f) + 0x400; + this->life = 40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_En_Ice_Block/EffectEnIceBlock_Draw.s") + this->draw = EffectEnIceBlock_Draw; + this->update = EffectEnIceBlock_Update; + EffectEnIceBlock_CheckIceBlockObject(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_En_Ice_Block/EffectEnIceBlock_Update.s") + return 1; +} + +void EffectEnIceBlock_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + s32 pad; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + if (EffectEnIceBlock_CheckIceBlockObject(this, globalCtx)) { + f32 scale = this->rScale * 0.1f * 0.01f; + + OPEN_DISPS(gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x06, + globalCtx->objectCtx.status[this->rObjId].segment); // object: OBJECT_ICE_BLOCK + + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Mult(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_RotateZS(this->rRot, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, &gIceBlockShardEffectDL); + + CLOSE_DISPS(gfxCtx); + } +} + +void EffectEnIceBlock_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + this->rRot += this->rRotVel; + EffectEnIceBlock_CheckIceBlockObject(this, globalCtx); +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c b/src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c index d18f57bb7..6627e1c87 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c +++ b/src/overlays/effects/ovl_Effect_Ss_Bubble/z_eff_ss_bubble.c @@ -5,23 +5,103 @@ */ #include "z_eff_ss_bubble.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rScale regs[0] +#define rVecAdjX regs[1] +#define rVecAdjZ regs[2] #define PARAMS ((EffectSsBubbleInitParams*)initParamsx) -s32 EffectSsBubble_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsBubble_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsBubble_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsBubble_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Bubble_InitVars = { EFFECT_SS_BUBBLE, EffectSsBubble_Init, }; -#endif +static f32 sVecAdjMaximums[] = { 291.0f, 582.0f, 1600.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Bubble/EffectSsBubble_Init.s") +u32 EffectSsBubble_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsBubbleInitParams* initParams = (EffectSsBubbleInitParams*)initParamsx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Bubble/EffectSsBubble_Draw.s") + { + TexturePtr tex = (Rand_ZeroOne() < 0.5f) ? gEffBubble1Tex : gEffBubble2Tex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Bubble/EffectSsBubble_Update.s") + this->gfx = VIRTUAL_TO_PHYSICAL(SEGMENTED_TO_VIRTUAL(tex)); + } + + this->pos.x = ((Rand_ZeroOne() - 0.5f) * initParams->xzPosRandScale) + initParams->pos.x; + this->pos.y = (((Rand_ZeroOne() - 0.5f) * initParams->yPosRandScale) + initParams->yPosOffset) + initParams->pos.y; + this->pos.z = ((Rand_ZeroOne() - 0.5f) * initParams->xzPosRandScale) + initParams->pos.z; + Math_Vec3f_Copy(&this->vec, &this->pos); + this->life = 1; + this->rScale = (((Rand_ZeroOne() * 0.5f) + 1.0f) * initParams->scale) * 100.0f; + this->draw = EffectSsBubble_Draw; + this->update = EffectSsBubble_Update; + + return 1; +} + +void EffectSsBubble_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + f32 scale = this->rScale / 100.0f; + + OPEN_DISPS(gfxCtx); + + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 150, 150, 150, 0); + gSPSegment(POLY_OPA_DISP++, 0x08, this->gfx); + gSPDisplayList(POLY_OPA_DISP++, gEffBubbleDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsBubble_Update(GlobalContext* globalCtx2, u32 index, EffectSs* this) { + WaterBox* waterBox; + f32 waterSurfaceY = this->pos.y; + Vec3f ripplePos; + GlobalContext* globalCtx = globalCtx2; + + if (!WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->pos.x, this->pos.z, &waterSurfaceY, &waterBox)) { + this->life = -1; + return; + } + if (waterSurfaceY < this->pos.y) { + ripplePos.x = this->pos.x; + ripplePos.y = waterSurfaceY; + ripplePos.z = this->pos.z; + EffectSsGRipple_Spawn(globalCtx, &ripplePos, 0, 80, 0); + this->life = -1; + label: + return; + } + if (((globalCtx->gameplayFrames + index) % 8) == 0) { + CollisionPoly* colPoly; + u32 speed; + s16 direction; + f32 rVecAdjMax; + + BgCheck_EntityRaycastFloor2_1(globalCtx, &globalCtx->colCtx, &colPoly, &this->pos); + speed = SurfaceType_GetConveyorSpeed(&globalCtx->colCtx, colPoly, BGCHECK_SCENE); + if ((speed != 0) && !SurfaceType_GetConveyorType(&globalCtx->colCtx, colPoly, BGCHECK_SCENE)) { + direction = SurfaceType_GetConveyorDirection(&globalCtx->colCtx, colPoly, BGCHECK_SCENE) << 0xA; + rVecAdjMax = sVecAdjMaximums[speed - 1]; + this->rVecAdjX = Math_SinS(direction) * rVecAdjMax; + this->rVecAdjZ = Math_CosS(direction) * rVecAdjMax; + } + } + this->vec.x += this->rVecAdjX / 100.0f; + this->vec.z += this->rVecAdjZ / 100.0f; + this->pos.x = ((Rand_ZeroOne() * 0.5f) - 0.25f) + this->vec.x; + this->accel.y = (Rand_ZeroOne() - 0.3f) * 0.2f; + this->pos.z = (Rand_ZeroOne() * 0.5f - 0.25f) + this->vec.z; + this->life++; +} 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..a345f0b5c 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 @@ -6,52 +6,369 @@ #include "z_eff_ss_kakera.h" +#define rReg0 regs[0] +#define rGravity regs[1] +#define rPitch regs[2] +#define rYaw regs[3] +#define rReg4 regs[4] +#define rReg5 regs[5] +#define rReg6 regs[6] +#define rScale regs[7] +#define rReg8 regs[8] +#define rReg9 regs[9] +#define rObjId regs[10] +#define rObjBankIndex regs[11] +#define rColorIndex regs[12] + #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 EffectSsKakera_CheckForObject(EffectSs* this, GlobalContext* globalCtx); + const EffectSsInit Effect_Ss_Kakera_InitVars = { EFFECT_SS_KAKERA, EffectSsKakera_Init, }; -#endif +KakeraColorStruct D_8097EAD8[] = { + { 0, { 255, 255, 255 } }, + { 0, { 235, 170, 130 } }, + { 1, { 210, 190, 170 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Init.s") +f32 D_8097EAE4[] = { 1.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097DE30.s") +u32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsKakeraInitParams* initParams = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Draw.s") + this->pos = initParams->pos; + this->velocity = initParams->velocity; + this->life = initParams->life; + this->priority = 101; + if (initParams->dList != NULL) { + this->gfx = initParams->dList; + switch (initParams->objId) { + case GAMEPLAY_KEEP: + case GAMEPLAY_FIELD_KEEP: + case GAMEPLAY_DANGEON_KEEP: + this->rObjId = KAKERA_OBJECT_DEFAULT; + break; + default: + this->rObjId = initParams->objId; + EffectSsKakera_CheckForObject(this, globalCtx); + break; + } + } else { + __assert("../z_eff_kakera.c", 193); + } + this->draw = EffectSsKakera_Draw; + this->update = EffectSsKakera_Update; + this->vec = initParams->unk_18; + this->rReg0 = initParams->unk_2C; + this->rGravity = initParams->gravity; + this->rPitch = Rand_ZeroOne() * 0x8000; + this->rYaw = Rand_ZeroOne() * 0x8000; + this->rReg4 = initParams->unk_26; + this->rReg5 = initParams->unk_28; + this->rReg6 = initParams->unk_2A; + this->rScale = initParams->scale; + this->rReg8 = initParams->unk_30; + this->rReg9 = initParams->unk_32; + this->rColorIndex = initParams->colorIdx; + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E130.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/func_8097E19C.s") +void EffectSsKakera_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s16 pad; + f32 scale = this->rScale / 256.0f; + s32 colorIndex = this->rColorIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E34C.s") + OPEN_DISPS(gfxCtx); + if (this->rObjId != KAKERA_OBJECT_DEFAULT) { + if ((((this->rReg4 >> 7) & 1) << 7) == 0x80) { + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[this->rObjBankIndex].segment); + } else { + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->rObjBankIndex].segment); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E368.s") + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_RotateYS(this->rYaw, MTXMODE_APPLY); + Matrix_RotateXS(this->rPitch, MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E384.s") + if ((((this->rReg4 >> 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_8097E3C0.s") +void EffectSsKakera_CheckForObject(EffectSs* this, GlobalContext* globalCtx) { + this->rObjBankIndex = Object_GetIndex(&globalCtx->objectCtx, this->rObjId); + if ((this->rObjBankIndex < 0) || (!Object_IsLoaded(&globalCtx->objectCtx, this->rObjBankIndex))) { + this->life = 0; + this->draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E400.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_8097E420.s") + temp_f18 = this->rReg5 / 1024.0f; + temp_f20 = this->rReg6 / 1024.0f; + range = (this->rReg9 / 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_8097E4B0.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_8097E4F0.s") +f32 func_8097E368(f32 arg0, s32 arg1) { + return 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E584.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_8097E660.s") +f32 func_8097E3C0(f32 arg0, s32 index) { + f32 square = SQ(arg0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E698.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_8097E7E0.s") +f32 func_8097E400(f32 arg0, s32 index) { + return func_8097E3C0(arg0, index); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Update.s") +s32 func_8097E420(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB0C[] = { 0.05f, 1.0f }; + f32 phi_f0; + s32 index = this->rReg0 & 3; + + 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 true; +} + +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->rReg0 >> 2) & 7; + + if (index != 0) { + this->accel.y += D_8097EB14[index]; + } + return true; +} + +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->rReg0 >> 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 true; +} + +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->rReg0 >> 7) & 0xF; + center = D_8097EB3C[index](distance, index); + rand = func_8097DE30(center, (this->rReg9 * 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 true; +} + +s32 func_8097E660(EffectSs* this, Vec3f* diff, f32 distance) { + this->accel.y += this->rGravity / 256.0f; + return true; +} + +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->rReg0 != 0) { + if (!func_8097E420(this, &diff, distance)) { + return false; + } + if (!func_8097E4B0(this, &diff, distance)) { + return false; + } + if (!func_8097E4F0(this, &diff, distance)) { + return false; + } + if (!func_8097E584(this, &diff, distance)) { + return false; + } + } + if (!func_8097E660(this, &diff, distance)) { + 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->rReg8 == 0) { + if ((((this->rReg4 >> 4) & 1) << 4) == (1 << 4)) { + if (this->pos.y <= (player->actor.floorHeight - ((this->rReg4 >> 2) & 3))) { + this->rReg9 = 0; + this->rReg0 = 0; + this->rReg4 &= ~0x60; + this->accel.x = this->accel.y = this->accel.z = 0.0f; + this->velocity.x = this->velocity.y = this->velocity.z = 0.0f; + this->rReg5 = this->rReg9; + this->rGravity = this->rReg9; + } + } else { + if (this->pos.y <= ((player->actor.floorHeight - ((this->rReg4 >> 2) & 3)) - 600.0f)) { + this->life = 0; + } + } + } else { + switch (this->rReg4 & 3) { + case 0: + this->rReg8 = 0; + break; + case 1: + if ((this->velocity.y < 0.0f) && + (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->rReg4 >> 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->rReg8 > 0) { + this->rReg8--; + } + } + break; + case 2: + if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->rReg4 >> 2) & 3])) { + this->rReg8 = 0; + } + break; + } + } +} + +void EffectSsKakera_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + switch (((this->rReg4 >> 5) & 3) << 5) { + case 0x20: + this->rPitch += 0x47B; + this->rYaw += 0x139; + break; + case 0x40: + this->rPitch += 0x1A7C; + this->rYaw += 0x47B; + break; + case 0x60: + this->rPitch += 0x3F27; + this->rYaw += 0xCA1; + break; + } + func_8097E19C(this); + if (!func_8097E698(this)) { + this->life = 0; + } + func_8097E7E0(this, globalCtx); + if (this->rObjId != KAKERA_OBJECT_DEFAULT) { + EffectSsKakera_CheckForObject(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_Kirakira/z_eff_ss_kirakira.c b/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.c index b78891a2e..4c7c01ca3 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.c +++ b/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.c @@ -1,33 +1,159 @@ /* * File: z_eff_ss_kirakira.c * Overlay: ovl_Effect_Ss_Kirakira - * Description: + * Description: Sparkles */ #include "z_eff_ss_kirakira.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rRotSpeed regs[0] +#define rYaw regs[1] +#define rPrimColorR regs[2] +#define rPrimColorG regs[3] +#define rPrimColorB regs[4] +#define rPrimColorA regs[5] +#define rEnvColorR regs[6] +#define rEnvColorG regs[7] +#define rEnvColorB regs[8] +#define rEnvColorA regs[9] +#define rAlphaStep regs[10] +#define rScale regs[11] +#define rLifespan regs[12] #define PARAMS ((EffectSsKirakiraInitParams*)initParamsx) -s32 EffectSsKirakira_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsKirakira_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void func_80977DB4(GlobalContext* globalCtx, u32 index, EffectSs* this); void func_80977E6C(GlobalContext* globalCtx, u32 index, EffectSs* this); void func_80977F28(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsKirakira_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Kirakira_InitVars = { EFFECT_SS_KIRAKIRA, EffectSsKirakira_Init, }; -#endif +u32 EffectSsKirakira_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsKirakiraInitParams* initParams = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kirakira/EffectSsKirakira_Init.s") + this->pos = initParams->pos; + this->velocity = initParams->velocity; + this->accel = initParams->accel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kirakira/EffectSsKirakira_Draw.s") + if ((this->life = initParams->life) < 0) { + this->life = -this->life; + this->gfx = gEffSparklesDL; + this->update = func_80977F28; + this->rEnvColorA = initParams->scale; + this->rScale = 0; + } else { + this->gfx = gEffSparklesDL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kirakira/func_80977DB4.s") + if (initParams->updateMode == 0) { + this->update = func_80977DB4; + } else { + this->update = func_80977E6C; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kirakira/func_80977E6C.s") + this->rEnvColorA = initParams->envColor.a; + this->rScale = initParams->scale; + if (this->rScale < 0) { + this->gfx = gameplay_keep_DL_06A800; + this->rScale = -this->rScale; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kirakira/func_80977F28.s") + this->draw = EffectSsKirakira_Draw; + this->rRotSpeed = initParams->rotSpeed; + this->rYaw = initParams->yaw; + this->rPrimColorR = initParams->primColor.r; + this->rPrimColorG = initParams->primColor.g; + this->rPrimColorB = initParams->primColor.b; + this->rPrimColorA = initParams->primColor.a; + this->rEnvColorR = initParams->envColor.r; + this->rEnvColorG = initParams->envColor.g; + this->rEnvColorB = initParams->envColor.b; + this->rAlphaStep = initParams->alphaStep; + this->rLifespan = initParams->life; + + return 1; +} + +void EffectSsKirakira_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx; + f32 scale = this->rScale / 10000.0f; + s32 pad; + MtxF mfTrans; + MtxF mfRot; + MtxF mfScale; + MtxF mfTransBillboard; + MtxF mfTransBillboardRot; + MtxF mfResult; + Mtx* mtx; + + gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z); + SkinMatrix_SetRotateRPY(&mfRot, 0, 0, this->rYaw); + SkinMatrix_SetScale(&mfScale, scale, scale, 1.0f); + SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->billboardMtxF, &mfTransBillboard); + SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfRot, &mfTransBillboardRot); + SkinMatrix_MtxFMtxFMult(&mfTransBillboardRot, &mfScale, &mfResult); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult); + + if (mtx != NULL) { + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(gfxCtx); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, + (((s8)((55.0f / this->rLifespan) * this->life) + 200))); + gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA); + gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + gSPDisplayList(POLY_XLU_DISP++, this->gfx); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + } + + CLOSE_DISPS(gfxCtx); +} + +void func_80977DB4(GlobalContext* globalCtx, u32 index, EffectSs* this) { + this->accel.x = (Rand_ZeroOne() * 0.4f) - 0.2f; + this->accel.z = (Rand_ZeroOne() * 0.4f) - 0.2f; + this->rEnvColorA += this->rAlphaStep; + + if (this->rEnvColorA < 0) { + this->rEnvColorA = 0; + this->rAlphaStep = -this->rAlphaStep; + } else if (this->rEnvColorA > 255) { + this->rEnvColorA = 255; + this->rAlphaStep = -this->rAlphaStep; + } + + this->rYaw += this->rRotSpeed; +} + +void func_80977E6C(GlobalContext* globalCtx, u32 index, EffectSs* this) { + this->velocity.x *= 0.95f; + this->velocity.z *= 0.95f; + this->accel.x = randPlusMinusPoint5Scaled(0.2f); + this->accel.z = randPlusMinusPoint5Scaled(0.2f); + this->rEnvColorA += this->rAlphaStep; + + if (this->rEnvColorA < 0) { + this->rEnvColorA = 0; + this->rAlphaStep = -this->rAlphaStep; + } else if (this->rEnvColorA > 255) { + this->rEnvColorA = 255; + this->rAlphaStep = -this->rAlphaStep; + } + + this->rYaw += this->rRotSpeed; +} + +void func_80977F28(GlobalContext* globalCtx, u32 index, EffectSs* this) { + this->rScale = this->rEnvColorA * Math_SinS((32768.0f / this->rLifespan) * this->life); +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.h b/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.h index c3020f590..66e73e0a5 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.h +++ b/src/overlays/effects/ovl_Effect_Ss_Kirakira/z_eff_ss_kirakira.h @@ -15,7 +15,7 @@ typedef struct { /* 0x34 */ s16 rotSpeed; /* 0x36 */ s16 yaw; /* 0x38 */ u8 updateMode; -} EffectSsKiraKiraInitParams; // size = 0x3C +} EffectSsKirakiraInitParams; // size = 0x3C extern const EffectSsInit Effect_Ss_Kirakira_InitVars; diff --git a/src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.c b/src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.c index ad2ef29a5..15fdcfc50 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.c +++ b/src/overlays/effects/ovl_Effect_Ss_Lightning/z_eff_ss_lightning.c @@ -1,29 +1,157 @@ /* * File: z_eff_ss_lightning.c * Overlay: ovl_Effect_Ss_Lightning - * Description: + * Description: Electric Discharge */ #include "z_eff_ss_lightning.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rPrimColorR regs[0] +#define rPrimColorG regs[1] +#define rPrimColorB regs[2] +#define rPrimColorA regs[3] +#define rEnvColorR regs[4] +#define rEnvColorG regs[5] +#define rEnvColorB regs[6] +#define rEnvColorA regs[7] +#define rNumBolts regs[8] +#define rScale regs[9] +#define rYaw regs[10] +#define rLifespan regs[11] #define PARAMS ((EffectSsLightningInitParams*)initParamsx) -s32 EffectSsLightning_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsLightning_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsLightning_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsLightning_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 +TexturePtr sLightningTextures[] = { + gEffLightning1Tex, gEffLightning2Tex, gEffLightning3Tex, gEffLightning4Tex, + gEffLightning5Tex, gEffLightning6Tex, gEffLightning7Tex, gEffLightning8Tex, +}; + const EffectSsInit Effect_Ss_Lightning_InitVars = { EFFECT_SS_LIGHTNING, EffectSsLightning_Init, }; -#endif +static s32 sIsDesegmented = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Lightning/EffectSsLightning_Init.s") +u32 EffectSsLightning_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsLightningInitParams* initParams = PARAMS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Lightning/func_8097A794.s") + this->pos = initParams->pos; + this->gfx = gEffLightningDL; + this->life = initParams->life; + this->draw = EffectSsLightning_Draw; + this->update = EffectSsLightning_Update; + this->rPrimColorR = initParams->primColor.r; + this->rPrimColorG = initParams->primColor.g; + this->rPrimColorB = initParams->primColor.b; + this->rPrimColorA = initParams->primColor.a; + this->rEnvColorR = initParams->envColor.r; + this->rEnvColorG = initParams->envColor.g; + this->rEnvColorB = initParams->envColor.b; + this->rEnvColorA = initParams->envColor.a; + this->rNumBolts = initParams->numBolts; + this->rScale = initParams->scale; + this->rYaw = initParams->yaw; + this->rLifespan = initParams->life; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Lightning/EffectSsLightning_Draw.s") + if (!sIsDesegmented) { + for (i = 0; i < ARRAY_COUNT(sLightningTextures); i++) { + sLightningTextures[i] = Lib_SegmentedToVirtual(sLightningTextures[i]); + } + sIsDesegmented = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Lightning/EffectSsLightning_Update.s") + return 1; +} + +void EffectSsLightning_NewLightning(GlobalContext* globalCtx, Vec3f* pos, s32 yaw, EffectSs* this) { + EffectSs newLightning; + + EffectSS_Delete(&newLightning); + newLightning = *this; + newLightning.pos = *pos; + newLightning.rNumBolts--; + newLightning.rYaw = yaw; + newLightning.life = newLightning.rLifespan; + + EffectSS_Copy(globalCtx, &newLightning); +} + +void EffectSsLightning_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + MtxF mfResult; + MtxF mfTrans; + MtxF mfScale; + MtxF mfRot; + MtxF mfTransBillboard; + MtxF mfTransBillboardRot; + Mtx* mtx; + f32 yScale; + s32 texIndex; + f32 xzScale; + + OPEN_DISPS(gfxCtx); + + yScale = this->rScale * 0.01f; + texIndex = this->rLifespan - this->life; + + if (texIndex >= ARRAY_COUNT(sLightningTextures)) { + texIndex = ARRAY_COUNT(sLightningTextures) - 1; + } + + SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z); + xzScale = yScale * 0.6f; + SkinMatrix_SetScale(&mfScale, xzScale, yScale, xzScale); + SkinMatrix_SetRotateRPY(&mfRot, this->vec.x, this->vec.y, this->rYaw); + SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->billboardMtxF, &mfTransBillboard); + SkinMatrix_MtxFMtxFMult(&mfTransBillboard, &mfRot, &mfTransBillboardRot); + SkinMatrix_MtxFMtxFMult(&mfTransBillboardRot, &mfScale, &mfResult); + + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &mfResult); + + if (mtx != NULL) { + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C9BC(gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, sLightningTextures[texIndex]); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, + this->rPrimColorA); + gDPSetEnvColor(POLY_XLU_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA); + gSPDisplayList(POLY_XLU_DISP++, this->gfx); + } + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsLightning_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + s32 pad; + Vec3f pos; + s32 yaw; + f32 scale; + s32 sign; + + if ((this->rNumBolts != 0) && ((this->life + 1) == this->rLifespan)) { + sign = (Rand_ZeroOne() < 0.5f) ? -1 : 1; + yaw = this->rYaw + sign * ((s32)((Rand_ZeroOne() * 3640.0f)) + 0xE38); + scale = (this->rScale * 0.01f) * 80.0f; + + pos.y = this->pos.y + (Math_SinS(this->rYaw - 0x4000) * scale); + + scale = Math_CosS(this->rYaw - 0x4000) * scale; + pos.x = this->pos.x - (Math_CosS(Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx))) * scale); + pos.z = this->pos.z + (Math_SinS(Camera_GetInputDirYaw(GET_ACTIVE_CAM(globalCtx))) * scale); + + EffectSsLightning_NewLightning(globalCtx, &pos, yaw, this); + + if (Rand_ZeroOne() < 0.1f) { + EffectSsLightning_NewLightning(globalCtx, &pos, (this->rYaw * 2) - yaw, this); + } + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c index b09dca014..2e8646a54 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c +++ b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.c @@ -1,30 +1,208 @@ /* * File: z_eff_ss_sbn.c * Overlay: ovl_Effect_Ss_Sbn - * Description: + * Description: Popped Deku Bubble + * + * Note: The gfx field is used to store the colPoly, not anything gfx related + * This is not a problem since gfx is already void* */ #include "z_eff_ss_sbn.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rScrollStep regs[0] +#define rScroll regs[1] +#define rTexIndex regs[2] +#define rAlpha regs[3] +#define rReg4 regs[4] +#define rReg4Step regs[5] +#define rRotAngle regs[6] +#define rScale regs[7] +#define rReg8 regs[8] #define PARAMS ((EffectSsSbnInitParams*)initParamsx) -s32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsSbn_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); -void func_80AC8ECC(GlobalContext* globalCtx, u32 index, EffectSs* this); -void func_80AC9164(GlobalContext* globalCtx, u32 index, EffectSs* this); +void EffectSsSbn_DrawSliding(GlobalContext* globalCtx, u32 index, EffectSs* this); +void EffectSsSbn_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Sbn_InitVars = { EFFECT_SS_SBN, EffectSsSbn_Init, }; -#endif +static TexturePtr sSlidingTextures[] = { + gEffPoppedDekuBubbleSliding1Tex, gEffPoppedDekuBubbleSliding2Tex, gEffPoppedDekuBubbleSliding3Tex, + gEffPoppedDekuBubbleSliding4Tex, gEffPoppedDekuBubbleSliding5Tex, gEffPoppedDekuBubbleSliding6Tex, + gEffPoppedDekuBubbleSliding7Tex, gEffPoppedDekuBubbleSliding8Tex, gEffPoppedDekuBubbleSliding9Tex, + gEffPoppedDekuBubbleSliding10Tex, gEffPoppedDekuBubbleSliding11Tex, gEffPoppedDekuBubbleSliding12Tex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/EffectSsSbn_Init.s") +static TexturePtr sTextures[] = { + gEffPoppedDekuBubble1Tex, gEffPoppedDekuBubble2Tex, gEffPoppedDekuBubble3Tex, + gEffPoppedDekuBubble4Tex, gEffPoppedDekuBubble5Tex, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/func_80AC8ECC.s") +u32 EffectSsSbn_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsSbnInitParams* initParams = PARAMS; + CollisionPoly* colPoly; + MtxF mtx; + Vec3f normal; + Vec3f colPolyVec; + Vec3f bubbleVec; + f32 angle; + f32 opposite; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/func_80AC9164.s") + Math_Vec3f_Copy(&this->pos, &initParams->pos); + Math_Vec3f_Copy(&this->velocity, &gZeroVec3f); + Math_Vec3f_Copy(&this->accel, &gZeroVec3f); + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sbn/EffectSsSbn_Update.s") + this->gfx = initParams->colPoly; + + this->rScroll = 0; + this->rScrollStep = 7; + this->rTexIndex = 0; + this->rAlpha = 200; + this->rReg4 = 250; + this->rReg4Step = 30; + + this->rScale = randPlusMinusPoint5Scaled(100.0f) + (initParams->scale * 120.0f); + if (this->rScale < 600) { + this->rScale = 600; + } else if (this->rScale > 1500) { + this->rScale = 1500; + } + + this->rReg8 = 1000; + this->rRotAngle = 0; + this->life = 93; + this->draw = EffectSsSbn_DrawSliding; + this->update = EffectSsSbn_Update; + + if (this->gfx != NULL) { + colPoly = this->gfx; + func_800C0094(colPoly, this->pos.x, this->pos.y, this->pos.z, &mtx); + normal.x = COLPOLY_GET_NORMAL(colPoly->normal.x); + normal.y = COLPOLY_GET_NORMAL(colPoly->normal.y); + normal.z = COLPOLY_GET_NORMAL(colPoly->normal.z); + if ((normal.y > 0.95f) || (normal.y < -0.95f)) { + this->draw = EffectSsSbn_Draw; + return 1; + } + if (normal.y > 0.05f) { + colPolyVec.x = normal.x * 10.0f; + colPolyVec.y = (-(SQ(normal.x) + SQ(normal.z)) * 10.0f) / normal.y; + colPolyVec.z = normal.z * 10.0f; + } else if (normal.y < -0.05f) { + colPolyVec.x = -normal.x * 10.0f; + colPolyVec.y = (-(SQ(normal.x) + SQ(normal.z)) * 10.0f) / -normal.y; + colPolyVec.z = -normal.z * 10.0f; + } else { + colPolyVec.x = 0.0f; + colPolyVec.y = -10.0f; + colPolyVec.z = 0.0f; + } + bubbleVec.x = -mtx.mf[2][0] * 10.0f; + bubbleVec.y = -mtx.mf[2][1] * 10.0f; + bubbleVec.z = -mtx.mf[2][2] * 10.0f; + Math3D_AngleBetweenVectors(&colPolyVec, &bubbleVec, &angle); + + opposite = (SQ(angle) >= 1.0f) ? 0.0f : sqrtf(1.0f - SQ(angle)); + if (((mtx.mf[0][0] * colPolyVec.x) + (mtx.mf[0][1] * colPolyVec.y) + (mtx.mf[0][2] * colPolyVec.z)) < 0.0f) { + this->rRotAngle = Math_FAtan2F(angle, opposite); + } else { + this->rRotAngle = -Math_FAtan2F(angle, opposite); + } + } + + return 1; +} + +void EffectSsSbn_DrawSliding(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + MtxF mtx; + f32 scale = this->rScale * 0.001f; + s32 pad; + + func_800C0094(this->gfx, this->pos.x, this->pos.y, this->pos.z, &mtx); + SkinMatrix_MulYRotation(&mtx, this->rRotAngle); + Matrix_Mult(&mtx, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); + + OPEN_DISPS(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(gfxCtx); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->rAlpha); + + if (this->rTexIndex < ARRAY_COUNT(sSlidingTextures)) { + { + TexturePtr tex = sSlidingTextures[this->rTexIndex]; + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(tex)); + } + this->rTexIndex++; + this->rScroll += this->rScrollStep; + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffPoppedDekuBubbleSliding12Tex)); + if ((this->rScrollStep >= 2) && ((globalCtx->state.frames % 2) == 0)) { + this->rScrollStep--; + } + this->rScroll += this->rScrollStep; + } + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, this->rScroll, 0x20, 0x20)); + gSPDisplayList(POLY_XLU_DISP++, gEffPoppedDekuBubbleSlidingDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSbn_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + MtxF mtx; + f32 scale = this->rScale * 0.001f; + + func_800C0094(this->gfx, this->pos.x, this->pos.y, this->pos.z, &mtx); + SkinMatrix_MulYRotation(&mtx, this->rRotAngle); + Matrix_Mult(&mtx, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_Scale(0.05f, 0.05f, 0.05f, MTXMODE_APPLY); + + OPEN_DISPS(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(gfxCtx); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_XLU_DECAL2); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->rAlpha); + + if (this->rTexIndex < ARRAY_COUNT(sTextures)) { + { + TexturePtr tex = sTextures[this->rTexIndex]; + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(tex)); + } + this->rTexIndex++; + } else { + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gEffPoppedDekuBubble5Tex)); + } + gSPDisplayList(POLY_XLU_DISP++, gEffPoppedDekuBubbleDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSbn_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + if (this->life < 10) { + this->rAlpha -= 20; + } else if (this->life >= 45) { + if (this->life < 85) { + this->rReg8 += 12; + this->rReg4 -= this->rReg4Step; + } else { + this->rReg8 = 1000; + } + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h index 40c3d693c..439ef88a0 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h +++ b/src/overlays/effects/ovl_Effect_Ss_Sbn/z_eff_ss_sbn.h @@ -4,8 +4,10 @@ #include "global.h" typedef struct { - char unk_0[UNK_SIZE]; -} EffectSsSbnInitParams; // size = ? + /* 0x00 */ Vec3f pos; + /* 0x0C */ CollisionPoly* colPoly; + /* 0x10 */ f32 scale; +} EffectSsSbnInitParams; // size = 0x14 extern const EffectSsInit Effect_Ss_Sbn_InitVars; diff --git a/src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c b/src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c index 6d2d4c6dd..5d30ecf04 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c +++ b/src/overlays/effects/ovl_Effect_Ss_Sibuki/z_eff_ss_sibuki.c @@ -5,23 +5,117 @@ */ #include "z_eff_ss_sibuki.h" +#include "objects/gameplay_keep/gameplay_keep.h" + +#define rPrimColorR regs[0] +#define rPrimColorG regs[1] +#define rPrimColorB regs[2] +#define rPrimColorA regs[3] +#define rEnvColorR regs[4] +#define rEnvColorG regs[5] +#define rEnvColorB regs[6] +#define rEnvColorA regs[7] +#define rMoveDelay regs[8] +#define rDirection regs[9] +#define rScale regs[10] #define PARAMS ((EffectSsSibukiInitParams*)initParamsx) -s32 EffectSsSibuki_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsSibuki_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsSibuki_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsSibuki_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Sibuki_InitVars = { EFFECT_SS_SIBUKI, EffectSsSibuki_Init, }; -#endif +u32 EffectSsSibuki_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsSibukiInitParams* initParams = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sibuki/EffectSsSibuki_Init.s") + this->pos = initParams->pos; + this->velocity = initParams->velocity; + this->accel = initParams->accel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sibuki/EffectSsSibuki_Draw.s") + { + TexturePtr tex = (KREG(2) != 0) ? gEffBubble2Tex : gEffBubble1Tex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Sibuki/EffectSsSibuki_Update.s") + this->gfx = VIRTUAL_TO_PHYSICAL(SEGMENTED_TO_VIRTUAL(tex)); + } + + this->life = ((s32)((Rand_ZeroOne() * (500.0f + KREG(64))) * 0.01f)) + KREG(65) + 10; + this->rMoveDelay = initParams->moveDelay + 1; + this->draw = EffectSsSibuki_Draw; + this->update = EffectSsSibuki_Update; + this->rDirection = initParams->direction; + this->rScale = initParams->scale; + this->rPrimColorR = 100; + this->rPrimColorG = 100; + this->rPrimColorB = 100; + this->rPrimColorA = 100; + this->rEnvColorR = 255; + this->rEnvColorG = 255; + this->rEnvColorB = 255; + this->rEnvColorA = 255; + + return 1; +} + +void EffectSsSibuki_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + f32 scale = this->rScale / 100.0f; + + OPEN_DISPS(gfxCtx); + + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(gfxCtx); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->rPrimColorR, this->rPrimColorG, this->rPrimColorB, this->rPrimColorA); + gDPSetEnvColor(POLY_OPA_DISP++, this->rEnvColorR, this->rEnvColorG, this->rEnvColorB, this->rEnvColorA); + gSPSegment(POLY_OPA_DISP++, 0x08, this->gfx); + gSPDisplayList(POLY_OPA_DISP++, gEffBubbleDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsSibuki_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + Player* player = GET_PLAYER(globalCtx); + s32 pad[2]; + f32 xzVelScale; + + if (this->pos.y <= player->actor.floorHeight) { + this->life = 0; + } + + if (this->rMoveDelay != 0) { + this->rMoveDelay--; + + if (this->rMoveDelay == 0) { + s16 yaw = Camera_GetInputDirYaw(Play_GetCamera(globalCtx, CAM_ID_MAIN)); + + xzVelScale = ((200.0f + KREG(20)) * 0.01f) + ((0.1f * Rand_ZeroOne()) * (KREG(23) + 20.0f)); + + if (this->rDirection != 0) { + xzVelScale *= -1.0f; + } + + this->velocity.x = Math_CosS(yaw) * xzVelScale; + this->velocity.z = -Math_SinS(yaw) * xzVelScale; + + this->velocity.y = ((700.0f + KREG(21)) * 0.01f) + ((0.1f * Rand_ZeroOne()) * (KREG(24) + 20.0f)); + this->accel.y = ((-100.0f + KREG(22)) * 0.01f) + ((0.1f * Rand_ZeroOne()) * KREG(25)); + + if (KREG(3) != 0) { + this->velocity.x *= (KREG(3) * 0.01f); + this->velocity.y *= (KREG(3) * 0.01f); + this->velocity.z *= (KREG(3) * 0.01f); + this->accel.y *= (KREG(4) * 0.01f); + } + } + } else { + if (this->rScale != 0) { + this->rScale = (this->rScale - KREG(26)) - 3; + } + } +} 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..adca90668 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,62 @@ /* * 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 rObjBankIndex regs[0] +#define rYaw regs[1] #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* initParams = PARAMS; + Vec3f pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stick/EffectSsStick_Init.s") + this->rObjBankIndex = Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_KEEP); + pos = initParams->pos; + this->pos = pos; + this->vec = pos; + this->rYaw = initParams->yaw; + this->velocity.x = Math_SinS(initParams->yaw) * 6.0f; + this->velocity.z = Math_CosS(initParams->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_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(0.01f, 0.0025f, 0.01f, MTXMODE_APPLY); + Matrix_RotateZYX(0, this->rYaw, 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->rObjBankIndex].segment); + gSPSegment(POLY_OPA_DISP++, 0x0C, D_801C0850); + gSPDisplayList(POLY_OPA_DISP++, gDekuStickDL); + + 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/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c b/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c index 714ce0b8c..abcd52393 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c +++ b/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.c @@ -5,23 +5,78 @@ */ #include "z_eff_ss_stone1.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define PARAMS ((EffectSsStone1InitParams*)initParamsx) -s32 EffectSsStone1_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +#define rReg0 regs[0] + +u32 EffectSsStone1_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsStone1_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsStone1_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Stone1_InitVars = { EFFECT_SS_STONE1, EffectSsStone1_Init, }; -#endif +typedef struct { + /* 0x00 */ TexturePtr texture; + /* 0x04 */ Color_RGBA8 primColor; + /* 0x08 */ Color_RGBA8 envColor; +} EffStoneDrawInfo; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stone1/EffectSsStone1_Init.s") +static EffStoneDrawInfo sDrawInfo[] = { + { gEffStone8Tex, { 200, 0, 0, 255 }, { 0, 0, 0, 255 } }, + { gEffStone7Tex, { 255, 100, 0, 255 }, { 100, 0, 0, 255 } }, + { gEffStone6Tex, { 255, 200, 0, 255 }, { 200, 0, 0, 255 } }, + { gEffStone5Tex, { 255, 255, 0, 255 }, { 255, 0, 0, 255 } }, + { gEffStone4Tex, { 255, 255, 150, 255 }, { 255, 150, 0, 255 } }, + { gEffStone3Tex, { 255, 255, 255, 255 }, { 255, 255, 0, 255 } }, + { gEffStone2Tex, { 255, 255, 255, 255 }, { 0, 255, 0, 255 } }, + { gEffStone1Tex, { 255, 255, 255, 255 }, { 0, 255, 255, 255 } }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stone1/EffectSsStone1_Draw.s") +u32 EffectSsStone1_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsStone1InitParams* initParams = PARAMS; + Vec3f pos = initParams->pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stone1/EffectSsStone1_Update.s") + this->pos = pos; + this->vec = pos; + this->life = 8; + this->rReg0 = initParams->reg0; + this->draw = EffectSsStone1_Draw; + this->update = EffectSsStone1_Update; + + return 1; +} + +void EffectSsStone1_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + EffStoneDrawInfo* drawParams = &sDrawInfo[this->life]; + Vec3f mfVec; + f32 mfW; + f32 scale; + + OPEN_DISPS(gfxCtx); + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &this->pos, &mfVec, &mfW); + scale = (mfW < 1500.0f) ? 3.0f : (mfW / 1500.0f) * 3.0f; + Matrix_Translate(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C9BC(gfxCtx); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(drawParams->texture)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, drawParams->primColor.r, drawParams->primColor.g, drawParams->primColor.b, + 255); + gDPSetEnvColor(POLY_XLU_DISP++, drawParams->envColor.r, drawParams->envColor.g, drawParams->envColor.b, 255); + gSPDisplayList(POLY_XLU_DISP++, gEffStoneDL); + + CLOSE_DISPS(gfxCtx); +} + +void EffectSsStone1_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + if ((this->life == 6) && (this->rReg0 != 0)) { + iREG(50) = 0; + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h b/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h index 566811a8a..365585a8e 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h +++ b/src/overlays/effects/ovl_Effect_Ss_Stone1/z_eff_ss_stone1.h @@ -5,7 +5,7 @@ typedef struct { /* 0x00 */ Vec3f pos; - /* 0x00 */ s32 unk_C; + /* 0x0C */ s32 reg0; } EffectSsStone1InitParams; // size = 0x10 extern const EffectSsInit Effect_Ss_Stone1_InitVars; diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c index 9069a6aca..df16aae5b 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[] = { @@ -70,11 +70,11 @@ void Daytelop_Update(DaytelopContext* this, GameState* gameState) { this->transitionCountdown--; if (this->transitionCountdown == 0) { - if (gSaveContext.day < 9) { + if (gSaveContext.save.day < 9) { gSaveContext.gameMode = 0; } else { gSaveContext.nextCutsceneIndex = 0xFFF6; - gSaveContext.day = 1; + gSaveContext.save.day = 1; } { @@ -83,7 +83,7 @@ void Daytelop_Update(DaytelopContext* this, GameState* gameState) { } SET_NEXT_GAMESTATE(&this->state, Play_Init, GlobalContext); - gSaveContext.time = CLOCK_TIME(6, 0); + gSaveContext.save.time = CLOCK_TIME(6, 0); D_801BDBC8 = 0xFE; } else if (this->transitionCountdown == 90) { this->fadeInState = DAYTELOP_HOURSTEXT_FADEIN; @@ -132,7 +132,7 @@ void Daytelop_Draw(DaytelopContext* this) { OPEN_DISPS(gfxCtx); func_8012C628(this->state.gfxCtx); - if (gSaveContext.day >= 9) { + if (gSaveContext.save.day >= 9) { // Draw a white screen gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); @@ -145,12 +145,12 @@ void Daytelop_Draw(DaytelopContext* this) { gDPSetRenderMode(POLY_OPA_DISP++, G_RM_OPA_SURF, G_RM_OPA_SURF2); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); - if (gSaveContext.day >= 9) { + if (gSaveContext.save.day >= 9) { gDPSetAlphaCompare(POLY_OPA_DISP++, G_AC_NONE); } // Draw the left side of the "Dawn of" texture - if (gSaveContext.day < 9) { + if (gSaveContext.save.day < 9) { gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayLeftTextures[CURRENT_DAY - 1], G_IM_FMT_I, 128, 64, 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); @@ -163,7 +163,7 @@ void Daytelop_Draw(DaytelopContext* this) { 0x0400, 0x0400); // Draw the right side of the "Dawn of" texture - if (gSaveContext.day < 9) { + if (gSaveContext.save.day < 9) { gDPLoadTextureBlock_4b(POLY_OPA_DISP++, sDayRightTextures[CURRENT_DAY - 1], G_IM_FMT_I, 128, 64, 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); @@ -176,7 +176,7 @@ void Daytelop_Draw(DaytelopContext* this) { 0x0400, 0x0400); // Draw the "Hours left" texture - if (gSaveContext.day < 9) { + if (gSaveContext.save.day < 9) { gDPPipeSync(POLY_OPA_DISP++); gDPSetRenderMode(POLY_OPA_DISP++, G_RM_XLU_SURF, G_RM_XLU_SURF2); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->alpha); @@ -193,7 +193,7 @@ void Daytelop_Draw(DaytelopContext* this) { void Daytelop_Main(GameState* thisx) { DaytelopContext* this = (DaytelopContext*)thisx; - func_8012CF0C(this->state.gfxCtx, 1, 1, 0, 0, 0); + func_8012CF0C(this->state.gfxCtx, true, true, 0, 0, 0); OPEN_DISPS(this->state.gfxCtx); gSPSegment(POLY_OPA_DISP++, 0x09, this->daytelopStaticFile); @@ -226,7 +226,7 @@ void Daytelop_Init(GameState* thisx) { DaytelopContext* this = (DaytelopContext*)thisx; Game_SetFramerateDivisor(thisx, 1); - Matrix_StateAlloc(thisx); + Matrix_Init(thisx); ShrinkWindow_Destroy(); View_Init(&this->view, thisx->gfxCtx); thisx->main = Daytelop_Main; @@ -234,9 +234,9 @@ void Daytelop_Init(GameState* thisx) { this->transitionCountdown = 140; this->fadeInState = DAYTELOP_HOURSTEXT_OFF; - if (gSaveContext.day < 9) { - if (gSaveContext.day == 0) { - func_80143AC4(); + if (gSaveContext.save.day < 9) { + if (gSaveContext.save.day == 0) { + Sram_ClearFlagsAtDawnOfTheFirstDay(); } Sram_IncrementDay(); } diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.h b/src/overlays/gamestates/ovl_daytelop/z_daytelop.h index eca743850..d77a5f334 100644 --- a/src/overlays/gamestates/ovl_daytelop/z_daytelop.h +++ b/src/overlays/gamestates/ovl_daytelop/z_daytelop.h @@ -1,5 +1,5 @@ -#ifndef _Z64_DAYTELOP_H_ -#define _Z64_DAYTELOP_H_ +#ifndef Z64_DAYTELOP_H +#define Z64_DAYTELOP_H #include "global.h" diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose.h b/src/overlays/gamestates/ovl_file_choose/z_file_choose.h index d2e71587d..78c4a9a62 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_choose.h +++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose.h @@ -1,12 +1,12 @@ -#ifndef _Z64_FILE_CHOOSE_H_ -#define _Z64_FILE_CHOOSE_H_ +#ifndef Z64_FILE_CHOOSE_H +#define Z64_FILE_CHOOSE_H #include "global.h" void FileChoose_Init(GameState* thisx); void FileChoose_Destroy(GameState* thisx); -typedef struct { +typedef struct FileChooseContext { /* 0x00000 */ GameState state; /* 0x000A4 */ Vtx* unk_A4; /* 0x000A8 */ u8* staticSegment; @@ -21,23 +21,35 @@ typedef struct { /* 0x242E0 */ EnvironmentContext envCtx; /* 0x243E0 */ Vtx* unk_243E0; /* 0x243E4 */ Vtx* unk_243E4; - /* 0x243E8 */ Vtx* unk_243E8; - /* 0x243EC */ Vtx* unk_243EC; - /* 0x243F0 */ Vtx* unk_243F0; - /* 0x243F4 */ u8 newf[6][4]; - /* 0x2440C */ u16 unk_2440C[4]; - /* 0x24414 */ u8 unk_24414[8][4]; - /* 0x24434 */ s16 healthCapacity[4]; - /* 0x2443C */ s16 health[4]; - /* 0x24444 */ u32 unk_24444[4]; - /* 0x24454 */ s8 unk_24454[4]; - /* 0x24458 */ u16 unk_24458[4]; - /* 0x24460 */ s16 unk_24460[4]; - /* 0x24468 */ u8 unk_24468[4]; - /* 0x2446C */ s16 rupees[4]; - /* 0x24474 */ u8 unk_24474[4]; - /* 0x24478 */ u8 unk_24478[4]; - /* 0x2447C */ u8 unk_2447C[4]; + /* 0x243E8 */ u8 newf2[2][6]; + /* 0x243F4 */ u8 newf[2][6]; + /* 0x24400 */ UNK_TYPE1 unk_24400[0xC]; + /* 0x2440C */ u16 unk_2440C[2]; + /* 0x24410 */ u16 unk_24410[2]; + /* 0x24414 */ u8 unk_24414[2][8]; // playername + /* 0x24424 */ u8 unk_24424[2][8]; // playername + /* 0x24434 */ s16 healthCapacity[2]; + /* 0x24438 */ u16 unk_24438[2]; + /* 0x2443C */ s16 health[2]; + /* 0x24440 */ u16 unk_24440[2]; + /* 0x24444 */ u32 unk_24444[2]; + /* 0x2444C */ u32 unk_2444C[2]; + /* 0x24454 */ s8 unk_24454[2]; + /* 0x24456 */ u8 unk_24456[2]; + /* 0x24458 */ u16 unk_24458[2]; + /* 0x2445C */ u16 unk_2445C[2]; + /* 0x24460 */ s16 unk_24460[2]; + /* 0x24464 */ s16 unk_24464[2]; + /* 0x24468 */ u8 unk_24468[2]; + /* 0x2446A */ u8 unk_2446A[2]; + /* 0x2446C */ s16 rupees[2]; + /* 0x24470 */ s16 unk_24470[2]; + /* 0x24474 */ s8 unk_24474[2]; + /* 0x24476 */ s8 unk_24476[2]; + /* 0x24478 */ s8 maskCount[2]; + /* 0x2447A */ s8 unk_2447A[2]; + /* 0x2447C */ s8 heartPieceCount[2]; + /* 0x2447E */ s8 unk_2447E[2]; /* 0x24480 */ s16 unk_24480; /* 0x24482 */ s16 unk_24482; /* 0x24484 */ s16 unk_24484; @@ -50,7 +62,7 @@ typedef struct { /* 0x24492 */ s16 unk_24492[3]; /* 0x24498 */ s16 unk_24498; /* 0x2449A */ s16 unk_2449A[6]; - /* 0x244A6 */ s16 unk_244A6; + /* 0x244A6 */ s16 fileNum; /* 0x244A8 */ s16 unk_244A8; /* 0x244AA */ s16 unk_244AA; /* 0x244AC */ s16 unk_244AC; @@ -101,4 +113,13 @@ typedef struct { /* 0x24550 */ s16 unk_24550; } FileChooseContext; // size = 0x24558 +// TODO: Confirm those values has the same meaning as their OoT counterparts +typedef enum { + /* 0x00 */ PAUSE_0, // PAUSE_ITEM + /* 0x01 */ PAUSE_1, // PAUSE_MAP + /* 0x02 */ PAUSE_2, // PAUSE_QUEST + /* 0x03 */ PAUSE_3, // PAUSE_EQUIP + /* 0x04 */ PAUSE_4 // PAUSE_WORLD_MAP +} PauseMenuPage; + #endif diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c index 91293528a..ea1ed9eed 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c +++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose_80807940.c @@ -12,7 +12,9 @@ extern UNK_TYPE D_0102A6B0; extern UNK_TYPE D_0102B170; extern UNK_TYPE D_010310F0; extern UNK_TYPE D_010311F0; -extern UNK_TYPE D_0E0002E0; + +// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file +extern GfxMasterList D_0E000000; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80807940.s") diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c b/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c index 2e116dd6b..ad9ca6ccf 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c +++ b/src/overlays/gamestates/ovl_file_choose/z_file_choose_NES.c @@ -12,7 +12,9 @@ extern UNK_TYPE D_0102A6B0; extern UNK_TYPE D_0102B170; extern UNK_TYPE D_010310F0; extern UNK_TYPE D_010311F0; -extern UNK_TYPE D_0E0002E0; + +// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file +extern GfxMasterList D_0E000000; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_8080BC20.s") diff --git a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c index 65d528464..6612d9728 100644 --- a/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c +++ b/src/overlays/gamestates/ovl_file_choose/z_file_nameset_NES.c @@ -12,7 +12,9 @@ extern UNK_TYPE D_0102A6B0; extern UNK_TYPE D_0102B170; extern UNK_TYPE D_010310F0; extern UNK_TYPE D_010311F0; -extern UNK_TYPE D_0E0002E0; + +// there are uses of D_0E000000.fillRect (appearing as D_0E0002E0) in this file +extern GfxMasterList D_0E000000; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_file_choose/func_80804010.s") diff --git a/src/overlays/gamestates/ovl_opening/z_opening.c b/src/overlays/gamestates/ovl_opening/z_opening.c index 96fe615fc..c705cb708 100644 --- a/src/overlays/gamestates/ovl_opening/z_opening.c +++ b/src/overlays/gamestates/ovl_opening/z_opening.c @@ -13,21 +13,21 @@ void Opening_SetupForTitleCutscene(OpeningContext* this) { gSaveContext.eventInf[1] &= (u8)~0x80; gSaveContext.gameMode = 1; - func_80144890(); + Sram_InitNewSave(); - gSaveContext.entranceIndex = openingEntrances[D_801BB12C]; - gSaveContext.nextCutsceneIndex = gSaveContext.cutscene = openingCutscenes[D_801BB12C]; + gSaveContext.save.entranceIndex = openingEntrances[D_801BB12C]; + gSaveContext.nextCutsceneIndex = gSaveContext.save.cutscene = openingCutscenes[D_801BB12C]; gSaveContext.sceneSetupIndex = 0; - gSaveContext.time = CLOCK_TIME(8, 0); - gSaveContext.day = 1; + gSaveContext.save.time = CLOCK_TIME(8, 0); + gSaveContext.save.day = 1; { GameState* thisx = &this->gameState; thisx->running = false; } SET_NEXT_GAMESTATE(&this->gameState, Play_Init, GlobalContext); - gSaveContext.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; } void func_80803EA0(OpeningContext* this) { @@ -37,7 +37,7 @@ void func_80803EA0(OpeningContext* this) { void Opening_Main(GameState* thisx) { OpeningContext* this = (OpeningContext*)thisx; - func_8012CF0C(this->gameState.gfxCtx, 0, 1, 0, 0, 0); + func_8012CF0C(this->gameState.gfxCtx, false, true, 0, 0, 0); Opening_SetupForTitleCutscene(this); func_80803EA0(this); } @@ -50,15 +50,15 @@ void Opening_Init(GameState* thisx) { OpeningContext* this = (OpeningContext*)thisx; Game_SetFramerateDivisor(&this->gameState, 1); - Matrix_StateAlloc(&this->gameState); + Matrix_Init(&this->gameState); ShrinkWindow_Init(); View_Init(&this->view, this->gameState.gfxCtx); this->gameState.main = Opening_Main; this->gameState.destroy = Opening_Destroy; gSaveContext.respawnFlag = 0; - gSaveContext.respawn[4].entranceIndex = 0xFF; - gSaveContext.respawn[5].entranceIndex = 0xFF; - gSaveContext.respawn[6].entranceIndex = 0xFF; - gSaveContext.respawn[7].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_GORON].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_ZORA].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_DEKU].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_HUMAN].entranceIndex = 0xFF; } diff --git a/src/overlays/gamestates/ovl_select/z_select.c b/src/overlays/gamestates/ovl_select/z_select.c index d58f7ac85..53dbc266f 100644 --- a/src/overlays/gamestates/ovl_select/z_select.c +++ b/src/overlays/gamestates/ovl_select/z_select.c @@ -5,7 +5,7 @@ */ #include "z_select.h" -#include "alloca.h" +#include "libc/alloca.h" #include "overlays/gamestates/ovl_title/z_title.h" void Select_LoadTitle(SelectContext* this) { @@ -33,26 +33,26 @@ void Select_LoadGame(SelectContext* this, u32 entranceIndex, s32 opt) { gSaveContext.unk_3F24 = 0; Audio_QueueSeqCmd(NA_BGM_STOP); - gSaveContext.entranceIndex = entranceIndex; + gSaveContext.save.entranceIndex = entranceIndex; if (opt != 0) { - gSaveContext.entranceIndex = - Entrance_CreateIndex((s32)gSaveContext.entranceIndex >> 9, opt, gSaveContext.entranceIndex & 0xF); + gSaveContext.save.entranceIndex = + Entrance_CreateIndex((s32)gSaveContext.save.entranceIndex >> 9, opt, gSaveContext.save.entranceIndex & 0xF); } - if (gSaveContext.entranceIndex == 0xC000) { - gSaveContext.day = 0; - gSaveContext.time = CLOCK_TIME(6, 0) - 1; + if (gSaveContext.save.entranceIndex == 0xC000) { + gSaveContext.save.day = 0; + gSaveContext.save.time = CLOCK_TIME(6, 0) - 1; } - gSaveContext.respawn[0].entranceIndex = 0xFFFF; - gSaveContext.seqIndex = 0xFF; + gSaveContext.respawn[RESTART_MODE_DOWN].entranceIndex = 0xFFFF; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; gSaveContext.showTitleCard = true; gSaveContext.respawnFlag = 0; - gSaveContext.respawn[4].entranceIndex = 0xFF; - gSaveContext.respawn[5].entranceIndex = 0xFF; - gSaveContext.respawn[6].entranceIndex = 0xFF; - gSaveContext.respawn[7].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_GORON].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_ZORA].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_DEKU].entranceIndex = 0xFF; + gSaveContext.respawn[RESPAWN_MODE_HUMAN].entranceIndex = 0xFF; D_801BDBB0 = 0; do { @@ -382,78 +382,78 @@ void Select_UpdateMenu(SelectContext* this) { } if (CHECK_BTN_ALL(controller1->press.button, BTN_B)) { - playerForm = gSaveContext.playerForm - 1; + playerForm = gSaveContext.save.playerForm - 1; if (playerForm < PLAYER_FORM_FIERCE_DEITY) { playerForm = PLAYER_FORM_HUMAN; } - gSaveContext.playerForm = playerForm; + gSaveContext.save.playerForm = playerForm; } if (CHECK_BTN_ALL(controller1->press.button, BTN_Z)) { - if (gSaveContext.cutscene == 0x8000) { - gSaveContext.cutscene = 0; - } else if (gSaveContext.cutscene == 0) { - gSaveContext.cutscene = 0x8800; - } else if (gSaveContext.cutscene == 0x8800) { - gSaveContext.cutscene = 0xFFF0; - } else if (gSaveContext.cutscene == 0xFFF0) { - gSaveContext.cutscene = 0xFFF1; - } else if (gSaveContext.cutscene == 0xFFF1) { - gSaveContext.cutscene = 0xFFF2; - } else if (gSaveContext.cutscene == 0xFFF2) { - gSaveContext.cutscene = 0xFFF3; - } else if (gSaveContext.cutscene == 0xFFF3) { - gSaveContext.cutscene = 0xFFF4; - } else if (gSaveContext.cutscene == 0xFFF4) { - gSaveContext.cutscene = 0xFFF5; - } else if (gSaveContext.cutscene == 0xFFF5) { - gSaveContext.cutscene = 0xFFF6; - } else if (gSaveContext.cutscene == 0xFFF6) { - gSaveContext.cutscene = 0xFFF7; - } else if (gSaveContext.cutscene == 0xFFF7) { - gSaveContext.cutscene = 0xFFF8; - } else if (gSaveContext.cutscene == 0xFFF8) { - gSaveContext.cutscene = 0xFFF9; - } else if (gSaveContext.cutscene == 0xFFF9) { - gSaveContext.cutscene = 0xFFFA; - } else if (gSaveContext.cutscene == 0xFFFA) { - gSaveContext.cutscene = 0x8000; + if (gSaveContext.save.cutscene == 0x8000) { + gSaveContext.save.cutscene = 0; + } else if (gSaveContext.save.cutscene == 0) { + gSaveContext.save.cutscene = 0x8800; + } else if (gSaveContext.save.cutscene == 0x8800) { + gSaveContext.save.cutscene = 0xFFF0; + } else if (gSaveContext.save.cutscene == 0xFFF0) { + gSaveContext.save.cutscene = 0xFFF1; + } else if (gSaveContext.save.cutscene == 0xFFF1) { + gSaveContext.save.cutscene = 0xFFF2; + } else if (gSaveContext.save.cutscene == 0xFFF2) { + gSaveContext.save.cutscene = 0xFFF3; + } else if (gSaveContext.save.cutscene == 0xFFF3) { + gSaveContext.save.cutscene = 0xFFF4; + } else if (gSaveContext.save.cutscene == 0xFFF4) { + gSaveContext.save.cutscene = 0xFFF5; + } else if (gSaveContext.save.cutscene == 0xFFF5) { + gSaveContext.save.cutscene = 0xFFF6; + } else if (gSaveContext.save.cutscene == 0xFFF6) { + gSaveContext.save.cutscene = 0xFFF7; + } else if (gSaveContext.save.cutscene == 0xFFF7) { + gSaveContext.save.cutscene = 0xFFF8; + } else if (gSaveContext.save.cutscene == 0xFFF8) { + gSaveContext.save.cutscene = 0xFFF9; + } else if (gSaveContext.save.cutscene == 0xFFF9) { + gSaveContext.save.cutscene = 0xFFFA; + } else if (gSaveContext.save.cutscene == 0xFFFA) { + gSaveContext.save.cutscene = 0x8000; } } else if (CHECK_BTN_ALL(controller1->press.button, BTN_R)) { - if (gSaveContext.cutscene == 0x8000) { - gSaveContext.cutscene = 0xFFFA; - } else if (gSaveContext.cutscene == 0) { - gSaveContext.cutscene = 0x8000; - } else if (gSaveContext.cutscene == 0x8800) { - gSaveContext.cutscene = 0; - } else if (gSaveContext.cutscene == 0xFFF0) { - gSaveContext.cutscene = 0x8800; - } else if (gSaveContext.cutscene == 0xFFF1) { - gSaveContext.cutscene = 0xFFF0; - } else if (gSaveContext.cutscene == 0xFFF2) { - gSaveContext.cutscene = 0xFFF1; - } else if (gSaveContext.cutscene == 0xFFF3) { - gSaveContext.cutscene = 0xFFF2; - } else if (gSaveContext.cutscene == 0xFFF4) { - gSaveContext.cutscene = 0xFFF3; - } else if (gSaveContext.cutscene == 0xFFF5) { - gSaveContext.cutscene = 0xFFF4; - } else if (gSaveContext.cutscene == 0xFFF6) { - gSaveContext.cutscene = 0xFFF5; - } else if (gSaveContext.cutscene == 0xFFF7) { - gSaveContext.cutscene = 0xFFF6; - } else if (gSaveContext.cutscene == 0xFFF8) { - gSaveContext.cutscene = 0xFFF7; - } else if (gSaveContext.cutscene == 0xFFF9) { - gSaveContext.cutscene = 0xFFF8; - } else if (gSaveContext.cutscene == 0xFFFA) { - gSaveContext.cutscene = 0xFFF9; + if (gSaveContext.save.cutscene == 0x8000) { + gSaveContext.save.cutscene = 0xFFFA; + } else if (gSaveContext.save.cutscene == 0) { + gSaveContext.save.cutscene = 0x8000; + } else if (gSaveContext.save.cutscene == 0x8800) { + gSaveContext.save.cutscene = 0; + } else if (gSaveContext.save.cutscene == 0xFFF0) { + gSaveContext.save.cutscene = 0x8800; + } else if (gSaveContext.save.cutscene == 0xFFF1) { + gSaveContext.save.cutscene = 0xFFF0; + } else if (gSaveContext.save.cutscene == 0xFFF2) { + gSaveContext.save.cutscene = 0xFFF1; + } else if (gSaveContext.save.cutscene == 0xFFF3) { + gSaveContext.save.cutscene = 0xFFF2; + } else if (gSaveContext.save.cutscene == 0xFFF4) { + gSaveContext.save.cutscene = 0xFFF3; + } else if (gSaveContext.save.cutscene == 0xFFF5) { + gSaveContext.save.cutscene = 0xFFF4; + } else if (gSaveContext.save.cutscene == 0xFFF6) { + gSaveContext.save.cutscene = 0xFFF5; + } else if (gSaveContext.save.cutscene == 0xFFF7) { + gSaveContext.save.cutscene = 0xFFF6; + } else if (gSaveContext.save.cutscene == 0xFFF8) { + gSaveContext.save.cutscene = 0xFFF7; + } else if (gSaveContext.save.cutscene == 0xFFF9) { + gSaveContext.save.cutscene = 0xFFF8; + } else if (gSaveContext.save.cutscene == 0xFFFA) { + gSaveContext.save.cutscene = 0xFFF9; } } - gSaveContext.isNight = false; - if (gSaveContext.cutscene == 0x8800) { - gSaveContext.isNight = true; + gSaveContext.save.isNight = false; + if (gSaveContext.save.cutscene == 0x8800) { + gSaveContext.save.isNight = true; } if (CHECK_BTN_ALL(controller1->press.button, BTN_CUP)) { @@ -464,14 +464,14 @@ void Select_UpdateMenu(SelectContext* this) { } if (CHECK_BTN_ALL(controller1->press.button, BTN_CLEFT)) { - if (gSaveContext.day > 1) { - gSaveContext.day--; + if (gSaveContext.save.day > 1) { + gSaveContext.save.day--; } } if (CHECK_BTN_ALL(controller1->press.button, BTN_CRIGHT)) { - if (gSaveContext.day < 4) { - gSaveContext.day++; + if (gSaveContext.save.day < 4) { + gSaveContext.save.day++; } } @@ -723,19 +723,19 @@ void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csI case 0: // clang-format off // "Afternoon-jara" - gSaveContext.time = CLOCK_TIME(12, 0); stage = "\x8Dオヒル\x8Cジャラ"; + gSaveContext.save.time = CLOCK_TIME(12, 0); stage = "\x8Dオヒル\x8Cジャラ"; // clang-format on break; case 0x8000: // clang-format off // "Morning-jara" - gSaveContext.time = CLOCK_TIME(6, 0) + 1; stage = "\x8Dアサ \x8Cジャラ"; + gSaveContext.save.time = CLOCK_TIME(6, 0) + 1; stage = "\x8Dアサ \x8Cジャラ"; // clang-format on break; case 0x8800: - gSaveContext.time = CLOCK_TIME(18, 1); + gSaveContext.save.time = CLOCK_TIME(18, 1); // "Night-jara" stage = "\x8Dヨル \x8Cジャラ"; break; @@ -743,7 +743,7 @@ void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csI case 0xFFF0: // clang-format off // "Cutscene 00" - gSaveContext.time = CLOCK_TIME(12, 0); stage = "デモ00"; + gSaveContext.save.time = CLOCK_TIME(12, 0); stage = "デモ00"; // clang-format on break; case 0xFFF1: @@ -791,13 +791,13 @@ void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csI stage = "???"; break; } - gSaveContext.environmentTime = gSaveContext.time; + gSaveContext.environmentTime = gSaveContext.save.time; GfxPrint_Printf(printer, "Stage:\x8C%s", stage); GfxPrint_SetPos(printer, 23, 25); GfxPrint_SetColor(printer, 255, 255, 55, 255); - switch (gSaveContext.day) { + switch (gSaveContext.save.day) { case 1: // "The First Day" day = "\x8Dサイショノヒ"; @@ -815,7 +815,7 @@ void Select_PrintCutsceneSetting(SelectContext* this, GfxPrint* printer, u16 csI day = "\x8Dクリアーノヒ"; break; default: - gSaveContext.day = 1; + gSaveContext.save.day = 1; // "The First Day" day = "\x8Dサイショノヒ"; break; @@ -837,8 +837,8 @@ void Select_DrawMenu(SelectContext* this) { GfxPrint_Open(printer, POLY_OPA_DISP); Select_PrintMenu(this, printer); - Select_PrintAgeSetting(this, printer, ((void)0, gSaveContext.playerForm)); - Select_PrintCutsceneSetting(this, printer, ((void)0, gSaveContext.cutscene)); + Select_PrintAgeSetting(this, printer, ((void)0, gSaveContext.save.playerForm)); + Select_PrintCutsceneSetting(this, printer, ((void)0, gSaveContext.save.cutscene)); POLY_OPA_DISP = GfxPrint_Close(printer); GfxPrint_Destroy(printer); @@ -868,7 +868,7 @@ void Select_DrawLoadingScreen(SelectContext* this) { void Select_Draw(SelectContext* this) { GraphicsContext* gfxCtx = this->state.gfxCtx; - func_8012CF0C(gfxCtx, 1, 1, 0, 0, 0); + func_8012CF0C(gfxCtx, true, true, 0, 0, 0); SET_FULLSCREEN_VIEWPORT(&this->view); View_RenderView(&this->view, 0xF); @@ -928,7 +928,7 @@ void Select_Init(GameState* thisx) { } Game_SetFramerateDivisor(&this->state, 1); - gSaveContext.cutscene = 0; - gSaveContext.playerForm = PLAYER_FORM_HUMAN; - gSaveContext.linkAge = 0; + gSaveContext.save.cutscene = 0; + gSaveContext.save.playerForm = PLAYER_FORM_HUMAN; + gSaveContext.save.linkAge = 0; } diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index ed732fc3d..1c32f6490 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)) { @@ -74,15 +74,15 @@ void Title_Draw(GameState* thisx) { eye.y = 4002.5417f; eye.z = 1119.0837f; - func_800B7FE0(&object, &eye, &lightDir, this->gameState.gfxCtx); + Hilite_DrawOpa(&object, &eye, &lightDir, this->gameState.gfxCtx); gSPSetLights1(POLY_OPA_DISP++, sTitleLights); Title_RenderView(this, 0.0f, 150.0f, 300.0f); func_8012C28C(this->gameState.gfxCtx); - Matrix_InsertTranslation(-53.0f, -5.0f, 0.0f, MTXMODE_NEW); + Matrix_Translate(-53.0f, -5.0f, 0.0f, MTXMODE_NEW); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); - Matrix_InsertRotation(0, titleRotation, 0, MTXMODE_APPLY); + Matrix_RotateZYX(0, titleRotation, 0, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(this->gameState.gfxCtx), G_MTX_LOAD); gSPDisplayList(POLY_OPA_DISP++, gNintendo64LogoNDL); @@ -105,7 +105,8 @@ void Title_Draw(GameState* thisx) { G_TX_NOLOD, G_TX_NOLOD); gDPSetTileSize(POLY_OPA_DISP++, 1, this->uls, (this->ult & 0x7F) - idx * 4, 0, 0); - gSPTextureRectangle(POLY_OPA_DISP++, 388, y << 2, 1156, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, 1 << 10, 1 << 10); + gSPTextureRectangle(POLY_OPA_DISP++, 97 << 2, y << 2, (97 + 192) << 2, (y + 2) << 2, G_TX_RENDERTILE, 0, 0, + 1 << 10, 1 << 10); } func_800FC444(this->gameState.gfxCtx, 0, 0, 0, this->coverAlpha, 2); @@ -118,7 +119,7 @@ void Title_Draw(GameState* thisx) { void Title_Main(GameState* thisx) { TitleContext* this = (TitleContext*)thisx; - func_8012CF0C(this->gameState.gfxCtx, 1, 1, 0, 0, 0); + func_8012CF0C(this->gameState.gfxCtx, true, true, 0, 0, 0); OPEN_DISPS(this->gameState.gfxCtx); @@ -127,7 +128,7 @@ void Title_Main(GameState* thisx) { Title_UpdateCounters(this); Title_Draw(&this->gameState); if (this->exit) { - gSaveContext.seqIndex = 0xFF; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; gSaveContext.gameMode = 1; @@ -144,7 +145,7 @@ void Title_Main(GameState* thisx) { void Title_Destroy(GameState* thisx) { TitleContext* this = (TitleContext*)thisx; - func_80146E40(&this->gameState, &this->sramCtx); + Sram_InitSram(&this->gameState, &this->sramCtx); ShrinkWindow_Destroy(); CIC6105_Nop80081828(); } @@ -158,7 +159,7 @@ void Title_Init(GameState* thisx) { DmaMgr_SendRequest0(this->staticSegment, (uintptr_t)_nintendo_rogo_staticSegmentRomStart, segmentSize); Game_SetFramerateDivisor(thisx, 1); - Matrix_StateAlloc(thisx); + Matrix_Init(thisx); ShrinkWindow_Init(); View_Init(&this->view, thisx->gfxCtx); @@ -172,7 +173,7 @@ void Title_Init(GameState* thisx) { gSaveContext.fileNum = 0xFF; } - gSaveContext.unk_3F3F = 1; + gSaveContext.unk_3F3F = true; Sram_Alloc(thisx, &this->sramCtx); this->ult = 0; this->timer = 20; 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..ddbb4547d 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 = 87cb648b4311d20673452111edaf4d38a5290c28 + parent = 06412c070f0240eacfaa860eee99b9c723245b7f method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/ExporterTest/CollisionExporter.cpp b/tools/ZAPD/ExporterTest/CollisionExporter.cpp index e00f5c1b0..87b9a05a2 100644 --- a/tools/ZAPD/ExporterTest/CollisionExporter.cpp +++ b/tools/ZAPD/ExporterTest/CollisionExporter.cpp @@ -50,10 +50,10 @@ void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] fs::path o writer->Write(col->polygons[i].vtxA); writer->Write(col->polygons[i].vtxB); writer->Write(col->polygons[i].vtxC); - writer->Write(col->polygons[i].a); - writer->Write(col->polygons[i].b); - writer->Write(col->polygons[i].c); - writer->Write(col->polygons[i].d); + writer->Write(col->polygons[i].normX); + writer->Write(col->polygons[i].normY); + writer->Write(col->polygons[i].normZ); + writer->Write(col->polygons[i].dist); } writer->Seek(col->polyTypeDefSegmentOffset, SeekOffsetType::Start); diff --git a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj index a709a3509..5bdfc7aa6 100644 --- a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj +++ b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj @@ -1,159 +1,160 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {65608eb0-1a47-45ad-ab66-192fb64c762c} - ExporterTest - 10.0 - ExporterExample - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - StaticLibrary - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - $(SolutionDir)\ZAPD\;$(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath) - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - true - stdcpp17 - stdc11 - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {65608eb0-1a47-45ad-ab66-192fb64c762c} + ExporterTest + 10.0 + ExporterExample + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + $(ProjectDir)..\ZAPD\;$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + true + stdcpp17 + stdc11 + MultiThreadedDebug + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + \ 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..9c4dde712 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 -j $(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..34ab95351 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 + ""; @@ -171,21 +171,23 @@ std::string Declaration::GetExternalDeclarationStr() const std::string Declaration::GetExternStr() const { - if (IsStatic() || varType == "") + if (IsStatic() || varType == "" || isUnaccounted) { return ""; } 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..531edc094 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); } } @@ -426,6 +434,10 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f std::string name = outPath.stem().string(); ZTexture tex(nullptr); + + if (name.find("u32") != std::string::npos) + tex.dWordAligned = false; + tex.FromPNG(pngFilePath.string(), texType); std::string cfgPath = StringHelper::Split(pngFilePath.string(), ".")[0] + ".cfg"; diff --git a/tools/decomp-permuter/src/__init__.py b/tools/ZAPD/ZAPD/NuGet/libpng.static.txt similarity index 100% rename from tools/decomp-permuter/src/__init__.py rename to tools/ZAPD/ZAPD/NuGet/libpng.static.txt diff --git a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp new file mode 100644 index 000000000..b69f47321 --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.cpp @@ -0,0 +1,208 @@ +#include "CutsceneMM_Commands.h" + +#include +#include + +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" + +// Specific for command lists where each entry has size 8 bytes +const std::unordered_map csCommandsDescMM = { + {CutsceneMMCommands::CS_CMD_MISC, {"CS_MISC", "(0x%02X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_SET_LIGHTING, {"CS_LIGHTING", "(0x%02X, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_SCENE_TRANS_FX, {"CS_SCENE_TRANS_FX", "(%i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_MOTIONBLUR, {"CS_MOTIONBLUR", "(%i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_GIVETATL, {"CS_GIVETATL", "(%i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_PLAYSEQ, {"CS_PLAYSEQ", "(0x%04X, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_130, {"CS_SCENE_UNK_130", "(0x%04X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_131, {"CS_SCENE_UNK_131", "(0x%04X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_132, {"CS_SCENE_UNK_132", "(%i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_STOPSEQ, {"CS_STOPSEQ", "(0x%04X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_PLAYAMBIENCE, {"CS_PLAYAMBIENCE", "(0x%04X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_FADEAMBIENCE, {"CS_FADEAMBIENCE", "(0x%04X, %i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_TERMINATOR, {"CS_TERMINATOR", "(%i, %i, %i)"}}, + {CutsceneMMCommands::CS_CMD_CHOOSE_CREDITS_SCENES, + {"CS_CHOOSE_CREDITS_SCENES", "(%i, %i, %i)"}}, +}; + +CutsceneSubCommandEntry_GenericMMCmd::CutsceneSubCommandEntry_GenericMMCmd( + const std::vector& rawData, offset_t rawDataIndex, CutsceneMMCommands cmdId) + : CutsceneSubCommandEntry(rawData, rawDataIndex), commandId(cmdId) +{ +} + +std::string CutsceneSubCommandEntry_GenericMMCmd::GetBodySourceCode() const +{ + const auto& element = csCommandsDescMM.find(commandId); + std::string entryFmt = "CS_UNK_DATA(0x%02X, %i, %i, %i)"; + + if (element != csCommandsDescMM.end()) + { + entryFmt = element->second.cmdMacro; + entryFmt += element->second.args; + } + + return StringHelper::Sprintf(entryFmt.c_str(), base, startFrame, endFrame, pad); +} + +CutsceneMMCommand_GenericCmd::CutsceneMMCommand_GenericCmd(const std::vector& rawData, + offset_t rawDataIndex, + CutsceneMMCommands cmdId) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + commandID = static_cast(cmdId); + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_GenericMMCmd(rawData, rawDataIndex, cmdId); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneMMCommand_GenericCmd::GetCommandMacro() const +{ + const auto& element = csCommandsDescMM.find(static_cast(commandID)); + + if (element != csCommandsDescMM.end()) + { + return StringHelper::Sprintf("%s_LIST(%i)", element->second.cmdMacro, numEntries); + } + + return StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%X, %i)", commandID, numEntries); +} + +CutsceneSubCommandEntry_Camera::CutsceneSubCommandEntry_Camera(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ +} + +std::string CutsceneSubCommandEntry_Camera::GetBodySourceCode() const +{ + return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X)", base, startFrame); +} + +size_t CutsceneSubCommandEntry_Camera::GetRawSize() const +{ + return 0x04; +} + +CutsceneMMCommand_Camera::CutsceneMMCommand_Camera(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries / 4; i++) + { + auto* entry = new CutsceneSubCommandEntry_Camera(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneMMCommand_Camera::GetCommandMacro() const +{ + return StringHelper::Sprintf("CS_CAMERA_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_FadeScreen::CutsceneSubCommandEntry_FadeScreen( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + unk_06 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x06); + unk_07 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x07); + unk_08 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08); + unk_09 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09); + unk_0A = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0A); + unk_0B = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0B); +} + +std::string CutsceneSubCommandEntry_FadeScreen::GetBodySourceCode() const +{ + return StringHelper::Sprintf("CS_FADESCREEN(0x%02X, %i, %i, %i, %i, %i)", base, startFrame, + endFrame, unk_06, unk_07, unk_08); +} + +size_t CutsceneSubCommandEntry_FadeScreen::GetRawSize() const +{ + return 0x0C; +} + +CutsceneMMCommand_FadeScreen::CutsceneMMCommand_FadeScreen(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_FadeScreen(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneMMCommand_FadeScreen::GetCommandMacro() const +{ + return StringHelper::Sprintf("CS_FADESCREEN_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_FadeSeq::CutsceneSubCommandEntry_FadeSeq( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + unk_08 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); +} + +std::string CutsceneSubCommandEntry_FadeSeq::GetBodySourceCode() const +{ + return StringHelper::Sprintf("CS_FADESEQ(%i, %i, %i)", base, startFrame, endFrame); +} + +size_t CutsceneSubCommandEntry_FadeSeq::GetRawSize() const +{ + return 0x0C; +} + +CutsceneMMCommand_FadeSeq::CutsceneMMCommand_FadeSeq(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_FadeSeq(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneMMCommand_FadeSeq::GetCommandMacro() const +{ + return StringHelper::Sprintf("CS_FADESEQ_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_NonImplemented::CutsceneSubCommandEntry_NonImplemented( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ +} + +CutsceneMMCommand_NonImplemented::CutsceneMMCommand_NonImplemented( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_NonImplemented(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} diff --git a/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h new file mode 100644 index 000000000..c8ae4eb60 --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/CutsceneMM_Commands.h @@ -0,0 +1,140 @@ +#pragma once + +#include "Cutscene_Commands.h" + +enum class CutsceneMMCommands +{ + /* 0x00A */ CS_CMD_TEXTBOX = 0xA, + /* 0x05A */ CS_CMD_CAMERA = 0x5A, + /* 0x096 */ CS_CMD_MISC = 0x96, + /* 0x097 */ CS_CMD_SET_LIGHTING, + /* 0x098 */ CS_CMD_SCENE_TRANS_FX, + /* 0x099 */ CS_CMD_MOTIONBLUR, + /* 0x09A */ CS_CMD_GIVETATL, + /* 0x09B */ CS_CMD_FADESCREEN, + /* 0x09C */ CS_CMD_FADESEQ, + /* 0x09D */ CS_CMD_SETTIME, + /* 0x0C8 */ CS_CMD_SET_PLAYER_ACTION = 0xC8, + /* 0x0FA */ CS_CMD_UNK_FA = 0xFA, + /* 0x0FE */ CS_CMD_UNK_FE = 0xFE, + /* 0x0FF */ CS_CMD_UNK_FF, + /* 0x100 */ CS_CMD_UNK_100, + /* 0x101 */ CS_CMD_UNK_101, + /* 0x102 */ CS_CMD_UNK_102, + /* 0x103 */ CS_CMD_UNK_103, + /* 0x104 */ CS_CMD_UNK_104, + /* 0x105 */ CS_CMD_UNK_105, + /* 0x108 */ CS_CMD_UNK_108 = 0x108, + /* 0x109 */ CS_CMD_UNK_109, + /* 0x12C */ CS_CMD_PLAYSEQ = 0x12C, + /* 0x12D */ CS_CMD_UNK_12D, + /* 0x130 */ CS_CMD_130 = 0x130, + /* 0x131 */ CS_CMD_131 = 0x131, + /* 0x132 */ CS_CMD_132 = 0x132, + /* 0x133 */ CS_CMD_STOPSEQ, + /* 0x134 */ CS_CMD_PLAYAMBIENCE, + /* 0x135 */ CS_CMD_FADEAMBIENCE, + /* 0x15E */ CS_CMD_TERMINATOR = 0x15E, + /* 0x15F */ CS_CMD_CHOOSE_CREDITS_SCENES, + /* 0x190 */ CS_CMD_RUMBLE = 0x190, +}; + +class CutsceneSubCommandEntry_GenericMMCmd : public CutsceneSubCommandEntry +{ +public: + CutsceneMMCommands commandId; + + CutsceneSubCommandEntry_GenericMMCmd(const std::vector& rawData, offset_t rawDataIndex, + CutsceneMMCommands cmdId); + + std::string GetBodySourceCode() const override; +}; + +class CutsceneMMCommand_GenericCmd : public CutsceneCommand +{ +public: + CutsceneMMCommand_GenericCmd(const std::vector& rawData, offset_t rawDataIndex, + CutsceneMMCommands cmdId); + + std::string GetCommandMacro() const override; +}; + +// TODO: MM cutscene camera command is implemented as a placeholder until we better understand how +// it works +class CutsceneSubCommandEntry_Camera : public CutsceneSubCommandEntry +{ +public: + uint32_t unk_08; + + CutsceneSubCommandEntry_Camera(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneMMCommand_Camera : public CutsceneCommand +{ +public: + CutsceneMMCommand_Camera(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_FadeScreen : public CutsceneSubCommandEntry +{ +public: + uint8_t unk_06; + uint8_t unk_07; + uint8_t unk_08; + uint8_t unk_09; + uint8_t unk_0A; + uint8_t unk_0B; + + CutsceneSubCommandEntry_FadeScreen(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneMMCommand_FadeScreen : public CutsceneCommand +{ +public: + CutsceneMMCommand_FadeScreen(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_FadeSeq : public CutsceneSubCommandEntry +{ +public: + uint32_t unk_08; + + CutsceneSubCommandEntry_FadeSeq(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneMMCommand_FadeSeq : public CutsceneCommand +{ +public: + CutsceneMMCommand_FadeSeq(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_NonImplemented : public CutsceneSubCommandEntry +{ +public: + CutsceneSubCommandEntry_NonImplemented(const std::vector& rawData, + offset_t rawDataIndex); +}; + +class CutsceneMMCommand_NonImplemented : public CutsceneCommand +{ +public: + CutsceneMMCommand_NonImplemented(const std::vector& rawData, offset_t rawDataIndex); +}; diff --git a/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.cpp b/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.cpp new file mode 100644 index 000000000..a716176b9 --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.cpp @@ -0,0 +1,591 @@ +#include "Cutscene_Commands.h" + +#include +#include + +#include "CutsceneMM_Commands.h" +#include "Globals.h" +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" + +/* CutsceneSubCommandEntry */ + +CutsceneSubCommandEntry::CutsceneSubCommandEntry(const std::vector& rawData, + offset_t rawDataIndex) +{ + base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); + startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); + endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); + pad = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); +} + +std::string CutsceneSubCommandEntry::GetBodySourceCode() const +{ + return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X), CMD_HH(0x%04X, 0x%04X)", base, startFrame, + endFrame, pad); +} + +size_t CutsceneSubCommandEntry::GetRawSize() const +{ + return 0x08; +} + +/* CutsceneCommand */ + +CutsceneCommand::CutsceneCommand(const std::vector& rawData, offset_t rawDataIndex) +{ + numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0); +} + +CutsceneCommand::~CutsceneCommand() +{ + for (auto& entry : entries) + { + delete entry; + } +} + +std::string CutsceneCommand::GetCommandMacro() const +{ + return StringHelper::Sprintf("CMD_W(0x%08X), CMD_W(0x%08X)", commandID, numEntries); +} + +std::string CutsceneCommand::GenerateSourceCode() const +{ + std::string result; + + result += GetCommandMacro(); + result += ",\n"; + + for (auto& entry : entries) + { + result += " "; + result += entry->GetBodySourceCode(); + result += ",\n"; + } + + return result; +} + +size_t CutsceneCommand::GetCommandSize() const +{ + size_t size = 0; + if (entries.size() > 0) + { + size = entries.at(0)->GetRawSize() * entries.size(); + } + else + { + size = 0x08 * numEntries; + } + return 0x08 + size; +} + +void CutsceneCommand::SetCommandID(uint32_t nCommandID) +{ + commandID = nCommandID; + + for (auto& entry : entries) + { + entry->commandID = commandID; + } +} + +// Specific for command lists where each entry has size 0x30 bytes +const std::unordered_map csCommandsDesc = { + {CutsceneCommands::Misc, + {"CS_MISC", "(0x%04X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}}, + {CutsceneCommands::SetLighting, + {"CS_LIGHTING", "(0x%02X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}}, + {CutsceneCommands::PlayBGM, {"CS_PLAY_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}}, + {CutsceneCommands::StopBGM, {"CS_STOP_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}}, + {CutsceneCommands::FadeBGM, {"CS_FADE_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}}, +}; + +CutsceneSubCommandEntry_GenericCmd::CutsceneSubCommandEntry_GenericCmd( + const std::vector& rawData, offset_t rawDataIndex, CutsceneCommands cmdId) + : CutsceneSubCommandEntry(rawData, rawDataIndex), commandId(cmdId) +{ + word0 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0); + word1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4); + + unused1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8); + unused2 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC); + unused3 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x10); + unused4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x14); + unused5 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x18); + unused6 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x1C); + unused7 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x20); + unused8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x24); + unused9 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x28); + unused10 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x2C); +} + +std::string CutsceneSubCommandEntry_GenericCmd::GetBodySourceCode() const +{ + const auto& element = csCommandsDesc.find(commandId); + + if (element != csCommandsDesc.end()) + { + std::string entryFmt = element->second.cmdMacro; + entryFmt += element->second.args; + + return StringHelper::Sprintf(entryFmt.c_str(), base, startFrame, endFrame, pad, unused1, + unused2, unused3, unused4, unused5, unused6, unused7, unused8, + unused9, unused10); + } + + return StringHelper::Sprintf("CS_UNK_DATA(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, " + "0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)", + word0, word1, unused1, unused2, unused3, unused4, unused5, unused6, + unused7, unused8, unused9, unused10); +} + +size_t CutsceneSubCommandEntry_GenericCmd::GetRawSize() const +{ + return 0x30; +} + +CutsceneCommand_GenericCmd::CutsceneCommand_GenericCmd(const std::vector& rawData, + offset_t rawDataIndex, + CutsceneCommands cmdId) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + commandID = static_cast(cmdId); + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_GenericCmd(rawData, rawDataIndex, cmdId); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneCommand_GenericCmd::GetCommandMacro() const +{ + const auto& element = csCommandsDesc.find(static_cast(commandID)); + + if (element != csCommandsDesc.end()) + { + return StringHelper::Sprintf("%s_LIST(%i)", element->second.cmdMacro, numEntries); + } + + return StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%X, %i)", commandID, numEntries); +} + +CutsceneCameraPoint::CutsceneCameraPoint(const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + continueFlag = BitConverter::ToInt8BE(rawData, rawDataIndex + 0); + cameraRoll = BitConverter::ToInt8BE(rawData, rawDataIndex + 1); + nextPointFrame = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + viewAngle = BitConverter::ToFloatBE(rawData, rawDataIndex + 4); + + posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 8); + posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 10); + posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 12); + + unused = BitConverter::ToInt16BE(rawData, rawDataIndex + 14); +} + +std::string CutsceneCameraPoint::GetBodySourceCode() const +{ + std::string result = ""; + + if (commandID == (int32_t)CutsceneCommands::SetCameraFocus) + { + result += "CS_CAM_FOCUS_POINT"; + } + else if (commandID == (int32_t)CutsceneCommands::SetCameraFocusLink) + { + result += "CS_CAM_FOCUS_POINT_PLAYER"; + } + else if (commandID == (int32_t)CutsceneCommands::SetCameraPosLink) + { + result += "CS_CAM_POS_PLAYER"; + } + else + { + result += "CS_CAM_POS"; + } + + std::string continueMacro = "CS_CMD_CONTINUE"; + if (continueFlag != 0) + continueMacro = "CS_CMD_STOP"; + + result += + StringHelper::Sprintf("(%s, 0x%02X, %i, %ff, %i, %i, %i, 0x%04X)", continueMacro.c_str(), + cameraRoll, nextPointFrame, viewAngle, posX, posY, posZ, unused); + return result; +} + +size_t CutsceneCameraPoint::GetRawSize() const +{ + return 0x10; +} + +CutsceneCommandSetCameraPos::CutsceneCommandSetCameraPos(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); + startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); + endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); + unused = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); + + bool shouldContinue = true; + + uint32_t currentPtr = rawDataIndex + 8; + + while (shouldContinue) + { + CutsceneCameraPoint* camPoint = new CutsceneCameraPoint(rawData, currentPtr); + entries.push_back(camPoint); + + if (camPoint->continueFlag == -1) + shouldContinue = false; + + currentPtr += camPoint->GetRawSize(); + } +} + +std::string CutsceneCommandSetCameraPos::GetCommandMacro() const +{ + std::string result; + + std::string listStr; + + if (commandID == (int32_t)CutsceneCommands::SetCameraFocus) + { + listStr = "CS_CAM_FOCUS_POINT_LIST"; + } + else if (commandID == (int32_t)CutsceneCommands::SetCameraFocusLink) + { + listStr = "CS_CAM_FOCUS_POINT_PLAYER_LIST"; + } + else if (commandID == (int32_t)CutsceneCommands::SetCameraPosLink) + { + listStr = "CS_CAM_POS_PLAYER_LIST"; + } + else + { + listStr = "CS_CAM_POS_LIST"; + } + + result += StringHelper::Sprintf("%s(%i, %i)", listStr.c_str(), startFrame, endFrame); + + return result; +} + +size_t CutsceneCommandSetCameraPos::GetCommandSize() const +{ + return 0x0C + entries.at(0)->GetRawSize() * entries.size(); +} + +CutsceneSubCommandEntry_Rumble::CutsceneSubCommandEntry_Rumble(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + unk_06 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x06); + unk_07 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x07); + unk_08 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08); + unk_09 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09); + unk_0A = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0A); + unk_0B = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0B); +} + +std::string CutsceneSubCommandEntry_Rumble::GetBodySourceCode() const +{ + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + return StringHelper::Sprintf("CS_RUMBLE(%i, %i, %i, 0x%02X, 0x%02X, 0x%02X)", base, + startFrame, endFrame, unk_06, unk_07, unk_08); + } + + return StringHelper::Sprintf("CS_CMD_09(%i, %i, %i, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X)", + base, startFrame, endFrame, unk_06, unk_07, unk_08, unk_09, unk_0A, + unk_0B); +} + +size_t CutsceneSubCommandEntry_Rumble::GetRawSize() const +{ + return 0x0C; +} + +CutsceneCommand_Rumble::CutsceneCommand_Rumble(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_Rumble(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneCommand_Rumble::GetCommandMacro() const +{ + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + return StringHelper::Sprintf("CS_RUMBLE_LIST(%i)", numEntries); + } + return StringHelper::Sprintf("CS_CMD_09_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_SetTime::CutsceneSubCommandEntry_SetTime( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + hour = BitConverter::ToUInt8BE(rawData, rawDataIndex + 6); + minute = BitConverter::ToUInt8BE(rawData, rawDataIndex + 7); + unk_08 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); +} + +std::string CutsceneSubCommandEntry_SetTime::GetBodySourceCode() const +{ + return StringHelper::Sprintf("CS_TIME(%i, %i, %i, %i, %i, %i)", base, startFrame, endFrame, + hour, minute, unk_08); +} + +size_t CutsceneSubCommandEntry_SetTime::GetRawSize() const +{ + return 0x0C; +} + +CutsceneCommand_SetTime::CutsceneCommand_SetTime(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_SetTime(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneCommand_SetTime::GetCommandMacro() const +{ + return StringHelper::Sprintf("CS_TIME_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_TextBox::CutsceneSubCommandEntry_TextBox( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + type = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6); + textId1 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8); + textId2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA); +} + +std::string CutsceneSubCommandEntry_TextBox::GetBodySourceCode() const +{ + if (type == 0xFFFF) + { + return StringHelper::Sprintf("CS_TEXT_NONE(%i, %i)", startFrame, endFrame); + } + if (type == 2) + { + return StringHelper::Sprintf("CS_TEXT_LEARN_SONG(%i, %i, %i, 0x%X)", base, startFrame, + endFrame, textId1); + } + + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + switch (type) + { + case 0: + return StringHelper::Sprintf("CS_TEXT_DEFAULT(0x%X, %i, %i, 0x%X, 0x%X)", base, + startFrame, endFrame, textId1, textId2); + + case 1: + return StringHelper::Sprintf("CS_TEXT_TYPE_1(0x%X, %i, %i, 0x%X, 0x%X)", base, + startFrame, endFrame, textId1, textId2); + + case 3: + return StringHelper::Sprintf("CS_TEXT_TYPE_3(0x%X, %i, %i, 0x%X, 0x%X)", base, + startFrame, endFrame, textId1, textId2); + + case 4: + return StringHelper::Sprintf("CS_TEXT_BOSSES_REMAINS(0x%X, %i, %i, 0x%X)", base, + startFrame, endFrame, textId1); + + case 5: + return StringHelper::Sprintf("CS_TEXT_ALL_NORMAL_MASKS(0x%X, %i, %i, 0x%X)", base, + startFrame, endFrame, textId1); + } + } + + return StringHelper::Sprintf("CS_TEXT_DISPLAY_TEXTBOX(0x%X, %i, %i, %i, 0x%X, 0x%X)", base, + startFrame, endFrame, type, textId1, textId2); +} + +size_t CutsceneSubCommandEntry_TextBox::GetRawSize() const +{ + return 0x0C; +} + +CutsceneCommand_TextBox::CutsceneCommand_TextBox(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_TextBox(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneCommand_TextBox::GetCommandMacro() const +{ + return StringHelper::Sprintf("CS_TEXT_LIST(%i)", numEntries); +} + +CutsceneSubCommandEntry_ActorAction::CutsceneSubCommandEntry_ActorAction( + const std::vector& rawData, offset_t rawDataIndex) + : CutsceneSubCommandEntry(rawData, rawDataIndex) +{ + rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6); + rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8); + rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA); + startPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0xC); + startPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x10); + startPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x14); + endPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x18); + endPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x1C); + endPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x20); + normalX = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x24); + normalY = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x28); + normalZ = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x2C); +} + +std::string CutsceneSubCommandEntry_ActorAction::GetBodySourceCode() const +{ + std::string result; + + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + if (static_cast(commandID) == + CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION) + { + result = "CS_PLAYER_ACTION"; + } + else + { + result = "CS_ACTOR_ACTION"; + } + } + else + { + if (static_cast(commandID) == CutsceneCommands::SetPlayerAction) + { + result = "CS_PLAYER_ACTION"; + } + else + { + result = "CS_NPC_ACTION"; + } + } + + result += + StringHelper::Sprintf("(%i, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, " + "%i, %i, %i, %i, %.11ef, %.11ef, %.11ef)", + base, startFrame, endFrame, rotX, rotY, rotZ, startPosX, startPosY, + startPosZ, endPosX, endPosY, endPosZ, normalX, normalY, normalZ); + return result; +} + +size_t CutsceneSubCommandEntry_ActorAction::GetRawSize() const +{ + return 0x30; +} + +CutsceneCommand_ActorAction::CutsceneCommand_ActorAction(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + for (size_t i = 0; i < numEntries; i++) + { + auto* entry = new CutsceneSubCommandEntry_ActorAction(rawData, rawDataIndex); + entries.push_back(entry); + rawDataIndex += entry->GetRawSize(); + } +} + +std::string CutsceneCommand_ActorAction::GetCommandMacro() const +{ + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + if (static_cast(commandID) == + CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION) + { + return StringHelper::Sprintf("CS_PLAYER_ACTION_LIST(%i)", numEntries); + } + return StringHelper::Sprintf("CS_ACTOR_ACTION_LIST(0x%03X, %i)", commandID, numEntries); + } + + if (static_cast(commandID) == CutsceneCommands::SetPlayerAction) + { + return StringHelper::Sprintf("CS_PLAYER_ACTION_LIST(%i)", entries.size()); + } + return StringHelper::Sprintf("CS_NPC_ACTION_LIST(0x%03X, %i)", commandID, entries.size()); +} + +CutsceneCommand_Terminator::CutsceneCommand_Terminator(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); + startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); + endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); + unknown = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); // endFrame duplicate +} + +std::string CutsceneCommand_Terminator::GenerateSourceCode() const +{ + std::string result; + + result += StringHelper::Sprintf("CS_TERMINATOR(%i, %i, %i),\n", base, startFrame, endFrame); + + return result; +} + +size_t CutsceneCommand_Terminator::GetCommandSize() const +{ + return 0x10; +} + +CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(const std::vector& rawData, + offset_t rawDataIndex) + : CutsceneCommand(rawData, rawDataIndex) +{ + rawDataIndex += 4; + + base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); + startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); + endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); +} + +std::string CutsceneCommandSceneTransFX::GenerateSourceCode() const +{ + return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i),\n", base, startFrame, endFrame); +} + +size_t CutsceneCommandSceneTransFX::GetCommandSize() const +{ + return 0x10; +} diff --git a/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.h b/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.h new file mode 100644 index 000000000..c46273587 --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/Cutscene_Commands.h @@ -0,0 +1,267 @@ +#pragma once + +#include +#include +#include + +#include "Declaration.h" + +enum class CutsceneCommands +{ + SetCameraPos = 0x0001, + SetCameraFocus = 0x0002, + Misc = 0x0003, + SetLighting = 0x0004, + SetCameraPosLink = 0x0005, + SetCameraFocusLink = 0x0006, + Cmd07 = 0x0007, + Cmd08 = 0x0008, + Cmd09 = 0x0009, // Rumble + Textbox = 0x0013, + SetPlayerAction = 0x000A, + SetActorAction1 = 0x000F, + SetActorAction2 = 0x000E, + SetActorAction3 = 0x0019, + SetActorAction4 = 0x001D, + SetActorAction5 = 0x001E, + SetActorAction6 = 0x002C, + SetActorAction7 = 0x001F, + SetActorAction8 = 0x0031, + SetActorAction9 = 0x003E, + SetActorAction10 = 0x008F, + SetSceneTransFX = 0x002D, + PlayBGM = 0x0056, + StopBGM = 0x0057, + FadeBGM = 0x007C, + SetTime = 0x008C, + Terminator = 0x03E8, +}; + +typedef struct CsCommandListDescriptor +{ + const char* cmdMacro; + const char* args; +} CsCommandListDescriptor; + +class CutsceneSubCommandEntry +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t pad; + + uint32_t commandID; + + CutsceneSubCommandEntry(const std::vector& rawData, offset_t rawDataIndex); + virtual ~CutsceneSubCommandEntry() = default; + + virtual std::string GetBodySourceCode() const; + + virtual size_t GetRawSize() const; +}; + +class CutsceneCommand +{ +public: + uint32_t commandID; + uint32_t commandIndex; + + uint32_t numEntries; + std::vector entries; + + CutsceneCommand(const std::vector& rawData, offset_t rawDataIndex); + virtual ~CutsceneCommand(); + + virtual std::string GetCommandMacro() const; + virtual std::string GenerateSourceCode() const; + virtual size_t GetCommandSize() const; + + virtual void SetCommandID(uint32_t nCommandID); +}; + +class CutsceneSubCommandEntry_GenericCmd : public CutsceneSubCommandEntry +{ +public: + CutsceneCommands commandId; + + uint32_t word0 = 0; + uint32_t word1 = 0; + + uint32_t unused1 = 0; + uint32_t unused2 = 0; + uint32_t unused3 = 0; + uint32_t unused4 = 0; + uint32_t unused5 = 0; + uint32_t unused6 = 0; + uint32_t unused7 = 0; + uint32_t unused8 = 0; + uint32_t unused9 = 0; + uint32_t unused10 = 0; + + CutsceneSubCommandEntry_GenericCmd(const std::vector& rawData, offset_t rawDataIndex, + CutsceneCommands cmdId); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommand_GenericCmd : public CutsceneCommand +{ +public: + CutsceneCommand_GenericCmd(const std::vector& rawData, offset_t rawDataIndex, + CutsceneCommands cmdId); + + std::string GetCommandMacro() const override; +}; + +class CutsceneCameraPoint : public CutsceneSubCommandEntry +{ +public: + int8_t continueFlag; + int8_t cameraRoll; + int16_t nextPointFrame; + float viewAngle; + int16_t posX, posY, posZ; + int16_t unused; + + CutsceneCameraPoint(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommandSetCameraPos : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unused; + + CutsceneCommandSetCameraPos(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; + + size_t GetCommandSize() const override; +}; + +class CutsceneCommandSceneTransFX : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + + CutsceneCommandSceneTransFX(const std::vector& rawData, offset_t rawDataIndex); + + std::string GenerateSourceCode() const override; + size_t GetCommandSize() const override; +}; + +class CutsceneSubCommandEntry_Rumble : public CutsceneSubCommandEntry +{ +public: + uint8_t unk_06; + uint8_t unk_07; + uint8_t unk_08; + uint8_t unk_09; + uint8_t unk_0A; + uint8_t unk_0B; + + CutsceneSubCommandEntry_Rumble(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommand_Rumble : public CutsceneCommand +{ +public: + CutsceneCommand_Rumble(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_SetTime : public CutsceneSubCommandEntry +{ +public: + uint8_t hour; + uint8_t minute; + uint32_t unk_08; + + CutsceneSubCommandEntry_SetTime(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommand_SetTime : public CutsceneCommand +{ +public: + CutsceneCommand_SetTime(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_TextBox : public CutsceneSubCommandEntry +{ +public: + uint16_t type; + uint16_t textId1; + uint16_t textId2; + + CutsceneSubCommandEntry_TextBox(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommand_TextBox : public CutsceneCommand +{ +public: + CutsceneCommand_TextBox(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneSubCommandEntry_ActorAction : public CutsceneSubCommandEntry +{ +public: + uint16_t rotX, rotY, rotZ; + int32_t startPosX, startPosY, startPosZ; + int32_t endPosX, endPosY, endPosZ; + float normalX, normalY, normalZ; + + CutsceneSubCommandEntry_ActorAction(const std::vector& rawData, offset_t rawDataIndex); + std::string GetBodySourceCode() const override; + + size_t GetRawSize() const override; +}; + +class CutsceneCommand_ActorAction : public CutsceneCommand +{ +public: + CutsceneCommand_ActorAction(const std::vector& rawData, offset_t rawDataIndex); + + std::string GetCommandMacro() const override; +}; + +class CutsceneCommand_Terminator : public CutsceneCommand +{ +public: + uint16_t base; + uint16_t startFrame; + uint16_t endFrame; + uint16_t unknown; + + CutsceneCommand_Terminator(const std::vector& rawData, offset_t rawDataIndex); + + std::string GenerateSourceCode() const override; + size_t GetCommandSize() const override; +}; 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..163b028b5 --- /dev/null +++ b/tools/ZAPD/ZAPD/WarningHandler.cpp @@ -0,0 +1,451 @@ +/** + * 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) { + bool forcePrint = false; + +#ifdef DEVELOPMENT + forcePrint = true; +#endif + + fprintf(stderr, "\n"); + + if (forcePrint || 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..f3bb35a3f 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj @@ -1,324 +1,362 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 15.0 - {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36} - ZAPD - 10.0 - ZAPD - - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - Application - true - v142 - MultiByte - - - Application - false - v142 - true - MultiByte - - - - - - - - - - - - - - - - - - - - - $(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) - - - $(IncludePath) - - - $(SolutionDir)ZAPD\lib\tinyxml2;$(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)ZAPD\lib\elfio;$(SolutionDir)ZAPD\lib\stb;$(ProjectDir);$(IncludePath) - $(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath) - - - - Level3 - Disabled - true - true - stdcpp17 - stdc11 - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - - - - - Level3 - Disabled - true - true - stdcpp17 - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - EnableFastChecks - stdc11 - - - true - libpng16.lib;ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) - - + + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36} + ZAPD + 10.0 + ZAPD + + + + Application + true + v143 + MultiByte + + + Application + false + v143 + true + MultiByte + + + Application + true + v143 + MultiByte + + + Application + false + v143 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + $(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) + + + $(SolutionDir)ZAPD\lib\tinyxml2;$(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)ZAPD\lib\elfio;$(SolutionDir)ZAPD\lib\stb;$(ProjectDir);$(IncludePath) + $(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath) + + + + Level3 + Disabled + true + true + stdcpp17 + stdc11 + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + + cd .. -python3 ZAPD/genbuildinfo.py - - - - - Level3 - MaxSpeed - true - true - true - true - - - true - true - - - - - Level3 - MaxSpeed - true - true - true - true - stdcpplatest - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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}. - - - - - - +mkdir build\ZAPD + python ZAPD/genbuildinfo.py + + + + + Level3 + Disabled + true + true + stdcpp17 + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableFastChecks + stdc11 + MultiThreadedDebug + + + true + ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) + false + + + cd .. +mkdir build\ZAPD + python ZAPD/genbuildinfo.py + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + cd .. +mkdir build\ZAPD + python ZAPD/genbuildinfo.py + + + + + Level3 + MaxSpeed + true + true + true + true + stdcpplatest + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + + + true + true + + + cd .. +mkdir build\ZAPD + python 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..4de236fad 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters @@ -1,509 +1,566 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - {02148456-5068-4613-8478-f10addc58e70} - - - {bcab3136-95ba-4839-833c-43d78ad6e335} - - - {dc06ed84-f6fe-4277-80f3-d62bd5cdbb98} - - - {6049c045-bc38-4221-b29e-ca6d4d8af4aa} - - - {490e3a08-047b-48d3-ab53-3a860a3b92aa} - - - {26c06845-8e8e-4b79-ad18-07c4f9c0f801} - - - {d45c420d-2378-47ac-92c5-80db9475c195} - - - {03cc56a2-e0e8-4167-80a0-98fb900a959a} - - - {73db0879-6df8-4f6a-8cc2-a1f836e9e796} - - - {be9a5be0-ec6a-4200-8e39-bb58c7da7aa8} - - - {7ee79d97-c6a8-4e82-93ef-37981f4d7838} - - - {85600275-99fe-491d-8189-bcc3dc1a8903} - - - - - Source Files - - - Source Files\Z64\ZRoom - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Libraries - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files - - - Source Files\Z64 - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Libraries\libgfxd - - - Source Files\Z64 - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64 - - - Source Files\Z64 - - - Source Files\Z64\ZRoom\Commands - - - Source Files\Z64 - - - Source Files - - - Source Files - - - Source Files\Z64 - - - - - Header Files\Z64\ZRoom - - - Header Files\Z64\ZRoom - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files\Libraries\elfio - - - Header Files - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Libraries - - - Header Files\Libraries - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files - - - Header Files\Z64 - - - Header Files - - - Header Files\Z64 - - - Header Files\Libraries\libgfxd - - - Header Files\Libraries\libgfxd - - - Header Files\Libraries\libgfxd - - - Header Files\Z64 - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64\ZRoom\Commands - - - Header Files\Z64 - - - Header Files\Z64 - - - Header Files\Z64\ZRoom\Commands - - - Header Files - - - Header Files\Z64 - - - Header Files - - - Header Files\Z64 - - - - - Resource Files - - - - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + {02148456-5068-4613-8478-f10addc58e70} + + + {bcab3136-95ba-4839-833c-43d78ad6e335} + + + {dc06ed84-f6fe-4277-80f3-d62bd5cdbb98} + + + {6049c045-bc38-4221-b29e-ca6d4d8af4aa} + + + {490e3a08-047b-48d3-ab53-3a860a3b92aa} + + + {26c06845-8e8e-4b79-ad18-07c4f9c0f801} + + + {d45c420d-2378-47ac-92c5-80db9475c195} + + + {03cc56a2-e0e8-4167-80a0-98fb900a959a} + + + {73db0879-6df8-4f6a-8cc2-a1f836e9e796} + + + {be9a5be0-ec6a-4200-8e39-bb58c7da7aa8} + + + {7ee79d97-c6a8-4e82-93ef-37981f4d7838} + + + {85600275-99fe-491d-8189-bcc3dc1a8903} + + + {ba9990b0-1082-48bb-874c-6108534b5455} + + + {ce9d91b0-ba20-4296-bc2d-8630965bb392} + + + {730beb67-6d59-4849-9d9b-702c4a565fc0} + + + + + Source Files + + + Source Files\Z64\ZRoom + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Libraries\libgfxd + + + Source Files\Z64 + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64 + + + Source Files\Z64\ZRoom\Commands + + + Source Files\Z64 + + + Source Files + + + Source Files + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files\Z64 + + + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files\Libraries\elfio + + + Header Files + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Libraries + + + Header Files\Libraries + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files\Libraries\libgfxd + + + Header Files\Libraries\libgfxd + + + Header Files\Libraries\libgfxd + + + Header Files\Z64 + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64\ZRoom\Commands + + + Header Files\Z64 + + + Header Files\Z64\ZRoom\Commands + + + Header Files + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + + + Resource Files + + + any\any + + + NuGet + + + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp index 9242f657a..74b520b50 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); @@ -50,7 +51,7 @@ void ZNormalAnimation::ParseRawData() { ZAnimation::ParseRawData(); - const uint8_t* data = parent->GetRawData().data(); + auto& data = parent->GetRawData(); rotationValuesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 4); rotationIndicesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 8); @@ -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..d4f55d6c8 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,18 +94,26 @@ 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++) { const auto& res = resList[i]; output += "\t"; - if (res->GetResourceType() == ZResourceType::Scalar || - res->GetResourceType() == ZResourceType::Vertex) + switch (res->GetResourceType()) + { + case ZResourceType::Pointer: + case ZResourceType::Scalar: + case ZResourceType::Vertex: + case ZResourceType::CollisionPoly: output += resList.at(i)->GetBodySourceCode(); - else + break; + + default: output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str()); + break; + } if (i < arrayCnt - 1 || res->IsExternalResource()) output += ",\n"; 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..992332db7 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -1,5 +1,6 @@ #include "ZCollision.h" +#include #include #include @@ -60,25 +61,62 @@ void ZCollisionHeader::ParseRawData() currentPtr += vec.GetRawDataSize(); vertices.push_back(vec); } - + for (uint16_t i = 0; i < numPolygons; i++) - polygons.push_back(PolygonEntry(rawData, polySegmentOffset + (i * 16))); + { + ZCollisionPoly poly(parent); + poly.SetRawDataIndex(polySegmentOffset + (i * 16)); + poly.ParseRawData(); + polygons.push_back(poly); + } uint16_t highestPolyType = 0; - for (PolygonEntry poly : polygons) + for (ZCollisionPoly poly : polygons) { if (poly.type > highestPolyType) highestPolyType = poly.type; } - for (uint16_t i = 0; i < highestPolyType + 1; i++) polygonTypes.push_back( BitConverter::ToUInt64BE(rawData, polyTypeDefSegmentOffset + (i * 8))); - if (camDataAddress != 0) - camData = new CameraDataList(parent, name, rawData, camDataSegmentOffset, - polyTypeDefSegmentOffset, polygonTypes.size()); + if (camDataAddress != SEGMENTED_NULL) + { + // Try to guess how many elements the CamDataList array has. + // The "guessing algorithm" is basically a "best effort" one and it + // is error-prone. + // This is based mostly on observation of how CollisionHeader data is + // usually ordered. If for some reason the data was in some other funny + // order, this would probably break. + // The most common ordering is: + // - *CamData* + // - SurfaceType + // - CollisionPoly + // - Vertices + // - WaterBoxes + // - CollisionHeader + offset_t upperCameraBoundary = polyTypeDefSegmentOffset; + if (upperCameraBoundary == 0) + { + upperCameraBoundary = polySegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = vtxSegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = waterBoxSegmentOffset; + } + if (upperCameraBoundary == 0) + { + upperCameraBoundary = rawDataIndex; + } + + camData = + new CameraDataList(parent, name, rawData, camDataSegmentOffset, upperCameraBoundary); + } for (uint16_t i = 0; i < numWaterBoxes; i++) waterBoxes.push_back(WaterBoxHeader( @@ -88,7 +126,7 @@ void ZCollisionHeader::ParseRawData() void ZCollisionHeader::DeclareReferences(const std::string& prefix) { - std::string declaration; + std::string declaration = ""; std::string auxName = name; if (name == "") @@ -106,8 +144,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( waterBoxSegmentOffset, DeclarationAlignment::Align4, 16 * waterBoxes.size(), "WaterBox", - StringHelper::Sprintf("%s_waterBoxes_%06X", auxName.c_str(), waterBoxSegmentOffset), - waterBoxes.size(), declaration); + StringHelper::Sprintf("%sWaterBoxes", auxName.c_str()), waterBoxes.size(), declaration); } if (polygons.size() > 0) @@ -116,18 +153,14 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) for (size_t i = 0; i < polygons.size(); i++) { - declaration += StringHelper::Sprintf( - "\t{ 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X },", - polygons[i].type, polygons[i].vtxA, polygons[i].vtxB, polygons[i].vtxC, - polygons[i].a, polygons[i].b, polygons[i].c, polygons[i].d); + declaration += StringHelper::Sprintf("\t%s,", polygons[i].GetBodySourceCode().c_str()); if (i + 1 < polygons.size()) declaration += "\n"; } parent->AddDeclarationArray( - polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly", - StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset), - polygons.size(), declaration); + polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, polygons[0].GetSourceTypeName().c_str(), + StringHelper::Sprintf("%sPolygons", auxName.c_str()), polygons.size(), declaration); } declaration.clear(); @@ -141,11 +174,10 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) } if (polyTypeDefAddress != 0) - parent->AddDeclarationArray( - polyTypeDefSegmentOffset, DeclarationAlignment::Align4, polygonTypes.size() * 8, - "SurfaceType", - StringHelper::Sprintf("%s_surfaceType_%08X", auxName.c_str(), polyTypeDefSegmentOffset), - polygonTypes.size(), declaration); + parent->AddDeclarationArray(polyTypeDefSegmentOffset, DeclarationAlignment::Align4, + polygonTypes.size() * 8, "SurfaceType", + StringHelper::Sprintf("%sSurfaceType", auxName.c_str()), + polygonTypes.size(), declaration); declaration.clear(); @@ -167,14 +199,13 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( vtxSegmentOffset, first.GetDeclarationAlignment(), vertices.size() * first.GetRawDataSize(), first.GetSourceTypeName(), - StringHelper::Sprintf("%s_vtx_%08X", auxName.c_str(), vtxSegmentOffset), - vertices.size(), declaration); + StringHelper::Sprintf("%sVertices", auxName.c_str()), vertices.size(), declaration); } } std::string ZCollisionHeader::GetBodySourceCode() const { - std::string declaration; + std::string declaration = ""; declaration += "\n"; @@ -183,11 +214,11 @@ std::string ZCollisionHeader::GetBodySourceCode() const std::string vtxName; Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s,\n", numVerts, vtxName.c_str()); std::string polyName; Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s,\n", numPolygons, polyName.c_str()); std::string surfaceName; Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName); @@ -199,7 +230,7 @@ std::string ZCollisionHeader::GetBodySourceCode() const std::string waterBoxName; Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName); - declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str()); + declaration += StringHelper::Sprintf("\t%i, %s\n", numWaterBoxes, waterBoxName.c_str()); return declaration; } @@ -224,34 +255,18 @@ size_t ZCollisionHeader::GetRawDataSize() const return 44; } -PolygonEntry::PolygonEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - type = BitConverter::ToUInt16BE(data, rawDataIndex + 0); - vtxA = BitConverter::ToUInt16BE(data, rawDataIndex + 2); - vtxB = BitConverter::ToUInt16BE(data, rawDataIndex + 4); - vtxC = BitConverter::ToUInt16BE(data, rawDataIndex + 6); - a = BitConverter::ToUInt16BE(data, rawDataIndex + 8); - b = BitConverter::ToUInt16BE(data, rawDataIndex + 10); - c = BitConverter::ToUInt16BE(data, rawDataIndex + 12); - d = BitConverter::ToUInt16BE(data, rawDataIndex + 14); -} - WaterBoxHeader::WaterBoxHeader(const std::vector& rawData, uint32_t rawDataIndex) { - const uint8_t* data = rawData.data(); - - xMin = BitConverter::ToInt16BE(data, rawDataIndex + 0); - ySurface = BitConverter::ToInt16BE(data, rawDataIndex + 2); - zMin = BitConverter::ToInt16BE(data, rawDataIndex + 4); - xLength = BitConverter::ToInt16BE(data, rawDataIndex + 6); - zLength = BitConverter::ToInt16BE(data, rawDataIndex + 8); + xMin = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + ySurface = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + zMin = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + xLength = BitConverter::ToInt16BE(rawData, rawDataIndex + 6); + zLength = BitConverter::ToInt16BE(rawData, rawDataIndex + 8); if (Globals::Instance->game == ZGame::OOT_SW97) - properties = BitConverter::ToInt16BE(data, rawDataIndex + 10); + properties = BitConverter::ToInt16BE(rawData, rawDataIndex + 10); else - properties = BitConverter::ToInt32BE(data, rawDataIndex + 12); + properties = BitConverter::ToInt32BE(rawData, rawDataIndex + 12); } std::string WaterBoxHeader::GetBodySourceCode() const @@ -261,16 +276,17 @@ std::string WaterBoxHeader::GetBodySourceCode() const } CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, - const std::vector& rawData, uint32_t rawDataIndex, - uint32_t polyTypeDefSegmentOffset, - [[maybe_unused]] uint32_t polygonTypesCnt) + const std::vector& rawData, offset_t rawDataIndex, + offset_t upperCameraBoundary) { std::string declaration; // Parse CameraDataEntries - int32_t numElements = (polyTypeDefSegmentOffset - rawDataIndex) / 8; - uint32_t cameraPosDataSeg = rawDataIndex; - for (int32_t i = 0; i < numElements; i++) + size_t numElements = (upperCameraBoundary - rawDataIndex) / 8; + assert(numElements < 10000); + + offset_t cameraPosDataSeg = rawDataIndex; + for (size_t i = 0; i < numElements; i++) { CameraDataEntry* entry = new CameraDataEntry(); @@ -302,8 +318,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, { int32_t index = ((entries[i]->cameraPosDataSeg & 0x00FFFFFF) - cameraPosDataOffset) / 0x6; - sprintf(camSegLine, "&%s_camPosData_%08X[%i]", prefix.c_str(), cameraPosDataOffset, - index); + sprintf(camSegLine, "&%sCamPosData[%i]", prefix.c_str(), index); } else sprintf(camSegLine, "NULL"); @@ -318,7 +333,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, parent->AddDeclarationArray( rawDataIndex, DeclarationAlignment::Align4, entries.size() * 8, "CamData", - StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(), + StringHelper::Sprintf("%sCamDataList", prefix.c_str(), rawDataIndex), entries.size(), declaration); uint32_t numDataTotal = (rawDataIndex - cameraPosDataOffset) / 0x6; @@ -339,10 +354,9 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, int32_t cameraPosDataIndex = GETSEGOFFSET(cameraPosDataSeg); uint32_t entrySize = numDataTotal * 0x6; - parent->AddDeclarationArray( - cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, "Vec3s", - StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex), - numDataTotal, declaration); + parent->AddDeclarationArray(cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, + "Vec3s", StringHelper::Sprintf("%sCamPosData", prefix.c_str()), + numDataTotal, declaration); } } diff --git a/tools/ZAPD/ZAPD/ZCollision.h b/tools/ZAPD/ZAPD/ZCollision.h index d0325bfb9..7481a8526 100644 --- a/tools/ZAPD/ZAPD/ZCollision.h +++ b/tools/ZAPD/ZAPD/ZCollision.h @@ -4,7 +4,9 @@ #include "ZResource.h" #include "ZRoom/ZRoom.h" #include "ZVector.h" +#include "ZCollisionPoly.h" +#if 0 class PolygonEntry { public: @@ -14,6 +16,7 @@ public: PolygonEntry(const std::vector& rawData, uint32_t rawDataIndex); }; +#endif class WaterBoxHeader { @@ -55,8 +58,7 @@ public: std::vector cameraPositionData; CameraDataList(ZFile* parent, const std::string& prefix, const std::vector& rawData, - uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset, - uint32_t polygonTypesCnt); + offset_t rawDataIndex, offset_t upperCameraBoundary); ~CameraDataList(); }; @@ -79,7 +81,7 @@ public: waterBoxSegmentOffset; std::vector vertices; - std::vector polygons; + std::vector polygons; std::vector polygonTypes; std::vector waterBoxes; CameraDataList* camData = nullptr; diff --git a/tools/ZAPD/ZAPD/ZCollisionPoly.cpp b/tools/ZAPD/ZAPD/ZCollisionPoly.cpp new file mode 100644 index 000000000..eb2c14ab9 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCollisionPoly.cpp @@ -0,0 +1,76 @@ +#include "ZCollisionPoly.h" + +#include "Globals.h" +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" + +REGISTER_ZFILENODE(CollisionPoly, ZCollisionPoly); + +ZCollisionPoly::ZCollisionPoly(ZFile* nParent) : ZResource(nParent) +{ +} + +ZCollisionPoly::~ZCollisionPoly() +{ +} + +void ZCollisionPoly::ParseRawData() +{ + const auto& rawData = parent->GetRawData(); + type = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); + + vtxA = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); + vtxB = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); + vtxC = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); + + normX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8); + normY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10); + normZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12); + + dist = BitConverter::ToUInt16BE(rawData, rawDataIndex + 14); +} + +void ZCollisionPoly::DeclareReferences(const std::string& prefix) +{ + std::string declaration; + std::string auxName = name; + + if (name == "") + auxName = GetDefaultName(prefix); + + parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4,GetRawDataSize(), GetSourceTypeName(), name.c_str(),GetBodySourceCode()); +} + +std::string ZCollisionPoly::GetBodySourceCode() const +{ + std::string declaration; + + declaration += StringHelper::Sprintf("{0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X}", type, vtxA, vtxB, vtxC, normX, normY, normZ, dist); + return declaration; +} + +std::string ZCollisionPoly::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%sCollisionPoly_%06X", prefix.c_str(), rawDataIndex); +} + + +ZResourceType ZCollisionPoly::GetResourceType() const +{ + return ZResourceType::CollisionPoly; +} + +size_t ZCollisionPoly::GetRawDataSize() const +{ + return 16; +} + +std::string ZCollisionPoly::GetSourceTypeName() const +{ + return "CollisionPoly"; +} + +bool ZCollisionPoly::DoesSupportArray() const +{ + return true; +} \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZCollisionPoly.h b/tools/ZAPD/ZAPD/ZCollisionPoly.h new file mode 100644 index 000000000..9596d2253 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZCollisionPoly.h @@ -0,0 +1,30 @@ +#pragma once + +#include "ZFile.h" +#include "ZResource.h" + + +class ZCollisionPoly : public ZResource +{ +public: + uint16_t type; + uint16_t vtxA, vtxB, vtxC; + uint16_t normX, normY, normZ; + uint16_t dist; + + ZCollisionPoly(ZFile* nParent); + ~ZCollisionPoly(); + + void ParseRawData() override; + void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + std::string GetDefaultName(const std::string& prefix) const override; + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + bool DoesSupportArray() const override; + + size_t GetRawDataSize() const override; +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp index 237481079..62f814b13 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.cpp +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -1,12 +1,17 @@ #include "ZCutscene.h" +#include + +#include "Globals.h" +#include "OtherStructs/CutsceneMM_Commands.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZResource.h" REGISTER_ZFILENODE(Cutscene, ZCutscene); -ZCutscene::ZCutscene(ZFile* nParent) : ZCutsceneBase(nParent) +ZCutscene::ZCutscene(ZFile* nParent) : ZResource(nParent) { } @@ -15,91 +20,20 @@ ZCutscene::~ZCutscene() for (CutsceneCommand* cmd : commands) delete cmd; } -CutsceneCommandSetCameraPos::~CutsceneCommandSetCameraPos() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandSpecialAction::~CutsceneCommandSpecialAction() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandFadeBGM::~CutsceneCommandFadeBGM() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandPlayBGM::~CutsceneCommandPlayBGM() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandStopBGM::~CutsceneCommandStopBGM() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandEnvLighting::~CutsceneCommandEnvLighting() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandUnknown9::~CutsceneCommandUnknown9() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandUnknown::~CutsceneCommandUnknown() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandDayTime::~CutsceneCommandDayTime() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandTextbox::~CutsceneCommandTextbox() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandActorAction::~CutsceneCommandActorAction() -{ - for (auto e : entries) - delete e; -} - -CutsceneCommandSceneTransFX::~CutsceneCommandSceneTransFX() -{ -} std::string ZCutscene::GetBodySourceCode() const { - std::string output; - uint32_t curPtr = 0; + std::string output = ""; output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame); for (size_t i = 0; i < commands.size(); i++) { CutsceneCommand* cmd = commands[i]; - output += " " + cmd->GenerateSourceCode(curPtr); - curPtr += cmd->GetCommandSize(); + output += " " + cmd->GenerateSourceCode(); } - output += StringHelper::Sprintf(" CS_END(),\n", commands.size(), endFrame); + output += StringHelper::Sprintf(" CS_END(),", commands.size(), endFrame); return output; } @@ -114,12 +48,19 @@ size_t ZCutscene::GetRawDataSize() const for (size_t i = 0; i < commands.size(); i++) { CutsceneCommand* cmd = commands[i]; + size += cmd->GetCommandSize(); - size += 4; } // End - size += 8; + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + size += 4; + } + else + { + size += 8; + } return size; } @@ -134,152 +75,68 @@ void ZCutscene::ParseRawData() commands = std::vector(); endFrame = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); - uint32_t currentPtr = rawDataIndex + 8; + offset_t currentPtr = rawDataIndex + 8; for (int32_t i = 0; i < numCommands; i++) { - int32_t id = BitConverter::ToInt32BE(rawData, currentPtr); + uint32_t id = BitConverter::ToUInt32BE(rawData, currentPtr); - if (id == -1) + if (id == 0xFFFFFFFF) break; - CutsceneCommands cmdID = (CutsceneCommands)GetCommandFromID(id); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) + { + printf("Cutscene Command: 0x%X (%i)\n", id, id); + } + currentPtr += 4; - int32_t numEntries = 1; + CutsceneCommand* cmd = nullptr; - for (int32_t j = 0; j < numEntries; j++) + if (Globals::Instance->game == ZGame::MM_RETAIL) { - CutsceneCommand* cmd = nullptr; - - switch (cmdID) - { - case CutsceneCommands::Cmd00: - break; - case CutsceneCommands::SetCameraPos: - cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); - break; - case CutsceneCommands::SetCameraFocus: - cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); - break; - case CutsceneCommands::SpecialAction: - cmd = new CutsceneCommandSpecialAction(rawData, currentPtr); - break; - case CutsceneCommands::SetLighting: - cmd = new CutsceneCommandEnvLighting(rawData, currentPtr); - break; - case CutsceneCommands::SetCameraPosLink: - cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); - break; - case CutsceneCommands::SetCameraFocusLink: - cmd = new CutsceneCommandSetCameraPos(rawData, currentPtr); - break; - case CutsceneCommands::Cmd07: - break; - case CutsceneCommands::Cmd08: - break; - case CutsceneCommands::Cmd09: - cmd = new CutsceneCommandUnknown9(rawData, currentPtr); - break; - case CutsceneCommands::Textbox: - cmd = new CutsceneCommandTextbox(rawData, currentPtr); - break; - case CutsceneCommands::Unknown: - cmd = new CutsceneCommandUnknown(rawData, currentPtr); - break; - case CutsceneCommands::SetActorAction0: - case CutsceneCommands::SetActorAction1: - case CutsceneCommands::SetActorAction2: - case CutsceneCommands::SetActorAction3: - case CutsceneCommands::SetActorAction4: - case CutsceneCommands::SetActorAction5: - case CutsceneCommands::SetActorAction6: - case CutsceneCommands::SetActorAction7: - case CutsceneCommands::SetActorAction8: - case CutsceneCommands::SetActorAction9: - case CutsceneCommands::SetActorAction10: - cmd = new CutsceneCommandActorAction(rawData, currentPtr); - break; - case CutsceneCommands::SetSceneTransFX: - cmd = new CutsceneCommandSceneTransFX(rawData, currentPtr); - break; - case CutsceneCommands::Nop: - cmd = new CutsceneCommandNop(rawData, currentPtr); - break; - case CutsceneCommands::PlayBGM: - cmd = new CutsceneCommandPlayBGM(rawData, currentPtr); - break; - case CutsceneCommands::StopBGM: - cmd = new CutsceneCommandStopBGM(rawData, currentPtr); - break; - case CutsceneCommands::FadeBGM: - cmd = new CutsceneCommandFadeBGM(rawData, currentPtr); - break; - case CutsceneCommands::SetTime: - cmd = new CutsceneCommandDayTime(rawData, currentPtr); - break; - case CutsceneCommands::Terminator: - cmd = new CutsceneCommandTerminator(rawData, currentPtr); - break; - case CutsceneCommands::End: - cmd = new CutsceneCommandEnd(rawData, currentPtr); - break; - case CutsceneCommands::Error: - fprintf(stderr, "Cutscene command error %d %s %d\n", (int32_t)cmdID, __FILE__, - __LINE__); - break; - } - - cmd->commandIndex = i; - cmd->commandID = (uint32_t)id; - currentPtr += (uint32_t)cmd->GetCommandSize(); - - commands.push_back(cmd); + cmd = GetCommandMM(id, currentPtr); } + else + { + cmd = GetCommandOoT(id, currentPtr); + } + + if (cmd == nullptr) + { + HANDLE_WARNING_RESOURCE( + WarningType::NotImplemented, parent, this, rawDataIndex, + StringHelper::Sprintf("Cutscene command not implemented"), + StringHelper::Sprintf("Command ID: 0x%X\nIndex: %d\ncurrentPtr-rawDataIndex: 0x%X", + id, i, currentPtr - rawDataIndex)); + cmd = new CutsceneMMCommand_NonImplemented(rawData, currentPtr); + } + + assert(cmd != nullptr); + + cmd->commandIndex = i; + cmd->SetCommandID(id); + size_t commmandSize = cmd->GetCommandSize(); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) + { + printf("\t Command size: 0x%zX (%zu)\n", commmandSize, commmandSize); + } + currentPtr += commmandSize - 4; + + commands.push_back(cmd); } } -CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) +CutsceneCommand* ZCutscene::GetCommandOoT(uint32_t id, offset_t currentPtr) const { + CutsceneCommands cmdID = static_cast(id); + + const auto& rawData = parent->GetRawData(); + switch (id) { - case 0x0003: - return CutsceneCommands::SpecialAction; - case 0x0004: - return CutsceneCommands::SetLighting; - case 0x0056: - return CutsceneCommands::PlayBGM; - case 0x0057: - return CutsceneCommands::StopBGM; - case 0x007C: - return CutsceneCommands::FadeBGM; - case 0x0009: - return CutsceneCommands::Cmd09; - case 0x0013: - return CutsceneCommands::Textbox; - case 0x008C: - return CutsceneCommands::SetTime; - case 0x0001: - return CutsceneCommands::SetCameraPos; - case 0x0002: - return CutsceneCommands::SetCameraFocus; - case 0x0005: - return CutsceneCommands::SetCameraPosLink; - case 0x0006: - return CutsceneCommands::SetCameraFocusLink; - case 0x0007: - return CutsceneCommands::Cmd07; - case 0x0008: - return CutsceneCommands::Cmd08; - case 0x03E8: - return CutsceneCommands::Terminator; - case 0xFFFF: - return CutsceneCommands::End; - case 0x002D: - return CutsceneCommands::SetSceneTransFX; - case 10: - return CutsceneCommands::SetActorAction0; - case 15: + case 10: // CutsceneCommands::SetPlayerAction + case 15: // CutsceneCommands::SetActorAction1 case 17: case 18: case 23: @@ -297,8 +154,7 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 138: case 139: case 144: - return CutsceneCommands::SetActorAction1; - case 14: + case 14: // CutsceneCommands::SetActorAction2 case 16: case 24: case 35: @@ -316,8 +172,7 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 125: case 131: case 141: - return CutsceneCommands::SetActorAction2; - case 25: + case 25: // CutsceneCommands::SetActorAction3 case 36: case 41: case 50: @@ -330,8 +185,7 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 121: case 126: case 132: - return CutsceneCommands::SetActorAction3; - case 29: + case 29: // CutsceneCommands::SetActorAction4 case 37: case 42: case 51: @@ -344,8 +198,7 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 108: case 127: case 133: - return CutsceneCommands::SetActorAction4; - case 30: + case 30: // CutsceneCommands::SetActorAction5 case 38: case 43: case 47: @@ -354,16 +207,14 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 83: case 128: case 135: - return CutsceneCommands::SetActorAction5; - case 44: + case 44: // CutsceneCommands::SetActorAction6 case 55: case 77: case 84: case 90: case 129: case 136: - return CutsceneCommands::SetActorAction6; - case 31: + case 31: // CutsceneCommands::SetActorAction7 case 52: case 57: case 58: @@ -371,19 +222,17 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 115: case 130: case 137: - return CutsceneCommands::SetActorAction7; - case 49: + case 49: // CutsceneCommands::SetActorAction8 case 60: case 89: case 111: case 114: case 134: case 142: - return CutsceneCommands::SetActorAction8; - case 62: - return CutsceneCommands::SetActorAction9; - case 143: - return CutsceneCommands::SetActorAction10; + case 62: // CutsceneCommands::SetActorAction9 + case 143: // CutsceneCommands::SetActorAction10 + return new CutsceneCommand_ActorAction(rawData, currentPtr); + case 0x0B: case 0x0D: case 0x1A: @@ -401,841 +250,120 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) case 0x70: case 0x71: case 0x4A: - return CutsceneCommands::Unknown; + return new CutsceneCommand_GenericCmd(rawData, currentPtr, cmdID); } - fprintf(stderr, "WARNING: Could not identify cutscene command ID 0x%04X\n", id); - - return CutsceneCommands::Error; -} - -ZResourceType ZCutscene::GetResourceType() const -{ - return ZResourceType::Cutscene; -} - -CutsceneCommand::CutsceneCommand([[maybe_unused]] const std::vector& rawData, - [[maybe_unused]] uint32_t rawDataIndex) -{ -} - -CutsceneCommand::~CutsceneCommand() -{ -} - -std::string CutsceneCommand::GetCName() -{ - return "SCmdCutsceneData"; -} - -std::string CutsceneCommand::GenerateSourceCode(uint32_t baseAddress) -{ - return StringHelper::Sprintf("%s CutsceneData%04XCmd%02X = { 0x%02X,", GetCName().c_str(), - baseAddress, commandIndex, commandID); -} - -size_t CutsceneCommand::GetCommandSize() -{ - return 4; -} - -CutsceneCameraPoint::CutsceneCameraPoint(const std::vector& rawData, uint32_t rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - continueFlag = data[rawDataIndex + 0]; - cameraRoll = data[rawDataIndex + 1]; - nextPointFrame = BitConverter::ToInt16BE(data, rawDataIndex + 2); - viewAngle = BitConverter::ToFloatBE(data, rawDataIndex + 4); - - posX = BitConverter::ToInt16BE(data, rawDataIndex + 8); - posY = BitConverter::ToInt16BE(data, rawDataIndex + 10); - posZ = BitConverter::ToInt16BE(data, rawDataIndex + 12); - - unused = BitConverter::ToInt16BE(data, rawDataIndex + 14); -} - -CutsceneCommandSetCameraPos::CutsceneCommandSetCameraPos(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - base = BitConverter::ToUInt16BE(data, rawDataIndex + 0); - startFrame = BitConverter::ToUInt16BE(data, rawDataIndex + 2); - endFrame = BitConverter::ToUInt16BE(data, rawDataIndex + 4); - unused = BitConverter::ToUInt16BE(data, rawDataIndex + 6); - - entries = std::vector(); - - bool shouldContinue = true; - - uint32_t currentPtr = rawDataIndex + 8; - - while (shouldContinue) + switch (cmdID) { - CutsceneCameraPoint* camPoint = new CutsceneCameraPoint(rawData, currentPtr); - entries.push_back(camPoint); + case CutsceneCommands::Misc: + case CutsceneCommands::SetLighting: + case CutsceneCommands::PlayBGM: + case CutsceneCommands::StopBGM: + case CutsceneCommands::FadeBGM: + return new CutsceneCommand_GenericCmd(rawData, currentPtr, cmdID); - if (camPoint->continueFlag == -1) - shouldContinue = false; + case CutsceneCommands::SetCameraPos: + case CutsceneCommands::SetCameraFocus: + case CutsceneCommands::SetCameraPosLink: + case CutsceneCommands::SetCameraFocusLink: + return new CutsceneCommandSetCameraPos(rawData, currentPtr); - currentPtr += 16; + case CutsceneCommands::Cmd07: + break; + case CutsceneCommands::Cmd08: + break; + case CutsceneCommands::Cmd09: + return new CutsceneCommand_Rumble(rawData, currentPtr); + case CutsceneCommands::Textbox: + return new CutsceneCommand_TextBox(rawData, currentPtr); + + case CutsceneCommands::SetPlayerAction: + case CutsceneCommands::SetActorAction1: + case CutsceneCommands::SetActorAction2: + case CutsceneCommands::SetActorAction3: + case CutsceneCommands::SetActorAction4: + case CutsceneCommands::SetActorAction5: + case CutsceneCommands::SetActorAction6: + case CutsceneCommands::SetActorAction7: + case CutsceneCommands::SetActorAction8: + case CutsceneCommands::SetActorAction9: + case CutsceneCommands::SetActorAction10: + break; + + case CutsceneCommands::SetSceneTransFX: + return new CutsceneCommandSceneTransFX(rawData, currentPtr); + + case CutsceneCommands::SetTime: + return new CutsceneCommand_SetTime(rawData, currentPtr); + case CutsceneCommands::Terminator: + return new CutsceneCommand_Terminator(rawData, currentPtr); } + + return nullptr; } -// TODO -std::string CutsceneCommandSetCameraPos::GetCName() +CutsceneCommand* ZCutscene::GetCommandMM(uint32_t id, offset_t currentPtr) const { - return ""; -} + CutsceneMMCommands cmdID = static_cast(id); -std::string CutsceneCommandSetCameraPos::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; + const auto& rawData = parent->GetRawData(); - std::string listStr; - std::string posStr; - - if (commandID == (int32_t)CutsceneCommands::SetCameraFocus) + if (((id >= 100) && (id < 150)) || (id == 201) || ((id >= 450) && (id < 600))) { - listStr = "CS_CAM_FOCUS_POINT_LIST"; - posStr = "CS_CAM_FOCUS_POINT"; + return new CutsceneCommand_ActorAction(rawData, currentPtr); } - else if (commandID == (int32_t)CutsceneCommands::SetCameraFocusLink) + + switch (cmdID) { - listStr = "CS_CAM_FOCUS_POINT_PLAYER_LIST"; - posStr = "CS_CAM_FOCUS_POINT_PLAYER"; - } - else if (commandID == (int32_t)CutsceneCommands::SetCameraPosLink) - { - listStr = "CS_CAM_POS_PLAYER_LIST"; - posStr = "CS_CAM_POS_PLAYER"; - } - else - { - listStr = "CS_CAM_POS_LIST"; - posStr = "CS_CAM_POS"; + case CutsceneMMCommands::CS_CMD_MISC: + case CutsceneMMCommands::CS_CMD_SET_LIGHTING: + case CutsceneMMCommands::CS_CMD_SCENE_TRANS_FX: + case CutsceneMMCommands::CS_CMD_MOTIONBLUR: + case CutsceneMMCommands::CS_CMD_GIVETATL: + case CutsceneMMCommands::CS_CMD_PLAYSEQ: + case CutsceneMMCommands::CS_CMD_130: + case CutsceneMMCommands::CS_CMD_131: + case CutsceneMMCommands::CS_CMD_132: + case CutsceneMMCommands::CS_CMD_STOPSEQ: + case CutsceneMMCommands::CS_CMD_PLAYAMBIENCE: + case CutsceneMMCommands::CS_CMD_FADEAMBIENCE: + case CutsceneMMCommands::CS_CMD_TERMINATOR: + case CutsceneMMCommands::CS_CMD_CHOOSE_CREDITS_SCENES: + + case CutsceneMMCommands::CS_CMD_UNK_FA: + case CutsceneMMCommands::CS_CMD_UNK_FE: + case CutsceneMMCommands::CS_CMD_UNK_FF: + case CutsceneMMCommands::CS_CMD_UNK_100: + case CutsceneMMCommands::CS_CMD_UNK_101: + case CutsceneMMCommands::CS_CMD_UNK_102: + case CutsceneMMCommands::CS_CMD_UNK_103: + case CutsceneMMCommands::CS_CMD_UNK_104: + case CutsceneMMCommands::CS_CMD_UNK_105: + case CutsceneMMCommands::CS_CMD_UNK_108: + case CutsceneMMCommands::CS_CMD_UNK_109: + case CutsceneMMCommands::CS_CMD_UNK_12D: + return new CutsceneMMCommand_GenericCmd(rawData, currentPtr, cmdID); + + case CutsceneMMCommands::CS_CMD_TEXTBOX: + return new CutsceneCommand_TextBox(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_CAMERA: + return new CutsceneMMCommand_Camera(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_FADESCREEN: + return new CutsceneMMCommand_FadeScreen(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_FADESEQ: + return new CutsceneMMCommand_FadeSeq(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_SETTIME: + return new CutsceneCommand_SetTime(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION: + return new CutsceneCommand_ActorAction(rawData, currentPtr); + case CutsceneMMCommands::CS_CMD_RUMBLE: + return new CutsceneCommand_Rumble(rawData, currentPtr); } - result += StringHelper::Sprintf("%s(%i, %i),\n", listStr.c_str(), startFrame, endFrame); - - for (size_t i = 0; i < entries.size(); i++) - { - std::string continueMacro = "CS_CMD_CONTINUE"; - if (entries[i]->continueFlag != 0) - continueMacro = "CS_CMD_STOP"; - result += StringHelper::Sprintf(" %s(%s, 0x%02X, %i, %ff, %i, %i, %i, 0x%04X),\n", - posStr.c_str(), continueMacro.c_str(), - entries[i]->cameraRoll, entries[i]->nextPointFrame, - entries[i]->viewAngle, entries[i]->posX, entries[i]->posY, - entries[i]->posZ, entries[i]->unused); - } - - return result; -} - -size_t CutsceneCommandSetCameraPos::GetCommandSize() -{ - return 8 + (entries.size() * 16); -} - -MusicFadeEntry::MusicFadeEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); - startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); - endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); - unknown0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); - unknown1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); - unknown2 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); - unknown3 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 16); - unknown4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 20); - unknown5 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 24); - unknown6 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 28); - unknown7 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 32); - unknown8 = BitConverter::ToUInt32BE(rawData, - rawDataIndex + 36); // Macro hardcodes it as zero - unknown9 = BitConverter::ToUInt32BE(rawData, - rawDataIndex + 40); // Macro hardcodes it as zero - unknown10 = BitConverter::ToUInt32BE(rawData, - rawDataIndex + 44); // Macro hardcodes it as zero -} - -CutsceneCommandFadeBGM::CutsceneCommandFadeBGM(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - uint32_t numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0); - - rawDataIndex += 4; - - for (uint32_t i = 0; i < numEntries; i++) - { - entries.push_back(new MusicFadeEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandFadeBGM::GetCName() -{ - return "CsCmdMusicFade"; -} - -std::string CutsceneCommandFadeBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_FADE_BGM_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - " CS_FADE_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->base, - entries[i]->startFrame, entries[i]->endFrame, entries[i]->unknown0, - entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, entries[i]->unknown4, - entries[i]->unknown5, entries[i]->unknown6, entries[i]->unknown7); - } - - return result; -} - -size_t CutsceneCommandFadeBGM::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 0x30 * entries.size(); -} - -MusicChangeEntry::MusicChangeEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - sequence = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0); - startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2); - endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4); - unknown0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); - unknown1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); - unknown2 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); - unknown3 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 16); - unknown4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 20); - unknown5 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 24); - unknown6 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 28); - unknown7 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 32); -} - -CutsceneCommandPlayBGM::CutsceneCommandPlayBGM(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - uint32_t numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0); - - rawDataIndex += 4; - - for (uint32_t i = 0; i < numEntries; i++) - { - entries.push_back(new MusicChangeEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandPlayBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_PLAY_BGM_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - " CS_PLAY_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", - entries[i]->sequence, entries[i]->startFrame, entries[i]->endFrame, - entries[i]->unknown0, entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, - entries[i]->unknown4, entries[i]->unknown5, entries[i]->unknown6, entries[i]->unknown7); - } - - return result; -} - -std::string CutsceneCommandPlayBGM::GetCName() -{ - return "CsCmdMusicChange"; -} - -size_t CutsceneCommandPlayBGM::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 0x30; -} - -CutsceneCommandStopBGM::CutsceneCommandStopBGM(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - uint32_t numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0); - - rawDataIndex += 4; - - for (uint32_t i = 0; i < numEntries; i++) - { - entries.push_back(new MusicChangeEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandStopBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_STOP_BGM_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - "\t\tCS_STOP_BGM(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->sequence, - entries[i]->startFrame, entries[i]->endFrame, entries[i]->unknown0, - entries[i]->unknown1, entries[i]->unknown2, entries[i]->unknown3, entries[i]->unknown4, - entries[i]->unknown5, entries[i]->unknown6, entries[i]->unknown7); - } - - return result; -} - -std::string CutsceneCommandStopBGM::GetCName() -{ - return "CsCmdMusicChange"; -} - -size_t CutsceneCommandStopBGM::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 0x30; -} - -EnvLightingEntry::EnvLightingEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - setting = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - unused0 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); - unused1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); - unused2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); - unused3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); - unused4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); - unused5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); - unused6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); - unused7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); -} - -CutsceneCommandEnvLighting::CutsceneCommandEnvLighting(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new EnvLightingEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandEnvLighting::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_LIGHTING_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - "\t\tCS_LIGHTING(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", entries[i]->setting, - entries[i]->startFrame, entries[i]->endFrame, entries[i]->unused0, entries[i]->unused1, - entries[i]->unused2, entries[i]->unused3, entries[i]->unused4, entries[i]->unused5, - entries[i]->unused6, entries[i]->unused7); - } - - return result; -} - -std::string CutsceneCommandEnvLighting::GetCName() -{ - return "CsCmdEnvLighting"; -} - -size_t CutsceneCommandEnvLighting::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (0x30 * entries.size()); -} - -Unknown9Entry::Unknown9Entry(const std::vector& rawData, uint32_t rawDataIndex) -{ - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - unk2 = rawData[rawDataIndex + 6]; - unk3 = rawData[rawDataIndex + 7]; - unk4 = rawData[rawDataIndex + 8]; - unused0 = rawData[rawDataIndex + 10]; - unused1 = rawData[rawDataIndex + 11]; - ; -} - -CutsceneCommandUnknown9::CutsceneCommandUnknown9(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new Unknown9Entry(rawData, rawDataIndex)); - rawDataIndex += 0x0C; - } -} - -std::string CutsceneCommandUnknown9::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_CMD_09_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf("\t\tCS_CMD_09(%i, %i, %i, %i, %i, %i, %i, %i),\n", - entries[i]->base, entries[i]->startFrame, - entries[i]->endFrame, entries[i]->unk2, entries[i]->unk3, - entries[i]->unk4, entries[i]->unused0, entries[i]->unused1); - } - - return result; -} - -std::string CutsceneCommandUnknown9::GetCName() -{ - return "CsCmdUnknown9"; -} - -size_t CutsceneCommandUnknown9::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (entries.size() * 12); -} - -UnkEntry::UnkEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - unused0 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 0); - unused1 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 4); - unused2 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 8); - unused3 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 12); - unused4 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 16); - unused5 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 20); - unused6 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 24); - unused7 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 28); - unused8 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 32); - unused9 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 36); - unused10 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 40); - unused11 = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex + 44); -} - -CutsceneCommandUnknown::CutsceneCommandUnknown(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new UnkEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandUnknown::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%02X, %i),\n", commandID, entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - " CS_UNK_DATA(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),\n", - entries[i]->unused0, entries[i]->unused1, entries[i]->unused2, entries[i]->unused3, - entries[i]->unused4, entries[i]->unused5, entries[i]->unused6, entries[i]->unused7, - entries[i]->unused8, entries[i]->unused9, entries[i]->unused10, entries[i]->unused11); - } - - return result; -} - -std::string CutsceneCommandUnknown::GetCName() -{ - return "CsCmdUnknown1A"; -} - -size_t CutsceneCommandUnknown::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (entries.size() * 0x30); -} - -DayTimeEntry::DayTimeEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - hour = rawData[rawDataIndex + 6]; - minute = rawData[rawDataIndex + 7]; - unused = rawData[rawDataIndex + 8]; -} - -CutsceneCommandDayTime::CutsceneCommandDayTime(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new DayTimeEntry(rawData, rawDataIndex)); - rawDataIndex += 12; - } -} - -std::string CutsceneCommandDayTime::GetCName() -{ - return "CsCmdDayTime"; -} - -std::string CutsceneCommandDayTime::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_TIME_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - " CS_TIME(%i, %i, %i, %i, %i, %i),\n", entries[i]->base, entries[i]->startFrame, - entries[i]->endFrame, entries[i]->hour, entries[i]->minute, entries[i]->unused); - } - - return result; -} - -size_t CutsceneCommandDayTime::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (entries.size() * 12); -} - -TextboxEntry::TextboxEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - type = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); - textID1 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 8); - textID2 = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 10); -} - -CutsceneCommandTextbox::CutsceneCommandTextbox(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new TextboxEntry(rawData, rawDataIndex)); - rawDataIndex += 12; - } -} - -std::string CutsceneCommandTextbox::GetCName() -{ - return "CsCmdTextbox"; -} - -std::string CutsceneCommandTextbox::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_TEXT_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - if (entries[i]->base == 0xFFFF) - { - result += StringHelper::Sprintf(" CS_TEXT_NONE(%i, %i),\n", - entries[i]->startFrame, entries[i]->endFrame); - } - else - { - result += StringHelper::Sprintf( - " CS_TEXT_DISPLAY_TEXTBOX(%i, %i, %i, %i, %i, %i),\n", entries[i]->base, - entries[i]->startFrame, entries[i]->endFrame, entries[i]->type, entries[i]->textID1, - entries[i]->textID2); - } - } - - return result; -} - -size_t CutsceneCommandTextbox::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (entries.size() * 12); -} - -ActorAction::ActorAction(const std::vector& rawData, uint32_t rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - action = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 4); - rotX = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 6); - rotY = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 8); - rotZ = (uint16_t)BitConverter::ToInt16BE(data, rawDataIndex + 10); - startPosX = BitConverter::ToInt32BE(data, rawDataIndex + 12); - startPosY = BitConverter::ToInt32BE(data, rawDataIndex + 16); - startPosZ = BitConverter::ToInt32BE(data, rawDataIndex + 20); - endPosX = BitConverter::ToInt32BE(data, rawDataIndex + 24); - endPosY = BitConverter::ToInt32BE(data, rawDataIndex + 28); - endPosZ = BitConverter::ToInt32BE(data, rawDataIndex + 32); - normalX = BitConverter::ToFloatBE(data, rawDataIndex + 36); - normalY = BitConverter::ToFloatBE(data, rawDataIndex + 40); - normalZ = BitConverter::ToFloatBE(data, rawDataIndex + 44); -} - -CutsceneCommandActorAction::CutsceneCommandActorAction(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new ActorAction(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandActorAction::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - std::string subCommand; - - if (commandID == 10) - { - result += StringHelper::Sprintf("CS_PLAYER_ACTION_LIST(%i),\n", entries.size()); - subCommand = "CS_PLAYER_ACTION"; - } - else - { - result += StringHelper::Sprintf("CS_NPC_ACTION_LIST(%i, %i),\n", commandID, entries.size()); - subCommand = "CS_NPC_ACTION"; - } - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - "\t\t%s(0x%04X, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, %i, %i, %i, %i, %.11ef, " - "%.11ef, %.11ef),\n", - subCommand.c_str(), entries[i]->action, entries[i]->startFrame, entries[i]->endFrame, - entries[i]->rotX, entries[i]->rotY, entries[i]->rotZ, entries[i]->startPosX, - entries[i]->startPosY, entries[i]->startPosZ, entries[i]->endPosX, entries[i]->endPosY, - entries[i]->endPosZ, entries[i]->normalX, entries[i]->normalY, entries[i]->normalZ); - } - - return result; -} - -std::string CutsceneCommandActorAction::GetCName() -{ - return "CsCmdBase"; -} - -size_t CutsceneCommandActorAction::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (entries.size() * 0x30); -} - -CutsceneCommandTerminator::CutsceneCommandTerminator(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - rawDataIndex += 4; - - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - unknown = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 6); // endFrame duplicate -} - -std::string CutsceneCommandTerminator::GetCName() -{ - return "CsCmdBase"; -} - -std::string CutsceneCommandTerminator::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_TERMINATOR(0x%04X, %i, %i),\n", base, startFrame, endFrame); - - return result; -} - -size_t CutsceneCommandTerminator::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 8; -} - -CutsceneCommandEnd::CutsceneCommandEnd(const std::vector& rawData, uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); -} - -std::string CutsceneCommandEnd::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_END(),\n"); - - return result; -} - -std::string CutsceneCommandEnd::GetCName() -{ - return "CsCmdBase"; -} - -size_t CutsceneCommandEnd::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 6; -} - -SpecialActionEntry::SpecialActionEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - base = BitConverter::ToUInt16BE(data, rawDataIndex + 0); - startFrame = BitConverter::ToUInt16BE(data, rawDataIndex + 2); - endFrame = BitConverter::ToUInt16BE(data, rawDataIndex + 4); - unused0 = BitConverter::ToUInt16BE(data, rawDataIndex + 6); - unused1 = BitConverter::ToUInt32BE(data, rawDataIndex + 8); - unused2 = BitConverter::ToUInt32BE(data, rawDataIndex + 12); - unused3 = BitConverter::ToUInt32BE(data, rawDataIndex + 16); - unused4 = BitConverter::ToUInt32BE(data, rawDataIndex + 20); - unused5 = BitConverter::ToUInt32BE(data, rawDataIndex + 24); - unused6 = BitConverter::ToUInt32BE(data, rawDataIndex + 28); - unused7 = BitConverter::ToUInt32BE(data, rawDataIndex + 32); - unused8 = BitConverter::ToUInt32BE(data, rawDataIndex + 36); - unused9 = BitConverter::ToUInt32BE(data, rawDataIndex + 40); - unused10 = BitConverter::ToUInt32BE(data, rawDataIndex + 44); -} - -CutsceneCommandSpecialAction::CutsceneCommandSpecialAction(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - int32_t numEntries = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); - - rawDataIndex += 4; - - for (int32_t i = 0; i < numEntries; i++) - { - entries.push_back(new SpecialActionEntry(rawData, rawDataIndex)); - rawDataIndex += 0x30; - } -} - -std::string CutsceneCommandSpecialAction::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - std::string result; - - result += StringHelper::Sprintf("CS_MISC_LIST(%i),\n", entries.size()); - - for (size_t i = 0; i < entries.size(); i++) - { - result += StringHelper::Sprintf( - "\t\tCS_MISC(0x%04X, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, %i, %i, %i, %i, %i, " - "%i),\n", - entries[i]->base, entries[i]->startFrame, entries[i]->endFrame, entries[i]->unused0, - entries[i]->unused1, entries[i]->unused2, entries[i]->unused3, entries[i]->unused4, - entries[i]->unused5, entries[i]->unused6, entries[i]->unused7, entries[i]->unused8, - entries[i]->unused9, entries[i]->unused10); - } - - return result; -} - -std::string CutsceneCommandSpecialAction::GetCName() -{ - return "CsCmdBase"; -} - -size_t CutsceneCommandSpecialAction::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + (0x30 * entries.size()); -} - -CutsceneCommandNop::CutsceneCommandNop(const std::vector& rawData, uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); -} - -std::string CutsceneCommandNop::GetCName() -{ - return "CsCmdBase"; -} - -size_t CutsceneCommandNop::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 6; -} - -CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(const std::vector& rawData, - uint32_t rawDataIndex) - : CutsceneCommand(rawData, rawDataIndex) -{ - rawDataIndex += 4; - - base = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - startFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - endFrame = (uint16_t)BitConverter::ToInt16BE(rawData, rawDataIndex + 4); -} - -std::string CutsceneCommandSceneTransFX::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) -{ - return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i),\n", base, startFrame, endFrame); -} - -std::string CutsceneCommandSceneTransFX::GetCName() -{ - return "CsCmdBase"; -} - -size_t CutsceneCommandSceneTransFX::GetCommandSize() -{ - return CutsceneCommand::GetCommandSize() + 8; -} - -ZCutsceneBase::ZCutsceneBase(ZFile* nParent) : ZResource(nParent) -{ + return nullptr; } -Declaration* ZCutsceneBase::DeclareVar(const std::string& prefix, const std::string& bodyStr) +Declaration* ZCutscene::DeclareVar(const std::string& prefix, const std::string& bodyStr) { std::string auxName = name; @@ -1249,7 +377,12 @@ Declaration* ZCutsceneBase::DeclareVar(const std::string& prefix, const std::str return decl; } -std::string ZCutsceneBase::GetSourceTypeName() const +std::string ZCutscene::GetSourceTypeName() const { return "CutsceneData"; } + +ZResourceType ZCutscene::GetResourceType() const +{ + return ZResourceType::Cutscene; +} diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h index cbb6a78b0..098f3ad86 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.h +++ b/tools/ZAPD/ZAPD/ZCutscene.h @@ -1,424 +1,15 @@ #pragma once -#include +#include #include #include -#include "ZFile.h" -#include "ZResource.h" #include "tinyxml2.h" -enum class CutsceneCommands -{ - Cmd00 = 0x0000, - SetCameraPos = 0x0001, - SetCameraFocus = 0x0002, - SpecialAction = 0x0003, - SetLighting = 0x0004, - SetCameraPosLink = 0x0005, - SetCameraFocusLink = 0x0006, - Cmd07 = 0x0007, - Cmd08 = 0x0008, - Cmd09 = 0x0009, - Unknown = 0x001A, - Textbox = 0x0013, - SetActorAction0 = 0x000A, - SetActorAction1 = 0x000F, - SetActorAction2 = 0x000E, - SetActorAction3 = 0x0019, - SetActorAction4 = 0x001D, - SetActorAction5 = 0x001E, - SetActorAction6 = 0x002C, - SetActorAction7 = 0x001F, - SetActorAction8 = 0x0031, - SetActorAction9 = 0x003E, - SetActorAction10 = 0x008F, - SetSceneTransFX = 0x002D, - Nop = 0x000B, - PlayBGM = 0x0056, - StopBGM = 0x0057, - FadeBGM = 0x007C, - SetTime = 0x008C, - Terminator = 0x03E8, - End = 0xFFFF, - Error = 0xFEAF, -}; +#include "OtherStructs/Cutscene_Commands.h" +#include "ZFile.h" +#include "ZResource.h" -class CutsceneCameraPoint -{ -public: - int8_t continueFlag; - int8_t cameraRoll; - int16_t nextPointFrame; - float viewAngle; - int16_t posX, posY, posZ; - int16_t unused; - - CutsceneCameraPoint(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommand -{ -public: - uint32_t commandID; - uint32_t commandIndex; - virtual ~CutsceneCommand(); - CutsceneCommand(const std::vector& rawData, uint32_t rawDataIndex); - virtual std::string GetCName(); - virtual std::string GenerateSourceCode(uint32_t baseAddress); - virtual size_t GetCommandSize(); -}; - -class CutsceneCommandSetCameraPos : public CutsceneCommand -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unused; - - std::vector entries; - ~CutsceneCommandSetCameraPos(); - CutsceneCommandSetCameraPos(const std::vector& rawData, uint32_t rawDataIndex); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class SpecialActionEntry -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unused0; - uint32_t unused1; - uint32_t unused2; - uint32_t unused3; - uint32_t unused4; - uint32_t unused5; - uint32_t unused6; - uint32_t unused7; - uint32_t unused8; - uint32_t unused9; - uint32_t unused10; - - SpecialActionEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandSpecialAction : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandSpecialAction(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandSpecialAction(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class MusicFadeEntry -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unknown0; - uint32_t unknown1; - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - uint32_t unknown8; - uint32_t unknown9; - uint32_t unknown10; - - MusicFadeEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandFadeBGM : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandFadeBGM(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandFadeBGM(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class MusicChangeEntry -{ -public: - uint16_t sequence; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unknown0; - uint32_t unknown1; - uint32_t unknown2; - uint32_t unknown3; - uint32_t unknown4; - uint32_t unknown5; - uint32_t unknown6; - uint32_t unknown7; - - MusicChangeEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandPlayBGM : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandPlayBGM(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandPlayBGM(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class CutsceneCommandStopBGM : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandStopBGM(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandStopBGM(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class EnvLightingEntry -{ -public: - uint16_t setting; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unused0; - uint32_t unused1; - uint32_t unused2; - uint32_t unused3; - uint32_t unused4; - uint32_t unused5; - uint32_t unused6; - uint32_t unused7; - - EnvLightingEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandEnvLighting : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandEnvLighting(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandEnvLighting(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class CutsceneCommandSceneTransFX : public CutsceneCommand -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - ~CutsceneCommandSceneTransFX(); - CutsceneCommandSceneTransFX(const std::vector& rawData, uint32_t rawDataIndex); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class Unknown9Entry -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unk2; - uint16_t unk3; - uint16_t unk4; - uint8_t unused0; - uint8_t unused1; - - Unknown9Entry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandUnknown9 : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandUnknown9(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandUnknown9(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class UnkEntry -{ -public: - uint32_t unused0; - uint32_t unused1; - uint32_t unused2; - uint32_t unused3; - uint32_t unused4; - uint32_t unused5; - uint32_t unused6; - uint32_t unused7; - uint32_t unused8; - uint32_t unused9; - uint32_t unused10; - uint32_t unused11; - - UnkEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandUnknown : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandUnknown(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandUnknown(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class DayTimeEntry -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint8_t hour; - uint8_t minute; - uint8_t unused; - - DayTimeEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandDayTime : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandDayTime(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandDayTime(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class TextboxEntry -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t type; - uint16_t textID1; - uint16_t textID2; - - TextboxEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandTextbox : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandTextbox(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandTextbox(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class ActorAction -{ -public: - uint16_t action; - uint16_t startFrame; - uint16_t endFrame; - int16_t rotX, rotY, rotZ; - int32_t startPosX, startPosY, startPosZ; - int32_t endPosX, endPosY, endPosZ; - float normalX, normalY, normalZ; - - ActorAction(const std::vector& rawData, uint32_t rawDataIndex); -}; - -class CutsceneCommandActorAction : public CutsceneCommand -{ -public: - std::vector entries; - - CutsceneCommandActorAction(const std::vector& rawData, uint32_t rawDataIndex); - ~CutsceneCommandActorAction(); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class CutsceneCommandTerminator : public CutsceneCommand -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - uint16_t unknown; - - CutsceneCommandTerminator(const std::vector& rawData, uint32_t rawDataIndex); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class CutsceneCommandEnd : public CutsceneCommand -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - - CutsceneCommandEnd(const std::vector& rawData, uint32_t rawDataIndex); - std::string GetCName(); - std::string GenerateSourceCode(uint32_t baseAddress); - size_t GetCommandSize(); -}; - -class CutsceneCommandNop : public CutsceneCommand -{ -public: - uint16_t base; - uint16_t startFrame; - uint16_t endFrame; - - CutsceneCommandNop(const std::vector& rawData, uint32_t rawDataIndex); - std::string GetCName(); - size_t GetCommandSize(); -}; - -class ZCutsceneBase : public ZResource -{ -public: - ZCutsceneBase(ZFile* nParent); - - Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; - - std::string GetSourceTypeName() const override; -}; - -class ZCutscene : public ZCutsceneBase +class ZCutscene : public ZResource { public: ZCutscene(ZFile* nParent); @@ -426,15 +17,20 @@ public: void ParseRawData() override; + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; + std::string GetBodySourceCode() const override; size_t GetRawDataSize() const override; + std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; - CutsceneCommands GetCommandFromID(int32_t id); - int32_t numCommands; int32_t endFrame; std::vector commands; + +protected: + CutsceneCommand* GetCommandOoT(uint32_t id, offset_t currentPtr) const; + CutsceneCommand* GetCommandMM(uint32_t id, offset_t currentPtr) const; }; diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.cpp b/tools/ZAPD/ZAPD/ZCutsceneMM.cpp deleted file mode 100644 index d0208bc07..000000000 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "ZCutsceneMM.h" - -#include "Utils/BitConverter.h" -#include "Utils/StringHelper.h" - -ZCutsceneMM::ZCutsceneMM(ZFile* nParent) : ZCutsceneBase(nParent) -{ -} - -ZCutsceneMM::~ZCutsceneMM() -{ - for (CutsceneCommand* cmd : commands) - delete cmd; -} - -std::string ZCutsceneMM::GetBodySourceCode() const -{ - std::string output; - - output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),", numCommands, endFrame); - - for (size_t i = 0; i < data.size(); i++) - { - if ((i % 4) == 0) - output += "\n "; - output += StringHelper::Sprintf("0x%08X, ", data[i]); - } - - return output; -} - -size_t ZCutsceneMM::GetRawDataSize() const -{ - return 8 + data.size() * 4; -} - -void ZCutsceneMM::ParseRawData() -{ - const auto& rawData = parent->GetRawData(); - - numCommands = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); - commands = std::vector(); - - endFrame = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); - uint32_t currentPtr = rawDataIndex + 8; - uint32_t lastData = 0; - - // TODO currently cutscenes aren't being parsed, so just consume words until we see an end - // marker. - do - { - lastData = BitConverter::ToInt32BE(rawData, currentPtr); - data.push_back(lastData); - currentPtr += 4; - } while (lastData != 0xFFFFFFFF); -} - -ZResourceType ZCutsceneMM::GetResourceType() const -{ - return ZResourceType::Cutscene; -} diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.h b/tools/ZAPD/ZAPD/ZCutsceneMM.h deleted file mode 100644 index 41b7de37f..000000000 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include -#include -#include -#include "ZCutscene.h" -#include "ZFile.h" -#include "tinyxml2.h" - -class ZCutsceneMM : public ZCutsceneBase -{ -public: - ZCutsceneMM(ZFile* nParent); - virtual ~ZCutsceneMM(); - - std::string GetBodySourceCode() const override; - - size_t GetRawDataSize() const override; - - void ParseRawData() override; - ZResourceType GetResourceType() const override; - -protected: - int32_t numCommands; - int32_t endFrame; - std::vector commands; - - std::vector data; -}; 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..b81399e2a 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); @@ -391,7 +406,7 @@ void ZFile::AddResource(ZResource* res) resources.push_back(res); } -ZResource* ZFile::FindResource(uint32_t rawDataIndex) +ZResource* ZFile::FindResource(offset_t rawDataIndex) { for (ZResource* res : resources) { @@ -680,7 +695,7 @@ bool ZFile::GetDeclarationArrayIndexedName(segptr_t segAddress, size_t elementSi return true; } -Declaration* ZFile::GetDeclaration(uint32_t address) const +Declaration* ZFile::GetDeclaration(offset_t address) const { if (declarations.find(address) != declarations.end()) return declarations.at(address); @@ -688,7 +703,7 @@ Declaration* ZFile::GetDeclaration(uint32_t address) const return nullptr; } -Declaration* ZFile::GetDeclarationRanged(uint32_t address) const +Declaration* ZFile::GetDeclarationRanged(offset_t address) const { for (const auto decl : declarations) { @@ -699,7 +714,7 @@ Declaration* ZFile::GetDeclarationRanged(uint32_t address) const return nullptr; } -bool ZFile::HasDeclaration(uint32_t address) +bool ZFile::HasDeclaration(offset_t address) { assert(GETSEGNUM(address) == 0); return declarations.find(address) != declarations.end(); @@ -761,6 +776,11 @@ void ZFile::GenerateSourceHeaderFiles() { OutputFormatter formatter; + std::string objectNameUpper = StringHelper::ToUpper(GetName()); + + formatter.Write(StringHelper::Sprintf("#ifndef %s_H\n#define %s_H 1\n\n", + objectNameUpper.c_str(), objectNameUpper.c_str())); + for (ZResource* res : resources) { std::string resSrc = res->GetSourceOutputHeader(""); @@ -777,6 +797,8 @@ void ZFile::GenerateSourceHeaderFiles() formatter.Write(ProcessExterns()); + formatter.Write("#endif\n"); + fs::path headerFilename = GetSourceOutputFolderPath() / outName.stem().concat(".h"); if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) @@ -935,9 +957,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 +1007,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 +1052,6 @@ std::string ZFile::ProcessDeclarations() } } - output += "\n"; - return output; } @@ -1187,14 +1167,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 +1204,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 +1215,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 +1244,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 +1312,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..275e27f1b 100644 --- a/tools/ZAPD/ZAPD/ZFile.h +++ b/tools/ZAPD/ZAPD/ZFile.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -46,13 +45,14 @@ public: ~ZFile(); std::string GetName() const; + std::string GetOutName() const; ZFileMode GetMode() const; const fs::path& GetXmlFilePath() const; const std::vector& GetRawData() const; void ExtractResources(); void BuildSourceFile(); void AddResource(ZResource* res); - ZResource* FindResource(uint32_t rawDataIndex); + ZResource* FindResource(offset_t rawDataIndex); std::vector GetResourcesOfType(ZResourceType resType); Declaration* AddDeclaration(offset_t address, DeclarationAlignment alignment, size_t size, @@ -81,9 +81,9 @@ public: const std::string& expectedType, std::string& declName) const; - Declaration* GetDeclaration(uint32_t address) const; - Declaration* GetDeclarationRanged(uint32_t address) const; - bool HasDeclaration(uint32_t address); + Declaration* GetDeclaration(offset_t address) const; + Declaration* GetDeclarationRanged(offset_t address) const; + bool HasDeclaration(offset_t address); std::string GetHeaderInclude() const; std::string GetZRoomHeaderInclude() 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..034d0850b 100644 --- a/tools/ZAPD/ZAPD/ZLimb.cpp +++ b/tools/ZAPD/ZAPD/ZLimb.cpp @@ -5,11 +5,14 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" +#include "ZSkeleton.h" REGISTER_ZFILENODE(Limb, ZLimb); ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent), segmentStruct(nParent) { + RegisterOptionalAttribute("EnumName"); RegisterOptionalAttribute("LimbType"); RegisterOptionalAttribute("Type"); } @@ -30,6 +33,12 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); + auto& enumNameXml = registeredAttributes.at("EnumName").value; + if (enumNameXml != "") + { + enumName = enumNameXml; + } + // Reading from a std::string limbType = registeredAttributes.at("LimbType").value; if (limbType == "") // Reading from a @@ -37,17 +46,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 +116,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 +237,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 += @@ -238,11 +249,24 @@ std::string ZLimb::GetBodySourceCode() const } else { + std::string childStr; + std::string siblingStr; + if (limbsTable != nullptr) + { + childStr = limbsTable->GetLimbEnumName(childIndex); + siblingStr = limbsTable->GetLimbEnumName(siblingIndex); + } + else + { + childStr = StringHelper::Sprintf("0x%02X", childIndex); + siblingStr = StringHelper::Sprintf("0x%02X", siblingIndex); + } + if (type != ZLimbType::Curve) { entryStr += StringHelper::Sprintf("{ %i, %i, %i }, ", transX, transY, transZ); } - entryStr += StringHelper::Sprintf("0x%02X, 0x%02X,\n", childIndex, siblingIndex); + entryStr += StringHelper::Sprintf("%s, %s,\n", childStr.c_str(), siblingStr.c_str()); switch (type) { @@ -350,6 +374,11 @@ ZLimbType ZLimb::GetTypeByAttributeName(const std::string& attrName) return ZLimbType::Invalid; } +void ZLimb::SetLimbIndex(uint8_t nLimbIndex) +{ + limbIndex = nLimbIndex; +} + void ZLimb::DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, const std::string& limbSuffix) { diff --git a/tools/ZAPD/ZAPD/ZLimb.h b/tools/ZAPD/ZAPD/ZLimb.h index 53a414329..ce31e4295 100644 --- a/tools/ZAPD/ZAPD/ZLimb.h +++ b/tools/ZAPD/ZAPD/ZLimb.h @@ -18,9 +18,14 @@ enum class ZLimbType Legacy, }; +class ZLimbTable; + class ZLimb : public ZResource { public: + std::string enumName; + ZLimbTable* limbsTable = nullptr; // borrowed pointer, do not delete! + ZLimbType type = ZLimbType::Standard; ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only @@ -39,6 +44,8 @@ public: int16_t transX, transY, transZ; uint8_t childIndex, siblingIndex; + uint8_t limbIndex = 0; + ZLimb(ZFile* nParent); void ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nType); @@ -59,6 +66,8 @@ public: static const char* GetSourceTypeName(ZLimbType limbType); static ZLimbType GetTypeByAttributeName(const std::string& attrName); + void SetLimbIndex(uint8_t nLimbIndex); + protected: void DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, const std::string& limbSuffix); 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/ZPointer.cpp b/tools/ZAPD/ZAPD/ZPointer.cpp new file mode 100644 index 000000000..6e6945cad --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPointer.cpp @@ -0,0 +1,57 @@ +#include "ZPointer.h" + +#include "Globals.h" +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" +#include "WarningHandler.h" +#include "ZFile.h" + +REGISTER_ZFILENODE(Pointer, ZPointer); + +ZPointer::ZPointer(ZFile* nParent) : ZResource(nParent) +{ + RegisterRequiredAttribute("Type"); +} + +void ZPointer::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + type = registeredAttributes.at("Type").value; +} + +void ZPointer::ParseRawData() +{ + auto& rawData = parent->GetRawData(); + + ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex); +} + +std::string ZPointer::GetBodySourceCode() const +{ + std::string ptrName; + + Globals::Instance->GetSegmentedPtrName(ptr, parent, "", ptrName); + + return ptrName; +} + +bool ZPointer::DoesSupportArray() const +{ + return true; +} + +std::string ZPointer::GetSourceTypeName() const +{ + return type + "*"; +} + +ZResourceType ZPointer::GetResourceType() const +{ + return ZResourceType::Pointer; +} + +size_t ZPointer::GetRawDataSize() const +{ + return 0x04; +} diff --git a/tools/ZAPD/ZAPD/ZPointer.h b/tools/ZAPD/ZAPD/ZPointer.h new file mode 100644 index 000000000..8fb588933 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPointer.h @@ -0,0 +1,22 @@ +#pragma once + +#include "ZResource.h" + +class ZPointer : public ZResource +{ +public: + segptr_t ptr = SEGMENTED_NULL; + std::string type; + + ZPointer(ZFile* nParent); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + std::string GetBodySourceCode() const override; + + bool DoesSupportArray() const override; + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; +}; diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp index cb811f4c3..8825cc97b 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; @@ -242,6 +247,11 @@ offset_t ZResource::GetRawDataIndex() const return rawDataIndex; } +void ZResource::SetRawDataIndex(offset_t nRawDataIndex) +{ + rawDataIndex = nRawDataIndex; +} + std::string ZResource::GetBodySourceCode() const { return "ERROR"; @@ -253,18 +263,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 +325,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..35984679c 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 @@ -32,6 +31,7 @@ enum class ZResourceType Background, Blob, CollisionHeader, + CollisionPoly, Cutscene, DisplayList, Limb, @@ -39,6 +39,7 @@ enum class ZResourceType Mtx, Path, PlayerAnimationData, + Pointer, Room, RoomCommand, Scalar, @@ -113,7 +114,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(); /** @@ -150,6 +151,8 @@ public: [[nodiscard]] const std::string& GetOutName() const; void SetOutName(const std::string& nName); [[nodiscard]] offset_t GetRawDataIndex() const; + void SetRawDataIndex(offset_t nRawDataIndex); + /** * The size of the current struct being extracted, not counting data referenced by it */ diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp index e51e550b0..3820203ef 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp @@ -10,53 +10,65 @@ SetCutscenes::SetCutscenes(ZFile* nParent) : ZRoomCommand(nParent) { } -SetCutscenes::~SetCutscenes() -{ - for (ZCutsceneBase* cutscene : cutscenes) - delete cutscene; -} - void SetCutscenes::ParseRawData() { ZRoomCommand::ParseRawData(); - std::string output; numCutscenes = cmdArg1; - if (Globals::Instance->game == ZGame::OOT_RETAIL || Globals::Instance->game == ZGame::OOT_SW97) - { - ZCutscene* cutscene = new ZCutscene(parent); - cutscene->ExtractFromFile(segmentOffset); - auto decl = parent->GetDeclaration(segmentOffset); - if (decl == nullptr) - { - cutscene->DeclareVar(zRoom->GetName().c_str(), ""); - } - - cutscenes.push_back(cutscene); - } - else + if (Globals::Instance->game == ZGame::MM_RETAIL) { int32_t currentPtr = segmentOffset; - std::string declaration; for (uint8_t i = 0; i < numCutscenes; i++) { CutsceneEntry entry(parent->GetRawData(), currentPtr); cutsceneEntries.push_back(entry); currentPtr += 8; + } + } +} - // TODO: don't hardcode %sCutsceneData_%06X, look up for the declared name instead - declaration += StringHelper::Sprintf( - " { %sCutsceneData_%06X, 0x%04X, 0x%02X, 0x%02X },", zRoom->GetName().c_str(), - entry.segmentOffset, entry.exit, entry.entrance, entry.flag); +void SetCutscenes::DeclareReferences(const std::string& prefix) +{ + std::string varPrefix = name; + if (varPrefix == "") + varPrefix = prefix; - if (i < numCutscenes - 1) + if (Globals::Instance->game == ZGame::MM_RETAIL) + { + std::string declaration; + size_t i = 0; + + for (const auto& entry : cutsceneEntries) + { + if (entry.segmentPtr != SEGMENTED_NULL && + GETSEGNUM(entry.segmentPtr) == parent->segment) + { + offset_t csOffset = Seg2Filespace(entry.segmentPtr, parent->baseAddress); + if (!parent->HasDeclaration(csOffset)) + { + auto* cutscene = new ZCutscene(parent); + cutscene->ExtractFromFile(csOffset); + cutscene->SetName(cutscene->GetDefaultName(varPrefix)); + cutscene->DeclareVar(varPrefix, ""); + cutscene->DeclareReferences(varPrefix); + parent->AddResource(cutscene); + } + } + + std::string csName; + Globals::Instance->GetSegmentedPtrName(entry.segmentPtr, parent, "CutsceneData", + csName); + + declaration += + StringHelper::Sprintf(" { %s, 0x%04X, 0x%02X, 0x%02X },", csName.c_str(), + entry.exit, entry.entrance, entry.flag); + + if (i + 1 < numCutscenes) declaration += "\n"; - ZCutsceneMM* cutscene = new ZCutsceneMM(parent); - cutscene->ExtractFromFile(entry.segmentOffset); - cutscenes.push_back(cutscene); + i++; } parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, @@ -65,19 +77,19 @@ void SetCutscenes::ParseRawData() zRoom->GetName().c_str(), segmentOffset), cutsceneEntries.size(), declaration); } - - for (ZCutsceneBase* cutscene : cutscenes) + else { - if (cutscene->GetRawDataIndex() != 0) + if (cmdArg2 != SEGMENTED_NULL && GETSEGNUM(cmdArg2) == parent->segment) { - Declaration* decl = parent->GetDeclaration(cutscene->GetRawDataIndex()); - if (decl == nullptr) + offset_t csOffset = Seg2Filespace(cmdArg2, parent->baseAddress); + if (!parent->HasDeclaration(csOffset)) { - cutscene->GetSourceOutputCode(zRoom->GetName()); - } - else if (decl->text == "") - { - decl->text = cutscene->GetBodySourceCode(); + auto* cutscene = new ZCutscene(parent); + cutscene->ExtractFromFile(csOffset); + cutscene->SetName(cutscene->GetDefaultName(varPrefix)); + cutscene->DeclareVar(varPrefix, ""); + cutscene->DeclareReferences(varPrefix); + parent->AddResource(cutscene); } } } @@ -86,11 +98,15 @@ void SetCutscenes::ParseRawData() std::string SetCutscenes::GetBodySourceCode() const { std::string listName; - Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName); if (Globals::Instance->game == ZGame::MM_RETAIL) + { + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneEntry", listName); return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_LIST(%i, %s)", numCutscenes, listName.c_str()); + } + + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName); return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_DATA(%s)", listName.c_str()); } @@ -105,7 +121,7 @@ RoomCommand SetCutscenes::GetRoomCommand() const } CutsceneEntry::CutsceneEntry(const std::vector& rawData, uint32_t rawDataIndex) - : segmentOffset(GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 0))), + : segmentPtr(BitConverter::ToInt32BE(rawData, rawDataIndex + 0)), exit(BitConverter::ToInt16BE(rawData, rawDataIndex + 4)), entrance(rawData[rawDataIndex + 6]), flag(rawData[rawDataIndex + 7]) { diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h index ad032bbe6..81a622c5b 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.h @@ -1,7 +1,6 @@ #pragma once #include "ZCutscene.h" -#include "ZCutsceneMM.h" #include "ZRoom/ZRoomCommand.h" class CutsceneEntry @@ -9,7 +8,7 @@ class CutsceneEntry public: CutsceneEntry(const std::vector& rawData, uint32_t rawDataIndex); - uint32_t segmentOffset; + segptr_t segmentPtr; uint16_t exit; uint8_t entrance; uint8_t flag; @@ -18,14 +17,13 @@ public: class SetCutscenes : public ZRoomCommand { public: - std::vector cutscenes; std::vector cutsceneEntries; // (MM Only) uint8_t numCutscenes; // (MM Only) SetCutscenes(ZFile* nParent); - ~SetCutscenes(); void ParseRawData() override; + void DeclareReferences(const std::string& prefix) override; std::string GetBodySourceCode() const override; 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..20138dd4d 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -104,9 +104,8 @@ std::string RomFile::GetBodySourceCode() const if (!isFirst) declaration += "\n"; - declaration += - StringHelper::Sprintf("\t{ (u32)_%sSegmentRomStart, (u32)_%sSegmentRomEnd },", - roomName.c_str(), roomName.c_str()); + declaration += StringHelper::Sprintf("\t{ _%sSegmentRomStart, _%sSegmentRomEnd },", + roomName.c_str(), roomName.c_str()); isFirst = false; } } @@ -115,11 +114,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..b3f7ce8c0 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.cpp +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -5,14 +5,18 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Skeleton, ZSkeleton); REGISTER_ZFILENODE(LimbTable, ZLimbTable); -ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent), limbsTable(nParent) +ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent) { RegisterRequiredAttribute("Type"); RegisterRequiredAttribute("LimbType"); + RegisterOptionalAttribute("EnumName"); + RegisterOptionalAttribute("LimbNone"); + RegisterOptionalAttribute("LimbMax"); } void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) @@ -27,18 +31,54 @@ 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'."); + } + + enumName = registeredAttributes.at("EnumName").value; + limbNoneName = registeredAttributes.at("LimbNone").value; + limbMaxName = registeredAttributes.at("LimbMax").value; + + if (enumName != "") + { + if (limbNoneName == "" || limbMaxName == "") + { + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "'EnumName' attribute was used but either 'LimbNone' or " + "'LimbMax' attribute is missing", + ""); + } + } + + if (limbNoneName != "") + { + if (limbMaxName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "'LimbNone' attribute was used but 'LimbMax' attribute is missing", ""); + } + } + + if (limbMaxName != "") + { + if (limbNoneName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "'LimbMax' attribute was used but 'LimbNone' attribute is missing", ""); + } } } @@ -54,12 +94,6 @@ void ZSkeleton::ParseRawData() { dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8); } - - if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment) - { - uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); - limbsTable.ExtractFromBinary(ptr, limbType, limbCount); - } } void ZSkeleton::DeclareReferences(const std::string& prefix) @@ -70,14 +104,33 @@ void ZSkeleton::DeclareReferences(const std::string& prefix) ZResource::DeclareReferences(defaultPrefix); - if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment) + if (limbsArrayAddress != SEGMENTED_NULL && GETSEGNUM(limbsArrayAddress) == parent->segment) { - uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); + offset_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); + if (!parent->HasDeclaration(ptr)) { - limbsTable.SetName(StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str())); - limbsTable.DeclareReferences(prefix); - limbsTable.GetSourceOutputCode(prefix); + limbsTable = new ZLimbTable(parent); + limbsTable->ExtractFromBinary(ptr, limbType, limbCount); + limbsTable->SetName(StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str())); + parent->AddResource(limbsTable); + } + else + { + limbsTable = static_cast(parent->FindResource(ptr)); + } + + if (limbsTable->enumName == "") + { + limbsTable->enumName = enumName; + } + if (limbsTable->limbNoneName == "") + { + limbsTable->limbNoneName = limbNoneName; + } + if (limbsTable->limbMaxName == "") + { + limbsTable->limbMaxName = limbMaxName; } } } @@ -87,15 +140,27 @@ std::string ZSkeleton::GetBodySourceCode() const std::string limbArrayName; Globals::Instance->GetSegmentedPtrName(limbsArrayAddress, parent, "", limbArrayName); + std::string countStr; + assert(limbsTable != nullptr); + // There are some Skeletons with the wrong limb count on them, so this check is necessary. + if (limbsTable->count == limbCount) + { + countStr = StringHelper::Sprintf("ARRAY_COUNT(%s)", limbArrayName.c_str()); + } + else + { + countStr = StringHelper::Sprintf("%i", limbCount); + } + switch (type) { case ZSkeletonType::Normal: case ZSkeletonType::Curve: - return StringHelper::Sprintf("\n\t%s, %i\n", limbArrayName.c_str(), limbCount); + return StringHelper::Sprintf("\n\t%s, %s\n", limbArrayName.c_str(), countStr.c_str()); case ZSkeletonType::Flex: - return StringHelper::Sprintf("\n\t{ %s, %i }, %i\n", limbArrayName.c_str(), limbCount, - dListCount); + return StringHelper::Sprintf("\n\t{ %s, %s }, %i\n", limbArrayName.c_str(), + countStr.c_str(), dListCount); } // TODO: Throw exception? @@ -137,7 +202,7 @@ ZResourceType ZSkeleton::GetResourceType() const DeclarationAlignment ZSkeleton::GetDeclarationAlignment() const { - return DeclarationAlignment::Align16; + return DeclarationAlignment::Align4; } uint8_t ZSkeleton::GetLimbCount() @@ -151,6 +216,9 @@ ZLimbTable::ZLimbTable(ZFile* nParent) : ZResource(nParent) { RegisterRequiredAttribute("LimbType"); RegisterRequiredAttribute("Count"); + RegisterOptionalAttribute("EnumName"); + RegisterOptionalAttribute("LimbNone"); + RegisterOptionalAttribute("LimbMax"); } void ZLimbTable::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nLimbType, size_t nCount) @@ -170,15 +238,47 @@ 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; } count = StringHelper::StrToL(registeredAttributes.at("Count").value); + + enumName = registeredAttributes.at("EnumName").value; + limbNoneName = registeredAttributes.at("LimbNone").value; + limbMaxName = registeredAttributes.at("LimbMax").value; + + if (enumName != "") + { + if (limbNoneName == "" || limbMaxName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "'EnumName' attribute was used but 'LimbNone'/'LimbMax' attributes is missing", ""); + } + } + + if (limbNoneName != "") + { + if (limbMaxName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "'LimbNone' attribute was used but 'LimbMax' attribute is missing", ""); + } + } + + if (limbMaxName != "") + { + if (limbNoneName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "'LimbMax' attribute was used but 'LimbNone' attribute is missing", ""); + } + } } void ZLimbTable::ParseRawData() @@ -209,15 +309,28 @@ void ZLimbTable::DeclareReferences(const std::string& prefix) if (limbAddress != 0 && GETSEGNUM(limbAddress) == parent->segment) { uint32_t limbOffset = Seg2Filespace(limbAddress, parent->baseAddress); + ZLimb* limb; + if (!parent->HasDeclaration(limbOffset)) { - ZLimb* limb = new ZLimb(parent); + limb = new ZLimb(parent); limb->ExtractFromBinary(limbOffset, limbType); limb->SetName(limb->GetDefaultName(varPrefix)); limb->DeclareVar(varPrefix, ""); limb->DeclareReferences(varPrefix); parent->AddResource(limb); } + else + { + limb = static_cast(parent->FindResource(limbOffset)); + assert(limb != nullptr); + assert(limb->GetResourceType() == ZResourceType::Limb); + } + + limb->limbsTable = this; + limb->SetLimbIndex(i + 1); + + limbsReferences.push_back(limb); } } } @@ -246,6 +359,13 @@ std::string ZLimbTable::GetBodySourceCode() const Globals::Instance->GetSegmentedPtrName(limbsAddresses[i], parent, "", limbName); body += StringHelper::Sprintf("\t%s,", limbName.c_str()); + auto& limb = limbsReferences.at(i); + std::string limbEnumName = limb->enumName; + if (limbEnumName != "") + { + body += StringHelper::Sprintf(" /* %s */", limbEnumName.c_str()); + } + if (i + 1 < count) body += "\n"; } @@ -253,6 +373,46 @@ std::string ZLimbTable::GetBodySourceCode() const return body; } +std::string ZLimbTable::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) +{ + if (limbNoneName == "" || limbMaxName == "" || enumName == "") + { + // Don't produce a enum of any of those attributes is missing + return ""; + } + + std::string limbEnum = StringHelper::Sprintf("typedef enum %s {\n", enumName.c_str()); + + // This assumes there isn't any skeleton with more than 0x100 limbs + + limbEnum += StringHelper::Sprintf(" /* 0x00 */ %s,\n", limbNoneName.c_str()); + + size_t i = 0; + for (; i < count; i++) + { + auto& limb = limbsReferences.at(i); + std::string limbEnumName = limb->enumName; + + if (limbEnumName == "") + { + HANDLE_ERROR_RESOURCE( + WarningType::MissingAttribute, parent, this, rawDataIndex, + "Skeleton's enum attributes were used but at least one limb is missing its " + "'LimbName' attribute", + StringHelper::Sprintf("When processing limb %02i, named '%s' at offset '0x%X'", + i + 1, limb->GetName().c_str(), limb->GetRawDataIndex())); + } + + limbEnum += StringHelper::Sprintf(" /* 0x%02X */ %s,\n", i + 1, limbEnumName.c_str()); + } + + limbEnum += StringHelper::Sprintf(" /* 0x%02X */ %s\n", i + 1, limbMaxName.c_str()); + + limbEnum += StringHelper::Sprintf("} %s;\n", enumName.c_str()); + + return limbEnum; +} + std::string ZLimbTable::GetSourceTypeName() const { switch (limbType) @@ -283,3 +443,28 @@ size_t ZLimbTable::GetRawDataSize() const { return 4 * limbsAddresses.size(); } + +std::string ZLimbTable::GetLimbEnumName(uint8_t limbIndex) const +{ + if (limbIndex == 0xFF) + { + return "LIMB_DONE"; + } + + if (limbIndex < count) + { + std::string limbEnumName = limbsReferences.at(limbIndex)->enumName; + if (limbEnumName != "") + { + return StringHelper::Sprintf("%s - 1", limbEnumName.c_str()); + } + } + else + { + HANDLE_WARNING_RESOURCE(WarningType::InvalidExtractedData, parent, this, rawDataIndex, + StringHelper::Sprintf("Limb index '%02i' out of range", limbIndex), + ""); + } + + return StringHelper::Sprintf("0x%02X", limbIndex); +} diff --git a/tools/ZAPD/ZAPD/ZSkeleton.h b/tools/ZAPD/ZAPD/ZSkeleton.h index ed003ceaf..c437a8484 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.h +++ b/tools/ZAPD/ZAPD/ZSkeleton.h @@ -18,6 +18,17 @@ enum class ZSkeletonType class ZLimbTable : public ZResource { public: + ZLimbType limbType = ZLimbType::Standard; + size_t count = 0; + + std::vector limbsAddresses; + std::vector limbsReferences; // borrowed pointers, do not delete! + + // XML attributes + std::string enumName; + std::string limbNoneName; + std::string limbMaxName; + ZLimbTable(ZFile* nParent); void ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nLimbType, size_t nCount); @@ -30,16 +41,14 @@ public: std::string GetBodySourceCode() const override; + std::string GetSourceOutputHeader(const std::string& prefix) override; + std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; size_t GetRawDataSize() const override; -protected: - ZLimbType limbType = ZLimbType::Standard; - size_t count = 0; - - std::vector limbsAddresses; + std::string GetLimbEnumName(uint8_t limbIndex) const; }; class ZSkeleton : public ZResource @@ -47,6 +56,10 @@ class ZSkeleton : public ZResource public: ZSkeletonType type = ZSkeletonType::Normal; ZLimbType limbType = ZLimbType::Standard; + std::string enumName; + std::string limbNoneName; + std::string limbMaxName; + segptr_t limbsArrayAddress; uint8_t limbCount = 0; uint8_t dListCount = 0; // FLEX SKELETON ONLY @@ -68,5 +81,5 @@ public: uint8_t GetLimbCount(); protected: - ZLimbTable limbsTable; + ZLimbTable* limbsTable = nullptr; // borrowed pointer, do not delete! }; 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..a9cb53941 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); @@ -15,6 +16,7 @@ ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent) { width = 0; height = 0; + dWordAligned = true; RegisterRequiredAttribute("Width"); RegisterRequiredAttribute("Height"); @@ -57,17 +59,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 +79,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 +95,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 +106,7 @@ 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()); + dWordAligned = false; switch (format) { @@ -136,8 +137,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; } } @@ -346,49 +350,51 @@ void ZTexture::DeclareReferences([[maybe_unused]] const std::string& prefix) void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath) { - switch (format) - { - case TextureType::RGBA16bpp: - PrepareRawDataRGBA16(pngFilePath); - break; - case TextureType::RGBA32bpp: - PrepareRawDataRGBA32(pngFilePath); - break; - case TextureType::Grayscale4bpp: - PrepareRawDataGrayscale4(pngFilePath); - break; - case TextureType::Grayscale8bpp: - PrepareRawDataGrayscale8(pngFilePath); - break; - case TextureType::GrayscaleAlpha4bpp: - PrepareRawDataGrayscaleAlpha4(pngFilePath); - break; - case TextureType::GrayscaleAlpha8bpp: - PrepareRawDataGrayscaleAlpha8(pngFilePath); - break; - case TextureType::GrayscaleAlpha16bpp: - PrepareRawDataGrayscaleAlpha16(pngFilePath); - break; - case TextureType::Palette4bpp: - PrepareRawDataPalette4(pngFilePath); - break; - case TextureType::Palette8bpp: - PrepareRawDataPalette8(pngFilePath); - break; - default: - throw std::runtime_error("Format is not supported!"); - } -} - -void ZTexture::PrepareRawDataRGBA16(const fs::path& rgbaPath) -{ - textureData.ReadPng(rgbaPath); + textureData.ReadPng(pngFilePath); width = textureData.GetWidth(); height = textureData.GetHeight(); textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); + textureDataRaw.resize(ALIGN8(GetRawDataSize())); + + switch (format) + { + case TextureType::RGBA16bpp: + PrepareRawDataRGBA16(); + break; + case TextureType::RGBA32bpp: + PrepareRawDataRGBA32(); + break; + case TextureType::Grayscale4bpp: + PrepareRawDataGrayscale4(); + break; + case TextureType::Grayscale8bpp: + PrepareRawDataGrayscale8(); + break; + case TextureType::GrayscaleAlpha4bpp: + PrepareRawDataGrayscaleAlpha4(); + break; + case TextureType::GrayscaleAlpha8bpp: + PrepareRawDataGrayscaleAlpha8(); + break; + case TextureType::GrayscaleAlpha16bpp: + PrepareRawDataGrayscaleAlpha16(); + break; + case TextureType::Palette4bpp: + PrepareRawDataPalette4(); + break; + case TextureType::Palette8bpp: + PrepareRawDataPalette8(); + break; + case TextureType::Error: + HANDLE_ERROR_PROCESS(WarningType::InvalidPNG, "Input PNG file has invalid format type", ""); + break; + } +} + +void ZTexture::PrepareRawDataRGBA16() +{ for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -410,15 +416,8 @@ void ZTexture::PrepareRawDataRGBA16(const fs::path& rgbaPath) } } -void ZTexture::PrepareRawDataRGBA32(const fs::path& rgbaPath) +void ZTexture::PrepareRawDataRGBA32() { - textureData.ReadPng(rgbaPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -434,15 +433,8 @@ void ZTexture::PrepareRawDataRGBA32(const fs::path& rgbaPath) } } -void ZTexture::PrepareRawDataGrayscale4(const fs::path& grayPath) +void ZTexture::PrepareRawDataGrayscale4() { - textureData.ReadPng(grayPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x += 2) @@ -456,15 +448,8 @@ void ZTexture::PrepareRawDataGrayscale4(const fs::path& grayPath) } } -void ZTexture::PrepareRawDataGrayscale8(const fs::path& grayPath) +void ZTexture::PrepareRawDataGrayscale8() { - textureData.ReadPng(grayPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -476,15 +461,8 @@ void ZTexture::PrepareRawDataGrayscale8(const fs::path& grayPath) } } -void ZTexture::PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath) +void ZTexture::PrepareRawDataGrayscaleAlpha4() { - textureData.ReadPng(grayAlphaPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x += 2) @@ -509,15 +487,8 @@ void ZTexture::PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath) } } -void ZTexture::PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath) +void ZTexture::PrepareRawDataGrayscaleAlpha8() { - textureData.ReadPng(grayAlphaPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -533,15 +504,8 @@ void ZTexture::PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath) } } -void ZTexture::PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath) +void ZTexture::PrepareRawDataGrayscaleAlpha16() { - textureData.ReadPng(grayAlphaPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -558,15 +522,8 @@ void ZTexture::PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath) } } -void ZTexture::PrepareRawDataPalette4(const fs::path& palPath) +void ZTexture::PrepareRawDataPalette4() { - textureData.ReadPng(palPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x += 2) @@ -581,15 +538,8 @@ void ZTexture::PrepareRawDataPalette4(const fs::path& palPath) } } -void ZTexture::PrepareRawDataPalette8(const fs::path& palPath) +void ZTexture::PrepareRawDataPalette8() { - textureData.ReadPng(palPath); - - width = textureData.GetWidth(); - height = textureData.GetHeight(); - - textureDataRaw.clear(); - textureDataRaw.resize(GetRawDataSize()); for (uint16_t y = 0; y < height; y++) { for (uint16_t x = 0; x < width; x++) @@ -717,7 +667,12 @@ void ZTexture::Save(const fs::path& outFolder) if (!Directory::Exists(outPath.string())) Directory::CreateDirectory(outPath.string()); - auto outFileName = outPath / (outName + "." + GetExternalExtension() + ".png"); + fs::path outFileName; + + if (!dWordAligned) + outFileName = outPath / (outName + ".u32" + "." + GetExternalExtension() + ".png"); + else + outFileName = outPath / (outName + +"." + GetExternalExtension() + ".png"); #ifdef TEXTURE_DEBUG printf("Saving PNG: %s\n", outFileName.c_str()); @@ -738,7 +693,7 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, { std::string auxName = name; std::string auxOutName = outName; - + std::string incStr; if (auxName == "") auxName = GetDefaultName(prefix); @@ -747,8 +702,12 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, auto filepath = Globals::Instance->outputPath / fs::path(auxOutName).stem(); - std::string incStr = - StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str()); + if (dWordAligned) + incStr = + StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str()); + else + incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", filepath.c_str(), + GetExternalExtension().c_str()); if (!Globals::Instance->cfg.texturePool.empty()) { @@ -758,13 +717,19 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, const auto& poolEntry = Globals::Instance->cfg.texturePool.find(hash); if (poolEntry != Globals::Instance->cfg.texturePool.end()) { - incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(), - GetExternalExtension().c_str()); + if (dWordAligned) + incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(), + GetExternalExtension().c_str()); + else + incStr = StringHelper::Sprintf("%s.u32.%s.inc.c", poolEntry->second.path.c_str(), + GetExternalExtension().c_str()); } } + size_t texSizeDivisor = (dWordAligned) ? 8 : 4; - Declaration* decl = parent->AddDeclarationIncludeArray( - rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, GetRawDataSize() / 8); + Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), + GetSourceTypeName(), auxName, + GetRawDataSize() / texSizeDivisor); decl->staticConf = staticConf; return decl; } @@ -772,15 +737,17 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, std::string ZTexture::GetBodySourceCode() const { std::string sourceOutput; - - for (size_t i = 0; i < textureDataRaw.size(); i += 8) + size_t texSizeInc = (dWordAligned) ? 8 : 4; + for (size_t i = 0; i < textureDataRaw.size(); i += texSizeInc) { if (i % 32 == 0) sourceOutput += " "; - - sourceOutput += - StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i)); - + if (dWordAligned) + sourceOutput += + StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i)); + else + sourceOutput += + StringHelper::Sprintf("0x%08llX, ", BitConverter::ToUInt32BE(textureDataRaw, i)); if (i % 32 == 24) sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32)); } @@ -805,7 +772,7 @@ ZResourceType ZTexture::GetResourceType() const std::string ZTexture::GetSourceTypeName() const { - return "u64"; + return dWordAligned ? "u64" : "u32"; } void ZTexture::CalcHash() @@ -860,13 +827,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 +846,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/ZTexture.h b/tools/ZAPD/ZAPD/ZTexture.h index ef67c3f6e..6f2c49935 100644 --- a/tools/ZAPD/ZAPD/ZTexture.h +++ b/tools/ZAPD/ZAPD/ZTexture.h @@ -40,20 +40,21 @@ protected: void PrepareBitmapPalette8(); void PrepareRawDataFromFile(const fs::path& inFolder); - void PrepareRawDataRGBA16(const fs::path& rgbaPath); - void PrepareRawDataRGBA32(const fs::path& rgbaPath); - void PrepareRawDataGrayscale4(const fs::path& grayPath); - void PrepareRawDataGrayscale8(const fs::path& grayPath); - void PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath); - void PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath); - void PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath); - void PrepareRawDataPalette4(const fs::path& palPath); - void PrepareRawDataPalette8(const fs::path& palPath); + void PrepareRawDataRGBA16(); + void PrepareRawDataRGBA32(); + void PrepareRawDataGrayscale4(); + void PrepareRawDataGrayscale8(); + void PrepareRawDataGrayscaleAlpha4(); + void PrepareRawDataGrayscaleAlpha8(); + void PrepareRawDataGrayscaleAlpha16(); + void PrepareRawDataPalette4(); + void PrepareRawDataPalette8(); public: ZTexture(ZFile* nParent); bool isPalette = false; + bool dWordAligned = true; void ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, TextureType nType, bool nIsPalette); 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/decomp-permuter/src/net/__init__.py b/tools/ZAPD/ZAPD/any/any/zlib.static.txt similarity index 100% rename from tools/decomp-permuter/src/net/__init__.py rename to tools/ZAPD/ZAPD/any/any/zlib.static.txt 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..646fa1274 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h +++ b/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h @@ -1,155 +1,160 @@ #pragma once +#include +#include +#include +#include #include -#include #include +#define ALIGN8(val) (((val) + 7) & ~7) +#define ALIGN16(val) (((val) + 0xF) & ~0xF) +#define ALIGN64(val) (((val) + 0x3F) & ~0x3F) + +#ifdef _MSC_VER +#define __PRETTY_FUNCTION__ __FUNCSIG__ +#endif + class BitConverter { public: - static inline int8_t ToInt8BE(const uint8_t* data, int32_t offset) + static inline int8_t ToInt8BE(const std::vector& data, size_t offset) { - return (uint8_t)data[offset + 0]; + if (offset + 0 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return (int8_t)data.at(offset + 0); } - static inline int8_t ToInt8BE(const std::vector& data, int32_t offset) + static inline uint8_t ToUInt8BE(const std::vector& data, size_t offset) { - return (uint8_t)data[offset + 0]; + if (offset + 0 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying an out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return (uint8_t)data.at(offset + 0); } - static inline uint8_t ToUInt8BE(const uint8_t* data, int32_t offset) + static inline int16_t ToInt16BE(const std::vector& data, size_t offset) { - return (uint8_t)data[offset + 0]; + if (offset + 1 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint16_t)data.at(offset + 0) << 8) + (uint16_t)data.at(offset + 1); } - static inline uint8_t ToUInt8BE(const std::vector& data, int32_t offset) + static inline uint16_t ToUInt16BE(const std::vector& data, size_t offset) { - return (uint8_t)data[offset + 0]; + if (offset + 1 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint16_t)data.at(offset + 0) << 8) + (uint16_t)data.at(offset + 1); } - static inline int16_t ToInt16BE(const uint8_t* data, int32_t offset) + static inline int32_t ToInt32BE(const std::vector& data, size_t offset) { - return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1]; + if (offset + 3 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint32_t)data.at(offset + 0) << 24) + ((uint32_t)data.at(offset + 1) << 16) + + ((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3); } - static inline int16_t ToInt16BE(const std::vector& data, int32_t offset) + static inline uint32_t ToUInt32BE(const std::vector& data, size_t offset) { - return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1]; + if (offset + 3 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint32_t)data.at(offset + 0) << 24) + ((uint32_t)data.at(offset + 1) << 16) + + ((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3); } - static inline uint16_t ToUInt16BE(const uint8_t* data, int32_t offset) + static inline int64_t ToInt64BE(const std::vector& data, size_t offset) { - return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1]; + if (offset + 7 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) + + ((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) + + ((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) + + ((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7)); } - static inline uint16_t ToUInt16BE(const std::vector& data, int32_t offset) + static inline uint64_t ToUInt64BE(const std::vector& data, size_t offset) { - return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1]; + if (offset + 7 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } + return ((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) + + ((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) + + ((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) + + ((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7)); } - static inline int32_t ToInt32BE(const uint8_t* data, int32_t offset) - { - return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; - } - - static inline int32_t ToInt32BE(const std::vector& data, int32_t offset) - { - return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; - } - - static inline uint32_t ToUInt32BE(const uint8_t* data, int32_t offset) - { - return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; - } - - static inline uint32_t ToUInt32BE(const std::vector& data, int32_t offset) - { - return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; - } - - static inline int64_t ToInt64BE(const uint8_t* data, int32_t offset) - { - return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); - } - - static inline int64_t ToInt64BE(const std::vector& data, int32_t offset) - { - return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); - } - - static inline uint64_t ToUInt64BE(const uint8_t* data, int32_t offset) - { - return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); - } - - static inline uint64_t ToUInt64BE(const std::vector& data, int32_t offset) - { - return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); - } - - static inline float ToFloatBE(const uint8_t* data, int32_t offset) + static inline float ToFloatBE(const std::vector& data, size_t offset) { + if (offset + 3 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } float value; - uint32_t floatData = ((uint32_t)data[offset + 0] << 24) + - ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; + uint32_t floatData = ((uint32_t)data.at(offset + 0) << 24) + + ((uint32_t)data.at(offset + 1) << 16) + + ((uint32_t)data.at(offset + 2) << 8) + (uint32_t)data.at(offset + 3); static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float"); std::memcpy(&value, &floatData, sizeof(value)); return value; } - static inline float ToFloatBE(const std::vector& data, int32_t offset) - { - float value; - uint32_t floatData = ((uint32_t)data[offset + 0] << 24) + - ((uint32_t)data[offset + 1] << 16) + - ((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3]; - static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float"); - std::memcpy(&value, &floatData, sizeof(value)); - return value; - } - - static inline double ToDoubleBE(const uint8_t* data, int32_t offset) + static inline double ToDoubleBE(const std::vector& data, size_t offset) { + if (offset + 7 > data.size()) + { + fprintf(stderr, "%s\n", __PRETTY_FUNCTION__); + fprintf(stderr, "Error: Trying a out-of-bounds reading from a data buffer\n"); + fprintf(stderr, "\t Buffer size: 0x%zX\n", data.size()); + fprintf(stderr, "\t Trying to read at offset: 0x%zX\n", offset); + } double value; uint64_t floatData = - ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); - static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double"); - // Checks if the float format on the platform the ZAPD binary is running on supports the - // same float format as the object file. - static_assert(std::numeric_limits::is_iec559, - "expected IEC559 floats on host machine"); - std::memcpy(&value, &floatData, sizeof(value)); - return value; - } - - static inline double ToDoubleBE(const std::vector& data, int32_t offset) - { - double value; - uint64_t floatData = - ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) + - ((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) + - ((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) + - ((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]); + ((uint64_t)data.at(offset + 0) << 56) + ((uint64_t)data.at(offset + 1) << 48) + + ((uint64_t)data.at(offset + 2) << 40) + ((uint64_t)data.at(offset + 3) << 32) + + ((uint64_t)data.at(offset + 4) << 24) + ((uint64_t)data.at(offset + 5) << 16) + + ((uint64_t)data.at(offset + 6) << 8) + ((uint64_t)data.at(offset + 7)); static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double"); // Checks if the float format on the platform the ZAPD binary is running on supports the // same float format as the object file. 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..2289927d8 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,17 @@ public: { return std::all_of(str.begin(), str.end(), ::isdigit); } + + static std::string ToUpper(const std::string& str) + { + std::string buff = str; + std::transform(buff.begin(), buff.end(), buff.begin(), ::toupper); + return buff; + } + + 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..c0ef260dd 100644 --- a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj +++ b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj @@ -1,165 +1,168 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {a2e01c3e-d647-45d1-9788-043debc1a908} - ZAPDUtils - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - StaticLibrary - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - - - - - - - true - - - false - - - true - - - false - - - - Level3 - true - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - true - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {a2e01c3e-d647-45d1-9788-043debc1a908} + ZAPDUtils + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + StaticLibrary + true + v143 + MultiByte + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + false + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDebug + Default + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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_extraction_xml_reference.md b/tools/ZAPD/docs/zapd_extraction_xml_reference.md index 06b95bb57..89ce33a6e 100644 --- a/tools/ZAPD/docs/zapd_extraction_xml_reference.md +++ b/tools/ZAPD/docs/zapd_extraction_xml_reference.md @@ -9,6 +9,7 @@ This document aims to be a small reference of how to create a compatible xml fil - [Basic XML](#basic-xml) - [Resources types](#resources-types) - [File](#file) + - [ExternalFile](#externalfile) - [Texture](#texture) - [Background](#background) - [Blob](#blob) @@ -33,6 +34,7 @@ This document aims to be a small reference of how to create a compatible xml fil - [Array](#array) - [Path](#path) - [PlayerAnimationData](#playeranimationdata) + - [Pointer](#pointer) ## Basic XML @@ -380,6 +382,13 @@ Useful only for the unused `object_human`'s animation data. - `Name`: Required. Suxffixed by `Skel`. - `Type`: Required. Valid values: `Normal`, `Flex` and `Curve`. - `LimbType`: Required. Valid values: `Standard`, `LOD`, `Skin`, `Curve` and `Legacy`. + - `EnumName`: Optional. The name of `typedef`'d limb enum. + - `LimbNone`: Optional. The name of the limb with index zero in the limb enum. + - `LimbMax`: Optional. The name of the max limb index in the limb enum. + +ZAPD is able to generate a limb enum by itself only if all the required data is provided. Providing some but not all the required data would trigger an error and the execution will halt. + +The required data is providing the `EnumName`, `LimbNone` and `LimbMax` attributes in the `Skeleton` or `LimbTable` node and the `EnumName` attribute in every `Limb` of this skeleton. ※ There are no restrictions in the `Type` and `LimbType` attributes besides the valid values, so any skeleton type can be combined with any limb type. @@ -398,6 +407,11 @@ Useful only for the unused `object_human`'s animation data. - `Name`: Required. Suxffixed by `Skel`. - `LimbType`: Required. Valid values: `Standard`, `LOD`, `Skin`, `Curve` and `Legacy`. - `Count`: Required. Amount of limbs. Integer. + - `EnumName`: Optional. The name of `typedef`'d limb enum. + - `LimbNone`: Optional. The name of the limb with index zero in the limb enum. + - `LimbMax`: Optional. The name of the max limb index in the limb enum. + +See [Skeleton](#skeleton) for info on the limb enum generation. ------------------------- @@ -413,6 +427,9 @@ Useful only for the unused `object_human`'s animation data. - `Name`: Required. Suxffixed by `Limb`. - `LimbType`: Required. Valid values: `Standard`, `LOD`, `Skin`, `Curve` and `Legacy`. + - `EnumName`: Optional. The name used for this limb in the limbs enum. It must be either present in every limb or in none. + +See [Skeleton](#skeleton) for info on the limb enum generation. ------------------------- @@ -589,7 +606,7 @@ Vec3s D_04002040[24] = { The `Array` element is special, because it needs an inner element to work. It will declare an array of its inner element. -Currently, only [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) support being wrapped in an array. +Currently, only [`Pointer`](#pointer), [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) support being wrapped in an array. - Example: @@ -637,3 +654,24 @@ Allows the extraction of the specific data of the player animations which are fo - `FrameCount`: Required. The length of the animation in frames. It must be a positive integer. ------------------------- + +### Pointer + +Allows the extraction of a variable that contains a pointer + +- Example: + +```xml + + + +``` + +- Attributes: + + - `Name`: Required. + - `Type`: Required. The type of the extracted pointer. + +※ Can be wrapped in an [`Array`](#array) tag. + +------------------------- 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/ZAPDConfigs/MM/ObjectList_MM.txt b/tools/ZAPDConfigs/MM/ObjectList_MM.txt index 5d8968d97..c3848574c 100644 --- a/tools/ZAPDConfigs/MM/ObjectList_MM.txt +++ b/tools/ZAPDConfigs/MM/ObjectList_MM.txt @@ -394,7 +394,7 @@ OBJECT_FALL OBJECT_HANAREYAMA_OBJ OBJECT_CRACE_OBJECT OBJECT_DNQ -OBJECT_OBJECT_UNSET_TOKEIDAI +OBJECT_OBJ_TOKEIDAI OBJECT_EG OBJECT_TRU OBJECT_TRT @@ -534,13 +534,13 @@ OBJECT_MASK_KYOJIN OBJECT_GI_RESERVE_C_01 OBJECT_ZOD OBJECT_KUMO30 -OBJECT_OBJECT_UNSET_YASI +OBJECT_OBJ_YASI OBJECT_MASK_ROMERNY OBJECT_TANRON1 OBJECT_TANRON2 OBJECT_TANRON3 OBJECT_GI_MAGICMUSHROOM -OBJECT_OBJECT_UNSET_CHAN +OBJECT_OBJ_CHAN OBJECT_GI_MASK10 OBJECT_ZOS OBJECT_MASK_POSTHAT @@ -578,7 +578,7 @@ OBJECT_TANRON5 OBJECT_DT OBJECT_GI_MASK03 OBJECT_CHA -OBJECT_OBJECT_UNSET_DINNER +OBJECT_OBJ_DINNER OBJECT_GI_RESERVE_B_01 OBJECT_LASTDAY OBJECT_BAI @@ -597,7 +597,7 @@ OBJECT_GI_SCHEDULE OBJECT_GI_STONEMASK OBJECT_ZORABAND OBJECT_KEPN_KOYA -OBJECT_OBJECT_UNSET_USIYANE +OBJECT_OBJ_USIYANE OBJECT_GI_MASK05 OBJECT_GI_MASK11 OBJECT_GI_MASK20 @@ -607,7 +607,7 @@ OBJECT_MASK_YOFUKASI OBJECT_MASK_MEOTO OBJECT_MASK_DANCER OBJECT_KZSAKU -OBJECT_OBJECT_UNSET_MILK_BIN +OBJECT_OBJ_MILK_BIN OBJECT_RANDOM_OBJ OBJECT_KUJIYA OBJECT_KITAN @@ -625,7 +625,7 @@ OBJECT_SYOTEN OBJECT_MOONEND OBJECT_OB OBJECT_GI_BOTTLE_04 -OBJECT_OBJECT_UNSET_DANPEILIFT +OBJECT_OBJ_DANPEILIFT OBJECT_WDOR01 OBJECT_WDOR02 OBJECT_WDOR03 @@ -640,4 +640,4 @@ OBJECT_GI_MASK22 OBJECT_LBFSHOT OBJECT_FUSEN OBJECT_ENDING_OBJ -OBJECT_GI_MASK13 \ No newline at end of file +OBJECT_GI_MASK13 diff --git a/tools/ZAPDConfigs/MM/SymbolMap_MM.txt b/tools/ZAPDConfigs/MM/SymbolMap_MM.txt index 015e7e88a..cc7b36b5e 100644 --- a/tools/ZAPDConfigs/MM/SymbolMap_MM.txt +++ b/tools/ZAPDConfigs/MM/SymbolMap_MM.txt @@ -1 +1 @@ -8012DB20 gMtxClear \ No newline at end of file +801D1DE0 gIdentityMtx diff --git a/tools/actorfixer.py b/tools/actorfixer.py deleted file mode 100755 index 4086528ef..000000000 --- a/tools/actorfixer.py +++ /dev/null @@ -1,186 +0,0 @@ -#!/usr/bin/env python3 - -import argparse, os - -# "old": "new" -animdict ={ - "Actor_GetSwitchFlag": "Flags_GetSwitch", - "atan_flip": "Math_Acot2F", - "atans": "Math_Atan2S", - "SysMatrix_StateAlloc": "Matrix_StateAlloc", - "SysMatrix_StatePush": "Matrix_StatePush", - "SysMatrix_CopyCurrentState": "Matrix_CopyCurrentState", - "SysMatrix_SetCurrentState": "Matrix_SetCurrentState", - "SysMatrix_InsertTranslation": "Matrix_InsertTranslation", - "SysMatrix_InsertMatrix": "Matrix_InsertMatrix", - "SysMatrix_Scale": "Matrix_Scale", - "SysMatrix_InsertXRotation_s": "Matrix_InsertXRotation_s", - "SysMatrix_InsertXRotation_f": "Matrix_InsertXRotation_f", - "SysMatrix_RotateStateAroundXAxis": "Matrix_RotateStateAroundXAxis", - "SysMatrix_SetStateXRotation": "Matrix_SetStateXRotation", - "SysMatrix_RotateY": "Matrix_RotateY", - "SysMatrix_InsertYRotation_f": "Matrix_InsertYRotation_f", - "SysMatrix_InsertZRotation_s": "Matrix_InsertZRotation_s", - "SysMatrix_InsertZRotation_f": "Matrix_InsertZRotation_f", - "SysMatrix_InsertRotation": "Matrix_InsertRotation", - "SysMatrix_JointPosition": "Matrix_JointPosition", - "SysMatrix_SetStateRotationAndTranslation": "Matrix_SetStateRotationAndTranslation", - "SysMatrix_ToRSPMatrix": "Matrix_ToRSPMatrix", - "SysMatrix_ToMtx": "Matrix_ToMtx", - "SysMatrix_NewMtx": "Matrix_NewMtx", - "SysMatrix_AppendToPolyOpaDisp": "Matrix_AppendToPolyOpaDisp", - "SysMatrix_MultiplyVector3fByState": "Matrix_MultiplyVector3fByState", - "SysMatrix_GetStateTranslation": "Matrix_GetStateTranslation", - "SysMatrix_GetStateTranslationAndScaledX": "Matrix_GetStateTranslationAndScaledX", - "SysMatrix_GetStateTranslationAndScaledY": "Matrix_GetStateTranslationAndScaledY", - "SysMatrix_GetStateTranslationAndScaledZ": "Matrix_GetStateTranslationAndScaledZ", - "SysMatrix_MultiplyVector3fXZByCurrentState": "Matrix_MultiplyVector3fXZByCurrentState", - "SysMatrix_MtxFCopy": "Matrix_MtxFCopy", - "SysMatrix_FromRSPMatrix": "Matrix_FromRSPMatrix", - "SysMatrix_MultiplyVector3fByMatrix": "Matrix_MultiplyVector3fByMatrix", - "SysMatrix_TransposeXYZ": "Matrix_TransposeXYZ", - "SysMatrix_NormalizeXYZ": "Matrix_NormalizeXYZ", - "SysMatrix_InsertRotationAroundUnitVector_f": "Matrix_InsertRotationAroundUnitVector_f", - "SysMatrix_InsertRotationAroundUnitVector_s": "Matrix_InsertRotationAroundUnitVector_s", - "func_800B78B8": "Actor_UpdateBgCheckInfo", - "func_8012403C": "Player_GetMask", - "func_8012404c": "Player_RemoveMask", - "Actor_SpawnWithParentAndCutscene": "Actor_SpawnAsChildAndCutscene", - "Actor_SpawnWithParent": "Actor_SpawnAsChild", - "func_800BE22C": "Actor_ApplyDamage", - "func_800F0568": "Audio_PlaySoundAtPosition", - "func_8016970C": "Play_CameraSetAtEye", - "func_800BBA88": "Enemy_StartFinishingBlow", - "ShrinkWindow_Step": "ShrinkWindow_Update", - "ShrinkWindow_Fini": "ShrinkWindow_Destroy", - "func_801A89A8": "Audio_QueueSeqCmd", - "SkelAnime_LodDrawLimb": "SkelAnime_DrawLimbLod", - "SkelAnime_LodDraw": "SkelAnime_DrawLod", - "SkelAnime_LodDrawLimbSV": "SkelAnime_DrawFlexLimbLod", - "SkelAnime_LodDrawSV": "SkelAnime_DrawFlexLod", - "SkelAnime_DrawLimb": "SkelAnime_DrawLimbOpa", - "SkelAnime_Draw": "SkelAnime_DrawOpa", - "SkelAnime_DrawLimbSV": "SkelAnime_DrawFlexLimbOpa", - "SkelAnime_DrawSV": "SkelAnime_DrawFlexOpa", - "SkelAnime_AnimateFrame": "SkelAnime_GetFrameData", - "SkelAnime_GetTotalFrames": "Animation_GetLength", - "SkelAnime_GetFrameCount": "Animation_GetLastFrame", - "SkelAnime_Draw2Limb": "SkelAnime_DrawLimb", - "SkelAnime_Draw2": "SkelAnime_Draw", - "SkelAnime_DrawLimbSV2": "SkelAnime_DrawFlexLimb", - "SkelAnime_DrawSV2": "SkelAnime_DrawFlex", - "func_80134FFC": "SkelAnime_GetFrameData2", - "func_801353D4": "Animation_GetLimbCount2", - "SkelAnime_GetTotalFrames2": "Animation_GetLength2", - "SkelAnime_GetFrameCount2": "Animation_GetLastFrame2", - "SkelAnime_InterpolateVec3s": "SkelAnime_InterpFrameTable", - "SkelAnime_AnimationCtxReset": "AnimationContext_Reset", - "func_801358D4": "AnimationContext_SetNextQueue", - "func_801358F4": "AnimationContext_DisableQueue", - "SkelAnime_NextEntry": "AnimationContext_AddEntry", - "SkelAnime_LoadLinkAnimetion": "AnimationContext_SetLoadFrame", - "SkelAnime_LoadAnimationType1": "AnimationContext_SetCopyAll", - "SkelAnime_LoadAnimationType2": "AnimationContext_SetInterp", - "SkelAnime_LoadAnimationType3": "AnimationContext_SetCopyTrue", - "SkelAnime_LoadAnimationType4": "AnimationContext_SetCopyFalse", - "SkelAnime_LoadAnimationType5": "AnimationContext_SetMoveActor", - "SkelAnime_LinkAnimetionLoaded": "AnimationContext_LoadFrame", - "SkelAnime_AnimationType1Loaded": "AnimationContext_CopyAll", - "SkelAnime_AnimationType2Loaded": "AnimationContext_CopyInterp", - "SkelAnime_AnimationType3Loaded": "AnimationContext_CopyTrue", - "SkelAnime_AnimationType4Loaded": "AnimationContext_CopyFalse", - "SkelAnime_AnimationType5Loaded": "AnimationContext_MoveActor", - "func_80135EE8": "AnimationContext_Update", - "SkelAnime_InitLinkAnimetion": "SkelAnime_InitLink", - "func_801360A8": "LinkAnimation_SetUpdateFunction", - "func_801360E0": "LinkAnimation_Update", - "func_80136104": "LinkAnimation_Morph", - "func_801361BC": "LinkAnimation_AnimateFrame", - "func_80136288": "LinkAnimation_Loop", - "func_8013631C": "LinkAnimation_Once", - "SkelAnime_SetTransition": "Animation_SetMorph", - "SkelAnime_ChangeLinkAnim": "LinkAnimation_Change", - "SkelAnime_ChangeLinkAnimDefaultStop": "LinkAnimation_PlayOnce", - "SkelAnime_ChangeLinkAnimPlaybackStop": "LinkAnimation_PlayOnceSetSpeed", - "SkelAnime_ChangeLinkAnimDefaultRepeat": "LinkAnimation_PlayLoop", - "SkelAnime_ChangeLinkAnimPlaybackRepeat": "LinkAnimation_PlayLoopSetSpeed", - "func_8013670C": "LinkAnimation_CopyJointToMorph", - "func_8013673C": "LinkAnimation_CopyMorphToJoint", - "func_8013676C": "LinkAnimation_LoadToMorph", - "func_801367B0": "LinkAnimation_LoadToJoint", - "func_801367F4": "LinkAnimation_InterpJointMorph", - "func_8013682C": "LinkAnimation_BlendToJoint", - "func_801368CC": "LinkAnimation_BlendToMorph", - "SkelAnime_SetModeStop": "LinkAnimation_EndLoop", - "func_80136990": "Animation_OnFrameImpl", - "func_80136A48": "LinkAnimation_OnFrame", - "SkelAnime_InitSV": "SkelAnime_InitFlex", - "func_80136C84": "SkelAnime_SetUpdate", - "SkelAnime_FrameUpdateMatrix": "SkelAnime_Update", - "func_80136CF4": "SkelAnime_Morph", - "func_80136D98": "SkelAnime_MorphTaper", - "func_80136F04": "SkelAnime_AnimateFrame", - "func_8013702C": "SkelAnime_LoopFull", - "func_801370B0": "SkelAnime_LoopPartial", - "func_8013713C": "SkelAnime_Once", - "SkelAnime_ChangeAnimImpl": "Animation_ChangeImpl", - "SkelAnime_ChangeAnim": "Animation_Change", - "SkelAnime_ChangeAnimDefaultStop": "Animation_PlayOnce", - "SkelAnime_ChangeAnimTransitionStop": "Animation_MorphToPlayOnce", - "SkelAnime_ChangeAnimPlaybackStop": "Animation_PlayOnceSetSpeed", - "SkelAnime_ChangeAnimDefaultRepeat": "Animation_PlayLoop", - "SkelAnime_ChangeAnimTransitionRepeat": "Animation_MorphToLoop", - "SkelAnime_ChangeAnimPlaybackRepeat": "Animation_PlayLoopSetSpeed", - "SkelAnime_AnimSetStop": "Animation_EndLoop", - "SkelAnime_AnimReverse": "Animation_Reverse", - "func_80137674": "SkelAnime_CopyFrameTableTrue", - "func_801376DC": "SkelAnime_CopyFrameTableFalse", - "func_80137748": "SkelAnime_UpdateTranslation", - "func_801378B8": "Animation_OnFrame", - "SkelAnime_CopyVec3s": "SkelAnime_CopyFrameTable", -} - -def replace_anim(file): - with open(file,'r',encoding = 'utf-8') as infile: - srcdata = infile.read() - - funcs = list(animdict.keys()) - fixes = 0 - for func in funcs: - newfunc = animdict.get(func) - if(newfunc is None): - print("How did this happen?") - return -1 - if(func in srcdata): - fixes += 1 - print(func) - srcdata = srcdata.replace(func, newfunc) - - if(fixes > 0): - print('Changed', fixes,'entr' + ('y' if fixes == 1 else 'ies') + ' in',file) - with open(file, 'w', encoding = 'utf-8', newline = '\n') as outfile: - outfile.write(srcdata) - return 1 - -def replace_anim_all(repo): - for subdir, dirs, files in os.walk(repo + os.sep + 'src'): - for filename in files: - if(filename.endswith('.c')): - file = subdir + os.sep + filename - replace_anim(file) - for subdir, dirs, files in os.walk(repo + os.sep + 'asm' + os.sep + 'non_matchings'): - for filename in files: - if(filename.endswith('.s')): - file = subdir + os.sep + filename - replace_anim(file) - return 1 - -parser = argparse.ArgumentParser(description='Update to the new animation names') -parser.add_argument('file', help="source file to be processed. use . to process the whole repo", default = None) - -if __name__ == "__main__": - args = parser.parse_args() - if(args.file == '.'): - replace_anim_all(os.curdir) - else: - replace_anim(args.file) diff --git a/tools/asm-differ/.gitrepo b/tools/asm-differ/.gitrepo index d3e4418c9..8d0a6445d 100644 --- a/tools/asm-differ/.gitrepo +++ b/tools/asm-differ/.gitrepo @@ -4,9 +4,9 @@ ; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme ; [subrepo] - remote = https://github.com/simonlindholm/asm-differ.git + remote = https://github.com/simonlindholm/asm-differ branch = main - commit = f30d43aceba6291aa3c08b7317b0458b6d734321 - parent = e977dfeb374c6de4076ca9a0f44ba5a6a701d849 + commit = 1236288d1520335c2bfb672078fec65084d7cb5c + parent = 2c5690701a350c7e7c3d6252dff925ad65d59910 method = merge cmdver = 0.4.3 diff --git a/tools/asm-differ/.pre-commit-config.yaml b/tools/asm-differ/.pre-commit-config.yaml index 6695f71ac..ccc4afc0e 100644 --- a/tools/asm-differ/.pre-commit-config.yaml +++ b/tools/asm-differ/.pre-commit-config.yaml @@ -1,6 +1,5 @@ repos: - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 22.1.0 hooks: - id: black - language_version: python3.6 diff --git a/tools/asm-differ/README.md b/tools/asm-differ/README.md index 4a7f329b3..205310d39 100644 --- a/tools/asm-differ/README.md +++ b/tools/asm-differ/README.md @@ -11,10 +11,10 @@ Nice differ for assembly code. Currently supports MIPS, PPC, AArch64, and ARM32; ## Usage -Create a file `diff_settings.sh` in some directory (see the one in this repo for an example). Then from that directory, run +Create a file `diff_settings.py` in some directory (see the one in this repo for an example). Then from that directory, run ```bash -/path/to/diff.sh [flags] (function|rom addr) +/path/to/diff.py [flags] (function|rom addr) ``` Recommended flags are `-mwo` (automatically run `make` on source file changes, and include symbols in diff). See `--help` for more details. diff --git a/tools/asm-differ/diff.py b/tools/asm-differ/diff.py index d7ac3f344..4b5bc892e 100755 --- a/tools/asm-differ/diff.py +++ b/tools/asm-differ/diff.py @@ -109,6 +109,15 @@ if __name__ == "__main__": help="""Diff .o files rather than a whole binary. This makes it possible to see symbol names. (Recommended)""", ) + parser.add_argument( + "-f", + "--objfile", + dest="objfile", + type=str, + help="""File path for an object file being diffed. When used + the map file isn't searched for the function given. Useful for dynamically + linked libraries.""", + ) parser.add_argument( "-e", "--elf", @@ -132,6 +141,14 @@ if __name__ == "__main__": help="""Tweak --source handling to make it work with binutils < 2.33. Implies --source.""", ) + parser.add_argument( + "-j", + "--section", + dest="diff_section", + default=".text", + metavar="SECTION", + help="Diff restricted to a given output section.", + ) parser.add_argument( "-L", "--line-numbers", @@ -356,6 +373,7 @@ except ModuleNotFoundError as e: class ProjectSettings: arch_str: str objdump_executable: str + objdump_flags: List[str] build_command: List[str] map_format: str mw_build_dir: str @@ -365,6 +383,7 @@ class ProjectSettings: source_directories: Optional[List[str]] source_extensions: List[str] show_line_numbers_default: bool + disassemble_all: bool @dataclass @@ -379,8 +398,10 @@ class Config: # Build/objdump options diff_obj: bool + objfile: Optional[str] make: bool source_old_binutils: bool + diff_section: str inlines: bool max_function_size_lines: int max_function_size_bytes: int @@ -422,9 +443,11 @@ def create_project_settings(settings: Dict[str, Any]) -> ProjectSettings: "source_extensions", [".c", ".h", ".cpp", ".hpp", ".s"] ), objdump_executable=get_objdump_executable(settings.get("objdump_executable")), + objdump_flags=settings.get("objdump_flags", []), map_format=settings.get("map_format", "gnu"), mw_build_dir=settings.get("mw_build_dir", "build/"), show_line_numbers_default=settings.get("show_line_numbers_default", True), + disassemble_all=settings.get("disassemble_all", False), ) @@ -461,8 +484,10 @@ def create_config(args: argparse.Namespace, project: ProjectSettings) -> Config: arch=arch, # Build/objdump options diff_obj=args.diff_obj, + objfile=args.objfile, make=args.make, source_old_binutils=args.source_old_binutils, + diff_section=args.diff_section, inlines=args.inlines, max_function_size_lines=args.max_lines, max_function_size_bytes=args.max_lines * 4, @@ -518,7 +543,7 @@ def get_arch(arch_str: str) -> "ArchSettings": raise ValueError(f"Unknown architecture: {arch_str}") -BUFFER_CMD: List[str] = ["tail", "-c", str(10 ** 9)] +BUFFER_CMD: List[str] = ["tail", "-c", str(10**9)] # -S truncates long lines instead of wrapping them # -R interprets color escape sequences @@ -640,6 +665,7 @@ class Text: class TableMetadata: headers: Tuple[Text, ...] current_score: int + max_score: int previous_score: Optional[int] @@ -808,12 +834,7 @@ class JsonFormatter(Formatter): return {"text": s, "format": f.name.lower()} elif isinstance(f, RotationFormat): attrs = asdict(f) - attrs.update( - { - "text": s, - "format": "rotation", - } - ) + attrs.update({"text": s, "format": "rotation"}) return attrs else: static_assert_unreachable(f) @@ -832,6 +853,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]] = [] @@ -960,7 +982,7 @@ def restrict_to_function(dump: str, fn_name: str) -> str: return "" -def serialize_data_references(references: List[Tuple[int, int, str]]) -> str: +def serialize_rodata_references(references: List[Tuple[int, int, str]]) -> str: return "".join( f"DATAREF {text_offset} {from_offset} {from_section}\n" for (text_offset, from_offset, from_section) in references @@ -989,7 +1011,11 @@ def run_objdump(cmd: ObjdumpCommand, config: Config, project: ProjectSettings) - flags, target, restrict = cmd try: out = subprocess.run( - [project.objdump_executable] + config.arch.arch_flags + flags + [target], + [project.objdump_executable] + + config.arch.arch_flags + + project.objdump_flags + + flags + + [target], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -1007,11 +1033,11 @@ def run_objdump(cmd: ObjdumpCommand, config: Config, project: ProjectSettings) - with open(target, "rb") as f: obj_data = f.read() - return preprocess_objdump_out(restrict, obj_data, out) + return preprocess_objdump_out(restrict, obj_data, out, config) def preprocess_objdump_out( - restrict: Optional[str], obj_data: Optional[bytes], objdump_out: str + restrict: Optional[str], obj_data: Optional[bytes], objdump_out: str, config: Config ) -> str: """ Preprocess the output of objdump into a format that `process()` expects. @@ -1031,13 +1057,16 @@ def preprocess_objdump_out( out = out.rstrip("\n") if obj_data: - out = serialize_data_references(parse_elf_data_references(obj_data)) + out + out = ( + serialize_rodata_references(parse_elf_rodata_references(obj_data, config)) + + out + ) return out def search_map_file( - fn_name: str, project: ProjectSettings + fn_name: str, project: ProjectSettings, config: Config ) -> Tuple[Optional[str], Optional[int]]: if not project.mapfile: fail(f"No map file configured; cannot find function {fn_name}.") @@ -1057,7 +1086,7 @@ def search_map_file( cands = [] last_line = "" for line in lines: - if line.startswith(" .text"): + if line.startswith(" " + config.diff_section): cur_objfile = line.split()[3] if "load address" in line: tokens = last_line.split() + line.split() @@ -1082,9 +1111,12 @@ def search_map_file( re.compile( # ram elf rom r" \S+ \S+ (\S+) (\S+) . " - + fn_name - # object name - + r"(?: \(entry of \.(?:init|text)\))? \t(\S+)" + + re.escape(fn_name) + + r"(?: \(entry of " + + re.escape(config.diff_section) + + r"\))? \t" + # object name + + "(\S+)" ), contents, ) @@ -1119,7 +1151,9 @@ def search_map_file( return None, None -def parse_elf_data_references(data: bytes) -> List[Tuple[int, int, str]]: +def parse_elf_rodata_references( + data: bytes, config: Config +) -> List[Tuple[int, int, str]]: e_ident = data[:16] if e_ident[:4] != b"\x7FELF": return [] @@ -1132,7 +1166,6 @@ def parse_elf_data_references(data: bytes) -> List[Tuple[int, int, str]]: is_little_endian = e_ident[5] == 1 str_end = "<" if is_little_endian else ">" str_off = "I" if is_32bit else "Q" - sym_size = {"B": 1, "H": 2, "I": 4, "Q": 8} def read(spec: str, offset: int) -> Tuple[int, ...]: spec = spec.replace("P", str_off) @@ -1184,17 +1217,25 @@ 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 + section_name = config.diff_section.encode("utf-8") + text_sections = [ + i + for i in range(e_shnum) + if sec_names[i] == section_name and sections[i].sh_size != 0 + ] + if len(text_sections) != 1: + return [] text_section = text_sections[0] ret: List[Tuple[int, int, str]] = [] for s in sections: if s.sh_type == SHT_REL or s.sh_type == SHT_RELA: if s.sh_info == text_section: - # Skip .text -> .text references + # Skip section_name -> section_name references continue sec_name = sec_names[s.sh_info].decode("latin1") + if sec_name != ".rodata": + continue sec_base = sections[s.sh_info].sh_offset for i in range(0, s.sh_size, s.sh_entsize): if s.sh_type == SHT_REL: @@ -1251,11 +1292,16 @@ def dump_elf( f"--stop-address={end_addr}", ] + if project.disassemble_all: + disassemble_flag = "-D" + else: + disassemble_flag = "-d" + flags2 = [ f"--disassemble={diff_elf_symbol}", ] - objdump_flags = ["-drz", "-j", ".text"] + objdump_flags = [disassemble_flag, "-rz", "-j", config.diff_section] return ( project.myimg, (objdump_flags + flags1, project.baseimg, None), @@ -1277,7 +1323,10 @@ def dump_objfile( if start.startswith("0"): fail("numerical start address not supported with -o; pass a function name") - objfile, _ = search_map_file(start, project) + objfile = config.objfile + if not objfile: + objfile, _ = search_map_file(start, project, config) + if not objfile: fail("Not able to find .o file for function.") @@ -1291,7 +1340,12 @@ def dump_objfile( if not os.path.isfile(refobjfile): fail(f'Please ensure an OK .o file exists at "{refobjfile}".') - objdump_flags = ["-drz", "-j", ".text"] + if project.disassemble_all: + disassemble_flag = "-D" + else: + disassemble_flag = "-d" + + objdump_flags = [disassemble_flag, "-rz", "-j", config.diff_section] return ( objfile, (objdump_flags, refobjfile, start), @@ -1308,7 +1362,7 @@ def dump_binary( run_make(project.myimg, project) start_addr = maybe_eval_int(start) if start_addr is None: - _, start_addr = search_map_file(start, project) + _, start_addr = search_map_file(start, project, config) if start_addr is None: fail("Not able to find function in map file.") if end is not None: @@ -1328,10 +1382,18 @@ def dump_binary( ) -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 @@ -1343,8 +1405,129 @@ 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 or "R_MIPS_JALR" 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: + imm = hex(int(imm, 16)) + repl += ("" if imm.startswith("-") 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 + elif "R_MIPS_GPREL16" in row: + repl = f"%gp_rel({repl})" + elif "R_MIPS_GOT16" in row: + repl = f"%got({repl})" + elif "R_MIPS_CALL16" in row: + repl = f"%call16({repl})" + 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) + return pool_match.group(1) if pool_match else 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: + if line.data_pool_addr is None: + continue + + # Add data symbol and its address to the line. + line_original = lines_by_line_number[line.data_pool_addr].original + value = line_original.split()[1] + addr = "{:x}".format(line.data_pool_addr) + line.original = line.normalized_original + f"={value} ({addr})" + + +class AsmProcessorAArch64(AsmProcessor): def __init__(self, config: Config) -> None: super().__init__(config) self._adrp_pair_registers: Set[str] = set() @@ -1394,23 +1577,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,13 +1586,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 = { @@ -1536,17 +1704,23 @@ PPC_BRANCH_INSTRUCTIONS = { MIPS_SETTINGS = ArchSettings( name="mips", re_int=re.compile(r"[0-9]+"), - re_comment=re.compile(r"<.*?>"), - re_reg=re.compile( - r"\$?\b(a[0-7]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|kt?[01]|fp|ra|zero)\b" - ), + re_comment=re.compile(r"<.*>"), + # Includes: + # - General purpose registers v0..1, a0..7, t0..9, s0..8, zero, at, fp, k0..1/kt0..1 + # - Float registers f0..31, or fv0..1, fa0..7, ft0..15, fs0..8 plus odd complements + # (actually used number depends on ABI) + # sp, gp should not be in this list + re_reg=re.compile(r"\$?\b([astv][0-9]|at|f[astv]?[0-9]+f?|kt?[01]|fp|ra|zero)\b"), 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) @@ -1554,7 +1728,7 @@ MIPSEL_SETTINGS = replace(MIPS_SETTINGS, name="mipsel", big_endian=False) ARM32_SETTINGS = ArchSettings( name="arm32", re_int=re.compile(r"[0-9]+"), - re_comment=re.compile(r"(<.*?>|//.*$)"), + re_comment=re.compile(r"(<.*>|//.*$)"), # Includes: # - General purpose registers: r0..13 # - Frame pointer registers: lr (r14), pc (r15) @@ -1566,42 +1740,54 @@ 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"(?|//.*$)"), - # GPRs and FP registers: X0-X30, W0-W30, [DSHQ]0..31 + re_comment=re.compile(r"(<.*>|//.*$)"), + # GPRs and FP registers: X0-X30, W0-W30, [BHSDVQ]0..31 + # (FP registers may be followed by data width and number of elements, e.g. V0.4S) # The zero registers and SP should not be in this list. - re_reg=re.compile(r"\$?\b([dshq][12]?[0-9]|[dshq]3[01]|[xw][12]?[0-9]|[xw]30)\b"), + re_reg=re.compile( + r"\$?\b([bhsdvq]([12]?[0-9]|3[01])(\.\d\d?[bhsdvq])?|[xw][12]?[0-9]|[xw]30)\b" + ), 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"(?|//.*$)"), + re_comment=re.compile(r"(<.*>|//.*$)"), re_reg=re.compile(r"\$?\b([rf][0-9]+)\b"), re_sprel=re.compile(r"(?<=,)(-?[0-9]+|-?0x[0-9a-f]+)\(r1\)"), 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(?!\(r1)|[^@]*@(ha|h|lo)"), + re_reloc=re.compile(r"R_PPC_"), branch_instructions=PPC_BRANCH_INSTRUCTIONS, instructions_with_address_immediates=PPC_BRANCH_INSTRUCTIONS.union({"bl"}), + proc=AsmProcessorPPC, ) ARCH_SETTINGS = [ MIPS_SETTINGS, MIPSEL_SETTINGS, ARM32_SETTINGS, + ARMEL_SETTINGS, AARCH64_SETTINGS, PPC_SETTINGS, ] @@ -1621,6 +1807,7 @@ def hexify_int(row: str, pat: Match[str], arch: ArchSettings) -> str: def parse_relocated_line(line: str) -> Tuple[str, str, str]: + # Pick out the last argument for c in ",\t ": if c in line: ind2 = line.rindex(c) @@ -1629,6 +1816,7 @@ def parse_relocated_line(line: str) -> Tuple[str, str, str]: raise Exception(f"failed to parse relocated line: {line}") before = line[: ind2 + 1] after = line[ind2 + 1 :] + # Move an optional ($reg) part of it to 'after' ind2 = after.find("(") if ind2 == -1: imm, after = after, "" @@ -1639,84 +1827,6 @@ def parse_relocated_line(line: str) -> 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 @@ -1733,6 +1843,7 @@ class Line: scorable_line: str line_num: Optional[int] = None branch_target: Optional[int] = None + data_pool_addr: Optional[int] = None source_filename: Optional[str] = None source_line_num: Optional[int] = None source_lines: List[str] = field(default_factory=list) @@ -1741,7 +1852,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 +1894,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( @@ -1794,13 +1905,22 @@ def process(dump: str, config: Config) -> List[Line]: source_lines.append(row) continue + # If the instructions loads a data pool symbol, extract the address of + # the symbol. + data_pool_addr = None + pool_match = re.search(ARM32_LOAD_POOL_PATTERN, row) + if pool_match: + offset = pool_match.group(3).split(" ")[0][1:] + data_pool_addr = int(offset, 16) + 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] @@ -1825,8 +1945,15 @@ def process(dump: str, config: Config) -> List[Line]: row_parts = [part.lstrip() for part in row.split(" ", 1)] mnemonic = row_parts[0].strip() - if mnemonic not in arch.instructions_with_address_immediates: - row = re.sub(arch.re_int, lambda m: hexify_int(row, m, arch), row) + addr = "" + if mnemonic in arch.instructions_with_address_immediates: + row, addr = split_off_address(row) + # objdump prefixes addresses with 0x/-0x if they don't resolve to some + # symbol + offset. Strip that. + addr = addr.replace("0x", "") + + row = re.sub(arch.re_int, lambda m: hexify_int(row, m, arch), row) + row += addr # Let 'original' be 'row' with relocations applied, while we continue # transforming 'row' into a coarser version that ignores registers and @@ -1835,27 +1962,17 @@ 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: scorable_line = re.sub(arch.re_sprel, "addr(sp)", scorable_line) - if mnemonic in arch.branch_instructions: - # Replace the final argument with "" - scorable_line = re.sub(r"[^, \t]+$", "", scorable_line) if skip_next: skip_next = False @@ -1878,8 +1995,6 @@ def process(dump: str, config: Config) -> List[Line]: branch_target = None if mnemonic in arch.branch_instructions: branch_target = int(row_parts[1].strip().split(",")[-1], 16) - if mnemonic in arch.branch_likely_instructions: - branch_target -= 4 output.append( Line( @@ -1890,6 +2005,7 @@ def process(dump: str, config: Config) -> List[Line]: scorable_line=scorable_line, line_num=line_num, branch_target=branch_target, + data_pool_addr=data_pool_addr, source_filename=source_filename, source_line_num=source_line_num, source_lines=source_lines, @@ -1904,6 +2020,7 @@ def process(dump: str, config: Config) -> List[Line]: elif stop_after_delay_slot: break + processor.post_process(output) return output @@ -1925,7 +2042,9 @@ def split_off_address(line: str) -> Tuple[str, str]: parts = line.split(",") if len(parts) < 2: parts = line.split(None, 1) - off = len(line) - len(parts[-1]) + if len(parts) < 2: + parts.append("") + off = len(line) - len(parts[-1].strip()) return line[:off], line[off:] @@ -1941,7 +2060,7 @@ def diff_sequences( ) -> List[Tuple[str, int, int, int, int]]: if ( algorithm != "levenshtein" - or len(seq1) * len(seq2) > 4 * 10 ** 8 + or len(seq1) * len(seq2) > 4 * 10**8 or len(seq1) + len(seq2) >= 0x110000 ): return diff_sequences_difflib(seq1, seq2) @@ -2123,6 +2242,18 @@ 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: @@ -2152,8 +2283,11 @@ 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 @@ -2221,10 +2355,15 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: line2_line = line_num_2to1[line2.line_num] line2_target = (line2_line[0] + (target - line2.line_num), 0) - # Set the key for three-way diffing to a normalized version. + # Adjust the branch target for scoring and three-way diffing. norm2, norm_branch2 = split_off_address(line2.normalized_original) - if norm_branch2 != "": - line2.normalized_original = norm2 + str(line2_target) + if norm_branch2 != "": + retargetted = hex(line2_target[0]).replace("0x", "") + if line2_target[1] != 0: + retargetted += f"+{line2_target[1]}" + line2.normalized_original = norm2 + retargetted + sc_base, _ = split_off_address(line2.scorable_line) + line2.scorable_line = sc_base + retargetted same_target = line2_target == (line1.branch_target, 0) else: # Do a naive comparison for non-branches (e.g. function calls). @@ -2384,8 +2523,9 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: ) ) + score = score_diff_lines(diffed_lines, config) 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 +2601,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 +2645,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/asm-processor/asm_processor.py b/tools/asm-processor/asm_processor.py index 6923752be..544b1b1b7 100644 --- a/tools/asm-processor/asm_processor.py +++ b/tools/asm-processor/asm_processor.py @@ -783,6 +783,13 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende else: min_instr_count = 2 skip_instr_count = 1 + elif opt == 'O0': + if framepointer: + min_instr_count = 8 + skip_instr_count = 8 + else: + min_instr_count = 4 + skip_instr_count = 4 elif opt == 'g': if framepointer: min_instr_count = 7 @@ -792,7 +799,7 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende skip_instr_count = 4 else: if opt != 'g3': - raise Failure("must pass one of -g, -O1, -O2, -O2 -g3") + raise Failure("must pass one of -g, -O0, -O1, -O2, -O2 -g3") if framepointer: min_instr_count = 4 skip_instr_count = 4 @@ -813,6 +820,7 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende ] is_cutscene_data = False + is_early_include = False for line_no, raw_line in enumerate(f, 1): raw_line = raw_line.rstrip() @@ -832,44 +840,51 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende global_asm = None else: global_asm.process_line(raw_line, output_enc) + elif line in ['GLOBAL_ASM(', '#pragma GLOBAL_ASM(']: + global_asm = GlobalAsmBlock("GLOBAL_ASM block at line " + str(line_no)) + start_index = len(output_lines) + elif ((line.startswith('GLOBAL_ASM("') or line.startswith('#pragma GLOBAL_ASM("')) + and line.endswith('")')): + fname = line[line.index('(') + 2 : -2] + out_dependencies.append(fname) + global_asm = GlobalAsmBlock(fname) + with open(fname, encoding=input_enc) as f: + for line2 in f: + global_asm.process_line(line2.rstrip(), output_enc) + src, fn = global_asm.finish(state) + output_lines[-1] = ''.join(src) + asm_functions.append(fn) + global_asm = None + elif line == '#pragma asmproc recurse': + # C includes qualified as + # #pragma asmproc recurse + # #include "file.c" + # will be processed recursively when encountered + is_early_include = True + elif is_early_include: + # Previous line was a #pragma asmproc recurse + is_early_include = False + if not line.startswith("#include "): + raise Failure("#pragma asmproc recurse must be followed by an #include ") + fpath = os.path.dirname(f.name) + fname = os.path.join(fpath, line[line.index(' ') + 2 : -1]) + out_dependencies.append(fname) + include_src = StringIO() + with open(fname, encoding=input_enc) as include_file: + parse_source(include_file, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, include_src) + include_src.write('#line ' + str(line_no + 1) + ' "' + f.name + '"') + output_lines[-1] = include_src.getvalue() + include_src.close() else: - if line in ['GLOBAL_ASM(', '#pragma GLOBAL_ASM(']: - global_asm = GlobalAsmBlock("GLOBAL_ASM block at line " + str(line_no)) - start_index = len(output_lines) - elif ((line.startswith('GLOBAL_ASM("') or line.startswith('#pragma GLOBAL_ASM("')) - and line.endswith('")')): - fname = line[line.index('(') + 2 : -2] - out_dependencies.append(fname) - global_asm = GlobalAsmBlock(fname) - with open(fname, encoding=input_enc) as f: - for line2 in f: - global_asm.process_line(line2.rstrip(), output_enc) - src, fn = global_asm.finish(state) - output_lines[-1] = ''.join(src) - asm_functions.append(fn) - global_asm = None - elif line.startswith('#include "') and line.endswith('" EARLY'): - # C includes qualified with EARLY (i.e. #include "file.c" EARLY) will be - # processed recursively when encountered - fpath = os.path.dirname(f.name) - fname = os.path.join(fpath, line[line.index(' ') + 2 : -7]) - out_dependencies.append(fname) - include_src = StringIO() - with open(fname, encoding=input_enc) as include_file: - parse_source(include_file, opt, framepointer, mips1, input_enc, output_enc, out_dependencies, include_src) - include_src.write('#line ' + str(line_no + 1) + ' "' + f.name + '"') - output_lines[-1] = include_src.getvalue() - include_src.close() - else: - # This is a hack to replace all floating-point numbers in an array of a particular type - # (in this case CutsceneData) with their corresponding IEEE-754 hexadecimal representation - if cutscene_data_regexpr.search(line) is not None: - is_cutscene_data = True - elif line.endswith("};"): - is_cutscene_data = False - if is_cutscene_data: - raw_line = re.sub(float_regexpr, repl_float_hex, raw_line) - output_lines[-1] = raw_line + # This is a hack to replace all floating-point numbers in an array of a particular type + # (in this case CutsceneData) with their corresponding IEEE-754 hexadecimal representation + if cutscene_data_regexpr.search(line) is not None: + is_cutscene_data = True + elif line.endswith("};"): + is_cutscene_data = False + if is_cutscene_data: + raw_line = re.sub(float_regexpr, repl_float_hex, raw_line) + output_lines[-1] = raw_line if print_source: if isinstance(print_source, StringIO): @@ -877,7 +892,14 @@ def parse_source(f, opt, framepointer, mips1, input_enc, output_enc, out_depende print_source.write(line + '\n') else: for line in output_lines: - print_source.write(line.encode(output_enc) + b'\n') + try: + line_encoded = line.encode(output_enc) + except UnicodeEncodeError: + print("Failed to encode a line to", output_enc) + print("The line:", line) + print("The line, utf-8-encoded:", line.encode("utf-8")) + raise + print_source.write(line_encoded + b'\n') print_source.flush() if print_source != sys.stdout.buffer: print_source.close() @@ -1239,6 +1261,7 @@ def run_wrapped(argv, outfile, functions): parser.add_argument('-mips1', dest='mips1', action='store_true') parser.add_argument('-g3', dest='g3', action='store_true') group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-O0', dest='opt', action='store_const', const='O0') group.add_argument('-O1', dest='opt', action='store_const', const='O1') group.add_argument('-O2', dest='opt', action='store_const', const='O2') group.add_argument('-g', dest='opt', action='store_const', const='g') diff --git a/tools/asm-processor/build.py b/tools/asm-processor/build.py index 493afd4d5..480dec9ed 100755 --- a/tools/asm-processor/build.py +++ b/tools/asm-processor/build.py @@ -10,30 +10,49 @@ dir_path = os.path.dirname(os.path.realpath(__file__)) prelude = os.path.join(dir_path, "prelude.inc") all_args = sys.argv[1:] -sep1 = all_args.index('--') -sep2 = all_args.index('--', sep1+1) +sep0 = [index for index, arg in enumerate(all_args) if not arg.startswith("-")][0] +sep1 = all_args.index("--") +sep2 = all_args.index("--", sep1 + 1) -compiler = all_args[:sep1] +asmproc_flags = all_args[:sep0] +compiler = all_args[sep0:sep1] -assembler = all_args[sep1+1:sep2] -assembler_sh = ' '.join(shlex.quote(x) for x in assembler) +assembler = all_args[sep1 + 1 : sep2] +assembler_sh = " ".join(shlex.quote(x) for x in assembler) -compile_args = all_args[sep2+1:] +compile_args = all_args[sep2 + 1 :] in_file = compile_args[-1] -out_ind = compile_args.index('-o') +out_ind = compile_args.index("-o") out_file = compile_args[out_ind + 1] del compile_args[-1] del compile_args[out_ind + 1] del compile_args[out_ind] in_dir = os.path.split(os.path.realpath(in_file))[0] -opt_flags = [x for x in compile_args if x in ['-g3', '-g', '-O1', '-O2', '-framepointer']] +opt_flags = [ + x for x in compile_args if x in ["-g3", "-g", "-O0", "-O1", "-O2", "-framepointer"] +] +if "-mips2" not in compile_args: + opt_flags.append("-mips1") -preprocessed_file = tempfile.NamedTemporaryFile(prefix='preprocessed', suffix='.c', delete=False) +asmproc_flags += opt_flags + [in_file] + +# Drop .mdebug and .gptab sections from resulting binaries. This makes +# resulting .o files much smaller and speeds up builds, but loses line +# number debug data. +# asmproc_flags += ["--drop-mdebug-gptab"] + +# Convert encoding before compiling. +# asmproc_flags += ["--input-enc", "utf-8", "--output-enc", "euc-jp"] + +preprocessed_file = tempfile.NamedTemporaryFile( + prefix="preprocessed", suffix=".c", delete=False +) try: - asmproc_flags = opt_flags + [in_file, '--input-enc', 'utf-8', '--output-enc', 'euc-jp'] - compile_cmdline = compiler + compile_args + ['-I', in_dir, '-o', out_file, preprocessed_file.name] + compile_cmdline = ( + compiler + compile_args + ["-I", in_dir, "-o", out_file, preprocessed_file.name] + ) functions, deps = asm_processor.run(asmproc_flags, outfile=preprocessed_file) try: @@ -41,13 +60,24 @@ try: except subprocess.CalledProcessError as e: print("Failed to compile file " + in_file + ". Command line:") print() - print(' '.join(shlex.quote(x) for x in compile_cmdline)) + print(" ".join(shlex.quote(x) for x in compile_cmdline)) print() sys.exit(55) # To keep the preprocessed file: # os._exit(1) - asm_processor.run(asmproc_flags + ['--post-process', out_file, '--assembler', assembler_sh, '--asm-prelude', prelude], functions=functions) + asm_processor.run( + asmproc_flags + + [ + "--post-process", + out_file, + "--assembler", + assembler_sh, + "--asm-prelude", + prelude, + ], + functions=functions, + ) deps_file = out_file[:-2] + ".asmproc.d" if deps: diff --git a/tools/asm-processor/prelude.inc b/tools/asm-processor/prelude.inc index 1ec8c6036..3e58ff149 100644 --- a/tools/asm-processor/prelude.inc +++ b/tools/asm-processor/prelude.inc @@ -1,5 +1,43 @@ .set noat .set noreorder .set gp=64 -.include "macro.inc" +.macro glabel label + .global \label + \label: +.endm + +# Float register aliases (o32 ABI, odd ones are rarely used) + +.set $fv0, $f0 +.set $fv0f, $f1 +.set $fv1, $f2 +.set $fv1f, $f3 +.set $ft0, $f4 +.set $ft0f, $f5 +.set $ft1, $f6 +.set $ft1f, $f7 +.set $ft2, $f8 +.set $ft2f, $f9 +.set $ft3, $f10 +.set $ft3f, $f11 +.set $fa0, $f12 +.set $fa0f, $f13 +.set $fa1, $f14 +.set $fa1f, $f15 +.set $ft4, $f16 +.set $ft4f, $f17 +.set $ft5, $f18 +.set $ft5f, $f19 +.set $fs0, $f20 +.set $fs0f, $f21 +.set $fs1, $f22 +.set $fs1f, $f23 +.set $fs2, $f24 +.set $fs2f, $f25 +.set $fs3, $f26 +.set $fs3f, $f27 +.set $fs4, $f28 +.set $fs4f, $f29 +.set $fs5, $f30 +.set $fs5f, $f31 diff --git a/tools/calc_bss.sh b/tools/calc_bss.sh old mode 100644 new mode 100755 index 4ce7ff417..23fcfe486 --- a/tools/calc_bss.sh +++ b/tools/calc_bss.sh @@ -34,7 +34,7 @@ echo "char measurement;" >> $TEMPC $(pwd)/tools/ido_recomp/linux/7.1/cc -G 0 -non_shared \ -Xfullwarn -Xcpluscomm -O2 -g3 -Xcpluscomm -mips2 \ - -I $(pwd)/include/ -I $(pwd)/src/ -I $(pwd)/assets/ -I $(pwd)/build/ \ + -I $(pwd)/ -I $(pwd)/include/ -I $(pwd)/src/ -I $(pwd)/assets/ -I $(pwd)/build/ \ -Wab,-r4300_mul -woff 624,649,838,712 -c $TEMPC -o $TEMPO LINE=$(${CROSS}objdump -t $TEMPO | grep measurement | cut -d' ' -f1) diff --git a/tools/decomp-permuter/.github/workflows/systray.yml b/tools/decomp-permuter/.github/workflows/systray.yml deleted file mode 100644 index b815d64cc..000000000 --- a/tools/decomp-permuter/.github/workflows/systray.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Systray - -on: - push: - branches: [ main ] - paths: - - 'src/net/cmd/systray/*' - pull_request: - branches: [ main ] - paths: - - 'src/net/cmd/systray/*' - -jobs: - - build: - name: Build on ${{ matrix.os }} - runs-on: ${{ matrix.os }} - strategy: - matrix: - include: - - os: ubuntu-16.04 - binary: permuter-systray-linux - - os: windows-latest - binary: permuter-systray.exe - - os: macos-latest - binary: permuter-systray-macos - steps: - - uses: actions/checkout@main - - - name: Install gtk3 - if: ${{ matrix.os == 'ubuntu-16.04' }} - run: sudo apt-get install libgtk-3-dev libappindicator3-dev - - - name: Setup Go environment - uses: actions/setup-go@v2.1.3 - - - name: Build - run: go build -o ${{ matrix.binary }} -ldflags "-s -w" tray.go - working-directory: src/net/cmd/systray/ - - - name: Upload artifact - uses: actions/upload-artifact@v2 - with: - name: ${{ matrix.binary }} - path: src/net/cmd/systray/${{ matrix.binary }} diff --git a/tools/decomp-permuter/.gitignore b/tools/decomp-permuter/.gitignore deleted file mode 100644 index 2dcae2143..000000000 --- a/tools/decomp-permuter/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*.o -*.s -*.c -*.py[cod] -.mypy_cache/ -.cache/ -__pycache__/ -!test/*.c -/nonmatchings -.vscode/ -pah.conf diff --git a/tools/decomp-permuter/.gitrepo b/tools/decomp-permuter/.gitrepo deleted file mode 100644 index 270e3df56..000000000 --- a/tools/decomp-permuter/.gitrepo +++ /dev/null @@ -1,12 +0,0 @@ -; DO NOT EDIT (unless you know what you are doing) -; -; This subdirectory is a git "subrepo", and this file is maintained by the -; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme -; -[subrepo] - remote = https://github.com/simonlindholm/decomp-permuter.git - branch = main - commit = a20bac9422b6d8adbf7c06473c2ae3c3fee16be5 - parent = 2668eec556c01fa2f4c16a203c93c208dc03e639 - method = merge - cmdver = 0.4.3 diff --git a/tools/decomp-permuter/.pre-commit-config.yaml b/tools/decomp-permuter/.pre-commit-config.yaml deleted file mode 100644 index 6695f71ac..000000000 --- a/tools/decomp-permuter/.pre-commit-config.yaml +++ /dev/null @@ -1,6 +0,0 @@ -repos: -- repo: https://github.com/psf/black - rev: 20.8b1 - hooks: - - id: black - language_version: python3.6 diff --git a/tools/decomp-permuter/LICENSE b/tools/decomp-permuter/LICENSE deleted file mode 100644 index ce6aab3a3..000000000 --- a/tools/decomp-permuter/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2019 Simon Lindholm and contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/tools/decomp-permuter/README.md b/tools/decomp-permuter/README.md deleted file mode 100644 index eb31c9d65..000000000 --- a/tools/decomp-permuter/README.md +++ /dev/null @@ -1,120 +0,0 @@ -# Decomp permuter - -Automatically permutes C files to better match a target binary. The permuter has two modes of operation: -- Random: purely at random, introduce temporary variables for values, change types, put statements on the same line... -- Manual: test all combinations of user-specified variations, using macros like `PERM_GENERAL(a = b ? c : d;, if (b) a = c; else a = d;)` to try both specified alternatives. - -The modes can also be combined, by using the `PERM_RANDOMIZE` macro. - -[](https://asciinema.org/a/232846) - -The main target for the tool is MIPS code compiled by old compilers (IDO, possibly GCC). -Getting it to work on other architectures shouldn't be too hard, however. -https://github.com/laqieer/decomp-permuter-arm has an ARM port. - -## Usage - -`./permuter.py directory/` runs the permuter; see below for the meaning of the directory. -Pass `-h` to see possible flags. `-j` is suggested (enables multi-threaded mode). - -You'll first need to install a couple of prerequisites: `python3 -m pip install pycparser pynacl toml` (also `dataclasses` if on Python 3.6 or below) - -The permuter expects as input one or more directory containing: - - a .c file with a single function, - - a .o file to match, - - a .sh file that compiles the .c file. - -For projects with a properly configured makefile, you should be able to set these up by running -``` -./import.py -``` -where file.c contains the function to be permuted, and file.s is its assembly in a self-contained file. -Otherwise, see USAGE.md for more details. - -For projects using Ninja instead of Make, add a `permuter_settings.toml` in the root or `tools/` directory of the project: -```toml -build_system = "ninja" -``` -Then `import.py` should work as expected if `build.ninja` is at the root of the project. - -The .c file may be modified with any of the following macros which affect manual permutation: - -- `PERM_GENERAL(a, b, ...)` expands to any of `a`, `b`, ... -- `PERM_VAR(a, b)` sets the meta-variable `a` to `b`, `PERM_VAR(a)` expands to the meta-variable `a`. -- `PERM_RANDOMIZE(code)` expands to `code`, but allows randomization within that region. Multiple regions may be specified. -- `PERM_LINESWAP(lines)` expands to a permutation of the ordered set of non-whitespace lines (split by `\n`). Each line must contain zero or more complete C statements. (For incomplete statements use `PERM_LINESWAP_TEXT`, which is slower because it has to repeatedly parse C code.) -- `PERM_INT(lo, hi)` expands to an integer between `lo` and `hi` (which must be constants). -- `PERM_IGNORE(code)` expands to `code`, without passing it through the C parser library (pycparser)/randomizer. This can be used to avoid parse errors for non-standard C, e.g. `asm` blocks. -- `PERM_PRETEND(code)` expands to `code` for the purpose of the C parser/randomizer, but gets removed afterwards. This can be used together with `PERM_IGNORE` to enable the permuter to deal with input it isn't designed for (e.g. inline functions, C++, non-code). -- `PERM_ONCE([key,] code)` expands to either `code` or to nothing, such that each unique key gets expanded exactly once. `key` defaults to `code`. For example, `PERM_ONCE(a;) b; PERM_ONCE(a;)` expands to either `a; b;` or `b; a;`. - -Arguments are split by a commas, exluding commas inside parenthesis. `(,)` is a special escape sequence that resolves to `,`. - -Nested macros are allowed, so e.g. -``` -PERM_VAR(delayed, ) -PERM_GENERAL(stmt;, PERM_VAR(delayed, stmt;)) -... -PERM_VAR(delayed) -``` -is an alternative way of writing `PERM_ONCE`. - -## permuter@home - -The permuter supports a distributed mode, where people can donate processor power to your permuter runs to speed them up. -To use this, pass `-J` when running `permuter.py` and follow the instructions. -You will need to be granted access by someone who is already connected to a permuter network. - -To allow others to use your computer for permuter runs, do the following: - -- install Docker (used for sandboxing and to ensure a consistent environment) -- if on Linux, add yourself to the Docker group: `sudo usermod -aG docker $USER` -- install required packages: `python3 -m pip install docker` -- open a terminal, and run `./pah.py run-server` to start the server. - There are a few required arguments (e.g. how many cores to use), see `--help` for more details. - -Please be aware that being in the Docker group implies (password-less) sudo rights. -You can avoid that for your personal account by running the permuter under a separate user. -Unfortunately, there is currently no way to run a sandboxed permuter server without sudo rights. 😢 - -Anyone who is granted access to permuter@home can run a server. - -To set up a new permuter network, see [src/net/controller/README.md](./src/net/controller/README.md). - -## FAQ - -**What do the scores mean?** The scores are computed by taking diffs of objdump'd .o -files, and giving different penalties for lines that are the same/use the same -instruction/are reordered/don't match at all. 0 means the function matches fully. -Stack positions are ignored unless --stack-diffs is passed (but beware that the -permuter is currently quite bad at resolving stack differences). For more details, -see scorer.py. It's far from a perfect system, and should probably be tweaked to -look at e.g. the register diff graph. - -**What sort of non-matchings are the permuter good at?** It's generally best towards -the end, when mostly regalloc changes remain. If there are reorderings or functional -changes, it's often easy to resolve those by hand, and neither the scorer nor the -randomizer tends to play well with them. - -**Should I use this instead of trying to match code by hand?** No, but it can be a good -complement. PERM macros can be used to quickly test lots of variations of a function at -once, in cases where there are interactions between several parts of a function. -The randomization mode often finds lots of nonsensical changes that improve regalloc -"by accident"; it's up to you to pick out the ones that look sensible. If none do, -it can still be useful to know which parts of the function need to be changed to get the -code nearer to matching. Having made one of the improvements, and the function can then be -permuted again, to find further possible improvements. - -## Helping out - -There's tons of room for helping out with the permuter! -Many more randomization passes could be added, the scoring function is far from optimal, -the permuter could be made easier to use, etc. etc. The GitHub Issues list has some ideas. - -Ideally, `mypy permuter.py` and `./run-tests.sh` should succeed with no errors, and files -formatted with `black`. To setup a pre-commit hook for black, run: -``` -pip install pre-commit black -pre-commit install -``` -PRs that skip this are still welcome, however. diff --git a/tools/decomp-permuter/USAGE.md b/tools/decomp-permuter/USAGE.md deleted file mode 100644 index d73b3a898..000000000 --- a/tools/decomp-permuter/USAGE.md +++ /dev/null @@ -1,25 +0,0 @@ -This file describes how to manually set up a directory for use with the permuter. -**You probably don't need to do this!** In normal circumstances, `./import.py` -does all this for you. See README.md for more details. - -* create a directory that will contain all of the input files for the invokation -* put a compile command into `/compile.sh` (see e.g. `compile_example.sh`; it will be invoked as `./compile.sh input.c -o output.o`) -* `gcc -E -P -I header_dir -D'__attribute__(x)=' orig_c_file.c > /base.c` -* `python3 strip_other_fns.py /base.c func_name` -* put asm for `func_name` into `/target.s`, with the following header: - -```asm -.set noat -.set noreorder -.set gp=64 -.macro glabel label - .global \label - .type \label, @function - \label: -.endm -``` -* `mips-linux-gnu-as -march=vr4300 -mabi=32 /target.s -o /target.o` -* optional sanity checks: - - `/compile.sh /base.c -o /base.o` - - `./diff.sh /target.o /base.o` -* `./permuter.py ` diff --git a/tools/decomp-permuter/compile_example.sh b/tools/decomp-permuter/compile_example.sh deleted file mode 100755 index f87bdfa18..000000000 --- a/tools/decomp-permuter/compile_example.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -mips-linux-gnu-gcc -O2 "$@" diff --git a/tools/decomp-permuter/diff.sh b/tools/decomp-permuter/diff.sh deleted file mode 100755 index 20ae8bba0..000000000 --- a/tools/decomp-permuter/diff.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash - -if [[ $# < 2 ]]; then - echo "Usage: $0 orig.o new.o [flags]" - exit 1 -fi - -if [ ! -f $1 -o ! -f $2 ]; then - echo Source files not readable - exit 1 -fi - -INPUT1="$1" -INPUT2="$2" -shift -shift -wdiff -n <(python3 ./src/objdump.py "$INPUT1" "$@") <(python3 ./src/objdump.py "$INPUT2" "$@") | colordiff | less -Ric diff --git a/tools/decomp-permuter/import.py b/tools/decomp-permuter/import.py deleted file mode 100755 index 9a314621c..000000000 --- a/tools/decomp-permuter/import.py +++ /dev/null @@ -1,808 +0,0 @@ -#!/usr/bin/env python3 -# usage: ./import.py path/to/file.c path/to/asm.s [make flags] -import argparse -from collections import defaultdict -import json -import os -import platform -import re -import shlex -import shutil -import subprocess -import sys -import toml -from typing import Callable, Dict, List, Match, Mapping, Optional, Pattern, Set, Tuple -import urllib.request -import urllib.parse - -from src import ast_util -from src.compiler import Compiler -from src.error import CandidateConstructionFailure - -is_macos = platform.system() == "Darwin" - - -def homebrew_gcc_cpp() -> str: - lookup_paths = ["/usr/local/bin", "/opt/homebrew/bin"] - - for lookup_path in lookup_paths: - try: - return max(f for f in os.listdir(lookup_path) if f.startswith("cpp-")) - except ValueError: - pass - - print( - "Error while looking up in " + ":".join(lookup_paths) + " for cpp- executable" - ) - sys.exit(1) - - -cpp_cmd = homebrew_gcc_cpp() if is_macos else "cpp" -make_cmd = "gmake" if is_macos else "make" - -ASM_PRELUDE: str = """ -.set noat -.set noreorder -.set gp=64 -.macro glabel label - .global \label - .type \label, @function - \label: -.endm -""" - -DEFAULT_AS_CMDLINE: List[str] = ["mips-linux-gnu-as", "-march=vr4300", "-mabi=32"] - -CPP: List[str] = [cpp_cmd, "-P", "-undef"] - -STUB_FN_MACROS: List[str] = [ - "-D_Static_assert(x, y)=", - "-D__attribute__(x)=", - "-DGLOBAL_ASM(...)=", -] - -SETTINGS_FILES = ["permuter_settings.toml", "tools/permuter_settings.toml"] - - -def formatcmd(cmdline: List[str]) -> str: - return " ".join(shlex.quote(arg) for arg in cmdline) - - -def parse_asm(asm_file: str) -> Tuple[str, str]: - func_name = None - asm_lines = [] - try: - with open(asm_file, encoding="utf-8") as f: - cur_section = ".text" - for line in f: - if line.strip().startswith(".section"): - cur_section = line.split()[1] - elif line.strip() in [ - ".text", - ".rdata", - ".rodata", - ".late_rodata", - ".bss", - ".data", - ]: - cur_section = line.strip() - if cur_section == ".text": - if func_name is None and line.strip().startswith("glabel "): - func_name = line.split()[1] - asm_lines.append(line) - except OSError as e: - print("Could not open assembly file:", e, file=sys.stderr) - sys.exit(1) - - if func_name is None: - print( - "Missing function name in assembly file! The file should start with 'glabel function_name'.", - file=sys.stderr, - ) - sys.exit(1) - - if not re.fullmatch(r"[a-zA-Z0-9_$]+", func_name): - print(f"Bad function name: {func_name}", file=sys.stderr) - sys.exit(1) - - return func_name, "".join(asm_lines) - - -def create_directory(func_name: str) -> str: - os.makedirs(f"nonmatchings/", exist_ok=True) - ctr = 0 - while True: - ctr += 1 - dirname = f"{func_name}-{ctr}" if ctr > 1 else func_name - dirname = f"nonmatchings/{dirname}" - try: - os.mkdir(dirname) - return dirname - except FileExistsError: - pass - - -def find_root_dir(filename: str, pattern: List[str]) -> Optional[str]: - old_dirname = None - dirname = os.path.abspath(os.path.dirname(filename)) - - while dirname and (not old_dirname or len(dirname) < len(old_dirname)): - for fname in pattern: - if os.path.isfile(os.path.join(dirname, fname)): - return dirname - old_dirname = dirname - dirname = os.path.dirname(dirname) - - return None - - -def fixup_build_command( - parts: List[str], ignore_part: str -) -> Tuple[List[str], Optional[List[str]]]: - res = [] - skip_count = 0 - assembler = None - for part in parts: - if skip_count > 0: - skip_count -= 1 - continue - if part in ["-MF", "-o"]: - skip_count = 1 - continue - if part == ignore_part: - continue - res.append(part) - - try: - ind0 = min( - i - for i, arg in enumerate(res) - if any( - cmd in arg - for cmd in ["asm_processor", "asm-processor", "preprocess.py"] - ) - ) - ind1 = res.index("--", ind0 + 1) - ind2 = res.index("--", ind1 + 1) - assembler = res[ind1 + 1 : ind2] - res = res[ind0 + 1 : ind1] + res[ind2 + 1 :] - except ValueError: - pass - - return res, assembler - - -def find_build_command_line( - root_dir: str, c_file: str, make_flags: List[str], build_system: str -) -> Tuple[List[str], List[str]]: - if build_system == "make": - build_invocation = [ - make_cmd, - "--always-make", - "--dry-run", - "--debug=j", - "PERMUTER=1", - ] + make_flags - elif build_system == "ninja": - build_invocation = ["ninja", "-t", "commands"] + make_flags - else: - print("Unknown build system '" + build_system + "'.") - sys.exit(1) - - rel_c_file = os.path.relpath(c_file, root_dir) - debug_output = ( - subprocess.check_output(build_invocation, cwd=root_dir) - .decode("utf-8") - .split("\n") - ) - - output = [] - close_match = False - - assembler = DEFAULT_AS_CMDLINE - for line in debug_output: - while "//" in line: - line = line.replace("//", "/") - while "/./" in line: - line = line.replace("/./", "/") - if rel_c_file not in line: - continue - - close_match = True - parts = shlex.split(line) - - # extract actual command from 'bash -c "..."' - if parts[0] == "bash" and "-c" in parts: - for part in parts: - if rel_c_file in part: - parts = shlex.split(part) - break - - if rel_c_file not in parts: - continue - if "-o" not in parts: - continue - if "-fsyntax-only" in parts: - continue - cmdline, asmproc_assembler = fixup_build_command(parts, rel_c_file) - if asmproc_assembler: - assembler = asmproc_assembler - output.append(cmdline) - - if not output: - close_extra = ( - "\n(Found one possible candidate, but didn't match due to " - "either spaces in paths, having -fsyntax-only, or missing an -o flag.)" - if close_match - else "" - ) - print( - "Failed to find compile command from build script output. " - f"Please ensure running '{' '.join(build_invocation)}' " - f"contains a line with the string '{rel_c_file}'.{close_extra}", - file=sys.stderr, - ) - sys.exit(1) - - if len(output) > 1: - output_lines = "\n".join(map(formatcmd, output)) - print( - f"Error: found multiple compile commands for {rel_c_file}:\n{output_lines}\n" - f"Please modify the build script such that '{' '.join(build_invocation)}' " - "produces a single compile command.", - file=sys.stderr, - ) - sys.exit(1) - - return output[0], assembler - - -PreserveMacros = Tuple[Pattern[str], Callable[[str], str]] - - -def build_preserve_macros( - cwd: str, preserve_regex: Optional[str], settings: Mapping[str, object] -) -> Optional[PreserveMacros]: - - subdata = settings.get("preserve_macros", {}) - assert isinstance(subdata, dict) - regexes = [] - for regex, value in subdata.items(): - assert isinstance(value, str) - regexes.append((re.compile(f"^(?:{regex})$"), value)) - - if preserve_regex == "" or (preserve_regex is None and not regexes): - return None - - if preserve_regex is None: - global_regex_text = "(?:" + ")|(?:".join(subdata.keys()) + ")" - else: - global_regex_text = preserve_regex - global_regex = re.compile(f"^(?:{global_regex_text})$") - - def type_fn(macro: str) -> str: - for regex, value in regexes: - if regex.match(macro): - return value - return "int" - - return global_regex, type_fn - - -def preprocess_c_with_macros( - cpp_command: List[str], cwd: str, preserve_macros: PreserveMacros -) -> Tuple[str, List[str]]: - """Import C file, preserving function macros. Subroutine of import_c_file. - - Returns the source code and a list of preserved macros.""" - - preserve_regex, preserve_type_fn = preserve_macros - - # Start by running 'cpp' in a mode that just processes ifdefs and includes. - source = subprocess.check_output( - cpp_command + ["-dD", "-fdirectives-only"], cwd=cwd, encoding="utf-8" - ) - - # Modify function macros that match preserved names so the preprocessor - # doesn't touch them, and at the same time normalize their syntax. Some - # of these instances may be in comments, but that's fine. - def repl(match: Match[str]) -> str: - name = match.group(1) - after = "(" if match.group(2) == "(" else " " - if preserve_regex.match(name): - return f"_permuter define {name}{after}" - else: - return f"#define {name}{after}" - - source = re.sub( - r"^\s*#\s*define\s+([a-zA-Z0-9_]+)([ \t\(]|$)", - repl, - source, - flags=re.MULTILINE, - ) - - # Get rid of auto-inserted macros which the second cpp invocation will - # warn about. - source = re.sub(r"^#define __STDC_.*\n", "", source, flags=re.MULTILINE) - - # Now, run the preprocessor again for real. - source = subprocess.check_output( - CPP + STUB_FN_MACROS, cwd=cwd, encoding="utf-8", input=source - ) - - # Finally, find all function-like defines that we hid (some might have - # been comments, so we couldn't do this before), and construct fake - # function declarations for them in a specially demarcated section of - # the file. When the compiler runs, this section will be replaced by - # the real defines and the preprocessor invoked once more. - late_defines = [] - lines = [] - graph = defaultdict(set) - reg_token = re.compile(r"[a-zA-Z0-9_]+") - for line in source.splitlines(): - is_macro = line.startswith("_permuter define ") - params = [] - if is_macro: - ind1 = line.find("(") - ind2 = line.find(" ", len("_permuter define ")) - ind = min(ind1, ind2) - if ind == -1: - ind = len(line) if ind1 == ind2 == -1 else max(ind1, ind2) - before = line[:ind] - after = line[ind:] - name = before.split()[2] - late_defines.append((name, after)) - if after.startswith("("): - params = [w.strip() for w in after[1 : after.find(")")].split(",")] - else: - lines.append(line) - name = "" - for m in reg_token.finditer(line): - name2 = m.group(0) - has_wildcard = False - if is_macro and name2 not in params: - wcbefore = line[: m.start()].rstrip().endswith("##") - wcafter = line[m.end() :].lstrip().startswith("##") - if wcbefore or wcafter: - graph[name].add(name2 + "*") - has_wildcard = True - if not has_wildcard: - graph[name].add(name2) - - # Prune away (recursively) unused macros, for cleanliness. - used_anywhere = set() - used_by_nonmacro = graph[""] - queue = [""] - while queue: - name = queue.pop() - if name not in used_anywhere: - used_anywhere.add(name) - if name.endswith("*"): - wildcard = name[:-1] - for name2 in graph: - if wildcard in name2: - queue.extend(graph[name2]) - else: - queue.extend(graph[name]) - - def get_decl(name: str, after: str) -> str: - typ = preserve_type_fn(name) - if after.startswith("("): - return f"{typ} {name}();" - else: - return f"extern {typ} {name};" - - used_macros = [name for (name, after) in late_defines if name in used_by_nonmacro] - - return ( - "\n".join( - ["#pragma _permuter latedefine start"] - + [ - f"#pragma _permuter define {name}{after}" - for (name, after) in late_defines - if name in used_anywhere - ] - + [ - get_decl(name, after) - for (name, after) in late_defines - if name in used_by_nonmacro - ] - + ["#pragma _permuter latedefine end"] - + lines - + [""] - ), - used_macros, - ) - - -def import_c_file( - compiler: List[str], - cwd: str, - in_file: str, - preserve_macros: Optional[PreserveMacros], -) -> str: - """Preprocess a C file into permuter-usable source. - - Prints preserved macros as a side effect. - - Returns source for base.c and compilable (macro-expanded) source.""" - in_file = os.path.relpath(in_file, cwd) - include_next = 0 - cpp_command = CPP + [in_file, "-D__sgi", "-D_LANGUAGE_C", "-DNON_MATCHING"] - - for arg in compiler: - if include_next > 0: - include_next -= 1 - cpp_command.append(arg) - continue - if arg in ["-D", "-U", "-I"]: - cpp_command.append(arg) - include_next = 1 - continue - if ( - arg.startswith("-D") - or arg.startswith("-U") - or arg.startswith("-I") - or arg in ["-nostdinc"] - ): - cpp_command.append(arg) - - try: - if preserve_macros is None: - # Simple codepath, should work even if the more complex one breaks. - source = subprocess.check_output( - cpp_command + STUB_FN_MACROS, cwd=cwd, encoding="utf-8" - ) - macros: List[str] = [] - else: - source, macros = preprocess_c_with_macros(cpp_command, cwd, preserve_macros) - - except subprocess.CalledProcessError as e: - print( - "Failed to preprocess input file, when running command:\n" - + formatcmd(e.cmd), - file=sys.stderr, - ) - sys.exit(1) - - if macros: - macro_str = "macros: " + ", ".join(macros) - else: - macro_str = "no macros" - print(f"Preserving {macro_str}. Use --preserve-macros='' to override.") - - return source - - -def prune_source( - source: str, should_prune: bool, func_name: str -) -> Tuple[str, Optional[str]]: - """Normalize the source by round-tripping it through pycparser, and - optionally reduce it to a smaller version that includes only the imported - function and functions/struct/variables that it uses. - - Returns (source, compilable_source).""" - try: - ast = ast_util.parse_c(source, from_import=True) - orig_fn, _ = ast_util.extract_fn(ast, func_name) - if should_prune: - try: - ast_util.prune_ast(orig_fn, ast) - source = ast_util.to_c_raw(ast) - except Exception: - print( - "Source minimization failed! " - "You could try --no-prune as a workaround." - ) - raise - return source, ast_util.to_c(ast, from_import=True) - except CandidateConstructionFailure as e: - print(e.message) - if should_prune and "PERM_" in source: - print( - "Please put in PERM macros after import, otherwise source " - "minimization does not work." - ) - else: - print("Proceeding anyway, but expect errors when permuting!") - return source, None - - -def prune_and_separate_context( - source: str, should_prune: bool, func_name: str -) -> Tuple[str, str]: - """Normalize the source by round-tripping it through pycparser, optionally - reduce it to a smaller version that includes only the imported function and - functions/struct/variables that it uses, and split the result into source - for the function itself, and the rest of the file (the "context"). - - Returns (source, context).""" - try: - ast = ast_util.parse_c(source, from_import=True) - orig_fn, ind = ast_util.extract_fn(ast, func_name) - if should_prune: - try: - ind = ast_util.prune_ast(orig_fn, ast) - except Exception: - print( - "Source minimization failed! " - "You could try --no-prune as a workaround." - ) - raise - del ast.ext[ind] - source = ast_util.to_c(orig_fn, from_import=True) - context = ast_util.to_c(ast, from_import=True) - return source, context - except CandidateConstructionFailure as e: - print(e.message) - print("Unable to split context from source.") - print("Proceeding anyway, but expect compile errors!") - return ast_util.process_pragmas(source), "" - - -def get_decompme_compiler_name( - compiler: List[str], settings: Mapping[str, object], api_base: str -) -> str: - decompme_settings = settings.get("decompme", {}) - assert isinstance(decompme_settings, dict) - compiler_mappings = decompme_settings.get("compilers", {}) - assert isinstance(compiler_mappings, dict) - - compiler_path = compiler[0] - - for path, compiler_name in compiler_mappings.items(): - assert isinstance(compiler_name, str) - if path == compiler_path: - return compiler_name - - try: - with urllib.request.urlopen(f"{api_base}/api/compilers") as f: - json_data = json.load(f) - available = json_data["compiler_ids"] - if not isinstance(available, list): - raise Exception("compiler_ids must be a list") - if not all(isinstance(name, str) for name in available): - raise Exception("compiler_ids must be a list of strings") - except Exception as e: - print(f"Failed to request available compilers from decomp.me:\n{e}") - - print() - print( - f'Unable to map compiler path "{compiler_path}" to something ' - "decomp.me understands." - ) - trail = "permuter_settings.toml, where ... is one of: " + ", ".join(available) - if compiler_mappings: - print( - "Please add an entry:\n\n" - f'"{compiler_path}" = "..."\n\n' - f"to the [decompme.compilers] section of {trail}" - ) - else: - print( - "Please add an section:\n\n" - "[decompme.compilers]\n" - f'"{compiler_path}" = "..."\n\n' - f"to {trail}" - ) - sys.exit(1) - - -def finalize_compile_command(cmdline: List[str]) -> str: - quoted = [arg if arg == "|" else shlex.quote(arg) for arg in cmdline] - ind = (quoted + ["|"]).index("|") - return " ".join(quoted[:ind] + ['"$INPUT"'] + quoted[ind:] + ["-o", '"$OUTPUT"']) - - -def get_compiler_flags(cmdline: List[str]) -> str: - flags = [b for a, b in zip(cmdline, cmdline[1:]) if a != "|" and b != "|"] - return " ".join(shlex.quote(flag) for flag in flags) - - -def write_compile_command(compiler: List[str], cwd: str, out_file: str) -> None: - - with open(out_file, "w", encoding="utf-8") as f: - f.write("#!/usr/bin/env bash\n") - f.write('INPUT="$(realpath "$1")"\n') - f.write('OUTPUT="$(realpath "$3")"\n') - f.write(f"cd {shlex.quote(cwd)}\n") - f.write(finalize_compile_command(compiler)) - os.chmod(out_file, 0o755) - - -def write_asm(asm_cont: str, out_file: str) -> None: - with open(out_file, "w", encoding="utf-8") as f: - f.write(ASM_PRELUDE) - f.write(asm_cont) - - -def compile_asm(assembler: List[str], cwd: str, in_file: str, out_file: str) -> None: - in_file = os.path.abspath(in_file) - out_file = os.path.abspath(out_file) - cmdline = assembler + [in_file, "-o", out_file] - try: - subprocess.check_call(cmdline, cwd=cwd) - except subprocess.CalledProcessError: - print( - f"Failed to assemble .s file, command line:\n{formatcmd(cmdline)}", - file=sys.stderr, - ) - sys.exit(1) - - -def compile_base(compile_script: str, source: str, c_file: str, out_file: str) -> None: - if "PERM_" in source: - print( - "Cannot test-compile imported code because it contains PERM macros. " - "It is recommended to put in PERM macros after import." - ) - return - escaped_c_file = json.dumps(c_file) - source = "#line 1 " + escaped_c_file + "\n" + source - compiler = Compiler(compile_script, show_errors=True) - o_file = compiler.compile(source) - if o_file: - shutil.move(o_file, out_file) - else: - print("Warning: failed to compile .c file.") - - -def write_to_file(cont: str, filename: str) -> None: - with open(filename, "w", encoding="utf-8") as f: - f.write(cont) - - -def main() -> None: - parser = argparse.ArgumentParser( - description="""Import a function for use with the permuter. - Will create a new directory nonmatchings/-/.""" - ) - parser.add_argument( - "c_file", - help="""File containing the function. - Assumes that the file can be built with 'make' to create an .o file.""", - ) - parser.add_argument( - "asm_file", - help="""File containing assembly for the function. - Must start with 'glabel ' and contain no other functions.""", - ) - parser.add_argument( - "make_flags", - nargs="*", - help="Arguments to pass to 'make'. PERMUTER=1 will always be passed.", - ) - parser.add_argument( - "--keep", action="store_true", help="Keep the directory on error." - ) - settings_files = ", ".join(SETTINGS_FILES[:-1]) + " or " + SETTINGS_FILES[-1] - parser.add_argument( - "--preserve-macros", - metavar="REGEX", - dest="preserve_macros_regex", - help=f"""Regex for which macros to preserve, or empty string for no macros. - By default, this is read from {settings_files} in a parent directory of - the imported file. Type information is also read from this file.""", - ) - parser.add_argument( - "--no-prune", - dest="prune", - action="store_false", - help="""Don't minimize the source to keep only the imported function and - functions/struct/variables that it uses. Normally this behavior is - useful to make the permuter faster, but in cases where unrelated code - affects the generated assembly asm it can be necessary to turn off. - Note that regardless of this setting the permuter always removes all - other functions by replacing them with declarations.""", - ) - parser.add_argument( - "--decompme", - dest="decompme", - action="store_true", - help="""Upload the function to decomp.me to share with other people, - instead of importing.""", - ) - args = parser.parse_args() - - root_dir = find_root_dir( - args.c_file, SETTINGS_FILES + ["Makefile", "makefile", "build.ninja"] - ) - - if not root_dir: - print(f"Can't find root dir of project!", file=sys.stderr) - sys.exit(1) - - settings: Mapping[str, object] = {} - for filename in SETTINGS_FILES: - filename = os.path.join(root_dir, filename) - if os.path.exists(filename): - with open(filename) as f: - settings = toml.load(f) - break - - build_system = settings.get("build_system", "make") - compiler = settings.get("compiler_command") - assembler = settings.get("assembler_command") - make_flags = args.make_flags - - func_name, asm_cont = parse_asm(args.asm_file) - print(f"Function name: {func_name}") - - if compiler or assembler: - assert isinstance(compiler, str) - assert isinstance(assembler, str) - assert settings.get("build_system") is None - - compiler = shlex.split(compiler) - assembler = shlex.split(assembler) - else: - assert isinstance(build_system, str) - compiler, assembler = find_build_command_line( - root_dir, args.c_file, make_flags, build_system - ) - - print(f"Compiler: {formatcmd(compiler)} {{input}} -o {{output}}") - print(f"Assembler: {formatcmd(assembler)} {{input}} -o {{output}}") - - preserve_macros = build_preserve_macros( - root_dir, args.preserve_macros_regex, settings - ) - source = import_c_file(compiler, root_dir, args.c_file, preserve_macros) - - if args.decompme: - api_base = os.environ.get("DECOMPME_API_BASE", "https://decomp.me") - compiler_name = get_decompme_compiler_name(compiler, settings, api_base) - source, context = prune_and_separate_context(source, args.prune, func_name) - print("Uploading...") - try: - post_data = urllib.parse.urlencode( - { - "target_asm": asm_cont, - "context": context, - "source_code": source, - "compiler": compiler_name, - "compiler_flags": get_compiler_flags(compiler), - } - ).encode("ascii") - with urllib.request.urlopen(f"{api_base}/api/scratch", post_data) as f: - resp = f.read() - json_data: Dict[str, str] = json.loads(resp) - if "slug" in json_data: - slug = json_data["slug"] - print(f"https://decomp.me/scratch/{slug}") - else: - error = json_data.get("error", resp) - print(f"Server error: {error}") - except Exception as e: - print(e) - return - - source, compilable_source = prune_source(source, args.prune, func_name) - - dirname = create_directory(func_name) - base_c_file = f"{dirname}/base.c" - base_o_file = f"{dirname}/base.o" - target_s_file = f"{dirname}/target.s" - target_o_file = f"{dirname}/target.o" - compile_script = f"{dirname}/compile.sh" - func_name_file = f"{dirname}/function.txt" - - try: - write_to_file(source, base_c_file) - write_to_file(func_name, func_name_file) - write_compile_command(compiler, root_dir, compile_script) - write_asm(asm_cont, target_s_file) - compile_asm(assembler, root_dir, target_s_file, target_o_file) - if compilable_source is not None: - compile_base(compile_script, compilable_source, base_c_file, base_o_file) - except: - if not args.keep: - print(f"\nDeleting directory {dirname} (run with --keep to preserve it).") - shutil.rmtree(dirname) - raise - - print(f"\nDone. Imported into {dirname}") - - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/mypy.ini b/tools/decomp-permuter/mypy.ini deleted file mode 100644 index 2d21c54b7..000000000 --- a/tools/decomp-permuter/mypy.ini +++ /dev/null @@ -1,27 +0,0 @@ -[mypy] -check_untyped_defs = True -disallow_any_generics = False -disallow_incomplete_defs = True -disallow_subclassing_any = True -disallow_untyped_calls = True -disallow_untyped_decorators = True -disallow_untyped_defs = True -no_implicit_optional = True -warn_redundant_casts = True -warn_return_any = True -warn_unused_ignores = True -mypy_path = stubs -python_version = 3.7 -files = import.py, pah.py, permuter.py, src/net/evaluator.py - -[mypy-nacl.*] -ignore_missing_imports = True - -[mypy-pystray.*] -ignore_missing_imports = True - -[mypy-docker.*] -ignore_missing_imports = True - -[mypy-PIL.*] -ignore_missing_imports = True diff --git a/tools/decomp-permuter/pah.py b/tools/decomp-permuter/pah.py deleted file mode 100755 index 0adbb369f..000000000 --- a/tools/decomp-permuter/pah.py +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/env python3 -from src.net.cmd.main import main - -main() diff --git a/tools/decomp-permuter/permuter.py b/tools/decomp-permuter/permuter.py deleted file mode 100755 index 8433c8218..000000000 --- a/tools/decomp-permuter/permuter.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python3 -from src.main import main - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/permuter_settings_example.toml b/tools/decomp-permuter/permuter_settings_example.toml deleted file mode 100644 index 46523f331..000000000 --- a/tools/decomp-permuter/permuter_settings_example.toml +++ /dev/null @@ -1,9 +0,0 @@ -# Optional configuration file for import.py. Put it in the root or in tools/ -# of the repo you are importing from. - -build_system = "ninja" - -[preserve_macros] -"g[DS]P.*" = "void" -"gDma.*" = "void" -"_SHIFTL" = "unsigned int" diff --git a/tools/decomp-permuter/run-tests.sh b/tools/decomp-permuter/run-tests.sh deleted file mode 100755 index eff96637e..000000000 --- a/tools/decomp-permuter/run-tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -python3 -m unittest discover -s test/ -# python3 -m pytest test/ diff --git a/tools/decomp-permuter/sort_cands.sh b/tools/decomp-permuter/sort_cands.sh deleted file mode 100755 index 2f30a8469..000000000 --- a/tools/decomp-permuter/sort_cands.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash - -if [[ $1 < 2 ]]; then - echo "Usage: $0 output_dir" - echo "Ex: $0 nonmatchings/func_80000000" - exit 1 -fi -if [[ ! -d $1 ]]; then - echo "Argument must be a directory" - exit 1 -fi - -find $1 -name score.txt -exec echo -n {}\ \; -exec cat {} \; | sort -rnk2 diff --git a/tools/decomp-permuter/src/ast_types.py b/tools/decomp-permuter/src/ast_types.py deleted file mode 100644 index 9eb21c28b..000000000 --- a/tools/decomp-permuter/src/ast_types.py +++ /dev/null @@ -1,303 +0,0 @@ -"""Functions and classes for dealing with types in a C AST. - -They make a number of simplifying assumptions: - - const and volatile doesn't matter. - - arithmetic promotes all int-like types to 'int'. - - no two variables can have the same name, even across functions. - -For the purposes of the randomizer these restrictions are acceptable.""" - -from dataclasses import dataclass, field -from typing import Union, Dict, Set, List - -from pycparser import c_ast -from pycparser.c_ast import ArrayDecl, TypeDecl, PtrDecl, FuncDecl, IdentifierType - -Type = Union[PtrDecl, ArrayDecl, TypeDecl, FuncDecl] -SimpleType = Union[PtrDecl, TypeDecl] - -StructUnion = Union[c_ast.Struct, c_ast.Union] - - -@dataclass -class TypeMap: - typedefs: Dict[str, Type] = field(default_factory=dict) - fn_ret_types: Dict[str, Type] = field(default_factory=dict) - var_types: Dict[str, Type] = field(default_factory=dict) - struct_defs: Dict[str, StructUnion] = field(default_factory=dict) - - -def basic_type(name: Union[str, List[str]]) -> TypeDecl: - names = [name] if isinstance(name, str) else name - idtype = IdentifierType(names=names) - return TypeDecl(declname=None, quals=[], type=idtype) - - -def pointer(type: Type) -> Type: - return PtrDecl(quals=[], type=type) - - -def resolve_typedefs(type: Type, typemap: TypeMap) -> Type: - while ( - isinstance(type, TypeDecl) - and isinstance(type.type, IdentifierType) - and len(type.type.names) == 1 - and type.type.names[0] in typemap.typedefs - ): - type = typemap.typedefs[type.type.names[0]] - return type - - -def pointer_decay(type: Type, typemap: TypeMap) -> SimpleType: - real_type = resolve_typedefs(type, typemap) - if isinstance(real_type, ArrayDecl): - return PtrDecl(quals=[], type=real_type.type) - if isinstance(real_type, FuncDecl): - return PtrDecl(quals=[], type=type) - if isinstance(real_type, TypeDecl) and isinstance(real_type.type, c_ast.Enum): - return basic_type("int") - assert not isinstance( - type, (ArrayDecl, FuncDecl) - ), "resolve_typedefs can't hide arrays/functions" - return type - - -def get_decl_type(decl: c_ast.Decl) -> Type: - """For a Decl that declares a variable (and not just a struct/union/enum), - return its type.""" - assert decl.name is not None - assert isinstance(decl.type, (PtrDecl, ArrayDecl, FuncDecl, TypeDecl)) - return decl.type - - -def deref_type(type: Type, typemap: TypeMap) -> Type: - type = resolve_typedefs(type, typemap) - assert isinstance(type, (ArrayDecl, PtrDecl)), "dereferencing non-pointer" - return type.type - - -def struct_member_type(struct: StructUnion, field_name: str, typemap: TypeMap) -> Type: - if not struct.decls: - assert ( - struct.name in typemap.struct_defs - ), f"Accessing field {field_name} of undefined struct {struct.name}" - struct = typemap.struct_defs[struct.name] - assert struct.decls, "struct_defs never points to an incomplete type" - for decl in struct.decls: - if isinstance(decl, c_ast.Decl): - if decl.name == field_name: - return get_decl_type(decl) - if decl.name == None and isinstance(decl.type, (c_ast.Struct, c_ast.Union)): - try: - return struct_member_type(decl.type, field_name, typemap) - except AssertionError: - pass - - assert False, f"No field {field_name} in struct {struct.name}" - - -def expr_type(node: c_ast.Node, typemap: TypeMap) -> Type: - def rec(sub_expr: c_ast.Node) -> Type: - return expr_type(sub_expr, typemap) - - if isinstance(node, c_ast.Assignment): - return rec(node.lvalue) - if isinstance(node, c_ast.StructRef): - lhs_type = rec(node.name) - if node.type == "->": - lhs_type = deref_type(lhs_type, typemap) - struct_type = resolve_typedefs(lhs_type, typemap) - assert isinstance(struct_type, TypeDecl) - assert isinstance( - struct_type.type, (c_ast.Struct, c_ast.Union) - ), f"struct deref of non-struct {struct_type.declname}" - return struct_member_type(struct_type.type, node.field.name, typemap) - if isinstance(node, c_ast.Cast): - return node.to_type.type - if isinstance(node, c_ast.Constant): - if node.type == "string": - return pointer(basic_type("char")) - if node.type == "char": - return basic_type("int") - return basic_type(node.type.split(" ")) - if isinstance(node, c_ast.ID): - return typemap.var_types[node.name] - if isinstance(node, c_ast.UnaryOp): - if node.op in ["p++", "p--", "++", "--"]: - return rec(node.expr) - if node.op == "&": - return pointer(rec(node.expr)) - if node.op == "*": - subtype = rec(node.expr) - return deref_type(subtype, typemap) - if node.op in ["-", "+"]: - subtype = pointer_decay(rec(node.expr), typemap) - if allowed_basic_type(subtype, typemap, ["double"]): - return basic_type("double") - if allowed_basic_type(subtype, typemap, ["float"]): - return basic_type("float") - if node.op in ["sizeof", "-", "+", "~", "!"]: - return basic_type("int") - assert False, f"unknown unary op {node.op}" - if isinstance(node, c_ast.BinaryOp): - lhs_type = pointer_decay(rec(node.left), typemap) - rhs_type = pointer_decay(rec(node.right), typemap) - if node.op in [">>", "<<"]: - return lhs_type - if node.op in ["<", "<=", ">", ">=", "==", "!=", "&&", "||"]: - return basic_type("int") - if node.op in "&|^%": - return basic_type("int") - real_lhs = resolve_typedefs(lhs_type, typemap) - real_rhs = resolve_typedefs(rhs_type, typemap) - if node.op in "+-": - lptr = isinstance(real_lhs, PtrDecl) - rptr = isinstance(real_rhs, PtrDecl) - if lptr or rptr: - if lptr and rptr: - assert node.op != "+", "pointer + pointer" - return basic_type("int") - if lptr: - return lhs_type - assert node.op == "+", "int - pointer" - return rhs_type - if node.op in "*/+-": - assert isinstance(real_lhs, TypeDecl) - assert isinstance(real_rhs, TypeDecl) - assert isinstance(real_lhs.type, IdentifierType) - assert isinstance(real_rhs.type, IdentifierType) - if "double" in real_lhs.type.names + real_rhs.type.names: - return basic_type("double") - if "float" in real_lhs.type.names + real_rhs.type.names: - return basic_type("float") - return basic_type("int") - if isinstance(node, c_ast.FuncCall): - expr = node.name - if isinstance(expr, c_ast.ID): - if expr.name not in typemap.fn_ret_types: - raise Exception(f"Called function {expr.name} is missing a prototype") - return typemap.fn_ret_types[expr.name] - else: - fptr_type = resolve_typedefs(rec(expr), typemap) - if isinstance(fptr_type, PtrDecl): - fptr_type = fptr_type.type - fptr_type = resolve_typedefs(fptr_type, typemap) - assert isinstance(fptr_type, FuncDecl), "call to non-function" - return fptr_type.type - if isinstance(node, c_ast.ExprList): - return rec(node.exprs[-1]) - if isinstance(node, c_ast.ArrayRef): - subtype = rec(node.name) - return deref_type(subtype, typemap) - if isinstance(node, c_ast.TernaryOp): - return rec(node.iftrue) - assert False, f"Unknown expression node type: {node}" - - -def decayed_expr_type(expr: c_ast.Node, typemap: TypeMap) -> SimpleType: - return pointer_decay(expr_type(expr, typemap), typemap) - - -def same_type( - type1: Type, type2: Type, typemap: TypeMap, allow_similar: bool = False -) -> bool: - while True: - type1 = resolve_typedefs(type1, typemap) - type2 = resolve_typedefs(type2, typemap) - if isinstance(type1, ArrayDecl) and isinstance(type2, ArrayDecl): - type1 = type1.type - type2 = type2.type - continue - if isinstance(type1, PtrDecl) and isinstance(type2, PtrDecl): - type1 = type1.type - type2 = type2.type - continue - if isinstance(type1, TypeDecl) and isinstance(type2, TypeDecl): - sub1 = type1.type - sub2 = type2.type - if isinstance(sub1, c_ast.Struct) and isinstance(sub2, c_ast.Struct): - return sub1.name == sub2.name - if isinstance(sub1, c_ast.Union) and isinstance(sub2, c_ast.Union): - return sub1.name == sub2.name - if ( - allow_similar - and isinstance(sub1, (IdentifierType, c_ast.Enum)) - and isinstance(sub2, (IdentifierType, c_ast.Enum)) - ): - # All int-ish types are similar (except void, but whatever) - return True - if isinstance(sub1, c_ast.Enum) and isinstance(sub2, c_ast.Enum): - return sub1.name == sub2.name - if isinstance(sub1, IdentifierType) and isinstance(sub2, IdentifierType): - return sorted(sub1.names) == sorted(sub2.names) - return False - - -def allowed_basic_type( - type: SimpleType, typemap: TypeMap, allowed_types: List[str] -) -> bool: - """Check if a type resolves to a basic type with one of the allowed_types - keywords in it.""" - base_type = resolve_typedefs(type, typemap) - if not isinstance(base_type, c_ast.TypeDecl): - return False - if not isinstance(base_type.type, c_ast.IdentifierType): - return False - if all(x not in base_type.type.names for x in allowed_types): - return False - return True - - -def build_typemap(ast: c_ast.FileAST) -> TypeMap: - ret = TypeMap() - for item in ast.ext: - if isinstance(item, c_ast.Typedef): - ret.typedefs[item.name] = item.type - if isinstance(item, c_ast.FuncDef): - assert item.decl.name is not None, "cannot define anonymous function" - assert isinstance(item.decl.type, FuncDecl) - ret.fn_ret_types[item.decl.name] = item.decl.type.type - if isinstance(item, c_ast.Decl) and isinstance(item.type, FuncDecl): - assert item.name is not None, "cannot define anonymous function" - ret.fn_ret_types[item.name] = item.type.type - defined_function_decls: Set[c_ast.Decl] = set() - - class Visitor(c_ast.NodeVisitor): - def visit_Struct(self, struct: c_ast.Struct) -> None: - if struct.decls and struct.name is not None: - ret.struct_defs[struct.name] = struct - # Do not visit decls of this struct - - def visit_Union(self, union: c_ast.Union) -> None: - if union.decls and union.name is not None: - ret.struct_defs[union.name] = union - # Do not visit decls of this union - - def visit_Decl(self, decl: c_ast.Decl) -> None: - if decl.name is not None: - ret.var_types[decl.name] = get_decl_type(decl) - if not isinstance(decl.type, FuncDecl) or decl in defined_function_decls: - # Do not visit declarations in parameter lists of functions - # other than our own. - self.visit(decl.type) - - def visit_Enumerator(self, enumerator: c_ast.Enumerator) -> None: - ret.var_types[enumerator.name] = basic_type("int") - - def visit_FuncDef(self, fn: c_ast.FuncDef) -> None: - if fn.decl.name is not None: - ret.var_types[fn.decl.name] = get_decl_type(fn.decl) - defined_function_decls.add(fn.decl) - self.generic_visit(fn) - - Visitor().visit(ast) - return ret - - -def set_decl_name(decl: c_ast.Decl) -> None: - name = decl.name - assert name is not None - type = get_decl_type(decl) - while not isinstance(type, TypeDecl): - type = type.type - type.declname = name diff --git a/tools/decomp-permuter/src/ast_util.py b/tools/decomp-permuter/src/ast_util.py deleted file mode 100644 index 91716fb97..000000000 --- a/tools/decomp-permuter/src/ast_util.py +++ /dev/null @@ -1,505 +0,0 @@ -from base64 import b64decode -from collections import defaultdict -import copy -from dataclasses import dataclass -from random import Random -import re -from typing import Any, Callable, Dict, List, Optional, Set, Tuple, TYPE_CHECKING, Union - -from pycparser import CParser, c_ast as ca, c_generator -from pycparser.plyparser import ParseError - -from .error import CandidateConstructionFailure -from .ast_types import SimpleType, set_decl_name - - -@dataclass -class Indices: - starts: Dict[ca.Node, int] - ends: Dict[ca.Node, int] - - -Block = Union[ca.Compound, ca.Case, ca.Default] -if TYPE_CHECKING: - # ca.Expression and ca.Statement don't actually exist, they live only in - # the stubs file. - Expression = ca.Expression - Statement = ca.Statement -else: - Expression = Statement = None - - -def to_c_raw(node: ca.Node) -> str: - source: str = c_generator.CGenerator().visit(node) - return source - - -def to_c(node: ca.Node, *, from_import: bool = False) -> str: - source = to_c_raw(node) if from_import else PatchedCGenerator().visit(node) - return process_pragmas(source) - - -def process_pragmas(source: str) -> str: - if "#pragma" not in source: - return source - lines = source.split("\n") - out: List[str] = [] - same_line = 0 - ignore = 0 - for line in lines: - stripped = line.strip() - if stripped.startswith("#pragma _permuter "): - # Expand permuter pragmas to nothing, by default. Still, keep one - # output line per input line to preserve line numbers for import.py - # error messages. - line = "" - - stripped = stripped[len("#pragma _permuter ") :] - if stripped == "sameline start": - same_line += 1 - elif stripped == "sameline end": - same_line -= 1 - elif stripped == "latedefine start": - ignore += 1 - elif stripped == "latedefine end": - assert ignore > 0, "mismatched ignore pragmas" - ignore -= 1 - elif stripped.startswith("define "): - assert ignore > 0, "define pragma must be within latedefine block" - line = "#" + stripped - elif stripped.startswith("b64literal "): - line = b64decode(stripped.split(" ", 1)[1]).decode("utf-8") - elif ignore > 0: - # Ignore non-pragma lines within latedefine section - line = "" - - if not same_line: - line += "\n" - elif line and out and not out[-1].endswith("\n"): - line = " " + line.lstrip() - out.append(line) - assert same_line == 0 - assert ignore == 0, "unbalanced ignore pragmas" - return "".join(out).rstrip() + "\n" - - -class PatchedCGenerator(c_generator.CGenerator): - """Like a CGenerator, except it keeps else if's prettier despite - the terrible things we've done to them in normalize_ast.""" - - def visit_If(self, n: ca.If) -> str: - n2 = n - if ( - n.iffalse - and isinstance(n.iffalse, ca.Compound) - and n.iffalse.block_items - and len(n.iffalse.block_items) == 1 - and isinstance(n.iffalse.block_items[0], ca.If) - ): - n2 = ca.If(cond=n.cond, iftrue=n.iftrue, iffalse=n.iffalse.block_items[0]) - return super().visit_If(n2) # type: ignore - - -def extract_fn(ast: ca.FileAST, fn_name: str) -> Tuple[ca.FuncDef, int]: - ret = [] - for i, node in enumerate(ast.ext): - if isinstance(node, ca.FuncDef): - if node.decl.name == fn_name: - ret.append((node, i)) - else: - node = node.decl - ast.ext[i] = node - if isinstance(node, ca.Decl) and isinstance(node.type, ca.FuncDecl): - node.funcspec = [spec for spec in node.funcspec if spec != "static"] - if len(ret) == 0: - raise CandidateConstructionFailure(f"Function {fn_name} not found in base.c.") - if len(ret) > 1: - raise CandidateConstructionFailure( - f"Found multiple copies of function {fn_name} in base.c." - ) - return ret[0] - - -def parse_c(source: str, *, from_import: bool = False) -> ca.FileAST: - try: - parser = CParser() - return parser.parse(source, "") - except ParseError as e: - msg = str(e) - position, msg = msg.split(": ", 1) - parts = position.split(":") - if len(parts) >= 2: - lineno = int(parts[1]) - posstr = f" at approximately line {lineno}" - if len(parts) >= 3: - posstr += f", column {parts[2]}" - if not from_import: - posstr += " (after PERM expansion)" - try: - line = source.split("\n")[lineno - 1].rstrip() - posstr += "\n\n" + line - except IndexError: - posstr += "(out of bounds?)" - else: - posstr = "" - raise CandidateConstructionFailure( - f"Syntax error in base.c.\n{msg}{posstr}" - ) from None - - -def compute_node_indices(top_node: ca.Node) -> Indices: - starts: Dict[ca.Node, int] = {} - ends: Dict[ca.Node, int] = {} - cur_index = 1 - - class Visitor(ca.NodeVisitor): - def generic_visit(self, node: ca.Node) -> None: - nonlocal cur_index - assert node not in starts, "nodes should only appear once in AST" - starts[node] = cur_index - cur_index += 2 - super().generic_visit(node) - ends[node] = cur_index - cur_index += 2 - - Visitor().visit(top_node) - return Indices(starts, ends) - - -def equal_ast(a: ca.Node, b: ca.Node) -> bool: - def equal(a: Any, b: Any) -> bool: - if type(a) != type(b): - return False - if a is None: - return b is None - if isinstance(a, list): - assert isinstance(b, list) - if len(a) != len(b): - return False - for i in range(len(a)): - if not equal(a[i], b[i]): - return False - return True - if isinstance(a, (int, str)): - return bool(a == b) - assert isinstance(a, ca.Node) - for name in a.__slots__[:-2]: # type: ignore - if not equal(getattr(a, name), getattr(b, name)): - return False - return True - - return equal(a, b) - - -def is_lvalue(expr: Expression) -> bool: - if isinstance(expr, (ca.ID, ca.StructRef, ca.ArrayRef)): - return True - if isinstance(expr, ca.UnaryOp): - return expr.op == "*" - return False - - -def is_effectful(expr: Expression) -> bool: - found = False - - class Visitor(ca.NodeVisitor): - def visit_UnaryOp(self, node: ca.UnaryOp) -> None: - nonlocal found - if node.op in ["p++", "p--", "++", "--"]: - found = True - else: - self.generic_visit(node.expr) - - def visit_FuncCall(self, _: ca.Node) -> None: - nonlocal found - found = True - - def visit_Assignment(self, _: ca.Node) -> None: - nonlocal found - found = True - - Visitor().visit(expr) - return found - - -def get_block_stmts(block: Block, force: bool) -> List[Statement]: - if isinstance(block, ca.Compound): - ret = block.block_items or [] - if force and not block.block_items: - block.block_items = ret - else: - ret = block.stmts or [] - if force and not block.stmts: - block.stmts = ret - return ret - - -def insert_decl( - fn: ca.FuncDef, var: str, type: SimpleType, random: Optional[Random] = None -) -> None: - type = copy.deepcopy(type) - decl = ca.Decl( - name=var, quals=[], storage=[], funcspec=[], type=type, init=None, bitsize=None - ) - set_decl_name(decl) - assert fn.body.block_items, "Non-empty function" - for index, stmt in enumerate(fn.body.block_items): - if not isinstance(stmt, ca.Decl): - break - else: - index = len(fn.body.block_items) - - if random: - index = random.randint(0, index) - fn.body.block_items[index:index] = [decl] - - -def insert_statement(block: Block, index: int, stmt: Statement) -> None: - stmts = get_block_stmts(block, True) - stmts[index:index] = [stmt] - - -def brace_nested_blocks(stmt: Statement) -> None: - def brace(stmt: Statement) -> Block: - if isinstance(stmt, (ca.Compound, ca.Case, ca.Default)): - return stmt - return ca.Compound([stmt]) - - if isinstance(stmt, (ca.For, ca.While, ca.DoWhile)): - stmt.stmt = brace(stmt.stmt) - elif isinstance(stmt, ca.If): - stmt.iftrue = brace(stmt.iftrue) - if stmt.iffalse: - stmt.iffalse = brace(stmt.iffalse) - elif isinstance(stmt, ca.Switch): - stmt.stmt = brace(stmt.stmt) - elif isinstance(stmt, ca.Label): - brace_nested_blocks(stmt.stmt) - - -def has_nested_block(node: ca.Node) -> bool: - return isinstance( - node, - ( - ca.Compound, - ca.For, - ca.While, - ca.DoWhile, - ca.If, - ca.Switch, - ca.Case, - ca.Default, - ), - ) - - -def for_nested_blocks(stmt: Statement, callback: Callable[[Block], None]) -> None: - def invoke(stmt: Statement) -> None: - assert isinstance( - stmt, (ca.Compound, ca.Case, ca.Default) - ), "brace_nested_blocks should have turned nested statements into blocks" - callback(stmt) - - if isinstance(stmt, ca.Compound): - invoke(stmt) - elif isinstance(stmt, (ca.For, ca.While, ca.DoWhile)): - invoke(stmt.stmt) - elif isinstance(stmt, ca.If): - if stmt.iftrue: - invoke(stmt.iftrue) - if stmt.iffalse: - invoke(stmt.iffalse) - elif isinstance(stmt, ca.Switch): - invoke(stmt.stmt) - elif isinstance(stmt, (ca.Case, ca.Default)): - invoke(stmt) - elif isinstance(stmt, ca.Label): - for_nested_blocks(stmt.stmt, callback) - - -def normalize_ast(fn: ca.FuncDef, ast: ca.FileAST) -> None: - """Add braces to all ifs/fors/etc., to make it easier to insert statements.""" - - def rec(block: Block) -> None: - stmts = get_block_stmts(block, False) - for stmt in stmts: - brace_nested_blocks(stmt) - for_nested_blocks(stmt, rec) - - rec(fn.body) - - -def prune_ast(fn: ca.FuncDef, ast: ca.FileAST) -> int: - """Prune away unnecessary parts of the AST, to reduce overhead from serialization - and from the compiler's C parser.""" - - # Create a GC graph that maps names of declarations and enumerators to indices - # in ast.ext, as well an initial list of GC roots, consisting of everything - # that isn't a Decl and or Typedef. - edges: Dict[str, List[int]] = defaultdict(list) - gc_roots: List[int] = [] - can_fwd_declare_typedef: Set[str] = set() - can_fwd_declare_tagged: Set[str] = set() - - def add_type_edges( - tp: Union["ca.Type", ca.Struct, ca.Union, ca.Enum], i: int - ) -> None: - while isinstance(tp, (ca.PtrDecl, ca.ArrayDecl)): - tp = tp.type - if isinstance(tp, ca.FuncDecl): - return - inner_type = tp.type if isinstance(tp, ca.TypeDecl) else tp - if isinstance(inner_type, ca.IdentifierType): - return - if inner_type.name: - edges[inner_type.name].append(i) - if isinstance(inner_type, ca.Enum) and inner_type.values: - for value in inner_type.values.enumerators: - edges[value.name].append(i) - if isinstance(inner_type, (ca.Struct, ca.Union)) and inner_type.decls: - for decl in inner_type.decls: - if isinstance(decl, ca.Decl): - add_type_edges(decl.type, i) - - for i in range(len(ast.ext)): - item = ast.ext[i] - if isinstance(item, ca.Decl) and not item.init: - # (Exclude declarations with initializers, since taking function - # pointers can affect regalloc on IDO.) - if item.name: - edges[item.name].append(i) - if isinstance(item.type, (ca.Struct, ca.Union, ca.Enum)) and item.type.name: - can_fwd_declare_tagged.add(item.type.name) - add_type_edges(item.type, i) - elif isinstance(item, ca.Typedef): - edges[item.name].append(i) - if isinstance(item.type, ca.TypeDecl) and isinstance( - item.type.type, (ca.Struct, ca.Union, ca.Enum) - ): - can_fwd_declare_typedef.add(item.name) - add_type_edges(item.type, i) - elif isinstance(item, ca.Pragma) and "GLOBAL_ASM" in item.string: - pass - else: - gc_roots.append(i) - - mentioned_ids: Set[str] = set() - - class IdVisitor(ca.NodeVisitor): - def visit_Pragma(self, node: ca.Pragma) -> None: - for token in re.findall(r"[a-zA-Z0-9_$]+", node.string): - mentioned_ids.add(token) - - def visit_ID(self, node: ca.ID) -> None: - mentioned_ids.add(node.name) - - IdVisitor().visit(ast) - - # Do the GC as a DFS traversal of the graph. Visiting a node searches its - # AST for all kinds of mentioned IDs, and adds more nodes to the stack - # using the edges we found before. - gc_todo: List[int] = gc_roots - need_fwd_decl_typedef: List[str] = [] - need_fwd_decl_tagged: List[str] = [] - - def add_name(name: str) -> None: - if name in edges: - gc_todo.extend(edges[name]) - del edges[name] - - class Visitor(ca.NodeVisitor): - def visit_Pragma(self, node: ca.Pragma) -> None: - for token in re.findall(r"[a-zA-Z0-9_$]+", node.string): - add_name(token) - - def visit_ID(self, node: ca.ID) -> None: - add_name(node.name) - - def visit_IdentifierType(self, node: ca.IdentifierType) -> None: - for name in node.names: - add_name(name) - - def visit_Enum(self, node: ca.Enum) -> None: - if node.name and not node.values: - add_name(node.name) - self.generic_visit(node) - - def visit_Struct(self, node: ca.Struct) -> None: - if node.name and not node.decls: - add_name(node.name) - self.generic_visit(node) - - def visit_Union(self, node: ca.Union) -> None: - if node.name and not node.decls: - add_name(node.name) - self.generic_visit(node) - - def visit_PtrDecl(self, node: ca.PtrDecl) -> None: - # For pointer declarations which haven't been accessed, forward - # declarations suffice. - if ( - isinstance(node.type, ca.TypeDecl) - and node.type.declname - and node.type.declname not in mentioned_ids - ): - tp = node.type.type - if isinstance(tp, ca.IdentifierType): - if all(name in can_fwd_declare_typedef for name in tp.names): - need_fwd_decl_typedef.extend(tp.names) - return - elif tp.name and tp.name in can_fwd_declare_tagged: - if not (tp.values if isinstance(tp, ca.Enum) else tp.decls): - need_fwd_decl_tagged.append(tp.name) - return - self.generic_visit(node) - - def visit_TypeDecl(self, node: ca.TypeDecl) -> None: - if node.declname: - add_name(node.declname) - self.generic_visit(node) - - keep_exts: Set[int] = set() - while gc_todo: - i = gc_todo.pop() - if i not in keep_exts: - keep_exts.add(i) - Visitor().visit(ast.ext[i]) - - temp_id = 0 - - def fwd_declare(tp: Union[ca.Struct, ca.Union, ca.Enum]) -> None: - nonlocal temp_id - if not tp.name: - temp_id += 1 - tp.name = f"_PermuterTemp{temp_id}" - if isinstance(tp, (ca.Struct, ca.Union)): - tp.decls = None - elif isinstance(tp, ca.Enum): - tp.values = None - else: - assert False - - new_ext = [] - - for i, item in enumerate(ast.ext): - if i in keep_exts: - pass - elif isinstance(item, ca.Typedef) and item.name in need_fwd_decl_typedef: - assert item.name in can_fwd_declare_typedef - assert isinstance(item.type, ca.TypeDecl) - assert isinstance(item.type.type, (ca.Struct, ca.Union, ca.Enum)) - fwd_declare(item.type.type) - elif ( - isinstance(item, ca.Decl) - and isinstance(item.type, (ca.Struct, ca.Union, ca.Enum)) - and item.type.name - and item.type.name in need_fwd_decl_tagged - ): - assert item.type.name in can_fwd_declare_tagged - fwd_declare(item.type) - else: - continue - new_ext.append(item) - - ast.ext = new_ext - return ast.ext.index(fn) diff --git a/tools/decomp-permuter/src/candidate.py b/tools/decomp-permuter/src/candidate.py deleted file mode 100644 index 5504b3d3d..000000000 --- a/tools/decomp-permuter/src/candidate.py +++ /dev/null @@ -1,99 +0,0 @@ -import copy -from dataclasses import dataclass, field -import functools -from typing import Optional, Tuple - -from pycparser import c_ast as ca - -from .compiler import Compiler -from .randomizer import Randomizer -from .scorer import Scorer -from .perm.perm import EvalState -from .perm.ast import apply_ast_perms -from .helpers import try_remove -from .profiler import Profiler -from . import ast_util - - -@dataclass -class CandidateResult: - """Represents the result of scoring a candidate, and is sent from child to - parent processes, or server to client with p@h.""" - - score: int - hash: Optional[str] - source: Optional[str] - profiler: Optional[Profiler] = None - - -@dataclass -class Candidate: - """ - Represents a AST candidate created from a source which can be randomized - (possibly multiple times), compiled, and scored. - """ - - ast: ca.FileAST - - fn_index: int - rng_seed: int - randomizer: Randomizer - score_value: Optional[int] = field(init=False, default=None) - score_hash: Optional[str] = field(init=False, default=None) - _cache_source: Optional[str] = field(init=False, default=None) - - @staticmethod - @functools.lru_cache(maxsize=16) - def _cached_shared_ast( - source: str, fn_name: str - ) -> Tuple[ca.FuncDef, int, ca.FileAST]: - ast = ast_util.parse_c(source) - orig_fn, fn_index = ast_util.extract_fn(ast, fn_name) - ast_util.normalize_ast(orig_fn, ast) - return orig_fn, fn_index, ast - - @staticmethod - def from_source( - source: str, eval_state: EvalState, fn_name: str, rng_seed: int - ) -> "Candidate": - # Use the same AST for all instances of the same original source, but - # with the target function deeply copied. Since we never change the - # AST outside of the target function, this is fine, and it saves us - # performance (deepcopy is really slow). - orig_fn, fn_index, ast = Candidate._cached_shared_ast(source, fn_name) - ast = copy.copy(ast) - ast.ext = copy.copy(ast.ext) - fn_copy = copy.deepcopy(orig_fn) - ast.ext[fn_index] = fn_copy - apply_ast_perms(fn_copy, eval_state) - return Candidate( - ast=ast, - fn_index=fn_index, - rng_seed=rng_seed, - randomizer=Randomizer(rng_seed), - ) - - def randomize_ast(self) -> None: - self.randomizer.randomize(self.ast, self.fn_index) - self._cache_source = None - - def get_source(self) -> str: - if self._cache_source is None: - self._cache_source = ast_util.to_c(self.ast) - return self._cache_source - - def compile(self, compiler: Compiler, show_errors: bool = False) -> Optional[str]: - source: str = self.get_source() - return compiler.compile(source, show_errors=show_errors) - - def score(self, scorer: Scorer, o_file: Optional[str]) -> CandidateResult: - self.score_value = None - self.score_hash = None - try: - self.score_value, self.score_hash = scorer.score(o_file) - finally: - if o_file: - try_remove(o_file) - return CandidateResult( - score=self.score_value, hash=self.score_hash, source=self.get_source() - ) diff --git a/tools/decomp-permuter/src/compiler.py b/tools/decomp-permuter/src/compiler.py deleted file mode 100644 index 284ed316b..000000000 --- a/tools/decomp-permuter/src/compiler.py +++ /dev/null @@ -1,48 +0,0 @@ -from typing import Optional -import tempfile -import subprocess - -from .helpers import try_remove - - -class Compiler: - def __init__(self, compile_cmd: str, *, show_errors: bool) -> None: - self.compile_cmd = compile_cmd - self.show_errors = show_errors - - def compile(self, source: str, *, show_errors: bool = False) -> Optional[str]: - """Try to compile a piece of C code. Returns the filename of the resulting .o - temp file if it succeeds.""" - show_errors = show_errors or self.show_errors - with tempfile.NamedTemporaryFile( - prefix="permuter", suffix=".c", mode="w", delete=False - ) as f: - c_name = f.name - f.write(source) - - with tempfile.NamedTemporaryFile( - prefix="permuter", suffix=".o", delete=False - ) as f2: - o_name = f2.name - - try: - stderr = 2 if show_errors else subprocess.DEVNULL - subprocess.check_call( - [self.compile_cmd, c_name, "-o", o_name], - stdout=stderr, - stderr=stderr, - ) - except subprocess.CalledProcessError: - if not show_errors: - try_remove(c_name) - try_remove(o_name) - return None - except KeyboardInterrupt: - # If Ctrl+C happens during this call, make a best effort in - # removing the .c and .o files. This is totally racy, but oh well... - try_remove(c_name) - try_remove(o_name) - raise - - try_remove(c_name) - return o_name diff --git a/tools/decomp-permuter/src/error.py b/tools/decomp-permuter/src/error.py deleted file mode 100644 index a3f53985f..000000000 --- a/tools/decomp-permuter/src/error.py +++ /dev/null @@ -1,11 +0,0 @@ -from dataclasses import dataclass - - -@dataclass -class ServerError(Exception): - message: str - - -@dataclass -class CandidateConstructionFailure(Exception): - message: str diff --git a/tools/decomp-permuter/src/helpers.py b/tools/decomp-permuter/src/helpers.py deleted file mode 100644 index 5daab7605..000000000 --- a/tools/decomp-permuter/src/helpers.py +++ /dev/null @@ -1,22 +0,0 @@ -import os -from typing import NoReturn - - -def plural(n: int, noun: str) -> str: - s = "s" if n != 1 else "" - return f"{n} {noun}{s}" - - -def exception_to_string(e: object) -> str: - return str(e) or e.__class__.__name__ - - -def static_assert_unreachable(x: NoReturn) -> NoReturn: - raise Exception("Unreachable! " + repr(x)) - - -def try_remove(path: str) -> None: - try: - os.remove(path) - except FileNotFoundError: - pass diff --git a/tools/decomp-permuter/src/main.py b/tools/decomp-permuter/src/main.py deleted file mode 100644 index 22320bbe2..000000000 --- a/tools/decomp-permuter/src/main.py +++ /dev/null @@ -1,654 +0,0 @@ -import argparse -from dataclasses import dataclass, field -import itertools -import multiprocessing -from multiprocessing import Queue -import os -import queue -import sys -import threading -import time -from typing import ( - Callable, - Dict, - Iterable, - Iterator, - List, - Optional, - Tuple, -) - -from .candidate import CandidateResult -from .compiler import Compiler -from .error import CandidateConstructionFailure -from .helpers import plural, static_assert_unreachable -from .net.client import start_client -from .net.core import ServerError, connect, enable_debug_mode, MAX_PRIO, MIN_PRIO -from .permuter import ( - EvalError, - EvalResult, - Feedback, - Finished, - Message, - NeedMoreWork, - Permuter, - Task, - WorkDone, -) -from .preprocess import preprocess -from .printer import Printer -from .profiler import Profiler -from .scorer import Scorer - -# The probability that the randomizer continues transforming the output it -# generated last time. -DEFAULT_RAND_KEEP_PROB = 0.6 - - -@dataclass -class Options: - directories: List[str] - show_errors: bool = False - show_timings: bool = False - print_diffs: bool = False - stack_differences: bool = False - abort_exceptions: bool = False - better_only: bool = False - best_only: bool = False - quiet: bool = False - stop_on_zero: bool = False - keep_prob: float = DEFAULT_RAND_KEEP_PROB - force_seed: Optional[str] = None - threads: int = 1 - use_network: bool = False - network_debug: bool = False - network_priority: float = 1.0 - - -def restricted_float(lo: float, hi: float) -> Callable[[str], float]: - def convert(x: str) -> float: - try: - ret = float(x) - except ValueError: - raise argparse.ArgumentTypeError(f"invalid float value: '{x}'") - - if ret < lo or ret > hi: - raise argparse.ArgumentTypeError( - f"value {x} is out of range (must be between {lo} and {hi})" - ) - return ret - - return convert - - -@dataclass -class EvalContext: - options: Options - printer: Printer = field(default_factory=Printer) - iteration: int = 0 - errors: int = 0 - overall_profiler: Profiler = field(default_factory=Profiler) - permuters: List[Permuter] = field(default_factory=list) - - -def write_candidate(perm: Permuter, result: CandidateResult) -> None: - """Write the candidate's C source and score to the next output directory""" - ctr = 0 - while True: - ctr += 1 - try: - output_dir = os.path.join(perm.dir, f"output-{result.score}-{ctr}") - os.mkdir(output_dir) - break - except FileExistsError: - pass - source = result.source - assert source is not None, "Permuter._need_to_send_source is wrong!" - with open(os.path.join(output_dir, "source.c"), "x", encoding="utf-8") as f: - f.write(source) - with open(os.path.join(output_dir, "score.txt"), "x", encoding="utf-8") as f: - f.write(f"{result.score}\n") - with open(os.path.join(output_dir, "diff.txt"), "x", encoding="utf-8") as f: - f.write(perm.diff(source) + "\n") - print(f"wrote to {output_dir}") - - -def post_score( - context: EvalContext, permuter: Permuter, result: EvalResult, who: Optional[str] -) -> bool: - if isinstance(result, EvalError): - if result.exc_str is not None: - context.printer.print( - "internal permuter failure.", permuter, who, keep_progress=True - ) - print(result.exc_str) - if result.seed is not None: - seed_str = str(result.seed[1]) - if result.seed[0] != 0: - seed_str = f"{result.seed[0]},{seed_str}" - print(f"To reproduce the failure, rerun with: --seed {seed_str}") - if context.options.abort_exceptions: - sys.exit(1) - else: - return False - - if context.options.print_diffs: - assert result.source is not None, "Permuter._need_to_send_source is wrong" - print() - print(permuter.diff(result.source)) - input("Press any key to continue...") - - profiler = result.profiler - score_value = result.score - - if profiler is not None: - for stattype in profiler.time_stats: - context.overall_profiler.add_stat(stattype, profiler.time_stats[stattype]) - - context.iteration += 1 - if score_value == permuter.scorer.PENALTY_INF: - disp_score = "inf" - context.errors += 1 - else: - disp_score = str(score_value) - timings = "" - if context.options.show_timings: - timings = " \t" + context.overall_profiler.get_str_stats() - status_line = f"iteration {context.iteration}, {context.errors} errors, score = {disp_score}{timings}" - - if permuter.should_output(result): - former_best = permuter.best_score - permuter.record_result(result) - if score_value < former_best: - color = "\u001b[32;1m" - msg = f"found new best score! ({score_value} vs {permuter.base_score})" - elif score_value == former_best: - color = "\u001b[32;1m" - msg = f"tied best score! ({score_value} vs {permuter.base_score})" - elif score_value < permuter.base_score: - color = "\u001b[33m" - msg = f"found a better score! ({score_value} vs {permuter.base_score})" - else: - color = "\u001b[33m" - msg = f"found different asm with same score ({score_value})" - context.printer.print(msg, permuter, who, color=color) - - write_candidate(permuter, result) - if not context.options.quiet: - context.printer.progress(status_line) - return score_value == 0 - - -def cycle_seeds(permuters: List[Permuter]) -> Iterable[Tuple[int, int]]: - """ - Return all possible (permuter index, seed) pairs, cycling over permuters. - If a permuter is randomized, it will keep repeating seeds infinitely. - """ - iterators: List[Iterator[Tuple[int, int]]] = [] - for perm_ind, permuter in enumerate(permuters): - it = permuter.seed_iterator() - iterators.append(zip(itertools.repeat(perm_ind), it)) - - i = 0 - while iterators: - i %= len(iterators) - item = next(iterators[i], None) - if item is None: - del iterators[i] - i -= 1 - else: - yield item - i += 1 - - -def multiprocess_worker( - permuters: List[Permuter], - input_queue: "Queue[Task]", - output_queue: "Queue[Feedback]", -) -> None: - try: - while True: - # Read a work item from the queue. If none is immediately available, - # tell the main thread to fill the queues more, and then block on - # the queue. - queue_item: Task - try: - queue_item = input_queue.get(block=False) - except queue.Empty: - output_queue.put((NeedMoreWork(), -1, None)) - queue_item = input_queue.get() - if isinstance(queue_item, Finished): - output_queue.put((queue_item, -1, None)) - output_queue.close() - break - permuter_index, seed = queue_item - permuter = permuters[permuter_index] - result = permuter.try_eval_candidate(seed) - if isinstance(result, CandidateResult) and permuter.should_output(result): - permuter.record_result(result) - output_queue.put((WorkDone(permuter_index, result), -1, None)) - output_queue.put((NeedMoreWork(), -1, None)) - except KeyboardInterrupt: - # Don't clutter the output with stack traces; Ctrl+C is the expected - # way to quit and sends KeyboardInterrupt to all processes. - # A heartbeat thing here would be good but is too complex. - # Don't join the queue background thread -- thread joins in relation - # to KeyboardInterrupt usually result in deadlocks. - input_queue.cancel_join_thread() - output_queue.cancel_join_thread() - - -def run(options: Options) -> List[int]: - last_time = time.time() - try: - - def heartbeat() -> None: - nonlocal last_time - last_time = time.time() - - return run_inner(options, heartbeat) - except KeyboardInterrupt: - if time.time() - last_time > 5: - print() - print("Aborting stuck process.") - raise - print() - print("Exiting.") - sys.exit(0) - - -def run_inner(options: Options, heartbeat: Callable[[], None]) -> List[int]: - print("Loading...") - - context = EvalContext(options) - - force_seed: Optional[int] = None - force_rng_seed: Optional[int] = None - if options.force_seed: - seed_parts = list(map(int, options.force_seed.split(","))) - force_rng_seed = seed_parts[-1] - force_seed = 0 if len(seed_parts) == 1 else seed_parts[0] - - name_counts: Dict[str, int] = {} - for i, d in enumerate(options.directories): - heartbeat() - compile_cmd = os.path.join(d, "compile.sh") - target_o = os.path.join(d, "target.o") - base_c = os.path.join(d, "base.c") - for fname in [compile_cmd, target_o, base_c]: - if not os.path.isfile(fname): - print(f"Missing file {fname}", file=sys.stderr) - sys.exit(1) - if not os.stat(compile_cmd).st_mode & 0o100: - print(f"{compile_cmd} must be marked executable.", file=sys.stderr) - sys.exit(1) - - fn_name: Optional[str] = None - try: - with open(os.path.join(d, "function.txt"), encoding="utf-8") as f: - fn_name = f.read().strip() - except FileNotFoundError: - pass - - if fn_name: - print(f"{base_c} ({fn_name})") - else: - print(base_c) - - compiler = Compiler(compile_cmd, show_errors=options.show_errors) - scorer = Scorer(target_o, stack_differences=options.stack_differences) - c_source = preprocess(base_c) - - try: - permuter = Permuter( - d, - fn_name, - compiler, - scorer, - base_c, - c_source, - force_seed=force_seed, - force_rng_seed=force_rng_seed, - keep_prob=options.keep_prob, - need_profiler=options.show_timings, - need_all_sources=options.print_diffs, - show_errors=options.show_errors, - best_only=options.best_only, - better_only=options.better_only, - ) - except CandidateConstructionFailure as e: - print(e.message, file=sys.stderr) - sys.exit(1) - - context.permuters.append(permuter) - name_counts[permuter.fn_name] = name_counts.get(permuter.fn_name, 0) + 1 - print() - - if not context.permuters: - print("No permuters!") - return [] - - for permuter in context.permuters: - if name_counts[permuter.fn_name] > 1: - permuter.unique_name += f" ({permuter.dir})" - print(f"[{permuter.unique_name}] base score = {permuter.best_score}") - - found_zero = False - if options.threads == 1 and not options.use_network: - # Simple single-threaded mode. This is not technically needed, but - # makes the permuter easier to debug. - for permuter_index, seed in cycle_seeds(context.permuters): - heartbeat() - permuter = context.permuters[permuter_index] - result = permuter.try_eval_candidate(seed) - if post_score(context, permuter, result, None): - found_zero = True - if options.stop_on_zero: - break - else: - seed_iterators: List[Optional[Iterator[int]]] = [ - permuter.seed_iterator() - for perm_ind, permuter in enumerate(context.permuters) - ] - seed_iterators_remaining = len(seed_iterators) - next_iterator_index = 0 - - # Create queues. - worker_task_queue: "Queue[Task]" = Queue() - feedback_queue: "Queue[Feedback]" = Queue() - - # Connect to network and create client threads and queues. - net_conns: "List[Tuple[threading.Thread, Queue[Task]]]" = [] - if options.use_network: - print("Connecting to permuter@home...") - if options.network_debug: - enable_debug_mode() - first_stats: Optional[Tuple[int, int, float]] = None - for perm_index in range(len(context.permuters)): - try: - port = connect() - except (EOFError, ServerError) as e: - print("Error:", e) - sys.exit(1) - thread, queue, stats = start_client( - port, - context.permuters[perm_index], - perm_index, - feedback_queue, - options.network_priority, - ) - net_conns.append((thread, queue)) - if first_stats is None: - first_stats = stats - assert first_stats is not None, "has at least one permuter" - clients_str = plural(first_stats[0], "other client") - servers_str = plural(first_stats[1], "server") - cores_str = plural(int(first_stats[2]), "core") - print(f"Connected! {servers_str} online ({cores_str}, {clients_str})") - - # Start local worker threads - processes: List[multiprocessing.Process] = [] - for i in range(options.threads): - p = multiprocessing.Process( - target=multiprocess_worker, - args=(context.permuters, worker_task_queue, feedback_queue), - ) - p.start() - processes.append(p) - - active_workers = len(processes) - - if not active_workers and not net_conns: - print("No workers available! Exiting.") - sys.exit(1) - - def process_finish(finish: Finished, source: int) -> None: - nonlocal active_workers - - if finish.reason: - permuter: Optional[Permuter] = None - if source != -1 and len(context.permuters) > 1: - permuter = context.permuters[source] - context.printer.print(finish.reason, permuter, None, keep_progress=True) - - if source == -1: - active_workers -= 1 - - def process_result(work: WorkDone, who: Optional[str]) -> bool: - permuter = context.permuters[work.perm_index] - return post_score(context, permuter, work.result, who) - - def get_task(perm_index: int) -> Optional[Tuple[int, int]]: - nonlocal next_iterator_index, seed_iterators_remaining - if perm_index == -1: - while seed_iterators_remaining > 0: - task = get_task(next_iterator_index) - next_iterator_index += 1 - next_iterator_index %= len(seed_iterators) - if task is not None: - return task - else: - it = seed_iterators[perm_index] - if it is not None: - seed = next(it, None) - if seed is None: - seed_iterators[perm_index] = None - seed_iterators_remaining -= 1 - else: - return (perm_index, seed) - return None - - # Feed the task queue with work and read from results queue. - # We generally match these up one-by-one to avoid overfilling queues, - # but workers can ask us to add more tasks into the system if they run - # out of work. (This will happen e.g. at the very beginning, when the - # queues are empty.) - while seed_iterators_remaining > 0: - heartbeat() - feedback, source, who = feedback_queue.get() - if isinstance(feedback, Finished): - process_finish(feedback, source) - elif isinstance(feedback, Message): - context.printer.print(feedback.text, None, who, keep_progress=True) - elif isinstance(feedback, WorkDone): - if process_result(feedback, who): - # Found score 0! - found_zero = True - if options.stop_on_zero: - break - elif isinstance(feedback, NeedMoreWork): - task = get_task(source) - if task is not None: - if source == -1: - worker_task_queue.put(task) - else: - net_conns[source][1].put(task) - else: - static_assert_unreachable(feedback) - - # Signal workers to stop. - for i in range(active_workers): - worker_task_queue.put(Finished()) - - for conn in net_conns: - conn[1].put(Finished()) - - # Await final results. - while active_workers > 0 or net_conns: - heartbeat() - feedback, source, who = feedback_queue.get() - if isinstance(feedback, Finished): - process_finish(feedback, source) - elif isinstance(feedback, Message): - context.printer.print(feedback.text, None, who, keep_progress=True) - elif isinstance(feedback, WorkDone): - if not (options.stop_on_zero and found_zero): - if process_result(feedback, who): - found_zero = True - elif isinstance(feedback, NeedMoreWork): - pass - else: - static_assert_unreachable(feedback) - - # Wait for workers to finish. - for p in processes: - p.join() - - # Wait for network connections to close (currently does not happen). - for conn in net_conns: - conn[0].join() - - if found_zero: - print("\nFound zero score! Exiting.") - return [permuter.best_score for permuter in context.permuters] - - -def main() -> None: - multiprocessing.freeze_support() - sys.setrecursionlimit(10000) - - # Ideally we would do: - # multiprocessing.set_start_method("spawn") - # here, to make multiprocessing behave the same across operating systems. - # However, that means that arguments to Process are passed across using - # pickling, which mysteriously breaks with pycparser... - # (AttributeError: 'CParser' object has no attribute 'p_abstract_declarator_opt') - # So, for now we live with the defaults, which make multiprocessing work on Linux, - # where it uses fork and doesn't pickle arguments, and break on Windows. Sigh. - - parser = argparse.ArgumentParser( - description="Randomly permute C files to better match a target binary." - ) - parser.add_argument( - "directories", - nargs="+", - metavar="directory", - help="Directory containing base.c, target.o and compile.sh. Multiple directories may be given.", - ) - parser.add_argument( - "--show-errors", - dest="show_errors", - action="store_true", - help="Display compiler error/warning messages, and keep .c files for failed compiles.", - ) - parser.add_argument( - "--show-timings", - dest="show_timings", - action="store_true", - help="Display the time taken by permuting vs. compiling vs. scoring.", - ) - parser.add_argument( - "--print-diffs", - dest="print_diffs", - action="store_true", - help="Instead of compiling generated sources, display diffs against a base version.", - ) - parser.add_argument( - "--abort-exceptions", - dest="abort_exceptions", - action="store_true", - help="Stop execution when an internal permuter exception occurs.", - ) - parser.add_argument( - "--better-only", - dest="better_only", - action="store_true", - help="Only report scores better than the base.", - ) - parser.add_argument( - "--best-only", - dest="best_only", - action="store_true", - help="Only report ties or new high scores.", - ) - parser.add_argument( - "--stop-on-zero", - dest="stop_on_zero", - action="store_true", - help="Stop after producing an output with score 0.", - ) - parser.add_argument( - "--quiet", - dest="quiet", - action="store_true", - help="Don't print a status line with the number of iterations.", - ) - parser.add_argument( - "--stack-diffs", - dest="stack_differences", - action="store_true", - help="Take stack differences into account when computing the score.", - ) - parser.add_argument( - "--keep-prob", - dest="keep_prob", - metavar="PROB", - type=restricted_float(0.0, 1.0), - default=DEFAULT_RAND_KEEP_PROB, - help="""Continue randomizing the previous output with the given probability - (float in 0..1, default %(default)s).""", - ) - parser.add_argument("--seed", dest="force_seed", type=str, help=argparse.SUPPRESS) - parser.add_argument( - "-j", - dest="threads", - type=int, - default=0, - help="Number of own threads to use (default: 1 without -J, 0 with -J).", - ) - parser.add_argument( - "-J", - dest="use_network", - action="store_true", - help="Harness extra compute power through cyberspace (permuter@home).", - ) - parser.add_argument( - "--pah-debug", - dest="network_debug", - action="store_true", - help="Enable debug prints for permuter@home.", - ) - parser.add_argument( - "--priority", - dest="network_priority", - metavar="PRIORITY", - type=restricted_float(MIN_PRIO, MAX_PRIO), - default=1.0, - help=f"""Proportion of server resources to use when multiple people - are using -J at the same time. - Defaults to 1.0, meaning resources are split equally, but can be - set to any value within [{MIN_PRIO}, {MAX_PRIO}]. - Each server runs with a priority threshold, which defaults to 0.1, - below which they will not run permuter jobs at all.""", - ) - - args = parser.parse_args() - - threads = args.threads - if not threads and not args.use_network: - threads = 1 - - options = Options( - directories=args.directories, - show_errors=args.show_errors, - show_timings=args.show_timings, - print_diffs=args.print_diffs, - abort_exceptions=args.abort_exceptions, - better_only=args.better_only, - best_only=args.best_only, - quiet=args.quiet, - stack_differences=args.stack_differences, - stop_on_zero=args.stop_on_zero, - keep_prob=args.keep_prob, - force_seed=args.force_seed, - threads=threads, - use_network=args.use_network, - network_debug=args.network_debug, - network_priority=args.network_priority, - ) - - run(options) - - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/src/net/client.py b/tools/decomp-permuter/src/net/client.py deleted file mode 100644 index 1a3442c32..000000000 --- a/tools/decomp-permuter/src/net/client.py +++ /dev/null @@ -1,272 +0,0 @@ -from multiprocessing import Queue -import re -import threading -from typing import Optional, Tuple -import zlib - -from ..candidate import CandidateResult -from ..helpers import exception_to_string -from ..permuter import ( - EvalError, - EvalResult, - Feedback, - FeedbackItem, - Finished, - Message, - NeedMoreWork, - Permuter, - Task, - WorkDone, -) -from ..profiler import Profiler -from .core import ( - PermuterData, - SocketPort, - json_prop, - permuter_data_to_json, -) - - -def _profiler_from_json(obj: dict) -> Profiler: - ret = Profiler() - for key in obj: - assert isinstance(key, str), "json properties are strings" - stat = Profiler.StatType[key] - time = json_prop(obj, key, float) - ret.add_stat(stat, time) - return ret - - -def _result_from_json(obj: dict, source: Optional[str]) -> EvalResult: - if "error" in obj: - return EvalError(exc_str=json_prop(obj, "error", str), seed=None) - - profiler: Optional[Profiler] = None - if "profiler" in obj: - profiler = _profiler_from_json(json_prop(obj, "profiler", dict)) - return CandidateResult( - score=json_prop(obj, "score", int), - hash=json_prop(obj, "hash", str) if "hash" in obj else None, - source=source, - profiler=profiler, - ) - - -def _make_script_portable(source: str) -> str: - """Parse a shell script and get rid of the machine-specific parts that - import.py introduces. The resulting script must be run in an environment - that has the right binaries in its $PATH, and with a current working - directory similar to where import.py found its target's make root.""" - lines = [] - for line in source.split("\n"): - if re.match("cd '?/", line): - # Skip cd's to absolute directory paths. Note that shlex quotes - # its argument with ' if it contains spaces/single quotes. - continue - if re.match("'?/", line): - quote = "'" if line[0] == "'" else "" - ind = line.find(quote + " ") - if ind == -1: - ind = len(line) - else: - ind += len(quote) - lastind = line.rfind("/", 0, ind) - assert lastind != -1 - # Emit a call to "which" as the first part, to ensure the called - # binary still sees an absolute path. qemu-irix requires this, - # for some reason. - line = "$(which " + quote + line[lastind + 1 : ind] + ")" + line[ind:] - lines.append(line) - return "\n".join(lines) - - -def make_portable_permuter(permuter: Permuter) -> PermuterData: - with open(permuter.scorer.target_o, "rb") as f: - target_o_bin = f.read() - - with open(permuter.compiler.compile_cmd, "r") as f2: - compile_script = _make_script_portable(f2.read()) - - return PermuterData( - base_score=permuter.base_score, - base_hash=permuter.base_hash, - fn_name=permuter.fn_name, - filename=permuter.source_file, - keep_prob=permuter.keep_prob, - need_profiler=permuter.need_profiler, - stack_differences=permuter.scorer.stack_differences, - compile_script=compile_script, - source=permuter.source, - target_o_bin=target_o_bin, - ) - - -class Connection: - _port: SocketPort - _permuter_data: PermuterData - _perm_index: int - _task_queue: "Queue[Task]" - _feedback_queue: "Queue[Feedback]" - - def __init__( - self, - port: SocketPort, - permuter_data: PermuterData, - perm_index: int, - task_queue: "Queue[Task]", - feedback_queue: "Queue[Feedback]", - ) -> None: - self._port = port - self._permuter_data = permuter_data - self._perm_index = perm_index - self._task_queue = task_queue - self._feedback_queue = feedback_queue - - def _send_permuter(self) -> None: - data = self._permuter_data - self._port.send_json(permuter_data_to_json(data)) - self._port.send(zlib.compress(data.source.encode("utf-8"))) - self._port.send(zlib.compress(data.target_o_bin)) - - def _feedback(self, feedback: FeedbackItem, server_nick: Optional[str]) -> None: - self._feedback_queue.put((feedback, self._perm_index, server_nick)) - - def _receive_one(self) -> bool: - """Receive a result/progress message and send it on. Returns true if - more work should be requested.""" - msg = self._port.receive_json() - msg_type = json_prop(msg, "type", str) - if msg_type == "need_work": - return True - - server_nick = json_prop(msg, "server", str) - if msg_type == "init_done": - base_hash = json_prop(msg, "hash", str) - my_base_hash = self._permuter_data.base_hash - text = "connected" - if base_hash != my_base_hash: - text += " (note: mismatching hash)" - self._feedback(Message(text), server_nick) - return True - - if msg_type == "init_failed": - text = "failed to initialize: " + json_prop(msg, "reason", str) - self._feedback(Message(text), server_nick) - return False - - if msg_type == "disconnect": - self._feedback(Message("disconnected"), server_nick) - return False - - if msg_type == "result": - source: Optional[str] = None - if msg.get("has_source") == True: - # Source is sent separately, compressed, since it can be - # large (hundreds of kilobytes is not uncommon). - compressed_source = self._port.receive() - try: - source = zlib.decompress(compressed_source).decode("utf-8") - except Exception as e: - text = "failed to decompress: " + exception_to_string(e) - self._feedback(Message(text), server_nick) - return True - try: - result = _result_from_json(msg, source) - self._feedback(WorkDone(self._perm_index, result), server_nick) - except Exception as e: - text = "failed to parse result message: " + exception_to_string(e) - self._feedback(Message(text), server_nick) - return True - - raise ValueError(f"Invalid message type {msg_type}") - - def run(self) -> None: - finish_reason: Optional[str] = None - try: - self._send_permuter() - self._port.receive_json() - - finished = False - - # Main loop: send messages from the queue on to the server, and - # vice versa. Currently we are being lazy and alternate between - # sending and receiving; this is nicely simple and keeps us on a - # single thread, however it could cause deadlocks if the server - # receiver stops reading because we aren't reading fast enough. - while True: - if not self._receive_one(): - continue - self._feedback(NeedMoreWork(), None) - - # Read a task and send it on, unless there are no more tasks. - if not finished: - task = self._task_queue.get() - if isinstance(task, Finished): - # We don't have a way of indicating to the server that - # all is done: the server currently doesn't track - # outstanding work so it doesn't know when to close - # the connection. (Even with this fixed we'll have the - # problem that servers may disconnect, losing work, so - # the task never truly finishes. But it might work well - # enough in practice.) - finished = True - else: - work = { - "type": "work", - "work": { - "seed": task[1], - }, - } - self._port.send_json(work) - - except EOFError: - finish_reason = "disconnected from permuter@home" - - except Exception as e: - errmsg = exception_to_string(e) - finish_reason = f"permuter@home error: {errmsg}" - - finally: - self._feedback(Finished(reason=finish_reason), None) - self._port.shutdown() - self._port.close() - - -def start_client( - port: SocketPort, - permuter: Permuter, - perm_index: int, - feedback_queue: "Queue[Feedback]", - priority: float, -) -> "Tuple[threading.Thread, Queue[Task], Tuple[int, int, float]]": - port.send_json( - { - "method": "connect_client", - "priority": priority, - } - ) - obj = port.receive_json() - if "error" in obj: - err = json_prop(obj, "error", str) - # TODO use another exception type - raise Exception(f"Failed to connect: {err}") - num_servers = json_prop(obj, "servers", int) - num_clients = json_prop(obj, "clients", int) - num_cores = json_prop(obj, "cores", float) - permuter_data = make_portable_permuter(permuter) - task_queue: "Queue[Task]" = Queue() - - conn = Connection( - port, - permuter_data, - perm_index, - task_queue, - feedback_queue, - ) - - thread = threading.Thread(target=conn.run, daemon=True) - thread.start() - - stats = (num_clients, num_servers, num_cores) - - return thread, task_queue, stats diff --git a/tools/decomp-permuter/src/net/cmd/base.py b/tools/decomp-permuter/src/net/cmd/base.py deleted file mode 100644 index 492044350..000000000 --- a/tools/decomp-permuter/src/net/cmd/base.py +++ /dev/null @@ -1,17 +0,0 @@ -import abc -from argparse import ArgumentParser, Namespace - - -class Command(abc.ABC): - command: str - help: str - - @staticmethod - @abc.abstractmethod - def add_arguments(parser: ArgumentParser) -> None: - ... - - @staticmethod - @abc.abstractmethod - def run(args: Namespace) -> None: - ... diff --git a/tools/decomp-permuter/src/net/cmd/icons/notok.ico b/tools/decomp-permuter/src/net/cmd/icons/notok.ico deleted file mode 100644 index 2825d0d9c..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/icons/notok.ico and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/icons/ok.ico b/tools/decomp-permuter/src/net/cmd/icons/ok.ico deleted file mode 100644 index bc0b0534b..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/icons/ok.ico and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/icons/okthink.ico b/tools/decomp-permuter/src/net/cmd/icons/okthink.ico deleted file mode 100644 index d3a8eacf8..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/icons/okthink.ico and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/main.py b/tools/decomp-permuter/src/net/cmd/main.py deleted file mode 100644 index 9d1e4db1c..000000000 --- a/tools/decomp-permuter/src/net/cmd/main.py +++ /dev/null @@ -1,70 +0,0 @@ -from argparse import ArgumentParser, RawDescriptionHelpFormatter -import sys - -from ..core import ServerError, enable_debug_mode -from .run_server import RunServerCommand -from .setup import SetupCommand -from .ping import PingCommand -from .vouch import VouchCommand - - -def main() -> None: - try: - # We currently sometimes log stuff to stdout, so it's preferable if it's - # line-buffered even when redirected to a non-tty (e.g. when running a - # permuter server as a systemd service). This is supported by Python 3.7 - # and up. - sys.stdout.reconfigure(line_buffering=True) # type: ignore - except Exception: - pass - - parser = ArgumentParser( - description="permuter@home - run the permuter across the Internet!\n\n" - "To use p@h as a client, just pass -J when running the permuter. " - "This script is\nonly necessary for configuration or when running a server.", - formatter_class=RawDescriptionHelpFormatter, - ) - - commands = [ - PingCommand, - RunServerCommand, - SetupCommand, - VouchCommand, - ] - - parser.add_argument( - "--debug", - dest="debug", - action="store_true", - help="Enable debug logging.", - ) - - subparsers = parser.add_subparsers(metavar="") - for command in commands: - subparser = subparsers.add_parser( - command.command, - help=command.help, - description=command.help, - ) - command.add_arguments(subparser) - subparser.set_defaults(subcommand_handler=command.run) - - args = parser.parse_args() - if args.debug: - enable_debug_mode() - - if "subcommand_handler" in args: - try: - args.subcommand_handler(args) - except EOFError as e: - print("Network error:", e) - sys.exit(1) - except ServerError as e: - print("Error:", e.message) - sys.exit(1) - else: - parser.print_help() - - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/src/net/cmd/ping.py b/tools/decomp-permuter/src/net/cmd/ping.py deleted file mode 100644 index e49f1e682..000000000 --- a/tools/decomp-permuter/src/net/cmd/ping.py +++ /dev/null @@ -1,32 +0,0 @@ -from argparse import ArgumentParser, Namespace -import time - -from ...helpers import plural -from ..core import connect, json_prop -from .base import Command - - -class PingCommand(Command): - command = "ping" - help = "Check server connectivity." - - @staticmethod - def add_arguments(parser: ArgumentParser) -> None: - pass - - @staticmethod - def run(args: Namespace) -> None: - run_ping() - - -def run_ping() -> None: - port = connect() - t0 = time.time() - port.send_json({"method": "ping"}) - msg = port.receive_json() - rtt = (time.time() - t0) * 1000 - print(f"Connected successfully! Round-trip time: {rtt:.1f} ms") - servers_str = plural(json_prop(msg, "servers", int), "server") - clients_str = plural(json_prop(msg, "clients", int), "client") - cores_str = plural(int(json_prop(msg, "cores", float)), "core") - print(f"{servers_str} online ({cores_str}, {clients_str})") diff --git a/tools/decomp-permuter/src/net/cmd/run_server.py b/tools/decomp-permuter/src/net/cmd/run_server.py deleted file mode 100644 index 429ddb1b6..000000000 --- a/tools/decomp-permuter/src/net/cmd/run_server.py +++ /dev/null @@ -1,616 +0,0 @@ -from argparse import ArgumentParser, Namespace -import base64 -from dataclasses import dataclass -from enum import Enum -from functools import partial -import json -import os -import platform -import queue -import random -import shutil -from subprocess import Popen, PIPE -import sys -import time -import threading -import traceback -from typing import Any, Callable, Dict, List, Optional, TYPE_CHECKING - -from ...helpers import static_assert_unreachable -from ..core import CancelToken, ServerError, read_config -from ..server import ( - Client, - Config, - IoActivity, - IoConnect, - IoDisconnect, - IoImmediateDisconnect, - IoReconnect, - IoServerFailed, - IoShutdown, - IoUserRemovePermuter, - IoWorkDone, - PermuterHandle, - Server, - ServerOptions, -) -from .base import Command -from .util import ask - - -class RunServerCommand(Command): - command = "run-server" - help = """Run a permuter server, allowing anyone with access to the central - server to run sandboxed permuter jobs on your machine. Requires docker.""" - - @staticmethod - def add_arguments(parser: ArgumentParser) -> None: - parser.add_argument( - "--cores", - dest="num_cores", - metavar="CORES", - type=float, - required=True, - help="Number of cores to use (float).", - ) - parser.add_argument( - "--memory", - dest="max_memory_gb", - metavar="MEMORY_GB", - type=float, - required=True, - help="""Restrict the sandboxed process to the given amount of memory in - gigabytes (float). If this limit is hit, the permuter will crash - horribly, but at least your system won't lock up.""", - ) - parser.add_argument( - "--systray", - dest="systray", - action="store_true", - help="""Make the server controllable through the system tray.""", - ) - parser.add_argument( - "--min-priority", - dest="min_priority", - metavar="PRIORITY", - type=float, - default=0.1, - help="""Only accept jobs from clients who pass --priority with a number - higher or equal to this value. (default: %(default)s)""", - ) - - @staticmethod - def run(args: Namespace) -> None: - options = ServerOptions( - num_cores=args.num_cores, - max_memory_gb=args.max_memory_gb, - min_priority=args.min_priority, - ) - - server_main(options, args.systray) - - -class SystrayState: - def server_reconnecting(self) -> None: - pass - - def server_connected(self) -> None: - pass - - def server_failed(self, graceful: bool, message: Optional[str] = None) -> None: - pass - - def connect(self, handle: PermuterHandle, nickname: str, fn_name: str) -> None: - pass - - def disconnect(self, handle: PermuterHandle) -> None: - pass - - def work_done(self, handle: PermuterHandle, is_improvement: bool) -> None: - pass - - def stop(self) -> None: - pass - - -@dataclass -class Permuter: - nickname: str - fn_name: str - iterations: int = 0 - improvements: int = 0 - last_systray_update: float = 0.0 - slot: "Optional[ClientSlot]" = None - - -@dataclass -class ClientSlot: - menu_id: int - iterations_id: int - improvements_id: int - stop_id: int - permuter: Optional[PermuterHandle] = None - - -class SystrayStatus(Enum): - CONNECTING = 0 - CONNECTED = 1 - FAILED = 2 - RECONNECTING = 3 - - -class RealSystrayState(SystrayState): - _CLIENT_SLOTS = 10 - _UPDATE_INTERVAL = 2.0 - _MENU_TOOLTIP = "permuter@home" - _permuters: Dict[PermuterHandle, Permuter] - _onclick: Dict[int, Callable[[], None]] - _client_slots: List[ClientSlot] - - def __init__( - self, - config: Config, - io_queue: "queue.Queue[IoActivity]", - ) -> None: - self._io_queue = io_queue - self._permuters = {} - self._onclick = {} - self._status = SystrayStatus.CONNECTING - self._fail_message: Optional[str] = None - - def load_icon(fname: str) -> str: - path = os.path.join(os.path.dirname(__file__), "icons", fname) - with open(path, "rb") as f: - data = f.read() - return base64.b64encode(data).decode("ascii") - - self._icons = { - "working": load_icon("okthink.ico"), - "passive": load_icon("ok.ico"), - "fail": load_icon("notok.ico"), - } - self._current_icon = "working" - - next_id = 100 - - def add_item( - menu: List[dict], - title: str, - onclick: Optional[Callable[[], None]] = None, - *, - submenu: Optional[List[dict]] = None, - hidden: bool = False, - ) -> int: - nonlocal next_id - next_id += 1 - obj = { - "title": title, - "enabled": onclick is not None or submenu is not None, - "hidden": hidden, - "__id": next_id, - } - if onclick is not None: - self._onclick[next_id] = onclick - if submenu is not None: - obj["items"] = submenu - menu.append(obj) - return next_id - - menu: List[dict] = [] - self._status_id = add_item(menu, "Connecting...") - self._client_slots = [] - for i in range(self._CLIENT_SLOTS): - submenu: List[dict] = [] - remove_cb = partial(self._remove_permuter, i) - self._client_slots.append( - ClientSlot( - iterations_id=add_item(submenu, ""), - improvements_id=add_item(submenu, ""), - stop_id=add_item(submenu, "Stop", remove_cb), - menu_id=add_item(menu, "", submenu=submenu, hidden=True), - ) - ) - self._more_id = add_item(menu, "", hidden=True) - add_item(menu, "Quit", self._quit) - - try: - path = self._setup_helper() - self._proc = Popen( - [path], - stdout=PIPE, - stdin=PIPE, - universal_newlines=True, - ) - assert self._proc.stdout is not None - self._proc_stdout = self._proc.stdout - assert self._proc.stdin is not None - self._proc_stdin = self._proc.stdin - - self._send( - { - "icon": self._icons[self._current_icon], - "tooltip": self._MENU_TOOLTIP, - "items": menu, - } - ) - - resp_str = self._proc_stdout.readline() - assert resp_str - resp = json.loads(resp_str) - assert isinstance(resp, dict) - assert resp.get("type") == "ready" - except Exception: - print("Failed to initialize systray!") - print() - print("See src/net/cmd/systray/README.md for details on how to set it up.") - traceback.print_exc() - sys.exit(1) - - self._read_thread = threading.Thread(target=self._read_loop, daemon=True) - self._read_thread.start() - - @staticmethod - def _setup_helper() -> str: - fname = "permuter-systray" - suffix = "" - osname = sys.platform.replace("darwin", "macos") - arch = platform.machine().replace("AMD64", "x86_64") - if ( - osname in ("win32", "msys", "cygwin") - or "microsoft" in platform.uname().release.lower() - ): - osname = "win" - suffix = ".exe" - - dir = os.path.join(os.path.dirname(__file__), "systray") - target_binary = os.path.join(dir, fname + suffix) - if os.path.exists(target_binary): - return target_binary - - prebuilt_file = f"{fname}-{osname}-{arch}{suffix}" - prebuilt_file = os.path.join(dir, "prebuilt", prebuilt_file) - - print("An external helper binary is required for systray support.") - print( - "To build it from source (requires Go), see src/net/cmd/systray/README.md." - ) - - if os.path.exists(prebuilt_file): - print("Alternatively, a pre-built binary can be used.") - if ask("Use pre-built binary?", default=False): - shutil.copy(prebuilt_file, target_binary) - os.chmod(target_binary, 0o755) - return target_binary - - print("Aborting.") - sys.exit(1) - - def _send(self, msg: dict) -> None: - data = json.dumps(msg) - self._proc_stdin.write(data + "\n") - self._proc_stdin.flush() - - def _update_item( - self, id: int, title: str, *, hidden: bool = False, enabled: bool = False - ) -> None: - self._send( - { - "type": "update-item", - "item": { - "title": title, - "enabled": enabled, - "hidden": hidden, - "__id": id, - }, - "seq_id": -1, - } - ) - - def _remove_permuter(self, slot_index: int) -> None: - slot = self._client_slots[slot_index] - if not slot.permuter: - return - handle = slot.permuter - self._io_queue.put((None, (handle, IoUserRemovePermuter()))) - - def _quit(self) -> None: - self._io_queue.put((None, IoShutdown())) - - def _read_loop(self) -> None: - while True: - resp_str = self._proc_stdout.readline() - if not resp_str: - break - try: - resp = json.loads(resp_str) - except Exception: - raise Exception(f"Failed to parse systray JSON: {resp_str}") from None - if resp["type"] == "clicked": - id = resp["__id"] - if id in self._onclick: - self._onclick[id]() - - def _permuter_slot(self, perm: Permuter) -> Optional[ClientSlot]: - for slot in self._client_slots: - if slot.permuter is not None and self._permuters[slot.permuter] is perm: - return slot - return None - - def _update_permuter(self, perm: Permuter, slot: ClientSlot) -> None: - self._update_item( - slot.iterations_id, - f"Iterations: {perm.iterations}", - ) - self._update_item( - slot.improvements_id, - f"Improvements found: {perm.improvements}", - ) - - def _update_status(self) -> None: - if self._status == SystrayStatus.CONNECTING: - status = "Reconnecting..." - icon = "working" - elif self._status == SystrayStatus.RECONNECTING: - status = "Disconnected, will reconnect..." - icon = "fail" - elif self._status == SystrayStatus.CONNECTED: - if self._permuters: - status = "Currently permuting:" - icon = "working" - else: - status = "Not running" - icon = "passive" - elif self._status == SystrayStatus.FAILED: - if self._fail_message: - status = f"Error: {self._fail_message}" - else: - status = "Error occurred" - icon = "fail" - else: - assert False, f"bad status {self._status}" - - self._update_item(self._status_id, status) - if self._current_icon != icon: - self._current_icon = icon - self._send( - { - "type": "update-menu", - "menu": { - "tooltip": self._MENU_TOOLTIP, - "icon": self._icons[icon], - }, - } - ) - - def _fill_slots(self) -> None: - has_more = False - while True: - key = next((k for k, p in self._permuters.items() if p.slot is None), None) - if key is None: - break - chosen_slot: Optional[ClientSlot] = None - for i in range(self._CLIENT_SLOTS - 1, -1, -1): - slot = self._client_slots[i] - if slot.permuter is None: - chosen_slot = slot - elif chosen_slot is not None: - break - if chosen_slot is None: - has_more = True - break - perm = self._permuters[key] - perm.slot = chosen_slot - chosen_slot.permuter = key - self._update_permuter(perm, chosen_slot) - self._update_item( - chosen_slot.menu_id, f"{perm.fn_name} ({perm.nickname})", enabled=True - ) - self._update_item(self._more_id, "More...", hidden=not has_more) - - def _hide_slot(self, slot: ClientSlot) -> None: - if slot.permuter is not None: - self._update_item(slot.menu_id, "", hidden=True) - slot.permuter = None - - def server_reconnecting(self) -> None: - self._status = SystrayStatus.CONNECTING - self._update_status() - - def server_connected(self) -> None: - self._status = SystrayStatus.CONNECTED - self._update_status() - - def server_failed(self, graceful: bool, message: Optional[str] = None) -> None: - self._status = SystrayStatus.RECONNECTING if graceful else SystrayStatus.FAILED - self._fail_message = message - self._permuters = {} - self._update_status() - for slot in self._client_slots: - self._hide_slot(slot) - self._fill_slots() - - def connect(self, handle: PermuterHandle, nickname: str, fn_name: str) -> None: - perm = Permuter(nickname, fn_name) - self._permuters[handle] = perm - self._fill_slots() - self._update_status() - - def disconnect(self, handle: PermuterHandle) -> None: - slot = self._permuters[handle].slot - del self._permuters[handle] - self._update_status() - if slot: - self._hide_slot(slot) - self._fill_slots() - - def work_done(self, handle: PermuterHandle, is_improvement: bool) -> None: - perm = self._permuters[handle] - perm.iterations += 1 - if is_improvement: - perm.improvements += 1 - if perm.slot and time.time() > perm.last_systray_update + self._UPDATE_INTERVAL: - perm.last_systray_update = time.time() - self._update_permuter(perm, perm.slot) - - def stop(self) -> None: - try: - self._send({"type": "exit"}) - except BrokenPipeError: - # The systray process may have been killed by Ctrl+C. - pass - self._proc.wait() - self._read_thread.join() - - -class Reconnector: - _RESET_BACKOFF_AFTER_UPTIME: float = 60.0 - _RANDOM_ADDEND_MAX: float = 60.0 - _BACKOFF_MULTIPLIER: float = 2.0 - _INITIAL_DELAY: float = 5.0 - - _io_queue: "queue.Queue[IoActivity]" - _reconnect_token: CancelToken - _reconnect_delay: float - _reconnect_timer: Optional[threading.Timer] - _start_time: float - _stop_time: float - - def __init__(self, io_queue: "queue.Queue[IoActivity]") -> None: - self._io_queue = io_queue - self._reconnect_token = CancelToken() - self._reconnect_delay = self._INITIAL_DELAY - self._reconnect_timer = None - self._start_time = self._stop_time = time.time() - - def mark_start(self) -> None: - self._start_time = time.time() - - def mark_stop(self) -> None: - self._stop_time = time.time() - - def stop(self) -> None: - self._reconnect_token.cancelled = True - if self._reconnect_timer is not None: - self._reconnect_timer.cancel() - self._reconnect_timer.join() - self._reconnect_timer = None - - def reconnect_eventually(self) -> int: - if self._stop_time - self._start_time > self._RESET_BACKOFF_AFTER_UPTIME: - delay = self._reconnect_delay = self._INITIAL_DELAY - else: - delay = self._reconnect_delay - self._reconnect_delay = ( - self._reconnect_delay * self._BACKOFF_MULTIPLIER - + random.uniform(1.0, self._RANDOM_ADDEND_MAX) - ) - token = CancelToken() - self._reconnect_token = token - self._reconnect_timer = threading.Timer( - delay, lambda: self._io_queue.put((token, IoReconnect())) - ) - self._reconnect_timer.daemon = True - self._reconnect_timer.start() - return int(delay) - - -def main_loop( - io_queue: "queue.Queue[IoActivity]", - server: Server, - systray: SystrayState, -) -> None: - reconnector = Reconnector(io_queue) - handle_clients: Dict[PermuterHandle, Client] = {} - while True: - token, activity = io_queue.get() - if token and token.cancelled: - continue - - if not isinstance(activity, tuple): - if isinstance(activity, IoShutdown): - break - - elif isinstance(activity, IoReconnect): - print("reconnecting...") - try: - systray.server_reconnecting() - reconnector.mark_start() - server.start() - systray.server_connected() - except EOFError: - delay = reconnector.reconnect_eventually() - print(f"failed again, reconnecting in {delay} seconds...") - systray.server_failed(True) - except ServerError as e: - print("failed!", e.message) - systray.server_failed(False, e.message) - except Exception: - print("failed!") - traceback.print_exc() - systray.server_failed(False) - - elif isinstance(activity, IoServerFailed): - if activity.message: - print("Server error:", activity.message) - print("disconnected from permuter@home") - server.stop() - reconnector.mark_stop() - systray.server_failed(activity.graceful, activity.message) - - if activity.graceful: - delay = reconnector.reconnect_eventually() - print(f"will reconnect in {delay} seconds...") - - else: - static_assert_unreachable(activity) - - else: - handle, msg = activity - - if isinstance(msg, IoConnect): - client = msg.client - handle_clients[handle] = client - systray.connect(handle, client.nickname, msg.fn_name) - print(f"[{client.nickname}] connected ({msg.fn_name})") - - elif isinstance(msg, IoDisconnect): - systray.disconnect(handle) - nickname = handle_clients[handle].nickname - del handle_clients[handle] - print(f"[{nickname}] {msg.reason}") - - elif isinstance(msg, IoImmediateDisconnect): - print(f"[{msg.client.nickname}] {msg.reason}") - - elif isinstance(msg, IoWorkDone): - # TODO: statistics - systray.work_done(handle, msg.is_improvement) - - elif isinstance(msg, IoUserRemovePermuter): - server.remove_permuter(handle) - - else: - static_assert_unreachable(msg) - - -def server_main(options: ServerOptions, use_systray: bool) -> None: - io_queue: "queue.Queue[IoActivity]" = queue.Queue() - config = read_config() - - systray: SystrayState - if use_systray: - systray = RealSystrayState(config, io_queue) - else: - systray = SystrayState() - - try: - server = Server(options, config, io_queue) - server.start() - - try: - systray.server_connected() - main_loop(io_queue, server, systray) - finally: - server.stop() - finally: - systray.stop() diff --git a/tools/decomp-permuter/src/net/cmd/setup.py b/tools/decomp-permuter/src/net/cmd/setup.py deleted file mode 100644 index 8238ded2b..000000000 --- a/tools/decomp-permuter/src/net/cmd/setup.py +++ /dev/null @@ -1,86 +0,0 @@ -from argparse import ArgumentParser, Namespace -import base64 -import os -import random -import string -import sys -from typing import Optional - -from nacl.public import SealedBox -from nacl.signing import SigningKey, VerifyKey - -from .base import Command -from ..core import connect, read_config, sign_with_magic, write_config -from .util import ask - - -class SetupCommand(Command): - command = "setup" - help = """Set up permuter@home. This will require someone else to grant you - access to the central server.""" - - @staticmethod - def add_arguments(parser: ArgumentParser) -> None: - pass - - @staticmethod - def run(args: Namespace) -> None: - _run_initial_setup() - - -def _random_name() -> str: - return "".join(random.choice(string.ascii_lowercase) for _ in range(5)) - - -def _run_initial_setup() -> None: - config = read_config() - signing_key: Optional[SigningKey] = config.signing_key - if not signing_key or not ask("Keep previous secret key", default=True): - signing_key = SigningKey.generate() - config.signing_key = signing_key - write_config(config) - verify_key = signing_key.verify_key - - nickname: Optional[str] = config.initial_setup_nickname - if not nickname or not ask(f"Keep previous nickname [{nickname}]", default=True): - default_nickname = os.environ.get("USER") or _random_name() - nickname = ( - input(f"Nickname [default: {default_nickname}]: ") or default_nickname - ) - config.initial_setup_nickname = nickname - write_config(config) - - signed_nickname = sign_with_magic(b"NAME", signing_key, nickname.encode("utf-8")) - - vouch_data = verify_key.encode() + signed_nickname - vouch_text = base64.b64encode(vouch_data).decode("utf-8") - print("Ask someone to run the following command:") - print(f"./pah.py vouch {vouch_text}") - print() - print("They should give you a token back in return. Paste that here:") - inp = input().strip() - - try: - token = base64.b64decode(inp.encode("utf-8")) - data = SealedBox(signing_key.to_curve25519_private_key()).decrypt(token) - config.server_address = data[32:].decode("utf-8") - config.server_verify_key = VerifyKey(data[:32]) - config.initial_setup_nickname = None - except Exception: - print("Invalid token!") - sys.exit(1) - - print(f"Server: {config.server_address}") - print("Testing connection...") - - port = connect(config) - port.send_json({"method": "ping"}) - port.receive_json() - - try: - write_config(config) - except Exception as e: - print("Failed to write config:", e) - sys.exit(1) - - print("permuter@home successfully set up!") diff --git a/tools/decomp-permuter/src/net/cmd/systray/.gitignore b/tools/decomp-permuter/src/net/cmd/systray/.gitignore deleted file mode 100644 index 49f8d190c..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -permuter-systray -permuter-systray.exe diff --git a/tools/decomp-permuter/src/net/cmd/systray/LICENSE b/tools/decomp-permuter/src/net/cmd/systray/LICENSE deleted file mode 100644 index dc9823bd1..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2017 Zack Young - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/tools/decomp-permuter/src/net/cmd/systray/README.md b/tools/decomp-permuter/src/net/cmd/systray/README.md deleted file mode 100644 index 5dee2f87e..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# systray - -This directory contains a Go application that shows a system tray, which the Python code interacts with. - -It is a fork of https://github.com/felixhao28/systray-portable. - -To build it: - -- install Go -- if on Linux, install dependencies: `libgtk-3-dev`, `libappindicator3-dev` -- run `go build` - -If on Windows, this needs to be done *outside* of WSL. diff --git a/tools/decomp-permuter/src/net/cmd/systray/go.mod b/tools/decomp-permuter/src/net/cmd/systray/go.mod deleted file mode 100644 index 4abd8814c..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module permuter-systray - -go 1.15 - -require github.com/getlantern/systray v1.1.0 - -replace github.com/getlantern/systray v1.1.0 => github.com/simonlindholm/systray v1.1.1-0.20210502122945-b7c77212cd56 diff --git a/tools/decomp-permuter/src/net/cmd/systray/go.sum b/tools/decomp-permuter/src/net/cmd/systray/go.sum deleted file mode 100644 index bd6cf2541..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/go.sum +++ /dev/null @@ -1,4 +0,0 @@ -github.com/simonlindholm/systray v1.1.1-0.20210502122945-b7c77212cd56 h1:UZcM1HdV25CQhhJD340jxRLRGl0V11V0wIoUDKTOZMI= -github.com/simonlindholm/systray v1.1.1-0.20210502122945-b7c77212cd56/go.mod h1:N5dpnnWiJhCxh+gXuNgDS2p5MjgcVR/TGwWuaDc4gLk= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9 h1:YTzHMGlqJu67/uEo1lBv0n3wBXhXNeUbB1XfN2vmTm0= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-linux-x86_64 b/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-linux-x86_64 deleted file mode 100755 index d23a6990d..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-linux-x86_64 and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-macos-x86_64 b/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-macos-x86_64 deleted file mode 100755 index 4eee7ff13..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-macos-x86_64 and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-win-x86_64.exe b/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-win-x86_64.exe deleted file mode 100755 index 8de9fc216..000000000 Binary files a/tools/decomp-permuter/src/net/cmd/systray/prebuilt/permuter-systray-win-x86_64.exe and /dev/null differ diff --git a/tools/decomp-permuter/src/net/cmd/systray/tray.go b/tools/decomp-permuter/src/net/cmd/systray/tray.go deleted file mode 100644 index 67c387844..000000000 --- a/tools/decomp-permuter/src/net/cmd/systray/tray.go +++ /dev/null @@ -1,287 +0,0 @@ -package main - -import ( - "bufio" - "encoding/base64" - "encoding/json" - "fmt" - "os" - "os/signal" - "reflect" - "strings" - "syscall" - - "github.com/getlantern/systray" -) - -func main() { - systray.Run(onReady, onExit) -} - -func onExit() { - os.Exit(0) -} - -// Item represents an item in the menu -type Item struct { - Icon string `json:"icon"` - Title string `json:"title"` - Tooltip string `json:"tooltip"` - Enabled bool `json:"enabled"` - Checked bool `json:"checked"` - Hidden bool `json:"hidden"` - Items []Item `json:"items"` - InternalID int `json:"__id"` -} - -// Menu has an icon, title and list of items -type Menu struct { - Icon string `json:"icon"` - Title string `json:"title"` - Tooltip string `json:"tooltip"` - Items []Item `json:"items"` -} - -// Action for an item?.. -type Action struct { - Type string `json:"type"` - Item Item `json:"item"` - Menu Menu `json:"menu"` -} - -// ClickEvent for an click event -type ClickEvent struct { - Type string `json:"type"` - InternalID int `json:"__id"` -} - -func readJSON(reader *bufio.Reader, v interface{}) error { - input, err := reader.ReadString('\n') - if err != nil { - return err - } - if len(input) < 1 { - return fmt.Errorf("Empty line") - } - - lineReader := strings.NewReader(input[0 : len(input)-1]) - if err := json.NewDecoder(lineReader).Decode(v); err != nil { - return err - } - - return nil -} - -func addMenuItem(items *[]*systray.MenuItem, seqID2InternalID *[]int, internalID2SeqID *map[int]int, item *Item, parent *systray.MenuItem) { - if item.Title == "" { - systray.AddSeparator() - *items = append(*items, nil) - } else { - var menuItem *systray.MenuItem - if parent == nil { - menuItem = systray.AddMenuItem(item.Title, item.Tooltip) - } else { - menuItem = parent.AddSubMenuItem(item.Title, item.Tooltip) - } - if item.Checked { - menuItem.Check() - } else { - menuItem.Uncheck() - } - if item.Enabled { - menuItem.Enable() - } else { - menuItem.Disable() - } - if len(item.Icon) > 0 { - icon, err := base64.StdEncoding.DecodeString(item.Icon) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } else { - menuItem.SetIcon(icon) - } - } - for i := 0; i < len(item.Items); i++ { - subitem := item.Items[i] - addMenuItem(items, seqID2InternalID, internalID2SeqID, &subitem, menuItem) - } - if item.Hidden { - menuItem.Hide() - } - *items = append(*items, menuItem) - } - seqID := len(*items) - 1 - (*internalID2SeqID)[item.InternalID] = seqID - *seqID2InternalID = append(*seqID2InternalID, item.InternalID) -} - -func onReady() { - signalChannel := make(chan os.Signal, 2) - signal.Notify(signalChannel, os.Interrupt, syscall.SIGTERM) - go func() { - for sig := range signalChannel { - switch sig { - case os.Interrupt, syscall.SIGTERM: - // handle SIGINT, SIGTERM - fmt.Fprintln(os.Stderr, "Quit") - systray.Quit() - default: - fmt.Fprintln(os.Stderr, "Unhandled signal:", sig) - } - } - }() - - items := make([]*systray.MenuItem, 0) - seqID2InternalID := make([]int, 0) - internalID2SeqID := make(map[int]int) - fmt.Println(`{"type": "ready"}`) - reader := bufio.NewReader(os.Stdin) - - var menu Menu - if err := readJSON(reader, &menu); err != nil { - fmt.Fprintln(os.Stderr, err) - systray.Quit() - return - } - - icon, err := base64.StdEncoding.DecodeString(menu.Icon) - if err != nil { - fmt.Fprintln(os.Stderr, err) - systray.Quit() - return - } - - systray.SetIcon(icon) - systray.SetTitle(menu.Title) - systray.SetTooltip(menu.Tooltip) - - updateItem := func(action Action) { - item := action.Item - seqID := internalID2SeqID[action.Item.InternalID] - menuItem := items[seqID] - if menuItem == nil { - return - } - if item.Hidden { - menuItem.Hide() - } else { - if item.Checked { - menuItem.Check() - } else { - menuItem.Uncheck() - } - if item.Enabled { - menuItem.Enable() - } else { - menuItem.Disable() - } - menuItem.SetTitle(item.Title) - menuItem.SetTooltip(item.Tooltip) - if len(item.Icon) > 0 { - icon, err := base64.StdEncoding.DecodeString(item.Icon) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } else { - menuItem.SetIcon(icon) - } - } - menuItem.Show() - for _, child := range item.Items { - seqID = internalID2SeqID[child.InternalID] - items[seqID].Show() - } - } - } - - updateMenu := func(action Action) { - m := action.Menu - if menu.Title != m.Title { - menu.Title = m.Title - systray.SetTitle(menu.Title) - } - if menu.Icon != m.Icon && m.Icon != "" { - menu.Icon = m.Icon - icon, err := base64.StdEncoding.DecodeString(menu.Icon) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } else { - systray.SetIcon(icon) - } - } - if menu.Tooltip != m.Tooltip { - menu.Tooltip = m.Tooltip - systray.SetTooltip(menu.Tooltip) - } - } - - update := func(action Action) { - switch action.Type { - case "update-item": - updateItem(action) - case "update-menu": - updateMenu(action) - case "update-item-and-menu": - updateItem(action) - updateMenu(action) - case "exit": - systray.Quit() - } - } - - for i := 0; i < len(menu.Items); i++ { - item := menu.Items[i] - addMenuItem(&items, &seqID2InternalID, &internalID2SeqID, &item, nil) - } - - go func(reader *bufio.Reader) { - for { - var action Action - if err := readJSON(reader, &action); err != nil { - fmt.Fprintln(os.Stderr, err) - systray.Quit() - break - } - update(action) - } - }(reader) - - stdoutEnc := json.NewEncoder(os.Stdout) - for { - itemsCnt := 0 - for _, ch := range items { - if ch != nil { - itemsCnt++ - } - } - cases := make([]reflect.SelectCase, itemsCnt) - caseCnt2SeqID := make([]int, len(items)) - itemsCnt = 0 - for i, ch := range items { - if ch == nil { - continue - } - cases[itemsCnt] = reflect.SelectCase{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch.ClickedCh)} - caseCnt2SeqID[itemsCnt] = i - itemsCnt++ - } - - remaining := len(cases) - for remaining > 0 { - chosen, _, ok := reflect.Select(cases) - if !ok { - // The chosen channel has been closed, so zero out the channel to disable the case - cases[chosen].Chan = reflect.ValueOf(nil) - remaining-- - continue - } - seqID := caseCnt2SeqID[chosen] - err := stdoutEnc.Encode(ClickEvent{ - Type: "clicked", - InternalID: seqID2InternalID[seqID], - }) - if err != nil { - fmt.Fprintln(os.Stderr, err) - } - } - } -} diff --git a/tools/decomp-permuter/src/net/cmd/util.py b/tools/decomp-permuter/src/net/cmd/util.py deleted file mode 100644 index dfe9b47e4..000000000 --- a/tools/decomp-permuter/src/net/cmd/util.py +++ /dev/null @@ -1,15 +0,0 @@ -import sys - - -def ask(msg: str, *, default: bool) -> bool: - if default: - msg += " (Y/n)? " - else: - msg += " (y/N)? " - res = input(msg).strip().lower() - if not res: - return default - if res in ["y", "yes", "n", "no"]: - return res[0] == "y" - print("Bad response!") - sys.exit(1) diff --git a/tools/decomp-permuter/src/net/cmd/vouch.py b/tools/decomp-permuter/src/net/cmd/vouch.py deleted file mode 100644 index 82b19a8b0..000000000 --- a/tools/decomp-permuter/src/net/cmd/vouch.py +++ /dev/null @@ -1,73 +0,0 @@ -from argparse import ArgumentParser, Namespace -import base64 -import sys - -from nacl.encoding import HexEncoder -from nacl.public import SealedBox -from nacl.signing import VerifyKey - -from ..core import connect, read_config, verify_with_magic -from .base import Command -from .util import ask - - -class VouchCommand(Command): - command = "vouch" - help = "Give someone access to the central server." - - @staticmethod - def add_arguments(parser: ArgumentParser) -> None: - parser.add_argument( - "magic", - help="Opaque hex string generated by 'setup'.", - ) - - @staticmethod - def run(args: Namespace) -> None: - run_vouch(args.magic) - - -def run_vouch(magic: str) -> None: - try: - vouch_data = base64.b64decode(magic.encode("utf-8")) - verify_key = VerifyKey(vouch_data[:32]) - signed_nickname = vouch_data[32:] - msg = verify_with_magic(b"NAME", verify_key, signed_nickname) - nickname = msg.decode("utf-8") - except Exception: - print("Could not parse data!") - sys.exit(1) - - try: - config = read_config() - port = connect(config) - port.send_json( - { - "method": "vouch", - "who": verify_key.encode(HexEncoder).decode("utf-8"), - "signed_name": HexEncoder.encode(signed_nickname).decode("utf-8"), - } - ) - port.receive_json() - except Exception as e: - print(f"Error: {e}") - sys.exit(1) - - if not ask(f"Grant permuter server access to {nickname}", default=True): - return - - try: - port.send_json({}) - port.receive_json() - except Exception as e: - print(f"Failed to grant access: {e}") - sys.exit(1) - - assert config.server_address, "checked by connect" - assert config.server_verify_key, "checked by connect" - data = config.server_verify_key.encode() + config.server_address.encode("utf-8") - token = SealedBox(verify_key.to_curve25519_public_key()).encrypt(data) - print("Granted!") - print() - print("Send them the following token:") - print(base64.b64encode(token).decode("utf-8")) diff --git a/tools/decomp-permuter/src/net/controller/.gitignore b/tools/decomp-permuter/src/net/controller/.gitignore deleted file mode 100644 index a2274adae..000000000 --- a/tools/decomp-permuter/src/net/controller/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target/ -config.toml -*.json diff --git a/tools/decomp-permuter/src/net/controller/Cargo.lock b/tools/decomp-permuter/src/net/controller/Cargo.lock deleted file mode 100644 index 9c9fab8c1..000000000 --- a/tools/decomp-permuter/src/net/controller/Cargo.lock +++ /dev/null @@ -1,607 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "argh" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91792f088f87cdc7a2cfb1d617fa5ea18d7f1dc22ef0e1b5f82f3157cdc522be" -dependencies = [ - "argh_derive", - "argh_shared", -] - -[[package]] -name = "argh_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4eb0c0c120ad477412dc95a4ce31e38f2113e46bd13511253f79196ca68b067" -dependencies = [ - "argh_shared", - "heck", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "argh_shared" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1" - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "bytes" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" - -[[package]] -name = "cc" -version = "1.0.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" -dependencies = [ - "libc", - "num-integer", - "num-traits", - "time", - "winapi", -] - -[[package]] -name = "getrandom" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "heck" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" -dependencies = [ - "unicode-segmentation", -] - -[[package]] -name = "hermit-abi" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" -dependencies = [ - "libc", -] - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "instant" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "itoa" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" - -[[package]] -name = "libc" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" - -[[package]] -name = "libsodium-sys" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a685b64f837b339074115f2e7f7b431ac73681d08d75b389db7498b8892b8a58" -dependencies = [ - "cc", - "libc", - "pkg-config", -] - -[[package]] -name = "lock_api" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "memchr" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" - -[[package]] -name = "mio" -version = "0.7.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" -dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", -] - -[[package]] -name = "miow" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" -dependencies = [ - "winapi", -] - -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "once_cell" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" - -[[package]] -name = "pahserver" -version = "0.0.1" -dependencies = [ - "argh", - "chrono", - "hex", - "pin-project", - "serde", - "serde_json", - "serde_tuple", - "slotmap", - "sodiumoxide", - "tempfile", - "tokio", - "toml", -] - -[[package]] -name = "parking_lot" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall", - "smallvec", - "winapi", -] - -[[package]] -name = "pin-project" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" - -[[package]] -name = "pkg-config" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" - -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "proc-macro2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core", -] - -[[package]] -name = "redox_syscall" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041" -dependencies = [ - "bitflags", -] - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "serde" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558dc50e1a5a5fa7112ca2ce4effcb321b0300c0d4ccf0776a9f60cd89031171" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.125" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b093b7a2bb58203b5da3056c05b4ec1fed827dcfdb37347a8841695263b3d06d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_tuple" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f025b91216f15a2a32aa39669329a475733590a015835d1783549a56d09427" -dependencies = [ - "serde", - "serde_tuple_macros", -] - -[[package]] -name = "serde_tuple_macros" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4076151d1a2b688e25aaf236997933c66e18b870d0369f8b248b8ab2be630d7e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "signal-hook-registry" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" -dependencies = [ - "libc", -] - -[[package]] -name = "slotmap" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585cd5dffe4e9e06f6dfdf66708b70aca3f781bed561f4f667b2d9c0d4559e36" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[package]] -name = "sodiumoxide" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7038b67c941e23501573cb7242ffb08709abe9b11eb74bceff875bbda024a6a8" -dependencies = [ - "libc", - "libsodium-sys", - "serde", -] - -[[package]] -name = "syn" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "tokio" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5" -dependencies = [ - "autocfg", - "bytes", - "libc", - "memchr", - "mio", - "num_cpus", - "once_cell", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "tokio-macros", - "winapi", -] - -[[package]] -name = "tokio-macros" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - -[[package]] -name = "unicode-segmentation" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/tools/decomp-permuter/src/net/controller/Cargo.toml b/tools/decomp-permuter/src/net/controller/Cargo.toml deleted file mode 100644 index 40b050b0a..000000000 --- a/tools/decomp-permuter/src/net/controller/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "pahserver" -version = "0.0.1" -edition = "2018" -resolver = "2" - -[dependencies] -tokio = { version = "1", features = ["full"] } -sodiumoxide = "0.2" -toml = "0.5" -serde = { version = "1.0", features = ["derive", "rc"] } -serde_json = "1.0" -serde_tuple = "0.5" -hex = "0.4" -argh = "0.1" -tempfile = "3" -slotmap = "1" -pin-project = "1" -chrono = "*" diff --git a/tools/decomp-permuter/src/net/controller/README.md b/tools/decomp-permuter/src/net/controller/README.md deleted file mode 100644 index 9661e6cf3..000000000 --- a/tools/decomp-permuter/src/net/controller/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# controller - -This directory contains code for the central permuter@home controller server, -written in Rust. All p@h traffic passes through here. - -If you just want to run a regular p@h server, you don't need to care about this. - -To setup your own copy of the controller server: - -- Install Rust and (for the libsodium dependency) GCC. -- Run `cargo build --release`. -- Run `./target/release/pahserver setup --db path/to/database.json` and follow - the instructions there. This will set the `priv_seed` part of `config.toml`, and - set up an initial trusted client. The rest of `config.toml` can be copied from - `config_example.toml`. -- Set up a reverse proxy that forwards HTTPS traffic from an external port or route - to HTTP for a port of your choice, e.g. using Nginx or Traefik. - If applicable, configure your firewall to let the external port through. -- Start the server with: - ``` -./target/release/pahserver run --listen-on 0.0.0.0: --config config.toml --db path/to/database.json -``` -and configure the system to run this at startup. diff --git a/tools/decomp-permuter/src/net/controller/config_example.toml b/tools/decomp-permuter/src/net/controller/config_example.toml deleted file mode 100644 index 9e0927085..000000000 --- a/tools/decomp-permuter/src/net/controller/config_example.toml +++ /dev/null @@ -1,2 +0,0 @@ -docker_image = "" -priv_seed = "0000000000000000000000000000000000000000000000000000000000000000" diff --git a/tools/decomp-permuter/src/net/controller/src/client.rs b/tools/decomp-permuter/src/net/controller/src/client.rs deleted file mode 100644 index 72a486d1b..000000000 --- a/tools/decomp-permuter/src/net/controller/src/client.rs +++ /dev/null @@ -1,205 +0,0 @@ -use std::collections::VecDeque; -use std::sync::Arc; - -use serde::{Deserialize, Serialize}; -use serde_json::json; -use tokio::sync::mpsc; - -use crate::db::UserId; -use crate::flimsy_semaphore::FlimsySemaphore; -use crate::port::{ReadPort, WritePort}; -use crate::stats; -use crate::util::SimpleResult; -use crate::{ - current_load, Permuter, PermuterData, PermuterId, PermuterResult, PermuterWork, ServerUpdate, - State, -}; - -const MIN_PERMUTER_VERSION: u32 = 1; - -const CLIENT_MAX_QUEUES_SIZE: usize = 100; -const MIN_PRIORITY: f64 = 0.001; -const MAX_PRIORITY: f64 = 10.0; - -#[derive(Debug, Deserialize)] -pub(crate) struct ConnectClientData { - priority: f64, -} - -#[derive(Deserialize)] -#[serde(tag = "type", rename_all = "snake_case")] -enum ClientMessage { - Work { work: PermuterWork }, -} - -#[derive(Serialize)] -struct PermuterResultMessage<'a> { - server: String, - #[serde(flatten)] - update: &'a ServerUpdate, -} - -async fn client_read( - port: &mut ReadPort<'_>, - perm_id: &PermuterId, - semaphore: &FlimsySemaphore, - state: &State, -) -> SimpleResult<()> { - loop { - let msg = port.recv().await?; - let msg: ClientMessage = serde_json::from_slice(&msg)?; - let ClientMessage::Work { work } = msg; - - // Avoid the work and result queues growing indefinitely by restricting - // their combined size with a semaphore. - semaphore.acquire().await; - - let mut m = state.m.lock().unwrap(); - let perm = m.permuters.get_mut(perm_id).unwrap(); - if perm.work_queue.is_empty() { - state.new_work_notification.notify_waiters(); - } - perm.work_queue.push_back(work); - } -} - -async fn client_write( - port: &mut WritePort<'_>, - fn_name: &str, - semaphore: &FlimsySemaphore, - state: &State, - mut result_rx: mpsc::UnboundedReceiver, - client_id: &UserId, -) -> SimpleResult<()> { - loop { - let res = result_rx.recv().await.unwrap(); - semaphore.release(); - - match res { - PermuterResult::NeedWork => { - port.send_json(&json!({ - "type": "need_work", - })) - .await?; - } - PermuterResult::Result(server_id, server_name, server_update) => { - port.send_json(&PermuterResultMessage { - server: server_name, - update: &server_update, - }) - .await?; - - if let ServerUpdate::Result { - compressed_source, - ref more_props, - .. - } = server_update - { - if let Some(ref data) = compressed_source { - port.send(data).await?; - } - - let score = more_props.get("score").and_then(|score| score.as_i64()); - let outcome = if compressed_source.is_none() { - stats::Outcome::Unhelpful - } else if matches!(score, Some(0)) { - stats::Outcome::Matched - } else { - stats::Outcome::Improved - }; - state - .log_stats(stats::Record::WorkDone { - server: server_id, - client: client_id.clone(), - fn_name: fn_name.to_string(), - outcome, - }) - .await?; - } - } - } - } -} - -pub(crate) async fn handle_connect_client<'a>( - mut read_port: ReadPort<'a>, - mut write_port: WritePort<'a>, - who_id: UserId, - who_name: &str, - permuter_version: u32, - state: &State, - data: ConnectClientData, -) -> SimpleResult<()> { - if permuter_version < MIN_PERMUTER_VERSION { - Err("Permuter version too old!")?; - } - - if !(MIN_PRIORITY <= data.priority && data.priority <= MAX_PRIORITY) { - Err("Priority out of range")?; - } - - let load = current_load(state, Some(data.priority)); - write_port.send_json(&load).await?; - - let permuter_data = read_port.recv().await?; - let mut permuter_data: PermuterData = serde_json::from_slice(&permuter_data)?; - permuter_data.compressed_source = read_port.recv().await?; - permuter_data.compressed_target_o_bin = read_port.recv().await?; - write_port.send_json(&json!({})).await?; - - eprintln!( - "[{}] start client ({}, {})", - &who_name, &permuter_data.fn_name, data.priority - ); - - state - .log_stats(stats::Record::ClientNewFunction { - client: who_id.clone(), - fn_name: permuter_data.fn_name.clone(), - }) - .await?; - - let energy_add = 1.0 / data.priority; - let fn_name = permuter_data.fn_name.clone(); - - let (result_tx, result_rx) = mpsc::unbounded_channel(); - let semaphore = Arc::new(FlimsySemaphore::new(CLIENT_MAX_QUEUES_SIZE)); - - let perm_id = { - let mut m = state.m.lock().unwrap(); - let id = m.next_permuter_id; - m.next_permuter_id += 1; - m.permuters.insert( - id, - Permuter { - data: permuter_data.into(), - client_id: who_id.clone(), - client_name: who_name.to_string(), - work_queue: VecDeque::new(), - result_tx: result_tx.clone(), - semaphore: semaphore.clone(), - priority: data.priority, - energy_add, - }, - ); - state.new_work_notification.notify_waiters(); - id - }; - - let r = tokio::try_join!( - client_read(&mut read_port, &perm_id, &semaphore, state), - client_write( - &mut write_port, - &fn_name, - &semaphore, - state, - result_rx, - &who_id - ) - ); - - state.m.lock().unwrap().permuters.remove(&perm_id); - state.new_work_notification.notify_waiters(); - r?; - Ok(()) -} diff --git a/tools/decomp-permuter/src/net/controller/src/db.rs b/tools/decomp-permuter/src/net/controller/src/db.rs deleted file mode 100644 index 8b608bd0d..000000000 --- a/tools/decomp-permuter/src/net/controller/src/db.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::collections::HashMap; -use std::convert::TryInto; - -use hex::FromHex; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_tuple::{Deserialize_tuple, Serialize_tuple}; -use sodiumoxide::crypto::sign; - -#[derive(Clone, Debug, Hash, Eq, PartialEq)] -pub struct ByteString([u8; SIZE]); - -impl ByteString { - fn to_hex(&self) -> String { - hex::encode(&self.0) - } - - fn from_hex(string: &str) -> Result, &'static str> { - Ok(ByteString( - Vec::from_hex(&string) - .map_err(|_| "not a valid hex string")? - .try_into() - .map_err(|_| "byte string has wrong size")?, - )) - } -} - -impl Serialize for ByteString { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_str(&self.to_hex()) - } -} - -impl<'de, const SIZE: usize> Deserialize<'de> for ByteString { - fn deserialize(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - use serde::de::Error; - let string = String::deserialize(deserializer)?; - ByteString::from_hex(&string).map_err(Error::custom) - } -} - -pub type UserId = ByteString<32>; - -impl UserId { - pub fn from_pubkey(key: &sign::PublicKey) -> UserId { - ByteString(key.as_ref().try_into().unwrap()) - } - - pub fn to_pubkey(&self) -> sign::PublicKey { - sign::PublicKey::from_slice(&self.0).unwrap() - } -} - -impl ByteString { - pub fn to_seed(&self) -> sign::Seed { - sign::Seed::from_slice(&self.0).unwrap() - } -} - -#[derive(Debug, Deserialize_tuple, Serialize_tuple)] -pub struct Stats { - pub iterations: u64, - pub improvements: u64, - pub matches: u64, - pub functions: u64, -} - -impl Default for Stats { - fn default() -> Stats { - Stats { - iterations: 0, - improvements: 0, - matches: 0, - functions: 0, - } - } -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct User { - pub trusted_by: Option, - pub name: String, - pub client_stats: Stats, - pub server_stats: Stats, -} - -#[derive(Debug, Deserialize, Serialize)] -pub struct DB { - pub users: HashMap, - pub func_stats: HashMap, - pub total_stats: Stats, -} - -impl DB { - pub fn func_stat(&mut self, fn_name: String) -> &mut Stats { - self.func_stats - .entry(fn_name) - .or_insert_with(Stats::default) - } -} diff --git a/tools/decomp-permuter/src/net/controller/src/flimsy_semaphore.rs b/tools/decomp-permuter/src/net/controller/src/flimsy_semaphore.rs deleted file mode 100644 index b29b41fea..000000000 --- a/tools/decomp-permuter/src/net/controller/src/flimsy_semaphore.rs +++ /dev/null @@ -1,61 +0,0 @@ -use std::convert::TryInto; -use std::sync::atomic::{AtomicIsize, Ordering}; - -use tokio::sync::Notify; - -/// An unfair semaphore that allows overdrafts. -pub struct FlimsySemaphore { - notify: Notify, - slots: AtomicIsize, -} - -impl FlimsySemaphore { - // Invariant: if `slots` has ever become non-positive, then if positive - // there will be a notify token in circulation. Taking the token - // synchronizes with a positive `slots`. - pub fn new(limit: usize) -> FlimsySemaphore { - FlimsySemaphore { - notify: Notify::new(), - slots: AtomicIsize::new(limit.try_into().unwrap()), - } - } - - pub fn acquire_ignore_limit(&self) { - self.slots.fetch_add(-1, Ordering::Acquire); - } - - pub async fn acquire(&self) { - let mut was_woken = false; - let mut val = self.slots.load(Ordering::Relaxed); - loop { - if val > 0 { - match self.slots.compare_exchange( - val, - val - 1, - Ordering::Acquire, - Ordering::Relaxed, - ) { - Ok(_) => { - if was_woken && val > 1 { - self.notify.notify_one(); - } - return; - } - Err(actually) => { - val = actually; - } - } - } else { - self.notify.notified().await; - was_woken = true; - val = self.slots.load(Ordering::Relaxed); - } - } - } - - pub fn release(&self) { - if self.slots.fetch_add(1, Ordering::Release) == 0 { - self.notify.notify_one(); - } - } -} diff --git a/tools/decomp-permuter/src/net/controller/src/main.rs b/tools/decomp-permuter/src/net/controller/src/main.rs deleted file mode 100644 index e50a91d53..000000000 --- a/tools/decomp-permuter/src/net/controller/src/main.rs +++ /dev/null @@ -1,418 +0,0 @@ -#![allow(clippy::try_err)] - -use std::collections::{HashMap, VecDeque}; -use std::convert::TryInto; -use std::default::Default; -use std::io::ErrorKind; -use std::sync::{Arc, Mutex}; - -use argh::FromArgs; -use serde::{Deserialize, Serialize}; -use serde_json::json; -use slotmap::{new_key_type, SlotMap}; -use sodiumoxide::crypto::box_; -use sodiumoxide::crypto::sign; -use tokio::fs; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::tcp::{ReadHalf, WriteHalf}; -use tokio::net::{TcpListener, TcpStream}; -use tokio::sync::{mpsc, watch, Notify}; -use tokio::time; - -use crate::db::{ByteString, UserId}; -use crate::flimsy_semaphore::FlimsySemaphore; -use crate::port::{ReadPort, WritePort}; -use crate::save::SaveableDB; -use crate::util::SimpleResult; - -mod client; -mod db; -mod flimsy_semaphore; -mod port; -mod save; -mod server; -mod setup; -mod stats; -mod util; -mod vouch; - -const HEARTBEAT_TIME: time::Duration = time::Duration::from_secs(300); - -#[derive(FromArgs)] -/// The permuter@home control server. -struct CmdOpts { - #[argh(subcommand)] - sub: SubCommand, -} - -#[derive(FromArgs)] -#[argh(subcommand)] -enum SubCommand { - RunServer(RunServerOpts), - Setup(SetupOpts), -} - -#[derive(FromArgs)] -/// Run the permuter@home control server. -#[argh(subcommand, name = "run")] -struct RunServerOpts { - /// ip:port to listen on (e.g. 0.0.0.0:1234) - #[argh(option)] - listen_on: String, - - /// path to TOML configuration file - #[argh(option)] - config: String, - - /// path to JSON database - #[argh(option)] - db: String, - - /// enable debug logging - #[argh(switch)] - debug: bool, -} - -#[derive(FromArgs)] -/// Setup initial database and config for permuter@home. -#[argh(subcommand, name = "setup")] -struct SetupOpts { - /// path to JSON database - #[argh(option)] - db: String, -} - -#[derive(Deserialize)] -struct Config { - docker_image: String, - priv_seed: ByteString<32>, -} - -#[derive(Debug, Deserialize, Serialize)] -struct PermuterData { - fn_name: String, - #[serde(skip)] - compressed_source: Vec, - #[serde(skip)] - compressed_target_o_bin: Vec, - #[serde(flatten)] - more_props: HashMap, -} - -#[derive(Clone, Copy, Debug, Deserialize, Serialize)] -struct PermuterWork { - seed: u64, -} - -#[derive(Debug, Deserialize, Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -enum ServerUpdate { - Result { - #[serde(skip_serializing, default)] - overhead_us: i64, - #[serde(skip)] - compressed_source: Option>, - #[serde(default)] - has_source: bool, - #[serde(flatten)] - more_props: HashMap, - }, - InitDone { - hash: String, - }, - InitFailed { - reason: String, - }, - Disconnect, -} - -#[derive(Debug)] -enum PermuterResult { - NeedWork, - Result(UserId, String, ServerUpdate), -} - -type PermuterId = u64; - -struct Permuter { - data: Arc, - client_id: UserId, - client_name: String, - work_queue: VecDeque, - result_tx: mpsc::UnboundedSender, - semaphore: Arc, - priority: f64, - energy_add: f64, -} - -impl Permuter { - fn send_result(&mut self, res: PermuterResult) { - // We can't use a blocking semaphore acquire here, because we don't - // want server sends to block on random client receives. In practice, - // this is probably fine. - let _ = self.result_tx.send(res); - self.semaphore.acquire_ignore_limit(); - } -} - -new_key_type! { struct ServerId; } - -struct ConnectedServer { - min_priority: f64, - num_cores: f64, -} - -struct MutableState { - servers: SlotMap, - permuters: HashMap, - next_permuter_id: PermuterId, -} - -struct State { - docker_image: String, - debug: bool, - sign_sk: sign::SecretKey, - db: SaveableDB, - stats_tx: mpsc::Sender, - heartbeat_rx: watch::Receiver<()>, - new_work_notification: Notify, - m: Mutex, -} - -impl State { - async fn log_stats(&self, record: stats::Record) -> SimpleResult<()> { - self.stats_tx - .send(record) - .await - .map_err(|_| "stats thread died".into()) - } -} - -#[derive(Deserialize)] -#[serde(tag = "method", rename_all = "snake_case")] -enum Request { - Ping, - Vouch(vouch::VouchData), - ConnectServer(server::ConnectServerData), - ConnectClient(client::ConnectClientData), -} - -#[derive(Serialize)] -struct Load { - clients: usize, - servers: usize, - cores: f64, -} - -#[tokio::main] -async fn main() -> SimpleResult<()> { - sodiumoxide::init().map_err(|()| "Failed to initialize cryptography library")?; - - let opts: CmdOpts = argh::from_env(); - - match opts.sub { - SubCommand::RunServer(opts) => run_server(opts).await?, - SubCommand::Setup(opts) => setup::run_setup(opts)?, - } - Ok(()) -} - -async fn run_server(opts: RunServerOpts) -> SimpleResult<()> { - let config: Config = toml::from_str(&fs::read_to_string(&opts.config).await?)?; - let (_, sign_sk) = sign::keypair_from_seed(&config.priv_seed.to_seed()); - - let (save_fut, db) = SaveableDB::open(&opts.db)?; - tokio::spawn(async move { - if let Err(e) = save_fut.await { - eprintln!("Failed to save! {:?}", e); - std::process::exit(1); - } - }); - - let (stats_fut, stats_tx) = stats::stats_thread(&db); - tokio::spawn(stats_fut); - - let (heartbeat_tx, heartbeat_rx) = watch::channel(()); - - let state: &'static State = Box::leak(Box::new(State { - docker_image: config.docker_image, - debug: opts.debug, - sign_sk, - db, - stats_tx, - heartbeat_rx, - new_work_notification: Notify::new(), - m: Mutex::new(MutableState { - servers: SlotMap::with_key(), - permuters: HashMap::new(), - next_permuter_id: 0, - }), - })); - - tokio::spawn(async move { - loop { - heartbeat_tx.send(()).expect("receiver is still alive"); - time::sleep(HEARTBEAT_TIME).await; - } - }); - - let listener = TcpListener::bind(opts.listen_on).await?; - - loop { - let (socket, _) = listener.accept().await?; - tokio::spawn(async move { - let mut who = "anonymous".to_string(); - if let Err(e) = handle_connection(socket, state, &mut who).await { - if let Some(e) = e.downcast_ref::() { - if matches!( - e.kind(), - ErrorKind::UnexpectedEof - | ErrorKind::ConnectionReset - | ErrorKind::TimedOut - | ErrorKind::BrokenPipe - ) { - eprintln!("[{}] disconnected", &who); - return; - } - } - eprintln!("[{}] error: {:?}", &who, e); - } - }); - } -} - -fn concat(a: &[T], b: &[T]) -> Vec { - a.iter().chain(b).cloned().collect() -} - -fn concat3(a: &[T], b: &[T], c: &[T]) -> Vec { - a.iter().chain(b).chain(c).cloned().collect() -} - -async fn handshake<'a>( - mut rd: ReadHalf<'a>, - mut wr: WriteHalf<'a>, - sign_sk: &sign::SecretKey, -) -> SimpleResult<(ReadPort<'a>, WritePort<'a>, UserId, u32)> { - let mut buffer = [0; 4 + 32]; - rd.read_exact(&mut buffer).await?; - let (magic, their_pk) = buffer.split_at(4); - if magic != b"p@h0" { - Err("Invalid protocol version")?; - } - let their_pk = box_::PublicKey::from_slice(&their_pk).unwrap(); - - let (our_pk, our_sk) = box_::gen_keypair(); - let signed_data = concat3(b"HELLO:", their_pk.as_ref(), our_pk.as_ref()); - let signature = sign::sign_detached(&signed_data, &sign_sk); - wr.write_all(&concat(our_pk.as_ref(), signature.as_ref())) - .await?; - - let key = box_::precompute(&their_pk, &our_sk); - let mut read_port = ReadPort::new(rd, &key); - let write_port = WritePort::new(wr, &key); - - let reply = read_port.recv().await?; - if reply.len() != 32 + 64 + 4 { - Err("Failed to perform secret handshake")?; - } - let (client_ver_key, rest) = reply.split_at(32); - let (client_signature, permuter_version) = rest.split_at(64); - let client_ver_key = sign::PublicKey::from_slice(client_ver_key).unwrap(); - let client_signature = sign::Signature::from_slice(client_signature).unwrap(); - let permuter_version = u32::from_be_bytes(permuter_version.try_into().unwrap()); - let signed_data = concat(b"WORLD:", our_pk.as_ref()); - if !sign::verify_detached(&client_signature, &signed_data, &client_ver_key) { - Err("Spoofed client signature!")?; - } - - Ok(( - read_port, - write_port, - UserId::from_pubkey(&client_ver_key), - permuter_version, - )) -} - -fn current_load(state: &State, priority: Option) -> Load { - let m = state.m.lock().unwrap(); - let mut servers: usize = 0; - let mut cores: f64 = 0.0; - for server in m.servers.values() { - if priority.map_or(true, |p| p >= server.min_priority) { - servers += 1; - cores += server.num_cores; - } - } - Load { - clients: m.permuters.len(), - servers, - cores, - } -} - -async fn handle_connection( - mut socket: TcpStream, - state: &State, - out_name: &mut String, -) -> SimpleResult<()> { - let (rd, wr) = socket.split(); - let (mut read_port, mut write_port, user_id, permuter_version) = - handshake(rd, wr, &state.sign_sk).await?; - let name = match state.db.read(|db| { - let user = db.users.get(&user_id)?; - Some(user.name.clone()) - }) { - Some(name) => name, - None => { - write_port.send_error("Access denied!").await?; - Err("Unknown client!")? - } - }; - *out_name = name.clone(); - eprintln!("[{}] connected (v {})", &name, permuter_version); - if state.debug { - read_port.set_debug(&name); - write_port.set_debug(&name); - } - write_port.send_json(&json!({})).await?; - - let request = read_port.recv().await?; - let request: Request = serde_json::from_slice(&request)?; - match request { - Request::Ping => { - eprintln!("[{}] ping", &name); - let load = current_load(state, None); - write_port.send_json(&load).await?; - } - Request::Vouch(data) => { - vouch::handle_vouch(read_port, write_port, user_id, &name, state, data).await?; - } - Request::ConnectServer(data) => { - server::handle_connect_server( - read_port, - write_port, - user_id, - &name, - permuter_version, - state, - data, - ) - .await?; - } - Request::ConnectClient(data) => { - client::handle_connect_client( - read_port, - write_port, - user_id, - &name, - permuter_version, - state, - data, - ) - .await?; - } - }; - - Ok(()) -} diff --git a/tools/decomp-permuter/src/net/controller/src/port.rs b/tools/decomp-permuter/src/net/controller/src/port.rs deleted file mode 100644 index 5e9c52eeb..000000000 --- a/tools/decomp-permuter/src/net/controller/src/port.rs +++ /dev/null @@ -1,115 +0,0 @@ -use std::convert::TryInto; - -use chrono::Local; -use serde::Serialize; -use sodiumoxide::crypto::box_; -use sodiumoxide::crypto::box_::{Nonce, PrecomputedKey}; -use tokio::io::{AsyncReadExt, AsyncWriteExt}; -use tokio::net::tcp::{ReadHalf, WriteHalf}; - -use crate::util::SimpleResult; - -fn debug_print(action: &str, who: &str, msg: &[u8]) { - let time = Local::now().format("%H:%M:%S:%f"); - if msg.len() <= 300 { - let msg = String::from_utf8( - msg.iter() - .copied() - .flat_map(std::ascii::escape_default) - .collect(), - ) - .unwrap(); - println!("{} debug: {} {}: {}", time, action, who, msg); - } else { - println!("{} debug: {} {}: {} bytes", time, action, who, msg.len()); - } -} - -pub struct ReadPort<'a> { - read_half: ReadHalf<'a>, - key: PrecomputedKey, - nonce: u64, - debug_name: Option<&'a str>, -} - -impl<'a> ReadPort<'a> { - pub fn new(read_half: ReadHalf<'a>, key: &PrecomputedKey) -> Self { - ReadPort { - read_half, - key: key.clone(), - nonce: 0, - debug_name: None, - } - } - - pub fn set_debug(&mut self, name: &'a str) { - self.debug_name = Some(name); - } - - pub async fn recv(&mut self) -> SimpleResult> { - let len = self.read_half.read_u64().await?; - if len >= (1 << 48) { - Err("Unreasonable packet length")? - } - let mut buffer = vec![0; len.try_into()?]; - self.read_half.read_exact(&mut buffer).await?; - let nonce = nonce_from_u64(self.nonce); - self.nonce += 2; - let data = - box_::open_precomputed(&buffer, &nonce, &self.key).map_err(|()| "Failed to decrypt")?; - if let Some(name) = self.debug_name { - debug_print("Receive from", name, &data); - } - Ok(data) - } -} - -pub struct WritePort<'a> { - write_half: WriteHalf<'a>, - key: PrecomputedKey, - nonce: u64, - debug_name: Option<&'a str>, -} - -impl<'a> WritePort<'a> { - pub fn new(write_half: WriteHalf<'a>, key: &PrecomputedKey) -> Self { - WritePort { - write_half, - key: key.clone(), - nonce: 1, - debug_name: None, - } - } - - pub fn set_debug(&mut self, name: &'a str) { - self.debug_name = Some(name); - } - - pub async fn send(&mut self, data: &[u8]) -> SimpleResult<()> { - if let Some(name) = self.debug_name { - debug_print("Send to", name, &data); - } - let nonce = nonce_from_u64(self.nonce); - self.nonce += 2; - let data = box_::seal_precomputed(data, &nonce, &self.key); - self.write_half.write_u64(data.len() as u64).await?; - self.write_half.write_all(&data).await?; - Ok(()) - } - - pub async fn send_json(&mut self, value: &T) -> SimpleResult<()> - where - T: Serialize, - { - self.send(&serde_json::to_vec(value)?).await - } - - pub async fn send_error(&mut self, message: &str) -> SimpleResult<()> { - self.send_json(message).await - } -} - -fn nonce_from_u64(num: u64) -> Nonce { - let nonce_bytes = [[0; 8], [0; 8], num.to_be_bytes()].concat(); - Nonce::from_slice(&nonce_bytes).unwrap() -} diff --git a/tools/decomp-permuter/src/net/controller/src/save.rs b/tools/decomp-permuter/src/net/controller/src/save.rs deleted file mode 100644 index 883637279..000000000 --- a/tools/decomp-permuter/src/net/controller/src/save.rs +++ /dev/null @@ -1,158 +0,0 @@ -use std::future::Future; -use std::io::Write; -use std::path::{Path, PathBuf}; -use std::sync::{Arc, RwLock}; -use std::time::Duration; - -use tempfile::NamedTempFile; -use tokio::sync::{mpsc, oneshot}; -use tokio::time::timeout; - -use crate::db::DB; -use crate::util::{FutureExt, SimpleResult}; - -const SAVE_INTERVAL: Duration = Duration::from_secs(30); - -enum SaveType { - Delayed, - Immediate(oneshot::Sender<()>), -} - -struct InnerSaveableDB { - db: DB, - stale: bool, - save_chan: mpsc::UnboundedSender, -} - -#[derive(Clone)] -pub struct SaveableDB(Arc>); - -async fn save_db_loop( - db: SaveableDB, - path: &Path, - mut save_channel: mpsc::UnboundedReceiver, -) -> SimpleResult<()> { - loop { - let mut done_chans = Vec::new(); - match save_channel.recv().await { - None => return Ok(()), - Some(SaveType::Immediate(chan)) => { - done_chans.push(chan); - } - Some(SaveType::Delayed) => { - // Wait for SAVE_INTERVAL or until we receive an Immediate save. - let _ = timeout(SAVE_INTERVAL, async { - loop { - match save_channel.recv().await { - None => { - break; - } - Some(SaveType::Immediate(chan)) => { - done_chans.push(chan); - break; - } - Some(SaveType::Delayed) => {} - }; - } - }) - .await; - } - }; - - // Clear the queue in case more messages have stacked up past an - // Immediate. Receiver::try_recv() is temporarily dead as of tokio 1.4 - // (https://github.com/tokio-rs/tokio/issues/3350) due to a bug where - // messages can be delayed, but in this case that doesn't matter. - loop { - match save_channel.recv().now_or_never().await { - None | Some(None) => { - break; - } - Some(Some(SaveType::Immediate(chan))) => { - done_chans.push(chan); - } - Some(Some(SaveType::Delayed)) => {} - }; - } - - // Mark the DB as non-stale, to start receiving save messages again. - db.0.write().unwrap().stale = false; - - // Actually do the save, by first serializing, then atomically saving - // the file by creating and renaming a temp file in the same directory. - let data = db.read(|db| serde_json::to_string(&db).unwrap()); - - let r: SimpleResult<()> = tokio::task::block_in_place(|| { - let parent_dir = path.parent().unwrap_or_else(|| Path::new(".")); - let mut tempf = NamedTempFile::new_in(parent_dir)?; - tempf.write_all(data.as_bytes())?; - tempf.as_file().sync_all()?; - tempf.persist(path)?; - Ok(()) - }); - r?; - - for chan in done_chans { - let _ = chan.send(()); - } - } -} - -impl SaveableDB { - pub fn open( - filename: &str, - ) -> SimpleResult<(impl Future>, SaveableDB)> { - let db_file = std::fs::File::open(filename)?; - let db: DB = serde_json::from_reader(&db_file)?; - - let (save_tx, save_rx) = mpsc::unbounded_channel(); - - let saveable_db = SaveableDB(Arc::new(RwLock::new(InnerSaveableDB { - db, - stale: false, - save_chan: save_tx, - }))); - - let path = PathBuf::from(filename); - let db2 = saveable_db.clone(); - - let fut = async move { save_db_loop(db2, &path, save_rx).await }; - Ok((fut, saveable_db)) - } - - pub fn read(&self, callback: impl FnOnce(&DB) -> T) -> T { - let inner = self.0.read().unwrap(); - callback(&inner.db) - } - - pub async fn write(&self, immediate: bool, callback: impl FnOnce(&mut DB) -> T) -> T { - let ret; - let rx2; - { - let mut inner = self.0.write().unwrap(); - ret = callback(&mut inner.db); - if immediate { - inner.stale = true; - let (tx, rx) = oneshot::channel(); - rx2 = rx; - inner - .save_chan - .send(SaveType::Immediate(tx)) - .map_err(|_| ()) - .expect("Failed to send message to save task"); - } else { - if !inner.stale { - inner.stale = true; - inner - .save_chan - .send(SaveType::Delayed) - .map_err(|_| ()) - .expect("Failed to send message to save task"); - } - return ret; - } - } - rx2.await.expect("Failed to save!"); - ret - } -} diff --git a/tools/decomp-permuter/src/net/controller/src/server.rs b/tools/decomp-permuter/src/net/controller/src/server.rs deleted file mode 100644 index 3f461adc5..000000000 --- a/tools/decomp-permuter/src/net/controller/src/server.rs +++ /dev/null @@ -1,500 +0,0 @@ -use std::collections::{HashMap, HashSet}; -use std::sync::{Arc, Mutex}; - -use serde::{Deserialize, Serialize}; -use serde_json::json; -use tokio::sync::{mpsc, mpsc::error::TrySendError, watch, Notify}; - -use crate::db::UserId; -use crate::port::{ReadPort, WritePort}; -use crate::stats; -use crate::util::SimpleResult; -use crate::{ - ConnectedServer, MutableState, PermuterData, PermuterId, PermuterResult, PermuterWork, - ServerUpdate, State, HEARTBEAT_TIME, -}; - -const MIN_PERMUTER_VERSION: u32 = 1; - -const SERVER_WORK_QUEUE_SIZE: usize = 100; -const TIME_US_GUESS: f64 = 100_000.0; -const MIN_OVERHEAD_US: f64 = 100_000.0; -const MAX_OVERHEAD_FACTOR: i64 = 2; - -#[derive(Debug, Deserialize)] -pub(crate) struct ConnectServerData { - min_priority: f64, - num_cores: f64, -} - -#[derive(Deserialize)] -#[serde(tag = "type", rename_all = "snake_case")] -enum ServerMessage { - NeedWork, - Update { - permuter: PermuterId, - time_us: f64, - update: ServerUpdate, - }, -} - -enum JobState { - Loading, - Loaded, - Failed, -} - -struct Job { - state: JobState, - energy: f64, - active_work: i64, -} - -struct ServerState { - min_priority: f64, - /// sum of active_work across all jobs - active_work: i64, - /// fractional part of how much work should be requested, in [0, 1) - more_work_acc: f64, - jobs: HashMap, -} - -async fn server_read( - port: &mut ReadPort<'_>, - who_id: &UserId, - who_name: &str, - server_state: &Mutex, - state: &State, - more_work_tx: mpsc::Sender<()>, - new_permuter: &Notify, -) -> SimpleResult<()> { - loop { - let msg = port.recv().await?; - let mut msg: ServerMessage = serde_json::from_slice(&msg)?; - if let ServerMessage::Update { - update: - ServerUpdate::Result { - ref mut compressed_source, - has_source: true, - .. - }, - .. - } = msg - { - *compressed_source = Some(port.recv().await?); - } - - let mut has_new = false; - let mut request_work; - - { - let mut m = state.m.lock().unwrap(); - let mut server_state = server_state.lock().unwrap(); - - let mut more_work: f64 = 1.0; - - if let ServerMessage::Update { - permuter: perm_id, - update, - time_us, - } = msg - { - // If we get back a message referring to a since-removed - // permuter, no need to do anything. Just request one more - // piece of work to make up for it. - if let Some(job) = server_state.jobs.get_mut(&perm_id) { - if let Some(perm) = m.permuters.get_mut(&perm_id) { - job.energy += perm.energy_add * time_us; - - match update { - ServerUpdate::InitDone { .. } => { - if !matches!(job.state, JobState::Loading) { - Err("Got InitDone while not in Loading state")?; - } - job.state = JobState::Loaded; - has_new = true; - } - ServerUpdate::InitFailed { .. } => { - if !matches!(job.state, JobState::Loading) { - Err("Got InitFailed while not in Loading state")?; - } - job.state = JobState::Failed; - } - ServerUpdate::Disconnect { .. } => { - if !matches!(job.state, JobState::Loaded) { - Err("Got Disconnect while not in Loaded state")?; - } - job.state = JobState::Failed; - let work = job.active_work; - job.active_work = 0; - server_state.active_work -= work; - more_work = 0.0; - } - ServerUpdate::Result { overhead_us, .. } => { - if !matches!(job.state, JobState::Loaded) { - Err("Got result while not in Loaded state")?; - } - // If the work item spent less than some given - // amount of time in queues, request more work. - // This ensures we saturate all server cores. - // On the other hand, if it spends too much time - // in queues, it's best if we reduce the amount - // of work. - // We don't need to adjust for time spent on the - // network, because we have backpressure on slow - // writes on both ends, and read continuously. - job.active_work -= 1; - server_state.active_work -= 1; - let min_overhead_us = (time_us + MIN_OVERHEAD_US) as i64; - if overhead_us == 0 { - // Legacy server, skip this logic. - } else if overhead_us > MAX_OVERHEAD_FACTOR * min_overhead_us { - more_work = 0.5; - } else if overhead_us < min_overhead_us { - more_work = 1.5; - } - } - } - perm.send_result(PermuterResult::Result( - who_id.clone(), - who_name.to_string(), - update, - )); - } - } - } - - more_work += server_state.more_work_acc; - request_work = more_work as i32; - server_state.more_work_acc = more_work - request_work as f64; - - if request_work == 0 - && server_state.active_work == 0 - && more_work_tx.capacity() == SERVER_WORK_QUEUE_SIZE - { - // Don't request 0 work if it would lead to total starvation. - request_work = 1; - } - } - - if has_new { - new_permuter.notify_waiters(); - state - .log_stats(stats::Record::ServerNewFunction { - server: who_id.clone(), - }) - .await?; - } - - for _ in 0..request_work { - // Try requesting more work by sending a message to the writer thread. - // If the queue is full (because the writer thread is blocked on a - // send), drop the request to avoid an unbounded backlog. - if let Err(TrySendError::Closed(_)) = more_work_tx.try_send(()) { - panic!("work chooser must not close except on error"); - } - } - } -} - -#[derive(Serialize)] -#[serde(tag = "type", rename_all = "snake_case")] -enum ToSend { - Work(PermuterWork), - Add { - client_id: UserId, - client_name: String, - data: Arc, - }, - Remove, -} - -#[derive(Serialize)] -struct OutMessage { - permuter: PermuterId, - #[serde(flatten)] - to_send: ToSend, -} - -fn try_next_work_message( - m: &mut MutableState, - server_state: &mut ServerState, -) -> Option { - let mut skip = HashSet::new(); - loop { - // If possible, send a new permuter. - if let Some((&perm_id, perm)) = m - .permuters - .iter() - .find(|(&perm_id, _)| !server_state.jobs.contains_key(&perm_id)) - { - server_state.jobs.insert( - perm_id, - Job { - state: JobState::Loading, - energy: 0.0, - active_work: 0, - }, - ); - return Some(OutMessage { - permuter: perm_id, - to_send: ToSend::Add { - client_id: perm.client_id.clone(), - client_name: perm.client_name.clone(), - data: perm.data.clone(), - }, - }); - } - - // If none, find an existing one to work on, or to remove. - let mut best_cost = 0.0; - let mut best: Option<(PermuterId, &mut Job)> = None; - let min_priority = server_state.min_priority; - for (&perm_id, job) in server_state.jobs.iter_mut() { - if let Some(perm) = m.permuters.get(&perm_id) { - let energy = - job.energy + (job.active_work as f64) * perm.energy_add * TIME_US_GUESS; - if matches!(job.state, JobState::Loaded) - && !skip.contains(&perm_id) - && perm.priority >= min_priority - && (best.is_none() || energy < best_cost) - { - best_cost = energy; - best = Some((perm_id, job)); - } - } else { - server_state.active_work -= job.active_work; - server_state.jobs.remove(&perm_id); - return Some(OutMessage { - permuter: perm_id, - to_send: ToSend::Remove, - }); - } - } - - let (perm_id, job) = match best { - None => return None, - Some(tup) => tup, - }; - - let perm = m.permuters.get_mut(&perm_id).unwrap(); - let work = match perm.work_queue.pop_front() { - None => { - // Chosen permuter is out of work. Ask it for more, and try - // again without it as a candidate. When the queue becomes - // non-empty again all sleeping writers will be notified. - perm.send_result(PermuterResult::NeedWork); - skip.insert(perm_id); - continue; - } - Some(work) => work, - }; - - perm.semaphore.release(); - - let min_energy = job.energy; - job.active_work += 1; - server_state.active_work += 1; - - // Adjust energies to be around zero, to avoid problems with float - // imprecision, and to ensure that new permuters that come in with - // energy zero will fit the schedule. - for job in server_state.jobs.values_mut() { - job.energy -= min_energy; - } - - return Some(OutMessage { - permuter: perm_id, - to_send: ToSend::Work(work), - }); - } -} - -async fn next_work_message( - server_state: &Mutex, - state: &State, - new_permuter: &Notify, -) -> OutMessage { - let mut wait_for = None; - loop { - if let Some(waiter) = wait_for { - waiter.await; - } - let mut m = state.m.lock().unwrap(); - let mut server_state = server_state.lock().unwrap(); - match try_next_work_message(&mut m, &mut server_state) { - Some(message) => return message, - None => { - // Nothing to work on! Register to be notified when something - // happens (while the lock is still held) and go to sleep. - let n1 = state.new_work_notification.notified(); - let n2 = new_permuter.notified(); - wait_for = Some(async move { - tokio::select! { - () = n1 => {} - () = n2 => {} - } - }); - } - } - } -} - -fn requires_response(work: &OutMessage) -> bool { - match work.to_send { - ToSend::Work { .. } => true, - ToSend::Add { .. } => true, - ToSend::Remove => false, - } -} - -async fn server_choose_work( - server_state: &Mutex, - state: &State, - mut more_work_rx: mpsc::Receiver<()>, - next_message_tx: mpsc::Sender, - wrote_message: &Notify, - new_permuter: &Notify, -) -> SimpleResult<()> { - loop { - let message = next_work_message(server_state, state, new_permuter).await; - let requires_response = requires_response(&message); - next_message_tx - .send(message) - .await - .map_err(|_| ()) - .expect("writer must not close except on error"); - wrote_message.notified().await; - if requires_response { - more_work_rx - .recv() - .await - .expect("reader must not close except on error"); - } - } -} - -async fn send_heartbeat(port: &mut WritePort<'_>) -> SimpleResult<()> { - port.send_json(&json!({ - "type": "heartbeat", - })) - .await -} - -async fn send_work(port: &mut WritePort<'_>, work: &OutMessage) -> SimpleResult<()> { - port.send_json(&work).await?; - if let ToSend::Add { ref data, .. } = work.to_send { - port.send(&data.compressed_source).await?; - port.send(&data.compressed_target_o_bin).await?; - } - Ok(()) -} - -async fn server_write( - port: &mut WritePort<'_>, - mut next_message_rx: mpsc::Receiver, - mut heartbeat_rx: watch::Receiver<()>, - wrote_message: &Notify, -) -> SimpleResult<()> { - loop { - tokio::select! { - work = next_message_rx.recv() => { - let work = work.expect("chooser must not close except on error"); - send_work(port, &work).await?; - wrote_message.notify_one(); - } - res = heartbeat_rx.changed() => { - res.expect("heartbeat thread panicked"); - send_heartbeat(port).await?; - } - } - } -} - -pub(crate) async fn handle_connect_server<'a>( - mut read_port: ReadPort<'a>, - mut write_port: WritePort<'a>, - who_id: UserId, - who_name: &str, - permuter_version: u32, - state: &State, - data: ConnectServerData, -) -> SimpleResult<()> { - if permuter_version < MIN_PERMUTER_VERSION { - Err("Permuter version too old!")?; - } - - eprintln!( - "[{}] start server ({}, {})", - who_name, data.min_priority, data.num_cores - ); - - write_port - .send_json(&json!({ - "docker_image": &state.docker_image, - "heartbeat_interval": HEARTBEAT_TIME.as_secs(), - })) - .await?; - - let (more_work_tx, more_work_rx) = mpsc::channel(SERVER_WORK_QUEUE_SIZE); - let (next_message_tx, next_message_rx) = mpsc::channel(1); - let wrote_message = Notify::new(); - let new_permuter = Notify::new(); - - let mut server_state = Mutex::new(ServerState { - min_priority: data.min_priority, - active_work: 0, - more_work_acc: 0.0, - jobs: HashMap::new(), - }); - - let id = state.m.lock().unwrap().servers.insert(ConnectedServer { - min_priority: data.min_priority, - num_cores: data.num_cores, - }); - - let r = tokio::try_join!( - server_read( - &mut read_port, - &who_id, - who_name, - &server_state, - state, - more_work_tx, - &new_permuter, - ), - server_choose_work( - &server_state, - state, - more_work_rx, - next_message_tx, - &wrote_message, - &new_permuter, - ), - server_write( - &mut write_port, - next_message_rx, - state.heartbeat_rx.clone(), - &wrote_message, - ) - ); - - { - let mut m = state.m.lock().unwrap(); - for (&perm_id, job) in &server_state.get_mut().unwrap().jobs { - if let JobState::Loaded = job.state { - if let Some(perm) = m.permuters.get_mut(&perm_id) { - perm.send_result(PermuterResult::Result( - who_id.clone(), - who_name.to_string(), - ServerUpdate::Disconnect, - )); - } - } - } - - m.servers.remove(id); - } - r?; - Ok(()) -} diff --git a/tools/decomp-permuter/src/net/controller/src/setup.rs b/tools/decomp-permuter/src/net/controller/src/setup.rs deleted file mode 100644 index 07fec490b..000000000 --- a/tools/decomp-permuter/src/net/controller/src/setup.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::collections::HashMap; -use std::default::Default; -use std::fs::OpenOptions; - -use sodiumoxide::crypto::sign; -use sodiumoxide::randombytes::randombytes; - -use crate::db::{User, UserId, DB}; -use crate::util::SimpleResult; -use crate::SetupOpts; - -pub(crate) fn run_setup(opts: SetupOpts) -> SimpleResult<()> { - let db_file = OpenOptions::new() - .write(true) - .create_new(true) - .open(&opts.db) - .unwrap_or_else(|e| { - eprintln!("Cannot create database file {}: {}. Aborting.", &opts.db, e); - std::process::exit(1); - }); - - let server_seed = sign::Seed::from_slice(&randombytes(32)).unwrap(); - let client_seed = sign::Seed::from_slice(&randombytes(32)).unwrap(); - - let (server_pub_key, _) = sign::keypair_from_seed(&server_seed); - let (client_pub_key, _) = sign::keypair_from_seed(&client_seed); - - let root_user = User { - trusted_by: None, - name: "root".into(), - client_stats: Default::default(), - server_stats: Default::default(), - }; - let mut users_map: HashMap = HashMap::new(); - users_map.insert(UserId::from_pubkey(&client_pub_key), root_user); - let db = DB { - users: users_map, - func_stats: HashMap::new(), - total_stats: Default::default(), - }; - - serde_json::to_writer(&db_file, &db)?; - - println!( - "Setup successful!\n\n\ - Put the following in the server's config.toml:\n\n\ - priv_seed = \"{}\"\n\n\ - Put the following in the root client's pah.conf:\n\n\ - secret_key = \"{}\"\n\ - server_public_key = \"{}\"\n\ - server_address = \"server.example:port\"", - hex::encode(server_seed), - hex::encode(client_seed), - hex::encode(server_pub_key) - ); - Ok(()) -} diff --git a/tools/decomp-permuter/src/net/controller/src/stats.rs b/tools/decomp-permuter/src/net/controller/src/stats.rs deleted file mode 100644 index 079e4582f..000000000 --- a/tools/decomp-permuter/src/net/controller/src/stats.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::future::Future; - -use tokio::sync::mpsc; - -use crate::db::{Stats, UserId}; -use crate::save::SaveableDB; - -const CHANNEL_CAPACITY: usize = 10000; - -#[derive(Clone, Copy)] -pub enum Outcome { - Matched, - Improved, - Unhelpful, -} - -pub enum Record { - WorkDone { - server: UserId, - client: UserId, - fn_name: String, - outcome: Outcome, - }, - ClientNewFunction { - client: UserId, - fn_name: String, - }, - ServerNewFunction { - server: UserId, - }, -} - -fn add_stats(stats: &mut Stats, outcome: Outcome) { - if matches!(outcome, Outcome::Matched) { - stats.matches += 1; - } - if matches!(outcome, Outcome::Matched | Outcome::Improved) { - stats.improvements += 1; - } - stats.iterations += 1; -} - -async fn stats_writer(db: &SaveableDB, mut rx: mpsc::Receiver) { - loop { - let record = rx.recv().await.unwrap(); - db.write(false, |db| { - match record { - Record::WorkDone { - server, - client, - fn_name, - outcome, - } => { - add_stats(&mut db.total_stats, outcome); - add_stats(db.func_stat(fn_name), outcome); - if let Some(user) = db.users.get_mut(&client) { - add_stats(&mut user.client_stats, outcome); - } - if let Some(user) = db.users.get_mut(&server) { - add_stats(&mut user.server_stats, outcome); - } - } - Record::ClientNewFunction { client, fn_name } => { - db.func_stat(fn_name).functions += 1; - if let Some(user) = db.users.get_mut(&client) { - user.client_stats.functions += 1; - } - db.total_stats.functions += 1; - } - Record::ServerNewFunction { server } => { - if let Some(user) = db.users.get_mut(&server) { - user.server_stats.functions += 1; - } - } - }; - }) - .await; - } -} - -pub fn stats_thread(db: &SaveableDB) -> (impl Future, mpsc::Sender) { - let (tx, rx) = mpsc::channel(CHANNEL_CAPACITY); - let db = db.clone(); - let fut = async move { - stats_writer(&db, rx).await; - }; - (fut, tx) -} diff --git a/tools/decomp-permuter/src/net/controller/src/util.rs b/tools/decomp-permuter/src/net/controller/src/util.rs deleted file mode 100644 index 0194f2916..000000000 --- a/tools/decomp-permuter/src/net/controller/src/util.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::error::Error; -use std::future::Future; -use std::pin::Pin; -use std::task::{Context, Poll}; - -use pin_project::pin_project; - -pub type SimpleResult = Result>; - -#[pin_project] -pub struct NowOrNever { - #[pin] - inner: F, -} - -impl Future for NowOrNever { - type Output = Option; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - let ret = self.project().inner.poll(cx); - Poll::Ready(match ret { - Poll::Pending => None, - Poll::Ready(val) => Some(val), - }) - } -} - -impl FutureExt for T where T: Future {} - -pub trait FutureExt: Future { - fn now_or_never(self) -> NowOrNever - where - Self: Sized, - { - NowOrNever { inner: self } - } -} diff --git a/tools/decomp-permuter/src/net/controller/src/vouch.rs b/tools/decomp-permuter/src/net/controller/src/vouch.rs deleted file mode 100644 index 19bd3580d..000000000 --- a/tools/decomp-permuter/src/net/controller/src/vouch.rs +++ /dev/null @@ -1,80 +0,0 @@ -use std::str; - -use hex::FromHex; -use serde::Deserialize; -use serde_json::json; -use sodiumoxide::crypto::sign; - -use crate::db::{User, UserId}; -use crate::port::{ReadPort, WritePort}; -use crate::util::SimpleResult; -use crate::{concat, State}; - -#[derive(Debug, Deserialize)] -pub(crate) struct VouchData { - who: UserId, - signed_name: String, -} - -fn verify_with_magic<'a>( - magic: &[u8], - data: &'a [u8], - key: &sign::PublicKey, -) -> SimpleResult<&'a [u8]> { - if data.len() < 64 { - Err("signature too short")?; - } - let (signature, data) = data.split_at(64); - let signed_data = concat(magic, data); - let signature = sign::Signature::from_slice(signature).unwrap(); - if !sign::verify_detached(&signature, &signed_data, key) { - Err("bad signature")?; - } - Ok(data) -} - -fn parse_signed_name(signed_name: &str, who: &UserId) -> SimpleResult { - let signed_name = Vec::from_hex(signed_name).map_err(|_| "not a valid hex string")?; - let name_bytes = verify_with_magic(b"NAME:", &signed_name, &who.to_pubkey())?; - let name = str::from_utf8(name_bytes)?; - if name.is_empty() { - Err("name is empty")?; - } - if name.chars().any(char::is_control) { - Err("name cannot contain control characters")?; - } - Ok(name.to_string()) -} - -pub(crate) async fn handle_vouch<'a>( - mut read_port: ReadPort<'a>, - mut write_port: WritePort<'a>, - who_id: UserId, - who_name: &str, - state: &State, - data: VouchData, -) -> SimpleResult<()> { - let vouchee_name = match parse_signed_name(&data.signed_name, &data.who) { - Ok(name) => name, - Err(e) => { - write_port.send_error(&format!("{}", &e)).await?; - Err(e)? - } - }; - write_port.send_json(&json!({})).await?; - read_port.recv().await?; - state - .db - .write(true, |db| { - db.users.entry(data.who).or_insert_with(|| User { - trusted_by: Some(who_id), - name: vouchee_name.clone(), - client_stats: Default::default(), - server_stats: Default::default(), - }); - }) - .await; - write_port.send_json(&json!({})).await?; - eprintln!("[{}] vouch {}", who_name, &vouchee_name); - Ok(()) -} diff --git a/tools/decomp-permuter/src/net/core.py b/tools/decomp-permuter/src/net/core.py deleted file mode 100644 index c7f497d43..000000000 --- a/tools/decomp-permuter/src/net/core.py +++ /dev/null @@ -1,416 +0,0 @@ -import abc -from dataclasses import dataclass -import datetime -import json -import socket -import struct -import sys -import toml -import typing -from typing import BinaryIO, List, Optional, Type, TypeVar, Union - -from nacl.encoding import HexEncoder -from nacl.public import Box, PrivateKey, PublicKey -from nacl.secret import SecretBox -from nacl.signing import SigningKey, VerifyKey - -from ..error import ServerError -from ..helpers import exception_to_string - -T = TypeVar("T") -AnyBox = Union[Box, SecretBox] - -PERMUTER_VERSION = 2 - -CONFIG_FILENAME = "pah.conf" - -MIN_PRIO = 0.01 -MAX_PRIO = 2.0 - -DEBUG_MODE = False - - -def enable_debug_mode() -> None: - """Enable debug logging.""" - global DEBUG_MODE - DEBUG_MODE = True - - -def debug_print(message: str) -> None: - if DEBUG_MODE: - time = datetime.datetime.now().strftime("%H:%M:%S:%f") - print(f"\n{time} debug: {message}") - - -@dataclass(eq=False) -class CancelToken: - cancelled: bool = False - - -@dataclass -class PermuterData: - base_score: int - base_hash: str - fn_name: str - filename: str - keep_prob: float - need_profiler: bool - stack_differences: bool - compile_script: str - source: str - target_o_bin: bytes - - -def permuter_data_from_json( - obj: dict, source: str, target_o_bin: bytes -) -> PermuterData: - return PermuterData( - base_score=json_prop(obj, "base_score", int), - base_hash=json_prop(obj, "base_hash", str), - fn_name=json_prop(obj, "fn_name", str), - filename=json_prop(obj, "filename", str), - keep_prob=json_prop(obj, "keep_prob", float), - need_profiler=json_prop(obj, "need_profiler", bool), - stack_differences=json_prop(obj, "stack_differences", bool), - compile_script=json_prop(obj, "compile_script", str), - source=source, - target_o_bin=target_o_bin, - ) - - -def permuter_data_to_json(perm: PermuterData) -> dict: - return { - "base_score": perm.base_score, - "base_hash": perm.base_hash, - "fn_name": perm.fn_name, - "filename": perm.filename, - "keep_prob": perm.keep_prob, - "need_profiler": perm.need_profiler, - "stack_differences": perm.stack_differences, - "compile_script": perm.compile_script, - } - - -@dataclass -class Config: - server_address: Optional[str] = None - server_verify_key: Optional[VerifyKey] = None - signing_key: Optional[SigningKey] = None - initial_setup_nickname: Optional[str] = None - - -def read_config() -> Config: - config = Config() - try: - with open(CONFIG_FILENAME) as f: - obj = toml.load(f) - - def read(key: str, t: Type[T]) -> Optional[T]: - ret = obj.get(key) - return ret if isinstance(ret, t) else None - - temp = read("server_public_key", str) - if temp: - config.server_verify_key = VerifyKey(HexEncoder.decode(temp)) - temp = read("secret_key", str) - if temp: - config.signing_key = SigningKey(HexEncoder.decode(temp)) - config.initial_setup_nickname = read("initial_setup_nickname", str) - config.server_address = read("server_address", str) - except FileNotFoundError: - pass - except Exception: - print(f"Malformed configuration file {CONFIG_FILENAME}.\n") - raise - return config - - -def write_config(config: Config) -> None: - obj = {} - - def write(key: str, val: Union[None, str, int]) -> None: - if val is not None: - obj[key] = val - - write("initial_setup_nickname", config.initial_setup_nickname) - write("server_address", config.server_address) - - key_hex: bytes - if config.server_verify_key: - key_hex = config.server_verify_key.encode(HexEncoder) - write("server_public_key", key_hex.decode("utf-8")) - if config.signing_key: - key_hex = config.signing_key.encode(HexEncoder) - write("secret_key", key_hex.decode("utf-8")) - - with open(CONFIG_FILENAME, "w") as f: - toml.dump(obj, f) - - -def file_read_max(inf: BinaryIO, n: int) -> bytes: - try: - ret = [] - while n > 0: - data = inf.read(n) - if not data: - break - ret.append(data) - n -= len(data) - return b"".join(ret) - except Exception as e: - raise EOFError from e - - -def file_read_fixed(inf: BinaryIO, n: int) -> bytes: - ret = file_read_max(inf, n) - if len(ret) != n: - raise EOFError - return ret - - -def socket_read_max(sock: socket.socket, n: int) -> bytes: - try: - ret = [] - while n > 0: - data = sock.recv(min(n, 4096)) - if not data: - break - ret.append(data) - n -= len(data) - return b"".join(ret) - except Exception as e: - raise EOFError from e - - -def socket_read_fixed(sock: socket.socket, n: int) -> bytes: - ret = socket_read_max(sock, n) - if len(ret) != n: - raise EOFError - return ret - - -def socket_shutdown(sock: socket.socket, how: int) -> None: - try: - sock.shutdown(how) - except Exception: - pass - - -def json_prop(obj: dict, prop: str, t: Type[T]) -> T: - ret = obj.get(prop) - if not isinstance(ret, t): - if t is float and isinstance(ret, int): - return typing.cast(T, float(ret)) - found_type = type(ret).__name__ - if prop not in obj: - raise ValueError(f"Member {prop} does not exist") - raise ValueError(f"Member {prop} must have type {t.__name__}; got {found_type}") - return ret - - -def json_array(obj: list, t: Type[T]) -> List[T]: - for elem in obj: - if not isinstance(elem, t): - found_type = type(elem).__name__ - raise ValueError( - f"Array elements must have type {t.__name__}; got {found_type}" - ) - return obj - - -def sign_with_magic(magic: bytes, signing_key: SigningKey, data: bytes) -> bytes: - signature: bytes = signing_key.sign(magic + b":" + data).signature - return signature + data - - -def verify_with_magic(magic: bytes, verify_key: VerifyKey, data: bytes) -> bytes: - if len(data) < 64: - raise ValueError("String is too small to contain a signature") - signature = data[:64] - data = data[64:] - verify_key.verify(magic + b":" + data, signature) - return data - - -class Port(abc.ABC): - def __init__(self, box: AnyBox, who: str, *, is_client: bool) -> None: - self._box = box - self._who = who - self._send_nonce = 0 if is_client else 1 - self._receive_nonce = 1 if is_client else 0 - - @abc.abstractmethod - def _send(self, data: bytes) -> None: - ... - - @abc.abstractmethod - def _receive(self, length: int) -> bytes: - ... - - @abc.abstractmethod - def _receive_max(self, length: int) -> bytes: - ... - - def send(self, msg: bytes) -> None: - """Send a binary message, potentially blocking.""" - if DEBUG_MODE: - if len(msg) <= 300: - debug_print(f"Send to {self._who}: {msg!r}") - else: - debug_print(f"Send to {self._who}: {len(msg)} bytes") - nonce = struct.pack(">16xQ", self._send_nonce) - self._send_nonce += 2 - data = self._box.encrypt(msg, nonce).ciphertext - length_data = struct.pack(">Q", len(data)) - try: - self._send(length_data + data) - except BrokenPipeError: - raise EOFError from None - - def send_json(self, msg: dict) -> None: - """Send a message in the form of a JSON dict, potentially blocking.""" - self.send(json.dumps(msg).encode("utf-8")) - - def receive(self) -> bytes: - """Read a binary message, blocking.""" - length_data = self._receive(8) - if length_data[0]: - # Lengths above 2^56 are unreasonable, so if we get one someone is - # sending us bad data. Raise an exception to help debugging. - length_data += self._receive_max(1024) - raise Exception( - f"Got unexpected data from {self._who}: " + repr(length_data) - ) - length = struct.unpack(">Q", length_data)[0] - data = self._receive(length) - nonce = struct.pack(">16xQ", self._receive_nonce) - self._receive_nonce += 2 - msg: bytes = self._box.decrypt(data, nonce) - if DEBUG_MODE: - if len(msg) <= 300: - debug_print(f"Receive from {self._who}: {msg!r}") - else: - debug_print(f"Receive from {self._who}: {len(msg)} bytes") - return msg - - def receive_json(self) -> dict: - """Read a message in the form of a JSON dict, blocking.""" - ret = json.loads(self.receive()) - if isinstance(ret, str): - # Raw strings indicate errors. - raise ServerError(ret) - if not isinstance(ret, dict): - # We always pass dictionaries as messages and no other data types, - # to ensure future extensibility. (Other types are rare in - # practice, anyway.) - raise ValueError("Top-level JSON value must be a dictionary") - return ret - - -class SocketPort(Port): - def __init__( - self, sock: socket.socket, box: AnyBox, who: str, *, is_client: bool - ) -> None: - self._sock = sock - super().__init__(box, who, is_client=is_client) - - def _send(self, data: bytes) -> None: - self._sock.sendall(data) - - def _receive(self, length: int) -> bytes: - return socket_read_fixed(self._sock, length) - - def _receive_max(self, length: int) -> bytes: - return socket_read_max(self._sock, length) - - def shutdown(self, how: int = socket.SHUT_RDWR) -> None: - socket_shutdown(self._sock, how) - - def close(self) -> None: - self._sock.close() - - -class FilePort(Port): - def __init__( - self, inf: BinaryIO, outf: BinaryIO, box: AnyBox, who: str, *, is_client: bool - ) -> None: - self._inf = inf - self._outf = outf - super().__init__(box, who, is_client=is_client) - - def _send(self, data: bytes) -> None: - self._outf.write(data) - self._outf.flush() - - def _receive(self, length: int) -> bytes: - return file_read_fixed(self._inf, length) - - def _receive_max(self, length: int) -> bytes: - return file_read_max(self._inf, length) - - -def _do_connect(config: Config) -> SocketPort: - if ( - not config.server_verify_key - or not config.signing_key - or not config.server_address - ): - print( - "Using permuter@home requires someone to give you access to a central -J server.\n" - "Run `./pah.py setup` to set this up." - ) - print() - sys.exit(1) - - host, port_str = config.server_address.split(":") - try: - sock = socket.create_connection((host, int(port_str))) - except ConnectionRefusedError: - raise EOFError("connection refused") from None - except socket.gaierror as e: - raise EOFError(f"DNS lookup failed: {e}") from None - except Exception as e: - raise EOFError("unable to connect: " + exception_to_string(e)) from None - - # Send over the protocol version and an ephemeral encryption key which we - # are going to use for all communication. - ephemeral_key = PrivateKey.generate() - ephemeral_key_data = ephemeral_key.public_key.encode() - sock.sendall(b"p@h0" + ephemeral_key_data) - - # Receive the server's encryption key, plus a signature of it and our own - # ephemeral key -- this guarantees that we are talking to the server and - # aren't victim to a replay attack. Use it to set up a communication port. - msg = socket_read_fixed(sock, 32 + 64) - server_enc_key_data = msg[:32] - config.server_verify_key.verify( - b"HELLO:" + ephemeral_key_data + server_enc_key_data, msg[32:] - ) - box = Box(ephemeral_key, PublicKey(server_enc_key_data)) - port = SocketPort(sock, box, "controller", is_client=True) - - # Use the encrypted port to send over our public key, proof that we are - # able to sign new things with it, as well as permuter version. - signature: bytes = config.signing_key.sign( - b"WORLD:" + server_enc_key_data - ).signature - port.send( - config.signing_key.verify_key.encode() - + signature - + struct.pack(">I", PERMUTER_VERSION) - ) - - # Get an acknowledgement that the server wants to talk to us. - obj = port.receive_json() - - if "message" in obj: - print(obj["message"]) - - return port - - -def connect(config: Optional[Config] = None) -> SocketPort: - """Authenticate and connect to the permuter@home controller server.""" - if not config: - config = read_config() - return _do_connect(config) diff --git a/tools/decomp-permuter/src/net/evaluator.py b/tools/decomp-permuter/src/net/evaluator.py deleted file mode 100644 index e9138a6c7..000000000 --- a/tools/decomp-permuter/src/net/evaluator.py +++ /dev/null @@ -1,401 +0,0 @@ -"""This file runs as a free-standing program within a sandbox, and processes -permutation requests. It communicates with the outside world on stdin/stdout.""" -import base64 -from dataclasses import dataclass -import math -from multiprocessing import Process, Queue -import os -import queue -import sys -from tempfile import mkstemp -import threading -import time -import traceback -from typing import Counter, Dict, List, Optional, Set, Tuple, Union -import zlib - -from nacl.secret import SecretBox - -from ..candidate import CandidateResult -from ..compiler import Compiler -from ..error import CandidateConstructionFailure -from ..helpers import exception_to_string, static_assert_unreachable -from ..permuter import EvalError, EvalResult, Permuter -from ..profiler import Profiler -from ..scorer import Scorer -from .core import ( - FilePort, - PermuterData, - Port, - json_prop, - permuter_data_from_json, -) - - -def _fix_stdout() -> None: - """Redirect stdout to stderr to make print() debugging work. This function - *must* be called at startup for each (sub)process, since we use stdout for - our own communication purposes.""" - sys.stdout = sys.stderr - - # In addition, we set stderr to flush on newlines, which does not happen by - # default when it is piped. (Requires Python 3.7, but we can assume that's - # available inside the sandbox.) - sys.stdout.reconfigure(line_buffering=True) # type: ignore - - -def _setup_port(secret: bytes) -> Port: - """Set up communication with the outside world.""" - port = FilePort( - sys.stdin.buffer, - sys.stdout.buffer, - SecretBox(secret), - "server", - is_client=False, - ) - - _fix_stdout() - - # Follow the controlling process's sanity check protocol. - magic = port.receive() - port.send(magic) - - return port - - -def _create_permuter(data: PermuterData) -> Permuter: - fd, path = mkstemp(suffix=".o", prefix="permuter", text=False) - try: - with os.fdopen(fd, "wb") as f: - f.write(data.target_o_bin) - scorer = Scorer(target_o=path, stack_differences=data.stack_differences) - finally: - os.unlink(path) - - fd, path = mkstemp(suffix=".sh", prefix="permuter", text=True) - try: - os.chmod(fd, 0o755) - with os.fdopen(fd, "w") as f2: - f2.write(data.compile_script) - compiler = Compiler(compile_cmd=path, show_errors=False) - - return Permuter( - dir="unused", - fn_name=data.fn_name, - compiler=compiler, - scorer=scorer, - source_file=data.filename, - source=data.source, - force_seed=None, - force_rng_seed=None, - keep_prob=data.keep_prob, - need_profiler=data.need_profiler, - need_all_sources=False, - show_errors=False, - better_only=False, - best_only=False, - ) - except: - os.unlink(path) - raise - - -@dataclass -class AddPermuter: - perm_id: str - data: PermuterData - - -@dataclass -class AddPermuterLocal: - perm_id: str - permuter: Permuter - - -@dataclass -class RemovePermuter: - perm_id: str - - -@dataclass -class WorkDone: - perm_id: str - id: int - time_us: int - result: EvalResult - - -@dataclass -class Work: - perm_id: str - id: int - seed: int - - -LocalWork = Tuple[Union[AddPermuterLocal, RemovePermuter], int] -GlobalWork = Tuple[Work, int] -Task = Union[AddPermuter, RemovePermuter, Work, WorkDone] - - -def _remove_permuter(perm: Permuter) -> None: - os.unlink(perm.compiler.compile_cmd) - - -def _send_result(item: WorkDone, port: Port) -> None: - obj = { - "type": "result", - "permuter": item.perm_id, - "id": item.id, - "time_us": item.time_us, - } - - res = item.result - if isinstance(res, EvalError): - obj["error"] = res.exc_str - port.send_json(obj) - return - - compressed_source = getattr(res, "compressed_source") - - obj["score"] = res.score - obj["has_source"] = compressed_source is not None - if res.hash is not None: - obj["hash"] = res.hash - if res.profiler is not None: - obj["profiler"] = { - st.name: res.profiler.time_stats[st] for st in Profiler.StatType - } - - port.send_json(obj) - - if compressed_source is not None: - port.send(compressed_source) - - -def multiprocess_worker( - worker_queue: "Queue[GlobalWork]", - local_queue: "Queue[LocalWork]", - task_queue: "Queue[Task]", -) -> None: - _fix_stdout() - - # Prevent deadlocks in case the parent process dies. - worker_queue.cancel_join_thread() - local_queue.cancel_join_thread() - task_queue.cancel_join_thread() - - permuters: Dict[str, Permuter] = {} - timestamp = 0 - - while True: - work, required_timestamp = worker_queue.get() - while True: - try: - block = timestamp < required_timestamp - task, timestamp = local_queue.get(block=block) - except queue.Empty: - break - if isinstance(task, AddPermuterLocal): - permuters[task.perm_id] = task.permuter - elif isinstance(task, RemovePermuter): - del permuters[task.perm_id] - else: - static_assert_unreachable(task) - - time_before = time.time() - - permuter = permuters[work.perm_id] - result = permuter.try_eval_candidate(work.seed) - if isinstance(result, CandidateResult) and permuter.should_output(result): - permuter.record_result(result) - - # Compress the source within the worker. (Why waste a free - # multi-threading opportunity?) - if isinstance(result, CandidateResult): - compressed_source: Optional[bytes] = None - if result.source is not None: - compressed_source = zlib.compress(result.source.encode("utf-8")) - setattr(result, "compressed_source", compressed_source) - result.source = None - - time_us = int((time.time() - time_before) * 10 ** 6) - task_queue.put( - WorkDone(perm_id=work.perm_id, id=work.id, time_us=time_us, result=result) - ) - - -def read_loop(task_queue: "Queue[Task]", port: Port) -> None: - try: - while True: - item = port.receive_json() - msg_type = json_prop(item, "type", str) - if msg_type == "add": - perm_id = json_prop(item, "permuter", str) - source = port.receive().decode("utf-8") - target_o_bin = port.receive() - data = permuter_data_from_json(item, source, target_o_bin) - task_queue.put(AddPermuter(perm_id=perm_id, data=data)) - - elif msg_type == "remove": - perm_id = json_prop(item, "permuter", str) - task_queue.put(RemovePermuter(perm_id=perm_id)) - - elif msg_type == "work": - perm_id = json_prop(item, "permuter", str) - id = json_prop(item, "id", int) - seed = json_prop(item, "seed", int) - task_queue.put(Work(perm_id=perm_id, id=id, seed=seed)) - - else: - raise Exception(f"Invalid message type {msg_type}") - - except Exception as e: - # In case the port is closed from the other side, skip writing an ugly - # error message. - if not isinstance(e, EOFError): - traceback.print_exc() - - # Exit the whole process, to improve the odds that the Docker container - # really stops and gets removed. - # - # The parent server has a "finally:" that does that, but it's not 100% - # trustworthy. In particular, pystray has a tendency to hard-crash - # (which doesn't fire "finally"s), and also reverts the signal handler - # for SIGINT to the default on Linux, making Ctrl+C not run cleanup. - # Either way, defense in depth here doesn't hurt, since leaking Docker - # containers is pretty bad. - # - # Unfortunately this still doesn't fix the problem, since we typically - # don't get a port closure signal when the parent process stops... - # TODO: listen to heartbeats as well. - sys.exit(1) - - -def main() -> None: - secret = base64.b64decode(os.environ["SECRET"]) - del os.environ["SECRET"] - os.environ["PERMUTER_IS_REMOTE"] = "1" - - port = _setup_port(secret) - - obj = port.receive_json() - num_cores = json_prop(obj, "num_cores", float) - num_threads = math.ceil(num_cores) - - worker_queue: "Queue[GlobalWork]" = Queue() - task_queue: "Queue[Task]" = Queue() - local_queues: "List[Queue[LocalWork]]" = [] - - for i in range(num_threads): - local_queue: "Queue[LocalWork]" = Queue() - p = Process( - target=multiprocess_worker, - args=(worker_queue, local_queue, task_queue), - daemon=True, - ) - p.start() - local_queues.append(local_queue) - - reader_thread = threading.Thread( - target=read_loop, args=(task_queue, port), daemon=True - ) - reader_thread.start() - - remaining_work: Counter[str] = Counter() - should_remove: Set[str] = set() - permuters: Dict[str, Permuter] = {} - timestamp = 0 - - def try_remove(perm_id: str) -> None: - nonlocal timestamp - assert perm_id in permuters - if perm_id not in should_remove or remaining_work[perm_id] != 0: - return - del remaining_work[perm_id] - should_remove.remove(perm_id) - timestamp += 1 - for q in local_queues: - q.put((RemovePermuter(perm_id=perm_id), timestamp)) - _remove_permuter(permuters[perm_id]) - del permuters[perm_id] - - while True: - item = task_queue.get() - - if isinstance(item, AddPermuter): - assert item.perm_id not in permuters - - msg: Dict[str, object] = { - "type": "init", - "permuter": item.perm_id, - } - - time_before = time.time() - try: - # Construct a permuter. This involves a compilation on the main - # thread, which isn't great but we can live with it for now. - permuter = _create_permuter(item.data) - - if permuter.base_score != item.data.base_score: - _remove_permuter(permuter) - score_str = f"{permuter.base_score} vs {item.data.base_score}" - if permuter.base_hash == item.data.base_hash: - hash_str = "same hash; different Python or permuter versions?" - else: - hash_str = "different hash; different objdump versions?" - raise CandidateConstructionFailure( - f"mismatching score: {score_str} ({hash_str})" - ) - - permuters[item.perm_id] = permuter - - msg["success"] = True - msg["base_score"] = permuter.base_score - msg["base_hash"] = permuter.base_hash - - # Tell all the workers about the new permuter. - # TODO: ideally we would also seed their Candidate lru_cache's - # to avoid all workers having to parse the source... - timestamp += 1 - for q in local_queues: - q.put( - ( - AddPermuterLocal(perm_id=item.perm_id, permuter=permuter), - timestamp, - ) - ) - except Exception as e: - # This shouldn't practically happen, since the client compiled - # the code successfully. Print a message if it does. - msg["success"] = False - msg["error"] = exception_to_string(e) - if isinstance(e, CandidateConstructionFailure): - print(e.message) - else: - traceback.print_exc() - - msg["time_us"] = int((time.time() - time_before) * 10 ** 6) - port.send_json(msg) - - elif isinstance(item, RemovePermuter): - # Silently ignore requests to remove permuters that have already - # been removed, which can occur when AddPermuter fails. - if item.perm_id in permuters: - should_remove.add(item.perm_id) - try_remove(item.perm_id) - - elif isinstance(item, WorkDone): - remaining_work[item.perm_id] -= 1 - try_remove(item.perm_id) - _send_result(item, port) - - elif isinstance(item, Work): - remaining_work[item.perm_id] += 1 - worker_queue.put((item, timestamp)) - - else: - static_assert_unreachable(item) - - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/src/net/server.py b/tools/decomp-permuter/src/net/server.py deleted file mode 100644 index 65d0c0bea..000000000 --- a/tools/decomp-permuter/src/net/server.py +++ /dev/null @@ -1,944 +0,0 @@ -import base64 -from dataclasses import dataclass -import pathlib -import queue -import struct -import sys -import threading -import time -import traceback -from typing import BinaryIO, Dict, Optional, Set, Tuple, Union, TYPE_CHECKING -import zlib - -if TYPE_CHECKING: - import docker - -from nacl.secret import SecretBox -import nacl.utils - -from ..helpers import exception_to_string, static_assert_unreachable -from .core import ( - CancelToken, - Config, - PermuterData, - Port, - ServerError, - SocketPort, - connect, - file_read_fixed, - json_prop, - permuter_data_from_json, - permuter_data_to_json, -) - - -_HEARTBEAT_INTERVAL_SLACK_SEC: float = 50.0 - - -@dataclass -class Client: - id: str - nickname: str - - -@dataclass -class AddPermuter: - handle: int - time_start: float - client: Client - permuter_data: PermuterData - - -@dataclass -class RemovePermuter: - handle: int - - -@dataclass -class Work: - handle: int - id: int - time_start: float - seed: int - - -@dataclass -class ImmediateDisconnect: - handle: int - client: Client - reason: str - - -@dataclass -class Disconnect: - handle: int - - -@dataclass -class PermInitFail: - perm_id: str - error: str - - -@dataclass -class PermInitSuccess: - perm_id: str - base_score: int - base_hash: str - time_us: int - - -@dataclass -class WorkDone: - perm_id: str - id: int - obj: dict - time_us: int - compressed_source: Optional[bytes] - - -class NeedMoreWork: - pass - - -@dataclass -class NetThreadDisconnected: - graceful: bool - message: Optional[str] = None - - -class Heartbeat: - pass - - -class Shutdown: - pass - - -Activity = Union[ - AddPermuter, - RemovePermuter, - Work, - ImmediateDisconnect, - Disconnect, - PermInitFail, - PermInitSuccess, - WorkDone, - NeedMoreWork, - NetThreadDisconnected, - Heartbeat, - Shutdown, -] - - -@dataclass -class OutputInitFail: - handle: int - error: str - - -@dataclass -class OutputInitSuccess: - handle: int - time_us: int - base_score: int - base_hash: str - - -@dataclass -class OutputDisconnect: - handle: int - - -@dataclass -class OutputNeedMoreWork: - pass - - -@dataclass -class OutputWork: - handle: int - time_start: float - time_us: int - obj: dict - compressed_source: Optional[bytes] - - -Output = Union[ - OutputDisconnect, - OutputInitFail, - OutputInitSuccess, - OutputNeedMoreWork, - OutputWork, - Shutdown, -] - - -@dataclass -class IoConnect: - fn_name: str - client: Client - - -@dataclass -class IoDisconnect: - reason: str - - -@dataclass -class IoImmediateDisconnect: - reason: str - client: Client - - -class IoUserRemovePermuter: - pass - - -@dataclass -class IoServerFailed: - graceful: bool - message: Optional[str] - - -class IoReconnect: - pass - - -class IoShutdown: - pass - - -@dataclass -class IoWorkDone: - score: Optional[int] - is_improvement: bool - - -PermuterHandle = Tuple[int, CancelToken] -IoMessage = Union[ - IoConnect, IoDisconnect, IoImmediateDisconnect, IoUserRemovePermuter, IoWorkDone -] -IoGlobalMessage = Union[IoReconnect, IoShutdown, IoServerFailed] -IoActivity = Tuple[ - Optional[CancelToken], Union[Tuple[PermuterHandle, IoMessage], IoGlobalMessage] -] - - -@dataclass -class ServerOptions: - num_cores: float - max_memory_gb: float - min_priority: float - - -class NetThread: - _port: Optional[SocketPort] - _main_queue: "queue.Queue[Activity]" - _controller_queue: "queue.Queue[Output]" - _read_thread: "threading.Thread" - _write_thread: "threading.Thread" - _next_work_id: int - - def __init__( - self, - port: SocketPort, - main_queue: "queue.Queue[Activity]", - ) -> None: - self._port = port - self._main_queue = main_queue - self._controller_queue = queue.Queue() - self._next_work_id = 0 - - self._read_thread = threading.Thread(target=self.read_loop, daemon=True) - self._read_thread.start() - - self._write_thread = threading.Thread(target=self.write_loop, daemon=True) - self._write_thread.start() - - def stop(self) -> None: - if self._port is None: - return - try: - self._controller_queue.put(Shutdown()) - self._port.shutdown() - self._read_thread.join() - self._write_thread.join() - self._port.close() - self._port = None - except Exception: - print("Failed to stop net thread.") - traceback.print_exc() - - def send_controller(self, msg: Output) -> None: - self._controller_queue.put(msg) - - def _read_one(self) -> Activity: - assert self._port is not None - - msg = self._port.receive_json() - time_start = time.time() - - msg_type = json_prop(msg, "type", str) - - if msg_type == "heartbeat": - return Heartbeat() - - handle = json_prop(msg, "permuter", int) - - if msg_type == "work": - seed = json_prop(msg, "seed", int) - id = self._next_work_id - self._next_work_id += 1 - return Work(handle=handle, id=id, time_start=time_start, seed=seed) - - elif msg_type == "add": - client_id = json_prop(msg, "client_id", str) - client_name = json_prop(msg, "client_name", str) - client = Client(client_id, client_name) - data = json_prop(msg, "data", dict) - compressed_source = self._port.receive() - compressed_target_o_bin = self._port.receive() - - try: - source = zlib.decompress(compressed_source).decode("utf-8") - target_o_bin = zlib.decompress(compressed_target_o_bin) - permuter = permuter_data_from_json(data, source, target_o_bin) - except Exception as e: - # Client sent something illegible. This can legitimately happen if the - # client runs another version, but it's interesting to log. - traceback.print_exc() - return ImmediateDisconnect( - handle=handle, - client=client, - reason=f"Failed to parse permuter: {exception_to_string(e)}", - ) - - return AddPermuter( - handle=handle, - time_start=time_start, - client=client, - permuter_data=permuter, - ) - - elif msg_type == "remove": - return RemovePermuter(handle=handle) - - else: - raise Exception(f"Bad message type: {msg_type}") - - def read_loop(self) -> None: - try: - while True: - msg = self._read_one() - self._main_queue.put(msg) - except EOFError: - self._main_queue.put(NetThreadDisconnected(graceful=True)) - except ServerError as e: - self._main_queue.put( - NetThreadDisconnected(graceful=False, message=e.message) - ) - except Exception: - traceback.print_exc() - self._main_queue.put(NetThreadDisconnected(graceful=False)) - - def _write_one(self, item: Output) -> None: - assert self._port is not None - - if isinstance(item, Shutdown): - # Handled by caller - pass - - elif isinstance(item, OutputInitFail): - self._port.send_json( - { - "type": "update", - "permuter": item.handle, - "time_us": 0, - "update": {"type": "init_failed", "reason": item.error}, - } - ) - - elif isinstance(item, OutputInitSuccess): - self._port.send_json( - { - "type": "update", - "permuter": item.handle, - "time_us": item.time_us, - "update": {"type": "init_done", "hash": item.base_hash}, - } - ) - - elif isinstance(item, OutputDisconnect): - self._port.send_json( - { - "type": "update", - "permuter": item.handle, - "time_us": 0, - "update": {"type": "disconnect"}, - } - ) - - elif isinstance(item, OutputNeedMoreWork): - self._port.send_json({"type": "need_work"}) - - elif isinstance(item, OutputWork): - overhead_us = int((time.time() - item.time_start) * 10 ** 6) - item.time_us - self._port.send_json( - { - "type": "update", - "permuter": item.handle, - "time_us": item.time_us, - "update": { - "type": "work", - "overhead_us": overhead_us, - **item.obj, - }, - } - ) - if item.compressed_source is not None: - self._port.send(item.compressed_source) - - else: - static_assert_unreachable(item) - - def write_loop(self) -> None: - try: - while True: - item = self._controller_queue.get() - if isinstance(item, Shutdown): - break - self._write_one(item) - except EOFError: - self._main_queue.put(NetThreadDisconnected(graceful=True)) - except Exception: - traceback.print_exc() - self._main_queue.put(NetThreadDisconnected(graceful=False)) - - -class ServerInner: - """This class represents an up-and-running server, connected to the controller and - to the evaluator.""" - - _evaluator_port: "DockerPort" - _main_queue: "queue.Queue[Activity]" - _io_queue: "queue.Queue[IoActivity]" - _net_thread: NetThread - _read_eval_thread: threading.Thread - _main_thread: threading.Thread - _heartbeat_interval: float - _last_heartbeat: float - _last_heartbeat_lock: threading.Lock - _active: Set[int] - _time_starts: Dict[int, float] - _token: CancelToken - - def __init__( - self, - net_port: SocketPort, - evaluator_port: "DockerPort", - io_queue: "queue.Queue[IoActivity]", - heartbeat_interval: float, - ) -> None: - self._evaluator_port = evaluator_port - self._main_queue = queue.Queue() - self._io_queue = io_queue - self._active = set() - self._time_starts = {} - self._token = CancelToken() - - self._net_thread = NetThread(net_port, self._main_queue) - - # Start a thread for checking heartbeats. - self._heartbeat_interval = heartbeat_interval - self._last_heartbeat = time.time() - self._last_heartbeat_lock = threading.Lock() - self._heartbeat_stop = threading.Event() - self._heartbeat_thread = threading.Thread( - target=self._heartbeat_loop, daemon=True - ) - self._heartbeat_thread.start() - - # Start a thread for reading evaluator results and sending them on to - # the main loop queue. - self._read_eval_thread = threading.Thread( - target=self._read_eval_loop, daemon=True - ) - self._read_eval_thread.start() - - # Start a thread for the main loop. - self._main_thread = threading.Thread(target=self._main_loop, daemon=True) - self._main_thread.start() - - def _send_controller(self, msg: Output) -> None: - self._net_thread.send_controller(msg) - - def _send_io(self, handle: int, io_msg: IoMessage) -> None: - self._io_queue.put((self._token, ((handle, self._token), io_msg))) - - def _send_io_global(self, io_msg: IoGlobalMessage) -> None: - self._io_queue.put((self._token, io_msg)) - - def _handle_message(self, msg: Activity) -> None: - if isinstance(msg, Shutdown): - # Handled by caller - pass - - elif isinstance(msg, Heartbeat): - with self._last_heartbeat_lock: - self._last_heartbeat = time.time() - - elif isinstance(msg, Work): - if msg.handle not in self._active: - self._need_work() - return - - self._time_starts[msg.id] = msg.time_start - self._evaluator_port.send_json( - { - "type": "work", - "permuter": str(msg.handle), - "id": msg.id, - "seed": msg.seed, - } - ) - - elif isinstance(msg, AddPermuter): - if msg.handle in self._active: - raise Exception("Repeated AddPermuter!") - - self._active.add(msg.handle) - self._send_permuter(str(msg.handle), msg.permuter_data) - fn_name = msg.permuter_data.fn_name - self._send_io(msg.handle, IoConnect(fn_name, msg.client)) - - elif isinstance(msg, RemovePermuter): - if msg.handle not in self._active: - return - - self._remove(msg.handle) - self._send_io(msg.handle, IoDisconnect("disconnected")) - - elif isinstance(msg, Disconnect): - if msg.handle not in self._active: - return - - self._remove(msg.handle) - self._send_io(msg.handle, IoDisconnect("kicked")) - self._send_controller(OutputDisconnect(handle=msg.handle)) - - elif isinstance(msg, ImmediateDisconnect): - if msg.handle in self._active: - raise Exception("ImmediateDisconnect is not immediate") - - self._send_io(msg.handle, IoImmediateDisconnect(msg.reason, msg.client)) - self._send_controller(OutputInitFail(handle=msg.handle, error=msg.reason)) - - elif isinstance(msg, PermInitFail): - handle = int(msg.perm_id) - if handle not in self._active: - self._need_work() - return - - self._active.remove(handle) - self._send_io(handle, IoDisconnect("failed to compile")) - self._send_controller( - OutputInitFail( - handle=handle, - error=msg.error, - ) - ) - - elif isinstance(msg, PermInitSuccess): - handle = int(msg.perm_id) - if handle not in self._active: - self._need_work() - return - - self._send_controller( - OutputInitSuccess( - handle=handle, - time_us=msg.time_us, - base_score=msg.base_score, - base_hash=msg.base_hash, - ) - ) - - elif isinstance(msg, WorkDone): - handle = int(msg.perm_id) - time_start = self._time_starts.pop(msg.id) - if handle not in self._active: - self._need_work() - return - - obj = msg.obj - obj["permuter"] = handle - score = json_prop(obj, "score", int) if "score" in obj else None - is_improvement = msg.compressed_source is not None - self._send_io( - handle, - IoWorkDone(score=score, is_improvement=is_improvement), - ) - self._send_controller( - OutputWork( - handle=handle, - time_start=time_start, - time_us=msg.time_us, - obj=obj, - compressed_source=msg.compressed_source, - ) - ) - - elif isinstance(msg, NeedMoreWork): - self._need_work() - - elif isinstance(msg, NetThreadDisconnected): - self._send_io_global(IoServerFailed(msg.graceful, msg.message)) - - else: - static_assert_unreachable(msg) - - def _need_work(self) -> None: - self._send_controller(OutputNeedMoreWork()) - - def _remove(self, handle: int) -> None: - self._evaluator_port.send_json({"type": "remove", "permuter": str(handle)}) - self._active.remove(handle) - - def _send_permuter(self, perm_id: str, perm: PermuterData) -> None: - self._evaluator_port.send_json( - { - "type": "add", - "permuter": perm_id, - **permuter_data_to_json(perm), - } - ) - self._evaluator_port.send(perm.source.encode("utf-8")) - self._evaluator_port.send(perm.target_o_bin) - - def _do_read_eval_loop(self) -> None: - while True: - msg = self._evaluator_port.receive_json() - msg_type = json_prop(msg, "type", str) - - if msg_type == "init": - perm_id = json_prop(msg, "permuter", str) - time_us = json_prop(msg, "time_us", int) - resp: Activity - if json_prop(msg, "success", bool): - resp = PermInitSuccess( - perm_id=perm_id, - base_score=json_prop(msg, "base_score", int), - base_hash=json_prop(msg, "base_hash", str), - time_us=time_us, - ) - else: - resp = PermInitFail( - perm_id=perm_id, - error=json_prop(msg, "error", str), - ) - self._main_queue.put(resp) - - elif msg_type == "result": - compressed_source: Optional[bytes] = None - if msg.get("has_source") == True: - compressed_source = self._evaluator_port.receive() - perm_id = json_prop(msg, "permuter", str) - id = json_prop(msg, "id", int) - time_us = json_prop(msg, "time_us", int) - del msg["permuter"] - del msg["id"] - del msg["time_us"] - self._main_queue.put( - WorkDone( - perm_id=perm_id, - id=id, - obj=msg, - time_us=time_us, - compressed_source=compressed_source, - ) - ) - - else: - raise Exception(f"Unknown message type from evaluator: {msg_type}") - - def _read_eval_loop(self) -> None: - try: - self._do_read_eval_loop() - except EOFError: - # Silence errors from shutdown. - pass - - def _main_loop(self) -> None: - while True: - msg = self._main_queue.get() - if isinstance(msg, Shutdown): - break - - self._handle_message(msg) - - def _heartbeat_loop(self) -> None: - second_attempt = False - while True: - with self._last_heartbeat_lock: - delay = ( - self._last_heartbeat - + self._heartbeat_interval - + _HEARTBEAT_INTERVAL_SLACK_SEC / 2 - - time.time() - ) - if delay <= 0: - if second_attempt: - self._main_queue.put(NetThreadDisconnected(graceful=True)) - return - # Handle clock skew or computer going to sleep by waiting a bit - # longer before giving up. - second_attempt = True - if self._heartbeat_stop.wait(_HEARTBEAT_INTERVAL_SLACK_SEC / 2): - return - else: - second_attempt = False - if self._heartbeat_stop.wait(delay): - return - - def remove_permuter(self, handle: int) -> None: - assert not self._token.cancelled - self._main_queue.put(Disconnect(handle=handle)) - - def stop(self) -> None: - assert not self._token.cancelled - self._token.cancelled = True - self._main_queue.put(Shutdown()) - self._heartbeat_stop.set() - self._net_thread.stop() - self._evaluator_port.shutdown() - self._main_thread.join() - self._heartbeat_thread.join() - - -class DockerPort(Port): - """Port for communicating with Docker. Communication is encrypted for a few - not-very-good reasons: - - it allows code reuse - - it adds error-checking - - it was fun to implement""" - - _sock: BinaryIO - _container: "docker.models.containers.Container" - _stdout_buffer: bytes - _closed: bool - - def __init__( - self, container: "docker.models.containers.Container", secret: bytes - ) -> None: - self._container = container - self._stdout_buffer = b"" - self._closed = False - - # Set up a socket for reading from stdout/stderr and writing to - # stdin for the container. The docker package does not seem to - # expose an API for writing the stdin, but we can do so directly - # by attaching a socket and poking at internal state. (See - # https://github.com/docker/docker-py/issues/983.) For stdout/ - # stderr, we use the format described at - # https://docs.docker.com/engine/api/v1.24/#attach-to-a-container. - # - # Hopefully this will keep working for at least a while... - try: - self._sock = container.attach_socket( - params={"stdout": True, "stdin": True, "stderr": True, "stream": True} - ) - self._sock._writing = True # type: ignore - except: - try: - container.remove(force=True) - except Exception: - pass - raise - - super().__init__(SecretBox(secret), "docker", is_client=True) - - def shutdown(self) -> None: - import docker - - if self._closed: - return - self._closed = True - try: - self._sock.close() - self._container.remove(force=True) - except Exception as e: - if not ( - isinstance(e, docker.errors.APIError) - and e.status_code == 409 - and "is already in progress" in str(e) - ): - print("Failed to shut down Docker") - traceback.print_exc() - - def _read_one(self) -> None: - header = file_read_fixed(self._sock, 8) - stream, length = struct.unpack(">BxxxI", header) - if stream not in [1, 2]: - raise Exception("Unexpected output from Docker: " + repr(header)) - data = file_read_fixed(self._sock, length) - if stream == 1: - self._stdout_buffer += data - else: - sys.stderr.buffer.write(b"Docker stderr: " + data) - sys.stderr.buffer.flush() - - def _receive(self, length: int) -> bytes: - while len(self._stdout_buffer) < length: - self._read_one() - ret = self._stdout_buffer[:length] - self._stdout_buffer = self._stdout_buffer[length:] - return ret - - def _receive_max(self, length: int) -> bytes: - length = min(length, len(self._stdout_buffer)) - ret = self._stdout_buffer[:length] - self._stdout_buffer = self._stdout_buffer[length:] - return ret - - def _send(self, data: bytes) -> None: - while data: - written = self._sock.write(data) - data = data[written:] - self._sock.flush() - - -def _start_evaluator(docker_image: str, options: ServerOptions) -> DockerPort: - """Spawn a docker container and set it up to evaluate permutations in, - returning a handle that we can use to communicate with it. - - We do this for a few reasons: - - enforcing a known Linux environment, all while the outside server can run - on e.g. Windows and display a systray - - enforcing resource limits - - sandboxing - - Docker does have the downside of requiring root access, so ideally we would - also have a Docker-less mode, where we leave the sandboxing to some other - tool, e.g. https://github.com/ioi/isolate/.""" - print("Starting docker...") - command = ["python3", "-m", "src.net.evaluator"] - secret = nacl.utils.random(32) - enc_secret = base64.b64encode(secret).decode("utf-8") - src_path = pathlib.Path(__file__).parent.parent.absolute() - - try: - import docker - - client = docker.from_env() - client.info() - except ModuleNotFoundError: - print( - "Running a server requires the docker Python package to be installed.\n" - "Run `python3 -m pip install --upgrade docker`." - ) - sys.exit(1) - except Exception: - traceback.print_exc() - print() - print( - "Failed to start docker. Make sure you have docker installed and " - "the docker daemon running, and either run the permuter with sudo " - 'or add yourself to the "docker" UNIX group.' - ) - sys.exit(1) - - try: - container = client.containers.run( - docker_image, - command, - detach=True, - remove=True, - stdin_open=True, - stdout=True, - environment={"SECRET": enc_secret}, - volumes={src_path: {"bind": "/src", "mode": "ro"}}, - tmpfs={"/tmp": "size=1G,exec"}, - nano_cpus=int(options.num_cores * 1e9), - mem_limit=int(options.max_memory_gb * 2 ** 30), - read_only=True, - network_disabled=True, - ) - except Exception as e: - print(f"Failed to start docker container: {e}") - sys.exit(1) - - port = DockerPort(container, secret) - - try: - # Sanity-check that the Docker container started successfully and can - # be communicated with. - magic = b"\0" * 1000 - port.send(magic) - r = port.receive() - if r != magic: - raise Exception("Failed initial sanity check.") - - port.send_json({"num_cores": options.num_cores}) - except: - port.shutdown() - raise - - print("Started.") - return port - - -class Server: - """This class represents a server that may or may not be connected to the - controller and the evaluator.""" - - _server: Optional[ServerInner] - _options: ServerOptions - _config: Config - _io_queue: "queue.Queue[IoActivity]" - - def __init__( - self, - options: ServerOptions, - config: Config, - io_queue: "queue.Queue[IoActivity]", - ) -> None: - self._server = None - self._options = options - self._config = config - self._io_queue = io_queue - - def start(self) -> None: - assert self._server is None - - net_port = connect(self._config) - net_port.send_json( - { - "method": "connect_server", - "min_priority": self._options.min_priority, - "num_cores": self._options.num_cores, - } - ) - obj = net_port.receive_json() - docker_image = json_prop(obj, "docker_image", str) - heartbeat_interval = json_prop(obj, "heartbeat_interval", float) - - evaluator_port = _start_evaluator(docker_image, self._options) - - try: - self._server = ServerInner( - net_port, evaluator_port, self._io_queue, heartbeat_interval - ) - except: - evaluator_port.shutdown() - raise - - def stop(self) -> None: - if self._server is None: - return - self._server.stop() - self._server = None - - def remove_permuter(self, handle: PermuterHandle) -> None: - if self._server is not None and not handle[1].cancelled: - self._server.remove_permuter(handle[0]) diff --git a/tools/decomp-permuter/src/objdump.py b/tools/decomp-permuter/src/objdump.py deleted file mode 100644 index 09dab5fb7..000000000 --- a/tools/decomp-permuter/src/objdump.py +++ /dev/null @@ -1,224 +0,0 @@ -#!/usr/bin/env python3 -from dataclasses import dataclass, field -import os -import re -import string -import subprocess -import sys -from typing import List, Match, Pattern, Set, Tuple - -# Ignore registers, for cleaner output. (We don't do this right now, but it can -# be useful for debugging.) -ign_regs = False - -# Don't include branch targets in the output. Assuming our input is semantically -# equivalent skipping it shouldn't be an issue, and it makes insertions have too -# large effect. -ign_branch_targets = True - -# Skip branch-likely delay slots. (They aren't interesting on IDO.) -skip_bl_delay_slots = True - -skip_lines = 1 -re_int = re.compile(r"[0-9]+") -re_int_full = re.compile(r"\b[0-9]+\b") - - -@dataclass -class ArchSettings: - objdump: List[str] - re_comment: Pattern[str] - re_reg: Pattern[str] - re_sprel: Pattern[str] - re_includes_sp: Pattern[str] - branch_instructions: Set[str] - forbidden: Set[str] = field(default_factory=lambda: set(string.ascii_letters + "_")) - branch_likely_instructions: Set[str] = field(default_factory=set) - - -MIPS_BRANCH_LIKELY_INSTRUCTIONS = { - "beql", - "bnel", - "beqzl", - "bnezl", - "bgezl", - "bgtzl", - "blezl", - "bltzl", - "bc1tl", - "bc1fl", -} -MIPS_BRANCH_INSTRUCTIONS = { - "b", - "j", - "beq", - "bne", - "beqz", - "bnez", - "bgez", - "bgtz", - "blez", - "bltz", - "bc1t", - "bc1f", -}.union(MIPS_BRANCH_LIKELY_INSTRUCTIONS) - -MIPS_SETTINGS: ArchSettings = ArchSettings( - re_comment=re.compile(r"<.*?>"), - re_reg=re.compile( - r"\$?\b(a[0-3]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|k[01]|fp|ra)\b" # leave out $zero - ), - re_sprel=re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\((sp|s8)\)"), - re_includes_sp=re.compile(r"\b(sp|s8)\b"), - objdump=["mips-linux-gnu-objdump", "-drz", "-m", "mips:4300"], - branch_likely_instructions=MIPS_BRANCH_LIKELY_INSTRUCTIONS, - branch_instructions=MIPS_BRANCH_INSTRUCTIONS, -) - - -def get_arch(o_file: str) -> ArchSettings: - # https://refspecs.linuxfoundation.org/elf/gabi4+/ch4.eheader.html - with open(o_file, "rb") as f: - f.seek(18) - arch_magic = f.read(2) - if arch_magic == b"\0\x08": - return MIPS_SETTINGS - # TODO: support PPC ("\0\x14"), ARM ("0\x28") - raise Exception("Bad ELF") - - -def parse_relocated_line(line: str) -> Tuple[str, str, str]: - try: - ind2 = line.rindex(",") - except ValueError: - ind2 = line.rindex("\t") - before = line[: ind2 + 1] - after = line[ind2 + 1 :] - ind2 = after.find("(") - if ind2 == -1: - imm, after = after, "" - else: - imm, after = after[:ind2], after[ind2:] - if imm == "0x0": - imm = "0" - return before, imm, after - - -def simplify_objdump( - input_lines: List[str], arch: ArchSettings, *, stack_differences: bool -) -> List[str]: - output_lines: List[str] = [] - nops = 0 - skip_next = False - for index, row in enumerate(input_lines): - if index < skip_lines: - continue - row = row.rstrip() - if ">:" in row or not row: - continue - if "R_MIPS_" in row: - prev = output_lines[-1] - if prev == "": - continue - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - # As part of ignoring branch targets, we ignore relocations for j - # instructions. The target is already lost anyway. - if imm == "": - assert ign_branch_targets - continue - # Sometimes s8 is used as a non-framepointer, but we've already lost - # the immediate value by pretending it is one. This isn't too bad, - # since it's rare and applies consistently. But we do need to handle it - # here to avoid a crash, by pretending that lost imms are zero for - # relocations. - if imm != "0" and imm != "imm" and imm != "addr": - repl += "+" + imm if int(imm, 0) > 0 else imm - if any( - reloc in row - for reloc in ["R_MIPS_LO16", "R_MIPS_LITERAL", "R_MIPS_GPREL16"] - ): - 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})" - else: - assert "R_MIPS_26" in row, f"unknown relocation type '{row}'" - output_lines[-1] = before + repl + after - continue - row = re.sub(arch.re_comment, "", row) - row = row.rstrip() - row = "\t".join(row.split("\t")[2:]) # [20:] - if not row: - continue - if skip_next: - skip_next = False - row = "" - if ign_regs: - row = re.sub(arch.re_reg, "", row) - row_parts = row.split("\t") - if len(row_parts) == 1: - row_parts.append("") - mnemonic, instr_args = row_parts - if not stack_differences: - if mnemonic == "addiu" and arch.re_includes_sp.search(instr_args): - row = re.sub(re_int_full, "imm", row) - if mnemonic in arch.branch_instructions: - if ign_branch_targets: - instr_parts = instr_args.split(",") - instr_parts[-1] = "" - instr_args = ",".join(instr_parts) - row = f"{mnemonic}\t{instr_args}" - # The last part is in hex, so skip the dec->hex conversion - else: - - def fn(pat: Match[str]) -> str: - full = pat.group(0) - if len(full) <= 1: - return full - start, end = pat.span() - if start and row[start - 1] in arch.forbidden: - return full - if end < len(row) and row[end] in arch.forbidden: - return full - return hex(int(full)) - - row = re.sub(re_int, fn, row) - if mnemonic in arch.branch_likely_instructions and skip_bl_delay_slots: - skip_next = True - if not stack_differences: - row = re.sub(arch.re_sprel, "addr(sp)", row) - # row = row.replace(',', ', ') - if row == "nop": - # strip trailing nops; padding is irrelevant to us - nops += 1 - else: - for _ in range(nops): - output_lines.append("nop") - nops = 0 - output_lines.append(row) - return output_lines - - -def objdump( - o_filename: str, arch: ArchSettings, *, stack_differences: bool = False -) -> List[str]: - output = subprocess.check_output(arch.objdump + [o_filename]) - lines = output.decode("utf-8").splitlines() - return simplify_objdump(lines, arch, stack_differences=stack_differences) - - -if __name__ == "__main__": - if len(sys.argv) < 2: - print(f"Usage: {sys.argv[0]} file.o", file=sys.stderr) - sys.exit(1) - - if not os.path.isfile(sys.argv[1]): - print(f"Source file {sys.argv[1]} is not readable.", file=sys.stderr) - sys.exit(1) - - lines = objdump(sys.argv[1], MIPS_SETTINGS) - for row in lines: - print(row) diff --git a/tools/decomp-permuter/src/perm/ast.py b/tools/decomp-permuter/src/perm/ast.py deleted file mode 100644 index a4a14d6a1..000000000 --- a/tools/decomp-permuter/src/perm/ast.py +++ /dev/null @@ -1,58 +0,0 @@ -from typing import List, Optional, Tuple - -from .. import ast_util -from .perm import EvalState, Perm -from ..ast_util import Block, Statement -from ..error import CandidateConstructionFailure - -from pycparser import c_ast as ca - - -class _Done(Exception): - pass - - -def _apply_perm(fn: ca.FuncDef, perm_id: int, perm: Perm, seed: int) -> None: - """Find and apply a single late perm macro in the AST.""" - # Currently we search for statement macros only. - wanted_pragma = f"_permuter ast_perm {perm_id}" - Loc = Tuple[List[Statement], int] - - def try_handle_block(block: ca.Node, where: Optional[Loc]) -> None: - if not isinstance(block, ca.Compound) or not block.block_items: - return - pragma = block.block_items[0] - if not isinstance(pragma, ca.Pragma) or pragma.string != wanted_pragma: - return - - args: List[Statement] = block.block_items[1:] - stmts = perm.eval_statement_ast(args, seed) - - if where: - where[0][where[1] : where[1] + 1] = stmts - else: - block.block_items = stmts - raise _Done - - def rec(block: Block) -> None: - # if (x) { _Pragma(...); inputs } -> if (x) { outputs } - try_handle_block(block, None) - stmts = ast_util.get_block_stmts(block, False) - for i, stmt in enumerate(stmts): - # { ... { _Pragma(...); inputs } ... } -> { ... outputs ... } - try_handle_block(stmt, (stmts, i)) - ast_util.for_nested_blocks(stmt, rec) - - try: - rec(fn.body) - raise CandidateConstructionFailure("Failed to find PERM macro in AST.") - except _Done: - pass - - -def apply_ast_perms(fn: ca.FuncDef, eval_state: EvalState) -> None: - """Find all late perm macros in the AST and apply them.""" - # Nested perms will have smaller IDs, so apply the perms from lowest ID to - # highest to ensure that all arguments to perms have already been evaluated. - for perm_id, (perm, seed) in enumerate(eval_state.ast_perms): - _apply_perm(fn, perm_id, perm, seed) diff --git a/tools/decomp-permuter/src/perm/eval.py b/tools/decomp-permuter/src/perm/eval.py deleted file mode 100644 index b84dcd592..000000000 --- a/tools/decomp-permuter/src/perm/eval.py +++ /dev/null @@ -1,36 +0,0 @@ -import random -from typing import List, Iterable, Set, Tuple - -from .perm import Perm, EvalState - - -def _gen_all_seeds(total_count: int) -> Iterable[int]: - """Generate all numbers 0..total_count-1 in random order, in expected time - O(1) per number.""" - seen: Set[int] = set() - while len(seen) < total_count // 2: - seed = random.randrange(total_count) - if seed not in seen: - seen.add(seed) - yield seed - - remaining: List[int] = [] - for seed in range(total_count): - if seed not in seen: - remaining.append(seed) - random.shuffle(remaining) - for seed in remaining: - yield seed - - -def perm_gen_all_seeds(perm: Perm) -> Iterable[int]: - while True: - for seed in _gen_all_seeds(perm.perm_count): - yield seed - if not perm.is_random(): - break - - -def perm_evaluate_one(perm: Perm) -> Tuple[str, EvalState]: - eval_state = EvalState() - return perm.evaluate(0, eval_state), eval_state diff --git a/tools/decomp-permuter/src/perm/parse.py b/tools/decomp-permuter/src/perm/parse.py deleted file mode 100644 index dd5a4838d..000000000 --- a/tools/decomp-permuter/src/perm/parse.py +++ /dev/null @@ -1,144 +0,0 @@ -from typing import Callable, Dict, List, Tuple -import re - -from .perm import ( - CombinePerm, - GeneralPerm, - IgnorePerm, - IntPerm, - LineSwapPerm, - LineSwapAstPerm, - OncePerm, - Perm, - PretendPerm, - RandomizerPerm, - RootPerm, - TextPerm, - VarPerm, -) - - -def _split_by_comma(text: str) -> List[str]: - level = 0 - current = "" - args: List[str] = [] - for c in text: - if c == "," and level == 0: - args.append(current) - current = "" - else: - if c == "(": - level += 1 - elif c == ")": - level -= 1 - assert level >= 0, "Bad nesting" - current += c - assert level == 0, "Mismatched parentheses" - args.append(current) - return args - - -def _split_args(text: str) -> List[Perm]: - perm_args = [_rec_perm_parse(arg) for arg in _split_by_comma(text)] - return perm_args - - -def _split_args_newline(text: str) -> List[Perm]: - return [_rec_perm_parse(line) for line in text.split("\n") if line.strip()] - - -def _split_args_text(text: str) -> List[str]: - perm_list = _split_args(text) - res: List[str] = [] - for perm in perm_list: - assert isinstance(perm, TextPerm) - res.append(perm.text) - return res - - -def _make_once_perm(text: str) -> OncePerm: - args = _split_by_comma(text) - if len(args) not in [1, 2]: - raise Exception("PERM_ONCE takes 1 or 2 arguments") - key = args[0].strip() - value = _rec_perm_parse(args[-1]) - return OncePerm(key, value) - - -def _make_var_perm(text: str) -> VarPerm: - args = _split_by_comma(text) - if len(args) not in [1, 2]: - raise Exception("PERM_VAR takes 1 or 2 arguments") - var_name = _rec_perm_parse(args[0]) - value = _rec_perm_parse(args[1]) if len(args) == 2 else None - return VarPerm(var_name, value) - - -PERM_FACTORIES: Dict[str, Callable[[str], Perm]] = { - "PERM_GENERAL": lambda text: GeneralPerm(_split_args(text)), - "PERM_ONCE": lambda text: _make_once_perm(text), - "PERM_RANDOMIZE": lambda text: RandomizerPerm(_rec_perm_parse(text)), - "PERM_VAR": lambda text: _make_var_perm(text), - "PERM_LINESWAP_TEXT": lambda text: LineSwapPerm(_split_args_newline(text)), - "PERM_LINESWAP": lambda text: LineSwapAstPerm(_split_args_newline(text)), - "PERM_INT": lambda text: IntPerm(*map(int, _split_args_text(text))), - "PERM_IGNORE": lambda text: IgnorePerm(_rec_perm_parse(text)), - "PERM_PRETEND": lambda text: PretendPerm(_rec_perm_parse(text)), -} - - -def _consume_arg_parens(text: str) -> Tuple[str, str]: - level = 0 - for i, c in enumerate(text): - if c == "(": - level += 1 - elif c == ")": - level -= 1 - if level == -1: - return text[:i], text[i + 1 :] - raise Exception("Failed to find closing parenthesis when parsing PERM macro") - - -def _rec_perm_parse(text: str) -> Perm: - remain = text - macro_search = r"(PERM_.+?)\(" - - perms: List[Perm] = [] - while len(remain) > 0: - match = re.search(macro_search, remain) - - # No match found; return remaining - if match is None: - text_perm = TextPerm(remain) - perms.append(text_perm) - break - - # Get perm type and args - perm_type = match.group(1) - if perm_type not in PERM_FACTORIES: - raise Exception("Unrecognized PERM macro: " + perm_type) - between = remain[: match.start()] - args, remain = _consume_arg_parens(remain[match.end() :]) - - # Create text perm - perms.append(TextPerm(between)) - - # Create new perm - perms.append(PERM_FACTORIES[perm_type](args)) - - if len(perms) == 1: - return perms[0] - return CombinePerm(perms) - - -def perm_parse(text: str) -> Perm: - ret = _rec_perm_parse(text) - if isinstance(ret, TextPerm): - ret = RandomizerPerm(ret) - print("No perm macros found. Defaulting to randomization.") - ret = RootPerm(ret) - if not ret.is_random(): - print(f"Will run for {ret.perm_count} iterations.") - else: - print(f"Will try {ret.perm_count} different base sources.") - return ret diff --git a/tools/decomp-permuter/src/perm/perm.py b/tools/decomp-permuter/src/perm/perm.py deleted file mode 100644 index 61cc6c21c..000000000 --- a/tools/decomp-permuter/src/perm/perm.py +++ /dev/null @@ -1,289 +0,0 @@ -from base64 import b64encode -from collections import defaultdict -from dataclasses import dataclass, field -from typing import Dict, List, Tuple, TypeVar, Optional -import math - -from pycparser import c_ast as ca - -from ..ast_util import Statement - -T = TypeVar("T") - - -@dataclass -class PreprocessState: - once_options: Dict[str, List["Perm"]] = field( - default_factory=lambda: defaultdict(list) - ) - - -@dataclass -class EvalState: - vars: Dict[str, str] = field(default_factory=dict) - once_choices: Dict[str, "Perm"] = field(default_factory=dict) - ast_perms: List[Tuple["Perm", int]] = field(default_factory=list) - - def register_ast_perm(self, perm: "Perm", seed: int) -> int: - ret = len(self.ast_perms) - self.ast_perms.append((perm, seed)) - return ret - - def gen_ast_statement_perm( - self, perm: "Perm", seed: int, *, statements: List[str] - ) -> str: - perm_id = self.register_ast_perm(perm, seed) - lines = [ - "{", - f"#pragma _permuter ast_perm {perm_id}", - *["{" + stmt + "}" for stmt in statements], - "}", - ] - return "\n".join(lines) - - -class Perm: - """A Perm subclass generates different variations of a part of the source - code. Its evaluate method will be called with a seed between 0 and - perm_count-1, and it should return a unique string for each. - - A Perm is allowed to return different strings for the same seed, but if so, - if should override is_random to return True. This will cause permutation - to happen in an infinite loop, rather than stop after the last permutation - has been tested.""" - - perm_count: int - children: List["Perm"] - - def evaluate(self, seed: int, state: EvalState) -> str: - return "" - - def eval_statement_ast(self, args: List[Statement], seed: int) -> List[Statement]: - raise NotImplementedError - - def preprocess(self, state: PreprocessState) -> None: - for p in self.children: - p.preprocess(state) - - def is_random(self) -> bool: - return any(p.is_random() for p in self.children) - - -def _eval_all(seed: int, perms: List[Perm], state: EvalState) -> List[str]: - ret = [] - for p in perms: - seed, sub_seed = divmod(seed, p.perm_count) - ret.append(p.evaluate(sub_seed, state)) - assert seed == 0, "seed must be in [0, prod(counts))" - return ret - - -def _count_all(perms: List[Perm]) -> int: - res = 1 - for p in perms: - res *= p.perm_count - return res - - -def _eval_either(seed: int, perms: List[Perm], state: EvalState) -> str: - for p in perms: - if seed < p.perm_count: - return p.evaluate(seed, state) - seed -= p.perm_count - assert False, "seed must be in [0, sum(counts))" - - -def _count_either(perms: List[Perm]) -> int: - return sum(p.perm_count for p in perms) - - -def _shuffle(items: List[T], seed: int) -> List[T]: - items = items[:] - output = [] - while items: - ind = seed % len(items) - seed //= len(items) - output.append(items[ind]) - del items[ind] - return output - - -class RootPerm(Perm): - def __init__(self, inner: Perm) -> None: - self.children = [inner] - self.perm_count = inner.perm_count - self.preprocess_state = PreprocessState() - self.preprocess(self.preprocess_state) - for key, options in self.preprocess_state.once_options.items(): - if len(options) == 1: - raise Exception(f"PERM_ONCE({key}) occurs only once, possible error?") - self.perm_count *= len(options) - - def evaluate(self, seed: int, state: EvalState) -> str: - for key, options in self.preprocess_state.once_options.items(): - seed, choice = divmod(seed, len(options)) - state.once_choices[key] = options[choice] - return self.children[0].evaluate(seed, state) - - -class TextPerm(Perm): - def __init__(self, text: str) -> None: - # Comma escape sequence - text = text.replace("(,)", ",") - self.text = text - self.children = [] - self.perm_count = 1 - - def evaluate(self, seed: int, state: EvalState) -> str: - return self.text - - -class IgnorePerm(Perm): - def __init__(self, inner: Perm) -> None: - self.children = [inner] - self.perm_count = inner.perm_count - - def evaluate(self, seed: int, state: EvalState) -> str: - text = self.children[0].evaluate(seed, state) - if not text: - return "" - encoded = b64encode(text.encode("utf-8")).decode("ascii") - return "#pragma _permuter b64literal " + encoded - - -class PretendPerm(Perm): - def __init__(self, inner: Perm) -> None: - self.children = [inner] - self.perm_count = inner.perm_count - - def evaluate(self, seed: int, state: EvalState) -> str: - text = self.children[0].evaluate(seed, state) - return "\n".join( - [ - "", - "#pragma _permuter latedefine start", - text, - "#pragma _permuter latedefine end", - "", - ] - ) - - -class CombinePerm(Perm): - def __init__(self, parts: List[Perm]) -> None: - self.children = parts - self.perm_count = _count_all(parts) - - def evaluate(self, seed: int, state: EvalState) -> str: - texts = _eval_all(seed, self.children, state) - return "".join(texts) - - -class RandomizerPerm(Perm): - def __init__(self, inner: Perm) -> None: - self.children = [inner] - self.perm_count = inner.perm_count - - def evaluate(self, seed: int, state: EvalState) -> str: - text = self.children[0].evaluate(seed, state) - return "\n".join( - [ - "", - "#pragma _permuter randomizer start", - text, - "#pragma _permuter randomizer end", - "", - ] - ) - - def is_random(self) -> bool: - return True - - -class GeneralPerm(Perm): - def __init__(self, candidates: List[Perm]) -> None: - self.perm_count = _count_either(candidates) - self.children = candidates - - def evaluate(self, seed: int, state: EvalState) -> str: - return _eval_either(seed, self.children, state) - - -class OncePerm(Perm): - def __init__(self, key: str, inner: Perm) -> None: - self.key = key - self.children = [inner] - self.perm_count = inner.perm_count - - def preprocess(self, state: PreprocessState) -> None: - state.once_options[self.key].append(self) - super().preprocess(state) - - def evaluate(self, seed: int, state: EvalState) -> str: - if state.once_choices[self.key] is self: - return self.children[0].evaluate(seed, state) - return "" - - -class VarPerm(Perm): - def __init__(self, var_name: Perm, expansion: Optional[Perm]) -> None: - if expansion: - self.children = [var_name, expansion] - else: - self.children = [var_name] - self.perm_count = _count_all(self.children) - - def evaluate(self, seed: int, state: EvalState) -> str: - var_name_perm = self.children[0] - seed, sub_seed = divmod(seed, var_name_perm.perm_count) - var_name = var_name_perm.evaluate(sub_seed, state).strip() - if len(self.children) > 1: - ret = self.children[1].evaluate(seed, state) - state.vars[var_name] = ret - return "" - else: - if var_name not in state.vars: - raise Exception(f"Tried to read undefined PERM_VAR {var_name}") - return state.vars[var_name] - - -class LineSwapPerm(Perm): - def __init__(self, lines: List[Perm]) -> None: - self.children = lines - self.own_count = math.factorial(len(lines)) - self.perm_count = self.own_count * _count_all(self.children) - - def evaluate(self, seed: int, state: EvalState) -> str: - sub_seed, variation = divmod(seed, self.own_count) - texts = _eval_all(sub_seed, self.children, state) - return "\n".join(_shuffle(texts, variation)) - - -class LineSwapAstPerm(Perm): - def __init__(self, lines: List[Perm]) -> None: - self.children = lines - self.own_count = math.factorial(len(lines)) - self.perm_count = self.own_count * _count_all(self.children) - - def evaluate(self, seed: int, state: EvalState) -> str: - sub_seed, variation = divmod(seed, self.own_count) - texts = _eval_all(sub_seed, self.children, state) - return state.gen_ast_statement_perm(self, variation, statements=texts) - - def eval_statement_ast(self, args: List[Statement], seed: int) -> List[Statement]: - ret = [] - for item in _shuffle(args, seed): - assert isinstance(item, ca.Compound) - ret.extend(item.block_items or []) - return ret - - -class IntPerm(Perm): - def __init__(self, low: int, high: int) -> None: - assert low <= high - self.low = low - self.children = [] - self.perm_count = high - low + 1 - - def evaluate(self, seed: int, state: EvalState) -> str: - return str(self.low + seed) diff --git a/tools/decomp-permuter/src/permuter.py b/tools/decomp-permuter/src/permuter.py deleted file mode 100644 index 143b98178..000000000 --- a/tools/decomp-permuter/src/permuter.py +++ /dev/null @@ -1,279 +0,0 @@ -from dataclasses import dataclass -import difflib -import itertools -import random -import re -import time -import traceback -from typing import ( - Any, - List, - Iterator, - Optional, - Tuple, - Union, -) - -from .candidate import Candidate, CandidateResult -from .compiler import Compiler -from .error import CandidateConstructionFailure -from .perm.perm import EvalState -from .perm.eval import perm_evaluate_one, perm_gen_all_seeds -from .perm.parse import perm_parse -from .profiler import Profiler -from .scorer import Scorer - - -@dataclass -class EvalError: - exc_str: Optional[str] - seed: Optional[Tuple[int, int]] - - -EvalResult = Union[CandidateResult, EvalError] - - -@dataclass -class Finished: - reason: Optional[str] = None - - -@dataclass -class Message: - text: str - - -class NeedMoreWork: - pass - - -class _CompileFailure(Exception): - pass - - -@dataclass -class WorkDone: - perm_index: int - result: EvalResult - - -Task = Union[Finished, Tuple[int, int]] -FeedbackItem = Union[Finished, Message, NeedMoreWork, WorkDone] -Feedback = Tuple[FeedbackItem, int, Optional[str]] - - -class Permuter: - """ - Represents a single source from which permutation candidates can be generated, - and which keeps track of good scores achieved so far. - """ - - def __init__( - self, - dir: str, - fn_name: Optional[str], - compiler: Compiler, - scorer: Scorer, - source_file: str, - source: str, - *, - force_seed: Optional[int], - force_rng_seed: Optional[int], - keep_prob: float, - need_profiler: bool, - need_all_sources: bool, - show_errors: bool, - best_only: bool, - better_only: bool, - ) -> None: - self.dir = dir - self.compiler = compiler - self.scorer = scorer - self.source_file = source_file - self.source = source - - if fn_name is None: - # Semi-legacy codepath; all functions imported through import.py have a - # function name. This would ideally be done on AST level instead of on the - # pre-macro'ed source code, but we don't care enough to make that - # refactoring. - fns = _find_fns(source) - if len(fns) == 0: - raise Exception(f"{self.source_file} does not contain any function!") - if len(fns) > 1: - raise Exception( - f"{self.source_file} must contain only one function, " - "or have a function.txt next to it with a function name." - ) - self.fn_name = fns[0] - else: - self.fn_name = fn_name - self.unique_name = self.fn_name - - self._permutations = perm_parse(source) - - self._force_seed = force_seed - self._force_rng_seed = force_rng_seed - self._cur_seed: Optional[Tuple[int, int]] = None - - self.keep_prob = keep_prob - self.need_profiler = need_profiler - self._need_all_sources = need_all_sources - self._show_errors = show_errors - self._best_only = best_only - self._better_only = better_only - - ( - self.base_score, - self.base_hash, - self.base_source, - ) = self._create_and_score_base() - self.best_score = self.base_score - self.hashes = {self.base_hash} - self._cur_cand: Optional[Candidate] = None - self._last_score: Optional[int] = None - - def _create_and_score_base(self) -> Tuple[int, str, str]: - base_source, eval_state = perm_evaluate_one(self._permutations) - base_cand = Candidate.from_source( - base_source, eval_state, self.fn_name, rng_seed=0 - ) - o_file = base_cand.compile(self.compiler, show_errors=True) - if not o_file: - raise CandidateConstructionFailure(f"Unable to compile {self.source_file}") - base_result = base_cand.score(self.scorer, o_file) - assert base_result.hash is not None - return base_result.score, base_result.hash, base_cand.get_source() - - def _need_to_send_source(self, result: CandidateResult) -> bool: - return self._need_all_sources or self.should_output(result) - - def _eval_candidate(self, seed: int) -> CandidateResult: - t0 = time.time() - - # Determine if we should keep the last candidate. - # Don't keep 0-score candidates; we'll only create new, worse, zeroes. - keep = ( - self._permutations.is_random() - and random.uniform(0, 1) < self.keep_prob - and self._last_score != 0 - and self._last_score != self.scorer.PENALTY_INF - ) or self._force_rng_seed - - self._last_score = None - - # Create a new candidate if we didn't keep the last one (or if the last one didn't exist) - # N.B. if we decide to keep the previous candidate, we will skip over the provided seed. - # This means we're not guaranteed to test all seeds, but it doesn't really matter since - # we're randomizing anyway. - if not self._cur_cand or not keep: - eval_state = EvalState() - cand_c = self._permutations.evaluate(seed, eval_state) - rng_seed = self._force_rng_seed or random.randrange(1, 10 ** 20) - self._cur_seed = (seed, rng_seed) - self._cur_cand = Candidate.from_source( - cand_c, eval_state, self.fn_name, rng_seed=rng_seed - ) - - # Randomize the candidate - if self._permutations.is_random(): - self._cur_cand.randomize_ast() - - t1 = time.time() - - self._cur_cand.get_source() - - t2 = time.time() - - o_file = self._cur_cand.compile(self.compiler) - if not o_file and self._show_errors: - raise _CompileFailure() - - t3 = time.time() - - result = self._cur_cand.score(self.scorer, o_file) - - t4 = time.time() - - if self.need_profiler: - profiler = Profiler() - profiler.add_stat(Profiler.StatType.perm, t1 - t0) - profiler.add_stat(Profiler.StatType.stringify, t2 - t1) - profiler.add_stat(Profiler.StatType.compile, t3 - t2) - profiler.add_stat(Profiler.StatType.score, t4 - t3) - result.profiler = profiler - - self._last_score = result.score - - if not self._need_to_send_source(result): - result.source = None - result.hash = None - - return result - - def should_output(self, result: CandidateResult) -> bool: - """Check whether a result should be outputted. This must be more liberal - in child processes than in parent ones, or else sources will be missing.""" - return ( - result.score <= self.base_score - and result.hash is not None - and result.source is not None - and not (result.score > self.best_score and self._best_only) - and ( - result.score < self.base_score - or (result.score == self.base_score and not self._better_only) - ) - and result.hash not in self.hashes - ) - - def record_result(self, result: CandidateResult) -> None: - """Record a new result, updating the best score and adding the hash to - the set of hashes we have already seen. No hash is recorded for score - 0, since we are interested in all score 0's, not just the first.""" - self.best_score = min(self.best_score, result.score) - if result.score != 0 and result.hash is not None: - self.hashes.add(result.hash) - - def seed_iterator(self) -> Iterator[int]: - """Create an iterator over all seeds for this permuter. The iterator - will be infinite if we are randomizing.""" - if self._force_seed is None: - return iter(perm_gen_all_seeds(self._permutations)) - if self._permutations.is_random(): - return itertools.repeat(self._force_seed) - return iter([self._force_seed]) - - def try_eval_candidate(self, seed: int) -> EvalResult: - """Evaluate a seed for the permuter.""" - try: - return self._eval_candidate(seed) - except _CompileFailure: - return EvalError(exc_str=None, seed=self._cur_seed) - except Exception: - return EvalError(exc_str=traceback.format_exc(), seed=self._cur_seed) - - def diff(self, other_source: str) -> str: - """Compute a unified white-space-ignoring diff from the (pretty-printed) - base source against another source generated from this permuter.""" - - class Line(str): - def __eq__(self, other: Any) -> bool: - return isinstance(other, str) and self.strip() == other.strip() - - def __hash__(self) -> int: - return hash(self.strip()) - - a = list(map(Line, self.base_source.split("\n"))) - b = list(map(Line, other_source.split("\n"))) - return "\n".join( - difflib.unified_diff(a, b, fromfile="before", tofile="after", lineterm="") - ) - - -def _find_fns(source: str) -> List[str]: - fns = re.findall(r"(\w+)\([^()\n]*\)\s*?{", source) - return [ - fn - for fn in fns - if not fn.startswith("PERM") and fn not in ["if", "for", "switch", "while"] - ] diff --git a/tools/decomp-permuter/src/preprocess.py b/tools/decomp-permuter/src/preprocess.py deleted file mode 100644 index 214d359c8..000000000 --- a/tools/decomp-permuter/src/preprocess.py +++ /dev/null @@ -1,10 +0,0 @@ -from typing import List -import subprocess - - -def preprocess(filename: str, cpp_args: List[str] = []) -> str: - return subprocess.check_output( - ["cpp"] + cpp_args + ["-P", "-nostdinc", filename], - universal_newlines=True, - encoding="utf-8", - ) diff --git a/tools/decomp-permuter/src/printer.py b/tools/decomp-permuter/src/printer.py deleted file mode 100644 index 804e63c15..000000000 --- a/tools/decomp-permuter/src/printer.py +++ /dev/null @@ -1,46 +0,0 @@ -from typing import Optional - -from .permuter import Permuter - -# Number of additional characters to replace with spaces, in addition to what -# is required based on the length of the previous progress line. This could be -# set to 0, but it's nice to have some margin to deal with e.g. zero-width -# control characters. -SAFETY_PAD = 10 - - -class Printer: - _last_progress: Optional[str] = None - - def progress(self, message: str) -> None: - if self._last_progress is None: - clear = "" - else: - pad = max(len(self._last_progress) - len(message) + SAFETY_PAD, 0) - clear = "\b" * pad + " " * pad + "\r" - print(clear + message, end="", flush=True) - self._last_progress = message - - def print( - self, - message: str, - permuter: Optional[Permuter], - who: Optional[str], - *, - color: str = "", - keep_progress: bool = False, - ) -> None: - if self._last_progress is not None: - if keep_progress: - print() - else: - pad = len(self._last_progress) + SAFETY_PAD - print("\r" + " " * pad + "\r", end="") - if permuter is not None: - message = f"[{permuter.unique_name}] {message}" - if who is not None: - message = f"[{who}] {message}" - if color: - message = f"{color}{message}\u001b[0m" - print(message) - self._last_progress = None diff --git a/tools/decomp-permuter/src/profiler.py b/tools/decomp-permuter/src/profiler.py deleted file mode 100644 index 974b3b988..000000000 --- a/tools/decomp-permuter/src/profiler.py +++ /dev/null @@ -1,23 +0,0 @@ -from enum import Enum - - -class Profiler: - class StatType(Enum): - perm = 1 - stringify = 2 - compile = 3 - score = 4 - - def __init__(self) -> None: - self.time_stats = {x: 0.0 for x in Profiler.StatType} - - def add_stat(self, stat: StatType, time_taken: float) -> None: - self.time_stats[stat] += time_taken - - def get_str_stats(self) -> str: - total_time = sum(self.time_stats[e] for e in self.time_stats) - timings = ", ".join( - f"{round(100 * self.time_stats[e] / total_time)}% {e.name}" - for e in self.time_stats - ) - return timings diff --git a/tools/decomp-permuter/src/randomizer.py b/tools/decomp-permuter/src/randomizer.py deleted file mode 100644 index 1eb59f22b..000000000 --- a/tools/decomp-permuter/src/randomizer.py +++ /dev/null @@ -1,1940 +0,0 @@ -import bisect -import copy -from dataclasses import dataclass, field -from random import Random -import typing -from typing import ( - Any, - Callable, - Dict, - List, - Optional, - Sequence, - Set, - Tuple, - TypeVar, - Union, -) - -from pycparser import c_ast as ca - -from . import ast_util -from .ast_util import Block, Indices, Statement, Expression -from .ast_types import ( - SimpleType, - Type, - TypeMap, - allowed_basic_type, - build_typemap, - decayed_expr_type, - get_decl_type, - resolve_typedefs, - same_type, - set_decl_name, - pointer_decay, -) - -# Set to true to perform expression type detection eagerly. This can help when -# debugging crashes in the ast_types code. -DEBUG_EAGER_TYPES = False - -# Randomize the type of introduced temporary variable with this probability -PROB_RANDOMIZE_TYPE = 0.3 - -# Reuse an existing var instead of introducing a new temporary one with this probability -PROB_REUSE_VAR = 0.5 - -# When wrapping statements in a new block, use a same-line `do { ... } while(0);` -# (as opposed to non-same-line `if (1) { ... }`) with this probability. -# This matches what macros often do. -PROB_INS_BLOCK_DOWHILE = 0.5 - -# Make a pointer to a temporary expression, rather than copy it by value, with -# this probability. (This always happens for expressions of struct type, -# regardless of this probability.) -PROB_TEMP_PTR = 0.05 - -# Instead of emitting an assignment statement, assign the temporary within the -# first expression it's used in with this probability. -PROB_TEMP_ASSIGN_AT_FIRST_USE = 0.1 - -# When creating a temporary for an expression, use the temporary for all equal -# expressions with this probability. -PROB_TEMP_REPLACE_ALL = 0.2 - -# When creating a temporary for an expression, use the temporary for an interval -# with maximal endpoint with this probability. -PROB_TEMP_REPLACE_MOST = 0.2 - -# When substituting a variable by its value, substitute all instances with this -# probability, rather than just a subrange or the complement of one. -PROB_EXPAND_REPLACE_ALL = 0.3 - -# When substituting a variable by its value, keep the variable assignment with -# this probability. -PROB_KEEP_REPLACED_VAR = 0.2 - -# Change the return type of an external function to void with this probability. -PROB_RET_VOID = 0.2 - -# Number larger than any node index. (If you're trying to compile a 1 GB large -# C file to matching asm, you have bigger problems than this limit.) -MAX_INDEX = 10 ** 9 - -T = TypeVar("T") - - -class RandomizationFailure(Exception): - pass - - -def ensure(condition: Any) -> None: - """Abort the randomization pass if 'condition' fails to hold, and try - another pass instead. Don't call this after making any modifications to - the AST.""" - if not condition: - raise RandomizationFailure - - -@dataclass -class Region: - start: int - end: int - indices: Optional[Indices] = field(compare=False) - - @staticmethod - def unbounded() -> "Region": - return Region(-1, MAX_INDEX, None) - - def is_unbounded(self) -> bool: - return self.indices is None - - def contains_node(self, node: ca.Node) -> bool: - """Check whether the region contains an entire node.""" - if self.indices is None: - return True - return ( - self.start < self.indices.starts[node] - and self.indices.ends[node] < self.end - ) - - def contains_pre(self, node: ca.Node) -> bool: - """Check whether the region contains a point just before a given node.""" - if self.indices is None: - return True - return self.start < self.indices.starts[node] < self.end - - def contains_pre_index(self, index: int) -> bool: - """Check whether the region contains a point just before a given node, - as specified by its index.""" - if self.indices is None: - return True - return self.start < index < self.end - - -def reverse_start_indices(indices: Indices) -> Dict[int, ca.Node]: - ret = {} - for k, v in indices.starts.items(): - ret[v] = k - return ret - - -def get_randomization_region( - top_node: ca.Node, indices: Indices, random: Random -) -> Region: - ret: List[Region] = [] - cur_start: Optional[int] = None - - class Visitor(ca.NodeVisitor): - def visit_Pragma(self, node: ca.Pragma) -> None: - nonlocal cur_start - if node.string == "_permuter randomizer start": - if cur_start is not None: - raise Exception("nested PERM_RANDOMIZE not supported") - cur_start = indices.ends[node] - if node.string == "_permuter randomizer end": - assert cur_start is not None, "randomizer end without start" - ret.append(Region(cur_start + 1, indices.starts[node] - 1, indices)) - cur_start = None - - Visitor().visit(top_node) - assert cur_start is None, "randomizer start without end" - if not ret: - return Region.unbounded() - return random.choice(ret) - - -def get_block_expressions(block: Block, region: Region) -> List[Expression]: - """Return a list of all expressions within a block that are also within a - given region.""" - exprs: List[Expression] = [] - - def visitor(expr: Expression) -> None: - if region.contains_node(expr): - exprs.append(expr) - - replace_subexprs(block, visitor) - return exprs - - -def compute_write_locations( - top_node: ca.Node, indices: Indices -) -> Dict[str, List[int]]: - writes: Dict[str, List[int]] = {} - - def add_write(var_name: str, loc: int) -> None: - if var_name not in writes: - writes[var_name] = [] - else: - assert ( - loc > writes[var_name][-1] - ), "consistent traversal order should guarantee monotonicity here" - writes[var_name].append(loc) - - class Visitor(ca.NodeVisitor): - def visit_Decl(self, node: ca.Decl) -> None: - if node.name: - add_write(node.name, indices.starts[node]) - self.generic_visit(node) - - def visit_UnaryOp(self, node: ca.UnaryOp) -> None: - if node.op in ["p++", "p--", "++", "--"] and isinstance(node.expr, ca.ID): - add_write(node.expr.name, indices.starts[node]) - self.generic_visit(node) - - def visit_Assignment(self, node: ca.Assignment) -> None: - if isinstance(node.lvalue, ca.ID): - add_write(node.lvalue.name, indices.starts[node]) - self.generic_visit(node) - - Visitor().visit(top_node) - return writes - - -def compute_read_locations(top_node: ca.Node, indices: Indices) -> Dict[str, List[int]]: - reads: Dict[str, List[int]] = {} - for node in find_var_reads(top_node): - var_name = node.name - loc = indices.starts[node] - if var_name not in reads: - reads[var_name] = [] - else: - assert ( - loc > reads[var_name][-1] - ), "consistent traversal order should guarantee monotonicity here" - reads[var_name].append(loc) - return reads - - -def find_var_reads(top_node: ca.Node) -> List[ca.ID]: - ret = [] - - class Visitor(ca.NodeVisitor): - def visit_Decl(self, node: ca.Decl) -> None: - if node.init: - self.visit(node.init) - - def visit_ID(self, node: ca.ID) -> None: - ret.append(node) - - def visit_UnaryOp(self, node: ca.UnaryOp) -> None: - if node.op == "&" and isinstance(node.expr, ca.ID): - return - self.generic_visit(node) - - def visit_StructRef(self, node: ca.StructRef) -> None: - self.visit(node.name) - - def visit_Assignment(self, node: ca.Assignment) -> None: - if isinstance(node.lvalue, ca.ID): - return - self.generic_visit(node) - - Visitor().visit(top_node) - return ret - - -def visit_replace(top_node: ca.Node, callback: Callable[[ca.Node, bool], Any]) -> None: - def empty_statement_to_none(node: Any) -> Any: - if isinstance(node, ca.EmptyStatement): - return None - return node - - def rec(orig_node: ca.Node, toplevel: bool = False, *, lvalue: bool = False) -> Any: - node: "ca.AnyNode" = typing.cast("ca.AnyNode", orig_node) - repl = callback(node, not toplevel and not lvalue) - if repl: - return repl - if isinstance(node, ca.Assignment): - node.lvalue = rec(node.lvalue, lvalue=True) - node.rvalue = rec(node.rvalue) - elif isinstance(node, ca.StructRef): - node.name = rec(node.name, lvalue=(lvalue and node.type == ".")) - elif isinstance(node, ca.Cast): - if node.expr: - node.expr = rec(node.expr) - elif isinstance(node, (ca.Constant, ca.ID)): - pass - elif isinstance(node, ca.UnaryOp): - if node.op in ["p++", "p--", "++", "--", "&"]: - node.expr = rec(node.expr, lvalue=True) - elif node.op != "sizeof": - node.expr = rec(node.expr) - elif isinstance(node, ca.BinaryOp): - node.left = rec(node.left) - node.right = rec(node.right) - elif isinstance(node, ca.FuncCall): - # not worth replacing .name - if node.args: - rec(node.args, True) - elif isinstance(node, ca.ExprList): - for i in range(len(node.exprs)): - if not isinstance(node.exprs[i], ca.Typename): - node.exprs[i] = rec(node.exprs[i]) - elif isinstance(node, ca.ArrayRef): - node.name = rec(node.name, lvalue=lvalue) - node.subscript = rec(node.subscript) - elif isinstance(node, ca.TernaryOp): - node.cond = rec(node.cond) - node.iftrue = rec(node.iftrue, True) - node.iffalse = rec(node.iffalse, True) - elif isinstance(node, ca.Return): - if node.expr: - node.expr = rec(node.expr) - elif isinstance(node, ca.Decl): - if node.init: - node.init = rec(node.init, isinstance(node.init, ca.InitList)) - elif isinstance(node, ca.For): - if node.init: - node.init = empty_statement_to_none(rec(node.init, True)) - if node.cond: - node.cond = rec(node.cond) - if node.next: - node.next = empty_statement_to_none(rec(node.next, True)) - node.stmt = rec(node.stmt, True) - elif isinstance(node, ca.Compound): - if node.block_items: - for i, sub in enumerate(node.block_items): - node.block_items[i] = rec(sub, True) - elif isinstance(node, (ca.Case, ca.Default)): - if node.stmts: - for i, sub in enumerate(node.stmts): - node.stmts[i] = rec(sub, True) - elif isinstance(node, ca.While): - node.cond = rec(node.cond) - node.stmt = rec(node.stmt, True) - elif isinstance(node, ca.DoWhile): - node.stmt = rec(node.stmt, True) - node.cond = rec(node.cond) - elif isinstance(node, ca.Switch): - node.cond = rec(node.cond) - node.stmt = rec(node.stmt, True) - elif isinstance(node, ca.Label): - node.stmt = rec(node.stmt, True) - elif isinstance(node, ca.If): - node.cond = rec(node.cond) - node.iftrue = rec(node.iftrue, True) - if node.iffalse: - node.iffalse = rec(node.iffalse, True) - elif isinstance( - node, - ( - ca.TypeDecl, - ca.PtrDecl, - ca.ArrayDecl, - ca.Typename, - ca.IdentifierType, - ca.Struct, - ca.Union, - ca.Enum, - ca.EmptyStatement, - ca.Pragma, - ca.Break, - ca.Continue, - ca.Goto, - ca.CompoundLiteral, - ca.Typedef, - ca.FuncDecl, - ca.FuncDef, - ca.EllipsisParam, - ca.Enumerator, - ca.EnumeratorList, - ca.FileAST, - ca.InitList, - ca.NamedInitializer, - ca.ParamList, - ), - ): - pass - else: - _: None = node - assert False, f"Node with unknown type: {node}" - return node - - rec(top_node, True) - - -def replace_subexprs(top_node: ca.Node, callback: Callable[[Expression], Any]) -> None: - def expr_filter(node: ca.Node, is_expr: bool) -> Any: - if not is_expr: - return None - return callback(typing.cast(Expression, node)) - - visit_replace(top_node, expr_filter) - - -def replace_node(top_node: ca.Node, old: ca.Node, new: ca.Node) -> None: - visit_replace(top_node, lambda node, _: new if node is old else None) - - -def random_bool(random: Random, prob: float) -> bool: - return random.random() < prob - - -def random_weighted(random: Random, values: Sequence[Tuple[T, float]]) -> T: - sumprob = 0.0 - for (val, prob) in values: - assert prob >= 0, "Probabilities must be non-negative" - sumprob += prob - assert sumprob > 0, "Cannot pick randomly from empty set" - targetprob = random.uniform(0, sumprob) - sumprob = 0.0 - for (val, prob) in values: - sumprob += prob - if sumprob > targetprob: - return val - - # Float imprecision - for (val, prob) in values: - if prob > 0: - return val - assert False, "unreachable" - - -def random_type(random: Random) -> SimpleType: - new_names: List[str] = [] - if random_bool(random, 0.5): - new_names.append("unsigned") - new_names.extend( - random_weighted( - random, - [ - (["char"], 1), - (["short"], 1), - (["int"], 2), - (["long"], 0.5), - (["long", "long"], 0.5), - ], - ) - ) - idtype = ca.IdentifierType(names=new_names) - quals = [] - if random_bool(random, 0.5): - quals = ["volatile"] - return ca.TypeDecl(declname=None, quals=quals, type=idtype) - - -def randomize_type( - type: SimpleType, typemap: TypeMap, random: Random, *, ensure_changed: bool = False -) -> SimpleType: - if allowed_basic_type( - type, typemap, ["int", "char", "long", "short", "signed", "unsigned"] - ): - return random_type(random) - if ensure_changed: - raise RandomizationFailure - return type - - -def randomize_innermost_type( - type: Type, typemap: TypeMap, random: Random, *, ensure_changed: bool = False -) -> Type: - if isinstance(type, ca.TypeDecl): - return randomize_type(type, typemap, random, ensure_changed=ensure_changed) - new_type = copy.copy(type) - new_type.type = randomize_innermost_type( - type.type, typemap, random, ensure_changed=ensure_changed - ) - return new_type - - -def get_insertion_points( - fn: ca.FuncDef, region: Region, *, allow_within_decl: bool = False -) -> List[Tuple[Block, int, Optional[ca.Node]]]: - cands: List[Tuple[Block, int, Optional[ca.Node]]] = [] - - def rec(block: Block) -> None: - stmts = ast_util.get_block_stmts(block, False) - last_node: ca.Node = block - for i, stmt in enumerate(stmts): - if region.contains_pre(stmt): - cands.append((block, i, stmt)) - ast_util.for_nested_blocks(stmt, rec) - last_node = stmt - if region.contains_node(last_node): - cands.append((block, len(stmts), None)) - - rec(fn.body) - if not allow_within_decl: - cands = [c for c in cands if not isinstance(c[2], ca.Decl)] - return cands - - -def maybe_reuse_var( - var: Optional[str], - assign_before: ca.Node, - orig_expr: Expression, - type: SimpleType, - reads: Dict[str, List[int]], - writes: Dict[str, List[int]], - indices: Indices, - typemap: TypeMap, - random: Random, -) -> Optional[str]: - if not random_bool(random, PROB_REUSE_VAR) or var is None: - return None - var_type: SimpleType = decayed_expr_type(ca.ID(var), typemap) - if not same_type(var_type, type, typemap, allow_similar=True): - return None - - def find_next(list: List[int], value: int) -> Optional[int]: - ind = bisect.bisect_left(list, value) - if ind < len(list): - return list[ind] - return None - - assignment_ind = indices.starts[assign_before] - expr_ind = indices.starts[orig_expr] - write = find_next(writes.get(var, []), assignment_ind) - read = find_next(reads.get(var, []), assignment_ind) - # TODO: if write/read is within expr, search again from after it (since - # we move expr, uses within it aren't relevant). - if read is not None and (write is None or write >= read): - # We don't want to overwrite a variable which we later read, - # unless we write to it before that read - return None - if write is not None and write < expr_ind: - # Our write will be overwritten before we manage to read from it. - return None - return var - - -def perm_temp_for_expr( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Create a temporary variable for a random expression. The variable will - be assigned at another random point (nearer the expression being more - likely), possibly reuse an existing variable, possibly be of a different - size/signedness, and possibly be used for other identical expressions as - well. Only expressions within the given region may be chosen for - replacement, but the assignment and the affected identical expressions may - be outside of it.""" - Place = Tuple[Block, int, Statement] - einds: Dict[ca.Node, int] = {} - writes: Dict[str, List[int]] = compute_write_locations(fn, indices) - reads: Dict[str, List[int]] = compute_read_locations(fn, indices) - typemap = build_typemap(ast) - candidates: List[Tuple[Tuple[Place, Expression, Optional[str]], float]] = [] - - # Step 0: decide whether to make a pointer to the chosen expression, or to - # copy it by value. - should_make_ptr = random_bool(random, PROB_TEMP_PTR) - - def surrounding_writes(expr: Expression, base: Expression) -> Tuple[int, int]: - """Compute the previous and next write to a variable included in expr, - starting from base. If none, default to -1 or MAX_INDEX respectively. - If base itself writes to an included variable (e.g. if it is an - increment expression), the \"next\" write will be defined as the node - itself, while the \"previous\" will continue searching to the left.""" - sub_reads = find_var_reads(expr) - prev_write = -1 - next_write = MAX_INDEX - base_index = indices.starts[base] - for sub_read in sub_reads: - var_name = sub_read.name - if var_name not in writes: - continue - # Find the first write that is strictly before indices[expr], - # and the first write that is on or after. - wr = writes[var_name] - ind = bisect.bisect_left(wr, base_index) - if ind > 0: - prev_write = max(prev_write, wr[ind - 1]) - if ind < len(wr): - next_write = min(next_write, wr[ind]) - return prev_write, next_write - - # Step 1: assign probabilities to each place/expression - def rec(block: Block, reuse_cands: List[str]) -> None: - stmts = ast_util.get_block_stmts(block, False) - reuse_cands = reuse_cands[:] - assignment_cands: List[Place] = [] # places to insert before - past_decls = False - for index, stmt in enumerate(stmts): - if isinstance(stmt, ca.Decl): - assert stmt.name, "Anonymous declarations cannot happen in functions" - if not isinstance(stmt.type, ca.ArrayDecl): - reuse_cands.append(stmt.name) - if not isinstance(stmt.type, ca.PtrDecl): - # Make non-pointers more common - reuse_cands.append(stmt.name) - elif not isinstance(stmt, ca.Pragma): - past_decls = True - if past_decls: - assignment_cands.append((block, index, stmt)) - - ast_util.for_nested_blocks(stmt, lambda b: rec(b, reuse_cands)) - - def visitor(expr: Expression) -> None: - if DEBUG_EAGER_TYPES: - decayed_expr_type(expr, typemap) - - if not region.contains_node(expr): - return - - orig_expr = expr - if should_make_ptr: - if not ast_util.is_lvalue(expr): - return - expr = ca.UnaryOp("&", expr) - - eind = einds.get(expr, 0) - prev_write, _ = surrounding_writes(expr, orig_expr) - - for place in assignment_cands[::-1]: - # If expr contains an ID which is written to within - # [place, expr), bail out; we're trying to move the - # assignment too high up. - # TODO: also fail on moving past function calls, or - # possibly-aliasing writes. - if indices.starts[place[2]] <= prev_write: - break - - # Make far-away places less likely, and similarly for - # trivial expressions. - eind += 1 - prob = 1 / eind - if isinstance(orig_expr, (ca.ID, ca.Constant)): - prob *= 0.15 if should_make_ptr else 0.5 - reuse_cand = random.choice(reuse_cands) if reuse_cands else None - candidates.append(((place, expr, reuse_cand), prob)) - - einds[expr] = eind - - replace_subexprs(stmt, visitor) - - rec(fn.body, []) - - # Step 2: decide on a place/expression - ensure(candidates) - place: Optional[Place] - place, expr, reuse_cand = random_weighted(random, candidates) - - if random_bool(random, PROB_TEMP_ASSIGN_AT_FIRST_USE): - # Don't emit a statement for the assignment, emit an assignment - # expression at the first use instead. - place = None - - type: SimpleType = decayed_expr_type(expr, typemap) - - # Always use pointers when replacing structs - if ( - not should_make_ptr - and isinstance(type, ca.TypeDecl) - and isinstance(type.type, (ca.Struct, ca.Union)) - and ast_util.is_lvalue(expr) - ): - should_make_ptr = True - expr = ca.UnaryOp("&", expr) - type = decayed_expr_type(expr, typemap) - - if should_make_ptr: - assert isinstance(expr, ca.UnaryOp) - assert not isinstance(expr.expr, ca.Typename) - orig_expr = expr.expr - else: - orig_expr = expr - # print("replacing:", to_c(expr)) - - # Step 3: decide on a variable to hold the expression - if place is not None: - assign_before = place[2] - else: - assign_before = orig_expr - reused_var = maybe_reuse_var( - reuse_cand, - assign_before, - orig_expr, - type, - reads, - writes, - indices, - typemap, - random, - ) - if reused_var is not None: - reused = True - var = reused_var - else: - reused = False - var = "new_var" - counter = 1 - while var in writes: - counter += 1 - var = f"new_var{counter}" - - # Step 4: possibly expand the replacement to include duplicate expressions. - prev_write, next_write = surrounding_writes(expr, orig_expr) - prev_write = max(prev_write, indices.starts[assign_before] - 1) - replace_cands: List[Expression] = [] - - def find_duplicates(e: Expression) -> None: - if prev_write < indices.starts[e] <= next_write and ast_util.equal_ast( - e, orig_expr - ): - replace_cands.append(e) - - if ast_util.is_effectful(expr): - replace_cands = [orig_expr] - else: - replace_subexprs(fn.body, find_duplicates) - - assert orig_expr in replace_cands - if random_bool(random, PROB_TEMP_REPLACE_ALL): - lo_index = 0 - hi_index = len(replace_cands) - else: - index = replace_cands.index(orig_expr) - lo_index = random.randint(0, index) - hi_index = random.randint(index + 1, len(replace_cands)) - if random_bool(random, PROB_TEMP_REPLACE_MOST): - if random_bool(random, 0.5): - lo_index = 0 - else: - hi_index = len(replace_cands) - replace_cand_set = set(replace_cands[lo_index:hi_index]) - - # Step 5: replace the chosen expression - def replacer(e: Expression) -> Optional[Expression]: - if e in replace_cand_set: - ret: Expression = ca.ID(var) - if place is None and e is orig_expr: - ret = ca.Assignment("=", ret, expr) - if should_make_ptr: - ret = ca.UnaryOp("*", ret) - return ret - return None - - replace_subexprs(fn.body, replacer) - - # Step 6: insert the assignment and any new variable declaration - if place is not None: - block, index, _ = place - assignment = ca.Assignment("=", ca.ID(var), expr) - ast_util.insert_statement(block, index, assignment) - if not reused: - if random_bool(random, PROB_RANDOMIZE_TYPE): - type = randomize_type(type, typemap, random) - ast_util.insert_decl(fn, var, type, random) - - -def perm_expand_expr( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Replace a random variable by its contents.""" - all_writes: Dict[str, List[int]] = compute_write_locations(fn, indices) - all_reads: Dict[str, List[int]] = compute_read_locations(fn, indices) - - # Step 1: pick out a variable to replace - rev: Dict[int, str] = {} - for var, locs in all_reads.items(): - for index in locs: - if region.contains_pre_index(index): - rev[index] = var - ensure(rev) - index = random.choice(list(rev.keys())) - var = rev[index] - - # Step 2: find the assignment it uses - reads = all_reads[var] - writes = all_writes.get(var, []) - i = bisect.bisect_left(writes, index) - # if i == 0, there is no write to replace the read by. - ensure(i > 0) - before = writes[i - 1] - after = MAX_INDEX if i == len(writes) else writes[i] - rev_indices = reverse_start_indices(indices) - write = rev_indices[before] - if ( - isinstance(write, ca.Decl) - and write.init - and not isinstance(write.init, ca.InitList) - ): - repl_expr = write.init - elif isinstance(write, ca.Assignment) and write.op == "=": - repl_expr = write.rvalue - else: - raise RandomizationFailure - - # Step 3: pick of the range of variables to replace - repl_cands = [ - i for i in reads if before < i < after and region.contains_pre_index(i) - ] - assert repl_cands, "index is always in repl_cands" - myi = repl_cands.index(index) - if not random_bool(random, PROB_EXPAND_REPLACE_ALL) and len(repl_cands) > 1: - # Keep using the variable for a bit in the middle - side = random.randrange(3) - H = len(repl_cands) - loi = 0 if side == 0 else random.randint(0, myi) - hii = H if side == 1 else random.randint(myi + 1, H) - if loi == 0 and hii == H: - loi, hii = myi, myi + 1 - repl_cands[loi:hii] = [] - keep_var = True - else: - keep_var = random_bool(random, PROB_KEEP_REPLACED_VAR) - repl_cands_set = set(repl_cands) - - # Don't duplicate effectful expressions. - if ast_util.is_effectful(repl_expr): - ensure(len(repl_cands) == 1 and not keep_var) - - # Step 4: do the replacement - def callback(expr: ca.Node, is_expr: bool) -> Optional[ca.Node]: - if indices.starts[expr] in repl_cands_set: - return copy.deepcopy(repl_expr) - if expr == write and isinstance(write, ca.Assignment) and not keep_var: - if is_expr: - return write.lvalue - else: - return ca.EmptyStatement() - return None - - visit_replace(fn.body, callback) - if not keep_var and isinstance(write, ca.Decl): - write.init = None - - -def perm_randomize_internal_type( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Randomize types of pre-existing local variables. Function parameters - are not included -- those are handled by perm_randomize_function_type. - Only variables mentioned within the given region are affected.""" - names: Set[str] = set() - - class IdVisitor(ca.NodeVisitor): - def visit_ID(self, node: ca.ID) -> None: - if region.contains_node(node): - names.add(node.name) - - def visit_StructRef(self, node: ca.StructRef) -> None: - self.visit(node.name) - - IdVisitor().visit(fn) - - typemap = build_typemap(ast) - decls: List[ca.Decl] = [] - - class Visitor(ca.NodeVisitor): - def visit_Decl(self, decl: ca.Decl) -> None: - if isinstance(decl.type, ca.TypeDecl) and decl.name and decl.name in names: - decls.append(decl) - self.generic_visit(decl) - - Visitor().visit(fn) - - ensure(decls) - decl = random.choice(decls) - assert isinstance(decl.type, ca.TypeDecl), "checked above" - decl.type = randomize_type(decl.type, typemap, random, ensure_changed=True) - set_decl_name(decl) - - -def perm_randomize_external_type( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Randomize types of global variables. Only variables mentioned within the - given region are affected.""" - names: Set[str] = set() - - class IdVisitor(ca.NodeVisitor): - def visit_ID(self, node: ca.ID) -> None: - if region.contains_node(node): - names.add(node.name) - - def visit_StructRef(self, node: ca.StructRef) -> None: - self.visit(node.name) - - IdVisitor().visit(fn) - - ensure(names) - name = random.choice(list(names)) - decls: List[Tuple[ca.Decl, int]] = [] - - for i in range(len(ast.ext)): - item = ast.ext[i] - if isinstance(item, ca.Decl) and item.name == name: - new_decl = copy.copy(item) - decls.append((new_decl, i)) - - ensure(decls) - decl = random.choice(decls)[0] - decl_type = get_decl_type(decl) - - typemap = build_typemap(ast) - new_type = randomize_innermost_type(decl_type, typemap, random, ensure_changed=True) - - for decl, i in decls: - decl.type = copy.deepcopy(new_type) - ast.ext[i] = decl - set_decl_name(decl) - - -def perm_randomize_function_type( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Randomize types of function parameters and returns. Only functions - called within the given region are affected, plus the current function.""" - assert fn.decl.name is not None, "function definitions have names" - names: Set[str] = {fn.decl.name} - - class IdVisitor(ca.NodeVisitor): - def visit_FuncCall(self, node: ca.FuncCall) -> None: - if region.contains_node(node) and isinstance(node.name, ca.ID): - names.add(node.name.name) - self.generic_visit(node) - - IdVisitor().visit(fn) - - name = random.choice(list(names)) - - # Find the declarations of function with the given name. For performance - # reasons, the part of the AST they live in are shared between all - # randomization runs, so if we mutated them in place bad things would - # happen. Thus, we replace the AST parts we plan to change with mutable - # copies. - all_decls: List[Tuple[ca.Decl, int, "ca.ExternalDeclaration"]] = [] - main_decl: Optional[ca.Decl] = None - for i in range(len(ast.ext)): - item = ast.ext[i] - if ( - isinstance(item, ca.Decl) - and isinstance(item.type, ca.FuncDecl) - and item.name == name - ): - new_decl = copy.copy(item) - ast.ext[i] = new_decl - all_decls.append((new_decl, i, new_decl)) - if isinstance(item, ca.FuncDef) and item.decl.name == name: - assert isinstance( - item.decl.type, ca.FuncDecl - ), "function definitions have function types" - new_fndef = copy.copy(item) - new_decl = copy.copy(item.decl) - new_fndef.decl = new_decl - ast.ext[i] = new_fndef - all_decls.append((new_decl, i, new_fndef)) - main_decl = new_decl - - # Change the type within the function definition if there is one (since we - # need to keep names there), or else within an arbitrary of the (typically - # just one) declarations. We later mirror the change to all declarations. - ensure(all_decls) - if not main_decl: - main_decl = random.choice(all_decls)[0] - - typemap = build_typemap(ast) - - main_fndecl = copy.deepcopy(main_decl.type) - assert isinstance(main_fndecl, ca.FuncDecl), "checked above" - main_decl.type = main_fndecl - - if random_bool(random, 0.5): - # Replace the return type, changing integer signedness/size as well as - # switching to/from void (which we should perhaps avoid if the function - # call result is used, but eh, it's annoying to tell). - type = pointer_decay(main_fndecl.type, typemap) - if allowed_basic_type(type, typemap, ["void"]): - main_fndecl.type = random_type(random) - elif random_bool(random, PROB_RET_VOID): - idtype = ca.IdentifierType(names=["void"]) - main_fndecl.type = ca.TypeDecl(declname=None, quals=[], type=idtype) - else: - main_fndecl.type = randomize_type( - type, typemap, random, ensure_changed=True - ) - set_decl_name(main_decl) - else: - # Replace a parameter, changing integer signedness/size. - if not main_fndecl.args: - raise RandomizationFailure - ensure(main_fndecl.args.params) - ind = random.randrange(len(main_fndecl.args.params)) - arg = main_fndecl.args.params[ind] - if isinstance(arg, (ca.ID, ca.EllipsisParam)): - raise RandomizationFailure - arg_type = arg.type if isinstance(arg, ca.Typename) else get_decl_type(arg) - type = pointer_decay(arg_type, typemap) - arg.type = randomize_type(type, typemap, random, ensure_changed=True) - if isinstance(arg, ca.Decl): - set_decl_name(arg) - - # Commit the changes by writing them back to the AST, for all declarations. - for i in range(len(all_decls)): - decl, ind, new_node = all_decls[i] - ast.ext[ind] = new_node - if decl is not main_decl: - decl.type = copy.deepcopy(main_decl.type) - - -def perm_refer_to_var( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Add `if (variable) {}` or `if (struct.member) {}` in a random place. - This will get optimized away but may affect regalloc.""" - # Find expression to insert, searching within the randomization region. - cands: List[Expression] = [ - expr - for expr in get_block_expressions(fn.body, region) - if isinstance(expr, (ca.StructRef, ca.ID)) - ] - ensure(cands) - expr = random.choice(cands) - ensure(not ast_util.is_effectful(expr)) - typemap = build_typemap(ast) - type: Type = resolve_typedefs(decayed_expr_type(expr, typemap), typemap) - if isinstance(type, ca.TypeDecl) and isinstance(type.type, (ca.Struct, ca.Union)): - expr = ca.UnaryOp("&", expr) - - if random_bool(random, 0.5): - expr = ca.UnaryOp("!", expr) - - # Insert it wherever -- possibly outside the randomization region, since regalloc - # can act at a distance. (Except before a declaration.) - ins_cands = get_insertion_points(fn, Region.unbounded()) - ensure(ins_cands) - - cond = copy.deepcopy(expr) - - # Repeat the condition up to two times: if (x && x && x) {} sometimes helps. - for i in range(random.choice((0, 0, 0, 0, 0, 1, 2, 2))): - cond = ca.BinaryOp("&&", cond, copy.deepcopy(expr)) - - stmt = ca.If(cond=cond, iftrue=ca.Compound(block_items=[]), iffalse=None) - tob, toi, _ = random.choice(ins_cands) - ast_util.insert_statement(tob, toi, stmt) - - -def perm_ins_block( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Wrap a random range of statements within `if (1) { ... }` or - `do { ... } while(0)`. Control flow can have remote effects, so this - mostly ignores the region restriction.""" - cands: List[Block] = [] - - def rec(block: Block) -> None: - cands.append(block) - for stmt in ast_util.get_block_stmts(block, False): - ast_util.for_nested_blocks(stmt, rec) - - rec(fn.body) - block = random.choice(cands) - stmts = ast_util.get_block_stmts(block, True) - decl_count = 0 - for stmt in stmts: - if isinstance(stmt, (ca.Decl, ca.Pragma)): - decl_count += 1 - else: - break - lo = random.randrange(decl_count, len(stmts) + 1) - hi = random.randrange(decl_count, len(stmts) + 1) - if hi < lo: - lo, hi = hi, lo - new_block = ca.Compound(block_items=stmts[lo:hi]) - if random_bool(random, PROB_INS_BLOCK_DOWHILE) and all( - region.contains_node(n) for n in stmts[lo:hi] - ): - cond = ca.Constant(type="int", value="0") - stmts[lo:hi] = [ - ca.Pragma("_permuter sameline start"), - ca.DoWhile(cond=cond, stmt=new_block), - ca.Pragma("_permuter sameline end"), - ] - else: - cond = ca.Constant(type="int", value="1") - stmts[lo:hi] = [ca.If(cond=cond, iftrue=new_block, iffalse=None)] - - -def perm_empty_stmt( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Inserts a no-op statement, one of: - - if (1) {} (sometimes multiple of them) - - if (0) {} - - label: - - goto label; label:; - - ; - Control flow can have remote effects, so this - ignores the region restriction.""" - - # Insert the statement wherever, except before a declaration. - cands = get_insertion_points(fn, Region.unbounded()) - ensure(cands) - - label_name = f"dummy_label_{random.randint(1, 10**6)}" - - stmts: List[Statement] = [] - - kind = random.randrange(5) - if kind == 0: # if (1) or multiple if (1) - count = random.choice([1, random.randint(2, 6)]) - for _ in range(count): - cond = ca.Constant(type="int", value="1") - stmts.append(ca.If(cond=cond, iftrue=ca.Compound([]), iffalse=None)) - elif kind == 1: # if (0) - cond = ca.Constant(type="int", value="0") - stmts = [ca.If(cond=cond, iftrue=ca.Compound([]), iffalse=None)] - elif kind == 2: # label: - stmts = [ca.Label(label_name, ca.EmptyStatement())] - pass - elif kind == 3: # goto label; label: - stmts = [ - ca.Goto(label_name), - ca.Label(label_name, ca.EmptyStatement()), - ] - elif kind == 4: # ; - stmts = [ca.EmptyStatement()] - - tob, toi, _ = random.choice(cands) - stmts.insert(0, ca.Pragma("_permuter sameline start")) - stmts.append(ca.Pragma("_permuter sameline end")) - for stmt in stmts[::-1]: - ast_util.insert_statement(tob, toi, stmt) - - -def perm_sameline( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Put all statements within a random interval on the same line.""" - cands = get_insertion_points(fn, region) - n = len(cands) - ensure(n >= 3) - # Generate a small random interval - lef: float = n - 2 - for i in range(4): - lef *= random.uniform(0, 1) - le = int(lef) + 2 - i = random.randrange(n - le) - j = i + le - # Insert the second statement first, since inserting a statement may cause - # later indices to move. - ast_util.insert_statement( - cands[j][0], cands[j][1], ca.Pragma("_permuter sameline end") - ) - ast_util.insert_statement( - cands[i][0], cands[i][1], ca.Pragma("_permuter sameline start") - ) - - -def perm_associative( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Change a+b into b+a, or similar for other commutative operations.""" - cands: List[ca.BinaryOp] = [] - commutative_ops = list("+*|&^<>") + ["<=", ">=", "==", "!="] - - class Visitor(ca.NodeVisitor): - def visit_BinaryOp(self, node: ca.BinaryOp) -> None: - if node.op in commutative_ops and region.contains_node(node): - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - node = random.choice(cands) - node.left, node.right = node.right, node.left - if node.op[0] == "<": - node.op = ">" + node.op[1:] - elif node.op[0] == ">": - node.op = "<" + node.op[1:] - - -def perm_condition( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Change if(x) into if(x != 0), or vice versa. Also handles for/while/do-while.""" - cands: List[Union[ca.If, ca.While, ca.DoWhile, ca.For]] = [] - - class Visitor(ca.NodeVisitor): - def visit_If(self, node: ca.If) -> None: - cands.append(node) - self.generic_visit(node) - - def visit_While(self, node: ca.While) -> None: - cands.append(node) - self.generic_visit(node) - - def visit_DoWhile(self, node: ca.DoWhile) -> None: - cands.append(node) - self.generic_visit(node) - - def visit_For(self, node: ca.For) -> None: - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - node = random.choice(cands) - if not node.cond: - raise RandomizationFailure - - if ( - isinstance(node.cond, ca.BinaryOp) - and node.cond.op in ["==", "!=", "<", ">", "<=", ">="] - and random_bool(random, 0.9) - ): - ensure(node.cond.op in ["==", "!="]) - ensure( - isinstance(node.cond.right, ca.Constant) - and node.cond.right.value in ["0", "0U", "0.0", "0.0f"] - ) - if node.cond.op == "==": - node.cond = ca.UnaryOp("!", node.cond.left) - else: - node.cond = node.cond.left - else: - expr = node.cond - op = "!=" - if isinstance(expr, ca.UnaryOp) and expr.op == "!" and random_bool(random, 0.9): - assert not isinstance(expr.expr, ca.Typename) - expr = expr.expr - op = "==" - zero = random_weighted( - random, - [ - (ca.Constant("int", "0"), 0.8), - (ca.Constant("unsigned int", "0U"), 0.2), - (ca.Constant("float", "0.0f"), 0.05), - ], - ) - node.cond = ca.BinaryOp(op, expr, zero) - - -def perm_add_self_assignment( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Introduce a "x = x;" somewhere.""" - cands = get_insertion_points(fn, region) - vars: List[str] = [] - - class Visitor(ca.NodeVisitor): - def visit_Decl(self, decl: ca.Decl) -> None: - if decl.name: - vars.append(decl.name) - self.generic_visit(decl) - - Visitor().visit(fn.body) - ensure(vars) - ensure(cands) - var = random.choice(vars) - where = random.choice(cands) - assignment = ca.Assignment("=", ca.ID(var), ca.ID(var)) - ast_util.insert_statement(where[0], where[1], assignment) - - -def perm_dummy_comma_expr( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Change x into (0, x) for a random expression x.""" - cands = get_block_expressions(fn.body, region) - ensure(cands) - expr = random.choice(cands) - new_expr = ca.ExprList([ca.Constant("int", "0"), expr]) - replace_node(fn.body, expr, new_expr) - - -def perm_reorder_stmts( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Move a statement to another random place.""" - cands = get_insertion_points(fn, region, allow_within_decl=True) - - # Figure out candidate statements to be moved. Don't move pragmas; it can - # cause assertion failures. Don't move blocks; statements are generally not - # reordered across basic blocks, and we don't want to risk moving a block - # to inside itself. - source_inds = [] - for i, c in enumerate(cands): - stmt = c[2] - if ( - stmt is not None - and not isinstance(stmt, ca.Pragma) - and not ast_util.has_nested_block(stmt) - ): - source_inds.append(i) - - ensure(source_inds) - fromi = random.choice(source_inds) - - weighted_cands = [] - for i in range(len(cands)): - dist = max(fromi - i, i - (fromi + 1)) - if dist == 0: - continue - # Move distance 1, 2, 3, ... with probabilities - # 23%, 12%, 8%, 6%, 4%, 3%, 3%, 2%, 2%, 2%, ... - prob = (dist + 1) ** -1.5 - weighted_cands.append((i, prob)) - ensure(weighted_cands) - toi = random_weighted(random, weighted_cands) - - fromb, fromi, from_stmt = cands[fromi] - tob, toi, to_stmt = cands[toi] - - if fromb == tob: - ensure(toi != fromi and toi != fromi + 1) - - if isinstance(from_stmt, ca.Decl): - # Moving a declaration is tricky, when also preserving C89 compatibility. - # We can move it to after another declaration, or to the start of a block. - # Alternatively, if the declaration includes an initializer, and we move - # it forwards, we can split that out as an assignment. - # We don't allow moving the declaration or assignment past the next - # occurrence of the variable. - ensure(from_stmt.name) - var_name = from_stmt.name - to_index = indices.starts[to_stmt] if to_stmt else indices.ends[fromb] - uses = 0 - - class Visitor(ca.NodeVisitor): - def visit_ID(self, node: ca.ID) -> None: - nonlocal uses - if node.name == var_name and indices.starts[node] < to_index: - uses += 1 - - def visit_TypeDecl(self, node: ca.TypeDecl) -> None: - nonlocal uses - if node.declname == var_name and indices.starts[node] < to_index: - uses += 1 - - Visitor().visit(fn.body) - ensure(uses <= 1) - - to_block_stmts = ast_util.get_block_stmts(tob, False) - if toi == 0 or isinstance(to_block_stmts[toi - 1], ca.Decl): - # Fine to move - pass - elif ( - from_stmt.name - and from_stmt.init - and not isinstance(from_stmt.init, ca.InitList) - and uses > 0 - ): - assignment = ca.Assignment("=", ca.ID(from_stmt.name), from_stmt.init) - ast_util.insert_statement(tob, toi, assignment) - from_stmt.init = None - return - else: - raise RandomizationFailure - else: - # Don't put statements before declarations. - ensure(not isinstance(to_stmt, ca.Decl)) - - if fromb == tob and fromi < toi: - toi -= 1 - - stmt = ast_util.get_block_stmts(fromb, True).pop(fromi) - ast_util.insert_statement(tob, toi, stmt) - - -def perm_compound_assignment( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Convert a statement of the form `x = x op y` to `x op= y`, or vice versa.""" - cands: List[ca.Assignment] = [] - operators = ["+", "-", "*", "/", "<<", ">>", "^", "|", "&"] - - class Visitor(ca.NodeVisitor): - def visit_Assignment(self, node: ca.Assignment) -> None: - if region.contains_node(node): - if node.op != "=" or ( - isinstance(node.rvalue, ca.BinaryOp) - and ast_util.equal_ast(node.lvalue, node.rvalue.left) - and node.rvalue.op in operators - ): - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - node = random.choice(cands) - - if node.op == "=": - assert isinstance(node.rvalue, ca.BinaryOp) - node.op = node.rvalue.op + node.op - node.rvalue = node.rvalue.right - else: - operator = node.op[:-1] - node.op = "=" - node.rvalue = ca.BinaryOp(operator, copy.deepcopy(node.lvalue), node.rvalue) - - -def perm_inequalities( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Adjusts inequalities to equivalent versions that sometimes produce different code. - For example, a > b and a >= b + 1, a < b to a <= b - 1 (and vice versa)""" - cands: List[ca.BinaryOp] = [] - inequalities = ["<", ">", "<=", ">="] - - class Visitor(ca.NodeVisitor): - def visit_BinaryOp(self, node: ca.BinaryOp) -> None: - if node.op in inequalities and region.contains_node(node): - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - - node = random.choice(cands) - - # Does not simplify, 'a <= (b + 1)' becomes 'a < ((b + 1) + 1)' - - def plus1(node: ca.Node) -> ca.BinaryOp: - return ca.BinaryOp("+", node, ca.Constant("int", "1")) - - def minus1(node: ca.Node) -> ca.BinaryOp: - return ca.BinaryOp("-", node, ca.Constant("int", "1")) - - # Don't change the operator, change both operands (can produce fake matches sometimes) - # Ex: a > b -> a + 1 > b + 1 - if random.random() < 0.25: - change = random.choice([plus1, minus1]) - node.left = change(node.left) - node.right = change(node.right) - - else: - if node.op in ["<", ">="]: - node.op = {"<": "<=", ">=": ">"}[node.op] - if random_bool(random, 0.5): - node.left = plus1(node.left) - else: - node.right = minus1(node.right) - else: - node.op = {">": ">=", "<=": "<"}[node.op] - if random_bool(random, 0.5): - node.left = minus1(node.left) - else: - node.right = plus1(node.right) - - -def perm_add_mask( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Add a random amount of masks of 0xFF[FFFFFFFFFFFFFF] to a random expression of integer type. - In some cases this mask is optimized out but affects regalloc. - The regalloc change seems to cycle with slight differences every n masks.""" - typemap = build_typemap(ast) - - # Find expression to add the mask to - cands: List[Expression] = get_block_expressions(fn.body, region) - ensure(cands) - - expr = random.choice(cands) - type: SimpleType = decayed_expr_type(expr, typemap) - ensure( - allowed_basic_type( - type, typemap, ["int", "char", "long", "short", "signed", "unsigned"] - ) - ) - - # Mask as if restricting the value to 8, 16, 32, or 64-bit width. - # Sometimes use an unsigned mask like '0xFFu' - masks: List[str] = ["0xFF", "0xFFFF", "0xFFFFFFFF", "0xFFFFFFFFFFFFFFFF"] - mask = random.choice(masks) + random.choice(["", "u"]) - - new_expr = ca.BinaryOp("&", expr, ca.Constant("int", mask)) - if random_bool(random, 0.3): - for _ in range(random.randrange(12)): - new_expr = ca.BinaryOp("&", new_expr, ca.Constant("int", mask)) - - replace_node(fn.body, expr, new_expr) - - -def perm_xor_zero( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Add ^0 to a random expression of integer type, or *1 to floats.""" - typemap = build_typemap(ast) - - # Find a random expression - cands: List[Expression] = get_block_expressions(fn.body, region) - ensure(cands) - - expr = random.choice(cands) - type: SimpleType = decayed_expr_type(expr, typemap) - int_types = ["int", "char", "long", "short", "signed", "unsigned"] - - if allowed_basic_type(type, typemap, int_types): - new_expr = ca.BinaryOp("^", expr, ca.Constant("int", "0")) - elif allowed_basic_type(type, typemap, ["float"]): - new_expr = ca.BinaryOp("*", expr, ca.Constant("float", "1.0f")) - elif allowed_basic_type(type, typemap, ["double"]): - new_expr = ca.BinaryOp("*", expr, ca.Constant("double", "1.0")) - else: - raise RandomizationFailure - - replace_node(fn.body, expr, new_expr) - - -def perm_float_literal( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Converts a Float Literal""" - cands: List[ca.Constant] = [] - - class Visitor(ca.NodeVisitor): - def visit_Constant(self, node: ca.Constant) -> None: - if node.type == "float" and region.contains_node(node): - cands.append(node) - - Visitor().visit(fn.body) - ensure(cands) - - node = random.choice(cands) - - value: str = node.value.lower() - choices: List[str] = [value[:-1]] - if value.endswith(".0f"): - choices.append(value[:-3] or "0") - elif value.endswith(".f"): - choices.append(value[:-2] or "0") - if value.startswith("0."): - choices.append("." + (value[2:] or "0")) - elif value.startswith("."): - choices.append("0" + value) - if value.endswith(".0f"): - choices.append((value[:-3] or "0") + ".f") - else: - choices.append(value[:-1] + "0f") - - ensure(choices) - value = random.choice(choices) - if value.endswith("f"): - type = "float" - elif "." in value: - type = "double" - else: - type = "int" - - replace_node(fn.body, node, ca.Constant(type, value)) - - -def perm_cast_simple( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Cast a random expression to a simple type (integral or floating point only).""" - typemap = build_typemap(ast) - - # Find a random expression - cands: List[Expression] = get_block_expressions(fn.body, region) - ensure(cands) - - expr = random.choice(cands) - type: SimpleType = decayed_expr_type(expr, typemap) - ensure( - allowed_basic_type( - type, - typemap, - ["int", "char", "long", "short", "signed", "unsigned", "float", "double"], - ) - ) - - integral_type = [["int"], ["char"], ["long"], ["short"], ["long", "long"]] - floating_type = [["float"], ["double"]] - new_type: List[str] - if random_bool(random, 0.5): - # Cast to integral type, sometimes unsigned - sign: List[str] = random.choice([[], ["unsigned"]]) - new_type = sign + random.choice(integral_type) - else: - # Cast to floating point type - new_type = random.choice(floating_type) - - # Surround the original expression with a cast to the chosen type - typedecl = ca.TypeDecl(None, [], ca.IdentifierType(new_type)) - new_expr = ca.Cast(ca.Typename(None, [], typedecl), expr) - replace_node(fn.body, expr, new_expr) - - -# struct_ref # type of a # easiest conversion -################################################################ -# (a + b).c; # impossible # -# (a + b)->c; # s* # a[b].c -# (*(a + b)).c; # s* # a[b].c -# (*(a + b))->c; # s** # (*(a[b]).c -# (&(a + b)).c; # impossible # -# (&(a + b))->c; # impossible # -# (*(&(a + b))).c; # impossible # -# (*(&(a + b)))->c; # imp: a+b=rvalue # -# (&(*(a + b))).c; # impossible # -# (&(*(a + b)))->c; # s* # a[b].c (-&* req.) -################################################################ -# (a[b]).c; # s* # (a + b)->c -# (a[b])->c; # s** # (*(a + b))->c -# (*(a[b])).c; # s** # (*(a + b))->c -# (*(a[b]))->c; # s*** # (*(*(a + b)))->c -# (&(a[b])).c; # impossible # -# (&(a[b]))->c; # s* # (&(*(a + b)))->c -# (*(&(a[b]))).c; # s* # (*(&(a + b)))->c -# (*(&(a[b])))->c; # s** # (*(&(*(a + b))))->c -# (&(*(a[b]))).c; # impossible # -# (&(*(a[b])))->c; # s** # (&(*(*(a + b))))->c -################################################################ -# a.c # s # (&a)->c -# a->c # s* # (*a).c -# (*a).c # s* # a->c -# (*a)->c # s** # (*(*a)).c -# (&a).c # impossible # -# (&a)->c # s # (*(&a)).c -def perm_struct_ref( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Permute struct references: (a + b)->c, and (*(a + b)).c, a[b].c, (&a[b])->c""" - cands: List[ca.StructRef] = [] - - class Visitor(ca.NodeVisitor): - def visit_StructRef(self, node: ca.StructRef) -> None: - if region.contains_node(node): - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - - # TODO: Split into separate perm? Need a separate one for arrayrefs, (a + b)[1] to a[b + 1] - def randomize_associative_binop(left: ca.Node, right: ca.BinaryOp) -> ca.BinaryOp: - """Try moving parentheses to the left side sometimes (sadly, it seems to matter)""" - if random_bool(random, 0.5) and right.op in ["+", "-"]: - # ((a + b) - c) - return ca.BinaryOp( - right.op, ca.BinaryOp("+", left, right.left), right.right - ) - else: - # (a + (b - c)) - return ca.BinaryOp("+", left, right) - - # Conversions - def to_array(node: ca.BinaryOp) -> ca.ArrayRef: - """Change a BinaryOp, a + b, to an ArrayRef, a[b] - The operator is expected to be + or -""" - # TODO: Permute binops like to_binop() does - if node.op == "-": - # Convert to a[-b] - node.right = ca.UnaryOp("-", node.right) - return ca.ArrayRef(node.left, node.right) - - def to_binop(node: ca.ArrayRef) -> ca.BinaryOp: - """Change an ArrayRef, a[b], to a BinaryOp, a + b - If b is also BinaryOp, such as a[b - 1], sometimes change the order of operations, - ie: a + (b - 1) vs (a + b) - 1""" - if isinstance(node.subscript, ca.BinaryOp): - return randomize_associative_binop(node.name, node.subscript) - return ca.BinaryOp("+", node.name, node.subscript) - - def deref(node: Expression) -> Expression: - """Surround the given node with a dereference operator""" - if isinstance(node, ca.UnaryOp) and node.op == "&": - assert not isinstance(node.expr, ca.Typename) - return node.expr - return ca.UnaryOp("*", node) - - def addr(node: Expression) -> Expression: - """Surround the given node with an address-of operator""" - if isinstance(node, ca.UnaryOp) and node.op == "*": - assert not isinstance(node.expr, ca.Typename) - return node.expr - return ca.UnaryOp("&", node) - - def rec(node: ca.Node) -> Any: - """Recurse down the StructRef tree, finding the parent of the leaf BinaryOp/ArrayRef. - Throws RandomizationFailure when a UnaryOp other than * or & was encountered.""" - if isinstance(node, ca.UnaryOp): - ensure(node.op in ["&", "*"]) - return rec(node.expr) or node - if isinstance(node, ca.StructRef): - return rec(node.name) or node - return None - - # TODO - def apply_child( # type: ignore - parent: Union[ca.StructRef, ca.UnaryOp], func - ) -> None: - if isinstance(parent, ca.StructRef): - parent.name = func(parent.name) - elif isinstance(parent, ca.UnaryOp): - parent.expr = func(parent.expr) - - def get_child(parent: Union[ca.StructRef, ca.UnaryOp]) -> ca.Node: - if isinstance(parent, ca.StructRef): - return parent.name - elif isinstance(parent, ca.UnaryOp): - return parent.expr - - struct_ref = random.choice(cands) - parent: Union[ca.StructRef, ca.UnaryOp] - - # Step 1: Find the parent of the leaf node - parent = rec(struct_ref) - - changed = False - - # Step 2: Simplify (...)->c to (*(...)).c - if struct_ref.type == "->": - struct_ref.type = "." - # check if deref would remove the parent node - if ( - parent is struct_ref.name - and isinstance(parent, ca.UnaryOp) - and parent.op == "&" - ): - struct_ref.name = deref(struct_ref.name) - parent = struct_ref - else: - struct_ref.name = deref(struct_ref.name) - if parent is struct_ref and isinstance( - struct_ref.name, ca.UnaryOp - ): # Check to make mypy happy - parent = struct_ref.name - changed = True - - # Simple StructRefs only need their type permuted - if isinstance(get_child(parent), (ca.ArrayRef, ca.BinaryOp)): - # For binops, a lhs like &(a+b)->c is impossible, because a + b is an rvalue - - # Step 3: Simplify further by converting ArrayRef to BinaryOp - if isinstance(get_child(parent), ca.ArrayRef): - apply_child(parent, to_binop) - apply_child(parent, deref) - parent = typing.cast("Union[ca.StructRef, ca.UnaryOp]", get_child(parent)) - changed = True - - # Step 4: Convert back to ArrayRef - if random_bool(random, 0.5): - # Sanity check that there's at least one dereference - if isinstance(parent, ca.UnaryOp) and parent.op == "*": - apply_child(parent, to_array) - apply_child(parent, addr) - changed = True - - # Step 5: Convert the StructRef type back - if random_bool(random, 0.5): - struct_ref.name = addr(struct_ref.name) - struct_ref.type = "->" - changed = True - - ensure(changed) - - -def perm_split_assignment( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Split assignments of the form a = b . c . d ...; into a = b; a = a . c . d ...;, a = c . d ...; a = b . a;, etc.""" - cands = [] - # Look for assignments of the form 'var = binaryOp' (ignores op=) - class Visitor(ca.NodeVisitor): - def visit_Assignment(self, node: ca.Assignment) -> None: - if ( - node.op == "=" - and isinstance(node.rvalue, ca.BinaryOp) - and region.contains_node(node) - ): - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - - assign = random.choice(cands) - var = assign.lvalue - - ins_cands = get_insertion_points(fn, region) - - for ins_block, ins_index, node in ins_cands: - if node is assign: - break - else: - raise RandomizationFailure - - binops = [] - - def collect_binops(node: ca.BinaryOp) -> None: - if isinstance(node.left, ca.BinaryOp): - collect_binops(node.left) - binops.append(node) - if isinstance(node.right, ca.BinaryOp): - collect_binops(node.right) - - collect_binops(typing.cast(ca.BinaryOp, assign.rvalue)) - - split = random.choice(binops) - - typemap = build_typemap(ast) - vartype = decayed_expr_type(var, typemap) - - # Choose which side to move to a new assignment - if random_bool(random, 0.5): - side = split.left - sidetype = decayed_expr_type(side, typemap) - ensure(same_type(vartype, sidetype, typemap, allow_similar=True)) - split.left = copy.deepcopy(var) - else: - side = split.right - sidetype = decayed_expr_type(side, typemap) - ensure(same_type(vartype, sidetype, typemap, allow_similar=True)) - split.right = copy.deepcopy(var) - - # The assignment is always inserted before the original - new_assign = ca.Assignment("=", copy.deepcopy(var), side) - ast_util.insert_statement(ins_block, ins_index, new_assign) - - -def perm_remove_ast( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Delete parts of the function that might be unnecessary (mistakes or unnecessary changes from an improved base.c).""" - cands: List[Tuple[ca.Node, ca.Node]] = [] - - class Visitor(ca.NodeVisitor): - def visit_Cast(self, node: ca.Cast) -> None: - if region.contains_node(node): - cands.append((node, node.expr)) - self.generic_visit(node) - - # Replace (a & constant) with (a). - def visit_BinaryOp(self, node: ca.BinaryOp) -> None: - if region.contains_node(node) and node.op == "&": - if isinstance(node.left, ca.Constant): - cands.append((node, node.right)) - if isinstance(node.right, ca.Constant): - cands.append((node, node.left)) - self.generic_visit(node) - - # Remove if statements that don't have an else - def visit_If(self, node: ca.If) -> None: - if not node.iffalse and region.contains_node(node): - cands.append((node, node.iftrue)) - self.generic_visit(node) - - # Remove loops - def visit_While(self, node: ca.While) -> None: - if region.contains_node(node): - cands.append((node, node.stmt)) - self.generic_visit(node) - - def visit_DoWhile(self, node: ca.DoWhile) -> None: - if region.contains_node(node): - cands.append((node, node.stmt)) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - - cand, expr = random.choice(cands) - replace_node(fn.body, cand, expr) - - -def perm_duplicate_assignment( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Duplicate an assignment, sometimes forcing IDO to reuse a register.""" - cands = [] - - class Visitor(ca.NodeVisitor): - def visit_Assignment(self, node: ca.Assignment) -> None: - if region.contains_node(node) and node.op == "=": - cands.append(node) - self.generic_visit(node) - - Visitor().visit(fn.body) - ensure(cands) - cand = random.choice(cands) - - ins_cands = get_insertion_points(fn, Region.unbounded()) - ensure(ins_cands) - - dup = copy.deepcopy(cand) - tob, toi, _ = random.choice(ins_cands) - ast_util.insert_statement(tob, toi, dup) - - -def perm_pad_var_decl( - fn: ca.FuncDef, ast: ca.FileAST, indices: Indices, region: Region, random: Random -) -> None: - """Inserts an unused variable to adjust stack offsets. Probably only useful with --stack-diffs enabled.""" - vars: List[str] = [] - - class Visitor(ca.NodeVisitor): - def visit_Decl(self, decl: ca.Decl) -> None: - if decl.name: - vars.append(decl.name) - self.generic_visit(decl) - - Visitor().visit(fn.body) - - var = "pad" - counter = 1 - while var in vars: - counter += 1 - var = f"pad{counter}" - - type = random_type(random) - ast_util.insert_decl(fn, var, type, random) - - -class Randomizer: - def __init__(self, rng_seed: int) -> None: - self.random = Random(rng_seed) - - def randomize(self, ast: ca.FileAST, fn_index: int) -> None: - fn = ast.ext[fn_index] - assert isinstance(fn, ca.FuncDef) - indices = ast_util.compute_node_indices(fn) - region = get_randomization_region(fn, indices, self.random) - methods = [ - (perm_temp_for_expr, 100), - (perm_expand_expr, 20), - (perm_reorder_stmts, 20), - (perm_add_mask, 15), - (perm_xor_zero, 10), - (perm_cast_simple, 10), - (perm_refer_to_var, 10), - (perm_float_literal, 10), - (perm_randomize_internal_type, 10), - (perm_randomize_external_type, 5), - (perm_randomize_function_type, 5), - (perm_split_assignment, 10), - (perm_sameline, 10), - (perm_ins_block, 10), - (perm_struct_ref, 10), - (perm_empty_stmt, 10), - (perm_condition, 10), - (perm_dummy_comma_expr, 5), - (perm_add_self_assignment, 5), - (perm_associative, 5), - (perm_inequalities, 5), - (perm_compound_assignment, 5), - (perm_remove_ast, 5), - (perm_duplicate_assignment, 5), - (perm_pad_var_decl, 1), - ] - while True: - method = random_weighted(self.random, methods) - try: - method(fn, ast, indices, region, self.random) - break - except RandomizationFailure: - pass diff --git a/tools/decomp-permuter/src/scorer.py b/tools/decomp-permuter/src/scorer.py deleted file mode 100644 index 8bac38f50..000000000 --- a/tools/decomp-permuter/src/scorer.py +++ /dev/null @@ -1,145 +0,0 @@ -from dataclasses import dataclass, field -import difflib -import hashlib -import re -from typing import Tuple, List, Optional -from collections import Counter - - -from .objdump import objdump, get_arch - - -@dataclass(init=False, unsafe_hash=True) -class DiffAsmLine: - line: str = field(compare=False) - mnemonic: str - - def __init__(self, line: str) -> None: - self.line = line - self.mnemonic = line.split("\t")[0] - - -class Scorer: - PENALTY_INF = 10 ** 9 - - PENALTY_STACKDIFF = 1 - PENALTY_REGALLOC = 5 - PENALTY_REORDERING = 60 - PENALTY_INSERTION = 100 - PENALTY_DELETION = 100 - - def __init__(self, target_o: str, *, stack_differences: bool): - self.target_o = target_o - self.arch = get_arch(target_o) - self.stack_differences = stack_differences - _, self.target_seq = self._objdump(target_o) - self.differ: difflib.SequenceMatcher[DiffAsmLine] = difflib.SequenceMatcher( - autojunk=False - ) - self.differ.set_seq2(self.target_seq) - - def _objdump(self, o_file: str) -> Tuple[str, List[DiffAsmLine]]: - ret = [] - lines = objdump(o_file, self.arch, stack_differences=self.stack_differences) - for line in lines: - ret.append(DiffAsmLine(line)) - return "\n".join(lines), ret - - def score(self, cand_o: Optional[str]) -> Tuple[int, str]: - if not cand_o: - return Scorer.PENALTY_INF, "" - - objdump_output, cand_seq = self._objdump(cand_o) - - score = 0 - deletions = [] - insertions = [] - - def lo_hi_match(old: str, new: str) -> bool: - old_lo = old.find("%lo") - old_hi = old.find("%hi") - new_lo = new.find("%lo") - new_hi = new.find("%hi") - - if old_lo != -1 and new_lo != -1: - old_idx = old_lo - new_idx = new_lo - elif old_hi != -1 and new_hi != -1: - old_idx = old_hi - new_idx = new_hi - else: - return False - - if old[:old_idx] != new[:new_idx]: - return False - - old_inner = old[old_idx + 4 : -1] - new_inner = new[new_idx + 4 : -1] - return old_inner.startswith(".") or new_inner.startswith(".") - - def diff_sameline(old: str, new: str) -> None: - nonlocal score - if old == new: - return - - if lo_hi_match(old, new): - return - - ignore_last_field = False - if self.stack_differences: - oldsp = re.search(self.arch.re_sprel, old) - newsp = re.search(self.arch.re_sprel, new) - if oldsp and newsp: - oldrel = int(oldsp.group(1) or "0", 0) - newrel = int(newsp.group(1) or "0", 0) - score += abs(oldrel - newrel) * self.PENALTY_STACKDIFF - ignore_last_field = True - - # Probably regalloc difference, or signed vs unsigned - - # Compare each field in order - newfields, oldfields = new.split(","), old.split(",") - if ignore_last_field: - newfields = newfields[:-1] - oldfields = oldfields[:-1] - for nf, of in zip(newfields, oldfields): - if nf != of: - score += self.PENALTY_REGALLOC - # Penalize any extra fields - score += abs(len(newfields) - len(oldfields)) * self.PENALTY_REGALLOC - - def diff_insert(line: str) -> None: - # Reordering or totally different codegen. - # Defer this until later when we can tell. - insertions.append(line) - - def diff_delete(line: str) -> None: - deletions.append(line) - - self.differ.set_seq1(cand_seq) - for (tag, i1, i2, j1, j2) in self.differ.get_opcodes(): - if tag == "equal": - for k in range(i2 - i1): - old = self.target_seq[j1 + k].line - new = cand_seq[i1 + k].line - diff_sameline(old, new) - if tag == "replace" or tag == "delete": - for k in range(i1, i2): - diff_insert(cand_seq[k].line) - if tag == "replace" or tag == "insert": - for k in range(j1, j2): - diff_delete(self.target_seq[k].line) - - insertions_co = Counter(insertions) - deletions_co = Counter(deletions) - for item in insertions_co + deletions_co: - ins = insertions_co[item] - dels = deletions_co[item] - common = min(ins, dels) - score += ( - (ins - common) * self.PENALTY_INSERTION - + (dels - common) * self.PENALTY_DELETION - + self.PENALTY_REORDERING * common - ) - - return (score, hashlib.sha256(objdump_output.encode()).hexdigest()) diff --git a/tools/decomp-permuter/strip_other_fns.py b/tools/decomp-permuter/strip_other_fns.py deleted file mode 100644 index af29a01df..000000000 --- a/tools/decomp-permuter/strip_other_fns.py +++ /dev/null @@ -1,74 +0,0 @@ -import re -import argparse -from typing import Optional -from pathlib import Path - - -def _find_bracket_end(input: str, start_index: int) -> int: - level = 1 - assert input[start_index] == "{" - i = start_index + 1 - while i < len(input): - if input[i] == "{": - level += 1 - elif input[i] == "}": - level -= 1 - if level == 0: - break - i += 1 - - assert level == 0, "unbalanced {}" - return i - - -def strip_other_fns(source: str, keep_fn_name: str) -> str: - result = "" - remain = source - while True: - fn_regex = re.compile(r"^.*\s+\**(\w+)\(.*\)\s*?{", re.M) - fn = re.search(fn_regex, remain) - if fn is None: - result += remain - remain = "" - break - - fn_name = fn.group(1) - bracket_end = _find_bracket_end(remain, fn.end() - 1) - if fn_name.startswith("PERM"): - result += remain[: bracket_end + 1] - elif fn_name == keep_fn_name: - result += "\n\n" + remain[: bracket_end + 1] + "\n\n" - else: - result += remain[: fn.end() - 1].rstrip() + ";" - - remain = remain[bracket_end + 1 :] - - return result - - -def strip_other_fns_and_write( - source: str, fn_name: str, out_filename: Optional[str] = None -) -> None: - stripped = strip_other_fns(source, fn_name) - - if out_filename is None: - print(stripped) - else: - with open(out_filename, "w", encoding="utf-8") as f: - f.write(stripped) - - -def main() -> None: - parser = argparse.ArgumentParser( - description="Remove all but a single function definition from a file." - ) - parser.add_argument("c_file", help="File containing the function.") - parser.add_argument("fn_name", help="Function name.") - args = parser.parse_args() - - source = Path(args.c_file).read_text() - strip_other_fns_and_write(source, args.fn_name, args.c_file) - - -if __name__ == "__main__": - main() diff --git a/tools/decomp-permuter/stubs/pycparser/__init__.py b/tools/decomp-permuter/stubs/pycparser/__init__.py deleted file mode 100644 index 06e6865b6..000000000 --- a/tools/decomp-permuter/stubs/pycparser/__init__.py +++ /dev/null @@ -1,18 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: __init__.py -# -# This package file exports some convenience functions for -# interacting with pycparser -# -# Eli Bendersky [https://eli.thegreenplace.net/] -# License: BSD -#----------------------------------------------------------------- -__all__ = ['c_parser', 'c_ast'] -__version__ = '2.19' - -from typing import Any, List, Union -from . import c_ast -from .c_parser import CParser - -def preprocess_file(filename: str, cpp_path: str='cpp', cpp_args: Union[List[str], str]='') -> str: ... -def parse_file(filename: str, use_cpp: bool=False, cpp_path: str='cpp', cpp_args: str='', parser: Any=None) -> c_ast.FileAST: ... diff --git a/tools/decomp-permuter/stubs/pycparser/c_ast.py b/tools/decomp-permuter/stubs/pycparser/c_ast.py deleted file mode 100644 index 5f41f6c65..000000000 --- a/tools/decomp-permuter/stubs/pycparser/c_ast.py +++ /dev/null @@ -1,719 +0,0 @@ -# ----------------------------------------------------------------- -# pycparser: c_ast.py -# -# AST Node classes. -# -# Eli Bendersky [https://eli.thegreenplace.net/] -# License: BSD -# ----------------------------------------------------------------- - - -from typing import TextIO, Iterable, List, Any, Optional, Union as Union_ -from .plyparser import Coord -import sys - - -class Node(object): - coord: Optional[Coord] - - def __repr__(self) -> str: - ... - - def __iter__(self) -> Iterable[Node]: - ... - - def children(self) -> Iterable[Node]: - ... - - def show( - self, - buf: TextIO = sys.stdout, - offset: int = 0, - attrnames: bool = False, - nodenames: bool = False, - showcoord: bool = False, - ) -> None: - ... - - -Expression = Union_[ - "ArrayRef", - "Assignment", - "BinaryOp", - "Cast", - "CompoundLiteral", - "Constant", - "ExprList", - "FuncCall", - "ID", - "TernaryOp", - "UnaryOp", -] -Statement = Union_[ - Expression, - "Break", - "Case", - "Compound", - "Continue", - "Decl", - "Default", - "DoWhile", - "EmptyStatement", - "For", - "Goto", - "If", - "Label", - "Return", - "Switch", - "Typedef", - "While", - "Pragma", -] -Type = Union_["PtrDecl", "ArrayDecl", "FuncDecl", "TypeDecl"] -InnerType = Union_["IdentifierType", "Struct", "Union", "Enum"] -ExternalDeclaration = Union_["FuncDef", "Decl", "Typedef", "Pragma"] -AnyNode = Union_[ - Statement, - Type, - InnerType, - "FuncDef", - "EllipsisParam", - "Enumerator", - "EnumeratorList", - "FileAST", - "InitList", - "NamedInitializer", - "ParamList", - "Typename", -] - - -class NodeVisitor: - def visit(self, node: Node) -> None: - ... - - def generic_visit(self, node: Node) -> None: - ... - - def visit_ArrayDecl(self, node: ArrayDecl) -> None: - ... - - def visit_ArrayRef(self, node: ArrayRef) -> None: - ... - - def visit_Assignment(self, node: Assignment) -> None: - ... - - def visit_BinaryOp(self, node: BinaryOp) -> None: - ... - - def visit_Break(self, node: Break) -> None: - ... - - def visit_Case(self, node: Case) -> None: - ... - - def visit_Cast(self, node: Cast) -> None: - ... - - def visit_Compound(self, node: Compound) -> None: - ... - - def visit_CompoundLiteral(self, node: CompoundLiteral) -> None: - ... - - def visit_Constant(self, node: Constant) -> None: - ... - - def visit_Continue(self, node: Continue) -> None: - ... - - def visit_Decl(self, node: Decl) -> None: - ... - - def visit_DeclList(self, node: DeclList) -> None: - ... - - def visit_Default(self, node: Default) -> None: - ... - - def visit_DoWhile(self, node: DoWhile) -> None: - ... - - def visit_EllipsisParam(self, node: EllipsisParam) -> None: - ... - - def visit_EmptyStatement(self, node: EmptyStatement) -> None: - ... - - def visit_Enum(self, node: Enum) -> None: - ... - - def visit_Enumerator(self, node: Enumerator) -> None: - ... - - def visit_EnumeratorList(self, node: EnumeratorList) -> None: - ... - - def visit_ExprList(self, node: ExprList) -> None: - ... - - def visit_FileAST(self, node: FileAST) -> None: - ... - - def visit_For(self, node: For) -> None: - ... - - def visit_FuncCall(self, node: FuncCall) -> None: - ... - - def visit_FuncDecl(self, node: FuncDecl) -> None: - ... - - def visit_FuncDef(self, node: FuncDef) -> None: - ... - - def visit_Goto(self, node: Goto) -> None: - ... - - def visit_ID(self, node: ID) -> None: - ... - - def visit_IdentifierType(self, node: IdentifierType) -> None: - ... - - def visit_If(self, node: If) -> None: - ... - - def visit_InitList(self, node: InitList) -> None: - ... - - def visit_Label(self, node: Label) -> None: - ... - - def visit_NamedInitializer(self, node: NamedInitializer) -> None: - ... - - def visit_ParamList(self, node: ParamList) -> None: - ... - - def visit_PtrDecl(self, node: PtrDecl) -> None: - ... - - def visit_Return(self, node: Return) -> None: - ... - - def visit_Struct(self, node: Struct) -> None: - ... - - def visit_StructRef(self, node: StructRef) -> None: - ... - - def visit_Switch(self, node: Switch) -> None: - ... - - def visit_TernaryOp(self, node: TernaryOp) -> None: - ... - - def visit_TypeDecl(self, node: TypeDecl) -> None: - ... - - def visit_Typedef(self, node: Typedef) -> None: - ... - - def visit_Typename(self, node: Typename) -> None: - ... - - def visit_UnaryOp(self, node: UnaryOp) -> None: - ... - - def visit_Union(self, node: Union) -> None: - ... - - def visit_While(self, node: While) -> None: - ... - - def visit_Pragma(self, node: Pragma) -> None: - ... - - -class ArrayDecl(Node): - type: Type - dim: Optional[Expression] - dim_quals: List[str] - - def __init__( - self, - type: Type, - dim: Optional[Node], - dim_quals: List[str], - coord: Optional[Coord] = None, - ): - ... - - -class ArrayRef(Node): - name: Expression - subscript: Expression - - def __init__(self, name: Node, subscript: Node, coord: Optional[Coord] = None): - ... - - -class Assignment(Node): - op: str - lvalue: Expression - rvalue: Expression - - def __init__( - self, - op: str, - lvalue: Expression, - rvalue: Expression, - coord: Optional[Coord] = None, - ): - ... - - -class BinaryOp(Node): - op: str - left: Expression - right: Expression - - def __init__(self, op: str, left: Node, right: Node, coord: Optional[Coord] = None): - ... - - -class Break(Node): - def __init__(self, coord: Optional[Coord] = None): - ... - - -class Case(Node): - expr: Expression - stmts: List[Statement] - - def __init__( - self, expr: Expression, stmts: List[Statement], coord: Optional[Coord] = None - ): - ... - - -class Cast(Node): - to_type: "Typename" - expr: Expression - - def __init__( - self, to_type: "Typename", expr: Expression, coord: Optional[Coord] = None - ): - ... - - -class Compound(Node): - block_items: Optional[List[Statement]] - - def __init__( - self, block_items: Optional[List[Statement]], coord: Optional[Coord] = None - ): - ... - - -class CompoundLiteral(Node): - type: "Typename" - init: "InitList" - - def __init__( - self, type: "Typename", init: "InitList", coord: Optional[Coord] = None - ): - ... - - -class Constant(Node): - type: str - value: str - - def __init__(self, type: str, value: str, coord: Optional[Coord] = None): - ... - - -class Continue(Node): - def __init__(self, coord: Optional[Coord] = None): - ... - - -class Decl(Node): - name: Optional[str] - quals: List[str] # e.g. const - storage: List[str] # e.g. register - funcspec: List[str] # e.g. inline - type: Union_[Type, "Struct", "Union", "Enum"] - init: Optional[Union_[Expression, "InitList"]] - bitsize: Optional[Expression] - - def __init__( - self, - name: Optional[str], - quals: List[str], - storage: List[str], - funcspec: List[str], - type: Union_[Type, "Struct", "Union", "Enum"], - init: Optional[Union_[Expression, "InitList"]], - bitsize: Optional[Expression], - coord: Optional[Coord] = None, - ): - ... - - -class DeclList(Node): - decls: List[Decl] - - def __init__(self, decls: List[Decl], coord: Optional[Coord] = None): - ... - - -class Default(Node): - stmts: List[Statement] - - def __init__(self, stmts: List[Statement], coord: Optional[Coord] = None): - ... - - -class DoWhile(Node): - cond: Expression - stmt: Statement - - def __init__( - self, cond: Expression, stmt: Statement, coord: Optional[Coord] = None - ): - ... - - -class EllipsisParam(Node): - def __init__(self, coord: Optional[Coord] = None): - ... - - -class EmptyStatement(Node): - def __init__(self, coord: Optional[Coord] = None): - ... - - -class Enum(Node): - name: Optional[str] - values: "Optional[EnumeratorList]" - - def __init__( - self, - name: Optional[str], - values: "Optional[EnumeratorList]", - coord: Optional[Coord] = None, - ): - ... - - -class Enumerator(Node): - name: str - value: Optional[Expression] - - def __init__( - self, name: str, value: Optional[Expression], coord: Optional[Coord] = None - ): - ... - - -class EnumeratorList(Node): - enumerators: List[Enumerator] - - def __init__(self, enumerators: List[Enumerator], coord: Optional[Coord] = None): - ... - - -class ExprList(Node): - exprs: List[Union_[Expression, Typename]] # typename only for offsetof - - def __init__( - self, exprs: List[Union_[Expression, Typename]], coord: Optional[Coord] = None - ): - ... - - -class FileAST(Node): - ext: List[ExternalDeclaration] - - def __init__(self, ext: List[ExternalDeclaration], coord: Optional[Coord] = None): - ... - - -class For(Node): - init: Union_[None, Expression, DeclList] - cond: Optional[Expression] - next: Optional[Expression] - stmt: Statement - - def __init__( - self, - init: Union_[None, Expression, DeclList], - cond: Optional[Expression], - next: Optional[Expression], - stmt: Statement, - coord: Optional[Coord] = None, - ): - ... - - -class FuncCall(Node): - name: Expression - args: Optional[ExprList] - - def __init__( - self, name: Expression, args: Optional[ExprList], coord: Optional[Coord] = None - ): - ... - - -class FuncDecl(Node): - args: Optional[ParamList] - type: Type # return type - - def __init__( - self, args: Optional[ParamList], type: Type, coord: Optional[Coord] = None - ): - ... - - -class FuncDef(Node): - decl: Decl - param_decls: Optional[List[Decl]] - body: Compound - - def __init__( - self, - decl: Decl, - param_decls: Optional[List[Decl]], - body: Compound, - coord: Optional[Coord] = None, - ): - ... - - -class Goto(Node): - name: str - - def __init__(self, name: str, coord: Optional[Coord] = None): - ... - - -class ID(Node): - name: str - - def __init__(self, name: str, coord: Optional[Coord] = None): - ... - - -class IdentifierType(Node): - names: List[str] # e.g. ['long', 'int'] - - def __init__(self, names: List[str], coord: Optional[Coord] = None): - ... - - -class If(Node): - cond: Expression - iftrue: Statement - iffalse: Optional[Statement] - - def __init__( - self, - cond: Expression, - iftrue: Statement, - iffalse: Optional[Statement], - coord: Optional[Coord] = None, - ): - ... - - -class InitList(Node): - exprs: List[Union_[Expression, "NamedInitializer"]] - - def __init__( - self, - exprs: List[Union_[Expression, "NamedInitializer"]], - coord: Optional[Coord] = None, - ): - ... - - -class Label(Node): - name: str - stmt: Statement - - def __init__(self, name: str, stmt: Statement, coord: Optional[Coord] = None): - ... - - -class NamedInitializer(Node): - name: List[Expression] # [ID(x), Constant(4)] for {.x[4] = ...} - expr: Expression - - def __init__( - self, name: List[Expression], expr: Expression, coord: Optional[Coord] = None - ): - ... - - -class ParamList(Node): - params: List[Union_[Decl, ID, Typename, EllipsisParam]] - - def __init__( - self, - params: List[Union_[Decl, ID, Typename, EllipsisParam]], - coord: Optional[Coord] = None, - ): - ... - - -class PtrDecl(Node): - quals: List[str] - type: Type - - def __init__(self, quals: List[str], type: Type, coord: Optional[Coord] = None): - ... - - -class Return(Node): - expr: Optional[Expression] - - def __init__(self, expr: Optional[Expression], coord: Optional[Coord] = None): - ... - - -class Struct(Node): - name: Optional[str] - decls: Optional[List[Union_[Decl, Pragma]]] - - def __init__( - self, - name: Optional[str], - decls: Optional[List[Union_[Decl, Pragma]]], - coord: Optional[Coord] = None, - ): - ... - - -class StructRef(Node): - name: Expression - type: str - field: ID - - def __init__( - self, name: Expression, type: str, field: ID, coord: Optional[Coord] = None - ): - ... - - -class Switch(Node): - cond: Expression - stmt: Statement - - def __init__( - self, cond: Expression, stmt: Statement, coord: Optional[Coord] = None - ): - ... - - -class TernaryOp(Node): - cond: Expression - iftrue: Expression - iffalse: Expression - - def __init__( - self, - cond: Expression, - iftrue: Expression, - iffalse: Expression, - coord: Optional[Coord] = None, - ): - ... - - -class TypeDecl(Node): - declname: Optional[str] - quals: List[str] - type: InnerType - - def __init__( - self, - declname: Optional[str], - quals: List[str], - type: InnerType, - coord: Optional[Coord] = None, - ): - ... - - -class Typedef(Node): - name: str - quals: List[str] - storage: List[str] - type: Type - - def __init__( - self, - name: str, - quals: List[str], - storage: List[str], - type: Type, - coord: Optional[Coord] = None, - ): - ... - - -class Typename(Node): - name: None - quals: List[str] - type: Type - - def __init__( - self, name: None, quals: List[str], type: Type, coord: Optional[Coord] = None - ): - ... - - -class UnaryOp(Node): - op: str - expr: Union_[Expression, Typename] - - def __init__( - self, op: str, expr: Union_[Expression, Typename], coord: Optional[Coord] = None - ): - ... - - -class Union(Node): - name: Optional[str] - decls: Optional[List[Union_[Decl, Pragma]]] - - def __init__( - self, - name: Optional[str], - decls: Optional[List[Union_[Decl, Pragma]]], - coord: Optional[Coord] = None, - ): - ... - - -class While(Node): - cond: Expression - stmt: Statement - - def __init__( - self, cond: Expression, stmt: Statement, coord: Optional[Coord] = None - ): - ... - - -class Pragma(Node): - string: str - - def __init__(self, string: str, coord: Optional[Coord] = None): - ... diff --git a/tools/decomp-permuter/stubs/pycparser/c_generator.py b/tools/decomp-permuter/stubs/pycparser/c_generator.py deleted file mode 100644 index ea3b70d07..000000000 --- a/tools/decomp-permuter/stubs/pycparser/c_generator.py +++ /dev/null @@ -1,13 +0,0 @@ -#------------------------------------------------------------------------------ -# pycparser: c_generator.py -# -# C code generator from pycparser AST nodes. -# -# Eli Bendersky [https://eli.thegreenplace.net/] -# License: BSD -#------------------------------------------------------------------------------ -from . import c_ast - -class CGenerator: - def __init__(self) -> None: ... - def visit(self, node: c_ast.Node) -> str: ... diff --git a/tools/decomp-permuter/stubs/pycparser/c_parser.py b/tools/decomp-permuter/stubs/pycparser/c_parser.py deleted file mode 100644 index fac2fa838..000000000 --- a/tools/decomp-permuter/stubs/pycparser/c_parser.py +++ /dev/null @@ -1,15 +0,0 @@ -#------------------------------------------------------------------------------ -# pycparser: c_parser.py -# -# CParser class: Parser and AST builder for the C language -# -# Eli Bendersky [https://eli.thegreenplace.net/] -# License: BSD -#------------------------------------------------------------------------------ - -from . import c_ast - -class CParser: - def __init__(self) -> None: ... - def parse(self, text: str, filename: str='', debuglevel: int=0) -> c_ast.FileAST: ... - diff --git a/tools/decomp-permuter/stubs/pycparser/plyparser.py b/tools/decomp-permuter/stubs/pycparser/plyparser.py deleted file mode 100644 index e63c53efb..000000000 --- a/tools/decomp-permuter/stubs/pycparser/plyparser.py +++ /dev/null @@ -1,27 +0,0 @@ -# ----------------------------------------------------------------- -# plyparser.py -# -# PLYParser class and other utilites for simplifying programming -# parsers with PLY -# -# Eli Bendersky [https://eli.thegreenplace.net/] -# License: BSD -# ----------------------------------------------------------------- - -from typing import Optional - - -class Coord: - file: str - line: int - column: Optional[int] - - def __init__(self, file: str, line: int, column: Optional[int] = None): - ... - - def __str__(self) -> str: - ... - - -class ParseError(Exception): - pass diff --git a/tools/decomp-permuter/test.py b/tools/decomp-permuter/test.py deleted file mode 100755 index aecdb14ac..000000000 --- a/tools/decomp-permuter/test.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python3 -import sys - -from pycparser import parse_file, c_generator - -fname = "test.c" if len(sys.argv) < 2 else sys.argv[1] - - -# ast = c_parser.CParser().parse(src) -ast = parse_file(fname, use_cpp=True) -# ast.show() -# print(c_generator.CGenerator().visit(ast)) -print(ast) diff --git a/tools/decomp-permuter/test/__init__.py b/tools/decomp-permuter/test/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/tools/decomp-permuter/test/compile.sh b/tools/decomp-permuter/test/compile.sh deleted file mode 100755 index 7788134bf..000000000 --- a/tools/decomp-permuter/test/compile.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -mips-linux-gnu-gcc -O2 -fno-PIC -fno-common -ffreestanding -mno-shared -mno-abicalls -G 0 -c "$@" diff --git a/tools/decomp-permuter/test/test_perm.py b/tools/decomp-permuter/test/test_perm.py deleted file mode 100644 index f3cc520ce..000000000 --- a/tools/decomp-permuter/test/test_perm.py +++ /dev/null @@ -1,247 +0,0 @@ -import os -from pathlib import Path -import re -import shutil -import tempfile -from typing import Any, Optional -import unittest - -from src.compiler import Compiler -from src.preprocess import preprocess -from src import main - - -class TestPermMacros(unittest.TestCase): - def go( - self, - intro: str, - outro: str, - base: str, - target: str, - *, - fn_name: Optional[str] = None, - **kwargs: Any - ) -> int: - base = intro + "\n" + base + "\n" + outro - target = intro + "\n" + target + "\n" + outro - compiler = Compiler("test/compile.sh", show_errors=True) - - # For debugging, to avoid the auto-deleted directory: - # target_dir = tempfile.mkdtemp() - with tempfile.TemporaryDirectory() as target_dir: - with open(os.path.join(target_dir, "base.c"), "w") as f: - f.write(base) - - target_o = compiler.compile(target, show_errors=True) - assert target_o is not None - shutil.move(target_o, os.path.join(target_dir, "target.o")) - - shutil.copy2("test/compile.sh", os.path.join(target_dir, "compile.sh")) - - if fn_name: - with open(os.path.join(target_dir, "function.txt"), "w") as f: - f.write(fn_name) - - opts = main.Options(directories=[target_dir], stop_on_zero=True, **kwargs) - return main.run(opts)[0] - - def test_general(self) -> None: - score = self.go( - "int test() {", - "}", - "return PERM_GENERAL(32,64);", - "return 64;", - ) - self.assertEqual(score, 0) - - def test_not_found(self) -> None: - score = self.go( - "int test() {", - "}", - "return PERM_GENERAL(32,64);", - "return 92;", - ) - self.assertNotEqual(score, 0) - - def test_multiple_functions(self) -> None: - score = self.go( - "", - "", - """ - int ignoreme() {} - int foo() { return PERM_GENERAL(32,64); } - int ignoreme2() {} - """, - "int foo() { return 64; }", - fn_name="foo", - ) - self.assertEqual(score, 0) - - def test_general_multiple(self) -> None: - score = self.go( - "int test() {", - "}", - "return PERM_GENERAL(1,2,3) + PERM_GENERAL(3,6,9);", - "return 9;", - ) - self.assertEqual(score, 0) - - def test_general_nested(self) -> None: - score = self.go( - "int test() {", - "}", - "return PERM_GENERAL(1,PERM_GENERAL(100,101),3) + PERM_GENERAL(3,6,9);", - "return 110;", - ) - self.assertEqual(score, 0) - - def test_cast(self) -> None: - score = self.go( - "int test(int a, int b) {", - "}", - "return a / PERM_GENERAL(,(unsigned int),(float)) b;", - "return a / (float) b;", - ) - self.assertEqual(score, 0) - - def test_cast_threaded(self) -> None: - score = self.go( - "int test(int a, int b) {", - "}", - "return a / PERM_GENERAL(,(unsigned int),(float)) b;", - "return a / (float) b;", - threads=2, - ) - self.assertEqual(score, 0) - - def test_ignore(self) -> None: - score = self.go( - "int test(int a, int b) {", - "}", - "PERM_IGNORE( return a / PERM_GENERAL(a, b); )", - "return a / b;", - ) - self.assertEqual(score, 0) - - def test_pretend(self) -> None: - score = self.go( - "int global;", - "", - """ - PERM_IGNORE( inline void foo() { ) - PERM_PRETEND( void foo(); void bar() { ) - PERM_RANDOMIZE( - global = 1; - ) - PERM_IGNORE( } void bar() { ) - PERM_RANDOMIZE( - global = 2; foo(); - ) - } - """, - """ - inline void foo() { global = 1; } - void bar() { foo(); global = 2; } - """, - fn_name="bar", - ) - self.assertEqual(score, 0) - - def test_once1(self) -> None: - score = self.go( - "volatile int A, B, C; void test() {", - "}", - """ - PERM_ONCE(B = 2;) - A = 1; - PERM_ONCE(B = 2;) - C = 3; - PERM_ONCE(B = 2;) - """, - "A = 1; B = 2; C = 3;", - ) - self.assertEqual(score, 0) - - def test_once2(self) -> None: - score = self.go( - "volatile int A, B, C; void test() {", - "}", - """ - PERM_VAR(emit,) - PERM_VAR(bademit,) - PERM_ONCE(1, PERM_VAR(bademit, A = 7;) A = 2;) - PERM_ONCE(1, PERM_VAR(emit, A = 1;)) - PERM_VAR(emit) - PERM_VAR(bademit) - PERM_ONCE(2, B = 2;) - PERM_ONCE(2, B = 1;) - PERM_ONCE(2,) - PERM_ONCE(3, PERM_VAR(bademit, A = 9)) - PERM_ONCE(3, PERM_VAR(bademit, A = 9)) - C = 3; - """, - "A = 1; B = 2; C = 3;", - ) - self.assertEqual(score, 0) - - def test_lineswap(self) -> None: - score = self.go( - "void a(); void b(); void c(); void test(void) {", - "}", - """ - PERM_LINESWAP( - a(); - b(); - c(); - ) - """, - "b(); a(); c();", - ) - self.assertEqual(score, 0) - - def test_lineswap_text(self) -> None: - score = self.go( - "void a(); void b(); void c(); void test(void) {", - "}", - """ - PERM_LINESWAP_TEXT( - a(); - b(); - c(); - ) - """, - "b(); a(); c();", - ) - self.assertEqual(score, 0) - - def test_randomizer(self) -> None: - score = self.go( - "void foo(); void bar(); void test(void) {", - "}", - "PERM_RANDOMIZE(bar(); foo();)", - "foo(); bar();", - ) - self.assertEqual(score, 0) - - def test_auto_randomizer(self) -> None: - score = self.go( - "void foo(); void bar(); void test(void) {", - "}", - "bar(); foo();", - "foo(); bar();", - ) - self.assertEqual(score, 0) - - def test_randomizer_threaded(self) -> None: - score = self.go( - "void foo(); void bar(); void test(void) {", - "}", - "PERM_RANDOMIZE(bar(); foo();)", - "foo(); bar();", - threads=2, - ) - self.assertEqual(score, 0) - - -if __name__ == "__main__": - unittest.main() diff --git a/tools/disasm/disasm.py b/tools/disasm/disasm.py old mode 100644 new mode 100755 index 1cb68106a..cb634d138 --- a/tools/disasm/disasm.py +++ b/tools/disasm/disasm.py @@ -1,124 +1,290 @@ #!/usr/bin/env python3 -import ast, math, os, re, struct -from mips_isa import * +import argparse, ast, math, os, re, struct +import bisect +import multiprocessing +from pathlib import Path +import mips_isa + +# Consider implementing gpr naming too, but already uses abi names by default +fpr_name_options = { + "numeric": mips_isa.numeric_fpr_names, + "o32": mips_isa.o32_fpr_names, +} + +parser = argparse.ArgumentParser() +parser.add_argument( + "-j", dest="jobs", type=int, default=1, help="number of processes to run at once" +) +parser.add_argument( + "-a", + "--all", + dest="all", + action="store_true", + default=False, + help="Decompile all files regardless of whether they are used or not", +) +parser.add_argument( + "-f", + "--files", + dest="files", + nargs="+", + required=False, + help="Optional list of files to diassemble separated by a space. This is a whitelist, all files will be skipped besides the ones listed here if used.", +) +parser.add_argument("--reg-names", choices=fpr_name_options.keys(), help="How to name registers in the output") + +args = parser.parse_args() +jobs = args.jobs + +mips_isa.mips_fpr_names = fpr_name_options.get(args.reg_names, mips_isa.mips_fpr_names) + ASM_OUT = "asm/" DATA_OUT = "data/" + +def discard_decomped_files(files_spec, include_files): + 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 + + force_include = False + if include_files: + if not any([x in name for x in include_files]): + continue + force_include = True + + # 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 + + include |= force_include + 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_isa.MIPS_INS_BEQL, + mips_isa.MIPS_INS_BGEZALL, + mips_isa.MIPS_INS_BGEZL, + mips_isa.MIPS_INS_BGTZL, + mips_isa.MIPS_INS_BLEZL, + mips_isa.MIPS_INS_BLTZALL, + mips_isa.MIPS_INS_BLTZL, + mips_isa.MIPS_INS_BNEL, + mips_isa.MIPS_INS_BC1TL, + mips_isa.MIPS_INS_BC1FL, ] MIPS_BRANCH_INSNS = [ *MIPS_BRANCH_LIKELY_INSNS, - MIPS_INS_BEQ, - MIPS_INS_BGEZ, MIPS_INS_BGEZAL, - MIPS_INS_BGTZ, - MIPS_INS_BNE, - MIPS_INS_BLTZ, MIPS_INS_BLTZAL, - MIPS_INS_BLEZ, - MIPS_INS_BC1T, MIPS_INS_BC1F, - - MIPS_INS_BEQZ, - MIPS_INS_BNEZ, - MIPS_INS_B, + mips_isa.MIPS_INS_BEQ, + mips_isa.MIPS_INS_BGEZ, + mips_isa.MIPS_INS_BGEZAL, + mips_isa.MIPS_INS_BGTZ, + mips_isa.MIPS_INS_BNE, + mips_isa.MIPS_INS_BLTZ, + mips_isa.MIPS_INS_BLTZAL, + mips_isa.MIPS_INS_BLEZ, + mips_isa.MIPS_INS_BC1T, + mips_isa.MIPS_INS_BC1F, + mips_isa.MIPS_INS_BEQZ, + mips_isa.MIPS_INS_BNEZ, + mips_isa.MIPS_INS_B, ] -MIPS_JUMP_INSNS = [ - MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J, MIPS_INS_JR -] +MIPS_JUMP_INSNS = [mips_isa.MIPS_INS_JAL, mips_isa.MIPS_INS_JALR, mips_isa.MIPS_INS_J, mips_isa.MIPS_INS_JR] -MIPS_FP_LOAD_INSNS = [ - MIPS_INS_LWC1, MIPS_INS_LDC1 -] +MIPS_FP_LOAD_INSNS = [mips_isa.MIPS_INS_LWC1, mips_isa.MIPS_INS_LDC1] -MIPS_FP_STORE_INSNS = [ - MIPS_INS_SWC1, MIPS_INS_SDC1 -] +MIPS_FP_STORE_INSNS = [mips_isa.MIPS_INS_SWC1, mips_isa.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_isa.MIPS_INS_SB, + mips_isa.MIPS_INS_SH, + mips_isa.MIPS_INS_SW, + mips_isa.MIPS_INS_SWL, + mips_isa.MIPS_INS_SWR, + mips_isa.MIPS_INS_SD, + mips_isa.MIPS_INS_SDL, + mips_isa.MIPS_INS_SDR, + mips_isa.MIPS_INS_SC, + mips_isa.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_isa.MIPS_INS_LB, + mips_isa.MIPS_INS_LBU, + mips_isa.MIPS_INS_LH, + mips_isa.MIPS_INS_LHU, + mips_isa.MIPS_INS_LW, + mips_isa.MIPS_INS_LWL, + mips_isa.MIPS_INS_LWR, + mips_isa.MIPS_INS_LWU, + mips_isa.MIPS_INS_LD, + mips_isa.MIPS_INS_LDL, + mips_isa.MIPS_INS_LDR, + mips_isa.MIPS_INS_LL, + mips_isa.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: @@ -133,63 +299,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 """ @@ -210,20 +390,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): @@ -234,8 +443,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]) @@ -256,7 +465,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: @@ -285,18 +496,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)) @@ -304,7 +517,71 @@ def format_f32(f_wd): return f".word 0x{f_wd:08X}" return f".float {reduce_float(repr(f))}" -def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): + +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) + elif setname == "data_labels": + data_labels.update(symbol) + elif setname == "branch_labels": + branch_labels.update(symbol) + elif setname == "jtbls": + jtbls.update(symbol) + elif setname == "jtbl_labels": + jtbl_labels.update(symbol) + elif setname == "floats": + floats.update(symbol) + elif setname == "doubles": + doubles.update(symbol) + elif setname == "prospective_strings": + prospective_strings.update(symbol) + elif setname == "strings": + strings.update(symbol) + elif setname == "symbols": + symbols.update(symbol) + elif setname == "constants": + constants.update(symbol) + elif setname == "dwords": + dwords.update(symbol) + elif setname == "files": + files.update(symbol) + + 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 {info['name']}") + if rodata is not None: rodata_words = as_word_list(rodata) @@ -312,18 +589,19 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): assert vram % 0x10 == 0 - functions.add(vram) - files.add(vram) + put_symbol(symbols_dict, "functions", vram) + 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() @@ -331,7 +609,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 @@ -347,60 +625,30 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): # assert insn.value_forname(insn.fields[0]) is not None # 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]) + # assert insn.id not in [MIPS_INS_ORI, mips_isa.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) for region in data_regions: assert region[1] != 0 - functions.add(region[1]) + put_symbol(symbols_dict, "functions", region[1]) if region[1] % 0x10 == 0: - files.add(region[1]) + 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]) + insns = [] + for i, raw_insn in enumerate(raw_insns, 0): + insn = mips_isa.decode_insn(raw_insn, vram + i * 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" - functions.add(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 - symbols.update({hi_vram : symbol_value}) - symbols.update({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) - - if insn.id == MIPS_INS_JR and insn.rs != MIPS_REG_RA: + if insn.id == mips_isa.MIPS_INS_JR and insn.rs != mips_isa.MIPS_REG_RA: # It's hard to find when two jump tables next to each other end, so do a naive first pass # to try and find as many jump tables as possible. # Luckily IDO has a very homogeneous output for jump tables for which it is very unlikely @@ -409,17 +657,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_isa.MIPS_INS_LW + and insn_m2.id == mips_isa.MIPS_INS_ADDU + and insn_m3.id == mips_isa.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_isa.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_isa.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_isa.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 @@ -428,14 +731,24 @@ 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: + if vaddr in functions or vaddr in symbols_dict["functions"]: # add func branch labels to all branch labels - branch_labels.update(func_branch_labels) + put_symbols(symbols_dict, "branch_labels", func_branch_labels) func_branch_labels.clear() # add func jtbl labels to all jtbl labels - jtbl_labels.update(func_jtbl_labels) + put_symbols(symbols_dict, "jtbl_labels", func_jtbl_labels) func_jtbl_labels.clear() # clear individual jtbl labels individual_jtbl_labels.clear() @@ -454,75 +767,110 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): if insn.id in MIPS_BRANCH_INSNS: func_branch_labels.add(insn.offset) delayed_insn = insn - elif insn.id == MIPS_INS_ERET: - functions.add(vaddr + 4) + elif insn.id == mips_isa.MIPS_INS_ERET: + put_symbol(symbols_dict, "functions", vaddr + 4) elif insn.id in MIPS_JUMP_INSNS: - if insn.id == MIPS_INS_JAL: + if insn.id == mips_isa.MIPS_INS_JAL: # mark function at target - functions.add(insn.target) - elif insn.id == MIPS_INS_J: + put_symbol(symbols_dict, "functions", insn.target) + elif insn.id == mips_isa.MIPS_INS_J: # mark label at target func_branch_labels.add(insn.target) - elif insn.id == MIPS_INS_JR: + elif insn.id == mips_isa.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}" - files.add(vaddr + 8 + n_padding * 4) - functions.add(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: + elif insn.id == mips_isa.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)}) - elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS: + lui_tracker.update({insn.rt: (vaddr, insn.imm)}) + elif insn.id == mips_isa.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_isa.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_isa.MIPS_INS_ADDIU) + ): lo_vram = vaddr symbol_value = (imm_value << 0x10) + insn.imm - symbols.update({hi_vram : symbol_value}) - symbols.update({lo_vram : symbol_value}) - if insn.id == MIPS_INS_LW: + put_symbols(symbols_dict, "symbols", {hi_vram: symbol_value}) + put_symbols(symbols_dict, "symbols", {lo_vram: symbol_value}) + if insn.id == mips_isa.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]: - 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): + while lookahead_insn.id not in [ + *MIPS_BRANCH_INSNS, + mips_isa.MIPS_INS_JAL, + mips_isa.MIPS_INS_JALR, + mips_isa.MIPS_INS_J, + ]: + if lookahead_insn.id == mips_isa.MIPS_INS_JR: + 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 @@ -530,47 +878,58 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): break label = rodata_words[offset] - jtbls.add(symbol_value) + 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 - dwords.add(symbol_value) - elif insn.id in [MIPS_INS_LWC1, MIPS_INS_SWC1]: # float load/stores + lookahead_insn = insns[cur_idx] # TODO fix vaddr here + elif insn.id == mips_isa.MIPS_INS_LD: # doubleword loads + put_symbol(symbols_dict, "dwords", symbol_value) + elif insn.id in [mips_isa.MIPS_INS_LWC1, mips_isa.MIPS_INS_SWC1]: # float load/stores # add float - floats.add(symbol_value) - elif insn.id in [MIPS_INS_LDC1, MIPS_INS_SDC1]: # double load/stores + put_symbol(symbols_dict, "floats", symbol_value) + elif insn.id in [mips_isa.MIPS_INS_LDC1, mips_isa.MIPS_INS_SDC1]: # double load/stores # add double - doubles.add(symbol_value) - elif insn.id == MIPS_INS_ADDIU and vaddr % 4 == 0: # strings seem to only ever be 4-byte aligned + put_symbol(symbols_dict, "doubles", symbol_value) + elif ( + insn.id == mips_isa.MIPS_INS_ADDIU and vaddr % 4 == 0 + ): # strings seem to only ever be 4-byte aligned # add possible string - prospective_strings.add(symbol_value) + 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_isa.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: + elif insn.id == mips_isa.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 - constants.update({hi_vram : const_value}) - constants.update({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_isa.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 @@ -579,25 +938,116 @@ 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_isa.MIPS_INS_MTC0, + mips_isa.MIPS_INS_MTC1, + mips_isa.MIPS_INS_DMTC1, + mips_isa.MIPS_INS_MULT, + mips_isa.MIPS_INS_MULTU, + mips_isa.MIPS_INS_DMULT, + mips_isa.MIPS_INS_DMULTU, + mips_isa.MIPS_INS_DIV, + mips_isa.MIPS_INS_DIVU, + mips_isa.MIPS_INS_DDIV, + mips_isa.MIPS_INS_DDIVU, + mips_isa.MIPS_INS_MTHI, + mips_isa.MIPS_INS_MTLO, + mips_isa.MIPS_INS_CTC1, + mips_isa.MIPS_INS_NOP, + mips_isa.MIPS_INS_BREAK, + mips_isa.MIPS_INS_TLBP, + mips_isa.MIPS_INS_TLBR, + mips_isa.MIPS_INS_TLBWI, + mips_isa.MIPS_INS_MOV_S, + mips_isa.MIPS_INS_MOV_D, + mips_isa.MIPS_INS_C_LT_S, + mips_isa.MIPS_INS_C_LT_D, + mips_isa.MIPS_INS_DIV_S, + mips_isa.MIPS_INS_MUL_S, + mips_isa.MIPS_INS_TRUNC_W_S, + mips_isa.MIPS_INS_CVT_S_W, + mips_isa.MIPS_INS_SUB_S, + mips_isa.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_isa.MIPS_INS_LUI: + op_str = [op_str] + instr["rt"] = insn.rt + + elif insn.id == mips_isa.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_isa.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_isa.MIPS_INS_JAL + or delayed_insn.id == mips_isa.MIPS_INS_JALR + or (delayed_insn.id == mips_isa.MIPS_INS_JR and delayed_insn.rs == mips_isa.MIPS_REG_RA) + ): # destroy lui tracking state lui_tracker.clear() - elif delayed_insn.id == MIPS_INS_JR and vaddr == next_jtbl_jr + 4: + elif delayed_insn.id == mips_isa.MIPS_INS_JR and vaddr == next_jtbl_jr + 4: # save lui tracking state for each jtbl label for label in individual_jtbl_labels[next_jtbl_jr]: save_tracker(label, lui_tracker.copy()) @@ -606,83 +1056,131 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs): # save lui tracking state save_tracker(delayed_insn.offset, lui_tracker.copy()) # destroy current lui tracking state for unconditional branches - if delayed_insn.id == MIPS_INS_B: + if delayed_insn.id == mips_isa.MIPS_INS_B: lui_tracker.clear() delayed_insn = None delay_slot = delayed_insn is not None - branch_labels.update(func_branch_labels) - jtbl_labels.update(func_jtbl_labels) + result_files.append([cur_file, results]) -def find_symbols_in_data(data, vram, end, relocs): + put_symbols(symbols_dict, "branch_labels", func_branch_labels) + put_symbols(symbols_dict, "jtbl_labels", func_jtbl_labels) + + return symbols_dict, result_files + + +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 {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 .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: @@ -693,7 +1191,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 @@ -703,8 +1201,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: @@ -712,14 +1212,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 @@ -732,36 +1234,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_isa.MIPS_INS_LUI: + symbol_value = symbols.get(vaddr, None) + if symbol_value is not None: + line += ( + f"{ mips_isa.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_isa.mips_gpr_names[insn['rt']]}, (0x{constant_value:08X} >> 16)" + ) + else: + line += entry["op"][0] + + elif insn["id"] == mips_isa.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_isa.MIPS_INS_ADDIU: + line += f"{ mips_isa.mips_gpr_names[insn['rt']]}, { mips_isa.mips_gpr_names[insn['rs']]}, %lo({proper_name(symbol_value)})" + else: + line += f"{mips_isa.mips_fpr_names[insn['ft']] if insn['id'] in MIPS_FP_LOAD_STORE_INSNS else mips_isa.mips_gpr_names[insn['rt']]}, %lo({proper_name(symbol_value)})({ mips_isa.mips_gpr_names[insn['base']]})" + else: + line += entry["op"][0] + + elif insn["id"] == mips_isa.MIPS_INS_ORI: + constant_value = constants.get(vaddr, None) + if constant_value is not None: + line += f"{ mips_isa.mips_gpr_names[insn['rt']]}, { mips_isa.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 = mips_isa.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}.{section[2]}.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 @@ -770,9 +1364,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 @@ -787,7 +1384,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)) @@ -796,31 +1393,33 @@ 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)) op_str = ", ".join(op_str_parts) delayed_insn = insn - elif insn.id == MIPS_INS_LUI: + elif insn.id == mips_isa.MIPS_INS_LUI: symbol_value = symbols.get(vaddr, None) if symbol_value is not None: - op_str = f"{mips_gpr_names[insn.rt]}, %hi({proper_name(symbol_value)})" + op_str = f"{ mips_isa.mips_gpr_names[insn.rt]}, %hi({proper_name(symbol_value)})" 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)" - elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS: + op_str = ( + f"{ mips_isa.mips_gpr_names[insn.rt]}, (0x{constant_value:08X} >> 16)" + ) + elif insn.id == mips_isa.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: - op_str = f"{mips_gpr_names[insn.rt]}, {mips_gpr_names[insn.rs]}, %lo({proper_name(symbol_value)})" + if insn.id == mips_isa.MIPS_INS_ADDIU: + op_str = f"{ mips_isa.mips_gpr_names[insn.rt]}, { mips_isa.mips_gpr_names[insn.rs]}, %lo({proper_name(symbol_value)})" else: - op_str = 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]})" - elif insn.id == MIPS_INS_ORI: + op_str = f"{mips_isa.mips_fpr_names[insn.ft] if insn.id in MIPS_FP_LOAD_STORE_INSNS else mips_isa.mips_gpr_names[insn.rt]}, %lo({proper_name(symbol_value)})({ mips_isa.mips_gpr_names[insn.base]})" + elif insn.id == mips_isa.MIPS_INS_ORI: constant_value = constants.get(vaddr, None) if constant_value is not None: - op_str = f"{mips_gpr_names[insn.rt]}, {mips_gpr_names[insn.rs]}, (0x{constant_value:08X} & 0xFFFF)" + op_str = f"{ mips_isa.mips_gpr_names[insn.rt]}, { mips_isa.mips_gpr_names[insn.rs]}, (0x{constant_value:08X} & 0xFFFF)" if delay_slot: mnemonic = " " + mnemonic @@ -831,194 +1430,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}.{section[2]}.s", "w") as outfile: + 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 @@ -1026,137 +1889,64 @@ 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") +def disassemble_makerom(section): + os.makedirs(f"{ASM_OUT}/makerom/", exist_ok=True) -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") - -# Find symbols for each segment -for segment in files_spec: - if segment[2] == 'makerom': - continue - - print(f"Finding symbols 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)}) - - 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 - find_symbols_in_text(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]) - elif section[2] == 'data': - find_symbols_in_data(section[4], section[0], section[1], section[5]) - elif 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] - -print("Disassembling Segments") - -# Textual disassembly for each segment -for segment in files_spec: - if segment[2] == 'makerom': - 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"""/* * The Legend of Zelda: Majora's Mask ROM header @@ -1180,46 +1970,48 @@ for segment in files_spec: with open(ASM_OUT + "/makerom/rom_header.s", "w") as outfile: outfile.write(out) + 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) + 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}) + 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(entry, entry_addr, [], segment) + disassemble_text(section[4], entry_addr, [], section[-1]) # manually set boot bss size... entry_asm = "" - with open(f"{ASM_OUT}/makerom/entry.reloc.s") as infile: # TODO why is this written out as .reloc.s + 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) - os.remove(f"{ASM_OUT}/makerom/entry.reloc.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) - - continue - elif 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 @@ -1237,129 +2029,132 @@ for segment in files_spec: 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) - continue + with open(ASM_OUT + "/dmadata/dmadata.s", "w") as outfile: + outfile.write(out) - 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])) - 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]) +def disassemble_segment(section): + if section[-1]["name"] == "[PADDING]": + return - # ("" if segment[2] != "overlay" else "overlays/") + - segment_dirname = segment[0] + print(f"Disassembling {section[-1]['name']} .{section[2]}") - result = asm_header(".rodata") - result += f"\nglabel {segment[0]}_Reloc\n" + 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]) - 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" + segment_dirname = section[-1]["name"] - 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) + result = asm_header(".rodata") + result += f"\nglabel {section[-1]['name']}_Reloc\n" -print("Splitting text and migrating rodata") + 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}/{section[-1]['name']}.reloc.s", "w" + ) as outfile: + outfile.write(result) -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 @@ -1371,7 +2166,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 @@ -1383,149 +2178,468 @@ 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 -# Split files and migrate rodata that should be migrated -for root,dirs,files in os.walk(ASM_OUT): - for f in files: - if "non_matchings" in root: + +# ==========================================# + +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.all: + new_spec = [] + for segment in files_spec: + if args.files and not any( + [file_name in segment[0] for file_name in args.files] + ): 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") + for offset, name in segment[4].items(): + if name == "": + name = f"{segment[2]}_{offset:08X}" + segment[4][offset] = name + new_spec.append(segment) + files_spec = new_spec +else: + # Prune + old_file_count = sum([len(f[4].keys()) for f in files_spec]) - print(asm_path) + files_spec = discard_decomped_files(files_spec, args.files) - asm = "" - with open(asm_path,"r") as infile: - asm = infile.read() + new_file_count = sum([len(f[4].keys()) for f in files_spec]) - rodata = "" - if os.path.exists(rodata_path): - # print(rodata_path) - with open(rodata_path, "r") as rodata_file: - rodata = rodata_file.read() + pruned = old_file_count - new_file_count + print(f"Pruned {pruned}/{old_file_count} files ({pruned / old_file_count:.02%})") - rodata_info = list(zip(rodata_syms(rodata), rodata_blocks(rodata))) +# Find floats, doubles, and strings +for var in sorted(variables_ast.keys()): + var_type = variables_ast[var][1] - # populate rdata and late_rodata lists - 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 = late_rodata_info - target.append((sym,block)) + 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) - # print([(sym,block.split("\n")[1:]) for sym,block in zip(rdata_syms,rdata_blocks)]) +# 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()) - function_info = list(zip([s.replace("glabel","").strip() for s in func_regex.findall(asm)], func_regex.split(asm)[1:])) + 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] - rdata_map = {} - late_rodata_map = {} +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 = multiprocessing.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 = multiprocessing.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 multiprocessing.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 file in Path(ASM_OUT).glob("**/*.s"): + asm_path = str(file) + + if "non_matchings" in asm_path: + continue + + if file.parts[1] == "overlays": + name = file.parts[2] + else: + name = file.parts[1] + + if not any([name == section[-1]["name"] for section in all_sections]): + continue + + 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: + asm = infile.read() + + rodata = "" + if os.path.exists(rodata_path): + # print(rodata_path) + with open(rodata_path, "r") as rodata_file: + rodata = rodata_file.read() + + rodata_info = list(zip(rodata_syms(rodata), rodata_blocks(rodata))) + + # populate rdata and late_rodata lists + 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: + # now populate late_rodata, if there is any + if sym == first_late_rodata: + target = late_rodata_info + 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:], + ) + ) + + rdata_map = {} + late_rodata_map = {} + + # pass 1 to resolve rodata splits + if rodata != "": + last_fn = None + + 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 + ] + # ignore multiple refs, take only the first + 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: + ref = referenced_in[sym] + if first: + cr = ref or sym + + if ref is not None and not first: + if ref != last_ref: + # existing function + cr = ref + 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)) + + # setup next iter + last_ref = ref + first = False + + do_splits(rdata_map, rdata_info) + 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()) + ) + + # pass 2 to output splits + for label in all_output: + fn_body = dict(function_info).get(label, None) + + text_out = "" + rodata_out = "" + + if fn_body is not None: + text_out = "glabel " + label.strip() + "\n" + fn_body.strip() + "\n" - # pass 1 to resolve rodata splits if rodata != "": - last_fn = None + rdata = rdata_map.get(label, None) + late_rodata = late_rodata_map.get(label, None) - referenced_in = {} # key=rodata label , value=function label + # 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.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"): + 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? + late_rodata_alignment = ( + f".late_rodata_alignment {'8' if vaddr % 8 == 0 else '4'}\n" + ) - 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 }) + rdata_out = "" + if rdata is not None: + rdata_out = ".rdata\n" + "".join([block for _, block in rdata]) - def do_splits(out_dict, info): - first = True - last_ref = None - cr = None - for sym,block in info: - ref = referenced_in[sym] - if first: - cr = ref or sym + 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]) + ) - if ref is not None and not first: - if ref != last_ref: - # existing function - cr = ref - 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)) + 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 "" + ) + ) - # setup next iter - last_ref = ref - first = False + all_out = rodata_out + text_out - do_splits(rdata_map, rdata_info) - do_splits(late_rodata_map, late_rodata_info) + # write it out + out_path = Path(asm_path.replace(ASM_OUT, f"{ASM_OUT}non_matchings/")).parent + if out_path.parts[2] not in ("overlays", "makerom"): + out_path /= file.name.split(".")[0] + out_path.mkdir(parents=True, exist_ok=True) - # 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())) - - # pass 2 to output splits - for label in all_output: - fn_body = dict(function_info).get(label, None) - - text_out = "" - rodata_out = "" - - if fn_body is not None: - text_out = "glabel " + label.strip() + "\n" + fn_body.strip() + "\n" - - if rodata != "": - rdata = rdata_map.get(label, None) - late_rodata = late_rodata_map.get(label, None) - - # 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: - # 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"): - 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? - 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]) - - 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]) - - 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 "") - 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 + out_path /= label + ".s" + with open(out_path, "w") as outfile: + outfile.write(all_out.strip() + "\n") 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 ed8637398..d8cd09c99 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -86,7 +86,7 @@ 0x80089470 : "destroythread", 0x80089580 : "voicecheckresult", 0x80089630 : "bzero", - 0x800896D0 : "rumblepak", + 0x800896D0 : "motor", 0x80089AA0 : "siacs", 0x80089B60 : "controller", 0x80089E40 : "createthread", @@ -245,7 +245,7 @@ 0x80096930 : "__osMemcpy", # .data section - 0x800969C0 : "rsp_boot", + 0x800969C0 : "rspboot", 0x80096B20 : "idle", 0x80096B40 : "viconfig", 0x80096B50 : "z_std_dma", @@ -259,7 +259,8 @@ 0x80097500 : "boot_800862E0", 0x80097520 : "fp", 0x80097530 : "rand", - 0x80097540 : "vimodeHpf", + 0x80097540 : "osViModeNtscHpf1", + 0x80097590 : "osViModePalLan1", 0x800975E0 : "sins", 0x80097DE0 : "exceptasm", 0x80097E10 : "thread", @@ -276,11 +277,14 @@ 0x80097F90 : "rotate", 0x80097FA0 : "voiceinit", 0x80097FB0 : "contramread", - 0x80097FC0 : "vi", + 0x80097FC0 : "osViModeNtscLan1", + 0x80097FC0 : "osViModeMpalLan1", + 0x80098060 : "vi", 0x800980D0 : "cartrominit", 0x800980E0 : "guS2DInitBg", 0x80098130 : "xldtob", 0x80098160 : "vimgr", + 0x80098180 : "voicecontrolgain", # .rodata section 0x80098190 : "boot_main", @@ -321,7 +325,7 @@ 0x8009CD50 : "rand", 0x8009CD60 : "__osMalloc", 0x8009CD70 : "sptask", - 0x8009CDB0 : "rumblepak", + 0x8009CDB0 : "motor", 0x8009CEB0 : "siacs", 0x8009CED0 : "controller", 0x8009CF60 : "voicegetreaddata", @@ -362,7 +366,6 @@ 0x800BFB80 : "z_bgcheck", 0x800CAAD0 : "z_bg_collect", 0x800CAE10 : "z_bg_item", - 0x800CB000 : "code_800CB000", 0x800CB210 : "z_camera", 0x800E03A0 : "z_collision_btltbls", 0x800E0400 : "[PADDING]", @@ -375,11 +378,11 @@ 0x800EA060 : "z_demo", 0x800EE320 : "z_draw", 0x800EFE60 : "z_eff_footmark", - 0x800F0390 : "code_800F0390", + 0x800F0390 : "z_sound_source", 0x800F05C0 : "z_elf_message", - 0x800F07C0 : "code_800F07C0", + 0x800F07C0 : "z_en_hy", 0x800F1250 : "z_face_reaction", - 0x800F12D0 : "code_800F12D0", + 0x800F12D0 : "z_env_flags", 0x800F1460 : "z_eventmgr", 0x800F23E0 : "z_fcurve_data", 0x800F2620 : "z_fcurve_data_skelanime", @@ -415,7 +418,7 @@ 0x8012F2E0 : "z_scene", 0x801307C0 : "z_scene_proc", 0x801322C0 : "z_scene_table", - 0x801323D0 : "code_801323D0", + 0x801323D0 : "z_schedule", 0x801330E0 : "z_skelanime", 0x80137970 : "z_skin", 0x80138410 : "z_skin_awb", @@ -455,7 +458,7 @@ 0x80173360 : "game", 0x80173BF0 : "gamealloc", 0x80173D30 : "graph", - 0x80174A40 : "code_80174A40", + 0x80174A40 : "graphalloc", 0x80174AA0 : "listalloc", 0x80174BF0 : "main", 0x80174F10 : "padmgr", @@ -467,7 +470,8 @@ 0x801795F0 : "sys_math3d", 0x8017FEB0 : "sys_math_atan", 0x80180160 : "sys_matrix", - 0x80182CE0 : "sys_ucode", + 0x80182C90 : "sys_ucode", + 0x80182CE0 : "", 0x80183070 : "code_80183070", 0x801830A0 : "c_keyframe", 0x80185660 : "sys_slowly", @@ -479,7 +483,8 @@ 0x8018B0F0 : "audio_heap", 0x8018EB60 : "audio_load", 0x80192BE0 : "code_80192BE0", - 0x80194710 : "code_80194710", + 0x80194710 : "audio_dcache", + 0x80194790 : "code_80194790", 0x80194930 : "audio_playback", 0x80196A00 : "audio_effects", 0x801974D0 : "audio_seqplayer", @@ -487,16 +492,20 @@ 0x8019AEB0 : "[PADDING]", 0x8019AEC0 : "code_8019AEC0", 0x8019AF00 : "code_8019AF00", + 0x801A4EB0 : "code_801A4EB0", 0x801A51F0 : "code_801A51F0", 0x801A5BC0 : "[PADDING]", 0x801A5BD0 : "code_801A5BD0", 0x801A7B10 : "code_801A7B10", - 0x801AA020 : "code_801AA020", + 0x801A9B10 : "jpegutils", + 0x801AA020 : "jpegdecoder", 0x801AA610 : "z_game_over", 0x801AAAA0 : "z_construct", # .data section - 0x801AAAB0 : "z_en_a_keep", + 0x801AAAB0 : "aspMain", + 0x801ABAB0 : "gspS2DEX2.fifo", + 0x801AD370 : "njpgdspMain", 0x801ADE60 : "", 0x801ADEC0 : "z_en_item00", 0x801AE240 : "z_eff_blure", @@ -504,6 +513,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", @@ -514,6 +524,7 @@ 0x801BA200 : "z_collision_check", 0x801BA550 : "z_debug_display", 0x801BB090 : "z_debug_mode", + 0x801BB120 : "z_demo", 0x801BB170 : "z_draw", 0x801BC240 : "z_eff_footmark", 0x801BC2A0 : "", @@ -523,6 +534,7 @@ 0x801BD910 : "", 0x801BDA70 : "z_horse", 0x801BDAC0 : "z_jpeg", + 0x801BDB00 : "z_kaleido_setup", 0x801BDB30 : "z_kanfont", 0x801BDB90 : "z_kankyo", 0x801BE960 : "z_lib", @@ -542,16 +554,16 @@ 0x801C2730 : "", 0x801C3B60 : "z_scene_proc", 0x801C3CA0 : "z_scene_table", - 0x801C5C50 : "", + 0x801C5C50 : "z_schedule", 0x801C5CB0 : "z_skelanime", 0x801C5CD0 : "z_skin_matrix", 0x801C5D10 : "z_sub_s", 0x801C5DD0 : "z_vimode", 0x801C5E30 : "z_vr_box", - 0x801C5FC0 : "z_vr_box_draw", - 0x801C67B0 : "z_sram_NES", + 0x801C5FC0 : "z_sram_NES", + 0x801C6A70 : "z_message", 0x801D0470 : "z_message_nes", - 0x801D0B50 : "", + 0x801D0B50 : "z_player_call", 0x801D0B70 : "z_kaleido_manager", 0x801D0BB0 : "", 0x801D0C80 : "z_fbdemo", @@ -560,19 +572,30 @@ 0x801D0D80 : "z_play_hireso", 0x801D14F0 : "audioMgr", 0x801D1500 : "game", - 0x801D1520 : "graph", + 0x801D1510 : "graph", + 0x801D1520 : "main", 0x801D1530 : "padmgr", 0x801D1540 : "speed_meter", 0x801D1570 : "sys_math", 0x801D15B0 : "", 0x801D15D0 : "sys_math_atan", 0x801D1DE0 : "sys_matrix", + 0x801D1E60 : "sys_ucode", 0x801D1E70 : "", - 0x801D2E80 : "", # audio_heap? - 0x801D3D90 : "", - 0x801D55B0 : "", + 0x801D2E80 : "audio_data", + 0x801D5FB0 : "audio_synthesis", + 0x801D5FE0 : "audio_load", + 0x801D5FF0 : "code_80192BE0", + 0x801D6010 : "code_80194790", + 0x801D6190 : "audio_effects", + 0x801D61A0 : "audio_seqplayer", + 0x801D6200 : "audio_dramStack", + 0x801D6600 : "code_8019AF00", + 0x801D8BE0 : "code_801A4EB0", 0x801D8E50 : "code_801A51F0", - 0x801D9090 : "", + 0x801D9090 : "audio_sound_params", + 0x801DB470 : "code_801A5BD0", + 0x801DB4C0 : "code_801A7B10", # .rodata section 0x801DBDF0 : "z_en_item00", @@ -586,7 +609,7 @@ 0x801DC9D0 : "z_actor", 0x801DCBB0 : "z_actor_dlftbls", 0x801DCC00 : "z_bgcheck", - 0x801DCDB0 : "code_800CB000", + 0x801DCDB0 : "z_bg_item", 0x801DCDC0 : "z_camera", 0x801DD5C0 : "z_collision_check", 0x801DD600 : "z_debug_mode", @@ -653,13 +676,18 @@ 0x801E0EC0 : "code_801A51F0", 0x801E1050 : "code_801A5BD0", 0x801E1070 : "code_801A7B10", - 0x801E1100 : "code_801AA020", + 0x801E1100 : "audio_init_params", 0x801E1110 : "z_game_over", - 0x801E1180 : "", + 0x801E1180 : "audio_tables", + 0x801E1E80 : "aspMain", + 0x801E2160 : "gspF3DZEX2.NoN.PosLight.fifo", + 0x801E3BB0 : "gspS2DEX2.fifo", + 0x801E3F40 : "njpgdspMain", # .bss section 0x801E3FA0 : "code_801E3FA0", 0x801E3FB0 : "z_effect", + 0x801ED890 : "flg_set", 0x801ED8A0 : "z_actor", 0x801ED930 : "z_actor_dlftbls", 0x801ED950 : "z_bgcheck", @@ -709,9 +737,9 @@ 0x801FD140 : "audio_load", 0x801FD1F0 : "code_8019AF00", 0x801FD5A0 : "code_801A51F0", - 0x801FE7C0 : "code_801A5BD0", + 0x801FD710 : "code_801A5BD0", 0x801FFD00 : "code_801A7B10", - 0x80208E90 : "code_801AA020", + 0x80208E90 : "jpegdecoder", 0x80208EA0 : "gfxbuffers", 0x8024A4C0 : "buffers", }, @@ -722,7 +750,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 6189a2309..c32e0365d 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -12,8 +12,8 @@ 0x80080514:("Idle_ThreadEntry",), 0x800805E0:("ViConfig_UpdateVi",), 0x80080748:("ViConfig_UpdateBlack",), - 0x80080790:("DmaMgr_DMARomToRam",), - 0x800808D4:("DmaMgr_DmaCallback0",), + 0x80080790:("DmaMgr_DmaRomToRam",), + 0x800808D4:("DmaMgr_DmaHandler",), 0x800808F4:("DmaMgr_FindDmaEntry",), 0x80080950:("DmaMgr_TranslateVromToRom",), 0x800809BC:("DmaMgr_FindDmaIndex",), @@ -158,14 +158,14 @@ 0x80086280:("__assert",), 0x800862B4:("func_800862B4",), 0x800862E0:("SystemArena_MallocMin1",), - 0x80086310:("SystemArena_FreeNull",), - 0x8008633C:("func_8008633C",), - 0x800863AC:("func_800863AC",), - 0x8008641C:("func_8008641C",), - 0x800864EC:("func_800864EC",), - 0x80086588:("func_80086588",), + 0x80086310:("SystemArena_FreeNullCheck",), + 0x8008633C:("SystemArena_RunBlockFunc",), + 0x800863AC:("SystemArena_RunBlockFunc1",), + 0x8008641C:("SystemArena_RunBlockFunc8",), + 0x800864EC:("SystemArena_RunBlockFunc1Reverse",), + 0x80086588:("SystemArena_RunInits",), 0x800865F8:("SystemArena_Init",), - 0x80086620:("func_80086620",), + 0x80086620:("PadSetup_Init",), 0x80086760:("func_80086760",), 0x80086794:("func_80086794",), 0x800867B4:("func_800867B4",), @@ -204,7 +204,7 @@ 0x80086E20:("SystemArena_Realloc",), 0x80086E50:("SystemArena_Free",), 0x80086E78:("SystemArena_Calloc",), - 0x80086ECC:("SystemArena_AnalyzeArena",), + 0x80086ECC:("SystemArena_GetSizes",), 0x80086F04:("SystemArena_CheckArena",), 0x80086F28:("SystemArena_InitArena",), 0x80086F58:("SystemArena_Cleanup",), @@ -222,14 +222,14 @@ 0x800871B4:("ArenaImpl_Unlock",), 0x800871DC:("ArenaImpl_GetLastBlock",), 0x8008720C:("__osMallocInit",), - 0x8008725C:("__osMallocAddBlock",), + 0x8008725C:("__osMallocAddHeap",), 0x800872FC:("__osMallocCleanup",), 0x8008731C:("__osMallocIsInitalized",), 0x80087324:("__osMalloc",), 0x80087408:("__osMallocR",), 0x800874EC:("__osFree",), 0x800875E4:("__osRealloc",), - 0x80087714:("__osAnalyzeArena",), + 0x80087714:("__osGetSizes",), 0x800877C4:("__osCheckArena",), 0x80087830:("proutSprintf",), 0x80087854:("vsprintf",), @@ -251,7 +251,7 @@ 0x800880B0:("osGetIntMask",), 0x80088110:("osVoiceSetWord",), 0x800882A0:("guScale",), - 0x80088350:("__sinf",), + 0x80088350:("sinf",), 0x80088510:("sins",), 0x80088580:("_VirtualToPhysicalTask",), 0x8008868C:("osSpTaskLoad",), @@ -280,9 +280,9 @@ 0x80089470:("osDestroyThread",), 0x80089580:("__osVoiceCheckResult",), 0x80089630:("bzero",), - 0x800896D0:("osSetRumble",), - 0x80089838:("osSetUpMempakWrite",), - 0x80089944:("osProbeRumblePak",), + 0x800896D0:("__osMotorAccess",), + 0x80089838:("_MakeMotorData",), + 0x80089944:("osMotorInit",), 0x80089AA0:("__osSiCreateAccessQueue",), 0x80089AF0:("__osSiGetAccess",), 0x80089B34:("__osSiRelAccess",), @@ -410,7 +410,7 @@ 0x80091AF0:("__osViInit",), 0x80091C10:("__osViSwapContext",), 0x80091F10:("osPiGetCmdQueue",), - 0x80091F40:("__cosf",), + 0x80091F40:("cosf",), 0x800920B0:("osEPiReadIo",), 0x80092100:("osViSetSpecialFeatures",), 0x80092260:("coss",), @@ -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",), @@ -596,10 +596,10 @@ 0x800B13D8:("func_800B13D8",), 0x800B14D4:("func_800B14D4",), 0x800B1598:("func_800B1598",), - 0x800B165C:("EffectSsKiraKira_SpawnSmallYellow",), - 0x800B16B8:("EffectSsKiraKira_SpawnSmall",), - 0x800B16F4:("EffectSsKiraKira_SpawnDispersed",), - 0x800B1830:("EffectSsKiraKira_SpawnFocused",), + 0x800B165C:("EffectSsKirakira_SpawnSmallYellow",), + 0x800B16B8:("EffectSsKirakira_SpawnSmall",), + 0x800B16F4:("EffectSsKirakira_SpawnDispersed",), + 0x800B1830:("EffectSsKirakira_SpawnFocused",), 0x800B1908:("EffectSsBomb2_SpawnFade",), 0x800B1970:("EffectSsBomb2_SpawnLayered",), 0x800B19E0:("EffectSsBlast_Spawn",), @@ -659,42 +659,42 @@ 0x800B3AD0:("Actor_PrintLists",), 0x800B3BA4:("ActorShape_Init",), 0x800B3BC8:("ActorShadow_Draw",), - 0x800B3FC0:("func_800B3FC0",), - 0x800B4024:("func_800B4024",), - 0x800B4088:("func_800B4088",), - 0x800B40B8:("func_800B40B8",), - 0x800B40E0:("func_800B40E0",), - 0x800B42F8:("func_800B42F8",), - 0x800B4A98:("func_800B4A98",), + 0x800B3FC0:("ActorShadow_DrawCircle",), + 0x800B4024:("ActorShadow_DrawSquare",), + 0x800B4088:("ActorShadow_DrawWhiteCircle",), + 0x800B40B8:("ActorShadow_DrawHorse",), + 0x800B40E0:("ActorShadow_DrawFoot",), + 0x800B42F8:("ActorShadow_DrawFeet",), + 0x800B4A98:("Actor_SetFeetPos",), 0x800B4AEC:("func_800B4AEC",), 0x800B4B50:("func_800B4B50",), - 0x800B4EDC:("func_800B4EDC",), - 0x800B4F40:("func_800B4F40",), + 0x800B4EDC:("Actor_GetProjectedPos",), + 0x800B4F40:("Target_SetPos",), 0x800B4F78:("func_800B4F78",), - 0x800B5040:("func_800B5040",), + 0x800B5040:("Target_SetColors",), 0x800B51A4:("Actor_TargetContextInit",), - 0x800B5208:("func_800B5208",), + 0x800B5208:("Actor_DrawZTarget",), 0x800B5814:("func_800B5814",), 0x800B5BB0:("Flags_GetSwitch",), - 0x800B5BF4:("Actor_SetSwitchFlag",), - 0x800B5C34:("Actor_UnsetSwitchFlag",), - 0x800B5C78:("Actor_GetChestFlag",), - 0x800B5C90:("Actor_SetChestFlag",), - 0x800B5CAC:("Actor_SetAllChestFlag",), - 0x800B5CB8:("Actor_GetAllChestFlag",), - 0x800B5CC4:("Actor_GetRoomCleared",), - 0x800B5CDC:("Actor_SetRoomCleared",), - 0x800B5CF8:("Actor_UnsetRoomCleared",), - 0x800B5D18:("Actor_GetRoomClearedTemp",), - 0x800B5D30:("Actor_SetRoomClearedTemp",), - 0x800B5D4C:("Actor_UnsetRoomClearedTemp",), - 0x800B5D6C:("Actor_GetCollectibleFlag",), - 0x800B5DB0:("Actor_SetCollectibleFlag",), - 0x800B5DF0:("Actor_TitleCardContextInit",), - 0x800B5E0C:("Actor_TitleCardCreate",), - 0x800B5E50:("Actor_Nop800B5E50",), - 0x800B5E68:("Actor_TitleCardUpdate",), - 0x800B5F24:("Actor_TitleCardDraw",), + 0x800B5BF4:("Flags_SetSwitch",), + 0x800B5C34:("Flags_UnsetSwitch",), + 0x800B5C78:("Flags_GetTreasure",), + 0x800B5C90:("Flags_SetTreasure",), + 0x800B5CAC:("Flags_SetAllTreasure",), + 0x800B5CB8:("Flags_GetAllTreasure",), + 0x800B5CC4:("Flags_GetClear",), + 0x800B5CDC:("Flags_SetClear",), + 0x800B5CF8:("Flags_UnsetClear",), + 0x800B5D18:("Flags_GetClearTemp",), + 0x800B5D30:("Flags_SetClearTemp",), + 0x800B5D4C:("Flags_UnsetClearTemp",), + 0x800B5D6C:("Flags_GetCollectible",), + 0x800B5DB0:("Flags_SetCollectible",), + 0x800B5DF0:("TitleCard_ContextInit",), + 0x800B5E0C:("TitleCard_InitBossName",), + 0x800B5E50:("TitleCard_InitPlaceName",), + 0x800B5E68:("TitleCard_Update",), + 0x800B5F24:("TitleCard_Draw",), 0x800B6434:("func_800B6434",), 0x800B6468:("func_800B6468",), 0x800B6474:("func_800B6474",), @@ -704,24 +704,24 @@ 0x800B6608:("func_800B6608",), 0x800B6680:("func_800B6680",), 0x800B670C:("Actor_MarkForDeath",), - 0x800B672C:("Actor_InitCurrPosition",), - 0x800B675C:("Actor_SetHeight",), - 0x800B67A0:("Actor_SetRotationFromDrawRotation",), - 0x800B67C0:("Actor_InitDrawRotation",), + 0x800B672C:("Actor_SetWorldToHome",), + 0x800B675C:("Actor_SetFocus",), + 0x800B67A0:("Actor_SetWorldRotToShape",), + 0x800B67C0:("Actor_SetShapeRotToWorld",), 0x800B67E0:("Actor_SetScale",), - 0x800B67FC:("Actor_SetObjectSegment",), - 0x800B6834:("Actor_InitToDefaultValues",), - 0x800B6948:("Actor_FiniActor",), + 0x800B67FC:("Actor_SetObjectDependency",), + 0x800B6834:("Actor_Init",), + 0x800B6948:("Actor_Destroy",), 0x800B6988:("Actor_SetMovementScale",), - 0x800B69AC:("Actor_ApplyMovement",), - 0x800B6A10:("Actor_SetVelocityYRotationAndGravity",), - 0x800B6A88:("Actor_SetVelocityAndMoveYRotationAndGravity",), - 0x800B6AB4:("Actor_SetVelocityXYRotation",), - 0x800B6B24:("Actor_SetVelocityAndMoveXYRotation",), - 0x800B6B50:("Actor_SetVelocityXYRotationReverse",), - 0x800B6BD8:("Actor_SetVelocityAndMoveXYRotationReverse",), - 0x800B6C04:("func_800B6C04",), - 0x800B6C58:("func_800B6C58",), + 0x800B69AC:("Actor_UpdatePos",), + 0x800B6A10:("Actor_UpdateVelocityWithGravity",), + 0x800B6A88:("Actor_MoveWithGravity",), + 0x800B6AB4:("Actor_UpdateVelocityWithoutGravity",), + 0x800B6B24:("Actor_MoveWithoutGravity",), + 0x800B6B50:("Actor_UpdateVelocityWithoutGravityReverse",), + 0x800B6BD8:("Actor_MoveWithoutGravityReverse",), + 0x800B6C04:("Actor_SetSpeeds",), + 0x800B6C58:("Actor_UpdatePosFromSkelAnime",), 0x800B6CD4:("Actor_YawBetweenActors",), 0x800B6D00:("Actor_YawBetweenActorsTop",), 0x800B6D2C:("Actor_YawToPoint",), @@ -732,76 +732,76 @@ 0x800B6DF8:("Actor_DistanceToPoint",), 0x800B6E1C:("Actor_XZDistanceBetweenActors",), 0x800B6E48:("Actor_XZDistanceToPoint",), - 0x800B6E6C:("Actor_CalcOffsetOrientedToDrawRotation",), - 0x800B6F0C:("Actor_YDistance",), + 0x800B6E6C:("Actor_OffsetOfPointInActorCoords",), + 0x800B6F0C:("Actor_HeightDiff",), 0x800B6F20:("func_800B6F20",), - 0x800B6FC8:("func_800B6FC8",), - 0x800B7090:("func_800B7090",), + 0x800B6FC8:("Player_GetHeight",), + 0x800B7090:("Player_GetRunSpeedLimit",), 0x800B7118:("func_800B7118",), 0x800B7128:("func_800B7128",), 0x800B715C:("func_800B715C",), - 0x800B7170:("func_800B7170",), - 0x800B71DC:("func_800B71DC",), + 0x800B7170:("Actor_SetCameraHorseSetting",), + 0x800B71DC:("Actor_MountHorse",), 0x800B7200:("func_800B7200",), 0x800B722C:("func_800B722C",), 0x800B724C:("func_800B724C",), 0x800B7298:("func_800B7298",), 0x800B72E0:("func_800B72E0",), 0x800B72F8:("func_800B72F8",), - 0x800B7320:("Actor_IsLinkFacingActor",), - 0x800B7378:("Actor_IsActorFacedByActor",), - 0x800B73E0:("Actor_IsActorFacingLink",), - 0x800B742C:("Actor_IsActorFacingActor",), - 0x800B748C:("Actor_IsActorFacingLinkAndWithinRange",), - 0x800B750C:("Actor_IsActorFacingActorAndWithinRange",), + 0x800B7320:("Player_IsFacingActor",), + 0x800B7378:("Actor_ActorBIsFacingActorA",), + 0x800B73E0:("Actor_IsFacingPlayer",), + 0x800B742C:("Actor_ActorAIsFacingActorB",), + 0x800B748C:("Actor_IsFacingAndNearPlayer",), + 0x800B750C:("Actor_ActorAIsFacingAndNearActorB",), 0x800B75A0:("func_800B75A0",), 0x800B761C:("func_800B761C",), 0x800B7678:("func_800B7678",), 0x800B78B8:("Actor_UpdateBgCheckInfo",), - 0x800B7E04:("func_800B7E04",), - 0x800B7FE0:("func_800B7FE0",), - 0x800B8018:("func_800B8018",), + 0x800B7E04:("Hilite_Draw",), + 0x800B7FE0:("Hilite_DrawOpa",), + 0x800B8018:("Hilite_DrawXlu",), 0x800B8050:("func_800B8050",), 0x800B8118:("func_800B8118",), - 0x800B81E0:("func_800B81E0",), - 0x800B8214:("func_800B8214",), - 0x800B8248:("func_800B8248",), + 0x800B81E0:("Actor_GetFocus",), + 0x800B8214:("Actor_GetWorld",), + 0x800B8248:("Actor_GetWorldPosShapeRot",), 0x800B82EC:("func_800B82EC",), 0x800B83BC:("func_800B83BC",), 0x800B83F8:("func_800B83F8",), - 0x800B84D0:("func_800B84D0",), + 0x800B84D0:("Actor_ProcessTalkRequest",), 0x800B8500:("func_800B8500",), 0x800B85E0:("func_800B85E0",), 0x800B8614:("func_800B8614",), 0x800B863C:("func_800B863C",), - 0x800B867C:("func_800B867C",), - 0x800B86C8:("func_800B86C8",), - 0x800B8708:("func_800B8708",), + 0x800B867C:("Actor_TextboxIsClosing",), + 0x800B86C8:("Actor_ChangeFocus",), + 0x800B8708:("Player_GetExchangeItemId",), 0x800B8718:("func_800B8718",), 0x800B874C:("func_800B874C",), 0x800B8804:("func_800B8804",), 0x800B882C:("func_800B882C",), 0x800B886C:("func_800B886C",), - 0x800B8898:("func_800B8898",), + 0x800B8898:("Actor_GetScreenPos",), 0x800B8934:("func_800B8934",), 0x800B89F8:("Actor_HasParent",), - 0x800B8A1C:("func_800B8A1C",), - 0x800B8B84:("func_800B8B84",), - 0x800B8BB0:("func_800B8BB0",), - 0x800B8BD0:("func_800B8BD0",), + 0x800B8A1C:("Actor_PickUp",), + 0x800B8B84:("Actor_PickUpNearby",), + 0x800B8BB0:("Actor_LiftActor",), + 0x800B8BD0:("Actor_PickUpFar",), 0x800B8BFC:("Actor_HasNoParent",), 0x800B8C20:("func_800B8C20",), 0x800B8C50:("func_800B8C50",), - 0x800B8C78:("func_800B8C78",), - 0x800B8C9C:("func_800B8C9C",), - 0x800B8CEC:("func_800B8CEC",), + 0x800B8C78:("Actor_HasRider",), + 0x800B8C9C:("Actor_SetRideActor",), + 0x800B8CEC:("Actor_HasNoRider",), 0x800B8D10:("func_800B8D10",), 0x800B8D50:("func_800B8D50",), 0x800B8D98:("func_800B8D98",), 0x800B8DD4:("func_800B8DD4",), 0x800B8E1C:("func_800B8E1C",), 0x800B8E58:("func_800B8E58",), - 0x800B8EC8:("Audio_PlayActorSound2",), + 0x800B8EC8:("Actor_PlaySfxAtPos",), 0x800B8EF4:("func_800B8EF4",), 0x800B8F98:("func_800B8F98",), 0x800B8FC0:("func_800B8FC0",), @@ -813,11 +813,11 @@ 0x800B90AC:("func_800B90AC",), 0x800B90F4:("func_800B90F4",), 0x800B9120:("func_800B9120",), - 0x800B9170:("Actor_Init",), - 0x800B9334:("func_800B9334",), + 0x800B9170:("Actor_InitContext",), + 0x800B9334:("Actor_SpawnSetupActors",), 0x800B948C:("Actor_UpdateActor",), 0x800B9780:("Actor_UpdateAll",), - 0x800B9A04:("Actor_DrawActor",), + 0x800B9A04:("Actor_Draw",), 0x800B9D1C:("func_800B9D1C",), 0x800B9E3C:("Actor_DrawAllSetup",), 0x800B9E4C:("Actor_RecordUndrawnActor",), @@ -829,17 +829,17 @@ 0x800BA6FC:("func_800BA6FC",), 0x800BA798:("func_800BA798",), 0x800BA8B8:("func_800BA8B8",), - 0x800BA9B4:("func_800BA9B4",), - 0x800BAAB4:("Actor_InsertIntoTypeList",), - 0x800BAB24:("Actor_RemoveFromTypeList",), + 0x800BA9B4:("Actor_CleanupContext",), + 0x800BAAB4:("Actor_AddToCategory",), + 0x800BAB24:("Actor_RemoveFromCategory",), 0x800BABFC:("Actor_FreeOverlay",), 0x800BAC60:("Actor_Spawn",), 0x800BACD4:("Actor_LoadOverlay",), 0x800BAE14:("Actor_SpawnAsChildAndCutscene",), 0x800BB0C0:("Actor_SpawnAsChild",), 0x800BB140:("Actor_SpawnTransitionActors",), - 0x800BB2D0:("func_800BB2D0",), - 0x800BB498:("func_800BB498",), + 0x800BB2D0:("Actor_SpawnEntry",), + 0x800BB498:("Actor_Delete",), 0x800BB59C:("func_800BB59C",), 0x800BB604:("func_800BB604",), 0x800BB8EC:("func_800BB8EC",), @@ -847,27 +847,27 @@ 0x800BBAC0:("func_800BBAC0",), 0x800BBB74:("func_800BBB74",), 0x800BBC20:("func_800BBC20",), - 0x800BBCEC:("func_800BBCEC",), - 0x800BBDAC:("func_800BBDAC",), + 0x800BBCEC:("Actor_SpawnBodyParts",), + 0x800BBDAC:("Actor_SpawnFloorDustRing",), 0x800BBFB0:("func_800BBFB0",), 0x800BC154:("func_800BC154",), 0x800BC188:("func_800BC188",), 0x800BC1B4:("func_800BC1B4",), 0x800BC270:("func_800BC270",), 0x800BC444:("func_800BC444",), - 0x800BC4EC:("func_800BC4EC",), - 0x800BC5B8:("func_800BC5B8",), - 0x800BC5EC:("func_800BC5EC",), + 0x800BC4EC:("Actor_TestFloorInDirection",), + 0x800BC5B8:("Actor_IsTargeted",), + 0x800BC5EC:("Actor_OtherIsTargeted",), 0x800BC620:("func_800BC620",), 0x800BC770:("func_800BC770",), 0x800BC7D8:("func_800BC7D8",), 0x800BC848:("func_800BC848",), - 0x800BC8B8:("func_800BC8B8",), - 0x800BCB50:("func_800BCB50",), - 0x800BCB70:("func_800BCB70",), + 0x800BC8B8:("Actor_DrawDoorLock",), + 0x800BCB50:("Actor_SpawnShieldParticlesMetal",), + 0x800BCB70:("Actor_SetColorFilter",), 0x800BCBF4:("func_800BCBF4",), 0x800BCC68:("func_800BCC68",), - 0x800BCCDC:("func_800BCCDC",), + 0x800BCCDC:("Actor_GetClosestPosOnPath",), 0x800BD2B4:("func_800BD2B4",), 0x800BD384:("func_800BD384",), 0x800BD6B8:("func_800BD6B8",), @@ -877,184 +877,184 @@ 0x800BD9E0:("func_800BD9E0",), 0x800BDAA0:("func_800BDAA0",), 0x800BDB6C:("func_800BDB6C",), - 0x800BDC5C:("func_800BDC5C",), + 0x800BDC5C:("Actor_ChangeAnimationByInfo",), 0x800BDCF4:("func_800BDCF4",), 0x800BDFB0:("Actor_Noop",), - 0x800BDFC0:("func_800BDFC0",), - 0x800BE03C:("func_800BE03C",), - 0x800BE0B8:("func_800BE0B8",), + 0x800BDFC0:("Gfx_DrawDListOpa",), + 0x800BE03C:("Gfx_DrawDListXlu",), + 0x800BE0B8:("Actor_FindNearby",), 0x800BE184:("func_800BE184",), 0x800BE22C:("Actor_ApplyDamage",), - 0x800BE258:("func_800BE258",), - 0x800BE2B8:("func_800BE2B8",), + 0x800BE258:("Actor_SetDropFlag",), + 0x800BE2B8:("Actor_SetDropFlagJntSph",), 0x800BE33C:("func_800BE33C",), 0x800BE3D0:("func_800BE3D0",), 0x800BE504:("func_800BE504",), 0x800BE568:("func_800BE568",), 0x800BE5CC:("func_800BE5CC",), 0x800BE63C:("func_800BE63C",), - 0x800BE680:("func_800BE680",), - 0x800BF7CC:("func_800BF7CC",), + 0x800BE680:("Actor_DrawDamageEffects",), + 0x800BF7CC:("Actor_SpawnIceEffects",), 0x800BF9A0:("ActorOverlayTable_FaultPrint",), 0x800BFA78:("ActorOverlayTable_FaultAddrConv",), 0x800BFAE8:("ActorOverlayTable_Init",), 0x800BFB40:("ActorOverlayTable_Cleanup",), - 0x800BFB80:("BgCheck_PolygonLinkedListNodeInit",), - 0x800BFB9C:("BgCheck_PolygonLinkedListResetHead",), - 0x800BFBAC:("BgCheck_ScenePolygonListsNodeInsert",), - 0x800BFC04:("BgCheck_PolygonLinkedListNodeInsert",), - 0x800BFC5C:("BgCheck_PolygonLinkedListInit",), - 0x800BFC70:("BgCheck_PolygonLinkedListAlloc",), - 0x800BFCC0:("BgCheck_PolygonLinkedListReset",), - 0x800BFCCC:("BgCheck_AllocPolygonLinkedListNode",), - 0x800BFCFC:("BgCheck_CreateVec3fFromVertex",), - 0x800BFD40:("BgCheck_CreateVertexFromVec3f",), + 0x800BFB80:("SSNode_SetValue",), + 0x800BFB9C:("SSList_SetNull",), + 0x800BFBAC:("SSNodeList_SetSSListHead",), + 0x800BFC04:("DynaSSNodeList_SetSSListHead",), + 0x800BFC5C:("DynaSSNodeList_Init",), + 0x800BFC70:("DynaSSNodeList_Alloc",), + 0x800BFCC0:("DynaSSNodeList_ResetCount",), + 0x800BFCCC:("DynaSSNodeList_GetNextNodeIdx",), + 0x800BFCFC:("BgCheck_Vec3sToVec3f",), + 0x800BFD40:("BgCheck_Vec3fToVec3s",), 0x800BFD84:("func_800BFD84",), 0x800BFDEC:("func_800BFDEC",), - 0x800BFFC4:("BgCheck_PolygonGetMinY",), - 0x800C003C:("BgCheck_PolygonGetNormal",), + 0x800BFFC4:("CollisionPoly_GetMinY",), + 0x800C003C:("CollisionPoly_GetNormalF",), 0x800C0094:("func_800C0094",), - 0x800C01B8:("func_800C01B8",), - 0x800C0220:("BgCheck_CreateTriNormFromPolygon",), - 0x800C02C0:("func_800C02C0",), - 0x800C0340:("func_800C0340",), - 0x800C0474:("func_800C0474",), - 0x800C0668:("func_800C0668",), - 0x800C06A8:("func_800C06A8",), - 0x800C074C:("func_800C074C",), - 0x800C07F0:("func_800C07F0",), - 0x800C0AF0:("BgCheck_PolygonCollidesWithSphere",), - 0x800C0BC0:("BgCheck_ScenePolygonListsInsertSorted",), - 0x800C0DE0:("BgCheck_ScenePolygonListsInsert",), - 0x800C0E74:("func_800C0E74",), - 0x800C10FC:("func_800C10FC",), - 0x800C1238:("func_800C1238",), - 0x800C12A4:("func_800C12A4",), - 0x800C1B68:("func_800C1B68",), - 0x800C1D7C:("func_800C1D7C",), - 0x800C2008:("func_800C2008",), - 0x800C20F4:("func_800C20F4",), - 0x800C2310:("func_800C2310",), - 0x800C2460:("func_800C2460",), - 0x800C2514:("func_800C2514",), - 0x800C25E0:("func_800C25E0",), - 0x800C26C0:("BgCheck_GetPolyMinSubdivisions",), - 0x800C2864:("BgCheck_GetPolyMaxSubdivisions",), - 0x800C2A30:("BgCheck_GetPolyMinMaxSubdivisions",), - 0x800C2BE0:("func_800C2BE0",), - 0x800C3334:("BgCheck_SplitScenePolygonsIntoSubdivisions",), - 0x800C3734:("BgCheck_GetIsDefaultSpecialScene",), - 0x800C3778:("BgCheck_GetSpecialSceneMaxMemory",), - 0x800C37BC:("BgCheck_CalcSubdivisionSize",), + 0x800C01B8:("CollisionPoly_GetPointDistanceFromPlane",), + 0x800C0220:("CollisionPoly_GetVertices",), + 0x800C02C0:("CollisionPoly_GetVerticesByBgId",), + 0x800C0340:("CollisionPoly_CheckYIntersectApprox1",), + 0x800C0474:("CollisionPoly_CheckYIntersect",), + 0x800C0668:("CollisionPoly_CheckYIntersectApprox2",), + 0x800C06A8:("CollisionPoly_CheckXIntersectApprox",), + 0x800C074C:("CollisionPoly_CheckZIntersectApprox",), + 0x800C07F0:("CollisionPoly_LineVsPoly",), + 0x800C0AF0:("CollisionPoly_SphVsPoly",), + 0x800C0BC0:("StaticLookup_AddPolyToSSList",), + 0x800C0DE0:("StaticLookup_AddPoly",), + 0x800C0E74:("BgCheck_RaycastFloorStaticList",), + 0x800C10FC:("BgCheck_RaycastFloorStatic",), + 0x800C1238:("BgCheck_ComputeWallDisplacement",), + 0x800C12A4:("BgCheck_SphVsStaticWall",), + 0x800C1B68:("BgCheck_CheckStaticCeiling",), + 0x800C1D7C:("BgCheck_CheckLineAgainstSSList",), + 0x800C2008:("BgCheck_CheckLineInSubdivision",), + 0x800C20F4:("BgCheck_SphVsFirstStaticPolyList",), + 0x800C2310:("BgCheck_SphVsFirstStaticPoly",), + 0x800C2460:("BgCheck_GetNearestStaticLookup",), + 0x800C2514:("BgCheck_GetStaticLookup",), + 0x800C25E0:("BgCheck_GetStaticLookupIndicesFromPos",), + 0x800C26C0:("BgCheck_GetSubdivisionMinBounds",), + 0x800C2864:("BgCheck_GetSubdivisionMaxBounds",), + 0x800C2A30:("BgCheck_GetPolySubdivisionBounds",), + 0x800C2BE0:("BgCheck_PolyIntersectsSubdivision",), + 0x800C3334:("BgCheck_InitStaticLookup",), + 0x800C3734:("BgCheck_IsSmallMemScene",), + 0x800C3778:("BgCheck_TryGetCustomMemsize",), + 0x800C37BC:("BgCheck_SetSubdivisionDimension",), 0x800C3844:("BgCheck_GetSpecialSceneMaxObjects",), - 0x800C389C:("BgCheck_Init",), - 0x800C3C00:("func_800C3C00",), - 0x800C3C14:("func_800C3C14",), - 0x800C3C2C:("BgCheck_GetActorMeshHeader",), - 0x800C3C94:("func_800C3C94",), - 0x800C3D50:("func_800C3D50",), - 0x800C3F40:("func_800C3F40",), - 0x800C3FA0:("func_800C3FA0",), - 0x800C4000:("func_800C4000",), - 0x800C4058:("func_800C4058",), - 0x800C40B4:("func_800C40B4",), - 0x800C411C:("func_800C411C",), - 0x800C4188:("func_800C4188",), - 0x800C41E4:("func_800C41E4",), - 0x800C4240:("func_800C4240",), - 0x800C42A8:("func_800C42A8",), - 0x800C4314:("func_800C4314",), - 0x800C43CC:("func_800C43CC",), - 0x800C4488:("func_800C4488",), - 0x800C44F0:("func_800C44F0",), - 0x800C455C:("func_800C455C",), - 0x800C45C4:("func_800C45C4",), - 0x800C4C74:("func_800C4C74",), - 0x800C4CD8:("func_800C4CD8",), - 0x800C4D3C:("func_800C4D3C",), - 0x800C4DA4:("func_800C4DA4",), - 0x800C4E10:("func_800C4E10",), - 0x800C4F38:("func_800C4F38",), - 0x800C4F84:("func_800C4F84",), - 0x800C4FD4:("func_800C4FD4",), - 0x800C5464:("func_800C5464",), - 0x800C54AC:("func_800C54AC",), - 0x800C5538:("func_800C5538",), - 0x800C55C4:("func_800C55C4",), - 0x800C5650:("func_800C5650",), - 0x800C56E0:("func_800C56E0",), - 0x800C576C:("func_800C576C",), - 0x800C57F8:("func_800C57F8",), - 0x800C583C:("func_800C583C",), - 0x800C58C8:("func_800C58C8",), - 0x800C5954:("func_800C5954",), - 0x800C5A20:("func_800C5A20",), - 0x800C5A64:("func_800C5A64",), - 0x800C5AAC:("BgCheck_ScenePolygonListsInit",), - 0x800C5AC4:("BgCheck_ScenePolygonListsAlloc",), - 0x800C5B80:("func_800C5B80",), - 0x800C5BBC:("BgCheck_ScenePolygonListsReserveNode",), - 0x800C5BD0:("BgCheck_ActorMeshParamsInit",), - 0x800C5C0C:("BgCheck_SetActorMeshParams",), - 0x800C5C5C:("BgCheck_AreActorMeshParamsEqual",), - 0x800C5D30:("BgCheck_ActorMeshPolyListsHeadsInit",), - 0x800C5D70:("BgCheck_ActorMeshPolyListsInit",), - 0x800C5D90:("BgCheck_ActorMeshVerticesIndexInit",), - 0x800C5D9C:("BgCheck_ActorMeshWaterboxesIndexInit",), - 0x800C5DA8:("BgCheck_ActorMeshInit",), - 0x800C5E10:("BgCheck_ActorMeshInitFromActor",), - 0x800C5EC8:("BgCheck_HasActorMeshChanged",), - 0x800C5EF0:("BgCheck_PolygonsInit",), - 0x800C5EFC:("BgCheck_PolygonsAlloc",), - 0x800C5F38:("BgCheck_VerticesInit",), - 0x800C5F44:("BgCheck_VerticesListAlloc",), - 0x800C5F8C:("BgCheck_WaterboxListInit",), - 0x800C5F9C:("BgCheck_WaterboxListAlloc",), - 0x800C5FD8:("BgCheck_ActorMeshUpdateParams",), - 0x800C6024:("BgCheck_IsActorMeshIndexValid",), - 0x800C6044:("BgCheck_DynaInit",), - 0x800C6098:("BgCheck_DynaAlloc",), - 0x800C6188:("BgCheck_AddActorMesh",), - 0x800C6248:("BgCheck_GetActorOfMesh",), + 0x800C389C:("BgCheck_Allocate",), + 0x800C3C00:("BgCheck_SetContextFlags",), + 0x800C3C14:("BgCheck_UnsetContextFlags",), + 0x800C3C2C:("BgCheck_GetCollisionHeader",), + 0x800C3C94:("BgCheck_PosInStaticBoundingBox",), + 0x800C3D50:("BgCheck_RaycastFloorImpl",), + 0x800C3F40:("BgCheck_CameraRaycastFloor1",), + 0x800C3FA0:("BgCheck_EntityRaycastFloor1",), + 0x800C4000:("BgCheck_EntityRaycastFloor2",), + 0x800C4058:("BgCheck_EntityRaycastFloor2_1",), + 0x800C40B4:("BgCheck_EntityRaycastFloor3",), + 0x800C411C:("BgCheck_EntityRaycastFloor5",), + 0x800C4188:("BgCheck_EntityRaycastFloor5_2",), + 0x800C41E4:("BgCheck_EntityRaycastFloor5_3",), + 0x800C4240:("BgCheck_EntityRaycastFloor6",), + 0x800C42A8:("BgCheck_EntityRaycastFloor7",), + 0x800C4314:("BgCheck_AnyRaycastFloor1",), + 0x800C43CC:("BgCheck_AnyRaycastFloor2",), + 0x800C4488:("BgCheck_CameraRaycastFloor2",), + 0x800C44F0:("BgCheck_EntityRaycastFloor8",), + 0x800C455C:("BgCheck_EntityRaycastFloor9",), + 0x800C45C4:("BgCheck_CheckWallImpl",), + 0x800C4C74:("BgCheck_EntitySphVsWall1",), + 0x800C4CD8:("BgCheck_EntitySphVsWall2",), + 0x800C4D3C:("BgCheck_EntitySphVsWall3",), + 0x800C4DA4:("BgCheck_EntitySphVsWall4",), + 0x800C4E10:("BgCheck_CheckCeilingImpl",), + 0x800C4F38:("BgCheck_AnyCheckCeiling",), + 0x800C4F84:("BgCheck_EntityCheckCeiling",), + 0x800C4FD4:("BgCheck_CheckLineImpl",), + 0x800C5464:("BgCheck_GetBccFlags",), + 0x800C54AC:("BgCheck_CameraLineTest1",), + 0x800C5538:("BgCheck_CameraLineTest2",), + 0x800C55C4:("BgCheck_EntityLineTest1",), + 0x800C5650:("BgCheck_EntityLineTest2",), + 0x800C56E0:("BgCheck_EntityLineTest3",), + 0x800C576C:("BgCheck_ProjectileLineTest",), + 0x800C57F8:("BgCheck_AnyLineTest1",), + 0x800C583C:("BgCheck_AnyLineTest2",), + 0x800C58C8:("BgCheck_AnyLineTest3",), + 0x800C5954:("BgCheck_SphVsFirstPolyImpl",), + 0x800C5A20:("BgCheck_SphVsFirstPoly",), + 0x800C5A64:("BgCheck_SphVsFirstWall",), + 0x800C5AAC:("SSNodeList_Init",), + 0x800C5AC4:("SSNodeList_Alloc",), + 0x800C5B80:("SSNodeList_GetNextNode",), + 0x800C5BBC:("SSNodeList_GetNextNodeIdx",), + 0x800C5BD0:("ScaleRotPos_Init",), + 0x800C5C0C:("ScaleRotPos_SetValue",), + 0x800C5C5C:("ScaleRotPos_Equals",), + 0x800C5D30:("DynaLookup_ResetLists",), + 0x800C5D70:("DynaLookup_Reset",), + 0x800C5D90:("DynaLookup_ResetVtxStartIndex",), + 0x800C5D9C:("DynaLookup_ResetWaterBoxStartIndex",), + 0x800C5DA8:("BgActor_Init",), + 0x800C5E10:("BgActor_SetActor",), + 0x800C5EC8:("BgActor_IsTransformUnchanged",), + 0x800C5EF0:("DynaPoly_NullPolyList",), + 0x800C5EFC:("DynaPoly_AllocPolyList",), + 0x800C5F38:("DynaPoly_NullVtxList",), + 0x800C5F44:("DynaPoly_AllocVtxList",), + 0x800C5F8C:("DynaPoly_InitWaterBoxList",), + 0x800C5F9C:("DynaPoly_AllocWaterBoxList",), + 0x800C5FD8:("DynaPoly_SetBgActorPrevTransform",), + 0x800C6024:("DynaPoly_IsBgIdBgActor",), + 0x800C6044:("DynaPoly_Init",), + 0x800C6098:("DynaPoly_Alloc",), + 0x800C6188:("DynaPoly_SetBgActor",), + 0x800C6248:("DynaPoly_GetActor",), 0x800C62BC:("func_800C62BC",), 0x800C6314:("func_800C6314",), 0x800C636C:("func_800C636C",), 0x800C63C4:("func_800C63C4",), 0x800C641C:("func_800C641C",), 0x800C6474:("func_800C6474",), - 0x800C64CC:("BgCheck_RemoveActorMesh",), + 0x800C64CC:("DynaPoly_DeleteBgActor",), 0x800C6554:("func_800C6554",), 0x800C656C:("BgCheck_CalcWaterboxDimensions",), - 0x800C6838:("BgCheck_AddActorMeshToLists",), + 0x800C6838:("DynaPoly_ExpandSRT",), 0x800C734C:("BgCheck_ResetFlagsIfLoadedActor",), - 0x800C73E4:("BgCheck_Update",), + 0x800C73E4:("DynaPoly_Setup",), 0x800C756C:("func_800C756C",), - 0x800C765C:("BgCheck_UpdateAllActorMeshes",), - 0x800C76EC:("func_800C76EC",), - 0x800C7974:("func_800C7974",), - 0x800C7E40:("func_800C7E40",), - 0x800C8580:("func_800C8580",), - 0x800C87D0:("func_800C87D0",), - 0x800C8A60:("func_800C8A60",), - 0x800C8BD0:("func_800C8BD0",), - 0x800C8DC0:("func_800C8DC0",), - 0x800C8EEC:("func_800C8EEC",), - 0x800C90AC:("func_800C90AC",), - 0x800C921C:("func_800C921C",), - 0x800C9380:("func_800C9380",), - 0x800C94E0:("BgCheck_RelocateMeshHeaderPointers",), - 0x800C9564:("BgCheck_RelocateMeshHeader",), - 0x800C9598:("BgCheck_RelocateAllMeshHeaders",), - 0x800C9640:("func_800C9640",), - 0x800C9694:("BgCheck_GetPolygonAttributes",), - 0x800C9704:("func_800C9704",), + 0x800C765C:("DynaPoly_UpdateBgActorTransforms",), + 0x800C76EC:("BgCheck_RaycastFloorDynaList",), + 0x800C7974:("BgCheck_RaycastFloorDyna",), + 0x800C7E40:("BgCheck_SphVsDynaWallInBgActor",), + 0x800C8580:("BgCheck_SphVsDynaWall",), + 0x800C87D0:("BgCheck_CheckDynaCeilingList",), + 0x800C8A60:("BgCheck_CheckDynaCeiling",), + 0x800C8BD0:("BgCheck_CheckLineAgainstBgActorSSList",), + 0x800C8DC0:("BgCheck_CheckLineAgainstBgActor",), + 0x800C8EEC:("BgCheck_CheckLineAgainstDyna",), + 0x800C90AC:("BgCheck_SphVsFirstDynaPolyList",), + 0x800C921C:("BgCheck_SphVsFirstDynaPolyInBgActor",), + 0x800C9380:("BgCheck_SphVsFirstDynaPoly",), + 0x800C94E0:("CollisionHeader_SegmentedToVirtual",), + 0x800C9564:("CollisionHeader_GetVirtual",), + 0x800C9598:("BgCheck_InitCollisionHeaders",), + 0x800C9640:("BgCheck_ResetPolyCheckTbl",), + 0x800C9694:("SurfaceType_GetData",), + 0x800C9704:("SurfaceType_GetCamDataIndex",), 0x800C9728:("func_800C9728",), - 0x800C9770:("func_800C9770",), + 0x800C9770:("SurfaceType_GetCameraSetting",), 0x800C97F8:("func_800C97F8",), 0x800C9844:("func_800C9844",), 0x800C98CC:("func_800C98CC",), - 0x800C9924:("func_800C9924",), - 0x800C99AC:("func_800C99AC",), + 0x800C9924:("SurfaceType_GetCamPosData",), + 0x800C99AC:("SurfaceType_GetSceneExitIndex",), 0x800C99D4:("func_800C99D4",), 0x800C99FC:("func_800C99FC",), 0x800C9A24:("func_800C9A24",), @@ -1065,30 +1065,30 @@ 0x800C9B18:("func_800C9B18",), 0x800C9B40:("func_800C9B40",), 0x800C9B68:("func_800C9B68",), - 0x800C9B90:("func_800C9B90",), + 0x800C9B90:("SurfaceType_IsHorseBlocked",), 0x800C9BB8:("func_800C9BB8",), - 0x800C9BDC:("func_800C9BDC",), + 0x800C9BDC:("SurfaceType_GetSfx",), 0x800C9C24:("func_800C9C24",), - 0x800C9C74:("func_800C9C74",), - 0x800C9C9C:("func_800C9C9C",), - 0x800C9CC4:("func_800C9CC4",), - 0x800C9CEC:("func_800C9CEC",), - 0x800C9D14:("func_800C9D14",), - 0x800C9D50:("func_800C9D50",), - 0x800C9D8C:("func_800C9D8C",), + 0x800C9C74:("SurfaceType_GetSlope",), + 0x800C9C9C:("SurfaceType_GetLightSettingIndex",), + 0x800C9CC4:("SurfaceType_GetEcho",), + 0x800C9CEC:("SurfaceType_IsHookshotSurface",), + 0x800C9D14:("SurfaceType_IsIgnoredByEntities",), + 0x800C9D50:("SurfaceType_IsIgnoredByProjectiles",), + 0x800C9D8C:("SurfaceType_GetConveyorType",), 0x800C9DDC:("func_800C9DDC",), - 0x800C9E18:("func_800C9E18",), - 0x800C9E40:("func_800C9E40",), - 0x800C9E88:("func_800C9E88",), - 0x800C9EBC:("func_800C9EBC",), - 0x800CA1AC:("func_800CA1AC",), - 0x800CA1E8:("func_800CA1E8",), - 0x800CA22C:("func_800CA22C",), + 0x800C9E18:("SurfaceType_GetConveyorSpeed",), + 0x800C9E40:("SurfaceType_GetConveyorDirection",), + 0x800C9E88:("SurfaceType_IsWallDamage",), + 0x800C9EBC:("WaterBox_GetSurfaceImpl",), + 0x800CA1AC:("WaterBox_GetSurface1",), + 0x800CA1E8:("WaterBox_GetSurface1_2",), + 0x800CA22C:("WaterBox_GetSurface2",), 0x800CA568:("func_800CA568",), - 0x800CA634:("func_800CA634",), - 0x800CA648:("func_800CA648",), + 0x800CA634:("WaterBox_GetCamDataIndex",), + 0x800CA648:("WaterBox_GetCameraSetting",), 0x800CA6B8:("func_800CA6B8",), - 0x800CA6D8:("func_800CA6D8",), + 0x800CA6D8:("WaterBox_GetLightSettingIndex",), 0x800CA6F0:("func_800CA6F0",), 0x800CA9D0:("func_800CA9D0",), 0x800CAA14:("func_800CAA14",), @@ -1096,22 +1096,22 @@ 0x800CAC0C:("BgCheck2_UpdateActorYRotation",), 0x800CACA0:("BgCheck2_AttachToMesh",), 0x800CAD2C:("BgCheck2_UpdateActorAttachedToMesh",), - 0x800CAE10:("BcCheck3_BgActorInit",), - 0x800CAE34:("BgCheck3_LoadMesh",), - 0x800CAE7C:("BgCheck3_ResetFlags",), - 0x800CAE88:("func_800CAE88",), - 0x800CAE9C:("func_800CAE9C",), - 0x800CAEB0:("func_800CAEB0",), - 0x800CAEE0:("func_800CAEE0",), - 0x800CAEF4:("func_800CAEF4",), - 0x800CAF24:("func_800CAF24",), - 0x800CAF38:("func_800CAF38",), - 0x800CAF4C:("func_800CAF4C",), - 0x800CAF70:("func_800CAF70",), - 0x800CAF94:("func_800CAF94",), - 0x800CAFB8:("func_800CAFB8",), - 0x800CAFDC:("func_800CAFDC",), - 0x800CB000:("func_800CB000",), + 0x800CAE10:("DynaPolyActor_Init",), + 0x800CAE34:("DynaPolyActor_LoadMesh",), + 0x800CAE7C:("DynaPolyActor_ResetState",), + 0x800CAE88:("DynaPolyActor_SetRidingFallingState",), + 0x800CAE9C:("DynaPolyActor_SetRidingMovingState",), + 0x800CAEB0:("DynaPolyActor_SetRidingMovingStateByIndex",), + 0x800CAEE0:("DynaPolyActor_SetRidingRotatingState",), + 0x800CAEF4:("DynaPolyActor_SetRidingRotatingStateByIndex",), + 0x800CAF24:("DynaPolyActor_SetSwitchPressedState",), + 0x800CAF38:("DynaPolyActor_SetHeavySwitchPressedState",), + 0x800CAF4C:("DynaPolyActor_IsInRidingFallingState",), + 0x800CAF70:("DynaPolyActor_IsInRidingMovingState",), + 0x800CAF94:("DynaPolyActor_IsInRidingRotatingState",), + 0x800CAFB8:("DynaPolyActor_IsInSwitchPressedState",), + 0x800CAFDC:("DynaPolyActor_IsInHeavySwitchPressedState",), + 0x800CB000:("DynaPolyActor_ValidateMove",), 0x800CB210:("Camera_fabsf",), 0x800CB240:("Camera_LengthVec3f",), 0x800CB270:("func_800CB270",), @@ -1268,17 +1268,17 @@ 0x800DE9B0:("Camera_Update",), 0x800DF498:("func_800DF498",), 0x800DF4D0:("Camera_SetMode",), - 0x800DF840:("func_800DF840",), + 0x800DF840:("Camera_ChangeMode",), 0x800DF86C:("func_800DF86C",), 0x800DF8EC:("func_800DF8EC",), 0x800DFAC8:("func_800DFAC8",), - 0x800DFB14:("func_800DFB14",), + 0x800DFB14:("Camera_ChangeDataIdx",), 0x800DFC1C:("func_800DFC1C",), 0x800DFC40:("func_800DFC40",), - 0x800DFC68:("func_800DFC68",), + 0x800DFC68:("Camera_GetInputDirYaw",), 0x800DFC90:("func_800DFC90",), - 0x800DFCB4:("func_800DFCB4",), - 0x800DFCDC:("func_800DFCDC",), + 0x800DFCB4:("Camera_GetCamDirPitch",), + 0x800DFCDC:("Camera_GetCamDirYaw",), 0x800DFD04:("func_800DFD04",), 0x800DFD78:("func_800DFD78",), 0x800DFEF0:("func_800DFEF0",), @@ -1290,13 +1290,13 @@ 0x800DFFAC:("func_800DFFAC",), 0x800E007C:("func_800E007C",), 0x800E01AC:("func_800E01AC",), - 0x800E01B8:("func_800E01B8",), + 0x800E01B8:("Camera_GetQuakeOffset",), 0x800E01DC:("func_800E01DC",), 0x800E0228:("func_800E0228",), 0x800E0238:("func_800E0238",), - 0x800E02AC:("func_800E02AC",), - 0x800E0308:("func_800E0308",), - 0x800E031C:("func_800E031C",), + 0x800E02AC:("Camera_SetToTrackActor",), + 0x800E0308:("Camera_SetTargetActor",), + 0x800E031C:("Camera_GetWaterYPos",), 0x800E0348:("func_800E0348",), 0x800E03A0:("DamageTable_Get",), 0x800E03CC:("DamageTable_Clear",), @@ -1518,13 +1518,13 @@ 0x800E8FA4:("func_800E8FA4",), 0x800E9138:("func_800E9138",), 0x800E9250:("func_800E9250",), - 0x800E9360:("func_800E9360",), + 0x800E9360:("SaveContext_Init",), 0x800E93E0:("GameInfo_Init",), - 0x800E9470:("func_800E9470",), + 0x800E9470:("DebugDisplay_Init",), 0x800E9488:("DebugDisplay_AddObject",), 0x800E9564:("DebugDisplay_DrawObjects",), - 0x800E95F4:("func_800E95F4",), - 0x800E97D8:("func_800E97D8",), + 0x800E95F4:("DebugDisplay_DrawSpriteI8",), + 0x800E97D8:("DebugDisplay_DrawPolygon",), 0x800E992C:("func_800E992C",), 0x800E99B0:("func_800E99B0",), 0x800E9C90:("func_800E9C90",), @@ -1534,36 +1534,36 @@ 0x800E9E94:("func_800E9E94",), 0x800E9F78:("func_800E9F78",), 0x800EA060:("Cutscene_Init",), - 0x800EA0D4:("func_800EA0D4",), - 0x800EA0EC:("func_800EA0EC",), - 0x800EA110:("Cutscene_StepCutscene1",), - 0x800EA15C:("Cutscene_StepCutscene2",), - 0x800EA210:("Cutscene_Nop800EA210",), + 0x800EA0D4:("Cutscene_Start",), + 0x800EA0EC:("Cutscene_End",), + 0x800EA110:("Cutscene_Update1",), + 0x800EA15C:("Cutscene_Update2",), + 0x800EA210:("Cutscene_DoNothing",), 0x800EA220:("func_800EA220",), 0x800EA258:("func_800EA258",), 0x800EA2B8:("func_800EA2B8",), - 0x800EA324:("func_800EA324",), - 0x800EABAC:("func_800EABAC",), - 0x800EAC08:("func_800EAC08",), - 0x800EAC44:("func_800EAC44",), - 0x800EAC94:("func_800EAC94",), - 0x800EAD14:("func_800EAD14",), + 0x800EA324:("Cutscene_Command_Misc",), + 0x800EABAC:("Cutscene_Command_SetLighting",), + 0x800EAC08:("Cutscene_Command_PlaySequence",), + 0x800EAC44:("Cutscene_Command_StopSequence",), + 0x800EAC94:("Cutscene_Command_FadeSequence",), + 0x800EAD14:("Cutscene_Command_PlayAmbienceSequence",), 0x800EAD48:("func_800EAD48",), 0x800EAD7C:("func_800EAD7C",), 0x800EADB0:("func_800EADB0",), - 0x800EAECC:("func_800EAECC",), - 0x800EAF20:("func_800EAF20",), - 0x800EAFE0:("func_800EAFE0",), - 0x800EB1DC:("func_800EB1DC",), - 0x800EB364:("func_800EB364",), - 0x800EB4B4:("func_800EB4B4",), - 0x800EB6F8:("func_800EB6F8",), - 0x800EBB68:("func_800EBB68",), - 0x800EBCD0:("func_800EBCD0",), - 0x800EBD60:("func_800EBD60",), - 0x800EC678:("func_800EC678",), - 0x800EC6D4:("func_800EC6D4",), - 0x800EC924:("func_800EC924",), + 0x800EAECC:("Cutscene_Command_FadeAmbienceSequence",), + 0x800EAF20:("Cutscene_Command_Rumble",), + 0x800EAFE0:("Cutscene_Command_FadeColorScreen",), + 0x800EB1DC:("Cutscene_Command_SetTime",), + 0x800EB364:("Cutscene_TerminatorImpl",), + 0x800EB4B4:("Cutscene_Command_Terminator",), + 0x800EB6F8:("Cutscene_Command_ChooseCreditsScenes",), + 0x800EBB68:("Cutscene_Command_MotionBlur",), + 0x800EBCD0:("Cutscene_Command_GiveTatlToPlayer",), + 0x800EBD60:("Cutscene_Command_TransitionFX",), + 0x800EC678:("Cutscene_Command_Camera",), + 0x800EC6D4:("Cutscene_CountNormalMasks",), + 0x800EC924:("Cutscene_Command_Textbox",), 0x800ECD7C:("func_800ECD7C",), 0x800ECE40:("Cutscene_ProcessCommands",), 0x800ED980:("func_800ED980",), @@ -1571,17 +1571,17 @@ 0x800EDA04:("func_800EDA04",), 0x800EDA84:("func_800EDA84",), 0x800EDBE0:("func_800EDBE0",), - 0x800EDDB0:("nop_800EDDB0",), + 0x800EDDB0:("func_800EDDB0",), 0x800EDDBC:("func_800EDDBC",), - 0x800EDDCC:("func_800EDDCC",), - 0x800EDE34:("func_800EDE34",), - 0x800EDF24:("func_800EDF24",), - 0x800EDF78:("func_800EDF78",), - 0x800EE0CC:("func_800EE0CC",), - 0x800EE1D8:("func_800EE1D8",), - 0x800EE200:("func_800EE200",), - 0x800EE29C:("func_800EE29C",), - 0x800EE2F4:("func_800EE2F4",), + 0x800EDDCC:("Cutscene_LoadCutsceneData",), + 0x800EDE34:("Cutscene_ActorTranslate",), + 0x800EDF24:("Cutscene_ActorTranslateAndYaw",), + 0x800EDF78:("Cutscene_ActorTranslateAndYawSmooth",), + 0x800EE0CC:("Cutscene_ActorTranslateXZAndYawSmooth",), + 0x800EE1D8:("Cutscene_GetSceneSetupIndex",), + 0x800EE200:("Cutscene_GetActorActionIndex",), + 0x800EE29C:("Cutscene_CheckActorAction",), + 0x800EE2F4:("Cutscene_IsPlaying",), 0x800EE320:("GetItem_Draw",), 0x800EE364:("func_800EE364",), 0x800EE400:("func_800EE400",), @@ -1610,32 +1610,32 @@ 0x800EFF04:("EffFootmark_Add",), 0x800F00BC:("EffFootmark_Update",), 0x800F01C8:("EffFootmark_Draw",), - 0x800F0390:("func_800F0390",), - 0x800F03C0:("func_800F03C0",), - 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",), + 0x800F0390:("SoundSource_InitAll",), + 0x800F03C0:("SoundSource_UpdateAll",), + 0x800F048C:("SoundSource_Add",), + 0x800F0568:("SoundSource_PlaySfxAtFixedWorldPos",), + 0x800F0590:("SoundSource_PlaySfxEachFrameAtFixedWorldPos",), + 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:("func_800F12D0",), - 0x800F1304:("func_800F1304",), - 0x800F1374:("func_800F1374",), - 0x800F13E8:("func_800F13E8",), + 0x800F12D0:("EnvFlags_UnsetAll",), + 0x800F1304:("EnvFlags_Set",), + 0x800F1374:("EnvFlags_Unset",), + 0x800F13E8:("EnvFlags_Get",), 0x800F1460:("func_800F1460",), 0x800F14F8:("ActorCutscene_GetCutsceneImpl",), 0x800F1544:("ActorCutscene_Init",), @@ -1677,10 +1677,10 @@ 0x800F2FFC:("FireObj_UpdateStateTransitions",), 0x800F31EC:("FireObj_Draw",), 0x800F33F4:("FireObj_InitLight",), - 0x800F34C4:("FireObj_FiniLight",), + 0x800F34C4:("FireObj_DestroyLight",), 0x800F34EC:("FireObj_UpdateLight",), 0x800F36CC:("FireObj_Init",), - 0x800F37B0:("FireObj_Fini",), + 0x800F37B0:("FireObj_Destroy",), 0x800F37F0:("FireObj_SetState2",), 0x800F3820:("FireObj_Update",), 0x800F3940:("func_800F3940",), @@ -1693,15 +1693,15 @@ 0x800F40A0:("func_800F40A0",), 0x800F415C:("func_800F415C",), 0x800F41E4:("func_800F41E4",), - 0x800F42A0:("func_800F42A0",), - 0x800F43BC:("func_800F43BC",), - 0x800F44F4:("func_800F44F4",), - 0x800F4540:("func_800F4540",), - 0x800F470C:("func_800F470C",), + 0x800F42A0:("Jpeg_ScheduleDecoderTask",), + 0x800F43BC:("Jpeg_CopyToZbuffer",), + 0x800F44F4:("Jpeg_GetUnalignedU16",), + 0x800F4540:("Jpeg_ParseMarkers",), + 0x800F470C:("Jpeg_Decode",), 0x800F4A10:("func_800F4A10",), - 0x800F4C0C:("func_800F4C0C",), - 0x800F4E20:("func_800F4E20",), - 0x800F4F28:("func_800F4F28",), + 0x800F4C0C:("KaleidoSetup_Update",), + 0x800F4E20:("KaleidoSetup_Init",), + 0x800F4F28:("KaleidoSetup_Destroy",), 0x800F4F40:("Font_LoadChar",), 0x800F4F54:("Font_LoadCharNES",), 0x800F4FC0:("Font_LoadMessageBoxEndIcon",), @@ -1710,7 +1710,7 @@ 0x800F50D4:("func_800F50D4",), 0x800F510C:("Kankyo_Init",), 0x800F5954:("func_800F5954",), - 0x800F5A8C:("func_800F5A8C",), + 0x800F5A8C:("Environment_LerpWeight",), 0x800F5B10:("func_800F5B10",), 0x800F5CD0:("func_800F5CD0",), 0x800F6834:("func_800F6834",), @@ -1738,7 +1738,7 @@ 0x800FAC20:("func_800FAC20",), 0x800FAF74:("func_800FAF74",), 0x800FB010:("func_800FB010",), - 0x800FB320:("func_800FB320",), + 0x800FB320:("Environment_AddLightningBolts",), 0x800FB388:("func_800FB388",), 0x800FB758:("func_800FB758",), 0x800FB9B4:("func_800FB9B4",), @@ -1847,7 +1847,7 @@ 0x8010007C:("Color_RGBA8_Copy",), 0x801000A4:("func_801000A4",), 0x801000CC:("func_801000CC",), - 0x801000F4:("func_801000F4",), + 0x801000F4:("Lib_PlaySfxAtPos",), 0x8010011C:("Lib_Vec3f_TranslateAndRotateY",), 0x801001B8:("Lib_LerpRGB",), 0x80100448:("Math_Vec3f_StepTo",), @@ -2064,7 +2064,7 @@ 0x8010C0C0:("Nmi_Init",), 0x8010C164:("Nmi_SetPrenmiStart",), 0x8010C19C:("Nmi_GetPrenmiHasStarted",), - 0x8010C1B0:("func_8010C1B0",), + 0x8010C1B0:("MsgEvent_SendNullTask",), 0x8010C230:("OLib_Vec3fDist",), 0x8010C274:("OLib_Vec3fDistOutDiff",), 0x8010C2D0:("OLib_Vec3fDistXZ",), @@ -2119,8 +2119,8 @@ 0x80114A9C:("func_80114A9C",), 0x80114B84:("func_80114B84",), 0x80114CA0:("func_80114CA0",), - 0x80114E90:("func_80114E90",), - 0x80114F2C:("func_80114F2C",), + 0x80114E90:("Interface_HasEmptyBottle",), + 0x80114F2C:("Interface_HasItemInBottle",), 0x80114FD0:("func_80114FD0",), 0x80115130:("func_80115130",), 0x801152B8:("func_801152B8",), @@ -2167,11 +2167,11 @@ 0x801210E0:("func_801210E0",), 0x80121F94:("func_80121F94",), 0x80121FC4:("func_80121FC4",), - 0x801224E0:("func_801224E0",), - 0x80122524:("func_80122524",), - 0x801225CC:("func_801225CC",), - 0x80122660:("func_80122660",), - 0x80122670:("func_80122670",), + 0x801224E0:("Path_GetByIndex",), + 0x80122524:("Path_OrientAndGetDistSq",), + 0x801225CC:("Path_CopyLastPoint",), + 0x80122660:("FrameAdvance_Init",), + 0x80122670:("FrameAdvance_Update",), 0x801226E0:("func_801226E0",), 0x80122744:("func_80122744",), 0x80122760:("func_80122760",), @@ -2191,7 +2191,7 @@ 0x8012301C:("func_8012301C",), 0x80123140:("func_80123140",), 0x80123358:("func_80123358",), - 0x801233E4:("func_801233E4",), + 0x801233E4:("Player_InCsMode",), 0x80123420:("func_80123420",), 0x80123434:("func_80123434",), 0x80123448:("func_80123448",), @@ -2206,7 +2206,7 @@ 0x80123AA4:("func_80123AA4",), 0x80123BD4:("func_80123BD4",), 0x80123C58:("func_80123C58",), - 0x80123C90:("func_80123C90",), + 0x80123C90:("Player_SetEquipmentData",), 0x80123D50:("func_80123D50",), 0x80123DA4:("func_80123DA4",), 0x80123DC0:("func_80123DC0",), @@ -2229,7 +2229,7 @@ 0x801241E0:("func_801241E0",), 0x8012420C:("func_8012420C",), 0x8012422C:("func_8012422C",), - 0x80124258:("func_80124258",), + 0x80124258:("Player_GetExplosiveHeld",), 0x80124278:("func_80124278",), 0x801242B4:("func_801242B4",), 0x801242DC:("func_801242DC",), @@ -2302,14 +2302,14 @@ 0x8012AA9C:("Quake_Add",), 0x8012AAC0:("Quake_RemoveFromIdx",), 0x8012AB08:("Quake_Calc",), - 0x8012AE68:("Quake2_Init",), - 0x8012AEAC:("Quake2_SetCountdown",), - 0x8012AED4:("Quake2_GetCountdown",), - 0x8012AEE4:("Quake2_GetType",), - 0x8012AEF4:("Quake2_SetType",), - 0x8012AF18:("Quake2_ClearType",), - 0x8012AF38:("Quake2_GetFloorQuake",), - 0x8012AF9C:("Quake2_Update",), + 0x8012AE68:("Distortion_Init",), + 0x8012AEAC:("Distortion_SetCountdown",), + 0x8012AED4:("Distortion_GetCountdown",), + 0x8012AEE4:("Distortion_GetType",), + 0x8012AEF4:("Distortion_SetType",), + 0x8012AF18:("Distortion_ClearType",), + 0x8012AF38:("Distortion_GetUnderwaterCurrentSpeed",), + 0x8012AF9C:("Distortion_Update",), 0x8012BBE8:("Quake_NumActiveQuakes",), 0x8012BC50:("Gfx_SetFog",), 0x8012BD8C:("Gfx_SetFogWithSync",), @@ -2405,16 +2405,16 @@ 0x8012EAA8:("Room_HandleLoadCallbacks",), 0x8012EBA8:("Room_Draw",), 0x8012EBF8:("func_8012EBF8",), - 0x8012EC80:("func_8012EC80",), - 0x8012ED34:("func_8012ED34",), - 0x8012ED78:("func_8012ED78",), - 0x8012EDE8:("func_8012EDE8",), - 0x8012EE34:("func_8012EE34",), - 0x8012EF0C:("func_8012EF0C",), - 0x8012F0EC:("func_8012F0EC",), - 0x8012F1BC:("func_8012F1BC",), - 0x8012F22C:("func_8012F22C",), - 0x8012F278:("func_8012F278",), + 0x8012EC80:("Inventory_GetBtnBItem",), + 0x8012ED34:("Inventory_ChangeEquipment",), + 0x8012ED78:("Inventory_DeleteEquipment",), + 0x8012EDE8:("Inventory_ChangeUpgrade",), + 0x8012EE34:("Inventory_IsMapVisible",), + 0x8012EF0C:("Inventory_SetMapVisibility",), + 0x8012F0EC:("Inventory_SaveDekuPlaygroundHighScore",), + 0x8012F1BC:("Inventory_IncrementSkullTokenCount",), + 0x8012F22C:("Inventory_GetSkullTokenCount",), + 0x8012F278:("Inventory_SaveLotteryCodeGuess",), 0x8012F2E0:("Object_Spawn",), 0x8012F3D0:("Object_InitBank",), 0x8012F4FC:("Object_UpdateBank",), @@ -2499,26 +2499,26 @@ 0x80132338:("Entrance_GetSceneNumAbsolute",), 0x80132374:("Entrance_GetSpawnNum",), 0x801323A0:("Entrance_GetTransitionFlags",), - 0x801323D0:("func_801323D0",), - 0x80132428:("func_80132428",), - 0x80132494:("func_80132494",), - 0x801326B8:("func_801326B8",), - 0x801328F0:("func_801328F0",), - 0x80132920:("func_80132920",), - 0x80132938:("func_80132938",), - 0x80132954:("func_80132954",), - 0x8013296C:("func_8013296C",), - 0x80132A18:("func_80132A18",), - 0x80132A3C:("func_80132A3C",), - 0x80132A80:("func_80132A80",), - 0x80132AD8:("func_80132AD8",), - 0x80132B24:("func_80132B24",), - 0x80132B84:("func_80132B84",), - 0x80132D70:("func_80132D70",), - 0x80132E9C:("func_80132E9C",), - 0x80132FDC:("func_80132FDC",), - 0x80133000:("func_80133000",), - 0x80133038:("func_80133038",), + 0x801323D0:("Schedule_CheckFlagS",), + 0x80132428:("Schedule_CheckFlagL",), + 0x80132494:("Schedule_CheckTimeRangeS",), + 0x801326B8:("Schedule_CheckTimeRangeL",), + 0x801328F0:("Schedule_ReturnValueL",), + 0x80132920:("Schedule_ReturnNone",), + 0x80132938:("Schedule_ReturnEmpty",), + 0x80132954:("Schedule_Nop",), + 0x8013296C:("Schedule_CheckMiscS",), + 0x80132A18:("Schedule_ReturnValueS",), + 0x80132A3C:("Schedule_CheckSceneS",), + 0x80132A80:("Schedule_CheckSceneL",), + 0x80132AD8:("Schedule_CheckDayS",), + 0x80132B24:("Schedule_CheckDayL",), + 0x80132B84:("Schedule_ReturnTime",), + 0x80132D70:("Schedule_CheckBeforeTimeS",), + 0x80132E9C:("Schedule_CheckBeforeTimeL",), + 0x80132FDC:("Schedule_BranchL",), + 0x80133000:("Schedule_JumpL",), + 0x80133038:("Schedule_RunScript",), 0x801330E0:("SkelAnime_DrawLimbLod",), 0x801332F0:("SkelAnime_DrawLod",), 0x801334A0:("SkelAnime_DrawFlexLimbLod",), @@ -2527,8 +2527,8 @@ 0x80133B3C:("SkelAnime_DrawOpa",), 0x80133CDC:("SkelAnime_DrawFlexLimbOpa",), 0x80133F28:("SkelAnime_DrawFlexOpa",), - 0x80134148:("func_80134148",), - 0x801343C0:("func_801343C0",), + 0x80134148:("SkelAnime_DrawTransformFlexLimbOpa",), + 0x801343C0:("SkelAnime_DrawTransformFlexOpa",), 0x80134600:("SkelAnime_GetFrameData",), 0x80134724:("Animation_GetLength",), 0x80134748:("Animation_GetLastFrame",), @@ -2536,7 +2536,7 @@ 0x80134990:("SkelAnime_Draw",), 0x80134B54:("SkelAnime_DrawFlexLimb",), 0x80134DBC:("SkelAnime_DrawFlex",), - 0x80134FFC:("SkelAnime_GetFrameData2",), + 0x80134FFC:("SkelAnime_GetFrameDataLegacy",), 0x801353D4:("Animation_GetLimbCount2",), 0x801353F8:("Animation_GetLength2",), 0x8013541C:("Animation_GetLastFrame2",), @@ -2608,23 +2608,23 @@ 0x801378B8:("Animation_OnFrame",), 0x801378E0:("SkelAnime_Free",), 0x8013792C:("SkelAnime_CopyFrameTable",), - 0x80137970:("func_80137970",), - 0x80137B34:("func_80137B34",), - 0x80137EBC:("func_80137EBC",), - 0x80137F58:("func_80137F58",), - 0x80138050:("func_80138050",), + 0x80137970:("Skin_UpdateVertices",), + 0x80137B34:("Skin_ApplyLimbModifications",), + 0x80137EBC:("Skin_DrawAnimatedLimb",), + 0x80137F58:("Skin_DrawLimb",), + 0x80138050:("Skin_DrawImpl",), 0x80138228:("func_80138228",), 0x80138258:("func_80138258",), 0x8013828C:("func_8013828C",), 0x801382C4:("func_801382C4",), - 0x80138300:("func_80138300",), - 0x8013835C:("func_8013835C",), - 0x80138410:("func_80138410",), - 0x80138424:("func_80138424",), - 0x8013859C:("func_8013859C",), - 0x80138700:("func_80138700",), + 0x80138300:("Skin_GetLimbPos",), + 0x8013835C:("Skin_GetVertexPos",), + 0x80138410:("Skin_Setup",), + 0x80138424:("Skin_InitAnimatedLimb",), + 0x8013859C:("Skin_Init",), + 0x80138700:("Skin_Free",), 0x801387D4:("func_801387D4",), - 0x801388E4:("func_801388E4",), + 0x801388E4:("Skin_ApplyAnimTransformations",), 0x80138BA0:("SkinMatrix_Vec3fMtxFMultXYZW",), 0x80138C88:("SkinMatrix_Vec3fMtxFMultXYZ",), 0x80138D38:("SkinMatrix_MtxFMtxFMult",), @@ -2655,61 +2655,61 @@ 0x8013A4C4:("func_8013A4C4",), 0x8013A504:("func_8013A504",), 0x8013A530:("func_8013A530",), - 0x8013A7C0:("func_8013A7C0",), - 0x8013A860:("func_8013A860",), - 0x8013AB00:("func_8013AB00",), - 0x8013AD6C:("func_8013AD6C",), - 0x8013AD9C:("func_8013AD9C",), - 0x8013AED4:("func_8013AED4",), + 0x8013A7C0:("SubS_FindDoor",), + 0x8013A860:("SubS_DrawTransformFlexLimb",), + 0x8013AB00:("SubS_DrawTransformFlex",), + 0x8013AD6C:("SubS_InCsMode",), + 0x8013AD9C:("SubS_UpdateLimb",), + 0x8013AED4:("SubS_UpdateFlags",), 0x8013AF00:("func_8013AF00",), 0x8013B010:("func_8013B010",), 0x8013B0C8:("func_8013B0C8",), 0x8013B350:("func_8013B350",), 0x8013B6B0:("func_8013B6B0",), 0x8013B878:("func_8013B878",), - 0x8013BB34:("func_8013BB34",), - 0x8013BB7C:("func_8013BB7C",), - 0x8013BC6C:("func_8013BC6C",), - 0x8013BD40:("func_8013BD40",), - 0x8013BEDC:("func_8013BEDC",), + 0x8013BB34:("SubS_GetAdditionalPath",), + 0x8013BB7C:("SubS_FindNearestActor",), + 0x8013BC6C:("SubS_ChangeAnimationByInfoS",), + 0x8013BD40:("SubS_HasReachedPoint",), + 0x8013BEDC:("SubS_GetDayDependentPath",), 0x8013C068:("func_8013C068",), 0x8013C624:("func_8013C624",), - 0x8013C8B8:("func_8013C8B8",), + 0x8013C8B8:("SubS_CopyPointFromPathCheckBounds",), 0x8013C964:("func_8013C964",), - 0x8013CC2C:("func_8013CC2C",), - 0x8013CD64:("func_8013CD64",), - 0x8013CF04:("func_8013CF04",), - 0x8013D0E0:("func_8013D0E0",), - 0x8013D2E0:("func_8013D2E0",), - 0x8013D5E8:("func_8013D5E8",), - 0x8013D648:("func_8013D648",), - 0x8013D68C:("func_8013D68C",), - 0x8013D720:("func_8013D720",), - 0x8013D768:("func_8013D768",), - 0x8013D83C:("func_8013D83C",), - 0x8013D8DC:("func_8013D8DC",), - 0x8013D924:("func_8013D924",), - 0x8013D960:("func_ActorCategoryIterateById",), - 0x8013D9C8:("func_8013D9C8",), - 0x8013DB90:("func_8013DB90",), - 0x8013DC40:("func_8013DC40",), - 0x8013DCCC:("func_8013DCCC",), - 0x8013DCE0:("func_8013DCE0",), - 0x8013DE04:("func_8013DE04",), - 0x8013DF3C:("func_8013DF3C",), - 0x8013E054:("func_8013E054",), - 0x8013E07C:("func_8013E07C",), - 0x8013E0A4:("func_8013E0A4",), - 0x8013E1C8:("func_8013E1C8",), - 0x8013E2D4:("func_8013E2D4",), - 0x8013E3B8:("func_8013E3B8",), - 0x8013E4B0:("func_8013E4B0",), - 0x8013E5CC:("func_8013E5CC",), - 0x8013E640:("func_8013E640",), + 0x8013CC2C:("SubS_FillShadowTex",), + 0x8013CD64:("SubS_GenShadowTex",), + 0x8013CF04:("SubS_DrawShadowTex",), + 0x8013D0E0:("SubS_ComputeTurnToPointRot",), + 0x8013D2E0:("SubS_TurnToPoint",), + 0x8013D5E8:("SubS_AngleDiffLessEqual",), + 0x8013D648:("SubS_GetPathByIndex",), + 0x8013D68C:("SubS_CopyPointFromPath",), + 0x8013D720:("SubS_GetDistSqAndOrientPoints",), + 0x8013D768:("SubS_MoveActorToPoint",), + 0x8013D83C:("SubS_GetDistSqAndOrientPath",), + 0x8013D8DC:("SubS_IsObjectLoaded",), + 0x8013D924:("SubS_GetObjectIndex",), + 0x8013D960:("SubS_FindActor",), + 0x8013D9C8:("SubS_FillLimbRotTables",), + 0x8013DB90:("SubS_IsFloorAbove",), + 0x8013DC40:("SubS_CopyPointFromPathList",), + 0x8013DCCC:("SubS_GetPathCount",), + 0x8013DCE0:("SubS_ActorPathing_Init",), + 0x8013DE04:("SubS_ActorPathing_Update",), + 0x8013DF3C:("SubS_ActorPathing_ComputePointInfo",), + 0x8013E054:("SubS_ActorPathing_MoveWithGravity",), + 0x8013E07C:("SubS_ActorPathing_MoveWithoutGravityReverse",), + 0x8013E0A4:("SubS_ActorPathing_SetNextPoint",), + 0x8013E1C8:("SubS_ChangeAnimationBySpeedInfo",), + 0x8013E2D4:("SubS_StartActorCutscene",), + 0x8013E3B8:("SubS_FillCutscenesList",), + 0x8013E4B0:("SubS_ConstructPlane",), + 0x8013E5CC:("SubS_LineSegVsPlane",), + 0x8013E640:("SubS_FindActorCustom",), 0x8013E748:("func_8013E748",), - 0x8013E7C0:("func_8013E7C0",), + 0x8013E7C0:("SubS_ActorAndPlayerFaceEachOther",), 0x8013E8F8:("func_8013E8F8",), - 0x8013E950:("func_8013E950",), + 0x8013E950:("SubS_TurnToPointStep",), 0x8013EC10:("func_8013EC10",), 0x8013EC44:("func_8013EC44",), 0x8013ECE0:("func_8013ECE0",), @@ -2734,13 +2734,13 @@ 0x8013F1D8:("View_WriteScissor",), 0x8013F28C:("View_SyncAndWriteScissor",), 0x8013F2F8:("View_SetScissorForLetterbox",), - 0x8013F3F8:("View_SetQuakeRotation",), - 0x8013F420:("View_SetQuakeScale",), - 0x8013F448:("View_SetQuakeSpeed",), - 0x8013F45C:("View_InitCameraQuake",), - 0x8013F4C0:("View_ClearQuake",), - 0x8013F4F4:("View_SetQuake",), - 0x8013F54C:("View_StepQuake",), + 0x8013F3F8:("View_SetDistortionDirRot",), + 0x8013F420:("View_SetDistortionScale",), + 0x8013F448:("View_SetDistortionSpeed",), + 0x8013F45C:("View_InitDistortion",), + 0x8013F4C0:("View_ClearDistortion",), + 0x8013F4F4:("View_SetDistortion",), + 0x8013F54C:("View_StepDistortion",), 0x8013F6FC:("View_RenderView",), 0x8013F748:("View_RenderToPerspectiveMatrix",), 0x8013FA1C:("View_RenderToOrthographicMatrix",), @@ -2783,34 +2783,34 @@ 0x801431E8:("func_801431E8",), 0x80143324:("func_80143324",), 0x801434E4:("func_801434E4",), - 0x801435A0:("func_801435A0",), - 0x80143624:("func_80143624",), - 0x80143668:("func_80143668",), - 0x80143A04:("func_80143A04",), - 0x80143A10:("func_80143A10",), - 0x80143A54:("func_80143A54",), - 0x80143AC4:("func_80143AC4",), - 0x80143B0C:("func_80143B0C",), + 0x801435A0:("SkyboxDraw_UpdateMatrix",), + 0x80143624:("SkyboxDraw_SetColors",), + 0x80143668:("SkyboxDraw_Draw",), + 0x80143A04:("SkyboxDraw_Noop",), + 0x80143A10:("Sram_ActivateOwl",), + 0x80143A54:("Sram_ClearHighscores",), + 0x80143AC4:("Sram_ClearFlagsAtDawnOfTheFirstDay",), + 0x80143B0C:("Sram_SaveEndOfCycle",), 0x80144574:("Sram_IncrementDay",), 0x801445E4:("Sram_CalcChecksum",), - 0x80144628:("func_80144628",), + 0x80144628:("Sram_ResetSave",), 0x80144684:("Sram_GenerateRandomSaveFields",), - 0x80144890:("func_80144890",), + 0x80144890:("Sram_InitNewSave",), 0x80144968:("Sram_InitDebugSave",), 0x80144A94:("func_80144A94",), - 0x80144E78:("func_80144E78",), + 0x80144E78:("Sram_OpenSave",), 0x8014546C:("func_8014546C",), 0x80145698:("func_80145698",), 0x801457CC:("func_801457CC",), 0x80146580:("func_80146580",), 0x80146628:("func_80146628",), - 0x80146AA0:("func_80146AA0",), + 0x80146AA0:("Sram_InitSave",), 0x80146DF8:("func_80146DF8",), - 0x80146E40:("func_80146E40",), + 0x80146E40:("Sram_InitSram",), 0x80146E70:("Sram_Alloc",), 0x80146EBC:("func_80146EBC",), - 0x80146EE8:("func_80146EE8",), - 0x80146F5C:("func_80146F5C",), + 0x80146EE8:("Sram_SaveSpecialEnterClockTown",), + 0x80146F5C:("Sram_SaveSpecialNewDay",), 0x80147008:("func_80147008",), 0x80147020:("func_80147020",), 0x80147068:("func_80147068",), @@ -2822,8 +2822,8 @@ 0x8014750C:("Sram_nop8014750C",), 0x80147520:("func_80147520",), 0x80147564:("func_80147564",), - 0x80147624:("func_80147624",), - 0x80147734:("func_80147734",), + 0x80147624:("Message_ShouldAdvance",), + 0x80147734:("Message_ShouldAdvanceSilent",), 0x801477B4:("func_801477B4",), 0x80147818:("func_80147818",), 0x80147F18:("func_80147F18",), @@ -2837,12 +2837,12 @@ 0x801496C8:("func_801496C8",), 0x8014995C:("func_8014995C",), 0x80149C18:("func_80149C18",), - 0x80149EBC:("func_80149EBC",), + 0x80149EBC:("Message_FindMessage",), 0x80149F74:("func_80149F74",), 0x8014AAD0:("func_8014AAD0",), 0x8014ADBC:("func_8014ADBC",), 0x8014C70C:("func_8014C70C",), - 0x8014CC14:("func_8014CC14",), + 0x8014CC14:("Message_LoadChar",), 0x8014CCB4:("func_8014CCB4",), 0x8014CDF0:("func_8014CDF0",), 0x8014CFDC:("func_8014CFDC",), @@ -2852,7 +2852,7 @@ 0x80150A84:("func_80150A84",), 0x80150D08:("func_80150D08",), 0x801514B0:("func_801514B0",), - 0x801518B0:("func_801518B0",), + 0x801518B0:("Message_StartTextbox",), 0x80151938:("func_80151938",), 0x80151A68:("func_80151A68",), 0x80151BB4:("func_80151BB4",), @@ -2860,7 +2860,7 @@ 0x80151DA4:("func_80151DA4",), 0x80152434:("func_80152434",), 0x80152464:("func_80152464",), - 0x80152498:("func_80152498",), + 0x80152498:("Message_GetState",), 0x8015268C:("func_8015268C",), 0x80152C64:("func_80152C64",), 0x80152CAC:("func_80152CAC",), @@ -2874,24 +2874,24 @@ 0x8015680C:("func_8015680C",), 0x801586A4:("func_801586A4",), 0x801586D4:("Message_Init",), - 0x801588D0:("func_801588D0",), - 0x80158988:("func_80158988",), - 0x80158A24:("func_80158A24",), - 0x80158C04:("func_80158C04",), - 0x80158D98:("func_80158D98",), - 0x80158FB0:("func_80158FB0",), - 0x8015926C:("func_8015926C",), + 0x801588D0:("Message_FindMessageNES",), + 0x80158988:("Message_LoadCharNES",), + 0x80158A24:("Message_LoadPluralRupeesNES",), + 0x80158C04:("Message_LoadLocalizedRupeesNES",), + 0x80158D98:("Message_LoadRupeesNES",), + 0x80158FB0:("Message_LoadTimeNES",), + 0x8015926C:("Message_LoadAreaTextNES",), 0x80159438:("func_80159438",), 0x8015966C:("func_8015966C",), 0x8015B198:("func_8015B198",), - 0x8015E750:("func_8015E750",), + 0x8015E750:("Message_FindCreditsMessage",), 0x8015E7EC:("func_8015E7EC",), 0x8015F8A8:("func_8015F8A8",), - 0x80160A90:("func_80160A90",), - 0x80160AF8:("func_80160AF8",), - 0x80160B40:("func_80160B40",), - 0x80160B80:("func_80160B80",), - 0x80160BC0:("func_80160BC0",), + 0x80160A90:("PlayerCall_InitFuncPtrs",), + 0x80160AF8:("PlayerCall_Init",), + 0x80160B40:("PlayerCall_Destroy",), + 0x80160B80:("PlayerCall_Update",), + 0x80160BC0:("PlayerCall_Draw",), 0x80160C00:("ShrinkWindow_SetLetterboxTarget",), 0x80160C14:("ShrinkWindow_GetLetterboxTarget",), 0x80160C28:("ShrinkWindow_SetLetterboxMagnitude",), @@ -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,10 +2995,10 @@ 0x80167814:("func_80167814",), 0x80167DE4:("func_80167DE4",), 0x80167F0C:("func_80167F0C",), - 0x80168090:("func_80168090",), + 0x80168090:("Play_Draw",), 0x80168DAC:("func_80168DAC",), 0x80168F64:("Play_Update",), - 0x801690CC:("func_801690CC",), + 0x801690CC:("Play_InCsMode",), 0x80169100:("func_80169100",), 0x801691F0:("func_801691F0",), 0x80169220:("Play_LoadScene",), @@ -3006,28 +3006,28 @@ 0x801692C4:("func_801692C4",), 0x801693D4:("Play_SceneInit",), 0x80169474:("func_80169474",), - 0x801694DC:("func_801694DC",), - 0x80169584:("Play_GetActiveCameraIndex",), - 0x80169590:("func_80169590",), - 0x80169600:("func_80169600",), - 0x80169668:("func_80169668",), + 0x801694DC:("Play_CreateSubCamera",), + 0x80169584:("Play_GetActiveCamId",), + 0x80169590:("Play_CameraChangeStatus",), + 0x80169600:("Play_ClearCamera",), + 0x80169668:("Play_ClearAllSubCameras",), 0x801696D4:("Play_GetCamera",), 0x8016970C:("Play_CameraSetAtEye",), - 0x8016981C:("func_8016981C",), - 0x80169940:("func_80169940",), - 0x80169988:("func_80169988",), - 0x801699D4:("func_801699D4",), + 0x8016981C:("Play_CameraSetAtEyeUp",), + 0x80169940:("Play_CameraSetFov",), + 0x80169988:("Play_CameraSetRoll",), + 0x801699D4:("Play_CopyCamera",), 0x80169A50:("func_80169A50",), - 0x80169AC0:("func_80169AC0",), + 0x80169AC0:("Play_CameraChangeSetting",), 0x80169AFC:("func_80169AFC",), - 0x80169BC4:("func_80169BC4",), + 0x80169BC4:("Play_CameraGetUID",), 0x80169BF8:("func_80169BF8",), - 0x80169C64:("func_80169C64",), - 0x80169C84:("func_80169C84",), - 0x80169CBC:("convert_scene_number_among_shared_scenes",), - 0x80169D40:("func_80169D40",), - 0x80169DCC:("func_80169DCC",), - 0x80169E6C:("func_80169E6C",), + 0x80169C64:("Play_GetCsCamDataSetting",), + 0x80169C84:("Play_GetCsCamDataVec3s",), + 0x80169CBC:("Play_GetOriginalSceneNumber",), + 0x80169D40:("Play_SaveCycleSceneFlags",), + 0x80169DCC:("Play_SetRespawnData",), + 0x80169E6C:("Play_SetupRespawnPoint",), 0x80169ECC:("func_80169ECC",), 0x80169EFC:("func_80169EFC",), 0x80169F78:("func_80169F78",), @@ -3035,9 +3035,9 @@ 0x80169FFC:("func_80169FFC",), 0x8016A01C:("FrameAdvance_IsEnabled",), 0x8016A02C:("func_8016A02C",), - 0x8016A0AC:("func_8016A0AC",), + 0x8016A0AC:("Play_IsUnderwater",), 0x8016A168:("func_8016A168",), - 0x8016A178:("func_8016A178",), + 0x8016A178:("Play_AssignPlayerActorCsIdsFromScene",), 0x8016A268:("func_8016A268",), 0x8016A2C8:("Play_Init",), 0x8016AC10:("func_8016AC10",), @@ -3135,7 +3135,7 @@ 0x80173950:("GameState_Init",), 0x80173A50:("GameState_Destroy",), 0x80173B00:("GameState_GetNextStateInit",), - 0x80173B0C:("Game_GetNextStateSize",), + 0x80173B0C:("GameState_GetNextStateSize",), 0x80173B18:("GameState_IsRunning",), 0x80173B24:("GameState_GetArenaSize",), 0x80173B48:("func_80173B48",), @@ -3145,16 +3145,16 @@ 0x80173CC8:("GameAlloc_Cleanup",), 0x80173D18:("GameAlloc_Init",), 0x80173D30:("Graph_FaultClient",), - 0x80173DAC:("Graph_DlAlloc",), - 0x80173DCC:("Graph_InitTHGA",), + 0x80173DAC:("Graph_InitTHGA",), + 0x80173DCC:("Graph_SetNextGfxPool",), 0x80173F98:("Graph_GetNextGameState",), 0x80174060:("Graph_FaultAddrConvFunc",), 0x801740D0:("Graph_Init",), 0x80174174:("Graph_Destroy",), - 0x801741A8:("Graph_Render",), - 0x801744AC:("Graph_FrameSetup",), - 0x801744F8:("Graph_RenderFrame",), - 0x80174868:("Graph_DoFrame",), + 0x801741A8:("Graph_TaskSet00",), + 0x801744AC:("Graph_UpdateGame",), + 0x801744F8:("Graph_ExecuteAndDraw",), + 0x80174868:("Graph_Update",), 0x801748A0:("Graph_ThreadEntry",), 0x80174A40:("Graph_GfxPlusOne",), 0x80174A4C:("Graph_BranchDlist",), @@ -3229,8 +3229,8 @@ 0x80178818:("func_80178818",), 0x80178978:("func_80178978",), 0x801789D4:("func_801789D4",), - 0x801789EC:("get_framebuffer",), - 0x80178A14:("get_zbuffer",), + 0x801789EC:("SysCfb_GetFbPtr",), + 0x80178A14:("SysCfb_GetZBuffer",), 0x80178A24:("func_80178A24",), 0x80178A34:("func_80178A34",), 0x80178A94:("func_80178A94",), @@ -3256,7 +3256,7 @@ 0x80179594:("Rand_ZeroFloat",), 0x801795C0:("randPlusMinusPoint5Scaled",), 0x801795F0:("Math3D_Normalize",), - 0x80179678:("func_80179678",), + 0x80179678:("Math3D_PlaneVsLineSegClosestPoint",), 0x80179798:("func_80179798",), 0x80179A44:("func_80179A44",), 0x80179B34:("func_80179B34",), @@ -3278,65 +3278,65 @@ 0x8017A678:("Math3D_XZDistance",), 0x8017A6A8:("Math3D_LengthSquared",), 0x8017A6D4:("Math3D_Vec3fMagnitude",), - 0x8017A6F8:("Math3D_DistanceSquared",), + 0x8017A6F8:("Math3D_Vec3fDistSq",), 0x8017A720:("Math3D_Distance",), 0x8017A740:("Math3D_DistanceS",), 0x8017A7B8:("func_8017A7B8",), 0x8017A7F8:("func_8017A7F8",), 0x8017A838:("func_8017A838",), 0x8017A878:("Math3D_CrossProduct",), - 0x8017A8EC:("Math3D_NormalVector",), - 0x8017A954:("func_8017A954",), - 0x8017AA0C:("func_8017AA0C",), - 0x8017ABBC:("func_8017ABBC",), - 0x8017AD38:("func_8017AD38",), + 0x8017A8EC:("Math3D_SurfaceNorm",), + 0x8017A954:("Math3D_PointRelativeToCubeFaces",), + 0x8017AA0C:("Math3D_PointRelativeToCubeEdges",), + 0x8017ABBC:("Math3D_PointRelativeToCubeVertices",), + 0x8017AD38:("Math3D_LineVsCube",), 0x8017B68C:("func_8017B68C",), 0x8017B7F8:("func_8017B7F8",), 0x8017B884:("Math3D_UnitNormalVector",), 0x8017B998:("Math3D_SignedDistanceFromPlane",), 0x8017B9D8:("func_8017B9D8",), - 0x8017BA14:("Math3D_NormalizedDistanceFromPlane",), - 0x8017BA4C:("Math3D_NormalizedSignedDistanceFromPlane",), - 0x8017BAD0:("func_8017BAD0",), + 0x8017BA14:("Math3D_UDistPlaneToPos",), + 0x8017BA4C:("Math3D_DistPlaneToPos",), + 0x8017BAD0:("Math3D_TriChkPointParaYDist",), 0x8017BD98:("func_8017BD98",), 0x8017BDE0:("func_8017BDE0",), - 0x8017BE30:("func_8017BE30",), - 0x8017BEE0:("func_8017BEE0",), + 0x8017BE30:("Math3D_TriChkPointParaYIntersectDist",), + 0x8017BEE0:("Math3D_TriChkPointParaYIntersectInsideTri",), 0x8017BF8C:("func_8017BF8C",), - 0x8017C008:("func_8017C008",), + 0x8017C008:("Math3D_TriChkLineSegParaYIntersect",), 0x8017C17C:("func_8017C17C",), 0x8017C1F0:("func_8017C1F0",), - 0x8017C494:("func_8017C494",), - 0x8017C540:("func_8017C540",), + 0x8017C494:("Math3D_TriChkPointParaYIntersectInsideTri2",), + 0x8017C540:("Math3D_TriChkPointParaXDist",), 0x8017C808:("func_8017C808",), - 0x8017C850:("func_8017C850",), + 0x8017C850:("Math3D_TriChkPointParaXIntersect",), 0x8017C904:("func_8017C904",), - 0x8017C980:("func_8017C980",), + 0x8017C980:("Math3D_TriChkLineSegParaXIntersect",), 0x8017CB08:("func_8017CB08",), - 0x8017CB7C:("func_8017CB7C",), + 0x8017CB7C:("Math3D_TriChkLineSegParaZDist",), 0x8017CEA8:("func_8017CEA8",), - 0x8017CEF0:("func_8017CEF0",), + 0x8017CEF0:("Math3D_TriChkPointParaZIntersect",), 0x8017CFA4:("func_8017CFA4",), - 0x8017D020:("func_8017D020",), + 0x8017D020:("Math3D_TriChkLineSegParaZIntersect",), 0x8017D1AC:("func_8017D1AC",), 0x8017D220:("func_8017D220",), - 0x8017D2FC:("func_8017D2FC",), + 0x8017D2FC:("Math3D_LineSegVsPlane",), 0x8017D404:("func_8017D404",), 0x8017D568:("Math3D_TriSetCoords",), 0x8017D618:("Math3D_IsPointInSphere",), - 0x8017D668:("func_8017D668",), + 0x8017D668:("Math3D_PointDistToLine2D",), 0x8017D7C0:("func_8017D7C0",), 0x8017D814:("func_8017D814",), 0x8017D91C:("func_8017D91C",), 0x8017DA24:("func_8017DA24",), - 0x8017DB2C:("Math3D_ColSphereLineSeg",), + 0x8017DB2C:("Math3D_LineVsSph",), 0x8017DD34:("func_8017DD34",), 0x8017DE74:("Math3D_ColSphereTri",), 0x8017E294:("func_8017E294",), 0x8017E350:("func_8017E350",), 0x8017ED20:("Math3D_ColCylinderTri",), 0x8017F1A0:("func_8017F1A0",), - 0x8017F1C0:("Math3D_ColSphereSphere",), + 0x8017F1C0:("Math3D_SphVsSph",), 0x8017F1E0:("Math3D_ColSphereSphereIntersect",), 0x8017F200:("Math3D_ColSphereSphereIntersectAndDistance",), 0x8017F2CC:("Math3D_ColSphereCylinderDistance",), @@ -3344,9 +3344,9 @@ 0x8017F45C:("Math3D_ColCylinderCylinderAmount",), 0x8017F47C:("Math3D_ColCylinderCylinderAmountAndDistance",), 0x8017F64C:("Math3d_ColTriTri",), - 0x8017F9C0:("func_8017F9C0",), - 0x8017FA34:("func_8017FA34",), - 0x8017FAA8:("func_8017FAA8",), + 0x8017F9C0:("Math3D_XZInSphere",), + 0x8017FA34:("Math3D_XYInSphere",), + 0x8017FAA8:("Math3D_YZInSphere",), 0x8017FB1C:("func_8017FB1C",), 0x8017FD44:("func_8017FD44",), 0x8017FEB0:("Math_GetAtan2Tbl",), @@ -3354,49 +3354,49 @@ 0x801800CC:("Math_Atan2F",), 0x80180100:("Math_FAtan2F",), 0x8018012C:("Math_Acot2F",), - 0x80180160:("Matrix_StateAlloc",), - 0x8018019C:("Matrix_StatePush",), - 0x801801CC:("Matrix_StatePop",), - 0x801801E8:("Matrix_CopyCurrentState",), - 0x8018020C:("Matrix_SetCurrentState",), - 0x80180234:("Matrix_GetCurrentState",), - 0x80180244:("Matrix_InsertMatrix",), - 0x8018029C:("Matrix_InsertTranslation",), + 0x80180160:("Matrix_Init",), + 0x8018019C:("Matrix_Push",), + 0x801801CC:("Matrix_Pop",), + 0x801801E8:("Matrix_Get",), + 0x8018020C:("Matrix_Put",), + 0x80180234:("Matrix_GetCurrent",), + 0x80180244:("Matrix_Mult",), + 0x8018029C:("Matrix_Translate",), 0x8018039C:("Matrix_Scale",), - 0x80180478:("Matrix_InsertXRotation_s",), - 0x80180610:("Matrix_InsertXRotation_f",), - 0x801807B8:("Matrix_RotateStateAroundXAxis",), - 0x80180900:("Matrix_SetStateXRotation",), - 0x801809AC:("Matrix_RotateY",), - 0x80180B48:("Matrix_InsertYRotation_f",), - 0x80180CF8:("Matrix_InsertZRotation_s",), - 0x80180E90:("Matrix_InsertZRotation_f",), - 0x8018103C:("Matrix_InsertRotation",), - 0x801812FC:("Matrix_JointPosition",), - 0x80181650:("Matrix_SetStateRotationAndTranslation",), - 0x801817FC:("Matrix_ToRSPMatrix",), + 0x80180478:("Matrix_RotateXS",), + 0x80180610:("Matrix_RotateXF",), + 0x801807B8:("Matrix_RotateXFApply",), + 0x80180900:("Matrix_RotateXFNew",), + 0x801809AC:("Matrix_RotateYS",), + 0x80180B48:("Matrix_RotateYF",), + 0x80180CF8:("Matrix_RotateZS",), + 0x80180E90:("Matrix_RotateZF",), + 0x8018103C:("Matrix_RotateZYX",), + 0x801812FC:("Matrix_TranslateRotateZYX",), + 0x80181650:("Matrix_SetTranslateRotateYXZ",), + 0x801817FC:("Matrix_MtxFToMtx",), 0x80181A18:("Matrix_ToMtx",), 0x80181A40:("Matrix_NewMtx",), - 0x80181A6C:("Matrix_AppendToPolyOpaDisp",), - 0x80181A98:("Matrix_MultiplyVector3fByState",), - 0x80181B50:("Matrix_GetStateTranslation",), - 0x80181B78:("Matrix_GetStateTranslationAndScaledX",), - 0x80181BC4:("Matrix_GetStateTranslationAndScaledY",), - 0x80181C10:("Matrix_GetStateTranslationAndScaledZ",), - 0x80181C5C:("Matrix_MultiplyVector3fXZByCurrentState",), + 0x80181A6C:("Matrix_MtxFToNewMtx",), + 0x80181A98:("Matrix_MultVec3f",), + 0x80181B50:("Matrix_MultZero",), + 0x80181B78:("Matrix_MultVecX",), + 0x80181BC4:("Matrix_MultVecY",), + 0x80181C10:("Matrix_MultVecZ",), + 0x80181C5C:("Matrix_MultVec3fXZ",), 0x80181CDC:("Matrix_MtxFCopy",), - 0x80181D64:("Matrix_FromRSPMatrix",), - 0x80181FB8:("Matrix_MultiplyVector3fByMatrix",), - 0x80182068:("Matrix_TransposeXYZ",), - 0x801820A0:("Matrix_NormalizeXYZ",), - 0x8018219C:("func_8018219C",), - 0x801822C4:("func_801822C4",), - 0x801823EC:("Matrix_InsertRotationAroundUnitVector_f",), - 0x8018284C:("Matrix_InsertRotationAroundUnitVector_s",), - 0x80182C90:("func_80182C90",), - 0x80182CA0:("func_80182CA0",), - 0x80182CBC:("func_80182CBC",), - 0x80182CCC:("func_80182CCC",), + 0x80181D64:("Matrix_MtxToMtxF",), + 0x80181FB8:("Matrix_MultVec3fExt",), + 0x80182068:("Matrix_Transpose",), + 0x801820A0:("Matrix_ReplaceRotation",), + 0x8018219C:("Matrix_MtxFToYXZRot",), + 0x801822C4:("Matrix_MtxFToZYXRot",), + 0x801823EC:("Matrix_RotateAxisF",), + 0x8018284C:("Matrix_RotateAxisS",), + 0x80182C90:("SysUcode_GetUCodeBoot",), + 0x80182CA0:("SysUcode_GetUCodeBootSize",), + 0x80182CBC:("SysUcode_GetUCode",), + 0x80182CCC:("SysUcode_GetUCodeData",), 0x80182CE0:("func_80182CE0",), 0x80183020:("func_80183020",), 0x80183058:("func_80183058",), @@ -3463,25 +3463,21 @@ 0x80185F04:("func_80185F04",), 0x80185F64:("func_80185F64",), 0x80185F90:("func_80185F90",), - 0x80186A70:("func_80186A70",), - 0x80186AB8:("func_80186AB8",), - 0x80186B28:("func_80186B28",), - 0x80186B30:("func_80186B30",), - 0x80186B38:("func_80186B38",), - 0x80186B68:("func_80186B68",), - 0x80186B70:("func_80186B70",), - 0x80186B78:("func_80186B78",), - 0x80186CAC:("func_80186CAC",), - 0x80186D60:("func_80186D60",), - 0x80186E64:("func_80186E64",), - 0x80186EC8:("func_80186EC8",), - 0x80187018:("func_80187018",), - 0x80187080:("func_80187080",), - 0x80187124:("func_80187124",), - 0x80187284:("func_80187284",), - 0x801872FC:("func_801872FC",), - 0x801873BC:("func_801873BC",), - 0x8018752C:("func_8018752C",), + 0x80186A70:("osFlashGetAddr",), + 0x80186AB8:("osFlashReInit",), + 0x80186B38:("osFlashChange",), + 0x80186B78:("osFlashInit",), + 0x80186CAC:("osFlashReadStatus",), + 0x80186D60:("osFlashReadId",), + 0x80186E64:("osFlashClearStatus",), + 0x80186EC8:("osFlashAllErase",), + 0x80187018:("osFlashAllEraseThrough",), + 0x80187080:("osFlashCheckEraseEnd",), + 0x80187124:("osFlashSectorErase",), + 0x80187284:("osFlashSectorEraseThrough",), + 0x801872FC:("osFlashWriteBuffer",), + 0x801873BC:("osFlashWriteArray",), + 0x8018752C:("osFlashReadArray",), 0x801877D0:("func_801877D0",), 0x80187B64:("func_80187B64",), 0x80187BEC:("func_80187BEC",), @@ -3552,138 +3548,138 @@ 0x8018AE34:("func_8018AE34",), 0x8018B0F0:("func_8018B0F0",), 0x8018B10C:("func_8018B10C",), - 0x8018B250:("func_8018B250",), - 0x8018B318:("func_8018B318",), - 0x8018B3FC:("func_8018B3FC",), - 0x8018B474:("func_8018B474",), - 0x8018B4F8:("func_8018B4F8",), - 0x8018B520:("func_8018B520",), - 0x8018B578:("func_8018B578",), - 0x8018B5D0:("func_8018B5D0",), - 0x8018B608:("func_8018B608",), - 0x8018B640:("func_8018B640",), - 0x8018B69C:("func_8018B69C",), - 0x8018B6E8:("func_8018B6E8",), - 0x8018B740:("func_8018B740",), - 0x8018B768:("func_8018B768",), - 0x8018B77C:("func_8018B77C",), - 0x8018B7AC:("func_8018B7AC",), - 0x8018B7BC:("func_8018B7BC",), - 0x8018B8FC:("func_8018B8FC",), - 0x8018B95C:("func_8018B95C",), - 0x8018B9E0:("func_8018B9E0",), - 0x8018BA64:("func_8018BA64",), - 0x8018BB28:("func_8018BB28",), - 0x8018BBEC:("func_8018BBEC",), - 0x8018C380:("func_8018C380",), - 0x8018C3D8:("func_8018C3D8",), + 0x8018B250:("AudioHeap_ResetLoadStatus",), + 0x8018B318:("AudioHeap_DiscardFont",), + 0x8018B3FC:("AudioHeap_ReleaseNotesForFont",), + 0x8018B474:("AudioHeap_DiscardSequence",), + 0x8018B4F8:("AudioHeap_WritebackDCache",), + 0x8018B520:("AudioHeap_AllocZeroedAttemptExternal",), + 0x8018B578:("AudioHeap_AllocAttemptExternal",), + 0x8018B5D0:("AudioHeap_AllocDmaMemory",), + 0x8018B608:("AudioHeap_AllocDmaMemoryZeroed",), + 0x8018B640:("AudioHeap_AllocZeroed",), + 0x8018B69C:("AudioHeap_TestAlloc",), + 0x8018B6E8:("AudioHeap_Alloc",), + 0x8018B740:("AudioHeap_AllocPoolInit",), + 0x8018B768:("AudioHeap_ClearPersistentCache",), + 0x8018B77C:("AudioHeap_ClearTemporaryCache",), + 0x8018B7AC:("AudioHeap_ResetPool",), + 0x8018B7BC:("AudioHeap_PopCache",), + 0x8018B8FC:("AudioHeap_InitMainPool",), + 0x8018B95C:("AudioHeap_InitSessionPool",), + 0x8018B9E0:("AudioHeap_InitCachePool",), + 0x8018BA64:("AudioHeap_InitPersistentCache",), + 0x8018BB28:("AudioHeap_InitTemporaryCache",), + 0x8018BBEC:("AudioHeap_AllocCached",), + 0x8018C380:("AudioHeap_SearchCaches",), + 0x8018C3D8:("AudioHeap_SearchRegularCaches",), 0x8018C4E4:("func_8018C4E4",), - 0x8018C8B8:("func_8018C8B8",), - 0x8018C8E8:("func_8018C8E8",), - 0x8018C93C:("func_8018C93C",), - 0x8018C994:("func_8018C994",), - 0x8018CB70:("func_8018CB70",), - 0x8018CB78:("func_8018CB78",), - 0x8018CC3C:("func_8018CC3C",), - 0x8018CCA8:("func_8018CCA8",), - 0x8018CFAC:("func_8018CFAC",), - 0x8018D57C:("func_8018D57C",), - 0x8018D5D4:("func_8018D5D4",), - 0x8018D658:("func_8018D658",), - 0x8018D6C8:("func_8018D6C8",), - 0x8018D760:("func_8018D760",), - 0x8018DA50:("func_8018DA50",), - 0x8018DBC4:("func_8018DBC4",), - 0x8018DCB4:("func_8018DCB4",), - 0x8018DCF8:("func_8018DCF8",), - 0x8018DD98:("func_8018DD98",), - 0x8018DDD4:("func_8018DDD4",), - 0x8018DF24:("func_8018DF24",), - 0x8018DFE0:("func_8018DFE0",), - 0x8018E00C:("func_8018E00C",), - 0x8018E03C:("func_8018E03C",), - 0x8018E2A8:("func_8018E2A8",), - 0x8018E344:("func_8018E344",), - 0x8018E8C8:("func_8018E8C8",), - 0x8018EB60:("func_8018EB60",), - 0x8018EC4C:("func_8018EC4C",), - 0x8018EF88:("func_8018EF88",), - 0x8018F220:("func_8018F220",), - 0x8018F298:("func_8018F298",), - 0x8018F310:("func_8018F310",), - 0x8018F388:("func_8018F388",), - 0x8018F3B8:("func_8018F3B8",), - 0x8018F3E8:("func_8018F3E8",), - 0x8018F448:("func_8018F448",), - 0x8018F478:("func_8018F478",), - 0x8018F4D8:("func_8018F4D8",), - 0x8018F588:("func_8018F588",), - 0x8018F604:("func_8018F604",), - 0x8018F6F0:("func_8018F6F0",), - 0x8018F7C0:("func_8018F7C0",), - 0x8018F7F8:("func_8018F7F8",), - 0x8018F83C:("func_8018F83C",), - 0x8018F880:("func_8018F880",), - 0x8018F8C4:("func_8018F8C4",), - 0x8018F908:("func_8018F908",), - 0x8018F9B8:("func_8018F9B8",), + 0x8018C8B8:("AudioHeap_ClearFilter",), + 0x8018C8E8:("AudioHeap_LoadLowPassFilter",), + 0x8018C93C:("AudioHeap_LoadHighPassFilter",), + 0x8018C994:("AudioHeap_LoadFilter",), + 0x8018CB70:("AudioHeap_UpdateReverb",), + 0x8018CB78:("AudioHeap_UpdateReverbs",), + 0x8018CC3C:("AudioHeap_ClearAiBuffers",), + 0x8018CCA8:("AudioHeap_ResetStep",), + 0x8018CFAC:("AudioHeap_Init",), + 0x8018D57C:("AudioHeap_SearchPermanentCache",), + 0x8018D5D4:("AudioHeap_AllocPermanent",), + 0x8018D658:("AudioHeap_AllocSampleCache",), + 0x8018D6C8:("AudioHeap_InitSampleCaches",), + 0x8018D760:("AudioHeap_AllocTemporarySampleCacheEntry",), + 0x8018DA50:("AudioHeap_UnapplySampleCacheForFont",), + 0x8018DBC4:("AudioHeap_DiscardSampleCacheEntry",), + 0x8018DCB4:("AudioHeap_UnapplySampleCache",), + 0x8018DCF8:("AudioHeap_AllocPersistentSampleCacheEntry",), + 0x8018DD98:("AudioHeap_DiscardSampleCacheForFont",), + 0x8018DDD4:("AudioHeap_DiscardSampleCaches",), + 0x8018DF24:("AudioHeap_ChangeStorage",), + 0x8018DFE0:("AudioHeap_DiscardSampleBank",), + 0x8018E00C:("AudioHeap_ApplySampleBankCache",), + 0x8018E03C:("AudioHeap_ApplySampleBankCacheInternal",), + 0x8018E2A8:("AudioHeap_DiscardSampleBanks",), + 0x8018E344:("AudioHeap_SetReverbData",), + 0x8018E8C8:("AudioHeap_InitReverb",), + 0x8018EB60:("AudioLoad_DecreaseSampleDmaTtls",), + 0x8018EC4C:("AudioLoad_DmaSampleData",), + 0x8018EF88:("AudioLoad_InitSampleDmaBuffers",), + 0x8018F220:("AudioLoad_IsFontLoadComplete",), + 0x8018F298:("AudioLoad_IsSeqLoadComplete",), + 0x8018F310:("AudioLoad_IsSampleLoadComplete",), + 0x8018F388:("AudioLoad_SetFontLoadStatus",), + 0x8018F3B8:("AudioLoad_SetSeqLoadStatus",), + 0x8018F3E8:("AudioLoad_SetSampleFontLoadStatusAndApplyCaches",), + 0x8018F448:("AudioLoad_SetSampleFontLoadStatus",), + 0x8018F478:("AudioLoad_InitTable",), + 0x8018F4D8:("AudioLoad_SyncLoadSeqFonts",), + 0x8018F588:("AudioLoad_SyncLoadSeqParts",), + 0x8018F604:("AudioLoad_SyncLoadSample",), + 0x8018F6F0:("AudioLoad_SyncLoadInstrument",), + 0x8018F7C0:("AudioLoad_AsyncLoad",), + 0x8018F7F8:("AudioLoad_AsyncLoadSeq",), + 0x8018F83C:("AudioLoad_AsyncLoadSampleBank",), + 0x8018F880:("AudioLoad_AsyncLoadFont",), + 0x8018F8C4:("AudioLoad_GetFontsForSequence",), + 0x8018F908:("AudioLoad_DiscardSeqFonts",), + 0x8018F9B8:("AudioLoad_DiscardFont",), 0x8018FA60:("func_8018FA60",), - 0x8018FAD0:("func_8018FAD0",), - 0x8018FB20:("func_8018FB20",), - 0x8018FB78:("func_8018FB78",), - 0x8018FCCC:("func_8018FCCC",), - 0x8018FD20:("func_8018FD20",), - 0x8018FD40:("func_8018FD40",), - 0x8018FE5C:("func_8018FE5C",), - 0x8018FF60:("func_8018FF60",), - 0x80190204:("func_80190204",), - 0x80190240:("func_80190240",), - 0x80190294:("func_80190294",), - 0x801902D8:("func_801902D8",), - 0x80190544:("func_80190544",), - 0x80190668:("func_80190668",), - 0x8019067C:("func_8019067C",), - 0x80190754:("func_80190754",), - 0x8019075C:("func_8019075C",), - 0x8019077C:("func_8019077C",), - 0x80190B08:("func_80190B08",), - 0x80190B38:("func_80190B38",), - 0x80190B44:("func_80190B44",), - 0x80190B50:("func_80190B50",), - 0x80190BB0:("func_80190BB0",), - 0x80190F50:("func_80190F50",), - 0x80190F64:("func_80190F64",), - 0x80191134:("func_80191134",), - 0x801911C4:("func_801911C4",), - 0x801911CC:("func_801911CC",), - 0x80191240:("func_80191240",), - 0x801913C8:("func_801913C8",), - 0x8019144C:("func_8019144C",), - 0x80191460:("func_80191460",), - 0x80191568:("func_80191568",), - 0x80191598:("func_80191598",), - 0x8019161C:("func_8019161C",), - 0x80191740:("func_80191740",), - 0x80191864:("func_80191864",), - 0x80191870:("func_80191870",), - 0x801919AC:("func_801919AC",), - 0x80191B40:("func_80191B40",), - 0x80191BD0:("func_80191BD0",), - 0x80191C40:("func_80191C40",), - 0x80191C54:("func_80191C54",), - 0x80191D94:("func_80191D94",), - 0x8019218C:("func_8019218C",), - 0x80192340:("func_80192340",), - 0x80192388:("func_80192388",), - 0x801924BC:("func_801924BC",), - 0x80192514:("func_80192514",), - 0x80192990:("func_80192990",), - 0x80192AD0:("func_80192AD0",), - 0x80192AD8:("func_80192AD8",), - 0x80192AE0:("func_80192AE0",), - 0x80192AE8:("func_80192AE8",), - 0x80192B54:("func_80192B54",), - 0x80192BAC:("func_80192BAC",), + 0x8018FAD0:("AudioLoad_SyncInitSeqPlayer",), + 0x8018FB20:("AudioLoad_SyncInitSeqPlayerSkipTicks",), + 0x8018FB78:("AudioLoad_SyncInitSeqPlayerInternal",), + 0x8018FCCC:("AudioLoad_SyncLoadSeq",), + 0x8018FD20:("AudioLoad_GetSampleBank",), + 0x8018FD40:("AudioLoad_TrySyncLoadSampleBank",), + 0x8018FE5C:("AudioLoad_SyncLoadFont",), + 0x8018FF60:("AudioLoad_SyncLoad",), + 0x80190204:("AudioLoad_GetRealTableIndex",), + 0x80190240:("AudioLoad_SearchCaches",), + 0x80190294:("AudioLoad_GetLoadTable",), + 0x801902D8:("AudioLoad_RelocateFont",), + 0x80190544:("AudioLoad_SyncDma",), + 0x80190668:("AudioLoad_SyncDmaUnkMedium",), + 0x8019067C:("AudioLoad_Dma",), + 0x80190754:("AudioLoad_Unused1",), + 0x8019075C:("AudioLoad_SyncLoadSimple",), + 0x8019077C:("AudioLoad_AsyncLoadInner",), + 0x80190B08:("AudioLoad_ProcessLoads",), + 0x80190B38:("AudioLoad_SetDmaHandler",), + 0x80190B44:("AudioLoad_SetUnusedHandler",), + 0x80190B50:("AudioLoad_InitSoundFontMeta",), + 0x80190BB0:("AudioLoad_Init",), + 0x80190F50:("AudioLoad_InitSlowLoads",), + 0x80190F64:("AudioLoad_SlowLoadSample",), + 0x80191134:("AudioLoad_GetFontSample",), + 0x801911C4:("AudioLoad_Unused2",), + 0x801911CC:("AudioLoad_FinishSlowLoad",), + 0x80191240:("AudioLoad_ProcessSlowLoads",), + 0x801913C8:("AudioLoad_DmaSlowCopy",), + 0x8019144C:("AudioLoad_DmaSlowCopyUnkMedium",), + 0x80191460:("AudioLoad_SlowLoadSeq",), + 0x80191568:("AudioLoad_InitAsyncLoads",), + 0x80191598:("AudioLoad_StartAsyncLoadUnkMedium",), + 0x8019161C:("AudioLoad_StartAsyncLoad",), + 0x80191740:("AudioLoad_ProcessAsyncLoads",), + 0x80191864:("AudioLoad_ProcessAsyncLoadUnkMedium",), + 0x80191870:("AudioLoad_FinishAsyncLoad",), + 0x801919AC:("AudioLoad_ProcessAsyncLoad",), + 0x80191B40:("AudioLoad_AsyncDma",), + 0x80191BD0:("AudioLoad_AsyncDmaRamUnloaded",), + 0x80191C40:("AudioLoad_AsyncDmaUnkMedium",), + 0x80191C54:("AudioLoad_RelocateSample",), + 0x80191D94:("AudioLoad_RelocateFontAndPreloadSamples",), + 0x8019218C:("AudioLoad_ProcessSamplePreloads",), + 0x80192340:("AudioLoad_AddToSampleSet",), + 0x80192388:("AudioLoad_GetSamplesForFont",), + 0x801924BC:("AudioLoad_AddUsedSample",), + 0x80192514:("AudioLoad_PreloadSamplesForFont",), + 0x80192990:("AudioLoad_LoadPermanentSamples",), + 0x80192AD0:("AudioLoad_Unused3",), + 0x80192AD8:("AudioLoad_Unused4",), + 0x80192AE0:("AudioLoad_Unused5",), + 0x80192AE8:("AudioLoad_ScriptLoad",), + 0x80192B54:("AudioLoad_ProcessScriptLoads",), + 0x80192BAC:("AudioLoad_InitScriptLoads",), 0x80192BE0:("func_80192BE0",), 0x80192C00:("func_80192C00",), 0x8019319C:("func_8019319C",), @@ -3693,7 +3689,7 @@ 0x8019380C:("func_8019380C",), 0x80193858:("func_80193858",), 0x8019387C:("func_8019387C",), - 0x801938A0:("func_801938A0",), + 0x801938A0:("Audio_QueueCmdS8",), 0x801938D0:("func_801938D0",), 0x80193900:("func_80193900",), 0x80193990:("func_80193990",), @@ -3722,69 +3718,69 @@ 0x80194528:("func_80194528",), 0x80194548:("func_80194548",), 0x80194568:("func_80194568",), - 0x80194668:("func_80194668",), - 0x801946E4:("func_801946E4",), - 0x80194710:("func_80194710",), - 0x80194750:("func_80194750",), + 0x80194668:("Audio_NextRandom",), + 0x801946E4:("Audio_InitMesgQueues",), + 0x80194710:("Audio_InvalDCache",), + 0x80194750:("Audio_WritebackDCache",), 0x80194790:("func_80194790",), 0x80194804:("func_80194804",), 0x80194840:("func_80194840",), 0x801948B0:("func_801948B0",), - 0x80194930:("func_80194930",), - 0x80194DB0:("func_80194DB0",), - 0x80194E60:("func_80194E60",), - 0x80194F20:("func_80194F20",), - 0x80194F84:("func_80194F84",), - 0x801954CC:("func_801954CC",), - 0x80195508:("func_80195508",), - 0x801955DC:("func_801955DC",), - 0x801956C0:("func_801956C0",), - 0x801957B4:("func_801957B4",), - 0x801958F8:("func_801958F8",), - 0x80195C40:("func_80195C40",), - 0x80195C60:("func_80195C60",), - 0x80195C80:("func_80195C80",), - 0x80195D84:("func_80195D84",), - 0x80195DDC:("func_80195DDC",), - 0x80195DEC:("func_80195DEC",), - 0x80195E3C:("func_80195E3C",), - 0x80195EE0:("func_80195EE0",), - 0x80196040:("func_80196040",), - 0x8019617C:("func_8019617C",), - 0x801961BC:("func_801961BC",), - 0x801961E8:("func_801961E8",), - 0x80196268:("func_80196268",), + 0x80194930:("AudioPlayback_InitNoteSub",), + 0x80194DB0:("AudioPlayback_NoteSetResamplingRate",), + 0x80194E60:("AudioPlayback_NoteInit",), + 0x80194F20:("AudioPlayback_NoteDisable",), + 0x80194F84:("AudioPlayback_ProcessNotes",), + 0x801954CC:("AudioPlayback_InstrumentGetSound",), + 0x80195508:("AudioPlayback_GetInstrumentInner",), + 0x801955DC:("AudioPlayback_GetDrum",), + 0x801956C0:("AudioPlayback_GetSfx",), + 0x801957B4:("AudioPlayback_SetFontInstrument",), + 0x801958F8:("AudioPlayback_SeqLayerDecayRelease",), + 0x80195C40:("AudioPlayback_SeqLayerNoteDecay",), + 0x80195C60:("AudioPlayback_SeqLayerNoteRelease",), + 0x80195C80:("AudioPlayback_BuildSyntheticWave",), + 0x80195D84:("AudioPlayback_InitSyntheticWave",), + 0x80195DDC:("AudioPlayback_InitNoteList",), + 0x80195DEC:("AudioPlayback_InitNoteLists",), + 0x80195E3C:("AudioPlayback_InitNoteFreeList",), + 0x80195EE0:("AudioPlayback_NotePoolClear",), + 0x80196040:("AudioPlayback_NotePoolFill",), + 0x8019617C:("AudioPlayback_AudioListPushFront",), + 0x801961BC:("AudioPlayback_AudioListRemove",), + 0x801961E8:("AudioPlayback_FindNodeWithPrioLessThan",), + 0x80196268:("AudioPlayback_NoteInitForLayer",), 0x801963E8:("func_801963E8",), - 0x8019641C:("func_8019641C",), - 0x80196448:("func_80196448",), - 0x80196494:("func_80196494",), - 0x801964F8:("func_801964F8",), - 0x801965F0:("func_801965F0",), - 0x801968C4:("func_801968C4",), - 0x80196A00:("func_80196A00",), - 0x80196BC8:("func_80196BC8",), - 0x80196D20:("func_80196D20",), - 0x80196D7C:("func_80196D7C",), - 0x80196DB4:("func_80196DB4",), - 0x80196FEC:("func_80196FEC",), - 0x80197048:("func_80197048",), - 0x80197138:("func_80197138",), - 0x80197164:("func_80197164",), - 0x80197188:("func_80197188",), + 0x8019641C:("AudioPlayback_NoteReleaseAndTakeOwnership",), + 0x80196448:("AudioPlayback_AllocNoteFromDisabled",), + 0x80196494:("AudioPlayback_AllocNoteFromDecaying",), + 0x801964F8:("AudioPlayback_AllocNoteFromActive",), + 0x801965F0:("AudioPlayback_AllocNote",), + 0x801968C4:("AudioPlayback_NoteInitAll",), + 0x80196A00:("AudioEffects_SequenceChannelProcessSound",), + 0x80196BC8:("AudioEffects_SequencePlayerProcessSound",), + 0x80196D20:("AudioEffects_GetPortamentoFreqScale",), + 0x80196D7C:("AudioEffects_GetVibratoPitchChange",), + 0x80196DB4:("AudioEffects_GetVibratoFreqScale",), + 0x80196FEC:("AudioEffects_NoteVibratoUpdate",), + 0x80197048:("AudioEffects_NoteVibratoInit",), + 0x80197138:("AudioEffects_NotePortamentoInit",), + 0x80197164:("AudioEffects_AdsrInit",), + 0x80197188:("AudioEffects_AdsrUpdate",), 0x801974D0:("func_801974D0",), 0x80197538:("func_80197538",), 0x80197714:("func_80197714",), 0x80197880:("func_80197880",), 0x801979D8:("func_801979D8",), 0x80197A54:("func_80197A54",), - 0x80197AA4:("func_80197AA4",), + 0x80197AA4:("AudioSeq_SequenceChannelDisable",), 0x80197B14:("func_80197B14",), 0x80197C0C:("func_80197C0C",), 0x80197C8C:("func_80197C8C",), - 0x80197D24:("func_80197D24",), - 0x80197D4C:("func_80197D4C",), - 0x80197E08:("func_80197E08",), - 0x80197E48:("func_80197E48",), + 0x80197D24:("AudioSeq_SequencePlayerDisableAsFinished",), + 0x80197D4C:("AudioSeq_SequencePlayerDisable",), + 0x80197E08:("AudioSeq_AudioListPushBack",), + 0x80197E48:("AudioSeq_AudioListPopBack",), 0x80197E88:("func_80197E88",), 0x80197F28:("func_80197F28",), 0x80197F3C:("func_80197F3C",), @@ -3803,23 +3799,23 @@ 0x8019A0BC:("func_8019A0BC",), 0x8019AA3C:("func_8019AA3C",), 0x8019AAF0:("func_8019AAF0",), - 0x8019AB40:("func_8019AB40",), - 0x8019AC10:("func_8019AC10",), + 0x8019AB40:("AudioSeq_ResetSequencePlayer",), + 0x8019AC10:("AudioSeq_InitSequencePlayerChannels",), 0x8019ACEC:("func_8019ACEC",), - 0x8019ADBC:("func_8019ADBC",), + 0x8019ADBC:("AudioSeq_InitSequencePlayers",), 0x8019AE40:("func_8019AE40",), 0x8019AEC0:("func_8019AEC0",), 0x8019AF00:("func_8019AF00",), 0x8019AF58:("func_8019AF58",), 0x8019AFE8:("func_8019AFE8",), 0x8019B02C:("func_8019B02C",), - 0x8019B074:("func_8019B074",), + 0x8019B074:("AudioOcarina_MapSongFromNotesToButtons",), 0x8019B144:("func_8019B144",), 0x8019B378:("func_8019B378",), 0x8019B38C:("func_8019B38C",), 0x8019B3D0:("func_8019B3D0",), 0x8019B4B8:("func_8019B4B8",), - 0x8019B544:("func_8019B544",), + 0x8019B544:("AudioOcarina_StartDefault",), 0x8019B568:("func_8019B568",), 0x8019B5AC:("func_8019B5AC",), 0x8019B5EC:("func_8019B5EC",), @@ -3832,7 +3828,7 @@ 0x8019C1D0:("func_8019C1D0",), 0x8019C268:("func_8019C268",), 0x8019C2E4:("func_8019C2E4",), - 0x8019C300:("func_8019C300",), + 0x8019C300:("AudioOcarina_SetInstrumentId",), 0x8019C398:("func_8019C398",), 0x8019C5A0:("func_8019C5A0",), 0x8019C8D8:("func_8019C8D8",), @@ -3842,12 +3838,12 @@ 0x8019CEBC:("func_8019CEBC",), 0x8019CF6C:("func_8019CF6C",), 0x8019CF78:("func_8019CF78",), - 0x8019CF9C:("func_8019CF9C",), + 0x8019CF9C:("AudioOcarina_GetPlaybackStaff",), 0x8019CFA8:("func_8019CFA8",), - 0x8019D134:("func_8019D134",), - 0x8019D26C:("func_8019D26C",), - 0x8019D488:("func_8019D488",), - 0x8019D4F8:("func_8019D4F8",), + 0x8019D134:("AudioOcarina_TerminaWallValidateNotes",), + 0x8019D26C:("AudioOcarina_TerminaWallGenerateNotes",), + 0x8019D488:("AudioOcarina_MemoryGameSetNumNotes",), + 0x8019D4F8:("AudioOcarina_MemoryGameGenerateNotes",), 0x8019D600:("func_8019D600",), 0x8019D758:("func_8019D758",), 0x8019D864:("func_8019D864",), @@ -3874,7 +3870,7 @@ 0x8019F0C8:("play_sound",), 0x8019F128:("func_8019F128",), 0x8019F170:("func_8019F170",), - 0x8019F1C0:("func_8019F1C0",), + 0x8019F1C0:("Audio_PlaySfxAtPos",), 0x8019F208:("func_8019F208",), 0x8019F230:("func_8019F230",), 0x8019F258:("func_8019F258",), @@ -3901,18 +3897,18 @@ 0x8019FE74:("func_8019FE74",), 0x8019FEDC:("func_8019FEDC",), 0x8019FF38:("func_8019FF38",), - 0x8019FF9C:("func_8019FF9C",), - 0x801A0048:("func_801A0048",), - 0x801A00EC:("func_801A00EC",), + 0x8019FF9C:("Audio_PlaySfxForRiver",), + 0x801A0048:("Audio_PlaySfxForWaterfall",), + 0x801A00EC:("Audio_StepFreqLerp",), 0x801A0124:("func_801A0124",), 0x801A0184:("func_801A0184",), 0x801A01C4:("func_801A01C4",), 0x801A0204:("func_801A0204",), 0x801A0238:("func_801A0238",), - 0x801A026C:("func_801A026C",), - 0x801A0318:("func_801A0318",), - 0x801A0450:("func_801A0450",), - 0x801A046C:("func_801A046C",), + 0x801A026C:("Audio_SetGanonsTowerBgmVolumeLevel",), + 0x801A0318:("Audio_SetGanonsTowerBgmVolume",), + 0x801A0450:("Audio_LowerMainBgmVolume",), + 0x801A046C:("Audio_UpdateRiverSoundVolumes",), 0x801A0554:("func_801A0554",), 0x801A05E4:("func_801A05E4",), 0x801A05F0:("func_801A05F0",), @@ -3920,9 +3916,9 @@ 0x801A0810:("func_801A0810",), 0x801A0868:("func_801A0868",), 0x801A09D4:("func_801A09D4",), - 0x801A0C70:("func_801A0C70",), - 0x801A0C90:("func_801A0C90",), - 0x801A0CB0:("func_801A0CB0",), + 0x801A0C70:("Audio_ClearSariaBgm",), + 0x801A0C90:("Audio_ClearSariaBgmAtPos",), + 0x801A0CB0:("Audio_SplitBgmChannels",), 0x801A0E44:("func_801A0E44",), 0x801A1290:("func_801A1290",), 0x801A1348:("func_801A1348",), @@ -3939,8 +3935,8 @@ 0x801A1F88:("func_801A1F88",), 0x801A1FB4:("func_801A1FB4",), 0x801A2090:("func_801A2090",), - 0x801A21FC:("func_801A21FC",), - 0x801A2460:("func_801A2460",), + 0x801A21FC:("Audio_PlaySariaBgm",), + 0x801A2460:("Audio_ClearSariaBgm2",), 0x801A246C:("func_801A246C",), 0x801A2544:("func_801A2544",), 0x801A257C:("func_801A257C",), @@ -3955,7 +3951,7 @@ 0x801A2C44:("func_801A2C44",), 0x801A2C88:("func_801A2C88",), 0x801A2D54:("func_801A2D54",), - 0x801A2DE0:("func_801A2DE0",), + 0x801A2DE0:("Audio_IsSequencePlaying",), 0x801A2E54:("func_801A2E54",), 0x801A2ED8:("func_801A2ED8",), 0x801A2F88:("func_801A2F88",), @@ -3982,7 +3978,7 @@ 0x801A3D98:("func_801A3D98",), 0x801A3E38:("func_801A3E38",), 0x801A3EC0:("func_801A3EC0",), - 0x801A3F54:("func_801A3F54",), + 0x801A3F54:("Audio_SetCutsceneFlag",), 0x801A3F6C:("func_801A3F6C",), 0x801A3FB4:("func_801A3FB4",), 0x801A3FFC:("func_801A3FFC",), @@ -4037,7 +4033,7 @@ 0x801A5BD0:("func_801A5BD0",), 0x801A5C28:("func_801A5C28",), 0x801A5C8C:("func_801A5C8C",), - 0x801A5CFC:("func_801A5CFC",), + 0x801A5CFC:("Audio_PlaySfxGeneral",), 0x801A5DDC:("func_801A5DDC",), 0x801A5F7C:("func_801A5F7C",), 0x801A6430:("func_801A6430",), @@ -4046,7 +4042,7 @@ 0x801A7084:("func_801A7084",), 0x801A7168:("func_801A7168",), 0x801A7284:("func_801A7284",), - 0x801A72CC:("func_801A72CC",), + 0x801A72CC:("Audio_StopSfxByPos",), 0x801A7328:("func_801A7328",), 0x801A7484:("func_801A7484",), 0x801A75E8:("func_801A75E8",), @@ -4054,7 +4050,7 @@ 0x801A7794:("func_801A7794",), 0x801A7828:("func_801A7828",), 0x801A787C:("func_801A787C",), - 0x801A78E4:("func_801A78E4",), + 0x801A78E4:("Audio_IsSfxPlaying",), 0x801A794C:("func_801A794C",), 0x801A7B10:("func_801A7B10",), 0x801A7D04:("func_801A7D04",), @@ -4065,24 +4061,24 @@ 0x801A8ABC:("func_801A8ABC",), 0x801A8B14:("func_801A8B14",), 0x801A8B2C:("func_801A8B2C",), - 0x801A8BD0:("func_801A8BD0",), + 0x801A8BD0:("Audio_SetVolumeScale",), 0x801A8D5C:("func_801A8D5C",), 0x801A9768:("func_801A9768",), 0x801A982C:("func_801A982C",), 0x801A99B8:("func_801A99B8",), 0x801A9A74:("func_801A9A74",), - 0x801A9B10:("func_801A9B10",), - 0x801A9B78:("func_801A9B78",), - 0x801A9BFC:("func_801A9BFC",), - 0x801A9C68:("func_801A9C68",), - 0x801A9D10:("func_801A9D10",), - 0x801A9DCC:("func_801A9DCC",), - 0x801A9EA4:("func_801A9EA4",), - 0x801A9F4C:("func_801A9F4C",), - 0x801AA020:("func_801AA020",), - 0x801AA248:("func_801AA248",), - 0x801AA3E4:("func_801AA3E4",), - 0x801AA520:("func_801AA520",), + 0x801A9B10:("JpegUtils_ProcessQuantizationTable",), + 0x801A9B78:("JpegUtils_ParseHuffmanCodesLengths",), + 0x801A9BFC:("JpegUtils_GetHuffmanCodes",), + 0x801A9C68:("JpegUtils_SetHuffmanTable",), + 0x801A9D10:("JpegUtils_ProcessHuffmanTableImpl",), + 0x801A9DCC:("JpegUtils_ProcessHuffmanTable",), + 0x801A9EA4:("JpegUtils_SetHuffmanTableOld",), + 0x801A9F4C:("JpegUtils_ProcessHuffmanTableImplOld",), + 0x801AA020:("JpegDecoder_Decode",), + 0x801AA248:("JpegDecoder_ProcessMcu",), + 0x801AA3E4:("JpegDecoder_ParseNextSymbol",), + 0x801AA520:("JpegDecoder_ReadBits",), 0x801AA610:("GameOver_Init",), 0x801AA624:("GameOver_FadeLights",), 0x801AA68C:("GameOver_Update",), @@ -4244,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",), @@ -4606,7 +4602,7 @@ 0x80841744:("func_80841744",), 0x8084182C:("func_8084182C",), 0x80841A50:("func_80841A50",), - 0x80841AC4:("func_80841AC4",), + 0x80841AC4:("Player_Init",), 0x80842510:("func_80842510",), 0x808425B4:("func_808425B4",), 0x808426F0:("func_808426F0",), @@ -4619,11 +4615,11 @@ 0x80844784:("func_80844784",), 0x80844D80:("func_80844D80",), 0x80844EF8:("func_80844EF8",), - 0x808460B8:("func_808460B8",), + 0x808460B8:("Player_Update",), 0x808463C0:("func_808463C0",), 0x80846460:("func_80846460",), - 0x80846528:("func_80846528",), - 0x808470D4:("func_808470D4",), + 0x80846528:("Player_Draw",), + 0x808470D4:("Player_Destroy",), 0x80847190:("func_80847190",), 0x8084748C:("func_8084748C",), 0x808475B4:("func_808475B4",), @@ -4897,7 +4893,7 @@ 0x80863188:("EnTest_Init",), 0x80863310:("EnTest_Destroy",), 0x8086333C:("EnTest_Update",), - 0x808634B8:("func_808634B8",), + 0x808634B8:("EnTest_OverrideKeyframeDraw",), 0x808636A8:("EnTest_Draw",), 0x80863870:("EnGirlA_SetupAction",), 0x8086387C:("EnGirlA_InitObjIndex",), @@ -4964,7 +4960,7 @@ 0x808670F0:("func_808670F0",), 0x80867144:("func_80867144",), 0x8086732C:("EnDoor_Update",), - 0x80867350:("func_80867350",), + 0x80867350:("EnDoor_OverrideLimbDraw",), 0x808674B0:("EnDoor_Draw",), 0x80867BD0:("func_80867BD0",), 0x80867BDC:("func_80867BDC",), @@ -4995,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",), @@ -5112,40 +5108,40 @@ 0x80872BC0:("func_80872BC0",), 0x80874810:("EnWallmas_Init",), 0x80874A28:("EnWallmas_Destroy",), - 0x80874A88:("func_80874A88",), - 0x80874B04:("func_80874B04",), - 0x80874B88:("func_80874B88",), - 0x80874BE4:("func_80874BE4",), - 0x80874D1C:("func_80874D1C",), - 0x80874DE8:("func_80874DE8",), - 0x80874F14:("func_80874F14",), - 0x80874FD8:("func_80874FD8",), - 0x80875014:("func_80875014",), - 0x80875054:("func_80875054",), - 0x808750B8:("func_808750B8",), - 0x80875108:("func_80875108",), - 0x808751C4:("func_808751C4",), - 0x8087520C:("func_8087520C",), - 0x80875248:("func_80875248",), - 0x808752CC:("func_808752CC",), - 0x808753F0:("func_808753F0",), - 0x80875484:("func_80875484",), - 0x80875518:("func_80875518",), - 0x8087556C:("func_8087556C",), - 0x808755A8:("func_808755A8",), - 0x80875638:("func_80875638",), - 0x808756AC:("func_808756AC",), - 0x8087571C:("func_8087571C",), - 0x808758C8:("func_808758C8",), - 0x80875910:("func_80875910",), - 0x8087596C:("func_8087596C",), - 0x808759B8:("func_808759B8",), - 0x80875A0C:("func_80875A0C",), - 0x80875A74:("func_80875A74",), + 0x80874A88:("EnWallmas_Freeze",), + 0x80874B04:("EnWallmas_ThawIfFrozen",), + 0x80874B88:("EnWallmas_TimerInit",), + 0x80874BE4:("EnWallmas_WaitToDrop",), + 0x80874D1C:("EnWallmas_SetupDrop",), + 0x80874DE8:("EnWallmas_Drop",), + 0x80874F14:("EnWallmas_SetupLand",), + 0x80874FD8:("EnWallmas_Land",), + 0x80875014:("EnWallmas_SetupStand",), + 0x80875054:("EnWallmas_Stand",), + 0x808750B8:("EnWallmas_SetupWalk",), + 0x80875108:("EnWallmas_Walk",), + 0x808751C4:("EnWallmas_SetupJumpToCeiling",), + 0x8087520C:("EnWallmas_JumpToCeiling",), + 0x80875248:("EnWallmas_SetupReturnToCeiling",), + 0x808752CC:("EnWallmas_ReturnToCeiling",), + 0x808753F0:("EnWallmas_SetupDamage",), + 0x80875484:("EnWallmas_Damage",), + 0x80875518:("EnWallmas_SetupCooldown",), + 0x8087556C:("EnWallmas_Cooldown",), + 0x808755A8:("EnWallmas_SetupDie",), + 0x80875638:("EnWallmas_Die",), + 0x808756AC:("EnWallmas_SetupTakePlayer",), + 0x8087571C:("EnWallmas_TakePlayer",), + 0x808758C8:("EnWallmas_ProximityOrSwitchInit",), + 0x80875910:("EnWallmas_WaitForProximity",), + 0x8087596C:("EnWallmas_WaitForSwitchFlag",), + 0x808759B8:("EnWallmas_SetupStun",), + 0x80875A0C:("EnWallmas_Stun",), + 0x80875A74:("EnWallmas_Update",), 0x80875CF4:("EnWallmas_Update",), - 0x80875F04:("func_80875F04",), - 0x808760A4:("func_808760A4",), - 0x80876118:("func_80876118",), + 0x80875F04:("EnWallmas_DrawShadow",), + 0x808760A4:("EnWallmas_OverrideLimbDraw",), + 0x80876118:("EnWallmas_PostLimbDraw",), 0x80876268:("EnWallmas_Draw",), 0x80876670:("EnDodongo_Init",), 0x808768D0:("EnDodongo_Destroy",), @@ -5210,82 +5206,82 @@ 0x8087AF48:("EnFirefly_OverrideLimbDraw",), 0x8087AF98:("EnFirefly_PostLimbDraw",), 0x8087B320:("EnFirefly_Draw",), - 0x8087B730:("func_8087B730",), - 0x8087B784:("func_8087B784",), + 0x8087B730:("EnHorse_RaceWaypointPos",), + 0x8087B784:("EnHorse_RotateToPoint",), 0x8087B7C0:("func_8087B7C0",), - 0x8087C0AC:("func_8087C0AC",), + 0x8087C0AC:("EnHorse_PlayWalkingSound",), 0x8087C178:("func_8087C178",), 0x8087C1C0:("func_8087C1C0",), - 0x8087C208:("func_8087C208",), + 0x8087C208:("EnHorse_SlopeSpeedMultiplier",), 0x8087C288:("func_8087C288",), 0x8087C2B8:("func_8087C2B8",), 0x8087C38C:("func_8087C38C",), - 0x8087C43C:("func_8087C43C",), - 0x8087C590:("func_8087C590",), - 0x8087C8B8:("func_8087C8B8",), - 0x8087C8D0:("func_8087C8D0",), - 0x8087C8E0:("func_8087C8E0",), - 0x8087C9D4:("func_8087C9D4",), - 0x8087C9EC:("func_8087C9EC",), + 0x8087C43C:("EnHorse_IdleAnimSounds",), + 0x8087C590:("EnHorse_Spawn",), + 0x8087C8B8:("EnHorse_ResetCutscene",), + 0x8087C8D0:("EnHorse_ResetRace",), + 0x8087C8E0:("EnHorse_PlayerCanMove",), + 0x8087C9D4:("EnHorse_ResetHorsebackArchery",), + 0x8087C9EC:("EnHorse_ClearDustFlags",), 0x8087C9F8:("func_8087C9F8",), 0x8087CA04:("func_8087CA04",), 0x8087CA14:("EnHorse_Init",), 0x8087D540:("func_8087D540",), 0x8087D69C:("EnHorse_Destroy",), - 0x8087D70C:("func_8087D70C",), - 0x8087D75C:("func_8087D75C",), - 0x8087D814:("func_8087D814",), - 0x8087D988:("func_8087D988",), - 0x8087DDEC:("func_8087DDEC",), - 0x8087DE28:("func_8087DE28",), - 0x8087DF64:("func_8087DF64",), - 0x8087E080:("func_8087E080",), - 0x8087E0A4:("func_8087E0A4",), - 0x8087E18C:("func_8087E18C",), - 0x8087E2A8:("func_8087E2A8",), - 0x8087E350:("func_8087E350",), - 0x8087E564:("func_8087E564",), - 0x8087E5B4:("func_8087E5B4",), - 0x8087E5D8:("func_8087E5D8",), - 0x8087E684:("func_8087E684",), - 0x8087E6D8:("func_8087E6D8",), - 0x8087E92C:("func_8087E92C",), - 0x8087E9D0:("func_8087E9D0",), - 0x8087EA1C:("func_8087EA1C",), - 0x8087EB54:("func_8087EB54",), - 0x8087EB78:("func_8087EB78",), - 0x8087EC20:("func_8087EC20",), - 0x8087EC78:("func_8087EC78",), - 0x8087ED10:("func_8087ED10",), - 0x8087EEC4:("func_8087EEC4",), - 0x8087F078:("func_8087F078",), - 0x8087F1FC:("func_8087F1FC",), - 0x8087F39C:("func_8087F39C",), - 0x8087F590:("func_8087F590",), - 0x8087F5B4:("func_8087F5B4",), - 0x8087F658:("func_8087F658",), - 0x8087F9A0:("func_8087F9A0",), - 0x8087F9C4:("func_8087F9C4",), - 0x8087FB08:("func_8087FB08",), - 0x8087FB14:("func_8087FB14",), - 0x8087FD94:("func_8087FD94",), - 0x8087FDB8:("func_8087FDB8",), - 0x8087FF08:("func_8087FF08",), - 0x8087FF14:("func_8087FF14",), - 0x808801A8:("func_808801A8",), - 0x808801F8:("func_808801F8",), - 0x808802D0:("func_808802D0",), - 0x808804A4:("func_808804A4",), - 0x808804CC:("func_808804CC",), - 0x80880500:("func_80880500",), - 0x80880534:("func_80880534",), - 0x808806DC:("func_808806DC",), - 0x80880844:("func_80880844",), - 0x80880978:("func_80880978",), - 0x80880D50:("func_80880D50",), - 0x80880DA8:("func_80880DA8",), - 0x80880E00:("func_80880E00",), - 0x80881128:("func_80881128",), + 0x8087D70C:("EnHorse_RotateToPlayer",), + 0x8087D75C:("EnHorse_Freeze",), + 0x8087D814:("EnHorse_Frozen",), + 0x8087D988:("EnHorse_UpdateSpeed",), + 0x8087DDEC:("EnHorse_StartMountedIdleResetAnim",), + 0x8087DE28:("EnHorse_StartMountedIdle",), + 0x8087DF64:("EnHorse_MountedIdle",), + 0x8087E080:("EnHorse_MountedIdleAnim",), + 0x8087E0A4:("EnHorse_MountedIdleWhinney",), + 0x8087E18C:("EnHorse_MountedIdleWhinneying",), + 0x8087E2A8:("EnHorse_StartTurning",), + 0x8087E350:("EnHorse_MountedTurn",), + 0x8087E564:("EnHorse_StartWalkingFromIdle",), + 0x8087E5B4:("EnHorse_StartWalkingInterruptable",), + 0x8087E5D8:("EnHorse_StartWalking",), + 0x8087E684:("EnHorse_MountedWalkingReset",), + 0x8087E6D8:("EnHorse_MountedWalk",), + 0x8087E92C:("EnHorse_StartTrotting",), + 0x8087E9D0:("EnHorse_MountedTrotReset",), + 0x8087EA1C:("EnHorse_MountedTrot",), + 0x8087EB54:("EnHorse_StartGallopingInterruptable",), + 0x8087EB78:("EnHorse_StartGalloping",), + 0x8087EC20:("EnHorse_MountedGallopReset",), + 0x8087EC78:("EnHorse_JumpLanding",), + 0x8087ED10:("EnHorse_MountedGallop",), + 0x8087EEC4:("EnHorse_StartRearing",), + 0x8087F078:("EnHorse_MountedRearing",), + 0x8087F1FC:("EnHorse_StartBraking",), + 0x8087F39C:("EnHorse_Stopping",), + 0x8087F590:("EnHorse_StartReversingInterruptable",), + 0x8087F5B4:("EnHorse_StartReversing",), + 0x8087F658:("EnHorse_Reverse",), + 0x8087F9A0:("EnHorse_LowJumpInit",), + 0x8087F9C4:("EnHorse_StartLowJump",), + 0x8087FB08:("EnHorse_Stub1",), + 0x8087FB14:("EnHorse_LowJump",), + 0x8087FD94:("EnHorse_HighJumpInit",), + 0x8087FDB8:("EnHorse_StartHighJump",), + 0x8087FF08:("EnHorse_Stub2",), + 0x8087FF14:("EnHorse_HighJump",), + 0x808801A8:("EnHorse_InitInactive",), + 0x808801F8:("EnHorse_Inactive",), + 0x808802D0:("EnHorse_PlayIdleAnimation",), + 0x808804A4:("EnHorse_ChangeIdleAnimation",), + 0x808804CC:("EnHorse_ResetIdleAnimation",), + 0x80880500:("EnHorse_StartIdleRidable",), + 0x80880534:("EnHorse_Idle",), + 0x808806DC:("EnHorse_StartMovingAnimation",), + 0x80880844:("EnHorse_SetFollowAnimation",), + 0x80880978:("EnHorse_FollowPlayer",), + 0x80880D50:("EnHorse_InitIngoHorse",), + 0x80880DA8:("EnHorse_SetIngoAnimation",), + 0x80880E00:("EnHorse_UpdateIngoHorseAnim",), + 0x80881128:("EnHorse_UpdateIngoRace",), 0x8088126C:("func_8088126C",), 0x80881290:("func_80881290",), 0x80881398:("func_80881398",), @@ -5293,26 +5289,26 @@ 0x80881634:("func_80881634",), 0x8088168C:("func_8088168C",), 0x808819D8:("func_808819D8",), - 0x80881BDC:("func_80881BDC",), - 0x80881C54:("func_80881C54",), - 0x80881DA4:("func_80881DA4",), - 0x80881DC8:("func_80881DC8",), - 0x80881F10:("func_80881F10",), - 0x80881F48:("func_80881F48",), - 0x808821C8:("func_808821C8",), - 0x808822CC:("func_808822CC",), - 0x8088247C:("func_8088247C",), - 0x80882564:("func_80882564",), - 0x808826B4:("func_808826B4",), - 0x80882820:("func_80882820",), - 0x808829D0:("func_808829D0",), - 0x808829F4:("func_808829F4",), - 0x80882A44:("func_80882A44",), - 0x80882B9C:("func_80882B9C",), - 0x80882D8C:("func_80882D8C",), - 0x80882DC0:("func_80882DC0",), - 0x80883104:("func_80883104",), - 0x80883308:("func_80883308",), + 0x80881BDC:("EnHorse_CsMoveInit",), + 0x80881C54:("EnHorse_CsMoveToPoint",), + 0x80881DA4:("EnHorse_CsSetAnimHighJump",), + 0x80881DC8:("EnHorse_CsPlayHighJumpAnim",), + 0x80881F10:("EnHorse_CsJumpInit",), + 0x80881F48:("EnHorse_CsJump",), + 0x808821C8:("EnHorse_CsRearingInit",), + 0x808822CC:("EnHorse_CsRearing",), + 0x8088247C:("EnHorse_WarpMoveInit",), + 0x80882564:("EnHorse_CsWarpMoveToPoint",), + 0x808826B4:("EnHorse_CsWarpRearingInit",), + 0x80882820:("EnHorse_CsWarpRearing",), + 0x808829D0:("EnHorse_InitCutscene",), + 0x808829F4:("EnHorse_GetCutsceneFunctionIndex",), + 0x80882A44:("EnHorse_CutsceneUpdate",), + 0x80882B9C:("EnHorse_UpdateHbaRaceInfo",), + 0x80882D8C:("EnHorse_InitHorsebackArchery",), + 0x80882DC0:("EnHorse_UpdateHbaAnim",), + 0x80883104:("EnHorse_UpdateHorsebackArchery",), + 0x80883308:("EnHorse_FleePlayer",), 0x80883B70:("func_80883B70",), 0x80883BEC:("func_80883BEC",), 0x80883CB0:("func_80883CB0",), @@ -5342,29 +5338,29 @@ 0x80884A40:("func_80884A40",), 0x80884D04:("func_80884D04",), 0x80884E0C:("func_80884E0C",), - 0x80885060:("func_80885060",), - 0x808850DC:("func_808850DC",), - 0x80885220:("func_80885220",), - 0x808853E0:("func_808853E0",), - 0x8088598C:("func_8088598C",), - 0x80885A80:("func_80885A80",), - 0x80885AF4:("func_80885AF4",), - 0x80885B4C:("func_80885B4C",), - 0x80885C90:("func_80885C90",), - 0x80885DA4:("func_80885DA4",), + 0x80885060:("EnHorse_Vec3fOffset",), + 0x808850DC:("EnHorse_CalcFloorHeight",), + 0x80885220:("EnHorse_ObstructMovement",), + 0x808853E0:("EnHorse_CheckFloors",), + 0x8088598C:("EnHorse_MountDismount",), + 0x80885A80:("EnHorse_StickDirection",), + 0x80885AF4:("EnHorse_UpdateStick",), + 0x80885B4C:("EnHorse_ResolveCollision",), + 0x80885C90:("EnHorse_BgCheckSlowMoving",), + 0x80885DA4:("EnHorse_UpdateBgCheckInfo",), 0x80886C00:("func_80886C00",), - 0x80886DC4:("func_80886DC4",), - 0x80886FA8:("func_80886FA8",), - 0x808870A4:("func_808870A4",), - 0x808871A0:("func_808871A0",), - 0x80887270:("func_80887270",), + 0x80886DC4:("EnHorse_RegenBoost",), + 0x80886FA8:("EnHorse_UpdatePlayerDir",), + 0x808870A4:("EnHorse_TiltBody",), + 0x808871A0:("EnHorse_UpdateConveyors",), + 0x80887270:("EnHorse_RandInt",), 0x808872A4:("EnHorse_Update",), - 0x80887D20:("func_80887D20",), - 0x80887D60:("func_80887D60",), - 0x80887E64:("func_80887E64",), - 0x80887EBC:("func_80887EBC",), - 0x80887F58:("func_80887F58",), - 0x80888C48:("func_80888C48",), + 0x80887D20:("EnHorse_PlayerDirToMountSide",), + 0x80887D60:("EnHorse_MountSideCheck",), + 0x80887E64:("EnHorse_GetMountSide",), + 0x80887EBC:("EnHorse_RandomOffset",), + 0x80887F58:("EnHorse_PostDraw",), + 0x80888C48:("EnHorse_OverrideLimbDraw",), 0x80888D18:("func_80888D18",), 0x80888D78:("EnHorse_Draw",), 0x8088A240:("EnArrow_Init",), @@ -5423,14 +5419,14 @@ 0x8088FE64:("func_8088FE64",), 0x8089010C:("func_8089010C",), 0x80890438:("EnElf_Update",), - 0x80890494:("func_80890494",), + 0x80890494:("EnElf_OverrideLimbDraw",), 0x808905B8:("EnElf_Draw",), 0x808908D0:("func_808908D0",), 0x80891060:("EnNiw_Init",), 0x808912E8:("EnNiw_Destroy",), - 0x80891320:("func_80891320",), + 0x80891320:("EnNiw_AnimateWingHead",), 0x808916B0:("EnNiw_SpawnAttackNiw",), - 0x808917F8:("func_808917F8",), + 0x808917F8:("EnNiw_UpdateRunning",), 0x80891974:("EnNiw_SetupIdle",), 0x808919E8:("EnNiw_Idle",), 0x80891D78:("EnNiw_Held",), @@ -5445,7 +5441,7 @@ 0x808925F8:("EnNiw_LandBeforeIdle",), 0x8089262C:("EnNiw_CheckRage",), 0x808927CC:("EnNiw_Update",), - 0x80892E70:("EnNiw_LimbDraw",), + 0x80892E70:("EnNiw_OverrideLimbDraw",), 0x80892FA0:("EnNiw_Draw",), 0x80893008:("EnNiw_SpawnFeather",), 0x808930FC:("EnNiw_UpdateFeather",), @@ -5498,8 +5494,8 @@ 0x80895FF8:("func_80895FF8",), 0x808963B4:("func_808963B4",), 0x808964E8:("EnTite_Update",), - 0x80896750:("func_80896750",), - 0x80896788:("func_80896788",), + 0x80896750:("EnTite_OverrideLimbDraw",), + 0x80896788:("EnTite_PostLimbDraw",), 0x8089695C:("EnTite_Draw",), 0x80896F30:("EnPeehat_Init",), 0x808970F4:("EnPeehat_Destroy",), @@ -5531,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",), @@ -5646,12 +5642,12 @@ 0x808A03E8:("func_808A03E8",), 0x808A0458:("EnBubble_Update",), 0x808A04D4:("EnBubble_Draw",), - 0x808A08F0:("func_808A08F0",), + 0x808A08F0:("DoorShutter_SetupAction",), 0x808A0900:("func_808A0900",), - 0x808A0974:("func_808A0974",), + 0x808A0974:("DoorShutter_SetupDoor",), 0x808A0B10:("DoorShutter_Init",), 0x808A0CD0:("DoorShutter_Destroy",), - 0x808A0D0C:("func_808A0D0C",), + 0x808A0D0C:("DoorShutter_SetupType",), 0x808A0D90:("func_808A0D90",), 0x808A0E28:("func_808A0E28",), 0x808A0F88:("func_808A0F88",), @@ -5670,7 +5666,7 @@ 0x808A1C50:("func_808A1C50",), 0x808A1CC4:("DoorShutter_Update",), 0x808A1D68:("func_808A1D68",), - 0x808A1E14:("func_808A1E14",), + 0x808A1E14:("DoorShutter_Draw",), 0x808A24D0:("EnBoom_SetupAction",), 0x808A24DC:("func_808A24DC",), 0x808A2700:("EnBoom_Init",), @@ -5692,7 +5688,7 @@ 0x808A3A44:("EnMinifrog_Jump",), 0x808A3B04:("EnMinifrog_TurnToPlayer",), 0x808A3B3C:("EnMinifrog_TurnToMissingFrog",), - 0x808A3B74:("EnMinifrog_SetCamera",), + 0x808A3B74:("EnMinifrog_SpawnDust",), 0x808A3DA8:("EnMinifrog_ReturnFrogCutscene",), 0x808A3F88:("EnMinifrog_SpawnGrowAndShrink",), 0x808A4040:("EnMinifrog_Idle",), @@ -5740,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",), @@ -5806,10 +5802,10 @@ 0x808AAB30:("EnOssan_UpdateStickDirectionPromptAnim",), 0x808AACE0:("EnOssan_WaitForBlink",), 0x808AAD14:("EnOssan_Blink",), - 0x808AADB4:("EnOssan_InitCuriosityShopMan",), - 0x808AAE1C:("EnOssan_InitPartTimeWorker",), - 0x808AAE84:("EnOssan_GetWelcomeCuriosityShopMan",), - 0x808AAFB0:("EnOssan_GetWelcomePartTimeWorker",), + 0x808AADB4:("EnOssan_CuriosityShopMan_Init",), + 0x808AAE1C:("EnOssan_PartTimeWorker_Init",), + 0x808AAE84:("EnOssan_CuriosityShopMan_GetWelcome",), + 0x808AAFB0:("EnOssan_PartTimerWorker_GetWelcome",), 0x808AB0B0:("EnOssan_SetHaveMet",), 0x808AB16C:("EnOssan_InitShop",), 0x808AB404:("EnOssan_GetCutscenes",), @@ -5817,52 +5813,52 @@ 0x808AB52C:("EnOssan_DrawCursor",), 0x808AB78C:("EnOssan_DrawTextRec",), 0x808AB928:("EnOssan_DrawStickDirectionPrompts",), - 0x808ABCD0:("EnOssan_OverrideLimbDrawCuriosityShopMan",), - 0x808ABD10:("EnOssan_OverrideLimbDrawPartTimeWorker",), - 0x808ABD60:("EnOssan_PostLimbDrawCuriosityShopMan",), - 0x808ABE18:("EnOssan_PostLimbDrawPartTimeWorker",), - 0x808ABE58:("EnOssan_DrawCuriosityShopMan",), - 0x808ABF30:("EnOssan_DrawPartTimeWorker",), + 0x808ABCD0:("EnOssan_CuriosityShopMan_OverrideLimbDraw",), + 0x808ABD10:("EnOssan_PartTimeWorker_OverrideLimbDraw",), + 0x808ABD60:("EnOssan_CuriosityShopMan_PostLimbDraw",), + 0x808ABE18:("EnOssan_PartTimeWorker_PostLimbDraw",), + 0x808ABE58:("EnOssan_CuriosityShopMan_Draw",), + 0x808ABF30:("EnOssan_PartTimeWorker_Draw",), 0x808AC920:("EnFamos_Init",), 0x808ACB08:("EnFamos_Destroy",), - 0x808ACB58:("func_808ACB58",), - 0x808ACD2C:("func_808ACD2C",), - 0x808ACF1C:("func_808ACF1C",), - 0x808ACF98:("func_808ACF98",), - 0x808AD05C:("func_808AD05C",), - 0x808AD170:("func_808AD170",), - 0x808AD18C:("func_808AD18C",), - 0x808AD1F0:("func_808AD1F0",), - 0x808AD294:("func_808AD294",), - 0x808AD31C:("func_808AD31C",), - 0x808AD378:("func_808AD378",), - 0x808AD3E8:("func_808AD3E8",), - 0x808AD42C:("func_808AD42C",), - 0x808AD54C:("func_808AD54C",), - 0x808AD5B0:("func_808AD5B0",), - 0x808AD66C:("func_808AD66C",), - 0x808AD68C:("func_808AD68C",), - 0x808AD7EC:("func_808AD7EC",), - 0x808AD840:("func_808AD840",), - 0x808AD888:("func_808AD888",), - 0x808AD8B8:("func_808AD8B8",), - 0x808ADA74:("func_808ADA74",), - 0x808ADAE8:("func_808ADAE8",), - 0x808ADB4C:("func_808ADB4C",), - 0x808ADB70:("func_808ADB70",), - 0x808ADC40:("func_808ADC40",), - 0x808ADC64:("func_808ADC64",), - 0x808ADD20:("func_808ADD20",), - 0x808ADDA8:("func_808ADDA8",), - 0x808ADE00:("func_808ADE00",), - 0x808ADE74:("func_808ADE74",), - 0x808ADFA4:("func_808ADFA4",), - 0x808ADFF0:("func_808ADFF0",), - 0x808AE030:("func_808AE030",), + 0x808ACB58:("EnFamos_SetupAttackDebris",), + 0x808ACD2C:("EnFamos_SetupDeathDebris",), + 0x808ACF1C:("EnFamos_IsPlayerSeen",), + 0x808ACF98:("EnFamos_UpdateBobbingHeight",), + 0x808AD05C:("EnFamos_UpdateFlipStatus",), + 0x808AD170:("EnFamos_SetupStillIdle",), + 0x808AD18C:("EnFamos_StillIdle",), + 0x808AD1F0:("EnFamos_SetupPathingIdle",), + 0x808AD294:("EnFamos_PathingIdle",), + 0x808AD31C:("EnFamos_SetupTurnHome",), + 0x808AD378:("EnFamos_TurnHome",), + 0x808AD3E8:("EnFamos_SetupReturnHome",), + 0x808AD42C:("EnFamos_ReturnHome",), + 0x808AD54C:("EnFamos_SetupAlert",), + 0x808AD5B0:("EnFamos_Alert",), + 0x808AD66C:("EnFamos_SetupChase",), + 0x808AD68C:("EnFamos_Chase",), + 0x808AD7EC:("EnFamos_SetupAttackAim",), + 0x808AD840:("EnFamos_AttackAim",), + 0x808AD888:("EnFamos_SetupAttack",), + 0x808AD8B8:("EnFamos_Attack",), + 0x808ADA74:("EnFamos_SetupFinishAttack",), + 0x808ADAE8:("EnFamos_FinishAttack",), + 0x808ADB4C:("EnFamos_SetupAttackRebound",), + 0x808ADB70:("EnFamos_AttackRebound",), + 0x808ADC40:("EnFamos_SetupScanForPlayer",), + 0x808ADC64:("EnFamos_ScanForPlayer",), + 0x808ADD20:("EnFamos_SetupDeathSlam",), + 0x808ADDA8:("EnFamos_DeathSlam",), + 0x808ADE00:("EnFamos_SetupDeathExplosion",), + 0x808ADE74:("EnFamos_DeathExplosion",), + 0x808ADFA4:("EnFamos_SetupDeathFade",), + 0x808ADFF0:("EnFamos_DeathFade",), + 0x808AE030:("EnFamos_UpdateDebrisPosRot",), 0x808AE0EC:("EnFamos_Update",), - 0x808AE304:("func_808AE304",), - 0x808AE3A8:("func_808AE3A8",), - 0x808AE3FC:("func_808AE3FC",), + 0x808AE304:("EnFamos_OverrideLimbDraw",), + 0x808AE3A8:("EnFamos_PostLimbDraw",), + 0x808AE3FC:("EnFamos_DrawDebris",), 0x808AE530:("EnFamos_Draw",), 0x808AE8C0:("EnBombf_SetupAction",), 0x808AE8CC:("EnBombf_Init",), @@ -5877,11 +5873,11 @@ 0x808AF8F8:("EnBombf_Draw",), 0x808AFCD0:("EnAm_Init",), 0x808AFDF8:("EnAm_Destroy",), - 0x808AFE38:("func_808AFE38",), + 0x808AFE38:("EnAm_SpawnEffects",), 0x808AFF9C:("func_808AFF9C",), - 0x808B0040:("func_808B0040",), - 0x808B00D8:("func_808B00D8",), - 0x808B0124:("func_808B0124",), + 0x808B0040:("EnAm_RemoveEnemyTexture",), + 0x808B00D8:("EnAm_WakeUp",), + 0x808B0124:("EnAm_ApplyEnemyTexture",), 0x808B0208:("func_808B0208",), 0x808B0358:("func_808B0358",), 0x808B03C0:("func_808B03C0",), @@ -5893,15 +5889,15 @@ 0x808B05C8:("func_808B05C8",), 0x808B0640:("func_808B0640",), 0x808B066C:("func_808B066C",), - 0x808B06D0:("func_808B06D0",), + 0x808B06D0:("EnAm_TakeDamage",), 0x808B07A8:("func_808B07A8",), 0x808B0820:("func_808B0820",), 0x808B0894:("func_808B0894",), 0x808B0AD0:("func_808B0AD0",), 0x808B0B4C:("func_808B0B4C",), - 0x808B0B9C:("func_808B0B9C",), + 0x808B0B9C:("EnAm_UpdateDamage",), 0x808B0CC8:("EnAm_Update",), - 0x808B0EA4:("func_808B0EA4",), + 0x808B0EA4:("EnAm_PostLimbDraw",), 0x808B0F98:("EnAm_Draw",), 0x808B1330:("EnDekubaba_Init",), 0x808B1504:("EnDekubaba_Destroy",), @@ -5975,7 +5971,7 @@ 0x808B74D8:("func_808B74D8",), 0x808B751C:("func_808B751C",), 0x808B75B0:("BgBreakwall_Init",), - 0x808B767C:("func_808B767C",), + 0x808B767C:("BgBreakwall_Destroy",), 0x808B76CC:("func_808B76CC",), 0x808B77D0:("func_808B77D0",), 0x808B77E0:("func_808B77E0",), @@ -5988,7 +5984,7 @@ 0x808B7A90:("func_808B7A90",), 0x808B7B54:("func_808B7B54",), 0x808B7D34:("func_808B7D34",), - 0x808B7FE4:("func_808B7FE4",), + 0x808B7FE4:("BgBreakwall_Draw",), 0x808B8490:("DoorWarp1_SetupAction",), 0x808B849C:("func_808B849C",), 0x808B8568:("func_808B8568",), @@ -6070,38 +6066,38 @@ 0x808BE6C4:("func_808BE6C4",), 0x808BE73C:("func_808BE73C",), 0x808BEA48:("EnDekunuts_Update",), - 0x808BEBD0:("func_808BEBD0",), - 0x808BED30:("func_808BED30",), + 0x808BEBD0:("EnDekunuts_OverrideLimbDraw",), + 0x808BED30:("EnDekunuts_PostLimbDraw",), 0x808BEE38:("EnDekunuts_Draw",), 0x808BF220:("EnBbfall_Init",), 0x808BF318:("EnBbfall_Destroy",), - 0x808BF344:("func_808BF344",), - 0x808BF3B8:("func_808BF3B8",), - 0x808BF438:("func_808BF438",), - 0x808BF4B4:("func_808BF4B4",), - 0x808BF514:("func_808BF514",), - 0x808BF578:("func_808BF578",), - 0x808BF5AC:("func_808BF5AC",), - 0x808BF5E0:("func_808BF5E0",), - 0x808BF734:("func_808BF734",), - 0x808BF7A0:("func_808BF7A0",), - 0x808BF830:("func_808BF830",), - 0x808BF894:("func_808BF894",), - 0x808BF8DC:("func_808BF8DC",), - 0x808BFA18:("func_808BFA18",), - 0x808BFA3C:("func_808BFA3C",), - 0x808BFAB4:("func_808BFAB4",), - 0x808BFB4C:("func_808BFB4C",), - 0x808BFCCC:("func_808BFCCC",), - 0x808BFE58:("func_808BFE58",), - 0x808BFF8C:("func_808BFF8C",), - 0x808C00A0:("func_808C00A0",), - 0x808C013C:("func_808C013C",), - 0x808C0178:("func_808C0178",), - 0x808C01E0:("func_808C01E0",), + 0x808BF344:("EnBbfall_Freeze",), + 0x808BF3B8:("EnBbfall_Thaw",), + 0x808BF438:("EnBbfall_IsTouchingLava",), + 0x808BF4B4:("EnBbfall_PlaySfx",), + 0x808BF514:("EnBbfall_CheckForWall",), + 0x808BF578:("EnBbfall_EnableColliders",), + 0x808BF5AC:("EnBbfall_DisableColliders",), + 0x808BF5E0:("EnBbfall_SetupWaitForPlayer",), + 0x808BF734:("EnBbfall_WaitForPlayer",), + 0x808BF7A0:("EnBbfall_SetupEmerge",), + 0x808BF830:("EnBbfall_Emerge",), + 0x808BF894:("EnBbfall_SetupFly",), + 0x808BF8DC:("EnBbfall_Fly",), + 0x808BFA18:("EnBbfall_SetupSinkIntoLava",), + 0x808BFA3C:("EnBbfall_SinkIntoLava",), + 0x808BFAB4:("EnBbfall_SetupDown",), + 0x808BFB4C:("EnBbfall_Down",), + 0x808BFCCC:("EnBbfall_SetupDead",), + 0x808BFE58:("EnBbfall_Dead",), + 0x808BFF8C:("EnBbfall_SetupDamage",), + 0x808C00A0:("EnBbfall_Damage",), + 0x808C013C:("EnBbfall_SetupFrozen",), + 0x808C0178:("EnBbfall_Frozen",), + 0x808C01E0:("EnBbfall_UpdateDamage",), 0x808C03EC:("EnBbfall_Update",), - 0x808C07D4:("func_808C07D4",), - 0x808C080C:("func_808C080C",), + 0x808C07D4:("EnBbfall_OverrideLimbDraw",), + 0x808C080C:("EnBbfall_PostLimbDraw",), 0x808C0A04:("EnBbfall_Draw",), 0x808C1030:("ArmsHook_SetupAction",), 0x808C103C:("ArmsHook_Init",), @@ -6117,37 +6113,37 @@ 0x808C1918:("ArmsHook_Draw",), 0x808C1D40:("EnBb_Init",), 0x808C1E68:("EnBb_Destroy",), - 0x808C1E94:("func_808C1E94",), - 0x808C1F00:("func_808C1F00",), - 0x808C1F74:("func_808C1F74",), - 0x808C1FF4:("func_808C1FF4",), - 0x808C20D4:("func_808C20D4",), - 0x808C2238:("func_808C2238",), - 0x808C2344:("func_808C2344",), - 0x808C23EC:("func_808C23EC",), - 0x808C254C:("func_808C254C",), - 0x808C25E0:("func_808C25E0",), - 0x808C272C:("func_808C272C",), - 0x808C28CC:("func_808C28CC",), - 0x808C2A00:("func_808C2A00",), - 0x808C2B1C:("func_808C2B1C",), - 0x808C2B94:("func_808C2B94",), - 0x808C2BD0:("func_808C2BD0",), - 0x808C2C38:("func_808C2C38",), - 0x808C2CB4:("func_808C2CB4",), - 0x808C2CF0:("func_808C2CF0",), - 0x808C2D78:("func_808C2D78",), - 0x808C2E34:("func_808C2E34",), + 0x808C1E94:("EnBb_CheckForWall",), + 0x808C1F00:("EnBb_Freeze",), + 0x808C1F74:("EnBb_Thaw",), + 0x808C1FF4:("EnBb_UpdateStateForFlying",), + 0x808C20D4:("EnBb_SetupFlyIdle",), + 0x808C2238:("EnBb_FlyIdle",), + 0x808C2344:("EnBb_SetupAttack",), + 0x808C23EC:("EnBb_Attack",), + 0x808C254C:("EnBb_SetupDown",), + 0x808C25E0:("EnBb_Down",), + 0x808C272C:("EnBb_SetupDead",), + 0x808C28CC:("EnBb_Dead",), + 0x808C2A00:("EnBb_SetupDamage",), + 0x808C2B1C:("EnBb_Damage",), + 0x808C2B94:("EnBb_SetupFrozen",), + 0x808C2BD0:("EnBb_Frozen",), + 0x808C2C38:("EnBb_SetupWaitForRevive",), + 0x808C2CB4:("EnBb_WaitForRevive",), + 0x808C2CF0:("EnBb_SetupRevive",), + 0x808C2D78:("EnBb_Revive",), + 0x808C2E34:("EnBb_UpdateDamage",), 0x808C30A0:("EnBb_Update",), - 0x808C32EC:("func_808C32EC",), - 0x808C3324:("func_808C3324",), + 0x808C32EC:("EnBb_OverrideLimbDraw",), + 0x808C3324:("EnBb_PostLimbDraw",), 0x808C351C:("EnBb_Draw",), 0x808C3A50:("BgKeikokuSpr_Init",), 0x808C3A78:("BgKeikokuSpr_Destroy",), 0x808C3A88:("BgKeikokuSpr_Update",), 0x808C3A98:("BgKeikokuSpr_Draw",), - 0x808C3C00:("func_808C3C00",), - 0x808C3D28:("func_808C3D28",), + 0x808C3C00:("EnWood02_SpawnZoneCheck",), + 0x808C3D28:("EnWood02_SpawnOffspring",), 0x808C3F30:("EnWood02_Init",), 0x808C4414:("EnWood02_Destroy",), 0x808C4458:("func_808C4458",), @@ -6262,8 +6258,8 @@ 0x808CCCF0:("func_808CCCF0",), 0x808CCDE4:("func_808CCDE4",), 0x808CCEE4:("EnVm_Update",), - 0x808CD020:("func_808CD020",), - 0x808CD08C:("func_808CD08C",), + 0x808CD020:("EnVm_OverrideLimbDraw",), + 0x808CD08C:("EnVm_PostLimbDraw",), 0x808CD238:("EnVm_Draw",), 0x808CD740:("DemoEffect_Init",), 0x808CD8E8:("DemoEffect_Destroy",), @@ -6342,55 +6338,55 @@ 0x808D2DC0:("func_808D2DC0",), 0x808D2E34:("func_808D2E34",), 0x808D316C:("EnFloormas_Update",), - 0x808D3488:("func_808D3488",), - 0x808D34C4:("func_808D34C4",), + 0x808D3488:("EnFloormas_OverrideLimbDraw",), + 0x808D34C4:("EnFloormas_PostLimbDraw",), 0x808D3630:("EnFloormas_Draw",), 0x808D3754:("func_808D3754",), 0x808D3E20:("EnRd_Init",), 0x808D414C:("EnRd_Destroy",), - 0x808D4190:("func_808D4190",), - 0x808D41FC:("func_808D41FC",), - 0x808D4260:("func_808D4260",), - 0x808D4308:("func_808D4308",), - 0x808D43AC:("func_808D43AC",), - 0x808D45D4:("func_808D45D4",), - 0x808D4660:("func_808D4660",), - 0x808D47DC:("func_808D47DC",), - 0x808D4868:("func_808D4868",), - 0x808D49E4:("func_808D49E4",), - 0x808D4A90:("func_808D4A90",), - 0x808D4B20:("func_808D4B20",), - 0x808D4CA8:("func_808D4CA8",), - 0x808D4DC4:("func_808D4DC4",), - 0x808D4E60:("func_808D4E60",), - 0x808D4FE0:("func_808D4FE0",), - 0x808D506C:("func_808D506C",), - 0x808D53C0:("func_808D53C0",), - 0x808D5440:("func_808D5440",), - 0x808D5660:("func_808D5660",), - 0x808D56E4:("func_808D56E4",), - 0x808D586C:("func_808D586C",), - 0x808D58CC:("func_808D58CC",), - 0x808D5C54:("func_808D5C54",), - 0x808D5CCC:("func_808D5CCC",), - 0x808D5D88:("func_808D5D88",), - 0x808D5DF4:("func_808D5DF4",), - 0x808D5E98:("func_808D5E98",), - 0x808D5F18:("func_808D5F18",), - 0x808D6008:("func_808D6008",), - 0x808D6054:("func_808D6054",), - 0x808D60B0:("func_808D60B0",), - 0x808D6130:("func_808D6130",), - 0x808D616C:("func_808D616C",), - 0x808D6200:("func_808D6200",), - 0x808D6310:("func_808D6310",), - 0x808D6388:("func_808D6388",), - 0x808D64D0:("func_808D64D0",), - 0x808D65BC:("func_808D65BC",), - 0x808D66A0:("func_808D66A0",), - 0x808D6814:("func_808D6814",), - 0x808D6A94:("func_808D6A94",), - 0x808D6B64:("func_808D6B64",), + 0x808D4190:("EnRd_UpdateParentForOtherRedeads",), + 0x808D41FC:("EnRd_ShouldNotDance",), + 0x808D4260:("EnRd_SetupDanceIfConditionsMet",), + 0x808D4308:("EnRd_SetupIdle",), + 0x808D43AC:("EnRd_Idle",), + 0x808D45D4:("EnRd_SetupSquattingDance",), + 0x808D4660:("EnRd_SquattingDance",), + 0x808D47DC:("EnRd_SetupClappingDance",), + 0x808D4868:("EnRd_ClappingDance",), + 0x808D49E4:("EnRd_EndClappingOrSquattingDanceWhenPlayerIsClose",), + 0x808D4A90:("EnRd_SetupPirouette",), + 0x808D4B20:("EnRd_Pirouette",), + 0x808D4CA8:("EnRd_EndPirouetteWhenPlayerIsClose",), + 0x808D4DC4:("EnRd_SetupRiseFromCoffin",), + 0x808D4E60:("EnRd_RiseFromCoffin",), + 0x808D4FE0:("EnRd_SetupWalkToPlayer",), + 0x808D506C:("EnRd_WalkToPlayer",), + 0x808D53C0:("EnRd_SetupWalkToHome",), + 0x808D5440:("EnRd_WalkToHome",), + 0x808D5660:("EnRd_SetupWalkToParent",), + 0x808D56E4:("EnRd_WalkToParent",), + 0x808D586C:("EnRd_SetupGrab",), + 0x808D58CC:("EnRd_Grab",), + 0x808D5C54:("EnRd_SetupAttemptPlayerFreeze",), + 0x808D5CCC:("EnRd_AttemptPlayerFreeze",), + 0x808D5D88:("EnRd_SetupGrabFail",), + 0x808D5DF4:("EnRd_GrabFail",), + 0x808D5E98:("EnRd_SetupTurnAwayAndShakeHead",), + 0x808D5F18:("EnRd_TurnAwayAndShakeHead",), + 0x808D6008:("EnRd_SetupStandUp",), + 0x808D6054:("EnRd_StandUp",), + 0x808D60B0:("EnRd_SetupCrouch",), + 0x808D6130:("EnRd_Crouch",), + 0x808D616C:("EnRd_SetupDamage",), + 0x808D6200:("EnRd_Damage",), + 0x808D6310:("EnRd_SetupDead",), + 0x808D6388:("EnRd_Dead",), + 0x808D64D0:("EnRd_SetupStunned",), + 0x808D65BC:("EnRd_Stunned",), + 0x808D66A0:("EnRd_TurnTowardsPlayer",), + 0x808D6814:("EnRd_UpdateDamage",), + 0x808D6A94:("EnRd_UpdateCollision",), + 0x808D6B64:("EnRd_UpdateEffect",), 0x808D6C10:("EnRd_Update",), 0x808D6DA0:("EnRd_OverrideLimbDraw",), 0x808D6DFC:("EnRd_PostLimbDraw",), @@ -6405,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",), @@ -6543,17 +6539,17 @@ 0x808E2444:("func_808E2444",), 0x808E24B4:("BgCtowerRot_Update",), 0x808E24D8:("BgCtowerRot_Draw",), - 0x808E2600:("func_808E2600",), - 0x808E26C8:("func_808E26C8",), + 0x808E2600:("MirRay_SetupCollider",), + 0x808E26C8:("MirRay_MakeShieldLight",), 0x808E286C:("MirRay_Init",), 0x808E2B04:("MirRay_Destroy",), 0x808E2B7C:("MirRay_Update",), - 0x808E2C68:("func_808E2C68",), - 0x808E2E1C:("func_808E2E1C",), - 0x808E2FF8:("func_808E2FF8",), - 0x808E30FC:("func_808E30FC",), + 0x808E2C68:("MirRay_SetIntensity",), + 0x808E2E1C:("MirRay_SetupReflectionPolys",), + 0x808E2FF8:("MirRay_RemoveSimilarReflections",), + 0x808E30FC:("MirRay_ReflectedBeam",), 0x808E36A4:("MirRay_Draw",), - 0x808E3984:("func_808E3984",), + 0x808E3984:("MirRay_CheckInFrustum",), 0x808E3EF0:("EnSb_Init",), 0x808E3FF0:("EnSb_Destroy",), 0x808E401C:("EnSb_SpawnBubbles",), @@ -6675,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",), @@ -6753,17 +6749,17 @@ 0x808F69B4:("EnIn_Draw",), 0x808F74B0:("EnBomChu_Init",), 0x808F7580:("EnBomChu_Destroy",), - 0x808F75D0:("func_808F75D0",), - 0x808F77E4:("func_808F77E4",), - 0x808F7868:("func_808F7868",), - 0x808F7944:("func_808F7944",), - 0x808F79D4:("func_808F79D4",), - 0x808F7A84:("func_808F7A84",), - 0x808F7E74:("func_808F7E74",), - 0x808F7FA0:("func_808F7FA0",), - 0x808F7FD0:("func_808F7FD0",), - 0x808F8080:("func_808F8080",), - 0x808F818C:("func_808F818C",), + 0x808F75D0:("EnBomChu_UpdateFloorPoly",), + 0x808F77E4:("EnBomChu_UpdateRotation",), + 0x808F7868:("EnBomChu_WaitForRelease",), + 0x808F7944:("EnBomChu_IsOnCollisionPoly",), + 0x808F79D4:("EnBomChu_SetupMove",), + 0x808F7A84:("EnBomChu_Move",), + 0x808F7E74:("EnBomChu_Explode",), + 0x808F7FA0:("EnBomChu_WaitForDeath",), + 0x808F7FD0:("EnBomChu_ActorCoordsToWorld",), + 0x808F8080:("EnBomChu_SpawnRipplesAndSplashes",), + 0x808F818C:("EnBomChu_HandleNonSceneCollision",), 0x808F83B8:("EnBomChu_Update",), 0x808F8714:("EnBomChu_Draw",), 0x808F8AA0:("func_808F8AA0",), @@ -6822,78 +6818,78 @@ 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",), - 0x80917290:("func_80917290",), - 0x809172E4:("func_809172E4",), - 0x8091734C:("func_8091734C",), - 0x80917378:("func_80917378",), - 0x80917408:("func_80917408",), - 0x80917538:("func_80917538",), - 0x80917604:("func_80917604",), - 0x8091763C:("func_8091763C",), - 0x8091768C:("func_8091768C",), + 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:("ObjOshihiki_RotateXZ",), + 0x809172E4:("ObjOshihiki_StrongEnough",), + 0x8091734C:("ObjOshihiki_ResetFloors",), + 0x80917378:("ObjOshihiki_GetBlockUnder",), + 0x80917408:("ObjOshihiki_UpdateInitPos",), + 0x80917538:("ObjOshihiki_NoSwitchPress",), + 0x80917604:("ObjOshihiki_SetScale",), + 0x8091763C:("ObjOshihiki_SetTextureStep",), + 0x8091768C:("ObjOshihiki_SetColor",), 0x809176D0:("ObjOshihiki_Init",), 0x8091780C:("ObjOshihiki_Destroy",), - 0x80917840:("func_80917840",), - 0x809179A0:("func_809179A0",), - 0x80917AEC:("func_80917AEC",), - 0x80917B44:("func_80917B44",), - 0x80917B9C:("func_80917B9C",), - 0x80917C14:("func_80917C14",), - 0x80917E8C:("func_80917E8C",), - 0x80917F88:("func_80917F88",), - 0x80917FC0:("func_80917FC0",), - 0x809180C8:("func_809180C8",), - 0x80918108:("func_80918108",), - 0x80918314:("func_80918314",), - 0x8091834C:("func_8091834C",), - 0x8091851C:("func_8091851C",), - 0x80918574:("func_80918574",), + 0x80917840:("ObjOshihiki_SetFloors",), + 0x809179A0:("ObjOshihiki_GetHighestFloor",), + 0x80917AEC:("ObjOshihiki_SetGround",), + 0x80917B44:("ObjOshihiki_CheckFloor",), + 0x80917B9C:("ObjOshihiki_CheckGround",), + 0x80917C14:("ObjOshihiki_CheckWall",), + 0x80917E8C:("ObjOshihiki_MoveWithBlockUnder",), + 0x80917F88:("ObjOshihiki_SetupOnScene",), + 0x80917FC0:("ObjOshihiki_OnScene",), + 0x809180C8:("ObjOshihiki_SetupOnActor",), + 0x80918108:("ObjOshihiki_OnActor",), + 0x80918314:("ObjOshihiki_SetupPush",), + 0x8091834C:("ObjOshihiki_Push",), + 0x8091851C:("ObjOshihiki_SetupFall",), + 0x80918574:("ObjOshihiki_Fall",), 0x80918678:("ObjOshihiki_Update",), 0x80918700:("ObjOshihiki_Draw",), 0x80918B40:("func_80918B40",), @@ -6916,8 +6912,8 @@ 0x8091A5A0:("func_8091A5A0",), 0x8091A7B0:("func_8091A7B0",), 0x8091A8A0:("func_8091A8A0",), - 0x8091A8C4:("func_8091A8C4",), - 0x8091A8F4:("func_8091A8F4",), + 0x8091A8C4:("EnInsect_XZDistanceSquared",), + 0x8091A8F4:("EnInsect_InBottleRange",), 0x8091A9E4:("func_8091A9E4",), 0x8091AA78:("EnInsect_Init",), 0x8091AC4C:("EnInsect_Destroy",), @@ -7004,12 +7000,12 @@ 0x80920340:("ArrowFire_SetupAction",), 0x8092034C:("ArrowFire_Init",), 0x809203F8:("ArrowFire_Destroy",), - 0x80920440:("func_80920440",), + 0x80920440:("FireArrow_ChargeAndWait",), 0x80920534:("FireArrow_Lerp",), - 0x8092058C:("func_8092058C",), - 0x809207A0:("func_809207A0",), + 0x8092058C:("FireArrow_Hit",), + 0x809207A0:("FireArrow_Fly",), 0x809208F4:("ArrowFire_Update",), - 0x80920948:("func_80920948",), + 0x80920948:("FireArrow_SetQuadVerticies",), 0x80920A24:("ArrowFire_Draw",), 0x80922430:("ArrowIce_SetupAction",), 0x8092243C:("ArrowIce_Init",), @@ -7023,10 +7019,10 @@ 0x80924300:("ArrowLight_SetupAction",), 0x8092430C:("ArrowLight_Init",), 0x80924388:("ArrowLight_Destroy",), - 0x809243AC:("func_809243AC",), - 0x809244A0:("func_809244A0",), - 0x809244F8:("func_809244F8",), - 0x809246C4:("func_809246C4",), + 0x809243AC:("ArrowLight_Charge",), + 0x809244A0:("ArrowLight_Lerp",), + 0x809244F8:("ArrowLight_Hit",), + 0x809246C4:("ArrowLight_Fly",), 0x80924818:("ArrowLight_Update",), 0x8092486C:("ArrowLight_Draw",), 0x809261B0:("ObjKibako_SpawnCollectible",), @@ -7255,37 +7251,37 @@ 0x809340BC:("func_809340BC",), 0x80934178:("func_80934178",), 0x80934464:("func_80934464",), - 0x809349E0:("func_809349E0",), - 0x80934AB4:("func_80934AB4",), - 0x80934F58:("func_80934F58",), - 0x80934FFC:("func_80934FFC",), - 0x809350C4:("func_809350C4",), - 0x809350F8:("func_809350F8",), - 0x8093517C:("func_8093517C",), - 0x809351A0:("func_809351A0",), - 0x809354F8:("func_809354F8",), - 0x809355A4:("func_809355A4",), - 0x8093561C:("func_8093561C",), + 0x809349E0:("EnKusa_ApplySway",), + 0x80934AB4:("EnKusa_Sway",), + 0x80934F58:("EnKusa_SnapToFloor",), + 0x80934FFC:("EnKusa_DropCollectible",), + 0x809350C4:("EnKusa_UpdateVelY",), + 0x809350F8:("EnKusa_RandScaleVecToZero",), + 0x8093517C:("EnKusa_SetScaleSmall",), + 0x809351A0:("EnKusa_SpawnFragments",), + 0x809354F8:("EnKusa_SpawnBugs",), + 0x809355A4:("EnKusa_GetWaterBox",), + 0x8093561C:("EnKusa_InitCollider",), 0x80935674:("EnKusa_Init",), 0x80935898:("EnKusa_Destroy",), - 0x809358C4:("func_809358C4",), - 0x809358D8:("func_809358D8",), - 0x80935988:("func_80935988",), - 0x809359AC:("func_809359AC",), - 0x80935B94:("func_80935B94",), - 0x80935BBC:("func_80935BBC",), - 0x80935CE8:("func_80935CE8",), - 0x80935D64:("func_80935D64",), - 0x80936120:("func_80936120",), - 0x80936168:("func_80936168",), - 0x809361A4:("func_809361A4",), - 0x809361B4:("func_809361B4",), - 0x80936220:("func_80936220",), - 0x80936290:("func_80936290",), - 0x809362D8:("func_809362D8",), + 0x809358C4:("EnKusa_SetupWaitObject",), + 0x809358D8:("EnKusa_WaitObject",), + 0x80935988:("EnKusa_SetupInteract",), + 0x809359AC:("EnKusa_WaitForInteract",), + 0x80935B94:("EnKusa_SetupLiftedUp",), + 0x80935BBC:("EnKusa_LiftedUp",), + 0x80935CE8:("EnKusa_SetupFall",), + 0x80935D64:("EnKusa_Fall",), + 0x80936120:("EnKusa_SetupCut",), + 0x80936168:("EnKusa_CutWaitRegrow",), + 0x809361A4:("EnKusa_DoNothing",), + 0x809361B4:("EnKusa_SetupUprootedWaitRegrow",), + 0x80936220:("EnKusa_UprootedWaitRegrow",), + 0x80936290:("EnKusa_SetupRegrow",), + 0x809362D8:("EnKusa_Regrow",), 0x80936370:("EnKusa_Update",), - 0x80936414:("func_80936414",), - 0x809365CC:("func_809365CC",), + 0x80936414:("EnKusa_DrawBush",), + 0x809365CC:("EnKusa_DrawGrass",), 0x80936CF0:("func_80936CF0",), 0x80936D58:("func_80936D58",), 0x80936F04:("func_80936F04",), @@ -7365,62 +7361,62 @@ 0x8093A3F4:("ObjBombiwa_Update",), 0x8093A418:("func_8093A418",), 0x8093A608:("func_8093A608",), - 0x8093ABD0:("func_8093ABD0",), - 0x8093AC6C:("func_8093AC6C",), - 0x8093ADA8:("func_8093ADA8",), - 0x8093AE1C:("func_8093AE1C",), - 0x8093AE74:("func_8093AE74",), - 0x8093AE88:("func_8093AE88",), - 0x8093AEC4:("func_8093AEC4",), - 0x8093AEF0:("func_8093AEF0",), - 0x8093AF1C:("func_8093AF1C",), - 0x8093AF54:("func_8093AF54",), + 0x8093ABD0:("ObjSwitch_InitJntSphCollider",), + 0x8093AC6C:("ObjSwitch_InitTrisCollider",), + 0x8093ADA8:("ObjSwitch_SpawnIce",), + 0x8093AE1C:("ObjSwitch_SetSwitchFlagState",), + 0x8093AE74:("ObjSwitch_CrystalUpdateTimer",), + 0x8093AE88:("ObjSwitch_StopCutscene",), + 0x8093AEC4:("ObjSwitch_PlayFootSwitchSfx",), + 0x8093AEF0:("ObjSwitch_PlayDiamondSwitchSfx",), + 0x8093AF1C:("ObjSwitch_SetFloorSwitchSnapPlayerState",), + 0x8093AF54:("ObjSwitch_FloorSwitchSnapPlayerToSwitchEdge",), 0x8093B084:("ObjSwitch_Init",), 0x8093B59C:("ObjSwitch_Destroy",), - 0x8093B648:("func_8093B648",), - 0x8093B668:("func_8093B668",), - 0x8093B6F4:("func_8093B6F4",), - 0x8093B710:("func_8093B710",), - 0x8093B92C:("func_8093B92C",), - 0x8093B940:("func_8093B940",), - 0x8093B9C0:("func_8093B9C0",), - 0x8093B9E4:("func_8093B9E4",), - 0x8093BB5C:("func_8093BB5C",), - 0x8093BB70:("func_8093BB70",), - 0x8093BBD0:("func_8093BBD0",), - 0x8093BCC8:("func_8093BCC8",), - 0x8093BCDC:("func_8093BCDC",), - 0x8093BD34:("func_8093BD34",), - 0x8093BD4C:("func_8093BD4C",), - 0x8093BDAC:("func_8093BDAC",), - 0x8093BDC0:("func_8093BDC0",), - 0x8093BE10:("func_8093BE10",), - 0x8093BE2C:("func_8093BE2C",), - 0x8093BEF0:("func_8093BEF0",), - 0x8093BF04:("func_8093BF04",), - 0x8093BF50:("func_8093BF50",), - 0x8093BF70:("func_8093BF70",), - 0x8093C0A4:("func_8093C0A4",), - 0x8093C0B8:("func_8093C0B8",), - 0x8093C138:("func_8093C138",), - 0x8093C15C:("func_8093C15C",), - 0x8093C23C:("func_8093C23C",), - 0x8093C250:("func_8093C250",), - 0x8093C2B4:("func_8093C2B4",), - 0x8093C2D4:("func_8093C2D4",), - 0x8093C3C8:("func_8093C3C8",), - 0x8093C3DC:("func_8093C3DC",), - 0x8093C460:("func_8093C460",), - 0x8093C488:("func_8093C488",), - 0x8093C584:("func_8093C584",), - 0x8093C598:("func_8093C598",), + 0x8093B648:("ObjSwitch_TryPlayCutsceneInit",), + 0x8093B668:("ObjSwitch_TryPlayCutscene",), + 0x8093B6F4:("ObjSwitch_FloorSwitchUpInit",), + 0x8093B710:("ObjSwitch_FloorSwitchUp",), + 0x8093B92C:("ObjSwitch_FloorSwitchPushDownInit",), + 0x8093B940:("ObjSwitch_FloorSwitchPushDown",), + 0x8093B9C0:("ObjSwitch_FloorSwitchDownInit",), + 0x8093B9E4:("ObjSwitch_FloorSwitchDown",), + 0x8093BB5C:("ObjSwitch_FloorSwitchRiseUpInit",), + 0x8093BB70:("ObjSwitch_FloorSwitchRiseUp",), + 0x8093BBD0:("ObjSwitch_IsEyeSwitchHit",), + 0x8093BCC8:("ObjSwitch_EyeSwitchFrozenInit",), + 0x8093BCDC:("ObjSwitch_EyeSwitchUnfrozen",), + 0x8093BD34:("ObjSwitch_EyeSwitchOpenInit",), + 0x8093BD4C:("ObjSwitch_EyeSwitchOpen",), + 0x8093BDAC:("ObjSwitch_EyeSwitchClosingInit",), + 0x8093BDC0:("ObjSwitch_EyeSwitchClosing",), + 0x8093BE10:("ObjSwitch_EyeSwitchClosedInit",), + 0x8093BE2C:("ObjSwitch_EyeSwitchClosed",), + 0x8093BEF0:("ObjSwitch_EyeSwitchOpeningInit",), + 0x8093BF04:("ObjSwitch_EyeSwitchOpening",), + 0x8093BF50:("ObjSwitch_CrystalSwitchOffInit",), + 0x8093BF70:("ObjSwitch_CrystalSwitchOff",), + 0x8093C0A4:("ObjSwitch_CrystalSwitchTurnOnInit",), + 0x8093C0B8:("ObjSwitch_CrystalSwitchTurnOn",), + 0x8093C138:("ObjSwitch_CrystalSwitchOnInit",), + 0x8093C15C:("ObjSwitch_CrystalSwitchOn",), + 0x8093C23C:("ObjSwitch_CrystalSwitchTurnOffInit",), + 0x8093C250:("ObjSwitch_CrystalSwitchTurnOff",), + 0x8093C2B4:("ObjSwitch_LargeFloorSwitchUpInit",), + 0x8093C2D4:("ObjSwitch_LargeFloorSwitchUp",), + 0x8093C3C8:("ObjSwitch_LargeFloorSwitchPushDownInit",), + 0x8093C3DC:("ObjSwitch_LargeFloorSwitchPushDown",), + 0x8093C460:("ObjSwitch_LargeFloorSwitchDownInit",), + 0x8093C488:("ObjSwitch_LargeFloorSwitchDown",), + 0x8093C584:("ObjSwitch_LargeFloorSwitchRiseUpInit",), + 0x8093C598:("ObjSwitch_LargeFloorSwitchRiseUp",), 0x8093C5FC:("ObjSwitch_Update",), - 0x8093C778:("func_8093C778",), - 0x8093C888:("func_8093C888",), - 0x8093C8B8:("func_8093C8B8",), - 0x8093C99C:("func_8093C99C",), - 0x8093CA80:("func_8093CA80",), - 0x8093CAC4:("func_8093CAC4",), + 0x8093C778:("ObjSwitch_DrawFloorSwitch",), + 0x8093C888:("ObjSwitch_DrawRustyFloorSwitch",), + 0x8093C8B8:("ObjSwitch_DrawVisibleEyeSwitch",), + 0x8093C99C:("ObjSwitch_DrawInvisibleEyeSwitch",), + 0x8093CA80:("ObjSwitch_DrawEyeSwitch",), + 0x8093CAC4:("ObjSwitch_DrawCrystalSwitch",), 0x8093CC24:("ObjSwitch_Draw",), 0x8093D3C0:("func_8093D3C0",), 0x8093D628:("ObjLift_Init",), @@ -7513,29 +7509,29 @@ 0x80943BC0:("func_80943BC0",), 0x80943BDC:("func_80943BDC",), 0x80943CA4:("EnDaiku_Update",), - 0x80943E18:("func_80943E18",), - 0x80943E60:("func_80943E60",), + 0x80943E18:("EnDaiku_OverrideLimbDraw",), + 0x80943E60:("EnDaiku_PostLimbDraw",), 0x80943EE4:("EnDaiku_Draw",), 0x809441E0:("EnNwc_Init",), 0x80944310:("EnNwc_Destroy",), - 0x80944320:("func_80944320",), - 0x80944554:("func_80944554",), - 0x80944590:("func_80944590",), - 0x809445D4:("func_809445D4",), - 0x80944630:("func_80944630",), - 0x809447A8:("func_809447A8",), - 0x80944818:("func_80944818",), - 0x809448A4:("func_809448A4",), - 0x809449D0:("func_809449D0",), - 0x80944A50:("func_80944A50",), - 0x80944E44:("func_80944E44",), - 0x80944EFC:("func_80944EFC",), - 0x80944FA8:("func_80944FA8",), - 0x8094506C:("func_8094506C",), + 0x80944320:("EnNwc_SpawnDust",), + 0x80944554:("EnNwc_FindGrog",), + 0x80944590:("EnNwc_PlayerReleasedBremanMarch",), + 0x809445D4:("EnNwc_IsFound",), + 0x80944630:("EnNwc_ChangeState",), + 0x809447A8:("EnNwc_ToggleState",), + 0x80944818:("EnNwc_CheckFound",), + 0x809448A4:("EnNwc_LoadNiwSkeleton",), + 0x809449D0:("EnNwc_CrowAtTheEnd",), + 0x80944A50:("EnNwc_Follow",), + 0x80944E44:("EnNwc_HopForward",), + 0x80944EFC:("EnNwc_RunAway",), + 0x80944FA8:("EnNwc_Turn",), + 0x8094506C:("EnNwc_CheckForBreman",), 0x809450C0:("EnNwc_Update",), 0x809451D8:("EnNwc_Draw",), - 0x8094529C:("func_8094529C",), - 0x80945310:("func_80945310",), + 0x8094529C:("EnNwc_OverrideLimbDraw",), + 0x80945310:("EnNwc_DrawAdultBody",), 0x809454F0:("ItemInbox_Init",), 0x80945524:("ItemInbox_Destroy",), 0x80945534:("ItemInbox_Idle",), @@ -7557,8 +7553,8 @@ 0x80946368:("func_80946368",), 0x80946400:("EnGe1_Draw",), 0x809466A0:("ObjBlockstop_Init",), - 0x809466F0:("func_809466F0",), - 0x809467E8:("func_809467E8",), + 0x809466F0:("ObjBlockstop_CheckForBlock",), + 0x809467E8:("ObjBlockstop_TryPlayCutscene",), 0x8094685C:("ObjBlockstop_Update",), 0x809468D0:("EnSda_Init",), 0x809468E0:("EnSda_Destroy",), @@ -7629,37 +7625,37 @@ 0x809510E4:("EnGm_Init",), 0x80951224:("EnGm_Destroy",), 0x80951264:("EnGm_Update",), - 0x809513AC:("func_809513AC",), - 0x809514BC:("func_809514BC",), - 0x80951594:("func_80951594",), + 0x809513AC:("EnGm_OverrideLimbDraw",), + 0x809514BC:("EnGm_PostLimbDraw",), + 0x80951594:("EnGm_TransformLimbDraw",), 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",), 0x80952CC8:("EnHs_Init",), 0x80952DD0:("EnHs_Destroy",), 0x80952DFC:("func_80952DFC",), - 0x80952E50:("func_80952E50",), + 0x80952E50:("EnHs_UpdateChickPos",), 0x80952F00:("func_80952F00",), 0x80952FE0:("func_80952FE0",), 0x80953098:("func_80953098",), 0x80953180:("func_80953180",), - 0x809532C0:("func_809532C0",), - 0x809532D0:("func_809532D0",), + 0x809532C0:("EnHs_DoNothing",), + 0x809532D0:("EnHs_SceneTransitToBunnyHoodDialogue",), 0x80953354:("func_80953354",), 0x809533A0:("func_809533A0",), 0x8095345C:("func_8095345C",), 0x8095359C:("EnHs_Update",), - 0x8095376C:("func_8095376C",), - 0x80953848:("func_80953848",), + 0x8095376C:("EnHs_OverrideLimbDraw",), + 0x80953848:("EnHs_PostLimbDraw",), 0x80953888:("EnHs_Draw",), - 0x80953A90:("func_80953A90",), + 0x80953A90:("BgIngate_FindActor",), 0x80953B40:("func_80953B40",), 0x80953BEC:("func_80953BEC",), 0x80953DA8:("func_80953DA8",), @@ -7684,13 +7680,13 @@ 0x80956954:("EnKanban_Draw",), 0x809580C0:("EnAttackNiw_Init",), 0x809581F4:("EnAttackNiw_Destroy",), - 0x80958228:("func_80958228",), - 0x809585B0:("func_809585B0",), - 0x80958634:("func_80958634",), - 0x80958974:("func_80958974",), - 0x80958BE4:("func_80958BE4",), + 0x80958228:("EnAttackNiw_AnimateWingHead",), + 0x809585B0:("EnAttackNiw_IsOnScreen",), + 0x80958634:("EnAttackNiw_EnterViewFromOffscreen",), + 0x80958974:("EnAttackNiw_AimAtPlayer",), + 0x80958BE4:("EnAttackNiw_FlyAway",), 0x80958CA8:("EnAttackNiw_Update",), - 0x80958F6C:("func_80958F6C",), + 0x80958F6C:("EnAttackNiw_OverrideLimbDraw",), 0x8095909C:("EnAttackNiw_Draw",), 0x809592E0:("func_809592E0",), 0x80959390:("EnMk_Init",), @@ -7706,8 +7702,8 @@ 0x80959D28:("func_80959D28",), 0x80959E18:("func_80959E18",), 0x8095A028:("EnMk_Update",), - 0x8095A150:("func_8095A150",), - 0x8095A198:("func_8095A198",), + 0x8095A150:("EnMk_OverrideLimbDraw",), + 0x8095A198:("EnMk_PostLimbDraw",), 0x8095A1D8:("EnMk_Draw",), 0x8095A510:("func_8095A510",), 0x8095A560:("EnOwl_Init",), @@ -7892,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",), @@ -7933,23 +7929,23 @@ 0x80967608:("func_80967608",), 0x809676A4:("EnWeatherTag_Update",), 0x80967784:("EnWeatherTag_Draw",), - 0x809679D0:("func_809679D0",), - 0x80967A48:("func_80967A48",), - 0x80967AB4:("func_80967AB4",), + 0x809679D0:("EnAni_DefaultBlink",), + 0x80967A48:("EnAni_WaitForEyeClose",), + 0x80967AB4:("EnAni_WaitForEyeOpen",), 0x80967B1C:("EnAni_Init",), 0x80967CE0:("EnAni_Destroy",), - 0x80967D20:("func_80967D20",), - 0x80967DA0:("func_80967DA0",), - 0x80967DCC:("func_80967DCC",), - 0x80967E34:("func_80967E34",), - 0x80967E90:("func_80967E90",), - 0x80967F20:("func_80967F20",), - 0x80967FA4:("func_80967FA4",), - 0x809680B0:("func_809680B0",), - 0x80968164:("func_80968164",), + 0x80967D20:("EnAni_SetText",), + 0x80967DA0:("EnAni_IdleStanding",), + 0x80967DCC:("EnAni_Talk",), + 0x80967E34:("EnAni_IdleInPain",), + 0x80967E90:("EnAni_FallOverInPain",), + 0x80967F20:("EnAni_LandOnFoot",), + 0x80967FA4:("EnAni_FallToGround",), + 0x809680B0:("EnAni_LoseBalance",), + 0x80968164:("EnAni_HangInTree",), 0x809682A8:("EnAni_Update",), - 0x80968504:("func_80968504",), - 0x8096854C:("func_8096854C",), + 0x80968504:("EnAni_OverrideLimbDraw",), + 0x8096854C:("EnAni_PostLimbDraw",), 0x8096858C:("EnAni_Draw",), 0x809687B0:("EnJs_Init",), 0x809689D4:("EnJs_Destroy",), @@ -7996,14 +7992,14 @@ 0x8096B260:("EnOkarinaEffect_Update",), 0x8096B310:("EnMag_Init",), 0x8096B5F4:("EnMag_Destroy",), - 0x8096B604:("func_8096B604",), + 0x8096B604:("EnMag_UpdateDisplayEffectColors",), 0x8096B94C:("EnMag_Update",), - 0x8096C998:("func_8096C998",), - 0x8096CBB0:("func_8096CBB0",), - 0x8096CDC8:("func_8096CDC8",), - 0x8096D230:("func_8096D230",), - 0x8096D60C:("func_8096D60C",), - 0x8096D74C:("func_8096D74C",), + 0x8096C998:("EnMag_DrawTextureI8",), + 0x8096CBB0:("EnMag_DrawTextureIA8",), + 0x8096CDC8:("EnMag_DrawEffectTextures",), + 0x8096D230:("EnMag_DrawImageRGBA32",), + 0x8096D60C:("EnMag_DrawCharTexture",), + 0x8096D74C:("EnMag_DrawInner",), 0x8096E868:("EnMag_Draw",), 0x8096EC40:("ElfMsg2_SetupAction",), 0x8096EC4C:("func_8096EC4C",), @@ -8020,37 +8016,37 @@ 0x8096F4DC:("BgF40Swlift_Draw",), 0x8096F5E0:("EnKakasi_Destroy",), 0x8096F60C:("EnKakasi_Init",), - 0x8096F800:("func_8096F800",), - 0x8096F88C:("func_8096F88C",), + 0x8096F800:("EnKakasi_SetAnimation",), + 0x8096F88C:("EnKakasi_8096F88C",), 0x8096F8D8:("func_8096F8D8",), 0x8096FA18:("func_8096FA18",), 0x8096FAAC:("func_8096FAAC",), 0x8096FBB8:("func_8096FBB8",), - 0x8096FC8C:("func_8096FC8C",), - 0x8096FCC4:("func_8096FCC4",), - 0x8096FDE8:("func_8096FDE8",), - 0x8096FE00:("func_8096FE00",), - 0x80970008:("func_80970008",), - 0x8097006C:("func_8097006C",), + 0x8096FC8C:("EnKakasi_InitTimeSkipDialogue",), + 0x8096FCC4:("EnKakasi_TimeSkipDialogue",), + 0x8096FDE8:("EnKakasi_SetupIdleStanding",), + 0x8096FE00:("EnKakasi_IdleStanding",), + 0x80970008:("EnKakasi_SetupDialogue",), + 0x8097006C:("EnKakasi_RegularDialogue",), 0x809705E4:("func_809705E4",), 0x80970658:("func_80970658",), 0x80970740:("func_80970740",), 0x80970978:("func_80970978",), - 0x80970A10:("func_80970A10",), - 0x80970A9C:("func_80970A9C",), - 0x80970F20:("func_80970F20",), - 0x80970FF8:("func_80970FF8",), - 0x80971064:("func_80971064",), - 0x80971430:("func_80971430",), + 0x80970A10:("EnKakasi_SetupPostSongLearnDialogue",), + 0x80970A9C:("EnKakasi_PostSongLearnDialogue",), + 0x80970F20:("EnKakasi_DancingRemark",), + 0x80970FF8:("EnKakasi_SetupDanceNightAway",), + 0x80971064:("EnKakasi_DancingNightAway",), + 0x80971430:("EnKakasi_DoNothing",), 0x80971440:("func_80971440",), 0x809714BC:("func_809714BC",), 0x80971794:("func_80971794",), 0x809717D0:("func_809717D0",), - 0x8097185C:("func_8097185C",), - 0x8097193C:("func_8097193C",), - 0x80971A38:("func_80971A38",), - 0x80971A64:("func_80971A64",), - 0x80971AD4:("func_80971AD4",), + 0x8097185C:("EnKakasi_SetupRiseOutOfGround",), + 0x8097193C:("EnKakasi_RisingOutOfGround",), + 0x80971A38:("EnKakasi_SetupIdleRisen",), + 0x80971A64:("EnKakasi_IdleRisen",), + 0x80971AD4:("EnKakasi_RisenDialogue",), 0x80971B48:("EnKakasi_Update",), 0x80971CE0:("func_80971CE0",), 0x80971D20:("EnKakasi_Draw",), @@ -8081,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",), @@ -8169,7 +8165,7 @@ 0x8097A548:("EffectSsGFire_Draw",), 0x8097A5F0:("EffectSsGFire_Update",), 0x8097A680:("EffectSsLightning_Init",), - 0x8097A794:("func_8097A794",), + 0x8097A794:("EffectSsLightning_NewLightning",), 0x8097A838:("EffectSsLightning_Draw",), 0x8097AA98:("EffectSsLightning_Update",), 0x8097AD60:("EffectSsDtBubble_Init",), @@ -8205,7 +8201,7 @@ 0x8097DCA0:("EffectSsKakera_Init",), 0x8097DE30:("func_8097DE30",), 0x8097DE6C:("EffectSsKakera_Draw",), - 0x8097E130:("func_8097E130",), + 0x8097E130:("EffectSsKakera_CheckForObject",), 0x8097E19C:("func_8097E19C",), 0x8097E34C:("func_8097E34C",), 0x8097E368:("func_8097E368",), @@ -8355,8 +8351,8 @@ 0x8098BCA8:("EnDg_Init",), 0x8098BE18:("EnDg_Destroy",), 0x8098BE44:("EnDg_Update",), - 0x8098BFB8:("func_8098BFB8",), - 0x8098BFD4:("func_8098BFD4",), + 0x8098BFB8:("EnDg_OverrideLimbDraw",), + 0x8098BFD4:("EnDg_PostLimbDraw",), 0x8098C06C:("EnDg_Draw",), 0x8098CA20:("func_8098CA20",), 0x8098CAD0:("func_8098CAD0",), @@ -8433,7 +8429,7 @@ 0x80990784:("EnWf_Destroy",), 0x809907D4:("func_809907D4",), 0x80990854:("func_80990854",), - 0x809908E0:("func_809908E0",), + 0x809908E0:("EnWf_Blink",), 0x80990948:("func_80990948",), 0x80990C6C:("func_80990C6C",), 0x80990E4C:("func_80990E4C",), @@ -8482,8 +8478,8 @@ 0x80993738:("func_80993738",), 0x8099386C:("func_8099386C",), 0x80993BC0:("EnWf_Update",), - 0x80993E50:("func_80993E50",), - 0x80993E94:("func_80993E94",), + 0x80993E50:("EnWf_OverrideLimbDraw",), + 0x80993E94:("EnWf_PostLimbDraw",), 0x80993F68:("EnWf_Draw",), 0x8099408C:("func_8099408C",), 0x809947B0:("func_809947B0",), @@ -8577,23 +8573,23 @@ 0x8099AA84:("func_8099AA84",), 0x8099AB30:("EnCrow_Init",), 0x8099AC2C:("EnCrow_Destroy",), - 0x8099AC58:("func_8099AC58",), - 0x8099AC8C:("func_8099AC8C",), - 0x8099B098:("func_8099B098",), - 0x8099B0CC:("func_8099B0CC",), - 0x8099B318:("func_8099B318",), - 0x8099B384:("func_8099B384",), - 0x8099B584:("func_8099B584",), - 0x8099B6AC:("func_8099B6AC",), - 0x8099B6C4:("func_8099B6C4",), - 0x8099B778:("func_8099B778",), - 0x8099B838:("func_8099B838",), - 0x8099B8EC:("func_8099B8EC",), - 0x8099B9E8:("func_8099B9E8",), - 0x8099BAB4:("func_8099BAB4",), + 0x8099AC58:("EnCrow_SetupFlyIdle",), + 0x8099AC8C:("EnCrow_FlyIdle",), + 0x8099B098:("EnCrow_SetupDiveAttack",), + 0x8099B0CC:("EnCrow_DiveAttack",), + 0x8099B318:("EnCrow_CheckIfFrozen",), + 0x8099B384:("EnCrow_SetupDamaged",), + 0x8099B584:("EnCrow_Damaged",), + 0x8099B6AC:("EnCrow_SetupDie",), + 0x8099B6C4:("EnCrow_Die",), + 0x8099B778:("EnCrow_SetupTurnAway",), + 0x8099B838:("EnCrow_TurnAway",), + 0x8099B8EC:("EnCrow_SetupRespawn",), + 0x8099B9E8:("EnCrow_Respawn",), + 0x8099BAB4:("EnCrow_UpdateDamage",), 0x8099BB84:("EnCrow_Update",), - 0x8099BE48:("func_8099BE48",), - 0x8099BF20:("func_8099BF20",), + 0x8099BE48:("EnCrow_OverrideLimbDraw",), + 0x8099BF20:("EnCrow_PostLimbDraw",), 0x8099BFA4:("EnCrow_Draw",), 0x8099C290:("func_8099C290",), 0x8099C328:("func_8099C328",), @@ -8619,20 +8615,20 @@ 0x8099D7DC:("OceffWipe4_Destroy",), 0x8099D810:("OceffWipe4_Update",), 0x8099D870:("OceffWipe4_Draw",), - 0x8099E790:("func_8099E790",), - 0x8099E858:("func_8099E858",), - 0x8099E96C:("func_8099E96C",), - 0x8099E9E0:("func_8099E9E0",), - 0x8099EA60:("func_8099EA60",), - 0x8099EBD8:("func_8099EBD8",), - 0x8099EC50:("func_8099EC50",), - 0x8099ED4C:("func_8099ED4C",), - 0x8099EE24:("func_8099EE24",), + 0x8099E790:("EnZo_SetAnimation",), + 0x8099E858:("EnZo_PlayWalkingSound",), + 0x8099E96C:("EnZo_Blink",), + 0x8099E9E0:("EnZo_UpdateCollider",), + 0x8099EA60:("EnZo_LookAtPlayer",), + 0x8099EBD8:("EnZo_Walk",), + 0x8099EC50:("EnZo_FollowPath",), + 0x8099ED4C:("EnZo_TreadWater",), + 0x8099EE24:("EnZo_DoNothing",), 0x8099EE34:("EnZo_Init",), 0x8099EF40:("EnZo_Destroy",), 0x8099EF6C:("EnZo_Update",), - 0x8099EFF4:("func_8099EFF4",), - 0x8099F15C:("func_8099F15C",), + 0x8099EFF4:("EnZo_OverrideLimbDraw",), + 0x8099F15C:("EnZo_PostLimbDraw",), 0x8099F268:("EnZo_Draw",), 0x8099F730:("EffectSsIceSmoke_Init",), 0x8099F7F4:("EffectSsIceSmoke_Draw",), @@ -8682,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",), @@ -8993,14 +8989,14 @@ 0x809BD858:("func_809BD858",), 0x809C0760:("EnWarptag_Init",), 0x809C0824:("EnWarptag_Destroy",), - 0x809C085C:("func_809C085C",), - 0x809C08E0:("func_809C08E0",), - 0x809C09A0:("func_809C09A0",), - 0x809C0A20:("func_809C0A20",), - 0x809C0AB4:("func_809C0AB4",), - 0x809C0E30:("func_809C0E30",), + 0x809C085C:("EnWarpTag_CheckDungeonKeepObject",), + 0x809C08E0:("EnWarpTag_WaitForPlayer",), + 0x809C09A0:("EnWarpTag_Unused809C09A0",), + 0x809C0A20:("EnWarpTag_Unused809C0A20",), + 0x809C0AB4:("EnWarpTag_RespawnPlayer",), + 0x809C0E30:("EnWarpTag_GrottoReturn",), 0x809C0F18:("EnWarptag_Update",), - 0x809C0F3C:("func_809C0F3C",), + 0x809C0F3C:("EnWarpTag_Draw",), 0x809C10B0:("func_809C10B0",), 0x809C1124:("func_809C1124",), 0x809C1158:("func_809C1158",), @@ -9035,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_TransformLimbDraw",), 0x809C3608:("EnAob01_Draw",), 0x809C3D80:("EnBoj01_Init",), 0x809C3D90:("EnBoj01_Destroy",), @@ -9082,7 +9078,7 @@ 0x809C5BA0:("func_809C5BA0",), 0x809C5BF4:("func_809C5BF4",), 0x809C5E14:("EnBomBowlMan_Update",), - 0x809C5F44:("func_809C5F44",), + 0x809C5F44:("EnBomBowlMan_OverrideLimbDraw",), 0x809C5FC4:("EnBomBowlMan_Draw",), 0x809C64C0:("func_809C64C0",), 0x809C6578:("EnSyatekiMan_Init",), @@ -9111,7 +9107,7 @@ 0x809C8808:("func_809C8808",), 0x809C898C:("func_809C898C",), 0x809C8BF0:("func_809C8BF0",), - 0x809C8DE8:("func_809C8DE8",), + 0x809C8DE8:("EnSyatekiMan_Blink",), 0x809C8E44:("EnSyatekiMan_Update",), 0x809C8EE4:("EnSyatekiMan_OverrideLimbDraw",), 0x809C8FAC:("EnSyatekiMan_PostLimbDraw",), @@ -9138,40 +9134,40 @@ 0x809CABC0:("func_809CABC0",), 0x809CACD0:("func_809CACD0",), 0x809CADE8:("EnSyatekiCrow_Update",), - 0x809CAE5C:("func_809CAE5C",), - 0x809CAF2C:("func_809CAF2C",), + 0x809CAE5C:("EnSyatekiCrow_OverrideLimbDraw",), + 0x809CAF2C:("EnSyatekiCrow_PostLimbDraw",), 0x809CAFEC:("EnSyatekiCrow_Draw",), 0x809CB200:("EnBoj04_Init",), 0x809CB210:("EnBoj04_Destroy",), 0x809CB220:("EnBoj04_Update",), 0x809CB230:("EnBoj04_Draw",), - 0x809CB290:("func_809CB290",), - 0x809CB404:("func_809CB404",), + 0x809CB290:("EnCne01_UpdateModel",), + 0x809CB404:("EnCne01_TestIsTalking",), 0x809CB4A0:("func_809CB4A0",), - 0x809CB520:("func_809CB520",), - 0x809CB5A0:("func_809CB5A0",), - 0x809CB5D8:("func_809CB5D8",), - 0x809CB5FC:("func_809CB5FC",), + 0x809CB520:("EnCne01_FinishInit",), + 0x809CB5A0:("EnCne01_Walk",), + 0x809CB5D8:("EnCne01_FaceForward",), + 0x809CB5FC:("EnCne01_Talk",), 0x809CB72C:("EnCne01_Init",), 0x809CB86C:("EnCne01_Destroy",), 0x809CB898:("EnCne01_Update",), - 0x809CB920:("func_809CB920",), - 0x809CBBC8:("func_809CBBC8",), - 0x809CBCA0:("func_809CBCA0",), + 0x809CB920:("EnCne01_OverrideLimbDraw",), + 0x809CBBC8:("EnCne01_PostLimbDraw",), + 0x809CBCA0:("EnCne01_TransformLimbDraw",), 0x809CBCB4:("EnCne01_Draw",), - 0x809CC060:("func_809CC060",), - 0x809CC1D4:("func_809CC1D4",), + 0x809CC060:("EnBba01_UpdateModel",), + 0x809CC1D4:("EnBba01_TestIsTalking",), 0x809CC270:("func_809CC270",), - 0x809CC2F0:("func_809CC2F0",), - 0x809CC370:("func_809CC370",), - 0x809CC3A8:("func_809CC3A8",), - 0x809CC3CC:("func_809CC3CC",), + 0x809CC2F0:("EnBba01_FinishInit",), + 0x809CC370:("EnBba01_Walk",), + 0x809CC3A8:("EnBba01_FaceFoward",), + 0x809CC3CC:("EnBba01_Talk",), 0x809CC4FC:("EnBba01_Init",), 0x809CC63C:("EnBba01_Destroy",), 0x809CC668:("EnBba01_Update",), - 0x809CC6F0:("func_809CC6F0",), - 0x809CC984:("func_809CC984",), - 0x809CCA5C:("func_809CCA5C",), + 0x809CC6F0:("EnBba01_OverrideLimbDraw",), + 0x809CC984:("EnBba01_PostLimbDraw",), + 0x809CCA5C:("EnBba01_TransformLimbDraw",), 0x809CCA70:("EnBba01_Draw",), 0x809CCDE0:("func_809CCDE0",), 0x809CCE98:("func_809CCE98",), @@ -9202,22 +9198,22 @@ 0x809CEEAC:("func_809CEEAC",), 0x809CEF0C:("BgSpdweb_Update",), 0x809CEF30:("BgSpdweb_Draw",), - 0x809CF350:("func_809CF350",), - 0x809CF394:("func_809CF394",), - 0x809CF444:("func_809CF444",), - 0x809CF4EC:("func_809CF4EC",), - 0x809CF67C:("func_809CF67C",), - 0x809CF848:("func_809CF848",), - 0x809CF8EC:("func_809CF8EC",), - 0x809CF950:("func_809CF950",), - 0x809CF9A0:("func_809CF9A0",), - 0x809CFA00:("func_809CFA00",), - 0x809CFA54:("func_809CFA54",), - 0x809CFBC4:("func_809CFBC4",), - 0x809CFC38:("func_809CFC38",), - 0x809CFD98:("func_809CFD98",), - 0x809CFE28:("func_809CFE28",), - 0x809CFF94:("func_809CFF94",), + 0x809CF350:("EnMttag_IsInFinishLine",), + 0x809CF394:("EnMttag_CheckPlayerCheatStatus",), + 0x809CF444:("EnMttag_AreFourRaceGoronsPresent",), + 0x809CF4EC:("EnMttag_GetCurrentCheckpoint",), + 0x809CF67C:("EnMttag_UpdateCheckpoints",), + 0x809CF848:("EnMttag_ExitRace",), + 0x809CF8EC:("EnMttag_ShowFalseStartMessage",), + 0x809CF950:("EnMttag_ShowCantWinMessage",), + 0x809CF9A0:("EnMttag_ShowIntroCutscene",), + 0x809CFA00:("EnMttag_WaitForIntroCutsceneToEnd",), + 0x809CFA54:("EnMttag_RaceStart",), + 0x809CFBC4:("EnMttag_IsAnyRaceGoronOverFinishLine",), + 0x809CFC38:("EnMttag_Race",), + 0x809CFD98:("EnMttag_RaceFinish",), + 0x809CFE28:("EnMttag_PotentiallyRestartRace",), + 0x809CFF94:("EnMttag_HandleCantWinChoice",), 0x809D0090:("EnMttag_Init",), 0x809D0138:("EnMttag_Destroy",), 0x809D0168:("EnMttag_Update",), @@ -9319,52 +9315,52 @@ 0x809DD2F8:("func_809DD2F8",), 0x809DD934:("func_809DD934",), 0x809DEAC4:("func_809DEAC4",), - 0x809E2760:("func_809E2760",), - 0x809E2788:("func_809E2788",), - 0x809E2880:("func_809E2880",), - 0x809E299C:("func_809E299C",), - 0x809E2AB4:("func_809E2AB4",), - 0x809E2B8C:("func_809E2B8C",), - 0x809E2C1C:("func_809E2C1C",), - 0x809E2C3C:("func_809E2C3C",), - 0x809E2D64:("func_809E2D64",), - 0x809E2DA0:("func_809E2DA0",), + 0x809E2760:("Boss03_PlayUnderwaterSfx",), + 0x809E2788:("Boss03_SpawnEffectWetSpot",), + 0x809E2880:("Boss03_SpawnEffectDroplet",), + 0x809E299C:("Boss03_SpawnEffectSplash",), + 0x809E2AB4:("Boss03_SpawnEffectBubble",), + 0x809E2B8C:("Boss03_UpdateSphereElement",), + 0x809E2C1C:("Boss03_SeedRand",), + 0x809E2C3C:("Boss03_RandZeroOne",), + 0x809E2D64:("Boss03_FindActorDblueMovebg",), + 0x809E2DA0:("Boss03_SpawnDust",), 0x809E2F7C:("Boss03_Init",), 0x809E343C:("Boss03_Destroy",), 0x809E344C:("func_809E344C",), 0x809E34B8:("func_809E34B8",), - 0x809E38EC:("func_809E38EC",), - 0x809E3968:("func_809E3968",), - 0x809E3D34:("func_809E3D34",), - 0x809E3D98:("func_809E3D98",), - 0x809E4180:("func_809E4180",), - 0x809E421C:("func_809E421C",), - 0x809E4674:("func_809E4674",), - 0x809E475C:("func_809E475C",), - 0x809E4910:("func_809E4910",), - 0x809E497C:("func_809E497C",), - 0x809E4C34:("func_809E4C34",), - 0x809E4C90:("func_809E4C90",), - 0x809E4E2C:("func_809E4E2C",), - 0x809E4E80:("func_809E4E80",), - 0x809E5ADC:("func_809E5ADC",), - 0x809E5B64:("func_809E5B64",), - 0x809E65F4:("func_809E65F4",), - 0x809E6640:("func_809E6640",), - 0x809E69A4:("func_809E69A4",), - 0x809E6A38:("func_809E6A38",), - 0x809E6B70:("func_809E6B70",), - 0x809E6BC0:("func_809E6BC0",), - 0x809E6CB4:("func_809E6CB4",), + 0x809E38EC:("Boss03_SetupChasePlayer",), + 0x809E3968:("Boss03_ChasePlayer",), + 0x809E3D34:("Boss03_SetupCatchPlayer",), + 0x809E3D98:("Boss03_CatchPlayer",), + 0x809E4180:("Boss03_SetupChewPlayer",), + 0x809E421C:("Boss03_ChewPlayer",), + 0x809E4674:("Boss03_SetupPrepareCharge",), + 0x809E475C:("Boss03_PrepareCharge",), + 0x809E4910:("Boss03_SetupCharge",), + 0x809E497C:("Boss03_Charge",), + 0x809E4C34:("Boss03_SetupJumpOverPlatform",), + 0x809E4C90:("Boss03_JumpOverPlatform",), + 0x809E4E2C:("Boss03_SetupIntroCutscene",), + 0x809E4E80:("Boss03_IntroCutscene",), + 0x809E5ADC:("Boss03_SetupDeathCutscene",), + 0x809E5B64:("Boss03_DeathCutscene",), + 0x809E65F4:("Boss03_SetupSpawnSmallFishesCutscene",), + 0x809E6640:("Boss03_SpawnSmallFishesCutscene",), + 0x809E69A4:("Boss03_SetupStunned",), + 0x809E6A38:("Boss03_Stunned",), + 0x809E6B70:("Boss03_SetupDamaged",), + 0x809E6BC0:("Boss03_Damaged",), + 0x809E6CB4:("Boss03_UpdateCollision",), 0x809E70EC:("Boss03_Update",), - 0x809E7920:("func_809E7920",), - 0x809E79C4:("func_809E79C4",), - 0x809E7AA8:("func_809E7AA8",), + 0x809E7920:("Boss03_SetObject",), + 0x809E79C4:("Boss03_OverrideLimbDraw",), + 0x809E7AA8:("Boss03_PostLimbDraw",), 0x809E7C0C:("Boss03_Draw",), - 0x809E7D00:("func_809E7D00",), - 0x809E81E4:("func_809E81E4",), - 0x809E8810:("func_809E8810",), - 0x809E8BEC:("func_809E8BEC",), + 0x809E7D00:("Boss03_UpdateEffects",), + 0x809E81E4:("Boss03_DrawEffects",), + 0x809E8810:("Boss03_SeaweedUpdate",), + 0x809E8BEC:("Boss03_SeaweedDraw",), 0x809EC040:("func_809EC040",), 0x809EC0D0:("Boss04_Init",), 0x809EC534:("Boss04_Destroy",), @@ -9379,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",), @@ -9456,11 +9452,11 @@ 0x809F5494:("func_809F5494",), 0x809F552C:("Boss07_Init",), 0x809F5DA0:("Boss07_Destroy",), - 0x809F5E14:("func_809F5E14",), + 0x809F5E14:("Boss07_Wrath_SetupIntro",), 0x809F5E88:("func_809F5E88",), 0x809F64F4:("func_809F64F4",), 0x809F65F4:("func_809F65F4",), - 0x809F7400:("func_809F7400",), + 0x809F7400:("Boss07_Wrath_SetupIdle",), 0x809F748C:("func_809F748C",), 0x809F7688:("func_809F7688",), 0x809F76D0:("func_809F76D0",), @@ -9609,7 +9605,7 @@ 0x80A0C938:("EnSob1_GetTalkOption",), 0x80A0CA38:("EnSob1_GetWelcome",), 0x80A0CC88:("EnSob1_GetGoodbye",), - 0x80A0CCEC:("EnSob1_EndInteractionBombShop",), + 0x80A0CCEC:("EnSob1_BombShopkeeper_EndInteraction",), 0x80A0CD48:("EnSob1_SpawnShopItems",), 0x80A0CE10:("EnSob1_GetObjIndices",), 0x80A0CED4:("EnSob1_Init",), @@ -9658,27 +9654,27 @@ 0x80A0EEC8:("EnSob1_UpdateItemSelectedProperty",), 0x80A0EF48:("EnSob1_UpdateCursorAnim",), 0x80A0F014:("EnSob1_UpdateStickDirectionPromptAnim",), - 0x80A0F1C4:("EnSob1_GetXZAngleAndDistanceSqToPoint",), + 0x80A0F1C4:("EnSob1_GetDistSqAndOrient",), 0x80A0F284:("EnSob1_GetCutscenes",), 0x80A0F2C8:("EnSob1_WaitForBlink",), 0x80A0F2FC:("EnSob1_Blink",), 0x80A0F39C:("EnSob1_ChangeObject",), 0x80A0F3D4:("EnSob1_AreObjectsLoaded",), - 0x80A0F470:("EnSob1_InitZoraShopkeeper",), - 0x80A0F554:("EnSob1_InitGoronShopkeeper",), - 0x80A0F638:("EnSob1_InitBombShopkeeper",), + 0x80A0F470:("EnSob1_ZoraShopkeeper_Init",), + 0x80A0F554:("EnSob1_GoronShopkeeper_Init",), + 0x80A0F638:("EnSob1_BombShopkeeper_Init",), 0x80A0F6B0:("EnSob1_InitShop",), 0x80A0FA0C:("EnSob1_Update",), 0x80A0FADC:("EnSob1_DrawCursor",), 0x80A0FD4C:("EnSob1_DrawTextRec",), 0x80A0FEE8:("EnSob1_DrawStickDirectionPrompt",), - 0x80A10290:("EnSob1_OverrideLimbDrawZoraShopkeeper",), - 0x80A102C8:("EnSob1_OverrideLimbDrawBombShopkeeper",), - 0x80A10308:("EnSob1_PostLimbDrawBombShopkeeper",), + 0x80A10290:("EnSob1_ZoraShopkeeper_OverrideLimbDraw",), + 0x80A102C8:("EnSob1_BombShopkeeper_OverrideLimbDraw",), + 0x80A10308:("EnSob1_BombShopkeeper_PostLimbDraw",), 0x80A10344:("EnSob1_EndDList",), - 0x80A10368:("EnSob1_DrawZoraShopkeeper",), - 0x80A104E4:("EnSob1_DrawGoronShopkeeper",), - 0x80A10608:("EnSob1_DrawBombShopkeeper",), + 0x80A10368:("EnSob1_ZoraShopkeeper_Draw",), + 0x80A104E4:("EnSob1_GoronShopkeeper_Draw",), + 0x80A10608:("EnSob1_BombShopkeeper_Draw",), 0x80A10FD0:("func_80A10FD0",), 0x80A11144:("func_80A11144",), 0x80A1143C:("func_80A1143C",), @@ -9746,36 +9742,36 @@ 0x80A15960:("EnGo_Destroy",), 0x80A159B0:("EnGo_Update",), 0x80A15B80:("func_80A15B80",), - 0x80A15D04:("func_80A15D04",), - 0x80A15E38:("func_80A15E38",), + 0x80A15D04:("EnGo_OverrideLimbDraw",), + 0x80A15E38:("EnGo_TransfromLimbDraw",), 0x80A15FEC:("func_80A15FEC",), - 0x80A16D40:("func_80A16D40",), - 0x80A16D6C:("func_80A16D6C",), + 0x80A16D40:("EnRaf_ClearPixelTeeth",), + 0x80A16D6C:("EnRaf_ClearPixelPetal",), 0x80A16D90:("EnRaf_Init",), 0x80A17018:("EnRaf_Destroy",), - 0x80A17060:("func_80A17060",), - 0x80A1712C:("func_80A1712C",), - 0x80A171D8:("func_80A171D8",), - 0x80A17414:("func_80A17414",), - 0x80A17464:("func_80A17464",), - 0x80A17530:("func_80A17530",), - 0x80A175E4:("func_80A175E4",), - 0x80A17848:("func_80A17848",), - 0x80A178A0:("func_80A178A0",), - 0x80A179C8:("func_80A179C8",), - 0x80A17C6C:("func_80A17C6C",), - 0x80A17D14:("func_80A17D14",), - 0x80A17D54:("func_80A17D54",), - 0x80A17DDC:("func_80A17DDC",), - 0x80A17E1C:("func_80A17E1C",), - 0x80A18080:("func_80A18080",), - 0x80A180B4:("func_80A180B4",), + 0x80A17060:("EnRaf_ChangeAnimation",), + 0x80A1712C:("EnRaf_SetupIdle",), + 0x80A171D8:("EnRaf_Idle",), + 0x80A17414:("EnRaf_SetupGrab",), + 0x80A17464:("EnRaf_Grab",), + 0x80A17530:("EnRaf_SetupChew",), + 0x80A175E4:("EnRaf_Chew",), + 0x80A17848:("EnRaf_SetupThrow",), + 0x80A178A0:("EnRaf_Throw",), + 0x80A179C8:("EnRaf_Explode",), + 0x80A17C6C:("EnRaf_PostDetonation",), + 0x80A17D14:("EnRaf_SetupConvulse",), + 0x80A17D54:("EnRaf_Convulse",), + 0x80A17DDC:("EnRaf_SetupDissolve",), + 0x80A17E1C:("EnRaf_Dissolve",), + 0x80A18080:("EnRaf_SetupDormant",), + 0x80A180B4:("EnRaf_Dormant",), 0x80A181B4:("EnRaf_Update",), - 0x80A1859C:("func_80A1859C",), + 0x80A1859C:("EnRaf_TransformLimbDraw",), 0x80A18A08:("EnRaf_Draw",), - 0x80A18A90:("func_80A18A90",), - 0x80A18B8C:("func_80A18B8C",), - 0x80A18DA0:("func_80A18DA0",), + 0x80A18A90:("EnRaf_InitializeParticle",), + 0x80A18B8C:("EnRaf_UpdateParticles",), + 0x80A18DA0:("EnRaf_DrawParticles",), 0x80A19740:("ObjFunen_Init",), 0x80A19778:("ObjFunen_Draw",), 0x80A19910:("ObjRaillift_UpdatePosition",), @@ -9791,23 +9787,23 @@ 0x80A1A220:("ObjRaillift_Draw",), 0x80A1A330:("ObjRaillift_DrawDekuFlowerPlatform",), 0x80A1A360:("ObjRaillift_DrawDekuFlowerPlatformColorful",), - 0x80A1A500:("func_80A1A500",), - 0x80A1A56C:("func_80A1A56C",), - 0x80A1A750:("func_80A1A750",), + 0x80A1A500:("BgNumaHana_SpawnOpenFlowerCollisionChild",), + 0x80A1A56C:("BgNumaHana_UpdatePetalPosRots",), + 0x80A1A750:("BgNumaHana_UpdateSettleRotation",), 0x80A1A7CC:("BgNumaHana_Init",), 0x80A1A9AC:("BgNumaHana_Destroy",), - 0x80A1AA14:("func_80A1AA14",), - 0x80A1AA28:("func_80A1AA28",), - 0x80A1AA38:("func_80A1AA38",), - 0x80A1AA4C:("func_80A1AA4C",), - 0x80A1AAE8:("func_80A1AAE8",), - 0x80A1AB00:("func_80A1AB00",), - 0x80A1ABD8:("func_80A1ABD8",), - 0x80A1ABF0:("func_80A1ABF0",), - 0x80A1ACCC:("func_80A1ACCC",), - 0x80A1ACE0:("func_80A1ACE0",), - 0x80A1AE08:("func_80A1AE08",), - 0x80A1AE1C:("func_80A1AE1C",), + 0x80A1AA14:("BgNumaHana_SetupDoNothing",), + 0x80A1AA28:("BgNumaHana_DoNothing",), + 0x80A1AA38:("BgNumaHana_SetupClosedIdle",), + 0x80A1AA4C:("BgNumaHana_ClosedIdle",), + 0x80A1AAE8:("BgNumaHana_SetupUnfoldInnerPetals",), + 0x80A1AB00:("BgNumaHana_UnfoldInnerPetals",), + 0x80A1ABD8:("BgNumaHana_SetupUnfoldOuterPetals",), + 0x80A1ABF0:("BgNumaHana_UnfoldOuterPetals",), + 0x80A1ACCC:("BgNumaHana_SetupRaiseFlower",), + 0x80A1ACE0:("BgNumaHana_RaiseFlower",), + 0x80A1AE08:("BgNumaHana_SetupOpenedIdle",), + 0x80A1AE1C:("BgNumaHana_OpenedIdle",), 0x80A1AE6C:("BgNumaHana_Update",), 0x80A1AF68:("BgNumaHana_Draw",), 0x80A1B3D0:("func_80A1B3D0",), @@ -9896,8 +9892,8 @@ 0x80A20858:("func_80A20858",), 0x80A208F8:("func_80A208F8",), 0x80A20A50:("EnSyatekiWf_Update",), - 0x80A20CF4:("func_80A20CF4",), - 0x80A20D10:("func_80A20D10",), + 0x80A20CF4:("EnSyatekiWf_OverrideLimbDraw",), + 0x80A20D10:("EnSyatekiWf_PostLimbDraw",), 0x80A20DA4:("EnSyatekiWf_Draw",), 0x80A21150:("func_80A21150",), 0x80A211F4:("func_80A211F4",), @@ -9929,7 +9925,7 @@ 0x80A227C0:("func_80A227C0",), 0x80A22880:("ObjSkateblock_Update",), 0x80A228D8:("ObjSkateblock_Draw",), - 0x80A22D40:("func_80A22D40",), + 0x80A22D40:("EffectEnIceBlock_CheckIceBlockObject",), 0x80A22DB8:("EffectEnIceBlock_Init",), 0x80A22E94:("EffectEnIceBlock_Draw",), 0x80A22FE4:("EffectEnIceBlock_Update",), @@ -9967,8 +9963,8 @@ 0x80A25440:("func_80A25440",), 0x80A25598:("ObjIceblock_Init",), 0x80A25758:("ObjIceblock_Destroy",), - 0x80A257A0:("func_80A257A0",), - 0x80A257B4:("func_80A257B4",), + 0x80A257A0:("ObjIceBlock_SetupAttemptSpawnCutscene",), + 0x80A257B4:("ObjIceBlock_AttemptSpawnCutscene",), 0x80A25824:("func_80A25824",), 0x80A2586C:("func_80A2586C",), 0x80A25978:("func_80A25978",), @@ -10085,7 +10081,7 @@ 0x80A2C4D0:("func_80A2C4D0",), 0x80A2C5DC:("func_80A2C5DC",), 0x80A2C78C:("EnSyatekiDekunuts_Update",), - 0x80A2C8A0:("func_80A2C8A0",), + 0x80A2C8A0:("EnSyatekiDekunuts_OverrideLimbDraw",), 0x80A2C8E8:("EnSyatekiDekunuts_Draw",), 0x80A2CD10:("ElfMsg3_SetupAction",), 0x80A2CD1C:("func_80A2CD1C",), @@ -10122,9 +10118,9 @@ 0x80A2EAAC:("DmSa_Destroy",), 0x80A2EABC:("DmSa_DoNothing",), 0x80A2EACC:("DmSa_Update",), - 0x80A2EB10:("func_80A2EB10",), - 0x80A2EB2C:("func_80A2EB2C",), - 0x80A2EB44:("func_80A2EB44",), + 0x80A2EB10:("DmSa_OverrideLimbDraw",), + 0x80A2EB2C:("DmSa_PostLimbDraw",), + 0x80A2EB44:("DmSa_TransformLimbDraw",), 0x80A2EB58:("func_80A2EB58",), 0x80A2EBB0:("func_80A2EBB0",), 0x80A2EBE8:("DmSa_Draw",), @@ -10190,8 +10186,8 @@ 0x80A32F48:("func_80A32F48",), 0x80A33098:("func_80A33098",), 0x80A331C4:("EnPr_Update",), - 0x80A3357C:("func_80A3357C",), - 0x80A335B4:("func_80A335B4",), + 0x80A3357C:("EnPr_OverrideLimbDraw",), + 0x80A335B4:("EnPr_PostLimbDraw",), 0x80A336C0:("EnPr_Draw",), 0x80A33B00:("func_80A33B00",), 0x80A33BB4:("func_80A33BB4",), @@ -10242,7 +10238,7 @@ 0x80A36B9C:("EnSyatekiOkuta_Update",), 0x80A36CB0:("func_80A36CB0",), 0x80A370EC:("func_80A370EC",), - 0x80A37294:("func_80A37294",), + 0x80A37294:("EnSyatekiOkuta_OverrideLimbDraw",), 0x80A3735C:("EnSyatekiOkuta_Draw",), 0x80A37ED0:("ObjShutter_Init",), 0x80A37EE0:("ObjShutter_Destroy",), @@ -10301,20 +10297,20 @@ 0x80A3AEC8:("DmTsg_Draw",), 0x80A3B080:("EnBaguo_Init",), 0x80A3B1F4:("EnBaguo_Destroy",), - 0x80A3B220:("func_80A3B220",), - 0x80A3B2CC:("func_80A3B2CC",), - 0x80A3B3E0:("func_80A3B3E0",), - 0x80A3B5E0:("func_80A3B5E0",), - 0x80A3B794:("func_80A3B794",), - 0x80A3B7B8:("func_80A3B7B8",), - 0x80A3B8F8:("func_80A3B8F8",), - 0x80A3B958:("func_80A3B958",), + 0x80A3B220:("EnBaguo_UndergroundIdle",), + 0x80A3B2CC:("EnBaguo_EmergeFromUnderground",), + 0x80A3B3E0:("EnBaguo_Idle",), + 0x80A3B5E0:("EnBaguo_Roll",), + 0x80A3B794:("EnBaguo_SetupRetreatUnderground",), + 0x80A3B7B8:("EnBaguo_RetreatUnderground",), + 0x80A3B8F8:("EnBaguo_PostDetonation",), + 0x80A3B958:("EnBaguo_CheckForDetonation",), 0x80A3BC88:("EnBaguo_Update",), - 0x80A3BE24:("func_80A3BE24",), - 0x80A3BE60:("func_80A3BE60",), - 0x80A3BF0C:("func_80A3BF0C",), - 0x80A3C008:("func_80A3C008",), - 0x80A3C17C:("func_80A3C17C",), + 0x80A3BE24:("EnBaguo_PostLimbDraw",), + 0x80A3BE60:("EnBaguo_DrawBody",), + 0x80A3BF0C:("EnBaguo_InitializeParticle",), + 0x80A3C008:("EnBaguo_UpdateParticles",), + 0x80A3C17C:("EnBaguo_DrawRockParticles",), 0x80A3C4E0:("func_80A3C4E0",), 0x80A3C560:("func_80A3C560",), 0x80A3C658:("func_80A3C658",), @@ -10473,8 +10469,8 @@ 0x80A483B4:("EnWiz_Draw",), 0x80A48FE0:("EnWizBrock_Init",), 0x80A490B0:("EnWizBrock_Destroy",), - 0x80A490E4:("func_80A490E4",), - 0x80A490FC:("func_80A490FC",), + 0x80A490E4:("EnWizBrock_SetupUpdateStatus",), + 0x80A490FC:("EnWizBrock_UpdateStatus",), 0x80A492E4:("EnWizBrock_Update",), 0x80A49308:("EnWizBrock_Draw",), 0x80A496A0:("EnWizFire_Init",), @@ -10849,14 +10845,14 @@ 0x80A675C4:("ObjDriftice_Draw",), 0x80A678B0:("EnLookNuts_Init",), 0x80A67A08:("EnLookNuts_Destroy",), - 0x80A67A34:("func_80A67A34",), + 0x80A67A34:("EnLookNuts_SetupPatrol",), 0x80A67AA8:("func_80A67AA8",), - 0x80A67C48:("func_80A67C48",), - 0x80A67D0C:("func_80A67D0C",), + 0x80A67C48:("EnLookNuts_SetupStandAndWait",), + 0x80A67D0C:("EnLookNuts_StandAndWait",), 0x80A67F30:("func_80A67F30",), 0x80A67FC4:("func_80A67FC4",), - 0x80A68080:("func_80A68080",), - 0x80A680FC:("func_80A680FC",), + 0x80A68080:("EnLookNuts_SetupSendPlayerToSpawn",), + 0x80A680FC:("EnLookNuts_SendPlayerToSpawn",), 0x80A681C4:("EnLookNuts_Update",), 0x80A68540:("EnLookNuts_Draw",), 0x80A687A0:("func_80A687A0",), @@ -10911,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_MoonsTear_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",), @@ -10960,8 +10956,8 @@ 0x80A6FFAC:("func_80A6FFAC",), 0x80A70084:("func_80A70084",), 0x80A70134:("EnMm3_Update",), - 0x80A701E0:("func_80A701E0",), - 0x80A702B0:("func_80A702B0",), + 0x80A701E0:("EnMm3_OverrideLimbDraw",), + 0x80A702B0:("EnMm3_PostLimbDraw",), 0x80A702F0:("EnMm3_Draw",), 0x80A706F0:("BgCraceMovebg_Init",), 0x80A7090C:("func_80A7090C",), @@ -11009,8 +11005,8 @@ 0x80A72BA4:("func_80A72BA4",), 0x80A72C04:("func_80A72C04",), 0x80A72CF8:("func_80A72CF8",), - 0x80A72D8C:("func_80A72D8C",), - 0x80A72FAC:("func_80A72FAC",), + 0x80A72D8C:("EnDno_ActorPathing_UpdateActorInfo",), + 0x80A72FAC:("EnDno_ActorPathing_Move",), 0x80A730A0:("func_80A730A0",), 0x80A73244:("func_80A73244",), 0x80A732C8:("func_80A732C8",), @@ -11104,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",), @@ -11251,9 +11247,9 @@ 0x80A88334:("EnTru_Init",), 0x80A884BC:("EnTru_Destroy",), 0x80A884E8:("EnTru_Update",), - 0x80A885B8:("func_80A885B8",), - 0x80A88698:("func_80A88698",), - 0x80A886D4:("func_80A886D4",), + 0x80A885B8:("EnTru_OverrideLimbDraw",), + 0x80A88698:("EnTru_PostLimbDraw",), + 0x80A886D4:("EnTru_TransformLimbDraw",), 0x80A887E4:("EnTru_Draw",), 0x80A8B770:("EnTrt_ChangeAnim",), 0x80A8B80C:("EnTrt_TestItemSelected",), @@ -11335,12 +11331,12 @@ 0x80A8FA00:("EnTrt_UpdateHeadPosAndRot",), 0x80A8FB34:("EnTrt_OverrideLimbDraw",), 0x80A8FBB4:("EnTrt_PostLimbDraw",), - 0x80A8FC64:("EnTrt_UnkActorDraw",), + 0x80A8FC64:("EnTrt_TransformLimbDraw",), 0x80A8FCE0:("EnTrt_Draw",), 0x80A903B0:("EnTest5_SetupAction",), 0x80A903BC:("EnTest5_Init",), 0x80A90468:("EnTest5_Destroy",), - 0x80A90478:("func_80A90478",), + 0x80A90478:("EnTest5_HandleBottleAction",), 0x80A905A4:("EnTest5_Update",), 0x80A90730:("func_80A90730",), 0x80A90C08:("func_80A90C08",), @@ -11506,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",), @@ -11534,7 +11530,7 @@ 0x80AA67F8:("func_80AA67F8",), 0x80AA695C:("func_80AA695C",), 0x80AA6A04:("DmChar00_Update",), - 0x80AA6A6C:("func_80AA6A6C",), + 0x80AA6A6C:("DmChar00_OverrideLimbDraw",), 0x80AA6B34:("DmChar00_Draw",), 0x80AA81E0:("DmChar01_Init",), 0x80AA8660:("DmChar01_Destroy",), @@ -11609,8 +11605,8 @@ 0x80AAD450:("func_80AAD450",), 0x80AAD4A8:("func_80AAD4A8",), 0x80AAD78C:("DmChar05_Update",), - 0x80AAD964:("func_80AAD964",), - 0x80AAD980:("func_80AAD980",), + 0x80AAD964:("DmChar05_OverrideLimbDraw",), + 0x80AAD980:("DmChar05_PostLimbDraw",), 0x80AAD998:("func_80AAD998",), 0x80AADA90:("func_80AADA90",), 0x80AADB4C:("func_80AADB4C",), @@ -11671,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_GetTargetSunMoonPanelRotation",), + 0x80AB27B4:("ObjTokeidai_SetupClockOrExteriorGear",), + 0x80AB2834:("ObjTokeidai_Clock_Init",), + 0x80AB28C8:("ObjTokeidai_ExteriorGear_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_ExteriorGear_Collapse",), + 0x80AB3240:("ObjTokeidai_ExteriorGear_OpenedIdle",), + 0x80AB32F0:("ObjTokeidai_TowerClock_Fall",), + 0x80AB3370:("ObjTokeidai_TowerClock_SlideOff",), + 0x80AB34CC:("ObjTokeidai_TowerClock_OpenedIdle",), + 0x80AB3544:("ObjTokeidai_Counterweight_Collapse",), + 0x80AB3598:("ObjTokeidai_Counterweight_OpenedIdle",), + 0x80AB363C:("ObjTokeidai_TerminaFieldWalls_Collapse",), + 0x80AB365C:("ObjTokeidai_TerminaFieldWalls_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_StaircaseToRooftop_Idle",), + 0x80AB3C50:("ObjTokeidai_IsPostFirstCycleFinalHours",), + 0x80AB3CCC:("ObjTokeidai_RotateOnHourChange",), + 0x80AB3ED0:("ObjTokeidai_TowerClock_Idle",), + 0x80AB4040:("ObjTokeidai_WallClock_Idle",), + 0x80AB4080:("ObjTokeidai_ExteriorGear_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_ExteriorGear_Draw",), 0x80AB4D10:("func_80AB4D10",), 0x80AB4E34:("func_80AB4E34",), 0x80AB4E58:("func_80AB4E58",), @@ -11808,16 +11804,16 @@ 0x80ABAE64:("func_80ABAE64",), 0x80ABB0E0:("EnGuardNuts_Init",), 0x80ABB1E4:("EnGuardNuts_Destroy",), - 0x80ABB210:("func_80ABB210",), - 0x80ABB29C:("func_80ABB29C",), - 0x80ABB2D4:("func_80ABB2D4",), + 0x80ABB210:("EnGuardNuts_ChangeAnim",), + 0x80ABB29C:("EnGuardNuts_SetupWait",), + 0x80ABB2D4:("EnGuardNuts_Wait",), 0x80ABB540:("func_80ABB540",), 0x80ABB590:("func_80ABB590",), - 0x80ABB854:("func_80ABB854",), - 0x80ABB91C:("func_80ABB91C",), - 0x80ABB990:("func_80ABB990",), + 0x80ABB854:("EnGuardNuts_Burrow",), + 0x80ABB91C:("EnGuardNuts_SetupUnburrow",), + 0x80ABB990:("EnGuardNuts_Unburrow",), 0x80ABBACC:("EnGuardNuts_Update",), - 0x80ABBC60:("func_80ABBC60",), + 0x80ABBC60:("EnGuardNuts_OverrideLimbDraw",), 0x80ABBCB8:("EnGuardNuts_Draw",), 0x80ABBFC0:("func_80ABBFC0",), 0x80ABC2E0:("func_80ABC2E0",), @@ -11916,33 +11912,33 @@ 0x80AC24A8:("func_80AC24A8",), 0x80AC26F0:("EnBigokuta_Init",), 0x80AC2874:("EnBigokuta_Destroy",), - 0x80AC28B4:("func_80AC28B4",), - 0x80AC299C:("func_80AC299C",), - 0x80AC2A1C:("func_80AC2A1C",), - 0x80AC2A7C:("func_80AC2A7C",), + 0x80AC28B4:("EnBigokuta_SetupCutsceneCamera",), + 0x80AC299C:("EnBigokuta_MoveCamera",), + 0x80AC2A1C:("EnBigokuta_ResetCamera",), + 0x80AC2A7C:("EnBigokuta_ShootPlayer",), 0x80AC2B4C:("func_80AC2B4C",), - 0x80AC2B98:("func_80AC2B98",), - 0x80AC2C30:("func_80AC2C30",), - 0x80AC2C84:("func_80AC2C84",), - 0x80AC2CE8:("func_80AC2CE8",), - 0x80AC2DAC:("func_80AC2DAC",), - 0x80AC2EBC:("func_80AC2EBC",), - 0x80AC2F20:("func_80AC2F20",), - 0x80AC2F64:("func_80AC2F64",), - 0x80AC3054:("func_80AC3054",), - 0x80AC30EC:("func_80AC30EC",), - 0x80AC31EC:("func_80AC31EC",), - 0x80AC33A4:("func_80AC33A4",), - 0x80AC33C0:("func_80AC33C0",), - 0x80AC3460:("func_80AC3460",), - 0x80AC34A8:("func_80AC34A8",), - 0x80AC35E8:("func_80AC35E8",), - 0x80AC3650:("func_80AC3650",), - 0x80AC3930:("func_80AC3930",), - 0x80AC39A0:("func_80AC39A0",), + 0x80AC2B98:("EnBigokuta_IsInWater",), + 0x80AC2C30:("EnBigokuta_SpawnRipple",), + 0x80AC2C84:("EnBigokuta_SetupIdle",), + 0x80AC2CE8:("EnBigokuta_Idle",), + 0x80AC2DAC:("EnBigokuta_SetupRise",), + 0x80AC2EBC:("EnBigokuta_RiseOutOfWater",), + 0x80AC2F20:("EnBigokuta_SetupIdleAboveWater",), + 0x80AC2F64:("EnBigokuta_IdleAboveWater",), + 0x80AC3054:("EnBigokuta_UpdateOrSetupCam",), + 0x80AC30EC:("EnBigokuta_SetupSuckInPlayer",), + 0x80AC31EC:("EnBigokuta_SuckInPlayer",), + 0x80AC33A4:("EnBigokuta_SetupHoldPlayer",), + 0x80AC33C0:("EnBigokuta_HoldPlayer",), + 0x80AC3460:("EnBigokuta_SetupDeathCutscene",), + 0x80AC34A8:("EnBigokuta_PlayDeathCutscene",), + 0x80AC35E8:("EnBigokuta_SetupDeathEffects",), + 0x80AC3650:("EnBigokuta_PlayDeathEffects",), + 0x80AC3930:("EnBigokuta_IsNearSwampBoat",), + 0x80AC39A0:("EnBigokuta_CheckOneHitKill",), 0x80AC3B2C:("EnBigokuta_Update",), - 0x80AC3D48:("func_80AC3D48",), - 0x80AC4204:("func_80AC4204",), + 0x80AC3D48:("EnBigokuta_OverrideLimbDraw",), + 0x80AC4204:("EnBigokuta_PostLimbDraw",), 0x80AC42F8:("EnBigokuta_Draw",), 0x80AC48F0:("BgIcefloe_Init",), 0x80AC4A04:("BgIcefloe_Destroy",), @@ -12001,8 +11997,8 @@ 0x80AC8A94:("TransitionWipe5_SetColor",), 0x80AC8AA0:("TransitionWipe5_SetEnvColor",), 0x80AC8B50:("EffectSsSbn_Init",), - 0x80AC8ECC:("func_80AC8ECC",), - 0x80AC9164:("func_80AC9164",), + 0x80AC8ECC:("EffectSsSbn_DrawSliding",), + 0x80AC9164:("EffectSsSbn_Draw",), 0x80AC933C:("EffectSsSbn_Update",), 0x80AC94C0:("func_80AC94C0",), 0x80AC94FC:("ObjOcarinalift_Init",), @@ -12075,30 +12071,30 @@ 0x80ACBDFC:("func_80ACBDFC",), 0x80ACBEE0:("ObjAqua_Update",), 0x80ACC048:("ObjAqua_Draw",), - 0x80ACC470:("func_80ACC470",), + 0x80ACC470:("EnElforg_InitializeParams",), 0x80ACC50C:("EnElforg_Init",), 0x80ACC7A4:("EnElforg_Destroy",), - 0x80ACC7E4:("func_80ACC7E4",), - 0x80ACC8D4:("func_80ACC8D4",), - 0x80ACC934:("func_80ACC934",), - 0x80ACC994:("func_80ACC994",), - 0x80ACCAC0:("func_80ACCAC0",), + 0x80ACC7E4:("EnElforg_SpawnSparkles",), + 0x80ACC8D4:("EnElforg_ApproachTargetYPosition",), + 0x80ACC934:("EnElforg_ApproachTargetSpeedXZ",), + 0x80ACC994:("EnElforg_MoveToTargetFairyFountain",), + 0x80ACCAC0:("EnElforg_MoveToTarget",), 0x80ACCBB8:("func_80ACCBB8",), - 0x80ACCBD0:("func_80ACCBD0",), - 0x80ACCC98:("func_80ACCC98",), - 0x80ACCE4C:("func_80ACCE4C",), - 0x80ACCEB0:("func_80ACCEB0",), - 0x80ACD088:("func_80ACD088",), - 0x80ACD164:("func_80ACD164",), - 0x80ACD1B0:("func_80ACD1B0",), - 0x80ACD1F0:("func_80ACD1F0",), - 0x80ACD2E4:("func_80ACD2E4",), - 0x80ACD59C:("func_80ACD59C",), - 0x80ACD610:("func_80ACD610",), - 0x80ACD6A8:("func_80ACD6A8",), - 0x80ACD6EC:("func_80ACD6EC",), + 0x80ACCBD0:("EnElforg_TrappedByBubble",), + 0x80ACCC98:("EnElforg_TurnInFairy",), + 0x80ACCE4C:("EnElforg_QuicklyCircleFairyFountain",), + 0x80ACCEB0:("EnElforg_FreeFloatingFairyFountain",), + 0x80ACD088:("EnElforg_CirclePlayer",), + 0x80ACD164:("EnElforg_FairyCollected",), + 0x80ACD1B0:("EnElforg_SetupFairyCollected",), + 0x80ACD1F0:("EnElforg_ClockTownFairyCollected",), + 0x80ACD2E4:("EnElforg_FreeFloating",), + 0x80ACD59C:("EnElforg_GetHoldingEnemy",), + 0x80ACD610:("EnElforg_TrappedByEnemy",), + 0x80ACD6A8:("EnElforg_SetupTrappedByEnemy",), + 0x80ACD6EC:("EnElforg_HiddenByCollider",), 0x80ACD798:("EnElforg_Update",), - 0x80ACD878:("func_80ACD878",), + 0x80ACD878:("EnElforg_OverrideLimbDraw",), 0x80ACD8C0:("EnElforg_Draw",), 0x80ACDCD0:("EnElfbub_Init",), 0x80ACDE34:("EnElfbub_Destroy",), @@ -12153,12 +12149,12 @@ 0x80AD1634:("func_80AD1634",), 0x80AD16A8:("func_80AD16A8",), 0x80AD19A0:("func_80AD19A0",), - 0x80AD1A4C:("func_80AD1A4C",), + 0x80AD1A4C:("EnOsn_Idle",), 0x80AD1A5C:("EnOsn_Init",), 0x80AD1C88:("EnOsn_Destroy",), 0x80AD1CC8:("EnOsn_Update",), - 0x80AD1DA8:("func_80AD1DA8",), - 0x80AD1E28:("func_80AD1E28",), + 0x80AD1DA8:("EnOsn_OverrideLimbDraw",), + 0x80AD1E28:("EnOsn_PostLimbDraw",), 0x80AD1F88:("EnOsn_Draw",), 0x80AD2B70:("BgCtowerGear_Splash",), 0x80AD2E84:("BgCtowerGear_Init",), @@ -12210,9 +12206,9 @@ 0x80AD5150:("EnTrt2_Update",), 0x80AD5234:("func_80AD5234",), 0x80AD5394:("func_80AD5394",), - 0x80AD54C8:("func_80AD54C8",), - 0x80AD5584:("func_80AD5584",), - 0x80AD566C:("func_80AD566C",), + 0x80AD54C8:("EnTrt2_OverrideLimbDraw",), + 0x80AD5584:("EnTrt2_PostLimbDraw",), + 0x80AD566C:("EnTrt2_TransformLimbDraw",), 0x80AD56E8:("func_80AD56E8",), 0x80AD5BB0:("ObjTokeiStep_SetSysMatrix",), 0x80AD5BE8:("ObjTokeiStep_AddQuake",), @@ -12280,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",), @@ -12332,7 +12328,7 @@ 0x80ADD400:("EnSellnuts_Update",), 0x80ADD4E0:("func_80ADD4E0",), 0x80ADD7B4:("func_80ADD7B4",), - 0x80ADD7CC:("func_80ADD7CC",), + 0x80ADD7CC:("EnSellnuts_TransformLimbDraw",), 0x80ADD8A4:("EnSellnuts_Draw",), 0x80ADE230:("func_80ADE230",), 0x80ADE5A4:("BgDkjailIvy_Init",), @@ -12388,8 +12384,8 @@ 0x80AE0D78:("func_80AE0D78",), 0x80AE0DDC:("EnTsn_Update",), 0x80AE0F84:("func_80AE0F84",), - 0x80AE0FA8:("func_80AE0FA8",), - 0x80AE1024:("func_80AE1024",), + 0x80AE0FA8:("EnTsn_OverrideLimbDraw",), + 0x80AE1024:("EnTsn_PostLimbDraw",), 0x80AE1080:("EnTsn_Draw",), 0x80AE1650:("func_80AE1650",), 0x80AE16A0:("func_80AE16A0",), @@ -12465,8 +12461,8 @@ 0x80AE5990:("EnFsn_Draw",), 0x80AE6130:("func_80AE6130",), 0x80AE615C:("func_80AE615C",), - 0x80AE61C0:("func_80AE61C0",), - 0x80AE625C:("func_80AE625C",), + 0x80AE61C0:("EnShn_IsFacingPlayer",), + 0x80AE625C:("EnShn_GetPlayer",), 0x80AE626C:("func_80AE626C",), 0x80AE63A8:("func_80AE63A8",), 0x80AE6488:("func_80AE6488",), @@ -12479,9 +12475,9 @@ 0x80AE6B30:("EnShn_Init",), 0x80AE6C4C:("EnShn_Destroy",), 0x80AE6C5C:("EnShn_Update",), - 0x80AE6CF0:("func_80AE6CF0",), - 0x80AE6D40:("func_80AE6D40",), - 0x80AE6D90:("func_80AE6D90",), + 0x80AE6CF0:("EnShn_OverrideLimbDraw",), + 0x80AE6D40:("EnShn_PostLimbDraw",), + 0x80AE6D90:("EnShn_TransformLimbDraw",), 0x80AE6E8C:("EnShn_Draw",), 0x80AE73A0:("EnStopheishi_Init",), 0x80AE74E0:("EnStopheishi_Destroy",), @@ -12608,8 +12604,8 @@ 0x80AEF2D8:("func_80AEF2D8",), 0x80AEF3E8:("EnTk_Update",), 0x80AEF5F4:("func_80AEF5F4",), - 0x80AEF65C:("func_80AEF65C",), - 0x80AEF6A4:("func_80AEF6A4",), + 0x80AEF65C:("EnTk_OverrideLimbDraw",), + 0x80AEF6A4:("EnTk_PostLimbDraw",), 0x80AEF734:("EnTk_Draw",), 0x80AF0060:("BgMarketStep_Init",), 0x80AF0088:("BgMarketStep_Draw",), @@ -12776,18 +12772,18 @@ 0x80AFA7A8:("EnPm_Init",), 0x80AFA8B0:("EnPm_Destroy",), 0x80AFA8F0:("EnPm_Update",), - 0x80AFAA04:("func_80AFAA04",), - 0x80AFAA44:("func_80AFAA44",), - 0x80AFABAC:("func_80AFABAC",), + 0x80AFAA04:("EnPm_OverrideLimbDraw",), + 0x80AFAA44:("EnPm_PostLimbDraw",), + 0x80AFABAC:("EnPm_TransformLimbDraw",), 0x80AFACAC:("EnPm_Draw",), - 0x80AFC960:("func_80AFC960",), + 0x80AFC960:("EnGakufu_ProcessNotes",), 0x80AFCA94:("EnGakufu_Init",), 0x80AFCB64:("EnGakufu_Destroy",), - 0x80AFCB94:("func_80AFCB94",), - 0x80AFCBD4:("func_80AFCBD4",), - 0x80AFCC14:("func_80AFCC14",), - 0x80AFCC24:("func_80AFCC24",), - 0x80AFCC58:("func_80AFCC58",), + 0x80AFCB94:("EnGakufu_DisplayOnTimer",), + 0x80AFCBD4:("EnGakufu_WaitForTimer",), + 0x80AFCC14:("EnGakufu_DoNothing",), + 0x80AFCC24:("EnGakufu_IsPlayerInRange",), + 0x80AFCC58:("EnGakufu_GiveReward",), 0x80AFCD44:("func_80AFCD44",), 0x80AFCDC8:("func_80AFCDC8",), 0x80AFCE70:("EnGakufu_Update",), @@ -12809,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",), @@ -12821,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_SetupAttemptPlayerFreeze",), + 0x80AFEC4C:("EnTalkGibud_AttemptPlayerFreeze",), + 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_UpdateDamage",), + 0x80B00B8C:("EnTalkGibud_UpdateCollision",), + 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",), @@ -13025,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",), @@ -13116,43 +13112,43 @@ 0x80B16808:("BgHakuginSwitch_Draw",), 0x80B16B00:("EnSnowman_Init",), 0x80B16F94:("EnSnowman_Destroy",), - 0x80B16FC0:("func_80B16FC0",), - 0x80B17144:("func_80B17144",), - 0x80B173D0:("func_80B173D0",), - 0x80B1746C:("func_80B1746C",), - 0x80B177EC:("func_80B177EC",), - 0x80B178B8:("func_80B178B8",), - 0x80B179D0:("func_80B179D0",), - 0x80B17A58:("func_80B17A58",), - 0x80B17CE8:("func_80B17CE8",), - 0x80B17D78:("func_80B17D78",), - 0x80B17EB4:("func_80B17EB4",), - 0x80B17EFC:("func_80B17EFC",), - 0x80B17F4C:("func_80B17F4C",), - 0x80B17FE0:("func_80B17FE0",), - 0x80B180A4:("func_80B180A4",), - 0x80B18124:("func_80B18124",), - 0x80B18380:("func_80B18380",), - 0x80B183A4:("func_80B183A4",), - 0x80B183C4:("func_80B183C4",), - 0x80B1848C:("func_80B1848C",), - 0x80B18600:("func_80B18600",), - 0x80B1861C:("func_80B1861C",), - 0x80B18908:("func_80B18908",), - 0x80B189C4:("func_80B189C4",), - 0x80B189D4:("func_80B189D4",), - 0x80B18A04:("func_80B18A04",), - 0x80B18A28:("func_80B18A28",), - 0x80B18B30:("func_80B18B30",), - 0x80B18BB4:("func_80B18BB4",), - 0x80B18C7C:("func_80B18C7C",), - 0x80B18F50:("func_80B18F50",), + 0x80B16FC0:("EnSnowman_SpawnCircularDustEffect",), + 0x80B17144:("EnSnowman_SpawnBigSnowballFragmentEffects",), + 0x80B173D0:("EnSnowman_SetupMoveSnowPile",), + 0x80B1746C:("EnSnowman_MoveSnowPile",), + 0x80B177EC:("EnSnowman_SetupEmerge",), + 0x80B178B8:("EnSnowman_Emerge",), + 0x80B179D0:("EnSnowman_SetupReadySnowball",), + 0x80B17A58:("EnSnowman_ReadySnowball",), + 0x80B17CE8:("EnSnowman_SetupThrowSnowball",), + 0x80B17D78:("EnSnowman_ThrowSnowball",), + 0x80B17EB4:("EnSnowman_SetupIdle",), + 0x80B17EFC:("EnSnowman_Idle",), + 0x80B17F4C:("EnSnowman_SetupSubmerge",), + 0x80B17FE0:("EnSnowman_Submerge",), + 0x80B180A4:("EnSnowman_SetupMelt",), + 0x80B18124:("EnSnowman_Melt",), + 0x80B18380:("EnSnowman_SetupStun",), + 0x80B183A4:("EnSnowman_Stun",), + 0x80B183C4:("EnSnowman_SetupDamaged",), + 0x80B1848C:("EnSnowman_Damaged",), + 0x80B18600:("EnSnowman_SetupDead",), + 0x80B1861C:("EnSnowman_Dead",), + 0x80B18908:("EnSnowman_SetupSplitDoNothing",), + 0x80B189C4:("EnSnowman_SplitDoNothing",), + 0x80B189D4:("EnSnowman_SetupMarkForDeath",), + 0x80B18A04:("EnSnowman_MarkForDeath",), + 0x80B18A28:("EnSnowman_CreateSplitEeno",), + 0x80B18B30:("EnSnowman_AbsorbEeno",), + 0x80B18BB4:("EnSnowman_SetupCombine",), + 0x80B18C7C:("EnSnowman_Combine",), + 0x80B18F50:("EnSnowman_UpdateDamage",), 0x80B1918C:("EnSnowman_Update",), - 0x80B19474:("func_80B19474",), - 0x80B19718:("func_80B19718",), + 0x80B19474:("EnSnowman_UpdateSnowball",), + 0x80B19718:("EnSnowman_PostLimbDraw",), 0x80B198B0:("EnSnowman_Draw",), - 0x80B19948:("func_80B19948",), - 0x80B19998:("func_80B19998",), + 0x80B19948:("EnSnowman_DrawSnowPile",), + 0x80B19998:("EnSnowman_DrawSnowball",), 0x80B19F60:("TGSw_ActionDecider",), 0x80B1A008:("TGSw_ActionExecuteOneShot",), 0x80B1A15C:("TGSw_Init",), @@ -13201,8 +13197,8 @@ 0x80B1C408:("func_80B1C408",), 0x80B1C61C:("EnPoSisters_Update",), 0x80B1C974:("func_80B1C974",), - 0x80B1CB44:("func_80B1CB44",), - 0x80B1CD34:("func_80B1CD34",), + 0x80B1CB44:("EnPoSisters_OverrideLimbDraw",), + 0x80B1CD34:("EnPoSisters_PostLimbDraw",), 0x80B1D484:("EnPoSisters_Draw",), 0x80B1DEB0:("EnPp_Init",), 0x80B1E234:("EnPp_Destroy",), @@ -13254,7 +13250,7 @@ 0x80B22750:("func_80B22750",), 0x80B2278C:("EnHakurock_Update",), 0x80B228F4:("func_80B228F4",), - 0x80B229A4:("func_80B229A4",), + 0x80B229A4:("EnHakurock_Draw",), 0x80B22C00:("func_80B22C00",), 0x80B22C2C:("func_80B22C2C",), 0x80B22C80:("func_80B22C80",), @@ -13271,7 +13267,7 @@ 0x80B23910:("func_80B23910",), 0x80B23934:("func_80B23934",), 0x80B239FC:("EnHanabi_Update",), - 0x80B23A38:("func_80B23A38",), + 0x80B23A38:("EnHanabi_Draw",), 0x80B23D50:("func_80B23D50",), 0x80B23DD0:("func_80B23DD0",), 0x80B23E10:("ObjDowsing_Init",), @@ -13281,28 +13277,28 @@ 0x80B23F50:("ObjWind_Destroy",), 0x80B23F60:("ObjWind_Update",), 0x80B243C0:("ObjWind_Draw",), - 0x80B24630:("func_80B24630",), - 0x80B246F4:("func_80B246F4",), - 0x80B2478C:("func_80B2478C",), - 0x80B248B8:("func_80B248B8",), + 0x80B24630:("EnRacedog_ChangeAnimation",), + 0x80B246F4:("EnRacedog_UpdateCollision",), + 0x80B2478C:("EnRacedog_GetYRotation",), + 0x80B248B8:("EnRacedog_GetFloorRot",), 0x80B24930:("EnRacedog_Init",), 0x80B24BE8:("EnRacedog_Destroy",), - 0x80B24C14:("func_80B24C14",), - 0x80B24CB4:("func_80B24CB4",), - 0x80B24E14:("func_80B24E14",), - 0x80B24F08:("func_80B24F08",), - 0x80B251EC:("func_80B251EC",), - 0x80B252F8:("func_80B252F8",), - 0x80B2538C:("func_80B2538C",), - 0x80B25448:("func_80B25448",), - 0x80B25490:("func_80B25490",), - 0x80B255AC:("func_80B255AC",), - 0x80B256BC:("func_80B256BC",), + 0x80B24C14:("EnRacedog_RaceStart",), + 0x80B24CB4:("EnRacedog_Race",), + 0x80B24E14:("EnRacedog_UpdateTextId",), + 0x80B24F08:("EnRacedog_UpdateSpeed",), + 0x80B251EC:("EnRacedog_CalculateFinalStretchTargetSpeed",), + 0x80B252F8:("EnRacedog_UpdateRaceVariables",), + 0x80B2538C:("EnRacedog_CheckForFinish",), + 0x80B25448:("EnRacedog_UpdateRunAnimationPlaySpeed",), + 0x80B25490:("EnRacedog_IsOverFinishLine",), + 0x80B255AC:("EnRacedog_SpawnFloorDustRing",), + 0x80B256BC:("EnRacedog_PlayWalkSfx",), 0x80B25708:("EnRacedog_Update",), - 0x80B2583C:("func_80B2583C",), - 0x80B258D8:("func_80B258D8",), - 0x80B25A74:("func_80B25A74",), - 0x80B25A90:("func_80B25A90",), + 0x80B2583C:("EnRacedog_UpdateSelectionArrow",), + 0x80B258D8:("EnRacedog_DrawSelectionArrow",), + 0x80B25A74:("EnRacedog_OverrideLimbDraw",), + 0x80B25A90:("EnRacedog_PostLimbDraw",), 0x80B25B14:("EnRacedog_Draw",), 0x80B262A0:("EnKendoJs_Init",), 0x80B264FC:("EnKendoJs_Destroy",), @@ -13334,8 +13330,8 @@ 0x80B279F0:("func_80B279F0",), 0x80B27A90:("func_80B27A90",), 0x80B27ACC:("EnKendoJs_Update",), - 0x80B27B54:("func_80B27B54",), - 0x80B27B8C:("func_80B27B8C",), + 0x80B27B54:("EnKendoJs_OverrideLimbDraw",), + 0x80B27B8C:("EnKendoJs_PostLimbDraw",), 0x80B27BA4:("EnKendoJs_Draw",), 0x80B28080:("BgBotihasira_Init",), 0x80B28124:("BgBotihasira_Destroy",), @@ -13370,8 +13366,8 @@ 0x80B2A448:("func_80B2A448",), 0x80B2A498:("func_80B2A498",), 0x80B2A738:("EnFish2_Update",), - 0x80B2ABF4:("func_80B2ABF4",), - 0x80B2AC20:("func_80B2AC20",), + 0x80B2ABF4:("EnFish2_OverrideLimbDraw",), + 0x80B2AC20:("EnFish2_PostLimbDraw",), 0x80B2AD34:("EnFish2_Draw",), 0x80B2ADB0:("func_80B2ADB0",), 0x80B2AF80:("func_80B2AF80",), @@ -13488,9 +13484,9 @@ 0x80B32E74:("EnZoraegg_Update",), 0x80B32F04:("func_80B32F04",), 0x80B331C8:("func_80B331C8",), - 0x80B3336C:("func_80B3336C",), + 0x80B3336C:("EnZoraegg_OverrideLimbDraw",), 0x80B333DC:("func_80B333DC",), - 0x80B33480:("func_80B33480",), + 0x80B33480:("EnZoraegg_PostLimbDraw",), 0x80B33818:("func_80B33818",), 0x80B338C0:("EnZoraegg_Draw",), 0x80B33D30:("EnKbt_Init",), @@ -13505,8 +13501,8 @@ 0x80B34574:("func_80B34574",), 0x80B34598:("func_80B34598",), 0x80B349A4:("EnKbt_Update",), - 0x80B349C8:("func_80B349C8",), - 0x80B34A00:("func_80B34A00",), + 0x80B349C8:("EnKbt_OverrideLimbDraw",), + 0x80B34A00:("EnKbt_PostLimbDraw",), 0x80B34A40:("EnKbt_Draw",), 0x80B34F70:("func_80B34F70",), 0x80B34FB4:("func_80B34FB4",), @@ -13531,8 +13527,8 @@ 0x80B364F8:("EnGg_Init",), 0x80B36660:("EnGg_Destroy",), 0x80B36670:("EnGg_Update",), - 0x80B368B0:("func_80B368B0",), - 0x80B368F0:("func_80B368F0",), + 0x80B368B0:("EnGg_OverrideLimbDraw",), + 0x80B368F0:("EnGg_PostLimbDraw",), 0x80B36A34:("EnGg_Draw",), 0x80B37080:("EnMaruta_Init",), 0x80B37280:("EnMaruta_Destroy",), @@ -13637,8 +13633,8 @@ 0x80B3D7B8:("EnDnp_Destroy",), 0x80B3D7E4:("EnDnp_Update",), 0x80B3D974:("func_80B3D974",), - 0x80B3DA88:("func_80B3DA88",), - 0x80B3DAA0:("func_80B3DAA0",), + 0x80B3DA88:("EnDnp_PostLimbDraw",), + 0x80B3DAA0:("EnDnp_TransformLimbDraw",), 0x80B3DB98:("EnDnp_Draw",), 0x80B3DFF0:("func_80B3DFF0",), 0x80B3E168:("func_80B3E168",), @@ -13661,9 +13657,9 @@ 0x80B3F318:("EnDai_Init",), 0x80B3F494:("EnDai_Destroy",), 0x80B3F4A4:("EnDai_Update",), - 0x80B3F598:("func_80B3F598",), - 0x80B3F614:("func_80B3F614",), - 0x80B3F6EC:("func_80B3F6EC",), + 0x80B3F598:("EnDai_OverrideLimbDraw",), + 0x80B3F614:("EnDai_PostLimbDraw",), + 0x80B3F6EC:("EnDai_TransformLimbDraw",), 0x80B3F78C:("func_80B3F78C",), 0x80B3F920:("func_80B3F920",), 0x80B3FB84:("EnDai_Draw",), @@ -14007,9 +14003,9 @@ 0x80B526FC:("EnGk_Init",), 0x80B529B8:("EnGk_Destroy",), 0x80B529E4:("EnGk_Update",), - 0x80B52AD4:("func_80B52AD4",), - 0x80B52AF0:("func_80B52AF0",), - 0x80B52D8C:("func_80B52D8C",), + 0x80B52AD4:("EnGk_OverrideLimbDraw",), + 0x80B52AF0:("EnGk_PostLimbDraw",), + 0x80B52D8C:("EnGk_TransformDraw",), 0x80B52F74:("EnGk_Draw",), 0x80B53840:("func_80B53840",), 0x80B539CC:("func_80B539CC",), @@ -14120,38 +14116,38 @@ 0x80B5CEC8:("func_80B5CEC8",), 0x80B5D114:("func_80B5D114",), 0x80B5D160:("func_80B5D160",), - 0x80B5D37C:("func_80B5D37C",), - 0x80B5D470:("func_80B5D470",), + 0x80B5D37C:("EnOt_ActorPathing_Move",), + 0x80B5D470:("EnOt_ActorPathing_UpdateActorInfo",), 0x80B5D648:("func_80B5D648",), 0x80B5D750:("func_80B5D750",), 0x80B5D8AC:("EnOt_Update",), 0x80B5DAEC:("func_80B5DAEC",), 0x80B5DB6C:("func_80B5DB6C",), 0x80B5DD20:("EnOt_Draw",), - 0x80B5DECC:("func_80B5DECC",), + 0x80B5DECC:("EnOt_PostLimbDraw",), 0x80B5DF58:("func_80B5DF58",), 0x80B5E078:("func_80B5E078",), 0x80B5E1D8:("func_80B5E1D8",), 0x80B5E890:("EnDragon_Init",), 0x80B5EA74:("EnDragon_Destroy",), - 0x80B5EAA0:("func_80B5EAA0",), - 0x80B5EB40:("func_80B5EB40",), - 0x80B5ED90:("func_80B5ED90",), - 0x80B5EDF0:("func_80B5EDF0",), - 0x80B5EE3C:("func_80B5EE3C",), - 0x80B5EF88:("func_80B5EF88",), - 0x80B5EFD0:("func_80B5EFD0",), - 0x80B5F3A4:("func_80B5F3A4",), - 0x80B5F418:("func_80B5F418",), - 0x80B5F508:("func_80B5F508",), - 0x80B5F888:("func_80B5F888",), - 0x80B5F8D8:("func_80B5F8D8",), - 0x80B5FCC0:("func_80B5FCC0",), - 0x80B5FD68:("func_80B5FD68",), - 0x80B60138:("func_80B60138",), + 0x80B5EAA0:("EnDragon_ChangeAnimation",), + 0x80B5EB40:("EnDragon_SpawnBubbles",), + 0x80B5ED90:("EnDragon_RetreatOnceTimerEnds",), + 0x80B5EDF0:("EnDragon_SetupRetreatOrIdle",), + 0x80B5EE3C:("EnDragon_RetreatOrIdle",), + 0x80B5EF88:("EnDragon_SetupExtend",), + 0x80B5EFD0:("EnDragon_Extend",), + 0x80B5F3A4:("EnDragon_CameraSetAtEye",), + 0x80B5F418:("EnDragon_SetupGrab",), + 0x80B5F508:("EnDragon_Grab",), + 0x80B5F888:("EnDragon_SetupAttack",), + 0x80B5F8D8:("EnDragon_Attack",), + 0x80B5FCC0:("EnDragon_SetupDead",), + 0x80B5FD68:("EnDragon_Dead",), + 0x80B60138:("EnDragon_UpdateDamage",), 0x80B6031C:("EnDragon_Update",), - 0x80B6043C:("func_80B6043C",), - 0x80B60494:("func_80B60494",), + 0x80B6043C:("EnDragon_OverrideLimbDraw",), + 0x80B60494:("EnDragon_PostLimbDraw",), 0x80B60564:("EnDragon_Draw",), 0x80B60AD0:("ObjDora_Init",), 0x80B60C70:("ObjDora_Destroy",), @@ -14165,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",), @@ -14282,7 +14278,7 @@ 0x80B6849C:("func_80B6849C",), 0x80B6D660:("BgSinkaiKabe_Init",), 0x80B6D9EC:("BgSinkaiKabe_Destroy",), - 0x80B6DA20:("func_80B6DA20",), + 0x80B6DA20:("BgSinkaiKabe_WaitForPlayer",), 0x80B6DB20:("BgSinkaiKabe_Update",), 0x80B6DBE0:("BgHakaCurtain_Init",), 0x80B6DC64:("BgHakaCurtain_Destroy",), @@ -14408,38 +14404,38 @@ 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",), - 0x80B73B98:("func_80B73B98",), - 0x80B73C58:("func_80B73C58",), - 0x80B73DF4:("func_80B73DF4",), - 0x80B73E3C:("func_80B73E3C",), - 0x80B73F1C:("func_80B73F1C",), - 0x80B7406C:("func_80B7406C",), - 0x80B7408C:("func_80B7408C",), - 0x80B74134:("func_80B74134",), - 0x80B741F8:("func_80B741F8",), - 0x80B742F8:("func_80B742F8",), - 0x80B74440:("func_80B74440",), - 0x80B74550:("func_80B74550",), - 0x80B747C8:("func_80B747C8",), - 0x80B74840:("func_80B74840",), - 0x80B749D0:("func_80B749D0",), - 0x80B74AD8:("func_80B74AD8",), - 0x80B74B54:("func_80B74B54",), - 0x80B74BC8:("func_80B74BC8",), - 0x80B74E5C:("func_80B74E5C",), - 0x80B750A0:("func_80B750A0",), - 0x80B7517C:("func_80B7517C",), - 0x80B751F8:("func_80B751F8",), + 0x80B73A90:("EnJg_GetShrineGoronToFocusOn",), + 0x80B73AE4:("EnJg_UpdateCollision",), + 0x80B73B98:("EnJg_GetWalkingYRotation",), + 0x80B73C58:("EnJg_ReachedPoint",), + 0x80B73DF4:("EnJg_GetCutsceneForTeachingLullabyIntro",), + 0x80B73E3C:("EnJg_SetupGoronShrineCheer",), + 0x80B73F1C:("EnJg_SetupTalk",), + 0x80B7406C:("EnJg_Idle",), + 0x80B7408C:("EnJg_GoronShrineIdle",), + 0x80B74134:("EnJg_GoronShrineTalk",), + 0x80B741F8:("EnJg_GoronShrineCheer",), + 0x80B742F8:("EnJg_AlternateTalkOrWalkInPlace",), + 0x80B74440:("EnJg_Walk",), + 0x80B74550:("EnJg_Talk",), + 0x80B747C8:("EnJg_SetupWalk",), + 0x80B74840:("EnJg_Freeze",), + 0x80B749D0:("EnJg_FrozenIdle",), + 0x80B74AD8:("EnJg_EndFrozenInteraction",), + 0x80B74B54:("EnJg_TeachLullabyIntro",), + 0x80B74BC8:("EnJg_LullabyIntroCutsceneAction",), + 0x80B74E5C:("EnJg_GetNextTextId",), + 0x80B750A0:("EnJg_GetStartingConversationTextId",), + 0x80B7517C:("EnJg_SpawnBreath",), + 0x80B751F8:("EnJg_CheckIfTalkingToPlayerAndHandleFreezeTimer",), 0x80B753A0:("EnJg_Init",), 0x80B75564:("EnJg_Destroy",), 0x80B75590:("EnJg_Update",), - 0x80B75658:("func_80B75658",), - 0x80B75708:("func_80B75708",), + 0x80B75658:("EnJg_OverrideLimbDraw",), + 0x80B75708:("EnJg_PostLimbDraw",), 0x80B757AC:("EnJg_Draw",), 0x80B76030:("func_80B76030",), 0x80B76110:("func_80B76110",), @@ -14461,9 +14457,9 @@ 0x80B76E1C:("EnTruMt_Destroy",), 0x80B76E48:("EnTruMt_Update",), 0x80B76ED4:("func_80B76ED4",), - 0x80B77008:("func_80B77008",), - 0x80B77078:("func_80B77078",), - 0x80B77354:("func_80B77354",), + 0x80B77008:("EnTruMt_OverrideLimbDraw",), + 0x80B77078:("EnTruMt_PostLimbDraw",), + 0x80B77354:("EnTruMt_TransformLimbDraw",), 0x80B773D0:("EnTruMt_Draw",), 0x80B77770:("func_80B77770",), 0x80B77FA4:("func_80B77FA4",), @@ -14521,36 +14517,36 @@ 0x80B7C03C:("ObjUm_Draw",), 0x80B7C890:("EnNeoReeba_Init",), 0x80B7CA08:("EnNeoReeba_Destroy",), - 0x80B7CA34:("func_80B7CA34",), - 0x80B7CA70:("func_80B7CA70",), - 0x80B7CB3C:("func_80B7CB3C",), - 0x80B7CB88:("func_80B7CB88",), - 0x80B7CCE0:("func_80B7CCE0",), - 0x80B7CD28:("func_80B7CD28",), - 0x80B7CE34:("func_80B7CE34",), - 0x80B7CE94:("func_80B7CE94",), - 0x80B7CFA0:("func_80B7CFA0",), - 0x80B7CFFC:("func_80B7CFFC",), - 0x80B7D130:("func_80B7D130",), - 0x80B7D150:("func_80B7D150",), - 0x80B7D254:("func_80B7D254",), - 0x80B7D2E4:("func_80B7D2E4",), - 0x80B7D360:("func_80B7D360",), - 0x80B7D398:("func_80B7D398",), - 0x80B7D3EC:("func_80B7D3EC",), - 0x80B7D47C:("func_80B7D47C",), - 0x80B7D4FC:("func_80B7D4FC",), - 0x80B7D5A4:("func_80B7D5A4",), - 0x80B7D6D0:("func_80B7D6D0",), - 0x80B7D788:("func_80B7D788",), - 0x80B7D9B8:("func_80B7D9B8",), - 0x80B7DC80:("func_80B7DC80",), - 0x80B7DD7C:("func_80B7DD7C",), - 0x80B7DF34:("func_80B7DF34",), - 0x80B7E0BC:("func_80B7E0BC",), - 0x80B7E260:("func_80B7E260",), + 0x80B7CA34:("EnNeoReeba_SetupWaitUnderground",), + 0x80B7CA70:("EnNeoReeba_WaitUnderground",), + 0x80B7CB3C:("EnNeoReeba_SetupChooseAction",), + 0x80B7CB88:("EnNeoReeba_ChooseAction",), + 0x80B7CCE0:("EnNeoReeba_SetupSink",), + 0x80B7CD28:("EnNeoReeba_Sink",), + 0x80B7CE34:("EnNeoReeba_SetupRise",), + 0x80B7CE94:("EnNeoReeba_RiseOutOfGround",), + 0x80B7CFA0:("EnNeoReeba_SetupMove",), + 0x80B7CFFC:("EnNeoReeba_Move",), + 0x80B7D130:("EnNeoReeba_SetupReturnHome",), + 0x80B7D150:("EnNeoReeba_ReturnHome",), + 0x80B7D254:("EnNeoReeba_SetupBounce",), + 0x80B7D2E4:("EnNeoReeba_Bounce",), + 0x80B7D360:("EnNeoReeba_SetupStun",), + 0x80B7D398:("EnNeoReeba_Stunned",), + 0x80B7D3EC:("EnNeoReeba_SetupFrozen",), + 0x80B7D47C:("EnNeoReeba_Frozen",), + 0x80B7D4FC:("EnNeoReeba_SetupDamageAnim",), + 0x80B7D5A4:("EnNeoReeba_DamageAnim",), + 0x80B7D6D0:("EnNeoReeba_SetupDeathEffects",), + 0x80B7D788:("EnNeoReeba_PlayDeathEffects",), + 0x80B7D9B8:("EnNeoReeba_HandleHit",), + 0x80B7DC80:("EnNeoReeba_UpdatePosition",), + 0x80B7DD7C:("EnNeoReeba_DrawFrozenEffects",), + 0x80B7DF34:("EnNeoReeba_DrawEffects",), + 0x80B7E0BC:("EnNeoReeba_SpawnIce",), + 0x80B7E260:("EnNeoReeba_SinkIfStoneMask",), 0x80B7E2C4:("EnNeoReeba_Update",), - 0x80B7E378:("func_80B7E378",), + 0x80B7E378:("EnNeoReeba_OverrideLimbDraw",), 0x80B7E424:("EnNeoReeba_Draw",), 0x80B7E930:("BgMbarChair_Init",), 0x80B7E980:("BgMbarChair_Destroy",), @@ -14812,8 +14808,8 @@ 0x80B90E84:("EnMaYto_SetRomaniFaceExpression",), 0x80B90EC8:("EnMaYto_SetFaceExpression",), 0x80B90EF0:("EnMaYto_InitFaceExpression",), - 0x80B90F84:("EnMaYto_HasSpokeToPlayerToday",), - 0x80B91014:("EnMaYto_HasSpokeToPlayer",), + 0x80B90F84:("EnMaYto_HasSpokenToPlayerToday",), + 0x80B91014:("EnMaYto_HasSpokenToPlayer",), 0x80B9109C:("EnMaYto_SetTalkedFlag",), 0x80B9110C:("EnMaYto_Update",), 0x80B91154:("EnMaYto_OverrideLimbDraw",), @@ -14874,7 +14870,7 @@ 0x80B95128:("func_80B95128",), 0x80B95240:("func_80B95240",), 0x80B95260:("EnZog_Update",), - 0x80B954C4:("func_80B954C4",), + 0x80B954C4:("EnZog_PostLimbDraw",), 0x80B95598:("func_80B95598",), 0x80B95668:("EnZog_Draw",), 0x80B95E20:("func_80B95E20",), @@ -14945,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",), @@ -15080,7 +15076,7 @@ 0x80BA3230:("func_80BA3230",), 0x80BA3344:("func_80BA3344",), 0x80BA3410:("ObjNozoki_Update",), - 0x80BA3434:("func_80BA3434",), + 0x80BA3434:("ObjNozoki_Draw",), 0x80BA36C0:("func_80BA36C0",), 0x80BA36FC:("EnToto_Init",), 0x80BA3810:("EnToto_Destroy",), @@ -15122,56 +15118,56 @@ 0x80BA4CB4:("func_80BA4CB4",), 0x80BA4E2C:("EnToto_Update",), 0x80BA4EFC:("EnToto_Draw",), - 0x80BA5400:("func_80BA5400",), + 0x80BA5400:("EnRailgibud_SpawnOtherGibdosAndSetPositionAndRotation",), 0x80BA5620:("EnRailgibud_Init",), 0x80BA577C:("EnRailgibud_Destroy",), - 0x80BA57A8:("func_80BA57A8",), - 0x80BA57F8:("func_80BA57F8",), - 0x80BA59F0:("func_80BA59F0",), - 0x80BA5A34:("func_80BA5A34",), - 0x80BA5AF0:("func_80BA5AF0",), - 0x80BA5B64:("func_80BA5B64",), - 0x80BA5DBC:("func_80BA5DBC",), - 0x80BA5E18:("func_80BA5E18",), - 0x80BA6054:("func_80BA6054",), - 0x80BA60B0:("func_80BA60B0",), - 0x80BA6158:("func_80BA6158",), - 0x80BA61A0:("func_80BA61A0",), - 0x80BA6284:("func_80BA6284",), - 0x80BA62D4:("func_80BA62D4",), - 0x80BA6440:("func_80BA6440",), - 0x80BA64AC:("func_80BA64AC",), - 0x80BA6584:("func_80BA6584",), - 0x80BA6604:("func_80BA6604",), - 0x80BA6664:("func_80BA6664",), - 0x80BA66C8:("func_80BA66C8",), - 0x80BA6800:("func_80BA6800",), - 0x80BA6974:("func_80BA6974",), - 0x80BA6B30:("func_80BA6B30",), - 0x80BA6B9C:("func_80BA6B9C",), - 0x80BA6D10:("func_80BA6D10",), - 0x80BA6DAC:("func_80BA6DAC",), - 0x80BA6DF8:("func_80BA6DF8",), - 0x80BA7088:("func_80BA7088",), - 0x80BA71E4:("func_80BA71E4",), - 0x80BA7234:("func_80BA7234",), - 0x80BA7388:("func_80BA7388",), - 0x80BA7434:("func_80BA7434",), - 0x80BA7578:("func_80BA7578",), - 0x80BA76C4:("func_80BA76C4",), + 0x80BA57A8:("EnRailgibud_SetupWalkInCircles",), + 0x80BA57F8:("EnRailgibud_WalkInCircles",), + 0x80BA59F0:("EnRailgibud_SetupAttemptPlayerFreeze",), + 0x80BA5A34:("EnRailgibud_AttemptPlayerFreeze",), + 0x80BA5AF0:("EnRailgibud_SetupWalkToPlayer",), + 0x80BA5B64:("EnRailgibud_WalkToPlayer",), + 0x80BA5DBC:("EnRailgibud_SetupGrab",), + 0x80BA5E18:("EnRailgibud_Grab",), + 0x80BA6054:("EnRailgibud_SetupGrabFail",), + 0x80BA60B0:("EnRailgibud_GrabFail",), + 0x80BA6158:("EnRailgibud_SetupTurnAwayAndShakeHead",), + 0x80BA61A0:("EnRailgibud_TurnAwayAndShakeHead",), + 0x80BA6284:("EnRailgibud_SetupWalkToHome",), + 0x80BA62D4:("EnRailgibud_WalkToHome",), + 0x80BA6440:("EnRailgibud_SetupDamage",), + 0x80BA64AC:("EnRailgibud_Damage",), + 0x80BA6584:("EnRailgibud_SetupStunned",), + 0x80BA6604:("EnRailgibud_Stunned",), + 0x80BA6664:("EnRailgibud_SetupDead",), + 0x80BA66C8:("EnRailgibud_Dead",), + 0x80BA6800:("EnRailgibud_SpawnEffectsForSinkingIntoTheGround",), + 0x80BA6974:("EnRailgibud_SpawnDust",), + 0x80BA6B30:("EnRailgibud_UpdateWalkForwardState",), + 0x80BA6B9C:("EnRailgibud_TurnTowardsPlayer",), + 0x80BA6D10:("EnRailgibud_PlayerInRangeWithCorrectState",), + 0x80BA6DAC:("EnRailgibud_PlayerOutOfRange",), + 0x80BA6DF8:("EnRailgibud_UpdateDamage",), + 0x80BA7088:("EnRailgibud_MoveToIdealGrabPositionAndRotation",), + 0x80BA71E4:("EnRailgibud_MoveWithGravity",), + 0x80BA7234:("EnRailgibud_MoveGrabbedPlayerAwayFromWall",), + 0x80BA7388:("EnRailgibud_UpdateEffect",), + 0x80BA7434:("EnRailgibud_CheckForGibdoMask",), + 0x80BA7578:("EnRailgibud_CheckIfTalkingToPlayer",), + 0x80BA76C4:("EnRailgibud_UpdateCollision",), 0x80BA77A0:("EnRailgibud_Update",), - 0x80BA7878:("func_80BA7878",), - 0x80BA789C:("func_80BA789C",), - 0x80BA78F8:("func_80BA78F8",), + 0x80BA7878:("EnRailgibud_MainGibdo_DeadUpdate",), + 0x80BA789C:("EnRailgibud_OverrideLimbDraw",), + 0x80BA78F8:("EnRailgibud_PostLimbDraw",), 0x80BA79D4:("EnRailgibud_Draw",), - 0x80BA7B6C:("func_80BA7B6C",), - 0x80BA7C78:("func_80BA7C78",), - 0x80BA7CF0:("func_80BA7CF0",), - 0x80BA7D04:("func_80BA7D04",), - 0x80BA7D14:("func_80BA7D14",), - 0x80BA7D30:("func_80BA7D30",), - 0x80BA7DC8:("func_80BA7DC8",), - 0x80BA8050:("func_80BA8050",), + 0x80BA7B6C:("EnRailgibud_InitCutsceneGibdo",), + 0x80BA7C78:("EnRailgibud_InitActorActionCommand",), + 0x80BA7CF0:("EnRailgibud_SetupDoNothing",), + 0x80BA7D04:("EnRailgibud_DoNothing",), + 0x80BA7D14:("EnRailgibud_SetupSinkIntoGround",), + 0x80BA7D30:("EnRailgibud_SinkIntoGround",), + 0x80BA7DC8:("EnRailgibud_PerformCutsceneActions",), + 0x80BA8050:("EnRailgibud_Cutscene_Update",), 0x80BA8820:("func_80BA8820",), 0x80BA886C:("func_80BA886C",), 0x80BA8C4C:("func_80BA8C4C",), @@ -15196,9 +15192,9 @@ 0x80BA9E6C:("EnBaba_Init",), 0x80BA9F24:("EnBaba_Destroy",), 0x80BA9F50:("EnBaba_Update",), - 0x80BA9FB0:("func_80BA9FB0",), - 0x80BAA198:("func_80BAA198",), - 0x80BAA20C:("func_80BAA20C",), + 0x80BA9FB0:("EnBaba_OverrideLimbDraw",), + 0x80BAA198:("EnBaba_PostLimbDraw",), + 0x80BAA20C:("EnBaba_TransformLimbDraw",), 0x80BAA220:("EnBaba_Draw",), 0x80BAA6D0:("EnSuttari_UpdateCollider",), 0x80BAA848:("EnSuttari_GetActorById",), @@ -15215,7 +15211,7 @@ 0x80BAB434:("func_80BAB434",), 0x80BAB490:("EnSuttari_GetPaths",), 0x80BAB4F0:("func_80BAB4F0",), - 0x80BAB698:("func_80BAB698",), + 0x80BAB698:("EnSuttari_GetDistSqAndOrient",), 0x80BAB758:("func_80BAB758",), 0x80BAB8F4:("func_80BAB8F4",), 0x80BABA90:("func_80BABA90",), @@ -15251,7 +15247,7 @@ 0x80BAE108:("EnSuttari_Update",), 0x80BAE250:("EnSuttari_OverrideLimbDraw",), 0x80BAE3C4:("EnSuttari_PostLimbDraw",), - 0x80BAE524:("EnSuttari_UnkDraw",), + 0x80BAE524:("EnSuttari_TransformLimbDraw",), 0x80BAE538:("EnSuttari_Draw",), 0x80BAEF70:("EnZod_Init",), 0x80BAF1C0:("EnZod_Destroy",), @@ -15278,23 +15274,23 @@ 0x80BB03E8:("EnZod_Draw",), 0x80BB08E0:("EnKujiya_Init",), 0x80BB0998:("EnKujiya_Destroy",), - 0x80BB09A8:("func_80BB09A8",), - 0x80BB09BC:("func_80BB09BC",), - 0x80BB0B28:("func_80BB0B28",), - 0x80BB0BF8:("func_80BB0BF8",), - 0x80BB0E44:("func_80BB0E44",), - 0x80BB0E58:("func_80BB0E58",), - 0x80BB0F24:("func_80BB0F24",), - 0x80BB0F38:("func_80BB0F38",), - 0x80BB0F94:("func_80BB0F94",), - 0x80BB0FA8:("func_80BB0FA8",), - 0x80BB0FF8:("func_80BB0FF8",), - 0x80BB1088:("func_80BB1088",), - 0x80BB10F8:("func_80BB10F8",), - 0x80BB1168:("func_80BB1168",), - 0x80BB1180:("func_80BB1180",), - 0x80BB1250:("func_80BB1250",), - 0x80BB1268:("func_80BB1268",), + 0x80BB09A8:("EnKujiya_SetupWait",), + 0x80BB09BC:("EnKujiya_Wait",), + 0x80BB0B28:("EnKujiya_HandlePlayerChoice",), + 0x80BB0BF8:("EnKujiya_ChooseNextDialogue",), + 0x80BB0E44:("EnKujiya_SetupTalk",), + 0x80BB0E58:("EnKujiya_Talk",), + 0x80BB0F24:("EnKujiya_SetupGivePrize",), + 0x80BB0F38:("EnKujiya_GivePrize",), + 0x80BB0F94:("EnKujiya_SetupFinishGivePrize",), + 0x80BB0FA8:("EnKujiya_FinishGivePrize",), + 0x80BB0FF8:("EnKujiya_CheckBoughtTicket",), + 0x80BB1088:("EnKujiya_SetBoughtTicket",), + 0x80BB10F8:("EnKujiya_UnsetBoughtTicket",), + 0x80BB1168:("EnKujiya_SetupTurnToOpen",), + 0x80BB1180:("EnKujiya_TurnToOpen",), + 0x80BB1250:("EnKujiya_SetupTurnToClosed",), + 0x80BB1268:("EnKujiya_TurnToClosed",), 0x80BB1338:("EnKujiya_Update",), 0x80BB135C:("EnKujiya_Draw",), 0x80BB16D0:("func_80BB16D0",), @@ -15328,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_TransformLimbDraw",), 0x80BB3BE0:("func_80BB3BE0",), 0x80BB3CB4:("func_80BB3CB4",), 0x80BB3E0C:("EnGeg_Draw",), @@ -15364,30 +15360,30 @@ 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",), 0x80BB9A1C:("func_80BB9A1C",), - 0x80BB9B40:("func_80BB9B40",), - 0x80BB9C08:("func_80BB9C08",), - 0x80BB9F24:("func_80BB9F24",), - 0x80BBA2FC:("func_80BBA2FC",), - 0x80BBA314:("func_80BBA314",), - 0x80BBA488:("func_80BBA488",), + 0x80BB9B40:("ObjChan_CalculatePotPosition",), + 0x80BB9C08:("ObjChan_InitChandelier",), + 0x80BB9F24:("ObjChan_ChandelierAction",), + 0x80BBA2FC:("ObjChan_InitPot",), + 0x80BBA314:("ObjChan_PotAction",), + 0x80BBA488:("ObjChan_CreateSmashParticles",), 0x80BBA738:("ObjChan_Update",), 0x80BBA78C:("ObjChan_Draw",), - 0x80BBA894:("func_80BBA894",), + 0x80BBA894:("ObjChan_DrawPot",), 0x80BBA930:("func_80BBA930",), 0x80BBACA0:("EnZos_Init",), 0x80BBAE60:("EnZos_Destroy",), @@ -15507,9 +15503,9 @@ 0x80BC2388:("EnJa_Init",), 0x80BC2498:("EnJa_Destroy",), 0x80BC24C4:("EnJa_Update",), - 0x80BC25E0:("func_80BC25E0",), - 0x80BC2620:("func_80BC2620",), - 0x80BC2B30:("func_80BC2B30",), + 0x80BC25E0:("EnJa_OverrideLimbDraw",), + 0x80BC2620:("EnJa_PostLimbDraw",), + 0x80BC2B30:("EnJa_TransformLimbDraw",), 0x80BC2CE4:("EnJa_Draw",), 0x80BC2EA4:("func_80BC2EA4",), 0x80BC3154:("func_80BC3154",), @@ -15535,14 +15531,14 @@ 0x80BC457C:("func_80BC457C",), 0x80BC458C:("BgF40Block_Update",), 0x80BC45CC:("BgF40Block_Draw",), - 0x80BC47B0:("func_80BC47B0",), + 0x80BC47B0:("BgF40Switch_CheckAll",), 0x80BC4A3C:("BgF40Switch_Init",), 0x80BC4AEC:("BgF40Switch_Destroy",), - 0x80BC4B20:("func_80BC4B20",), - 0x80BC4B94:("func_80BC4B94",), - 0x80BC4BB8:("func_80BC4BB8",), - 0x80BC4C68:("func_80BC4C68",), - 0x80BC4D30:("func_80BC4D30",), + 0x80BC4B20:("BgF40Switch_Unpress",), + 0x80BC4B94:("BgF40Switch_IdlePressed",), + 0x80BC4BB8:("BgF40Switch_Press",), + 0x80BC4C68:("BgF40Switch_WaitToPress",), + 0x80BC4D30:("BgF40Switch_IdleUnpressed",), 0x80BC4D54:("BgF40Switch_Update",), 0x80BC4D90:("BgF40Switch_Draw",), 0x80BC4F30:("EnPoComposer_Init",), @@ -15645,9 +15641,9 @@ 0x80BCC508:("EnScopenuts_Init",), 0x80BCC77C:("EnScopenuts_Destroy",), 0x80BCC7A8:("EnScopenuts_Update",), - 0x80BCC828:("func_80BCC828",), - 0x80BCC9CC:("func_80BCC9CC",), - 0x80BCC9E4:("func_80BCC9E4",), + 0x80BCC828:("EnScopenuts_OverrideLimbDraw",), + 0x80BCC9CC:("EnScopenuts_PostLimbDraw",), + 0x80BCC9E4:("EnScopenuts_TransformLimbDraw",), 0x80BCCAAC:("EnScopenuts_Draw",), 0x80BCD000:("func_80BCD000",), 0x80BCD09C:("func_80BCD09C",), @@ -15704,14 +15700,14 @@ 0x80BD0434:("func_80BD0434",), 0x80BD049C:("func_80BD049C",), 0x80BD04E0:("func_80BD04E0",), - 0x80BD064C:("func_80BD064C",), - 0x80BD0660:("func_80BD0660",), + 0x80BD064C:("EnHgo_SetupDialogueHandler",), + 0x80BD0660:("EnHgo_DefaultDialogueHandler",), 0x80BD06FC:("func_80BD06FC",), 0x80BD0898:("func_80BD0898",), 0x80BD0B8C:("func_80BD0B8C",), 0x80BD0C30:("EnHgo_Update",), - 0x80BD0CF0:("func_80BD0CF0",), - 0x80BD0D38:("func_80BD0D38",), + 0x80BD0CF0:("EnHgo_OverrideLimbDraw",), + 0x80BD0D38:("EnHgo_PostLimbDraw",), 0x80BD0D7C:("EnHgo_Draw",), 0x80BD11E0:("EnZov_Init",), 0x80BD13B0:("EnZov_Destroy",), @@ -15734,8 +15730,8 @@ 0x80BD1F1C:("func_80BD1F1C",), 0x80BD1FC8:("func_80BD1FC8",), 0x80BD20B4:("EnZov_Update",), - 0x80BD2380:("func_80BD2380",), - 0x80BD2404:("func_80BD2404",), + 0x80BD2380:("EnZov_OverrideLimbDraw",), + 0x80BD2404:("EnZov_PostLimbDraw",), 0x80BD24B4:("EnZov_Draw",), 0x80BD2A30:("func_80BD2A30",), 0x80BD2AE0:("func_80BD2AE0",), @@ -15762,8 +15758,8 @@ 0x80BD3854:("EnAh_Init",), 0x80BD396C:("EnAh_Destroy",), 0x80BD3998:("EnAh_Update",), - 0x80BD3AA8:("func_80BD3AA8",), - 0x80BD3AF8:("func_80BD3AF8",), + 0x80BD3AA8:("EnAh_PostLimbDraw",), + 0x80BD3AF8:("EnAh_TransformLimbDraw",), 0x80BD3CAC:("EnAh_Draw",), 0x80BD4090:("ObjHgdoor_SetChild",), 0x80BD40D0:("func_80BD40D0",), @@ -16033,9 +16029,9 @@ 0x80BDF75C:("EnAl_Init",), 0x80BDF840:("EnAl_Destroy",), 0x80BDF86C:("EnAl_Update",), - 0x80BDF914:("func_80BDF914",), - 0x80BDF950:("func_80BDF950",), - 0x80BDFA34:("func_80BDFA34",), + 0x80BDF914:("EnAl_OverrideLimbDraw",), + 0x80BDF950:("EnAl_PostLimbDraw",), + 0x80BDFA34:("EnAl_TransformLimbDraw",), 0x80BDFB30:("EnAl_Draw",), 0x80BE04E0:("func_80BE04E0",), 0x80BE0590:("func_80BE0590",), @@ -16061,9 +16057,9 @@ 0x80BE1424:("EnTab_Init",), 0x80BE1524:("EnTab_Destroy",), 0x80BE1550:("EnTab_Update",), - 0x80BE1648:("func_80BE1648",), - 0x80BE16B4:("func_80BE16B4",), - 0x80BE1704:("func_80BE1704",), + 0x80BE1648:("EnTab_OverrideLimbDraw",), + 0x80BE16B4:("EnTab_PostLimbDraw",), + 0x80BE1704:("EnTab_TransformDraw",), 0x80BE1810:("EnTab_Draw",), 0x80BE1C80:("func_80BE1C80",), 0x80BE1CEC:("EnNimotsu_Init",), @@ -16072,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",), @@ -16098,10 +16094,10 @@ 0x80BE393C:("EnRuppecrow_Draw",), 0x80BE3B80:("EnTanron4_Init",), 0x80BE3DB0:("EnTanron4_Destroy",), - 0x80BE3DC0:("func_80BE3DC0",), - 0x80BE3DFC:("func_80BE3DFC",), - 0x80BE4268:("func_80BE4268",), - 0x80BE42A4:("func_80BE42A4",), + 0x80BE3DC0:("EnTanron4_SetupFlyNearHome",), + 0x80BE3DFC:("EnTanron4_FlyNearHome",), + 0x80BE4268:("EnTanron4_SetupFlyNearActor",), + 0x80BE42A4:("EnTanron4_FlyNearActor",), 0x80BE4734:("EnTanron4_Update",), 0x80BE4804:("EnTanron4_Draw",), 0x80BE4930:("func_80BE4930",), @@ -16165,23 +16161,23 @@ 0x80BE8D94:("EnBaisen_Draw",), 0x80BE8F20:("EnHeishi_Init",), 0x80BE9090:("EnHeishi_Destroy",), - 0x80BE90BC:("func_80BE90BC",), - 0x80BE9148:("func_80BE9148",), - 0x80BE91DC:("func_80BE91DC",), - 0x80BE9214:("func_80BE9214",), + 0x80BE90BC:("EnHeishi_ChangeAnimation",), + 0x80BE9148:("EnHeishi_SetHeadRotation",), + 0x80BE91DC:("EnHeishi_SetupIdle",), + 0x80BE9214:("EnHeishi_Idle",), 0x80BE9224:("EnHeishi_Update",), - 0x80BE9380:("func_80BE9380",), + 0x80BE9380:("EnHeishi_OverrideLimbDraw",), 0x80BE93D8:("EnHeishi_Draw",), 0x80BE9510:("EnDemoheishi_Init",), 0x80BE95C0:("EnDemoheishi_Destroy",), - 0x80BE95EC:("func_80BE95EC",), - 0x80BE9678:("func_80BE9678",), - 0x80BE970C:("func_80BE970C",), - 0x80BE975C:("func_80BE975C",), - 0x80BE97F0:("func_80BE97F0",), - 0x80BE980C:("func_80BE980C",), + 0x80BE95EC:("EnDemoheishi_ChangeAnimation",), + 0x80BE9678:("EnDemoheishi_SetHeadRotation",), + 0x80BE970C:("EnDemoheishi_SetupIdle",), + 0x80BE975C:("EnDemoheishi_Idle",), + 0x80BE97F0:("EnDemoheishi_SetupTalk",), + 0x80BE980C:("EnDemoheishi_Talk",), 0x80BE9864:("EnDemoheishi_Update",), - 0x80BE9974:("func_80BE9974",), + 0x80BE9974:("EnDemoheishi_OverrideLimbDraw",), 0x80BE99CC:("EnDemoheishi_Draw",), 0x80BE9B20:("EnDt_Init",), 0x80BE9C48:("EnDt_Destroy",), @@ -16276,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_TransformLimbDraw",), 0x80BF0258:("EnAkindonuts_Draw",), 0x80BF0D90:("EffStk_Init",), 0x80BF0DD0:("EffStk_Destroy",), @@ -16319,9 +16315,9 @@ 0x80BF2CC0:("EnIg_Init",), 0x80BF2DC4:("EnIg_Destroy",), 0x80BF2E04:("EnIg_Update",), - 0x80BF2EDC:("func_80BF2EDC",), - 0x80BF2EFC:("func_80BF2EFC",), - 0x80BF302C:("func_80BF302C",), + 0x80BF2EDC:("EnIg_OverrideLimbDraw",), + 0x80BF2EFC:("EnIg_PostLimbDraw",), + 0x80BF302C:("EnIg_TransformLimbDraw",), 0x80BF312C:("EnIg_Draw",), 0x80BF3920:("func_80BF3920",), 0x80BF3C64:("func_80BF3C64",), @@ -16383,24 +16379,24 @@ 0x80BFA100:("EnYb_Init",), 0x80BFA2D0:("EnYb_Destroy",), 0x80BFA2FC:("func_80BFA2FC",), - 0x80BFA350:("func_80BFA350",), - 0x80BFA444:("func_80BFA444",), - 0x80BFA5CC:("func_80BFA5CC",), - 0x80BFA634:("func_80BFA634",), - 0x80BFA67C:("func_80BFA67C",), - 0x80BFA6E0:("func_80BFA6E0",), - 0x80BFA710:("func_80BFA710",), - 0x80BFA730:("func_80BFA730",), - 0x80BFA868:("func_80BFA868",), - 0x80BFA91C:("func_80BFA91C",), - 0x80BFA9D4:("func_80BFA9D4",), - 0x80BFAB4C:("func_80BFAB4C",), - 0x80BFABF0:("func_80BFABF0",), - 0x80BFAC88:("func_80BFAC88",), - 0x80BFAE80:("func_80BFAE80",), + 0x80BFA350:("EnYb_ActorShadowFunc",), + 0x80BFA444:("EnYb_SetAnimation",), + 0x80BFA5CC:("EnYb_CanTalk",), + 0x80BFA634:("EnYb_UpdateAnimation",), + 0x80BFA67C:("EnYb_FinishTeachingCutscene",), + 0x80BFA6E0:("EnYb_ChangeCutscene",), + 0x80BFA710:("EnYb_EnableProximityMusic",), + 0x80BFA730:("EnYb_Disappear",), + 0x80BFA868:("EnYb_SetupLeaving",), + 0x80BFA91C:("EnYb_ReceiveMask",), + 0x80BFA9D4:("EnYb_Talk",), + 0x80BFAB4C:("EnYb_TeachingDanceFinish",), + 0x80BFABF0:("EnYb_TeachingDance",), + 0x80BFAC88:("EnYb_Idle",), + 0x80BFAE80:("EnYb_WaitForMidnight",), 0x80BFAEFC:("EnYb_Update",), - 0x80BFB074:("func_80BFB074",), - 0x80BFB0E0:("func_80BFB0E0",), + 0x80BFB074:("EnYb_PostLimbDrawOpa",), + 0x80BFB0E0:("EnYb_PostLimbDrawXlu",), 0x80BFB14C:("EnYb_Draw",), 0x80BFB480:("EnRz_Init",), 0x80BFB780:("func_80BFB780",), @@ -16487,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",), @@ -16519,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",), @@ -16534,11 +16530,11 @@ 0x80C04354:("func_80C04354",), 0x80C043C8:("func_80C043C8",), 0x80C0443C:("EnBombers_Update",), - 0x80C045B4:("func_80C045B4",), + 0x80C045B4:("EnBombers_OverrideLimbDraw",), 0x80C04614:("EnBombers_Draw",), 0x80C04930:("EnBombers2_Init",), 0x80C04A80:("EnBombers2_Destroy",), - 0x80C04AAC:("func_80C04AAC",), + 0x80C04AAC:("EnBombers2_ChangeAnim",), 0x80C04B40:("func_80C04B40",), 0x80C04BA0:("func_80C04BA0",), 0x80C04D00:("func_80C04D00",), @@ -16622,10 +16618,10 @@ 0x80C08950:("EnNnh_Draw",), 0x80C08A80:("ObjKzsaku_Init",), 0x80C08B2C:("ObjKzsaku_Destroy",), - 0x80C08B60:("func_80C08B60",), - 0x80C08B7C:("func_80C08B7C",), + 0x80C08B60:("ObjKzsaku_SetupIdle",), + 0x80C08B7C:("ObjKzsaku_Idle",), 0x80C08BBC:("func_80C08BBC",), - 0x80C08BD0:("func_80C08BD0",), + 0x80C08BD0:("ObjKzsaku_Rise",), 0x80C08C84:("func_80C08C84",), 0x80C08CB0:("func_80C08CB0",), 0x80C08D20:("ObjKzsaku_Update",), @@ -16742,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_TransformLimbDraw",), 0x80C105EC:("EnRecepgirl_Draw",), 0x80C10770:("EnThiefbird_Init",), 0x80C10958:("EnThiefbird_Destroy",), @@ -16815,8 +16811,8 @@ 0x80C14D14:("func_80C14D14",), 0x80C14D58:("func_80C14D58",), 0x80C14E08:("EnJgameTsn_Update",), - 0x80C14E64:("func_80C14E64",), - 0x80C14EE4:("func_80C14EE4",), + 0x80C14E64:("EnJgamesTsn_OverrideLimbDraw",), + 0x80C14EE4:("EnJgamesTsn_PostLimbDraw",), 0x80C14F1C:("EnJgameTsn_Draw",), 0x80C152F0:("ObjJgameLight_Init",), 0x80C1542C:("ObjJgameLight_Destroy",), @@ -16976,16 +16972,16 @@ 0x80C1E048:("DmNb_Init",), 0x80C1E0F8:("DmNb_Destroy",), 0x80C1E108:("DmNb_Update",), - 0x80C1E168:("DmNb_UnkActorDraw",), + 0x80C1E168:("DmNb_TransformLimbDraw",), 0x80C1E17C:("DmNb_Draw",), - 0x80C1E290:("func_80C1E290",), - 0x80C1E2D4:("func_80C1E2D4",), - 0x80C1E3DC:("func_80C1E3DC",), + 0x80C1E290:("EnDrs_CollisionUpdate",), + 0x80C1E2D4:("EnDrs_Setup",), + 0x80C1E3DC:("EnDrs_Idle",), 0x80C1E3EC:("EnDrs_Init",), 0x80C1E424:("EnDrs_Destroy",), 0x80C1E450:("EnDrs_Update",), - 0x80C1E4B0:("func_80C1E4B0",), - 0x80C1E568:("func_80C1E568",), + 0x80C1E4B0:("EnDrs_PostLimbDraw",), + 0x80C1E568:("EnDrs_Draw",), 0x80C1E690:("EnEndingHero_Init",), 0x80C1E738:("EnEndingHero_Destroy",), 0x80C1E748:("func_80C1E748",), @@ -17050,8 +17046,8 @@ 0x80C21468:("func_80C21468",), 0x80C215E4:("func_80C215E4",), 0x80C21790:("EnHintSkb_Update",), - 0x80C21858:("func_80C21858",), - 0x80C219D4:("func_80C219D4",), + 0x80C21858:("EnHintSkb_OverrideLimbDraw",), + 0x80C219D4:("EnHintSkb_PostLimbDraw",), 0x80C21B9C:("EnHintSkb_Draw",), 0x80C22350:("func_80C22350",), 0x80C22400:("func_80C22400",), @@ -17094,7 +17090,7 @@ 0x80C23980:("func_80C23980",), 0x80C2399C:("func_80C2399C",), 0x80C239C8:("EnEndingHero5_Update",), - 0x80C23A30:("func_80C23A30",), + 0x80C23A30:("EnEndingHero5_PostLimbDraw",), 0x80C23A7C:("EnEndingHero5_Draw",), 0x80C23C90:("EnEndingHero6_Init",), 0x80C23D50:("EnEndingHero6_Destroy",), @@ -17116,8 +17112,8 @@ 0x80C24BE0:("DmGm_Init",), 0x80C24C34:("DmGm_Destroy",), 0x80C24C44:("DmGm_Update",), - 0x80C24CD0:("func_80C24CD0",), - 0x80C24E4C:("func_80C24E4C",), + 0x80C24CD0:("DmGm_PostLimbDraw",), + 0x80C24E4C:("DmGm_TransformLimbDraw",), 0x80C25000:("func_80C25000",), 0x80C25360:("func_80C25360",), 0x80C253D0:("func_80C253D0",), diff --git a/tools/disasm/mips_isa.py b/tools/disasm/mips_isa.py index 44cddacd7..337bbd021 100644 --- a/tools/disasm/mips_isa.py +++ b/tools/disasm/mips_isa.py @@ -286,15 +286,26 @@ mips_cop0_names = [ "TagLo" , "TagHi" , "ErrorEPC" , "Reserved31", ] -mips_fpr_names = [ +numeric_fpr_names = [ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", - "$31", + "$31", # Floating-point control/status register ] +o32_fpr_names = [ + "$fv0", "$fv0f", "$fv1", "$fv1f", + "$ft0", "$ft0f", "$ft1", "$ft1f", "$ft2", "$ft2f", "$ft3", "$ft3f", + "$fa0", "$fa0f", "$fa1", "$fa1f", + "$ft4", "$ft4f", "$ft5", "$ft5f", + "$fs0", "$fs0f", "$fs1", "$fs1f", "$fs2", "$fs2f", "$fs3", "$fs3f", "$fs4", "$fs4f", "$fs5", + "$31", # Floating-point control/status register +] + +mips_fpr_names = numeric_fpr_names + # Instruction field fetching def sign_extend_16(value): diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index c30c80ce6..199b13a05 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), @@ -35,7 +35,9 @@ 0x80096CD0:("sGfxPrintUnkTLUT","u16","[16]",0x20), 0x80096CF0:("sGfxPrintUnkData","u8","[8]",0x8), 0x80096CF8:("sGfxPrintFontData","u8","[0x800]",0x800), - 0x80097500:("D_80097500","UNK_TYPE4","",0x4), + 0x80097500:("sInitFuncs","void*","",0x4), + 0x80097504:("sNew","char","[4]",0x4), + 0x80097508:("D_80097508","[24]","",0x18), 0x80097520:("qNaN0x3FFFFF","f32","",0x4), 0x80097524:("qNaN0x10000","f32","",0x4), 0x80097528:("sNaN0x3FFFFF","f32","",0x4), @@ -72,16 +74,16 @@ 0x80097FA0:("D_80097FA0","UNK_TYPE1","",0x1), 0x80097FA4:("D_80097FA4","UNK_TYPE1","",0x1), 0x80097FA5:("D_80097FA5","UNK_TYPE1","",0x1), - 0x80097FB0:("D_80097FB0","UNK_TYPE4","",0x4), + 0x80097FB0:("__osPfsLastChannel","s32","",0x4), 0x80097FC0:("osViModeNtscLan1","OSViMode","",0x50), 0x80098010:("osViModeMpalLan1","OSViMode","",0x50), 0x80098060:("D_80098060","__OSViContext","[2]",0x60), 0x800980C0:("__osViCurr","__OSViContext*","",0x4), 0x800980C4:("__osViNext","__OSViContext*","",0x4), - 0x800980D0:("D_800980D0","UNK_TYPE4","",0x4), + 0x800980D0:("sCartRomNeedsInit","UNK_TYPE4","",0x4), 0x800980E0:("osViModeFpalLan1","OSViMode","",0x50), - 0x80098130:("ldigs","char","[]",0x14), - 0x80098144:("udigs","char","[]",0x14), + 0x80098130:("ldigs","u8","[]",0x14), + 0x80098144:("udigs","u8","[]",0x14), 0x80098160:("__osViDevMgr","OSDevMgr","",0x1c), 0x8009817C:("__additional_scanline","UNK_TYPE4","",0x4), 0x80098180:("D_80098180","UNK_TYPE1","",0x1), @@ -331,7 +333,7 @@ 0x8009CEB8:("__osSiAccessQueue","OSMesgQueue","",0x18), 0x8009CED0:("__osContPifRam","OSPifRam","",0x40), 0x8009CF0C:("D_8009CF0C","UNK_TYPE1","",0x1), - 0x8009CF10:("__osContLastCmd","u8","",0x1), + 0x8009CF10:("__osContLastPoll","u8","",0x1), 0x8009CF11:("__osMaxControllers","u8","",0x1), 0x8009CF18:("__osEepromTimer","OSTimer","",0x20), 0x8009CF38:("D_8009CF38","OSMesgQueue","",0x18), @@ -364,10 +366,10 @@ 0x8009F888:("viCounterMsg","OSIoMesg","",0x18), 0x8009F8A0:("viRetrace","u16","",0x2), 0x8009F8B0:("dmadata","DmaEntry","[1568]",0x6200), - 0x80186028:("D_80186028","UNK_TYPE1","",0x1), - 0x801AAAB0:("D_801AAAB0","UNK_TYPE1","",0x1), - 0x801ABAB0:("D_801ABAB0","UNK_TYPE1","",0x1), - 0x801AD370:("D_801AD370","UNK_TYPE1","",0x1), + 0x80186028:("D_80186028","s16","[1316]",0xa48), + 0x801AAAB0:("aspMainTextStart","UNK_TYPE1","",0x1), + 0x801ABAB0:("gspS2DEX2_fifoTextStart","UNK_TYPE1","",0x1), + 0x801AD370:("njpgdspMainTextStart","UNK_TYPE1","",0x1), 0x801ADE60:("En_A_Obj_InitVars","ActorInit","",0x20), 0x801ADE80:("enAObjCylinderInit","ColliderCylinderInit","",0x2c), 0x801ADEAC:("enAObjInitVar","ActorInitVar","",0x4), @@ -397,8 +399,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,48 +421,38 @@ 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), 0x801AEC78:("sTimer","s32","",0x4), 0x801AEC80:("D_801AEC80","Color_RGBA8","",0x4), - 0x801AEC84:("D_801AEC84","s801AEC84","[13]",0x68), + 0x801AEC84:("sTatlColorList","TatlColor","[13]",0x68), 0x801AECEC:("actorMovementScale","f32","",0x4), - 0x801AECF0:("D_801AECF0","f32","",0x4), - 0x801AECF4:("D_801AECF4","f32","",0x4), - 0x801AED48:("D_801AED48","UNK_TYPE1","",0x1), + 0x801AECF0:("gTargetRanges","f32","[]",0x58), + 0x801AED48:("D_801AED48","s16","[8]",0x10), 0x801AED58:("D_801AED58","UNK_TYPE4","",0x4), 0x801AED88:("actorDefaultHitColor","Color_RGBA8","",0x4), 0x801AED8C:("D_801AED8C","UNK_TYPE1","",0x1), - 0x801AED98:("D_801AED98","UNK_TYPE4","",0x4), + 0x801AED98:("D_801AED98","Vec3f","",0xC), 0x801AEDA4:("D_801AEDA4","UNK_TYPE4","",0x4), 0x801AEDB0:("D_801AEDB0","UNK_TYPE1","",0x1), 0x801AEDD4:("D_801AEDD4","UNK_TYPE4","",0x4), 0x801AEE28:("D_801AEE28","UNK_TYPE4","",0x4), 0x801AEE30:("D_801AEE30","UNK_TYPE4","",0x4), - 0x801AEE38:("D_801AEE38","UNK_TYPE4","",0x4), - 0x801AEE4C:("D_801AEE4C","UNK_TYPE2","",0x2), + 0x801AEE38:("D_801AEE38","struct_801AEE38","[14]",0x150), 0x801AEF88:("D_801AEF88","UNK_TYPE1","",0x1), 0x801AEFA0:("D_801AEFA0","UNK_TYPE1","",0x1), - 0x801AEFA8:("D_801AEFA8","UNK_TYPE1","",0x1), + 0x801AEFA8:("sElectricSparkTextures","UNK_TYPE1","",0x1), 0x801AEFB8:("D_801AEFB8","UNK_TYPE1","",0x1), 0x801AEFBC:("D_801AEFBC","UNK_TYPE1","",0x1), 0x801AEFC0:("D_801AEFC0","UNK_TYPE1","",0x1), 0x801AEFD0:("gActorOverlayTable","ActorOverlay","[ACTOR_ID_MAX]",0x5640), 0x801B4610:("gMaxActorId","s32","",0x4), - 0x801B4620:("D_801B4620","u32","[32]",0x80), - 0x801B46A0:("D_801B46A0","u16","[16]",0x20), - 0x801B46C0:("D_801B46C0","u8","[16]",0x10), - 0x801B46D0:("bgSpecialSceneParamsDefault","s16","[1]",0x2), - 0x801B46D2:("D_801B46D2","UNK_TYPE1","",0x1), - 0x801B46D4:("bgSpecialSceneMaxMemory","BgSpecialSceneMaxMemory","[1]",0x8), - 0x801B46DC:("bgSpecialSceneMeshSubdivisions","BgSpecialSceneMeshSubdivision","[3]",0x24), - 0x801B4700:("bgSpecialSceneMaxObjects","BgSpecialSceneMaxObjects","[1]",0x8), + 0x801B46DC:("sSceneSubdivisionList","BgCheckSceneSubdivisionEntry","[3]",0x24), + 0x801B4700:("sCustomDynapolyMem","BgSpecialSceneMaxObjects","[1]",0x8), 0x801B4708:("D_801B4708","UNK_TYPE1","",0x1), 0x801B4710:("D_801B4710","UNK_TYPE1","",0x1), 0x801B4738:("D_801B4738","UNK_TYPE1","",0x1), @@ -888,26 +880,25 @@ 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:("D_801BA790","UNK_TYPE1","",0x1), + 0x801BA790:("sDebugDisplay1DL","UNK_TYPE1","",0x1), 0x801BA7F0:("D_801BA7F0","UNK_TYPE1","",0x1), - 0x801BA870:("D_801BA870","UNK_TYPE1","",0x1), + 0x801BA870:("sDebugDisplay2DL","UNK_TYPE1","",0x1), 0x801BA8C0:("D_801BA8C0","UNK_TYPE1","",0x1), 0x801BAAC0:("D_801BAAC0","UNK_TYPE1","",0x1), - 0x801BAB40:("D_801BAB40","UNK_TYPE1","",0x1), + 0x801BAB40:("sDebugDisplay3DL","UNK_TYPE1","",0x1), 0x801BABB8:("D_801BABB8","UNK_TYPE1","",0x1), 0x801BACB8:("D_801BACB8","UNK_TYPE1","",0x1), 0x801BADB8:("D_801BADB8","UNK_TYPE1","",0x1), 0x801BAEB8:("D_801BAEB8","UNK_TYPE1","",0x1), 0x801BAFB8:("D_801BAFB8","UNK_TYPE1","",0x1), - 0x801BAFF8:("D_801BAFF8","UNK_TYPE1","",0x1), - 0x801BB010:("D_801BB010","UNK_TYPE1","",0x1), - 0x801BB018:("D_801BB018","UNK_TYPE1","",0x1), - 0x801BB050:("D_801BB050","UNK_TYPE1","",0x1), - 0x801BB058:("D_801BB058","UNK_TYPE1","",0x1), + 0x801BAFF8:("gDebugSpriteDL","UNK_TYPE1","",0x1), + 0x801BB010:("sDebugObjectDrawFuncTable","UNK_TYPE1","",0x1), + 0x801BB018:("sDebugObjectInfoTable","UNK_TYPE1","",0x1), + 0x801BB050:("sDebugDisplayLight1","Lights1","",0x24), 0x801BB068:("D_801BB068","UNK_TYPE2","",0x2), 0x801BB08C:("D_801BB08C","UNK_TYPE1","",0x1), 0x801BB090:("D_801BB090","UNK_TYPE4","",0x4), @@ -918,7 +909,7 @@ 0x801BB124:("D_801BB124","UNK_TYPE2","",0x2), 0x801BB128:("D_801BB128","UNK_TYPE2","",0x2), 0x801BB12C:("D_801BB12C","UNK_TYPE1","",0x1), - 0x801BB130:("D_801BB130","UNK_TYPE1","",0x1), + 0x801BB130:("sCutsceneStoredPlayerForm","UNK_TYPE1","",0x1), 0x801BB134:("sCsStateHandlers1","cutscene_update_func","[5]",0x14), 0x801BB148:("sCsStateHandlers2","cutscene_update_func","[5]",0x14), 0x801BB15C:("D_801BB15C","UNK_TYPE2","",0x2), @@ -928,9 +919,9 @@ 0x801BC240:("D_801BC240","Gfx","[9]",0x48), 0x801BC288:("D_801BC288","Gfx","[3]",0x18), 0x801BC2A0:("D_801BC2A0","UNK_TYPE1","",0x1), - 0x801BC3F0:("D_801BC3F0","UNK_TYPE1","",0x1), - 0x801BC400:("D_801BC400","UNK_TYPE1","",0x1), - 0x801BC410:("D_801BC410","UNK_TYPE1","",0x1), + 0x801BC3F0:("gEnHyBodyParts","UNK_TYPE1","",0x1), + 0x801BC400:("gEnHyParentBodyParts","UNK_TYPE1","",0x1), + 0x801BC410:("gEnHyShadowSizes","s32",[],0x10), 0x801BC420:("sReactionTextIds","u16","[]",0x140A), 0x801BD830:("actorCutscenesGlobalCutscenes","ActorCutscene","[8]",0x80), 0x801BD8B0:("actorCutsceneCurrent","s16","",0x2), @@ -942,8 +933,9 @@ 0x801BD8C0:("actorCutscenesGlobalCtxt","GlobalContext*","",0x4), 0x801BD8C4:("actorCutsceneReturnCamera","s16","",0x2), 0x801BD8C6:("D_801BD8C6","s16","",0x2), - 0x801BD8D0:("fireObjCollisionInit","ColliderCylinderInit","",0x2c), - 0x801BD8FC:("D_801BD8FC","FireObjLightParams","[2]",0x10), + 0x801BD8D0:("sFireObjCollisionInit","ColliderCylinderInit","",0x2c), + 0x801BD8FC:("sFireObjColors","FireObjColors","[1]",0x08), + 0x801BD904:("sFireObjLightParams","FireObjLightParams","[1]",0x08), 0x801BD910:("gGameStateOverlayTable","GameStateOverlay","[7]",0x150), 0x801BDA60:("graphNumGameStates","UNK_TYPE4","",0x4), 0x801BDA70:("D_801BDA70","UNK_TYPE2","",0x2), @@ -968,8 +960,8 @@ 0x801BDAF0:("D_801BDAF0","UNK_TYPE4","",0x4), 0x801BDAF8:("D_801BDAF8","UNK_TYPE4","",0x4), 0x801BDB00:("D_801BDB00","UNK_TYPE1","",0x1), - 0x801BDB08:("D_801BDB08","UNK_TYPE1","",0x1), - 0x801BDB18:("D_801BDB18","UNK_TYPE1","",0x1), + 0x801BDB08:("sKaleidoSetupEyeX","UNK_TYPE1","",0x1), + 0x801BDB18:("sKaleidoSetupEyeZ","UNK_TYPE1","",0x1), 0x801BDB30:("kanfontOrdering","u8","[92]",0x5c), 0x801BDB90:("D_801BDB90","f32","",0x4), 0x801BDB94:("D_801BDB94","UNK_TYPE4","",0x4), @@ -1389,15 +1381,15 @@ 0x801C1DC0:("gUpgradeMasks","u32","[8]",0x20), 0x801C1DE0:("gUpgradeNegMasks","UNK_TYPE1","",0x1), 0x801C1E00:("gEquipShifts","u8","[4]",0x4), - 0x801C1E04:("gUpgradeShifts","u8","[16]",0x10), - 0x801C1E14:("gUpgradeCapacities","UNK_TYPE1","[]",0x38), + 0x801C1E04:("gUpgradeShifts","u8","[8]",0x8), + 0x801C1E0C:("gUpgradeCapacities","UNK_TYPE1","[]",0x40), 0x801C1E4C:("gGsFlagsMask","UNK_TYPE2","",0x2), 0x801C1E5C:("gGsFlagsShift","UNK_TYPE2","",0x2), 0x801C1E6C:("gItemIcons","UNK_PTR","[131]",0x20C), 0x801C2078:("gItemSlots","u8","[80]",0x50), 0x801C20C8:("gItemPrices","UNK_TYPE1","",0x1), 0x801C212C:("gScenesPerRegion","SceneIdList","[]",0x252), - 0x801C2380:("D_801C2380","u16","[]",0x90), + 0x801C2380:("sScenesPerTingleMap","u16","[]",0x90), 0x801C2410:("D_801C2410","UNK_TYPE1","",0x1), 0x801C2650:("tatlMessageFiles","RomFile","[2]",0x10), 0x801C2660:("sceneTextureFiles","RomFile","[9]",0x48), @@ -1979,9 +1971,9 @@ 0x801C5CD0:("sMtxFClear","MtxF","",0x40), 0x801C5D10:("D_801C5D10","UNK_TYPE1","",0x1), 0x801C5D20:("D_801C5D20","UNK_TYPE1","",0x1), - 0x801C5D60:("D_801C5D60","UNK_TYPE1","",0x1), - 0x801C5D80:("D_801C5D80","UNK_TYPE1","",0x1), - 0x801C5DB0:("D_801C5DB0","UNK_TYPE1","",0x1), + 0x801C5D60:("gShadowDL","UNK_TYPE1","",0x1), + 0x801C5D80:("gShadowVtxDL","UNK_TYPE1","",0x1), + 0x801C5DB0:("gOneVec3f","UNK_TYPE1","",0x1), 0x801C5DD0:("D_801C5DD0","UNK_TYPE1","",0x1), 0x801C5DE0:("D_801C5DE0","UNK_TYPE1","",0x1), 0x801C5DF0:("D_801C5DF0","UNK_TYPE1","",0x1), @@ -1993,33 +1985,27 @@ 0x801C5EB0:("D_801C5EB0","UNK_TYPE4","",0x4), 0x801C5EC4:("D_801C5EC4","UNK_TYPE2","",0x2), 0x801C5F44:("D_801C5F44","UNK_TYPE4","",0x4), - 0x801C5FC0:("D_801C5FC0","UNK_TYPE4","",0x4), - 0x801C5FC4:("D_801C5FC4","UNK_TYPE4","",0x4), - 0x801C5FC8:("D_801C5FC8","UNK_TYPE4","",0x4), - 0x801C5FCC:("D_801C5FCC","UNK_TYPE4","",0x4), - 0x801C5FD0:("D_801C5FD0","UNK_TYPE4","",0x4), + 0x801C5FC0:("D_801C5FC0","u32","[452]",0x710), 0x801C66D0:("D_801C66D0","UNK_TYPE2","",0x2), 0x801C6798:("D_801C6798","UNK_TYPE4","",0x4), 0x801C67B0:("D_801C67B0","UNK_TYPE1","",0x1), - 0x801C67C8:("D_801C67C8","UNK_TYPE4","",0x4), - 0x801C67CC:("D_801C67CC","UNK_TYPE4","",0x4), + 0x801C67C8:("D_801C67C8","s32","[8]",0x20), 0x801C67E8:("D_801C67E8","UNK_TYPE4","",0x4), - 0x801C67F0:("D_801C67F0","UNK_TYPE4","",0x4), - 0x801C67F4:("D_801C67F4","UNK_TYPE4","",0x4), + 0x801C67F0:("D_801C67F0","s32","[8]",0x20), 0x801C6818:("D_801C6818","UNK_TYPE1","",0x1), 0x801C6838:("D_801C6838","UNK_TYPE4","",0x4), 0x801C6840:("D_801C6840","UNK_TYPE1","",0x1), 0x801C6850:("D_801C6850","UNK_TYPE1","",0x1), 0x801C6870:("D_801C6870","UNK_TYPE1","",0x1), 0x801C6890:("D_801C6890","UNK_TYPE1","",0x1), - 0x801C6898:("D_801C6898","SaveInfo","",0x28), - 0x801C68C0:("D_801C68C0","SaveContext_struct2","",0x22), - 0x801C68E4:("gSaveDefaultInventory","Inventory","",0x88), - 0x801C696C:("gSaveDefaultChecksum","u16","",0x2), - 0x801C6970:("D_801C6970","SaveInfo","",0x28), - 0x801C6998:("D_801C6998","SaveContext_struct2","",0x22), - 0x801C69BC:("D_801C69BC","Inventory","",0x88), - 0x801C6A44:("D_801C6A44","u16","",0x2), + 0x801C6898:("sSaveDefaultPlayerData","SavePlayerData","",0x28), + 0x801C68C0:("sSaveDefaultItemEquips","ItemEquips","",0x22), + 0x801C68E4:("sSaveDefaultInventory","Inventory","",0x88), + 0x801C696C:("sSaveDefaultChecksum","u16","",0x2), + 0x801C6970:("sSaveDebugPlayerData","SaveInfo","",0x28), + 0x801C6998:("sSaveDebugItemEquips","ItemEquips","",0x22), + 0x801C69BC:("sSaveDebugInventory","Inventory","",0x88), + 0x801C6A44:("sSaveDebugChecksum","u16","",0x2), 0x801C6A48:("D_801C6A48","UNK_TYPE1","",0x1), 0x801C6A50:("D_801C6A50","UNK_TYPE1","",0x1), 0x801C6A58:("D_801C6A58","UNK_TYPE1","",0x1), @@ -2176,9 +2162,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), @@ -2190,7 +2176,7 @@ 0x801D0D58:("D_801D0D58","UNK_TYPE2","",0x2), 0x801D0D5C:("D_801D0D5C","UNK_TYPE2","",0x2), 0x801D0D60:("D_801D0D60","Input*","",0x4), - 0x801D0D64:("D_801D0D64","UNK_TYPE2","",0x2), + 0x801D0D64:("D_801D0D64","s16","[10]",0x14), 0x801D0D7A:("D_801D0D7A","UNK_TYPE1","",0x1), 0x801D0D80:("D_801D0D80","UNK_TYPE1","",0x1), 0x801D11F4:("D_801D11F4","UNK_TYPE1","",0x1), @@ -2244,8 +2230,6 @@ 0x801D1504:("gFramerateDivisorF","f32","",0x4), 0x801D1508:("gFramerateDivisorHalf","f32","",0x4), 0x801D150C:("gFramerateDivisorThird","f32","",0x4), - 0x801D1510:("D_801D1510","UNK_TYPE4","",0x4), - 0x801D1514:("D_801D1514","UNK_TYPE4","",0x4), 0x801D1520:("gScreenWidth","s32","",0x4), 0x801D1524:("gScreenHeight","s32","",0x4), 0x801D1528:("startHeapSize","UNK_TYPE4","",0x4), @@ -2254,48 +2238,43 @@ 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), - 0x801D3070:("D_801D3070","UNK_TYPE1","",0x1), - 0x801D3700:("D_801D3700","UNK_TYPE1","",0x1), - 0x801D3D90:("D_801D3D90","UNK_TYPE1","",0x1), - 0x801D3F90:("D_801D3F90","UNK_TYPE1","",0x1), - 0x801D4190:("D_801D4190","UNK_TYPE1","",0x1), - 0x801D4390:("D_801D4390","UNK_TYPE1","",0x1), - 0x801D4590:("D_801D4590","UNK_TYPE1","",0x1), + 0x801D2E80:("gLowPassFilterData","UNK_TYPE1","",0x1), + 0x801D2F80:("gHighPassFilterData","UNK_TYPE1","",0x1), + 0x801D3070:("gBandStopFilterData","UNK_TYPE1","",0x1), + 0x801D3700:("gBandPassFilterData","UNK_TYPE1","",0x1), + 0x801D3D90:("gSawtoothWaveSample","UNK_TYPE1","",0x1), + 0x801D3F90:("gTriangleWaveSample","UNK_TYPE1","",0x1), + 0x801D4190:("gSineWaveSample","UNK_TYPE1","",0x1), + 0x801D4390:("gSquareWaveSample","UNK_TYPE1","",0x1), + 0x801D4590:("gWhiteNoiseSample","UNK_TYPE1","",0x1), 0x801D4790:("D_801D4790","UNK_TYPE1","",0x1), - 0x801D4990:("D_801D4990","UNK_TYPE1","",0x1), - 0x801D4B90:("D_801D4B90","UNK_TYPE1","",0x1), - 0x801D4D90:("D_801D4D90","UNK_PTR","",0x4), - 0x801D4D98:("D_801D4D98","UNK_PTR","",0x4), - 0x801D4DB0:("D_801D4DB0","UNK_PTR","",0x4), - 0x801D4DB4:("D_801D4DB4","UNK_TYPE1","",0x1), - 0x801D4FB4:("D_801D4FB4","UNK_TYPE1","",0x1), - 0x801D51B4:("D_801D51B4","UNK_TYPE4","",0x4), - 0x801D53B4:("D_801D53B4","UNK_TYPE4","",0x4), - 0x801D55B4:("D_801D55B4","UNK_TYPE1","",0x1), - 0x801D57B4:("D_801D57B4","UNK_TYPE1","",0x1), - 0x801D57C4:("D_801D57C4","UNK_TYPE1","",0x1), - 0x801D57D4:("D_801D57D4","UNK_TYPE1","",0x1), - 0x801D57E4:("D_801D57E4","UNK_TYPE4","",0x4), - 0x801D5804:("D_801D5804","UNK_TYPE4","",0x4), - 0x801D5824:("D_801D5824","UNK_TYPE2","",0x2), - 0x801D58A2:("D_801D58A2","UNK_TYPE2","",0x2), - 0x801D58AA:("D_801D58AA","UNK_TYPE1","",0x1), - 0x801D5928:("D_801D5928","UNK_TYPE1","",0x1), - 0x801D5B24:("D_801D5B24","UNK_TYPE1","",0x1), - 0x801D5B28:("D_801D5B28","UNK_TYPE1","",0x1), - 0x801D5D24:("D_801D5D24","UNK_TYPE1","",0x1), - 0x801D5D28:("D_801D5D28","UNK_TYPE1","",0x1), - 0x801D5F24:("D_801D5F24","UNK_TYPE1","",0x1), + 0x801D4990:("gEighthPulseWaveSample","UNK_TYPE1","",0x1), + 0x801D4B90:("gQuarterPulseWaveSample","UNK_TYPE1","",0x1), + 0x801D4D90:("gWaveSamples","s16*","[9]",0x24), + 0x801D4DB4:("gBendPitchOneOctaveFrequencies","f32","[256]",0x400), + 0x801D51B4:("gBendPitchTwoSemitonesFrequencies","f32","[256]",0x400), + 0x801D55B4:("gPitchFrequencies","f32","[128]",0x200), + 0x801D57B4:("gDefaultShortNoteVelocityTable","UNK_TYPE1","",0x1), + 0x801D57C4:("gDefaultShortNoteGateTimeTable","UNK_TYPE1","",0x1), + 0x801D57D4:("gDefaultEnvelope","UNK_TYPE1","",0x1), + 0x801D57E4:("gZeroNoteSub","UNK_TYPE4","",0x4), + 0x801D5804:("gDefaultNoteSub","UNK_TYPE4","",0x4), + 0x801D5824:("gHeadsetPanQuantization","u16","[64]",0x80), + 0x801D58A4:("D_801D58A4","s32","",0x4), + 0x801D58A8:("D_801D58A8","s16","[64]",0x80), + 0x801D5928:("gHeadsetPanVolume","f32","[128]",0x200), + 0x801D5B28:("gStereoPanVolume","f32","[128]",0x200), + 0x801D5D28:("gDefaultPanVolume","f32","[128]",0x200), + 0x801D5F28:("D_801D5F28","s16","[64]",0x80), + 0x801D5FB0:("D_801D5FB0","UNK_TYPE4","",0x4), 0x801D5FB4:("D_801D5FB4","UNK_TYPE4","",0x4), 0x801D5FB8:("D_801D5FB8","UNK_TYPE4","",0x4), 0x801D5FBC:("D_801D5FBC","UNK_TYPE4","",0x4), @@ -2303,7 +2282,7 @@ 0x801D5FD4:("D_801D5FD4","UNK_TYPE1","",0x1), 0x801D5FE0:("D_801D5FE0","UNK_PTR","",0x4), 0x801D5FE4:("D_801D5FE4","UNK_TYPE1","",0x1), - 0x801D5FE8:("D_801D5FE8","UNK_TYPE4","",0x4), + 0x801D5FE8:("gAudioContextInitalized","UNK_TYPE4","",0x4), 0x801D5FEC:("D_801D5FEC","UNK_TYPE4","",0x4), 0x801D5FF0:("D_801D5FF0","UNK_TYPE4","",0x4), 0x801D5FF4:("D_801D5FF4","UNK_TYPE4","",0x4), @@ -2314,130 +2293,124 @@ 0x801D6014:("D_801D6014","UNK_TYPE1","",0x1), 0x801D6028:("D_801D6028","UNK_TYPE1","",0x1), 0x801D6098:("D_801D6098","UNK_TYPE1","",0x1), - 0x801D6100:("D_801D6100","UNK_TYPE1","",0x1), 0x801D6188:("D_801D6188","UNK_PTR","",0x4), 0x801D618C:("D_801D618C","UNK_PTR","",0x4), 0x801D6190:("D_801D6190","f32","",0x4), 0x801D6194:("D_801D6194","UNK_TYPE4","",0x4), + 0x801D61A0:("D_801D61A0","u8","[96]",0x60), 0x801D6200:("D_801D6200","UNK_TYPE1","",0x1), 0x801D6600:("D_801D6600","UNK_TYPE1","",0x1), 0x801D6608:("D_801D6608","UNK_TYPE1","",0x1), - 0x801D6610:("D_801D6610","UNK_TYPE1","",0x1), - 0x801D662C:("D_801D662C","UNK_TYPE1","",0x1), - 0x801D6648:("D_801D6648","UNK_TYPE1","",0x1), - 0x801D664C:("D_801D664C","UNK_TYPE1","",0x1), - 0x801D6650:("D_801D6650","UNK_TYPE1","",0x1), - 0x801D6654:("D_801D6654","UNK_TYPE4","",0x4), - 0x801D6658:("D_801D6658","UNK_TYPE1","",0x1), - 0x801D665C:("D_801D665C","UNK_TYPE1","",0x1), - 0x801D6660:("D_801D6660","UNK_TYPE1","",0x1), - 0x801D666C:("D_801D666C","UNK_TYPE1","",0x1), - 0x801D6680:("D_801D6680","UNK_TYPE1","",0x1), - 0x801D6684:("D_801D6684","UNK_TYPE1","",0x1), - 0x801D6694:("D_801D6694","UNK_TYPE4","",0x4), - 0x801D6698:("D_801D6698","UNK_TYPE1","",0x1), - 0x801D669E:("D_801D669E","UNK_TYPE1","",0x1), - 0x801D669F:("D_801D669F","UNK_TYPE1","",0x1), - 0x801D66A0:("D_801D66A0","UNK_TYPE1","",0x1), - 0x801D66A4:("D_801D66A4","UNK_TYPE2","",0x2), - 0x801D66A8:("D_801D66A8","UNK_TYPE1","",0x1), - 0x801D66AC:("D_801D66AC","UNK_TYPE1","",0x1), - 0x801D66B0:("D_801D66B0","UNK_TYPE1","",0x1), - 0x801D66B4:("D_801D66B4","UNK_TYPE1","",0x1), - 0x801D66B8:("D_801D66B8","UNK_TYPE1","",0x1), - 0x801D66BC:("D_801D66BC","UNK_TYPE1","",0x1), - 0x801D66C0:("D_801D66C0","UNK_TYPE1","",0x1), - 0x801D66C4:("D_801D66C4","f32","",0x4), - 0x801D66C8:("D_801D66C8","UNK_TYPE1","",0x1), - 0x801D66CC:("D_801D66CC","UNK_TYPE2","",0x2), - 0x801D66D0:("D_801D66D0","UNK_TYPE1","",0x1), - 0x801D66D4:("D_801D66D4","UNK_TYPE1","",0x1), - 0x801D66D8:("D_801D66D8","UNK_TYPE4","",0x4), - 0x801D66DC:("D_801D66DC","UNK_TYPE4","",0x4), - 0x801D66E0:("D_801D66E0","UNK_TYPE1","",0x1), - 0x801D66E4:("D_801D66E4","UNK_TYPE1","",0x1), - 0x801D66E8:("D_801D66E8","UNK_TYPE1","",0x1), - 0x801D66EC:("D_801D66EC","UNK_TYPE1","",0x1), - 0x801D66F0:("D_801D66F0","UNK_TYPE1","",0x1), - 0x801D66F4:("D_801D66F4","UNK_TYPE4","",0x4), - 0x801D66F8:("D_801D66F8","UNK_TYPE4","",0x4), - 0x801D66FC:("D_801D66FC","UNK_TYPE1","",0x1), - 0x801D6700:("D_801D6700","UNK_TYPE1","",0x1), - 0x801D6780:("D_801D6780","UNK_TYPE1","",0x1), - 0x801D6794:("D_801D6794","UNK_TYPE1","",0x1), - 0x801D6FB4:("D_801D6FB4","UNK_TYPE1","",0x1), - 0x801D6FB8:("D_801D6FB8","UNK_TYPE1","",0x1), - 0x801D6FBC:("D_801D6FBC","UNK_TYPE1","",0x1), - 0x801D6FC0:("D_801D6FC0","UNK_TYPE1","",0x1), - 0x801D6FC4:("D_801D6FC4","UNK_TYPE1","",0x1), - 0x801D6FC8:("D_801D6FC8","UNK_TYPE1","",0x1), - 0x801D6FCC:("D_801D6FCC","f32","",0x4), - 0x801D6FD0:("D_801D6FD0","UNK_TYPE1","",0x1), - 0x801D6FD4:("D_801D6FD4","UNK_TYPE1","",0x1), - 0x801D6FD8:("D_801D6FD8","UNK_TYPE1","",0x1), - 0x801D6FDC:("D_801D6FDC","UNK_TYPE1","",0x1), - 0x801D6FE0:("D_801D6FE0","UNK_TYPE1","",0x1), + 0x801D6610:("gChannelsPerBank","UNK_TYPE1","",0x1), + 0x801D662C:("gUsedChannelsPerBank","UNK_TYPE1","",0x1), + 0x801D6648:("sGiantsMaskFreq","UNK_TYPE1","",0x1), + 0x801D664C:("sGiantsMaskReverbAdd","UNK_TYPE1","",0x1), + 0x801D6650:("sWaterWheelVolume","UNK_TYPE1","",0x1), + 0x801D6654:("gSfxVolume","UNK_TYPE4","",0x4), + 0x801D6658:("sSfxTimer","UNK_TYPE1","",0x1), + 0x801D665C:("sSfxTimerLerpRange2","UNK_TYPE1","",0x1), + 0x801D6660:("sSfxTimerLerpRange1","s8","",0x1), + 0x801D6664:("D_801D6664","f32","[2]",0x8), + 0x801D666C:("sAudioIncreasingTranspose","UNK_TYPE1","",0x1), + 0x801D6680:("sPrevChargeLevel","UNK_TYPE1","",0x1), + 0x801D6684:("sChargeLevelsSfxFreq","UNK_TYPE1","",0x1), + 0x801D6694:("sCurChargeLevelSfxFreq","UNK_TYPE4","",0x4), + 0x801D6698:("sGanonsTowerLevelsVol","u8","[8]",0x8), + 0x801D66A0:("sEnterGanonsTowerTimer","UNK_TYPE1","",0x1), + 0x801D66A4:("sSfxVolumeDuration","UNK_TYPE2","",0x2), + 0x801D66A8:("sAudioFileSelectSetting","UNK_TYPE1","",0x1), + 0x801D66AC:("sAudioIsWindowOpen","UNK_TYPE1","",0x1), + 0x801D66B0:("sAudioCutsceneFlag","UNK_TYPE1","",0x1), + 0x801D66B4:("sSpecReverb","UNK_TYPE1","",0x1), + 0x801D66B8:("sAudioEnvReverb","UNK_TYPE1","",0x1), + 0x801D66BC:("sAudioCodeReverb","UNK_TYPE1","",0x1), + 0x801D66C0:("sPrevSeqMode","UNK_TYPE1","",0x1), + 0x801D66C4:("sAudioEnemyDist","f32","",0x4), + 0x801D66C8:("sAudioEnemyVol","UNK_TYPE1","",0x1), + 0x801D66CC:("sPrevMainBgmSeqId","UNK_TYPE2","",0x2), + 0x801D66D0:("sBgmPlayerIOPort7","UNK_TYPE1","",0x1), + 0x801D66D4:("sSceneSeqId2","UNK_TYPE1","",0x1), + 0x801D66D8:("sNumFramesStill","UNK_TYPE4","",0x4), + 0x801D66DC:("sNumFramesMoving","UNK_TYPE4","",0x4), + 0x801D66E0:("sAudioBaseFilter","UNK_TYPE1","",0x1), + 0x801D66E4:("sAudioExtraFilter","UNK_TYPE1","",0x1), + 0x801D66E8:("sAudioBaseFilter2","UNK_TYPE1","",0x1), + 0x801D66EC:("sAudioExtraFilter2","UNK_TYPE1","",0x1), + 0x801D66F0:("gUnderwaterSfxReverbAdd","UNK_TYPE1","",0x1), + 0x801D66F4:("sRiverSoundBgmPos","UNK_TYPE4","",0x4), + 0x801D66F8:("sRiverSoundXZDistToPlayer","UNK_TYPE4","",0x4), + 0x801D66FC:("sObjSoundMainBgmSeqId","UNK_TYPE1","",0x1), + 0x801D6700:("sSeqFlags","UNK_TYPE1","",0x1), + 0x801D6780:("sSpecReverbs","UNK_TYPE1","",0x1), + 0x801D6794:("sNatureAmbienceData","UNK_TYPE1","",0x1), + 0x801D6FB4:("sIsOcarinaInputEnabled","UNK_TYPE1","",0x1), + 0x801D6FB8:("sOcarinaInstrumentId","UNK_TYPE1","",0x1), + 0x801D6FBC:("sCurOcarinaPitch","UNK_TYPE1","",0x1), + 0x801D6FC0:("sPrevOcarinaPitch","UNK_TYPE1","",0x1), + 0x801D6FC4:("sCurOcarinaButtonIndex","UNK_TYPE1","",0x1), + 0x801D6FC8:("sMusicStaffPrevPitch","UNK_TYPE1","",0x1), + 0x801D6FCC:("sCurOcarinaBendFreq","f32","",0x4), + 0x801D6FD0:("sDefaultOcarinaVolume","UNK_TYPE1","",0x1), + 0x801D6FD4:("sCurOcarinaBendIndex","UNK_TYPE1","",0x1), + 0x801D6FD8:("sCurOcarinaVolume","UNK_TYPE1","",0x1), + 0x801D6FDC:("sCurOcarinaVibrato","UNK_TYPE1","",0x1), + 0x801D6FE0:("sPlaybackState","UNK_TYPE1","",0x1), 0x801D6FE4:("D_801D6FE4","UNK_TYPE1","",0x1), 0x801D6FE8:("D_801D6FE8","UNK_TYPE1","",0x1), - 0x801D6FEC:("D_801D6FEC","UNK_TYPE4","",0x4), - 0x801D6FF0:("D_801D6FF0","UNK_TYPE4","",0x4), - 0x801D6FF4:("D_801D6FF4","UNK_TYPE2","",0x2), - 0x801D6FF8:("D_801D6FF8","UNK_TYPE2","",0x2), - 0x801D6FFC:("D_801D6FFC","UNK_TYPE4","",0x4), - 0x801D7000:("D_801D7000","UNK_TYPE1","",0x1), - 0x801D7004:("D_801D7004","UNK_TYPE1","",0x1), - 0x801D7008:("D_801D7008","UNK_TYPE1","",0x1), - 0x801D700C:("D_801D700C","UNK_TYPE1","",0x1), - 0x801D7010:("D_801D7010","f32","",0x4), - 0x801D7014:("D_801D7014","f32","",0x4), - 0x801D7018:("D_801D7018","UNK_TYPE4","",0x4), - 0x801D701C:("D_801D701C","UNK_TYPE4","",0x4), - 0x801D701E:("D_801D701E","UNK_TYPE1","",0x1), - 0x801D701F:("D_801D701F","UNK_TYPE1","",0x1), - 0x801D7020:("D_801D7020","UNK_TYPE1","",0x1), - 0x801D7028:("D_801D7028","UNK_TYPE1","",0x1), - 0x801D702C:("D_801D702C","UNK_TYPE1","",0x1), - 0x801D7030:("D_801D7030","UNK_TYPE1","",0x1), - 0x801D7038:("D_801D7038","UNK_TYPE1","",0x1), - 0x801D703C:("D_801D703C","UNK_TYPE1","",0x1), - 0x801D7040:("D_801D7040","UNK_TYPE1","",0x1), - 0x801D7044:("D_801D7044","UNK_TYPE1","",0x1), - 0x801D7E04:("D_801D7E04","UNK_TYPE4","",0x4), - 0x801D7EA4:("D_801D7EA4","UNK_TYPE1","",0x1), - 0x801D7F44:("D_801D7F44","UNK_TYPE1","",0x1), - 0x801D84E4:("D_801D84E4","UNK_TYPE1","",0x1), - 0x801D84F0:("D_801D84F0","UNK_PTR","",0x4), - 0x801D84F4:("D_801D84F4","UNK_TYPE1","",0x1), - 0x801D8508:("D_801D8508","UNK_TYPE1","",0x1), - 0x801D850C:("D_801D850C","UNK_TYPE1","",0x1), - 0x801D8510:("D_801D8510","UNK_TYPE4","",0x4), - 0x801D8514:("D_801D8514","UNK_TYPE1","",0x1), - 0x801D8518:("D_801D8518","UNK_TYPE1","",0x1), - 0x801D851C:("D_801D851C","UNK_TYPE1","",0x1), - 0x801D8520:("D_801D8520","UNK_TYPE1","",0x1), - 0x801D8524:("D_801D8524","UNK_TYPE1","",0x1), - 0x801D8528:("D_801D8528","UNK_TYPE1","",0x1), - 0x801D852C:("D_801D852C","UNK_TYPE1","",0x1), + 0x801D6FEC:("sOcarinaFlags","UNK_TYPE4","",0x4), + 0x801D6FF0:("sPlaybackNoteTimer","UNK_TYPE4","",0x4), + 0x801D6FF4:("sPlaybackNotePos","UNK_TYPE2","",0x2), + 0x801D6FF8:("sPlaybackStaffPos","UNK_TYPE2","",0x2), + 0x801D6FFC:("sPrevOcarinaSongFlags","UNK_TYPE4","",0x4), + 0x801D7000:("sPlaybackNoteValue","UNK_TYPE1","",0x1), + 0x801D7004:("sNotePlaybackVolume","UNK_TYPE1","",0x1), + 0x801D7008:("sNotePlaybackVibrato","UNK_TYPE1","",0x1), + 0x801D700C:("sNotePlaybackBend","UNK_TYPE1","",0x1), + 0x801D7010:("sNormalizedNotePlaybackTone","f32","",0x4), + 0x801D7014:("sNormalizedNotePlaybackVolume","f32","",0x4), + 0x801D7018:("sOcarinaPlaybackTaskStart","UNK_TYPE4","",0x4), + 0x801D701C:("sOcarinaWallCounter","UNK_TYPE4","",0x4), + 0x801D7020:("sCurOcarinaSong","u8","[8]",0x8), + 0x801D7028:("sOcarinaSongAppendPos","UNK_TYPE1","",0x1), + 0x801D702C:("sOcarinaSongStartingPos","UNK_TYPE1","",0x1), + 0x801D7030:("sButtonToPitchMap","UNK_TYPE1","",0x1), + 0x801D7038:("sOcarinaMemoryGameAppendPos","UNK_TYPE1","",0x1), + 0x801D703C:("sOcaMemoryGameEndPos","UNK_TYPE1","",0x1), + 0x801D7040:("sOcaMemoryGameNumNotes","UNK_TYPE1","",0x1), + 0x801D7044:("sOcarinaSongNotes","OcarinaNote","[24][20]",0xF00), + 0x801D7F44:("sOoTOcarinaSongNotes","OcarinaNote","[9][20]",0x5A0), + 0x801D84E4:("sOoTOcarinaSongsNumNotes","UNK_TYPE1","",0x1), + 0x801D84F0:("sPlaybackSong","UNK_PTR","",0x4), + 0x801D84F4:("sFrogsSongNotes","u8","[14]",0xE), + 0x801D8504:("gFrogsSongPtr","u8*","",0x4), + 0x801D8508:("sRecordingState","UNK_TYPE1","",0x1), + 0x801D850C:("sRecordSongPos","UNK_TYPE1","",0x1), + 0x801D8510:("sOcarinaRecordTaskStart","UNK_TYPE4","",0x4), + 0x801D8514:("sRecordOcarinaPitch","UNK_TYPE1","",0x1), + 0x801D8518:("sRecordOcarinaVolume","UNK_TYPE1","",0x1), + 0x801D851C:("sRecordOcarinaVibrato","UNK_TYPE1","",0x1), + 0x801D8520:("sRecordOcarinaBendIndex","UNK_TYPE1","",0x1), + 0x801D8524:("sRecordOcarinaButtonIndex","UNK_TYPE1","",0x1), + 0x801D8528:("sPlayedOcarinaSongIndexPlusOne","UNK_TYPE1","",0x1), + 0x801D852C:("sMusicStaffNumNotesPerTest","UNK_TYPE1","",0x1), 0x801D8530:("D_801D8530","UNK_TYPE1","",0x1), 0x801D8534:("D_801D8534","UNK_TYPE4","",0x4), - 0x801D8538:("D_801D8538","UNK_TYPE1","",0x1), - 0x801D853C:("D_801D853C","UNK_TYPE1","",0x1), - 0x801D853E:("D_801D853E","UNK_TYPE2","",0x2), - 0x801D8544:("D_801D8544","UNK_TYPE1","",0x1), - 0x801D889C:("D_801D889C","UNK_PTR","",0x4), - 0x801D88A0:("D_801D88A0","UNK_PTR","",0x4), - 0x801D88A4:("D_801D88A4","UNK_PTR","",0x4), - 0x801D88A8:("D_801D88A8","UNK_TYPE1","",0x1), - 0x801D88B8:("D_801D88B8","UNK_TYPE1","",0x1), - 0x801D8A48:("D_801D8A48","UNK_TYPE1","",0x1), - 0x801D8B20:("D_801D8B20","UNK_TYPE1","",0x1), - 0x801D8B24:("D_801D8B24","UNK_PTR","",0x4), - 0x801D8B28:("D_801D8B28","UNK_TYPE2","",0x2), - 0x801D8B2C:("D_801D8B2C","UNK_TYPE1","",0x1), + 0x801D8538:("sIsOcarinaNoteChanged","UNK_TYPE1","",0x1), + 0x801D853C:("sScarecrowsLongSongNotes","OcarinaNote","[108]",0x360), + 0x801D889C:("gScarecrowLongSongPtr","UNK_PTR","",0x4), + 0x801D88A0:("gScarecrowSpawnSongPtr","UNK_PTR","",0x4), + 0x801D88A4:("sTerminaWallSongPtr","UNK_PTR","",0x4), + 0x801D88A8:("sPitchToButtonMap","UNK_TYPE1","",0x1), + 0x801D88B8:("sCustomSequenceScript","UNK_TYPE1","",0x1), + 0x801D8A48:("gOcarinaSongButtons","UNK_TYPE1","",0x1), + 0x801D8B20:("sScarecrowAfterCreditsState","UNK_TYPE1","",0x1), + 0x801D8B24:("sScarecrowAfterCreditsIntrumentId","UNK_PTR","",0x4), + 0x801D8B28:("sScarecrowAfterCreditsTimer","UNK_TYPE2","",0x2), + 0x801D8B2C:("sRequestCustomSequence","UNK_TYPE1","",0x1), 0x801D8B30:("D_801D8B30","UNK_TYPE1","",0x1), - 0x801D8BB0:("D_801D8BB0","UNK_TYPE1","",0x1), - 0x801D8BD0:("D_801D8BD0","UNK_TYPE2","",0x2), - 0x801D8BD4:("D_801D8BD4","UNK_TYPE4","",0x4), + 0x801D8BB0:("sBigBellsVolume","UNK_TYPE1","",0x1), + 0x801D8BD0:("sBgmPlayers","UNK_TYPE2","",0x2), + 0x801D8BD4:("sSfxOriginalPos","UNK_TYPE4","",0x4), 0x801D8BE0:("D_801D8BE0","UNK_TYPE1","",0x1), 0x801D8E3C:("D_801D8E3C","UNK_TYPE1","",0x1), 0x801D8E40:("D_801D8E40","UNK_TYPE4","",0x4), @@ -2445,14 +2418,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), @@ -2484,7 +2457,7 @@ 0x801DB8B8:("D_801DB8B8","UNK_TYPE1","",0x1), 0x801DB900:("D_801DB900","UNK_TYPE1","",0x1), 0x801DB930:("D_801DB930","UNK_PTR","",0x4), - 0x801DB958:("D_801DB958","s8018CFAC","[21]",0x498), + 0x801DB958:("gAudioSpecs","AudioSpec","[21]",0x498), 0x801DBDF0:("D_801DBDF0","f32","",0x4), 0x801DBDF4:("jtbl_801DBDF4","UNK_PTR","",0x4), 0x801DBE68:("D_801DBE68","f32","",0x4), @@ -3703,7 +3676,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), @@ -3809,16 +3782,16 @@ 0x801E07C4:("jtbl_801E07C4","UNK_PTR","",0x4), 0x801E0948:("jtbl_801E0948","UNK_PTR","",0x4), 0x801E0A08:("jtbl_801E0A08","UNK_PTR","",0x4), - 0x801E0BD0:("D_801E0BD0","UNK_TYPE1","",0x1), - 0x801E0BFC:("D_801E0BFC","UNK_TYPE1","",0x1), - 0x801E0C14:("D_801E0C14","char","[]",0x1), - 0x801E0C38:("D_801E0C38","char","[]",0x1), - 0x801E0C64:("D_801E0C64","char","[]",0x1), - 0x801E0C6C:("D_801E0C6C","char","[]",0x1), - 0x801E0C74:("D_801E0C74","char","[]",0x1), - 0x801E0C7C:("D_801E0C7C","char","[]",0x1), - 0x801E0CA4:("D_801E0CA4","char","[]",0x1), - 0x801E0CD0:("D_801E0CD0","char","[]",0x1), + 0x801E0BD0:("gAudioEnvironmentalSfx","UNK_TYPE1","",0x1), + 0x801E0BFC:("sIsOcarinaSongReserved","UNK_TYPE1","",0x1), + 0x801E0C14:("sAudioOcarinaUnusedText0","char","[]",0x1), + 0x801E0C38:("sAudioOcarinaUnusedText1","char","[]",0x1), + 0x801E0C64:("sAudioOcarinaUnusedText2","char","[]",0x1), + 0x801E0C6C:("sAudioOcarinaUnusedText3","char","[]",0x1), + 0x801E0C74:("sAudioOcarinaUnusedText4","char","[]",0x1), + 0x801E0C7C:("sAudioOcarinaUnusedText5","char","[]",0x1), + 0x801E0CA4:("sAudioOcarinaUnusedText6","char","[]",0x1), + 0x801E0CD0:("sAudioOcarinaUnusedText7","char","[]",0x1), 0x801E0CEC:("D_801E0CEC","f32","",0x4), 0x801E0CF0:("D_801E0CF0","f32","",0x4), 0x801E0CF4:("D_801E0CF4","f32","",0x4), @@ -3885,33 +3858,24 @@ 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), - 0x801E1420:("D_801E1420","UNK_TYPE1","",0x1), - 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), - 0x801E3BB0:("D_801E3BB0","UNK_TYPE1","",0x1), - 0x801E3F40:("D_801E3F40","UNK_TYPE1","",0x1), + 0x801E1180:("gSoundFontTable","UNK_TYPE2","",0x2), + 0x801E1420:("gSequenceFontTable","UNK_TYPE1","",0x1), + 0x801E1630:("gSequenceTable","UNK_TYPE2","",0x2), + 0x801E1E40:("gSampleBankTable","UNK_TYPE1","",0x1), + 0x801E1E80:("aspMainDataStart","UNK_TYPE1","",0x2E0), + 0x801E2160:("gspF3DZEX2_NoN_PosLight_fifoTextStart","UNK_TYPE1","",0x1), + 0x801E3790:("gspF3DZEX2_NoN_PosLight_fifoDataStart","UNK_TYPE1","",0x1), + 0x801E3BB0:("gspS2DEX2_fifoDataStart","UNK_TYPE1","",0x1), + 0x801E3F40:("njpgdspMainDataStart","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), + 0x801ED8A0:("sActorFaultClient","UNK_TYPE1","",0x1), 0x801ED8B0:("D_801ED8B0","UNK_TYPE1","",0x1), 0x801ED8B4:("D_801ED8B4","UNK_TYPE1","",0x1), 0x801ED8B8:("D_801ED8B8","UNK_TYPE1","",0x1), @@ -3919,7 +3883,7 @@ 0x801ED8C0:("D_801ED8C0","UNK_TYPE1","",0x1), 0x801ED8C4:("D_801ED8C4","UNK_TYPE1","",0x1), 0x801ED8C8:("D_801ED8C8","f32","",0x4), - 0x801ED8CC:("D_801ED8CC","f32","",0x4), + 0x801ED8CC:("sBgmEnemyDistSq","f32","",0x4), 0x801ED8D0:("D_801ED8D0","f32","",0x4), 0x801ED8D4:("D_801ED8D4","UNK_TYPE1","",0x1), 0x801ED8D8:("D_801ED8D8","UNK_TYPE1","",0x1), @@ -3930,34 +3894,17 @@ 0x801ED940:("D_801ED940","FaultAddrConvClient","",0xc), 0x801ED950:("D_801ED950","char","[80]",0x50), 0x801ED9A0:("D_801ED9A0","char","[80]",0x50), - 0x801ED9F0:("D_801ED9F0","Vec3f","",0xc), - 0x801ED9FC:("D_801ED9FC","Vec3f","",0xc), - 0x801EDA08:("D_801EDA08","Vec3f","",0xc), - 0x801EDA18:("D_801EDA18","Vec3f","",0xc), - 0x801EDA24:("D_801EDA24","Vec3f","",0xc), - 0x801EDA30:("D_801EDA30","Vec3f","",0xc), + 0x801ED9F0:("D_801ED9F0","Vec3f","[3]",0x24), + 0x801EDA18:("D_801EDA18","Vec3f","[3]",0x24), 0x801EDA40:("D_801EDA40","MtxF","",0x40), - 0x801EDA80:("D_801EDA80","Vec3f","",0xc), - 0x801EDA8C:("D_801EDA8C","Vec3f","",0xc), - 0x801EDA98:("D_801EDA98","Vec3f","",0xc), + 0x801EDA80:("D_801EDA80","Vec3f","[3]",0x24), 0x801EDAA8:("D_801EDAA8","char","[80]",0x50), 0x801EDAF8:("D_801EDAF8","char","[80]",0x50), - 0x801EDB48:("D_801EDB48","Vec3f","",0xc), - 0x801EDB54:("D_801EDB54","Vec3f","",0xc), - 0x801EDB60:("D_801EDB60","Vec3f","",0xc), - 0x801EDB70:("D_801EDB70","Vec3f","",0xc), - 0x801EDB7C:("D_801EDB7C","Vec3f","",0xc), - 0x801EDB88:("D_801EDB88","Vec3f","",0xc), - 0x801EDB98:("D_801EDB98","f32","",0x4), - 0x801EDB9C:("D_801EDB9C","f32","",0x4), - 0x801EDBA0:("D_801EDBA0","f32","",0x4), - 0x801EDBA4:("D_801EDBA4","UNK_TYPE1","",0x1), + 0x801EDB48:("D_801EDB48","Vec3f","[3]",0x24), + 0x801EDB70:("D_801EDB70","Vec3f","[3]",0x24), + 0x801EDB98:("D_801EDB98","Plane","",0x10), 0x801EDBA8:("D_801EDBA8","Sphere16","",0x8), 0x801EDBB0:("D_801EDBB0","TriNorm","",0x34), - 0x801EDBD4:("D_801EDBD4","UNK_TYPE1","",0x1), - 0x801EDBD8:("D_801EDBD8","UNK_TYPE1","",0x1), - 0x801EDBDC:("D_801EDBDC","UNK_TYPE1","",0x1), - 0x801EDBE0:("D_801EDBE0","UNK_TYPE1","",0x1), 0x801EDBF0:("D_801EDBF0","s16","",0x2), 0x801EDBF4:("D_801EDBF4","UNK_TYPE1","",0x1), 0x801EDBF8:("D_801EDBF8","UNK_TYPE1","",0x1), @@ -4010,12 +3957,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), @@ -4024,16 +3971,14 @@ 0x801F3F58:("D_801F3F58","UNK_TYPE1","",0x1), 0x801F3F5A:("D_801F3F5A","UNK_TYPE1","",0x1), 0x801F3F60:("gGameInfo","GameInfo*","",0x4), - 0x801F3F70:("D_801F3F70","UNK_TYPE1","",0x1), + 0x801F3F70:("sDebugObjectListHead","UNK_TYPE1","",0x1), 0x801F3F80:("D_801F3F80","UNK_TYPE1","",0x1), 0x801F3F83:("D_801F3F83","UNK_TYPE1","",0x1), 0x801F48C8:("D_801F48C8","UNK_TYPE1","",0x1), - 0x801F4D40:("D_801F4D40","UNK_TYPE1","",0x1), - 0x801F4D42:("D_801F4D42","UNK_TYPE2","",0x2), - 0x801F4D48:("D_801F4D48","UNK_TYPE1","",0x1), - 0x801F4DC8:("D_801F4DC8","UNK_TYPE1","",0x1), - 0x801F4DCA:("D_801F4DCA","UNK_TYPE1","",0x1), - 0x801F4DCC:("D_801F4DCC","UNK_TYPE2","[8]",0x10), + 0x801F4D40:("seqId","u16","",0x2), + 0x801F4D42:("sCutsceneQuakeIndex","UNK_TYPE2","",0x2), + 0x801F4D48:("sCutsceneCameraInfo","UNK_TYPE","",0x80), + 0x801F4DC8:("D_801F4DC8","u16","[10]",0x14), 0x801F4DDC:("D_801F4DDC","UNK_TYPE1","",0x1), 0x801F4DE0:("D_801F4DE0","UNK_TYPE1","",0x1), 0x801F4DE2:("D_801F4DE2","UNK_TYPE2","",0x2), @@ -4117,19 +4062,20 @@ 0x801F59F4:("D_801F59F4","UNK_TYPE1","",0x1), 0x801F59F8:("D_801F59F8","UNK_TYPE1","",0x1), 0x801F5A00:("sQuakeRequest","QuakeRequest","[4]",0x90), - 0x801F5A90:("sQuake2Context","Quake2Context","",0xc), + 0x801F5A90:("sDistortionContext","DistortionContext","",0xc), 0x801F5AA0:("sMatAnimStep","s32","",0x4), 0x801F5AA4:("sMatAnimFlags","u32","",0x4), 0x801F5AA8:("sMatAnimAlphaRatio","f32","",0x4), 0x801F5AB0:("sAnimQueueFlags","UNK_TYPE1","",0x1), 0x801F5AB4:("sDisableAnimQueueFlags","UNK_TYPE1","",0x1), - 0x801F5AC0:("D_801F5AC0","UNK_TYPE1","",0x1), + 0x801F5AC0:("gSkinLimbMatrices","MtxF","[60]",0xF00), + 0x801F69C0:("D_801F69C0","UNK_TYPE1","",0x10), 0x801F69D0:("D_801F69D0","UNK_TYPE1","",0x1), 0x801F6A10:("D_801F6A10","UNK_TYPE1","",0x1), 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), @@ -4147,17 +4093,17 @@ 0x801F6B1E:("D_801F6B1E","UNK_TYPE1","",0x1), 0x801F6B20:("D_801F6B20","UNK_TYPE1","",0x1), 0x801F6B22:("D_801F6B22","UNK_TYPE1","",0x1), - 0x801F6B30:("D_801F6B30","UNK_TYPE1","",0x1), - 0x801F6B34:("D_801F6B34","UNK_TYPE1","",0x1), - 0x801F6B38:("D_801F6B38","UNK_TYPE1","",0x1), - 0x801F6B3C:("D_801F6B3C","UNK_TYPE1","",0x1), + 0x801F6B30:("sPlayerCallInitFunc","UNK_TYPE1","",0x1), + 0x801F6B34:("sPlayerCallDestroyFunc","UNK_TYPE1","",0x1), + 0x801F6B38:("sPlayerCallUpdateFunc","UNK_TYPE1","",0x1), + 0x801F6B3C:("sPlayerCallDrawFunc","UNK_TYPE1","",0x1), 0x801F6B40:("gShrinkWindowContext","ShrinkWindowContext","",0x4), 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), @@ -4180,11 +4126,11 @@ 0x801F8020:("D_801F8020","struct_801F8020","",0x10), 0x801F8030:("sMonoColors","VisMono","",0x18), 0x801F8048:("D_801F8048","UNK_TYPE1","",0x1), - 0x801F80D0:("grapgFaultAddrConvClient","FaultAddrConvClient","",0xc), - 0x801F80E0:("graphFaultClient","FaultClient","",0x10), - 0x801F80F0:("graphDlEntry","Gfx*","",0x4), - 0x801F80F8:("D_801F80F8","UNK_TYPE1","",0x1), - 0x801F8150:("lastRenderFrameTimestamp","u64","",0x8), + 0x801F80D0:("sGraphFaultAddrConvClient","FaultAddrConvClient","",0xc), + 0x801F80E0:("sGraphFaultClient","FaultClient","",0x10), + 0x801F80F0:("gGfxMasterDL","Gfx*","",0x4), + 0x801F80F8:("sGraphCfbInfos","UNK_TYPE1","",0x1), + 0x801F8150:("sGraphTaskStartTime","u64","",0x8), 0x801F8160:("sSiIntMsgQ","OSMesgQueue","",0x18), 0x801F8178:("sSiIntMsgBuf","OSMesg","[1]",0x4), 0x801F8180:("gSegments","u32","[16]",0x40), @@ -4227,20 +4173,20 @@ 0x801FBB88:("D_801FBB88","OSViMode*","",0x4), 0x801FBB8C:("gZBufferPtr","u16*","",0x4), 0x801FBB90:("D_801FBB90","UNK_TYPE4","",0x4), - 0x801FBB94:("D_801FBB94","UNK_TYPE1","",0x1), - 0x801FBB98:("D_801FBB98","UNK_TYPE1","",0x1), + 0x801FBB94:("gGfxSPTaskOutputBufferPtr","UNK_TYPE1","",0x1), + 0x801FBB98:("gGfxSPTaskOutputBufferSize","UNK_TYPE1","",0x1), 0x801FBB9C:("D_801FBB9C","UNK_TYPE1","",0x1), 0x801FBBA0:("D_801FBBA0","UNK_TYPE1","",0x1), - 0x801FBBA4:("sys_cfb_zbufl","u16*","",0x4), - 0x801FBBA8:("sys_cfb_wbufl","u16**","",0x4), - 0x801FBBAC:("sys_cfb_fifol","u16**","",0x4), - 0x801FBBB0:("D_801FBBB0","UNK_TYPE1","",0x1), + 0x801FBBA4:("gZBuffer","u16*","",0x4), + 0x801FBBA8:("gWorkBuffer","u16**","",0x4), + 0x801FBBAC:("gGfxSPTaskOutputBuffer","u16**","",0x4), + 0x801FBBB0:("gGfxSPTaskOutputBufferEnd","UNK_TYPE1","",0x1), 0x801FBBB4:("D_801FBBB4","UNK_TYPE1","",0x1), 0x801FBBB8:("D_801FBBB8","UNK_TYPE1","",0x1), 0x801FBBBC:("D_801FBBBC","UNK_TYPE1","",0x1), 0x801FBBC0:("D_801FBBC0","UNK_TYPE1","",0x1), - 0x801FBBC4:("D_801FBBC4","UNK_TYPE1","",0x1), - 0x801FBBC8:("D_801FBBC8","UNK_TYPE1","",0x1), + 0x801FBBC4:("gGfxSPTaskOutputBuffer2","UNK_TYPE1","",0x1), + 0x801FBBC8:("gGfxSPTaskOutputBufferEnd2","UNK_TYPE1","",0x1), 0x801FBBCC:("D_801FBBCC","UNK_TYPE2","",0x2), 0x801FBBCE:("D_801FBBCE","UNK_TYPE2","",0x2), 0x801FBBD0:("D_801FBBD0","UNK_TYPE1","",0x1), @@ -4263,8 +4209,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), @@ -4330,98 +4276,94 @@ 0x801FCE58:("sys_flashromOSThread","OSThread","",0x1b0), 0x801FD008:("D_801FD008","s80185D40","",0x2c), 0x801FD034:("D_801FD034","OSMesg","",0x4), - 0x801FD040:("D_801FD040","UNK_TYPE1","",0x1), + 0x801FD040:("D_801FD040","s32","",0x10), 0x801FD050:("D_801FD050","OSIoMesg","",0x18), - 0x801FD068:("D_801FD068","OSMesgQueue","",0x18), - 0x801FD080:("D_801FD080","OSPiHandle","",0x74), - 0x801FD0F4:("D_801FD0F4","UNK_TYPE1","",0x1), - 0x801FD0F8:("D_801FD0F8","UNK_TYPE1","",0x1), + 0x801FD068:("__osFlashMessageQ","OSMesgQueue","",0x18), + 0x801FD080:("__osFlashHandler","OSPiHandle","",0x74), + 0x801FD0F4:("__osFlashMsgBuf","OSMesg","",0x4), + 0x801FD0F8:("__osFlashVersion","u32","",0x4), 0x801FD120:("D_801FD120","UNK_TYPE1","",0x1), 0x801FD140:("D_801FD140","UNK_TYPE1","",0x1), 0x801FD158:("D_801FD158","UNK_TYPE1","",0x1), 0x801FD198:("D_801FD198","UNK_TYPE1","",0x1), 0x801FD1E0:("D_801FD1E0","UNK_TYPE1","",0x1), - 0x801FD1F0:("D_801FD1F0","UNK_TYPE1","",0x1), - 0x801FD250:("D_801FD250","UNK_TYPE1","",0x1), - 0x801FD254:("D_801FD254","UNK_TYPE1","",0x1), - 0x801FD258:("D_801FD258","UNK_TYPE1","",0x1), - 0x801FD25C:("D_801FD25C","UNK_TYPE1","",0x1), - 0x801FD260:("D_801FD260","UNK_TYPE1","",0x1), - 0x801FD264:("D_801FD264","UNK_TYPE1","",0x1), - 0x801FD268:("D_801FD268","UNK_TYPE1","",0x1), - 0x801FD278:("D_801FD278","UNK_TYPE1","",0x1), - 0x801FD288:("D_801FD288","UNK_TYPE1","",0x1), - 0x801FD28C:("D_801FD28C","UNK_TYPE1","",0x1), - 0x801FD28D:("D_801FD28D","UNK_TYPE1","",0x1), - 0x801FD28E:("D_801FD28E","UNK_TYPE1","",0x1), - 0x801FD28F:("D_801FD28F","UNK_TYPE1","",0x1), - 0x801FD290:("D_801FD290","UNK_TYPE1","",0x1), - 0x801FD291:("D_801FD291","UNK_TYPE1","",0x1), - 0x801FD294:("D_801FD294","UNK_TYPE1","",0x1), - 0x801FD298:("D_801FD298","UNK_TYPE1","",0x1), - 0x801FD29C:("D_801FD29C","UNK_TYPE1","",0x1), - 0x801FD2A0:("D_801FD2A0","UNK_TYPE1","",0x1), - 0x801FD2A8:("D_801FD2A8","UNK_TYPE1","",0x1), + 0x801FD1F0:("sSfxSettings","UNK_TYPE1","",0x1), + 0x801FD250:("sSfxSettingsFlags","UNK_TYPE1","",0x1), + 0x801FD254:("sTwoSemitonesLoweredFreq","UNK_TYPE1","",0x1), + 0x801FD258:("sSfxIncreasedReverb","UNK_TYPE1","",0x1), + 0x801FD25C:("sSfxSyncedVolume","UNK_TYPE1","",0x1), + 0x801FD260:("sSfxSyncedVolumeForMetalEffects","UNK_TYPE1","",0x1), + 0x801FD264:("sSfxSyncedFreq","UNK_TYPE1","",0x1), + 0x801FD268:("sRiverFreqScaleLerp","UNK_TYPE1","",0x1), + 0x801FD278:("sWaterfallFreqScaleLerp","UNK_TYPE1","",0x1), + 0x801FD288:("sSfxAdjustedFreq","UNK_TYPE1","",0x1), + 0x801FD28C:("sSfxCustomReverb","UNK_TYPE1","",0x1), + 0x801FD28D:("sRiverSoundMainBgmVol","UNK_TYPE1","",0x1), + 0x801FD28E:("sRiverSoundMainBgmCurrentVol","UNK_TYPE1","",0x1), + 0x801FD28F:("sRiverSoundMainBgmLower","UNK_TYPE1","",0x1), + 0x801FD290:("sRiverSoundMainBgmRestore","UNK_TYPE1","",0x1), + 0x801FD291:("sGanonsTowerVol","UNK_TYPE1","",0x1), + 0x801FD294:("sSfxVolumeCur","UNK_TYPE1","",0x1), + 0x801FD298:("sSfxVolumeTarget","UNK_TYPE1","",0x1), + 0x801FD29C:("sSfxVolumeRate","UNK_TYPE1","",0x1), + 0x801FD2A0:("sSceneSeqId1","UNK_TYPE1","",0x1), + 0x801FD2A8:("sSfxChannelState","UNK_TYPE1","",0x1), 0x801FD3A8:("D_801FD3A8","UNK_TYPE1","",0x1), 0x801FD3A9:("D_801FD3A9","UNK_TYPE1","",0x1), - 0x801FD3AA:("D_801FD3AA","UNK_TYPE1","",0x1), - 0x801FD3AB:("D_801FD3AB","UNK_TYPE1","",0x1), - 0x801FD3AC:("D_801FD3AC","UNK_TYPE1","",0x1), - 0x801FD3AE:("D_801FD3AE","UNK_TYPE1","",0x1), - 0x801FD3AF:("D_801FD3AF","UNK_TYPE1","",0x1), - 0x801FD3B0:("D_801FD3B0","UNK_TYPE1","",0x1), - 0x801FD3B4:("D_801FD3B4","UNK_TYPE1","",0x1), - 0x801FD3B7:("D_801FD3B7","UNK_TYPE1","",0x1), - 0x801FD3B8:("D_801FD3B8","UNK_TYPE1","",0x1), - 0x801FD3D8:("D_801FD3D8","UNK_TYPE1","",0x1), - 0x801FD3D9:("D_801FD3D9","UNK_TYPE1","",0x1), - 0x801FD3DA:("D_801FD3DA","UNK_TYPE1","",0x1), - 0x801FD3E0:("D_801FD3E0","UNK_TYPE1","",0x1), - 0x801FD3EC:("D_801FD3EC","UNK_TYPE1","",0x1), - 0x801FD3F0:("D_801FD3F0","UNK_TYPE1","",0x1), - 0x801FD3FC:("D_801FD3FC","UNK_TYPE1","",0x1), - 0x801FD400:("D_801FD400","UNK_TYPE1","",0x1), - 0x801FD404:("D_801FD404","UNK_TYPE1","",0x1), - 0x801FD408:("D_801FD408","UNK_TYPE1","",0x1), - 0x801FD40C:("D_801FD40C","UNK_TYPE1","",0x1), - 0x801FD410:("D_801FD410","UNK_TYPE1","",0x1), - 0x801FD420:("D_801FD420","UNK_TYPE1","",0x1), - 0x801FD42C:("D_801FD42C","UNK_TYPE1","",0x1), - 0x801FD430:("D_801FD430","UNK_TYPE1","",0x1), - 0x801FD431:("D_801FD431","UNK_TYPE1","",0x1), + 0x801FD3AA:("sRiverSoundBgmTimer","UNK_TYPE1","",0x1), + 0x801FD3AB:("sFanfareState","UNK_TYPE1","",0x1), + 0x801FD3AC:("sFanfareSeqId","UNK_TYPE1","",0x1), + 0x801FD3AE:("sMuteOnlySfxAndNatureSeq","UNK_TYPE1","",0x1), + 0x801FD3AF:("sAllPlayersMutedExceptOcaAndSys","UNK_TYPE1","",0x1), + 0x801FD3B0:("sAudioPauseState","UNK_TYPE1","",0x1), + 0x801FD3B4:("sSpatialSeqIsActive","u8","[4]",0x4), + 0x801FD3B8:("sSequenceFilter","UNK_TYPE1","",0x1), + 0x801FD3D8:("sIsFinalHoursOrSoaring","UNK_TYPE1","",0x1), + 0x801FD3D9:("sObjSoundFanfareSeqId","UNK_TYPE1","",0x1), + 0x801FD3DA:("sObjSoundFanfareRequested","UNK_TYPE1","",0x1), + 0x801FD3E0:("sObjSoundFanfarePos","UNK_TYPE1","",0x1), + 0x801FD3EC:("sObjSoundPlayerIndex","UNK_TYPE1","",0x1), + 0x801FD3F0:("sObjSoundPos","UNK_TYPE1","",0x1), + 0x801FD3FC:("sObjSoundFlags","UNK_TYPE1","",0x1), + 0x801FD400:("sObjSoundMinDist","UNK_TYPE1","",0x1), + 0x801FD404:("sObjSoundMaxDist","UNK_TYPE1","",0x1), + 0x801FD408:("sObjSoundMaxVol","UNK_TYPE1","",0x1), + 0x801FD40C:("sObjSoundMinVol","UNK_TYPE1","",0x1), + 0x801FD410:("sSpatialSeqNoFilterPos","UNK_TYPE1","",0x1), + 0x801FD420:("sSpatialSeqFilterPos","UNK_TYPE1","",0x1), + 0x801FD42C:("sSpatialSeqMaxDist","UNK_TYPE1","",0x1), + 0x801FD430:("sSpatialSeqSeqId","UNK_TYPE1","",0x1), + 0x801FD431:("sSpatialSeqFlags","UNK_TYPE1","",0x1), 0x801FD432:("D_801FD432","UNK_TYPE1","",0x1), - 0x801FD433:("D_801FD433","UNK_TYPE1","",0x1), + 0x801FD433:("sSpatialSubBgmFadeTimer","UNK_TYPE1","",0x1), 0x801FD434:("D_801FD434","UNK_TYPE1","",0x1), - 0x801FD435:("D_801FD435","UNK_TYPE1","",0x1), - 0x801FD436:("D_801FD436","UNK_TYPE1","",0x1), + 0x801FD435:("sSpatialSeqPlayerIndex","UNK_TYPE1","",0x1), + 0x801FD436:("sSpatialSeqFadeTimer","UNK_TYPE1","",0x1), 0x801FD438:("D_801FD438","UNK_TYPE1","",0x1), - 0x801FD43A:("D_801FD43A","UNK_TYPE1","",0x1), - 0x801FD43B:("D_801FD43B","UNK_TYPE1","",0x1), - 0x801FD43E:("D_801FD43E","UNK_TYPE1","",0x1), - 0x801FD442:("D_801FD442","UNK_TYPE1","",0x1), - 0x801FD448:("D_801FD448","UNK_TYPE1","",0x1), - 0x801FD44C:("D_801FD44C","UNK_TYPE1","",0x1), - 0x801FD44D:("D_801FD44D","UNK_TYPE1","",0x1), - 0x801FD450:("D_801FD450","UNK_TYPE1","",0x1), - 0x801FD454:("D_801FD454","UNK_TYPE1","",0x1), - 0x801FD458:("D_801FD458","UNK_TYPE1","",0x1), - 0x801FD45C:("D_801FD45C","UNK_TYPE1","",0x1), - 0x801FD460:("D_801FD460","UNK_TYPE1","",0x1), - 0x801FD461:("D_801FD461","UNK_TYPE1","",0x1), - 0x801FD462:("D_801FD462","UNK_TYPE1","",0x1), - 0x801FD463:("D_801FD463","UNK_TYPE1","",0x1), - 0x801FD464:("D_801FD464","UNK_TYPE1","",0x1), - 0x801FD468:("D_801FD468","UNK_TYPE1","",0x1), - 0x801FD46C:("D_801FD46C","UNK_TYPE1","",0x1), - 0x801FD470:("D_801FD470","UNK_TYPE1","",0x1), - 0x801FD4A0:("D_801FD4A0","UNK_TYPE1","",0x1), - 0x801FD4D0:("D_801FD4D0","UNK_TYPE1","",0x1), - 0x801FD500:("D_801FD500","UNK_TYPE1","",0x1), + 0x801FD43A:("sPlayingStaff","OcarinaStaff","",0x3), + 0x801FD43E:("sPlaybackStaff","OcarinaStaff","",0x3), + 0x801FD442:("sRecordingStaff","OcarinaStaff","",0x3), + 0x801FD448:("sOcarinaUpdateTaskCurrent","UNK_TYPE1","",0x1), + 0x801FD44C:("sOcarinaInputStickRel","OcarinaControlStick","",0x2), + 0x801FD450:("sOcarinaInputButtonCur","UNK_TYPE1","",0x1), + 0x801FD454:("sOcarinaInputButtonStart","UNK_TYPE1","",0x1), + 0x801FD458:("sOcarinaInputButtonPrev","UNK_TYPE1","",0x1), + 0x801FD45C:("sOcaInputBtnPress","UNK_TYPE1","",0x1), + 0x801FD460:("sOcarinaResetDelay","UNK_TYPE1","",0x1), + 0x801FD461:("sOcarinaResetUnused","UNK_TYPE1","",0x1), + 0x801FD462:("sOcarinaHasStartedSong","UNK_TYPE1","",0x1), + 0x801FD463:("sFirstOcarinaSongIndex","UNK_TYPE1","",0x1), + 0x801FD464:("sLastOcarinaSongIndex","UNK_TYPE1","",0x1), + 0x801FD468:("sOcarinaAvailSongs","UNK_TYPE1","",0x1), + 0x801FD46C:("sOcarinaStaffPlayingPos","UNK_TYPE1","",0x1), + 0x801FD470:("sMusicStaffPos","UNK_TYPE1","",0x1), + 0x801FD4A0:("sMusicStaffCurHeldLength","UNK_TYPE1","",0x1), + 0x801FD4D0:("sMusicStaffExpectedLength","UNK_TYPE1","",0x1), + 0x801FD500:("sMusicStaffExpectedPitch","UNK_TYPE1","",0x1), 0x801FD518:("D_801FD518","UNK_TYPE1","",0x1), - 0x801FD530:("D_801FD530","UNK_TYPE1","",0x1), - 0x801FD533:("D_801FD533","UNK_TYPE1","",0x1), - 0x801FD590:("D_801FD590","UNK_TYPE1","",0x1), - 0x801FD598:("D_801FD598","UNK_TYPE1","",0x1), + 0x801FD530:("D_801FD530","u32","[24]",0x60), + 0x801FD590:("sRecordingSongNote","UNK_TYPE1","",0x1), + 0x801FD598:("sCustomSequencePc","UNK_TYPE1","",0x1), 0x801FD5A0:("D_801FD5A0","UNK_TYPE1","",0x1), 0x801FD5A4:("D_801FD5A4","UNK_TYPE1","",0x1), 0x801FD5B8:("D_801FD5B8","UNK_TYPE1","",0x1), @@ -4437,7 +4379,7 @@ 0x801FE4C0:("D_801FE4C0","UNK_TYPE1","",0x1), 0x801FE640:("D_801FE640","UNK_TYPE1","",0x1), 0x801FE6D0:("D_801FE6D0","UNK_TYPE1","",0x1), - 0x801FE7C0:("D_801FE7C0","s801FE7C0","[1]",0x14), + 0x801FE7C0:("D_801FE7C0","SoundRequest","[1]",0x14), 0x801FFBC0:("D_801FFBC0","UNK_TYPE1","",0x1), 0x801FFBC8:("D_801FFBC8","UNK_TYPE1","",0x1), 0x801FFBD0:("D_801FFBD0","UNK_TYPE1","",0x1), @@ -4462,140 +4404,16 @@ 0x80200BCC:("D_80200BCC","UNK_TYPE1","",0x1), 0x80200BCE:("D_80200BCE","UNK_TYPE1","",0x1), 0x80200BD0:("D_80200BD0","UNK_TYPE1","",0x1), - 0x80200C70:("D_80200C70","UNK_TYPE1","",0x1), - 0x80200C71:("D_80200C71","UNK_TYPE1","",0x1), - 0x80200C76:("D_80200C76","UNK_TYPE1","",0x1), - 0x80200C78:("D_80200C78","UNK_TYPE1","",0x1), - 0x80200C7C:("D_80200C7C","UNK_TYPE1","",0x1), - 0x80200C80:("D_80200C80","UNK_TYPE1","",0x1), - 0x80200C92:("D_80200C92","UNK_TYPE1","",0x1), - 0x80200C94:("D_80200C94","UNK_TYPE1","",0x1), - 0x80200C98:("D_80200C98","UNK_TYPE1","",0x1), - 0x80200C9A:("D_80200C9A","UNK_TYPE1","",0x1), - 0x80200C9E:("D_80200C9E","UNK_TYPE1","",0x1), - 0x80200CA0:("D_80200CA0","UNK_TYPE1","",0x1), - 0x80200CF0:("D_80200CF0","UNK_TYPE1","",0x1), - 0x80200D38:("D_80200D38","UNK_TYPE1","",0x1), - 0x80200D70:("D_80200D70","UNK_TYPE1","",0x1), - 0x802011F0:("D_802011F0","UNK_TYPE1","",0x1), - 0x8020178C:("D_8020178C","UNK_TYPE1","",0x1), - 0x802017B0:("D_802017B0","UNK_TYPE1","",0x1), - 0x80201D68:("D_80201D68","UNK_TYPE1","",0x1), - 0x80201D6C:("D_80201D6C","UNK_TYPE1","",0x1), - 0x802023FC:("D_802023FC","UNK_TYPE1","",0x1), - 0x80202878:("D_80202878","UNK_TYPE1","",0x1), - 0x80202880:("D_80202880","UNK_TYPE1","",0x1), - 0x802028BC:("D_802028BC","UNK_TYPE1","",0x1), - 0x80202980:("D_80202980","OSMesgQueue","",0x18), - 0x802029D8:("D_802029D8","UNK_TYPE1","",0x1), - 0x80202AB0:("D_80202AB0","OSMesgQueue","",0x18), - 0x80202AC8:("D_80202AC8","OSMesg","[16]",0x40), - 0x80202B08:("D_80202B08","OSMesgQueue","",0x18), - 0x80202B20:("D_80202B20","OSMesg","[16]",0x40), - 0x80202B60:("D_80202B60","OSMesgQueue","",0x18), - 0x80202B78:("D_80202B78","OSMesg","[64]",0x100), - 0x80203278:("D_80203278","OSMesgQueue","",0x18), - 0x80203290:("D_80203290","OSMesg","[1]",0x4), - 0x80203294:("D_80203294","UNK_TYPE1","",0x1), - 0x802034C0:("D_802034C0","UNK_TYPE1","",0x1), - 0x802034C4:("D_802034C4","UNK_TYPE1","",0x1), - 0x802034C8:("D_802034C8","UNK_TYPE1","",0x1), - 0x802034D0:("D_802034D0","UNK_TYPE4","",0x4), - 0x802034D4:("D_802034D4","UNK_TYPE1","",0x1), - 0x802034D8:("D_802034D8","UNK_TYPE1","",0x1), - 0x802034DC:("D_802034DC","UNK_TYPE1","",0x1), - 0x802034E8:("D_802034E8","UNK_TYPE1","",0x1), - 0x802034F0:("D_802034F0","UNK_TYPE2","",0x2), - 0x802034F8:("D_802034F8","UNK_TYPE1","",0x1), - 0x802034FC:("D_802034FC","UNK_TYPE1","",0x1), - 0x80203500:("D_80203500","UNK_TYPE1","",0x1), - 0x80203528:("D_80203528","UNK_TYPE4","",0x4), - 0x8020352C:("D_8020352C","UNK_TYPE1","",0x1), - 0x8020352E:("D_8020352E","UNK_TYPE1","",0x1), - 0x80203530:("D_80203530","UNK_TYPE1","",0x1), - 0x8020360C:("D_8020360C","UNK_TYPE4","",0x4), - 0x80203618:("D_80203618","UNK_TYPE1","",0x1), - 0x8020361C:("D_8020361C","UNK_TYPE1","",0x1), - 0x80203620:("D_80203620","UNK_TYPE1","",0x1), - 0x80203624:("D_80203624","UNK_TYPE1","",0x1), - 0x80203628:("D_80203628","UNK_TYPE1","",0x1), - 0x80203630:("D_80203630","UNK_TYPE1","",0x1), - 0x80203640:("D_80203640","UNK_TYPE1","",0x1), - 0x80203650:("D_80203650","UNK_TYPE1","",0x1), - 0x80203660:("D_80203660","UNK_TYPE1","",0x1), - 0x80203690:("D_80203690","UNK_TYPE1","",0x1), - 0x802036A0:("D_802036A0","UNK_TYPE1","",0x1), - 0x802036B0:("D_802036B0","UNK_TYPE1","",0x1), - 0x802036C0:("D_802036C0","UNK_TYPE1","",0x1), - 0x802036C4:("D_802036C4","UNK_TYPE1","",0x1), - 0x80203794:("D_80203794","UNK_TYPE1","",0x1), - 0x80203798:("D_80203798","UNK_TYPE1","",0x1), - 0x802037D0:("D_802037D0","UNK_TYPE1","",0x1), - 0x802037D4:("D_802037D4","UNK_TYPE1","",0x1), - 0x802038A4:("D_802038A4","UNK_TYPE1","",0x1), - 0x802038A8:("D_802038A8","UNK_TYPE1","",0x1), - 0x802038C2:("D_802038C2","UNK_TYPE1","",0x1), - 0x802038CE:("D_802038CE","UNK_TYPE1","",0x1), - 0x802038E0:("D_802038E0","UNK_TYPE1","",0x1), - 0x802038E4:("D_802038E4","UNK_TYPE1","",0x1), - 0x80203970:("D_80203970","UNK_TYPE1","",0x1), - 0x802039B4:("D_802039B4","UNK_TYPE1","",0x1), - 0x802039B8:("D_802039B8","UNK_TYPE1","",0x1), - 0x802039D2:("D_802039D2","UNK_TYPE1","",0x1), - 0x802039DE:("D_802039DE","UNK_TYPE1","",0x1), - 0x802039F0:("D_802039F0","UNK_TYPE1","",0x1), - 0x802039FC:("D_802039FC","UNK_TYPE1","",0x1), - 0x80203B80:("D_80203B80","UNK_TYPE1","",0x1), - 0x80203B88:("D_80203B88","UNK_TYPE1","",0x1), - 0x80203B90:("D_80203B90","UNK_TYPE1","",0x1), - 0x80204590:("D_80204590","UNK_TYPE1","",0x1), - 0x80204594:("D_80204594","UNK_TYPE1","",0x1), - 0x80204598:("D_80204598","UNK_TYPE1","",0x1), - 0x802045A4:("D_802045A4","UNK_TYPE1","",0x1), - 0x80204FA4:("D_80204FA4","UNK_TYPE1","",0x1), - 0x80204FA8:("D_80204FA8","UNK_TYPE1","",0x1), - 0x80204FB4:("D_80204FB4","UNK_TYPE1","",0x1), - 0x80204FB8:("D_80204FB8","UNK_TYPE1","",0x1), - 0x80204FC0:("D_80204FC0","UNK_TYPE1","",0x1), - 0x80204FCC:("D_80204FCC","UNK_TYPE1","",0x1), - 0x80204FD8:("D_80204FD8","UNK_TYPE1","",0x1), - 0x80205008:("D_80205008","UNK_TYPE1","",0x1), - 0x80205038:("D_80205038","UNK_TYPE1","",0x1), - 0x802050B9:("D_802050B9","UNK_TYPE1","",0x1), - 0x802050C0:("D_802050C0","UNK_TYPE1","",0x1), - 0x802050C4:("D_802050C4","UNK_TYPE1","",0x1), - 0x802050CC:("D_802050CC","UNK_TYPE4","",0x4), - 0x802050D0:("D_802050D0","UNK_TYPE4","",0x4), - 0x80205228:("D_80205228","UNK_TYPE1","",0x1), - 0x8020522B:("D_8020522B","UNK_TYPE1","",0x1), - 0x80205390:("D_80205390","UNK_TYPE1","",0x1), - 0x802053C8:("D_802053C8","UNK_TYPE1","",0x1), - 0x802057B0:("D_802057B0","UNK_TYPE1","",0x1), - 0x80205830:("D_80205830","UNK_TYPE1","",0x1), - 0x802084B0:("D_802084B0","UNK_TYPE1","",0x1), - 0x80208530:("D_80208530","UNK_TYPE1","",0x1), - 0x80208598:("D_80208598","UNK_TYPE1","",0x1), - 0x802085A8:("D_802085A8","UNK_TYPE1","",0x1), - 0x802085B8:("D_802085B8","UNK_TYPE1","",0x1), - 0x802085C8:("D_802085C8","UNK_TYPE1","",0x1), - 0x802085D8:("D_802085D8","UNK_TYPE1","",0x1), - 0x802085F8:("D_802085F8","UNK_TYPE1","",0x1), - 0x802085FC:("D_802085FC","UNK_TYPE1","",0x1), - 0x80208604:("D_80208604","UNK_TYPE1","",0x1), - 0x8020861C:("D_8020861C","UNK_TYPE1","",0x1), - 0x80208634:("D_80208634","UNK_TYPE1","",0x1), - 0x8020864C:("D_8020864C","UNK_TYPE1","",0x1), - 0x80208650:("D_80208650","UNK_TYPE1","",0x1), - 0x80208654:("D_80208654","UNK_TYPE1","",0x1), + 0x80200C70:("gAudioContext","AudioContext","",0x81F8), 0x80208E68:("D_80208E68","UNK_TYPE4","",0x4), 0x80208E6C:("D_80208E6C","UNK_TYPE4","",0x4), 0x80208E70:("D_80208E70","UNK_TYPE4","",0x4), 0x80208E74:("D_80208E74","UNK_TYPE4","",0x4), - 0x80208E90:("D_80208E90","UNK_TYPE1","",0x1), - 0x80208E94:("D_80208E94","UNK_TYPE1","",0x1), - 0x80208E98:("D_80208E98","UNK_TYPE1","",0x1), - 0x80208E99:("D_80208E99","UNK_TYPE1","",0x1), - 0x80208E9C:("D_80208E9C","UNK_TYPE1","",0x1), + 0x80208E90:("sJpegBitStreamPtr","UNK_TYPE1","",0x1), + 0x80208E94:("sJpegBitStreamByteIdx","UNK_TYPE1","",0x1), + 0x80208E98:("sJpegBitStreamBitIdx","UNK_TYPE1","",0x1), + 0x80208E99:("sJpegBitStreamDontSkip","UNK_TYPE1","",0x1), + 0x80208E9C:("sJpegBitStreamCurWord","UNK_TYPE1","",0x1), 0x80208EA0:("gGfxSPTaskYieldBuffer","u8","[OS_YIELD_DATA_SIZE]",0xC00), 0x80209AA0:("gGfxSPTaskStack","u8","[0x400]",0x400), 0x80209EA0:("gGfxPools","GfxPool","[2]",0x40620), @@ -5359,8 +5177,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), @@ -5796,13 +5614,11 @@ 0x80867784:("D_80867784","UNK_TYPE1","",0x1), 0x8086778C:("D_8086778C","UNK_PTR","",0x4), 0x8086780C:("En_Door_InitVars","UNK_TYPE1","",0x1), - 0x8086782C:("D_8086782C","UNK_TYPE2","",0x2), - 0x80867886:("D_80867886","UNK_TYPE1","",0x1), - 0x8086788A:("D_8086788A","UNK_TYPE2","",0x2), - 0x80867954:("D_80867954","UNK_TYPE1","",0x1), - 0x80867964:("D_80867964","UNK_TYPE1","",0x1), - 0x8086798C:("D_8086798C","UNK_TYPE1","",0x1), - 0x80867998:("D_80867998","UNK_TYPE1","",0x1), + 0x8086782C:("sObjInfo","UNK_TYPE2","",0x126), + 0x80867954:("sInitChain","UNK_TYPE1","",0x1), + 0x80867964:("sAnimations","AnimationHeader","[10]",0x28), + 0x8086798C:("sAnimOpenFrames","u8","[10]",0x10), + 0x80867998:("sAnimCloseFrames","u8","[10]",0x10), 0x808679A4:("D_808679A4","UNK_TYPE1","",0x1), 0x80867A20:("D_80867A20","f32","",0x4), 0x80867BC0:("D_80867BC0","UNK_TYPE1","",0x1), @@ -5985,10 +5801,7 @@ 0x808763AC:("D_808763AC","UNK_TYPE1","",0x1), 0x808763B4:("D_808763B4","UNK_TYPE1","",0x1), 0x808763C0:("D_808763C0","UNK_TYPE1","",0x1), - 0x808763D4:("D_808763D4","UNK_TYPE1","",0x1), - 0x808763D6:("D_808763D6","UNK_TYPE1","",0x1), - 0x808763E6:("D_808763E6","UNK_TYPE1","",0x1), - 0x808763E7:("D_808763E7","UNK_TYPE1","",0x1), + 0x808763D4:("D_808763D4","s8","[25]",0x25), 0x808763F0:("D_808763F0","f32","",0x4), 0x808763F4:("D_808763F4","f32","",0x4), 0x808763F8:("D_808763F8","f32","",0x4), @@ -6010,7 +5823,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), @@ -6080,19 +5893,18 @@ 0x8087B538:("D_8087B538","f32","",0x4), 0x80888EC0:("D_80888EC0","UNK_TYPE1","",0x1), 0x80888EE4:("D_80888EE4","UNK_TYPE1","",0x1), - 0x80888F08:("D_80888F08","UNK_TYPE1","",0x1), + 0x80888F08:("sAnimationHeaders","AnimationHeader*","[5]",0x14), 0x80888F1C:("D_80888F1C","UNK_TYPE1","",0x1), 0x80888F34:("D_80888F34","UNK_TYPE4","",0x4), - 0x80888F40:("D_80888F40","UNK_TYPE1","",0x1), + 0x80888F40:("sSkeletonHeaders","UNK_TYPE1","",0x1), 0x80888F54:("En_Horse_InitVars","UNK_TYPE1","",0x1), - 0x80888F74:("D_80888F74","UNK_TYPE1","",0x1), - 0x80888FA0:("D_80888FA0","UNK_TYPE1","",0x1), + 0x80888F74:("sCylinderInit1","UNK_TYPE1","",0x1), + 0x80888FA0:("sCylinderInit2","UNK_TYPE1","",0x1), 0x80888FCC:("D_80888FCC","UNK_TYPE1","",0x1), - 0x80888FF0:("D_80888FF0","UNK_TYPE1","",0x1), - 0x80888FFC:("D_80888FFC","UNK_PTR","",0x4), - 0x80889000:("D_80889000","UNK_TYPE1","",0x1), + 0x80888FF0:("sJntSphInit","UNK_TYPE1","",0x10), + 0x80889000:("sColChkInfoInit","UNK_TYPE1","",0x1), 0x80889008:("D_80889008","UNK_TYPE1","",0x1), - 0x80889010:("D_80889010","UNK_TYPE1","",0x1), + 0x80889010:("sInitChain","UNK_TYPE1","",0x1), 0x80889018:("D_80889018","UNK_TYPE1","",0x1), 0x80889030:("D_80889030","UNK_TYPE1","",0x1), 0x80889048:("D_80889048","UNK_TYPE1","",0x1), @@ -6107,7 +5919,7 @@ 0x8088911C:("D_8088911C","UNK_TYPE1","",0x1), 0x80889148:("D_80889148","UNK_TYPE4","",0x4), 0x80889154:("D_80889154","UNK_TYPE4","",0x4), - 0x80889160:("D_80889160","UNK_PTR","",0x4), + 0x80889160:("sActionFuncs","UNK_PTR","",0x4), 0x808891C8:("D_808891C8","UNK_TYPE4","",0x4), 0x808891D4:("D_808891D4","UNK_TYPE4","",0x4), 0x808891E0:("D_808891E0","UNK_TYPE4","",0x4), @@ -6235,10 +6047,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), @@ -6447,7 +6259,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), @@ -6539,24 +6351,12 @@ 0x808A2300:("D_808A2300","f32","",0x4), 0x808A2304:("D_808A2304","f32","",0x4), 0x808A2FF0:("En_Boom_InitVars","UNK_TYPE1","",0x1), - 0x808A3010:("D_808A3010","UNK_TYPE1","",0x1), - 0x808A3060:("D_808A3060","UNK_TYPE1","",0x1), - 0x808A3068:("D_808A3068","UNK_TYPE1","",0x1), - 0x808A3069:("D_808A3069","UNK_TYPE1","",0x1), - 0x808A306A:("D_808A306A","UNK_TYPE1","",0x1), - 0x808A306B:("D_808A306B","UNK_TYPE1","",0x1), - 0x808A306C:("D_808A306C","UNK_TYPE1","",0x1), - 0x808A306D:("D_808A306D","UNK_TYPE1","",0x1), - 0x808A306E:("D_808A306E","UNK_TYPE1","",0x1), - 0x808A306F:("D_808A306F","UNK_TYPE1","",0x1), - 0x808A3070:("D_808A3070","UNK_TYPE1","",0x1), - 0x808A3071:("D_808A3071","UNK_TYPE1","",0x1), - 0x808A3072:("D_808A3072","UNK_TYPE1","",0x1), - 0x808A3073:("D_808A3073","UNK_TYPE1","",0x1), - 0x808A3074:("D_808A3074","UNK_TYPE1","",0x1), - 0x808A3075:("D_808A3075","UNK_TYPE1","",0x1), - 0x808A3076:("D_808A3076","UNK_TYPE1","",0x1), - 0x808A3077:("D_808A3077","UNK_TYPE1","",0x1), + 0x808A3010:("sQuadInit","UNK_TYPE1","",0x1), + 0x808A3060:("sInitChain","UNK_TYPE1","",0x1), + 0x808A3068:("D_808A3068","Color_RGBA8","",0x4), + 0x808A306C:("D_808A306C","Color_RGBA8","",0x4), + 0x808A3070:("D_808A3070","Color_RGBA8","",0x4), + 0x808A3074:("D_808A3074","Color_RGBA8","",0x4), 0x808A3078:("D_808A3078","UNK_TYPE4","",0x4), 0x808A30B0:("D_808A30B0","f32","",0x4), 0x808A30B4:("D_808A30B4","f32","",0x4), @@ -6773,10 +6573,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), @@ -6936,7 +6734,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), @@ -7159,7 +6957,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), @@ -7512,7 +7309,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), @@ -7588,12 +7385,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), @@ -7604,18 +7400,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), @@ -7625,7 +7420,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), @@ -7639,14 +7435,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), @@ -7923,11 +7719,6 @@ 0x8090DC1C:("D_8090DC1C","f32","",0x4), 0x8090DC20:("D_8090DC20","f32","",0x4), 0x8090DC24:("D_8090DC24","f32","",0x4), - 0x8090DC30:("enFishingOverlayInfo","OverlayRelocationSection","",0x14), - 0x8090DC44:("enFishingOverlayRelocations","u32","[2393]",0x2564), - 0x809101AC:("enFishingOverlayInfoOffset","u32","",0x4), - 0x80910000:("D_80910000","UNK_TYPE1","",0x1), - 0x80910001:("D_80910001","UNK_TYPE1","",0x1), 0x809101B0:("D_809101B0","f32","",0x4), 0x809101B4:("D_809101B4","f32","",0x4), 0x809101B8:("D_809101B8","UNK_TYPE1","",0x1), @@ -7937,46 +7728,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), @@ -7988,29 +7770,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), @@ -8022,8 +7798,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), @@ -8197,15 +7972,14 @@ 0x8092024C:("D_8092024C","UNK_TYPE1","",0x1), 0x80920268:("D_80920268","UNK_TYPE1","",0x1), 0x80920290:("jtbl_80920290","UNK_PTR","",0x4), - 0x80920DF0:("arrowFireTexture1","u8","[2048]",0x800), - 0x809215F0:("arrowFireTexture2","u8","[2048]",0x800), - 0x80921DF0:("arrowFireVertices","F3DVertex","[43]",0x2b0), - 0x80921FF0:("D_80921FF0","UNK_TYPE1","",0x1), - 0x809220A0:("D_809220A0","Gfx","[22]",0xb0), - 0x80922150:("D_80922150","Gfx","[24]",0xc0), + 0x80920DF0:("gFireArrowTex","u8","[2048]",0x800), + 0x809215F0:("gFireArrowMaskTex","u8","[2048]",0x800), + 0x80921DF0:("gFireArrowVtx","F3DVertex","[43]",0x2b0), + 0x809220A0:("gIceArrowMaterialDL","Gfx","[22]",0xb0), + 0x80922150:("gIceArrowModelDL","Gfx","[24]",0xc0), 0x80922210:("Arrow_Fire_InitVars","ActorInit","",0x20), - 0x80922230:("D_80922230","UNK_TYPE1","",0x1), - 0x80922280:("fireArrowActorInitVars","ActorInitVar","[1]",0x4), + 0x80922230:("sQuadInit","UNK_TYPE1","",0x1), + 0x80922280:("sInitChain","ActorInitVar","[1]",0x4), 0x80922284:("D_80922284","Vec3f","",0xc), 0x80922290:("D_80922290","Vec3f","",0xc), 0x8092229C:("D_8092229C","Vec3f","",0xc), @@ -8246,7 +8020,7 @@ 0x80925F10:("D_80925F10","UNK_TYPE1","",0x1), 0x80925FC0:("D_80925FC0","UNK_TYPE1","",0x1), 0x80926080:("Arrow_Light_InitVars","UNK_TYPE1","",0x1), - 0x809260A0:("D_809260A0","UNK_TYPE1","",0x1), + 0x809260A0:("sInitChain","UNK_TYPE1","",0x1), 0x809260B0:("D_809260B0","char","[]",0x1), 0x809260B8:("D_809260B8","f32","",0x4), 0x809260BC:("D_809260BC","f32","",0x4), @@ -8326,7 +8100,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), @@ -8638,7 +8412,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), @@ -8849,14 +8623,14 @@ 0x809548A0:("Bg_Ingate_InitVars","UNK_TYPE1","",0x1), 0x809572E0:("En_Kanban_InitVars","UNK_TYPE1","",0x1), 0x80957300:("D_80957300","UNK_TYPE1","",0x1), - 0x8095732C:("D_8095732C","UNK_TYPE2","",0x2), + 0x8095732C:("sPartFlags","UNK_TYPE2","",0x2), 0x8095732E:("D_8095732E","UNK_TYPE2","",0x2), 0x80957330:("D_80957330","UNK_TYPE2","",0x2), 0x80957332:("D_80957332","UNK_TYPE2","",0x2), - 0x80957344:("D_80957344","UNK_TYPE4","",0x4), - 0x80957428:("D_80957428","UNK_TYPE4","",0x4), - 0x8095750C:("D_8095750C","UNK_TYPE1","",0x1), - 0x80957530:("D_80957530","UNK_TYPE1","",0x1), + 0x80957344:("sPieceOffsets","UNK_TYPE4","",0x4), + 0x80957428:("sPieceSizes","UNK_TYPE4","",0x4), + 0x8095750C:("sCutTypes","UNK_TYPE1","",0x1), + 0x80957530:("sCutFlags","UNK_TYPE1","",0x1), 0x8095753C:("D_8095753C","UNK_TYPE4","",0x4), 0x80957548:("D_80957548","UNK_TYPE4","",0x4), 0x8095754C:("D_8095754C","UNK_TYPE4","",0x4), @@ -9064,28 +8838,28 @@ 0x8096AD3C:("jtbl_8096AD3C","UNK_PTR","",0x4), 0x8096B290:("En_Okarina_Effect_InitVars","UNK_TYPE1","",0x1), 0x8096B2B0:("D_8096B2B0","f32","",0x4), - 0x8096E910:("D_8096E910","UNK_TYPE2","",0x2), - 0x8096E914:("D_8096E914","UNK_TYPE2","",0x2), - 0x8096E918:("D_8096E918","UNK_TYPE2","",0x2), - 0x8096E91C:("D_8096E91C","UNK_TYPE2","",0x2), - 0x8096E920:("D_8096E920","UNK_TYPE2","",0x2), + 0x8096E910:("sInputDelayTimer","s16","",0x2), + 0x8096E914:("sZeldaEffectColorTimer","s16","",0x2), + 0x8096E918:("sZeldaEffectColorTargetIndex","s16","",0x2), + 0x8096E91C:("sTextAlphaTargetIndex","s16","",0x2), + 0x8096E920:("sTextAlphaTimer","s16","",0x2), 0x8096E924:("En_Mag_InitVars","UNK_TYPE1","",0x1), - 0x8096E944:("D_8096E944","UNK_TYPE1","",0x1), - 0x8096E948:("D_8096E948","UNK_TYPE1","",0x1), - 0x8096E94C:("D_8096E94C","UNK_TYPE1","",0x1), - 0x8096E950:("D_8096E950","UNK_TYPE1","",0x1), - 0x8096E954:("D_8096E954","UNK_TYPE1","",0x1), - 0x8096E958:("D_8096E958","UNK_TYPE2","",0x2), - 0x8096E95C:("D_8096E95C","UNK_TYPE2","",0x2), - 0x8096E960:("D_8096E960","UNK_TYPE2","",0x2), - 0x8096E964:("D_8096E964","UNK_TYPE1","",0x1), - 0x8096E970:("D_8096E970","UNK_TYPE4","",0x4), - 0x8096E988:("D_8096E988","UNK_TYPE4","",0x4), - 0x8096E9A0:("D_8096E9A0","UNK_TYPE4","",0x4), - 0x8096E9B8:("D_8096E9B8","UNK_TYPE2","",0x2), - 0x8096E9C4:("D_8096E9C4","UNK_TYPE2","",0x2), - 0x8096E9D0:("D_8096E9D0","UNK_TYPE2","",0x2), - 0x8096E9D4:("D_8096E9D4","UNK_TYPE1","",0x1), + 0x8096E944:("sDisplayEffectPrimRedTargets","s16","[2]",0x4), + 0x8096E948:("sDisplayEffectPrimGreenTargets","s16","[2]",0x4), + 0x8096E94C:("sDisplayEffectPrimBlueTargets","s16","[2]",0x4), + 0x8096E950:("sDisplayEffectEnvRedTargets","s16","[2]",0x4), + 0x8096E954:("sDisplayEffectEnvBlueTargets","s16","[2]",0x4), + 0x8096E958:("sAppearEffectPrimGreenTargets","s16","[2]",0x4), + 0x8096E95C:("sAppearEffectEnvRedTargets","s16","[2]",0x4), + 0x8096E960:("sAppearEffectEnvBlueTargets","s16","[2]",0x4), + 0x8096E964:("pressStartFontIndices","u8","[10]",0x1), + 0x8096E970:("sAppearEffectMaskTextures","TexturePtr","[6]",0x18), + 0x8096E988:("sDisplayEffectMaskTextures","TexturePtr","[6]",0x18), + 0x8096E9A0:("sEffectTextures","TexturePtr","[6]",0x18), + 0x8096E9B8:("sEffectScrollVelocitySs","s16","[6]",0xC), + 0x8096E9C4:("sEffectScrollVelocityTs","s16","[6]",0xC), + 0x8096E9D0:("sTextAlpha","s16","",0x2), + 0x8096E9D4:("sTextAlphaTargets","s16","[2]",0x4), 0x8096E9E0:("jtbl_8096E9E0","UNK_PTR","",0x4), 0x8096F090:("Elf_Msg2_InitVars","UNK_TYPE1","",0x1), 0x8096F0B0:("D_8096F0B0","UNK_TYPE1","",0x1), @@ -9210,8 +8984,8 @@ 0x80979150:("D_80979150","f32","",0x4), 0x80979560:("Effect_Ss_D_Fire_InitVars","UNK_TYPE1","",0x1), 0x80979568:("D_80979568","UNK_TYPE1","",0x1), - 0x80979AB0:("Effect_Ss_Bubble_InitVars","UNK_TYPE1","",0x1), - 0x80979AB8:("D_80979AB8","UNK_TYPE1","",0x1), + 0x80979AB0:("Effect_Ss_Bubble_InitVars","UNK_TYPE1","",0x8), + 0x80979AB8:("D_80979AB8","f32","[3]",0xC), 0x80979AD0:("D_80979AD0","f32","",0x4), 0x80979AD4:("D_80979AD4","f32","",0x4), 0x80979FF0:("Effect_Ss_G_Ripple_InitVars","UNK_TYPE1","",0x1), @@ -10423,8 +10197,8 @@ 0x809DF570:("D_809DF570","UNK_TYPE1","",0x1), 0x809DF590:("Boss_02_InitVars","UNK_TYPE1","",0x1), 0x809DF5B0:("D_809DF5B0","f32","",0x4), - 0x809DF5B6:("D_809DF5B6","UNK_TYPE2","",0x2), - 0x809DF5E6:("D_809DF5E6","UNK_TYPE2","",0x2), + 0x809DF5B4:("D_809DF5B4","UNK_TYPE2","[24]",0x30), + 0x809DF5E4:("D_809DF5E4","UNK_TYPE2","[24]",0x30), 0x809DF614:("D_809DF614","UNK_TYPE1","",0x1), 0x809DF92C:("D_809DF92C","UNK_TYPE1","",0x1), 0x809DF93C:("D_809DF93C","UNK_TYPE1","",0x1), @@ -10522,17 +10296,17 @@ 0x809E8F14:("D_809E8F14","UNK_TYPE1","",0x1), 0x809E8F24:("D_809E8F24","UNK_TYPE1","",0x1), 0x809E8FD8:("D_809E8FD8","UNK_TYPE1","",0x1), - 0x809E8FE8:("D_809E8FE8","UNK_TYPE4","",0x4), - 0x809E90FC:("D_809E90FC","UNK_TYPE1","",0x1), - 0x809E9100:("D_809E9100","UNK_TYPE1","",0x1), + 0x809E8FE8:("sGyorgInitialPos","Vec3f","",0xC), + 0x809E8FF4:("D_809E8FF4","f32","",0x1), + 0x809E90FC:("sGyorgDustPrimColor","UNK_TYPE1","",0x1), + 0x809E9100:("sGyorgDustEnvColor","UNK_TYPE1","",0x1), 0x809E9104:("D_809E9104","UNK_TYPE1","",0x1), - 0x809E9128:("D_809E9128","UNK_TYPE1","",0x1), - 0x809E9136:("D_809E9136","UNK_TYPE1","",0x1), + 0x809E9128:("sGyorgSphElementIndices","s8","[30]",0x1E), 0x809E9148:("D_809E9148","UNK_TYPE1","",0x1), - 0x809E9154:("D_809E9154","UNK_TYPE1","",0x1), + 0x809E9154:("D_809E9154","Vec3f","[7]",0x54), 0x809E91A8:("D_809E91A8","UNK_TYPE1","",0x1), 0x809E91B4:("D_809E91B4","f32","",0x4), - 0x809E91C0:("D_809E91C0","UNK_TYPE4","",0x4), + 0x809E91C0:("sGyorgSeaweedDLs","UNK_TYPE4","",0x4), 0x809E91E0:("D_809E91E0","f32","",0x4), 0x809E91E4:("D_809E91E4","f32","",0x4), 0x809E91E8:("D_809E91E8","f32","",0x4), @@ -10595,13 +10369,11 @@ 0x809E9841:("D_809E9841","UNK_TYPE1","",0x1), 0x809E9842:("D_809E9842","UNK_TYPE1","",0x1), 0x809E9848:("D_809E9848","UNK_TYPE1","",0x1), - 0x809E9858:("D_809E9858","UNK_TYPE1","",0x1), - 0x809E989C:("D_809E989C","UNK_TYPE1","",0x1), - 0x809E98E0:("D_809E98E0","UNK_TYPE1","",0x1), - 0x809EC030:("D_809EC030","UNK_TYPE4","",0x4), - 0x809EC034:("D_809EC034","UNK_TYPE4","",0x4), - 0x809EC038:("D_809EC038","UNK_TYPE4","",0x4), - 0x809EC03C:("D_809EC03C","UNK_TYPE4","",0x4), + 0x809E9858:("sGyorgEffects","UNK_TYPE1","[150]",0x27D8), + 0x809EC030:("sGyorgBossInstance","UNK_TYPE4","",0x4), + 0x809EC034:("sRandSeed0","UNK_TYPE4","",0x4), + 0x809EC038:("sRandSeed1","UNK_TYPE4","",0x4), + 0x809EC03C:("sRandSeed2","UNK_TYPE4","",0x4), 0x809EE150:("D_809EE150","UNK_TYPE1","",0x1), 0x809EE170:("Boss_04_InitVars","UNK_TYPE1","",0x1), 0x809EE190:("D_809EE190","UNK_TYPE1","",0x1), @@ -10995,9 +10767,6 @@ 0x80A0C55C:("D_80A0C55C","f32","",0x4), 0x80A0C560:("D_80A0C560","f32","",0x4), 0x80A0C7C0:("En_Boj_05_InitVars","UNK_TYPE1","",0x1), - 0x80A0C7E0:("enBoj05OverlayInfo","OverlayRelocationSection","",0x14), - 0x80A0C7F4:("enBoj05OverlayRelocations","u32","[4]",0x10), - 0x80A0C80C:("enBoj05OverlayInfoOffset","u32","",0x4), 0x80A10860:("sAnimationsBombShopkeeper","UNK_PTR","",0x4), 0x80A10890:("En_Sob1_InitVars","UNK_TYPE1","",0x1), 0x80A108B0:("sObjectIds","UNK_TYPE2","",0x2), @@ -11066,7 +10835,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), @@ -11101,10 +10870,10 @@ 0x80A16818:("jtbl_80A16818","UNK_PTR","",0x4), 0x80A18EC0:("En_Raf_InitVars","UNK_TYPE1","",0x1), 0x80A18EE0:("D_80A18EE0","UNK_TYPE1","",0x1), - 0x80A18F0C:("D_80A18F0C","UNK_TYPE1","",0x1), - 0x80A18F4C:("D_80A18F4C","UNK_TYPE1","",0x1), - 0x80A18F8C:("D_80A18F8C","UNK_TYPE1","",0x1), - 0x80A1918C:("D_80A1918C","UNK_TYPE1","",0x1), + 0x80A18F0C:("D_80A18F0C","u8","[0x40]",0x40), + 0x80A18F4C:("D_80A18F4C","u8","[0x40]",0x40), + 0x80A18F8C:("D_80A18F8C","u8","[0x200]",0x200), + 0x80A1918C:("D_80A1918C","u8","[0x200]",0x200), 0x80A1939C:("D_80A1939C","UNK_TYPE1","",0x1), 0x80A193BC:("D_80A193BC","UNK_TYPE4","",0x4), 0x80A193C8:("D_80A193C8","UNK_TYPE1","",0x1), @@ -11114,10 +10883,8 @@ 0x80A19400:("D_80A19400","UNK_TYPE4","",0x4), 0x80A1940C:("D_80A1940C","UNK_TYPE4","",0x4), 0x80A19418:("D_80A19418","UNK_TYPE2","",0x2), - 0x80A19420:("D_80A19420","UNK_TYPE1","",0x1), - 0x80A19438:("D_80A19438","UNK_TYPE1","",0x1), - 0x80A19444:("D_80A19444","UNK_TYPE1","",0x1), - 0x80A1945C:("D_80A1945C","UNK_TYPE1","",0x1), + 0x80A19420:("D_80A19420","Vec3f","[3]",0x24), + 0x80A19444:("D_80A19444","Vec3f","[3]",0x24), 0x80A19468:("D_80A19468","UNK_TYPE2","",0x2), 0x80A19474:("D_80A19474","UNK_TYPE1","",0x1), 0x80A194B0:("D_80A194B0","UNK_TYPE1","",0x1), @@ -11727,8 +11494,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), @@ -12034,7 +11801,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), @@ -12095,10 +11862,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), @@ -12344,10 +12109,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), @@ -12379,8 +12141,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), @@ -12635,8 +12395,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), @@ -12657,9 +12416,6 @@ 0x80A8B440:("jtbl_D_80A8B440","UNK_PTR","",0x4), 0x80A8B478:("jtbl_D_80A8B478","UNK_PTR","",0x4), 0x80A8B48C:("jtbl_D_80A8B48C","UNK_PTR","",0x4), - 0x80A8B4A0:("enTruOverlayInfo","OverlayRelocationSection","",0x14), - 0x80A8B4B4:("enTruOverlayRelocations","u32","[174]",0x2b8), - 0x80A8B76C:("enTruOverlayInfoOffset","u32","",0x4), 0x80A8FE10:("sAnimations","UNK_TYPE1","",0x1), 0x80A8FEB0:("En_Trt_InitVars","UNK_TYPE1","",0x1), 0x80A8FED0:("sActorScale","UNK_TYPE4","",0x4), @@ -13141,9 +12897,6 @@ 0x80AC027C:("jtbl_80AC027C","UNK_PTR","",0x4), 0x80AC0300:("jtbl_80AC0300","UNK_PTR","",0x4), 0x80AC03E4:("jtbl_80AC03E4","UNK_PTR","",0x4), - 0x80AC0400:("enMa4OverlayInfo","OverlayRelocationSection","",0x14), - 0x80AC0414:("enMa4OverlayRelocations","u32","[262]",0x418), - 0x80AC082C:("enMa4OverlayInfoOffset","u32","",0x4), 0x80AC1090:("En_Twig_InitVars","UNK_TYPE1","",0x1), 0x80AC10B0:("D_80AC10B0","UNK_TYPE1","",0x1), 0x80AC10BC:("D_80AC10BC","UNK_TYPE2","",0x2), @@ -13697,10 +13450,9 @@ 0x80AF34F4:("D_80AF34F4","f32","",0x4), 0x80AF34F8:("D_80AF34F8","f32","",0x4), 0x80AF38B0:("D_80AF38B0","UNK_TYPE1","",0x1), - 0x80AF38F0:("D_80AF38F0","f32","",0x4), - 0x80AF38F4:("D_80AF38F4","f32","",0x4), - 0x80AF38F8:("D_80AF38F8","f32","",0x4), - 0x80AF3900:("D_80AF3900","UNK_TYPE1","",0x1), + 0x80AF38F0:("D_80AF38F0","Vec3f","",0xC), + 0x80AF38FC:("D_80AF38FC","UNK_TYPE4","",0x4), + 0x80AF3900:("D_80AF3900","Vec3f","",0xC), 0x80AF3E80:("Obj_Lightblock_InitVars","UNK_TYPE1","",0x1), 0x80AF3EA0:("D_80AF3EA0","UNK_TYPE1","",0x1), 0x80AF3ECC:("D_80AF3ECC","UNK_TYPE1","",0x1), @@ -14139,10 +13891,8 @@ 0x80B19AAC:("D_80B19AAC","UNK_TYPE1","",0x1), 0x80B19AB8:("D_80B19AB8","UNK_TYPE1","",0x1), 0x80B19AC4:("D_80B19AC4","UNK_TYPE1","",0x1), - 0x80B19AD0:("D_80B19AD0","UNK_TYPE1","",0x1), - 0x80B19ADA:("D_80B19ADA","UNK_TYPE1","",0x1), - 0x80B19ADC:("D_80B19ADC","UNK_TYPE1","",0x1), - 0x80B19B18:("D_80B19B18","UNK_TYPE1","",0x1), + 0x80B19AD0:("D_80B19AD0","s8","[12]",0xC), + 0x80B19ADC:("D_80B19ADC","Vec3f","[5]",0x3C), 0x80B19B20:("D_80B19B20","f32","",0x4), 0x80B19B24:("D_80B19B24","f32","",0x4), 0x80B19B28:("D_80B19B28","f32","",0x4), @@ -14274,25 +14024,18 @@ 0x80B245CC:("D_80B245CC","UNK_TYPE4","",0x4), 0x80B245D0:("D_80B245D0","f32","",0x4), 0x80B25D20:("En_Racedog_InitVars","UNK_TYPE1","",0x1), - 0x80B25D40:("D_80B25D40","UNK_TYPE2","",0x2), - 0x80B25D44:("D_80B25D44","UNK_TYPE2","",0x2), - 0x80B25D48:("D_80B25D48","UNK_TYPE2","",0x2), - 0x80B25D4C:("D_80B25D4C","UNK_TYPE2","",0x2), - 0x80B25D50:("D_80B25D50","f32","",0x4), - 0x80B25D54:("D_80B25D54","f32","",0x4), - 0x80B25D88:("D_80B25D88","UNK_TYPE1","",0x1), - 0x80B25D90:("D_80B25D90","UNK_TYPE1","",0x1), - 0x80B25D94:("D_80B25D94","UNK_TYPE1","",0x1), - 0x80B25D96:("D_80B25D96","UNK_TYPE1","",0x1), - 0x80B25E68:("D_80B25E68","UNK_TYPE4","",0x4), - 0x80B25E72:("D_80B25E72","UNK_TYPE2","",0x2), - 0x80B25E78:("D_80B25E78","UNK_TYPE1","",0x1), - 0x80B25E98:("D_80B25E98","UNK_TYPE1","",0x1), - 0x80B25EC4:("D_80B25EC4","UNK_TYPE1","",0x1), - 0x80B25ED0:("D_80B25ED0","UNK_TYPE1","",0x1), - 0x80B25EF0:("D_80B25EF0","UNK_PTR","",0x4), - 0x80B25EF4:("D_80B25EF4","UNK_TYPE1","",0x1), - 0x80B25F14:("D_80B25F14","UNK_TYPE1","",0x1), + 0x80B25D40:("D_80B25D40","s16","",0x2), + 0x80B25D44:("D_80B25D44","s16","",0x2), + 0x80B25D48:("D_80B25D48","s16","",0x2), + 0x80B25D4C:("D_80B25D4C","s16","",0x2), + 0x80B25D50:("D_80B25D50","f32","",0x38), + 0x80B25D88:("D_80B25D88","UNK_TYPE1","",0xE0), + 0x80B25E68:("D_80B25E68","UNK_TYPE1","",0x10), + 0x80B25E78:("D_80B25E78","f32","",0x20), + 0x80B25E98:("D_80B25E98","UNK_TYPE1","",0x2C), + 0x80B25EC4:("D_80B25EC4","UNK_TYPE1","",0xC), + 0x80B25ED0:("D_80B25ED0","UNK_TYPE1","",0x20), + 0x80B25EF0:("D_80B25EF0","UNK_TYPE1","",0x100), 0x80B25FF0:("D_80B25FF0","UNK_TYPE1","",0x1), 0x80B25FF4:("D_80B25FF4","UNK_TYPE4","",0x4), 0x80B26000:("D_80B26000","UNK_TYPE4","",0x4), @@ -14424,10 +14167,7 @@ 0x80B311D8:("D_80B311D8","UNK_TYPE1","",0x1), 0x80B31340:("D_80B31340","UNK_TYPE1","",0x1), 0x80B31350:("D_80B31350","UNK_TYPE1","",0x1), - 0x80B313A0:("D_80B313A0","UNK_TYPE1","",0x18), - 0x80B313B8:("D_80B313B8","UNK_TYPE1","",0x18), - 0x80B313D0:("D_80B313D0","UNK_TYPE1","",0x18), - 0x80B313E8:("D_80B313E8","UNK_TYPE1","",0x18), + 0x80B313A0:("D_80B313A0","ObjSpidertentStruct2","[4]",0x60), 0x80B31400:("D_80B31400","UNK_TYPE1","",0x1), 0x80B3140C:("D_80B3140C","UNK_TYPE1","",0x1), 0x80B31418:("D_80B31418","UNK_TYPE1","",0x1), @@ -14634,7 +14374,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), @@ -15039,15 +14779,10 @@ 0x80B60754:("D_80B60754","UNK_TYPE1","",0x1), 0x80B60758:("D_80B60758","UNK_TYPE1","",0x1), 0x80B60764:("D_80B60764","UNK_TYPE1","",0x1), - 0x80B60770:("D_80B60770","f32","",0x4), - 0x80B60774:("D_80B60774","f32","",0x4), - 0x80B60778:("D_80B60778","f32","",0x4), - 0x80B6077C:("D_80B6077C","UNK_TYPE1","",0x1), - 0x80B60780:("D_80B60780","f32","",0x4), - 0x80B60788:("D_80B60788","UNK_TYPE1","",0x1), - 0x80B60790:("D_80B60790","f32","",0x4), - 0x80B607E8:("D_80B607E8","UNK_TYPE1","",0x1), - 0x80B607F0:("D_80B607F0","f32","",0x4), + 0x80B60770:("D_80B60770","Vec3f","",0xC), + 0x80B6077C:("D_80B6077C","Vec3f","",0xC), + 0x80B60788:("D_80B60788","Vec3f","[8]",0x60), + 0x80B607E8:("D_80B607E8","Vec3f","[8]",0x60), 0x80B60848:("D_80B60848","UNK_TYPE1","",0x1), 0x80B60858:("D_80B60858","UNK_TYPE1","",0x1), 0x80B60878:("D_80B60878","UNK_TYPE4","",0x4), @@ -15846,7 +15581,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), @@ -15898,9 +15633,7 @@ 0x80BB821C:("D_80BB821C","f32","",0x4), 0x80BB8450:("D_80BB8450","UNK_TYPE4","",0x4), 0x80BB8454:("D_80BB8454","f32","",0x4), - 0x80BB8458:("D_80BB8458","UNK_TYPE4","",0x4), - 0x80BB845C:("D_80BB845C","UNK_TYPE4","",0x4), - 0x80BB8460:("D_80BB8460","UNK_TYPE4","",0x4), + 0x80BB8458:("D_80BB8458","EnTanron2*","[82]",0x148), 0x80BB9720:("D_80BB9720","UNK_TYPE4","",0x4), 0x80BB972C:("D_80BB972C","UNK_TYPE4","",0x4), 0x80BB9730:("En_Tanron3_InitVars","UNK_TYPE1","",0x1), @@ -15918,10 +15651,10 @@ 0x80BB97D0:("D_80BB97D0","f32","",0x4), 0x80BB97D4:("D_80BB97D4","f32","",0x4), 0x80BBAB10:("Obj_Chan_InitVars","UNK_TYPE1","",0x1), - 0x80BBAB30:("D_80BBAB30","UNK_TYPE1","",0x1), - 0x80BBAB5C:("D_80BBAB5C","UNK_TYPE1","",0x1), - 0x80BBAB60:("D_80BBAB60","UNK_TYPE4","",0x4), - 0x80BBAB78:("D_80BBAB78","f32","",0x4), + 0x80BBAB30:("sObjChanCylinderInit","UNK_TYPE1","",0x1), + 0x80BBAB5C:("sObjChanInitChain","UNK_TYPE1","",0x1), + 0x80BBAB60:("sObjChanFlameSize","UNK_TYPE4","",0x4), + 0x80BBAB78:("sObjChanFlameYOffset","f32","",0x4), 0x80BBAB80:("D_80BBAB80","f32","",0x4), 0x80BBAB84:("D_80BBAB84","f32","",0x4), 0x80BBAB88:("D_80BBAB88","f32","",0x4), @@ -15932,7 +15665,7 @@ 0x80BBAB9C:("D_80BBAB9C","f32","",0x4), 0x80BBABA0:("D_80BBABA0","f32","",0x4), 0x80BBABA4:("D_80BBABA4","f32","",0x4), - 0x80BBAC90:("D_80BBAC90","UNK_TYPE1","",0x1), + 0x80BBAC90:("sObjChanLoaded","UNK_TYPE1","",0x1), 0x80BBC6D0:("En_Zos_InitVars","UNK_TYPE1","",0x1), 0x80BBC6F0:("D_80BBC6F0","UNK_TYPE1","",0x1), 0x80BBC71C:("D_80BBC71C","UNK_TYPE1","",0x1), @@ -15998,8 +15731,8 @@ 0x80BC4668:("D_80BC4668","UNK_TYPE1","",0x1), 0x80BC4680:("jtbl_80BC4680","UNK_PTR","",0x4), 0x80BC4DD0:("Bg_F40_Switch_InitVars","UNK_TYPE1","",0x1), - 0x80BC4DF0:("D_80BC4DF0","UNK_TYPE4","",0x4), - 0x80BC4DF4:("D_80BC4DF4","UNK_TYPE4","",0x4), + 0x80BC4DF0:("sBgF40SwitchGlobalsInitialized","s32","",0x4), + 0x80BC4DF4:("sBgF40SwitchGlobalFlags","BgF40SwitchGlobalFlags","",0x10), 0x80BC4E04:("D_80BC4E04","UNK_TYPE1","",0x1), 0x80BC4E20:("D_80BC4E20","f32","",0x4), 0x80BC4E24:("D_80BC4E24","f32","",0x4), @@ -16008,7 +15741,7 @@ 0x80BC4E30:("D_80BC4E30","f32","",0x4), 0x80BC4E34:("D_80BC4E34","f32","",0x4), 0x80BC4E38:("D_80BC4E38","f32","",0x4), - 0x80BC4F20:("D_80BC4F20","UNK_TYPE1","",0x1), + 0x80BC4F20:("sBgF40SwitchLastUpdateFrame","u32","",0x4), 0x80BC6760:("En_Po_Composer_InitVars","UNK_TYPE1","",0x1), 0x80BC6780:("D_80BC6780","UNK_TYPE1","",0x1), 0x80BC67AC:("D_80BC67AC","UNK_TYPE1","",0x1), @@ -16264,9 +15997,7 @@ 0x80BDDCF0:("D_80BDDCF0","UNK_TYPE1","",0x1), 0x80BDDD1C:("D_80BDDD1C","UNK_TYPE4","",0x4), 0x80BDDD28:("D_80BDDD28","UNK_TYPE4","",0x4), - 0x80BDDD34:("D_80BDDD34","f32","",0x4), - 0x80BDDD38:("D_80BDDD38","f32","",0x4), - 0x80BDDD3C:("D_80BDDD3C","f32","",0x4), + 0x80BDDD34:("D_80BDDD34","Vec3f","",0xC), 0x80BDDD40:("D_80BDDD40","UNK_TYPE1","",0x1), 0x80BDDD4C:("D_80BDDD4C","UNK_TYPE1","",0x1), 0x80BDDD58:("D_80BDDD58","UNK_TYPE4","",0x4), @@ -16376,9 +16107,9 @@ 0x80BE6150:("En_Tanron6_InitVars","UNK_TYPE1","",0x1), 0x80BE6170:("D_80BE6170","UNK_TYPE1","",0x1), 0x80BE78D0:("En_Daiku2_InitVars","UNK_TYPE1","",0x1), - 0x80BE78F0:("sTextIds","UNK_TYPE1","",0x1), + 0x80BE78F0:("sTextIds","s16","",0x1), 0x80BE7900:("D_80BE7900","UNK_TYPE1","",0x1), - 0x80BE792C:("sAnimations","UNK_TYPE1","",0x1), + 0x80BE792C:("sAnimations","AnimationHeader*","",0x1), 0x80BE7958:("D_80BE7958","UNK_TYPE1","",0x1), 0x80BE7970:("D_80BE7970","f32","",0x4), 0x80BE7974:("D_80BE7974","f32","",0x4), @@ -16396,14 +16127,14 @@ 0x80BE8E4C:("D_80BE8E4C","UNK_TYPE1","",0x1), 0x80BE8E58:("D_80BE8E58","UNK_TYPE1","",0x1), 0x80BE9430:("En_Heishi_InitVars","UNK_TYPE1","",0x1), - 0x80BE9450:("D_80BE9450","UNK_TYPE1","",0x1), - 0x80BE947C:("D_80BE947C","UNK_TYPE1","",0x1), - 0x80BE9490:("D_80BE9490","UNK_TYPE1","",0x1), + 0x80BE9450:("sCylinderInit","UNK_TYPE1","",0x1), + 0x80BE947C:("sAnimations","UNK_TYPE1","",0x1), + 0x80BE9490:("sAnimModes","UNK_TYPE1","",0x1), 0x80BE9A30:("En_Demo_heishi_InitVars","UNK_TYPE1","",0x1), - 0x80BE9A50:("D_80BE9A50","UNK_TYPE1","",0x1), - 0x80BE9A7C:("D_80BE9A7C","UNK_TYPE1","",0x1), - 0x80BE9A80:("D_80BE9A80","UNK_TYPE1","",0x1), - 0x80BE9A94:("D_80BE9A94","UNK_TYPE1","",0x1), + 0x80BE9A50:("sCylinderInit","UNK_TYPE1","",0x1), + 0x80BE9A7C:("sTextIds","UNK_TYPE1","",0x1), + 0x80BE9A80:("sAnimations","UNK_TYPE1","",0x1), + 0x80BE9A94:("sAnimModes","UNK_TYPE1","",0x1), 0x80BEB1B0:("En_Dt_InitVars","UNK_TYPE1","",0x1), 0x80BEB1D0:("D_80BEB1D0","UNK_TYPE1","",0x1), 0x80BEB208:("D_80BEB208","UNK_TYPE1","",0x1), @@ -16498,7 +16229,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), @@ -16645,13 +16376,13 @@ 0x80C0482C:("D_80C0482C","UNK_TYPE1","",0x1), 0x80C04838:("D_80C04838","UNK_TYPE1","",0x1), 0x80C05880:("En_Bombers2_InitVars","UNK_TYPE1","",0x1), - 0x80C058A0:("D_80C058A0","UNK_TYPE1","",0x1), - 0x80C058B0:("D_80C058B0","UNK_TYPE1","",0x1), - 0x80C058DC:("D_80C058DC","UNK_TYPE1","",0x1), - 0x80C058F8:("D_80C058F8","UNK_TYPE1","",0x1), - 0x80C05900:("D_80C05900","UNK_TYPE1","",0x1), - 0x80C05910:("D_80C05910","UNK_PTR","",0x4), - 0x80C05914:("D_80C05914","UNK_TYPE1","",0x1), + 0x80C058A0:("sTextIds","u16","",0x1), + 0x80C058B0:("sCylinderInit","UNK_TYPE1","",0x1), + 0x80C058DC:("sAnimations","AnimationHeader*","",0x1), + 0x80C058F8:("sAnimModes","u8","",0x1), + 0x80C05900:("sSetPrimColorDL","UNK_TYPE1","",0x1), + 0x80C05910:("sSetPrimColorDlPtr","Gfx*","",0x4), + 0x80C05914:("sEyeTextures","void*","",0x1), 0x80C05920:("D_80C05920","UNK_TYPE4","",0x4), 0x80C05930:("jtbl_80C05930","UNK_PTR","",0x4), 0x80C06440:("En_Bombal_InitVars","UNK_TYPE1","",0x1), 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/m2ctx.py b/tools/m2ctx.py index a095c2811..0824899f1 100755 --- a/tools/m2ctx.py +++ b/tools/m2ctx.py @@ -7,6 +7,46 @@ script_dir = os.path.dirname(os.path.realpath(__file__)) root_dir = script_dir + "/../" src_dir = root_dir + "src/" +# Read through the processes context and replace whatever +def custom_replacements(output): + output = output.splitlines() + + i = 0 + while i < len(output): + line = output[i] + + ############### actorLists[2].first -> Player* ############### + if "typedef struct ActorListEntry " in line: + actorListText = "" + i += 1 + while not output[i].startswith("}"): + actorListText += output[i] + i += 1 + actorCats = [ + "actorSwitch", + "bg", + "player", + "explosive", + "npc", + "enemy", + "prop", + "itemAction", + "misc", + "boss", + "door", + "chest", + ] + actorList = [] + for x in range(12): + actorList.append(actorListText.replace("first;", f"{actorCats[x]};") + "\n") + if x == 2: + actorList[x] = actorList[x].replace("Actor*", "struct Player*") + elif "ActorListEntry actorLists[ACTORCAT_MAX];" in line: + output[i] = "struct {\n" + "".join(actorList) + "};" + ######################################################## + + i += 1 + return "\n".join(output) def get_c_dir(dirname): for root, dirs, files in os.walk(src_dir): @@ -42,6 +82,8 @@ def main(): description="Creates a ctx.c file for mips2c. " "Output will be saved as oot/ctx.c") parser.add_argument('filepath', help="path of c file to be processed") + parser.add_argument("--custom", "-c", dest="custom", action="store_true", default=False, + help="Apply custom replacements to the output to help aid m2c output") args = parser.parse_args() if args.filepath: @@ -59,6 +101,9 @@ def main(): output = import_c_file(c_file_path) + if args.custom: + output = custom_replacements(output) + with open(os.path.join(root_dir, "ctx.c"), "w", encoding="UTF-8") as f: f.write(output) diff --git a/tools/namefixer.py b/tools/namefixer.py new file mode 100755 index 000000000..1d6c89a7b --- /dev/null +++ b/tools/namefixer.py @@ -0,0 +1,767 @@ +#!/usr/bin/env python3 + +import os +import argparse + +# all occurrences of keys will be replaced by associated value +simpleReplace = { + # "Math_Rand_":"Rand_", + # "ACTORTYPE":"ACTORCAT", + # "DistToLink":"DistToPlayer", + # "HitItem":"HitInfo", +} + +# all occurrences of keys will be replaced by associated value, +# if the occurence is the whole word +# for example, if there is a space before and an open parenthesis after, +# like for a function call: ` func_8002E4B4(` +# +# Custom behaviour can be enabled by using a tuple as the value (see +# explanation in replace_single below) +wordReplace = { + "Actor_GetSwitchFlag": "Flags_GetSwitch", + "atan_flip": "Math_Acot2F", + "atans": "Math_Atan2S", + + # "SysMatrix_StateAlloc": "Matrix_StateAlloc", + # "SysMatrix_StatePush": "Matrix_StatePush", + # "SysMatrix_StatePop": "Matrix_StatePop", + # "SysMatrix_GetCurrentState": "Matrix_GetCurrentState", + # "SysMatrix_CopyCurrentState": "Matrix_CopyCurrentState", + # "SysMatrix_SetCurrentState": "Matrix_SetCurrentState", + # "SysMatrix_InsertTranslation": "Matrix_InsertTranslation", + # "SysMatrix_InsertMatrix": "Matrix_InsertMatrix", + # "SysMatrix_Scale": "Matrix_Scale", + # "SysMatrix_InsertXRotation_s": "Matrix_InsertXRotation_s", + # "SysMatrix_InsertXRotation_f": "Matrix_InsertXRotation_f", + # "SysMatrix_RotateStateAroundXAxis": "Matrix_RotateStateAroundXAxis", + # "SysMatrix_SetStateXRotation": "Matrix_SetStateXRotation", + # "SysMatrix_RotateY": "Matrix_RotateY", + # "SysMatrix_InsertYRotation_f": "Matrix_InsertYRotation_f", + # "SysMatrix_InsertZRotation_s": "Matrix_InsertZRotation_s", + # "SysMatrix_InsertZRotation_f": "Matrix_InsertZRotation_f", + # "SysMatrix_InsertRotation": "Matrix_InsertRotation", + # "SysMatrix_JointPosition": "Matrix_JointPosition", + # "SysMatrix_SetStateRotationAndTranslation": "Matrix_SetStateRotationAndTranslation", + # "SysMatrix_ToRSPMatrix": "Matrix_ToRSPMatrix", + # "SysMatrix_ToMtx": "Matrix_ToMtx", + # "SysMatrix_NewMtx": "Matrix_NewMtx", + # "SysMatrix_AppendToPolyOpaDisp": "Matrix_AppendToPolyOpaDisp", + # "SysMatrix_MultiplyVector3fByState": "Matrix_MultiplyVector3fByState", + # "SysMatrix_GetStateTranslation": "Matrix_GetStateTranslation", + # "SysMatrix_GetStateTranslationAndScaledX": "Matrix_GetStateTranslationAndScaledX", + # "SysMatrix_GetStateTranslationAndScaledY": "Matrix_GetStateTranslationAndScaledY", + # "SysMatrix_GetStateTranslationAndScaledZ": "Matrix_GetStateTranslationAndScaledZ", + # "SysMatrix_MultiplyVector3fXZByCurrentState": "Matrix_MultiplyVector3fXZByCurrentState", + # "SysMatrix_MtxFCopy": "Matrix_MtxFCopy", + # "SysMatrix_FromRSPMatrix": "Matrix_FromRSPMatrix", + # "SysMatrix_MultiplyVector3fByMatrix": "Matrix_MultiplyVector3fByMatrix", + # "SysMatrix_TransposeXYZ": "Matrix_TransposeXYZ", + # "SysMatrix_NormalizeXYZ": "Matrix_NormalizeXYZ", + # "SysMatrix_InsertRotationAroundUnitVector_f": "Matrix_InsertRotationAroundUnitVector_f", + # "SysMatrix_InsertRotationAroundUnitVector_s": "Matrix_InsertRotationAroundUnitVector_s", + # "SysMatrix_GetStateAsRSPMatrix": "Matrix_GetStateAsRSPMatrix", + + "Matrix_StateAlloc": "Matrix_Init", + "Matrix_StatePush": "Matrix_Push", + "Matrix_StatePop": "Matrix_Pop", + "Matrix_CopyCurrentState": "Matrix_Get", + "Matrix_SetCurrentState": "Matrix_Put", + "Matrix_GetCurrentState": "Matrix_GetCurrent", + "Matrix_InsertMatrix": "Matrix_Mult", + "Matrix_InsertTranslation": "Matrix_Translate", + "Matrix_InsertXRotation_s": "Matrix_RotateXS", + "Matrix_InsertXRotation_f": "Matrix_RotateXF", + "Matrix_RotateStateAroundXAxis": "Matrix_RotateXFApply", + "Matrix_SetStateXRotation": "Matrix_RotateXFNew", + # "Matrix_RotateY": "Matrix_RotateYS", + "Matrix_InsertYRotation_f": "Matrix_RotateYF", + "Matrix_InsertZRotation_s": "Matrix_RotateZS", + "Matrix_InsertZRotation_f": "Matrix_RotateZF", + "Matrix_InsertRotation": "Matrix_RotateZYX", + "Matrix_JointPosition": "Matrix_TranslateRotateZYX", + "Matrix_SetStateRotationAndTranslation": "Matrix_SetTranslateRotateYXZ", + "Matrix_ToRSPMatrix": "Matrix_MtxFToMtx", + "Matrix_MultiplyVector3fByState": "Matrix_MultVec3f", + "Matrix_GetStateTranslation": "Matrix_MultZero", + "Matrix_GetStateTranslationAndScaledX": "Matrix_MultVecX", + "Matrix_GetStateTranslationAndScaledY": "Matrix_MultVecY", + "Matrix_GetStateTranslationAndScaledZ": "Matrix_MultVecZ", + "Matrix_MultiplyVector3fXZByCurrentState": "Matrix_MultVec3fXZ", + "Matrix_FromRSPMatrix": "Matrix_MtxToMtxF", + "Matrix_TransposeXYZ": "Matrix_Transpose", + "Matrix_NormalizeXYZ": "Matrix_ReplaceRotation", + "func_8018219C": "Matrix_MtxFToYXZRot", + "func_801822C4": "Matrix_MtxFToZYXRot", + "Matrix_InsertRotationAroundUnitVector_f": "Matrix_RotateAxisF", + "Matrix_InsertRotationAroundUnitVector_s": "Matrix_RotateAxisS", + + "func_800B78B8": "Actor_UpdateBgCheckInfo", + "func_8012403C": "Player_GetMask", + "func_8012404c": "Player_RemoveMask", + "Actor_SpawnWithParentAndCutscene": "Actor_SpawnAsChildAndCutscene", + "Actor_SpawnWithParent": "Actor_SpawnAsChild", + "Actor_IsLinkFacingActor": "Player_IsFacingActor", + "Actor_IsActorFacingLink": "Actor_IsFacingPlayer", + "Actor_IsActorFacingLinkAndWithinRange": "Actor_IsFacingAndNearPlayer", + "Actor_IsActorFacingActorAndWithinRange": "Actor_ActorAIsFacingAndNearActorB", + "Actor_IsActorFacingActor": "Actor_ActorAIsFacingActorB", + "Actor_IsActorFacedByActor": "Actor_ActorBIsFacingActorA", + "func_800B84D0": "Actor_ProcessTalkRequest", + "func_8017D668": "Math3D_PointDistToLine2D", + "func_800BDFC0": "Gfx_DrawDListOpa", + "func_800BE03C": "Gfx_DrawDListXlu", + "func_800B6FC8": "Player_GetHeight", + "Actor_InitCurrPosition": "Actor_SetWorldToHome", + "Actor_SetHeight": "Actor_SetFocus", + "Actor_SetRotationFromDrawRotation": "Actor_SetWorldRotToShape", + "Actor_InitDrawRotation": "Actor_SetShapeRotToWorld", + "Actor_CalcOffsetOrientedToDrawRotation": "Actor_OffsetOfPointInActorCoords", + "Actor_ApplyMovement": "Actor_UpdatePos", + "Actor_SetVelocityYRotationAndGravity": "Actor_UpdateVelocityWithGravity", + "Actor_SetVelocityAndMoveYRotationAndGravity": "Actor_MoveWithGravity", + "Actor_SetVelocityXYRotation": "Actor_UpdateVelocityWithoutGravity", + "Actor_SetVelocityAndMoveXYRotation": "Actor_MoveWithoutGravity", + "Actor_SetVelocityXYRotationReverse": "Actor_UpdateVelocityWithoutGravityReverse", + "Actor_SetVelocityAndMoveXYRotationReverse": "Actor_MoveWithoutGravityReverse", + "func_800B6C04": "Actor_SetSpeeds", + "func_800B81E0": "Actor_GetFocus", + "func_800B8214": "Actor_GetWorld", + "func_800B8248": "Actor_GetWorldPosShapeRot", + "func_800BE22C": "Actor_ApplyDamage", + "Audio_PlaySoundAtPosition": "SoundSource_PlaySfxAtFixedWorldPos", + "func_800F0590": "SoundSource_PlaySfxEachFrameAtFixedWorldPos", + "func_8016970C": "Play_CameraSetAtEye", + "func_800BBA88": "Enemy_StartFinishingBlow", + "ShrinkWindow_Step": "ShrinkWindow_Update", + "ShrinkWindow_Fini": "ShrinkWindow_Destroy", + "func_801A89A8": "Audio_QueueSeqCmd", + "func_8019F1C0": "Audio_PlaySfxAtPos", + "func_801A72CC": "Audio_StopSfxByPos", + "SkelAnime_LodDrawLimb": "SkelAnime_DrawLimbLod", + "SkelAnime_LodDraw": "SkelAnime_DrawLod", + "SkelAnime_LodDrawLimbSV": "SkelAnime_DrawFlexLimbLod", + "SkelAnime_LodDrawSV": "SkelAnime_DrawFlexLod", + # "SkelAnime_DrawLimb": "SkelAnime_DrawLimbOpa", # A different function is called this now + # "SkelAnime_Draw": "SkelAnime_DrawOpa", # A different function is called this now + "SkelAnime_DrawLimbSV": "SkelAnime_DrawFlexLimbOpa", + "SkelAnime_DrawSV": "SkelAnime_DrawFlexOpa", + # "SkelAnime_AnimateFrame": "SkelAnime_GetFrameData", # A different function is called this now + "SkelAnime_GetTotalFrames": "Animation_GetLength", + "SkelAnime_GetFrameCount": "Animation_GetLastFrame", + "SkelAnime_Draw2Limb": "SkelAnime_DrawLimb", + "SkelAnime_Draw2": "SkelAnime_Draw", + "SkelAnime_DrawLimbSV2": "SkelAnime_DrawFlexLimb", + "SkelAnime_DrawSV2": "SkelAnime_DrawFlex", + "func_80134FFC": "SkelAnime_GetFrameData2", + "func_801353D4": "Animation_GetLimbCount2", + "SkelAnime_GetTotalFrames2": "Animation_GetLength2", + "SkelAnime_GetFrameCount2": "Animation_GetLastFrame2", + "SkelAnime_InterpolateVec3s": "SkelAnime_InterpFrameTable", + "SkelAnime_AnimationCtxReset": "AnimationContext_Reset", + "func_801358D4": "AnimationContext_SetNextQueue", + "func_801358F4": "AnimationContext_DisableQueue", + "SkelAnime_NextEntry": "AnimationContext_AddEntry", + "SkelAnime_LoadLinkAnimetion": "AnimationContext_SetLoadFrame", + "SkelAnime_LoadAnimationType1": "AnimationContext_SetCopyAll", + "SkelAnime_LoadAnimationType2": "AnimationContext_SetInterp", + "SkelAnime_LoadAnimationType3": "AnimationContext_SetCopyTrue", + "SkelAnime_LoadAnimationType4": "AnimationContext_SetCopyFalse", + "SkelAnime_LoadAnimationType5": "AnimationContext_SetMoveActor", + "SkelAnime_LinkAnimetionLoaded": "AnimationContext_LoadFrame", + "SkelAnime_AnimationType1Loaded": "AnimationContext_CopyAll", + "SkelAnime_AnimationType2Loaded": "AnimationContext_CopyInterp", + "SkelAnime_AnimationType3Loaded": "AnimationContext_CopyTrue", + "SkelAnime_AnimationType4Loaded": "AnimationContext_CopyFalse", + "SkelAnime_AnimationType5Loaded": "AnimationContext_MoveActor", + "func_80135EE8": "AnimationContext_Update", + "SkelAnime_InitLinkAnimetion": "SkelAnime_InitLink", + "func_801360A8": "LinkAnimation_SetUpdateFunction", + "func_801360E0": "LinkAnimation_Update", + "func_80136104": "LinkAnimation_Morph", + "func_801361BC": "LinkAnimation_AnimateFrame", + "func_80136288": "LinkAnimation_Loop", + "func_8013631C": "LinkAnimation_Once", + "SkelAnime_SetTransition": "Animation_SetMorph", + "SkelAnime_ChangeLinkAnim": "LinkAnimation_Change", + "SkelAnime_ChangeLinkAnimDefaultStop": "LinkAnimation_PlayOnce", + "SkelAnime_ChangeLinkAnimPlaybackStop": "LinkAnimation_PlayOnceSetSpeed", + "SkelAnime_ChangeLinkAnimDefaultRepeat": "LinkAnimation_PlayLoop", + "SkelAnime_ChangeLinkAnimPlaybackRepeat": "LinkAnimation_PlayLoopSetSpeed", + "func_8013670C": "LinkAnimation_CopyJointToMorph", + "func_8013673C": "LinkAnimation_CopyMorphToJoint", + "func_8013676C": "LinkAnimation_LoadToMorph", + "func_801367B0": "LinkAnimation_LoadToJoint", + "func_801367F4": "LinkAnimation_InterpJointMorph", + "func_8013682C": "LinkAnimation_BlendToJoint", + "func_801368CC": "LinkAnimation_BlendToMorph", + "SkelAnime_SetModeStop": "LinkAnimation_EndLoop", + "func_80136990": "Animation_OnFrameImpl", + "func_80136A48": "LinkAnimation_OnFrame", + "SkelAnime_InitSV": "SkelAnime_InitFlex", + "func_80136C84": "SkelAnime_SetUpdate", + "SkelAnime_FrameUpdateMatrix": "SkelAnime_Update", + "func_80136CF4": "SkelAnime_Morph", + "func_80136D98": "SkelAnime_MorphTaper", + "func_80136F04": "SkelAnime_AnimateFrame", + "func_8013702C": "SkelAnime_LoopFull", + "func_801370B0": "SkelAnime_LoopPartial", + "func_8013713C": "SkelAnime_Once", + "SkelAnime_ChangeAnimImpl": "Animation_ChangeImpl", + "SkelAnime_ChangeAnim": "Animation_Change", + "SkelAnime_ChangeAnimDefaultStop": "Animation_PlayOnce", + "SkelAnime_ChangeAnimTransitionStop": "Animation_MorphToPlayOnce", + "SkelAnime_ChangeAnimPlaybackStop": "Animation_PlayOnceSetSpeed", + "SkelAnime_ChangeAnimDefaultRepeat": "Animation_PlayLoop", + "SkelAnime_ChangeAnimTransitionRepeat": "Animation_MorphToLoop", + "SkelAnime_ChangeAnimPlaybackRepeat": "Animation_PlayLoopSetSpeed", + "SkelAnime_AnimSetStop": "Animation_EndLoop", + "SkelAnime_AnimReverse": "Animation_Reverse", + "func_80137674": "SkelAnime_CopyFrameTableTrue", + "func_801376DC": "SkelAnime_CopyFrameTableFalse", + "func_80137748": "SkelAnime_UpdateTranslation", + "func_801378B8": "Animation_OnFrame", + "SkelAnime_CopyVec3s": "SkelAnime_CopyFrameTable", + "Actor_SetObjectSegment": "Actor_SetObjectDependency", + "func_800B3FC0": "ActorShadow_DrawCircle", + "func_800B4024": "ActorShadow_DrawSquare", + "func_800B4088": "ActorShadow_DrawWhiteCircle", + "func_800B40B8": "ActorShadow_DrawHorse", + "func_800B40E0": "ActorShadow_DrawFoot", + "func_800B42F8": "ActorShadow_DrawFeet", + "func_800B4A98": "Actor_SetFeetPos", + "Actor_SetSwitchFlag": "Flags_SetSwitch", + "Actor_UnsetSwitchFlag": "Flags_UnsetSwitch", + "Actor_GetChestFlag": "Flags_GetTreasure", + "Actor_SetChestFlag": "Flags_SetTreasure", + "Actor_SetAllChestFlag": "Flags_SetAllTreasure", + "Actor_GetAllChestFlag": "Flags_GetAllTreasure", + "Actor_GetRoomCleared": "Flags_GetClear", + "Actor_SetRoomCleared": "Flags_SetClear", + "Actor_UnsetRoomCleared": "Flags_UnsetClear", + "Actor_GetRoomClearedTemp": "Flags_GetClearTemp", + "Actor_SetRoomClearedTemp": "Flags_SetClearTemp", + "Actor_UnsetRoomClearedTemp": "Flags_UnsetTempClear", + "Actor_GetCollectibleFlag": "Flags_GetCollectible", + "Actor_SetCollectibleFlag": "Flags_SetCollectible", + "func_800B8A1C": "Actor_PickUp", + "func_800B8B84": "Actor_PickUpNearby", + "func_800B8BB0": "Actor_LiftActor", + "func_800B8BD0": "Actor_PickUpFar", + "func_801A5CFC": "Audio_PlaySfxGeneral", + "func_800BBDAC": "Actor_SpawnFloorDustRing", + "func_800B8708": "Player_GetExchangeItemId", + "func_801233E4": "Player_InCsMode", + "func_800BC4EC": "Actor_TestFloorInDirection", + "func_800BC5B8": "Actor_IsTargeted", + "func_800BC5EC": "Actor_OtherIsTargeted", + "func_800BCB70": "Actor_SetColorFilter", + "func_800BE0B8": "Actor_FindNearby", + "func_800BE258": "Actor_SetDropFlag", + "func_800BE2B8": "Actor_SetDropFlagJntSph", + "Actor_TitleCardCreate": "TitleCard_InitBossName", + "func_800B867C": "Actor_TextboxIsClosing", + "func_800BDC5C": "Actor_ChangeAnimationByInfo", + "Actor_ChangeAnimation": "Actor_ChangeAnimationByInfo", + "func_80152498": "Message_GetState", + "func_800B8898": "Actor_GetScreenPos", + "Audio_PlayActorSound2": "Actor_PlaySfxAtPos", + "func_800BF7CC": "Actor_SpawnIceEffects", + "Actor_IsFacingPlayerAndWithinRange": "Actor_IsFacingAndNearPlayer", + "func_800BC8B8": "Actor_DrawDoorLock", + "func_800B86C8": "Actor_ChangeFocus", + "zelda_malloc": "ZeldaArena_Malloc", + "zelda_mallocR": "ZeldaArena_MallocR", + "zelda_realloc": "ZeldaArena_Realloc", + "zelda_free": "ZeldaArena_Free", + "zelda_calloc": "ZeldaArena_Calloc", + "MainHeap_AnalyzeArena": "ZeldaArena_GetSizes", + "MainHeap_Check": "ZeldaArena_Check", + "MainHeap_Init": "ZeldaArena_Init", + "MainHeap_Cleanup": "ZeldaArena_Cleanup", + "MainHeap_IsInitialized": "ZeldaArena_IsInitialized", + "func_80138300": "Skin_GetLimbPos", + "func_8013835C": "Skin_GetVertexPos", + "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", + "BcCheck3_BgActorInit": "DynaPolyActor_Init", + "BgCheck3_LoadMesh": "DynaPolyActor_LoadMesh", + "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_GetConveyorType", + "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_800DFB14": "Camera_ChangeDataIdx", + "func_800DFC68": "Camera_GetInputDirYaw", + "func_800DFCB4": "Camera_GetCamDirPitch", + "func_800DFCDC": "Camera_GetCamDirYaw", + "func_800E0308": "Camera_SetTargetActor", + "func_800E031C": "Camera_GetWaterYPos", + "func_800E02AC": "Camera_SetToTrackActor", + "func_801694DC": "Play_CreateSubCamera", + "Play_GetActiveCameraIndex": "Play_GetActiveCamId", + "func_80169590": "Play_CameraChangeStatus", + "func_80169600": "Play_ClearCamera", + "func_80169668": "Play_ClearAllSubCameras", + "func_8016981C": "Play_CameraSetAtEyeUp", + "func_80169940": "Play_CameraSetFov", + "func_80169988": "Play_CameraSetRoll", + "func_801699D4": "Play_CopyCamera", + "func_80169AC0": "Play_CameraChangeSetting", + "func_80169BC4": "Play_CameraGetUID", + "func_80169C64": "Play_GetCsCamDataSetting", + "func_80169C84": "Play_GetCsCamDataVec3s", + "convert_scene_number_among_shared_scenes": "Play_GetOriginalSceneNumber", + "func_80169D40": "Play_SaveCycleSceneFlags", + "func_80169DCC": "Play_SetRespawnData", + "func_80169E6C": "Play_SetupRespawnPoint", + "func_8016A0AC": "Play_IsUnderwater", + "func_801690CC": "Play_InCsMode", + "func_8017D2FC": "Math3D_LineSegVsPlane", + "func_800A81F0": "EffectBlure_AddVertex", + "func_800A8514": "EffectBlure_AddSpace", + "Effect_GetParams": "Effect_GetByIndex", + "func_800F5A8C": "Environment_LerpWeight", + "func_801A3F54": "Audio_SetCutsceneFlag", + "func_800EA0D4": "Cutscene_Start", + "func_800EA0EC": "Cutscene_End", + "func_800EDE34": "Cutscene_ActorTranslate", + "func_800EDF24": "Cutscene_ActorTranslateAndYaw", + "func_800EDF78": "Cutscene_ActorTranslateAndYawSmooth", + "func_800EE0CC": "Cutscene_ActorTranslateXZAndYawSmooth", + "func_800EE1D8": "Cutscene_GetSceneSetupIndex", + "func_800EE200": "Cutscene_GetActorActionIndex", + "func_800EE29C": "Cutscene_CheckActorAction", + "func_800EE2F4": "Cutscene_IsPlaying", + "func_801343C0": "SkelAnime_DrawTransformFlexOpa", + "func_80134148": "SkelAnime_DrawTransformFlexLimbOpa", + "func_80114E90": "Interface_HasEmptyBottle", + "func_80114F2C": "Interface_HasItemInBottle", + "func_80123C90": "Player_SetEquipmentData", + "Quake2_ClearType": "Distortion_ClearType", + "Quake2_SetType": "Distortion_SetType", + "Quake2_SetCountdown": "Distortion_SetCountdown", + "func_800BE680": "Actor_DrawDamageEffects", + "func_8012F22C": "Inventory_GetSkullTokenCount", + + "func_8013AB00": "SubS_DrawTransformFlex", + "func_8013A860": "SubS_DrawTransformFlexLimb", + "func_8013BC6C": "SubS_ChangeAnimationByInfoS", + "func_8013E1C8": "SubS_ChangeAnimationBySpeedInfo", + "func_8013D9C8": "SubS_FillLimbRotTables", + "func_8013A7C0": "SubS_FindDoor", + "func_8013E640": "SubS_FindActorCustom", + "func_ActorCategoryIterateById": "SubS_FindActor", + "func_8013BB7C": "SubS_FindNearestActor", + "func_8013E2D4": "SubS_StartActorCutscene", + "func_8013E3B8": "SubS_FillCutscenesList", + "func_8013AED4": "SubS_UpdateFlags", + "func_8013D8DC": "SubS_IsObjectLoaded", + "func_8013D924": "SubS_GetObjectIndex", + "func_8013D5E8": "SubS_AngleDiffLessEqual", + "func_8013DCE0": "SubS_ActorPathing_Init", + "func_8013DE04": "SubS_ActorPathing_Update", + "func_8013DF3C": "SubS_ActorPathing_ComputePointInfo", + "func_8013E054": "SubS_ActorPathing_MoveWithGravity", + "func_8013E07C": "SubS_ActorPathing_MoveWithoutGravityReverse", + "func_8013E0A4": "SubS_ActorPathing_SetNextPoint", + "func_8013BB34": "SubS_GetAdditionalPath", + "func_8013BD40": "SubS_HasReachedPoint", + "func_8013BEDC": "SubS_GetDayDependentPath", + "func_8013C8B8": "SubS_CopyPointFromPathCheckBounds", + "func_8013D648": "SubS_GetPathByIndex", + "func_8013D68C": "SubS_CopyPointFromPath", + "func_8013D720": "SubS_GetDistSqAndOrientPoints", + "func_8013D768": "SubS_MoveActorToPoint", + "func_8013D83C": "SubS_GetDistSqAndOrientPath", + "func_8013DB90": "SubS_IsFloorAbove", + "func_8013DC40": "SubS_CopyPointFromPathList", + "func_8013DCCC": "SubS_GetPathCount", + "func_8013AD9C": "SubS_UpdateLimb", + "func_8013D2E0": "SubS_TurnToPoint", + + "func_80147624": "Message_ShouldAdvance", + "func_80147734": "Message_ShouldAdvanceSilent", + "func_80149EBC": "Message_FindMessage", + "func_8014CC14": "Message_LoadChar", + "func_801518B0": "Message_StartTextbox", + "func_801588D0": "Message_FindMessageNES", + "func_80158988": "Message_LoadCharNES", + "func_80158A24": "Message_LoadPluralRupeesNES", + "func_80158C04": "Message_LoadLocalizedRupeesNES", + "func_80158D98": "Message_LoadRupeesNES", + "func_80158FB0": "Message_LoadTimeNES", + "func_8015926C": "Message_LoadAreaTextNES", + "func_8015E750": "Message_FindCreditsMessage", + "func_80133038": "Schedule_RunScript", + + "EffectSsKiraKira_SpawnSmallYellow": "EffectSsKirakira_SpawnSmallYellow", + "EffectSsKiraKira_SpawnSmall": "EffectSsKirakira_SpawnSmall", + "EffectSsKiraKira_SpawnDispersed": "EffectSsKirakira_SpawnDispersed", + "EffectSsKiraKira_SpawnFocused": "EffectSsKirakira_SpawnFocused", + + # Struct members + "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", + + "actor.minVelocityY": "actor.terminalVelocity", + "actor.yDistToWater": "actor.depthInWater", + "actor.yDistToPlayer": "actor.playerHeightRel", + + "gSaveContext.weekEventReg": "gSaveContext.save.weekEventReg", + "gSaveContext.playerForm": "gSaveContext.save.playerForm", + "gSaveContext.day": "gSaveContext.save.day", + "gSaveContext.isNight": "gSaveContext.save.isNight", + "gSaveContext.naviTimer": "gSaveContext.save.playerData.tatlTimer", + "gSaveContext.tatlTimer": "gSaveContext.save.playerData.tatlTimer", + "gSaveContext.rupees": "gSaveContext.save.playerData.rupees", + "gSaveContext.magicAcquired": "gSaveContext.save.playerData.magicAcquired", + "gSaveContext.doubleMagic": "gSaveContext.save.playerData.doubleMagic", + "gSaveContext.doubleDefense": "gSaveContext.save.playerData.doubleDefense", + "gSaveContext.playerName": "gSaveContext.save.playerData.playerName", + "gSaveContext.inventory": "gSaveContext.save.inventory", + "gSaveContext.equippedMask": "gSaveContext.save.equippedMask", + "gSaveContext.entranceIndex": "gSaveContext.save.entranceIndex", + "gSaveContext.time": "gSaveContext.save.time", + "gSaveContext.unk_14": "gSaveContext.save.daySpeed", + "gSaveContext.unk_FE6": "gSaveContext.save.bombersCaughtNum", + "gSaveContext.unk_FE7": "gSaveContext.save.bombersCaughtOrder", + "gSaveContext.linkAge": "gSaveContext.save.linkAge", + "gSaveContext.dekuPlaygroundHighScores": "gSaveContext.save.dekuPlaygroundHighScores", + "gSaveContext.lotteryCodeGuess": "gSaveContext.save.lotteryCodeGuess", + "gSaveContext.permanentSceneFlags": "gSaveContext.save.permanentSceneFlags", + "gSaveContext.bomberCode": "gSaveContext.save.bomberCode", + "gSaveContext.skullTokenCount": "gSaveContext.save.skullTokenCount", + "gSaveContext.cutscene": "gSaveContext.save.cutscene", + "gSaveContext.health": "gSaveContext.save.playerData.health", + "gSaveContext.unk_1016": "gSaveContext.jinxTimer", + "gSaveContext.unk_3F58": "gSaveContext.sunsSongState", + + "player->unk_A87": "player->exchangeItemId", + "player->leftHandActor": "player->heldActor", + "player->unk_384": "player->getItemId", + "player->unk_386": "player->getItemDirection", + "player->unk_388": "player->interactRangeActor", + "player->unk_38C": "player->mountSide", + "player->unk_394": "player->csMode", + "csCtx.npcActions": "csCtx.actorActions", + "csCtx->npcActions": "csCtx->actorActions", + "csCtx.unk_12": "csCtx.currentCsIndex", + "globalCtx->mf_187FC": "globalCtx->billboardMtxF", + "globalCtx->projectionMatrix": "globalCtx->viewProjectionMtxF", + "globalCtx->actorCtx.actorList[": "globalCtx->actorCtx.actorLists[", + "globalCtx->envCtx.unk_8C": "globalCtx->envCtx.lightSettings", + "globalCtx->envCtx.unk_E5": "globalCtx->envCtx.fillScreen", + "globalCtx->envCtx.unk_E6": "globalCtx->envCtx.screenFillColor", + "globalCtx->envCtx.unk_C3": "globalCtx->envCtx.lightSettingOverride", + "globalCtx->envCtx.unk_DC": "globalCtx->envCtx.lightBlend", + + "globalCtx->msgCtx.unk1202A": "globalCtx->msgCtx.ocarinaMode", + "globalCtx->msgCtx.unk1202C": "globalCtx->msgCtx.ocarinaAction", + "globalCtx->msgCtx.unk11F22": "globalCtx->msgCtx.msgMode", + "globalCtx->msgCtx.unk11F04": "globalCtx->msgCtx.currentTextId", + + "D_801D15B0" : "gZeroVec3f", + "D_801D15BC" : "gZeroVec3s", + "D_801D1DE0" : "gIdentityMtx", + "D_801D1E20" : "gIdentityMtxF", + "D_04020658" : "gameplay_keep_Anim_020658", + "D_04022B28" : "gDoorSkel", + "D_04023100" : "gDoorCol", + + # Structs + "ActorAnimationEntry": "AnimationInfo", + "ActorAnimationEntryS": "AnimationInfoS", + "struct_80B8E1A8": "AnimationSpeedInfo", + + # Macros + "CUR_EQUIP_VALUE_VOID": "GET_CUR_EQUIP_VALUE", + "CUR_UPG_VALUE_VOID": "GET_CUR_UPG_VALUE", + "ICHAIN_F32_DIV1000(minVelocityY,": "ICHAIN_F32_DIV1000(terminalVelocity,", + "ICHAIN_F32(minVelocityY,": "ICHAIN_F32(terminalVelocity,", + + # Example of custom behaviour: + # "PLAYER": ("GET_PLAYER(globalCtx)", {"ignore": (-1, '"PLAYER"')}), # ignore "PLAYER" in sSoundBankNames +} + +# [a-zA-Z0-9_] +def is_word_char(c): + return (c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or (c >= '0' and c <= '9') or c == '_' + +def replace_single(file): + with open(file, 'r', encoding = 'utf-8') as infile: + srcdata = infile.read() + + changesCount = 0 + + for old, new in simpleReplace.items(): + # replace `old` with `new` + if old in srcdata: + changesCount += 1 + print(old, "->", new) + srcdata = srcdata.replace(old, new) + + for old, new in wordReplace.items(): + # `new` can be a tuple where the first element is what to replace `old` with, + # and the second element is a dict containing "custom behavior" properties. + if isinstance(new, tuple): + custom_behavior = True + new, custom_behavior_data = new + # The "ignore" data is a tuple where the first element is an offset relative to + # where `old` was found, and the string from that index must differ from the + # tuple's second element for the replacement to be done. + custom_behavior_ignore_data = custom_behavior_data.get("ignore") + custom_behavior_ignore = custom_behavior_ignore_data is not None + if custom_behavior_ignore: + custom_behavior_ignore_offset, custom_behavior_ignore_match = custom_behavior_ignore_data + else: + custom_behavior = False + # replace `old` with `new` if the occurence of `old` is the whole word + oldStartIdx = srcdata.find(old) + if oldStartIdx >= 0: + old_start_as_word = is_word_char(old[0]) + old_end_as_word = is_word_char(old[-1]) + replaceCount = 0 + while oldStartIdx >= 0: + replace = True + if old_start_as_word: + if oldStartIdx == 0: + pass + elif is_word_char(srcdata[oldStartIdx-1]): + replace = False + if old_end_as_word: + oldEndIdx = oldStartIdx + len(old) + if oldEndIdx >= len(srcdata): + pass + elif is_word_char(srcdata[oldEndIdx]): + replace = False + if replace and custom_behavior and custom_behavior_ignore: + if srcdata[oldStartIdx + custom_behavior_ignore_offset:].startswith(custom_behavior_ignore_match): + replace = False + if replace: + srcdata = srcdata[:oldStartIdx] + new + srcdata[oldEndIdx:] + replaceCount += 1 + oldStartIdx = srcdata.find(old, oldStartIdx + len(new)) + if replaceCount > 0: + changesCount += 1 + print(old, "->", new) + + if changesCount > 0: + print('Changed', changesCount, 'entry' if changesCount == 1 else 'entries', 'in', file) + with open(file, 'w', encoding = 'utf-8', newline = '\n') as outfile: + outfile.write(srcdata) + +def replace_all(repo): + for subdir, dirs, files in os.walk(os.path.join(repo,'src')): + for filename in files: + if filename.endswith('.c') or filename.endswith('.h'): + file = os.path.join(subdir,filename) + replace_single(file) + + for subdir, dirs, files in os.walk(os.path.join(repo,'asm')): + for filename in files: + if filename.endswith('.s'): + file = os.path.join(subdir,filename) + replace_single(file) + + for subdir, dirs, files in os.walk(os.path.join(repo,'data')): + for filename in files: + if filename.endswith('.s'): + file = os.path.join(subdir,filename) + replace_single(file) + + for subdir, dirs, files in os.walk(os.path.join(repo,'docs')): + for filename in files: + if filename.endswith('.md'): + file = os.path.join(subdir,filename) + replace_single(file) + + +def dictSanityCheck(): + keys = wordReplace.keys() + values = wordReplace.values() + for k in keys: + if k in values: + print(f"Key '{k}' found in values") + print(f"This would produce unintended renames") + print(f"Fix this by removing said key from the dictionary") + exit(-1) + + keys = simpleReplace.keys() + values = {*wordReplace.values(), *simpleReplace.values()} + for k in keys: + for value in values: + if k in value: + print(f"Key '{k}' found in values") + print(f"This would produce unintended renames") + print(f"Fix this by removing said key from the dictionary") + exit(-1) + +def main(): + parser = argparse.ArgumentParser(description='Apply function renames to a file') + parser.add_argument('file', help="source file to be processed. use . to process the whole repo") + args = parser.parse_args() + + dictSanityCheck() + + if args.file == '.': + replace_all(os.curdir) + else: + replace_single(args.file) + +if __name__ == "__main__": + main() 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/overlayhelpers/scheduledis.py b/tools/overlayhelpers/scheduledis.py new file mode 100755 index 000000000..b441b94c7 --- /dev/null +++ b/tools/overlayhelpers/scheduledis.py @@ -0,0 +1,264 @@ +#!/usr/bin/env python3 +# +# MM Event Script Disassembler +# + +import argparse, os, struct, math +from actor_symbols import resolve_symbol + +cmd_info = [ + ('SCHEDULE_CMD_CHECK_FLAG_S', 0x04, '>BBb', (2, )), + ('SCHEDULE_CMD_CHECK_FLAG_L', 0x05, '>BBh', (2, )), + ('SCHEDULE_CMD_CHECK_TIME_RANGE_S', 0x06, '>BBBBb', (4, )), + ('SCHEDULE_CMD_CHECK_TIME_RANGE_L', 0x07, '>BBBBh', (4, )), + ('SCHEDULE_CMD_RET_VAL_L', 0x03, '>H', ( )), + ('SCHEDULE_CMD_RET_NONE', 0x01, '', ( )), + ('SCHEDULE_CMD_RET_EMPTY', 0x01, '', ( )), + ('SCHEDULE_CMD_NOP', 0x04, '>BBB', ( )), + ('SCHEDULE_CMD_CHECK_MISC_S', 0x03, '>Bb', (1, )), + ('SCHEDULE_CMD_RET_VAL_S', 0x02, '>B', ( )), + ('SCHEDULE_CMD_CHECK_NOT_IN_SCENE_S', 0x04, '>Hb', (1, )), + ('SCHEDULE_CMD_CHECK_NOT_IN_SCENE_L', 0x05, '>Hh', (1, )), + ('SCHEDULE_CMD_CHECK_NOT_IN_DAY_S', 0x04, '>Hb', (1, )), + ('SCHEDULE_CMD_CHECK_NOT_IN_DAY_L', 0x05, '>Hh', (1, )), + ('SCHEDULE_CMD_RET_TIME', 0x06, '>BBBBB', ( )), + ('SCHEDULE_CMD_CHECK_BEFORE_TIME_S', 0x04, '>BBb', (2, )), + ('SCHEDULE_CMD_CHECK_BEFORE_TIME_L', 0x05, '>BBh', (2, )), + ('SCHEDULE_CMD_BRANCH_S', 0x02, '>b', (0, )), + ('SCHEDULE_CMD_BRANCH_L', 0x03, '>h', (0, )), +] + +scene_names = [ + 'SCENE_20SICHITAI2', + 'SCENE_UNSET_1', + 'SCENE_UNSET_2', + 'SCENE_UNSET_3', + 'SCENE_UNSET_4', + 'SCENE_UNSET_5', + 'SCENE_UNSET_6', + 'SCENE_KAKUSIANA', + 'SCENE_SPOT00', + 'SCENE_UNSET_9', + 'SCENE_WITCH_SHOP', + 'SCENE_LAST_BS', + 'SCENE_HAKASHITA', + 'SCENE_AYASHIISHOP', + 'SCENE_UNSET_E', + 'SCENE_UNSET_F', + 'SCENE_OMOYA', + 'SCENE_BOWLING', + 'SCENE_SONCHONOIE', + 'SCENE_IKANA', + 'SCENE_KAIZOKU', + 'SCENE_MILK_BAR', + 'SCENE_INISIE_N', + 'SCENE_TAKARAYA', + 'SCENE_INISIE_R', + 'SCENE_OKUJOU', + 'SCENE_OPENINGDAN', + 'SCENE_MITURIN', + 'SCENE_13HUBUKINOMITI', + 'SCENE_CASTLE', + 'SCENE_DEKUTES', + 'SCENE_MITURIN_BS', + 'SCENE_SYATEKI_MIZU', + 'SCENE_HAKUGIN', + 'SCENE_ROMANYMAE', + 'SCENE_PIRATE', + 'SCENE_SYATEKI_MORI', + 'SCENE_SINKAI', + 'SCENE_YOUSEI_IZUMI', + 'SCENE_KINSTA1', + 'SCENE_KINDAN2', + 'SCENE_TENMON_DAI', + 'SCENE_LAST_DEKU', + 'SCENE_22DEKUCITY', + 'SCENE_KAJIYA', + 'SCENE_00KEIKOKU', + 'SCENE_POSTHOUSE', + 'SCENE_LABO', + 'SCENE_DANPEI2TEST', + 'SCENE_UNSET_31', + 'SCENE_16GORON_HOUSE', + 'SCENE_33ZORACITY', + 'SCENE_8ITEMSHOP', + 'SCENE_F01', + 'SCENE_INISIE_BS', + 'SCENE_30GYOSON', + 'SCENE_31MISAKI', + 'SCENE_TAKARAKUJI', + 'SCENE_UNSET_3A', + 'SCENE_TORIDE', + 'SCENE_FISHERMAN', + 'SCENE_GORONSHOP', + 'SCENE_DEKU_KING', + 'SCENE_LAST_GORON', + 'SCENE_24KEMONOMITI', + 'SCENE_F01_B', + 'SCENE_F01C', + 'SCENE_BOTI', + 'SCENE_HAKUGIN_BS', + 'SCENE_20SICHITAI', + 'SCENE_21MITURINMAE', + 'SCENE_LAST_ZORA', + 'SCENE_11GORONNOSATO2', + 'SCENE_SEA', + 'SCENE_35TAKI', + 'SCENE_REDEAD', + 'SCENE_BANDROOM', + 'SCENE_11GORONNOSATO', + 'SCENE_GORON_HAKA', + 'SCENE_SECOM', + 'SCENE_10YUKIYAMANOMURA', + 'SCENE_TOUGITES', + 'SCENE_DANPEI', + 'SCENE_IKANAMAE', + 'SCENE_DOUJOU', + 'SCENE_MUSICHOUSE', + 'SCENE_IKNINSIDE', + 'SCENE_MAP_SHOP', + 'SCENE_F40', + 'SCENE_F41', + 'SCENE_10YUKIYAMANOMURA2', + 'SCENE_14YUKIDAMANOMITI', + 'SCENE_12HAKUGINMAE', + 'SCENE_17SETUGEN', + 'SCENE_17SETUGEN2', + 'SCENE_SEA_BS', + 'SCENE_RANDOM', + 'SCENE_YADOYA', + 'SCENE_KONPEKI_ENT', + 'SCENE_INSIDETOWER', + 'SCENE_26SARUNOMORI', + 'SCENE_LOST_WOODS', + 'SCENE_LAST_LINK', + 'SCENE_SOUGEN', + 'SCENE_BOMYA', + 'SCENE_KYOJINNOMA', + 'SCENE_KOEPONARACE', + 'SCENE_GORONRACE', + 'SCENE_TOWN', + 'SCENE_ICHIBA', + 'SCENE_BACKTOWN', + 'SCENE_CLOCKTOWER', + 'SCENE_ALLEY' +] + +def read_bytes(data_file, offset, len): + data_file.seek(offset) + return bytearray(data_file.read(len)) + +def calc_length(data_file, offset): + off = 0 + cmd = None + branch_targets = [] + + # Parse script, just keeping track of branches, until we find the end + while any([branch >= off for branch in branch_targets]) or cmd not in [0x04, 0x05, 0x06, 0x09]: + cmd = read_bytes(data_file, offset + off, 1)[0] + + cmd_len = cmd_info[cmd][1] + cmd_args = cmd_info[cmd][2] + + if len(cmd_args) > 1: + arg_values = struct.unpack(cmd_args, read_bytes(data_file, offset + off + 1, cmd_len - 1)) + for i in cmd_info[cmd][3]: + branch_targets.append(off + arg_values[i] + cmd_len) + + off += cmd_len + + return off + +def disassemble_unk_script(data_file, offset): + off = 0 + cmd = None + branch_targets = [] + script_len = calc_length(data_file, offset); + script_len_num_digits = 0 if script_len == 1 else int(math.ceil(math.log(script_len - 1, 16))) + + out = "static u8 sScheduleScript[] = {\n" + + # Keep trying to disassemble until it hits a terminator and no commands branch past it + while any([branch >= off for branch in branch_targets]) or cmd not in [0x04, 0x05, 0x06, 0x09]: + cmd = read_bytes(data_file, offset + off, 1)[0] + + cmd_name = cmd_info[cmd][0] + cmd_len = cmd_info[cmd][1] + cmd_args = cmd_info[cmd][2] + + args_formatted = [] + if len(cmd_args) > 1: # handle args + arg_values = struct.unpack(cmd_args, read_bytes(data_file, offset + off + 1, cmd_len - 1)) + for i,(arg_value,arg_type) in enumerate(zip(arg_values, cmd_args[1:]),0): + arg_formatted = "" + if arg_type == "h": + arg_formatted = f"{arg_value:#x}" + elif arg_type == "b": + arg_formatted = f"{arg_value:#x}" + elif arg_type == "H": + if (cmd == 0x0A or cmd == 0x0B) and (arg_value < len(scene_names)): + arg_formatted = scene_names[arg_value] + else: + arg_formatted = f"{arg_value}" + elif arg_type == "B": + if cmd == 0x00 or cmd == 0x01: + arg_formatted = f"0x{arg_value:02X}" + elif cmd == 0x08: + if arg_value == 0: + arg_formatted = "SCHEDULE_CHECK_MISC_ROOM_KEY" + elif arg_value == 1: + arg_formatted = "SCHEDULE_CHECK_MISC_LETTER_TO_KAFEI" + elif arg_value == 2: + arg_formatted = "SCHEDULE_CHECK_MISC_MASK_ROMANI" + else: + arg_formatted = f"0x{arg_value:02X}" + else: + arg_formatted = f"{arg_value:2}" + elif arg_type == "S": + if arg_value < len(scene_names): + arg_formatted = scene_names[arg_value] + else: + arg_formatted = f"0x{arg_value:04X}" + + if i in cmd_info[cmd][3]: # skip argument indices + # add skip args to branch targets, and change the output to absolute differences rather than relative offsets + arg_value += cmd_len + branch_targets.append(off + arg_value) + if arg_value == cmd_len: + arg_formatted == "0" + else: + arg_formatted = f"0x{off + arg_value:0{script_len_num_digits}X} - 0x{off + cmd_len:0{script_len_num_digits}X}" + args_formatted.append(arg_formatted) + + args = ", ".join(args_formatted) if len(args_formatted) != 0 else "" + + out += f" /* 0x{off:0{script_len_num_digits}X} */ {cmd_name}({args}),\n" + + off += cmd_len + + out = out.strip() + out += "\n};" + + print(out) + +def hex_parse(s): + return int(s, 16) + +def main(): + parser = argparse.ArgumentParser(description="Disassembles MM event scripts") + parser.add_argument('address', help="VRAM or ROM address to disassemble at", type=hex_parse) + args = parser.parse_args() + + file_result = resolve_symbol(args.address) + + if file_result[0] is None: + print("Invalid address") + return + + print(hex(file_result[1]), "in", file_result[0].split(os.sep)[-1]) + + with open(file_result[0],"rb") as data_file: + disassemble_unk_script(data_file, file_result[1]) + +if __name__ == "__main__": + main() diff --git a/tools/permuter_settings.toml b/tools/permuter_settings.toml index f5805056b..2676d13ee 100644 --- a/tools/permuter_settings.toml +++ b/tools/permuter_settings.toml @@ -13,6 +13,8 @@ SQ = "int" CLAMP = "int" CLOCK_TIME = "int" CURRENT_DAY = "int" +CHECK_NEWF = "int" +NULL = "int" [decompme.compilers] "tools/ido_recomp/linux/7.1/cc" = "ido7.1" 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/reloc_spec_check.sh b/tools/reloc_spec_check.sh new file mode 100755 index 000000000..434a49ec3 --- /dev/null +++ b/tools/reloc_spec_check.sh @@ -0,0 +1,112 @@ +#!/bin/bash + +# This script checks for overlay's relocs to be correctly used on the spec file depending on the overlay's NON_MATCHING/NON_EQUIVALENT +# and minimize possible broken NON_MATCHING builds. +# The script performs the following checks: +# - The extracted reloc isn't being used on the spec if the overlay has no other GLOBAL_ASM left (it has been matched). +# - Warn if an overlay is using both NON_MATCHING and NON_EQUIVALENT. +# - Warn if an overlay has NON_MATCHING ifdefs but some functions are still unattempted. +# - Both relocs (generated and extracted) are used on the spec on NON_MATCHING overlays. +# - The generated reloc isn't being used on NON_EQUIVALENT overlays. +# If any of those checks fails for any overlay, the script will print a warning and exit with a non-zero exit code. + +BOLD="$(tput bold)" +RED="$(tput setaf 1)" +PURPLE="$(tput setaf 5)" +WHITE="$(tput setaf 7)" +BLINK="$(tput blink)" +RST="$(tput sgr0)" + +# Run the script from the root of the project +DIR="$(dirname "$(readlink -f "$0")")" +cd "$DIR/.." + +EXIT_CODE=0 + +OVERLAYS_SUBFOLDERS="$(find src/overlays/*/* -type d)" + +while read OVL_FOLDER; do + # C files which are part of the current overlay + FILES_OF_OVERLAY="$(find "$OVL_FOLDER" -name '*.c')" + # List of files (of the current overlay) which doesn't contain GLOBAL_ASM + FILES_WITHOUT_PRAGMA="$(grep -L '#pragma GLOBAL_ASM' ${FILES_OF_OVERLAY})" + + if [ "$FILES_OF_OVERLAY" == "$FILES_WITHOUT_PRAGMA" ]; then + # This overlay is fully matched, so it should not be using the extracted reloc (use the generated one instead) + + OVL_NAME="$(cut -d '/' -f 4 <<< ${OVL_FOLDER})" + + # Parse the spec, searching for the extracted reloc of this overlay + OVL_WITH_EXTRACTED_RELOC="$(grep -F "$OVL_NAME".reloc spec)" + + if [ "$OVL_WITH_EXTRACTED_RELOC" != "" ]; then + echo "${BOLD} Matching overlay using extracted reloc on spec found: ${RED} ${OVL_FOLDER} ${RST}" + echo " Don't forget to change the extracted reloc to the generated one on the spec, otherwise the matched overlay won't be shiftable" + EXIT_CODE=1 + fi + else + # Overlay not fully matched + + # Search for files with NON_MATCHING and NON_EQUIVALENT + FILES_WITH_NON_MATCHING="$(grep -Fl '#ifdef NON_MATCHING' ${FILES_OF_OVERLAY})" + FILES_WITH_NON_EQUIVALENT="$(grep -Fl '#ifdef NON_EQUIVALENT' ${FILES_OF_OVERLAY})" + + if [ "$FILES_WITH_NON_MATCHING" != "" ] && [ "$FILES_WITH_NON_EQUIVALENT" != "" ]; then + # An overlay can't have both NON_MATCHINGs and NON_EQUIVALENTs, because relocs wouldn't be generated correctly + + echo "${BOLD} Overlay with both NON_MATCHINGs and NON_EQUIVALENTs found: ${RED} ${OVL_FOLDER} ${RST}" + echo " Overlays can't have both NON_MATCHING and NON_EQUIVALENT because it breaks NON_MATCHING builds" + echo " As an alternative you could mark NON_MATCHING functions as NON_EQUIVALENT and add a comment mentioning it is actually equivalent" + EXIT_CODE=1 + + elif [ "$FILES_WITH_NON_MATCHING" != "" ]; then + # Overlay only contains NON_MATCHINGs + + # Get the count of NON_MATCHING and GLOBAL_ASM of the current overlay + NON_MATCHINGS_COUNT_OF_OVERLAY="$(grep -F '#ifdef NON_MATCHING' ${FILES_WITH_NON_MATCHING} | wc -l)" + PRAGMAS_COUNT_OF_OVERLAY="$(grep -F '#pragma GLOBAL_ASM' ${FILES_WITH_NON_MATCHING} | wc -l)" + + if [ "$NON_MATCHINGS_COUNT_OF_OVERLAY" != "$PRAGMAS_COUNT_OF_OVERLAY" ]; then + # If an overlay uses NON_MATCHING, then every function should be either matching or marked as NON_MATCHING + + echo "${BOLD} Found an overlay with a differing number of NON_MATCHINGs and #pragma GLOBAL_ASM: ${RED} ${OVL_FOLDER} ${RST}" + echo " To use a NON_MATCHING check on an overlay, every function that does not match should verified to be equivalent" + echo " But the amount of NON_MATCHING ifdefs and GLOBAL_ASM does no match, which may suggest not every function of this overlay may have been attempted" + EXIT_CODE=1 + fi + + OVL_NAME="$(cut -d '/' -f 4 <<< ${OVL_FOLDER})" + + # Parse the spec, searching for the extracted reloc of this overlay + OVL_WITH_EXTRACTED_RELOC="$(grep -F "$OVL_NAME".reloc spec)" + + # Parse the spec, searching for the generated reloc of this overlay + OVL_WITH_GENERATED_RELOC="$(grep -F "$OVL_NAME"_reloc spec)" + + if [ "$OVL_WITH_EXTRACTED_RELOC" == "" ] || [ "$OVL_WITH_GENERATED_RELOC" == "" ]; then + # Overlays with NON_MATCHINGs should have both relocs on the spec + + echo "${BOLD} NON_MATCHING overlay missing either extracted or generated reloc on spec found: ${RED} ${OVL_FOLDER} ${RST}" + echo " Overlays with NON_MATCHING ifdefs must also add a NON_MATCHING ifdef on the spec to allow using the generated reloc on NON_MATCHING builds" + EXIT_CODE=1 + fi + elif [ "$FILES_WITH_NON_EQUIVALENT" != "" ]; then + # Overlay only contains NON_EQUIVALENTs + + OVL_NAME="$(cut -d '/' -f 4 <<< ${OVL_FOLDER})" + + # Parse the spec, searching for the generated reloc of this overlay + OVL_WITH_GENERATED_RELOC="$(grep -F "$OVL_NAME"_reloc spec)" + + if [ "$OVL_WITH_GENERATED_RELOC" != "" ]; then + # Overlays with NON_EQUIVALENTs should not use a generated reloc + + echo "${BOLD} NON_EQUIVALENT overlay with generated reloc on spec found: ${RED} ${OVL_FOLDER} ${RST}" + echo " Overlays with NON_EQUIVALENT ifdefs can't use generated relocs" + EXIT_CODE=1 + fi + fi + fi +done <<< ${OVERLAYS_SUBFOLDERS} + +exit $EXIT_CODE 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/boot_functions.csv b/tools/sizes/boot_functions.csv index 9d9b2d8b0..a86be3b83 100644 --- a/tools/sizes/boot_functions.csv +++ b/tools/sizes/boot_functions.csv @@ -9,8 +9,8 @@ asm/non_matchings/boot/idle/Idle_InitVideo.s,Idle_InitVideo,0x8008038C,0x62 asm/non_matchings/boot/idle/Idle_ThreadEntry.s,Idle_ThreadEntry,0x80080514,0x33 asm/non_matchings/boot/viconfig/ViConfig_UpdateVi.s,ViConfig_UpdateVi,0x800805E0,0x5A asm/non_matchings/boot/viconfig/ViConfig_UpdateBlack.s,ViConfig_UpdateBlack,0x80080748,0x12 -asm/non_matchings/boot/z_std_dma/DmaMgr_DMARomToRam.s,DmaMgr_DMARomToRam,0x80080790,0x51 -asm/non_matchings/boot/z_std_dma/DmaMgr_DmaCallback0.s,DmaMgr_DmaCallback0,0x800808D4,0x8 +asm/non_matchings/boot/z_std_dma/DmaMgr_DmaRomToRam.s,DmaMgr_DmaRomToRam,0x80080790,0x51 +asm/non_matchings/boot/z_std_dma/DmaMgr_DmaHandler.s,DmaMgr_DmaHandler,0x800808D4,0x8 asm/non_matchings/boot/z_std_dma/DmaMgr_FindDmaEntry.s,DmaMgr_FindDmaEntry,0x800808F4,0x17 asm/non_matchings/boot/z_std_dma/DmaMgr_TranslateVromToRom.s,DmaMgr_TranslateVromToRom,0x80080950,0x1B asm/non_matchings/boot/z_std_dma/DmaMgr_FindDmaIndex.s,DmaMgr_FindDmaIndex,0x800809BC,0xE @@ -155,14 +155,14 @@ asm/non_matchings/boot/mtxuty-cvt/MtxConv_L2F.s,MtxConv_L2F,0x80086258,0xA asm/non_matchings/boot/assert/__assert.s,__assert,0x80086280,0xD asm/non_matchings/boot/assert/func_800862B4.s,func_800862B4,0x800862B4,0xB asm/non_matchings/boot/boot_800862E0/SystemArena_MallocMin1.s,SystemArena_MallocMin1,0x800862E0,0xC -asm/non_matchings/boot/boot_800862E0/SystemArena_FreeNull.s,SystemArena_FreeNull,0x80086310,0xB -asm/non_matchings/boot/boot_800862E0/func_8008633C.s,func_8008633C,0x8008633C,0x1C -asm/non_matchings/boot/boot_800862E0/func_800863AC.s,func_800863AC,0x800863AC,0x1C -asm/non_matchings/boot/boot_800862E0/func_8008641C.s,func_8008641C,0x8008641C,0x34 -asm/non_matchings/boot/boot_800862E0/func_800864EC.s,func_800864EC,0x800864EC,0x27 -asm/non_matchings/boot/boot_800862E0/func_80086588.s,func_80086588,0x80086588,0x1C +asm/non_matchings/boot/boot_800862E0/SystemArena_FreeNullCheck.s,SystemArena_FreeNullCheck,0x80086310,0xB +asm/non_matchings/boot/boot_800862E0/SystemArena_RunBlockFunc.s,SystemArena_RunBlockFunc,0x8008633C,0x1C +asm/non_matchings/boot/boot_800862E0/SystemArena_RunBlockFunc1.s,SystemArena_RunBlockFunc1,0x800863AC,0x1C +asm/non_matchings/boot/boot_800862E0/SystemArena_RunBlockFunc8.s,SystemArena_RunBlockFunc8,0x8008641C,0x34 +asm/non_matchings/boot/boot_800862E0/SystemArena_RunBlockFunc1Reverse.s,SystemArena_RunBlockFunc1Reverse,0x800864EC,0x27 +asm/non_matchings/boot/boot_800862E0/SystemArena_RunInits.s,SystemArena_RunInits,0x80086588,0x1C asm/non_matchings/boot/boot_800862E0/SystemArena_Init.s,SystemArena_Init,0x800865F8,0xA -asm/non_matchings/boot/padsetup/func_80086620.s,func_80086620,0x80086620,0x50 +asm/non_matchings/boot/padsetup/PadSetup_Init.s,PadSetup_Init,0x80086620,0x50 asm/non_matchings/boot/boot_80086760/func_80086760.s,func_80086760,0x80086760,0xD asm/non_matchings/boot/boot_80086760/func_80086794.s,func_80086794,0x80086794,0x8 asm/non_matchings/boot/boot_80086760/func_800867B4.s,func_800867B4,0x800867B4,0x8 @@ -201,7 +201,7 @@ asm/non_matchings/boot/system_malloc/SystemArena_MallocR.s,SystemArena_MallocR,0 asm/non_matchings/boot/system_malloc/SystemArena_Realloc.s,SystemArena_Realloc,0x80086E20,0xC asm/non_matchings/boot/system_malloc/SystemArena_Free.s,SystemArena_Free,0x80086E50,0xA asm/non_matchings/boot/system_malloc/SystemArena_Calloc.s,SystemArena_Calloc,0x80086E78,0x15 -asm/non_matchings/boot/system_malloc/SystemArena_AnalyzeArena.s,SystemArena_AnalyzeArena,0x80086ECC,0xE +asm/non_matchings/boot/system_malloc/SystemArena_GetSizes.s,SystemArena_GetSizes,0x80086ECC,0xE asm/non_matchings/boot/system_malloc/SystemArena_CheckArena.s,SystemArena_CheckArena,0x80086F04,0x9 asm/non_matchings/boot/system_malloc/SystemArena_InitArena.s,SystemArena_InitArena,0x80086F28,0xC asm/non_matchings/boot/system_malloc/SystemArena_Cleanup.s,SystemArena_Cleanup,0x80086F58,0x9 @@ -219,14 +219,14 @@ asm/non_matchings/boot/__osMalloc/ArenaImpl_Lock.s,ArenaImpl_Lock,0x8008718C,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_Unlock.s,ArenaImpl_Unlock,0x800871B4,0xA asm/non_matchings/boot/__osMalloc/ArenaImpl_GetLastBlock.s,ArenaImpl_GetLastBlock,0x800871DC,0xC asm/non_matchings/boot/__osMalloc/__osMallocInit.s,__osMallocInit,0x8008720C,0x14 -asm/non_matchings/boot/__osMalloc/__osMallocAddBlock.s,__osMallocAddBlock,0x8008725C,0x28 +asm/non_matchings/boot/__osMalloc/__osMallocAddHeap.s,__osMallocAddHeap,0x8008725C,0x28 asm/non_matchings/boot/__osMalloc/__osMallocCleanup.s,__osMallocCleanup,0x800872FC,0x8 asm/non_matchings/boot/__osMalloc/__osMallocIsInitalized.s,__osMallocIsInitalized,0x8008731C,0x2 asm/non_matchings/boot/__osMalloc/__osMalloc.s,__osMalloc,0x80087324,0x39 asm/non_matchings/boot/__osMalloc/__osMallocR.s,__osMallocR,0x80087408,0x39 asm/non_matchings/boot/__osMalloc/__osFree.s,__osFree,0x800874EC,0x3E asm/non_matchings/boot/__osMalloc/__osRealloc.s,__osRealloc,0x800875E4,0x4C -asm/non_matchings/boot/__osMalloc/__osAnalyzeArena.s,__osAnalyzeArena,0x80087714,0x2C +asm/non_matchings/boot/__osMalloc/__osGetSizes.s,__osGetSizes,0x80087714,0x2C asm/non_matchings/boot/__osMalloc/__osCheckArena.s,__osCheckArena,0x800877C4,0x1B asm/non_matchings/boot/sprintf/proutSprintf.s,proutSprintf,0x80087830,0x9 asm/non_matchings/boot/sprintf/vsprintf.s,vsprintf,0x80087854,0x14 @@ -248,7 +248,7 @@ asm/non_matchings/boot/setintmask/osSetIntMask.s,osSetIntMask,0x80088010,0x28 asm/non_matchings/boot/getintmask/osGetIntMask.s,osGetIntMask,0x800880B0,0x18 asm/non_matchings/boot/voicesetword/osVoiceSetWord.s,osVoiceSetWord,0x80088110,0x64 asm/non_matchings/boot/guScale/guScale.s,guScale,0x800882A0,0x2C -asm/non_matchings/boot/sinf/__sinf.s,__sinf,0x80088350,0x70 +asm/non_matchings/boot/sinf/sinf.s,sinf,0x80088350,0x70 asm/non_matchings/boot/sins/sins.s,sins,0x80088510,0x1C asm/non_matchings/boot/sptask/_VirtualToPhysicalTask.s,_VirtualToPhysicalTask,0x80088580,0x43 asm/non_matchings/boot/sptask/osSpTaskLoad.s,osSpTaskLoad,0x8008868C,0x5A @@ -277,9 +277,9 @@ asm/non_matchings/boot/thread/__osDequeueThread.s,__osDequeueThread,0x80089430,0 asm/non_matchings/boot/destroythread/osDestroyThread.s,osDestroyThread,0x80089470,0x44 asm/non_matchings/boot/voicecheckresult/__osVoiceCheckResult.s,__osVoiceCheckResult,0x80089580,0x2C asm/non_matchings/boot/bzero/bzero.s,bzero,0x80089630,0x28 -asm/non_matchings/boot/rumblepak/osSetRumble.s,osSetRumble,0x800896D0,0x5A -asm/non_matchings/boot/rumblepak/osSetUpMempakWrite.s,osSetUpMempakWrite,0x80089838,0x43 -asm/non_matchings/boot/rumblepak/osProbeRumblePak.s,osProbeRumblePak,0x80089944,0x57 +asm/non_matchings/boot/rumblepak/__osMotorAccess.s,__osMotorAccess,0x800896D0,0x5A +asm/non_matchings/boot/rumblepak/_MakeMotorData.s,_MakeMotorData,0x80089838,0x43 +asm/non_matchings/boot/rumblepak/osMotorInit.s,osMotorInit,0x80089944,0x57 asm/non_matchings/boot/siacs/__osSiCreateAccessQueue.s,__osSiCreateAccessQueue,0x80089AA0,0x14 asm/non_matchings/boot/siacs/__osSiGetAccess.s,__osSiGetAccess,0x80089AF0,0x11 asm/non_matchings/boot/siacs/__osSiRelAccess.s,__osSiRelAccess,0x80089B34,0xB @@ -407,7 +407,7 @@ asm/non_matchings/boot/interrupt/__osRestoreInt.s,__osRestoreInt,0x80091AD0,0x8 asm/non_matchings/boot/vi/__osViInit.s,__osViInit,0x80091AF0,0x48 asm/non_matchings/boot/viswapcontext/__osViSwapContext.s,__osViSwapContext,0x80091C10,0xC0 asm/non_matchings/boot/pigetcmdq/osPiGetCmdQueue.s,osPiGetCmdQueue,0x80091F10,0xC -asm/non_matchings/boot/cosf/__cosf.s,__cosf,0x80091F40,0x5C +asm/non_matchings/boot/cosf/cosf.s,cosf,0x80091F40,0x5C asm/non_matchings/boot/epiread/osEPiReadIo.s,osEPiReadIo,0x800920B0,0x14 asm/non_matchings/boot/visetspecial/osViSetSpecialFeatures.s,osViSetSpecialFeatures,0x80092100,0x58 asm/non_matchings/boot/coss/coss.s,coss,0x80092260,0xC diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 14919f754..5b7c0d71d 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 @@ -110,10 +110,10 @@ asm/non_matchings/code/z_effect_soft_sprite_old_init/func_800B139C.s,func_800B13 asm/non_matchings/code/z_effect_soft_sprite_old_init/func_800B13D8.s,func_800B13D8,0x800B13D8,0x3F asm/non_matchings/code/z_effect_soft_sprite_old_init/func_800B14D4.s,func_800B14D4,0x800B14D4,0x31 asm/non_matchings/code/z_effect_soft_sprite_old_init/func_800B1598.s,func_800B1598,0x800B1598,0x31 -asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKiraKira_SpawnSmallYellow.s,EffectSsKiraKira_SpawnSmallYellow,0x800B165C,0x17 -asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKiraKira_SpawnSmall.s,EffectSsKiraKira_SpawnSmall,0x800B16B8,0xF -asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKiraKira_SpawnDispersed.s,EffectSsKiraKira_SpawnDispersed,0x800B16F4,0x4F -asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKiraKira_SpawnFocused.s,EffectSsKiraKira_SpawnFocused,0x800B1830,0x36 +asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKirakira_SpawnSmallYellow.s,EffectSsKirakira_SpawnSmallYellow,0x800B165C,0x17 +asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKirakira_SpawnSmall.s,EffectSsKirakira_SpawnSmall,0x800B16B8,0xF +asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKirakira_SpawnDispersed.s,EffectSsKirakira_SpawnDispersed,0x800B16F4,0x4F +asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsKirakira_SpawnFocused.s,EffectSsKirakira_SpawnFocused,0x800B1830,0x36 asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsBomb2_SpawnFade.s,EffectSsBomb2_SpawnFade,0x800B1908,0x1A asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsBomb2_SpawnLayered.s,EffectSsBomb2_SpawnLayered,0x800B1970,0x1C asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsBlast_Spawn.s,EffectSsBlast_Spawn,0x800B19E0,0x24 @@ -168,47 +168,47 @@ asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsIceSmoke_Spawn.s,Ef asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsIceBlock_Spawn.s,EffectSsIceBlock_Spawn,0x800B326C,0x19 asm/non_matchings/code/flg_set/FlagSet_Update.s,FlagSet_Update,0x800B32D0,0xDD asm/non_matchings/code/flg_set/FlagSet_Draw.s,FlagSet_Draw,0x800B3644,0x8F -asm/non_matchings/code/z_DLF/DLF_LoadGameState.s,DLF_LoadGameState,0x800B3880,0x49 -asm/non_matchings/code/z_DLF/DLF_FreeGameState.s,DLF_FreeGameState,0x800B39A4,0x4B +asm/non_matchings/code/z_DLF/Overlay_LoadGameState.s,Overlay_LoadGameState,0x800B3880,0x49 +asm/non_matchings/code/z_DLF/Overlay_FreeGameState.s,Overlay_FreeGameState,0x800B39A4,0x4B asm/non_matchings/code/z_actor/Actor_PrintLists.s,Actor_PrintLists,0x800B3AD0,0x35 asm/non_matchings/code/z_actor/ActorShape_Init.s,ActorShape_Init,0x800B3BA4,0x9 asm/non_matchings/code/z_actor/ActorShadow_Draw.s,ActorShadow_Draw,0x800B3BC8,0xFE -asm/non_matchings/code/z_actor/func_800B3FC0.s,func_800B3FC0,0x800B3FC0,0x19 -asm/non_matchings/code/z_actor/func_800B4024.s,func_800B4024,0x800B4024,0x19 -asm/non_matchings/code/z_actor/func_800B4088.s,func_800B4088,0x800B4088,0xC -asm/non_matchings/code/z_actor/func_800B40B8.s,func_800B40B8,0x800B40B8,0xA -asm/non_matchings/code/z_actor/func_800B40E0.s,func_800B40E0,0x800B40E0,0x86 -asm/non_matchings/code/z_actor/func_800B42F8.s,func_800B42F8,0x800B42F8,0x1E8 -asm/non_matchings/code/z_actor/func_800B4A98.s,func_800B4A98,0x800B4A98,0x15 +asm/non_matchings/code/z_actor/ActorShadow_DrawCircle.s,ActorShadow_DrawCircle,0x800B3FC0,0x19 +asm/non_matchings/code/z_actor/ActorShadow_DrawSquare.s,ActorShadow_DrawSquare,0x800B4024,0x19 +asm/non_matchings/code/z_actor/ActorShadow_DrawWhiteCircle.s,ActorShadow_DrawWhiteCircle,0x800B4088,0xC +asm/non_matchings/code/z_actor/ActorShadow_DrawHorse.s,ActorShadow_DrawHorse,0x800B40B8,0xA +asm/non_matchings/code/z_actor/ActorShadow_DrawFoot.s,ActorShadow_DrawFoot,0x800B40E0,0x86 +asm/non_matchings/code/z_actor/ActorShadow_DrawFeet.s,ActorShadow_DrawFeet,0x800B42F8,0x1E8 +asm/non_matchings/code/z_actor/Actor_SetFeetPos.s,Actor_SetFeetPos,0x800B4A98,0x15 asm/non_matchings/code/z_actor/func_800B4AEC.s,func_800B4AEC,0x800B4AEC,0x19 asm/non_matchings/code/z_actor/func_800B4B50.s,func_800B4B50,0x800B4B50,0xE3 -asm/non_matchings/code/z_actor/func_800B4EDC.s,func_800B4EDC,0x800B4EDC,0x19 -asm/non_matchings/code/z_actor/func_800B4F40.s,func_800B4F40,0x800B4F40,0xE +asm/non_matchings/code/z_actor/Actor_GetProjectedPos.s,Actor_GetProjectedPos,0x800B4EDC,0x19 +asm/non_matchings/code/z_actor/Target_SetPos.s,Target_SetPos,0x800B4F40,0xE asm/non_matchings/code/z_actor/func_800B4F78.s,func_800B4F78,0x800B4F78,0x32 -asm/non_matchings/code/z_actor/func_800B5040.s,func_800B5040,0x800B5040,0x59 +asm/non_matchings/code/z_actor/Target_SetColors.s,Target_SetColors,0x800B5040,0x59 asm/non_matchings/code/z_actor/Actor_TargetContextInit.s,Actor_TargetContextInit,0x800B51A4,0x19 -asm/non_matchings/code/z_actor/func_800B5208.s,func_800B5208,0x800B5208,0x183 +asm/non_matchings/code/z_actor/Actor_DrawZTarget.s,Actor_DrawZTarget,0x800B5208,0x183 asm/non_matchings/code/z_actor/func_800B5814.s,func_800B5814,0x800B5814,0xE7 asm/non_matchings/code/z_actor/Flags_GetSwitch.s,Flags_GetSwitch,0x800B5BB0,0x11 -asm/non_matchings/code/z_actor/Actor_SetSwitchFlag.s,Actor_SetSwitchFlag,0x800B5BF4,0x10 -asm/non_matchings/code/z_actor/Actor_UnsetSwitchFlag.s,Actor_UnsetSwitchFlag,0x800B5C34,0x11 -asm/non_matchings/code/z_actor/Actor_GetChestFlag.s,Actor_GetChestFlag,0x800B5C78,0x6 -asm/non_matchings/code/z_actor/Actor_SetChestFlag.s,Actor_SetChestFlag,0x800B5C90,0x7 -asm/non_matchings/code/z_actor/Actor_SetAllChestFlag.s,Actor_SetAllChestFlag,0x800B5CAC,0x3 -asm/non_matchings/code/z_actor/Actor_GetAllChestFlag.s,Actor_GetAllChestFlag,0x800B5CB8,0x3 -asm/non_matchings/code/z_actor/Actor_GetRoomCleared.s,Actor_GetRoomCleared,0x800B5CC4,0x6 -asm/non_matchings/code/z_actor/Actor_SetRoomCleared.s,Actor_SetRoomCleared,0x800B5CDC,0x7 -asm/non_matchings/code/z_actor/Actor_UnsetRoomCleared.s,Actor_UnsetRoomCleared,0x800B5CF8,0x8 -asm/non_matchings/code/z_actor/Actor_GetRoomClearedTemp.s,Actor_GetRoomClearedTemp,0x800B5D18,0x6 -asm/non_matchings/code/z_actor/Actor_SetRoomClearedTemp.s,Actor_SetRoomClearedTemp,0x800B5D30,0x7 -asm/non_matchings/code/z_actor/Actor_UnsetRoomClearedTemp.s,Actor_UnsetRoomClearedTemp,0x800B5D4C,0x8 -asm/non_matchings/code/z_actor/Actor_GetCollectibleFlag.s,Actor_GetCollectibleFlag,0x800B5D6C,0x11 -asm/non_matchings/code/z_actor/Actor_SetCollectibleFlag.s,Actor_SetCollectibleFlag,0x800B5DB0,0x10 -asm/non_matchings/code/z_actor/Actor_TitleCardContextInit.s,Actor_TitleCardContextInit,0x800B5DF0,0x7 -asm/non_matchings/code/z_actor/Actor_TitleCardCreate.s,Actor_TitleCardCreate,0x800B5E0C,0x11 -asm/non_matchings/code/z_actor/Actor_Nop800B5E50.s,Actor_Nop800B5E50,0x800B5E50,0x6 -asm/non_matchings/code/z_actor/Actor_TitleCardUpdate.s,Actor_TitleCardUpdate,0x800B5E68,0x2F -asm/non_matchings/code/z_actor/Actor_TitleCardDraw.s,Actor_TitleCardDraw,0x800B5F24,0x144 +asm/non_matchings/code/z_actor/Flags_SetSwitch.s,Flags_SetSwitch,0x800B5BF4,0x10 +asm/non_matchings/code/z_actor/Flags_UnsetSwitch.s,Flags_UnsetSwitch,0x800B5C34,0x11 +asm/non_matchings/code/z_actor/Flags_GetTreasure.s,Flags_GetTreasure,0x800B5C78,0x6 +asm/non_matchings/code/z_actor/Flags_SetTreasure.s,Flags_SetTreasure,0x800B5C90,0x7 +asm/non_matchings/code/z_actor/Flags_SetAllTreasure.s,Flags_SetAllTreasure,0x800B5CAC,0x3 +asm/non_matchings/code/z_actor/Flags_GetAllTreasure.s,Flags_GetAllTreasure,0x800B5CB8,0x3 +asm/non_matchings/code/z_actor/Flags_GetClear.s,Flags_GetClear,0x800B5CC4,0x6 +asm/non_matchings/code/z_actor/Flags_SetClear.s,Flags_SetClear,0x800B5CDC,0x7 +asm/non_matchings/code/z_actor/Flags_UnsetClear.s,Flags_UnsetClear,0x800B5CF8,0x8 +asm/non_matchings/code/z_actor/Flags_GetClearTemp.s,Flags_GetClearTemp,0x800B5D18,0x6 +asm/non_matchings/code/z_actor/Flags_SetClearTemp.s,Flags_SetClearTemp,0x800B5D30,0x7 +asm/non_matchings/code/z_actor/Flags_UnsetClearTemp.s,Flags_UnsetClearTemp,0x800B5D4C,0x8 +asm/non_matchings/code/z_actor/Flags_GetCollectible.s,Flags_GetCollectible,0x800B5D6C,0x11 +asm/non_matchings/code/z_actor/Flags_SetCollectible.s,Flags_SetCollectible,0x800B5DB0,0x10 +asm/non_matchings/code/z_actor/TitleCard_ContextInit.s,TitleCard_ContextInit,0x800B5DF0,0x7 +asm/non_matchings/code/z_actor/TitleCard_InitBossName.s,TitleCard_InitBossName,0x800B5E0C,0x11 +asm/non_matchings/code/z_actor/TitleCard_InitPlaceName.s,TitleCard_InitPlaceName,0x800B5E50,0x6 +asm/non_matchings/code/z_actor/TitleCard_Update.s,TitleCard_Update,0x800B5E68,0x2F +asm/non_matchings/code/z_actor/TitleCard_Draw.s,TitleCard_Draw,0x800B5F24,0x144 asm/non_matchings/code/z_actor/func_800B6434.s,func_800B6434,0x800B6434,0xD asm/non_matchings/code/z_actor/func_800B6468.s,func_800B6468,0x800B6468,0x3 asm/non_matchings/code/z_actor/func_800B6474.s,func_800B6474,0x800B6474,0x6 @@ -218,24 +218,24 @@ asm/non_matchings/code/z_actor/func_800B6584.s,func_800B6584,0x800B6584,0x21 asm/non_matchings/code/z_actor/func_800B6608.s,func_800B6608,0x800B6608,0x1E asm/non_matchings/code/z_actor/func_800B6680.s,func_800B6680,0x800B6680,0x23 asm/non_matchings/code/z_actor/Actor_MarkForDeath.s,Actor_MarkForDeath,0x800B670C,0x8 -asm/non_matchings/code/z_actor/Actor_InitCurrPosition.s,Actor_InitCurrPosition,0x800B672C,0xC -asm/non_matchings/code/z_actor/Actor_SetHeight.s,Actor_SetHeight,0x800B675C,0x11 -asm/non_matchings/code/z_actor/Actor_SetRotationFromDrawRotation.s,Actor_SetRotationFromDrawRotation,0x800B67A0,0x8 -asm/non_matchings/code/z_actor/Actor_InitDrawRotation.s,Actor_InitDrawRotation,0x800B67C0,0x8 +asm/non_matchings/code/z_actor/Actor_SetWorldToHome.s,Actor_SetWorldToHome,0x800B672C,0xC +asm/non_matchings/code/z_actor/Actor_SetFocus.s,Actor_SetFocus,0x800B675C,0x11 +asm/non_matchings/code/z_actor/Actor_SetWorldRotToShape.s,Actor_SetWorldRotToShape,0x800B67A0,0x8 +asm/non_matchings/code/z_actor/Actor_SetShapeRotToWorld.s,Actor_SetShapeRotToWorld,0x800B67C0,0x8 asm/non_matchings/code/z_actor/Actor_SetScale.s,Actor_SetScale,0x800B67E0,0x7 -asm/non_matchings/code/z_actor/Actor_SetObjectSegment.s,Actor_SetObjectSegment,0x800B67FC,0xE -asm/non_matchings/code/z_actor/Actor_InitToDefaultValues.s,Actor_InitToDefaultValues,0x800B6834,0x45 -asm/non_matchings/code/z_actor/Actor_FiniActor.s,Actor_FiniActor,0x800B6948,0x10 +asm/non_matchings/code/z_actor/Actor_SetObjectDependency.s,Actor_SetObjectDependency,0x800B67FC,0xE +asm/non_matchings/code/z_actor/Actor_Init.s,Actor_Init,0x800B6834,0x45 +asm/non_matchings/code/z_actor/Actor_Destroy.s,Actor_Destroy,0x800B6948,0x10 asm/non_matchings/code/z_actor/Actor_SetMovementScale.s,Actor_SetMovementScale,0x800B6988,0x9 -asm/non_matchings/code/z_actor/Actor_ApplyMovement.s,Actor_ApplyMovement,0x800B69AC,0x19 -asm/non_matchings/code/z_actor/Actor_SetVelocityYRotationAndGravity.s,Actor_SetVelocityYRotationAndGravity,0x800B6A10,0x1E -asm/non_matchings/code/z_actor/Actor_SetVelocityAndMoveYRotationAndGravity.s,Actor_SetVelocityAndMoveYRotationAndGravity,0x800B6A88,0xB -asm/non_matchings/code/z_actor/Actor_SetVelocityXYRotation.s,Actor_SetVelocityXYRotation,0x800B6AB4,0x1C -asm/non_matchings/code/z_actor/Actor_SetVelocityAndMoveXYRotation.s,Actor_SetVelocityAndMoveXYRotation,0x800B6B24,0xB -asm/non_matchings/code/z_actor/Actor_SetVelocityXYRotationReverse.s,Actor_SetVelocityXYRotationReverse,0x800B6B50,0x22 -asm/non_matchings/code/z_actor/Actor_SetVelocityAndMoveXYRotationReverse.s,Actor_SetVelocityAndMoveXYRotationReverse,0x800B6BD8,0xB -asm/non_matchings/code/z_actor/func_800B6C04.s,func_800B6C04,0x800B6C04,0x15 -asm/non_matchings/code/z_actor/func_800B6C58.s,func_800B6C58,0x800B6C58,0x1F +asm/non_matchings/code/z_actor/Actor_UpdatePos.s,Actor_UpdatePos,0x800B69AC,0x19 +asm/non_matchings/code/z_actor/Actor_UpdateVelocityWithGravity.s,Actor_UpdateVelocityWithGravity,0x800B6A10,0x1E +asm/non_matchings/code/z_actor/Actor_MoveWithGravity.s,Actor_MoveWithGravity,0x800B6A88,0xB +asm/non_matchings/code/z_actor/Actor_UpdateVelocityWithoutGravity.s,Actor_UpdateVelocityWithoutGravity,0x800B6AB4,0x1C +asm/non_matchings/code/z_actor/Actor_MoveWithoutGravity.s,Actor_MoveWithoutGravity,0x800B6B24,0xB +asm/non_matchings/code/z_actor/Actor_UpdateVelocityWithoutGravityReverse.s,Actor_UpdateVelocityWithoutGravityReverse,0x800B6B50,0x22 +asm/non_matchings/code/z_actor/Actor_MoveWithoutGravityReverse.s,Actor_MoveWithoutGravityReverse,0x800B6BD8,0xB +asm/non_matchings/code/z_actor/Actor_SetSpeeds.s,Actor_SetSpeeds,0x800B6C04,0x15 +asm/non_matchings/code/z_actor/Actor_UpdatePosFromSkelAnime.s,Actor_UpdatePosFromSkelAnime,0x800B6C58,0x1F asm/non_matchings/code/z_actor/Actor_YawBetweenActors.s,Actor_YawBetweenActors,0x800B6CD4,0xB asm/non_matchings/code/z_actor/Actor_YawBetweenActorsTop.s,Actor_YawBetweenActorsTop,0x800B6D00,0xB asm/non_matchings/code/z_actor/Actor_YawToPoint.s,Actor_YawToPoint,0x800B6D2C,0x9 @@ -246,76 +246,76 @@ asm/non_matchings/code/z_actor/Actor_DistanceBetweenActors.s,Actor_DistanceBetwe asm/non_matchings/code/z_actor/Actor_DistanceToPoint.s,Actor_DistanceToPoint,0x800B6DF8,0x9 asm/non_matchings/code/z_actor/Actor_XZDistanceBetweenActors.s,Actor_XZDistanceBetweenActors,0x800B6E1C,0xB asm/non_matchings/code/z_actor/Actor_XZDistanceToPoint.s,Actor_XZDistanceToPoint,0x800B6E48,0x9 -asm/non_matchings/code/z_actor/Actor_CalcOffsetOrientedToDrawRotation.s,Actor_CalcOffsetOrientedToDrawRotation,0x800B6E6C,0x28 -asm/non_matchings/code/z_actor/Actor_YDistance.s,Actor_YDistance,0x800B6F0C,0x5 +asm/non_matchings/code/z_actor/Actor_OffsetOfPointInActorCoords.s,Actor_OffsetOfPointInActorCoords,0x800B6E6C,0x28 +asm/non_matchings/code/z_actor/Actor_HeightDiff.s,Actor_HeightDiff,0x800B6F0C,0x5 asm/non_matchings/code/z_actor/func_800B6F20.s,func_800B6F20,0x800B6F20,0x2A -asm/non_matchings/code/z_actor/func_800B6FC8.s,func_800B6FC8,0x800B6FC8,0x32 -asm/non_matchings/code/z_actor/func_800B7090.s,func_800B7090,0x800B7090,0x22 +asm/non_matchings/code/z_actor/Player_GetHeight.s,Player_GetHeight,0x800B6FC8,0x32 +asm/non_matchings/code/z_actor/Player_GetRunSpeedLimit.s,Player_GetRunSpeedLimit,0x800B7090,0x22 asm/non_matchings/code/z_actor/func_800B7118.s,func_800B7118,0x800B7118,0x4 asm/non_matchings/code/z_actor/func_800B7128.s,func_800B7128,0x800B7128,0xD asm/non_matchings/code/z_actor/func_800B715C.s,func_800B715C,0x800B715C,0x5 -asm/non_matchings/code/z_actor/func_800B7170.s,func_800B7170,0x800B7170,0x1B -asm/non_matchings/code/z_actor/func_800B71DC.s,func_800B71DC,0x800B71DC,0x9 +asm/non_matchings/code/z_actor/Actor_SetCameraHorseSetting.s,Actor_SetCameraHorseSetting,0x800B7170,0x1B +asm/non_matchings/code/z_actor/Actor_MountHorse.s,Actor_MountHorse,0x800B71DC,0x9 asm/non_matchings/code/z_actor/func_800B7200.s,func_800B7200,0x800B7200,0xB asm/non_matchings/code/z_actor/func_800B722C.s,func_800B722C,0x800B722C,0x8 asm/non_matchings/code/z_actor/func_800B724C.s,func_800B724C,0x800B724C,0x13 asm/non_matchings/code/z_actor/func_800B7298.s,func_800B7298,0x800B7298,0x12 asm/non_matchings/code/z_actor/func_800B72E0.s,func_800B72E0,0x800B72E0,0x6 asm/non_matchings/code/z_actor/func_800B72F8.s,func_800B72F8,0x800B72F8,0xA -asm/non_matchings/code/z_actor/Actor_IsLinkFacingActor.s,Actor_IsLinkFacingActor,0x800B7320,0x16 -asm/non_matchings/code/z_actor/Actor_IsActorFacedByActor.s,Actor_IsActorFacedByActor,0x800B7378,0x1A -asm/non_matchings/code/z_actor/Actor_IsActorFacingLink.s,Actor_IsActorFacingLink,0x800B73E0,0x13 -asm/non_matchings/code/z_actor/Actor_IsActorFacingActor.s,Actor_IsActorFacingActor,0x800B742C,0x18 -asm/non_matchings/code/z_actor/Actor_IsActorFacingLinkAndWithinRange.s,Actor_IsActorFacingLinkAndWithinRange,0x800B748C,0x20 -asm/non_matchings/code/z_actor/Actor_IsActorFacingActorAndWithinRange.s,Actor_IsActorFacingActorAndWithinRange,0x800B750C,0x25 +asm/non_matchings/code/z_actor/Player_IsFacingActor.s,Player_IsFacingActor,0x800B7320,0x16 +asm/non_matchings/code/z_actor/Actor_ActorBIsFacingActorA.s,Actor_ActorBIsFacingActorA,0x800B7378,0x1A +asm/non_matchings/code/z_actor/Actor_IsFacingPlayer.s,Actor_IsFacingPlayer,0x800B73E0,0x13 +asm/non_matchings/code/z_actor/Actor_ActorAIsFacingActorB.s,Actor_ActorAIsFacingActorB,0x800B742C,0x18 +asm/non_matchings/code/z_actor/Actor_IsFacingAndNearPlayer.s,Actor_IsFacingAndNearPlayer,0x800B748C,0x20 +asm/non_matchings/code/z_actor/Actor_ActorAIsFacingAndNearActorB.s,Actor_ActorAIsFacingAndNearActorB,0x800B750C,0x25 asm/non_matchings/code/z_actor/func_800B75A0.s,func_800B75A0,0x800B75A0,0x1F asm/non_matchings/code/z_actor/func_800B761C.s,func_800B761C,0x800B761C,0x17 asm/non_matchings/code/z_actor/func_800B7678.s,func_800B7678,0x800B7678,0x90 asm/non_matchings/code/z_actor/Actor_UpdateBgCheckInfo.s,Actor_UpdateBgCheckInfo,0x800B78B8,0x153 -asm/non_matchings/code/z_actor/func_800B7E04.s,func_800B7E04,0x800B7E04,0x77 -asm/non_matchings/code/z_actor/func_800B7FE0.s,func_800B7FE0,0x800B7FE0,0xE -asm/non_matchings/code/z_actor/func_800B8018.s,func_800B8018,0x800B8018,0xE +asm/non_matchings/code/z_actor/Hilite_Draw.s,Hilite_Draw,0x800B7E04,0x77 +asm/non_matchings/code/z_actor/Hilite_DrawOpa.s,Hilite_DrawOpa,0x800B7FE0,0xE +asm/non_matchings/code/z_actor/Hilite_DrawXlu.s,Hilite_DrawXlu,0x800B8018,0xE asm/non_matchings/code/z_actor/func_800B8050.s,func_800B8050,0x800B8050,0x32 asm/non_matchings/code/z_actor/func_800B8118.s,func_800B8118,0x800B8118,0x32 -asm/non_matchings/code/z_actor/func_800B81E0.s,func_800B81E0,0x800B81E0,0xD -asm/non_matchings/code/z_actor/func_800B8214.s,func_800B8214,0x800B8214,0xD -asm/non_matchings/code/z_actor/func_800B8248.s,func_800B8248,0x800B8248,0x29 +asm/non_matchings/code/z_actor/Actor_GetFocus.s,Actor_GetFocus,0x800B81E0,0xD +asm/non_matchings/code/z_actor/Actor_GetWorld.s,Actor_GetWorld,0x800B8214,0xD +asm/non_matchings/code/z_actor/Actor_GetWorldPosShapeRot.s,Actor_GetWorldPosShapeRot,0x800B8248,0x29 asm/non_matchings/code/z_actor/func_800B82EC.s,func_800B82EC,0x800B82EC,0x34 asm/non_matchings/code/z_actor/func_800B83BC.s,func_800B83BC,0x800B83BC,0xF asm/non_matchings/code/z_actor/func_800B83F8.s,func_800B83F8,0x800B83F8,0x36 -asm/non_matchings/code/z_actor/func_800B84D0.s,func_800B84D0,0x800B84D0,0xC +asm/non_matchings/code/z_actor/Actor_ProcessTalkRequest.s,Actor_ProcessTalkRequest,0x800B84D0,0xC asm/non_matchings/code/z_actor/func_800B8500.s,func_800B8500,0x800B8500,0x38 asm/non_matchings/code/z_actor/func_800B85E0.s,func_800B85E0,0x800B85E0,0xD asm/non_matchings/code/z_actor/func_800B8614.s,func_800B8614,0x800B8614,0xA asm/non_matchings/code/z_actor/func_800B863C.s,func_800B863C,0x800B863C,0x10 -asm/non_matchings/code/z_actor/func_800B867C.s,func_800B867C,0x800B867C,0x13 -asm/non_matchings/code/z_actor/func_800B86C8.s,func_800B86C8,0x800B86C8,0x10 -asm/non_matchings/code/z_actor/func_800B8708.s,func_800B8708,0x800B8708,0x4 +asm/non_matchings/code/z_actor/Actor_TextboxIsClosing.s,Actor_TextboxIsClosing,0x800B867C,0x13 +asm/non_matchings/code/z_actor/Actor_ChangeFocus.s,Actor_ChangeFocus,0x800B86C8,0x10 +asm/non_matchings/code/z_actor/Player_GetExchangeItemId.s,Player_GetExchangeItemId,0x800B8708,0x4 asm/non_matchings/code/z_actor/func_800B8718.s,func_800B8718,0x800B8718,0xD asm/non_matchings/code/z_actor/func_800B874C.s,func_800B874C,0x800B874C,0x2E asm/non_matchings/code/z_actor/func_800B8804.s,func_800B8804,0x800B8804,0xA asm/non_matchings/code/z_actor/func_800B882C.s,func_800B882C,0x800B882C,0x10 asm/non_matchings/code/z_actor/func_800B886C.s,func_800B886C,0x800B886C,0xB -asm/non_matchings/code/z_actor/func_800B8898.s,func_800B8898,0x800B8898,0x27 +asm/non_matchings/code/z_actor/Actor_GetScreenPos.s,Actor_GetScreenPos,0x800B8898,0x27 asm/non_matchings/code/z_actor/func_800B8934.s,func_800B8934,0x800B8934,0x31 asm/non_matchings/code/z_actor/Actor_HasParent.s,Actor_HasParent,0x800B89F8,0x9 -asm/non_matchings/code/z_actor/func_800B8A1C.s,func_800B8A1C,0x800B8A1C,0x5A -asm/non_matchings/code/z_actor/func_800B8B84.s,func_800B8B84,0x800B8B84,0xB -asm/non_matchings/code/z_actor/func_800B8BB0.s,func_800B8BB0,0x800B8BB0,0x8 -asm/non_matchings/code/z_actor/func_800B8BD0.s,func_800B8BD0,0x800B8BD0,0xB +asm/non_matchings/code/z_actor/Actor_PickUp.s,Actor_PickUp,0x800B8A1C,0x5A +asm/non_matchings/code/z_actor/Actor_PickUpNearby.s,Actor_PickUpNearby,0x800B8B84,0xB +asm/non_matchings/code/z_actor/Actor_LiftActor.s,Actor_LiftActor,0x800B8BB0,0x8 +asm/non_matchings/code/z_actor/Actor_PickUpFar.s,Actor_PickUpFar,0x800B8BD0,0xB asm/non_matchings/code/z_actor/Actor_HasNoParent.s,Actor_HasNoParent,0x800B8BFC,0x9 asm/non_matchings/code/z_actor/func_800B8C20.s,func_800B8C20,0x800B8C20,0xC asm/non_matchings/code/z_actor/func_800B8C50.s,func_800B8C50,0x800B8C50,0xA -asm/non_matchings/code/z_actor/func_800B8C78.s,func_800B8C78,0x800B8C78,0x9 -asm/non_matchings/code/z_actor/func_800B8C9C.s,func_800B8C9C,0x800B8C9C,0x14 -asm/non_matchings/code/z_actor/func_800B8CEC.s,func_800B8CEC,0x800B8CEC,0x9 +asm/non_matchings/code/z_actor/Actor_HasRider.s,Actor_HasRider,0x800B8C78,0x9 +asm/non_matchings/code/z_actor/Actor_SetRideActor.s,Actor_SetRideActor,0x800B8C9C,0x14 +asm/non_matchings/code/z_actor/Actor_HasNoRider.s,Actor_HasNoRider,0x800B8CEC,0x9 asm/non_matchings/code/z_actor/func_800B8D10.s,func_800B8D10,0x800B8D10,0x10 asm/non_matchings/code/z_actor/func_800B8D50.s,func_800B8D50,0x800B8D50,0x12 asm/non_matchings/code/z_actor/func_800B8D98.s,func_800B8D98,0x800B8D98,0xF asm/non_matchings/code/z_actor/func_800B8DD4.s,func_800B8DD4,0x800B8DD4,0x12 asm/non_matchings/code/z_actor/func_800B8E1C.s,func_800B8E1C,0x800B8E1C,0xF asm/non_matchings/code/z_actor/func_800B8E58.s,func_800B8E58,0x800B8E58,0x1C -asm/non_matchings/code/z_actor/Audio_PlayActorSound2.s,Audio_PlayActorSound2,0x800B8EC8,0xB +asm/non_matchings/code/z_actor/Actor_PlaySfxAtPos.s,Actor_PlaySfxAtPos,0x800B8EC8,0xB asm/non_matchings/code/z_actor/func_800B8EF4.s,func_800B8EF4,0x800B8EF4,0x29 asm/non_matchings/code/z_actor/func_800B8F98.s,func_800B8F98,0x800B8F98,0xA asm/non_matchings/code/z_actor/func_800B8FC0.s,func_800B8FC0,0x800B8FC0,0xA @@ -327,11 +327,11 @@ asm/non_matchings/code/z_actor/func_800B9098.s,func_800B9098,0x800B9098,0x5 asm/non_matchings/code/z_actor/func_800B90AC.s,func_800B90AC,0x800B90AC,0x12 asm/non_matchings/code/z_actor/func_800B90F4.s,func_800B90F4,0x800B90F4,0xB asm/non_matchings/code/z_actor/func_800B9120.s,func_800B9120,0x800B9120,0x14 -asm/non_matchings/code/z_actor/Actor_Init.s,Actor_Init,0x800B9170,0x71 -asm/non_matchings/code/z_actor/func_800B9334.s,func_800B9334,0x800B9334,0x56 +asm/non_matchings/code/z_actor/Actor_InitContext.s,Actor_InitContext,0x800B9170,0x71 +asm/non_matchings/code/z_actor/Actor_SpawnSetupActors.s,Actor_SpawnSetupActors,0x800B9334,0x56 asm/non_matchings/code/z_actor/Actor_UpdateActor.s,Actor_UpdateActor,0x800B948C,0xBD asm/non_matchings/code/z_actor/Actor_UpdateAll.s,Actor_UpdateAll,0x800B9780,0xA1 -asm/non_matchings/code/z_actor/Actor_DrawActor.s,Actor_DrawActor,0x800B9A04,0xC6 +asm/non_matchings/code/z_actor/Actor_Draw.s,Actor_Draw,0x800B9A04,0xC6 asm/non_matchings/code/z_actor/func_800B9D1C.s,func_800B9D1C,0x800B9D1C,0x48 asm/non_matchings/code/z_actor/Actor_DrawAllSetup.s,Actor_DrawAllSetup,0x800B9E3C,0x4 asm/non_matchings/code/z_actor/Actor_RecordUndrawnActor.s,Actor_RecordUndrawnActor,0x800B9E4C,0xE @@ -343,45 +343,45 @@ asm/non_matchings/code/z_actor/Actor_DrawAll.s,Actor_DrawAll,0x800BA42C,0xB4 asm/non_matchings/code/z_actor/func_800BA6FC.s,func_800BA6FC,0x800BA6FC,0x27 asm/non_matchings/code/z_actor/func_800BA798.s,func_800BA798,0x800BA798,0x48 asm/non_matchings/code/z_actor/func_800BA8B8.s,func_800BA8B8,0x800BA8B8,0x3F -asm/non_matchings/code/z_actor/func_800BA9B4.s,func_800BA9B4,0x800BA9B4,0x40 -asm/non_matchings/code/z_actor/Actor_InsertIntoTypeList.s,Actor_InsertIntoTypeList,0x800BAAB4,0x1C -asm/non_matchings/code/z_actor/Actor_RemoveFromTypeList.s,Actor_RemoveFromTypeList,0x800BAB24,0x36 +asm/non_matchings/code/z_actor/Actor_CleanupContext.s,Actor_CleanupContext,0x800BA9B4,0x40 +asm/non_matchings/code/z_actor/Actor_AddToCategory.s,Actor_AddToCategory,0x800BAAB4,0x1C +asm/non_matchings/code/z_actor/Actor_RemoveFromCategory.s,Actor_RemoveFromCategory,0x800BAB24,0x36 asm/non_matchings/code/z_actor/Actor_FreeOverlay.s,Actor_FreeOverlay,0x800BABFC,0x19 asm/non_matchings/code/z_actor/Actor_Spawn.s,Actor_Spawn,0x800BAC60,0x1D asm/non_matchings/code/z_actor/Actor_LoadOverlay.s,Actor_LoadOverlay,0x800BACD4,0x50 -asm/non_matchings/code/z_actor/Actor_SpawnWithParentAndCutscene.s,Actor_SpawnWithParentAndCutscene,0x800BAE14,0xAB -asm/non_matchings/code/z_actor/Actor_SpawnWithParent.s,Actor_SpawnWithParent,0x800BB0C0,0x20 +asm/non_matchings/code/z_actor/Actor_SpawnAsChildAndCutscene.s,Actor_SpawnAsChildAndCutscene,0x800BAE14,0xAB +asm/non_matchings/code/z_actor/Actor_SpawnAsChild.s,Actor_SpawnAsChild,0x800BB0C0,0x20 asm/non_matchings/code/z_actor/Actor_SpawnTransitionActors.s,Actor_SpawnTransitionActors,0x800BB140,0x64 -asm/non_matchings/code/z_actor/func_800BB2D0.s,func_800BB2D0,0x800BB2D0,0x72 -asm/non_matchings/code/z_actor/func_800BB498.s,func_800BB498,0x800BB498,0x41 +asm/non_matchings/code/z_actor/Actor_SpawnEntry.s,Actor_SpawnEntry,0x800BB2D0,0x72 +asm/non_matchings/code/z_actor/Actor_Delete.s,Actor_Delete,0x800BB498,0x41 asm/non_matchings/code/z_actor/func_800BB59C.s,func_800BB59C,0x800BB59C,0x1A asm/non_matchings/code/z_actor/func_800BB604.s,func_800BB604,0x800BB604,0xBA asm/non_matchings/code/z_actor/func_800BB8EC.s,func_800BB8EC,0x800BB8EC,0x67 -asm/non_matchings/code/z_actor/func_800BBA88.s,func_800BBA88,0x800BBA88,0xE +asm/non_matchings/code/z_actor/Enemy_StartFinishingBlow.s,Enemy_StartFinishingBlow,0x800BBA88,0xE asm/non_matchings/code/z_actor/func_800BBAC0.s,func_800BBAC0,0x800BBAC0,0x2D asm/non_matchings/code/z_actor/func_800BBB74.s,func_800BBB74,0x800BBB74,0x2B asm/non_matchings/code/z_actor/func_800BBC20.s,func_800BBC20,0x800BBC20,0x33 -asm/non_matchings/code/z_actor/func_800BBCEC.s,func_800BBCEC,0x800BBCEC,0x30 -asm/non_matchings/code/z_actor/func_800BBDAC.s,func_800BBDAC,0x800BBDAC,0x81 +asm/non_matchings/code/z_actor/Actor_SpawnBodyParts.s,Actor_SpawnBodyParts,0x800BBCEC,0x30 +asm/non_matchings/code/z_actor/Actor_SpawnFloorDustRing.s,Actor_SpawnFloorDustRing,0x800BBDAC,0x81 asm/non_matchings/code/z_actor/func_800BBFB0.s,func_800BBFB0,0x800BBFB0,0x69 asm/non_matchings/code/z_actor/func_800BC154.s,func_800BC154,0x800BC154,0xD asm/non_matchings/code/z_actor/func_800BC188.s,func_800BC188,0x800BC188,0xB asm/non_matchings/code/z_actor/func_800BC1B4.s,func_800BC1B4,0x800BC1B4,0x2F asm/non_matchings/code/z_actor/func_800BC270.s,func_800BC270,0x800BC270,0x75 asm/non_matchings/code/z_actor/func_800BC444.s,func_800BC444,0x800BC444,0x2A -asm/non_matchings/code/z_actor/func_800BC4EC.s,func_800BC4EC,0x800BC4EC,0x33 -asm/non_matchings/code/z_actor/func_800BC5B8.s,func_800BC5B8,0x800BC5B8,0xD -asm/non_matchings/code/z_actor/func_800BC5EC.s,func_800BC5EC,0x800BC5EC,0xD +asm/non_matchings/code/z_actor/Actor_TestFloorInDirection.s,Actor_TestFloorInDirection,0x800BC4EC,0x33 +asm/non_matchings/code/z_actor/Actor_IsTargeted.s,Actor_IsTargeted,0x800BC5B8,0xD +asm/non_matchings/code/z_actor/Actor_OtherIsTargeted.s,Actor_OtherIsTargeted,0x800BC5EC,0xD asm/non_matchings/code/z_actor/func_800BC620.s,func_800BC620,0x800BC620,0x54 asm/non_matchings/code/z_actor/func_800BC770.s,func_800BC770,0x800BC770,0x1A asm/non_matchings/code/z_actor/func_800BC7D8.s,func_800BC7D8,0x800BC7D8,0x1C asm/non_matchings/code/z_actor/func_800BC848.s,func_800BC848,0x800BC848,0x1C -asm/non_matchings/code/z_actor/func_800BC8B8.s,func_800BC8B8,0x800BC8B8,0xA6 -asm/non_matchings/code/z_actor/func_800BCB50.s,func_800BCB50,0x800BCB50,0x8 -asm/non_matchings/code/z_actor/func_800BCB70.s,func_800BCB70,0x800BCB70,0x21 +asm/non_matchings/code/z_actor/Actor_DrawDoorLock.s,Actor_DrawDoorLock,0x800BC8B8,0xA6 +asm/non_matchings/code/z_actor/Actor_SpawnShieldParticlesMetal.s,Actor_SpawnShieldParticlesMetal,0x800BCB50,0x8 +asm/non_matchings/code/z_actor/Actor_SetColorFilter.s,Actor_SetColorFilter,0x800BCB70,0x21 asm/non_matchings/code/z_actor/func_800BCBF4.s,func_800BCBF4,0x800BCBF4,0x1D asm/non_matchings/code/z_actor/func_800BCC68.s,func_800BCC68,0x800BCC68,0x1D -asm/non_matchings/code/z_actor/func_800BCCDC.s,func_800BCCDC,0x800BCCDC,0x176 +asm/non_matchings/code/z_actor/Actor_GetClosestPosOnPath.s,Actor_GetClosestPosOnPath,0x800BCCDC,0x176 asm/non_matchings/code/z_actor/func_800BD2B4.s,func_800BD2B4,0x800BD2B4,0x34 asm/non_matchings/code/z_actor/func_800BD384.s,func_800BD384,0x800BD384,0xCD asm/non_matchings/code/z_actor/func_800BD6B8.s,func_800BD6B8,0x800BD6B8,0xB @@ -391,55 +391,55 @@ asm/non_matchings/code/z_actor/func_800BD9A0.s,func_800BD9A0,0x800BD9A0,0x10 asm/non_matchings/code/z_actor/func_800BD9E0.s,func_800BD9E0,0x800BD9E0,0x30 asm/non_matchings/code/z_actor/func_800BDAA0.s,func_800BDAA0,0x800BDAA0,0x33 asm/non_matchings/code/z_actor/func_800BDB6C.s,func_800BDB6C,0x800BDB6C,0x3C -asm/non_matchings/code/z_actor/func_800BDC5C.s,func_800BDC5C,0x800BDC5C,0x26 +asm/non_matchings/code/z_actor/Actor_ChangeAnimationByInfo.s,Actor_ChangeAnimationByInfo,0x800BDC5C,0x26 asm/non_matchings/code/z_actor/func_800BDCF4.s,func_800BDCF4,0x800BDCF4,0xAF asm/non_matchings/code/z_actor/Actor_Noop.s,Actor_Noop,0x800BDFB0,0x4 -asm/non_matchings/code/z_actor/func_800BDFC0.s,func_800BDFC0,0x800BDFC0,0x1F -asm/non_matchings/code/z_actor/func_800BE03C.s,func_800BE03C,0x800BE03C,0x1F -asm/non_matchings/code/z_actor/func_800BE0B8.s,func_800BE0B8,0x800BE0B8,0x33 +asm/non_matchings/code/z_actor/Gfx_DrawDListOpa.s,Gfx_DrawDListOpa,0x800BDFC0,0x1F +asm/non_matchings/code/z_actor/Gfx_DrawDListXlu.s,Gfx_DrawDListXlu,0x800BE03C,0x1F +asm/non_matchings/code/z_actor/Actor_FindNearby.s,Actor_FindNearby,0x800BE0B8,0x33 asm/non_matchings/code/z_actor/func_800BE184.s,func_800BE184,0x800BE184,0x2A -asm/non_matchings/code/z_actor/func_800BE22C.s,func_800BE22C,0x800BE22C,0xB -asm/non_matchings/code/z_actor/func_800BE258.s,func_800BE258,0x800BE258,0x18 -asm/non_matchings/code/z_actor/func_800BE2B8.s,func_800BE2B8,0x800BE2B8,0x21 +asm/non_matchings/code/z_actor/Actor_ApplyDamage.s,Actor_ApplyDamage,0x800BE22C,0xB +asm/non_matchings/code/z_actor/Actor_SetDropFlag.s,Actor_SetDropFlag,0x800BE258,0x18 +asm/non_matchings/code/z_actor/Actor_SetDropFlagJntSph.s,Actor_SetDropFlagJntSph,0x800BE2B8,0x21 asm/non_matchings/code/z_actor/func_800BE33C.s,func_800BE33C,0x800BE33C,0x25 asm/non_matchings/code/z_actor/func_800BE3D0.s,func_800BE3D0,0x800BE3D0,0x4D asm/non_matchings/code/z_actor/func_800BE504.s,func_800BE504,0x800BE504,0x19 asm/non_matchings/code/z_actor/func_800BE568.s,func_800BE568,0x800BE568,0x19 asm/non_matchings/code/z_actor/func_800BE5CC.s,func_800BE5CC,0x800BE5CC,0x1C asm/non_matchings/code/z_actor/func_800BE63C.s,func_800BE63C,0x800BE63C,0x11 -asm/non_matchings/code/z_actor/func_800BE680.s,func_800BE680,0x800BE680,0x453 -asm/non_matchings/code/z_actor/func_800BF7CC.s,func_800BF7CC,0x800BF7CC,0x75 +asm/non_matchings/code/z_actor/Actor_DrawDamageEffects.s,Actor_DrawDamageEffects,0x800BE680,0x453 +asm/non_matchings/code/z_actor/Actor_SpawnIceEffects.s,Actor_SpawnIceEffects,0x800BF7CC,0x75 asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_FaultPrint.s,ActorOverlayTable_FaultPrint,0x800BF9A0,0x36 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_GetConveyorType.s,SurfaceType_GetConveyorType,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 @@ -610,22 +610,22 @@ asm/non_matchings/code/z_bg_collect/BgCheck2_UpdateActorPosition.s,BgCheck2_Upda asm/non_matchings/code/z_bg_collect/BgCheck2_UpdateActorYRotation.s,BgCheck2_UpdateActorYRotation,0x800CAC0C,0x25 asm/non_matchings/code/z_bg_collect/BgCheck2_AttachToMesh.s,BgCheck2_AttachToMesh,0x800CACA0,0x23 asm/non_matchings/code/z_bg_collect/BgCheck2_UpdateActorAttachedToMesh.s,BgCheck2_UpdateActorAttachedToMesh,0x800CAD2C,0x39 -asm/non_matchings/code/z_bg_item/BcCheck3_BgActorInit.s,BcCheck3_BgActorInit,0x800CAE10,0x9 -asm/non_matchings/code/z_bg_item/BgCheck3_LoadMesh.s,BgCheck3_LoadMesh,0x800CAE34,0x12 -asm/non_matchings/code/z_bg_item/BgCheck3_ResetFlags.s,BgCheck3_ResetFlags,0x800CAE7C,0x3 -asm/non_matchings/code/z_bg_item/func_800CAE88.s,func_800CAE88,0x800CAE88,0x5 -asm/non_matchings/code/z_bg_item/func_800CAE9C.s,func_800CAE9C,0x800CAE9C,0x5 -asm/non_matchings/code/z_bg_item/func_800CAEB0.s,func_800CAEB0,0x800CAEB0,0xC -asm/non_matchings/code/z_bg_item/func_800CAEE0.s,func_800CAEE0,0x800CAEE0,0x5 -asm/non_matchings/code/z_bg_item/func_800CAEF4.s,func_800CAEF4,0x800CAEF4,0xC -asm/non_matchings/code/z_bg_item/func_800CAF24.s,func_800CAF24,0x800CAF24,0x5 -asm/non_matchings/code/z_bg_item/func_800CAF38.s,func_800CAF38,0x800CAF38,0x5 -asm/non_matchings/code/z_bg_item/func_800CAF4C.s,func_800CAF4C,0x800CAF4C,0x9 -asm/non_matchings/code/z_bg_item/func_800CAF70.s,func_800CAF70,0x800CAF70,0x9 -asm/non_matchings/code/z_bg_item/func_800CAF94.s,func_800CAF94,0x800CAF94,0x9 -asm/non_matchings/code/z_bg_item/func_800CAFB8.s,func_800CAFB8,0x800CAFB8,0x9 -asm/non_matchings/code/z_bg_item/func_800CAFDC.s,func_800CAFDC,0x800CAFDC,0x9 -asm/non_matchings/code/code_800CB000/func_800CB000.s,func_800CB000,0x800CB000,0x84 +asm/non_matchings/code/z_bg_item/DynaPoly_Init.s,DynaPoly_Init,0x800CAE10,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_LoadMesh.s,DynaPoly_LoadMesh,0x800CAE34,0x12 +asm/non_matchings/code/z_bg_item/DynaPoly_ResetState.s,DynaPoly_ResetState,0x800CAE7C,0x3 +asm/non_matchings/code/z_bg_item/DynaPoly_SetRidingFallingState.s,DynaPoly_SetRidingFallingState,0x800CAE88,0x5 +asm/non_matchings/code/z_bg_item/DynaPoly_SetRidingMovingState.s,DynaPoly_SetRidingMovingState,0x800CAE9C,0x5 +asm/non_matchings/code/z_bg_item/DynaPoly_SetRidingMovingStateByIndex.s,DynaPoly_SetRidingMovingStateByIndex,0x800CAEB0,0xC +asm/non_matchings/code/z_bg_item/DynaPoly_SetRidingRotatingState.s,DynaPoly_SetRidingRotatingState,0x800CAEE0,0x5 +asm/non_matchings/code/z_bg_item/DynaPoly_SetRidingRotatingStateByIndex.s,DynaPoly_SetRidingRotatingStateByIndex,0x800CAEF4,0xC +asm/non_matchings/code/z_bg_item/DynaPoly_SetSwitchPressedState.s,DynaPoly_SetSwitchPressedState,0x800CAF24,0x5 +asm/non_matchings/code/z_bg_item/DynaPoly_SetHeavySwitchPressedState.s,DynaPoly_SetHeavySwitchPressedState,0x800CAF38,0x5 +asm/non_matchings/code/z_bg_item/DynaPoly_IsInRidingFallingState.s,DynaPoly_IsInRidingFallingState,0x800CAF4C,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_IsInRidingMovingState.s,DynaPoly_IsInRidingMovingState,0x800CAF70,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_IsInRidingRotatingState.s,DynaPoly_IsInRidingRotatingState,0x800CAF94,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_IsInSwitchPressedState.s,DynaPoly_IsInSwitchPressedState,0x800CAFB8,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_IsInHeavySwitchPressedState.s,DynaPoly_IsInHeavySwitchPressedState,0x800CAFDC,0x9 +asm/non_matchings/code/z_bg_item/DynaPoly_ValidateMove.s,DynaPoly_ValidateMove,0x800CB000,0x84 asm/non_matchings/code/z_camera/Camera_fabsf.s,Camera_fabsf,0x800CB210,0xC asm/non_matchings/code/z_camera/Camera_LengthVec3f.s,Camera_LengthVec3f,0x800CB240,0xC asm/non_matchings/code/z_camera/func_800CB270.s,func_800CB270,0x800CB270,0x30 @@ -782,17 +782,17 @@ asm/non_matchings/code/z_camera/func_800DE954.s,func_800DE954,0x800DE954,0x17 asm/non_matchings/code/z_camera/Camera_Update.s,Camera_Update,0x800DE9B0,0x2BA asm/non_matchings/code/z_camera/func_800DF498.s,func_800DF498,0x800DF498,0xE asm/non_matchings/code/z_camera/Camera_SetMode.s,Camera_SetMode,0x800DF4D0,0xDC -asm/non_matchings/code/z_camera/func_800DF840.s,func_800DF840,0x800DF840,0xB +asm/non_matchings/code/z_camera/Camera_ChangeMode.s,Camera_ChangeMode,0x800DF840,0xB asm/non_matchings/code/z_camera/func_800DF86C.s,func_800DF86C,0x800DF86C,0x20 asm/non_matchings/code/z_camera/func_800DF8EC.s,func_800DF8EC,0x800DF8EC,0x77 asm/non_matchings/code/z_camera/func_800DFAC8.s,func_800DFAC8,0x800DFAC8,0x13 -asm/non_matchings/code/z_camera/func_800DFB14.s,func_800DFB14,0x800DFB14,0x42 +asm/non_matchings/code/z_camera/Camera_ChangeDataIdx.s,Camera_ChangeDataIdx,0x800DFB14,0x42 asm/non_matchings/code/z_camera/func_800DFC1C.s,func_800DFC1C,0x800DFC1C,0x9 asm/non_matchings/code/z_camera/func_800DFC40.s,func_800DFC40,0x800DFC40,0xA -asm/non_matchings/code/z_camera/func_800DFC68.s,func_800DFC68,0x800DFC68,0xA +asm/non_matchings/code/z_camera/Camera_GetInputDirYaw.s,Camera_GetInputDirYaw,0x800DFC68,0xA asm/non_matchings/code/z_camera/func_800DFC90.s,func_800DFC90,0x800DFC90,0x9 -asm/non_matchings/code/z_camera/func_800DFCB4.s,func_800DFCB4,0x800DFCB4,0xA -asm/non_matchings/code/z_camera/func_800DFCDC.s,func_800DFCDC,0x800DFCDC,0xA +asm/non_matchings/code/z_camera/Camera_GetCamDirPitch.s,Camera_GetCamDirPitch,0x800DFCB4,0xA +asm/non_matchings/code/z_camera/Camera_GetCamDirYaw.s,Camera_GetCamDirYaw,0x800DFCDC,0xA asm/non_matchings/code/z_camera/func_800DFD04.s,func_800DFD04,0x800DFD04,0x1D asm/non_matchings/code/z_camera/func_800DFD78.s,func_800DFD78,0x800DFD78,0x5E asm/non_matchings/code/z_camera/func_800DFEF0.s,func_800DFEF0,0x800DFEF0,0xA @@ -804,13 +804,13 @@ asm/non_matchings/code/z_camera/Camera_ClearFlags.s,Camera_ClearFlags,0x800DFF84 asm/non_matchings/code/z_camera/func_800DFFAC.s,func_800DFFAC,0x800DFFAC,0x34 asm/non_matchings/code/z_camera/func_800E007C.s,func_800E007C,0x800E007C,0x4C asm/non_matchings/code/z_camera/func_800E01AC.s,func_800E01AC,0x800E01AC,0x3 -asm/non_matchings/code/z_camera/func_800E01B8.s,func_800E01B8,0x800E01B8,0x9 +asm/non_matchings/code/z_camera/Camera_GetQuakeOffset.s,Camera_GetQuakeOffset,0x800E01B8,0x9 asm/non_matchings/code/z_camera/func_800E01DC.s,func_800E01DC,0x800E01DC,0x13 asm/non_matchings/code/z_camera/func_800E0228.s,func_800E0228,0x800E0228,0x4 asm/non_matchings/code/z_camera/func_800E0238.s,func_800E0238,0x800E0238,0x1D -asm/non_matchings/code/z_camera/func_800E02AC.s,func_800E02AC,0x800E02AC,0x17 -asm/non_matchings/code/z_camera/func_800E0308.s,func_800E0308,0x800E0308,0x5 -asm/non_matchings/code/z_camera/func_800E031C.s,func_800E031C,0x800E031C,0xB +asm/non_matchings/code/z_camera/Camera_SetToTrackActor.s,Camera_SetToTrackActor,0x800E02AC,0x17 +asm/non_matchings/code/z_camera/Camera_SetTargetActor.s,Camera_SetTargetActor,0x800E0308,0x5 +asm/non_matchings/code/z_camera/Camera_GetWaterYPos.s,Camera_GetWaterYPos,0x800E031C,0xB asm/non_matchings/code/z_camera/func_800E0348.s,func_800E0348,0x800E0348,0x16 asm/non_matchings/code/z_collision_btltbls/DamageTable_Get.s,DamageTable_Get,0x800E03A0,0xB asm/non_matchings/code/z_collision_btltbls/DamageTable_Clear.s,DamageTable_Clear,0x800E03CC,0xD @@ -1034,7 +1034,7 @@ asm/non_matchings/code/code_800E8EA0/func_800E9138.s,func_800E9138,0x800E9138,0x asm/non_matchings/code/code_800E8EA0/func_800E9250.s,func_800E9250,0x800E9250,0x44 asm/non_matchings/code/z_common_data/func_800E9360.s,func_800E9360,0x800E9360,0x20 asm/non_matchings/code/z_debug/GameInfo_Init.s,GameInfo_Init,0x800E93E0,0x24 -asm/non_matchings/code/z_debug_display/func_800E9470.s,func_800E9470,0x800E9470,0x6 +asm/non_matchings/code/z_debug_display/DebugDisplay_Init.s,DebugDisplay_Init,0x800E9470,0x6 asm/non_matchings/code/z_debug_display/DebugDisplay_AddObject.s,DebugDisplay_AddObject,0x800E9488,0x37 asm/non_matchings/code/z_debug_display/DebugDisplay_DrawObjects.s,DebugDisplay_DrawObjects,0x800E9564,0x24 asm/non_matchings/code/z_debug_display/func_800E95F4.s,func_800E95F4,0x800E95F4,0x79 @@ -1048,36 +1048,36 @@ asm/non_matchings/code/z_debug_mode/func_800E9DBC.s,func_800E9DBC,0x800E9DBC,0x3 asm/non_matchings/code/z_debug_mode/func_800E9E94.s,func_800E9E94,0x800E9E94,0x39 asm/non_matchings/code/z_debug_mode/func_800E9F78.s,func_800E9F78,0x800E9F78,0x3A asm/non_matchings/code/z_demo/Cutscene_Init.s,Cutscene_Init,0x800EA060,0x1D -asm/non_matchings/code/z_demo/func_800EA0D4.s,func_800EA0D4,0x800EA0D4,0x6 -asm/non_matchings/code/z_demo/func_800EA0EC.s,func_800EA0EC,0x800EA0EC,0x9 -asm/non_matchings/code/z_demo/Cutscene_StepCutscene1.s,Cutscene_StepCutscene1,0x800EA110,0x13 -asm/non_matchings/code/z_demo/Cutscene_StepCutscene2.s,Cutscene_StepCutscene2,0x800EA15C,0x2D -asm/non_matchings/code/z_demo/Cutscene_Nop800EA210.s,Cutscene_Nop800EA210,0x800EA210,0x4 +asm/non_matchings/code/z_demo/Cutscene_Start.s,Cutscene_Start,0x800EA0D4,0x6 +asm/non_matchings/code/z_demo/Cutscene_End.s,Cutscene_End,0x800EA0EC,0x9 +asm/non_matchings/code/z_demo/Cutscene_Update1.s,Cutscene_Update1,0x800EA110,0x13 +asm/non_matchings/code/z_demo/Cutscene_Update2.s,Cutscene_Update2,0x800EA15C,0x2D +asm/non_matchings/code/z_demo/Cutscene_DoNothing.s,Cutscene_DoNothing,0x800EA210,0x4 asm/non_matchings/code/z_demo/func_800EA220.s,func_800EA220,0x800EA220,0xE asm/non_matchings/code/z_demo/func_800EA258.s,func_800EA258,0x800EA258,0x18 asm/non_matchings/code/z_demo/func_800EA2B8.s,func_800EA2B8,0x800EA2B8,0x1B -asm/non_matchings/code/z_demo/func_800EA324.s,func_800EA324,0x800EA324,0x222 -asm/non_matchings/code/z_demo/func_800EABAC.s,func_800EABAC,0x800EABAC,0x17 -asm/non_matchings/code/z_demo/func_800EAC08.s,func_800EAC08,0x800EAC08,0xF -asm/non_matchings/code/z_demo/func_800EAC44.s,func_800EAC44,0x800EAC44,0x14 -asm/non_matchings/code/z_demo/func_800EAC94.s,func_800EAC94,0x800EAC94,0x20 -asm/non_matchings/code/z_demo/func_800EAD14.s,func_800EAD14,0x800EAD14,0xD +asm/non_matchings/code/z_demo/Cutscene_Command_Misc.s,Cutscene_Command_Misc,0x800EA324,0x222 +asm/non_matchings/code/z_demo/Cutscene_Command_SetLighting.s,Cutscene_Command_SetLighting,0x800EABAC,0x17 +asm/non_matchings/code/z_demo/Cutscene_Command_PlaySequence.s,Cutscene_Command_PlaySequence,0x800EAC08,0xF +asm/non_matchings/code/z_demo/Cutscene_Command_StopSequence.s,Cutscene_Command_StopSequence,0x800EAC44,0x14 +asm/non_matchings/code/z_demo/Cutscene_Command_FadeSequence.s,Cutscene_Command_FadeSequence,0x800EAC94,0x20 +asm/non_matchings/code/z_demo/Cutscene_Command_PlayAmbienceSequence.s,Cutscene_Command_PlayAmbienceSequence,0x800EAD14,0xD asm/non_matchings/code/z_demo/func_800EAD48.s,func_800EAD48,0x800EAD48,0xD asm/non_matchings/code/z_demo/func_800EAD7C.s,func_800EAD7C,0x800EAD7C,0xD asm/non_matchings/code/z_demo/func_800EADB0.s,func_800EADB0,0x800EADB0,0x47 -asm/non_matchings/code/z_demo/func_800EAECC.s,func_800EAECC,0x800EAECC,0x15 -asm/non_matchings/code/z_demo/func_800EAF20.s,func_800EAF20,0x800EAF20,0x30 -asm/non_matchings/code/z_demo/func_800EAFE0.s,func_800EAFE0,0x800EAFE0,0x7F -asm/non_matchings/code/z_demo/func_800EB1DC.s,func_800EB1DC,0x800EB1DC,0x62 -asm/non_matchings/code/z_demo/func_800EB364.s,func_800EB364,0x800EB364,0x54 -asm/non_matchings/code/z_demo/func_800EB4B4.s,func_800EB4B4,0x800EB4B4,0x91 -asm/non_matchings/code/z_demo/func_800EB6F8.s,func_800EB6F8,0x800EB6F8,0x11C -asm/non_matchings/code/z_demo/func_800EBB68.s,func_800EBB68,0x800EBB68,0x5A -asm/non_matchings/code/z_demo/func_800EBCD0.s,func_800EBCD0,0x800EBCD0,0x24 -asm/non_matchings/code/z_demo/func_800EBD60.s,func_800EBD60,0x800EBD60,0x246 -asm/non_matchings/code/z_demo/func_800EC678.s,func_800EC678,0x800EC678,0x17 -asm/non_matchings/code/z_demo/func_800EC6D4.s,func_800EC6D4,0x800EC6D4,0x94 -asm/non_matchings/code/z_demo/func_800EC924.s,func_800EC924,0x800EC924,0x116 +asm/non_matchings/code/z_demo/Cutscene_Command_FadeAmbienceSequence.s,Cutscene_Command_FadeAmbienceSequence,0x800EAECC,0x15 +asm/non_matchings/code/z_demo/Cutscene_Command_Rumble.s,Cutscene_Command_Rumble,0x800EAF20,0x30 +asm/non_matchings/code/z_demo/Cutscene_Command_FadeColorScreen.s,Cutscene_Command_FadeColorScreen,0x800EAFE0,0x7F +asm/non_matchings/code/z_demo/Cutscene_Command_SetTime.s,Cutscene_Command_SetTime,0x800EB1DC,0x62 +asm/non_matchings/code/z_demo/Cutscene_TerminatorImpl.s,Cutscene_TerminatorImpl,0x800EB364,0x54 +asm/non_matchings/code/z_demo/Cutscene_Command_Terminator.s,Cutscene_Command_Terminator,0x800EB4B4,0x91 +asm/non_matchings/code/z_demo/Cutscene_Command_ChooseCreditsScenes.s,Cutscene_Command_ChooseCreditsScenes,0x800EB6F8,0x11C +asm/non_matchings/code/z_demo/Cutscene_Command_MotionBlur.s,Cutscene_Command_MotionBlur,0x800EBB68,0x5A +asm/non_matchings/code/z_demo/Cutscene_Command_GiveTatlToPlayer.s,Cutscene_Command_GiveTatlToPlayer,0x800EBCD0,0x24 +asm/non_matchings/code/z_demo/Cutscene_Command_TransitionFX.s,Cutscene_Command_TransitionFX,0x800EBD60,0x246 +asm/non_matchings/code/z_demo/Cutscene_Command_Camera.s,Cutscene_Command_Camera,0x800EC678,0x17 +asm/non_matchings/code/z_demo/Cutscene_CountNormalMasks.s,Cutscene_CountNormalMasks,0x800EC6D4,0x94 +asm/non_matchings/code/z_demo/Cutscene_Command_Textbox.s,Cutscene_Command_Textbox,0x800EC924,0x116 asm/non_matchings/code/z_demo/func_800ECD7C.s,func_800ECD7C,0x800ECD7C,0x31 asm/non_matchings/code/z_demo/Cutscene_ProcessCommands.s,Cutscene_ProcessCommands,0x800ECE40,0x2D0 asm/non_matchings/code/z_demo/func_800ED980.s,func_800ED980,0x800ED980,0x11 @@ -1085,17 +1085,17 @@ asm/non_matchings/code/z_demo/func_800ED9C4.s,func_800ED9C4,0x800ED9C4,0x10 asm/non_matchings/code/z_demo/func_800EDA04.s,func_800EDA04,0x800EDA04,0x20 asm/non_matchings/code/z_demo/func_800EDA84.s,func_800EDA84,0x800EDA84,0x57 asm/non_matchings/code/z_demo/func_800EDBE0.s,func_800EDBE0,0x800EDBE0,0x74 -asm/non_matchings/code/z_demo/nop_800EDDB0.s,nop_800EDDB0,0x800EDDB0,0x3 +asm/non_matchings/code/z_demo/func_800EDDB0.s,func_800EDDB0,0x800EDDB0,0x3 asm/non_matchings/code/z_demo/func_800EDDBC.s,func_800EDDBC,0x800EDDBC,0x4 -asm/non_matchings/code/z_demo/func_800EDDCC.s,func_800EDDCC,0x800EDDCC,0x1A -asm/non_matchings/code/z_demo/func_800EDE34.s,func_800EDE34,0x800EDE34,0x3C -asm/non_matchings/code/z_demo/func_800EDF24.s,func_800EDF24,0x800EDF24,0x15 -asm/non_matchings/code/z_demo/func_800EDF78.s,func_800EDF78,0x800EDF78,0x55 -asm/non_matchings/code/z_demo/func_800EE0CC.s,func_800EE0CC,0x800EE0CC,0x43 -asm/non_matchings/code/z_demo/func_800EE1D8.s,func_800EE1D8,0x800EE1D8,0xA -asm/non_matchings/code/z_demo/func_800EE200.s,func_800EE200,0x800EE200,0x27 -asm/non_matchings/code/z_demo/func_800EE29C.s,func_800EE29C,0x800EE29C,0x16 -asm/non_matchings/code/z_demo/func_800EE2F4.s,func_800EE2F4,0x800EE2F4,0xB +asm/non_matchings/code/z_demo/Cutscene_LoadCutsceneData.s,Cutscene_LoadCutsceneData,0x800EDDCC,0x1A +asm/non_matchings/code/z_demo/Cutscene_ActorTranslate.s,Cutscene_ActorTranslate,0x800EDE34,0x3C +asm/non_matchings/code/z_demo/Cutscene_ActorTranslateAndYaw.s,Cutscene_ActorTranslateAndYaw,0x800EDF24,0x15 +asm/non_matchings/code/z_demo/Cutscene_ActorTranslateAndYawSmooth.s,Cutscene_ActorTranslateAndYawSmooth,0x800EDF78,0x55 +asm/non_matchings/code/z_demo/Cutscene_ActorTranslateXZAndYawSmooth.s,Cutscene_ActorTranslateXZAndYawSmooth,0x800EE0CC,0x43 +asm/non_matchings/code/z_demo/Cutscene_GetSceneSetupIndex.s,Cutscene_GetSceneSetupIndex,0x800EE1D8,0xA +asm/non_matchings/code/z_demo/Cutscene_GetActorActionIndex.s,Cutscene_GetActorActionIndex,0x800EE200,0x27 +asm/non_matchings/code/z_demo/Cutscene_CheckActorAction.s,Cutscene_CheckActorAction,0x800EE29C,0x16 +asm/non_matchings/code/z_demo/Cutscene_IsPlaying.s,Cutscene_IsPlaying,0x800EE2F4,0xB asm/non_matchings/code/z_draw/GetItem_Draw.s,GetItem_Draw,0x800EE320,0x11 asm/non_matchings/code/z_draw/func_800EE364.s,func_800EE364,0x800EE364,0x27 asm/non_matchings/code/z_draw/func_800EE400.s,func_800EE400,0x800EE400,0x7F @@ -1124,11 +1124,11 @@ asm/non_matchings/code/z_eff_footmark/EffFootmark_Init.s,EffFootmark_Init,0x800E asm/non_matchings/code/z_eff_footmark/EffFootmark_Add.s,EffFootmark_Add,0x800EFF04,0x6E asm/non_matchings/code/z_eff_footmark/EffFootmark_Update.s,EffFootmark_Update,0x800F00BC,0x43 asm/non_matchings/code/z_eff_footmark/EffFootmark_Draw.s,EffFootmark_Draw,0x800F01C8,0x72 -asm/non_matchings/code/code_800F0390/func_800F0390.s,func_800F0390,0x800F0390,0xC -asm/non_matchings/code/code_800F0390/func_800F03C0.s,func_800F03C0,0x800F03C0,0x33 -asm/non_matchings/code/code_800F0390/func_800F048C.s,func_800F048C,0x800F048C,0x37 -asm/non_matchings/code/code_800F0390/func_800F0568.s,func_800F0568,0x800F0568,0xA -asm/non_matchings/code/code_800F0390/func_800F0590.s,func_800F0590,0x800F0590,0xC +asm/non_matchings/code/z_sound_source/SoundSource_InitAll.s,SoundSource_InitAll,0x800F0390,0xC +asm/non_matchings/code/z_sound_source/SoundSource_UpdateAll.s,SoundSource_UpdateAll,0x800F03C0,0x33 +asm/non_matchings/code/z_sound_source/SoundSource_Add.s,SoundSource_Add,0x800F048C,0x37 +asm/non_matchings/code/z_sound_source/SoundSource_PlaySfxAtFixedWorldPos.s,SoundSource_PlaySfxAtFixedWorldPos,0x800F0568,0xA +asm/non_matchings/code/z_sound_source/SoundSource_PlaySfxEachFrameAtFixedWorldPos.s,SoundSource_PlaySfxEachFrameAtFixedWorldPos,0x800F0590,0xC asm/non_matchings/code/z_elf_message/func_800F05C0.s,func_800F05C0,0x800F05C0,0x80 asm/non_matchings/code/code_800F07C0/func_800F07C0.s,func_800F07C0,0x800F07C0,0x32 asm/non_matchings/code/code_800F07C0/func_800F0888.s,func_800F0888,0x800F0888,0x2F @@ -1207,13 +1207,13 @@ asm/non_matchings/code/z_horse/func_800F3ED4.s,func_800F3ED4,0x800F3ED4,0x73 asm/non_matchings/code/z_horse/func_800F40A0.s,func_800F40A0,0x800F40A0,0x2F asm/non_matchings/code/z_horse/func_800F415C.s,func_800F415C,0x800F415C,0x22 asm/non_matchings/code/z_horse/func_800F41E4.s,func_800F41E4,0x800F41E4,0x2F -asm/non_matchings/code/z_jpeg/func_800F42A0.s,func_800F42A0,0x800F42A0,0x47 -asm/non_matchings/code/z_jpeg/func_800F43BC.s,func_800F43BC,0x800F43BC,0x4E -asm/non_matchings/code/z_jpeg/func_800F44F4.s,func_800F44F4,0x800F44F4,0x13 -asm/non_matchings/code/z_jpeg/func_800F4540.s,func_800F4540,0x800F4540,0x73 -asm/non_matchings/code/z_jpeg/func_800F470C.s,func_800F470C,0x800F470C,0xC1 +asm/non_matchings/code/z_jpeg/Jpeg_ScheduleDecoderTask.s,Jpeg_ScheduleDecoderTask,0x800F42A0,0x47 +asm/non_matchings/code/z_jpeg/Jpeg_CopyToZbuffer.s,Jpeg_CopyToZbuffer,0x800F43BC,0x4E +asm/non_matchings/code/z_jpeg/Jpeg_GetUnalignedU16.s,Jpeg_GetUnalignedU16,0x800F44F4,0x13 +asm/non_matchings/code/z_jpeg/Jpeg_ParseMarkers.s,Jpeg_ParseMarkers,0x800F4540,0x73 +asm/non_matchings/code/z_jpeg/Jpeg_Decode.s,Jpeg_Decode,0x800F470C,0xC1 asm/non_matchings/code/z_kaleido_setup/func_800F4A10.s,func_800F4A10,0x800F4A10,0x7F -asm/non_matchings/code/z_kaleido_setup/func_800F4C0C.s,func_800F4C0C,0x800F4C0C,0x85 +asm/non_matchings/code/z_kaleido_setup/KaleidoSetup_Update.s,KaleidoSetup_Update,0x800F4C0C,0x85 asm/non_matchings/code/z_kaleido_setup/func_800F4E20.s,func_800F4E20,0x800F4E20,0x42 asm/non_matchings/code/z_kaleido_setup/func_800F4F28.s,func_800F4F28,0x800F4F28,0x6 asm/non_matchings/code/z_kanfont/Font_LoadChar.s,Font_LoadChar,0x800F4F40,0x5 @@ -1224,7 +1224,7 @@ asm/non_matchings/code/z_kankyo/func_800F5090.s,func_800F5090,0x800F5090,0x11 asm/non_matchings/code/z_kankyo/func_800F50D4.s,func_800F50D4,0x800F50D4,0xE asm/non_matchings/code/z_kankyo/Kankyo_Init.s,Kankyo_Init,0x800F510C,0x212 asm/non_matchings/code/z_kankyo/func_800F5954.s,func_800F5954,0x800F5954,0x4E -asm/non_matchings/code/z_kankyo/func_800F5A8C.s,func_800F5A8C,0x800F5A8C,0x21 +asm/non_matchings/code/z_kankyo/Environment_LerpWeight.s,Environment_LerpWeight,0x800F5A8C,0x21 asm/non_matchings/code/z_kankyo/func_800F5B10.s,func_800F5B10,0x800F5B10,0x70 asm/non_matchings/code/z_kankyo/func_800F5CD0.s,func_800F5CD0,0x800F5CD0,0x2D9 asm/non_matchings/code/z_kankyo/func_800F6834.s,func_800F6834,0x800F6834,0x46 @@ -1252,7 +1252,7 @@ asm/non_matchings/code/z_kankyo/func_800FAAB4.s,func_800FAAB4,0x800FAAB4,0x5B asm/non_matchings/code/z_kankyo/func_800FAC20.s,func_800FAC20,0x800FAC20,0xD5 asm/non_matchings/code/z_kankyo/func_800FAF74.s,func_800FAF74,0x800FAF74,0x27 asm/non_matchings/code/z_kankyo/func_800FB010.s,func_800FB010,0x800FB010,0xC4 -asm/non_matchings/code/z_kankyo/func_800FB320.s,func_800FB320,0x800FB320,0x1A +asm/non_matchings/code/z_kankyo/Environment_AddLightningBolts.s,Environment_AddLightningBolts,0x800FB320,0x1A asm/non_matchings/code/z_kankyo/func_800FB388.s,func_800FB388,0x800FB388,0xF4 asm/non_matchings/code/z_kankyo/func_800FB758.s,func_800FB758,0x800FB758,0x97 asm/non_matchings/code/z_kankyo/func_800FB9B4.s,func_800FB9B4,0x800FB9B4,0xC2 @@ -1361,7 +1361,7 @@ asm/non_matchings/code/z_lib/Math_ApproachS.s,Math_ApproachS,0x800FFFD8,0x29 asm/non_matchings/code/z_lib/Color_RGBA8_Copy.s,Color_RGBA8_Copy,0x8010007C,0xA asm/non_matchings/code/z_lib/func_801000A4.s,func_801000A4,0x801000A4,0xA asm/non_matchings/code/z_lib/func_801000CC.s,func_801000CC,0x801000CC,0xA -asm/non_matchings/code/z_lib/func_801000F4.s,func_801000F4,0x801000F4,0xA +asm/non_matchings/code/z_lib/Lib_PlaySfxAtPos.s,Lib_PlaySfxAtPos,0x801000F4,0xA asm/non_matchings/code/z_lib/Lib_Vec3f_TranslateAndRotateY.s,Lib_Vec3f_TranslateAndRotateY,0x8010011C,0x27 asm/non_matchings/code/z_lib/Lib_LerpRGB.s,Lib_LerpRGB,0x801001B8,0xA4 asm/non_matchings/code/z_lib/Math_Vec3f_StepTo.s,Math_Vec3f_StepTo,0x80100448,0x2D @@ -1405,16 +1405,16 @@ asm/non_matchings/code/z_lights/Lights_NewAndDraw.s,Lights_NewAndDraw,0x801026E8 asm/non_matchings/code/z_lights/Lights_New.s,Lights_New,0x80102834,0x13 asm/non_matchings/code/z_lights/Lights_GlowCheck.s,Lights_GlowCheck,0x80102880,0x79 asm/non_matchings/code/z_lights/Lights_DrawGlow.s,Lights_DrawGlow,0x80102A64,0x7F -asm/non_matchings/code/z_malloc/zelda_malloc.s,zelda_malloc,0x80102C60,0xA -asm/non_matchings/code/z_malloc/zelda_mallocR.s,zelda_mallocR,0x80102C88,0xA -asm/non_matchings/code/z_malloc/zelda_realloc.s,zelda_realloc,0x80102CB0,0xC -asm/non_matchings/code/z_malloc/zelda_free.s,zelda_free,0x80102CE0,0xA -asm/non_matchings/code/z_malloc/zelda_calloc.s,zelda_calloc,0x80102D08,0x16 -asm/non_matchings/code/z_malloc/MainHeap_AnalyzeArena.s,MainHeap_AnalyzeArena,0x80102D60,0xE -asm/non_matchings/code/z_malloc/MainHeap_Check.s,MainHeap_Check,0x80102D98,0x9 -asm/non_matchings/code/z_malloc/MainHeap_Init.s,MainHeap_Init,0x80102DBC,0xC -asm/non_matchings/code/z_malloc/MainHeap_Cleanup.s,MainHeap_Cleanup,0x80102DEC,0x9 -asm/non_matchings/code/z_malloc/MainHeap_IsInitialized.s,MainHeap_IsInitialized,0x80102E10,0xC +asm/non_matchings/code/z_malloc/ZeldaArena_Malloc.s,ZeldaArena_Malloc,0x80102C60,0xA +asm/non_matchings/code/z_malloc/ZeldaArena_MallocR.s,ZeldaArena_MallocR,0x80102C88,0xA +asm/non_matchings/code/z_malloc/ZeldaArena_Realloc.s,ZeldaArena_Realloc,0x80102CB0,0xC +asm/non_matchings/code/z_malloc/ZeldaArena_Free.s,ZeldaArena_Free,0x80102CE0,0xA +asm/non_matchings/code/z_malloc/ZeldaArena_Calloc.s,ZeldaArena_Calloc,0x80102D08,0x16 +asm/non_matchings/code/z_malloc/ZeldaArena_GetSizes.s,ZeldaArena_GetSizes,0x80102D60,0xE +asm/non_matchings/code/z_malloc/ZeldaArena_Check.s,ZeldaArena_Check,0x80102D98,0x9 +asm/non_matchings/code/z_malloc/ZeldaArena_Init.s,ZeldaArena_Init,0x80102DBC,0xC +asm/non_matchings/code/z_malloc/ZeldaArena_Cleanup.s,ZeldaArena_Cleanup,0x80102DEC,0x9 +asm/non_matchings/code/z_malloc/ZeldaArena_IsInitialized.s,ZeldaArena_IsInitialized,0x80102E10,0xC asm/non_matchings/code/z_map_disp/func_80102E40.s,func_80102E40,0x80102E40,0x14 asm/non_matchings/code/z_map_disp/func_80102E90.s,func_80102E90,0x80102E90,0x5 asm/non_matchings/code/z_map_disp/func_80102EA4.s,func_80102EA4,0x80102EA4,0x4 @@ -1578,7 +1578,7 @@ asm/non_matchings/code/z_msgevent/func_8010BF58.s,func_8010BF58,0x8010BF58,0x5A asm/non_matchings/code/z_nmi_buff/Nmi_Init.s,Nmi_Init,0x8010C0C0,0x29 asm/non_matchings/code/z_nmi_buff/Nmi_SetPrenmiStart.s,Nmi_SetPrenmiStart,0x8010C164,0xE asm/non_matchings/code/z_nmi_buff/Nmi_GetPrenmiHasStarted.s,Nmi_GetPrenmiHasStarted,0x8010C19C,0x5 -asm/non_matchings/code/z_nmi_buff/func_8010C1B0.s,func_8010C1B0,0x8010C1B0,0x20 +asm/non_matchings/code/z_nmi_buff/MsgEvent_SendNullTask.s,MsgEvent_SendNullTask,0x8010C1B0,0x20 asm/non_matchings/code/z_olib/OLib_Vec3fDist.s,OLib_Vec3fDist,0x8010C230,0x11 asm/non_matchings/code/z_olib/OLib_Vec3fDistOutDiff.s,OLib_Vec3fDistOutDiff,0x8010C274,0x17 asm/non_matchings/code/z_olib/OLib_Vec3fDistXZ.s,OLib_Vec3fDistXZ,0x8010C2D0,0xD @@ -1633,8 +1633,8 @@ asm/non_matchings/code/z_parameter/func_801149A0.s,func_801149A0,0x801149A0,0x3F asm/non_matchings/code/z_parameter/func_80114A9C.s,func_80114A9C,0x80114A9C,0x3A asm/non_matchings/code/z_parameter/func_80114B84.s,func_80114B84,0x80114B84,0x47 asm/non_matchings/code/z_parameter/func_80114CA0.s,func_80114CA0,0x80114CA0,0x7C -asm/non_matchings/code/z_parameter/func_80114E90.s,func_80114E90,0x80114E90,0x27 -asm/non_matchings/code/z_parameter/func_80114F2C.s,func_80114F2C,0x80114F2C,0x29 +asm/non_matchings/code/z_parameter/Interface_HasEmptyBottle.s,Interface_HasEmptyBottle,0x80114E90,0x27 +asm/non_matchings/code/z_parameter/Interface_HasItemInBottle.s,Interface_HasItemInBottle,0x80114F2C,0x29 asm/non_matchings/code/z_parameter/func_80114FD0.s,func_80114FD0,0x80114FD0,0x58 asm/non_matchings/code/z_parameter/func_80115130.s,func_80115130,0x80115130,0x62 asm/non_matchings/code/z_parameter/func_801152B8.s,func_801152B8,0x801152B8,0x44 @@ -1705,7 +1705,7 @@ asm/non_matchings/code/z_player_lib/func_8012300C.s,func_8012300C,0x8012300C,0x4 asm/non_matchings/code/z_player_lib/func_8012301C.s,func_8012301C,0x8012301C,0x49 asm/non_matchings/code/z_player_lib/func_80123140.s,func_80123140,0x80123140,0x86 asm/non_matchings/code/z_player_lib/func_80123358.s,func_80123358,0x80123358,0x23 -asm/non_matchings/code/z_player_lib/func_801233E4.s,func_801233E4,0x801233E4,0xF +asm/non_matchings/code/z_player_lib/Player_InCsMode.s,Player_InCsMode,0x801233E4,0xF asm/non_matchings/code/z_player_lib/func_80123420.s,func_80123420,0x80123420,0x5 asm/non_matchings/code/z_player_lib/func_80123434.s,func_80123434,0x80123434,0x5 asm/non_matchings/code/z_player_lib/func_80123448.s,func_80123448,0x80123448,0x1A @@ -1720,7 +1720,7 @@ asm/non_matchings/code/z_player_lib/func_801239AC.s,func_801239AC,0x801239AC,0x3 asm/non_matchings/code/z_player_lib/func_80123AA4.s,func_80123AA4,0x80123AA4,0x4C asm/non_matchings/code/z_player_lib/func_80123BD4.s,func_80123BD4,0x80123BD4,0x21 asm/non_matchings/code/z_player_lib/func_80123C58.s,func_80123C58,0x80123C58,0xE -asm/non_matchings/code/z_player_lib/func_80123C90.s,func_80123C90,0x80123C90,0x30 +asm/non_matchings/code/z_player_lib/Player_SetEquipmentData.s,Player_SetEquipmentData,0x80123C90,0x30 asm/non_matchings/code/z_player_lib/func_80123D50.s,func_80123D50,0x80123D50,0x15 asm/non_matchings/code/z_player_lib/func_80123DA4.s,func_80123DA4,0x80123DA4,0x7 asm/non_matchings/code/z_player_lib/func_80123DC0.s,func_80123DC0,0x80123DC0,0x34 @@ -1743,7 +1743,7 @@ asm/non_matchings/code/z_player_lib/func_801241B4.s,func_801241B4,0x801241B4,0xB asm/non_matchings/code/z_player_lib/func_801241E0.s,func_801241E0,0x801241E0,0xB asm/non_matchings/code/z_player_lib/func_8012420C.s,func_8012420C,0x8012420C,0x8 asm/non_matchings/code/z_player_lib/func_8012422C.s,func_8012422C,0x8012422C,0xB -asm/non_matchings/code/z_player_lib/func_80124258.s,func_80124258,0x80124258,0x8 +asm/non_matchings/code/z_player_lib/Player_GetExplosiveHeld.s,Player_GetExplosiveHeld,0x80124258,0x8 asm/non_matchings/code/z_player_lib/func_80124278.s,func_80124278,0x80124278,0xF asm/non_matchings/code/z_player_lib/func_801242B4.s,func_801242B4,0x801242B4,0xA asm/non_matchings/code/z_player_lib/func_801242DC.s,func_801242DC,0x801242DC,0x51 @@ -1816,14 +1816,14 @@ asm/non_matchings/code/z_quake/Quake_Init.s,Quake_Init,0x8012AA48,0x15 asm/non_matchings/code/z_quake/Quake_Add.s,Quake_Add,0x8012AA9C,0x9 asm/non_matchings/code/z_quake/Quake_RemoveFromIdx.s,Quake_RemoveFromIdx,0x8012AAC0,0x12 asm/non_matchings/code/z_quake/Quake_Calc.s,Quake_Calc,0x8012AB08,0xD8 -asm/non_matchings/code/z_quake/Quake2_Init.s,Quake2_Init,0x8012AE68,0x11 -asm/non_matchings/code/z_quake/Quake2_SetCountdown.s,Quake2_SetCountdown,0x8012AEAC,0xA -asm/non_matchings/code/z_quake/Quake2_GetCountdown.s,Quake2_GetCountdown,0x8012AED4,0x4 -asm/non_matchings/code/z_quake/Quake2_GetType.s,Quake2_GetType,0x8012AEE4,0x4 -asm/non_matchings/code/z_quake/Quake2_SetType.s,Quake2_SetType,0x8012AEF4,0x9 -asm/non_matchings/code/z_quake/Quake2_ClearType.s,Quake2_ClearType,0x8012AF18,0x8 -asm/non_matchings/code/z_quake/Quake2_GetFloorQuake.s,Quake2_GetFloorQuake,0x8012AF38,0x19 -asm/non_matchings/code/z_quake/Quake2_Update.s,Quake2_Update,0x8012AF9C,0x313 +asm/non_matchings/code/z_quake/Distortion_Init.s,Distortion_Init,0x8012AE68,0x11 +asm/non_matchings/code/z_quake/Distortion_SetCountdown.s,Distortion_SetCountdown,0x8012AEAC,0xA +asm/non_matchings/code/z_quake/Distortion_GetCountdown.s,Distortion_GetCountdown,0x8012AED4,0x4 +asm/non_matchings/code/z_quake/Distortion_GetType.s,Distortion_GetType,0x8012AEE4,0x4 +asm/non_matchings/code/z_quake/Distortion_SetType.s,Distortion_SetType,0x8012AEF4,0x9 +asm/non_matchings/code/z_quake/Distortion_ClearType.s,Distortion_ClearType,0x8012AF18,0x8 +asm/non_matchings/code/z_quake/Distortion_GetUnderwaterCurrentSpeed.s,Distortion_GetUnderwaterCurrentSpeed,0x8012AF38,0x19 +asm/non_matchings/code/z_quake/Distortion_Update.s,Distortion_Update,0x8012AF9C,0x313 asm/non_matchings/code/z_quake/Quake_NumActiveQuakes.s,Quake_NumActiveQuakes,0x8012BBE8,0x1A asm/non_matchings/code/z_rcp/Gfx_SetFog.s,Gfx_SetFog,0x8012BC50,0x4F asm/non_matchings/code/z_rcp/Gfx_SetFogWithSync.s,Gfx_SetFogWithSync,0x8012BD8C,0x5F @@ -1919,16 +1919,16 @@ asm/non_matchings/code/z_room/Room_StartRoomTransition.s,Room_StartRoomTransitio asm/non_matchings/code/z_room/Room_HandleLoadCallbacks.s,Room_HandleLoadCallbacks,0x8012EAA8,0x40 asm/non_matchings/code/z_room/Room_Draw.s,Room_Draw,0x8012EBA8,0x14 asm/non_matchings/code/z_room/func_8012EBF8.s,func_8012EBF8,0x8012EBF8,0x22 -asm/non_matchings/code/code_8012EC80/func_8012EC80.s,func_8012EC80,0x8012EC80,0x2D -asm/non_matchings/code/code_8012EC80/func_8012ED34.s,func_8012ED34,0x8012ED34,0x11 -asm/non_matchings/code/code_8012EC80/func_8012ED78.s,func_8012ED78,0x8012ED78,0x1C -asm/non_matchings/code/code_8012EC80/func_8012EDE8.s,func_8012EDE8,0x8012EDE8,0x13 -asm/non_matchings/code/code_8012EC80/func_8012EE34.s,func_8012EE34,0x8012EE34,0x36 -asm/non_matchings/code/code_8012EC80/func_8012EF0C.s,func_8012EF0C,0x8012EF0C,0x78 -asm/non_matchings/code/code_8012EC80/func_8012F0EC.s,func_8012F0EC,0x8012F0EC,0x34 -asm/non_matchings/code/code_8012EC80/func_8012F1BC.s,func_8012F1BC,0x8012F1BC,0x1C -asm/non_matchings/code/code_8012EC80/func_8012F22C.s,func_8012F22C,0x8012F22C,0x13 -asm/non_matchings/code/code_8012EC80/func_8012F278.s,func_8012F278,0x8012F278,0x16 +asm/non_matchings/code/code_8012EC80/Inventory_GetBtnBItem.s,Inventory_GetBtnBItem,0x8012EC80,0x2D +asm/non_matchings/code/code_8012EC80/Inventory_ChangeEquipment.s,Inventory_ChangeEquipment,0x8012ED34,0x11 +asm/non_matchings/code/code_8012EC80/Inventory_DeleteEquipment.s,Inventory_DeleteEquipment,0x8012ED78,0x1C +asm/non_matchings/code/code_8012EC80/Inventory_ChangeUpgrade.s,Inventory_ChangeUpgrade,0x8012EDE8,0x13 +asm/non_matchings/code/code_8012EC80/Inventory_IsMapVisible.s,Inventory_IsMapVisible,0x8012EE34,0x36 +asm/non_matchings/code/code_8012EC80/Inventory_SetMapVisibility.s,Inventory_SetMapVisibility,0x8012EF0C,0x78 +asm/non_matchings/code/code_8012EC80/Inventory_SaveDekuPlaygroundHighScore.s,Inventory_SaveDekuPlaygroundHighScore,0x8012F0EC,0x34 +asm/non_matchings/code/code_8012EC80/Inventory_IncrementSkullTokenCount.s,Inventory_IncrementSkullTokenCount,0x8012F1BC,0x1C +asm/non_matchings/code/code_8012EC80/Inventory_GetSkullTokenCount.s,Inventory_GetSkullTokenCount,0x8012F22C,0x13 +asm/non_matchings/code/code_8012EC80/Inventory_SaveLotteryCodeGuess.s,Inventory_SaveLotteryCodeGuess,0x8012F278,0x16 asm/non_matchings/code/z_scene/Object_Spawn.s,Object_Spawn,0x8012F2E0,0x3C asm/non_matchings/code/z_scene/Object_InitBank.s,Object_InitBank,0x8012F3D0,0x4B asm/non_matchings/code/z_scene/Object_UpdateBank.s,Object_UpdateBank,0x8012F4FC,0x43 @@ -2041,8 +2041,8 @@ asm/non_matchings/code/z_skelanime/SkelAnime_DrawLimb.s,SkelAnime_DrawLimb,0x801 asm/non_matchings/code/z_skelanime/SkelAnime_Draw.s,SkelAnime_Draw,0x80133B3C,0x68 asm/non_matchings/code/z_skelanime/SkelAnime_DrawLimbSV.s,SkelAnime_DrawLimbSV,0x80133CDC,0x93 asm/non_matchings/code/z_skelanime/SkelAnime_DrawFlexOpa.s,SkelAnime_DrawFlexOpa,0x80133F28,0x88 -asm/non_matchings/code/z_skelanime/func_80134148.s,func_80134148,0x80134148,0x9E -asm/non_matchings/code/z_skelanime/func_801343C0.s,func_801343C0,0x801343C0,0x90 +asm/non_matchings/code/z_skelanime/SkelAnime_DrawTransformFlexLimbOpa.s,SkelAnime_DrawTransformFlexLimbOpa,0x80134148,0x9E +asm/non_matchings/code/z_skelanime/SkelAnime_DrawTransformFlexOpa.s,SkelAnime_DrawTransformFlexOpa,0x801343C0,0x90 asm/non_matchings/code/z_skelanime/SkelAnime_AnimateFrame.s,SkelAnime_AnimateFrame,0x80134600,0x49 asm/non_matchings/code/z_skelanime/SkelAnime_GetTotalFrames.s,SkelAnime_GetTotalFrames,0x80134724,0x9 asm/non_matchings/code/z_skelanime/Animation_GetLastFrame.s,Animation_GetLastFrame,0x80134748,0xB @@ -2050,62 +2050,62 @@ asm/non_matchings/code/z_skelanime/SkelAnime_Draw2Limb.s,SkelAnime_Draw2Limb,0x8 asm/non_matchings/code/z_skelanime/SkelAnime_Draw.s,SkelAnime_Draw,0x80134990,0x71 asm/non_matchings/code/z_skelanime/SkelAnime_DrawLimbSV2.s,SkelAnime_DrawLimbSV2,0x80134B54,0x9A asm/non_matchings/code/z_skelanime/SkelAnime_DrawFlex.s,SkelAnime_DrawFlex,0x80134DBC,0x90 -asm/non_matchings/code/z_skelanime/func_80134FFC.s,func_80134FFC,0x80134FFC,0xF6 -asm/non_matchings/code/z_skelanime/func_801353D4.s,func_801353D4,0x801353D4,0x9 +asm/non_matchings/code/z_skelanime/SkelAnime_GetFrameData2.s,SkelAnime_GetFrameData2,0x80134FFC,0xF6 +asm/non_matchings/code/z_skelanime/Animation_GetLimbCount2.s,Animation_GetLimbCount2,0x801353D4,0x9 asm/non_matchings/code/z_skelanime/SkelAnime_GetTotalFrames2.s,SkelAnime_GetTotalFrames2,0x801353F8,0x9 asm/non_matchings/code/z_skelanime/SkelAnime_GetFrameCount2.s,SkelAnime_GetFrameCount2,0x8013541C,0xB -asm/non_matchings/code/z_skelanime/SkelAnime_InterpolateVec3s.s,SkelAnime_InterpolateVec3s,0x80135448,0x120 -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationCtxReset.s,SkelAnime_AnimationCtxReset,0x801358C8,0x3 -asm/non_matchings/code/z_skelanime/func_801358D4.s,func_801358D4,0x801358D4,0x8 -asm/non_matchings/code/z_skelanime/func_801358F4.s,func_801358F4,0x801358F4,0xA -asm/non_matchings/code/z_skelanime/SkelAnime_NextEntry.s,SkelAnime_NextEntry,0x8013591C,0xE -asm/non_matchings/code/z_skelanime/SkelAnime_LoadLinkAnimetion.s,SkelAnime_LoadLinkAnimetion,0x80135954,0x35 -asm/non_matchings/code/z_skelanime/SkelAnime_LoadAnimationType1.s,SkelAnime_LoadAnimationType1,0x80135A28,0x1A -asm/non_matchings/code/z_skelanime/SkelAnime_LoadAnimationType2.s,SkelAnime_LoadAnimationType2,0x80135A90,0x1C -asm/non_matchings/code/z_skelanime/SkelAnime_LoadAnimationType3.s,SkelAnime_LoadAnimationType3,0x80135B00,0x1C -asm/non_matchings/code/z_skelanime/SkelAnime_LoadAnimationType4.s,SkelAnime_LoadAnimationType4,0x80135B70,0x1C -asm/non_matchings/code/z_skelanime/SkelAnime_LoadAnimationType5.s,SkelAnime_LoadAnimationType5,0x80135BE0,0x17 -asm/non_matchings/code/z_skelanime/SkelAnime_LinkAnimetionLoaded.s,SkelAnime_LinkAnimetionLoaded,0x80135C3C,0xC -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationType1Loaded.s,SkelAnime_AnimationType1Loaded,0x80135C6C,0x1C -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationType2Loaded.s,SkelAnime_AnimationType2Loaded,0x80135CDC,0x17 -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationType3Loaded.s,SkelAnime_AnimationType3Loaded,0x80135D38,0x20 -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationType4Loaded.s,SkelAnime_AnimationType4Loaded,0x80135DB8,0x21 -asm/non_matchings/code/z_skelanime/SkelAnime_AnimationType5Loaded.s,SkelAnime_AnimationType5Loaded,0x80135E3C,0x2B -asm/non_matchings/code/z_skelanime/func_80135EE8.s,func_80135EE8,0x80135EE8,0x28 +asm/non_matchings/code/z_skelanime/SkelAnime_InterpFrameTable.s,SkelAnime_InterpFrameTable,0x80135448,0x120 +asm/non_matchings/code/z_skelanime/AnimationContext_Reset.s,AnimationContext_Reset,0x801358C8,0x3 +asm/non_matchings/code/z_skelanime/AnimationContext_SetNextQueue.s,AnimationContext_SetNextQueue,0x801358D4,0x8 +asm/non_matchings/code/z_skelanime/AnimationContext_DisableQueue.s,AnimationContext_DisableQueue,0x801358F4,0xA +asm/non_matchings/code/z_skelanime/AnimationContext_AddEntry.s,AnimationContext_AddEntry,0x8013591C,0xE +asm/non_matchings/code/z_skelanime/AnimationContext_SetLoadFrame.s,AnimationContext_SetLoadFrame,0x80135954,0x35 +asm/non_matchings/code/z_skelanime/AnimationContext_SetCopyAll.s,AnimationContext_SetCopyAll,0x80135A28,0x1A +asm/non_matchings/code/z_skelanime/AnimationContext_SetInterp.s,AnimationContext_SetInterp,0x80135A90,0x1C +asm/non_matchings/code/z_skelanime/AnimationContext_SetCopyTrue.s,AnimationContext_SetCopyTrue,0x80135B00,0x1C +asm/non_matchings/code/z_skelanime/AnimationContext_SetCopyFalse.s,AnimationContext_SetCopyFalse,0x80135B70,0x1C +asm/non_matchings/code/z_skelanime/AnimationContext_SetMoveActor.s,AnimationContext_SetMoveActor,0x80135BE0,0x17 +asm/non_matchings/code/z_skelanime/AnimationContext_LoadFrame.s,AnimationContext_LoadFrame,0x80135C3C,0xC +asm/non_matchings/code/z_skelanime/AnimationContext_CopyAll.s,AnimationContext_CopyAll,0x80135C6C,0x1C +asm/non_matchings/code/z_skelanime/AnimationContext_CopyInterp.s,AnimationContext_CopyInterp,0x80135CDC,0x17 +asm/non_matchings/code/z_skelanime/AnimationContext_CopyTrue.s,AnimationContext_CopyTrue,0x80135D38,0x20 +asm/non_matchings/code/z_skelanime/AnimationContext_CopyFalse.s,AnimationContext_CopyFalse,0x80135DB8,0x21 +asm/non_matchings/code/z_skelanime/AnimationContext_MoveActor.s,AnimationContext_MoveActor,0x80135E3C,0x2B +asm/non_matchings/code/z_skelanime/AnimationContext_Update.s,AnimationContext_Update,0x80135EE8,0x28 asm/non_matchings/code/z_skelanime/SkelAnime_InitLinkAnimetion.s,SkelAnime_InitLinkAnimetion,0x80135F88,0x48 -asm/non_matchings/code/z_skelanime/func_801360A8.s,func_801360A8,0x801360A8,0xE -asm/non_matchings/code/z_skelanime/func_801360E0.s,func_801360E0,0x801360E0,0x9 -asm/non_matchings/code/z_skelanime/func_80136104.s,func_80136104,0x80136104,0x2E -asm/non_matchings/code/z_skelanime/func_801361BC.s,func_801361BC,0x801361BC,0x33 -asm/non_matchings/code/z_skelanime/func_80136288.s,func_80136288,0x80136288,0x25 -asm/non_matchings/code/z_skelanime/func_8013631C.s,func_8013631C,0x8013631C,0x35 -asm/non_matchings/code/z_skelanime/SkelAnime_SetTransition.s,SkelAnime_SetTransition,0x801363F0,0x9 -asm/non_matchings/code/z_skelanime/SkelAnime_ChangeLinkAnim.s,SkelAnime_ChangeLinkAnim,0x80136414,0x5E -asm/non_matchings/code/z_skelanime/SkelAnime_ChangeLinkAnimDefaultStop.s,SkelAnime_ChangeLinkAnimDefaultStop,0x8013658C,0x18 -asm/non_matchings/code/z_skelanime/SkelAnime_ChangeLinkAnimPlaybackStop.s,SkelAnime_ChangeLinkAnimPlaybackStop,0x801365EC,0x19 -asm/non_matchings/code/z_skelanime/SkelAnime_ChangeLinkAnimDefaultRepeat.s,SkelAnime_ChangeLinkAnimDefaultRepeat,0x80136650,0x17 -asm/non_matchings/code/z_skelanime/SkelAnime_ChangeLinkAnimPlaybackRepeat.s,SkelAnime_ChangeLinkAnimPlaybackRepeat,0x801366AC,0x18 -asm/non_matchings/code/z_skelanime/func_8013670C.s,func_8013670C,0x8013670C,0xC -asm/non_matchings/code/z_skelanime/func_8013673C.s,func_8013673C,0x8013673C,0xC -asm/non_matchings/code/z_skelanime/func_8013676C.s,func_8013676C,0x8013676C,0x11 -asm/non_matchings/code/z_skelanime/func_801367B0.s,func_801367B0,0x801367B0,0x11 -asm/non_matchings/code/z_skelanime/func_801367F4.s,func_801367F4,0x801367F4,0xE -asm/non_matchings/code/z_skelanime/func_8013682C.s,func_8013682C,0x8013682C,0x28 -asm/non_matchings/code/z_skelanime/func_801368CC.s,func_801368CC,0x801368CC,0x28 -asm/non_matchings/code/z_skelanime/SkelAnime_SetModeStop.s,SkelAnime_SetModeStop,0x8013696C,0x9 -asm/non_matchings/code/z_skelanime/func_80136990.s,func_80136990,0x80136990,0x2E -asm/non_matchings/code/z_skelanime/func_80136A48.s,func_80136A48,0x80136A48,0xD +asm/non_matchings/code/z_skelanime/LinkAnimation_SetUpdateFunction.s,LinkAnimation_SetUpdateFunction,0x801360A8,0xE +asm/non_matchings/code/z_skelanime/LinkAnimation_Update.s,LinkAnimation_Update,0x801360E0,0x9 +asm/non_matchings/code/z_skelanime/LinkAnimation_Morph.s,LinkAnimation_Morph,0x80136104,0x2E +asm/non_matchings/code/z_skelanime/LinkAnimation_AnimateFrame.s,LinkAnimation_AnimateFrame,0x801361BC,0x33 +asm/non_matchings/code/z_skelanime/LinkAnimation_Loop.s,LinkAnimation_Loop,0x80136288,0x25 +asm/non_matchings/code/z_skelanime/LinkAnimation_Once.s,LinkAnimation_Once,0x8013631C,0x35 +asm/non_matchings/code/z_skelanime/Animation_SetMorph.s,Animation_SetMorph,0x801363F0,0x9 +asm/non_matchings/code/z_skelanime/LinkAnimation_Change.s,LinkAnimation_Change,0x80136414,0x5E +asm/non_matchings/code/z_skelanime/LinkAnimation_ChangeDefaultStop.s,LinkAnimation_ChangeDefaultStop,0x8013658C,0x18 +asm/non_matchings/code/z_skelanime/LinkAnimation_ChangePlaybackStop.s,LinkAnimation_ChangePlaybackStop,0x801365EC,0x19 +asm/non_matchings/code/z_skelanime/LinkAnimation_ChangeDefaultRepeat.s,LinkAnimation_ChangeDefaultRepeat,0x80136650,0x17 +asm/non_matchings/code/z_skelanime/LinkAnimation_ChangePlaybackRepeat.s,LinkAnimation_ChangePlaybackRepeat,0x801366AC,0x18 +asm/non_matchings/code/z_skelanime/LinkAnimation_CopyJointToMorph.s,LinkAnimation_CopyJointToMorph,0x8013670C,0xC +asm/non_matchings/code/z_skelanime/LinkAnimation_CopyMorphToJoint.s,LinkAnimation_CopyMorphToJoint,0x8013673C,0xC +asm/non_matchings/code/z_skelanime/LinkAnimation_LoadToMorph.s,LinkAnimation_LoadToMorph,0x8013676C,0x11 +asm/non_matchings/code/z_skelanime/LinkAnimation_LoadToJoint.s,LinkAnimation_LoadToJoint,0x801367B0,0x11 +asm/non_matchings/code/z_skelanime/LinkAnimation_InterpJointMorph.s,LinkAnimation_InterpJointMorph,0x801367F4,0xE +asm/non_matchings/code/z_skelanime/LinkAnimation_BlendToJoint.s,LinkAnimation_BlendToJoint,0x8013682C,0x28 +asm/non_matchings/code/z_skelanime/LinkAnimation_BlendToMorph.s,LinkAnimation_BlendToMorph,0x801368CC,0x28 +asm/non_matchings/code/z_skelanime/LinkAnimation_EndLoop.s,LinkAnimation_EndLoop,0x8013696C,0x9 +asm/non_matchings/code/z_skelanime/Animation_OnFrameImpl.s,Animation_OnFrameImpl,0x80136990,0x2E +asm/non_matchings/code/z_skelanime/LinkAnimation_OnFrame.s,LinkAnimation_OnFrame,0x80136A48,0xD asm/non_matchings/code/z_skelanime/SkelAnime_Init.s,SkelAnime_Init,0x80136A7C,0x2D asm/non_matchings/code/z_skelanime/SkelAnime_InitFlex.s,SkelAnime_InitFlex,0x80136B30,0x2F asm/non_matchings/code/z_skelanime/SkelAnime_InitSkin.s,SkelAnime_InitSkin,0x80136BEC,0x26 -asm/non_matchings/code/z_skelanime/func_80136C84.s,func_80136C84,0x80136C84,0x13 +asm/non_matchings/code/z_skelanime/SkelAnime_SetUpdate.s,SkelAnime_SetUpdate,0x80136C84,0x13 asm/non_matchings/code/z_skelanime/SkelAnime_Update.s,SkelAnime_Update,0x80136CD0,0x9 -asm/non_matchings/code/z_skelanime/func_80136CF4.s,func_80136CF4,0x80136CF4,0x29 -asm/non_matchings/code/z_skelanime/func_80136D98.s,func_80136D98,0x80136D98,0x5B -asm/non_matchings/code/z_skelanime/func_80136F04.s,func_80136F04,0x80136F04,0x4A -asm/non_matchings/code/z_skelanime/func_8013702C.s,func_8013702C,0x8013702C,0x21 -asm/non_matchings/code/z_skelanime/func_801370B0.s,func_801370B0,0x801370B0,0x23 -asm/non_matchings/code/z_skelanime/func_8013713C.s,func_8013713C,0x8013713C,0x3C +asm/non_matchings/code/z_skelanime/SkelAnime_Morph.s,SkelAnime_Morph,0x80136CF4,0x29 +asm/non_matchings/code/z_skelanime/SkelAnime_MorphTaper.s,SkelAnime_MorphTaper,0x80136D98,0x5B +asm/non_matchings/code/z_skelanime/SkelAnime_AnimateFrame.s,SkelAnime_AnimateFrame,0x80136F04,0x4A +asm/non_matchings/code/z_skelanime/SkelAnime_LoopFull.s,SkelAnime_LoopFull,0x8013702C,0x21 +asm/non_matchings/code/z_skelanime/SkelAnime_LoopPartial.s,SkelAnime_LoopPartial,0x801370B0,0x23 +asm/non_matchings/code/z_skelanime/SkelAnime_Once.s,SkelAnime_Once,0x8013713C,0x3C asm/non_matchings/code/z_skelanime/Animation_ChangeImpl.s,Animation_ChangeImpl,0x8013722C,0x6F asm/non_matchings/code/z_skelanime/Animation_Change.s,Animation_Change,0x801373E8,0x12 asm/non_matchings/code/z_skelanime/Animation_PlayOnce.s,Animation_PlayOnce,0x80137430,0x16 @@ -2114,31 +2114,31 @@ asm/non_matchings/code/z_skelanime/Animation_PlayOnceSetSpeed.s,Animation_PlayOn asm/non_matchings/code/z_skelanime/Animation_PlayLoop.s,Animation_PlayLoop,0x80137540,0x15 asm/non_matchings/code/z_skelanime/Animation_MorphToLoop.s,Animation_MorphToLoop,0x80137594,0xE asm/non_matchings/code/z_skelanime/Animation_ChangePlaybackRepeat.s,Animation_ChangePlaybackRepeat,0x801375CC,0x16 -asm/non_matchings/code/z_skelanime/SkelAnime_AnimSetStop.s,SkelAnime_AnimSetStop,0x80137624,0xB -asm/non_matchings/code/z_skelanime/SkelAnime_AnimReverse.s,SkelAnime_AnimReverse,0x80137650,0x9 -asm/non_matchings/code/z_skelanime/func_80137674.s,func_80137674,0x80137674,0x1A -asm/non_matchings/code/z_skelanime/func_801376DC.s,func_801376DC,0x801376DC,0x1B -asm/non_matchings/code/z_skelanime/func_80137748.s,func_80137748,0x80137748,0x5C +asm/non_matchings/code/z_skelanime/Animation_EndLoop.s,Animation_EndLoop,0x80137624,0xB +asm/non_matchings/code/z_skelanime/Animation_Reverse.s,Animation_Reverse,0x80137650,0x9 +asm/non_matchings/code/z_skelanime/SkelAnime_CopyFrameTableTrue.s,SkelAnime_CopyFrameTableTrue,0x80137674,0x1A +asm/non_matchings/code/z_skelanime/SkelAnime_CopyFrameTableFalse.s,SkelAnime_CopyFrameTableFalse,0x801376DC,0x1B +asm/non_matchings/code/z_skelanime/SkelAnime_UpdateTranslation.s,SkelAnime_UpdateTranslation,0x80137748,0x5C asm/non_matchings/code/z_skelanime/Animation_OnFrame.s,Animation_OnFrame,0x801378B8,0xA asm/non_matchings/code/z_skelanime/SkelAnime_Free.s,SkelAnime_Free,0x801378E0,0x13 -asm/non_matchings/code/z_skelanime/SkelAnime_CopyVec3s.s,SkelAnime_CopyVec3s,0x8013792C,0x11 -asm/non_matchings/code/z_skin/func_80137970.s,func_80137970,0x80137970,0x71 -asm/non_matchings/code/z_skin/func_80137B34.s,func_80137B34,0x80137B34,0xE2 -asm/non_matchings/code/z_skin/func_80137EBC.s,func_80137EBC,0x80137EBC,0x27 -asm/non_matchings/code/z_skin/func_80137F58.s,func_80137F58,0x80137F58,0x3E -asm/non_matchings/code/z_skin/func_80138050.s,func_80138050,0x80138050,0x76 +asm/non_matchings/code/z_skelanime/SkelAnime_CopyFrameTable.s,SkelAnime_CopyFrameTable,0x8013792C,0x11 +asm/non_matchings/code/z_skin/Skin_UpdateVertices.s,Skin_UpdateVertices,0x80137970,0x71 +asm/non_matchings/code/z_skin/Skin_ApplyLimbModifications.s,Skin_ApplyLimbModifications,0x80137B34,0xE2 +asm/non_matchings/code/z_skin/Skin_DrawAnimatedLimb.s,Skin_DrawAnimatedLimb,0x80137EBC,0x27 +asm/non_matchings/code/z_skin/Skin_DrawLimb.s,Skin_DrawLimb,0x80137F58,0x3E +asm/non_matchings/code/z_skin/Skin_DrawImpl.s,Skin_DrawImpl,0x80138050,0x76 asm/non_matchings/code/z_skin/func_80138228.s,func_80138228,0x80138228,0xC asm/non_matchings/code/z_skin/func_80138258.s,func_80138258,0x80138258,0xD asm/non_matchings/code/z_skin/func_8013828C.s,func_8013828C,0x8013828C,0xE asm/non_matchings/code/z_skin/func_801382C4.s,func_801382C4,0x801382C4,0xF -asm/non_matchings/code/z_skin/func_80138300.s,func_80138300,0x80138300,0x17 -asm/non_matchings/code/z_skin/func_8013835C.s,func_8013835C,0x8013835C,0x2D -asm/non_matchings/code/z_skin_awb/func_80138410.s,func_80138410,0x80138410,0x5 -asm/non_matchings/code/z_skin_awb/func_80138424.s,func_80138424,0x80138424,0x5E -asm/non_matchings/code/z_skin_awb/func_8013859C.s,func_8013859C,0x8013859C,0x59 -asm/non_matchings/code/z_skin_awb/func_80138700.s,func_80138700,0x80138700,0x35 +asm/non_matchings/code/z_skin/Skin_GetLimbPos.s,Skin_GetLimbPos,0x80138300,0x17 +asm/non_matchings/code/z_skin/Skin_GetVertexPos.s,Skin_GetVertexPos,0x8013835C,0x2D +asm/non_matchings/code/z_skin_awb/Skin_Setup.s,Skin_Setup,0x80138410,0x5 +asm/non_matchings/code/z_skin_awb/Skin_InitAnimatedLimb.s,Skin_InitAnimatedLimb,0x80138424,0x5E +asm/non_matchings/code/z_skin_awb/Skin_Init.s,Skin_Init,0x8013859C,0x59 +asm/non_matchings/code/z_skin_awb/Skin_Free.s,Skin_Free,0x80138700,0x35 asm/non_matchings/code/z_skin_awb/func_801387D4.s,func_801387D4,0x801387D4,0x44 -asm/non_matchings/code/z_skin_awb/func_801388E4.s,func_801388E4,0x801388E4,0xAF +asm/non_matchings/code/z_skin_awb/Skin_ApplyAnimTransformations.s,Skin_ApplyAnimTransformations,0x801388E4,0xAF asm/non_matchings/code/z_skin_matrix/SkinMatrix_Vec3fMtxFMultXYZW.s,SkinMatrix_Vec3fMtxFMultXYZW,0x80138BA0,0x3A asm/non_matchings/code/z_skin_matrix/SkinMatrix_Vec3fMtxFMultXYZ.s,SkinMatrix_Vec3fMtxFMultXYZ,0x80138C88,0x2C asm/non_matchings/code/z_skin_matrix/SkinMatrix_MtxFMtxFMult.s,SkinMatrix_MtxFMtxFMult,0x80138D38,0xD7 @@ -2169,61 +2169,61 @@ 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/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 -asm/non_matchings/code/z_sub_s/func_8013AD9C.s,func_8013AD9C,0x8013AD9C,0x4E -asm/non_matchings/code/z_sub_s/func_8013AED4.s,func_8013AED4,0x8013AED4,0xB +asm/non_matchings/code/z_sub_s/SubS_FindDoor.s,SubS_FindDoor,0x8013A7C0,0x28 +asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlexLimb.s,SubS_DrawTransformFlexLimb,0x8013A860,0xA8 +asm/non_matchings/code/z_sub_s/SubS_DrawTransformFlex.s,SubS_DrawTransformFlex,0x8013AB00,0x9B +asm/non_matchings/code/z_sub_s/SubS_InCsMode.s,SubS_InCsMode,0x8013AD6C,0xC +asm/non_matchings/code/z_sub_s/SubS_UpdateLimb.s,SubS_UpdateLimb,0x8013AD9C,0x4E +asm/non_matchings/code/z_sub_s/SubS_UpdateFlags.s,SubS_UpdateFlags,0x8013AED4,0xB asm/non_matchings/code/z_sub_s/func_8013AF00.s,func_8013AF00,0x8013AF00,0x44 asm/non_matchings/code/z_sub_s/func_8013B010.s,func_8013B010,0x8013B010,0x2E asm/non_matchings/code/z_sub_s/func_8013B0C8.s,func_8013B0C8,0x8013B0C8,0xA2 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/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 +asm/non_matchings/code/z_sub_s/SubS_GetAdditionalPath.s,SubS_GetAdditionalPath,0x8013BB34,0x12 +asm/non_matchings/code/z_sub_s/SubS_FindNearestActor.s,SubS_FindNearestActor,0x8013BB7C,0x3C +asm/non_matchings/code/z_sub_s/SubS_ChangeAnimationByInfoS.s,SubS_ChangeAnimationByInfoS,0x8013BC6C,0x35 +asm/non_matchings/code/z_sub_s/SubS_HasReachedPoint.s,SubS_HasReachedPoint,0x8013BD40,0x67 +asm/non_matchings/code/z_sub_s/SubS_GetDayDependentPath.s,SubS_GetDayDependentPath,0x8013BEDC,0x63 asm/non_matchings/code/z_sub_s/func_8013C068.s,func_8013C068,0x8013C068,0x16F asm/non_matchings/code/z_sub_s/func_8013C624.s,func_8013C624,0x8013C624,0xA5 -asm/non_matchings/code/z_sub_s/func_8013C8B8.s,func_8013C8B8,0x8013C8B8,0x2B +asm/non_matchings/code/z_sub_s/SubS_CopyPointFromPathCheckBounds.s,SubS_CopyPointFromPathCheckBounds,0x8013C8B8,0x2B asm/non_matchings/code/z_sub_s/func_8013C964.s,func_8013C964,0x8013C964,0xB2 -asm/non_matchings/code/z_sub_s/func_8013CC2C.s,func_8013CC2C,0x8013CC2C,0x4E -asm/non_matchings/code/z_sub_s/func_8013CD64.s,func_8013CD64,0x8013CD64,0x68 -asm/non_matchings/code/z_sub_s/func_8013CF04.s,func_8013CF04,0x8013CF04,0x77 -asm/non_matchings/code/z_sub_s/func_8013D0E0.s,func_8013D0E0,0x8013D0E0,0x80 -asm/non_matchings/code/z_sub_s/func_8013D2E0.s,func_8013D2E0,0x8013D2E0,0xC2 -asm/non_matchings/code/z_sub_s/func_8013D5E8.s,func_8013D5E8,0x8013D5E8,0x18 -asm/non_matchings/code/z_sub_s/func_8013D648.s,func_8013D648,0x8013D648,0x11 -asm/non_matchings/code/z_sub_s/func_8013D68C.s,func_8013D68C,0x8013D68C,0x25 -asm/non_matchings/code/z_sub_s/func_8013D720.s,func_8013D720,0x8013D720,0x12 -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/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 -asm/non_matchings/code/z_sub_s/func_8013DCCC.s,func_8013DCCC,0x8013DCCC,0x5 -asm/non_matchings/code/z_sub_s/func_8013DCE0.s,func_8013DCE0,0x8013DCE0,0x49 -asm/non_matchings/code/z_sub_s/func_8013DE04.s,func_8013DE04,0x8013DE04,0x4E -asm/non_matchings/code/z_sub_s/func_8013DF3C.s,func_8013DF3C,0x8013DF3C,0x46 -asm/non_matchings/code/z_sub_s/func_8013E054.s,func_8013E054,0x8013E054,0xA -asm/non_matchings/code/z_sub_s/func_8013E07C.s,func_8013E07C,0x8013E07C,0xA -asm/non_matchings/code/z_sub_s/func_8013E0A4.s,func_8013E0A4,0x8013E0A4,0x49 -asm/non_matchings/code/z_sub_s/func_8013E1C8.s,func_8013E1C8,0x8013E1C8,0x43 -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_FillShadowTex.s,SubS_FillShadowTex,0x8013CC2C,0x4E +asm/non_matchings/code/z_sub_s/SubS_GenShadowTex.s,SubS_GenShadowTex,0x8013CD64,0x68 +asm/non_matchings/code/z_sub_s/SubS_DrawShadowTex.s,SubS_DrawShadowTex,0x8013CF04,0x77 +asm/non_matchings/code/z_sub_s/SubS_ComputeTurnToPointRot.s,SubS_ComputeTurnToPointRot,0x8013D0E0,0x80 +asm/non_matchings/code/z_sub_s/SubS_TurnToPoint.s,SubS_TurnToPoint,0x8013D2E0,0xC2 +asm/non_matchings/code/z_sub_s/SubS_AngleDiffLessEqual.s,SubS_AngleDiffLessEqual,0x8013D5E8,0x18 +asm/non_matchings/code/z_sub_s/SubS_GetPathByIndex.s,SubS_GetPathByIndex,0x8013D648,0x11 +asm/non_matchings/code/z_sub_s/SubS_CopyPointFromPath.s,SubS_CopyPointFromPath,0x8013D68C,0x25 +asm/non_matchings/code/z_sub_s/SubS_GetDistSqAndOrientPoints.s,SubS_GetDistSqAndOrientPoints,0x8013D720,0x12 +asm/non_matchings/code/z_sub_s/SubS_MoveActorToPoint.s,SubS_MoveActorToPoint,0x8013D768,0x35 +asm/non_matchings/code/z_sub_s/SubS_GetDistSqAndOrientPath.s,SubS_GetDistSqAndOrientPath,0x8013D83C,0x28 +asm/non_matchings/code/z_sub_s/SubS_IsObjectLoaded.s,SubS_IsObjectLoaded,0x8013D8DC,0x12 +asm/non_matchings/code/z_sub_s/SubS_GetObjectIndex.s,SubS_GetObjectIndex,0x8013D924,0xF +asm/non_matchings/code/z_sub_s/SubS_FindActor.s,SubS_FindActor,0x8013D960,0x1A +asm/non_matchings/code/z_sub_s/SubS_FillLimbRotTables.s,SubS_FillLimbRotTables,0x8013D9C8,0x72 +asm/non_matchings/code/z_sub_s/SubS_IsFloorAbove.s,SubS_IsFloorAbove,0x8013DB90,0x2C +asm/non_matchings/code/z_sub_s/SubS_CopyPointFromPathList.s,SubS_CopyPointFromPathList,0x8013DC40,0x23 +asm/non_matchings/code/z_sub_s/SubS_GetPathCount.s,SubS_GetPathCount,0x8013DCCC,0x5 +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_Init.s,SubS_ActorPathing_Init,0x8013DCE0,0x49 +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_Update.s,SubS_ActorPathing_Update,0x8013DE04,0x4E +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_ComputePointInfo.s,SubS_ActorPathing_ComputePointInfo,0x8013DF3C,0x46 +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_MoveWithGravity.s,SubS_ActorPathing_MoveWithGravity,0x8013E054,0xA +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_MoveWithoutGravityReverse.s,SubS_ActorPathing_MoveWithoutGravityReverse,0x8013E07C,0xA +asm/non_matchings/code/z_sub_s/SubS_ActorPathing_SetNextPoint.s,SubS_ActorPathing_SetNextPoint,0x8013E0A4,0x49 +asm/non_matchings/code/z_sub_s/SubS_ChangeAnimationBySpeedInfo.s,SubS_ChangeAnimationBySpeedInfo,0x8013E1C8,0x43 +asm/non_matchings/code/z_sub_s/SubS_StartActorCutscene.s,SubS_StartActorCutscene,0x8013E2D4,0x39 +asm/non_matchings/code/z_sub_s/SubS_FillCutscenesList.s,SubS_FillCutscenesList,0x8013E3B8,0x3E +asm/non_matchings/code/z_sub_s/SubS_ConstructPlane.s,SubS_ConstructPlane,0x8013E4B0,0x47 +asm/non_matchings/code/z_sub_s/SubS_LineSegVsPlane.s,SubS_LineSegVsPlane,0x8013E5CC,0x1D +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/SubS_ActorAndPlayerFaceEachOther.s,SubS_ActorAndPlayerFaceEachOther,0x8013E7C0,0x4E asm/non_matchings/code/z_sub_s/func_8013E8F8.s,func_8013E8F8,0x8013E8F8,0x16 -asm/non_matchings/code/z_sub_s/func_8013E950.s,func_8013E950,0x8013E950,0xB0 +asm/non_matchings/code/z_sub_s/SubS_TurnToPointStep.s,SubS_TurnToPointStep,0x8013E950,0xB0 asm/non_matchings/code/code_8013EC10/func_8013EC10.s,func_8013EC10,0x8013EC10,0xD asm/non_matchings/code/code_8013EC10/func_8013EC44.s,func_8013EC44,0x8013EC44,0x27 asm/non_matchings/code/code_8013EC10/func_8013ECE0.s,func_8013ECE0,0x8013ECE0,0x2F @@ -2248,13 +2248,13 @@ asm/non_matchings/code/z_view/View_GetViewport.s,View_GetViewport,0x8013F1B0,0xA asm/non_matchings/code/z_view/View_WriteScissor.s,View_WriteScissor,0x8013F1D8,0x2D asm/non_matchings/code/z_view/View_SyncAndWriteScissor.s,View_SyncAndWriteScissor,0x8013F28C,0x1B asm/non_matchings/code/z_view/View_SetScissorForLetterbox.s,View_SetScissorForLetterbox,0x8013F2F8,0x40 -asm/non_matchings/code/z_view/View_SetQuakeRotation.s,View_SetQuakeRotation,0x8013F3F8,0xA -asm/non_matchings/code/z_view/View_SetQuakeScale.s,View_SetQuakeScale,0x8013F420,0xA -asm/non_matchings/code/z_view/View_SetQuakeSpeed.s,View_SetQuakeSpeed,0x8013F448,0x5 -asm/non_matchings/code/z_view/View_InitCameraQuake.s,View_InitCameraQuake,0x8013F45C,0x19 -asm/non_matchings/code/z_view/View_ClearQuake.s,View_ClearQuake,0x8013F4C0,0xD -asm/non_matchings/code/z_view/View_SetQuake.s,View_SetQuake,0x8013F4F4,0x16 -asm/non_matchings/code/z_view/View_StepQuake.s,View_StepQuake,0x8013F54C,0x6C +asm/non_matchings/code/z_view/View_SetDistortionDirRot.s,View_SetDistortionDirRot,0x8013F3F8,0xA +asm/non_matchings/code/z_view/View_SetDistortionScale.s,View_SetDistortionScale,0x8013F420,0xA +asm/non_matchings/code/z_view/View_SetDistortionSpeed.s,View_SetDistortionSpeed,0x8013F448,0x5 +asm/non_matchings/code/z_view/View_InitDistortion.s,View_InitDistortion,0x8013F45C,0x19 +asm/non_matchings/code/z_view/View_ClearDistortion.s,View_ClearDistortion,0x8013F4C0,0xD +asm/non_matchings/code/z_view/View_SetDistortion.s,View_SetDistortion,0x8013F4F4,0x16 +asm/non_matchings/code/z_view/View_StepDistortion.s,View_StepDistortion,0x8013F54C,0x6C asm/non_matchings/code/z_view/View_RenderView.s,View_RenderView,0x8013F6FC,0x13 asm/non_matchings/code/z_view/View_RenderToPerspectiveMatrix.s,View_RenderToPerspectiveMatrix,0x8013F748,0xB5 asm/non_matchings/code/z_view/View_RenderToOrthographicMatrix.s,View_RenderToOrthographicMatrix,0x8013FA1C,0x6B @@ -2301,30 +2301,30 @@ asm/non_matchings/code/z_vr_box_draw/func_801435A0.s,func_801435A0,0x801435A0,0x asm/non_matchings/code/z_vr_box_draw/func_80143624.s,func_80143624,0x80143624,0x11 asm/non_matchings/code/z_vr_box_draw/func_80143668.s,func_80143668,0x80143668,0xE7 asm/non_matchings/code/z_vr_box_draw/func_80143A04.s,func_80143A04,0x80143A04,0x3 -asm/non_matchings/code/z_sram_NES/func_80143A10.s,func_80143A10,0x80143A10,0x11 -asm/non_matchings/code/z_sram_NES/func_80143A54.s,func_80143A54,0x80143A54,0x1C -asm/non_matchings/code/z_sram_NES/func_80143AC4.s,func_80143AC4,0x80143AC4,0x12 -asm/non_matchings/code/z_sram_NES/func_80143B0C.s,func_80143B0C,0x80143B0C,0x29A +asm/non_matchings/code/z_sram_NES/Sram_ActivateOwl.s,Sram_ActivateOwl,0x80143A10,0x11 +asm/non_matchings/code/z_sram_NES/Sram_ClearHighscores.s,Sram_ClearHighscores,0x80143A54,0x1C +asm/non_matchings/code/z_sram_NES/Sram_ClearFlagsAtDawnOfTheFirstDay.s,Sram_ClearFlagsAtDawnOfTheFirstDay,0x80143AC4,0x12 +asm/non_matchings/code/z_sram_NES/Sram_SaveEndOfCycle.s,Sram_SaveEndOfCycle,0x80143B0C,0x29A asm/non_matchings/code/z_sram_NES/Sram_IncrementDay.s,Sram_IncrementDay,0x80144574,0x1C asm/non_matchings/code/z_sram_NES/Sram_CalcChecksum.s,Sram_CalcChecksum,0x801445E4,0x11 -asm/non_matchings/code/z_sram_NES/func_80144628.s,func_80144628,0x80144628,0x17 +asm/non_matchings/code/z_sram_NES/Sram_ResetSave.s,Sram_ResetSave,0x80144628,0x17 asm/non_matchings/code/z_sram_NES/Sram_GenerateRandomSaveFields.s,Sram_GenerateRandomSaveFields,0x80144684,0x83 asm/non_matchings/code/z_sram_NES/func_80144890.s,func_80144890,0x80144890,0x36 asm/non_matchings/code/z_sram_NES/Sram_InitDebugSave.s,Sram_InitDebugSave,0x80144968,0x4B asm/non_matchings/code/z_sram_NES/func_80144A94.s,func_80144A94,0x80144A94,0xF9 -asm/non_matchings/code/z_sram_NES/func_80144E78.s,func_80144E78,0x80144E78,0x17D +asm/non_matchings/code/z_sram_NES/Sram_OpenSave.s,Sram_OpenSave,0x80144E78,0x17D asm/non_matchings/code/z_sram_NES/func_8014546C.s,func_8014546C,0x8014546C,0x8B asm/non_matchings/code/z_sram_NES/func_80145698.s,func_80145698,0x80145698,0x4D asm/non_matchings/code/z_sram_NES/func_801457CC.s,func_801457CC,0x801457CC,0x36D asm/non_matchings/code/z_sram_NES/func_80146580.s,func_80146580,0x80146580,0x2A asm/non_matchings/code/z_sram_NES/func_80146628.s,func_80146628,0x80146628,0x11E -asm/non_matchings/code/z_sram_NES/func_80146AA0.s,func_80146AA0,0x80146AA0,0xD6 +asm/non_matchings/code/z_sram_NES/Sram_InitSave.s,Sram_InitSave,0x80146AA0,0xD6 asm/non_matchings/code/z_sram_NES/func_80146DF8.s,func_80146DF8,0x80146DF8,0x12 -asm/non_matchings/code/z_sram_NES/func_80146E40.s,func_80146E40,0x80146E40,0xC +asm/non_matchings/code/z_sram_NES/Sram_InitSram.s,Sram_InitSram,0x80146E40,0xC asm/non_matchings/code/z_sram_NES/Sram_Alloc.s,Sram_Alloc,0x80146E70,0x13 asm/non_matchings/code/z_sram_NES/func_80146EBC.s,func_80146EBC,0x80146EBC,0xB -asm/non_matchings/code/z_sram_NES/func_80146EE8.s,func_80146EE8,0x80146EE8,0x1D -asm/non_matchings/code/z_sram_NES/func_80146F5C.s,func_80146F5C,0x80146F5C,0x2B +asm/non_matchings/code/z_sram_NES/Sram_SaveSpecialEnterClockTown.s,Sram_SaveSpecialEnterClockTown,0x80146EE8,0x1D +asm/non_matchings/code/z_sram_NES/Sram_SaveSpecialNewDay.s,Sram_SaveSpecialNewDay,0x80146F5C,0x2B asm/non_matchings/code/z_sram_NES/func_80147008.s,func_80147008,0x80147008,0x6 asm/non_matchings/code/z_sram_NES/func_80147020.s,func_80147020,0x80147020,0x12 asm/non_matchings/code/z_sram_NES/func_80147068.s,func_80147068,0x80147068,0x34 @@ -2336,8 +2336,8 @@ asm/non_matchings/code/z_sram_NES/func_80147414.s,func_80147414,0x80147414,0x3E asm/non_matchings/code/z_sram_NES/Sram_nop8014750C.s,Sram_nop8014750C,0x8014750C,0x5 asm/non_matchings/code/z_message/func_80147520.s,func_80147520,0x80147520,0x11 asm/non_matchings/code/z_message/func_80147564.s,func_80147564,0x80147564,0x30 -asm/non_matchings/code/z_message/func_80147624.s,func_80147624,0x80147624,0x44 -asm/non_matchings/code/z_message/func_80147734.s,func_80147734,0x80147734,0x20 +asm/non_matchings/code/z_message/Message_ShouldAdvance.s,Message_ShouldAdvance,0x80147624,0x44 +asm/non_matchings/code/z_message/Message_ShouldAdvanceSilent.s,Message_ShouldAdvanceSilent,0x80147734,0x20 asm/non_matchings/code/z_message/func_801477B4.s,func_801477B4,0x801477B4,0x19 asm/non_matchings/code/z_message/func_80147818.s,func_80147818,0x80147818,0x1C0 asm/non_matchings/code/z_message/func_80147F18.s,func_80147F18,0x80147F18,0x190 @@ -2351,12 +2351,12 @@ asm/non_matchings/code/z_message/func_80149454.s,func_80149454,0x80149454,0x9D asm/non_matchings/code/z_message/func_801496C8.s,func_801496C8,0x801496C8,0xA5 asm/non_matchings/code/z_message/func_8014995C.s,func_8014995C,0x8014995C,0xAF asm/non_matchings/code/z_message/func_80149C18.s,func_80149C18,0x80149C18,0xA9 -asm/non_matchings/code/z_message/func_80149EBC.s,func_80149EBC,0x80149EBC,0x2E +asm/non_matchings/code/z_message/Message_FindMessage.s,Message_FindMessage,0x80149EBC,0x2E asm/non_matchings/code/z_message/func_80149F74.s,func_80149F74,0x80149F74,0x2D7 asm/non_matchings/code/z_message/func_8014AAD0.s,func_8014AAD0,0x8014AAD0,0xBB asm/non_matchings/code/z_message/func_8014ADBC.s,func_8014ADBC,0x8014ADBC,0x654 asm/non_matchings/code/z_message/func_8014C70C.s,func_8014C70C,0x8014C70C,0x142 -asm/non_matchings/code/z_message/func_8014CC14.s,func_8014CC14,0x8014CC14,0x28 +asm/non_matchings/code/z_message/Message_LoadChar.s,Message_LoadChar,0x8014CC14,0x28 asm/non_matchings/code/z_message/func_8014CCB4.s,func_8014CCB4,0x8014CCB4,0x4F asm/non_matchings/code/z_message/func_8014CDF0.s,func_8014CDF0,0x8014CDF0,0x7B asm/non_matchings/code/z_message/func_8014CFDC.s,func_8014CFDC,0x8014CFDC,0xCA @@ -2366,7 +2366,7 @@ asm/non_matchings/code/z_message/func_8014D7B4.s,func_8014D7B4,0x8014D7B4,0xCB4 asm/non_matchings/code/z_message/func_80150A84.s,func_80150A84,0x80150A84,0xA1 asm/non_matchings/code/z_message/func_80150D08.s,func_80150D08,0x80150D08,0x1EA asm/non_matchings/code/z_message/func_801514B0.s,func_801514B0,0x801514B0,0x100 -asm/non_matchings/code/z_message/func_801518B0.s,func_801518B0,0x801518B0,0x22 +asm/non_matchings/code/z_message/Message_StartTextbox.s,Message_StartTextbox,0x801518B0,0x22 asm/non_matchings/code/z_message/func_80151938.s,func_80151938,0x80151938,0x4C asm/non_matchings/code/z_message/func_80151A68.s,func_80151A68,0x80151A68,0x53 asm/non_matchings/code/z_message/func_80151BB4.s,func_80151BB4,0x80151BB4,0x3A @@ -2374,7 +2374,7 @@ asm/non_matchings/code/z_message/func_80151C9C.s,func_80151C9C,0x80151C9C,0x42 asm/non_matchings/code/z_message/func_80151DA4.s,func_80151DA4,0x80151DA4,0x1A4 asm/non_matchings/code/z_message/func_80152434.s,func_80152434,0x80152434,0xC asm/non_matchings/code/z_message/func_80152464.s,func_80152464,0x80152464,0xD -asm/non_matchings/code/z_message/func_80152498.s,func_80152498,0x80152498,0x7D +asm/non_matchings/code/z_message/Message_GetState.s,Message_GetState,0x80152498,0x7D asm/non_matchings/code/z_message/func_8015268C.s,func_8015268C,0x8015268C,0x176 asm/non_matchings/code/z_message/func_80152C64.s,func_80152C64,0x80152C64,0x12 asm/non_matchings/code/z_message/func_80152CAC.s,func_80152CAC,0x80152CAC,0x85 @@ -2388,24 +2388,24 @@ asm/non_matchings/code/z_message/func_80156758.s,func_80156758,0x80156758,0x2D asm/non_matchings/code/z_message/func_8015680C.s,func_8015680C,0x8015680C,0x7A6 asm/non_matchings/code/z_message/func_801586A4.s,func_801586A4,0x801586A4,0xC asm/non_matchings/code/z_message/Message_Init.s,Message_Init,0x801586D4,0x7F -asm/non_matchings/code/z_message_nes/func_801588D0.s,func_801588D0,0x801588D0,0x2E -asm/non_matchings/code/z_message_nes/func_80158988.s,func_80158988,0x80158988,0x27 -asm/non_matchings/code/z_message_nes/func_80158A24.s,func_80158A24,0x80158A24,0x78 -asm/non_matchings/code/z_message_nes/func_80158C04.s,func_80158C04,0x80158C04,0x65 -asm/non_matchings/code/z_message_nes/func_80158D98.s,func_80158D98,0x80158D98,0x86 -asm/non_matchings/code/z_message_nes/func_80158FB0.s,func_80158FB0,0x80158FB0,0xAF -asm/non_matchings/code/z_message_nes/func_8015926C.s,func_8015926C,0x8015926C,0x73 +asm/non_matchings/code/z_message_nes/Message_FindMessageNES.s,Message_FindMessageNES,0x801588D0,0x2E +asm/non_matchings/code/z_message_nes/Message_LoadCharNES.s,Message_LoadCharNES,0x80158988,0x27 +asm/non_matchings/code/z_message_nes/Message_LoadPluralRupeesNES.s,Message_LoadPluralRupeesNES,0x80158A24,0x78 +asm/non_matchings/code/z_message_nes/Message_LoadLocalizedRupeesNES.s,Message_LoadLocalizedRupeesNES,0x80158C04,0x65 +asm/non_matchings/code/z_message_nes/Message_LoadRupeesNES.s,Message_LoadRupeesNES,0x80158D98,0x86 +asm/non_matchings/code/z_message_nes/Message_LoadTimeNES.s,Message_LoadTimeNES,0x80158FB0,0xAF +asm/non_matchings/code/z_message_nes/Message_LoadAreaTextNES.s,Message_LoadAreaTextNES,0x8015926C,0x73 asm/non_matchings/code/z_message_nes/func_80159438.s,func_80159438,0x80159438,0x8D asm/non_matchings/code/z_message_nes/func_8015966C.s,func_8015966C,0x8015966C,0x6CB asm/non_matchings/code/z_message_nes/func_8015B198.s,func_8015B198,0x8015B198,0xD6E -asm/non_matchings/code/z_message_staff/func_8015E750.s,func_8015E750,0x8015E750,0x27 +asm/non_matchings/code/z_message_staff/Message_FindCreditsMessage.s,Message_FindCreditsMessage,0x8015E750,0x27 asm/non_matchings/code/z_message_staff/func_8015E7EC.s,func_8015E7EC,0x8015E7EC,0x42F asm/non_matchings/code/z_message_staff/func_8015F8A8.s,func_8015F8A8,0x8015F8A8,0x47A -asm/non_matchings/code/z_player_call/func_80160A90.s,func_80160A90,0x80160A90,0x1A -asm/non_matchings/code/z_player_call/func_80160AF8.s,func_80160AF8,0x80160AF8,0x12 -asm/non_matchings/code/z_player_call/func_80160B40.s,func_80160B40,0x80160B40,0x10 -asm/non_matchings/code/z_player_call/func_80160B80.s,func_80160B80,0x80160B80,0x10 -asm/non_matchings/code/z_player_call/func_80160BC0.s,func_80160BC0,0x80160BC0,0x10 +asm/non_matchings/code/z_player_call/PlayerCall_InitFuncPtrs.s,PlayerCall_InitFuncPtrs,0x80160A90,0x1A +asm/non_matchings/code/z_player_call/PlayerCall_Init.s,PlayerCall_Init,0x80160AF8,0x12 +asm/non_matchings/code/z_player_call/PlayerCall_Destroy.s,PlayerCall_Destroy,0x80160B40,0x10 +asm/non_matchings/code/z_player_call/PlayerCall_Update.s,PlayerCall_Update,0x80160B80,0x10 +asm/non_matchings/code/z_player_call/PlayerCall_Draw.s,PlayerCall_Draw,0x80160BC0,0x10 asm/non_matchings/code/z_shrink_window/ShrinkWindow_SetLetterboxTarget.s,ShrinkWindow_SetLetterboxTarget,0x80160C00,0x5 asm/non_matchings/code/z_shrink_window/ShrinkWindow_GetLetterboxTarget.s,ShrinkWindow_GetLetterboxTarget,0x80160C14,0x5 asm/non_matchings/code/z_shrink_window/ShrinkWindow_SetLetterboxMagnitude.s,ShrinkWindow_SetLetterboxMagnitude,0x80160C28,0x5 @@ -2415,8 +2415,8 @@ asm/non_matchings/code/z_shrink_window/ShrinkWindow_GetPillarboxTarget.s,ShrinkW asm/non_matchings/code/z_shrink_window/ShrinkWindow_SetPillarboxMagnitude.s,ShrinkWindow_SetPillarboxMagnitude,0x80160C78,0x5 asm/non_matchings/code/z_shrink_window/ShrinkWindow_GetPillarboxMagnitude.s,ShrinkWindow_GetPillarboxMagnitude,0x80160C8C,0x5 asm/non_matchings/code/z_shrink_window/ShrinkWindow_Init.s,ShrinkWindow_Init,0x80160CA0,0xD -asm/non_matchings/code/z_shrink_window/ShrinkWindow_Fini.s,ShrinkWindow_Fini,0x80160CD4,0x4 -asm/non_matchings/code/z_shrink_window/ShrinkWindow_Step.s,ShrinkWindow_Step,0x80160CE4,0x2D +asm/non_matchings/code/z_shrink_window/ShrinkWindow_Destroy.s,ShrinkWindow_Destroy,0x80160CD4,0x4 +asm/non_matchings/code/z_shrink_window/ShrinkWindow_Update.s,ShrinkWindow_Update,0x80160CE4,0x2D asm/non_matchings/code/z_shrink_window/ShrinkWindow_Draw.s,ShrinkWindow_Draw,0x80160D98,0xFA asm/non_matchings/code/db_camera/func_80161180.s,func_80161180,0x80161180,0x7 asm/non_matchings/code/db_camera/func_8016119C.s,func_8016119C,0x8016119C,0x24 @@ -2509,10 +2509,10 @@ 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 +asm/non_matchings/code/z_play/Play_InCsMode.s,Play_InCsMode,0x801690CC,0xD asm/non_matchings/code/z_play/func_80169100.s,func_80169100,0x80169100,0x3C asm/non_matchings/code/z_play/func_801691F0.s,func_801691F0,0x801691F0,0xC asm/non_matchings/code/z_play/Play_LoadScene.s,Play_LoadScene,0x80169220,0x17 @@ -2520,28 +2520,28 @@ asm/non_matchings/code/z_play/func_8016927C.s,func_8016927C,0x8016927C,0x12 asm/non_matchings/code/z_play/func_801692C4.s,func_801692C4,0x801692C4,0x44 asm/non_matchings/code/z_play/Play_SceneInit.s,Play_SceneInit,0x801693D4,0x28 asm/non_matchings/code/z_play/func_80169474.s,func_80169474,0x80169474,0x1A -asm/non_matchings/code/z_play/func_801694DC.s,func_801694DC,0x801694DC,0x2A -asm/non_matchings/code/z_play/Play_GetActiveCameraIndex.s,Play_GetActiveCameraIndex,0x80169584,0x3 -asm/non_matchings/code/z_play/func_80169590.s,func_80169590,0x80169590,0x1C -asm/non_matchings/code/z_play/func_80169600.s,func_80169600,0x80169600,0x1A -asm/non_matchings/code/z_play/func_80169668.s,func_80169668,0x80169668,0x1B +asm/non_matchings/code/z_play/Play_CreateSubCamera.s,Play_CreateSubCamera,0x801694DC,0x2A +asm/non_matchings/code/z_play/Play_GetActiveCamId.s,Play_GetActiveCamId,0x80169584,0x3 +asm/non_matchings/code/z_play/Play_CameraChangeStatus.s,Play_CameraChangeStatus,0x80169590,0x1C +asm/non_matchings/code/z_play/Play_ClearCamera.s,Play_ClearCamera,0x80169600,0x1A +asm/non_matchings/code/z_play/Play_ClearAllSubCameras.s,Play_ClearAllSubCameras,0x80169668,0x1B asm/non_matchings/code/z_play/Play_GetCamera.s,Play_GetCamera,0x801696D4,0xE -asm/non_matchings/code/z_play/func_8016970C.s,func_8016970C,0x8016970C,0x44 -asm/non_matchings/code/z_play/func_8016981C.s,func_8016981C,0x8016981C,0x49 -asm/non_matchings/code/z_play/func_80169940.s,func_80169940,0x80169940,0x12 -asm/non_matchings/code/z_play/func_80169988.s,func_80169988,0x80169988,0x13 -asm/non_matchings/code/z_play/func_801699D4.s,func_801699D4,0x801699D4,0x1F +asm/non_matchings/code/z_play/Play_CameraSetAtEye.s,Play_CameraSetAtEye,0x8016970C,0x44 +asm/non_matchings/code/z_play/Play_CameraSetAtEyeUp.s,Play_CameraSetAtEyeUp,0x8016981C,0x49 +asm/non_matchings/code/z_play/Play_CameraSetFov.s,Play_CameraSetFov,0x80169940,0x12 +asm/non_matchings/code/z_play/Play_CameraSetRoll.s,Play_CameraSetRoll,0x80169988,0x13 +asm/non_matchings/code/z_play/Play_CopyCamera.s,Play_CopyCamera,0x801699D4,0x1F asm/non_matchings/code/z_play/func_80169A50.s,func_80169A50,0x80169A50,0x1C -asm/non_matchings/code/z_play/func_80169AC0.s,func_80169AC0,0x80169AC0,0xF +asm/non_matchings/code/z_play/Play_CameraChangeSetting.s,Play_CameraChangeSetting,0x80169AC0,0xF asm/non_matchings/code/z_play/func_80169AFC.s,func_80169AFC,0x80169AFC,0x32 -asm/non_matchings/code/z_play/func_80169BC4.s,func_80169BC4,0x80169BC4,0xD +asm/non_matchings/code/z_play/Play_CameraGetUID.s,Play_CameraGetUID,0x80169BC4,0xD asm/non_matchings/code/z_play/func_80169BF8.s,func_80169BF8,0x80169BF8,0x1B -asm/non_matchings/code/z_play/func_80169C64.s,func_80169C64,0x80169C64,0x8 -asm/non_matchings/code/z_play/func_80169C84.s,func_80169C84,0x80169C84,0xE -asm/non_matchings/code/z_play/convert_scene_number_among_shared_scenes.s,convert_scene_number_among_shared_scenes,0x80169CBC,0x21 -asm/non_matchings/code/z_play/func_80169D40.s,func_80169D40,0x80169D40,0x23 -asm/non_matchings/code/z_play/func_80169DCC.s,func_80169DCC,0x80169DCC,0x28 -asm/non_matchings/code/z_play/func_80169E6C.s,func_80169E6C,0x80169E6C,0x18 +asm/non_matchings/code/z_play/Play_GetCsCamDataSetting.s,Play_GetCsCamDataSetting,0x80169C64,0x8 +asm/non_matchings/code/z_play/Play_GetCsCamDataVec3s.s,Play_GetCsCamDataVec3s,0x80169C84,0xE +asm/non_matchings/code/z_play/Play_GetOriginalSceneNumber.s,Play_GetOriginalSceneNumber,0x80169CBC,0x21 +asm/non_matchings/code/z_play/Play_SaveCycleSceneFlags.s,Play_SaveCycleSceneFlags,0x80169D40,0x23 +asm/non_matchings/code/z_play/Play_SetRespawnData.s,Play_SetRespawnData,0x80169DCC,0x28 +asm/non_matchings/code/z_play/Play_SetupRespawnPoint.s,Play_SetupRespawnPoint,0x80169E6C,0x18 asm/non_matchings/code/z_play/func_80169ECC.s,func_80169ECC,0x80169ECC,0xC asm/non_matchings/code/z_play/func_80169EFC.s,func_80169EFC,0x80169EFC,0x1F asm/non_matchings/code/z_play/func_80169F78.s,func_80169F78,0x80169F78,0x19 @@ -2549,7 +2549,7 @@ asm/non_matchings/code/z_play/func_80169FDC.s,func_80169FDC,0x80169FDC,0x8 asm/non_matchings/code/z_play/func_80169FFC.s,func_80169FFC,0x80169FFC,0x8 asm/non_matchings/code/z_play/FrameAdvance_IsEnabled.s,FrameAdvance_IsEnabled,0x8016A01C,0x4 asm/non_matchings/code/z_play/func_8016A02C.s,func_8016A02C,0x8016A02C,0x20 -asm/non_matchings/code/z_play/func_8016A0AC.s,func_8016A0AC,0x8016A0AC,0x2F +asm/non_matchings/code/z_play/Play_IsUnderwater.s,Play_IsUnderwater,0x8016A0AC,0x2F asm/non_matchings/code/z_play/func_8016A168.s,func_8016A168,0x8016A168,0x4 asm/non_matchings/code/z_play/func_8016A178.s,func_8016A178,0x8016A178,0x3C asm/non_matchings/code/z_play/func_8016A268.s,func_8016A268,0x8016A268,0x18 @@ -2646,11 +2646,11 @@ asm/non_matchings/code/game/Game_Update.s,Game_Update,0x8017377C,0x1A asm/non_matchings/code/game/Game_IncrementFrameCount.s,Game_IncrementFrameCount,0x801737E4,0xB asm/non_matchings/code/game/Game_InitHeap.s,Game_InitHeap,0x80173810,0x1C asm/non_matchings/code/game/Game_ResizeHeap.s,Game_ResizeHeap,0x80173880,0x34 -asm/non_matchings/code/game/Game_StateInit.s,Game_StateInit,0x80173950,0x40 -asm/non_matchings/code/game/Game_StateFini.s,Game_StateFini,0x80173A50,0x2C -asm/non_matchings/code/game/Game_GetNextStateInit.s,Game_GetNextStateInit,0x80173B00,0x3 -asm/non_matchings/code/game/Game_GetNextStateSize.s,Game_GetNextStateSize,0x80173B0C,0x3 -asm/non_matchings/code/game/Game_GetShouldContinue.s,Game_GetShouldContinue,0x80173B18,0x3 +asm/non_matchings/code/game/GameState_Init.s,GameState_Init,0x80173950,0x40 +asm/non_matchings/code/game/GameState_Destroy.s,GameState_Destroy,0x80173A50,0x2C +asm/non_matchings/code/game/GameState_GetNextStateInit.s,GameState_GetNextStateInit,0x80173B00,0x3 +asm/non_matchings/code/game/GameState_GetNextStateSize.s,GameState_GetNextStateSize,0x80173B0C,0x3 +asm/non_matchings/code/game/GameState_IsRunning.s,GameState_IsRunning,0x80173B18,0x3 asm/non_matchings/code/game/Game_GetHeapFreeSize.s,Game_GetHeapFreeSize,0x80173B24,0x9 asm/non_matchings/code/game/func_80173B48.s,func_80173B48,0x80173B48,0x2A asm/non_matchings/code/gamealloc/func_80173BF0.s,func_80173BF0,0x80173BF0,0x8 @@ -2659,20 +2659,20 @@ asm/non_matchings/code/gamealloc/Gamealloc_Free.s,Gamealloc_Free,0x80173C7C,0x13 asm/non_matchings/code/gamealloc/Gamealloc_FreeAll.s,Gamealloc_FreeAll,0x80173CC8,0x14 asm/non_matchings/code/gamealloc/Gamealloc_Init.s,Gamealloc_Init,0x80173D18,0x6 asm/non_matchings/code/graph/Graph_FaultClient.s,Graph_FaultClient,0x80173D30,0x1F -asm/non_matchings/code/graph/Graph_DlAlloc.s,Graph_DlAlloc,0x80173DAC,0x8 -asm/non_matchings/code/graph/Graph_InitTHGA.s,Graph_InitTHGA,0x80173DCC,0x73 +asm/non_matchings/code/graph/Graph_InitTHGA.s,Graph_InitTHGA,0x80173DAC,0x8 +asm/non_matchings/code/graph/Graph_SetNextGfxPool.s,Graph_SetNextGfxPool,0x80173DCC,0x73 asm/non_matchings/code/graph/Graph_GetNextGameState.s,Graph_GetNextGameState,0x80173F98,0x32 asm/non_matchings/code/graph/Graph_FaultAddrConvFunc.s,Graph_FaultAddrConvFunc,0x80174060,0x1C asm/non_matchings/code/graph/Graph_Init.s,Graph_Init,0x801740D0,0x29 asm/non_matchings/code/graph/Graph_Destroy.s,Graph_Destroy,0x80174174,0xD -asm/non_matchings/code/graph/Graph_Render.s,Graph_Render,0x801741A8,0xC1 -asm/non_matchings/code/graph/Graph_FrameSetup.s,Graph_FrameSetup,0x801744AC,0x13 -asm/non_matchings/code/graph/Graph_RenderFrame.s,Graph_RenderFrame,0x801744F8,0xDC -asm/non_matchings/code/graph/Graph_DoFrame.s,Graph_DoFrame,0x80174868,0xE +asm/non_matchings/code/graph/Graph_TaskSet00.s,Graph_TaskSet00,0x801741A8,0xC1 +asm/non_matchings/code/graph/Graph_UpdateGame.s,Graph_UpdateGame,0x801744AC,0x13 +asm/non_matchings/code/graph/Graph_ExecuteAndDraw.s,Graph_ExecuteAndDraw,0x801744F8,0xDC +asm/non_matchings/code/graph/Graph_Update.s,Graph_Update,0x80174868,0xE asm/non_matchings/code/graph/Graph_ThreadEntry.s,Graph_ThreadEntry,0x801748A0,0x68 -asm/non_matchings/code/code_80174A40/Graph_GfxPlusOne.s,Graph_GfxPlusOne,0x80174A40,0x3 -asm/non_matchings/code/code_80174A40/Graph_BranchDlist.s,Graph_BranchDlist,0x80174A4C,0x6 -asm/non_matchings/code/code_80174A40/Graph_DlistAlloc.s,Graph_DlistAlloc,0x80174A64,0xF +asm/non_matchings/code/graphalloc/Graph_GfxPlusOne.s,Graph_GfxPlusOne,0x80174A40,0x3 +asm/non_matchings/code/graphalloc/Graph_BranchDlist.s,Graph_BranchDlist,0x80174A4C,0x6 +asm/non_matchings/code/graphalloc/Graph_DlistAlloc.s,Graph_DlistAlloc,0x80174A64,0xF asm/non_matchings/code/listalloc/func_80174AA0.s,func_80174AA0,0x80174AA0,0x5 asm/non_matchings/code/listalloc/func_80174AB4.s,func_80174AB4,0x80174AB4,0x1B asm/non_matchings/code/listalloc/func_80174B20.s,func_80174B20,0x80174B20,0x20 @@ -2743,8 +2743,8 @@ asm/non_matchings/code/sys_cmpdma/func_80178750.s,func_80178750,0x80178750,0x32 asm/non_matchings/code/sys_cmpdma/func_80178818.s,func_80178818,0x80178818,0x58 asm/non_matchings/code/sys_cmpdma/func_80178978.s,func_80178978,0x80178978,0x17 asm/non_matchings/code/sys_cmpdma/func_801789D4.s,func_801789D4,0x801789D4,0x6 -asm/non_matchings/code/sys_cmpdma/get_framebuffer.s,get_framebuffer,0x801789EC,0xA -asm/non_matchings/code/sys_cmpdma/get_zbuffer.s,get_zbuffer,0x80178A14,0x4 +asm/non_matchings/code/sys_cmpdma/SysCfb_GetFbPtr.s,SysCfb_GetFbPtr,0x801789EC,0xA +asm/non_matchings/code/sys_cmpdma/SysCfb_GetZBuffer.s,SysCfb_GetZBuffer,0x80178A14,0x4 asm/non_matchings/code/sys_cmpdma/func_80178A24.s,func_80178A24,0x80178A24,0x4 asm/non_matchings/code/sys_cmpdma/func_80178A34.s,func_80178A34,0x80178A34,0x18 asm/non_matchings/code/sys_cmpdma/func_80178A94.s,func_80178A94,0x80178A94,0xB @@ -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,58 +2792,58 @@ 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 +asm/non_matchings/code/sys_math3d/Math3D_LineSegVsPlane.s,Math3D_LineSegVsPlane,0x8017D2FC,0x42 asm/non_matchings/code/sys_math3d/func_8017D404.s,func_8017D404,0x8017D404,0x59 asm/non_matchings/code/sys_math3d/Math3D_TriSetCoords.s,Math3D_TriSetCoords,0x8017D568,0x2C asm/non_matchings/code/sys_math3d/Math3D_IsPointInSphere.s,Math3D_IsPointInSphere,0x8017D618,0x14 -asm/non_matchings/code/sys_math3d/func_8017D668.s,func_8017D668,0x8017D668,0x56 +asm/non_matchings/code/sys_math3d/Math3D_PointDistToLine2D.s,Math3D_PointDistToLine2D,0x8017D668,0x56 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 @@ -2868,49 +2868,49 @@ asm/non_matchings/code/sys_math_atan/Math_Atan2S.s,Math_Atan2S,0x8017FEE4,0x7A asm/non_matchings/code/sys_math_atan/Math_Atan2F.s,Math_Atan2F,0x801800CC,0xD asm/non_matchings/code/sys_math_atan/Math_FAtan2F.s,Math_FAtan2F,0x80180100,0xB asm/non_matchings/code/sys_math_atan/Math_Acot2F.s,Math_Acot2F,0x8018012C,0xD -asm/non_matchings/code/sys_matrix/Matrix_StateAlloc.s,Matrix_StateAlloc,0x80180160,0xF -asm/non_matchings/code/sys_matrix/Matrix_StatePush.s,Matrix_StatePush,0x8018019C,0xC -asm/non_matchings/code/sys_matrix/Matrix_StatePop.s,Matrix_StatePop,0x801801CC,0x7 -asm/non_matchings/code/sys_matrix/Matrix_CopyCurrentState.s,Matrix_CopyCurrentState,0x801801E8,0x9 -asm/non_matchings/code/sys_matrix/Matrix_SetCurrentState.s,Matrix_SetCurrentState,0x8018020C,0xA -asm/non_matchings/code/sys_matrix/Matrix_GetCurrentState.s,Matrix_GetCurrentState,0x80180234,0x4 -asm/non_matchings/code/sys_matrix/Matrix_InsertMatrix.s,Matrix_InsertMatrix,0x80180244,0x16 -asm/non_matchings/code/sys_matrix/Matrix_InsertTranslation.s,Matrix_InsertTranslation,0x8018029C,0x40 +asm/non_matchings/code/sys_matrix/Matrix_Init.s,Matrix_Init,0x80180160,0xF +asm/non_matchings/code/sys_matrix/Matrix_Push.s,Matrix_Push,0x8018019C,0xC +asm/non_matchings/code/sys_matrix/Matrix_Pop.s,Matrix_Pop,0x801801CC,0x7 +asm/non_matchings/code/sys_matrix/Matrix_Get.s,Matrix_Get,0x801801E8,0x9 +asm/non_matchings/code/sys_matrix/Matrix_Put.s,Matrix_Put,0x8018020C,0xA +asm/non_matchings/code/sys_matrix/Matrix_GetCurrent.s,Matrix_GetCurrent,0x80180234,0x4 +asm/non_matchings/code/sys_matrix/Matrix_Mult.s,Matrix_Mult,0x80180244,0x16 +asm/non_matchings/code/sys_matrix/Matrix_Translate.s,Matrix_Translate,0x8018029C,0x40 asm/non_matchings/code/sys_matrix/Matrix_Scale.s,Matrix_Scale,0x8018039C,0x37 -asm/non_matchings/code/sys_matrix/Matrix_InsertXRotation_s.s,Matrix_InsertXRotation_s,0x80180478,0x66 -asm/non_matchings/code/sys_matrix/Matrix_InsertXRotation_f.s,Matrix_InsertXRotation_f,0x80180610,0x6A -asm/non_matchings/code/sys_matrix/Matrix_RotateStateAroundXAxis.s,Matrix_RotateStateAroundXAxis,0x801807B8,0x52 -asm/non_matchings/code/sys_matrix/Matrix_SetStateXRotation.s,Matrix_SetStateXRotation,0x80180900,0x2B -asm/non_matchings/code/sys_matrix/Matrix_RotateY.s,Matrix_RotateY,0x801809AC,0x67 -asm/non_matchings/code/sys_matrix/Matrix_InsertYRotation_f.s,Matrix_InsertYRotation_f,0x80180B48,0x6C -asm/non_matchings/code/sys_matrix/Matrix_InsertZRotation_s.s,Matrix_InsertZRotation_s,0x80180CF8,0x66 -asm/non_matchings/code/sys_matrix/Matrix_InsertZRotation_f.s,Matrix_InsertZRotation_f,0x80180E90,0x6B -asm/non_matchings/code/sys_matrix/Matrix_InsertRotation.s,Matrix_InsertRotation,0x8018103C,0xB0 +asm/non_matchings/code/sys_matrix/Matrix_RotateXS.s,Matrix_RotateXS,0x80180478,0x66 +asm/non_matchings/code/sys_matrix/Matrix_RotateXF.s,Matrix_RotateXF,0x80180610,0x6A +asm/non_matchings/code/sys_matrix/Matrix_RotateXFApply.s,Matrix_RotateXFApply,0x801807B8,0x52 +asm/non_matchings/code/sys_matrix/Matrix_RotateXFNew.s,Matrix_RotateXFNew,0x80180900,0x2B +asm/non_matchings/code/sys_matrix/Matrix_RotateYS.s,Matrix_RotateYS,0x801809AC,0x67 +asm/non_matchings/code/sys_matrix/Matrix_RotateYF.s,Matrix_RotateYF,0x80180B48,0x6C +asm/non_matchings/code/sys_matrix/Matrix_RotateZS.s,Matrix_RotateZS,0x80180CF8,0x66 +asm/non_matchings/code/sys_matrix/Matrix_RotateZF.s,Matrix_RotateZF,0x80180E90,0x6B +asm/non_matchings/code/sys_matrix/Matrix_RotateZYX.s,Matrix_RotateZYX,0x8018103C,0xB0 asm/non_matchings/code/sys_matrix/Matrix_RotateAndTranslateState.s,Matrix_RotateAndTranslateState,0x801812FC,0xD5 -asm/non_matchings/code/sys_matrix/Matrix_SetStateRotationAndTranslation.s,Matrix_SetStateRotationAndTranslation,0x80181650,0x6B -asm/non_matchings/code/sys_matrix/Matrix_ToRSPMatrix.s,Matrix_ToRSPMatrix,0x801817FC,0x87 -asm/non_matchings/code/sys_matrix/Matrix_GetStateAsRSPMatrix.s,Matrix_GetStateAsRSPMatrix,0x80181A18,0xA +asm/non_matchings/code/sys_matrix/Matrix_SetTranslateRotateYXZ.s,Matrix_SetTranslateRotateYXZ,0x80181650,0x6B +asm/non_matchings/code/sys_matrix/Matrix_MtxFToMtx.s,Matrix_MtxFToMtx,0x801817FC,0x87 +asm/non_matchings/code/sys_matrix/Matrix_ToMtx.s,Matrix_ToMtx,0x80181A18,0xA asm/non_matchings/code/sys_matrix/Matrix_NewMtx.s,Matrix_NewMtx,0x80181A40,0xB -asm/non_matchings/code/sys_matrix/Matrix_AppendToPolyOpaDisp.s,Matrix_AppendToPolyOpaDisp,0x80181A6C,0xB -asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fByState.s,Matrix_MultiplyVector3fByState,0x80181A98,0x2E -asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslation.s,Matrix_GetStateTranslation,0x80181B50,0xA -asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledX.s,Matrix_GetStateTranslationAndScaledX,0x80181B78,0x13 -asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledY.s,Matrix_GetStateTranslationAndScaledY,0x80181BC4,0x13 -asm/non_matchings/code/sys_matrix/Matrix_GetStateTranslationAndScaledZ.s,Matrix_GetStateTranslationAndScaledZ,0x80181C10,0x13 -asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fXZByCurrentState.s,Matrix_MultiplyVector3fXZByCurrentState,0x80181C5C,0x20 +asm/non_matchings/code/sys_matrix/Matrix_MtxFToNewMtx.s,Matrix_MtxFToNewMtx,0x80181A6C,0xB +asm/non_matchings/code/sys_matrix/Matrix_MultVec3f.s,Matrix_MultVec3f,0x80181A98,0x2E +asm/non_matchings/code/sys_matrix/Matrix_MultZero.s,Matrix_MultZero,0x80181B50,0xA +asm/non_matchings/code/sys_matrix/Matrix_MultVecX.s,Matrix_MultVecX,0x80181B78,0x13 +asm/non_matchings/code/sys_matrix/Matrix_MultVecY.s,Matrix_MultVecY,0x80181BC4,0x13 +asm/non_matchings/code/sys_matrix/Matrix_MultVecZ.s,Matrix_MultVecZ,0x80181C10,0x13 +asm/non_matchings/code/sys_matrix/Matrix_MultVec3fXZ.s,Matrix_MultVec3fXZ,0x80181C5C,0x20 asm/non_matchings/code/sys_matrix/Matrix_MtxFCopy.s,Matrix_MtxFCopy,0x80181CDC,0x22 -asm/non_matchings/code/sys_matrix/Matrix_FromRSPMatrix.s,Matrix_FromRSPMatrix,0x80181D64,0x95 -asm/non_matchings/code/sys_matrix/Matrix_MultiplyVector3fByMatrix.s,Matrix_MultiplyVector3fByMatrix,0x80181FB8,0x2C -asm/non_matchings/code/sys_matrix/Matrix_TransposeXYZ.s,Matrix_TransposeXYZ,0x80182068,0xE -asm/non_matchings/code/sys_matrix/Matrix_NormalizeXYZ.s,Matrix_NormalizeXYZ,0x801820A0,0x3F -asm/non_matchings/code/sys_matrix/func_8018219C.s,func_8018219C,0x8018219C,0x4A -asm/non_matchings/code/sys_matrix/func_801822C4.s,func_801822C4,0x801822C4,0x4A -asm/non_matchings/code/sys_matrix/Matrix_InsertRotationAroundUnitVector_f.s,Matrix_InsertRotationAroundUnitVector_f,0x801823EC,0x118 -asm/non_matchings/code/sys_matrix/Matrix_InsertRotationAroundUnitVector_s.s,Matrix_InsertRotationAroundUnitVector_s,0x8018284C,0x111 -asm/non_matchings/code/sys_matrix/func_80182C90.s,func_80182C90,0x80182C90,0x4 -asm/non_matchings/code/sys_matrix/func_80182CA0.s,func_80182CA0,0x80182CA0,0x7 -asm/non_matchings/code/sys_matrix/func_80182CBC.s,func_80182CBC,0x80182CBC,0x4 -asm/non_matchings/code/sys_matrix/func_80182CCC.s,func_80182CCC,0x80182CCC,0x5 +asm/non_matchings/code/sys_matrix/Matrix_MtxToMtxF.s,Matrix_MtxToMtxF,0x80181D64,0x95 +asm/non_matchings/code/sys_matrix/Matrix_MultVec3fExt.s,Matrix_MultVec3fExt,0x80181FB8,0x2C +asm/non_matchings/code/sys_matrix/Matrix_Transpose.s,Matrix_Transpose,0x80182068,0xE +asm/non_matchings/code/sys_matrix/Matrix_ReplaceRotation.s,Matrix_ReplaceRotation,0x801820A0,0x3F +asm/non_matchings/code/sys_matrix/Matrix_MtxFToYXZRot.s,Matrix_MtxFToYXZRot,0x8018219C,0x4A +asm/non_matchings/code/sys_matrix/Matrix_MtxFToZYXRot.s,Matrix_MtxFToZYXRot,0x801822C4,0x4A +asm/non_matchings/code/sys_matrix/Matrix_RotateAxisF.s,Matrix_RotateAxisF,0x801823EC,0x118 +asm/non_matchings/code/sys_matrix/Matrix_RotateAxisS.s,Matrix_RotateAxisS,0x8018284C,0x111 +asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBoot.s,SysUcode_GetUCodeBoot,0x80182C90,0x4 +asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBootSize.s,SysUcode_GetUCodeBootSize,0x80182CA0,0x7 +asm/non_matchings/code/sys_ucode/SysUcode_GetUCode.s,SysUcode_GetUCode,0x80182CBC,0x4 +asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeData.s,SysUcode_GetUCodeData,0x80182CCC,0x5 asm/non_matchings/code/sys_ucode/func_80182CE0.s,func_80182CE0,0x80182CE0,0xD0 asm/non_matchings/code/sys_ucode/func_80183020.s,func_80183020,0x80183020,0xE asm/non_matchings/code/sys_ucode/func_80183058.s,func_80183058,0x80183058,0x6 @@ -3064,140 +3064,138 @@ asm/non_matchings/code/audio_synthesis/func_8018A768.s,func_8018A768,0x8018A768, asm/non_matchings/code/audio_synthesis/func_8018A808.s,func_8018A808,0x8018A808,0x12F asm/non_matchings/code/audio_synthesis/func_8018ACC4.s,func_8018ACC4,0x8018ACC4,0x5C asm/non_matchings/code/audio_synthesis/func_8018AE34.s,func_8018AE34,0x8018AE34,0xAF -asm/non_matchings/code/audio_heap/func_8018B0F0.s,func_8018B0F0,0x8018B0F0,0x7 -asm/non_matchings/code/audio_heap/func_8018B10C.s,func_8018B10C,0x8018B10C,0x51 -asm/non_matchings/code/audio_heap/func_8018B250.s,func_8018B250,0x8018B250,0x32 -asm/non_matchings/code/audio_heap/func_8018B318.s,func_8018B318,0x8018B318,0x39 -asm/non_matchings/code/audio_heap/func_8018B3FC.s,func_8018B3FC,0x8018B3FC,0x1E -asm/non_matchings/code/audio_heap/func_8018B474.s,func_8018B474,0x8018B474,0x21 -asm/non_matchings/code/audio_heap/func_8018B4F8.s,func_8018B4F8,0x8018B4F8,0xA -asm/non_matchings/code/audio_heap/func_8018B520.s,func_8018B520,0x8018B520,0x16 -asm/non_matchings/code/audio_heap/func_8018B578.s,func_8018B578,0x8018B578,0x16 -asm/non_matchings/code/audio_heap/func_8018B5D0.s,func_8018B5D0,0x8018B5D0,0xE -asm/non_matchings/code/audio_heap/func_8018B608.s,func_8018B608,0x8018B608,0xE -asm/non_matchings/code/audio_heap/func_8018B640.s,func_8018B640,0x8018B640,0x17 -asm/non_matchings/code/audio_heap/func_8018B69C.s,func_8018B69C,0x8018B69C,0x13 -asm/non_matchings/code/audio_heap/func_8018B6E8.s,func_8018B6E8,0x8018B6E8,0x16 -asm/non_matchings/code/audio_heap/func_8018B740.s,func_8018B740,0x8018B740,0xA -asm/non_matchings/code/audio_heap/func_8018B768.s,func_8018B768,0x8018B768,0x5 -asm/non_matchings/code/audio_heap/func_8018B77C.s,func_8018B77C,0x8018B77C,0xC -asm/non_matchings/code/audio_heap/func_8018B7AC.s,func_8018B7AC,0x8018B7AC,0x4 -asm/non_matchings/code/audio_heap/func_8018B7BC.s,func_8018B7BC,0x8018B7BC,0x50 -asm/non_matchings/code/audio_heap/func_8018B8FC.s,func_8018B8FC,0x8018B8FC,0x18 -asm/non_matchings/code/audio_heap/func_8018B95C.s,func_8018B95C,0x8018B95C,0x21 -asm/non_matchings/code/audio_heap/func_8018B9E0.s,func_8018B9E0,0x8018B9E0,0x21 -asm/non_matchings/code/audio_heap/func_8018BA64.s,func_8018BA64,0x8018BA64,0x31 -asm/non_matchings/code/audio_heap/func_8018BB28.s,func_8018BB28,0x8018BB28,0x31 -asm/non_matchings/code/audio_heap/func_8018BBEC.s,func_8018BBEC,0x8018BBEC,0x1E5 -asm/non_matchings/code/audio_heap/func_8018C380.s,func_8018C380,0x8018C380,0x16 -asm/non_matchings/code/audio_heap/func_8018C3D8.s,func_8018C3D8,0x8018C3D8,0x43 +asm/non_matchings/code/audio_heap/AudioHeap_ResetLoadStatus.s,AudioHeap_ResetLoadStatus,0x8018B250,0x32 +asm/non_matchings/code/audio_heap/AudioHeap_DiscardFont.s,AudioHeap_DiscardFont,0x8018B318,0x39 +asm/non_matchings/code/audio_heap/AudioHeap_ReleaseNotesForFont.s,AudioHeap_ReleaseNotesForFont,0x8018B3FC,0x1E +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSequence.s,AudioHeap_DiscardSequence,0x8018B474,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_WritebackDCache.s,AudioHeap_WritebackDCache,0x8018B4F8,0xA +asm/non_matchings/code/audio_heap/AudioHeap_AllocZeroedAttemptExternal.s,AudioHeap_AllocZeroedAttemptExternal,0x8018B520,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_AllocAttemptExternal.s,AudioHeap_AllocAttemptExternal,0x8018B578,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_AllocDmaMemory.s,AudioHeap_AllocDmaMemory,0x8018B5D0,0xE +asm/non_matchings/code/audio_heap/AudioHeap_AllocDmaMemoryZeroed.s,AudioHeap_AllocDmaMemoryZeroed,0x8018B608,0xE +asm/non_matchings/code/audio_heap/AudioHeap_AllocZeroed.s,AudioHeap_AllocZeroed,0x8018B640,0x17 +asm/non_matchings/code/audio_heap/AudioHeap_TestAlloc.s,AudioHeap_TestAlloc,0x8018B69C,0x13 +asm/non_matchings/code/audio_heap/Audio_Alloc.s,Audio_Alloc,0x8018B6E8,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_AllocPoolInit.s,AudioHeap_AllocPoolInit,0x8018B740,0xA +asm/non_matchings/code/audio_heap/AudioHeap_ClearPersistentCache.s,AudioHeap_ClearPersistentCache,0x8018B768,0x5 +asm/non_matchings/code/audio_heap/AudioHeap_ClearTemporaryCache.s,AudioHeap_ClearTemporaryCache,0x8018B77C,0xC +asm/non_matchings/code/audio_heap/AudioHeap_ResetPool.s,AudioHeap_ResetPool,0x8018B7AC,0x4 +asm/non_matchings/code/audio_heap/AudioHeap_PopCache.s,AudioHeap_PopCache,0x8018B7BC,0x50 +asm/non_matchings/code/audio_heap/AudioHeap_InitMainPool.s,AudioHeap_InitMainPool,0x8018B8FC,0x18 +asm/non_matchings/code/audio_heap/AudioHeap_InitSessionPool.s,AudioHeap_InitSessionPool,0x8018B95C,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_InitCachePool.s,AudioHeap_InitCachePool,0x8018B9E0,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_InitPersistentCache.s,AudioHeap_InitPersistentCache,0x8018BA64,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_InitTemporaryCache.s,AudioHeap_InitTemporaryCache,0x8018BB28,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_AllocCached.s,AudioHeap_AllocCached,0x8018BBEC,0x1E5 +asm/non_matchings/code/audio_heap/AudioHeap_SearchCaches.s,AudioHeap_SearchCaches,0x8018C380,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_SearchRegularCaches.s,AudioHeap_SearchRegularCaches,0x8018C3D8,0x43 asm/non_matchings/code/audio_heap/func_8018C4E4.s,func_8018C4E4,0x8018C4E4,0xF5 -asm/non_matchings/code/audio_heap/func_8018C8B8.s,func_8018C8B8,0x8018C8B8,0xC -asm/non_matchings/code/audio_heap/func_8018C8E8.s,func_8018C8E8,0x8018C8E8,0x15 -asm/non_matchings/code/audio_heap/func_8018C93C.s,func_8018C93C,0x8018C93C,0x16 -asm/non_matchings/code/audio_heap/func_8018C994.s,func_8018C994,0x8018C994,0x77 -asm/non_matchings/code/audio_heap/func_8018CB70.s,func_8018CB70,0x8018CB70,0x2 -asm/non_matchings/code/audio_heap/func_8018CB78.s,func_8018CB78,0x8018CB78,0x31 -asm/non_matchings/code/audio_heap/func_8018CC3C.s,func_8018CC3C,0x8018CC3C,0x1B -asm/non_matchings/code/audio_heap/func_8018CCA8.s,func_8018CCA8,0x8018CCA8,0xC1 -asm/non_matchings/code/audio_heap/func_8018CFAC.s,func_8018CFAC,0x8018CFAC,0x174 -asm/non_matchings/code/audio_heap/func_8018D57C.s,func_8018D57C,0x8018D57C,0x16 -asm/non_matchings/code/audio_heap/func_8018D5D4.s,func_8018D5D4,0x8018D5D4,0x21 -asm/non_matchings/code/audio_heap/func_8018D658.s,func_8018D658,0x8018D658,0x1C -asm/non_matchings/code/audio_heap/func_8018D6C8.s,func_8018D6C8,0x8018D6C8,0x26 -asm/non_matchings/code/audio_heap/func_8018D760.s,func_8018D760,0x8018D760,0xBC -asm/non_matchings/code/audio_heap/func_8018DA50.s,func_8018DA50,0x8018DA50,0x5D -asm/non_matchings/code/audio_heap/func_8018DBC4.s,func_8018DBC4,0x8018DBC4,0x3C -asm/non_matchings/code/audio_heap/func_8018DCB4.s,func_8018DCB4,0x8018DCB4,0x11 -asm/non_matchings/code/audio_heap/func_8018DCF8.s,func_8018DCF8,0x8018DCF8,0x28 -asm/non_matchings/code/audio_heap/func_8018DD98.s,func_8018DD98,0x8018DD98,0xF -asm/non_matchings/code/audio_heap/func_8018DDD4.s,func_8018DDD4,0x8018DDD4,0x54 -asm/non_matchings/code/audio_heap/func_8018DF24.s,func_8018DF24,0x8018DF24,0x2F -asm/non_matchings/code/audio_heap/func_8018DFE0.s,func_8018DFE0,0x8018DFE0,0xB -asm/non_matchings/code/audio_heap/func_8018E00C.s,func_8018E00C,0x8018E00C,0xC -asm/non_matchings/code/audio_heap/func_8018E03C.s,func_8018E03C,0x8018E03C,0x9B -asm/non_matchings/code/audio_heap/func_8018E2A8.s,func_8018E2A8,0x8018E2A8,0x27 -asm/non_matchings/code/audio_heap/func_8018E344.s,func_8018E344,0x8018E344,0x161 -asm/non_matchings/code/audio_heap/func_8018E8C8.s,func_8018E8C8,0x8018E8C8,0xA6 -asm/non_matchings/code/audio_load/func_8018EB60.s,func_8018EB60,0x8018EB60,0x3B -asm/non_matchings/code/audio_load/func_8018EC4C.s,func_8018EC4C,0x8018EC4C,0xCF -asm/non_matchings/code/audio_load/func_8018EF88.s,func_8018EF88,0x8018EF88,0xA6 -asm/non_matchings/code/audio_load/func_8018F220.s,func_8018F220,0x8018F220,0x1E -asm/non_matchings/code/audio_load/func_8018F298.s,func_8018F298,0x8018F298,0x1E -asm/non_matchings/code/audio_load/func_8018F310.s,func_8018F310,0x8018F310,0x1E -asm/non_matchings/code/audio_load/func_8018F388.s,func_8018F388,0x8018F388,0xC -asm/non_matchings/code/audio_load/func_8018F3B8.s,func_8018F3B8,0x8018F3B8,0xC -asm/non_matchings/code/audio_load/func_8018F3E8.s,func_8018F3E8,0x8018F3E8,0x18 -asm/non_matchings/code/audio_load/func_8018F448.s,func_8018F448,0x8018F448,0xC -asm/non_matchings/code/audio_load/func_8018F478.s,func_8018F478,0x8018F478,0x18 -asm/non_matchings/code/audio_load/func_8018F4D8.s,func_8018F4D8,0x8018F4D8,0x2C -asm/non_matchings/code/audio_load/func_8018F588.s,func_8018F588,0x8018F588,0x1F -asm/non_matchings/code/audio_load/func_8018F604.s,func_8018F604,0x8018F604,0x3B -asm/non_matchings/code/audio_load/func_8018F6F0.s,func_8018F6F0,0x8018F6F0,0x34 -asm/non_matchings/code/audio_load/func_8018F7C0.s,func_8018F7C0,0x8018F7C0,0xE -asm/non_matchings/code/audio_load/func_8018F7F8.s,func_8018F7F8,0x8018F7F8,0x11 -asm/non_matchings/code/audio_load/func_8018F83C.s,func_8018F83C,0x8018F83C,0x11 -asm/non_matchings/code/audio_load/func_8018F880.s,func_8018F880,0x8018F880,0x11 -asm/non_matchings/code/audio_load/func_8018F8C4.s,func_8018F8C4,0x8018F8C4,0x11 -asm/non_matchings/code/audio_load/func_8018F908.s,func_8018F908,0x8018F908,0x2C -asm/non_matchings/code/audio_load/func_8018F9B8.s,func_8018F9B8,0x8018F9B8,0x2A +asm/non_matchings/code/audio_heap/AudioHeap_ClearFilter.s,AudioHeap_ClearFilter,0x8018C8B8,0xC +asm/non_matchings/code/audio_heap/AudioHeap_LoadLowPassFilter.s,AudioHeap_LoadLowPassFilter,0x8018C8E8,0x15 +asm/non_matchings/code/audio_heap/AudioHeap_LoadHighPassFilter.s,AudioHeap_LoadHighPassFilter,0x8018C93C,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_LoadFilter.s,AudioHeap_LoadFilter,0x8018C994,0x77 +asm/non_matchings/code/audio_heap/AudioHeap_UpdateReverb.s,AudioHeap_UpdateReverb,0x8018CB70,0x2 +asm/non_matchings/code/audio_heap/AudioHeap_UpdateReverbs.s,AudioHeap_UpdateReverbs,0x8018CB78,0x31 +asm/non_matchings/code/audio_heap/AudioHeap_ClearAiBuffers.s,AudioHeap_ClearAiBuffers,0x8018CC3C,0x1B +asm/non_matchings/code/audio_heap/AudioHeap_ResetStep.s,AudioHeap_ResetStep,0x8018CCA8,0xC1 +asm/non_matchings/code/audio_heap/AudioHeap_Init.s,AudioHeap_Init,0x8018CFAC,0x174 +asm/non_matchings/code/audio_heap/AudioHeap_SearchPermanentCache.s,AudioHeap_SearchPermanentCache,0x8018D57C,0x16 +asm/non_matchings/code/audio_heap/AudioHeap_AllocPermanent.s,AudioHeap_AllocPermanent,0x8018D5D4,0x21 +asm/non_matchings/code/audio_heap/AudioHeap_AllocSampleCache.s,AudioHeap_AllocSampleCache,0x8018D658,0x1C +asm/non_matchings/code/audio_heap/AudioHeap_InitSampleCaches.s,AudioHeap_InitSampleCaches,0x8018D6C8,0x26 +asm/non_matchings/code/audio_heap/AudioHeap_AllocTemporarySampleCacheEntry.s,AudioHeap_AllocTemporarySampleCacheEntry,0x8018D760,0xBC +asm/non_matchings/code/audio_heap/AudioHeap_UnapplySampleCacheForFont.s,AudioHeap_UnapplySampleCacheForFont,0x8018DA50,0x5D +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCacheEntry.s,AudioHeap_DiscardSampleCacheEntry,0x8018DBC4,0x3C +asm/non_matchings/code/audio_heap/AudioHeap_UnapplySampleCache.s,AudioHeap_UnapplySampleCache,0x8018DCB4,0x11 +asm/non_matchings/code/audio_heap/AudioHeap_AllocPersistentSampleCacheEntry.s,AudioHeap_AllocPersistentSampleCacheEntry,0x8018DCF8,0x28 +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCacheForFont.s,AudioHeap_DiscardSampleCacheForFont,0x8018DD98,0xF +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleCaches.s,AudioHeap_DiscardSampleCaches,0x8018DDD4,0x54 +asm/non_matchings/code/audio_heap/AudioHeap_ChangeStorage.s,AudioHeap_ChangeStorage,0x8018DF24,0x2F +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleBank.s,AudioHeap_DiscardSampleBank,0x8018DFE0,0xB +asm/non_matchings/code/audio_heap/AudioHeap_ApplySampleBankCache.s,AudioHeap_ApplySampleBankCache,0x8018E00C,0xC +asm/non_matchings/code/audio_heap/AudioHeap_ApplySampleBankCacheInternal.s,AudioHeap_ApplySampleBankCacheInternal,0x8018E03C,0x9B +asm/non_matchings/code/audio_heap/AudioHeap_DiscardSampleBanks.s,AudioHeap_DiscardSampleBanks,0x8018E2A8,0x27 +asm/non_matchings/code/audio_heap/AudioHeap_SetReverbData.s,AudioHeap_SetReverbData,0x8018E344,0x161 +asm/non_matchings/code/audio_heap/AudioHeap_InitReverb.s,AudioHeap_InitReverb,0x8018E8C8,0xA6 +asm/non_matchings/code/audio_load/AudioLoad_DecreaseSampleDmaTtls.s,AudioLoad_DecreaseSampleDmaTtls,0x8018EB60,0x3B +asm/non_matchings/code/audio_load/AudioLoad_DmaSampleData.s,AudioLoad_DmaSampleData,0x8018EC4C,0xCF +asm/non_matchings/code/audio_load/AudioLoad_InitSampleDmaBuffers.s,AudioLoad_InitSampleDmaBuffers,0x8018EF88,0xA6 +asm/non_matchings/code/audio_load/AudioLoad_IsFontLoadComplete.s,AudioLoad_IsFontLoadComplete,0x8018F220,0x1E +asm/non_matchings/code/audio_load/AudioLoad_IsSeqLoadComplete.s,AudioLoad_IsSeqLoadComplete,0x8018F298,0x1E +asm/non_matchings/code/audio_load/AudioLoad_IsSampleLoadComplete.s,AudioLoad_IsSampleLoadComplete,0x8018F310,0x1E +asm/non_matchings/code/audio_load/AudioLoad_SetFontLoadStatus.s,AudioLoad_SetFontLoadStatus,0x8018F388,0xC +asm/non_matchings/code/audio_load/AudioLoad_SetSeqLoadStatus.s,AudioLoad_SetSeqLoadStatus,0x8018F3B8,0xC +asm/non_matchings/code/audio_load/AudioLoad_SetSampleFontLoadStatusAndApplyCaches.s,AudioLoad_SetSampleFontLoadStatusAndApplyCaches,0x8018F3E8,0x18 +asm/non_matchings/code/audio_load/AudioLoad_SetSampleFontLoadStatus.s,AudioLoad_SetSampleFontLoadStatus,0x8018F448,0xC +asm/non_matchings/code/audio_load/AudioLoad_InitTable.s,AudioLoad_InitTable,0x8018F478,0x18 +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadSeqFonts.s,AudioLoad_SyncLoadSeqFonts,0x8018F4D8,0x2C +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadSeqParts.s,AudioLoad_SyncLoadSeqParts,0x8018F588,0x1F +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadSample.s,AudioLoad_SyncLoadSample,0x8018F604,0x3B +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadInstrument.s,AudioLoad_SyncLoadInstrument,0x8018F6F0,0x34 +asm/non_matchings/code/audio_load/AudioLoad_AsyncLoad.s,AudioLoad_AsyncLoad,0x8018F7C0,0xE +asm/non_matchings/code/audio_load/AudioLoad_AsyncLoadSeq.s,AudioLoad_AsyncLoadSeq,0x8018F7F8,0x11 +asm/non_matchings/code/audio_load/AudioLoad_AsyncLoadSampleBank.s,AudioLoad_AsyncLoadSampleBank,0x8018F83C,0x11 +asm/non_matchings/code/audio_load/AudioLoad_AsyncLoadFont.s,AudioLoad_AsyncLoadFont,0x8018F880,0x11 +asm/non_matchings/code/audio_load/AudioLoad_GetFontsForSequence.s,AudioLoad_GetFontsForSequence,0x8018F8C4,0x11 +asm/non_matchings/code/audio_load/AudioLoad_DiscardSeqFonts.s,AudioLoad_DiscardSeqFonts,0x8018F908,0x2C +asm/non_matchings/code/audio_load/AudioLoad_DiscardFont.s,AudioLoad_DiscardFont,0x8018F9B8,0x2A asm/non_matchings/code/audio_load/func_8018FA60.s,func_8018FA60,0x8018FA60,0x1C -asm/non_matchings/code/audio_load/func_8018FAD0.s,func_8018FAD0,0x8018FAD0,0x14 -asm/non_matchings/code/audio_load/func_8018FB20.s,func_8018FB20,0x8018FB20,0x16 -asm/non_matchings/code/audio_load/func_8018FB78.s,func_8018FB78,0x8018FB78,0x55 -asm/non_matchings/code/audio_load/func_8018FCCC.s,func_8018FCCC,0x8018FCCC,0x15 -asm/non_matchings/code/audio_load/func_8018FD20.s,func_8018FD20,0x8018FD20,0x8 -asm/non_matchings/code/audio_load/func_8018FD40.s,func_8018FD40,0x8018FD40,0x47 -asm/non_matchings/code/audio_load/func_8018FE5C.s,func_8018FE5C,0x8018FE5C,0x41 -asm/non_matchings/code/audio_load/func_8018FF60.s,func_8018FF60,0x8018FF60,0xA9 -asm/non_matchings/code/audio_load/func_80190204.s,func_80190204,0x80190204,0xF -asm/non_matchings/code/audio_load/func_80190240.s,func_80190240,0x80190240,0x15 -asm/non_matchings/code/audio_load/func_80190294.s,func_80190294,0x80190294,0x11 -asm/non_matchings/code/audio_load/func_801902D8.s,func_801902D8,0x801902D8,0x9B -asm/non_matchings/code/audio_load/func_80190544.s,func_80190544,0x80190544,0x49 -asm/non_matchings/code/audio_load/func_80190668.s,func_80190668,0x80190668,0x5 -asm/non_matchings/code/audio_load/func_8019067C.s,func_8019067C,0x8019067C,0x36 -asm/non_matchings/code/audio_load/func_80190754.s,func_80190754,0x80190754,0x2 -asm/non_matchings/code/audio_load/func_8019075C.s,func_8019075C,0x8019075C,0x8 -asm/non_matchings/code/audio_load/func_8019077C.s,func_8019077C,0x8019077C,0xE3 -asm/non_matchings/code/audio_load/func_80190B08.s,func_80190B08,0x80190B08,0xC -asm/non_matchings/code/audio_load/func_80190B38.s,func_80190B38,0x80190B38,0x3 -asm/non_matchings/code/audio_load/func_80190B44.s,func_80190B44,0x80190B44,0x3 -asm/non_matchings/code/audio_load/func_80190B50.s,func_80190B50,0x80190B50,0x18 -asm/non_matchings/code/audio_load/func_80190BB0.s,func_80190BB0,0x80190BB0,0xE8 -asm/non_matchings/code/audio_load/func_80190F50.s,func_80190F50,0x80190F50,0x5 -asm/non_matchings/code/audio_load/func_80190F64.s,func_80190F64,0x80190F64,0x74 -asm/non_matchings/code/audio_load/func_80191134.s,func_80191134,0x80191134,0x24 -asm/non_matchings/code/audio_load/func_801911C4.s,func_801911C4,0x801911C4,0x2 -asm/non_matchings/code/audio_load/func_801911CC.s,func_801911CC,0x801911CC,0x1D -asm/non_matchings/code/audio_load/func_80191240.s,func_80191240,0x80191240,0x62 -asm/non_matchings/code/audio_load/func_801913C8.s,func_801913C8,0x801913C8,0x21 -asm/non_matchings/code/audio_load/func_8019144C.s,func_8019144C,0x8019144C,0x5 -asm/non_matchings/code/audio_load/func_80191460.s,func_80191460,0x80191460,0x42 -asm/non_matchings/code/audio_load/func_80191568.s,func_80191568,0x80191568,0xC -asm/non_matchings/code/audio_load/func_80191598.s,func_80191598,0x80191598,0x21 -asm/non_matchings/code/audio_load/func_8019161C.s,func_8019161C,0x8019161C,0x49 -asm/non_matchings/code/audio_load/func_80191740.s,func_80191740,0x80191740,0x49 -asm/non_matchings/code/audio_load/func_80191864.s,func_80191864,0x80191864,0x3 -asm/non_matchings/code/audio_load/func_80191870.s,func_80191870,0x80191870,0x4F -asm/non_matchings/code/audio_load/func_801919AC.s,func_801919AC,0x801919AC,0x65 -asm/non_matchings/code/audio_load/func_80191B40.s,func_80191B40,0x80191B40,0x24 -asm/non_matchings/code/audio_load/func_80191BD0.s,func_80191BD0,0x80191BD0,0x1C -asm/non_matchings/code/audio_load/func_80191C40.s,func_80191C40,0x80191C40,0x5 -asm/non_matchings/code/audio_load/func_80191C54.s,func_80191C54,0x80191C54,0x50 -asm/non_matchings/code/audio_load/func_80191D94.s,func_80191D94,0x80191D94,0xFE -asm/non_matchings/code/audio_load/func_8019218C.s,func_8019218C,0x8019218C,0x6D -asm/non_matchings/code/audio_load/func_80192340.s,func_80192340,0x80192340,0x12 -asm/non_matchings/code/audio_load/func_80192388.s,func_80192388,0x80192388,0x4D -asm/non_matchings/code/audio_load/func_801924BC.s,func_801924BC,0x801924BC,0x16 -asm/non_matchings/code/audio_load/func_80192514.s,func_80192514,0x80192514,0x11F -asm/non_matchings/code/audio_load/func_80192990.s,func_80192990,0x80192990,0x50 -asm/non_matchings/code/audio_load/func_80192AD0.s,func_80192AD0,0x80192AD0,0x2 -asm/non_matchings/code/audio_load/func_80192AD8.s,func_80192AD8,0x80192AD8,0x2 -asm/non_matchings/code/audio_load/func_80192AE0.s,func_80192AE0,0x80192AE0,0x2 -asm/non_matchings/code/audio_load/func_80192AE8.s,func_80192AE8,0x80192AE8,0x1B -asm/non_matchings/code/audio_load/func_80192B54.s,func_80192B54,0x80192B54,0x16 -asm/non_matchings/code/audio_load/func_80192BAC.s,func_80192BAC,0x80192BAC,0xD +asm/non_matchings/code/audio_load/AudioLoad_SyncInitSeqPlayer.s,AudioLoad_SyncInitSeqPlayer,0x8018FAD0,0x14 +asm/non_matchings/code/audio_load/AudioLoad_SyncInitSeqPlayerSkipTicks.s,AudioLoad_SyncInitSeqPlayerSkipTicks,0x8018FB20,0x16 +asm/non_matchings/code/audio_load/AudioLoad_SyncInitSeqPlayerInternal.s,AudioLoad_SyncInitSeqPlayerInternal,0x8018FB78,0x55 +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadSeq.s,AudioLoad_SyncLoadSeq,0x8018FCCC,0x15 +asm/non_matchings/code/audio_load/AudioLoad_GetSampleBank.s,AudioLoad_GetSampleBank,0x8018FD20,0x8 +asm/non_matchings/code/audio_load/AudioLoad_TrySyncLoadSampleBank.s,AudioLoad_TrySyncLoadSampleBank,0x8018FD40,0x47 +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadFont.s,AudioLoad_SyncLoadFont,0x8018FE5C,0x41 +asm/non_matchings/code/audio_load/AudioLoad_SyncLoad.s,AudioLoad_SyncLoad,0x8018FF60,0xA9 +asm/non_matchings/code/audio_load/AudioLoad_GetRealTableIndex.s,AudioLoad_GetRealTableIndex,0x80190204,0xF +asm/non_matchings/code/audio_load/AudioLoad_SearchCaches.s,AudioLoad_SearchCaches,0x80190240,0x15 +asm/non_matchings/code/audio_load/AudioLoad_GetLoadTable.s,AudioLoad_GetLoadTable,0x80190294,0x11 +asm/non_matchings/code/audio_load/AudioLoad_RelocateFont.s,AudioLoad_RelocateFont,0x801902D8,0x9B +asm/non_matchings/code/audio_load/AudioLoad_SyncDma.s,AudioLoad_SyncDma,0x80190544,0x49 +asm/non_matchings/code/audio_load/AudioLoad_SyncDmaUnkMedium.s,AudioLoad_SyncDmaUnkMedium,0x80190668,0x5 +asm/non_matchings/code/audio_load/AudioLoad_Dma.s,AudioLoad_Dma,0x8019067C,0x36 +asm/non_matchings/code/audio_load/AudioLoad_Unused1.s,AudioLoad_Unused1,0x80190754,0x2 +asm/non_matchings/code/audio_load/AudioLoad_SyncLoadSimple.s,AudioLoad_SyncLoadSimple,0x8019075C,0x8 +asm/non_matchings/code/audio_load/AudioLoad_AsyncLoadInner.s,AudioLoad_AsyncLoadInner,0x8019077C,0xE3 +asm/non_matchings/code/audio_load/AudioLoad_ProcessLoads.s,AudioLoad_ProcessLoads,0x80190B08,0xC +asm/non_matchings/code/audio_load/AudioLoad_SetDmaHandler.s,AudioLoad_SetDmaHandler,0x80190B38,0x3 +asm/non_matchings/code/audio_load/AudioLoad_SetUnusedHandler.s,AudioLoad_SetUnusedHandler,0x80190B44,0x3 +asm/non_matchings/code/audio_load/AudioLoad_InitSoundFontMeta.s,AudioLoad_InitSoundFontMeta,0x80190B50,0x18 +asm/non_matchings/code/audio_load/AudioLoad_Init.s,AudioLoad_Init,0x80190BB0,0xE8 +asm/non_matchings/code/audio_load/AudioLoad_InitSlowLoads.s,AudioLoad_InitSlowLoads,0x80190F50,0x5 +asm/non_matchings/code/audio_load/AudioLoad_SlowLoadSample.s,AudioLoad_SlowLoadSample,0x80190F64,0x74 +asm/non_matchings/code/audio_load/AudioLoad_GetFontSample.s,AudioLoad_GetFontSample,0x80191134,0x24 +asm/non_matchings/code/audio_load/AudioLoad_Unused2.s,AudioLoad_Unused2,0x801911C4,0x2 +asm/non_matchings/code/audio_load/AudioLoad_FinishSlowLoad.s,AudioLoad_FinishSlowLoad,0x801911CC,0x1D +asm/non_matchings/code/audio_load/AudioLoad_ProcessSlowLoads.s,AudioLoad_ProcessSlowLoads,0x80191240,0x62 +asm/non_matchings/code/audio_load/AudioLoad_DmaSlowCopy.s,AudioLoad_DmaSlowCopy,0x801913C8,0x21 +asm/non_matchings/code/audio_load/AudioLoad_DmaSlowCopyUnkMedium.s,AudioLoad_DmaSlowCopyUnkMedium,0x8019144C,0x5 +asm/non_matchings/code/audio_load/AudioLoad_SlowLoadSeq.s,AudioLoad_SlowLoadSeq,0x80191460,0x42 +asm/non_matchings/code/audio_load/AudioLoad_InitAsyncLoads.s,AudioLoad_InitAsyncLoads,0x80191568,0xC +asm/non_matchings/code/audio_load/AudioLoad_StartAsyncLoadUnkMedium.s,AudioLoad_StartAsyncLoadUnkMedium,0x80191598,0x21 +asm/non_matchings/code/audio_load/AudioLoad_StartAsyncLoad.s,AudioLoad_StartAsyncLoad,0x8019161C,0x49 +asm/non_matchings/code/audio_load/AudioLoad_ProcessAsyncLoads.s,AudioLoad_ProcessAsyncLoads,0x80191740,0x49 +asm/non_matchings/code/audio_load/AudioLoad_ProcessAsyncLoadUnkMedium.s,AudioLoad_ProcessAsyncLoadUnkMedium,0x80191864,0x3 +asm/non_matchings/code/audio_load/AudioLoad_FinishAsyncLoad.s,AudioLoad_FinishAsyncLoad,0x80191870,0x4F +asm/non_matchings/code/audio_load/AudioLoad_ProcessAsyncLoad.s,AudioLoad_ProcessAsyncLoad,0x801919AC,0x65 +asm/non_matchings/code/audio_load/AudioLoad_AsyncDma.s,AudioLoad_AsyncDma,0x80191B40,0x24 +asm/non_matchings/code/audio_load/AudioLoad_AsyncDmaRamUnloaded.s,AudioLoad_AsyncDmaRamUnloaded,0x80191BD0,0x1C +asm/non_matchings/code/audio_load/AudioLoad_AsyncDmaUnkMedium.s,AudioLoad_AsyncDmaUnkMedium,0x80191C40,0x5 +asm/non_matchings/code/audio_load/AudioLoad_RelocateSample.s,AudioLoad_RelocateSample,0x80191C54,0x50 +asm/non_matchings/code/audio_load/AudioLoad_RelocateFontAndPreloadSamples.s,AudioLoad_RelocateFontAndPreloadSamples,0x80191D94,0xFE +asm/non_matchings/code/audio_load/AudioLoad_ProcessSamplePreloads.s,AudioLoad_ProcessSamplePreloads,0x8019218C,0x6D +asm/non_matchings/code/audio_load/AudioLoad_AddToSampleSet.s,AudioLoad_AddToSampleSet,0x80192340,0x12 +asm/non_matchings/code/audio_load/AudioLoad_GetSamplesForFont.s,AudioLoad_GetSamplesForFont,0x80192388,0x4D +asm/non_matchings/code/audio_load/AudioLoad_AddUsedSample.s,AudioLoad_AddUsedSample,0x801924BC,0x16 +asm/non_matchings/code/audio_load/AudioLoad_PreloadSamplesForFont.s,AudioLoad_PreloadSamplesForFont,0x80192514,0x11F +asm/non_matchings/code/audio_load/AudioLoad_LoadPermanentSamples.s,AudioLoad_LoadPermanentSamples,0x80192990,0x50 +asm/non_matchings/code/audio_load/AudioLoad_Unused3.s,AudioLoad_Unused3,0x80192AD0,0x2 +asm/non_matchings/code/audio_load/AudioLoad_Unused4.s,AudioLoad_Unused4,0x80192AD8,0x2 +asm/non_matchings/code/audio_load/AudioLoad_Unused5.s,AudioLoad_Unused5,0x80192AE0,0x2 +asm/non_matchings/code/audio_load/AudioLoad_ScriptLoad.s,AudioLoad_ScriptLoad,0x80192AE8,0x1B +asm/non_matchings/code/audio_load/AudioLoad_ProcessScriptLoads.s,AudioLoad_ProcessScriptLoads,0x80192B54,0x16 +asm/non_matchings/code/audio_load/AudioLoad_InitScriptLoads.s,AudioLoad_InitScriptLoads,0x80192BAC,0xD asm/non_matchings/code/code_80192BE0/func_80192BE0.s,func_80192BE0,0x80192BE0,0x8 asm/non_matchings/code/code_80192BE0/func_80192C00.s,func_80192C00,0x80192C00,0x167 asm/non_matchings/code/code_80192BE0/func_8019319C.s,func_8019319C,0x8019319C,0x14F @@ -3207,7 +3205,7 @@ asm/non_matchings/code/code_80192BE0/func_80193774.s,func_80193774,0x80193774,0x asm/non_matchings/code/code_80192BE0/func_8019380C.s,func_8019380C,0x8019380C,0x13 asm/non_matchings/code/code_80192BE0/func_80193858.s,func_80193858,0x80193858,0x9 asm/non_matchings/code/code_80192BE0/func_8019387C.s,func_8019387C,0x8019387C,0x9 -asm/non_matchings/code/code_80192BE0/func_801938A0.s,func_801938A0,0x801938A0,0xC +asm/non_matchings/code/code_80192BE0/Audio_QueueCmdS8.s,Audio_QueueCmdS8,0x801938A0,0xC asm/non_matchings/code/code_80192BE0/func_801938D0.s,func_801938D0,0x801938D0,0xC asm/non_matchings/code/code_80192BE0/func_80193900.s,func_80193900,0x80193900,0x24 asm/non_matchings/code/code_80192BE0/func_80193990.s,func_80193990,0x80193990,0x6 @@ -3236,69 +3234,69 @@ asm/non_matchings/code/code_80192BE0/func_8019440C.s,func_8019440C,0x8019440C,0x asm/non_matchings/code/code_80192BE0/func_80194528.s,func_80194528,0x80194528,0x8 asm/non_matchings/code/code_80192BE0/func_80194548.s,func_80194548,0x80194548,0x8 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_80192BE0/Audio_NextRandom.s,Audio_NextRandom,0x80194668,0x1F +asm/non_matchings/code/code_80192BE0/Audio_InitMesgQueues.s,Audio_InitMesgQueues,0x801946E4,0xB +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 asm/non_matchings/code/code_80194710/func_801948B0.s,func_801948B0,0x801948B0,0x20 -asm/non_matchings/code/audio_playback/func_80194930.s,func_80194930,0x80194930,0x120 -asm/non_matchings/code/audio_playback/func_80194DB0.s,func_80194DB0,0x80194DB0,0x2C -asm/non_matchings/code/audio_playback/func_80194E60.s,func_80194E60,0x80194E60,0x30 -asm/non_matchings/code/audio_playback/func_80194F20.s,func_80194F20,0x80194F20,0x19 -asm/non_matchings/code/audio_playback/func_80194F84.s,func_80194F84,0x80194F84,0x152 -asm/non_matchings/code/audio_playback/func_801954CC.s,func_801954CC,0x801954CC,0xF -asm/non_matchings/code/audio_playback/func_80195508.s,func_80195508,0x80195508,0x35 -asm/non_matchings/code/audio_playback/func_801955DC.s,func_801955DC,0x801955DC,0x39 -asm/non_matchings/code/audio_playback/func_801956C0.s,func_801956C0,0x801956C0,0x3D -asm/non_matchings/code/audio_playback/func_801957B4.s,func_801957B4,0x801957B4,0x51 -asm/non_matchings/code/audio_playback/func_801958F8.s,func_801958F8,0x801958F8,0xD2 -asm/non_matchings/code/audio_playback/func_80195C40.s,func_80195C40,0x80195C40,0x8 -asm/non_matchings/code/audio_playback/func_80195C60.s,func_80195C60,0x80195C60,0x8 -asm/non_matchings/code/audio_playback/func_80195C80.s,func_80195C80,0x80195C80,0x41 -asm/non_matchings/code/audio_playback/func_80195D84.s,func_80195D84,0x80195D84,0x16 -asm/non_matchings/code/audio_playback/func_80195DDC.s,func_80195DDC,0x80195DDC,0x4 -asm/non_matchings/code/audio_playback/func_80195DEC.s,func_80195DEC,0x80195DEC,0x14 -asm/non_matchings/code/audio_playback/func_80195E3C.s,func_80195E3C,0x80195E3C,0x29 -asm/non_matchings/code/audio_playback/func_80195EE0.s,func_80195EE0,0x80195EE0,0x58 -asm/non_matchings/code/audio_playback/func_80196040.s,func_80196040,0x80196040,0x4F -asm/non_matchings/code/audio_playback/func_8019617C.s,func_8019617C,0x8019617C,0x10 -asm/non_matchings/code/audio_playback/func_801961BC.s,func_801961BC,0x801961BC,0xB -asm/non_matchings/code/audio_playback/func_801961E8.s,func_801961E8,0x801961E8,0x20 -asm/non_matchings/code/audio_playback/func_80196268.s,func_80196268,0x80196268,0x60 +asm/non_matchings/code/audio_playback/AudioPlayback_InitNoteSub.s,AudioPlayback_InitNoteSub,0x80194930,0x120 +asm/non_matchings/code/audio_playback/AudioPlayback_NoteSetResamplingRate.s,AudioPlayback_NoteSetResamplingRate,0x80194DB0,0x2C +asm/non_matchings/code/audio_playback/AudioPlayback_NoteInit.s,AudioPlayback_NoteInit,0x80194E60,0x30 +asm/non_matchings/code/audio_playback/AudioPlayback_NoteDisable.s,AudioPlayback_NoteDisable,0x80194F20,0x19 +asm/non_matchings/code/audio_playback/AudioPlayback_ProcessNotes.s,AudioPlayback_ProcessNotes,0x80194F84,0x152 +asm/non_matchings/code/audio_playback/AudioPlayback_InstrumentGetSound.s,AudioPlayback_InstrumentGetSound,0x801954CC,0xF +asm/non_matchings/code/audio_playback/AudioPlayback_GetInstrumentInner.s,AudioPlayback_GetInstrumentInner,0x80195508,0x35 +asm/non_matchings/code/audio_playback/AudioPlayback_GetDrum.s,AudioPlayback_GetDrum,0x801955DC,0x39 +asm/non_matchings/code/audio_playback/AudioPlayback_GetSfx.s,AudioPlayback_GetSfx,0x801956C0,0x3D +asm/non_matchings/code/audio_playback/AudioPlayback_SetFontInstrument.s,AudioPlayback_SetFontInstrument,0x801957B4,0x51 +asm/non_matchings/code/audio_playback/AudioPlayback_SeqLayerDecayRelease.s,AudioPlayback_SeqLayerDecayRelease,0x801958F8,0xD2 +asm/non_matchings/code/audio_playback/AudioPlayback_SeqLayerNoteDecay.s,AudioPlayback_SeqLayerNoteDecay,0x80195C40,0x8 +asm/non_matchings/code/audio_playback/AudioPlayback_SeqLayerNoteRelease.s,AudioPlayback_SeqLayerNoteRelease,0x80195C60,0x8 +asm/non_matchings/code/audio_playback/AudioPlayback_BuildSyntheticWave.s,AudioPlayback_BuildSyntheticWave,0x80195C80,0x41 +asm/non_matchings/code/audio_playback/AudioPlayback_InitSyntheticWave.s,AudioPlayback_InitSyntheticWave,0x80195D84,0x16 +asm/non_matchings/code/audio_playback/AudioPlayback_InitNoteList.s,AudioPlayback_InitNoteList,0x80195DDC,0x4 +asm/non_matchings/code/audio_playback/AudioPlayback_InitNoteLists.s,AudioPlayback_InitNoteLists,0x80195DEC,0x14 +asm/non_matchings/code/audio_playback/AudioPlayback_InitNoteFreeList.s,AudioPlayback_InitNoteFreeList,0x80195E3C,0x29 +asm/non_matchings/code/audio_playback/AudioPlayback_NotePoolClear.s,AudioPlayback_NotePoolClear,0x80195EE0,0x58 +asm/non_matchings/code/audio_playback/AudioPlayback_NotePoolFill.s,AudioPlayback_NotePoolFill,0x80196040,0x4F +asm/non_matchings/code/audio_playback/AudioPlayback_AudioListPushFront.s,AudioPlayback_AudioListPushFront,0x8019617C,0x10 +asm/non_matchings/code/audio_playback/AudioPlayback_AudioListRemove.s,AudioPlayback_AudioListRemove,0x801961BC,0xB +asm/non_matchings/code/audio_playback/AudioPlayback_FindNodeWithPrioLessThan.s,AudioPlayback_FindNodeWithPrioLessThan,0x801961E8,0x20 +asm/non_matchings/code/audio_playback/AudioPlayback_NoteInitForLayer.s,AudioPlayback_NoteInitForLayer,0x80196268,0x60 asm/non_matchings/code/audio_playback/func_801963E8.s,func_801963E8,0x801963E8,0xD -asm/non_matchings/code/audio_playback/func_8019641C.s,func_8019641C,0x8019641C,0xB -asm/non_matchings/code/audio_playback/func_80196448.s,func_80196448,0x80196448,0x13 -asm/non_matchings/code/audio_playback/func_80196494.s,func_80196494,0x80196494,0x19 -asm/non_matchings/code/audio_playback/func_801964F8.s,func_801964F8,0x801964F8,0x3E -asm/non_matchings/code/audio_playback/func_801965F0.s,func_801965F0,0x801965F0,0xB5 -asm/non_matchings/code/audio_playback/func_801968C4.s,func_801968C4,0x801968C4,0x4F -asm/non_matchings/code/audio_effects/func_80196A00.s,func_80196A00,0x80196A00,0x72 -asm/non_matchings/code/audio_effects/func_80196BC8.s,func_80196BC8,0x80196BC8,0x56 -asm/non_matchings/code/audio_effects/func_80196D20.s,func_80196D20,0x80196D20,0x17 -asm/non_matchings/code/audio_effects/func_80196D7C.s,func_80196D7C,0x80196D7C,0xE -asm/non_matchings/code/audio_effects/func_80196DB4.s,func_80196DB4,0x80196DB4,0x8E -asm/non_matchings/code/audio_effects/func_80196FEC.s,func_80196FEC,0x80196FEC,0x17 -asm/non_matchings/code/audio_effects/func_80197048.s,func_80197048,0x80197048,0x3C -asm/non_matchings/code/audio_effects/func_80197138.s,func_80197138,0x80197138,0xB -asm/non_matchings/code/audio_effects/func_80197164.s,func_80197164,0x80197164,0x9 -asm/non_matchings/code/audio_effects/func_80197188.s,func_80197188,0x80197188,0xD2 +asm/non_matchings/code/audio_playback/AudioPlayback_NoteReleaseAndTakeOwnership.s,AudioPlayback_NoteReleaseAndTakeOwnership,0x8019641C,0xB +asm/non_matchings/code/audio_playback/AudioPlayback_AllocNoteFromDisabled.s,AudioPlayback_AllocNoteFromDisabled,0x80196448,0x13 +asm/non_matchings/code/audio_playback/AudioPlayback_AllocNoteFromDecaying.s,AudioPlayback_AllocNoteFromDecaying,0x80196494,0x19 +asm/non_matchings/code/audio_playback/AudioPlayback_AllocNoteFromActive.s,AudioPlayback_AllocNoteFromActive,0x801964F8,0x3E +asm/non_matchings/code/audio_playback/AudioPlayback_AllocNote.s,AudioPlayback_AllocNote,0x801965F0,0xB5 +asm/non_matchings/code/audio_playback/AudioPlayback_NoteInitAll.s,AudioPlayback_NoteInitAll,0x801968C4,0x4F +asm/non_matchings/code/audio_effects/AudioEffects_SequenceChannelProcessSound.s,AudioEffects_SequenceChannelProcessSound,0x80196A00,0x72 +asm/non_matchings/code/audio_effects/AudioEffects_SequencePlayerProcessSound.s,AudioEffects_SequencePlayerProcessSound,0x80196BC8,0x56 +asm/non_matchings/code/audio_effects/AudioEffects_GetPortamentoFreqScale.s,AudioEffects_GetPortamentoFreqScale,0x80196D20,0x17 +asm/non_matchings/code/audio_effects/AudioEffects_GetVibratoPitchChange.s,AudioEffects_GetVibratoPitchChange,0x80196D7C,0xE +asm/non_matchings/code/audio_effects/AudioEffects_GetVibratoFreqScale.s,AudioEffects_GetVibratoFreqScale,0x80196DB4,0x8E +asm/non_matchings/code/audio_effects/AudioEffects_NoteVibratoUpdate.s,AudioEffects_NoteVibratoUpdate,0x80196FEC,0x17 +asm/non_matchings/code/audio_effects/AudioEffects_NoteVibratoInit.s,AudioEffects_NoteVibratoInit,0x80197048,0x3C +asm/non_matchings/code/audio_effects/AudioEffects_NotePortamentoInit.s,AudioEffects_NotePortamentoInit,0x80197138,0xB +asm/non_matchings/code/audio_effects/AudioEffects_AdsrInit.s,AudioEffects_AdsrInit,0x80197164,0x9 +asm/non_matchings/code/audio_effects/AudioEffects_AdsrUpdate.s,AudioEffects_AdsrUpdate,0x80197188,0xD2 asm/non_matchings/code/audio_seqplayer/func_801974D0.s,func_801974D0,0x801974D0,0x1A asm/non_matchings/code/audio_seqplayer/func_80197538.s,func_80197538,0x80197538,0x77 asm/non_matchings/code/audio_seqplayer/func_80197714.s,func_80197714,0x80197714,0x5B asm/non_matchings/code/audio_seqplayer/func_80197880.s,func_80197880,0x80197880,0x56 asm/non_matchings/code/audio_seqplayer/func_801979D8.s,func_801979D8,0x801979D8,0x1F asm/non_matchings/code/audio_seqplayer/func_80197A54.s,func_80197A54,0x80197A54,0x14 -asm/non_matchings/code/audio_seqplayer/func_80197AA4.s,func_80197AA4,0x80197AA4,0x1C +asm/non_matchings/code/audio_seqplayer/AudioSeq_SequenceChannelDisable.s,AudioSeq_SequenceChannelDisable,0x80197AA4,0x1C asm/non_matchings/code/audio_seqplayer/func_80197B14.s,func_80197B14,0x80197B14,0x3E asm/non_matchings/code/audio_seqplayer/func_80197C0C.s,func_80197C0C,0x80197C0C,0x20 asm/non_matchings/code/audio_seqplayer/func_80197C8C.s,func_80197C8C,0x80197C8C,0x26 -asm/non_matchings/code/audio_seqplayer/func_80197D24.s,func_80197D24,0x80197D24,0xA -asm/non_matchings/code/audio_seqplayer/func_80197D4C.s,func_80197D4C,0x80197D4C,0x2F -asm/non_matchings/code/audio_seqplayer/func_80197E08.s,func_80197E08,0x80197E08,0x10 -asm/non_matchings/code/audio_seqplayer/func_80197E48.s,func_80197E48,0x80197E48,0x10 +asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisableAsFinished.s,AudioSeq_SequencePlayerDisableAsFinished,0x80197D24,0xA +asm/non_matchings/code/audio_seqplayer/AudioSeq_SequencePlayerDisable.s,AudioSeq_SequencePlayerDisable,0x80197D4C,0x2F +asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPushBack.s,AudioSeq_AudioListPushBack,0x80197E08,0x10 +asm/non_matchings/code/audio_seqplayer/AudioSeq_AudioListPopBack.s,AudioSeq_AudioListPopBack,0x80197E48,0x10 asm/non_matchings/code/audio_seqplayer/func_80197E88.s,func_80197E88,0x80197E88,0x28 asm/non_matchings/code/audio_seqplayer/func_80197F28.s,func_80197F28,0x80197F28,0x5 asm/non_matchings/code/audio_seqplayer/func_80197F3C.s,func_80197F3C,0x80197F3C,0xE @@ -3317,23 +3315,23 @@ asm/non_matchings/code/audio_seqplayer/func_80199268.s,func_80199268,0x80199268, asm/non_matchings/code/audio_seqplayer/func_8019A0BC.s,func_8019A0BC,0x8019A0BC,0x260 asm/non_matchings/code/audio_seqplayer/func_8019AA3C.s,func_8019AA3C,0x8019AA3C,0x2D asm/non_matchings/code/audio_seqplayer/func_8019AAF0.s,func_8019AAF0,0x8019AAF0,0x14 -asm/non_matchings/code/audio_seqplayer/func_8019AB40.s,func_8019AB40,0x8019AB40,0x34 -asm/non_matchings/code/audio_seqplayer/func_8019AC10.s,func_8019AC10,0x8019AC10,0x37 +asm/non_matchings/code/audio_seqplayer/AudioSeq_ResetSequencePlayer.s,AudioSeq_ResetSequencePlayer,0x8019AB40,0x34 +asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayerChannels.s,AudioSeq_InitSequencePlayerChannels,0x8019AC10,0x37 asm/non_matchings/code/audio_seqplayer/func_8019ACEC.s,func_8019ACEC,0x8019ACEC,0x34 -asm/non_matchings/code/audio_seqplayer/func_8019ADBC.s,func_8019ADBC,0x8019ADBC,0x21 +asm/non_matchings/code/audio_seqplayer/AudioSeq_InitSequencePlayers.s,AudioSeq_InitSequencePlayers,0x8019ADBC,0x21 asm/non_matchings/code/code_8019AE40/func_8019AE40.s,func_8019AE40,0x8019AE40,0x1C asm/non_matchings/code/code_8019AEC0/func_8019AEC0.s,func_8019AEC0,0x8019AEC0,0x10 asm/non_matchings/code/code_8019AF00/func_8019AF00.s,func_8019AF00,0x8019AF00,0x16 asm/non_matchings/code/code_8019AF00/func_8019AF58.s,func_8019AF58,0x8019AF58,0x24 asm/non_matchings/code/code_8019AF00/func_8019AFE8.s,func_8019AFE8,0x8019AFE8,0x11 asm/non_matchings/code/code_8019AF00/func_8019B02C.s,func_8019B02C,0x8019B02C,0x12 -asm/non_matchings/code/code_8019AF00/func_8019B074.s,func_8019B074,0x8019B074,0x34 +asm/non_matchings/code/code_8019AF00/AudioOcarina_MapSongFromNotesToButtons.s,AudioOcarina_MapSongFromNotesToButtons,0x8019B074,0x34 asm/non_matchings/code/code_8019AF00/func_8019B144.s,func_8019B144,0x8019B144,0x8D asm/non_matchings/code/code_8019AF00/func_8019B378.s,func_8019B378,0x8019B378,0x5 asm/non_matchings/code/code_8019AF00/func_8019B38C.s,func_8019B38C,0x8019B38C,0x11 asm/non_matchings/code/code_8019AF00/func_8019B3D0.s,func_8019B3D0,0x8019B3D0,0x3A asm/non_matchings/code/code_8019AF00/func_8019B4B8.s,func_8019B4B8,0x8019B4B8,0x23 -asm/non_matchings/code/code_8019AF00/func_8019B544.s,func_8019B544,0x8019B544,0x9 +asm/non_matchings/code/code_8019AF00/AudioOcarina_StartDefault.s,AudioOcarina_StartDefault,0x8019B544,0x9 asm/non_matchings/code/code_8019AF00/func_8019B568.s,func_8019B568,0x8019B568,0x11 asm/non_matchings/code/code_8019AF00/func_8019B5AC.s,func_8019B5AC,0x8019B5AC,0x10 asm/non_matchings/code/code_8019AF00/func_8019B5EC.s,func_8019B5EC,0x8019B5EC,0xB @@ -3346,7 +3344,7 @@ asm/non_matchings/code/code_8019AF00/func_8019C1C0.s,func_8019C1C0,0x8019C1C0,0x asm/non_matchings/code/code_8019AF00/func_8019C1D0.s,func_8019C1D0,0x8019C1D0,0x26 asm/non_matchings/code/code_8019AF00/func_8019C268.s,func_8019C268,0x8019C268,0x1F asm/non_matchings/code/code_8019AF00/func_8019C2E4.s,func_8019C2E4,0x8019C2E4,0x7 -asm/non_matchings/code/code_8019AF00/func_8019C300.s,func_8019C300,0x8019C300,0x26 +asm/non_matchings/code/code_8019AF00/AudioOcarina_SetInstrumentId.s,AudioOcarina_SetInstrumentId,0x8019C300,0x26 asm/non_matchings/code/code_8019AF00/func_8019C398.s,func_8019C398,0x8019C398,0x82 asm/non_matchings/code/code_8019AF00/func_8019C5A0.s,func_8019C5A0,0x8019C5A0,0xCE asm/non_matchings/code/code_8019AF00/func_8019C8D8.s,func_8019C8D8,0x8019C8D8,0x10C @@ -3356,12 +3354,12 @@ asm/non_matchings/code/code_8019AF00/func_8019CE6C.s,func_8019CE6C,0x8019CE6C,0x asm/non_matchings/code/code_8019AF00/func_8019CEBC.s,func_8019CEBC,0x8019CEBC,0x2C asm/non_matchings/code/code_8019AF00/func_8019CF6C.s,func_8019CF6C,0x8019CF6C,0x3 asm/non_matchings/code/code_8019AF00/func_8019CF78.s,func_8019CF78,0x8019CF78,0x9 -asm/non_matchings/code/code_8019AF00/func_8019CF9C.s,func_8019CF9C,0x8019CF9C,0x3 +asm/non_matchings/code/code_8019AF00/AudioOcarina_GetPlaybackStaff.s,AudioOcarina_GetPlaybackStaff,0x8019CF9C,0x3 asm/non_matchings/code/code_8019AF00/func_8019CFA8.s,func_8019CFA8,0x8019CFA8,0x63 -asm/non_matchings/code/code_8019AF00/func_8019D134.s,func_8019D134,0x8019D134,0x4E -asm/non_matchings/code/code_8019AF00/func_8019D26C.s,func_8019D26C,0x8019D26C,0x87 -asm/non_matchings/code/code_8019AF00/func_8019D488.s,func_8019D488,0x8019D488,0x1C -asm/non_matchings/code/code_8019AF00/func_8019D4F8.s,func_8019D4F8,0x8019D4F8,0x42 +asm/non_matchings/code/code_8019AF00/AudioOcarina_TerminaWallValidateNotes.s,AudioOcarina_TerminaWallValidateNotes,0x8019D134,0x4E +asm/non_matchings/code/code_8019AF00/AudioOcarina_TerminaWallGenerateNotes.s,AudioOcarina_TerminaWallGenerateNotes,0x8019D26C,0x87 +asm/non_matchings/code/code_8019AF00/AudioOcarina_MemoryGameSetNumNotes.s,AudioOcarina_MemoryGameSetNumNotes,0x8019D488,0x1C +asm/non_matchings/code/code_8019AF00/AudioOcarina_MemoryGameGenerateNotes.s,AudioOcarina_MemoryGameGenerateNotes,0x8019D4F8,0x42 asm/non_matchings/code/code_8019AF00/func_8019D600.s,func_8019D600,0x8019D600,0x56 asm/non_matchings/code/code_8019AF00/func_8019D758.s,func_8019D758,0x8019D758,0x43 asm/non_matchings/code/code_8019AF00/func_8019D864.s,func_8019D864,0x8019D864,0x14 @@ -3388,7 +3386,7 @@ asm/non_matchings/code/code_8019AF00/func_8019F05C.s,func_8019F05C,0x8019F05C,0x asm/non_matchings/code/code_8019AF00/play_sound.s,play_sound,0x8019F0C8,0x18 asm/non_matchings/code/code_8019AF00/func_8019F128.s,func_8019F128,0x8019F128,0x12 asm/non_matchings/code/code_8019AF00/func_8019F170.s,func_8019F170,0x8019F170,0x14 -asm/non_matchings/code/code_8019AF00/func_8019F1C0.s,func_8019F1C0,0x8019F1C0,0x12 +asm/non_matchings/code/code_8019AF00/Audio_PlaySfxAtPos.s,Audio_PlaySfxAtPos,0x8019F1C0,0x12 asm/non_matchings/code/code_8019AF00/func_8019F208.s,func_8019F208,0x8019F208,0xA asm/non_matchings/code/code_8019AF00/func_8019F230.s,func_8019F230,0x8019F230,0xA asm/non_matchings/code/code_8019AF00/func_8019F258.s,func_8019F258,0x8019F258,0x2A @@ -3415,18 +3413,18 @@ asm/non_matchings/code/code_8019AF00/func_8019FE1C.s,func_8019FE1C,0x8019FE1C,0x asm/non_matchings/code/code_8019AF00/func_8019FE74.s,func_8019FE74,0x8019FE74,0x1A asm/non_matchings/code/code_8019AF00/func_8019FEDC.s,func_8019FEDC,0x8019FEDC,0x17 asm/non_matchings/code/code_8019AF00/func_8019FF38.s,func_8019FF38,0x8019FF38,0x19 -asm/non_matchings/code/code_8019AF00/func_8019FF9C.s,func_8019FF9C,0x8019FF9C,0x2B -asm/non_matchings/code/code_8019AF00/func_801A0048.s,func_801A0048,0x801A0048,0x29 -asm/non_matchings/code/code_8019AF00/func_801A00EC.s,func_801A00EC,0x801A00EC,0xE +asm/non_matchings/code/code_8019AF00/Audio_PlaySfxForRiver.s,Audio_PlaySfxForRiver,0x8019FF9C,0x2B +asm/non_matchings/code/code_8019AF00/Audio_PlaySfxForWaterfall.s,Audio_PlaySfxForWaterfall,0x801A0048,0x29 +asm/non_matchings/code/code_8019AF00/Audio_StepFreqLerp.s,Audio_StepFreqLerp,0x801A00EC,0xE asm/non_matchings/code/code_8019AF00/func_801A0124.s,func_801A0124,0x801A0124,0x18 asm/non_matchings/code/code_8019AF00/func_801A0184.s,func_801A0184,0x801A0184,0x10 asm/non_matchings/code/code_8019AF00/func_801A01C4.s,func_801A01C4,0x801A01C4,0x10 asm/non_matchings/code/code_8019AF00/func_801A0204.s,func_801A0204,0x801A0204,0xD asm/non_matchings/code/code_8019AF00/func_801A0238.s,func_801A0238,0x801A0238,0xD -asm/non_matchings/code/code_8019AF00/func_801A026C.s,func_801A026C,0x801A026C,0x2B -asm/non_matchings/code/code_8019AF00/func_801A0318.s,func_801A0318,0x801A0318,0x4E -asm/non_matchings/code/code_8019AF00/func_801A0450.s,func_801A0450,0x801A0450,0x7 -asm/non_matchings/code/code_8019AF00/func_801A046C.s,func_801A046C,0x801A046C,0x3A +asm/non_matchings/code/code_8019AF00/Audio_SetGanonsTowerBgmVolumeLevel.s,Audio_SetGanonsTowerBgmVolumeLevel,0x801A026C,0x2B +asm/non_matchings/code/code_8019AF00/Audio_SetGanonsTowerBgmVolume.s,Audio_SetGanonsTowerBgmVolume,0x801A0318,0x4E +asm/non_matchings/code/code_8019AF00/Audio_LowerMainBgmVolume.s,Audio_LowerMainBgmVolume,0x801A0450,0x7 +asm/non_matchings/code/code_8019AF00/Audio_UpdateRiverSoundVolumes.s,Audio_UpdateRiverSoundVolumes,0x801A046C,0x3A asm/non_matchings/code/code_8019AF00/func_801A0554.s,func_801A0554,0x801A0554,0x24 asm/non_matchings/code/code_8019AF00/func_801A05E4.s,func_801A05E4,0x801A05E4,0x3 asm/non_matchings/code/code_8019AF00/func_801A05F0.s,func_801A05F0,0x801A05F0,0x19 @@ -3434,9 +3432,9 @@ asm/non_matchings/code/code_8019AF00/func_801A0654.s,func_801A0654,0x801A0654,0x asm/non_matchings/code/code_8019AF00/func_801A0810.s,func_801A0810,0x801A0810,0x16 asm/non_matchings/code/code_8019AF00/func_801A0868.s,func_801A0868,0x801A0868,0x5B asm/non_matchings/code/code_8019AF00/func_801A09D4.s,func_801A09D4,0x801A09D4,0xA7 -asm/non_matchings/code/code_8019AF00/func_801A0C70.s,func_801A0C70,0x801A0C70,0x8 -asm/non_matchings/code/code_8019AF00/func_801A0C90.s,func_801A0C90,0x801A0C90,0x8 -asm/non_matchings/code/code_8019AF00/func_801A0CB0.s,func_801A0CB0,0x801A0CB0,0x65 +asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm.s,Audio_ClearSariaBgm,0x801A0C70,0x8 +asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgmAtPos.s,Audio_ClearSariaBgmAtPos,0x801A0C90,0x8 +asm/non_matchings/code/code_8019AF00/Audio_SplitBgmChannels.s,Audio_SplitBgmChannels,0x801A0CB0,0x65 asm/non_matchings/code/code_8019AF00/func_801A0E44.s,func_801A0E44,0x801A0E44,0x113 asm/non_matchings/code/code_8019AF00/func_801A1290.s,func_801A1290,0x801A1290,0x2E asm/non_matchings/code/code_8019AF00/func_801A1348.s,func_801A1348,0x801A1348,0x1D @@ -3453,8 +3451,8 @@ asm/non_matchings/code/code_8019AF00/func_801A1F00.s,func_801A1F00,0x801A1F00,0x asm/non_matchings/code/code_8019AF00/func_801A1F88.s,func_801A1F88,0x801A1F88,0xB asm/non_matchings/code/code_8019AF00/func_801A1FB4.s,func_801A1FB4,0x801A1FB4,0x37 asm/non_matchings/code/code_8019AF00/func_801A2090.s,func_801A2090,0x801A2090,0x5B -asm/non_matchings/code/code_8019AF00/func_801A21FC.s,func_801A21FC,0x801A21FC,0x99 -asm/non_matchings/code/code_8019AF00/func_801A2460.s,func_801A2460,0x801A2460,0x3 +asm/non_matchings/code/code_8019AF00/Audio_PlaySariaBgm.s,Audio_PlaySariaBgm,0x801A21FC,0x99 +asm/non_matchings/code/code_8019AF00/Audio_ClearSariaBgm2.s,Audio_ClearSariaBgm2,0x801A2460,0x3 asm/non_matchings/code/code_8019AF00/func_801A246C.s,func_801A246C,0x801A246C,0x36 asm/non_matchings/code/code_8019AF00/func_801A2544.s,func_801A2544,0x801A2544,0xE asm/non_matchings/code/code_8019AF00/func_801A257C.s,func_801A257C,0x801A257C,0x1A @@ -3469,7 +3467,7 @@ asm/non_matchings/code/code_8019AF00/func_801A2C20.s,func_801A2C20,0x801A2C20,0x asm/non_matchings/code/code_8019AF00/func_801A2C44.s,func_801A2C44,0x801A2C44,0x11 asm/non_matchings/code/code_8019AF00/func_801A2C88.s,func_801A2C88,0x801A2C88,0x33 asm/non_matchings/code/code_8019AF00/func_801A2D54.s,func_801A2D54,0x801A2D54,0x23 -asm/non_matchings/code/code_8019AF00/func_801A2DE0.s,func_801A2DE0,0x801A2DE0,0x1D +asm/non_matchings/code/code_8019AF00/Audio_IsSequencePlaying.s,Audio_IsSequencePlaying,0x801A2DE0,0x1D asm/non_matchings/code/code_8019AF00/func_801A2E54.s,func_801A2E54,0x801A2E54,0x21 asm/non_matchings/code/code_8019AF00/func_801A2ED8.s,func_801A2ED8,0x801A2ED8,0x2C asm/non_matchings/code/code_8019AF00/func_801A2F88.s,func_801A2F88,0x801A2F88,0xF @@ -3496,7 +3494,7 @@ asm/non_matchings/code/code_8019AF00/func_801A3D54.s,func_801A3D54,0x801A3D54,0x asm/non_matchings/code/code_8019AF00/func_801A3D98.s,func_801A3D98,0x801A3D98,0x28 asm/non_matchings/code/code_8019AF00/func_801A3E38.s,func_801A3E38,0x801A3E38,0x22 asm/non_matchings/code/code_8019AF00/func_801A3EC0.s,func_801A3EC0,0x801A3EC0,0x25 -asm/non_matchings/code/code_8019AF00/func_801A3F54.s,func_801A3F54,0x801A3F54,0x6 +asm/non_matchings/code/code_8019AF00/Audio_SetCutsceneFlag.s,Audio_SetCutsceneFlag,0x801A3F54,0x6 asm/non_matchings/code/code_8019AF00/func_801A3F6C.s,func_801A3F6C,0x801A3F6C,0x12 asm/non_matchings/code/code_8019AF00/func_801A3FB4.s,func_801A3FB4,0x801A3FB4,0x12 asm/non_matchings/code/code_8019AF00/func_801A3FFC.s,func_801A3FFC,0x801A3FFC,0x4 @@ -3551,7 +3549,7 @@ asm/non_matchings/code/code_801A51F0/func_801A5A1C.s,func_801A5A1C,0x801A5A1C,0x asm/non_matchings/code/code_801A5BD0/func_801A5BD0.s,func_801A5BD0,0x801A5BD0,0x16 asm/non_matchings/code/code_801A5BD0/func_801A5C28.s,func_801A5C28,0x801A5C28,0x19 asm/non_matchings/code/code_801A5BD0/func_801A5C8C.s,func_801A5C8C,0x801A5C8C,0x1C -asm/non_matchings/code/code_801A5BD0/func_801A5CFC.s,func_801A5CFC,0x801A5CFC,0x38 +asm/non_matchings/code/code_801A5BD0/Audio_PlaySfxGeneral.s,Audio_PlaySfxGeneral,0x801A5CFC,0x38 asm/non_matchings/code/code_801A5BD0/func_801A5DDC.s,func_801A5DDC,0x801A5DDC,0x68 asm/non_matchings/code/code_801A5BD0/func_801A5F7C.s,func_801A5F7C,0x801A5F7C,0x12D asm/non_matchings/code/code_801A5BD0/func_801A6430.s,func_801A6430,0x801A6430,0x66 @@ -3560,7 +3558,7 @@ asm/non_matchings/code/code_801A5BD0/func_801A6D0C.s,func_801A6D0C,0x801A6D0C,0x asm/non_matchings/code/code_801A5BD0/func_801A7084.s,func_801A7084,0x801A7084,0x39 asm/non_matchings/code/code_801A5BD0/func_801A7168.s,func_801A7168,0x801A7168,0x47 asm/non_matchings/code/code_801A5BD0/func_801A7284.s,func_801A7284,0x801A7284,0x12 -asm/non_matchings/code/code_801A5BD0/func_801A72CC.s,func_801A72CC,0x801A72CC,0x17 +asm/non_matchings/code/code_801A5BD0/Audio_StopSfxByPos.s,Audio_StopSfxByPos,0x801A72CC,0x17 asm/non_matchings/code/code_801A5BD0/func_801A7328.s,func_801A7328,0x801A7328,0x57 asm/non_matchings/code/code_801A5BD0/func_801A7484.s,func_801A7484,0x801A7484,0x59 asm/non_matchings/code/code_801A5BD0/func_801A75E8.s,func_801A75E8,0x801A75E8,0x4E @@ -3568,7 +3566,7 @@ asm/non_matchings/code/code_801A5BD0/func_801A7720.s,func_801A7720,0x801A7720,0x asm/non_matchings/code/code_801A5BD0/func_801A7794.s,func_801A7794,0x801A7794,0x25 asm/non_matchings/code/code_801A5BD0/func_801A7828.s,func_801A7828,0x801A7828,0x15 asm/non_matchings/code/code_801A5BD0/func_801A787C.s,func_801A787C,0x801A787C,0x1A -asm/non_matchings/code/code_801A5BD0/func_801A78E4.s,func_801A78E4,0x801A78E4,0x1A +asm/non_matchings/code/code_801A5BD0/Audio_IsSfxPlaying.s,Audio_IsSfxPlaying,0x801A78E4,0x1A asm/non_matchings/code/code_801A5BD0/func_801A794C.s,func_801A794C,0x801A794C,0x71 asm/non_matchings/code/code_801A7B10/func_801A7B10.s,func_801A7B10,0x801A7B10,0x7D asm/non_matchings/code/code_801A7B10/func_801A7D04.s,func_801A7D04,0x801A7D04,0x20 @@ -3579,24 +3577,24 @@ asm/non_matchings/code/code_801A7B10/func_801A8A50.s,func_801A8A50,0x801A8A50,0x asm/non_matchings/code/code_801A7B10/func_801A8ABC.s,func_801A8ABC,0x801A8ABC,0x16 asm/non_matchings/code/code_801A7B10/func_801A8B14.s,func_801A8B14,0x801A8B14,0x6 asm/non_matchings/code/code_801A7B10/func_801A8B2C.s,func_801A8B2C,0x801A8B2C,0x29 -asm/non_matchings/code/code_801A7B10/func_801A8BD0.s,func_801A8BD0,0x801A8BD0,0x63 +asm/non_matchings/code/code_801A7B10/Audio_SetVolumeScale.s,Audio_SetVolumeScale,0x801A8BD0,0x63 asm/non_matchings/code/code_801A7B10/func_801A8D5C.s,func_801A8D5C,0x801A8D5C,0x283 asm/non_matchings/code/code_801A7B10/func_801A9768.s,func_801A9768,0x801A9768,0x31 asm/non_matchings/code/code_801A7B10/func_801A982C.s,func_801A982C,0x801A982C,0x63 asm/non_matchings/code/code_801A7B10/func_801A99B8.s,func_801A99B8,0x801A99B8,0x2F asm/non_matchings/code/code_801A7B10/func_801A9A74.s,func_801A9A74,0x801A9A74,0x27 -asm/non_matchings/code/code_801A7B10/func_801A9B10.s,func_801A9B10,0x801A9B10,0x1A -asm/non_matchings/code/code_801A7B10/func_801A9B78.s,func_801A9B78,0x801A9B78,0x21 -asm/non_matchings/code/code_801A7B10/func_801A9BFC.s,func_801A9BFC,0x801A9BFC,0x1B -asm/non_matchings/code/code_801A7B10/func_801A9C68.s,func_801A9C68,0x801A9C68,0x2A -asm/non_matchings/code/code_801A7B10/func_801A9D10.s,func_801A9D10,0x801A9D10,0x2F -asm/non_matchings/code/code_801A7B10/func_801A9DCC.s,func_801A9DCC,0x801A9DCC,0x36 -asm/non_matchings/code/code_801A7B10/func_801A9EA4.s,func_801A9EA4,0x801A9EA4,0x2A -asm/non_matchings/code/code_801A7B10/func_801A9F4C.s,func_801A9F4C,0x801A9F4C,0x35 -asm/non_matchings/code/code_801AA020/func_801AA020.s,func_801AA020,0x801AA020,0x8A -asm/non_matchings/code/code_801AA020/func_801AA248.s,func_801AA248,0x801AA248,0x67 -asm/non_matchings/code/code_801AA020/func_801AA3E4.s,func_801AA3E4,0x801AA3E4,0x4F -asm/non_matchings/code/code_801AA020/func_801AA520.s,func_801AA520,0x801AA520,0x3C +asm/non_matchings/code/jpegutils/JpegUtils_ProcessQuantizationTable.s,JpegUtils_ProcessQuantizationTable,0x801A9B10,0x1A +asm/non_matchings/code/jpegutils/JpegUtils_ParseHuffmanCodesLengths.s,JpegUtils_ParseHuffmanCodesLengths,0x801A9B78,0x21 +asm/non_matchings/code/jpegutils/JpegUtils_GetHuffmanCodes.s,JpegUtils_GetHuffmanCodes,0x801A9BFC,0x1B +asm/non_matchings/code/jpegutils/JpegUtils_SetHuffmanTable.s,JpegUtils_SetHuffmanTable,0x801A9C68,0x2A +asm/non_matchings/code/jpegutils/JpegUtils_ProcessHuffmanTableImpl.s,JpegUtils_ProcessHuffmanTableImpl,0x801A9D10,0x2F +asm/non_matchings/code/jpegutils/JpegUtils_ProcessHuffmanTable.s,JpegUtils_ProcessHuffmanTable,0x801A9DCC,0x36 +asm/non_matchings/code/jpegutils/JpegUtils_SetHuffmanTableOld.s,JpegUtils_SetHuffmanTableOld,0x801A9EA4,0x2A +asm/non_matchings/code/jpegutils/JpegUtils_ProcessHuffmanTableImplOld.s,JpegUtils_ProcessHuffmanTableImplOld,0x801A9F4C,0x35 +asm/non_matchings/code/jpegdecoder/JpegDecoder_Decode.s,JpegDecoder_Decode,0x801AA020,0x8A +asm/non_matchings/code/jpegdecoder/JpegDecoder_ProcessMcu.s,JpegDecoder_ProcessMcu,0x801AA248,0x67 +asm/non_matchings/code/jpegdecoder/JpegDecoder_ParseNextSymbol.s,JpegDecoder_ParseNextSymbol,0x801AA3E4,0x4F +asm/non_matchings/code/jpegdecoder/JpegDecoder_ReadBits.s,JpegDecoder_ReadBits,0x801AA520,0x3C asm/non_matchings/code/z_game_over/GameOver_Init.s,GameOver_Init,0x801AA610,0x5 asm/non_matchings/code/z_game_over/GameOver_FadeLights.s,GameOver_FadeLights,0x801AA624,0x1A asm/non_matchings/code/z_game_over/GameOver_Update.s,GameOver_Update,0x801AA68C,0x105 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/warnings_count/.gitignore b/tools/warnings_count/.gitignore index 5606ab0ef..eaf2f58b5 100644 --- a/tools/warnings_count/.gitignore +++ b/tools/warnings_count/.gitignore @@ -2,3 +2,4 @@ warnings_setup_new.txt warnings_disasm_new.txt warnings_build_new.txt +warnings_temp.txt diff --git a/tools/warnings_count/check_new_warnings.sh b/tools/warnings_count/check_new_warnings.sh index 7a196c28b..27cda1b25 100755 --- a/tools/warnings_count/check_new_warnings.sh +++ b/tools/warnings_count/check_new_warnings.sh @@ -32,18 +32,30 @@ Check for new warnings created. Optional arguments: -h Display this message and exit. + -f Run full build process -j N use N jobs (does not support plain -j because you shouldn't use it anyway) " } jobs=1 +full= +run="make clean + make uncompressed" -while getopts "hj:" opt + + +while getopts "hfj:" opt do case $opt in h) show_help exit 0 ;; + f) full="true" + run="make distclean + make setup + make disasm + make all" + ;; j) j_option_arg="$OPTARG" if [[ ! "${j_option_arg}" =~ ^[0-9]*$ ]] then @@ -61,10 +73,7 @@ shift $(($OPTIND - 1)) # Confirm run with -j jobs echo "This will run - make distclean - make setup - make disasm - make all + $run using $jobs threads. This may take some time." read -r -p "Is this okay? [Y/n]" response response=${response,,} # tolower @@ -90,16 +99,20 @@ make_warnings () { && rm tools/warnings_count/warnings_temp.txt } +if [[ $full ]]; then + make distclean + make_warnings setup setup + make_warnings disasm disasm + make_warnings all build +else + make clean + make_warnings uncompressed build +fi -make distclean -make_warnings setup setup -make_warnings disasm disasm -make_warnings all build -echo " -$(tput ${TPUTTERM} setaf 3)(lots of make output ${TPUTTERM} here...) -$RST" -$COMPARE_WARNINGS setup -$COMPARE_WARNINGS disasm +if [[ $full ]]; then + $COMPARE_WARNINGS setup + $COMPARE_WARNINGS disasm +fi $COMPARE_WARNINGS build diff --git a/tools/warnings_count/update_current_warnings.sh b/tools/warnings_count/update_current_warnings.sh index afbc4a423..f2cff34c5 100755 --- a/tools/warnings_count/update_current_warnings.sh +++ b/tools/warnings_count/update_current_warnings.sh @@ -8,5 +8,7 @@ cd "$DIR/../.." make distclean make setup 2> tools/warnings_count/warnings_setup_current.txt +make assets 2> tools/warnings_count/warnings_assets_current.txt make disasm 2> tools/warnings_count/warnings_disasm_current.txt -make all 2> tools/warnings_count/warnings_build_current.txt +make uncompressed 2> tools/warnings_count/warnings_build_current.txt +make compressed 2> tools/warnings_count/warnings_compress_current.txt diff --git a/tools/decomp-permuter/src/net/cmd/__init__.py b/tools/warnings_count/warnings_assets_current.txt similarity index 100% rename from tools/decomp-permuter/src/net/cmd/__init__.py rename to tools/warnings_count/warnings_assets_current.txt diff --git a/tools/decomp-permuter/src/perm/__init__.py b/tools/warnings_count/warnings_compress_current.txt similarity index 100% rename from tools/decomp-permuter/src/perm/__init__.py rename to tools/warnings_count/warnings_compress_current.txt 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 77a444f20..983891676 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 @@ -206,9 +211,6 @@ D_0200B998 = 0x0200B998; D_04000320 = 0x04000320; D_040003E0 = 0x040003E0; -D_040008D0 = 0x040008D0; -D_04001D00 = 0x04001D00; -D_040021A8 = 0x040021A8; D_040032B0 = 0x040032B0; D_0400CF48 = 0x0400CF48; D_0400CF58 = 0x0400CF58; @@ -377,18 +379,9 @@ D_0400E408 = 0x0400E408; D_0400E410 = 0x0400E410; D_0400E418 = 0x0400E418; D_0400E430 = 0x0400E430; -D_0400EB7C = 0x0400EB7C; -D_0400ED80 = 0x0400ED80; -D_0400E710 = 0x0400E710; -D_04011518 = 0x04011518; -D_040117A8 = 0x040117A8; -D_040118D8 = 0x040118D8; -D_04011BD0 = 0x04011BD0; -D_040127E8 = 0x040127E8; D_04012860 = 0x04012860; D_040128BC = 0x040128BC; D_04014560 = 0x04014560; -D_04014570 = 0x04014570; D_04015DB0 = 0x04015DB0; D_04015FA0 = 0x04015FA0; D_04016360 = 0x04016360; @@ -399,16 +392,10 @@ D_0401A620 = 0x0401A620; D_0401ACF0 = 0x0401ACF0; D_0401ED00 = 0x0401ED00; D_0401F0F0 = 0x0401F0F0; -D_0401F740 = 0x0401F740; -D_0401F7C0 = 0x0401F7C0; -D_0401F8C0 = 0x0401F8C0; -D_0401FA40 = 0x0401FA40; D_04020658 = 0x04020658; D_04020BB8 = 0x04020BB8; D_04020D00 = 0x04020D00; D_040221B8 = 0x040221B8; -D_04022B28 = 0x04022B28; -D_04023100 = 0x04023100; D_04023130 = 0x04023130; D_04023210 = 0x04023210; D_04023288 = 0x04023288; @@ -431,13 +418,6 @@ D_04029CB0 = 0x04029CB0; D_04029CF0 = 0x04029CF0; D_04029D20 = 0x04029D20; D_0402AF58 = 0x0402AF58; -D_0402B494 = 0x0402B494; -D_0402C818 = 0x0402C818; -D_0402C890 = 0x0402C890; -D_0402C908 = 0x0402C908; -D_0402C980 = 0x0402C980; -D_0402C9F8 = 0x0402C9F8; -D_0402CA98 = 0x0402CA98; D_0402E510 = 0x0402E510; D_0402E65C = 0x0402E65C; D_0402F028 = 0x0402F028; @@ -449,16 +429,7 @@ D_04035710 = 0x04035710; D_040367B0 = 0x040367B0; D_040377B0 = 0x040377B0; D_04037850 = 0x04037850; -D_040378F0 = 0x040378F0; -D_04037DF0 = 0x04037DF0; -D_040382F0 = 0x040382F0; -D_040387F0 = 0x040387F0; -D_04038CF0 = 0x04038CF0; -D_040391F0 = 0x040391F0; -D_040396F0 = 0x040396F0; -D_04039BF0 = 0x04039BF0; D_0403A0F0 = 0x0403A0F0; -D_0403C190 = 0x0403C190; D_0403F230 = 0x0403F230; D_04044300 = 0x04044300; D_0404F250 = 0x0404F250; @@ -478,28 +449,15 @@ D_040549A8 = 0x040549A8; D_04054A90 = 0x04054A90; D_04054C90 = 0x04054C90; D_04054F18 = 0x04054F18; -D_04054F20 = 0x04054F20; -D_04055628 = 0x04055628; D_04058BA0 = 0x04058BA0; D_0405AAB0 = 0x0405AAB0; D_0405AED0 = 0x0405AED0; -D_0405B6F0 = 0x0405B6F0; D_0405BEF0 = 0x0405BEF0; -D_0405C6F0 = 0x0405C6F0; D_0405CEF0 = 0x0405CEF0; D_0405E6F0 = 0x0405E6F0; D_0405F6F0 = 0x0405F6F0; -D_0405F7C0 = 0x0405F7C0; D_0405FFC0 = 0x0405FFC0; -D_040607C0 = 0x040607C0; -D_04060FC0 = 0x04060FC0; D_040617C0 = 0x040617C0; -D_04061FC0 = 0x04061FC0; -D_04061FE0 = 0x04061FE0; -D_04062000 = 0x04062000; -D_04062020 = 0x04062020; -D_04062040 = 0x04062040; -D_04062060 = 0x04062060; D_040622C0 = 0x040622C0; D_0406A800 = 0x0406A800; D_0406AB30 = 0x0406AB30; @@ -511,19 +469,12 @@ D_0406F380 = 0x0406F380; D_0406F9F0 = 0x0406F9F0; D_0406FAE0 = 0x0406FAE0; D_040706E0 = 0x040706E0; -D_04071230 = 0x04071230; -D_04073F00 = 0x04073F00; -D_04074330 = 0x04074330; -D_04075400 = 0x04075400; D_04075A40 = 0x04075A40; -D_04075B30 = 0x04075B30; D_04076BC0 = 0x04076BC0; -D_04077480 = 0x04077480; D_04079B10 = 0x04079B10; D_0407AB10 = 0x0407AB10; D_0407AB58 = 0x0407AB58; D_0407AB70 = 0x0407AB70; -D_0407AE00 = 0x0407AE00; D_0407AFB0 = 0x0407AFB0; D_0407D590 = 0x0407D590; D_0407D650 = 0x0407D650; @@ -535,19 +486,16 @@ D_04081628 = 0x04081628; D_04083534 = 0x04083534; D_04085640 = 0x04085640; D_0408DBE0 = 0x0408DBE0; -D_0408DFE0 = 0x0408DFE0; -D_0408E3E0 = 0x0408E3E0; -D_0408E7E0 = 0x0408E7E0; D_0408EBE0 = 0x0408EBE0; -D_0408EFE0 = 0x0408EFE0; -D_0408F3E0 = 0x0408F3E0; -D_0408F7E0 = 0x0408F7E0; D_04091BE0 = 0x04091BE0; D_04091CE0 = 0x04091CE0; +D_04091DE0 = 0x04091DE0; +D_04091FE0 = 0x04091FE0; +D_040921E0 = 0x040921E0; +D_040923E0 = 0x040923E0; // segment 0x05 -D_05000C40 = 0x05000C40; D_05001D20 = 0x05001D20; D_05002FA0 = 0x05002FA0; D_050061E8 = 0x050061E8; @@ -555,25 +503,16 @@ D_05006420 = 0x05006420; D_050066B0 = 0x050066B0; D_05006760 = 0x05006760; D_05007498 = 0x05007498; -D_05007890 = 0x05007890; D_050078A0 = 0x050078A0; D_05007938 = 0x05007938; -D_05007980 = 0x05007980; -D_05007E00 = 0x05007E00; -D_05008018 = 0x05008018; D_050085F0 = 0x050085F0; D_050089D0 = 0x050089D0; -D_05017EA0 = 0x05017EA0; -D_05018090 = 0x05018090; D_050182A8 = 0x050182A8; D_0501B370 = 0x0501B370; -D_0501B508 = 0x0501B508; D_0501BEE0 = 0x0501BEE0; D_0501BFB8 = 0x0501BFB8; D_0501C058 = 0x0501C058; D_0501C118 = 0x0501C118; -D_0501D980 = 0x0501D980; -D_050219E0 = 0x050219E0; D_05021EF0 = 0x05021EF0; D_05023008 = 0x05023008; D_0502324C = 0x0502324C; @@ -583,8 +522,6 @@ D_0502324C = 0x0502324C; // code D_06001254 = 0x06001254; -D_06001290 = 0x06001290; -D_06001470 = 0x06001470; D_06001C60 = 0x06001C60; D_06007390 = 0x06007390; D_06008AA0 = 0x06008AA0; @@ -603,10 +540,6 @@ D_06011AB8 = 0x06011AB8; D_06012A80 = 0x06012A80; D_06013138 = 0x06013138; -// ovl_Arms_Hook - -D_0601D960 = 0x0601D960; - // ovl_Bg_Astr_Bombwall D_06002178 = 0x06002178; @@ -619,65 +552,16 @@ D_06002498 = 0x06002498; D_06000638 = 0x06000638; D_06001BD8 = 0x06001BD8; -// ovl_Bg_Breakwall - -D_06000A50 = 0x06000A50; -D_06000C98 = 0x06000C98; - // ovl_Bg_Crace_Movebg D_060003A0 = 0x060003A0; D_06000E00 = 0x06000E00; -// ovl_Bg_Ctower_Gear - -D_06010828 = 0x06010828; -D_06015F30 = 0x06015F30; -D_060160A0 = 0x060160A0; -D_06016E70 = 0x06016E70; -D_06017018 = 0x06017018; -D_06018118 = 0x06018118; -D_06018588 = 0x06018588; - -// ovl_Bg_Ctower_Rot - -D_060129D0 = 0x060129D0; -D_06012DA0 = 0x06012DA0; -D_060142E8 = 0x060142E8; -D_06017220 = 0x06017220; -D_06017410 = 0x06017410; -D_060174E0 = 0x060174E0; -D_06017650 = 0x06017650; - -// ovl_Bg_Dblue_Balance - -D_0600CD10 = 0x0600CD10; -D_0600CE00 = 0x0600CE00; -D_0600D110 = 0x0600D110; -D_0600D250 = 0x0600D250; - // ovl_Bg_Dblue_Elevator D_060002C8 = 0x060002C8; D_060005C4 = 0x060005C4; -// ovl_Bg_Dblue_Movebg - -D_06004848 = 0x06004848; -D_060052B8 = 0x060052B8; -D_06008778 = 0x06008778; -D_0600A528 = 0x0600A528; -D_0600CD10 = 0x0600CD10; -D_0600CE00 = 0x0600CE00; - -// ovl_Bg_Dblue_Waterfall - -D_06003250 = 0x06003250; -D_06003358 = 0x06003358; -D_06003770 = 0x06003770; -D_0600B280 = 0x0600B280; -D_0600B448 = 0x0600B448; - // ovl_Bg_Dkjail_Ivy D_06000080 = 0x06000080; @@ -691,22 +575,11 @@ D_0600D228 = 0x0600D228; D_0601C6F4 = 0x0601C6F4; D_0601C8B4 = 0x0601C8B4; -// ovl_Bg_F40_Block - -D_060043D0 = 0x060043D0; -D_06004640 = 0x06004640; - // ovl_Bg_F40_Flift D_06004038 = 0x06004038; D_06004240 = 0x06004240; -// ovl_Bg_F40_Switch - -D_06000118 = 0x06000118; -D_06000390 = 0x06000390; -D_06000438 = 0x06000438; - // ovl_Bg_F40_Swlift D_06003B08 = 0x06003B08; @@ -716,40 +589,18 @@ D_06003E80 = 0x06003E80; D_06000040 = 0x06000040; -// ovl_Bg_Fu_Kaiten - -D_060005D0 = 0x060005D0; -D_06002D30 = 0x06002D30; - // ovl_Bg_Fu_Mizu D_06002FC0 = 0x06002FC0; D_060037D8 = 0x060037D8; D_060037F8 = 0x060037F8; -// ovl_Bg_Goron_Oyu - -D_06000080 = 0x06000080; -D_06000158 = 0x06000158; -D_06000968 = 0x06000968; -D_06000988 = 0x06000988; - // ovl_Bg_Haka_Bombwall D_06000040 = 0x06000040; D_06000148 = 0x06000148; D_06001680 = 0x06001680; -// ovl_Bg_Haka_Curtain - -D_06001410 = 0x06001410; -D_06001588 = 0x06001588; - -// ovl_Bg_Haka_Tomb - -D_060007B0 = 0x060007B0; -D_06000EE8 = 0x06000EE8; - // ovl_Bg_Hakugin_Bombwall D_06009830 = 0x06009830; @@ -759,35 +610,14 @@ D_06009830 = 0x06009830; D_0600ACB8 = 0x0600ACB8; D_0600BF40 = 0x0600BF40; -// ovl_Bg_Hakugin_Post - -D_0600D3B0 = 0x0600D3B0; -D_0600C1A8 = 0x0600C1A8; -D_0600C568 = 0x0600C568; -D_0600CA38 = 0x0600CA38; -D_0600CEC8 = 0x0600CEC8; -D_0600D098 = 0x0600D098; - -// ovl_Bg_Hakugin_Switch - -D_06000268 = 0x06000268; -D_060005C8 = 0x060005C8; - // ovl_Bg_Icefloe D_060001E0 = 0x060001E0; D_06000C90 = 0x06000C90; -// ovl_Bg_Icicle - -D_060000D0 = 0x060000D0; -D_06000294 = 0x06000294; - // ovl_Bg_Ikana_Bombwall -D_06000128 = 0x06000128; D_06000288 = 0x06000288; -D_06000488 = 0x06000488; // ovl_Bg_Ikana_Dharma @@ -803,35 +633,11 @@ D_06001AD8 = 0x06001AD8; D_06001E18 = 0x06001E18; D_06002358 = 0x06002358; -// ovl_Bg_Ikana_Ray - -D_06001100 = 0x06001100; -D_06001228 = 0x06001228; - -// ovl_Bg_Ikana_Rotaryroom - -D_06004710 = 0x06004710; -D_060048A0 = 0x060048A0; -D_06007360 = 0x06007360; -D_06007448 = 0x06007448; -D_06007B68 = 0x06007B68; - -// ovl_Bg_Ikana_Shutter - -D_06000CE8 = 0x06000CE8; -D_06000F28 = 0x06000F28; - // ovl_Bg_Ikninside D_0600CC78 = 0x0600CC78; D_0600DE48 = 0x0600DE48; -// ovl_Bg_Iknin_Susceil - -D_0600C308 = 0x0600C308; -D_0600C670 = 0x0600C670; -D_0600CBAC = 0x0600CBAC; - // ovl_Bg_Iknv_Doukutu D_0600DB60 = 0x0600DB60; @@ -845,33 +651,11 @@ D_06012700 = 0x06012700; D_06012728 = 0x06012728; D_06012788 = 0x06012788; -// ovl_Bg_Iknv_Obj - -D_06011880 = 0x06011880; -D_060119D4 = 0x060119D4; -D_060129C8 = 0x060129C8; -D_06012CA4 = 0x06012CA4; -D_06013058 = 0x06013058; - -// ovl_Bg_Ingate - -D_060006B0 = 0x060006B0; -D_060016DC = 0x060016DC; - // ovl_Bg_Keikoku_Saku D_06001640 = 0x06001640; D_06002300 = 0x06002300; -// ovl_Bg_Keikoku_Spr - -D_06000100 = 0x06000100; -D_060001F8 = 0x060001F8; -D_06000300 = 0x06000300; -D_060003F8 = 0x060003F8; -D_06000500 = 0x06000500; -D_060005F8 = 0x060005F8; - // ovl_Bg_Kin2_Bombwall D_06000128 = 0x06000128; @@ -879,93 +663,29 @@ D_060002C0 = 0x060002C0; D_06000360 = 0x06000360; D_06000490 = 0x06000490; -// ovl_Bg_Kin2_Fence - -D_06000828 = 0x06000828; -D_06000908 = 0x06000908; - // ovl_Bg_Kin2_Picture D_06000658 = 0x06000658; D_06000798 = 0x06000798; -// ovl_Bg_Ladder - -D_060000A0 = 0x060000A0; -D_060001D8 = 0x060001D8; -D_060002D0 = 0x060002D0; -D_06000408 = 0x06000408; -D_06000500 = 0x06000500; -D_06000638 = 0x06000638; -D_06000730 = 0x06000730; -D_06000868 = 0x06000868; - // ovl_Bg_Last_Bwall D_06000098 = 0x06000098; -// ovl_Bg_Lbfshot - -D_06000228 = 0x06000228; -D_060014D8 = 0x060014D8; - -// ovl_Bg_Lotus - -D_06000040 = 0x06000040; -D_06000A20 = 0x06000A20; - -// ovl_Bg_Market_Step - -D_0601F050 = 0x0601F050; -D_06018DA0 = 0x06018DA0; -D_0601EF10 = 0x0601EF10; -D_06018C60 = 0x06018C60; - -// ovl_Bg_Mbar_Chair - -D_06000288 = 0x06000288; -D_060019B4 = 0x060019B4; - -// ovl_Bg_Numa_Hana - -D_06000870 = 0x06000870; -D_06009FE0 = 0x06009FE0; -D_0600A740 = 0x0600A740; -D_0600AB88 = 0x0600AB88; -D_0600B928 = 0x0600B928; -D_0600BE58 = 0x0600BE58; - // ovl_Bg_Open_Shutter D_060003E8 = 0x060003E8; D_06001640 = 0x06001640; -// ovl_Bg_Open_Spot - -D_06001A60 = 0x06001A60; -D_06001B40 = 0x06001B40; -D_06002CE0 = 0x06002CE0; // ovl_Bg_Sinkai_Kabe D_06000048 = 0x06000048; -// ovl_Bg_Spdweb - -D_06000060 = 0x06000060; -D_060011C0 = 0x060011C0; -D_060012F0 = 0x060012F0; -D_06002678 = 0x06002678; - // ovl_Bg_Spout_Fire D_06000040 = 0x06000040; -// ovl_Bg_Tobira01 - -D_06000088 = 0x06000088; -D_060011C0 = 0x060011C0; - // ovl_Bg_Umajump D_06001220 = 0x06001220; @@ -1008,38 +728,6 @@ D_06022118 = 0x06022118; D_060222D0 = 0x060222D0; D_06022550 = 0x06022550; -// ovl_Boss_02 - -D_06000230 = 0x06000230; -D_060002E0 = 0x060002E0; -D_060003A0 = 0x060003A0; -D_060041A0 = 0x060041A0; -D_06008650 = 0x06008650; -D_06009B10 = 0x06009B10; -D_06009C78 = 0x06009C78; - -// ovl_Boss_03 - -D_06004260 = 0x06004260; -D_060042B0 = 0x060042B0; -D_060042F8 = 0x060042F8; -D_06007E50 = 0x06007E50; -D_06007EB0 = 0x06007EB0; -D_06007EC8 = 0x06007EC8; -D_060093A8 = 0x060093A8; -D_06009554 = 0x06009554; -D_060099D0 = 0x060099D0; -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; @@ -1062,7 +750,6 @@ D_06018CF0 = 0x06018CF0; D_06018DE0 = 0x06018DE0; D_06019360 = 0x06019360; D_060193B0 = 0x060193B0; -D_06019490 = 0x06019490; // ovl_Boss_07 @@ -1153,16 +840,6 @@ D_060134D0 = 0x060134D0; D_06013828 = 0x06013828; D_06014040 = 0x06014040; -// ovl_Demo_Effect - -D_06000050 = 0x06000050; -D_06000060 = 0x06000060; -D_060012E8 = 0x060012E8; - -// ovl_Demo_Kankyo - -D_06001000 = 0x06001000; - // ovl_Demo_Moonend D_06001214 = 0x06001214; @@ -1171,22 +848,6 @@ D_0600B5A0 = 0x0600B5A0; D_06010C40 = 0x06010C40; D_060129F0 = 0x060129F0; -// ovl_Demo_Syoten - -D_0600023C = 0x0600023C; -D_06001298 = 0x06001298; -D_06001328 = 0x06001328; -D_06001370 = 0x06001370; -D_06001448 = 0x06001448; -D_06001730 = 0x06001730; -D_060018B8 = 0x060018B8; -D_060018C0 = 0x060018C0; -D_06001DD0 = 0x06001DD0; -D_06002880 = 0x06002880; -D_06002A20 = 0x06002A20; -D_06002B88 = 0x06002B88; -D_06002B98 = 0x06002B98; - // ovl_Demo_Tre_Lgt D_06007D78 = 0x06007D78; @@ -1199,40 +860,12 @@ D_06009E70 = 0x06009E70; D_0600A0D8 = 0x0600A0D8; -// ovl_Dm_An - -D_06000E70 = 0x06000E70; -D_06012618 = 0x06012618; - // ovl_Dm_Bal D_060005FC = 0x060005FC; D_06001804 = 0x06001804; D_0600A6D0 = 0x0600A6D0; -// ovl_Dm_Char01 - -D_06009928 = 0x06009928; -D_06009D70 = 0x06009D70; -D_06009E4C = 0x06009E4C; -D_0600A398 = 0x0600A398; -D_0600A5C0 = 0x0600A5C0; -D_0600A8F8 = 0x0600A8F8; -D_0600AA50 = 0x0600AA50; -D_0600AF98 = 0x0600AF98; -D_0600B1A0 = 0x0600B1A0; -D_0600DE50 = 0x0600DE50; -D_0600DF18 = 0x0600DF18; -D_0600F3C0 = 0x0600F3C0; -D_0600F768 = 0x0600F768; -D_0600FAE8 = 0x0600FAE8; -D_0600FE5C = 0x0600FE5C; -D_0600FE90 = 0x0600FE90; -D_06010C3C = 0x06010C3C; -D_06010EF0 = 0x06010EF0; -D_06010FD8 = 0x06010FD8; -D_060110B8 = 0x060110B8; - // ovl_Dm_Char02 D_0600AD68 = 0x0600AD68; @@ -1241,39 +874,11 @@ D_0600AD68 = 0x0600AD68; D_06020550 = 0x06020550; -// ovl_Dm_Char05 - -D_060001D0 = 0x060001D0; -D_060010B0 = 0x060010B0; -D_060013D0 = 0x060013D0; -D_06001E70 = 0x06001E70; -D_060042B0 = 0x060042B0; - // ovl_Dm_Char06 D_060013A8 = 0x060013A8; D_06006868 = 0x06006868; -// ovl_Dm_Char07 - -D_06000100 = 0x06000100; -D_06000240 = 0x06000240; -D_06000650 = 0x06000650; -D_06000790 = 0x06000790; -D_06000B80 = 0x06000B80; -D_06000CC0 = 0x06000CC0; -D_060010D0 = 0x060010D0; -D_06001210 = 0x06001210; -D_060015E0 = 0x060015E0; -D_060016B8 = 0x060016B8; -D_06002BA0 = 0x06002BA0; -D_06002CD0 = 0x06002CD0; -D_06006688 = 0x06006688; -D_060076A0 = 0x060076A0; -D_06007918 = 0x06007918; -D_060105F8 = 0x060105F8; -D_06010D68 = 0x06010D68; - // ovl_Dm_Char08 D_06002328 = 0x06002328; @@ -1286,16 +891,6 @@ D_0600E748 = 0x0600E748; D_0600005C = 0x0600005C; D_06001398 = 0x06001398; -// ovl_Dm_Gm - -D_06000E70 = 0x06000E70; -D_06012618 = 0x06012618; - -// ovl_Dm_Nb - -D_06000990 = 0x06000990; -D_06008C40 = 0x06008C40; - // ovl_Dm_Opstage D_06000970 = 0x06000970; @@ -1308,40 +903,6 @@ D_06003068 = 0x06003068; D_06003720 = 0x06003720; D_06003728 = 0x06003728; -// ovl_Dm_Sa - -D_0600CC94 = 0x0600CC94; -D_06013328 = 0x06013328; - -// ovl_Dm_Statue - -D_06000520 = 0x06000520; -D_06001788 = 0x06001788; - -// ovl_Dm_Stk - -D_060046B0 = 0x060046B0; -D_060053C0 = 0x060053C0; -D_06005870 = 0x06005870; -D_06006BB0 = 0x06006BB0; -D_06007840 = 0x06007840; -D_060079F0 = 0x060079F0; -D_060084C0 = 0x060084C0; -D_06008658 = 0x06008658; -D_060087B0 = 0x060087B0; -D_06008A80 = 0x06008A80; -D_060090C0 = 0x060090C0; -D_06009710 = 0x06009710; -D_06009AC0 = 0x06009AC0; -D_06009DA0 = 0x06009DA0; -D_0600A530 = 0x0600A530; -D_0600A5C0 = 0x0600A5C0; -D_0600AE30 = 0x0600AE30; -D_0600AEC0 = 0x0600AEC0; -D_0600CAD0 = 0x0600CAD0; -D_06013328 = 0x06013328; -D_06016620 = 0x06016620; - // ovl_Dm_Tsg D_06002D30 = 0x06002D30; @@ -1352,38 +913,14 @@ D_06011458 = 0x06011458; D_0600DE08 = 0x0600DE08; D_0600E038 = 0x0600E038; -// ovl_Door_Spiral - -D_06000590 = 0x06000590; -D_060007A8 = 0x060007A8; -D_06000EA0 = 0x06000EA0; -D_060012C0 = 0x060012C0; -D_060014C8 = 0x060014C8; -D_06002110 = 0x06002110; -D_06004448 = 0x06004448; -D_060051B8 = 0x060051B8; -D_06006128 = 0x06006128; -D_06009278 = 0x06009278; -D_06012B70 = 0x06012B70; -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 - -D_06000A38 = 0x06000A38; // ovl_Effect_Ss_D_Fire @@ -1423,28 +960,6 @@ D_06000180 = 0x06000180; D_060002A8 = 0x060002A8; D_06000F38 = 0x06000F38; -// ovl_En_Ah - -D_06009E70 = 0x06009E70; - -// ovl_En_Akindonuts - -D_06001350 = 0x06001350; -D_06005488 = 0x06005488; -D_06008290 = 0x06008290; -D_0600AC70 = 0x0600AC70; - -// ovl_En_Al - -D_0600A0D8 = 0x0600A0D8; - -// ovl_En_Am - -D_06000238 = 0x06000238; -D_0600033C = 0x0600033C; -D_06005948 = 0x06005948; -D_06005B3C = 0x06005B3C; - // ovl_En_An D_06000308 = 0x06000308; @@ -1469,16 +984,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; -D_06002530 = 0x06002530; - // ovl_En_Az D_06007438 = 0x06007438; @@ -1487,23 +992,6 @@ D_06017990 = 0x06017990; D_0601ABF0 = 0x0601ABF0; D_0601AD00 = 0x0601AD00; -// ovl_En_Baba - -D_06005EF0 = 0x06005EF0; -D_06006B10 = 0x06006B10; -D_060092A0 = 0x060092A0; - -// ovl_En_Baguo - -D_060020E8 = 0x060020E8; - -// ovl_En_Baisen - -D_060008B4 = 0x060008B4; -D_06008198 = 0x06008198; -D_060011C0 = 0x060011C0; -D_06007908 = 0x06007908; - // ovl_En_Bal D_060005FC = 0x060005FC; @@ -1518,22 +1006,6 @@ D_0600D530 = 0x0600D530; D_060000A0 = 0x060000A0; D_060000C8 = 0x060000C8; -// ovl_En_Bb - -D_06000184 = 0x06000184; -D_06000444 = 0x06000444; -D_06001A30 = 0x06001A30; - -// ovl_En_Bba_01 - -D_06005EF0 = 0x06005EF0; - -// ovl_En_Bbfall - -D_06000184 = 0x06000184; -D_06000444 = 0x06000444; -D_06001A30 = 0x06001A30; - // ovl_En_Bee D_0600005C = 0x0600005C; @@ -1544,13 +1016,6 @@ D_06001398 = 0x06001398; D_06000074 = 0x06000074; D_06001E60 = 0x06001E60; -// ovl_En_Bigokuta - -D_06000444 = 0x06000444; -D_06000A74 = 0x06000A74; -D_060014B8 = 0x060014B8; -D_06006BC0 = 0x06006BC0; - // ovl_En_Bigpamet D_06000440 = 0x06000440; @@ -1563,60 +1028,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; -D_06000AB0 = 0x06000AB0; -D_06000FDC = 0x06000FDC; -D_060049F0 = 0x060049F0; -D_06004E70 = 0x06004E70; -D_06005270 = 0x06005270; -D_0600578C = 0x0600578C; -D_06005B58 = 0x06005B58; - // ovl_En_Bjt D_06002390 = 0x06002390; @@ -1626,37 +1037,16 @@ D_06002390 = 0x06002390; D_06000A00 = 0x06000A00; D_06000D78 = 0x06000D78; -// ovl_En_Bombers - -D_060064B8 = 0x060064B8; -D_0600F82C = 0x0600F82C; - // ovl_En_Bombers2 D_060064B8 = 0x060064B8; D_0600F82C = 0x0600F82C; -// ovl_En_Bombf - -D_06000340 = 0x06000340; -D_06000408 = 0x06000408; -D_06000530 = 0x06000530; - -// ovl_En_Bomjima - -D_060064B8 = 0x060064B8; -D_0600F82C = 0x0600F82C; - // ovl_En_Bomjimb D_060064B8 = 0x060064B8; D_0600F82C = 0x0600F82C; -// ovl_En_Bom_Bowl_Man - -D_060064B8 = 0x060064B8; -D_0600F82C = 0x0600F82C; - // ovl_En_Box D_0600043C = 0x0600043C; @@ -1680,86 +1070,11 @@ D_0600C3E0 = 0x0600C3E0; D_06001000 = 0x06001000; -// ovl_En_Cha - -D_06000710 = 0x06000710; -D_06000958 = 0x06000958; - -// ovl_En_Cne_01 - -D_060000F0 = 0x060000F0; -D_06001300 = 0x06001300; - -// ovl_En_Cow - -D_060001CC = 0x060001CC; -D_06004010 = 0x06004010; -D_06004264 = 0x06004264; -D_06004348 = 0x06004348; -D_06004C30 = 0x06004C30; -D_06004E98 = 0x06004E98; - // ovl_En_Crow D_060000F0 = 0x060000F0; D_060010C0 = 0x060010C0; -// ovl_En_Dai - -D_06000230 = 0x06000230; -D_060002E8 = 0x060002E8; -D_0600C538 = 0x0600C538; -D_060130D0 = 0x060130D0; -D_060107B0 = 0x060107B0; -D_06010FB0 = 0x06010FB0; -D_060117B0 = 0x060117B0; -D_06010FB0 = 0x06010FB0; -D_06011FB0 = 0x06011FB0; -D_060127B0 = 0x060127B0; -D_060079E4 = 0x060079E4; -D_06007354 = 0x06007354; -D_06000CEC = 0x06000CEC; -D_060069DC = 0x060069DC; -D_0600563C = 0x0600563C; -D_06002E58 = 0x06002E58; -D_06006590 = 0x06006590; - -// ovl_En_Daiku - -D_06001114 = 0x06001114; -D_06002FA0 = 0x06002FA0; -D_06008EC8 = 0x06008EC8; -D_0600A850 = 0x0600A850; -D_0600B690 = 0x0600B690; -D_0600ACD0 = 0x0600ACD0; -D_0600C92C = 0x0600C92C; -D_06000C44 = 0x06000C44; -D_0600C234 = 0x0600C234; -D_06000600 = 0x06000600; -D_0600BEAC = 0x0600BEAC; -D_060070C0 = 0x060070C0; -D_06006FB0 = 0x06006FB0; -D_06006E80 = 0x06006E80; -D_06006D70 = 0x06006D70; - -// ovl_En_Daiku2 - -D_0600ACD0 = 0x0600ACD0; -D_0600C92C = 0x0600C92C; -D_06000C44 = 0x06000C44; -D_0600C234 = 0x0600C234; -D_06000600 = 0x06000600; -D_06001114 = 0x06001114; -D_0600B690 = 0x0600B690; -D_06001A24 = 0x06001A24; -D_0600D328 = 0x0600D328; -D_060009E0 = 0x060009E0; -D_06002134 = 0x06002134; -D_06002FA0 = 0x06002FA0; -D_06009638 = 0x06009638; -D_0600A390 = 0x0600A390; -D_0600A850 = 0x0600A850; - // ovl_En_Death D_06000E64 = 0x06000E64; @@ -1791,222 +1106,15 @@ D_06001828 = 0x06001828; D_06002A40 = 0x06002A40; D_06003070 = 0x06003070; -// ovl_En_Dekunuts - -D_06000168 = 0x06000168; -D_06001E50 = 0x06001E50; -D_06001F50 = 0x06001F50; -D_06002468 = 0x06002468; -D_0600259C = 0x0600259C; -D_06002A5C = 0x06002A5C; -D_06002BD4 = 0x06002BD4; -D_06002DD4 = 0x06002DD4; -D_06002FA4 = 0x06002FA4; -D_06003180 = 0x06003180; -D_0600326C = 0x0600326C; -D_060033E4 = 0x060033E4; -D_06003780 = 0x06003780; - // ovl_En_Demo_heishi D_06003BFC = 0x06003BFC; D_0600D640 = 0x0600D640; -// ovl_En_Dg - -D_060080F0 = 0x060080F0; -D_060021C8 = 0x060021C8; -D_06001BD8 = 0x06001BD8; -D_06000998 = 0x06000998; -D_06001FB0 = 0x06001FB0; -D_06001048 = 0x06001048; -D_06001348 = 0x06001348; -D_06001560 = 0x06001560; -D_06001A84 = 0x06001A84; -D_060017C0 = 0x060017C0; - -// ovl_En_Dinofos - -D_06000580 = 0x06000580; -D_06000AF0 = 0x06000AF0; -D_06001040 = 0x06001040; -D_060013C0 = 0x060013C0; -D_060017B8 = 0x060017B8; -D_06001CCC = 0x06001CCC; -D_060025B4 = 0x060025B4; -D_06002E40 = 0x06002E40; -D_06009570 = 0x06009570; -D_06009B70 = 0x06009B70; -D_0600ABD0 = 0x0600ABD0; -D_0600C974 = 0x0600C974; -D_0600D21C = 0x0600D21C; -D_0600D62C = 0x0600D62C; -D_06008E30 = 0x06008E30; -D_06009030 = 0x06009030; -D_06009230 = 0x06009230; - -// ovl_En_Dnb - -D_06000000 = 0x06000000; -D_06000020 = 0x06000020; -D_06004638 = 0x06004638; -D_06004710 = 0x06004710; -D_06004D8C = 0x06004D8C; - // ovl_En_Dnh D_06002950 = 0x06002950; -// ovl_En_Dnk - -D_060023B8 = 0x060023B8; -D_06002468 = 0x06002468; -D_06002848 = 0x06002848; -D_06000B70 = 0x06000B70; -D_06002A08 = 0x06002A08; -D_0600031C = 0x0600031C; -D_06000430 = 0x06000430; -D_06000894 = 0x06000894; -D_06002B6C = 0x06002B6C; -D_060006CC = 0x060006CC; -D_060024CC = 0x060024CC; -D_060026C4 = 0x060026C4; -D_06002894 = 0x06002894; -D_06002B90 = 0x06002B90; -D_06002F7C = 0x06002F7C; -D_06003128 = 0x06003128; -D_060029BC = 0x060029BC; -D_06002E84 = 0x06002E84; -D_06000168 = 0x06000168; -D_0600259C = 0x0600259C; -D_06002A5C = 0x06002A5C; -D_06002BD4 = 0x06002BD4; -D_06002DD4 = 0x06002DD4; -D_06002FA4 = 0x06002FA4; -D_06003180 = 0x06003180; -D_0600326C = 0x0600326C; -D_060033E4 = 0x060033E4; -D_06003780 = 0x06003780; -D_06002950 = 0x06002950; -D_06001680 = 0x06001680; -D_06001700 = 0x06001700; -D_06001780 = 0x06001780; - -// ovl_En_Dno - -D_06007CA4 = 0x06007CA4; -D_0600E1F8 = 0x0600E1F8; -D_801C20C0 = 0x801C20C0; -D_06000470 = 0x06000470; -D_060008F0 = 0x060008F0; -D_06000F6C = 0x06000F6C; -D_06001A50 = 0x06001A50; -D_06002530 = 0x06002530; -D_06003320 = 0x06003320; -D_060036D0 = 0x060036D0; -D_060041CC = 0x060041CC; -D_06004DD8 = 0x06004DD8; -D_06005F98 = 0x06005F98; -D_06006488 = 0x06006488; -D_060073E4 = 0x060073E4; -D_060077A8 = 0x060077A8; -D_06008324 = 0x06008324; -D_06008AE4 = 0x06008AE4; -D_06009100 = 0x06009100; -D_060051E4 = 0x060051E4; -D_06005E20 = 0x06005E20; -D_06006F84 = 0x06006F84; - -// ovl_En_Dnp - -D_06010D60 = 0x06010D60; -D_060007D8 = 0x060007D8; -D_060021DC = 0x060021DC; -D_060026B8 = 0x060026B8; -D_06004D08 = 0x06004D08; -D_060071F4 = 0x060071F4; -D_06007960 = 0x06007960; -D_06008588 = 0x06008588; -D_0600A900 = 0x0600A900; -D_0600AEB8 = 0x0600AEB8; -D_0600B754 = 0x0600B754; -D_0600674C = 0x0600674C; -D_0600BAD8 = 0x0600BAD8; -D_06006B74 = 0x06006B74; -D_06012428 = 0x06012428; -D_0600B324 = 0x0600B324; -D_060115B8 = 0x060115B8; -D_0600923C = 0x0600923C; -D_06009AA0 = 0x06009AA0; -D_0600125C = 0x0600125C; -D_060017F8 = 0x060017F8; -D_06001C1C = 0x06001C1C; -D_060057AC = 0x060057AC; -D_0600625C = 0x0600625C; -D_060103D0 = 0x060103D0; -D_060105D0 = 0x060105D0; -D_060107D0 = 0x060107D0; -D_060109D0 = 0x060109D0; - -// ovl_En_Dnq - -D_0600EB48 = 0x0600EB48; -D_06008328 = 0x06008328; -D_06007528 = 0x06007528; -D_060006F0 = 0x060006F0; -D_06000BF8 = 0x06000BF8; -D_06002690 = 0x06002690; -D_06003408 = 0x06003408; -D_06006984 = 0x06006984; -D_06005E18 = 0x06005E18; -D_06005284 = 0x06005284; -D_06001AEC = 0x06001AEC; -D_06001100 = 0x06001100; -D_06004EA0 = 0x06004EA0; -D_0600F504 = 0x0600F504; -D_060047B8 = 0x060047B8; -D_06005A14 = 0x06005A14; -D_06003DBC = 0x06003DBC; - -// ovl_En_Dns - -D_06002C48 = 0x06002C48; -D_06002DD8 = 0x06002DD8; -D_06003310 = 0x06003310; -D_060034EC = 0x060034EC; -D_060008F4 = 0x060008F4; -D_06000BD8 = 0x06000BD8; -D_06000D58 = 0x06000D58; -D_06000FEC = 0x06000FEC; -D_060002A8 = 0x060002A8; -D_06000734 = 0x06000734; -D_060028E8 = 0x060028E8; -D_06002968 = 0x06002968; -D_060029E8 = 0x060029E8; -D_06002968 = 0x06002968; - -// ovl_En_Dodongo - -D_060013C4 = 0x060013C4; -D_06001A44 = 0x06001A44; -D_060028F0 = 0x060028F0; -D_06003088 = 0x06003088; -D_06003B14 = 0x06003B14; -D_060042C4 = 0x060042C4; -D_06004C20 = 0x06004C20; -D_06008318 = 0x06008318; -D_06008B1C = 0x06008B1C; - -// ovl_En_Dragon - -D_06004398 = 0x06004398; -D_060048B8 = 0x060048B8; - -// ovl_En_Drs - -D_06000E70 = 0x06000E70; -D_06005A78 = 0x06005A78; - // ovl_En_Ds2n D_06008038 = 0x06008038; @@ -2017,11 +1125,6 @@ D_06008170 = 0x06008170; D_0600112C = 0x0600112C; D_0600B0CC = 0x0600B0CC; -// ovl_En_Dy_Extra - -D_0600DD40 = 0x0600DD40; -D_0600DEF0 = 0x0600DEF0; - // ovl_En_Egblock D_06001698 = 0x06001698; @@ -2040,103 +1143,14 @@ D_060094E4 = 0x060094E4; D_06009664 = 0x06009664; D_0600EE4C = 0x0600EE4C; -// ovl_En_Elfbub - -D_06001000 = 0x06001000; - -// ovl_En_Encount2 - -D_06000A00 = 0x06000A00; -D_06000D78 = 0x06000D78; -D_06002420 = 0x06002420; - // ovl_En_Encount3 D_060009A0 = 0x060009A0; -// ovl_En_Ending_Hero - -D_06000BE0 = 0x06000BE0; -D_0600B0CC = 0x0600B0CC; -D_06007350 = 0x06007350; -D_06007750 = 0x06007750; -D_06009590 = 0x06009590; -D_06009F90 = 0x06009F90; -D_0600A390 = 0x0600A390; -D_0600A490 = 0x0600A490; -D_0600A790 = 0x0600A790; -D_0600AB90 = 0x0600AB90; - -// ovl_En_Ending_Hero2 - -D_060011C0 = 0x060011C0; -D_06007908 = 0x06007908; - -// ovl_En_Ending_Hero3 - -D_06000E50 = 0x06000E50; -D_06007150 = 0x06007150; - -// ovl_En_Ending_Hero4 - -D_06002A84 = 0x06002A84; -D_0600D640 = 0x0600D640; - -// ovl_En_Ending_Hero5 - -D_06002FA0 = 0x06002FA0; -D_06006D70 = 0x06006D70; -D_06006E80 = 0x06006E80; -D_06006FB0 = 0x06006FB0; -D_060070C0 = 0x060070C0; -D_0600A390 = 0x0600A390; -D_0600A850 = 0x0600A850; - -// ovl_En_Ending_Hero6 - -D_0600B0CC = 0x0600B0CC; -D_06007908 = 0x06007908; -D_06007150 = 0x06007150; -D_0600D640 = 0x0600D640; -D_0600A850 = 0x0600A850; -D_06000BE0 = 0x06000BE0; -D_060011C0 = 0x060011C0; -D_06000E50 = 0x06000E50; -D_06002A84 = 0x06002A84; -D_06002FA0 = 0x06002FA0; -D_060070C0 = 0x060070C0; -D_06006FB0 = 0x06006FB0; -D_06006E80 = 0x06006E80; -D_06006D70 = 0x06006D70; -D_0600A390_dl = 0x0600A390; -D_06007350 = 0x06007350; -D_06009590 = 0x06009590; -D_06009F90 = 0x06009F90; -D_0600A790 = 0x0600A790; -D_0600AB90 = 0x0600AB90; -D_06007750 = 0x06007750; -D_0600A390_tex = 0x0600A390; -D_0600A490 = 0x0600A490; - // ovl_En_Estone 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; @@ -2150,139 +1164,12 @@ D_060000F8 = 0x060000F8; D_06003D38 = 0x06003D38; D_06003DC8 = 0x06003DC8; -// ovl_En_Fg - -D_060007BC = 0x060007BC; -D_060011C0 = 0x060011C0; -D_06001534 = 0x06001534; -D_060059A0 = 0x060059A0; -D_0600B328 = 0x0600B328; -D_0600B338 = 0x0600B338; -D_0600B538 = 0x0600B538; - -// ovl_En_Firefly - -D_0600017C = 0x0600017C; -D_06001678 = 0x06001678; -D_060018B8 = 0x060018B8; - -// ovl_En_Fish2 - -D_060013AC = 0x060013AC; -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_0600007C = 0x0600007C; 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 - -D_06000590 = 0x06000590; -D_06000EA4 = 0x06000EA4; -D_060019CC = 0x060019CC; -D_06002158 = 0x06002158; -D_060039B0 = 0x060039B0; -D_060041F4 = 0x060041F4; -D_06008688 = 0x06008688; -D_06008FB0 = 0x06008FB0; -D_06009244 = 0x06009244; -D_06009520 = 0x06009520; -D_06009DB0 = 0x06009DB0; -D_0600A054 = 0x0600A054; - -// ovl_En_Fsn - -D_06005BC0 = 0x06005BC0; -D_06006D40 = 0x06006D40; -D_06007140 = 0x06007140; -D_0600B9D8 = 0x0600B9D8; -D_0600C26C = 0x0600C26C; -D_0600C58C = 0x0600C58C; -D_0600CB3C = 0x0600CB3C; -D_0600D354 = 0x0600D354; -D_0600DE34 = 0x0600DE34; -D_0600E3EC = 0x0600E3EC; -D_0600F00C = 0x0600F00C; -D_0600F180 = 0x0600F180; -D_0600F218 = 0x0600F218; -D_06012C34 = 0x06012C34; -D_060131FC = 0x060131FC; -D_06013320 = 0x06013320; -D_060138B0 = 0x060138B0; -D_0601430C = 0x0601430C; - -// ovl_En_Fu - -D_06001F74 = 0x06001F74; -D_06002F64 = 0x06002F64; -D_06004904 = 0x06004904; -D_06005304 = 0x06005304; -D_060053E0 = 0x060053E0; -D_0600B0A0 = 0x0600B0A0; -D_0600B0E0 = 0x0600B0E0; -D_0600B2B0 = 0x0600B2B0; -D_0600BAC4 = 0x0600BAC4; - -// ovl_En_Fu_Kago - -D_060006A0 = 0x060006A0; -D_06000740 = 0x06000740; -D_060007E0 = 0x060007E0; -D_06000880 = 0x06000880; -D_06000920 = 0x06000920; -D_060009C0 = 0x060009C0; -D_060015C0 = 0x060015C0; - -// ovl_En_Fu_Mato - -D_060023D4 = 0x060023D4; -D_06002720 = 0x06002720; - -// ovl_En_Gb2 - -D_0600049C = 0x0600049C; -D_06007230 = 0x06007230; // ovl_En_Ge1 @@ -2304,204 +1191,28 @@ 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; -D_0600F6C0 = 0x0600F6C0; - -// ovl_En_Gg2 - -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; -D_06000AC4 = 0x06000AC4; -D_060043F0 = 0x060043F0; -D_06004A7C = 0x06004A7C; -D_06004F40 = 0x06004F40; -D_0600B1D8 = 0x0600B1D8; -D_0600C240 = 0x0600C240; - -// ovl_En_Gk - -D_06006680 = 0x06006680; -D_06006688 = 0x06006688; -D_0600787C = 0x0600787C; -D_060079C0 = 0x060079C0; - -// ovl_En_Gm - -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; - -// ovl_En_Goroiwa - -D_060032E0 = 0x060032E0; -D_060082D0 = 0x060082D0; - // ovl_En_Grasshopper D_06000F9C = 0x06000F9C; D_06003F00 = 0x06003F00; -// ovl_En_Gs - -D_06000950 = 0x06000950; -D_060009D0 = 0x060009D0; -D_06000A60 = 0x06000A60; - -// ovl_En_Guard_Nuts - -D_06002700 = 0x06002700; -D_06002848 = 0x06002848; -D_06002A08 = 0x06002A08; - -// ovl_En_Guruguru - -D_06000B04 = 0x06000B04; -D_0600057C = 0x0600057C; -D_06005F20 = 0x06005F20; -D_06006320 = 0x06006320; -D_06006720 = 0x06006720; -D_06006920 = 0x06006920; -D_06006C90 = 0x06006C90; - -// ovl_En_Hakurock - -D_06011100 = 0x06011100; -D_06011178 = 0x06011178; - // ovl_En_Hata D_060000C0 = 0x060000C0; D_06000444 = 0x06000444; D_06002FD0 = 0x06002FD0; -// ovl_En_Heishi - -D_06003BFC = 0x06003BFC; -D_0600D640 = 0x0600D640; - -// ovl_En_Hg - -D_06000370 = 0x06000370; -D_06001138 = 0x06001138; -D_060015D4 = 0x060015D4; -D_06001960 = 0x06001960; -D_0600260C = 0x0600260C; -D_06005E28 = 0x06005E28; -D_06008580 = 0x06008580; -D_06009D44 = 0x06009D44; -D_0600A164 = 0x0600A164; -D_0600AE1C = 0x0600AE1C; - - // ovl_En_Hgo D_0600B644 = 0x0600B644; D_0600F248 = 0x0600F248; D_06012A58 = 0x06012A58; -// ovl_En_Hidden_Nuts - -D_060023B8 = 0x060023B8; -D_060024CC = 0x060024CC; - -// ovl_En_Hint_Skb - -D_06002190 = 0x06002190; -D_06003584 = 0x06003584; -D_06005EF8 = 0x06005EF8; -D_0600697C = 0x0600697C; - -// ovl_En_Horse - -D_06008C68 = 0x06008C68; -D_0600A8DC = 0x0600A8DC; -D_0600AD08 = 0x0600AD08; -D_0600B3E0 = 0x0600B3E0; -D_0600BDE0 = 0x0600BDE0; -D_0600D178 = 0x0600D178; -D_0600D4E8 = 0x0600D4E8; -D_060150D8 = 0x060150D8; - -// ovl_En_Horse_Game_Check - -D_060013A0 = 0x060013A0; -D_060014B0 = 0x060014B0; -D_06002FB8 = 0x06002FB8; -D_06003030 = 0x06003030; -D_060030C0 = 0x060030C0; -D_06003918 = 0x06003918; - // ovl_En_Horse_Link_Child D_06002F98 = 0x06002F98; D_0600A480 = 0x0600A480; -// ovl_En_Hs - -D_060005C0 = 0x060005C0; -D_06006260 = 0x06006260; - -// ovl_En_Ig - -D_06008710 = 0x06008710; -D_060087B8 = 0x060087B8; -D_060089D8 = 0x060089D8; -D_06008B00 = 0x06008B00; -D_0600C538 = 0x0600C538; -D_060130D0 = 0x060130D0; - // ovl_En_Ik D_06000CE8 = 0x06000CE8; @@ -2517,105 +1228,6 @@ D_060057F4 = 0x060057F4; D_06006294 = 0x06006294; D_060136A0 = 0x060136A0; -// ovl_En_In - -D_060003B4 = 0x060003B4; -D_06000CB0 = 0x06000CB0; -D_06001BE0 = 0x06001BE0; -D_06001C30 = 0x06001C30; -D_06001D10 = 0x06001D10; -D_06003520 = 0x06003520; -D_060035E0 = 0x060035E0; -D_060043E0 = 0x060043E0; -D_06004820 = 0x06004820; -D_06004C20 = 0x06004C20; -D_06007A70 = 0x06007A70; -D_06007C48 = 0x06007C48; -D_06012A78 = 0x06012A78; -D_06012DF8 = 0x06012DF8; -D_06013440 = 0x06013440; -D_06013540 = 0x06013540; -D_06013670 = 0x06013670; -D_060137A0 = 0x060137A0; -D_060138D0 = 0x060138D0; -D_06013A00 = 0x06013A00; -D_06013DE0 = 0x06013DE0; -D_06013F10 = 0x06013F10; -D_06014040 = 0x06014040; -D_06014420 = 0x06014420; -D_060145D8 = 0x060145D8; -D_06014710 = 0x06014710; -D_06014860 = 0x06014860; -D_060149A8 = 0x060149A8; -D_06014AE0 = 0x06014AE0; -D_06014C30 = 0x06014C30; -D_06014EA8 = 0x06014EA8; -D_06014F8C = 0x06014F8C; -D_06015918 = 0x06015918; -D_06015E38 = 0x06015E38; -D_06016484 = 0x06016484; -D_06016A60 = 0x06016A60; -D_060170DC = 0x060170DC; -D_060177AC = 0x060177AC; -D_06018240 = 0x06018240; -D_060187C8 = 0x060187C8; -D_060198A8 = 0x060198A8; -D_06019EB4 = 0x06019EB4; -D_0601A140 = 0x0601A140; -D_0601B3C4 = 0x0601B3C4; -D_0601B904 = 0x0601B904; -D_0601C0B0 = 0x0601C0B0; -D_0601C528 = 0x0601C528; - -// ovl_En_Invadepoh - -D_06000080 = 0x06000080; -D_060003B0 = 0x060003B0; -D_06000550 = 0x06000550; -D_06000560 = 0x06000560; -D_06000608 = 0x06000608; -D_060006C8 = 0x060006C8; -D_06000720 = 0x06000720; -D_06000998 = 0x06000998; -D_06001560 = 0x06001560; -D_06001674 = 0x06001674; -D_06001BD8 = 0x06001BD8; -D_06001D80 = 0x06001D80; -D_060021C8 = 0x060021C8; -D_06002A8C = 0x06002A8C; -D_06004010 = 0x06004010; -D_06004264 = 0x06004264; -D_06004C30 = 0x06004C30; -D_06004E50 = 0x06004E50; -D_06004E98 = 0x06004E98; -D_06007328 = 0x06007328; -D_060080F0 = 0x060080F0; -D_06009E58 = 0x06009E58; -D_0600A174 = 0x0600A174; -D_0600FFC8 = 0x0600FFC8; -D_060107C8 = 0x060107C8; -D_06010FC8 = 0x06010FC8; -D_060117C8 = 0x060117C8; -D_06011AD8 = 0x06011AD8; -D_06011FC8 = 0x06011FC8; -D_060122D8 = 0x060122D8; -D_060127C8 = 0x060127C8; -D_06012AD8 = 0x06012AD8; -D_06012BC8 = 0x06012BC8; -D_06012FC8 = 0x06012FC8; -D_060132D8 = 0x060132D8; -D_060133C8 = 0x060133C8; -D_06013928 = 0x06013928; -D_06013AD8 = 0x06013AD8; -D_06014088 = 0x06014088; -D_060142D8 = 0x060142D8; -D_06014AD8 = 0x06014AD8; -D_06014ED8 = 0x06014ED8; -D_060152D8 = 0x060152D8; -D_060156D8 = 0x060156D8; -D_06015C28 = 0x06015C28; -D_06016720 = 0x06016720; - // ovl_En_Invadepoh_Demo D_06000080 = 0x06000080; @@ -2632,30 +1244,6 @@ D_06012FC8 = 0x06012FC8; D_06013928 = 0x06013928; D_06016588 = 0x06016588; -// ovl_En_Ishi - -D_060009B0 = 0x060009B0; - -// ovl_En_Ja - -D_0600BA30 = 0x0600BA30; -D_0600BCC8 = 0x0600BCC8; -D_0600C240 = 0x0600C240; - -// ovl_En_Jc_Mato - -D_06000390 = 0x06000390; - -// ovl_En_Jg - -D_0601ADC0 = 0x0601ADC0; -D_0601AFF0 = 0x0601AFF0; - -// ovl_En_Jgame_Tsn - -D_06008AB8 = 0x06008AB8; -D_060092FC = 0x060092FC; - // ovl_En_Js D_06010880 = 0x06010880; @@ -2681,73 +1269,11 @@ D_060081F4 = 0x060081F4; D_060058B8 = 0x060058B8; D_0600D828 = 0x0600D828; -// ovl_En_Kakasi - -D_06000214 = 0x06000214; -D_060065B0 = 0x060065B0; - -// 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; D_06001630 = 0x06001630; -// ovl_En_Karebaba - -D_060002B8 = 0x060002B8; -D_060010F0 = 0x060010F0; -D_06001828 = 0x06001828; -D_06002A40 = 0x06002A40; -D_06003070 = 0x06003070; - -// ovl_En_Kbt - -D_06004274 = 0x06004274; -D_0600DEE8 = 0x0600DEE8; - -// ovl_En_Kendo_Js - -D_0600016C = 0x0600016C; -D_060003DC = 0x060003DC; -D_06000F4C = 0x06000F4C; -D_06006990 = 0x06006990; - -// ovl_En_Kgy - -D_06004B98 = 0x06004B98; -D_0600E8F0 = 0x0600E8F0; -D_0600EE58 = 0x0600EE58; -D_0600F180 = 0x0600F180; -D_0600F6A0 = 0x0600F6A0; -D_0600F910 = 0x0600F910; -D_060008FC = 0x060008FC; -D_0600292C = 0x0600292C; -D_060042E4 = 0x060042E4; -D_060101F0 = 0x060101F0; -D_06001764 = 0x06001764; -D_06003334 = 0x06003334; -D_06010B84 = 0x06010B84; -D_06001EA4 = 0x06001EA4; -D_06003D88 = 0x06003D88; -D_04001D00 = 0x04001D00; -D_040021A8 = 0x040021A8; - // ovl_En_Kitan D_06000CE8 = 0x06000CE8; @@ -2814,61 +1340,11 @@ D_06021E34 = 0x06021E34; D_06022728 = 0x06022728; D_06022CAC = 0x06022CAC; -// ovl_En_Kujiya - -D_06002A80 = 0x06002A80; -D_06003030 = 0x06003030; -D_06003248 = 0x06003248; -D_06003358 = 0x06003358; -D_060034A8 = 0x060034A8; -D_060035B8 = 0x060035B8; -D_060036B0 = 0x060036B0; -D_060037C0 = 0x060037C0; -D_06003C80 = 0x06003C80; -D_06003D58 = 0x06003D58; -D_06006198 = 0x06006198; - -// ovl_En_Kusa - -D_06000140 = 0x06000140; -D_060002E0 = 0x060002E0; - // ovl_En_Lift_Nuts D_060029E8 = 0x060029E8; D_0600AC70 = 0x0600AC70; -// ovl_En_Look_Nuts - -D_06000430 = 0x06000430; -D_06002848 = 0x06002848; -D_06002B6C = 0x06002B6C; - -// ovl_En_Ma4 - -D_060003B0 = 0x060003B0; -D_06000A20 = 0x06000A20; -D_06002A8C = 0x06002A8C; -D_06007328 = 0x06007328; -D_06007D98 = 0x06007D98; -D_0600852C = 0x0600852C; -D_06008F6C = 0x06008F6C; -D_06009E58 = 0x06009E58; -D_0600FFC8 = 0x0600FFC8; -D_060107C8 = 0x060107C8; -D_06010FC8 = 0x06010FC8; -D_060117C8 = 0x060117C8; -D_06011FC8 = 0x06011FC8; -D_060127C8 = 0x060127C8; -D_06012BC8 = 0x06012BC8; -D_06012FC8 = 0x06012FC8; -D_060133C8 = 0x060133C8; -D_06013928 = 0x06013928; -D_06014088 = 0x06014088; -D_06015B7C = 0x06015B7C; -D_06018948 = 0x06018948; -D_0601B76C = 0x0601B76C; - // ovl_En_Mag D_06000000 = 0x06000000; @@ -2880,81 +1356,6 @@ D_06011740 = 0x06011740; D_06011BC0 = 0x06011BC0; D_06011E48 = 0x06011E48; -// ovl_En_Maruta - -D_06002EC0 = 0x06002EC0; - -// ovl_En_Ma_Yto - -D_06000CC0 = 0x06000CC0; -D_06001FD0 = 0x06001FD0; -D_060030B4 = 0x060030B4; -D_06003D54 = 0x06003D54; -D_06004370 = 0x06004370; -D_06005314 = 0x06005314; -D_06005430 = 0x06005430; -D_060070EC = 0x060070EC; -D_06007E28 = 0x06007E28; -D_060093E8 = 0x060093E8; -D_0600A174 = 0x0600A174; -D_0600AF7C = 0x0600AF7C; -D_06011AD8 = 0x06011AD8; -D_060122D8 = 0x060122D8; -D_06012AD8 = 0x06012AD8; -D_060132D8 = 0x060132D8; -D_06013AD8 = 0x06013AD8; -D_060142D8 = 0x060142D8; -D_06014AD8 = 0x06014AD8; -D_06014ED8 = 0x06014ED8; -D_060152D8 = 0x060152D8; -D_060156D8 = 0x060156D8; -D_06015C28 = 0x06015C28; -D_06016720 = 0x06016720; - -// ovl_En_Ma_Yts - -D_060003B0 = 0x060003B0; -D_06002A8C = 0x06002A8C; -D_060043A0 = 0x060043A0; -D_06007328 = 0x06007328; -D_06007D98 = 0x06007D98; -D_0600852C = 0x0600852C; -D_06008F6C = 0x06008F6C; -D_06009E58 = 0x06009E58; -D_0600FFC8 = 0x0600FFC8; -D_060107C8 = 0x060107C8; -D_06010FC8 = 0x06010FC8; -D_060117C8 = 0x060117C8; -D_06011FC8 = 0x06011FC8; -D_060127C8 = 0x060127C8; -D_06012BC8 = 0x06012BC8; -D_06012FC8 = 0x06012FC8; -D_060133C8 = 0x060133C8; -D_06013928 = 0x06013928; -D_06014088 = 0x06014088; -D_06015B7C = 0x06015B7C; -D_060180DC = 0x060180DC; -D_06018948 = 0x06018948; -D_0601B76C = 0x0601B76C; - -// ovl_En_Minifrog - -D_060007BC = 0x060007BC; -D_06001534 = 0x06001534; -D_060059A0 = 0x060059A0; -D_06005BA0 = 0x06005BA0; -D_0600B538 = 0x0600B538; - -// ovl_En_Mk - -D_06001C38 = 0x06001C38; -D_06006CA0 = 0x06006CA0; - -// ovl_En_Mm3 - -D_060096E8 = 0x060096E8; -D_0600A4E0 = 0x0600A4E0; - // ovl_En_Mnk D_06003584 = 0x06003584; @@ -2966,16 +1367,6 @@ D_060105DC = 0x060105DC; D_06019B88 = 0x06019B88; D_0601D518 = 0x0601D518; -// ovl_En_Ms - -D_060005EC = 0x060005EC; -D_06003DC0 = 0x06003DC0; - -// ovl_En_Muto - -D_06000E50 = 0x06000E50; -D_06007150 = 0x06007150; - // ovl_En_Nb D_06008C40 = 0x06008C40; @@ -2989,17 +1380,6 @@ D_06001EE8 = 0x06001EE8; D_06013380 = 0x06013380; -// ovl_En_Niw - -D_060000E8 = 0x060000E8; -D_060023B0 = 0x060023B0; -D_06002428 = 0x06002428; -D_06002530 = 0x06002530; - -// ovl_En_Nnh - -D_06001510 = 0x06001510; - // ovl_En_Nwc D_060000E8 = 0x060000E8; @@ -3017,150 +1397,16 @@ D_06003EE4 = 0x06003EE4; D_06004204 = 0x06004204; D_0600466C = 0x0600466C; -// ovl_En_Osk - -D_060000B8 = 0x060000B8; -D_060038F0 = 0x060038F0; -D_06006808 = 0x06006808; -D_06007B48 = 0x06007B48; -D_06009F00 = 0x06009F00; -D_0600B490 = 0x0600B490; - // ovl_En_Osn D_060192A0 = 0x060192A0; D_060201BC = 0x060201BC; D_060202F0 = 0x060202F0; -// ovl_En_Ossan - -D_060028A0 = 0x060028A0; -D_06005BC0 = 0x06005BC0; -D_06006498 = 0x06006498; -D_06006B18 = 0x06006B18; -D_06006D40 = 0x06006D40; -D_06006F18 = 0x06006F18; -D_06007140 = 0x06007140; -D_06009D34 = 0x06009D34; -D_0600A460 = 0x0600A460; -D_0600CB3C = 0x0600CB3C; -D_0600DE34 = 0x0600DE34; -D_0600E3EC = 0x0600E3EC; -D_0600C58C = 0x0600C58C; -D_0600F00C = 0x0600F00C; -D_0600B9D8 = 0x0600B9D8; -D_0600C26C = 0x0600C26C; -D_0600D354 = 0x0600D354; -D_06012C34 = 0x06012C34; -D_060131FC = 0x060131FC; -D_06013320 = 0x06013320; -D_060138B0 = 0x060138B0; -D_0601430C = 0x0601430C; - -// ovl_En_Ot - -D_06000040 = 0x06000040; -D_06000078 = 0x06000078; -D_060004A0 = 0x060004A0; -D_060005F8 = 0x060005F8; -D_060008D8 = 0x060008D8; -D_06004800 = 0x06004800; - -// ovl_En_Owl - -D_06001168 = 0x06001168; -D_06001200 = 0x06001200; -D_06001ADC = 0x06001ADC; -D_0600C5F8 = 0x0600C5F8; -D_0600C6D4 = 0x0600C6D4; -D_0600CB94 = 0x0600CB94; -D_0600CDB0 = 0x0600CDB0; -D_060105C0 = 0x060105C0; -D_06008EB8 = 0x06008EB8; -D_060092B8 = 0x060092B8; -D_060096B8 = 0x060096B8; - -// ovl_En_Pamera - - -D_06008448 = 0x06008448; -D_060005BC = 0x060005BC; -D_06008AE0 = 0x06008AE0; -D_06008E38 = 0x06008E38; -D_0600A844 = 0x0600A844; -D_0600B0C4 = 0x0600B0C4; -D_06009870 = 0x06009870; -D_06009F54 = 0x06009F54; -D_0600B5B0 = 0x0600B5B0; -D_0600BCC4 = 0x0600BCC4; -D_0600D9DC = 0x0600D9DC; -D_0600E16C = 0x0600E16C; -D_0600C9F4 = 0x0600C9F4; -D_0600D0F0 = 0x0600D0F0; -D_060074E8 = 0x060074E8; -D_060078E8 = 0x060078E8; -D_060066E8 = 0x060066E8; -D_06006AE8 = 0x06006AE8; -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; -D_060083E0 = 0x060083E0; -D_060085C8 = 0x060085C8; -D_060096E8 = 0x060096E8; - -// ovl_En_Poh - -D_060001A8 = 0x060001A8; -D_060004EC = 0x060004EC; -D_060006E0 = 0x060006E0; -D_06000A60 = 0x06000A60; -D_060011C4 = 0x060011C4; -D_060015B0 = 0x060015B0; -D_06002608 = 0x06002608; -D_06002D28 = 0x06002D28; -D_06003850 = 0x06003850; -D_060050D0 = 0x060050D0; - // ovl_En_Po_Composer D_0600188C = 0x0600188C; @@ -3170,224 +1416,37 @@ D_06006F38 = 0x06006F38; D_06006FD8 = 0x06006FD8; D_06009930 = 0x06009930; -// ovl_En_Po_Fusen - -D_06000040 = 0x06000040; -D_060024F0 = 0x060024F0; - -// ovl_En_Po_Sisters - -D_06000114 = 0x06000114; -D_060008C0 = 0x060008C0; -D_06000A54 = 0x06000A54; -D_06000D40 = 0x06000D40; -D_0600119C = 0x0600119C; -D_060014CC = 0x060014CC; -D_060027B0 = 0x060027B0; -D_060046E0 = 0x060046E0; -D_060065C8 = 0x060065C8; - // ovl_En_Pp D_0600A844 = 0x0600A844; D_06012768 = 0x06012768; -// ovl_En_Pr - -D_060021E8 = 0x060021E8; -D_060038B8 = 0x060038B8; - // ovl_En_Pr2 D_06003904 = 0x06003904; D_06004188 = 0x06004188; D_06004340 = 0x06004340; -// ovl_En_Prz - -D_06004188 = 0x06004188; -D_06004340 = 0x06004340; - // ovl_En_Pst D_06001A80 = 0x06001A80; -// ovl_En_Racedog - -D_06000550 = 0x06000550; -D_06000618 = 0x06000618; -D_060080F0 = 0x060080F0; - -// ovl_En_Raf - -D_06000108 = 0x06000108; -D_06000A64 = 0x06000A64; -D_060024E0 = 0x060024E0; -D_06002EF8 = 0x06002EF8; -D_060032F8 = 0x060032F8; -D_06003428 = 0x06003428; - -// ovl_En_Railgibud - -D_060053E8 = 0x060053E8; -D_0600ABE0 = 0x0600ABE0; -D_06010B88 = 0x06010B88; -D_06006678 = 0x06006678; -D_06006B08 = 0x06006B08; -D_06006EEC = 0x06006EEC; -D_060073A4 = 0x060073A4; -D_06007BBC = 0x06007BBC; -D_060081A8 = 0x060081A8; -D_06009298 = 0x06009298; -D_06009900 = 0x06009900; -D_0600A450 = 0x0600A450; -D_060113EC = 0x060113EC; -D_0601216C = 0x0601216C; -D_060118D8 = 0x060118D8; -D_06011DB8 = 0x06011DB8; -D_0600A450 = 0x0600A450; -D_06005DF4 = 0x06005DF4; -D_060061E4 = 0x060061E4; -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; D_0600026C = 0x0600026C; D_06001858 = 0x06001858; -// ovl_En_Rd - -D_060053E8 = 0x060053E8; -D_06006678 = 0x06006678; -D_06006B08 = 0x06006B08; -D_06006EEC = 0x06006EEC; -D_060073A4 = 0x060073A4; -D_06007BBC = 0x06007BBC; -D_060081A8 = 0x060081A8; -D_06009298 = 0x06009298; -D_06009900 = 0x06009900; -D_0600A450 = 0x0600A450; -D_0600ABE0 = 0x0600ABE0; -D_06010B88 = 0x06010B88; -D_060113EC = 0x060113EC; -D_060118D8 = 0x060118D8; -D_06011DB8 = 0x06011DB8; -D_0601216C = 0x0601216C; - -// ovl_En_Recepgirl - -D_06000968 = 0x06000968; -D_06001384 = 0x06001384; -D_06009890 = 0x06009890; -D_0600A280 = 0x0600A280; -D_0600AD98 = 0x0600AD98; -D_06011B60 = 0x06011B60; - -// ovl_En_Rg - -D_060091A8 = 0x060091A8; -D_06011AC8 = 0x06011AC8; -D_06014CF0 = 0x06014CF0; -D_06014D00 = 0x06014D00; - -// ovl_En_Rr - -D_06000470 = 0x06000470; - -// ovl_En_Rsn - -D_06005458 = 0x06005458; -D_0600788C = 0x0600788C; -D_06009120 = 0x06009120; -D_06009220 = 0x06009220; - // ovl_En_Ru D_0600C700 = 0x0600C700; -// ovl_En_Ruppecrow - -D_060000F0 = 0x060000F0; -D_060010C0 = 0x060010C0; - // ovl_En_Rz D_06003A20 = 0x06003A20; D_0600D768 = 0x0600D768; D_0600D8D8 = 0x0600D8D8; -// ovl_En_Sb - -D_0600004C = 0x0600004C; -D_060000B4 = 0x060000B4; -D_06000124 = 0x06000124; -D_06000194 = 0x06000194; -D_06002BF0 = 0x06002BF0; -D_06002C8C = 0x06002C8C; - -// ovl_En_Scopecrow - -D_060000F0 = 0x060000F0; -D_060010C0 = 0x060010C0; - -// ovl_En_Scopenuts - -D_06001420 = 0x06001420; -D_06005488 = 0x06005488; -D_06008290 = 0x06008290; -D_0600AC70 = 0x0600AC70; - -// ovl_En_Sellnuts - -D_06001350 = 0x06001350; -D_06005488 = 0x06005488; -D_06008290 = 0x06008290; -D_0600AC70 = 0x0600AC70; -D_06000994 = 0x06000994; -D_060012F4 = 0x060012F4; -D_06001BC8 = 0x06001BC8; -D_06001E2C = 0x06001E2C; -D_06002268 = 0x06002268; -D_06002670 = 0x06002670; -D_060029E8 = 0x060029E8; -D_06002F08 = 0x06002F08; -D_06003438 = 0x06003438; -D_060038CC = 0x060038CC; -D_06003CC0 = 0x06003CC0; -D_06004700 = 0x06004700; -D_06004AA0 = 0x06004AA0; -D_06004E38 = 0x06004E38; -D_0600577C = 0x0600577C; -D_06005CA8 = 0x06005CA8; -D_0600B0B4 = 0x0600B0B4; - -// ovl_En_Shn - -D_0600B738 = 0x0600B738; -D_0600E7D0 = 0x0600E7D0; - -// ovl_En_Skb - -D_06001D1C = 0x06001D1C; -D_06002190 = 0x06002190; -D_06003584 = 0x06003584; -D_06005EF8 = 0x06005EF8; -D_0600697C = 0x0600697C; -D_06006D90 = 0x06006D90; -D_060009E4 = 0x060009E4; -D_060015EC = 0x060015EC; -D_0600270C = 0x0600270C; -D_06002AC8 = 0x06002AC8; -D_060064E0 = 0x060064E0; - // ovl_En_Slime D_060004C0 = 0x060004C0; @@ -3395,58 +1454,14 @@ D_06000650 = 0x06000650; D_06000828 = 0x06000828; D_06000A10 = 0x06000A10; -// ovl_En_Snowman - -D_06000404 = 0x06000404; -D_060007B4 = 0x060007B4; -D_060045A0 = 0x060045A0; -D_06004628 = 0x06004628; -D_060046D8 = 0x060046D8; -D_06004A90 = 0x06004A90; -D_06004F14 = 0x06004F14; -D_0600544C = 0x0600544C; -D_0600554C = 0x0600554C; -D_060058CC = 0x060058CC; - // ovl_En_Snowwd D_06000198 = 0x06000198; D_06001AA0 = 0x06001AA0; -// ovl_En_Sob1 - -D_06008268 = 0x06008268; -D_0600D208 = 0x0600D208; -D_0600078C = 0x0600078C; -D_06011AC8 = 0x06011AC8; -D_060000FC = 0x060000FC; -D_06000970 = 0x06000970; -D_060087BC = 0x060087BC; -D_060050A0 = 0x060050A0; -D_060058A0 = 0x060058A0; -D_060060A0 = 0x060060A0; -D_06010438 = 0x06010438; -D_06010C38 = 0x06010C38; -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 - -D_060031F8 = 0x060031F8; -D_06005998 = 0x06005998; // ovl_En_Sth2 @@ -3464,84 +1479,12 @@ D_0600D640 = 0x0600D640; D_06006C18 = 0x06006C18; D_0600D640 = 0x0600D640; -// ovl_En_Stream - -D_06000950 = 0x06000950; - -// ovl_En_Suttari - -D_0600071C = 0x0600071C; -D_0600AF90 = 0x0600AF90; -D_0600C240 = 0x0600C240; -D_06010BDC = 0x06010BDC; -D_0601139C = 0x0601139C; -D_06011C38 = 0x06011C38; -D_06011F84 = 0x06011F84; -D_060128F4 = 0x060128F4; -D_06012E84 = 0x06012E84; -D_06013380 = 0x06013380; - -// ovl_En_Sw - -D_06003FB0 = 0x06003FB0; -D_060043D8 = 0x060043D8; -D_060045C0 = 0x060045C0; -D_06004658 = 0x06004658; -D_060046F0 = 0x060046F0; -D_06004788 = 0x06004788; -D_06004820 = 0x06004820; -D_060048B8 = 0x060048B8; -D_06004950 = 0x06004950; -D_060049E8 = 0x060049E8; -D_06005298 = 0x06005298; -D_06000304 = 0x06000304; -D_060055A8 = 0x060055A8; -D_06005B98 = 0x06005B98; - -// ovl_En_Syateki_Crow - -D_060000F0 = 0x060000F0; -D_060010C0 = 0x060010C0; - -// ovl_En_Syateki_Dekunuts - -D_06001E50 = 0x06001E50; -D_06002468 = 0x06002468; -D_06002A5C = 0x06002A5C; -D_06003180 = 0x06003180; - -// ovl_En_Syateki_Man - -D_06005AC8 = 0x06005AC8; -D_060062C8 = 0x060062C8; -D_0600D2F8 = 0x0600D2F8; -D_0600D9D0 = 0x0600D9D0; -D_0600DFEC = 0x0600DFEC; -D_0600E7D0 = 0x0600E7D0; -D_0600F2D0 = 0x0600F2D0; -D_0600FB90 = 0x0600FB90; -D_06010390 = 0x06010390; - -// ovl_En_Syateki_Okuta - -D_060033D0 = 0x060033D0; -D_0600466C = 0x0600466C; - -// ovl_En_Syateki_Wf - -D_060095D0 = 0x060095D0; -D_0600A3CC = 0x0600A3CC; - // ovl_En_S_Goro D_060091A8 = 0x060091A8; D_06011AC8 = 0x06011AC8; D_06012DE0 = 0x06012DE0; -// ovl_En_Tab - -D_06007F78 = 0x06007F78; - // ovl_En_Takaraya D_06000968 = 0x06000968; @@ -3551,13 +1494,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; @@ -3565,22 +1501,11 @@ D_060034C8 = 0x060034C8; D_06004510 = 0x06004510; D_06004550 = 0x06004550; -// ovl_En_Tanron3 - -D_0600DA20 = 0x0600DA20; -D_0600DAAC = 0x0600DAAC; - // ovl_En_Tanron4 D_06000168 = 0x06000168; D_06000E68 = 0x06000E68; -// ovl_En_Tanron5 - -D_06006FD0 = 0x06006FD0; -D_06007A88 = 0x06007A88; -D_06007D18 = 0x06007D18; - // ovl_En_Test3 D_0600CB60 = 0x0600CB60; @@ -3593,150 +1518,21 @@ D_0600B0A0 = 0x0600B0A0; D_0600B0E0 = 0x0600B0E0; D_0600B2B0 = 0x0600B2B0; -// ovl_En_Thiefbird - -D_06000088 = 0x06000088; -D_06000278 = 0x06000278; -D_06000604 = 0x06000604; -D_06003060 = 0x06003060; -D_060030D8 = 0x060030D8; -D_060033B0 = 0x060033B0; -D_06003D58 = 0x06003D58; -D_060061A0 = 0x060061A0; -D_060063C4 = 0x060063C4; -D_06004348 = 0x06004348; -D_06004B88 = 0x06004B88; -D_060055E0 = 0x060055E0; - -// ovl_En_Tite - -D_060004F8 = 0x060004F8; -D_0600069C = 0x0600069C; -D_0600083C = 0x0600083C; -D_06000A14 = 0x06000A14; -D_06000C70 = 0x06000C70; -D_060012E4 = 0x060012E4; -D_06003A20 = 0x06003A20; - -// ovl_En_Tk - -D_060030A4 = 0x060030A4; -D_0600B530 = 0x0600B530; -D_0600B9E8 = 0x0600B9E8; - -// ovl_En_Torch2 - -D_0401C430 = 0x0401C430; -D_04048DF0 = 0x04048DF0; -D_04057B10 = 0x04057B10; -D_04089070 = 0x04089070; - -// ovl_En_Toto - -D_06000C80 = 0x06000C80; -D_06001324 = 0x06001324; -D_060016A4 = 0x060016A4; -D_06001DF0 = 0x06001DF0; -D_060022C8 = 0x060022C8; -D_060028B8 = 0x060028B8; -D_06002F20 = 0x06002F20; -D_06003AA8 = 0x06003AA8; -D_06008AE8 = 0x06008AE8; -D_0600A068 = 0x0600A068; -D_0600A468 = 0x0600A468; -D_0600A978 = 0x0600A978; -D_0600B3E0 = 0x0600B3E0; -D_0600B894 = 0x0600B894; -D_0600BC08 = 0x0600BC08; -D_0600C880 = 0x0600C880; - // ovl_En_Trt D_0600FEF0 = 0x0600FEF0; -D_0600FD34 = 0x0600FD34; -D_0600DE68 = 0x0600DE68; -D_06002224 = 0x06002224; -D_06001EF4 = 0x06001EF4; -D_060030EC = 0x060030EC; -D_0600D52C = 0x0600D52C; -D_06002CB0 = 0x06002CB0; -D_0600EE98 = 0x0600EE98; -D_06003D78 = 0x06003D78; D_06000A44 = 0x06000A44; -D_0600B0B8 = 0x0600B0B8; -D_0600B8B8 = 0x0600B8B8; -D_0600C0B8 = 0x0600C0B8; - -// ovl_En_Trt2 - -D_06000A44 = 0x06000A44; -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 - -D_060004C8 = 0x060004C8; -D_0601AA60 = 0x0601AA60; - -// ovl_En_Tsn - -D_06000964 = 0x06000964; -D_06001198 = 0x06001198; -D_06008AB8 = 0x06008AB8; -D_060092FC = 0x060092FC; // ovl_En_Twig D_060014C8 = 0x060014C8; D_06001C38 = 0x06001C38; -// ovl_En_Vm - -D_06000068 = 0x06000068; -D_06002728 = 0x06002728; -D_06003F60 = 0x06003F60; - -// ovl_En_Wallmas - -D_06000590 = 0x06000590; -D_06000EA4 = 0x06000EA4; -D_060019CC = 0x060019CC; -D_0600299C = 0x0600299C; -D_060041F4 = 0x060041F4; -D_06008688 = 0x06008688; -D_06008FB0 = 0x06008FB0; -D_06009244 = 0x06009244; -D_06009520 = 0x06009520; -D_06009DB0 = 0x06009DB0; -D_0600A054 = 0x0600A054; - -// ovl_En_Warp_Uzu - -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; @@ -3747,19 +1543,6 @@ D_060014C0 = 0x060014C0; D_060015B0 = 0x060015B0; D_06001E20 = 0x06001E20; -// ovl_En_Wf - -D_06003BC0 = 0x06003BC0; -D_06004638 = 0x06004638; -D_06004A90 = 0x06004A90; -D_06004C44 = 0x06004C44; -D_060053D0 = 0x060053D0; -D_06005700 = 0x06005700; -D_060095D0 = 0x060095D0; -D_06009808 = 0x06009808; -D_06009A50 = 0x06009A50; -D_0600A3CC = 0x0600A3CC; - // ovl_En_Wiz D_06001860 = 0x06001860; @@ -3768,423 +1551,67 @@ D_060025F0 = 0x060025F0; D_060066C0 = 0x060066C0; D_0600B320 = 0x0600B320; -// ovl_En_Wiz_Brock - -D_060010E8 = 0x060010E8; -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; - -// ovl_En_Yb - -D_06000200 = 0x06000200; -D_06005F48 = 0x06005F48; - // ovl_En_Zl4 D_06013328 = 0x06013328; -// ovl_En_Zo - -D_0600D208 = 0x0600D208; - -// ovl_En_Zob - -D_06006998 = 0x06006998; -D_06010810 = 0x06010810; - // ovl_En_Zod 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; -D_06001E08 = 0x06001E08; -D_06004C90 = 0x06004C90; -D_06004D20 = 0x06004D20; -D_06004E04 = 0x06004E04; -D_06004FE4 = 0x06004FE4; -D_06005098 = 0x06005098; -D_06005250 = 0x06005250; - -// ovl_En_Zos - -D_0600A164 = 0x0600A164; -D_06013088 = 0x06013088; -D_060136E0 = 0x060136E0; -D_06015238 = 0x06015238; - -// ovl_En_Zot - -D_06002898 = 0x06002898; -D_06004248 = 0x06004248; -D_060050A0 = 0x060050A0; -D_060058A0 = 0x060058A0; -D_060060A0 = 0x060060A0; -D_0600D208 = 0x0600D208; -D_0600DE20 = 0x0600DE20; -D_0600DF54 = 0x0600DF54; -D_0600E400 = 0x0600E400; -D_0600EDF0 = 0x0600EDF0; -D_0600F4E8 = 0x0600F4E8; -D_0600FDF0 = 0x0600FDF0; -D_06010B18 = 0x06010B18; -D_06011424 = 0x06011424; - -// ovl_En_Zov - -D_0600D3EC = 0x0600D3EC; -D_06016258 = 0x06016258; - -// ovl_En_Zow - -D_060029F0 = 0x060029F0; -D_06002A50 = 0x06002A50; -D_06002BA0 = 0x06002BA0; -D_06002C10 = 0x06002C10; -D_06003610 = 0x06003610; -D_06004248 = 0x06004248; -D_0600D208 = 0x0600D208; -D_0600D220 = 0x0600D220; -D_0600D288 = 0x0600D288; - -// ovl_Item_B_Heart - -D_06001290 = 0x06001290; -D_06001470 = 0x06001470; - -// ovl_Mir_Ray - -D_06000168 = 0x06000168; -D_060003F8 = 0x060003F8; -D_060004B0 = 0x060004B0; - // ovl_Mir_Ray3 D_06000168 = 0x06000168; D_060003F8 = 0x060003F8; D_060004B0 = 0x060004B0; -// ovl_Obj_Armos - -D_0600033C = 0x0600033C; -D_06005948 = 0x06005948; -D_06005CF8 = 0x06005CF8; - -// ovl_Obj_Bean - -D_06000090 = 0x06000090; -D_060002D0 = 0x060002D0; -D_060004BC = 0x060004BC; -D_06000530 = 0x06000530; -D_06002208 = 0x06002208; - -// ovl_Obj_Bell - -D_06000570 = 0x06000570; -D_06000698 = 0x06000698; -D_060007A8 = 0x060007A8; -D_06000840 = 0x06000840; -D_060008D0 = 0x060008D0; -D_06000960 = 0x06000960; -D_06001BA8 = 0x06001BA8; - -// ovl_Obj_Bigicicle - -D_060009B0 = 0x060009B0; -D_060014F0 = 0x060014F0; - // ovl_Obj_Boat D_06007630 = 0x06007630; D_06009A88 = 0x06009A88; -// ovl_Obj_Bombiwa - -D_060009E0 = 0x060009E0; -D_06000AF0 = 0x06000AF0; -D_06004560 = 0x06004560; -D_06004688 = 0x06004688; -D_06005990 = 0x06005990; - -// ovl_Obj_Boyo - -D_06000300 = 0x06000300; -D_06000E88 = 0x06000E88; - -// ovl_Obj_Chan - -D_06000A10 = 0x06000A10; -D_06000AF0 = 0x06000AF0; -D_06001960 = 0x06001960; -D_06002358 = 0x06002358; - // ovl_Obj_Chikuwa D_06000D10 = 0x06000D10; D_06000F00 = 0x06000F00; -// ovl_Obj_Comb - -D_06000CB0 = 0x06000CB0; -D_06001040 = 0x06001040; - // ovl_Obj_Danpeilift D_06000180 = 0x06000180; D_06000BA0 = 0x06000BA0; -// ovl_Obj_Dhouse - -D_06004928 = 0x06004928; -D_06005A78 = 0x06005A78; -D_06008040 = 0x06008040; -D_060081D8 = 0x060081D8; - -// ovl_Obj_Dinner - -D_060011E0 = 0x060011E0; - -// ovl_Obj_Dora - -D_06003FD0 = 0x06003FD0; -D_06004160 = 0x06004160; - -// ovl_Obj_Driftice - -D_060016A0 = 0x060016A0; -D_06001AA8 = 0x06001AA8; - -// ovl_Obj_Ending - -D_060003D0 = 0x060003D0; -D_06001FF8 = 0x06001FF8; -D_060031A0 = 0x060031A0; -D_06003440 = 0x06003440; - -// ovl_Obj_Entotu - -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; - -// ovl_Obj_Ghaka - -D_06001980 = 0x06001980; -D_06001A20 = 0x06001A20; -D_06003CD0 = 0x06003CD0; - -// ovl_Obj_Hakaisi - -D_06001F10 = 0x06001F10; -D_060021B0 = 0x060021B0; -D_06002650 = 0x06002650; -D_060029C0 = 0x060029C0; -D_06002CC0 = 0x06002CC0; -D_06002FC4 = 0x06002FC4; - -// ovl_Obj_Hana - -D_06000500 = 0x06000500; - -// ovl_Obj_Hariko - -D_06000080 = 0x06000080; -D_06000110 = 0x06000110; - -// ovl_Obj_Hgdoor - -D_06001670 = 0x06001670; -D_06001768 = 0x06001768; -D_060018C0 = 0x060018C0; -D_06001AB0 = 0x06001AB0; -D_06001BA8 = 0x06001BA8; -D_06001D10 = 0x06001D10; - -// ovl_Obj_HsStump - -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; -D_06000BF0 = 0x06000BF0; -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; -// ovl_Obj_Jg_Gakki - -D_0601B1E8 = 0x0601B1E8; -D_0601B210 = 0x0601B210; - -// ovl_Obj_Kendo_Kanban - -D_06000180 = 0x06000180; - -// ovl_Obj_Kepn_Koya - -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; -D_06001118 = 0x06001118; - // ovl_Obj_Lift D_06000D10 = 0x06000D10; D_06000F00 = 0x06000F00; -// ovl_Obj_Lightblock - -D_06000178 = 0x06000178; -D_06000B80 = 0x06000B80; - -// ovl_Obj_Lightswitch - -D_06000260 = 0x06000260; -D_06000398 = 0x06000398; -D_06000408 = 0x06000408; -D_06000420 = 0x06000420; -D_06000C20 = 0x06000C20; -D_06001420 = 0x06001420; - // ovl_Obj_Lupygamelift D_060048D0 = 0x060048D0; D_060071B8 = 0x060071B8; -// ovl_Obj_Milk_Bin - -D_060004B0 = 0x060004B0; - // ovl_Obj_Mine D_06000030 = 0x06000030; D_06002068 = 0x06002068; D_06002188 = 0x06002188; -// ovl_Obj_Moon_Stone - -D_06000C80 = 0x06000C80; -D_06000D78 = 0x06000D78; -D_06001C60 = 0x06001C60; - -// ovl_Obj_Nozoki - -D_060001C0 = 0x060001C0; - // ovl_Obj_Ocarinalift D_06001DB0 = 0x06001DB0; D_06001E40 = 0x06001E40; D_060048D0 = 0x060048D0; -// ovl_Obj_Raillift - -D_06000208 = 0x06000208; -D_060048D0 = 0x060048D0; -D_06004BF0 = 0x06004BF0; -D_06004FF8 = 0x06004FF8; -D_060071B8 = 0x060071B8; - // ovl_Obj_Shutter D_060011E0 = 0x060011E0; -// ovl_Obj_Smork - -D_06001C00 = 0x06001C00; - -// ovl_Obj_Snowball - -D_060082D0 = 0x060082D0; -D_06008B90 = 0x06008B90; - -// ovl_Obj_Snowball2 - -D_06008B90 = 0x06008B90; - -// ovl_Obj_Spinyroll - -D_06000460 = 0x06000460; -D_06000E68 = 0x06000E68; - -// ovl_Obj_Syokudai - -D_060003A0 = 0x060003A0; -D_06000870 = 0x06000870; -D_06000B90 = 0x06000B90; - // ovl_Obj_Takaraya_Wall D_06000B70 = 0x06000B70; @@ -4203,26 +1630,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; @@ -4236,12 +1643,6 @@ D_06003038 = 0x06003038; D_060023B0 = 0x060023B0; D_060024E8 = 0x060024E8; -// ovl_Obj_Tree - -D_06000680 = 0x06000680; -D_060007C8 = 0x060007C8; -D_06001B2C = 0x06001B2C; - // ovl_Obj_Um D_06007E20 = 0x06007E20; @@ -4255,33 +1656,12 @@ D_06000098 = 0x06000098; D_06000838 = 0x06000838; D_060022AC = 0x060022AC; -// ovl_Obj_Visiblock - -D_06000140 = 0x06000140; -D_06000AD0 = 0x06000AD0; - -// ovl_Obj_Vspinyroll - -D_06000460 = 0x06000460; -D_06000F80 = 0x06000F80; - // ovl_Obj_Y2lift D_06001680 = 0x06001680; D_060019B0 = 0x060019B0; -// ovl_Obj_Yado - -D_06000320 = 0x06000320; -D_06000430 = 0x06000430; -D_060012E8 = 0x060012E8; - -// ovl_Obj_Yasi - -D_06000360 = 0x06000360; -D_06001428 = 0x06001428; - -// ovl_Player_Actor +// ovl_player_actor D_06008860 = 0x06008860; D_0600BDD8 = 0x0600BDD8; @@ -4366,6 +1746,9 @@ D_0D003700 = 0x0D003700; // segment 0x0E +D_0E000000 = 0x0E000000; + +// TODO the following are fake and are offsets into the structure at D_0E000000 D_0E000048 = 0x0E000048; D_0E000088 = 0x0E000088; D_0E000140 = 0x0E000140; @@ -4376,7 +1759,6 @@ D_0E0002B0 = 0x0E0002B0; D_0E0002B8 = 0x0E0002B8; D_0E0002C8 = 0x0E0002C8; D_0E0002E0 = 0x0E0002E0; -D_0E0002F8 = 0x0E0002F8; // segment 0x0F